Class AesCounterRandom
- java.lang.Object
-
- java.util.Random
-
- io.github.pr0methean.betterrandom.prng.BaseRandom
-
- io.github.pr0methean.betterrandom.prng.CipherCounterRandom
-
- io.github.pr0methean.betterrandom.prng.AesCounterRandom
-
- All Implemented Interfaces:
ByteArrayReseedableRandom
,EntropyCountingRandom
,Java8CompatRandom
,RepeatableRandom
,SeekableRandom
,Dumpable
,Serializable
public class AesCounterRandom extends CipherCounterRandom
CipherCounterRandom using AES (Rijndael).
Keys larger than 128 bits, and thus seeds larger than 256 bits, require unlimited strength cryptography policy files on closed-source JDKs.
NOTE: Because instances of this class require 128-bit seeds, it is not possible to seed this RNG using the
CipherCounterRandom.setSeed(long)
method inherited fromRandom
until the seed array has been set.- Author:
- Daniel Dyer, Chris Hennick
- See Also:
- Serialized Form
-
-
Field Summary
Fields Modifier and Type Field Description protected Cipher
cipher
The AES cipher that will generate the pseudorandom numbers.static int
MAX_SEED_LENGTH_BYTES
Maximum total length of the seed, including both key and initial counter value.-
Fields inherited from class io.github.pr0methean.betterrandom.prng.CipherCounterRandom
counter, currentBlock, index
-
Fields inherited from class io.github.pr0methean.betterrandom.prng.BaseRandom
ENTROPY_OF_DOUBLE, ENTROPY_OF_FLOAT, entropyBits, lock, randomSeeder, seed, superConstructorFinished
-
-
Constructor Summary
Constructors Constructor Description AesCounterRandom()
Creates a new RNG and seeds it using 256 bits from theDefaultSeedGenerator
.AesCounterRandom(byte[] seed)
Creates an RNG and seeds it with the specified seed data.AesCounterRandom(int seedSizeBytes)
Seed the RNG using theDefaultSeedGenerator
to create a seed of the specified size.AesCounterRandom(SeedGenerator seedGenerator)
Seed the RNG using the provided seed generation strategy to create a 256-bit seed.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description MoreObjects.ToStringHelper
addSubclassFields(MoreObjects.ToStringHelper original)
Adds the fields that were not inherited from BaseRandom to the givenMoreObjects.ToStringHelper
for dumping.protected void
createCipher()
Creates the cipher thatCipherCounterRandom.doCipher(byte[], byte[])
will invoke.protected MessageDigest
createHash()
Returns the hash that will be used to combine seeds.protected void
doCipher(byte[] input, byte[] output)
Executes the cipher.int
getBlocksAtOnce()
Returns how many consecutive values of the counter are encrypted at once, in order to reduce the number of calls to Cipher methods.int
getBytesAtOnce()
Returns the number of random bytes that can be precalculated at once, which is normallygetCounterSizeBytes() * getBlocksAtOnce()
.int
getCounterSizeBytes()
Returns the length of the counter, which should equal the cipher's block size.protected int
getKeyLength(int inputLength)
Returns the length of the key that should be extracted from a seed of a given length.int
getMaxKeyLengthBytes()
Returns the maximum length in bytes of an AES key, which isMath.min(Cipher.getMaxAllowedKeyLength("AES/ECB/NoPadding") / 8, 32)
.int
getMaxTotalSeedLengthBytes()
Returns the maximum seed length, including both the cipher key and a new counter value.protected int
getMinSeedLength()
Returns the minimum seed length.int
getNewSeedLength()
Returns the longest supported seed length.protected void
setKey(byte[] key)
Sets the key on the cipher.protected void
setSeedInternal(byte[] seed)
Sets the seed, and should be overridden to set other state that derives from the seed.-
Methods inherited from class io.github.pr0methean.betterrandom.prng.CipherCounterRandom
advance, initTransientFields, next, nextBlock, setSeed, setSeed, supportsMultipleSeedLengths
-
Methods inherited from class io.github.pr0methean.betterrandom.prng.BaseRandom
checkLength, creditEntropyForNewSeed, debitEntropy, doubles, doubles, doubles, doubles, dump, entropyOfInt, entropyOfLong, fallbackSetSeedIfInitialized, gaussians, gaussians, getEntropyBits, getRandomSeeder, getSeed, internalNextGaussian, ints, ints, ints, ints, lockForNextGaussian, longs, longs, longs, longs, needsReseedingEarly, nextBoolean, nextBytes, nextDouble, nextDouble, nextDouble, nextDoubleNoEntropyDebit, nextElement, nextElement, nextEnum, nextFloat, nextGaussian, nextInt, nextInt, nextInt, nextLong, nextLong, nextLong, nextLongNoEntropyDebit, preferSeedWithLong, setRandomSeeder, unlockForNextGaussian, usesParallelStreams, withProbability, withProbabilityInternal
-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface io.github.pr0methean.betterrandom.RepeatableRandom
getSeed
-
-
-
-
Field Detail
-
cipher
protected transient Cipher cipher
The AES cipher that will generate the pseudorandom numbers.
-
MAX_SEED_LENGTH_BYTES
public static final int MAX_SEED_LENGTH_BYTES
Maximum total length of the seed, including both key and initial counter value.
-
-
Constructor Detail
-
AesCounterRandom
public AesCounterRandom() throws SeedException
Creates a new RNG and seeds it using 256 bits from theDefaultSeedGenerator
.- Throws:
SeedException
- if theDefaultSeedGenerator
fails to generate a seed.
-
AesCounterRandom
public AesCounterRandom(SeedGenerator seedGenerator) throws SeedException
Seed the RNG using the provided seed generation strategy to create a 256-bit seed.- Parameters:
seedGenerator
- The seed generation strategy that will provide the seed value for this RNG.- Throws:
SeedException
- if there is a problem generating a seed.
-
AesCounterRandom
public AesCounterRandom(int seedSizeBytes) throws SeedException
Seed the RNG using theDefaultSeedGenerator
to create a seed of the specified size.- Parameters:
seedSizeBytes
- The number of bytes to use for seed data. Valid values range from 16 toMAX_SEED_LENGTH_BYTES
.- Throws:
SeedException
- if theDefaultSeedGenerator
fails to generate a seed.
-
AesCounterRandom
public AesCounterRandom(byte[] seed)
Creates an RNG and seeds it with the specified seed data.- Parameters:
seed
- The seed data used to initialize the RNG. Length must be at least 16 and no more thanMAX_SEED_LENGTH_BYTES
.
-
-
Method Detail
-
getBlocksAtOnce
public int getBlocksAtOnce()
Description copied from class:CipherCounterRandom
Returns how many consecutive values of the counter are encrypted at once, in order to reduce the number of calls to Cipher methods. Each counter value encrypts to yield a "block" of pseudorandom data. Changing this value won't change the output if the cipher is running in block mode, but it may impact performance.- Specified by:
getBlocksAtOnce
in classCipherCounterRandom
- Returns:
- the number of blocks (counter values) to encrypt at once
-
getBytesAtOnce
public int getBytesAtOnce()
Description copied from class:CipherCounterRandom
Returns the number of random bytes that can be precalculated at once, which is normallygetCounterSizeBytes() * getBlocksAtOnce()
.- Overrides:
getBytesAtOnce
in classCipherCounterRandom
- Returns:
- the number of random bytes that can be precalculated at once
-
getMaxTotalSeedLengthBytes
public int getMaxTotalSeedLengthBytes()
Description copied from class:CipherCounterRandom
Returns the maximum seed length, including both the cipher key and a new counter value.- Overrides:
getMaxTotalSeedLengthBytes
in classCipherCounterRandom
- Returns:
- the maximum seed length
-
getMinSeedLength
protected int getMinSeedLength()
Description copied from class:CipherCounterRandom
Returns the minimum seed length.- Specified by:
getMinSeedLength
in classCipherCounterRandom
- Returns:
- the minimum seed length
-
getCounterSizeBytes
public int getCounterSizeBytes()
Description copied from class:CipherCounterRandom
Returns the length of the counter, which should equal the cipher's block size.- Overrides:
getCounterSizeBytes
in classCipherCounterRandom
- Returns:
- the length of the counter
-
getMaxKeyLengthBytes
public int getMaxKeyLengthBytes()
Returns the maximum length in bytes of an AES key, which isMath.min(Cipher.getMaxAllowedKeyLength("AES/ECB/NoPadding") / 8, 32)
. If the seed is longer than this, part of it becomes the counter's initial value. Otherwise, the full seed becomes the AES key and the counter is initially zero.- Specified by:
getMaxKeyLengthBytes
in classCipherCounterRandom
- Returns:
- the maximum length in bytes of an AES key.
-
getKeyLength
protected int getKeyLength(int inputLength)
Description copied from class:CipherCounterRandom
Returns the length of the key that should be extracted from a seed of a given length. During the initial seeding, whatever part of the seed does not become the key, becomes the counter's initial value.- Specified by:
getKeyLength
in classCipherCounterRandom
- Parameters:
inputLength
- the length of the whole seed- Returns:
- the length of the key
-
createHash
protected MessageDigest createHash()
Description copied from class:CipherCounterRandom
Returns the hash that will be used to combine seeds. Only called on construction and deserialization.- Specified by:
createHash
in classCipherCounterRandom
- Returns:
- a resettable
MessageDigest
-
createCipher
protected void createCipher()
Description copied from class:CipherCounterRandom
Creates the cipher thatCipherCounterRandom.doCipher(byte[], byte[])
will invoke.CipherCounterRandom.setKey(byte[])
will be called before the cipher is used.- Specified by:
createCipher
in classCipherCounterRandom
-
setSeedInternal
protected void setSeedInternal(byte[] seed)
Description copied from class:BaseRandom
Sets the seed, and should be overridden to set other state that derives from the seed. Called byBaseRandom.setSeed(byte[])
, constructors, andreadObject(ObjectInputStream)
. When called after initialization, theBaseRandom.lock
is always held.- Overrides:
setSeedInternal
in classCipherCounterRandom
- Parameters:
seed
- The new seed.
-
setKey
protected void setKey(byte[] key) throws InvalidKeyException
Description copied from class:CipherCounterRandom
Sets the key on the cipher. Always called withlock
held.- Specified by:
setKey
in classCipherCounterRandom
- Parameters:
key
- the new key- Throws:
InvalidKeyException
- if the cipher rejects the key
-
getNewSeedLength
public int getNewSeedLength()
Returns the longest supported seed length.- Specified by:
getNewSeedLength
in interfaceByteArrayReseedableRandom
- Overrides:
getNewSeedLength
in classCipherCounterRandom
- Returns:
- The desired length of a new byte-array seed.
-
addSubclassFields
public MoreObjects.ToStringHelper addSubclassFields(MoreObjects.ToStringHelper original)
Description copied from class:BaseRandom
Adds the fields that were not inherited from BaseRandom to the givenMoreObjects.ToStringHelper
for dumping.- Specified by:
addSubclassFields
in classBaseRandom
- Parameters:
original
- aMoreObjects.ToStringHelper
object.- Returns:
original
with the fields not inherited from BaseRandom written to it.
-
doCipher
protected void doCipher(byte[] input, byte[] output) throws GeneralSecurityException
Description copied from class:CipherCounterRandom
Executes the cipher.- Specified by:
doCipher
in classCipherCounterRandom
- Parameters:
input
- an array of input whose length is equal toCipherCounterRandom.getBytesAtOnce()
output
- an array of output whose length is equal toCipherCounterRandom.getBytesAtOnce()
- Throws:
GeneralSecurityException
- if an internal error occurs in the cipher
-
-