From ffbdca8c5e1263aef800829189dc2b50ce98543d Mon Sep 17 00:00:00 2001 From: fitchgc <36850835+fitchgc@users.noreply.github.com> Date: Thu, 29 Sep 2022 07:01:54 +0000 Subject: [PATCH] =?UTF-8?q?=E9=AA=8C=E8=AF=81=E9=80=9A=E8=BF=87=E9=92=B1?= =?UTF-8?q?=E5=8C=85=E7=9A=84=E7=AD=BE=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 163 ++++++++++++++++++++++++++++++-------- Cargo.toml | 6 +- examples/test.rs | 14 ++-- src/wallet/wallet_impl.rs | 73 +++++++++++++---- wallet.json | 6 +- 5 files changed, 202 insertions(+), 60 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 126ea16..b77a95e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,6 +14,15 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +[[package]] +name = "autocfg" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" +dependencies = [ + "autocfg 1.1.0", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -26,6 +35,12 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "bitcoin_hashes" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "006cc91e1a1d99819bc5b8214be3555c1f0611b169f527a1fdc54ed1f2b745b0" + [[package]] name = "bitcoin_hashes" version = "0.11.0" @@ -630,7 +645,7 @@ version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ - "autocfg", + "autocfg 1.1.0", "hashbrown", ] @@ -703,7 +718,7 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" dependencies = [ - "autocfg", + "autocfg 1.1.0", "scopeguard", ] @@ -770,7 +785,7 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" dependencies = [ - "autocfg", + "autocfg 1.1.0", "num-integer", "num-traits", "rand 0.5.6", @@ -782,7 +797,7 @@ version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ - "autocfg", + "autocfg 1.1.0", "num-traits", ] @@ -792,7 +807,7 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ - "autocfg", + "autocfg 1.1.0", ] [[package]] @@ -864,7 +879,7 @@ version = "0.9.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f" dependencies = [ - "autocfg", + "autocfg 1.1.0", "cc", "libc", "openssl-src", @@ -1032,6 +1047,25 @@ dependencies = [ "winapi", ] +[[package]] +name = "rand" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +dependencies = [ + "autocfg 0.1.8", + "libc", + "rand_chacha 0.1.1", + "rand_core 0.4.2", + "rand_hc", + "rand_isaac", + "rand_jitter", + "rand_os", + "rand_pcg", + "rand_xorshift", + "winapi", +] + [[package]] name = "rand" version = "0.8.5" @@ -1039,10 +1073,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", + "rand_chacha 0.3.1", "rand_core 0.6.4", ] +[[package]] +name = "rand_chacha" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +dependencies = [ + "autocfg 0.1.8", + "rand_core 0.3.1", +] + [[package]] name = "rand_chacha" version = "0.3.1" @@ -1077,6 +1121,77 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_hc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_isaac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_jitter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" +dependencies = [ + "libc", + "rand_core 0.4.2", + "winapi", +] + +[[package]] +name = "rand_os" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +dependencies = [ + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.4.2", + "rdrand", + "winapi", +] + +[[package]] +name = "rand_pcg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" +dependencies = [ + "autocfg 0.1.8", + "rand_core 0.4.2", +] + +[[package]] +name = "rand_xorshift" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -1162,8 +1277,10 @@ name = "rustwallet" version = "0.1.0" dependencies = [ "anyhow", + "bitcoin_hashes 0.11.0", + "hex", "openssl", - "secp256k1 0.24.0", + "secp256k1", "serde", "serde_json", "shamir_secret_sharing", @@ -1199,18 +1316,9 @@ version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c42e6f1735c5f00f51e43e28d6634141f2bcad10931b2609ddd74a86d751260" dependencies = [ - "secp256k1-sys 0.4.2", -] - -[[package]] -name = "secp256k1" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7649a0b3ffb32636e60c7ce0d70511eda9c52c658cd0634e194d5a19943aeff" -dependencies = [ - "bitcoin_hashes", - "rand 0.8.5", - "secp256k1-sys 0.6.0", + "bitcoin_hashes 0.10.0", + "rand 0.6.5", + "secp256k1-sys", ] [[package]] @@ -1222,15 +1330,6 @@ dependencies = [ "cc", ] -[[package]] -name = "secp256k1-sys" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7058dc8eaf3f2810d7828680320acda0b25a288f6d288e19278e249bbf74226b" -dependencies = [ - "cc", -] - [[package]] name = "security-framework" version = "2.7.0" @@ -1365,7 +1464,7 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" dependencies = [ - "autocfg", + "autocfg 1.1.0", ] [[package]] @@ -1495,7 +1594,7 @@ version = "1.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0020c875007ad96677dcc890298f4b942882c5d4eb7cc8f439fc3bf813dc9c95" dependencies = [ - "autocfg", + "autocfg 1.1.0", "bytes", "libc", "memchr", @@ -1790,7 +1889,7 @@ dependencies = [ "pin-project", "reqwest", "rlp", - "secp256k1 0.21.3", + "secp256k1", "serde", "serde_json", "soketto", diff --git a/Cargo.toml b/Cargo.toml index 0e2376d..5a9bd08 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,11 +15,13 @@ crate-type = ["staticlib", "lib"] [dependencies] anyhow = "1.0.65" +bitcoin_hashes = "0.11.0" +hex = "0.4.3" openssl = { version = "0.10.41", features = ["vendored"] } -secp256k1 = { version = "0.24.0", features = ["rand", "bitcoin_hashes"] } +secp256k1 = { version = "0.21.3", features = ["rand-std", "bitcoin_hashes", "recovery"] } serde = { version = "1.0.145", features = ["derive"]} serde_json = "1.0.85" shamir_secret_sharing = "0.1.1" tiny-keccak = "1.5" -web3 = "0.18.0" +web3 = { version = "0.18.0", features = ["signing"] } diff --git a/examples/test.rs b/examples/test.rs index 4630522..998f896 100644 --- a/examples/test.rs +++ b/examples/test.rs @@ -12,20 +12,20 @@ use rustwallet::{ fn main() { unsafe { - let wallet: CWallet = generate_cwallet(); - println!("---- generated a wallet to be used on C-side ----"); - print_wallet(&wallet); + // let wallet: CWallet = generate_cwallet(); + // println!("---- generated a wallet to be used on C-side ----"); + // print_wallet(&wallet); - println!("---- saving the wallet to wallet.json ----"); - save_wallet(&wallet); - println!("---- saved! ----"); + // println!("---- saving the wallet to wallet.json ----"); + // save_wallet(&wallet); + // println!("---- saved! ----"); println!("---- fetching the saved wallet to be exposed to C-side ----"); let fetched = fetch_cwallet(); print_wallet(&fetched); sign(); - free_cwallet(wallet); // 对应 generate_cwallet() + // free_cwallet(wallet); // 对应 generate_cwallet() free_cwallet(fetched); // 对应 fetch_wallet() } } diff --git a/src/wallet/wallet_impl.rs b/src/wallet/wallet_impl.rs index d2c977c..80d6e1d 100644 --- a/src/wallet/wallet_impl.rs +++ b/src/wallet/wallet_impl.rs @@ -1,20 +1,23 @@ +extern crate hex; + use anyhow::Result; -use secp256k1::ecdsa::Signature; +use web3::types::{ H256, Bytes }; +use secp256k1::{PublicKey, SecretKey, Message, Secp256k1}; use secp256k1::rand::rngs::OsRng; -use secp256k1::{PublicKey, SecretKey, Message}; -use secp256k1::hashes::sha256; use serde::{Deserialize, Serialize}; use std::io::BufWriter; use std::str::FromStr; use std::{fs::OpenOptions, io::BufReader}; use tiny_keccak::keccak256; use web3::types::Address; +use web3::signing::{ hash_message, SecretKeyRef, Key }; use std::str; use core::fmt::Write; pub fn generate_keypair() -> (SecretKey, PublicKey) { - let secp = secp256k1::Secp256k1::new(); - secp.generate_keypair(&mut OsRng) + let secp = Secp256k1::new(); + let mut rng = OsRng::new().expect("OsRng"); + secp.generate_keypair(&mut rng) } pub fn public_key_address(public_key: &PublicKey) -> Address { @@ -38,10 +41,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); - } - println!("{:?}", s); + // for i in &secret_key.secret_bytes() { + // write!(s, "{:02x}", *i).unwrap(); + // } + // println!("{:?}", s); Wallet { @@ -71,15 +74,53 @@ impl Wallet { Ok(wallet) } - pub fn sign(&self, msg: &str) -> Result { - let secp = secp256k1::Secp256k1::new(); - let message = Message::from_hashed_data::(msg.as_bytes()); + pub fn sign(&self, msg: S) -> Result<()> + where + S: AsRef<[u8]>,{ + let secp = Secp256k1::new(); println!("secret key str: {:?}", self.secret_key); - println!("message: {:?}", message); + 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 sig = secp.sign_ecdsa(&message, &pk); - let sig = secp.sign_ecdsa(&message, &pk); - Ok(sig) + + 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 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 string1 = String::with_capacity(2 * 65); + for i in bytes.iter() { + write!(string1, "{:02x}", i).unwrap(); + } + println!("web3 sign: {:?}", string1); + + 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 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(()) } } diff --git a/wallet.json b/wallet.json index 9e363dd..7fd36a7 100644 --- a/wallet.json +++ b/wallet.json @@ -1,5 +1,5 @@ { - "secret_key": "4877e4466ed17b3fa3c5040760a8401bc26565126bd611fdbd903a4652a26b37", - "public_key": "03a0b65abcf64937afff82590b1580add0a3a344e00f209de388dd1378f8162419", - "public_address": "0x5f88990fa8ad8c6e8c33929a685fadec146102f4" + "secret_key": "64a6f7baa58d7381f4068fc729568009ef8f36e9c7d9c33d2cf06afc25c01e87", + "public_key": "03b7f10a2f6e8c267c71fbf43250cc89dec346e9e82ac8588d554eea7881eb3ed2", + "public_address": "0xbee138f1dd559a9758806c0eaf9d5d12ff60aff5" } \ No newline at end of file