diff options
author | Tim Whittington <bc@whittington.net.nz> | 2013-10-14 13:26:33 +1300 |
---|---|---|
committer | Tim Whittington <bc@whittington.net.nz> | 2013-10-20 21:32:35 +1300 |
commit | 94115c98b4dd69c1ab3d2cc00d2654fd3d4c74c9 (patch) | |
tree | a232e897e2d50aea2feb3c7d844e38601d49aa23 | |
parent | Refactor digest tests to subclass DigestTest, the same as bc-java. (diff) | |
download | BouncyCastle.NET-ed25519-94115c98b4dd69c1ab3d2cc00d2654fd3d4c74c9.tar.xz |
Port HMac optimisation using Memoable digests from bc-java.
-rw-r--r-- | crypto/src/crypto/macs/HMac.cs | 44 |
1 files changed, 37 insertions, 7 deletions
diff --git a/crypto/src/crypto/macs/HMac.cs b/crypto/src/crypto/macs/HMac.cs index 7ae1e02b9..460f3c5a0 100644 --- a/crypto/src/crypto/macs/HMac.cs +++ b/crypto/src/crypto/macs/HMac.cs @@ -3,6 +3,7 @@ using System.Collections; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Macs { @@ -20,6 +21,8 @@ namespace Org.BouncyCastle.Crypto.Macs private readonly IDigest digest; private readonly int digestSize; private readonly int blockLength; + private IMemoable ipadState; + private IMemoable opadState; private readonly byte[] inputPad; private readonly byte[] outputBuf; @@ -68,8 +71,19 @@ namespace Org.BouncyCastle.Crypto.Macs XorPad(inputPad, blockLength, IPAD); XorPad(outputBuf, blockLength, OPAD); - // Initialise the digest + if (digest is IMemoable) + { + opadState = ((IMemoable)digest).Copy(); + + ((IDigest)opadState).BlockUpdate(outputBuf, 0, blockLength); + } + digest.BlockUpdate(inputPad, 0, inputPad.Length); + + if (digest is IMemoable) + { + ipadState = ((IMemoable)digest).Copy(); + } } public virtual int GetMacSize() @@ -90,13 +104,29 @@ namespace Org.BouncyCastle.Crypto.Macs public virtual int DoFinal(byte[] output, int outOff) { digest.DoFinal(outputBuf, blockLength); - digest.BlockUpdate(outputBuf, 0, outputBuf.Length); - int len = digest.DoFinal(output, outOff); - Array.Clear(outputBuf, blockLength, digestSize); - - // Initialise the digest - digest.BlockUpdate(inputPad, 0, inputPad.Length); + if (opadState != null) + { + ((IMemoable)digest).Reset(opadState); + digest.BlockUpdate(outputBuf, blockLength, digest.GetDigestSize()); + } + else + { + digest.BlockUpdate(outputBuf, 0, outputBuf.Length); + } + + int len = digest.DoFinal(output, outOff); + + Array.Clear(outputBuf, blockLength, digestSize); + + if (ipadState != null) + { + ((IMemoable)digest).Reset(ipadState); + } + else + { + digest.BlockUpdate(inputPad, 0, inputPad.Length); + } return len; } |