From 1140abb9f0b9b2099cd551f987119e67a5abab40 Mon Sep 17 00:00:00 2001 From: Ho Vei Date: Thu, 12 Jan 2023 11:14:23 +0800 Subject: [PATCH 01/10] Squashed commit of the following: commit a9ec2633504ac48460b5a72d6d889ae18d55c393 Author: Ho Vei Date: Thu Jan 12 11:13:13 2023 +0800 better organize --- src/hash.rs | 152 +++++++++++++++++++++++------------------- tests/hash_proving.rs | 110 +++++++++++++++++++----------- 2 files changed, 155 insertions(+), 107 deletions(-) diff --git a/src/hash.rs b/src/hash.rs index 95ff28f..8c1b8bf 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -3,12 +3,8 @@ use crate::poseidon::primitives::{ ConstantLengthIden3, Domain, Hash, P128Pow5T3, Spec, VariableLengthIden3, }; +use halo2_proofs::arithmetic::FieldExt; use halo2_proofs::halo2curves::bn256::Fr; -use halo2_proofs::{arithmetic::FieldExt, circuit::Chip}; - -trait PoseidonChip: Chip { - fn construct(config: &Self::Config) -> Self; -} /// indicate an field can be hashed in merkle tree (2 Fields to 1 Field) pub trait Hashable: FieldExt { @@ -62,16 +58,14 @@ impl MessageHashable for Fr { use crate::poseidon::{PoseidonInstructions, Pow5Chip, Pow5Config, StateWord, Var}; use halo2_proofs::{ - circuit::{Layouter, SimpleFloorPlanner, Value}, - plonk::{ - Advice, Circuit, Column, ConstraintSystem, Error, Expression, Fixed, Selector, TableColumn, - }, + circuit::{Chip, Layouter, Value}, + plonk::{Advice, Column, ConstraintSystem, Error, Expression, Fixed, Selector, TableColumn}, poly::Rotation, }; -/// The config for hash circuit +/// The config for poseidon hash circuit #[derive(Clone, Debug)] -pub struct HashConfig { +pub struct PoseidonHashConfig { permute_config: Pow5Config, hash_table: [Column; 4], hash_table_aux: [Column; 6], @@ -82,7 +76,7 @@ pub struct HashConfig { s_table: Selector, } -impl HashConfig { +impl PoseidonHashConfig { /// obtain the commitment index of hash table pub fn commitment_index(&self) -> [usize; 4] { self.hash_table.map(|col| col.index()) @@ -226,11 +220,9 @@ impl HashConfig { } } -/// Hash circuit -#[derive(Clone, Default)] -pub struct HashCircuit { - /// the records in circuits - pub calcs: usize, +/// Poseidon hash table +#[derive(Clone, Default, Debug)] +pub struct PoseidonHashTable { /// the input messages for hashes pub inputs: Vec<[Fp; 2]>, /// the control flag for each permutation @@ -239,17 +231,7 @@ pub struct HashCircuit { pub checks: Vec>, } -impl HashCircuit { - /// create circuit from traces - pub fn new(calcs: usize) -> Self { - Self { - calcs, - inputs: Vec::new(), - controls: Vec::new(), - checks: Vec::new(), - } - } - +impl PoseidonHashTable { /// Add common inputs pub fn constant_inputs<'d>(&mut self, src: impl IntoIterator) { let mut new_inps: Vec<_> = src.into_iter().copied().collect(); @@ -275,11 +257,12 @@ impl HashCircuit { &mut self, src: impl IntoIterator, ctrl_start: u64, + step: usize, ) { let mut new_inps: Vec<_> = src.into_iter().copied().collect(); let mut ctrl_series: Vec<_> = std::iter::successors(Some(ctrl_start), |n| { - if *n > (STEP as u64) { - Some(n - STEP as u64) + if *n > (step as u64) { + Some(n - step as u64) } else { None } @@ -292,13 +275,33 @@ impl HashCircuit { self.inputs.append(&mut new_inps); self.controls.append(&mut ctrl_series); } +} - /// load the whole circuit - pub fn load( - &self, - config: HashConfig, - layouter: &mut impl Layouter, - ) -> Result<(), Error> { +/// Represent the chip for Poseidon hash table +#[derive(Debug)] +pub struct PoseidonHashChip<'d, Fp: FieldExt, const STEP: usize> { + calcs: usize, + data: &'d PoseidonHashTable, + config: PoseidonHashConfig, +} + +impl<'d, Fp: Hashable, const STEP: usize> PoseidonHashChip<'d, Fp, STEP> { + ///construct the chip + pub fn construct( + config: PoseidonHashConfig, + data: &'d PoseidonHashTable, + calcs: usize, + ) -> Self { + Self { + calcs, + data, + config, + } + } + + /// load the table into circuit under the specified config + pub fn load(&self, layouter: &mut impl Layouter) -> Result<(), Error> { + let config = &self.config; let constants_cell = layouter.assign_region( || "constant heading", |mut region| { @@ -329,6 +332,7 @@ impl HashCircuit { }, )?; + let data = self.data; let (states_in, states_out) = layouter.assign_region( || "hash table", |mut region| { @@ -338,20 +342,20 @@ impl HashCircuit { let dummy_input: [Option<&[Fp; 2]>; 1] = [None]; let dummy_item: [Option<&Fp>; 1] = [None]; - let inputs_i = self + let inputs_i = data .inputs .iter() .map(Some) .chain(dummy_input.into_iter().cycle()) .take(self.calcs); - let controls_i = self + let controls_i = data .controls .iter() .map(Some) .chain(dummy_item.into_iter().cycle()) .take(self.calcs); - let checks_i = self + let checks_i = data .checks .iter() .map(|i| i.as_ref()) @@ -569,28 +573,15 @@ impl HashCircuit { } } -impl Circuit for HashCircuit { - type Config = HashConfig; - type FloorPlanner = SimpleFloorPlanner; - - fn without_witnesses(&self) -> Self { - Self { - calcs: self.calcs, - ..Default::default() - } - } +impl Chip for PoseidonHashChip<'_, Fp, STEP> { + type Config = PoseidonHashConfig; + type Loaded = PoseidonHashTable; - fn configure(meta: &mut ConstraintSystem) -> Self::Config { - let hash_tbl = [0; 4].map(|_| meta.advice_column()); - Self::Config::configure_sub(meta, hash_tbl, STEP) + fn config(&self) -> &Self::Config { + &self.config } - - fn synthesize( - &self, - config: Self::Config, - mut layouter: impl Layouter, - ) -> Result<(), Error> { - self.load(config, &mut layouter) + fn loaded(&self) -> &Self::Loaded { + self.data } } @@ -598,6 +589,7 @@ impl Circuit for HashCircuit { mod tests { use super::*; use halo2_proofs::halo2curves::group::ff::PrimeField; + use halo2_proofs::{circuit::SimpleFloorPlanner, plonk::Circuit}; #[test] fn poseidon_hash() { @@ -644,7 +636,36 @@ mod tests { } use halo2_proofs::dev::MockProver; - type HashCircuit = super::HashCircuit; + const TEST_STEP: usize = 32; + + // test circuit derived from table data + impl Circuit for PoseidonHashTable { + type Config = (PoseidonHashConfig, usize); + type FloorPlanner = SimpleFloorPlanner; + + fn without_witnesses(&self) -> Self { + Self { + ..Default::default() + } + } + + fn configure(meta: &mut ConstraintSystem) -> Self::Config { + let hash_tbl = [0; 4].map(|_| meta.advice_column()); + ( + PoseidonHashConfig::configure_sub(meta, hash_tbl, TEST_STEP), + 4, + ) + } + + fn synthesize( + &self, + (config, max_rows): Self::Config, + mut layouter: impl Layouter, + ) -> Result<(), Error> { + let chip = PoseidonHashChip::::construct(config, self, max_rows); + chip.load(&mut layouter) + } + } #[cfg(feature = "print_layout")] #[test] @@ -679,9 +700,8 @@ mod tests { Fr::from_str_vartime("3").unwrap(), ]; - let k = 7; - let circuit = HashCircuit { - calcs: 2, + let k = 8; + let circuit = PoseidonHashTable { inputs: vec![message1, message2], ..Default::default() }; @@ -699,8 +719,7 @@ mod tests { let message2 = [Fr::from_str_vartime("50331648").unwrap(), Fr::zero()]; let k = 8; - let circuit = HashCircuit { - calcs: 4, + let circuit = PoseidonHashTable { inputs: vec![message1, message2], controls: vec![Fr::from_u128(45), Fr::from_u128(13)], checks: vec![None, Some(Fr::from_str_vartime("15002881182751877599173281392790087382867290792048832034781070831698029191486").unwrap())], @@ -708,8 +727,7 @@ mod tests { let prover = MockProver::run(k, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); - let circuit = HashCircuit { - calcs: 4, + let circuit = PoseidonHashTable { inputs: vec![message1, message2, message1], controls: vec![Fr::from_u128(64), Fr::from_u128(32), Fr::zero()], checks: Vec::new(), diff --git a/tests/hash_proving.rs b/tests/hash_proving.rs index 40c97cd..ee148b9 100644 --- a/tests/hash_proving.rs +++ b/tests/hash_proving.rs @@ -13,10 +13,40 @@ use halo2_proofs::poly::kzg::strategy::SingleStrategy; use halo2_proofs::transcript::{ Blake2bRead, Blake2bWrite, Challenge255, TranscriptReadBuffer, TranscriptWriterBuffer, }; -use poseidon_circuit::{hash, DEFAULT_STEP}; +use halo2_proofs::{ + circuit::{Layouter, SimpleFloorPlanner}, + plonk::{Circuit, ConstraintSystem, Error}, +}; +use poseidon_circuit::{hash::*, DEFAULT_STEP}; use rand::SeedableRng; use rand_chacha::ChaCha8Rng; +struct TestCircuit(PoseidonHashTable, usize); + +// test circuit derived from table data +impl Circuit for TestCircuit { + type Config = PoseidonHashConfig; + type FloorPlanner = SimpleFloorPlanner; + + fn without_witnesses(&self) -> Self { + Self(PoseidonHashTable::default(), self.1) + } + + fn configure(meta: &mut ConstraintSystem) -> Self::Config { + let hash_tbl = [0; 4].map(|_| meta.advice_column()); + PoseidonHashConfig::configure_sub(meta, hash_tbl, DEFAULT_STEP) + } + + fn synthesize( + &self, + config: Self::Config, + mut layouter: impl Layouter, + ) -> Result<(), Error> { + let chip = PoseidonHashChip::::construct(config, &self.0, self.1); + chip.load(&mut layouter) + } +} + #[test] fn hash_circuit() { let message1 = [ @@ -29,11 +59,13 @@ fn hash_circuit() { ]; let k = 7; - let circuit = hash::HashCircuit:: { - inputs: vec![message1, message2], - calcs: 3, - ..Default::default() - }; + let circuit = TestCircuit( + PoseidonHashTable { + inputs: vec![message1, message2], + ..Default::default() + }, + 3, + ); let prover = MockProver::run(k, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); } @@ -42,29 +74,28 @@ fn hash_circuit() { fn vk_validity() { let params = Params::::unsafe_setup(8); - let circuit = hash::HashCircuit:: { - calcs: 3, - ..Default::default() - }; + let circuit = TestCircuit(PoseidonHashTable::default(), 3); let vk1 = keygen_vk(¶ms, &circuit).unwrap(); let mut vk1_buf: Vec = Vec::new(); vk1.write(&mut vk1_buf).unwrap(); - let circuit = hash::HashCircuit:: { - inputs: vec![ - [ - Fp::from_str_vartime("1").unwrap(), - Fp::from_str_vartime("2").unwrap(), + let circuit = TestCircuit( + PoseidonHashTable { + inputs: vec![ + [ + Fp::from_str_vartime("1").unwrap(), + Fp::from_str_vartime("2").unwrap(), + ], + [ + Fp::from_str_vartime("0").unwrap(), + Fp::from_str_vartime("1").unwrap(), + ], ], - [ - Fp::from_str_vartime("0").unwrap(), - Fp::from_str_vartime("1").unwrap(), - ], - ], - calcs: 3, - ..Default::default() - }; + ..Default::default() + }, + 3, + ); let vk2 = keygen_vk(¶ms, &circuit).unwrap(); let mut vk2_buf: Vec = Vec::new(); @@ -81,20 +112,22 @@ fn proof_and_verify() { let os_rng = ChaCha8Rng::from_seed([101u8; 32]); let mut transcript = Blake2bWrite::<_, G1Affine, Challenge255<_>>::init(vec![]); - let circuit = hash::HashCircuit:: { - inputs: vec![ - [ - Fp::from_str_vartime("1").unwrap(), - Fp::from_str_vartime("2").unwrap(), + let circuit = TestCircuit( + PoseidonHashTable { + inputs: vec![ + [ + Fp::from_str_vartime("1").unwrap(), + Fp::from_str_vartime("2").unwrap(), + ], + [ + Fp::from_str_vartime("0").unwrap(), + Fp::from_str_vartime("1").unwrap(), + ], ], - [ - Fp::from_str_vartime("0").unwrap(), - Fp::from_str_vartime("1").unwrap(), - ], - ], - calcs: 3, - ..Default::default() - }; + ..Default::default() + }, + 4, + ); let prover = MockProver::run(k, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); @@ -116,10 +149,7 @@ fn proof_and_verify() { let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof_script[..]); let verifier_params: ParamsVerifier = params.verifier_params().clone(); let strategy = SingleStrategy::new(¶ms); - let circuit = hash::HashCircuit:: { - calcs: 3, - ..Default::default() - }; + let circuit = TestCircuit(PoseidonHashTable::default(), 4); let vk = keygen_vk(¶ms, &circuit).unwrap(); assert!( From c3cd6effe61b123c6bfcd3ce76281e534cd9c329 Mon Sep 17 00:00:00 2001 From: Ho Vei Date: Thu, 26 Jan 2023 11:41:46 +0800 Subject: [PATCH 02/10] add test for short messages --- src/hash.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/hash.rs b/src/hash.rs index 8c1b8bf..ecfbc94 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -734,5 +734,21 @@ mod tests { }; let prover = MockProver::run(k, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); + + let circuit = PoseidonHashTable:: { + inputs: vec![message2], + controls: vec![Fr::from_u128(13)], + ..Default::default() + }; + let prover = MockProver::run(k, &circuit, vec![]).unwrap(); + assert_eq!(prover.verify(), Ok(())); + + + let circuit = PoseidonHashTable:: { + ..Default::default() + }; + let prover = MockProver::run(k, &circuit, vec![]).unwrap(); + assert_eq!(prover.verify(), Ok(())); + } } From 7c681a98c07a4badf9755cce4c4b86985d3da9cc Mon Sep 17 00:00:00 2001 From: Ho Vei Date: Fri, 3 Feb 2023 10:17:11 +0800 Subject: [PATCH 03/10] Squashed commit of the following: commit 0c81d5677629c376ae46ee8c3f3479692d0309ba Author: Ho Vei Date: Fri Feb 3 10:16:05 2023 +0800 api on row/circuit size and fmt commit 03c0e159305afdf1466e23eaf71b2d8f2408b729 Author: Ho Vei Date: Thu Feb 2 23:46:54 2023 +0800 clippy for formatted string commit 035f6eb08c1c2e65d717dd531813e5d4f65dc7ab Author: Ho Vei Date: Thu Feb 2 23:46:37 2023 +0800 refactoring assignment and optimize constraintions commit 5fbf04016759082bd4e9e3aafd96daf7ca17aa3b Author: Ho Vei Date: Thu Feb 2 23:45:47 2023 +0800 bump toolchain commit f964a07fd2041eadf94a90cf7a99de67af3ccb68 Author: Ho Vei Date: Wed Feb 1 22:34:17 2023 +0800 constraint for custom row and tougher test commit 01535c16598a80c221dc80932dad682e89e80275 Author: Ho Vei Date: Wed Feb 1 21:56:57 2023 +0800 extend hash table and add missed constraints commit 7d0f5544914cb748a927989c06af85908c5885d1 Author: Ho Vei Date: Wed Feb 1 15:02:31 2023 +0800 upgrade bitvec --- Cargo.toml | 6 +- rust-toolchain | 2 +- spec/hash-table.md | 31 +- src/hash.rs | 547 ++++++++++++++------------ src/poseidon.rs | 2 +- src/poseidon/pow5.rs | 18 +- src/poseidon/primitives.rs | 4 +- src/poseidon/primitives/grain.rs | 4 +- src/poseidon/primitives/p128pow5t3.rs | 2 +- tests/hash_proving.rs | 11 +- 10 files changed, 350 insertions(+), 277 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b8baddc..09a4362 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,11 +9,7 @@ edition = "2021" halo2_proofs = { git = "https://github.com/scroll-tech/halo2.git", branch = "scroll-dev-1220" } lazy_static = "1.4.0" thiserror = "1.0" -bitvec = "0.22" - -[patch.crates-io] -# temporary solution to funty@1.2.0 being yanked, tracking issue: https://github.com/ferrilab/funty/issues/7 -funty = { git = "https://github.com/ferrilab/funty/", rev = "7ef0d890fbcd8b3def1635ac1a877fc298488446" } +bitvec = "1" [features] # printout the layout of circuits for demo and some unittests diff --git a/rust-toolchain b/rust-toolchain index 7d80f30..60d6790 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -nightly-2022-08-23 \ No newline at end of file +nightly-2022-12-10 \ No newline at end of file diff --git a/spec/hash-table.md b/spec/hash-table.md index c9d6588..91d9e56 100644 --- a/spec/hash-table.md +++ b/spec/hash-table.md @@ -14,17 +14,17 @@ ## Interface Table -The hash circuit exposes a table containing multiple inputs/output pairs. This table can be looked up by the MPT and codehash circuits. The table has four columns: 2 inputs, 1 digest output, and 1 for control flags. +The hash circuit exposes a table containing multiple inputs/output pairs. This table can be looked up by the MPT and codehash circuits. The table has four columns: 2 inputs, 1 digest output, 2 for control flags and additional marking. -| 0: Hash index | 1: Message | 2: Message | 3: Control flag | -| --------------- | ---------------- | --------------- | --------------- | -| MPT digest | MPT input 1 | MPT input 2 | 0 | -| | | | | -| var-len digest | word 0 | word 1 | 2000 | -| var-len digest | word 2 | word 3 | 1968 | -| ... | ... | ... | ... | -| var-len digest | word W-2 | word W-1 | 16 | -| | | | | +| 0: Hash index | 1: Message | 2: Message | 3: Control flag | 4: Head flag | +| --------------- | ---------------- | --------------- | --------------- | ------------ | +| MPT digest | MPT input 1 | MPT input 2 | 0 | 1 | +| | | | | | +| var-len digest | word 0 | word 1 | 2000 | 1 | +| var-len digest | word 2 | word 3 | 1968 | 0 | +| ... | ... | ... | ... | 0 | +| var-len digest | word W-2 | word W-1 | 16 | 0 | +| | | | | | The hash circuit supports two modes: @@ -49,6 +49,17 @@ Compute the digest of a variable-length message. One such entry is composed of c Specifically, `STEP = 32`. +### Head flag + +The head flag is set at each beginning of message, i.e each row under MPT mode and the first row of message in Var-Len mode would be set to 1 + +### Custom row + +2 Additional row is put at the beginning of hash table: + +1. A row being filled with 0 for any lookup which is not enabled +2. A row with `control` and `Message` field being set to 0 and the hash is set to a customed value for representing +the hash of empty message. Currently it is set to equal to `keccak256(nil)` and the indexed hash value must be properly set under challenge API ## Internal Table (hash_table_aux) diff --git a/src/hash.rs b/src/hash.rs index ecfbc94..1e141ae 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -58,7 +58,7 @@ impl MessageHashable for Fr { use crate::poseidon::{PoseidonInstructions, Pow5Chip, Pow5Config, StateWord, Var}; use halo2_proofs::{ - circuit::{Chip, Layouter, Value}, + circuit::{Chip, Layouter, Region, Value}, plonk::{Advice, Column, ConstraintSystem, Error, Expression, Fixed, Selector, TableColumn}, poly::Rotation, }; @@ -67,42 +67,43 @@ use halo2_proofs::{ #[derive(Clone, Debug)] pub struct PoseidonHashConfig { permute_config: Pow5Config, - hash_table: [Column; 4], + hash_table: [Column; 5], hash_table_aux: [Column; 6], control_aux: Column, s_sponge_continue: Column, constants: [Column; 6], control_step_range: TableColumn, s_table: Selector, + s_custom: Selector, } impl PoseidonHashConfig { /// obtain the commitment index of hash table - pub fn commitment_index(&self) -> [usize; 4] { + pub fn commitment_index(&self) -> [usize; 5] { self.hash_table.map(|col| col.index()) } /// obtain the hash_table columns - pub fn hash_tbl_cols(&self) -> [Column; 4] { + pub fn hash_tbl_cols(&self) -> [Column; 5] { self.hash_table } /// build configure for sub circuit pub fn configure_sub( meta: &mut ConstraintSystem, - hash_table: [Column; 4], + hash_table: [Column; 5], step: usize, ) -> Self { let state = [0; 3].map(|_| meta.advice_column()); let partial_sbox = meta.advice_column(); let constants = [0; 6].map(|_| meta.fixed_column()); - let s_table = meta.complex_selector(); + let s_table = meta.selector(); + let s_custom = meta.selector(); let hash_table_aux = [0; 6].map(|_| meta.advice_column()); for col in hash_table_aux.iter().chain(hash_table[0..1].iter()) { meta.enable_equality(*col); } - meta.enable_equality(constants[0]); let control = hash_table[3]; let s_sponge_continue = meta.advice_column(); @@ -115,41 +116,68 @@ impl PoseidonHashConfig { let hash_out = hash_table_aux[5]; let hash_inp = &hash_table[1..3]; let hash_index = hash_table[0]; + let header_mark = hash_table[4]; + + meta.create_gate("custom row", |meta| { + let s_enable = meta.query_selector(s_custom); + + vec![ + s_enable.clone() * meta.query_advice(hash_inp[0], Rotation::cur()), + s_enable.clone() * meta.query_advice(hash_inp[1], Rotation::cur()), + s_enable * meta.query_advice(control, Rotation::cur()), + ] + }); meta.create_gate("control constrain", |meta| { + /* + s_continue must be bool + s_continue must be false on each row which control is 0 (MPT mode) + header_mark is just not(s_continue) + */ let s_enable = meta.query_selector(s_table); let ctrl = meta.query_advice(control, Rotation::cur()); let ctrl_bool = ctrl.clone() * meta.query_advice(control_aux, Rotation::cur()); let s_continue = meta.query_advice(s_sponge_continue, Rotation::cur()); vec![ + s_enable.clone() + * s_continue.clone() + * (Expression::Constant(Fp::one()) - s_continue.clone()), s_enable.clone() * ctrl * (Expression::Constant(Fp::one()) - ctrl_bool.clone()), - s_enable * s_continue * (Expression::Constant(Fp::one()) - ctrl_bool), + s_enable.clone() + * s_continue.clone() + * (Expression::Constant(Fp::one()) - ctrl_bool), + s_enable + * (Expression::Constant(Fp::one()) + - s_continue + - meta.query_advice(header_mark, Rotation::cur())), ] }); meta.create_gate("control step", |meta| { - let s_enable = meta.query_selector(s_table); + /* + when s_continue is true, it trigger a RANGE checking on the ctrl_prev + to less than or equal to **step** + and current ctrl can not be 0 + */ let s_continue = meta.query_advice(s_sponge_continue, Rotation::cur()); + let s_enable = meta.query_selector(s_table) * s_continue; let ctrl = meta.query_advice(control, Rotation::cur()); let ctrl_prev = meta.query_advice(control, Rotation::prev()); + let ctrl_bool = ctrl.clone() * meta.query_advice(control_aux, Rotation::cur()); vec![ - s_enable - * s_continue + s_enable.clone() * (ctrl + Expression::Constant(Fp::from_u128(step as u128)) - ctrl_prev), + s_enable * (Expression::Constant(Fp::one()) - ctrl_bool), ] }); meta.lookup("control range check", |meta| { - let s_enable = meta.query_selector(s_table); - let s_continue = meta.query_advice(s_sponge_continue, Rotation::cur()); + let s_enable = meta.query_advice(header_mark, Rotation::cur()); let ctrl = meta.query_advice(control, Rotation::prev()); - vec![( - s_enable * (Expression::Constant(Fp::one()) - s_continue) * ctrl, - control_step_range, - )] + vec![(s_enable * ctrl, control_step_range)] }); meta.create_gate("hash index constrain", |meta| { @@ -215,6 +243,7 @@ impl PoseidonHashConfig { constants, control_step_range, s_table, + s_custom, s_sponge_continue, } } @@ -229,6 +258,8 @@ pub struct PoseidonHashTable { pub controls: Vec, /// the expected hash output for checking pub checks: Vec>, + /// the custom hash for nil message + pub nil_msg_hash: Option, } impl PoseidonHashTable { @@ -275,6 +306,20 @@ impl PoseidonHashTable { self.inputs.append(&mut new_inps); self.controls.append(&mut ctrl_series); } + + /// return the row which poseidon table use (notice it maybe much smaller + /// than the actual circuit row required) + pub fn table_size(&self) -> usize { + self.inputs.len() + } +} + +impl PoseidonHashTable { + /// return minimum required the circuit rows\ + /// (size of hashes * rows required by each hash) + pub fn minimum_row_require(&self) -> usize { + self.inputs.len() * Fp::hash_block_size() + } } /// Represent the chip for Poseidon hash table @@ -285,6 +330,8 @@ pub struct PoseidonHashChip<'d, Fp: FieldExt, const STEP: usize> { config: PoseidonHashConfig, } +type PermutedState = Vec<[StateWord; 3]>; + impl<'d, Fp: Hashable, const STEP: usize> PoseidonHashChip<'d, Fp, STEP> { ///construct the chip pub fn construct( @@ -299,254 +346,251 @@ impl<'d, Fp: Hashable, const STEP: usize> PoseidonHashChip<'d, Fp, STEP> { } } - /// load the table into circuit under the specified config - pub fn load(&self, layouter: &mut impl Layouter) -> Result<(), Error> { + fn fill_hash_tbl_custom(&self, region: &mut Region<'_, Fp>) -> Result { let config = &self.config; - let constants_cell = layouter.assign_region( - || "constant heading", - |mut region| { - let c0 = region.assign_fixed( - || "constant zero", - config.constants[0], - 0, - || Value::known(Fp::zero()), - )?; - - Ok([c0]) - }, - )?; - layouter.assign_table( - || "STEP range check", - |mut table| { - (0..STEP + 1).into_iter().try_for_each(|i| { - table - .assign_cell( - || "STEP range check", - config.control_step_range, - i, - || Value::known(Fp::from_u128(i as u128)), - ) - .map(|_| ()) - }) - }, - )?; - - let data = self.data; - let (states_in, states_out) = layouter.assign_region( - || "hash table", - |mut region| { - let mut states_in = Vec::new(); - let mut states_out = Vec::new(); - let hash_helper = Fp::hasher(); - - let dummy_input: [Option<&[Fp; 2]>; 1] = [None]; - let dummy_item: [Option<&Fp>; 1] = [None]; - let inputs_i = data - .inputs - .iter() - .map(Some) - .chain(dummy_input.into_iter().cycle()) - .take(self.calcs); - let controls_i = data - .controls - .iter() - .map(Some) - .chain(dummy_item.into_iter().cycle()) - .take(self.calcs); - - let checks_i = data - .checks - .iter() - .map(|i| i.as_ref()) - .chain(dummy_item.into_iter().cycle()) - .take(self.calcs); - - // notice our hash table has a (0, 0, 0) at the beginning - for col in config.hash_table { - region.assign_advice(|| "dummy inputs", col, 0, || Value::known(Fp::zero()))?; - } - - for col in config.hash_table_aux { - region.assign_advice( - || "dummy aux inputs", - col, - 0, - || Value::known(Fp::zero()), - )?; - } + config.s_custom.enable(region, 0)?; + // all zero row + for (tip, cols) in [ + ("dummy inputs", config.hash_table.as_slice()), + ("dummy aux inputs", config.hash_table_aux.as_slice()), + ("control aux head", [config.control_aux].as_slice()), + ( + "control sponge continue head", + [config.s_sponge_continue].as_slice(), + ), + ] { + for col in cols { + region.assign_advice(|| tip, *col, 0, || Value::known(Fp::zero()))?; + } + } - region.assign_advice( - || "control aux head", - config.control_aux, - 0, - || Value::known(Fp::zero()), - )?; + config.s_custom.enable(region, 1)?; + // custom + for (tip, cols) in [ + ("custom inputs", &config.hash_table[1..4]), + ("custom aux inputs", config.hash_table_aux.as_slice()), + ("control aux head custom", [config.control_aux].as_slice()), + ( + "control sponge continue head custom", + [config.s_sponge_continue].as_slice(), + ), + ] { + for col in cols { + region.assign_advice(|| tip, *col, 1, || Value::known(Fp::zero()))?; + } + } - let c_ctrl = region.assign_advice( - || "control sponge continue head", - config.s_sponge_continue, - 0, - || Value::known(Fp::zero()), - )?; + // input, notice hash index constrain require we also assign hash_out col + for col in [config.hash_table_aux[5], config.hash_table[0]] { + region.assign_advice( + || "custom hash for nil", + col, + 1, + || { + self.data + .nil_msg_hash + .map(Value::known) + .unwrap_or_else(Value::unknown) + }, + )?; + } + region.assign_advice( + || "custom mark", + config.hash_table[4], + 1, + || Value::known(Fp::one()), + )?; - // contraint 0 to zero constant - region.constrain_equal(c_ctrl.cell(), constants_cell[0].cell())?; + Ok(2) + } - let mut is_new_sponge = true; - let mut process_start = 0; - let mut offset = 1; - let mut state: [Fp; 3] = [Fp::zero(); 3]; + fn fill_hash_tbl_body( + &self, + region: &mut Region<'_, Fp>, + begin_offset: usize, + ) -> Result<(PermutedState, PermutedState), Error> { + let config = &self.config; + let data = self.data; - for (i, ((inp, control), check)) in - inputs_i.zip(controls_i).zip(checks_i).enumerate() - { - let control = control.copied().unwrap_or_else(Fp::zero); - offset = i + 1; + let mut states_in = Vec::new(); + let mut states_out = Vec::new(); + let hash_helper = Fp::hasher(); + + let dummy_input: [Option<&[Fp; 2]>; 1] = [None]; + let dummy_item: [Option<&Fp>; 1] = [None]; + let inputs_i = data + .inputs + .iter() + .map(Some) + .chain(dummy_input.into_iter().cycle()) + .take(self.calcs); + let controls_i = data + .controls + .iter() + .map(Some) + .chain(dummy_item.into_iter().cycle()) + .take(self.calcs); + + let checks_i = data + .checks + .iter() + .map(|i| i.as_ref()) + .chain(dummy_item.into_iter().cycle()) + .take(self.calcs); + + let mut is_new_sponge = true; + let mut process_start = 0; + let mut state: [Fp; 3] = [Fp::zero(); 3]; + let mut last_offset = 0; + + for (i, ((inp, control), check)) in inputs_i.zip(controls_i).zip(checks_i).enumerate() { + let control = control.copied().unwrap_or_else(Fp::zero); + let offset = i + begin_offset; + last_offset = offset; + + if is_new_sponge { + state[0] = control; + process_start = offset; + } - if is_new_sponge { - state[0] = control; - process_start = offset; - } + let inp = inp + .map(|[a, b]| [*a, *b]) + .unwrap_or_else(|| [Fp::zero(), Fp::zero()]); - let inp = inp - .map(|[a, b]| [*a, *b]) - .unwrap_or_else(|| [Fp::zero(), Fp::zero()]); + state.iter_mut().skip(1).zip(inp).for_each(|(s, inp)| { + if is_new_sponge { + *s = inp; + } else { + *s += inp; + } + }); - state.iter_mut().skip(1).zip(inp).for_each(|(s, inp)| { - if is_new_sponge { - *s = inp; - } else { - *s += inp; - } - }); + let state_start = state; + hash_helper.permute(&mut state); //here we calculate the hash - let state_start = state; - hash_helper.permute(&mut state); //here we calculate the hash + //and sanity check ... + if let Some(ck) = check { + assert_eq!(*ck, state[0]); + } - //and sanity check ... - if let Some(ck) = check { - assert_eq!(*ck, state[0]); - } + let current_hash = state[0]; - config.s_table.enable(&mut region, offset)?; - - let c_start = [ - region.assign_advice( - || format!("state input 0_{}", i), - config.hash_table_aux[0], - offset, - || Value::known(state_start[0]), - )?, - region.assign_advice( - || format!("state input 1_{}", i), - config.hash_table_aux[1], - offset, - || Value::known(state_start[1]), - )?, - region.assign_advice( - || format!("state input 2_{}", i), - config.hash_table_aux[2], - offset, - || Value::known(state_start[2]), - )?, - ]; - - let current_hash = state[0]; - let c_end = [ - region.assign_advice( - || format!("state output hash_{}", i), - config.hash_table_aux[5], - offset, - || Value::known(state[0]), - )?, - region.assign_advice( - || format!("state output 1_{}", i), - config.hash_table_aux[3], - offset, - || Value::known(state[1]), - )?, - region.assign_advice( - || format!("state output 2_{}", i), - config.hash_table_aux[4], - offset, - || Value::known(state[2]), - )?, - ]; + //assignment ... + config.s_table.enable(region, offset)?; + let c_start = [0; 3] + .into_iter() + .enumerate() + .map(|(i, _)| { region.assign_advice( - || format!("state input control_{}", i), - config.hash_table[3], + || format!("state input {i}_{offset}"), + config.hash_table_aux[i], offset, - || Value::known(control), - )?; + || Value::known(state_start[i]), + ) + }) + .collect::, _>>()?; + let c_end = [5, 3, 4] + .into_iter() + .enumerate() + .map(|(i, j)| { region.assign_advice( - || format!("state input control_aux_{}", i), - config.control_aux, + || format!("state output {i}_{offset}"), + config.hash_table_aux[j], offset, - || Value::known(control.invert().unwrap_or_else(Fp::zero)), - )?; + || Value::known(state[i]), + ) + }) + .collect::, _>>()?; + + for (tip, col, val) in [ + ("hash input first", config.hash_table[1], inp[0]), + ("hash input second", config.hash_table[2], inp[1]), + ("state input control", config.hash_table[3], control), + ( + "state beginning flag", + config.hash_table[4], + if is_new_sponge { Fp::one() } else { Fp::zero() }, + ), + ( + "state input control_aux", + config.control_aux, + control.invert().unwrap_or_else(Fp::zero), + ), + ( + "state continue control", + config.s_sponge_continue, + if is_new_sponge { Fp::zero() } else { Fp::one() }, + ), + ] { + region.assign_advice( + || format!("{tip}_{offset}"), + col, + offset, + || Value::known(val), + )?; + } - region.assign_advice( - || format!("state continue control_{}", i), - config.s_sponge_continue, - offset, - || Value::known(if is_new_sponge { Fp::zero() } else { Fp::one() }), - )?; + is_new_sponge = control <= Fp::from_u128(STEP as u128); + + //fill all the hash_table[0] with result hash + if is_new_sponge { + (process_start..=offset).try_for_each(|ith| { + region + .assign_advice( + || format!("hash index_{ith}"), + config.hash_table[0], + ith, + || Value::known(current_hash), + ) + .map(|_| ()) + })?; + } - region.assign_advice( - || format!("hash input first_{}", i), - config.hash_table[1], - offset, - || Value::known(inp[0]), - )?; + //we directly specify the init state of permutation + let c_start_arr: [_; 3] = c_start.try_into().expect("same size"); + states_in.push(c_start_arr.map(StateWord::from)); + let c_end_arr: [_; 3] = c_end.try_into().expect("same size"); + states_out.push(c_end_arr.map(StateWord::from)); + } - region.assign_advice( - || format!("hash input second_{}", i), - config.hash_table[2], - offset, - || Value::known(inp[1]), - )?; - - is_new_sponge = control <= Fp::from_u128(STEP as u128); - - //fill all the hash_table[0] with result hash - if is_new_sponge { - (process_start..offset + 1).try_for_each(|ith| { - region - .assign_advice( - || format!("hash index_{}", ith), - config.hash_table[0], - ith, - || Value::known(current_hash), - ) - .map(|_| ()) - })?; - } + // set the last row is "custom", a row both enabled and customed + // can only fill a padding row ([0, 0] in MPT mode) + config.s_custom.enable(region, last_offset)?; + Ok((states_in, states_out)) + } - //we directly specify the init state of permutation - states_in.push(c_start.map(StateWord::from)); - states_out.push(c_end.map(StateWord::from)); - } + /// load the table into circuit under the specified config + pub fn load(&self, layouter: &mut impl Layouter) -> Result<(), Error> { + let config = &self.config; - // enforce the last row is "not continue", so user can not put a variable - // message till the last row but this should be acceptable (?) - let c_last_ctrl = region.assign_advice( - || "control sponge continue last", - config.s_sponge_continue, - offset, - || Value::known(Fp::zero()), - )?; + layouter.assign_table( + || "STEP range check", + |mut table| { + (0..STEP + 1).into_iter().try_for_each(|i| { + table + .assign_cell( + || "STEP range check", + config.control_step_range, + i, + || Value::known(Fp::from_u128(i as u128)), + ) + .map(|_| ()) + }) + }, + )?; - // contraint 0 to tail line - region.constrain_equal(c_last_ctrl.cell(), constants_cell[0].cell())?; - Ok((states_in, states_out)) + let (states_in, states_out) = layouter.assign_region( + || "hash table", + |mut region| { + let offset = self.fill_hash_tbl_custom(&mut region)?; + self.fill_hash_tbl_body(&mut region, offset) }, )?; let mut chip_finals = Vec::new(); - for state in states_in { let chip = Pow5Chip::construct(config.permute_config.clone()); @@ -650,7 +694,7 @@ mod tests { } fn configure(meta: &mut ConstraintSystem) -> Self::Config { - let hash_tbl = [0; 4].map(|_| meta.advice_column()); + let hash_tbl = [0; 5].map(|_| meta.advice_column()); ( PoseidonHashConfig::configure_sub(meta, hash_tbl, TEST_STEP), 4, @@ -662,7 +706,13 @@ mod tests { (config, max_rows): Self::Config, mut layouter: impl Layouter, ) -> Result<(), Error> { - let chip = PoseidonHashChip::::construct(config, self, max_rows); + let mut data_with_challenge = self.clone(); + data_with_challenge.nil_msg_hash.replace(Fp::from(42u64)); + let chip = PoseidonHashChip::::construct( + config, + &data_with_challenge, + max_rows, + ); chip.load(&mut layouter) } } @@ -678,13 +728,24 @@ mod tests { .titled("Hash circuit Layout", ("sans-serif", 60)) .unwrap(); - let circuit = HashCircuit { - calcs: 2, + let message1 = [ + Fr::from_str_vartime("1").unwrap(), + Fr::from_str_vartime("2").unwrap(), + ]; + + let message2 = [ + Fr::from_str_vartime("2").unwrap(), + Fr::from_str_vartime("3").unwrap(), + ]; + + let k = 8; + let circuit = PoseidonHashTable { + inputs: vec![message1, message2], ..Default::default() }; halo2_proofs::dev::CircuitLayout::default() .show_equality_constraints(true) - .render(7, &circuit, &root) + .render(k, &circuit, &root) .unwrap(); } @@ -723,6 +784,7 @@ mod tests { inputs: vec![message1, message2], controls: vec![Fr::from_u128(45), Fr::from_u128(13)], checks: vec![None, Some(Fr::from_str_vartime("15002881182751877599173281392790087382867290792048832034781070831698029191486").unwrap())], + ..Default::default() }; let prover = MockProver::run(k, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); @@ -731,6 +793,7 @@ mod tests { inputs: vec![message1, message2, message1], controls: vec![Fr::from_u128(64), Fr::from_u128(32), Fr::zero()], checks: Vec::new(), + ..Default::default() }; let prover = MockProver::run(k, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); @@ -743,12 +806,10 @@ mod tests { let prover = MockProver::run(k, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); - let circuit = PoseidonHashTable:: { ..Default::default() }; let prover = MockProver::run(k, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); - } } diff --git a/src/poseidon.rs b/src/poseidon.rs index 8857f7e..83daae5 100644 --- a/src/poseidon.rs +++ b/src/poseidon.rs @@ -287,7 +287,7 @@ impl< .enumerate() { self.sponge - .absorb(layouter.namespace(|| format!("absorb_{}", i)), value)?; + .absorb(layouter.namespace(|| format!("absorb_{i}")), value)?; } self.sponge .finish_absorbing(layouter.namespace(|| "finish absorbing"))? diff --git a/src/poseidon/pow5.rs b/src/poseidon/pow5.rs index 45c5170..25ec79a 100644 --- a/src/poseidon/pow5.rs +++ b/src/poseidon/pow5.rs @@ -343,7 +343,7 @@ impl< let mut state = Vec::with_capacity(WIDTH); let mut load_state_word = |i: usize, value: F| -> Result<_, Error> { let var = region.assign_advice_from_constant( - || format!("state_{}", i), + || format!("state_{i}"), config.state[i], 0, value, @@ -382,7 +382,7 @@ impl< initial_state[i] .0 .copy_advice( - || format!("load state_{}", i), + || format!("load state_{i}"), &mut region, config.state[i], 0, @@ -398,7 +398,7 @@ impl< let constraint_var = match input.0[i].clone() { Some(PaddedWord::Message(word)) => word, Some(PaddedWord::Padding(padding_value)) => region.assign_fixed( - || format!("load pad_{}", i), + || format!("load pad_{i}"), config.rc_b[i], 1, || Value::known(padding_value), @@ -407,7 +407,7 @@ impl< }; constraint_var .copy_advice( - || format!("load input_{}", i), + || format!("load input_{i}"), &mut region, config.state[i], 1, @@ -421,7 +421,7 @@ impl< let constrain_output_word = |i: usize| { region .assign_advice( - || format!("load output_{}", i), + || format!("load output_{i}"), config.state[i], 2, || { @@ -568,7 +568,7 @@ impl Pow5State { let r: Vec<_> = Some(r_0).into_iter().chain(r_i).collect(); region.assign_advice( - || format!("round_{} partial_sbox", round), + || format!("round_{round} partial_sbox"), config.partial_sbox, offset, || r[0], @@ -629,7 +629,7 @@ impl Pow5State { let load_state_word = |i: usize| { initial_state[i] .0 - .copy_advice(|| format!("load state_{}", i), region, config.state[i], 0) + .copy_advice(|| format!("load state_{i}"), region, config.state[i], 0) .map(StateWord) }; @@ -651,7 +651,7 @@ impl Pow5State { // Load the round constants. let mut load_round_constant = |i: usize| { region.assign_fixed( - || format!("round_{} rc_{}", round, i), + || format!("round_{round} rc_{i}"), config.rc_a[i], offset, || Value::known(config.round_constants[round][i]), @@ -667,7 +667,7 @@ impl Pow5State { let next_state_word = |i: usize| { let value = next_state[i]; let var = region.assign_advice( - || format!("round_{} state_{}", next_round, i), + || format!("round_{next_round} state_{i}"), config.state[i], offset + 1, || value, diff --git a/src/poseidon/primitives.rs b/src/poseidon/primitives.rs index dc7865d..6747e34 100644 --- a/src/poseidon/primitives.rs +++ b/src/poseidon/primitives.rs @@ -323,7 +323,7 @@ impl Domain for Constan type Padding = iter::Take>; fn name() -> String { - format!("ConstantLength<{}>", L) + format!("ConstantLength<{L}>") } fn initial_capacity_element() -> F { @@ -351,7 +351,7 @@ impl Domain for Constan type Padding = as Domain>::Padding; fn name() -> String { - format!("ConstantLength<{}> in iden3's style", L) + format!("ConstantLength<{L}> in iden3's style") } // iden3's scheme do not set any capacity mark diff --git a/src/poseidon/primitives/grain.rs b/src/poseidon/primitives/grain.rs index bfc0715..6ed9bf5 100644 --- a/src/poseidon/primitives/grain.rs +++ b/src/poseidon/primitives/grain.rs @@ -44,7 +44,7 @@ impl SboxType { } pub(super) struct Grain { - state: BitArr!(for 80, in Msb0, u8), + state: BitArr!(for 80, in u8, Msb0), next_bit: usize, _field: PhantomData, } @@ -52,7 +52,7 @@ pub(super) struct Grain { impl Grain { pub(super) fn new(sbox: SboxType, t: u16, r_f: u16, r_p: u16) -> Self { // Initialize the LFSR state. - let mut state = bitarr![Msb0, u8; 1; STATE]; + let mut state = bitarr![u8, Msb0; 1; STATE]; let mut set_bits = |offset: usize, len, value| { // Poseidon reference impl sets initial state bits in MSB order. for i in 0..len { diff --git a/src/poseidon/primitives/p128pow5t3.rs b/src/poseidon/primitives/p128pow5t3.rs index 6d06386..6916912 100644 --- a/src/poseidon/primitives/p128pow5t3.rs +++ b/src/poseidon/primitives/p128pow5t3.rs @@ -33,7 +33,7 @@ impl Spec for P128Pow5T3 { } fn sbox(val: Fp) -> Fp { - val.pow_vartime(&[5]) + val.pow_vartime([5]) } fn secure_mds() -> usize { diff --git a/tests/hash_proving.rs b/tests/hash_proving.rs index ee148b9..95b7783 100644 --- a/tests/hash_proving.rs +++ b/tests/hash_proving.rs @@ -33,7 +33,7 @@ impl Circuit for TestCircuit { } fn configure(meta: &mut ConstraintSystem) -> Self::Config { - let hash_tbl = [0; 4].map(|_| meta.advice_column()); + let hash_tbl = [0; 5].map(|_| meta.advice_column()); PoseidonHashConfig::configure_sub(meta, hash_tbl, DEFAULT_STEP) } @@ -42,7 +42,10 @@ impl Circuit for TestCircuit { config: Self::Config, mut layouter: impl Layouter, ) -> Result<(), Error> { - let chip = PoseidonHashChip::::construct(config, &self.0, self.1); + let mut data_with_challenge = self.0.clone(); + data_with_challenge.nil_msg_hash.replace(Fp::from(42u64)); + let chip = + PoseidonHashChip::::construct(config, &data_with_challenge, self.1); chip.load(&mut layouter) } } @@ -120,10 +123,12 @@ fn proof_and_verify() { Fp::from_str_vartime("2").unwrap(), ], [ - Fp::from_str_vartime("0").unwrap(), + Fp::from_str_vartime("30").unwrap(), Fp::from_str_vartime("1").unwrap(), ], + [Fp::from_str_vartime("65536").unwrap(), Fp::zero()], ], + controls: vec![Fp::zero(), Fp::from(46u64), Fp::from(14u64)], ..Default::default() }, 4, From a9214ce046e82aa3523b101033661d9c552128dc Mon Sep 17 00:00:00 2001 From: Ho Vei Date: Thu, 9 Feb 2023 00:17:34 +0800 Subject: [PATCH 04/10] squash merge from scroll-dev-0201 --- Cargo.toml | 5 ++++- src/hash.rs | 34 +++++++++++++++++++++++----------- tests/hash_proving.rs | 11 +++++++---- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 09a4362..c7d90a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,11 +6,14 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -halo2_proofs = { git = "https://github.com/scroll-tech/halo2.git", branch = "scroll-dev-1220" } +halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v2022_09_10" } lazy_static = "1.4.0" thiserror = "1.0" bitvec = "1" +[patch."https://github.com/privacy-scaling-explorations/halo2.git"] +halo2_proofs = { git = "https://github.com/scroll-tech/halo2.git", branch = "scroll-dev-1220" } + [features] # printout the layout of circuits for demo and some unittests print_layout = ["halo2_proofs/dev-graph"] diff --git a/src/hash.rs b/src/hash.rs index 1e141ae..803144a 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -280,6 +280,7 @@ impl PoseidonHashTable { for (a, b, c) in src { self.inputs.push([*a, *b]); self.checks.push(Some(*c)); + self.controls.push(Fp::zero()); } } @@ -305,6 +306,7 @@ impl PoseidonHashTable { assert_eq!(new_inps.len(), ctrl_series.len()); self.inputs.append(&mut new_inps); self.controls.append(&mut ctrl_series); + assert_eq!(self.inputs.len(), self.controls.len()); } /// return the row which poseidon table use (notice it maybe much smaller @@ -326,6 +328,8 @@ impl PoseidonHashTable { #[derive(Debug)] pub struct PoseidonHashChip<'d, Fp: FieldExt, const STEP: usize> { calcs: usize, + nil_msg_hash: Option, + mpt_only: bool, data: &'d PoseidonHashTable, config: PoseidonHashConfig, } @@ -338,9 +342,13 @@ impl<'d, Fp: Hashable, const STEP: usize> PoseidonHashChip<'d, Fp, STEP> { config: PoseidonHashConfig, data: &'d PoseidonHashTable, calcs: usize, + mpt_only: bool, + nil_msg_hash: Option, ) -> Self { Self { calcs, + mpt_only, + nil_msg_hash, data, config, } @@ -366,6 +374,10 @@ impl<'d, Fp: Hashable, const STEP: usize> PoseidonHashChip<'d, Fp, STEP> { } config.s_custom.enable(region, 1)?; + if self.mpt_only { + return Ok(1); + } + // custom for (tip, cols) in [ ("custom inputs", &config.hash_table[1..4]), @@ -388,8 +400,7 @@ impl<'d, Fp: Hashable, const STEP: usize> PoseidonHashChip<'d, Fp, STEP> { col, 1, || { - self.data - .nil_msg_hash + self.nil_msg_hash .map(Value::known) .unwrap_or_else(Value::unknown) }, @@ -417,26 +428,24 @@ impl<'d, Fp: Hashable, const STEP: usize> PoseidonHashChip<'d, Fp, STEP> { let mut states_out = Vec::new(); let hash_helper = Fp::hasher(); - let dummy_input: [Option<&[Fp; 2]>; 1] = [None]; - let dummy_item: [Option<&Fp>; 1] = [None]; let inputs_i = data .inputs .iter() .map(Some) - .chain(dummy_input.into_iter().cycle()) + .chain(std::iter::repeat(None)) .take(self.calcs); let controls_i = data .controls .iter() .map(Some) - .chain(dummy_item.into_iter().cycle()) + .chain(std::iter::repeat(None)) .take(self.calcs); let checks_i = data .checks .iter() .map(|i| i.as_ref()) - .chain(dummy_item.into_iter().cycle()) + .chain(std::iter::repeat(None)) .take(self.calcs); let mut is_new_sponge = true; @@ -471,7 +480,10 @@ impl<'d, Fp: Hashable, const STEP: usize> PoseidonHashChip<'d, Fp, STEP> { //and sanity check ... if let Some(ck) = check { - assert_eq!(*ck, state[0]); + assert_eq!( + *ck, state[0], + "hash output not match with expected at {offset}" + ); } let current_hash = state[0]; @@ -706,12 +718,12 @@ mod tests { (config, max_rows): Self::Config, mut layouter: impl Layouter, ) -> Result<(), Error> { - let mut data_with_challenge = self.clone(); - data_with_challenge.nil_msg_hash.replace(Fp::from(42u64)); let chip = PoseidonHashChip::::construct( config, - &data_with_challenge, + &self, max_rows, + false, + Some(Fp::from(42u64)), ); chip.load(&mut layouter) } diff --git a/tests/hash_proving.rs b/tests/hash_proving.rs index 95b7783..fad83b6 100644 --- a/tests/hash_proving.rs +++ b/tests/hash_proving.rs @@ -42,10 +42,13 @@ impl Circuit for TestCircuit { config: Self::Config, mut layouter: impl Layouter, ) -> Result<(), Error> { - let mut data_with_challenge = self.0.clone(); - data_with_challenge.nil_msg_hash.replace(Fp::from(42u64)); - let chip = - PoseidonHashChip::::construct(config, &data_with_challenge, self.1); + let chip = PoseidonHashChip::::construct( + config, + &self.0, + self.1, + false, + Some(Fp::from(42u64)), + ); chip.load(&mut layouter) } } From 714f50c7572a4ff6f2b1fa51a9604a99cd7b6c71 Mon Sep 17 00:00:00 2001 From: Ho Vei Date: Fri, 10 Feb 2023 10:05:57 +0800 Subject: [PATCH 05/10] fixing phase issue --- src/hash.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/hash.rs b/src/hash.rs index 803144a..ef08123 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -100,7 +100,13 @@ impl PoseidonHashConfig { let s_table = meta.selector(); let s_custom = meta.selector(); - let hash_table_aux = [0; 6].map(|_| meta.advice_column()); + let hash_table_aux = [0, 1, 2, 3, 4, 5].map(|idx| { + if idx < 5 { + meta.advice_column() + } else { + meta.advice_column_in(halo2_proofs::plonk::SecondPhase) + } + }); for col in hash_table_aux.iter().chain(hash_table[0..1].iter()) { meta.enable_equality(*col); } @@ -706,7 +712,13 @@ mod tests { } fn configure(meta: &mut ConstraintSystem) -> Self::Config { - let hash_tbl = [0; 5].map(|_| meta.advice_column()); + let hash_tbl = [0, 1, 2, 3, 4].map(|idx| { + if idx == 0 { + meta.advice_column_in(halo2_proofs::plonk::SecondPhase) + } else { + meta.advice_column() + } + }); ( PoseidonHashConfig::configure_sub(meta, hash_tbl, TEST_STEP), 4, From fb4082538592d339b87029ce1b249e2c00703b49 Mon Sep 17 00:00:00 2001 From: naure Date: Tue, 28 Feb 2023 03:59:18 +0100 Subject: [PATCH 06/10] compact-constants: fold constants into one per partial round (#9) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Aurélien Nicolas --- src/poseidon/primitives.rs | 2 + src/poseidon/primitives/bn256/mod.rs | 56 ++++++++++++- src/poseidon/primitives/p128pow5t3_compact.rs | 82 +++++++++++++++++++ 3 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 src/poseidon/primitives/p128pow5t3_compact.rs diff --git a/src/poseidon/primitives.rs b/src/poseidon/primitives.rs index 6747e34..39bd469 100644 --- a/src/poseidon/primitives.rs +++ b/src/poseidon/primitives.rs @@ -24,6 +24,8 @@ pub(crate) mod pasta; //pub(crate) mod test_vectors; mod p128pow5t3; +mod p128pow5t3_compact; + pub use p128pow5t3::P128Pow5T3; use grain::SboxType; diff --git a/src/poseidon/primitives/bn256/mod.rs b/src/poseidon/primitives/bn256/mod.rs index 3c49ab5..ace9e18 100644 --- a/src/poseidon/primitives/bn256/mod.rs +++ b/src/poseidon/primitives/bn256/mod.rs @@ -26,7 +26,8 @@ mod tests { use std::marker::PhantomData; use crate::poseidon::primitives::p128pow5t3::P128Pow5T3; - use crate::poseidon::primitives::Spec; + use crate::poseidon::primitives::p128pow5t3_compact::P128Pow5T3CompactSpec; + use crate::poseidon::primitives::{permute, Spec}; use super::*; @@ -112,4 +113,57 @@ mod tests { } } } + + #[test] + fn test_compact_constants() { + let input = [ + Fp::from_raw([ + 0x0000_0000_0000_0000, + 0x0000_0000_0000_0000, + 0x0000_0000_0000_0000, + 0x0000_0000_0000_0000, + ]), + Fp::from_raw([ + 0x0000_0000_0000_0001, + 0x0000_0000_0000_0000, + 0x0000_0000_0000_0000, + 0x0000_0000_0000_0000, + ]), + Fp::from_raw([ + 0x0000_0000_0000_0002, + 0x0000_0000_0000_0000, + 0x0000_0000_0000_0000, + 0x0000_0000_0000_0000, + ]), + ]; + + let output = { + let mut state = input.clone(); + + let (rc, mds, _inv) = P128Pow5T3::::constants(); + permute::, 3, 2>(&mut state, &mds, &rc[..]); + + // This is the raw form with 3 constants per round. + assert_ne!(rc[4][1], Fp::zero()); + + state + }; + + let output_compact = { + let mut state = input.clone(); + + let (rc, mds, _inv) = P128Pow5T3CompactSpec::::constants(); + permute::, 3, 2>(&mut state, &mds, &rc[..]); + + // This is the compact form with 1 constant per partial round. + for i in 4..4 + 57 { + assert_eq!(rc[i][1], Fp::zero()); + assert_eq!(rc[i][2], Fp::zero()); + } + + state + }; + + assert_eq!(output, output_compact); + } } diff --git a/src/poseidon/primitives/p128pow5t3_compact.rs b/src/poseidon/primitives/p128pow5t3_compact.rs new file mode 100644 index 0000000..118b080 --- /dev/null +++ b/src/poseidon/primitives/p128pow5t3_compact.rs @@ -0,0 +1,82 @@ +use std::marker::PhantomData; + +use halo2_proofs::arithmetic::FieldExt; + +use super::p128pow5t3::P128Pow5T3Constants; +use super::{Mds, Spec}; + +/// Poseidon-128 using the $x^5$ S-box, with a width of 3 field elements, and the +/// standard number of rounds for 128-bit security "with margin". +/// +#[derive(Debug)] +pub struct P128Pow5T3CompactSpec { + _marker: PhantomData, +} + +impl Spec for P128Pow5T3CompactSpec { + fn full_rounds() -> usize { + 8 + } + + fn partial_rounds() -> usize { + Fp::partial_rounds() + } + + fn sbox(val: Fp) -> Fp { + val.pow_vartime(&[5]) + } + + fn secure_mds() -> usize { + unimplemented!() + } + + fn constants() -> (Vec<[Fp; 3]>, Mds, Mds) { + let (mut rc, mds, inv) = (Fp::round_constants(), Fp::mds(), Fp::mds_inv()); + + let first_partial = Self::full_rounds() / 2; + let after_partials = first_partial + Self::partial_rounds(); + + // Propagate the constants of each partial round into the next. + for i in first_partial..after_partials { + // Extract the constants rc[i][1] and rc[i][2] that do not pass through the S-box. + // Leave the value 0 in their place. + // rc[i][0] stays in place. + let rc_tail = vec_remove_tail(&mut rc[i]); + + // Pass forward through the MDS matrix. + let rc_carry = mat_mul(&mds, &rc_tail); + + // Accumulate the carried constants into the next round. + vec_accumulate(&mut rc[i + 1], &rc_carry); + } + // Now constants have accumulated into the next full round. + + (rc, mds, inv) + } +} + +fn mat_mul(mat: &Mds, input: &[Fp; T]) -> [Fp; T] { + let mut out = [Fp::zero(); T]; + #[allow(clippy::needless_range_loop)] + for i in 0..T { + for j in 0..T { + out[i] += mat[i][j] * input[j]; + } + } + out +} + +fn vec_accumulate(a: &mut [Fp; T], b: &[Fp; T]) { + for i in 0..T { + a[i] += b[i]; + } +} + +fn vec_remove_tail(a: &mut [Fp; T]) -> [Fp; T] { + let mut tail = [Fp::zero(); T]; + for i in 1..T { + tail[i] = a[i]; + a[i] = Fp::zero(); + } + tail +} From ee36e1ee11e110e32d19f56e3152cf8840352444 Mon Sep 17 00:00:00 2001 From: Ho Vei Date: Thu, 2 Mar 2023 15:05:15 +0800 Subject: [PATCH 07/10] add test for compact spec --- src/poseidon/primitives.rs | 14 +++++++++++++- src/poseidon/primitives/p128pow5t3_compact.rs | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/poseidon/primitives.rs b/src/poseidon/primitives.rs index 39bd469..dee0464 100644 --- a/src/poseidon/primitives.rs +++ b/src/poseidon/primitives.rs @@ -27,6 +27,7 @@ mod p128pow5t3; mod p128pow5t3_compact; pub use p128pow5t3::P128Pow5T3; +pub use p128pow5t3_compact::P128Pow5T3CompactSpec as P128Pow5T3Compact; use grain::SboxType; @@ -492,7 +493,7 @@ mod tests { use super::pasta::Fp; use halo2_proofs::arithmetic::FieldExt; - use super::{permute, ConstantLength, Hash, P128Pow5T3, Spec}; + use super::{permute, ConstantLength, Hash, P128Pow5T3, P128Pow5T3Compact, Spec}; type OrchardNullifier = P128Pow5T3; #[test] @@ -524,4 +525,15 @@ mod tests { let result = hasher.hash(message); assert_eq!(state[0], result); } + + #[test] + fn spec_equivalence() { + let message = [Fp::from(6), Fp::from(42)]; + let hasher1 = Hash::<_, P128Pow5T3, ConstantLength<2>, 3, 2>::init(); + let hasher2 = Hash::<_, P128Pow5T3Compact, ConstantLength<2>, 3, 2>::init(); + + let result1 = hasher1.hash(message.clone()); + let result2 = hasher2.hash(message.clone()); + assert_eq!(result1, result2); + } } diff --git a/src/poseidon/primitives/p128pow5t3_compact.rs b/src/poseidon/primitives/p128pow5t3_compact.rs index 118b080..d5bd1e8 100644 --- a/src/poseidon/primitives/p128pow5t3_compact.rs +++ b/src/poseidon/primitives/p128pow5t3_compact.rs @@ -23,7 +23,7 @@ impl Spec for P128Pow5T3CompactSpec { } fn sbox(val: Fp) -> Fp { - val.pow_vartime(&[5]) + val.pow_vartime([5]) } fn secure_mds() -> usize { From 231450d15a4352568543f14da361247964123e01 Mon Sep 17 00:00:00 2001 From: Ho Vei Date: Thu, 2 Mar 2023 15:05:38 +0800 Subject: [PATCH 08/10] fix unnecessary phase spec in test circuit --- src/hash.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/hash.rs b/src/hash.rs index ef08123..d179d0d 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -712,13 +712,8 @@ mod tests { } fn configure(meta: &mut ConstraintSystem) -> Self::Config { - let hash_tbl = [0, 1, 2, 3, 4].map(|idx| { - if idx == 0 { - meta.advice_column_in(halo2_proofs::plonk::SecondPhase) - } else { - meta.advice_column() - } - }); + let hash_tbl = [0; 5].map(|_| meta.advice_column()); + ( PoseidonHashConfig::configure_sub(meta, hash_tbl, TEST_STEP), 4, From bd920432eb6672badac4d3443f1e3dadb93bfeb7 Mon Sep 17 00:00:00 2001 From: naure Date: Tue, 21 Mar 2023 15:56:58 +0100 Subject: [PATCH 09/10] Septidon integration (#14) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * compact-constants: fold constants into one per partial round * septidon: working circuit for Poseidon septuple rounds * septidon: design diagrams * septidon-integration: support both septuple implementation and original using a trait * septidon: fix after merge --------- Co-authored-by: Aurélien Nicolas --- src/hash.rs | 140 +++++++++------ src/lib.rs | 2 + src/poseidon.rs | 12 +- src/poseidon/pow5.rs | 28 ++- src/poseidon/primitives.rs | 2 +- src/poseidon/primitives/p128pow5t3_compact.rs | 2 +- src/septidon.rs | 17 ++ src/septidon/README.md | 150 ++++++++++++++++ src/septidon/Septidon.png | Bin 0 -> 260102 bytes src/septidon/control.rs | 63 +++++++ src/septidon/full_round.rs | 52 ++++++ src/septidon/instruction.rs | 95 ++++++++++ src/septidon/loop_chip.rs | 41 +++++ src/septidon/params.rs | 49 ++++++ src/septidon/septidon_chip.rs | 166 ++++++++++++++++++ src/septidon/septuple_round.rs | 124 +++++++++++++ src/septidon/state.rs | 133 ++++++++++++++ src/septidon/tests.rs | 66 +++++++ src/septidon/transition_round.rs | 125 +++++++++++++ src/septidon/util.rs | 130 ++++++++++++++ tests/hash_proving.rs | 5 +- 21 files changed, 1341 insertions(+), 61 deletions(-) create mode 100644 src/septidon.rs create mode 100644 src/septidon/README.md create mode 100755 src/septidon/Septidon.png create mode 100644 src/septidon/control.rs create mode 100644 src/septidon/full_round.rs create mode 100644 src/septidon/instruction.rs create mode 100644 src/septidon/loop_chip.rs create mode 100644 src/septidon/params.rs create mode 100644 src/septidon/septidon_chip.rs create mode 100644 src/septidon/septuple_round.rs create mode 100644 src/septidon/state.rs create mode 100644 src/septidon/tests.rs create mode 100644 src/septidon/transition_round.rs create mode 100644 src/septidon/util.rs diff --git a/src/hash.rs b/src/hash.rs index d179d0d..c06db7b 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -3,8 +3,8 @@ use crate::poseidon::primitives::{ ConstantLengthIden3, Domain, Hash, P128Pow5T3, Spec, VariableLengthIden3, }; -use halo2_proofs::arithmetic::FieldExt; use halo2_proofs::halo2curves::bn256::Fr; +use halo2_proofs::{arithmetic::FieldExt, circuit::AssignedCell}; /// indicate an field can be hashed in merkle tree (2 Fields to 1 Field) pub trait Hashable: FieldExt { @@ -56,7 +56,7 @@ impl MessageHashable for Fr { } } -use crate::poseidon::{PoseidonInstructions, Pow5Chip, Pow5Config, StateWord, Var}; +use crate::poseidon::{PermuteChip, PoseidonInstructions}; use halo2_proofs::{ circuit::{Chip, Layouter, Region, Value}, plonk::{Advice, Column, ConstraintSystem, Error, Expression, Fixed, Selector, TableColumn}, @@ -65,19 +65,19 @@ use halo2_proofs::{ /// The config for poseidon hash circuit #[derive(Clone, Debug)] -pub struct PoseidonHashConfig { - permute_config: Pow5Config, +pub struct PoseidonHashConfig> { + permute_config: PC::Config, hash_table: [Column; 5], hash_table_aux: [Column; 6], control_aux: Column, s_sponge_continue: Column, - constants: [Column; 6], + constants: [Column; 1], control_step_range: TableColumn, s_table: Selector, s_custom: Selector, } -impl PoseidonHashConfig { +impl> PoseidonHashConfig { /// obtain the commitment index of hash table pub fn commitment_index(&self) -> [usize; 5] { self.hash_table.map(|col| col.index()) @@ -94,9 +94,8 @@ impl PoseidonHashConfig { hash_table: [Column; 5], step: usize, ) -> Self { - let state = [0; 3].map(|_| meta.advice_column()); - let partial_sbox = meta.advice_column(); - let constants = [0; 6].map(|_| meta.fixed_column()); + // TODO: remove this "constants". + let constants = [0; 1].map(|_| meta.fixed_column()); let s_table = meta.selector(); let s_custom = meta.selector(); @@ -236,13 +235,7 @@ impl PoseidonHashConfig { }); Self { - permute_config: Pow5Chip::configure::( - meta, - state, - partial_sbox, - constants[..3].try_into().unwrap(), //rc_a - constants[3..].try_into().unwrap(), //rc_b - ), + permute_config: PC::configure(meta), hash_table, hash_table_aux, control_aux, @@ -332,20 +325,26 @@ impl PoseidonHashTable { /// Represent the chip for Poseidon hash table #[derive(Debug)] -pub struct PoseidonHashChip<'d, Fp: FieldExt, const STEP: usize> { +pub struct PoseidonHashChip<'d, Fp: FieldExt, const STEP: usize, PC: PermuteChip> { calcs: usize, nil_msg_hash: Option, mpt_only: bool, data: &'d PoseidonHashTable, - config: PoseidonHashConfig, + config: PoseidonHashConfig, } -type PermutedState = Vec<[StateWord; 3]>; +type PermutedState = Vec<[Word; 3]>; -impl<'d, Fp: Hashable, const STEP: usize> PoseidonHashChip<'d, Fp, STEP> { +impl< + 'd, + Fp: Hashable, + const STEP: usize, + PC: PermuteChip + PoseidonInstructions, + > PoseidonHashChip<'d, Fp, STEP, PC> +{ ///construct the chip pub fn construct( - config: PoseidonHashConfig, + config: PoseidonHashConfig, data: &'d PoseidonHashTable, calcs: usize, mpt_only: bool, @@ -426,7 +425,7 @@ impl<'d, Fp: Hashable, const STEP: usize> PoseidonHashChip<'d, Fp, STEP> { &self, region: &mut Region<'_, Fp>, begin_offset: usize, - ) -> Result<(PermutedState, PermutedState), Error> { + ) -> Result<(PermutedState, PermutedState), Error> { let config = &self.config; let data = self.data; @@ -569,9 +568,9 @@ impl<'d, Fp: Hashable, const STEP: usize> PoseidonHashChip<'d, Fp, STEP> { //we directly specify the init state of permutation let c_start_arr: [_; 3] = c_start.try_into().expect("same size"); - states_in.push(c_start_arr.map(StateWord::from)); + states_in.push(c_start_arr.map(PC::Word::from)); let c_end_arr: [_; 3] = c_end.try_into().expect("same size"); - states_out.push(c_end_arr.map(StateWord::from)); + states_out.push(c_end_arr.map(PC::Word::from)); } // set the last row is "custom", a row both enabled and customed @@ -610,12 +609,11 @@ impl<'d, Fp: Hashable, const STEP: usize> PoseidonHashChip<'d, Fp, STEP> { let mut chip_finals = Vec::new(); for state in states_in { - let chip = Pow5Chip::construct(config.permute_config.clone()); + let chip = PC::construct(config.permute_config.clone()); - let final_state = - as PoseidonInstructions>::permute( - &chip, layouter, &state, - )?; + let final_state = >::permute( + &chip, layouter, &state, + )?; chip_finals.push(final_state); } @@ -625,6 +623,8 @@ impl<'d, Fp: Hashable, const STEP: usize> PoseidonHashChip<'d, Fp, STEP> { |mut region| { for (state, final_state) in states_out.iter().zip(chip_finals.iter()) { for (s_cell, final_cell) in state.iter().zip(final_state.iter()) { + let s_cell: AssignedCell = s_cell.clone().into(); + let final_cell: AssignedCell = final_cell.clone().into(); region.constrain_equal(s_cell.cell(), final_cell.cell())?; } } @@ -635,8 +635,10 @@ impl<'d, Fp: Hashable, const STEP: usize> PoseidonHashChip<'d, Fp, STEP> { } } -impl Chip for PoseidonHashChip<'_, Fp, STEP> { - type Config = PoseidonHashConfig; +impl> Chip + for PoseidonHashChip<'_, Fp, STEP, PC> +{ + type Config = PoseidonHashConfig; type Loaded = PoseidonHashTable; fn config(&self) -> &Self::Config { @@ -649,6 +651,11 @@ impl Chip for PoseidonHashChip<'_, Fp, STEP #[cfg(test)] mod tests { + use std::marker::PhantomData; + + use crate::poseidon::Pow5Chip; + use crate::septidon::SeptidonChip; + use super::*; use halo2_proofs::halo2curves::group::ff::PrimeField; use halo2_proofs::{circuit::SimpleFloorPlanner, plonk::Circuit}; @@ -701,19 +708,33 @@ mod tests { const TEST_STEP: usize = 32; // test circuit derived from table data - impl Circuit for PoseidonHashTable { - type Config = (PoseidonHashConfig, usize); + //#[derive(Clone, Default, Debug)] + struct TestCircuit> { + table: PoseidonHashTable, + _phantom: PhantomData, + } + + impl> TestCircuit { + pub fn new(table: PoseidonHashTable) -> Self { + TestCircuit { + table, + _phantom: PhantomData, + } + } + } + + impl + PoseidonInstructions::SpecType, 3, 2>> + Circuit for TestCircuit + { + type Config = (PoseidonHashConfig, usize); type FloorPlanner = SimpleFloorPlanner; fn without_witnesses(&self) -> Self { - Self { - ..Default::default() - } + Self::new(Default::default()) } - fn configure(meta: &mut ConstraintSystem) -> Self::Config { + fn configure(meta: &mut ConstraintSystem) -> Self::Config { let hash_tbl = [0; 5].map(|_| meta.advice_column()); - ( PoseidonHashConfig::configure_sub(meta, hash_tbl, TEST_STEP), 4, @@ -723,14 +744,14 @@ mod tests { fn synthesize( &self, (config, max_rows): Self::Config, - mut layouter: impl Layouter, + mut layouter: impl Layouter, ) -> Result<(), Error> { - let chip = PoseidonHashChip::::construct( + let chip = PoseidonHashChip::::construct( config, - &self, + &self.table, max_rows, false, - Some(Fp::from(42u64)), + Some(Fr::from(42u64)), ); chip.load(&mut layouter) } @@ -770,6 +791,13 @@ mod tests { #[test] fn poseidon_hash_circuit() { + poseidon_hash_circuit_impl::>(); + poseidon_hash_circuit_impl::(); + } + + fn poseidon_hash_circuit_impl< + PC: PermuteChip + PoseidonInstructions::SpecType, 3, 2>, + >() { let message1 = [ Fr::from_str_vartime("1").unwrap(), Fr::from_str_vartime("2").unwrap(), @@ -781,16 +809,23 @@ mod tests { ]; let k = 8; - let circuit = PoseidonHashTable { + let circuit = TestCircuit::::new(PoseidonHashTable { inputs: vec![message1, message2], ..Default::default() - }; + }); let prover = MockProver::run(k, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); } #[test] fn poseidon_var_len_hash_circuit() { + poseidon_var_len_hash_circuit_impl::>(); + poseidon_var_len_hash_circuit_impl::(); + } + + fn poseidon_var_len_hash_circuit_impl< + PC: PermuteChip + PoseidonInstructions::SpecType, 3, 2>, + >() { let message1 = [ Fr::from_str_vartime("1").unwrap(), Fr::from_str_vartime("2").unwrap(), @@ -799,35 +834,34 @@ mod tests { let message2 = [Fr::from_str_vartime("50331648").unwrap(), Fr::zero()]; let k = 8; - let circuit = PoseidonHashTable { + let circuit = TestCircuit::::new( PoseidonHashTable { inputs: vec![message1, message2], controls: vec![Fr::from_u128(45), Fr::from_u128(13)], checks: vec![None, Some(Fr::from_str_vartime("15002881182751877599173281392790087382867290792048832034781070831698029191486").unwrap())], ..Default::default() - }; + }); let prover = MockProver::run(k, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); - let circuit = PoseidonHashTable { + let circuit = TestCircuit::::new(PoseidonHashTable { inputs: vec![message1, message2, message1], controls: vec![Fr::from_u128(64), Fr::from_u128(32), Fr::zero()], checks: Vec::new(), ..Default::default() - }; + }); let prover = MockProver::run(k, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); - let circuit = PoseidonHashTable:: { + let circuit = TestCircuit::::new(PoseidonHashTable:: { inputs: vec![message2], controls: vec![Fr::from_u128(13)], ..Default::default() - }; + }); let prover = MockProver::run(k, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); - - let circuit = PoseidonHashTable:: { + let circuit = TestCircuit::::new(PoseidonHashTable:: { ..Default::default() - }; + }); let prover = MockProver::run(k, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); } diff --git a/src/lib.rs b/src/lib.rs index 6543edd..dc69c08 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,6 +8,8 @@ pub mod hash; pub mod poseidon; +pub mod septidon; + pub use halo2_proofs::halo2curves::bn256::Fr as Bn256Fr; pub use hash::Hashable; diff --git a/src/poseidon.rs b/src/poseidon.rs index 83daae5..b346ee0 100644 --- a/src/poseidon.rs +++ b/src/poseidon.rs @@ -7,7 +7,7 @@ use std::marker::PhantomData; use halo2_proofs::{ arithmetic::{Field, FieldExt}, circuit::{AssignedCell, Chip, Layouter}, - plonk::Error, + plonk::{ConstraintSystem, Error}, }; mod pow5; @@ -15,6 +15,7 @@ pub use pow5::{Pow5Chip, Pow5Config, StateWord, Var}; pub mod primitives; use primitives::{Absorbing, ConstantLength, Domain, Spec, SpongeMode, Squeezing, State}; +use std::fmt::Debug as DebugT; /// A word from the padded input to a Poseidon sponge. #[derive(Clone, Debug)] @@ -25,6 +26,15 @@ pub enum PaddedWord { Padding(F), } +/// This trait is the interface to chips that implement a permutation. +pub trait PermuteChip: Chip + Clone + DebugT { + /// Configure the permutation chip. + fn configure(meta: &mut ConstraintSystem) -> Self::Config; + + /// Get a chip from its config. + fn construct(config: Self::Config) -> Self; +} + /// The set of circuit instructions required to use the Poseidon permutation. pub trait PoseidonInstructions, const T: usize, const RATE: usize>: Chip diff --git a/src/poseidon/pow5.rs b/src/poseidon/pow5.rs index 25ec79a..64dc8b4 100644 --- a/src/poseidon/pow5.rs +++ b/src/poseidon/pow5.rs @@ -8,9 +8,11 @@ use halo2_proofs::{ poly::Rotation, }; +use crate::Hashable; + use super::{ primitives::{Absorbing, Domain, Mds, Spec, Squeezing, State}, - PaddedWord, PoseidonInstructions, PoseidonSpongeInstructions, + PaddedWord, PermuteChip, PoseidonInstructions, PoseidonSpongeInstructions, }; /// Trait for a variable in the circuit. @@ -56,7 +58,7 @@ pub struct Pow5Config { /// /// The chip is implemented using a single round per row for full rounds, and two rounds /// per row for partial rounds. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct Pow5Chip { config: Pow5Config, } @@ -258,6 +260,26 @@ impl Chip for Pow5Chip PermuteChip for Pow5Chip { + fn configure(meta: &mut ConstraintSystem) -> Self::Config { + let state = [0; 3].map(|_| meta.advice_column()); + let partial_sbox = meta.advice_column(); + let constants = [0; 6].map(|_| meta.fixed_column()); + + Pow5Chip::configure::( + meta, + state, + partial_sbox, + constants[..3].try_into().unwrap(), //rc_a + constants[3..].try_into().unwrap(), //rc_b + ) + } + + fn construct(config: Self::Config) -> Self { + Self::construct(config) + } +} + impl, const WIDTH: usize, const RATE: usize> PoseidonInstructions for Pow5Chip { @@ -455,7 +477,7 @@ impl< /// A word in the Poseidon state. #[derive(Clone, Debug)] -pub struct StateWord(AssignedCell); +pub struct StateWord(pub AssignedCell); impl From> for AssignedCell { fn from(state_word: StateWord) -> AssignedCell { diff --git a/src/poseidon/primitives.rs b/src/poseidon/primitives.rs index dee0464..bf189ef 100644 --- a/src/poseidon/primitives.rs +++ b/src/poseidon/primitives.rs @@ -24,7 +24,7 @@ pub(crate) mod pasta; //pub(crate) mod test_vectors; mod p128pow5t3; -mod p128pow5t3_compact; +pub(crate) mod p128pow5t3_compact; pub use p128pow5t3::P128Pow5T3; pub use p128pow5t3_compact::P128Pow5T3CompactSpec as P128Pow5T3Compact; diff --git a/src/poseidon/primitives/p128pow5t3_compact.rs b/src/poseidon/primitives/p128pow5t3_compact.rs index d5bd1e8..f6db10c 100644 --- a/src/poseidon/primitives/p128pow5t3_compact.rs +++ b/src/poseidon/primitives/p128pow5t3_compact.rs @@ -2,7 +2,7 @@ use std::marker::PhantomData; use halo2_proofs::arithmetic::FieldExt; -use super::p128pow5t3::P128Pow5T3Constants; +pub use super::p128pow5t3::P128Pow5T3Constants; use super::{Mds, Spec}; /// Poseidon-128 using the $x^5$ S-box, with a width of 3 field elements, and the diff --git a/src/septidon.rs b/src/septidon.rs new file mode 100644 index 0000000..ae497f6 --- /dev/null +++ b/src/septidon.rs @@ -0,0 +1,17 @@ +//! An implementation using septuple rounds. +//! See: src/README.md + +mod control; +mod full_round; +mod instruction; +mod loop_chip; +mod params; +mod septidon_chip; +mod septuple_round; +mod state; +#[cfg(test)] +mod tests; +mod transition_round; +mod util; + +pub use septidon_chip::SeptidonChip; diff --git a/src/septidon/README.md b/src/septidon/README.md new file mode 100644 index 0000000..2b62c6d --- /dev/null +++ b/src/septidon/README.md @@ -0,0 +1,150 @@ +# A Poseidon Chip with Septuple Rounds + +This is a circuit for a Poseidon permutation. It uses 8 rows per permutation. It exposes pairs of input/output at fixed +locations, to use with a sponge circuit. It is designed as a set of chips, that can be rearranged to obtain 4, 2, or +even 1 rows per permutation. It can potentially be configured with a max gate degree of 5 for faster proving. + + +**[Design Diagrams](https://miro.com/app/board/uXjVPLsk0oU=/?moveToWidget=3458764546593848776&cot=14)** + +![diagram](./Septidon.png) + + +# Spec + +## S-box + +- Config: + - 1 advice column A. + - 1 fixed column C. +- get_input() -> Expr: + Return an expression of degree 1 of the input A. +- get_output() -> Expr: + Return an expression of degree 5 of the output B. + B = (A + C)**5 + +### Partial State = SBox +### Full State = [SBox; 3] + +## Full Round + +- Config: 3 S-boxes +- get_input() -> [Expr; 3]: + Return an expression of degree 1 of the full state before the round. +- get_output() -> [Expr; 3]: + Return an expression of degree 5 of the full state after the round. + MDS . [outputs of the S-boxes] + +## Loop + +Iterate rounds on consecutive rows, with the ability to break the loop. + +- Config: + - A Round config (Full or Partial) where the iteration takes place. + - A Full State where to hold the result after break. [Expr; 3] + - A selector expression indicating when to break. Expr +- get_constraint() -> Expr + An expression that must equal zero. + +The degrees of the result and selector expressions must add up to at most 5. +The loop must break at the end of the circuit. + + +## Full Rounds Layout + +A layout of 4 Full Rounds and the output of the 4th round. The output is stored vertically in a given column, parallel to the round executions. For the first 4 full rounds, the output is the input of the first partial round. For the last 4 full rounds, the output is the final state. + +Layout: + +Selector | Rounds | Output +---------|-----------|---------- + 0 | [State 0] | (untouched) + 0 | [State 1] | output.0 + 0 | [State 2] | output.1 + 1 | [State 3] | output.2 + +- Config: + - A selector expression indicating when to output and restart. Expr. + - A Full Round Loop config for initial and intermediate states. + - A column where to hold the output state. + + +## First Partial Round + +An implementation of the first partial round, with support for a selector. + +- Config: + - A selector indicating where this specific round is enabled. + - 3 cells holding a full state as input. + - The S-Box type is not appropriate here because this works differently. + - 1 cell to hold an intermediate result a_square. + - A Full State where to hold the output. + + a = state.0 + round_constants[4] + a_square = a * a + b = a_square * a_square * a + [output] = MDS . [b, state.1, state.2] + + +## Transition Layout + +A layout of the first partial round inside of a column. + +Selector | Input | Output +---------|--------------|--------- + 0 | a_square | [output] + 0 | state.0 | (untouched) + 0 | state.1 | (untouched) + 1 | state.2 | (untouched) + + +## Septuple Round + +A batch of seven partial rounds, without selectors. + +- Config: 1 Full State, 6 Partial States. +- get_input() -> [Expr; 3]: + Return an expression of degree 1 of the full state before the rounds. +- get_output() -> [Expr; 3]: + Return an expression of degree 5 of the full state after the rounds. + + +## Septuple Rounds Layout + +A layout of 8 chained Septuple Rounds. Similar to Full Rounds Loop/Layout. +The output is the input of the next Full Rounds Layout. + + +## Control Chip + +The control chip generates signals for the selectors and switches of other chips. + +- Config: 1 fixed column +- full_rounds_break() -> the signal to interrupt the loops of full rounds. +- partial_rounds_break() -> the signal to interrupt the loops of partial rounds. +- transition_round() -> the signal to run the first partial round. + + +## Permutation Chip + +A permutation of an initial state into a final state. + +- Config: + - 2 Full States + - 6 Partial States + - 1 Column for the transition to partial rounds, and the final state. +- get_input() -> [Expr; 3]: + Return an expression of degree 1 of the initial full state. +- get_output() -> [Expr; 3]: + Return an expression of degree 1 of the final full state. + + +## Alternative: 14x-Round + +A batch of 14 partial rounds, without selectors. + +- Config: 1 Full State, 13 Partial States + +## Alternative: 14x-Rounds Layout + +A layout of 4 chained 14-Rounds. Similar to Full Rounds Loop/Layout. diff --git a/src/septidon/Septidon.png b/src/septidon/Septidon.png new file mode 100755 index 0000000000000000000000000000000000000000..4ad313840fecfb9d7ca83a0d64427bcff3715b78 GIT binary patch literal 260102 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

q`sO)z6& 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 +ss)n8T;>I|NPjNW_wg!WFn?WNW^UX^f`62O0q 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%0A02)Bo+S+uU)Hb=y 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 UYNgd?K;9(9tE%$pvid&%2YX)PmjD0& literal 0 HcmV?d00001 diff --git a/src/septidon/control.rs b/src/septidon/control.rs new file mode 100644 index 0000000..368afc0 --- /dev/null +++ b/src/septidon/control.rs @@ -0,0 +1,63 @@ +use super::util::query; +use crate::septidon::params::GATE_DEGREE_5; +use halo2_proofs::circuit::{Region, Value}; +use halo2_proofs::halo2curves::bn256::Fr as F; +use halo2_proofs::plonk::{Column, ConstraintSystem, Error, Expression, Fixed, VirtualCells}; +use halo2_proofs::poly::Rotation; + +#[derive(Clone, Debug)] +pub struct ControlChip { + is_last: Column, +} + +pub struct ControlSignals { + // Signals that control the switches between steps of the permutation. + pub break_full_rounds: Expression, + pub transition_round: Expression, + pub break_partial_rounds: Expression, + + // A selector that can disable all chips on all rows. + pub selector: Expression, +} + +impl ControlChip { + pub fn configure(cs: &mut ConstraintSystem) -> (Self, ControlSignals) { + let is_last = cs.fixed_column(); + + let signals = query(cs, |meta| { + let signal_middle = meta.query_fixed(is_last, Rotation(4)); // Seen from the middle row. + let signal_last = meta.query_fixed(is_last, Rotation::cur()); + let middle_or_last = signal_middle.clone() + signal_last.clone(); // Assume no overlap. + + ControlSignals { + break_full_rounds: middle_or_last, + transition_round: signal_middle, + break_partial_rounds: signal_last, + selector: Self::derive_selector(is_last, meta), + } + }); + + let chip = Self { is_last }; + (chip, signals) + } + + /// Assign the fixed positions of the last row of permutations. + pub fn assign(&self, region: &mut Region<'_, F>) -> Result<(), Error> { + region.assign_fixed(|| "", self.is_last, 7, || Value::known(F::one()))?; + Ok(()) + } + + fn derive_selector(is_last: Column, meta: &mut VirtualCells<'_, F>) -> Expression { + if GATE_DEGREE_5 { + // Variant with no selector. Do not disable gates, do not increase the gate degree. + Expression::Constant(F::one()) + } else { + // Variant with a selector enabled on all rows of valid permutations. + // Detect is_last=1, seen from its own row or up to 7 rows below. + (0..8_i32) + .map(|i| meta.query_fixed(is_last, Rotation(i))) + .reduce(|acc, x| acc + x) + .unwrap() // Boolean any. + } + } +} diff --git a/src/septidon/full_round.rs b/src/septidon/full_round.rs new file mode 100644 index 0000000..e26f755 --- /dev/null +++ b/src/septidon/full_round.rs @@ -0,0 +1,52 @@ +use super::loop_chip::LoopBody; +use super::params::mds; +use super::state::{Cell, FullState, SBox}; +use super::util::matmul; +use super::util::query; +use crate::septidon::util::{join_values, split_values}; +use halo2_proofs::circuit::{Region, Value}; +use halo2_proofs::halo2curves::bn256::Fr as F; +use halo2_proofs::plonk::{ConstraintSystem, Error, Expression, VirtualCells}; + +#[derive(Clone, Debug)] +pub struct FullRoundChip(pub FullState); + +impl FullRoundChip { + pub fn configure(cs: &mut ConstraintSystem) -> (Self, LoopBody) { + let chip = Self(FullState::configure(cs)); + + let loop_body = query(cs, |meta| { + let next_state = chip.0.map(|sbox| sbox.input.query(meta, 1)); + let output = chip.full_round_expr(meta); + LoopBody { next_state, output } + }); + + (chip, loop_body) + } + + fn full_round_expr(&self, meta: &mut VirtualCells<'_, F>) -> [Expression; 3] { + let sbox_out = self.0.map(|sbox: &SBox| sbox.output_expr(meta)); + matmul::expr(&mds(), sbox_out) + } + + pub fn input_cells(&self) -> [Cell; 3] { + self.0.map(|sbox| sbox.input.clone()) + } + + /// Assign the witness. + pub fn assign( + &self, + region: &mut Region<'_, F>, + offset: usize, + round_constants: [F; 3], + input: [Value; 3], + ) -> Result<[Value; 3], Error> { + let mut sbox_out = [Value::unknown(); 3]; + for i in 0..3 { + let sbox: &SBox = &self.0 .0[i]; + sbox_out[i] = sbox.assign(region, offset, round_constants[i], input[i])?; + } + let output = join_values(sbox_out).map(|sbox_out| matmul::value(&mds(), sbox_out)); + Ok(split_values(output)) + } +} diff --git a/src/septidon/instruction.rs b/src/septidon/instruction.rs new file mode 100644 index 0000000..ca9e7bd --- /dev/null +++ b/src/septidon/instruction.rs @@ -0,0 +1,95 @@ +use super::{params::F, util::map_array, SeptidonChip}; +use crate::poseidon::{ + primitives::{Spec, State}, + PermuteChip, PoseidonInstructions, StateWord, Var, +}; +use halo2_proofs::{ + circuit::{Chip, Layouter}, + plonk::{ConstraintSystem, Error}, +}; + +const WIDTH: usize = 3; +const RATE: usize = 2; + +impl PermuteChip for SeptidonChip { + fn configure(meta: &mut ConstraintSystem) -> Self::Config { + let chip = Self::configure(meta); + + // Enable equality on the input/output columns, required by the function permute. + for cell in chip.initial_state_cells() { + meta.enable_equality(cell.column); + } + for cell in chip.final_state_cells() { + meta.enable_equality(cell.column); + } + + chip + } + + fn construct(config: Self::Config) -> Self { + config + } +} + +impl> PoseidonInstructions for SeptidonChip { + type Word = StateWord; + + fn permute( + &self, + layouter: &mut impl Layouter, + initial_state: &State, + ) -> Result, Error> { + layouter.assign_region( + || "permute state", + |mut region| { + let region = &mut region; + + // Copy the given initial_state into the permutation chip. + let chip_input = self.initial_state_cells(); + for i in 0..WIDTH { + initial_state[i].0.copy_advice( + || format!("load state_{}", i), + region, + chip_input[i].column, + chip_input[i].offset as usize, + )?; + } + + // Assign the internal witness of the permutation. + let initial_values = map_array(&initial_state, |word| word.value()); + let final_values = self.assign_permutation(region, initial_values)?; + + // Return the cells containing the final state. + let chip_output = self.final_state_cells(); + let final_state: Vec> = (0..WIDTH) + .map(|i| { + region + .assign_advice( + || format!("output {i}"), + chip_output[i].column, + chip_output[i].offset as usize, + || final_values[i], + ) + .map(StateWord) + }) + .collect::, _>>()?; + + Ok(final_state.try_into().unwrap()) + }, + ) + } +} + +impl Chip for SeptidonChip { + type Config = Self; + + type Loaded = (); + + fn config(&self) -> &Self::Config { + self + } + + fn loaded(&self) -> &Self::Loaded { + &() + } +} diff --git a/src/septidon/loop_chip.rs b/src/septidon/loop_chip.rs new file mode 100644 index 0000000..db977e4 --- /dev/null +++ b/src/septidon/loop_chip.rs @@ -0,0 +1,41 @@ +use super::state::Cell; +use super::util::select; +use halo2_proofs::halo2curves::bn256::Fr as F; +use halo2_proofs::plonk::{ConstraintSystem, Constraints, Expression}; + +#[derive(Clone, Debug)] +pub struct LoopChip {} + +pub struct LoopBody { + pub next_state: [Expression; 3], + /// Cells where the output is, relative to the break signal. + pub output: [Expression; 3], +} + +impl LoopChip { + pub fn configure( + cs: &mut ConstraintSystem, + q: Expression, + body: LoopBody, + break_signal: Expression, + output: [Cell; 3], + ) -> Self { + cs.create_gate("loop", |meta| { + let constraints = (0..3) + .map(|i| { + let destination = select::expr( + break_signal.clone(), + output[i].query(meta, 0), + body.next_state[i].clone(), + ); + + destination - body.output[i].clone() + }) + .collect::>(); + + Constraints::with_selector(q, constraints) + }); + + Self {} + } +} diff --git a/src/septidon/params.rs b/src/septidon/params.rs new file mode 100644 index 0000000..1293472 --- /dev/null +++ b/src/septidon/params.rs @@ -0,0 +1,49 @@ +use crate::poseidon::primitives::p128pow5t3_compact::{P128Pow5T3CompactSpec, P128Pow5T3Constants}; +use crate::poseidon::primitives::Mds as MdsT; +use crate::poseidon::primitives::Spec; +use lazy_static::lazy_static; + +/// This implementation can be limited to gate degree 5. However, this mode will not work with +/// blinding or inactive rows. Enable only with a prover that supports assignments to all n rows. +pub const GATE_DEGREE_5: bool = false; + +/// This implementation supports only the scalar field of BN254 at the moment. +/// +/// To implement for the Pasta curves, adjust the parameters below, and replace the transition round +/// by a copy, to get 56 rounds instead of 57. +pub use halo2_proofs::halo2curves::bn256::Fr as F; + +pub mod sbox { + use super::super::util::pow_5; + use super::F; + use halo2_proofs::plonk::Expression; + + pub fn expr(input: Expression, round_constant: Expression) -> Expression { + pow_5::expr(input + round_constant) + } + + pub fn value(input: F, round_constant: F) -> F { + pow_5::value(input + round_constant) + } +} + +pub type Mds = MdsT; + +lazy_static! { + static ref MDS: Mds = F::mds(); +} + +pub fn mds() -> &'static Mds { + &MDS +} + +lazy_static! { + static ref ROUND_CONSTANTS: Vec<[F; 3]> = { + let (rc, _, _) = P128Pow5T3CompactSpec::::constants(); + rc + }; +} + +pub fn round_constant(index: usize) -> [F; 3] { + ROUND_CONSTANTS[index] +} diff --git a/src/septidon/septidon_chip.rs b/src/septidon/septidon_chip.rs new file mode 100644 index 0000000..720b3bd --- /dev/null +++ b/src/septidon/septidon_chip.rs @@ -0,0 +1,166 @@ +use halo2_proofs::circuit::{Region, Value}; +use halo2_proofs::halo2curves::bn256::Fr as F; +use halo2_proofs::plonk::{ConstraintSystem, Error}; + +use super::control::ControlChip; +use super::full_round::FullRoundChip; +use super::loop_chip::LoopChip; +use super::septuple_round::SeptupleRoundChip; +use super::state::Cell; +use super::transition_round::TransitionRoundChip; +use super::util::map_array; +use crate::septidon::params::round_constant; + +/// The configuration of the permutation chip. +/// +/// ``` +/// use halo2_proofs::halo2curves::bn256::Fr as F; +/// use halo2_proofs::plonk::ConstraintSystem; +/// use poseidon_circuit::septidon::SeptidonChip; +/// +/// let mut cs = ConstraintSystem::::default(); +/// let config = SeptidonChip::configure(&mut cs); +/// ``` +#[derive(Clone, Debug)] +pub struct SeptidonChip { + control_chip: ControlChip, + + transition_chip: TransitionRoundChip, + + full_round_chip: FullRoundChip, + + partial_round_chip: SeptupleRoundChip, +} + +impl SeptidonChip { + /// Create a new chip. + pub fn configure(cs: &mut ConstraintSystem) -> Self { + let (control_chip, signals) = ControlChip::configure(cs); + let q = || signals.selector.clone(); + + let (full_round_chip, full_round_loop_body) = FullRoundChip::configure(cs); + + let (partial_round_chip, partial_round_loop_body) = SeptupleRoundChip::configure(cs, q()); + + let transition_chip = { + // The output of the transition round is the input of the partial rounds loop. + let output = partial_round_chip.input(); + TransitionRoundChip::configure(cs, signals.transition_round, output) + }; + + { + // The output of full rounds go into the transition round. + let output = transition_chip.input(); + + LoopChip::configure( + cs, + q(), + full_round_loop_body, + signals.break_full_rounds, + output, + ) + }; + + { + // The output of partial rounds go horizontally into the second loop of full rounds, + // which runs parallel to the last 4 partials rounds (indexed [-3; 0]). + let full_round_sboxes = &full_round_chip.0 .0; + let output: [Cell; 3] = [ + full_round_sboxes[0].input.rotated(-3), + full_round_sboxes[1].input.rotated(-3), + full_round_sboxes[2].input.rotated(-3), + ]; + + LoopChip::configure( + cs, + q(), + partial_round_loop_body, + signals.break_partial_rounds, + output, + ) + }; + + let chip = Self { + control_chip, + transition_chip, + full_round_chip, + partial_round_chip, + }; + + chip + } + + /// How many rows are used per permutation. + pub fn height_per_permutation() -> usize { + 8 + } + + fn final_offset() -> usize { + Self::height_per_permutation() - 1 + } + + /// Return the cells containing the initial state. The parent chip must constrain these cells. + /// Cells are relative to the row 0 of a region of a permutation. + pub fn initial_state_cells(&self) -> [Cell; 3] { + self.full_round_chip.input_cells() + } + + /// Return the cells containing the final state. The parent chip must constrain these cells. + /// Cells are relative to the row 0 of a region of a permutation. + pub fn final_state_cells(&self) -> [Cell; 3] { + let relative_cells = self.transition_chip.input(); + map_array(&relative_cells, |cell| { + cell.rotated(Self::final_offset() as i32) + }) + } + + /// Assign the witness of a permutation into the given region. + pub fn assign_permutation( + &self, + region: &mut Region<'_, F>, + initial_state: [Value; 3], + ) -> Result<[Value; 3], Error> { + self.control_chip.assign(region)?; + + let mut state = initial_state; + + // First half of full rounds. + for offset in 0..4 { + state = self + .full_round_chip + .assign(region, offset, round_constant(offset), state)?; + } + + // First partial round. + // Its round constant is part of the gate (not a fixed column). + let middle_offset = 3; + state = self + .transition_chip + .assign_first_partial_state(region, middle_offset, state)?; + + // The rest of partial rounds. + for offset in 0..8 { + let round_index = 5 + offset * 7; + let round_constants = (round_index..round_index + 7) + .map(|idx| round_constant(idx)[0]) + .collect::>(); + state = self + .partial_round_chip + .assign(region, offset, &round_constants, state)?; + } + + // The second half of full rounds. + for offset in 4..8 { + state = + self.full_round_chip + .assign(region, offset, round_constant(offset + 57), state)?; + } + + // Put the final state into its place. + let final_offset = 7; + self.transition_chip + .assign_final_state(region, final_offset, state)?; + + Ok(state) + } +} diff --git a/src/septidon/septuple_round.rs b/src/septidon/septuple_round.rs new file mode 100644 index 0000000..ab80498 --- /dev/null +++ b/src/septidon/septuple_round.rs @@ -0,0 +1,124 @@ +use super::loop_chip::LoopBody; +use super::state::{Cell, SBox}; +use super::util::query; +use crate::septidon::params::mds; +use crate::septidon::util::{join_values, matmul, split_values}; +use halo2_proofs::circuit::{Region, Value}; +use halo2_proofs::halo2curves::bn256::Fr as F; +use halo2_proofs::plonk::{ConstraintSystem, Constraints, Error, Expression, VirtualCells}; + +#[derive(Clone, Debug)] +pub struct SeptupleRoundChip { + first_sbox: SBox, + first_linears: [Cell; 2], + following_sboxes: [SBox; 6], +} + +impl SeptupleRoundChip { + pub fn configure(cs: &mut ConstraintSystem, q: Expression) -> (Self, LoopBody) { + let chip = Self { + first_sbox: SBox::configure(cs), + first_linears: [Cell::configure(cs), Cell::configure(cs)], + following_sboxes: (0..6) + .map(|_| SBox::configure(cs)) + .collect::>() + .try_into() + .unwrap(), + }; + + let input = chip.input(); + let (input_state, next_state) = query(cs, |meta| { + ( + [ + input[0].query(meta, 0), // Not read directly but via first_sbox.output_expr. + input[1].query(meta, 0), + input[2].query(meta, 0), + ], + [ + input[0].query(meta, 1), + input[1].query(meta, 1), + input[2].query(meta, 1), + ], + ) + }); + + let output = { + // The input state is constrained by another chip (TransitionRoundChip). + let mut checked_sbox = &chip.first_sbox; + let mut state = input_state; + + cs.create_gate("septuple_round", |meta| { + let mut constraints = vec![]; + + for sbox_to_check in &chip.following_sboxes { + // Calculate the expression of the next state. + state = Self::partial_round_expr(meta, checked_sbox, &state); + + // Compare the high-degree expression of the state with the equivalent witness. + let witness = sbox_to_check.input_expr(meta); + constraints.push(state[0].clone() - witness.clone()); + // We validated the S-Box input, so we can use next_sbox.output_expr. + checked_sbox = sbox_to_check; + } + + // Output the last round as an expression. + state = Self::partial_round_expr(meta, checked_sbox, &state); + + Constraints::with_selector(q, constraints) + }); + state + }; + + let loop_body = LoopBody { next_state, output }; + + (chip, loop_body) + } + + fn partial_round_expr( + meta: &mut VirtualCells<'_, F>, + sbox: &SBox, + input: &[Expression; 3], + ) -> [Expression; 3] { + let sbox_out = [sbox.output_expr(meta), input[1].clone(), input[2].clone()]; + matmul::expr(&mds(), sbox_out) + } + + pub fn input(&self) -> [Cell; 3] { + [ + self.first_sbox.input.clone(), + self.first_linears[0].clone(), + self.first_linears[1].clone(), + ] + } + + /// Assign the witness. + pub fn assign( + &self, + region: &mut Region<'_, F>, + offset: usize, + round_constants: &[F], + input: [Value; 3], + ) -> Result<[Value; 3], Error> { + // Assign the first non-S-Box cells. + for i in 0..2 { + self.first_linears[i].assign(region, offset, input[1 + i])?; + } + + let mut state = input; + let mut assign_partial_round = |i: usize, sbox: &SBox| -> Result<(), Error> { + // Assign the following S-Boxes. + state[0] = sbox.assign(region, offset, round_constants[i], state[0])?; + // Apply the matrix. + state = split_values(join_values(state).map(|s| matmul::value(&mds(), s))); + Ok(()) + }; + + assign_partial_round(0, &self.first_sbox)?; + + for (i, sbox) in self.following_sboxes.iter().enumerate() { + assign_partial_round(1 + i, sbox)?; + } + + Ok(state) + } +} diff --git a/src/septidon/state.rs b/src/septidon/state.rs new file mode 100644 index 0000000..72f11a4 --- /dev/null +++ b/src/septidon/state.rs @@ -0,0 +1,133 @@ +use crate::septidon::params; +use halo2_proofs::circuit::{Region, Value}; +use halo2_proofs::halo2curves::bn256::Fr as F; +use halo2_proofs::plonk::{ + Advice, Column, ConstraintSystem, Error, Expression, Fixed, VirtualCells, +}; +use halo2_proofs::poly::Rotation; + +/// Cell remembers the relative position of a cell in the region of a permutation. +/// It can be used in configuration and synthesis. +#[derive(Clone, Debug)] +pub struct Cell { + pub column: Column, + /// An offset relative to the owner of this Cell. + pub offset: i32, +} + +impl Cell { + pub fn configure(cs: &mut ConstraintSystem) -> Self { + Cell { + column: cs.advice_column(), + offset: 0, + } + } + + pub fn new(column: Column, offset: i32) -> Self { + Self { column, offset } + } + + pub fn rotated(&self, offset: i32) -> Self { + Self { + column: self.column, + offset: self.offset + offset, + } + } + + pub fn query(&self, meta: &mut VirtualCells, offset: i32) -> Expression { + meta.query_advice(self.column, Rotation(self.offset + offset)) + } + + pub fn region_offset(&self) -> usize { + assert!(self.offset >= 0); + self.offset as usize + } + + pub fn assign( + &self, + region: &mut Region<'_, F>, + origin_offset: usize, + input: Value, + ) -> Result<(), Error> { + let offset = origin_offset as i32 + self.offset; + assert!(offset >= 0, "cannot assign to a cell outside of its region"); + region.assign_advice(|| "cell", self.column, offset as usize, || input)?; + Ok(()) + } +} + +#[derive(Clone, Debug)] +pub struct SBox { + pub input: Cell, + round_constant: Column, +} + +impl SBox { + pub fn configure(cs: &mut ConstraintSystem) -> Self { + SBox { + input: Cell::configure(cs), + round_constant: cs.fixed_column(), + } + } + + /// Assign the witness of the input. + pub fn assign( + &self, + region: &mut Region<'_, F>, + offset: usize, + round_constant: F, + input: Value, + ) -> Result, Error> { + region.assign_fixed( + || "round_constant", + self.round_constant, + offset + self.input.region_offset(), + || Value::known(round_constant), + )?; + region.assign_advice( + || "initial_state", + self.input.column, + offset + self.input.region_offset(), + || input, + )?; + let output = input.map(|i| params::sbox::value(i, round_constant)); + Ok(output) + } + + pub fn input_expr(&self, meta: &mut VirtualCells<'_, F>) -> Expression { + self.input.query(meta, 0) + } + + pub fn rc_expr(&self, meta: &mut VirtualCells<'_, F>) -> Expression { + meta.query_fixed(self.round_constant, Rotation(self.input.offset)) + } + + pub fn output_expr(&self, meta: &mut VirtualCells<'_, F>) -> Expression { + let input = self.input_expr(meta); + let round_constant = self.rc_expr(meta); + params::sbox::expr(input, round_constant) + } +} + +#[derive(Clone, Debug)] +pub struct FullState(pub [SBox; 3]); + +impl FullState { + pub fn configure(cs: &mut ConstraintSystem) -> Self { + Self([ + SBox::configure(cs), + SBox::configure(cs), + SBox::configure(cs), + ]) + } + + pub fn map(&self, mut f: F) -> [T; 3] + where + F: FnMut(&SBox) -> T, + { + let a = f(&self.0[0]); + let b = f(&self.0[1]); + let c = f(&self.0[2]); + [a, b, c] + } +} diff --git a/src/septidon/tests.rs b/src/septidon/tests.rs new file mode 100644 index 0000000..e0af700 --- /dev/null +++ b/src/septidon/tests.rs @@ -0,0 +1,66 @@ +use halo2_proofs::circuit::{Layouter, Region, SimpleFloorPlanner, Value}; +use halo2_proofs::dev::MockProver; +use halo2_proofs::halo2curves::bn256::Fr as F; +use halo2_proofs::plonk::{Circuit, ConstraintSystem, Error}; + +use super::SeptidonChip; +use crate::septidon::util::join_values; + +#[test] +fn septidon_permutation() { + let k = 5; + let inactive_rows = 6; // Assume default in this test. + + let circuit = TestCircuit { + height: (1 << k) - inactive_rows, + }; + let prover = MockProver::run(k as u32, &circuit, vec![]).unwrap(); + prover.verify_at_rows(0..1, 0..0).unwrap(); +} + +#[derive(Clone)] +struct TestCircuit { + height: usize, +} + +impl Circuit for TestCircuit { + type Config = SeptidonChip; + type FloorPlanner = SimpleFloorPlanner; + + fn without_witnesses(&self) -> Self { + self.clone() + } + + fn configure(cs: &mut ConstraintSystem) -> Self::Config { + SeptidonChip::configure(cs) + } + + fn synthesize( + &self, + config: SeptidonChip, + mut layouter: impl Layouter, + ) -> Result<(), Error> { + let num_permutations = self.height / 8; + + for _ in 0..num_permutations { + let initial_state = [ + Value::known(F::from(0)), + Value::known(F::from(1)), + Value::known(F::from(2)), + ]; + + let final_state = layouter.assign_region( + || "SeptidonChip", + |mut region: Region<'_, F>| config.assign_permutation(&mut region, initial_state), + )?; + + let got = format!("{:?}", join_values(final_state).inner.unwrap()); + + // For input 0,1,2. + let expect = "[0x115cc0f5e7d690413df64c6b9662e9cf2a3617f2743245519e19607a4417189a, 0x0fca49b798923ab0239de1c9e7a4a9a2210312b6a2f616d18b5a87f9b628ae29, 0x0e7ae82e40091e63cbd4f16a6d16310b3729d4b6e138fcf54110e2867045a30c]"; + assert_eq!(got, expect); + } + + Ok(()) + } +} diff --git a/src/septidon/transition_round.rs b/src/septidon/transition_round.rs new file mode 100644 index 0000000..7d6c1f5 --- /dev/null +++ b/src/septidon/transition_round.rs @@ -0,0 +1,125 @@ +use super::state::Cell; +use crate::septidon::params; +use crate::septidon::params::{mds, round_constant}; +use crate::septidon::util::{join_values, matmul, split_values}; +use halo2_proofs::circuit::{Region, Value}; +use halo2_proofs::halo2curves::bn256::Fr as F; +use halo2_proofs::plonk::{Advice, Column, ConstraintSystem, Constraints, Error, Expression}; + +#[derive(Clone, Debug)] +pub struct TransitionRoundChip { + column: Column, +} + +impl TransitionRoundChip { + pub fn configure( + cs: &mut ConstraintSystem, + signal: Expression, + next_state: [Cell; 3], + ) -> Self { + let chip = Self { + column: cs.advice_column(), + }; + + cs.create_gate("transition round", |meta| { + // The input cells are relative to the signal. + let input = chip.input(); + let input = [ + input[0].query(meta, 0), + input[1].query(meta, 0), + input[2].query(meta, 0), + ]; + + let output = Self::first_partial_round_expr(&input); + + // Get the next_state from the point of view of the signal. + let next_state = [ + next_state[0].query(meta, -3), + next_state[1].query(meta, -3), + next_state[2].query(meta, -3), + ]; + + let constraints = vec![ + output[0].clone() - next_state[0].clone(), + output[1].clone() - next_state[1].clone(), + output[2].clone() - next_state[2].clone(), + ]; + + Constraints::with_selector(signal, constraints) + }); + + chip + } + + // Return an expression of the state after the first partial round given the state before. + // TODO: implement with with degree <= 5 using the helper cell. + fn first_partial_round_expr(input: &[Expression; 3]) -> [Expression; 3] { + let rc = Expression::Constant(Self::round_constant()); + let sbox_out = [ + params::sbox::expr(input[0].clone(), rc), + input[1].clone(), + input[2].clone(), + ]; + matmul::expr(&mds(), sbox_out) + } + + fn round_constant() -> F { + round_constant(4)[0] + } + + /// Return the input cells of this round, relative to the signal. + // TODO: rename because it is also used as final state. + pub fn input(&self) -> [Cell; 3] { + // The input to the transition round is vertical in the transition column. + [ + Cell::new(self.column, -2), + Cell::new(self.column, -1), + Cell::new(self.column, 0), + ] + } + + pub fn helper_cell(&self) -> Cell { + Cell::new(self.column, -3) + } + + /// Assign the state of the first partial round, and return the round output. + pub fn assign_first_partial_state( + &self, + region: &mut Region<'_, F>, + middle_break_offset: usize, + input: [Value; 3], + ) -> Result<[Value; 3], Error> { + let output = Self::first_partial_round(&input); + for (value, cell) in input.into_iter().zip(self.input()) { + cell.assign(region, middle_break_offset, value)?; + } + self.helper_cell() + .assign(region, middle_break_offset, Value::known(F::zero()))?; + Ok(output) + } + + fn first_partial_round(input: &[Value; 3]) -> [Value; 3] { + let sbox_out = [ + input[0].map(|f| params::sbox::value(f, Self::round_constant())), + input[1], + input[2], + ]; + let output = join_values(sbox_out).map(|s| matmul::value(&mds(), s)); + split_values(output) + } + + /// Assign the final state. This has the same layout as the first partial state, at another offset. + pub fn assign_final_state( + &self, + region: &mut Region<'_, F>, + final_break_offset: usize, + input: [Value; 3], + ) -> Result<(), Error> { + for (value, cell) in input.into_iter().zip(self.input()) { + cell.assign(region, final_break_offset, value)?; + } + self.helper_cell() + .assign(region, final_break_offset, Value::known(F::zero()))?; + Ok(()) + } +} diff --git a/src/septidon/util.rs b/src/septidon/util.rs new file mode 100644 index 0000000..847e0ab --- /dev/null +++ b/src/septidon/util.rs @@ -0,0 +1,130 @@ +use halo2_proofs::circuit::Value; +use halo2_proofs::halo2curves::bn256::Fr as F; +use halo2_proofs::plonk::{ConstraintSystem, Expression, VirtualCells}; + +pub fn map_array(array: &[IN; 3], mut f: FN) -> [OUT; 3] +where + FN: FnMut(&IN) -> OUT, +{ + let a = f(&array[0]); + let b = f(&array[1]); + let c = f(&array[2]); + [a, b, c] +} + +/// Helper to make queries to a ConstraintSystem. Escape the "create_gate" closures. +pub fn query(cs: &mut ConstraintSystem, f: impl FnOnce(&mut VirtualCells<'_, F>) -> T) -> T { + let mut queries: Option = None; + cs.create_gate("query", |meta| { + queries = Some(f(meta)); + [Expression::Constant(F::zero())] + }); + queries.unwrap() +} + +pub fn join_values(values: [Value; 3]) -> Value<[F; 3]> { + values[0] + .zip(values[1]) + .zip(values[2]) + .map(|((v0, v1), v2)| [v0, v1, v2]) +} + +pub fn split_values(values: Value<[F; 3]>) -> [Value; 3] { + [ + values.map(|v| v[0]), + values.map(|v| v[1]), + values.map(|v| v[2]), + ] +} + +pub mod pow_5 { + use super::super::params::F; + use halo2_proofs::plonk::Expression; + + pub fn expr(v: Expression) -> Expression { + let v2 = v.clone() * v.clone(); + v2.clone() * v2 * v + } + + pub fn value(v: F) -> F { + let v2 = v * v; + v2 * v2 * v + } +} + +/// Matrix multiplication expressions and values. +pub mod matmul { + use super::super::params::{Mds, F}; + use halo2_proofs::plonk::Expression; + use std::convert::TryInto; + + /// Multiply a vector of expressions by a constant matrix. + pub fn expr(matrix: &Mds, vector: [Expression; 3]) -> [Expression; 3] { + (0..3) + .map(|next_idx| { + (0..3) + .map(|idx| vector[idx].clone() * matrix[next_idx][idx]) + .reduce(|acc, term| acc + term) + .unwrap() + }) + .collect::>() + .try_into() + .unwrap() + } + + /// Multiply a vector of values by a constant matrix. + pub fn value(matrix: &Mds, vector: [F; 3]) -> [F; 3] { + (0..3) + .map(|next_idx| { + (0..3) + .map(|idx| vector[idx] * matrix[next_idx][idx]) + .reduce(|acc, term| acc + term) + .unwrap() + }) + .collect::>() + .try_into() + .unwrap() + } +} + +/// Returns `when_true` when `selector == 1`, and returns `when_false` when +/// `selector == 0`. `selector` needs to be boolean. +pub mod select { + use halo2_proofs::{arithmetic::FieldExt, plonk::Expression}; + + /// Returns the `when_true` expression when the selector is true, else + /// returns the `when_false` expression. + pub fn expr( + selector: Expression, + when_true: Expression, + when_false: Expression, + ) -> Expression { + let one = Expression::Constant(F::from(1)); + selector.clone() * when_true + (one - selector) * when_false + } + + /// Returns the `when_true` value when the selector is true, else returns + /// the `when_false` value. + pub fn value(selector: F, when_true: F, when_false: F) -> F { + selector * when_true + (F::one() - selector) * when_false + } +} + +/// Gadget for boolean OR. +pub mod or { + use halo2_proofs::{arithmetic::FieldExt, plonk::Expression}; + + /// Return (a OR b), assuming a and b are boolean expressions. + pub fn expr(a: Expression, b: Expression) -> Expression { + let one = Expression::Constant(F::from(1)); + // a OR b <=> !(!a AND !b) + one.clone() - ((one.clone() - a) * (one.clone() - b)) + } + + /// Return (a OR b), assuming a and b are boolean values. + pub fn value(a: F, b: F) -> F { + let one = F::one(); + // a OR b <=> !(!a AND !b) + one - ((one - a) * (one - b)) + } +} diff --git a/tests/hash_proving.rs b/tests/hash_proving.rs index fad83b6..8c1cd24 100644 --- a/tests/hash_proving.rs +++ b/tests/hash_proving.rs @@ -17,6 +17,7 @@ use halo2_proofs::{ circuit::{Layouter, SimpleFloorPlanner}, plonk::{Circuit, ConstraintSystem, Error}, }; +use poseidon_circuit::poseidon::Pow5Chip; use poseidon_circuit::{hash::*, DEFAULT_STEP}; use rand::SeedableRng; use rand_chacha::ChaCha8Rng; @@ -25,7 +26,7 @@ struct TestCircuit(PoseidonHashTable, usize); // test circuit derived from table data impl Circuit for TestCircuit { - type Config = PoseidonHashConfig; + type Config = PoseidonHashConfig>; type FloorPlanner = SimpleFloorPlanner; fn without_witnesses(&self) -> Self { @@ -42,7 +43,7 @@ impl Circuit for TestCircuit { config: Self::Config, mut layouter: impl Layouter, ) -> Result<(), Error> { - let chip = PoseidonHashChip::::construct( + let chip = PoseidonHashChip::>::construct( config, &self.0, self.1, From fd91bb78ead6a8cb3648861554976f57a29ae538 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Nicolas?= Date: Mon, 20 Mar 2023 21:22:21 +0100 Subject: [PATCH 10/10] halo2-ecc-snark-verifier-0220: fixes after merge --- src/hash.rs | 4 ++-- src/poseidon.rs | 4 ++-- src/poseidon/primitives/p128pow5t3_compact.rs | 19 ++++++++++--------- src/septidon/util.rs | 16 ++++++++-------- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/hash.rs b/src/hash.rs index 326064d..d0c1c94 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -173,7 +173,7 @@ impl> PoseidonHashConfig { vec![ s_enable.clone() * (ctrl + Expression::Constant(Fp::from_u128(step as u128)) - ctrl_prev), - s_enable * (Expression::Constant(Fp::one()) - ctrl_bool), + s_enable * (Expression::Constant(Fp::ONE) - ctrl_bool), ] }); @@ -278,7 +278,7 @@ impl PoseidonHashTable { for (a, b, c) in src { self.inputs.push([*a, *b]); self.checks.push(Some(*c)); - self.controls.push(Fp::zero()); + self.controls.push(Fp::ZERO); } } diff --git a/src/poseidon.rs b/src/poseidon.rs index 7e60816..b558aee 100644 --- a/src/poseidon.rs +++ b/src/poseidon.rs @@ -6,7 +6,7 @@ use std::marker::PhantomData; use halo2_proofs::{ circuit::{AssignedCell, Chip, Layouter}, - ff::{Field, FromUniformBytes}, + ff::{Field, FromUniformBytes, PrimeField}, plonk::{ConstraintSystem, Error}, }; @@ -27,7 +27,7 @@ pub enum PaddedWord { } /// This trait is the interface to chips that implement a permutation. -pub trait PermuteChip: Chip + Clone + DebugT { +pub trait PermuteChip: Chip + Clone + DebugT { /// Configure the permutation chip. fn configure(meta: &mut ConstraintSystem) -> Self::Config; diff --git a/src/poseidon/primitives/p128pow5t3_compact.rs b/src/poseidon/primitives/p128pow5t3_compact.rs index f6db10c..d669525 100644 --- a/src/poseidon/primitives/p128pow5t3_compact.rs +++ b/src/poseidon/primitives/p128pow5t3_compact.rs @@ -1,7 +1,6 @@ +use halo2_proofs::ff::{FromUniformBytes, PrimeField}; use std::marker::PhantomData; -use halo2_proofs::arithmetic::FieldExt; - pub use super::p128pow5t3::P128Pow5T3Constants; use super::{Mds, Spec}; @@ -13,7 +12,9 @@ pub struct P128Pow5T3CompactSpec { _marker: PhantomData, } -impl Spec for P128Pow5T3CompactSpec { +impl + Ord> Spec + for P128Pow5T3CompactSpec +{ fn full_rounds() -> usize { 8 } @@ -55,8 +56,8 @@ impl Spec for P128Pow5T3CompactSpec { } } -fn mat_mul(mat: &Mds, input: &[Fp; T]) -> [Fp; T] { - let mut out = [Fp::zero(); T]; +fn mat_mul(mat: &Mds, input: &[Fp; T]) -> [Fp; T] { + let mut out = [Fp::ZERO; T]; #[allow(clippy::needless_range_loop)] for i in 0..T { for j in 0..T { @@ -66,17 +67,17 @@ fn mat_mul(mat: &Mds, input: &[Fp; T]) -> [ out } -fn vec_accumulate(a: &mut [Fp; T], b: &[Fp; T]) { +fn vec_accumulate(a: &mut [Fp; T], b: &[Fp; T]) { for i in 0..T { a[i] += b[i]; } } -fn vec_remove_tail(a: &mut [Fp; T]) -> [Fp; T] { - let mut tail = [Fp::zero(); T]; +fn vec_remove_tail(a: &mut [Fp; T]) -> [Fp; T] { + let mut tail = [Fp::ZERO; T]; for i in 1..T { tail[i] = a[i]; - a[i] = Fp::zero(); + a[i] = Fp::ZERO; } tail } diff --git a/src/septidon/util.rs b/src/septidon/util.rs index 847e0ab..f7df926 100644 --- a/src/septidon/util.rs +++ b/src/septidon/util.rs @@ -90,11 +90,11 @@ pub mod matmul { /// Returns `when_true` when `selector == 1`, and returns `when_false` when /// `selector == 0`. `selector` needs to be boolean. pub mod select { - use halo2_proofs::{arithmetic::FieldExt, plonk::Expression}; + use halo2_proofs::{ff::PrimeField, plonk::Expression}; /// Returns the `when_true` expression when the selector is true, else /// returns the `when_false` expression. - pub fn expr( + pub fn expr( selector: Expression, when_true: Expression, when_false: Expression, @@ -105,25 +105,25 @@ pub mod select { /// Returns the `when_true` value when the selector is true, else returns /// the `when_false` value. - pub fn value(selector: F, when_true: F, when_false: F) -> F { - selector * when_true + (F::one() - selector) * when_false + pub fn value(selector: F, when_true: F, when_false: F) -> F { + selector * when_true + (F::ONE - selector) * when_false } } /// Gadget for boolean OR. pub mod or { - use halo2_proofs::{arithmetic::FieldExt, plonk::Expression}; + use halo2_proofs::{ff::PrimeField, plonk::Expression}; /// Return (a OR b), assuming a and b are boolean expressions. - pub fn expr(a: Expression, b: Expression) -> Expression { + pub fn expr(a: Expression, b: Expression) -> Expression { let one = Expression::Constant(F::from(1)); // a OR b <=> !(!a AND !b) one.clone() - ((one.clone() - a) * (one.clone() - b)) } /// Return (a OR b), assuming a and b are boolean values. - pub fn value(a: F, b: F) -> F { - let one = F::one(); + pub fn value(a: F, b: F) -> F { + let one = F::ONE; // a OR b <=> !(!a AND !b) one - ((one - a) * (one - b)) }