diff --git a/examples/test.rs b/examples/test.rs index 5f90f01..f58b5ee 100644 --- a/examples/test.rs +++ b/examples/test.rs @@ -6,9 +6,7 @@ use std::ffi::CStr; //use rustylib::gen::{CWallet}; -use rustwallet::{ - fetch_cwallet, free_cwallet, generate_cwallet, save_wallet, sign, sss_sign, CWallet, -}; +use rustwallet::{fetch_cwallet, free_cwallet, sign, sss_sign, CWallet}; fn main() { unsafe { @@ -24,7 +22,9 @@ fn main() { let fetched = fetch_cwallet(); print_wallet(&fetched); sign(); - sss_sign(); + let sign_str = "111"; + let cstr = std::ffi::CString::new(sign_str).unwrap(); + sss_sign(cstr.into_raw()); // free_cwallet(wallet); // 对应 generate_cwallet() free_cwallet(fetched); // 对应 fetch_wallet() diff --git a/src/lib.rs b/src/lib.rs index fa16efb..d6ecd46 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -73,29 +73,28 @@ pub unsafe extern "C" fn sign() { Err(_) => { println!("error sign"); } - Ok(w) => { - match w.sign("111") { - Err(err) => { - println!("error sign: {:?}", err); - } - Ok(sig) => { - println!("sig result: {:?}", sig); - } + Ok(w) => match w.sign("111") { + Err(err) => { + println!("error sign: {:?}", err); } - - } + Ok(sig) => { + println!("sig result: {:?}", sig); + } + }, }; } #[no_mangle] -pub unsafe extern "C" fn sss_sign() { +pub unsafe extern "C" fn sss_sign(msg: *const std::os::raw::c_char) { + let c_str = CStr::from_ptr(msg); + let str = c_str.to_str().unwrap(); match wallet_impl::Wallet::retrieve_keys("wallet.json") { Err(_) => { println!("error sign"); } Ok(w) => { - w.sss_sign(); - } + w.sss_sign(&str); + } }; } diff --git a/src/wallet/wallet_impl.rs b/src/wallet/wallet_impl.rs index 0426ed3..5aee84b 100644 --- a/src/wallet/wallet_impl.rs +++ b/src/wallet/wallet_impl.rs @@ -1,19 +1,19 @@ extern crate hex; use anyhow::Result; -use secp256k1::{PublicKey, SecretKey, Message, Secp256k1}; +use core::fmt::Write; use secp256k1::rand::rngs::OsRng; +use secp256k1::{Message, PublicKey, Secp256k1, SecretKey}; use serde::{Deserialize, Serialize}; +use shamir_secret_sharing::num_bigint::BigInt; +use shamir_secret_sharing::ShamirSecretSharing as SSS; use std::io::BufWriter; +use std::str; use std::str::FromStr; use std::{fs::OpenOptions, io::BufReader}; use tiny_keccak::keccak256; +use web3::signing::{hash_message, Key, SecretKeyRef}; 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(); @@ -29,7 +29,6 @@ pub fn public_key_address(public_key: &PublicKey) -> Address { Address::from_slice(&hash[12..]) } - #[derive(Serialize, Deserialize, Debug)] pub struct Wallet { pub secret_key: String, @@ -41,13 +40,9 @@ impl Wallet { pub fn new(secret_key: &SecretKey, public_key: &PublicKey) -> Self { 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.serialize_secret() { - write!(s, "{:02x}", *i).unwrap(); - } + let s = hex::encode(&secret_key.serialize_secret()); println!("{:?}", s); - Wallet { secret_key: s, public_key: public_key.to_string(), @@ -61,7 +56,6 @@ impl Wallet { .create(true) .open(file_path)?; let buf_writer = BufWriter::new(file); - serde_json::to_writer_pretty(buf_writer, self)?; Ok(()) @@ -70,28 +64,30 @@ impl Wallet { pub fn retrieve_keys(file_path: &str) -> Result { let file = OpenOptions::new().read(true).open(file_path)?; let buf_reader = BufReader::new(file); - let wallet: Wallet = serde_json::from_reader(buf_reader)?; + Ok(wallet) } - pub fn sss_sign(&self) { + pub 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: BigInt::parse_bytes( - b"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", - 16, - ) - .unwrap(), + prime: pb, }; - + 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; @@ -107,18 +103,21 @@ impl Wallet { println!("recover: {:?}", secret_b.to_str_radix(16)); } - pub fn sign(&self, msg: S) -> Result<()> - where - S: AsRef<[u8]>,{ + pub fn sign(&self, msg: S) -> Result<()> + where + S: AsRef<[u8]>, + { let secp = Secp256k1::new(); println!("secret key str: {:?}", self.secret_key); let message = msg.as_ref(); let message_hash = hash_message(message.as_ref()); let pk = SecretKey::from_str(&self.secret_key).expect("32 bytes, within curve order"); 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() @@ -137,20 +136,22 @@ impl Wallet { bytes.extend_from_slice(signature.s.as_bytes()); bytes.push(v); - let mut str_sign = String::with_capacity(2 * 65); - for i in bytes.iter() { - write!(str_sign, "{:02x}", i).unwrap(); - } + let str_sign = hex::encode(bytes); 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(); - let mut s = String::with_capacity(2 * 65); - for i in signature { - write!(s, "{:02x}", i).unwrap(); - } + let (recovery_id, signature) = secp + .sign_ecdsa_recoverable(&message_to_hash, &pk) + .serialize_compact(); + // let mut s = String::with_capacity(2 * 65); + // for i in signature { + // write!(s, "{:02x}", i).unwrap(); + // } + let mut s = hex::encode(signature); let standard_v = recovery_id.to_i32() as u64 + 27; - let rv:u8 = standard_v.try_into().expect("signature recovery in electrum notation always fits in a u8"); + let rv: u8 = standard_v + .try_into() + .expect("signature recovery in electrum notation always fits in a u8"); write!(s, "{:02x}", rv).unwrap(); println!("normal sigx: {:?}", s);