@@ -13,9 +13,9 @@ use alloy::{
1313 primitives:: { keccak256, Address , U256 } ,
1414} ;
1515use clap:: Args ;
16- use sha2:: { digest:: generic_array:: GenericArray , Digest } ;
16+ use sha2:: digest:: { generic_array:: GenericArray , FixedOutputReset , Update } ;
1717use unionlabs:: {
18- primitives:: { H160 , H256 } ,
18+ primitives:: { ByteArrayExt , H160 , H256 } ,
1919 typenum,
2020} ;
2121
@@ -90,14 +90,16 @@ impl Cmd {
9090 } )
9191 . unwrap_or ( ( Vec :: new ( ) , None ) ) ;
9292
93- let mut salt_preimage = ( <H160 >:: new ( self . sender . into ( ) ) . to_string ( ) + "/" )
93+ let mut salt_preimage: [ u8 ; 42 + 1 + 32 ] = ( <H160 >:: new ( self . sender . into ( ) ) . to_string ( )
94+ + "/" )
9495 . into_bytes ( )
9596 . into_iter ( )
9697 . chain ( [ 0 ; 32 ] )
97- . collect :: < Vec < _ > > ( ) ;
98- let range = ( salt_preimage . len ( ) - 32 ) ..salt_preimage . len ( ) ;
99-
98+ . collect :: < Vec < _ > > ( )
99+ . try_into ( )
100+ . unwrap ( ) ;
100101 let seed = self . seed ;
102+ let range = ( salt_preimage. len ( ) - 32 ) ..salt_preimage. len ( ) ;
101103
102104 let mut handles = Vec :: new ( ) ;
103105 for i in 0 ..self . threads {
@@ -106,112 +108,98 @@ impl Cmd {
106108 let deployer = self . deployer ;
107109 let prefix_bytes = prefix_bytes. clone ( ) ;
108110 let suffix_bytes = suffix_bytes. clone ( ) ;
109- let mut salt_preimage = salt_preimage. clone ( ) ;
110- let range = range. clone ( ) ;
111111
112112 let handle = thread:: spawn ( move || -> Option < H256 > {
113113 let mut local_attempts = 0u64 ;
114114
115115 let mut salt = ( 0 ..( i + 1 ) ) . fold ( seed, |acc, _| {
116- U256 :: from_be_bytes ( sha2:: Sha256 :: digest ( acc. to_be_bytes :: < 32 > ( ) ) . into ( ) )
116+ U256 :: from_be_bytes (
117+ <sha2:: Sha256 as sha2:: Digest >:: digest ( acc. to_be_bytes :: < 32 > ( ) ) . into ( ) ,
118+ )
117119 } ) ;
118120 println ! ( "{i}: {salt}" ) ;
119121
122+ * salt_preimage. array_slice_mut :: < { 42 + 1 } , 32 > ( ) = salt. to_be_bytes ( ) ;
123+
124+ let mut counter =
125+ u64:: from_be_bytes ( salt. to_be_bytes :: < 32 > ( ) . array_slice :: < 0 , 8 > ( ) ) ;
126+
127+ let mut proxy_preimage: [ u8 ; 1 + 20 + 32 + 32 ] = [ 0xff ]
128+ . into_iter ( )
129+ . chain ( deployer)
130+ . chain ( salt. to_be_bytes :: < 32 > ( ) )
131+ . chain ( hex ! (
132+ "21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f"
133+ ) )
134+ . collect :: < Vec < _ > > ( )
135+ . try_into ( )
136+ . unwrap ( ) ;
137+
138+ let mut hasher = <keccak_asm:: Keccak256 as sha2:: Digest >:: new ( ) ;
139+
140+ let mut out: GenericArray < u8 , typenum:: U32 > = [ 0_u8 ; 32 ] . into ( ) ;
141+
120142 while !found. load ( Ordering :: Relaxed ) {
121- loop {
122- salt += U256 :: ONE ;
123- salt_preimage[ range. clone ( ) ] . copy_from_slice ( & salt. to_be_bytes :: < 32 > ( ) ) ;
124-
125- let addr = {
126- let salt = keccak_asm:: Keccak256 :: digest ( & salt_preimage) ;
127- let mut out: GenericArray < u8 , typenum:: U32 > = [ 0_u8 ; 32 ] . into ( ) ;
128- keccak_asm:: Keccak256 :: new ( )
129- . chain_update ( [ 0xff ] )
130- . chain_update ( deployer)
131- . chain_update ( salt)
132- . chain_update ( hex ! ( "21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f" ) )
133- . finalize_into ( & mut out) ;
134-
135- let mut address_out: GenericArray < u8 , typenum:: U32 > = [ 0_u8 ; 32 ] . into ( ) ;
136- keccak_asm:: Keccak256 :: new ( )
137- . chain_update ( [ 0xd6 , 0x94 ] )
138- . chain_update ( & out[ 12 ..] )
139- . chain_update ( [ 0x01 ] )
140- . finalize_into ( & mut address_out) ;
141-
142- Address :: from_slice ( & address_out[ 12 ..] )
143- } ;
143+ ' inner: while local_attempts < 100000 {
144+ * salt_preimage. array_slice_mut :: < { 42 + 1 } , 8 > ( ) = counter. to_be_bytes ( ) ;
144145
145- let address_bytes = addr. as_slice ( ) ;
146+ <_ as Update >:: update ( & mut hasher, & salt_preimage) ;
147+ <_ as FixedOutputReset >:: finalize_into_reset (
148+ & mut hasher,
149+ proxy_preimage. array_slice_mut :: < 21 , 32 > ( ) . into ( ) ,
150+ ) ;
146151
147- let matches_prefix = if prefix_bytes. is_empty ( ) && prefix_nibble. is_none ( ) {
148- true
149- } else {
150- let full_bytes_match = if prefix_bytes. is_empty ( ) {
151- true
152- } else if address_bytes. len ( ) < prefix_bytes. len ( ) {
153- false
154- } else {
155- address_bytes[ ..prefix_bytes. len ( ) ] == prefix_bytes[ ..]
156- } ;
152+ <_ as Update >:: update ( & mut hasher, & proxy_preimage) ;
153+ <_ as FixedOutputReset >:: finalize_into_reset ( & mut hasher, & mut out) ;
154+
155+ <_ as Update >:: update ( & mut hasher, & [ 0xd6 , 0x94 ] ) ;
156+ <_ as Update >:: update ( & mut hasher, & out[ 12 ..] ) ;
157+ <_ as Update >:: update ( & mut hasher, & [ 0x01 ] ) ;
158+ <_ as FixedOutputReset >:: finalize_into_reset ( & mut hasher, & mut out) ;
159+
160+ let addr_bytes = & out[ 12 ..] ;
157161
162+ let matches_prefix = {
158163 if let Some ( nibble) = prefix_nibble {
159- if address_bytes. len ( ) <= prefix_bytes. len ( ) {
160- false
161- } else {
162- let byte_to_check = address_bytes[ prefix_bytes. len ( ) ] ;
163- let high_nibble = ( byte_to_check >> 4 ) & 0xF ;
164- full_bytes_match && high_nibble == nibble
165- }
164+ let bytes_match = addr_bytes[ ..prefix_bytes. len ( ) ] == prefix_bytes;
165+ bytes_match
166+ && ( ( addr_bytes[ prefix_bytes. len ( ) ] >> 4 ) & 0xF == nibble)
166167 } else {
167- full_bytes_match
168+ addr_bytes [ ..prefix_bytes . len ( ) ] == prefix_bytes
168169 }
169170 } ;
170171
171- let matches_suffix =
172- if suffix_bytes. is_empty ( ) && suffix_leading_nibble. is_none ( ) {
173- true
174- } else if let Some ( leading_nibble) = suffix_leading_nibble {
175- let required_bytes = suffix_bytes. len ( ) + 1 ; // +1 for the nibble
176- if address_bytes. len ( ) < required_bytes {
177- false
178- } else {
179- let suffix_start = address_bytes. len ( ) - suffix_bytes. len ( ) ;
180- let bytes_match = if suffix_bytes. is_empty ( ) {
181- true
182- } else {
183- address_bytes[ suffix_start..] == suffix_bytes[ ..]
184- } ;
185-
186- let nibble_byte_index =
187- address_bytes. len ( ) - suffix_bytes. len ( ) - 1 ;
188- let byte_with_nibble = address_bytes[ nibble_byte_index] ;
189- let low_nibble = byte_with_nibble & 0xF ;
190- let nibble_matches = low_nibble == leading_nibble;
191-
192- bytes_match && nibble_matches
193- }
194- } else if address_bytes. len ( ) < suffix_bytes. len ( ) {
195- false
196- } else {
197- let suffix_start = address_bytes. len ( ) - suffix_bytes. len ( ) ;
198- address_bytes[ suffix_start..] == suffix_bytes[ ..]
199- } ;
172+ let matches_suffix = || {
173+ if let Some ( leading_nibble) = suffix_leading_nibble {
174+ let bytes_match =
175+ addr_bytes[ 20 - suffix_bytes. len ( ) ..] == suffix_bytes;
200176
201- local_attempts += 1 ;
177+ bytes_match
178+ && ( addr_bytes[ 20 - suffix_bytes. len ( ) - 1 ] & 0xF
179+ == leading_nibble)
180+ } else {
181+ addr_bytes[ 20 - suffix_bytes. len ( ) ..] == suffix_bytes
182+ }
183+ } ;
202184
203- if matches_prefix && matches_suffix {
185+ if matches_prefix && matches_suffix ( ) {
186+ let salt_bytes =
187+ H256 :: new ( salt_preimage. array_slice :: < { 42 + 1 } , 32 > ( ) ) ;
204188 found. store ( true , Ordering :: Relaxed ) ;
205189 total_attempts. fetch_add ( local_attempts, Ordering :: Relaxed ) ;
206- return Some ( salt. to_be_bytes :: < 32 > ( ) . into ( ) ) ;
207- }
190+ println ! ( "Salt: {}" , salt_bytes) ;
191+ println ! ( "Address: {}" , <H160 >:: try_from( addr_bytes) . unwrap( ) ) ;
192+ return Some ( salt_bytes) ;
193+ } else {
194+ counter = counter. wrapping_add ( 1 ) ;
195+ local_attempts += 1 ;
208196
209- if local_attempts % 200000 == 0 {
210- total_attempts. fetch_add ( 200000 , Ordering :: Relaxed ) ;
211- local_attempts = 0 ;
212- break ;
197+ continue ' inner;
213198 }
214199 }
200+
201+ total_attempts. fetch_add ( local_attempts, Ordering :: Relaxed ) ;
202+ local_attempts = 0 ;
215203 }
216204
217205 total_attempts. fetch_add ( local_attempts, Ordering :: Relaxed ) ;
0 commit comments