Expand description
Implements SHA3 as per NIST FIPS 202.
§Examples
§Hash
Hash functionality is accessed via the Hash trait,
which is implemented by SHA3_224, SHA3_256, SHA3_384 and SHA3_512.
The simplest usage is via the one-shot functions.
use bouncycastle_core::traits::Hash;
use bouncycastle_sha3 as sha3;
let data: &[u8] = b"Hello, world!";
let output: Vec<u8> = sha3::SHA3_256::new().hash(data);More advanced usage will require creating a SHA3 or SHAKE object to hold state between successive calls, for example if input is received in chunks and not all available at the same time:
use bouncycastle_core::traits::Hash;
use bouncycastle_sha3 as sha3;
let data: &[u8] = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F
\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F
\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F
\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
let mut sha3 = sha3::SHA3_256::new();
for chunk in data.chunks(16) {
sha3.do_update(chunk);
}
let output: Vec<u8> = sha3.do_final();It is also possible to provide input where the final byte contains less than 8 bits of data (ie is a partial byte); for example, the following code uses only 3 bits of the final byte:
use bouncycastle_core::traits::Hash;
use bouncycastle_sha3 as sha3;
let data: &[u8] = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F";
let mut sha3 = sha3::SHA3_256::new();
sha3.do_update(&data[..data.len()-1]);
let final_byte = data[data.len()-1];
let output: Vec<u8> = sha3.do_final_partial_bits(final_byte, 3).expect("Failed to finalize hash state.");§XOF
SHA3 offers Extendable-Output Functions in the form of SHAKE, which is accessed through the XOF trait,
which is implemented by SHAKE128 and SHAKE256.
The difference from Hash is that SHAKE can produce output of any length.
The simplest usage is via the static functions. The following example produces a 16 byte (128-bit) and 16KiB output:
use bouncycastle_core::traits::XOF;
use bouncycastle_sha3 as sha3;
let data: &[u8] = b"Hello, world!";
let output_16byte: Vec<u8> = sha3::SHAKE128::new().hash_xof(data, 16);
let output_16KiB: Vec<u8> = sha3::SHAKE128::new().hash_xof(data, 16 * 1024);As with Hash above, the XOF trait has streaming APIs in the form of XOF::absorb and XOF::squeeze.
Unlike Hash::do_final, XOF::squeeze can be called multiple times.
Note, however, that once you start squeezing, you can no longer absorb more input – XOF::absorb
will throw a HashError::InvalidState, but the SHAKE object will still be usable for squeezing
as if the erroneous absorb call never happened.
The following code produces the same output as the previous example:
use bouncycastle_core::traits::XOF;
use bouncycastle_sha3 as sha3;
let data: &[u8] = b"Hello, world!";
let mut shake = sha3::SHAKE128::new();
shake.absorb(data).expect("infallible before squeeze");
let output_16byte: Vec<u8> = shake.squeeze(16);
let mut shake = sha3::SHAKE128::new();
let mut output_16KiB: Vec<u8> = vec![];
for i in 0..16 { output_16KiB.extend_from_slice(&shake.squeeze(1024)) }§KDF
SHA3 offers Key Derivation Functions in the form of KDF, which is accessed through the KDF trait,
which is implemented by all SHA3 and SHAKE variants.
KDF acts on KeyMaterial objects as both the input and output values.
In the case of SHA3, the KDF interfaces are simple wrapper functions around the underlying SHA3 or SHAKE
primitive that correctly maintains the length and entropy metadata of the key material that it is acting on.
This is intended to act as a developer ait to prevent some classes of developer mistakes, such as
deriving a cryptographic key from uninitialized (aka zeroized) input key material, or using low-entropy
input key material to derive a MAC, symmetric, or asymmetric key.
use bouncycastle_core::traits::KDF;
use bouncycastle_core::key_material::{KeyMaterial256, KeyType};
use bouncycastle_sha3 as sha3;
let input_key = KeyMaterial256::from_bytes(b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F").unwrap();
let output_key = sha3::SHA3_256::new().derive_key(&input_key, b"Additional input").unwrap();In the previous example, since KeyMaterial::from_bytes cannot know the amount of entropy in the input data,
it automatically tags it as KeyType::Unknown, and thus SHA3Internal::derive_key produces an output key
which also has type KeyType::Unknown.
This would also be the case even if the input had type
KeyType::CryptographicRandom since the input KeyMaterial is 16 bytes but SHA3_256 needs at least 32 bytes of
full-entropy input key material in order to be able to produce full entropy output key material.
§Suspending and resuming execution
When hashing a large message, it can be advantageous to be able to suspend the operation to a cache and resume it later; for example if waiting for the message to stream over a slow network connection.
For this reason, all SHA3 algorithms impl Suspendable.
use bouncycastle_sha3 as sha3;
use bouncycastle_core::traits::{Hash, Suspendable};
let msg_part1 = b"The quick brown fox";
let msg_part2 = b" jumped over the lazy dog";
let mut sha3 = sha3::SHA3_256::new();
sha3.do_update(msg_part1);
// suspend the in-progress extract while "waiting" for the second part of the message.
let serialized_state = sha3.suspend();
// ...
// do other things in the meantime
// ...
// ... later, possibly on another host: resume from the serialized state.
let mut sha3_resumed = sha3::SHA3_256::from_suspended(serialized_state).unwrap();
sha3_resumed.do_update(msg_part2);
let h: Vec<u8> = sha3_resumed.do_final();Structs§
- SHA3
Internal - Internal struct for SHA3. This uses a private bound so that you cannot instantiate it directly and have to use the provided and NIST-approved parameters.
- SHA3_
224Params - The parameters for SHA3_224.
- SHA3_
256Params - The parameters for SHA3_256.
- SHA3_
384Params - The parameters for SHA3_384.
- SHA3_
512Params - The parameters for SHA3_512.
- SHAK
E128 Params - The parameters for SHAKE128.
- SHAK
E256 Params - The parameters for SHAKE256.
- SHAKE
Internal - Internal struct for SHAKE. This uses a private bound so that you cannot instantiate it directly and have to use the provided and NIST-approved parameters.
Constants§
- SHA3_
224_ NAME - SHA3_
256_ NAME - SHA3_
384_ NAME - SHA3_
512_ NAME - SHAK
E128_ NAME - SHAK
E256_ NAME - SUSPENDED_
SHA3_ STATE_ LEN - Length in bytes of the serialized state of a SHA3 or SHAKE instance.