This commit is contained in:
2026-06-15 18:18:16 +08:00
parent 97c9fba14e
commit 2b9f134e5f
4164 changed files with 386922 additions and 79 deletions

View File

@@ -0,0 +1,650 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
#if NETSTANDARD1_0_OR_GREATER || NETCOREAPP1_0_OR_GREATER || UNITY_2021_2_OR_NEWER
using System.Runtime.CompilerServices;
#endif
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/* The BLAKE2 cryptographic hash function was designed by Jean-
Philippe Aumasson, Samuel Neves, Zooko Wilcox-O'Hearn, and Christian
Winnerlein.
Reference Implementation and Description can be found at: https://blake2.net/
Internet Draft: https://tools.ietf.org/html/draft-saarinen-blake2-02
This implementation does not support the Tree Hashing Mode.
For unkeyed hashing, developers adapting BLAKE2 to ASN.1 - based
message formats SHOULD use the OID tree at x = 1.3.6.1.4.1.1722.12.2.
Algorithm | Target | Collision | Hash | Hash ASN.1 |
Identifier | Arch | Security | nn | OID Suffix |
---------------+--------+-----------+------+------------+
id-blake2b160 | 64-bit | 2**80 | 20 | x.1.20 |
id-blake2b256 | 64-bit | 2**128 | 32 | x.1.32 |
id-blake2b384 | 64-bit | 2**192 | 48 | x.1.48 |
id-blake2b512 | 64-bit | 2**256 | 64 | x.1.64 |
---------------+--------+-----------+------+------------+
*/
/**
* Implementation of the cryptographic hash function Blake2b.
* <p/>
* Blake2b offers a built-in keying mechanism to be used directly
* for authentication ("Prefix-MAC") rather than a HMAC construction.
* <p/>
* Blake2b offers a built-in support for a salt for randomized hashing
* and a personal string for defining a unique hash function for each application.
* <p/>
* BLAKE2b is optimized for 64-bit platforms and produces digests of any size
* between 1 and 64 bytes.
*/
public sealed class Blake2bDigest
: IDigest
{
// Blake2b Initialization Vector:
private static readonly ulong[] blake2b_IV =
// Produced from the square root of primes 2, 3, 5, 7, 11, 13, 17, 19.
// The same as SHA-512 IV.
{
0x6a09e667f3bcc908UL, 0xbb67ae8584caa73bUL, 0x3c6ef372fe94f82bUL,
0xa54ff53a5f1d36f1UL, 0x510e527fade682d1UL, 0x9b05688c2b3e6c1fUL,
0x1f83d9abfb41bd6bUL, 0x5be0cd19137e2179UL
};
// Message word permutations:
private static readonly byte[,] blake2b_sigma =
{
{ 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 },
{ 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 }
};
private const int ROUNDS = 12; // to use for Catenas H'
private const int BLOCK_LENGTH_BYTES = 128;// bytes
// General parameters:
private int digestLength = 64; // 1- 64 bytes
private int keyLength = 0; // 0 - 64 bytes for keyed hashing for MAC
private byte[] salt = null;// new byte[16];
private byte[] personalization = null;// new byte[16];
// the key
private byte[] key = null;
// Tree hashing parameters:
// Because this class does not implement the Tree Hashing Mode,
// these parameters can be treated as constants (see init() function)
/*
* private int fanout = 1; // 0-255 private int depth = 1; // 1 - 255
* private int leafLength= 0; private long nodeOffset = 0L; private int
* nodeDepth = 0; private int innerHashLength = 0;
*/
// whenever this buffer overflows, it will be processed
// in the Compress() function.
// For performance issues, long messages will not use this buffer.
private byte[] buffer = null;// new byte[BLOCK_LENGTH_BYTES];
// Position of last inserted byte:
private int bufferPos = 0;// a value from 0 up to 128
private ulong[] internalState = new ulong[16]; // In the Blake2b paper it is
// called: v
private ulong[] chainValue = null; // state vector, in the Blake2b paper it
// is called: h
private ulong t0 = 0UL; // holds last significant bits, counter (counts bytes)
private ulong t1 = 0UL; // counter: Length up to 2^128 are supported
private ulong f0 = 0UL; // finalization flag, for last block: ~0L
// For Tree Hashing Mode, not used here:
// private long f1 = 0L; // finalization flag, for last node: ~0L
public Blake2bDigest()
: this(512)
{
}
public Blake2bDigest(Blake2bDigest digest)
{
this.bufferPos = digest.bufferPos;
this.buffer = Arrays.Clone(digest.buffer);
this.keyLength = digest.keyLength;
this.key = Arrays.Clone(digest.key);
this.digestLength = digest.digestLength;
this.chainValue = Arrays.Clone(digest.chainValue);
this.personalization = Arrays.Clone(digest.personalization);
this.salt = Arrays.Clone(digest.salt);
this.t0 = digest.t0;
this.t1 = digest.t1;
this.f0 = digest.f0;
}
/**
* Basic sized constructor - size in bits.
*
* @param digestSize size of the digest in bits
*/
public Blake2bDigest(int digestSize)
{
if (digestSize < 8 || digestSize > 512 || digestSize % 8 != 0)
throw new ArgumentException("BLAKE2b digest bit length must be a multiple of 8 and not greater than 512");
buffer = new byte[BLOCK_LENGTH_BYTES];
keyLength = 0;
this.digestLength = digestSize / 8;
Init();
}
/**
* Blake2b for authentication ("Prefix-MAC mode").
* After calling the doFinal() method, the key will
* remain to be used for further computations of
* this instance.
* The key can be overwritten using the clearKey() method.
*
* @param key A key up to 64 bytes or null
*/
public Blake2bDigest(byte[] key)
{
buffer = new byte[BLOCK_LENGTH_BYTES];
if (key != null)
{
this.key = new byte[key.Length];
Array.Copy(key, 0, this.key, 0, key.Length);
if (key.Length > 64)
throw new ArgumentException("Keys > 64 are not supported");
keyLength = key.Length;
Array.Copy(key, 0, buffer, 0, key.Length);
bufferPos = BLOCK_LENGTH_BYTES; // zero padding
}
digestLength = 64;
Init();
}
/**
* Blake2b with key, required digest length (in bytes), salt and personalization.
* After calling the doFinal() method, the key, the salt and the personal string
* will remain and might be used for further computations with this instance.
* The key can be overwritten using the clearKey() method, the salt (pepper)
* can be overwritten using the clearSalt() method.
*
* @param key A key up to 64 bytes or null
* @param digestLength from 1 up to 64 bytes
* @param salt 16 bytes or null
* @param personalization 16 bytes or null
*/
public Blake2bDigest(byte[] key, int digestLength, byte[] salt, byte[] personalization)
{
if (digestLength < 1 || digestLength > 64)
throw new ArgumentException("Invalid digest length (required: 1 - 64)");
this.digestLength = digestLength;
this.buffer = new byte[BLOCK_LENGTH_BYTES];
if (salt != null)
{
if (salt.Length != 16)
throw new ArgumentException("salt length must be exactly 16 bytes");
this.salt = new byte[16];
Array.Copy(salt, 0, this.salt, 0, salt.Length);
}
if (personalization != null)
{
if (personalization.Length != 16)
throw new ArgumentException("personalization length must be exactly 16 bytes");
this.personalization = new byte[16];
Array.Copy(personalization, 0, this.personalization, 0, personalization.Length);
}
if (key != null)
{
if (key.Length > 64)
throw new ArgumentException("Keys > 64 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 = BLOCK_LENGTH_BYTES; // zero padding
}
Init();
}
// initialize chainValue
private void Init()
{
if (chainValue == null)
{
chainValue = new ulong[8];
chainValue[0] = blake2b_IV[0] ^ (ulong)(digestLength | (keyLength << 8) | 0x1010000);
// 0x1010000 = ((fanout << 16) | (depth << 24) | (leafLength <<
// 32));
// with fanout = 1; depth = 0; leafLength = 0;
chainValue[1] = blake2b_IV[1];// ^ nodeOffset; with nodeOffset = 0;
chainValue[2] = blake2b_IV[2];// ^ ( nodeDepth | (innerHashLength << 8) );
// with nodeDepth = 0; innerHashLength = 0;
chainValue[3] = blake2b_IV[3];
chainValue[4] = blake2b_IV[4];
chainValue[5] = blake2b_IV[5];
if (salt != null)
{
chainValue[4] ^= Pack.LE_To_UInt64(salt, 0);
chainValue[5] ^= Pack.LE_To_UInt64(salt, 8);
}
chainValue[6] = blake2b_IV[6];
chainValue[7] = blake2b_IV[7];
if (personalization != null)
{
chainValue[6] ^= Pack.LE_To_UInt64(personalization, 0);
chainValue[7] ^= Pack.LE_To_UInt64(personalization, 8);
}
}
}
private void InitializeInternalState()
{
// initialize v:
Array.Copy(chainValue, 0, internalState, 0, chainValue.Length);
Array.Copy(blake2b_IV, 0, internalState, chainValue.Length, 4);
internalState[12] = t0 ^ blake2b_IV[4];
internalState[13] = t1 ^ blake2b_IV[5];
internalState[14] = f0 ^ blake2b_IV[6];
internalState[15] = blake2b_IV[7];// ^ f1 with f1 = 0
}
/**
* update the message digest with a single byte.
*
* @param b the input byte to be entered.
*/
public void Update(byte b)
{
// process the buffer if full else add to buffer:
int remainingLength = BLOCK_LENGTH_BYTES - bufferPos;
if (remainingLength == 0)
{ // full buffer
t0 += BLOCK_LENGTH_BYTES;
if (t0 == 0)
{ // if message > 2^64
t1++;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
Compress(buffer);
#else
Compress(buffer, 0);
#endif
Array.Clear(buffer, 0, buffer.Length);// clear buffer
buffer[0] = b;
bufferPos = 1;
}
else
{
buffer[bufferPos] = b;
bufferPos++;
}
}
/**
* update the message digest with a block of bytes.
*
* @param message the byte array containing the data.
* @param offset the offset into the byte array where the data starts.
* @param len the length of the data.
*/
public void BlockUpdate(byte[] message, int offset, int len)
{
if (message == null || len == 0)
return;
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
BlockUpdate(message.AsSpan(offset, len));
#else
int remainingLength = 0; // left bytes of buffer
if (bufferPos != 0)
{ // commenced, incomplete buffer
// complete the buffer:
remainingLength = BLOCK_LENGTH_BYTES - bufferPos;
if (remainingLength < len)
{ // full buffer + at least 1 byte
Array.Copy(message, offset, buffer, bufferPos, remainingLength);
t0 += BLOCK_LENGTH_BYTES;
if (t0 == 0)
{ // if message > 2^64
t1++;
}
Compress(buffer, 0);
bufferPos = 0;
Array.Clear(buffer, 0, buffer.Length);// clear buffer
}
else
{
Array.Copy(message, offset, buffer, bufferPos, len);
bufferPos += len;
return;
}
}
// process blocks except last block (also if last block is full)
int messagePos;
int blockWiseLastPos = offset + len - BLOCK_LENGTH_BYTES;
for (messagePos = offset + remainingLength; messagePos < blockWiseLastPos; messagePos += BLOCK_LENGTH_BYTES)
{ // block wise 128 bytes
// without buffer:
t0 += BLOCK_LENGTH_BYTES;
if (t0 == 0)
{
t1++;
}
Compress(message, messagePos);
}
// fill the buffer with left bytes, this might be a full block
Array.Copy(message, messagePos, buffer, 0, offset + len - messagePos);
bufferPos += offset + len - messagePos;
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void BlockUpdate(ReadOnlySpan<byte> input)
{
if (input.IsEmpty)
return;
int remainingLength = 0; // left bytes of buffer
if (bufferPos != 0)
{ // commenced, incomplete buffer
// complete the buffer:
remainingLength = BLOCK_LENGTH_BYTES - bufferPos;
if (remainingLength < input.Length)
{ // full buffer + at least 1 byte
input[..remainingLength].CopyTo(buffer.AsSpan(bufferPos));
t0 += BLOCK_LENGTH_BYTES;
if (t0 == 0)
{ // if message > 2^64
t1++;
}
Compress(buffer);
bufferPos = 0;
Array.Clear(buffer, 0, buffer.Length);// clear buffer
}
else
{
input.CopyTo(buffer.AsSpan(bufferPos));
bufferPos += input.Length;
return;
}
}
// process blocks except last block (also if last block is full)
int messagePos;
int blockWiseLastPos = input.Length - BLOCK_LENGTH_BYTES;
for (messagePos = remainingLength; messagePos < blockWiseLastPos; messagePos += BLOCK_LENGTH_BYTES)
{ // block wise 128 bytes
// without buffer:
t0 += BLOCK_LENGTH_BYTES;
if (t0 == 0)
{
t1++;
}
Compress(input[messagePos..]);
}
// fill the buffer with left bytes, this might be a full block
input[messagePos..].CopyTo(buffer.AsSpan());
bufferPos += input.Length - messagePos;
}
#endif
/**
* close the digest, producing the final digest value. The doFinal
* call leaves the digest reset.
* Key, salt and personal string remain.
*
* @param out the array the digest is to be copied into.
* @param outOffset the offset into the out array the digest is to start at.
*/
public int DoFinal(byte[] output, int outOffset)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
return DoFinal(output.AsSpan(outOffset));
#else
f0 = 0xFFFFFFFFFFFFFFFFUL;
t0 += (ulong)bufferPos;
if (bufferPos > 0 && t0 == 0)
{
t1++;
}
Compress(buffer, 0);
Array.Clear(buffer, 0, buffer.Length);// Holds eventually the key if input is null
Array.Clear(internalState, 0, internalState.Length);
int full = digestLength >> 3, partial = digestLength & 7;
Pack.UInt64_To_LE(chainValue, 0, full, output, outOffset);
if (partial > 0)
{
byte[] bytes = new byte[8];
Pack.UInt64_To_LE(chainValue[full], bytes, 0);
Array.Copy(bytes, 0, output, outOffset + digestLength - partial, partial);
}
Array.Clear(chainValue, 0, chainValue.Length);
Reset();
return digestLength;
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public int DoFinal(Span<byte> output)
{
f0 = 0xFFFFFFFFFFFFFFFFUL;
t0 += (ulong)bufferPos;
if (bufferPos > 0 && t0 == 0)
{
t1++;
}
Compress(buffer);
Array.Clear(buffer, 0, buffer.Length);// Holds eventually the key if input is null
Array.Clear(internalState, 0, internalState.Length);
int full = digestLength >> 3, partial = digestLength & 7;
Pack.UInt64_To_LE(chainValue.AsSpan(0, full), output);
if (partial > 0)
{
Span<byte> bytes = stackalloc byte[8];
Pack.UInt64_To_LE(chainValue[full], bytes);
bytes[..partial].CopyTo(output[(digestLength - partial)..]);
}
Array.Clear(chainValue, 0, chainValue.Length);
Reset();
return digestLength;
}
#endif
/**
* Reset the digest back to it's initial state.
* The key, the salt and the personal string will
* remain for further computations.
*/
public void Reset()
{
bufferPos = 0;
f0 = 0L;
t0 = 0L;
t1 = 0L;
chainValue = null;
Array.Clear(buffer, 0, buffer.Length);
if (key != null)
{
Array.Copy(key, 0, buffer, 0, key.Length);
bufferPos = BLOCK_LENGTH_BYTES; // zero padding
}
Init();
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private void Compress(ReadOnlySpan<byte> message)
{
InitializeInternalState();
Span<ulong> m = stackalloc ulong[16];
Pack.LE_To_UInt64(message, m);
for (int round = 0; round < ROUNDS; round++)
{
// G apply to columns of internalState:m[blake2b_sigma[round][2 * blockPos]] /+1
G(m[blake2b_sigma[round, 0]], m[blake2b_sigma[round, 1]], 0, 4, 8, 12);
G(m[blake2b_sigma[round, 2]], m[blake2b_sigma[round, 3]], 1, 5, 9, 13);
G(m[blake2b_sigma[round, 4]], m[blake2b_sigma[round, 5]], 2, 6, 10, 14);
G(m[blake2b_sigma[round, 6]], m[blake2b_sigma[round, 7]], 3, 7, 11, 15);
// G apply to diagonals of internalState:
G(m[blake2b_sigma[round, 8]], m[blake2b_sigma[round, 9]], 0, 5, 10, 15);
G(m[blake2b_sigma[round, 10]], m[blake2b_sigma[round, 11]], 1, 6, 11, 12);
G(m[blake2b_sigma[round, 12]], m[blake2b_sigma[round, 13]], 2, 7, 8, 13);
G(m[blake2b_sigma[round, 14]], m[blake2b_sigma[round, 15]], 3, 4, 9, 14);
}
// update chain values:
for (int offset = 0; offset < chainValue.Length; offset++)
{
chainValue[offset] = chainValue[offset] ^ internalState[offset] ^ internalState[offset + 8];
}
}
#else
private void Compress(byte[] message, int messagePos)
{
InitializeInternalState();
ulong[] m = new ulong[16];
Pack.LE_To_UInt64(message, messagePos, m);
for (int round = 0; round < ROUNDS; round++)
{
// G apply to columns of internalState:m[blake2b_sigma[round][2 * blockPos]] /+1
G(m[blake2b_sigma[round,0]], m[blake2b_sigma[round,1]], 0, 4, 8, 12);
G(m[blake2b_sigma[round,2]], m[blake2b_sigma[round,3]], 1, 5, 9, 13);
G(m[blake2b_sigma[round,4]], m[blake2b_sigma[round,5]], 2, 6, 10, 14);
G(m[blake2b_sigma[round,6]], m[blake2b_sigma[round,7]], 3, 7, 11, 15);
// G apply to diagonals of internalState:
G(m[blake2b_sigma[round,8]], m[blake2b_sigma[round,9]], 0, 5, 10, 15);
G(m[blake2b_sigma[round,10]], m[blake2b_sigma[round,11]], 1, 6, 11, 12);
G(m[blake2b_sigma[round,12]], m[blake2b_sigma[round,13]], 2, 7, 8, 13);
G(m[blake2b_sigma[round,14]], m[blake2b_sigma[round,15]], 3, 4, 9, 14);
}
// update chain values:
for (int offset = 0; offset < chainValue.Length; offset++)
{
chainValue[offset] = chainValue[offset] ^ internalState[offset] ^ internalState[offset + 8];
}
}
#endif
#if NETSTANDARD1_0_OR_GREATER || NETCOREAPP1_0_OR_GREATER || UNITY_2021_2_OR_NEWER
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
private void G(ulong m1, ulong m2, int posA, int posB, int posC, int posD)
{
internalState[posA] = internalState[posA] + internalState[posB] + m1;
internalState[posD] = Rotr64(internalState[posD] ^ internalState[posA], 32);
internalState[posC] = internalState[posC] + internalState[posD];
internalState[posB] = Rotr64(internalState[posB] ^ internalState[posC], 24); // replaces 25 of BLAKE
internalState[posA] = internalState[posA] + internalState[posB] + m2;
internalState[posD] = Rotr64(internalState[posD] ^ internalState[posA], 16);
internalState[posC] = internalState[posC] + internalState[posD];
internalState[posB] = Rotr64(internalState[posB] ^ internalState[posC], 63); // replaces 11 of BLAKE
}
private static ulong Rotr64(ulong x, int rot)
{
return x >> rot | x << -rot;
}
/**
* return the algorithm name
*
* @return the algorithm name
*/
public string AlgorithmName => "BLAKE2b";
/**
* return the size, in bytes, of the digest produced by this message digest.
*
* @return the size, in bytes, of the digest produced by this message digest.
*/
public int GetDigestSize()
{
return digestLength;
}
/**
* Return the size in bytes of the internal buffer the digest applies it's compression
* function to.
*
* @return byte length of the digests internal buffer.
*/
public int GetByteLength()
{
return BLOCK_LENGTH_BYTES;
}
/**
* Overwrite the key
* if it is no longer used (zeroization)
*/
public void ClearKey()
{
if (key != null)
{
Array.Clear(key, 0, key.Length);
Array.Clear(buffer, 0, buffer.Length);
}
}
/**
* Overwrite the salt (pepper) if it
* is secret and no longer used (zeroization)
*/
public void ClearSalt()
{
if (salt != null)
{
Array.Clear(salt, 0, salt.Length);
}
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5c0deea8745064b488d55fa482c167c9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,684 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
#if NETSTANDARD1_0_OR_GREATER || NETCOREAPP1_0_OR_GREATER || UNITY_2021_2_OR_NEWER
using System.Runtime.CompilerServices;
#endif
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/*
The BLAKE2 cryptographic hash function was designed by Jean-
Philippe Aumasson, Samuel Neves, Zooko Wilcox-O'Hearn, and Christian
Winnerlein.
Reference Implementation and Description can be found at: https://blake2.net/
RFC: https://tools.ietf.org/html/rfc7693
This implementation does not support the Tree Hashing Mode.
For unkeyed hashing, developers adapting BLAKE2 to ASN.1 - based
message formats SHOULD use the OID tree at x = 1.3.6.1.4.1.1722.12.2.
Algorithm | Target | Collision | Hash | Hash ASN.1 |
Identifier | Arch | Security | nn | OID Suffix |
---------------+--------+-----------+------+------------+
id-blake2s128 | 32-bit | 2**64 | 16 | x.2.4 |
id-blake2s160 | 32-bit | 2**80 | 20 | x.2.5 |
id-blake2s224 | 32-bit | 2**112 | 28 | x.2.7 |
id-blake2s256 | 32-bit | 2**128 | 32 | x.2.8 |
---------------+--------+-----------+------+------------+
*/
/**
* Implementation of the cryptographic hash function BLAKE2s.
* <p/>
* BLAKE2s offers a built-in keying mechanism to be used directly
* for authentication ("Prefix-MAC") rather than a HMAC construction.
* <p/>
* BLAKE2s offers a built-in support for a salt for randomized hashing
* and a personal string for defining a unique hash function for each application.
* <p/>
* BLAKE2s is optimized for 32-bit platforms and produces digests of any size
* between 1 and 32 bytes.
*/
public sealed class Blake2sDigest
: IDigest
{
/**
* BLAKE2s Initialization Vector
**/
private static readonly uint[] blake2s_IV =
// Produced from the square root of primes 2, 3, 5, 7, 11, 13, 17, 19.
// The same as SHA-256 IV.
{
0x6a09e667, 0xbb67ae85, 0x3c6ef372,
0xa54ff53a, 0x510e527f, 0x9b05688c,
0x1f83d9ab, 0x5be0cd19
};
/**
* Message word permutations
**/
private static readonly byte[,] blake2s_sigma =
{
{ 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 const int ROUNDS = 10; // to use for Catenas H'
private const int BLOCK_LENGTH_BYTES = 64;// bytes
// General parameters:
private int digestLength = 32; // 1- 32 bytes
private int keyLength = 0; // 0 - 32 bytes for keyed hashing for MAC
private byte[] salt = null;
private byte[] personalization = null;
private byte[] key = null;
// Tree hashing parameters:
// The Tree Hashing Mode is not supported but these are used for the XOF implementation
private int fanout = 1; // 0-255
private int depth = 1; // 0-255
private int leafLength = 0;
private long nodeOffset = 0L;
private int nodeDepth = 0;
private int innerHashLength = 0;
/**
* Whenever this buffer overflows, it will be processed in the Compress()
* function. For performance issues, long messages will not use this buffer.
*/
private byte[] buffer = null;
/**
* Position of last inserted byte
**/
private int bufferPos = 0;// a value from 0 up to BLOCK_LENGTH_BYTES
/**
* Internal state, in the BLAKE2 paper it is called v
**/
private uint[] internalState = new uint[16];
/**
* State vector, in the BLAKE2 paper it is called h
**/
private uint[] chainValue = null;
// counter (counts bytes): Length up to 2^64 are supported
/**
* holds least significant bits of counter
**/
private uint t0 = 0;
/**
* holds most significant bits of counter
**/
private uint t1 = 0;
/**
* finalization flag, for last block: ~0
**/
private uint f0 = 0;
// For Tree Hashing Mode, not used here:
// private long f1 = 0L; // finalization flag, for last node: ~0L
/**
* BLAKE2s-256 for hashing.
*/
public Blake2sDigest()
: this(256)
{
}
public Blake2sDigest(Blake2sDigest digest)
{
this.bufferPos = digest.bufferPos;
this.buffer = Arrays.Clone(digest.buffer);
this.keyLength = digest.keyLength;
this.key = Arrays.Clone(digest.key);
this.digestLength = digest.digestLength;
this.internalState = Arrays.Clone(digest.internalState);
this.chainValue = Arrays.Clone(digest.chainValue);
this.t0 = digest.t0;
this.t1 = digest.t1;
this.f0 = digest.f0;
this.salt = Arrays.Clone(digest.salt);
this.personalization = Arrays.Clone(digest.personalization);
this.fanout = digest.fanout;
this.depth = digest.depth;
this.leafLength = digest.leafLength;
this.nodeOffset = digest.nodeOffset;
this.nodeDepth = digest.nodeDepth;
this.innerHashLength = digest.innerHashLength;
}
/**
* BLAKE2s for hashing.
*
* @param digestBits the desired digest length in bits. Must be a multiple of 8 and less than 256.
*/
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");
digestLength = digestBits / 8;
Init(null, null, null);
}
/**
* BLAKE2s for authentication ("Prefix-MAC mode").
* <p/>
* After calling the doFinal() method, the key will remain to be used for
* further computations of this instance. The key can be overwritten using
* the clearKey() method.
*
* @param key a key up to 32 bytes or null
*/
public Blake2sDigest(byte[] key)
{
Init(null, null, key);
}
/**
* BLAKE2s with key, required digest length, salt and personalization.
* <p/>
* After calling the doFinal() method, the key, the salt and the personal
* string will remain and might be used for further computations with this
* instance. The key can be overwritten using the clearKey() method, the
* salt (pepper) can be overwritten using the clearSalt() method.
*
* @param key a key up to 32 bytes or null
* @param digestBytes from 1 up to 32 bytes
* @param salt 8 bytes or null
* @param personalization 8 bytes or null
*/
public Blake2sDigest(byte[] key, int digestBytes, byte[] salt, byte[] personalization)
{
if (digestBytes < 1 || digestBytes > 32)
throw new ArgumentException("Invalid digest length (required: 1 - 32)");
this.digestLength = digestBytes;
Init(salt, personalization, key);
}
// XOF root hash parameters
internal Blake2sDigest(int digestBytes, byte[] key, byte[] salt, byte[] personalization, long offset)
{
digestLength = digestBytes;
nodeOffset = offset;
Init(salt, personalization, key);
}
// XOF internal hash parameters
internal Blake2sDigest(int digestBytes, int hashLength, long offset)
{
digestLength = digestBytes;
nodeOffset = offset;
fanout = 0;
depth = 0;
leafLength = hashLength;
innerHashLength = hashLength;
nodeDepth = 0;
Init(null, null, null);
}
// initialize the digest's parameters
private void Init(byte[] salt, byte[] personalization, byte[] key)
{
buffer = new byte[BLOCK_LENGTH_BYTES];
if (key != null && key.Length > 0)
{
keyLength = key.Length;
if (keyLength > 32)
throw new ArgumentException("Keys > 32 bytes are not supported");
this.key = new byte[keyLength];
Array.Copy(key, 0, this.key, 0, keyLength);
Array.Copy(key, 0, buffer, 0, keyLength);
bufferPos = BLOCK_LENGTH_BYTES; // zero padding
}
if (chainValue == null)
{
chainValue = new uint[8];
chainValue[0] = blake2s_IV[0]
^ (uint)(digestLength | (keyLength << 8) | ((fanout << 16) | (depth << 24)));
chainValue[1] = blake2s_IV[1] ^ (uint)leafLength;
int nofHi = (int)(nodeOffset >> 32);
int nofLo = (int)nodeOffset;
chainValue[2] = blake2s_IV[2] ^ (uint)nofLo;
chainValue[3] = blake2s_IV[3] ^ (uint)(nofHi | (nodeDepth << 16) | (innerHashLength << 24));
chainValue[4] = blake2s_IV[4];
chainValue[5] = blake2s_IV[5];
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);
chainValue[4] ^= Pack.LE_To_UInt32(salt, 0);
chainValue[5] ^= Pack.LE_To_UInt32(salt, 4);
}
chainValue[6] = blake2s_IV[6];
chainValue[7] = blake2s_IV[7];
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);
chainValue[6] ^= Pack.LE_To_UInt32(personalization, 0);
chainValue[7] ^= Pack.LE_To_UInt32(personalization, 4);
}
}
}
private void InitializeInternalState()
{
// initialize v:
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];// ^ f1 with f1 = 0
}
/**
* Update the message digest with a single byte.
*
* @param b the input byte to be entered.
*/
public void Update(byte b)
{
// process the buffer if full else add to buffer:
int remainingLength = BLOCK_LENGTH_BYTES - bufferPos;
if (remainingLength == 0)
{ // full buffer
t0 += BLOCK_LENGTH_BYTES;
if (t0 == 0)
{ // if message > 2^32
t1++;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
Compress(buffer);
#else
Compress(buffer, 0);
#endif
Array.Clear(buffer, 0, buffer.Length);// clear buffer
buffer[0] = b;
bufferPos = 1;
}
else
{
buffer[bufferPos] = b;
bufferPos++;
}
}
/**
* Update the message digest with a block of bytes.
*
* @param message the byte array containing the data.
* @param offset the offset into the byte array where the data starts.
* @param len the length of the data.
*/
public void BlockUpdate(byte[] message, int offset, int len)
{
if (message == null || len == 0)
return;
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
BlockUpdate(message.AsSpan(offset, len));
#else
int remainingLength = 0; // left bytes of buffer
if (bufferPos != 0)
{ // commenced, incomplete buffer
// complete the buffer:
remainingLength = BLOCK_LENGTH_BYTES - bufferPos;
if (remainingLength < len)
{ // full buffer + at least 1 byte
Array.Copy(message, offset, buffer, bufferPos, remainingLength);
t0 += BLOCK_LENGTH_BYTES;
if (t0 == 0)
{ // if message > 2^32
t1++;
}
Compress(buffer, 0);
bufferPos = 0;
Array.Clear(buffer, 0, buffer.Length);// clear buffer
}
else
{
Array.Copy(message, offset, buffer, bufferPos, len);
bufferPos += len;
return;
}
}
// process blocks except last block (also if last block is full)
int messagePos;
int blockWiseLastPos = offset + len - BLOCK_LENGTH_BYTES;
for (messagePos = offset + remainingLength;
messagePos < blockWiseLastPos;
messagePos += BLOCK_LENGTH_BYTES)
{ // block wise 64 bytes
// without buffer:
t0 += BLOCK_LENGTH_BYTES;
if (t0 == 0)
{
t1++;
}
Compress(message, messagePos);
}
// fill the buffer with left bytes, this might be a full block
Array.Copy(message, messagePos, buffer, 0, offset + len
- messagePos);
bufferPos += offset + len - messagePos;
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void BlockUpdate(ReadOnlySpan<byte> input)
{
if (input.IsEmpty)
return;
int remainingLength = 0; // left bytes of buffer
if (bufferPos != 0)
{ // commenced, incomplete buffer
// complete the buffer:
remainingLength = BLOCK_LENGTH_BYTES - bufferPos;
if (remainingLength < input.Length)
{ // full buffer + at least 1 byte
input[..remainingLength].CopyTo(buffer.AsSpan(bufferPos));
t0 += BLOCK_LENGTH_BYTES;
if (t0 == 0)
{ // if message > 2^32
t1++;
}
Compress(buffer);
bufferPos = 0;
Array.Clear(buffer, 0, buffer.Length);// clear buffer
}
else
{
input.CopyTo(buffer.AsSpan(bufferPos));
bufferPos += input.Length;
return;
}
}
// process blocks except last block (also if last block is full)
int messagePos;
int blockWiseLastPos = input.Length - BLOCK_LENGTH_BYTES;
for (messagePos = remainingLength;
messagePos < blockWiseLastPos;
messagePos += BLOCK_LENGTH_BYTES)
{ // block wise 64 bytes
// without buffer:
t0 += BLOCK_LENGTH_BYTES;
if (t0 == 0)
{
t1++;
}
Compress(input[messagePos..]);
}
// fill the buffer with left bytes, this might be a full block
input[messagePos..].CopyTo(buffer.AsSpan());
bufferPos += input.Length - messagePos;
}
#endif
/**
* Close the digest, producing the final digest value. The doFinal() call
* leaves the digest reset. Key, salt and personal string remain.
*
* @param out the array the digest is to be copied into.
* @param outOffset the offset into the out array the digest is to start at.
*/
public int DoFinal(byte[] output, int outOffset)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
return DoFinal(output.AsSpan(outOffset));
#else
f0 = 0xFFFFFFFFU;
t0 += (uint)bufferPos;
// bufferPos may be < 64, so (t0 == 0) does not work
// for 2^32 < message length > 2^32 - 63
if ((t0 < 0) && (bufferPos > -t0))
{
t1++;
}
Compress(buffer, 0);
Array.Clear(buffer, 0, buffer.Length);// Holds eventually the key if input is null
Array.Clear(internalState, 0, internalState.Length);
int full = digestLength >> 2, partial = digestLength & 3;
Pack.UInt32_To_LE(chainValue, 0, full, output, outOffset);
if (partial > 0)
{
byte[] bytes = new byte[4];
Pack.UInt32_To_LE(chainValue[full], bytes, 0);
Array.Copy(bytes, 0, output, outOffset + digestLength - partial, partial);
}
Array.Clear(chainValue, 0, chainValue.Length);
Reset();
return digestLength;
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public int DoFinal(Span<byte> output)
{
f0 = 0xFFFFFFFFU;
t0 += (uint)bufferPos;
// bufferPos may be < 64, so (t0 == 0) does not work
// for 2^32 < message length > 2^32 - 63
if ((t0 < 0) && (bufferPos > -t0))
{
t1++;
}
Compress(buffer);
Array.Clear(buffer, 0, buffer.Length);// Holds eventually the key if input is null
Array.Clear(internalState, 0, internalState.Length);
int full = digestLength >> 2, partial = digestLength & 3;
Pack.UInt32_To_LE(chainValue.AsSpan(0, full), output);
if (partial > 0)
{
Span<byte> bytes = stackalloc byte[4];
Pack.UInt32_To_LE(chainValue[full], bytes);
bytes[..partial].CopyTo(output[(digestLength - partial)..]);
}
Array.Clear(chainValue, 0, chainValue.Length);
Reset();
return digestLength;
}
#endif
/**
* Reset the digest back to its initial state. The key, the salt and the
* personal string will remain for further computations.
*/
public void Reset()
{
bufferPos = 0;
f0 = 0;
t0 = 0;
t1 = 0;
chainValue = null;
Array.Clear(buffer, 0, buffer.Length);
if (key != null)
{
Array.Copy(key, 0, buffer, 0, key.Length);
bufferPos = BLOCK_LENGTH_BYTES; // zero padding
}
Init(this.salt, this.personalization, this.key);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private void Compress(ReadOnlySpan<byte> message)
{
InitializeInternalState();
Span<uint> m = stackalloc uint[16];
Pack.LE_To_UInt32(message, m);
for (int round = 0; round < ROUNDS; round++)
{
// G apply to columns of internalState: m[blake2s_sigma[round][2 * blockPos]] /+1
G(m[blake2s_sigma[round, 0]], m[blake2s_sigma[round, 1]], 0, 4, 8, 12);
G(m[blake2s_sigma[round, 2]], m[blake2s_sigma[round, 3]], 1, 5, 9, 13);
G(m[blake2s_sigma[round, 4]], m[blake2s_sigma[round, 5]], 2, 6, 10, 14);
G(m[blake2s_sigma[round, 6]], m[blake2s_sigma[round, 7]], 3, 7, 11, 15);
// G apply to diagonals of internalState:
G(m[blake2s_sigma[round, 8]], m[blake2s_sigma[round, 9]], 0, 5, 10, 15);
G(m[blake2s_sigma[round, 10]], m[blake2s_sigma[round, 11]], 1, 6, 11, 12);
G(m[blake2s_sigma[round, 12]], m[blake2s_sigma[round, 13]], 2, 7, 8, 13);
G(m[blake2s_sigma[round, 14]], m[blake2s_sigma[round, 15]], 3, 4, 9, 14);
}
// update chain values:
for (int offset = 0; offset < chainValue.Length; offset++)
{
chainValue[offset] = chainValue[offset] ^ internalState[offset] ^ internalState[offset + 8];
}
}
#else
private void Compress(byte[] message, int messagePos)
{
InitializeInternalState();
uint[] m = new uint[16];
Pack.LE_To_UInt32(message, messagePos, m);
for (int round = 0; round < ROUNDS; round++)
{
// G apply to columns of internalState: m[blake2s_sigma[round][2 * blockPos]] /+1
G(m[blake2s_sigma[round,0]], m[blake2s_sigma[round,1]], 0, 4, 8, 12);
G(m[blake2s_sigma[round,2]], m[blake2s_sigma[round,3]], 1, 5, 9, 13);
G(m[blake2s_sigma[round,4]], m[blake2s_sigma[round,5]], 2, 6, 10, 14);
G(m[blake2s_sigma[round,6]], m[blake2s_sigma[round,7]], 3, 7, 11, 15);
// G apply to diagonals of internalState:
G(m[blake2s_sigma[round,8]], m[blake2s_sigma[round,9]], 0, 5, 10, 15);
G(m[blake2s_sigma[round,10]], m[blake2s_sigma[round,11]], 1, 6, 11, 12);
G(m[blake2s_sigma[round,12]], m[blake2s_sigma[round,13]], 2, 7, 8, 13);
G(m[blake2s_sigma[round,14]], m[blake2s_sigma[round,15]], 3, 4, 9, 14);
}
// update chain values:
for (int offset = 0; offset < chainValue.Length; offset++)
{
chainValue[offset] = chainValue[offset] ^ internalState[offset] ^ internalState[offset + 8];
}
}
#endif
#if NETSTANDARD1_0_OR_GREATER || NETCOREAPP1_0_OR_GREATER || UNITY_2021_2_OR_NEWER
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
private void G(uint m1, uint m2, int posA, int posB, int posC, int posD)
{
internalState[posA] = internalState[posA] + internalState[posB] + m1;
internalState[posD] = Integers.RotateRight(internalState[posD] ^ internalState[posA], 16);
internalState[posC] = internalState[posC] + internalState[posD];
internalState[posB] = Integers.RotateRight(internalState[posB] ^ internalState[posC], 12);
internalState[posA] = internalState[posA] + internalState[posB] + m2;
internalState[posD] = Integers.RotateRight(internalState[posD] ^ internalState[posA], 8);
internalState[posC] = internalState[posC] + internalState[posD];
internalState[posB] = Integers.RotateRight(internalState[posB] ^ internalState[posC], 7);
}
/**
* Return the algorithm name.
*
* @return the algorithm name
*/
public string AlgorithmName => "BLAKE2s";
/**
* Return the size in bytes of the digest produced by this message digest.
*
* @return the size in bytes of the digest produced by this message digest.
*/
public int GetDigestSize()
{
return digestLength;
}
/**
* Return the size in bytes of the internal buffer the digest applies its
* compression function to.
*
* @return byte length of the digest's internal buffer.
*/
public int GetByteLength()
{
return BLOCK_LENGTH_BYTES;
}
/**
* Overwrite the key if it is no longer used (zeroization).
*/
public void ClearKey()
{
if (key != null)
{
Array.Clear(key, 0, key.Length);
Array.Clear(buffer, 0, buffer.Length);
}
}
/**
* Overwrite the salt (pepper) if it is secret and no longer used
* (zeroization).
*/
public void ClearSalt()
{
if (salt != null)
{
Array.Clear(salt, 0, salt.Length);
}
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f38dc128cef64e749839553cc8b9473b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,372 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/*
The BLAKE2 cryptographic hash function was designed by Jean-
Philippe Aumasson, Samuel Neves, Zooko Wilcox-O'Hearn, and Christian
Winnerlein.
Reference Implementation and Description can be found at: https://blake2.net/blake2x.pdf
*/
/**
* Implementation of the eXtendable Output Function (XOF) BLAKE2xs.
* <p/>
* BLAKE2xs offers a built-in keying mechanism to be used directly
* for authentication ("Prefix-MAC") rather than a HMAC construction.
* <p/>
* BLAKE2xs offers a built-in support for a salt for randomized hashing
* and a personal string for defining a unique hash function for each application.
* <p/>
* BLAKE2xs is optimized for 32-bit platforms and produces digests of any size
* between 1 and 2^16-2 bytes. The length can also be unknown and then the maximum
* length will be 2^32 blocks of 32 bytes.
*/
public sealed class Blake2xsDigest
: IXof
{
/**
* Magic number to indicate an unknown length of digest
*/
public const int UnknownDigestLength = 65535;
private const int DigestLength = 32;
private const long MaxNumberBlocks = 1L << 32;
/**
* Expected digest length for the xof. It can be unknown.
*/
private int digestLength;
/**
* Root hash that will take the updates
*/
private Blake2sDigest hash;
/**
* Digest of the root hash
*/
private byte[] h0 = null;
/**
* Digest of each round of the XOF
*/
private byte[] buf = new byte[32];
/**
* Current position for a round
*/
private int bufPos = 32;
/**
* Overall position of the digest. It is useful when the length is known
* in advance to get last block length.
*/
private int digestPos = 0;
/**
* Keep track of the round number to detect the end of the digest after
* 2^32 blocks of 32 bytes.
*/
private long blockPos = 0;
/**
* Current node offset incremented by 1 every round.
*/
private long nodeOffset;
/**
* BLAKE2xs for hashing with unknown digest length
*/
public Blake2xsDigest()
: this(UnknownDigestLength)
{
}
/**
* BLAKE2xs for hashing
*
* @param digestBytes The desired digest length in bytes. Must be above 1 and less than 2^16-1
*/
public Blake2xsDigest(int digestBytes)
: this(digestBytes, null, null, null)
{
}
/**
* BLAKE2xs with key
*
* @param digestBytes The desired digest length in bytes. Must be above 1 and less than 2^16-1
* @param key A key up to 32 bytes or null
*/
public Blake2xsDigest(int digestBytes, byte[] key)
: this(digestBytes, key, null, null)
{
}
/**
* BLAKE2xs with key, salt and personalization
*
* @param digestBytes The desired digest length in bytes. Must be above 1 and less than 2^16-1
* @param key A key up to 32 bytes or null
* @param salt 8 bytes or null
* @param personalization 8 bytes or null
*/
public Blake2xsDigest(int digestBytes, byte[] key, byte[] salt, byte[] personalization)
{
if (digestBytes < 1 || digestBytes > UnknownDigestLength)
throw new ArgumentException("BLAKE2xs digest length must be between 1 and 2^16-1");
digestLength = digestBytes;
nodeOffset = ComputeNodeOffset();
hash = new Blake2sDigest(DigestLength, key, salt, personalization, nodeOffset);
}
public Blake2xsDigest(Blake2xsDigest digest)
{
digestLength = digest.digestLength;
hash = new Blake2sDigest(digest.hash);
h0 = Arrays.Clone(digest.h0);
buf = Arrays.Clone(digest.buf);
bufPos = digest.bufPos;
digestPos = digest.digestPos;
blockPos = digest.blockPos;
nodeOffset = digest.nodeOffset;
}
/**
* Return the algorithm name.
*
* @return the algorithm name
*/
public string AlgorithmName => "BLAKE2xs";
/**
* Return the size in bytes of the digest produced by this message digest.
*
* @return the size in bytes of the digest produced by this message digest.
*/
public int GetDigestSize() => digestLength;
/**
* Return the size in bytes of the internal buffer the digest applies its
* compression function to.
*
* @return byte length of the digest's internal buffer.
*/
public int GetByteLength() => hash.GetByteLength();
/**
* Return the maximum size in bytes the digest can produce when the length
* is unknown
*
* @return byte length of the largest digest with unknown length
*/
public long GetUnknownMaxLength()
{
return MaxNumberBlocks * DigestLength;
}
/**
* Update the message digest with a single byte.
*
* @param in the input byte to be entered.
*/
public void Update(byte b)
{
hash.Update(b);
}
/**
* Update the message digest with a block of bytes.
*
* @param in the byte array containing the data.
* @param inOff the offset into the byte array where the data starts.
* @param len the length of the data.
*/
public void BlockUpdate(byte[] input, int inOff, int inLen)
{
hash.BlockUpdate(input, inOff, inLen);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void BlockUpdate(ReadOnlySpan<byte> input)
{
hash.BlockUpdate(input);
}
#endif
/**
* Reset the digest back to its initial state. The key, the salt and the
* personal string will remain for further computations.
*/
public void Reset()
{
hash.Reset();
h0 = null;
bufPos = DigestLength;
digestPos = 0;
blockPos = 0;
nodeOffset = ComputeNodeOffset();
}
/**
* Close the digest, producing the final digest value. The doFinal() call
* leaves the digest reset. Key, salt and personal string remain.
*
* @param out the array the digest is to be copied into.
* @param outOffset the offset into the out array the digest is to start at.
*/
public int DoFinal(byte[] output, int outOff)
{
return OutputFinal(output, outOff, digestLength);
}
/**
* Close the digest, producing the final digest value. The doFinal() call
* leaves the digest reset. Key, salt, personal string remain.
*
* @param out output array to write the output bytes to.
* @param outOff offset to start writing the bytes at.
* @param outLen the number of output bytes requested.
*/
public int OutputFinal(byte[] output, int outOff, int outLen)
{
int ret = Output(output, outOff, outLen);
Reset();
return ret;
}
/**
* Start outputting the results of the final calculation for this digest. Unlike doFinal, this method
* will continue producing output until the Xof is explicitly reset, or signals otherwise.
*
* @param out output array to write the output bytes to.
* @param outOff offset to start writing the bytes at.
* @param outLen the number of output bytes requested.
* @return the number of bytes written
*/
public int Output(byte[] output, int outOff, int outLen)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
return Output(output.AsSpan(outOff, outLen));
#else
if (h0 == null)
{
h0 = new byte[hash.GetDigestSize()];
hash.DoFinal(h0, 0);
}
if (digestLength != UnknownDigestLength)
{
if (digestPos + outLen > digestLength)
throw new ArgumentException("Output length is above the digest length");
}
else if (blockPos << 5 >= GetUnknownMaxLength())
{
throw new ArgumentException("Maximum length is 2^32 blocks of 32 bytes");
}
for (int i = 0; i < outLen; i++)
{
if (bufPos >= DigestLength)
{
Blake2sDigest h = new Blake2sDigest(ComputeStepLength(), DigestLength, nodeOffset);
h.BlockUpdate(h0, 0, h0.Length);
Arrays.Fill(buf, 0);
h.DoFinal(buf, 0);
bufPos = 0;
nodeOffset++;
blockPos++;
}
output[outOff + i] = buf[bufPos];
bufPos++;
digestPos++;
}
return outLen;
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public int DoFinal(Span<byte> output)
{
return OutputFinal(output[..digestLength]);
}
public int OutputFinal(Span<byte> output)
{
int ret = Output(output);
Reset();
return ret;
}
public int Output(Span<byte> output)
{
int outLen = output.Length;
if (h0 == null)
{
h0 = new byte[hash.GetDigestSize()];
hash.DoFinal(h0);
}
if (digestLength != UnknownDigestLength)
{
if (digestPos + outLen > digestLength)
throw new ArgumentException("Output length is above the digest length");
}
else if (blockPos << 5 >= GetUnknownMaxLength())
{
throw new ArgumentException("Maximum length is 2^32 blocks of 32 bytes");
}
for (int i = 0; i < outLen; i++)
{
if (bufPos >= DigestLength)
{
Blake2sDigest h = new Blake2sDigest(ComputeStepLength(), DigestLength, nodeOffset);
h.BlockUpdate(h0);
Arrays.Fill(buf, 0);
h.DoFinal(buf);
bufPos = 0;
nodeOffset++;
blockPos++;
}
output[i] = buf[bufPos];
bufPos++;
digestPos++;
}
return outLen;
}
#endif
// get the next round length. If the length is unknown, the digest length is always the maximum.
private int ComputeStepLength()
{
if (digestLength == UnknownDigestLength)
return DigestLength;
return System.Math.Min(DigestLength, digestLength - digestPos);
}
private long ComputeNodeOffset()
{
return digestLength * 0x100000000L;
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f72a9edc1d4af6742be974d8134695bf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bee07850754eaa04fa2781d2d26032fc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,131 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/// <summary>
/// Customizable SHAKE function.
/// </summary>
public class CShakeDigest
: ShakeDigest
{
private static readonly byte[] padding = new byte[100];
private static byte[] EncodeString(byte[] str)
{
if (Arrays.IsNullOrEmpty(str))
{
return XofUtilities.LeftEncode(0L);
}
return Arrays.Concatenate(XofUtilities.LeftEncode(str.Length * 8L), str);
}
private readonly byte[] diff;
/// <summary>
/// Base constructor
/// </summary>
/// <param name="bitLength">bit length of the underlying SHAKE function, 128 or 256.</param>
/// <param name="N">the function name string, note this is reserved for use by NIST. Avoid using it if not required.</param>
/// <param name="S">the customization string - available for local use.</param>
public CShakeDigest(int bitLength, byte[] N, byte[] S)
: base(bitLength)
{
if ((N == null || N.Length == 0) && (S == null || S.Length == 0))
{
diff = null;
}
else
{
diff = Arrays.ConcatenateAll(XofUtilities.LeftEncode(rate / 8), EncodeString(N), EncodeString(S));
DiffPadAndAbsorb();
}
}
public CShakeDigest(CShakeDigest source)
: base(source)
{
this.diff = Arrays.Clone(source.diff);
}
// bytepad in SP 800-185
private void DiffPadAndAbsorb()
{
int blockSize = rate / 8;
Absorb(diff, 0, diff.Length);
int delta = diff.Length % blockSize;
// only add padding if needed
if (delta != 0)
{
int required = blockSize - delta;
while (required > padding.Length)
{
Absorb(padding, 0, padding.Length);
required -= padding.Length;
}
Absorb(padding, 0, required);
}
}
public override string AlgorithmName
{
get { return "CSHAKE" + fixedOutputLength; }
}
public override int Output(byte[] output, int outOff, int outLen)
{
if (diff == null)
{
return base.Output(output, outOff, outLen);
}
if (!squeezing)
{
AbsorbBits(0x00, 2);
}
Squeeze(output, outOff, ((long)outLen) << 3);
return outLen;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override int Output(Span<byte> output)
{
if (diff == null)
{
return base.Output(output);
}
if (!squeezing)
{
AbsorbBits(0x00, 2);
}
Squeeze(output);
return output.Length;
}
#endif
public override void Reset()
{
base.Reset();
if (diff != null)
{
DiffPadAndAbsorb();
}
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0988d25e484f83e4ab7c804e88f69c76
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,631 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/**
* implementation of Ukrainian DSTU 7564 hash function
*/
public class Dstu7564Digest
: IDigest, IMemoable
{
private const int NB_512 = 8; //Number of 8-byte words in state for <=256-bit hash code.
private const int NB_1024 = 16; //Number of 8-byte words in state for <=512-bit hash code.
private const int NR_512 = 10; //Number of rounds for 512-bit state.
private const int NR_1024 = 14; //Number of rounds for 1024-bit state.
private int hashSize;
private int blockSize;
private int columns;
private int rounds;
private ulong[] state;
private ulong[] tempState1;
private ulong[] tempState2;
// TODO Guard against 'inputBlocks' overflow (2^64 blocks)
private ulong inputBlocks;
private int bufOff;
private byte[] buf;
public Dstu7564Digest(Dstu7564Digest digest)
{
CopyIn(digest);
}
private void CopyIn(Dstu7564Digest digest)
{
this.hashSize = digest.hashSize;
this.blockSize = digest.blockSize;
this.rounds = digest.rounds;
if (columns > 0 && columns == digest.columns)
{
Array.Copy(digest.state, 0, state, 0, columns);
Array.Copy(digest.buf, 0, buf, 0, blockSize);
}
else
{
this.columns = digest.columns;
this.state = Arrays.Clone(digest.state);
this.tempState1 = new ulong[columns];
this.tempState2 = new ulong[columns];
this.buf = Arrays.Clone(digest.buf);
}
this.inputBlocks = digest.inputBlocks;
this.bufOff = digest.bufOff;
}
public Dstu7564Digest(int hashSizeBits)
{
if (hashSizeBits == 256 || hashSizeBits == 384 || hashSizeBits == 512)
{
this.hashSize = hashSizeBits / 8;
}
else
{
throw new ArgumentException("Hash size is not recommended. Use 256/384/512 instead");
}
if (hashSizeBits > 256)
{
this.columns = NB_1024;
this.rounds = NR_1024;
}
else
{
this.columns = NB_512;
this.rounds = NR_512;
}
this.blockSize = columns << 3;
this.state = new ulong[columns];
this.state[0] = (ulong)blockSize;
this.tempState1 = new ulong[columns];
this.tempState2 = new ulong[columns];
this.buf = new byte[blockSize];
}
public virtual string AlgorithmName
{
get { return "DSTU7564"; }
}
public virtual int GetDigestSize()
{
return hashSize;
}
public virtual int GetByteLength()
{
return blockSize;
}
public virtual void Update(byte input)
{
buf[bufOff++] = input;
if (bufOff == blockSize)
{
ProcessBlock(buf, 0);
bufOff = 0;
++inputBlocks;
}
}
public virtual void BlockUpdate(byte[] input, int inOff, int length)
{
while (bufOff != 0 && length > 0)
{
Update(input[inOff++]);
--length;
}
while (length >= blockSize)
{
ProcessBlock(input, inOff);
inOff += blockSize;
length -= blockSize;
++inputBlocks;
}
while (length > 0)
{
Update(input[inOff++]);
--length;
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual void BlockUpdate(ReadOnlySpan<byte> input)
{
while (bufOff != 0 && input.Length > 0)
{
Update(input[0]);
input = input[1..];
}
while (input.Length >= blockSize)
{
ProcessBlock(input);
input = input[blockSize..];
++inputBlocks;
}
while (input.Length > 0)
{
Update(input[0]);
input = input[1..];
}
}
#endif
public virtual int DoFinal(byte[] output, int outOff)
{
// Apply padding: terminator byte and 96-bit length field
{
int inputBytes = bufOff;
buf[bufOff++] = (byte)0x80;
int lenPos = blockSize - 12;
if (bufOff > lenPos)
{
while (bufOff < blockSize)
{
buf[bufOff++] = 0;
}
bufOff = 0;
ProcessBlock(buf, 0);
}
while (bufOff < lenPos)
{
buf[bufOff++] = 0;
}
ulong c = ((inputBlocks & 0xFFFFFFFFUL) * (ulong)blockSize + (uint)inputBytes) << 3;
Pack.UInt32_To_LE((uint)c, buf, bufOff);
bufOff += 4;
c >>= 32;
c += ((inputBlocks >> 32) * (ulong)blockSize) << 3;
Pack.UInt64_To_LE(c, buf, bufOff);
//bufOff += 8;
ProcessBlock(buf, 0);
}
{
Array.Copy(state, 0, tempState1, 0, columns);
P(tempState1);
for (int col = 0; col < columns; ++col)
{
state[col] ^= tempState1[col];
}
}
int neededColumns = hashSize / 8;
for (int col = columns - neededColumns; col < columns; ++col)
{
Pack.UInt64_To_LE(state[col], output, outOff);
outOff += 8;
}
Reset();
return hashSize;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual int DoFinal(Span<byte> output)
{
// Apply padding: terminator byte and 96-bit length field
{
int inputBytes = bufOff;
buf[bufOff++] = (byte)0x80;
int lenPos = blockSize - 12;
if (bufOff > lenPos)
{
while (bufOff < blockSize)
{
buf[bufOff++] = 0;
}
bufOff = 0;
ProcessBlock(buf, 0);
}
while (bufOff < lenPos)
{
buf[bufOff++] = 0;
}
ulong c = ((inputBlocks & 0xFFFFFFFFUL) * (ulong)blockSize + (uint)inputBytes) << 3;
Pack.UInt32_To_LE((uint)c, buf, bufOff);
bufOff += 4;
c >>= 32;
c += ((inputBlocks >> 32) * (ulong)blockSize) << 3;
Pack.UInt64_To_LE(c, buf, bufOff);
//bufOff += 8;
ProcessBlock(buf, 0);
}
{
Array.Copy(state, 0, tempState1, 0, columns);
P(tempState1);
for (int col = 0; col < columns; ++col)
{
state[col] ^= tempState1[col];
}
}
int neededColumns = hashSize / 8;
for (int col = columns - neededColumns; col < columns; ++col)
{
Pack.UInt64_To_LE(state[col], output);
output = output[8..];
}
Reset();
return hashSize;
}
#endif
public virtual void Reset()
{
Array.Clear(state, 0, state.Length);
state[0] = (ulong)blockSize;
inputBlocks = 0;
bufOff = 0;
}
protected virtual void ProcessBlock(byte[] input, int inOff)
{
int pos = inOff;
for (int col = 0; col < columns; ++col)
{
ulong word = Pack.LE_To_UInt64(input, pos);
pos += 8;
tempState1[col] = state[col] ^ word;
tempState2[col] = word;
}
P(tempState1);
Q(tempState2);
for (int col = 0; col < columns; ++col)
{
state[col] ^= tempState1[col] ^ tempState2[col];
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
protected virtual void ProcessBlock(ReadOnlySpan<byte> input)
{
for (int col = 0; col < columns; ++col)
{
ulong word = Pack.LE_To_UInt64(input);
input = input[8..];
tempState1[col] = state[col] ^ word;
tempState2[col] = word;
}
P(tempState1);
Q(tempState2);
for (int col = 0; col < columns; ++col)
{
state[col] ^= tempState1[col] ^ tempState2[col];
}
}
#endif
private void P(ulong[] s)
{
for (int round = 0; round < rounds; ++round)
{
ulong rc = (ulong)round;
/* AddRoundConstants */
for (int col = 0; col < columns; ++col)
{
s[col] ^= rc;
rc += 0x10L;
}
ShiftRows(s);
SubBytes(s);
MixColumns(s);
}
}
private void Q(ulong[] s)
{
for (int round = 0; round < rounds; ++round)
{
/* AddRoundConstantsQ */
ulong rc = ((ulong)(((columns - 1) << 4) ^ round) << 56) | 0x00F0F0F0F0F0F0F3UL;
for (int col = 0; col < columns; ++col)
{
s[col] += rc;
rc -= 0x1000000000000000L;
}
ShiftRows(s);
SubBytes(s);
MixColumns(s);
}
}
private static ulong MixColumn(ulong c)
{
//// Calculate column multiplied by powers of 'x'
//ulong x0 = c;
//ulong x1 = ((x0 & 0x7F7F7F7F7F7F7F7FUL) << 1) ^ (((x0 & 0x8080808080808080UL) >> 7) * 0x1DUL);
//ulong x2 = ((x1 & 0x7F7F7F7F7F7F7F7FUL) << 1) ^ (((x1 & 0x8080808080808080UL) >> 7) * 0x1DUL);
//ulong x3 = ((x2 & 0x7F7F7F7F7F7F7F7FUL) << 1) ^ (((x2 & 0x8080808080808080UL) >> 7) * 0x1DUL);
//// Calculate products with circulant matrix from (0x01, 0x01, 0x05, 0x01, 0x08, 0x06, 0x07, 0x04)
//ulong m0 = x0;
//ulong m1 = x0;
//ulong m2 = x0 ^ x2;
//ulong m3 = x0;
//ulong m4 = x3;
//ulong m5 = x1 ^ x2;
//ulong m6 = x0 ^ x1 ^ x2;
//ulong m7 = x2;
//// Assemble the rotated products
//return m0
// ^ Rotate(8, m1)
// ^ Rotate(16, m2)
// ^ Rotate(24, m3)
// ^ Rotate(32, m4)
// ^ Rotate(40, m5)
// ^ Rotate(48, m6)
// ^ Rotate(56, m7);
// Multiply elements by 'x'
ulong x1 = ((c & 0x7F7F7F7F7F7F7F7FUL) << 1) ^ (((c & 0x8080808080808080UL) >> 7) * 0x1DUL);
ulong u, v;
u = Rotate(8, c) ^ c;
u ^= Rotate(16, u);
u ^= Rotate(48, c);
v = u ^ c ^ x1;
// Multiply elements by 'x^2'
v = ((v & 0x3F3F3F3F3F3F3F3FUL) << 2) ^ (((v & 0x8080808080808080UL) >> 6) * 0x1DUL) ^ (((v & 0x4040404040404040UL) >> 6) * 0x1DUL);
return u ^ Rotate(32, v) ^ Rotate(40, x1) ^ Rotate(48, x1);
}
private void MixColumns(ulong[] s)
{
for (int col = 0; col < columns; ++col)
{
s[col] = MixColumn(s[col]);
}
}
private static ulong Rotate(int n, ulong x)
{
return (x >> n) | (x << -n);
}
private void ShiftRows(ulong[] s)
{
switch (columns)
{
case NB_512:
{
ulong c0 = s[0], c1 = s[1], c2 = s[2], c3 = s[3];
ulong c4 = s[4], c5 = s[5], c6 = s[6], c7 = s[7];
ulong d;
d = (c0 ^ c4) & 0xFFFFFFFF00000000UL; c0 ^= d; c4 ^= d;
d = (c1 ^ c5) & 0x00FFFFFFFF000000UL; c1 ^= d; c5 ^= d;
d = (c2 ^ c6) & 0x0000FFFFFFFF0000UL; c2 ^= d; c6 ^= d;
d = (c3 ^ c7) & 0x000000FFFFFFFF00UL; c3 ^= d; c7 ^= d;
d = (c0 ^ c2) & 0xFFFF0000FFFF0000UL; c0 ^= d; c2 ^= d;
d = (c1 ^ c3) & 0x00FFFF0000FFFF00UL; c1 ^= d; c3 ^= d;
d = (c4 ^ c6) & 0xFFFF0000FFFF0000UL; c4 ^= d; c6 ^= d;
d = (c5 ^ c7) & 0x00FFFF0000FFFF00UL; c5 ^= d; c7 ^= d;
d = (c0 ^ c1) & 0xFF00FF00FF00FF00UL; c0 ^= d; c1 ^= d;
d = (c2 ^ c3) & 0xFF00FF00FF00FF00UL; c2 ^= d; c3 ^= d;
d = (c4 ^ c5) & 0xFF00FF00FF00FF00UL; c4 ^= d; c5 ^= d;
d = (c6 ^ c7) & 0xFF00FF00FF00FF00UL; c6 ^= d; c7 ^= d;
s[0] = c0; s[1] = c1; s[2] = c2; s[3] = c3;
s[4] = c4; s[5] = c5; s[6] = c6; s[7] = c7;
break;
}
case NB_1024:
{
ulong c00 = s[0], c01 = s[1], c02 = s[2], c03 = s[3];
ulong c04 = s[4], c05 = s[5], c06 = s[6], c07 = s[7];
ulong c08 = s[8], c09 = s[9], c10 = s[10], c11 = s[11];
ulong c12 = s[12], c13 = s[13], c14 = s[14], c15 = s[15];
ulong d;
// NOTE: Row 7 is shifted by 11
d = (c00 ^ c08) & 0xFF00000000000000UL; c00 ^= d; c08 ^= d;
d = (c01 ^ c09) & 0xFF00000000000000UL; c01 ^= d; c09 ^= d;
d = (c02 ^ c10) & 0xFFFF000000000000UL; c02 ^= d; c10 ^= d;
d = (c03 ^ c11) & 0xFFFFFF0000000000UL; c03 ^= d; c11 ^= d;
d = (c04 ^ c12) & 0xFFFFFFFF00000000UL; c04 ^= d; c12 ^= d;
d = (c05 ^ c13) & 0x00FFFFFFFF000000UL; c05 ^= d; c13 ^= d;
d = (c06 ^ c14) & 0x00FFFFFFFFFF0000UL; c06 ^= d; c14 ^= d;
d = (c07 ^ c15) & 0x00FFFFFFFFFFFF00UL; c07 ^= d; c15 ^= d;
d = (c00 ^ c04) & 0x00FFFFFF00000000UL; c00 ^= d; c04 ^= d;
d = (c01 ^ c05) & 0xFFFFFFFFFF000000UL; c01 ^= d; c05 ^= d;
d = (c02 ^ c06) & 0xFF00FFFFFFFF0000UL; c02 ^= d; c06 ^= d;
d = (c03 ^ c07) & 0xFF0000FFFFFFFF00UL; c03 ^= d; c07 ^= d;
d = (c08 ^ c12) & 0x00FFFFFF00000000UL; c08 ^= d; c12 ^= d;
d = (c09 ^ c13) & 0xFFFFFFFFFF000000UL; c09 ^= d; c13 ^= d;
d = (c10 ^ c14) & 0xFF00FFFFFFFF0000UL; c10 ^= d; c14 ^= d;
d = (c11 ^ c15) & 0xFF0000FFFFFFFF00UL; c11 ^= d; c15 ^= d;
d = (c00 ^ c02) & 0xFFFF0000FFFF0000UL; c00 ^= d; c02 ^= d;
d = (c01 ^ c03) & 0x00FFFF0000FFFF00UL; c01 ^= d; c03 ^= d;
d = (c04 ^ c06) & 0xFFFF0000FFFF0000UL; c04 ^= d; c06 ^= d;
d = (c05 ^ c07) & 0x00FFFF0000FFFF00UL; c05 ^= d; c07 ^= d;
d = (c08 ^ c10) & 0xFFFF0000FFFF0000UL; c08 ^= d; c10 ^= d;
d = (c09 ^ c11) & 0x00FFFF0000FFFF00UL; c09 ^= d; c11 ^= d;
d = (c12 ^ c14) & 0xFFFF0000FFFF0000UL; c12 ^= d; c14 ^= d;
d = (c13 ^ c15) & 0x00FFFF0000FFFF00UL; c13 ^= d; c15 ^= d;
d = (c00 ^ c01) & 0xFF00FF00FF00FF00UL; c00 ^= d; c01 ^= d;
d = (c02 ^ c03) & 0xFF00FF00FF00FF00UL; c02 ^= d; c03 ^= d;
d = (c04 ^ c05) & 0xFF00FF00FF00FF00UL; c04 ^= d; c05 ^= d;
d = (c06 ^ c07) & 0xFF00FF00FF00FF00UL; c06 ^= d; c07 ^= d;
d = (c08 ^ c09) & 0xFF00FF00FF00FF00UL; c08 ^= d; c09 ^= d;
d = (c10 ^ c11) & 0xFF00FF00FF00FF00UL; c10 ^= d; c11 ^= d;
d = (c12 ^ c13) & 0xFF00FF00FF00FF00UL; c12 ^= d; c13 ^= d;
d = (c14 ^ c15) & 0xFF00FF00FF00FF00UL; c14 ^= d; c15 ^= d;
s[0] = c00; s[1] = c01; s[2] = c02; s[3] = c03;
s[4] = c04; s[5] = c05; s[6] = c06; s[7] = c07;
s[8] = c08; s[9] = c09; s[10] = c10; s[11] = c11;
s[12] = c12; s[13] = c13; s[14] = c14; s[15] = c15;
break;
}
default:
{
throw new InvalidOperationException("unsupported state size: only 512/1024 are allowed");
}
}
}
private void SubBytes(ulong[] s)
{
for (int i = 0; i < columns; ++i)
{
ulong u = s[i];
uint lo = (uint)u, hi = (uint)(u >> 32);
byte t0 = S0[lo & 0xFF];
byte t1 = S1[(lo >> 8) & 0xFF];
byte t2 = S2[(lo >> 16) & 0xFF];
byte t3 = S3[lo >> 24];
lo = (uint)t0 | ((uint)t1 << 8) | ((uint)t2 << 16) | ((uint)t3 << 24);
byte t4 = S0[hi & 0xFF];
byte t5 = S1[(hi >> 8) & 0xFF];
byte t6 = S2[(hi >> 16) & 0xFF];
byte t7 = S3[hi >> 24];
hi = (uint)t4 | ((uint)t5 << 8) | ((uint)t6 << 16) | ((uint)t7 << 24);
s[i] = (ulong)lo | ((ulong)hi << 32);
}
}
private static readonly byte[] S0 = new byte[] {
0xa8, 0x43, 0x5f, 0x06, 0x6b, 0x75, 0x6c, 0x59, 0x71, 0xdf, 0x87, 0x95, 0x17, 0xf0, 0xd8, 0x09,
0x6d, 0xf3, 0x1d, 0xcb, 0xc9, 0x4d, 0x2c, 0xaf, 0x79, 0xe0, 0x97, 0xfd, 0x6f, 0x4b, 0x45, 0x39,
0x3e, 0xdd, 0xa3, 0x4f, 0xb4, 0xb6, 0x9a, 0x0e, 0x1f, 0xbf, 0x15, 0xe1, 0x49, 0xd2, 0x93, 0xc6,
0x92, 0x72, 0x9e, 0x61, 0xd1, 0x63, 0xfa, 0xee, 0xf4, 0x19, 0xd5, 0xad, 0x58, 0xa4, 0xbb, 0xa1,
0xdc, 0xf2, 0x83, 0x37, 0x42, 0xe4, 0x7a, 0x32, 0x9c, 0xcc, 0xab, 0x4a, 0x8f, 0x6e, 0x04, 0x27,
0x2e, 0xe7, 0xe2, 0x5a, 0x96, 0x16, 0x23, 0x2b, 0xc2, 0x65, 0x66, 0x0f, 0xbc, 0xa9, 0x47, 0x41,
0x34, 0x48, 0xfc, 0xb7, 0x6a, 0x88, 0xa5, 0x53, 0x86, 0xf9, 0x5b, 0xdb, 0x38, 0x7b, 0xc3, 0x1e,
0x22, 0x33, 0x24, 0x28, 0x36, 0xc7, 0xb2, 0x3b, 0x8e, 0x77, 0xba, 0xf5, 0x14, 0x9f, 0x08, 0x55,
0x9b, 0x4c, 0xfe, 0x60, 0x5c, 0xda, 0x18, 0x46, 0xcd, 0x7d, 0x21, 0xb0, 0x3f, 0x1b, 0x89, 0xff,
0xeb, 0x84, 0x69, 0x3a, 0x9d, 0xd7, 0xd3, 0x70, 0x67, 0x40, 0xb5, 0xde, 0x5d, 0x30, 0x91, 0xb1,
0x78, 0x11, 0x01, 0xe5, 0x00, 0x68, 0x98, 0xa0, 0xc5, 0x02, 0xa6, 0x74, 0x2d, 0x0b, 0xa2, 0x76,
0xb3, 0xbe, 0xce, 0xbd, 0xae, 0xe9, 0x8a, 0x31, 0x1c, 0xec, 0xf1, 0x99, 0x94, 0xaa, 0xf6, 0x26,
0x2f, 0xef, 0xe8, 0x8c, 0x35, 0x03, 0xd4, 0x7f, 0xfb, 0x05, 0xc1, 0x5e, 0x90, 0x20, 0x3d, 0x82,
0xf7, 0xea, 0x0a, 0x0d, 0x7e, 0xf8, 0x50, 0x1a, 0xc4, 0x07, 0x57, 0xb8, 0x3c, 0x62, 0xe3, 0xc8,
0xac, 0x52, 0x64, 0x10, 0xd0, 0xd9, 0x13, 0x0c, 0x12, 0x29, 0x51, 0xb9, 0xcf, 0xd6, 0x73, 0x8d,
0x81, 0x54, 0xc0, 0xed, 0x4e, 0x44, 0xa7, 0x2a, 0x85, 0x25, 0xe6, 0xca, 0x7c, 0x8b, 0x56, 0x80
};
private static readonly byte[] S1 = new byte[] {
0xce, 0xbb, 0xeb, 0x92, 0xea, 0xcb, 0x13, 0xc1, 0xe9, 0x3a, 0xd6, 0xb2, 0xd2, 0x90, 0x17, 0xf8,
0x42, 0x15, 0x56, 0xb4, 0x65, 0x1c, 0x88, 0x43, 0xc5, 0x5c, 0x36, 0xba, 0xf5, 0x57, 0x67, 0x8d,
0x31, 0xf6, 0x64, 0x58, 0x9e, 0xf4, 0x22, 0xaa, 0x75, 0x0f, 0x02, 0xb1, 0xdf, 0x6d, 0x73, 0x4d,
0x7c, 0x26, 0x2e, 0xf7, 0x08, 0x5d, 0x44, 0x3e, 0x9f, 0x14, 0xc8, 0xae, 0x54, 0x10, 0xd8, 0xbc,
0x1a, 0x6b, 0x69, 0xf3, 0xbd, 0x33, 0xab, 0xfa, 0xd1, 0x9b, 0x68, 0x4e, 0x16, 0x95, 0x91, 0xee,
0x4c, 0x63, 0x8e, 0x5b, 0xcc, 0x3c, 0x19, 0xa1, 0x81, 0x49, 0x7b, 0xd9, 0x6f, 0x37, 0x60, 0xca,
0xe7, 0x2b, 0x48, 0xfd, 0x96, 0x45, 0xfc, 0x41, 0x12, 0x0d, 0x79, 0xe5, 0x89, 0x8c, 0xe3, 0x20,
0x30, 0xdc, 0xb7, 0x6c, 0x4a, 0xb5, 0x3f, 0x97, 0xd4, 0x62, 0x2d, 0x06, 0xa4, 0xa5, 0x83, 0x5f,
0x2a, 0xda, 0xc9, 0x00, 0x7e, 0xa2, 0x55, 0xbf, 0x11, 0xd5, 0x9c, 0xcf, 0x0e, 0x0a, 0x3d, 0x51,
0x7d, 0x93, 0x1b, 0xfe, 0xc4, 0x47, 0x09, 0x86, 0x0b, 0x8f, 0x9d, 0x6a, 0x07, 0xb9, 0xb0, 0x98,
0x18, 0x32, 0x71, 0x4b, 0xef, 0x3b, 0x70, 0xa0, 0xe4, 0x40, 0xff, 0xc3, 0xa9, 0xe6, 0x78, 0xf9,
0x8b, 0x46, 0x80, 0x1e, 0x38, 0xe1, 0xb8, 0xa8, 0xe0, 0x0c, 0x23, 0x76, 0x1d, 0x25, 0x24, 0x05,
0xf1, 0x6e, 0x94, 0x28, 0x9a, 0x84, 0xe8, 0xa3, 0x4f, 0x77, 0xd3, 0x85, 0xe2, 0x52, 0xf2, 0x82,
0x50, 0x7a, 0x2f, 0x74, 0x53, 0xb3, 0x61, 0xaf, 0x39, 0x35, 0xde, 0xcd, 0x1f, 0x99, 0xac, 0xad,
0x72, 0x2c, 0xdd, 0xd0, 0x87, 0xbe, 0x5e, 0xa6, 0xec, 0x04, 0xc6, 0x03, 0x34, 0xfb, 0xdb, 0x59,
0xb6, 0xc2, 0x01, 0xf0, 0x5a, 0xed, 0xa7, 0x66, 0x21, 0x7f, 0x8a, 0x27, 0xc7, 0xc0, 0x29, 0xd7
};
private static readonly byte[] S2 = new byte[] {
0x93, 0xd9, 0x9a, 0xb5, 0x98, 0x22, 0x45, 0xfc, 0xba, 0x6a, 0xdf, 0x02, 0x9f, 0xdc, 0x51, 0x59,
0x4a, 0x17, 0x2b, 0xc2, 0x94, 0xf4, 0xbb, 0xa3, 0x62, 0xe4, 0x71, 0xd4, 0xcd, 0x70, 0x16, 0xe1,
0x49, 0x3c, 0xc0, 0xd8, 0x5c, 0x9b, 0xad, 0x85, 0x53, 0xa1, 0x7a, 0xc8, 0x2d, 0xe0, 0xd1, 0x72,
0xa6, 0x2c, 0xc4, 0xe3, 0x76, 0x78, 0xb7, 0xb4, 0x09, 0x3b, 0x0e, 0x41, 0x4c, 0xde, 0xb2, 0x90,
0x25, 0xa5, 0xd7, 0x03, 0x11, 0x00, 0xc3, 0x2e, 0x92, 0xef, 0x4e, 0x12, 0x9d, 0x7d, 0xcb, 0x35,
0x10, 0xd5, 0x4f, 0x9e, 0x4d, 0xa9, 0x55, 0xc6, 0xd0, 0x7b, 0x18, 0x97, 0xd3, 0x36, 0xe6, 0x48,
0x56, 0x81, 0x8f, 0x77, 0xcc, 0x9c, 0xb9, 0xe2, 0xac, 0xb8, 0x2f, 0x15, 0xa4, 0x7c, 0xda, 0x38,
0x1e, 0x0b, 0x05, 0xd6, 0x14, 0x6e, 0x6c, 0x7e, 0x66, 0xfd, 0xb1, 0xe5, 0x60, 0xaf, 0x5e, 0x33,
0x87, 0xc9, 0xf0, 0x5d, 0x6d, 0x3f, 0x88, 0x8d, 0xc7, 0xf7, 0x1d, 0xe9, 0xec, 0xed, 0x80, 0x29,
0x27, 0xcf, 0x99, 0xa8, 0x50, 0x0f, 0x37, 0x24, 0x28, 0x30, 0x95, 0xd2, 0x3e, 0x5b, 0x40, 0x83,
0xb3, 0x69, 0x57, 0x1f, 0x07, 0x1c, 0x8a, 0xbc, 0x20, 0xeb, 0xce, 0x8e, 0xab, 0xee, 0x31, 0xa2,
0x73, 0xf9, 0xca, 0x3a, 0x1a, 0xfb, 0x0d, 0xc1, 0xfe, 0xfa, 0xf2, 0x6f, 0xbd, 0x96, 0xdd, 0x43,
0x52, 0xb6, 0x08, 0xf3, 0xae, 0xbe, 0x19, 0x89, 0x32, 0x26, 0xb0, 0xea, 0x4b, 0x64, 0x84, 0x82,
0x6b, 0xf5, 0x79, 0xbf, 0x01, 0x5f, 0x75, 0x63, 0x1b, 0x23, 0x3d, 0x68, 0x2a, 0x65, 0xe8, 0x91,
0xf6, 0xff, 0x13, 0x58, 0xf1, 0x47, 0x0a, 0x7f, 0xc5, 0xa7, 0xe7, 0x61, 0x5a, 0x06, 0x46, 0x44,
0x42, 0x04, 0xa0, 0xdb, 0x39, 0x86, 0x54, 0xaa, 0x8c, 0x34, 0x21, 0x8b, 0xf8, 0x0c, 0x74, 0x67
};
private static readonly byte[] S3 = new byte[] {
0x68, 0x8d, 0xca, 0x4d, 0x73, 0x4b, 0x4e, 0x2a, 0xd4, 0x52, 0x26, 0xb3, 0x54, 0x1e, 0x19, 0x1f,
0x22, 0x03, 0x46, 0x3d, 0x2d, 0x4a, 0x53, 0x83, 0x13, 0x8a, 0xb7, 0xd5, 0x25, 0x79, 0xf5, 0xbd,
0x58, 0x2f, 0x0d, 0x02, 0xed, 0x51, 0x9e, 0x11, 0xf2, 0x3e, 0x55, 0x5e, 0xd1, 0x16, 0x3c, 0x66,
0x70, 0x5d, 0xf3, 0x45, 0x40, 0xcc, 0xe8, 0x94, 0x56, 0x08, 0xce, 0x1a, 0x3a, 0xd2, 0xe1, 0xdf,
0xb5, 0x38, 0x6e, 0x0e, 0xe5, 0xf4, 0xf9, 0x86, 0xe9, 0x4f, 0xd6, 0x85, 0x23, 0xcf, 0x32, 0x99,
0x31, 0x14, 0xae, 0xee, 0xc8, 0x48, 0xd3, 0x30, 0xa1, 0x92, 0x41, 0xb1, 0x18, 0xc4, 0x2c, 0x71,
0x72, 0x44, 0x15, 0xfd, 0x37, 0xbe, 0x5f, 0xaa, 0x9b, 0x88, 0xd8, 0xab, 0x89, 0x9c, 0xfa, 0x60,
0xea, 0xbc, 0x62, 0x0c, 0x24, 0xa6, 0xa8, 0xec, 0x67, 0x20, 0xdb, 0x7c, 0x28, 0xdd, 0xac, 0x5b,
0x34, 0x7e, 0x10, 0xf1, 0x7b, 0x8f, 0x63, 0xa0, 0x05, 0x9a, 0x43, 0x77, 0x21, 0xbf, 0x27, 0x09,
0xc3, 0x9f, 0xb6, 0xd7, 0x29, 0xc2, 0xeb, 0xc0, 0xa4, 0x8b, 0x8c, 0x1d, 0xfb, 0xff, 0xc1, 0xb2,
0x97, 0x2e, 0xf8, 0x65, 0xf6, 0x75, 0x07, 0x04, 0x49, 0x33, 0xe4, 0xd9, 0xb9, 0xd0, 0x42, 0xc7,
0x6c, 0x90, 0x00, 0x8e, 0x6f, 0x50, 0x01, 0xc5, 0xda, 0x47, 0x3f, 0xcd, 0x69, 0xa2, 0xe2, 0x7a,
0xa7, 0xc6, 0x93, 0x0f, 0x0a, 0x06, 0xe6, 0x2b, 0x96, 0xa3, 0x1c, 0xaf, 0x6a, 0x12, 0x84, 0x39,
0xe7, 0xb0, 0x82, 0xf7, 0xfe, 0x9d, 0x87, 0x5c, 0x81, 0x35, 0xde, 0xb4, 0xa5, 0xfc, 0x80, 0xef,
0xcb, 0xbb, 0x6b, 0x76, 0xba, 0x5a, 0x7d, 0x78, 0x0b, 0x95, 0xe3, 0xad, 0x74, 0x98, 0x3b, 0x36,
0x64, 0x6d, 0xdc, 0xf0, 0x59, 0xa9, 0x4c, 0x17, 0x7f, 0x91, 0xb8, 0xc9, 0x57, 0x1b, 0xe0, 0x61
};
public virtual IMemoable Copy()
{
return new Dstu7564Digest(this);
}
public virtual void Reset(IMemoable other)
{
Dstu7564Digest d = (Dstu7564Digest)other;
CopyIn(d);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a03b01a2336c00343a34238ac76aff2c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,396 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/**
* implementation of GOST R 34.11-94
*/
public class Gost3411Digest
: IDigest, IMemoable
{
private const int DIGEST_LENGTH = 32;
private byte[] H = new byte[32], L = new byte[32],
M = new byte[32], Sum = new byte[32];
private byte[][] C = MakeC();
private byte[] xBuf = new byte[32];
private int xBufOff;
private ulong byteCount;
private readonly IBlockCipher cipher = new Gost28147Engine();
private byte[] sBox;
private static byte[][] MakeC()
{
byte[][] c = new byte[4][];
for (int i = 0; i < 4; ++i)
{
c[i] = new byte[32];
}
return c;
}
/**
* Standard constructor
*/
public Gost3411Digest()
{
sBox = Gost28147Engine.GetSBox("D-A");
cipher.Init(true, new ParametersWithSBox(null, sBox));
Reset();
}
/**
* Constructor to allow use of a particular sbox with GOST28147
* @see GOST28147Engine#getSBox(String)
*/
public Gost3411Digest(byte[] sBoxParam)
{
sBox = Arrays.Clone(sBoxParam);
cipher.Init(true, new ParametersWithSBox(null, sBox));
Reset();
}
/**
* Copy constructor. This will copy the state of the provided
* message digest.
*/
public Gost3411Digest(Gost3411Digest t)
{
Reset(t);
}
public string AlgorithmName
{
get { return "Gost3411"; }
}
public int GetDigestSize()
{
return DIGEST_LENGTH;
}
public void Update(
byte input)
{
xBuf[xBufOff++] = input;
if (xBufOff == xBuf.Length)
{
sumByteArray(xBuf); // calc sum M
processBlock(xBuf, 0);
xBufOff = 0;
}
byteCount++;
}
public void BlockUpdate(byte[] input, int inOff, int length)
{
while ((xBufOff != 0) && (length > 0))
{
Update(input[inOff]);
inOff++;
length--;
}
while (length >= xBuf.Length)
{
Array.Copy(input, inOff, xBuf, 0, xBuf.Length);
sumByteArray(xBuf); // calc sum M
processBlock(xBuf, 0);
inOff += xBuf.Length;
length -= xBuf.Length;
byteCount += (uint)xBuf.Length;
}
// load in the remainder.
while (length > 0)
{
Update(input[inOff]);
inOff++;
length--;
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void BlockUpdate(ReadOnlySpan<byte> input)
{
while ((xBufOff != 0) && (input.Length > 0))
{
Update(input[0]);
input = input[1..];
}
while (input.Length >= xBuf.Length)
{
input[..xBuf.Length].CopyTo(xBuf.AsSpan());
sumByteArray(xBuf); // calc sum M
processBlock(xBuf, 0);
input = input[xBuf.Length..];
byteCount += (uint)xBuf.Length;
}
// load in the remainder.
while (input.Length > 0)
{
Update(input[0]);
input = input[1..];
}
}
#endif
// (i + 1 + 4(k - 1)) = 8i + k i = 0-3, k = 1-8
private byte[] K = new byte[32];
private byte[] P(byte[] input)
{
int fourK = 0;
for(int k = 0; k < 8; k++)
{
K[fourK++] = input[k];
K[fourK++] = input[8 + k];
K[fourK++] = input[16 + k];
K[fourK++] = input[24 + k];
}
return K;
}
//A (x) = (x0 ^ x1) || x3 || x2 || x1
byte[] a = new byte[8];
private byte[] A(byte[] input)
{
for(int j=0; j<8; j++)
{
a[j]=(byte)(input[j] ^ input[j+8]);
}
Array.Copy(input, 8, input, 0, 24);
Array.Copy(a, 0, input, 24, 8);
return input;
}
//Encrypt function, ECB mode
private void E(byte[] key, byte[] s, int sOff, byte[] input, int inOff)
{
cipher.Init(true, new KeyParameter(key));
cipher.ProcessBlock(input, inOff, s, sOff);
}
// (in:) n16||..||n1 ==> (out:) n1^n2^n3^n4^n13^n16||n16||..||n2
internal short[] wS = new short[16], w_S = new short[16];
private void fw(byte[] input)
{
cpyBytesToShort(input, wS);
w_S[15] = (short)(wS[0] ^ wS[1] ^ wS[2] ^ wS[3] ^ wS[12] ^ wS[15]);
Array.Copy(wS, 1, w_S, 0, 15);
cpyShortToBytes(w_S, input);
}
// block processing
internal byte[] S = new byte[32], U = new byte[32], V = new byte[32], W = new byte[32];
private void processBlock(byte[] input, int inOff)
{
Array.Copy(input, inOff, M, 0, 32);
//key step 1
// H = h3 || h2 || h1 || h0
// S = s3 || s2 || s1 || s0
H.CopyTo(U, 0);
M.CopyTo(V, 0);
for (int j=0; j<32; j++)
{
W[j] = (byte)(U[j]^V[j]);
}
// Encrypt gost28147-ECB
E(P(W), S, 0, H, 0); // s0 = EK0 [h0]
//keys step 2,3,4
for (int i=1; i<4; i++)
{
byte[] tmpA = A(U);
for (int j=0; j<32; j++)
{
U[j] = (byte)(tmpA[j] ^ C[i][j]);
}
V = A(A(V));
for (int j=0; j<32; j++)
{
W[j] = (byte)(U[j]^V[j]);
}
// Encrypt gost28147-ECB
E(P(W), S, i * 8, H, i * 8); // si = EKi [hi]
}
// x(M, H) = y61(H^y(M^y12(S)))
for(int n = 0; n < 12; n++)
{
fw(S);
}
for(int n = 0; n < 32; n++)
{
S[n] = (byte)(S[n] ^ M[n]);
}
fw(S);
for(int n = 0; n < 32; n++)
{
S[n] = (byte)(H[n] ^ S[n]);
}
for(int n = 0; n < 61; n++)
{
fw(S);
}
Array.Copy(S, 0, H, 0, H.Length);
}
private void Finish()
{
ulong bitCount = byteCount * 8;
Pack.UInt64_To_LE(bitCount, L);
while (xBufOff != 0)
{
Update((byte)0);
}
processBlock(L, 0);
processBlock(Sum, 0);
}
public int DoFinal(byte[] output, int outOff)
{
Finish();
H.CopyTo(output, outOff);
Reset();
return DIGEST_LENGTH;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public int DoFinal(Span<byte> output)
{
Finish();
H.CopyTo(output);
Reset();
return DIGEST_LENGTH;
}
#endif
/**
* reset the chaining variables to the IV values.
*/
private static readonly byte[] C2 = {
0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,
(byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,(byte)0xFF,0x00,
0x00,(byte)0xFF,(byte)0xFF,0x00,(byte)0xFF,0x00,0x00,(byte)0xFF,
(byte)0xFF,0x00,0x00,0x00,(byte)0xFF,(byte)0xFF,0x00,(byte)0xFF
};
public void Reset()
{
byteCount = 0;
xBufOff = 0;
Array.Clear(H, 0, H.Length);
Array.Clear(L, 0, L.Length);
Array.Clear(M, 0, M.Length);
Array.Clear(C[1], 0, C[1].Length); // real index C = +1 because index array with 0.
Array.Clear(C[3], 0, C[3].Length);
Array.Clear(Sum, 0, Sum.Length);
Array.Clear(xBuf, 0, xBuf.Length);
C2.CopyTo(C[2], 0);
}
// 256 bitsblock modul -> (Sum + a mod (2^256))
private void sumByteArray(
byte[] input)
{
int carry = 0;
for (int i = 0; i != Sum.Length; i++)
{
int sum = (Sum[i] & 0xff) + (input[i] & 0xff) + carry;
Sum[i] = (byte)sum;
carry = sum >> 8;
}
}
private static void cpyBytesToShort(byte[] S, short[] wS)
{
for(int i = 0; i < S.Length / 2; i++)
{
wS[i] = (short)(((S[i*2+1]<<8)&0xFF00)|(S[i*2]&0xFF));
}
}
private static void cpyShortToBytes(short[] wS, byte[] S)
{
for(int i=0; i<S.Length/2; i++)
{
S[i*2 + 1] = (byte)(wS[i] >> 8);
S[i*2] = (byte)wS[i];
}
}
public int GetByteLength()
{
return 32;
}
public IMemoable Copy()
{
return new Gost3411Digest(this);
}
public void Reset(IMemoable other)
{
Gost3411Digest t = (Gost3411Digest)other;
this.sBox = t.sBox;
cipher.Init(true, new ParametersWithSBox(null, sBox));
Reset();
Array.Copy(t.H, 0, this.H, 0, t.H.Length);
Array.Copy(t.L, 0, this.L, 0, t.L.Length);
Array.Copy(t.M, 0, this.M, 0, t.M.Length);
Array.Copy(t.Sum, 0, this.Sum, 0, t.Sum.Length);
Array.Copy(t.C[1], 0, this.C[1], 0, t.C[1].Length);
Array.Copy(t.C[2], 0, this.C[2], 0, t.C[2].Length);
Array.Copy(t.C[3], 0, this.C[3], 0, t.C[3].Length);
Array.Copy(t.xBuf, 0, this.xBuf, 0, t.xBuf.Length);
this.xBufOff = t.xBufOff;
this.byteCount = t.byteCount;
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e5311e8ec7da50a49869272448d25a55
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 62002e4c2dd254b47978d794ba626c57
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,70 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
public class Gost3411_2012_256Digest : Gost3411_2012Digest
{
private readonly static byte[] IV = {
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
};
public override string AlgorithmName
{
get { return "GOST3411-2012-256"; }
}
public Gost3411_2012_256Digest() : base(IV)
{
}
public Gost3411_2012_256Digest(Gost3411_2012_256Digest other) : base(IV)
{
Reset(other);
}
public override int GetDigestSize()
{
return 32;
}
public override int DoFinal(byte[] output, int outOff)
{
byte[] result = new byte[64];
base.DoFinal(result, 0);
Array.Copy(result, 32, output, outOff, 32);
return 32;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override int DoFinal(Span<byte> output)
{
Span<byte> result = stackalloc byte[64];
base.DoFinal(result);
result[32..].CopyTo(output);
return 32;
}
#endif
public override IMemoable Copy()
{
return new Gost3411_2012_256Digest(this);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 165295a43c0dbb04cb991fcdb8bf4046
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,47 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
public class Gost3411_2012_512Digest:Gost3411_2012Digest
{
private readonly static byte[] IV = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
public override string AlgorithmName
{
get { return "GOST3411-2012-512"; }
}
public Gost3411_2012_512Digest():base(IV)
{
}
public Gost3411_2012_512Digest(Gost3411_2012_512Digest other) : base(IV)
{
Reset(other);
}
public override int GetDigestSize()
{
return 64;
}
public override IMemoable Copy()
{
return new Gost3411_2012_512Digest(this);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: aa737713c49092a45894db5f7cf32869
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,187 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/**
* base implementation of MD4 family style digest as outlined in
* "Handbook of Applied Cryptography", pages 344 - 347.
*/
public abstract class GeneralDigest
: IDigest, IMemoable
{
private const int BYTE_LENGTH = 64;
private byte[] xBuf;
private int xBufOff;
private long byteCount;
internal GeneralDigest()
{
xBuf = new byte[4];
}
internal GeneralDigest(GeneralDigest t)
{
xBuf = new byte[t.xBuf.Length];
CopyIn(t);
}
protected void CopyIn(GeneralDigest t)
{
Array.Copy(t.xBuf, 0, xBuf, 0, t.xBuf.Length);
xBufOff = t.xBufOff;
byteCount = t.byteCount;
}
public void Update(byte input)
{
xBuf[xBufOff++] = input;
if (xBufOff == xBuf.Length)
{
ProcessWord(xBuf, 0);
xBufOff = 0;
}
byteCount++;
}
public void BlockUpdate(
byte[] input,
int inOff,
int length)
{
length = System.Math.Max(0, length);
//
// fill the current word
//
int i = 0;
if (xBufOff != 0)
{
while (i < length)
{
xBuf[xBufOff++] = input[inOff + i++];
if (xBufOff == 4)
{
ProcessWord(xBuf, 0);
xBufOff = 0;
break;
}
}
}
//
// process whole words.
//
int limit = length - 3;
for (; i < limit; i += 4)
{
ProcessWord(input, inOff + i);
}
//
// load in the remainder.
//
while (i < length)
{
xBuf[xBufOff++] = input[inOff + i++];
}
byteCount += length;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void BlockUpdate(ReadOnlySpan<byte> input)
{
int length = input.Length;
//
// fill the current word
//
int i = 0;
if (xBufOff != 0)
{
while (i < length)
{
xBuf[xBufOff++] = input[i++];
if (xBufOff == 4)
{
ProcessWord(xBuf, 0);
xBufOff = 0;
break;
}
}
}
//
// process whole words.
//
int limit = length - 3;
for (; i < limit; i += 4)
{
ProcessWord(input.Slice(i, 4));
}
//
// load in the remainder.
//
while (i < length)
{
xBuf[xBufOff++] = input[i++];
}
byteCount += length;
}
#endif
public void Finish()
{
long bitLength = (byteCount << 3);
//
// add the pad bytes.
//
Update((byte)128);
while (xBufOff != 0) Update((byte)0);
ProcessLength(bitLength);
ProcessBlock();
}
public virtual void Reset()
{
byteCount = 0;
xBufOff = 0;
Array.Clear(xBuf, 0, xBuf.Length);
}
public int GetByteLength()
{
return BYTE_LENGTH;
}
internal abstract void ProcessWord(byte[] input, int inOff);
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
internal abstract void ProcessWord(ReadOnlySpan<byte> word);
#endif
internal abstract void ProcessLength(long bitLength);
internal abstract void ProcessBlock();
public abstract string AlgorithmName { get; }
public abstract int GetDigestSize();
public abstract int DoFinal(byte[] output, int outOff);
public abstract IMemoable Copy();
public abstract void Reset(IMemoable t);
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public abstract int DoFinal(Span<byte> output);
#endif
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3ff36403fe499a744a8b32d26de7b631
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,218 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
public sealed class Haraka256Digest
: HarakaBase
{
private readonly byte[] m_buf;
private int m_bufPos;
public Haraka256Digest()
{
m_buf = new byte[32];
m_bufPos = 0;
}
public override string AlgorithmName => "Haraka-256";
public override int GetByteLength() => 32;
public override void Update(byte input)
{
if (m_bufPos > 32 - 1)
throw new ArgumentException("total input cannot be more than 32 bytes");
m_buf[m_bufPos++] = input;
}
public override void BlockUpdate(byte[] input, int inOff, int len)
{
if (m_bufPos > 32 - len)
throw new ArgumentException("total input cannot be more than 32 bytes");
Array.Copy(input, inOff, m_buf, m_bufPos, len);
m_bufPos += len;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override void BlockUpdate(ReadOnlySpan<byte> input)
{
if (m_bufPos > 32 - input.Length)
throw new ArgumentException("total input cannot be more than 32 bytes");
input.CopyTo(m_buf.AsSpan(m_bufPos));
m_bufPos += input.Length;
}
#endif
public override int DoFinal(byte[] output, int outOff)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
return DoFinal(output.AsSpan(outOff));
#else
if (m_bufPos != 32)
throw new ArgumentException("input must be exactly 32 bytes");
if (output.Length - outOff < 32)
throw new ArgumentException("output too short to receive digest");
int rv = Haraka256256(m_buf, output, outOff);
Reset();
return rv;
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override int DoFinal(Span<byte> output)
{
if (m_bufPos != 32)
throw new ArgumentException("input must be exactly 32 bytes");
if (output.Length < 32)
throw new ArgumentException("output too short to receive digest");
#if NETCOREAPP3_0_OR_GREATER
if (Haraka256_X86.IsSupported)
{
Haraka256_X86.Hash(m_buf, output);
Reset();
return 32;
}
#endif
int rv = Haraka256256(m_buf, output);
Reset();
return rv;
}
#endif
public override void Reset()
{
m_bufPos = 0;
Array.Clear(m_buf, 0, 32);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private static int Haraka256256(ReadOnlySpan<byte> msg, Span<byte> output)
{
byte[][] s1 = new byte[2][];
s1[0] = new byte[16];
s1[1] = new byte[16];
byte[][] s2 = new byte[2][];
s2[0] = new byte[16];
s2[1] = new byte[16];
msg[ ..16].CopyTo(s1[0]);
msg[16..32].CopyTo(s1[1]);
s1[0] = AesEnc(s1[0], RC[0]);
s1[1] = AesEnc(s1[1], RC[1]);
s1[0] = AesEnc(s1[0], RC[2]);
s1[1] = AesEnc(s1[1], RC[3]);
Mix256(s1, s2);
s1[0] = AesEnc(s2[0], RC[4]);
s1[1] = AesEnc(s2[1], RC[5]);
s1[0] = AesEnc(s1[0], RC[6]);
s1[1] = AesEnc(s1[1], RC[7]);
Mix256(s1, s2);
s1[0] = AesEnc(s2[0], RC[8]);
s1[1] = AesEnc(s2[1], RC[9]);
s1[0] = AesEnc(s1[0], RC[10]);
s1[1] = AesEnc(s1[1], RC[11]);
Mix256(s1, s2);
s1[0] = AesEnc(s2[0], RC[12]);
s1[1] = AesEnc(s2[1], RC[13]);
s1[0] = AesEnc(s1[0], RC[14]);
s1[1] = AesEnc(s1[1], RC[15]);
Mix256(s1, s2);
s1[0] = AesEnc(s2[0], RC[16]);
s1[1] = AesEnc(s2[1], RC[17]);
s1[0] = AesEnc(s1[0], RC[18]);
s1[1] = AesEnc(s1[1], RC[19]);
Mix256(s1, s2);
Xor(s2[0], msg , output[ ..16]);
Xor(s2[1], msg[16..], output[16..32]);
return DIGEST_SIZE;
}
#else
private static int Haraka256256(byte[] msg, byte[] output, int outOff)
{
byte[][] s1 = new byte[2][];
s1[0] = new byte[16];
s1[1] = new byte[16];
byte[][] s2 = new byte[2][];
s2[0] = new byte[16];
s2[1] = new byte[16];
Array.Copy(msg, 0, s1[0], 0, 16);
Array.Copy(msg, 16, s1[1], 0, 16);
s1[0] = AesEnc(s1[0], RC[0]);
s1[1] = AesEnc(s1[1], RC[1]);
s1[0] = AesEnc(s1[0], RC[2]);
s1[1] = AesEnc(s1[1], RC[3]);
Mix256(s1, s2);
s1[0] = AesEnc(s2[0], RC[4]);
s1[1] = AesEnc(s2[1], RC[5]);
s1[0] = AesEnc(s1[0], RC[6]);
s1[1] = AesEnc(s1[1], RC[7]);
Mix256(s1, s2);
s1[0] = AesEnc(s2[0], RC[8]);
s1[1] = AesEnc(s2[1], RC[9]);
s1[0] = AesEnc(s1[0], RC[10]);
s1[1] = AesEnc(s1[1], RC[11]);
Mix256(s1, s2);
s1[0] = AesEnc(s2[0], RC[12]);
s1[1] = AesEnc(s2[1], RC[13]);
s1[0] = AesEnc(s1[0], RC[14]);
s1[1] = AesEnc(s1[1], RC[15]);
Mix256(s1, s2);
s1[0] = AesEnc(s2[0], RC[16]);
s1[1] = AesEnc(s2[1], RC[17]);
s1[0] = AesEnc(s1[0], RC[18]);
s1[1] = AesEnc(s1[1], RC[19]);
Mix256(s1, s2);
s1[0] = Xor(s2[0], msg, 0);
s1[1] = Xor(s2[1], msg, 16);
Array.Copy(s1[0], 0, output, outOff , 16);
Array.Copy(s1[1], 0, output, outOff + 16, 16);
return DIGEST_SIZE;
}
#endif
private static void Mix256(byte[][] s1, byte[][] s2)
{
Array.Copy(s1[0], 0, s2[0], 0, 4);
Array.Copy(s1[1], 0, s2[0], 4, 4);
Array.Copy(s1[0], 4, s2[0], 8, 4);
Array.Copy(s1[1], 4, s2[0], 12, 4);
Array.Copy(s1[0], 8, s2[1], 0, 4);
Array.Copy(s1[1], 8, s2[1], 4, 4);
Array.Copy(s1[0], 12, s2[1], 8, 4);
Array.Copy(s1[1], 12, s2[1], 12, 4);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7c5eb74b94701ee478cb64e34260ae39
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,148 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
#if NETCOREAPP3_0_OR_GREATER
using System;
using System.Buffers.Binary;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
using Aes = System.Runtime.Intrinsics.X86.Aes;
using Sse2 = System.Runtime.Intrinsics.X86.Sse2;
public static class Haraka256_X86
{
public static bool IsSupported => Aes.IsSupported;
public static void Hash(ReadOnlySpan<byte> input, Span<byte> output)
{
if (!IsSupported)
throw new PlatformNotSupportedException(nameof(Haraka256_X86));
var s0 = Load128(input[ ..16]);
var s1 = Load128(input[16..32]);
ImplRounds(ref s0, ref s1, Haraka512_X86.DefaultRoundConstants.AsSpan(0, 20));
s0 = Sse2.Xor(s0, Load128(input[ ..16]));
s1 = Sse2.Xor(s1, Load128(input[16..32]));
Store128(s0, output[ ..16]);
Store128(s1, output[16..32]);
}
public static void Hash(ReadOnlySpan<byte> input, Span<byte> output,
ReadOnlySpan<Vector128<byte>> roundConstants)
{
if (!IsSupported)
throw new PlatformNotSupportedException(nameof(Haraka256_X86));
var s0 = Load128(input[ ..16]);
var s1 = Load128(input[16..32]);
ImplRounds(ref s0, ref s1, roundConstants[..20]);
s0 = Sse2.Xor(s0, Load128(input[ ..16]));
s1 = Sse2.Xor(s1, Load128(input[16..32]));
Store128(s0, output[ ..16]);
Store128(s1, output[16..32]);
}
public static void Permute(ReadOnlySpan<byte> input, Span<byte> output)
{
if (!IsSupported)
throw new PlatformNotSupportedException(nameof(Haraka256_X86));
var s0 = Load128(input[ ..16]);
var s1 = Load128(input[16..32]);
ImplRounds(ref s0, ref s1, Haraka512_X86.DefaultRoundConstants.AsSpan(0, 20));
Store128(s0, output[ ..16]);
Store128(s1, output[16..32]);
}
public static void Permute(ReadOnlySpan<byte> input, Span<byte> output,
ReadOnlySpan<Vector128<byte>> roundConstants)
{
if (!IsSupported)
throw new PlatformNotSupportedException(nameof(Haraka256_X86));
var s0 = Load128(input[ ..16]);
var s1 = Load128(input[16..32]);
ImplRounds(ref s0, ref s1, roundConstants[..20]);
Store128(s0, output[ ..16]);
Store128(s1, output[16..32]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ImplRounds(ref Vector128<byte> s0, ref Vector128<byte> s1, ReadOnlySpan<Vector128<byte>> rc)
{
ImplRound(ref s0, ref s1, rc[ .. 4]);
ImplRound(ref s0, ref s1, rc[ 4.. 8]);
ImplRound(ref s0, ref s1, rc[ 8..12]);
ImplRound(ref s0, ref s1, rc[12..16]);
ImplRound(ref s0, ref s1, rc[16..20]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ImplRound(ref Vector128<byte> s0, ref Vector128<byte> s1, ReadOnlySpan<Vector128<byte>> rc)
{
ImplAes(ref s0, ref s1, rc[..4]);
ImplMix(ref s0, ref s1);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ImplAes(ref Vector128<byte> s0, ref Vector128<byte> s1, ReadOnlySpan<Vector128<byte>> rc)
{
s0 = Aes.Encrypt(s0, rc[0]);
s1 = Aes.Encrypt(s1, rc[1]);
s0 = Aes.Encrypt(s0, rc[2]);
s1 = Aes.Encrypt(s1, rc[3]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ImplMix(ref Vector128<byte> s0, ref Vector128<byte> s1)
{
Vector128<uint> t0 = s0.AsUInt32();
Vector128<uint> t1 = s1.AsUInt32();
s0 = Sse2.UnpackLow(t0, t1).AsByte();
s1 = Sse2.UnpackHigh(t0, t1).AsByte();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector128<byte> Load128(ReadOnlySpan<byte> t)
{
if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<byte>>() == 16)
return MemoryMarshal.Read<Vector128<byte>>(t);
return Vector128.Create(
BinaryPrimitives.ReadUInt64LittleEndian(t[..8]),
BinaryPrimitives.ReadUInt64LittleEndian(t[8..])
).AsByte();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Store128(Vector128<byte> s, Span<byte> t)
{
if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<byte>>() == 16)
{
MemoryMarshal.Write(t, ref s);
return;
}
var u = s.AsUInt64();
BinaryPrimitives.WriteUInt64LittleEndian(t[..8], u.GetElement(0));
BinaryPrimitives.WriteUInt64LittleEndian(t[8..], u.GetElement(1));
}
}
}
#endif
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ec8595086a6fa294190927f533980baf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,291 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
public sealed class Haraka512Digest
: HarakaBase
{
private readonly byte[] m_buf;
private int m_bufPos;
public Haraka512Digest()
{
m_buf = new byte[64];
m_bufPos = 0;
}
public override string AlgorithmName => "Haraka-512";
public override int GetByteLength() => 64;
public override void Update(byte input)
{
if (m_bufPos > 64 - 1)
throw new ArgumentException("total input cannot be more than 64 bytes");
m_buf[m_bufPos++] = input;
}
public override void BlockUpdate(byte[] input, int inOff, int len)
{
if (m_bufPos > 64 - len)
throw new ArgumentException("total input cannot be more than 64 bytes");
Array.Copy(input, inOff, m_buf, m_bufPos, len);
m_bufPos += len;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override void BlockUpdate(ReadOnlySpan<byte> input)
{
if (m_bufPos > 64 - input.Length)
throw new ArgumentException("total input cannot be more than 64 bytes");
input.CopyTo(m_buf.AsSpan(m_bufPos));
m_bufPos += input.Length;
}
#endif
public override int DoFinal(byte[] output, int outOff)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
return DoFinal(output.AsSpan(outOff));
#else
if (m_bufPos != 64)
throw new ArgumentException("input must be exactly 64 bytes");
if (output.Length - outOff < 32)
throw new ArgumentException("output too short to receive digest");
int rv = Haraka512256(m_buf, output, outOff);
Reset();
return rv;
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override int DoFinal(Span<byte> output)
{
if (m_bufPos != 64)
throw new ArgumentException("input must be exactly 64 bytes");
if (output.Length < 32)
throw new ArgumentException("output too short to receive digest");
#if NETCOREAPP3_0_OR_GREATER
if (Haraka512_X86.IsSupported)
{
Haraka512_X86.Hash(m_buf, output);
Reset();
return 32;
}
#endif
int rv = Haraka512256(m_buf, output);
Reset();
return rv;
}
#endif
public override void Reset()
{
m_bufPos = 0;
Array.Clear(m_buf, 0, 64);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private static int Haraka512256(ReadOnlySpan<byte> msg, Span<byte> output)
{
byte[][] s1 = new byte[4][];
s1[0] = new byte[16];
s1[1] = new byte[16];
s1[2] = new byte[16];
s1[3] = new byte[16];
byte[][] s2 = new byte[4][];
s2[0] = new byte[16];
s2[1] = new byte[16];
s2[2] = new byte[16];
s2[3] = new byte[16];
msg[ ..16].CopyTo(s1[0]);
msg[16..32].CopyTo(s1[1]);
msg[32..48].CopyTo(s1[2]);
msg[48..64].CopyTo(s1[3]);
s1[0] = AesEnc(s1[0], RC[0]);
s1[1] = AesEnc(s1[1], RC[1]);
s1[2] = AesEnc(s1[2], RC[2]);
s1[3] = AesEnc(s1[3], RC[3]);
s1[0] = AesEnc(s1[0], RC[4]);
s1[1] = AesEnc(s1[1], RC[5]);
s1[2] = AesEnc(s1[2], RC[6]);
s1[3] = AesEnc(s1[3], RC[7]);
Mix512(s1, s2);
s1[0] = AesEnc(s2[0], RC[8]);
s1[1] = AesEnc(s2[1], RC[9]);
s1[2] = AesEnc(s2[2], RC[10]);
s1[3] = AesEnc(s2[3], RC[11]);
s1[0] = AesEnc(s1[0], RC[12]);
s1[1] = AesEnc(s1[1], RC[13]);
s1[2] = AesEnc(s1[2], RC[14]);
s1[3] = AesEnc(s1[3], RC[15]);
Mix512(s1, s2);
s1[0] = AesEnc(s2[0], RC[16]);
s1[1] = AesEnc(s2[1], RC[17]);
s1[2] = AesEnc(s2[2], RC[18]);
s1[3] = AesEnc(s2[3], RC[19]);
s1[0] = AesEnc(s1[0], RC[20]);
s1[1] = AesEnc(s1[1], RC[21]);
s1[2] = AesEnc(s1[2], RC[22]);
s1[3] = AesEnc(s1[3], RC[23]);
Mix512(s1, s2);
s1[0] = AesEnc(s2[0], RC[24]);
s1[1] = AesEnc(s2[1], RC[25]);
s1[2] = AesEnc(s2[2], RC[26]);
s1[3] = AesEnc(s2[3], RC[27]);
s1[0] = AesEnc(s1[0], RC[28]);
s1[1] = AesEnc(s1[1], RC[29]);
s1[2] = AesEnc(s1[2], RC[30]);
s1[3] = AesEnc(s1[3], RC[31]);
Mix512(s1, s2);
s1[0] = AesEnc(s2[0], RC[32]);
s1[1] = AesEnc(s2[1], RC[33]);
s1[2] = AesEnc(s2[2], RC[34]);
s1[3] = AesEnc(s2[3], RC[35]);
s1[0] = AesEnc(s1[0], RC[36]);
s1[1] = AesEnc(s1[1], RC[37]);
s1[2] = AesEnc(s1[2], RC[38]);
s1[3] = AesEnc(s1[3], RC[39]);
Mix512(s1, s2);
Xor(s2[0], msg, s1[0]);
Xor(s2[1], msg[16..], s1[1]);
Xor(s2[2], msg[32..], s1[2]);
Xor(s2[3], msg[48..], s1[3]);
s1[0].AsSpan(8, 8).CopyTo(output);
s1[1].AsSpan(8, 8).CopyTo(output[8..]);
s1[2].AsSpan(0, 8).CopyTo(output[16..]);
s1[3].AsSpan(0, 8).CopyTo(output[24..]);
return DIGEST_SIZE;
}
#else
private static int Haraka512256(byte[] msg, byte[] output, int outOff)
{
byte[][] s1 = new byte[4][];
s1[0] = new byte[16];
s1[1] = new byte[16];
s1[2] = new byte[16];
s1[3] = new byte[16];
byte[][] s2 = new byte[4][];
s2[0] = new byte[16];
s2[1] = new byte[16];
s2[2] = new byte[16];
s2[3] = new byte[16];
Array.Copy(msg, 0, s1[0], 0, 16);
Array.Copy(msg, 16, s1[1], 0, 16);
Array.Copy(msg, 32, s1[2], 0, 16);
Array.Copy(msg, 48, s1[3], 0, 16);
s1[0] = AesEnc(s1[0], RC[0]);
s1[1] = AesEnc(s1[1], RC[1]);
s1[2] = AesEnc(s1[2], RC[2]);
s1[3] = AesEnc(s1[3], RC[3]);
s1[0] = AesEnc(s1[0], RC[4]);
s1[1] = AesEnc(s1[1], RC[5]);
s1[2] = AesEnc(s1[2], RC[6]);
s1[3] = AesEnc(s1[3], RC[7]);
Mix512(s1, s2);
s1[0] = AesEnc(s2[0], RC[8]);
s1[1] = AesEnc(s2[1], RC[9]);
s1[2] = AesEnc(s2[2], RC[10]);
s1[3] = AesEnc(s2[3], RC[11]);
s1[0] = AesEnc(s1[0], RC[12]);
s1[1] = AesEnc(s1[1], RC[13]);
s1[2] = AesEnc(s1[2], RC[14]);
s1[3] = AesEnc(s1[3], RC[15]);
Mix512(s1, s2);
s1[0] = AesEnc(s2[0], RC[16]);
s1[1] = AesEnc(s2[1], RC[17]);
s1[2] = AesEnc(s2[2], RC[18]);
s1[3] = AesEnc(s2[3], RC[19]);
s1[0] = AesEnc(s1[0], RC[20]);
s1[1] = AesEnc(s1[1], RC[21]);
s1[2] = AesEnc(s1[2], RC[22]);
s1[3] = AesEnc(s1[3], RC[23]);
Mix512(s1, s2);
s1[0] = AesEnc(s2[0], RC[24]);
s1[1] = AesEnc(s2[1], RC[25]);
s1[2] = AesEnc(s2[2], RC[26]);
s1[3] = AesEnc(s2[3], RC[27]);
s1[0] = AesEnc(s1[0], RC[28]);
s1[1] = AesEnc(s1[1], RC[29]);
s1[2] = AesEnc(s1[2], RC[30]);
s1[3] = AesEnc(s1[3], RC[31]);
Mix512(s1, s2);
s1[0] = AesEnc(s2[0], RC[32]);
s1[1] = AesEnc(s2[1], RC[33]);
s1[2] = AesEnc(s2[2], RC[34]);
s1[3] = AesEnc(s2[3], RC[35]);
s1[0] = AesEnc(s1[0], RC[36]);
s1[1] = AesEnc(s1[1], RC[37]);
s1[2] = AesEnc(s1[2], RC[38]);
s1[3] = AesEnc(s1[3], RC[39]);
Mix512(s1, s2);
s1[0] = Xor(s2[0], msg, 0);
s1[1] = Xor(s2[1], msg, 16);
s1[2] = Xor(s2[2], msg, 32);
s1[3] = Xor(s2[3], msg, 48);
Array.Copy(s1[0], 8, output, outOff, 8);
Array.Copy(s1[1], 8, output, outOff + 8, 8);
Array.Copy(s1[2], 0, output, outOff + 16, 8);
Array.Copy(s1[3], 0, output, outOff + 24, 8);
return DIGEST_SIZE;
}
#endif
private static void Mix512(byte[][] s1, byte[][] s2)
{
Array.Copy(s1[0], 12, s2[0], 0, 4);
Array.Copy(s1[2], 12, s2[0], 4, 4);
Array.Copy(s1[1], 12, s2[0], 8, 4);
Array.Copy(s1[3], 12, s2[0], 12, 4);
Array.Copy(s1[2], 0, s2[1], 0, 4);
Array.Copy(s1[0], 0, s2[1], 4, 4);
Array.Copy(s1[3], 0, s2[1], 8, 4);
Array.Copy(s1[1], 0, s2[1], 12, 4);
Array.Copy(s1[2], 4, s2[2], 0, 4);
Array.Copy(s1[0], 4, s2[2], 4, 4);
Array.Copy(s1[3], 4, s2[2], 8, 4);
Array.Copy(s1[1], 4, s2[2], 12, 4);
Array.Copy(s1[0], 8, s2[3], 0, 4);
Array.Copy(s1[2], 8, s2[3], 4, 4);
Array.Copy(s1[1], 8, s2[3], 8, 4);
Array.Copy(s1[3], 8, s2[3], 12, 4);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b8a8760e24c83f14eb1d631436058560
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,244 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
#if NETCOREAPP3_0_OR_GREATER
using System;
using System.Buffers.Binary;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
using Aes = System.Runtime.Intrinsics.X86.Aes;
using Sse2 = System.Runtime.Intrinsics.X86.Sse2;
public static class Haraka512_X86
{
public static bool IsSupported => Aes.IsSupported;
// Haraka round constants
internal static readonly Vector128<byte>[] DefaultRoundConstants = new Vector128<byte>[]
{
Vector128.Create(0x9D, 0x7B, 0x81, 0x75, 0xF0, 0xFE, 0xC5, 0xB2, 0x0A, 0xC0, 0x20, 0xE6, 0x4C, 0x70, 0x84, 0x06),
Vector128.Create(0x17, 0xF7, 0x08, 0x2F, 0xA4, 0x6B, 0x0F, 0x64, 0x6B, 0xA0, 0xF3, 0x88, 0xE1, 0xB4, 0x66, 0x8B),
Vector128.Create(0x14, 0x91, 0x02, 0x9F, 0x60, 0x9D, 0x02, 0xCF, 0x98, 0x84, 0xF2, 0x53, 0x2D, 0xDE, 0x02, 0x34),
Vector128.Create(0x79, 0x4F, 0x5B, 0xFD, 0xAF, 0xBC, 0xF3, 0xBB, 0x08, 0x4F, 0x7B, 0x2E, 0xE6, 0xEA, 0xD6, 0x0E),
Vector128.Create(0x44, 0x70, 0x39, 0xBE, 0x1C, 0xCD, 0xEE, 0x79, 0x8B, 0x44, 0x72, 0x48, 0xCB, 0xB0, 0xCF, 0xCB),
Vector128.Create(0x7B, 0x05, 0x8A, 0x2B, 0xED, 0x35, 0x53, 0x8D, 0xB7, 0x32, 0x90, 0x6E, 0xEE, 0xCD, 0xEA, 0x7E),
Vector128.Create(0x1B, 0xEF, 0x4F, 0xDA, 0x61, 0x27, 0x41, 0xE2, 0xD0, 0x7C, 0x2E, 0x5E, 0x43, 0x8F, 0xC2, 0x67),
Vector128.Create(0x3B, 0x0B, 0xC7, 0x1F, 0xE2, 0xFD, 0x5F, 0x67, 0x07, 0xCC, 0xCA, 0xAF, 0xB0, 0xD9, 0x24, 0x29),
Vector128.Create(0xEE, 0x65, 0xD4, 0xB9, 0xCA, 0x8F, 0xDB, 0xEC, 0xE9, 0x7F, 0x86, 0xE6, 0xF1, 0x63, 0x4D, 0xAB),
Vector128.Create(0x33, 0x7E, 0x03, 0xAD, 0x4F, 0x40, 0x2A, 0x5B, 0x64, 0xCD, 0xB7, 0xD4, 0x84, 0xBF, 0x30, 0x1C),
Vector128.Create(0x00, 0x98, 0xF6, 0x8D, 0x2E, 0x8B, 0x02, 0x69, 0xBF, 0x23, 0x17, 0x94, 0xB9, 0x0B, 0xCC, 0xB2),
Vector128.Create(0x8A, 0x2D, 0x9D, 0x5C, 0xC8, 0x9E, 0xAA, 0x4A, 0x72, 0x55, 0x6F, 0xDE, 0xA6, 0x78, 0x04, 0xFA),
Vector128.Create(0xD4, 0x9F, 0x12, 0x29, 0x2E, 0x4F, 0xFA, 0x0E, 0x12, 0x2A, 0x77, 0x6B, 0x2B, 0x9F, 0xB4, 0xDF),
Vector128.Create(0xEE, 0x12, 0x6A, 0xBB, 0xAE, 0x11, 0xD6, 0x32, 0x36, 0xA2, 0x49, 0xF4, 0x44, 0x03, 0xA1, 0x1E),
Vector128.Create(0xA6, 0xEC, 0xA8, 0x9C, 0xC9, 0x00, 0x96, 0x5F, 0x84, 0x00, 0x05, 0x4B, 0x88, 0x49, 0x04, 0xAF),
Vector128.Create(0xEC, 0x93, 0xE5, 0x27, 0xE3, 0xC7, 0xA2, 0x78, 0x4F, 0x9C, 0x19, 0x9D, 0xD8, 0x5E, 0x02, 0x21),
Vector128.Create(0x73, 0x01, 0xD4, 0x82, 0xCD, 0x2E, 0x28, 0xB9, 0xB7, 0xC9, 0x59, 0xA7, 0xF8, 0xAA, 0x3A, 0xBF),
Vector128.Create(0x6B, 0x7D, 0x30, 0x10, 0xD9, 0xEF, 0xF2, 0x37, 0x17, 0xB0, 0x86, 0x61, 0x0D, 0x70, 0x60, 0x62),
Vector128.Create(0xC6, 0x9A, 0xFC, 0xF6, 0x53, 0x91, 0xC2, 0x81, 0x43, 0x04, 0x30, 0x21, 0xC2, 0x45, 0xCA, 0x5A),
Vector128.Create(0x3A, 0x94, 0xD1, 0x36, 0xE8, 0x92, 0xAF, 0x2C, 0xBB, 0x68, 0x6B, 0x22, 0x3C, 0x97, 0x23, 0x92),
Vector128.Create(0xB4, 0x71, 0x10, 0xE5, 0x58, 0xB9, 0xBA, 0x6C, 0xEB, 0x86, 0x58, 0x22, 0x38, 0x92, 0xBF, 0xD3),
Vector128.Create(0x8D, 0x12, 0xE1, 0x24, 0xDD, 0xFD, 0x3D, 0x93, 0x77, 0xC6, 0xF0, 0xAE, 0xE5, 0x3C, 0x86, 0xDB),
Vector128.Create(0xB1, 0x12, 0x22, 0xCB, 0xE3, 0x8D, 0xE4, 0x83, 0x9C, 0xA0, 0xEB, 0xFF, 0x68, 0x62, 0x60, 0xBB),
Vector128.Create(0x7D, 0xF7, 0x2B, 0xC7, 0x4E, 0x1A, 0xB9, 0x2D, 0x9C, 0xD1, 0xE4, 0xE2, 0xDC, 0xD3, 0x4B, 0x73),
Vector128.Create(0x4E, 0x92, 0xB3, 0x2C, 0xC4, 0x15, 0x14, 0x4B, 0x43, 0x1B, 0x30, 0x61, 0xC3, 0x47, 0xBB, 0x43),
Vector128.Create(0x99, 0x68, 0xEB, 0x16, 0xDD, 0x31, 0xB2, 0x03, 0xF6, 0xEF, 0x07, 0xE7, 0xA8, 0x75, 0xA7, 0xDB),
Vector128.Create(0x2C, 0x47, 0xCA, 0x7E, 0x02, 0x23, 0x5E, 0x8E, 0x77, 0x59, 0x75, 0x3C, 0x4B, 0x61, 0xF3, 0x6D),
Vector128.Create(0xF9, 0x17, 0x86, 0xB8, 0xB9, 0xE5, 0x1B, 0x6D, 0x77, 0x7D, 0xDE, 0xD6, 0x17, 0x5A, 0xA7, 0xCD),
Vector128.Create(0x5D, 0xEE, 0x46, 0xA9, 0x9D, 0x06, 0x6C, 0x9D, 0xAA, 0xE9, 0xA8, 0x6B, 0xF0, 0x43, 0x6B, 0xEC),
Vector128.Create(0xC1, 0x27, 0xF3, 0x3B, 0x59, 0x11, 0x53, 0xA2, 0x2B, 0x33, 0x57, 0xF9, 0x50, 0x69, 0x1E, 0xCB),
Vector128.Create(0xD9, 0xD0, 0x0E, 0x60, 0x53, 0x03, 0xED, 0xE4, 0x9C, 0x61, 0xDA, 0x00, 0x75, 0x0C, 0xEE, 0x2C),
Vector128.Create(0x50, 0xA3, 0xA4, 0x63, 0xBC, 0xBA, 0xBB, 0x80, 0xAB, 0x0C, 0xE9, 0x96, 0xA1, 0xA5, 0xB1, 0xF0),
Vector128.Create(0x39, 0xCA, 0x8D, 0x93, 0x30, 0xDE, 0x0D, 0xAB, 0x88, 0x29, 0x96, 0x5E, 0x02, 0xB1, 0x3D, 0xAE),
Vector128.Create(0x42, 0xB4, 0x75, 0x2E, 0xA8, 0xF3, 0x14, 0x88, 0x0B, 0xA4, 0x54, 0xD5, 0x38, 0x8F, 0xBB, 0x17),
Vector128.Create(0xF6, 0x16, 0x0A, 0x36, 0x79, 0xB7, 0xB6, 0xAE, 0xD7, 0x7F, 0x42, 0x5F, 0x5B, 0x8A, 0xBB, 0x34),
Vector128.Create(0xDE, 0xAF, 0xBA, 0xFF, 0x18, 0x59, 0xCE, 0x43, 0x38, 0x54, 0xE5, 0xCB, 0x41, 0x52, 0xF6, 0x26),
Vector128.Create(0x78, 0xC9, 0x9E, 0x83, 0xF7, 0x9C, 0xCA, 0xA2, 0x6A, 0x02, 0xF3, 0xB9, 0x54, 0x9A, 0xE9, 0x4C),
Vector128.Create(0x35, 0x12, 0x90, 0x22, 0x28, 0x6E, 0xC0, 0x40, 0xBE, 0xF7, 0xDF, 0x1B, 0x1A, 0xA5, 0x51, 0xAE),
Vector128.Create(0xCF, 0x59, 0xA6, 0x48, 0x0F, 0xBC, 0x73, 0xC1, 0x2B, 0xD2, 0x7E, 0xBA, 0x3C, 0x61, 0xC1, 0xA0),
Vector128.Create(0xA1, 0x9D, 0xC5, 0xE9, 0xFD, 0xBD, 0xD6, 0x4A, 0x88, 0x82, 0x28, 0x02, 0x03, 0xCC, 0x6A, 0x75),
};
public static void Hash(ReadOnlySpan<byte> input, Span<byte> output)
{
if (!IsSupported)
throw new PlatformNotSupportedException(nameof(Haraka512_X86));
var s0 = Load128(input[ ..16]);
var s1 = Load128(input[16..32]);
var s2 = Load128(input[32..48]);
var s3 = Load128(input[48..64]);
ImplRounds(ref s0, ref s1, ref s2, ref s3, DefaultRoundConstants.AsSpan(0, 40));
s0 = Sse2.Xor(s0, Load128(input[ ..16]));
s1 = Sse2.Xor(s1, Load128(input[16..32]));
s2 = Sse2.Xor(s2, Load128(input[32..48]));
s3 = Sse2.Xor(s3, Load128(input[48..64]));
Store64(s0.GetUpper(), output[ .. 8]);
Store64(s1.GetUpper(), output[ 8..16]);
Store64(s2.GetLower(), output[16..24]);
Store64(s3.GetLower(), output[24..32]);
}
public static void Hash(ReadOnlySpan<byte> input, Span<byte> output,
ReadOnlySpan<Vector128<byte>> roundConstants)
{
if (!IsSupported)
throw new PlatformNotSupportedException(nameof(Haraka512_X86));
var s0 = Load128(input[ ..16]);
var s1 = Load128(input[16..32]);
var s2 = Load128(input[32..48]);
var s3 = Load128(input[48..64]);
ImplRounds(ref s0, ref s1, ref s2, ref s3, roundConstants[..40]);
s0 = Sse2.Xor(s0, Load128(input[ ..16]));
s1 = Sse2.Xor(s1, Load128(input[16..32]));
s2 = Sse2.Xor(s2, Load128(input[32..48]));
s3 = Sse2.Xor(s3, Load128(input[48..64]));
Store64(s0.GetUpper(), output[ .. 8]);
Store64(s1.GetUpper(), output[ 8..16]);
Store64(s2.GetLower(), output[16..24]);
Store64(s3.GetLower(), output[24..32]);
}
public static void Permute(ReadOnlySpan<byte> input, Span<byte> output)
{
if (!IsSupported)
throw new PlatformNotSupportedException(nameof(Haraka512_X86));
var s0 = Load128(input[ ..16]);
var s1 = Load128(input[16..32]);
var s2 = Load128(input[32..48]);
var s3 = Load128(input[48..64]);
ImplRounds(ref s0, ref s1, ref s2, ref s3, DefaultRoundConstants.AsSpan(0, 40));
Store128(s0, output[ ..16]);
Store128(s1, output[16..32]);
Store128(s2, output[32..48]);
Store128(s3, output[48..64]);
}
public static void Permute(ReadOnlySpan<byte> input, Span<byte> output,
ReadOnlySpan<Vector128<byte>> roundConstants)
{
if (!IsSupported)
throw new PlatformNotSupportedException(nameof(Haraka512_X86));
var s0 = Load128(input[ ..16]);
var s1 = Load128(input[16..32]);
var s2 = Load128(input[32..48]);
var s3 = Load128(input[48..64]);
ImplRounds(ref s0, ref s1, ref s2, ref s3, roundConstants[..40]);
Store128(s0, output[ ..16]);
Store128(s1, output[16..32]);
Store128(s2, output[32..48]);
Store128(s3, output[48..64]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ImplRounds(ref Vector128<byte> s0, ref Vector128<byte> s1, ref Vector128<byte> s2,
ref Vector128<byte> s3, ReadOnlySpan<Vector128<byte>> rc)
{
ImplRound(ref s0, ref s1, ref s2, ref s3, rc[ .. 8]);
ImplRound(ref s0, ref s1, ref s2, ref s3, rc[ 8..16]);
ImplRound(ref s0, ref s1, ref s2, ref s3, rc[16..24]);
ImplRound(ref s0, ref s1, ref s2, ref s3, rc[24..32]);
ImplRound(ref s0, ref s1, ref s2, ref s3, rc[32..40]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ImplRound(ref Vector128<byte> s0, ref Vector128<byte> s1, ref Vector128<byte> s2,
ref Vector128<byte> s3, ReadOnlySpan<Vector128<byte>> rc)
{
ImplAes(ref s0, ref s1, ref s2, ref s3, rc[..8]);
ImplMix(ref s0, ref s1, ref s2, ref s3);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ImplAes(ref Vector128<byte> s0, ref Vector128<byte> s1, ref Vector128<byte> s2,
ref Vector128<byte> s3, ReadOnlySpan<Vector128<byte>> rc)
{
s0 = Aes.Encrypt(s0, rc[0]);
s1 = Aes.Encrypt(s1, rc[1]);
s2 = Aes.Encrypt(s2, rc[2]);
s3 = Aes.Encrypt(s3, rc[3]);
s0 = Aes.Encrypt(s0, rc[4]);
s1 = Aes.Encrypt(s1, rc[5]);
s2 = Aes.Encrypt(s2, rc[6]);
s3 = Aes.Encrypt(s3, rc[7]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ImplMix(ref Vector128<byte> s0, ref Vector128<byte> s1, ref Vector128<byte> s2,
ref Vector128<byte> s3)
{
var t0 = s0.AsUInt32();
var t1 = s1.AsUInt32();
var t2 = s2.AsUInt32();
var t3 = s3.AsUInt32();
var u0 = Sse2.UnpackLow(t0, t1);
var u1 = Sse2.UnpackHigh(t0, t1);
var u2 = Sse2.UnpackLow(t2, t3);
var u3 = Sse2.UnpackHigh(t2, t3);
s0 = Sse2.UnpackHigh(u1, u3).AsByte();
s1 = Sse2.UnpackLow(u2, u0).AsByte();
s2 = Sse2.UnpackHigh(u2, u0).AsByte();
s3 = Sse2.UnpackLow(u1, u3).AsByte();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector128<byte> Load128(ReadOnlySpan<byte> t)
{
if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<byte>>() == 16)
return MemoryMarshal.Read<Vector128<byte>>(t);
return Vector128.Create(
BinaryPrimitives.ReadUInt64LittleEndian(t[..8]),
BinaryPrimitives.ReadUInt64LittleEndian(t[8..])
).AsByte();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Store128(Vector128<byte> s, Span<byte> t)
{
if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<byte>>() == 16)
{
MemoryMarshal.Write(t, ref s);
return;
}
var u = s.AsUInt64();
BinaryPrimitives.WriteUInt64LittleEndian(t[..8], u.GetElement(0));
BinaryPrimitives.WriteUInt64LittleEndian(t[8..], u.GetElement(1));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Store64(Vector64<byte> s, Span<byte> t)
{
if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector64<byte>>() == 8)
{
MemoryMarshal.Write(t, ref s);
return;
}
var u = s.AsUInt64();
BinaryPrimitives.WriteUInt64LittleEndian(t, u.ToScalar());
}
}
}
#endif
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0e537a49b8c6586488a9c4e0c1549f89
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,188 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
public abstract class HarakaBase
: IDigest
{
internal static readonly int DIGEST_SIZE = 32;
// Haraka round constants
internal static readonly byte[][] RC = new byte[][]
{
new byte[]{ 0x9D, 0x7B, 0x81, 0x75, 0xF0, 0xFE, 0xC5, 0xB2, 0x0A, 0xC0, 0x20, 0xE6, 0x4C, 0x70, 0x84, 0x06 },
new byte[]{ 0x17, 0xF7, 0x08, 0x2F, 0xA4, 0x6B, 0x0F, 0x64, 0x6B, 0xA0, 0xF3, 0x88, 0xE1, 0xB4, 0x66, 0x8B },
new byte[]{ 0x14, 0x91, 0x02, 0x9F, 0x60, 0x9D, 0x02, 0xCF, 0x98, 0x84, 0xF2, 0x53, 0x2D, 0xDE, 0x02, 0x34 },
new byte[]{ 0x79, 0x4F, 0x5B, 0xFD, 0xAF, 0xBC, 0xF3, 0xBB, 0x08, 0x4F, 0x7B, 0x2E, 0xE6, 0xEA, 0xD6, 0x0E },
new byte[]{ 0x44, 0x70, 0x39, 0xBE, 0x1C, 0xCD, 0xEE, 0x79, 0x8B, 0x44, 0x72, 0x48, 0xCB, 0xB0, 0xCF, 0xCB },
new byte[]{ 0x7B, 0x05, 0x8A, 0x2B, 0xED, 0x35, 0x53, 0x8D, 0xB7, 0x32, 0x90, 0x6E, 0xEE, 0xCD, 0xEA, 0x7E },
new byte[]{ 0x1B, 0xEF, 0x4F, 0xDA, 0x61, 0x27, 0x41, 0xE2, 0xD0, 0x7C, 0x2E, 0x5E, 0x43, 0x8F, 0xC2, 0x67 },
new byte[]{ 0x3B, 0x0B, 0xC7, 0x1F, 0xE2, 0xFD, 0x5F, 0x67, 0x07, 0xCC, 0xCA, 0xAF, 0xB0, 0xD9, 0x24, 0x29 },
new byte[]{ 0xEE, 0x65, 0xD4, 0xB9, 0xCA, 0x8F, 0xDB, 0xEC, 0xE9, 0x7F, 0x86, 0xE6, 0xF1, 0x63, 0x4D, 0xAB },
new byte[]{ 0x33, 0x7E, 0x03, 0xAD, 0x4F, 0x40, 0x2A, 0x5B, 0x64, 0xCD, 0xB7, 0xD4, 0x84, 0xBF, 0x30, 0x1C },
new byte[]{ 0x00, 0x98, 0xF6, 0x8D, 0x2E, 0x8B, 0x02, 0x69, 0xBF, 0x23, 0x17, 0x94, 0xB9, 0x0B, 0xCC, 0xB2 },
new byte[]{ 0x8A, 0x2D, 0x9D, 0x5C, 0xC8, 0x9E, 0xAA, 0x4A, 0x72, 0x55, 0x6F, 0xDE, 0xA6, 0x78, 0x04, 0xFA },
new byte[]{ 0xD4, 0x9F, 0x12, 0x29, 0x2E, 0x4F, 0xFA, 0x0E, 0x12, 0x2A, 0x77, 0x6B, 0x2B, 0x9F, 0xB4, 0xDF },
new byte[]{ 0xEE, 0x12, 0x6A, 0xBB, 0xAE, 0x11, 0xD6, 0x32, 0x36, 0xA2, 0x49, 0xF4, 0x44, 0x03, 0xA1, 0x1E },
new byte[]{ 0xA6, 0xEC, 0xA8, 0x9C, 0xC9, 0x00, 0x96, 0x5F, 0x84, 0x00, 0x05, 0x4B, 0x88, 0x49, 0x04, 0xAF },
new byte[]{ 0xEC, 0x93, 0xE5, 0x27, 0xE3, 0xC7, 0xA2, 0x78, 0x4F, 0x9C, 0x19, 0x9D, 0xD8, 0x5E, 0x02, 0x21 },
new byte[]{ 0x73, 0x01, 0xD4, 0x82, 0xCD, 0x2E, 0x28, 0xB9, 0xB7, 0xC9, 0x59, 0xA7, 0xF8, 0xAA, 0x3A, 0xBF },
new byte[]{ 0x6B, 0x7D, 0x30, 0x10, 0xD9, 0xEF, 0xF2, 0x37, 0x17, 0xB0, 0x86, 0x61, 0x0D, 0x70, 0x60, 0x62 },
new byte[]{ 0xC6, 0x9A, 0xFC, 0xF6, 0x53, 0x91, 0xC2, 0x81, 0x43, 0x04, 0x30, 0x21, 0xC2, 0x45, 0xCA, 0x5A },
new byte[]{ 0x3A, 0x94, 0xD1, 0x36, 0xE8, 0x92, 0xAF, 0x2C, 0xBB, 0x68, 0x6B, 0x22, 0x3C, 0x97, 0x23, 0x92 },
new byte[]{ 0xB4, 0x71, 0x10, 0xE5, 0x58, 0xB9, 0xBA, 0x6C, 0xEB, 0x86, 0x58, 0x22, 0x38, 0x92, 0xBF, 0xD3 },
new byte[]{ 0x8D, 0x12, 0xE1, 0x24, 0xDD, 0xFD, 0x3D, 0x93, 0x77, 0xC6, 0xF0, 0xAE, 0xE5, 0x3C, 0x86, 0xDB },
new byte[]{ 0xB1, 0x12, 0x22, 0xCB, 0xE3, 0x8D, 0xE4, 0x83, 0x9C, 0xA0, 0xEB, 0xFF, 0x68, 0x62, 0x60, 0xBB },
new byte[]{ 0x7D, 0xF7, 0x2B, 0xC7, 0x4E, 0x1A, 0xB9, 0x2D, 0x9C, 0xD1, 0xE4, 0xE2, 0xDC, 0xD3, 0x4B, 0x73 },
new byte[]{ 0x4E, 0x92, 0xB3, 0x2C, 0xC4, 0x15, 0x14, 0x4B, 0x43, 0x1B, 0x30, 0x61, 0xC3, 0x47, 0xBB, 0x43 },
new byte[]{ 0x99, 0x68, 0xEB, 0x16, 0xDD, 0x31, 0xB2, 0x03, 0xF6, 0xEF, 0x07, 0xE7, 0xA8, 0x75, 0xA7, 0xDB },
new byte[]{ 0x2C, 0x47, 0xCA, 0x7E, 0x02, 0x23, 0x5E, 0x8E, 0x77, 0x59, 0x75, 0x3C, 0x4B, 0x61, 0xF3, 0x6D },
new byte[]{ 0xF9, 0x17, 0x86, 0xB8, 0xB9, 0xE5, 0x1B, 0x6D, 0x77, 0x7D, 0xDE, 0xD6, 0x17, 0x5A, 0xA7, 0xCD },
new byte[]{ 0x5D, 0xEE, 0x46, 0xA9, 0x9D, 0x06, 0x6C, 0x9D, 0xAA, 0xE9, 0xA8, 0x6B, 0xF0, 0x43, 0x6B, 0xEC },
new byte[]{ 0xC1, 0x27, 0xF3, 0x3B, 0x59, 0x11, 0x53, 0xA2, 0x2B, 0x33, 0x57, 0xF9, 0x50, 0x69, 0x1E, 0xCB },
new byte[]{ 0xD9, 0xD0, 0x0E, 0x60, 0x53, 0x03, 0xED, 0xE4, 0x9C, 0x61, 0xDA, 0x00, 0x75, 0x0C, 0xEE, 0x2C },
new byte[]{ 0x50, 0xA3, 0xA4, 0x63, 0xBC, 0xBA, 0xBB, 0x80, 0xAB, 0x0C, 0xE9, 0x96, 0xA1, 0xA5, 0xB1, 0xF0 },
new byte[]{ 0x39, 0xCA, 0x8D, 0x93, 0x30, 0xDE, 0x0D, 0xAB, 0x88, 0x29, 0x96, 0x5E, 0x02, 0xB1, 0x3D, 0xAE },
new byte[]{ 0x42, 0xB4, 0x75, 0x2E, 0xA8, 0xF3, 0x14, 0x88, 0x0B, 0xA4, 0x54, 0xD5, 0x38, 0x8F, 0xBB, 0x17 },
new byte[]{ 0xF6, 0x16, 0x0A, 0x36, 0x79, 0xB7, 0xB6, 0xAE, 0xD7, 0x7F, 0x42, 0x5F, 0x5B, 0x8A, 0xBB, 0x34 },
new byte[]{ 0xDE, 0xAF, 0xBA, 0xFF, 0x18, 0x59, 0xCE, 0x43, 0x38, 0x54, 0xE5, 0xCB, 0x41, 0x52, 0xF6, 0x26 },
new byte[]{ 0x78, 0xC9, 0x9E, 0x83, 0xF7, 0x9C, 0xCA, 0xA2, 0x6A, 0x02, 0xF3, 0xB9, 0x54, 0x9A, 0xE9, 0x4C },
new byte[]{ 0x35, 0x12, 0x90, 0x22, 0x28, 0x6E, 0xC0, 0x40, 0xBE, 0xF7, 0xDF, 0x1B, 0x1A, 0xA5, 0x51, 0xAE },
new byte[]{ 0xCF, 0x59, 0xA6, 0x48, 0x0F, 0xBC, 0x73, 0xC1, 0x2B, 0xD2, 0x7E, 0xBA, 0x3C, 0x61, 0xC1, 0xA0 },
new byte[]{ 0xA1, 0x9D, 0xC5, 0xE9, 0xFD, 0xBD, 0xD6, 0x4A, 0x88, 0x82, 0x28, 0x02, 0x03, 0xCC, 0x6A, 0x75 },
};
private static readonly byte[,] S =
{
{ 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76 },
{ 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0 },
{ 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15 },
{ 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75 },
{ 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84 },
{ 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF },
{ 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8 },
{ 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2 },
{ 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73 },
{ 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB },
{ 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79 },
{ 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08 },
{ 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A },
{ 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E },
{ 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF },
{ 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 },
};
private static byte SBox(byte x)
{
return S[(uint)x >> 4, x & 0xFU];
}
private static byte[] SubBytes(byte[] s)
{
byte[] output = new byte[s.Length];
for(int i = 0; i < 16; ++i)
{
output[i] = SBox(s[i]);
}
return output;
}
private static byte[] ShiftRows(byte[] s)
{
return new byte[]{
s[0], s[5], s[10], s[15],
s[4], s[9], s[14], s[3],
s[8], s[13], s[2], s[7],
s[12], s[1], s[6], s[11]
};
}
internal static byte[] AesEnc(byte[] s, byte[] rk)
{
s = SubBytes(s);
s = ShiftRows(s);
s = MixColumns(s);
XorTo(rk, s);
return s;
}
private static byte MulX(byte p)
{
return (byte)(((p & 0x7F) << 1) ^ (((uint)p >> 7) * 0x1BU));
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
internal static void Xor(ReadOnlySpan<byte> x, ReadOnlySpan<byte> y, Span<byte> z)
{
for (int i = 0; i < z.Length; i++)
{
z[i] = (byte)(x[i] ^ y[i]);
}
}
#else
internal static byte[] Xor(byte[] x, byte[] y, int yStart)
{
byte[] output = new byte[16];
for (int i = 0; i < output.Length; i++)
{
output[i] = (byte)(x[i] ^ y[yStart++]);
}
return output;
}
#endif
private static void XorTo(byte[] x, byte[] z)
{
for (int i = 0; i < 16; i += 4)
{
z[i + 0] ^= x[i + 0];
z[i + 1] ^= x[i + 1];
z[i + 2] ^= x[i + 2];
z[i + 3] ^= x[i + 3];
}
}
private static byte[] MixColumns(byte[] s)
{
byte[] output = new byte[s.Length];
int j = 0, i4;
for (int i = 0; i < 4; i++)
{
i4 = i << 2;
output[j++] = (byte)(MulX(s[i4]) ^ MulX(s[i4 + 1]) ^ s[i4 + 1] ^ s[i4 + 2] ^ s[i4 + 3]);
output[j++] = (byte)(s[i4] ^ MulX(s[i4 + 1]) ^ MulX(s[i4 + 2]) ^ s[i4 + 2] ^ s[i4 + 3]);
output[j++] = (byte)(s[i4] ^ s[i4 + 1] ^ MulX(s[i4 + 2]) ^ MulX(s[i4 + 3]) ^ s[i4 + 3]);
output[j++] = (byte)(MulX(s[i4]) ^ s[i4] ^ s[i4 + 1] ^ s[i4 + 2] ^ MulX(s[i4 + 3]));
}
return output;
}
public abstract string AlgorithmName { get; }
public int GetDigestSize()
{
return DIGEST_SIZE;
}
public abstract int GetByteLength();
public abstract void Update(byte input);
public abstract void BlockUpdate(byte[] input, int inOff, int length);
public abstract int DoFinal(byte[] output, int outOff);
public abstract void Reset();
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public abstract void BlockUpdate(ReadOnlySpan<byte> input);
public abstract int DoFinal(Span<byte> output);
#endif
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 58663e5f241e0d6489d7ab1a31fed7da
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,515 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.Diagnostics;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/// <summary>
/// Implementation of Keccak based on following KeccakNISTInterface.c from http://keccak.noekeon.org/
/// </summary>
/// <remarks>
/// Following the naming conventions used in the C source code to enable easy review of the implementation.
/// </remarks>
public class KeccakDigest
: IDigest, IMemoable
{
private static readonly ulong[] KeccakRoundConstants = new ulong[]{
0x0000000000000001UL, 0x0000000000008082UL, 0x800000000000808aUL, 0x8000000080008000UL,
0x000000000000808bUL, 0x0000000080000001UL, 0x8000000080008081UL, 0x8000000000008009UL,
0x000000000000008aUL, 0x0000000000000088UL, 0x0000000080008009UL, 0x000000008000000aUL,
0x000000008000808bUL, 0x800000000000008bUL, 0x8000000000008089UL, 0x8000000000008003UL,
0x8000000000008002UL, 0x8000000000000080UL, 0x000000000000800aUL, 0x800000008000000aUL,
0x8000000080008081UL, 0x8000000000008080UL, 0x0000000080000001UL, 0x8000000080008008UL
};
private ulong[] state = new ulong[25];
protected byte[] dataQueue = new byte[192];
protected int rate;
protected int bitsInQueue;
protected internal int fixedOutputLength;
protected bool squeezing;
public KeccakDigest()
: this(288)
{
}
public KeccakDigest(int bitLength)
{
Init(bitLength);
}
public KeccakDigest(KeccakDigest source)
{
CopyIn(source);
}
private void CopyIn(KeccakDigest source)
{
Array.Copy(source.state, 0, this.state, 0, source.state.Length);
Array.Copy(source.dataQueue, 0, this.dataQueue, 0, source.dataQueue.Length);
this.rate = source.rate;
this.bitsInQueue = source.bitsInQueue;
this.fixedOutputLength = source.fixedOutputLength;
this.squeezing = source.squeezing;
}
public virtual string AlgorithmName
{
get { return "Keccak-" + fixedOutputLength; }
}
public virtual int GetDigestSize()
{
return fixedOutputLength >> 3;
}
public virtual void Update(byte input)
{
Absorb(input);
}
public virtual void BlockUpdate(byte[] input, int inOff, int len)
{
Absorb(input, inOff, len);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual void BlockUpdate(ReadOnlySpan<byte> input)
{
Absorb(input);
}
#endif
public virtual int DoFinal(byte[] output, int outOff)
{
Squeeze(output, outOff, fixedOutputLength);
Reset();
return GetDigestSize();
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual int DoFinal(Span<byte> output)
{
int digestSize = GetDigestSize();
Squeeze(output[..digestSize]);
Reset();
return digestSize;
}
#endif
/*
* TODO Possible API change to support partial-byte suffixes.
*/
protected virtual int DoFinal(byte[] output, int outOff, byte partialByte, int partialBits)
{
if (partialBits > 0)
{
AbsorbBits(partialByte, partialBits);
}
Squeeze(output, outOff, fixedOutputLength);
Reset();
return GetDigestSize();
}
public virtual void Reset()
{
Init(fixedOutputLength);
}
/**
* Return the size of block that the compression function is applied to in bytes.
*
* @return internal byte length of a block.
*/
public virtual int GetByteLength()
{
return rate >> 3;
}
private void Init(int bitLength)
{
switch (bitLength)
{
case 128:
case 224:
case 256:
case 288:
case 384:
case 512:
InitSponge(1600 - (bitLength << 1));
break;
default:
throw new ArgumentException("must be one of 128, 224, 256, 288, 384, or 512.", "bitLength");
}
}
private void InitSponge(int rate)
{
if (rate <= 0 || rate >= 1600 || (rate & 63) != 0)
throw new InvalidOperationException("invalid rate value");
this.rate = rate;
Array.Clear(state, 0, state.Length);
Arrays.Fill(this.dataQueue, (byte)0);
this.bitsInQueue = 0;
this.squeezing = false;
this.fixedOutputLength = (1600 - rate) >> 1;
}
protected void Absorb(byte data)
{
if ((bitsInQueue & 7) != 0)
throw new InvalidOperationException("attempt to absorb with odd length queue");
if (squeezing)
throw new InvalidOperationException("attempt to absorb while squeezing");
dataQueue[bitsInQueue >> 3] = data;
if ((bitsInQueue += 8) == rate)
{
KeccakAbsorb(dataQueue, 0);
bitsInQueue = 0;
}
}
protected void Absorb(byte[] data, int off, int len)
{
if ((bitsInQueue & 7) != 0)
throw new InvalidOperationException("attempt to absorb with odd length queue");
if (squeezing)
throw new InvalidOperationException("attempt to absorb while squeezing");
int bytesInQueue = bitsInQueue >> 3;
int rateBytes = rate >> 3;
int available = rateBytes - bytesInQueue;
if (len < available)
{
Array.Copy(data, off, dataQueue, bytesInQueue, len);
this.bitsInQueue += len << 3;
return;
}
int count = 0;
if (bytesInQueue > 0)
{
Array.Copy(data, off, dataQueue, bytesInQueue, available);
count += available;
KeccakAbsorb(dataQueue, 0);
}
int remaining;
while ((remaining = (len - count)) >= rateBytes)
{
KeccakAbsorb(data, off + count);
count += rateBytes;
}
Array.Copy(data, off + count, dataQueue, 0, remaining);
this.bitsInQueue = remaining << 3;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
protected void Absorb(ReadOnlySpan<byte> data)
{
if ((bitsInQueue & 7) != 0)
throw new InvalidOperationException("attempt to absorb with odd length queue");
if (squeezing)
throw new InvalidOperationException("attempt to absorb while squeezing");
int bytesInQueue = bitsInQueue >> 3;
int rateBytes = rate >> 3;
int len = data.Length;
int available = rateBytes - bytesInQueue;
if (len < available)
{
data.CopyTo(dataQueue.AsSpan(bytesInQueue));
this.bitsInQueue += len << 3;
return;
}
int count = 0;
if (bytesInQueue > 0)
{
data[..available].CopyTo(dataQueue.AsSpan(bytesInQueue));
count += available;
KeccakAbsorb(dataQueue, 0);
}
int remaining;
while ((remaining = len - count) >= rateBytes)
{
KeccakAbsorb(data[count..]);
count += rateBytes;
}
data[count..].CopyTo(dataQueue.AsSpan());
this.bitsInQueue = remaining << 3;
}
#endif
protected void AbsorbBits(int data, int bits)
{
if (bits < 1 || bits > 7)
throw new ArgumentException("must be in the range 1 to 7", "bits");
if ((bitsInQueue & 7) != 0)
throw new InvalidOperationException("attempt to absorb with odd length queue");
if (squeezing)
throw new InvalidOperationException("attempt to absorb while squeezing");
int mask = (1 << bits) - 1;
dataQueue[bitsInQueue >> 3] = (byte)(data & mask);
// NOTE: After this, bitsInQueue is no longer a multiple of 8, so no more absorbs will work
bitsInQueue += bits;
}
private void PadAndSwitchToSqueezingPhase()
{
Debug.Assert(bitsInQueue < rate);
dataQueue[bitsInQueue >> 3] |= (byte)(1 << (bitsInQueue & 7));
if (++bitsInQueue == rate)
{
KeccakAbsorb(dataQueue, 0);
}
else
{
int full = bitsInQueue >> 6, partial = bitsInQueue & 63;
int off = 0;
for (int i = 0; i < full; ++i)
{
state[i] ^= Pack.LE_To_UInt64(dataQueue, off);
off += 8;
}
if (partial > 0)
{
ulong mask = (1UL << partial) - 1UL;
state[full] ^= Pack.LE_To_UInt64(dataQueue, off) & mask;
}
}
state[(rate - 1) >> 6] ^= (1UL << 63);
bitsInQueue = 0;
squeezing = true;
}
protected void Squeeze(byte[] output, int offset, long outputLength)
{
if (!squeezing)
{
PadAndSwitchToSqueezingPhase();
}
if ((outputLength & 7L) != 0L)
throw new InvalidOperationException("outputLength not a multiple of 8");
long i = 0;
while (i < outputLength)
{
if (bitsInQueue == 0)
{
KeccakExtract();
}
int partialBlock = (int)System.Math.Min((long)bitsInQueue, outputLength - i);
Array.Copy(dataQueue, (rate - bitsInQueue) >> 3, output, offset + (int)(i >> 3), partialBlock >> 3);
bitsInQueue -= partialBlock;
i += partialBlock;
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
protected void Squeeze(Span<byte> output)
{
if (!squeezing)
{
PadAndSwitchToSqueezingPhase();
}
long outputLength = (long)output.Length << 3;
long i = 0;
while (i < outputLength)
{
if (bitsInQueue == 0)
{
KeccakExtract();
}
int partialBlock = (int)System.Math.Min(bitsInQueue, outputLength - i);
dataQueue.AsSpan((rate - bitsInQueue) >> 3, partialBlock >> 3).CopyTo(output[(int)(i >> 3)..]);
bitsInQueue -= partialBlock;
i += partialBlock;
}
}
#endif
private void KeccakAbsorb(byte[] data, int off)
{
int count = rate >> 6;
for (int i = 0; i < count; ++i)
{
state[i] ^= Pack.LE_To_UInt64(data, off);
off += 8;
}
KeccakPermutation();
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private void KeccakAbsorb(ReadOnlySpan<byte> data)
{
int count = rate >> 6, off = 0;
for (int i = 0; i < count; ++i)
{
state[i] ^= Pack.LE_To_UInt64(data[off..]);
off += 8;
}
KeccakPermutation();
}
#endif
private void KeccakExtract()
{
KeccakPermutation();
Pack.UInt64_To_LE(state, 0, rate >> 6, dataQueue, 0);
this.bitsInQueue = rate;
}
private void KeccakPermutation()
{
ulong[] A = state;
ulong a00 = A[ 0], a01 = A[ 1], a02 = A[ 2], a03 = A[ 3], a04 = A[ 4];
ulong a05 = A[ 5], a06 = A[ 6], a07 = A[ 7], a08 = A[ 8], a09 = A[ 9];
ulong a10 = A[10], a11 = A[11], a12 = A[12], a13 = A[13], a14 = A[14];
ulong a15 = A[15], a16 = A[16], a17 = A[17], a18 = A[18], a19 = A[19];
ulong a20 = A[20], a21 = A[21], a22 = A[22], a23 = A[23], a24 = A[24];
for (int i = 0; i < 24; i++)
{
// theta
ulong c0 = a00 ^ a05 ^ a10 ^ a15 ^ a20;
ulong c1 = a01 ^ a06 ^ a11 ^ a16 ^ a21;
ulong c2 = a02 ^ a07 ^ a12 ^ a17 ^ a22;
ulong c3 = a03 ^ a08 ^ a13 ^ a18 ^ a23;
ulong c4 = a04 ^ a09 ^ a14 ^ a19 ^ a24;
ulong d1 = Longs.RotateLeft(c1, 1) ^ c4;
ulong d2 = Longs.RotateLeft(c2, 1) ^ c0;
ulong d3 = Longs.RotateLeft(c3, 1) ^ c1;
ulong d4 = Longs.RotateLeft(c4, 1) ^ c2;
ulong d0 = Longs.RotateLeft(c0, 1) ^ c3;
a00 ^= d1; a05 ^= d1; a10 ^= d1; a15 ^= d1; a20 ^= d1;
a01 ^= d2; a06 ^= d2; a11 ^= d2; a16 ^= d2; a21 ^= d2;
a02 ^= d3; a07 ^= d3; a12 ^= d3; a17 ^= d3; a22 ^= d3;
a03 ^= d4; a08 ^= d4; a13 ^= d4; a18 ^= d4; a23 ^= d4;
a04 ^= d0; a09 ^= d0; a14 ^= d0; a19 ^= d0; a24 ^= d0;
// rho/pi
c1 = Longs.RotateLeft(a01, 1);
a01 = Longs.RotateLeft(a06, 44);
a06 = Longs.RotateLeft(a09, 20);
a09 = Longs.RotateLeft(a22, 61);
a22 = Longs.RotateLeft(a14, 39);
a14 = Longs.RotateLeft(a20, 18);
a20 = Longs.RotateLeft(a02, 62);
a02 = Longs.RotateLeft(a12, 43);
a12 = Longs.RotateLeft(a13, 25);
a13 = Longs.RotateLeft(a19, 8);
a19 = Longs.RotateLeft(a23, 56);
a23 = Longs.RotateLeft(a15, 41);
a15 = Longs.RotateLeft(a04, 27);
a04 = Longs.RotateLeft(a24, 14);
a24 = Longs.RotateLeft(a21, 2);
a21 = Longs.RotateLeft(a08, 55);
a08 = Longs.RotateLeft(a16, 45);
a16 = Longs.RotateLeft(a05, 36);
a05 = Longs.RotateLeft(a03, 28);
a03 = Longs.RotateLeft(a18, 21);
a18 = Longs.RotateLeft(a17, 15);
a17 = Longs.RotateLeft(a11, 10);
a11 = Longs.RotateLeft(a07, 6);
a07 = Longs.RotateLeft(a10, 3);
a10 = c1;
// chi
c0 = a00 ^ (~a01 & a02);
c1 = a01 ^ (~a02 & a03);
a02 ^= ~a03 & a04;
a03 ^= ~a04 & a00;
a04 ^= ~a00 & a01;
a00 = c0;
a01 = c1;
c0 = a05 ^ (~a06 & a07);
c1 = a06 ^ (~a07 & a08);
a07 ^= ~a08 & a09;
a08 ^= ~a09 & a05;
a09 ^= ~a05 & a06;
a05 = c0;
a06 = c1;
c0 = a10 ^ (~a11 & a12);
c1 = a11 ^ (~a12 & a13);
a12 ^= ~a13 & a14;
a13 ^= ~a14 & a10;
a14 ^= ~a10 & a11;
a10 = c0;
a11 = c1;
c0 = a15 ^ (~a16 & a17);
c1 = a16 ^ (~a17 & a18);
a17 ^= ~a18 & a19;
a18 ^= ~a19 & a15;
a19 ^= ~a15 & a16;
a15 = c0;
a16 = c1;
c0 = a20 ^ (~a21 & a22);
c1 = a21 ^ (~a22 & a23);
a22 ^= ~a23 & a24;
a23 ^= ~a24 & a20;
a24 ^= ~a20 & a21;
a20 = c0;
a21 = c1;
// iota
a00 ^= KeccakRoundConstants[i];
}
A[ 0] = a00; A[ 1] = a01; A[ 2] = a02; A[ 3] = a03; A[ 4] = a04;
A[ 5] = a05; A[ 6] = a06; A[ 7] = a07; A[ 8] = a08; A[ 9] = a09;
A[10] = a10; A[11] = a11; A[12] = a12; A[13] = a13; A[14] = a14;
A[15] = a15; A[16] = a16; A[17] = a17; A[18] = a18; A[19] = a19;
A[20] = a20; A[21] = a21; A[22] = a22; A[23] = a23; A[24] = a24;
}
public virtual IMemoable Copy()
{
return new KeccakDigest(this);
}
public virtual void Reset(IMemoable other)
{
CopyIn((KeccakDigest)other);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c192d088e0263af4d8c9ea06cd4a902c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,416 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/**
* Base class for SHA-384 and SHA-512.
*/
public abstract class LongDigest
: IDigest, IMemoable
{
private int MyByteLength = 128;
private byte[] xBuf;
private int xBufOff;
private long byteCount1;
private long byteCount2;
internal ulong H1, H2, H3, H4, H5, H6, H7, H8;
private ulong[] W = new ulong[80];
private int wOff;
/**
* Constructor for variable length word
*/
internal LongDigest()
{
xBuf = new byte[8];
Reset();
}
/**
* Copy constructor. We are using copy constructors in place
* of the object.Clone() interface as this interface is not
* supported by J2ME.
*/
internal LongDigest(
LongDigest t)
{
xBuf = new byte[t.xBuf.Length];
CopyIn(t);
}
protected void CopyIn(LongDigest t)
{
Array.Copy(t.xBuf, 0, xBuf, 0, t.xBuf.Length);
xBufOff = t.xBufOff;
byteCount1 = t.byteCount1;
byteCount2 = t.byteCount2;
H1 = t.H1;
H2 = t.H2;
H3 = t.H3;
H4 = t.H4;
H5 = t.H5;
H6 = t.H6;
H7 = t.H7;
H8 = t.H8;
Array.Copy(t.W, 0, W, 0, t.W.Length);
wOff = t.wOff;
}
public void Update(
byte input)
{
xBuf[xBufOff++] = input;
if (xBufOff == xBuf.Length)
{
ProcessWord(xBuf, 0);
xBufOff = 0;
}
byteCount1++;
}
public void BlockUpdate(
byte[] input,
int inOff,
int length)
{
//
// fill the current word
//
while ((xBufOff != 0) && (length > 0))
{
Update(input[inOff]);
inOff++;
length--;
}
//
// process whole words.
//
while (length >= xBuf.Length)
{
ProcessWord(input, inOff);
inOff += xBuf.Length;
length -= xBuf.Length;
byteCount1 += xBuf.Length;
}
//
// load in the remainder.
//
while (length > 0)
{
Update(input[inOff]);
inOff++;
length--;
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void BlockUpdate(ReadOnlySpan<byte> input)
{
int inOff = 0;
int length = input.Length;
//
// fill the current word
//
while ((xBufOff != 0) && (length > 0))
{
Update(input[inOff]);
inOff++;
length--;
}
//
// process whole words.
//
while (length >= xBuf.Length)
{
ProcessWord(input.Slice(inOff, xBuf.Length));
inOff += xBuf.Length;
length -= xBuf.Length;
byteCount1 += xBuf.Length;
}
//
// load in the remainder.
//
while (length > 0)
{
Update(input[inOff]);
inOff++;
length--;
}
}
#endif
public void Finish()
{
AdjustByteCounts();
long lowBitLength = byteCount1 << 3;
long hiBitLength = byteCount2;
//
// add the pad bytes.
//
Update((byte)128);
while (xBufOff != 0)
{
Update((byte)0);
}
ProcessLength(lowBitLength, hiBitLength);
ProcessBlock();
}
public virtual void Reset()
{
byteCount1 = 0;
byteCount2 = 0;
xBufOff = 0;
for (int i = 0; i < xBuf.Length; i++)
{
xBuf[i] = 0;
}
wOff = 0;
Array.Clear(W, 0, W.Length);
}
internal void ProcessWord(
byte[] input,
int inOff)
{
W[wOff] = Pack.BE_To_UInt64(input, inOff);
if (++wOff == 16)
{
ProcessBlock();
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
internal void ProcessWord(ReadOnlySpan<byte> word)
{
W[wOff] = Pack.BE_To_UInt64(word);
if (++wOff == 16)
{
ProcessBlock();
}
}
#endif
/**
* adjust the byte counts so that byteCount2 represents the
* upper long (less 3 bits) word of the byte count.
*/
private void AdjustByteCounts()
{
if (byteCount1 > 0x1fffffffffffffffL)
{
byteCount2 += (long)((ulong)byteCount1 >> 61);
byteCount1 &= 0x1fffffffffffffffL;
}
}
internal void ProcessLength(
long lowW,
long hiW)
{
if (wOff > 14)
{
ProcessBlock();
}
W[14] = (ulong)hiW;
W[15] = (ulong)lowW;
}
internal void ProcessBlock()
{
AdjustByteCounts();
//
// expand 16 word block into 80 word blocks.
//
for (int ti = 16; ti <= 79; ++ti)
{
W[ti] = Sigma1(W[ti - 2]) + W[ti - 7] + Sigma0(W[ti - 15]) + W[ti - 16];
}
//
// set up working variables.
//
ulong a = H1;
ulong b = H2;
ulong c = H3;
ulong d = H4;
ulong e = H5;
ulong f = H6;
ulong g = H7;
ulong h = H8;
int t = 0;
for (int i = 0; i < 10; i++)
{
// t = 8 * i
h += Sum1(e) + Ch(e, f, g) + K[t] + W[t++];
d += h;
h += Sum0(a) + Maj(a, b, c);
// t = 8 * i + 1
g += Sum1(d) + Ch(d, e, f) + K[t] + W[t++];
c += g;
g += Sum0(h) + Maj(h, a, b);
// t = 8 * i + 2
f += Sum1(c) + Ch(c, d, e) + K[t] + W[t++];
b += f;
f += Sum0(g) + Maj(g, h, a);
// t = 8 * i + 3
e += Sum1(b) + Ch(b, c, d) + K[t] + W[t++];
a += e;
e += Sum0(f) + Maj(f, g, h);
// t = 8 * i + 4
d += Sum1(a) + Ch(a, b, c) + K[t] + W[t++];
h += d;
d += Sum0(e) + Maj(e, f, g);
// t = 8 * i + 5
c += Sum1(h) + Ch(h, a, b) + K[t] + W[t++];
g += c;
c += Sum0(d) + Maj(d, e, f);
// t = 8 * i + 6
b += Sum1(g) + Ch(g, h, a) + K[t] + W[t++];
f += b;
b += Sum0(c) + Maj(c, d, e);
// t = 8 * i + 7
a += Sum1(f) + Ch(f, g, h) + K[t] + W[t++];
e += a;
a += Sum0(b) + Maj(b, c, d);
}
H1 += a;
H2 += b;
H3 += c;
H4 += d;
H5 += e;
H6 += f;
H7 += g;
H8 += h;
//
// reset the offset and clean out the word buffer.
//
wOff = 0;
Array.Clear(W, 0, 16);
}
/* SHA-384 and SHA-512 functions (as for SHA-256 but for longs) */
private static ulong Ch(ulong x, ulong y, ulong z)
{
return (x & y) ^ (~x & z);
}
private static ulong Maj(ulong x, ulong y, ulong z)
{
return (x & y) ^ (x & z) ^ (y & z);
}
private static ulong Sum0(ulong x)
{
return ((x << 36) | (x >> 28)) ^ ((x << 30) | (x >> 34)) ^ ((x << 25) | (x >> 39));
}
private static ulong Sum1(ulong x)
{
return ((x << 50) | (x >> 14)) ^ ((x << 46) | (x >> 18)) ^ ((x << 23) | (x >> 41));
}
private static ulong Sigma0(ulong x)
{
return ((x << 63) | (x >> 1)) ^ ((x << 56) | (x >> 8)) ^ (x >> 7);
}
private static ulong Sigma1(ulong x)
{
return ((x << 45) | (x >> 19)) ^ ((x << 3) | (x >> 61)) ^ (x >> 6);
}
/* SHA-384 and SHA-512 Constants
* (represent the first 64 bits of the fractional parts of the
* cube roots of the first sixty-four prime numbers)
*/
internal static readonly ulong[] K =
{
0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694,
0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4,
0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70,
0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30,
0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,
0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b,
0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,
0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817
};
public int GetByteLength()
{
return MyByteLength;
}
public abstract string AlgorithmName { get; }
public abstract int GetDigestSize();
public abstract int DoFinal(byte[] output, int outOff);
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public abstract int DoFinal(Span<byte> output);
#endif
public abstract IMemoable Copy();
public abstract void Reset(IMemoable t);
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 22ad50beafd5a894b9c3f96b5370a0d6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,330 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/**
* implementation of MD2
* as outlined in RFC1319 by B.Kaliski from RSA Laboratories April 1992
*/
public class MD2Digest
: IDigest, IMemoable
{
private const int DigestLength = 16;
private const int BYTE_LENGTH = 16;
/* X buffer */
private byte[] X = new byte[48];
private int xOff;
/* M buffer */
private byte[] M = new byte[16];
private int mOff;
/* check sum */
private byte[] C = new byte[16];
private int COff;
public MD2Digest()
{
Reset();
}
public MD2Digest(MD2Digest t)
{
CopyIn(t);
}
private void CopyIn(MD2Digest t)
{
Array.Copy(t.X, 0, X, 0, t.X.Length);
xOff = t.xOff;
Array.Copy(t.M, 0, M, 0, t.M.Length);
mOff = t.mOff;
Array.Copy(t.C, 0, C, 0, t.C.Length);
COff = t.COff;
}
/**
* return the algorithm name
*
* @return the algorithm name
*/
public string AlgorithmName
{
get { return "MD2"; }
}
public int GetDigestSize()
{
return DigestLength;
}
public int GetByteLength()
{
return BYTE_LENGTH;
}
/**
* Close the digest, producing the final digest value. The doFinal
* call leaves the digest reset.
*
* @param out the array the digest is to be copied into.
* @param outOff the offset into the out array the digest is to start at.
*/
public int DoFinal(byte[] output, int outOff)
{
// add padding
byte paddingByte = (byte)(M.Length - mOff);
for (int i=mOff;i<M.Length;i++)
{
M[i] = paddingByte;
}
//do final check sum
ProcessChecksum(M);
// do final block process
ProcessBlock(M);
ProcessBlock(C);
Array.Copy(X, xOff, output, outOff, 16);
Reset();
return DigestLength;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public int DoFinal(Span<byte> output)
{
// add padding
byte paddingByte = (byte)(M.Length - mOff);
for (int i = mOff; i < M.Length; i++)
{
M[i] = paddingByte;
}
//do final check sum
ProcessChecksum(M);
// do final block process
ProcessBlock(M);
ProcessBlock(C);
X.AsSpan(xOff, 16).CopyTo(output);
Reset();
return DigestLength;
}
#endif
/**
* reset the digest back to it's initial state.
*/
public void Reset()
{
xOff = 0;
for (int i = 0; i != X.Length; i++)
{
X[i] = 0;
}
mOff = 0;
for (int i = 0; i != M.Length; i++)
{
M[i] = 0;
}
COff = 0;
for (int i = 0; i != C.Length; i++)
{
C[i] = 0;
}
}
/**
* update the message digest with a single byte.
*
* @param in the input byte to be entered.
*/
public void Update(byte input)
{
M[mOff++] = input;
if (mOff == 16)
{
ProcessChecksum(M);
ProcessBlock(M);
mOff = 0;
}
}
/**
* update the message digest with a block of bytes.
*
* @param in the byte array containing the data.
* @param inOff the offset into the byte array where the data starts.
* @param len the length of the data.
*/
public void BlockUpdate(byte[] input, int inOff, int length)
{
//
// fill the current word
//
while ((mOff != 0) && (length > 0))
{
Update(input[inOff]);
inOff++;
length--;
}
//
// process whole words.
//
while (length >= 16)
{
Array.Copy(input,inOff,M,0,16);
ProcessChecksum(M);
ProcessBlock(M);
length -= 16;
inOff += 16;
}
//
// load in the remainder.
//
while (length > 0)
{
Update(input[inOff]);
inOff++;
length--;
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void BlockUpdate(ReadOnlySpan<byte> input)
{
//
// fill the current word
//
while ((mOff != 0) && (input.Length > 0))
{
Update(input[0]);
input = input[1..];
}
//
// process whole words.
//
while (input.Length >= 16)
{
input[..16].CopyTo(M);
ProcessChecksum(M);
ProcessBlock(M);
input = input[16..];
}
//
// load in the remainder.
//
while (input.Length > 0)
{
Update(input[0]);
input = input[1..];
}
}
#endif
internal void ProcessChecksum(byte[] m)
{
int L = C[15];
for (int i=0;i<16;i++)
{
C[i] ^= S[(m[i] ^ L) & 0xff];
L = C[i];
}
}
internal void ProcessBlock(byte[] m)
{
for (int i=0;i<16;i++)
{
X[i+16] = m[i];
X[i+32] = (byte)(m[i] ^ X[i]);
}
// encrypt block
int t = 0;
for (int j=0;j<18;j++)
{
for (int k=0;k<48;k++)
{
t = X[k] ^= S[t];
t = t & 0xff;
}
t = (t + j)%256;
}
}
// 256-byte random permutation constructed from the digits of PI
private static readonly byte[] S = {
(byte)41,(byte)46,(byte)67,(byte)201,(byte)162,(byte)216,(byte)124,
(byte)1,(byte)61,(byte)54,(byte)84,(byte)161,(byte)236,(byte)240,
(byte)6,(byte)19,(byte)98,(byte)167,(byte)5,(byte)243,(byte)192,
(byte)199,(byte)115,(byte)140,(byte)152,(byte)147,(byte)43,(byte)217,
(byte)188,(byte)76,(byte)130,(byte)202,(byte)30,(byte)155,(byte)87,
(byte)60,(byte)253,(byte)212,(byte)224,(byte)22,(byte)103,(byte)66,
(byte)111,(byte)24,(byte)138,(byte)23,(byte)229,(byte)18,(byte)190,
(byte)78,(byte)196,(byte)214,(byte)218,(byte)158,(byte)222,(byte)73,
(byte)160,(byte)251,(byte)245,(byte)142,(byte)187,(byte)47,(byte)238,
(byte)122,(byte)169,(byte)104,(byte)121,(byte)145,(byte)21,(byte)178,
(byte)7,(byte)63,(byte)148,(byte)194,(byte)16,(byte)137,(byte)11,
(byte)34,(byte)95,(byte)33,(byte)128,(byte)127,(byte)93,(byte)154,
(byte)90,(byte)144,(byte)50,(byte)39,(byte)53,(byte)62,(byte)204,
(byte)231,(byte)191,(byte)247,(byte)151,(byte)3,(byte)255,(byte)25,
(byte)48,(byte)179,(byte)72,(byte)165,(byte)181,(byte)209,(byte)215,
(byte)94,(byte)146,(byte)42,(byte)172,(byte)86,(byte)170,(byte)198,
(byte)79,(byte)184,(byte)56,(byte)210,(byte)150,(byte)164,(byte)125,
(byte)182,(byte)118,(byte)252,(byte)107,(byte)226,(byte)156,(byte)116,
(byte)4,(byte)241,(byte)69,(byte)157,(byte)112,(byte)89,(byte)100,
(byte)113,(byte)135,(byte)32,(byte)134,(byte)91,(byte)207,(byte)101,
(byte)230,(byte)45,(byte)168,(byte)2,(byte)27,(byte)96,(byte)37,
(byte)173,(byte)174,(byte)176,(byte)185,(byte)246,(byte)28,(byte)70,
(byte)97,(byte)105,(byte)52,(byte)64,(byte)126,(byte)15,(byte)85,
(byte)71,(byte)163,(byte)35,(byte)221,(byte)81,(byte)175,(byte)58,
(byte)195,(byte)92,(byte)249,(byte)206,(byte)186,(byte)197,(byte)234,
(byte)38,(byte)44,(byte)83,(byte)13,(byte)110,(byte)133,(byte)40,
(byte)132, 9,(byte)211,(byte)223,(byte)205,(byte)244,(byte)65,
(byte)129,(byte)77,(byte)82,(byte)106,(byte)220,(byte)55,(byte)200,
(byte)108,(byte)193,(byte)171,(byte)250,(byte)36,(byte)225,(byte)123,
(byte)8,(byte)12,(byte)189,(byte)177,(byte)74,(byte)120,(byte)136,
(byte)149,(byte)139,(byte)227,(byte)99,(byte)232,(byte)109,(byte)233,
(byte)203,(byte)213,(byte)254,(byte)59,(byte)0,(byte)29,(byte)57,
(byte)242,(byte)239,(byte)183,(byte)14,(byte)102,(byte)88,(byte)208,
(byte)228,(byte)166,(byte)119,(byte)114,(byte)248,(byte)235,(byte)117,
(byte)75,(byte)10,(byte)49,(byte)68,(byte)80,(byte)180,(byte)143,
(byte)237,(byte)31,(byte)26,(byte)219,(byte)153,(byte)141,(byte)51,
(byte)159,(byte)17,(byte)131,(byte)20
};
public IMemoable Copy()
{
return new MD2Digest(this);
}
public void Reset(IMemoable other)
{
MD2Digest d = (MD2Digest)other;
CopyIn(d);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4e909e062ea7a9147877f48fde815da7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,297 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/**
* implementation of MD4 as RFC 1320 by R. Rivest, MIT Laboratory for
* Computer Science and RSA Data Security, Inc.
* <p>
* <b>NOTE</b>: This algorithm is only included for backwards compatibility
* with legacy applications, it's not secure, don't use it for anything new!</p>
*/
public class MD4Digest
: GeneralDigest
{
private const int DigestLength = 16;
private int H1, H2, H3, H4; // IV's
private int[] X = new int[16];
private int xOff;
/**
* Standard constructor
*/
public MD4Digest()
{
Reset();
}
/**
* Copy constructor. This will copy the state of the provided
* message digest.
*/
public MD4Digest(MD4Digest t) : base(t)
{
CopyIn(t);
}
private void CopyIn(MD4Digest t)
{
base.CopyIn(t);
H1 = t.H1;
H2 = t.H2;
H3 = t.H3;
H4 = t.H4;
Array.Copy(t.X, 0, X, 0, t.X.Length);
xOff = t.xOff;
}
public override string AlgorithmName
{
get { return "MD4"; }
}
public override int GetDigestSize()
{
return DigestLength;
}
internal override void ProcessWord(byte[] input, int inOff)
{
X[xOff++] = (int)Pack.LE_To_UInt32(input, inOff);
if (xOff == 16)
{
ProcessBlock();
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
internal override void ProcessWord(ReadOnlySpan<byte> word)
{
X[xOff++] = (int)Pack.LE_To_UInt32(word);
if (xOff == 16)
{
ProcessBlock();
}
}
#endif
internal override void ProcessLength(
long bitLength)
{
if (xOff > 14)
{
ProcessBlock();
}
X[14] = (int)(bitLength & 0xffffffff);
X[15] = (int)((ulong) bitLength >> 32);
}
public override int DoFinal(byte[] output, int outOff)
{
Finish();
Pack.UInt32_To_LE((uint)H1, output, outOff);
Pack.UInt32_To_LE((uint)H2, output, outOff + 4);
Pack.UInt32_To_LE((uint)H3, output, outOff + 8);
Pack.UInt32_To_LE((uint)H4, output, outOff + 12);
Reset();
return DigestLength;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override int DoFinal(Span<byte> output)
{
Finish();
Pack.UInt32_To_LE((uint)H1, output);
Pack.UInt32_To_LE((uint)H2, output[4..]);
Pack.UInt32_To_LE((uint)H3, output[8..]);
Pack.UInt32_To_LE((uint)H4, output[12..]);
Reset();
return DigestLength;
}
#endif
/**
* reset the chaining variables to the IV values.
*/
public override void Reset()
{
base.Reset();
H1 = unchecked((int) 0x67452301);
H2 = unchecked((int) 0xefcdab89);
H3 = unchecked((int) 0x98badcfe);
H4 = unchecked((int) 0x10325476);
xOff = 0;
for (int i = 0; i != X.Length; i++)
{
X[i] = 0;
}
}
//
// round 1 left rotates
//
private const int S11 = 3;
private const int S12 = 7;
private const int S13 = 11;
private const int S14 = 19;
//
// round 2 left rotates
//
private const int S21 = 3;
private const int S22 = 5;
private const int S23 = 9;
private const int S24 = 13;
//
// round 3 left rotates
//
private const int S31 = 3;
private const int S32 = 9;
private const int S33 = 11;
private const int S34 = 15;
/*
* F, G, H and I are the basic MD4 functions.
*/
private int F(
int u,
int v,
int w)
{
return (u & v) | (~u & w);
}
private int G(
int u,
int v,
int w)
{
return (u & v) | (u & w) | (v & w);
}
private int H(
int u,
int v,
int w)
{
return u ^ v ^ w;
}
internal override void ProcessBlock()
{
int a = H1;
int b = H2;
int c = H3;
int d = H4;
//
// Round 1 - F cycle, 16 times.
//
a = Integers.RotateLeft((a + F(b, c, d) + X[ 0]), S11);
d = Integers.RotateLeft((d + F(a, b, c) + X[ 1]), S12);
c = Integers.RotateLeft((c + F(d, a, b) + X[ 2]), S13);
b = Integers.RotateLeft((b + F(c, d, a) + X[ 3]), S14);
a = Integers.RotateLeft((a + F(b, c, d) + X[ 4]), S11);
d = Integers.RotateLeft((d + F(a, b, c) + X[ 5]), S12);
c = Integers.RotateLeft((c + F(d, a, b) + X[ 6]), S13);
b = Integers.RotateLeft((b + F(c, d, a) + X[ 7]), S14);
a = Integers.RotateLeft((a + F(b, c, d) + X[ 8]), S11);
d = Integers.RotateLeft((d + F(a, b, c) + X[ 9]), S12);
c = Integers.RotateLeft((c + F(d, a, b) + X[10]), S13);
b = Integers.RotateLeft((b + F(c, d, a) + X[11]), S14);
a = Integers.RotateLeft((a + F(b, c, d) + X[12]), S11);
d = Integers.RotateLeft((d + F(a, b, c) + X[13]), S12);
c = Integers.RotateLeft((c + F(d, a, b) + X[14]), S13);
b = Integers.RotateLeft((b + F(c, d, a) + X[15]), S14);
//
// Round 2 - G cycle, 16 times.
//
a = Integers.RotateLeft((a + G(b, c, d) + X[ 0] + 0x5a827999), S21);
d = Integers.RotateLeft((d + G(a, b, c) + X[ 4] + 0x5a827999), S22);
c = Integers.RotateLeft((c + G(d, a, b) + X[ 8] + 0x5a827999), S23);
b = Integers.RotateLeft((b + G(c, d, a) + X[12] + 0x5a827999), S24);
a = Integers.RotateLeft((a + G(b, c, d) + X[ 1] + 0x5a827999), S21);
d = Integers.RotateLeft((d + G(a, b, c) + X[ 5] + 0x5a827999), S22);
c = Integers.RotateLeft((c + G(d, a, b) + X[ 9] + 0x5a827999), S23);
b = Integers.RotateLeft((b + G(c, d, a) + X[13] + 0x5a827999), S24);
a = Integers.RotateLeft((a + G(b, c, d) + X[ 2] + 0x5a827999), S21);
d = Integers.RotateLeft((d + G(a, b, c) + X[ 6] + 0x5a827999), S22);
c = Integers.RotateLeft((c + G(d, a, b) + X[10] + 0x5a827999), S23);
b = Integers.RotateLeft((b + G(c, d, a) + X[14] + 0x5a827999), S24);
a = Integers.RotateLeft((a + G(b, c, d) + X[ 3] + 0x5a827999), S21);
d = Integers.RotateLeft((d + G(a, b, c) + X[ 7] + 0x5a827999), S22);
c = Integers.RotateLeft((c + G(d, a, b) + X[11] + 0x5a827999), S23);
b = Integers.RotateLeft((b + G(c, d, a) + X[15] + 0x5a827999), S24);
//
// Round 3 - H cycle, 16 times.
//
a = Integers.RotateLeft((a + H(b, c, d) + X[ 0] + 0x6ed9eba1), S31);
d = Integers.RotateLeft((d + H(a, b, c) + X[ 8] + 0x6ed9eba1), S32);
c = Integers.RotateLeft((c + H(d, a, b) + X[ 4] + 0x6ed9eba1), S33);
b = Integers.RotateLeft((b + H(c, d, a) + X[12] + 0x6ed9eba1), S34);
a = Integers.RotateLeft((a + H(b, c, d) + X[ 2] + 0x6ed9eba1), S31);
d = Integers.RotateLeft((d + H(a, b, c) + X[10] + 0x6ed9eba1), S32);
c = Integers.RotateLeft((c + H(d, a, b) + X[ 6] + 0x6ed9eba1), S33);
b = Integers.RotateLeft((b + H(c, d, a) + X[14] + 0x6ed9eba1), S34);
a = Integers.RotateLeft((a + H(b, c, d) + X[ 1] + 0x6ed9eba1), S31);
d = Integers.RotateLeft((d + H(a, b, c) + X[ 9] + 0x6ed9eba1), S32);
c = Integers.RotateLeft((c + H(d, a, b) + X[ 5] + 0x6ed9eba1), S33);
b = Integers.RotateLeft((b + H(c, d, a) + X[13] + 0x6ed9eba1), S34);
a = Integers.RotateLeft((a + H(b, c, d) + X[ 3] + 0x6ed9eba1), S31);
d = Integers.RotateLeft((d + H(a, b, c) + X[11] + 0x6ed9eba1), S32);
c = Integers.RotateLeft((c + H(d, a, b) + X[ 7] + 0x6ed9eba1), S33);
b = Integers.RotateLeft((b + H(c, d, a) + X[15] + 0x6ed9eba1), S34);
H1 += a;
H2 += b;
H3 += c;
H4 += d;
//
// reset the offset and clean out the word buffer.
//
xOff = 0;
for (int i = 0; i != X.Length; i++)
{
X[i] = 0;
}
}
public override IMemoable Copy()
{
return new MD4Digest(this);
}
public override void Reset(IMemoable other)
{
MD4Digest d = (MD4Digest)other;
CopyIn(d);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 30103169ff457af48aeddd23381fc50c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,343 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/**
* implementation of MD5 as outlined in "Handbook of Applied Cryptography", pages 346 - 347.
*/
public class MD5Digest
: GeneralDigest
{
private const int DigestLength = 16;
private uint H1, H2, H3, H4; // IV's
private uint[] X = new uint[16];
private int xOff;
public MD5Digest()
{
Reset();
}
/**
* Copy constructor. This will copy the state of the provided
* message digest.
*/
public MD5Digest(MD5Digest t)
: base(t)
{
CopyIn(t);
}
private void CopyIn(MD5Digest t)
{
base.CopyIn(t);
H1 = t.H1;
H2 = t.H2;
H3 = t.H3;
H4 = t.H4;
Array.Copy(t.X, 0, X, 0, t.X.Length);
xOff = t.xOff;
}
public override string AlgorithmName
{
get { return "MD5"; }
}
public override int GetDigestSize()
{
return DigestLength;
}
internal override void ProcessWord(byte[] input, int inOff)
{
X[xOff] = Pack.LE_To_UInt32(input, inOff);
if (++xOff == 16)
{
ProcessBlock();
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
internal override void ProcessWord(ReadOnlySpan<byte> word)
{
X[xOff] = Pack.LE_To_UInt32(word);
if (++xOff == 16)
{
ProcessBlock();
}
}
#endif
internal override void ProcessLength(
long bitLength)
{
if (xOff > 14)
{
if (xOff == 15)
X[15] = 0;
ProcessBlock();
}
for (int i = xOff; i < 14; ++i)
{
X[i] = 0;
}
X[14] = (uint)((ulong)bitLength);
X[15] = (uint)((ulong)bitLength >> 32);
}
public override int DoFinal(
byte[] output,
int outOff)
{
Finish();
Pack.UInt32_To_LE(H1, output, outOff);
Pack.UInt32_To_LE(H2, output, outOff + 4);
Pack.UInt32_To_LE(H3, output, outOff + 8);
Pack.UInt32_To_LE(H4, output, outOff + 12);
Reset();
return DigestLength;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override int DoFinal(Span<byte> output)
{
Finish();
Pack.UInt32_To_LE(H1, output);
Pack.UInt32_To_LE(H2, output[4..]);
Pack.UInt32_To_LE(H3, output[8..]);
Pack.UInt32_To_LE(H4, output[12..]);
Reset();
return DigestLength;
}
#endif
/**
* reset the chaining variables to the IV values.
*/
public override void Reset()
{
base.Reset();
H1 = 0x67452301;
H2 = 0xefcdab89;
H3 = 0x98badcfe;
H4 = 0x10325476;
xOff = 0;
for (int i = 0; i != X.Length; i++)
{
X[i] = 0;
}
}
//
// round 1 left rotates
//
private static readonly int S11 = 7;
private static readonly int S12 = 12;
private static readonly int S13 = 17;
private static readonly int S14 = 22;
//
// round 2 left rotates
//
private static readonly int S21 = 5;
private static readonly int S22 = 9;
private static readonly int S23 = 14;
private static readonly int S24 = 20;
//
// round 3 left rotates
//
private static readonly int S31 = 4;
private static readonly int S32 = 11;
private static readonly int S33 = 16;
private static readonly int S34 = 23;
//
// round 4 left rotates
//
private static readonly int S41 = 6;
private static readonly int S42 = 10;
private static readonly int S43 = 15;
private static readonly int S44 = 21;
/*
* rotate int x left n bits.
*/
private static uint RotateLeft(
uint x,
int n)
{
return (x << n) | (x >> (32 - n));
}
/*
* F, G, H and I are the basic MD5 functions.
*/
private static uint F(
uint u,
uint v,
uint w)
{
return (u & v) | (~u & w);
}
private static uint G(
uint u,
uint v,
uint w)
{
return (u & w) | (v & ~w);
}
private static uint H(
uint u,
uint v,
uint w)
{
return u ^ v ^ w;
}
private static uint K(
uint u,
uint v,
uint w)
{
return v ^ (u | ~w);
}
internal override void ProcessBlock()
{
uint a = H1;
uint b = H2;
uint c = H3;
uint d = H4;
//
// Round 1 - F cycle, 16 times.
//
a = RotateLeft((a + F(b, c, d) + X[0] + 0xd76aa478), S11) + b;
d = RotateLeft((d + F(a, b, c) + X[1] + 0xe8c7b756), S12) + a;
c = RotateLeft((c + F(d, a, b) + X[2] + 0x242070db), S13) + d;
b = RotateLeft((b + F(c, d, a) + X[3] + 0xc1bdceee), S14) + c;
a = RotateLeft((a + F(b, c, d) + X[4] + 0xf57c0faf), S11) + b;
d = RotateLeft((d + F(a, b, c) + X[5] + 0x4787c62a), S12) + a;
c = RotateLeft((c + F(d, a, b) + X[6] + 0xa8304613), S13) + d;
b = RotateLeft((b + F(c, d, a) + X[7] + 0xfd469501), S14) + c;
a = RotateLeft((a + F(b, c, d) + X[8] + 0x698098d8), S11) + b;
d = RotateLeft((d + F(a, b, c) + X[9] + 0x8b44f7af), S12) + a;
c = RotateLeft((c + F(d, a, b) + X[10] + 0xffff5bb1), S13) + d;
b = RotateLeft((b + F(c, d, a) + X[11] + 0x895cd7be), S14) + c;
a = RotateLeft((a + F(b, c, d) + X[12] + 0x6b901122), S11) + b;
d = RotateLeft((d + F(a, b, c) + X[13] + 0xfd987193), S12) + a;
c = RotateLeft((c + F(d, a, b) + X[14] + 0xa679438e), S13) + d;
b = RotateLeft((b + F(c, d, a) + X[15] + 0x49b40821), S14) + c;
//
// Round 2 - G cycle, 16 times.
//
a = RotateLeft((a + G(b, c, d) + X[1] + 0xf61e2562), S21) + b;
d = RotateLeft((d + G(a, b, c) + X[6] + 0xc040b340), S22) + a;
c = RotateLeft((c + G(d, a, b) + X[11] + 0x265e5a51), S23) + d;
b = RotateLeft((b + G(c, d, a) + X[0] + 0xe9b6c7aa), S24) + c;
a = RotateLeft((a + G(b, c, d) + X[5] + 0xd62f105d), S21) + b;
d = RotateLeft((d + G(a, b, c) + X[10] + 0x02441453), S22) + a;
c = RotateLeft((c + G(d, a, b) + X[15] + 0xd8a1e681), S23) + d;
b = RotateLeft((b + G(c, d, a) + X[4] + 0xe7d3fbc8), S24) + c;
a = RotateLeft((a + G(b, c, d) + X[9] + 0x21e1cde6), S21) + b;
d = RotateLeft((d + G(a, b, c) + X[14] + 0xc33707d6), S22) + a;
c = RotateLeft((c + G(d, a, b) + X[3] + 0xf4d50d87), S23) + d;
b = RotateLeft((b + G(c, d, a) + X[8] + 0x455a14ed), S24) + c;
a = RotateLeft((a + G(b, c, d) + X[13] + 0xa9e3e905), S21) + b;
d = RotateLeft((d + G(a, b, c) + X[2] + 0xfcefa3f8), S22) + a;
c = RotateLeft((c + G(d, a, b) + X[7] + 0x676f02d9), S23) + d;
b = RotateLeft((b + G(c, d, a) + X[12] + 0x8d2a4c8a), S24) + c;
//
// Round 3 - H cycle, 16 times.
//
a = RotateLeft((a + H(b, c, d) + X[5] + 0xfffa3942), S31) + b;
d = RotateLeft((d + H(a, b, c) + X[8] + 0x8771f681), S32) + a;
c = RotateLeft((c + H(d, a, b) + X[11] + 0x6d9d6122), S33) + d;
b = RotateLeft((b + H(c, d, a) + X[14] + 0xfde5380c), S34) + c;
a = RotateLeft((a + H(b, c, d) + X[1] + 0xa4beea44), S31) + b;
d = RotateLeft((d + H(a, b, c) + X[4] + 0x4bdecfa9), S32) + a;
c = RotateLeft((c + H(d, a, b) + X[7] + 0xf6bb4b60), S33) + d;
b = RotateLeft((b + H(c, d, a) + X[10] + 0xbebfbc70), S34) + c;
a = RotateLeft((a + H(b, c, d) + X[13] + 0x289b7ec6), S31) + b;
d = RotateLeft((d + H(a, b, c) + X[0] + 0xeaa127fa), S32) + a;
c = RotateLeft((c + H(d, a, b) + X[3] + 0xd4ef3085), S33) + d;
b = RotateLeft((b + H(c, d, a) + X[6] + 0x04881d05), S34) + c;
a = RotateLeft((a + H(b, c, d) + X[9] + 0xd9d4d039), S31) + b;
d = RotateLeft((d + H(a, b, c) + X[12] + 0xe6db99e5), S32) + a;
c = RotateLeft((c + H(d, a, b) + X[15] + 0x1fa27cf8), S33) + d;
b = RotateLeft((b + H(c, d, a) + X[2] + 0xc4ac5665), S34) + c;
//
// Round 4 - K cycle, 16 times.
//
a = RotateLeft((a + K(b, c, d) + X[0] + 0xf4292244), S41) + b;
d = RotateLeft((d + K(a, b, c) + X[7] + 0x432aff97), S42) + a;
c = RotateLeft((c + K(d, a, b) + X[14] + 0xab9423a7), S43) + d;
b = RotateLeft((b + K(c, d, a) + X[5] + 0xfc93a039), S44) + c;
a = RotateLeft((a + K(b, c, d) + X[12] + 0x655b59c3), S41) + b;
d = RotateLeft((d + K(a, b, c) + X[3] + 0x8f0ccc92), S42) + a;
c = RotateLeft((c + K(d, a, b) + X[10] + 0xffeff47d), S43) + d;
b = RotateLeft((b + K(c, d, a) + X[1] + 0x85845dd1), S44) + c;
a = RotateLeft((a + K(b, c, d) + X[8] + 0x6fa87e4f), S41) + b;
d = RotateLeft((d + K(a, b, c) + X[15] + 0xfe2ce6e0), S42) + a;
c = RotateLeft((c + K(d, a, b) + X[6] + 0xa3014314), S43) + d;
b = RotateLeft((b + K(c, d, a) + X[13] + 0x4e0811a1), S44) + c;
a = RotateLeft((a + K(b, c, d) + X[4] + 0xf7537e82), S41) + b;
d = RotateLeft((d + K(a, b, c) + X[11] + 0xbd3af235), S42) + a;
c = RotateLeft((c + K(d, a, b) + X[2] + 0x2ad7d2bb), S43) + d;
b = RotateLeft((b + K(c, d, a) + X[9] + 0xeb86d391), S44) + c;
H1 += a;
H2 += b;
H3 += c;
H4 += d;
xOff = 0;
}
public override IMemoable Copy()
{
return new MD5Digest(this);
}
public override void Reset(IMemoable other)
{
MD5Digest d = (MD5Digest)other;
CopyIn(d);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3b796d8fcf1612242a0a30ae4f5210a1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,80 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/**
* Wrapper removes exposure to the IMemoable interface on an IDigest implementation.
*/
public class NonMemoableDigest
: IDigest
{
protected readonly IDigest mBaseDigest;
/**
* Base constructor.
*
* @param baseDigest underlying digest to use.
* @exception IllegalArgumentException if baseDigest is null
*/
public NonMemoableDigest(IDigest baseDigest)
{
if (baseDigest == null)
throw new ArgumentNullException("baseDigest");
this.mBaseDigest = baseDigest;
}
public virtual string AlgorithmName
{
get { return mBaseDigest.AlgorithmName; }
}
public virtual int GetDigestSize()
{
return mBaseDigest.GetDigestSize();
}
public virtual void Update(byte input)
{
mBaseDigest.Update(input);
}
public virtual void BlockUpdate(byte[] input, int inOff, int len)
{
mBaseDigest.BlockUpdate(input, inOff, len);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual void BlockUpdate(ReadOnlySpan<byte> input)
{
mBaseDigest.BlockUpdate(input);
}
#endif
public virtual int DoFinal(byte[] output, int outOff)
{
return mBaseDigest.DoFinal(output, outOff);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual int DoFinal(Span<byte> output)
{
return mBaseDigest.DoFinal(output);
}
#endif
public virtual void Reset()
{
mBaseDigest.Reset();
}
public virtual int GetByteLength()
{
return mBaseDigest.GetByteLength();
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 82a60840f57e81049bfdaea27a443e84
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,90 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.IO;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
public class NullDigest : IDigest
{
private readonly MemoryStream bOut = new MemoryStream();
public string AlgorithmName
{
get { return "NULL"; }
}
public int GetByteLength()
{
// TODO Is this okay?
return 0;
}
public int GetDigestSize()
{
return Convert.ToInt32(bOut.Length);
}
public void Update(byte b)
{
bOut.WriteByte(b);
}
public void BlockUpdate(byte[] inBytes, int inOff, int len)
{
bOut.Write(inBytes, inOff, len);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void BlockUpdate(ReadOnlySpan<byte> input)
{
bOut.Write(input);
}
#endif
public int DoFinal(byte[] outBytes, int outOff)
{
try
{
byte[] data = bOut.GetBuffer();
int length = Convert.ToInt32(bOut.Length);
Array.Copy(data, 0, outBytes, outOff, length);
return length;
}
finally
{
Reset();
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public int DoFinal(Span<byte> output)
{
try
{
byte[] data = bOut.GetBuffer();
int length = Convert.ToInt32(bOut.Length);
data.AsSpan(0, length).CopyTo(output);
return length;
}
finally
{
Reset();
}
}
#endif
public void Reset()
{
bOut.SetLength(0);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0427788772c120d4fb0f3b7fb8357cb5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,306 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/// <summary>
/// ParallelHash - a hash designed to support the efficient hashing of very long strings, by taking advantage,
/// of the parallelism available in modern processors with an optional XOF mode.
/// <para>
/// From NIST Special Publication 800-185 - SHA-3 Derived Functions:cSHAKE, KMAC, TupleHash and ParallelHash
/// </para>
/// </summary>
public class ParallelHash
: IXof, IDigest
{
private static readonly byte[] N_PARALLEL_HASH = Strings.ToByteArray("ParallelHash");
private readonly CShakeDigest cshake;
private readonly CShakeDigest compressor;
private readonly int bitLength;
private readonly int outputLength;
private readonly int B;
private readonly byte[] buffer;
private readonly byte[] compressorBuffer;
private bool firstOutput;
private int nCount;
private int bufOff;
/**
* Base constructor.
*
* @param bitLength bit length of the underlying SHAKE function, 128 or 256.
* @param S the customization string - available for local use.
* @param B the blocksize (in bytes) for hashing.
*/
public ParallelHash(int bitLength, byte[] S, int B)
: this(bitLength, S, B, bitLength * 2)
{
}
public ParallelHash(int bitLength, byte[] S, int B, int outputSize)
{
this.cshake = new CShakeDigest(bitLength, N_PARALLEL_HASH, S);
this.compressor = new CShakeDigest(bitLength, new byte[0], new byte[0]);
this.bitLength = bitLength;
this.B = B;
this.outputLength = (outputSize + 7) / 8;
this.buffer = new byte[B];
this.compressorBuffer = new byte[bitLength * 2 / 8];
Reset();
}
public ParallelHash(ParallelHash source)
{
this.cshake = new CShakeDigest(source.cshake);
this.compressor = new CShakeDigest(source.compressor);
this.bitLength = source.bitLength;
this.B = source.B;
this.outputLength = source.outputLength;
this.buffer = Arrays.Clone(source.buffer);
this.compressorBuffer = Arrays.Clone(source.compressorBuffer);
}
public virtual string AlgorithmName
{
get { return "ParallelHash" + cshake.AlgorithmName.Substring(6); }
}
public virtual int GetByteLength()
{
return cshake.GetByteLength();
}
public virtual int GetDigestSize()
{
return outputLength;
}
public virtual void Update(byte b)
{
buffer[bufOff++] = b;
if (bufOff == buffer.Length)
{
Compress();
}
}
public virtual void BlockUpdate(byte[] inBuf, int inOff, int len)
{
len = System.Math.Max(0, len);
//
// fill the current word
//
int i = 0;
if (bufOff != 0)
{
while (i < len && bufOff != buffer.Length)
{
buffer[bufOff++] = inBuf[inOff + i++];
}
if (bufOff == buffer.Length)
{
Compress();
}
}
if (i < len)
{
while (len - i >= B)
{
Compress(inBuf, inOff + i, B);
i += B;
}
}
while (i < len)
{
Update(inBuf[inOff + i++]);
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual void BlockUpdate(ReadOnlySpan<byte> input)
{
//
// fill the current word
//
int i = 0;
if (bufOff != 0)
{
while (i < input.Length && bufOff != buffer.Length)
{
buffer[bufOff++] = input[i++];
}
if (bufOff == buffer.Length)
{
Compress();
}
}
if (i < input.Length)
{
while (input.Length - i >= B)
{
Compress(input, i, B);
i += B;
}
}
while (i < input.Length)
{
Update(input[i++]);
}
}
#endif
private void Compress()
{
Compress(buffer, 0, bufOff);
bufOff = 0;
}
private void Compress(byte[] buf, int offSet, int len)
{
compressor.BlockUpdate(buf, offSet, len);
compressor.OutputFinal(compressorBuffer, 0, compressorBuffer.Length);
cshake.BlockUpdate(compressorBuffer, 0, compressorBuffer.Length);
nCount++;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private void Compress(ReadOnlySpan<byte> input, int pos, int len)
{
compressor.BlockUpdate(input.Slice(pos, len));
compressor.OutputFinal(compressorBuffer, 0, compressorBuffer.Length);
cshake.BlockUpdate(compressorBuffer, 0, compressorBuffer.Length);
nCount++;
}
#endif
private void WrapUp(int outputSize)
{
if (bufOff != 0)
{
Compress();
}
byte[] nOut = XofUtilities.RightEncode(nCount);
byte[] encOut = XofUtilities.RightEncode(outputSize * 8);
cshake.BlockUpdate(nOut, 0, nOut.Length);
cshake.BlockUpdate(encOut, 0, encOut.Length);
firstOutput = false;
}
public virtual int DoFinal(byte[] outBuf, int outOff)
{
if (firstOutput)
{
WrapUp(outputLength);
}
int rv = cshake.DoFinal(outBuf, outOff);
Reset();
return rv;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual int DoFinal(Span<byte> output)
{
if (firstOutput)
{
WrapUp(outputLength);
}
int rv = cshake.DoFinal(output);
Reset();
return rv;
}
#endif
public virtual int OutputFinal(byte[] outBuf, int outOff, int outLen)
{
if (firstOutput)
{
WrapUp(outputLength);
}
int rv = cshake.OutputFinal(outBuf, outOff, outLen);
Reset();
return rv;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual int OutputFinal(Span<byte> output)
{
if (firstOutput)
{
WrapUp(outputLength);
}
int rv = cshake.OutputFinal(output);
Reset();
return rv;
}
#endif
public virtual int Output(byte[] outBuf, int outOff, int outLen)
{
if (firstOutput)
{
WrapUp(0);
}
return cshake.Output(outBuf, outOff, outLen);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual int Output(Span<byte> output)
{
if (firstOutput)
{
WrapUp(0);
}
return cshake.Output(output);
}
#endif
public virtual void Reset()
{
cshake.Reset();
Arrays.Clear(buffer);
byte[] hdr = XofUtilities.LeftEncode(B);
cshake.BlockUpdate(hdr, 0, hdr.Length);
nCount = 0;
bufOff = 0;
firstOutput = true;
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 98d360bb82670f245b69255d383defd3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,499 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/**
* implementation of RipeMD128
*/
public class RipeMD128Digest
: GeneralDigest
{
private const int DigestLength = 16;
private int H0, H1, H2, H3; // IV's
private int[] X = new int[16];
private int xOff;
/**
* Standard constructor
*/
public RipeMD128Digest()
{
Reset();
}
/**
* Copy constructor. This will copy the state of the provided
* message digest.
*/
public RipeMD128Digest(RipeMD128Digest t) : base(t)
{
CopyIn(t);
}
private void CopyIn(RipeMD128Digest t)
{
base.CopyIn(t);
H0 = t.H0;
H1 = t.H1;
H2 = t.H2;
H3 = t.H3;
Array.Copy(t.X, 0, X, 0, t.X.Length);
xOff = t.xOff;
}
public override string AlgorithmName
{
get { return "RIPEMD128"; }
}
public override int GetDigestSize()
{
return DigestLength;
}
internal override void ProcessWord(byte[] input, int inOff)
{
X[xOff++] = (int)Pack.LE_To_UInt32(input, inOff);
if (xOff == 16)
{
ProcessBlock();
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
internal override void ProcessWord(ReadOnlySpan<byte> word)
{
X[xOff++] = (int)Pack.LE_To_UInt32(word);
if (xOff == 16)
{
ProcessBlock();
}
}
#endif
internal override void ProcessLength(
long bitLength)
{
if (xOff > 14)
{
ProcessBlock();
}
X[14] = (int)(bitLength & 0xffffffff);
X[15] = (int)((ulong) bitLength >> 32);
}
public override int DoFinal(byte[] output, int outOff)
{
Finish();
Pack.UInt32_To_LE((uint)H0, output, outOff);
Pack.UInt32_To_LE((uint)H1, output, outOff + 4);
Pack.UInt32_To_LE((uint)H2, output, outOff + 8);
Pack.UInt32_To_LE((uint)H3, output, outOff + 12);
Reset();
return DigestLength;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override int DoFinal(Span<byte> output)
{
Finish();
Pack.UInt32_To_LE((uint)H0, output);
Pack.UInt32_To_LE((uint)H1, output[4..]);
Pack.UInt32_To_LE((uint)H2, output[8..]);
Pack.UInt32_To_LE((uint)H3, output[12..]);
Reset();
return DigestLength;
}
#endif
/**
* reset the chaining variables to the IV values.
*/
public override void Reset()
{
base.Reset();
H0 = unchecked((int) 0x67452301);
H1 = unchecked((int) 0xefcdab89);
H2 = unchecked((int) 0x98badcfe);
H3 = unchecked((int) 0x10325476);
xOff = 0;
for (int i = 0; i != X.Length; i++)
{
X[i] = 0;
}
}
/*
* rotate int x left n bits.
*/
private int RL(
int x,
int n)
{
return (x << n) | (int) ((uint) x >> (32 - n));
}
/*
* f1,f2,f3,f4 are the basic RipeMD128 functions.
*/
/*
* F
*/
private int F1(
int x,
int y,
int z)
{
return x ^ y ^ z;
}
/*
* G
*/
private int F2(
int x,
int y,
int z)
{
return (x & y) | (~x & z);
}
/*
* H
*/
private int F3(
int x,
int y,
int z)
{
return (x | ~y) ^ z;
}
/*
* I
*/
private int F4(
int x,
int y,
int z)
{
return (x & z) | (y & ~z);
}
private int F1(
int a,
int b,
int c,
int d,
int x,
int s)
{
return RL(a + F1(b, c, d) + x, s);
}
private int F2(
int a,
int b,
int c,
int d,
int x,
int s)
{
return RL(a + F2(b, c, d) + x + unchecked((int) 0x5a827999), s);
}
private int F3(
int a,
int b,
int c,
int d,
int x,
int s)
{
return RL(a + F3(b, c, d) + x + unchecked((int) 0x6ed9eba1), s);
}
private int F4(
int a,
int b,
int c,
int d,
int x,
int s)
{
return RL(a + F4(b, c, d) + x + unchecked((int) 0x8f1bbcdc), s);
}
private int FF1(
int a,
int b,
int c,
int d,
int x,
int s)
{
return RL(a + F1(b, c, d) + x, s);
}
private int FF2(
int a,
int b,
int c,
int d,
int x,
int s)
{
return RL(a + F2(b, c, d) + x + unchecked((int) 0x6d703ef3), s);
}
private int FF3(
int a,
int b,
int c,
int d,
int x,
int s)
{
return RL(a + F3(b, c, d) + x + unchecked((int) 0x5c4dd124), s);
}
private int FF4(
int a,
int b,
int c,
int d,
int x,
int s)
{
return RL(a + F4(b, c, d) + x + unchecked((int) 0x50a28be6), s);
}
internal override void ProcessBlock()
{
int a, aa;
int b, bb;
int c, cc;
int d, dd;
a = aa = H0;
b = bb = H1;
c = cc = H2;
d = dd = H3;
//
// Round 1
//
a = F1(a, b, c, d, X[ 0], 11);
d = F1(d, a, b, c, X[ 1], 14);
c = F1(c, d, a, b, X[ 2], 15);
b = F1(b, c, d, a, X[ 3], 12);
a = F1(a, b, c, d, X[ 4], 5);
d = F1(d, a, b, c, X[ 5], 8);
c = F1(c, d, a, b, X[ 6], 7);
b = F1(b, c, d, a, X[ 7], 9);
a = F1(a, b, c, d, X[ 8], 11);
d = F1(d, a, b, c, X[ 9], 13);
c = F1(c, d, a, b, X[10], 14);
b = F1(b, c, d, a, X[11], 15);
a = F1(a, b, c, d, X[12], 6);
d = F1(d, a, b, c, X[13], 7);
c = F1(c, d, a, b, X[14], 9);
b = F1(b, c, d, a, X[15], 8);
//
// Round 2
//
a = F2(a, b, c, d, X[ 7], 7);
d = F2(d, a, b, c, X[ 4], 6);
c = F2(c, d, a, b, X[13], 8);
b = F2(b, c, d, a, X[ 1], 13);
a = F2(a, b, c, d, X[10], 11);
d = F2(d, a, b, c, X[ 6], 9);
c = F2(c, d, a, b, X[15], 7);
b = F2(b, c, d, a, X[ 3], 15);
a = F2(a, b, c, d, X[12], 7);
d = F2(d, a, b, c, X[ 0], 12);
c = F2(c, d, a, b, X[ 9], 15);
b = F2(b, c, d, a, X[ 5], 9);
a = F2(a, b, c, d, X[ 2], 11);
d = F2(d, a, b, c, X[14], 7);
c = F2(c, d, a, b, X[11], 13);
b = F2(b, c, d, a, X[ 8], 12);
//
// Round 3
//
a = F3(a, b, c, d, X[ 3], 11);
d = F3(d, a, b, c, X[10], 13);
c = F3(c, d, a, b, X[14], 6);
b = F3(b, c, d, a, X[ 4], 7);
a = F3(a, b, c, d, X[ 9], 14);
d = F3(d, a, b, c, X[15], 9);
c = F3(c, d, a, b, X[ 8], 13);
b = F3(b, c, d, a, X[ 1], 15);
a = F3(a, b, c, d, X[ 2], 14);
d = F3(d, a, b, c, X[ 7], 8);
c = F3(c, d, a, b, X[ 0], 13);
b = F3(b, c, d, a, X[ 6], 6);
a = F3(a, b, c, d, X[13], 5);
d = F3(d, a, b, c, X[11], 12);
c = F3(c, d, a, b, X[ 5], 7);
b = F3(b, c, d, a, X[12], 5);
//
// Round 4
//
a = F4(a, b, c, d, X[ 1], 11);
d = F4(d, a, b, c, X[ 9], 12);
c = F4(c, d, a, b, X[11], 14);
b = F4(b, c, d, a, X[10], 15);
a = F4(a, b, c, d, X[ 0], 14);
d = F4(d, a, b, c, X[ 8], 15);
c = F4(c, d, a, b, X[12], 9);
b = F4(b, c, d, a, X[ 4], 8);
a = F4(a, b, c, d, X[13], 9);
d = F4(d, a, b, c, X[ 3], 14);
c = F4(c, d, a, b, X[ 7], 5);
b = F4(b, c, d, a, X[15], 6);
a = F4(a, b, c, d, X[14], 8);
d = F4(d, a, b, c, X[ 5], 6);
c = F4(c, d, a, b, X[ 6], 5);
b = F4(b, c, d, a, X[ 2], 12);
//
// Parallel round 1
//
aa = FF4(aa, bb, cc, dd, X[ 5], 8);
dd = FF4(dd, aa, bb, cc, X[14], 9);
cc = FF4(cc, dd, aa, bb, X[ 7], 9);
bb = FF4(bb, cc, dd, aa, X[ 0], 11);
aa = FF4(aa, bb, cc, dd, X[ 9], 13);
dd = FF4(dd, aa, bb, cc, X[ 2], 15);
cc = FF4(cc, dd, aa, bb, X[11], 15);
bb = FF4(bb, cc, dd, aa, X[ 4], 5);
aa = FF4(aa, bb, cc, dd, X[13], 7);
dd = FF4(dd, aa, bb, cc, X[ 6], 7);
cc = FF4(cc, dd, aa, bb, X[15], 8);
bb = FF4(bb, cc, dd, aa, X[ 8], 11);
aa = FF4(aa, bb, cc, dd, X[ 1], 14);
dd = FF4(dd, aa, bb, cc, X[10], 14);
cc = FF4(cc, dd, aa, bb, X[ 3], 12);
bb = FF4(bb, cc, dd, aa, X[12], 6);
//
// Parallel round 2
//
aa = FF3(aa, bb, cc, dd, X[ 6], 9);
dd = FF3(dd, aa, bb, cc, X[11], 13);
cc = FF3(cc, dd, aa, bb, X[ 3], 15);
bb = FF3(bb, cc, dd, aa, X[ 7], 7);
aa = FF3(aa, bb, cc, dd, X[ 0], 12);
dd = FF3(dd, aa, bb, cc, X[13], 8);
cc = FF3(cc, dd, aa, bb, X[ 5], 9);
bb = FF3(bb, cc, dd, aa, X[10], 11);
aa = FF3(aa, bb, cc, dd, X[14], 7);
dd = FF3(dd, aa, bb, cc, X[15], 7);
cc = FF3(cc, dd, aa, bb, X[ 8], 12);
bb = FF3(bb, cc, dd, aa, X[12], 7);
aa = FF3(aa, bb, cc, dd, X[ 4], 6);
dd = FF3(dd, aa, bb, cc, X[ 9], 15);
cc = FF3(cc, dd, aa, bb, X[ 1], 13);
bb = FF3(bb, cc, dd, aa, X[ 2], 11);
//
// Parallel round 3
//
aa = FF2(aa, bb, cc, dd, X[15], 9);
dd = FF2(dd, aa, bb, cc, X[ 5], 7);
cc = FF2(cc, dd, aa, bb, X[ 1], 15);
bb = FF2(bb, cc, dd, aa, X[ 3], 11);
aa = FF2(aa, bb, cc, dd, X[ 7], 8);
dd = FF2(dd, aa, bb, cc, X[14], 6);
cc = FF2(cc, dd, aa, bb, X[ 6], 6);
bb = FF2(bb, cc, dd, aa, X[ 9], 14);
aa = FF2(aa, bb, cc, dd, X[11], 12);
dd = FF2(dd, aa, bb, cc, X[ 8], 13);
cc = FF2(cc, dd, aa, bb, X[12], 5);
bb = FF2(bb, cc, dd, aa, X[ 2], 14);
aa = FF2(aa, bb, cc, dd, X[10], 13);
dd = FF2(dd, aa, bb, cc, X[ 0], 13);
cc = FF2(cc, dd, aa, bb, X[ 4], 7);
bb = FF2(bb, cc, dd, aa, X[13], 5);
//
// Parallel round 4
//
aa = FF1(aa, bb, cc, dd, X[ 8], 15);
dd = FF1(dd, aa, bb, cc, X[ 6], 5);
cc = FF1(cc, dd, aa, bb, X[ 4], 8);
bb = FF1(bb, cc, dd, aa, X[ 1], 11);
aa = FF1(aa, bb, cc, dd, X[ 3], 14);
dd = FF1(dd, aa, bb, cc, X[11], 14);
cc = FF1(cc, dd, aa, bb, X[15], 6);
bb = FF1(bb, cc, dd, aa, X[ 0], 14);
aa = FF1(aa, bb, cc, dd, X[ 5], 6);
dd = FF1(dd, aa, bb, cc, X[12], 9);
cc = FF1(cc, dd, aa, bb, X[ 2], 12);
bb = FF1(bb, cc, dd, aa, X[13], 9);
aa = FF1(aa, bb, cc, dd, X[ 9], 12);
dd = FF1(dd, aa, bb, cc, X[ 7], 5);
cc = FF1(cc, dd, aa, bb, X[10], 15);
bb = FF1(bb, cc, dd, aa, X[14], 8);
dd += c + H1; // final result for H0
//
// combine the results
//
H1 = H2 + d + aa;
H2 = H3 + a + bb;
H3 = H0 + b + cc;
H0 = dd;
//
// reset the offset and clean out the word buffer.
//
xOff = 0;
for (int i = 0; i != X.Length; i++)
{
X[i] = 0;
}
}
public override IMemoable Copy()
{
return new RipeMD128Digest(this);
}
public override void Reset(IMemoable other)
{
RipeMD128Digest d = (RipeMD128Digest)other;
CopyIn(d);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 45af7eb1eb4624a47b69ef38eb873350
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,461 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/**
* implementation of RipeMD see,
* http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
*/
public class RipeMD160Digest
: GeneralDigest
{
private const int DigestLength = 20;
private int H0, H1, H2, H3, H4; // IV's
private int[] X = new int[16];
private int xOff;
/**
* Standard constructor
*/
public RipeMD160Digest()
{
Reset();
}
/**
* Copy constructor. This will copy the state of the provided
* message digest.
*/
public RipeMD160Digest(RipeMD160Digest t) : base(t)
{
CopyIn(t);
}
private void CopyIn(RipeMD160Digest t)
{
base.CopyIn(t);
H0 = t.H0;
H1 = t.H1;
H2 = t.H2;
H3 = t.H3;
H4 = t.H4;
Array.Copy(t.X, 0, X, 0, t.X.Length);
xOff = t.xOff;
}
public override string AlgorithmName
{
get { return "RIPEMD160"; }
}
public override int GetDigestSize()
{
return DigestLength;
}
internal override void ProcessWord(byte[] input, int inOff)
{
X[xOff++] = (int)Pack.LE_To_UInt32(input, inOff);
if (xOff == 16)
{
ProcessBlock();
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
internal override void ProcessWord(ReadOnlySpan<byte> word)
{
X[xOff++] = (int)Pack.LE_To_UInt32(word);
if (xOff == 16)
{
ProcessBlock();
}
}
#endif
internal override void ProcessLength(
long bitLength)
{
if (xOff > 14)
{
ProcessBlock();
}
X[14] = (int)(bitLength & 0xffffffff);
X[15] = (int)((ulong) bitLength >> 32);
}
public override int DoFinal(byte[] output, int outOff)
{
Finish();
Pack.UInt32_To_LE((uint)H0, output, outOff);
Pack.UInt32_To_LE((uint)H1, output, outOff + 4);
Pack.UInt32_To_LE((uint)H2, output, outOff + 8);
Pack.UInt32_To_LE((uint)H3, output, outOff + 12);
Pack.UInt32_To_LE((uint)H4, output, outOff + 16);
Reset();
return DigestLength;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override int DoFinal(Span<byte> output)
{
Finish();
Pack.UInt32_To_LE((uint)H0, output);
Pack.UInt32_To_LE((uint)H1, output[4..]);
Pack.UInt32_To_LE((uint)H2, output[8..]);
Pack.UInt32_To_LE((uint)H3, output[12..]);
Pack.UInt32_To_LE((uint)H4, output[16..]);
Reset();
return DigestLength;
}
#endif
/**
* reset the chaining variables to the IV values.
*/
public override void Reset()
{
base.Reset();
H0 = unchecked((int) 0x67452301);
H1 = unchecked((int) 0xefcdab89);
H2 = unchecked((int) 0x98badcfe);
H3 = unchecked((int) 0x10325476);
H4 = unchecked((int) 0xc3d2e1f0);
xOff = 0;
for (int i = 0; i != X.Length; i++)
{
X[i] = 0;
}
}
/*
* rotate int x left n bits.
*/
private int RL(
int x,
int n)
{
return (x << n) | (int) ((uint) x >> (32 - n));
}
/*
* f1,f2,f3,f4,f5 are the basic RipeMD160 functions.
*/
/*
* rounds 0-15
*/
private int F1(
int x,
int y,
int z)
{
return x ^ y ^ z;
}
/*
* rounds 16-31
*/
private int F2(
int x,
int y,
int z)
{
return (x & y) | (~x & z);
}
/*
* rounds 32-47
*/
private int F3(
int x,
int y,
int z)
{
return (x | ~y) ^ z;
}
/*
* rounds 48-63
*/
private int F4(
int x,
int y,
int z)
{
return (x & z) | (y & ~z);
}
/*
* rounds 64-79
*/
private int F5(
int x,
int y,
int z)
{
return x ^ (y | ~z);
}
internal override void ProcessBlock()
{
int a, aa;
int b, bb;
int c, cc;
int d, dd;
int e, ee;
a = aa = H0;
b = bb = H1;
c = cc = H2;
d = dd = H3;
e = ee = H4;
//
// Rounds 1 - 16
//
// left
a = RL(a + F1(b,c,d) + X[ 0], 11) + e; c = RL(c, 10);
e = RL(e + F1(a,b,c) + X[ 1], 14) + d; b = RL(b, 10);
d = RL(d + F1(e,a,b) + X[ 2], 15) + c; a = RL(a, 10);
c = RL(c + F1(d,e,a) + X[ 3], 12) + b; e = RL(e, 10);
b = RL(b + F1(c,d,e) + X[ 4], 5) + a; d = RL(d, 10);
a = RL(a + F1(b,c,d) + X[ 5], 8) + e; c = RL(c, 10);
e = RL(e + F1(a,b,c) + X[ 6], 7) + d; b = RL(b, 10);
d = RL(d + F1(e,a,b) + X[ 7], 9) + c; a = RL(a, 10);
c = RL(c + F1(d,e,a) + X[ 8], 11) + b; e = RL(e, 10);
b = RL(b + F1(c,d,e) + X[ 9], 13) + a; d = RL(d, 10);
a = RL(a + F1(b,c,d) + X[10], 14) + e; c = RL(c, 10);
e = RL(e + F1(a,b,c) + X[11], 15) + d; b = RL(b, 10);
d = RL(d + F1(e,a,b) + X[12], 6) + c; a = RL(a, 10);
c = RL(c + F1(d,e,a) + X[13], 7) + b; e = RL(e, 10);
b = RL(b + F1(c,d,e) + X[14], 9) + a; d = RL(d, 10);
a = RL(a + F1(b,c,d) + X[15], 8) + e; c = RL(c, 10);
// right
aa = RL(aa + F5(bb,cc,dd) + X[ 5] + unchecked((int) 0x50a28be6), 8) + ee; cc = RL(cc, 10);
ee = RL(ee + F5(aa,bb,cc) + X[14] + unchecked((int) 0x50a28be6), 9) + dd; bb = RL(bb, 10);
dd = RL(dd + F5(ee,aa,bb) + X[ 7] + unchecked((int) 0x50a28be6), 9) + cc; aa = RL(aa, 10);
cc = RL(cc + F5(dd,ee,aa) + X[ 0] + unchecked((int) 0x50a28be6), 11) + bb; ee = RL(ee, 10);
bb = RL(bb + F5(cc,dd,ee) + X[ 9] + unchecked((int) 0x50a28be6), 13) + aa; dd = RL(dd, 10);
aa = RL(aa + F5(bb,cc,dd) + X[ 2] + unchecked((int) 0x50a28be6), 15) + ee; cc = RL(cc, 10);
ee = RL(ee + F5(aa,bb,cc) + X[11] + unchecked((int) 0x50a28be6), 15) + dd; bb = RL(bb, 10);
dd = RL(dd + F5(ee,aa,bb) + X[ 4] + unchecked((int) 0x50a28be6), 5) + cc; aa = RL(aa, 10);
cc = RL(cc + F5(dd,ee,aa) + X[13] + unchecked((int) 0x50a28be6), 7) + bb; ee = RL(ee, 10);
bb = RL(bb + F5(cc,dd,ee) + X[ 6] + unchecked((int) 0x50a28be6), 7) + aa; dd = RL(dd, 10);
aa = RL(aa + F5(bb,cc,dd) + X[15] + unchecked((int) 0x50a28be6), 8) + ee; cc = RL(cc, 10);
ee = RL(ee + F5(aa,bb,cc) + X[ 8] + unchecked((int) 0x50a28be6), 11) + dd; bb = RL(bb, 10);
dd = RL(dd + F5(ee,aa,bb) + X[ 1] + unchecked((int) 0x50a28be6), 14) + cc; aa = RL(aa, 10);
cc = RL(cc + F5(dd,ee,aa) + X[10] + unchecked((int) 0x50a28be6), 14) + bb; ee = RL(ee, 10);
bb = RL(bb + F5(cc,dd,ee) + X[ 3] + unchecked((int) 0x50a28be6), 12) + aa; dd = RL(dd, 10);
aa = RL(aa + F5(bb,cc,dd) + X[12] + unchecked((int) 0x50a28be6), 6) + ee; cc = RL(cc, 10);
//
// Rounds 16-31
//
// left
e = RL(e + F2(a,b,c) + X[ 7] + unchecked((int) 0x5a827999), 7) + d; b = RL(b, 10);
d = RL(d + F2(e,a,b) + X[ 4] + unchecked((int) 0x5a827999), 6) + c; a = RL(a, 10);
c = RL(c + F2(d,e,a) + X[13] + unchecked((int) 0x5a827999), 8) + b; e = RL(e, 10);
b = RL(b + F2(c,d,e) + X[ 1] + unchecked((int) 0x5a827999), 13) + a; d = RL(d, 10);
a = RL(a + F2(b,c,d) + X[10] + unchecked((int) 0x5a827999), 11) + e; c = RL(c, 10);
e = RL(e + F2(a,b,c) + X[ 6] + unchecked((int) 0x5a827999), 9) + d; b = RL(b, 10);
d = RL(d + F2(e,a,b) + X[15] + unchecked((int) 0x5a827999), 7) + c; a = RL(a, 10);
c = RL(c + F2(d,e,a) + X[ 3] + unchecked((int) 0x5a827999), 15) + b; e = RL(e, 10);
b = RL(b + F2(c,d,e) + X[12] + unchecked((int) 0x5a827999), 7) + a; d = RL(d, 10);
a = RL(a + F2(b,c,d) + X[ 0] + unchecked((int) 0x5a827999), 12) + e; c = RL(c, 10);
e = RL(e + F2(a,b,c) + X[ 9] + unchecked((int) 0x5a827999), 15) + d; b = RL(b, 10);
d = RL(d + F2(e,a,b) + X[ 5] + unchecked((int) 0x5a827999), 9) + c; a = RL(a, 10);
c = RL(c + F2(d,e,a) + X[ 2] + unchecked((int) 0x5a827999), 11) + b; e = RL(e, 10);
b = RL(b + F2(c,d,e) + X[14] + unchecked((int) 0x5a827999), 7) + a; d = RL(d, 10);
a = RL(a + F2(b,c,d) + X[11] + unchecked((int) 0x5a827999), 13) + e; c = RL(c, 10);
e = RL(e + F2(a,b,c) + X[ 8] + unchecked((int) 0x5a827999), 12) + d; b = RL(b, 10);
// right
ee = RL(ee + F4(aa,bb,cc) + X[ 6] + unchecked((int) 0x5c4dd124), 9) + dd; bb = RL(bb, 10);
dd = RL(dd + F4(ee,aa,bb) + X[11] + unchecked((int) 0x5c4dd124), 13) + cc; aa = RL(aa, 10);
cc = RL(cc + F4(dd,ee,aa) + X[ 3] + unchecked((int) 0x5c4dd124), 15) + bb; ee = RL(ee, 10);
bb = RL(bb + F4(cc,dd,ee) + X[ 7] + unchecked((int) 0x5c4dd124), 7) + aa; dd = RL(dd, 10);
aa = RL(aa + F4(bb,cc,dd) + X[ 0] + unchecked((int) 0x5c4dd124), 12) + ee; cc = RL(cc, 10);
ee = RL(ee + F4(aa,bb,cc) + X[13] + unchecked((int) 0x5c4dd124), 8) + dd; bb = RL(bb, 10);
dd = RL(dd + F4(ee,aa,bb) + X[ 5] + unchecked((int) 0x5c4dd124), 9) + cc; aa = RL(aa, 10);
cc = RL(cc + F4(dd,ee,aa) + X[10] + unchecked((int) 0x5c4dd124), 11) + bb; ee = RL(ee, 10);
bb = RL(bb + F4(cc,dd,ee) + X[14] + unchecked((int) 0x5c4dd124), 7) + aa; dd = RL(dd, 10);
aa = RL(aa + F4(bb,cc,dd) + X[15] + unchecked((int) 0x5c4dd124), 7) + ee; cc = RL(cc, 10);
ee = RL(ee + F4(aa,bb,cc) + X[ 8] + unchecked((int) 0x5c4dd124), 12) + dd; bb = RL(bb, 10);
dd = RL(dd + F4(ee,aa,bb) + X[12] + unchecked((int) 0x5c4dd124), 7) + cc; aa = RL(aa, 10);
cc = RL(cc + F4(dd,ee,aa) + X[ 4] + unchecked((int) 0x5c4dd124), 6) + bb; ee = RL(ee, 10);
bb = RL(bb + F4(cc,dd,ee) + X[ 9] + unchecked((int) 0x5c4dd124), 15) + aa; dd = RL(dd, 10);
aa = RL(aa + F4(bb,cc,dd) + X[ 1] + unchecked((int) 0x5c4dd124), 13) + ee; cc = RL(cc, 10);
ee = RL(ee + F4(aa,bb,cc) + X[ 2] + unchecked((int) 0x5c4dd124), 11) + dd; bb = RL(bb, 10);
//
// Rounds 32-47
//
// left
d = RL(d + F3(e,a,b) + X[ 3] + unchecked((int) 0x6ed9eba1), 11) + c; a = RL(a, 10);
c = RL(c + F3(d,e,a) + X[10] + unchecked((int) 0x6ed9eba1), 13) + b; e = RL(e, 10);
b = RL(b + F3(c,d,e) + X[14] + unchecked((int) 0x6ed9eba1), 6) + a; d = RL(d, 10);
a = RL(a + F3(b,c,d) + X[ 4] + unchecked((int) 0x6ed9eba1), 7) + e; c = RL(c, 10);
e = RL(e + F3(a,b,c) + X[ 9] + unchecked((int) 0x6ed9eba1), 14) + d; b = RL(b, 10);
d = RL(d + F3(e,a,b) + X[15] + unchecked((int) 0x6ed9eba1), 9) + c; a = RL(a, 10);
c = RL(c + F3(d,e,a) + X[ 8] + unchecked((int) 0x6ed9eba1), 13) + b; e = RL(e, 10);
b = RL(b + F3(c,d,e) + X[ 1] + unchecked((int) 0x6ed9eba1), 15) + a; d = RL(d, 10);
a = RL(a + F3(b,c,d) + X[ 2] + unchecked((int) 0x6ed9eba1), 14) + e; c = RL(c, 10);
e = RL(e + F3(a,b,c) + X[ 7] + unchecked((int) 0x6ed9eba1), 8) + d; b = RL(b, 10);
d = RL(d + F3(e,a,b) + X[ 0] + unchecked((int) 0x6ed9eba1), 13) + c; a = RL(a, 10);
c = RL(c + F3(d,e,a) + X[ 6] + unchecked((int) 0x6ed9eba1), 6) + b; e = RL(e, 10);
b = RL(b + F3(c,d,e) + X[13] + unchecked((int) 0x6ed9eba1), 5) + a; d = RL(d, 10);
a = RL(a + F3(b,c,d) + X[11] + unchecked((int) 0x6ed9eba1), 12) + e; c = RL(c, 10);
e = RL(e + F3(a,b,c) + X[ 5] + unchecked((int) 0x6ed9eba1), 7) + d; b = RL(b, 10);
d = RL(d + F3(e,a,b) + X[12] + unchecked((int) 0x6ed9eba1), 5) + c; a = RL(a, 10);
// right
dd = RL(dd + F3(ee,aa,bb) + X[15] + unchecked((int) 0x6d703ef3), 9) + cc; aa = RL(aa, 10);
cc = RL(cc + F3(dd,ee,aa) + X[ 5] + unchecked((int) 0x6d703ef3), 7) + bb; ee = RL(ee, 10);
bb = RL(bb + F3(cc,dd,ee) + X[ 1] + unchecked((int) 0x6d703ef3), 15) + aa; dd = RL(dd, 10);
aa = RL(aa + F3(bb,cc,dd) + X[ 3] + unchecked((int) 0x6d703ef3), 11) + ee; cc = RL(cc, 10);
ee = RL(ee + F3(aa,bb,cc) + X[ 7] + unchecked((int) 0x6d703ef3), 8) + dd; bb = RL(bb, 10);
dd = RL(dd + F3(ee,aa,bb) + X[14] + unchecked((int) 0x6d703ef3), 6) + cc; aa = RL(aa, 10);
cc = RL(cc + F3(dd,ee,aa) + X[ 6] + unchecked((int) 0x6d703ef3), 6) + bb; ee = RL(ee, 10);
bb = RL(bb + F3(cc,dd,ee) + X[ 9] + unchecked((int) 0x6d703ef3), 14) + aa; dd = RL(dd, 10);
aa = RL(aa + F3(bb,cc,dd) + X[11] + unchecked((int) 0x6d703ef3), 12) + ee; cc = RL(cc, 10);
ee = RL(ee + F3(aa,bb,cc) + X[ 8] + unchecked((int) 0x6d703ef3), 13) + dd; bb = RL(bb, 10);
dd = RL(dd + F3(ee,aa,bb) + X[12] + unchecked((int) 0x6d703ef3), 5) + cc; aa = RL(aa, 10);
cc = RL(cc + F3(dd,ee,aa) + X[ 2] + unchecked((int) 0x6d703ef3), 14) + bb; ee = RL(ee, 10);
bb = RL(bb + F3(cc,dd,ee) + X[10] + unchecked((int) 0x6d703ef3), 13) + aa; dd = RL(dd, 10);
aa = RL(aa + F3(bb,cc,dd) + X[ 0] + unchecked((int) 0x6d703ef3), 13) + ee; cc = RL(cc, 10);
ee = RL(ee + F3(aa,bb,cc) + X[ 4] + unchecked((int) 0x6d703ef3), 7) + dd; bb = RL(bb, 10);
dd = RL(dd + F3(ee,aa,bb) + X[13] + unchecked((int) 0x6d703ef3), 5) + cc; aa = RL(aa, 10);
//
// Rounds 48-63
//
// left
c = RL(c + F4(d,e,a) + X[ 1] + unchecked((int) 0x8f1bbcdc), 11) + b; e = RL(e, 10);
b = RL(b + F4(c,d,e) + X[ 9] + unchecked((int) 0x8f1bbcdc), 12) + a; d = RL(d, 10);
a = RL(a + F4(b,c,d) + X[11] + unchecked((int) 0x8f1bbcdc), 14) + e; c = RL(c, 10);
e = RL(e + F4(a,b,c) + X[10] + unchecked((int) 0x8f1bbcdc), 15) + d; b = RL(b, 10);
d = RL(d + F4(e,a,b) + X[ 0] + unchecked((int) 0x8f1bbcdc), 14) + c; a = RL(a, 10);
c = RL(c + F4(d,e,a) + X[ 8] + unchecked((int) 0x8f1bbcdc), 15) + b; e = RL(e, 10);
b = RL(b + F4(c,d,e) + X[12] + unchecked((int) 0x8f1bbcdc), 9) + a; d = RL(d, 10);
a = RL(a + F4(b,c,d) + X[ 4] + unchecked((int) 0x8f1bbcdc), 8) + e; c = RL(c, 10);
e = RL(e + F4(a,b,c) + X[13] + unchecked((int) 0x8f1bbcdc), 9) + d; b = RL(b, 10);
d = RL(d + F4(e,a,b) + X[ 3] + unchecked((int) 0x8f1bbcdc), 14) + c; a = RL(a, 10);
c = RL(c + F4(d,e,a) + X[ 7] + unchecked((int) 0x8f1bbcdc), 5) + b; e = RL(e, 10);
b = RL(b + F4(c,d,e) + X[15] + unchecked((int) 0x8f1bbcdc), 6) + a; d = RL(d, 10);
a = RL(a + F4(b,c,d) + X[14] + unchecked((int) 0x8f1bbcdc), 8) + e; c = RL(c, 10);
e = RL(e + F4(a,b,c) + X[ 5] + unchecked((int) 0x8f1bbcdc), 6) + d; b = RL(b, 10);
d = RL(d + F4(e,a,b) + X[ 6] + unchecked((int) 0x8f1bbcdc), 5) + c; a = RL(a, 10);
c = RL(c + F4(d,e,a) + X[ 2] + unchecked((int) 0x8f1bbcdc), 12) + b; e = RL(e, 10);
// right
cc = RL(cc + F2(dd,ee,aa) + X[ 8] + unchecked((int) 0x7a6d76e9), 15) + bb; ee = RL(ee, 10);
bb = RL(bb + F2(cc,dd,ee) + X[ 6] + unchecked((int) 0x7a6d76e9), 5) + aa; dd = RL(dd, 10);
aa = RL(aa + F2(bb,cc,dd) + X[ 4] + unchecked((int) 0x7a6d76e9), 8) + ee; cc = RL(cc, 10);
ee = RL(ee + F2(aa,bb,cc) + X[ 1] + unchecked((int) 0x7a6d76e9), 11) + dd; bb = RL(bb, 10);
dd = RL(dd + F2(ee,aa,bb) + X[ 3] + unchecked((int) 0x7a6d76e9), 14) + cc; aa = RL(aa, 10);
cc = RL(cc + F2(dd,ee,aa) + X[11] + unchecked((int) 0x7a6d76e9), 14) + bb; ee = RL(ee, 10);
bb = RL(bb + F2(cc,dd,ee) + X[15] + unchecked((int) 0x7a6d76e9), 6) + aa; dd = RL(dd, 10);
aa = RL(aa + F2(bb,cc,dd) + X[ 0] + unchecked((int) 0x7a6d76e9), 14) + ee; cc = RL(cc, 10);
ee = RL(ee + F2(aa,bb,cc) + X[ 5] + unchecked((int) 0x7a6d76e9), 6) + dd; bb = RL(bb, 10);
dd = RL(dd + F2(ee,aa,bb) + X[12] + unchecked((int) 0x7a6d76e9), 9) + cc; aa = RL(aa, 10);
cc = RL(cc + F2(dd,ee,aa) + X[ 2] + unchecked((int) 0x7a6d76e9), 12) + bb; ee = RL(ee, 10);
bb = RL(bb + F2(cc,dd,ee) + X[13] + unchecked((int) 0x7a6d76e9), 9) + aa; dd = RL(dd, 10);
aa = RL(aa + F2(bb,cc,dd) + X[ 9] + unchecked((int) 0x7a6d76e9), 12) + ee; cc = RL(cc, 10);
ee = RL(ee + F2(aa,bb,cc) + X[ 7] + unchecked((int) 0x7a6d76e9), 5) + dd; bb = RL(bb, 10);
dd = RL(dd + F2(ee,aa,bb) + X[10] + unchecked((int) 0x7a6d76e9), 15) + cc; aa = RL(aa, 10);
cc = RL(cc + F2(dd,ee,aa) + X[14] + unchecked((int) 0x7a6d76e9), 8) + bb; ee = RL(ee, 10);
//
// Rounds 64-79
//
// left
b = RL(b + F5(c,d,e) + X[ 4] + unchecked((int) 0xa953fd4e), 9) + a; d = RL(d, 10);
a = RL(a + F5(b,c,d) + X[ 0] + unchecked((int) 0xa953fd4e), 15) + e; c = RL(c, 10);
e = RL(e + F5(a,b,c) + X[ 5] + unchecked((int) 0xa953fd4e), 5) + d; b = RL(b, 10);
d = RL(d + F5(e,a,b) + X[ 9] + unchecked((int) 0xa953fd4e), 11) + c; a = RL(a, 10);
c = RL(c + F5(d,e,a) + X[ 7] + unchecked((int) 0xa953fd4e), 6) + b; e = RL(e, 10);
b = RL(b + F5(c,d,e) + X[12] + unchecked((int) 0xa953fd4e), 8) + a; d = RL(d, 10);
a = RL(a + F5(b,c,d) + X[ 2] + unchecked((int) 0xa953fd4e), 13) + e; c = RL(c, 10);
e = RL(e + F5(a,b,c) + X[10] + unchecked((int) 0xa953fd4e), 12) + d; b = RL(b, 10);
d = RL(d + F5(e,a,b) + X[14] + unchecked((int) 0xa953fd4e), 5) + c; a = RL(a, 10);
c = RL(c + F5(d,e,a) + X[ 1] + unchecked((int) 0xa953fd4e), 12) + b; e = RL(e, 10);
b = RL(b + F5(c,d,e) + X[ 3] + unchecked((int) 0xa953fd4e), 13) + a; d = RL(d, 10);
a = RL(a + F5(b,c,d) + X[ 8] + unchecked((int) 0xa953fd4e), 14) + e; c = RL(c, 10);
e = RL(e + F5(a,b,c) + X[11] + unchecked((int) 0xa953fd4e), 11) + d; b = RL(b, 10);
d = RL(d + F5(e,a,b) + X[ 6] + unchecked((int) 0xa953fd4e), 8) + c; a = RL(a, 10);
c = RL(c + F5(d,e,a) + X[15] + unchecked((int) 0xa953fd4e), 5) + b; e = RL(e, 10);
b = RL(b + F5(c,d,e) + X[13] + unchecked((int) 0xa953fd4e), 6) + a; d = RL(d, 10);
// right
bb = RL(bb + F1(cc,dd,ee) + X[12], 8) + aa; dd = RL(dd, 10);
aa = RL(aa + F1(bb,cc,dd) + X[15], 5) + ee; cc = RL(cc, 10);
ee = RL(ee + F1(aa,bb,cc) + X[10], 12) + dd; bb = RL(bb, 10);
dd = RL(dd + F1(ee,aa,bb) + X[ 4], 9) + cc; aa = RL(aa, 10);
cc = RL(cc + F1(dd,ee,aa) + X[ 1], 12) + bb; ee = RL(ee, 10);
bb = RL(bb + F1(cc,dd,ee) + X[ 5], 5) + aa; dd = RL(dd, 10);
aa = RL(aa + F1(bb,cc,dd) + X[ 8], 14) + ee; cc = RL(cc, 10);
ee = RL(ee + F1(aa,bb,cc) + X[ 7], 6) + dd; bb = RL(bb, 10);
dd = RL(dd + F1(ee,aa,bb) + X[ 6], 8) + cc; aa = RL(aa, 10);
cc = RL(cc + F1(dd,ee,aa) + X[ 2], 13) + bb; ee = RL(ee, 10);
bb = RL(bb + F1(cc,dd,ee) + X[13], 6) + aa; dd = RL(dd, 10);
aa = RL(aa + F1(bb,cc,dd) + X[14], 5) + ee; cc = RL(cc, 10);
ee = RL(ee + F1(aa,bb,cc) + X[ 0], 15) + dd; bb = RL(bb, 10);
dd = RL(dd + F1(ee,aa,bb) + X[ 3], 13) + cc; aa = RL(aa, 10);
cc = RL(cc + F1(dd,ee,aa) + X[ 9], 11) + bb; ee = RL(ee, 10);
bb = RL(bb + F1(cc,dd,ee) + X[11], 11) + aa; dd = RL(dd, 10);
dd += c + H1;
H1 = H2 + d + ee;
H2 = H3 + e + aa;
H3 = H4 + a + bb;
H4 = H0 + b + cc;
H0 = dd;
//
// reset the offset and clean out the word buffer.
//
xOff = 0;
for (int i = 0; i != X.Length; i++)
{
X[i] = 0;
}
}
public override IMemoable Copy()
{
return new RipeMD160Digest(this);
}
public override void Reset(IMemoable other)
{
RipeMD160Digest d = (RipeMD160Digest)other;
CopyIn(d);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fdd72432e5cbe2f44b0111376025b4ea
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,452 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/// <remarks>
/// <p>Implementation of RipeMD256.</p>
/// <p><b>Note:</b> this algorithm offers the same level of security as RipeMD128.</p>
/// </remarks>
public class RipeMD256Digest
: GeneralDigest
{
public override string AlgorithmName
{
get { return "RIPEMD256"; }
}
public override int GetDigestSize()
{
return DigestLength;
}
private const int DigestLength = 32;
private int H0, H1, H2, H3, H4, H5, H6, H7; // IV's
private int[] X = new int[16];
private int xOff;
/// <summary> Standard constructor</summary>
public RipeMD256Digest()
{
Reset();
}
/// <summary> Copy constructor. This will copy the state of the provided
/// message digest.
/// </summary>
public RipeMD256Digest(RipeMD256Digest t):base(t)
{
CopyIn(t);
}
private void CopyIn(RipeMD256Digest t)
{
base.CopyIn(t);
H0 = t.H0;
H1 = t.H1;
H2 = t.H2;
H3 = t.H3;
H4 = t.H4;
H5 = t.H5;
H6 = t.H6;
H7 = t.H7;
Array.Copy(t.X, 0, X, 0, t.X.Length);
xOff = t.xOff;
}
internal override void ProcessWord(byte[] input, int inOff)
{
X[xOff++] = (int)Pack.LE_To_UInt32(input, inOff);
if (xOff == 16)
{
ProcessBlock();
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
internal override void ProcessWord(ReadOnlySpan<byte> word)
{
X[xOff++] = (int)Pack.LE_To_UInt32(word);
if (xOff == 16)
{
ProcessBlock();
}
}
#endif
internal override void ProcessLength(
long bitLength)
{
if (xOff > 14)
{
ProcessBlock();
}
X[14] = (int)(bitLength & 0xffffffff);
X[15] = (int)((ulong)bitLength >> 32);
}
public override int DoFinal(byte[] output, int outOff)
{
Finish();
Pack.UInt32_To_LE((uint)H0, output, outOff);
Pack.UInt32_To_LE((uint)H1, output, outOff + 4);
Pack.UInt32_To_LE((uint)H2, output, outOff + 8);
Pack.UInt32_To_LE((uint)H3, output, outOff + 12);
Pack.UInt32_To_LE((uint)H4, output, outOff + 16);
Pack.UInt32_To_LE((uint)H5, output, outOff + 20);
Pack.UInt32_To_LE((uint)H6, output, outOff + 24);
Pack.UInt32_To_LE((uint)H7, output, outOff + 28);
Reset();
return DigestLength;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override int DoFinal(Span<byte> output)
{
Finish();
Pack.UInt32_To_LE((uint)H0, output);
Pack.UInt32_To_LE((uint)H1, output[4..]);
Pack.UInt32_To_LE((uint)H2, output[8..]);
Pack.UInt32_To_LE((uint)H3, output[12..]);
Pack.UInt32_To_LE((uint)H4, output[16..]);
Pack.UInt32_To_LE((uint)H5, output[20..]);
Pack.UInt32_To_LE((uint)H6, output[24..]);
Pack.UInt32_To_LE((uint)H7, output[28..]);
Reset();
return DigestLength;
}
#endif
/// <summary> reset the chaining variables to the IV values.</summary>
public override void Reset()
{
base.Reset();
H0 = unchecked((int)0x67452301);
H1 = unchecked((int)0xefcdab89);
H2 = unchecked((int)0x98badcfe);
H3 = unchecked((int)0x10325476);
H4 = unchecked((int)0x76543210);
H5 = unchecked((int)0xFEDCBA98);
H6 = unchecked((int)0x89ABCDEF);
H7 = unchecked((int)0x01234567);
xOff = 0;
for (int i = 0; i != X.Length; i++)
{
X[i] = 0;
}
}
/*
* rotate int x left n bits.
*/
private int RL(
int x,
int n)
{
return (x << n) | (int)((uint)x >> (32 - n));
}
/*
* f1,f2,f3,f4 are the basic RipeMD128 functions.
*/
/*
* F
*/
private int F1(int x, int y, int z)
{
return x ^ y ^ z;
}
/*
* G
*/
private int F2(int x, int y, int z)
{
return (x & y) | (~ x & z);
}
/*
* H
*/
private int F3(int x, int y, int z)
{
return (x | ~ y) ^ z;
}
/*
* I
*/
private int F4(int x, int y, int z)
{
return (x & z) | (y & ~ z);
}
private int F1(int a, int b, int c, int d, int x, int s)
{
return RL(a + F1(b, c, d) + x, s);
}
private int F2(int a, int b, int c, int d, int x, int s)
{
return RL(a + F2(b, c, d) + x + unchecked((int)0x5a827999), s);
}
private int F3(int a, int b, int c, int d, int x, int s)
{
return RL(a + F3(b, c, d) + x + unchecked((int)0x6ed9eba1), s);
}
private int F4(int a, int b, int c, int d, int x, int s)
{
return RL(a + F4(b, c, d) + x + unchecked((int)0x8f1bbcdc), s);
}
private int FF1(int a, int b, int c, int d, int x, int s)
{
return RL(a + F1(b, c, d) + x, s);
}
private int FF2(int a, int b, int c, int d, int x, int s)
{
return RL(a + F2(b, c, d) + x + unchecked((int)0x6d703ef3), s);
}
private int FF3(int a, int b, int c, int d, int x, int s)
{
return RL(a + F3(b, c, d) + x + unchecked((int)0x5c4dd124), s);
}
private int FF4(int a, int b, int c, int d, int x, int s)
{
return RL(a + F4(b, c, d) + x + unchecked((int)0x50a28be6), s);
}
internal override void ProcessBlock()
{
int a, aa;
int b, bb;
int c, cc;
int d, dd;
int t;
a = H0;
b = H1;
c = H2;
d = H3;
aa = H4;
bb = H5;
cc = H6;
dd = H7;
//
// Round 1
//
a = F1(a, b, c, d, X[0], 11);
d = F1(d, a, b, c, X[1], 14);
c = F1(c, d, a, b, X[2], 15);
b = F1(b, c, d, a, X[3], 12);
a = F1(a, b, c, d, X[4], 5);
d = F1(d, a, b, c, X[5], 8);
c = F1(c, d, a, b, X[6], 7);
b = F1(b, c, d, a, X[7], 9);
a = F1(a, b, c, d, X[8], 11);
d = F1(d, a, b, c, X[9], 13);
c = F1(c, d, a, b, X[10], 14);
b = F1(b, c, d, a, X[11], 15);
a = F1(a, b, c, d, X[12], 6);
d = F1(d, a, b, c, X[13], 7);
c = F1(c, d, a, b, X[14], 9);
b = F1(b, c, d, a, X[15], 8);
aa = FF4(aa, bb, cc, dd, X[5], 8);
dd = FF4(dd, aa, bb, cc, X[14], 9);
cc = FF4(cc, dd, aa, bb, X[7], 9);
bb = FF4(bb, cc, dd, aa, X[0], 11);
aa = FF4(aa, bb, cc, dd, X[9], 13);
dd = FF4(dd, aa, bb, cc, X[2], 15);
cc = FF4(cc, dd, aa, bb, X[11], 15);
bb = FF4(bb, cc, dd, aa, X[4], 5);
aa = FF4(aa, bb, cc, dd, X[13], 7);
dd = FF4(dd, aa, bb, cc, X[6], 7);
cc = FF4(cc, dd, aa, bb, X[15], 8);
bb = FF4(bb, cc, dd, aa, X[8], 11);
aa = FF4(aa, bb, cc, dd, X[1], 14);
dd = FF4(dd, aa, bb, cc, X[10], 14);
cc = FF4(cc, dd, aa, bb, X[3], 12);
bb = FF4(bb, cc, dd, aa, X[12], 6);
t = a; a = aa; aa = t;
//
// Round 2
//
a = F2(a, b, c, d, X[7], 7);
d = F2(d, a, b, c, X[4], 6);
c = F2(c, d, a, b, X[13], 8);
b = F2(b, c, d, a, X[1], 13);
a = F2(a, b, c, d, X[10], 11);
d = F2(d, a, b, c, X[6], 9);
c = F2(c, d, a, b, X[15], 7);
b = F2(b, c, d, a, X[3], 15);
a = F2(a, b, c, d, X[12], 7);
d = F2(d, a, b, c, X[0], 12);
c = F2(c, d, a, b, X[9], 15);
b = F2(b, c, d, a, X[5], 9);
a = F2(a, b, c, d, X[2], 11);
d = F2(d, a, b, c, X[14], 7);
c = F2(c, d, a, b, X[11], 13);
b = F2(b, c, d, a, X[8], 12);
aa = FF3(aa, bb, cc, dd, X[6], 9);
dd = FF3(dd, aa, bb, cc, X[11], 13);
cc = FF3(cc, dd, aa, bb, X[3], 15);
bb = FF3(bb, cc, dd, aa, X[7], 7);
aa = FF3(aa, bb, cc, dd, X[0], 12);
dd = FF3(dd, aa, bb, cc, X[13], 8);
cc = FF3(cc, dd, aa, bb, X[5], 9);
bb = FF3(bb, cc, dd, aa, X[10], 11);
aa = FF3(aa, bb, cc, dd, X[14], 7);
dd = FF3(dd, aa, bb, cc, X[15], 7);
cc = FF3(cc, dd, aa, bb, X[8], 12);
bb = FF3(bb, cc, dd, aa, X[12], 7);
aa = FF3(aa, bb, cc, dd, X[4], 6);
dd = FF3(dd, aa, bb, cc, X[9], 15);
cc = FF3(cc, dd, aa, bb, X[1], 13);
bb = FF3(bb, cc, dd, aa, X[2], 11);
t = b; b = bb; bb = t;
//
// Round 3
//
a = F3(a, b, c, d, X[3], 11);
d = F3(d, a, b, c, X[10], 13);
c = F3(c, d, a, b, X[14], 6);
b = F3(b, c, d, a, X[4], 7);
a = F3(a, b, c, d, X[9], 14);
d = F3(d, a, b, c, X[15], 9);
c = F3(c, d, a, b, X[8], 13);
b = F3(b, c, d, a, X[1], 15);
a = F3(a, b, c, d, X[2], 14);
d = F3(d, a, b, c, X[7], 8);
c = F3(c, d, a, b, X[0], 13);
b = F3(b, c, d, a, X[6], 6);
a = F3(a, b, c, d, X[13], 5);
d = F3(d, a, b, c, X[11], 12);
c = F3(c, d, a, b, X[5], 7);
b = F3(b, c, d, a, X[12], 5);
aa = FF2(aa, bb, cc, dd, X[15], 9);
dd = FF2(dd, aa, bb, cc, X[5], 7);
cc = FF2(cc, dd, aa, bb, X[1], 15);
bb = FF2(bb, cc, dd, aa, X[3], 11);
aa = FF2(aa, bb, cc, dd, X[7], 8);
dd = FF2(dd, aa, bb, cc, X[14], 6);
cc = FF2(cc, dd, aa, bb, X[6], 6);
bb = FF2(bb, cc, dd, aa, X[9], 14);
aa = FF2(aa, bb, cc, dd, X[11], 12);
dd = FF2(dd, aa, bb, cc, X[8], 13);
cc = FF2(cc, dd, aa, bb, X[12], 5);
bb = FF2(bb, cc, dd, aa, X[2], 14);
aa = FF2(aa, bb, cc, dd, X[10], 13);
dd = FF2(dd, aa, bb, cc, X[0], 13);
cc = FF2(cc, dd, aa, bb, X[4], 7);
bb = FF2(bb, cc, dd, aa, X[13], 5);
t = c; c = cc; cc = t;
//
// Round 4
//
a = F4(a, b, c, d, X[1], 11);
d = F4(d, a, b, c, X[9], 12);
c = F4(c, d, a, b, X[11], 14);
b = F4(b, c, d, a, X[10], 15);
a = F4(a, b, c, d, X[0], 14);
d = F4(d, a, b, c, X[8], 15);
c = F4(c, d, a, b, X[12], 9);
b = F4(b, c, d, a, X[4], 8);
a = F4(a, b, c, d, X[13], 9);
d = F4(d, a, b, c, X[3], 14);
c = F4(c, d, a, b, X[7], 5);
b = F4(b, c, d, a, X[15], 6);
a = F4(a, b, c, d, X[14], 8);
d = F4(d, a, b, c, X[5], 6);
c = F4(c, d, a, b, X[6], 5);
b = F4(b, c, d, a, X[2], 12);
aa = FF1(aa, bb, cc, dd, X[8], 15);
dd = FF1(dd, aa, bb, cc, X[6], 5);
cc = FF1(cc, dd, aa, bb, X[4], 8);
bb = FF1(bb, cc, dd, aa, X[1], 11);
aa = FF1(aa, bb, cc, dd, X[3], 14);
dd = FF1(dd, aa, bb, cc, X[11], 14);
cc = FF1(cc, dd, aa, bb, X[15], 6);
bb = FF1(bb, cc, dd, aa, X[0], 14);
aa = FF1(aa, bb, cc, dd, X[5], 6);
dd = FF1(dd, aa, bb, cc, X[12], 9);
cc = FF1(cc, dd, aa, bb, X[2], 12);
bb = FF1(bb, cc, dd, aa, X[13], 9);
aa = FF1(aa, bb, cc, dd, X[9], 12);
dd = FF1(dd, aa, bb, cc, X[7], 5);
cc = FF1(cc, dd, aa, bb, X[10], 15);
bb = FF1(bb, cc, dd, aa, X[14], 8);
t = d; d = dd; dd = t;
H0 += a;
H1 += b;
H2 += c;
H3 += d;
H4 += aa;
H5 += bb;
H6 += cc;
H7 += dd;
//
// reset the offset and clean out the word buffer.
//
xOff = 0;
for (int i = 0; i != X.Length; i++)
{
X[i] = 0;
}
}
public override IMemoable Copy()
{
return new RipeMD256Digest(this);
}
public override void Reset(IMemoable other)
{
RipeMD256Digest d = (RipeMD256Digest)other;
CopyIn(d);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2a14f014cfc81b3408d8336c2f7e2029
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,483 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/// <remarks>
/// <p>Implementation of RipeMD 320.</p>
/// <p><b>Note:</b> this algorithm offers the same level of security as RipeMD160.</p>
/// </remarks>
public class RipeMD320Digest
: GeneralDigest
{
public override string AlgorithmName
{
get { return "RIPEMD320"; }
}
public override int GetDigestSize()
{
return DigestLength;
}
private const int DigestLength = 40;
private int H0, H1, H2, H3, H4, H5, H6, H7, H8, H9; // IV's
private int[] X = new int[16];
private int xOff;
/// <summary> Standard constructor</summary>
public RipeMD320Digest()
{
Reset();
}
/// <summary> Copy constructor. This will copy the state of the provided
/// message digest.
/// </summary>
public RipeMD320Digest(RipeMD320Digest t)
: base(t)
{
CopyIn(t);
}
private void CopyIn(RipeMD320Digest t)
{
base.CopyIn(t);
H0 = t.H0;
H1 = t.H1;
H2 = t.H2;
H3 = t.H3;
H4 = t.H4;
H5 = t.H5;
H6 = t.H6;
H7 = t.H7;
H8 = t.H8;
H9 = t.H9;
Array.Copy(t.X, 0, X, 0, t.X.Length);
xOff = t.xOff;
}
internal override void ProcessWord(byte[] input, int inOff)
{
X[xOff++] = (int)Pack.LE_To_UInt32(input, inOff);
if (xOff == 16)
{
ProcessBlock();
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
internal override void ProcessWord(ReadOnlySpan<byte> word)
{
X[xOff++] = (int)Pack.LE_To_UInt32(word);
if (xOff == 16)
{
ProcessBlock();
}
}
#endif
internal override void ProcessLength(
long bitLength)
{
if (xOff > 14)
{
ProcessBlock();
}
X[14] = (int)(bitLength & 0xffffffff);
X[15] = (int)((ulong)bitLength >> 32);
}
public override int DoFinal(byte[] output, int outOff)
{
Finish();
Pack.UInt32_To_LE((uint)H0, output, outOff);
Pack.UInt32_To_LE((uint)H1, output, outOff + 4);
Pack.UInt32_To_LE((uint)H2, output, outOff + 8);
Pack.UInt32_To_LE((uint)H3, output, outOff + 12);
Pack.UInt32_To_LE((uint)H4, output, outOff + 16);
Pack.UInt32_To_LE((uint)H5, output, outOff + 20);
Pack.UInt32_To_LE((uint)H6, output, outOff + 24);
Pack.UInt32_To_LE((uint)H7, output, outOff + 28);
Pack.UInt32_To_LE((uint)H8, output, outOff + 32);
Pack.UInt32_To_LE((uint)H9, output, outOff + 36);
Reset();
return DigestLength;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override int DoFinal(Span<byte> output)
{
Finish();
Pack.UInt32_To_LE((uint)H0, output);
Pack.UInt32_To_LE((uint)H1, output[4..]);
Pack.UInt32_To_LE((uint)H2, output[8..]);
Pack.UInt32_To_LE((uint)H3, output[12..]);
Pack.UInt32_To_LE((uint)H4, output[16..]);
Pack.UInt32_To_LE((uint)H5, output[20..]);
Pack.UInt32_To_LE((uint)H6, output[24..]);
Pack.UInt32_To_LE((uint)H7, output[28..]);
Pack.UInt32_To_LE((uint)H8, output[32..]);
Pack.UInt32_To_LE((uint)H9, output[36..]);
Reset();
return DigestLength;
}
#endif
/// <summary> reset the chaining variables to the IV values.</summary>
public override void Reset()
{
base.Reset();
H0 = unchecked((int) 0x67452301);
H1 = unchecked((int) 0xefcdab89);
H2 = unchecked((int) 0x98badcfe);
H3 = unchecked((int) 0x10325476);
H4 = unchecked((int) 0xc3d2e1f0);
H5 = unchecked((int) 0x76543210);
H6 = unchecked((int) 0xFEDCBA98);
H7 = unchecked((int) 0x89ABCDEF);
H8 = unchecked((int) 0x01234567);
H9 = unchecked((int) 0x3C2D1E0F);
xOff = 0;
for (int i = 0; i != X.Length; i++)
{
X[i] = 0;
}
}
/*
* rotate int x left n bits.
*/
private int RL(
int x,
int n)
{
return (x << n) | (int)(((uint)x) >> (32 - n));
}
/*
* f1,f2,f3,f4,f5 are the basic RipeMD160 functions.
*/
/*
* rounds 0-15
*/
private int F1(int x, int y, int z)
{
return x ^ y ^ z;
}
/*
* rounds 16-31
*/
private int F2(int x, int y, int z)
{
return (x & y) | (~ x & z);
}
/*
* rounds 32-47
*/
private int F3(int x, int y, int z)
{
return (x | ~ y) ^ z;
}
/*
* rounds 48-63
*/
private int F4(int x, int y, int z)
{
return (x & z) | (y & ~ z);
}
/*
* rounds 64-79
*/
private int F5(int x, int y, int z)
{
return x ^ (y | ~z);
}
internal override void ProcessBlock()
{
int a, aa;
int b, bb;
int c, cc;
int d, dd;
int e, ee;
int t;
a = H0;
b = H1;
c = H2;
d = H3;
e = H4;
aa = H5;
bb = H6;
cc = H7;
dd = H8;
ee = H9;
//
// Rounds 1 - 16
//
// left
a = RL(a + F1(b, c, d) + X[0], 11) + e; c = RL(c, 10);
e = RL(e + F1(a, b, c) + X[1], 14) + d; b = RL(b, 10);
d = RL(d + F1(e, a, b) + X[2], 15) + c; a = RL(a, 10);
c = RL(c + F1(d, e, a) + X[3], 12) + b; e = RL(e, 10);
b = RL(b + F1(c, d, e) + X[4], 5) + a; d = RL(d, 10);
a = RL(a + F1(b, c, d) + X[5], 8) + e; c = RL(c, 10);
e = RL(e + F1(a, b, c) + X[6], 7) + d; b = RL(b, 10);
d = RL(d + F1(e, a, b) + X[7], 9) + c; a = RL(a, 10);
c = RL(c + F1(d, e, a) + X[8], 11) + b; e = RL(e, 10);
b = RL(b + F1(c, d, e) + X[9], 13) + a; d = RL(d, 10);
a = RL(a + F1(b, c, d) + X[10], 14) + e; c = RL(c, 10);
e = RL(e + F1(a, b, c) + X[11], 15) + d; b = RL(b, 10);
d = RL(d + F1(e, a, b) + X[12], 6) + c; a = RL(a, 10);
c = RL(c + F1(d, e, a) + X[13], 7) + b; e = RL(e, 10);
b = RL(b + F1(c, d, e) + X[14], 9) + a; d = RL(d, 10);
a = RL(a + F1(b, c, d) + X[15], 8) + e; c = RL(c, 10);
// right
aa = RL(aa + F5(bb, cc, dd) + X[5] + unchecked((int)0x50a28be6), 8) + ee; cc = RL(cc, 10);
ee = RL(ee + F5(aa, bb, cc) + X[14] + unchecked((int)0x50a28be6), 9) + dd; bb = RL(bb, 10);
dd = RL(dd + F5(ee, aa, bb) + X[7] + unchecked((int)0x50a28be6), 9) + cc; aa = RL(aa, 10);
cc = RL(cc + F5(dd, ee, aa) + X[0] + unchecked((int)0x50a28be6), 11) + bb; ee = RL(ee, 10);
bb = RL(bb + F5(cc, dd, ee) + X[9] + unchecked((int)0x50a28be6), 13) + aa; dd = RL(dd, 10);
aa = RL(aa + F5(bb, cc, dd) + X[2] + unchecked((int)0x50a28be6), 15) + ee; cc = RL(cc, 10);
ee = RL(ee + F5(aa, bb, cc) + X[11] + unchecked((int)0x50a28be6), 15) + dd; bb = RL(bb, 10);
dd = RL(dd + F5(ee, aa, bb) + X[4] + unchecked((int)0x50a28be6), 5) + cc; aa = RL(aa, 10);
cc = RL(cc + F5(dd, ee, aa) + X[13] + unchecked((int)0x50a28be6), 7) + bb; ee = RL(ee, 10);
bb = RL(bb + F5(cc, dd, ee) + X[6] + unchecked((int)0x50a28be6), 7) + aa; dd = RL(dd, 10);
aa = RL(aa + F5(bb, cc, dd) + X[15] + unchecked((int)0x50a28be6), 8) + ee; cc = RL(cc, 10);
ee = RL(ee + F5(aa, bb, cc) + X[8] + unchecked((int)0x50a28be6), 11) + dd; bb = RL(bb, 10);
dd = RL(dd + F5(ee, aa, bb) + X[1] + unchecked((int)0x50a28be6), 14) + cc; aa = RL(aa, 10);
cc = RL(cc + F5(dd, ee, aa) + X[10] + unchecked((int)0x50a28be6), 14) + bb; ee = RL(ee, 10);
bb = RL(bb + F5(cc, dd, ee) + X[3] + unchecked((int)0x50a28be6), 12) + aa; dd = RL(dd, 10);
aa = RL(aa + F5(bb, cc, dd) + X[12] + unchecked((int)0x50a28be6), 6) + ee; cc = RL(cc, 10);
t = a; a = aa; aa = t;
//
// Rounds 16-31
//
// left
e = RL(e + F2(a, b, c) + X[7] + unchecked((int)0x5a827999), 7) + d; b = RL(b, 10);
d = RL(d + F2(e, a, b) + X[4] + unchecked((int)0x5a827999), 6) + c; a = RL(a, 10);
c = RL(c + F2(d, e, a) + X[13] + unchecked((int)0x5a827999), 8) + b; e = RL(e, 10);
b = RL(b + F2(c, d, e) + X[1] + unchecked((int)0x5a827999), 13) + a; d = RL(d, 10);
a = RL(a + F2(b, c, d) + X[10] + unchecked((int)0x5a827999), 11) + e; c = RL(c, 10);
e = RL(e + F2(a, b, c) + X[6] + unchecked((int)0x5a827999), 9) + d; b = RL(b, 10);
d = RL(d + F2(e, a, b) + X[15] + unchecked((int)0x5a827999), 7) + c; a = RL(a, 10);
c = RL(c + F2(d, e, a) + X[3] + unchecked((int)0x5a827999), 15) + b; e = RL(e, 10);
b = RL(b + F2(c, d, e) + X[12] + unchecked((int)0x5a827999), 7) + a; d = RL(d, 10);
a = RL(a + F2(b, c, d) + X[0] + unchecked((int)0x5a827999), 12) + e; c = RL(c, 10);
e = RL(e + F2(a, b, c) + X[9] + unchecked((int)0x5a827999), 15) + d; b = RL(b, 10);
d = RL(d + F2(e, a, b) + X[5] + unchecked((int)0x5a827999), 9) + c; a = RL(a, 10);
c = RL(c + F2(d, e, a) + X[2] + unchecked((int)0x5a827999), 11) + b; e = RL(e, 10);
b = RL(b + F2(c, d, e) + X[14] + unchecked((int)0x5a827999), 7) + a; d = RL(d, 10);
a = RL(a + F2(b, c, d) + X[11] + unchecked((int)0x5a827999), 13) + e; c = RL(c, 10);
e = RL(e + F2(a, b, c) + X[8] + unchecked((int)0x5a827999), 12) + d; b = RL(b, 10);
// right
ee = RL(ee + F4(aa, bb, cc) + X[6] + unchecked((int)0x5c4dd124), 9) + dd; bb = RL(bb, 10);
dd = RL(dd + F4(ee, aa, bb) + X[11] + unchecked((int)0x5c4dd124), 13) + cc; aa = RL(aa, 10);
cc = RL(cc + F4(dd, ee, aa) + X[3] + unchecked((int)0x5c4dd124), 15) + bb; ee = RL(ee, 10);
bb = RL(bb + F4(cc, dd, ee) + X[7] + unchecked((int)0x5c4dd124), 7) + aa; dd = RL(dd, 10);
aa = RL(aa + F4(bb, cc, dd) + X[0] + unchecked((int)0x5c4dd124), 12) + ee; cc = RL(cc, 10);
ee = RL(ee + F4(aa, bb, cc) + X[13] + unchecked((int)0x5c4dd124), 8) + dd; bb = RL(bb, 10);
dd = RL(dd + F4(ee, aa, bb) + X[5] + unchecked((int)0x5c4dd124), 9) + cc; aa = RL(aa, 10);
cc = RL(cc + F4(dd, ee, aa) + X[10] + unchecked((int)0x5c4dd124), 11) + bb; ee = RL(ee, 10);
bb = RL(bb + F4(cc, dd, ee) + X[14] + unchecked((int)0x5c4dd124), 7) + aa; dd = RL(dd, 10);
aa = RL(aa + F4(bb, cc, dd) + X[15] + unchecked((int)0x5c4dd124), 7) + ee; cc = RL(cc, 10);
ee = RL(ee + F4(aa, bb, cc) + X[8] + unchecked((int)0x5c4dd124), 12) + dd; bb = RL(bb, 10);
dd = RL(dd + F4(ee, aa, bb) + X[12] + unchecked((int)0x5c4dd124), 7) + cc; aa = RL(aa, 10);
cc = RL(cc + F4(dd, ee, aa) + X[4] + unchecked((int)0x5c4dd124), 6) + bb; ee = RL(ee, 10);
bb = RL(bb + F4(cc, dd, ee) + X[9] + unchecked((int)0x5c4dd124), 15) + aa; dd = RL(dd, 10);
aa = RL(aa + F4(bb, cc, dd) + X[1] + unchecked((int)0x5c4dd124), 13) + ee; cc = RL(cc, 10);
ee = RL(ee + F4(aa, bb, cc) + X[2] + unchecked((int)0x5c4dd124), 11) + dd; bb = RL(bb, 10);
t = b; b = bb; bb = t;
//
// Rounds 32-47
//
// left
d = RL(d + F3(e, a, b) + X[3] + unchecked((int)0x6ed9eba1), 11) + c; a = RL(a, 10);
c = RL(c + F3(d, e, a) + X[10] + unchecked((int)0x6ed9eba1), 13) + b; e = RL(e, 10);
b = RL(b + F3(c, d, e) + X[14] + unchecked((int)0x6ed9eba1), 6) + a; d = RL(d, 10);
a = RL(a + F3(b, c, d) + X[4] + unchecked((int)0x6ed9eba1), 7) + e; c = RL(c, 10);
e = RL(e + F3(a, b, c) + X[9] + unchecked((int)0x6ed9eba1), 14) + d; b = RL(b, 10);
d = RL(d + F3(e, a, b) + X[15] + unchecked((int)0x6ed9eba1), 9) + c; a = RL(a, 10);
c = RL(c + F3(d, e, a) + X[8] + unchecked((int)0x6ed9eba1), 13) + b; e = RL(e, 10);
b = RL(b + F3(c, d, e) + X[1] + unchecked((int)0x6ed9eba1), 15) + a; d = RL(d, 10);
a = RL(a + F3(b, c, d) + X[2] + unchecked((int)0x6ed9eba1), 14) + e; c = RL(c, 10);
e = RL(e + F3(a, b, c) + X[7] + unchecked((int)0x6ed9eba1), 8) + d; b = RL(b, 10);
d = RL(d + F3(e, a, b) + X[0] + unchecked((int)0x6ed9eba1), 13) + c; a = RL(a, 10);
c = RL(c + F3(d, e, a) + X[6] + unchecked((int)0x6ed9eba1), 6) + b; e = RL(e, 10);
b = RL(b + F3(c, d, e) + X[13] + unchecked((int)0x6ed9eba1), 5) + a; d = RL(d, 10);
a = RL(a + F3(b, c, d) + X[11] + unchecked((int)0x6ed9eba1), 12) + e; c = RL(c, 10);
e = RL(e + F3(a, b, c) + X[5] + unchecked((int)0x6ed9eba1), 7) + d; b = RL(b, 10);
d = RL(d + F3(e, a, b) + X[12] + unchecked((int)0x6ed9eba1), 5) + c; a = RL(a, 10);
// right
dd = RL(dd + F3(ee, aa, bb) + X[15] + unchecked((int)0x6d703ef3), 9) + cc; aa = RL(aa, 10);
cc = RL(cc + F3(dd, ee, aa) + X[5] + unchecked((int)0x6d703ef3), 7) + bb; ee = RL(ee, 10);
bb = RL(bb + F3(cc, dd, ee) + X[1] + unchecked((int)0x6d703ef3), 15) + aa; dd = RL(dd, 10);
aa = RL(aa + F3(bb, cc, dd) + X[3] + unchecked((int)0x6d703ef3), 11) + ee; cc = RL(cc, 10);
ee = RL(ee + F3(aa, bb, cc) + X[7] + unchecked((int)0x6d703ef3), 8) + dd; bb = RL(bb, 10);
dd = RL(dd + F3(ee, aa, bb) + X[14] + unchecked((int)0x6d703ef3), 6) + cc; aa = RL(aa, 10);
cc = RL(cc + F3(dd, ee, aa) + X[6] + unchecked((int)0x6d703ef3), 6) + bb; ee = RL(ee, 10);
bb = RL(bb + F3(cc, dd, ee) + X[9] + unchecked((int)0x6d703ef3), 14) + aa; dd = RL(dd, 10);
aa = RL(aa + F3(bb, cc, dd) + X[11] + unchecked((int)0x6d703ef3), 12) + ee; cc = RL(cc, 10);
ee = RL(ee + F3(aa, bb, cc) + X[8] + unchecked((int)0x6d703ef3), 13) + dd; bb = RL(bb, 10);
dd = RL(dd + F3(ee, aa, bb) + X[12] + unchecked((int)0x6d703ef3), 5) + cc; aa = RL(aa, 10);
cc = RL(cc + F3(dd, ee, aa) + X[2] + unchecked((int)0x6d703ef3), 14) + bb; ee = RL(ee, 10);
bb = RL(bb + F3(cc, dd, ee) + X[10] + unchecked((int)0x6d703ef3), 13) + aa; dd = RL(dd, 10);
aa = RL(aa + F3(bb, cc, dd) + X[0] + unchecked((int)0x6d703ef3), 13) + ee; cc = RL(cc, 10);
ee = RL(ee + F3(aa, bb, cc) + X[4] + unchecked((int)0x6d703ef3), 7) + dd; bb = RL(bb, 10);
dd = RL(dd + F3(ee, aa, bb) + X[13] + unchecked((int)0x6d703ef3), 5) + cc; aa = RL(aa, 10);
t = c; c = cc; cc = t;
//
// Rounds 48-63
//
// left
c = RL(c + F4(d, e, a) + X[1] + unchecked((int)0x8f1bbcdc), 11) + b; e = RL(e, 10);
b = RL(b + F4(c, d, e) + X[9] + unchecked((int)0x8f1bbcdc), 12) + a; d = RL(d, 10);
a = RL(a + F4(b, c, d) + X[11] + unchecked((int)0x8f1bbcdc), 14) + e; c = RL(c, 10);
e = RL(e + F4(a, b, c) + X[10] + unchecked((int)0x8f1bbcdc), 15) + d; b = RL(b, 10);
d = RL(d + F4(e, a, b) + X[0] + unchecked((int)0x8f1bbcdc), 14) + c; a = RL(a, 10);
c = RL(c + F4(d, e, a) + X[8] + unchecked((int)0x8f1bbcdc), 15) + b; e = RL(e, 10);
b = RL(b + F4(c, d, e) + X[12] + unchecked((int)0x8f1bbcdc), 9) + a; d = RL(d, 10);
a = RL(a + F4(b, c, d) + X[4] + unchecked((int)0x8f1bbcdc), 8) + e; c = RL(c, 10);
e = RL(e + F4(a, b, c) + X[13] + unchecked((int)0x8f1bbcdc), 9) + d; b = RL(b, 10);
d = RL(d + F4(e, a, b) + X[3] + unchecked((int)0x8f1bbcdc), 14) + c; a = RL(a, 10);
c = RL(c + F4(d, e, a) + X[7] + unchecked((int)0x8f1bbcdc), 5) + b; e = RL(e, 10);
b = RL(b + F4(c, d, e) + X[15] + unchecked((int)0x8f1bbcdc), 6) + a; d = RL(d, 10);
a = RL(a + F4(b, c, d) + X[14] + unchecked((int)0x8f1bbcdc), 8) + e; c = RL(c, 10);
e = RL(e + F4(a, b, c) + X[5] + unchecked((int)0x8f1bbcdc), 6) + d; b = RL(b, 10);
d = RL(d + F4(e, a, b) + X[6] + unchecked((int)0x8f1bbcdc), 5) + c; a = RL(a, 10);
c = RL(c + F4(d, e, a) + X[2] + unchecked((int)0x8f1bbcdc), 12) + b; e = RL(e, 10);
// right
cc = RL(cc + F2(dd, ee, aa) + X[8] + unchecked((int)0x7a6d76e9), 15) + bb; ee = RL(ee, 10);
bb = RL(bb + F2(cc, dd, ee) + X[6] + unchecked((int)0x7a6d76e9), 5) + aa; dd = RL(dd, 10);
aa = RL(aa + F2(bb, cc, dd) + X[4] + unchecked((int)0x7a6d76e9), 8) + ee; cc = RL(cc, 10);
ee = RL(ee + F2(aa, bb, cc) + X[1] + unchecked((int)0x7a6d76e9), 11) + dd; bb = RL(bb, 10);
dd = RL(dd + F2(ee, aa, bb) + X[3] + unchecked((int)0x7a6d76e9), 14) + cc; aa = RL(aa, 10);
cc = RL(cc + F2(dd, ee, aa) + X[11] + unchecked((int)0x7a6d76e9), 14) + bb; ee = RL(ee, 10);
bb = RL(bb + F2(cc, dd, ee) + X[15] + unchecked((int)0x7a6d76e9), 6) + aa; dd = RL(dd, 10);
aa = RL(aa + F2(bb, cc, dd) + X[0] + unchecked((int)0x7a6d76e9), 14) + ee; cc = RL(cc, 10);
ee = RL(ee + F2(aa, bb, cc) + X[5] + unchecked((int)0x7a6d76e9), 6) + dd; bb = RL(bb, 10);
dd = RL(dd + F2(ee, aa, bb) + X[12] + unchecked((int)0x7a6d76e9), 9) + cc; aa = RL(aa, 10);
cc = RL(cc + F2(dd, ee, aa) + X[2] + unchecked((int)0x7a6d76e9), 12) + bb; ee = RL(ee, 10);
bb = RL(bb + F2(cc, dd, ee) + X[13] + unchecked((int)0x7a6d76e9), 9) + aa; dd = RL(dd, 10);
aa = RL(aa + F2(bb, cc, dd) + X[9] + unchecked((int)0x7a6d76e9), 12) + ee; cc = RL(cc, 10);
ee = RL(ee + F2(aa, bb, cc) + X[7] + unchecked((int)0x7a6d76e9), 5) + dd; bb = RL(bb, 10);
dd = RL(dd + F2(ee, aa, bb) + X[10] + unchecked((int)0x7a6d76e9), 15) + cc; aa = RL(aa, 10);
cc = RL(cc + F2(dd, ee, aa) + X[14] + unchecked((int)0x7a6d76e9), 8) + bb; ee = RL(ee, 10);
t = d; d = dd; dd = t;
//
// Rounds 64-79
//
// left
b = RL(b + F5(c, d, e) + X[4] + unchecked((int)0xa953fd4e), 9) + a; d = RL(d, 10);
a = RL(a + F5(b, c, d) + X[0] + unchecked((int)0xa953fd4e), 15) + e; c = RL(c, 10);
e = RL(e + F5(a, b, c) + X[5] + unchecked((int)0xa953fd4e), 5) + d; b = RL(b, 10);
d = RL(d + F5(e, a, b) + X[9] + unchecked((int)0xa953fd4e), 11) + c; a = RL(a, 10);
c = RL(c + F5(d, e, a) + X[7] + unchecked((int)0xa953fd4e), 6) + b; e = RL(e, 10);
b = RL(b + F5(c, d, e) + X[12] + unchecked((int)0xa953fd4e), 8) + a; d = RL(d, 10);
a = RL(a + F5(b, c, d) + X[2] + unchecked((int)0xa953fd4e), 13) + e; c = RL(c, 10);
e = RL(e + F5(a, b, c) + X[10] + unchecked((int)0xa953fd4e), 12) + d; b = RL(b, 10);
d = RL(d + F5(e, a, b) + X[14] + unchecked((int)0xa953fd4e), 5) + c; a = RL(a, 10);
c = RL(c + F5(d, e, a) + X[1] + unchecked((int)0xa953fd4e), 12) + b; e = RL(e, 10);
b = RL(b + F5(c, d, e) + X[3] + unchecked((int)0xa953fd4e), 13) + a; d = RL(d, 10);
a = RL(a + F5(b, c, d) + X[8] + unchecked((int)0xa953fd4e), 14) + e; c = RL(c, 10);
e = RL(e + F5(a, b, c) + X[11] + unchecked((int)0xa953fd4e), 11) + d; b = RL(b, 10);
d = RL(d + F5(e, a, b) + X[6] + unchecked((int)0xa953fd4e), 8) + c; a = RL(a, 10);
c = RL(c + F5(d, e, a) + X[15] + unchecked((int)0xa953fd4e), 5) + b; e = RL(e, 10);
b = RL(b + F5(c, d, e) + X[13] + unchecked((int)0xa953fd4e), 6) + a; d = RL(d, 10);
// right
bb = RL(bb + F1(cc, dd, ee) + X[12], 8) + aa; dd = RL(dd, 10);
aa = RL(aa + F1(bb, cc, dd) + X[15], 5) + ee; cc = RL(cc, 10);
ee = RL(ee + F1(aa, bb, cc) + X[10], 12) + dd; bb = RL(bb, 10);
dd = RL(dd + F1(ee, aa, bb) + X[4], 9) + cc; aa = RL(aa, 10);
cc = RL(cc + F1(dd, ee, aa) + X[1], 12) + bb; ee = RL(ee, 10);
bb = RL(bb + F1(cc, dd, ee) + X[5], 5) + aa; dd = RL(dd, 10);
aa = RL(aa + F1(bb, cc, dd) + X[8], 14) + ee; cc = RL(cc, 10);
ee = RL(ee + F1(aa, bb, cc) + X[7], 6) + dd; bb = RL(bb, 10);
dd = RL(dd + F1(ee, aa, bb) + X[6], 8) + cc; aa = RL(aa, 10);
cc = RL(cc + F1(dd, ee, aa) + X[2], 13) + bb; ee = RL(ee, 10);
bb = RL(bb + F1(cc, dd, ee) + X[13], 6) + aa; dd = RL(dd, 10);
aa = RL(aa + F1(bb, cc, dd) + X[14], 5) + ee; cc = RL(cc, 10);
ee = RL(ee + F1(aa, bb, cc) + X[0], 15) + dd; bb = RL(bb, 10);
dd = RL(dd + F1(ee, aa, bb) + X[3], 13) + cc; aa = RL(aa, 10);
cc = RL(cc + F1(dd, ee, aa) + X[9], 11) + bb; ee = RL(ee, 10);
bb = RL(bb + F1(cc, dd, ee) + X[11], 11) + aa; dd = RL(dd, 10);
//
// do (e, ee) swap as part of assignment.
//
H0 += a;
H1 += b;
H2 += c;
H3 += d;
H4 += ee;
H5 += aa;
H6 += bb;
H7 += cc;
H8 += dd;
H9 += e;
//
// reset the offset and clean out the word buffer.
//
xOff = 0;
for (int i = 0; i != X.Length; i++)
{
X[i] = 0;
}
}
public override IMemoable Copy()
{
return new RipeMD320Digest(this);
}
public override void Reset(IMemoable other)
{
RipeMD320Digest d = (RipeMD320Digest)other;
CopyIn(d);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 476882eab702ee7499a832a4de9d851b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,98 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.Diagnostics;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/// <summary>
/// Implementation of SHA-3 based on following KeccakNISTInterface.c from http://keccak.noekeon.org/
/// </summary>
/// <remarks>
/// Following the naming conventions used in the C source code to enable easy review of the implementation.
/// </remarks>
public class Sha3Digest
: KeccakDigest
{
private static int CheckBitLength(int bitLength)
{
switch (bitLength)
{
case 224:
case 256:
case 384:
case 512:
return bitLength;
default:
throw new ArgumentException(bitLength + " not supported for SHA-3", "bitLength");
}
}
public Sha3Digest()
: this(256)
{
}
public Sha3Digest(int bitLength)
: base(CheckBitLength(bitLength))
{
}
public Sha3Digest(Sha3Digest source)
: base(source)
{
}
public override string AlgorithmName
{
get { return "SHA3-" + fixedOutputLength; }
}
public override int DoFinal(byte[] output, int outOff)
{
AbsorbBits(0x02, 2);
return base.DoFinal(output, outOff);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override int DoFinal(Span<byte> output)
{
AbsorbBits(0x02, 2);
return base.DoFinal(output);
}
#endif
/*
* TODO Possible API change to support partial-byte suffixes.
*/
protected override int DoFinal(byte[] output, int outOff, byte partialByte, int partialBits)
{
if (partialBits < 0 || partialBits > 7)
throw new ArgumentException("must be in the range [0,7]", "partialBits");
int finalInput = (partialByte & ((1 << partialBits) - 1)) | (0x02 << partialBits);
Debug.Assert(finalInput >= 0);
int finalBits = partialBits + 2;
if (finalBits >= 8)
{
Absorb((byte)finalInput);
finalBits -= 8;
finalInput >>= 8;
}
return base.DoFinal(output, outOff, (byte)finalInput, finalBits);
}
public override IMemoable Copy()
{
return new Sha3Digest(this);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 88fb31baea5cef347af0fcbaa0d0cbc4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,344 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/// <summary>
/// Implementation of Chinese SM3 digest as described at
/// http://tools.ietf.org/html/draft-shen-sm3-hash-00
/// and at .... ( Chinese PDF )
/// </summary>
/// <remarks>
/// The specification says "process a bit stream",
/// but this is written to process bytes in blocks of 4,
/// meaning this will process 32-bit word groups.
/// But so do also most other digest specifications,
/// including the SHA-256 which was a origin for
/// this specification.
/// </remarks>
public class SM3Digest
: GeneralDigest
{
private const int DIGEST_LENGTH = 32; // bytes
private const int BLOCK_SIZE = 64 / 4; // of 32 bit ints (16 ints)
private uint[] V = new uint[DIGEST_LENGTH / 4]; // in 32 bit ints (8 ints)
private uint[] inwords = new uint[BLOCK_SIZE];
private int xOff;
// Work-bufs used within processBlock()
private uint[] W = new uint[68];
// Round constant T for processBlock() which is 32 bit integer rolled left up to (63 MOD 32) bit positions.
private static readonly uint[] T = new uint[64];
static SM3Digest()
{
for (int i = 0; i < 16; ++i)
{
uint t = 0x79CC4519;
T[i] = (t << i) | (t >> (32 - i));
}
for (int i = 16; i < 64; ++i)
{
int n = i % 32;
uint t = 0x7A879D8A;
T[i] = (t << n) | (t >> (32 - n));
}
}
/// <summary>
/// Standard constructor
/// </summary>
public SM3Digest()
{
Reset();
}
/// <summary>
/// Copy constructor. This will copy the state of the provided
/// message digest.
/// </summary>
public SM3Digest(SM3Digest t)
: base(t)
{
CopyIn(t);
}
private void CopyIn(SM3Digest t)
{
Array.Copy(t.V, 0, this.V, 0, this.V.Length);
Array.Copy(t.inwords, 0, this.inwords, 0, this.inwords.Length);
xOff = t.xOff;
}
public override string AlgorithmName
{
get { return "SM3"; }
}
public override int GetDigestSize()
{
return DIGEST_LENGTH;
}
public override IMemoable Copy()
{
return new SM3Digest(this);
}
public override void Reset(IMemoable other)
{
SM3Digest d = (SM3Digest)other;
base.CopyIn(d);
CopyIn(d);
}
/// <summary>
/// reset the chaining variables
/// </summary>
public override void Reset()
{
base.Reset();
this.V[0] = 0x7380166F;
this.V[1] = 0x4914B2B9;
this.V[2] = 0x172442D7;
this.V[3] = 0xDA8A0600;
this.V[4] = 0xA96F30BC;
this.V[5] = 0x163138AA;
this.V[6] = 0xE38DEE4D;
this.V[7] = 0xB0FB0E4E;
this.xOff = 0;
}
public override int DoFinal(byte[] output, int outOff)
{
Finish();
Pack.UInt32_To_BE(V, output, outOff);
Reset();
return DIGEST_LENGTH;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override int DoFinal(Span<byte> output)
{
Finish();
Pack.UInt32_To_BE(V, output);
Reset();
return DIGEST_LENGTH;
}
#endif
internal override void ProcessWord(byte[] input, int inOff)
{
inwords[xOff++] = Pack.BE_To_UInt32(input, inOff);
if (this.xOff >= 16)
{
ProcessBlock();
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
internal override void ProcessWord(ReadOnlySpan<byte> word)
{
inwords[xOff++] = Pack.BE_To_UInt32(word);
if (this.xOff >= 16)
{
ProcessBlock();
}
}
#endif
internal override void ProcessLength(long bitLength)
{
if (this.xOff > (BLOCK_SIZE - 2))
{
// xOff == 15 --> can't fit the 64 bit length field at tail..
this.inwords[this.xOff] = 0; // fill with zero
++this.xOff;
ProcessBlock();
}
// Fill with zero words, until reach 2nd to last slot
while (this.xOff < (BLOCK_SIZE - 2))
{
this.inwords[this.xOff] = 0;
++this.xOff;
}
// Store input data length in BITS
this.inwords[this.xOff++] = (uint)(bitLength >> 32);
this.inwords[this.xOff++] = (uint)(bitLength);
}
/*
3.4.2. Constants
Tj = 79cc4519 when 0 < = j < = 15
Tj = 7a879d8a when 16 < = j < = 63
3.4.3. Boolean function
FFj(X;Y;Z) = X XOR Y XOR Z when 0 < = j < = 15
= (X AND Y) OR (X AND Z) OR (Y AND Z) when 16 < = j < = 63
GGj(X;Y;Z) = X XOR Y XOR Z when 0 < = j < = 15
= (X AND Y) OR (NOT X AND Z) when 16 < = j < = 63
The X, Y, Z in the fomular are words!GBP
3.4.4. Permutation function
P0(X) = X XOR (X <<< 9) XOR (X <<< 17) ## ROLL, not SHIFT
P1(X) = X XOR (X <<< 15) XOR (X <<< 23) ## ROLL, not SHIFT
The X in the fomular are a word.
----------
Each ROLL converted to Java expression:
ROLL 9 : ((x << 9) | (x >> (32-9))))
ROLL 17 : ((x << 17) | (x >> (32-17)))
ROLL 15 : ((x << 15) | (x >> (32-15)))
ROLL 23 : ((x << 23) | (x >> (32-23)))
*/
private uint P0(uint x)
{
uint r9 = ((x << 9) | (x >> (32 - 9)));
uint r17 = ((x << 17) | (x >> (32 - 17)));
return (x ^ r9 ^ r17);
}
private uint P1(uint x)
{
uint r15 = ((x << 15) | (x >> (32 - 15)));
uint r23 = ((x << 23) | (x >> (32 - 23)));
return (x ^ r15 ^ r23);
}
private uint FF0(uint x, uint y, uint z)
{
return (x ^ y ^ z);
}
private uint FF1(uint x, uint y, uint z)
{
return ((x & y) | (x & z) | (y & z));
}
private uint GG0(uint x, uint y, uint z)
{
return (x ^ y ^ z);
}
private uint GG1(uint x, uint y, uint z)
{
return ((x & y) | ((~x) & z));
}
internal override void ProcessBlock()
{
for (int j = 0; j < 16; ++j)
{
this.W[j] = this.inwords[j];
}
for (int j = 16; j < 68; ++j)
{
uint wj3 = this.W[j - 3];
uint r15 = ((wj3 << 15) | (wj3 >> (32 - 15)));
uint wj13 = this.W[j - 13];
uint r7 = ((wj13 << 7) | (wj13 >> (32 - 7)));
this.W[j] = P1(this.W[j - 16] ^ this.W[j - 9] ^ r15) ^ r7 ^ this.W[j - 6];
}
uint A = this.V[0];
uint B = this.V[1];
uint C = this.V[2];
uint D = this.V[3];
uint E = this.V[4];
uint F = this.V[5];
uint G = this.V[6];
uint H = this.V[7];
for (int j = 0; j < 16; ++j)
{
uint a12 = ((A << 12) | (A >> (32 - 12)));
uint s1_ = a12 + E + T[j];
uint SS1 = ((s1_ << 7) | (s1_ >> (32 - 7)));
uint SS2 = SS1 ^ a12;
uint Wj = W[j];
uint W1j = Wj ^ W[j + 4];
uint TT1 = FF0(A, B, C) + D + SS2 + W1j;
uint TT2 = GG0(E, F, G) + H + SS1 + Wj;
D = C;
C = ((B << 9) | (B >> (32 - 9)));
B = A;
A = TT1;
H = G;
G = ((F << 19) | (F >> (32 - 19)));
F = E;
E = P0(TT2);
}
// Different FF,GG functions on rounds 16..63
for (int j = 16; j < 64; ++j)
{
uint a12 = ((A << 12) | (A >> (32 - 12)));
uint s1_ = a12 + E + T[j];
uint SS1 = ((s1_ << 7) | (s1_ >> (32 - 7)));
uint SS2 = SS1 ^ a12;
uint Wj = W[j];
uint W1j = Wj ^ W[j + 4];
uint TT1 = FF1(A, B, C) + D + SS2 + W1j;
uint TT2 = GG1(E, F, G) + H + SS1 + Wj;
D = C;
C = ((B << 9) | (B >> (32 - 9)));
B = A;
A = TT1;
H = G;
G = ((F << 19) | (F >> (32 - 19)));
F = E;
E = P0(TT2);
}
this.V[0] ^= A;
this.V[1] ^= B;
this.V[2] ^= C;
this.V[3] ^= D;
this.V[4] ^= E;
this.V[5] ^= F;
this.V[6] ^= G;
this.V[7] ^= H;
this.xOff = 0;
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0589b095ef908cc4abad41f8b206686b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,314 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/**
* implementation of SHA-1 as outlined in "Handbook of Applied Cryptography", pages 346 - 349.
*
* It is interesting to ponder why the, apart from the extra IV, the other difference here from MD5
* is the "endianness" of the word processing!
*/
public class Sha1Digest
: GeneralDigest
{
private const int DigestLength = 20;
private uint H1, H2, H3, H4, H5;
private uint[] X = new uint[80];
private int xOff;
public Sha1Digest()
{
Reset();
}
/**
* Copy constructor. This will copy the state of the provided
* message digest.
*/
public Sha1Digest(Sha1Digest t)
: base(t)
{
CopyIn(t);
}
private void CopyIn(Sha1Digest t)
{
base.CopyIn(t);
H1 = t.H1;
H2 = t.H2;
H3 = t.H3;
H4 = t.H4;
H5 = t.H5;
Array.Copy(t.X, 0, X, 0, t.X.Length);
xOff = t.xOff;
}
public override string AlgorithmName
{
get { return "SHA-1"; }
}
public override int GetDigestSize()
{
return DigestLength;
}
internal override void ProcessWord(byte[] input, int inOff)
{
X[xOff] = Pack.BE_To_UInt32(input, inOff);
if (++xOff == 16)
{
ProcessBlock();
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
internal override void ProcessWord(ReadOnlySpan<byte> word)
{
X[xOff] = Pack.BE_To_UInt32(word);
if (++xOff == 16)
{
ProcessBlock();
}
}
#endif
internal override void ProcessLength(long bitLength)
{
if (xOff > 14)
{
ProcessBlock();
}
X[14] = (uint)((ulong)bitLength >> 32);
X[15] = (uint)((ulong)bitLength);
}
public override int DoFinal(
byte[] output,
int outOff)
{
Finish();
Pack.UInt32_To_BE(H1, output, outOff);
Pack.UInt32_To_BE(H2, output, outOff + 4);
Pack.UInt32_To_BE(H3, output, outOff + 8);
Pack.UInt32_To_BE(H4, output, outOff + 12);
Pack.UInt32_To_BE(H5, output, outOff + 16);
Reset();
return DigestLength;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override int DoFinal(Span<byte> output)
{
Finish();
Pack.UInt32_To_BE(H1, output);
Pack.UInt32_To_BE(H2, output[4..]);
Pack.UInt32_To_BE(H3, output[8..]);
Pack.UInt32_To_BE(H4, output[12..]);
Pack.UInt32_To_BE(H5, output[16..]);
Reset();
return DigestLength;
}
#endif
/**
* reset the chaining variables
*/
public override void Reset()
{
base.Reset();
H1 = 0x67452301;
H2 = 0xefcdab89;
H3 = 0x98badcfe;
H4 = 0x10325476;
H5 = 0xc3d2e1f0;
xOff = 0;
Array.Clear(X, 0, X.Length);
}
//
// Additive constants
//
private const uint Y1 = 0x5a827999;
private const uint Y2 = 0x6ed9eba1;
private const uint Y3 = 0x8f1bbcdc;
private const uint Y4 = 0xca62c1d6;
private static uint F(uint u, uint v, uint w)
{
return (u & v) | (~u & w);
}
private static uint H(uint u, uint v, uint w)
{
return u ^ v ^ w;
}
private static uint G(uint u, uint v, uint w)
{
return (u & v) | (u & w) | (v & w);
}
internal override void ProcessBlock()
{
//
// expand 16 word block into 80 word block.
//
for (int i = 16; i < 80; i++)
{
uint t = X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16];
X[i] = t << 1 | t >> 31;
}
//
// set up working variables.
//
uint A = H1;
uint B = H2;
uint C = H3;
uint D = H4;
uint E = H5;
//
// round 1
//
int idx = 0;
for (int j = 0; j < 4; j++)
{
// E = rotateLeft(A, 5) + F(B, C, D) + E + X[idx++] + Y1
// B = rotateLeft(B, 30)
E += (A << 5 | (A >> 27)) + F(B, C, D) + X[idx++] + Y1;
B = B << 30 | (B >> 2);
D += (E << 5 | (E >> 27)) + F(A, B, C) + X[idx++] + Y1;
A = A << 30 | (A >> 2);
C += (D << 5 | (D >> 27)) + F(E, A, B) + X[idx++] + Y1;
E = E << 30 | (E >> 2);
B += (C << 5 | (C >> 27)) + F(D, E, A) + X[idx++] + Y1;
D = D << 30 | (D >> 2);
A += (B << 5 | (B >> 27)) + F(C, D, E) + X[idx++] + Y1;
C = C << 30 | (C >> 2);
}
//
// round 2
//
for (int j = 0; j < 4; j++)
{
// E = rotateLeft(A, 5) + H(B, C, D) + E + X[idx++] + Y2
// B = rotateLeft(B, 30)
E += (A << 5 | (A >> 27)) + H(B, C, D) + X[idx++] + Y2;
B = B << 30 | (B >> 2);
D += (E << 5 | (E >> 27)) + H(A, B, C) + X[idx++] + Y2;
A = A << 30 | (A >> 2);
C += (D << 5 | (D >> 27)) + H(E, A, B) + X[idx++] + Y2;
E = E << 30 | (E >> 2);
B += (C << 5 | (C >> 27)) + H(D, E, A) + X[idx++] + Y2;
D = D << 30 | (D >> 2);
A += (B << 5 | (B >> 27)) + H(C, D, E) + X[idx++] + Y2;
C = C << 30 | (C >> 2);
}
//
// round 3
//
for (int j = 0; j < 4; j++)
{
// E = rotateLeft(A, 5) + G(B, C, D) + E + X[idx++] + Y3
// B = rotateLeft(B, 30)
E += (A << 5 | (A >> 27)) + G(B, C, D) + X[idx++] + Y3;
B = B << 30 | (B >> 2);
D += (E << 5 | (E >> 27)) + G(A, B, C) + X[idx++] + Y3;
A = A << 30 | (A >> 2);
C += (D << 5 | (D >> 27)) + G(E, A, B) + X[idx++] + Y3;
E = E << 30 | (E >> 2);
B += (C << 5 | (C >> 27)) + G(D, E, A) + X[idx++] + Y3;
D = D << 30 | (D >> 2);
A += (B << 5 | (B >> 27)) + G(C, D, E) + X[idx++] + Y3;
C = C << 30 | (C >> 2);
}
//
// round 4
//
for (int j = 0; j < 4; j++)
{
// E = rotateLeft(A, 5) + H(B, C, D) + E + X[idx++] + Y4
// B = rotateLeft(B, 30)
E += (A << 5 | (A >> 27)) + H(B, C, D) + X[idx++] + Y4;
B = B << 30 | (B >> 2);
D += (E << 5 | (E >> 27)) + H(A, B, C) + X[idx++] + Y4;
A = A << 30 | (A >> 2);
C += (D << 5 | (D >> 27)) + H(E, A, B) + X[idx++] + Y4;
E = E << 30 | (E >> 2);
B += (C << 5 | (C >> 27)) + H(D, E, A) + X[idx++] + Y4;
D = D << 30 | (D >> 2);
A += (B << 5 | (B >> 27)) + H(C, D, E) + X[idx++] + Y4;
C = C << 30 | (C >> 2);
}
H1 += A;
H2 += B;
H3 += C;
H4 += D;
H5 += E;
//
// reset start of the buffer.
//
xOff = 0;
Array.Clear(X, 0, 16);
}
public override IMemoable Copy()
{
return new Sha1Digest(this);
}
public override void Reset(IMemoable other)
{
Sha1Digest d = (Sha1Digest)other;
CopyIn(d);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 41a426a9144a0d14c89f165afedfd344
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,319 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/**
* SHA-224 as described in RFC 3874
* <pre>
* block word digest
* SHA-1 512 32 160
* SHA-224 512 32 224
* SHA-256 512 32 256
* SHA-384 1024 64 384
* SHA-512 1024 64 512
* </pre>
*/
public class Sha224Digest
: GeneralDigest
{
private const int DigestLength = 28;
private uint H1, H2, H3, H4, H5, H6, H7, H8;
private uint[] X = new uint[64];
private int xOff;
/**
* Standard constructor
*/
public Sha224Digest()
{
Reset();
}
/**
* Copy constructor. This will copy the state of the provided
* message digest.
*/
public Sha224Digest(
Sha224Digest t)
: base(t)
{
CopyIn(t);
}
private void CopyIn(Sha224Digest t)
{
base.CopyIn(t);
H1 = t.H1;
H2 = t.H2;
H3 = t.H3;
H4 = t.H4;
H5 = t.H5;
H6 = t.H6;
H7 = t.H7;
H8 = t.H8;
Array.Copy(t.X, 0, X, 0, t.X.Length);
xOff = t.xOff;
}
public override string AlgorithmName
{
get { return "SHA-224"; }
}
public override int GetDigestSize()
{
return DigestLength;
}
internal override void ProcessWord(byte[] input, int inOff)
{
X[xOff] = Pack.BE_To_UInt32(input, inOff);
if (++xOff == 16)
{
ProcessBlock();
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
internal override void ProcessWord(ReadOnlySpan<byte> word)
{
X[xOff] = Pack.BE_To_UInt32(word);
if (++xOff == 16)
{
ProcessBlock();
}
}
#endif
internal override void ProcessLength(
long bitLength)
{
if (xOff > 14)
{
ProcessBlock();
}
X[14] = (uint)((ulong)bitLength >> 32);
X[15] = (uint)((ulong)bitLength);
}
public override int DoFinal(byte[] output, int outOff)
{
Finish();
Pack.UInt32_To_BE(H1, output, outOff);
Pack.UInt32_To_BE(H2, output, outOff + 4);
Pack.UInt32_To_BE(H3, output, outOff + 8);
Pack.UInt32_To_BE(H4, output, outOff + 12);
Pack.UInt32_To_BE(H5, output, outOff + 16);
Pack.UInt32_To_BE(H6, output, outOff + 20);
Pack.UInt32_To_BE(H7, output, outOff + 24);
Reset();
return DigestLength;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override int DoFinal(Span<byte> output)
{
Finish();
Pack.UInt32_To_BE(H1, output);
Pack.UInt32_To_BE(H2, output[4..]);
Pack.UInt32_To_BE(H3, output[8..]);
Pack.UInt32_To_BE(H4, output[12..]);
Pack.UInt32_To_BE(H5, output[16..]);
Pack.UInt32_To_BE(H6, output[20..]);
Pack.UInt32_To_BE(H7, output[24..]);
Reset();
return DigestLength;
}
#endif
/**
* reset the chaining variables
*/
public override void Reset()
{
base.Reset();
/* SHA-224 initial hash value
*/
H1 = 0xc1059ed8;
H2 = 0x367cd507;
H3 = 0x3070dd17;
H4 = 0xf70e5939;
H5 = 0xffc00b31;
H6 = 0x68581511;
H7 = 0x64f98fa7;
H8 = 0xbefa4fa4;
xOff = 0;
Array.Clear(X, 0, X.Length);
}
internal override void ProcessBlock()
{
//
// expand 16 word block into 64 word blocks.
//
for (int ti = 16; ti <= 63; ti++)
{
X[ti] = Theta1(X[ti - 2]) + X[ti - 7] + Theta0(X[ti - 15]) + X[ti - 16];
}
//
// set up working variables.
//
uint a = H1;
uint b = H2;
uint c = H3;
uint d = H4;
uint e = H5;
uint f = H6;
uint g = H7;
uint h = H8;
int t = 0;
for(int i = 0; i < 8; i ++)
{
// t = 8 * i
h += Sum1(e) + Ch(e, f, g) + K[t] + X[t];
d += h;
h += Sum0(a) + Maj(a, b, c);
++t;
// t = 8 * i + 1
g += Sum1(d) + Ch(d, e, f) + K[t] + X[t];
c += g;
g += Sum0(h) + Maj(h, a, b);
++t;
// t = 8 * i + 2
f += Sum1(c) + Ch(c, d, e) + K[t] + X[t];
b += f;
f += Sum0(g) + Maj(g, h, a);
++t;
// t = 8 * i + 3
e += Sum1(b) + Ch(b, c, d) + K[t] + X[t];
a += e;
e += Sum0(f) + Maj(f, g, h);
++t;
// t = 8 * i + 4
d += Sum1(a) + Ch(a, b, c) + K[t] + X[t];
h += d;
d += Sum0(e) + Maj(e, f, g);
++t;
// t = 8 * i + 5
c += Sum1(h) + Ch(h, a, b) + K[t] + X[t];
g += c;
c += Sum0(d) + Maj(d, e, f);
++t;
// t = 8 * i + 6
b += Sum1(g) + Ch(g, h, a) + K[t] + X[t];
f += b;
b += Sum0(c) + Maj(c, d, e);
++t;
// t = 8 * i + 7
a += Sum1(f) + Ch(f, g, h) + K[t] + X[t];
e += a;
a += Sum0(b) + Maj(b, c, d);
++t;
}
H1 += a;
H2 += b;
H3 += c;
H4 += d;
H5 += e;
H6 += f;
H7 += g;
H8 += h;
//
// reset the offset and clean out the word buffer.
//
xOff = 0;
Array.Clear(X, 0, 16);
}
/* SHA-224 functions */
private static uint Ch(uint x, uint y, uint z)
{
return (x & y) ^ (~x & z);
}
private static uint Maj(uint x, uint y, uint z)
{
return (x & y) ^ (x & z) ^ (y & z);
}
private static uint Sum0(uint x)
{
return ((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10));
}
private static uint Sum1(uint x)
{
return ((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7));
}
private static uint Theta0(uint x)
{
return ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ (x >> 3);
}
private static uint Theta1(uint x)
{
return ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ (x >> 10);
}
/* SHA-224 Constants
* (represent the first 32 bits of the fractional parts of the
* cube roots of the first sixty-four prime numbers)
*/
internal static readonly uint[] K = {
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
};
public override IMemoable Copy()
{
return new Sha224Digest(this);
}
public override void Reset(IMemoable other)
{
Sha224Digest d = (Sha224Digest)other;
CopyIn(d);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 196dff09414f1c54d8fadd93e2f6f434
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,349 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/**
* Draft FIPS 180-2 implementation of SHA-256. <b>Note:</b> As this is
* based on a draft this implementation is subject to change.
*
* <pre>
* block word digest
* SHA-1 512 32 160
* SHA-256 512 32 256
* SHA-384 1024 64 384
* SHA-512 1024 64 512
* </pre>
*/
public class Sha256Digest
: GeneralDigest
{
private const int DigestLength = 32;
private uint H1, H2, H3, H4, H5, H6, H7, H8;
private uint[] X = new uint[64];
private int xOff;
public Sha256Digest()
{
initHs();
}
/**
* Copy constructor. This will copy the state of the provided
* message digest.
*/
public Sha256Digest(Sha256Digest t) : base(t)
{
CopyIn(t);
}
private void CopyIn(Sha256Digest t)
{
base.CopyIn(t);
H1 = t.H1;
H2 = t.H2;
H3 = t.H3;
H4 = t.H4;
H5 = t.H5;
H6 = t.H6;
H7 = t.H7;
H8 = t.H8;
Array.Copy(t.X, 0, X, 0, t.X.Length);
xOff = t.xOff;
}
public override string AlgorithmName
{
get { return "SHA-256"; }
}
public override int GetDigestSize()
{
return DigestLength;
}
internal override void ProcessWord(byte[] input, int inOff)
{
X[xOff] = Pack.BE_To_UInt32(input, inOff);
if (++xOff == 16)
{
ProcessBlock();
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
internal override void ProcessWord(ReadOnlySpan<byte> word)
{
X[xOff] = Pack.BE_To_UInt32(word);
if (++xOff == 16)
{
ProcessBlock();
}
}
#endif
internal override void ProcessLength(
long bitLength)
{
if (xOff > 14)
{
ProcessBlock();
}
X[14] = (uint)((ulong)bitLength >> 32);
X[15] = (uint)((ulong)bitLength);
}
public override int DoFinal(byte[] output, int outOff)
{
Finish();
Pack.UInt32_To_BE(H1, output, outOff);
Pack.UInt32_To_BE(H2, output, outOff + 4);
Pack.UInt32_To_BE(H3, output, outOff + 8);
Pack.UInt32_To_BE(H4, output, outOff + 12);
Pack.UInt32_To_BE(H5, output, outOff + 16);
Pack.UInt32_To_BE(H6, output, outOff + 20);
Pack.UInt32_To_BE(H7, output, outOff + 24);
Pack.UInt32_To_BE(H8, output, outOff + 28);
Reset();
return DigestLength;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override int DoFinal(Span<byte> output)
{
Finish();
Pack.UInt32_To_BE(H1, output);
Pack.UInt32_To_BE(H2, output[4..]);
Pack.UInt32_To_BE(H3, output[8..]);
Pack.UInt32_To_BE(H4, output[12..]);
Pack.UInt32_To_BE(H5, output[16..]);
Pack.UInt32_To_BE(H6, output[20..]);
Pack.UInt32_To_BE(H7, output[24..]);
Pack.UInt32_To_BE(H8, output[28..]);
Reset();
return DigestLength;
}
#endif
/**
* reset the chaining variables
*/
public override void Reset()
{
base.Reset();
initHs();
xOff = 0;
Array.Clear(X, 0, X.Length);
}
private void initHs()
{
/* SHA-256 initial hash value
* The first 32 bits of the fractional parts of the square roots
* of the first eight prime numbers
*/
H1 = 0x6a09e667;
H2 = 0xbb67ae85;
H3 = 0x3c6ef372;
H4 = 0xa54ff53a;
H5 = 0x510e527f;
H6 = 0x9b05688c;
H7 = 0x1f83d9ab;
H8 = 0x5be0cd19;
}
internal override void ProcessBlock()
{
//
// expand 16 word block into 64 word blocks.
//
for (int ti = 16; ti <= 63; ti++)
{
X[ti] = Theta1(X[ti - 2]) + X[ti - 7] + Theta0(X[ti - 15]) + X[ti - 16];
}
//
// set up working variables.
//
uint a = H1;
uint b = H2;
uint c = H3;
uint d = H4;
uint e = H5;
uint f = H6;
uint g = H7;
uint h = H8;
int t = 0;
for(int i = 0; i < 8; ++i)
{
// t = 8 * i
h += Sum1Ch(e, f, g) + K[t] + X[t];
d += h;
h += Sum0Maj(a, b, c);
++t;
// t = 8 * i + 1
g += Sum1Ch(d, e, f) + K[t] + X[t];
c += g;
g += Sum0Maj(h, a, b);
++t;
// t = 8 * i + 2
f += Sum1Ch(c, d, e) + K[t] + X[t];
b += f;
f += Sum0Maj(g, h, a);
++t;
// t = 8 * i + 3
e += Sum1Ch(b, c, d) + K[t] + X[t];
a += e;
e += Sum0Maj(f, g, h);
++t;
// t = 8 * i + 4
d += Sum1Ch(a, b, c) + K[t] + X[t];
h += d;
d += Sum0Maj(e, f, g);
++t;
// t = 8 * i + 5
c += Sum1Ch(h, a, b) + K[t] + X[t];
g += c;
c += Sum0Maj(d, e, f);
++t;
// t = 8 * i + 6
b += Sum1Ch(g, h, a) + K[t] + X[t];
f += b;
b += Sum0Maj(c, d, e);
++t;
// t = 8 * i + 7
a += Sum1Ch(f, g, h) + K[t] + X[t];
e += a;
a += Sum0Maj(b, c, d);
++t;
}
H1 += a;
H2 += b;
H3 += c;
H4 += d;
H5 += e;
H6 += f;
H7 += g;
H8 += h;
//
// reset the offset and clean out the word buffer.
//
xOff = 0;
Array.Clear(X, 0, 16);
}
private static uint Sum1Ch(uint x, uint y, uint z)
{
// return Sum1(x) + Ch(x, y, z);
return (((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7)))
//+ ((x & y) ^ ((~x) & z));
+ (z ^ (x & (y ^ z)));
}
private static uint Sum0Maj(uint x, uint y, uint z)
{
// return Sum0(x) + Maj(x, y, z);
return (((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10)))
//+ ((x & y) ^ (x & z) ^ (y & z));
+ ((x & y) | (z & (x ^ y)));
}
// /* SHA-256 functions */
// private static uint Ch(uint x, uint y, uint z)
// {
// return (x & y) ^ ((~x) & z);
// //return z ^ (x & (y ^ z));
// }
//
// private static uint Maj(uint x, uint y, uint z)
// {
// //return (x & y) ^ (x & z) ^ (y & z);
// return (x & y) | (z & (x ^ y));
// }
//
// private static uint Sum0(uint x)
// {
// return ((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10));
// }
//
// private static uint Sum1(uint x)
// {
// return ((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7));
// }
private static uint Theta0(uint x)
{
return ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ (x >> 3);
}
private static uint Theta1(uint x)
{
return ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ (x >> 10);
}
/* SHA-256 Constants
* (represent the first 32 bits of the fractional parts of the
* cube roots of the first sixty-four prime numbers)
*/
private static readonly uint[] K = {
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
};
public override IMemoable Copy()
{
return new Sha256Digest(this);
}
public override void Reset(IMemoable other)
{
Sha256Digest d = (Sha256Digest)other;
CopyIn(d);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c7ab212094fb3c944884279b4171f310
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,122 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/**
* Draft FIPS 180-2 implementation of SHA-384. <b>Note:</b> As this is
* based on a draft this implementation is subject to change.
*
* <pre>
* block word digest
* SHA-1 512 32 160
* SHA-256 512 32 256
* SHA-384 1024 64 384
* SHA-512 1024 64 512
* </pre>
*/
public class Sha384Digest
: LongDigest
{
private const int DigestLength = 48;
public Sha384Digest()
{
}
/**
* Copy constructor. This will copy the state of the provided
* message digest.
*/
public Sha384Digest(
Sha384Digest t)
: base(t)
{
}
public override string AlgorithmName
{
get { return "SHA-384"; }
}
public override int GetDigestSize()
{
return DigestLength;
}
public override int DoFinal(
byte[] output,
int outOff)
{
Finish();
Pack.UInt64_To_BE(H1, output, outOff);
Pack.UInt64_To_BE(H2, output, outOff + 8);
Pack.UInt64_To_BE(H3, output, outOff + 16);
Pack.UInt64_To_BE(H4, output, outOff + 24);
Pack.UInt64_To_BE(H5, output, outOff + 32);
Pack.UInt64_To_BE(H6, output, outOff + 40);
Reset();
return DigestLength;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override int DoFinal(Span<byte> output)
{
Finish();
Pack.UInt64_To_BE(H1, output);
Pack.UInt64_To_BE(H2, output[8..]);
Pack.UInt64_To_BE(H3, output[16..]);
Pack.UInt64_To_BE(H4, output[24..]);
Pack.UInt64_To_BE(H5, output[32..]);
Pack.UInt64_To_BE(H6, output[40..]);
Reset();
return DigestLength;
}
#endif
/**
* reset the chaining variables
*/
public override void Reset()
{
base.Reset();
/* SHA-384 initial hash value
* The first 64 bits of the fractional parts of the square roots
* of the 9th through 16th prime numbers
*/
H1 = 0xcbbb9d5dc1059ed8;
H2 = 0x629a292a367cd507;
H3 = 0x9159015a3070dd17;
H4 = 0x152fecd8f70e5939;
H5 = 0x67332667ffc00b31;
H6 = 0x8eb44a8768581511;
H7 = 0xdb0c2e0d64f98fa7;
H8 = 0x47b5481dbefa4fa4;
}
public override IMemoable Copy()
{
return new Sha384Digest(this);
}
public override void Reset(IMemoable other)
{
Sha384Digest d = (Sha384Digest)other;
CopyIn(d);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7f6cc67018dd5fa4eacd17db15740561
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,127 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/**
* Draft FIPS 180-2 implementation of SHA-512. <b>Note:</b> As this is
* based on a draft this implementation is subject to change.
*
* <pre>
* block word digest
* SHA-1 512 32 160
* SHA-256 512 32 256
* SHA-384 1024 64 384
* SHA-512 1024 64 512
* </pre>
*/
public class Sha512Digest
: LongDigest
{
private const int DigestLength = 64;
public Sha512Digest()
{
}
/**
* Copy constructor. This will copy the state of the provided
* message digest.
*/
public Sha512Digest(
Sha512Digest t)
: base(t)
{
}
public override string AlgorithmName
{
get { return "SHA-512"; }
}
public override int GetDigestSize()
{
return DigestLength;
}
public override int DoFinal(
byte[] output,
int outOff)
{
Finish();
Pack.UInt64_To_BE(H1, output, outOff);
Pack.UInt64_To_BE(H2, output, outOff + 8);
Pack.UInt64_To_BE(H3, output, outOff + 16);
Pack.UInt64_To_BE(H4, output, outOff + 24);
Pack.UInt64_To_BE(H5, output, outOff + 32);
Pack.UInt64_To_BE(H6, output, outOff + 40);
Pack.UInt64_To_BE(H7, output, outOff + 48);
Pack.UInt64_To_BE(H8, output, outOff + 56);
Reset();
return DigestLength;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override int DoFinal(Span<byte> output)
{
Finish();
Pack.UInt64_To_BE(H1, output);
Pack.UInt64_To_BE(H2, output[8..]);
Pack.UInt64_To_BE(H3, output[16..]);
Pack.UInt64_To_BE(H4, output[24..]);
Pack.UInt64_To_BE(H5, output[32..]);
Pack.UInt64_To_BE(H6, output[40..]);
Pack.UInt64_To_BE(H7, output[48..]);
Pack.UInt64_To_BE(H8, output[56..]);
Reset();
return DigestLength;
}
#endif
/**
* reset the chaining variables
*/
public override void Reset()
{
base.Reset();
/* SHA-512 initial hash value
* The first 64 bits of the fractional parts of the square roots
* of the first eight prime numbers
*/
H1 = 0x6a09e667f3bcc908;
H2 = 0xbb67ae8584caa73b;
H3 = 0x3c6ef372fe94f82b;
H4 = 0xa54ff53a5f1d36f1;
H5 = 0x510e527fade682d1;
H6 = 0x9b05688c2b3e6c1f;
H7 = 0x1f83d9abfb41bd6b;
H8 = 0x5be0cd19137e2179;
}
public override IMemoable Copy()
{
return new Sha512Digest(this);
}
public override void Reset(IMemoable other)
{
Sha512Digest d = (Sha512Digest)other;
CopyIn(d);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 603d234c6bf03824d9d994a78b4a9e67
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,249 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/**
* FIPS 180-4 implementation of SHA-512/t
*/
public class Sha512tDigest
: LongDigest
{
private const ulong A5 = 0xa5a5a5a5a5a5a5a5UL;
private readonly int digestLength;
private ulong H1t, H2t, H3t, H4t, H5t, H6t, H7t, H8t;
/**
* Standard constructor
*/
public Sha512tDigest(int bitLength)
{
if (bitLength >= 512)
throw new ArgumentException("cannot be >= 512", "bitLength");
if (bitLength % 8 != 0)
throw new ArgumentException("needs to be a multiple of 8", "bitLength");
if (bitLength == 384)
throw new ArgumentException("cannot be 384 use SHA384 instead", "bitLength");
this.digestLength = bitLength / 8;
tIvGenerate(digestLength * 8);
Reset();
}
/**
* Copy constructor. This will copy the state of the provided
* message digest.
*/
public Sha512tDigest(Sha512tDigest t)
: base(t)
{
this.digestLength = t.digestLength;
Reset(t);
}
public override string AlgorithmName
{
get { return "SHA-512/" + (digestLength * 8); }
}
public override int GetDigestSize()
{
return digestLength;
}
public override int DoFinal(byte[] output, int outOff)
{
Finish();
UInt64_To_BE(H1, output, outOff, digestLength);
UInt64_To_BE(H2, output, outOff + 8, digestLength - 8);
UInt64_To_BE(H3, output, outOff + 16, digestLength - 16);
UInt64_To_BE(H4, output, outOff + 24, digestLength - 24);
UInt64_To_BE(H5, output, outOff + 32, digestLength - 32);
UInt64_To_BE(H6, output, outOff + 40, digestLength - 40);
UInt64_To_BE(H7, output, outOff + 48, digestLength - 48);
UInt64_To_BE(H8, output, outOff + 56, digestLength - 56);
Reset();
return digestLength;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override int DoFinal(Span<byte> output)
{
Finish();
UInt64_To_BE(H1, output, 0, digestLength);
UInt64_To_BE(H2, output, 8, digestLength - 8);
UInt64_To_BE(H3, output, 16, digestLength - 16);
UInt64_To_BE(H4, output, 24, digestLength - 24);
UInt64_To_BE(H5, output, 32, digestLength - 32);
UInt64_To_BE(H6, output, 40, digestLength - 40);
UInt64_To_BE(H7, output, 48, digestLength - 48);
UInt64_To_BE(H8, output, 56, digestLength - 56);
Reset();
return digestLength;
}
#endif
/**
* reset the chaining variables
*/
public override void Reset()
{
base.Reset();
/*
* initial hash values use the iv generation algorithm for t.
*/
H1 = H1t;
H2 = H2t;
H3 = H3t;
H4 = H4t;
H5 = H5t;
H6 = H6t;
H7 = H7t;
H8 = H8t;
}
private void tIvGenerate(int bitLength)
{
H1 = 0x6a09e667f3bcc908UL ^ A5;
H2 = 0xbb67ae8584caa73bUL ^ A5;
H3 = 0x3c6ef372fe94f82bUL ^ A5;
H4 = 0xa54ff53a5f1d36f1UL ^ A5;
H5 = 0x510e527fade682d1UL ^ A5;
H6 = 0x9b05688c2b3e6c1fUL ^ A5;
H7 = 0x1f83d9abfb41bd6bUL ^ A5;
H8 = 0x5be0cd19137e2179UL ^ A5;
Update(0x53);
Update(0x48);
Update(0x41);
Update(0x2D);
Update(0x35);
Update(0x31);
Update(0x32);
Update(0x2F);
if (bitLength > 100)
{
Update((byte)(bitLength / 100 + 0x30));
bitLength = bitLength % 100;
Update((byte)(bitLength / 10 + 0x30));
bitLength = bitLength % 10;
Update((byte)(bitLength + 0x30));
}
else if (bitLength > 10)
{
Update((byte)(bitLength / 10 + 0x30));
bitLength = bitLength % 10;
Update((byte)(bitLength + 0x30));
}
else
{
Update((byte)(bitLength + 0x30));
}
Finish();
H1t = H1;
H2t = H2;
H3t = H3;
H4t = H4;
H5t = H5;
H6t = H6;
H7t = H7;
H8t = H8;
}
private static void UInt64_To_BE(ulong n, byte[] bs, int off, int max)
{
if (max > 0)
{
UInt32_To_BE((uint)(n >> 32), bs, off, max);
if (max > 4)
{
UInt32_To_BE((uint)n, bs, off + 4, max - 4);
}
}
}
private static void UInt32_To_BE(uint n, byte[] bs, int off, int max)
{
int num = System.Math.Min(4, max);
while (--num >= 0)
{
int shift = 8 * (3 - num);
bs[off + num] = (byte)(n >> shift);
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private static void UInt64_To_BE(ulong n, Span<byte> bs, int off, int max)
{
if (max > 0)
{
UInt32_To_BE((uint)(n >> 32), bs, off, max);
if (max > 4)
{
UInt32_To_BE((uint)n, bs, off + 4, max - 4);
}
}
}
private static void UInt32_To_BE(uint n, Span<byte> bs, int off, int max)
{
int num = System.Math.Min(4, max);
while (--num >= 0)
{
int shift = 8 * (3 - num);
bs[off + num] = (byte)(n >> shift);
}
}
#endif
public override IMemoable Copy()
{
return new Sha512tDigest(this);
}
public override void Reset(IMemoable other)
{
Sha512tDigest t = (Sha512tDigest)other;
if (this.digestLength != t.digestLength)
{
throw new MemoableResetException("digestLength inappropriate in other");
}
base.CopyIn(t);
this.H1t = t.H1t;
this.H2t = t.H2t;
this.H3t = t.H3t;
this.H4t = t.H4t;
this.H5t = t.H5t;
this.H6t = t.H6t;
this.H7t = t.H7t;
this.H8t = t.H8t;
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 805a17d6beefcfb43bf74d7c88ce8572
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,156 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.Diagnostics;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/// <summary>
/// Implementation of SHAKE based on following KeccakNISTInterface.c from http://keccak.noekeon.org/
/// </summary>
/// <remarks>
/// Following the naming conventions used in the C source code to enable easy review of the implementation.
/// </remarks>
public class ShakeDigest
: KeccakDigest, IXof
{
private static int CheckBitLength(int bitLength)
{
switch (bitLength)
{
case 128:
case 256:
return bitLength;
default:
throw new ArgumentException(bitLength + " not supported for SHAKE", "bitLength");
}
}
public ShakeDigest()
: this(128)
{
}
public ShakeDigest(int bitLength)
: base(CheckBitLength(bitLength))
{
}
public ShakeDigest(ShakeDigest source)
: base(source)
{
}
public override string AlgorithmName
{
get { return "SHAKE" + fixedOutputLength; }
}
public override int GetDigestSize()
{
return fixedOutputLength >> 2;
}
public override int DoFinal(byte[] output, int outOff)
{
return OutputFinal(output, outOff, GetDigestSize());
}
public virtual int OutputFinal(byte[] output, int outOff, int outLen)
{
int length = Output(output, outOff, outLen);
Reset();
return length;
}
public virtual int Output(byte[] output, int outOff, int outLen)
{
if (!squeezing)
{
AbsorbBits(0x0F, 4);
}
Squeeze(output, outOff, (long)outLen << 3);
return outLen;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override int DoFinal(Span<byte> output)
{
return OutputFinal(output[..GetDigestSize()]);
}
public virtual int OutputFinal(Span<byte> output)
{
int length = Output(output);
Reset();
return length;
}
public virtual int Output(Span<byte> output)
{
if (!squeezing)
{
AbsorbBits(0x0F, 4);
}
Squeeze(output);
return output.Length;
}
#endif
/*
* TODO Possible API change to support partial-byte suffixes.
*/
protected override int DoFinal(byte[] output, int outOff, byte partialByte, int partialBits)
{
return OutputFinal(output, outOff, GetDigestSize(), partialByte, partialBits);
}
/*
* TODO Possible API change to support partial-byte suffixes.
*/
protected virtual int OutputFinal(byte[] output, int outOff, int outLen, byte partialByte, int partialBits)
{
if (partialBits < 0 || partialBits > 7)
throw new ArgumentException("must be in the range [0,7]", "partialBits");
int finalInput = (partialByte & ((1 << partialBits) - 1)) | (0x0F << partialBits);
Debug.Assert(finalInput >= 0);
int finalBits = partialBits + 4;
if (finalBits >= 8)
{
Absorb((byte)finalInput);
finalBits -= 8;
finalInput >>= 8;
}
if (finalBits > 0)
{
AbsorbBits(finalInput, finalBits);
}
Squeeze(output, outOff, (long)outLen << 3);
Reset();
return outLen;
}
public override IMemoable Copy()
{
return new ShakeDigest(this);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6273666f69aa67b44b94cad56baaa506
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,108 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/**
* Wrapper class that reduces the output length of a particular digest to
* only the first n bytes of the digest function.
*/
public class ShortenedDigest
: IDigest
{
private IDigest baseDigest;
private int length;
/**
* Base constructor.
*
* @param baseDigest underlying digest to use.
* @param length length in bytes of the output of doFinal.
* @exception ArgumentException if baseDigest is null, or length is greater than baseDigest.GetDigestSize().
*/
public ShortenedDigest(
IDigest baseDigest,
int length)
{
if (baseDigest == null)
{
throw new ArgumentNullException("baseDigest");
}
if (length > baseDigest.GetDigestSize())
{
throw new ArgumentException("baseDigest output not large enough to support length");
}
this.baseDigest = baseDigest;
this.length = length;
}
public string AlgorithmName
{
get { return baseDigest.AlgorithmName + "(" + length * 8 + ")"; }
}
public int GetDigestSize()
{
return length;
}
public void Update(byte input)
{
baseDigest.Update(input);
}
public void BlockUpdate(byte[] input, int inOff, int length)
{
baseDigest.BlockUpdate(input, inOff, length);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void BlockUpdate(ReadOnlySpan<byte> input)
{
baseDigest.BlockUpdate(input);
}
#endif
public int DoFinal(byte[] output, int outOff)
{
byte[] tmp = new byte[baseDigest.GetDigestSize()];
baseDigest.DoFinal(tmp, 0);
Array.Copy(tmp, 0, output, outOff, length);
return length;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public int DoFinal(Span<byte> output)
{
int baseDigestSize = baseDigest.GetDigestSize();
Span<byte> tmp = baseDigestSize <= 128
? stackalloc byte[baseDigestSize]
: new byte[baseDigestSize];
baseDigest.DoFinal(tmp);
tmp[..length].CopyTo(output);
return length;
}
#endif
public void Reset()
{
baseDigest.Reset();
}
public int GetByteLength()
{
return baseDigest.GetByteLength();
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cbd0bed026d0cbf47aa6b18f2e30d58d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,129 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/// <summary>
/// Implementation of the Skein parameterised hash function in 256, 512 and 1024 bit block sizes,
/// based on the <see cref="Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines.ThreefishEngine">Threefish</see> tweakable block cipher.
/// </summary>
/// <remarks>
/// This is the 1.3 version of Skein defined in the Skein hash function submission to the NIST SHA-3
/// competition in October 2010.
/// <p/>
/// Skein was designed by Niels Ferguson - Stefan Lucks - Bruce Schneier - Doug Whiting - Mihir
/// Bellare - Tadayoshi Kohno - Jon Callas - Jesse Walker.
/// </remarks>
/// <seealso cref="Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests.SkeinEngine"/>
/// <seealso cref="Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters.SkeinParameters"/>
public class SkeinDigest
: IDigest, IMemoable
{
/// <summary>
/// 256 bit block size - Skein-256
/// </summary>
public const int SKEIN_256 = SkeinEngine.SKEIN_256;
/// <summary>
/// 512 bit block size - Skein-512
/// </summary>
public const int SKEIN_512 = SkeinEngine.SKEIN_512;
/// <summary>
/// 1024 bit block size - Skein-1024
/// </summary>
public const int SKEIN_1024 = SkeinEngine.SKEIN_1024;
private readonly SkeinEngine engine;
/// <summary>
/// Constructs a Skein digest with an internal state size and output size.
/// </summary>
/// <param name="stateSizeBits">the internal state size in bits - one of <see cref="SKEIN_256"/> <see cref="SKEIN_512"/> or
/// <see cref="SKEIN_1024"/>.</param>
/// <param name="digestSizeBits">the output/digest size to produce in bits, which must be an integral number of
/// bytes.</param>
public SkeinDigest(int stateSizeBits, int digestSizeBits)
{
this.engine = new SkeinEngine(stateSizeBits, digestSizeBits);
Init(null);
}
public SkeinDigest(SkeinDigest digest)
{
this.engine = new SkeinEngine(digest.engine);
}
public void Reset(IMemoable other)
{
SkeinDigest d = (SkeinDigest)other;
engine.Reset(d.engine);
}
public IMemoable Copy()
{
return new SkeinDigest(this);
}
public string AlgorithmName
{
get { return "Skein-" + (engine.BlockSize * 8) + "-" + (engine.OutputSize * 8); }
}
public int GetDigestSize()
{
return engine.OutputSize;
}
public int GetByteLength()
{
return engine.BlockSize;
}
/// <summary>
/// Optionally initialises the Skein digest with the provided parameters.
/// </summary>
/// See <see cref="Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters.SkeinParameters"></see> for details on the parameterisation of the Skein hash function.
/// <param name="parameters">the parameters to apply to this engine, or <code>null</code> to use no parameters.</param>
public void Init(SkeinParameters parameters)
{
engine.Init(parameters);
}
public void Reset()
{
engine.Reset();
}
public void Update(byte inByte)
{
engine.Update(inByte);
}
public void BlockUpdate(byte[] inBytes, int inOff, int len)
{
engine.BlockUpdate(inBytes, inOff, len);
}
public int DoFinal(byte[] outBytes, int outOff)
{
return engine.DoFinal(outBytes, outOff);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void BlockUpdate(ReadOnlySpan<byte> input)
{
engine.BlockUpdate(input);
}
public int DoFinal(Span<byte> output)
{
return engine.DoFinal(output);
}
#endif
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fdd2fe90256780c4088d4f2b67651b26
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,903 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.Collections.Generic;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Collections;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/// <summary>
/// Implementation of the Skein family of parameterised hash functions in 256, 512 and 1024 bit block
/// sizes, based on the <see cref="Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines.ThreefishEngine">Threefish</see> tweakable block cipher.
/// </summary>
/// <remarks>
/// This is the 1.3 version of Skein defined in the Skein hash function submission to the NIST SHA-3
/// competition in October 2010.
/// <p/>
/// Skein was designed by Niels Ferguson - Stefan Lucks - Bruce Schneier - Doug Whiting - Mihir
/// Bellare - Tadayoshi Kohno - Jon Callas - Jesse Walker.
/// <p/>
/// This implementation is the basis for <see cref="Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests.SkeinDigest"/> and <see cref="Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs.SkeinMac"/>, implementing the
/// parameter based configuration system that allows Skein to be adapted to multiple applications. <br/>
/// Initialising the engine with <see cref="Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters.SkeinParameters"/> allows standard and arbitrary parameters to
/// be applied during the Skein hash function.
/// <p/>
/// Implemented:
/// <ul>
/// <li>256, 512 and 1024 bit internal states.</li>
/// <li>Full 96 bit input length.</li>
/// <li>Parameters defined in the Skein specification, and arbitrary other pre and post message
/// parameters.</li>
/// <li>Arbitrary output size in 1 byte intervals.</li>
/// </ul>
/// <p/>
/// Not implemented:
/// <ul>
/// <li>Sub-byte length input (bit padding).</li>
/// <li>Tree hashing.</li>
/// </ul>
/// </remarks>
/// <seealso cref="Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters.SkeinParameters"/>
public class SkeinEngine
: IMemoable
{
/// <summary>
/// 256 bit block size - Skein-256
/// </summary>
public const int SKEIN_256 = ThreefishEngine.BLOCKSIZE_256;
/// <summary>
/// 512 bit block size - Skein-512
/// </summary>
public const int SKEIN_512 = ThreefishEngine.BLOCKSIZE_512;
/// <summary>
/// 1024 bit block size - Skein-1024
/// </summary>
public const int SKEIN_1024 = ThreefishEngine.BLOCKSIZE_1024;
// Minimal at present, but more complex when tree hashing is implemented
private class Configuration
{
private byte[] bytes = new byte[32];
public Configuration(long outputSizeBits)
{
// 0..3 = ASCII SHA3
bytes[0] = (byte)'S';
bytes[1] = (byte)'H';
bytes[2] = (byte)'A';
bytes[3] = (byte)'3';
// 4..5 = version number in LSB order
bytes[4] = 1;
bytes[5] = 0;
// 8..15 = output length
Pack.UInt64_To_LE((ulong)outputSizeBits, bytes, 8);
}
public byte[] Bytes
{
get { return bytes; }
}
}
public class Parameter
{
private int type;
private byte[] value;
public Parameter(int type, byte[] value)
{
this.type = type;
this.value = value;
}
public int Type
{
get { return type; }
}
public byte[] Value
{
get { return value; }
}
}
/**
* The parameter type for the Skein key.
*/
private const int PARAM_TYPE_KEY = 0;
/**
* The parameter type for the Skein configuration block.
*/
private const int PARAM_TYPE_CONFIG = 4;
/**
* The parameter type for the message.
*/
private const int PARAM_TYPE_MESSAGE = 48;
/**
* The parameter type for the output transformation.
*/
private const int PARAM_TYPE_OUTPUT = 63;
/**
* Precalculated UBI(CFG) states for common state/output combinations without key or other
* pre-message params.
*/
private static readonly IDictionary<int, ulong[]> InitialStates = new Dictionary<int, ulong[]>();
static SkeinEngine()
{
// From Appendix C of the Skein 1.3 NIST submission
InitialState(SKEIN_256, 128, new ulong[]{
0xe1111906964d7260UL,
0x883daaa77c8d811cUL,
0x10080df491960f7aUL,
0xccf7dde5b45bc1c2UL});
InitialState(SKEIN_256, 160, new ulong[]{
0x1420231472825e98UL,
0x2ac4e9a25a77e590UL,
0xd47a58568838d63eUL,
0x2dd2e4968586ab7dUL});
InitialState(SKEIN_256, 224, new ulong[]{
0xc6098a8c9ae5ea0bUL,
0x876d568608c5191cUL,
0x99cb88d7d7f53884UL,
0x384bddb1aeddb5deUL});
InitialState(SKEIN_256, 256, new ulong[]{
0xfc9da860d048b449UL,
0x2fca66479fa7d833UL,
0xb33bc3896656840fUL,
0x6a54e920fde8da69UL});
InitialState(SKEIN_512, 128, new ulong[]{
0xa8bc7bf36fbf9f52UL,
0x1e9872cebd1af0aaUL,
0x309b1790b32190d3UL,
0xbcfbb8543f94805cUL,
0x0da61bcd6e31b11bUL,
0x1a18ebead46a32e3UL,
0xa2cc5b18ce84aa82UL,
0x6982ab289d46982dUL});
InitialState(SKEIN_512, 160, new ulong[]{
0x28b81a2ae013bd91UL,
0xc2f11668b5bdf78fUL,
0x1760d8f3f6a56f12UL,
0x4fb747588239904fUL,
0x21ede07f7eaf5056UL,
0xd908922e63ed70b8UL,
0xb8ec76ffeccb52faUL,
0x01a47bb8a3f27a6eUL});
InitialState(SKEIN_512, 224, new ulong[]{
0xccd0616248677224UL,
0xcba65cf3a92339efUL,
0x8ccd69d652ff4b64UL,
0x398aed7b3ab890b4UL,
0x0f59d1b1457d2bd0UL,
0x6776fe6575d4eb3dUL,
0x99fbc70e997413e9UL,
0x9e2cfccfe1c41ef7UL});
InitialState(SKEIN_512, 384, new ulong[]{
0xa3f6c6bf3a75ef5fUL,
0xb0fef9ccfd84faa4UL,
0x9d77dd663d770cfeUL,
0xd798cbf3b468fddaUL,
0x1bc4a6668a0e4465UL,
0x7ed7d434e5807407UL,
0x548fc1acd4ec44d6UL,
0x266e17546aa18ff8UL});
InitialState(SKEIN_512, 512, new ulong[]{
0x4903adff749c51ceUL,
0x0d95de399746df03UL,
0x8fd1934127c79bceUL,
0x9a255629ff352cb1UL,
0x5db62599df6ca7b0UL,
0xeabe394ca9d5c3f4UL,
0x991112c71a75b523UL,
0xae18a40b660fcc33UL});
}
private static void InitialState(int blockSize, int outputSize, ulong[] state)
{
InitialStates.Add(VariantIdentifier(blockSize / 8, outputSize / 8), state);
}
private static int VariantIdentifier(int blockSizeBytes, int outputSizeBytes)
{
return (outputSizeBytes << 16) | blockSizeBytes;
}
private class UbiTweak
{
/**
* Point at which position might overflow long, so switch to add with carry logic
*/
private const ulong LOW_RANGE = ulong.MaxValue - uint.MaxValue;
/**
* Bit 127 = final
*/
private const ulong T1_FINAL = 1UL << 63;
/**
* Bit 126 = first
*/
private const ulong T1_FIRST = 1UL << 62;
/**
* UBI uses a 128 bit tweak
*/
private ulong[] tweak = new ulong[2];
/**
* Whether 64 bit position exceeded
*/
private bool extendedPosition;
public UbiTweak()
{
Reset();
}
public void Reset(UbiTweak tweak)
{
this.tweak = Arrays.Clone(tweak.tweak, this.tweak);
this.extendedPosition = tweak.extendedPosition;
}
public void Reset()
{
tweak[0] = 0;
tweak[1] = 0;
extendedPosition = false;
First = true;
}
public uint Type
{
get
{
return (uint)((tweak[1] >> 56) & 0x3FUL);
}
set
{
// Bits 120..125 = type
tweak[1] = (tweak[1] & 0xFFFFFFC000000000UL) | ((value & 0x3FUL) << 56);
}
}
public bool First
{
get
{
return ((tweak[1] & T1_FIRST) != 0);
}
set
{
if (value)
{
tweak[1] |= T1_FIRST;
}
else
{
tweak[1] &= ~T1_FIRST;
}
}
}
public bool Final
{
get
{
return ((tweak[1] & T1_FINAL) != 0);
}
set
{
if (value)
{
tweak[1] |= T1_FINAL;
}
else
{
tweak[1] &= ~T1_FINAL;
}
}
}
/**
* Advances the position in the tweak by the specified value.
*/
public void AdvancePosition(int advance)
{
// Bits 0..95 = position
if (extendedPosition)
{
ulong[] parts = new ulong[3];
parts[0] = tweak[0] & 0xFFFFFFFFUL;
parts[1] = (tweak[0] >> 32) & 0xFFFFFFFFUL;
parts[2] = tweak[1] & 0xFFFFFFFFUL;
ulong carry = (ulong)advance;
for (int i = 0; i < parts.Length; i++)
{
carry += parts[i];
parts[i] = carry;
carry >>= 32;
}
tweak[0] = ((parts[1] & 0xFFFFFFFFUL) << 32) | (parts[0] & 0xFFFFFFFFUL);
tweak[1] = (tweak[1] & 0xFFFFFFFF00000000UL) | (parts[2] & 0xFFFFFFFFUL);
}
else
{
ulong position = tweak[0];
position += (uint)advance;
tweak[0] = position;
if (position > LOW_RANGE)
{
extendedPosition = true;
}
}
}
public ulong[] GetWords()
{
return tweak;
}
public override string ToString()
{
return Type + " first: " + First + ", final: " + Final;
}
}
/**
* The Unique Block Iteration chaining mode.
*/
// TODO: This might be better as methods...
private class UBI
{
private readonly UbiTweak tweak = new UbiTweak();
private readonly SkeinEngine engine;
/**
* Buffer for the current block of message data
*/
private byte[] currentBlock;
/**
* Offset into the current message block
*/
private int currentOffset;
/**
* Buffer for message words for feedback into encrypted block
*/
private ulong[] message;
public UBI(SkeinEngine engine, int blockSize)
{
this.engine = engine;
currentBlock = new byte[blockSize];
message = new ulong[currentBlock.Length / 8];
}
public void Reset(UBI ubi)
{
currentBlock = Arrays.Clone(ubi.currentBlock, currentBlock);
currentOffset = ubi.currentOffset;
message = Arrays.Clone(ubi.message, this.message);
tweak.Reset(ubi.tweak);
}
public void Reset(int type)
{
tweak.Reset();
tweak.Type = (uint)type;
currentOffset = 0;
}
public void Update(byte[] value, int offset, int len, ulong[] output)
{
/*
* Buffer complete blocks for the underlying Threefish cipher, only flushing when there
* are subsequent bytes (last block must be processed in doFinal() with final=true set).
*/
int copied = 0;
while (len > copied)
{
if (currentOffset == currentBlock.Length)
{
ProcessBlock(output);
tweak.First = false;
currentOffset = 0;
}
int toCopy = System.Math.Min(len - copied, currentBlock.Length - currentOffset);
Array.Copy(value, offset + copied, currentBlock, currentOffset, toCopy);
copied += toCopy;
currentOffset += toCopy;
tweak.AdvancePosition(toCopy);
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void Update(ReadOnlySpan<byte> input, ulong[] output)
{
/*
* Buffer complete blocks for the underlying Threefish cipher, only flushing when there
* are subsequent bytes (last block must be processed in doFinal() with final=true set).
*/
int copied = 0, len = input.Length;
while (len > copied)
{
if (currentOffset == currentBlock.Length)
{
ProcessBlock(output);
tweak.First = false;
currentOffset = 0;
}
int toCopy = System.Math.Min(len - copied, currentBlock.Length - currentOffset);
input.Slice(copied, toCopy).CopyTo(currentBlock.AsSpan(currentOffset));
copied += toCopy;
currentOffset += toCopy;
tweak.AdvancePosition(toCopy);
}
}
#endif
private void ProcessBlock(ulong[] output)
{
engine.threefish.Init(true, engine.chain, tweak.GetWords());
Pack.LE_To_UInt64(currentBlock, 0, message);
engine.threefish.ProcessBlock(message, output);
for (int i = 0; i < output.Length; i++)
{
output[i] ^= message[i];
}
}
public void DoFinal(ulong[] output)
{
// Pad remainder of current block with zeroes
for (int i = currentOffset; i < currentBlock.Length; i++)
{
currentBlock[i] = 0;
}
tweak.Final = true;
ProcessBlock(output);
}
}
/**
* Underlying Threefish tweakable block cipher
*/
private readonly ThreefishEngine threefish;
/**
* Size of the digest output, in bytes
*/
private readonly int outputSizeBytes;
/**
* The current chaining/state value
*/
private ulong[] chain;
/**
* The initial state value
*/
private ulong[] initialState;
/**
* The (optional) key parameter
*/
private byte[] key;
/**
* Parameters to apply prior to the message
*/
private Parameter[] preMessageParameters;
/**
* Parameters to apply after the message, but prior to output
*/
private Parameter[] postMessageParameters;
/**
* The current UBI operation
*/
private readonly UBI ubi;
/**
* Buffer for single byte update method
*/
private readonly byte[] singleByte = new byte[1];
/// <summary>
/// Constructs a Skein digest with an internal state size and output size.
/// </summary>
/// <param name="blockSizeBits">the internal state size in bits - one of <see cref="SKEIN_256"/> <see cref="SKEIN_512"/> or
/// <see cref="SKEIN_1024"/>.</param>
/// <param name="outputSizeBits">the output/digest size to produce in bits, which must be an integral number of
/// bytes.</param>
public SkeinEngine(int blockSizeBits, int outputSizeBits)
{
if (outputSizeBits % 8 != 0)
{
throw new ArgumentException("Output size must be a multiple of 8 bits. :" + outputSizeBits);
}
// TODO: Prevent digest sizes > block size?
this.outputSizeBytes = outputSizeBits / 8;
this.threefish = new ThreefishEngine(blockSizeBits);
this.ubi = new UBI(this,threefish.GetBlockSize());
}
/// <summary>
/// Creates a SkeinEngine as an exact copy of an existing instance.
/// </summary>
public SkeinEngine(SkeinEngine engine)
: this(engine.BlockSize * 8, engine.OutputSize * 8)
{
CopyIn(engine);
}
private void CopyIn(SkeinEngine engine)
{
this.ubi.Reset(engine.ubi);
this.chain = Arrays.Clone(engine.chain, this.chain);
this.initialState = Arrays.Clone(engine.initialState, this.initialState);
this.key = Arrays.Clone(engine.key, this.key);
this.preMessageParameters = Clone(engine.preMessageParameters, this.preMessageParameters);
this.postMessageParameters = Clone(engine.postMessageParameters, this.postMessageParameters);
}
private static Parameter[] Clone(Parameter[] data, Parameter[] existing)
{
if (data == null)
{
return null;
}
if ((existing == null) || (existing.Length != data.Length))
{
existing = new Parameter[data.Length];
}
Array.Copy(data, 0, existing, 0, existing.Length);
return existing;
}
public IMemoable Copy()
{
return new SkeinEngine(this);
}
public void Reset(IMemoable other)
{
SkeinEngine s = (SkeinEngine)other;
if ((BlockSize != s.BlockSize) || (outputSizeBytes != s.outputSizeBytes))
{
throw new MemoableResetException("Incompatible parameters in provided SkeinEngine.");
}
CopyIn(s);
}
public int OutputSize
{
get { return outputSizeBytes; }
}
public int BlockSize
{
get { return threefish.GetBlockSize (); }
}
/// <summary>
/// Initialises the Skein engine with the provided parameters. See <see cref="Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters.SkeinParameters"/> for
/// details on the parameterisation of the Skein hash function.
/// </summary>
/// <param name="parameters">the parameters to apply to this engine, or <code>null</code> to use no parameters.</param>
public void Init(SkeinParameters parameters)
{
this.chain = null;
this.key = null;
this.preMessageParameters = null;
this.postMessageParameters = null;
if (parameters != null)
{
byte[] key = parameters.GetKey();
if (key.Length < 16)
{
throw new ArgumentException("Skein key must be at least 128 bits.");
}
InitParams(parameters.GetParameters());
}
CreateInitialState();
// Initialise message block
UbiInit(PARAM_TYPE_MESSAGE);
}
private void InitParams(IDictionary<int, byte[]> parameters)
{
//IEnumerator keys = parameters.Keys.GetEnumerator();
var pre = new List<Parameter>();
var post = new List<Parameter>();
//while (keys.MoveNext())
foreach (var parameter in parameters)
{
int type = parameter.Key;
byte[] value = parameter.Value;
if (type == PARAM_TYPE_KEY)
{
this.key = value;
}
else if (type < PARAM_TYPE_MESSAGE)
{
pre.Add(new Parameter(type, value));
}
else
{
post.Add(new Parameter(type, value));
}
}
preMessageParameters = new Parameter[pre.Count];
pre.CopyTo(preMessageParameters, 0);
Array.Sort(preMessageParameters);
postMessageParameters = new Parameter[post.Count];
post.CopyTo(postMessageParameters, 0);
Array.Sort(postMessageParameters);
}
/**
* Calculate the initial (pre message block) chaining state.
*/
private void CreateInitialState()
{
var precalc = CollectionUtilities.GetValueOrNull(InitialStates, VariantIdentifier(BlockSize, OutputSize));
if ((key == null) && (precalc != null))
{
// Precalculated UBI(CFG)
chain = Arrays.Clone(precalc);
}
else
{
// Blank initial state
chain = new ulong[BlockSize / 8];
// Process key block
if (key != null)
{
UbiComplete(SkeinParameters.PARAM_TYPE_KEY, key);
}
// Process configuration block
UbiComplete(PARAM_TYPE_CONFIG, new Configuration(outputSizeBytes * 8).Bytes);
}
// Process additional pre-message parameters
if (preMessageParameters != null)
{
for (int i = 0; i < preMessageParameters.Length; i++)
{
Parameter param = preMessageParameters[i];
UbiComplete(param.Type, param.Value);
}
}
initialState = Arrays.Clone(chain);
}
/// <summary>
/// Reset the engine to the initial state (with the key and any pre-message parameters , ready to
/// accept message input.
/// </summary>
public void Reset()
{
Array.Copy(initialState, 0, chain, 0, chain.Length);
UbiInit(PARAM_TYPE_MESSAGE);
}
private void UbiComplete(int type, byte[] value)
{
UbiInit(type);
this.ubi.Update(value, 0, value.Length, chain);
UbiFinal();
}
private void UbiInit(int type)
{
this.ubi.Reset(type);
}
private void UbiFinal()
{
ubi.DoFinal(chain);
}
private void CheckInitialised()
{
if (this.ubi == null)
{
throw new ArgumentException("Skein engine is not initialised.");
}
}
public void Update(byte inByte)
{
singleByte[0] = inByte;
BlockUpdate(singleByte, 0, 1);
}
public void BlockUpdate(byte[] inBytes, int inOff, int len)
{
CheckInitialised();
ubi.Update(inBytes, inOff, len, chain);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void BlockUpdate(ReadOnlySpan<byte> input)
{
CheckInitialised();
ubi.Update(input, chain);
}
#endif
public int DoFinal(byte[] outBytes, int outOff)
{
CheckInitialised();
if (outBytes.Length < (outOff + outputSizeBytes))
{
throw new DataLengthException("Output buffer is too short to hold output");
}
// Finalise message block
UbiFinal();
// Process additional post-message parameters
if (postMessageParameters != null)
{
for (int i = 0; i < postMessageParameters.Length; i++)
{
Parameter param = postMessageParameters[i];
UbiComplete(param.Type, param.Value);
}
}
// Perform the output transform
int blockSize = BlockSize;
int blocksRequired = ((outputSizeBytes + blockSize - 1) / blockSize);
for (int i = 0; i < blocksRequired; i++)
{
int toWrite = System.Math.Min(blockSize, outputSizeBytes - (i * blockSize));
Output((ulong)i, outBytes, outOff + (i * blockSize), toWrite);
}
Reset();
return outputSizeBytes;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public int DoFinal(Span<byte> output)
{
CheckInitialised();
if (output.Length < outputSizeBytes)
throw new DataLengthException("Output span is too short to hold output");
// Finalise message block
UbiFinal();
// Process additional post-message parameters
if (postMessageParameters != null)
{
for (int i = 0; i < postMessageParameters.Length; i++)
{
Parameter param = postMessageParameters[i];
UbiComplete(param.Type, param.Value);
}
}
// Perform the output transform
int blockSize = BlockSize;
int blocksRequired = (outputSizeBytes + blockSize - 1) / blockSize;
for (int i = 0; i < blocksRequired; i++)
{
int toWrite = System.Math.Min(blockSize, outputSizeBytes - (i * blockSize));
//Output((ulong)i, outBytes, outOff + (i * blockSize), toWrite);
Output((ulong)i, output[(i * blockSize)..], toWrite);
}
Reset();
return outputSizeBytes;
}
#endif
private void Output(ulong outputSequence, byte[] outBytes, int outOff, int outputBytes)
{
byte[] currentBytes = new byte[8];
Pack.UInt64_To_LE(outputSequence, currentBytes, 0);
// Output is a sequence of UBI invocations all of which use and preserve the pre-output state
ulong[] outputWords = new ulong[chain.Length];
UbiInit(PARAM_TYPE_OUTPUT);
this.ubi.Update(currentBytes, 0, currentBytes.Length, outputWords);
ubi.DoFinal(outputWords);
int wordsRequired = (outputBytes + 8 - 1) / 8;
for (int i = 0; i < wordsRequired; i++)
{
int toWrite = System.Math.Min(8, outputBytes - (i * 8));
if (toWrite == 8)
{
Pack.UInt64_To_LE(outputWords[i], outBytes, outOff + (i * 8));
}
else
{
Pack.UInt64_To_LE(outputWords[i], currentBytes, 0);
Array.Copy(currentBytes, 0, outBytes, outOff + (i * 8), toWrite);
}
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private void Output(ulong outputSequence, Span<byte> output, int outputBytes)
{
Span<byte> currentBytes = stackalloc byte[8];
Pack.UInt64_To_LE(outputSequence, currentBytes);
// Output is a sequence of UBI invocations all of which use and preserve the pre-output state
ulong[] outputWords = new ulong[chain.Length];
UbiInit(PARAM_TYPE_OUTPUT);
this.ubi.Update(currentBytes, outputWords);
ubi.DoFinal(outputWords);
int wordsRequired = (outputBytes + 8 - 1) / 8;
for (int i = 0; i < wordsRequired; i++)
{
int toWrite = System.Math.Min(8, outputBytes - (i * 8));
if (toWrite == 8)
{
Pack.UInt64_To_LE(outputWords[i], output[(i * 8)..]);
}
else
{
Pack.UInt64_To_LE(outputWords[i], currentBytes);
currentBytes[..toWrite].CopyTo(output[(i * 8)..]);
}
}
}
#endif
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5fc9ba0ef2e52a1469ef1f7e1e2b9219
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,932 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/**
* implementation of Tiger based on:
* <a href="http://www.cs.technion.ac.il/~biham/Reports/Tiger">
* http://www.cs.technion.ac.il/~biham/Reports/Tiger</a>
*/
public class TigerDigest
: IDigest, IMemoable
{
private const int MyByteLength = 64;
/*
* S-Boxes.
*/
private static readonly long[] t1 = {
unchecked((long) 0x02AAB17CF7E90C5EL) /* 0 */, unchecked((long) 0xAC424B03E243A8ECL) /* 1 */,
unchecked((long) 0x72CD5BE30DD5FCD3L) /* 2 */, unchecked((long) 0x6D019B93F6F97F3AL) /* 3 */,
unchecked((long) 0xCD9978FFD21F9193L) /* 4 */, unchecked((long) 0x7573A1C9708029E2L) /* 5 */,
unchecked((long) 0xB164326B922A83C3L) /* 6 */, unchecked((long) 0x46883EEE04915870L) /* 7 */,
unchecked((long) 0xEAACE3057103ECE6L) /* 8 */, unchecked((long) 0xC54169B808A3535CL) /* 9 */,
unchecked((long) 0x4CE754918DDEC47CL) /* 10 */, unchecked((long) 0x0AA2F4DFDC0DF40CL) /* 11 */,
unchecked((long) 0x10B76F18A74DBEFAL) /* 12 */, unchecked((long) 0xC6CCB6235AD1AB6AL) /* 13 */,
unchecked((long) 0x13726121572FE2FFL) /* 14 */, unchecked((long) 0x1A488C6F199D921EL) /* 15 */,
unchecked((long) 0x4BC9F9F4DA0007CAL) /* 16 */, unchecked((long) 0x26F5E6F6E85241C7L) /* 17 */,
unchecked((long) 0x859079DBEA5947B6L) /* 18 */, unchecked((long) 0x4F1885C5C99E8C92L) /* 19 */,
unchecked((long) 0xD78E761EA96F864BL) /* 20 */, unchecked((long) 0x8E36428C52B5C17DL) /* 21 */,
unchecked((long) 0x69CF6827373063C1L) /* 22 */, unchecked((long) 0xB607C93D9BB4C56EL) /* 23 */,
unchecked((long) 0x7D820E760E76B5EAL) /* 24 */, unchecked((long) 0x645C9CC6F07FDC42L) /* 25 */,
unchecked((long) 0xBF38A078243342E0L) /* 26 */, unchecked((long) 0x5F6B343C9D2E7D04L) /* 27 */,
unchecked((long) 0xF2C28AEB600B0EC6L) /* 28 */, unchecked((long) 0x6C0ED85F7254BCACL) /* 29 */,
unchecked((long) 0x71592281A4DB4FE5L) /* 30 */, unchecked((long) 0x1967FA69CE0FED9FL) /* 31 */,
unchecked((long) 0xFD5293F8B96545DBL) /* 32 */, unchecked((long) 0xC879E9D7F2A7600BL) /* 33 */,
unchecked((long) 0x860248920193194EL) /* 34 */, unchecked((long) 0xA4F9533B2D9CC0B3L) /* 35 */,
unchecked((long) 0x9053836C15957613L) /* 36 */, unchecked((long) 0xDB6DCF8AFC357BF1L) /* 37 */,
unchecked((long) 0x18BEEA7A7A370F57L) /* 38 */, unchecked((long) 0x037117CA50B99066L) /* 39 */,
unchecked((long) 0x6AB30A9774424A35L) /* 40 */, unchecked((long) 0xF4E92F02E325249BL) /* 41 */,
unchecked((long) 0x7739DB07061CCAE1L) /* 42 */, unchecked((long) 0xD8F3B49CECA42A05L) /* 43 */,
unchecked((long) 0xBD56BE3F51382F73L) /* 44 */, unchecked((long) 0x45FAED5843B0BB28L) /* 45 */,
unchecked((long) 0x1C813D5C11BF1F83L) /* 46 */, unchecked((long) 0x8AF0E4B6D75FA169L) /* 47 */,
unchecked((long) 0x33EE18A487AD9999L) /* 48 */, unchecked((long) 0x3C26E8EAB1C94410L) /* 49 */,
unchecked((long) 0xB510102BC0A822F9L) /* 50 */, unchecked((long) 0x141EEF310CE6123BL) /* 51 */,
unchecked((long) 0xFC65B90059DDB154L) /* 52 */, unchecked((long) 0xE0158640C5E0E607L) /* 53 */,
unchecked((long) 0x884E079826C3A3CFL) /* 54 */, unchecked((long) 0x930D0D9523C535FDL) /* 55 */,
unchecked((long) 0x35638D754E9A2B00L) /* 56 */, unchecked((long) 0x4085FCCF40469DD5L) /* 57 */,
unchecked((long) 0xC4B17AD28BE23A4CL) /* 58 */, unchecked((long) 0xCAB2F0FC6A3E6A2EL) /* 59 */,
unchecked((long) 0x2860971A6B943FCDL) /* 60 */, unchecked((long) 0x3DDE6EE212E30446L) /* 61 */,
unchecked((long) 0x6222F32AE01765AEL) /* 62 */, unchecked((long) 0x5D550BB5478308FEL) /* 63 */,
unchecked((long) 0xA9EFA98DA0EDA22AL) /* 64 */, unchecked((long) 0xC351A71686C40DA7L) /* 65 */,
unchecked((long) 0x1105586D9C867C84L) /* 66 */, unchecked((long) 0xDCFFEE85FDA22853L) /* 67 */,
unchecked((long) 0xCCFBD0262C5EEF76L) /* 68 */, unchecked((long) 0xBAF294CB8990D201L) /* 69 */,
unchecked((long) 0xE69464F52AFAD975L) /* 70 */, unchecked((long) 0x94B013AFDF133E14L) /* 71 */,
unchecked((long) 0x06A7D1A32823C958L) /* 72 */, unchecked((long) 0x6F95FE5130F61119L) /* 73 */,
unchecked((long) 0xD92AB34E462C06C0L) /* 74 */, unchecked((long) 0xED7BDE33887C71D2L) /* 75 */,
unchecked((long) 0x79746D6E6518393EL) /* 76 */, unchecked((long) 0x5BA419385D713329L) /* 77 */,
unchecked((long) 0x7C1BA6B948A97564L) /* 78 */, unchecked((long) 0x31987C197BFDAC67L) /* 79 */,
unchecked((long) 0xDE6C23C44B053D02L) /* 80 */, unchecked((long) 0x581C49FED002D64DL) /* 81 */,
unchecked((long) 0xDD474D6338261571L) /* 82 */, unchecked((long) 0xAA4546C3E473D062L) /* 83 */,
unchecked((long) 0x928FCE349455F860L) /* 84 */, unchecked((long) 0x48161BBACAAB94D9L) /* 85 */,
unchecked((long) 0x63912430770E6F68L) /* 86 */, unchecked((long) 0x6EC8A5E602C6641CL) /* 87 */,
unchecked((long) 0x87282515337DDD2BL) /* 88 */, unchecked((long) 0x2CDA6B42034B701BL) /* 89 */,
unchecked((long) 0xB03D37C181CB096DL) /* 90 */, unchecked((long) 0xE108438266C71C6FL) /* 91 */,
unchecked((long) 0x2B3180C7EB51B255L) /* 92 */, unchecked((long) 0xDF92B82F96C08BBCL) /* 93 */,
unchecked((long) 0x5C68C8C0A632F3BAL) /* 94 */, unchecked((long) 0x5504CC861C3D0556L) /* 95 */,
unchecked((long) 0xABBFA4E55FB26B8FL) /* 96 */, unchecked((long) 0x41848B0AB3BACEB4L) /* 97 */,
unchecked((long) 0xB334A273AA445D32L) /* 98 */, unchecked((long) 0xBCA696F0A85AD881L) /* 99 */,
unchecked((long) 0x24F6EC65B528D56CL) /* 100 */, unchecked((long) 0x0CE1512E90F4524AL) /* 101 */,
unchecked((long) 0x4E9DD79D5506D35AL) /* 102 */, unchecked((long) 0x258905FAC6CE9779L) /* 103 */,
unchecked((long) 0x2019295B3E109B33L) /* 104 */, unchecked((long) 0xF8A9478B73A054CCL) /* 105 */,
unchecked((long) 0x2924F2F934417EB0L) /* 106 */, unchecked((long) 0x3993357D536D1BC4L) /* 107 */,
unchecked((long) 0x38A81AC21DB6FF8BL) /* 108 */, unchecked((long) 0x47C4FBF17D6016BFL) /* 109 */,
unchecked((long) 0x1E0FAADD7667E3F5L) /* 110 */, unchecked((long) 0x7ABCFF62938BEB96L) /* 111 */,
unchecked((long) 0xA78DAD948FC179C9L) /* 112 */, unchecked((long) 0x8F1F98B72911E50DL) /* 113 */,
unchecked((long) 0x61E48EAE27121A91L) /* 114 */, unchecked((long) 0x4D62F7AD31859808L) /* 115 */,
unchecked((long) 0xECEBA345EF5CEAEBL) /* 116 */, unchecked((long) 0xF5CEB25EBC9684CEL) /* 117 */,
unchecked((long) 0xF633E20CB7F76221L) /* 118 */, unchecked((long) 0xA32CDF06AB8293E4L) /* 119 */,
unchecked((long) 0x985A202CA5EE2CA4L) /* 120 */, unchecked((long) 0xCF0B8447CC8A8FB1L) /* 121 */,
unchecked((long) 0x9F765244979859A3L) /* 122 */, unchecked((long) 0xA8D516B1A1240017L) /* 123 */,
unchecked((long) 0x0BD7BA3EBB5DC726L) /* 124 */, unchecked((long) 0xE54BCA55B86ADB39L) /* 125 */,
unchecked((long) 0x1D7A3AFD6C478063L) /* 126 */, unchecked((long) 0x519EC608E7669EDDL) /* 127 */,
unchecked((long) 0x0E5715A2D149AA23L) /* 128 */, unchecked((long) 0x177D4571848FF194L) /* 129 */,
unchecked((long) 0xEEB55F3241014C22L) /* 130 */, unchecked((long) 0x0F5E5CA13A6E2EC2L) /* 131 */,
unchecked((long) 0x8029927B75F5C361L) /* 132 */, unchecked((long) 0xAD139FABC3D6E436L) /* 133 */,
unchecked((long) 0x0D5DF1A94CCF402FL) /* 134 */, unchecked((long) 0x3E8BD948BEA5DFC8L) /* 135 */,
unchecked((long) 0xA5A0D357BD3FF77EL) /* 136 */, unchecked((long) 0xA2D12E251F74F645L) /* 137 */,
unchecked((long) 0x66FD9E525E81A082L) /* 138 */, unchecked((long) 0x2E0C90CE7F687A49L) /* 139 */,
unchecked((long) 0xC2E8BCBEBA973BC5L) /* 140 */, unchecked((long) 0x000001BCE509745FL) /* 141 */,
unchecked((long) 0x423777BBE6DAB3D6L) /* 142 */, unchecked((long) 0xD1661C7EAEF06EB5L) /* 143 */,
unchecked((long) 0xA1781F354DAACFD8L) /* 144 */, unchecked((long) 0x2D11284A2B16AFFCL) /* 145 */,
unchecked((long) 0xF1FC4F67FA891D1FL) /* 146 */, unchecked((long) 0x73ECC25DCB920ADAL) /* 147 */,
unchecked((long) 0xAE610C22C2A12651L) /* 148 */, unchecked((long) 0x96E0A810D356B78AL) /* 149 */,
unchecked((long) 0x5A9A381F2FE7870FL) /* 150 */, unchecked((long) 0xD5AD62EDE94E5530L) /* 151 */,
unchecked((long) 0xD225E5E8368D1427L) /* 152 */, unchecked((long) 0x65977B70C7AF4631L) /* 153 */,
unchecked((long) 0x99F889B2DE39D74FL) /* 154 */, unchecked((long) 0x233F30BF54E1D143L) /* 155 */,
unchecked((long) 0x9A9675D3D9A63C97L) /* 156 */, unchecked((long) 0x5470554FF334F9A8L) /* 157 */,
unchecked((long) 0x166ACB744A4F5688L) /* 158 */, unchecked((long) 0x70C74CAAB2E4AEADL) /* 159 */,
unchecked((long) 0xF0D091646F294D12L) /* 160 */, unchecked((long) 0x57B82A89684031D1L) /* 161 */,
unchecked((long) 0xEFD95A5A61BE0B6BL) /* 162 */, unchecked((long) 0x2FBD12E969F2F29AL) /* 163 */,
unchecked((long) 0x9BD37013FEFF9FE8L) /* 164 */, unchecked((long) 0x3F9B0404D6085A06L) /* 165 */,
unchecked((long) 0x4940C1F3166CFE15L) /* 166 */, unchecked((long) 0x09542C4DCDF3DEFBL) /* 167 */,
unchecked((long) 0xB4C5218385CD5CE3L) /* 168 */, unchecked((long) 0xC935B7DC4462A641L) /* 169 */,
unchecked((long) 0x3417F8A68ED3B63FL) /* 170 */, unchecked((long) 0xB80959295B215B40L) /* 171 */,
unchecked((long) 0xF99CDAEF3B8C8572L) /* 172 */, unchecked((long) 0x018C0614F8FCB95DL) /* 173 */,
unchecked((long) 0x1B14ACCD1A3ACDF3L) /* 174 */, unchecked((long) 0x84D471F200BB732DL) /* 175 */,
unchecked((long) 0xC1A3110E95E8DA16L) /* 176 */, unchecked((long) 0x430A7220BF1A82B8L) /* 177 */,
unchecked((long) 0xB77E090D39DF210EL) /* 178 */, unchecked((long) 0x5EF4BD9F3CD05E9DL) /* 179 */,
unchecked((long) 0x9D4FF6DA7E57A444L) /* 180 */, unchecked((long) 0xDA1D60E183D4A5F8L) /* 181 */,
unchecked((long) 0xB287C38417998E47L) /* 182 */, unchecked((long) 0xFE3EDC121BB31886L) /* 183 */,
unchecked((long) 0xC7FE3CCC980CCBEFL) /* 184 */, unchecked((long) 0xE46FB590189BFD03L) /* 185 */,
unchecked((long) 0x3732FD469A4C57DCL) /* 186 */, unchecked((long) 0x7EF700A07CF1AD65L) /* 187 */,
unchecked((long) 0x59C64468A31D8859L) /* 188 */, unchecked((long) 0x762FB0B4D45B61F6L) /* 189 */,
unchecked((long) 0x155BAED099047718L) /* 190 */, unchecked((long) 0x68755E4C3D50BAA6L) /* 191 */,
unchecked((long) 0xE9214E7F22D8B4DFL) /* 192 */, unchecked((long) 0x2ADDBF532EAC95F4L) /* 193 */,
unchecked((long) 0x32AE3909B4BD0109L) /* 194 */, unchecked((long) 0x834DF537B08E3450L) /* 195 */,
unchecked((long) 0xFA209DA84220728DL) /* 196 */, unchecked((long) 0x9E691D9B9EFE23F7L) /* 197 */,
unchecked((long) 0x0446D288C4AE8D7FL) /* 198 */, unchecked((long) 0x7B4CC524E169785BL) /* 199 */,
unchecked((long) 0x21D87F0135CA1385L) /* 200 */, unchecked((long) 0xCEBB400F137B8AA5L) /* 201 */,
unchecked((long) 0x272E2B66580796BEL) /* 202 */, unchecked((long) 0x3612264125C2B0DEL) /* 203 */,
unchecked((long) 0x057702BDAD1EFBB2L) /* 204 */, unchecked((long) 0xD4BABB8EACF84BE9L) /* 205 */,
unchecked((long) 0x91583139641BC67BL) /* 206 */, unchecked((long) 0x8BDC2DE08036E024L) /* 207 */,
unchecked((long) 0x603C8156F49F68EDL) /* 208 */, unchecked((long) 0xF7D236F7DBEF5111L) /* 209 */,
unchecked((long) 0x9727C4598AD21E80L) /* 210 */, unchecked((long) 0xA08A0896670A5FD7L) /* 211 */,
unchecked((long) 0xCB4A8F4309EBA9CBL) /* 212 */, unchecked((long) 0x81AF564B0F7036A1L) /* 213 */,
unchecked((long) 0xC0B99AA778199ABDL) /* 214 */, unchecked((long) 0x959F1EC83FC8E952L) /* 215 */,
unchecked((long) 0x8C505077794A81B9L) /* 216 */, unchecked((long) 0x3ACAAF8F056338F0L) /* 217 */,
unchecked((long) 0x07B43F50627A6778L) /* 218 */, unchecked((long) 0x4A44AB49F5ECCC77L) /* 219 */,
unchecked((long) 0x3BC3D6E4B679EE98L) /* 220 */, unchecked((long) 0x9CC0D4D1CF14108CL) /* 221 */,
unchecked((long) 0x4406C00B206BC8A0L) /* 222 */, unchecked((long) 0x82A18854C8D72D89L) /* 223 */,
unchecked((long) 0x67E366B35C3C432CL) /* 224 */, unchecked((long) 0xB923DD61102B37F2L) /* 225 */,
unchecked((long) 0x56AB2779D884271DL) /* 226 */, unchecked((long) 0xBE83E1B0FF1525AFL) /* 227 */,
unchecked((long) 0xFB7C65D4217E49A9L) /* 228 */, unchecked((long) 0x6BDBE0E76D48E7D4L) /* 229 */,
unchecked((long) 0x08DF828745D9179EL) /* 230 */, unchecked((long) 0x22EA6A9ADD53BD34L) /* 231 */,
unchecked((long) 0xE36E141C5622200AL) /* 232 */, unchecked((long) 0x7F805D1B8CB750EEL) /* 233 */,
unchecked((long) 0xAFE5C7A59F58E837L) /* 234 */, unchecked((long) 0xE27F996A4FB1C23CL) /* 235 */,
unchecked((long) 0xD3867DFB0775F0D0L) /* 236 */, unchecked((long) 0xD0E673DE6E88891AL) /* 237 */,
unchecked((long) 0x123AEB9EAFB86C25L) /* 238 */, unchecked((long) 0x30F1D5D5C145B895L) /* 239 */,
unchecked((long) 0xBB434A2DEE7269E7L) /* 240 */, unchecked((long) 0x78CB67ECF931FA38L) /* 241 */,
unchecked((long) 0xF33B0372323BBF9CL) /* 242 */, unchecked((long) 0x52D66336FB279C74L) /* 243 */,
unchecked((long) 0x505F33AC0AFB4EAAL) /* 244 */, unchecked((long) 0xE8A5CD99A2CCE187L) /* 245 */,
unchecked((long) 0x534974801E2D30BBL) /* 246 */, unchecked((long) 0x8D2D5711D5876D90L) /* 247 */,
unchecked((long) 0x1F1A412891BC038EL) /* 248 */, unchecked((long) 0xD6E2E71D82E56648L) /* 249 */,
unchecked((long) 0x74036C3A497732B7L) /* 250 */, unchecked((long) 0x89B67ED96361F5ABL) /* 251 */,
unchecked((long) 0xFFED95D8F1EA02A2L) /* 252 */, unchecked((long) 0xE72B3BD61464D43DL) /* 253 */,
unchecked((long) 0xA6300F170BDC4820L) /* 254 */, unchecked((long) 0xEBC18760ED78A77AL) /* 255 */,
};
private static readonly long[] t2 = {
unchecked((long) 0xE6A6BE5A05A12138L) /* 256 */, unchecked((long) 0xB5A122A5B4F87C98L) /* 257 */,
unchecked((long) 0x563C6089140B6990L) /* 258 */, unchecked((long) 0x4C46CB2E391F5DD5L) /* 259 */,
unchecked((long) 0xD932ADDBC9B79434L) /* 260 */, unchecked((long) 0x08EA70E42015AFF5L) /* 261 */,
unchecked((long) 0xD765A6673E478CF1L) /* 262 */, unchecked((long) 0xC4FB757EAB278D99L) /* 263 */,
unchecked((long) 0xDF11C6862D6E0692L) /* 264 */, unchecked((long) 0xDDEB84F10D7F3B16L) /* 265 */,
unchecked((long) 0x6F2EF604A665EA04L) /* 266 */, unchecked((long) 0x4A8E0F0FF0E0DFB3L) /* 267 */,
unchecked((long) 0xA5EDEEF83DBCBA51L) /* 268 */, unchecked((long) 0xFC4F0A2A0EA4371EL) /* 269 */,
unchecked((long) 0xE83E1DA85CB38429L) /* 270 */, unchecked((long) 0xDC8FF882BA1B1CE2L) /* 271 */,
unchecked((long) 0xCD45505E8353E80DL) /* 272 */, unchecked((long) 0x18D19A00D4DB0717L) /* 273 */,
unchecked((long) 0x34A0CFEDA5F38101L) /* 274 */, unchecked((long) 0x0BE77E518887CAF2L) /* 275 */,
unchecked((long) 0x1E341438B3C45136L) /* 276 */, unchecked((long) 0xE05797F49089CCF9L) /* 277 */,
unchecked((long) 0xFFD23F9DF2591D14L) /* 278 */, unchecked((long) 0x543DDA228595C5CDL) /* 279 */,
unchecked((long) 0x661F81FD99052A33L) /* 280 */, unchecked((long) 0x8736E641DB0F7B76L) /* 281 */,
unchecked((long) 0x15227725418E5307L) /* 282 */, unchecked((long) 0xE25F7F46162EB2FAL) /* 283 */,
unchecked((long) 0x48A8B2126C13D9FEL) /* 284 */, unchecked((long) 0xAFDC541792E76EEAL) /* 285 */,
unchecked((long) 0x03D912BFC6D1898FL) /* 286 */, unchecked((long) 0x31B1AAFA1B83F51BL) /* 287 */,
unchecked((long) 0xF1AC2796E42AB7D9L) /* 288 */, unchecked((long) 0x40A3A7D7FCD2EBACL) /* 289 */,
unchecked((long) 0x1056136D0AFBBCC5L) /* 290 */, unchecked((long) 0x7889E1DD9A6D0C85L) /* 291 */,
unchecked((long) 0xD33525782A7974AAL) /* 292 */, unchecked((long) 0xA7E25D09078AC09BL) /* 293 */,
unchecked((long) 0xBD4138B3EAC6EDD0L) /* 294 */, unchecked((long) 0x920ABFBE71EB9E70L) /* 295 */,
unchecked((long) 0xA2A5D0F54FC2625CL) /* 296 */, unchecked((long) 0xC054E36B0B1290A3L) /* 297 */,
unchecked((long) 0xF6DD59FF62FE932BL) /* 298 */, unchecked((long) 0x3537354511A8AC7DL) /* 299 */,
unchecked((long) 0xCA845E9172FADCD4L) /* 300 */, unchecked((long) 0x84F82B60329D20DCL) /* 301 */,
unchecked((long) 0x79C62CE1CD672F18L) /* 302 */, unchecked((long) 0x8B09A2ADD124642CL) /* 303 */,
unchecked((long) 0xD0C1E96A19D9E726L) /* 304 */, unchecked((long) 0x5A786A9B4BA9500CL) /* 305 */,
unchecked((long) 0x0E020336634C43F3L) /* 306 */, unchecked((long) 0xC17B474AEB66D822L) /* 307 */,
unchecked((long) 0x6A731AE3EC9BAAC2L) /* 308 */, unchecked((long) 0x8226667AE0840258L) /* 309 */,
unchecked((long) 0x67D4567691CAECA5L) /* 310 */, unchecked((long) 0x1D94155C4875ADB5L) /* 311 */,
unchecked((long) 0x6D00FD985B813FDFL) /* 312 */, unchecked((long) 0x51286EFCB774CD06L) /* 313 */,
unchecked((long) 0x5E8834471FA744AFL) /* 314 */, unchecked((long) 0xF72CA0AEE761AE2EL) /* 315 */,
unchecked((long) 0xBE40E4CDAEE8E09AL) /* 316 */, unchecked((long) 0xE9970BBB5118F665L) /* 317 */,
unchecked((long) 0x726E4BEB33DF1964L) /* 318 */, unchecked((long) 0x703B000729199762L) /* 319 */,
unchecked((long) 0x4631D816F5EF30A7L) /* 320 */, unchecked((long) 0xB880B5B51504A6BEL) /* 321 */,
unchecked((long) 0x641793C37ED84B6CL) /* 322 */, unchecked((long) 0x7B21ED77F6E97D96L) /* 323 */,
unchecked((long) 0x776306312EF96B73L) /* 324 */, unchecked((long) 0xAE528948E86FF3F4L) /* 325 */,
unchecked((long) 0x53DBD7F286A3F8F8L) /* 326 */, unchecked((long) 0x16CADCE74CFC1063L) /* 327 */,
unchecked((long) 0x005C19BDFA52C6DDL) /* 328 */, unchecked((long) 0x68868F5D64D46AD3L) /* 329 */,
unchecked((long) 0x3A9D512CCF1E186AL) /* 330 */, unchecked((long) 0x367E62C2385660AEL) /* 331 */,
unchecked((long) 0xE359E7EA77DCB1D7L) /* 332 */, unchecked((long) 0x526C0773749ABE6EL) /* 333 */,
unchecked((long) 0x735AE5F9D09F734BL) /* 334 */, unchecked((long) 0x493FC7CC8A558BA8L) /* 335 */,
unchecked((long) 0xB0B9C1533041AB45L) /* 336 */, unchecked((long) 0x321958BA470A59BDL) /* 337 */,
unchecked((long) 0x852DB00B5F46C393L) /* 338 */, unchecked((long) 0x91209B2BD336B0E5L) /* 339 */,
unchecked((long) 0x6E604F7D659EF19FL) /* 340 */, unchecked((long) 0xB99A8AE2782CCB24L) /* 341 */,
unchecked((long) 0xCCF52AB6C814C4C7L) /* 342 */, unchecked((long) 0x4727D9AFBE11727BL) /* 343 */,
unchecked((long) 0x7E950D0C0121B34DL) /* 344 */, unchecked((long) 0x756F435670AD471FL) /* 345 */,
unchecked((long) 0xF5ADD442615A6849L) /* 346 */, unchecked((long) 0x4E87E09980B9957AL) /* 347 */,
unchecked((long) 0x2ACFA1DF50AEE355L) /* 348 */, unchecked((long) 0xD898263AFD2FD556L) /* 349 */,
unchecked((long) 0xC8F4924DD80C8FD6L) /* 350 */, unchecked((long) 0xCF99CA3D754A173AL) /* 351 */,
unchecked((long) 0xFE477BACAF91BF3CL) /* 352 */, unchecked((long) 0xED5371F6D690C12DL) /* 353 */,
unchecked((long) 0x831A5C285E687094L) /* 354 */, unchecked((long) 0xC5D3C90A3708A0A4L) /* 355 */,
unchecked((long) 0x0F7F903717D06580L) /* 356 */, unchecked((long) 0x19F9BB13B8FDF27FL) /* 357 */,
unchecked((long) 0xB1BD6F1B4D502843L) /* 358 */, unchecked((long) 0x1C761BA38FFF4012L) /* 359 */,
unchecked((long) 0x0D1530C4E2E21F3BL) /* 360 */, unchecked((long) 0x8943CE69A7372C8AL) /* 361 */,
unchecked((long) 0xE5184E11FEB5CE66L) /* 362 */, unchecked((long) 0x618BDB80BD736621L) /* 363 */,
unchecked((long) 0x7D29BAD68B574D0BL) /* 364 */, unchecked((long) 0x81BB613E25E6FE5BL) /* 365 */,
unchecked((long) 0x071C9C10BC07913FL) /* 366 */, unchecked((long) 0xC7BEEB7909AC2D97L) /* 367 */,
unchecked((long) 0xC3E58D353BC5D757L) /* 368 */, unchecked((long) 0xEB017892F38F61E8L) /* 369 */,
unchecked((long) 0xD4EFFB9C9B1CC21AL) /* 370 */, unchecked((long) 0x99727D26F494F7ABL) /* 371 */,
unchecked((long) 0xA3E063A2956B3E03L) /* 372 */, unchecked((long) 0x9D4A8B9A4AA09C30L) /* 373 */,
unchecked((long) 0x3F6AB7D500090FB4L) /* 374 */, unchecked((long) 0x9CC0F2A057268AC0L) /* 375 */,
unchecked((long) 0x3DEE9D2DEDBF42D1L) /* 376 */, unchecked((long) 0x330F49C87960A972L) /* 377 */,
unchecked((long) 0xC6B2720287421B41L) /* 378 */, unchecked((long) 0x0AC59EC07C00369CL) /* 379 */,
unchecked((long) 0xEF4EAC49CB353425L) /* 380 */, unchecked((long) 0xF450244EEF0129D8L) /* 381 */,
unchecked((long) 0x8ACC46E5CAF4DEB6L) /* 382 */, unchecked((long) 0x2FFEAB63989263F7L) /* 383 */,
unchecked((long) 0x8F7CB9FE5D7A4578L) /* 384 */, unchecked((long) 0x5BD8F7644E634635L) /* 385 */,
unchecked((long) 0x427A7315BF2DC900L) /* 386 */, unchecked((long) 0x17D0C4AA2125261CL) /* 387 */,
unchecked((long) 0x3992486C93518E50L) /* 388 */, unchecked((long) 0xB4CBFEE0A2D7D4C3L) /* 389 */,
unchecked((long) 0x7C75D6202C5DDD8DL) /* 390 */, unchecked((long) 0xDBC295D8E35B6C61L) /* 391 */,
unchecked((long) 0x60B369D302032B19L) /* 392 */, unchecked((long) 0xCE42685FDCE44132L) /* 393 */,
unchecked((long) 0x06F3DDB9DDF65610L) /* 394 */, unchecked((long) 0x8EA4D21DB5E148F0L) /* 395 */,
unchecked((long) 0x20B0FCE62FCD496FL) /* 396 */, unchecked((long) 0x2C1B912358B0EE31L) /* 397 */,
unchecked((long) 0xB28317B818F5A308L) /* 398 */, unchecked((long) 0xA89C1E189CA6D2CFL) /* 399 */,
unchecked((long) 0x0C6B18576AAADBC8L) /* 400 */, unchecked((long) 0xB65DEAA91299FAE3L) /* 401 */,
unchecked((long) 0xFB2B794B7F1027E7L) /* 402 */, unchecked((long) 0x04E4317F443B5BEBL) /* 403 */,
unchecked((long) 0x4B852D325939D0A6L) /* 404 */, unchecked((long) 0xD5AE6BEEFB207FFCL) /* 405 */,
unchecked((long) 0x309682B281C7D374L) /* 406 */, unchecked((long) 0xBAE309A194C3B475L) /* 407 */,
unchecked((long) 0x8CC3F97B13B49F05L) /* 408 */, unchecked((long) 0x98A9422FF8293967L) /* 409 */,
unchecked((long) 0x244B16B01076FF7CL) /* 410 */, unchecked((long) 0xF8BF571C663D67EEL) /* 411 */,
unchecked((long) 0x1F0D6758EEE30DA1L) /* 412 */, unchecked((long) 0xC9B611D97ADEB9B7L) /* 413 */,
unchecked((long) 0xB7AFD5887B6C57A2L) /* 414 */, unchecked((long) 0x6290AE846B984FE1L) /* 415 */,
unchecked((long) 0x94DF4CDEACC1A5FDL) /* 416 */, unchecked((long) 0x058A5BD1C5483AFFL) /* 417 */,
unchecked((long) 0x63166CC142BA3C37L) /* 418 */, unchecked((long) 0x8DB8526EB2F76F40L) /* 419 */,
unchecked((long) 0xE10880036F0D6D4EL) /* 420 */, unchecked((long) 0x9E0523C9971D311DL) /* 421 */,
unchecked((long) 0x45EC2824CC7CD691L) /* 422 */, unchecked((long) 0x575B8359E62382C9L) /* 423 */,
unchecked((long) 0xFA9E400DC4889995L) /* 424 */, unchecked((long) 0xD1823ECB45721568L) /* 425 */,
unchecked((long) 0xDAFD983B8206082FL) /* 426 */, unchecked((long) 0xAA7D29082386A8CBL) /* 427 */,
unchecked((long) 0x269FCD4403B87588L) /* 428 */, unchecked((long) 0x1B91F5F728BDD1E0L) /* 429 */,
unchecked((long) 0xE4669F39040201F6L) /* 430 */, unchecked((long) 0x7A1D7C218CF04ADEL) /* 431 */,
unchecked((long) 0x65623C29D79CE5CEL) /* 432 */, unchecked((long) 0x2368449096C00BB1L) /* 433 */,
unchecked((long) 0xAB9BF1879DA503BAL) /* 434 */, unchecked((long) 0xBC23ECB1A458058EL) /* 435 */,
unchecked((long) 0x9A58DF01BB401ECCL) /* 436 */, unchecked((long) 0xA070E868A85F143DL) /* 437 */,
unchecked((long) 0x4FF188307DF2239EL) /* 438 */, unchecked((long) 0x14D565B41A641183L) /* 439 */,
unchecked((long) 0xEE13337452701602L) /* 440 */, unchecked((long) 0x950E3DCF3F285E09L) /* 441 */,
unchecked((long) 0x59930254B9C80953L) /* 442 */, unchecked((long) 0x3BF299408930DA6DL) /* 443 */,
unchecked((long) 0xA955943F53691387L) /* 444 */, unchecked((long) 0xA15EDECAA9CB8784L) /* 445 */,
unchecked((long) 0x29142127352BE9A0L) /* 446 */, unchecked((long) 0x76F0371FFF4E7AFBL) /* 447 */,
unchecked((long) 0x0239F450274F2228L) /* 448 */, unchecked((long) 0xBB073AF01D5E868BL) /* 449 */,
unchecked((long) 0xBFC80571C10E96C1L) /* 450 */, unchecked((long) 0xD267088568222E23L) /* 451 */,
unchecked((long) 0x9671A3D48E80B5B0L) /* 452 */, unchecked((long) 0x55B5D38AE193BB81L) /* 453 */,
unchecked((long) 0x693AE2D0A18B04B8L) /* 454 */, unchecked((long) 0x5C48B4ECADD5335FL) /* 455 */,
unchecked((long) 0xFD743B194916A1CAL) /* 456 */, unchecked((long) 0x2577018134BE98C4L) /* 457 */,
unchecked((long) 0xE77987E83C54A4ADL) /* 458 */, unchecked((long) 0x28E11014DA33E1B9L) /* 459 */,
unchecked((long) 0x270CC59E226AA213L) /* 460 */, unchecked((long) 0x71495F756D1A5F60L) /* 461 */,
unchecked((long) 0x9BE853FB60AFEF77L) /* 462 */, unchecked((long) 0xADC786A7F7443DBFL) /* 463 */,
unchecked((long) 0x0904456173B29A82L) /* 464 */, unchecked((long) 0x58BC7A66C232BD5EL) /* 465 */,
unchecked((long) 0xF306558C673AC8B2L) /* 466 */, unchecked((long) 0x41F639C6B6C9772AL) /* 467 */,
unchecked((long) 0x216DEFE99FDA35DAL) /* 468 */, unchecked((long) 0x11640CC71C7BE615L) /* 469 */,
unchecked((long) 0x93C43694565C5527L) /* 470 */, unchecked((long) 0xEA038E6246777839L) /* 471 */,
unchecked((long) 0xF9ABF3CE5A3E2469L) /* 472 */, unchecked((long) 0x741E768D0FD312D2L) /* 473 */,
unchecked((long) 0x0144B883CED652C6L) /* 474 */, unchecked((long) 0xC20B5A5BA33F8552L) /* 475 */,
unchecked((long) 0x1AE69633C3435A9DL) /* 476 */, unchecked((long) 0x97A28CA4088CFDECL) /* 477 */,
unchecked((long) 0x8824A43C1E96F420L) /* 478 */, unchecked((long) 0x37612FA66EEEA746L) /* 479 */,
unchecked((long) 0x6B4CB165F9CF0E5AL) /* 480 */, unchecked((long) 0x43AA1C06A0ABFB4AL) /* 481 */,
unchecked((long) 0x7F4DC26FF162796BL) /* 482 */, unchecked((long) 0x6CBACC8E54ED9B0FL) /* 483 */,
unchecked((long) 0xA6B7FFEFD2BB253EL) /* 484 */, unchecked((long) 0x2E25BC95B0A29D4FL) /* 485 */,
unchecked((long) 0x86D6A58BDEF1388CL) /* 486 */, unchecked((long) 0xDED74AC576B6F054L) /* 487 */,
unchecked((long) 0x8030BDBC2B45805DL) /* 488 */, unchecked((long) 0x3C81AF70E94D9289L) /* 489 */,
unchecked((long) 0x3EFF6DDA9E3100DBL) /* 490 */, unchecked((long) 0xB38DC39FDFCC8847L) /* 491 */,
unchecked((long) 0x123885528D17B87EL) /* 492 */, unchecked((long) 0xF2DA0ED240B1B642L) /* 493 */,
unchecked((long) 0x44CEFADCD54BF9A9L) /* 494 */, unchecked((long) 0x1312200E433C7EE6L) /* 495 */,
unchecked((long) 0x9FFCC84F3A78C748L) /* 496 */, unchecked((long) 0xF0CD1F72248576BBL) /* 497 */,
unchecked((long) 0xEC6974053638CFE4L) /* 498 */, unchecked((long) 0x2BA7B67C0CEC4E4CL) /* 499 */,
unchecked((long) 0xAC2F4DF3E5CE32EDL) /* 500 */, unchecked((long) 0xCB33D14326EA4C11L) /* 501 */,
unchecked((long) 0xA4E9044CC77E58BCL) /* 502 */, unchecked((long) 0x5F513293D934FCEFL) /* 503 */,
unchecked((long) 0x5DC9645506E55444L) /* 504 */, unchecked((long) 0x50DE418F317DE40AL) /* 505 */,
unchecked((long) 0x388CB31A69DDE259L) /* 506 */, unchecked((long) 0x2DB4A83455820A86L) /* 507 */,
unchecked((long) 0x9010A91E84711AE9L) /* 508 */, unchecked((long) 0x4DF7F0B7B1498371L) /* 509 */,
unchecked((long) 0xD62A2EABC0977179L) /* 510 */, unchecked((long) 0x22FAC097AA8D5C0EL) /* 511 */,
};
private static readonly long[] t3 = {
unchecked((long) 0xF49FCC2FF1DAF39BL) /* 512 */, unchecked((long) 0x487FD5C66FF29281L) /* 513 */,
unchecked((long) 0xE8A30667FCDCA83FL) /* 514 */, unchecked((long) 0x2C9B4BE3D2FCCE63L) /* 515 */,
unchecked((long) 0xDA3FF74B93FBBBC2L) /* 516 */, unchecked((long) 0x2FA165D2FE70BA66L) /* 517 */,
unchecked((long) 0xA103E279970E93D4L) /* 518 */, unchecked((long) 0xBECDEC77B0E45E71L) /* 519 */,
unchecked((long) 0xCFB41E723985E497L) /* 520 */, unchecked((long) 0xB70AAA025EF75017L) /* 521 */,
unchecked((long) 0xD42309F03840B8E0L) /* 522 */, unchecked((long) 0x8EFC1AD035898579L) /* 523 */,
unchecked((long) 0x96C6920BE2B2ABC5L) /* 524 */, unchecked((long) 0x66AF4163375A9172L) /* 525 */,
unchecked((long) 0x2174ABDCCA7127FBL) /* 526 */, unchecked((long) 0xB33CCEA64A72FF41L) /* 527 */,
unchecked((long) 0xF04A4933083066A5L) /* 528 */, unchecked((long) 0x8D970ACDD7289AF5L) /* 529 */,
unchecked((long) 0x8F96E8E031C8C25EL) /* 530 */, unchecked((long) 0xF3FEC02276875D47L) /* 531 */,
unchecked((long) 0xEC7BF310056190DDL) /* 532 */, unchecked((long) 0xF5ADB0AEBB0F1491L) /* 533 */,
unchecked((long) 0x9B50F8850FD58892L) /* 534 */, unchecked((long) 0x4975488358B74DE8L) /* 535 */,
unchecked((long) 0xA3354FF691531C61L) /* 536 */, unchecked((long) 0x0702BBE481D2C6EEL) /* 537 */,
unchecked((long) 0x89FB24057DEDED98L) /* 538 */, unchecked((long) 0xAC3075138596E902L) /* 539 */,
unchecked((long) 0x1D2D3580172772EDL) /* 540 */, unchecked((long) 0xEB738FC28E6BC30DL) /* 541 */,
unchecked((long) 0x5854EF8F63044326L) /* 542 */, unchecked((long) 0x9E5C52325ADD3BBEL) /* 543 */,
unchecked((long) 0x90AA53CF325C4623L) /* 544 */, unchecked((long) 0xC1D24D51349DD067L) /* 545 */,
unchecked((long) 0x2051CFEEA69EA624L) /* 546 */, unchecked((long) 0x13220F0A862E7E4FL) /* 547 */,
unchecked((long) 0xCE39399404E04864L) /* 548 */, unchecked((long) 0xD9C42CA47086FCB7L) /* 549 */,
unchecked((long) 0x685AD2238A03E7CCL) /* 550 */, unchecked((long) 0x066484B2AB2FF1DBL) /* 551 */,
unchecked((long) 0xFE9D5D70EFBF79ECL) /* 552 */, unchecked((long) 0x5B13B9DD9C481854L) /* 553 */,
unchecked((long) 0x15F0D475ED1509ADL) /* 554 */, unchecked((long) 0x0BEBCD060EC79851L) /* 555 */,
unchecked((long) 0xD58C6791183AB7F8L) /* 556 */, unchecked((long) 0xD1187C5052F3EEE4L) /* 557 */,
unchecked((long) 0xC95D1192E54E82FFL) /* 558 */, unchecked((long) 0x86EEA14CB9AC6CA2L) /* 559 */,
unchecked((long) 0x3485BEB153677D5DL) /* 560 */, unchecked((long) 0xDD191D781F8C492AL) /* 561 */,
unchecked((long) 0xF60866BAA784EBF9L) /* 562 */, unchecked((long) 0x518F643BA2D08C74L) /* 563 */,
unchecked((long) 0x8852E956E1087C22L) /* 564 */, unchecked((long) 0xA768CB8DC410AE8DL) /* 565 */,
unchecked((long) 0x38047726BFEC8E1AL) /* 566 */, unchecked((long) 0xA67738B4CD3B45AAL) /* 567 */,
unchecked((long) 0xAD16691CEC0DDE19L) /* 568 */, unchecked((long) 0xC6D4319380462E07L) /* 569 */,
unchecked((long) 0xC5A5876D0BA61938L) /* 570 */, unchecked((long) 0x16B9FA1FA58FD840L) /* 571 */,
unchecked((long) 0x188AB1173CA74F18L) /* 572 */, unchecked((long) 0xABDA2F98C99C021FL) /* 573 */,
unchecked((long) 0x3E0580AB134AE816L) /* 574 */, unchecked((long) 0x5F3B05B773645ABBL) /* 575 */,
unchecked((long) 0x2501A2BE5575F2F6L) /* 576 */, unchecked((long) 0x1B2F74004E7E8BA9L) /* 577 */,
unchecked((long) 0x1CD7580371E8D953L) /* 578 */, unchecked((long) 0x7F6ED89562764E30L) /* 579 */,
unchecked((long) 0xB15926FF596F003DL) /* 580 */, unchecked((long) 0x9F65293DA8C5D6B9L) /* 581 */,
unchecked((long) 0x6ECEF04DD690F84CL) /* 582 */, unchecked((long) 0x4782275FFF33AF88L) /* 583 */,
unchecked((long) 0xE41433083F820801L) /* 584 */, unchecked((long) 0xFD0DFE409A1AF9B5L) /* 585 */,
unchecked((long) 0x4325A3342CDB396BL) /* 586 */, unchecked((long) 0x8AE77E62B301B252L) /* 587 */,
unchecked((long) 0xC36F9E9F6655615AL) /* 588 */, unchecked((long) 0x85455A2D92D32C09L) /* 589 */,
unchecked((long) 0xF2C7DEA949477485L) /* 590 */, unchecked((long) 0x63CFB4C133A39EBAL) /* 591 */,
unchecked((long) 0x83B040CC6EBC5462L) /* 592 */, unchecked((long) 0x3B9454C8FDB326B0L) /* 593 */,
unchecked((long) 0x56F56A9E87FFD78CL) /* 594 */, unchecked((long) 0x2DC2940D99F42BC6L) /* 595 */,
unchecked((long) 0x98F7DF096B096E2DL) /* 596 */, unchecked((long) 0x19A6E01E3AD852BFL) /* 597 */,
unchecked((long) 0x42A99CCBDBD4B40BL) /* 598 */, unchecked((long) 0xA59998AF45E9C559L) /* 599 */,
unchecked((long) 0x366295E807D93186L) /* 600 */, unchecked((long) 0x6B48181BFAA1F773L) /* 601 */,
unchecked((long) 0x1FEC57E2157A0A1DL) /* 602 */, unchecked((long) 0x4667446AF6201AD5L) /* 603 */,
unchecked((long) 0xE615EBCACFB0F075L) /* 604 */, unchecked((long) 0xB8F31F4F68290778L) /* 605 */,
unchecked((long) 0x22713ED6CE22D11EL) /* 606 */, unchecked((long) 0x3057C1A72EC3C93BL) /* 607 */,
unchecked((long) 0xCB46ACC37C3F1F2FL) /* 608 */, unchecked((long) 0xDBB893FD02AAF50EL) /* 609 */,
unchecked((long) 0x331FD92E600B9FCFL) /* 610 */, unchecked((long) 0xA498F96148EA3AD6L) /* 611 */,
unchecked((long) 0xA8D8426E8B6A83EAL) /* 612 */, unchecked((long) 0xA089B274B7735CDCL) /* 613 */,
unchecked((long) 0x87F6B3731E524A11L) /* 614 */, unchecked((long) 0x118808E5CBC96749L) /* 615 */,
unchecked((long) 0x9906E4C7B19BD394L) /* 616 */, unchecked((long) 0xAFED7F7E9B24A20CL) /* 617 */,
unchecked((long) 0x6509EADEEB3644A7L) /* 618 */, unchecked((long) 0x6C1EF1D3E8EF0EDEL) /* 619 */,
unchecked((long) 0xB9C97D43E9798FB4L) /* 620 */, unchecked((long) 0xA2F2D784740C28A3L) /* 621 */,
unchecked((long) 0x7B8496476197566FL) /* 622 */, unchecked((long) 0x7A5BE3E6B65F069DL) /* 623 */,
unchecked((long) 0xF96330ED78BE6F10L) /* 624 */, unchecked((long) 0xEEE60DE77A076A15L) /* 625 */,
unchecked((long) 0x2B4BEE4AA08B9BD0L) /* 626 */, unchecked((long) 0x6A56A63EC7B8894EL) /* 627 */,
unchecked((long) 0x02121359BA34FEF4L) /* 628 */, unchecked((long) 0x4CBF99F8283703FCL) /* 629 */,
unchecked((long) 0x398071350CAF30C8L) /* 630 */, unchecked((long) 0xD0A77A89F017687AL) /* 631 */,
unchecked((long) 0xF1C1A9EB9E423569L) /* 632 */, unchecked((long) 0x8C7976282DEE8199L) /* 633 */,
unchecked((long) 0x5D1737A5DD1F7ABDL) /* 634 */, unchecked((long) 0x4F53433C09A9FA80L) /* 635 */,
unchecked((long) 0xFA8B0C53DF7CA1D9L) /* 636 */, unchecked((long) 0x3FD9DCBC886CCB77L) /* 637 */,
unchecked((long) 0xC040917CA91B4720L) /* 638 */, unchecked((long) 0x7DD00142F9D1DCDFL) /* 639 */,
unchecked((long) 0x8476FC1D4F387B58L) /* 640 */, unchecked((long) 0x23F8E7C5F3316503L) /* 641 */,
unchecked((long) 0x032A2244E7E37339L) /* 642 */, unchecked((long) 0x5C87A5D750F5A74BL) /* 643 */,
unchecked((long) 0x082B4CC43698992EL) /* 644 */, unchecked((long) 0xDF917BECB858F63CL) /* 645 */,
unchecked((long) 0x3270B8FC5BF86DDAL) /* 646 */, unchecked((long) 0x10AE72BB29B5DD76L) /* 647 */,
unchecked((long) 0x576AC94E7700362BL) /* 648 */, unchecked((long) 0x1AD112DAC61EFB8FL) /* 649 */,
unchecked((long) 0x691BC30EC5FAA427L) /* 650 */, unchecked((long) 0xFF246311CC327143L) /* 651 */,
unchecked((long) 0x3142368E30E53206L) /* 652 */, unchecked((long) 0x71380E31E02CA396L) /* 653 */,
unchecked((long) 0x958D5C960AAD76F1L) /* 654 */, unchecked((long) 0xF8D6F430C16DA536L) /* 655 */,
unchecked((long) 0xC8FFD13F1BE7E1D2L) /* 656 */, unchecked((long) 0x7578AE66004DDBE1L) /* 657 */,
unchecked((long) 0x05833F01067BE646L) /* 658 */, unchecked((long) 0xBB34B5AD3BFE586DL) /* 659 */,
unchecked((long) 0x095F34C9A12B97F0L) /* 660 */, unchecked((long) 0x247AB64525D60CA8L) /* 661 */,
unchecked((long) 0xDCDBC6F3017477D1L) /* 662 */, unchecked((long) 0x4A2E14D4DECAD24DL) /* 663 */,
unchecked((long) 0xBDB5E6D9BE0A1EEBL) /* 664 */, unchecked((long) 0x2A7E70F7794301ABL) /* 665 */,
unchecked((long) 0xDEF42D8A270540FDL) /* 666 */, unchecked((long) 0x01078EC0A34C22C1L) /* 667 */,
unchecked((long) 0xE5DE511AF4C16387L) /* 668 */, unchecked((long) 0x7EBB3A52BD9A330AL) /* 669 */,
unchecked((long) 0x77697857AA7D6435L) /* 670 */, unchecked((long) 0x004E831603AE4C32L) /* 671 */,
unchecked((long) 0xE7A21020AD78E312L) /* 672 */, unchecked((long) 0x9D41A70C6AB420F2L) /* 673 */,
unchecked((long) 0x28E06C18EA1141E6L) /* 674 */, unchecked((long) 0xD2B28CBD984F6B28L) /* 675 */,
unchecked((long) 0x26B75F6C446E9D83L) /* 676 */, unchecked((long) 0xBA47568C4D418D7FL) /* 677 */,
unchecked((long) 0xD80BADBFE6183D8EL) /* 678 */, unchecked((long) 0x0E206D7F5F166044L) /* 679 */,
unchecked((long) 0xE258A43911CBCA3EL) /* 680 */, unchecked((long) 0x723A1746B21DC0BCL) /* 681 */,
unchecked((long) 0xC7CAA854F5D7CDD3L) /* 682 */, unchecked((long) 0x7CAC32883D261D9CL) /* 683 */,
unchecked((long) 0x7690C26423BA942CL) /* 684 */, unchecked((long) 0x17E55524478042B8L) /* 685 */,
unchecked((long) 0xE0BE477656A2389FL) /* 686 */, unchecked((long) 0x4D289B5E67AB2DA0L) /* 687 */,
unchecked((long) 0x44862B9C8FBBFD31L) /* 688 */, unchecked((long) 0xB47CC8049D141365L) /* 689 */,
unchecked((long) 0x822C1B362B91C793L) /* 690 */, unchecked((long) 0x4EB14655FB13DFD8L) /* 691 */,
unchecked((long) 0x1ECBBA0714E2A97BL) /* 692 */, unchecked((long) 0x6143459D5CDE5F14L) /* 693 */,
unchecked((long) 0x53A8FBF1D5F0AC89L) /* 694 */, unchecked((long) 0x97EA04D81C5E5B00L) /* 695 */,
unchecked((long) 0x622181A8D4FDB3F3L) /* 696 */, unchecked((long) 0xE9BCD341572A1208L) /* 697 */,
unchecked((long) 0x1411258643CCE58AL) /* 698 */, unchecked((long) 0x9144C5FEA4C6E0A4L) /* 699 */,
unchecked((long) 0x0D33D06565CF620FL) /* 700 */, unchecked((long) 0x54A48D489F219CA1L) /* 701 */,
unchecked((long) 0xC43E5EAC6D63C821L) /* 702 */, unchecked((long) 0xA9728B3A72770DAFL) /* 703 */,
unchecked((long) 0xD7934E7B20DF87EFL) /* 704 */, unchecked((long) 0xE35503B61A3E86E5L) /* 705 */,
unchecked((long) 0xCAE321FBC819D504L) /* 706 */, unchecked((long) 0x129A50B3AC60BFA6L) /* 707 */,
unchecked((long) 0xCD5E68EA7E9FB6C3L) /* 708 */, unchecked((long) 0xB01C90199483B1C7L) /* 709 */,
unchecked((long) 0x3DE93CD5C295376CL) /* 710 */, unchecked((long) 0xAED52EDF2AB9AD13L) /* 711 */,
unchecked((long) 0x2E60F512C0A07884L) /* 712 */, unchecked((long) 0xBC3D86A3E36210C9L) /* 713 */,
unchecked((long) 0x35269D9B163951CEL) /* 714 */, unchecked((long) 0x0C7D6E2AD0CDB5FAL) /* 715 */,
unchecked((long) 0x59E86297D87F5733L) /* 716 */, unchecked((long) 0x298EF221898DB0E7L) /* 717 */,
unchecked((long) 0x55000029D1A5AA7EL) /* 718 */, unchecked((long) 0x8BC08AE1B5061B45L) /* 719 */,
unchecked((long) 0xC2C31C2B6C92703AL) /* 720 */, unchecked((long) 0x94CC596BAF25EF42L) /* 721 */,
unchecked((long) 0x0A1D73DB22540456L) /* 722 */, unchecked((long) 0x04B6A0F9D9C4179AL) /* 723 */,
unchecked((long) 0xEFFDAFA2AE3D3C60L) /* 724 */, unchecked((long) 0xF7C8075BB49496C4L) /* 725 */,
unchecked((long) 0x9CC5C7141D1CD4E3L) /* 726 */, unchecked((long) 0x78BD1638218E5534L) /* 727 */,
unchecked((long) 0xB2F11568F850246AL) /* 728 */, unchecked((long) 0xEDFABCFA9502BC29L) /* 729 */,
unchecked((long) 0x796CE5F2DA23051BL) /* 730 */, unchecked((long) 0xAAE128B0DC93537CL) /* 731 */,
unchecked((long) 0x3A493DA0EE4B29AEL) /* 732 */, unchecked((long) 0xB5DF6B2C416895D7L) /* 733 */,
unchecked((long) 0xFCABBD25122D7F37L) /* 734 */, unchecked((long) 0x70810B58105DC4B1L) /* 735 */,
unchecked((long) 0xE10FDD37F7882A90L) /* 736 */, unchecked((long) 0x524DCAB5518A3F5CL) /* 737 */,
unchecked((long) 0x3C9E85878451255BL) /* 738 */, unchecked((long) 0x4029828119BD34E2L) /* 739 */,
unchecked((long) 0x74A05B6F5D3CECCBL) /* 740 */, unchecked((long) 0xB610021542E13ECAL) /* 741 */,
unchecked((long) 0x0FF979D12F59E2ACL) /* 742 */, unchecked((long) 0x6037DA27E4F9CC50L) /* 743 */,
unchecked((long) 0x5E92975A0DF1847DL) /* 744 */, unchecked((long) 0xD66DE190D3E623FEL) /* 745 */,
unchecked((long) 0x5032D6B87B568048L) /* 746 */, unchecked((long) 0x9A36B7CE8235216EL) /* 747 */,
unchecked((long) 0x80272A7A24F64B4AL) /* 748 */, unchecked((long) 0x93EFED8B8C6916F7L) /* 749 */,
unchecked((long) 0x37DDBFF44CCE1555L) /* 750 */, unchecked((long) 0x4B95DB5D4B99BD25L) /* 751 */,
unchecked((long) 0x92D3FDA169812FC0L) /* 752 */, unchecked((long) 0xFB1A4A9A90660BB6L) /* 753 */,
unchecked((long) 0x730C196946A4B9B2L) /* 754 */, unchecked((long) 0x81E289AA7F49DA68L) /* 755 */,
unchecked((long) 0x64669A0F83B1A05FL) /* 756 */, unchecked((long) 0x27B3FF7D9644F48BL) /* 757 */,
unchecked((long) 0xCC6B615C8DB675B3L) /* 758 */, unchecked((long) 0x674F20B9BCEBBE95L) /* 759 */,
unchecked((long) 0x6F31238275655982L) /* 760 */, unchecked((long) 0x5AE488713E45CF05L) /* 761 */,
unchecked((long) 0xBF619F9954C21157L) /* 762 */, unchecked((long) 0xEABAC46040A8EAE9L) /* 763 */,
unchecked((long) 0x454C6FE9F2C0C1CDL) /* 764 */, unchecked((long) 0x419CF6496412691CL) /* 765 */,
unchecked((long) 0xD3DC3BEF265B0F70L) /* 766 */, unchecked((long) 0x6D0E60F5C3578A9EL) /* 767 */,
};
private static readonly long[] t4 = {
unchecked((long) 0x5B0E608526323C55L) /* 768 */, unchecked((long) 0x1A46C1A9FA1B59F5L) /* 769 */,
unchecked((long) 0xA9E245A17C4C8FFAL) /* 770 */, unchecked((long) 0x65CA5159DB2955D7L) /* 771 */,
unchecked((long) 0x05DB0A76CE35AFC2L) /* 772 */, unchecked((long) 0x81EAC77EA9113D45L) /* 773 */,
unchecked((long) 0x528EF88AB6AC0A0DL) /* 774 */, unchecked((long) 0xA09EA253597BE3FFL) /* 775 */,
unchecked((long) 0x430DDFB3AC48CD56L) /* 776 */, unchecked((long) 0xC4B3A67AF45CE46FL) /* 777 */,
unchecked((long) 0x4ECECFD8FBE2D05EL) /* 778 */, unchecked((long) 0x3EF56F10B39935F0L) /* 779 */,
unchecked((long) 0x0B22D6829CD619C6L) /* 780 */, unchecked((long) 0x17FD460A74DF2069L) /* 781 */,
unchecked((long) 0x6CF8CC8E8510ED40L) /* 782 */, unchecked((long) 0xD6C824BF3A6ECAA7L) /* 783 */,
unchecked((long) 0x61243D581A817049L) /* 784 */, unchecked((long) 0x048BACB6BBC163A2L) /* 785 */,
unchecked((long) 0xD9A38AC27D44CC32L) /* 786 */, unchecked((long) 0x7FDDFF5BAAF410ABL) /* 787 */,
unchecked((long) 0xAD6D495AA804824BL) /* 788 */, unchecked((long) 0xE1A6A74F2D8C9F94L) /* 789 */,
unchecked((long) 0xD4F7851235DEE8E3L) /* 790 */, unchecked((long) 0xFD4B7F886540D893L) /* 791 */,
unchecked((long) 0x247C20042AA4BFDAL) /* 792 */, unchecked((long) 0x096EA1C517D1327CL) /* 793 */,
unchecked((long) 0xD56966B4361A6685L) /* 794 */, unchecked((long) 0x277DA5C31221057DL) /* 795 */,
unchecked((long) 0x94D59893A43ACFF7L) /* 796 */, unchecked((long) 0x64F0C51CCDC02281L) /* 797 */,
unchecked((long) 0x3D33BCC4FF6189DBL) /* 798 */, unchecked((long) 0xE005CB184CE66AF1L) /* 799 */,
unchecked((long) 0xFF5CCD1D1DB99BEAL) /* 800 */, unchecked((long) 0xB0B854A7FE42980FL) /* 801 */,
unchecked((long) 0x7BD46A6A718D4B9FL) /* 802 */, unchecked((long) 0xD10FA8CC22A5FD8CL) /* 803 */,
unchecked((long) 0xD31484952BE4BD31L) /* 804 */, unchecked((long) 0xC7FA975FCB243847L) /* 805 */,
unchecked((long) 0x4886ED1E5846C407L) /* 806 */, unchecked((long) 0x28CDDB791EB70B04L) /* 807 */,
unchecked((long) 0xC2B00BE2F573417FL) /* 808 */, unchecked((long) 0x5C9590452180F877L) /* 809 */,
unchecked((long) 0x7A6BDDFFF370EB00L) /* 810 */, unchecked((long) 0xCE509E38D6D9D6A4L) /* 811 */,
unchecked((long) 0xEBEB0F00647FA702L) /* 812 */, unchecked((long) 0x1DCC06CF76606F06L) /* 813 */,
unchecked((long) 0xE4D9F28BA286FF0AL) /* 814 */, unchecked((long) 0xD85A305DC918C262L) /* 815 */,
unchecked((long) 0x475B1D8732225F54L) /* 816 */, unchecked((long) 0x2D4FB51668CCB5FEL) /* 817 */,
unchecked((long) 0xA679B9D9D72BBA20L) /* 818 */, unchecked((long) 0x53841C0D912D43A5L) /* 819 */,
unchecked((long) 0x3B7EAA48BF12A4E8L) /* 820 */, unchecked((long) 0x781E0E47F22F1DDFL) /* 821 */,
unchecked((long) 0xEFF20CE60AB50973L) /* 822 */, unchecked((long) 0x20D261D19DFFB742L) /* 823 */,
unchecked((long) 0x16A12B03062A2E39L) /* 824 */, unchecked((long) 0x1960EB2239650495L) /* 825 */,
unchecked((long) 0x251C16FED50EB8B8L) /* 826 */, unchecked((long) 0x9AC0C330F826016EL) /* 827 */,
unchecked((long) 0xED152665953E7671L) /* 828 */, unchecked((long) 0x02D63194A6369570L) /* 829 */,
unchecked((long) 0x5074F08394B1C987L) /* 830 */, unchecked((long) 0x70BA598C90B25CE1L) /* 831 */,
unchecked((long) 0x794A15810B9742F6L) /* 832 */, unchecked((long) 0x0D5925E9FCAF8C6CL) /* 833 */,
unchecked((long) 0x3067716CD868744EL) /* 834 */, unchecked((long) 0x910AB077E8D7731BL) /* 835 */,
unchecked((long) 0x6A61BBDB5AC42F61L) /* 836 */, unchecked((long) 0x93513EFBF0851567L) /* 837 */,
unchecked((long) 0xF494724B9E83E9D5L) /* 838 */, unchecked((long) 0xE887E1985C09648DL) /* 839 */,
unchecked((long) 0x34B1D3C675370CFDL) /* 840 */, unchecked((long) 0xDC35E433BC0D255DL) /* 841 */,
unchecked((long) 0xD0AAB84234131BE0L) /* 842 */, unchecked((long) 0x08042A50B48B7EAFL) /* 843 */,
unchecked((long) 0x9997C4EE44A3AB35L) /* 844 */, unchecked((long) 0x829A7B49201799D0L) /* 845 */,
unchecked((long) 0x263B8307B7C54441L) /* 846 */, unchecked((long) 0x752F95F4FD6A6CA6L) /* 847 */,
unchecked((long) 0x927217402C08C6E5L) /* 848 */, unchecked((long) 0x2A8AB754A795D9EEL) /* 849 */,
unchecked((long) 0xA442F7552F72943DL) /* 850 */, unchecked((long) 0x2C31334E19781208L) /* 851 */,
unchecked((long) 0x4FA98D7CEAEE6291L) /* 852 */, unchecked((long) 0x55C3862F665DB309L) /* 853 */,
unchecked((long) 0xBD0610175D53B1F3L) /* 854 */, unchecked((long) 0x46FE6CB840413F27L) /* 855 */,
unchecked((long) 0x3FE03792DF0CFA59L) /* 856 */, unchecked((long) 0xCFE700372EB85E8FL) /* 857 */,
unchecked((long) 0xA7BE29E7ADBCE118L) /* 858 */, unchecked((long) 0xE544EE5CDE8431DDL) /* 859 */,
unchecked((long) 0x8A781B1B41F1873EL) /* 860 */, unchecked((long) 0xA5C94C78A0D2F0E7L) /* 861 */,
unchecked((long) 0x39412E2877B60728L) /* 862 */, unchecked((long) 0xA1265EF3AFC9A62CL) /* 863 */,
unchecked((long) 0xBCC2770C6A2506C5L) /* 864 */, unchecked((long) 0x3AB66DD5DCE1CE12L) /* 865 */,
unchecked((long) 0xE65499D04A675B37L) /* 866 */, unchecked((long) 0x7D8F523481BFD216L) /* 867 */,
unchecked((long) 0x0F6F64FCEC15F389L) /* 868 */, unchecked((long) 0x74EFBE618B5B13C8L) /* 869 */,
unchecked((long) 0xACDC82B714273E1DL) /* 870 */, unchecked((long) 0xDD40BFE003199D17L) /* 871 */,
unchecked((long) 0x37E99257E7E061F8L) /* 872 */, unchecked((long) 0xFA52626904775AAAL) /* 873 */,
unchecked((long) 0x8BBBF63A463D56F9L) /* 874 */, unchecked((long) 0xF0013F1543A26E64L) /* 875 */,
unchecked((long) 0xA8307E9F879EC898L) /* 876 */, unchecked((long) 0xCC4C27A4150177CCL) /* 877 */,
unchecked((long) 0x1B432F2CCA1D3348L) /* 878 */, unchecked((long) 0xDE1D1F8F9F6FA013L) /* 879 */,
unchecked((long) 0x606602A047A7DDD6L) /* 880 */, unchecked((long) 0xD237AB64CC1CB2C7L) /* 881 */,
unchecked((long) 0x9B938E7225FCD1D3L) /* 882 */, unchecked((long) 0xEC4E03708E0FF476L) /* 883 */,
unchecked((long) 0xFEB2FBDA3D03C12DL) /* 884 */, unchecked((long) 0xAE0BCED2EE43889AL) /* 885 */,
unchecked((long) 0x22CB8923EBFB4F43L) /* 886 */, unchecked((long) 0x69360D013CF7396DL) /* 887 */,
unchecked((long) 0x855E3602D2D4E022L) /* 888 */, unchecked((long) 0x073805BAD01F784CL) /* 889 */,
unchecked((long) 0x33E17A133852F546L) /* 890 */, unchecked((long) 0xDF4874058AC7B638L) /* 891 */,
unchecked((long) 0xBA92B29C678AA14AL) /* 892 */, unchecked((long) 0x0CE89FC76CFAADCDL) /* 893 */,
unchecked((long) 0x5F9D4E0908339E34L) /* 894 */, unchecked((long) 0xF1AFE9291F5923B9L) /* 895 */,
unchecked((long) 0x6E3480F60F4A265FL) /* 896 */, unchecked((long) 0xEEBF3A2AB29B841CL) /* 897 */,
unchecked((long) 0xE21938A88F91B4ADL) /* 898 */, unchecked((long) 0x57DFEFF845C6D3C3L) /* 899 */,
unchecked((long) 0x2F006B0BF62CAAF2L) /* 900 */, unchecked((long) 0x62F479EF6F75EE78L) /* 901 */,
unchecked((long) 0x11A55AD41C8916A9L) /* 902 */, unchecked((long) 0xF229D29084FED453L) /* 903 */,
unchecked((long) 0x42F1C27B16B000E6L) /* 904 */, unchecked((long) 0x2B1F76749823C074L) /* 905 */,
unchecked((long) 0x4B76ECA3C2745360L) /* 906 */, unchecked((long) 0x8C98F463B91691BDL) /* 907 */,
unchecked((long) 0x14BCC93CF1ADE66AL) /* 908 */, unchecked((long) 0x8885213E6D458397L) /* 909 */,
unchecked((long) 0x8E177DF0274D4711L) /* 910 */, unchecked((long) 0xB49B73B5503F2951L) /* 911 */,
unchecked((long) 0x10168168C3F96B6BL) /* 912 */, unchecked((long) 0x0E3D963B63CAB0AEL) /* 913 */,
unchecked((long) 0x8DFC4B5655A1DB14L) /* 914 */, unchecked((long) 0xF789F1356E14DE5CL) /* 915 */,
unchecked((long) 0x683E68AF4E51DAC1L) /* 916 */, unchecked((long) 0xC9A84F9D8D4B0FD9L) /* 917 */,
unchecked((long) 0x3691E03F52A0F9D1L) /* 918 */, unchecked((long) 0x5ED86E46E1878E80L) /* 919 */,
unchecked((long) 0x3C711A0E99D07150L) /* 920 */, unchecked((long) 0x5A0865B20C4E9310L) /* 921 */,
unchecked((long) 0x56FBFC1FE4F0682EL) /* 922 */, unchecked((long) 0xEA8D5DE3105EDF9BL) /* 923 */,
unchecked((long) 0x71ABFDB12379187AL) /* 924 */, unchecked((long) 0x2EB99DE1BEE77B9CL) /* 925 */,
unchecked((long) 0x21ECC0EA33CF4523L) /* 926 */, unchecked((long) 0x59A4D7521805C7A1L) /* 927 */,
unchecked((long) 0x3896F5EB56AE7C72L) /* 928 */, unchecked((long) 0xAA638F3DB18F75DCL) /* 929 */,
unchecked((long) 0x9F39358DABE9808EL) /* 930 */, unchecked((long) 0xB7DEFA91C00B72ACL) /* 931 */,
unchecked((long) 0x6B5541FD62492D92L) /* 932 */, unchecked((long) 0x6DC6DEE8F92E4D5BL) /* 933 */,
unchecked((long) 0x353F57ABC4BEEA7EL) /* 934 */, unchecked((long) 0x735769D6DA5690CEL) /* 935 */,
unchecked((long) 0x0A234AA642391484L) /* 936 */, unchecked((long) 0xF6F9508028F80D9DL) /* 937 */,
unchecked((long) 0xB8E319A27AB3F215L) /* 938 */, unchecked((long) 0x31AD9C1151341A4DL) /* 939 */,
unchecked((long) 0x773C22A57BEF5805L) /* 940 */, unchecked((long) 0x45C7561A07968633L) /* 941 */,
unchecked((long) 0xF913DA9E249DBE36L) /* 942 */, unchecked((long) 0xDA652D9B78A64C68L) /* 943 */,
unchecked((long) 0x4C27A97F3BC334EFL) /* 944 */, unchecked((long) 0x76621220E66B17F4L) /* 945 */,
unchecked((long) 0x967743899ACD7D0BL) /* 946 */, unchecked((long) 0xF3EE5BCAE0ED6782L) /* 947 */,
unchecked((long) 0x409F753600C879FCL) /* 948 */, unchecked((long) 0x06D09A39B5926DB6L) /* 949 */,
unchecked((long) 0x6F83AEB0317AC588L) /* 950 */, unchecked((long) 0x01E6CA4A86381F21L) /* 951 */,
unchecked((long) 0x66FF3462D19F3025L) /* 952 */, unchecked((long) 0x72207C24DDFD3BFBL) /* 953 */,
unchecked((long) 0x4AF6B6D3E2ECE2EBL) /* 954 */, unchecked((long) 0x9C994DBEC7EA08DEL) /* 955 */,
unchecked((long) 0x49ACE597B09A8BC4L) /* 956 */, unchecked((long) 0xB38C4766CF0797BAL) /* 957 */,
unchecked((long) 0x131B9373C57C2A75L) /* 958 */, unchecked((long) 0xB1822CCE61931E58L) /* 959 */,
unchecked((long) 0x9D7555B909BA1C0CL) /* 960 */, unchecked((long) 0x127FAFDD937D11D2L) /* 961 */,
unchecked((long) 0x29DA3BADC66D92E4L) /* 962 */, unchecked((long) 0xA2C1D57154C2ECBCL) /* 963 */,
unchecked((long) 0x58C5134D82F6FE24L) /* 964 */, unchecked((long) 0x1C3AE3515B62274FL) /* 965 */,
unchecked((long) 0xE907C82E01CB8126L) /* 966 */, unchecked((long) 0xF8ED091913E37FCBL) /* 967 */,
unchecked((long) 0x3249D8F9C80046C9L) /* 968 */, unchecked((long) 0x80CF9BEDE388FB63L) /* 969 */,
unchecked((long) 0x1881539A116CF19EL) /* 970 */, unchecked((long) 0x5103F3F76BD52457L) /* 971 */,
unchecked((long) 0x15B7E6F5AE47F7A8L) /* 972 */, unchecked((long) 0xDBD7C6DED47E9CCFL) /* 973 */,
unchecked((long) 0x44E55C410228BB1AL) /* 974 */, unchecked((long) 0xB647D4255EDB4E99L) /* 975 */,
unchecked((long) 0x5D11882BB8AAFC30L) /* 976 */, unchecked((long) 0xF5098BBB29D3212AL) /* 977 */,
unchecked((long) 0x8FB5EA14E90296B3L) /* 978 */, unchecked((long) 0x677B942157DD025AL) /* 979 */,
unchecked((long) 0xFB58E7C0A390ACB5L) /* 980 */, unchecked((long) 0x89D3674C83BD4A01L) /* 981 */,
unchecked((long) 0x9E2DA4DF4BF3B93BL) /* 982 */, unchecked((long) 0xFCC41E328CAB4829L) /* 983 */,
unchecked((long) 0x03F38C96BA582C52L) /* 984 */, unchecked((long) 0xCAD1BDBD7FD85DB2L) /* 985 */,
unchecked((long) 0xBBB442C16082AE83L) /* 986 */, unchecked((long) 0xB95FE86BA5DA9AB0L) /* 987 */,
unchecked((long) 0xB22E04673771A93FL) /* 988 */, unchecked((long) 0x845358C9493152D8L) /* 989 */,
unchecked((long) 0xBE2A488697B4541EL) /* 990 */, unchecked((long) 0x95A2DC2DD38E6966L) /* 991 */,
unchecked((long) 0xC02C11AC923C852BL) /* 992 */, unchecked((long) 0x2388B1990DF2A87BL) /* 993 */,
unchecked((long) 0x7C8008FA1B4F37BEL) /* 994 */, unchecked((long) 0x1F70D0C84D54E503L) /* 995 */,
unchecked((long) 0x5490ADEC7ECE57D4L) /* 996 */, unchecked((long) 0x002B3C27D9063A3AL) /* 997 */,
unchecked((long) 0x7EAEA3848030A2BFL) /* 998 */, unchecked((long) 0xC602326DED2003C0L) /* 999 */,
unchecked((long) 0x83A7287D69A94086L) /* 1000 */, unchecked((long) 0xC57A5FCB30F57A8AL) /* 1001 */,
unchecked((long) 0xB56844E479EBE779L) /* 1002 */, unchecked((long) 0xA373B40F05DCBCE9L) /* 1003 */,
unchecked((long) 0xD71A786E88570EE2L) /* 1004 */, unchecked((long) 0x879CBACDBDE8F6A0L) /* 1005 */,
unchecked((long) 0x976AD1BCC164A32FL) /* 1006 */, unchecked((long) 0xAB21E25E9666D78BL) /* 1007 */,
unchecked((long) 0x901063AAE5E5C33CL) /* 1008 */, unchecked((long) 0x9818B34448698D90L) /* 1009 */,
unchecked((long) 0xE36487AE3E1E8ABBL) /* 1010 */, unchecked((long) 0xAFBDF931893BDCB4L) /* 1011 */,
unchecked((long) 0x6345A0DC5FBBD519L) /* 1012 */, unchecked((long) 0x8628FE269B9465CAL) /* 1013 */,
unchecked((long) 0x1E5D01603F9C51ECL) /* 1014 */, unchecked((long) 0x4DE44006A15049B7L) /* 1015 */,
unchecked((long) 0xBF6C70E5F776CBB1L) /* 1016 */, unchecked((long) 0x411218F2EF552BEDL) /* 1017 */,
unchecked((long) 0xCB0C0708705A36A3L) /* 1018 */, unchecked((long) 0xE74D14754F986044L) /* 1019 */,
unchecked((long) 0xCD56D9430EA8280EL) /* 1020 */, unchecked((long) 0xC12591D7535F5065L) /* 1021 */,
unchecked((long) 0xC83223F1720AEF96L) /* 1022 */, unchecked((long) 0xC3A0396F7363A51FL) /* 1023 */
};
private const int DigestLength = 24;
//
// registers
//
private long a, b, c;
private long byteCount;
//
// buffers
//
private byte[] m_buffer = new byte[8];
private int bOff;
private long[] x = new long[8];
private int xOff;
/**
* Standard constructor
*/
public TigerDigest()
{
Reset();
}
/**
* Copy constructor. This will copy the state of the provided
* message digest.
*/
public TigerDigest(TigerDigest t)
{
Reset(t);
}
public string AlgorithmName
{
get { return "Tiger"; }
}
public int GetDigestSize()
{
return DigestLength;
}
public int GetByteLength()
{
return MyByteLength;
}
private void ProcessWord(byte[] b, int off)
{
x[xOff++] = (long)Pack.LE_To_UInt64(b, off);
if (xOff == x.Length)
{
ProcessBlock();
}
bOff = 0;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private void ProcessWord(ReadOnlySpan<byte> b)
{
x[xOff++] = (long)Pack.LE_To_UInt64(b);
if (xOff == x.Length)
{
ProcessBlock();
}
bOff = 0;
}
#endif
public void Update(
byte input)
{
m_buffer[bOff++] = input;
if (bOff == m_buffer.Length)
{
ProcessWord(m_buffer, 0);
}
byteCount++;
}
public void BlockUpdate(
byte[] input,
int inOff,
int length)
{
//
// fill the current word
//
while ((bOff != 0) && (length > 0))
{
Update(input[inOff]);
inOff++;
length--;
}
//
// process whole words.
//
while (length >= 8)
{
ProcessWord(input, inOff);
inOff += 8;
length -= 8;
byteCount += 8;
}
//
// load in the remainder.
//
while (length > 0)
{
Update(input[inOff]);
inOff++;
length--;
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void BlockUpdate(ReadOnlySpan<byte> input)
{
int inOff = 0, length = input.Length;
//
// fill the current word
//
while ((bOff != 0) && (length > 0))
{
Update(input[inOff]);
inOff++;
length--;
}
//
// process whole words.
//
while (length >= 8)
{
ProcessWord(input[inOff..]);
inOff += 8;
length -= 8;
byteCount += 8;
}
//
// load in the remainder.
//
while (length > 0)
{
Update(input[inOff]);
inOff++;
length--;
}
}
#endif
private void RoundABC(
long x,
long mul)
{
c ^= x ;
a -= t1[(int)c & 0xff] ^ t2[(int)(c >> 16) & 0xff]
^ t3[(int)(c >> 32) & 0xff] ^ t4[(int)(c >> 48) & 0xff];
b += t4[(int)(c >> 8) & 0xff] ^ t3[(int)(c >> 24) & 0xff]
^ t2[(int)(c >> 40) & 0xff] ^ t1[(int)(c >> 56) & 0xff];
b *= mul;
}
private void RoundBCA(
long x,
long mul)
{
a ^= x ;
b -= t1[(int)a & 0xff] ^ t2[(int)(a >> 16) & 0xff]
^ t3[(int)(a >> 32) & 0xff] ^ t4[(int)(a >> 48) & 0xff];
c += t4[(int)(a >> 8) & 0xff] ^ t3[(int)(a >> 24) & 0xff]
^ t2[(int)(a >> 40) & 0xff] ^ t1[(int)(a >> 56) & 0xff];
c *= mul;
}
private void RoundCAB(
long x,
long mul)
{
b ^= x ;
c -= t1[(int)b & 0xff] ^ t2[(int)(b >> 16) & 0xff]
^ t3[(int)(b >> 32) & 0xff] ^ t4[(int)(b >> 48) & 0xff];
a += t4[(int)(b >> 8) & 0xff] ^ t3[(int)(b >> 24) & 0xff]
^ t2[(int)(b >> 40) & 0xff] ^ t1[(int)(b >> 56) & 0xff];
a *= mul;
}
private void KeySchedule()
{
x[0] -= x[7] ^ unchecked ((long) 0xA5A5A5A5A5A5A5A5L);
x[1] ^= x[0];
x[2] += x[1];
x[3] -= x[2] ^ ((~x[1]) << 19);
x[4] ^= x[3];
x[5] += x[4];
x[6] -= x[5] ^ (long) ((ulong) (~x[4]) >> 23);
x[7] ^= x[6];
x[0] += x[7];
x[1] -= x[0] ^ ((~x[7]) << 19);
x[2] ^= x[1];
x[3] += x[2];
x[4] -= x[3] ^ (long) ((ulong) (~x[2]) >> 23);
x[5] ^= x[4];
x[6] += x[5];
x[7] -= x[6] ^ 0x0123456789ABCDEFL;
}
private void ProcessBlock()
{
//
// save abc
//
long aa = a;
long bb = b;
long cc = c;
//
// rounds and schedule
//
RoundABC(x[0], 5);
RoundBCA(x[1], 5);
RoundCAB(x[2], 5);
RoundABC(x[3], 5);
RoundBCA(x[4], 5);
RoundCAB(x[5], 5);
RoundABC(x[6], 5);
RoundBCA(x[7], 5);
KeySchedule();
RoundCAB(x[0], 7);
RoundABC(x[1], 7);
RoundBCA(x[2], 7);
RoundCAB(x[3], 7);
RoundABC(x[4], 7);
RoundBCA(x[5], 7);
RoundCAB(x[6], 7);
RoundABC(x[7], 7);
KeySchedule();
RoundBCA(x[0], 9);
RoundCAB(x[1], 9);
RoundABC(x[2], 9);
RoundBCA(x[3], 9);
RoundCAB(x[4], 9);
RoundABC(x[5], 9);
RoundBCA(x[6], 9);
RoundCAB(x[7], 9);
//
// feed forward
//
a ^= aa;
b -= bb;
c += cc;
//
// clear the x buffer
//
xOff = 0;
for (int i = 0; i != x.Length; i++)
{
x[i] = 0;
}
}
private void ProcessLength(
long bitLength)
{
x[7] = bitLength;
}
private void Finish()
{
long bitLength = (byteCount << 3);
Update((byte)0x01);
while (bOff != 0)
{
Update((byte)0);
}
ProcessLength(bitLength);
ProcessBlock();
}
public int DoFinal(
byte[] output,
int outOff)
{
Finish();
Pack.UInt64_To_LE((ulong)a, output, outOff);
Pack.UInt64_To_LE((ulong)b, output, outOff + 8);
Pack.UInt64_To_LE((ulong)c, output, outOff + 16);
Reset();
return DigestLength;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public int DoFinal(Span<byte> output)
{
Finish();
Pack.UInt64_To_LE((ulong)a, output);
Pack.UInt64_To_LE((ulong)b, output[8..]);
Pack.UInt64_To_LE((ulong)c, output[16..]);
Reset();
return DigestLength;
}
#endif
/**
* reset the chaining variables
*/
public void Reset()
{
a = unchecked((long) 0x0123456789ABCDEFL);
b = unchecked((long) 0xFEDCBA9876543210L);
c = unchecked((long) 0xF096A5B4C3B2E187L);
xOff = 0;
for (int i = 0; i != x.Length; i++)
{
x[i] = 0;
}
bOff = 0;
for (int i = 0; i != m_buffer.Length; i++)
{
m_buffer[i] = 0;
}
byteCount = 0;
}
public IMemoable Copy()
{
return new TigerDigest(this);
}
public void Reset(IMemoable other)
{
TigerDigest t = (TigerDigest)other;
a = t.a;
b = t.b;
c = t.c;
Array.Copy(t.x, 0, x, 0, t.x.Length);
xOff = t.xOff;
Array.Copy(t.m_buffer, 0, m_buffer, 0, t.m_buffer.Length);
bOff = t.bOff;
byteCount = t.byteCount;
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d844a8a4d2da2bd4686ebc970d9a76ea
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,165 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/// <summary>
/// TupleHash - a hash designed to simply hash a tuple of input strings, any or all of which may be empty strings,
/// in an unambiguous way with an optional XOF mode.
/// <para>
/// From NIST Special Publication 800-185 - SHA-3 Derived Functions:cSHAKE, KMAC, TupleHash and ParallelHash
/// </para>
/// </summary>
public class TupleHash
: IXof, IDigest
{
private static readonly byte[] N_TUPLE_HASH = Strings.ToByteArray("TupleHash");
private readonly CShakeDigest cshake;
private readonly int bitLength;
private readonly int outputLength;
private bool firstOutput;
/**
* Base constructor.
*
* @param bitLength bit length of the underlying SHAKE function, 128 or 256.
* @param S the customization string - available for local use.
*/
public TupleHash(int bitLength, byte[] S)
: this(bitLength, S, bitLength * 2)
{
}
public TupleHash(int bitLength, byte[] S, int outputSize)
{
this.cshake = new CShakeDigest(bitLength, N_TUPLE_HASH, S);
this.bitLength = bitLength;
this.outputLength = (outputSize + 7) / 8;
Reset();
}
public TupleHash(TupleHash original)
{
this.cshake = new CShakeDigest(original.cshake);
this.bitLength = cshake.fixedOutputLength;
this.outputLength = bitLength * 2 / 8;
this.firstOutput = original.firstOutput;
}
public virtual string AlgorithmName
{
get { return "TupleHash" + cshake.AlgorithmName.Substring(6); }
}
public virtual int GetByteLength()
{
return cshake.GetByteLength();
}
public virtual int GetDigestSize()
{
return outputLength;
}
public virtual void Update(byte b)
{
byte[] bytes = XofUtilities.Encode(b);
cshake.BlockUpdate(bytes, 0, bytes.Length);
}
public virtual void BlockUpdate(byte[] inBuf, int inOff, int len)
{
byte[] bytes = XofUtilities.Encode(inBuf, inOff, len);
cshake.BlockUpdate(bytes, 0, bytes.Length);
}
private void WrapUp(int outputSize)
{
byte[] encOut = XofUtilities.RightEncode(outputSize * 8);
cshake.BlockUpdate(encOut, 0, encOut.Length);
firstOutput = false;
}
public virtual int DoFinal(byte[] outBuf, int outOff)
{
return OutputFinal(outBuf, outOff, GetDigestSize());
}
public virtual int OutputFinal(byte[] outBuf, int outOff, int outLen)
{
if (firstOutput)
{
WrapUp(GetDigestSize());
}
int rv = cshake.OutputFinal(outBuf, outOff, outLen);
Reset();
return rv;
}
public virtual int Output(byte[] outBuf, int outOff, int outLen)
{
if (firstOutput)
{
WrapUp(0);
}
return cshake.Output(outBuf, outOff, outLen);
}
public virtual void Reset()
{
cshake.Reset();
firstOutput = true;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual void BlockUpdate(ReadOnlySpan<byte> input)
{
XofUtilities.EncodeTo(cshake, input);
}
public virtual int DoFinal(Span<byte> output)
{
return OutputFinal(output[..GetDigestSize()]);
}
public virtual int OutputFinal(Span<byte> output)
{
if (firstOutput)
{
WrapUp(GetDigestSize());
}
int rv = cshake.OutputFinal(output);
Reset();
return rv;
}
public virtual int Output(Span<byte> output)
{
if (firstOutput)
{
WrapUp(0);
}
return cshake.Output(output);
}
#endif
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: df6122cc4bf939f458500f4a09da5bb5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,386 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
/**
* Implementation of WhirlpoolDigest, based on Java source published by Barreto and Rijmen.
*/
public sealed class WhirlpoolDigest
: IDigest, IMemoable
{
private const int BITCOUNT_ARRAY_SIZE = 32;
private const int BYTE_LENGTH = 64;
private const int DIGEST_LENGTH_BYTES = 512 / 8;
private const int REDUCTION_POLYNOMIAL = 0x011d; // 2^8 + 2^4 + 2^3 + 2 + 1;
private const int ROUNDS = 10;
private static readonly int[] SBOX =
{
0x18, 0x23, 0xc6, 0xe8, 0x87, 0xb8, 0x01, 0x4f, 0x36, 0xa6, 0xd2, 0xf5, 0x79, 0x6f, 0x91, 0x52,
0x60, 0xbc, 0x9b, 0x8e, 0xa3, 0x0c, 0x7b, 0x35, 0x1d, 0xe0, 0xd7, 0xc2, 0x2e, 0x4b, 0xfe, 0x57,
0x15, 0x77, 0x37, 0xe5, 0x9f, 0xf0, 0x4a, 0xda, 0x58, 0xc9, 0x29, 0x0a, 0xb1, 0xa0, 0x6b, 0x85,
0xbd, 0x5d, 0x10, 0xf4, 0xcb, 0x3e, 0x05, 0x67, 0xe4, 0x27, 0x41, 0x8b, 0xa7, 0x7d, 0x95, 0xd8,
0xfb, 0xee, 0x7c, 0x66, 0xdd, 0x17, 0x47, 0x9e, 0xca, 0x2d, 0xbf, 0x07, 0xad, 0x5a, 0x83, 0x33,
0x63, 0x02, 0xaa, 0x71, 0xc8, 0x19, 0x49, 0xd9, 0xf2, 0xe3, 0x5b, 0x88, 0x9a, 0x26, 0x32, 0xb0,
0xe9, 0x0f, 0xd5, 0x80, 0xbe, 0xcd, 0x34, 0x48, 0xff, 0x7a, 0x90, 0x5f, 0x20, 0x68, 0x1a, 0xae,
0xb4, 0x54, 0x93, 0x22, 0x64, 0xf1, 0x73, 0x12, 0x40, 0x08, 0xc3, 0xec, 0xdb, 0xa1, 0x8d, 0x3d,
0x97, 0x00, 0xcf, 0x2b, 0x76, 0x82, 0xd6, 0x1b, 0xb5, 0xaf, 0x6a, 0x50, 0x45, 0xf3, 0x30, 0xef,
0x3f, 0x55, 0xa2, 0xea, 0x65, 0xba, 0x2f, 0xc0, 0xde, 0x1c, 0xfd, 0x4d, 0x92, 0x75, 0x06, 0x8a,
0xb2, 0xe6, 0x0e, 0x1f, 0x62, 0xd4, 0xa8, 0x96, 0xf9, 0xc5, 0x25, 0x59, 0x84, 0x72, 0x39, 0x4c,
0x5e, 0x78, 0x38, 0x8c, 0xd1, 0xa5, 0xe2, 0x61, 0xb3, 0x21, 0x9c, 0x1e, 0x43, 0xc7, 0xfc, 0x04,
0x51, 0x99, 0x6d, 0x0d, 0xfa, 0xdf, 0x7e, 0x24, 0x3b, 0xab, 0xce, 0x11, 0x8f, 0x4e, 0xb7, 0xeb,
0x3c, 0x81, 0x94, 0xf7, 0xb9, 0x13, 0x2c, 0xd3, 0xe7, 0x6e, 0xc4, 0x03, 0x56, 0x44, 0x7f, 0xa9,
0x2a, 0xbb, 0xc1, 0x53, 0xdc, 0x0b, 0x9d, 0x6c, 0x31, 0x74, 0xf6, 0x46, 0xac, 0x89, 0x14, 0xe1,
0x16, 0x3a, 0x69, 0x09, 0x70, 0xb6, 0xd0, 0xed, 0xcc, 0x42, 0x98, 0xa4, 0x28, 0x5c, 0xf8, 0x86
};
private static readonly ulong[] C0 = new ulong[256];
private static readonly ulong[] C1 = new ulong[256];
private static readonly ulong[] C2 = new ulong[256];
private static readonly ulong[] C3 = new ulong[256];
private static readonly ulong[] C4 = new ulong[256];
private static readonly ulong[] C5 = new ulong[256];
private static readonly ulong[] C6 = new ulong[256];
private static readonly ulong[] C7 = new ulong[256];
/*
* increment() can be implemented in this way using 2 arrays or
* by having some temporary variables that are used to set the
* value provided by EIGHT[i] and carry within the loop.
*
* not having done any timing, this seems likely to be faster
* at the slight expense of 32*(sizeof short) bytes
*/
private static readonly short[] EIGHT = new short[BITCOUNT_ARRAY_SIZE];
static WhirlpoolDigest()
{
EIGHT[BITCOUNT_ARRAY_SIZE - 1] = 8;
for (int i = 0; i < 256; i++)
{
int v1 = SBOX[i];
int v2 = MulX(v1);
int v4 = MulX(v2);
int v5 = v4 ^ v1;
int v8 = MulX(v4);
int v9 = v8 ^ v1;
C0[i] = PackIntoUInt64(v1, v1, v4, v1, v8, v5, v2, v9);
C1[i] = PackIntoUInt64(v9, v1, v1, v4, v1, v8, v5, v2);
C2[i] = PackIntoUInt64(v2, v9, v1, v1, v4, v1, v8, v5);
C3[i] = PackIntoUInt64(v5, v2, v9, v1, v1, v4, v1, v8);
C4[i] = PackIntoUInt64(v8, v5, v2, v9, v1, v1, v4, v1);
C5[i] = PackIntoUInt64(v1, v8, v5, v2, v9, v1, v1, v4);
C6[i] = PackIntoUInt64(v4, v1, v8, v5, v2, v9, v1, v1);
C7[i] = PackIntoUInt64(v1, v4, v1, v8, v5, v2, v9, v1);
}
}
// int's are used to prevent sign extension. The values that are really being used are actually just 0..255
private static int MulX(int input)
{
return (input << 1) ^ (-(input >> 7) & REDUCTION_POLYNOMIAL);
}
private static ulong PackIntoUInt64(int b7, int b6, int b5, int b4, int b3, int b2, int b1, int b0)
{
return ((ulong)b7 << 56) ^
((ulong)b6 << 48) ^
((ulong)b5 << 40) ^
((ulong)b4 << 32) ^
((ulong)b3 << 24) ^
((ulong)b2 << 16) ^
((ulong)b1 << 8) ^
(ulong)b0;
}
private readonly ulong[] _rc = new ulong[ROUNDS + 1];
public WhirlpoolDigest()
{
_rc[0] = 0UL;
for (int r = 1; r <= ROUNDS; r++)
{
int i = 8 * (r - 1);
_rc[r] =
(C0[i ] & 0xff00000000000000UL) ^
(C1[i + 1] & 0x00ff000000000000UL) ^
(C2[i + 2] & 0x0000ff0000000000UL) ^
(C3[i + 3] & 0x000000ff00000000UL) ^
(C4[i + 4] & 0x00000000ff000000UL) ^
(C5[i + 5] & 0x0000000000ff0000UL) ^
(C6[i + 6] & 0x000000000000ff00UL) ^
(C7[i + 7] & 0x00000000000000ffUL);
}
}
// --------------------------------------------------------------------------------------//
// -- buffer information --
private byte[] _buffer = new byte[64];
private int _bufferPos;
private short[] _bitCount = new short[BITCOUNT_ARRAY_SIZE];
// -- internal hash state --
private ulong[] _hash = new ulong[8];
private ulong[] _K = new ulong[8]; // the round key
private ulong[] _L = new ulong[8];
private ulong[] _block = new ulong[8]; // mu (buffer)
private ulong[] _state = new ulong[8]; // the current "cipher" state
/**
* Copy constructor. This will copy the state of the provided message digest.
*/
public WhirlpoolDigest(WhirlpoolDigest originalDigest)
{
Reset(originalDigest);
}
public string AlgorithmName
{
get { return "Whirlpool"; }
}
public int GetDigestSize()
{
return DIGEST_LENGTH_BYTES;
}
public int DoFinal(byte[] output, int outOff)
{
// sets output[outOff] .. output[outOff+DIGEST_LENGTH_BYTES]
Finish();
Pack.UInt64_To_BE(_hash, output, outOff);
Reset();
return GetDigestSize();
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public int DoFinal(Span<byte> output)
{
// sets output[0..DIGEST_LENGTH_BYTES]
Finish();
Pack.UInt64_To_BE(_hash, output);
Reset();
return GetDigestSize();
}
#endif
/**
* Reset the chaining variables
*/
public void Reset()
{
// set variables to null, blank, whatever
_bufferPos = 0;
Array.Clear(_bitCount, 0, _bitCount.Length);
Array.Clear(_buffer, 0, _buffer.Length);
Array.Clear(_hash, 0, _hash.Length);
Array.Clear(_K, 0, _K.Length);
Array.Clear(_L, 0, _L.Length);
Array.Clear(_block, 0, _block.Length);
Array.Clear(_state, 0, _state.Length);
}
// this takes a buffer of information and fills the block
private void ProcessFilledBuffer()
{
// copies into the block...
Pack.BE_To_UInt64(_buffer, 0, _block);
ProcessBlock();
_bufferPos = 0;
Array.Clear(_buffer, 0, _buffer.Length);
}
private void ProcessBlock()
{
// buffer contents have been transferred to the _block[] array via ProcessFilledBuffer
// compute and apply K^0
for (int i = 0; i < 8; i++)
{
_state[i] = _block[i] ^ (_K[i] = _hash[i]);
}
// iterate over the rounds
for (int round = 1; round <= ROUNDS; round++)
{
for (int i = 0; i < 8; i++)
{
_L[i] = C0[(int)(_K[(i - 0) & 7] >> 56) & 0xff];
_L[i] ^= C1[(int)(_K[(i - 1) & 7] >> 48) & 0xff];
_L[i] ^= C2[(int)(_K[(i - 2) & 7] >> 40) & 0xff];
_L[i] ^= C3[(int)(_K[(i - 3) & 7] >> 32) & 0xff];
_L[i] ^= C4[(int)(_K[(i - 4) & 7] >> 24) & 0xff];
_L[i] ^= C5[(int)(_K[(i - 5) & 7] >> 16) & 0xff];
_L[i] ^= C6[(int)(_K[(i - 6) & 7] >> 8) & 0xff];
_L[i] ^= C7[(int)(_K[(i - 7) & 7]) & 0xff];
}
Array.Copy(_L, 0, _K, 0, _K.Length);
_K[0] ^= _rc[round];
// apply the round transformation
for (int i = 0; i < 8; i++)
{
_L[i] = _K[i];
_L[i] ^= C0[(int)(_state[(i - 0) & 7] >> 56) & 0xff];
_L[i] ^= C1[(int)(_state[(i - 1) & 7] >> 48) & 0xff];
_L[i] ^= C2[(int)(_state[(i - 2) & 7] >> 40) & 0xff];
_L[i] ^= C3[(int)(_state[(i - 3) & 7] >> 32) & 0xff];
_L[i] ^= C4[(int)(_state[(i - 4) & 7] >> 24) & 0xff];
_L[i] ^= C5[(int)(_state[(i - 5) & 7] >> 16) & 0xff];
_L[i] ^= C6[(int)(_state[(i - 6) & 7] >> 8) & 0xff];
_L[i] ^= C7[(int)(_state[(i - 7) & 7]) & 0xff];
}
// save the current state
Array.Copy(_L, 0, _state, 0, _state.Length);
}
// apply Miuaguchi-Preneel compression
for (int i = 0; i < 8; i++)
{
_hash[i] ^= _state[i] ^ _block[i];
}
}
public void Update(byte input)
{
_buffer[_bufferPos] = input;
if (++_bufferPos == _buffer.Length)
{
ProcessFilledBuffer();
}
Increment();
}
private void Increment()
{
int carry = 0;
for (int i = _bitCount.Length - 1; i >= 0; i--)
{
int sum = (_bitCount[i] & 0xff) + EIGHT[i] + carry;
carry = sum >> 8;
_bitCount[i] = (short)(sum & 0xff);
}
}
public void BlockUpdate(byte[] input, int inOff, int length)
{
while (length > 0)
{
Update(input[inOff]);
++inOff;
--length;
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void BlockUpdate(ReadOnlySpan<byte> input)
{
for (int i = 0; i < input.Length; ++i)
{
Update(input[i]);
}
}
#endif
private void Finish()
{
/*
* this makes a copy of the current bit length. at the expense of an
* object creation of 32 bytes rather than providing a _stopCounting
* boolean which was the alternative I could think of.
*/
byte[] bitLength = CopyBitLength();
_buffer[_bufferPos] |= 0x80;
if (++_bufferPos == _buffer.Length)
{
ProcessFilledBuffer();
}
/*
* Final block contains
* [ ... data .... ][0][0][0][ length ]
*
* if [ length ] cannot fit. Need to create a new block.
*/
if (_bufferPos > 32)
{
while (_bufferPos != 0)
{
Update((byte)0);
}
}
while (_bufferPos <= 32)
{
Update((byte)0);
}
// copy the length information to the final 32 bytes of the 64 byte block....
Array.Copy(bitLength, 0, _buffer, 32, bitLength.Length);
ProcessFilledBuffer();
}
private byte[] CopyBitLength()
{
byte[] rv = new byte[BITCOUNT_ARRAY_SIZE];
for (int i = 0; i < rv.Length; i++)
{
rv[i] = (byte)(_bitCount[i] & 0xff);
}
return rv;
}
public int GetByteLength()
{
return BYTE_LENGTH;
}
public IMemoable Copy()
{
return new WhirlpoolDigest(this);
}
public void Reset(IMemoable other)
{
WhirlpoolDigest originalDigest = (WhirlpoolDigest)other;
Array.Copy(originalDigest._rc, 0, _rc, 0, _rc.Length);
Array.Copy(originalDigest._buffer, 0, _buffer, 0, _buffer.Length);
this._bufferPos = originalDigest._bufferPos;
Array.Copy(originalDigest._bitCount, 0, _bitCount, 0, _bitCount.Length);
// -- internal hash state --
Array.Copy(originalDigest._hash, 0, _hash, 0, _hash.Length);
Array.Copy(originalDigest._K, 0, _K, 0, _K.Length);
Array.Copy(originalDigest._L, 0, _L, 0, _L.Length);
Array.Copy(originalDigest._block, 0, _block, 0, _block.Length);
Array.Copy(originalDigest._state, 0, _state, 0, _state.Length);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 18d8b02a2f6887d4e895210123d65ad1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,121 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests
{
internal class XofUtilities
{
internal static byte[] LeftEncode(long strLen)
{
byte n = 1;
long v = strLen;
while ((v >>= 8) != 0)
{
n++;
}
byte[] b = new byte[n + 1];
b[0] = n;
for (int i = 1; i <= n; i++)
{
b[i] = (byte)(strLen >> (8 * (n - i)));
}
return b;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
internal static int LeftEncode(long length, Span<byte> lengthEncoding)
{
byte n = 1;
long v = length;
while ((v >>= 8) != 0)
{
n++;
}
lengthEncoding[0] = n;
for (int i = 1; i <= n; i++)
{
lengthEncoding[i] = (byte)(length >> (8 * (n - i)));
}
return 1 + n;
}
#endif
internal static byte[] RightEncode(long strLen)
{
byte n = 1;
long v = strLen;
while ((v >>= 8) != 0)
{
n++;
}
byte[] b = new byte[n + 1];
b[n] = n;
for (int i = 0; i < n; i++)
{
b[i] = (byte)(strLen >> (8 * (n - i - 1)));
}
return b;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
internal static int RightEncode(long length, Span<byte> lengthEncoding)
{
byte n = 1;
long v = length;
while ((v >>= 8) != 0)
{
n++;
}
lengthEncoding[n] = n;
for (int i = 0; i < n; i++)
{
lengthEncoding[i] = (byte)(length >> (8 * (n - i - 1)));
}
return n + 1;
}
#endif
internal static byte[] Encode(byte X)
{
return Arrays.Concatenate(LeftEncode(8), new byte[] { X });
}
internal static byte[] Encode(byte[] inBuf, int inOff, int len)
{
if (inBuf.Length == len)
{
return Arrays.Concatenate(LeftEncode(len * 8), inBuf);
}
return Arrays.Concatenate(LeftEncode(len * 8), Arrays.CopyOfRange(inBuf, inOff, inOff + len));
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
internal static void EncodeTo(IDigest digest, ReadOnlySpan<byte> buf)
{
Span<byte> lengthEncoding = stackalloc byte[9];
int count = LeftEncode(buf.Length * 8, lengthEncoding);
digest.BlockUpdate(lengthEncoding[..count]);
digest.BlockUpdate(buf);
}
#endif
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 44b50b608bf4d5f4299319d919b9830c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: