From 2d4024523d79c8bbc0ed7317e264288003a04f3e Mon Sep 17 00:00:00 2001 From: aya015757881 <2581015450@qq.com> Date: Tue, 10 Dec 2024 10:25:09 +0800 Subject: [PATCH 1/6] feat: ed25519 private key derivation --- .../extended_key/extended_private_key.rs | 4 ++ crates/anychain-kms/src/bip32/mod.rs | 2 +- crates/anychain-kms/src/bip32/private_key.rs | 68 ++++++++++++++++--- 3 files changed, 64 insertions(+), 10 deletions(-) diff --git a/crates/anychain-kms/src/bip32/extended_key/extended_private_key.rs b/crates/anychain-kms/src/bip32/extended_key/extended_private_key.rs index e17a9b3..97c21a1 100644 --- a/crates/anychain-kms/src/bip32/extended_key/extended_private_key.rs +++ b/crates/anychain-kms/src/bip32/extended_key/extended_private_key.rs @@ -8,6 +8,7 @@ use core::{ fmt::{self, Debug}, str::FromStr, }; +use curve25519_dalek::scalar::Scalar; //use hmac::{Mac, NewMac}; use hmac::Mac; use subtle::{Choice, ConstantTimeEq}; @@ -27,6 +28,9 @@ const BIP39_DOMAIN_SEPARATOR: [u8; 12] = [ /// Extended private secp256k1 ECDSA signing key. pub type XprvSecp256k1 = ExtendedPrivateKey; +/// Extended private ed25519 signing key. +pub type XprvEd25519 = ExtendedPrivateKey; + /// Extended private keys derived using BIP32. /// /// Generic around a [`PrivateKey`] type. When the `secp256k1` feature of this diff --git a/crates/anychain-kms/src/bip32/mod.rs b/crates/anychain-kms/src/bip32/mod.rs index c1d91de..b1ace93 100644 --- a/crates/anychain-kms/src/bip32/mod.rs +++ b/crates/anychain-kms/src/bip32/mod.rs @@ -13,7 +13,7 @@ pub use extended_key::{ extended_public_key::ExtendedPublicKey, ExtendedKey, }; pub use extended_key::{ - extended_private_key::XprvSecp256k1, + extended_private_key::{XprvEd25519, XprvSecp256k1}, extended_public_key::{XpubEd25519, XpubSecp256k1}, }; pub use prefix::Prefix; diff --git a/crates/anychain-kms/src/bip32/private_key.rs b/crates/anychain-kms/src/bip32/private_key.rs index 70c2a0c..e63c46d 100644 --- a/crates/anychain-kms/src/bip32/private_key.rs +++ b/crates/anychain-kms/src/bip32/private_key.rs @@ -1,10 +1,9 @@ //! Trait for deriving child keys on a given type. -use crate::bip32::{PublicKey, Result}; +use crate::bip32::{Error, PublicKey, Result, XprvEd25519, XprvSecp256k1}; -use crate::bip32::{Error, XprvSecp256k1}; - -use libsecp256k1; +use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE as G, scalar::Scalar}; +use group::GroupEncoding; /// Trait for key types which can be derived using BIP32. pub trait PrivateKey: Sized { @@ -65,16 +64,51 @@ impl From<&XprvSecp256k1> for libsecp256k1::SecretKey { } } +impl PrivateKey for Scalar { + type PublicKey = ed25519_dalek::PublicKey; + + fn from_bytes(bytes: Vec) -> Result { + let mut sk = [0u8; 32]; + sk.copy_from_slice(&bytes); + Ok(Scalar::from_bytes_mod_order(sk)) + } + + fn to_bytes(&self) -> Vec { + self.to_bytes().to_vec() + } + + fn derive_child(&self, tweak: Vec) -> Result { + let mut _tweak = [0u8; 32]; + _tweak.copy_from_slice(&tweak); + let tweak = Scalar::from_bytes_mod_order(_tweak); + Ok(self + tweak) + } + + fn public_key(&self) -> Self::PublicKey { + let pk = (G * self).to_bytes(); + ed25519_dalek::PublicKey::from_bytes(&pk).unwrap() + } +} + +impl From for Scalar { + fn from(xprv: XprvEd25519) -> Scalar { + Scalar::from(&xprv) + } +} + +impl From<&XprvEd25519> for Scalar { + fn from(xprv: &XprvEd25519) -> Scalar { + *xprv.private_key() + } +} + #[cfg(test)] mod tests { + use super::{XprvEd25519, XprvSecp256k1}; use hex_literal::hex; - //type XprvSecp256k1 = crate::bip32::ExtendedPrivateKey; - - type XprvSecp256k1 = crate::bip32::ExtendedPrivateKey; - #[test] - fn secp256k1_derivation() { + fn test_secp256k1_derivation() { let seed = hex!( "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a2 9f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542" @@ -88,4 +122,20 @@ mod tests { "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j".parse().unwrap() ); } + + #[test] + fn test_ed25519_derivation() { + let seed = hex!( + "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a2 + 9f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542" + ); + + let path = "m/0/2147483647'/1/2147483646'/2"; + let xprv = XprvEd25519::new_from_path(seed, &path.parse().unwrap()).unwrap(); + + assert_eq!( + xprv, + "xprvA3jRL3NoAajWVMc6JWKPgQrxx5Xt6VVpgj8y6FMcBbseE4DkZEP8cfVqJQtQvyCqZpb39KZE5r7UUGwunJg9m3wksLj5x94cJv4ahGMarGU".parse().unwrap() + ); + } } From 92d2f1a9ac590dd379d44ff7329ee56929640cde Mon Sep 17 00:00:00 2001 From: aya015757881 <2581015450@qq.com> Date: Tue, 10 Dec 2024 10:26:10 +0800 Subject: [PATCH 2/6] refactor: version update --- Cargo.lock | 2 +- crates/anychain-kms/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b6887c..1c816a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -241,7 +241,7 @@ dependencies = [ [[package]] name = "anychain-kms" -version = "0.1.13" +version = "0.1.14" dependencies = [ "anyhow", "bs58 0.4.0", diff --git a/crates/anychain-kms/Cargo.toml b/crates/anychain-kms/Cargo.toml index 67e97c1..056f223 100644 --- a/crates/anychain-kms/Cargo.toml +++ b/crates/anychain-kms/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "anychain-kms" description = "A Rust library providing Key Management Schema for AnyChain. Handles general security and signature algorithms." -version = "0.1.13" +version = "0.1.14" keywords = ["cryptography", "security", "signature", "algorithm"] categories = ["cryptography::cryptocurrencies"] From 5bd91cede37dc1e7a09809f51996d4b4200af061 Mon Sep 17 00:00:00 2001 From: aya015757881 <2581015450@qq.com> Date: Tue, 10 Dec 2024 10:28:53 +0800 Subject: [PATCH 3/6] refactor: remove useless code --- .../anychain-kms/src/bip32/extended_key/extended_private_key.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/anychain-kms/src/bip32/extended_key/extended_private_key.rs b/crates/anychain-kms/src/bip32/extended_key/extended_private_key.rs index 97c21a1..30fae48 100644 --- a/crates/anychain-kms/src/bip32/extended_key/extended_private_key.rs +++ b/crates/anychain-kms/src/bip32/extended_key/extended_private_key.rs @@ -9,7 +9,6 @@ use core::{ str::FromStr, }; use curve25519_dalek::scalar::Scalar; -//use hmac::{Mac, NewMac}; use hmac::Mac; use subtle::{Choice, ConstantTimeEq}; use zeroize::Zeroize; From 52d44a7178439936b14fc78847d7ed7968cbeaf4 Mon Sep 17 00:00:00 2001 From: aya015757881 <2581015450@qq.com> Date: Tue, 10 Dec 2024 10:30:00 +0800 Subject: [PATCH 4/6] refactor: annotation --- .../anychain-kms/src/bip32/extended_key/extended_private_key.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/anychain-kms/src/bip32/extended_key/extended_private_key.rs b/crates/anychain-kms/src/bip32/extended_key/extended_private_key.rs index 30fae48..a3a51f1 100644 --- a/crates/anychain-kms/src/bip32/extended_key/extended_private_key.rs +++ b/crates/anychain-kms/src/bip32/extended_key/extended_private_key.rs @@ -24,7 +24,7 @@ const BIP39_DOMAIN_SEPARATOR: [u8; 12] = [ 0x42, 0x69, 0x74, 0x63, 0x6f, 0x69, 0x6e, 0x20, 0x73, 0x65, 0x65, 0x64, ]; -/// Extended private secp256k1 ECDSA signing key. +/// Extended private secp256k1 signing key. pub type XprvSecp256k1 = ExtendedPrivateKey; /// Extended private ed25519 signing key. From 9912e21bb5ba66fab33f467608cbca9394d16165 Mon Sep 17 00:00:00 2001 From: aya015757881 <2581015450@qq.com> Date: Tue, 10 Dec 2024 12:52:58 +0800 Subject: [PATCH 5/6] fix: adapt ed25519 public key to 33-byte length --- .../src/bip32/extended_key/extended_private_key.rs | 5 ++--- .../src/bip32/extended_key/extended_public_key.rs | 9 +++++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/crates/anychain-kms/src/bip32/extended_key/extended_private_key.rs b/crates/anychain-kms/src/bip32/extended_key/extended_private_key.rs index a3a51f1..6121855 100644 --- a/crates/anychain-kms/src/bip32/extended_key/extended_private_key.rs +++ b/crates/anychain-kms/src/bip32/extended_key/extended_private_key.rs @@ -1,8 +1,7 @@ //! Extended private keys use crate::bip32::{ - ChildNumber, Depth, Error, ExtendedKey, ExtendedKeyAttrs, ExtendedPublicKey, HmacSha512, - KeyFingerprint, Prefix, PrivateKey, PublicKey, Result, KEY_SIZE, + ChildNumber, Depth, Error, ExtendedKey, ExtendedKeyAttrs, ExtendedPublicKey, HmacSha512, KeyFingerprint, Prefix, PrivateKey, PublicKey, Result, XpubEd25519, XpubSecp256k1, KEY_SIZE }; use core::{ fmt::{self, Debug}, @@ -250,4 +249,4 @@ where Err(Error::Crypto) } } -} +} \ No newline at end of file diff --git a/crates/anychain-kms/src/bip32/extended_key/extended_public_key.rs b/crates/anychain-kms/src/bip32/extended_key/extended_public_key.rs index 9ad7f04..8abf36c 100644 --- a/crates/anychain-kms/src/bip32/extended_key/extended_public_key.rs +++ b/crates/anychain-kms/src/bip32/extended_key/extended_public_key.rs @@ -96,7 +96,12 @@ where attrs: self.attrs.clone(), key_bytes: { let mut key_bytes = [0u8; KEY_SIZE + 1]; - key_bytes.copy_from_slice(&self.to_bytes()); + let bytes = self.to_bytes(); + let bytes = match bytes.len() { + KEY_SIZE => [vec![0u8], bytes].concat(), + _ => bytes, + }; + key_bytes.copy_from_slice(&bytes); key_bytes }, } @@ -148,4 +153,4 @@ where Err(Error::Crypto) } } -} +} \ No newline at end of file From 85a69f799b45f756026c9441c9c95c9f9f10783d Mon Sep 17 00:00:00 2001 From: aya015757881 <2581015450@qq.com> Date: Tue, 10 Dec 2024 12:56:39 +0800 Subject: [PATCH 6/6] style: cargo fmt --- .../src/bip32/extended_key/extended_private_key.rs | 5 +++-- .../src/bip32/extended_key/extended_public_key.rs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/crates/anychain-kms/src/bip32/extended_key/extended_private_key.rs b/crates/anychain-kms/src/bip32/extended_key/extended_private_key.rs index 6121855..a3a51f1 100644 --- a/crates/anychain-kms/src/bip32/extended_key/extended_private_key.rs +++ b/crates/anychain-kms/src/bip32/extended_key/extended_private_key.rs @@ -1,7 +1,8 @@ //! Extended private keys use crate::bip32::{ - ChildNumber, Depth, Error, ExtendedKey, ExtendedKeyAttrs, ExtendedPublicKey, HmacSha512, KeyFingerprint, Prefix, PrivateKey, PublicKey, Result, XpubEd25519, XpubSecp256k1, KEY_SIZE + ChildNumber, Depth, Error, ExtendedKey, ExtendedKeyAttrs, ExtendedPublicKey, HmacSha512, + KeyFingerprint, Prefix, PrivateKey, PublicKey, Result, KEY_SIZE, }; use core::{ fmt::{self, Debug}, @@ -249,4 +250,4 @@ where Err(Error::Crypto) } } -} \ No newline at end of file +} diff --git a/crates/anychain-kms/src/bip32/extended_key/extended_public_key.rs b/crates/anychain-kms/src/bip32/extended_key/extended_public_key.rs index 8abf36c..b1f5b55 100644 --- a/crates/anychain-kms/src/bip32/extended_key/extended_public_key.rs +++ b/crates/anychain-kms/src/bip32/extended_key/extended_public_key.rs @@ -153,4 +153,4 @@ where Err(Error::Crypto) } } -} \ No newline at end of file +}