diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-03-11 13:11:44 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-03-11 13:11:44 +0700 |
commit | 8ad240105db29a96e12e785ac5586c52f3fce9bb (patch) | |
tree | e990918e1ab065c6966ee8380b3f98ddef419a97 | |
parent | Improve SipHashTest to cover varying update methods (diff) | |
download | BouncyCastle.NET-ed25519-8ad240105db29a96e12e785ac5586c52f3fce9bb.tar.xz |
Optimization (faster at all input lengths, but especially for long block-aligned inputs)
-rw-r--r-- | crypto/src/crypto/macs/SipHash.cs | 56 |
1 files changed, 39 insertions, 17 deletions
diff --git a/crypto/src/crypto/macs/SipHash.cs b/crypto/src/crypto/macs/SipHash.cs index ab8b1b06b..34b0ef090 100644 --- a/crypto/src/crypto/macs/SipHash.cs +++ b/crypto/src/crypto/macs/SipHash.cs @@ -23,8 +23,8 @@ namespace Org.BouncyCastle.Crypto.Macs protected long k0, k1; protected long v0, v1, v2, v3, v4; - protected byte[] buf = new byte[8]; - protected int bufPos = 0; + protected long m = 0; + protected int wordPos = 0; protected int wordCount = 0; /// <summary>SipHash-2-4</summary> @@ -69,34 +69,57 @@ namespace Org.BouncyCastle.Crypto.Macs public virtual void Update(byte input) { - buf[bufPos] = input; - if (++bufPos == buf.Length) + m = (long)(((ulong)m >> 8) | ((ulong)input << 56)); + + if (++wordPos == 8) { ProcessMessageWord(); - bufPos = 0; + wordPos = 0; } } public virtual void BlockUpdate(byte[] input, int offset, int length) { - for (int i = 0; i < length; ++i) + int i = 0, fullWords = length & ~7; + if (wordPos == 0) { - buf[bufPos] = input[offset + i]; - if (++bufPos == buf.Length) + for (; i < fullWords; i += 8) { + m = (long)Pack.LE_To_UInt64(input, offset + i); ProcessMessageWord(); - bufPos = 0; + } + for (; i < length; ++i) + { + m = (long)(((ulong)m >> 8) | ((ulong)input[offset + i] << 56)); + } + wordPos = length - fullWords; + } + else + { + int bits = wordPos << 3; + for (; i < fullWords; i += 8) + { + ulong n = Pack.LE_To_UInt64(input, offset + i); + m = (long)(((ulong)m >> (64 - bits)) | (n << bits)); + ProcessMessageWord(); + m = (long)n; + } + for (; i < length; ++i) + { + m = (long)(((ulong)m >> 8) | ((ulong)input[offset + i] << 56)); + + if (++wordPos == 8) + { + ProcessMessageWord(); + wordPos = 0; + } } } } public virtual long DoFinal() { - buf[7] = (byte)((wordCount << 3) + bufPos); - while (bufPos < 7) - { - buf[bufPos++] = 0; - } + m = (long)(((ulong)m >> ((8 - wordPos) << 3)) | ((ulong)((wordCount << 3) + wordPos) << 56)); ProcessMessageWord(); @@ -125,15 +148,14 @@ namespace Org.BouncyCastle.Crypto.Macs v2 = k0 ^ 0x6c7967656e657261L; v3 = k1 ^ 0x7465646279746573L; - Array.Clear(buf, 0, buf.Length); - bufPos = 0; + m = 0; + wordPos = 0; wordCount = 0; } protected virtual void ProcessMessageWord() { ++wordCount; - long m = (long)Pack.LE_To_UInt64(buf, 0); v3 ^= m; ApplySipRounds(c); v0 ^= m; |