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

Commit

Permalink
swap ed25519-dalek for ed25519-zebra; no batch verificaiton
Browse files Browse the repository at this point in the history
  • Loading branch information
jakehemmerle committed May 10, 2021
1 parent de24234 commit cc921fd
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 28 deletions.
15 changes: 14 additions & 1 deletion Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ crossbeam-deque = { opt-level = 3 }
crossbeam-queue = { opt-level = 3 }
crypto-mac = { opt-level = 3 }
curve25519-dalek = { opt-level = 3 }
ed25519-dalek = { opt-level = 3 }
ed25519-zebra = { opt-level = 3 }
flate2 = { opt-level = 3 }
futures-channel = { opt-level = 3 }
hashbrown = { opt-level = 3 }
Expand Down
6 changes: 3 additions & 3 deletions primitives/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ dyn-clonable = { version = "0.9.0", optional = true }
thiserror = { version = "1.0.21", optional = true }

# full crypto
ed25519-dalek = { version = "1.0.1", default-features = false, features = ["u64_backend", "alloc"], optional = true }
ed25519-zebra = { version = "2.2.0", default-features = false, optional = true}
blake2-rfc = { version = "0.2.18", default-features = false, optional = true }
tiny-keccak = { version = "2.0.1", features = ["keccak"], optional = true }
schnorrkel = { version = "0.9.1", features = ["preaudit_deprecated", "u64_backend"], default-features = false, optional = true }
Expand Down Expand Up @@ -91,7 +91,7 @@ std = [
"serde",
"twox-hash/std",
"blake2-rfc/std",
"ed25519-dalek/std",
"ed25519-zebra",
"hex/std",
"base58",
"substrate-bip39",
Expand Down Expand Up @@ -120,7 +120,7 @@ std = [
# or Intel SGX.
# For the regular wasm runtime builds this should not be used.
full_crypto = [
"ed25519-dalek",
"ed25519-zebra",
"blake2-rfc",
"tiny-keccak",
"schnorrkel",
Expand Down
48 changes: 25 additions & 23 deletions primitives/core/src/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use codec::{Encode, Decode};
#[cfg(feature = "full_crypto")]
use core::convert::TryFrom;
#[cfg(feature = "full_crypto")]
use ed25519_dalek::{Signer as _, Verifier as _};
use ed25519_zebra::{SigningKey, VerificationKey};
#[cfg(feature = "std")]
use substrate_bip39::seed_from_entropy;
#[cfg(feature = "std")]
Expand Down Expand Up @@ -59,16 +59,18 @@ pub struct Public(pub [u8; 32]);

/// A key pair.
#[cfg(feature = "full_crypto")]
pub struct Pair(ed25519_dalek::Keypair);
pub struct Pair {
public: VerificationKey,
secret: SigningKey,
}

#[cfg(feature = "full_crypto")]
impl Clone for Pair {
fn clone(&self) -> Self {
Pair(ed25519_dalek::Keypair {
public: self.0.public.clone(),
secret: ed25519_dalek::SecretKey::from_bytes(self.0.secret.as_bytes())
.expect("key is always the correct size; qed")
})
Pair {
public: self.public.clone(),
secret: self.secret.clone(),
}
}
}

Expand Down Expand Up @@ -467,18 +469,19 @@ impl TraitPair for Pair {
///
/// You should never need to use this; generate(), generate_with_phrase
fn from_seed_slice(seed_slice: &[u8]) -> Result<Pair, SecretStringError> {
let secret = ed25519_dalek::SecretKey::from_bytes(seed_slice)
// does try_into consume the seed? can I consume seed_slice here? I think not right?
let secret = SigningKey::try_from(seed_slice)
.map_err(|_| SecretStringError::InvalidSeedLength)?;
let public = ed25519_dalek::PublicKey::from(&secret);
Ok(Pair(ed25519_dalek::Keypair { secret, public }))
let public = VerificationKey::from(&secret);
Ok(Pair {secret, public})
}

/// Derive a child key from a series of given junctions.
fn derive<Iter: Iterator<Item=DeriveJunction>>(&self,
path: Iter,
_seed: Option<Seed>,
) -> Result<(Pair, Option<Seed>), DeriveError> {
let mut acc = self.0.secret.to_bytes();
let mut acc: [u8; 32] = self.secret.into();
for j in path {
match j {
DeriveJunction::Soft(_cc) => return Err(DeriveError::SoftKeyInPath),
Expand All @@ -490,15 +493,14 @@ impl TraitPair for Pair {

/// Get the public key.
fn public(&self) -> Public {
let mut r = [0u8; 32];
let pk = self.0.public.as_bytes();
r.copy_from_slice(pk);
Public(r)
// does this consume public? Is that why we used copy_from_slice?
let pk: [u8; 32] = self.public.into();
Public(pk)
}

/// Sign a message.
fn sign(&self, message: &[u8]) -> Signature {
let r = self.0.sign(message).to_bytes();
let r: [u8; 64] = self.secret.sign(message).into();
Signature::from_raw(r)
}

Expand All @@ -512,17 +514,17 @@ 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.
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()) {
let public_key = match VerificationKey::try_from(pubkey.as_ref()) {
Ok(pk) => pk,
Err(_) => return false,
};

let sig = match ed25519_dalek::Signature::try_from(sig) {
let sig = match ed25519_zebra::Signature::try_from(sig) {
Ok(s) => s,
Err(_) => return false
};

match public_key.verify(message.as_ref(), &sig) {
match public_key.verify(&sig, message.as_ref()) {
Ok(_) => true,
_ => false,
}
Expand All @@ -537,8 +539,8 @@ impl TraitPair for Pair {
#[cfg(feature = "full_crypto")]
impl Pair {
/// Get the seed for this key.
pub fn seed(&self) -> &Seed {
self.0.secret.as_bytes()
pub fn seed(&self) -> Seed {
self.secret.into()
}

/// Exactly as `from_string` except that if no matches are found then, the the first 32
Expand Down Expand Up @@ -588,12 +590,12 @@ mod test {
fn seed_and_derive_should_work() {
let seed = hex!("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60");
let pair = Pair::from_seed(&seed);
assert_eq!(pair.seed(), &seed);
assert_eq!(pair.seed(), seed);
let path = vec![DeriveJunction::Hard([0u8; 32])];
let derived = pair.derive(path.into_iter(), None).ok().unwrap().0;
assert_eq!(
derived.seed(),
&hex!("ede3354e133f9c8e337ddd6ee5415ed4b4ffe5fc7d21e933f4930a3730e5b21c")
hex!("ede3354e133f9c8e337ddd6ee5415ed4b4ffe5fc7d21e933f4930a3730e5b21c")
);
}

Expand Down

0 comments on commit cc921fd

Please sign in to comment.