Skip to content

Commit a496b94

Browse files
Add the case for 26 char long mini-privatekeys
1 parent a890199 commit a496b94

File tree

2 files changed

+87
-38
lines changed

2 files changed

+87
-38
lines changed

Src/FinderOuter/Backend/ConstantsFO.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ public struct ConstantsFO
3131

3232
public const char MiniKeyStart = 'S';
3333
public const int MiniKeyLen1 = 22;
34-
public const int MiniKeyLen2 = 30;
34+
public const int MiniKeyLen2 = 26;
35+
public const int MiniKeyLen3 = 30;
3536

3637
public const int Bip38ByteLen = 39;
3738
public const int Bip38Base58Len = 58;

Src/FinderOuter/Services/MiniKeyService.cs

Lines changed: 85 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)