chore: change to BINARY_CHUNK_SIZE
This commit is contained in:
parent
7cb9f7bfdf
commit
636c92a78b
1 changed files with 20 additions and 16 deletions
|
@ -38,6 +38,9 @@ const DIGEST_SIZE: usize = DIGEST_RANGE.end - DIGEST_RANGE.start;
|
||||||
/// The number of rounds is set to 7 to target 128-bit security level
|
/// The number of rounds is set to 7 to target 128-bit security level
|
||||||
const NUM_ROUNDS: usize = 7;
|
const NUM_ROUNDS: usize = 7;
|
||||||
|
|
||||||
|
/// The number of byte chunks defining a field element when hashing a sequence of bytes
|
||||||
|
const BINARY_CHUNK_SIZE: usize = 7;
|
||||||
|
|
||||||
/// S-Box and Inverse S-Box powers;
|
/// S-Box and Inverse S-Box powers;
|
||||||
///
|
///
|
||||||
/// The constants are defined for tests only because the exponentiations in the code are unrolled
|
/// The constants are defined for tests only because the exponentiations in the code are unrolled
|
||||||
|
@ -93,12 +96,12 @@ impl HashFn for Rpo256 {
|
||||||
|
|
||||||
fn hash(bytes: &[u8]) -> Self::Digest {
|
fn hash(bytes: &[u8]) -> Self::Digest {
|
||||||
// compute the number of elements required to represent the string; we will be processing
|
// compute the number of elements required to represent the string; we will be processing
|
||||||
// the string in 7-byte chunks, thus the number of elements will be equal to the number
|
// the string in BINARY_CHUNK_SIZE-byte chunks, thus the number of elements will be equal
|
||||||
// of such chunks (including a potential partial chunk at the end).
|
// to the number of such chunks (including a potential partial chunk at the end).
|
||||||
let num_elements = if bytes.len() % 7 == 0 {
|
let num_elements = if bytes.len() % BINARY_CHUNK_SIZE == 0 {
|
||||||
bytes.len() / 7
|
bytes.len() / BINARY_CHUNK_SIZE
|
||||||
} else {
|
} else {
|
||||||
bytes.len() / 7 + 1
|
bytes.len() / BINARY_CHUNK_SIZE + 1
|
||||||
};
|
};
|
||||||
|
|
||||||
// initialize state to all zeros, except for the first element of the capacity part, which
|
// initialize state to all zeros, except for the first element of the capacity part, which
|
||||||
|
@ -107,19 +110,20 @@ impl HashFn for Rpo256 {
|
||||||
let mut state = [ZERO; STATE_WIDTH];
|
let mut state = [ZERO; STATE_WIDTH];
|
||||||
state[CAPACITY_RANGE.start] = Felt::new(num_elements as u64);
|
state[CAPACITY_RANGE.start] = Felt::new(num_elements as u64);
|
||||||
|
|
||||||
// break the string into 7-byte chunks, convert each chunk into a field element, and
|
// break the string into BINARY_CHUNK_SIZE-byte chunks, convert each chunk into a field
|
||||||
// absorb the element into the rate portion of the state. we use 7-byte chunks because
|
// element, and absorb the element into the rate portion of the state. we use
|
||||||
// every 7-byte chunk is guaranteed to map to some field element.
|
// BINARY_CHUNK_SIZE-byte chunks because every BINARY_CHUNK_SIZE-byte chunk is guaranteed
|
||||||
|
// to map to some field element.
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
let mut buf = [0_u8; 8];
|
let mut buf = [0_u8; 8];
|
||||||
for chunk in bytes.chunks(7) {
|
for chunk in bytes.chunks(BINARY_CHUNK_SIZE) {
|
||||||
if i < num_elements - 1 {
|
if i < num_elements - 1 {
|
||||||
buf[..7].copy_from_slice(chunk);
|
buf[..BINARY_CHUNK_SIZE].copy_from_slice(chunk);
|
||||||
} else {
|
} else {
|
||||||
// if we are dealing with the last chunk, it may be smaller than 7 bytes long, so
|
// if we are dealing with the last chunk, it may be smaller than BINARY_CHUNK_SIZE
|
||||||
// we need to handle it slightly differently. we also append a byte with value 1
|
// bytes long, so we need to handle it slightly differently. We also append a byte
|
||||||
// to the end of the string; this pads the string in such a way that adding
|
// with value 1 to the end of the string; this pads the string in such a way that
|
||||||
// trailing zeros results in different hash
|
// adding trailing zeros results in different hash
|
||||||
let chunk_len = chunk.len();
|
let chunk_len = chunk.len();
|
||||||
buf = [0_u8; 8];
|
buf = [0_u8; 8];
|
||||||
buf[..chunk_len].copy_from_slice(chunk);
|
buf[..chunk_len].copy_from_slice(chunk);
|
||||||
|
@ -129,7 +133,7 @@ impl HashFn for Rpo256 {
|
||||||
// convert the bytes into a field element and absorb it into the rate portion of the
|
// convert the bytes into a field element and absorb it into the rate portion of the
|
||||||
// state; if the rate is filled up, apply the Rescue permutation and start absorbing
|
// state; if the rate is filled up, apply the Rescue permutation and start absorbing
|
||||||
// again from zero index.
|
// again from zero index.
|
||||||
state[RATE_RANGE.start + i] += Felt::new(u64::from_le_bytes(buf));
|
state[RATE_RANGE.start + i] = Felt::new(u64::from_le_bytes(buf));
|
||||||
i += 1;
|
i += 1;
|
||||||
if i % RATE_WIDTH == 0 {
|
if i % RATE_WIDTH == 0 {
|
||||||
Self::apply_permutation(&mut state);
|
Self::apply_permutation(&mut state);
|
||||||
|
@ -138,7 +142,7 @@ impl HashFn for Rpo256 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we absorbed some elements but didn't apply a permutation to them (would happen when
|
// if we absorbed some elements but didn't apply a permutation to them (would happen when
|
||||||
// the number of elements is not a multiple of RATE_WIDTH), apply the Rescue permutation.
|
// the number of elements is not a multiple of RATE_WIDTH), apply the RPO permutation.
|
||||||
// we don't need to apply any extra padding because we injected total number of elements
|
// we don't need to apply any extra padding because we injected total number of elements
|
||||||
// in the input list into the capacity portion of the state during initialization.
|
// in the input list into the capacity portion of the state during initialization.
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
|
|
Loading…
Add table
Reference in a new issue