diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2015-11-16 21:30:04 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2015-11-16 21:30:04 +0700 |
commit | 8bda1de4207632587d2df5fbd08797e22d5f8463 (patch) | |
tree | 206f6e7b0427cd96e7203d580ac08ffb4557180b /crypto | |
parent | Remove redundant semicolons (diff) | |
download | BouncyCastle.NET-ed25519-8bda1de4207632587d2df5fbd08797e22d5f8463.tar.xz |
Finish port of latest PRNG/DRBG stuff from Java
Diffstat (limited to 'crypto')
24 files changed, 2297 insertions, 1399 deletions
diff --git a/crypto/crypto.csproj b/crypto/crypto.csproj index 28d0b19b3..0c6dba76c 100644 --- a/crypto/crypto.csproj +++ b/crypto/crypto.csproj @@ -4314,6 +4314,11 @@ BuildAction = "Compile" /> <File + RelPath = "src\crypto\prng\BasicEntropySourceProvider.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\crypto\prng\CryptoApiRandomGenerator.cs" SubType = "Code" BuildAction = "Compile" @@ -4324,6 +4329,21 @@ BuildAction = "Compile" /> <File + RelPath = "src\crypto\prng\IDrbgProvider.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "src\crypto\prng\IEntropySource.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "src\crypto\prng\IEntropySourceProvider.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\crypto\prng\IRandomGenerator.cs" SubType = "Code" BuildAction = "Compile" @@ -4334,6 +4354,16 @@ BuildAction = "Compile" /> <File + RelPath = "src\crypto\prng\SP800SecureRandom.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "src\crypto\prng\SP800SecureRandomBuilder.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\crypto\prng\ThreadedSeedGenerator.cs" SubType = "Code" BuildAction = "Compile" @@ -4344,6 +4374,46 @@ BuildAction = "Compile" /> <File + RelPath = "src\crypto\prng\X931Rng.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "src\crypto\prng\X931SecureRandom.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "src\crypto\prng\X931SecureRandomBuilder.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "src\crypto\prng\drbg\CtrSP800Drbg.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "src\crypto\prng\drbg\DrbgUtilities.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "src\crypto\prng\drbg\HashSP800Drbg.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "src\crypto\prng\drbg\HMacSP800Drbg.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "src\crypto\prng\drbg\ISP80090Drbg.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\crypto\signers\DSADigestSigner.cs" SubType = "Code" BuildAction = "Compile" @@ -11070,6 +11140,41 @@ BuildAction = "Compile" /> <File + RelPath = "test\src\crypto\prng\test\CtrDrbgTest.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "test\src\crypto\prng\test\DrbgTestVector.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "test\src\crypto\prng\test\HashDrbgTest.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "test\src\crypto\prng\test\HMacDrbgTest.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "test\src\crypto\prng\test\TestEntropySourcProvider.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "test\src\crypto\prng\test\X931Test.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "test\src\crypto\prng\test\X931TestVector.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "test\src\crypto\test\AeadTestUtilities.cs" SubType = "Code" BuildAction = "Compile" diff --git a/crypto/src/crypto/prng/BasicEntropySourceProvider.cs b/crypto/src/crypto/prng/BasicEntropySourceProvider.cs new file mode 100644 index 000000000..0e929e0fd --- /dev/null +++ b/crypto/src/crypto/prng/BasicEntropySourceProvider.cs @@ -0,0 +1,70 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Prng +{ + /** + * An EntropySourceProvider where entropy generation is based on a SecureRandom output using SecureRandom.generateSeed(). + */ + public class BasicEntropySourceProvider + : IEntropySourceProvider + { + private readonly SecureRandom mSecureRandom; + private readonly bool mPredictionResistant; + + /** + * Create a entropy source provider based on the passed in SecureRandom. + * + * @param secureRandom the SecureRandom to base EntropySource construction on. + * @param isPredictionResistant boolean indicating if the SecureRandom is based on prediction resistant entropy or not (true if it is). + */ + public BasicEntropySourceProvider(SecureRandom secureRandom, bool isPredictionResistant) + { + mSecureRandom = secureRandom; + mPredictionResistant = isPredictionResistant; + } + + /** + * Return an entropy source that will create bitsRequired bits of entropy on + * each invocation of getEntropy(). + * + * @param bitsRequired size (in bits) of entropy to be created by the provided source. + * @return an EntropySource that generates bitsRequired bits of entropy on each call to its getEntropy() method. + */ + public IEntropySource Get(int bitsRequired) + { + return new BasicEntropySource(mSecureRandom, mPredictionResistant, bitsRequired); + } + + private class BasicEntropySource + : IEntropySource + { + private readonly SecureRandom mSecureRandom; + private readonly bool mPredictionResistant; + private readonly int mEntropySize; + + internal BasicEntropySource(SecureRandom secureRandom, bool predictionResistant, int entropySize) + { + this.mSecureRandom = secureRandom; + this.mPredictionResistant = predictionResistant; + this.mEntropySize = entropySize; + } + + bool IEntropySource.IsPredictionResistant + { + get { return mPredictionResistant; } + } + + byte[] IEntropySource.GetEntropy() + { + return mSecureRandom.GenerateSeed((mEntropySize + 7) / 8); + } + + int IEntropySource.EntropySize + { + get { return mEntropySize; } + } + } + } +} diff --git a/crypto/src/crypto/prng/IDrbgProvider.cs b/crypto/src/crypto/prng/IDrbgProvider.cs new file mode 100644 index 000000000..5ebf5fd8d --- /dev/null +++ b/crypto/src/crypto/prng/IDrbgProvider.cs @@ -0,0 +1,11 @@ +using System; + +using Org.BouncyCastle.Crypto.Prng.Drbg; + +namespace Org.BouncyCastle.Crypto.Prng +{ + internal interface IDrbgProvider + { + ISP80090Drbg Get(IEntropySource entropySource); + } +} diff --git a/crypto/src/crypto/prng/IEntropySource.cs b/crypto/src/crypto/prng/IEntropySource.cs index 33ce1b801..90b9e61af 100644 --- a/crypto/src/crypto/prng/IEntropySource.cs +++ b/crypto/src/crypto/prng/IEntropySource.cs @@ -1,9 +1,9 @@ using System; -namespace Org.BouncyCastle.Crypto +namespace Org.BouncyCastle.Crypto.Prng { /// <summary> - /// Base interface describing an entropy source for a DRGB. + /// Base interface describing an entropy source for a DRBG. /// </summary> public interface IEntropySource { diff --git a/crypto/src/crypto/prng/IEntropySourceProvider.cs b/crypto/src/crypto/prng/IEntropySourceProvider.cs index 990c6497b..643f92ef8 100644 --- a/crypto/src/crypto/prng/IEntropySourceProvider.cs +++ b/crypto/src/crypto/prng/IEntropySourceProvider.cs @@ -1,8 +1,6 @@ using System; -using System.Collections.Generic; -using System.Text; -namespace Org.BouncyCastle.Crypto +namespace Org.BouncyCastle.Crypto.Prng { /// <summary> /// Base interface describing a provider of entropy sources. diff --git a/crypto/src/crypto/prng/SP800SecureRandom.cs b/crypto/src/crypto/prng/SP800SecureRandom.cs new file mode 100644 index 000000000..996ba0846 --- /dev/null +++ b/crypto/src/crypto/prng/SP800SecureRandom.cs @@ -0,0 +1,82 @@ +using System; + +using Org.BouncyCastle.Crypto.Prng.Drbg; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Prng +{ + public class SP800SecureRandom + : SecureRandom + { + private readonly IDrbgProvider mDrbgProvider; + private readonly bool mPredictionResistant; + private readonly SecureRandom mRandomSource; + private readonly IEntropySource mEntropySource; + + private ISP80090Drbg mDrbg; + + internal SP800SecureRandom(SecureRandom randomSource, IEntropySource entropySource, IDrbgProvider drbgProvider, bool predictionResistant) + : base((IRandomGenerator)null) + { + this.mRandomSource = randomSource; + this.mEntropySource = entropySource; + this.mDrbgProvider = drbgProvider; + this.mPredictionResistant = predictionResistant; + } + + public override void SetSeed(byte[] seed) + { + lock (this) + { + if (mRandomSource != null) + { + this.mRandomSource.SetSeed(seed); + } + } + } + + public override void SetSeed(long seed) + { + lock (this) + { + // this will happen when SecureRandom() is created + if (mRandomSource != null) + { + this.mRandomSource.SetSeed(seed); + } + } + } + + public override void NextBytes(byte[] bytes) + { + lock (this) + { + if (mDrbg == null) + { + mDrbg = mDrbgProvider.Get(mEntropySource); + } + + // check if a reseed is required... + if (mDrbg.Generate(bytes, null, mPredictionResistant) < 0) + { + mDrbg.Reseed(null); + mDrbg.Generate(bytes, null, mPredictionResistant); + } + } + } + + public override void NextBytes(byte[] buf, int off, int len) + { + byte[] bytes = new byte[len]; + NextBytes(bytes); + Array.Copy(bytes, 0, buf, off, len); + } + + public override byte[] GenerateSeed(int numBytes) + { + byte[] bytes = new byte[numBytes]; + NextBytes(bytes); + return bytes; + } + } +} diff --git a/crypto/src/crypto/prng/SP800SecureRandomBuilder.cs b/crypto/src/crypto/prng/SP800SecureRandomBuilder.cs new file mode 100644 index 000000000..7199f1ae7 --- /dev/null +++ b/crypto/src/crypto/prng/SP800SecureRandomBuilder.cs @@ -0,0 +1,208 @@ +using System; + +using Org.BouncyCastle.Crypto.Prng.Drbg; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Prng +{ + /** + * Builder class for making SecureRandom objects based on SP 800-90A Deterministic Random Bit Generators (DRBG). + */ + public class SP800SecureRandomBuilder + { + private readonly SecureRandom mRandom; + private readonly IEntropySourceProvider mEntropySourceProvider; + + private byte[] mPersonalizationString = null; + private int mSecurityStrength = 256; + private int mEntropyBitsRequired = 256; + + /** + * Basic constructor, creates a builder using an EntropySourceProvider based on the default SecureRandom with + * predictionResistant set to false. + * <p> + * Any SecureRandom created from a builder constructed like this will make use of input passed to SecureRandom.setSeed() if + * the default SecureRandom does for its generateSeed() call. + * </p> + */ + public SP800SecureRandomBuilder() + : this(new SecureRandom(), false) + { + } + + /** + * Construct a builder with an EntropySourceProvider based on the passed in SecureRandom and the passed in value + * for prediction resistance. + * <p> + * Any SecureRandom created from a builder constructed like this will make use of input passed to SecureRandom.setSeed() if + * the passed in SecureRandom does for its generateSeed() call. + * </p> + * @param entropySource + * @param predictionResistant + */ + public SP800SecureRandomBuilder(SecureRandom entropySource, bool predictionResistant) + { + this.mRandom = entropySource; + this.mEntropySourceProvider = new BasicEntropySourceProvider(entropySource, predictionResistant); + } + + /** + * Create a builder which makes creates the SecureRandom objects from a specified entropy source provider. + * <p> + * <b>Note:</b> If this constructor is used any calls to setSeed() in the resulting SecureRandom will be ignored. + * </p> + * @param entropySourceProvider a provider of EntropySource objects. + */ + public SP800SecureRandomBuilder(IEntropySourceProvider entropySourceProvider) + { + this.mRandom = null; + this.mEntropySourceProvider = entropySourceProvider; + } + + /** + * Set the personalization string for DRBG SecureRandoms created by this builder + * @param personalizationString the personalisation string for the underlying DRBG. + * @return the current builder. + */ + public SP800SecureRandomBuilder SetPersonalizationString(byte[] personalizationString) + { + this.mPersonalizationString = personalizationString; + return this; + } + + /** + * Set the security strength required for DRBGs used in building SecureRandom objects. + * + * @param securityStrength the security strength (in bits) + * @return the current builder. + */ + public SP800SecureRandomBuilder SetSecurityStrength(int securityStrength) + { + this.mSecurityStrength = securityStrength; + return this; + } + + /** + * Set the amount of entropy bits required for seeding and reseeding DRBGs used in building SecureRandom objects. + * + * @param entropyBitsRequired the number of bits of entropy to be requested from the entropy source on each seed/reseed. + * @return the current builder. + */ + public SP800SecureRandomBuilder SetEntropyBitsRequired(int entropyBitsRequired) + { + this.mEntropyBitsRequired = entropyBitsRequired; + return this; + } + + /** + * Build a SecureRandom based on a SP 800-90A Hash DRBG. + * + * @param digest digest algorithm to use in the DRBG underneath the SecureRandom. + * @param nonce nonce value to use in DRBG construction. + * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes. + * @return a SecureRandom supported by a Hash DRBG. + */ + public SP800SecureRandom BuildHash(IDigest digest, byte[] nonce, bool predictionResistant) + { + return new SP800SecureRandom(mRandom, mEntropySourceProvider.Get(mEntropyBitsRequired), + new HashDrbgProvider(digest, nonce, mPersonalizationString, mSecurityStrength), predictionResistant); + } + + /** + * Build a SecureRandom based on a SP 800-90A CTR DRBG. + * + * @param cipher the block cipher to base the DRBG on. + * @param keySizeInBits key size in bits to be used with the block cipher. + * @param nonce nonce value to use in DRBG construction. + * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes. + * @return a SecureRandom supported by a CTR DRBG. + */ + public SP800SecureRandom BuildCtr(IBlockCipher cipher, int keySizeInBits, byte[] nonce, bool predictionResistant) + { + return new SP800SecureRandom(mRandom, mEntropySourceProvider.Get(mEntropyBitsRequired), + new CtrDrbgProvider(cipher, keySizeInBits, nonce, mPersonalizationString, mSecurityStrength), predictionResistant); + } + + /** + * Build a SecureRandom based on a SP 800-90A HMAC DRBG. + * + * @param hMac HMAC algorithm to use in the DRBG underneath the SecureRandom. + * @param nonce nonce value to use in DRBG construction. + * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes. + * @return a SecureRandom supported by a HMAC DRBG. + */ + public SP800SecureRandom BuildHMac(IMac hMac, byte[] nonce, bool predictionResistant) + { + return new SP800SecureRandom(mRandom, mEntropySourceProvider.Get(mEntropyBitsRequired), + new HMacDrbgProvider(hMac, nonce, mPersonalizationString, mSecurityStrength), predictionResistant); + } + + private class HashDrbgProvider + : IDrbgProvider + { + private readonly IDigest mDigest; + private readonly byte[] mNonce; + private readonly byte[] mPersonalizationString; + private readonly int mSecurityStrength; + + public HashDrbgProvider(IDigest digest, byte[] nonce, byte[] personalizationString, int securityStrength) + { + this.mDigest = digest; + this.mNonce = nonce; + this.mPersonalizationString = personalizationString; + this.mSecurityStrength = securityStrength; + } + + public ISP80090Drbg Get(IEntropySource entropySource) + { + return new HashSP800Drbg(mDigest, mSecurityStrength, entropySource, mPersonalizationString, mNonce); + } + } + + private class HMacDrbgProvider + : IDrbgProvider + { + private readonly IMac mHMac; + private readonly byte[] mNonce; + private readonly byte[] mPersonalizationString; + private readonly int mSecurityStrength; + + public HMacDrbgProvider(IMac hMac, byte[] nonce, byte[] personalizationString, int securityStrength) + { + this.mHMac = hMac; + this.mNonce = nonce; + this.mPersonalizationString = personalizationString; + this.mSecurityStrength = securityStrength; + } + + public ISP80090Drbg Get(IEntropySource entropySource) + { + return new HMacSP800Drbg(mHMac, mSecurityStrength, entropySource, mPersonalizationString, mNonce); + } + } + + private class CtrDrbgProvider + : IDrbgProvider + { + private readonly IBlockCipher mBlockCipher; + private readonly int mKeySizeInBits; + private readonly byte[] mNonce; + private readonly byte[] mPersonalizationString; + private readonly int mSecurityStrength; + + public CtrDrbgProvider(IBlockCipher blockCipher, int keySizeInBits, byte[] nonce, byte[] personalizationString, int securityStrength) + { + this.mBlockCipher = blockCipher; + this.mKeySizeInBits = keySizeInBits; + this.mNonce = nonce; + this.mPersonalizationString = personalizationString; + this.mSecurityStrength = securityStrength; + } + + public ISP80090Drbg Get(IEntropySource entropySource) + { + return new CtrSP800Drbg(mBlockCipher, mKeySizeInBits, mSecurityStrength, entropySource, mPersonalizationString, mNonce); + } + } + } +} diff --git a/crypto/src/crypto/prng/X931Rng.cs b/crypto/src/crypto/prng/X931Rng.cs new file mode 100644 index 000000000..d09cc6618 --- /dev/null +++ b/crypto/src/crypto/prng/X931Rng.cs @@ -0,0 +1,141 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Prng +{ + internal class X931Rng + { + private const long BLOCK64_RESEED_MAX = 1L << (16 - 1); + private const long BLOCK128_RESEED_MAX = 1L << (24 - 1); + private const int BLOCK64_MAX_BITS_REQUEST = 1 << (13 - 1); + private const int BLOCK128_MAX_BITS_REQUEST = 1 << (19 - 1); + + private readonly IBlockCipher mEngine; + private readonly IEntropySource mEntropySource; + + private readonly byte[] mDT; + private readonly byte[] mI; + private readonly byte[] mR; + + private byte[] mV; + + private long mReseedCounter = 1; + + /** + * + * @param engine + * @param entropySource + */ + internal X931Rng(IBlockCipher engine, byte[] dateTimeVector, IEntropySource entropySource) + { + this.mEngine = engine; + this.mEntropySource = entropySource; + + this.mDT = new byte[engine.GetBlockSize()]; + + Array.Copy(dateTimeVector, 0, mDT, 0, mDT.Length); + + this.mI = new byte[engine.GetBlockSize()]; + this.mR = new byte[engine.GetBlockSize()]; + } + + /** + * Populate a passed in array with random data. + * + * @param output output array for generated bits. + * @param predictionResistant true if a reseed should be forced, false otherwise. + * + * @return number of bits generated, -1 if a reseed required. + */ + internal int Generate(byte[] output, bool predictionResistant) + { + if (mR.Length == 8) // 64 bit block size + { + if (mReseedCounter > BLOCK64_RESEED_MAX) + return -1; + + if (IsTooLarge(output, BLOCK64_MAX_BITS_REQUEST / 8)) + throw new ArgumentException("Number of bits per request limited to " + BLOCK64_MAX_BITS_REQUEST, "output"); + } + else + { + if (mReseedCounter > BLOCK128_RESEED_MAX) + return -1; + + if (IsTooLarge(output, BLOCK128_MAX_BITS_REQUEST / 8)) + throw new ArgumentException("Number of bits per request limited to " + BLOCK128_MAX_BITS_REQUEST, "output"); + } + + if (predictionResistant || mV == null) + { + mV = mEntropySource.GetEntropy(); + if (mV.Length != mEngine.GetBlockSize()) + throw new InvalidOperationException("Insufficient entropy returned"); + } + + int m = output.Length / mR.Length; + + for (int i = 0; i < m; i++) + { + mEngine.ProcessBlock(mDT, 0, mI, 0); + Process(mR, mI, mV); + Process(mV, mR, mI); + + Array.Copy(mR, 0, output, i * mR.Length, mR.Length); + + Increment(mDT); + } + + int bytesToCopy = (output.Length - m * mR.Length); + + if (bytesToCopy > 0) + { + mEngine.ProcessBlock(mDT, 0, mI, 0); + Process(mR, mI, mV); + Process(mV, mR, mI); + + Array.Copy(mR, 0, output, m * mR.Length, bytesToCopy); + + Increment(mDT); + } + + mReseedCounter++; + + return output.Length; + } + + /** + * Reseed the RNG. + */ + internal void Reseed() + { + mV = mEntropySource.GetEntropy(); + if (mV.Length != mEngine.GetBlockSize()) + throw new InvalidOperationException("Insufficient entropy returned"); + mReseedCounter = 1; + } + + private void Process(byte[] res, byte[] a, byte[] b) + { + for (int i = 0; i != res.Length; i++) + { + res[i] = (byte)(a[i] ^ b[i]); + } + + mEngine.ProcessBlock(res, 0, res, 0); + } + + private void Increment(byte[] val) + { + for (int i = val.Length - 1; i >= 0; i--) + { + if (++val[i] != 0) + break; + } + } + + private static bool IsTooLarge(byte[] bytes, int maxBytes) + { + return bytes != null && bytes.Length > maxBytes; + } + } +} diff --git a/crypto/src/crypto/prng/X931SecureRandom.cs b/crypto/src/crypto/prng/X931SecureRandom.cs new file mode 100644 index 000000000..a87bf1567 --- /dev/null +++ b/crypto/src/crypto/prng/X931SecureRandom.cs @@ -0,0 +1,72 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Prng +{ + public class X931SecureRandom + : SecureRandom + { + private readonly bool mPredictionResistant; + private readonly SecureRandom mRandomSource; + private readonly X931Rng mDrbg; + + internal X931SecureRandom(SecureRandom randomSource, X931Rng drbg, bool predictionResistant) + : base((IRandomGenerator)null) + { + this.mRandomSource = randomSource; + this.mDrbg = drbg; + this.mPredictionResistant = predictionResistant; + } + + public override void SetSeed(byte[] seed) + { + lock (this) + { + if (mRandomSource != null) + { + this.mRandomSource.SetSeed(seed); + } + } + } + + public override void SetSeed(long seed) + { + lock (this) + { + // this will happen when SecureRandom() is created + if (mRandomSource != null) + { + this.mRandomSource.SetSeed(seed); + } + } + } + + public override void NextBytes(byte[] bytes) + { + lock (this) + { + // check if a reseed is required... + if (mDrbg.Generate(bytes, mPredictionResistant) < 0) + { + mDrbg.Reseed(); + mDrbg.Generate(bytes, mPredictionResistant); + } + } + } + + public override void NextBytes(byte[] buf, int off, int len) + { + byte[] bytes = new byte[len]; + NextBytes(bytes); + Array.Copy(bytes, 0, buf, off, len); + } + + public override byte[] GenerateSeed(int numBytes) + { + byte[] bytes = new byte[numBytes]; + NextBytes(bytes); + return bytes; + } + } +} diff --git a/crypto/src/crypto/prng/X931SecureRandomBuilder.cs b/crypto/src/crypto/prng/X931SecureRandomBuilder.cs new file mode 100644 index 000000000..31e94312e --- /dev/null +++ b/crypto/src/crypto/prng/X931SecureRandomBuilder.cs @@ -0,0 +1,87 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Utilities; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Date; + +namespace Org.BouncyCastle.Crypto.Prng +{ + public class X931SecureRandomBuilder + { + private readonly SecureRandom mRandom; // JDK 1.1 complains on final. + + private IEntropySourceProvider mEntropySourceProvider; + private byte[] mDateTimeVector; + + /** + * Basic constructor, creates a builder using an EntropySourceProvider based on the default SecureRandom with + * predictionResistant set to false. + * <p> + * Any SecureRandom created from a builder constructed like this will make use of input passed to SecureRandom.setSeed() if + * the default SecureRandom does for its generateSeed() call. + * </p> + */ + public X931SecureRandomBuilder() + : this(new SecureRandom(), false) + { + } + + /** + * Construct a builder with an EntropySourceProvider based on the passed in SecureRandom and the passed in value + * for prediction resistance. + * <p> + * Any SecureRandom created from a builder constructed like this will make use of input passed to SecureRandom.setSeed() if + * the passed in SecureRandom does for its generateSeed() call. + * </p> + * @param entropySource + * @param predictionResistant + */ + public X931SecureRandomBuilder(SecureRandom entropySource, bool predictionResistant) + { + this.mRandom = entropySource; + this.mEntropySourceProvider = new BasicEntropySourceProvider(mRandom, predictionResistant); + } + + /** + * Create a builder which makes creates the SecureRandom objects from a specified entropy source provider. + * <p> + * <b>Note:</b> If this constructor is used any calls to setSeed() in the resulting SecureRandom will be ignored. + * </p> + * @param entropySourceProvider a provider of EntropySource objects. + */ + public X931SecureRandomBuilder(IEntropySourceProvider entropySourceProvider) + { + this.mRandom = null; + this.mEntropySourceProvider = entropySourceProvider; + } + + public X931SecureRandomBuilder SetDateTimeVector(byte[] dateTimeVector) + { + this.mDateTimeVector = dateTimeVector; + return this; + } + + /** + * Construct a X9.31 secure random generator using the passed in engine and key. If predictionResistant is true the + * generator will be reseeded on each request. + * + * @param engine a block cipher to use as the operator. + * @param key the block cipher key to initialise engine with. + * @param predictionResistant true if engine to be reseeded on each use, false otherwise. + * @return a SecureRandom. + */ + public X931SecureRandom Build(IBlockCipher engine, KeyParameter key, bool predictionResistant) + { + if (mDateTimeVector == null) + { + mDateTimeVector = new byte[engine.GetBlockSize()]; + Pack.UInt64_To_BE((ulong)DateTimeUtilities.CurrentUnixMs(), mDateTimeVector, 0); + } + + engine.Init(true, key); + + return new X931SecureRandom(mRandom, new X931Rng(engine, mDateTimeVector, mEntropySourceProvider.Get(engine.GetBlockSize() * 8)), predictionResistant); + } + } +} diff --git a/crypto/src/crypto/prng/drbg/CtrSP800Drbg.cs b/crypto/src/crypto/prng/drbg/CtrSP800Drbg.cs index d9595d530..2e4fbe4ed 100644 --- a/crypto/src/crypto/prng/drbg/CtrSP800Drbg.cs +++ b/crypto/src/crypto/prng/drbg/CtrSP800Drbg.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Encoders; @@ -8,24 +9,25 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg /** * A SP800-90A CTR DRBG. */ - public class CTRSP800Drbg: SP80090Drbg + public class CtrSP800Drbg + : ISP80090Drbg { - private static readonly long TDEA_RESEED_MAX = 1L << (32 - 1); - private static readonly long AES_RESEED_MAX = 1L << (48 - 1); - private static readonly int TDEA_MAX_BITS_REQUEST = 1 << (13 - 1); - private static readonly int AES_MAX_BITS_REQUEST = 1 << (19 - 1); - - private IEntropySource _entropySource; - private IBlockCipher _engine; - private int _keySizeInBits; - private int _seedLength; - private int _securityStrength; - - // internal state - private byte[] _Key; - private byte[] _V; - private long _reseedCounter = 0; - private bool _isTDEA = false; + private static readonly long TDEA_RESEED_MAX = 1L << (32 - 1); + private static readonly long AES_RESEED_MAX = 1L << (48 - 1); + private static readonly int TDEA_MAX_BITS_REQUEST = 1 << (13 - 1); + private static readonly int AES_MAX_BITS_REQUEST = 1 << (19 - 1); + + private readonly IEntropySource mEntropySource; + private readonly IBlockCipher mEngine; + private readonly int mKeySizeInBits; + private readonly int mSeedLength; + private readonly int mSecurityStrength; + + // internal state + private byte[] mKey; + private byte[] mV; + private long mReseedCounter = 0; + private bool mIsTdea = false; /** * Construct a SP800-90A CTR DRBG. @@ -39,66 +41,58 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg * @param personalizationString personalization string to distinguish this DRBG (may be null). * @param nonce nonce to further distinguish this DRBG (may be null). */ - public CTRSP800Drbg(IBlockCipher engine, int keySizeInBits, int securityStrength, IEntropySource entropySource, byte[] personalizationString, byte[] nonce) + public CtrSP800Drbg(IBlockCipher engine, int keySizeInBits, int securityStrength, IEntropySource entropySource, + byte[] personalizationString, byte[] nonce) { - _entropySource = entropySource; - _engine = engine; - - _keySizeInBits = keySizeInBits; - _securityStrength = securityStrength; - _seedLength = keySizeInBits + engine.getBlockSize() * 8; - _isTDEA = isTDEA(engine); - if (securityStrength > 256) - { throw new ArgumentException("Requested security strength is not supported by the derivation function"); - } - - if (getMaxSecurityStrength(engine, keySizeInBits) < securityStrength) - { + if (GetMaxSecurityStrength(engine, keySizeInBits) < securityStrength) throw new ArgumentException("Requested security strength is not supported by block cipher and key size"); - } - if (entropySource.EntropySize < securityStrength) - { throw new ArgumentException("Not enough entropy for security strength required"); - } - byte[] entropy = getEntropy(); // Get_entropy_input + mEntropySource = entropySource; + mEngine = engine; + + mKeySizeInBits = keySizeInBits; + mSecurityStrength = securityStrength; + mSeedLength = keySizeInBits + engine.GetBlockSize() * 8; + mIsTdea = IsTdea(engine); + + byte[] entropy = GetEntropy(); // Get_entropy_input - CTR_DRBG_Instantiate_algorithm(entropy, nonce, personalizationString); + CTR_DRBG_Instantiate_algorithm(entropy, nonce, personalizationString); } - private void CTR_DRBG_Instantiate_algorithm(byte[] entropy, byte[] nonce, - byte[] personalisationString) + private void CTR_DRBG_Instantiate_algorithm(byte[] entropy, byte[] nonce, byte[] personalisationString) { - byte[] seedMaterial = Arrays.Concatenate(entropy, nonce, personalisationString); - byte[] seed = Block_Cipher_df(seedMaterial, _seedLength); + byte[] seedMaterial = Arrays.ConcatenateAll(entropy, nonce, personalisationString); + byte[] seed = Block_Cipher_df(seedMaterial, mSeedLength); - int outlen = _engine.getBlockSize(); + int outlen = mEngine.GetBlockSize(); - _Key = new byte[(_keySizeInBits + 7) / 8]; - _V = new byte[outlen]; + mKey = new byte[(mKeySizeInBits + 7) / 8]; + mV = new byte[outlen]; - // _Key & _V are modified by this call - CTR_DRBG_Update(seed, _Key, _V); + // mKey & mV are modified by this call + CTR_DRBG_Update(seed, mKey, mV); - _reseedCounter = 1; + mReseedCounter = 1; } - private void CTR_DRBG_Update(byte[] seed, byte[] key, byte[] v) + private void CTR_DRBG_Update(byte[] seed, byte[] key, byte[] v) { byte[] temp = new byte[seed.Length]; - byte[] outputBlock = new byte[_engine.getBlockSize()]; - - int i=0; - int outLen = _engine.getBlockSize(); + byte[] outputBlock = new byte[mEngine.GetBlockSize()]; + + int i = 0; + int outLen = mEngine.GetBlockSize(); - _engine.init(true, new KeyParameter(expandKey(key))); + mEngine.Init(true, new KeyParameter(ExpandKey(key))); while (i*outLen < seed.Length) { - addOneTo(v); - _engine.processBlock(v, 0, outputBlock, 0); + AddOneTo(v); + mEngine.ProcessBlock(v, 0, outputBlock, 0); int bytesToCopy = ((temp.Length - i * outLen) > outLen) ? outLen : (temp.Length - i * outLen); @@ -115,49 +109,48 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg private void CTR_DRBG_Reseed_algorithm(byte[] additionalInput) { - byte[] seedMaterial = Arrays.Concatenate(getEntropy(), additionalInput); + byte[] seedMaterial = Arrays.Concatenate(GetEntropy(), additionalInput); - seedMaterial = Block_Cipher_df(seedMaterial, _seedLength); + seedMaterial = Block_Cipher_df(seedMaterial, mSeedLength); - CTR_DRBG_Update(seedMaterial, _Key, _V); + CTR_DRBG_Update(seedMaterial, mKey, mV); - _reseedCounter = 1; + mReseedCounter = 1; } - private void XOR(byte[] output, byte[] a, byte[] b, int bOff) + private void XOR(byte[] output, byte[] a, byte[] b, int bOff) { - for (int i=0; i< output.Length; i++) + for (int i = 0; i < output.Length; i++) { - output[i] = (byte)(a[i] ^ b[i+bOff]); + output[i] = (byte)(a[i] ^ b[bOff + i]); } } - - private void addOneTo(byte[] longer) + + private void AddOneTo(byte[] longer) { - int carry = 1; - for (int i = 1; i <= longer.Length; i++) // warning - { - int res = (longer[longer.Length - i] & 0xff) + carry; - carry = (res > 0xff) ? 1 : 0; - longer[longer.Length - i] = (byte)res; - } + uint carry = 1; + int i = longer.Length; + while (--i >= 0) + { + carry += longer[i]; + longer[i] = (byte)carry; + carry >>= 8; + } } - private byte[] getEntropy() + private byte[] GetEntropy() { - byte[] entropy = _entropySource.getEntropy(); - if (entropy.Length < (_securityStrength + 7) / 8) - { - throw new IllegalStateException("Insufficient entropy provided by entropy source"); - } + byte[] entropy = mEntropySource.GetEntropy(); + if (entropy.Length < (mSecurityStrength + 7) / 8) + throw new InvalidOperationException("Insufficient entropy provided by entropy source"); return entropy; } // -- Internal state migration --- - - private static final byte[] K_BITS = Hex.decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"); - // 1. If (number_of_bits_to_return > max_number_of_bits), then return an + private static readonly byte[] K_BITS = Hex.Decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"); + + // 1. If (number_of_bits_to_return > max_number_of_bits), then return an // ERROR_FLAG. // 2. L = len (input_string)/8. // 3. N = number_of_bits_to_return/8. @@ -219,7 +212,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg // 15. Return SUCCESS and requested_bits. private byte[] Block_Cipher_df(byte[] inputString, int bitLength) { - int outLen = _engine.getBlockSize(); + int outLen = mEngine.GetBlockSize(); int L = inputString.Length; // already in bytes int N = bitLength / 8; // 4 S = L || N || inputstring || 0x80 @@ -232,16 +225,16 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg S[8 + L] = (byte)0x80; // S already padded with zeros - byte[] temp = new byte[_keySizeInBits / 8 + outLen]; + byte[] temp = new byte[mKeySizeInBits / 8 + outLen]; byte[] bccOut = new byte[outLen]; byte[] IV = new byte[outLen]; int i = 0; - byte[] K = new byte[_keySizeInBits / 8]; + byte[] K = new byte[mKeySizeInBits / 8]; Array.Copy(K_BITS, 0, K, 0, K.Length); - while (i*outLen*8 < _keySizeInBits + outLen *8) + while (i*outLen*8 < mKeySizeInBits + outLen *8) { copyIntToByteArray(IV, i, 0); BCC(bccOut, K, IV, S); @@ -261,11 +254,11 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg temp = new byte[bitLength / 2]; i = 0; - _engine.init(true, new KeyParameter(expandKey(K))); + mEngine.Init(true, new KeyParameter(ExpandKey(K))); while (i * outLen < temp.Length) { - _engine.processBlock(X, 0, X, 0); + mEngine.ProcessBlock(X, 0, X, 0); int bytesToCopy = ((temp.Length - i * outLen) > outLen) ? outLen @@ -292,23 +285,23 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg */ private void BCC(byte[] bccOut, byte[] k, byte[] iV, byte[] data) { - int outlen = _engine.getBlockSize(); + int outlen = mEngine.GetBlockSize(); byte[] chainingValue = new byte[outlen]; // initial values = 0 int n = data.Length / outlen; byte[] inputBlock = new byte[outlen]; - _engine.init(true, new KeyParameter(expandKey(k))); + mEngine.Init(true, new KeyParameter(ExpandKey(k))); - _engine.processBlock(iV, 0, chainingValue, 0); + mEngine.ProcessBlock(iV, 0, chainingValue, 0); - for (int i = 0; i < n; i++) + for (int i = 0; i < n; i++) { XOR(inputBlock, chainingValue, data, i*outlen); - _engine.processBlock(inputBlock, 0, chainingValue, 0); + mEngine.ProcessBlock(inputBlock, 0, chainingValue, 0); } - Array.Copy(chainingValue, 0, bccOut, 0, bccOut.Length); + Array.Copy(chainingValue, 0, bccOut, 0, bccOut.Length); } private void copyIntToByteArray(byte[] buf, int value, int offSet) @@ -326,9 +319,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg */ public int BlockSize { - get { - return _V.Length * 8; - } + get { return mV.Length * 8; } } /** @@ -342,32 +333,24 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg */ public int Generate(byte[] output, byte[] additionalInput, bool predictionResistant) { - if (_isTDEA) + if (mIsTdea) { - if (_reseedCounter > TDEA_RESEED_MAX) - { + if (mReseedCounter > TDEA_RESEED_MAX) return -1; - } - if (Utils.isTooLarge(output, TDEA_MAX_BITS_REQUEST / 8)) - { - throw new ArgumentException("Number of bits per request limited to " + TDEA_MAX_BITS_REQUEST); - } + if (DrbgUtilities.IsTooLarge(output, TDEA_MAX_BITS_REQUEST / 8)) + throw new ArgumentException("Number of bits per request limited to " + TDEA_MAX_BITS_REQUEST, "output"); } else { - if (_reseedCounter > AES_RESEED_MAX) - { + if (mReseedCounter > AES_RESEED_MAX) return -1; - } - if (Utils.isTooLarge(output, AES_MAX_BITS_REQUEST / 8)) - { - throw new ArgumentException("Number of bits per request limited to " + AES_MAX_BITS_REQUEST); - } + if (DrbgUtilities.IsTooLarge(output, AES_MAX_BITS_REQUEST / 8)) + throw new ArgumentException("Number of bits per request limited to " + AES_MAX_BITS_REQUEST, "output"); } - if (predictionResistant) + if (predictionResistant) { CTR_DRBG_Reseed_algorithm(additionalInput); additionalInput = null; @@ -375,39 +358,39 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg if (additionalInput != null) { - additionalInput = Block_Cipher_df(additionalInput, _seedLength); - CTR_DRBG_Update(additionalInput, _Key, _V); + additionalInput = Block_Cipher_df(additionalInput, mSeedLength); + CTR_DRBG_Update(additionalInput, mKey, mV); } else { - additionalInput = new byte[_seedLength]; + additionalInput = new byte[mSeedLength]; } - byte[] tmp = new byte[_V.Length]; + byte[] tmp = new byte[mV.Length]; - _engine.init(true, new KeyParameter(expandKey(_Key))); + mEngine.Init(true, new KeyParameter(ExpandKey(mKey))); - for (int i = 0; i <= output.Length / tmp.Length; i++) + for (int i = 0; i <= output.Length / tmp.Length; i++) { - int bytesToCopy = ((output.Length - i * tmp.Length) > tmp.Length) - ? tmp.Length - : (output.Length - i * _V.Length); + int bytesToCopy = ((output.Length - i * tmp.Length) > tmp.Length) + ? tmp.Length + : (output.Length - i * mV.Length); - if (bytesToCopy != 0) + if (bytesToCopy != 0) { - addOneTo(_V); + AddOneTo(mV); - _engine.processBlock(_V, 0, tmp, 0); + mEngine.ProcessBlock(mV, 0, tmp, 0); - Array.Copy(tmp, 0, output, i * tmp.Length, bytesToCopy); + Array.Copy(tmp, 0, output, i * tmp.Length, bytesToCopy); } } - CTR_DRBG_Update(additionalInput, _Key, _V); + CTR_DRBG_Update(additionalInput, mKey, mV); - _reseedCounter++; + mReseedCounter++; - return output.Length * 8; + return output.Length * 8; } /** @@ -420,14 +403,14 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg CTR_DRBG_Reseed_algorithm(additionalInput); } - private boolean isTDEA(BlockCipher cipher) + private bool IsTdea(IBlockCipher cipher) { return cipher.AlgorithmName.Equals("DESede") || cipher.AlgorithmName.Equals("TDEA"); } - private int getMaxSecurityStrength(BlockCipher cipher, int keySizeInBits) + private int GetMaxSecurityStrength(IBlockCipher cipher, int keySizeInBits) { - if (isTDEA(cipher) && keySizeInBits == 168) + if (IsTdea(cipher) && keySizeInBits == 168) { return 112; } @@ -436,19 +419,19 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg return keySizeInBits; } - return -1; + return -1; } - byte[] expandKey(byte[] key) + private byte[] ExpandKey(byte[] key) { - if (_isTDEA) + if (mIsTdea) { // expand key to 192 bits. byte[] tmp = new byte[24]; - padKey(key, 0, tmp, 0); - padKey(key, 7, tmp, 8); - padKey(key, 14, tmp, 16); + PadKey(key, 0, tmp, 0); + PadKey(key, 7, tmp, 8); + PadKey(key, 14, tmp, 16); return tmp; } @@ -466,7 +449,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg * @param tmp * @param tmpOff */ - private void padKey(byte[] keyMaster, int keyOff, byte[] tmp, int tmpOff) + private void PadKey(byte[] keyMaster, int keyOff, byte[] tmp, int tmpOff) { tmp[tmpOff + 0] = (byte)(keyMaster[keyOff + 0] & 0xfe); tmp[tmpOff + 1] = (byte)((keyMaster[keyOff + 0] << 7) | ((keyMaster[keyOff + 1] & 0xfc) >> 1)); @@ -479,15 +462,15 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg for (int i = tmpOff; i <= tmpOff + 7; i++) { - int b = tmp[i]; - tmp[i] = (byte)((b & 0xfe) | - ((((b >> 1) ^ - (b >> 2) ^ - (b >> 3) ^ - (b >> 4) ^ - (b >> 5) ^ - (b >> 6) ^ - (b >> 7)) ^ 0x01) & 0x01)); + uint b = tmp[i]; + + uint parity = b ^ 1U; + parity ^= (parity >> 4); + parity ^= (parity >> 2); + parity ^= (parity >> 1); + parity &= 1U; + + tmp[i] = (byte)(b ^ parity); } } } diff --git a/crypto/src/crypto/prng/drbg/DrbgUtilities.cs b/crypto/src/crypto/prng/drbg/DrbgUtilities.cs index b5f3b5830..d9a1c439c 100644 --- a/crypto/src/crypto/prng/drbg/DrbgUtilities.cs +++ b/crypto/src/crypto/prng/drbg/DrbgUtilities.cs @@ -5,39 +5,39 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Prng.Drbg { - internal class Utils + internal class DrbgUtilities { private static readonly IDictionary maxSecurityStrengths = Platform.CreateHashtable(); - static Utils() + static DrbgUtilities() { - maxSecurityStrengths.put("SHA-1", 128); + maxSecurityStrengths.Add("SHA-1", 128); - maxSecurityStrengths.put("SHA-224", 192); - maxSecurityStrengths.put("SHA-256", 256); - maxSecurityStrengths.put("SHA-384", 256); - maxSecurityStrengths.put("SHA-512", 256); + maxSecurityStrengths.Add("SHA-224", 192); + maxSecurityStrengths.Add("SHA-256", 256); + maxSecurityStrengths.Add("SHA-384", 256); + maxSecurityStrengths.Add("SHA-512", 256); - maxSecurityStrengths.put("SHA-512/224", 192); - maxSecurityStrengths.put("SHA-512/256", 256); + maxSecurityStrengths.Add("SHA-512/224", 192); + maxSecurityStrengths.Add("SHA-512/256", 256); } - internal static int getMaxSecurityStrength(IDigest d) + internal static int GetMaxSecurityStrength(IDigest d) { return (int)maxSecurityStrengths[d.AlgorithmName]; } - internal static int getMaxSecurityStrength(IMac m) + internal static int GetMaxSecurityStrength(IMac m) { - String name = m.getAlgorithmName(); + string name = m.AlgorithmName; - return (int)maxSecurityStrengths[name.substring(0, name.indexOf("/"))]; + return (int)maxSecurityStrengths[name.Substring(0, name.IndexOf("/"))]; } /** * Used by both Dual EC and Hash. */ - internal static byte[] hash_df(Digest digest, byte[] seedMaterial, int seedLength) + internal static byte[] HashDF(IDigest digest, byte[] seedMaterial, int seedLength) { // 1. temp = the Null string. // 2. . @@ -52,10 +52,10 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg // 6. Return SUCCESS and requested_bits. byte[] temp = new byte[(seedLength + 7) / 8]; - int len = temp.Length / digest.getDigestSize(); + int len = temp.Length / digest.GetDigestSize(); int counter = 1; - byte[] dig = new byte[digest.getDigestSize()]; + byte[] dig = new byte[digest.GetDigestSize()]; for (int i = 0; i <= len; i++) { @@ -82,20 +82,20 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg if (seedLength % 8 != 0) { int shift = 8 - (seedLength % 8); - int carry = 0; + uint carry = 0; - for (int i = 0; i != temp.Length; i++) + for (int i = 0; i != temp.Length; i++) { - uint b = temp[i] & 0xff; + uint b = temp[i]; temp[i] = (byte)((b >> shift) | (carry << (8 - shift))); carry = b; } } - return temp; + return temp; } - internal static boolean isTooLarge(byte[] bytes, int maxBytes) + internal static bool IsTooLarge(byte[] bytes, int maxBytes) { return bytes != null && bytes.Length > maxBytes; } diff --git a/crypto/src/crypto/prng/drbg/HMacSP800Drbg.cs b/crypto/src/crypto/prng/drbg/HMacSP800Drbg.cs index 78a710097..78331705e 100644 --- a/crypto/src/crypto/prng/drbg/HMacSP800Drbg.cs +++ b/crypto/src/crypto/prng/drbg/HMacSP800Drbg.cs @@ -8,19 +8,21 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg /** * A SP800-90A HMAC DRBG. */ - public class HMacSP800Drbg: SP80090Drbg + public class HMacSP800Drbg + : ISP80090Drbg { - private readonly static long RESEED_MAX = 1L << (48 - 1); - private readonly static int MAX_BITS_REQUEST = 1 << (19 - 1); + private readonly static long RESEED_MAX = 1L << (48 - 1); + private readonly static int MAX_BITS_REQUEST = 1 << (19 - 1); - private byte[] _K; - private byte[] _V; - private long _reseedCounter; - private EntropySource _entropySource; - private Mac _hMac; - private int _securityStrength; + private readonly byte[] mK; + private readonly byte[] mV; + private readonly IEntropySource mEntropySource; + private readonly IMac mHMac; + private readonly int mSecurityStrength; - /** + private long mReseedCounter; + + /** * Construct a SP800-90A Hash DRBG. * <p> * Minimum entropy requirement is the security strength requested. @@ -33,33 +35,28 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg */ public HMacSP800Drbg(IMac hMac, int securityStrength, IEntropySource entropySource, byte[] personalizationString, byte[] nonce) { - if (securityStrength > Utils.getMaxSecurityStrength(hMac)) - { + if (securityStrength > DrbgUtilities.GetMaxSecurityStrength(hMac)) throw new ArgumentException("Requested security strength is not supported by the derivation function"); - } - if (entropySource.EntropySize < securityStrength) - { throw new ArgumentException("Not enough entropy for security strength required"); - } - _securityStrength = securityStrength; - _entropySource = entropySource; - _hMac = hMac; + mHMac = hMac; + mSecurityStrength = securityStrength; + mEntropySource = entropySource; - byte[] entropy = getEntropy(); - byte[] seedMaterial = Arrays.Concatenate(entropy, nonce, personalizationString); + byte[] entropy = GetEntropy(); + byte[] seedMaterial = Arrays.ConcatenateAll(entropy, nonce, personalizationString); - _K = new byte[hMac.GetMacSize()]; - _V = new byte[_K.Length]; - Arrays.fill(_V, (byte)1); + mK = new byte[hMac.GetMacSize()]; + mV = new byte[mK.Length]; + Arrays.Fill(mV, (byte)1); - hmac_DRBG_Update(seedMaterial); + hmac_DRBG_Update(seedMaterial); - _reseedCounter = 1; + mReseedCounter = 1; } - private void hmac_DRBG_Update(byte[] seedMaterial) + private void hmac_DRBG_Update(byte[] seedMaterial) { hmac_DRBG_Update_Func(seedMaterial, (byte)0x00); if (seedMaterial != null) @@ -70,22 +67,22 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg private void hmac_DRBG_Update_Func(byte[] seedMaterial, byte vValue) { - _hMac.Init(new KeyParameter(_K)); + mHMac.Init(new KeyParameter(mK)); - _hMac.BlockUpdate(_V, 0, _V.Length); - _hMac.Update(vValue); + mHMac.BlockUpdate(mV, 0, mV.Length); + mHMac.Update(vValue); if (seedMaterial != null) { - _hMac.update(seedMaterial, 0, seedMaterial.Length); + mHMac.BlockUpdate(seedMaterial, 0, seedMaterial.Length); } - _hMac.DoFinal(_K, 0); + mHMac.DoFinal(mK, 0); - _hMac.Init(new KeyParameter(_K)); - _hMac.BlockUpdate(_V, 0, _V.Length); + mHMac.Init(new KeyParameter(mK)); + mHMac.BlockUpdate(mV, 0, mV.Length); - _hMac.DoFinal(_V, 0); + mHMac.DoFinal(mV, 0); } /** @@ -95,9 +92,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg */ public int BlockSize { - get { - return _V.Length * 8; - } + get { return mV.Length * 8; } } /** @@ -109,23 +104,21 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg * * @return number of bits generated, -1 if a reseed required. */ - public int Generate(byte[] output, byte[] additionalInput, boolean predictionResistant) + public int Generate(byte[] output, byte[] additionalInput, bool predictionResistant) { int numberOfBits = output.Length * 8; - if (numberOfBits > MAX_BITS_REQUEST) - { - throw new IllegalArgumentException("Number of bits per request limited to " + MAX_BITS_REQUEST); - } + if (numberOfBits > MAX_BITS_REQUEST) + throw new ArgumentException("Number of bits per request limited to " + MAX_BITS_REQUEST, "output"); - if (_reseedCounter > RESEED_MAX) + if (mReseedCounter > RESEED_MAX) { return -1; } - if (predictionResistant) + if (predictionResistant) { - reseed(additionalInput); + Reseed(additionalInput); additionalInput = null; } @@ -135,36 +128,36 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg hmac_DRBG_Update(additionalInput); } - // 3. + // 3. byte[] rv = new byte[output.Length]; - int m = output.Length / _V.Length; + int m = output.Length / mV.Length; - _hMac.Init(new KeyParameter(_K)); + mHMac.Init(new KeyParameter(mK)); for (int i = 0; i < m; i++) { - _hMac.BlockUpdate(_V, 0, _V.Length); - _hMac.DoFinal(_V, 0); + mHMac.BlockUpdate(mV, 0, mV.Length); + mHMac.DoFinal(mV, 0); - Array.Copy(_V, 0, rv, i * _V.Length, _V.Length); + Array.Copy(mV, 0, rv, i * mV.Length, mV.Length); } - if (m * _V.Length < rv.Length) + if (m * mV.Length < rv.Length) { - _hMac.BlockUpdate(_V, 0, _V.Length); - _hMac.DoFinal(_V, 0); + mHMac.BlockUpdate(mV, 0, mV.Length); + mHMac.DoFinal(mV, 0); - Array.Copy(_V, 0, rv, m * _V.Length, rv.Length - (m * _V.Length)); + Array.Copy(mV, 0, rv, m * mV.Length, rv.Length - (m * mV.Length)); } - hmac_DRBG_Update(additionalInput); + hmac_DRBG_Update(additionalInput); - _reseedCounter++; + mReseedCounter++; Array.Copy(rv, 0, output, 0, output.Length); - return numberOfBits; + return numberOfBits; } /** @@ -174,22 +167,19 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg */ public void Reseed(byte[] additionalInput) { - byte[] entropy = getEntropy(); + byte[] entropy = GetEntropy(); byte[] seedMaterial = Arrays.Concatenate(entropy, additionalInput); hmac_DRBG_Update(seedMaterial); - _reseedCounter = 1; + mReseedCounter = 1; } - private byte[] getEntropy() + private byte[] GetEntropy() { - byte[] entropy = _entropySource.GetEntropy(); - - if (entropy.Length < (_securityStrength + 7) / 8) - { - throw new IllegalStateException("Insufficient entropy provided by entropy source"); - } + byte[] entropy = mEntropySource.GetEntropy(); + if (entropy.Length < (mSecurityStrength + 7) / 8) + throw new InvalidOperationException("Insufficient entropy provided by entropy source"); return entropy; } } diff --git a/crypto/src/crypto/prng/drbg/HashSP800Drbg.cs b/crypto/src/crypto/prng/drbg/HashSP800Drbg.cs index 868778817..493da5a75 100644 --- a/crypto/src/crypto/prng/drbg/HashSP800Drbg.cs +++ b/crypto/src/crypto/prng/drbg/HashSP800Drbg.cs @@ -8,36 +8,37 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg /** * A SP800-90A Hash DRBG. */ - public class HashSP800Drbg: SP80090Drbg + public class HashSP800Drbg + : ISP80090Drbg { - private readonly static byte[] ONE = { 0x01 }; + private readonly static byte[] ONE = { 0x01 }; - private readonly static long RESEED_MAX = 1L << (48 - 1); - private readonly static int MAX_BITS_REQUEST = 1 << (19 - 1); + private readonly static long RESEED_MAX = 1L << (48 - 1); + private readonly static int MAX_BITS_REQUEST = 1 << (19 - 1); private static readonly IDictionary seedlens = Platform.CreateHashtable(); static HashSP800Drbg() { - seedlens.Add("SHA-1", 440); - seedlens.Add("SHA-224", 440); - seedlens.Add("SHA-256", 440); - seedlens.Add("SHA-512/256", 440); - seedlens.Add("SHA-512/224", 440); - seedlens.Add("SHA-384", 888); - seedlens.Add("SHA-512", 888); - + seedlens.Add("SHA-1", 440); + seedlens.Add("SHA-224", 440); + seedlens.Add("SHA-256", 440); + seedlens.Add("SHA-512/256", 440); + seedlens.Add("SHA-512/224", 440); + seedlens.Add("SHA-384", 888); + seedlens.Add("SHA-512", 888); } - private IDigest _digest; - private byte[] _V; - private byte[] _C; - private long _reseedCounter; - private IEntropySource _entropySource; - private int _securityStrength; - private int _seedLength; + private readonly IDigest mDigest; + private readonly IEntropySource mEntropySource; + private readonly int mSecurityStrength; + private readonly int mSeedLength; - /** + private byte[] mV; + private byte[] mC; + private long mReseedCounter; + + /** * Construct a SP800-90A Hash DRBG. * <p> * Minimum entropy requirement is the security strength requested. @@ -50,22 +51,17 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg */ public HashSP800Drbg(IDigest digest, int securityStrength, IEntropySource entropySource, byte[] personalizationString, byte[] nonce) { - if (securityStrength > Utils.getMaxSecurityStrength(digest)) - { + if (securityStrength > DrbgUtilities.GetMaxSecurityStrength(digest)) throw new ArgumentException("Requested security strength is not supported by the derivation function"); - } - if (entropySource.EntropySize < securityStrength) - { throw new ArgumentException("Not enough entropy for security strength required"); - } - _digest = digest; - _entropySource = entropySource; - _securityStrength = securityStrength; - _seedLength = ((Integer)seedlens.get(digest.getAlgorithmName())).intValue(); + mDigest = digest; + mEntropySource = entropySource; + mSecurityStrength = securityStrength; + mSeedLength = (int)seedlens[digest.AlgorithmName]; - // 1. seed_material = entropy_input || nonce || personalization_string. + // 1. seed_material = entropy_input || nonce || personalization_string. // 2. seed = Hash_df (seed_material, seedlen). // 3. V = seed. // 4. C = Hash_df ((0x00 || V), seedlen). Comment: Preceed V with a byte @@ -73,16 +69,16 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg // 5. reseed_counter = 1. // 6. Return V, C, and reseed_counter as the initial_working_state - byte[] entropy = getEntropy(); - byte[] seedMaterial = Arrays.Concatenate(entropy, nonce, personalizationString); - byte[] seed = Utils.hash_df(_digest, seedMaterial, _seedLength); + byte[] entropy = GetEntropy(); + byte[] seedMaterial = Arrays.ConcatenateAll(entropy, nonce, personalizationString); + byte[] seed = DrbgUtilities.HashDF(mDigest, seedMaterial, mSeedLength); - _V = seed; - byte[] subV = new byte[_V.Length + 1]; - Array.Copy(_V, 0, subV, 1, _V.Length); - _C = Utils.hash_df(_digest, subV, _seedLength); + mV = seed; + byte[] subV = new byte[mV.Length + 1]; + Array.Copy(mV, 0, subV, 1, mV.Length); + mC = DrbgUtilities.HashDF(mDigest, subV, mSeedLength); - _reseedCounter = 1; + mReseedCounter = 1; } /** @@ -92,9 +88,7 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg */ public int BlockSize { - get { - return _digest.GetDigestSize () * 8; - } + get { return mDigest.GetDigestSize () * 8; } } /** @@ -121,97 +115,95 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg // 6. reseed_counter = reseed_counter + 1. // 7. Return SUCCESS, returned_bits, and the new values of V, C, and // reseed_counter for the new_working_state. - int numberOfBits = output.Length*8; + int numberOfBits = output.Length * 8; if (numberOfBits > MAX_BITS_REQUEST) - { - throw new ArgumentException("Number of bits per request limited to " + MAX_BITS_REQUEST); - } + throw new ArgumentException("Number of bits per request limited to " + MAX_BITS_REQUEST, "output"); - if (_reseedCounter > RESEED_MAX) - { + if (mReseedCounter > RESEED_MAX) return -1; - } - if (predictionResistant) + if (predictionResistant) { - reseed(additionalInput); + Reseed(additionalInput); additionalInput = null; } // 2. if (additionalInput != null) { - byte[] newInput = new byte[1 + _V.Length + additionalInput.Length]; + byte[] newInput = new byte[1 + mV.Length + additionalInput.Length]; newInput[0] = 0x02; - Array.Copy(_V, 0, newInput, 1, _V.Length); + Array.Copy(mV, 0, newInput, 1, mV.Length); // TODO: inOff / inLength - Array.Copy(additionalInput, 0, newInput, 1 + _V.Length, additionalInput.Length); - byte[] w = hash(newInput); + Array.Copy(additionalInput, 0, newInput, 1 + mV.Length, additionalInput.Length); + byte[] w = Hash(newInput); - addTo(_V, w); + AddTo(mV, w); } - - // 3. - byte[] rv = hashgen(_V, numberOfBits); - - // 4. - byte[] subH = new byte[_V.Length + 1]; - Array.Copy(_V, 0, subH, 1, _V.Length); + + // 3. + byte[] rv = hashgen(mV, numberOfBits); + + // 4. + byte[] subH = new byte[mV.Length + 1]; + Array.Copy(mV, 0, subH, 1, mV.Length); subH[0] = 0x03; - - byte[] H = hash(subH); - - // 5. - addTo(_V, H); - addTo(_V, _C); + + byte[] H = Hash(subH); + + // 5. + AddTo(mV, H); + AddTo(mV, mC); byte[] c = new byte[4]; - c[0] = (byte)(_reseedCounter >> 24); - c[1] = (byte)(_reseedCounter >> 16); - c[2] = (byte)(_reseedCounter >> 8); - c[3] = (byte)_reseedCounter; - - addTo(_V, c); + c[0] = (byte)(mReseedCounter >> 24); + c[1] = (byte)(mReseedCounter >> 16); + c[2] = (byte)(mReseedCounter >> 8); + c[3] = (byte)mReseedCounter; + + AddTo(mV, c); - _reseedCounter++; + mReseedCounter++; Array.Copy(rv, 0, output, 0, output.Length); return numberOfBits; } - private byte[] getEntropy() + private byte[] GetEntropy() { - byte[] entropy = _entropySource.getEntropy(); - if (entropy.Length < (_securityStrength + 7) / 8) - { - throw new IllegalStateException("Insufficient entropy provided by entropy source"); - } + byte[] entropy = mEntropySource.GetEntropy(); + if (entropy.Length < (mSecurityStrength + 7) / 8) + throw new InvalidOperationException("Insufficient entropy provided by entropy source"); return entropy; } // this will always add the shorter length byte array mathematically to the // longer length byte array. // be careful.... - private void addTo(byte[] longer, byte[] shorter) + private void AddTo(byte[] longer, byte[] shorter) { - int carry = 0; - for (int i=1;i <= shorter.Length; i++) // warning - { - int res = (longer[longer.Length-i] & 0xff) + (shorter[shorter.Length-i] & 0xff) + carry; - carry = (res > 0xff) ? 1 : 0; - longer[longer.Length-i] = (byte)res; - } - - for (int i=shorter.Length+1;i <= longer.Length; i++) // warning - { - int res = (longer[longer.Length-i] & 0xff) + carry; - carry = (res > 0xff) ? 1 : 0; - longer[longer.Length-i] = (byte)res; - } + int off = longer.Length - shorter.Length; + + uint carry = 0; + int i = shorter.Length; + while (--i >= 0) + { + carry += (uint)longer[off + i] + (uint)shorter[i]; + longer[off + i] = (byte)carry; + carry >>= 8; + } + + i = off; + while (--i >= 0) + { + carry += longer[i]; + longer[i] = (byte)carry; + carry >>= 8; + } } - /** + /** * Reseed the DRBG. * * @param additionalInput additional input to be added to the DRBG in this step. @@ -231,33 +223,33 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg // 6. Return V, C, and reseed_counter for the new_working_state. // // Comment: Precede with a byte of all zeros. - byte[] entropy = getEntropy(); - byte[] seedMaterial = Arrays.Concatenate(ONE, _V, entropy, additionalInput); - byte[] seed = Utils.hash_df(_digest, seedMaterial, _seedLength); + byte[] entropy = GetEntropy(); + byte[] seedMaterial = Arrays.ConcatenateAll(ONE, mV, entropy, additionalInput); + byte[] seed = DrbgUtilities.HashDF(mDigest, seedMaterial, mSeedLength); - _V = seed; - byte[] subV = new byte[_V.Length + 1]; + mV = seed; + byte[] subV = new byte[mV.Length + 1]; subV[0] = 0x00; - Array.Copy(_V, 0, subV, 1, _V.Length); - _C = Utils.hash_df(_digest, subV, _seedLength); + Array.Copy(mV, 0, subV, 1, mV.Length); + mC = DrbgUtilities.HashDF(mDigest, subV, mSeedLength); - _reseedCounter = 1; - } - - private byte[] hash(byte[] input) - { - byte[] hash = new byte[_digest.GetDigestSize()]; - doHash(input, hash); - return hash; + mReseedCounter = 1; } - private void doHash(byte[] input, byte[] output) - { - _digest.BlockUpdate(input, 0, input.Length); - _digest.DoFinal(output, 0); - } + private byte[] Hash(byte[] input) + { + byte[] hash = new byte[mDigest.GetDigestSize()]; + DoHash(input, hash); + return hash; + } + + private void DoHash(byte[] input, byte[] output) + { + mDigest.BlockUpdate(input, 0, input.Length); + mDigest.DoFinal(output, 0); + } - // 1. m = [requested_number_of_bits / outlen] + // 1. m = [requested_number_of_bits / outlen] // 2. data = V. // 3. W = the Null string. // 4. For i = 1 to m @@ -268,25 +260,25 @@ namespace Org.BouncyCastle.Crypto.Prng.Drbg // 5. returned_bits = Leftmost (requested_no_of_bits) bits of W. private byte[] hashgen(byte[] input, int lengthInBits) { - int digestSize = _digest.GetDigestSize(); + int digestSize = mDigest.GetDigestSize(); int m = (lengthInBits / 8) / digestSize; - byte[] data = new byte[input.Length]; + byte[] data = new byte[input.Length]; Array.Copy(input, 0, data, 0, input.Length); byte[] W = new byte[lengthInBits / 8]; - byte[] dig = new byte[_digest.GetDigestSize()]; + byte[] dig = new byte[mDigest.GetDigestSize()]; for (int i = 0; i <= m; i++) { - doHash(data, dig); + DoHash(data, dig); int bytesToCopy = ((W.Length - i * dig.Length) > dig.Length) ? dig.Length : (W.Length - i * dig.Length); Array.Copy(dig, 0, W, i * dig.Length, bytesToCopy); - addTo(data, ONE); + AddTo(data, ONE); } return W; diff --git a/crypto/src/crypto/prng/drbg/ISP80090Drbg.cs b/crypto/src/crypto/prng/drbg/ISP80090Drbg.cs index c39cf365f..0e398209e 100644 --- a/crypto/src/crypto/prng/drbg/ISP80090Drbg.cs +++ b/crypto/src/crypto/prng/drbg/ISP80090Drbg.cs @@ -1,9 +1,11 @@ +using System; + namespace Org.BouncyCastle.Crypto.Prng.Drbg { /** * Interface to SP800-90A deterministic random bit generators. */ - public interface SP80090Drbg + public interface ISP80090Drbg { /** * Return the block size of the DRBG. diff --git a/crypto/src/security/SecureRandom.cs b/crypto/src/security/SecureRandom.cs index 4894a93e6..875709e57 100644 --- a/crypto/src/security/SecureRandom.cs +++ b/crypto/src/security/SecureRandom.cs @@ -164,13 +164,7 @@ namespace Org.BouncyCastle.Security public override int Next() { - for (;;) - { - int i = NextInt() & int.MaxValue; - - if (i != int.MaxValue) - return i; - } + return NextInt() & int.MaxValue; } public override int Next(int maxValue) @@ -184,11 +178,9 @@ namespace Org.BouncyCastle.Security } // Test whether maxValue is a power of 2 - if ((maxValue & -maxValue) == maxValue) + if ((maxValue & (maxValue - 1)) == 0) { - int val = NextInt() & int.MaxValue; - long lr = ((long) maxValue * (long) val) >> 31; - return (int) lr; + return NextInt() & (maxValue - 1); } int bits, result; @@ -244,16 +236,17 @@ namespace Org.BouncyCastle.Security public virtual int NextInt() { - byte[] intBytes = new byte[4]; - NextBytes(intBytes); - - int result = 0; - for (int i = 0; i < 4; i++) - { - result = (result << 8) + (intBytes[i] & 0xff); - } - - return result; + byte[] bytes = new byte[4]; + NextBytes(bytes); + + uint result = bytes[0]; + result <<= 8; + result |= bytes[1]; + result <<= 8; + result |= bytes[2]; + result <<= 8; + result |= bytes[3]; + return (int)result; } public virtual long NextLong() diff --git a/crypto/src/util/Arrays.cs b/crypto/src/util/Arrays.cs index 32c56b8b5..df9b4e7ee 100644 --- a/crypto/src/util/Arrays.cs +++ b/crypto/src/util/Arrays.cs @@ -591,57 +591,33 @@ namespace Org.BouncyCastle.Utilities return rv; } - public static byte[] Concatenate(byte[] a, byte[] b, byte[] c) + public static byte[] ConcatenateAll(params byte[][] vs) { - if (a != null && b != null && c != null) - { - byte[] rv = new byte[a.Length + b.Length + c.Length]; - - Array.Copy(a, 0, rv, 0, a.Length); - Array.Copy(b, 0, rv, a.Length, b.Length); - Array.Copy(c, 0, rv, a.Length + b.Length, c.Length); + byte[][] nonNull = new byte[vs.Length][]; + int count = 0; + int totalLength = 0; - return rv; - } - else if (b == null) - { - return Concatenate(a, c); - } - else + for (int i = 0; i < vs.Length; ++i) + { + byte[] v = vs[i]; + if (v != null) { - return Concatenate(a, b); + nonNull[count++] = v; + totalLength += v.Length; } - } + } - public static byte[] Concatenate(byte[] a, byte[] b, byte[] c, byte[] d) - { - if (a != null && b != null && c != null && d != null) - { - byte[] rv = new byte[a.Length + b.Length + c.Length + d.Length]; + byte[] result = new byte[totalLength]; + int pos = 0; - Array.Copy(a, 0, rv, 0, a.Length); - Array.Copy(b, 0, rv, a.Length, b.Length); - Array.Copy(c, 0, rv, a.Length + b.Length, c.Length); - Array.Copy(d, 0, rv, a.Length + b.Length + c.Length, d.Length); + for (int j = 0; j < count; ++j) + { + byte[] v = nonNull[j]; + Array.Copy(v, 0, result, pos, v.Length); + pos += v.Length; + } - return rv; - } - else if (d == null) - { - return Concatenate(a, b, c); - } - else if (c == null) - { - return Concatenate(a, b, d); - } - else if (b == null) - { - return Concatenate(a, c, d); - } - else - { - return Concatenate(b, c, d); - } + return result; } public static int[] Concatenate(int[] a, int[] b) diff --git a/crypto/test/src/crypto/prng/test/CtrDrbgTest.cs b/crypto/test/src/crypto/prng/test/CtrDrbgTest.cs index e081ec132..44b08f3a6 100644 --- a/crypto/test/src/crypto/prng/test/CtrDrbgTest.cs +++ b/crypto/test/src/crypto/prng/test/CtrDrbgTest.cs @@ -1,10 +1,11 @@ using System; +using NUnit.Framework; + using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.Crypto.Prng.Drbg; using Org.BouncyCastle.Utilities.Test; using Org.BouncyCastle.Utilities.Encoders; -using NUnit.Framework; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Crypto.Parameters; @@ -14,356 +15,365 @@ namespace Org.BouncyCastle.Crypto.Prng.Test * CTR DRBG Test */ [TestFixture] - public class CtrDrbgTest : SimpleTest + public class CtrDrbgTest + : SimpleTest { - public override String Name { - get { - return "CTRDRBGTest"; - } + public override string Name + { + get { return "CTRDRBGTest"; } } - public static void main(String[] args) + public static void Main(string[] args) { RunTest(new CtrDrbgTest()); } - private DRBGTestVector[] createTestVectorData() + [Test] + public void TestFunction() { - return new DRBGTestVector[] - { - new DRBGTestVector( - new DesEdeEngine(), 168, - new Bit232EntropyProvider().Get(232), - false, - "20212223242526", - 112, - new String[] - { - "ABC88224514D0316EA3D48AEE3C9A2B4", - "D3D3F372E43E7ABDC4FA293743EED076" - } - ), - new DRBGTestVector( - new DesEdeEngine(), 168, - new Bit232EntropyProvider().Get(232), - false, - "20212223242526", - 112, - new String[] - { - "D4564EE072ACA5BD279536E14F94CB12", - "1CCD9AFEF15A9679BA75E35225585DEA" - } - ) - .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C") - .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBC"), - new DRBGTestVector( - new DesEdeEngine(), 168, - new Bit232EntropyProvider().Get(232), - false, - "20212223242526", - 112, - new String[] - { - "760BED7D92B083B10AF31CF0656081EB", - "FD1AC41482384D823CF3FD6F0E6C88B3" - } - ) - .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C"), - new DRBGTestVector( - new DesEdeEngine(), 168, - new Bit232EntropyProvider().Get(232), - false, - "20212223242526", - 112, - new String[] - { - "7A4C1D7ADC8A67FDB50100ED23583A2C", - "43044D311C0E07541CA5C8B0916976B2" - } - ) - .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C") - .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C") - .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBC"), - new DRBGTestVector( - new DesEdeEngine(), 168, - new Bit232EntropyProvider().Get(232), - true, - "20212223242526", - 112, - new String[] - { - "8FB78ABCA75C9F284E974E36141866BC", - "9D9745FF31C42A4488CBB771B13B5D86" - } - ), - new DRBGTestVector( - new DesEdeEngine(), 168, - new Bit232EntropyProvider().Get(232), - true, - "20212223242526", - 112, - new String[] - { - "0E389920A09B485AA4ABD0CA7E60D89C", - "F4478EC6659A0D3577625B0C73A211DD" - } - ) - .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C") - .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBC"), - new DRBGTestVector( - new DesEdeEngine(), 168, - new Bit232EntropyProvider().Get(232), - true, - "20212223242526", - 112, - new String[] - { - "64983055D014550B39DE699E43130B64", - "035FDDA8582A2214EC722C410A8D95D3" - } - ) - .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C"), - new DRBGTestVector( - new DesEdeEngine(), 168, - new Bit232EntropyProvider().Get(232), - true, - "20212223242526", - 112, - new String[] - { - "A29C1A8C42FBC562D7D1DBA7DC541FFE", - "0BDA66B049429061C013E4228C2F44C6" - } - ) - .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C") - .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C") - .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBC"), - new DRBGTestVector( - new AesFastEngine(), 128, - new Bit256EntropyProvider().Get(256), - false, - "2021222324252627", - 128, - new String[] - { - "8CF59C8CF6888B96EB1C1E3E79D82387AF08A9E5FF75E23F1FBCD4559B6B997E", - "69CDEF912C692D61B1DA4C05146B52EB7B8849BD87937835328254EC25A9180E" - } - ), - new DRBGTestVector( - new AesFastEngine(), 128, - new Bit256EntropyProvider().Get(256), - false, - "2021222324252627", - 128, - new String[] - { - "E8C74A4B7BFFB53BEB80E78CA86BB6DF70E2032AEB473E0DD54D2339CEFCE9D0", - "26B3F823B4DBAFC23B141375E10B3AEB7A0B5DEF1C7D760B6F827D01ECD17AC7" - } - ) - .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F") - .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF"), - new DRBGTestVector( - new AesFastEngine(), 128, - new Bit256EntropyProvider().Get(256), - false, - "2021222324252627", - 128, - new String[] - { - "18FDEFBDC43D7A36D5D6D862205765D1D701C9F237007030DF1B8E70EE4EEE29", - "9888F1D38BB1CCE31B363AA1BD9B39616876C30DEE1FF0B7BD8C4C441715C833" - } - ) - .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F"), - new DRBGTestVector( - new AesFastEngine(), 128, - new Bit256EntropyProvider().Get(256), - true, - "2021222324252627", - 128, - new String[] - { - "BFF4B85D68C84529F24F69F9ACF1756E29BA648DDEB825C225FA32BA490EF4A9", - "9BD2635137A52AF7D0FCBEFEFB97EA93A0F4C438BD98956C0DACB04F15EE25B3" - } - ), - new DRBGTestVector( - new AesFastEngine(), 128, - new Bit256EntropyProvider().Get(256), - true, - "2021222324252627", - 128, - new String[] - { - "4573AC8BBB33D7CC4DBEF3EEDF6EAE748B536C3A1082CEE4948CDB51C83A7F9C", - "99C628CDD87BD8C2F1FE443AA7F761DA16886436326323354DA6311FFF5BC678" - } - ) - .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F") - .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF"), - new DRBGTestVector( - new AesFastEngine(), 128, - new Bit256EntropyProvider().Get(256), - true, - "2021222324252627", - 128, - new String[] - { - "F324104E2FA14F79D8AA60DF06B93B3BC157324958F0A7EE1E193677A70E0250", - "78F4C840134F40DC001BFAD3A90B5EF4DEBDBFAC3CFDF0CD69A89DC4FD34713F" - } - ) - .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F"), - new DRBGTestVector( - new AesFastEngine(), 192, - new Bit320EntropyProvider().Get(320), - false, - "202122232425262728292A2B", - 192, - new String[] - { - "E231244B3235B085C81604424357E85201E3828B5C45568679A5555F867AAC8C", - "DDD0F7BCCADADAA31A67652259CE569A271DD85CF66C3D6A7E9FAED61F38D219" - } - ) - .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F6061626364656667"), - new DRBGTestVector( - new AesFastEngine(), 192, - new Bit320EntropyProvider().Get(320), - true, - "202122232425262728292A2B", - 192, - new String[] - { - "F780D4A2C25CF8EE7407D948EC0B724A4235D8B20E65081392755CA7912AD7C0", - "BA14617F915BA964CB79276BDADC840C14B631BBD1A59097054FA6DFF863B238" - } - ) - .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F6061626364656667"), - new DRBGTestVector( - new AesFastEngine(), 256, - new Bit384EntropyProvider().Get(384), - false, - "202122232425262728292A2B2C2D2E2F", - 256, - new String[] - { - "47111E146562E9AA2FB2A1B095D37A8165AF8FC7CA611D632BE7D4C145C83900", - "98A28E3B1BA363C9DAF0F6887A1CF52B833D3354D77A7C10837DD63DD2E645F8" - } - ) - .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F") - .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F") - .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECF"), - new DRBGTestVector( - new AesFastEngine(), 256, - new Bit384EntropyProvider().Get(384), - true, - "202122232425262728292A2B2C2D2E2F", - 256, - new String[] - { - "71BB3F9C9CEAF4E6C92A83EB4C7225010EE150AC75E23F5F77AD5073EF24D88A", - "386DEBBBF091BBF0502957B0329938FB836B82E594A2F5FDD5EB28D4E35528F4" - } - ) - .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F") - .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECF"), - new DRBGTestVector( - new AesFastEngine(), 256, - new Bit384EntropyProvider().Get(384), - true, - "202122232425262728292A2B2C2D2E2F", - 256, - new String[] - { - "1A2E3FEE9056E98D375525FDC2B63B95B47CE51FCF594D804BD5A17F2E01139B", - "601F95384F0D85946301D1EACE8F645A825CE38F1E2565B0C0C439448E9CA8AC" - } - ) - .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F"), - new DRBGTestVector( - new AesFastEngine(), 256, - new Bit384EntropyProvider().Get(384), - true, - "202122232425262728292A2B2C2D2E2F", - 256, - new String[] - { - "EAE6BCE781807E524D26605EA198077932D01EEB445B9AC6C5D99C101D29F46E", - "738E99C95AF59519AAD37FF3D5180986ADEBAB6E95836725097E50A8D1D0BD28" - } - ) - .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F") - .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F") - .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECF"), - new DRBGTestVector( - new AesFastEngine(), 256, - new Bit384EntropyProvider().Get(384), - true, - "202122232425262728292A2B2C2D2E2F", - 256, - new String[] - { - "eae6bce781807e524d26605ea198077932d01eeb445b9ac6c5d99c101d29f46e30b27377", - "ec51b55b49904c3ff9e13939f1cf27398993e1b3acb2b0be0be8761261428f0aa8ba2657" - } - ) - .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F") - .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F") - .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECF") + string resultText = Perform().ToString(); + + Assert.AreEqual(Name + ": Okay", resultText); + } + + private DrbgTestVector[] CreateTestVectorData() + { + return new DrbgTestVector[] + { + new DrbgTestVector( + new DesEdeEngine(), 168, + new Bit232EntropyProvider().Get(232), + false, + "20212223242526", + 112, + new string[] + { + "ABC88224514D0316EA3D48AEE3C9A2B4", + "D3D3F372E43E7ABDC4FA293743EED076" + } + ), + new DrbgTestVector( + new DesEdeEngine(), 168, + new Bit232EntropyProvider().Get(232), + false, + "20212223242526", + 112, + new string[] + { + "D4564EE072ACA5BD279536E14F94CB12", + "1CCD9AFEF15A9679BA75E35225585DEA" + } + ) + .AddAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C") + .AddAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBC"), + new DrbgTestVector( + new DesEdeEngine(), 168, + new Bit232EntropyProvider().Get(232), + false, + "20212223242526", + 112, + new string[] + { + "760BED7D92B083B10AF31CF0656081EB", + "FD1AC41482384D823CF3FD6F0E6C88B3" + } + ) + .SetPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C"), + new DrbgTestVector( + new DesEdeEngine(), 168, + new Bit232EntropyProvider().Get(232), + false, + "20212223242526", + 112, + new string[] + { + "7A4C1D7ADC8A67FDB50100ED23583A2C", + "43044D311C0E07541CA5C8B0916976B2" + } + ) + .SetPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C") + .AddAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C") + .AddAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBC"), + new DrbgTestVector( + new DesEdeEngine(), 168, + new Bit232EntropyProvider().Get(232), + true, + "20212223242526", + 112, + new string[] + { + "8FB78ABCA75C9F284E974E36141866BC", + "9D9745FF31C42A4488CBB771B13B5D86" + } + ), + new DrbgTestVector( + new DesEdeEngine(), 168, + new Bit232EntropyProvider().Get(232), + true, + "20212223242526", + 112, + new string[] + { + "0E389920A09B485AA4ABD0CA7E60D89C", + "F4478EC6659A0D3577625B0C73A211DD" + } + ) + .AddAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C") + .AddAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBC"), + new DrbgTestVector( + new DesEdeEngine(), 168, + new Bit232EntropyProvider().Get(232), + true, + "20212223242526", + 112, + new string[] + { + "64983055D014550B39DE699E43130B64", + "035FDDA8582A2214EC722C410A8D95D3" + } + ) + .SetPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C"), + new DrbgTestVector( + new DesEdeEngine(), 168, + new Bit232EntropyProvider().Get(232), + true, + "20212223242526", + 112, + new string[] + { + "A29C1A8C42FBC562D7D1DBA7DC541FFE", + "0BDA66B049429061C013E4228C2F44C6" + } + ) + .SetPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C") + .AddAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C") + .AddAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBC"), + new DrbgTestVector( + new AesFastEngine(), 128, + new Bit256EntropyProvider().Get(256), + false, + "2021222324252627", + 128, + new string[] + { + "8CF59C8CF6888B96EB1C1E3E79D82387AF08A9E5FF75E23F1FBCD4559B6B997E", + "69CDEF912C692D61B1DA4C05146B52EB7B8849BD87937835328254EC25A9180E" + } + ), + new DrbgTestVector( + new AesFastEngine(), 128, + new Bit256EntropyProvider().Get(256), + false, + "2021222324252627", + 128, + new string[] + { + "E8C74A4B7BFFB53BEB80E78CA86BB6DF70E2032AEB473E0DD54D2339CEFCE9D0", + "26B3F823B4DBAFC23B141375E10B3AEB7A0B5DEF1C7D760B6F827D01ECD17AC7" + } + ) + .AddAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F") + .AddAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF"), + new DrbgTestVector( + new AesFastEngine(), 128, + new Bit256EntropyProvider().Get(256), + false, + "2021222324252627", + 128, + new string[] + { + "18FDEFBDC43D7A36D5D6D862205765D1D701C9F237007030DF1B8E70EE4EEE29", + "9888F1D38BB1CCE31B363AA1BD9B39616876C30DEE1FF0B7BD8C4C441715C833" + } + ) + .SetPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F"), + new DrbgTestVector( + new AesFastEngine(), 128, + new Bit256EntropyProvider().Get(256), + true, + "2021222324252627", + 128, + new string[] + { + "BFF4B85D68C84529F24F69F9ACF1756E29BA648DDEB825C225FA32BA490EF4A9", + "9BD2635137A52AF7D0FCBEFEFB97EA93A0F4C438BD98956C0DACB04F15EE25B3" + } + ), + new DrbgTestVector( + new AesFastEngine(), 128, + new Bit256EntropyProvider().Get(256), + true, + "2021222324252627", + 128, + new string[] + { + "4573AC8BBB33D7CC4DBEF3EEDF6EAE748B536C3A1082CEE4948CDB51C83A7F9C", + "99C628CDD87BD8C2F1FE443AA7F761DA16886436326323354DA6311FFF5BC678" + } + ) + .AddAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F") + .AddAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF"), + new DrbgTestVector( + new AesFastEngine(), 128, + new Bit256EntropyProvider().Get(256), + true, + "2021222324252627", + 128, + new string[] + { + "F324104E2FA14F79D8AA60DF06B93B3BC157324958F0A7EE1E193677A70E0250", + "78F4C840134F40DC001BFAD3A90B5EF4DEBDBFAC3CFDF0CD69A89DC4FD34713F" + } + ) + .SetPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F"), + new DrbgTestVector( + new AesFastEngine(), 192, + new Bit320EntropyProvider().Get(320), + false, + "202122232425262728292A2B", + 192, + new string[] + { + "E231244B3235B085C81604424357E85201E3828B5C45568679A5555F867AAC8C", + "DDD0F7BCCADADAA31A67652259CE569A271DD85CF66C3D6A7E9FAED61F38D219" + } + ) + .SetPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F6061626364656667"), + new DrbgTestVector( + new AesFastEngine(), 192, + new Bit320EntropyProvider().Get(320), + true, + "202122232425262728292A2B", + 192, + new string[] + { + "F780D4A2C25CF8EE7407D948EC0B724A4235D8B20E65081392755CA7912AD7C0", + "BA14617F915BA964CB79276BDADC840C14B631BBD1A59097054FA6DFF863B238" + } + ) + .SetPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F6061626364656667"), + new DrbgTestVector( + new AesFastEngine(), 256, + new Bit384EntropyProvider().Get(384), + false, + "202122232425262728292A2B2C2D2E2F", + 256, + new string[] + { + "47111E146562E9AA2FB2A1B095D37A8165AF8FC7CA611D632BE7D4C145C83900", + "98A28E3B1BA363C9DAF0F6887A1CF52B833D3354D77A7C10837DD63DD2E645F8" + } + ) + .SetPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F") + .AddAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F") + .AddAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECF"), + new DrbgTestVector( + new AesFastEngine(), 256, + new Bit384EntropyProvider().Get(384), + true, + "202122232425262728292A2B2C2D2E2F", + 256, + new string[] + { + "71BB3F9C9CEAF4E6C92A83EB4C7225010EE150AC75E23F5F77AD5073EF24D88A", + "386DEBBBF091BBF0502957B0329938FB836B82E594A2F5FDD5EB28D4E35528F4" + } + ) + .AddAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F") + .AddAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECF"), + new DrbgTestVector( + new AesFastEngine(), 256, + new Bit384EntropyProvider().Get(384), + true, + "202122232425262728292A2B2C2D2E2F", + 256, + new string[] + { + "1A2E3FEE9056E98D375525FDC2B63B95B47CE51FCF594D804BD5A17F2E01139B", + "601F95384F0D85946301D1EACE8F645A825CE38F1E2565B0C0C439448E9CA8AC" + } + ) + .SetPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F"), + new DrbgTestVector( + new AesFastEngine(), 256, + new Bit384EntropyProvider().Get(384), + true, + "202122232425262728292A2B2C2D2E2F", + 256, + new string[] + { + "EAE6BCE781807E524D26605EA198077932D01EEB445B9AC6C5D99C101D29F46E", + "738E99C95AF59519AAD37FF3D5180986ADEBAB6E95836725097E50A8D1D0BD28" + } + ) + .SetPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F") + .AddAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F") + .AddAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECF"), + new DrbgTestVector( + new AesFastEngine(), 256, + new Bit384EntropyProvider().Get(384), + true, + "202122232425262728292A2B2C2D2E2F", + 256, + new string[] + { + "eae6bce781807e524d26605ea198077932d01eeb445b9ac6c5d99c101d29f46e30b27377", + "ec51b55b49904c3ff9e13939f1cf27398993e1b3acb2b0be0be8761261428f0aa8ba2657" + } + ) + .SetPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F") + .AddAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F") + .AddAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECF") }; } public override void PerformTest() { - DRBGTestVector[] tests = createTestVectorData(); - SP80090Drbg d; - DRBGTestVector tv; + DrbgTestVector[] tests = CreateTestVectorData(); + ISP80090Drbg d; + DrbgTestVector tv; byte[] output; for (int i = 0; i != tests.Length; i++) { tv = tests[i]; - byte[] nonce = tv.nonce(); - byte[] personalisationString = tv.personalizationString(); + byte[] nonce = tv.GetNonce(); + byte[] personalisationString = tv.GetPersonalizationString(); - d = new CtrSP800Drbg(tv.getCipher(), tv.keySizeInBits(), tv.securityStrength(), tv.entropySource(), personalisationString, nonce); + d = new CtrSP800Drbg(tv.Cipher, tv.KeySizeInBits, tv.SecurityStrength, tv.EntropySource, personalisationString, nonce); - output = new byte[tv.expectedValue(0).Length]; + output = new byte[tv.GetExpectedValue(0).Length]; - d.Generate(output, tv.additionalInput(0), tv.predictionResistance()); + d.Generate(output, tv.GetAdditionalInput(0), tv.PredictionResistance); - byte[] expected = tv.expectedValue(0); + byte[] expected = tv.GetExpectedValue(0); if (!AreEqual(expected, output)) { - Fail("Test #" + (i + 1) + ".1 failed, expected " + Hex.ToHexString(tv.expectedValue(0)) + " got " + Hex.ToHexString(output)); + Fail("Test #" + (i + 1) + ".1 failed, expected " + Hex.ToHexString(tv.GetExpectedValue(0)) + " got " + Hex.ToHexString(output)); } - output = new byte[tv.expectedValue(0).Length]; + output = new byte[tv.GetExpectedValue(0).Length]; - d.Generate(output, tv.additionalInput(1), tv.predictionResistance()); + d.Generate(output, tv.GetAdditionalInput(1), tv.PredictionResistance); - expected = tv.expectedValue(1); + expected = tv.GetExpectedValue(1); if (!AreEqual(expected, output)) { - Fail("Test #" + (i + 1) + ".2 failed, expected " + Hex.ToHexString(tv.expectedValue(1)) + " got " + Hex.ToHexString(output)); + Fail("Test #" + (i + 1) + ".2 failed, expected " + Hex.ToHexString(tv.GetExpectedValue(1)) + " got " + Hex.ToHexString(output)); } } // DESede/TDEA key parity test tv = tests[0]; - SP80090Drbg drbg = new CtrSP800Drbg(new KeyParityCipher(tv.getCipher()), tv.keySizeInBits(), tv.securityStrength(), tv.entropySource(), tv.personalizationString(), tv.nonce()); + ISP80090Drbg drbg = new CtrSP800Drbg(new KeyParityCipher(tv.Cipher), tv.KeySizeInBits, tv.SecurityStrength, tv.EntropySource, + tv.GetPersonalizationString(), tv.GetNonce()); - output = new byte[tv.expectedValue(0).Length]; + output = new byte[tv.GetExpectedValue(0).Length]; - drbg.Generate(output, tv.additionalInput(0), tv.predictionResistance()); + drbg.Generate(output, tv.GetAdditionalInput(0), tv.PredictionResistance); // Exception tests try @@ -422,21 +432,21 @@ namespace Org.BouncyCastle.Crypto.Prng.Test internal class Bit232EntropyProvider : TestEntropySourceProvider { internal Bit232EntropyProvider() : base(Hex.Decode( - "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C" + - "808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C" + - "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDC"), true) + "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C" + + "808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C" + + "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDC"), true) { } } internal class Bit256EntropyProvider : TestEntropySourceProvider { internal Bit256EntropyProvider(): base(Hex.Decode( - "0001020304050607" + - "08090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F" + - "8081828384858687" + - "88898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F" + - "C0C1C2C3C4C5C6C7" + - "C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF"), true) + "0001020304050607" + + "08090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F" + + "8081828384858687" + + "88898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F" + + "C0C1C2C3C4C5C6C7" + + "C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF"), true) { } } @@ -489,18 +499,12 @@ namespace Org.BouncyCastle.Crypto.Prng.Test public String AlgorithmName { - get - { - return cipher.AlgorithmName; - } + get { return cipher.AlgorithmName; } } public bool IsPartialBlockOkay { - get - { - return false; - } + get { return false; } } public int GetBlockSize() @@ -518,7 +522,5 @@ namespace Org.BouncyCastle.Crypto.Prng.Test cipher.Reset(); } } - } - } diff --git a/crypto/test/src/crypto/prng/test/DrbgTestVector.cs b/crypto/test/src/crypto/prng/test/DrbgTestVector.cs index a4129b9f8..e0a8eeaf5 100644 --- a/crypto/test/src/crypto/prng/test/DrbgTestVector.cs +++ b/crypto/test/src/crypto/prng/test/DrbgTestVector.cs @@ -1,24 +1,25 @@ -using Org.BouncyCastle.Utilities.Encoders; -using System; -using System.Collections.Generic; -using System.Text; +using System; +using System.Collections; + +using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Crypto.Prng.Test { - public class DRBGTestVector + public class DrbgTestVector { private IDigest _digest; private IBlockCipher _cipher; private int _keySizeInBits; private IEntropySource _eSource; private bool _pr; - private String _nonce; - private String _personalisation; + private string _nonce; + private string _personalisation; private int _ss; private String[] _ev; - private List<string> _ai = new List<string>(); + private IList _ai = new ArrayList(); - public DRBGTestVector(IDigest digest, IEntropySource eSource, bool predictionResistance, String nonce, int securityStrength, String[] expected) + public DrbgTestVector(IDigest digest, IEntropySource eSource, bool predictionResistance, string nonce, + int securityStrength, string[] expected) { _digest = digest; _eSource = eSource; @@ -29,7 +30,8 @@ namespace Org.BouncyCastle.Crypto.Prng.Test _personalisation = null; } - public DRBGTestVector(IBlockCipher cipher, int keySizeInBits, IEntropySource eSource, bool predictionResistance, String nonce, int securityStrength, String[] expected) + public DrbgTestVector(IBlockCipher cipher, int keySizeInBits, IEntropySource eSource, bool predictionResistance, + string nonce, int securityStrength, string[] expected) { _cipher = cipher; _keySizeInBits = keySizeInBits; @@ -41,89 +43,69 @@ namespace Org.BouncyCastle.Crypto.Prng.Test _personalisation = null; } - public IDigest getDigest() + public IDigest Digest { - return _digest; + get { return _digest; } } - public IBlockCipher getCipher() + public IBlockCipher Cipher { - return _cipher; + get { return _cipher; } } - public int keySizeInBits() + public int KeySizeInBits { - return _keySizeInBits; + get { return _keySizeInBits; } } - public DRBGTestVector addAdditionalInput(String input) + public DrbgTestVector AddAdditionalInput(string input) { _ai.Add(input); - return this; } - public DRBGTestVector setPersonalizationString(String p) + public DrbgTestVector SetPersonalizationString(string p) { _personalisation = p; - return this; } - public IEntropySource entropySource() + public IEntropySource EntropySource { - return _eSource; + get { return _eSource; } } - public bool predictionResistance() + public bool PredictionResistance { - return _pr; + get { return _pr; } } - public byte[] nonce() + public byte[] GetNonce() { - if (_nonce == null) - { - return null; - } - - return Hex.Decode(_nonce); + return _nonce == null ? null : Hex.Decode(_nonce); } - public byte[] personalizationString() + public byte[] GetPersonalizationString() { - if (_personalisation == null) - { - return null; - } - - return Hex.Decode(_personalisation); + return _personalisation == null ? null : Hex.Decode(_personalisation); } - public int securityStrength() + public int SecurityStrength { - return _ss; + get { return _ss; } } - public byte[] expectedValue(int index) + public byte[] GetExpectedValue(int index) { return Hex.Decode(_ev[index]); } - public byte[] additionalInput(int position) + public byte[] GetAdditionalInput(int position) { - int len = _ai.Count; - byte[] rv; - if (position >= len) - { - rv = null; - } - else - { - rv = Hex.Decode((string)(_ai[position])); - } - return rv; - } + if (position >= _ai.Count) + return null; + return Hex.Decode((string)_ai[position]); + } } } diff --git a/crypto/test/src/crypto/prng/test/HMacDrbgTest.cs b/crypto/test/src/crypto/prng/test/HMacDrbgTest.cs index b8d383663..a5ca30836 100644 --- a/crypto/test/src/crypto/prng/test/HMacDrbgTest.cs +++ b/crypto/test/src/crypto/prng/test/HMacDrbgTest.cs @@ -1,12 +1,12 @@ - -using System; +using System; + +using NUnit.Framework; using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto.Macs; using Org.BouncyCastle.Crypto.Prng.Drbg; using Org.BouncyCastle.Utilities.Test; using Org.BouncyCastle.Utilities.Encoders; -using NUnit.Framework; namespace Org.BouncyCastle.Crypto.Prng.Test { @@ -14,142 +14,141 @@ namespace Org.BouncyCastle.Crypto.Prng.Test * HMAC SP800-90 DRBG */ [TestFixture] - public class HMacDrbgTest : SimpleTest + public class HMacDrbgTest + : SimpleTest { - public override String Name + public override string Name { - get - { - return "HMacDRBG"; - } + get { return "HMacDRBG"; } } - public static void main(String[] args) + public static void Main(string[] args) { RunTest(new HMacDrbgTest()); } [Test] - public void HMacDrbgTestFunction() + public void TestFunction() { string resultText = Perform().ToString(); Assert.AreEqual(Name + ": Okay", resultText); } - private DRBGTestVector[] createTestVectorData() + private DrbgTestVector[] CreateTestVectorData() { - return new DRBGTestVector[] - { - new DRBGTestVector( + return new DrbgTestVector[] + { + new DrbgTestVector( new Sha1Digest(), new SHA1EntropyProvider().Get(440), false, "2021222324", 80, - new String[] - { - "5A7D3B449F481CB38DF79AD2B1FCC01E57F8135E8C0B22CD0630BFB0127FB5408C8EFC17A929896E", - "82cf772ec3e84b00fc74f5df104efbfb2428554e9ce367d03aeade37827fa8e9cb6a08196115d948" - }), - new DRBGTestVector( + new string[] + { + "5A7D3B449F481CB38DF79AD2B1FCC01E57F8135E8C0B22CD0630BFB0127FB5408C8EFC17A929896E", + "82cf772ec3e84b00fc74f5df104efbfb2428554e9ce367d03aeade37827fa8e9cb6a08196115d948" + }), + new DrbgTestVector( new Sha1Digest(), new SHA1EntropyProvider().Get(440), false, "2021222324", 80, - new String[] - { - "B3BD05246CBA12A64735A4E3FDE599BC1BE30F439BD060208EEA7D71F9D123DF47B3CE069D98EDE6", - "B5DADA380E2872DF935BCA55B882C8C9376902AB639765472B71ACEBE2EA8B1B6B49629CB67317E0" - }) - .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F70717273747576"), - new DRBGTestVector( + new string[] + { + "B3BD05246CBA12A64735A4E3FDE599BC1BE30F439BD060208EEA7D71F9D123DF47B3CE069D98EDE6", + "B5DADA380E2872DF935BCA55B882C8C9376902AB639765472B71ACEBE2EA8B1B6B49629CB67317E0" + }) + .SetPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F70717273747576"), + new DrbgTestVector( new Sha1Digest(), new SHA1EntropyProvider().Get(440), false, "2021222324", 80, - new String[] - { - "C7AAAC583C6EF6300714C2CC5D06C148CFFB40449AD0BB26FAC0497B5C57E161E36681BCC930CE80", - "6EBD2B7B5E0A2AD7A24B1BF9A1DBA47D43271719B9C37B7FE81BA94045A14A7CB514B446666EA5A7" - }) - .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F90919293949596") - .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6"), - new DRBGTestVector( + new string[] + { + "C7AAAC583C6EF6300714C2CC5D06C148CFFB40449AD0BB26FAC0497B5C57E161E36681BCC930CE80", + "6EBD2B7B5E0A2AD7A24B1BF9A1DBA47D43271719B9C37B7FE81BA94045A14A7CB514B446666EA5A7" + }) + .AddAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F90919293949596") + .AddAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6"), + new DrbgTestVector( new Sha1Digest(), new SHA1EntropyProvider().Get(440), true, "2021222324", 80, - new String[] - { - "FEC4597F06A3A8CC8529D59557B9E661053809C0BC0EFC282ABD87605CC90CBA9B8633DCB1DAE02E", - "84ADD5E2D2041C01723A4DE4335B13EFDF16B0E51A0AD39BD15E862E644F31E4A2D7D843E57C5968" - }), - new DRBGTestVector( + new string[] + { + "FEC4597F06A3A8CC8529D59557B9E661053809C0BC0EFC282ABD87605CC90CBA9B8633DCB1DAE02E", + "84ADD5E2D2041C01723A4DE4335B13EFDF16B0E51A0AD39BD15E862E644F31E4A2D7D843E57C5968" + }), + new DrbgTestVector( new Sha1Digest(), new SHA1EntropyProvider().Get(440), true, "2021222324", 80, - new String[] - { - "6C37FDD729AA40F80BC6AB08CA7CC649794F6998B57081E4220F22C5C283E2C91B8E305AB869C625", - "CAF57DCFEA393B9236BF691FA456FEA7FDF1DF8361482CA54D5FA723F4C88B4FA504BF03277FA783" - }) - .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F70717273747576"), - new DRBGTestVector( + new string[] + { + "6C37FDD729AA40F80BC6AB08CA7CC649794F6998B57081E4220F22C5C283E2C91B8E305AB869C625", + "CAF57DCFEA393B9236BF691FA456FEA7FDF1DF8361482CA54D5FA723F4C88B4FA504BF03277FA783" + }) + .SetPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F70717273747576"), + new DrbgTestVector( new Sha1Digest(), new SHA1EntropyProvider().Get(440), true, "2021222324", 80, - new String[] - { - "A1BA8FA58BB5013F43F7B6ED52B4539FA16DC77957AEE815B9C07004C7E992EB8C7E591964AFEEA2", - "84264A73A818C95C2F424B37D3CC990B046FB50C2DC64A164211889A010F2471A0912FFEA1BF0195" - }) - .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F90919293949596") - .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6"), - new DRBGTestVector( + new string[] + { + "A1BA8FA58BB5013F43F7B6ED52B4539FA16DC77957AEE815B9C07004C7E992EB8C7E591964AFEEA2", + "84264A73A818C95C2F424B37D3CC990B046FB50C2DC64A164211889A010F2471A0912FFEA1BF0195" + }) + .AddAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F90919293949596") + .AddAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6"), + new DrbgTestVector( new Sha256Digest(), new SHA256EntropyProvider().Get(440), false, "2021222324252627", 128, - new String[] - { - "D67B8C1734F46FA3F763CF57C6F9F4F2" + - "DC1089BD8BC1F6F023950BFC5617635208C8501238AD7A44" + - "00DEFEE46C640B61AF77C2D1A3BFAA90EDE5D207406E5403", - "8FDAEC20F8B421407059E3588920DA7E" + - "DA9DCE3CF8274DFA1C59C108C1D0AA9B0FA38DA5C792037C" + - "4D33CD070CA7CD0C5608DBA8B885654639DE2187B74CB263" - }), - new DRBGTestVector( + new string[] + { + "D67B8C1734F46FA3F763CF57C6F9F4F2" + + "DC1089BD8BC1F6F023950BFC5617635208C8501238AD7A44" + + "00DEFEE46C640B61AF77C2D1A3BFAA90EDE5D207406E5403", + "8FDAEC20F8B421407059E3588920DA7E" + + "DA9DCE3CF8274DFA1C59C108C1D0AA9B0FA38DA5C792037C" + + "4D33CD070CA7CD0C5608DBA8B885654639DE2187B74CB263" + }), + new DrbgTestVector( new Sha256Digest(), new SHA256EntropyProvider().Get(440), true, "2021222324252627", 128, - new String[] - { - "FABD0AE25C69DC2EFDEFB7F20C5A31B5" + - "7AC938AB771AA19BF8F5F1468F665C938C9A1A5DF0628A56" + - "90F15A1AD8A613F31BBD65EEAD5457D5D26947F29FE91AA7", - "6BD925B0E1C232EFD67CCD84F722E927" + - "ECB46AB2B740014777AF14BA0BBF53A45BDBB62B3F7D0B9C" + - "8EEAD057C0EC754EF8B53E60A1F434F05946A8B686AFBC7A" - }), - new DRBGTestVector( + new string[] + { + "FABD0AE25C69DC2EFDEFB7F20C5A31B5" + + "7AC938AB771AA19BF8F5F1468F665C938C9A1A5DF0628A56" + + "90F15A1AD8A613F31BBD65EEAD5457D5D26947F29FE91AA7", + "6BD925B0E1C232EFD67CCD84F722E927" + + "ECB46AB2B740014777AF14BA0BBF53A45BDBB62B3F7D0B9C" + + "8EEAD057C0EC754EF8B53E60A1F434F05946A8B686AFBC7A" + }), + new DrbgTestVector( new Sha384Digest(), new SHA384EntropyProvider().Get(888), false, "202122232425262728292A2B", 192, - new String[]{ + new string[] + { "03AB8BCE4D1DBBB636C5C5B7E1C58499FEB1C619CDD11D35" + "CD6CF6BB8F20EF27B6F5F9054FF900DB9EBF7BF30ED4DCBB" + "BC8D5B51C965EA226FFEE2CA5AB2EFD00754DC32F357BF7A" + @@ -157,20 +156,22 @@ namespace Org.BouncyCastle.Crypto.Prng.Test "B907E77144FD55A54E9BA1A6A0EED0AAC780020C41A15DD8" + "9A6C163830BA1D094E6A17100FF71EE30A96E1EE04D2A966" + "03832A4E404F1966C2B5F4CB61B9927E8D12AC1E1A24CF23" + - "88C14E8EC96C35181EAEE32AAA46330DEAAFE5E7CE783C74"}) - .setPersonalizationString( - "404142434445464748494A4B4C4D4E" + - "4F505152535455565758595A5B5C5D5E5F60616263646566" + - "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + - "7F808182838485868788898A8B8C8D8E8F90919293949596" + - "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE"), - new DRBGTestVector( + "88C14E8EC96C35181EAEE32AAA46330DEAAFE5E7CE783C74" + }) + .SetPersonalizationString( + "404142434445464748494A4B4C4D4E" + + "4F505152535455565758595A5B5C5D5E5F60616263646566" + + "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + + "7F808182838485868788898A8B8C8D8E8F90919293949596" + + "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE"), + new DrbgTestVector( new Sha384Digest(), new SHA384EntropyProvider().Get(888), true, "202122232425262728292A2B", 192, - new String[]{ + new string[] + { "804A3AD720F4FCE8738D0632514FEF16430CB7D63A8DF1A5" + "F02A3CE3BD7ED6A668B69E63E2BB93F096EE753D6194A0F1" + "A32711063653009636337D22167CC4402D019AC216FA574F" + @@ -178,45 +179,49 @@ namespace Org.BouncyCastle.Crypto.Prng.Test "73B8E55C753202176A17B9B9754A9FE6F23B01861FCD4059" + "6AEAA301AF1AEF8AF0EAF22FBF34541EFFAB1431666ACACC" + "759338C7E28672819D53CFEF10A3E19DAFBD53295F1980A9" + - "F491504A2725506784B7AC826D92C838A8668171CAAA86E7"}) - .setPersonalizationString( - "404142434445464748494A4B4C4D4E" + - "4F505152535455565758595A5B5C5D5E5F60616263646566" + - "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + - "7F808182838485868788898A8B8C8D8E8F90919293949596" + - "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE"), - new DRBGTestVector( + "F491504A2725506784B7AC826D92C838A8668171CAAA86E7" + }) + .SetPersonalizationString( + "404142434445464748494A4B4C4D4E" + + "4F505152535455565758595A5B5C5D5E5F60616263646566" + + "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + + "7F808182838485868788898A8B8C8D8E8F90919293949596" + + "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE"), + new DrbgTestVector( new Sha512Digest(), new SHA512EntropyProvider().Get(888), false, "202122232425262728292A2B2C2D2E2F", 256, - new String[]{ + new string[] + { "2A5FF6520C20F66E" + - "D5EA431BD4AEAC58F975EEC9A015137D5C94B73AA09CB8B5" + - "9D611DDEECEB34A52BB999424009EB9EAC5353F92A6699D2" + - "0A02164EEBBC6492941E10426323898465DFD731C7E04730" + - "60A5AA8973841FDF3446FB6E72A58DA8BDA2A57A36F3DD98" + - "6DF85C8A5C6FF31CDE660BF8A841B21DD6AA9D3AC356B87B", + "D5EA431BD4AEAC58F975EEC9A015137D5C94B73AA09CB8B5" + + "9D611DDEECEB34A52BB999424009EB9EAC5353F92A6699D2" + + "0A02164EEBBC6492941E10426323898465DFD731C7E04730" + + "60A5AA8973841FDF3446FB6E72A58DA8BDA2A57A36F3DD98" + + "6DF85C8A5C6FF31CDE660BF8A841B21DD6AA9D3AC356B87B", "0EDC8D7D7CEEC7FE" + - "36333FB30C0A9A4B27AA0BECBF075568B006C1C3693B1C29" + - "0F84769C213F98EB5880909EDF068FDA6BFC43503987BBBD" + - "4FC23AFBE982FE4B4B007910CC4874EEC217405421C8D8A1" + - "BA87EC684D0AF9A6101D9DB787AE82C3A6A25ED478DF1B12" + - "212CEC325466F3AC7C48A56166DD0B119C8673A1A9D54F67"}) - .setPersonalizationString( - "404142434445464748494A4B4C4D4E" + - "4F505152535455565758595A5B5C5D5E5F60616263646566" + - "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + - "7F808182838485868788898A8B8C8D8E8F90919293949596" + - "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE"), - new DRBGTestVector( + "36333FB30C0A9A4B27AA0BECBF075568B006C1C3693B1C29" + + "0F84769C213F98EB5880909EDF068FDA6BFC43503987BBBD" + + "4FC23AFBE982FE4B4B007910CC4874EEC217405421C8D8A1" + + "BA87EC684D0AF9A6101D9DB787AE82C3A6A25ED478DF1B12" + + "212CEC325466F3AC7C48A56166DD0B119C8673A1A9D54F67" + }) + .SetPersonalizationString( + "404142434445464748494A4B4C4D4E" + + "4F505152535455565758595A5B5C5D5E5F60616263646566" + + "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + + "7F808182838485868788898A8B8C8D8E8F90919293949596" + + "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE"), + new DrbgTestVector( new Sha512Digest(), new SHA512EntropyProvider().Get(888), true, "202122232425262728292A2B2C2D2E2F", 256, - new String[]{ + new string[] + { "AAE4DC3C9ECC74D9" + "061DD527117EF3D29E1E52B26853C539D6CA797E8DA3D0BB" + "171D8E30B8B194D8C28F7F6BE3B986B88506DC6A01B294A7" + @@ -228,20 +233,22 @@ namespace Org.BouncyCastle.Crypto.Prng.Test "B9D8E5093ECE7B6BF48638D8F704D134ADDEB7F4E9D5C142" + "CD05683E72B516486AF24AEC15D61E81E270DD4EBED91B62" + "12EB8896A6250D5C8BC3A4A12F7E3068FBDF856F47EB23D3" + - "79F82C1EBCD1585FB260B9C0C42625FBCEE68CAD773CD5B1"}) - .setPersonalizationString( + "79F82C1EBCD1585FB260B9C0C42625FBCEE68CAD773CD5B1" + }) + .SetPersonalizationString( "404142434445464748494A4B4C4D4E" + - "4F505152535455565758595A5B5C5D5E5F60616263646566" + - "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + - "7F808182838485868788898A8B8C8D8E8F90919293949596" + - "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE"), - new DRBGTestVector( + "4F505152535455565758595A5B5C5D5E5F60616263646566" + + "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + + "7F808182838485868788898A8B8C8D8E8F90919293949596" + + "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE"), + new DrbgTestVector( new Sha512Digest(), new SHA512EntropyProvider().Get(888), false, "202122232425262728292A2B2C2D2E2F", 256, - new String[]{ + new string[] + { "7AE31A2DEC31075F" + "E5972660C16D22ECC0D415C5693001BE5A468B590BC1AE2C" + "43F647F8D681AEEA0D87B79B0B4E5D089CA2C9D327534234" + @@ -253,51 +260,55 @@ namespace Org.BouncyCastle.Crypto.Prng.Test "AB823C29F2EBDEC3EDE962F93D920A1DB59C84E1E879C29F" + "5F9995FC3A6A3AF9B587CA7C13EA197D423E81E1D6469942" + "B6E2CA83A97E91F6B298266AC148A1809776C26AF5E239A5" + - "5A2BEB9E752203A694E1F3FE2B3E6A0C9C314421CDB55FBD "}) - .setPersonalizationString( + "5A2BEB9E752203A694E1F3FE2B3E6A0C9C314421CDB55FBD " + }) + .SetPersonalizationString( "404142434445464748494A4B4C4D4E" + "4F505152535455565758595A5B5C5D5E5F60616263646566" + "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + "7F808182838485868788898A8B8C8D8E8F90919293949596" + "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE") - .addAdditionalInput( + .AddAdditionalInput( "606162636465666768696A6B6C6D6E" + "6F707172737475767778797A7B7C7D7E7F80818283848586" + "8788898A8B8C8D8E8F909192939495969798999A9B9C9D9E" + "9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + "B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCE") - .addAdditionalInput( + .AddAdditionalInput( "A0A1A2A3A4A5A6A7A8A9AAABACADAE" + "AFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6" + "C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDE" + "DFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6" + "F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E"), - new DRBGTestVector( + new DrbgTestVector( new Sha512Digest(), new SHA512EntropyProvider().Get(888), true, "202122232425262728292A2B2C2D2E2F", 256, - new String[]{ + new string[] + { "28FD6060C4F35F4D" + - "317AB2060EE32019E0DAA330F3F5650BBCA57CB67EE6AF1C" + - "6F25D1B01F3601EDA85DC2ED29A9B2BA4C85CF491CE7185F" + - "1A2BD9378AE3C655BD1CEC2EE108AE7FC382989F6D4FEA8A" + - "B01499697C2F07945CE02C5ED617D04287FEAF3BA638A4CE" + - "F3BB6B827E40AF16279580FCF1FDAD830930F7FDE341E2AF", + "317AB2060EE32019E0DAA330F3F5650BBCA57CB67EE6AF1C" + + "6F25D1B01F3601EDA85DC2ED29A9B2BA4C85CF491CE7185F" + + "1A2BD9378AE3C655BD1CEC2EE108AE7FC382989F6D4FEA8A" + + "B01499697C2F07945CE02C5ED617D04287FEAF3BA638A4CE" + + "F3BB6B827E40AF16279580FCF1FDAD830930F7FDE341E2AF", "C0B1601AFE39338B" + - "58DC2BE7C256AEBE3C21C5A939BEEC7E97B3528AC420F0C6" + - "341847187666E0FF578A8EB0A37809F877365A28DF2FA0F0" + - "6354A6F02496747369375B9A9D6B756FDC4A8FB308E08256" + - "9D79A85BB960F747256626389A3B45B0ABE7ECBC39D5CD7B" + - "2C18DF2E5FDE8C9B8D43474C54B6F9839468445929B438C7"}), - new DRBGTestVector( + "58DC2BE7C256AEBE3C21C5A939BEEC7E97B3528AC420F0C6" + + "341847187666E0FF578A8EB0A37809F877365A28DF2FA0F0" + + "6354A6F02496747369375B9A9D6B756FDC4A8FB308E08256" + + "9D79A85BB960F747256626389A3B45B0ABE7ECBC39D5CD7B" + + "2C18DF2E5FDE8C9B8D43474C54B6F9839468445929B438C7" + }), + new DrbgTestVector( new Sha512Digest(), new SHA512EntropyProvider().Get(888), true, "202122232425262728292A2B2C2D2E2F", 256, - new String[]{ + new string[] + { "72691D2103FB567C" + "CD30370715B36666F63430087B1C688281CA0974DB456BDB" + "A7EB5C48CFF62EA05F9508F3B530CE995A272B11EC079C13" + @@ -309,26 +320,28 @@ namespace Org.BouncyCastle.Crypto.Prng.Test "2F12BEB71D801C0942E7C0864B3DB67A9356DB203490D881" + "24FE86BCE38AC2269B4FDA6ABAA884039DF80A0336A24D79" + "1EB3067C8F5F0CF0F18DD73B66A7B316FB19E02835CC6293" + - "65FCD1D3BE640178ED9093B91B36E1D68135F2785BFF505C"}) - .addAdditionalInput( + "65FCD1D3BE640178ED9093B91B36E1D68135F2785BFF505C" + }) + .AddAdditionalInput( "606162636465666768696A6B6C6D6E" + "6F707172737475767778797A7B7C7D7E7F80818283848586" + "8788898A8B8C8D8E8F909192939495969798999A9B9C9D9E" + "9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + "B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCE") - .addAdditionalInput( + .AddAdditionalInput( "A0A1A2A3A4A5A6A7A8A9AAABACADAE" + "AFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6" + "C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDE" + "DFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6" + "F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E"), - new DRBGTestVector( + new DrbgTestVector( new Sha512Digest(), new SHA512EntropyProvider().Get(888), true, "202122232425262728292A2B2C2D2E2F", 256, - new String[]{ + new string[] + { "AAE4DC3C9ECC74D9" + "061DD527117EF3D29E1E52B26853C539D6CA797E8DA3D0BB" + "171D8E30B8B194D8C28F7F6BE3B986B88506DC6A01B294A7" + @@ -340,20 +353,22 @@ namespace Org.BouncyCastle.Crypto.Prng.Test "B9D8E5093ECE7B6BF48638D8F704D134ADDEB7F4E9D5C142" + "CD05683E72B516486AF24AEC15D61E81E270DD4EBED91B62" + "12EB8896A6250D5C8BC3A4A12F7E3068FBDF856F47EB23D3" + - "79F82C1EBCD1585FB260B9C0C42625FBCEE68CAD773CD5B1"}) - .setPersonalizationString( + "79F82C1EBCD1585FB260B9C0C42625FBCEE68CAD773CD5B1" + }) + .SetPersonalizationString( "404142434445464748494A4B4C4D4E" + - "4F505152535455565758595A5B5C5D5E5F60616263646566" + - "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + - "7F808182838485868788898A8B8C8D8E8F90919293949596" + - "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE"), - new DRBGTestVector( + "4F505152535455565758595A5B5C5D5E5F60616263646566" + + "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + + "7F808182838485868788898A8B8C8D8E8F90919293949596" + + "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE"), + new DrbgTestVector( new Sha512Digest(), new SHA512EntropyProvider().Get(888), true, "202122232425262728292A2B2C2D2E2F", 256, - new String[]{ + new string[] + { "B8E827652175E6E0" + "6E513C7BE94B5810C14ED94AD903647940CAEB7EE014C848" + "8DCBBE6D4D6616D06656A3DC707CDAC4F02EE6D8408C065F" + @@ -365,61 +380,62 @@ namespace Org.BouncyCastle.Crypto.Prng.Test "BD1B5C196C57CF759BB9871BE0C163A57315EA96F615136D" + "064572F09F26D659D24211F9610FFCDFFDA8CE23FFA96735" + "7595182660877766035EED800B05364CE324A75EB63FD9B3" + - "EED956D147480B1D0A42DF8AA990BB628666F6F61D60CBE2"}) - .setPersonalizationString( + "EED956D147480B1D0A42DF8AA990BB628666F6F61D60CBE2" + }) + .SetPersonalizationString( "404142434445464748494A4B4C4D4E" + - "4F505152535455565758595A5B5C5D5E5F60616263646566" + - "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + - "7F808182838485868788898A8B8C8D8E8F90919293949596" + - "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE") - .addAdditionalInput( + "4F505152535455565758595A5B5C5D5E5F60616263646566" + + "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + + "7F808182838485868788898A8B8C8D8E8F90919293949596" + + "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE") + .AddAdditionalInput( "606162636465666768696A6B6C6D6E" + - "6F707172737475767778797A7B7C7D7E7F80818283848586" + - "8788898A8B8C8D8E8F909192939495969798999A9B9C9D9E" + - "9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + - "B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCE") - .addAdditionalInput( + "6F707172737475767778797A7B7C7D7E7F80818283848586" + + "8788898A8B8C8D8E8F909192939495969798999A9B9C9D9E" + + "9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + + "B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCE") + .AddAdditionalInput( "A0A1A2A3A4A5A6A7A8A9AAABACADAE" + "AFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6" + "C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDE" + "DFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6" + "F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E") - }; + }; } public override void PerformTest() { - DRBGTestVector[] tests = createTestVectorData(); - SP80090Drbg d; + DrbgTestVector[] tests = CreateTestVectorData(); + ISP80090Drbg d; for (int i = 0; i != tests.Length; i++) { - DRBGTestVector tv = tests[i]; + DrbgTestVector tv = tests[i]; - byte[] nonce = tv.nonce(); - byte[] personalisationString = tv.personalizationString(); + byte[] nonce = tv.GetNonce(); + byte[] personalisationString = tv.GetPersonalizationString(); - d = new HMacSP800Drbg(new HMac(tv.getDigest()), tv.securityStrength(), tv.entropySource(), personalisationString, nonce); + d = new HMacSP800Drbg(new HMac(tv.Digest), tv.SecurityStrength, tv.EntropySource, personalisationString, nonce); - byte[] output = new byte[tv.expectedValue(0).Length]; + byte[] output = new byte[tv.GetExpectedValue(0).Length]; - d.Generate(output, tv.additionalInput(0), tv.predictionResistance()); + d.Generate(output, tv.GetAdditionalInput(0), tv.PredictionResistance); - byte[] expected = tv.expectedValue(0); + byte[] expected = tv.GetExpectedValue(0); if (!AreEqual(expected, output)) { - Fail("Test #" + (i + 1) + ".1 failed, expected " + Hex.ToHexString(tv.expectedValue(0)) + " got " + Hex.ToHexString(output)); + Fail("Test #" + (i + 1) + ".1 failed, expected " + Hex.ToHexString(tv.GetExpectedValue(0)) + " got " + Hex.ToHexString(output)); } - output = new byte[tv.expectedValue(0).Length]; + output = new byte[tv.GetExpectedValue(0).Length]; - d.Generate(output, tv.additionalInput(1), tv.predictionResistance()); + d.Generate(output, tv.GetAdditionalInput(1), tv.PredictionResistance); - expected = tv.expectedValue(1); + expected = tv.GetExpectedValue(1); if (!AreEqual(expected, output)) { - Fail("Test #" + (i + 1) + ".2 failed, expected " + Hex.ToHexString(tv.expectedValue(1)) + " got " + Hex.ToHexString(output)); + Fail("Test #" + (i + 1) + ".2 failed, expected " + Hex.ToHexString(tv.GetExpectedValue(1)) + " got " + Hex.ToHexString(output)); } } @@ -441,11 +457,10 @@ namespace Org.BouncyCastle.Crypto.Prng.Test private class SHA1EntropyProvider : TestEntropySourceProvider { - internal SHA1EntropyProvider() : base( - Hex.Decode( - "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F30313233343536" - + "808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" - + "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6"), true) + internal SHA1EntropyProvider() : base(Hex.Decode( + "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F30313233343536" + + "808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + + "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6"), true) { } } @@ -453,15 +468,15 @@ namespace Org.BouncyCastle.Crypto.Prng.Test internal class SHA256EntropyProvider : TestEntropySourceProvider { internal SHA256EntropyProvider() : base(Hex.Decode( - "00010203040506" + - "0708090A0B0C0D0E0F101112131415161718191A1B1C1D1E" + - "1F202122232425262728292A2B2C2D2E2F30313233343536" + - "80818283848586" + - "8788898A8B8C8D8E8F909192939495969798999A9B9C9D9E" + - "9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + - "C0C1C2C3C4C5C6" + - "C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDE" + - "DFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6"), true) + "00010203040506" + + "0708090A0B0C0D0E0F101112131415161718191A1B1C1D1E" + + "1F202122232425262728292A2B2C2D2E2F30313233343536" + + "80818283848586" + + "8788898A8B8C8D8E8F909192939495969798999A9B9C9D9E" + + "9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + + "C0C1C2C3C4C5C6" + + "C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDE" + + "DFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6"), true) { } } @@ -469,43 +484,41 @@ namespace Org.BouncyCastle.Crypto.Prng.Test internal class SHA384EntropyProvider : TestEntropySourceProvider { internal SHA384EntropyProvider() : base(Hex.Decode( - "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223242526" - + "2728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50515253545556" - + "5758595A5B5C5D5E5F606162636465666768696A6B6C6D6E" + - "808182838485868788898A8B8C8D8E" + - "8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6" + - "A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBE" + - "BFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6" + - "D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEE" + - "C0C1C2C3C4C5C6C7C8C9CACBCCCDCE" + - "CFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6" + - "E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFE" + - "FF000102030405060708090A0B0C0D0E0F10111213141516" + - "1718191A1B1C1D1E1F202122232425262728292A2B2C2D2E"), true) + "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223242526" + + "2728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50515253545556" + + "5758595A5B5C5D5E5F606162636465666768696A6B6C6D6E" + + "808182838485868788898A8B8C8D8E" + + "8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6" + + "A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBE" + + "BFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6" + + "D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEE" + + "C0C1C2C3C4C5C6C7C8C9CACBCCCDCE" + + "CFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6" + + "E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFE" + + "FF000102030405060708090A0B0C0D0E0F10111213141516" + + "1718191A1B1C1D1E1F202122232425262728292A2B2C2D2E"), true) { } } internal class SHA512EntropyProvider : TestEntropySourceProvider { - internal SHA512EntropyProvider() : - base(Hex.Decode( - "000102030405060708090A0B0C0D0E" + - "0F101112131415161718191A1B1C1D1E1F20212223242526" + - "2728292A2B2C2D2E2F303132333435363738393A3B3C3D3E" + - "3F404142434445464748494A4B4C4D4E4F50515253545556" + - "5758595A5B5C5D5E5F606162636465666768696A6B6C6D6E" + - "808182838485868788898A8B8C8D8E" + - "8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6" + - "A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBE" + - "BFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6" + - "D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEE" + - "C0C1C2C3C4C5C6C7C8C9CACBCCCDCE" + - "CFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6" + - "E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFE" + - "FF000102030405060708090A0B0C0D0E0F10111213141516" + - "1718191A1B1C1D1E1F202122232425262728292A2B2C2D2E"), true) - { - } + internal SHA512EntropyProvider() : base(Hex.Decode( + "000102030405060708090A0B0C0D0E" + + "0F101112131415161718191A1B1C1D1E1F20212223242526" + + "2728292A2B2C2D2E2F303132333435363738393A3B3C3D3E" + + "3F404142434445464748494A4B4C4D4E4F50515253545556" + + "5758595A5B5C5D5E5F606162636465666768696A6B6C6D6E" + + "808182838485868788898A8B8C8D8E" + + "8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6" + + "A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBE" + + "BFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6" + + "D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEE" + + "C0C1C2C3C4C5C6C7C8C9CACBCCCDCE" + + "CFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6" + + "E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFE" + + "FF000102030405060708090A0B0C0D0E0F10111213141516" + + "1718191A1B1C1D1E1F202122232425262728292A2B2C2D2E"), true) + { } } } } diff --git a/crypto/test/src/crypto/prng/test/HashDrbgTest.cs b/crypto/test/src/crypto/prng/test/HashDrbgTest.cs index d9776e0d6..892ca74da 100644 --- a/crypto/test/src/crypto/prng/test/HashDrbgTest.cs +++ b/crypto/test/src/crypto/prng/test/HashDrbgTest.cs @@ -1,10 +1,11 @@ using System; +using NUnit.Framework; + using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto.Prng.Drbg; using Org.BouncyCastle.Utilities.Test; using Org.BouncyCastle.Utilities.Encoders; -using NUnit.Framework; namespace Org.BouncyCastle.Crypto.Prng.Test { @@ -12,365 +13,371 @@ namespace Org.BouncyCastle.Crypto.Prng.Test * DRBG Test */ [TestFixture] - public class HashDrbgTest: SimpleTest + public class HashDrbgTest + : SimpleTest { - public override String Name - { - get - { - return "HashDRBG"; - } + public override string Name + { + get { return "HashDRBG"; } } - public static void main(String[] args) - { + public static void Main(string[] args) + { RunTest(new HashDrbgTest()); } - private DRBGTestVector[] createTestVectorData() - { - return new DRBGTestVector[] - { - new DRBGTestVector( - new Sha1Digest(), - new SHA1EntropyProvider().Get(440), - false, - "2021222324", - 80, - new String[] - { - "9F7CFF1ECA23E750F66326969F11800F12088BA68E441D15D888B3FE12BF66FE057494F4546DE2F1", - "B77AA5C0CD55BBCEED7574AF223AFD988C7EEC8EFF4A94E5E89D26A04F58FA79F5E0D3702D7A9A6A" - } - ), - new DRBGTestVector( + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); + + Assert.AreEqual(Name + ": Okay", resultText); + } + + private DrbgTestVector[] CreateTestVectorData() + { + return new DrbgTestVector[] + { + new DrbgTestVector( + new Sha1Digest(), + new SHA1EntropyProvider().Get(440), + false, + "2021222324", + 80, + new string[] + { + "9F7CFF1ECA23E750F66326969F11800F12088BA68E441D15D888B3FE12BF66FE057494F4546DE2F1", + "B77AA5C0CD55BBCEED7574AF223AFD988C7EEC8EFF4A94E5E89D26A04F58FA79F5E0D3702D7A9A6A" + } + ), + new DrbgTestVector( new Sha1Digest(), new SHA1EntropyProvider().Get(440), false, "2021222324", 80, - new String[] - { - "AB438BD3B01A0AF85CFEE29F7D7B71621C4908B909124D430E7B406FB1086EA994C582E0D656D989", - "29D9098F987E7005314A0F51B3DD2B8122F4AED706735DE6AD5DDBF223177C1E5F3AEBC52FAB90B9" - }) - .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F70717273747576"), - new DRBGTestVector( + new string[] + { + "AB438BD3B01A0AF85CFEE29F7D7B71621C4908B909124D430E7B406FB1086EA994C582E0D656D989", + "29D9098F987E7005314A0F51B3DD2B8122F4AED706735DE6AD5DDBF223177C1E5F3AEBC52FAB90B9" + }) + .SetPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F70717273747576"), + new DrbgTestVector( new Sha1Digest(), new SHA1EntropyProvider().Get(440), false, "2021222324", 80, - new String[] - { - "E76B4EDD5C865BC8AFD809A59B69B429AC7F4352A579BCF3F75E56249A3491F87C3CA6848B0FAB25", - "6577B6B4F87A93240B199FE51A3B335313683103DECE171E3256FB7E803586CA4E45DD242EB01F70" - }) - .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F90919293949596") - .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6"), - new DRBGTestVector( + new string[] + { + "E76B4EDD5C865BC8AFD809A59B69B429AC7F4352A579BCF3F75E56249A3491F87C3CA6848B0FAB25", + "6577B6B4F87A93240B199FE51A3B335313683103DECE171E3256FB7E803586CA4E45DD242EB01F70" + }) + .AddAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F90919293949596") + .AddAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6"), + new DrbgTestVector( new Sha1Digest(), new SHA1EntropyProvider().Get(440), true, "2021222324", 80, - new String[] - { - "56EF4913373994D5539F4D7D17AFE7448CDF5E72416CC6A71A340059FA0D5AE526B23250C46C0944", - "575B37A2739814F966C63B60A2C4F149CA9ACC84FC4B25493289B085C67B2E30F5F0B99A2C349E2A" - }), - new DRBGTestVector( + new string[] + { + "56EF4913373994D5539F4D7D17AFE7448CDF5E72416CC6A71A340059FA0D5AE526B23250C46C0944", + "575B37A2739814F966C63B60A2C4F149CA9ACC84FC4B25493289B085C67B2E30F5F0B99A2C349E2A" + }), + new DrbgTestVector( new Sha1Digest(), new SHA1EntropyProvider().Get(440), true, "2021222324", 80, - new String[] - { - "532CA1165DCFF21C55592687639884AF4BC4B057DF8F41DE653AB44E2ADEC7C9303E75ABE277EDBF", - "73C2C67C696D686D0C4DBCEB5C2AF7DDF6F020B6874FAE4390F102117ECAAFF54418529A367005A0" - }) - .setPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F70717273747576"), - new DRBGTestVector( + new string[] + { + "532CA1165DCFF21C55592687639884AF4BC4B057DF8F41DE653AB44E2ADEC7C9303E75ABE277EDBF", + "73C2C67C696D686D0C4DBCEB5C2AF7DDF6F020B6874FAE4390F102117ECAAFF54418529A367005A0" + }) + .SetPersonalizationString("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F70717273747576"), + new DrbgTestVector( new Sha1Digest(), new SHA1EntropyProvider().Get(440), true, "2021222324", 80, - new String[] - { - "183C242A1430E46C4ED70B4DBE1BF9AB0AB8721CDCA2A2D1820AD6F6C956858543B2AA191D8D1287", - "F196F9BD021C745CBD5AC7BFCE48EAAF0D0E7C091FBF436940E63A198EE770D9A4F0718669AF2BC9" - }) - .addAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F90919293949596") - .addAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6"), - new DRBGTestVector( + new string[] + { + "183C242A1430E46C4ED70B4DBE1BF9AB0AB8721CDCA2A2D1820AD6F6C956858543B2AA191D8D1287", + "F196F9BD021C745CBD5AC7BFCE48EAAF0D0E7C091FBF436940E63A198EE770D9A4F0718669AF2BC9" + }) + .AddAdditionalInput("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F90919293949596") + .AddAdditionalInput("A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6"), + new DrbgTestVector( new Sha256Digest(), new SHA256EntropyProvider().Get(440), false, "2021222324252627", 128, - new String[] - { - "77E05A0E7DC78AB5D8934D5E93E82C06" + - "A07C04CEE6C9C53045EEB485872777CF3B3E35C474F976B8" + - "94BF301A86FA651F463970E89D4A0534B2ECAD29EC044E7E", - "5FF4BA493C40CFFF3B01E472C575668C" + - "CE3880B9290B05BFEDE5EC96ED5E9B2898508B09BC800EEE" + - "099A3C90602ABD4B1D4F343D497C6055C87BB956D53BF351" - } + new string[] + { + "77E05A0E7DC78AB5D8934D5E93E82C06" + + "A07C04CEE6C9C53045EEB485872777CF3B3E35C474F976B8" + + "94BF301A86FA651F463970E89D4A0534B2ECAD29EC044E7E", + "5FF4BA493C40CFFF3B01E472C575668C" + + "CE3880B9290B05BFEDE5EC96ED5E9B2898508B09BC800EEE" + + "099A3C90602ABD4B1D4F343D497C6055C87BB956D53BF351" + } ), - new DRBGTestVector( + new DrbgTestVector( new Sha256Digest(), new SHA256EntropyProvider().Get(440), true, "2021222324252627", 128, - new String[] - { - "92275523C70E567BCF9B35EC50B933F8" + - "12616DF586B7F72EE1BC7735A5C2654373CBBC72316DFF84" + - "20A33BF02B97AC8D1952583F270ACD7005CC027F4CF1187E", - "681A46B2AA8694A0FE4DEEA720927A84" + - "EAAA985E59C19F8BE0984D8CBEF8C69B754167641946E040" + - "EE2043E1CCB29DCF063C0A50830E428E6DCA262ECD77C542" - }), - new DRBGTestVector( - new Sha384Digest(), - new SHA384EntropyProvider().Get(888), - false, - "202122232425262728292A2B", - 192, - new String[] - { - "04FF23AD15E78790ADD36B438BBC097C7A11747CC2CCEEDE" + - "2C978B23B3DC63B732C953061D7764990ABFEFC47A581B92" + - "1BC0428C4F12212460E406A0F0651E7F0CB9A90ABFDB07B5" + - "25565C74F0AA085082F6CF213AAFAD0C0646895078F1E1FE", - "4F35B85F95DEE3E873054905CFD02341653E18F529930CBE" + - "14D909F37FEAF2C790D22FAE7516B4590BE35D53E2FE1A35" + - "AFE4B6607CB358589C3B4D094A1D81FE0717F1DF5BDDEB3E" + - "114F130BB781E66C22B5B770E8AE115FF39F8ADAF66DEEDF" - } - ), - new DRBGTestVector( - new Sha384Digest(), - new SHA384EntropyProvider().Get(888), - true, - "202122232425262728292A2B", - 192, - new String[] - { - "97993B78F7C31C0E876DC92EB7D6C408E09D608AD6B99D0E" + - "A2229B05A578C426334FCC8A1C7E676ED2D89A5B4CDF5B3F" + - "4ADF11936BF14F4E10909DBA9C24F4FDFFDE72351DA8E2CC" + - "3B135A395373899E5F1A5955B880CA9B9E9DD4C9CA7FA4D4", - "F5983946320E36C64EF283CA1F65D197CF81624EC6778E77" + - "0E78949D84EF21A45CDD62D1DB76920D4C2836FC6AE5299F" + - "AF1357D9701FAD10FBD88D1E2832239436D76EB271BDC3CA" + - "04425EC88BC0E89A4D5C37FFCE7C6C3ABDE9C413AE6D3FEA" - } - ), - new DRBGTestVector( - new Sha512Digest(), - new SHA512EntropyProvider().Get(888), - false, - "202122232425262728292A2B2C2D2E2F", - 256, - new String[] - { - "DA126CF95C6BF97E" + - "2F731F2137A907ACC70FD7AC9EBACD1C6E31C74029B052E3" + - "AABC48F3B00993F2B2381F7650A55322A968C86E05DE88E6" + - "367F6EF89A601DB4342E9086C7AC13B5E56C32E9E668040B" + - "73847893C5BFD38A1CF44F348B4EEE4CD68ADB7E7B8C837F" + - "19BC4F902761F7CFF24AB1D704FD11C4E929D8553753B55D", - "400B977CE8A2BB6A" + - "84C6FD1CF901459685ABF5408CFF4588CEDF52E2D2DC300A" + - "A9B4FAED8CD0161C2172B1FD269253195883D6EBF21020F2" + - "C20E5F2C81AE60C8595B834A229B1F5B726C1125717E6207" + - "8886EF38E61E32707AD5F8116C6393DFB6E7C7AE0E8E92BB" + - "D7E0C3D04BBA02F5169F2F569A58158915FEE4C9D28D45DB" - } - ) - .setPersonalizationString( - "404142434445464748494A4B4C4D4E" + - "4F505152535455565758595A5B5C5D5E5F60616263646566" + - "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + - "7F808182838485868788898A8B8C8D8E8F90919293949596" + - "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE") - .addAdditionalInput( - "606162636465666768696A6B6C6D6E" + - "6F707172737475767778797A7B7C7D7E7F80818283848586" + - "8788898A8B8C8D8E8F909192939495969798999A9B9C9D9E" + - "9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + - "B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCE") - .addAdditionalInput( - "A0A1A2A3A4A5A6A7A8A9AAABACADAE" + - "AFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6" + - "C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDE" + - "DFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6" + - "F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E"), - new DRBGTestVector( - new Sha512Digest(), - new SHA512EntropyProvider().Get(888), - true, - "202122232425262728292A2B2C2D2E2F", - 256, - new String[] - { - "F93CA6855590A77F" + - "07354097E90E026648B6115DF008FFEDBD9D9811F54E8286" + - "EF00FDD6BA1E58DF2535E3FBDD9A9BA3754A97F36EE83322" + - "1582060A1F37FCE4EE8826636B28EAD589593F4CA8B64738" + - "8F24EB3F0A34796968D21BDEE6F81FD5DF93536F935937B8" + - "025EC8CBF57DDB0C61F2E41463CC1516D657DA2829C6BF90", - "4817618F48C60FB1" + - "CE5BFBDA0CAF4591882A31F6EE3FE0F78779992A06EC60F3" + - "7FB9A8D6108C231F0A927754B0599FA4FA27A4E25E065EF0" + - "3085B892979DC0E7A1080883CAEBFDFD3665A8F2D061C521" + - "F7D6E3DA2AF8B97B6B43B6EC831AF515070A83BBB9AC95ED" + - "4EF49B756A2377A5F0833D847E27A88DDB0C2CE4AD782E7B " - } - ), - new DRBGTestVector( - new Sha512Digest(), - new SHA512EntropyProvider().Get(888), - true, - "202122232425262728292A2B2C2D2E2F", - 256, - new String[] - { - "0455DD4AD7DBACB2" + - "410BE58DF7248D765A4547ABAEE1743B0BCAD37EBD06DA7C" + - "F7CE5E2216E525327E9E2005EBEF2CE53BD733B18128627D" + - "3FD6153089373AF2606A1584646A0EA488BFEF45228699A0" + - "89CEA8AEC44502D86D9591F3552C688B7F7B45FCB0C3C2B9" + - "43C1CD8A6FC63DF4D81C3DA543C9CF2843855EA84E4F959C", - "C047D46D7F614E4E" + - "4A7952C79A451F8F7ACA379967E2977C401C626A2ED70D74" + - "A63660579A354115BC8C8C8CC3AEA3050686A0CFCDB6FA9C" + - "F78D4C2165BAF851C6F9B1CD16A2E14C15C6DAAC56C16E75" + - "FC84A14D58B41622E88B0F1B1995587FD8BAA999CBA98025" + - "4C8AB9A9691DF7B84D88B639A9A3106DEABEB63748B99C09" - } - ) - .addAdditionalInput( + new string[] + { + "92275523C70E567BCF9B35EC50B933F8" + + "12616DF586B7F72EE1BC7735A5C2654373CBBC72316DFF84" + + "20A33BF02B97AC8D1952583F270ACD7005CC027F4CF1187E", + "681A46B2AA8694A0FE4DEEA720927A84" + + "EAAA985E59C19F8BE0984D8CBEF8C69B754167641946E040" + + "EE2043E1CCB29DCF063C0A50830E428E6DCA262ECD77C542" + }), + new DrbgTestVector( + new Sha384Digest(), + new SHA384EntropyProvider().Get(888), + false, + "202122232425262728292A2B", + 192, + new string[] + { + "04FF23AD15E78790ADD36B438BBC097C7A11747CC2CCEEDE" + + "2C978B23B3DC63B732C953061D7764990ABFEFC47A581B92" + + "1BC0428C4F12212460E406A0F0651E7F0CB9A90ABFDB07B5" + + "25565C74F0AA085082F6CF213AAFAD0C0646895078F1E1FE", + "4F35B85F95DEE3E873054905CFD02341653E18F529930CBE" + + "14D909F37FEAF2C790D22FAE7516B4590BE35D53E2FE1A35" + + "AFE4B6607CB358589C3B4D094A1D81FE0717F1DF5BDDEB3E" + + "114F130BB781E66C22B5B770E8AE115FF39F8ADAF66DEEDF" + } + ), + new DrbgTestVector( + new Sha384Digest(), + new SHA384EntropyProvider().Get(888), + true, + "202122232425262728292A2B", + 192, + new string[] + { + "97993B78F7C31C0E876DC92EB7D6C408E09D608AD6B99D0E" + + "A2229B05A578C426334FCC8A1C7E676ED2D89A5B4CDF5B3F" + + "4ADF11936BF14F4E10909DBA9C24F4FDFFDE72351DA8E2CC" + + "3B135A395373899E5F1A5955B880CA9B9E9DD4C9CA7FA4D4", + "F5983946320E36C64EF283CA1F65D197CF81624EC6778E77" + + "0E78949D84EF21A45CDD62D1DB76920D4C2836FC6AE5299F" + + "AF1357D9701FAD10FBD88D1E2832239436D76EB271BDC3CA" + + "04425EC88BC0E89A4D5C37FFCE7C6C3ABDE9C413AE6D3FEA" + } + ), + new DrbgTestVector( + new Sha512Digest(), + new SHA512EntropyProvider().Get(888), + false, + "202122232425262728292A2B2C2D2E2F", + 256, + new string[] + { + "DA126CF95C6BF97E" + + "2F731F2137A907ACC70FD7AC9EBACD1C6E31C74029B052E3" + + "AABC48F3B00993F2B2381F7650A55322A968C86E05DE88E6" + + "367F6EF89A601DB4342E9086C7AC13B5E56C32E9E668040B" + + "73847893C5BFD38A1CF44F348B4EEE4CD68ADB7E7B8C837F" + + "19BC4F902761F7CFF24AB1D704FD11C4E929D8553753B55D", + "400B977CE8A2BB6A" + + "84C6FD1CF901459685ABF5408CFF4588CEDF52E2D2DC300A" + + "A9B4FAED8CD0161C2172B1FD269253195883D6EBF21020F2" + + "C20E5F2C81AE60C8595B834A229B1F5B726C1125717E6207" + + "8886EF38E61E32707AD5F8116C6393DFB6E7C7AE0E8E92BB" + + "D7E0C3D04BBA02F5169F2F569A58158915FEE4C9D28D45DB" + } + ) + .SetPersonalizationString( + "404142434445464748494A4B4C4D4E" + + "4F505152535455565758595A5B5C5D5E5F60616263646566" + + "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + + "7F808182838485868788898A8B8C8D8E8F90919293949596" + + "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE") + .AddAdditionalInput( "606162636465666768696A6B6C6D6E" + "6F707172737475767778797A7B7C7D7E7F80818283848586" + "8788898A8B8C8D8E8F909192939495969798999A9B9C9D9E" + "9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + "B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCE") - .addAdditionalInput( + .AddAdditionalInput( "A0A1A2A3A4A5A6A7A8A9AAABACADAE" + "AFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6" + "C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDE" + "DFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6" + "F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E"), - new DRBGTestVector( - new Sha512Digest(), - new SHA512EntropyProvider().Get(888), - true, - "202122232425262728292A2B2C2D2E2F", - 256, - new String[] - { - "22EB93A67911DA73" + - "85D9180C78127DE1A04FF713114C07C9C615F7CC5EF72744" + - "A2DDCD7C3CB85E65DED8EF5F240FBDCBEBBDE2BAAC8ECF7D" + - "CBC8AC333E54607AD41DC495D83DF72A05EF55B127C1441C" + - "9A0EFFDA2C7954DB6C2D04342EB812E5E0B11D6C395F41ED" + - "A2702ECE5BA479E2DFA18F953097492636C12FE30CE5C968", - "E66698CFBF1B3F2E" + - "919C03036E584EAA81CF1C6666240AF05F70637043733954" + - "D8A1E5A66A04C53C6900FDC145D4A3A80A31F5868ACE9AC9" + - "4E14E2051F624A05EEA1F8B684AA5410BCE315E76EA07C71" + - "5D6F34731320FF0DCF78D795E6EFA2DF92B98BE636CDFBA2" + - "9008DD392112AEC202F2E481CB9D83F987FEA69CD1B368BB" - } - ) - .setPersonalizationString( - "404142434445464748494A4B4C4D4E" + - "4F505152535455565758595A5B5C5D5E5F60616263646566" + - "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + - "7F808182838485868788898A8B8C8D8E8F90919293949596" + - "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE"), - new DRBGTestVector( - new Sha512Digest(), - new SHA512EntropyProvider().Get(888), - true, - "202122232425262728292A2B2C2D2E2F", - 256, - new String[] - { - "7596A76372308BD5" + - "A5613439934678B35521A94D81ABFE63A21ACF61ABB88B61" + - "E86A12C37F308F2BBBE32BE4B38D03AE808386494D70EF52" + - "E9E1365DD18B7784CAB826F31D47579E4D57F69D8BF3152B" + - "95741946CEBE58571DF58ED39980D9AF44E69F01E8989759" + - "8E40171101A0E3302838E0AD9E849C01988993CF9F6E5263", - "DBE5EE36FCD85301" + - "303E1C3617C1AC5E23C08885D0BEFAAD0C85A0D89F85B9F1" + - "6ECE3D88A24EB96504F2F13EFA7049621782F5DE2C416A0D" + - "294CCFE53545C4E309C48E1E285A2B829A574B72B3C2FBE1" + - "34D01E3706B486F2401B9820E17298A342666918E15B8462" + - "87F8C5AF2D96B20FAF3D0BB392E15F4A06CDB0DECD1B6AD7" - } - ) - .setPersonalizationString( - "404142434445464748494A4B4C4D4E" + - "4F505152535455565758595A5B5C5D5E5F60616263646566" + - "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + - "7F808182838485868788898A8B8C8D8E8F90919293949596" + - "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE") - .addAdditionalInput( - "606162636465666768696A6B6C6D6E" + - "6F707172737475767778797A7B7C7D7E7F80818283848586" + - "8788898A8B8C8D8E8F909192939495969798999A9B9C9D9E" + - "9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + - "B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCE") - .addAdditionalInput( - "A0A1A2A3A4A5A6A7A8A9AAABACADAE" + - "AFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6" + - "C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDE" + - "DFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6" + - "F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E") + new DrbgTestVector( + new Sha512Digest(), + new SHA512EntropyProvider().Get(888), + true, + "202122232425262728292A2B2C2D2E2F", + 256, + new string[] + { + "F93CA6855590A77F" + + "07354097E90E026648B6115DF008FFEDBD9D9811F54E8286" + + "EF00FDD6BA1E58DF2535E3FBDD9A9BA3754A97F36EE83322" + + "1582060A1F37FCE4EE8826636B28EAD589593F4CA8B64738" + + "8F24EB3F0A34796968D21BDEE6F81FD5DF93536F935937B8" + + "025EC8CBF57DDB0C61F2E41463CC1516D657DA2829C6BF90", + "4817618F48C60FB1" + + "CE5BFBDA0CAF4591882A31F6EE3FE0F78779992A06EC60F3" + + "7FB9A8D6108C231F0A927754B0599FA4FA27A4E25E065EF0" + + "3085B892979DC0E7A1080883CAEBFDFD3665A8F2D061C521" + + "F7D6E3DA2AF8B97B6B43B6EC831AF515070A83BBB9AC95ED" + + "4EF49B756A2377A5F0833D847E27A88DDB0C2CE4AD782E7B " + } + ), + new DrbgTestVector( + new Sha512Digest(), + new SHA512EntropyProvider().Get(888), + true, + "202122232425262728292A2B2C2D2E2F", + 256, + new string[] + { + "0455DD4AD7DBACB2" + + "410BE58DF7248D765A4547ABAEE1743B0BCAD37EBD06DA7C" + + "F7CE5E2216E525327E9E2005EBEF2CE53BD733B18128627D" + + "3FD6153089373AF2606A1584646A0EA488BFEF45228699A0" + + "89CEA8AEC44502D86D9591F3552C688B7F7B45FCB0C3C2B9" + + "43C1CD8A6FC63DF4D81C3DA543C9CF2843855EA84E4F959C", + "C047D46D7F614E4E" + + "4A7952C79A451F8F7ACA379967E2977C401C626A2ED70D74" + + "A63660579A354115BC8C8C8CC3AEA3050686A0CFCDB6FA9C" + + "F78D4C2165BAF851C6F9B1CD16A2E14C15C6DAAC56C16E75" + + "FC84A14D58B41622E88B0F1B1995587FD8BAA999CBA98025" + + "4C8AB9A9691DF7B84D88B639A9A3106DEABEB63748B99C09" + } + ) + .AddAdditionalInput( + "606162636465666768696A6B6C6D6E" + + "6F707172737475767778797A7B7C7D7E7F80818283848586" + + "8788898A8B8C8D8E8F909192939495969798999A9B9C9D9E" + + "9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + + "B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCE") + .AddAdditionalInput( + "A0A1A2A3A4A5A6A7A8A9AAABACADAE" + + "AFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6" + + "C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDE" + + "DFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6" + + "F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E"), + new DrbgTestVector( + new Sha512Digest(), + new SHA512EntropyProvider().Get(888), + true, + "202122232425262728292A2B2C2D2E2F", + 256, + new string[] + { + "22EB93A67911DA73" + + "85D9180C78127DE1A04FF713114C07C9C615F7CC5EF72744" + + "A2DDCD7C3CB85E65DED8EF5F240FBDCBEBBDE2BAAC8ECF7D" + + "CBC8AC333E54607AD41DC495D83DF72A05EF55B127C1441C" + + "9A0EFFDA2C7954DB6C2D04342EB812E5E0B11D6C395F41ED" + + "A2702ECE5BA479E2DFA18F953097492636C12FE30CE5C968", + "E66698CFBF1B3F2E" + + "919C03036E584EAA81CF1C6666240AF05F70637043733954" + + "D8A1E5A66A04C53C6900FDC145D4A3A80A31F5868ACE9AC9" + + "4E14E2051F624A05EEA1F8B684AA5410BCE315E76EA07C71" + + "5D6F34731320FF0DCF78D795E6EFA2DF92B98BE636CDFBA2" + + "9008DD392112AEC202F2E481CB9D83F987FEA69CD1B368BB" + } + ) + .SetPersonalizationString( + "404142434445464748494A4B4C4D4E" + + "4F505152535455565758595A5B5C5D5E5F60616263646566" + + "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + + "7F808182838485868788898A8B8C8D8E8F90919293949596" + + "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE"), + new DrbgTestVector( + new Sha512Digest(), + new SHA512EntropyProvider().Get(888), + true, + "202122232425262728292A2B2C2D2E2F", + 256, + new string[] + { + "7596A76372308BD5" + + "A5613439934678B35521A94D81ABFE63A21ACF61ABB88B61" + + "E86A12C37F308F2BBBE32BE4B38D03AE808386494D70EF52" + + "E9E1365DD18B7784CAB826F31D47579E4D57F69D8BF3152B" + + "95741946CEBE58571DF58ED39980D9AF44E69F01E8989759" + + "8E40171101A0E3302838E0AD9E849C01988993CF9F6E5263", + "DBE5EE36FCD85301" + + "303E1C3617C1AC5E23C08885D0BEFAAD0C85A0D89F85B9F1" + + "6ECE3D88A24EB96504F2F13EFA7049621782F5DE2C416A0D" + + "294CCFE53545C4E309C48E1E285A2B829A574B72B3C2FBE1" + + "34D01E3706B486F2401B9820E17298A342666918E15B8462" + + "87F8C5AF2D96B20FAF3D0BB392E15F4A06CDB0DECD1B6AD7" + } + ) + .SetPersonalizationString( + "404142434445464748494A4B4C4D4E" + + "4F505152535455565758595A5B5C5D5E5F60616263646566" + + "6768696A6B6C6D6E6F707172737475767778797A7B7C7D7E" + + "7F808182838485868788898A8B8C8D8E8F90919293949596" + + "9798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAE") + .AddAdditionalInput( + "606162636465666768696A6B6C6D6E" + + "6F707172737475767778797A7B7C7D7E7F80818283848586" + + "8788898A8B8C8D8E8F909192939495969798999A9B9C9D9E" + + "9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + + "B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCE") + .AddAdditionalInput( + "A0A1A2A3A4A5A6A7A8A9AAABACADAE" + + "AFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6" + + "C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDE" + + "DFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6" + + "F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E") }; } public override void PerformTest() { - DRBGTestVector[] tests = createTestVectorData(); - SP80090Drbg d; + DrbgTestVector[] tests = CreateTestVectorData(); + ISP80090Drbg d; for (int i = 0; i != tests.Length; i++) { - DRBGTestVector tv = tests[i]; + DrbgTestVector tv = tests[i]; - byte[] nonce = tv.nonce(); - byte[] personalisationString = tv.personalizationString(); + byte[] nonce = tv.GetNonce(); + byte[] personalisationString = tv.GetPersonalizationString(); - d = new HashSP800Drbg(tv.getDigest(), tv.securityStrength(), tv.entropySource(), personalisationString, nonce); + d = new HashSP800Drbg(tv.Digest, tv.SecurityStrength, tv.EntropySource, personalisationString, nonce); - byte[] output = new byte[tv.expectedValue(0).Length]; + byte[] output = new byte[tv.GetExpectedValue(0).Length]; - d.Generate(output, tv.additionalInput(0), tv.predictionResistance()); + d.Generate(output, tv.GetAdditionalInput(0), tv.PredictionResistance); - byte[] expected = tv.expectedValue(0); + byte[] expected = tv.GetExpectedValue(0); if (!AreEqual(expected, output)) { - Fail("Test #" + (i + 1) + ".1 failed, expected " + Hex.ToHexString(tv.expectedValue(0)) + " got " + Hex.ToHexString(output)); + Fail("Test #" + (i + 1) + ".1 failed, expected " + Hex.ToHexString(tv.GetExpectedValue(0)) + " got " + Hex.ToHexString(output)); } - output = new byte[tv.expectedValue(0).Length]; + output = new byte[tv.GetExpectedValue(0).Length]; - d.Generate(output, tv.additionalInput(1), tv.predictionResistance()); + d.Generate(output, tv.GetAdditionalInput(1), tv.PredictionResistance); - expected = tv.expectedValue(1); + expected = tv.GetExpectedValue(1); if (!AreEqual(expected, output)) { - Fail("Test #" + (i + 1) + ".2 failed, expected " + Hex.ToHexString(tv.expectedValue(1)) + " got " + Hex.ToHexString(output)); + Fail("Test #" + (i + 1) + ".2 failed, expected " + Hex.ToHexString(tv.GetExpectedValue(1)) + " got " + Hex.ToHexString(output)); } } @@ -403,69 +410,68 @@ namespace Org.BouncyCastle.Crypto.Prng.Test } } - internal class SHA1EntropyProvider: TestEntropySourceProvider - { - internal SHA1EntropyProvider(): base( - Hex.Decode( - "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F30313233343536" - + "808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" - + "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6"), true) - {} - } + internal class SHA1EntropyProvider : TestEntropySourceProvider + { + internal SHA1EntropyProvider() : base(Hex.Decode( + "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F30313233343536" + + "808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + + "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6"), true) + {} + } - internal class SHA256EntropyProvider: TestEntropySourceProvider - { - internal SHA256EntropyProvider(): base(Hex.Decode( + internal class SHA256EntropyProvider : TestEntropySourceProvider + { + internal SHA256EntropyProvider() : base(Hex.Decode( "00010203040506" + - "0708090A0B0C0D0E0F101112131415161718191A1B1C1D1E" + - "1F202122232425262728292A2B2C2D2E2F30313233343536" + - "80818283848586" + - "8788898A8B8C8D8E8F909192939495969798999A9B9C9D9E" + - "9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + - "C0C1C2C3C4C5C6" + - "C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDE" + - "DFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6"), true) - { } - } + "0708090A0B0C0D0E0F101112131415161718191A1B1C1D1E" + + "1F202122232425262728292A2B2C2D2E2F30313233343536" + + "80818283848586" + + "8788898A8B8C8D8E8F909192939495969798999A9B9C9D9E" + + "9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6" + + "C0C1C2C3C4C5C6" + + "C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDE" + + "DFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6"), true) + { } + } - internal class SHA384EntropyProvider: TestEntropySourceProvider - { - internal SHA384EntropyProvider(): base(Hex.Decode( - "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223242526" - + "2728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50515253545556" - + "5758595A5B5C5D5E5F606162636465666768696A6B6C6D6E" + - "808182838485868788898A8B8C8D8E" + - "8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6" + - "A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBE" + - "BFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6" + - "D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEE" + - "C0C1C2C3C4C5C6C7C8C9CACBCCCDCE" + - "CFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6" + - "E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFE" + - "FF000102030405060708090A0B0C0D0E0F10111213141516" + - "1718191A1B1C1D1E1F202122232425262728292A2B2C2D2E"), true) - {} - } + internal class SHA384EntropyProvider : TestEntropySourceProvider + { + internal SHA384EntropyProvider() : base(Hex.Decode( + "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223242526" + + "2728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50515253545556" + + "5758595A5B5C5D5E5F606162636465666768696A6B6C6D6E" + + "808182838485868788898A8B8C8D8E" + + "8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6" + + "A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBE" + + "BFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6" + + "D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEE" + + "C0C1C2C3C4C5C6C7C8C9CACBCCCDCE" + + "CFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6" + + "E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFE" + + "FF000102030405060708090A0B0C0D0E0F10111213141516" + + "1718191A1B1C1D1E1F202122232425262728292A2B2C2D2E"), true) + {} + } - internal class SHA512EntropyProvider: TestEntropySourceProvider - { - internal SHA512EntropyProvider(): base(Hex.Decode( + internal class SHA512EntropyProvider : TestEntropySourceProvider + { + internal SHA512EntropyProvider() : base(Hex.Decode( "000102030405060708090A0B0C0D0E" + - "0F101112131415161718191A1B1C1D1E1F20212223242526" + - "2728292A2B2C2D2E2F303132333435363738393A3B3C3D3E" + - "3F404142434445464748494A4B4C4D4E4F50515253545556" + - "5758595A5B5C5D5E5F606162636465666768696A6B6C6D6E" + - "808182838485868788898A8B8C8D8E" + - "8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6" + - "A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBE" + - "BFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6" + - "D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEE" + - "C0C1C2C3C4C5C6C7C8C9CACBCCCDCE" + - "CFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6" + - "E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFE" + - "FF000102030405060708090A0B0C0D0E0F10111213141516" + - "1718191A1B1C1D1E1F202122232425262728292A2B2C2D2E"), true) - { } + "0F101112131415161718191A1B1C1D1E1F20212223242526" + + "2728292A2B2C2D2E2F303132333435363738393A3B3C3D3E" + + "3F404142434445464748494A4B4C4D4E4F50515253545556" + + "5758595A5B5C5D5E5F606162636465666768696A6B6C6D6E" + + "808182838485868788898A8B8C8D8E" + + "8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6" + + "A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBE" + + "BFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6" + + "D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEE" + + "C0C1C2C3C4C5C6C7C8C9CACBCCCDCE" + + "CFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6" + + "E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFE" + + "FF000102030405060708090A0B0C0D0E0F10111213141516" + + "1718191A1B1C1D1E1F202122232425262728292A2B2C2D2E"), true) + { } + } } } -} diff --git a/crypto/test/src/crypto/prng/test/TestEntropySourceProvider.cs b/crypto/test/src/crypto/prng/test/TestEntropySourceProvider.cs index a37bcd844..647799630 100644 --- a/crypto/test/src/crypto/prng/test/TestEntropySourceProvider.cs +++ b/crypto/test/src/crypto/prng/test/TestEntropySourceProvider.cs @@ -2,7 +2,8 @@ namespace Org.BouncyCastle.Crypto.Prng.Test { - public class TestEntropySourceProvider: IEntropySourceProvider + public class TestEntropySourceProvider + : IEntropySourceProvider { private readonly byte[] data; private readonly bool isPredictionResistant; @@ -18,7 +19,8 @@ namespace Org.BouncyCastle.Crypto.Prng.Test return new EntropySource(bitsRequired, data, isPredictionResistant); } - internal class EntropySource: IEntropySource + internal class EntropySource + : IEntropySource { private readonly int bitsRequired; private readonly byte[] data; @@ -35,30 +37,21 @@ namespace Org.BouncyCastle.Crypto.Prng.Test public bool IsPredictionResistant { - get - { - return isPredictionResistant; - } + get { return isPredictionResistant; } } public byte[] GetEntropy() { byte[] rv = new byte[bitsRequired / 8]; - Array.Copy(data, index, rv, 0, rv.Length); - index += bitsRequired / 8; - return rv; } public int EntropySize { - get - { - return bitsRequired; - } + get { return bitsRequired; } } + } } } -} diff --git a/crypto/test/src/crypto/prng/test/X931Test.cs b/crypto/test/src/crypto/prng/test/X931Test.cs new file mode 100644 index 000000000..1132ea34a --- /dev/null +++ b/crypto/test/src/crypto/prng/test/X931Test.cs @@ -0,0 +1,137 @@ +using System; + +using NUnit.Framework; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.Test; + +namespace Org.BouncyCastle.Crypto.Prng.Test +{ + /** + * HMAC SP800-90 DRBG + */ + [TestFixture] + public class X931Test + : SimpleTest + { + public override string Name + { + get { return "X931"; } + } + + public static void Main(string[] args) + { + RunTest(new X931Test()); + } + + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); + + Assert.AreEqual(Name + ": Okay", resultText); + } + + private X931TestVector[] CreateTestVectorData() + { + return new X931TestVector[] + { + new X931TestVector( + new AesEngine(), + new Aes128EntropyProvider(), + "f7d36762b9915f1ed585eb8e91700eb2", + "259e67249288597a4d61e7c0e690afae", + false, + new string[] + { + "15f013af5a8e9df9a8e37500edaeac43", + "a9d74bb1c90a222adc398546d64879cf", + "0379e404042d58180764fb9e6c5d94bb", + "3c74603e036d28c79947ffb56fee4e51", + "e872101a4df81ebbe1e632fc87195d52", + "26a6b3d33b8e7e68b75d9630ec036314" + }), + new X931TestVector( + new DesEdeEngine(), + new TDesEntropyProvider(), + "ef16ec643e5db5892cbc6eabba310b3410e6f8759e3e382c", + "55df103deaf68dc4", + false, + new string[] + { + "9c960bb9662ce6de", + "d9d0e527fd0931da", + "3e2db9994e9e6995", + "0e3868aef8218cf7", + "7b0b0ca137f8fd81", + "f657df270ad12265" + }) + }; + } + + public override void PerformTest() + { + X931TestVector[] vectors = CreateTestVectorData(); + + for (int i = 0; i != vectors.Length; i++) + { + X931TestVector tv = vectors[i]; + X931SecureRandomBuilder bld = new X931SecureRandomBuilder(tv.EntropyProvider); + + bld.SetDateTimeVector(Hex.Decode(tv.DateTimeVector)); + + SecureRandom rand = bld.Build(tv.Engine, new KeyParameter(Hex.Decode(tv.Key)), tv.IsPredictionResistant); + + for (int j = 0; j != tv.Expected.Length - 1; j++) + { + byte[] expected = Hex.Decode(tv.Expected[j]); + byte[] res = new byte[expected.Length]; + + rand.NextBytes(res); + + if (!Arrays.AreEqual(expected, res)) + { + Fail("expected output wrong [" + j + "] got : " + Strings.FromByteArray(Hex.Encode(res))); + } + } + + { + byte[] expected = Hex.Decode(tv.Expected[tv.Expected.Length - 1]); + byte[] res = new byte[expected.Length]; + + for (int j = tv.Expected.Length - 1; j != 10000; j++) + { + rand.NextBytes(res); + } + + if (!Arrays.AreEqual(expected, res)) + { + Fail("expected output wrong [" + 10000 + "] got : " + Strings.FromByteArray(Hex.Encode(res))); + } + } + } + } + + private class Aes128EntropyProvider + : TestEntropySourceProvider + { + internal Aes128EntropyProvider() + : base(Hex.Decode("35cc0ea481fc8a4f5f05c7d4667233b2"), true) + { + } + } + + private class TDesEntropyProvider + : TestEntropySourceProvider + { + internal TDesEntropyProvider() + : base(Hex.Decode("96d872b9122c5e74"), true) + { + } + } + } +} diff --git a/crypto/test/src/crypto/prng/test/X931TestVector.cs b/crypto/test/src/crypto/prng/test/X931TestVector.cs new file mode 100644 index 000000000..e641b0a66 --- /dev/null +++ b/crypto/test/src/crypto/prng/test/X931TestVector.cs @@ -0,0 +1,55 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Prng.Test +{ + public class X931TestVector + { + private readonly IBlockCipher engine; + private readonly IEntropySourceProvider entropyProvider; + private readonly string key; + private readonly string dateTimeVector; + private readonly bool predictionResistant; + private readonly string[] expected; + + public X931TestVector(IBlockCipher engine, IEntropySourceProvider entropyProvider, string key, string dateTimeVector, + bool predictionResistant, string[] expected) + { + this.engine = engine; + this.entropyProvider = entropyProvider; + this.key = key; + this.dateTimeVector = dateTimeVector; + this.predictionResistant = predictionResistant; + this.expected = expected; + } + + public string DateTimeVector + { + get { return dateTimeVector; } + } + + public IBlockCipher Engine + { + get { return engine; } + } + + public IEntropySourceProvider EntropyProvider + { + get { return entropyProvider; } + } + + public string[] Expected + { + get { return expected; } + } + + public string Key + { + get { return key; } + } + + public bool IsPredictionResistant + { + get { return predictionResistant; } + } + } +} |