public class SHAKE128InputStream extends SHAKEInputStream
NIST (FIPS PUB 202) specifies the Secure Hash Algorithm-3 (SHA-3) family of message digest algorithms as supplement of the SHA-1 and SHA-2 message digest algorithm family. SHA-3 is based on the KECCAK message digest algorithm but is not fully identical to KECCAK because it adds a suffix to the message to ensure domain separation between the SHA-3 hash function and the newly specified SHA-3 Extendable-Output Function (XOF). The XOF allows the output to be extended to any desired length.
This class implements an InputStream for the SHAKE128 Extendable
Output Function.
The suffix "128" does not indicate the (arbitrary) output
length of the XOF, it specifies its security strength.
SHAKE128 provides less than 128 bits of security if the output length d is
sufficiently small (see FIPS PUB 202). The collision resistance is min(d/2, 128),
the preimage resistance is >=min(d, 128), and the 2nd preimage resistance
is min(d,128). For example, if d = 224, then SHAKE128 provides min(224/2,128)=112
bits of collision resistance and min(224, 128) = 128 bits of preimage resistance (see FIPS PUB 202).
Although it is possible to use an XOF as a hash function for a fixed output length,
XOFs have the potential for generating related outputs. When selecting two different
output length values for a common message, the two outputs of the XOF will be closely
related. The longer output will be an extension of the shorter output. For that reason
XOFs should be used with special care. See (the Security section of) NIST FIPS PUB 202
for more information! Please be aware that SHAKE128 is approved as XOF, but NOT as hash
function. Approved XOF use cases may be specified in further NIST Special Publications.
Currently the JCA API does not provide any engines for Extendable Output Functions.
Because of their relation to hash functions and the membership of SHAKE128 and SHAKE128 to the
SHA-3 family SHAKE may be used a MessageDigest
engine. A MessageDigest
engine, however, represents a hash function with a fixed-length digest output whereas
the output of an Extendable Output Function may have any length. In analogy to
a hash function the XOF first has to be updated with the input data. After the data
update has been completed output data of any length can be read from the XOF.
This reading functionality makes it possible to implement SHAKE as an input stream.
However, in difference to an ordinary input stream you first may have to
update
the stream with the input data before subsequently
reading
digest output from it, e.g:
// create the SHAKEInputStream SHAKE128InputStream shake128In = new SHAKE128InputStream(); ... // provide the input data by any required number of update calls: ... shake128In.update(m1); shake128In.update(m2); ... // after update has finished read output data of any desired length byte[] outBuf = ...; while (...) { shake128In.read(outBuf); } ... // close the stream shake128In.close();Note that the SHAKEInputStream by default will never produce an EOF since it is able to produce an arbitrary number of output bytes. Thus trying to read bytes until method
read
returns -1 may cause an infinite loop! For that reason you have take
care to actually get the requested amount of output data, e.g.:
SHAKE128InputStream shake128In = new SHAKE128InputStream(); ... // update with data ... int outputSize = ...; byte[] outputBuf = new byte[outputSize]; shake128In.read(outputBuf); shake128In.close();Alternatively you may let the SHAKEInputStream control the data reads by specifying the maximum output data size when
creating
the stream, e.g.:
int outputSize = ...; SHAKE128InputStream shake128In = new SHAKE128InputStream(outputSize); ... // update with data ... byte[] buf = new byte[2048]; int r = -1; while ((r = shake128In.read(buf)) != -1) { } shake128In.close();SHAKE is a based on a so-called sponge function. As you see from the examples above the usage of the SHAKEInputStream consists of two phases: during the update phase input data is absorbed by the XOF and during the read phase output data is squeezed from the XOF. As soon as you have started to read data from the stream you cannot provide update data anymore. However, SHAKEInputStream provides a
reset
functionality allowing to start a new data update phase without creating a new
stream:
... shake128In.reset(); ...
Constructor and Description |
---|
SHAKE128InputStream()
Default constructor.
|
SHAKE128InputStream(int outputSize)
Creates a new SHAKE128InputStream with the given maximum read size.
|
public SHAKE128InputStream()
By default a SHAKE128InputStream will never produce an EOF since it is able
to produce an arbitrary number of output bytes. Thus trying to read bytes until
method read
returns -1 may cause an infinite loop! For that reason
you have take care to actually read the requested amount of output data from the
stream, e.g.
SHAKE128InputStream shake128In = new SHAKE128InputStream(); ... // update with data ... int outputSize = ...; byte[] outputBuf = new byte[outputSize]; shake128In.read(outputBuf); shake128In.close();Alternatively you may let the SHAKE128InputStream control the data reads by specifying the maximum output data size when
creating
the stream.public SHAKE128InputStream(int outputSize)
By default a SHAKE128InputStream will never produce an EOF since it is able
to produce an arbitrary number of output bytes. Thus trying to read bytes until
method read
returns -1 may cause an infinite loop! For that reason
you have take care to actually get the requested amount of output data or use
this constructor to tell the SHAKE128InputStream the maximum number of bytes
that can be read from the stream, e.g.:
int outputSize = ...; SHAKE128InputStream shake128In = new SHAKE128InputStream(outputSize); ... // update with data ... byte[] buf = new byte[2048]; int r = -1; while ((r = shake128In.read(buf)) != -1) { } shake128In.close();
outputSize
- the maximum number of bytes that can be read from this stream