summary refs log tree commit diff
diff options
context:
space:
mode:
authorTim Whittington <bc@whittington.net.nz>2013-10-14 13:26:33 +1300
committerTim Whittington <bc@whittington.net.nz>2013-10-20 21:32:35 +1300
commit94115c98b4dd69c1ab3d2cc00d2654fd3d4c74c9 (patch)
treea232e897e2d50aea2feb3c7d844e38601d49aa23
parentRefactor digest tests to subclass DigestTest, the same as bc-java. (diff)
downloadBouncyCastle.NET-ed25519-94115c98b4dd69c1ab3d2cc00d2654fd3d4c74c9.tar.xz
Port HMac optimisation using Memoable digests from bc-java.
-rw-r--r--crypto/src/crypto/macs/HMac.cs44
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;
         }