From 8ad240105db29a96e12e785ac5586c52f3fce9bb Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Tue, 11 Mar 2014 13:11:44 +0700 Subject: Optimization (faster at all input lengths, but especially for long block-aligned inputs) --- crypto/src/crypto/macs/SipHash.cs | 56 +++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 17 deletions(-) (limited to 'crypto') 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; /// SipHash-2-4 @@ -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; -- cgit 1.4.1