Skip to content

Commit

Permalink
Testcase: Add a trait: ChainConfig, used for other on-chain signatures (
Browse files Browse the repository at this point in the history
#3)

* Add a trait: ChainConfig, used for other on-chain signatures

* Add debug info in Bitcoin testcase
  • Loading branch information
joii2020 authored Jan 11, 2024
1 parent 5e8c467 commit 9bca6d5
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 109 deletions.
184 changes: 92 additions & 92 deletions tests/omni_lock_rust/tests/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -645,24 +645,21 @@ pub fn sign_tx_by_input_group(
});
blake2b.finalize(&mut message);

let message = if config.id.flags == IDENTITY_FLAGS_ETHEREUM {
convert_keccak256_hash(&message)
} else if config.id.flags == IDENTITY_FLAGS_EOS {
assert!(config.eos.is_some());
config.eos.as_ref().unwrap().convert_message(&message)
} else if config.id.flags == IDENTITY_FLAGS_TRON {
assert!(config.tron.is_some());
config.tron.as_ref().unwrap().convert_message(&message)
} else if config.id.flags == IDENTITY_FLAGS_BITCOIN {
assert!(config.bitcoin.is_some());
config.bitcoin.as_ref().unwrap().convert_message(&message)
} else if config.id.flags == IDENTITY_FLAGS_DOGECOIN {
assert!(config.dogecoin.is_some());
config.dogecoin.as_ref().unwrap().convert_message(&message)
println!("origin message: {:02x?}", message);

let message = if use_chain_confg(config.id.flags) {
assert!(config.chain_config.is_some());
config
.chain_config
.as_ref()
.unwrap()
.convert_message(&message)
} else {
CkbH256::from(message)
};

println!("sign message: {:02x?}", message.as_bytes().to_vec());

let witness_lock = if config.id.flags == IDENTITY_FLAGS_DL {
let (mut sig, pubkey) = if config.use_rsa {
rsa_sign(message.as_bytes(), &config.rsa_private_key)
Expand Down Expand Up @@ -702,40 +699,17 @@ pub fn sign_tx_by_input_group(
&identity,
None,
)
} else if config.id.flags == IDENTITY_FLAGS_EOS {
} else if use_chain_confg(config.id.flags) {
let sig_bytes = config
.eos
.as_ref()
.unwrap()
.sign(&config.private_key, message);
gen_witness_lock(
sig_bytes,
config.use_rc,
config.use_rc_identity,
&proof_vec,
&identity,
None,
)
} else if config.id.flags == IDENTITY_FLAGS_BITCOIN {
let sig_bytes = config
.bitcoin
.as_ref()
.unwrap()
.sign(&config.private_key, message);
gen_witness_lock(
sig_bytes,
config.use_rc,
config.use_rc_identity,
&proof_vec,
&identity,
None,
)
} else if config.id.flags == IDENTITY_FLAGS_DOGECOIN {
let sig_bytes = config
.dogecoin
.chain_config
.as_ref()
.unwrap()
.sign(&config.private_key, message);
println!(
"bitcoin sign(size: {}): {:02x?}",
sig_bytes.len(),
sig_bytes.to_vec()
);
gen_witness_lock(
sig_bytes,
config.use_rc,
Expand All @@ -757,6 +731,12 @@ pub fn sign_tx_by_input_group(
)
};

println!(
"omni lock witness(size: {}): {:02x?}",
witness_lock.len(),
witness_lock.to_vec()
);

witness
.as_builder()
.lock(Some(witness_lock).pack())
Expand Down Expand Up @@ -785,6 +765,11 @@ pub fn sign_tx_by_input_group(

pub fn gen_tx(dummy: &mut DummyDataLoader, config: &mut TestConfig) -> TransactionView {
let lock_args = config.gen_args();
println!(
"omni lock args(size: {}): {:02x?}",
lock_args.len(),
lock_args.to_vec()
);
gen_tx_with_grouped_args(dummy, vec![(lock_args, 1)], config)
}

Expand Down Expand Up @@ -1165,6 +1150,40 @@ impl Default for MultisigTestConfig {
}
}

pub trait ChainConfig {
fn get_pubkey_hash(&self, pubkey: &Pubkey) -> [u8; 20];
fn convert_message(&self, message: &[u8; 32]) -> CkbH256;
fn sign(&self, privkey: &Privkey, message: CkbH256) -> Bytes;
}

pub fn use_chain_confg(flags: u8) -> bool {
flags == IDENTITY_FLAGS_ETHEREUM
|| flags == IDENTITY_FLAGS_EOS
|| flags == IDENTITY_FLAGS_TRON
|| flags == IDENTITY_FLAGS_BITCOIN
|| flags == IDENTITY_FLAGS_DOGECOIN
}

#[derive(Default)]
pub struct EthereumConfig {
pub pubkey_err: bool,
}

impl ChainConfig for EthereumConfig {
fn get_pubkey_hash(&self, pubkey: &Pubkey) -> [u8; 20] {
keccak160(&pubkey.as_ref()[..]).to_vec().try_into().unwrap()
}

fn convert_message(&self, message: &[u8; 32]) -> CkbH256 {
convert_keccak256_hash(message)
}

fn sign(&self, privkey: &Privkey, message: CkbH256) -> Bytes {
let sig = privkey.sign_recoverable(&message).expect("sign");
Bytes::from(sig.serialize())
}
}

pub struct BitcoinConfig {
pub sign_vtype: u8,
pub pubkey_err: bool,
Expand All @@ -1179,8 +1198,8 @@ impl Default for BitcoinConfig {
}
}

impl BitcoinConfig {
pub fn get_pubkey_hash(&self, pubkey: &Pubkey) -> [u8; 20] {
impl ChainConfig for BitcoinConfig {
fn get_pubkey_hash(&self, pubkey: &Pubkey) -> [u8; 20] {
if self.pubkey_err {
let mut r = [0u8; 20];
thread_rng().fill_bytes(&mut r);
Expand All @@ -1193,7 +1212,10 @@ impl BitcoinConfig {
pk_data[0] = SECP256K1_TAG_PUBKEY_UNCOMPRESSED;
pk_data[1..].copy_from_slice(pubkey.as_bytes());

bitcoin_hash160(&pk_data)
let r = bitcoin_hash160(&pk_data);
println!("public key hash: {:02x?}", r);

r
}
BITCOIN_V_TYPE_P2PKHCOMPRESSED => bitcoin_hash160(&pubkey.serialize()),
BITCOIN_V_TYPE_SEGWITP2SH => {
Expand All @@ -1213,7 +1235,7 @@ impl BitcoinConfig {
}
}

pub fn convert_message(&self, message: &[u8; 32]) -> CkbH256 {
fn convert_message(&self, message: &[u8; 32]) -> CkbH256 {
let message_magic = b"Bitcoin Signed Message:\n";
let msg_hex = hex::encode(message);
assert_eq!(msg_hex.len(), 64);
Expand All @@ -1237,7 +1259,7 @@ impl BitcoinConfig {
CkbH256::from(msg)
}

pub fn sign(&self, privkey: &Privkey, message: CkbH256) -> Bytes {
fn sign(&self, privkey: &Privkey, message: CkbH256) -> Bytes {
let sign = privkey
.sign_recoverable(&message)
.expect("sign secp256k1")
Expand All @@ -1256,12 +1278,12 @@ impl BitcoinConfig {
#[derive(Default)]
pub struct DogecoinConfig(pub BitcoinConfig);

impl DogecoinConfig {
pub fn get_pubkey_hash(&self, pubkey: &Pubkey) -> [u8; 20] {
impl ChainConfig for DogecoinConfig {
fn get_pubkey_hash(&self, pubkey: &Pubkey) -> [u8; 20] {
self.0.get_pubkey_hash(pubkey)
}

pub fn convert_message(&self, message: &[u8; 32]) -> CkbH256 {
fn convert_message(&self, message: &[u8; 32]) -> CkbH256 {
let message_magic = b"\x19Dogecoin Signed Message:\n\x40";
let msg_hex = hex::encode(message);
assert_eq!(msg_hex.len(), 64);
Expand All @@ -1275,16 +1297,16 @@ impl DogecoinConfig {
CkbH256::from(msg)
}

pub fn sign(&self, privkey: &Privkey, message: CkbH256) -> Bytes {
fn sign(&self, privkey: &Privkey, message: CkbH256) -> Bytes {
self.0.sign(privkey, message)
}
}

#[derive(Default)]
pub struct EOSConfig(pub BitcoinConfig);

impl EOSConfig {
pub fn get_pubkey_hash(&self, pubkey: &Pubkey) -> [u8; 20] {
impl ChainConfig for EOSConfig {
fn get_pubkey_hash(&self, pubkey: &Pubkey) -> [u8; 20] {
if self.0.pubkey_err {
let mut r = [0u8; 20];
thread_rng().fill_bytes(&mut r);
Expand All @@ -1307,11 +1329,11 @@ impl EOSConfig {
ckb_hash::blake2b_256(buf)[..20].try_into().unwrap()
}

pub fn convert_message(&self, message: &[u8; 32]) -> CkbH256 {
fn convert_message(&self, message: &[u8; 32]) -> CkbH256 {
CkbH256::from_slice(message).unwrap()
}

pub fn sign(&self, privkey: &Privkey, message: CkbH256) -> Bytes {
fn sign(&self, privkey: &Privkey, message: CkbH256) -> Bytes {
self.0.sign(privkey, message)
}
}
Expand All @@ -1321,8 +1343,8 @@ pub struct TronConfig {
pub pubkey_err: bool,
}

impl TronConfig {
pub fn get_pubkey_hash(&self, pubkey: &Pubkey) -> [u8; 20] {
impl ChainConfig for TronConfig {
fn get_pubkey_hash(&self, pubkey: &Pubkey) -> [u8; 20] {
if self.pubkey_err {
let mut r = [0u8; 20];
thread_rng().fill_bytes(&mut r);
Expand All @@ -1338,7 +1360,7 @@ impl TronConfig {
r[12..].try_into().unwrap()
}

pub fn convert_message(&self, message: &[u8; 32]) -> CkbH256 {
fn convert_message(&self, message: &[u8; 32]) -> CkbH256 {
let eth_prefix: &[u8; 24] = b"\x19TRON Signed Message:\n32";
let mut hasher = Keccak256::new();
hasher.update(eth_prefix);
Expand All @@ -1347,6 +1369,11 @@ impl TronConfig {
let rr = CkbH256::from_slice(r.as_slice()).expect("convert_keccak256_hash");
rr
}

fn sign(&self, privkey: &Privkey, message: CkbH256) -> Bytes {
let sig = privkey.sign_recoverable(&message).expect("sign");
Bytes::from(sig.serialize())
}
}

pub struct TestConfig {
Expand Down Expand Up @@ -1389,11 +1416,7 @@ pub struct TestConfig {
pub running_script: Script,
pub leading_witness_count: usize,

// Bitcoin
pub eos: Option<EOSConfig>,
pub tron: Option<TronConfig>,
pub bitcoin: Option<BitcoinConfig>,
pub dogecoin: Option<DogecoinConfig>,
pub chain_config: Option<Box<dyn ChainConfig>>,
}

#[derive(Copy, Clone, PartialEq)]
Expand Down Expand Up @@ -1436,8 +1459,6 @@ impl TestConfig {

let blake160 = if flags == IDENTITY_FLAGS_PUBKEY_HASH {
pubkey_hash
} else if flags == IDENTITY_FLAGS_ETHEREUM {
keccak160(&pubkey.as_ref()[..])
} else {
Bytes::from(&[0; 20][..])
};
Expand Down Expand Up @@ -1493,10 +1514,7 @@ impl TestConfig {
running_script: Default::default(),
leading_witness_count: 0,

eos: None,
tron: None,
bitcoin: None,
dogecoin: None,
chain_config: None,
}
}

Expand Down Expand Up @@ -1538,27 +1556,9 @@ impl TestConfig {
self.use_rc_identity = used;
}

pub fn set_eos(&mut self, eos: EOSConfig) {
let pkhash = eos.get_pubkey_hash(&self.pubkey);
self.eos = Some(eos);
self.id.blake160 = Bytes::from(pkhash.to_vec());
}

pub fn set_tron(&mut self, tron: TronConfig) {
let pkhash = tron.get_pubkey_hash(&self.pubkey);
self.tron = Some(tron);
self.id.blake160 = Bytes::from(pkhash.to_vec());
}

pub fn set_bitcoin(&mut self, btc: BitcoinConfig) {
let pkhash = btc.get_pubkey_hash(&self.pubkey);
self.bitcoin = Some(btc);
self.id.blake160 = Bytes::from(pkhash.to_vec());
}

pub fn set_dogecoin(&mut self, dogecoin: DogecoinConfig) {
let pkhash = dogecoin.get_pubkey_hash(&self.pubkey);
self.dogecoin = Some(dogecoin);
pub fn set_chain_config(&mut self, config: Box<dyn ChainConfig>) {
let pkhash = config.get_pubkey_hash(&self.pubkey);
self.chain_config = Some(config);
self.id.blake160 = Bytes::from(pkhash.to_vec());
}

Expand Down
Loading

0 comments on commit 9bca6d5

Please sign in to comment.