123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
- using System;
- using Org.BouncyCastle.Crypto.Utilities;
- using Org.BouncyCastle.Utilities;
- namespace 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;
- }
- }
- }
- #endif
|