diff options
author | Tim Whittington <bc@whittington.net.nz> | 2013-10-12 19:46:25 +1300 |
---|---|---|
committer | Tim Whittington <bc@whittington.net.nz> | 2013-10-20 21:32:33 +1300 |
commit | f64b37993aaec3f2baaab236af58c295b06c9f92 (patch) | |
tree | ced19bc4695aafe6112dbada80601d5cf8def51f /crypto | |
parent | Port SkeinDigest and SkeinMac from bc-java. (diff) | |
download | BouncyCastle.NET-ed25519-f64b37993aaec3f2baaab236af58c295b06c9f92.tar.xz |
Port Memoable digest support from bc-java.
Diffstat (limited to 'crypto')
25 files changed, 536 insertions, 96 deletions
diff --git a/crypto/crypto.mdp b/crypto/crypto.mdp index f3589858f..e79b81b17 100644 --- a/crypto/crypto.mdp +++ b/crypto/crypto.mdp @@ -2308,6 +2308,8 @@ <File subtype="Code" buildaction="Compile" name="test/src/crypto/test/SkeinDigestTest.cs" /> <File subtype="Code" buildaction="Compile" name="test/src/crypto/test/SkeinMacTest.cs" /> <File subtype="Code" buildaction="Compile" name="src/crypto/macs/SkeinMac.cs" /> + <File subtype="Code" buildaction="Compile" name="src/util/IMemoable.cs" /> + <File subtype="Code" buildaction="Compile" name="src/util/MemoableResetException.cs" /> </Contents> <References> <ProjectReference type="Assembly" localcopy="True" refto="test/lib/nunit.core.dll" /> diff --git a/crypto/src/crypto/digests/GOST3411Digest.cs b/crypto/src/crypto/digests/GOST3411Digest.cs index 9f0bec9e6..218adf68c 100644 --- a/crypto/src/crypto/digests/GOST3411Digest.cs +++ b/crypto/src/crypto/digests/GOST3411Digest.cs @@ -11,7 +11,7 @@ namespace Org.BouncyCastle.Crypto.Digests * implementation of GOST R 34.11-94 */ public class Gost3411Digest - : IDigest + : IDigest, IMemoable { private const int DIGEST_LENGTH = 32; @@ -24,7 +24,7 @@ namespace Org.BouncyCastle.Crypto.Digests private ulong byteCount; private readonly IBlockCipher cipher = new Gost28147Engine(); - private readonly byte[] sBox; + private byte[] sBox; private static byte[][] MakeC() { @@ -65,22 +65,7 @@ namespace Org.BouncyCastle.Crypto.Digests */ public Gost3411Digest(Gost3411Digest t) { - this.sBox = t.sBox; - cipher.Init(true, new ParametersWithSBox(null, sBox)); - - Reset(); - - Array.Copy(t.H, 0, this.H, 0, t.H.Length); - Array.Copy(t.L, 0, this.L, 0, t.L.Length); - Array.Copy(t.M, 0, this.M, 0, t.M.Length); - Array.Copy(t.Sum, 0, this.Sum, 0, t.Sum.Length); - Array.Copy(t.C[1], 0, this.C[1], 0, t.C[1].Length); - Array.Copy(t.C[2], 0, this.C[2], 0, t.C[2].Length); - Array.Copy(t.C[3], 0, this.C[3], 0, t.C[3].Length); - Array.Copy(t.xBuf, 0, this.xBuf, 0, t.xBuf.Length); - - this.xBufOff = t.xBufOff; - this.byteCount = t.byteCount; + Reset(t); } public string AlgorithmName @@ -339,5 +324,33 @@ namespace Org.BouncyCastle.Crypto.Digests { return 32; } + + public IMemoable Copy() + { + return new Gost3411Digest(this); + } + + public void Reset(IMemoable other) + { + Gost3411Digest t = (Gost3411Digest)other; + + this.sBox = t.sBox; + cipher.Init(true, new ParametersWithSBox(null, sBox)); + + Reset(); + + Array.Copy(t.H, 0, this.H, 0, t.H.Length); + Array.Copy(t.L, 0, this.L, 0, t.L.Length); + Array.Copy(t.M, 0, this.M, 0, t.M.Length); + Array.Copy(t.Sum, 0, this.Sum, 0, t.Sum.Length); + Array.Copy(t.C[1], 0, this.C[1], 0, t.C[1].Length); + Array.Copy(t.C[2], 0, this.C[2], 0, t.C[2].Length); + Array.Copy(t.C[3], 0, this.C[3], 0, t.C[3].Length); + Array.Copy(t.xBuf, 0, this.xBuf, 0, t.xBuf.Length); + + this.xBufOff = t.xBufOff; + this.byteCount = t.byteCount; + } } + } diff --git a/crypto/src/crypto/digests/GeneralDigest.cs b/crypto/src/crypto/digests/GeneralDigest.cs index 77c17ed58..54a09ae05 100644 --- a/crypto/src/crypto/digests/GeneralDigest.cs +++ b/crypto/src/crypto/digests/GeneralDigest.cs @@ -1,5 +1,7 @@ using System; +using Org.BouncyCastle.Utilities; + namespace Org.BouncyCastle.Crypto.Digests { /** @@ -7,7 +9,7 @@ namespace Org.BouncyCastle.Crypto.Digests * "Handbook of Applied Cryptography", pages 344 - 347. */ public abstract class GeneralDigest - : IDigest + : IDigest, IMemoable { private const int BYTE_LENGTH = 64; @@ -22,8 +24,13 @@ namespace Org.BouncyCastle.Crypto.Digests } internal GeneralDigest(GeneralDigest t) - { - xBuf = new byte[t.xBuf.Length]; + { + xBuf = new byte[t.xBuf.Length]; + CopyIn(t); + } + + protected void CopyIn(GeneralDigest t) + { Array.Copy(t.xBuf, 0, xBuf, 0, t.xBuf.Length); xBufOff = t.xBufOff; @@ -114,5 +121,7 @@ namespace Org.BouncyCastle.Crypto.Digests public abstract string AlgorithmName { get; } public abstract int GetDigestSize(); public abstract int DoFinal(byte[] output, int outOff); + public abstract IMemoable Copy(); + public abstract void Reset(IMemoable t); } } diff --git a/crypto/src/crypto/digests/LongDigest.cs b/crypto/src/crypto/digests/LongDigest.cs index 702753b2b..9ee9bcd57 100644 --- a/crypto/src/crypto/digests/LongDigest.cs +++ b/crypto/src/crypto/digests/LongDigest.cs @@ -2,6 +2,7 @@ using System; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Digests { @@ -9,7 +10,7 @@ namespace Org.BouncyCastle.Crypto.Digests * Base class for SHA-384 and SHA-512. */ public abstract class LongDigest - : IDigest + : IDigest, IMemoable { private int MyByteLength = 128; @@ -41,8 +42,14 @@ namespace Org.BouncyCastle.Crypto.Digests */ internal LongDigest( LongDigest t) - { - xBuf = new byte[t.xBuf.Length]; + { + xBuf = new byte[t.xBuf.Length]; + + CopyIn(t); + } + + protected void CopyIn(LongDigest t) + { Array.Copy(t.xBuf, 0, xBuf, 0, t.xBuf.Length); xBufOff = t.xBufOff; @@ -342,5 +349,7 @@ namespace Org.BouncyCastle.Crypto.Digests public abstract string AlgorithmName { get; } public abstract int GetDigestSize(); public abstract int DoFinal(byte[] output, int outOff); + public abstract IMemoable Copy(); + public abstract void Reset(IMemoable t); } } diff --git a/crypto/src/crypto/digests/MD2Digest.cs b/crypto/src/crypto/digests/MD2Digest.cs index 78c696f33..6d90f3f9d 100644 --- a/crypto/src/crypto/digests/MD2Digest.cs +++ b/crypto/src/crypto/digests/MD2Digest.cs @@ -1,5 +1,7 @@ using System; + using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Digests { @@ -9,7 +11,7 @@ namespace Org.BouncyCastle.Crypto.Digests * as outlined in RFC1319 by B.Kaliski from RSA Laboratories April 1992 */ public class MD2Digest - : IDigest + : IDigest, IMemoable { private const int DigestLength = 16; private const int BYTE_LENGTH = 16; @@ -32,8 +34,14 @@ namespace Org.BouncyCastle.Crypto.Digests { Reset(); } + public MD2Digest(MD2Digest t) - { + { + CopyIn(t); + } + + private void CopyIn(MD2Digest t) + { Array.Copy(t.X, 0, X, 0, t.X.Length); xOff = t.xOff; Array.Copy(t.M, 0, M, 0, t.M.Length); @@ -41,6 +49,7 @@ namespace Org.BouncyCastle.Crypto.Digests Array.Copy(t.C, 0, C, 0, t.C.Length); COff = t.COff; } + /** * return the algorithm name * @@ -242,6 +251,19 @@ namespace Org.BouncyCastle.Crypto.Digests (byte)237,(byte)31,(byte)26,(byte)219,(byte)153,(byte)141,(byte)51, (byte)159,(byte)17,(byte)131,(byte)20 }; + + public IMemoable Copy() + { + return new MD2Digest(this); + } + + public void Reset(IMemoable other) + { + MD2Digest d = (MD2Digest)other; + + CopyIn(d); + } + } } diff --git a/crypto/src/crypto/digests/MD4Digest.cs b/crypto/src/crypto/digests/MD4Digest.cs index bc4eae0fd..8743f7dad 100644 --- a/crypto/src/crypto/digests/MD4Digest.cs +++ b/crypto/src/crypto/digests/MD4Digest.cs @@ -1,5 +1,7 @@ using System; +using Org.BouncyCastle.Utilities; + namespace Org.BouncyCastle.Crypto.Digests { /** @@ -32,7 +34,13 @@ namespace Org.BouncyCastle.Crypto.Digests * message digest. */ public MD4Digest(MD4Digest t) : base(t) - { + { + CopyIn(t); + } + + private void CopyIn(MD4Digest t) + { + base.CopyIn(t); H1 = t.H1; H2 = t.H2; H3 = t.H3; @@ -266,6 +274,19 @@ namespace Org.BouncyCastle.Crypto.Digests X[i] = 0; } } + + public override IMemoable Copy() + { + return new MD4Digest(this); + } + + public override void Reset(IMemoable other) + { + MD4Digest d = (MD4Digest)other; + + CopyIn(d); + } + } } diff --git a/crypto/src/crypto/digests/MD5Digest.cs b/crypto/src/crypto/digests/MD5Digest.cs index 2116d64f0..c60ac92a3 100644 --- a/crypto/src/crypto/digests/MD5Digest.cs +++ b/crypto/src/crypto/digests/MD5Digest.cs @@ -1,6 +1,7 @@ using System; using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Digests { @@ -28,7 +29,13 @@ namespace Org.BouncyCastle.Crypto.Digests */ public MD5Digest(MD5Digest t) : base(t) - { + { + CopyIn(t); + } + + private void CopyIn(MD5Digest t) + { + base.CopyIn(t); H1 = t.H1; H2 = t.H2; H3 = t.H3; @@ -287,7 +294,20 @@ namespace Org.BouncyCastle.Crypto.Digests xOff = 0; } - } + + public override IMemoable Copy() + { + return new MD5Digest(this); + } + + public override void Reset(IMemoable other) + { + MD5Digest d = (MD5Digest)other; + + CopyIn(d); + } + + } } diff --git a/crypto/src/crypto/digests/RipeMD128Digest.cs b/crypto/src/crypto/digests/RipeMD128Digest.cs index 8977583a4..e8a0331ca 100644 --- a/crypto/src/crypto/digests/RipeMD128Digest.cs +++ b/crypto/src/crypto/digests/RipeMD128Digest.cs @@ -1,5 +1,7 @@ using System; +using Org.BouncyCastle.Utilities; + namespace Org.BouncyCastle.Crypto.Digests { /** @@ -28,8 +30,15 @@ namespace Org.BouncyCastle.Crypto.Digests * message digest. */ public RipeMD128Digest(RipeMD128Digest t) : base(t) - { - H0 = t.H0; + { + CopyIn(t); + } + + private void CopyIn(RipeMD128Digest t) + { + base.CopyIn(t); + + H0 = t.H0; H1 = t.H1; H2 = t.H2; H3 = t.H3; @@ -457,6 +466,19 @@ namespace Org.BouncyCastle.Crypto.Digests X[i] = 0; } } + + public override IMemoable Copy() + { + return new RipeMD128Digest(this); + } + + public override void Reset(IMemoable other) + { + RipeMD128Digest d = (RipeMD128Digest)other; + + CopyIn(d); + } + } } diff --git a/crypto/src/crypto/digests/RipeMD160Digest.cs b/crypto/src/crypto/digests/RipeMD160Digest.cs index 8ce52ae58..af4aa44bb 100644 --- a/crypto/src/crypto/digests/RipeMD160Digest.cs +++ b/crypto/src/crypto/digests/RipeMD160Digest.cs @@ -1,5 +1,7 @@ using System; +using Org.BouncyCastle.Utilities; + namespace Org.BouncyCastle.Crypto.Digests { /** @@ -30,6 +32,13 @@ namespace Org.BouncyCastle.Crypto.Digests */ public RipeMD160Digest(RipeMD160Digest t) : base(t) { + CopyIn(t); + } + + private void CopyIn(RipeMD160Digest t) + { + base.CopyIn(t); + H0 = t.H0; H1 = t.H1; H2 = t.H2; @@ -418,6 +427,19 @@ namespace Org.BouncyCastle.Crypto.Digests X[i] = 0; } } + + public override IMemoable Copy() + { + return new RipeMD160Digest(this); + } + + public override void Reset(IMemoable other) + { + RipeMD160Digest d = (RipeMD160Digest)other; + + CopyIn(d); + } + } } diff --git a/crypto/src/crypto/digests/RipeMD256Digest.cs b/crypto/src/crypto/digests/RipeMD256Digest.cs index 950e94f80..306275767 100644 --- a/crypto/src/crypto/digests/RipeMD256Digest.cs +++ b/crypto/src/crypto/digests/RipeMD256Digest.cs @@ -1,5 +1,7 @@ using System; +using Org.BouncyCastle.Utilities; + namespace Org.BouncyCastle.Crypto.Digests { /// <remarks> @@ -37,6 +39,12 @@ namespace Org.BouncyCastle.Crypto.Digests /// </summary> public RipeMD256Digest(RipeMD256Digest t):base(t) { + CopyIn(t); + } + + private void CopyIn(RipeMD256Digest t) + { + base.CopyIn(t); H0 = t.H0; H1 = t.H1; @@ -405,5 +413,18 @@ namespace Org.BouncyCastle.Crypto.Digests X[i] = 0; } } + + public override IMemoable Copy() + { + return new RipeMD256Digest(this); + } + + public override void Reset(IMemoable other) + { + RipeMD256Digest d = (RipeMD256Digest)other; + + CopyIn(d); + } + } } diff --git a/crypto/src/crypto/digests/RipeMD320Digest.cs b/crypto/src/crypto/digests/RipeMD320Digest.cs index 25c74baef..767d74dba 100644 --- a/crypto/src/crypto/digests/RipeMD320Digest.cs +++ b/crypto/src/crypto/digests/RipeMD320Digest.cs @@ -1,5 +1,7 @@ using System; +using Org.BouncyCastle.Utilities; + namespace Org.BouncyCastle.Crypto.Digests { /// <remarks> @@ -38,6 +40,12 @@ namespace Org.BouncyCastle.Crypto.Digests public RipeMD320Digest(RipeMD320Digest t) : base(t) { + CopyIn(t); + } + + private void CopyIn(RipeMD320Digest t) + { + base.CopyIn(t); H0 = t.H0; H1 = t.H1; @@ -434,5 +442,18 @@ namespace Org.BouncyCastle.Crypto.Digests X[i] = 0; } } + + public override IMemoable Copy() + { + return new RipeMD320Digest(this); + } + + public override void Reset(IMemoable other) + { + RipeMD320Digest d = (RipeMD320Digest)other; + + CopyIn(d); + } + } } diff --git a/crypto/src/crypto/digests/SHA3Digest.cs b/crypto/src/crypto/digests/SHA3Digest.cs index a115495f4..2c6837b3c 100644 --- a/crypto/src/crypto/digests/SHA3Digest.cs +++ b/crypto/src/crypto/digests/SHA3Digest.cs @@ -11,7 +11,7 @@ namespace Org.BouncyCastle.Crypto.Digests /// Following the naming conventions used in the C source code to enable easy review of the implementation. /// </remarks> public class Sha3Digest - : IDigest + : IDigest, IMemoable { private static readonly ulong[] KeccakRoundConstants = KeccakInitializeRoundConstants(); @@ -103,6 +103,11 @@ namespace Org.BouncyCastle.Crypto.Digests public Sha3Digest(Sha3Digest source) { + CopyIn(source); + } + + private void CopyIn(Sha3Digest source) + { Array.Copy(source.state, 0, this.state, 0, source.state.Length); Array.Copy(source.dataQueue, 0, this.dataQueue, 0, source.dataQueue.Length); this.rate = source.rate; @@ -537,5 +542,19 @@ namespace Org.BouncyCastle.Crypto.Digests { Array.Copy(byteState, 0, data, 0, laneCount * 8); } + + public IMemoable Copy() + { + return new Sha3Digest(this); + } + + public void Reset(IMemoable other) + { + Sha3Digest d = (Sha3Digest)other; + + CopyIn(d); + } + + } } diff --git a/crypto/src/crypto/digests/Sha1Digest.cs b/crypto/src/crypto/digests/Sha1Digest.cs index e72b84f94..60ec651d5 100644 --- a/crypto/src/crypto/digests/Sha1Digest.cs +++ b/crypto/src/crypto/digests/Sha1Digest.cs @@ -1,6 +1,7 @@ using System; using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Digests { @@ -33,6 +34,13 @@ namespace Org.BouncyCastle.Crypto.Digests public Sha1Digest(Sha1Digest t) : base(t) { + CopyIn(t); + } + + private void CopyIn(Sha1Digest t) + { + base.CopyIn(t); + H1 = t.H1; H2 = t.H2; H3 = t.H3; @@ -259,5 +267,18 @@ namespace Org.BouncyCastle.Crypto.Digests xOff = 0; Array.Clear(X, 0, 16); } + + public override IMemoable Copy() + { + return new Sha1Digest(this); + } + + public override void Reset(IMemoable other) + { + Sha1Digest d = (Sha1Digest)other; + + CopyIn(d); + } + } } diff --git a/crypto/src/crypto/digests/Sha224Digest.cs b/crypto/src/crypto/digests/Sha224Digest.cs index 66ecd4ecd..b4e853745 100644 --- a/crypto/src/crypto/digests/Sha224Digest.cs +++ b/crypto/src/crypto/digests/Sha224Digest.cs @@ -1,6 +1,7 @@ using System; using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Digests { @@ -41,6 +42,13 @@ namespace Org.BouncyCastle.Crypto.Digests Sha224Digest t) : base(t) { + CopyIn(t); + } + + private void CopyIn(Sha224Digest t) + { + base.CopyIn(t); + H1 = t.H1; H2 = t.H2; H3 = t.H3; @@ -264,5 +272,18 @@ namespace Org.BouncyCastle.Crypto.Digests 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; + + public override IMemoable Copy() + { + return new Sha224Digest(this); + } + + public override void Reset(IMemoable other) + { + Sha224Digest d = (Sha224Digest)other; + + CopyIn(d); + } + } } diff --git a/crypto/src/crypto/digests/Sha256Digest.cs b/crypto/src/crypto/digests/Sha256Digest.cs index 1c00ab71f..98e10a34d 100644 --- a/crypto/src/crypto/digests/Sha256Digest.cs +++ b/crypto/src/crypto/digests/Sha256Digest.cs @@ -1,6 +1,7 @@ using System; using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Digests { @@ -36,6 +37,13 @@ namespace Org.BouncyCastle.Crypto.Digests */ public Sha256Digest(Sha256Digest t) : base(t) { + CopyIn(t); + } + + private void CopyIn(Sha256Digest t) + { + base.CopyIn(t); + H1 = t.H1; H2 = t.H2; H3 = t.H3; @@ -305,5 +313,18 @@ namespace Org.BouncyCastle.Crypto.Digests 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; + + public override IMemoable Copy() + { + return new Sha256Digest(this); + } + + public override void Reset(IMemoable other) + { + Sha256Digest d = (Sha256Digest)other; + + CopyIn(d); + } + } } diff --git a/crypto/src/crypto/digests/Sha384Digest.cs b/crypto/src/crypto/digests/Sha384Digest.cs index f1372d0a9..e6c9a9aa9 100644 --- a/crypto/src/crypto/digests/Sha384Digest.cs +++ b/crypto/src/crypto/digests/Sha384Digest.cs @@ -1,6 +1,7 @@ using System; using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Digests { @@ -83,5 +84,18 @@ namespace Org.BouncyCastle.Crypto.Digests H7 = 0xdb0c2e0d64f98fa7; H8 = 0x47b5481dbefa4fa4; } + + public override IMemoable Copy() + { + return new Sha384Digest(this); + } + + public override void Reset(IMemoable other) + { + Sha384Digest d = (Sha384Digest)other; + + CopyIn(d); + } + } } diff --git a/crypto/src/crypto/digests/Sha512Digest.cs b/crypto/src/crypto/digests/Sha512Digest.cs index b38ff8ee7..2a0964fd3 100644 --- a/crypto/src/crypto/digests/Sha512Digest.cs +++ b/crypto/src/crypto/digests/Sha512Digest.cs @@ -1,6 +1,7 @@ using System; using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Digests { @@ -86,5 +87,18 @@ namespace Org.BouncyCastle.Crypto.Digests H7 = 0x1f83d9abfb41bd6b; H8 = 0x5be0cd19137e2179; } + + public override IMemoable Copy() + { + return new Sha512Digest(this); + } + + public override void Reset(IMemoable other) + { + Sha512Digest d = (Sha512Digest)other; + + CopyIn(d); + } + } } diff --git a/crypto/src/crypto/digests/Sha512tDigest.cs b/crypto/src/crypto/digests/Sha512tDigest.cs index 7580d6267..2caefa763 100644 --- a/crypto/src/crypto/digests/Sha512tDigest.cs +++ b/crypto/src/crypto/digests/Sha512tDigest.cs @@ -1,6 +1,7 @@ using System; using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Digests { @@ -44,14 +45,7 @@ namespace Org.BouncyCastle.Crypto.Digests { this.digestLength = t.digestLength; - 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; + Reset(t); } public override string AlgorithmName @@ -175,5 +169,32 @@ namespace Org.BouncyCastle.Crypto.Digests 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; + } + + } } diff --git a/crypto/src/crypto/digests/SkeinDigest.cs b/crypto/src/crypto/digests/SkeinDigest.cs index b24fb3995..f826ce503 100644 --- a/crypto/src/crypto/digests/SkeinDigest.cs +++ b/crypto/src/crypto/digests/SkeinDigest.cs @@ -22,7 +22,7 @@ namespace Org.BouncyCastle.Crypto.Digests /// <seealso cref="Org.BouncyCastle.Crypto.Digests.SkeinEngine"/> /// <seealso cref="Org.BouncyCastle.Crypto.Parameters.SkeinParameters"/> public class SkeinDigest - : IDigest//, IMemoable + : IDigest, IMemoable { /// <summary> /// 256 bit block size - Skein-256 @@ -57,16 +57,16 @@ namespace Org.BouncyCastle.Crypto.Digests this.engine = new SkeinEngine(digest.engine); } - // public void Reset(IMemoable other) - // { - // SkeinDigest d = (SkeinDigest)other; - // engine.reset(d.engine); - // } - // - // public IMemoable copy() - // { - // return new SkeinDigest(this); - // } + public void Reset(IMemoable other) + { + SkeinDigest d = (SkeinDigest)other; + engine.Reset(d.engine); + } + + public IMemoable Copy() + { + return new SkeinDigest(this); + } public String AlgorithmName { diff --git a/crypto/src/crypto/digests/SkeinEngine.cs b/crypto/src/crypto/digests/SkeinEngine.cs index 94529bcf6..49ec51304 100644 --- a/crypto/src/crypto/digests/SkeinEngine.cs +++ b/crypto/src/crypto/digests/SkeinEngine.cs @@ -41,7 +41,7 @@ namespace Org.BouncyCastle.Crypto.Digests /// </remarks> /// <seealso cref="Org.BouncyCastle.Crypto.Parameters.SkeinParameters"/> public class SkeinEngine - // : IMemoable + : IMemoable { /// <summary> /// 256 bit block size - Skein-256 @@ -565,20 +565,20 @@ namespace Org.BouncyCastle.Crypto.Digests return existing; } - // public IMemoable Copy() - // { - // return new SkeinEngine(this); - // } - // - // public void Reset(IMemoable other) - // { - // SkeinEngine s = (SkeinEngine)other; - // if ((getBlockSize() != s.getBlockSize()) || (outputSizeBytes != s.outputSizeBytes)) - // { - // throw new IllegalArgumentException("Incompatible parameters in provided SkeinEngine."); - // } - // copyIn(s); - // } + public IMemoable Copy() + { + return new SkeinEngine(this); + } + + public void Reset(IMemoable other) + { + SkeinEngine s = (SkeinEngine)other; + if ((BlockSize != s.BlockSize) || (outputSizeBytes != s.outputSizeBytes)) + { + throw new MemoableResetException("Incompatible parameters in provided SkeinEngine."); + } + CopyIn(s); + } public int OutputSize { diff --git a/crypto/src/crypto/digests/TigerDigest.cs b/crypto/src/crypto/digests/TigerDigest.cs index b8c9a7664..059232de0 100644 --- a/crypto/src/crypto/digests/TigerDigest.cs +++ b/crypto/src/crypto/digests/TigerDigest.cs @@ -1,5 +1,7 @@ using System; + using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Digests { @@ -9,7 +11,7 @@ namespace Org.BouncyCastle.Crypto.Digests * http://www.cs.technion.ac.il/~biham/Reports/Tiger</a> */ public class TigerDigest - : IDigest + : IDigest, IMemoable { private const int MyByteLength = 64; @@ -571,17 +573,7 @@ namespace Org.BouncyCastle.Crypto.Digests */ public TigerDigest(TigerDigest t) { - a = t.a; - b = t.b; - c = t.c; - - Array.Copy(t.x, 0, x, 0, t.x.Length); - xOff = t.xOff; - - Array.Copy(t.Buffer, 0, Buffer, 0, t.Buffer.Length); - bOff = t.bOff; - - byteCount = t.byteCount; + Reset(t); } public string AlgorithmName @@ -864,5 +856,28 @@ namespace Org.BouncyCastle.Crypto.Digests byteCount = 0; } - } + + public IMemoable Copy() + { + return new TigerDigest(this); + } + + public void Reset(IMemoable other) + { + TigerDigest t = (TigerDigest)other; + + a = t.a; + b = t.b; + c = t.c; + + Array.Copy(t.x, 0, x, 0, t.x.Length); + xOff = t.xOff; + + Array.Copy(t.Buffer, 0, Buffer, 0, t.Buffer.Length); + bOff = t.bOff; + + byteCount = t.byteCount; + } + + } } diff --git a/crypto/src/crypto/digests/WhirlpoolDigest.cs b/crypto/src/crypto/digests/WhirlpoolDigest.cs index df83f4508..55b71205e 100644 --- a/crypto/src/crypto/digests/WhirlpoolDigest.cs +++ b/crypto/src/crypto/digests/WhirlpoolDigest.cs @@ -1,6 +1,7 @@ using System; using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Digests { @@ -9,7 +10,8 @@ namespace Org.BouncyCastle.Crypto.Digests * and Rijmen. * */ - public sealed class WhirlpoolDigest : IDigest + public sealed class WhirlpoolDigest + : IDigest, IMemoable { private const int BYTE_LENGTH = 64; @@ -149,19 +151,7 @@ namespace Org.BouncyCastle.Crypto.Digests */ public WhirlpoolDigest(WhirlpoolDigest originalDigest) { - Array.Copy(originalDigest._rc, 0, _rc, 0, _rc.Length); - - Array.Copy(originalDigest._buffer, 0, _buffer, 0, _buffer.Length); - - this._bufferPos = originalDigest._bufferPos; - Array.Copy(originalDigest._bitCount, 0, _bitCount, 0, _bitCount.Length); - - // -- internal hash state -- - Array.Copy(originalDigest._hash, 0, _hash, 0, _hash.Length); - Array.Copy(originalDigest._K, 0, _K, 0, _K.Length); - Array.Copy(originalDigest._L, 0, _L, 0, _L.Length); - Array.Copy(originalDigest._block, 0, _block, 0, _block.Length); - Array.Copy(originalDigest._state, 0, _state, 0, _state.Length); + Reset(originalDigest); } public string AlgorithmName @@ -393,5 +383,31 @@ namespace Org.BouncyCastle.Crypto.Digests { return BYTE_LENGTH; } + + public IMemoable Copy() + { + return new WhirlpoolDigest(this); + } + + public void Reset(IMemoable other) + { + WhirlpoolDigest originalDigest = (WhirlpoolDigest)other; + + Array.Copy(originalDigest._rc, 0, _rc, 0, _rc.Length); + + Array.Copy(originalDigest._buffer, 0, _buffer, 0, _buffer.Length); + + this._bufferPos = originalDigest._bufferPos; + Array.Copy(originalDigest._bitCount, 0, _bitCount, 0, _bitCount.Length); + + // -- internal hash state -- + Array.Copy(originalDigest._hash, 0, _hash, 0, _hash.Length); + Array.Copy(originalDigest._K, 0, _K, 0, _K.Length); + Array.Copy(originalDigest._L, 0, _L, 0, _L.Length); + Array.Copy(originalDigest._block, 0, _block, 0, _block.Length); + Array.Copy(originalDigest._state, 0, _state, 0, _state.Length); + } + + } } diff --git a/crypto/src/util/IMemoable.cs b/crypto/src/util/IMemoable.cs new file mode 100644 index 000000000..befc10fbf --- /dev/null +++ b/crypto/src/util/IMemoable.cs @@ -0,0 +1,29 @@ +using System; + +namespace Org.BouncyCastle.Utilities +{ + public interface IMemoable + { + /// <summary> + /// Produce a copy of this object with its configuration and in its current state. + /// </summary> + /// <remarks> + /// The returned object may be used simply to store the state, or may be used as a similar object + /// starting from the copied state. + /// </remarks> + IMemoable Copy(); + + /// <summary> + /// Restore a copied object state into this object. + /// </summary> + /// <remarks> + /// Implementations of this method <em>should</em> try to avoid or minimise memory allocation to perform the reset. + /// </remarks> + /// <param name="other">an object originally {@link #copy() copied} from an object of the same type as this instance.</param> + /// <exception cref="ClassCastException">if the provided object is not of the correct type.</exception> + /// <exception cref="MemoableResetException">if the <b>other</b> parameter is in some other way invalid.</exception> + void Reset(IMemoable other); + } + +} + diff --git a/crypto/src/util/MemoableResetException.cs b/crypto/src/util/MemoableResetException.cs new file mode 100644 index 000000000..d9542dab2 --- /dev/null +++ b/crypto/src/util/MemoableResetException.cs @@ -0,0 +1,27 @@ +using System; + +namespace Org.BouncyCastle.Utilities +{ + /** + * Exception to be thrown on a failure to reset an object implementing Memoable. + * <p> + * The exception extends ClassCastException to enable users to have a single handling case, + * only introducing specific handling of this one if required. + * </p> + */ + public class MemoableResetException + : InvalidCastException + { + /** + * Basic Constructor. + * + * @param msg message to be associated with this exception. + */ + public MemoableResetException(string msg) + : base(msg) + { + } + } + +} + diff --git a/crypto/test/src/crypto/test/DigestTest.cs b/crypto/test/src/crypto/test/DigestTest.cs index 533e87181..930979643 100644 --- a/crypto/test/src/crypto/test/DigestTest.cs +++ b/crypto/test/src/crypto/test/DigestTest.cs @@ -2,6 +2,7 @@ using System; using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Encoders; using Org.BouncyCastle.Utilities.Test; @@ -35,9 +36,9 @@ namespace Org.BouncyCastle.Crypto.Tests for (int i = 0; i < input.Length - 1; i++) { - byte[] m = toByteArray(input[i]); + byte[] msg = toByteArray(input[i]); - vectorTest(digest, i, resBuf, m, Hex.Decode(results[i])); + vectorTest(digest, i, resBuf, msg, Hex.Decode(results[i])); } byte[] lastV = toByteArray(input[input.Length - 1]); @@ -68,6 +69,45 @@ namespace Org.BouncyCastle.Crypto.Tests { Fail("failing second clone vector test", results[results.Length - 1], Hex.ToHexString(resBuf)); } + + // + // memo test + // + IMemoable m = (IMemoable)digest; + + digest.BlockUpdate(lastV, 0, lastV.Length/2); + + // copy the Digest + IMemoable copy1 = m.Copy(); + IMemoable copy2 = copy1.Copy(); + + digest.BlockUpdate(lastV, lastV.Length/2, lastV.Length - lastV.Length/2); + digest.DoFinal(resBuf, 0); + + if (!AreEqual(lastDigest, resBuf)) + { + Fail("failing memo vector test", results[results.Length - 1], Hex.ToHexString(resBuf)); + } + + m.Reset(copy1); + + digest.BlockUpdate(lastV, lastV.Length/2, lastV.Length - lastV.Length/2); + digest.DoFinal(resBuf, 0); + + if (!AreEqual(lastDigest, resBuf)) + { + Fail("failing memo reset vector test", results[results.Length - 1], Hex.ToHexString(resBuf)); + } + + IDigest md = (IDigest)copy2; + + md.BlockUpdate(lastV, lastV.Length/2, lastV.Length - lastV.Length/2); + md.DoFinal(resBuf, 0); + + if (!AreEqual(lastDigest, resBuf)) + { + Fail("failing memo copy vector test", results[results.Length - 1], Hex.ToHexString(resBuf)); + } } private byte[] toByteArray( |