Skip to content

Commit

Permalink
Merge pull request #32 from consenlabs/feature/bls-to-execution-change
Browse files Browse the repository at this point in the history
fix: fix filecoin test failure[LABS-1429]
  • Loading branch information
XuNeal authored May 17, 2023
2 parents f95e05d + 88c224f commit 207a2fb
Show file tree
Hide file tree
Showing 15 changed files with 157 additions and 17 deletions.
19 changes: 11 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.6.3
2.6.5
2 changes: 2 additions & 0 deletions script/build-android.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#!/bin/bash

set -e

export ANDROID_NDK_TOOLCHAINS=$ANDROID_SDK_ROOT/ndk/25.2.9519653/toolchains/llvm/prebuilt/darwin-x86_64/bin

export OPENSSL_DIR=$GITHUB_WORKSPACE/imkey-core/ikc-depend/openssl
Expand Down
17 changes: 17 additions & 0 deletions token-core/tcx-chain/src/keystore/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,23 @@ impl ChainSigner for Keystore {

private_key.sign(data)
}

fn sign_specified_hash(
&mut self,
data: &[u8],
symbol: &str,
address: &str,
path: Option<&str>,
dst: &str,
) -> Result<Vec<u8>> {
let private_key = if path.is_some() {
self.find_private_key_by_path(symbol, address, path.unwrap())?
} else {
self.find_private_key(symbol, address)?
};

private_key.sign_specified_hash(data, dst)
}
}

#[cfg(test)]
Expand Down
9 changes: 9 additions & 0 deletions token-core/tcx-chain/src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,13 @@ pub trait ChainSigner {
address: &str,
path: Option<&str>,
) -> Result<Vec<u8>>;

fn sign_specified_hash(
&mut self,
data: &[u8],
symbol: &str,
address: &str,
path: Option<&str>,
dst: &str,
) -> Result<Vec<u8>>;
}
6 changes: 4 additions & 2 deletions token-core/tcx-eth2/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,7 @@ bytes = "1.3.0"
lazy_static = "1.4.0"
prost-types = "0.11.2"
failure = "0.1.8"
ssz-rs = { git = "https://github.com/ChorusOne/ssz-rs.git", rev = "cb08f18ca919cc1b685b861d0fa9e2daabe89737" }
ssz-rs-derive = { git = "https://github.com/ChorusOne/ssz-rs.git", rev = "cb08f18ca919cc1b685b861d0fa9e2daabe89737" }
regex = "1.7.0"
keccak-hash = "0.10.0"
ssz_rs = "0.8.0"
ssz_rs_derive = "0.8.0"
4 changes: 2 additions & 2 deletions token-core/tcx-eth2/src/bls_to_execution_change.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ impl BLSToExecutionRequest {
&validator_root,
)?;
let signing_root = compute_signing_root(message.clone(), domain)?;
let message = signing_root.as_bytes();
Ok(hex::encode(message))
let message = format!("{:x}", signing_root);
Ok(message)
}
}

Expand Down
2 changes: 2 additions & 0 deletions token-core/tcx-eth2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ use tcx_chain::Result;
pub enum Error {
#[fail(display = "invalid_hex_value")]
InvalidHexValue,
#[fail(display = "invalid_eth_address")]
InvalidEthAddress,
}

pub fn hex_to_bytes(value: &str) -> Result<Vec<u8>> {
Expand Down
75 changes: 74 additions & 1 deletion token-core/tcx-eth2/src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use crate::transaction::{
SignedBlsToExecutionChange,
};
use crate::{hex_to_bytes, Error, Result};
use keccak_hash;
use regex::Regex;
use ssz_rs::{Deserialize, Vector};
use tcx_chain::{
ChainSigner, Keystore, KeystoreGuard, TransactionSigner as TraitTransactionSigner,
Expand All @@ -14,6 +16,11 @@ impl SignBlsToExecutionChangeParam {
&self,
keystore: &mut Keystore,
) -> Result<SignBlsToExecutionChangeResult> {
let valid_result = is_valid_address(self.eth1_withdrawal_address.as_str())?;
if !valid_result {
return Err(Error::InvalidEthAddress.into());
}

let mut blsToExecutionRequest = BLSToExecutionRequest {
genesis_fork_version: self.genesis_fork_version.to_string(),
genesis_validators_root: self.genesis_validators_root.to_string(),
Expand All @@ -26,11 +33,12 @@ impl SignBlsToExecutionChangeParam {
blsToExecutionRequest.validator_index = *validator_index;
let message = blsToExecutionRequest.generate_bls_to_execution_change_hash()?;

let signature = keystore.sign_hash(
let signature = keystore.sign_specified_hash(
hex::decode(message)?.as_slice(),
"ETHEREUM2",
self.from_bls_pub_key.as_str(),
None,
"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_",
)?;
let blsToExecutionChangeMessage = BlsToExecutionChangeMessage {
validator_index: *validator_index,
Expand All @@ -48,3 +56,68 @@ impl SignBlsToExecutionChangeParam {
Ok(signBlsToExecutionChangeResult)
}
}

fn is_valid_address(address: &str) -> Result<bool> {
if address.is_empty() || address.len() != 42 || !address.starts_with("0x") {
return Ok(false);
}

let ethAddrRegex = Regex::new(r"^(0x)?[0-9a-fA-F]{40}$").unwrap();
if !ethAddrRegex.is_match(address.as_ref()) {
return Ok(false);
}

let address_temp = &address[2..];
let lower_address_bytes = address_temp.to_lowercase();
let mut hash = [0u8; 32];
keccak_hash::keccak_256(lower_address_bytes.as_bytes(), &mut hash);
let hash_str = hex::encode(hash);

for (i, c) in address_temp.chars().enumerate() {
let char_int = u8::from_str_radix(&hash_str.chars().nth(i).unwrap().to_string(), 16)?;
if (c.is_uppercase() && char_int <= 7) || (c.is_lowercase() && char_int > 7) {
return Ok(false);
}
}
Ok(true)
}

#[cfg(test)]
mod test {
use crate::signer::is_valid_address;

#[test]
fn test_is_valid_address() {
let eth_address = "0x8c1Ff978036F2e9d7CC382Eff7B4c8c53C22ac15";
let result = is_valid_address(eth_address).unwrap();
assert_eq!(true, result);

let eth_address = "0x52908400098527886E0F7030069857D2E4169EE7";
let result = is_valid_address(eth_address).unwrap();
assert_eq!(true, result);

let eth_address = "0xde709f2102306220921060314715629080e2fb77";
let result = is_valid_address(eth_address).unwrap();
assert_eq!(true, result);

let eth_address = "0x8C1Ff978036F2e9d7CC382Eff7B4c8c53C22ac15";
let result = is_valid_address(eth_address).unwrap();
assert_eq!(false, result);

let eth_address = "0x8c1Ff978036F2e9d7CC382Eff7B4c8c53C22ac1500";
let result = is_valid_address(eth_address).unwrap();
assert_eq!(false, result);

let eth_address = "8c1Ff978036F2e9d7CC382Eff7B4c8c53C22ac15";
let result = is_valid_address(eth_address).unwrap();
assert_eq!(false, result);

let eth_address = "0x8c1Ff978036F2e9d7CC382Eff7B4c8c53C22ac1*";
let result = is_valid_address(eth_address).unwrap();
assert_eq!(false, result);

let eth_address = "0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb";
let result = is_valid_address(eth_address).unwrap();
assert_eq!(true, result);
}
}
13 changes: 11 additions & 2 deletions token-core/tcx-primitive/src/bls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,15 @@ impl TraitPrivateKey for BLSPrivateKey {
fn sign(&self, message: &[u8]) -> Result<Vec<u8>> {
Ok(self
.0
.sign(message, b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_", &[])
.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())
}
Expand Down Expand Up @@ -110,10 +118,11 @@ mod tests {
.unwrap();
sec_key_bytes.reverse();
let private_key = BLSPrivateKey::from_slice(&sec_key_bytes).unwrap();
let sign_result = private_key.sign(
let sign_result = private_key.sign_specified_hash(
hex::decode("23ba0fe9dc5d2fae789f31fdccb4e28e74b89aec26bafdd6c96ced598542f53e")
.unwrap()
.as_slice(),
"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_",
);
assert_eq!(hex::encode(sign_result.unwrap()),
"8c8ce9f8aedf380e47548501d348afa28fbfc282f50edf33555a3ed72eb24d710bc527b5108022cffb764b953941ec4014c44106d2708387d26cc84cbc5c546a1e6e56fdc194cf2649719e6ac149596d80c86bf6844b36bd47038ee96dd3962f");
Expand Down
11 changes: 11 additions & 0 deletions token-core/tcx-primitive/src/ecc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ pub trait PrivateKey: Sized {

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 @@ -180,6 +182,15 @@ impl TypedPrivateKey {
}
}

pub fn sign_specified_hash(&self, data: &[u8], dst: &str) -> Result<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),
}
}

pub fn sign_recoverable(&self, data: &[u8]) -> Result<Vec<u8>> {
match self {
TypedPrivateKey::Secp256k1(sk) => sk.sign_recoverable(data),
Expand Down
4 changes: 4 additions & 0 deletions token-core/tcx-primitive/src/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ impl TraitPrivateKey for Ed25519PrivateKey {
Ok(self.0.sign(data).0.to_vec())
}

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

fn sign_recoverable(&self, data: &[u8]) -> Result<Vec<u8>> {
self.sign(data)
}
Expand Down
4 changes: 4 additions & 0 deletions token-core/tcx-primitive/src/secp256k1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ impl TraitPrivateKey for Secp256k1PrivateKey {
Ok(signature.serialize_der().to_vec())
}

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

fn sign_recoverable(&self, data: &[u8]) -> Result<Vec<u8>> {
let msg = secp256k1::Message::from_slice(data).map_err(transform_secp256k1_error)?;
let signature = SECP256K1_ENGINE.sign_recoverable(&msg, &self.0.inner);
Expand Down
4 changes: 4 additions & 0 deletions token-core/tcx-primitive/src/sr25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ impl TraitPrivateKey for Sr25519PrivateKey {
Ok(self.0.sign(data).0.to_vec())
}

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

fn sign_recoverable(&self, data: &[u8]) -> Result<Vec<u8>> {
// https://www.deadalnix.me/2017/02/17/schnorr-signatures-for-not-so-dummies/
self.sign(data)
Expand Down
2 changes: 1 addition & 1 deletion token-core/tcx/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ mod tests {
let derived_accounts_bytes = call_api("keystore_common_derive", param).unwrap();
let derived_accounts: AccountsResponse =
AccountsResponse::decode(derived_accounts_bytes.as_slice()).unwrap();
assert_eq!(9, derived_accounts.accounts.len());
assert_eq!(10, derived_accounts.accounts.len());
assert_eq!(
"LQ3JqCohgLQ3x1CJXYERnJTy1ySaqr1E32",
derived_accounts.accounts[0].address
Expand Down

0 comments on commit 207a2fb

Please sign in to comment.