mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-04 23:03:08 +00:00
Use outer hash in Challenger
This commit is contained in:
parent
c126641c5d
commit
314a5845b7
@ -135,7 +135,7 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>
|
||||
pub(crate) fn open_plonk(
|
||||
commitments: &[&Self; 4],
|
||||
zeta: F::Extension,
|
||||
challenger: &mut Challenger<F, C::InnerHasher>,
|
||||
challenger: &mut Challenger<F, C::Hasher>,
|
||||
common_data: &CommonCircuitData<F, C, D>,
|
||||
timing: &mut TimingTree,
|
||||
) -> (FriProof<F, C::Hasher, D>, OpeningSet<F, D>) {
|
||||
|
||||
@ -21,7 +21,7 @@ pub fn fri_proof<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const
|
||||
lde_polynomial_coeffs: PolynomialCoeffs<F::Extension>,
|
||||
// Evaluation of the polynomial on the large domain.
|
||||
lde_polynomial_values: PolynomialValues<F::Extension>,
|
||||
challenger: &mut Challenger<F, C::InnerHasher>,
|
||||
challenger: &mut Challenger<F, C::Hasher>,
|
||||
common_data: &CommonCircuitData<F, C, D>,
|
||||
timing: &mut TimingTree,
|
||||
) -> FriProof<F, C::Hasher, D> {
|
||||
@ -63,7 +63,7 @@ pub fn fri_proof<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const
|
||||
fn fri_committed_trees<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>(
|
||||
mut coeffs: PolynomialCoeffs<F::Extension>,
|
||||
mut values: PolynomialValues<F::Extension>,
|
||||
challenger: &mut Challenger<F, C::InnerHasher>,
|
||||
challenger: &mut Challenger<F, C::Hasher>,
|
||||
common_data: &CommonCircuitData<F, C, D>,
|
||||
) -> (
|
||||
Vec<MerkleTree<F, C::Hasher>>,
|
||||
@ -140,7 +140,7 @@ fn fri_prover_query_rounds<
|
||||
>(
|
||||
initial_merkle_trees: &[&MerkleTree<F, C::Hasher>],
|
||||
trees: &[MerkleTree<F, C::Hasher>],
|
||||
challenger: &mut Challenger<F, C::InnerHasher>,
|
||||
challenger: &mut Challenger<F, C::Hasher>,
|
||||
n: usize,
|
||||
common_data: &CommonCircuitData<F, C, D>,
|
||||
) -> Vec<FriQueryRound<F, C::Hasher, D>> {
|
||||
@ -156,7 +156,7 @@ fn fri_prover_query_round<
|
||||
>(
|
||||
initial_merkle_trees: &[&MerkleTree<F, C::Hasher>],
|
||||
trees: &[MerkleTree<F, C::Hasher>],
|
||||
challenger: &mut Challenger<F, C::InnerHasher>,
|
||||
challenger: &mut Challenger<F, C::Hasher>,
|
||||
n: usize,
|
||||
common_data: &CommonCircuitData<F, C, D>,
|
||||
) -> FriQueryRound<F, C::Hasher, D> {
|
||||
|
||||
@ -15,7 +15,7 @@ use crate::plonk::proof::{OpeningSet, OpeningSetTarget};
|
||||
|
||||
/// Observes prover messages, and generates challenges by hashing the transcript, a la Fiat-Shamir.
|
||||
#[derive(Clone)]
|
||||
pub struct Challenger<F: RichField, H: AlgebraicHasher<F>> {
|
||||
pub struct Challenger<F: RichField, H: Hasher<F>> {
|
||||
sponge_state: [F; SPONGE_WIDTH],
|
||||
input_buffer: Vec<F>,
|
||||
output_buffer: Vec<F>,
|
||||
@ -30,7 +30,7 @@ pub struct Challenger<F: RichField, H: AlgebraicHasher<F>> {
|
||||
/// design, but it can be viewed as a duplex sponge whose inputs are sometimes zero (when we perform
|
||||
/// multiple squeezes) and whose outputs are sometimes ignored (when we perform multiple
|
||||
/// absorptions). Thus the security properties of a duplex sponge still apply to our design.
|
||||
impl<F: RichField, H: AlgebraicHasher<F>> Challenger<F, H> {
|
||||
impl<F: RichField, H: Hasher<F>> Challenger<F, H> {
|
||||
pub fn new() -> Challenger<F, H> {
|
||||
Challenger {
|
||||
sponge_state: [F::ZERO; SPONGE_WIDTH],
|
||||
|
||||
@ -34,6 +34,9 @@ pub trait Hasher<F: RichField>: Sized + Clone + Debug + Eq + PartialEq {
|
||||
const HASH_SIZE: usize;
|
||||
type Hash: GenericHashOut<F>;
|
||||
|
||||
/// Permutation used in the sponge construction.
|
||||
type Permutation: PlonkyPermutation<F>;
|
||||
|
||||
fn hash(input: Vec<F>, pad: bool) -> Self::Hash;
|
||||
fn two_to_one(left: Self::Hash, right: Self::Hash) -> Self::Hash;
|
||||
}
|
||||
@ -43,8 +46,6 @@ pub trait AlgebraicHasher<F: RichField>: Hasher<F, Hash = HashOut<F>> {
|
||||
// TODO: Adding a `const WIDTH: usize` here yields a compiler error down the line.
|
||||
// Maybe try again in a while.
|
||||
|
||||
/// Permutation used in the sponge construction.
|
||||
type Permutation: PlonkyPermutation<F>;
|
||||
/// Circuit to conditionally swap two chunks of the inputs (useful in verifying Merkle proofs),
|
||||
/// then apply the permutation.
|
||||
fn permute_swapped<const D: usize>(
|
||||
@ -62,19 +63,18 @@ pub struct PoseidonHash;
|
||||
impl<F: RichField> Hasher<F> for PoseidonHash {
|
||||
const HASH_SIZE: usize = 4 * 8;
|
||||
type Hash = HashOut<F>;
|
||||
type Permutation = PoseidonPermutation;
|
||||
|
||||
fn hash(input: Vec<F>, pad: bool) -> Self::Hash {
|
||||
hash_n_to_hash::<F, <Self as AlgebraicHasher<F>>::Permutation>(input, pad)
|
||||
hash_n_to_hash::<F, Self::Permutation>(input, pad)
|
||||
}
|
||||
|
||||
fn two_to_one(left: Self::Hash, right: Self::Hash) -> Self::Hash {
|
||||
compress::<F, <Self as AlgebraicHasher<F>>::Permutation>(left, right)
|
||||
compress::<F, Self::Permutation>(left, right)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: RichField> AlgebraicHasher<F> for PoseidonHash {
|
||||
type Permutation = PoseidonPermutation;
|
||||
|
||||
fn permute_swapped<const D: usize>(
|
||||
inputs: [Target; SPONGE_WIDTH],
|
||||
swap: BoolTarget,
|
||||
@ -111,19 +111,18 @@ pub struct GMiMCHash;
|
||||
impl<F: RichField> Hasher<F> for GMiMCHash {
|
||||
const HASH_SIZE: usize = 4 * 8;
|
||||
type Hash = HashOut<F>;
|
||||
type Permutation = GMiMCPermutation;
|
||||
|
||||
fn hash(input: Vec<F>, pad: bool) -> Self::Hash {
|
||||
hash_n_to_hash::<F, <Self as AlgebraicHasher<F>>::Permutation>(input, pad)
|
||||
hash_n_to_hash::<F, Self::Permutation>(input, pad)
|
||||
}
|
||||
|
||||
fn two_to_one(left: Self::Hash, right: Self::Hash) -> Self::Hash {
|
||||
compress::<F, <Self as AlgebraicHasher<F>>::Permutation>(left, right)
|
||||
compress::<F, Self::Permutation>(left, right)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: RichField> AlgebraicHasher<F> for GMiMCHash {
|
||||
type Permutation = GMiMCPermutation;
|
||||
|
||||
fn permute_swapped<const D: usize>(
|
||||
inputs: [Target; SPONGE_WIDTH],
|
||||
swap: BoolTarget,
|
||||
@ -155,12 +154,45 @@ impl<F: RichField> AlgebraicHasher<F> for GMiMCHash {
|
||||
}
|
||||
}
|
||||
|
||||
/// Keccak-256 permutation used in the challenger.
|
||||
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());
|
||||
}
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
||||
/// Keccak-256 hash function.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub struct KeccakHash<const N: usize>;
|
||||
impl<F: RichField, const N: usize> Hasher<F> for KeccakHash<N> {
|
||||
const HASH_SIZE: usize = N;
|
||||
type Hash = BytesHash<N>;
|
||||
type Permutation = KeccakPermutation;
|
||||
|
||||
fn hash(input: Vec<F>, _pad: bool) -> Self::Hash {
|
||||
let mut buffer = Buffer::new(Vec::new());
|
||||
|
||||
@ -32,7 +32,7 @@ fn get_challenges<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, cons
|
||||
let num_fri_queries = config.fri_config.num_query_rounds;
|
||||
let lde_size = common_data.lde_size();
|
||||
|
||||
let mut challenger = Challenger::<F, C::InnerHasher>::new();
|
||||
let mut challenger = Challenger::<F, C::Hasher>::new();
|
||||
|
||||
// Observe the instance.
|
||||
challenger.observe_hash::<C::Hasher>(common_data.circuit_digest);
|
||||
|
||||
@ -79,7 +79,7 @@ pub(crate) fn prove<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, co
|
||||
)
|
||||
);
|
||||
|
||||
let mut challenger = Challenger::new();
|
||||
let mut challenger = Challenger::<F, C::Hasher>::new();
|
||||
|
||||
// Observe the instance.
|
||||
challenger.observe_hash::<C::Hasher>(common_data.circuit_digest);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user