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

Commit cf36d2f

Browse files
jakehemmerlegilescopebkchrdavxy
authored
swap ed25519-dalek for ed25519-zebra (#11781)
* swap ed25519-dalek for ed25519-zebra; no batch verificaiton fixed batch verificaiton tests removed additional zero verificaiton tests removed comments, fixed test bug, added #[derive(Clone)] Update primitives/core/src/ed25519.rs Co-authored-by: Squirrel <gilescope@gmail.com> * modified assertion to allow default ed25519-zebra zero key behavior * cargo clippy * Update primitives/core/Cargo.toml Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * Update primitives/core/src/ed25519.rs Co-authored-by: Davide Galassi <davxy@datawok.net> * Update primitives/core/src/ed25519.rs Co-authored-by: Davide Galassi <davxy@datawok.net> * Update primitives/core/src/ed25519.rs Co-authored-by: Davide Galassi <davxy@datawok.net> * Update primitives/core/src/ed25519.rs Co-authored-by: Davide Galassi <davxy@datawok.net> * updated Cargo.lock for sp-core * fix inaccurate comment Co-authored-by: Squirrel <gilescope@gmail.com> Co-authored-by: Bastian Köcher <info@kchr.de> Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> Co-authored-by: Davide Galassi <davxy@datawok.net>
1 parent 669ed36 commit cf36d2f

File tree

5 files changed

+57
-45
lines changed

5 files changed

+57
-45
lines changed

Cargo.lock

Lines changed: 15 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ crc32fast = { opt-level = 3 }
258258
crossbeam-deque = { opt-level = 3 }
259259
crypto-mac = { opt-level = 3 }
260260
curve25519-dalek = { opt-level = 3 }
261-
ed25519-dalek = { opt-level = 3 }
261+
ed25519-zebra = { opt-level = 3 }
262262
flate2 = { opt-level = 3 }
263263
futures-channel = { opt-level = 3 }
264264
hashbrown = { opt-level = 3 }

primitives/core/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ thiserror = { version = "1.0.30", optional = true }
4747
bitflags = "1.3"
4848

4949
# full crypto
50-
ed25519-dalek = { version = "1.0.1", default-features = false, features = ["u64_backend", "alloc"], optional = true }
50+
ed25519-zebra = { version = "3.0.0", default-features = false, optional = true}
5151
blake2-rfc = { version = "0.2.18", default-features = false, optional = true }
5252
schnorrkel = { version = "0.9.1", features = [
5353
"preaudit_deprecated",
@@ -97,7 +97,7 @@ std = [
9797
"sp-std/std",
9898
"serde",
9999
"blake2-rfc/std",
100-
"ed25519-dalek/std",
100+
"ed25519-zebra",
101101
"hex/std",
102102
"base58",
103103
"substrate-bip39",
@@ -127,7 +127,7 @@ std = [
127127
# or Intel SGX.
128128
# For the regular wasm runtime builds this should not be used.
129129
full_crypto = [
130-
"ed25519-dalek",
130+
"ed25519-zebra",
131131
"blake2-rfc",
132132
"schnorrkel",
133133
"hex",

primitives/core/src/ed25519.rs

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ use crate::crypto::{DeriveJunction, Pair as TraitPair, SecretStringError};
3939
#[cfg(feature = "std")]
4040
use bip39::{Language, Mnemonic, MnemonicType};
4141
#[cfg(feature = "full_crypto")]
42-
use ed25519_dalek::{Signer as _, Verifier as _};
42+
use core::convert::TryFrom;
43+
#[cfg(feature = "full_crypto")]
44+
use ed25519_zebra::{SigningKey, VerificationKey};
4345
#[cfg(feature = "std")]
4446
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
4547
use sp_runtime_interface::pass_by::PassByInner;
@@ -75,17 +77,10 @@ pub struct Public(pub [u8; 32]);
7577

7678
/// A key pair.
7779
#[cfg(feature = "full_crypto")]
78-
pub struct Pair(ed25519_dalek::Keypair);
79-
80-
#[cfg(feature = "full_crypto")]
81-
impl Clone for Pair {
82-
fn clone(&self) -> Self {
83-
Pair(ed25519_dalek::Keypair {
84-
public: self.0.public,
85-
secret: ed25519_dalek::SecretKey::from_bytes(self.0.secret.as_bytes())
86-
.expect("key is always the correct size; qed"),
87-
})
88-
}
80+
#[derive(Copy, Clone)]
81+
pub struct Pair {
82+
public: VerificationKey,
83+
secret: SigningKey,
8984
}
9085

9186
impl AsRef<[u8; 32]> for Public {
@@ -456,10 +451,10 @@ impl TraitPair for Pair {
456451
///
457452
/// You should never need to use this; generate(), generate_with_phrase
458453
fn from_seed_slice(seed_slice: &[u8]) -> Result<Pair, SecretStringError> {
459-
let secret = ed25519_dalek::SecretKey::from_bytes(seed_slice)
460-
.map_err(|_| SecretStringError::InvalidSeedLength)?;
461-
let public = ed25519_dalek::PublicKey::from(&secret);
462-
Ok(Pair(ed25519_dalek::Keypair { secret, public }))
454+
let secret =
455+
SigningKey::try_from(seed_slice).map_err(|_| SecretStringError::InvalidSeedLength)?;
456+
let public = VerificationKey::from(&secret);
457+
Ok(Pair { secret, public })
463458
}
464459

465460
/// Derive a child key from a series of given junctions.
@@ -468,7 +463,7 @@ impl TraitPair for Pair {
468463
path: Iter,
469464
_seed: Option<Seed>,
470465
) -> Result<(Pair, Option<Seed>), DeriveError> {
471-
let mut acc = self.0.secret.to_bytes();
466+
let mut acc = self.secret.into();
472467
for j in path {
473468
match j {
474469
DeriveJunction::Soft(_cc) => return Err(DeriveError::SoftKeyInPath),
@@ -480,16 +475,12 @@ impl TraitPair for Pair {
480475

481476
/// Get the public key.
482477
fn public(&self) -> Public {
483-
let mut r = [0u8; 32];
484-
let pk = self.0.public.as_bytes();
485-
r.copy_from_slice(pk);
486-
Public(r)
478+
Public(self.public.into())
487479
}
488480

489481
/// Sign a message.
490482
fn sign(&self, message: &[u8]) -> Signature {
491-
let r = self.0.sign(message).to_bytes();
492-
Signature::from_raw(r)
483+
Signature::from_raw(self.secret.sign(message).into())
493484
}
494485

495486
/// Verify a signature on a message. Returns true if the signature is good.
@@ -502,17 +493,17 @@ impl TraitPair for Pair {
502493
/// This doesn't use the type system to ensure that `sig` and `pubkey` are the correct
503494
/// size. Use it only if you're coming from byte buffers and need the speed.
504495
fn verify_weak<P: AsRef<[u8]>, M: AsRef<[u8]>>(sig: &[u8], message: M, pubkey: P) -> bool {
505-
let public_key = match ed25519_dalek::PublicKey::from_bytes(pubkey.as_ref()) {
496+
let public_key = match VerificationKey::try_from(pubkey.as_ref()) {
506497
Ok(pk) => pk,
507498
Err(_) => return false,
508499
};
509500

510-
let sig = match ed25519_dalek::Signature::try_from(sig) {
501+
let sig = match ed25519_zebra::Signature::try_from(sig) {
511502
Ok(s) => s,
512503
Err(_) => return false,
513504
};
514505

515-
public_key.verify(message.as_ref(), &sig).is_ok()
506+
public_key.verify(&sig, message.as_ref()).is_ok()
516507
}
517508

518509
/// Return a vec filled with raw data.
@@ -524,8 +515,8 @@ impl TraitPair for Pair {
524515
#[cfg(feature = "full_crypto")]
525516
impl Pair {
526517
/// Get the seed for this key.
527-
pub fn seed(&self) -> &Seed {
528-
self.0.secret.as_bytes()
518+
pub fn seed(&self) -> Seed {
519+
self.secret.into()
529520
}
530521

531522
/// Exactly as `from_string` except that if no matches are found then, the the first 32
@@ -577,12 +568,12 @@ mod test {
577568
fn seed_and_derive_should_work() {
578569
let seed = hex!("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60");
579570
let pair = Pair::from_seed(&seed);
580-
assert_eq!(pair.seed(), &seed);
571+
assert_eq!(pair.seed(), seed);
581572
let path = vec![DeriveJunction::Hard([0u8; 32])];
582573
let derived = pair.derive(path.into_iter(), None).ok().unwrap().0;
583574
assert_eq!(
584575
derived.seed(),
585-
&hex!("ede3354e133f9c8e337ddd6ee5415ed4b4ffe5fc7d21e933f4930a3730e5b21c")
576+
hex!("ede3354e133f9c8e337ddd6ee5415ed4b4ffe5fc7d21e933f4930a3730e5b21c")
586577
);
587578
}
588579

primitives/io/src/lib.rs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1895,15 +1895,18 @@ mod tests {
18951895
ext.register_extension(TaskExecutorExt::new(TaskExecutor::new()));
18961896
ext.execute_with(|| {
18971897
let pair = sr25519::Pair::generate_with_phrase(None).0;
1898+
let pair_unused = sr25519::Pair::generate_with_phrase(None).0;
18981899
crypto::start_batch_verify();
18991900
for it in 0..70 {
19001901
let msg = format!("Schnorrkel {}!", it);
19011902
let signature = pair.sign(msg.as_bytes());
19021903
crypto::sr25519_batch_verify(&signature, msg.as_bytes(), &pair.public());
19031904
}
19041905

1905-
// push invlaid
1906-
crypto::sr25519_batch_verify(&zero_sr_sig(), &Vec::new(), &zero_sr_pub());
1906+
// push invalid
1907+
let msg = b"asdf!";
1908+
let signature = pair.sign(msg);
1909+
crypto::sr25519_batch_verify(&signature, msg, &pair_unused.public());
19071910
assert!(!crypto::finish_batch_verify());
19081911

19091912
crypto::start_batch_verify();
@@ -1938,10 +1941,10 @@ mod tests {
19381941
ext.register_extension(TaskExecutorExt::new(TaskExecutor::new()));
19391942

19401943
ext.execute_with(|| {
1941-
// invalid ed25519 signature
1944+
// valid ed25519 signature
19421945
crypto::start_batch_verify();
19431946
crypto::ed25519_batch_verify(&zero_ed_sig(), &Vec::new(), &zero_ed_pub());
1944-
assert!(!crypto::finish_batch_verify());
1947+
assert!(crypto::finish_batch_verify());
19451948

19461949
// 2 valid ed25519 signatures
19471950
crypto::start_batch_verify();
@@ -1961,12 +1964,14 @@ mod tests {
19611964
// 1 valid, 1 invalid ed25519 signature
19621965
crypto::start_batch_verify();
19631966

1964-
let pair = ed25519::Pair::generate_with_phrase(None).0;
1967+
let pair1 = ed25519::Pair::generate_with_phrase(None).0;
1968+
let pair2 = ed25519::Pair::generate_with_phrase(None).0;
19651969
let msg = b"Important message";
1966-
let signature = pair.sign(msg);
1967-
crypto::ed25519_batch_verify(&signature, msg, &pair.public());
1970+
let signature = pair1.sign(msg);
19681971

19691972
crypto::ed25519_batch_verify(&zero_ed_sig(), &Vec::new(), &zero_ed_pub());
1973+
crypto::ed25519_batch_verify(&signature, msg, &pair1.public());
1974+
crypto::ed25519_batch_verify(&signature, msg, &pair2.public());
19701975

19711976
assert!(!crypto::finish_batch_verify());
19721977

@@ -1993,11 +1998,13 @@ mod tests {
19931998
// 1 valid sr25519, 1 invalid sr25519
19941999
crypto::start_batch_verify();
19952000

1996-
let pair = sr25519::Pair::generate_with_phrase(None).0;
2001+
let pair1 = sr25519::Pair::generate_with_phrase(None).0;
2002+
let pair2 = sr25519::Pair::generate_with_phrase(None).0;
19972003
let msg = b"Schnorrkcel!";
1998-
let signature = pair.sign(msg);
1999-
crypto::sr25519_batch_verify(&signature, msg, &pair.public());
2004+
let signature = pair1.sign(msg);
20002005

2006+
crypto::sr25519_batch_verify(&signature, msg, &pair1.public());
2007+
crypto::sr25519_batch_verify(&signature, msg, &pair2.public());
20012008
crypto::sr25519_batch_verify(&zero_sr_sig(), &Vec::new(), &zero_sr_pub());
20022009

20032010
assert!(!crypto::finish_batch_verify());

0 commit comments

Comments
 (0)