Skip to content

Commit

Permalink
refactor TypePrivateKey signature
Browse files Browse the repository at this point in the history
  • Loading branch information
tyrone committed Jan 24, 2024
1 parent f133932 commit 5f8c948
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 185 deletions.
2 changes: 1 addition & 1 deletion token-core/tcx-eth2/src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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_",
Expand Down
6 changes: 5 additions & 1 deletion token-core/tcx-filecoin/src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,11 @@ impl TransactionSigner<UnsignedMessage, SignedMessage> 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()),
Expand Down
51 changes: 15 additions & 36 deletions token-core/tcx-keystore/src/keystore/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -455,23 +455,10 @@ impl Signer for Keystore {
) -> Result<Vec<u8>> {
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)),
}
}

Expand All @@ -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<Vec<u8>> {
fn bls_sign(&mut self, hash: &[u8], derivation_path: &str, dst: &str) -> Result<Vec<u8>> {
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<Vec<u8>> {
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<Vec<u8>> {
Expand All @@ -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<Vec<u8>> {
todo!()
fn ed25519_sign(&mut self, hash: &[u8], derivation_path: &str) -> Result<Vec<u8>> {
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)
}
}

Expand Down
11 changes: 2 additions & 9 deletions token-core/tcx-keystore/src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,9 @@ pub trait Signer {
derivation_path: &str,
) -> Result<Vec<u8>>;

fn bls_sign(&mut self, hash: &[u8], derivation_path: &str) -> Result<Vec<u8>>;

fn bls_sign_specified_alg(
&mut self,
hash: &[u8],
derivation_path: &str,
sig_alg: &str,
) -> Result<Vec<u8>>;
fn bls_sign(&mut self, hash: &[u8], derivation_path: &str, dst: &str) -> Result<Vec<u8>>;

fn sr25519_sign(&mut self, hash: &[u8], derivation_path: &str) -> Result<Vec<u8>>;

fn schnorr_sign(&mut self, hash: &[u8], derivation_path: &str) -> Result<Vec<u8>>;
fn ed25519_sign(&mut self, hash: &[u8], derivation_path: &str) -> Result<Vec<u8>>;
}
46 changes: 13 additions & 33 deletions token-core/tcx-primitive/src/bls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@ impl From<SecretKey> 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<Vec<u8>> {
Ok(self
.0
.sign(message, dst.as_bytes(), &[])
.compress()
.to_vec())
}
}

impl TraitPrivateKey for BLSPrivateKey {
type PublicKey = BLSPublicKey;

Expand All @@ -44,26 +56,6 @@ impl TraitPrivateKey for BLSPrivateKey {
BLSPublicKey(self.0.sk_to_pk())
}

fn sign(&self, message: &[u8]) -> Result<Vec<u8>> {
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<Vec<u8>> {
Ok(self
.0
.sign(message, dst.as_bytes(), &[])
.compress()
.to_vec())
}

fn sign_recoverable(&self, _: &[u8]) -> Result<Vec<u8>> {
Err(KeyError::NotImplement.into())
}

fn to_bytes(&self) -> Vec<u8> {
let mut private_key = self.0.serialize().to_vec();
private_key.reverse();
Expand Down Expand Up @@ -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();
Expand All @@ -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]
Expand Down
88 changes: 31 additions & 57 deletions token-core/tcx-primitive/src/ecc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down Expand Up @@ -83,12 +81,6 @@ pub trait PrivateKey: Sized {

fn public_key(&self) -> Self::PublicKey;

fn sign(&self, _: &[u8]) -> Result<Vec<u8>>;

fn sign_specified_hash(&self, _: &[u8], dst: &str) -> Result<Vec<u8>>;

fn sign_recoverable(&self, data: &[u8]) -> Result<Vec<u8>>;

fn to_bytes(&self) -> Vec<u8>;
}

Expand Down Expand Up @@ -155,48 +147,42 @@ impl TypedPrivateKey {
}
}

pub fn to_bytes(&self) -> Vec<u8> {
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<Vec<u8>> {
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<Vec<u8>> {
pub fn to_bytes(&self) -> Vec<u8> {
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<Vec<u8>> {
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()),
}
}
}
Expand Down Expand Up @@ -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());

Expand All @@ -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();
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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();
Expand Down
Loading

0 comments on commit 5f8c948

Please sign in to comment.