mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-09 09:13:09 +00:00
PR feedback
This commit is contained in:
parent
77a2fc6100
commit
7b03ebe1b8
@ -1,3 +1,5 @@
|
||||
use std::mem::size_of;
|
||||
|
||||
use keccak_hash::keccak;
|
||||
|
||||
use crate::hash::hash_types::{BytesHash, RichField};
|
||||
@ -5,37 +7,49 @@ use crate::hash::hashing::{PlonkyPermutation, SPONGE_WIDTH};
|
||||
use crate::plonk::config::Hasher;
|
||||
use crate::util::serialization::Buffer;
|
||||
|
||||
/// Keccak-256 permutation used in the challenger.
|
||||
/// Keccak-256 pseudo-permutation (not necessarily one-to-one) used in the challenger.
|
||||
/// A state `input: [F; 12]` is sent to the field representation of `H(input) || H(H(input)) || H(H(H(input)))`
|
||||
/// where `H` is the Keccak-256 hash.
|
||||
pub struct KeccakPermutation;
|
||||
impl<F: RichField> PlonkyPermutation<F> for KeccakPermutation {
|
||||
fn permute(input: [F; SPONGE_WIDTH]) -> [F; SPONGE_WIDTH] {
|
||||
// Fill a byte array with the little-endian representation of the field array.
|
||||
let mut buffer = [0u8; SPONGE_WIDTH * std::mem::size_of::<u64>()];
|
||||
for i in 0..SPONGE_WIDTH {
|
||||
buffer[i * std::mem::size_of::<F>()..(i + 1) * std::mem::size_of::<F>()]
|
||||
.copy_from_slice(&input[i].to_canonical_u64().to_le_bytes());
|
||||
// Use rejection sampling so that if one of the `u64` values in the output is larger than
|
||||
// the field order, we increment the nonce and start again.
|
||||
'rejection_sampling: for nonce in 0u64.. {
|
||||
// Fill a byte array with the little-endian representation of the field array.
|
||||
let mut buffer = [0u8; (SPONGE_WIDTH + 1) * size_of::<u64>()];
|
||||
for i in 0..SPONGE_WIDTH {
|
||||
buffer[i * size_of::<u64>()..(i + 1) * size_of::<u64>()]
|
||||
.copy_from_slice(&input[i].to_canonical_u64().to_le_bytes());
|
||||
}
|
||||
// Add the nonce at the end of the buffer.
|
||||
buffer[SPONGE_WIDTH * size_of::<u64>()..].copy_from_slice(&nonce.to_le_bytes());
|
||||
// Concatenate `H(input), H(H(input)), H(H(H(input)))`.
|
||||
let permutated_input_bytes = {
|
||||
let mut ans = [0u8; 96];
|
||||
ans[0..32].copy_from_slice(&keccak(buffer).0);
|
||||
ans[32..64].copy_from_slice(&keccak(keccak(buffer).0).0);
|
||||
ans[64..96].copy_from_slice(&keccak(keccak(keccak(buffer).0).0).0);
|
||||
ans
|
||||
};
|
||||
// Write the hashed byte array to a field array.
|
||||
let mut permutated_input = [F::ZERO; SPONGE_WIDTH];
|
||||
for i in 0..SPONGE_WIDTH {
|
||||
let perm_u64 = u64::from_le_bytes(
|
||||
permutated_input_bytes[i * size_of::<u64>()..(i + 1) * size_of::<u64>()]
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
);
|
||||
if perm_u64 >= F::ORDER {
|
||||
// If a value is larger than the field order, we break and start again with a new nonce.
|
||||
continue 'rejection_sampling;
|
||||
} else {
|
||||
permutated_input[i] = F::from_canonical_u64(perm_u64);
|
||||
}
|
||||
}
|
||||
return permutated_input;
|
||||
}
|
||||
// Concatenate `H(input), H(H(input)), H(H(H(input)))`.
|
||||
let permutated_input_bytes = {
|
||||
let mut ans = [0u8; 96];
|
||||
ans[0..32].copy_from_slice(&keccak(buffer).0);
|
||||
ans[32..64].copy_from_slice(&keccak(keccak(buffer).0).0);
|
||||
ans[64..96].copy_from_slice(&keccak(keccak(keccak(buffer).0).0).0);
|
||||
ans
|
||||
};
|
||||
// Write the hashed byte array to a field array.
|
||||
let mut permutated_input = [F::ZERO; SPONGE_WIDTH];
|
||||
for i in 0..SPONGE_WIDTH {
|
||||
permutated_input[i] = F::from_noncanonical_u64(u64::from_le_bytes(
|
||||
permutated_input_bytes
|
||||
[i * std::mem::size_of::<F>()..(i + 1) * std::mem::size_of::<F>()]
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
));
|
||||
}
|
||||
permutated_input
|
||||
panic!("Improbable.")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user