273 lines
8.5 KiB
C#
273 lines
8.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using PspCrypto.Security.Cryptography;
|
|
|
|
namespace PspCrypto
|
|
{
|
|
public class SHA224Managed_OLD : SHA224
|
|
{
|
|
|
|
private const int BLOCK_SIZE_BYTES = 64;
|
|
|
|
private uint[] _H;
|
|
private ulong count;
|
|
private byte[] _ProcessingBuffer; // Used to start data when passed less than a block worth.
|
|
private int _ProcessingBufferCount; // Counts how much data we have stored that still needs processed.
|
|
private uint[] buff;
|
|
|
|
public SHA224Managed_OLD()
|
|
{
|
|
_H = new uint[8];
|
|
_ProcessingBuffer = new byte[BLOCK_SIZE_BYTES];
|
|
buff = new uint[64];
|
|
Initialize();
|
|
}
|
|
|
|
private uint Ch(uint u, uint v, uint w)
|
|
{
|
|
return (u & v) ^ (~u & w);
|
|
}
|
|
|
|
private uint Maj(uint u, uint v, uint w)
|
|
{
|
|
return (u & v) ^ (u & w) ^ (v & w);
|
|
}
|
|
|
|
private uint Ro0(uint x)
|
|
{
|
|
return ((x >> 7) | (x << 25))
|
|
^ ((x >> 18) | (x << 14))
|
|
^ (x >> 3);
|
|
}
|
|
|
|
private uint Ro1(uint x)
|
|
{
|
|
return ((x >> 17) | (x << 15))
|
|
^ ((x >> 19) | (x << 13))
|
|
^ (x >> 10);
|
|
}
|
|
|
|
private uint Sig0(uint x)
|
|
{
|
|
return ((x >> 2) | (x << 30))
|
|
^ ((x >> 13) | (x << 19))
|
|
^ ((x >> 22) | (x << 10));
|
|
}
|
|
|
|
private uint Sig1(uint x)
|
|
{
|
|
return ((x >> 6) | (x << 26))
|
|
^ ((x >> 11) | (x << 21))
|
|
^ ((x >> 25) | (x << 7));
|
|
}
|
|
|
|
|
|
public void HashData2(ReadOnlySpan<byte> data, Span<byte> hash)
|
|
{
|
|
var tmp = ComputeHash(data.ToArray());
|
|
tmp.CopyTo(hash);
|
|
}
|
|
|
|
protected override void HashCore(byte[] rgb, int start, int size)
|
|
{
|
|
int i;
|
|
State = 1;
|
|
|
|
if (_ProcessingBufferCount != 0)
|
|
{
|
|
if (size < (BLOCK_SIZE_BYTES - _ProcessingBufferCount))
|
|
{
|
|
System.Buffer.BlockCopy(rgb, start, _ProcessingBuffer, _ProcessingBufferCount, size);
|
|
_ProcessingBufferCount += size;
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
i = (BLOCK_SIZE_BYTES - _ProcessingBufferCount);
|
|
System.Buffer.BlockCopy(rgb, start, _ProcessingBuffer, _ProcessingBufferCount, i);
|
|
ProcessBlock(_ProcessingBuffer, 0);
|
|
_ProcessingBufferCount = 0;
|
|
start += i;
|
|
size -= i;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < size - size % BLOCK_SIZE_BYTES; i += BLOCK_SIZE_BYTES)
|
|
{
|
|
ProcessBlock(rgb, start + i);
|
|
}
|
|
|
|
if (size % BLOCK_SIZE_BYTES != 0)
|
|
{
|
|
System.Buffer.BlockCopy(rgb, size - size % BLOCK_SIZE_BYTES + start, _ProcessingBuffer, 0, size % BLOCK_SIZE_BYTES);
|
|
_ProcessingBufferCount = size % BLOCK_SIZE_BYTES;
|
|
}
|
|
}
|
|
|
|
protected override byte[] HashFinal()
|
|
{
|
|
byte[] hash = new byte[28];
|
|
int i, j;
|
|
|
|
ProcessFinalBlock(_ProcessingBuffer, 0, _ProcessingBufferCount);
|
|
|
|
for (i = 0; i < 7; i++)
|
|
{
|
|
for (j = 0; j < 4; j++)
|
|
{
|
|
hash[i * 4 + j] = (byte)(_H[i] >> (24 - j * 8));
|
|
}
|
|
}
|
|
|
|
State = 0;
|
|
return hash;
|
|
}
|
|
|
|
public override void Initialize()
|
|
{
|
|
count = 0;
|
|
_ProcessingBufferCount = 0;
|
|
|
|
_H[0] = 0xC1059ED8;
|
|
_H[1] = 0x367CD507;
|
|
_H[2] = 0x3070DD17;
|
|
_H[3] = 0xF70E5939;
|
|
_H[4] = 0xFFC00B31;
|
|
_H[5] = 0x68581511;
|
|
_H[6] = 0x64F98FA7;
|
|
_H[7] = 0xBEFA4FA4;
|
|
}
|
|
|
|
private void ProcessBlock(byte[] inputBuffer, int inputOffset)
|
|
{
|
|
uint a, b, c, d, e, f, g, h;
|
|
uint t1, t2;
|
|
int i;
|
|
uint[] K1 = _K1;
|
|
uint[] buff = this.buff;
|
|
|
|
count += BLOCK_SIZE_BYTES;
|
|
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
buff[i] = (uint)(((inputBuffer[inputOffset + 4 * i]) << 24)
|
|
| ((inputBuffer[inputOffset + 4 * i + 1]) << 16)
|
|
| ((inputBuffer[inputOffset + 4 * i + 2]) << 8)
|
|
| ((inputBuffer[inputOffset + 4 * i + 3])));
|
|
}
|
|
|
|
|
|
for (i = 16; i < 64; i++)
|
|
{
|
|
t1 = buff[i - 15];
|
|
t1 = (((t1 >> 7) | (t1 << 25)) ^ ((t1 >> 18) | (t1 << 14)) ^ (t1 >> 3));
|
|
|
|
t2 = buff[i - 2];
|
|
t2 = (((t2 >> 17) | (t2 << 15)) ^ ((t2 >> 19) | (t2 << 13)) ^ (t2 >> 10));
|
|
buff[i] = t2 + buff[i - 7] + t1 + buff[i - 16];
|
|
}
|
|
|
|
a = _H[0];
|
|
b = _H[1];
|
|
c = _H[2];
|
|
d = _H[3];
|
|
e = _H[4];
|
|
f = _H[5];
|
|
g = _H[6];
|
|
h = _H[7];
|
|
|
|
for (i = 0; i < 64; i++)
|
|
{
|
|
t1 = h + (((e >> 6) | (e << 26)) ^ ((e >> 11) | (e << 21)) ^ ((e >> 25) | (e << 7))) + ((e & f) ^ (~e & g)) + K1[i] + buff[i];
|
|
|
|
t2 = (((a >> 2) | (a << 30)) ^ ((a >> 13) | (a << 19)) ^ ((a >> 22) | (a << 10)));
|
|
t2 = t2 + ((a & b) ^ (a & c) ^ (b & c));
|
|
h = g;
|
|
g = f;
|
|
f = e;
|
|
e = d + t1;
|
|
d = c;
|
|
c = b;
|
|
b = a;
|
|
a = t1 + t2;
|
|
}
|
|
|
|
_H[0] += a;
|
|
_H[1] += b;
|
|
_H[2] += c;
|
|
_H[3] += d;
|
|
_H[4] += e;
|
|
_H[5] += f;
|
|
_H[6] += g;
|
|
_H[7] += h;
|
|
}
|
|
|
|
private void ProcessFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
|
|
{
|
|
ulong total = count + (ulong)inputCount;
|
|
int paddingSize = (56 - (int)(total % BLOCK_SIZE_BYTES));
|
|
|
|
if (paddingSize < 1)
|
|
paddingSize += BLOCK_SIZE_BYTES;
|
|
|
|
byte[] fooBuffer = new byte[inputCount + paddingSize + 8];
|
|
|
|
for (int i = 0; i < inputCount; i++)
|
|
{
|
|
fooBuffer[i] = inputBuffer[i + inputOffset];
|
|
}
|
|
|
|
fooBuffer[inputCount] = 0x80;
|
|
for (int i = inputCount + 1; i < inputCount + paddingSize; i++)
|
|
{
|
|
fooBuffer[i] = 0x00;
|
|
}
|
|
|
|
// I deal in bytes. The algorithm deals in bits.
|
|
ulong size = total << 3;
|
|
AddLength(size, fooBuffer, inputCount + paddingSize);
|
|
ProcessBlock(fooBuffer, 0);
|
|
|
|
if (inputCount + paddingSize + 8 == 128)
|
|
{
|
|
ProcessBlock(fooBuffer, 64);
|
|
}
|
|
}
|
|
|
|
internal void AddLength(ulong length, byte[] buffer, int position)
|
|
{
|
|
buffer[position++] = (byte)(length >> 56);
|
|
buffer[position++] = (byte)(length >> 48);
|
|
buffer[position++] = (byte)(length >> 40);
|
|
buffer[position++] = (byte)(length >> 32);
|
|
buffer[position++] = (byte)(length >> 24);
|
|
buffer[position++] = (byte)(length >> 16);
|
|
buffer[position++] = (byte)(length >> 8);
|
|
buffer[position] = (byte)(length);
|
|
}
|
|
|
|
// SHA-224/256 Constants
|
|
// Represent the first 32 bits of the fractional parts of the
|
|
// cube roots of the first sixty-four prime numbers
|
|
public readonly static uint[] _K1 = {
|
|
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
|
|
0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
|
|
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
|
|
0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
|
|
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
|
|
0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
|
|
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
|
|
0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
|
|
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
|
|
0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
|
|
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
|
|
0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
|
|
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
|
|
0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
|
|
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
|
|
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
|
|
};
|
|
}
|
|
}
|