You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
204 lines
5.3 KiB
204 lines
5.3 KiB
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) |
|
#pragma warning disable |
|
using System; |
|
|
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities; |
|
|
|
namespace BestHTTP.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; |
|
} |
|
|
|
/** |
|
* 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); |
|
} |
|
} |
|
|
|
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
|
|
|