Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Use both ring and ed25519-dalek
Browse files Browse the repository at this point in the history
  • Loading branch information
tomaka committed Apr 29, 2019
1 parent 880d421 commit d028013
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 3 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion core/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ impl-serde = { version = "0.1", optional = true }
wasmi = { version = "0.4.3", optional = true }
hash-db = { version = "0.12", default-features = false }
hash256-std-hasher = { version = "0.12", default-features = false }
ed25519-dalek = { version = "1.0.0-pre.1", optional = true }
base58 = { version = "0.1", optional = true }
blake2-rfc = { version = "0.2.18", optional = true }
schnorrkel = { version = "0.1", optional = true }
Expand All @@ -27,6 +26,13 @@ tiny-bip39 = { version = "0.6.1", optional = true }
hex = { version = "0.3", optional = true }
regex = {version = "1.1", optional = true }

[target.'cfg(target_arch = "wasm32")'.dependencies]
ed25519-dalek = { version = "1.0.0-pre.1", optional = true }

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
ring = { version = "0.14", optional = true }
untrusted = { version = "0.6", optional = true }

[dev-dependencies]
substrate-serializer = { path = "../serializer" }
pretty_assertions = "0.6"
Expand Down Expand Up @@ -54,6 +60,8 @@ std = [
"twox-hash",
"blake2-rfc",
"ed25519-dalek",
"ring",
"untrusted",
"hex",
"base58",
"substrate-bip39",
Expand Down
77 changes: 75 additions & 2 deletions core/primitives/src/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,19 @@ type Seed = [u8; 32];
pub struct Public(pub [u8; 32]);

/// A key pair.
#[cfg(feature = "std")]
#[cfg(all(feature = "std", not(target_arch = "wasm32")))]
pub struct Pair(ring::signature::Ed25519KeyPair, Seed);
#[cfg(all(feature = "std", target_arch = "wasm32"))]
pub struct Pair(ed25519_dalek::Keypair);

#[cfg(feature = "std")]
#[cfg(all(feature = "std", not(target_arch = "wasm32")))]
impl Clone for Pair {
fn clone(&self) -> Self {
Pair::from_seed(self.1.clone())
}
}

#[cfg(all(feature = "std", target_arch = "wasm32"))]
impl Clone for Pair {
fn clone(&self) -> Self {
Pair(ed25519_dalek::Keypair {
Expand Down Expand Up @@ -390,6 +399,17 @@ impl TraitPair for Pair {
/// Make a new key pair from secret seed material.
///
/// You should never need to use this; generate(), generate_with_phrasee
#[cfg(not(target_arch = "wasm32"))]
fn from_seed(seed: Seed) -> Pair {
let key = ring::signature::Ed25519KeyPair::from_seed_unchecked(untrusted::Input::from(&seed[..]))
.expect("seed has valid length; qed");
Pair(key, seed)
}

/// Make a new key pair from secret seed material.
///
/// You should never need to use this; generate(), generate_with_phrasee
#[cfg(target_arch = "wasm32")]
fn from_seed(seed: Seed) -> Pair {
let secret = ed25519_dalek::SecretKey::from_bytes(&seed[..])
.expect("seed has valid length; qed");
Expand All @@ -413,6 +433,9 @@ impl TraitPair for Pair {

/// Derive a child key from a series of given junctions.
fn derive<Iter: Iterator<Item=DeriveJunction>>(&self, path: Iter) -> Result<Pair, DeriveError> {
#[cfg(not(target_arch = "wasm32"))]
let mut acc = self.1.clone();
#[cfg(target_arch = "wasm32")]
let mut acc = self.0.public.to_bytes();
for j in path {
match j {
Expand All @@ -430,19 +453,45 @@ impl TraitPair for Pair {

/// Get the public key.
fn public(&self) -> Public {
#[cfg(not(target_arch = "wasm32"))]
use ring::signature::KeyPair;
let mut r = [0u8; 32];
#[cfg(not(target_arch = "wasm32"))]
let pk = self.0.public_key().as_ref();
#[cfg(target_arch = "wasm32")]
let pk = self.0.public.as_bytes();
r.copy_from_slice(pk);
Public(r)
}

/// Sign a message.
fn sign(&self, message: &[u8]) -> Signature {
#[cfg(not(target_arch = "wasm32"))]
let r = {
let mut r = [0u8; 64];
r.copy_from_slice(self.0.sign(message).as_ref());
r
};
#[cfg(target_arch = "wasm32")]
let r = self.0.sign(message).to_bytes();
Signature::from_raw(r)
}

/// Verify a signature on a message. Returns true if the signature is good.
#[cfg(not(target_arch = "wasm32"))]
fn verify<P: AsRef<Self::Public>, M: AsRef<[u8]>>(sig: &Self::Signature, message: M, pubkey: P) -> bool {
let public_key = untrusted::Input::from(&pubkey.as_ref().0[..]);
let msg = untrusted::Input::from(message.as_ref());
let sig = untrusted::Input::from(&sig.0[..]);

match ring::signature::verify(&ring::signature::ED25519, public_key, msg, sig) {
Ok(_) => true,
_ => false,
}
}

/// Verify a signature on a message. Returns true if the signature is good.
#[cfg(target_arch = "wasm32")]
fn verify<P: AsRef<Self::Public>, M: AsRef<[u8]>>(sig: &Self::Signature, message: M, pubkey: P) -> bool {
Self::verify_weak(&sig.0[..], message.as_ref(), &pubkey.as_ref().0[..])
}
Expand All @@ -451,6 +500,23 @@ impl TraitPair for Pair {
///
/// This doesn't use the type system to ensure that `sig` and `pubkey` are the correct
/// size. Use it only if you're coming from byte buffers and need the speed.
#[cfg(not(target_arch = "wasm32"))]
fn verify_weak<P: AsRef<[u8]>, M: AsRef<[u8]>>(sig: &[u8], message: M, pubkey: P) -> bool {
let public_key = untrusted::Input::from(pubkey.as_ref());
let msg = untrusted::Input::from(message.as_ref());
let sig = untrusted::Input::from(sig);

match ring::signature::verify(&ring::signature::ED25519, public_key, msg, sig) {
Ok(_) => true,
_ => false,
}
}

/// Verify a signature on a message. Returns true if the signature is good.
///
/// This doesn't use the type system to ensure that `sig` and `pubkey` are the correct
/// size. Use it only if you're coming from byte buffers and need the speed.
#[cfg(target_arch = "wasm32")]
fn verify_weak<P: AsRef<[u8]>, M: AsRef<[u8]>>(sig: &[u8], message: M, pubkey: P) -> bool {
let public_key = match ed25519_dalek::PublicKey::from_bytes(pubkey.as_ref()) {
Ok(pk) => pk,
Expand All @@ -472,6 +538,13 @@ impl TraitPair for Pair {
#[cfg(feature = "std")]
impl Pair {
/// Get the seed for this key.
#[cfg(not(target_arch = "wasm32"))]
pub fn seed(&self) -> &Seed {
&self.1
}

/// Get the seed for this key.
#[cfg(target_arch = "wasm32")]
pub fn seed(&self) -> &Seed {
self.0.public.as_bytes()
}
Expand Down

0 comments on commit d028013

Please sign in to comment.