Skip to content

Commit a890199

Browse files
Add new SHA methods to compress 26 and 27 bytes + tests
1 parent 884c50d commit a890199

File tree

2 files changed

+178
-0
lines changed

2 files changed

+178
-0
lines changed

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

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,132 @@ public unsafe void Compress24(uint* hPt, uint* wPt)
526526
CompressBlockWithWSet(hPt, wPt);
527527
}
528528

529+
/// <summary>
530+
/// Computes _single_ SHA256 hash for
531+
/// (data.Length == 26) and (wPt[0] to wPt[15] is set) and (Init() is called)
532+
/// </summary>
533+
/// <param name="hPt">HashState pointer</param>
534+
/// <param name="wPt">Working vector pointer</param>
535+
public unsafe void Compress26(uint* hPt, uint* wPt)
536+
{
537+
// w6 = extra value | 0b00000000_00000000_10000000_00000000U
538+
// w7 to w14 = 0
539+
// w15 = 208
540+
wPt[16] = SSIG0(wPt[1]) + wPt[0];
541+
wPt[17] = 7471104 + SSIG0(wPt[2]) + wPt[1];
542+
wPt[18] = SSIG1(wPt[16]) + SSIG0(wPt[3]) + wPt[2];
543+
wPt[19] = SSIG1(wPt[17]) + SSIG0(wPt[4]) + wPt[3];
544+
wPt[20] = SSIG1(wPt[18]) + SSIG0(wPt[5]) + wPt[4];
545+
wPt[21] = SSIG1(wPt[19]) + SSIG0(wPt[6]) + wPt[5];
546+
wPt[22] = SSIG1(wPt[20]) + 208 + wPt[6];
547+
wPt[23] = SSIG1(wPt[21]) + wPt[16];
548+
wPt[24] = SSIG1(wPt[22]) + wPt[17];
549+
wPt[25] = SSIG1(wPt[23]) + wPt[18];
550+
wPt[26] = SSIG1(wPt[24]) + wPt[19];
551+
wPt[27] = SSIG1(wPt[25]) + wPt[20];
552+
wPt[28] = SSIG1(wPt[26]) + wPt[21];
553+
wPt[29] = SSIG1(wPt[27]) + wPt[22];
554+
wPt[30] = SSIG1(wPt[28]) + wPt[23] + 2687762459;
555+
wPt[31] = SSIG1(wPt[29]) + wPt[24] + SSIG0(wPt[16]) + 208;
556+
wPt[32] = SSIG1(wPt[30]) + wPt[25] + SSIG0(wPt[17]) + wPt[16];
557+
wPt[33] = SSIG1(wPt[31]) + wPt[26] + SSIG0(wPt[18]) + wPt[17];
558+
wPt[34] = SSIG1(wPt[32]) + wPt[27] + SSIG0(wPt[19]) + wPt[18];
559+
wPt[35] = SSIG1(wPt[33]) + wPt[28] + SSIG0(wPt[20]) + wPt[19];
560+
wPt[36] = SSIG1(wPt[34]) + wPt[29] + SSIG0(wPt[21]) + wPt[20];
561+
wPt[37] = SSIG1(wPt[35]) + wPt[30] + SSIG0(wPt[22]) + wPt[21];
562+
wPt[38] = SSIG1(wPt[36]) + wPt[31] + SSIG0(wPt[23]) + wPt[22];
563+
wPt[39] = SSIG1(wPt[37]) + wPt[32] + SSIG0(wPt[24]) + wPt[23];
564+
wPt[40] = SSIG1(wPt[38]) + wPt[33] + SSIG0(wPt[25]) + wPt[24];
565+
wPt[41] = SSIG1(wPt[39]) + wPt[34] + SSIG0(wPt[26]) + wPt[25];
566+
wPt[42] = SSIG1(wPt[40]) + wPt[35] + SSIG0(wPt[27]) + wPt[26];
567+
wPt[43] = SSIG1(wPt[41]) + wPt[36] + SSIG0(wPt[28]) + wPt[27];
568+
wPt[44] = SSIG1(wPt[42]) + wPt[37] + SSIG0(wPt[29]) + wPt[28];
569+
wPt[45] = SSIG1(wPt[43]) + wPt[38] + SSIG0(wPt[30]) + wPt[29];
570+
wPt[46] = SSIG1(wPt[44]) + wPt[39] + SSIG0(wPt[31]) + wPt[30];
571+
wPt[47] = SSIG1(wPt[45]) + wPt[40] + SSIG0(wPt[32]) + wPt[31];
572+
wPt[48] = SSIG1(wPt[46]) + wPt[41] + SSIG0(wPt[33]) + wPt[32];
573+
wPt[49] = SSIG1(wPt[47]) + wPt[42] + SSIG0(wPt[34]) + wPt[33];
574+
wPt[50] = SSIG1(wPt[48]) + wPt[43] + SSIG0(wPt[35]) + wPt[34];
575+
wPt[51] = SSIG1(wPt[49]) + wPt[44] + SSIG0(wPt[36]) + wPt[35];
576+
wPt[52] = SSIG1(wPt[50]) + wPt[45] + SSIG0(wPt[37]) + wPt[36];
577+
wPt[53] = SSIG1(wPt[51]) + wPt[46] + SSIG0(wPt[38]) + wPt[37];
578+
wPt[54] = SSIG1(wPt[52]) + wPt[47] + SSIG0(wPt[39]) + wPt[38];
579+
wPt[55] = SSIG1(wPt[53]) + wPt[48] + SSIG0(wPt[40]) + wPt[39];
580+
wPt[56] = SSIG1(wPt[54]) + wPt[49] + SSIG0(wPt[41]) + wPt[40];
581+
wPt[57] = SSIG1(wPt[55]) + wPt[50] + SSIG0(wPt[42]) + wPt[41];
582+
wPt[58] = SSIG1(wPt[56]) + wPt[51] + SSIG0(wPt[43]) + wPt[42];
583+
wPt[59] = SSIG1(wPt[57]) + wPt[52] + SSIG0(wPt[44]) + wPt[43];
584+
wPt[60] = SSIG1(wPt[58]) + wPt[53] + SSIG0(wPt[45]) + wPt[44];
585+
wPt[61] = SSIG1(wPt[59]) + wPt[54] + SSIG0(wPt[46]) + wPt[45];
586+
wPt[62] = SSIG1(wPt[60]) + wPt[55] + SSIG0(wPt[47]) + wPt[46];
587+
wPt[63] = SSIG1(wPt[61]) + wPt[56] + SSIG0(wPt[48]) + wPt[47];
588+
589+
CompressBlockWithWSet(hPt, wPt);
590+
}
591+
592+
/// <summary>
593+
/// Computes _single_ SHA256 hash for
594+
/// (data.Length == 27) 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 Compress27(uint* hPt, uint* wPt)
599+
{
600+
// w6 = extra value | 0b00000000_00000000_00000000_10000000U
601+
// w7 to w14 = 0
602+
// w15 = 216
603+
wPt[16] = SSIG0(wPt[1]) + wPt[0];
604+
wPt[17] = 7798784 + 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]) + 216 + wPt[6];
610+
wPt[23] = SSIG1(wPt[21]) + wPt[16];
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] + 2956328986;
618+
wPt[31] = SSIG1(wPt[29]) + wPt[24] + SSIG0(wPt[16]) + 216;
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 == 28) and (wPt[0] to wPt[15] is set) and (Init() is called)

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

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,58 @@ public unsafe void Compress24Test()
374374
}
375375
}
376376

377+
[Fact]
378+
public unsafe void Compress26Test()
379+
{
380+
int dataLen = 26;
381+
byte[] data = GetRandomBytes(dataLen);
382+
byte[] expected = ComputeSingleSha(data);
383+
384+
using Sha256 sha = new Sha256();
385+
fixed (uint* hPt = &sha.hashState[0], wPt = &sha.w[0])
386+
{
387+
int dIndex = 0;
388+
for (int i = 0; i < 6; i++, dIndex += 4)
389+
{
390+
wPt[i] = (uint)((data[dIndex] << 24) | (data[dIndex + 1] << 16) | (data[dIndex + 2] << 8) | data[dIndex + 3]);
391+
}
392+
wPt[6] = (uint)data[24] << 24 | (uint)data[25] << 16 | 0b00000000_00000000_10000000_00000000U;
393+
394+
wPt[15] = (uint)dataLen * 8;
395+
sha.Init(hPt);
396+
sha.Compress26(hPt, wPt);
397+
byte[] actual = sha.GetBytes(hPt);
398+
399+
Assert.Equal(expected, actual);
400+
}
401+
}
402+
403+
[Fact]
404+
public unsafe void Compress27Test()
405+
{
406+
int dataLen = 27;
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 < 6; 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[6] = (uint)data[24] << 24 | (uint)data[25] << 16 | (uint)data[26] << 8 | 0b00000000_00000000_00000000_10000000U;
419+
420+
wPt[15] = (uint)dataLen * 8;
421+
sha.Init(hPt);
422+
sha.Compress27(hPt, wPt);
423+
byte[] actual = sha.GetBytes(hPt);
424+
425+
Assert.Equal(expected, actual);
426+
}
427+
}
428+
377429
[Fact]
378430
public unsafe void Compress28Test()
379431
{

0 commit comments

Comments
 (0)