From 0236a704612abaae364321c8e56c5921bd447240 Mon Sep 17 00:00:00 2001 From: cebgcontract <99630598+cebgcontract@users.noreply.github.com> Date: Tue, 1 Nov 2022 14:05:34 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E6=89=93=E5=8D=B0=E4=BF=A1?= =?UTF-8?q?=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/test.rs | 4 +- rustwallet.h | 21 ++++++---- src/lib.rs | 25 ++++++------ src/wallet/wallet_impl.rs | 84 +++++---------------------------------- 4 files changed, 39 insertions(+), 95 deletions(-) diff --git a/examples/test.rs b/examples/test.rs index e40a6e3..238c10f 100644 --- a/examples/test.rs +++ b/examples/test.rs @@ -6,7 +6,7 @@ use std::ffi::{CStr, CString}; use std::os::raw::c_char; -use rustwallet::{new_wallet, get_address, restore_wallet, reset_wallet, free_cwallet, sign, sign_for_tran, CWallet}; +use rustwallet::{new_wallet, get_address, restore_wallet, reset_wallet, free_cwallet, sign, sign_for_tran, CWallet, generate_sec_key}; macro_rules! print_cchar{ ($p1:expr) => ( @@ -57,6 +57,8 @@ fn main() { println!("address: {}", address_str); let sign_str = sign_for_tran(&wallet,str_to_cchar!("cc0dac9a2bd7125bbe9130b83053494860f7a444868a45a9c00a865631ba8894")); print_cchar!(sign_str); + let s_key = generate_sec_key(&wallet); + print_cchar!(s_key); let key0 = "aadcabedb89a41db4c815bd149d3e7a1ff04247947efd5768666ba5f5e2df2e2"; diff --git a/rustwallet.h b/rustwallet.h index 448c162..593e636 100644 --- a/rustwallet.h +++ b/rustwallet.h @@ -4,19 +4,24 @@ #include typedef struct CWallet { - char *public_key; - char *private_key; - char *public_addr; + char *msg_key; + char *master_key; + char *second_key; + char *backup_key; } CWallet; -struct CWallet generate_cwallet(void); +struct CWallet new_wallet(const char *msg); + +struct CWallet restore_wallet(const struct CWallet *cw); + +struct CWallet reset_wallet(const struct CWallet *cw); void free_cwallet(struct CWallet cw); -void save_wallet(const struct CWallet *cw); +char *get_address(const struct CWallet *cw); -struct CWallet fetch_cwallet(void); +char *generate_sec_key(const struct CWallet *cw); -void sign(void); +char *sign(const struct CWallet *cw, const char *msg); -void sss_sign(const char *msg); +char *sign_for_tran(const struct CWallet *cw, const char *msg); diff --git a/src/lib.rs b/src/lib.rs index 940ba2d..fa31bfb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -85,27 +85,21 @@ pub struct CWallet { #[no_mangle] pub unsafe extern "C" fn new_wallet(msg: *const c_char) -> CWallet { - println!("generating wallet"); let str = cchar_to_str!(msg); let rust_wallet = wallet_impl::Wallet::new(str); - println!("rust_wallet: {:?}", &rust_wallet); convert_to_cwallet(rust_wallet) } #[no_mangle] pub unsafe extern "C" fn restore_wallet(cw: &CWallet) -> CWallet { - println!("restore wallet"); let rust_wallet = convert_to_rwallet(cw); - println!("rust_wallet: {:?}", &rust_wallet); convert_to_cwallet(rust_wallet) } #[no_mangle] pub unsafe extern "C" fn reset_wallet(cw: &CWallet) -> CWallet { - println!("restore wallet"); let rust_wallet = convert_to_rwallet(cw); let rust_wallet2 = rust_wallet.reset_wallet(); - println!("new rust_wallet: {:?}", &rust_wallet2); convert_to_cwallet(rust_wallet2) } @@ -120,17 +114,23 @@ pub unsafe extern "C" fn free_cwallet(cw: CWallet) { #[no_mangle] pub unsafe extern "C" fn get_address(cw: &CWallet) -> *mut c_char{ let rwallet = convert_to_rwallet(cw); - println!("rwallet: {:?}", rwallet); let address = rwallet.get_address(); let address_str = format!("{:?}", address); let c_address = CString::new(address_str).unwrap(); c_address.into_raw() } +#[no_mangle] +pub unsafe extern "C" fn generate_sec_key(cw: &CWallet) -> *mut c_char { + let rwallet = convert_to_rwallet(cw); + let s_key = rwallet.generate_sec_key(); + let cs_key = CString::new(s_key).unwrap(); + cs_key.into_raw() +} + #[no_mangle] pub unsafe extern "C" fn sign(cw: &CWallet, msg: *const c_char) -> *mut c_char{ let rwallet = convert_to_rwallet(cw); - println!("rwallet: {:?}", rwallet); let msg_str = cchar_to_str!(msg); let signature = rwallet.sign(msg_str); let r = match signature { @@ -143,19 +143,18 @@ pub unsafe extern "C" fn sign(cw: &CWallet, msg: *const c_char) -> *mut c_char{ #[no_mangle] pub unsafe extern "C" fn sign_for_tran(cw: &CWallet, msg: *const c_char) -> *mut c_char{ let rwallet = convert_to_rwallet(cw); - println!("rwallet: {:?}", rwallet); let msg_str = cchar_to_str!(msg); let signature = rwallet.sign_for_tran(msg_str); - let r = match signature { - Ok(v) => v, + let (r, recid) = match signature { + Ok((v, _recid)) => (v, _recid), Err(err) => panic!("Problem sign: {:?}", err), }; - str_to_cchar!(r) + let result = format!("{}|{}", r, recid); + str_to_cchar!(result) } unsafe fn convert_to_cwallet(rwallet: Wallet) -> CWallet { - // 转换Rust字符串数据为C的字符串并移交ownership let c_msgkey: *mut c_char = str_to_cchar!(rwallet.msg_key); let c_masterkey: *mut c_char = str_to_cchar!(rwallet.master_key); let c_secondkey = ostr_to_cchar!(rwallet.second_key); diff --git a/src/wallet/wallet_impl.rs b/src/wallet/wallet_impl.rs index 7a547e1..a40f621 100644 --- a/src/wallet/wallet_impl.rs +++ b/src/wallet/wallet_impl.rs @@ -82,12 +82,9 @@ impl Wallet { pub fn new(msg: &str) -> Self{ let (secret_key, _pub_key) = generate_keypair(); let s = hex::encode(&secret_key.serialize_secret()); - // let sk2 = "b8256097c1ff2bdd483ffb53d35203a8a7ff19547d65d97f2810732a27e80c1f"; - let shares_str = generate_sss_keypair(msg, &s); - // let addr: Address = public_key_address(&pub_key); - println!("secret key: {:?}", secret_key); - println!("{:?}", s); + // println!("secret key: {:?}", secret_key); + // println!("{:?}", s); let second_key = shares_str.get(1).map(String::clone); let backup_key = shares_str.get(2).map(String::clone); Wallet { @@ -98,23 +95,6 @@ impl Wallet { } } - // pub fn restore_wallet(msg: &str, _key_master: &str, _key_second: Option<&str>, _key_backup: Option<&str>) -> Self { - // let key_second: Option = match _key_second { - // None => None, - // Some(val) => Some(val.to_string()) - // }; - // let key_backup: Option = match _key_backup { - // None => None, - // Some(val) => Some(val.to_string()) - // }; - // Wallet { - // msg_key: msg.to_string(), - // master_key: _key_master.to_string(), - // second_key: key_second, - // backup_key: key_backup - // } - // } - pub fn reset_wallet(&self) -> Self{ let secret_key = self.get_secret_key(); let s = hex::encode(&secret_key.serialize_secret()); @@ -168,57 +148,17 @@ impl Wallet { get_public_key(&s_key) } + pub fn generate_sec_key(&self) -> String { + let secret_key = self.get_secret_key(); + let s = hex::encode(&secret_key.serialize_secret()); + s + } + pub fn get_address(&self) -> Address { let public_key = self.get_public_key(); public_key_address(&public_key) } - fn sss_sign(&self, msg: &str) { - let k_hash = keccak256(msg.as_bytes()); - println!("k_hash: {:?}", &k_hash); - let s = hex::encode(&k_hash); - println!("k_hash str: {:?}", &s); - println!("k_hash byte: {:?}", &s.as_bytes()); - let pb = BigInt::parse_bytes(&s.as_bytes(), 16).unwrap(); - let sss = SSS { - threshold: 2, - share_amount: 3, - prime: pb, - }; - let skey = "64a6f7baa58d7381f4068fc729568009ef8f36e9c7d9c33d2cf06afc25c01e87"; - let secret = BigInt::parse_bytes( - &skey.as_bytes(), - 16, - ) - .unwrap(); - - let shares = sss.split(secret.clone()); - let key0 = shares[1].clone().1; - let key1 = shares[2].clone().1; - println!("key0: {:?}", key0.to_str_radix(16)); - println!("key1: {:?}", key1.to_str_radix(16)); - let key_str_0 = "539e52f2ffc060329010ae551e8684124bad26d93b0c9333154a5a5e116f5e0"; - let key_str_1 = "44c523387a58ee8628e81d5e36014e78a05838f51205d765b7e729da33727ae2"; - let key0 = BigInt::parse_bytes( - &key_str_0.as_bytes(), - 16, - ) - .unwrap(); - let key1 = BigInt::parse_bytes( - &key_str_1.as_bytes(), - 16, - ) - .unwrap(); - let kp0: (usize, BigInt) = (2, key0); - let kp1 = (3, key1); - let tmp = vec![kp0, kp1]; - // println!("shares: {:?}", shares); - // assert_eq!(secret, sss.recover(&shares[..sss.threshold as usize])); - println!("secret: {:?}", secret.to_str_radix(16)); - let secret_b = sss.recover(&tmp); - println!("recover: {:?}", secret_b.to_str_radix(16)); - } - pub fn sign(&self, msg: S) -> Result where S: AsRef<[u8]>, @@ -227,7 +167,6 @@ impl Wallet { let secret_key = self.get_secret_key(); let message = msg.as_ref(); let message_hash = hash_message(message.as_ref()); - println!("secret key: {:?}", &secret_key); let message_to_hash = Message::from_slice(message_hash.as_ref()).unwrap(); let (recovery_id, signature) = secp .sign_ecdsa_recoverable(&message_to_hash, &secret_key) @@ -239,11 +178,9 @@ impl Wallet { .try_into() .expect("signature recovery in electrum notation always fits in a u8"); write!(s, "{:02x}", rv).unwrap(); - println!("normal sigx: {:?}", s); - Ok(s) } - pub fn sign_for_tran(&self, msg: S) -> Result + pub fn sign_for_tran(&self, msg: S) -> Result<(String, i32)> where S: AsRef<[u8]>, { @@ -255,6 +192,7 @@ impl Wallet { .sign_ecdsa_recoverable(&message_to_hash, &secret_key) .serialize_compact(); let s = hex::encode(signature); - Ok(s) + let recid = _recovery_id.to_i32(); + Ok((s, recid)) } }