diff --git a/Cargo.lock b/Cargo.lock index d79390dd..154ed008 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -235,17 +235,10 @@ dependencies = [ ] [[package]] -name = "curve25519-dalek-ng" -version = "4.1.1" +name = "ct-codecs" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core", - "subtle-ng", - "zeroize", -] +checksum = "f3b7eb4404b8195a9abb6356f4ac07d8ba267045c8d6d220ac4dc992e6cc75df" [[package]] name = "data-encoding" @@ -293,18 +286,13 @@ dependencies = [ ] [[package]] -name = "ed25519-consensus" -version = "2.0.1" +name = "ed25519-compact" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1dd91246c940272326f665724138660a183577ffb77b384a5e10d67d2d5075a" +checksum = "c25036262e9b9c81fe4c6decb438f753f66a8f06aac5dbe9eb2b28355c85c3f5" dependencies = [ - "curve25519-dalek-ng", - "hex", - "rand_core", - "serde", - "sha2 0.9.9", - "thiserror", - "zeroize", + "ct-codecs", + "getrandom", ] [[package]] @@ -418,12 +406,6 @@ dependencies = [ "libc", ] -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - [[package]] name = "home" version = "0.5.3" @@ -807,7 +789,7 @@ dependencies = [ "chrono", "colored", "crossbeam-channel", - "ed25519-consensus", + "ed25519-compact", "fastrand", "git-ref-format", "git-url", @@ -974,12 +956,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "subtle-ng" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" - [[package]] name = "syn" version = "1.0.99" @@ -1194,9 +1170,3 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "zeroize" -version = "1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" diff --git a/node/Cargo.toml b/node/Cargo.toml index 96564575..2ad0890a 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" [dependencies] anyhow = { version = "1" } bs58 = { version = "0.4.0" } -ed25519-consensus = { version = "2.0.1" } +ed25519-compact = { version = "1.0.12", features = ["pem"] } byteorder = { version = "1" } bloomy = { version = "1.2" } chrono = { version = "0.4.0" } diff --git a/node/src/crypto.rs b/node/src/crypto.rs index 4fb83744..07fcaee0 100644 --- a/node/src/crypto.rs +++ b/node/src/crypto.rs @@ -1,11 +1,11 @@ use std::sync::Arc; use std::{fmt, ops::Deref, str::FromStr}; -use ed25519_consensus as ed25519; +use ed25519_compact as ed25519; use serde::{Deserialize, Serialize}; use thiserror::Error; -pub use ed25519::Error; +pub use ed25519::{Error, KeyPair, Seed}; /// Verified (used as type witness). #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -54,7 +54,7 @@ pub struct Signature(pub ed25519::Signature); impl fmt::Display for Signature { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let base = multibase::Base::Base58Btc; - write!(f, "{}", multibase::encode(base, &self.to_bytes())) + write!(f, "{}", multibase::encode(base, self.deref())) } } @@ -83,7 +83,7 @@ impl FromStr for Signature { fn from_str(s: &str) -> Result { let (_, bytes) = multibase::decode(s)?; - let sig = ed25519::Signature::try_from(bytes.as_slice())?; + let sig = ed25519::Signature::from_slice(bytes.as_slice())?; Ok(Self(sig)) } @@ -99,7 +99,7 @@ impl Deref for Signature { impl From<[u8; 64]> for Signature { fn from(bytes: [u8; 64]) -> Self { - Self(ed25519::Signature::from(bytes)) + Self(ed25519::Signature::new(bytes)) } } @@ -107,17 +107,17 @@ impl TryFrom<&[u8]> for Signature { type Error = ed25519::Error; fn try_from(bytes: &[u8]) -> Result { - ed25519::Signature::try_from(bytes).map(Self) + ed25519::Signature::from_slice(bytes).map(Self) } } /// The public/verification key. #[derive(Serialize, Deserialize, Eq, Copy, Clone)] #[serde(into = "String", try_from = "String")] -pub struct PublicKey(pub ed25519::VerificationKey); +pub struct PublicKey(pub ed25519::PublicKey); /// The private/signing key. -pub type SecretKey = ed25519::SigningKey; +pub type SecretKey = ed25519::SecretKey; #[derive(Error, Debug)] pub enum PublicKeyError { @@ -126,12 +126,12 @@ pub enum PublicKeyError { #[error("invalid multibase string: {0}")] Multibase(#[from] multibase::Error), #[error("invalid key: {0}")] - InvalidKey(#[from] ed25519_consensus::Error), + InvalidKey(#[from] ed25519::Error), } impl std::hash::Hash for PublicKey { fn hash(&self, state: &mut H) { - self.0.as_bytes().hash(state) + self.0.deref().hash(state) } } @@ -159,8 +159,8 @@ impl PartialEq for PublicKey { } } -impl From for PublicKey { - fn from(other: ed25519::VerificationKey) -> Self { +impl From for PublicKey { + fn from(other: ed25519::PublicKey) -> Self { Self(other) } } @@ -169,13 +169,13 @@ impl TryFrom<[u8; 32]> for PublicKey { type Error = ed25519::Error; fn try_from(other: [u8; 32]) -> Result { - Ok(Self(ed25519::VerificationKey::try_from(other)?)) + Ok(Self(ed25519::PublicKey::new(other))) } } impl PublicKey { pub fn to_human(&self) -> String { - multibase::encode(multibase::Base::Base58Btc, &self.0) + multibase::encode(multibase::Base::Base58Btc, self.0.deref()) } } @@ -187,7 +187,7 @@ impl FromStr for PublicKey { let array: [u8; 32] = bytes .try_into() .map_err(|v: Vec| PublicKeyError::InvalidLength(v.len()))?; - let key = ed25519::VerificationKey::try_from(ed25519::VerificationKeyBytes::from(array))?; + let key = ed25519::PublicKey::new(array); Ok(Self(key)) } @@ -202,7 +202,7 @@ impl TryFrom for PublicKey { } impl Deref for PublicKey { - type Target = ed25519::VerificationKey; + type Target = ed25519::PublicKey; fn deref(&self) -> &Self::Target { &self.0 diff --git a/node/src/identity/doc.rs b/node/src/identity/doc.rs index b82043f4..71783ea3 100644 --- a/node/src/identity/doc.rs +++ b/node/src/identity/doc.rs @@ -443,7 +443,7 @@ impl Identity { // Keys that signed the *current* document version. signatures = trailers::parse_signatures(msg).unwrap(); for (pk, sig) in &signatures { - if let Err(err) = pk.verify(sig, blob.content()) { + if let Err(err) = pk.verify(blob.content(), sig) { return Err(IdentityError::InvalidSignature(*pk, err)); } } diff --git a/node/src/service/message.rs b/node/src/service/message.rs index ba07c784..21533381 100644 --- a/node/src/service/message.rs +++ b/node/src/service/message.rs @@ -85,7 +85,7 @@ impl NodeAnnouncement { /// Verify a signature on this message. pub fn verify(&self, signer: &NodeId, signature: &crypto::Signature) -> bool { let msg = wire::serialize(self); - signer.verify(signature, &msg).is_ok() + signer.verify(&msg, signature).is_ok() } } @@ -130,7 +130,7 @@ impl RefsAnnouncement { /// Verify a signature on this message. pub fn verify(&self, signer: &NodeId, signature: &crypto::Signature) -> bool { let msg = wire::serialize(self); - signer.verify(signature, &msg).is_ok() + signer.verify(&msg, signature).is_ok() } /// Sign this announcement. @@ -150,7 +150,7 @@ impl InventoryAnnouncement { /// Verify a signature on this message. pub fn verify(&self, signer: NodeId, signature: &crypto::Signature) -> bool { let msg = wire::serialize(self); - signer.verify(signature, &msg).is_ok() + signer.verify(&msg, signature).is_ok() } } diff --git a/node/src/storage/refs.rs b/node/src/storage/refs.rs index 4e09feee..52aaedd5 100644 --- a/node/src/storage/refs.rs +++ b/node/src/storage/refs.rs @@ -64,7 +64,7 @@ impl Refs { let refs = self; let msg = refs.canonical(); - match signer.verify(&signature, &msg) { + match signer.verify(&msg, &signature) { Ok(()) => Ok(SignedRefs { refs, signature, @@ -205,7 +205,7 @@ impl SignedRefs { pub fn verify(&self, signer: &PublicKey) -> Result<(), crypto::Error> { let canonical = self.refs.canonical(); - match signer.verify(&self.signature, &canonical) { + match signer.verify(&canonical, &self.signature) { Ok(()) => Ok(()), Err(e) => Err(e), } @@ -232,7 +232,7 @@ impl SignedRefs { let signature = repo.blob_at(oid, Path::new(SIGNATURE_BLOB_PATH))?; let signature: crypto::Signature = signature.content().try_into()?; - match remote.verify(&signature, refs.content()) { + match remote.verify(refs.content(), &signature) { Ok(()) => { let refs = Refs::from_canonical(refs.content())?; @@ -263,7 +263,7 @@ impl SignedRefs { let tree = { let raw = repo.raw(); let refs_blob_oid = raw.blob(&self.canonical())?; - let sig_blob_oid = raw.blob(&self.signature.to_bytes())?; + let sig_blob_oid = raw.blob(self.signature.as_ref())?; let mut builder = raw.treebuilder(None)?; builder.insert(REFS_BLOB_PATH, refs_blob_oid, 0o100_644)?; diff --git a/node/src/test/arbitrary.rs b/node/src/test/arbitrary.rs index 759e6b9b..08c14418 100644 --- a/node/src/test/arbitrary.rs +++ b/node/src/test/arbitrary.rs @@ -11,7 +11,7 @@ use quickcheck::Arbitrary; use crate::collections::HashMap; use crate::crypto; -use crate::crypto::{PublicKey, SecretKey, Signer, Unverified, Verified}; +use crate::crypto::{KeyPair, PublicKey, Seed, Signer, Unverified, Verified}; use crate::git; use crate::hash; use crate::identity::{doc::Delegate, doc::Doc, Did, Id, Project}; @@ -302,7 +302,10 @@ impl Arbitrary for storage::Remote { impl Arbitrary for MockSigner { fn arbitrary(g: &mut quickcheck::Gen) -> Self { let bytes: ByteArray<32> = Arbitrary::arbitrary(g); - MockSigner::from(SecretKey::from(bytes.into_inner())) + let seed = Seed::new(bytes.into_inner()); + let sk = KeyPair::from_seed(seed).sk; + + MockSigner::from(sk) } } @@ -324,12 +327,10 @@ impl Arbitrary for hash::Digest { impl Arbitrary for PublicKey { fn arbitrary(g: &mut quickcheck::Gen) -> Self { - use ed25519_consensus::SigningKey; - let bytes: ByteArray<32> = Arbitrary::arbitrary(g); - let sk = SigningKey::from(bytes.into_inner()); - let vk = sk.verification_key(); + let seed = Seed::new(bytes.into_inner()); + let keypair = KeyPair::from_seed(seed); - PublicKey(vk) + PublicKey(keypair.pk) } } diff --git a/node/src/test/crypto.rs b/node/src/test/crypto.rs index 65008c39..486b7901 100644 --- a/node/src/test/crypto.rs +++ b/node/src/test/crypto.rs @@ -1,4 +1,4 @@ -use crate::crypto::{PublicKey, SecretKey, Signature, Signer}; +use crate::crypto::{KeyPair, PublicKey, SecretKey, Seed, Signature, Signer}; #[derive(Debug, Clone)] pub struct MockSigner { @@ -13,24 +13,28 @@ impl MockSigner { for byte in &mut bytes { *byte = rng.u8(..); } - Self::from(SecretKey::from(bytes)) + let seed = Seed::new(bytes); + let keypair = KeyPair::from_seed(seed); + + Self::from(keypair.sk) } } impl From for MockSigner { fn from(sk: SecretKey) -> Self { - let pk = sk.verification_key().into(); + let pk = sk.public_key().into(); Self { sk, pk } } } impl Default for MockSigner { fn default() -> Self { - let bytes: [u8; 32] = [0; 32]; - let sk = SecretKey::from(bytes); + let seed = Seed::generate(); + let keypair = KeyPair::from_seed(seed); + let sk = keypair.sk; Self { - pk: sk.verification_key().into(), + pk: sk.public_key().into(), sk, } } @@ -56,6 +60,6 @@ impl Signer for MockSigner { } fn sign(&self, msg: &[u8]) -> Signature { - self.sk.sign(msg).into() + self.sk.sign(msg, None).into() } } diff --git a/node/src/wire.rs b/node/src/wire.rs index 8a307c79..b95cfad0 100644 --- a/node/src/wire.rs +++ b/node/src/wire.rs @@ -137,7 +137,7 @@ impl Encode for usize { impl Encode for PublicKey { fn encode(&self, writer: &mut W) -> Result { - self.as_bytes().encode(writer) + self.deref().encode(writer) } } @@ -224,7 +224,7 @@ impl Encode for Refs { impl Encode for Signature { fn encode(&self, writer: &mut W) -> Result { - self.to_bytes().encode(writer) + self.deref().encode(writer) } }