1313using System . Linq ;
1414using System . Numerics ;
1515using System . Reflection ;
16+ using System . Text ;
1617using System . Threading . Tasks ;
1718
1819namespace FinderOuter . Services
@@ -50,6 +51,7 @@ public MnemonicSevice(Report rep) : base(rep)
5051
5152 private int missCount ;
5253 private string [ ] words ;
54+ private string passPhrase ;
5355
5456
5557 readonly List < IEnumerable < int > > Final = new List < IEnumerable < int > > ( ) ;
@@ -59,6 +61,60 @@ private void SetResult(IEnumerable<int> item)
5961 }
6062
6163
64+ private unsafe void SetBip32 ( byte [ ] mnemonic )
65+ {
66+ HmacSha512 hmac = new HmacSha512 ( mnemonic ) ;
67+
68+ byte [ ] salt = Encoding . UTF8 . GetBytes ( $ "mnemonic{ passPhrase ? . Normalize ( NormalizationForm . FormKD ) } ") ;
69+ byte [ ] saltForHmac = new byte [ salt . Length + 4 ] ;
70+ Buffer . BlockCopy ( salt , 0 , saltForHmac , 0 , salt . Length ) ;
71+
72+ byte [ ] seed = new byte [ 64 ] ;
73+
74+ fixed ( byte * saltPt = & saltForHmac [ salt . Length ] )
75+ {
76+ // F()
77+ byte [ ] resultOfF = new byte [ hmac . OutputSize ] ;
78+
79+ // Concatinate i after salt
80+ //saltPt[0] = (byte)(1 >> 24);
81+ //saltPt[1] = (byte)(1 >> 16);
82+ //saltPt[2] = (byte)(1 >> 8);
83+ saltPt [ 3 ] = 1 ;
84+
85+ // compute u1
86+ byte [ ] u1 = hmac . ComputeHash ( saltForHmac ) ;
87+
88+ Buffer . BlockCopy ( u1 , 0 , resultOfF , 0 , u1 . Length ) ;
89+
90+ // compute u2 to u(c-1) where c is iteration and each u is the hmac of previous u
91+ for ( int j = 1 ; j < 2048 ; j ++ )
92+ {
93+ u1 = hmac . ComputeHash ( u1 ) ;
94+
95+ // result of F() is XOR sum of all u arrays
96+ int len = u1 . Length ;
97+ fixed ( byte * first = resultOfF , second = u1 )
98+ {
99+ byte * fp = first ;
100+ byte * sp = second ;
101+
102+ * ( ulong * ) fp ^= * ( ulong * ) sp ;
103+ * ( ulong * ) ( fp + 8 ) ^ = * ( ulong * ) ( sp + 8 ) ;
104+ * ( ulong * ) ( fp + 16 ) ^ = * ( ulong * ) ( sp + 16 ) ;
105+ * ( ulong * ) ( fp + 24 ) ^ = * ( ulong * ) ( sp + 24 ) ;
106+ * ( ulong * ) ( fp + 32 ) ^ = * ( ulong * ) ( sp + 32 ) ;
107+ * ( ulong * ) ( fp + 40 ) ^ = * ( ulong * ) ( sp + 40 ) ;
108+ * ( ulong * ) ( fp + 48 ) ^ = * ( ulong * ) ( sp + 48 ) ;
109+ * ( ulong * ) ( fp + 56 ) ^ = * ( ulong * ) ( sp + 56 ) ;
110+ }
111+ }
112+
113+ Buffer . BlockCopy ( resultOfF , 0 , seed , 0 , resultOfF . Length ) ;
114+ }
115+ }
116+
117+
62118 private unsafe bool Loop24 ( )
63119 {
64120 var cartesian = CartesianProduct. Create( Enumerable . Repeat ( Enumerable . Range ( 0 , 2048 ) , missCount ) ) ;
@@ -136,7 +192,16 @@ private unsafe bool Loop24()
136192
137193 if ( ( byte ) wrd [ 23 ] == hPt [ 0 ] >> 24 )
138194 {
139- SetResult ( item ) ;
195+ StringBuilder sb = new StringBuilder( 24 ) ;
196+ for ( int i = 0 ; i < 23 ; i++ )
197+ {
198+ sb. Append( $"{ allWords[ wrd[ i] ] } ") ;
199+ }
200+
201+ // no space at the end.
202+ sb. Append( $"{ allWords[ wrd[ 23 ] ] } ") ;
203+
204+ SetBip32( Encoding. UTF8. GetBytes( sb. ToString( ) ) ) ;
140205 }
141206 }
142207 }
@@ -175,7 +240,16 @@ private unsafe bool Loop21()
175240
176241 if ( ( wrd[ 20 ] & 0b111_1111 ) == hPt[ 0 ] >> 25 )
177242 {
178- SetResult ( item ) ;
243+ StringBuilder sb = new StringBuilder( 21 ) ;
244+ for ( int i = 0 ; i < 20 ; i++ )
245+ {
246+ sb. Append( $"{ allWords[ wrd[ i] ] } ") ;
247+ }
248+
249+ // no space at the end.
250+ sb. Append( $"{ allWords[ wrd[ 20 ] ] } ") ;
251+
252+ SetBip32( Encoding. UTF8. GetBytes( sb. ToString( ) ) ) ;
179253 }
180254 }
181255 }
@@ -213,7 +287,16 @@ private unsafe bool Loop18()
213287
214288 if ( ( wrd[ 17 ] & 0b11_1111 ) == hPt[ 0 ] >> 26 )
215289 {
216- SetResult ( item ) ;
290+ StringBuilder sb = new StringBuilder( 18 ) ;
291+ for ( int i = 0 ; i < 17 ; i++ )
292+ {
293+ sb. Append( $"{ allWords[ wrd[ i] ] } ") ;
294+ }
295+
296+ // no space at the end.
297+ sb. Append( $"{ allWords[ wrd[ 17 ] ] } ") ;
298+
299+ SetBip32( Encoding. UTF8. GetBytes( sb. ToString( ) ) ) ;
217300 }
218301 }
219302 }
@@ -250,7 +333,16 @@ private unsafe bool Loop15()
250333
251334 if ( ( wrd[ 14 ] & 0b1_1111 ) == hPt[ 0 ] >> 27 )
252335 {
253- SetResult ( item ) ;
336+ StringBuilder sb = new StringBuilder( 15 ) ;
337+ for ( int i = 0 ; i < 14 ; i++ )
338+ {
339+ sb. Append( $"{ allWords[ wrd[ i] ] } ") ;
340+ }
341+
342+ // no space at the end.
343+ sb. Append( $"{ allWords[ wrd[ 14 ] ] } ") ;
344+
345+ SetBip32( Encoding. UTF8. GetBytes( sb. ToString( ) ) ) ;
254346 }
255347 }
256348 }
@@ -286,7 +378,16 @@ private unsafe bool Loop12()
286378
287379 if ( ( wrd[ 11 ] & 0b1111 ) == hPt[ 0 ] >> 28 )
288380 {
289- SetResult ( item ) ;
381+ StringBuilder sb = new StringBuilder( 12 ) ;
382+ for ( int i = 0 ; i < 11 ; i++ )
383+ {
384+ sb. Append( $"{ allWords[ wrd[ i] ] } ") ;
385+ }
386+
387+ // no space at the end.
388+ sb. Append( $"{ allWords[ wrd[ 11 ] ] } ") ;
389+
390+ SetBip32( Encoding. UTF8. GetBytes( sb. ToString( ) ) ) ;
290391 }
291392 }
292393 }
0 commit comments