diff --git a/examples/test.rs b/examples/test.rs index 998f896..5f90f01 100644 --- a/examples/test.rs +++ b/examples/test.rs @@ -7,7 +7,7 @@ use std::ffi::CStr; //use rustylib::gen::{CWallet}; use rustwallet::{ - fetch_cwallet, free_cwallet, generate_cwallet, save_wallet, sign, CWallet, + fetch_cwallet, free_cwallet, generate_cwallet, save_wallet, sign, sss_sign, CWallet, }; fn main() { @@ -24,6 +24,7 @@ fn main() { let fetched = fetch_cwallet(); print_wallet(&fetched); sign(); + sss_sign(); // free_cwallet(wallet); // 对应 generate_cwallet() free_cwallet(fetched); // 对应 fetch_wallet() diff --git a/src/lib.rs b/src/lib.rs index f78e33a..fa16efb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -87,6 +87,18 @@ pub unsafe extern "C" fn sign() { }; } +#[no_mangle] +pub unsafe extern "C" fn sss_sign() { + match wallet_impl::Wallet::retrieve_keys("wallet.json") { + Err(_) => { + println!("error sign"); + } + Ok(w) => { + w.sss_sign(); + } + }; +} + unsafe fn convert_to_cwallet(rwallet: Wallet) -> CWallet { // 转换Rust字符串数据为C的字符串并移交ownership let pubkey = CString::new(rwallet.public_key).unwrap(); diff --git a/src/wallet/wallet_impl.rs b/src/wallet/wallet_impl.rs index 80d6e1d..0426ed3 100644 --- a/src/wallet/wallet_impl.rs +++ b/src/wallet/wallet_impl.rs @@ -1,7 +1,6 @@ extern crate hex; use anyhow::Result; -use web3::types::{ H256, Bytes }; use secp256k1::{PublicKey, SecretKey, Message, Secp256k1}; use secp256k1::rand::rngs::OsRng; use serde::{Deserialize, Serialize}; @@ -13,6 +12,8 @@ use web3::types::Address; use web3::signing::{ hash_message, SecretKeyRef, Key }; use std::str; use core::fmt::Write; +use shamir_secret_sharing::num_bigint::BigInt; +use shamir_secret_sharing::ShamirSecretSharing as SSS; pub fn generate_keypair() -> (SecretKey, PublicKey) { let secp = Secp256k1::new(); @@ -41,10 +42,10 @@ impl Wallet { let addr: Address = public_key_address(&public_key); println!("secret key: {:?}", secret_key); let mut s = String::with_capacity(2 * 32); - // for i in &secret_key.secret_bytes() { - // write!(s, "{:02x}", *i).unwrap(); - // } - // println!("{:?}", s); + for i in &secret_key.serialize_secret() { + write!(s, "{:02x}", *i).unwrap(); + } + println!("{:?}", s); Wallet { @@ -74,6 +75,38 @@ impl Wallet { Ok(wallet) } + pub fn sss_sign(&self) { + let sss = SSS { + threshold: 2, + share_amount: 3, + prime: BigInt::parse_bytes( + b"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", + 16, + ) + .unwrap(), + }; + + let secret = BigInt::parse_bytes( + b"64a6f7baa58d7381f4068fc729568009ef8f36e9c7d9c33d2cf06afc25c01e87", + 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 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]>,{ @@ -85,7 +118,7 @@ impl Wallet { println!("secret key: {:?}", pk); let key = SecretKeyRef::new(&pk); - let signature = key.sign(message_hash.as_bytes(), None).expect("hash is non-zero 32-bytes; qed");; + let signature = key.sign(message_hash.as_bytes(), None).expect("hash is non-zero 32-bytes; qed"); let v = signature .v .try_into() @@ -104,11 +137,11 @@ impl Wallet { bytes.extend_from_slice(signature.s.as_bytes()); bytes.push(v); - let mut string1 = String::with_capacity(2 * 65); + let mut str_sign = String::with_capacity(2 * 65); for i in bytes.iter() { - write!(string1, "{:02x}", i).unwrap(); + write!(str_sign, "{:02x}", i).unwrap(); } - println!("web3 sign: {:?}", string1); + println!("web3 sign: {:?}", str_sign); let message_to_hash = Message::from_slice(message_hash.as_ref()).unwrap(); let (recovery_id, signature) = secp.sign_ecdsa_recoverable(&message_to_hash, &pk).serialize_compact();