Crate fdh[−][src]
Full Domain Hash
A Full Domain Hash (FDH) is a cryptographic construction that extends the size of a hash digest to an arbitrary length. For example, SHA256 can be expanded to 1024 bits instead of the usual 256 bits.
We construct an FDH by computing a number of cycles where cycles=(target length)/(digest length) + 1
. We then compute FDH(M) = HASH(M||0) || HASH(M||1) || ... || HASH(M||cycles−1)
, where HASH
is any hash function, M
is the message, ||
denotes concatenation, and numerical values are single byte u8
.
FDHs are usually used with an RSA signature scheme where the target length is the size of the key. See https://en.wikipedia.org/wiki/Full_Domain_Hash
This crate makes extensive use of the digest
crate's cryptograhic hash traits, so most useful methods are implemented as part of digest
traits. These traits are re-exported for convenience. See https://github.com/RustCrypto/hashes for a list of compatible hashes.
Example
use sha2::Sha256; use fdh::{FullDomainHash, Update, VariableOutput}; // Expand SHA256 from 256 bits to 1024 bits. let output_bits = 1024; let output_bytes = 1024 / 8; let mut hasher = FullDomainHash::<Sha256>::new(output_bytes).unwrap(); hasher.update(b"ATTACK AT DAWN"); let result = hasher.finalize_boxed().into_vec();
no_std
This crate also supports no_std
.
#![no_std] use sha2::Sha256; use fdh::{FullDomainHash, Update, ExtendableOutput, XofReader}; // Expand SHA256 from 256 bits to 512 bits (and beyond), reading it in 16 byte chunks. let mut hasher = FullDomainHash::<Sha256>::default(); hasher.update(b"ATTACK AT DAWN"); let mut reader = hasher.finalize_xof(); let mut read_buf = <[u8; 16]>::default(); // Read the first 16 bytes into read_buf reader.read(&mut read_buf); // Read the second 16 bytes into read_buf reader.read(&mut read_buf); // If we want, we can just keep going, reading as many bits as we want indefinitely. reader.read(&mut read_buf); reader.read(&mut read_buf);
Restricted Domain
This crate also supports getting a digest that is within a specific domain. It follows an algorithim like so:
fn digest_in_domain(message, iv):
digest = fdh(message, iv)
while not digest.in_domain():
iv++
digest = fdh(message, iv)
return digest, iv
The method results_in_domain()
is provided to accomplish this. The helper methods results_between()
, results_lt()
, results_gt()
are provided for the common case where the digest must be in a certain range.
An example that produces a digest that is odd:
use sha2::Sha512; use fdh::{FullDomainHash, Update, VariableOutput}; use num_bigint::BigUint; use num_integer::Integer; // Get a full domain hash that is odd let mut hasher = FullDomainHash::<Sha512>::new(64).unwrap(); hasher.update(b"ATTACKATDAWN"); fn digest_is_odd(digest: &[u8]) -> bool { BigUint::from_bytes_be(digest).is_odd() } let iv = 0; let (digest, iv) = hasher.results_in_domain(iv, digest_is_odd).unwrap();
Modules
movingwindow |
Structs
FullDomainHash |
Enums
Error | Error types |
Traits
Digest | The |
ExtendableOutput | Trait which describes extendable-output functions (XOF). |
Reset | Trait for resetting hash instances |
Update | Trait for updating digest state with input data. |
VariableOutput | Trait for returning digest result with the variable size |
XofReader | Trait for describing readers which are used to extract extendable output from XOF (extendable-output function) result. |