init commit

This commit is contained in:
2025-10-09 09:57:24 +09:00
commit 4d551bd74f
6636 changed files with 1218703 additions and 0 deletions

View File

@@ -0,0 +1,385 @@
using System;
using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Digests;
public class Blake2sDigest : IDigest
{
private const int ROUNDS = 10;
private const int BLOCK_LENGTH_BYTES = 64;
private static readonly uint[] blake2s_IV = new uint[8] { 1779033703u, 3144134277u, 1013904242u, 2773480762u, 1359893119u, 2600822924u, 528734635u, 1541459225u };
private static readonly byte[,] blake2s_sigma = new byte[10, 16]
{
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15
},
{
14, 10, 4, 8, 9, 15, 13, 6, 1, 12,
0, 2, 11, 7, 5, 3
},
{
11, 8, 12, 0, 5, 2, 15, 13, 10, 14,
3, 6, 7, 1, 9, 4
},
{
7, 9, 3, 1, 13, 12, 11, 14, 2, 6,
5, 10, 4, 0, 15, 8
},
{
9, 0, 5, 7, 2, 4, 10, 15, 14, 1,
11, 12, 6, 8, 3, 13
},
{
2, 12, 6, 10, 0, 11, 8, 3, 4, 13,
7, 5, 15, 14, 1, 9
},
{
12, 5, 1, 15, 14, 13, 4, 10, 0, 7,
6, 3, 9, 2, 8, 11
},
{
13, 11, 7, 14, 12, 1, 3, 9, 5, 0,
15, 4, 8, 6, 2, 10
},
{
6, 15, 14, 9, 11, 3, 0, 8, 12, 2,
13, 7, 1, 4, 10, 5
},
{
10, 2, 8, 4, 7, 6, 1, 5, 15, 11,
9, 14, 3, 12, 13, 0
}
};
private int digestLength = 32;
private int keyLength = 0;
private byte[] salt = null;
private byte[] personalization = null;
private byte[] key = null;
private byte[] buffer = null;
private int bufferPos = 0;
private uint[] internalState = new uint[16];
private uint[] chainValue = null;
private uint t0 = 0u;
private uint t1 = 0u;
private uint f0 = 0u;
public virtual string AlgorithmName => "BLAKE2s";
public Blake2sDigest()
: this(256)
{
}
public Blake2sDigest(Blake2sDigest digest)
{
bufferPos = digest.bufferPos;
buffer = Arrays.Clone(digest.buffer);
keyLength = digest.keyLength;
key = Arrays.Clone(digest.key);
digestLength = digest.digestLength;
chainValue = Arrays.Clone(digest.chainValue);
personalization = Arrays.Clone(digest.personalization);
}
public Blake2sDigest(int digestBits)
{
if (digestBits < 8 || digestBits > 256 || digestBits % 8 != 0)
{
throw new ArgumentException("BLAKE2s digest bit length must be a multiple of 8 and not greater than 256");
}
buffer = new byte[64];
keyLength = 0;
digestLength = digestBits / 8;
Init();
}
public Blake2sDigest(byte[] key)
{
buffer = new byte[64];
if (key != null)
{
if (key.Length > 32)
{
throw new ArgumentException("Keys > 32 are not supported");
}
this.key = new byte[key.Length];
Array.Copy(key, 0, this.key, 0, key.Length);
keyLength = key.Length;
Array.Copy(key, 0, buffer, 0, key.Length);
bufferPos = 64;
}
digestLength = 32;
Init();
}
public Blake2sDigest(byte[] key, int digestBytes, byte[] salt, byte[] personalization)
{
if (digestBytes < 1 || digestBytes > 32)
{
throw new ArgumentException("Invalid digest length (required: 1 - 32)");
}
digestLength = digestBytes;
buffer = new byte[64];
if (salt != null)
{
if (salt.Length != 8)
{
throw new ArgumentException("Salt length must be exactly 8 bytes");
}
this.salt = new byte[8];
Array.Copy(salt, 0, this.salt, 0, salt.Length);
}
if (personalization != null)
{
if (personalization.Length != 8)
{
throw new ArgumentException("Personalization length must be exactly 8 bytes");
}
this.personalization = new byte[8];
Array.Copy(personalization, 0, this.personalization, 0, personalization.Length);
}
if (key != null)
{
if (key.Length > 32)
{
throw new ArgumentException("Keys > 32 bytes are not supported");
}
this.key = new byte[key.Length];
Array.Copy(key, 0, this.key, 0, key.Length);
keyLength = key.Length;
Array.Copy(key, 0, buffer, 0, key.Length);
bufferPos = 64;
}
Init();
}
private void Init()
{
if (chainValue == null)
{
chainValue = new uint[8];
chainValue[0] = blake2s_IV[0] ^ (uint)(digestLength | (keyLength << 8) | 0x1010000);
chainValue[1] = blake2s_IV[1];
chainValue[2] = blake2s_IV[2];
chainValue[3] = blake2s_IV[3];
chainValue[4] = blake2s_IV[4];
chainValue[5] = blake2s_IV[5];
if (salt != null)
{
uint[] array;
(array = chainValue)[4] = array[4] ^ Pack.LE_To_UInt32(salt, 0);
(array = chainValue)[5] = array[5] ^ Pack.LE_To_UInt32(salt, 4);
}
chainValue[6] = blake2s_IV[6];
chainValue[7] = blake2s_IV[7];
if (personalization != null)
{
uint[] array;
(array = chainValue)[6] = array[6] ^ Pack.LE_To_UInt32(personalization, 0);
(array = chainValue)[7] = array[7] ^ Pack.LE_To_UInt32(personalization, 4);
}
}
}
private void InitializeInternalState()
{
Array.Copy(chainValue, 0, internalState, 0, chainValue.Length);
Array.Copy(blake2s_IV, 0, internalState, chainValue.Length, 4);
internalState[12] = t0 ^ blake2s_IV[4];
internalState[13] = t1 ^ blake2s_IV[5];
internalState[14] = f0 ^ blake2s_IV[6];
internalState[15] = blake2s_IV[7];
}
public virtual void Update(byte b)
{
if (64 - bufferPos == 0)
{
t0 += 64u;
if (t0 == 0)
{
t1++;
}
Compress(buffer, 0);
Array.Clear(buffer, 0, buffer.Length);
buffer[0] = b;
bufferPos = 1;
}
else
{
buffer[bufferPos] = b;
bufferPos++;
}
}
public virtual void BlockUpdate(byte[] message, int offset, int len)
{
if (message == null || len == 0)
{
return;
}
int num = 0;
if (bufferPos != 0)
{
num = 64 - bufferPos;
if (num >= len)
{
Array.Copy(message, offset, buffer, bufferPos, len);
bufferPos += len;
return;
}
Array.Copy(message, offset, buffer, bufferPos, num);
t0 += 64u;
if (t0 == 0)
{
t1++;
}
Compress(buffer, 0);
bufferPos = 0;
Array.Clear(buffer, 0, buffer.Length);
}
int num2 = offset + len - 64;
int i;
for (i = offset + num; i < num2; i += 64)
{
t0 += 64u;
if (t0 == 0)
{
t1++;
}
Compress(message, i);
}
Array.Copy(message, i, buffer, 0, offset + len - i);
bufferPos += offset + len - i;
}
public virtual int DoFinal(byte[] output, int outOffset)
{
f0 = uint.MaxValue;
t0 += (uint)bufferPos;
if (t0 < 0 && bufferPos > 0L - (long)t0)
{
t1++;
}
Compress(buffer, 0);
Array.Clear(buffer, 0, buffer.Length);
Array.Clear(internalState, 0, internalState.Length);
for (int i = 0; i < chainValue.Length && i * 4 < digestLength; i++)
{
byte[] sourceArray = Pack.UInt32_To_LE(chainValue[i]);
if (i * 4 < digestLength - 4)
{
Array.Copy(sourceArray, 0, output, outOffset + i * 4, 4);
}
else
{
Array.Copy(sourceArray, 0, output, outOffset + i * 4, digestLength - i * 4);
}
}
Array.Clear(chainValue, 0, chainValue.Length);
Reset();
return digestLength;
}
public virtual void Reset()
{
bufferPos = 0;
f0 = 0u;
t0 = 0u;
t1 = 0u;
chainValue = null;
Array.Clear(buffer, 0, buffer.Length);
if (key != null)
{
Array.Copy(key, 0, buffer, 0, key.Length);
bufferPos = 64;
}
Init();
}
private void Compress(byte[] message, int messagePos)
{
InitializeInternalState();
uint[] array = new uint[16];
for (int i = 0; i < 16; i++)
{
array[i] = Pack.LE_To_UInt32(message, messagePos + i * 4);
}
for (int j = 0; j < 10; j++)
{
G(array[blake2s_sigma[j, 0]], array[blake2s_sigma[j, 1]], 0, 4, 8, 12);
G(array[blake2s_sigma[j, 2]], array[blake2s_sigma[j, 3]], 1, 5, 9, 13);
G(array[blake2s_sigma[j, 4]], array[blake2s_sigma[j, 5]], 2, 6, 10, 14);
G(array[blake2s_sigma[j, 6]], array[blake2s_sigma[j, 7]], 3, 7, 11, 15);
G(array[blake2s_sigma[j, 8]], array[blake2s_sigma[j, 9]], 0, 5, 10, 15);
G(array[blake2s_sigma[j, 10]], array[blake2s_sigma[j, 11]], 1, 6, 11, 12);
G(array[blake2s_sigma[j, 12]], array[blake2s_sigma[j, 13]], 2, 7, 8, 13);
G(array[blake2s_sigma[j, 14]], array[blake2s_sigma[j, 15]], 3, 4, 9, 14);
}
for (int k = 0; k < chainValue.Length; k++)
{
chainValue[k] = chainValue[k] ^ internalState[k] ^ internalState[k + 8];
}
}
private void G(uint m1, uint m2, int posA, int posB, int posC, int posD)
{
internalState[posA] = internalState[posA] + internalState[posB] + m1;
internalState[posD] = rotr32(internalState[posD] ^ internalState[posA], 16);
internalState[posC] += internalState[posD];
internalState[posB] = rotr32(internalState[posB] ^ internalState[posC], 12);
internalState[posA] = internalState[posA] + internalState[posB] + m2;
internalState[posD] = rotr32(internalState[posD] ^ internalState[posA], 8);
internalState[posC] += internalState[posD];
internalState[posB] = rotr32(internalState[posB] ^ internalState[posC], 7);
}
private uint rotr32(uint x, int rot)
{
return (x >> rot) | (x << -rot);
}
public virtual int GetDigestSize()
{
return digestLength;
}
public virtual int GetByteLength()
{
return 64;
}
public virtual void ClearKey()
{
if (key != null)
{
Array.Clear(key, 0, key.Length);
Array.Clear(buffer, 0, buffer.Length);
}
}
public virtual void ClearSalt()
{
if (salt != null)
{
Array.Clear(salt, 0, salt.Length);
}
}
}