From 33522f5500cd81b6908184deec6bd956bb8adca2 Mon Sep 17 00:00:00 2001 From: Zhai Can Date: Sun, 12 Nov 2023 15:46:00 +0800 Subject: [PATCH 1/6] impl `std::error::Error` for Error --- src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 0cd3ac5..5966ba3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -255,6 +255,8 @@ pub enum Error { WifKey, } +impl std::error::Error for Error {} + /// Internal Functions to manipulate an arbitrary number of bytes [u8]. trait BytesManipulation { /// Encode informed data in base 58 check. From ca295eb9e48e42fc4867af1ed106ad48e87d166d Mon Sep 17 00:00:00 2001 From: Zhai Can Date: Sun, 12 Nov 2023 17:04:50 +0800 Subject: [PATCH 2/6] pass compilation under `no_std` env --- Cargo.toml | 17 +++++++++++------ src/lib.rs | 26 +++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 966a066..0a3d7b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,10 +19,15 @@ readme = "README.md" [dependencies] aes = "0.7.4" -bs58 = "0.4.0" -rand = "0.8.4" -ripemd160 = "0.9.1" +bs58 = { version = "0.4.0", default-features = false, features = ["alloc"] } +rand = { version = "0.8.4", default-features = false, features = ["alloc"] } +ripemd160 = { version = "0.9.0", default-features = false } scrypt = { version = "0.7.0", default-features = false } -secp256k1 = "0.20.3" -sha2 = "0.9.5" -unicode-normalization = "0.1.19" +secp256k1 = { version = "0.20.0", default-features = false, features = ["alloc"] } +digest = { version = "0.10.7", default-features = false } +sha2 = { version = "0.10.8", default-features = false } +unicode-normalization = { version = "0.1.19", default-features = false } + +[features] +default = ["std"] +std = ["rand/std", "sha2/std", "unicode-normalization/std", "digest/std"] \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 5966ba3..fc61358 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -169,6 +169,23 @@ //! }); //! ``` +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(not(feature = "std"))] +extern crate alloc; + +#[cfg(not(feature = "std"))] +use alloc::{ + string::String, + vec::Vec, + vec +}; + +fn f() { + let s = String::new(); + Secp256k1::::new(); +} + use aes::Aes256; use aes::cipher::{ BlockDecrypt, @@ -177,10 +194,10 @@ use aes::cipher::{ NewBlockCipher }; use rand::RngCore; +use digest::Digest; use ripemd160::Ripemd160; use scrypt::Params; use secp256k1::{Secp256k1, SecretKey, PublicKey}; -use sha2::Digest; use unicode_normalization::UnicodeNormalization; /// Number of base58 characters on every encrypted private key. @@ -255,6 +272,7 @@ pub enum Error { WifKey, } +#[cfg(feature = "std")] impl std::error::Error for Error {} /// Internal Functions to manipulate an arbitrary number of bytes [u8]. @@ -685,6 +703,7 @@ impl BytesManipulation for [u8] { #[inline] fn hash160(&self) -> [u8; 20] { let mut result = [0x00; 20]; + use ripemd160::Digest; result[..].copy_from_slice(&Ripemd160::digest(&sha2::Sha256::digest(self))); result } @@ -785,7 +804,7 @@ impl Generate for str { let mut pass_factor = [0x00; 32]; let mut seed_b = [0x00; 24]; - rand::thread_rng().fill_bytes(&mut owner_salt); + // rand::thread_rng().fill_bytes(&mut owner_salt); scrypt::scrypt( self.nfc().collect::().as_bytes(), @@ -798,7 +817,8 @@ impl Generate for str { let mut pass_point_mul = PublicKey::from_slice(&pass_point).map_err(|_| Error::PubKey)?; - rand::thread_rng().fill_bytes(&mut seed_b); + // TODO: RNG + // rand::thread_rng().fill_bytes(&mut seed_b); let factor_b = seed_b.hash256(); From bcb0188ddc44b9b5668b61fa5700b5dddb09af3f Mon Sep 17 00:00:00 2001 From: Zhai Can Date: Sun, 12 Nov 2023 17:05:24 +0800 Subject: [PATCH 3/6] use `thread_rng` under `std` environment --- Cargo.toml | 2 +- src/lib.rs | 24 +++++++++++++++++------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0a3d7b0..fdf4bb9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,4 +30,4 @@ unicode-normalization = { version = "0.1.19", default-features = false } [features] default = ["std"] -std = ["rand/std", "sha2/std", "unicode-normalization/std", "digest/std"] \ No newline at end of file +std = ["rand/std", "rand/std_rng", "sha2/std", "unicode-normalization/std", "digest/std"] \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index fc61358..4606de9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -181,10 +181,15 @@ use alloc::{ vec }; -fn f() { - let s = String::new(); - Secp256k1::::new(); -} +#[cfg(feature = "std")] +extern crate std; + +#[cfg(feature = "std")] +use std::{ + string::String, + vec, + vec::Vec, +}; use aes::Aes256; use aes::cipher::{ @@ -804,7 +809,7 @@ impl Generate for str { let mut pass_factor = [0x00; 32]; let mut seed_b = [0x00; 24]; - // rand::thread_rng().fill_bytes(&mut owner_salt); + fill_random_bytes(&mut owner_salt); scrypt::scrypt( self.nfc().collect::().as_bytes(), @@ -817,8 +822,7 @@ impl Generate for str { let mut pass_point_mul = PublicKey::from_slice(&pass_point).map_err(|_| Error::PubKey)?; - // TODO: RNG - // rand::thread_rng().fill_bytes(&mut seed_b); + fill_random_bytes(&mut owner_salt); let factor_b = seed_b.hash256(); @@ -884,6 +888,12 @@ impl Generate for str { } } +fn fill_random_bytes(buf: &mut [u8]) { + #[cfg(feature = "std")] + rand::thread_rng().fill_bytes(buf) + // TODO: no_std +} + impl PrivateKeyManipulation for [u8; 32] { #[inline] fn public(&self, compress: bool) -> Result, Error> { From deb6dbd74b0edc5c8fb9afa4822ca5b5615dd0ba Mon Sep 17 00:00:00 2001 From: Zhai Can Date: Sun, 12 Nov 2023 17:10:24 +0800 Subject: [PATCH 4/6] cargo clippy --- src/lib.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4606de9..2731b25 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -198,7 +198,6 @@ use aes::cipher::{ generic_array::GenericArray, NewBlockCipher }; -use rand::RngCore; use digest::Digest; use ripemd160::Ripemd160; use scrypt::Params; @@ -716,7 +715,7 @@ impl BytesManipulation for [u8] { #[inline] fn hash256(&self) -> [u8; 32] { let mut result = [0x00; 32]; - result[..].copy_from_slice(&sha2::Sha256::digest(&sha2::Sha256::digest(self))); + result[..].copy_from_slice(&sha2::Sha256::digest(sha2::Sha256::digest(self))); result } @@ -888,10 +887,15 @@ impl Generate for str { } } +#[inline] fn fill_random_bytes(buf: &mut [u8]) { #[cfg(feature = "std")] - rand::thread_rng().fill_bytes(buf) + { + use rand::RngCore; + rand::thread_rng().fill_bytes(buf) + } // TODO: no_std + let _ = buf; } impl PrivateKeyManipulation for [u8; 32] { @@ -1189,7 +1193,7 @@ mod tests { Err(Error::WifKey) ); assert_eq!( - "KzkcmnPaJd7mqT47Rnk9XMGRfW2wfo7ar2M2o6Yoe6Rdgbg2bHM9".replace("d", "b").decode_wif(), + "KzkcmnPaJd7mqT47Rnk9XMGRfW2wfo7ar2M2o6Yoe6Rdgbg2bHM9".replace('d', "b").decode_wif(), Err(Error::Checksum) ); assert_eq!(["a"; 51].concat().decode_wif(), Err(Error::WifKey)); @@ -1206,7 +1210,7 @@ mod tests { } assert!(TV_ENCRYPTED[1].decrypt("Satoshi").is_ok()); assert_eq!(TV_ENCRYPTED[1].decrypt("wrong"), Err(Error::Pass)); - assert_eq!(TV_ENCRYPTED[1].replace("X", "x").decrypt("Satoshi"), Err(Error::Checksum)); + assert_eq!(TV_ENCRYPTED[1].replace('X', "x").decrypt("Satoshi"), Err(Error::Checksum)); assert_eq!(TV_ENCRYPTED[1][1..].decrypt("Satoshi"), Err(Error::EncKey)); } From 7265fa7b50b6b76faef2c206cf2205f0a9668c5c Mon Sep 17 00:00:00 2001 From: Zhai Can Date: Sun, 12 Nov 2023 17:23:32 +0800 Subject: [PATCH 5/6] fix a copy-paste mistake --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 2731b25..0555618 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -821,7 +821,7 @@ impl Generate for str { let mut pass_point_mul = PublicKey::from_slice(&pass_point).map_err(|_| Error::PubKey)?; - fill_random_bytes(&mut owner_salt); + fill_random_bytes(&mut seed_b); let factor_b = seed_b.hash256(); From 3011932337dca015e5304153227b2a640488b249 Mon Sep 17 00:00:00 2001 From: Zhai Can Date: Sun, 12 Nov 2023 18:03:54 +0800 Subject: [PATCH 6/6] add `Generate::generate_rng` function --- src/lib.rs | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 0555618..ce499a2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -199,6 +199,7 @@ use aes::cipher::{ NewBlockCipher }; use digest::Digest; +use rand::{RngCore}; use ripemd160::Ripemd160; use scrypt::Params; use secp256k1::{Secp256k1, SecretKey, PublicKey}; @@ -651,7 +652,10 @@ pub trait Generate { /// .decrypt("\u{03d2}\u{0301}\u{0000}\u{010400}\u{01f4a9}").is_ok() /// ); /// ``` - fn generate(&self, compress: bool) -> Result; + #[cfg(feature = "std")] + fn generate(&self, compress: bool) -> Result; + + fn generate_rng(&self, compress: bool, rng: &mut R) -> Result; } /// Internal trait to manipulate private keys (32 bytes). @@ -802,13 +806,17 @@ impl Encrypt for [u8; 32] { } impl Generate for str { - #[inline] - fn generate(&self, compress: bool) -> Result { + #[cfg(feature = "std")] + fn generate(&self, compress: bool) -> Result { + self.generate_rng(compress, &mut rand::thread_rng()) + } + + fn generate_rng(&self, compress: bool, rng: &mut R) -> Result { let mut owner_salt = [0x00; 8]; let mut pass_factor = [0x00; 32]; let mut seed_b = [0x00; 24]; - fill_random_bytes(&mut owner_salt); + rng.fill_bytes(&mut owner_salt); scrypt::scrypt( self.nfc().collect::().as_bytes(), @@ -821,7 +829,7 @@ impl Generate for str { let mut pass_point_mul = PublicKey::from_slice(&pass_point).map_err(|_| Error::PubKey)?; - fill_random_bytes(&mut seed_b); + rng.fill_bytes(&mut seed_b); let factor_b = seed_b.hash256(); @@ -887,17 +895,6 @@ impl Generate for str { } } -#[inline] -fn fill_random_bytes(buf: &mut [u8]) { - #[cfg(feature = "std")] - { - use rand::RngCore; - rand::thread_rng().fill_bytes(buf) - } - // TODO: no_std - let _ = buf; -} - impl PrivateKeyManipulation for [u8; 32] { #[inline] fn public(&self, compress: bool) -> Result, Error> {