diff --git a/examples/test.rs b/examples/test.rs index 92425fe..f58b5ee 100644 --- a/examples/test.rs +++ b/examples/test.rs @@ -6,7 +6,7 @@ use std::ffi::CStr; //use rustylib::gen::{CWallet}; -use rustwallet::{fetch_cwallet, free_cwallet, sss_sign, CWallet}; +use rustwallet::{fetch_cwallet, free_cwallet, sign, sss_sign, CWallet}; fn main() { unsafe { @@ -21,7 +21,7 @@ fn main() { println!("---- fetching the saved wallet to be exposed to C-side ----"); let fetched = fetch_cwallet(); print_wallet(&fetched); - // sign(); + sign(); let sign_str = "111"; let cstr = std::ffi::CString::new(sign_str).unwrap(); sss_sign(cstr.into_raw()); diff --git a/src/lib.rs b/src/lib.rs index 0ac73ef..d6ecd46 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -67,22 +67,22 @@ pub unsafe extern "C" fn fetch_cwallet() -> CWallet { Ok(w) => return convert_to_cwallet(w), }; } -// #[no_mangle] -// pub unsafe extern "C" fn sign() { -// match wallet_impl::Wallet::retrieve_keys("wallet.json") { -// Err(_) => { -// println!("error sign"); -// } -// 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 sign() { + match wallet_impl::Wallet::retrieve_keys("wallet.json") { + Err(_) => { + println!("error sign"); + } + 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(msg: *const std::os::raw::c_char) { diff --git a/src/wallet/wallet_impl.rs b/src/wallet/wallet_impl.rs index df3a899..5aee84b 100644 --- a/src/wallet/wallet_impl.rs +++ b/src/wallet/wallet_impl.rs @@ -1,15 +1,18 @@ extern crate hex; use anyhow::Result; +use core::fmt::Write; use secp256k1::rand::rngs::OsRng; -use secp256k1::{PublicKey, Secp256k1, SecretKey}; +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; pub fn generate_keypair() -> (SecretKey, PublicKey) { @@ -100,58 +103,58 @@ impl Wallet { println!("recover: {:?}", secret_b.to_str_radix(16)); } - // 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); + 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 v = signature - // .v - // .try_into() - // .expect("signature recovery in electrum notation always fits in a u8"); + let key = SecretKeyRef::new(&pk); + let signature = key + .sign(message_hash.as_bytes(), None) + .expect("hash is non-zero 32-bytes; qed"); + let v = signature + .v + .try_into() + .expect("signature recovery in electrum notation always fits in a u8"); - // // let signature_bytes = Bytes({ - // // let mut bytes = Vec::with_capacity(65); - // // bytes.extend_from_slice(signature.r.as_bytes()); - // // bytes.extend_from_slice(signature.s.as_bytes()); - // // bytes.push(v); - // // bytes - // // }); + // let signature_bytes = Bytes({ + // let mut bytes = Vec::with_capacity(65); + // bytes.extend_from_slice(signature.r.as_bytes()); + // bytes.extend_from_slice(signature.s.as_bytes()); + // bytes.push(v); + // bytes + // }); - // let mut bytes = Vec::with_capacity(65); - // bytes.extend_from_slice(signature.r.as_bytes()); - // bytes.extend_from_slice(signature.s.as_bytes()); - // bytes.push(v); + let mut bytes = Vec::with_capacity(65); + bytes.extend_from_slice(signature.r.as_bytes()); + bytes.extend_from_slice(signature.s.as_bytes()); + bytes.push(v); - // let str_sign = hex::encode(bytes); - // println!("web3 sign: {:?}", str_sign); + 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 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"); - // write!(s, "{:02x}", rv).unwrap(); - // println!("normal sigx: {:?}", s); + 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 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"); + write!(s, "{:02x}", rv).unwrap(); + println!("normal sigx: {:?}", s); - // Ok(()) - // } + Ok(()) + } }