Skip to content

Commit 9c7ae20

Browse files
Add SHA256 compress methods for 30 and 22 bytes + tests
1 parent 2e5629c commit 9c7ae20

File tree

2 files changed

+190
-12
lines changed

2 files changed

+190
-12
lines changed

Src/FinderOuter/Backend/Cryptography/Hashing/Sha256.cs

Lines changed: 138 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,69 @@ public unsafe void Compress20(uint* hPt, uint* wPt)
337337
CompressBlockWithWSet(hPt, wPt);
338338
}
339339

340+
/// <summary>
341+
/// Computes _single_ SHA256 hash for
342+
/// (data.Length == 22) and (wPt[0] to wPt[15] is set) and (Init() is called)
343+
/// </summary>
344+
/// <param name="hPt">HashState pointer</param>
345+
/// <param name="wPt">Working vector pointer</param>
346+
public unsafe void Compress22(uint* hPt, uint* wPt)
347+
{
348+
// w5 = extra values | 0b00000000_00000000_10000000_00000000U
349+
// w6 to w14 = 0
350+
// w15 = 176
351+
wPt[16] = SSIG0(wPt[1]) + wPt[0];
352+
wPt[17] = 5111808 + SSIG0(wPt[2]) + wPt[1];
353+
wPt[18] = SSIG1(wPt[16]) + SSIG0(wPt[3]) + wPt[2];
354+
wPt[19] = SSIG1(wPt[17]) + SSIG0(wPt[4]) + wPt[3];
355+
wPt[20] = SSIG1(wPt[18]) + SSIG0(wPt[5]) + wPt[4];
356+
wPt[21] = SSIG1(wPt[19]) + wPt[5];
357+
wPt[22] = SSIG1(wPt[20]) + 176;
358+
wPt[23] = SSIG1(wPt[21]) + wPt[16];
359+
wPt[24] = SSIG1(wPt[22]) + wPt[17];
360+
wPt[25] = SSIG1(wPt[23]) + wPt[18];
361+
wPt[26] = SSIG1(wPt[24]) + wPt[19];
362+
wPt[27] = SSIG1(wPt[25]) + wPt[20];
363+
wPt[28] = SSIG1(wPt[26]) + wPt[21];
364+
wPt[29] = SSIG1(wPt[27]) + wPt[22];
365+
wPt[30] = SSIG1(wPt[28]) + wPt[23] + 1613496343;
366+
wPt[31] = SSIG1(wPt[29]) + wPt[24] + SSIG0(wPt[16]) + 176;
367+
wPt[32] = SSIG1(wPt[30]) + wPt[25] + SSIG0(wPt[17]) + wPt[16];
368+
wPt[33] = SSIG1(wPt[31]) + wPt[26] + SSIG0(wPt[18]) + wPt[17];
369+
wPt[34] = SSIG1(wPt[32]) + wPt[27] + SSIG0(wPt[19]) + wPt[18];
370+
wPt[35] = SSIG1(wPt[33]) + wPt[28] + SSIG0(wPt[20]) + wPt[19];
371+
wPt[36] = SSIG1(wPt[34]) + wPt[29] + SSIG0(wPt[21]) + wPt[20];
372+
wPt[37] = SSIG1(wPt[35]) + wPt[30] + SSIG0(wPt[22]) + wPt[21];
373+
wPt[38] = SSIG1(wPt[36]) + wPt[31] + SSIG0(wPt[23]) + wPt[22];
374+
wPt[39] = SSIG1(wPt[37]) + wPt[32] + SSIG0(wPt[24]) + wPt[23];
375+
wPt[40] = SSIG1(wPt[38]) + wPt[33] + SSIG0(wPt[25]) + wPt[24];
376+
wPt[41] = SSIG1(wPt[39]) + wPt[34] + SSIG0(wPt[26]) + wPt[25];
377+
wPt[42] = SSIG1(wPt[40]) + wPt[35] + SSIG0(wPt[27]) + wPt[26];
378+
wPt[43] = SSIG1(wPt[41]) + wPt[36] + SSIG0(wPt[28]) + wPt[27];
379+
wPt[44] = SSIG1(wPt[42]) + wPt[37] + SSIG0(wPt[29]) + wPt[28];
380+
wPt[45] = SSIG1(wPt[43]) + wPt[38] + SSIG0(wPt[30]) + wPt[29];
381+
wPt[46] = SSIG1(wPt[44]) + wPt[39] + SSIG0(wPt[31]) + wPt[30];
382+
wPt[47] = SSIG1(wPt[45]) + wPt[40] + SSIG0(wPt[32]) + wPt[31];
383+
wPt[48] = SSIG1(wPt[46]) + wPt[41] + SSIG0(wPt[33]) + wPt[32];
384+
wPt[49] = SSIG1(wPt[47]) + wPt[42] + SSIG0(wPt[34]) + wPt[33];
385+
wPt[50] = SSIG1(wPt[48]) + wPt[43] + SSIG0(wPt[35]) + wPt[34];
386+
wPt[51] = SSIG1(wPt[49]) + wPt[44] + SSIG0(wPt[36]) + wPt[35];
387+
wPt[52] = SSIG1(wPt[50]) + wPt[45] + SSIG0(wPt[37]) + wPt[36];
388+
wPt[53] = SSIG1(wPt[51]) + wPt[46] + SSIG0(wPt[38]) + wPt[37];
389+
wPt[54] = SSIG1(wPt[52]) + wPt[47] + SSIG0(wPt[39]) + wPt[38];
390+
wPt[55] = SSIG1(wPt[53]) + wPt[48] + SSIG0(wPt[40]) + wPt[39];
391+
wPt[56] = SSIG1(wPt[54]) + wPt[49] + SSIG0(wPt[41]) + wPt[40];
392+
wPt[57] = SSIG1(wPt[55]) + wPt[50] + SSIG0(wPt[42]) + wPt[41];
393+
wPt[58] = SSIG1(wPt[56]) + wPt[51] + SSIG0(wPt[43]) + wPt[42];
394+
wPt[59] = SSIG1(wPt[57]) + wPt[52] + SSIG0(wPt[44]) + wPt[43];
395+
wPt[60] = SSIG1(wPt[58]) + wPt[53] + SSIG0(wPt[45]) + wPt[44];
396+
wPt[61] = SSIG1(wPt[59]) + wPt[54] + SSIG0(wPt[46]) + wPt[45];
397+
wPt[62] = SSIG1(wPt[60]) + wPt[55] + SSIG0(wPt[47]) + wPt[46];
398+
wPt[63] = SSIG1(wPt[61]) + wPt[56] + SSIG0(wPt[48]) + wPt[47];
399+
400+
CompressBlockWithWSet(hPt, wPt);
401+
}
402+
340403
/// <summary>
341404
/// Computes _single_ SHA256 hash for
342405
/// (data.Length == 23) and (wPt[0] to wPt[15] is set) and (Init() is called)
@@ -526,6 +589,69 @@ public unsafe void Compress28(uint* hPt, uint* wPt)
526589
CompressBlockWithWSet(hPt, wPt);
527590
}
528591

592+
/// <summary>
593+
/// Computes _single_ SHA256 hash for
594+
/// (data.Length == 31) and (wPt[0] to wPt[15] is set) and (Init() is called)
595+
/// </summary>
596+
/// <param name="hPt">HashState pointer</param>
597+
/// <param name="wPt">Working vector pointer</param>
598+
public unsafe void Compress30(uint* hPt, uint* wPt)
599+
{
600+
// w7 = extra value | 0b00000000_00000000_10000000_00000000U
601+
// w8 to w14 = 0
602+
// w15 = 240
603+
wPt[16] = SSIG0(wPt[1]) + wPt[0];
604+
wPt[17] = 6684672 + 0 + SSIG0(wPt[2]) + wPt[1];
605+
wPt[18] = SSIG1(wPt[16]) + SSIG0(wPt[3]) + wPt[2];
606+
wPt[19] = SSIG1(wPt[17]) + SSIG0(wPt[4]) + wPt[3];
607+
wPt[20] = SSIG1(wPt[18]) + SSIG0(wPt[5]) + wPt[4];
608+
wPt[21] = SSIG1(wPt[19]) + SSIG0(wPt[6]) + wPt[5];
609+
wPt[22] = SSIG1(wPt[20]) + 240 + SSIG0(wPt[7]) + wPt[6];
610+
wPt[23] = SSIG1(wPt[21]) + wPt[16] + wPt[7];
611+
wPt[24] = SSIG1(wPt[22]) + wPt[17];
612+
wPt[25] = SSIG1(wPt[23]) + wPt[18];
613+
wPt[26] = SSIG1(wPt[24]) + wPt[19];
614+
wPt[27] = SSIG1(wPt[25]) + wPt[20];
615+
wPt[28] = SSIG1(wPt[26]) + wPt[21];
616+
wPt[29] = SSIG1(wPt[27]) + wPt[22];
617+
wPt[30] = SSIG1(wPt[28]) + wPt[23] + 3762028575;
618+
wPt[31] = SSIG1(wPt[29]) + wPt[24] + SSIG0(wPt[16]) + 240;
619+
wPt[32] = SSIG1(wPt[30]) + wPt[25] + SSIG0(wPt[17]) + wPt[16];
620+
wPt[33] = SSIG1(wPt[31]) + wPt[26] + SSIG0(wPt[18]) + wPt[17];
621+
wPt[34] = SSIG1(wPt[32]) + wPt[27] + SSIG0(wPt[19]) + wPt[18];
622+
wPt[35] = SSIG1(wPt[33]) + wPt[28] + SSIG0(wPt[20]) + wPt[19];
623+
wPt[36] = SSIG1(wPt[34]) + wPt[29] + SSIG0(wPt[21]) + wPt[20];
624+
wPt[37] = SSIG1(wPt[35]) + wPt[30] + SSIG0(wPt[22]) + wPt[21];
625+
wPt[38] = SSIG1(wPt[36]) + wPt[31] + SSIG0(wPt[23]) + wPt[22];
626+
wPt[39] = SSIG1(wPt[37]) + wPt[32] + SSIG0(wPt[24]) + wPt[23];
627+
wPt[40] = SSIG1(wPt[38]) + wPt[33] + SSIG0(wPt[25]) + wPt[24];
628+
wPt[41] = SSIG1(wPt[39]) + wPt[34] + SSIG0(wPt[26]) + wPt[25];
629+
wPt[42] = SSIG1(wPt[40]) + wPt[35] + SSIG0(wPt[27]) + wPt[26];
630+
wPt[43] = SSIG1(wPt[41]) + wPt[36] + SSIG0(wPt[28]) + wPt[27];
631+
wPt[44] = SSIG1(wPt[42]) + wPt[37] + SSIG0(wPt[29]) + wPt[28];
632+
wPt[45] = SSIG1(wPt[43]) + wPt[38] + SSIG0(wPt[30]) + wPt[29];
633+
wPt[46] = SSIG1(wPt[44]) + wPt[39] + SSIG0(wPt[31]) + wPt[30];
634+
wPt[47] = SSIG1(wPt[45]) + wPt[40] + SSIG0(wPt[32]) + wPt[31];
635+
wPt[48] = SSIG1(wPt[46]) + wPt[41] + SSIG0(wPt[33]) + wPt[32];
636+
wPt[49] = SSIG1(wPt[47]) + wPt[42] + SSIG0(wPt[34]) + wPt[33];
637+
wPt[50] = SSIG1(wPt[48]) + wPt[43] + SSIG0(wPt[35]) + wPt[34];
638+
wPt[51] = SSIG1(wPt[49]) + wPt[44] + SSIG0(wPt[36]) + wPt[35];
639+
wPt[52] = SSIG1(wPt[50]) + wPt[45] + SSIG0(wPt[37]) + wPt[36];
640+
wPt[53] = SSIG1(wPt[51]) + wPt[46] + SSIG0(wPt[38]) + wPt[37];
641+
wPt[54] = SSIG1(wPt[52]) + wPt[47] + SSIG0(wPt[39]) + wPt[38];
642+
wPt[55] = SSIG1(wPt[53]) + wPt[48] + SSIG0(wPt[40]) + wPt[39];
643+
wPt[56] = SSIG1(wPt[54]) + wPt[49] + SSIG0(wPt[41]) + wPt[40];
644+
wPt[57] = SSIG1(wPt[55]) + wPt[50] + SSIG0(wPt[42]) + wPt[41];
645+
wPt[58] = SSIG1(wPt[56]) + wPt[51] + SSIG0(wPt[43]) + wPt[42];
646+
wPt[59] = SSIG1(wPt[57]) + wPt[52] + SSIG0(wPt[44]) + wPt[43];
647+
wPt[60] = SSIG1(wPt[58]) + wPt[53] + SSIG0(wPt[45]) + wPt[44];
648+
wPt[61] = SSIG1(wPt[59]) + wPt[54] + SSIG0(wPt[46]) + wPt[45];
649+
wPt[62] = SSIG1(wPt[60]) + wPt[55] + SSIG0(wPt[47]) + wPt[46];
650+
wPt[63] = SSIG1(wPt[61]) + wPt[56] + SSIG0(wPt[48]) + wPt[47];
651+
652+
CompressBlockWithWSet(hPt, wPt);
653+
}
654+
529655
/// <summary>
530656
/// Computes _single_ SHA256 hash for
531657
/// (data.Length == 31) and (wPt[0] to wPt[15] is set) and (Init() is called)
@@ -539,19 +665,19 @@ public unsafe void Compress31(uint* hPt, uint* wPt)
539665
// w15 = 248
540666
wPt[16] = 0 + 0 + SSIG0(wPt[1]) + wPt[0];
541667
wPt[17] = 6488064 + 0 + SSIG0(wPt[2]) + wPt[1];
542-
wPt[18] = SSIG1(wPt[16]) + 0 + SSIG0(wPt[3]) + wPt[2];
543-
wPt[19] = SSIG1(wPt[17]) + 0 + SSIG0(wPt[4]) + wPt[3];
544-
wPt[20] = SSIG1(wPt[18]) + 0 + SSIG0(wPt[5]) + wPt[4];
545-
wPt[21] = SSIG1(wPt[19]) + 0 + SSIG0(wPt[6]) + wPt[5];
668+
wPt[18] = SSIG1(wPt[16]) + SSIG0(wPt[3]) + wPt[2];
669+
wPt[19] = SSIG1(wPt[17]) + SSIG0(wPt[4]) + wPt[3];
670+
wPt[20] = SSIG1(wPt[18]) + SSIG0(wPt[5]) + wPt[4];
671+
wPt[21] = SSIG1(wPt[19]) + SSIG0(wPt[6]) + wPt[5];
546672
wPt[22] = SSIG1(wPt[20]) + 248 + SSIG0(wPt[7]) + wPt[6];
547-
wPt[23] = SSIG1(wPt[21]) + wPt[16] + 0 + wPt[7];
548-
wPt[24] = SSIG1(wPt[22]) + wPt[17] + 0 + 0;
549-
wPt[25] = SSIG1(wPt[23]) + wPt[18] + 0 + 0;
550-
wPt[26] = SSIG1(wPt[24]) + wPt[19] + 0 + 0;
551-
wPt[27] = SSIG1(wPt[25]) + wPt[20] + 0 + 0;
552-
wPt[28] = SSIG1(wPt[26]) + wPt[21] + 0 + 0;
553-
wPt[29] = SSIG1(wPt[27]) + wPt[22] + 0 + 0;
554-
wPt[30] = SSIG1(wPt[28]) + wPt[23] + 4030595102 + 0;
673+
wPt[23] = SSIG1(wPt[21]) + wPt[16] + wPt[7];
674+
wPt[24] = SSIG1(wPt[22]) + wPt[17];
675+
wPt[25] = SSIG1(wPt[23]) + wPt[18];
676+
wPt[26] = SSIG1(wPt[24]) + wPt[19];
677+
wPt[27] = SSIG1(wPt[25]) + wPt[20];
678+
wPt[28] = SSIG1(wPt[26]) + wPt[21];
679+
wPt[29] = SSIG1(wPt[27]) + wPt[22];
680+
wPt[30] = SSIG1(wPt[28]) + wPt[23] + 4030595102;
555681
wPt[31] = SSIG1(wPt[29]) + wPt[24] + SSIG0(wPt[16]) + 248;
556682
wPt[32] = SSIG1(wPt[30]) + wPt[25] + SSIG0(wPt[17]) + wPt[16];
557683
wPt[33] = SSIG1(wPt[31]) + wPt[26] + SSIG0(wPt[18]) + wPt[17];

Src/Tests/Backend/Cryptography/Hashing/Sha256Tests.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,32 @@ public unsafe void Compress20Test()
296296
}
297297
}
298298

299+
[Fact]
300+
public unsafe void Compress22Test()
301+
{
302+
int dataLen = 22;
303+
byte[] data = GetRandomBytes(dataLen);
304+
byte[] expected = ComputeSingleSha(data);
305+
306+
using Sha256 sha = new Sha256();
307+
fixed (uint* hPt = &sha.hashState[0], wPt = &sha.w[0])
308+
{
309+
int dIndex = 0;
310+
for (int i = 0; i < 5; i++, dIndex += 4)
311+
{
312+
wPt[i] = (uint)((data[dIndex] << 24) | (data[dIndex + 1] << 16) | (data[dIndex + 2] << 8) | data[dIndex + 3]);
313+
}
314+
wPt[5] = (uint)((data[20] << 24) | (data[21] << 16) | 0b00000000_00000000_10000000_00000000U);
315+
316+
wPt[15] = (uint)dataLen * 8;
317+
sha.Init(hPt);
318+
sha.Compress22(hPt, wPt);
319+
byte[] actual = sha.GetBytes(hPt);
320+
321+
Assert.Equal(expected, actual);
322+
}
323+
}
324+
299325
[Fact]
300326
public unsafe void Compress23Test()
301327
{
@@ -374,6 +400,32 @@ public unsafe void Compress28Test()
374400
}
375401
}
376402

403+
[Fact]
404+
public unsafe void Compress30Test()
405+
{
406+
int dataLen = 30;
407+
byte[] data = GetRandomBytes(dataLen);
408+
byte[] expected = ComputeSingleSha(data);
409+
410+
using Sha256 sha = new Sha256();
411+
fixed (uint* hPt = &sha.hashState[0], wPt = &sha.w[0])
412+
{
413+
int dIndex = 0;
414+
for (int i = 0; i < 7; i++, dIndex += 4)
415+
{
416+
wPt[i] = (uint)((data[dIndex] << 24) | (data[dIndex + 1] << 16) | (data[dIndex + 2] << 8) | data[dIndex + 3]);
417+
}
418+
wPt[7] = (uint)((data[28] << 24) | (data[29] << 16) | 0b00000000_00000000_10000000_00000000U);
419+
420+
wPt[15] = (uint)dataLen * 8;
421+
sha.Init(hPt);
422+
sha.Compress30(hPt, wPt);
423+
byte[] actual = sha.GetBytes(hPt);
424+
425+
Assert.Equal(expected, actual);
426+
}
427+
}
428+
377429
[Fact]
378430
public unsafe void Compress31Test()
379431
{

0 commit comments

Comments
 (0)