@@ -119,6 +119,64 @@ private unsafe bool Loop23()
119119 }
120120
121121
122+ private unsafe bool Loop27 ( )
123+ {
124+ // Same as above but key is 26 chars
125+ var cartesian = CartesianProduct . Create ( Enumerable . Repeat ( Encoding . UTF8 . GetBytes ( ConstantsFO . Base58Chars ) , missCount ) ) ;
126+ using Sha256 sha = new Sha256 ( ) ;
127+ bool success = false ;
128+
129+ byte [ ] temp = new byte [ precomputed . Length ] ;
130+ fixed ( uint * hPt = & sha . hashState [ 0 ] , wPt = & sha . w [ 0 ] )
131+ fixed ( byte * pre = & precomputed [ 0 ] , tmp = & temp [ 0 ] )
132+ fixed ( int * mi = & missingIndexes [ 0 ] )
133+ {
134+ foreach ( var item in cartesian )
135+ {
136+ Buffer . MemoryCopy ( pre , tmp , 26 , 26 ) ;
137+ int mis = 0 ;
138+ foreach ( var keyItem in item )
139+ {
140+ tmp [ mi [ mis ] ] = keyItem ;
141+ mis ++ ;
142+ }
143+
144+ wPt [ 0 ] = 0b01010011_00000000_00000000_00000000U | ( uint ) tmp [ 1 ] << 16 | ( uint ) tmp [ 2 ] << 8 | tmp [ 3 ] ;
145+ wPt [ 1 ] = ( uint ) tmp [ 4 ] << 24 | ( uint ) tmp [ 5 ] << 16 | ( uint ) tmp [ 6 ] << 8 | tmp [ 7 ] ;
146+ wPt [ 2 ] = ( uint ) tmp [ 8 ] << 24 | ( uint ) tmp [ 9 ] << 16 | ( uint ) tmp [ 10 ] << 8 | tmp [ 11 ] ;
147+ wPt [ 3 ] = ( uint ) tmp [ 12 ] << 24 | ( uint ) tmp [ 13 ] << 16 | ( uint ) tmp [ 14 ] << 8 | tmp [ 15 ] ;
148+ wPt [ 4 ] = ( uint ) tmp [ 16 ] << 24 | ( uint ) tmp [ 17 ] << 16 | ( uint ) tmp [ 18 ] << 8 | tmp [ 19 ] ;
149+ wPt [ 5 ] = ( uint ) tmp [ 20 ] << 24 | ( uint ) tmp [ 21 ] << 16 | ( uint ) tmp [ 22 ] << 8 | tmp [ 23 ] ;
150+ wPt [ 6 ] = ( uint ) tmp [ 24 ] << 24 | ( uint ) tmp [ 25 ] << 16 | 0b00000000_00000000_00111111_10000000U ;
151+ // from 7 to 14 = 0
152+ wPt [ 15 ] = 216 ; // 27 *8 = 216
153+
154+ sha . Init ( hPt ) ;
155+ sha . Compress27 ( hPt , wPt ) ;
156+
157+ if ( ( hPt [ 0 ] & 0b11111111_00000000_00000000_00000000U ) == 0 )
158+ {
159+ wPt [ 6 ] ^= 0b00000000_00000000_10111111_10000000U ;
160+ // from 7 to 14 (remain) = 0
161+ wPt [ 15 ] = 208 ; // 26 *8 = 208
162+
163+ sha . Init ( hPt ) ;
164+ sha . Compress26 ( hPt , wPt ) ;
165+
166+ if ( comparer . Compare ( sha . GetBytes ( hPt ) ) )
167+ {
168+ SetResult ( item ) ;
169+ success = true ;
170+ break ;
171+ }
172+ }
173+ }
174+ }
175+
176+ return success ;
177+ }
178+
179+
122180 private unsafe bool Loop31 ( )
123181 {
124182 var cartesian = CartesianProduct . Create ( Enumerable . Repeat ( Encoding . UTF8 . GetBytes ( ConstantsFO . Base58Chars ) , missCount ) ) ;
@@ -180,6 +238,22 @@ private unsafe bool Loop31()
180238 }
181239
182240
241+ private void PreCompute ( char missingChar )
242+ {
243+ int mis = 0 ;
244+ for ( int i = 0 ; i < keyToCheck . Length ; i ++ )
245+ {
246+ if ( keyToCheck [ i ] == missingChar )
247+ {
248+ missingIndexes [ mis ++ ] = i ;
249+ }
250+ else
251+ {
252+ precomputed [ i ] = ( byte ) keyToCheck [ i ] ;
253+ }
254+ }
255+ }
256+
183257 public async Task < bool > Find ( string key , string extra , char missingChar )
184258 {
185259 report . Init ( ) ;
@@ -215,50 +289,24 @@ public async Task<bool> Find(string key, string extra, char missingChar)
215289 if ( key . Length == ConstantsFO . MiniKeyLen1 )
216290 {
217291 precomputed = new byte [ ConstantsFO . MiniKeyLen1 ] ;
218- int mis = 0 ;
219- for ( int i = 0 ; i < key . Length ; i ++ )
220- {
221- if ( key [ i ] == missingChar )
222- {
223- missingIndexes [ mis ++ ] = i ;
224- }
225- else
226- {
227- precomputed [ i ] = ( byte ) key [ i ] ;
228- }
229- }
230-
231- success = await Task . Run ( ( ) =>
232- {
233- return Loop23 ( ) ;
234- }
235- ) ;
292+ PreCompute ( missingChar ) ;
293+ success = await Task . Run ( Loop23 ) ;
236294 }
237295 else if ( key . Length == ConstantsFO . MiniKeyLen2 )
238296 {
239297 precomputed = new byte [ ConstantsFO . MiniKeyLen2 ] ;
240- int mis = 0 ;
241- for ( int i = 0 ; i < key . Length ; i ++ )
242- {
243- if ( key [ i ] == missingChar )
244- {
245- missingIndexes [ mis ++ ] = i ;
246- }
247- else
248- {
249- precomputed [ i ] = ( byte ) key [ i ] ;
250- }
251- }
252-
253- success = await Task . Run ( ( ) =>
254- {
255- return Loop31 ( ) ;
256- }
257- ) ;
298+ PreCompute ( missingChar ) ;
299+ success = await Task . Run ( Loop27 ) ;
300+ }
301+ else if ( key . Length == ConstantsFO . MiniKeyLen3 )
302+ {
303+ precomputed = new byte [ ConstantsFO . MiniKeyLen3 ] ;
304+ PreCompute ( missingChar ) ;
305+ success = await Task . Run ( Loop31 ) ;
258306 }
259307 else
260308 {
261- return report . Fail ( $ "Minikey length must be { ConstantsFO . MiniKeyLen1 } or { ConstantsFO . MiniKeyLen2 } .") ;
309+ return report . Fail ( $ "Minikey length must be { ConstantsFO . MiniKeyLen1 } or { ConstantsFO . MiniKeyLen3 } .") ;
262310 }
263311
264312 watch . Stop ( ) ;
0 commit comments