Skip to content

Commit e070417

Browse files
Add a new SHA512 method to compress 64 byte blocks
1 parent 860daa1 commit e070417

File tree

2 files changed

+119
-2
lines changed

2 files changed

+119
-2
lines changed

Src/FinderOuter/Backend/Hashing/Sha512Fo.cs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,85 @@ public static unsafe void CompressSingleBlock(byte* dPt, ulong* hPt, ulong* wPt)
333333
CompressBlockWithWSet(hPt, wPt);
334334
}
335335

336+
/// <summary>
337+
/// Computes _single_ SHA512 hash for
338+
/// (data.Length == 64) and (wPt[0] to wPt[15] is set) and (Init() is called)
339+
/// </summary>
340+
/// <param name="hPt"></param>
341+
/// <param name="wPt"></param>
342+
public static unsafe void Compress64(ulong* hPt, ulong* wPt)
343+
{
344+
// w8 = 0b10000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000UL
345+
// w9 to w14 = 0
346+
// w15 = 512
347+
wPt[16] = SSIG0(wPt[1]) + wPt[0];
348+
wPt[17] = 18014398509486088 + SSIG0(wPt[2]) + wPt[1];
349+
wPt[18] = SSIG1(wPt[16]) + SSIG0(wPt[3]) + wPt[2];
350+
wPt[19] = SSIG1(wPt[17]) + SSIG0(wPt[4]) + wPt[3];
351+
wPt[20] = SSIG1(wPt[18]) + SSIG0(wPt[5]) + wPt[4];
352+
wPt[21] = SSIG1(wPt[19]) + SSIG0(wPt[6]) + wPt[5];
353+
wPt[22] = SSIG1(wPt[20]) + 512 + SSIG0(wPt[7]) + wPt[6];
354+
wPt[23] = SSIG1(wPt[21]) + wPt[16] + 4719772409484279808 + wPt[7];
355+
wPt[24] = SSIG1(wPt[22]) + wPt[17] + 9223372036854775808;
356+
wPt[25] = SSIG1(wPt[23]) + wPt[18];
357+
wPt[26] = SSIG1(wPt[24]) + wPt[19];
358+
wPt[27] = SSIG1(wPt[25]) + wPt[20];
359+
wPt[28] = SSIG1(wPt[26]) + wPt[21];
360+
wPt[29] = SSIG1(wPt[27]) + wPt[22];
361+
wPt[30] = SSIG1(wPt[28]) + wPt[23] + 262;
362+
wPt[31] = SSIG1(wPt[29]) + wPt[24] + SSIG0(wPt[16]) + 512;
363+
wPt[32] = SSIG1(wPt[30]) + wPt[25] + SSIG0(wPt[17]) + wPt[16];
364+
wPt[33] = SSIG1(wPt[31]) + wPt[26] + SSIG0(wPt[18]) + wPt[17];
365+
wPt[34] = SSIG1(wPt[32]) + wPt[27] + SSIG0(wPt[19]) + wPt[18];
366+
wPt[35] = SSIG1(wPt[33]) + wPt[28] + SSIG0(wPt[20]) + wPt[19];
367+
wPt[36] = SSIG1(wPt[34]) + wPt[29] + SSIG0(wPt[21]) + wPt[20];
368+
wPt[37] = SSIG1(wPt[35]) + wPt[30] + SSIG0(wPt[22]) + wPt[21];
369+
wPt[38] = SSIG1(wPt[36]) + wPt[31] + SSIG0(wPt[23]) + wPt[22];
370+
wPt[39] = SSIG1(wPt[37]) + wPt[32] + SSIG0(wPt[24]) + wPt[23];
371+
wPt[40] = SSIG1(wPt[38]) + wPt[33] + SSIG0(wPt[25]) + wPt[24];
372+
wPt[41] = SSIG1(wPt[39]) + wPt[34] + SSIG0(wPt[26]) + wPt[25];
373+
wPt[42] = SSIG1(wPt[40]) + wPt[35] + SSIG0(wPt[27]) + wPt[26];
374+
wPt[43] = SSIG1(wPt[41]) + wPt[36] + SSIG0(wPt[28]) + wPt[27];
375+
wPt[44] = SSIG1(wPt[42]) + wPt[37] + SSIG0(wPt[29]) + wPt[28];
376+
wPt[45] = SSIG1(wPt[43]) + wPt[38] + SSIG0(wPt[30]) + wPt[29];
377+
wPt[46] = SSIG1(wPt[44]) + wPt[39] + SSIG0(wPt[31]) + wPt[30];
378+
wPt[47] = SSIG1(wPt[45]) + wPt[40] + SSIG0(wPt[32]) + wPt[31];
379+
wPt[48] = SSIG1(wPt[46]) + wPt[41] + SSIG0(wPt[33]) + wPt[32];
380+
wPt[49] = SSIG1(wPt[47]) + wPt[42] + SSIG0(wPt[34]) + wPt[33];
381+
wPt[50] = SSIG1(wPt[48]) + wPt[43] + SSIG0(wPt[35]) + wPt[34];
382+
wPt[51] = SSIG1(wPt[49]) + wPt[44] + SSIG0(wPt[36]) + wPt[35];
383+
wPt[52] = SSIG1(wPt[50]) + wPt[45] + SSIG0(wPt[37]) + wPt[36];
384+
wPt[53] = SSIG1(wPt[51]) + wPt[46] + SSIG0(wPt[38]) + wPt[37];
385+
wPt[54] = SSIG1(wPt[52]) + wPt[47] + SSIG0(wPt[39]) + wPt[38];
386+
wPt[55] = SSIG1(wPt[53]) + wPt[48] + SSIG0(wPt[40]) + wPt[39];
387+
wPt[56] = SSIG1(wPt[54]) + wPt[49] + SSIG0(wPt[41]) + wPt[40];
388+
wPt[57] = SSIG1(wPt[55]) + wPt[50] + SSIG0(wPt[42]) + wPt[41];
389+
wPt[58] = SSIG1(wPt[56]) + wPt[51] + SSIG0(wPt[43]) + wPt[42];
390+
wPt[59] = SSIG1(wPt[57]) + wPt[52] + SSIG0(wPt[44]) + wPt[43];
391+
wPt[60] = SSIG1(wPt[58]) + wPt[53] + SSIG0(wPt[45]) + wPt[44];
392+
wPt[61] = SSIG1(wPt[59]) + wPt[54] + SSIG0(wPt[46]) + wPt[45];
393+
wPt[62] = SSIG1(wPt[60]) + wPt[55] + SSIG0(wPt[47]) + wPt[46];
394+
wPt[63] = SSIG1(wPt[61]) + wPt[56] + SSIG0(wPt[48]) + wPt[47];
395+
wPt[64] = SSIG1(wPt[62]) + wPt[57] + SSIG0(wPt[49]) + wPt[48];
396+
wPt[65] = SSIG1(wPt[63]) + wPt[58] + SSIG0(wPt[50]) + wPt[49];
397+
wPt[66] = SSIG1(wPt[64]) + wPt[59] + SSIG0(wPt[51]) + wPt[50];
398+
wPt[67] = SSIG1(wPt[65]) + wPt[60] + SSIG0(wPt[52]) + wPt[51];
399+
wPt[68] = SSIG1(wPt[66]) + wPt[61] + SSIG0(wPt[53]) + wPt[52];
400+
wPt[69] = SSIG1(wPt[67]) + wPt[62] + SSIG0(wPt[54]) + wPt[53];
401+
wPt[70] = SSIG1(wPt[68]) + wPt[63] + SSIG0(wPt[55]) + wPt[54];
402+
wPt[71] = SSIG1(wPt[69]) + wPt[64] + SSIG0(wPt[56]) + wPt[55];
403+
wPt[72] = SSIG1(wPt[70]) + wPt[65] + SSIG0(wPt[57]) + wPt[56];
404+
wPt[73] = SSIG1(wPt[71]) + wPt[66] + SSIG0(wPt[58]) + wPt[57];
405+
wPt[74] = SSIG1(wPt[72]) + wPt[67] + SSIG0(wPt[59]) + wPt[58];
406+
wPt[75] = SSIG1(wPt[73]) + wPt[68] + SSIG0(wPt[60]) + wPt[59];
407+
wPt[76] = SSIG1(wPt[74]) + wPt[69] + SSIG0(wPt[61]) + wPt[60];
408+
wPt[77] = SSIG1(wPt[75]) + wPt[70] + SSIG0(wPt[62]) + wPt[61];
409+
wPt[78] = SSIG1(wPt[76]) + wPt[71] + SSIG0(wPt[63]) + wPt[62];
410+
wPt[79] = SSIG1(wPt[77]) + wPt[72] + SSIG0(wPt[64]) + wPt[63];
411+
412+
CompressBlockWithWSet(hPt, wPt);
413+
}
414+
336415
/// <summary>
337416
/// Computes _single_ SHA512 hash for the second block of
338417
/// (data.Length == 165) and (wPt[0] to wPt[15] is set) and (Init() is called)

Src/Tests/Backend/Hashing/Sha512FoTests.cs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,7 @@ private static byte[] GetRandomBytes(int len)
156156
}
157157
private static byte[] ComputeSingleSha(byte[] data)
158158
{
159-
using System.Security.Cryptography.SHA512 sysSha = System.Security.Cryptography.SHA512.Create();
160-
return sysSha.ComputeHash(data);
159+
return System.Security.Cryptography.SHA512.HashData(data);
161160
}
162161

163162
[Fact]
@@ -317,6 +316,45 @@ public unsafe void CompressSingleBlockTest(int len)
317316
}
318317
}
319318

319+
[Fact]
320+
public unsafe void Compress64Test()
321+
{
322+
int dataLen = 64;
323+
byte[] data = GetRandomBytes(dataLen);
324+
byte[] expected = ComputeSingleSha(data);
325+
326+
ulong* hPt = stackalloc ulong[Sha512Fo.UBufferSize];
327+
ulong* wPt = hPt + Sha512Fo.HashStateSize;
328+
329+
int dIndex = 0;
330+
for (int i = 0; i < 8; i++, dIndex += 8)
331+
{
332+
wPt[i] =
333+
((ulong)data[dIndex] << 56) |
334+
((ulong)data[dIndex + 1] << 48) |
335+
((ulong)data[dIndex + 2] << 40) |
336+
((ulong)data[dIndex + 3] << 32) |
337+
((ulong)data[dIndex + 4] << 24) |
338+
((ulong)data[dIndex + 5] << 16) |
339+
((ulong)data[dIndex + 6] << 8) |
340+
data[dIndex + 7];
341+
}
342+
wPt[8] = 0b10000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000UL;
343+
for (int i = 9; i < 15; i++)
344+
{
345+
wPt[i] = 0;
346+
}
347+
348+
wPt[15] = (ulong)(dataLen * 8);
349+
350+
Sha512Fo.Init(hPt);
351+
Sha512Fo.Compress64(hPt, wPt);
352+
353+
byte[] actual = Sha512Fo.GetBytes(hPt);
354+
355+
Assert.Equal(expected, actual);
356+
}
357+
320358
[Fact]
321359
public unsafe void Compress165SecondBlockTest()
322360
{

0 commit comments

Comments
 (0)