[][src]Crate fdh

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.


use sha2::Sha256;
use fdh::{FullDomainHash, Input, 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.input(b"ATTACK AT DAWN");
let result = hasher.vec_result();


This crate also supports no_std.

use sha2::Sha256;
use fdh::{FullDomainHash, Input, 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.input(b"ATTACK AT DAWN");
let mut reader = hasher.xof_result();
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():
       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, Input, 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();

fn digest_is_odd(digest: &BigUint) -> bool {
let iv = 0;

let (digest, iv) = hasher.results_in_domain(iv, digest_is_odd).unwrap();







Error types



Trait which describes extendable-output functions (XOF).


Trait for processing input data


Trait for resetting hash instances


Trait for returning digest result with the varaible size


Trait for decribing readers which are used to extract extendable output from XOF (extendable-output function) result.