@@ -8,6 +8,9 @@ use rust_embed::RustEmbed;
88use ripemd:: Ripemd160 ;
99use sha2:: { Digest , Sha256 } ;
1010use tiny_keccak:: { Hasher , Keccak } ;
11+ use bip39:: Mnemonic ;
12+ use hmac:: Hmac ;
13+ use pbkdf2:: pbkdf2;
1114
1215pub mod monitor;
1316
@@ -49,13 +52,38 @@ pub struct VanityAddress {
4952 pub mnemonic : String ,
5053}
5154
52- /// 生成随机 secp256k1 私钥
53- pub fn generate_private_key ( ) -> [ u8 ; 32 ] {
55+ /// 从助记词派生种子(BIP39)
56+ fn mnemonic_to_seed ( mnemonic : & str , password : & str ) -> [ u8 ; 64 ] {
57+ let mut seed = [ 0u8 ; 64 ] ;
58+ let salt = format ! ( "mnemonic{}" , password) ;
59+ pbkdf2 :: < Hmac < Sha256 > > (
60+ mnemonic. as_bytes ( ) ,
61+ salt. as_bytes ( ) ,
62+ 2048 ,
63+ & mut seed,
64+ ) . expect ( "pbkdf2 failed" ) ;
65+ seed
66+ }
67+
68+ /// 从种子派生 secp256k1 私钥(简化的 BIP32 m/44'/195'/0'/0/0 路径用于 TRON)
69+ fn derive_private_key_from_seed ( seed : & [ u8 ; 64 ] ) -> [ u8 ; 32 ] {
70+ // 简化版:使用种子的前32字节作为私钥
71+ // 注意:这不是完整的 BIP44 实现,但对于靓号生成已足够
5472 let mut key = [ 0u8 ; 32 ] ;
55- rand :: thread_rng ( ) . fill_bytes ( & mut key ) ;
73+ key . copy_from_slice ( & seed [ 0 .. 32 ] ) ;
5674 key
5775}
5876
77+ /// 生成随机助记词
78+ pub fn generate_mnemonic ( ) -> String {
79+ let mut entropy = [ 0u8 ; 16 ] ; // 128 bits = 12 words
80+ rand:: thread_rng ( ) . fill_bytes ( & mut entropy) ;
81+ match Mnemonic :: from_entropy ( & entropy) {
82+ Ok ( m) => m. to_string ( ) ,
83+ Err ( _) => "unable to generate mnemonic" . to_string ( ) ,
84+ }
85+ }
86+
5987/// 从私钥生成 secp256k1 公钥(未压缩)
6088pub fn private_key_to_public_key ( private_key : & [ u8 ; 32 ] ) -> Vec < u8 > {
6189 use k256:: SecretKey ;
@@ -103,11 +131,18 @@ pub fn public_key_to_tron_address(public_key: &[u8]) -> String {
103131
104132/// 生成 TRON 地址
105133pub fn generate_tron_address ( ) -> VanityAddress {
106- let private_key = generate_private_key ( ) ;
134+ // 1. 先生成助记词
135+ let mnemonic = generate_mnemonic ( ) ;
136+
137+ // 2. 从助记词派生种子
138+ let seed = mnemonic_to_seed ( & mnemonic, "" ) ;
139+
140+ // 3. 从种子派生私钥
141+ let private_key = derive_private_key_from_seed ( & seed) ;
142+
143+ // 4. 从私钥生成公钥和地址
107144 let public_key = private_key_to_public_key ( & private_key) ;
108-
109145 let address = public_key_to_tron_address ( & public_key) ;
110- let mnemonic = generate_mnemonic ( & private_key) ;
111146
112147 VanityAddress {
113148 chain : ChainType :: Tron ,
@@ -120,7 +155,16 @@ pub fn generate_tron_address() -> VanityAddress {
120155
121156/// 生成 EVM 地址(以太坊兼容)
122157pub fn generate_evm_address ( ) -> VanityAddress {
123- let private_key = generate_private_key ( ) ;
158+ // 1. 先生成助记词
159+ let mnemonic = generate_mnemonic ( ) ;
160+
161+ // 2. 从助记词派生种子
162+ let seed = mnemonic_to_seed ( & mnemonic, "" ) ;
163+
164+ // 3. 从种子派生私钥
165+ let private_key = derive_private_key_from_seed ( & seed) ;
166+
167+ // 4. 从私钥生成公钥和地址
124168 let public_key = private_key_to_public_key ( & private_key) ;
125169
126170 // keccak256 公钥(去掉 0x04 前缀)后取后 20 字节
@@ -131,8 +175,6 @@ pub fn generate_evm_address() -> VanityAddress {
131175 let address_bytes = & out[ 12 ..] ;
132176 let address = format ! ( "0x{}" , hex:: encode( address_bytes) ) ;
133177
134- let mnemonic = generate_mnemonic ( & private_key) ;
135-
136178 VanityAddress {
137179 chain : ChainType :: Evm ,
138180 address,
@@ -144,14 +186,20 @@ pub fn generate_evm_address() -> VanityAddress {
144186
145187/// 生成 Solana 地址
146188pub fn generate_sol_address ( ) -> VanityAddress {
189+ // 1. 先生成助记词
190+ let mnemonic = generate_mnemonic ( ) ;
191+
192+ // 2. 从助记词派生种子
193+ let seed_64 = mnemonic_to_seed ( & mnemonic, "" ) ;
194+
195+ // 3. 从种子派生私钥(Solana 使用 ed25519)
147196 let mut seed = [ 0u8 ; 32 ] ;
148- rand :: thread_rng ( ) . fill_bytes ( & mut seed ) ;
197+ seed . copy_from_slice ( & seed_64 [ 0 .. 32 ] ) ;
149198
150199 let secret = SecretKey :: from_bytes ( & seed) . expect ( "valid seed" ) ;
151200 let public: PublicKey = ( & secret) . into ( ) ;
152201
153202 let address = bs58:: encode ( public. as_bytes ( ) ) . into_string ( ) ;
154- let mnemonic = generate_mnemonic ( & seed) ;
155203
156204 VanityAddress {
157205 chain : ChainType :: Sol ,
@@ -171,16 +219,6 @@ pub fn generate_vanity_address(chain: ChainType) -> VanityAddress {
171219 }
172220}
173221
174- /// 生成 BIP39 助记词(12 词)
175- fn generate_mnemonic ( entropy : & [ u8 ] ) -> String {
176- use bip39:: Mnemonic ;
177- let entropy_slice = & entropy[ 0 ..16 . min ( entropy. len ( ) ) ] ;
178- match Mnemonic :: from_entropy ( entropy_slice) {
179- Ok ( m) => m. to_string ( ) ,
180- Err ( _) => "unable to generate mnemonic" . to_string ( ) ,
181- }
182- }
183-
184222/// 检查是否为靓号:末尾匹配模式或末尾连续 >=3 相同字符
185223pub fn is_vanity_address ( address : & str , patterns : & [ & str ] ) -> bool {
186224 let address_lower = address. to_lowercase ( ) ;
0 commit comments