Browse Source

Merge pull request #40 from 0xPolygonMiden/kaneki-domain-separator

Domain separator during merge
al-gkr-basic-workflow
Kaneki (カネキ ケン) 2 years ago
committed by GitHub
parent
commit
6de7730e30
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 1 deletions
  1. +22
    -0
      src/hash/rpo/mod.rs
  2. +36
    -1
      src/hash/rpo/tests.rs

+ 22
- 0
src/hash/rpo/mod.rs

@ -294,6 +294,28 @@ impl Rpo256 {
<Self as ElementHasher>::hash_elements(elements)
}
// DOMAIN IDENTIFIER
// --------------------------------------------------------------------------------------------
/// Returns a hash of two digests and a domain identifier.
pub fn merge_in_domain(values: &[RpoDigest; 2], domain: Felt) -> RpoDigest {
// initialize the state by copying the digest elements into the rate portion of the state
// (8 total elements), and set the capacity elements to 0.
let mut state = [ZERO; STATE_WIDTH];
let it = RpoDigest::digests_as_elements(values.iter());
for (i, v) in it.enumerate() {
state[RATE_RANGE.start + i] = *v;
}
// set the second capacity element to the domain value. The first capacity element is used
// for padding purposes.
state[CAPACITY_RANGE.start + 1] = domain;
// apply the RPO permutation and return the first four elements of the state
Self::apply_permutation(&mut state);
RpoDigest::new(state[DIGEST_RANGE].try_into().unwrap())
}
// RESCUE PERMUTATION
// --------------------------------------------------------------------------------------------

+ 36
- 1
src/hash/rpo/tests.rs

@ -1,5 +1,6 @@
use super::{
Felt, FieldElement, Hasher, Rpo256, RpoDigest, StarkField, ALPHA, INV_ALPHA, STATE_WIDTH, ZERO,
Felt, FieldElement, Hasher, Rpo256, RpoDigest, StarkField, ALPHA, CAPACITY_RANGE, DIGEST_RANGE,
INV_ALPHA, RATE_RANGE, STATE_WIDTH, ZERO,
};
use core::convert::TryInto;
use rand_utils::rand_value;
@ -51,6 +52,40 @@ fn hash_elements_vs_merge() {
assert_eq!(m_result, h_result);
}
#[test]
fn hash_elements_vs_merge_in_domain() {
let elements = [Felt::new(rand_value()); 8];
let digests: [RpoDigest; 2] = [
RpoDigest::new(elements[..4].try_into().unwrap()),
RpoDigest::new(elements[4..].try_into().unwrap()),
];
// pick a random domain value.
let domain = Felt::new(rand_value());
// convert the elements into a list of base field elements
let elements = Felt::as_base_elements(&elements);
// initialize state to all zeros.
let mut state = [ZERO; STATE_WIDTH];
// set the second capacity element to the domain.
state[CAPACITY_RANGE.start + 1] = domain;
// absorb elements into the state.
state[RATE_RANGE.start..RATE_RANGE.end].copy_from_slice(elements);
// apply permutation to the state.
Rpo256::apply_permutation(&mut state);
// return the first 4 elements of the state as hash result
let h_result = RpoDigest::new(state[DIGEST_RANGE].try_into().unwrap());
let m_result = Rpo256::merge_in_domain(&digests, domain);
assert_eq!(m_result, h_result);
}
#[test]
fn hash_elements_vs_merge_with_int() {
let tmp = [Felt::new(rand_value()); 4];

Loading…
Cancel
Save