diff --git a/token-core/tcx-eth2/src/signer.rs b/token-core/tcx-eth2/src/signer.rs index 2c38992d..31251f39 100644 --- a/token-core/tcx-eth2/src/signer.rs +++ b/token-core/tcx-eth2/src/signer.rs @@ -31,7 +31,7 @@ impl SignBlsToExecutionChangeParam { bls_to_execution_request.validator_index = *validator_index; let message = bls_to_execution_request.generate_bls_to_execution_change_hash()?; - let signature = keystore.bls_sign_specified_alg( + let signature = keystore.bls_sign( Vec::from_hex_auto(&message)?.as_slice(), "m/12381/3600/0/0", "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_", diff --git a/token-core/tcx-filecoin/src/signer.rs b/token-core/tcx-filecoin/src/signer.rs index 152a225b..069383fc 100644 --- a/token-core/tcx-filecoin/src/signer.rs +++ b/token-core/tcx-filecoin/src/signer.rs @@ -79,7 +79,11 @@ impl TransactionSigner for Keystore { } CurveType::BLS => { signature_type = 2; - signature = self.bls_sign(&cid.to_bytes(), &sign_context.derivation_path)?; + signature = self.bls_sign( + &cid.to_bytes(), + &sign_context.derivation_path, + "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_", + )?; cid = unsigned_message.cid()?; } _ => return Err(Error::InvalidCurveType.into()), diff --git a/token-core/tcx-keystore/src/keystore/mod.rs b/token-core/tcx-keystore/src/keystore/mod.rs index f1b0ecdb..d31f33ad 100644 --- a/token-core/tcx-keystore/src/keystore/mod.rs +++ b/token-core/tcx-keystore/src/keystore/mod.rs @@ -455,23 +455,10 @@ impl Signer for Keystore { ) -> Result> { match (curve, sig_alg.to_uppercase().as_str()) { ("secp256k1", "ECDSA") => self.secp256k1_ecdsa_sign_recoverable(hash, derivation_path), - ("bls12-381", "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_") => { - self.bls_sign(hash, derivation_path) - } - ("bls12-381", "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_") => self - .bls_sign_specified_alg( - hash, - derivation_path, - "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_", - ), - (curve, _) => { - let curve_type = CurveType::from_str(curve); - let private_key = match self { - Keystore::PrivateKey(ks) => ks.get_private_key(curve_type)?, - Keystore::Hd(ks) => ks.get_private_key(curve_type, derivation_path)?, - }; - private_key.sign(hash) - } + ("bls12-381", dst) => self.bls_sign(hash, derivation_path, dst), + ("ed25519", _) => self.ed25519_sign(hash, derivation_path), + ("sr25519", _) => self.sr25519_sign(hash, derivation_path), + (_, _) => Err(anyhow!("unsupported curve: {} sig_alg: {}", curve, sig_alg)), } } @@ -485,29 +472,16 @@ impl Signer for Keystore { Keystore::Hd(ks) => ks.get_private_key(CurveType::SECP256k1, derivation_path)?, }; - private_key.sign_recoverable(hash) + private_key.as_secp256k1()?.sign_recoverable(hash) } - fn bls_sign(&mut self, hash: &[u8], derivation_path: &str) -> Result> { + fn bls_sign(&mut self, hash: &[u8], derivation_path: &str, dst: &str) -> Result> { let private_key = match self { Keystore::PrivateKey(ks) => ks.get_private_key(CurveType::BLS)?, Keystore::Hd(ks) => ks.get_private_key(CurveType::BLS, derivation_path)?, }; - private_key.sign(hash) - } - - fn bls_sign_specified_alg( - &mut self, - hash: &[u8], - derivation_path: &str, - sig_alg: &str, - ) -> Result> { - let private_key: TypedPrivateKey = match self { - Keystore::PrivateKey(ks) => ks.get_private_key(CurveType::BLS)?, - Keystore::Hd(ks) => ks.get_private_key(CurveType::BLS, derivation_path)?, - }; - private_key.sign_specified_hash(hash, sig_alg) + private_key.as_bls()?.sign(hash, dst) } fn sr25519_sign(&mut self, hash: &[u8], derivation_path: &str) -> Result> { @@ -516,11 +490,16 @@ impl Signer for Keystore { Keystore::Hd(ks) => ks.get_private_key(CurveType::SR25519, derivation_path)?, }; - private_key.sign(hash) + private_key.as_sr25519()?.sign(hash) } - fn schnorr_sign(&mut self, _hash: &[u8], _derivation_path: &str) -> Result> { - todo!() + fn ed25519_sign(&mut self, hash: &[u8], derivation_path: &str) -> Result> { + let private_key = match self { + Keystore::PrivateKey(ks) => ks.get_private_key(CurveType::ED25519)?, + Keystore::Hd(ks) => ks.get_private_key(CurveType::ED25519, derivation_path)?, + }; + + private_key.as_ed25519()?.sign(hash) } } diff --git a/token-core/tcx-keystore/src/signer.rs b/token-core/tcx-keystore/src/signer.rs index 09588d9d..bdc0e3e2 100644 --- a/token-core/tcx-keystore/src/signer.rs +++ b/token-core/tcx-keystore/src/signer.rs @@ -52,16 +52,9 @@ pub trait Signer { derivation_path: &str, ) -> Result>; - fn bls_sign(&mut self, hash: &[u8], derivation_path: &str) -> Result>; - - fn bls_sign_specified_alg( - &mut self, - hash: &[u8], - derivation_path: &str, - sig_alg: &str, - ) -> Result>; + fn bls_sign(&mut self, hash: &[u8], derivation_path: &str, dst: &str) -> Result>; fn sr25519_sign(&mut self, hash: &[u8], derivation_path: &str) -> Result>; - fn schnorr_sign(&mut self, hash: &[u8], derivation_path: &str) -> Result>; + fn ed25519_sign(&mut self, hash: &[u8], derivation_path: &str) -> Result>; } diff --git a/token-core/tcx-primitive/src/bls.rs b/token-core/tcx-primitive/src/bls.rs index 1cea97f1..bff84a5c 100644 --- a/token-core/tcx-primitive/src/bls.rs +++ b/token-core/tcx-primitive/src/bls.rs @@ -20,6 +20,18 @@ impl From for BLSPrivateKey { } } +impl BLSPrivateKey { + pub const DEFAULT_DST: &'static str = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_"; + + pub fn sign(&self, message: &[u8], dst: &str) -> Result> { + Ok(self + .0 + .sign(message, dst.as_bytes(), &[]) + .compress() + .to_vec()) + } +} + impl TraitPrivateKey for BLSPrivateKey { type PublicKey = BLSPublicKey; @@ -44,26 +56,6 @@ impl TraitPrivateKey for BLSPrivateKey { BLSPublicKey(self.0.sk_to_pk()) } - fn sign(&self, message: &[u8]) -> Result> { - Ok(self - .0 - .sign(message, b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_", &[]) - .compress() - .to_vec()) - } - - fn sign_specified_hash(&self, message: &[u8], dst: &str) -> Result> { - Ok(self - .0 - .sign(message, dst.as_bytes(), &[]) - .compress() - .to_vec()) - } - - fn sign_recoverable(&self, _: &[u8]) -> Result> { - Err(KeyError::NotImplement.into()) - } - fn to_bytes(&self) -> Vec { let mut private_key = self.0.serialize().to_vec(); private_key.reverse(); @@ -143,11 +135,6 @@ mod tests { #[test] fn test_bls_sign() { - // let private_key = BLSPrivateKey::from_slice( - // &Vec::from_hex("068dce0c90cb428ab37a74af0191eac49648035f1aaef077734b91e05985ec55") - // .unwrap(), - // ) - // .unwrap(); let mut sec_key_bytes = Vec::from_hex("068dce0c90cb428ab37a74af0191eac49648035f1aaef077734b91e05985ec55") .unwrap(); @@ -156,17 +143,10 @@ mod tests { let message = Vec::from_hex("23ba0fe9dc5d2fae789f31fdccb4e28e74b89aec26bafdd6c96ced598542f53e") .unwrap(); - let sign_result = private_key.sign_specified_hash( + let sign_result = private_key.sign( message.clone().as_slice(), "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_", ); - assert_eq!(sign_result.unwrap().to_hex(), - "8c8ce9f8aedf380e47548501d348afa28fbfc282f50edf33555a3ed72eb24d710bc527b5108022cffb764b953941ec4014c44106d2708387d26cc84cbc5c546a1e6e56fdc194cf2649719e6ac149596d80c86bf6844b36bd47038ee96dd3962f"); - let sign_result = private_key.sign_recoverable(message.as_slice()); - assert_eq!( - sign_result.err().unwrap().to_string(), - KeyError::NotImplement.to_string() - ); } #[test] diff --git a/token-core/tcx-primitive/src/ecc.rs b/token-core/tcx-primitive/src/ecc.rs index c3de82c8..1dece65d 100644 --- a/token-core/tcx-primitive/src/ecc.rs +++ b/token-core/tcx-primitive/src/ecc.rs @@ -52,8 +52,6 @@ pub enum KeyError { InvalidEd25519Key, #[error("unsupport_ed25519_pubkey_derivation")] UnsupportEd25519PubkeyDerivation, - #[error("unsupport_normal_derivation")] - UnsupportNormalDerivation, #[error("not_implement")] NotImplement, #[error("secp256k1_error")] @@ -83,12 +81,6 @@ pub trait PrivateKey: Sized { fn public_key(&self) -> Self::PublicKey; - fn sign(&self, _: &[u8]) -> Result>; - - fn sign_specified_hash(&self, _: &[u8], dst: &str) -> Result>; - - fn sign_recoverable(&self, data: &[u8]) -> Result>; - fn to_bytes(&self) -> Vec; } @@ -155,48 +147,42 @@ impl TypedPrivateKey { } } - pub fn to_bytes(&self) -> Vec { + pub fn as_sr25519(&self) -> Result<&Sr25519PrivateKey> { match self { - TypedPrivateKey::Secp256k1(sk) => sk.to_bytes(), - TypedPrivateKey::SR25519(sk) => sk.to_bytes(), - TypedPrivateKey::Ed25519(sk) => sk.to_bytes(), - TypedPrivateKey::BLS(sk) => sk.to_bytes(), + TypedPrivateKey::SR25519(sk) => Ok(sk), + _ => Err(KeyError::InvalidCurveType.into()), } } - pub fn public_key(&self) -> TypedPublicKey { + pub fn as_bls(&self) -> Result<&BLSPrivateKey> { match self { - TypedPrivateKey::Secp256k1(sk) => TypedPublicKey::Secp256k1(sk.public_key()), - TypedPrivateKey::SR25519(sk) => TypedPublicKey::SR25519(sk.public_key()), - TypedPrivateKey::Ed25519(sk) => TypedPublicKey::Ed25519(sk.public_key()), - TypedPrivateKey::BLS(sk) => TypedPublicKey::BLS(sk.public_key()), + TypedPrivateKey::BLS(sk) => Ok(sk), + _ => Err(KeyError::InvalidCurveType.into()), } } - pub fn sign(&self, data: &[u8]) -> Result> { + pub fn as_ed25519(&self) -> Result<&Ed25519PrivateKey> { match self { - TypedPrivateKey::Secp256k1(sk) => sk.sign(data), - TypedPrivateKey::SR25519(sk) => sk.sign(data), - TypedPrivateKey::Ed25519(sk) => sk.sign(data), - TypedPrivateKey::BLS(sk) => sk.sign(data), + TypedPrivateKey::Ed25519(sk) => Ok(sk), + _ => Err(KeyError::InvalidCurveType.into()), } } - pub fn sign_specified_hash(&self, data: &[u8], dst: &str) -> Result> { + pub fn to_bytes(&self) -> Vec { match self { - TypedPrivateKey::Secp256k1(sk) => sk.sign_specified_hash(data, dst), - TypedPrivateKey::SR25519(sk) => sk.sign_specified_hash(data, dst), - TypedPrivateKey::Ed25519(sk) => sk.sign_specified_hash(data, dst), - TypedPrivateKey::BLS(sk) => sk.sign_specified_hash(data, dst), + TypedPrivateKey::Secp256k1(sk) => sk.to_bytes(), + TypedPrivateKey::SR25519(sk) => sk.to_bytes(), + TypedPrivateKey::Ed25519(sk) => sk.to_bytes(), + TypedPrivateKey::BLS(sk) => sk.to_bytes(), } } - pub fn sign_recoverable(&self, data: &[u8]) -> Result> { + pub fn public_key(&self) -> TypedPublicKey { match self { - TypedPrivateKey::Secp256k1(sk) => sk.sign_recoverable(data), - TypedPrivateKey::SR25519(sk) => sk.sign_recoverable(data), - TypedPrivateKey::Ed25519(sk) => sk.sign_recoverable(data), - TypedPrivateKey::BLS(sk) => sk.sign_recoverable(data), + TypedPrivateKey::Secp256k1(sk) => TypedPublicKey::Secp256k1(sk.public_key()), + TypedPrivateKey::SR25519(sk) => TypedPublicKey::SR25519(sk.public_key()), + TypedPrivateKey::Ed25519(sk) => TypedPublicKey::Ed25519(sk.public_key()), + TypedPrivateKey::BLS(sk) => TypedPublicKey::BLS(sk.public_key()), } } } @@ -487,7 +473,7 @@ mod tests { "fc581c897af481b10cf846d88754f1d115e486e5b7bcc39c0588c01b0a9b7a11"; #[test] - fn typed_private_key() { + fn test_typed_private_key() { let ret = TypedPrivateKey::from_slice(CurveType::ED25519, &default_private_key()); assert!(ret.is_ok()); @@ -498,12 +484,16 @@ mod tests { assert_eq!(sk.curve_type(), CurveType::SECP256k1); assert_eq!(sk.public_key().to_bytes().to_hex(), PUB_KEY_HEX); - let sign_ret = sk.sign(&default_private_key()).unwrap(); + let sign_ret = sk + .as_secp256k1() + .unwrap() + .sign(&default_private_key()) + .unwrap(); assert_eq!(sign_ret.to_hex(), "304402206614e4bfa3ba1f6c975286a0a683871d6f0525a0860631afa5bea4da78ca012a02207a663d4980abed218683f66a63bbb766975fd525b8442a0424f6347c3d4f9261"); } #[test] - fn typed_deterministic_private_key() { + fn test_typed_deterministic_private_key() { let root = TypedDeterministicPrivateKey::from_mnemonic(CurveType::SECP256k1, &TEST_MNEMONIC) .unwrap(); @@ -537,7 +527,7 @@ mod tests { // todo: // this test run failure because of the invalid path // #[test] - fn typed_deterministic_private_key_sr25519() { + fn test_typed_deterministic_private_key_sr25519() { let root = TypedDeterministicPrivateKey::from_mnemonic(CurveType::SR25519, &TEST_MNEMONIC) .unwrap(); @@ -611,35 +601,19 @@ mod tests { } #[test] - fn test_sign_specified_hash() { - let message = "0000000000000000000000000000000000000000000000000000000000000000".as_bytes(); - let sk = TypedPrivateKey::from_slice(CurveType::SECP256k1, &default_private_key()).unwrap(); - let sign_ret = sk.sign_specified_hash(message, "blake2b"); - assert_eq!(sign_ret.err().unwrap().to_string(), "not_implement"); - - let sk = TypedPrivateKey::from_slice(CurveType::ED25519, &default_private_key()).unwrap(); - let sign_ret = sk.sign_specified_hash(message, "blake2b"); - assert_eq!(sign_ret.err().unwrap().to_string(), "not_implement"); - - let sk = TypedPrivateKey::from_slice(CurveType::SR25519, message).unwrap(); - let sign_ret = sk.sign_specified_hash(message, "blake2b"); - assert_eq!(sign_ret.err().unwrap().to_string(), "not_implement"); - } - - #[test] - fn test_sign_recoverable() { + fn test_sign() { let message = "0000000000000000000000000000000000000000000000000000000000000000".as_bytes(); let sk = TypedPrivateKey::from_slice(CurveType::ED25519, &default_private_key()).unwrap(); - let sign_ret = sk.sign_recoverable(message).unwrap(); + let sign_ret = sk.as_ed25519().unwrap().sign(message).unwrap(); assert_eq!(sign_ret.to_hex(), "65879392febf60e1fe01dfc301832c45b978f154639b2b0a3137264acc56bf41c380a81d73fa621753236dcab456afff2a4228f16fb80cce249dff3a8d7bf90b"); let sk = TypedPrivateKey::from_slice(CurveType::SR25519, message).unwrap(); - let sign_ret = sk.sign_recoverable(message); + let sign_ret = sk.as_sr25519().unwrap().sign(message); assert!(sign_ret.is_ok()); } #[test] - fn cross_test_tw() { + fn test_cross_tw() { let root = TypedDeterministicPrivateKey::from_mnemonic(CurveType::SECP256k1, "ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn fatal") .unwrap(); diff --git a/token-core/tcx-primitive/src/ed25519.rs b/token-core/tcx-primitive/src/ed25519.rs index bb57caf4..da12f425 100644 --- a/token-core/tcx-primitive/src/ed25519.rs +++ b/token-core/tcx-primitive/src/ed25519.rs @@ -24,6 +24,12 @@ impl From for Ed25519PrivateKey { } } +impl Ed25519PrivateKey { + pub fn sign(&self, data: &[u8]) -> Result> { + Ok(self.0.sign(data).0.to_vec()) + } +} + impl TraitPrivateKey for Ed25519PrivateKey { type PublicKey = Ed25519PublicKey; @@ -39,18 +45,6 @@ impl TraitPrivateKey for Ed25519PrivateKey { Ed25519PublicKey(self.0.public()) } - fn sign(&self, data: &[u8]) -> Result> { - Ok(self.0.sign(data).0.to_vec()) - } - - fn sign_specified_hash(&self, _: &[u8], _: &str) -> Result> { - Err(KeyError::NotImplement.into()) - } - - fn sign_recoverable(&self, data: &[u8]) -> Result> { - self.sign(data) - } - fn to_bytes(&self) -> Vec { self.0.to_raw_vec() } @@ -167,14 +161,10 @@ mod test { let pair: Pair/* Type */ = sp_core::Pair::from_seed(b"12345678901234567890123456789012"); let ed25519_private_key = Ed25519PrivateKey::from(pair); let signature = ed25519_private_key - .sign_recoverable(b"12345678901234567890123456789012") + .sign(b"12345678901234567890123456789012") .unwrap(); assert_eq!(signature.to_hex(), "23e1797e5d729e7bb21cd8a37d8c5be7171fb7626c9e45e7bd17e74bfab3a6255fb60f95e0042406b3a67d41cc65f7fc193c4ca161df9be3c8d0accf4c30cf03"); - let signature = - ed25519_private_key.sign_specified_hash(b"12345678901234567890123456789012", "blake2b"); - assert_eq!(signature.err().unwrap().to_string(), "not_implement"); - let public_key = ed25519_private_key.public_key().0; assert_eq!( public_key.to_hex(), diff --git a/token-core/tcx-primitive/src/secp256k1.rs b/token-core/tcx-primitive/src/secp256k1.rs index dff2db36..d1496ad8 100644 --- a/token-core/tcx-primitive/src/secp256k1.rs +++ b/token-core/tcx-primitive/src/secp256k1.rs @@ -60,6 +60,22 @@ impl Secp256k1PrivateKey { } } +impl Secp256k1PrivateKey { + pub fn sign(&self, data: &[u8]) -> Result> { + let msg = secp256k1::Message::from_slice(data).map_err(transform_secp256k1_error)?; + let signature = SECP256K1_ENGINE.sign_ecdsa(&msg, &self.0.inner); + Ok(signature.serialize_der().to_vec()) + } + + pub fn sign_recoverable(&self, data: &[u8]) -> Result> { + let msg = secp256k1::Message::from_slice(data).map_err(transform_secp256k1_error)?; + let signature = SECP256K1_ENGINE.sign_ecdsa_recoverable(&msg, &self.0.inner); + let (recover_id, sign) = signature.serialize_compact(); + let signed_bytes = [sign[..].to_vec(), vec![(recover_id.to_i32()) as u8]].concat(); + Ok(signed_bytes) + } +} + impl TraitPrivateKey for Secp256k1PrivateKey { type PublicKey = Secp256k1PublicKey; @@ -76,24 +92,6 @@ impl TraitPrivateKey for Secp256k1PrivateKey { Secp256k1PublicKey(self.0.public_key(&SECP256K1_ENGINE)) } - fn sign(&self, data: &[u8]) -> Result> { - let msg = secp256k1::Message::from_slice(data).map_err(transform_secp256k1_error)?; - let signature = SECP256K1_ENGINE.sign_ecdsa(&msg, &self.0.inner); - Ok(signature.serialize_der().to_vec()) - } - - fn sign_specified_hash(&self, _: &[u8], _: &str) -> Result> { - Err(KeyError::NotImplement.into()) - } - - fn sign_recoverable(&self, data: &[u8]) -> Result> { - let msg = secp256k1::Message::from_slice(data).map_err(transform_secp256k1_error)?; - let signature = SECP256K1_ENGINE.sign_ecdsa_recoverable(&msg, &self.0.inner); - let (recover_id, sign) = signature.serialize_compact(); - let signed_bytes = [sign[..].to_vec(), vec![(recover_id.to_i32()) as u8]].concat(); - Ok(signed_bytes) - } - fn to_bytes(&self) -> Vec { self.0.to_bytes() } diff --git a/token-core/tcx-primitive/src/sr25519.rs b/token-core/tcx-primitive/src/sr25519.rs index 599eaf7a..132e9882 100644 --- a/token-core/tcx-primitive/src/sr25519.rs +++ b/token-core/tcx-primitive/src/sr25519.rs @@ -27,6 +27,12 @@ impl From for Sr25519PrivateKey { } } +impl Sr25519PrivateKey { + pub fn sign(&self, data: &[u8]) -> Result> { + Ok(self.0.sign(data).0.to_vec()) + } +} + impl TraitPrivateKey for Sr25519PrivateKey { type PublicKey = Sr25519PublicKey; @@ -40,19 +46,6 @@ impl TraitPrivateKey for Sr25519PrivateKey { Sr25519PublicKey(self.0.public()) } - fn sign(&self, data: &[u8]) -> Result> { - Ok(self.0.sign(data).0.to_vec()) - } - - fn sign_specified_hash(&self, _: &[u8], _: &str) -> Result> { - Err(KeyError::NotImplement.into()) - } - - fn sign_recoverable(&self, data: &[u8]) -> Result> { - // https://www.deadalnix.me/2017/02/17/schnorr-signatures-for-not-so-dummies/ - self.sign(data) - } - fn to_bytes(&self) -> Vec { let bytes = self.0.to_raw_vec(); let secret_key = SecretKey::from_bytes(&bytes).expect("sr25519 uniform key to ed25519 key");