From 2d91063e67e0ac1f38e5d2348d9128b8b85da7ee Mon Sep 17 00:00:00 2001 From: Csongor Bokay <8850110+bcsongor@users.noreply.github.com> Date: Wed, 10 Sep 2025 01:47:51 +0200 Subject: [PATCH 1/5] Update secp256k1 version to 0.31.1 --- Cargo.lock | 127 +++++++++++++++++++++++++++++++++++++++++++++------- Cargo.toml | 6 +-- src/main.rs | 5 ++- 3 files changed, 118 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2d6d3bc..d9c18b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "ahash" @@ -8,7 +8,7 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "getrandom", + "getrandom 0.2.10", "once_cell", "version_check", ] @@ -57,6 +57,22 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "bitcoin-io" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b47c4ab7a93edb0c7198c5535ed9b52b63095f4e9b45279c6736cec4b856baf" + +[[package]] +name = "bitcoin_hashes" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16" +dependencies = [ + "bitcoin-io", + "hex-conservative", +] + [[package]] name = "bitflags" version = "2.3.3" @@ -367,7 +383,19 @@ checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.5+wasi-0.2.4", ] [[package]] @@ -409,6 +437,15 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +[[package]] +name = "hex-conservative" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd" +dependencies = [ + "arrayvec", +] + [[package]] name = "is-terminal" version = "0.4.9" @@ -452,9 +489,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.147" +version = "0.2.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" [[package]] name = "linux-raw-sys" @@ -598,6 +635,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "radium" version = "0.7.0" @@ -611,8 +654,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", ] [[package]] @@ -622,7 +675,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", ] [[package]] @@ -631,7 +694,16 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.10", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.3", ] [[package]] @@ -724,7 +796,7 @@ dependencies = [ "byteorder", "bytes", "num-traits", - "rand", + "rand 0.8.5", "rkyv", "serde", "serde_json", @@ -772,19 +844,20 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "secp256k1" -version = "0.28.2" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24b59d129cdadea20aea4fb2352fa053712e5d713eee47d700cd4b2bc002f10" +checksum = "2c3c81b43dc2d8877c216a3fccf76677ee1ebccd429566d3e67447290d0c42b2" dependencies = [ - "rand", + "bitcoin_hashes", + "rand 0.9.2", "secp256k1-sys", ] [[package]] name = "secp256k1-sys" -version = "0.9.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d1746aae42c19d583c3c1a8c646bfad910498e2051c551a7f2e3c0c9fbb7eb" +checksum = "dcb913707158fadaf0d8702c2db0e857de66eb003ccfdda5924b5f5ac98efb38" dependencies = [ "cc", ] @@ -940,6 +1013,24 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.14.5+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4494f6290a82f5fe584817a676a34b9d6763e8d9d18204009fb31dceca98fd4" +dependencies = [ + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.0+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03fa2761397e5bd52002cd7e73110c71af2109aca4e521a9f40473fe685b0a24" +dependencies = [ + "wit-bindgen", +] + [[package]] name = "wasm-bindgen" version = "0.2.80" @@ -1101,6 +1192,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +[[package]] +name = "wit-bindgen" +version = "0.45.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c573471f125075647d03df72e026074b7203790d41351cd6edc96f46bcccd36" + [[package]] name = "wyz" version = "0.5.1" diff --git a/Cargo.toml b/Cargo.toml index 199f9af..aee925d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ authors = ["Csongor Bokay <8850110+bcsongor@users.noreply.github.com>"] license = "GPL-3.0-or-later" keywords = ["blockchain", "ethereum", "ethereum-address", "vanity-address", "vanitygen"] categories = ["command-line-utilities"] -edition = "2021" +edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -14,7 +14,7 @@ edition = "2021" getopts = "0.2" num_cpus = "1" regex = "1" -secp256k1 = { version = "0.28", features = ["std", "rand-std", "global-context"] } +secp256k1 = { version = "0.31.1", features = ["rand", "global-context"] } tiny-keccak = { version = "2", features = ["keccak"] } rust_decimal = { version = "1", features = ["maths"] } @@ -30,4 +30,4 @@ name = "hex" harness = false [profile.release] -lto = "fat" \ No newline at end of file +lto = "fat" diff --git a/src/main.rs b/src/main.rs index bf6d639..f44b96c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,7 @@ use getopts::{Matches, Options}; use regex::{Regex, RegexBuilder}; use rust_decimal::{Decimal, MathematicalOps}; use secp256k1::generate_keypair; -use secp256k1::rand::thread_rng; +use secp256k1::rand::rng; use std::process::exit; use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; use std::sync::Arc; @@ -313,8 +313,9 @@ fn main() { let mut addr_hex_buf = [0u8; ADDRESS_HEX_LENGTH]; let mut checksum_addr_hex_buf = [0u8; ADDRESS_HEX_LENGTH]; + let mut rng = rng(); while !found.load(Ordering::Acquire) { - let (sk, pk) = generate_keypair(&mut thread_rng()); + let (sk, pk) = generate_keypair(&mut rng); // The uncompressed public key is prefixed with a constant 0x04 byte meaning it has // both X and Y coordinates. Let's get rid of it! From 9405760f2c910ead6fed3c38272540db8c6d6d2e Mon Sep 17 00:00:00 2001 From: Csongor Bokay <8850110+bcsongor@users.noreply.github.com> Date: Thu, 11 Sep 2025 00:01:17 +0200 Subject: [PATCH 2/5] Fix incorrect buffer size check in to_checksum_address --- benches/checksum.rs | 2 +- benches/hex.rs | 2 +- src/main.rs | 9 ++++----- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/benches/checksum.rs b/benches/checksum.rs index 4c931c8..19afa4c 100644 --- a/benches/checksum.rs +++ b/benches/checksum.rs @@ -1,4 +1,4 @@ -use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use criterion::{Criterion, black_box, criterion_group, criterion_main}; use tiny_keccak::{Hasher, Keccak}; const ADDRESS_HEX_LENGTH: usize = 40; diff --git a/benches/hex.rs b/benches/hex.rs index 5b6e608..790f720 100644 --- a/benches/hex.rs +++ b/benches/hex.rs @@ -1,4 +1,4 @@ -use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use criterion::{Criterion, black_box, criterion_group, criterion_main}; use std::fmt::Write; const KECCAK256_HASH_BYTES_LENGTH: usize = 32; diff --git a/src/main.rs b/src/main.rs index f44b96c..9e4b661 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,8 +4,8 @@ use rust_decimal::{Decimal, MathematicalOps}; use secp256k1::generate_keypair; use secp256k1::rand::rng; use std::process::exit; -use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; use std::sync::Arc; +use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; use std::time::{Duration, Instant}; use std::{env, thread}; use tiny_keccak::{Hasher, Keccak}; @@ -162,7 +162,7 @@ fn to_checksum_address<'a>(addr: &str, checksum_addr_hex_buf: &'a mut [u8]) -> & panic!("to_checksum_address: invalid address"); } - if checksum_addr_hex_buf.len() < ADDRESS_BYTES_LENGTH { + if checksum_addr_hex_buf.len() < ADDRESS_HEX_LENGTH { panic!("to_checksum_address: buffer overflow"); } @@ -424,8 +424,7 @@ fn main() { #[cfg(test)] mod tests { use crate::{ - calc_difficulty, calc_probability, is_addr_matching, is_lower_hex, to_checksum_address, - to_hex, AddressPart, Rules, ADDRESS_HEX_LENGTH, + calc_difficulty, calc_probability, is_addr_matching, is_lower_hex, to_checksum_address, to_hex, AddressPart, Rules, ADDRESS_HEX_LENGTH }; use regex::RegexBuilder; use rust_decimal::Decimal; @@ -495,7 +494,7 @@ mod tests { #[should_panic(expected = "to_checksum_address: buffer overflow")] fn it_should_fail_to_checksum_on_buffer_overflow() { let addr = "00000000219ab540356cbb839cbe05303d7705fa"; - let mut checksum_addr_buf = [0u8; 2]; + let mut checksum_addr_buf = [0u8; ADDRESS_HEX_LENGTH - 1]; to_checksum_address(addr, &mut checksum_addr_buf); } From e697ba2969addd36a9d95e1d9130d0744de2f450 Mon Sep 17 00:00:00 2001 From: Csongor Bokay <8850110+bcsongor@users.noreply.github.com> Date: Thu, 11 Sep 2025 00:19:37 +0200 Subject: [PATCH 3/5] Optimise to_checksum_address: use hash nibbles, drop hex conversion --- src/main.rs | 49 ++++++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/src/main.rs b/src/main.rs index 9e4b661..19e1b01 100644 --- a/src/main.rs +++ b/src/main.rs @@ -121,7 +121,6 @@ impl TryFrom for Configuration { const ADDRESS_HEX_LENGTH: usize = 40; const ADDRESS_BYTES_LENGTH: usize = ADDRESS_HEX_LENGTH / 2; const KECCAK256_HASH_BYTES_LENGTH: usize = 32; -const KECCAK256_HASH_HEX_LENGTH: usize = KECCAK256_HASH_BYTES_LENGTH * 2; const PUBLIC_KEY_BYTES_START_INDEX: usize = 1; const ADDRESS_BYTES_START_INDEX: usize = KECCAK256_HASH_BYTES_LENGTH - ADDRESS_BYTES_LENGTH; @@ -170,23 +169,23 @@ fn to_checksum_address<'a>(addr: &str, checksum_addr_hex_buf: &'a mut [u8]) -> & let mut hash = [0u8; KECCAK256_HASH_BYTES_LENGTH]; let mut hasher = Keccak::v256(); - hasher.update(&addr_bytes); + hasher.update(addr_bytes); hasher.finalize(&mut hash); - let mut buf = [0u8; KECCAK256_HASH_HEX_LENGTH]; - let addr_hash = to_hex(&hash, &mut buf); - let addr_hash_bytes = addr_hash.as_bytes(); - - for i in 0..addr_bytes.len() { - let byte = addr_bytes[i]; - checksum_addr_hex_buf[i] = if addr_hash_bytes[i] >= 56 { - byte.to_ascii_uppercase() + for (i, &ch) in addr_bytes.iter().enumerate() { + let nibble = if (i & 1) == 0 { + hash[i / 2] >> 4 // High part. } else { - byte // Already lowercase. - } + hash[i / 2] & 0x0f // Low part. + }; + checksum_addr_hex_buf[i] = if nibble > 7 { + ch.to_ascii_uppercase() + } else { + ch + }; } - std::str::from_utf8(&checksum_addr_hex_buf[0..addr.len()]) + std::str::from_utf8(&checksum_addr_hex_buf[..addr_bytes.len()]) .expect("to_checksum_address: failed to convert byte array to hex string") } @@ -468,18 +467,18 @@ mod tests { #[test] fn it_should_checksum_address() { - let addr = "00000000219ab540356cbb839cbe05303d7705fa"; - let mut checksum_addr_buf = [0u8; ADDRESS_HEX_LENGTH]; - assert_eq!( - to_checksum_address(addr, &mut checksum_addr_buf), - "00000000219ab540356cBB839Cbe05303d7705Fa" - ); - - let mut checksum_addr_buf = [0u8; ADDRESS_HEX_LENGTH * 2]; - assert_eq!( - to_checksum_address(addr, &mut checksum_addr_buf), - "00000000219ab540356cBB839Cbe05303d7705Fa" - ); + let checksum_addrs = [ + "00000000219ab540356cBB839Cbe05303d7705Fa", + "d8dA6BF26964aF9D7eEd9e03E53415D37aA96045", + "C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + "A0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + ]; + + for &checksum_addr in &checksum_addrs { + let addr_lower = checksum_addr.to_lowercase(); + let mut buf = [0u8; ADDRESS_HEX_LENGTH]; + assert_eq!(to_checksum_address(&addr_lower, &mut buf), checksum_addr); + } } #[test] From 515dd6007b9f34376c5d52401d5521ddb1d96648 Mon Sep 17 00:00:00 2001 From: Csongor Bokay <8850110+bcsongor@users.noreply.github.com> Date: Fri, 12 Sep 2025 23:47:34 +0200 Subject: [PATCH 4/5] Bump version to 1.2.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d9c18b1..c21f57a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -937,7 +937,7 @@ dependencies = [ [[package]] name = "tinyvanityeth" -version = "1.1.2" +version = "1.2.0" dependencies = [ "criterion", "getopts", diff --git a/Cargo.toml b/Cargo.toml index aee925d..9e3c54e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tinyvanityeth" -version = "1.1.2" +version = "1.2.0" description = "Tiny and fast command line tool to find vanity Ethereum addresses." authors = ["Csongor Bokay <8850110+bcsongor@users.noreply.github.com>"] license = "GPL-3.0-or-later" From 66e68c749e0b8e10b3b8ca61b3ba0cac7482d8cd Mon Sep 17 00:00:00 2001 From: Csongor Bokay <8850110+bcsongor@users.noreply.github.com> Date: Fri, 12 Sep 2025 23:55:17 +0200 Subject: [PATCH 5/5] Update benckmarks --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ac1f3c8..37ef368 100644 --- a/README.md +++ b/README.md @@ -84,19 +84,19 @@ like [secp256k1](https://github.com/rust-bitcoin/rust-secp256k1/) and Case-insensitive search for an address with the prefix `5eaf00d`. 🍣 -**Apple M1 Max** (`stable-aarch64-apple-darwin - rustc 1.61.0`) +**Apple M1 Max** (`stable-aarch64-apple-darwin - rustc 1.89.0`) | Platform | Speed | |:----------------------------------------|------------------:| -| tinyvanityeth | ~488,247 addr/sec | +| tinyvanityeth | ~580,748 addr/sec | | [vanity-eth.tk](https://vanity-eth.tk/) | ~19,047 addr/sec | -**Intel Xeon E5-1620v2** (`stable-x86_64-pc-windows-msvc - rustc 1.61.0`) +**Intel Core i9-13900KS** (`stable-x86_64-pc-windows-msvc - rustc 1.89.0`) | Platform | Speed | |:----------------------------------------|-----------------:| -| tinyvanityeth | ~77,084 addr/sec | -| [vanity-eth.tk](https://vanity-eth.tk/) | ~4,889 addr/sec | +| tinyvanityeth | ~934,903 addr/sec | +| [vanity-eth.tk](https://vanity-eth.tk/) | ~51,762 addr/sec | ## 🧑‍💻 Development