pub struct RpJive64_256();
Expand description

Implementation of Hasher trait for Rescue Prime hash function with 256-bit output.

The hash function is implemented according to the Rescue Prime specifications with the following exception:

  • We set the number of rounds to 7, which implies a 40% security margin instead of the 50% margin used in the specifications (a 50% margin rounds up to 8 rounds). The primary motivation for this is that having the number of rounds be one less than a power of two simplifies AIR design for computations involving the hash function.
  • When hashing a sequence of elements, implement the Hirose padding rule. However, it also means that our instantiation of Rescue Prime cannot be used in a stream mode as the number of elements to be hashed must be known upfront.
  • We use the first 4 elements of the state (rather than the last 4 elements of the state) for capacity and the remaining 8 elements for rate. The output of the hash function comes from the first four elements of the rate portion of the state (elements 4, 5, 6, and 7). This effectively applies a fixed bit permutation before and after XLIX permutation. We assert without proof that this does not affect security of the construction.
  • Instead of using Vandermonde matrices as a standard way of generating an MDS matrix as described in Rescue Prime paper, we use a methodology developed by Polygon Zero to find an MDS matrix with coefficients which are small powers of two in frequency domain. This allows us to dramatically reduce MDS matrix multiplication time. Using a different MDS matrix does not affect security of the hash function as any MDS matrix satisfies Rescue Prime construction (as described in section 4.2 of the paper).

The parameters used to instantiate the function are:

  • Field: 64-bit prime field with modulus 2^64 - 2^32 + 1.
  • State width: 8 field elements.
  • Capacity size: 4 field elements.
  • Number of founds: 7.
  • S-Box degree: 7.

The above parameters target 128-bit security level. The digest consists of four field elements and it can be serialized into 32 bytes (256 bits).

§Hash output consistency

Functions hash_elements(), merge(), and merge_with_int() are not consistent. This is because the former is instantiated with a sponge construction, while the latter use the Jive compression mode and hence do not rely on the sponge construction.

In addition, hash() function is not consistent with the functions mentioned above. For example, if we take two field elements, serialize them to bytes and hash them using hash(), the result will differ from the result obtained by hashing these elements directly using hash_elements() function. The reason for this difference is that hash() function needs to be able to handle arbitrary binary strings, which may or may not encode valid field elements - and thus, deserialization procedure used by this function is different from the procedure used to deserialize valid field elements.

Thus, if the underlying data consists of valid field elements, it might make more sense to deserialize them into field elements and then hash them using hash_elements() function rather then hashing the serialized bytes using hash() function.

Implementations§

source§

impl RpJive64_256

source

pub const NUM_ROUNDS: usize = 7usize

The number of rounds is set to 7 to target 128-bit security level with 40% security margin.

source

pub const STATE_WIDTH: usize = 8usize

Sponge state is set to 8 field elements or 64 bytes; 4 elements are reserved for rate and the remaining 4 elements are reserved for capacity.

source

pub const RATE_RANGE: Range<usize> = RATE_RANGE

The rate portion of the state is located in elements 4 through 7 (inclusive).

source

pub const CAPACITY_RANGE: Range<usize> = CAPACITY_RANGE

The capacity portion of the state is located in elements 0, 1, 2, and 3.

source

pub const DIGEST_RANGE: Range<usize> = DIGEST_RANGE

The output of the hash function can be read from state elements 4, 5, 6, and 7.

source

pub const MDS: [[BaseElement; 8]; 8] = MDS

MDS matrix used for computing the linear layer in a Rescue Prime round.

source

pub const INV_MDS: [[BaseElement; 8]; 8] = INV_MDS

Inverse of the MDS matrix.

source

pub const ARK1: [[BaseElement; 8]; 7] = ARK1

Round constants added to the hasher state in the first half of the Rescue Prime round.

source

pub const ARK2: [[BaseElement; 8]; 7] = ARK2

Round constants added to the hasher state in the second half of the Rescue Prime round.

source

pub fn apply_permutation(state: &mut [BaseElement; 8])

Applies Rescue-XLIX permutation to the provided state.

source

pub fn apply_round(state: &mut [BaseElement; 8], round: usize)

Rescue-XLIX round function.

source

pub fn apply_jive_summation( initial_state: &[BaseElement; 8], final_state: &[BaseElement; 8] ) -> ElementDigest

Trait Implementations§

source§

impl ElementHasher for RpJive64_256

§

type BaseField = BaseElement

Specifies a base field for elements which can be hashed with this hasher.
source§

fn hash_elements<E: FieldElement<BaseField = Self::BaseField>>( elements: &[E] ) -> Self::Digest

Returns a hash of the provided field elements.
source§

impl Hasher for RpJive64_256

§

type Digest = ElementDigest

Specifies a digest type returned by this hasher.
source§

const COLLISION_RESISTANCE: u32 = 128u32

Collision resistance of the hash function measured in bits.
source§

fn hash(bytes: &[u8]) -> Self::Digest

Returns a hash of the provided sequence of bytes.
source§

fn merge(values: &[Self::Digest; 2]) -> Self::Digest

Returns a hash of two digests. This method is intended for use in construction of Merkle trees.
source§

fn merge_with_int(seed: Self::Digest, value: u64) -> Self::Digest

Returns hash(seed || value). This method is intended for use in PRNG and PoW contexts.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.