Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Hook <dgh@cryptoworkshop.com>2013-05-11 03:48:37 +0400
committerDavid Hook <dgh@cryptoworkshop.com>2013-05-11 03:48:37 +0400
commitf733f717fb13387a61dedc0a57d23487069d9b67 (patch)
tree6f32fad65a2fb78fb2aab2986a38553bce706e44
parent299db0910a5a58f737d6feaa3386229a6135791d (diff)
refactoring.
-rw-r--r--src/main/java/org/bouncycastle/crypto/prng/DRBGProvider.java8
-rw-r--r--src/main/java/org/bouncycastle/crypto/prng/SP800SecureRandom.java (renamed from src/main/java/org/bouncycastle/crypto/random/SP800SecureRandom.java)12
-rw-r--r--src/main/java/org/bouncycastle/crypto/prng/SP800SecureRandomBuilder.java (renamed from src/main/java/org/bouncycastle/crypto/random/SP800SecureRandomBuilder.java)15
-rw-r--r--src/main/java/org/bouncycastle/crypto/prng/VMPCRandomGenerator.java1
-rw-r--r--src/main/java/org/bouncycastle/crypto/prng/drbg/CTRSP800DRBG.java (renamed from src/main/java/org/bouncycastle/crypto/prng/CTRSP800DRBG.java)5
-rw-r--r--src/main/java/org/bouncycastle/crypto/prng/drbg/DualECSP800DRBG.java (renamed from src/main/java/org/bouncycastle/crypto/prng/DualECSP800DRBG.java)5
-rw-r--r--src/main/java/org/bouncycastle/crypto/prng/drbg/HMacSP800DRBG.java (renamed from src/main/java/org/bouncycastle/crypto/prng/HMacSP800DRBG.java)3
-rw-r--r--src/main/java/org/bouncycastle/crypto/prng/drbg/HashSP800DRBG.java (renamed from src/main/java/org/bouncycastle/crypto/prng/HashSP800DRBG.java)611
-rw-r--r--src/main/java/org/bouncycastle/crypto/prng/drbg/SP80090DRBG.java (renamed from src/main/java/org/bouncycastle/crypto/prng/SP80090DRBG.java)2
-rw-r--r--src/main/java/org/bouncycastle/crypto/prng/package.html2
-rw-r--r--src/main/java/org/bouncycastle/crypto/random/DRBGProvider.java9
-rw-r--r--src/test/java/org/bouncycastle/crypto/random/test/SP800RandomTest.java2
-rw-r--r--src/test/java/org/bouncycastle/crypto/test/CTRDRBGTest.java4
-rw-r--r--src/test/java/org/bouncycastle/crypto/test/DualECDRBGTest.java4
-rw-r--r--src/test/java/org/bouncycastle/crypto/test/HMacDRBGTest.java4
-rw-r--r--src/test/java/org/bouncycastle/crypto/test/HashDRBGTest.java4
16 files changed, 347 insertions, 344 deletions
diff --git a/src/main/java/org/bouncycastle/crypto/prng/DRBGProvider.java b/src/main/java/org/bouncycastle/crypto/prng/DRBGProvider.java
new file mode 100644
index 00000000..c39760c9
--- /dev/null
+++ b/src/main/java/org/bouncycastle/crypto/prng/DRBGProvider.java
@@ -0,0 +1,8 @@
+package org.bouncycastle.crypto.prng;
+
+import org.bouncycastle.crypto.prng.drbg.SP80090DRBG;
+
+interface DRBGProvider
+{
+ SP80090DRBG get(EntropySource entropySource);
+}
diff --git a/src/main/java/org/bouncycastle/crypto/random/SP800SecureRandom.java b/src/main/java/org/bouncycastle/crypto/prng/SP800SecureRandom.java
index 0b54ac54..e1ec6c28 100644
--- a/src/main/java/org/bouncycastle/crypto/random/SP800SecureRandom.java
+++ b/src/main/java/org/bouncycastle/crypto/prng/SP800SecureRandom.java
@@ -1,9 +1,8 @@
-package org.bouncycastle.crypto.random;
+package org.bouncycastle.crypto.prng;
import java.security.SecureRandom;
-import org.bouncycastle.crypto.prng.EntropySource;
-import org.bouncycastle.crypto.prng.SP80090DRBG;
+import org.bouncycastle.crypto.prng.drbg.SP80090DRBG;
public class SP800SecureRandom
extends SecureRandom
@@ -55,7 +54,12 @@ public class SP800SecureRandom
drbg = drbgProvider.get(entropySource);
}
- drbg.generate(bytes, null, predictionResistant);
+ // check if a reseed is required...
+ if (drbg.generate(bytes, null, predictionResistant) < 0)
+ {
+ drbg.reseed(entropySource.getEntropy());
+ drbg.generate(bytes, null, predictionResistant);
+ }
}
}
diff --git a/src/main/java/org/bouncycastle/crypto/random/SP800SecureRandomBuilder.java b/src/main/java/org/bouncycastle/crypto/prng/SP800SecureRandomBuilder.java
index 10bd3505..c5c5827a 100644
--- a/src/main/java/org/bouncycastle/crypto/random/SP800SecureRandomBuilder.java
+++ b/src/main/java/org/bouncycastle/crypto/prng/SP800SecureRandomBuilder.java
@@ -1,18 +1,15 @@
-package org.bouncycastle.crypto.random;
+package org.bouncycastle.crypto.prng;
import java.security.SecureRandom;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.Mac;
-import org.bouncycastle.crypto.prng.BasicEntropySourceProvider;
-import org.bouncycastle.crypto.prng.CTRSP800DRBG;
-import org.bouncycastle.crypto.prng.DualECSP800DRBG;
-import org.bouncycastle.crypto.prng.EntropySource;
-import org.bouncycastle.crypto.prng.EntropySourceProvider;
-import org.bouncycastle.crypto.prng.HMacSP800DRBG;
-import org.bouncycastle.crypto.prng.HashSP800DRBG;
-import org.bouncycastle.crypto.prng.SP80090DRBG;
+import org.bouncycastle.crypto.prng.drbg.CTRSP800DRBG;
+import org.bouncycastle.crypto.prng.drbg.DualECSP800DRBG;
+import org.bouncycastle.crypto.prng.drbg.HMacSP800DRBG;
+import org.bouncycastle.crypto.prng.drbg.HashSP800DRBG;
+import org.bouncycastle.crypto.prng.drbg.SP80090DRBG;
/**
* Builder class for making SecureRandom objects based on SP 800-90A Deterministic Random Bit Generators (DRBG).
diff --git a/src/main/java/org/bouncycastle/crypto/prng/VMPCRandomGenerator.java b/src/main/java/org/bouncycastle/crypto/prng/VMPCRandomGenerator.java
index 9f9ff7b2..b882b796 100644
--- a/src/main/java/org/bouncycastle/crypto/prng/VMPCRandomGenerator.java
+++ b/src/main/java/org/bouncycastle/crypto/prng/VMPCRandomGenerator.java
@@ -124,5 +124,4 @@ public class VMPCRandomGenerator implements RandomGenerator
}
}
}
-
}
diff --git a/src/main/java/org/bouncycastle/crypto/prng/CTRSP800DRBG.java b/src/main/java/org/bouncycastle/crypto/prng/drbg/CTRSP800DRBG.java
index c3b33abb..50f70467 100644
--- a/src/main/java/org/bouncycastle/crypto/prng/CTRSP800DRBG.java
+++ b/src/main/java/org/bouncycastle/crypto/prng/drbg/CTRSP800DRBG.java
@@ -1,14 +1,15 @@
-package org.bouncycastle.crypto.prng;
+package org.bouncycastle.crypto.prng.drbg;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
+import org.bouncycastle.crypto.prng.EntropySource;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.encoders.Hex;
public class CTRSP800DRBG
implements SP80090DRBG
{
- private EntropySource _entropySource;
+ private EntropySource _entropySource;
private BlockCipher _engine;
private int _keySizeInBits;
private int _seedLength;
diff --git a/src/main/java/org/bouncycastle/crypto/prng/DualECSP800DRBG.java b/src/main/java/org/bouncycastle/crypto/prng/drbg/DualECSP800DRBG.java
index caeac7a0..518ae04e 100644
--- a/src/main/java/org/bouncycastle/crypto/prng/DualECSP800DRBG.java
+++ b/src/main/java/org/bouncycastle/crypto/prng/drbg/DualECSP800DRBG.java
@@ -1,9 +1,10 @@
-package org.bouncycastle.crypto.prng;
+package org.bouncycastle.crypto.prng.drbg;
import java.math.BigInteger;
import org.bouncycastle.asn1.nist.NISTNamedCurves;
import org.bouncycastle.crypto.Digest;
+import org.bouncycastle.crypto.prng.EntropySource;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECFieldElement;
import org.bouncycastle.math.ec.ECPoint;
@@ -35,7 +36,7 @@ public class DualECSP800DRBG
private Digest _digest;
private int _reseedCounter;
- private EntropySource _entropySource;
+ private EntropySource _entropySource;
private int _securityStrength;
private int _seedlen;
private int _outlen;
diff --git a/src/main/java/org/bouncycastle/crypto/prng/HMacSP800DRBG.java b/src/main/java/org/bouncycastle/crypto/prng/drbg/HMacSP800DRBG.java
index dd22f4c6..de448f7b 100644
--- a/src/main/java/org/bouncycastle/crypto/prng/HMacSP800DRBG.java
+++ b/src/main/java/org/bouncycastle/crypto/prng/drbg/HMacSP800DRBG.java
@@ -1,7 +1,8 @@
-package org.bouncycastle.crypto.prng;
+package org.bouncycastle.crypto.prng.drbg;
import org.bouncycastle.crypto.Mac;
import org.bouncycastle.crypto.params.KeyParameter;
+import org.bouncycastle.crypto.prng.EntropySource;
import org.bouncycastle.util.Arrays;
public class HMacSP800DRBG
diff --git a/src/main/java/org/bouncycastle/crypto/prng/HashSP800DRBG.java b/src/main/java/org/bouncycastle/crypto/prng/drbg/HashSP800DRBG.java
index c52dd917..489054b0 100644
--- a/src/main/java/org/bouncycastle/crypto/prng/HashSP800DRBG.java
+++ b/src/main/java/org/bouncycastle/crypto/prng/drbg/HashSP800DRBG.java
@@ -1,305 +1,306 @@
-package org.bouncycastle.crypto.prng;
-
-import java.util.Hashtable;
-
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.util.Arrays;
-import org.bouncycastle.util.Integers;
-
-public class HashSP800DRBG implements SP80090DRBG
-{
- private final static byte[] ONE = { 0x01 };
- private final static int RESEED_MAX = 100000;
- private final static Hashtable seedlens = new Hashtable();
-
- static
- {
- seedlens.put("SHA-1", Integers.valueOf(440));
- seedlens.put("SHA-224", Integers.valueOf(440));
- seedlens.put("SHA-256", Integers.valueOf(440));
- seedlens.put("SHA-512/256", Integers.valueOf(440));
- seedlens.put("SHA-512/224", Integers.valueOf(440));
- seedlens.put("SHA-384", Integers.valueOf(888));
- seedlens.put("SHA-512", Integers.valueOf(888));
- }
-
- private Digest _digest;
- private byte[] _V;
- private byte[] _C;
- private int _reseedCounter;
- private EntropySource _entropySource;
- private int _securityStrength;
- private int _seedLength;
-
- public HashSP800DRBG(Digest digest, EntropySource entropySource, byte[] nonce,
- byte[] personalisationString, int securityStrength)
- {
- if (securityStrength > digest.getDigestSize() * 8) // TODO: this may, or may not be correct, but it's good enough for now
- {
- throw new IllegalStateException(
- "Security strength is not supported by the derivation function");
- }
-
- _digest = digest;
- _entropySource = entropySource;
- _securityStrength = securityStrength;
- _seedLength = ((Integer)seedlens.get(digest.getAlgorithmName())).intValue();
-
- // 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
- // of zeros.
- // 5. reseed_counter = 1.
- // 6. Return V, C, and reseed_counter as the initial_working_state
-
- byte[] entropy = entropySource.getEntropy();
- byte[] seedMaterial = Arrays.concatenate(entropy, nonce, personalisationString);
- byte[] seed = hash_df(seedMaterial, _seedLength);
-
- _V = seed;
- byte[] subV = new byte[_V.length + 1];
- System.arraycopy(_V, 0, subV, 1, _V.length);
- _C = hash_df(subV, _seedLength);
- _reseedCounter = 1;
-
-// System.out.println("Constructor V: "+ new String(Hex.encode(_V)));
-// System.out.println("Constructor C: "+ new String(Hex.encode(_C)));
-
- }
-
- // 1. If reseed_counter > reseed_interval, then return an indication that a
- // reseed is required.
- // 2. If (additional_input != Null), then do
- // 2.1 w = Hash (0x02 || V || additional_input).
- // 2.2 V = (V + w) mod 2^seedlen
- // .
- // 3. (returned_bits) = Hashgen (requested_number_of_bits, V).
- // 4. H = Hash (0x03 || V).
- // 5. V = (V + H + C + reseed_counter) mod 2^seedlen
- // .
- // 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.
- public int generate(byte[] output, byte[] additionalInput, boolean predictionResistant)
- {
- int numberOfBits = output.length*8;
-
- if (predictionResistant || _reseedCounter > RESEED_MAX)
- {
- reseed(additionalInput);
- additionalInput = null;
- }
-
- // 2.
- if (additionalInput != null)
- {
- byte[] newInput = new byte[1 + _V.length + additionalInput.length];
- newInput[0] = 0x02;
- System.arraycopy(_V, 0, newInput, 1, _V.length);
- // TODO: inOff / inLength
- System.arraycopy(additionalInput, 0, newInput, 1 + _V.length, additionalInput.length);
- byte[] w = hash(newInput);
-
- addTo(_V, w);
- }
-
- // 3.
- byte[] rv = hashgen(_V, numberOfBits);
-
- // 4.
- byte[] subH = new byte[_V.length + 1];
- System.arraycopy(_V, 0, subH, 1, _V.length);
- subH[0] = 0x03;
-
- byte[] H = hash(subH);
-
- // 5.
- addTo(_V, H);
- addTo(_V, _C);
- 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);
- _reseedCounter++;
-
- System.arraycopy(rv, 0, output, 0, output.length);
-// System.out.println("Generate V: "+ new String(Hex.encode(_V)));
-// System.out.println("Generate C: "+ new String(Hex.encode(_C)));
-
- return numberOfBits;
- }
-
- // 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)
- {
- 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;
- }
- }
-
- // 1. seed_material = 0x01 || V || entropy_input || additional_input.
- //
- // 2. seed = Hash_df (seed_material, seedlen).
- //
- // 3. V = seed.
- //
- // 4. C = Hash_df ((0x00 || V), seedlen).
- //
- // 5. reseed_counter = 1.
- //
- // 6. Return V, C, and reseed_counter for the new_working_state.
- //
- // Comment: Precede with a byte of all zeros.
- public void reseed(byte[] additionalInput)
- {
- if (additionalInput == null)
- {
- additionalInput = new byte[0];
- }
-
- byte[] entropy = _entropySource.getEntropy();
-
-// System.out.println("Reseed Entropy: "+ new String(Hex.encode(entropy)));
-
- byte[] seedMaterial = Arrays.concatenate(ONE, _V, entropy, additionalInput);
-
-// System.out.println("Reseed SeedMaterial: "+ new String(Hex.encode(seedMaterial)));
-
- byte[] seed = hash_df(seedMaterial, _seedLength);
-
-// System.out.println("Reseed Seed: "+ new String(Hex.encode(seed)));
-
- _V = seed;
- byte[] subV = new byte[_V.length + 1];
- subV[0] = 0x00;
- System.arraycopy(_V, 0, subV, 1, _V.length);
- _C = hash_df(subV, _seedLength);
- _reseedCounter = 1;
-
-// System.out.println("Reseed V: "+ new String(Hex.encode(_V)));
-// System.out.println("Reseed C: "+ new String(Hex.encode(_C)));
- }
-
-
- // ---- Internal manipulation ---
- // ---- Migrating from the external HashDF class --
-
-
- // 1. temp = the Null string.
- // 2. .
- // 3. counter = an 8-bit binary value representing the integer "1".
- // 4. For i = 1 to len do
- // Comment : In step 4.1, no_of_bits_to_return
- // is used as a 32-bit string.
- // 4.1 temp = temp || Hash (counter || no_of_bits_to_return ||
- // input_string).
- // 4.2 counter = counter + 1.
- // 5. requested_bits = Leftmost (no_of_bits_to_return) of temp.
- // 6. Return SUCCESS and requested_bits.
- private byte[] hash_df(byte[] seedMaterial, int seedLength)
- {
- byte[] temp = new byte[seedLength / 8];
-
- int len = temp.length / _digest.getDigestSize();
- int counter = 1;
-
- byte[] dig = new byte[_digest.getDigestSize()];
-
- for (int i = 0; i <= len; i++)
- {
- _digest.update((byte)counter);
-
- _digest.update((byte)(seedLength >> 24));
- _digest.update((byte)(seedLength >> 16));
- _digest.update((byte)(seedLength >> 8));
- _digest.update((byte)seedLength);
-
- _digest.update(seedMaterial, 0, seedMaterial.length);
-
- _digest.doFinal(dig, 0);
-
- int bytesToCopy = ((temp.length - i * dig.length) > dig.length)
- ? dig.length
- : (temp.length - i * dig.length);
- System.arraycopy(dig, 0, temp, i * dig.length, bytesToCopy);
-
- counter++;
- }
-
- // do a left shift to get rid of excess bits.
- if (seedLength % 8 != 0)
- {
- int shift = 8 - (seedLength % 8);
- int carry = 0;
-
- for (int i = 0; i != temp.length; i++)
- {
- int b = temp[i] & 0xff;
- temp[i] = (byte)((b >>> shift) | (carry << (8 - shift)));
- carry = b;
- }
- }
-
- return temp;
- }
-
- private byte[] hash(byte[] input)
- {
- _digest.update(input, 0, input.length);
- byte[] hash = new byte[_digest.getDigestSize()];
- _digest.doFinal(hash, 0);
- return hash;
- }
-
- // 1. m = [requested_number_of_bits / outlen]
- // 2. data = V.
- // 3. W = the Null string.
- // 4. For i = 1 to m
- // 4.1 wi = Hash (data).
- // 4.2 W = W || wi.
- // 4.3 data = (data + 1) mod 2^seedlen
- // .
- // 5. returned_bits = Leftmost (requested_no_of_bits) bits of W.
- private byte[] hashgen(byte[] input, int lengthInBits)
- {
- int digestSize = _digest.getDigestSize();
- int m = (lengthInBits / 8) / digestSize;
-
- byte[] data = new byte[input.length];
- System.arraycopy(input, 0, data, 0, input.length);
-
- byte[] W = new byte[lengthInBits / 8];
-
- byte[] dig;
- for (int i = 0; i <= m; i++)
- {
- dig = hash(data);
-
- int bytesToCopy = ((W.length - i * dig.length) > dig.length)
- ? dig.length
- : (W.length - i * dig.length);
- System.arraycopy(dig, 0, W, i * dig.length, bytesToCopy);
-
- addTo(data, ONE);
- }
-
- return W;
- }
-}
+package org.bouncycastle.crypto.prng.drbg;
+
+import java.util.Hashtable;
+
+import org.bouncycastle.crypto.Digest;
+import org.bouncycastle.crypto.prng.EntropySource;
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Integers;
+
+public class HashSP800DRBG implements SP80090DRBG
+{
+ private final static byte[] ONE = { 0x01 };
+ private final static int RESEED_MAX = 100000;
+ private final static Hashtable seedlens = new Hashtable();
+
+ static
+ {
+ seedlens.put("SHA-1", Integers.valueOf(440));
+ seedlens.put("SHA-224", Integers.valueOf(440));
+ seedlens.put("SHA-256", Integers.valueOf(440));
+ seedlens.put("SHA-512/256", Integers.valueOf(440));
+ seedlens.put("SHA-512/224", Integers.valueOf(440));
+ seedlens.put("SHA-384", Integers.valueOf(888));
+ seedlens.put("SHA-512", Integers.valueOf(888));
+ }
+
+ private Digest _digest;
+ private byte[] _V;
+ private byte[] _C;
+ private int _reseedCounter;
+ private EntropySource _entropySource;
+ private int _securityStrength;
+ private int _seedLength;
+
+ public HashSP800DRBG(Digest digest, EntropySource entropySource, byte[] nonce,
+ byte[] personalisationString, int securityStrength)
+ {
+ if (securityStrength > digest.getDigestSize() * 8) // TODO: this may, or may not be correct, but it's good enough for now
+ {
+ throw new IllegalStateException(
+ "Security strength is not supported by the derivation function");
+ }
+
+ _digest = digest;
+ _entropySource = entropySource;
+ _securityStrength = securityStrength;
+ _seedLength = ((Integer)seedlens.get(digest.getAlgorithmName())).intValue();
+
+ // 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
+ // of zeros.
+ // 5. reseed_counter = 1.
+ // 6. Return V, C, and reseed_counter as the initial_working_state
+
+ byte[] entropy = entropySource.getEntropy();
+ byte[] seedMaterial = Arrays.concatenate(entropy, nonce, personalisationString);
+ byte[] seed = hash_df(seedMaterial, _seedLength);
+
+ _V = seed;
+ byte[] subV = new byte[_V.length + 1];
+ System.arraycopy(_V, 0, subV, 1, _V.length);
+ _C = hash_df(subV, _seedLength);
+ _reseedCounter = 1;
+
+// System.out.println("Constructor V: "+ new String(Hex.encode(_V)));
+// System.out.println("Constructor C: "+ new String(Hex.encode(_C)));
+
+ }
+
+ // 1. If reseed_counter > reseed_interval, then return an indication that a
+ // reseed is required.
+ // 2. If (additional_input != Null), then do
+ // 2.1 w = Hash (0x02 || V || additional_input).
+ // 2.2 V = (V + w) mod 2^seedlen
+ // .
+ // 3. (returned_bits) = Hashgen (requested_number_of_bits, V).
+ // 4. H = Hash (0x03 || V).
+ // 5. V = (V + H + C + reseed_counter) mod 2^seedlen
+ // .
+ // 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.
+ public int generate(byte[] output, byte[] additionalInput, boolean predictionResistant)
+ {
+ int numberOfBits = output.length*8;
+
+ if (predictionResistant || _reseedCounter > RESEED_MAX)
+ {
+ reseed(additionalInput);
+ additionalInput = null;
+ }
+
+ // 2.
+ if (additionalInput != null)
+ {
+ byte[] newInput = new byte[1 + _V.length + additionalInput.length];
+ newInput[0] = 0x02;
+ System.arraycopy(_V, 0, newInput, 1, _V.length);
+ // TODO: inOff / inLength
+ System.arraycopy(additionalInput, 0, newInput, 1 + _V.length, additionalInput.length);
+ byte[] w = hash(newInput);
+
+ addTo(_V, w);
+ }
+
+ // 3.
+ byte[] rv = hashgen(_V, numberOfBits);
+
+ // 4.
+ byte[] subH = new byte[_V.length + 1];
+ System.arraycopy(_V, 0, subH, 1, _V.length);
+ subH[0] = 0x03;
+
+ byte[] H = hash(subH);
+
+ // 5.
+ addTo(_V, H);
+ addTo(_V, _C);
+ 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);
+ _reseedCounter++;
+
+ System.arraycopy(rv, 0, output, 0, output.length);
+// System.out.println("Generate V: "+ new String(Hex.encode(_V)));
+// System.out.println("Generate C: "+ new String(Hex.encode(_C)));
+
+ return numberOfBits;
+ }
+
+ // 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)
+ {
+ 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;
+ }
+ }
+
+ // 1. seed_material = 0x01 || V || entropy_input || additional_input.
+ //
+ // 2. seed = Hash_df (seed_material, seedlen).
+ //
+ // 3. V = seed.
+ //
+ // 4. C = Hash_df ((0x00 || V), seedlen).
+ //
+ // 5. reseed_counter = 1.
+ //
+ // 6. Return V, C, and reseed_counter for the new_working_state.
+ //
+ // Comment: Precede with a byte of all zeros.
+ public void reseed(byte[] additionalInput)
+ {
+ if (additionalInput == null)
+ {
+ additionalInput = new byte[0];
+ }
+
+ byte[] entropy = _entropySource.getEntropy();
+
+// System.out.println("Reseed Entropy: "+ new String(Hex.encode(entropy)));
+
+ byte[] seedMaterial = Arrays.concatenate(ONE, _V, entropy, additionalInput);
+
+// System.out.println("Reseed SeedMaterial: "+ new String(Hex.encode(seedMaterial)));
+
+ byte[] seed = hash_df(seedMaterial, _seedLength);
+
+// System.out.println("Reseed Seed: "+ new String(Hex.encode(seed)));
+
+ _V = seed;
+ byte[] subV = new byte[_V.length + 1];
+ subV[0] = 0x00;
+ System.arraycopy(_V, 0, subV, 1, _V.length);
+ _C = hash_df(subV, _seedLength);
+ _reseedCounter = 1;
+
+// System.out.println("Reseed V: "+ new String(Hex.encode(_V)));
+// System.out.println("Reseed C: "+ new String(Hex.encode(_C)));
+ }
+
+
+ // ---- Internal manipulation ---
+ // ---- Migrating from the external HashDF class --
+
+
+ // 1. temp = the Null string.
+ // 2. .
+ // 3. counter = an 8-bit binary value representing the integer "1".
+ // 4. For i = 1 to len do
+ // Comment : In step 4.1, no_of_bits_to_return
+ // is used as a 32-bit string.
+ // 4.1 temp = temp || Hash (counter || no_of_bits_to_return ||
+ // input_string).
+ // 4.2 counter = counter + 1.
+ // 5. requested_bits = Leftmost (no_of_bits_to_return) of temp.
+ // 6. Return SUCCESS and requested_bits.
+ private byte[] hash_df(byte[] seedMaterial, int seedLength)
+ {
+ byte[] temp = new byte[seedLength / 8];
+
+ int len = temp.length / _digest.getDigestSize();
+ int counter = 1;
+
+ byte[] dig = new byte[_digest.getDigestSize()];
+
+ for (int i = 0; i <= len; i++)
+ {
+ _digest.update((byte)counter);
+
+ _digest.update((byte)(seedLength >> 24));
+ _digest.update((byte)(seedLength >> 16));
+ _digest.update((byte)(seedLength >> 8));
+ _digest.update((byte)seedLength);
+
+ _digest.update(seedMaterial, 0, seedMaterial.length);
+
+ _digest.doFinal(dig, 0);
+
+ int bytesToCopy = ((temp.length - i * dig.length) > dig.length)
+ ? dig.length
+ : (temp.length - i * dig.length);
+ System.arraycopy(dig, 0, temp, i * dig.length, bytesToCopy);
+
+ counter++;
+ }
+
+ // do a left shift to get rid of excess bits.
+ if (seedLength % 8 != 0)
+ {
+ int shift = 8 - (seedLength % 8);
+ int carry = 0;
+
+ for (int i = 0; i != temp.length; i++)
+ {
+ int b = temp[i] & 0xff;
+ temp[i] = (byte)((b >>> shift) | (carry << (8 - shift)));
+ carry = b;
+ }
+ }
+
+ return temp;
+ }
+
+ private byte[] hash(byte[] input)
+ {
+ _digest.update(input, 0, input.length);
+ byte[] hash = new byte[_digest.getDigestSize()];
+ _digest.doFinal(hash, 0);
+ return hash;
+ }
+
+ // 1. m = [requested_number_of_bits / outlen]
+ // 2. data = V.
+ // 3. W = the Null string.
+ // 4. For i = 1 to m
+ // 4.1 wi = Hash (data).
+ // 4.2 W = W || wi.
+ // 4.3 data = (data + 1) mod 2^seedlen
+ // .
+ // 5. returned_bits = Leftmost (requested_no_of_bits) bits of W.
+ private byte[] hashgen(byte[] input, int lengthInBits)
+ {
+ int digestSize = _digest.getDigestSize();
+ int m = (lengthInBits / 8) / digestSize;
+
+ byte[] data = new byte[input.length];
+ System.arraycopy(input, 0, data, 0, input.length);
+
+ byte[] W = new byte[lengthInBits / 8];
+
+ byte[] dig;
+ for (int i = 0; i <= m; i++)
+ {
+ dig = hash(data);
+
+ int bytesToCopy = ((W.length - i * dig.length) > dig.length)
+ ? dig.length
+ : (W.length - i * dig.length);
+ System.arraycopy(dig, 0, W, i * dig.length, bytesToCopy);
+
+ addTo(data, ONE);
+ }
+
+ return W;
+ }
+}
diff --git a/src/main/java/org/bouncycastle/crypto/prng/SP80090DRBG.java b/src/main/java/org/bouncycastle/crypto/prng/drbg/SP80090DRBG.java
index 9fbd88f7..c93eb54c 100644
--- a/src/main/java/org/bouncycastle/crypto/prng/SP80090DRBG.java
+++ b/src/main/java/org/bouncycastle/crypto/prng/drbg/SP80090DRBG.java
@@ -1,4 +1,4 @@
-package org.bouncycastle.crypto.prng;
+package org.bouncycastle.crypto.prng.drbg;
public interface SP80090DRBG
{
diff --git a/src/main/java/org/bouncycastle/crypto/prng/package.html b/src/main/java/org/bouncycastle/crypto/prng/package.html
index 99525fbf..bb583abd 100644
--- a/src/main/java/org/bouncycastle/crypto/prng/package.html
+++ b/src/main/java/org/bouncycastle/crypto/prng/package.html
@@ -1,5 +1,5 @@
<html>
<body bgcolor="#ffffff">
-Lightweight psuedo-random number generators.
+Lightweight psuedo-random number generators and SecureRandom builders.
</body>
</html>
diff --git a/src/main/java/org/bouncycastle/crypto/random/DRBGProvider.java b/src/main/java/org/bouncycastle/crypto/random/DRBGProvider.java
deleted file mode 100644
index f1ef83b2..00000000
--- a/src/main/java/org/bouncycastle/crypto/random/DRBGProvider.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.bouncycastle.crypto.random;
-
-import org.bouncycastle.crypto.prng.SP80090DRBG;
-import org.bouncycastle.crypto.prng.EntropySource;
-
-interface DRBGProvider
-{
- SP80090DRBG get(EntropySource entropySource);
-}
diff --git a/src/test/java/org/bouncycastle/crypto/random/test/SP800RandomTest.java b/src/test/java/org/bouncycastle/crypto/random/test/SP800RandomTest.java
index c84b5744..5a7ad692 100644
--- a/src/test/java/org/bouncycastle/crypto/random/test/SP800RandomTest.java
+++ b/src/test/java/org/bouncycastle/crypto/random/test/SP800RandomTest.java
@@ -6,7 +6,7 @@ import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.engines.DESedeEngine;
import org.bouncycastle.crypto.macs.HMac;
-import org.bouncycastle.crypto.random.SP800SecureRandomBuilder;
+import org.bouncycastle.crypto.prng.SP800SecureRandomBuilder;
import org.bouncycastle.crypto.test.DRBGTestVector;
import org.bouncycastle.crypto.test.TestEntropySourceProvider;
import org.bouncycastle.util.Arrays;
diff --git a/src/test/java/org/bouncycastle/crypto/test/CTRDRBGTest.java b/src/test/java/org/bouncycastle/crypto/test/CTRDRBGTest.java
index 813bbed3..59d2177b 100644
--- a/src/test/java/org/bouncycastle/crypto/test/CTRDRBGTest.java
+++ b/src/test/java/org/bouncycastle/crypto/test/CTRDRBGTest.java
@@ -2,8 +2,8 @@ package org.bouncycastle.crypto.test;
import org.bouncycastle.crypto.engines.AESFastEngine;
import org.bouncycastle.crypto.engines.DESedeEngine;
-import org.bouncycastle.crypto.prng.CTRSP800DRBG;
-import org.bouncycastle.crypto.prng.SP80090DRBG;
+import org.bouncycastle.crypto.prng.drbg.CTRSP800DRBG;
+import org.bouncycastle.crypto.prng.drbg.SP80090DRBG;
import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.util.test.SimpleTest;
diff --git a/src/test/java/org/bouncycastle/crypto/test/DualECDRBGTest.java b/src/test/java/org/bouncycastle/crypto/test/DualECDRBGTest.java
index 9161e6e5..8764b694 100644
--- a/src/test/java/org/bouncycastle/crypto/test/DualECDRBGTest.java
+++ b/src/test/java/org/bouncycastle/crypto/test/DualECDRBGTest.java
@@ -3,8 +3,8 @@ package org.bouncycastle.crypto.test;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.digests.SHA384Digest;
import org.bouncycastle.crypto.digests.SHA512Digest;
-import org.bouncycastle.crypto.prng.DualECSP800DRBG;
-import org.bouncycastle.crypto.prng.SP80090DRBG;
+import org.bouncycastle.crypto.prng.drbg.DualECSP800DRBG;
+import org.bouncycastle.crypto.prng.drbg.SP80090DRBG;
import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.util.test.SimpleTest;
diff --git a/src/test/java/org/bouncycastle/crypto/test/HMacDRBGTest.java b/src/test/java/org/bouncycastle/crypto/test/HMacDRBGTest.java
index e98d770c..06f2b25b 100644
--- a/src/test/java/org/bouncycastle/crypto/test/HMacDRBGTest.java
+++ b/src/test/java/org/bouncycastle/crypto/test/HMacDRBGTest.java
@@ -5,8 +5,8 @@ import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.digests.SHA384Digest;
import org.bouncycastle.crypto.digests.SHA512Digest;
import org.bouncycastle.crypto.macs.HMac;
-import org.bouncycastle.crypto.prng.HMacSP800DRBG;
-import org.bouncycastle.crypto.prng.SP80090DRBG;
+import org.bouncycastle.crypto.prng.drbg.HMacSP800DRBG;
+import org.bouncycastle.crypto.prng.drbg.SP80090DRBG;
import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.util.test.SimpleTest;
diff --git a/src/test/java/org/bouncycastle/crypto/test/HashDRBGTest.java b/src/test/java/org/bouncycastle/crypto/test/HashDRBGTest.java
index 06304d72..93920d64 100644
--- a/src/test/java/org/bouncycastle/crypto/test/HashDRBGTest.java
+++ b/src/test/java/org/bouncycastle/crypto/test/HashDRBGTest.java
@@ -4,8 +4,8 @@ import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.digests.SHA384Digest;
import org.bouncycastle.crypto.digests.SHA512Digest;
-import org.bouncycastle.crypto.prng.HashSP800DRBG;
-import org.bouncycastle.crypto.prng.SP80090DRBG;
+import org.bouncycastle.crypto.prng.drbg.HashSP800DRBG;
+import org.bouncycastle.crypto.prng.drbg.SP80090DRBG;
import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.util.test.SimpleTest;