diff --git a/src/plonk/config.rs b/src/plonk/config.rs index e448bc7c..c77ce5f5 100644 --- a/src/plonk/config.rs +++ b/src/plonk/config.rs @@ -8,10 +8,12 @@ use crate::field::extension_field::quadratic::QuadraticExtension; use crate::field::extension_field::{Extendable, FieldExtension}; use crate::field::field_types::RichField; use crate::field::goldilocks_field::GoldilocksField; +use crate::gates::gmimc::GMiMCGate; use crate::gates::poseidon::PoseidonGate; use crate::hash::hash_types::{BytesHash, HashOut}; use crate::hash::hashing::{ - compress, hash_n_to_hash, PlonkyPermutation, PoseidonPermutation, SPONGE_WIDTH, + compress, hash_n_to_hash, GMiMCPermutation, PlonkyPermutation, PoseidonPermutation, + SPONGE_WIDTH, }; use crate::iop::target::{BoolTarget, Target}; use crate::plonk::circuit_builder::CircuitBuilder; @@ -106,55 +108,54 @@ impl AlgebraicHasher for PoseidonHash { } } -// TODO: Remove width from `GMiMCGate` to make this work. -// #[derive(Copy, Clone, Debug, Eq, PartialEq)] -// pub struct GMiMCHash; -// impl Hasher for GMiMCHash { -// const HASH_SIZE: usize = 4 * 8; -// type Hash = HashOut; -// -// fn hash(input: Vec, pad: bool) -> Self::Hash { -// hash_n_to_hash::>::Permutation>(input, pad) -// } -// -// fn two_to_one(left: Self::Hash, right: Self::Hash) -> Self::Hash { -// compress::>::Permutation>(left, right) -// } -// } -// -// impl AlgebraicHasher for GMiMCHash { -// type Permutation = GMiMCPermutation; -// -// fn permute_swapped( -// inputs: [Target; WIDTH], -// swap: BoolTarget, -// builder: &mut CircuitBuilder, -// ) -> [Target; WIDTH] -// where -// F: Extendable, -// { -// let gate_type = GMiMCGate::::new(); -// let gate = builder.add_gate(gate_type, vec![]); -// -// let swap_wire = GMiMCGate::::WIRE_SWAP; -// let swap_wire = Target::wire(gate, swap_wire); -// builder.connect(swap.target, swap_wire); -// -// // Route input wires. -// for i in 0..W { -// let in_wire = GMiMCGate::::wire_input(i); -// let in_wire = Target::wire(gate, in_wire); -// builder.connect(inputs[i], in_wire); -// } -// -// // Collect output wires. -// (0..W) -// .map(|i| Target::wire(gate, input: GMiMCGate::wire_output(i))) -// .collect::>() -// .try_into() -// .unwrap() -// } -// } +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct GMiMCHash; +impl Hasher for GMiMCHash { + const HASH_SIZE: usize = 4 * 8; + type Hash = HashOut; + + fn hash(input: Vec, pad: bool) -> Self::Hash { + hash_n_to_hash::>::Permutation>(input, pad) + } + + fn two_to_one(left: Self::Hash, right: Self::Hash) -> Self::Hash { + compress::>::Permutation>(left, right) + } +} + +impl AlgebraicHasher for GMiMCHash { + type Permutation = GMiMCPermutation; + + fn permute_swapped( + inputs: [Target; SPONGE_WIDTH], + swap: BoolTarget, + builder: &mut CircuitBuilder, + ) -> [Target; SPONGE_WIDTH] + where + F: Extendable, + { + let gate_type = GMiMCGate::::new(); + let gate = builder.add_gate(gate_type, vec![]); + + let swap_wire = GMiMCGate::::WIRE_SWAP; + let swap_wire = Target::wire(gate, swap_wire); + builder.connect(swap.target, swap_wire); + + // Route input wires. + for i in 0..SPONGE_WIDTH { + let in_wire = GMiMCGate::::wire_input(i); + let in_wire = Target::wire(gate, in_wire); + builder.connect(inputs[i], in_wire); + } + + // Collect output wires. + (0..SPONGE_WIDTH) + .map(|i| Target::wire(gate, GMiMCGate::::wire_output(i))) + .collect::>() + .try_into() + .unwrap() + } +} /// Keccak-256 hash function. #[derive(Copy, Clone, Debug, Eq, PartialEq)] @@ -225,6 +226,16 @@ impl AlgebraicConfig<2> for PoseidonGoldilocksConfig { type InnerHasher = PoseidonHash; } +/// Configuration using GMiMC over the Goldilocks field. +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub struct GMiMCGoldilocksConfig; +impl AlgebraicConfig<2> for GMiMCGoldilocksConfig { + type F = GoldilocksField; + type FE = QuadraticExtension; + type Hasher = GMiMCHash; + type InnerHasher = GMiMCHash; +} + /// Configuration using truncated Keccak over the Goldilocks field. #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub struct KeccakGoldilocksConfig;