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,280 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Utilities;
namespace Org.BouncyCastle.Crypto.Macs;
public class Poly1305 : IMac
{
private const int BlockSize = 16;
private readonly IBlockCipher cipher;
private readonly byte[] singleByte = new byte[1];
private uint r0;
private uint r1;
private uint r2;
private uint r3;
private uint r4;
private uint s1;
private uint s2;
private uint s3;
private uint s4;
private uint k0;
private uint k1;
private uint k2;
private uint k3;
private byte[] currentBlock = new byte[16];
private int currentBlockOffset = 0;
private uint h0;
private uint h1;
private uint h2;
private uint h3;
private uint h4;
public string AlgorithmName
{
get
{
if (cipher != null)
{
return "Poly1305-" + cipher.AlgorithmName;
}
return "Poly1305";
}
}
public Poly1305()
{
cipher = null;
}
public Poly1305(IBlockCipher cipher)
{
if (cipher.GetBlockSize() != 16)
{
throw new ArgumentException("Poly1305 requires a 128 bit block cipher.");
}
this.cipher = cipher;
}
public void Init(ICipherParameters parameters)
{
byte[] nonce = null;
if (cipher != null)
{
if (!(parameters is ParametersWithIV))
{
throw new ArgumentException("Poly1305 requires an IV when used with a block cipher.", "parameters");
}
ParametersWithIV parametersWithIV = (ParametersWithIV)parameters;
nonce = parametersWithIV.GetIV();
parameters = parametersWithIV.Parameters;
}
if (!(parameters is KeyParameter))
{
throw new ArgumentException("Poly1305 requires a key.");
}
KeyParameter keyParameter = (KeyParameter)parameters;
SetKey(keyParameter.GetKey(), nonce);
Reset();
}
private void SetKey(byte[] key, byte[] nonce)
{
if (key.Length != 32)
{
throw new ArgumentException("Poly1305 key must be 256 bits.");
}
if (cipher != null && (nonce == null || nonce.Length != 16))
{
throw new ArgumentException("Poly1305 requires a 128 bit IV.");
}
uint num = Pack.LE_To_UInt32(key, 0);
uint num2 = Pack.LE_To_UInt32(key, 4);
uint num3 = Pack.LE_To_UInt32(key, 8);
uint num4 = Pack.LE_To_UInt32(key, 12);
r0 = num & 0x3FFFFFF;
r1 = ((num >> 26) | (num2 << 6)) & 0x3FFFF03;
r2 = ((num2 >> 20) | (num3 << 12)) & 0x3FFC0FF;
r3 = ((num3 >> 14) | (num4 << 18)) & 0x3F03FFF;
r4 = (num4 >> 8) & 0xFFFFF;
s1 = r1 * 5;
s2 = r2 * 5;
s3 = r3 * 5;
s4 = r4 * 5;
byte[] array;
int num5;
if (cipher == null)
{
array = key;
num5 = 16;
}
else
{
array = new byte[16];
num5 = 0;
cipher.Init(forEncryption: true, new KeyParameter(key, 16, 16));
cipher.ProcessBlock(nonce, 0, array, 0);
}
k0 = Pack.LE_To_UInt32(array, num5);
k1 = Pack.LE_To_UInt32(array, num5 + 4);
k2 = Pack.LE_To_UInt32(array, num5 + 8);
k3 = Pack.LE_To_UInt32(array, num5 + 12);
}
public int GetMacSize()
{
return 16;
}
public void Update(byte input)
{
singleByte[0] = input;
BlockUpdate(singleByte, 0, 1);
}
public void BlockUpdate(byte[] input, int inOff, int len)
{
int num = 0;
while (len > num)
{
if (currentBlockOffset == 16)
{
ProcessBlock();
currentBlockOffset = 0;
}
int num2 = System.Math.Min(len - num, 16 - currentBlockOffset);
Array.Copy(input, num + inOff, currentBlock, currentBlockOffset, num2);
num += num2;
currentBlockOffset += num2;
}
}
private void ProcessBlock()
{
if (currentBlockOffset < 16)
{
currentBlock[currentBlockOffset] = 1;
for (int i = currentBlockOffset + 1; i < 16; i++)
{
currentBlock[i] = 0;
}
}
ulong num = Pack.LE_To_UInt32(currentBlock, 0);
ulong num2 = Pack.LE_To_UInt32(currentBlock, 4);
ulong num3 = Pack.LE_To_UInt32(currentBlock, 8);
ulong num4 = Pack.LE_To_UInt32(currentBlock, 12);
h0 += (uint)(int)(num & 0x3FFFFFF);
h1 += (uint)(int)((((num2 << 32) | num) >> 26) & 0x3FFFFFF);
h2 += (uint)(int)((((num3 << 32) | num2) >> 20) & 0x3FFFFFF);
h3 += (uint)(int)((((num4 << 32) | num3) >> 14) & 0x3FFFFFF);
h4 += (uint)(int)(num4 >> 8);
if (currentBlockOffset == 16)
{
h4 += 16777216u;
}
ulong num5 = mul32x32_64(h0, r0) + mul32x32_64(h1, s4) + mul32x32_64(h2, s3) + mul32x32_64(h3, s2) + mul32x32_64(h4, s1);
ulong num6 = mul32x32_64(h0, r1) + mul32x32_64(h1, r0) + mul32x32_64(h2, s4) + mul32x32_64(h3, s3) + mul32x32_64(h4, s2);
ulong num7 = mul32x32_64(h0, r2) + mul32x32_64(h1, r1) + mul32x32_64(h2, r0) + mul32x32_64(h3, s4) + mul32x32_64(h4, s3);
ulong num8 = mul32x32_64(h0, r3) + mul32x32_64(h1, r2) + mul32x32_64(h2, r1) + mul32x32_64(h3, r0) + mul32x32_64(h4, s4);
ulong num9 = mul32x32_64(h0, r4) + mul32x32_64(h1, r3) + mul32x32_64(h2, r2) + mul32x32_64(h3, r1) + mul32x32_64(h4, r0);
h0 = (uint)((int)num5 & 0x3FFFFFF);
num6 += num5 >> 26;
h1 = (uint)((int)num6 & 0x3FFFFFF);
num7 += num6 >> 26;
h2 = (uint)((int)num7 & 0x3FFFFFF);
num8 += num7 >> 26;
h3 = (uint)((int)num8 & 0x3FFFFFF);
num9 += num8 >> 26;
h4 = (uint)((int)num9 & 0x3FFFFFF);
h0 += (uint)((int)(num9 >> 26) * 5);
h1 += h0 >> 26;
h0 &= 67108863u;
}
public int DoFinal(byte[] output, int outOff)
{
Check.DataLength(output, outOff, 16, "Output buffer is too short.");
if (currentBlockOffset > 0)
{
ProcessBlock();
}
h1 += h0 >> 26;
h0 &= 67108863u;
h2 += h1 >> 26;
h1 &= 67108863u;
h3 += h2 >> 26;
h2 &= 67108863u;
h4 += h3 >> 26;
h3 &= 67108863u;
h0 += (h4 >> 26) * 5;
h4 &= 67108863u;
h1 += h0 >> 26;
h0 &= 67108863u;
uint num = h0 + 5;
uint num2 = num >> 26;
num &= 0x3FFFFFF;
uint num3 = h1 + num2;
num2 = num3 >> 26;
num3 &= 0x3FFFFFF;
uint num4 = h2 + num2;
num2 = num4 >> 26;
num4 &= 0x3FFFFFF;
uint num5 = h3 + num2;
num2 = num5 >> 26;
num5 &= 0x3FFFFFF;
uint num6 = h4 + num2 - 67108864;
num2 = (num6 >> 31) - 1;
uint num7 = ~num2;
h0 = (h0 & num7) | (num & num2);
h1 = (h1 & num7) | (num3 & num2);
h2 = (h2 & num7) | (num4 & num2);
h3 = (h3 & num7) | (num5 & num2);
h4 = (h4 & num7) | (num6 & num2);
ulong num8 = (ulong)(h0 | (h1 << 26)) + (ulong)k0;
ulong num9 = (ulong)((h1 >> 6) | (h2 << 20)) + (ulong)k1;
ulong num10 = (ulong)((h2 >> 12) | (h3 << 14)) + (ulong)k2;
ulong num11 = (ulong)((h3 >> 18) | (h4 << 8)) + (ulong)k3;
Pack.UInt32_To_LE((uint)num8, output, outOff);
num9 += num8 >> 32;
Pack.UInt32_To_LE((uint)num9, output, outOff + 4);
num10 += num9 >> 32;
Pack.UInt32_To_LE((uint)num10, output, outOff + 8);
num11 += num10 >> 32;
Pack.UInt32_To_LE((uint)num11, output, outOff + 12);
Reset();
return 16;
}
public void Reset()
{
currentBlockOffset = 0;
h0 = (h1 = (h2 = (h3 = (h4 = 0u))));
}
private static ulong mul32x32_64(uint i1, uint i2)
{
return (ulong)i1 * (ulong)i2;
}
}