From 07aff4a3e442512160f526ea6c9282e2af573745 Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Fri, 29 Nov 2024 14:22:10 +0000 Subject: [PATCH 01/35] included poseidon-gadget --- plonkish_backend/Cargo.toml | 7 + plonkish_backend/src/frontend/halo2.rs | 2 + .../src/frontend/halo2/poseidongadget.rs | 14 + .../frontend/halo2/poseidongadget/poseidon.rs | 298 ++++ .../halo2/poseidongadget/poseidon/pow5.rs | 883 ++++++++++ .../poseidongadget/poseidon/primitives.rs | 408 +++++ .../poseidongadget/poseidon/primitives/fp.rs | 1431 +++++++++++++++++ .../poseidongadget/poseidon/primitives/fq.rs | 1431 +++++++++++++++++ .../poseidon/primitives/grain.rs | 196 +++ .../poseidongadget/poseidon/primitives/mds.rs | 124 ++ .../poseidon/primitives/p128pow5t3.rs | 320 ++++ .../poseidon/primitives/test_vectors.rs | 1261 +++++++++++++++ .../halo2/poseidongadget/utilities.rs | 496 ++++++ .../poseidongadget/utilities/cond_swap.rs | 289 ++++ .../utilities/rm_lookup_range_check.rs | 658 ++++++++ 15 files changed, 7818 insertions(+) create mode 100644 plonkish_backend/src/frontend/halo2/poseidongadget.rs create mode 100644 plonkish_backend/src/frontend/halo2/poseidongadget/poseidon.rs create mode 100644 plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/pow5.rs create mode 100644 plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives.rs create mode 100644 plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/fp.rs create mode 100644 plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/fq.rs create mode 100644 plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/grain.rs create mode 100644 plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/mds.rs create mode 100644 plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/p128pow5t3.rs create mode 100644 plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/test_vectors.rs create mode 100644 plonkish_backend/src/frontend/halo2/poseidongadget/utilities.rs create mode 100644 plonkish_backend/src/frontend/halo2/poseidongadget/utilities/cond_swap.rs create mode 100644 plonkish_backend/src/frontend/halo2/poseidongadget/utilities/rm_lookup_range_check.rs diff --git a/plonkish_backend/Cargo.toml b/plonkish_backend/Cargo.toml index e22ceb94..98519583 100644 --- a/plonkish_backend/Cargo.toml +++ b/plonkish_backend/Cargo.toml @@ -16,6 +16,11 @@ serde = { version = "1.0", features = ["derive"] } bincode = "1.3.3" sha3 = "0.10.6" poseidon = { git = "https://github.com/han0110/poseidon", branch = "feature/with-spec" } +# TO DO - remove these 4 lines? +ff = { version = "0.13", features = ["bits"] } +group = "0.13" +proptest = { version = "1.0.0", optional = true } +uint = "0.9.2" # timer ark-std = { version = "^0.4.0", default-features = false, optional = true } @@ -30,6 +35,8 @@ halo2_proofs = { git = "https://github.com/han0110/halo2.git", branch = "feature paste = "1.0.11" criterion = "0.4.0" pprof = { version = "0.11.0", features = ["criterion", "flamegraph"] } +# remove below line? +proptest = "1.0.0" [features] default = ["parallel", "frontend-halo2"] diff --git a/plonkish_backend/src/frontend/halo2.rs b/plonkish_backend/src/frontend/halo2.rs index 2e198f13..54d0fa1f 100644 --- a/plonkish_backend/src/frontend/halo2.rs +++ b/plonkish_backend/src/frontend/halo2.rs @@ -26,6 +26,8 @@ use std::{ pub mod circuit; #[cfg(test)] mod test; +pub mod poseidongadget; + pub trait CircuitExt: Circuit { fn rand(_k: usize, _rng: impl RngCore) -> Self diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget.rs b/plonkish_backend/src/frontend/halo2/poseidongadget.rs new file mode 100644 index 00000000..98453f11 --- /dev/null +++ b/plonkish_backend/src/frontend/halo2/poseidongadget.rs @@ -0,0 +1,14 @@ +// This crate been taking from privacy scaling explorations crate: https://github.com/privacy-scaling-explorations/poseidon-gadget/tree/main/src +//! This crate provides the poseidon gadget for use with `halo2_proofs`. +//! This gadget has been extracted from zcash's halo2_gadgets: +//! https://github.com/zcash/halo2/tree/main/halo2_gadgets + +#![cfg_attr(docsrs, feature(doc_cfg))] +// Catch documentation errors caused by code changes. +#![deny(rustdoc::broken_intra_doc_links)] +#![deny(missing_debug_implementations)] +#![deny(missing_docs)] +#![deny(unsafe_code)] + +pub mod poseidon; +pub mod utilities; \ No newline at end of file diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon.rs b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon.rs new file mode 100644 index 00000000..e93e7a2c --- /dev/null +++ b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon.rs @@ -0,0 +1,298 @@ +//! The Poseidon algebraic hash function. + +use std::convert::TryInto; +use std::fmt; +use std::marker::PhantomData; + +use ff::PrimeField; +use group::ff::Field; +use halo2_proofs::{ + circuit::{AssignedCell, Chip, Layouter}, + plonk::Error, +}; + +mod pow5; +pub use pow5::{Pow5Chip, Pow5Config, StateWord}; + +pub mod primitives; +use primitives::{Absorbing, ConstantLength, Domain, Spec, SpongeMode, Squeezing, State}; + +/// A word from the padded input to a Poseidon sponge. +#[derive(Clone, Debug)] +pub enum PaddedWord { + /// A message word provided by the prover. + Message(AssignedCell), + /// A padding word, that will be fixed in the circuit parameters. + Padding(F), +} + +/// The set of circuit instructions required to use the Poseidon permutation. +pub trait PoseidonInstructions, const T: usize, const RATE: usize>: + Chip +{ + /// Variable representing the word over which the Poseidon permutation operates. + type Word: Clone + fmt::Debug + From> + Into>; + + /// Applies the Poseidon permutation to the given state. + fn permute( + &self, + layouter: &mut impl Layouter, + initial_state: &State, + ) -> Result, Error>; +} + +/// The set of circuit instructions required to use the [`Sponge`] and [`Hash`] gadgets. +/// +/// [`Hash`]: self::Hash +pub trait PoseidonSpongeInstructions< + F: Field, + S: Spec, + D: Domain, + const T: usize, + const RATE: usize, +>: PoseidonInstructions +{ + /// Returns the initial empty state for the given domain. + fn initial_state(&self, layouter: &mut impl Layouter) + -> Result, Error>; + + /// Adds the given input to the state. + fn add_input( + &self, + layouter: &mut impl Layouter, + initial_state: &State, + input: &Absorbing, RATE>, + ) -> Result, Error>; + + /// Extracts sponge output from the given state. + fn get_output(state: &State) -> Squeezing; +} + +/// A word over which the Poseidon permutation operates. +#[derive(Debug)] +pub struct Word< + F: Field, + PoseidonChip: PoseidonInstructions, + S: Spec, + // Width + const T: usize, + const RATE: usize, +> { + inner: PoseidonChip::Word, +} + +impl< + F: Field, + PoseidonChip: PoseidonInstructions, + S: Spec, + const T: usize, + const RATE: usize, + > Word +{ + /// The word contained in this gadget. + pub fn inner(&self) -> PoseidonChip::Word { + self.inner.clone() + } + + /// Construct a [`Word`] gadget from the inner word. + pub fn from_inner(inner: PoseidonChip::Word) -> Self { + Self { inner } + } +} + +fn poseidon_sponge< + F: Field, + PoseidonChip: PoseidonSpongeInstructions, + S: Spec, + D: Domain, + const T: usize, + const RATE: usize, +>( + chip: &PoseidonChip, + mut layouter: impl Layouter, + state: &mut State, + input: Option<&Absorbing, RATE>>, +) -> Result, Error> { + if let Some(input) = input { + *state = chip.add_input(&mut layouter, state, input)?; + } + *state = chip.permute(&mut layouter, state)?; + Ok(PoseidonChip::get_output(state)) +} + +/// A Poseidon sponge. +#[derive(Debug)] +pub struct Sponge< + F: Field, + PoseidonChip: PoseidonSpongeInstructions, + S: Spec, + M: SpongeMode, + D: Domain, + const T: usize, + const RATE: usize, +> { + chip: PoseidonChip, + mode: M, + state: State, + _marker: PhantomData, +} + +impl< + F: Field, + PoseidonChip: PoseidonSpongeInstructions, + S: Spec, + D: Domain, + const T: usize, + const RATE: usize, + > Sponge, RATE>, D, T, RATE> +{ + /// Constructs a new duplex sponge for the given Poseidon specification. + pub fn new(chip: PoseidonChip, mut layouter: impl Layouter) -> Result { + chip.initial_state(&mut layouter).map(|state| Sponge { + chip, + mode: Absorbing( + (0..RATE) + .map(|_| None) + .collect::>() + .try_into() + .unwrap(), + ), + state, + _marker: PhantomData, + }) + } + + /// Absorbs an element into the sponge. + pub fn absorb( + &mut self, + mut layouter: impl Layouter, + value: PaddedWord, + ) -> Result<(), Error> { + for entry in self.mode.0.iter_mut() { + if entry.is_none() { + *entry = Some(value); + return Ok(()); + } + } + + // We've already absorbed as many elements as we can + let _ = poseidon_sponge( + &self.chip, + layouter.namespace(|| "PoseidonSponge"), + &mut self.state, + Some(&self.mode), + )?; + self.mode = Absorbing::init_with(value); + + Ok(()) + } + + /// Transitions the sponge into its squeezing state. + #[allow(clippy::type_complexity)] + pub fn finish_absorbing( + mut self, + mut layouter: impl Layouter, + ) -> Result, D, T, RATE>, Error> + { + let mode = poseidon_sponge( + &self.chip, + layouter.namespace(|| "PoseidonSponge"), + &mut self.state, + Some(&self.mode), + )?; + + Ok(Sponge { + chip: self.chip, + mode, + state: self.state, + _marker: PhantomData, + }) + } +} + +impl< + F: Field, + PoseidonChip: PoseidonSpongeInstructions, + S: Spec, + D: Domain, + const T: usize, + const RATE: usize, + > Sponge, D, T, RATE> +{ + /// Squeezes an element from the sponge. + pub fn squeeze(&mut self, mut layouter: impl Layouter) -> Result, Error> { + loop { + for entry in self.mode.0.iter_mut() { + if let Some(inner) = entry.take() { + return Ok(inner.into()); + } + } + + // We've already squeezed out all available elements + self.mode = poseidon_sponge( + &self.chip, + layouter.namespace(|| "PoseidonSponge"), + &mut self.state, + None, + )?; + } + } +} + +/// A Poseidon hash function, built around a sponge. +#[derive(Debug)] +pub struct Hash< + F: Field, + PoseidonChip: PoseidonSpongeInstructions, + S: Spec, + D: Domain, + const T: usize, + const RATE: usize, +> { + sponge: Sponge, RATE>, D, T, RATE>, +} + +impl< + F: Field, + PoseidonChip: PoseidonSpongeInstructions, + S: Spec, + D: Domain, + const T: usize, + const RATE: usize, + > Hash +{ + /// Initializes a new hasher. + pub fn init(chip: PoseidonChip, layouter: impl Layouter) -> Result { + Sponge::new(chip, layouter).map(|sponge| Hash { sponge }) + } +} + +impl< + F: PrimeField, + PoseidonChip: PoseidonSpongeInstructions, T, RATE>, + S: Spec, + const T: usize, + const RATE: usize, + const L: usize, + > Hash, T, RATE> +{ + /// Hashes the given input. + pub fn hash( + mut self, + mut layouter: impl Layouter, + message: [AssignedCell; L], + ) -> Result, Error> { + for (i, value) in message + .into_iter() + .map(PaddedWord::Message) + .chain( as Domain>::padding(L).map(PaddedWord::Padding)) + .enumerate() + { + self.sponge + .absorb(layouter.namespace(|| format!("absorb_{i}")), value)?; + } + self.sponge + .finish_absorbing(layouter.namespace(|| "finish absorbing"))? + .squeeze(layouter.namespace(|| "squeeze")) + } +} diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/pow5.rs b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/pow5.rs new file mode 100644 index 00000000..18a80c50 --- /dev/null +++ b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/pow5.rs @@ -0,0 +1,883 @@ +use std::convert::TryInto; +use std::iter; + +use halo2_proofs::{ + arithmetic::Field, + circuit::{AssignedCell, Cell, Chip, Layouter, Region, Value}, + plonk::{ + Advice, Any, Column, ConstraintSystem, Constraints, Error, Expression, Fixed, Selector, + }, + poly::Rotation, +}; + +use super::{ + primitives::{Absorbing, Domain, Mds, Spec, Squeezing, State}, + PaddedWord, PoseidonInstructions, PoseidonSpongeInstructions, +}; +use crate::frontend::halo2::poseidongadget::utilities::Var; + +/// Configuration for a [`Pow5Chip`]. +#[derive(Clone, Debug)] +pub struct Pow5Config { + pub(crate) state: [Column; WIDTH], + partial_sbox: Column, + rc_a: [Column; WIDTH], + rc_b: [Column; WIDTH], + s_full: Selector, + s_partial: Selector, + s_pad_and_add: Selector, + + half_full_rounds: usize, + half_partial_rounds: usize, + alpha: [u64; 4], + round_constants: Vec<[F; WIDTH]>, + m_reg: Mds, + #[allow(dead_code)] + m_inv: Mds, +} + +/// A Poseidon chip using an $x^5$ S-Box. +/// +/// The chip is implemented using a single round per row for full rounds, and two rounds +/// per row for partial rounds. +#[derive(Debug)] +pub struct Pow5Chip { + config: Pow5Config, +} + +impl Pow5Chip { + /// Configures this chip for use in a circuit. + /// + /// # Side-effects + /// + /// All columns in `state` will be equality-enabled. + // + // TODO: Does the rate need to be hard-coded here, or only the width? It probably + // needs to be known wherever we implement the hashing gadget, but it isn't strictly + // necessary for the permutation. + pub fn configure>( + meta: &mut ConstraintSystem, + state: [Column; WIDTH], + partial_sbox: Column, + rc_a: [Column; WIDTH], + rc_b: [Column; WIDTH], + ) -> Pow5Config { + assert_eq!(RATE, WIDTH - 1); + // Generate constants for the Poseidon permutation. + // This gadget requires R_F and R_P to be even. + assert!(S::full_rounds() & 1 == 0); + assert!(S::partial_rounds() & 1 == 0); + let half_full_rounds = S::full_rounds() / 2; + let half_partial_rounds = S::partial_rounds() / 2; + let (round_constants, m_reg, m_inv) = S::constants(); + + // This allows state words to be initialized (by constraining them equal to fixed + // values), and used in a permutation from an arbitrary region. rc_a is used in + // every permutation round, while rc_b is empty in the initial and final full + // rounds, so we use rc_b as "scratch space" for fixed values (enabling potential + // layouter optimisations). + for column in iter::empty() + .chain(state.iter().cloned().map(Column::::from)) + .chain(rc_b.iter().cloned().map(Column::::from)) + { + meta.enable_equality(column); + } + + let s_full = meta.selector(); + let s_partial = meta.selector(); + let s_pad_and_add = meta.selector(); + + let alpha = [5, 0, 0, 0]; + let pow_5 = |v: Expression| { + let v2 = v.clone() * v.clone(); + v2.clone() * v2 * v + }; + + meta.create_gate("full round", |meta| { + let s_full = meta.query_selector(s_full); + + Constraints::with_selector( + s_full, + (0..WIDTH) + .map(|next_idx| { + let state_next = meta.query_advice(state[next_idx], Rotation::next()); + let expr = (0..WIDTH) + .map(|idx| { + let state_cur = meta.query_advice(state[idx], Rotation::cur()); + let rc_a = meta.query_fixed(rc_a[idx], Rotation::cur()); + pow_5(state_cur + rc_a) * m_reg[next_idx][idx] + }) + .reduce(|acc, term| acc + term) + .expect("WIDTH > 0"); + expr - state_next + }) + .collect::>(), + ) + }); + + meta.create_gate("partial rounds", |meta| { + let cur_0 = meta.query_advice(state[0], Rotation::cur()); + let mid_0 = meta.query_advice(partial_sbox, Rotation::cur()); + + let rc_a0 = meta.query_fixed(rc_a[0], Rotation::cur()); + let rc_b0 = meta.query_fixed(rc_b[0], Rotation::cur()); + + let s_partial = meta.query_selector(s_partial); + + use halo2_proofs::plonk::VirtualCells; + let mid = |idx: usize, meta: &mut VirtualCells| { + let mid = mid_0.clone() * m_reg[idx][0]; + (1..WIDTH).fold(mid, |acc, cur_idx| { + let cur = meta.query_advice(state[cur_idx], Rotation::cur()); + let rc_a = meta.query_fixed(rc_a[cur_idx], Rotation::cur()); + acc + (cur + rc_a) * m_reg[idx][cur_idx] + }) + }; + + let next = |idx: usize, meta: &mut VirtualCells| { + (0..WIDTH) + .map(|next_idx| { + let next = meta.query_advice(state[next_idx], Rotation::next()); + next * m_inv[idx][next_idx] + }) + .reduce(|acc, next| acc + next) + .expect("WIDTH > 0") + }; + + let partial_round_linear = |idx: usize, meta: &mut VirtualCells| { + let rc_b = meta.query_fixed(rc_b[idx], Rotation::cur()); + mid(idx, meta) + rc_b - next(idx, meta) + }; + + Constraints::with_selector( + s_partial, + std::iter::empty() + // state[0] round a + .chain(Some(pow_5(cur_0 + rc_a0) - mid_0.clone())) + // state[0] round b + .chain(Some(pow_5(mid(0, meta) + rc_b0) - next(0, meta))) + .chain((1..WIDTH).map(|idx| partial_round_linear(idx, meta))) + .collect::>(), + ) + }); + + meta.create_gate("pad-and-add", |meta| { + let initial_state_rate = meta.query_advice(state[RATE], Rotation::prev()); + let output_state_rate = meta.query_advice(state[RATE], Rotation::next()); + + let s_pad_and_add = meta.query_selector(s_pad_and_add); + + let pad_and_add = |idx: usize| { + let initial_state = meta.query_advice(state[idx], Rotation::prev()); + let input = meta.query_advice(state[idx], Rotation::cur()); + let output_state = meta.query_advice(state[idx], Rotation::next()); + + // We pad the input by storing the required padding in fixed columns and + // then constraining the corresponding input columns to be equal to it. + initial_state + input - output_state + }; + + Constraints::with_selector( + s_pad_and_add, + (0..RATE) + .map(pad_and_add) + // The capacity element is never altered by the input. + .chain(Some(initial_state_rate - output_state_rate)) + .collect::>(), + ) + }); + + Pow5Config { + state, + partial_sbox, + rc_a, + rc_b, + s_full, + s_partial, + s_pad_and_add, + half_full_rounds, + half_partial_rounds, + alpha, + round_constants, + m_reg, + m_inv, + } + } + + /// Construct a [`Pow5Chip`]. + pub fn construct(config: Pow5Config) -> Self { + Pow5Chip { config } + } +} + +impl Chip for Pow5Chip { + type Config = Pow5Config; + type Loaded = (); + + fn config(&self) -> &Self::Config { + &self.config + } + + fn loaded(&self) -> &Self::Loaded { + &() + } +} + +impl, const WIDTH: usize, const RATE: usize> + PoseidonInstructions for Pow5Chip +{ + type Word = StateWord; + + fn permute( + &self, + layouter: &mut impl Layouter, + initial_state: &State, + ) -> Result, Error> { + let config = self.config(); + + layouter.assign_region( + || "permute state", + |mut region| { + // Load the initial state into this region. + let state = Pow5State::load(&mut region, config, initial_state)?; + + let state = (0..config.half_full_rounds) + .try_fold(state, |res, r| res.full_round(&mut region, config, r, r))?; + + let state = (0..config.half_partial_rounds).try_fold(state, |res, r| { + res.partial_round( + &mut region, + config, + config.half_full_rounds + 2 * r, + config.half_full_rounds + r, + ) + })?; + + let state = (0..config.half_full_rounds).try_fold(state, |res, r| { + res.full_round( + &mut region, + config, + config.half_full_rounds + 2 * config.half_partial_rounds + r, + config.half_full_rounds + config.half_partial_rounds + r, + ) + })?; + + Ok(state.0) + }, + ) + } +} + +impl< + F: Field, + S: Spec, + D: Domain, + const WIDTH: usize, + const RATE: usize, + > PoseidonSpongeInstructions for Pow5Chip +{ + fn initial_state( + &self, + layouter: &mut impl Layouter, + ) -> Result, Error> { + let config = self.config(); + let state = layouter.assign_region( + || format!("initial state for domain {}", D::name()), + |mut region| { + 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}"), + config.state[i], + 0, + value, + )?; + state.push(StateWord(var)); + + Ok(()) + }; + + for i in 0..RATE { + load_state_word(i, F::ZERO)?; + } + load_state_word(RATE, D::initial_capacity_element())?; + + Ok(state) + }, + )?; + + Ok(state.try_into().unwrap()) + } + + fn add_input( + &self, + layouter: &mut impl Layouter, + initial_state: &State, + input: &Absorbing, RATE>, + ) -> Result, Error> { + let config = self.config(); + layouter.assign_region( + || format!("add input for domain {}", D::name()), + |mut region| { + config.s_pad_and_add.enable(&mut region, 1)?; + + // Load the initial state into this region. + let load_state_word = |i: usize| { + initial_state[i] + .0 + .copy_advice( + || format!("load state_{i}"), + &mut region, + config.state[i], + 0, + ) + .map(StateWord) + }; + let initial_state: Result, Error> = + (0..WIDTH).map(load_state_word).collect(); + let initial_state = initial_state?; + + // Load the input into this region. + let load_input_word = |i: usize| { + 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}"), + config.rc_b[i], + 1, + || Value::known(padding_value), + )?, + _ => panic!("Input is not padded"), + }; + constraint_var + .copy_advice( + || format!("load input_{i}"), + &mut region, + config.state[i], + 1, + ) + .map(StateWord) + }; + let input: Result, Error> = (0..RATE).map(load_input_word).collect(); + let input = input?; + + // Constrain the output. + let constrain_output_word = |i: usize| { + let value = initial_state[i].0.value().copied() + + input + .get(i) + .map(|word| word.0.value().cloned()) + // The capacity element is never altered by the input. + .unwrap_or_else(|| Value::known(F::ZERO)); + region + .assign_advice(|| format!("load output_{i}"), config.state[i], 2, || value) + .map(StateWord) + }; + + let output: Result, Error> = (0..WIDTH).map(constrain_output_word).collect(); + output.map(|output| output.try_into().unwrap()) + }, + ) + } + + fn get_output(state: &State) -> Squeezing { + Squeezing( + state[..RATE] + .iter() + .map(|word| Some(word.clone())) + .collect::>() + .try_into() + .unwrap(), + ) + } +} + +/// A word in the Poseidon state. +#[derive(Clone, Debug)] +pub struct StateWord(AssignedCell); + +impl From> for AssignedCell { + fn from(state_word: StateWord) -> AssignedCell { + state_word.0 + } +} + +impl From> for StateWord { + fn from(cell_value: AssignedCell) -> StateWord { + StateWord(cell_value) + } +} + +impl Var for StateWord { + fn cell(&self) -> Cell { + self.0.cell() + } + + fn value(&self) -> Value { + self.0.value().cloned() + } +} + +#[derive(Debug)] +struct Pow5State([StateWord; WIDTH]); + +impl Pow5State { + fn full_round( + self, + region: &mut Region, + config: &Pow5Config, + round: usize, + offset: usize, + ) -> Result { + Self::round(region, config, round, offset, config.s_full, |_| { + let q = self.0.iter().enumerate().map(|(idx, word)| { + word.0 + .value() + .map(|v| *v + config.round_constants[round][idx]) + }); + let r: Value> = q.map(|q| q.map(|q| q.pow(config.alpha))).collect(); + let m = &config.m_reg; + let state = m.iter().map(|m_i| { + r.as_ref().map(|r| { + r.iter() + .enumerate() + .fold(F::ZERO, |acc, (j, r_j)| acc + m_i[j] * r_j) + }) + }); + + Ok((round + 1, state.collect::>().try_into().unwrap())) + }) + } + + fn partial_round( + self, + region: &mut Region, + config: &Pow5Config, + round: usize, + offset: usize, + ) -> Result { + Self::round(region, config, round, offset, config.s_partial, |region| { + let m = &config.m_reg; + let p: Value> = self.0.iter().map(|word| word.0.value().cloned()).collect(); + + let r: Value> = p.map(|p| { + let r_0 = (p[0] + config.round_constants[round][0]).pow(config.alpha); + let r_i = p[1..] + .iter() + .enumerate() + .map(|(i, p_i)| *p_i + config.round_constants[round][i + 1]); + std::iter::empty().chain(Some(r_0)).chain(r_i).collect() + }); + + region.assign_advice( + || format!("round_{round} partial_sbox"), + config.partial_sbox, + offset, + || r.as_ref().map(|r| r[0]), + )?; + + let p_mid: Value> = m + .iter() + .map(|m_i| { + r.as_ref().map(|r| { + m_i.iter() + .zip(r.iter()) + .fold(F::ZERO, |acc, (m_ij, r_j)| acc + *m_ij * r_j) + }) + }) + .collect(); + + // Load the second round constants. + let mut load_round_constant = |i: usize| { + region.assign_fixed( + || format!("round_{} rc_{}", round + 1, i), + config.rc_b[i], + offset, + || Value::known(config.round_constants[round + 1][i]), + ) + }; + for i in 0..WIDTH { + load_round_constant(i)?; + } + + let r_mid: Value> = p_mid.map(|p| { + let r_0 = (p[0] + config.round_constants[round + 1][0]).pow(config.alpha); + let r_i = p[1..] + .iter() + .enumerate() + .map(|(i, p_i)| *p_i + config.round_constants[round + 1][i + 1]); + std::iter::empty().chain(Some(r_0)).chain(r_i).collect() + }); + + let state: Vec> = m + .iter() + .map(|m_i| { + r_mid.as_ref().map(|r| { + m_i.iter() + .zip(r.iter()) + .fold(F::ZERO, |acc, (m_ij, r_j)| acc + *m_ij * r_j) + }) + }) + .collect(); + + Ok((round + 2, state.try_into().unwrap())) + }) + } + + fn load( + region: &mut Region, + config: &Pow5Config, + initial_state: &State, WIDTH>, + ) -> Result { + let load_state_word = |i: usize| { + initial_state[i] + .0 + .copy_advice(|| format!("load state_{i}"), region, config.state[i], 0) + .map(StateWord) + }; + + let state: Result, _> = (0..WIDTH).map(load_state_word).collect(); + state.map(|state| Pow5State(state.try_into().unwrap())) + } + + fn round( + region: &mut Region, + config: &Pow5Config, + round: usize, + offset: usize, + round_gate: Selector, + round_fn: impl FnOnce(&mut Region) -> Result<(usize, [Value; WIDTH]), Error>, + ) -> Result { + // Enable the required gate. + round_gate.enable(region, offset)?; + + // Load the round constants. + let mut load_round_constant = |i: usize| { + region.assign_fixed( + || format!("round_{round} rc_{i}"), + config.rc_a[i], + offset, + || Value::known(config.round_constants[round][i]), + ) + }; + for i in 0..WIDTH { + load_round_constant(i)?; + } + + // Compute the next round's state. + let (next_round, next_state) = round_fn(region)?; + + let next_state_word = |i: usize| { + let value = next_state[i]; + let var = region.assign_advice( + || format!("round_{next_round} state_{i}"), + config.state[i], + offset + 1, + || value, + )?; + Ok(StateWord(var)) + }; + + let next_state: Result, _> = (0..WIDTH).map(next_state_word).collect(); + next_state.map(|next_state| Pow5State(next_state.try_into().unwrap())) + } +} + +#[cfg(test)] +mod tests { + use group::ff::{Field, PrimeField}; + use halo2_proofs::{ + circuit::{Layouter, SimpleFloorPlanner, Value}, + dev::MockProver, + plonk::{Circuit, ConstraintSystem, Error}, + }; + use halo2_curves::pasta::{pallas, Fp}; + use rand::rngs::OsRng; + + use super::{PoseidonInstructions, Pow5Chip, Pow5Config, StateWord}; + use crate::frontend::halo2::poseidongadget::poseidon::{ + primitives::{self as poseidon, ConstantLength, P128Pow5T3 as OrchardNullifier, Spec}, + Hash, + }; + use std::convert::TryInto; + use std::marker::PhantomData; + + struct PermuteCircuit, const WIDTH: usize, const RATE: usize>( + PhantomData, + ); + + impl, const WIDTH: usize, const RATE: usize> Circuit + for PermuteCircuit + { + type Config = Pow5Config; + type FloorPlanner = SimpleFloorPlanner; + #[cfg(feature = "circuit-params")] + type Params = (); + + fn without_witnesses(&self) -> Self { + PermuteCircuit::(PhantomData) + } + + fn configure(meta: &mut ConstraintSystem) -> Pow5Config { + let state = (0..WIDTH).map(|_| meta.advice_column()).collect::>(); + let partial_sbox = meta.advice_column(); + + let rc_a = (0..WIDTH).map(|_| meta.fixed_column()).collect::>(); + let rc_b = (0..WIDTH).map(|_| meta.fixed_column()).collect::>(); + + Pow5Chip::configure::( + meta, + state.try_into().unwrap(), + partial_sbox, + rc_a.try_into().unwrap(), + rc_b.try_into().unwrap(), + ) + } + + fn synthesize( + &self, + config: Pow5Config, + mut layouter: impl Layouter, + ) -> Result<(), Error> { + let initial_state = layouter.assign_region( + || "prepare initial state", + |mut region| { + let state_word = |i: usize| { + let value = Value::known(Fp::from(i as u64)); + let var = region.assign_advice( + || format!("load state_{}", i), + config.state[i], + 0, + || value, + )?; + Ok(StateWord(var)) + }; + + let state: Result, Error> = (0..WIDTH).map(state_word).collect(); + Ok(state?.try_into().unwrap()) + }, + )?; + + let chip = Pow5Chip::construct(config.clone()); + let final_state = as PoseidonInstructions< + Fp, + S, + WIDTH, + RATE, + >>::permute(&chip, &mut layouter, &initial_state)?; + + // For the purpose of this test, compute the real final state inline. + let mut expected_final_state = (0..WIDTH) + .map(|idx| Fp::from(idx as u64)) + .collect::>() + .try_into() + .unwrap(); + let (round_constants, mds, _) = S::constants(); + poseidon::permute::<_, S, WIDTH, RATE>( + &mut expected_final_state, + &mds, + &round_constants, + ); + + layouter.assign_region( + || "constrain final state", + |mut region| { + let mut final_state_word = |i: usize| { + let var = region.assign_advice( + || format!("load final_state_{}", i), + config.state[i], + 0, + || Value::known(expected_final_state[i]), + )?; + region.constrain_equal(final_state[i].0.cell(), var.cell()) + }; + + for i in 0..(WIDTH) { + final_state_word(i)?; + } + + Ok(()) + }, + ) + } + } + + #[test] + fn poseidon_permute() { + let k = 6; + let circuit = PermuteCircuit::(PhantomData); + let prover = MockProver::run::<_, true>(k, &circuit, vec![]).unwrap(); + assert_eq!(prover.verify(), Ok(())) + } + + struct HashCircuit< + S: Spec, + const WIDTH: usize, + const RATE: usize, + const L: usize, + > { + message: Value<[Fp; L]>, + // For the purpose of this test, witness the result. + // TODO: Move this into an instance column. + output: Value, + _spec: PhantomData, + } + + impl, const WIDTH: usize, const RATE: usize, const L: usize> + Circuit for HashCircuit + { + type Config = Pow5Config; + type FloorPlanner = SimpleFloorPlanner; + #[cfg(feature = "circuit-params")] + type Params = (); + + fn without_witnesses(&self) -> Self { + Self { + message: Value::unknown(), + output: Value::unknown(), + _spec: PhantomData, + } + } + + fn configure(meta: &mut ConstraintSystem) -> Pow5Config { + let state = (0..WIDTH).map(|_| meta.advice_column()).collect::>(); + let partial_sbox = meta.advice_column(); + + let rc_a = (0..WIDTH).map(|_| meta.fixed_column()).collect::>(); + let rc_b = (0..WIDTH).map(|_| meta.fixed_column()).collect::>(); + + meta.enable_constant(rc_b[0]); + + Pow5Chip::configure::( + meta, + state.try_into().unwrap(), + partial_sbox, + rc_a.try_into().unwrap(), + rc_b.try_into().unwrap(), + ) + } + + fn synthesize( + &self, + config: Pow5Config, + mut layouter: impl Layouter, + ) -> Result<(), Error> { + let chip = Pow5Chip::construct(config.clone()); + + let message = layouter.assign_region( + || "load message", + |mut region| { + let message_word = |i: usize| { + let value = self.message.map(|message_vals| message_vals[i]); + region.assign_advice( + || format!("load message_{}", i), + config.state[i], + 0, + || value, + ) + }; + + let message: Result, Error> = (0..L).map(message_word).collect(); + Ok(message?.try_into().unwrap()) + }, + )?; + + let hasher = Hash::<_, _, S, ConstantLength, WIDTH, RATE>::init( + chip, + layouter.namespace(|| "init"), + )?; + let output = hasher.hash(layouter.namespace(|| "hash"), message)?; + + layouter.assign_region( + || "constrain output", + |mut region| { + let expected_var = region.assign_advice( + || "load output", + config.state[0], + 0, + || self.output, + )?; + region.constrain_equal(output.cell(), expected_var.cell()) + }, + ) + } + } + + #[test] + fn poseidon_hash() { + let rng = OsRng; + + let message = [Fp::random(rng), Fp::random(rng)]; + let output = + poseidon::Hash::<_, OrchardNullifier, ConstantLength<2>, 3, 2>::init().hash(message); + + let k = 6; + let circuit = HashCircuit:: { + message: Value::known(message), + output: Value::known(output), + _spec: PhantomData, + }; + let prover = MockProver::run::<_, true>(k, &circuit, vec![]).unwrap(); + assert_eq!(prover.verify(), Ok(())) + } + + #[test] + fn poseidon_hash_longer_input() { + let rng = OsRng; + + let message = [Fp::random(rng), Fp::random(rng), Fp::random(rng)]; + let output = + poseidon::Hash::<_, OrchardNullifier, ConstantLength<3>, 3, 2>::init().hash(message); + + let k = 7; + let circuit = HashCircuit:: { + message: Value::known(message), + output: Value::known(output), + _spec: PhantomData, + }; + let prover = MockProver::run::<_, true>(k, &circuit, vec![]).unwrap(); + assert_eq!(prover.verify(), Ok(())) + } + + #[test] + fn hash_test_vectors() { + for tv in crate::frontend::halo2::poseidongadget::poseidon::primitives::test_vectors::fp::hash() { + let message = [ + pallas::Base::from_repr(tv.input[0]).unwrap(), + pallas::Base::from_repr(tv.input[1]).unwrap(), + ]; + let output = poseidon::Hash::<_, OrchardNullifier, ConstantLength<2>, 3, 2>::init() + .hash(message); + + let k = 6; + let circuit = HashCircuit:: { + message: Value::known(message), + output: Value::known(output), + _spec: PhantomData, + }; + let prover = MockProver::run::<_, true>(k, &circuit, vec![]).unwrap(); + assert_eq!(prover.verify(), Ok(())); + } + } + + #[cfg(feature = "test-dev-graph")] + #[test] + fn print_poseidon_chip() { + use plotters::prelude::*; + + let root = BitMapBackend::new("poseidon-chip-layout.png", (1024, 768)).into_drawing_area(); + root.fill(&WHITE).unwrap(); + let root = root + .titled("Poseidon Chip Layout", ("sans-serif", 60)) + .unwrap(); + + let circuit = HashCircuit:: { + message: Value::unknown(), + output: Value::unknown(), + _spec: PhantomData, + }; + halo2_proofs::dev::CircuitLayout::default() + .render(6, &circuit, &root) + .unwrap(); + } +} diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives.rs b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives.rs new file mode 100644 index 00000000..f638feff --- /dev/null +++ b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives.rs @@ -0,0 +1,408 @@ +//! The Poseidon algebraic hash function. + +use std::convert::TryInto; +use std::fmt; +use std::iter; +use std::marker::PhantomData; + +use ff::FromUniformBytes; +use ff::PrimeField; +use halo2_proofs::arithmetic::Field; + +pub(crate) mod fp; +pub(crate) mod fq; +pub(crate) mod grain; +pub(crate) mod mds; + +#[cfg(test)] +pub(crate) mod test_vectors; + +mod p128pow5t3; +pub use p128pow5t3::P128Pow5T3; + +use grain::SboxType; + +/// The type used to hold permutation state. +pub(crate) type State = [F; T]; + +/// The type used to hold sponge rate. +pub(crate) type SpongeRate = [Option; RATE]; + +/// The type used to hold the MDS matrix and its inverse. +pub type Mds = [[F; T]; T]; + +/// A specification for a Poseidon permutation. +pub trait Spec: fmt::Debug { + /// The number of full rounds for this specification. + /// + /// This must be an even number. + fn full_rounds() -> usize; + + /// The number of partial rounds for this specification. + fn partial_rounds() -> usize; + + /// The S-box for this specification. + fn sbox(val: F) -> F; + + /// Side-loaded index of the first correct and secure MDS that will be generated by + /// the reference implementation. + /// + /// This is used by the default implementation of [`Spec::constants`]. If you are + /// hard-coding the constants, you may leave this unimplemented. + fn secure_mds() -> usize; + + /// Generates `(round_constants, mds, mds^-1)` corresponding to this specification. + fn constants() -> (Vec<[F; T]>, Mds, Mds); +} + +/// Generates `(round_constants, mds, mds^-1)` corresponding to this specification. +pub fn generate_constants< + F: FromUniformBytes<64> + Ord, + S: Spec, + const T: usize, + const RATE: usize, +>() -> (Vec<[F; T]>, Mds, Mds) { + let r_f = S::full_rounds(); + let r_p = S::partial_rounds(); + + let mut grain = grain::Grain::new(SboxType::Pow, T as u16, r_f as u16, r_p as u16); + + let round_constants = (0..(r_f + r_p)) + .map(|_| { + let mut rc_row = [F::ZERO; T]; + for (rc, value) in rc_row + .iter_mut() + .zip((0..T).map(|_| grain.next_field_element())) + { + *rc = value; + } + rc_row + }) + .collect(); + + let (mds, mds_inv) = mds::generate_mds::(&mut grain, S::secure_mds()); + + (round_constants, mds, mds_inv) +} + +/// Runs the Poseidon permutation on the given state. +pub(crate) fn permute, const T: usize, const RATE: usize>( + state: &mut State, + mds: &Mds, + round_constants: &[[F; T]], +) { + let r_f = S::full_rounds() / 2; + let r_p = S::partial_rounds(); + + let apply_mds = |state: &mut State| { + let mut new_state = [F::ZERO; T]; + // Matrix multiplication + #[allow(clippy::needless_range_loop)] + for i in 0..T { + for j in 0..T { + new_state[i] += mds[i][j] * state[j]; + } + } + *state = new_state; + }; + + let full_round = |state: &mut State, rcs: &[F; T]| { + for (word, rc) in state.iter_mut().zip(rcs.iter()) { + *word = S::sbox(*word + rc); + } + apply_mds(state); + }; + + let part_round = |state: &mut State, rcs: &[F; T]| { + for (word, rc) in state.iter_mut().zip(rcs.iter()) { + *word += rc; + } + // In a partial round, the S-box is only applied to the first state word. + state[0] = S::sbox(state[0]); + apply_mds(state); + }; + + iter::empty() + .chain(iter::repeat(&full_round as &dyn Fn(&mut State, &[F; T])).take(r_f)) + .chain(iter::repeat(&part_round as &dyn Fn(&mut State, &[F; T])).take(r_p)) + .chain(iter::repeat(&full_round as &dyn Fn(&mut State, &[F; T])).take(r_f)) + .zip(round_constants.iter()) + .fold(state, |state, (round, rcs)| { + round(state, rcs); + state + }); +} + +fn poseidon_sponge, const T: usize, const RATE: usize>( + state: &mut State, + input: Option<&Absorbing>, + mds_matrix: &Mds, + round_constants: &[[F; T]], +) -> Squeezing { + if let Some(Absorbing(input)) = input { + // `Iterator::zip` short-circuits when one iterator completes, so this will only + // mutate the rate portion of the state. + for (word, value) in state.iter_mut().zip(input.iter()) { + *word += value.expect("poseidon_sponge is called with a padded input"); + } + } + + permute::(state, mds_matrix, round_constants); + + let mut output = [None; RATE]; + for (word, value) in output.iter_mut().zip(state.iter()) { + *word = Some(*value); + } + Squeezing(output) +} + +mod private { + pub trait SealedSpongeMode {} + impl SealedSpongeMode for super::Absorbing {} + impl SealedSpongeMode for super::Squeezing {} +} + +/// The state of the `Sponge`. +pub trait SpongeMode: private::SealedSpongeMode {} + +/// The absorbing state of the `Sponge`. +#[derive(Debug, Clone)] +pub struct Absorbing(pub(crate) SpongeRate); + +/// The squeezing state of the `Sponge`. +#[derive(Debug)] +pub struct Squeezing(pub(crate) SpongeRate); + +impl SpongeMode for Absorbing {} +impl SpongeMode for Squeezing {} + +impl Absorbing { + pub(crate) fn init_with(val: F) -> Self { + Self( + iter::once(Some(val)) + .chain((1..RATE).map(|_| None)) + .collect::>() + .try_into() + .unwrap(), + ) + } +} + +#[derive(Clone)] +/// A Poseidon sponge. +pub(crate) struct Sponge< + F: Field, + S: Spec, + M: SpongeMode, + const T: usize, + const RATE: usize, +> { + mode: M, + state: State, + mds_matrix: Mds, + round_constants: Vec<[F; T]>, + _marker: PhantomData, +} + +impl, const T: usize, const RATE: usize> + Sponge, T, RATE> +{ + /// Constructs a new sponge for the given Poseidon specification. + pub(crate) fn new(initial_capacity_element: F) -> Self { + let (round_constants, mds_matrix, _) = S::constants(); + + let mode = Absorbing([None; RATE]); + let mut state = [F::ZERO; T]; + state[RATE] = initial_capacity_element; + + Sponge { + mode, + state, + mds_matrix, + round_constants, + _marker: PhantomData, + } + } + + /// Absorbs an element into the sponge. + pub(crate) fn absorb(&mut self, value: F) { + for entry in self.mode.0.iter_mut() { + if entry.is_none() { + *entry = Some(value); + return; + } + } + + // We've already absorbed as many elements as we can + let _ = poseidon_sponge::( + &mut self.state, + Some(&self.mode), + &self.mds_matrix, + &self.round_constants, + ); + self.mode = Absorbing::init_with(value); + } + + /// Transitions the sponge into its squeezing state. + pub(crate) fn finish_absorbing(mut self) -> Sponge, T, RATE> { + let mode = poseidon_sponge::( + &mut self.state, + Some(&self.mode), + &self.mds_matrix, + &self.round_constants, + ); + + Sponge { + mode, + state: self.state, + mds_matrix: self.mds_matrix, + round_constants: self.round_constants, + _marker: PhantomData, + } + } +} + +impl, const T: usize, const RATE: usize> + Sponge, T, RATE> +{ + /// Squeezes an element from the sponge. + pub(crate) fn squeeze(&mut self) -> F { + loop { + for entry in self.mode.0.iter_mut() { + if let Some(e) = entry.take() { + return e; + } + } + + // We've already squeezed out all available elements + self.mode = poseidon_sponge::( + &mut self.state, + None, + &self.mds_matrix, + &self.round_constants, + ); + } + } +} + +/// A domain in which a Poseidon hash function is being used. +pub trait Domain { + /// Iterator that outputs padding field elements. + type Padding: IntoIterator; + + /// The name of this domain, for debug formatting purposes. + fn name() -> String; + + /// The initial capacity element, encoding this domain. + fn initial_capacity_element() -> F; + + /// Returns the padding to be appended to the input. + fn padding(input_len: usize) -> Self::Padding; +} + +/// A Poseidon hash function used with constant input length. +/// +/// Domain specified in [ePrint 2019/458 section 4.2](https://eprint.iacr.org/2019/458.pdf). +#[derive(Clone, Copy, Debug)] +pub struct ConstantLength; + +impl Domain for ConstantLength { + type Padding = iter::Take>; + + fn name() -> String { + format!("ConstantLength<{L}>") + } + + fn initial_capacity_element() -> F { + // Capacity value is $length \cdot 2^64 + (o-1)$ where o is the output length. + // We hard-code an output length of 1. + F::from_u128((L as u128) << 64) + } + + fn padding(input_len: usize) -> Self::Padding { + assert_eq!(input_len, L); + // For constant-input-length hashing, we pad the input with zeroes to a multiple + // of RATE. On its own this would not be sponge-compliant padding, but the + // Poseidon authors encode the constant length into the capacity element, ensuring + // that inputs of different lengths do not share the same permutation. + let k = (L + RATE - 1) / RATE; + iter::repeat(F::ZERO).take(k * RATE - L) + } +} + +#[derive(Clone)] +/// A Poseidon hash function, built around a sponge. +pub struct Hash< + F: Field, + S: Spec, + D: Domain, + const T: usize, + const RATE: usize, +> { + sponge: Sponge, T, RATE>, + _domain: PhantomData, +} + +impl, D: Domain, const T: usize, const RATE: usize> + fmt::Debug for Hash +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Hash") + .field("width", &T) + .field("rate", &RATE) + .field("R_F", &S::full_rounds()) + .field("R_P", &S::partial_rounds()) + .field("domain", &D::name()) + .finish() + } +} + +impl, D: Domain, const T: usize, const RATE: usize> + Hash +{ + /// Initializes a new hasher. + pub fn init() -> Self { + Hash { + sponge: Sponge::new(D::initial_capacity_element()), + _domain: PhantomData, + } + } +} + +impl, const T: usize, const RATE: usize, const L: usize> + Hash, T, RATE> +{ + /// Hashes the given input. + pub fn hash(mut self, message: [F; L]) -> F { + for value in message + .into_iter() + .chain( as Domain>::padding(L)) + { + self.sponge.absorb(value); + } + self.sponge.finish_absorbing().squeeze() + } +} + +#[cfg(test)] +mod tests { + use super::{permute, ConstantLength, Hash, P128Pow5T3 as OrchardNullifier, Spec}; + use ff::PrimeField; + use halo2_curves::pasta::pallas; + + #[test] + fn orchard_spec_equivalence() { + let message = [pallas::Base::from(6), pallas::Base::from(42)]; + + let (round_constants, mds, _) = OrchardNullifier::constants(); + + let hasher = Hash::<_, OrchardNullifier, ConstantLength<2>, 3, 2>::init(); + let result = hasher.hash(message); + + // The result should be equivalent to just directly applying the permutation and + // taking the first state element as the output. + let mut state = [message[0], message[1], pallas::Base::from_u128(2 << 64)]; + permute::<_, OrchardNullifier, 3, 2>(&mut state, &mds, &round_constants); + assert_eq!(state[0], result); + } +} diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/fp.rs b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/fp.rs new file mode 100644 index 00000000..1bda4a9c --- /dev/null +++ b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/fp.rs @@ -0,0 +1,1431 @@ +//! Constants for using Poseidon with the Pallas field. +//! +//! The constants can be reproduced by running the following Sage script from +//! [this repository](https://github.com/daira/pasta-hadeshash): +//! +//! ```text +//! $ sage generate_parameters_grain.sage 1 0 255 3 8 56 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001 +//! ``` +use halo2_curves::pasta::pallas; + +// Number of round constants: 192 +// Round constants for GF(p): +pub(crate) const ROUND_CONSTANTS: [[pallas::Base; 3]; 64] = [ + [ + pallas::Base::from_raw([ + 0x5753_8c25_9642_6303, + 0x4e71_162f_3100_3b70, + 0x353f_628f_76d1_10f3, + 0x360d_7470_611e_473d, + ]), + pallas::Base::from_raw([ + 0xbdb7_4213_bf63_188b, + 0x4908_ac2f_12eb_e06f, + 0x5dc3_c6c5_febf_aa31, + 0x2bab_94d7_ae22_2d13, + ]), + pallas::Base::from_raw([ + 0x0939_d927_53cc_5dc8, + 0xef77_e7d7_3676_6c5d, + 0x2bf0_3e1a_29aa_871f, + 0x150c_93fe_f652_fb1c, + ]), + ], + [ + pallas::Base::from_raw([ + 0x1425_9dce_5377_82b2, + 0x03cc_0a60_141e_894e, + 0x955d_55db_56dc_57c1, + 0x3270_661e_6892_8b3a, + ]), + pallas::Base::from_raw([ + 0xce9f_b9ff_c345_afb3, + 0xb407_c370_f2b5_a1cc, + 0xa0b7_afe4_e205_7299, + 0x073f_116f_0412_2e25, + ]), + pallas::Base::from_raw([ + 0x8eba_d76f_c715_54d8, + 0x55c9_cd20_61ae_93ca, + 0x7aff_d09c_1f53_f5fd, + 0x2a32_ec5c_4ee5_b183, + ]), + ], + [ + pallas::Base::from_raw([ + 0x2d8c_cbe2_92ef_eead, + 0x634d_24fc_6e25_59f2, + 0x651e_2cfc_7406_28ca, + 0x2703_26ee_039d_f19e, + ]), + pallas::Base::from_raw([ + 0xa068_fc37_c182_e274, + 0x8af8_95bc_e012_f182, + 0xdc10_0fe7_fcfa_5491, + 0x27c6_642a_c633_bc66, + ]), + pallas::Base::from_raw([ + 0x9ca1_8682_e26d_7ff9, + 0x710e_1fb6_ab97_6a45, + 0xd27f_5739_6989_129d, + 0x1bdf_d8b0_1401_c70a, + ]), + ], + [ + pallas::Base::from_raw([ + 0xc832_d824_261a_35ea, + 0xf4f6_fb3f_9054_d373, + 0x14b9_d6a9_c84d_d678, + 0x162a_14c6_2f9a_89b8, + ]), + pallas::Base::from_raw([ + 0xf798_2466_7b5b_6bec, + 0xac0a_1fc7_1e2c_f0c0, + 0x2af6_f79e_3127_feea, + 0x2d19_3e0f_76de_586b, + ]), + pallas::Base::from_raw([ + 0x5d0b_f58d_c8a4_aa94, + 0x4fef_f829_8499_0ff8, + 0x8169_6ef1_104e_674f, + 0x044c_a3cc_4a85_d73b, + ]), + ], + [ + pallas::Base::from_raw([ + 0x6198_785f_0cd6_b9af, + 0xb8d9_e2d4_f314_f46f, + 0x1d04_5341_6d3e_235c, + 0x1cba_f2b3_71da_c6a8, + ]), + pallas::Base::from_raw([ + 0x343e_0761_0f3f_ede5, + 0x293c_4ab0_38fd_bbdc, + 0x0e6c_49d0_61b6_b5f4, + 0x1d5b_2777_692c_205b, + ]), + pallas::Base::from_raw([ + 0xf60e_971b_8d73_b04f, + 0x06a9_adb0_c1e6_f962, + 0xaa30_535b_dd74_9a7e, + 0x2e9b_dbba_3dd3_4bff, + ]), + ], + [ + pallas::Base::from_raw([ + 0x035a_1366_1f22_418b, + 0xde40_fbe2_6d04_7b05, + 0x8bd5_bae3_6969_299f, + 0x2de1_1886_b180_11ca, + ]), + pallas::Base::from_raw([ + 0xbc99_8884_ba96_a721, + 0x2ab9_395c_449b_e947, + 0x0d5b_4a3f_1841_dcd8, + 0x2e07_de17_80b8_a70d, + ]), + pallas::Base::from_raw([ + 0x825e_4c2b_b749_25ca, + 0x2504_40a9_9d6b_8af3, + 0xbbdb_63db_d52d_ad16, + 0x0f69_f185_4d20_ca0c, + ]), + ], + [ + pallas::Base::from_raw([ + 0x816c_0594_22dc_705e, + 0x6ce5_1135_07f9_6de9, + 0x0d13_5dc6_39fb_09a4, + 0x2eb1_b254_17fe_1767, + ]), + pallas::Base::from_raw([ + 0xb8b1_bdf4_953b_d82c, + 0xff36_c661_d26c_c42d, + 0x8c24_cb44_c3fa_b48a, + 0x115c_d0a0_643c_fb98, + ]), + pallas::Base::from_raw([ + 0xde80_1612_311d_04cd, + 0xbb57_ddf1_4e0f_958a, + 0x066d_7378_b999_868b, + 0x26ca_293f_7b2c_462d, + ]), + ], + [ + pallas::Base::from_raw([ + 0xf520_9d14_b248_20ca, + 0x0f16_0bf9_f71e_967f, + 0x2a83_0aa1_6241_2cd9, + 0x17bf_1b93_c4c7_e01a, + ]), + pallas::Base::from_raw([ + 0x05c8_6f2e_7dc2_93c5, + 0xe03c_0354_bd8c_fd38, + 0xa24f_8456_369c_85df, + 0x35b4_1a7a_c4f3_c571, + ]), + pallas::Base::from_raw([ + 0x72ac_156a_f435_d09e, + 0x64e1_4d3b_eb2d_ddde, + 0x4359_2799_4849_bea9, + 0x3b14_8008_0523_c439, + ]), + ], + [ + pallas::Base::from_raw([ + 0x2716_18d8_74b1_4c6d, + 0x08e2_8644_2a2d_3eb2, + 0x4950_856d_c907_d575, + 0x2cc6_8100_31dc_1b0d, + ]), + pallas::Base::from_raw([ + 0x91f3_18c0_9f0c_b566, + 0x9e51_7aa9_3b78_341d, + 0x0596_18e2_afd2_ef99, + 0x25bd_bbed_a1bd_e8c1, + ]), + pallas::Base::from_raw([ + 0xc631_3487_073f_7f7b, + 0x2a5e_d0a2_7b61_926c, + 0xb95f_33c2_5dde_8ac0, + 0x392a_4a87_58e0_6ee8, + ]), + ], + [ + pallas::Base::from_raw([ + 0xe7bb_cef0_2eb5_866c, + 0x5e6a_6fd1_5db8_9365, + 0x9aa6_111f_4de0_0948, + 0x272a_5587_8a08_442b, + ]), + pallas::Base::from_raw([ + 0x9b92_5b3c_5b21_e0e2, + 0xa6eb_ba01_1694_dd12, + 0xefa1_3c4e_60e2_6239, + 0x2d5b_308b_0cf0_2cdf, + ]), + pallas::Base::from_raw([ + 0xef38_c57c_3116_73ac, + 0x44df_f42f_18b4_6c56, + 0xdd5d_293d_72e2_e5f2, + 0x1654_9fc6_af2f_3b72, + ]), + ], + [ + pallas::Base::from_raw([ + 0x9b71_26d9_b468_60df, + 0x7639_8265_3442_0311, + 0xfa69_c3a2_ad52_f76d, + 0x1b10_bb7a_82af_ce39, + ]), + pallas::Base::from_raw([ + 0x90d2_7f6a_00b7_dfc8, + 0xd1b3_6968_ba04_05c0, + 0xc79c_2df7_dc98_a3be, + 0x0f1e_7505_ebd9_1d2f, + ]), + pallas::Base::from_raw([ + 0xff45_7756_b819_bb20, + 0x797f_d6e3_f18e_b1ca, + 0x537a_7497_a3b4_3f46, + 0x2f31_3faf_0d3f_6187, + ]), + ], + [ + pallas::Base::from_raw([ + 0xf0bc_3e73_2ecb_26f6, + 0x5cad_11eb_f0f7_ceb8, + 0xfa3c_a61c_0ed1_5bc5, + 0x3a5c_bb6d_e450_b481, + ]), + pallas::Base::from_raw([ + 0x8655_27cb_ca91_5982, + 0x51ba_a6e2_0f89_2b62, + 0xd920_86e2_53b4_39d6, + 0x3dab_54bc_9bef_688d, + ]), + pallas::Base::from_raw([ + 0x3680_45ac_f2b7_1ae3, + 0x4c24_b33b_410f_efd4, + 0xe280_d316_7012_3f74, + 0x06db_fb42_b979_884d, + ]), + ], + [ + pallas::Base::from_raw([ + 0xa7fc_32d2_2f18_b9d3, + 0xb8d2_de72_e3d2_c9ec, + 0xc6f0_39ea_1973_a63e, + 0x068d_6b46_08aa_e810, + ]), + pallas::Base::from_raw([ + 0x2b5d_fcc5_5725_55df, + 0xb868_a7d7_e1f1_f69a, + 0x0ee2_58c9_b8fd_fccd, + 0x366e_bfaf_a3ad_381c, + ]), + pallas::Base::from_raw([ + 0xe6bc_229e_95bc_76b1, + 0x7ef6_6d89_d044_d022, + 0x04db_3024_f41d_3f56, + 0x3967_8f65_512f_1ee4, + ]), + ], + [ + pallas::Base::from_raw([ + 0xe534_c88f_e53d_85fe, + 0xcf82_c25f_99dc_01a4, + 0xd58b_7750_a3bc_2fe1, + 0x2166_8f01_6a80_63c0, + ]), + pallas::Base::from_raw([ + 0x4bef_429b_c533_1608, + 0xe34d_ea56_439f_e195, + 0x1bc7_4936_3e98_a768, + 0x39d0_0994_a8a5_046a, + ]), + pallas::Base::from_raw([ + 0x770c_956f_60d8_81b3, + 0xb163_d416_05d3_9f99, + 0x6b20_3bbe_12fb_3425, + 0x1f9d_bdc3_f843_1263, + ]), + ], + [ + pallas::Base::from_raw([ + 0x9794_a9f7_c336_eab2, + 0xbe0b_c829_fe5e_66c6, + 0xe5f1_7b9e_0ee0_cab6, + 0x0277_45a9_cddf_ad95, + ]), + pallas::Base::from_raw([ + 0x5202_5657_abd8_aee0, + 0x2fa4_3fe2_0a45_c78d, + 0x788d_695c_61e9_3212, + 0x1cec_0803_c504_b635, + ]), + pallas::Base::from_raw([ + 0xd387_2a95_59a0_3a73, + 0xed50_82c8_dbf3_1365, + 0x7207_7448_ef87_cc6e, + 0x1235_23d7_5e9f_abc1, + ]), + ], + [ + pallas::Base::from_raw([ + 0x0017_79e3_a1d3_57f4, + 0x27fe_ba35_975e_e7e5, + 0xf419_b848_e5d6_94bf, + 0x1723_d145_2c9c_f02d, + ]), + pallas::Base::from_raw([ + 0x9dab_1ee4_dcf9_6622, + 0x21c3_f776_f572_836d, + 0xfcc0_573d_7e61_3694, + 0x1739_d180_a160_10bd, + ]), + pallas::Base::from_raw([ + 0x7029_0452_042d_048d, + 0xfafa_96fb_eb0a_b893, + 0xacce_3239_1794_b627, + 0x2d4e_6354_da9c_c554, + ]), + ], + [ + pallas::Base::from_raw([ + 0x670b_cf6f_8b48_5dcd, + 0x8f3b_d43f_9926_0621, + 0x4a86_9553_c9d0_07f8, + 0x153e_e614_2e53_5e33, + ]), + pallas::Base::from_raw([ + 0xd258_d2e2_b778_2172, + 0x968a_d442_4af8_3700, + 0x635e_f7e7_a430_b486, + 0x0c45_bfd3_a69a_aa65, + ]), + pallas::Base::from_raw([ + 0x0e56_33d2_51f7_3307, + 0x6897_ac0a_8ffa_5ff1, + 0xf2d5_6aec_8314_4600, + 0x0adf_d53b_256a_6957, + ]), + ], + [ + pallas::Base::from_raw([ + 0xac9d_36a8_b751_6d63, + 0x3f87_b28f_1c1b_e4bd, + 0x8cd1_726b_7cba_b8ee, + 0x315d_2ac8_ebdb_ac3c, + ]), + pallas::Base::from_raw([ + 0x299c_e44e_a423_d8e1, + 0xc9bb_60d1_f695_9879, + 0xcfae_c23d_2b16_883f, + 0x1b84_7271_2d02_eef4, + ]), + pallas::Base::from_raw([ + 0xc4a5_4041_98ad_f70c, + 0x367d_2c54_e369_28c9, + 0xbd0b_70fa_2255_eb6f, + 0x3c1c_d07e_fda6_ff24, + ]), + ], + [ + pallas::Base::from_raw([ + 0xbbe5_23ae_f9ab_107a, + 0x4a16_073f_738f_7e0c, + 0x687f_4e51_b2e1_dcd3, + 0x1360_52d2_6bb3_d373, + ]), + pallas::Base::from_raw([ + 0x676c_36c2_4ef9_67dd, + 0x7b3c_fbb8_7303_2681, + 0xc1bd_d859_a123_2a1d, + 0x16c9_6bee_f6a0_a848, + ]), + pallas::Base::from_raw([ + 0x067e_ec7f_2d63_40c4, + 0x0123_87ba_b4f1_662d, + 0x2ab7_fed8_f499_a9fb, + 0x284b_38c5_7ff6_5c26, + ]), + ], + [ + pallas::Base::from_raw([ + 0xaf1d_ff20_4c92_2f86, + 0xfc06_772c_1c04_11a6, + 0x39e2_4219_8897_d17c, + 0x0c59_93d1_75e8_1f66, + ]), + pallas::Base::from_raw([ + 0xbbf5_3f67_b1f8_7b15, + 0xf248_87ad_48e1_7759, + 0xfcda_655d_1ba9_c8f9, + 0x03bf_7a3f_7bd0_43da, + ]), + pallas::Base::from_raw([ + 0x9b5c_d09e_36d8_be62, + 0x4c8f_9cbe_69f0_e827, + 0xb0cf_9995_67f0_0e73, + 0x3188_fe4e_e9f9_fafb, + ]), + ], + [ + pallas::Base::from_raw([ + 0xafea_99a2_ec6c_595a, + 0x3af5_bf77_c1c4_2652, + 0x5a39_768c_480d_61e1, + 0x171f_528c_cf65_8437, + ]), + pallas::Base::from_raw([ + 0x5a05_63b9_b8e9_f1d5, + 0x812c_3286_ee70_0067, + 0x196e_4185_9b35_ef88, + 0x12f4_175c_4ab4_5afc, + ]), + pallas::Base::from_raw([ + 0x0e74_d4d3_6911_8b79, + 0x7e23_e1aa_be96_cfab, + 0x8f8f_dcf8_00a9_ac69, + 0x3a50_9e15_5cb7_ebfd, + ]), + ], + [ + pallas::Base::from_raw([ + 0x9871_2c65_678c_fd30, + 0x984b_c8f2_e4c1_b69e, + 0x1a89_920e_2504_c3b3, + 0x10f2_a685_df4a_27c8, + ]), + pallas::Base::from_raw([ + 0xe8a1_6728_cc9d_4918, + 0x5457_3c93_33c5_6321, + 0x1d8d_93d5_4ab9_1a0e, + 0x09e5_f497_90c8_a0e2, + ]), + pallas::Base::from_raw([ + 0x609a_7403_47cf_5fea, + 0x42d1_7ed6_ee0f_ab7e, + 0x2bf3_5705_d9f8_4a34, + 0x352d_69be_d80e_e3e5, + ]), + ], + [ + pallas::Base::from_raw([ + 0x3a75_8af6_fa84_e0e8, + 0xc634_debd_281b_76a6, + 0x4915_62fa_f2b1_90d3, + 0x058e_e73b_a9f3_f293, + ]), + pallas::Base::from_raw([ + 0x621a_1325_10a4_3904, + 0x092c_b921_19bc_76be, + 0xcd0f_1fc5_5b1a_3250, + 0x232f_99cc_911e_ddd9, + ]), + pallas::Base::from_raw([ + 0xc3b9_7c1e_301b_c213, + 0xf9ef_d52c_a6bc_2961, + 0x86c2_2c6c_5d48_69f0, + 0x201b_eed7_b8f3_ab81, + ]), + ], + [ + pallas::Base::from_raw([ + 0xbf6b_3431_ba94_e9bc, + 0x2938_8842_744a_1210, + 0xa1c9_291d_5860_2f51, + 0x1376_dce6_5800_30c6, + ]), + pallas::Base::from_raw([ + 0x6454_843c_5486_d7b3, + 0x072b_a8b0_2d92_e722, + 0x2b33_56c3_8238_f761, + 0x1793_199e_6fd6_ba34, + ]), + pallas::Base::from_raw([ + 0x06a3_f1d3_b433_311b, + 0x3c66_160d_c62a_acac, + 0x9fee_9c20_c87a_67df, + 0x22de_7a74_88dc_c735, + ]), + ], + [ + pallas::Base::from_raw([ + 0x30d6_e3fd_516b_47a8, + 0xdbe0_b77f_ae77_e1d0, + 0xdf8f_f37f_e2d8_edf8, + 0x3514_d5e9_066b_b160, + ]), + pallas::Base::from_raw([ + 0x1937_7427_137a_81c7, + 0xff45_3d6f_900f_144a, + 0xf919_a00d_abbf_5fa5, + 0x30cd_3006_931a_d636, + ]), + pallas::Base::from_raw([ + 0x5b6a_7422_0692_b506, + 0x8f9e_4b2c_ae2e_bb51, + 0x41f8_1a5c_f613_c8df, + 0x253d_1a5c_5293_4127, + ]), + ], + [ + pallas::Base::from_raw([ + 0x73f6_66cb_86a4_8e8e, + 0x851b_3a59_c990_fafc, + 0xa35e_9613_e7f5_fe92, + 0x035b_461c_02d7_9d19, + ]), + pallas::Base::from_raw([ + 0x7cfb_f86a_3aa0_4780, + 0x92b1_283c_2d5f_ccde, + 0x5bc0_0eed_d56b_93e0, + 0x23a9_9280_79d1_75bd, + ]), + pallas::Base::from_raw([ + 0xf1e4_ccd7_3fa0_0a82, + 0xb5e2_ea34_36ee_f957, + 0xf159_4a07_63c6_11ab, + 0x13a7_785a_e134_ea92, + ]), + ], + [ + pallas::Base::from_raw([ + 0xbbf0_4f52_52de_4279, + 0x3889_c578_6344_6d88, + 0x4962_ae3c_0da1_7e31, + 0x39fc_e308_b7d4_3c57, + ]), + pallas::Base::from_raw([ + 0x3b57_e344_89b5_3fad, + 0xbef0_0a08_c6ed_38d2, + 0xc0fd_f016_62f6_0d22, + 0x1aae_1883_3f8e_1d3a, + ]), + pallas::Base::from_raw([ + 0x5551_3e03_3398_513f, + 0x27c1_b3fd_8f85_d8a8, + 0x8b2e_80c0_64fd_83ed, + 0x1a76_1ce8_2400_af01, + ]), + ], + [ + pallas::Base::from_raw([ + 0x5244_ca74_9b73_e481, + 0xdcf6_af28_30a5_0287, + 0x16dd_1a87_ca22_e1cc, + 0x275a_03e4_5add_a7c3, + ]), + pallas::Base::from_raw([ + 0x58a2_53cf_b6a9_5786, + 0x07e5_6145_3fc5_648b, + 0xeb08_e47e_5fea_bcf8, + 0x2e5a_10f0_8b5a_b8bb, + ]), + pallas::Base::from_raw([ + 0xe033_d82c_efe7_8ce3, + 0xc141_a5b6_d594_bec4, + 0xb84e_9c33_3b29_32f1, + 0x1459_cb85_8720_8473, + ]), + ], + [ + pallas::Base::from_raw([ + 0x5cec_7e7b_338f_be1b, + 0x52f9_332f_bffc_fbbd, + 0x7b92_ce81_0e14_a400, + 0x193a_e592_1d78_b5de, + ]), + pallas::Base::from_raw([ + 0x6022_4be6_7248_e82c, + 0x3743_84f4_a072_8205, + 0x8911_1fb2_c466_0281, + 0x3097_898a_5d00_11a4, + ]), + pallas::Base::from_raw([ + 0x5499_80de_8629_30f5, + 0x1979_b2d1_c465_b4d9, + 0x5717_82fd_96ce_54b4, + 0x378d_97bf_8c86_4ae7, + ]), + ], + [ + pallas::Base::from_raw([ + 0x37ea_32a9_71d1_7884, + 0xdbc7_f5cb_4609_3421, + 0x8813_6287_ce37_6b08, + 0x2eb0_4ea7_c01d_97ec, + ]), + pallas::Base::from_raw([ + 0xead3_726f_1af2_e7b0, + 0x861c_bda4_7680_4e6c, + 0x2302_a1c2_2e49_baec, + 0x3642_5347_ea03_f641, + ]), + pallas::Base::from_raw([ + 0xecd6_27e5_9590_d09e, + 0x3f5b_5ca5_a19a_9701, + 0xcc99_6cd8_5c98_a1d8, + 0x26b7_2df4_7408_ad42, + ]), + ], + [ + pallas::Base::from_raw([ + 0x59be_ce31_f0a3_1e95, + 0xde01_212e_e458_8f89, + 0x1f05_636c_610b_89aa, + 0x1301_80e4_4e29_24db, + ]), + pallas::Base::from_raw([ + 0x9ea8_e7bc_7926_3550, + 0xdf77_93cc_89e5_b52f, + 0x7327_5aca_ed5f_579c, + 0x219e_9773_7d39_79ba, + ]), + pallas::Base::from_raw([ + 0x9c12_635d_f251_d153, + 0x3b06_72dd_7d42_cbb4, + 0x3461_363f_81c4_89a2, + 0x3cdb_9359_8a5c_a528, + ]), + ], + [ + pallas::Base::from_raw([ + 0x2861_ce16_f219_d5a9, + 0x4ad0_4470_45a7_c5aa, + 0x2072_4b92_7a0c_a81c, + 0x0e59_e6f3_32d7_ed37, + ]), + pallas::Base::from_raw([ + 0x43b0_a3fc_ff20_36bd, + 0x172c_c07b_9d33_fbf9, + 0x3d73_6946_7222_697a, + 0x1b06_4342_d51a_4275, + ]), + pallas::Base::from_raw([ + 0x3eb3_1022_8a0e_5f6c, + 0x78fa_9fb9_1712_21b7, + 0x2f36_3c55_b288_2e0b, + 0x30b8_2a99_8cbd_8e8a, + ]), + ], + [ + pallas::Base::from_raw([ + 0xe46f_6d42_9874_0107, + 0x8ad7_1ea7_15be_0573, + 0x63df_7a76_e858_a4aa, + 0x23e4_ab37_183a_cba4, + ]), + pallas::Base::from_raw([ + 0xfca9_95e2_b599_14a1, + 0xacfe_1464_0de0_44f2, + 0x5d33_094e_0bed_a75b, + 0x2795_d5c5_fa42_8022, + ]), + pallas::Base::from_raw([ + 0xc26d_909d_ee8b_53c0, + 0xa668_7c3d_f16c_8fe4, + 0xd765_f26d_d03f_4c45, + 0x3001_ca40_1e89_601c, + ]), + ], + [ + pallas::Base::from_raw([ + 0xe7fe_a6bd_f347_1380, + 0xe84b_5beb_ae4e_501d, + 0xf7bf_86e8_9280_827f, + 0x0072_e45c_c676_b08e, + ]), + pallas::Base::from_raw([ + 0xd0c5_4dde_b26b_86c0, + 0xb648_29e2_d40e_41bd, + 0xe2ab_e4c5_18ce_599e, + 0x13de_7054_8487_4bb5, + ]), + pallas::Base::from_raw([ + 0x3891_5b43_2a99_59a5, + 0x82bb_18e5_af1b_05bb, + 0x3159_50f1_211d_efe8, + 0x0408_a9fc_f9d6_1abf, + ]), + ], + [ + pallas::Base::from_raw([ + 0x3407_0cbe_e268_86a0, + 0xae4d_23b0_b41b_e9a8, + 0xbb4e_4a14_00cc_d2c4, + 0x2780_b9e7_5b55_676e, + ]), + pallas::Base::from_raw([ + 0x9405_5920_98b4_056f, + 0xdc4d_8fbe_fe24_405a, + 0xf803_33ec_8563_4ac9, + 0x3a57_0d4d_7c4e_7ac3, + ]), + pallas::Base::from_raw([ + 0x78d2_b247_8995_20b4, + 0xe2cc_1507_bebd_cc62, + 0xf347_c247_fcf0_9294, + 0x0c13_cca7_cb1f_9d2c, + ]), + ], + [ + pallas::Base::from_raw([ + 0x2e8c_88f7_7074_70e0, + 0x0b50_bb2e_b82d_f74d, + 0xd261_4a19_7c6b_794b, + 0x14f5_9baa_03cd_0ca4, + ]), + pallas::Base::from_raw([ + 0xbe52_476e_0a16_f3be, + 0xa51d_54ed_e661_67f5, + 0x6f54_6e17_04c3_9c60, + 0x307d_efee_925d_fb43, + ]), + pallas::Base::from_raw([ + 0x380b_67d8_0473_dce3, + 0x6611_0683_6adf_e5e7, + 0x7a07_e767_4b5a_2621, + 0x1960_cd51_1a91_e060, + ]), + ], + [ + pallas::Base::from_raw([ + 0x15aa_f1f7_7125_89dd, + 0xb8ee_335d_8828_4cbe, + 0xca2a_d0fb_5667_2500, + 0x2301_ef9c_63ea_84c5, + ]), + pallas::Base::from_raw([ + 0x5e68_478c_4d60_27a9, + 0xc861_82d1_b424_6b58, + 0xd10f_4cd5_2be9_7f6b, + 0x029a_5a47_da79_a488, + ]), + pallas::Base::from_raw([ + 0x2cc4_f962_eaae_2260, + 0xf97f_e46b_6a92_5428, + 0x2360_d17d_890e_55cb, + 0x32d7_b16a_7f11_cc96, + ]), + ], + [ + pallas::Base::from_raw([ + 0xc0ca_b915_d536_3d9f, + 0xa5f2_404c_d7b3_5eb0, + 0x18e8_57a9_8d49_8cf7, + 0x2670_3e48_c03b_81ca, + ]), + pallas::Base::from_raw([ + 0xf691_123a_e112_b928, + 0xf443_88bd_6b89_221e, + 0x88ac_8d25_a246_03f1, + 0x0486_82a3_5b32_65bc, + ]), + pallas::Base::from_raw([ + 0x3ab7_defc_b8d8_03e2, + 0x91d6_e171_5164_775e, + 0xd72c_ddc6_cf06_b507, + 0x06b1_3904_41fa_7030, + ]), + ], + [ + pallas::Base::from_raw([ + 0xbcd7_9541_4a6e_2e86, + 0x43b3_60f6_386a_86d7, + 0x1689_426d_ce05_fcd8, + 0x31aa_0eeb_868c_626d, + ]), + pallas::Base::from_raw([ + 0xed77_f5d5_76b9_9cc3, + 0x90ef_d8f4_1b20_78b2, + 0x057a_bad3_764c_104b, + 0x2394_64f7_5bf7_b6af, + ]), + pallas::Base::from_raw([ + 0xb2cb_4873_07c1_cecf, + 0xa5cc_47c5_9654_b2a7, + 0xa45e_19ed_813a_54ab, + 0x0a64_d4c0_4fd4_26bd, + ]), + ], + [ + pallas::Base::from_raw([ + 0x1f73_1532_2f65_8735, + 0x777c_7a92_1a06_2e9d, + 0x576a_4ad2_5986_0fb1, + 0x21fb_bdbb_7367_0734, + ]), + pallas::Base::from_raw([ + 0x6743_2400_3fc5_2146, + 0x5b86_d294_63d3_1564, + 0xd937_1ca2_eb95_acf3, + 0x31b8_6f3c_f017_05d4, + ]), + pallas::Base::from_raw([ + 0x7045_f48a_a4eb_4f6f, + 0x1354_1d65_157e_e1ce, + 0x05ef_1736_d090_56f6, + 0x2bfd_e533_5437_7c91, + ]), + ], + [ + pallas::Base::from_raw([ + 0x5a13_a58d_2001_1e2f, + 0xf4d5_239c_11d0_eafa, + 0xd558_f36e_65f8_eca7, + 0x1233_ca93_6ec2_4671, + ]), + pallas::Base::from_raw([ + 0x6e70_af0a_7a92_4b3a, + 0x8780_58d0_234a_576f, + 0xc437_846d_8e0b_2b30, + 0x27d4_52a4_3ac7_dea2, + ]), + pallas::Base::from_raw([ + 0xa025_76b9_4392_f980, + 0x6a30_641a_1c3d_87b2, + 0xe816_ea8d_a493_e0fa, + 0x2699_dba8_2184_e413, + ]), + ], + [ + pallas::Base::from_raw([ + 0x608c_6f7a_61b5_6e55, + 0xf185_8466_4f8c_ab49, + 0xc398_8bae_e42e_4b10, + 0x36c7_22f0_efcc_8803, + ]), + pallas::Base::from_raw([ + 0x6e49_ac17_0dbb_7fcd, + 0x85c3_8899_a7b5_a833, + 0x08b0_f2ec_89cc_aa37, + 0x02b3_ff48_861e_339b, + ]), + pallas::Base::from_raw([ + 0xa8c5_ae03_ad98_e405, + 0x6fc3_ff4c_49eb_59ad, + 0x6016_2f44_27bc_657b, + 0x0b70_d061_d58d_8a7f, + ]), + ], + [ + pallas::Base::from_raw([ + 0x2e06_cc4a_f33b_0a06, + 0xad3d_e8be_46ed_9693, + 0xf875_3ade_b9d7_cee2, + 0x3fc2_a13f_127f_96a4, + ]), + pallas::Base::from_raw([ + 0xc120_80ac_117e_e15f, + 0x00cb_3d62_1e17_1d80, + 0x1bd6_3434_ac8c_419f, + 0x0c41_a6e4_8dd2_3a51, + ]), + pallas::Base::from_raw([ + 0x9685_213e_9692_f5e1, + 0x72aa_ad7e_4e75_339d, + 0xed44_7653_7169_084e, + 0x2de8_072a_6bd8_6884, + ]), + ], + [ + pallas::Base::from_raw([ + 0x0ad0_1184_567b_027c, + 0xb81c_f735_cc9c_39c0, + 0x9d34_96a3_d9fe_05ec, + 0x0355_7a8f_7b38_a17f, + ]), + pallas::Base::from_raw([ + 0x45bc_b5ac_0082_6abc, + 0x060f_4336_3d81_8e54, + 0xee97_6d34_282f_1a37, + 0x0b5f_5955_2f49_8735, + ]), + pallas::Base::from_raw([ + 0x2f29_09e1_7e22_b0df, + 0xf5d6_46e5_7507_e548, + 0xfedb_b185_70dc_7300, + 0x0e29_23a5_fee7_b878, + ]), + ], + [ + pallas::Base::from_raw([ + 0xf71e_ed73_f15b_3326, + 0xcf1c_b37c_3b03_2af6, + 0xc787_be97_020a_7fdd, + 0x1d78_5005_a7a0_0592, + ]), + pallas::Base::from_raw([ + 0x0acf_bfb2_23f8_f00d, + 0xa590_b88a_3b06_0294, + 0x0ba5_fedc_b8f2_5bd2, + 0x1ad7_72c2_73d9_c6df, + ]), + pallas::Base::from_raw([ + 0xc1ce_13d6_0f2f_5031, + 0x8105_10eb_61f0_672d, + 0xa78f_3275_c278_234b, + 0x027b_d647_85fc_bd2a, + ]), + ], + [ + pallas::Base::from_raw([ + 0x8337_f5e0_7923_a853, + 0xe224_3134_6945_7b8e, + 0xce6f_8ffe_a103_1b6d, + 0x2080_0f44_1b4a_0526, + ]), + pallas::Base::from_raw([ + 0xa33d_7bed_89a4_408a, + 0x36cd_c8ee_d662_ad37, + 0x6eea_2cd4_9f43_12b4, + 0x3d5a_d61d_7b65_f938, + ]), + pallas::Base::from_raw([ + 0x3bbb_ae94_cc19_5284, + 0x1df9_6cc0_3ea4_b26d, + 0x02c5_f91b_e4dd_8e3d, + 0x1333_8bc3_51fc_46dd, + ]), + ], + [ + pallas::Base::from_raw([ + 0xc527_1c29_7852_819e, + 0x646c_49f9_b46c_bf19, + 0xb87d_b1e2_af3e_a923, + 0x25e5_2be5_07c9_2760, + ]), + pallas::Base::from_raw([ + 0x5c38_0ab7_01b5_2ea9, + 0xa34c_83a3_485c_6b2d, + 0x7109_6d8b_1b98_3c98, + 0x1c49_2d64_c157_aaa4, + ]), + pallas::Base::from_raw([ + 0xa20c_0b3d_a0da_4ca3, + 0xd434_87bc_288d_f682, + 0xf4e6_c5e7_a573_f592, + 0x0c5b_8015_7999_2718, + ]), + ], + [ + pallas::Base::from_raw([ + 0x7ea3_3c93_e408_33cf, + 0x584e_9e62_a7f9_554e, + 0x6869_5c0c_d7cb_f43d, + 0x1090_b1b4_d2be_be7a, + ]), + pallas::Base::from_raw([ + 0xe383_e1ec_3baa_8d69, + 0x1b21_8e35_ecf2_328e, + 0x68f5_ce5c_bed1_9cad, + 0x33e3_8018_a801_387a, + ]), + pallas::Base::from_raw([ + 0xb76b_0b3d_787e_e953, + 0x5f4a_02d2_8729_e3ae, + 0xeef8_d83d_0e87_6bac, + 0x1654_af18_772b_2da5, + ]), + ], + [ + pallas::Base::from_raw([ + 0xef7c_e6a0_1326_5477, + 0xbb08_9387_0367_ec6c, + 0x4474_2de8_8c5a_b0d5, + 0x1678_be3c_c9c6_7993, + ]), + pallas::Base::from_raw([ + 0xaf5d_4789_3348_f766, + 0xdaf1_8183_55b1_3b4f, + 0x7ff9_c6be_546e_928a, + 0x3780_bd1e_01f3_4c22, + ]), + pallas::Base::from_raw([ + 0xa123_8032_0d7c_c1de, + 0x5d11_e69a_a6c0_b98c, + 0x0786_018e_7cb7_7267, + 0x1e83_d631_5c9f_125b, + ]), + ], + [ + pallas::Base::from_raw([ + 0x1799_603e_855c_e731, + 0xc486_894d_76e0_c33b, + 0x160b_4155_2f29_31c8, + 0x354a_fd0a_2f9d_0b26, + ]), + pallas::Base::from_raw([ + 0x8b99_7ee0_6be1_bff3, + 0x60b0_0dbe_1fac_ed07, + 0x2d8a_ffa6_2905_c5a5, + 0x00cd_6d29_f166_eadc, + ]), + pallas::Base::from_raw([ + 0x08d0_6419_1708_2f2c, + 0xc60d_0197_3f18_3057, + 0xdbe0_e3d7_cdbc_66ef, + 0x1d62_1935_2768_e3ae, + ]), + ], + [ + pallas::Base::from_raw([ + 0xfa08_dd98_0638_7577, + 0xafe3_ca1d_b8d4_f529, + 0xe48d_2370_d7d1_a142, + 0x1463_36e2_5db5_181d, + ]), + pallas::Base::from_raw([ + 0xa901_d3ce_84de_0ad4, + 0x022e_54b4_9c13_d907, + 0x997a_2116_3e2e_43df, + 0x0005_d8e0_85fd_72ee, + ]), + pallas::Base::from_raw([ + 0x1c36_f313_4196_4484, + 0x6f8e_bc1d_2296_021a, + 0x0dd5_e61c_8a4e_8642, + 0x364e_97c7_a389_3227, + ]), + ], + [ + pallas::Base::from_raw([ + 0xd7a0_0c03_d2e0_baaa, + 0xfa97_ec80_ad30_7a52, + 0x561c_6fff_1534_6878, + 0x0118_9910_671b_c16b, + ]), + pallas::Base::from_raw([ + 0x63fd_8ac5_7a95_ca8c, + 0x4c0f_7e00_1df4_90aa, + 0x5229_dfaa_0123_1a45, + 0x162a_7c80_f4d2_d12e, + ]), + pallas::Base::from_raw([ + 0x32e6_9efb_22f4_0b96, + 0xcaff_31b4_fda3_2124, + 0x2604_e4af_b09f_8603, + 0x2a0d_6c09_5766_66bb, + ]), + ], + [ + pallas::Base::from_raw([ + 0xc0a0_180f_8cbf_c0d2, + 0xf444_d10d_63a7_4e2c, + 0xe16a_4d60_3d5a_808e, + 0x0978_e5c5_1e1e_5649, + ]), + pallas::Base::from_raw([ + 0x03f4_460e_bc35_1b6e, + 0x0508_7d90_3bda_cfd1, + 0xebe1_9bbd_ce25_1011, + 0x1bdc_ee3a_aca9_cd25, + ]), + pallas::Base::from_raw([ + 0xf619_64bf_3ade_7670, + 0x0c94_7321_e007_5e3f, + 0xe494_7914_0b19_44fd, + 0x1862_cccb_70b5_b885, + ]), + ], + [ + pallas::Base::from_raw([ + 0xc326_7da6_e94a_dc50, + 0x39ee_99c1_cc6e_5dda, + 0xbc26_cc88_3a19_87e1, + 0x1f3e_91d8_63c1_6922, + ]), + pallas::Base::from_raw([ + 0x0f85_b4ac_2c36_7406, + 0xfa66_1465_c656_ad99, + 0xef5c_08f8_478f_663a, + 0x1af4_7a48_a601_6a49, + ]), + pallas::Base::from_raw([ + 0x0eab_cd87_e7d0_1b15, + 0x1c36_98b0_a2e3_da10, + 0x009d_5733_8c69_3505, + 0x3c8e_e901_956e_3d3f, + ]), + ], + [ + pallas::Base::from_raw([ + 0x8b94_7721_8967_3476, + 0xe10c_e2b7_069f_4dbd, + 0x68d0_b024_f591_b520, + 0x1660_a8cd_e7fe_c553, + ]), + pallas::Base::from_raw([ + 0x9d8d_0f67_fdaa_79d5, + 0x3963_c2c1_f558_6e2f, + 0x1303_9363_34dd_1132, + 0x0f6d_9919_29d5_e4e7, + ]), + pallas::Base::from_raw([ + 0x7a43_3091_e1ce_2d3a, + 0x4e7f_da77_0712_f343, + 0xcc62_5eaa_ab52_b4dc, + 0x02b9_cea1_921c_d9f6, + ]), + ], + [ + pallas::Base::from_raw([ + 0x3797_b2d8_3760_43b3, + 0xd8ca_f468_976f_0472, + 0x214f_7c67_84ac_b565, + 0x14a3_23b9_9b90_0331, + ]), + pallas::Base::from_raw([ + 0x347f_ef2c_00f0_953a, + 0x718b_7fbc_7788_af78, + 0xec01_ea79_642d_5760, + 0x1904_76b5_80cb_9277, + ]), + pallas::Base::from_raw([ + 0xff4e_7e6f_b268_dfd7, + 0x9660_902b_6008_7651, + 0xa424_63d3_0b44_2b6f, + 0x090a_3a9d_869d_2eef, + ]), + ], + [ + pallas::Base::from_raw([ + 0xf983_387e_a045_6203, + 0xe365_0013_04f9_a11e, + 0x0dbe_8fd2_270a_6795, + 0x3877_a955_8636_7567, + ]), + pallas::Base::from_raw([ + 0x39c0_af0f_e01f_4a06, + 0x6011_8c53_a218_1352, + 0x5df3_9a2c_c63d_dc0a, + 0x2d89_4691_240f_e953, + ]), + pallas::Base::from_raw([ + 0x1aca_9eaf_9bba_9850, + 0x5914_e855_eeb4_4aa1, + 0x7ef7_1780_2016_6189, + 0x21b9_c182_92bd_bc59, + ]), + ], + [ + pallas::Base::from_raw([ + 0x33f5_09a7_4ad9_d39b, + 0x272e_1cc6_c36a_2968, + 0x505a_05f2_a6ae_834c, + 0x2fe7_6be7_cff7_23e2, + ]), + pallas::Base::from_raw([ + 0x0df9_fa97_277f_a8b4, + 0xd15b_ff84_0dda_e8a5, + 0x9299_81d7_cfce_253b, + 0x187a_a448_f391_e3ca, + ]), + pallas::Base::from_raw([ + 0xf0c6_6af5_ffc7_3736, + 0x663c_cf7b_2ffe_4b5e, + 0x007a_b3aa_3617_f422, + 0x0b70_83ad_7517_07bf, + ]), + ], + [ + pallas::Base::from_raw([ + 0x2f9b_20f1_fbd4_9791, + 0x1975_b962_f6cb_8e0b, + 0x3bc4_ca99_02c5_2acb, + 0x030d_dbb4_7049_3f16, + ]), + pallas::Base::from_raw([ + 0x3a1c_62ca_8fbf_2525, + 0x8fb8_ab9d_60ea_17b2, + 0x950b_0ab1_8d35_46df, + 0x3130_fbaf_fb5a_a82a, + ]), + pallas::Base::from_raw([ + 0x43a8_7618_0dc3_82e0, + 0x15ce_2ead_2fcd_051e, + 0x4f74_d74b_ac2e_e457, + 0x337f_5447_07c4_30f0, + ]), + ], + [ + pallas::Base::from_raw([ + 0x26de_98a8_736d_1d11, + 0x7d8e_471a_9fb9_5fef, + 0xac9d_91b0_930d_ac75, + 0x3499_7991_9015_394f, + ]), + pallas::Base::from_raw([ + 0xccfc_b618_31d5_c775, + 0x3bf9_3da6_fff3_1d95, + 0x2305_cd7a_921e_c5f1, + 0x027c_c4ef_e3fb_35dd, + ]), + pallas::Base::from_raw([ + 0xc3fa_2629_635d_27de, + 0x67f1_c6b7_3147_64af, + 0x61b7_1a36_9868_2ad2, + 0x037f_9f23_6595_4c5b, + ]), + ], + [ + pallas::Base::from_raw([ + 0x77c5_b024_8483_71ae, + 0x6041_4abe_362d_01c9, + 0x10f1_cc6d_f8b4_bcd7, + 0x1f69_7cac_4d07_feb7, + ]), + pallas::Base::from_raw([ + 0x786a_dd24_4aa0_ef29, + 0x3145_c478_0631_09d6, + 0x26e6_c851_fbd5_72a6, + 0x267a_750f_e5d7_cfbc, + ]), + pallas::Base::from_raw([ + 0x180e_2b4d_3e75_6f65, + 0xaf28_5fa8_2ce4_fae5, + 0x678c_9996_d9a4_72c8, + 0x0c91_feab_4a43_193a, + ]), + ], + [ + pallas::Base::from_raw([ + 0x79c4_7c57_3ac4_10f7, + 0x7e3b_83af_4a4b_a3ba, + 0x2186_c303_8ea0_5e69, + 0x1745_569a_0a3e_3014, + ]), + pallas::Base::from_raw([ + 0x1e03_8852_2696_191f, + 0xfdff_66c6_f3b5_ffe1, + 0xeca5_1207_78a5_6711, + 0x2986_3d54_6e7e_7c0d, + ]), + pallas::Base::from_raw([ + 0x2f22_5e63_66bf_e390, + 0xa79a_03df_8339_94c6, + 0xbf06_bae4_9ef8_53f6, + 0x1148_d6ab_2bd0_0192, + ]), + ], + [ + pallas::Base::from_raw([ + 0xf4f6_331a_8b26_5d15, + 0xf745_f45d_350d_41d4, + 0xe18b_1499_060d_a366, + 0x02e0_e121_b0f3_dfef, + ]), + pallas::Base::from_raw([ + 0x078a_e6aa_1510_54b7, + 0x6904_0173_6d44_a653, + 0xb89e_f73a_40a2_b274, + 0x0d0a_a46e_76a6_a278, + ]), + pallas::Base::from_raw([ + 0x9a4d_532c_7b6e_0958, + 0x392d_de71_0f1f_06db, + 0xeee5_45f3_fa6d_3d08, + 0x1394_3675_b04a_a986, + ]), + ], + [ + pallas::Base::from_raw([ + 0x961f_c818_dcbb_66b5, + 0xc9f2_b325_7530_dafe, + 0xd97a_11d6_3088_f5d9, + 0x2901_ec61_942d_34aa, + ]), + pallas::Base::from_raw([ + 0xfdf5_44b9_63d1_fdc7, + 0x22ff_a2a2_af9f_a3e3, + 0xf431_d544_34a3_e0cf, + 0x2020_4a21_05d2_2e7e, + ]), + pallas::Base::from_raw([ + 0x1211_b9e2_190d_6852, + 0xa004_abe8_e015_28c4, + 0x5c1e_3e9e_27a5_71c3, + 0x3a8a_6282_9512_1d5c, + ]), + ], +]; +// Secure MDS: 0 +// n: 255 +// t: 3 +// N: 765 +// Result Algorithm 1: +// [True, 0] +// Result Algorithm 2: +// [True, None] +// Result Algorithm 3: +// [True, None] +// Prime number: 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001 +// MDS matrix: +pub(crate) const MDS: [[pallas::Base; 3]; 3] = [ + [ + pallas::Base::from_raw([ + 0x323f_2486_d7e1_1b63, + 0x97d7_a0ab_2385_0b56, + 0xb3d5_9fbd_c8c9_ead4, + 0x0ab5_e5b8_74a6_8de7, + ]), + pallas::Base::from_raw([ + 0x8eca_5596_e996_ab5e, + 0x240d_4a7c_bf73_5736, + 0x293f_0f0d_886c_7954, + 0x3191_6628_e58a_5abb, + ]), + pallas::Base::from_raw([ + 0x19d1_cf25_d8e8_345d, + 0xa0a3_b71a_5fb1_5735, + 0xd803_952b_bb36_4fdf, + 0x07c0_45d5_f5e9_e5a6, + ]), + ], + [ + pallas::Base::from_raw([ + 0xd049_cdc8_d085_167c, + 0x3a0a_4640_48bd_770a, + 0xf8e2_4f66_822c_2d9f, + 0x2331_6263_0ebf_9ed7, + ]), + pallas::Base::from_raw([ + 0x4022_7011_3e04_7a2e, + 0x78f8_365c_85bb_ab07, + 0xb366_6454_8d60_957d, + 0x25ca_e259_9892_a8b0, + ]), + pallas::Base::from_raw([ + 0xf84d_806f_685f_747a, + 0x9aad_3d82_62ef_d83f, + 0x7493_8717_989a_1957, + 0x22f5_b5e1_e608_1c97, + ]), + ], + [ + pallas::Base::from_raw([ + 0xfee7_a994_4f84_dbe4, + 0x2168_0eab_c56b_c15d, + 0xf333_aa91_c383_3464, + 0x2e29_dd59_c64b_1037, + ]), + pallas::Base::from_raw([ + 0xc771_effa_4326_3664, + 0xcbea_f48b_3a06_24c3, + 0x92d1_5e7d_ceef_1665, + 0x1d1a_ab4e_c1cd_6788, + ]), + pallas::Base::from_raw([ + 0x1563_9415_f6e8_5ef1, + 0x7587_2c39_b59a_31f6, + 0x51e0_cbea_d655_16b9, + 0x3bf7_6308_6a18_9364, + ]), + ], +]; + +pub(crate) const MDS_INV: [[pallas::Base; 3]; 3] = [ + [ + pallas::Base::from_raw([ + 0xc6de_463c_d140_4e6b, + 0x4543_705f_35e9_8ab5, + 0xcc59_ffd0_0de8_6443, + 0x2cc0_57f3_fa14_687a, + ]), + pallas::Base::from_raw([ + 0x1718_4041_7cab_7576, + 0xfadb_f8ae_7ae2_4796, + 0x5fd7_2b55_df20_8385, + 0x32e7_c439_f2f9_67e5, + ]), + pallas::Base::from_raw([ + 0x9426_45bd_7d44_64e0, + 0x1403_db6f_5030_2040, + 0xf461_778a_bf6c_91fa, + 0x2eae_5df8_c311_5969, + ]), + ], + [ + pallas::Base::from_raw([ + 0xa1ca_1516_a4a1_a6a0, + 0x13f0_74fd_e9a1_8b29, + 0xdb18_b4ae_fe68_d26d, + 0x07bf_3684_8106_7199, + ]), + pallas::Base::from_raw([ + 0xe824_25bc_1b23_a059, + 0xbb1d_6504_0c85_c1bf, + 0x018a_918b_9dac_5dad, + 0x2aec_6906_c63f_3cf1, + ]), + pallas::Base::from_raw([ + 0xe054_1adf_238e_0781, + 0x76b2_a713_9db7_1b36, + 0x1215_944a_64a2_46b2, + 0x0952_e024_3aec_2af0, + ]), + ], + [ + pallas::Base::from_raw([ + 0x2a41_8d8d_73a7_c908, + 0xaef9_112e_952f_dbb5, + 0x723a_63a0_c09d_ab26, + 0x2fcb_ba6f_9159_a219, + ]), + pallas::Base::from_raw([ + 0x76ef_ab42_d4fb_a90b, + 0xc5e4_960d_7424_cd37, + 0xb4dd_d4b4_d645_2256, + 0x1ec7_3725_74f3_851b, + ]), + pallas::Base::from_raw([ + 0xadc8_933c_6f3c_72ee, + 0x87a7_435d_30f8_be81, + 0x3c26_fa4b_7d25_b1e4, + 0x0d0c_2efd_6472_f12a, + ]), + ], +]; diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/fq.rs b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/fq.rs new file mode 100644 index 00000000..f3a70686 --- /dev/null +++ b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/fq.rs @@ -0,0 +1,1431 @@ +//! Constants for using Poseidon with the Vesta field. +//! +//! The constants can be reproduced by running the following Sage script from +//! [this repository](https://github.com/daira/pasta-hadeshash): +//! +//! ```text +//! sage generate_parameters_grain.sage 1 0 255 3 8 56 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 +//! ``` +use halo2_curves::pasta::vesta; + +// Number of round constants: 192 +// Round constants for GF(p): +pub(crate) const ROUND_CONSTANTS: [[vesta::Base; 3]; 64] = [ + [ + vesta::Base::from_raw([ + 0x5753_8c25_9642_6303, + 0x4e71_162f_3100_3b70, + 0x353f_628f_76d1_10f3, + 0x360d_7470_611e_473d, + ]), + vesta::Base::from_raw([ + 0xbdb7_4213_bf63_188b, + 0x4908_ac2f_12eb_e06f, + 0x5dc3_c6c5_febf_aa31, + 0x2bab_94d7_ae22_2d13, + ]), + vesta::Base::from_raw([ + 0x0939_d927_53cc_5dc8, + 0xef77_e7d7_3676_6c5d, + 0x2bf0_3e1a_29aa_871f, + 0x150c_93fe_f652_fb1c, + ]), + ], + [ + vesta::Base::from_raw([ + 0x1425_9dce_5377_82b2, + 0x03cc_0a60_141e_894e, + 0x955d_55db_56dc_57c1, + 0x3270_661e_6892_8b3a, + ]), + vesta::Base::from_raw([ + 0xce9f_b9ff_c345_afb3, + 0xb407_c370_f2b5_a1cc, + 0xa0b7_afe4_e205_7299, + 0x073f_116f_0412_2e25, + ]), + vesta::Base::from_raw([ + 0x8eba_d76f_c715_54d8, + 0x55c9_cd20_61ae_93ca, + 0x7aff_d09c_1f53_f5fd, + 0x2a32_ec5c_4ee5_b183, + ]), + ], + [ + vesta::Base::from_raw([ + 0x2d8c_cbe2_92ef_eead, + 0x634d_24fc_6e25_59f2, + 0x651e_2cfc_7406_28ca, + 0x2703_26ee_039d_f19e, + ]), + vesta::Base::from_raw([ + 0xa068_fc37_c182_e274, + 0x8af8_95bc_e012_f182, + 0xdc10_0fe7_fcfa_5491, + 0x27c6_642a_c633_bc66, + ]), + vesta::Base::from_raw([ + 0x9ca1_8682_e26d_7ff9, + 0x710e_1fb6_ab97_6a45, + 0xd27f_5739_6989_129d, + 0x1bdf_d8b0_1401_c70a, + ]), + ], + [ + vesta::Base::from_raw([ + 0xc832_d824_261a_35ea, + 0xf4f6_fb3f_9054_d373, + 0x14b9_d6a9_c84d_d678, + 0x162a_14c6_2f9a_89b8, + ]), + vesta::Base::from_raw([ + 0xf798_2466_7b5b_6bec, + 0xac0a_1fc7_1e2c_f0c0, + 0x2af6_f79e_3127_feea, + 0x2d19_3e0f_76de_586b, + ]), + vesta::Base::from_raw([ + 0x5d0b_f58d_c8a4_aa94, + 0x4fef_f829_8499_0ff8, + 0x8169_6ef1_104e_674f, + 0x044c_a3cc_4a85_d73b, + ]), + ], + [ + vesta::Base::from_raw([ + 0x6198_785f_0cd6_b9af, + 0xb8d9_e2d4_f314_f46f, + 0x1d04_5341_6d3e_235c, + 0x1cba_f2b3_71da_c6a8, + ]), + vesta::Base::from_raw([ + 0x343e_0761_0f3f_ede5, + 0x293c_4ab0_38fd_bbdc, + 0x0e6c_49d0_61b6_b5f4, + 0x1d5b_2777_692c_205b, + ]), + vesta::Base::from_raw([ + 0xf60e_971b_8d73_b04f, + 0x06a9_adb0_c1e6_f962, + 0xaa30_535b_dd74_9a7e, + 0x2e9b_dbba_3dd3_4bff, + ]), + ], + [ + vesta::Base::from_raw([ + 0x035a_1366_1f22_418b, + 0xde40_fbe2_6d04_7b05, + 0x8bd5_bae3_6969_299f, + 0x2de1_1886_b180_11ca, + ]), + vesta::Base::from_raw([ + 0xbc99_8884_ba96_a721, + 0x2ab9_395c_449b_e947, + 0x0d5b_4a3f_1841_dcd8, + 0x2e07_de17_80b8_a70d, + ]), + vesta::Base::from_raw([ + 0x825e_4c2b_b749_25ca, + 0x2504_40a9_9d6b_8af3, + 0xbbdb_63db_d52d_ad16, + 0x0f69_f185_4d20_ca0c, + ]), + ], + [ + vesta::Base::from_raw([ + 0x816c_0594_22dc_705e, + 0x6ce5_1135_07f9_6de9, + 0x0d13_5dc6_39fb_09a4, + 0x2eb1_b254_17fe_1767, + ]), + vesta::Base::from_raw([ + 0xb8b1_bdf4_953b_d82c, + 0xff36_c661_d26c_c42d, + 0x8c24_cb44_c3fa_b48a, + 0x115c_d0a0_643c_fb98, + ]), + vesta::Base::from_raw([ + 0xde80_1612_311d_04cd, + 0xbb57_ddf1_4e0f_958a, + 0x066d_7378_b999_868b, + 0x26ca_293f_7b2c_462d, + ]), + ], + [ + vesta::Base::from_raw([ + 0xf520_9d14_b248_20ca, + 0x0f16_0bf9_f71e_967f, + 0x2a83_0aa1_6241_2cd9, + 0x17bf_1b93_c4c7_e01a, + ]), + vesta::Base::from_raw([ + 0x05c8_6f2e_7dc2_93c5, + 0xe03c_0354_bd8c_fd38, + 0xa24f_8456_369c_85df, + 0x35b4_1a7a_c4f3_c571, + ]), + vesta::Base::from_raw([ + 0x72ac_156a_f435_d09e, + 0x64e1_4d3b_eb2d_ddde, + 0x4359_2799_4849_bea9, + 0x3b14_8008_0523_c439, + ]), + ], + [ + vesta::Base::from_raw([ + 0x2716_18d8_74b1_4c6d, + 0x08e2_8644_2a2d_3eb2, + 0x4950_856d_c907_d575, + 0x2cc6_8100_31dc_1b0d, + ]), + vesta::Base::from_raw([ + 0x91f3_18c0_9f0c_b566, + 0x9e51_7aa9_3b78_341d, + 0x0596_18e2_afd2_ef99, + 0x25bd_bbed_a1bd_e8c1, + ]), + vesta::Base::from_raw([ + 0xc631_3487_073f_7f7b, + 0x2a5e_d0a2_7b61_926c, + 0xb95f_33c2_5dde_8ac0, + 0x392a_4a87_58e0_6ee8, + ]), + ], + [ + vesta::Base::from_raw([ + 0xe7bb_cef0_2eb5_866c, + 0x5e6a_6fd1_5db8_9365, + 0x9aa6_111f_4de0_0948, + 0x272a_5587_8a08_442b, + ]), + vesta::Base::from_raw([ + 0x9b92_5b3c_5b21_e0e2, + 0xa6eb_ba01_1694_dd12, + 0xefa1_3c4e_60e2_6239, + 0x2d5b_308b_0cf0_2cdf, + ]), + vesta::Base::from_raw([ + 0xef38_c57c_3116_73ac, + 0x44df_f42f_18b4_6c56, + 0xdd5d_293d_72e2_e5f2, + 0x1654_9fc6_af2f_3b72, + ]), + ], + [ + vesta::Base::from_raw([ + 0x9b71_26d9_b468_60df, + 0x7639_8265_3442_0311, + 0xfa69_c3a2_ad52_f76d, + 0x1b10_bb7a_82af_ce39, + ]), + vesta::Base::from_raw([ + 0x90d2_7f6a_00b7_dfc8, + 0xd1b3_6968_ba04_05c0, + 0xc79c_2df7_dc98_a3be, + 0x0f1e_7505_ebd9_1d2f, + ]), + vesta::Base::from_raw([ + 0xff45_7756_b819_bb20, + 0x797f_d6e3_f18e_b1ca, + 0x537a_7497_a3b4_3f46, + 0x2f31_3faf_0d3f_6187, + ]), + ], + [ + vesta::Base::from_raw([ + 0xf0bc_3e73_2ecb_26f6, + 0x5cad_11eb_f0f7_ceb8, + 0xfa3c_a61c_0ed1_5bc5, + 0x3a5c_bb6d_e450_b481, + ]), + vesta::Base::from_raw([ + 0x8655_27cb_ca91_5982, + 0x51ba_a6e2_0f89_2b62, + 0xd920_86e2_53b4_39d6, + 0x3dab_54bc_9bef_688d, + ]), + vesta::Base::from_raw([ + 0x3680_45ac_f2b7_1ae3, + 0x4c24_b33b_410f_efd4, + 0xe280_d316_7012_3f74, + 0x06db_fb42_b979_884d, + ]), + ], + [ + vesta::Base::from_raw([ + 0xa7fc_32d2_2f18_b9d3, + 0xb8d2_de72_e3d2_c9ec, + 0xc6f0_39ea_1973_a63e, + 0x068d_6b46_08aa_e810, + ]), + vesta::Base::from_raw([ + 0x2b5d_fcc5_5725_55df, + 0xb868_a7d7_e1f1_f69a, + 0x0ee2_58c9_b8fd_fccd, + 0x366e_bfaf_a3ad_381c, + ]), + vesta::Base::from_raw([ + 0xe6bc_229e_95bc_76b1, + 0x7ef6_6d89_d044_d022, + 0x04db_3024_f41d_3f56, + 0x3967_8f65_512f_1ee4, + ]), + ], + [ + vesta::Base::from_raw([ + 0xe534_c88f_e53d_85fe, + 0xcf82_c25f_99dc_01a4, + 0xd58b_7750_a3bc_2fe1, + 0x2166_8f01_6a80_63c0, + ]), + vesta::Base::from_raw([ + 0x4bef_429b_c533_1608, + 0xe34d_ea56_439f_e195, + 0x1bc7_4936_3e98_a768, + 0x39d0_0994_a8a5_046a, + ]), + vesta::Base::from_raw([ + 0x770c_956f_60d8_81b3, + 0xb163_d416_05d3_9f99, + 0x6b20_3bbe_12fb_3425, + 0x1f9d_bdc3_f843_1263, + ]), + ], + [ + vesta::Base::from_raw([ + 0x9794_a9f7_c336_eab2, + 0xbe0b_c829_fe5e_66c6, + 0xe5f1_7b9e_0ee0_cab6, + 0x0277_45a9_cddf_ad95, + ]), + vesta::Base::from_raw([ + 0x5202_5657_abd8_aee0, + 0x2fa4_3fe2_0a45_c78d, + 0x788d_695c_61e9_3212, + 0x1cec_0803_c504_b635, + ]), + vesta::Base::from_raw([ + 0xd387_2a95_59a0_3a73, + 0xed50_82c8_dbf3_1365, + 0x7207_7448_ef87_cc6e, + 0x1235_23d7_5e9f_abc1, + ]), + ], + [ + vesta::Base::from_raw([ + 0x0017_79e3_a1d3_57f4, + 0x27fe_ba35_975e_e7e5, + 0xf419_b848_e5d6_94bf, + 0x1723_d145_2c9c_f02d, + ]), + vesta::Base::from_raw([ + 0x9dab_1ee4_dcf9_6622, + 0x21c3_f776_f572_836d, + 0xfcc0_573d_7e61_3694, + 0x1739_d180_a160_10bd, + ]), + vesta::Base::from_raw([ + 0x7029_0452_042d_048d, + 0xfafa_96fb_eb0a_b893, + 0xacce_3239_1794_b627, + 0x2d4e_6354_da9c_c554, + ]), + ], + [ + vesta::Base::from_raw([ + 0x670b_cf6f_8b48_5dcd, + 0x8f3b_d43f_9926_0621, + 0x4a86_9553_c9d0_07f8, + 0x153e_e614_2e53_5e33, + ]), + vesta::Base::from_raw([ + 0xd258_d2e2_b778_2172, + 0x968a_d442_4af8_3700, + 0x635e_f7e7_a430_b486, + 0x0c45_bfd3_a69a_aa65, + ]), + vesta::Base::from_raw([ + 0x0e56_33d2_51f7_3307, + 0x6897_ac0a_8ffa_5ff1, + 0xf2d5_6aec_8314_4600, + 0x0adf_d53b_256a_6957, + ]), + ], + [ + vesta::Base::from_raw([ + 0xac9d_36a8_b751_6d63, + 0x3f87_b28f_1c1b_e4bd, + 0x8cd1_726b_7cba_b8ee, + 0x315d_2ac8_ebdb_ac3c, + ]), + vesta::Base::from_raw([ + 0x299c_e44e_a423_d8e1, + 0xc9bb_60d1_f695_9879, + 0xcfae_c23d_2b16_883f, + 0x1b84_7271_2d02_eef4, + ]), + vesta::Base::from_raw([ + 0xc4a5_4041_98ad_f70c, + 0x367d_2c54_e369_28c9, + 0xbd0b_70fa_2255_eb6f, + 0x3c1c_d07e_fda6_ff24, + ]), + ], + [ + vesta::Base::from_raw([ + 0xbbe5_23ae_f9ab_107a, + 0x4a16_073f_738f_7e0c, + 0x687f_4e51_b2e1_dcd3, + 0x1360_52d2_6bb3_d373, + ]), + vesta::Base::from_raw([ + 0x676c_36c2_4ef9_67dd, + 0x7b3c_fbb8_7303_2681, + 0xc1bd_d859_a123_2a1d, + 0x16c9_6bee_f6a0_a848, + ]), + vesta::Base::from_raw([ + 0x067e_ec7f_2d63_40c4, + 0x0123_87ba_b4f1_662d, + 0x2ab7_fed8_f499_a9fb, + 0x284b_38c5_7ff6_5c26, + ]), + ], + [ + vesta::Base::from_raw([ + 0xaf1d_ff20_4c92_2f86, + 0xfc06_772c_1c04_11a6, + 0x39e2_4219_8897_d17c, + 0x0c59_93d1_75e8_1f66, + ]), + vesta::Base::from_raw([ + 0xbbf5_3f67_b1f8_7b15, + 0xf248_87ad_48e1_7759, + 0xfcda_655d_1ba9_c8f9, + 0x03bf_7a3f_7bd0_43da, + ]), + vesta::Base::from_raw([ + 0x9b5c_d09e_36d8_be62, + 0x4c8f_9cbe_69f0_e827, + 0xb0cf_9995_67f0_0e73, + 0x3188_fe4e_e9f9_fafb, + ]), + ], + [ + vesta::Base::from_raw([ + 0xafea_99a2_ec6c_595a, + 0x3af5_bf77_c1c4_2652, + 0x5a39_768c_480d_61e1, + 0x171f_528c_cf65_8437, + ]), + vesta::Base::from_raw([ + 0x5a05_63b9_b8e9_f1d5, + 0x812c_3286_ee70_0067, + 0x196e_4185_9b35_ef88, + 0x12f4_175c_4ab4_5afc, + ]), + vesta::Base::from_raw([ + 0x0e74_d4d3_6911_8b79, + 0x7e23_e1aa_be96_cfab, + 0x8f8f_dcf8_00a9_ac69, + 0x3a50_9e15_5cb7_ebfd, + ]), + ], + [ + vesta::Base::from_raw([ + 0x9871_2c65_678c_fd30, + 0x984b_c8f2_e4c1_b69e, + 0x1a89_920e_2504_c3b3, + 0x10f2_a685_df4a_27c8, + ]), + vesta::Base::from_raw([ + 0xe8a1_6728_cc9d_4918, + 0x5457_3c93_33c5_6321, + 0x1d8d_93d5_4ab9_1a0e, + 0x09e5_f497_90c8_a0e2, + ]), + vesta::Base::from_raw([ + 0x609a_7403_47cf_5fea, + 0x42d1_7ed6_ee0f_ab7e, + 0x2bf3_5705_d9f8_4a34, + 0x352d_69be_d80e_e3e5, + ]), + ], + [ + vesta::Base::from_raw([ + 0x3a75_8af6_fa84_e0e8, + 0xc634_debd_281b_76a6, + 0x4915_62fa_f2b1_90d3, + 0x058e_e73b_a9f3_f293, + ]), + vesta::Base::from_raw([ + 0x621a_1325_10a4_3904, + 0x092c_b921_19bc_76be, + 0xcd0f_1fc5_5b1a_3250, + 0x232f_99cc_911e_ddd9, + ]), + vesta::Base::from_raw([ + 0xc3b9_7c1e_301b_c213, + 0xf9ef_d52c_a6bc_2961, + 0x86c2_2c6c_5d48_69f0, + 0x201b_eed7_b8f3_ab81, + ]), + ], + [ + vesta::Base::from_raw([ + 0xbf6b_3431_ba94_e9bc, + 0x2938_8842_744a_1210, + 0xa1c9_291d_5860_2f51, + 0x1376_dce6_5800_30c6, + ]), + vesta::Base::from_raw([ + 0x6454_843c_5486_d7b3, + 0x072b_a8b0_2d92_e722, + 0x2b33_56c3_8238_f761, + 0x1793_199e_6fd6_ba34, + ]), + vesta::Base::from_raw([ + 0x06a3_f1d3_b433_311b, + 0x3c66_160d_c62a_acac, + 0x9fee_9c20_c87a_67df, + 0x22de_7a74_88dc_c735, + ]), + ], + [ + vesta::Base::from_raw([ + 0x30d6_e3fd_516b_47a8, + 0xdbe0_b77f_ae77_e1d0, + 0xdf8f_f37f_e2d8_edf8, + 0x3514_d5e9_066b_b160, + ]), + vesta::Base::from_raw([ + 0x1937_7427_137a_81c7, + 0xff45_3d6f_900f_144a, + 0xf919_a00d_abbf_5fa5, + 0x30cd_3006_931a_d636, + ]), + vesta::Base::from_raw([ + 0x5b6a_7422_0692_b506, + 0x8f9e_4b2c_ae2e_bb51, + 0x41f8_1a5c_f613_c8df, + 0x253d_1a5c_5293_4127, + ]), + ], + [ + vesta::Base::from_raw([ + 0x73f6_66cb_86a4_8e8e, + 0x851b_3a59_c990_fafc, + 0xa35e_9613_e7f5_fe92, + 0x035b_461c_02d7_9d19, + ]), + vesta::Base::from_raw([ + 0x7cfb_f86a_3aa0_4780, + 0x92b1_283c_2d5f_ccde, + 0x5bc0_0eed_d56b_93e0, + 0x23a9_9280_79d1_75bd, + ]), + vesta::Base::from_raw([ + 0xf1e4_ccd7_3fa0_0a82, + 0xb5e2_ea34_36ee_f957, + 0xf159_4a07_63c6_11ab, + 0x13a7_785a_e134_ea92, + ]), + ], + [ + vesta::Base::from_raw([ + 0xbbf0_4f52_52de_4279, + 0x3889_c578_6344_6d88, + 0x4962_ae3c_0da1_7e31, + 0x39fc_e308_b7d4_3c57, + ]), + vesta::Base::from_raw([ + 0x3b57_e344_89b5_3fad, + 0xbef0_0a08_c6ed_38d2, + 0xc0fd_f016_62f6_0d22, + 0x1aae_1883_3f8e_1d3a, + ]), + vesta::Base::from_raw([ + 0x5551_3e03_3398_513f, + 0x27c1_b3fd_8f85_d8a8, + 0x8b2e_80c0_64fd_83ed, + 0x1a76_1ce8_2400_af01, + ]), + ], + [ + vesta::Base::from_raw([ + 0x5244_ca74_9b73_e481, + 0xdcf6_af28_30a5_0287, + 0x16dd_1a87_ca22_e1cc, + 0x275a_03e4_5add_a7c3, + ]), + vesta::Base::from_raw([ + 0x58a2_53cf_b6a9_5786, + 0x07e5_6145_3fc5_648b, + 0xeb08_e47e_5fea_bcf8, + 0x2e5a_10f0_8b5a_b8bb, + ]), + vesta::Base::from_raw([ + 0xe033_d82c_efe7_8ce3, + 0xc141_a5b6_d594_bec4, + 0xb84e_9c33_3b29_32f1, + 0x1459_cb85_8720_8473, + ]), + ], + [ + vesta::Base::from_raw([ + 0x5cec_7e7b_338f_be1b, + 0x52f9_332f_bffc_fbbd, + 0x7b92_ce81_0e14_a400, + 0x193a_e592_1d78_b5de, + ]), + vesta::Base::from_raw([ + 0x6022_4be6_7248_e82c, + 0x3743_84f4_a072_8205, + 0x8911_1fb2_c466_0281, + 0x3097_898a_5d00_11a4, + ]), + vesta::Base::from_raw([ + 0x5499_80de_8629_30f5, + 0x1979_b2d1_c465_b4d9, + 0x5717_82fd_96ce_54b4, + 0x378d_97bf_8c86_4ae7, + ]), + ], + [ + vesta::Base::from_raw([ + 0x37ea_32a9_71d1_7884, + 0xdbc7_f5cb_4609_3421, + 0x8813_6287_ce37_6b08, + 0x2eb0_4ea7_c01d_97ec, + ]), + vesta::Base::from_raw([ + 0xead3_726f_1af2_e7b0, + 0x861c_bda4_7680_4e6c, + 0x2302_a1c2_2e49_baec, + 0x3642_5347_ea03_f641, + ]), + vesta::Base::from_raw([ + 0xecd6_27e5_9590_d09e, + 0x3f5b_5ca5_a19a_9701, + 0xcc99_6cd8_5c98_a1d8, + 0x26b7_2df4_7408_ad42, + ]), + ], + [ + vesta::Base::from_raw([ + 0x59be_ce31_f0a3_1e95, + 0xde01_212e_e458_8f89, + 0x1f05_636c_610b_89aa, + 0x1301_80e4_4e29_24db, + ]), + vesta::Base::from_raw([ + 0x9ea8_e7bc_7926_3550, + 0xdf77_93cc_89e5_b52f, + 0x7327_5aca_ed5f_579c, + 0x219e_9773_7d39_79ba, + ]), + vesta::Base::from_raw([ + 0x9c12_635d_f251_d153, + 0x3b06_72dd_7d42_cbb4, + 0x3461_363f_81c4_89a2, + 0x3cdb_9359_8a5c_a528, + ]), + ], + [ + vesta::Base::from_raw([ + 0x2861_ce16_f219_d5a9, + 0x4ad0_4470_45a7_c5aa, + 0x2072_4b92_7a0c_a81c, + 0x0e59_e6f3_32d7_ed37, + ]), + vesta::Base::from_raw([ + 0x43b0_a3fc_ff20_36bd, + 0x172c_c07b_9d33_fbf9, + 0x3d73_6946_7222_697a, + 0x1b06_4342_d51a_4275, + ]), + vesta::Base::from_raw([ + 0x3eb3_1022_8a0e_5f6c, + 0x78fa_9fb9_1712_21b7, + 0x2f36_3c55_b288_2e0b, + 0x30b8_2a99_8cbd_8e8a, + ]), + ], + [ + vesta::Base::from_raw([ + 0xe46f_6d42_9874_0107, + 0x8ad7_1ea7_15be_0573, + 0x63df_7a76_e858_a4aa, + 0x23e4_ab37_183a_cba4, + ]), + vesta::Base::from_raw([ + 0xfca9_95e2_b599_14a1, + 0xacfe_1464_0de0_44f2, + 0x5d33_094e_0bed_a75b, + 0x2795_d5c5_fa42_8022, + ]), + vesta::Base::from_raw([ + 0xc26d_909d_ee8b_53c0, + 0xa668_7c3d_f16c_8fe4, + 0xd765_f26d_d03f_4c45, + 0x3001_ca40_1e89_601c, + ]), + ], + [ + vesta::Base::from_raw([ + 0xe7fe_a6bd_f347_1380, + 0xe84b_5beb_ae4e_501d, + 0xf7bf_86e8_9280_827f, + 0x0072_e45c_c676_b08e, + ]), + vesta::Base::from_raw([ + 0xd0c5_4dde_b26b_86c0, + 0xb648_29e2_d40e_41bd, + 0xe2ab_e4c5_18ce_599e, + 0x13de_7054_8487_4bb5, + ]), + vesta::Base::from_raw([ + 0x3891_5b43_2a99_59a5, + 0x82bb_18e5_af1b_05bb, + 0x3159_50f1_211d_efe8, + 0x0408_a9fc_f9d6_1abf, + ]), + ], + [ + vesta::Base::from_raw([ + 0x3407_0cbe_e268_86a0, + 0xae4d_23b0_b41b_e9a8, + 0xbb4e_4a14_00cc_d2c4, + 0x2780_b9e7_5b55_676e, + ]), + vesta::Base::from_raw([ + 0x9405_5920_98b4_056f, + 0xdc4d_8fbe_fe24_405a, + 0xf803_33ec_8563_4ac9, + 0x3a57_0d4d_7c4e_7ac3, + ]), + vesta::Base::from_raw([ + 0x78d2_b247_8995_20b4, + 0xe2cc_1507_bebd_cc62, + 0xf347_c247_fcf0_9294, + 0x0c13_cca7_cb1f_9d2c, + ]), + ], + [ + vesta::Base::from_raw([ + 0x2e8c_88f7_7074_70e0, + 0x0b50_bb2e_b82d_f74d, + 0xd261_4a19_7c6b_794b, + 0x14f5_9baa_03cd_0ca4, + ]), + vesta::Base::from_raw([ + 0xbe52_476e_0a16_f3be, + 0xa51d_54ed_e661_67f5, + 0x6f54_6e17_04c3_9c60, + 0x307d_efee_925d_fb43, + ]), + vesta::Base::from_raw([ + 0x380b_67d8_0473_dce3, + 0x6611_0683_6adf_e5e7, + 0x7a07_e767_4b5a_2621, + 0x1960_cd51_1a91_e060, + ]), + ], + [ + vesta::Base::from_raw([ + 0x15aa_f1f7_7125_89dd, + 0xb8ee_335d_8828_4cbe, + 0xca2a_d0fb_5667_2500, + 0x2301_ef9c_63ea_84c5, + ]), + vesta::Base::from_raw([ + 0x5e68_478c_4d60_27a9, + 0xc861_82d1_b424_6b58, + 0xd10f_4cd5_2be9_7f6b, + 0x029a_5a47_da79_a488, + ]), + vesta::Base::from_raw([ + 0x2cc4_f962_eaae_2260, + 0xf97f_e46b_6a92_5428, + 0x2360_d17d_890e_55cb, + 0x32d7_b16a_7f11_cc96, + ]), + ], + [ + vesta::Base::from_raw([ + 0xc0ca_b915_d536_3d9f, + 0xa5f2_404c_d7b3_5eb0, + 0x18e8_57a9_8d49_8cf7, + 0x2670_3e48_c03b_81ca, + ]), + vesta::Base::from_raw([ + 0xf691_123a_e112_b928, + 0xf443_88bd_6b89_221e, + 0x88ac_8d25_a246_03f1, + 0x0486_82a3_5b32_65bc, + ]), + vesta::Base::from_raw([ + 0x3ab7_defc_b8d8_03e2, + 0x91d6_e171_5164_775e, + 0xd72c_ddc6_cf06_b507, + 0x06b1_3904_41fa_7030, + ]), + ], + [ + vesta::Base::from_raw([ + 0xbcd7_9541_4a6e_2e86, + 0x43b3_60f6_386a_86d7, + 0x1689_426d_ce05_fcd8, + 0x31aa_0eeb_868c_626d, + ]), + vesta::Base::from_raw([ + 0xed77_f5d5_76b9_9cc3, + 0x90ef_d8f4_1b20_78b2, + 0x057a_bad3_764c_104b, + 0x2394_64f7_5bf7_b6af, + ]), + vesta::Base::from_raw([ + 0xb2cb_4873_07c1_cecf, + 0xa5cc_47c5_9654_b2a7, + 0xa45e_19ed_813a_54ab, + 0x0a64_d4c0_4fd4_26bd, + ]), + ], + [ + vesta::Base::from_raw([ + 0x1f73_1532_2f65_8735, + 0x777c_7a92_1a06_2e9d, + 0x576a_4ad2_5986_0fb1, + 0x21fb_bdbb_7367_0734, + ]), + vesta::Base::from_raw([ + 0x6743_2400_3fc5_2146, + 0x5b86_d294_63d3_1564, + 0xd937_1ca2_eb95_acf3, + 0x31b8_6f3c_f017_05d4, + ]), + vesta::Base::from_raw([ + 0x7045_f48a_a4eb_4f6f, + 0x1354_1d65_157e_e1ce, + 0x05ef_1736_d090_56f6, + 0x2bfd_e533_5437_7c91, + ]), + ], + [ + vesta::Base::from_raw([ + 0x5a13_a58d_2001_1e2f, + 0xf4d5_239c_11d0_eafa, + 0xd558_f36e_65f8_eca7, + 0x1233_ca93_6ec2_4671, + ]), + vesta::Base::from_raw([ + 0x6e70_af0a_7a92_4b3a, + 0x8780_58d0_234a_576f, + 0xc437_846d_8e0b_2b30, + 0x27d4_52a4_3ac7_dea2, + ]), + vesta::Base::from_raw([ + 0xa025_76b9_4392_f980, + 0x6a30_641a_1c3d_87b2, + 0xe816_ea8d_a493_e0fa, + 0x2699_dba8_2184_e413, + ]), + ], + [ + vesta::Base::from_raw([ + 0x608c_6f7a_61b5_6e55, + 0xf185_8466_4f8c_ab49, + 0xc398_8bae_e42e_4b10, + 0x36c7_22f0_efcc_8803, + ]), + vesta::Base::from_raw([ + 0x6e49_ac17_0dbb_7fcd, + 0x85c3_8899_a7b5_a833, + 0x08b0_f2ec_89cc_aa37, + 0x02b3_ff48_861e_339b, + ]), + vesta::Base::from_raw([ + 0xa8c5_ae03_ad98_e405, + 0x6fc3_ff4c_49eb_59ad, + 0x6016_2f44_27bc_657b, + 0x0b70_d061_d58d_8a7f, + ]), + ], + [ + vesta::Base::from_raw([ + 0x2e06_cc4a_f33b_0a06, + 0xad3d_e8be_46ed_9693, + 0xf875_3ade_b9d7_cee2, + 0x3fc2_a13f_127f_96a4, + ]), + vesta::Base::from_raw([ + 0xc120_80ac_117e_e15f, + 0x00cb_3d62_1e17_1d80, + 0x1bd6_3434_ac8c_419f, + 0x0c41_a6e4_8dd2_3a51, + ]), + vesta::Base::from_raw([ + 0x9685_213e_9692_f5e1, + 0x72aa_ad7e_4e75_339d, + 0xed44_7653_7169_084e, + 0x2de8_072a_6bd8_6884, + ]), + ], + [ + vesta::Base::from_raw([ + 0x0ad0_1184_567b_027c, + 0xb81c_f735_cc9c_39c0, + 0x9d34_96a3_d9fe_05ec, + 0x0355_7a8f_7b38_a17f, + ]), + vesta::Base::from_raw([ + 0x45bc_b5ac_0082_6abc, + 0x060f_4336_3d81_8e54, + 0xee97_6d34_282f_1a37, + 0x0b5f_5955_2f49_8735, + ]), + vesta::Base::from_raw([ + 0x2f29_09e1_7e22_b0df, + 0xf5d6_46e5_7507_e548, + 0xfedb_b185_70dc_7300, + 0x0e29_23a5_fee7_b878, + ]), + ], + [ + vesta::Base::from_raw([ + 0xf71e_ed73_f15b_3326, + 0xcf1c_b37c_3b03_2af6, + 0xc787_be97_020a_7fdd, + 0x1d78_5005_a7a0_0592, + ]), + vesta::Base::from_raw([ + 0x0acf_bfb2_23f8_f00d, + 0xa590_b88a_3b06_0294, + 0x0ba5_fedc_b8f2_5bd2, + 0x1ad7_72c2_73d9_c6df, + ]), + vesta::Base::from_raw([ + 0xc1ce_13d6_0f2f_5031, + 0x8105_10eb_61f0_672d, + 0xa78f_3275_c278_234b, + 0x027b_d647_85fc_bd2a, + ]), + ], + [ + vesta::Base::from_raw([ + 0x8337_f5e0_7923_a853, + 0xe224_3134_6945_7b8e, + 0xce6f_8ffe_a103_1b6d, + 0x2080_0f44_1b4a_0526, + ]), + vesta::Base::from_raw([ + 0xa33d_7bed_89a4_408a, + 0x36cd_c8ee_d662_ad37, + 0x6eea_2cd4_9f43_12b4, + 0x3d5a_d61d_7b65_f938, + ]), + vesta::Base::from_raw([ + 0x3bbb_ae94_cc19_5284, + 0x1df9_6cc0_3ea4_b26d, + 0x02c5_f91b_e4dd_8e3d, + 0x1333_8bc3_51fc_46dd, + ]), + ], + [ + vesta::Base::from_raw([ + 0xc527_1c29_7852_819e, + 0x646c_49f9_b46c_bf19, + 0xb87d_b1e2_af3e_a923, + 0x25e5_2be5_07c9_2760, + ]), + vesta::Base::from_raw([ + 0x5c38_0ab7_01b5_2ea9, + 0xa34c_83a3_485c_6b2d, + 0x7109_6d8b_1b98_3c98, + 0x1c49_2d64_c157_aaa4, + ]), + vesta::Base::from_raw([ + 0xa20c_0b3d_a0da_4ca3, + 0xd434_87bc_288d_f682, + 0xf4e6_c5e7_a573_f592, + 0x0c5b_8015_7999_2718, + ]), + ], + [ + vesta::Base::from_raw([ + 0x7ea3_3c93_e408_33cf, + 0x584e_9e62_a7f9_554e, + 0x6869_5c0c_d7cb_f43d, + 0x1090_b1b4_d2be_be7a, + ]), + vesta::Base::from_raw([ + 0xe383_e1ec_3baa_8d69, + 0x1b21_8e35_ecf2_328e, + 0x68f5_ce5c_bed1_9cad, + 0x33e3_8018_a801_387a, + ]), + vesta::Base::from_raw([ + 0xb76b_0b3d_787e_e953, + 0x5f4a_02d2_8729_e3ae, + 0xeef8_d83d_0e87_6bac, + 0x1654_af18_772b_2da5, + ]), + ], + [ + vesta::Base::from_raw([ + 0xef7c_e6a0_1326_5477, + 0xbb08_9387_0367_ec6c, + 0x4474_2de8_8c5a_b0d5, + 0x1678_be3c_c9c6_7993, + ]), + vesta::Base::from_raw([ + 0xaf5d_4789_3348_f766, + 0xdaf1_8183_55b1_3b4f, + 0x7ff9_c6be_546e_928a, + 0x3780_bd1e_01f3_4c22, + ]), + vesta::Base::from_raw([ + 0xa123_8032_0d7c_c1de, + 0x5d11_e69a_a6c0_b98c, + 0x0786_018e_7cb7_7267, + 0x1e83_d631_5c9f_125b, + ]), + ], + [ + vesta::Base::from_raw([ + 0x1799_603e_855c_e731, + 0xc486_894d_76e0_c33b, + 0x160b_4155_2f29_31c8, + 0x354a_fd0a_2f9d_0b26, + ]), + vesta::Base::from_raw([ + 0x8b99_7ee0_6be1_bff3, + 0x60b0_0dbe_1fac_ed07, + 0x2d8a_ffa6_2905_c5a5, + 0x00cd_6d29_f166_eadc, + ]), + vesta::Base::from_raw([ + 0x08d0_6419_1708_2f2c, + 0xc60d_0197_3f18_3057, + 0xdbe0_e3d7_cdbc_66ef, + 0x1d62_1935_2768_e3ae, + ]), + ], + [ + vesta::Base::from_raw([ + 0xfa08_dd98_0638_7577, + 0xafe3_ca1d_b8d4_f529, + 0xe48d_2370_d7d1_a142, + 0x1463_36e2_5db5_181d, + ]), + vesta::Base::from_raw([ + 0xa901_d3ce_84de_0ad4, + 0x022e_54b4_9c13_d907, + 0x997a_2116_3e2e_43df, + 0x0005_d8e0_85fd_72ee, + ]), + vesta::Base::from_raw([ + 0x1c36_f313_4196_4484, + 0x6f8e_bc1d_2296_021a, + 0x0dd5_e61c_8a4e_8642, + 0x364e_97c7_a389_3227, + ]), + ], + [ + vesta::Base::from_raw([ + 0xd7a0_0c03_d2e0_baaa, + 0xfa97_ec80_ad30_7a52, + 0x561c_6fff_1534_6878, + 0x0118_9910_671b_c16b, + ]), + vesta::Base::from_raw([ + 0x63fd_8ac5_7a95_ca8c, + 0x4c0f_7e00_1df4_90aa, + 0x5229_dfaa_0123_1a45, + 0x162a_7c80_f4d2_d12e, + ]), + vesta::Base::from_raw([ + 0x32e6_9efb_22f4_0b96, + 0xcaff_31b4_fda3_2124, + 0x2604_e4af_b09f_8603, + 0x2a0d_6c09_5766_66bb, + ]), + ], + [ + vesta::Base::from_raw([ + 0xc0a0_180f_8cbf_c0d2, + 0xf444_d10d_63a7_4e2c, + 0xe16a_4d60_3d5a_808e, + 0x0978_e5c5_1e1e_5649, + ]), + vesta::Base::from_raw([ + 0x03f4_460e_bc35_1b6e, + 0x0508_7d90_3bda_cfd1, + 0xebe1_9bbd_ce25_1011, + 0x1bdc_ee3a_aca9_cd25, + ]), + vesta::Base::from_raw([ + 0xf619_64bf_3ade_7670, + 0x0c94_7321_e007_5e3f, + 0xe494_7914_0b19_44fd, + 0x1862_cccb_70b5_b885, + ]), + ], + [ + vesta::Base::from_raw([ + 0xc326_7da6_e94a_dc50, + 0x39ee_99c1_cc6e_5dda, + 0xbc26_cc88_3a19_87e1, + 0x1f3e_91d8_63c1_6922, + ]), + vesta::Base::from_raw([ + 0x0f85_b4ac_2c36_7406, + 0xfa66_1465_c656_ad99, + 0xef5c_08f8_478f_663a, + 0x1af4_7a48_a601_6a49, + ]), + vesta::Base::from_raw([ + 0x0eab_cd87_e7d0_1b15, + 0x1c36_98b0_a2e3_da10, + 0x009d_5733_8c69_3505, + 0x3c8e_e901_956e_3d3f, + ]), + ], + [ + vesta::Base::from_raw([ + 0x8b94_7721_8967_3476, + 0xe10c_e2b7_069f_4dbd, + 0x68d0_b024_f591_b520, + 0x1660_a8cd_e7fe_c553, + ]), + vesta::Base::from_raw([ + 0x9d8d_0f67_fdaa_79d5, + 0x3963_c2c1_f558_6e2f, + 0x1303_9363_34dd_1132, + 0x0f6d_9919_29d5_e4e7, + ]), + vesta::Base::from_raw([ + 0x7a43_3091_e1ce_2d3a, + 0x4e7f_da77_0712_f343, + 0xcc62_5eaa_ab52_b4dc, + 0x02b9_cea1_921c_d9f6, + ]), + ], + [ + vesta::Base::from_raw([ + 0x3797_b2d8_3760_43b3, + 0xd8ca_f468_976f_0472, + 0x214f_7c67_84ac_b565, + 0x14a3_23b9_9b90_0331, + ]), + vesta::Base::from_raw([ + 0x347f_ef2c_00f0_953a, + 0x718b_7fbc_7788_af78, + 0xec01_ea79_642d_5760, + 0x1904_76b5_80cb_9277, + ]), + vesta::Base::from_raw([ + 0xff4e_7e6f_b268_dfd7, + 0x9660_902b_6008_7651, + 0xa424_63d3_0b44_2b6f, + 0x090a_3a9d_869d_2eef, + ]), + ], + [ + vesta::Base::from_raw([ + 0xf983_387e_a045_6203, + 0xe365_0013_04f9_a11e, + 0x0dbe_8fd2_270a_6795, + 0x3877_a955_8636_7567, + ]), + vesta::Base::from_raw([ + 0x39c0_af0f_e01f_4a06, + 0x6011_8c53_a218_1352, + 0x5df3_9a2c_c63d_dc0a, + 0x2d89_4691_240f_e953, + ]), + vesta::Base::from_raw([ + 0x1aca_9eaf_9bba_9850, + 0x5914_e855_eeb4_4aa1, + 0x7ef7_1780_2016_6189, + 0x21b9_c182_92bd_bc59, + ]), + ], + [ + vesta::Base::from_raw([ + 0x33f5_09a7_4ad9_d39b, + 0x272e_1cc6_c36a_2968, + 0x505a_05f2_a6ae_834c, + 0x2fe7_6be7_cff7_23e2, + ]), + vesta::Base::from_raw([ + 0x0df9_fa97_277f_a8b4, + 0xd15b_ff84_0dda_e8a5, + 0x9299_81d7_cfce_253b, + 0x187a_a448_f391_e3ca, + ]), + vesta::Base::from_raw([ + 0xf0c6_6af5_ffc7_3736, + 0x663c_cf7b_2ffe_4b5e, + 0x007a_b3aa_3617_f422, + 0x0b70_83ad_7517_07bf, + ]), + ], + [ + vesta::Base::from_raw([ + 0x2f9b_20f1_fbd4_9791, + 0x1975_b962_f6cb_8e0b, + 0x3bc4_ca99_02c5_2acb, + 0x030d_dbb4_7049_3f16, + ]), + vesta::Base::from_raw([ + 0x3a1c_62ca_8fbf_2525, + 0x8fb8_ab9d_60ea_17b2, + 0x950b_0ab1_8d35_46df, + 0x3130_fbaf_fb5a_a82a, + ]), + vesta::Base::from_raw([ + 0x43a8_7618_0dc3_82e0, + 0x15ce_2ead_2fcd_051e, + 0x4f74_d74b_ac2e_e457, + 0x337f_5447_07c4_30f0, + ]), + ], + [ + vesta::Base::from_raw([ + 0x26de_98a8_736d_1d11, + 0x7d8e_471a_9fb9_5fef, + 0xac9d_91b0_930d_ac75, + 0x3499_7991_9015_394f, + ]), + vesta::Base::from_raw([ + 0xccfc_b618_31d5_c775, + 0x3bf9_3da6_fff3_1d95, + 0x2305_cd7a_921e_c5f1, + 0x027c_c4ef_e3fb_35dd, + ]), + vesta::Base::from_raw([ + 0xc3fa_2629_635d_27de, + 0x67f1_c6b7_3147_64af, + 0x61b7_1a36_9868_2ad2, + 0x037f_9f23_6595_4c5b, + ]), + ], + [ + vesta::Base::from_raw([ + 0x77c5_b024_8483_71ae, + 0x6041_4abe_362d_01c9, + 0x10f1_cc6d_f8b4_bcd7, + 0x1f69_7cac_4d07_feb7, + ]), + vesta::Base::from_raw([ + 0x786a_dd24_4aa0_ef29, + 0x3145_c478_0631_09d6, + 0x26e6_c851_fbd5_72a6, + 0x267a_750f_e5d7_cfbc, + ]), + vesta::Base::from_raw([ + 0x180e_2b4d_3e75_6f65, + 0xaf28_5fa8_2ce4_fae5, + 0x678c_9996_d9a4_72c8, + 0x0c91_feab_4a43_193a, + ]), + ], + [ + vesta::Base::from_raw([ + 0x79c4_7c57_3ac4_10f7, + 0x7e3b_83af_4a4b_a3ba, + 0x2186_c303_8ea0_5e69, + 0x1745_569a_0a3e_3014, + ]), + vesta::Base::from_raw([ + 0x1e03_8852_2696_191f, + 0xfdff_66c6_f3b5_ffe1, + 0xeca5_1207_78a5_6711, + 0x2986_3d54_6e7e_7c0d, + ]), + vesta::Base::from_raw([ + 0x2f22_5e63_66bf_e390, + 0xa79a_03df_8339_94c6, + 0xbf06_bae4_9ef8_53f6, + 0x1148_d6ab_2bd0_0192, + ]), + ], + [ + vesta::Base::from_raw([ + 0xf4f6_331a_8b26_5d15, + 0xf745_f45d_350d_41d4, + 0xe18b_1499_060d_a366, + 0x02e0_e121_b0f3_dfef, + ]), + vesta::Base::from_raw([ + 0x078a_e6aa_1510_54b7, + 0x6904_0173_6d44_a653, + 0xb89e_f73a_40a2_b274, + 0x0d0a_a46e_76a6_a278, + ]), + vesta::Base::from_raw([ + 0x9a4d_532c_7b6e_0958, + 0x392d_de71_0f1f_06db, + 0xeee5_45f3_fa6d_3d08, + 0x1394_3675_b04a_a986, + ]), + ], + [ + vesta::Base::from_raw([ + 0x961f_c818_dcbb_66b5, + 0xc9f2_b325_7530_dafe, + 0xd97a_11d6_3088_f5d9, + 0x2901_ec61_942d_34aa, + ]), + vesta::Base::from_raw([ + 0xfdf5_44b9_63d1_fdc7, + 0x22ff_a2a2_af9f_a3e3, + 0xf431_d544_34a3_e0cf, + 0x2020_4a21_05d2_2e7e, + ]), + vesta::Base::from_raw([ + 0x1211_b9e2_190d_6852, + 0xa004_abe8_e015_28c4, + 0x5c1e_3e9e_27a5_71c3, + 0x3a8a_6282_9512_1d5c, + ]), + ], +]; + +// n: 255 +// t: 3 +// N: 765 +// Result Algorithm 1: +// [True, 0] +// Result Algorithm 2: +// [True, None] +// Result Algorithm 3: +// [True, None] +// Prime number: 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 +// MDS matrix: +pub(crate) const MDS: [[vesta::Base; 3]; 3] = [ + [ + vesta::Base::from_raw([ + 0xeb4f_1f74_2963_421f, + 0x5f71_0afc_43dd_c5f6, + 0x9191_3f56_cf21_af2b, + 0x1853_b497_7c6f_a227, + ]), + vesta::Base::from_raw([ + 0x45e5_1db6_ac6f_e4a7, + 0x5a0f_a4df_a500_bcad, + 0x63f4_84c1_0fcf_0586, + 0x3d83_1189_cfbb_c452, + ]), + vesta::Base::from_raw([ + 0xd188_37f9_8347_f137, + 0x3f89_65c7_8083_8a94, + 0x4ba8_8b9e_4017_19c0, + 0x3a0e_3f84_d3c1_77d8, + ]), + ], + [ + vesta::Base::from_raw([ + 0x84fd_7923_337c_f77e, + 0x2896_f8d0_fd5c_9a75, + 0x8e9d_c529_f471_8f83, + 0x35e2_6e39_8450_6279, + ]), + vesta::Base::from_raw([ + 0x3eb9_24f5_6fff_7908, + 0x3641_cecf_3a2a_5a8a, + 0x00cd_7dbe_a799_70ab, + 0x10a8_1663_02cb_753c, + ]), + vesta::Base::from_raw([ + 0xb672_27c1_a141_ae94, + 0x198e_1aee_777e_2521, + 0xf434_92ce_5121_4b00, + 0x314f_762a_506d_321b, + ]), + ], + [ + vesta::Base::from_raw([ + 0xabcb_d614_eaf5_eba1, + 0xa90f_28b0_cb31_76fb, + 0xcb2e_ab86_ef31_d915, + 0x07b8_5627_c832_782a, + ]), + vesta::Base::from_raw([ + 0xc255_efd0_06b5_db1c, + 0xb5d9_85dc_1630_a4b2, + 0x9756_4e1b_5d1a_c72f, + 0x2a2d_e13e_70f2_7e16, + ]), + vesta::Base::from_raw([ + 0xcffd_f529_3334_29fc, + 0x21e3_af7e_f123_32cd, + 0xfff5_40a8_7327_c7ce, + 0x2c60_94d1_c6e1_caba, + ]), + ], +]; + +pub(crate) const MDS_INV: [[vesta::Base; 3]; 3] = [ + [ + vesta::Base::from_raw([ + 0xb204_ddc6_5e58_2044, + 0x47a6_0484_b0a9_9c91, + 0xcaf5_4d78_24c1_200e, + 0x36df_4950_21cf_7828, + ]), + vesta::Base::from_raw([ + 0x6a6b_94ad_aa0d_9c9e, + 0xe2cd_38b9_59d4_61ff, + 0xe43e_c4bf_3e0d_f00c, + 0x034f_beae_4650_c2c7, + ]), + vesta::Base::from_raw([ + 0xa862_7a02_8c1a_f7d6, + 0x841b_ebf1_a15b_746e, + 0x1fd5_6832_d0ab_5570, + 0x20a8_64d6_790f_7c1c, + ]), + ], + [ + vesta::Base::from_raw([ + 0x3470_d5c5_53bc_9d20, + 0x1f95_660f_eb5d_b121, + 0xdd31_97ac_c894_9076, + 0x2d08_703d_48ec_d7dc, + ]), + vesta::Base::from_raw([ + 0x6b5b_42b0_67d8_30f3, + 0x6169_b6fa_721a_470e, + 0xeff3_18a2_8983_158a, + 0x2db1_0ecd_507a_2f27, + ]), + vesta::Base::from_raw([ + 0xfbae_b537_d278_4760, + 0x0068_e709_07e7_089d, + 0x926a_5fc0_cc1e_f726, + 0x0c8a_58c0_6473_cdfa, + ]), + ], + [ + vesta::Base::from_raw([ + 0x3a5a_ca10_7129_6e61, + 0x4ad4_442e_96c9_d5e8, + 0x5432_f0c0_b908_a411, + 0x2a64_2dca_695d_744d, + ]), + vesta::Base::from_raw([ + 0x1bd9_bfcb_be02_5ff1, + 0x24f6_ad43_b703_ad90, + 0xebb7_238d_f00d_17e7, + 0x114e_c796_fb40_3f5f, + ]), + vesta::Base::from_raw([ + 0x67f0_642e_14a9_c3bf, + 0xf6a6_9176_7069_7a97, + 0x0408_110d_c66e_b147, + 0x2825_e067_5968_dbeb, + ]), + ], +]; diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/grain.rs b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/grain.rs new file mode 100644 index 00000000..6c0ebf80 --- /dev/null +++ b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/grain.rs @@ -0,0 +1,196 @@ +//! The Grain LFSR in self-shrinking mode, as used by Poseidon. + +use std::marker::PhantomData; + +use bitvec::prelude::*; +use ff::{FromUniformBytes, PrimeField}; +use halo2_proofs::arithmetic::Field; + +const STATE: usize = 80; + +#[derive(Debug, Clone, Copy)] +pub(super) enum FieldType { + /// GF(2^n) + #[allow(dead_code)] + Binary, + /// GF(p) + PrimeOrder, +} + +impl FieldType { + fn tag(&self) -> u8 { + match self { + FieldType::Binary => 0, + FieldType::PrimeOrder => 1, + } + } +} + +#[derive(Debug, Clone, Copy)] +pub(super) enum SboxType { + /// x^alpha + Pow, + /// x^(-1) + #[allow(dead_code)] + Inv, +} + +impl SboxType { + fn tag(&self) -> u8 { + match self { + SboxType::Pow => 0, + SboxType::Inv => 1, + } + } +} + +pub(super) struct Grain { + state: BitArr!(for 80, in u8, Msb0), + next_bit: usize, + _field: PhantomData, +} + +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![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 { + *state.get_mut(offset + len - 1 - i).unwrap() = (value >> i) & 1 != 0; + } + }; + set_bits(0, 2, FieldType::PrimeOrder.tag() as u16); + set_bits(2, 4, sbox.tag() as u16); + set_bits(6, 12, F::NUM_BITS as u16); + set_bits(18, 12, t); + set_bits(30, 10, r_f); + set_bits(40, 10, r_p); + + let mut grain = Grain { + state, + next_bit: STATE, + _field: PhantomData, + }; + + // Discard the first 160 bits. + for _ in 0..20 { + grain.load_next_8_bits(); + grain.next_bit = STATE; + } + + grain + } + + fn load_next_8_bits(&mut self) { + let mut new_bits = 0u8; + for i in 0..8 { + new_bits |= ((self.state[i + 62] + ^ self.state[i + 51] + ^ self.state[i + 38] + ^ self.state[i + 23] + ^ self.state[i + 13] + ^ self.state[i]) as u8) + << i; + } + self.state.rotate_left(8); + self.next_bit -= 8; + for i in 0..8 { + *self.state.get_mut(self.next_bit + i).unwrap() = (new_bits >> i) & 1 != 0; + } + } + + fn get_next_bit(&mut self) -> bool { + if self.next_bit == STATE { + self.load_next_8_bits(); + } + let ret = self.state[self.next_bit]; + self.next_bit += 1; + ret + } + + /// Returns the next field element from this Grain instantiation. + pub(super) fn next_field_element(&mut self) -> F { + // Loop until we get an element in the field. + loop { + let mut bytes = F::Repr::default(); + + // Poseidon reference impl interprets the bits as a repr in MSB order, because + // it's easy to do that in Python. Meanwhile, our field elements all use LSB + // order. There's little motivation to diverge from the reference impl; these + // are all constants, so we aren't introducing big-endianness into the rest of + // the circuit (assuming unkeyed Poseidon, but we probably wouldn't want to + // implement Grain inside a circuit, so we'd use a different round constant + // derivation function there). + let view = bytes.as_mut(); + for (i, bit) in self.take(F::NUM_BITS as usize).enumerate() { + // If we diverged from the reference impl and interpreted the bits in LSB + // order, we would remove this line. + let i = F::NUM_BITS as usize - 1 - i; + + view[i / 8] |= if bit { 1 << (i % 8) } else { 0 }; + } + + if let Some(f) = F::from_repr_vartime(bytes) { + break f; + } + } + } +} + +impl> Grain { + /// Returns the next field element from this Grain instantiation, without using + /// rejection sampling. + pub(super) fn next_field_element_without_rejection(&mut self) -> F { + let mut bytes = [0u8; 64]; + + // Poseidon reference impl interprets the bits as a repr in MSB order, because + // it's easy to do that in Python. Additionally, it does not use rejection + // sampling in cases where the constants don't specifically need to be uniformly + // random for security. We do not provide APIs that take a field-element-sized + // array and reduce it modulo the field order, because those are unsafe APIs to + // offer generally (accidentally using them can lead to divergence in consensus + // systems due to not rejecting canonical forms). + // + // Given that we don't want to diverge from the reference implementation, we hack + // around this restriction by serializing the bits into a 64-byte array and then + // calling F::from_bytes_wide. PLEASE DO NOT COPY THIS INTO YOUR OWN CODE! + let view = bytes.as_mut(); + for (i, bit) in self.take(F::NUM_BITS as usize).enumerate() { + // If we diverged from the reference impl and interpreted the bits in LSB + // order, we would remove this line. + let i = F::NUM_BITS as usize - 1 - i; + + view[i / 8] |= if bit { 1 << (i % 8) } else { 0 }; + } + + F::from_uniform_bytes(&bytes) + } +} + +impl Iterator for Grain { + type Item = bool; + + fn next(&mut self) -> Option { + // Evaluate bits in pairs: + // - If the first bit is a 1, output the second bit. + // - If the first bit is a 0, discard the second bit. + while !self.get_next_bit() { + self.get_next_bit(); + } + Some(self.get_next_bit()) + } +} + +#[cfg(test)] +mod tests { + use halo2_curves::pasta::Fp; + + use super::{Grain, SboxType}; + + #[test] + fn grain() { + let mut grain = Grain::::new(SboxType::Pow, 3, 8, 56); + let _f = grain.next_field_element(); + } +} diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/mds.rs b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/mds.rs new file mode 100644 index 00000000..2a6f33f5 --- /dev/null +++ b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/mds.rs @@ -0,0 +1,124 @@ +use ff::FromUniformBytes; + +use super::{grain::Grain, Mds}; + +pub(super) fn generate_mds + Ord, const T: usize>( + grain: &mut Grain, + mut select: usize, +) -> (Mds, Mds) { + let (xs, ys, mds) = loop { + // Generate two [F; T] arrays of unique field elements. + let (xs, ys) = loop { + let mut vals: Vec<_> = (0..2 * T) + .map(|_| grain.next_field_element_without_rejection()) + .collect(); + + // Check that we have unique field elements. + let mut unique = vals.clone(); + unique.sort_unstable(); + unique.dedup(); + if vals.len() == unique.len() { + let rhs = vals.split_off(T); + break (vals, rhs); + } + }; + + // We need to ensure that the MDS is secure. Instead of checking the MDS against + // the relevant algorithms directly, we witness a fixed number of MDS matrices + // that we need to sample from the given Grain state before obtaining a secure + // matrix. This can be determined out-of-band via the reference implementation in + // Sage. + if select != 0 { + select -= 1; + continue; + } + + // Generate a Cauchy matrix, with elements a_ij in the form: + // a_ij = 1/(x_i + y_j); x_i + y_j != 0 + // + // It would be much easier to use the alternate definition: + // a_ij = 1/(x_i - y_j); x_i - y_j != 0 + // + // These are clearly equivalent on `y <- -y`, but it is easier to work with the + // negative formulation, because ensuring that xs ∪ ys is unique implies that + // x_i - y_j != 0 by construction (whereas the positive case does not hold). It + // also makes computation of the matrix inverse simpler below (the theorem used + // was formulated for the negative definition). + // + // However, the Poseidon paper and reference impl use the positive formulation, + // and we want to rely on the reference impl for MDS security, so we use the same + // formulation. + let mut mds = [[F::ZERO; T]; T]; + #[allow(clippy::needless_range_loop)] + for i in 0..T { + for j in 0..T { + let sum = xs[i] + ys[j]; + // We leverage the secure MDS selection counter to also check this. + assert!(!sum.is_zero_vartime()); + mds[i][j] = sum.invert().unwrap(); + } + } + + break (xs, ys, mds); + }; + + // Compute the inverse. All square Cauchy matrices have a non-zero determinant and + // thus are invertible. The inverse for a Cauchy matrix of the form: + // + // a_ij = 1/(x_i - y_j); x_i - y_j != 0 + // + // has elements b_ij given by: + // + // b_ij = (x_j - y_i) A_j(y_i) B_i(x_j) (Schechter 1959, Theorem 1) + // + // where A_i(x) and B_i(x) are the Lagrange polynomials for xs and ys respectively. + // + // We adapt this to the positive Cauchy formulation by negating ys. + let mut mds_inv = [[F::ZERO; T]; T]; + let l = |xs: &[F], j, x: F| { + let x_j = xs[j]; + xs.iter().enumerate().fold(F::ONE, |acc, (m, x_m)| { + if m == j { + acc + } else { + // We can invert freely; by construction, the elements of xs are distinct. + let diff: F = x_j - *x_m; + acc * (x - x_m) * diff.invert().unwrap() + } + }) + }; + let neg_ys: Vec<_> = ys.iter().map(|y| -*y).collect(); + for i in 0..T { + for j in 0..T { + mds_inv[i][j] = (xs[j] - neg_ys[i]) * l(&xs, j, neg_ys[i]) * l(&neg_ys, i, xs[j]); + } + } + + (mds, mds_inv) +} + +#[cfg(test)] +mod tests { + use halo2_curves::pasta::Fp; + + use super::{generate_mds, Grain}; + + #[test] + fn poseidon_mds() { + const T: usize = 3; + let mut grain = Grain::new(super::super::grain::SboxType::Pow, T as u16, 8, 56); + let (mds, mds_inv) = generate_mds::(&mut grain, 0); + + // Verify that MDS * MDS^-1 = I. + #[allow(clippy::needless_range_loop)] + for i in 0..T { + for j in 0..T { + let expected = if i == j { Fp::one() } else { Fp::zero() }; + assert_eq!( + (0..T).fold(Fp::zero(), |acc, k| acc + (mds[i][k] * mds_inv[k][j])), + expected + ); + } + } + } +} diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/p128pow5t3.rs b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/p128pow5t3.rs new file mode 100644 index 00000000..8b074e35 --- /dev/null +++ b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/p128pow5t3.rs @@ -0,0 +1,320 @@ +use halo2_proofs::arithmetic::Field; +use halo2_curves::pasta::{pallas::Base as Fp, vesta::Base as Fq}; + +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". +/// +/// The standard specification for this set of parameters (on either of the Pasta +/// fields) uses $R_F = 8, R_P = 56$. This is conveniently an even number of +/// partial rounds, making it easier to construct a Halo 2 circuit. +#[derive(Debug)] +pub struct P128Pow5T3; + +impl Spec for P128Pow5T3 { + fn full_rounds() -> usize { + 8 + } + + fn partial_rounds() -> usize { + 56 + } + + fn sbox(val: Fp) -> Fp { + val.pow_vartime([5]) + } + + fn secure_mds() -> usize { + unimplemented!() + } + + fn constants() -> (Vec<[Fp; 3]>, Mds, Mds) { + ( + super::fp::ROUND_CONSTANTS[..].to_vec(), + super::fp::MDS, + super::fp::MDS_INV, + ) + } +} + +impl Spec for P128Pow5T3 { + fn full_rounds() -> usize { + 8 + } + + fn partial_rounds() -> usize { + 56 + } + + fn sbox(val: Fq) -> Fq { + val.pow_vartime([5]) + } + + fn secure_mds() -> usize { + unimplemented!() + } + + fn constants() -> (Vec<[Fq; 3]>, Mds, Mds) { + ( + super::fq::ROUND_CONSTANTS[..].to_vec(), + super::fq::MDS, + super::fq::MDS_INV, + ) + } +} + +#[cfg(test)] +mod tests { + #![allow(dead_code)] + use super::{ + super::{fp, fq}, + Fp, Fq, + }; + use crate::frontend::halo2::poseidongadget::poseidon::primitives::{ + generate_constants, permute, ConstantLength, Hash, Mds, Spec, + }; + use ff::PrimeField; + use ff::{Field, FromUniformBytes}; + use std::marker::PhantomData; + + /// The same Poseidon specification as poseidon::P128Pow5T3, but constructed + /// such that its constants will be generated at runtime. + #[derive(Debug)] + pub struct P128Pow5T3Gen(PhantomData); + + impl P128Pow5T3Gen { + pub fn new() -> Self { + P128Pow5T3Gen(PhantomData) + } + } + + impl + Ord, const SECURE_MDS: usize> Spec + for P128Pow5T3Gen + { + fn full_rounds() -> usize { + 8 + } + + fn partial_rounds() -> usize { + 56 + } + + fn sbox(val: F) -> F { + val.pow_vartime([5]) + } + + fn secure_mds() -> usize { + SECURE_MDS + } + + fn constants() -> (Vec<[F; 3]>, Mds, Mds) { + generate_constants::<_, Self, 3, 2>() + } + } + + #[test] + fn verify_constants() { + fn verify_constants_helper + Ord>( + expected_round_constants: [[F; 3]; 64], + expected_mds: [[F; 3]; 3], + expected_mds_inv: [[F; 3]; 3], + ) { + let (round_constants, mds, mds_inv) = P128Pow5T3Gen::::constants(); + + for (actual, expected) in round_constants + .iter() + .flatten() + .zip(expected_round_constants.iter().flatten()) + { + assert_eq!(actual, expected); + } + + for (actual, expected) in mds.iter().flatten().zip(expected_mds.iter().flatten()) { + assert_eq!(actual, expected); + } + + for (actual, expected) in mds_inv + .iter() + .flatten() + .zip(expected_mds_inv.iter().flatten()) + { + assert_eq!(actual, expected); + } + } + + verify_constants_helper(fp::ROUND_CONSTANTS, fp::MDS, fp::MDS_INV); + verify_constants_helper(fq::ROUND_CONSTANTS, fq::MDS, fq::MDS_INV); + } + + #[test] + fn test_against_reference() { + { + // , using parameters from + // `generate_parameters_grain.sage 1 0 255 3 8 56 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001`. + // The test vector is generated by `sage poseidonperm_x5_pallas_3.sage --rust` + + let mut 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 expected_output = [ + Fp::from_raw([ + 0xaeb1_bc02_4aec_a456, + 0xf7e6_9a71_d0b6_42a0, + 0x94ef_b364_f966_240f, + 0x2a52_6acd_0b64_b453, + ]), + Fp::from_raw([ + 0x012a_3e96_28e5_b82a, + 0xdcd4_2e7f_bed9_dafe, + 0x76ff_7dae_343d_5512, + 0x13c5_d156_8b4a_a430, + ]), + Fp::from_raw([ + 0x3590_29a1_d34e_9ddd, + 0xf7cf_dfe1_bda4_2c7b, + 0x256f_cd59_7984_561a, + 0x0a49_c868_c697_6544, + ]), + ]; + + permute::, 3, 2>(&mut input, &fp::MDS, &fp::ROUND_CONSTANTS); + assert_eq!(input, expected_output); + } + + { + // , using parameters from + // `generate_parameters_grain.sage 1 0 255 3 8 56 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001`. + // The test vector is generated by `sage poseidonperm_x5_vesta_3.sage --rust` + + let mut input = [ + Fq::from_raw([ + 0x0000_0000_0000_0000, + 0x0000_0000_0000_0000, + 0x0000_0000_0000_0000, + 0x0000_0000_0000_0000, + ]), + Fq::from_raw([ + 0x0000_0000_0000_0001, + 0x0000_0000_0000_0000, + 0x0000_0000_0000_0000, + 0x0000_0000_0000_0000, + ]), + Fq::from_raw([ + 0x0000_0000_0000_0002, + 0x0000_0000_0000_0000, + 0x0000_0000_0000_0000, + 0x0000_0000_0000_0000, + ]), + ]; + + let expected_output = [ + Fq::from_raw([ + 0x0eb0_8ea8_13be_be59, + 0x4d43_d197_3dd3_36c6, + 0xeddd_74f2_2f8f_2ff7, + 0x315a_1f4c_db94_2f7c, + ]), + Fq::from_raw([ + 0xf9f1_26e6_1ea1_65f1, + 0x413e_e0eb_7bbd_2198, + 0x642a_dee0_dd13_aa48, + 0x3be4_75f2_d764_2bde, + ]), + Fq::from_raw([ + 0x14d5_4237_2a7b_a0d9, + 0x5019_bfd4_e042_3fa0, + 0x117f_db24_20d8_ea60, + 0x25ab_8aec_e953_7168, + ]), + ]; + + permute::, 3, 2>(&mut input, &fq::MDS, &fq::ROUND_CONSTANTS); + assert_eq!(input, expected_output); + } + } + + #[test] + fn permute_test_vectors() { + { + let (round_constants, mds, _) = super::P128Pow5T3::constants(); + + for tv in crate::frontend::halo2::poseidongadget::poseidon::primitives::test_vectors::fp::permute() { + let mut state = [ + Fp::from_repr(tv.initial_state[0]).unwrap(), + Fp::from_repr(tv.initial_state[1]).unwrap(), + Fp::from_repr(tv.initial_state[2]).unwrap(), + ]; + + permute::(&mut state, &mds, &round_constants); + + for (expected, actual) in tv.final_state.iter().zip(state.iter()) { + assert_eq!(&actual.to_repr(), expected); + } + } + } + + { + let (round_constants, mds, _) = super::P128Pow5T3::constants(); + + for tv in crate::frontend::halo2::poseidongadget::poseidon::primitives::test_vectors::fq::permute() { + let mut state = [ + Fq::from_repr(tv.initial_state[0]).unwrap(), + Fq::from_repr(tv.initial_state[1]).unwrap(), + Fq::from_repr(tv.initial_state[2]).unwrap(), + ]; + + permute::(&mut state, &mds, &round_constants); + + for (expected, actual) in tv.final_state.iter().zip(state.iter()) { + assert_eq!(&actual.to_repr(), expected); + } + } + } + } + + #[test] + fn hash_test_vectors() { + for tv in crate::frontend::halo2::poseidongadget::poseidon::primitives::test_vectors::fp::hash() { + let message = [ + Fp::from_repr(tv.input[0]).unwrap(), + Fp::from_repr(tv.input[1]).unwrap(), + ]; + + let result = + Hash::<_, super::P128Pow5T3, ConstantLength<2>, 3, 2>::init().hash(message); + + assert_eq!(result.to_repr(), tv.output); + } + + for tv in crate::frontend::halo2::poseidongadget::poseidon::primitives::test_vectors::fq::hash() { + let message = [ + Fq::from_repr(tv.input[0]).unwrap(), + Fq::from_repr(tv.input[1]).unwrap(), + ]; + + let result = + Hash::<_, super::P128Pow5T3, ConstantLength<2>, 3, 2>::init().hash(message); + + assert_eq!(result.to_repr(), tv.output); + } + } +} diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/test_vectors.rs b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/test_vectors.rs new file mode 100644 index 00000000..1c345a48 --- /dev/null +++ b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/test_vectors.rs @@ -0,0 +1,1261 @@ +//! Test vectors for [`OrchardNullifier`]. + +pub(crate) struct PermuteTestVector { + pub(crate) initial_state: [[u8; 32]; 3], + pub(crate) final_state: [[u8; 32]; 3], +} + +pub(crate) struct HashTestVector { + pub(crate) input: [[u8; 32]; 2], + pub(crate) output: [u8; 32], +} + +pub(crate) mod fp { + use super::*; + + pub(crate) fn permute() -> Vec { + use PermuteTestVector as TestVector; + + // From https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/orchard_poseidon/permute/fp.py + vec![ + TestVector { + initial_state: [ + [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ], + [ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ], + [ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ], + ], + final_state: [ + [ + 0x56, 0xa4, 0xec, 0x4a, 0x02, 0xbc, 0xb1, 0xae, 0xa0, 0x42, 0xb6, 0xd0, + 0x71, 0x9a, 0xe6, 0xf7, 0x0f, 0x24, 0x66, 0xf9, 0x64, 0xb3, 0xef, 0x94, + 0x53, 0xb4, 0x64, 0x0b, 0xcd, 0x6a, 0x52, 0x2a, + ], + [ + 0x2a, 0xb8, 0xe5, 0x28, 0x96, 0x3e, 0x2a, 0x01, 0xfe, 0xda, 0xd9, 0xbe, + 0x7f, 0x2e, 0xd4, 0xdc, 0x12, 0x55, 0x3d, 0x34, 0xae, 0x7d, 0xff, 0x76, + 0x30, 0xa4, 0x4a, 0x8b, 0x56, 0xd1, 0xc5, 0x13, + ], + [ + 0xdd, 0x9d, 0x4e, 0xd3, 0xa1, 0x29, 0x90, 0x35, 0x7b, 0x2c, 0xa4, 0xbd, + 0xe1, 0xdf, 0xcf, 0xf7, 0x1a, 0x56, 0x84, 0x79, 0x59, 0xcd, 0x6f, 0x25, + 0x44, 0x65, 0x97, 0xc6, 0x68, 0xc8, 0x49, 0x0a, + ], + ], + }, + TestVector { + initial_state: [ + [ + 0x5c, 0x7a, 0x8f, 0x73, 0xad, 0xfc, 0x70, 0xfb, 0x3f, 0x13, 0x94, 0x49, + 0xac, 0x6b, 0x57, 0x07, 0x4c, 0x4d, 0x6e, 0x66, 0xb1, 0x64, 0x93, 0x9d, + 0xaf, 0xfa, 0x2e, 0xf6, 0xee, 0x69, 0x21, 0x08, + ], + [ + 0x1a, 0xdd, 0x86, 0xb3, 0xf2, 0xe1, 0xbd, 0xa6, 0x2a, 0x5d, 0x2e, 0x0e, + 0x98, 0x2b, 0x77, 0xe6, 0xb0, 0xef, 0x9c, 0xa3, 0xf2, 0x49, 0x88, 0xc7, + 0xb3, 0x53, 0x42, 0x01, 0xcf, 0xb1, 0xcd, 0x0d, + ], + [ + 0xbd, 0x69, 0xb8, 0x25, 0x32, 0xb6, 0x94, 0x0f, 0xf2, 0x59, 0x0f, 0x67, + 0x9b, 0xa9, 0xc7, 0x27, 0x1f, 0xe0, 0x1f, 0x7e, 0x9c, 0x8e, 0x36, 0xd6, + 0xa5, 0xe2, 0x9d, 0x4e, 0x30, 0xa7, 0x35, 0x14, + ], + ], + final_state: [ + [ + 0xd0, 0x6e, 0x2f, 0x83, 0x38, 0x92, 0x8a, 0x7e, 0xe7, 0x38, 0x0c, 0x77, + 0x92, 0x80, 0x87, 0xcd, 0xa2, 0xfd, 0x29, 0x61, 0xa1, 0x52, 0x69, 0x03, + 0x7a, 0x22, 0xd6, 0xd1, 0x20, 0xae, 0xdd, 0x21, + ], + [ + 0x29, 0x55, 0xa4, 0x5f, 0x41, 0x6f, 0x10, 0xd6, 0xbc, 0x79, 0xac, 0x94, + 0xd0, 0xc0, 0x69, 0xc9, 0x49, 0xe5, 0xf4, 0xbd, 0x09, 0x48, 0x1e, 0x1f, + 0x36, 0x8c, 0xb9, 0xb8, 0xee, 0x51, 0x14, 0x0d, + ], + [ + 0x0d, 0x83, 0x76, 0xbb, 0xe9, 0xd6, 0x5d, 0x2b, 0x1e, 0x13, 0x6f, 0xb7, + 0xd9, 0x82, 0xab, 0x87, 0xc5, 0x1c, 0x40, 0x30, 0x44, 0xbe, 0x5c, 0x79, + 0x9d, 0x56, 0xbb, 0x68, 0xac, 0xf9, 0x5b, 0x10, + ], + ], + }, + TestVector { + initial_state: [ + [ + 0xbc, 0x50, 0x98, 0x42, 0x55, 0xd6, 0xaf, 0xbe, 0x9e, 0xf9, 0x28, 0x48, + 0xed, 0x5a, 0xc0, 0x08, 0x62, 0xc2, 0xfa, 0x7b, 0x2f, 0xec, 0xbc, 0xb6, + 0x4b, 0x69, 0x68, 0x91, 0x2a, 0x63, 0x81, 0x0e, + ], + [ + 0x3d, 0xc1, 0x66, 0xd5, 0x6a, 0x1d, 0x62, 0xf5, 0xa8, 0xd7, 0x55, 0x1d, + 0xb5, 0xfd, 0x93, 0x13, 0xe8, 0xc7, 0x20, 0x3d, 0x99, 0x6a, 0xf7, 0xd4, + 0x77, 0x08, 0x37, 0x56, 0xd5, 0x9a, 0xf8, 0x0d, + ], + [ + 0x05, 0xa7, 0x45, 0xf4, 0x5d, 0x7f, 0xf6, 0xdb, 0x10, 0xbc, 0x67, 0xfd, + 0xf0, 0xf0, 0x3e, 0xbf, 0x81, 0x30, 0xab, 0x33, 0x36, 0x26, 0x97, 0xb0, + 0xe4, 0xe4, 0xc7, 0x63, 0xcc, 0xb8, 0xf6, 0x36, + ], + ], + final_state: [ + [ + 0x0b, 0x77, 0xec, 0x53, 0x07, 0x14, 0x5a, 0x0c, 0x05, 0x2d, 0xc7, 0xa9, + 0xd6, 0xf9, 0x6a, 0xc3, 0x41, 0xae, 0x72, 0x64, 0x08, 0x32, 0xd5, 0x8e, + 0x51, 0xeb, 0x92, 0xa4, 0x17, 0x80, 0x17, 0x12, + ], + [ + 0x3b, 0x52, 0x3f, 0x44, 0xf0, 0x0e, 0x46, 0x3f, 0x8b, 0x0f, 0xd7, 0xd4, + 0xfc, 0x0e, 0x28, 0x0c, 0xdb, 0xde, 0xb9, 0x27, 0xf1, 0x81, 0x68, 0x07, + 0x7b, 0xb3, 0x62, 0xf2, 0x67, 0x5a, 0x2e, 0x18, + ], + [ + 0x95, 0x7a, 0x97, 0x06, 0xff, 0xcc, 0x35, 0x15, 0x64, 0xae, 0x80, 0x2a, + 0x99, 0x11, 0x31, 0x4c, 0x05, 0xe2, 0x3e, 0x22, 0xaf, 0xcf, 0x83, 0x40, + 0x59, 0xdf, 0x80, 0xfa, 0xc1, 0x05, 0x76, 0x26, + ], + ], + }, + TestVector { + initial_state: [ + [ + 0x49, 0x5c, 0x22, 0x2f, 0x7f, 0xba, 0x1e, 0x31, 0xde, 0xfa, 0x3d, 0x5a, + 0x57, 0xef, 0xc2, 0xe1, 0xe9, 0xb0, 0x1a, 0x03, 0x55, 0x87, 0xd5, 0xfb, + 0x1a, 0x38, 0xe0, 0x1d, 0x94, 0x90, 0x3d, 0x3c, + ], + [ + 0x3d, 0x0a, 0xd3, 0x36, 0x1f, 0xec, 0x09, 0x77, 0x90, 0xd9, 0xbe, 0x0e, + 0x42, 0x98, 0x8d, 0x7d, 0x25, 0xc9, 0xa1, 0x38, 0xf4, 0x9b, 0x1a, 0x53, + 0x7e, 0xdc, 0xf0, 0x4b, 0xe3, 0x4a, 0x98, 0x11, + ], + [ + 0xa4, 0xaf, 0x9d, 0xb6, 0xd2, 0x7b, 0x50, 0x72, 0x83, 0x5f, 0x0c, 0x3e, + 0x88, 0x39, 0x5e, 0xd7, 0xa4, 0x1b, 0x00, 0x52, 0xad, 0x80, 0x84, 0xa8, + 0xb9, 0xda, 0x94, 0x8d, 0x32, 0x0d, 0xad, 0x16, + ], + ], + final_state: [ + [ + 0x67, 0x80, 0x08, 0x3f, 0x7f, 0x82, 0xcb, 0x42, 0x54, 0xe7, 0xb6, 0x6f, + 0x4b, 0x83, 0x84, 0x6a, 0xc9, 0x77, 0x3f, 0xb9, 0xc3, 0x9c, 0x6e, 0xc9, + 0x81, 0x8b, 0x06, 0x22, 0x23, 0x09, 0x55, 0x2a, + ], + [ + 0xa5, 0xf9, 0xa5, 0x7e, 0x2c, 0x40, 0xb1, 0x58, 0xd8, 0x16, 0x53, 0x43, + 0xe6, 0x02, 0x65, 0x2c, 0x3e, 0xfc, 0x0b, 0x64, 0xdd, 0xca, 0xee, 0xe5, + 0xce, 0x3d, 0x95, 0x1f, 0xd5, 0x9f, 0x50, 0x08, + ], + [ + 0xdc, 0xa4, 0x64, 0x36, 0x12, 0x7c, 0x47, 0x7e, 0x83, 0x95, 0x0f, 0xa0, + 0x7c, 0xc6, 0x8a, 0x56, 0x6e, 0x54, 0x18, 0x55, 0xad, 0xc2, 0x68, 0x52, + 0x97, 0x87, 0x35, 0x24, 0x88, 0x92, 0x1e, 0x3b, + ], + ], + }, + TestVector { + initial_state: [ + [ + 0x4d, 0x54, 0x31, 0xe6, 0x43, 0x7d, 0x0b, 0x5b, 0xed, 0xbb, 0xcd, 0xaf, + 0x34, 0x5b, 0x86, 0xc4, 0x12, 0x1f, 0xc0, 0x0f, 0xe7, 0xf2, 0x35, 0x73, + 0x42, 0x76, 0xd3, 0x8d, 0x47, 0xf1, 0xe1, 0x11, + ], + [ + 0xdd, 0x0c, 0x7a, 0x1d, 0x81, 0x1c, 0x7d, 0x9c, 0xd4, 0x6d, 0x37, 0x7b, + 0x3f, 0xde, 0xab, 0x3f, 0xb6, 0x79, 0xf3, 0xdc, 0x60, 0x1d, 0x00, 0x82, + 0x85, 0xed, 0xcb, 0xda, 0xe6, 0x9c, 0xe8, 0x3c, + ], + [ + 0x19, 0xe4, 0xaa, 0xc0, 0x35, 0x90, 0x17, 0xec, 0x85, 0xa1, 0x83, 0xd2, + 0x20, 0x53, 0xdb, 0x33, 0xf7, 0x34, 0x76, 0xf2, 0x1a, 0x48, 0x2e, 0xc9, + 0x37, 0x83, 0x65, 0xc8, 0xf7, 0x39, 0x3c, 0x14, + ], + ], + final_state: [ + [ + 0x89, 0x99, 0x8e, 0x5e, 0x0f, 0xa1, 0x95, 0x2a, 0x40, 0xb8, 0xb5, 0x2b, + 0x62, 0xd9, 0x45, 0x70, 0xa4, 0x9a, 0x7d, 0x91, 0xdd, 0x22, 0x6d, 0x69, + 0x2b, 0xc9, 0xb1, 0xa6, 0x13, 0xc9, 0x08, 0x30, + ], + [ + 0xd0, 0xee, 0x44, 0xd9, 0xa9, 0x0d, 0x90, 0x79, 0xef, 0xfb, 0x24, 0x86, + 0xd3, 0xd8, 0x4d, 0x1a, 0x18, 0x4e, 0xdf, 0x14, 0x97, 0x0b, 0xac, 0x36, + 0xc7, 0x48, 0x04, 0xc7, 0xff, 0xbe, 0xe5, 0x0b, + ], + [ + 0x04, 0x81, 0x45, 0xa6, 0x61, 0xce, 0x78, 0x7c, 0x7e, 0x12, 0x2a, 0xc6, + 0x44, 0x7e, 0x9b, 0xa3, 0x93, 0xd3, 0x67, 0xac, 0x05, 0x4f, 0xaa, 0xc5, + 0xb7, 0xb5, 0xf7, 0x19, 0x2b, 0x2f, 0xde, 0x21, + ], + ], + }, + TestVector { + initial_state: [ + [ + 0xe2, 0x88, 0x53, 0x15, 0xeb, 0x46, 0x71, 0x09, 0x8b, 0x79, 0x53, 0x5e, + 0x79, 0x0f, 0xe5, 0x3e, 0x29, 0xfe, 0xf2, 0xb3, 0x76, 0x66, 0x97, 0xac, + 0x32, 0xb4, 0xf4, 0x73, 0xf4, 0x68, 0xa0, 0x08, + ], + [ + 0xe6, 0x23, 0x89, 0xfc, 0x16, 0x57, 0xe0, 0xde, 0xf0, 0xb6, 0x32, 0xc6, + 0xae, 0x25, 0xf9, 0xf7, 0x83, 0xb2, 0x7d, 0xb5, 0x9a, 0x4a, 0x15, 0x3d, + 0x88, 0x2d, 0x2b, 0x21, 0x03, 0x59, 0x65, 0x15, + ], + [ + 0xeb, 0x94, 0x94, 0xc6, 0xd2, 0x27, 0xe2, 0x16, 0x3b, 0x46, 0x99, 0xd9, + 0x91, 0xf4, 0x33, 0xbf, 0x94, 0x86, 0xa7, 0xaf, 0xcf, 0x4a, 0x0d, 0x9c, + 0x73, 0x1e, 0x98, 0x5d, 0x99, 0x58, 0x9c, 0x0b, + ], + ], + final_state: [ + [ + 0xce, 0x2d, 0x1f, 0x8d, 0x67, 0x7f, 0xfb, 0xfd, 0x73, 0xb2, 0x35, 0xe8, + 0xc6, 0x87, 0xfb, 0x42, 0x18, 0x7f, 0x78, 0x81, 0xc3, 0xce, 0x9c, 0x79, + 0x4f, 0x2b, 0xd4, 0x61, 0x40, 0xf7, 0xcc, 0x2a, + ], + [ + 0xaf, 0x82, 0x92, 0x39, 0xb6, 0xd5, 0x5d, 0x5f, 0x43, 0xec, 0x6f, 0x32, + 0xb8, 0x4a, 0x2a, 0x01, 0x1e, 0x64, 0xc5, 0x74, 0x73, 0x9f, 0x87, 0xcb, + 0x47, 0xdc, 0x70, 0x23, 0x83, 0xfa, 0x5a, 0x34, + ], + [ + 0x03, 0xd1, 0x08, 0x5b, 0x21, 0x4c, 0x69, 0xb8, 0xbf, 0xe8, 0x91, 0x02, + 0xbd, 0x61, 0x7e, 0xce, 0x0c, 0x54, 0x00, 0x17, 0x96, 0x40, 0x41, 0x05, + 0xc5, 0x33, 0x30, 0xd2, 0x49, 0x58, 0x1d, 0x0f, + ], + ], + }, + TestVector { + initial_state: [ + [ + 0xb7, 0x38, 0xe8, 0xaa, 0x0a, 0x15, 0x26, 0xa5, 0xbd, 0xef, 0x61, 0x31, + 0x20, 0x37, 0x2e, 0x83, 0x1a, 0x20, 0xda, 0x8a, 0xba, 0x18, 0xd1, 0xdb, + 0xeb, 0xbc, 0x86, 0x2d, 0xed, 0x42, 0x43, 0x1e, + ], + [ + 0x91, 0x47, 0x69, 0x30, 0xe3, 0x38, 0x5c, 0xd3, 0xe3, 0x37, 0x9e, 0x38, + 0x53, 0xd9, 0x34, 0x67, 0xe0, 0x01, 0xaf, 0xa2, 0xfb, 0x8d, 0xc3, 0x43, + 0x6d, 0x75, 0xa4, 0xa6, 0xf2, 0x65, 0x72, 0x10, + ], + [ + 0x4b, 0x19, 0x22, 0x32, 0xec, 0xb9, 0xf0, 0xc0, 0x24, 0x11, 0xe5, 0x25, + 0x96, 0xbc, 0x5e, 0x90, 0x45, 0x7e, 0x74, 0x59, 0x39, 0xff, 0xed, 0xbd, + 0x12, 0x86, 0x3c, 0xe7, 0x1a, 0x02, 0xaf, 0x11, + ], + ], + final_state: [ + [ + 0x5f, 0xcc, 0xd8, 0x7d, 0x2f, 0x66, 0x7b, 0x9e, 0xe3, 0x88, 0xf3, 0x4c, + 0x1c, 0x71, 0x06, 0x87, 0x12, 0x7b, 0xff, 0x5b, 0x02, 0x21, 0xfd, 0x8a, + 0x52, 0x94, 0x88, 0x66, 0x91, 0x57, 0x94, 0x2b, + ], + [ + 0x89, 0x62, 0xb5, 0x80, 0x30, 0xaa, 0x63, 0x52, 0xd9, 0x90, 0xf3, 0xb9, + 0x00, 0x1c, 0xcb, 0xe8, 0x8a, 0x56, 0x27, 0x58, 0x1b, 0xbf, 0xb9, 0x01, + 0xac, 0x4a, 0x6a, 0xed, 0xfa, 0xe5, 0xc6, 0x34, + ], + [ + 0x7c, 0x0b, 0x76, 0x59, 0xf2, 0x4c, 0x98, 0xaf, 0x31, 0x0e, 0x3e, 0x8d, + 0x82, 0xb5, 0xf3, 0x99, 0x43, 0x3c, 0xdd, 0xa5, 0x8f, 0x48, 0xd9, 0xef, + 0x8d, 0xd0, 0xca, 0x86, 0x42, 0x72, 0xda, 0x3f, + ], + ], + }, + TestVector { + initial_state: [ + [ + 0x7b, 0x41, 0x7a, 0xdb, 0x63, 0xb3, 0x71, 0x22, 0xa5, 0xbf, 0x62, 0xd2, + 0x6f, 0x1e, 0x7f, 0x26, 0x8f, 0xb8, 0x6b, 0x12, 0xb5, 0x6d, 0xa9, 0xc3, + 0x82, 0x85, 0x7d, 0xee, 0xcc, 0x40, 0xa9, 0x0d, + ], + [ + 0x5e, 0x29, 0x35, 0x39, 0x71, 0xb3, 0x49, 0x94, 0xb6, 0x21, 0xb0, 0xb2, + 0x61, 0xae, 0xb3, 0x78, 0x6d, 0xd9, 0x84, 0xd5, 0x67, 0xdb, 0x28, 0x57, + 0xb9, 0x27, 0xb7, 0xfa, 0xe2, 0xdb, 0x58, 0x31, + ], + [ + 0x05, 0x41, 0x5d, 0x46, 0x42, 0x78, 0x9d, 0x38, 0xf5, 0x0b, 0x8d, 0xbc, + 0xc1, 0x29, 0xca, 0xb3, 0xd1, 0x7d, 0x19, 0xf3, 0x35, 0x5b, 0xcf, 0x73, + 0xce, 0xcb, 0x8c, 0xb8, 0xa5, 0xda, 0x01, 0x30, + ], + ], + final_state: [ + [ + 0x9e, 0xe1, 0xad, 0xdc, 0x6f, 0x64, 0xda, 0xb6, 0xac, 0xdc, 0xea, 0xec, + 0xc1, 0xfb, 0xbc, 0x8a, 0x32, 0x45, 0x8e, 0x49, 0xc1, 0x9e, 0x79, 0x85, + 0x56, 0xc6, 0x4b, 0x59, 0x8b, 0xa6, 0xff, 0x14, + ], + [ + 0x42, 0xcc, 0x10, 0x36, 0x4f, 0xd6, 0x59, 0xc3, 0xcc, 0x77, 0x25, 0x84, + 0xdb, 0x91, 0xc4, 0x9a, 0x38, 0x67, 0x2b, 0x69, 0x24, 0x93, 0xb9, 0x07, + 0x5f, 0x16, 0x53, 0xca, 0x1f, 0xae, 0x1c, 0x33, + ], + [ + 0xff, 0x41, 0xf3, 0x51, 0x80, 0x14, 0x56, 0xc4, 0x96, 0x0b, 0x39, 0x3a, + 0xff, 0xa8, 0x62, 0x13, 0xa7, 0xea, 0xc0, 0x6c, 0x66, 0x21, 0x3b, 0x45, + 0xc3, 0xb5, 0x0e, 0xc6, 0x48, 0xd6, 0x7d, 0x0d, + ], + ], + }, + TestVector { + initial_state: [ + [ + 0x71, 0x52, 0xf1, 0x39, 0x36, 0xa2, 0x70, 0x57, 0x26, 0x70, 0xdc, 0x82, + 0xd3, 0x90, 0x26, 0xc6, 0xcb, 0x4c, 0xd4, 0xb0, 0xf7, 0xf5, 0xaa, 0x2a, + 0x4f, 0x5a, 0x53, 0x41, 0xec, 0x5d, 0xd7, 0x15, + ], + [ + 0x40, 0x6f, 0x2f, 0xdd, 0x2a, 0xfa, 0x73, 0x3f, 0x5f, 0x64, 0x1c, 0x8c, + 0x21, 0x86, 0x2a, 0x1b, 0xaf, 0xce, 0x26, 0x09, 0xd9, 0xee, 0xcf, 0xa1, + 0x58, 0xcf, 0xb5, 0xcd, 0x79, 0xf8, 0x80, 0x08, + ], + [ + 0xe2, 0x15, 0xdc, 0x7d, 0x96, 0x57, 0xba, 0xd3, 0xfb, 0x88, 0xb0, 0x1e, + 0x99, 0x38, 0x44, 0x54, 0x36, 0x24, 0xc2, 0x5f, 0xa9, 0x59, 0xcc, 0x97, + 0x48, 0x9c, 0xe7, 0x57, 0x45, 0x82, 0x4b, 0x37, + ], + ], + final_state: [ + [ + 0x63, 0x09, 0x15, 0xd7, 0xd8, 0x25, 0xeb, 0x74, 0x37, 0xb0, 0xe4, 0x6e, + 0x37, 0x28, 0x6a, 0x88, 0xb3, 0x89, 0xdc, 0x69, 0x85, 0x93, 0x07, 0x11, + 0x6d, 0x34, 0x7b, 0x98, 0xca, 0x14, 0x5c, 0x31, + ], + [ + 0xaa, 0x58, 0x1b, 0xae, 0xe9, 0x4f, 0xb5, 0x46, 0xa7, 0x61, 0xf1, 0x7a, + 0x5d, 0x6e, 0xaa, 0x70, 0x29, 0x52, 0x78, 0x42, 0xf3, 0x1c, 0x39, 0x87, + 0xb8, 0x68, 0xed, 0x7d, 0xaf, 0xfd, 0xb5, 0x34, + ], + [ + 0x7d, 0xc1, 0x17, 0xb3, 0x39, 0x1a, 0xab, 0x85, 0xde, 0x9f, 0x42, 0x4d, + 0xb6, 0x65, 0x1e, 0x00, 0x45, 0xab, 0x79, 0x98, 0xf2, 0x8e, 0x54, 0x10, + 0x15, 0x35, 0x90, 0x61, 0x99, 0xce, 0x1f, 0x1a, + ], + ], + }, + TestVector { + initial_state: [ + [ + 0x86, 0x8c, 0x53, 0x23, 0x9c, 0xfb, 0xdf, 0x73, 0xca, 0xec, 0x65, 0x60, + 0x40, 0x37, 0x31, 0x4f, 0xaa, 0xce, 0xb5, 0x62, 0x18, 0xc6, 0xbd, 0x30, + 0xf8, 0x37, 0x4a, 0xc1, 0x33, 0x86, 0x79, 0x3f, + ], + [ + 0x21, 0xa9, 0xfb, 0x80, 0xad, 0x03, 0xbc, 0x0c, 0xda, 0x4a, 0x44, 0x94, + 0x6c, 0x00, 0xe1, 0xb1, 0xa1, 0xdf, 0x0e, 0x5b, 0x87, 0xb5, 0xbe, 0xce, + 0x47, 0x7a, 0x70, 0x96, 0x49, 0xe9, 0x50, 0x06, + ], + [ + 0x04, 0x91, 0x39, 0x48, 0x25, 0x64, 0xf1, 0x85, 0xc7, 0x90, 0x0e, 0x83, + 0xc7, 0x38, 0x07, 0x0a, 0xf6, 0x55, 0x6d, 0xf6, 0xed, 0x4b, 0x4d, 0xdd, + 0x3d, 0x9a, 0x69, 0xf5, 0x33, 0x57, 0xd7, 0x36, + ], + ], + final_state: [ + [ + 0x6a, 0x5a, 0x19, 0x19, 0xa4, 0x49, 0xa5, 0xe0, 0x29, 0x71, 0x1f, 0x48, + 0x8a, 0xdb, 0xd6, 0xb0, 0x3e, 0x5c, 0x92, 0x7b, 0x6f, 0x9d, 0x9d, 0x35, + 0xc5, 0xb3, 0xcc, 0xeb, 0x76, 0x60, 0x52, 0x03, + ], + [ + 0x80, 0x47, 0x5b, 0x46, 0x89, 0x59, 0x61, 0x47, 0xab, 0x2a, 0xdf, 0x01, + 0x73, 0xdb, 0x28, 0x9b, 0x3a, 0x26, 0xa1, 0x04, 0x84, 0x21, 0x73, 0xe8, + 0x8b, 0xdb, 0xfe, 0xc0, 0x4a, 0x28, 0x67, 0x1b, + ], + [ + 0x1e, 0xf3, 0xc8, 0xd0, 0xf5, 0x44, 0x44, 0xf5, 0x55, 0xb1, 0x5f, 0x7b, + 0xc9, 0xfa, 0x4f, 0xfa, 0x0f, 0x56, 0x7c, 0x0f, 0x19, 0xac, 0x7d, 0x0f, + 0xf9, 0x44, 0xfd, 0x36, 0x42, 0x6e, 0x32, 0x3a, + ], + ], + }, + TestVector { + initial_state: [ + [ + 0x7d, 0x4f, 0x5c, 0xcb, 0x01, 0x64, 0x3c, 0x31, 0xdb, 0x84, 0x5e, 0xec, + 0xd5, 0xd6, 0x3d, 0xc1, 0x6a, 0x95, 0xe3, 0x02, 0x5b, 0x97, 0x92, 0xff, + 0xf7, 0xf2, 0x44, 0xfc, 0x71, 0x62, 0x69, 0x39, + ], + [ + 0x26, 0xd6, 0x2e, 0x95, 0x96, 0xfa, 0x82, 0x5c, 0x6b, 0xf2, 0x1a, 0xff, + 0x9e, 0x68, 0x62, 0x5a, 0x19, 0x24, 0x40, 0xea, 0x06, 0x82, 0x81, 0x23, + 0xd9, 0x78, 0x84, 0x80, 0x6f, 0x15, 0xfa, 0x08, + ], + [ + 0xd9, 0x52, 0x75, 0x4a, 0x23, 0x64, 0xb6, 0x66, 0xff, 0xc3, 0x0f, 0xdb, + 0x01, 0x47, 0x86, 0xda, 0x3a, 0x61, 0x28, 0xae, 0xf7, 0x84, 0xa6, 0x46, + 0x10, 0xa8, 0x9d, 0x1a, 0x70, 0x99, 0x21, 0x2d, + ], + ], + final_state: [ + [ + 0x1b, 0x4a, 0xc9, 0xbe, 0xf5, 0x6b, 0xdb, 0x6f, 0xb4, 0x2d, 0x3e, 0x3c, + 0xd3, 0xa2, 0xac, 0x70, 0xa4, 0xc4, 0x0c, 0x42, 0x5b, 0x0b, 0xd6, 0x67, + 0x9c, 0xa5, 0x7b, 0x30, 0x7e, 0xf1, 0xd4, 0x2f, + ], + [ + 0x1a, 0x2e, 0xf4, 0x11, 0x94, 0xaa, 0xa2, 0x34, 0x32, 0xe0, 0x86, 0xed, + 0x8a, 0xdb, 0xd1, 0xde, 0xec, 0x3c, 0x7c, 0xb3, 0x96, 0xde, 0x35, 0xba, + 0xe9, 0x5a, 0xaf, 0x5a, 0x08, 0xa0, 0xec, 0x36, + ], + [ + 0x68, 0xeb, 0x80, 0xc7, 0x3e, 0x2c, 0xcb, 0xde, 0xe1, 0xba, 0x71, 0x24, + 0x77, 0x61, 0xd5, 0xb5, 0xec, 0xc6, 0x20, 0xe6, 0xe4, 0x8e, 0x00, 0x3b, + 0x02, 0x3d, 0x9f, 0x55, 0x61, 0x66, 0x2f, 0x20, + ], + ], + }, + ] + } + + pub(crate) fn hash() -> Vec { + use HashTestVector as TestVector; + + // From https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/orchard_poseidon/hash/fp.py + vec![ + TestVector { + input: [ + [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ], + [ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ], + ], + output: [ + 0x83, 0x58, 0xd7, 0x11, 0xa0, 0x32, 0x9d, 0x38, 0xbe, 0xcd, 0x54, 0xfb, 0xa7, + 0xc2, 0x83, 0xed, 0x3e, 0x08, 0x9a, 0x39, 0xc9, 0x1b, 0x6a, 0x9d, 0x10, 0xef, + 0xb0, 0x2b, 0xc3, 0xf1, 0x2f, 0x06, + ], + }, + TestVector { + input: [ + [ + 0x5c, 0x7a, 0x8f, 0x73, 0xad, 0xfc, 0x70, 0xfb, 0x3f, 0x13, 0x94, 0x49, + 0xac, 0x6b, 0x57, 0x07, 0x4c, 0x4d, 0x6e, 0x66, 0xb1, 0x64, 0x93, 0x9d, + 0xaf, 0xfa, 0x2e, 0xf6, 0xee, 0x69, 0x21, 0x08, + ], + [ + 0x1a, 0xdd, 0x86, 0xb3, 0xf2, 0xe1, 0xbd, 0xa6, 0x2a, 0x5d, 0x2e, 0x0e, + 0x98, 0x2b, 0x77, 0xe6, 0xb0, 0xef, 0x9c, 0xa3, 0xf2, 0x49, 0x88, 0xc7, + 0xb3, 0x53, 0x42, 0x01, 0xcf, 0xb1, 0xcd, 0x0d, + ], + ], + output: [ + 0xdb, 0x26, 0x75, 0xff, 0x3e, 0xf8, 0xfe, 0x30, 0xc4, 0xd5, 0xde, 0x61, 0xca, + 0xc0, 0x2a, 0x8e, 0xf1, 0xa0, 0x85, 0x23, 0xbe, 0x92, 0x39, 0x4b, 0x79, 0xd2, + 0x67, 0x26, 0x30, 0x3b, 0xe6, 0x03, + ], + }, + TestVector { + input: [ + [ + 0xbd, 0x69, 0xb8, 0x25, 0x32, 0xb6, 0x94, 0x0f, 0xf2, 0x59, 0x0f, 0x67, + 0x9b, 0xa9, 0xc7, 0x27, 0x1f, 0xe0, 0x1f, 0x7e, 0x9c, 0x8e, 0x36, 0xd6, + 0xa5, 0xe2, 0x9d, 0x4e, 0x30, 0xa7, 0x35, 0x14, + ], + [ + 0xbc, 0x50, 0x98, 0x42, 0x55, 0xd6, 0xaf, 0xbe, 0x9e, 0xf9, 0x28, 0x48, + 0xed, 0x5a, 0xc0, 0x08, 0x62, 0xc2, 0xfa, 0x7b, 0x2f, 0xec, 0xbc, 0xb6, + 0x4b, 0x69, 0x68, 0x91, 0x2a, 0x63, 0x81, 0x0e, + ], + ], + output: [ + 0xf5, 0x12, 0x1d, 0x1e, 0x1d, 0x5c, 0xfe, 0x8d, 0xa8, 0x96, 0xac, 0x0f, 0x9c, + 0x18, 0x3d, 0x76, 0x00, 0x31, 0xf6, 0xef, 0x8c, 0x7a, 0x41, 0xe6, 0x5e, 0xb0, + 0x07, 0xcd, 0xdc, 0x1d, 0x14, 0x3d, + ], + }, + TestVector { + input: [ + [ + 0x3d, 0xc1, 0x66, 0xd5, 0x6a, 0x1d, 0x62, 0xf5, 0xa8, 0xd7, 0x55, 0x1d, + 0xb5, 0xfd, 0x93, 0x13, 0xe8, 0xc7, 0x20, 0x3d, 0x99, 0x6a, 0xf7, 0xd4, + 0x77, 0x08, 0x37, 0x56, 0xd5, 0x9a, 0xf8, 0x0d, + ], + [ + 0x05, 0xa7, 0x45, 0xf4, 0x5d, 0x7f, 0xf6, 0xdb, 0x10, 0xbc, 0x67, 0xfd, + 0xf0, 0xf0, 0x3e, 0xbf, 0x81, 0x30, 0xab, 0x33, 0x36, 0x26, 0x97, 0xb0, + 0xe4, 0xe4, 0xc7, 0x63, 0xcc, 0xb8, 0xf6, 0x36, + ], + ], + output: [ + 0xa4, 0x16, 0xa5, 0xe7, 0x13, 0x51, 0x36, 0xa0, 0x50, 0x56, 0x90, 0x00, 0x58, + 0xfa, 0x50, 0xbf, 0x18, 0x6a, 0xd7, 0x33, 0x90, 0xac, 0xe6, 0x32, 0x3d, 0x8d, + 0x81, 0xaa, 0x8a, 0xdb, 0xd4, 0x11, + ], + }, + TestVector { + input: [ + [ + 0x49, 0x5c, 0x22, 0x2f, 0x7f, 0xba, 0x1e, 0x31, 0xde, 0xfa, 0x3d, 0x5a, + 0x57, 0xef, 0xc2, 0xe1, 0xe9, 0xb0, 0x1a, 0x03, 0x55, 0x87, 0xd5, 0xfb, + 0x1a, 0x38, 0xe0, 0x1d, 0x94, 0x90, 0x3d, 0x3c, + ], + [ + 0x3d, 0x0a, 0xd3, 0x36, 0x1f, 0xec, 0x09, 0x77, 0x90, 0xd9, 0xbe, 0x0e, + 0x42, 0x98, 0x8d, 0x7d, 0x25, 0xc9, 0xa1, 0x38, 0xf4, 0x9b, 0x1a, 0x53, + 0x7e, 0xdc, 0xf0, 0x4b, 0xe3, 0x4a, 0x98, 0x11, + ], + ], + output: [ + 0x1a, 0xba, 0xf3, 0x06, 0xfe, 0xd0, 0x5f, 0xa8, 0x92, 0x84, 0x8c, 0x49, 0xf6, + 0xba, 0x10, 0x41, 0x63, 0x43, 0x3f, 0x3f, 0x63, 0x31, 0x08, 0xa1, 0x3b, 0xc1, + 0x5b, 0x2a, 0x1d, 0x55, 0xd4, 0x0c, + ], + }, + TestVector { + input: [ + [ + 0xa4, 0xaf, 0x9d, 0xb6, 0xd2, 0x7b, 0x50, 0x72, 0x83, 0x5f, 0x0c, 0x3e, + 0x88, 0x39, 0x5e, 0xd7, 0xa4, 0x1b, 0x00, 0x52, 0xad, 0x80, 0x84, 0xa8, + 0xb9, 0xda, 0x94, 0x8d, 0x32, 0x0d, 0xad, 0x16, + ], + [ + 0x4d, 0x54, 0x31, 0xe6, 0x43, 0x7d, 0x0b, 0x5b, 0xed, 0xbb, 0xcd, 0xaf, + 0x34, 0x5b, 0x86, 0xc4, 0x12, 0x1f, 0xc0, 0x0f, 0xe7, 0xf2, 0x35, 0x73, + 0x42, 0x76, 0xd3, 0x8d, 0x47, 0xf1, 0xe1, 0x11, + ], + ], + output: [ + 0x04, 0xa1, 0x8a, 0xeb, 0x59, 0x3f, 0x79, 0x0b, 0x76, 0xa3, 0x99, 0xb7, 0xc1, + 0x52, 0x8a, 0xcd, 0xed, 0xe9, 0x3b, 0x3b, 0x2c, 0x49, 0x6b, 0xd7, 0x1b, 0xd5, + 0x87, 0xcb, 0xd7, 0xcf, 0xdf, 0x35, + ], + }, + TestVector { + input: [ + [ + 0xdd, 0x0c, 0x7a, 0x1d, 0x81, 0x1c, 0x7d, 0x9c, 0xd4, 0x6d, 0x37, 0x7b, + 0x3f, 0xde, 0xab, 0x3f, 0xb6, 0x79, 0xf3, 0xdc, 0x60, 0x1d, 0x00, 0x82, + 0x85, 0xed, 0xcb, 0xda, 0xe6, 0x9c, 0xe8, 0x3c, + ], + [ + 0x19, 0xe4, 0xaa, 0xc0, 0x35, 0x90, 0x17, 0xec, 0x85, 0xa1, 0x83, 0xd2, + 0x20, 0x53, 0xdb, 0x33, 0xf7, 0x34, 0x76, 0xf2, 0x1a, 0x48, 0x2e, 0xc9, + 0x37, 0x83, 0x65, 0xc8, 0xf7, 0x39, 0x3c, 0x14, + ], + ], + output: [ + 0x11, 0x03, 0xcc, 0xdc, 0x00, 0xd0, 0xf3, 0x5f, 0x65, 0x83, 0x14, 0x11, 0x6b, + 0xc2, 0xbc, 0xd9, 0x43, 0x74, 0xa9, 0x1f, 0xf9, 0x87, 0x7e, 0x70, 0x66, 0x33, + 0x29, 0x04, 0x2b, 0xd2, 0xf6, 0x1f, + ], + }, + TestVector { + input: [ + [ + 0xe2, 0x88, 0x53, 0x15, 0xeb, 0x46, 0x71, 0x09, 0x8b, 0x79, 0x53, 0x5e, + 0x79, 0x0f, 0xe5, 0x3e, 0x29, 0xfe, 0xf2, 0xb3, 0x76, 0x66, 0x97, 0xac, + 0x32, 0xb4, 0xf4, 0x73, 0xf4, 0x68, 0xa0, 0x08, + ], + [ + 0xe6, 0x23, 0x89, 0xfc, 0x16, 0x57, 0xe0, 0xde, 0xf0, 0xb6, 0x32, 0xc6, + 0xae, 0x25, 0xf9, 0xf7, 0x83, 0xb2, 0x7d, 0xb5, 0x9a, 0x4a, 0x15, 0x3d, + 0x88, 0x2d, 0x2b, 0x21, 0x03, 0x59, 0x65, 0x15, + ], + ], + output: [ + 0xf8, 0xf8, 0xc6, 0x5f, 0x43, 0x7c, 0x45, 0xbe, 0xac, 0x11, 0xeb, 0x7d, 0x9e, + 0x47, 0x58, 0x6d, 0x87, 0x9a, 0xfd, 0x6f, 0x93, 0x04, 0x35, 0xbe, 0x0c, 0x01, + 0xd1, 0x9c, 0x89, 0x5b, 0x8d, 0x10, + ], + }, + TestVector { + input: [ + [ + 0xeb, 0x94, 0x94, 0xc6, 0xd2, 0x27, 0xe2, 0x16, 0x3b, 0x46, 0x99, 0xd9, + 0x91, 0xf4, 0x33, 0xbf, 0x94, 0x86, 0xa7, 0xaf, 0xcf, 0x4a, 0x0d, 0x9c, + 0x73, 0x1e, 0x98, 0x5d, 0x99, 0x58, 0x9c, 0x0b, + ], + [ + 0xb7, 0x38, 0xe8, 0xaa, 0x0a, 0x15, 0x26, 0xa5, 0xbd, 0xef, 0x61, 0x31, + 0x20, 0x37, 0x2e, 0x83, 0x1a, 0x20, 0xda, 0x8a, 0xba, 0x18, 0xd1, 0xdb, + 0xeb, 0xbc, 0x86, 0x2d, 0xed, 0x42, 0x43, 0x1e, + ], + ], + output: [ + 0x5a, 0xeb, 0x48, 0x96, 0x21, 0xb0, 0x2e, 0x8e, 0x69, 0x27, 0xb9, 0x4f, 0xd2, + 0x9a, 0x61, 0x01, 0x83, 0xdf, 0x7f, 0x42, 0x87, 0xe9, 0xcb, 0xf1, 0xcc, 0xc8, + 0x81, 0xd7, 0xd0, 0xb7, 0x38, 0x27, + ], + }, + TestVector { + input: [ + [ + 0x91, 0x47, 0x69, 0x30, 0xe3, 0x38, 0x5c, 0xd3, 0xe3, 0x37, 0x9e, 0x38, + 0x53, 0xd9, 0x34, 0x67, 0xe0, 0x01, 0xaf, 0xa2, 0xfb, 0x8d, 0xc3, 0x43, + 0x6d, 0x75, 0xa4, 0xa6, 0xf2, 0x65, 0x72, 0x10, + ], + [ + 0x4b, 0x19, 0x22, 0x32, 0xec, 0xb9, 0xf0, 0xc0, 0x24, 0x11, 0xe5, 0x25, + 0x96, 0xbc, 0x5e, 0x90, 0x45, 0x7e, 0x74, 0x59, 0x39, 0xff, 0xed, 0xbd, + 0x12, 0x86, 0x3c, 0xe7, 0x1a, 0x02, 0xaf, 0x11, + ], + ], + output: [ + 0xb0, 0x14, 0x47, 0x20, 0xf5, 0xf2, 0xa2, 0x5d, 0x49, 0x2a, 0x50, 0x4e, 0xc0, + 0x73, 0x7f, 0x09, 0x7e, 0xd8, 0x52, 0x17, 0x4f, 0x55, 0xf5, 0x86, 0x30, 0x91, + 0x30, 0x6c, 0x1a, 0xf2, 0x00, 0x35, + ], + }, + TestVector { + input: [ + [ + 0x7b, 0x41, 0x7a, 0xdb, 0x63, 0xb3, 0x71, 0x22, 0xa5, 0xbf, 0x62, 0xd2, + 0x6f, 0x1e, 0x7f, 0x26, 0x8f, 0xb8, 0x6b, 0x12, 0xb5, 0x6d, 0xa9, 0xc3, + 0x82, 0x85, 0x7d, 0xee, 0xcc, 0x40, 0xa9, 0x0d, + ], + [ + 0x5e, 0x29, 0x35, 0x39, 0x71, 0xb3, 0x49, 0x94, 0xb6, 0x21, 0xb0, 0xb2, + 0x61, 0xae, 0xb3, 0x78, 0x6d, 0xd9, 0x84, 0xd5, 0x67, 0xdb, 0x28, 0x57, + 0xb9, 0x27, 0xb7, 0xfa, 0xe2, 0xdb, 0x58, 0x31, + ], + ], + output: [ + 0xbb, 0xbe, 0xb7, 0x42, 0xd6, 0xe7, 0xc0, 0x1a, 0xdb, 0xf4, 0xd3, 0x85, 0x5e, + 0x35, 0xfe, 0xc4, 0x62, 0x04, 0x30, 0x89, 0xc1, 0x8b, 0xa8, 0x02, 0x90, 0x64, + 0x7b, 0xb0, 0xe5, 0x81, 0xad, 0x11, + ], + }, + ] + } +} + +pub(crate) mod fq { + use super::*; + + pub(crate) fn permute() -> Vec { + use PermuteTestVector as TestVector; + + // From https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/orchard_poseidon/permute/fq.py + vec![ + TestVector { + initial_state: [ + [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ], + [ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ], + [ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ], + ], + final_state: [ + [ + 0x59, 0xbe, 0xbe, 0x13, 0xa8, 0x8e, 0xb0, 0x0e, 0xc6, 0x36, 0xd3, 0x3d, + 0x97, 0xd1, 0x43, 0x4d, 0xf7, 0x2f, 0x8f, 0x2f, 0xf2, 0x74, 0xdd, 0xed, + 0x7c, 0x2f, 0x94, 0xdb, 0x4c, 0x1f, 0x5a, 0x31, + ], + [ + 0xf1, 0x65, 0xa1, 0x1e, 0xe6, 0x26, 0xf1, 0xf9, 0x98, 0x21, 0xbd, 0x7b, + 0xeb, 0xe0, 0x3e, 0x41, 0x48, 0xaa, 0x13, 0xdd, 0xe0, 0xde, 0x2a, 0x64, + 0xde, 0x2b, 0x64, 0xd7, 0xf2, 0x75, 0xe4, 0x3b, + ], + [ + 0xd9, 0xa0, 0x7b, 0x2a, 0x37, 0x42, 0xd5, 0x14, 0xa0, 0x3f, 0x42, 0xe0, + 0xd4, 0xbf, 0x19, 0x50, 0x60, 0xea, 0xd8, 0x20, 0x24, 0xdb, 0x7f, 0x11, + 0x68, 0x71, 0x53, 0xe9, 0xec, 0x8a, 0xab, 0x25, + ], + ], + }, + TestVector { + initial_state: [ + [ + 0x5c, 0x7a, 0x8f, 0x73, 0x79, 0x42, 0x57, 0x08, 0x7e, 0x63, 0x4c, 0x49, + 0xac, 0x6b, 0x57, 0x07, 0x4c, 0x4d, 0x6e, 0x66, 0xb1, 0x64, 0x93, 0x9d, + 0xaf, 0xfa, 0x2e, 0xf6, 0xee, 0x69, 0x21, 0x08, + ], + [ + 0x1a, 0xdd, 0x86, 0xb3, 0x8a, 0x6d, 0x8a, 0xc0, 0xa6, 0xfd, 0x9e, 0x0d, + 0x98, 0x2b, 0x77, 0xe6, 0xb0, 0xef, 0x9c, 0xa3, 0xf2, 0x49, 0x88, 0xc7, + 0xb3, 0x53, 0x42, 0x01, 0xcf, 0xb1, 0xcd, 0x0d, + ], + [ + 0xbd, 0x69, 0xb8, 0x25, 0xca, 0x41, 0x61, 0x29, 0x6e, 0xfa, 0x7f, 0x66, + 0x9b, 0xa9, 0xc7, 0x27, 0x1f, 0xe0, 0x1f, 0x7e, 0x9c, 0x8e, 0x36, 0xd6, + 0xa5, 0xe2, 0x9d, 0x4e, 0x30, 0xa7, 0x35, 0x14, + ], + ], + final_state: [ + [ + 0xcd, 0x8f, 0x83, 0x92, 0xdf, 0xc7, 0x72, 0x8f, 0x5f, 0x6d, 0x85, 0x4c, + 0xc4, 0x60, 0x70, 0xa4, 0x0c, 0xba, 0x7a, 0x80, 0x33, 0x2d, 0xdc, 0x65, + 0xcb, 0xe2, 0x4a, 0xc3, 0xde, 0x23, 0x5e, 0x0e, + ], + [ + 0xc2, 0x53, 0xe5, 0x95, 0x3c, 0x83, 0xaa, 0x8a, 0x23, 0xd4, 0xd5, 0x58, + 0x7f, 0xbf, 0xc0, 0x7e, 0x78, 0x33, 0x1f, 0x7d, 0x46, 0xd1, 0xf5, 0xfa, + 0x54, 0x4d, 0x6a, 0xbd, 0xd4, 0x24, 0x1b, 0x27, + ], + [ + 0xb8, 0xc8, 0x33, 0x9b, 0xf9, 0x47, 0x2a, 0xd1, 0xc5, 0x27, 0xb7, 0x5e, + 0x99, 0x81, 0x2c, 0xa9, 0x1c, 0x5c, 0xbd, 0x7f, 0x4d, 0x46, 0x6f, 0x1a, + 0x13, 0x5a, 0x67, 0x50, 0x66, 0x76, 0x64, 0x34, + ], + ], + }, + TestVector { + initial_state: [ + [ + 0xbc, 0x50, 0x98, 0x42, 0xb9, 0xa7, 0x62, 0xe5, 0x58, 0xea, 0x51, 0x47, + 0xed, 0x5a, 0xc0, 0x08, 0x62, 0xc2, 0xfa, 0x7b, 0x2f, 0xec, 0xbc, 0xb6, + 0x4b, 0x69, 0x68, 0x91, 0x2a, 0x63, 0x81, 0x0e, + ], + [ + 0x3d, 0xc1, 0x66, 0xd5, 0x6a, 0x1d, 0x62, 0xf5, 0xa8, 0xd7, 0x55, 0x1d, + 0xb5, 0xfd, 0x93, 0x13, 0xe8, 0xc7, 0x20, 0x3d, 0x99, 0x6a, 0xf7, 0xd4, + 0x77, 0x08, 0x37, 0x56, 0xd5, 0x9a, 0xf8, 0x0d, + ], + [ + 0x05, 0xa7, 0x45, 0xf4, 0x29, 0xc5, 0xdc, 0xe8, 0x4e, 0x0c, 0x20, 0xfd, + 0xf0, 0xf0, 0x3e, 0xbf, 0x81, 0x30, 0xab, 0x33, 0x36, 0x26, 0x97, 0xb0, + 0xe4, 0xe4, 0xc7, 0x63, 0xcc, 0xb8, 0xf6, 0x36, + ], + ], + final_state: [ + [ + 0xa3, 0x5b, 0x56, 0x64, 0x62, 0x4a, 0x78, 0x49, 0x9e, 0xce, 0xe0, 0xfa, + 0x05, 0x18, 0x79, 0xa2, 0xad, 0x1c, 0xa4, 0x53, 0x9b, 0x5b, 0xd2, 0xa4, + 0x67, 0xe2, 0xea, 0x8d, 0x4e, 0x2d, 0x40, 0x08, + ], + [ + 0x36, 0xc2, 0x21, 0x7a, 0xe5, 0x75, 0xaa, 0xf8, 0xf2, 0x54, 0xd6, 0xe0, + 0x60, 0x10, 0x1c, 0xdc, 0x85, 0xaa, 0x39, 0x3c, 0x09, 0x54, 0x3b, 0xf0, + 0x48, 0x99, 0x7a, 0x7c, 0x5c, 0xb9, 0x27, 0x02, + ], + [ + 0x38, 0x12, 0x7e, 0xbe, 0xaf, 0x11, 0xae, 0x56, 0x64, 0x47, 0x14, 0x05, + 0x29, 0x3b, 0x60, 0x1c, 0x43, 0xf0, 0x3e, 0x8e, 0x40, 0x78, 0x11, 0x3a, + 0x63, 0x37, 0x10, 0x11, 0x9f, 0x9a, 0x1b, 0x1f, + ], + ], + }, + TestVector { + initial_state: [ + [ + 0x49, 0x5c, 0x22, 0x2f, 0x7f, 0xba, 0x1e, 0x31, 0xde, 0xfa, 0x3d, 0x5a, + 0x57, 0xef, 0xc2, 0xe1, 0xe9, 0xb0, 0x1a, 0x03, 0x55, 0x87, 0xd5, 0xfb, + 0x1a, 0x38, 0xe0, 0x1d, 0x94, 0x90, 0x3d, 0x3c, + ], + [ + 0x3d, 0x0a, 0xd3, 0x36, 0xeb, 0x31, 0xf0, 0x83, 0xce, 0x29, 0x77, 0x0e, + 0x42, 0x98, 0x8d, 0x7d, 0x25, 0xc9, 0xa1, 0x38, 0xf4, 0x9b, 0x1a, 0x53, + 0x7e, 0xdc, 0xf0, 0x4b, 0xe3, 0x4a, 0x98, 0x11, + ], + [ + 0xa4, 0xaf, 0x9d, 0xb6, 0x36, 0x4d, 0x03, 0x99, 0x3d, 0x50, 0x35, 0x3d, + 0x88, 0x39, 0x5e, 0xd7, 0xa4, 0x1b, 0x00, 0x52, 0xad, 0x80, 0x84, 0xa8, + 0xb9, 0xda, 0x94, 0x8d, 0x32, 0x0d, 0xad, 0x16, + ], + ], + final_state: [ + [ + 0x5c, 0x76, 0x63, 0x4f, 0xc7, 0x1a, 0x43, 0x7a, 0x3c, 0xc7, 0x89, 0x9d, + 0xb3, 0xb5, 0x1c, 0xea, 0xe6, 0x9a, 0xd0, 0x0b, 0x14, 0x96, 0xa6, 0x80, + 0x32, 0xd3, 0x83, 0x17, 0x37, 0x08, 0x79, 0x18, + ], + [ + 0xd3, 0xcc, 0x4e, 0xab, 0x45, 0x0a, 0xac, 0xc4, 0x5f, 0x9b, 0x32, 0x7e, + 0xbb, 0x9a, 0x50, 0xb8, 0x59, 0xca, 0x08, 0x0e, 0x10, 0x6b, 0x54, 0xc3, + 0x1c, 0x09, 0xc2, 0x1e, 0x1d, 0x79, 0xdf, 0x2a, + ], + [ + 0x09, 0x1e, 0x8f, 0x1e, 0xe9, 0xba, 0x00, 0xa3, 0xe3, 0xcf, 0x85, 0xd5, + 0xd6, 0x95, 0x3d, 0x25, 0xe0, 0x1e, 0x8b, 0xdb, 0x43, 0xde, 0x0f, 0xb7, + 0x30, 0x82, 0x4e, 0x6a, 0x8f, 0x69, 0x7e, 0x1c, + ], + ], + }, + TestVector { + initial_state: [ + [ + 0x4d, 0x54, 0x31, 0xe6, 0xdb, 0x08, 0xd8, 0x74, 0x69, 0x5c, 0x3e, 0xaf, + 0x34, 0x5b, 0x86, 0xc4, 0x12, 0x1f, 0xc0, 0x0f, 0xe7, 0xf2, 0x35, 0x73, + 0x42, 0x76, 0xd3, 0x8d, 0x47, 0xf1, 0xe1, 0x11, + ], + [ + 0xdd, 0x0c, 0x7a, 0x1d, 0xe5, 0xed, 0x2f, 0xc3, 0x8e, 0x5e, 0x60, 0x7a, + 0x3f, 0xde, 0xab, 0x3f, 0xb6, 0x79, 0xf3, 0xdc, 0x60, 0x1d, 0x00, 0x82, + 0x85, 0xed, 0xcb, 0xda, 0xe6, 0x9c, 0xe8, 0x3c, + ], + [ + 0x19, 0xe4, 0xaa, 0xc0, 0xcd, 0x1b, 0xe4, 0x05, 0x02, 0x42, 0xf4, 0xd1, + 0x20, 0x53, 0xdb, 0x33, 0xf7, 0x34, 0x76, 0xf2, 0x1a, 0x48, 0x2e, 0xc9, + 0x37, 0x83, 0x65, 0xc8, 0xf7, 0x39, 0x3c, 0x14, + ], + ], + final_state: [ + [ + 0x00, 0xff, 0x3c, 0x20, 0xd5, 0xac, 0x28, 0x33, 0xe6, 0xd3, 0x84, 0x27, + 0xd0, 0x44, 0x06, 0x17, 0x9e, 0x31, 0xf3, 0xde, 0xd0, 0xe0, 0x33, 0xab, + 0x4f, 0x51, 0xfc, 0xb4, 0x28, 0xf8, 0x39, 0x1b, + ], + [ + 0x2a, 0x63, 0x7a, 0xa0, 0x4f, 0xb8, 0x0d, 0x9c, 0x50, 0xf3, 0x16, 0xb6, + 0x36, 0x7f, 0xa4, 0xf6, 0xed, 0x52, 0xd0, 0x7c, 0x99, 0xa1, 0x30, 0x29, + 0xd9, 0x3f, 0xae, 0xd3, 0xdd, 0x1e, 0xbc, 0x2f, + ], + [ + 0x12, 0x31, 0x54, 0xbb, 0x87, 0x60, 0x13, 0x94, 0x5f, 0x54, 0x69, 0x34, + 0x9d, 0x5f, 0xc3, 0xfc, 0xfc, 0xc9, 0xd2, 0xda, 0xb8, 0x06, 0x43, 0x0d, + 0x49, 0x69, 0x46, 0xf3, 0xbf, 0x2b, 0x61, 0x11, + ], + ], + }, + TestVector { + initial_state: [ + [ + 0xe2, 0x88, 0x53, 0x15, 0xeb, 0x46, 0x71, 0x09, 0x8b, 0x79, 0x53, 0x5e, + 0x79, 0x0f, 0xe5, 0x3e, 0x29, 0xfe, 0xf2, 0xb3, 0x76, 0x66, 0x97, 0xac, + 0x32, 0xb4, 0xf4, 0x73, 0xf4, 0x68, 0xa0, 0x08, + ], + [ + 0xe6, 0x23, 0x89, 0xfc, 0xe2, 0x9c, 0xc6, 0xeb, 0x2e, 0x07, 0xeb, 0xc5, + 0xae, 0x25, 0xf9, 0xf7, 0x83, 0xb2, 0x7d, 0xb5, 0x9a, 0x4a, 0x15, 0x3d, + 0x88, 0x2d, 0x2b, 0x21, 0x03, 0x59, 0x65, 0x15, + ], + [ + 0xeb, 0x94, 0x94, 0xc6, 0x6a, 0xb3, 0xae, 0x30, 0xb7, 0xe6, 0x09, 0xd9, + 0x91, 0xf4, 0x33, 0xbf, 0x94, 0x86, 0xa7, 0xaf, 0xcf, 0x4a, 0x0d, 0x9c, + 0x73, 0x1e, 0x98, 0x5d, 0x99, 0x58, 0x9c, 0x0b, + ], + ], + final_state: [ + [ + 0xe7, 0x1e, 0xb4, 0x88, 0x51, 0xd7, 0x73, 0xb5, 0xa3, 0xb5, 0xd2, 0xb6, + 0xf6, 0xeb, 0x01, 0xc3, 0x79, 0x3f, 0x2f, 0xeb, 0xdf, 0xd1, 0xb9, 0x53, + 0xf0, 0x6f, 0xa9, 0x59, 0xc7, 0x26, 0xbc, 0x18, + ], + [ + 0x37, 0x71, 0xf8, 0x29, 0xfb, 0xf2, 0x74, 0x87, 0xf1, 0xdf, 0x2b, 0x5e, + 0xe9, 0x94, 0x97, 0x0b, 0x14, 0xd7, 0x13, 0xce, 0xae, 0x73, 0xa6, 0x33, + 0x95, 0x78, 0x4d, 0xcd, 0xf9, 0xaa, 0x30, 0x30, + ], + [ + 0x48, 0x06, 0xaf, 0xf7, 0x5e, 0xd3, 0xc6, 0xb9, 0x72, 0x1b, 0xc5, 0x23, + 0x0d, 0xd7, 0x76, 0xf9, 0x27, 0x44, 0x62, 0x90, 0x97, 0xcf, 0x5c, 0x2b, + 0x7f, 0x14, 0x2c, 0xf2, 0x74, 0xa5, 0x07, 0x37, + ], + ], + }, + TestVector { + initial_state: [ + [ + 0xb7, 0x38, 0xe8, 0xaa, 0xd6, 0x5a, 0x0c, 0xb2, 0xfb, 0x3f, 0x1a, 0x31, + 0x20, 0x37, 0x2e, 0x83, 0x1a, 0x20, 0xda, 0x8a, 0xba, 0x18, 0xd1, 0xdb, + 0xeb, 0xbc, 0x86, 0x2d, 0xed, 0x42, 0x43, 0x1e, + ], + [ + 0x91, 0x47, 0x69, 0x30, 0xaf, 0x7e, 0x42, 0xe0, 0x21, 0x88, 0x56, 0x38, + 0x53, 0xd9, 0x34, 0x67, 0xe0, 0x01, 0xaf, 0xa2, 0xfb, 0x8d, 0xc3, 0x43, + 0x6d, 0x75, 0xa4, 0xa6, 0xf2, 0x65, 0x72, 0x10, + ], + [ + 0x4b, 0x19, 0x22, 0x32, 0xec, 0xb9, 0xf0, 0xc0, 0x24, 0x11, 0xe5, 0x25, + 0x96, 0xbc, 0x5e, 0x90, 0x45, 0x7e, 0x74, 0x59, 0x39, 0xff, 0xed, 0xbd, + 0x12, 0x86, 0x3c, 0xe7, 0x1a, 0x02, 0xaf, 0x11, + ], + ], + final_state: [ + [ + 0x9d, 0x58, 0x16, 0x08, 0x94, 0x8a, 0xd0, 0x15, 0xf5, 0x38, 0x82, 0xc0, + 0x2d, 0x22, 0x40, 0x2f, 0x71, 0xbd, 0x52, 0x7a, 0xb6, 0xb0, 0xbd, 0xab, + 0x5e, 0xaf, 0xef, 0x0c, 0xd9, 0x41, 0xe8, 0x33, + ], + [ + 0xf4, 0x69, 0xd9, 0x80, 0x6d, 0x0b, 0x9d, 0x92, 0x46, 0x6b, 0xbd, 0xe4, + 0x90, 0x4b, 0x88, 0x2d, 0x29, 0xcc, 0x45, 0x6d, 0xef, 0xa4, 0x77, 0x3f, + 0x5d, 0x9a, 0x92, 0x79, 0x6c, 0x60, 0xed, 0x1d, + ], + [ + 0x3c, 0xf1, 0xa7, 0x38, 0x35, 0xf9, 0x42, 0x5d, 0x46, 0x87, 0xa0, 0x9b, + 0xea, 0xcf, 0x48, 0x9a, 0xa6, 0x0e, 0xcb, 0xfc, 0xae, 0xa0, 0x61, 0xc9, + 0x7e, 0xd3, 0x72, 0x86, 0x1c, 0x08, 0x0a, 0x3d, + ], + ], + }, + TestVector { + initial_state: [ + [ + 0x7b, 0x41, 0x7a, 0xdb, 0xfb, 0x3e, 0x3e, 0x3c, 0x21, 0x60, 0xd3, 0xd1, + 0x6f, 0x1e, 0x7f, 0x26, 0x8f, 0xb8, 0x6b, 0x12, 0xb5, 0x6d, 0xa9, 0xc3, + 0x82, 0x85, 0x7d, 0xee, 0xcc, 0x40, 0xa9, 0x0d, + ], + [ + 0x5e, 0x29, 0x35, 0x39, 0x3d, 0xf9, 0x2f, 0xa1, 0xf4, 0x71, 0x68, 0xb2, + 0x61, 0xae, 0xb3, 0x78, 0x6d, 0xd9, 0x84, 0xd5, 0x67, 0xdb, 0x28, 0x57, + 0xb9, 0x27, 0xb7, 0xfa, 0xe2, 0xdb, 0x58, 0x31, + ], + [ + 0x05, 0x41, 0x5d, 0x46, 0x42, 0x78, 0x9d, 0x38, 0xf5, 0x0b, 0x8d, 0xbc, + 0xc1, 0x29, 0xca, 0xb3, 0xd1, 0x7d, 0x19, 0xf3, 0x35, 0x5b, 0xcf, 0x73, + 0xce, 0xcb, 0x8c, 0xb8, 0xa5, 0xda, 0x01, 0x30, + ], + ], + final_state: [ + [ + 0x73, 0x2c, 0x01, 0x83, 0x41, 0x7f, 0xdf, 0x33, 0x43, 0xc1, 0xef, 0x69, + 0xfd, 0xf6, 0xb3, 0xe7, 0xfd, 0x52, 0x9e, 0xe8, 0x44, 0x63, 0x48, 0xf2, + 0x78, 0x50, 0x74, 0xaf, 0xe2, 0x97, 0xe5, 0x39, + ], + [ + 0xc0, 0x33, 0xd0, 0x1c, 0xb2, 0x29, 0x7f, 0x14, 0xdc, 0xcf, 0x8a, 0x37, + 0xc8, 0x90, 0x02, 0x09, 0x46, 0x5c, 0xc7, 0x41, 0x24, 0x50, 0xe0, 0xb0, + 0x82, 0x84, 0xf9, 0xaa, 0xa1, 0x18, 0xde, 0x34, + ], + [ + 0x17, 0xf9, 0xa6, 0x65, 0x38, 0x93, 0xea, 0x76, 0xbe, 0x60, 0x00, 0x20, + 0xb8, 0xff, 0xbf, 0xd9, 0x53, 0xae, 0x4a, 0x94, 0xad, 0x00, 0x10, 0x43, + 0x37, 0xb9, 0xf7, 0xde, 0x69, 0x88, 0x60, 0x31, + ], + ], + }, + TestVector { + initial_state: [ + [ + 0x71, 0x52, 0xf1, 0x39, 0x36, 0xa2, 0x70, 0x57, 0x26, 0x70, 0xdc, 0x82, + 0xd3, 0x90, 0x26, 0xc6, 0xcb, 0x4c, 0xd4, 0xb0, 0xf7, 0xf5, 0xaa, 0x2a, + 0x4f, 0x5a, 0x53, 0x41, 0xec, 0x5d, 0xd7, 0x15, + ], + [ + 0x40, 0x6f, 0x2f, 0xdd, 0x2a, 0xfa, 0x73, 0x3f, 0x5f, 0x64, 0x1c, 0x8c, + 0x21, 0x86, 0x2a, 0x1b, 0xaf, 0xce, 0x26, 0x09, 0xd9, 0xee, 0xcf, 0xa1, + 0x58, 0xcf, 0xb5, 0xcd, 0x79, 0xf8, 0x80, 0x08, + ], + [ + 0xe2, 0x15, 0xdc, 0x7d, 0x62, 0x9d, 0xa0, 0xe0, 0x39, 0xd9, 0x68, 0x1e, + 0x99, 0x38, 0x44, 0x54, 0x36, 0x24, 0xc2, 0x5f, 0xa9, 0x59, 0xcc, 0x97, + 0x48, 0x9c, 0xe7, 0x57, 0x45, 0x82, 0x4b, 0x37, + ], + ], + final_state: [ + [ + 0x16, 0x0a, 0x24, 0x98, 0x48, 0x62, 0xea, 0xe0, 0xa3, 0x33, 0x50, 0x7b, + 0x36, 0x11, 0x93, 0x13, 0x71, 0xc6, 0x1d, 0x8e, 0x65, 0x71, 0x38, 0xcf, + 0xb2, 0xfa, 0x3b, 0x0f, 0x4d, 0xe5, 0xed, 0x3b, + ], + [ + 0xc5, 0xbd, 0x5a, 0x00, 0x44, 0xb6, 0xdb, 0xfe, 0x88, 0xb6, 0x97, 0xf7, + 0x1e, 0xa0, 0x55, 0xb4, 0xe2, 0x32, 0x42, 0x66, 0x6b, 0xf4, 0xe1, 0xb0, + 0x27, 0x52, 0xee, 0xce, 0x08, 0xfb, 0xe8, 0x05, + ], + [ + 0x30, 0x34, 0xdc, 0x8e, 0x8d, 0x4f, 0x6e, 0x33, 0x53, 0x83, 0xb9, 0x01, + 0x35, 0x8a, 0xe4, 0xb7, 0x5f, 0xcc, 0xc7, 0x22, 0x69, 0xdb, 0x83, 0x37, + 0x89, 0xce, 0xd4, 0xc0, 0xad, 0x83, 0x25, 0x1e, + ], + ], + }, + TestVector { + initial_state: [ + [ + 0x86, 0x8c, 0x53, 0x23, 0x9c, 0xfb, 0xdf, 0x73, 0xca, 0xec, 0x65, 0x60, + 0x40, 0x37, 0x31, 0x4f, 0xaa, 0xce, 0xb5, 0x62, 0x18, 0xc6, 0xbd, 0x30, + 0xf8, 0x37, 0x4a, 0xc1, 0x33, 0x86, 0x79, 0x3f, + ], + [ + 0x21, 0xa9, 0xfb, 0x80, 0xad, 0x03, 0xbc, 0x0c, 0xda, 0x4a, 0x44, 0x94, + 0x6c, 0x00, 0xe1, 0xb1, 0xa1, 0xdf, 0x0e, 0x5b, 0x87, 0xb5, 0xbe, 0xce, + 0x47, 0x7a, 0x70, 0x96, 0x49, 0xe9, 0x50, 0x06, + ], + [ + 0x04, 0x91, 0x39, 0x48, 0xf1, 0xa9, 0xd7, 0x92, 0x05, 0xe1, 0xc6, 0x82, + 0xc7, 0x38, 0x07, 0x0a, 0xf6, 0x55, 0x6d, 0xf6, 0xed, 0x4b, 0x4d, 0xdd, + 0x3d, 0x9a, 0x69, 0xf5, 0x33, 0x57, 0xd7, 0x36, + ], + ], + final_state: [ + [ + 0x63, 0xe6, 0x3f, 0x14, 0xcc, 0x49, 0xec, 0x8f, 0x59, 0x93, 0x33, 0xae, + 0x04, 0x2c, 0xb4, 0x0c, 0x6f, 0xa8, 0x5f, 0x2d, 0x67, 0x64, 0xde, 0xad, + 0x13, 0x16, 0x44, 0x04, 0x97, 0x8b, 0x12, 0x03, + ], + [ + 0xc5, 0x61, 0xf3, 0x87, 0xb4, 0xaa, 0x32, 0x60, 0x09, 0x0f, 0x01, 0x73, + 0x88, 0x01, 0xb5, 0x34, 0xbe, 0x39, 0x6a, 0x13, 0xee, 0x11, 0x6b, 0x21, + 0xdb, 0x76, 0x10, 0x69, 0x59, 0x3d, 0xb6, 0x2f, + ], + [ + 0x10, 0x1a, 0x4b, 0xfd, 0x56, 0x89, 0xd5, 0x5a, 0xa7, 0x0e, 0xcf, 0x44, + 0x6d, 0xc3, 0x1a, 0x89, 0xbc, 0x62, 0xde, 0xb7, 0xed, 0x36, 0xf5, 0x49, + 0x19, 0x9c, 0xe1, 0x7b, 0xac, 0xe7, 0x32, 0x1b, + ], + ], + }, + TestVector { + initial_state: [ + [ + 0x7d, 0x4f, 0x5c, 0xcb, 0x99, 0xef, 0x08, 0x4b, 0x57, 0x25, 0xcf, 0xeb, + 0xd5, 0xd6, 0x3d, 0xc1, 0x6a, 0x95, 0xe3, 0x02, 0x5b, 0x97, 0x92, 0xff, + 0xf7, 0xf2, 0x44, 0xfc, 0x71, 0x62, 0x69, 0x39, + ], + [ + 0x26, 0xd6, 0x2e, 0x95, 0x96, 0xfa, 0x82, 0x5c, 0x6b, 0xf2, 0x1a, 0xff, + 0x9e, 0x68, 0x62, 0x5a, 0x19, 0x24, 0x40, 0xea, 0x06, 0x82, 0x81, 0x23, + 0xd9, 0x78, 0x84, 0x80, 0x6f, 0x15, 0xfa, 0x08, + ], + [ + 0xd9, 0x52, 0x75, 0x4a, 0xef, 0xa9, 0x9c, 0x73, 0x3d, 0x14, 0xc8, 0xda, + 0x01, 0x47, 0x86, 0xda, 0x3a, 0x61, 0x28, 0xae, 0xf7, 0x84, 0xa6, 0x46, + 0x10, 0xa8, 0x9d, 0x1a, 0x70, 0x99, 0x21, 0x2d, + ], + ], + final_state: [ + [ + 0x45, 0xed, 0x54, 0x17, 0x40, 0x7b, 0xfd, 0xb7, 0x97, 0xbc, 0xfe, 0x70, + 0x74, 0xdf, 0xf8, 0x0e, 0x32, 0xa5, 0x62, 0xed, 0x88, 0x73, 0x78, 0x1d, + 0xbc, 0xf4, 0xf6, 0x7e, 0x06, 0xbe, 0x0c, 0x23, + ], + [ + 0x13, 0x2f, 0x3f, 0x55, 0xd8, 0xfb, 0xfd, 0x46, 0x7b, 0x2a, 0xe2, 0x2b, + 0x8c, 0x64, 0x93, 0x43, 0x64, 0xcf, 0x9c, 0x4a, 0x0b, 0x07, 0xed, 0xb4, + 0x02, 0x87, 0xc3, 0x92, 0xc9, 0xc1, 0x45, 0x12, + ], + [ + 0xd0, 0x51, 0xc3, 0x7f, 0xf6, 0x4c, 0xad, 0xa2, 0xb4, 0x82, 0xf1, 0x1f, + 0x85, 0x64, 0x39, 0x6b, 0x75, 0xe3, 0xf8, 0x1b, 0x35, 0x52, 0xd8, 0x9a, + 0xf4, 0x92, 0xcf, 0x00, 0x52, 0x3c, 0x04, 0x15, + ], + ], + }, + ] + } + + pub(crate) fn hash() -> Vec { + use HashTestVector as TestVector; + + // From https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/orchard_poseidon/hash/fq.py + vec![ + TestVector { + input: [ + [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ], + [ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ], + ], + output: [ + 0x4e, 0x68, 0xf6, 0x85, 0x70, 0x29, 0x57, 0xf3, 0xbf, 0x54, 0x6b, 0x7a, 0x09, + 0x01, 0x31, 0x4e, 0x51, 0x4f, 0x19, 0x5e, 0xe3, 0xb1, 0x64, 0x46, 0x22, 0x77, + 0x9d, 0x93, 0xdf, 0x96, 0xba, 0x15, + ], + }, + TestVector { + input: [ + [ + 0x5c, 0x7a, 0x8f, 0x73, 0x79, 0x42, 0x57, 0x08, 0x7e, 0x63, 0x4c, 0x49, + 0xac, 0x6b, 0x57, 0x07, 0x4c, 0x4d, 0x6e, 0x66, 0xb1, 0x64, 0x93, 0x9d, + 0xaf, 0xfa, 0x2e, 0xf6, 0xee, 0x69, 0x21, 0x08, + ], + [ + 0x1a, 0xdd, 0x86, 0xb3, 0x8a, 0x6d, 0x8a, 0xc0, 0xa6, 0xfd, 0x9e, 0x0d, + 0x98, 0x2b, 0x77, 0xe6, 0xb0, 0xef, 0x9c, 0xa3, 0xf2, 0x49, 0x88, 0xc7, + 0xb3, 0x53, 0x42, 0x01, 0xcf, 0xb1, 0xcd, 0x0d, + ], + ], + output: [ + 0x0c, 0x0a, 0xd9, 0x0a, 0x2e, 0x0c, 0xba, 0x0e, 0xe6, 0xa5, 0x5a, 0xc5, 0x38, + 0xa4, 0x35, 0xc9, 0x39, 0x04, 0x98, 0xae, 0xb5, 0x30, 0x3e, 0x3d, 0xad, 0x70, + 0x3a, 0xd1, 0xdc, 0xdb, 0x43, 0x2b, + ], + }, + TestVector { + input: [ + [ + 0xbd, 0x69, 0xb8, 0x25, 0xca, 0x41, 0x61, 0x29, 0x6e, 0xfa, 0x7f, 0x66, + 0x9b, 0xa9, 0xc7, 0x27, 0x1f, 0xe0, 0x1f, 0x7e, 0x9c, 0x8e, 0x36, 0xd6, + 0xa5, 0xe2, 0x9d, 0x4e, 0x30, 0xa7, 0x35, 0x14, + ], + [ + 0xbc, 0x50, 0x98, 0x42, 0xb9, 0xa7, 0x62, 0xe5, 0x58, 0xea, 0x51, 0x47, + 0xed, 0x5a, 0xc0, 0x08, 0x62, 0xc2, 0xfa, 0x7b, 0x2f, 0xec, 0xbc, 0xb6, + 0x4b, 0x69, 0x68, 0x91, 0x2a, 0x63, 0x81, 0x0e, + ], + ], + output: [ + 0xa6, 0x0c, 0xc8, 0xb8, 0x53, 0xaf, 0xce, 0xdb, 0xa1, 0x44, 0x65, 0xd5, 0x31, + 0xc7, 0x3c, 0xbc, 0xe1, 0x9e, 0x46, 0x0b, 0xa8, 0x04, 0x62, 0x2d, 0xf5, 0x21, + 0x23, 0x1d, 0xa1, 0x21, 0xc6, 0x08, + ], + }, + TestVector { + input: [ + [ + 0x3d, 0xc1, 0x66, 0xd5, 0x6a, 0x1d, 0x62, 0xf5, 0xa8, 0xd7, 0x55, 0x1d, + 0xb5, 0xfd, 0x93, 0x13, 0xe8, 0xc7, 0x20, 0x3d, 0x99, 0x6a, 0xf7, 0xd4, + 0x77, 0x08, 0x37, 0x56, 0xd5, 0x9a, 0xf8, 0x0d, + ], + [ + 0x05, 0xa7, 0x45, 0xf4, 0x29, 0xc5, 0xdc, 0xe8, 0x4e, 0x0c, 0x20, 0xfd, + 0xf0, 0xf0, 0x3e, 0xbf, 0x81, 0x30, 0xab, 0x33, 0x36, 0x26, 0x97, 0xb0, + 0xe4, 0xe4, 0xc7, 0x63, 0xcc, 0xb8, 0xf6, 0x36, + ], + ], + output: [ + 0xad, 0xa8, 0xca, 0xe4, 0x6a, 0x04, 0x2d, 0x00, 0xb0, 0x2e, 0x33, 0xc3, 0x6e, + 0x65, 0x8c, 0x22, 0x13, 0xfe, 0x81, 0x34, 0x53, 0x8b, 0x56, 0x03, 0x19, 0xe9, + 0x99, 0xf3, 0xf5, 0x82, 0x90, 0x00, + ], + }, + TestVector { + input: [ + [ + 0x49, 0x5c, 0x22, 0x2f, 0x7f, 0xba, 0x1e, 0x31, 0xde, 0xfa, 0x3d, 0x5a, + 0x57, 0xef, 0xc2, 0xe1, 0xe9, 0xb0, 0x1a, 0x03, 0x55, 0x87, 0xd5, 0xfb, + 0x1a, 0x38, 0xe0, 0x1d, 0x94, 0x90, 0x3d, 0x3c, + ], + [ + 0x3d, 0x0a, 0xd3, 0x36, 0xeb, 0x31, 0xf0, 0x83, 0xce, 0x29, 0x77, 0x0e, + 0x42, 0x98, 0x8d, 0x7d, 0x25, 0xc9, 0xa1, 0x38, 0xf4, 0x9b, 0x1a, 0x53, + 0x7e, 0xdc, 0xf0, 0x4b, 0xe3, 0x4a, 0x98, 0x11, + ], + ], + output: [ + 0x19, 0x94, 0x9f, 0xc7, 0x74, 0x04, 0x99, 0x37, 0x00, 0x58, 0x12, 0x7d, 0x04, + 0x0f, 0x11, 0x24, 0x5e, 0xba, 0x6c, 0x37, 0x80, 0xe9, 0x3e, 0x26, 0x16, 0xf4, + 0xc1, 0x77, 0x56, 0x30, 0x78, 0x2d, + ], + }, + TestVector { + input: [ + [ + 0xa4, 0xaf, 0x9d, 0xb6, 0x36, 0x4d, 0x03, 0x99, 0x3d, 0x50, 0x35, 0x3d, + 0x88, 0x39, 0x5e, 0xd7, 0xa4, 0x1b, 0x00, 0x52, 0xad, 0x80, 0x84, 0xa8, + 0xb9, 0xda, 0x94, 0x8d, 0x32, 0x0d, 0xad, 0x16, + ], + [ + 0x4d, 0x54, 0x31, 0xe6, 0xdb, 0x08, 0xd8, 0x74, 0x69, 0x5c, 0x3e, 0xaf, + 0x34, 0x5b, 0x86, 0xc4, 0x12, 0x1f, 0xc0, 0x0f, 0xe7, 0xf2, 0x35, 0x73, + 0x42, 0x76, 0xd3, 0x8d, 0x47, 0xf1, 0xe1, 0x11, + ], + ], + output: [ + 0x29, 0x6e, 0xba, 0xb4, 0xb4, 0x5a, 0xb9, 0x20, 0x97, 0xa7, 0xe6, 0xe7, 0xcc, + 0x6d, 0xd7, 0xd4, 0x7a, 0x12, 0x3e, 0x85, 0x50, 0xa3, 0x3d, 0xf1, 0x20, 0xcc, + 0xa5, 0x38, 0x90, 0x67, 0x1b, 0x21, + ], + }, + TestVector { + input: [ + [ + 0xdd, 0x0c, 0x7a, 0x1d, 0xe5, 0xed, 0x2f, 0xc3, 0x8e, 0x5e, 0x60, 0x7a, + 0x3f, 0xde, 0xab, 0x3f, 0xb6, 0x79, 0xf3, 0xdc, 0x60, 0x1d, 0x00, 0x82, + 0x85, 0xed, 0xcb, 0xda, 0xe6, 0x9c, 0xe8, 0x3c, + ], + [ + 0x19, 0xe4, 0xaa, 0xc0, 0xcd, 0x1b, 0xe4, 0x05, 0x02, 0x42, 0xf4, 0xd1, + 0x20, 0x53, 0xdb, 0x33, 0xf7, 0x34, 0x76, 0xf2, 0x1a, 0x48, 0x2e, 0xc9, + 0x37, 0x83, 0x65, 0xc8, 0xf7, 0x39, 0x3c, 0x14, + ], + ], + output: [ + 0xa8, 0x87, 0x6e, 0x8d, 0x2f, 0x30, 0x0a, 0x62, 0x05, 0x4b, 0x49, 0x4c, 0x8f, + 0x21, 0xc1, 0xd0, 0xad, 0xbd, 0xac, 0x89, 0xbf, 0x2a, 0xad, 0x9f, 0x3c, 0x1b, + 0x10, 0xc4, 0x78, 0x8c, 0x2d, 0x3d, + ], + }, + TestVector { + input: [ + [ + 0xe2, 0x88, 0x53, 0x15, 0xeb, 0x46, 0x71, 0x09, 0x8b, 0x79, 0x53, 0x5e, + 0x79, 0x0f, 0xe5, 0x3e, 0x29, 0xfe, 0xf2, 0xb3, 0x76, 0x66, 0x97, 0xac, + 0x32, 0xb4, 0xf4, 0x73, 0xf4, 0x68, 0xa0, 0x08, + ], + [ + 0xe6, 0x23, 0x89, 0xfc, 0xe2, 0x9c, 0xc6, 0xeb, 0x2e, 0x07, 0xeb, 0xc5, + 0xae, 0x25, 0xf9, 0xf7, 0x83, 0xb2, 0x7d, 0xb5, 0x9a, 0x4a, 0x15, 0x3d, + 0x88, 0x2d, 0x2b, 0x21, 0x03, 0x59, 0x65, 0x15, + ], + ], + output: [ + 0xc2, 0xda, 0xcb, 0x1e, 0xea, 0xed, 0x88, 0x0b, 0x87, 0xd0, 0x4d, 0xd9, 0x61, + 0x95, 0x73, 0x0e, 0x98, 0xbd, 0x0f, 0x14, 0x77, 0x7b, 0x3e, 0xf0, 0xda, 0x40, + 0xe4, 0xc0, 0x87, 0xb1, 0x9d, 0x28, + ], + }, + TestVector { + input: [ + [ + 0xeb, 0x94, 0x94, 0xc6, 0x6a, 0xb3, 0xae, 0x30, 0xb7, 0xe6, 0x09, 0xd9, + 0x91, 0xf4, 0x33, 0xbf, 0x94, 0x86, 0xa7, 0xaf, 0xcf, 0x4a, 0x0d, 0x9c, + 0x73, 0x1e, 0x98, 0x5d, 0x99, 0x58, 0x9c, 0x0b, + ], + [ + 0xb7, 0x38, 0xe8, 0xaa, 0xd6, 0x5a, 0x0c, 0xb2, 0xfb, 0x3f, 0x1a, 0x31, + 0x20, 0x37, 0x2e, 0x83, 0x1a, 0x20, 0xda, 0x8a, 0xba, 0x18, 0xd1, 0xdb, + 0xeb, 0xbc, 0x86, 0x2d, 0xed, 0x42, 0x43, 0x1e, + ], + ], + output: [ + 0x5a, 0x55, 0xe3, 0x08, 0x2e, 0x55, 0xa5, 0x66, 0xb9, 0xca, 0xb1, 0xca, 0xf4, + 0x48, 0xf7, 0x0f, 0x8c, 0x9a, 0x53, 0xa1, 0xc9, 0xf6, 0x9e, 0x2a, 0x80, 0xdd, + 0xb8, 0x58, 0x3f, 0x99, 0x01, 0x26, + ], + }, + TestVector { + input: [ + [ + 0x91, 0x47, 0x69, 0x30, 0xaf, 0x7e, 0x42, 0xe0, 0x21, 0x88, 0x56, 0x38, + 0x53, 0xd9, 0x34, 0x67, 0xe0, 0x01, 0xaf, 0xa2, 0xfb, 0x8d, 0xc3, 0x43, + 0x6d, 0x75, 0xa4, 0xa6, 0xf2, 0x65, 0x72, 0x10, + ], + [ + 0x4b, 0x19, 0x22, 0x32, 0xec, 0xb9, 0xf0, 0xc0, 0x24, 0x11, 0xe5, 0x25, + 0x96, 0xbc, 0x5e, 0x90, 0x45, 0x7e, 0x74, 0x59, 0x39, 0xff, 0xed, 0xbd, + 0x12, 0x86, 0x3c, 0xe7, 0x1a, 0x02, 0xaf, 0x11, + ], + ], + output: [ + 0xca, 0xc6, 0x68, 0x8a, 0x3d, 0x2a, 0x7d, 0xca, 0xe1, 0xd4, 0x60, 0x1f, 0x9b, + 0xf0, 0x6d, 0x58, 0x00, 0x8f, 0x24, 0x85, 0x6a, 0xe6, 0x00, 0xf0, 0xe0, 0x90, + 0x07, 0x23, 0xaf, 0xa1, 0x20, 0x03, + ], + }, + TestVector { + input: [ + [ + 0x7b, 0x41, 0x7a, 0xdb, 0xfb, 0x3e, 0x3e, 0x3c, 0x21, 0x60, 0xd3, 0xd1, + 0x6f, 0x1e, 0x7f, 0x26, 0x8f, 0xb8, 0x6b, 0x12, 0xb5, 0x6d, 0xa9, 0xc3, + 0x82, 0x85, 0x7d, 0xee, 0xcc, 0x40, 0xa9, 0x0d, + ], + [ + 0x5e, 0x29, 0x35, 0x39, 0x3d, 0xf9, 0x2f, 0xa1, 0xf4, 0x71, 0x68, 0xb2, + 0x61, 0xae, 0xb3, 0x78, 0x6d, 0xd9, 0x84, 0xd5, 0x67, 0xdb, 0x28, 0x57, + 0xb9, 0x27, 0xb7, 0xfa, 0xe2, 0xdb, 0x58, 0x31, + ], + ], + output: [ + 0xd7, 0xe7, 0x83, 0x91, 0x97, 0x83, 0xb0, 0x8b, 0x5f, 0xad, 0x08, 0x9d, 0x57, + 0x1e, 0xc1, 0x8f, 0xb4, 0x63, 0x28, 0x53, 0x99, 0x3f, 0x35, 0xe3, 0xee, 0x54, + 0x3d, 0x4e, 0xed, 0xf6, 0x5f, 0x38, + ], + }, + ] + } +} diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/utilities.rs b/plonkish_backend/src/frontend/halo2/poseidongadget/utilities.rs new file mode 100644 index 00000000..c105d20e --- /dev/null +++ b/plonkish_backend/src/frontend/halo2/poseidongadget/utilities.rs @@ -0,0 +1,496 @@ +//! Utility gadgets. + +use ff::{Field, PrimeField, PrimeFieldBits}; +use halo2_proofs::{ + circuit::{AssignedCell, Cell, Layouter, Value}, + plonk::{Advice, Column, Error, Expression}, +}; +use std::marker::PhantomData; +use std::ops::Range; + +pub mod cond_swap; + +/// A type that has a value at either keygen or proving time. +pub trait FieldValue { + /// Returns the value of this type. + fn value(&self) -> Value<&F>; +} + +impl FieldValue for Value { + fn value(&self) -> Value<&F> { + self.as_ref() + } +} + +impl FieldValue for AssignedCell { + fn value(&self) -> Value<&F> { + self.value() + } +} + +/// Trait for a variable in the circuit. +pub trait Var: Clone + std::fmt::Debug + From> { + /// The cell at which this variable was allocated. + fn cell(&self) -> Cell; + + /// The value allocated to this variable. + fn value(&self) -> Value; +} + +impl Var for AssignedCell { + fn cell(&self) -> Cell { + self.cell() + } + + fn value(&self) -> Value { + self.value().cloned() + } +} + +/// Trait for utilities used across circuits. +pub trait UtilitiesInstructions { + /// Variable in the circuit. + type Var: Var; + + /// Load a variable. + fn load_private( + &self, + mut layouter: impl Layouter, + column: Column, + value: Value, + ) -> Result { + layouter.assign_region( + || "load private", + |mut region| { + region + .assign_advice(|| "load private", column, 0, || value) + .map(Self::Var::from) + }, + ) + } +} + +/// A type representing a range-constrained field element. +#[derive(Clone, Copy, Debug)] +pub struct RangeConstrained> { + inner: T, + num_bits: usize, + _phantom: PhantomData, +} + +impl> RangeConstrained { + /// Returns the range-constrained inner type. + pub fn inner(&self) -> &T { + &self.inner + } + + /// Returns the number of bits to which this cell is constrained. + pub fn num_bits(&self) -> usize { + self.num_bits + } +} + +impl RangeConstrained> { + /// Constructs a `RangeConstrained>` as a bitrange of the given value. + pub fn bitrange_of(value: Value<&F>, bitrange: Range) -> Self { + let num_bits = bitrange.len(); + Self { + inner: value.map(|value| bitrange_subset(value, bitrange)), + num_bits, + _phantom: PhantomData, + } + } +} + +impl RangeConstrained> { + /// Constructs a `RangeConstrained>` without verifying that the + /// cell is correctly range constrained. + /// + /// This API only exists to ease with integrating this type into existing circuits, + /// and will likely be removed in future. + pub fn unsound_unchecked(cell: AssignedCell, num_bits: usize) -> Self { + Self { + inner: cell, + num_bits, + _phantom: PhantomData, + } + } + + /// Extracts the range-constrained value from this range-constrained cell. + pub fn value(&self) -> RangeConstrained> { + RangeConstrained { + inner: self.inner.value().copied(), + num_bits: self.num_bits, + _phantom: PhantomData, + } + } +} + +/// Checks that an expression is either 1 or 0. +pub fn bool_check(value: Expression) -> Expression { + range_check(value, 2) +} + +/// If `a` then `b`, else `c`. Returns (a * b) + (1 - a) * c. +/// +/// `a` must be a boolean-constrained expression. +pub fn ternary(a: Expression, b: Expression, c: Expression) -> Expression { + let one_minus_a = Expression::Constant(F::ONE) - a.clone(); + a * b + one_minus_a * c +} + +/// Takes a specified subsequence of the little-endian bit representation of a field element. +/// The bits are numbered from 0 for the LSB. +pub fn bitrange_subset(field_elem: &F, bitrange: Range) -> F { + // We can allow a subsequence of length NUM_BITS, because + // field_elem.to_le_bits() returns canonical bitstrings. + assert!(bitrange.end <= F::NUM_BITS as usize); + + field_elem + .to_le_bits() + .iter() + .by_vals() + .skip(bitrange.start) + .take(bitrange.end - bitrange.start) + .rev() + .fold(F::ZERO, |acc, bit| { + if bit { + acc.double() + F::ONE + } else { + acc.double() + } + }) +} + +/// Check that an expression is in the small range [0..range), +/// i.e. 0 ≤ word < range. +pub fn range_check(word: Expression, range: usize) -> Expression { + (1..range).fold(word.clone(), |acc, i| { + acc * (Expression::Constant(F::from(i as u64)) - word.clone()) + }) +} + +/// Decompose a word `alpha` into `window_num_bits` bits (little-endian) +/// For a window size of `w`, this returns [k_0, ..., k_n] where each `k_i` +/// is a `w`-bit value, and `scalar = k_0 + k_1 * w + k_n * w^n`. +/// +/// # Panics +/// +/// We are returning a `Vec` which means the window size is limited to +/// <= 8 bits. +pub fn decompose_word( + word: &F, + word_num_bits: usize, + window_num_bits: usize, +) -> Vec { + assert!(window_num_bits <= 8); + + // Pad bits to multiple of window_num_bits + let padding = (window_num_bits - (word_num_bits % window_num_bits)) % window_num_bits; + let bits: Vec = word + .to_le_bits() + .into_iter() + .take(word_num_bits) + .chain(std::iter::repeat(false).take(padding)) + .collect(); + assert_eq!(bits.len(), word_num_bits + padding); + + bits.chunks_exact(window_num_bits) + .map(|chunk| chunk.iter().rev().fold(0, |acc, b| (acc << 1) + (*b as u8))) + .collect() +} + +/// The u64 integer represented by an L-bit little-endian bitstring. +/// +/// # Panics +/// +/// Panics if the bitstring is longer than 64 bits. +pub fn lebs2ip(bits: &[bool; L]) -> u64 { + assert!(L <= 64); + bits.iter() + .enumerate() + .fold(0u64, |acc, (i, b)| acc + if *b { 1 << i } else { 0 }) +} + +/// The sequence of bits representing a u64 in little-endian order. +/// +/// # Panics +/// +/// Panics if the expected length of the sequence `NUM_BITS` exceeds +/// 64. +pub fn i2lebsp(int: u64) -> [bool; NUM_BITS] { + /// Takes in an FnMut closure and returns a constant-length array with elements of + /// type `Output`. + fn gen_const_array( + closure: impl FnMut(usize) -> Output, + ) -> [Output; LEN] { + let mut ret: [Output; LEN] = [Default::default(); LEN]; + for (bit, val) in ret.iter_mut().zip((0..LEN).map(closure)) { + *bit = val; + } + ret + } + assert!(NUM_BITS <= 64); + gen_const_array(|mask: usize| (int & (1 << mask)) != 0) +} + +#[cfg(test)] +mod tests { + use super::*; + use ff::FromUniformBytes; + use group::ff::{Field, PrimeField}; + use halo2_proofs::{ + circuit::{Layouter, SimpleFloorPlanner}, + dev::{FailureLocation, MockProver, VerifyFailure}, + plonk::{Any, Circuit, ConstraintSystem, Constraints, Error, Selector}, + poly::Rotation, + }; + use halo2_curves::pasta::pallas; + use proptest::prelude::*; + use rand::rngs::OsRng; + use std::convert::TryInto; + use std::iter; + use uint::construct_uint; + + #[test] + fn test_range_check() { + struct MyCircuit(u8); + + impl UtilitiesInstructions for MyCircuit { + type Var = AssignedCell; + } + + #[derive(Clone)] + struct Config { + selector: Selector, + advice: Column, + } + + impl Circuit for MyCircuit { + type Config = Config; + type FloorPlanner = SimpleFloorPlanner; + #[cfg(feature = "circuit-params")] + type Params = (); + + fn without_witnesses(&self) -> Self { + MyCircuit(self.0) + } + + fn configure(meta: &mut ConstraintSystem) -> Self::Config { + let selector = meta.selector(); + let advice = meta.advice_column(); + + meta.create_gate("range check", |meta| { + let selector = meta.query_selector(selector); + let advice = meta.query_advice(advice, Rotation::cur()); + + Constraints::with_selector(selector, Some(range_check(advice, RANGE))) + }); + + Config { selector, advice } + } + + fn synthesize( + &self, + config: Self::Config, + mut layouter: impl Layouter, + ) -> Result<(), Error> { + layouter.assign_region( + || "range constrain", + |mut region| { + config.selector.enable(&mut region, 0)?; + region.assign_advice( + || format!("witness {}", self.0), + config.advice, + 0, + || Value::known(pallas::Base::from(self.0 as u64)), + )?; + + Ok(()) + }, + ) + } + } + + for i in 0..8 { + let circuit: MyCircuit<8> = MyCircuit(i); + let prover = MockProver::::run::<_,true>(3, &circuit, vec![]).unwrap(); + assert_eq!(prover.verify(), Ok(())); + } + + { + let circuit: MyCircuit<8> = MyCircuit(8); + let prover = MockProver::::run::<_,true>(3, &circuit, vec![]).unwrap(); + assert_eq!( + prover.verify(), + Err(vec![VerifyFailure::ConstraintNotSatisfied { + constraint: ((0, "range check").into(), 0, "").into(), + location: FailureLocation::InRegion { + region: (0, "range constrain").into(), + offset: 0, + }, + cell_values: vec![(((Any::advice(), 0).into(), 0).into(), "0x8".to_string())], + }]) + ); + } + } + + #[allow(clippy::assign_op_pattern)] + #[allow(clippy::ptr_offset_with_cast)] + #[allow(clippy::single_range_in_vec_init)] + #[test] + fn test_bitrange_subset() { + let rng = OsRng; + + construct_uint! { + struct U256(4); + } + + // Subset full range. + { + let field_elem = pallas::Base::random(rng); + let bitrange = 0..(pallas::Base::NUM_BITS as usize); + let subset = bitrange_subset(&field_elem, bitrange); + assert_eq!(field_elem, subset); + } + + // Subset zero bits + { + let field_elem = pallas::Base::random(rng); + let bitrange = 0..0; + let subset = bitrange_subset(&field_elem, bitrange); + assert_eq!(pallas::Base::zero(), subset); + } + + // Closure to decompose field element into pieces using consecutive ranges, + // and check that we recover the original. + let decompose = |field_elem: pallas::Base, ranges: &[Range]| { + assert_eq!( + ranges.iter().map(|range| range.len()).sum::(), + pallas::Base::NUM_BITS as usize + ); + assert_eq!(ranges[0].start, 0); + assert_eq!(ranges.last().unwrap().end, pallas::Base::NUM_BITS as usize); + + // Check ranges are contiguous + #[allow(unused_assignments)] + { + let mut ranges = ranges.iter(); + let mut range = ranges.next().unwrap(); + if let Some(next_range) = ranges.next() { + assert_eq!(range.end, next_range.start); + range = next_range; + } + } + + let subsets = ranges + .iter() + .map(|range| bitrange_subset(&field_elem, range.clone())) + .collect::>(); + + let mut sum = subsets[0]; + let mut num_bits = 0; + for (idx, subset) in subsets.iter().skip(1).enumerate() { + // 2^num_bits + let range_shift: [u8; 32] = { + num_bits += ranges[idx].len(); + let mut range_shift = [0u8; 32]; + U256([2, 0, 0, 0]) + .pow(U256([num_bits as u64, 0, 0, 0])) + .to_little_endian(&mut range_shift); + range_shift + }; + sum += subset * pallas::Base::from_repr(range_shift).unwrap(); + } + assert_eq!(field_elem, sum); + }; + decompose(pallas::Base::random(rng), &[0..255]); + decompose(pallas::Base::random(rng), &[0..1, 1..255]); + decompose(pallas::Base::random(rng), &[0..254, 254..255]); + decompose(pallas::Base::random(rng), &[0..127, 127..255]); + decompose(pallas::Base::random(rng), &[0..128, 128..255]); + decompose( + pallas::Base::random(rng), + &[0..50, 50..100, 100..150, 150..200, 200..255], + ); + } + + prop_compose! { + fn arb_scalar()(bytes in prop::array::uniform32(0u8..)) -> pallas::Scalar { + // Instead of rejecting out-of-range bytes, let's reduce them. + let mut buf = [0; 64]; + buf[..32].copy_from_slice(&bytes); + pallas::Scalar::from_uniform_bytes(&buf) + } + } + + proptest! { + #[test] + fn test_decompose_word( + scalar in arb_scalar(), + window_num_bits in 1u8..9 + ) { + // Get decomposition into `window_num_bits` bits + let decomposed = decompose_word(&scalar, pallas::Scalar::NUM_BITS as usize, window_num_bits as usize); + + // Flatten bits + let bits = decomposed + .iter() + .flat_map(|window| (0..window_num_bits).map(move |mask| (window & (1 << mask)) != 0)); + + // Ensure this decomposition contains 256 or fewer set bits. + assert!(!bits.clone().skip(32*8).any(|b| b)); + + // Pad or truncate bits to 32 bytes + let bits: Vec = bits.chain(iter::repeat(false)).take(32*8).collect(); + + let bytes: Vec = bits.chunks_exact(8).map(|chunk| chunk.iter().rev().fold(0, |acc, b| (acc << 1) + (*b as u8))).collect(); + + // Check that original scalar is recovered from decomposition + assert_eq!(scalar, pallas::Scalar::from_repr(bytes.try_into().unwrap()).unwrap()); + } + } + + #[test] + fn lebs2ip_round_trip() { + use rand::rngs::OsRng; + + let mut rng = OsRng; + { + let int = rng.next_u64(); + assert_eq!(lebs2ip::<64>(&i2lebsp(int)), int); + } + + assert_eq!(lebs2ip::<64>(&i2lebsp(0)), 0); + assert_eq!( + lebs2ip::<64>(&i2lebsp(0xFFFFFFFFFFFFFFFF)), + 0xFFFFFFFFFFFFFFFF + ); + } + + #[test] + fn i2lebsp_round_trip() { + { + let bitstring = (0..64).map(|_| rand::random()).collect::>(); + assert_eq!( + i2lebsp::<64>(lebs2ip::<64>(&bitstring.clone().try_into().unwrap())).to_vec(), + bitstring + ); + } + + { + let bitstring = [false; 64]; + assert_eq!(i2lebsp(lebs2ip(&bitstring)), bitstring); + } + + { + let bitstring = [true; 64]; + assert_eq!(i2lebsp(lebs2ip(&bitstring)), bitstring); + } + + { + let bitstring = []; + assert_eq!(i2lebsp(lebs2ip(&bitstring)), bitstring); + } + } +} diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/utilities/cond_swap.rs b/plonkish_backend/src/frontend/halo2/poseidongadget/utilities/cond_swap.rs new file mode 100644 index 00000000..c937f3eb --- /dev/null +++ b/plonkish_backend/src/frontend/halo2/poseidongadget/utilities/cond_swap.rs @@ -0,0 +1,289 @@ +//! Gadget and chip for a conditional swap utility. + +use super::{bool_check, ternary, UtilitiesInstructions}; +use ff::{Field, PrimeField}; +use halo2_proofs::{ + circuit::{AssignedCell, Chip, Layouter, Value}, + plonk::{Advice, Column, ConstraintSystem, Constraints, Error, Selector}, + poly::Rotation, +}; +use std::marker::PhantomData; + +/// Instructions for a conditional swap gadget. +pub trait CondSwapInstructions: UtilitiesInstructions { + #[allow(clippy::type_complexity)] + /// Given an input pair (a,b) and a `swap` boolean flag, returns + /// (b,a) if `swap` is set, else (a,b) if `swap` is not set. + /// + /// The second element of the pair is required to be a witnessed + /// value, not a variable that already exists in the circuit. + fn swap( + &self, + layouter: impl Layouter, + pair: (Self::Var, Value), + swap: Value, + ) -> Result<(Self::Var, Self::Var), Error>; +} + +/// A chip implementing a conditional swap. +#[derive(Clone, Debug)] +pub struct CondSwapChip { + config: CondSwapConfig, + _marker: PhantomData, +} + +impl Chip for CondSwapChip { + type Config = CondSwapConfig; + type Loaded = (); + + fn config(&self) -> &Self::Config { + &self.config + } + + fn loaded(&self) -> &Self::Loaded { + &() + } +} + +/// Configuration for the [`CondSwapChip`]. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct CondSwapConfig { + q_swap: Selector, + a: Column, + b: Column, + a_swapped: Column, + b_swapped: Column, + swap: Column, +} + +impl UtilitiesInstructions for CondSwapChip { + type Var = AssignedCell; +} + +impl CondSwapInstructions for CondSwapChip { + #[allow(clippy::type_complexity)] + fn swap( + &self, + mut layouter: impl Layouter, + pair: (Self::Var, Value), + swap: Value, + ) -> Result<(Self::Var, Self::Var), Error> { + let config = self.config(); + + layouter.assign_region( + || "swap", + |mut region| { + // Enable `q_swap` selector + config.q_swap.enable(&mut region, 0)?; + + // Copy in `a` value + let a = pair.0.copy_advice(|| "copy a", &mut region, config.a, 0)?; + + // Witness `b` value + let b = region.assign_advice(|| "witness b", config.b, 0, || pair.1)?; + + // Witness `swap` value + let swap_val = swap.map(|swap| F::from(swap as u64)); + region.assign_advice(|| "swap", config.swap, 0, || swap_val)?; + + // Conditionally swap a + let a_swapped = { + let a_swapped = a + .value() + .zip(b.value()) + .zip(swap) + .map(|((a, b), swap)| if swap { b } else { a }) + .cloned(); + region.assign_advice(|| "a_swapped", config.a_swapped, 0, || a_swapped)? + }; + + // Conditionally swap b + let b_swapped = { + let b_swapped = a + .value() + .zip(b.value()) + .zip(swap) + .map(|((a, b), swap)| if swap { a } else { b }) + .cloned(); + region.assign_advice(|| "b_swapped", config.b_swapped, 0, || b_swapped)? + }; + + // Return swapped pair + Ok((a_swapped, b_swapped)) + }, + ) + } +} + +impl CondSwapChip { + /// Configures this chip for use in a circuit. + /// + /// # Side-effects + /// + /// `advices[0]` will be equality-enabled. + pub fn configure( + meta: &mut ConstraintSystem, + advices: [Column; 5], + ) -> CondSwapConfig { + let a = advices[0]; + // Only column a is used in an equality constraint directly by this chip. + meta.enable_equality(a); + + let q_swap = meta.selector(); + + let config = CondSwapConfig { + q_swap, + a, + b: advices[1], + a_swapped: advices[2], + b_swapped: advices[3], + swap: advices[4], + }; + + // TODO: optimise shape of gate for Merkle path validation + + meta.create_gate("a' = b â‹… swap + a â‹… (1-swap)", |meta| { + let q_swap = meta.query_selector(q_swap); + + let a = meta.query_advice(config.a, Rotation::cur()); + let b = meta.query_advice(config.b, Rotation::cur()); + let a_swapped = meta.query_advice(config.a_swapped, Rotation::cur()); + let b_swapped = meta.query_advice(config.b_swapped, Rotation::cur()); + let swap = meta.query_advice(config.swap, Rotation::cur()); + + // This checks that `a_swapped` is equal to `b` when `swap` is set, + // but remains as `a` when `swap` is not set. + let a_check = a_swapped - ternary(swap.clone(), b.clone(), a.clone()); + + // This checks that `b_swapped` is equal to `a` when `swap` is set, + // but remains as `b` when `swap` is not set. + let b_check = b_swapped - ternary(swap.clone(), a, b); + + // Check `swap` is boolean. + let bool_check = bool_check(swap); + + Constraints::with_selector( + q_swap, + [ + ("a check", a_check), + ("b check", b_check), + ("swap is bool", bool_check), + ], + ) + }); + + config + } + + /// Constructs a [`CondSwapChip`] given a [`CondSwapConfig`]. + pub fn construct(config: CondSwapConfig) -> Self { + CondSwapChip { + config, + _marker: PhantomData, + } + } +} + +#[cfg(test)] +mod tests { + use super::super::UtilitiesInstructions; + use super::{CondSwapChip, CondSwapConfig, CondSwapInstructions}; + use ff::PrimeField; + use group::ff::Field; + use halo2_proofs::{ + circuit::{Layouter, SimpleFloorPlanner, Value}, + dev::MockProver, + plonk::{Circuit, ConstraintSystem, Error}, + }; + use halo2_curves::pasta::pallas::Base; + use rand::rngs::OsRng; + + #[test] + fn cond_swap() { + #[derive(Default)] + struct MyCircuit { + a: Value, + b: Value, + swap: Value, + } + + impl Circuit for MyCircuit { + type Config = CondSwapConfig; + type FloorPlanner = SimpleFloorPlanner; + #[cfg(feature = "circuit-params")] + type Params = (); + + fn without_witnesses(&self) -> Self { + Self::default() + } + + fn configure(meta: &mut ConstraintSystem) -> Self::Config { + let advices = [ + meta.advice_column(), + meta.advice_column(), + meta.advice_column(), + meta.advice_column(), + meta.advice_column(), + ]; + + CondSwapChip::::configure(meta, advices) + } + + fn synthesize( + &self, + config: Self::Config, + mut layouter: impl Layouter, + ) -> Result<(), Error> { + let chip = CondSwapChip::::construct(config.clone()); + + // Load the pair and the swap flag into the circuit. + let a = chip.load_private(layouter.namespace(|| "a"), config.a, self.a)?; + // Return the swapped pair. + let swapped_pair = chip.swap( + layouter.namespace(|| "swap"), + (a.clone(), self.b), + self.swap, + )?; + + self.swap + .zip(a.value().zip(self.b.as_ref())) + .zip(swapped_pair.0.value().zip(swapped_pair.1.value())) + .assert_if_known(|((swap, (a, b)), (a_swapped, b_swapped))| { + if *swap { + // Check that `a` and `b` have been swapped + (a_swapped == b) && (b_swapped == a) + } else { + // Check that `a` and `b` have not been swapped + (a_swapped == a) && (b_swapped == b) + } + }); + + Ok(()) + } + } + + let rng = OsRng; + + // Test swap case + { + let circuit: MyCircuit = MyCircuit { + a: Value::known(Base::random(rng)), + b: Value::known(Base::random(rng)), + swap: Value::known(true), + }; + let prover = MockProver::::run::<_, true>(3, &circuit, vec![]).unwrap(); + assert_eq!(prover.verify(), Ok(())); + } + + // Test non-swap case + { + let circuit: MyCircuit = MyCircuit { + a: Value::known(Base::random(rng)), + b: Value::known(Base::random(rng)), + swap: Value::known(false), + }; + let prover = MockProver::::run::<_,true>(3, &circuit, vec![]).unwrap(); + assert_eq!(prover.verify(), Ok(())); + } + } +} diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/utilities/rm_lookup_range_check.rs b/plonkish_backend/src/frontend/halo2/poseidongadget/utilities/rm_lookup_range_check.rs new file mode 100644 index 00000000..a4a48bff --- /dev/null +++ b/plonkish_backend/src/frontend/halo2/poseidongadget/utilities/rm_lookup_range_check.rs @@ -0,0 +1,658 @@ +//! Make use of a K-bit lookup table to decompose a field element into K-bit +//! words. + +use halo2_proofs::{ + circuit::{AssignedCell, Layouter, Region}, + plonk::{Advice, Column, ConstraintSystem, Constraints, Error, Selector, TableColumn}, + poly::Rotation, +}; +use std::{convert::TryInto, marker::PhantomData}; + +use ff::PrimeFieldBits; + +use super::*; + +/// The running sum $[z_0, ..., z_W]$. If created in strict mode, $z_W = 0$. +#[derive(Debug)] +pub struct RunningSum(Vec>); +impl std::ops::Deref for RunningSum { + type Target = Vec>; + + fn deref(&self) -> &Vec> { + &self.0 + } +} + +impl RangeConstrained> { + /// Witnesses a subset of the bits in `value` and constrains them to be the correct + /// number of bits. + /// + /// # Panics + /// + /// Panics if `bitrange.len() >= K`. + pub fn witness_short( + lookup_config: &LookupRangeCheckConfig, + layouter: impl Layouter, + value: Value<&F>, + bitrange: Range, + ) -> Result { + let num_bits = bitrange.len(); + assert!(num_bits < K); + + // Witness the subset and constrain it to be the correct number of bits. + lookup_config + .witness_short_check( + layouter, + value.map(|value| bitrange_subset(value, bitrange)), + num_bits, + ) + .map(|inner| Self { + inner, + num_bits, + _phantom: PhantomData, + }) + } +} + +/// Configuration that provides methods for a lookup range check. +#[derive(Eq, PartialEq, Debug, Clone, Copy)] +pub struct LookupRangeCheckConfig { + q_lookup: Selector, + q_running: Selector, + q_bitshift: Selector, + running_sum: Column, + table_idx: TableColumn, + _marker: PhantomData, +} + +impl LookupRangeCheckConfig { + /// The `running_sum` advice column breaks the field element into `K`-bit + /// words. It is used to construct the input expression to the lookup + /// argument. + /// + /// The `table_idx` fixed column contains values from [0..2^K). Looking up + /// a value in `table_idx` constrains it to be within this range. The table + /// can be loaded outside this helper. + /// + /// # Side-effects + /// + /// Both the `running_sum` and `constants` columns will be equality-enabled. + pub fn configure( + meta: &mut ConstraintSystem, + running_sum: Column, + table_idx: TableColumn, + ) -> Self { + meta.enable_equality(running_sum); + + let q_lookup = meta.complex_selector(); + let q_running = meta.complex_selector(); + let q_bitshift = meta.selector(); + let config = LookupRangeCheckConfig { + q_lookup, + q_running, + q_bitshift, + running_sum, + table_idx, + _marker: PhantomData, + }; + + // https://p.z.cash/halo2-0.1:decompose-combined-lookup + meta.lookup("lookup", |meta| { + let q_lookup = meta.query_selector(config.q_lookup); + let q_running = meta.query_selector(config.q_running); + let z_cur = meta.query_advice(config.running_sum, Rotation::cur()); + + // In the case of a running sum decomposition, we recover the word from + // the difference of the running sums: + // z_i = 2^{K}â‹…z_{i + 1} + a_i + // => a_i = z_i - 2^{K}â‹…z_{i + 1} + let running_sum_lookup = { + let running_sum_word = { + let z_next = meta.query_advice(config.running_sum, Rotation::next()); + z_cur.clone() - z_next * F::from(1 << K) + }; + + q_running.clone() * running_sum_word + }; + + // In the short range check, the word is directly witnessed. + let short_lookup = { + let short_word = z_cur; + let q_short = Expression::Constant(F::ONE) - q_running; + + q_short * short_word + }; + + // Combine the running sum and short lookups: + vec![( + q_lookup * (running_sum_lookup + short_lookup), + config.table_idx, + )] + }); + + // For short lookups, check that the word has been shifted by the correct number of bits. + // https://p.z.cash/halo2-0.1:decompose-short-lookup + meta.create_gate("Short lookup bitshift", |meta| { + let q_bitshift = meta.query_selector(config.q_bitshift); + let word = meta.query_advice(config.running_sum, Rotation::prev()); + let shifted_word = meta.query_advice(config.running_sum, Rotation::cur()); + let inv_two_pow_s = meta.query_advice(config.running_sum, Rotation::next()); + + let two_pow_k = F::from(1 << K); + + // shifted_word = word * 2^{K-s} + // = word * 2^K * inv_two_pow_s + Constraints::with_selector( + q_bitshift, + Some(word * two_pow_k * inv_two_pow_s - shifted_word), + ) + }); + + config + } + + #[cfg(test)] + // Loads the values [0..2^K) into `table_idx`. This is only used in testing + // for now, since the Sinsemilla chip provides a pre-loaded table in the + // Orchard context. + pub fn load(&self, layouter: &mut impl Layouter) -> Result<(), Error> { + layouter.assign_table( + || "table_idx", + |mut table| { + // We generate the row values lazily (we only need them during keygen). + for index in 0..(1 << K) { + table.assign_cell( + || "table_idx", + self.table_idx, + index, + || Value::known(F::from(index as u64)), + )?; + } + Ok(()) + }, + ) + } + + /// Range check on an existing cell that is copied into this helper. + /// + /// Returns an error if `element` is not in a column that was passed to + /// [`ConstraintSystem::enable_equality`] during circuit configuration. + pub fn copy_check( + &self, + mut layouter: impl Layouter, + element: AssignedCell, + num_words: usize, + strict: bool, + ) -> Result, Error> { + layouter.assign_region( + || format!("{:?} words range check", num_words), + |mut region| { + // Copy `element` and initialize running sum `z_0 = element` to decompose it. + let z_0 = element.copy_advice(|| "z_0", &mut region, self.running_sum, 0)?; + self.range_check(&mut region, z_0, num_words, strict) + }, + ) + } + + /// Range check on a value that is witnessed in this helper. + pub fn witness_check( + &self, + mut layouter: impl Layouter, + value: Value, + num_words: usize, + strict: bool, + ) -> Result, Error> { + layouter.assign_region( + || "Witness element", + |mut region| { + let z_0 = + region.assign_advice(|| "Witness element", self.running_sum, 0, || value)?; + self.range_check(&mut region, z_0, num_words, strict) + }, + ) + } + + /// If `strict` is set to "true", the field element must fit into + /// `num_words * K` bits. In other words, the final cumulative sum `z_{num_words}` + /// must be zero. + /// + /// If `strict` is set to "false", the final `z_{num_words}` is not constrained. + /// + /// `element` must have been assigned to `self.running_sum` at offset 0. + fn range_check( + &self, + region: &mut Region<'_, F>, + element: AssignedCell, + num_words: usize, + strict: bool, + ) -> Result, Error> { + // `num_words` must fit into a single field element. + assert!(num_words * K <= F::CAPACITY as usize); + let num_bits = num_words * K; + + // Chunk the first num_bits bits into K-bit words. + let words = { + // Take first num_bits bits of `element`. + let bits = element.value().map(|element| { + element + .to_le_bits() + .into_iter() + .take(num_bits) + .collect::>() + }); + + bits.map(|bits| { + bits.chunks_exact(K) + .map(|word| F::from(lebs2ip::(&(word.try_into().unwrap())))) + .collect::>() + }) + .transpose_vec(num_words) + }; + + let mut zs = vec![element.clone()]; + + // Assign cumulative sum such that + // z_i = 2^{K}â‹…z_{i + 1} + a_i + // => z_{i + 1} = (z_i - a_i) / (2^K) + // + // For `element` = a_0 + 2^10 a_1 + ... + 2^{120} a_{12}}, initialize z_0 = `element`. + // If `element` fits in 130 bits, we end up with z_{13} = 0. + let mut z = element; + let inv_two_pow_k = F::from(1u64 << K).invert().unwrap(); + for (idx, word) in words.iter().enumerate() { + // Enable q_lookup on this row + self.q_lookup.enable(region, idx)?; + // Enable q_running on this row + self.q_running.enable(region, idx)?; + + // z_next = (z_cur - m_cur) / 2^K + z = { + let z_val = z + .value() + .zip(*word) + .map(|(z, word)| (*z - word) * inv_two_pow_k); + + // Assign z_next + region.assign_advice( + || format!("z_{:?}", idx + 1), + self.running_sum, + idx + 1, + || z_val, + )? + }; + zs.push(z.clone()); + } + + if strict { + // Constrain the final `z` to be zero. + region.constrain_constant(zs.last().unwrap().cell(), F::ZERO)?; + } + + Ok(RunningSum(zs)) + } + + /// Short range check on an existing cell that is copied into this helper. + /// + /// # Panics + /// + /// Panics if NUM_BITS is equal to or larger than K. + pub fn copy_short_check( + &self, + mut layouter: impl Layouter, + element: AssignedCell, + num_bits: usize, + ) -> Result<(), Error> { + assert!(num_bits < K); + layouter.assign_region( + || format!("Range check {:?} bits", num_bits), + |mut region| { + // Copy `element` to use in the k-bit lookup. + let element = + element.copy_advice(|| "element", &mut region, self.running_sum, 0)?; + + self.short_range_check(&mut region, element, num_bits) + }, + ) + } + + /// Short range check on value that is witnessed in this helper. + /// + /// # Panics + /// + /// Panics if num_bits is larger than K. + pub fn witness_short_check( + &self, + mut layouter: impl Layouter, + element: Value, + num_bits: usize, + ) -> Result, Error> { + assert!(num_bits <= K); + layouter.assign_region( + || format!("Range check {:?} bits", num_bits), + |mut region| { + // Witness `element` to use in the k-bit lookup. + let element = + region.assign_advice(|| "Witness element", self.running_sum, 0, || element)?; + + self.short_range_check(&mut region, element.clone(), num_bits)?; + + Ok(element) + }, + ) + } + + /// Constrain `x` to be a NUM_BITS word. + /// + /// `element` must have been assigned to `self.running_sum` at offset 0. + fn short_range_check( + &self, + region: &mut Region<'_, F>, + element: AssignedCell, + num_bits: usize, + ) -> Result<(), Error> { + // Enable lookup for `element`, to constrain it to 10 bits. + self.q_lookup.enable(region, 0)?; + + // Enable lookup for shifted element, to constrain it to 10 bits. + self.q_lookup.enable(region, 1)?; + + // Check element has been shifted by the correct number of bits. + self.q_bitshift.enable(region, 1)?; + + // Assign shifted `element * 2^{K - num_bits}` + let shifted = element.value().into_field() * F::from(1 << (K - num_bits)); + + region.assign_advice( + || format!("element * 2^({}-{})", K, num_bits), + self.running_sum, + 1, + || shifted, + )?; + + // Assign 2^{-num_bits} from a fixed column. + let inv_two_pow_s = F::from(1 << num_bits).invert().unwrap(); + region.assign_advice_from_constant( + || format!("2^(-{})", num_bits), + self.running_sum, + 2, + inv_two_pow_s, + )?; + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::LookupRangeCheckConfig; + + use super::super::lebs2ip; + use crate::sinsemilla::primitives::K; + + use ff::{Field, PrimeFieldBits}; + use halo2_proofs::{ + circuit::{Layouter, SimpleFloorPlanner, Value}, + dev::{FailureLocation, MockProver, VerifyFailure}, + plonk::{Circuit, ConstraintSystem, Error}, + }; + use halo2_curves::pasta::pallas; + + use std::{convert::TryInto, marker::PhantomData}; + + #[test] + fn lookup_range_check() { + #[derive(Clone, Copy)] + struct MyCircuit { + num_words: usize, + _marker: PhantomData, + } + + impl Circuit for MyCircuit { + type Config = LookupRangeCheckConfig; + type FloorPlanner = SimpleFloorPlanner; + #[cfg(feature = "circuit-params")] + type Params = (); + + fn without_witnesses(&self) -> Self { + *self + } + + fn configure(meta: &mut ConstraintSystem) -> Self::Config { + let running_sum = meta.advice_column(); + let table_idx = meta.lookup_table_column(); + let constants = meta.fixed_column(); + meta.enable_constant(constants); + + LookupRangeCheckConfig::::configure(meta, running_sum, table_idx) + } + + fn synthesize( + &self, + config: Self::Config, + mut layouter: impl Layouter, + ) -> Result<(), Error> { + // Load table_idx + config.load(&mut layouter)?; + + // Lookup constraining element to be no longer than num_words * K bits. + let elements_and_expected_final_zs = [ + (F::from((1 << (self.num_words * K)) - 1), F::ZERO, true), // a word that is within self.num_words * K bits long + (F::from(1 << (self.num_words * K)), F::ONE, false), // a word that is just over self.num_words * K bits long + ]; + + fn expected_zs( + element: F, + num_words: usize, + ) -> Vec { + let chunks = { + element + .to_le_bits() + .iter() + .by_vals() + .take(num_words * K) + .collect::>() + .chunks_exact(K) + .map(|chunk| F::from(lebs2ip::(chunk.try_into().unwrap()))) + .collect::>() + }; + let expected_zs = { + let inv_two_pow_k = F::from(1 << K).invert().unwrap(); + chunks.iter().fold(vec![element], |mut zs, a_i| { + // z_{i + 1} = (z_i - a_i) / 2^{K} + let z = (zs[zs.len() - 1] - a_i) * inv_two_pow_k; + zs.push(z); + zs + }) + }; + expected_zs + } + + for (element, expected_final_z, strict) in elements_and_expected_final_zs.iter() { + let expected_zs = expected_zs::(*element, self.num_words); + + let zs = config.witness_check( + layouter.namespace(|| format!("Lookup {:?}", self.num_words)), + Value::known(*element), + self.num_words, + *strict, + )?; + + assert_eq!(*expected_zs.last().unwrap(), *expected_final_z); + + for (expected_z, z) in expected_zs.into_iter().zip(zs.iter()) { + z.value().assert_if_known(|z| &&expected_z == z); + } + } + Ok(()) + } + } + + { + let circuit: MyCircuit = MyCircuit { + num_words: 6, + _marker: PhantomData, + }; + + let prover = MockProver::::run(11, &circuit, vec![]).unwrap(); + assert_eq!(prover.verify(), Ok(())); + } + } + + #[test] + fn short_range_check() { + struct MyCircuit { + element: Value, + num_bits: usize, + } + + impl Circuit for MyCircuit { + type Config = LookupRangeCheckConfig; + type FloorPlanner = SimpleFloorPlanner; + #[cfg(feature = "circuit-params")] + type Params = (); + + fn without_witnesses(&self) -> Self { + MyCircuit { + element: Value::unknown(), + num_bits: self.num_bits, + } + } + + fn configure(meta: &mut ConstraintSystem) -> Self::Config { + let running_sum = meta.advice_column(); + let table_idx = meta.lookup_table_column(); + let constants = meta.fixed_column(); + meta.enable_constant(constants); + + LookupRangeCheckConfig::::configure(meta, running_sum, table_idx) + } + + fn synthesize( + &self, + config: Self::Config, + mut layouter: impl Layouter, + ) -> Result<(), Error> { + // Load table_idx + config.load(&mut layouter)?; + + // Lookup constraining element to be no longer than num_bits. + config.witness_short_check( + layouter.namespace(|| format!("Lookup {:?} bits", self.num_bits)), + self.element, + self.num_bits, + )?; + + Ok(()) + } + } + + // Edge case: zero bits + { + let circuit: MyCircuit = MyCircuit { + element: Value::known(pallas::Base::zero()), + num_bits: 0, + }; + let prover = MockProver::::run(11, &circuit, vec![]).unwrap(); + assert_eq!(prover.verify(), Ok(())); + } + + // Edge case: K bits + { + let circuit: MyCircuit = MyCircuit { + element: Value::known(pallas::Base::from((1 << K) - 1)), + num_bits: K, + }; + let prover = MockProver::::run(11, &circuit, vec![]).unwrap(); + assert_eq!(prover.verify(), Ok(())); + } + + // Element within `num_bits` + { + let circuit: MyCircuit = MyCircuit { + element: Value::known(pallas::Base::from((1 << 6) - 1)), + num_bits: 6, + }; + let prover = MockProver::::run(11, &circuit, vec![]).unwrap(); + assert_eq!(prover.verify(), Ok(())); + } + + // Element larger than `num_bits` but within K bits + { + let circuit: MyCircuit = MyCircuit { + element: Value::known(pallas::Base::from(1 << 6)), + num_bits: 6, + }; + let prover = MockProver::::run(11, &circuit, vec![]).unwrap(); + assert_eq!( + prover.verify(), + Err(vec![VerifyFailure::Lookup { + name: "lookup".to_string(), + lookup_index: 0, + location: FailureLocation::InRegion { + region: (1, "Range check 6 bits").into(), + offset: 1, + }, + }]), + ); + } + + // Element larger than K bits + { + let circuit: MyCircuit = MyCircuit { + element: Value::known(pallas::Base::from(1 << K)), + num_bits: 6, + }; + let prover = MockProver::::run(11, &circuit, vec![]).unwrap(); + assert_eq!( + prover.verify(), + Err(vec![ + VerifyFailure::Lookup { + name: "lookup".to_string(), + lookup_index: 0, + location: FailureLocation::InRegion { + region: (1, "Range check 6 bits").into(), + offset: 0, + }, + }, + VerifyFailure::Lookup { + name: "lookup".to_string(), + lookup_index: 0, + location: FailureLocation::InRegion { + region: (1, "Range check 6 bits").into(), + offset: 1, + }, + }, + ]) + ); + } + + // Element which is not within `num_bits`, but which has a shifted value within + // num_bits + { + let num_bits = 6; + let shifted = pallas::Base::from((1 << num_bits) - 1); + // Recall that shifted = element * 2^{K-s} + // => element = shifted * 2^{s-K} + let element = shifted + * pallas::Base::from(1 << (K as u64 - num_bits)) + .invert() + .unwrap(); + let circuit: MyCircuit = MyCircuit { + element: Value::known(element), + num_bits: num_bits as usize, + }; + let prover = MockProver::::run(11, &circuit, vec![]).unwrap(); + assert_eq!( + prover.verify(), + Err(vec![VerifyFailure::Lookup { + name: "lookup".to_string(), + lookup_index: 0, + location: FailureLocation::InRegion { + region: (1, "Range check 6 bits").into(), + offset: 0, + }, + }]) + ); + } + } +} From abcbf1825271d831f209a41eae5da33fb5d10249 Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Fri, 20 Dec 2024 12:53:26 +0000 Subject: [PATCH 02/35] sum check comments and and changing to BN254 field for poseidon circuit --- .../src/backend/hyperplonk/verifier.rs | 4 + .../halo2/poseidongadget/poseidon/pow5.rs | 134 ++++++++++++++++-- .../poseidongadget/poseidon/primitives.rs | 3 + .../src/pcs/multilinear/zeromorph.rs | 1 - .../src/piop/sum_check/classic/eval.rs | 1 + plonkish_backend/src/poly/multilinear.rs | 1 + plonkish_backend/src/util/arithmetic/msm.rs | 1 - 7 files changed, 130 insertions(+), 15 deletions(-) diff --git a/plonkish_backend/src/backend/hyperplonk/verifier.rs b/plonkish_backend/src/backend/hyperplonk/verifier.rs index 4a20ef67..d730b2cb 100644 --- a/plonkish_backend/src/backend/hyperplonk/verifier.rs +++ b/plonkish_backend/src/backend/hyperplonk/verifier.rs @@ -48,6 +48,8 @@ pub(crate) fn verify_sum_check( y: &[F], transcript: &mut impl FieldTranscriptRead, ) -> Result<(Vec>, Vec>), Error> { + // In description of the sum check protocol in https://eprint.iacr.org/2022/1355.pdf, + // x_eval corresponds to the v in the final check, x is \alpha_1, ..., \alpha_{\mu} the challenges during the sum check protocol let (x_eval, x) = ClassicSumCheck::, BinaryField>::verify( &(), num_vars, @@ -56,6 +58,7 @@ pub(crate) fn verify_sum_check( transcript, )?; + // Check that f(\alpha_1, ..., \alpha_{\mu}) = v holds, where f is the expression let pcs_query = pcs_query(expression, instances.len()); let (evals_for_rotation, evals) = pcs_query .iter() @@ -79,6 +82,7 @@ pub(crate) fn verify_sum_check( )); } + // Obtain points and evaluations for which we need to verify the opening proofs let point_offset = point_offset(&pcs_query); let evals = pcs_query .iter() diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/pow5.rs b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/pow5.rs index 18a80c50..952fdc10 100644 --- a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/pow5.rs +++ b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/pow5.rs @@ -29,6 +29,7 @@ pub struct Pow5Config { half_full_rounds: usize, half_partial_rounds: usize, + // alpha represents exponent in s-box alpha: [u64; 4], round_constants: Vec<[F; WIDTH]>, m_reg: Mds, @@ -589,27 +590,46 @@ mod tests { use halo2_proofs::{ circuit::{Layouter, SimpleFloorPlanner, Value}, dev::MockProver, - plonk::{Circuit, ConstraintSystem, Error}, + plonk::{Circuit, ConstraintSystem, Error,keygen_vk,keygen_pk,create_proof,verify_proof}, + poly::kzg::{commitment::{KZGCommitmentScheme,ParamsKZG},multiopen::{ProverGWC, VerifierGWC},strategy::SingleStrategy,}, + transcript::{Blake2bRead, Blake2bWrite, Challenge255, TranscriptReadBuffer, TranscriptWriterBuffer}, }; use halo2_curves::pasta::{pallas, Fp}; + use halo2_curves::bn256::{Bn256,Fr,Fq}; + use halo2_curves::grumpkin; use rand::rngs::OsRng; use super::{PoseidonInstructions, Pow5Chip, Pow5Config, StateWord}; use crate::frontend::halo2::poseidongadget::poseidon::{ - primitives::{self as poseidon, ConstantLength, P128Pow5T3 as OrchardNullifier, Spec}, + primitives::{self as poseidon, ConstantLength, P128Pow5T3 as OrchardNullifier, BN256param as newParam, Spec}, Hash, }; use std::convert::TryInto; use std::marker::PhantomData; - struct PermuteCircuit, const WIDTH: usize, const RATE: usize>( + use crate::backend::{ + hyperplonk::HyperPlonk, + PlonkishCircuit, + PlonkishBackend, + }; + + use crate::{ + frontend::halo2::{CircuitExt,Halo2Circuit}, + pcs::{multilinear::{MultilinearKzg,Zeromorph},univariate::{UnivariateKzg,UnivariateIpa}}, + util::{ + transcript::{InMemoryTranscript,Keccak256Transcript}, + test::seeded_std_rng, + } + }; + + struct PermuteCircuit, const WIDTH: usize, const RATE: usize>( PhantomData, ); - impl, const WIDTH: usize, const RATE: usize> Circuit + impl, const WIDTH: usize, const RATE: usize> Circuit for PermuteCircuit { - type Config = Pow5Config; + type Config = Pow5Config; type FloorPlanner = SimpleFloorPlanner; #[cfg(feature = "circuit-params")] type Params = (); @@ -618,7 +638,7 @@ mod tests { PermuteCircuit::(PhantomData) } - fn configure(meta: &mut ConstraintSystem) -> Pow5Config { + fn configure(meta: &mut ConstraintSystem) -> Pow5Config { let state = (0..WIDTH).map(|_| meta.advice_column()).collect::>(); let partial_sbox = meta.advice_column(); @@ -636,14 +656,14 @@ mod tests { fn synthesize( &self, - config: Pow5Config, - mut layouter: impl Layouter, + config: Pow5Config, + mut layouter: impl Layouter, ) -> Result<(), Error> { let initial_state = layouter.assign_region( || "prepare initial state", |mut region| { let state_word = |i: usize| { - let value = Value::known(Fp::from(i as u64)); + let value = Value::known(Fr::from(i as u64)); let var = region.assign_advice( || format!("load state_{}", i), config.state[i], @@ -660,7 +680,7 @@ mod tests { let chip = Pow5Chip::construct(config.clone()); let final_state = as PoseidonInstructions< - Fp, + Fr, S, WIDTH, RATE, @@ -668,7 +688,7 @@ mod tests { // For the purpose of this test, compute the real final state inline. let mut expected_final_state = (0..WIDTH) - .map(|idx| Fp::from(idx as u64)) + .map(|idx| Fr::from(idx as u64)) .collect::>() .try_into() .unwrap(); @@ -678,7 +698,6 @@ mod tests { &mds, &round_constants, ); - layouter.assign_region( || "constrain final state", |mut region| { @@ -702,12 +721,100 @@ mod tests { } } - #[test] + impl CircuitExt for PermuteCircuit::, 6, 5> { + + fn instances(&self) -> Vec> { + /*let mut expected_final_state = (0..7) + .map(|idx| Fq::from(idx as u64)) + .collect::>() + .try_into() + .unwrap();*/ + Vec::new() + } + } + + /* #[test] fn poseidon_permute() { let k = 6; let circuit = PermuteCircuit::(PhantomData); let prover = MockProver::run::<_, true>(k, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())) + }*/ + #[test] + fn poseidon_permute_new_param() { + type Pb = HyperPlonk>>; + let circuit = Halo2Circuit::new::(6, PermuteCircuit::, 6, 5>(PhantomData)); + let param = Pb::setup(&circuit.circuit_info().unwrap(), seeded_std_rng()).unwrap(); + let (pp, vp) = Pb::preprocess(¶m, &circuit.circuit_info().unwrap()).unwrap(); + let proof = { + let mut transcript = Keccak256Transcript::new(()); + Pb::prove(&pp, &circuit, &mut transcript, seeded_std_rng()).unwrap(); + transcript.into_proof() + }; + let result = { + let mut transcript = Keccak256Transcript::from_proof((), proof.as_slice()); + Pb::verify(&vp, circuit.instances(), &mut transcript, seeded_std_rng()) + }; + assert_eq!(result, Ok(())) + //assert!(false) + + /*let k =6; + let circuit = PermuteCircuit::, 7, 6>(PhantomData); + let prover = MockProver::run::<_, false>(k, &circuit, vec![]).unwrap(); + //assert_eq!(prover.verify(), Ok(())) + prover.assert_satisfied()*/ + + /*let k =6; + let circuit = PermuteCircuit::, 7, 6>(PhantomData); + let prover = MockProver::run::<_, true>(k, &circuit, vec![]).unwrap(); + //assert_eq!(prover.verify(), Ok(())) + prover.assert_satisfied()*/ + + /*let k =6; + let params = ParamsKZG::::setup(k, seeded_std_rng()); + let circuit = PermuteCircuit::, 7, 6>(PhantomData); + let vk = + keygen_vk::<_, _, _, true>(¶ms, &circuit).expect("keygen_vk should not fail"); + let pk = keygen_pk::<_, _, _, true>(¶ms, vk, &circuit) + .expect("keygen_pk should not fail"); + let instances_vec: Vec<&[Fr]> = Vec::new(); + let instances: &[&[Fr]] = &instances_vec; + let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); + create_proof::< + KZGCommitmentScheme, + ProverGWC<'_, Bn256>, + _, + _, + _, + _, + true, + >( + ¶ms, + &pk, + &[circuit], + &[instances], + seeded_std_rng(), + &mut transcript, + ) + .expect("prover should not fail"); + let proof = transcript.finalize(); + let strategy = SingleStrategy::new(¶ms); + let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]); + let result = verify_proof::< + KZGCommitmentScheme, + VerifierGWC<'_, Bn256>, + _, + _, + SingleStrategy<'_, Bn256>, + true, + >( + ¶ms, + pk.get_vk(), + strategy, + &[instances], + &mut transcript + ).is_ok(); + assert!(result)*/ } struct HashCircuit< @@ -880,4 +987,5 @@ mod tests { .render(6, &circuit, &root) .unwrap(); } + } diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives.rs b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives.rs index f638feff..5582de6f 100644 --- a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives.rs +++ b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives.rs @@ -20,6 +20,9 @@ pub(crate) mod test_vectors; mod p128pow5t3; pub use p128pow5t3::P128Pow5T3; +mod bn256param; +pub use bn256param::BN256param; + use grain::SboxType; /// The type used to hold permutation state. diff --git a/plonkish_backend/src/pcs/multilinear/zeromorph.rs b/plonkish_backend/src/pcs/multilinear/zeromorph.rs index abc6fde3..81a71d69 100644 --- a/plonkish_backend/src/pcs/multilinear/zeromorph.rs +++ b/plonkish_backend/src/pcs/multilinear/zeromorph.rs @@ -379,7 +379,6 @@ where let comm = if cfg!(feature = "sanity-check") { assert_eq!(f.evaluate(&x), C::Scalar::ZERO); - UnivariateIpa::::commit(pp, &f)? } else { Default::default() diff --git a/plonkish_backend/src/piop/sum_check/classic/eval.rs b/plonkish_backend/src/piop/sum_check/classic/eval.rs index 429c16a1..62bcfb39 100644 --- a/plonkish_backend/src/piop/sum_check/classic/eval.rs +++ b/plonkish_backend/src/piop/sum_check/classic/eval.rs @@ -24,6 +24,7 @@ impl Evaluations { Self(vec![F::ZERO; degree + 1]) } + // All points between 0 and degree +1 fn points(degree: usize) -> Vec { steps(F::ZERO).take(degree + 1).collect() } diff --git a/plonkish_backend/src/poly/multilinear.rs b/plonkish_backend/src/poly/multilinear.rs index c673eb66..efd9f67c 100644 --- a/plonkish_backend/src/poly/multilinear.rs +++ b/plonkish_backend/src/poly/multilinear.rs @@ -195,6 +195,7 @@ impl MultilinearPolynomial { Self::new(output) } + // New polynomial with first variable fixed to x_i, i.e. f(X_i, .., X_n) becomes f(x_i, X_{i+1}, .., X_n). pub fn fix_var_in_place(&mut self, x_i: &F, buf: &mut Self) { merge_into(&mut buf.evals, self.evals(), x_i, 1, 0); buf.num_vars = self.num_vars - 1; diff --git a/plonkish_backend/src/util/arithmetic/msm.rs b/plonkish_backend/src/util/arithmetic/msm.rs index 3ca3d2a2..4764863f 100644 --- a/plonkish_backend/src/util/arithmetic/msm.rs +++ b/plonkish_backend/src/util/arithmetic/msm.rs @@ -157,7 +157,6 @@ fn variable_base_msm_serial( } } } - let scalars = scalars.iter().map(|scalar| scalar.to_repr()).collect_vec(); let num_bytes = scalars[0].as_ref().len(); let num_bits = 8 * num_bytes; From 715e098ed85c4a377c48959a026f827c9cea8e28 Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Fri, 20 Dec 2024 16:39:45 +0000 Subject: [PATCH 03/35] add parameter file and reduce parameter --- .../halo2/poseidongadget/poseidon/pow5.rs | 4 +- .../poseidon/primitives/bn256param.rs | 165 ++++++++++++++++++ 2 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/bn256param.rs diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/pow5.rs b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/pow5.rs index 952fdc10..a79fb334 100644 --- a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/pow5.rs +++ b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/pow5.rs @@ -721,7 +721,7 @@ mod tests { } } - impl CircuitExt for PermuteCircuit::, 6, 5> { + impl CircuitExt for PermuteCircuit::, 5, 4> { fn instances(&self) -> Vec> { /*let mut expected_final_state = (0..7) @@ -743,7 +743,7 @@ mod tests { #[test] fn poseidon_permute_new_param() { type Pb = HyperPlonk>>; - let circuit = Halo2Circuit::new::(6, PermuteCircuit::, 6, 5>(PhantomData)); + let circuit = Halo2Circuit::new::(6, PermuteCircuit::, 5, 4>(PhantomData)); let param = Pb::setup(&circuit.circuit_info().unwrap(), seeded_std_rng()).unwrap(); let (pp, vp) = Pb::preprocess(¶m, &circuit.circuit_info().unwrap()).unwrap(); let proof = { diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/bn256param.rs b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/bn256param.rs new file mode 100644 index 00000000..d1f5e474 --- /dev/null +++ b/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/bn256param.rs @@ -0,0 +1,165 @@ +// TO DO: don't want to use two lines below +use halo2_proofs::arithmetic::Field; +use super::{Mds, Spec}; +use halo2_curves::bn256::Fr; +use crate::frontend::halo2::poseidongadget::poseidon::primitives::generate_constants; + +// To do rewrite this below +/// 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". +/// +/// The standard specification for this set of parameters (on either of the Pasta +/// fields) uses $R_F = 8, R_P = 56$. This is conveniently an even number of +/// partial rounds, making it easier to construct a Halo 2 circuit. +#[derive(Debug)] +// Do we have to specify width and rate generically? +pub struct BN256param; + +impl Spec for BN256param { + fn full_rounds() -> usize { + 8 + } + + fn partial_rounds() -> usize { + //TO DO: we need an even number of partial rounds - can we round up + match T { + 2 => 56, + // Rounded up from 57 + 3 => 58, + 4 => 56, + 5 => 60, + 6 => 60, + // Rounded up from 63 + 7 => 64, + _ => unimplemented!(), + } + } + + fn sbox(val: Fr) -> Fr { + val.pow_vartime([5]) + } + + fn secure_mds() -> usize { + SECURE_MDS + } + + fn constants() -> (Vec<[Fr; T]>, Mds, Mds) { + // TO DO: manually generate the constants here + generate_constants::<_, Self, T, R>() + } +} + +// TO DO Remove both + + +#[cfg(test)] +mod tests { + #![allow(dead_code)] + use crate::frontend::halo2::poseidongadget::poseidon::primitives::{ + generate_constants, permute, ConstantLength, Hash, Mds, Spec, + }; + use ff::PrimeField; + use ff::{Field, FromUniformBytes}; + use std::marker::PhantomData; + + /// The same Poseidon specification as poseidon::P128Pow5T3, but constructed + /// such that its constants will be generated at runtime. + #[derive(Debug)] + // to do change Field to Fr? + pub struct BN256paramGen(PhantomData); + + impl BN256paramGen { + pub fn new() -> Self { + BN256paramGen(PhantomData) + } + } + + impl + Ord, const SECURE_MDS: usize> Spec for BN256paramGen { + fn full_rounds() -> usize { + 8 + } + + fn partial_rounds() -> usize { + //TO DO: we need an even number of partial rounds - can we round up + match T { + 2 => 56, + // Rounded up from 57 + 3 => 58, + 4 => 56, + 5 => 60, + 6 => 60, + // Rounded up from 63 + 7 => 64, + _ => unimplemented!(), + } + } + + fn sbox(val: F) -> F { + val.pow_vartime([5]) + } + + fn secure_mds() -> usize { + SECURE_MDS + } + + fn constants() -> (Vec<[F; T]>, Mds, Mds) { + // TO DO: manually generate the constants here + generate_constants::<_, Self, T, R>() + } + } + + #[test] + #[ignore] + fn verify_constants() { + // TO DO: write this as in p128pow5t3.rs once we have the constants manually generated + } + + #[test] + #[ignore] + fn test_against_reference() { + // TO DO: write this as in p128pow5t3.rs once we have the constants manually generated + } + + #[test] + #[ignore] + fn permute_test_vectors() { + + /* macro_rules! permute_test_vectors { + ($t:expr) => { + { + r = $t - 1; + let (round_constants, mds, _) = super::BN256param::<$t,r>::constants(); + + // Generate test vectors for the permutation + for tv in crate::frontend::halo2::poseidongadget::poseidon::primitives::test_vectors::fp::permute() { + let mut state = [ + Fp::from_repr(tv.initial_state[0]).unwrap(), + Fp::from_repr(tv.initial_state[1]).unwrap(), + Fp::from_repr(tv.initial_state[2]).unwrap(), + ]; + + permute::, $t, r>(&mut state, &mds, &round_constants); + + for (expected, actual) in tv.final_state.iter().zip(state.iter()) { + assert_eq!(&actual.to_repr(), expected); + } + } + } + + }; + } + + for t in 1..7 { + permute_test_vectors!(t); + + }*/ + + + } + + #[test] + #[ignore] + // Generate test vectors for the permutation and adapt this + fn hash_test_vectors() { + } +} From ed084d470ff05665150cb7b9a27bd82c051c73fc Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Fri, 20 Dec 2024 17:41:12 +0000 Subject: [PATCH 04/35] move into circuits folder --- plonkish_backend/src/circuits.rs | 1 + .../src/{frontend/halo2 => circuits}/poseidongadget.rs | 0 .../halo2 => circuits}/poseidongadget/poseidon.rs | 0 .../halo2 => circuits}/poseidongadget/poseidon/pow5.rs | 6 +++--- .../poseidongadget/poseidon/primitives.rs | 0 .../poseidongadget/poseidon/primitives/bn256param.rs | 4 ++-- .../poseidongadget/poseidon/primitives/fp.rs | 0 .../poseidongadget/poseidon/primitives/fq.rs | 0 .../poseidongadget/poseidon/primitives/grain.rs | 0 .../poseidongadget/poseidon/primitives/mds.rs | 0 .../poseidongadget/poseidon/primitives/p128pow5t3.rs | 10 +++++----- .../poseidongadget/poseidon/primitives/test_vectors.rs | 0 .../halo2 => circuits}/poseidongadget/utilities.rs | 0 .../poseidongadget/utilities/cond_swap.rs | 0 .../poseidongadget/utilities/rm_lookup_range_check.rs | 0 plonkish_backend/src/frontend/halo2.rs | 1 - plonkish_backend/src/lib.rs | 1 + 17 files changed, 12 insertions(+), 11 deletions(-) create mode 100644 plonkish_backend/src/circuits.rs rename plonkish_backend/src/{frontend/halo2 => circuits}/poseidongadget.rs (100%) rename plonkish_backend/src/{frontend/halo2 => circuits}/poseidongadget/poseidon.rs (100%) rename plonkish_backend/src/{frontend/halo2 => circuits}/poseidongadget/poseidon/pow5.rs (99%) rename plonkish_backend/src/{frontend/halo2 => circuits}/poseidongadget/poseidon/primitives.rs (100%) rename plonkish_backend/src/{frontend/halo2 => circuits}/poseidongadget/poseidon/primitives/bn256param.rs (96%) rename plonkish_backend/src/{frontend/halo2 => circuits}/poseidongadget/poseidon/primitives/fp.rs (100%) rename plonkish_backend/src/{frontend/halo2 => circuits}/poseidongadget/poseidon/primitives/fq.rs (100%) rename plonkish_backend/src/{frontend/halo2 => circuits}/poseidongadget/poseidon/primitives/grain.rs (100%) rename plonkish_backend/src/{frontend/halo2 => circuits}/poseidongadget/poseidon/primitives/mds.rs (100%) rename plonkish_backend/src/{frontend/halo2 => circuits}/poseidongadget/poseidon/primitives/p128pow5t3.rs (94%) rename plonkish_backend/src/{frontend/halo2 => circuits}/poseidongadget/poseidon/primitives/test_vectors.rs (100%) rename plonkish_backend/src/{frontend/halo2 => circuits}/poseidongadget/utilities.rs (100%) rename plonkish_backend/src/{frontend/halo2 => circuits}/poseidongadget/utilities/cond_swap.rs (100%) rename plonkish_backend/src/{frontend/halo2 => circuits}/poseidongadget/utilities/rm_lookup_range_check.rs (100%) diff --git a/plonkish_backend/src/circuits.rs b/plonkish_backend/src/circuits.rs new file mode 100644 index 00000000..5eaed0c2 --- /dev/null +++ b/plonkish_backend/src/circuits.rs @@ -0,0 +1 @@ +pub mod poseidongadget; diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget.rs b/plonkish_backend/src/circuits/poseidongadget.rs similarity index 100% rename from plonkish_backend/src/frontend/halo2/poseidongadget.rs rename to plonkish_backend/src/circuits/poseidongadget.rs diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon.rs similarity index 100% rename from plonkish_backend/src/frontend/halo2/poseidongadget/poseidon.rs rename to plonkish_backend/src/circuits/poseidongadget/poseidon.rs diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/pow5.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs similarity index 99% rename from plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/pow5.rs rename to plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs index a79fb334..1e91434c 100644 --- a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/pow5.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs @@ -14,7 +14,7 @@ use super::{ primitives::{Absorbing, Domain, Mds, Spec, Squeezing, State}, PaddedWord, PoseidonInstructions, PoseidonSpongeInstructions, }; -use crate::frontend::halo2::poseidongadget::utilities::Var; +use crate::circuits::poseidongadget::utilities::Var; /// Configuration for a [`Pow5Chip`]. #[derive(Clone, Debug)] @@ -600,7 +600,7 @@ mod tests { use rand::rngs::OsRng; use super::{PoseidonInstructions, Pow5Chip, Pow5Config, StateWord}; - use crate::frontend::halo2::poseidongadget::poseidon::{ + use crate::circuits::poseidongadget::poseidon::{ primitives::{self as poseidon, ConstantLength, P128Pow5T3 as OrchardNullifier, BN256param as newParam, Spec}, Hash, }; @@ -948,7 +948,7 @@ mod tests { #[test] fn hash_test_vectors() { - for tv in crate::frontend::halo2::poseidongadget::poseidon::primitives::test_vectors::fp::hash() { + for tv in crate::circuits::poseidongadget::poseidon::primitives::test_vectors::fp::hash() { let message = [ pallas::Base::from_repr(tv.input[0]).unwrap(), pallas::Base::from_repr(tv.input[1]).unwrap(), diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives.rs similarity index 100% rename from plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives.rs rename to plonkish_backend/src/circuits/poseidongadget/poseidon/primitives.rs diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/bn256param.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs similarity index 96% rename from plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/bn256param.rs rename to plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs index d1f5e474..38825fcd 100644 --- a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/bn256param.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs @@ -2,7 +2,7 @@ use halo2_proofs::arithmetic::Field; use super::{Mds, Spec}; use halo2_curves::bn256::Fr; -use crate::frontend::halo2::poseidongadget::poseidon::primitives::generate_constants; +use crate::circuits::poseidongadget::poseidon::primitives::generate_constants; // To do rewrite this below /// Poseidon-128 using the $x^5$ S-box, with a width of 3 field elements, and the @@ -55,7 +55,7 @@ impl Spec fo #[cfg(test)] mod tests { #![allow(dead_code)] - use crate::frontend::halo2::poseidongadget::poseidon::primitives::{ + use crate::circuits::poseidongadget::poseidon::primitives::{ generate_constants, permute, ConstantLength, Hash, Mds, Spec, }; use ff::PrimeField; diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/fp.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/fp.rs similarity index 100% rename from plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/fp.rs rename to plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/fp.rs diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/fq.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/fq.rs similarity index 100% rename from plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/fq.rs rename to plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/fq.rs diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/grain.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/grain.rs similarity index 100% rename from plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/grain.rs rename to plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/grain.rs diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/mds.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/mds.rs similarity index 100% rename from plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/mds.rs rename to plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/mds.rs diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/p128pow5t3.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/p128pow5t3.rs similarity index 94% rename from plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/p128pow5t3.rs rename to plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/p128pow5t3.rs index 8b074e35..b3493199 100644 --- a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/p128pow5t3.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/p128pow5t3.rs @@ -71,7 +71,7 @@ mod tests { super::{fp, fq}, Fp, Fq, }; - use crate::frontend::halo2::poseidongadget::poseidon::primitives::{ + use crate::circuits::poseidongadget::poseidon::primitives::{ generate_constants, permute, ConstantLength, Hash, Mds, Spec, }; use ff::PrimeField; @@ -257,7 +257,7 @@ mod tests { { let (round_constants, mds, _) = super::P128Pow5T3::constants(); - for tv in crate::frontend::halo2::poseidongadget::poseidon::primitives::test_vectors::fp::permute() { + for tv in crate::circuits::poseidongadget::poseidon::primitives::test_vectors::fp::permute() { let mut state = [ Fp::from_repr(tv.initial_state[0]).unwrap(), Fp::from_repr(tv.initial_state[1]).unwrap(), @@ -275,7 +275,7 @@ mod tests { { let (round_constants, mds, _) = super::P128Pow5T3::constants(); - for tv in crate::frontend::halo2::poseidongadget::poseidon::primitives::test_vectors::fq::permute() { + for tv in crate::circuits::poseidongadget::poseidon::primitives::test_vectors::fq::permute() { let mut state = [ Fq::from_repr(tv.initial_state[0]).unwrap(), Fq::from_repr(tv.initial_state[1]).unwrap(), @@ -293,7 +293,7 @@ mod tests { #[test] fn hash_test_vectors() { - for tv in crate::frontend::halo2::poseidongadget::poseidon::primitives::test_vectors::fp::hash() { + for tv in crate::circuits::poseidongadget::poseidon::primitives::test_vectors::fp::hash() { let message = [ Fp::from_repr(tv.input[0]).unwrap(), Fp::from_repr(tv.input[1]).unwrap(), @@ -305,7 +305,7 @@ mod tests { assert_eq!(result.to_repr(), tv.output); } - for tv in crate::frontend::halo2::poseidongadget::poseidon::primitives::test_vectors::fq::hash() { + for tv in crate::circuits::poseidongadget::poseidon::primitives::test_vectors::fq::hash() { let message = [ Fq::from_repr(tv.input[0]).unwrap(), Fq::from_repr(tv.input[1]).unwrap(), diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/test_vectors.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/test_vectors.rs similarity index 100% rename from plonkish_backend/src/frontend/halo2/poseidongadget/poseidon/primitives/test_vectors.rs rename to plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/test_vectors.rs diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/utilities.rs b/plonkish_backend/src/circuits/poseidongadget/utilities.rs similarity index 100% rename from plonkish_backend/src/frontend/halo2/poseidongadget/utilities.rs rename to plonkish_backend/src/circuits/poseidongadget/utilities.rs diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/utilities/cond_swap.rs b/plonkish_backend/src/circuits/poseidongadget/utilities/cond_swap.rs similarity index 100% rename from plonkish_backend/src/frontend/halo2/poseidongadget/utilities/cond_swap.rs rename to plonkish_backend/src/circuits/poseidongadget/utilities/cond_swap.rs diff --git a/plonkish_backend/src/frontend/halo2/poseidongadget/utilities/rm_lookup_range_check.rs b/plonkish_backend/src/circuits/poseidongadget/utilities/rm_lookup_range_check.rs similarity index 100% rename from plonkish_backend/src/frontend/halo2/poseidongadget/utilities/rm_lookup_range_check.rs rename to plonkish_backend/src/circuits/poseidongadget/utilities/rm_lookup_range_check.rs diff --git a/plonkish_backend/src/frontend/halo2.rs b/plonkish_backend/src/frontend/halo2.rs index 09a80454..8b2ef2e0 100644 --- a/plonkish_backend/src/frontend/halo2.rs +++ b/plonkish_backend/src/frontend/halo2.rs @@ -26,7 +26,6 @@ use std::{ pub mod circuit; #[cfg(test)] mod test; -pub mod poseidongadget; pub trait CircuitExt: Circuit { diff --git a/plonkish_backend/src/lib.rs b/plonkish_backend/src/lib.rs index 1cd59eec..ede727b2 100644 --- a/plonkish_backend/src/lib.rs +++ b/plonkish_backend/src/lib.rs @@ -2,6 +2,7 @@ pub mod accumulation; pub mod backend; +pub mod circuits; pub mod frontend; pub mod pcs; pub mod piop; From b6f0f995a2843e504268c87a25d7702cfe7c0028 Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Fri, 20 Dec 2024 17:56:51 +0000 Subject: [PATCH 05/35] Revert "Merge remote-tracking branch 'origin/main' into lydia/poseidoncircuit" This reverts commit 33788fa096e27f2c6643d937f4e0c10eccc6ba8c, reversing changes made to abcbf1825271d831f209a41eae5da33fb5d10249. --- .../src/accumulation/protostar/hyperplonk.rs | 12 +++--- .../protostar/hyperplonk/preprocessor.rs | 7 +++- .../src/accumulation/sangria/hyperplonk.rs | 12 +++--- plonkish_backend/src/backend/hyperplonk.rs | 39 +++++++++++-------- .../src/backend/hyperplonk/preprocessor.rs | 27 +++++++------ .../src/backend/hyperplonk/prover.rs | 13 ++++--- .../src/backend/hyperplonk/util.rs | 2 +- plonkish_backend/src/backend/unihyperplonk.rs | 2 - plonkish_backend/src/frontend/halo2.rs | 33 +++++++++------- .../src/frontend/halo2/circuit.rs | 8 ++-- .../src/pcs/multilinear/brakedown.rs | 2 - .../src/pcs/multilinear/gemini.rs | 16 +++----- plonkish_backend/src/pcs/multilinear/hyrax.rs | 2 - plonkish_backend/src/pcs/multilinear/ipa.rs | 6 +-- plonkish_backend/src/pcs/multilinear/kzg.rs | 7 +--- .../src/pcs/multilinear/zeromorph.rs | 16 ++++---- plonkish_backend/src/pcs/univariate.rs | 4 +- plonkish_backend/src/pcs/univariate/hyrax.rs | 6 +-- plonkish_backend/src/pcs/univariate/ipa.rs | 8 ++-- plonkish_backend/src/pcs/univariate/kzg.rs | 4 +- .../src/piop/sum_check/classic/coeff.rs | 4 +- plonkish_backend/src/util/code/brakedown.rs | 2 - plonkish_backend/src/util/expression.rs | 2 +- rust-toolchain | 2 +- 24 files changed, 112 insertions(+), 124 deletions(-) diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs index 5b61df25..221cab44 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs @@ -595,8 +595,8 @@ pub(crate) mod test { HyperPlonk, }, pcs::{ - multilinear::Zeromorph, - univariate::{UnivariateIpa, UnivariateKzg}, + multilinear::{Gemini, MultilinearIpa, MultilinearKzg, Zeromorph}, + univariate::UnivariateKzg, }, util::{ expression::rotate::BinaryField, @@ -641,10 +641,8 @@ pub(crate) mod test { }; } - //tests!(ipa, MultilinearIpa); - //tests!(kzg, MultilinearKzg); - //tests!(gemini_kzg, Gemini>); + tests!(ipa, MultilinearIpa); + tests!(kzg, MultilinearKzg); + tests!(gemini_kzg, Gemini>); tests!(zeromorph_kzg, Zeromorph>); - //tests!(gemini_ipa, Gemini>); - tests!(zeromorph_ipa, Zeromorph>); } diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs index 3179205e..83d212d4 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs @@ -352,10 +352,13 @@ pub(crate) fn lookup_constraints( let [m, h_input, h_table] = &[m, h, h + 1] .map(|poly| Query::new(poly, Rotation::cur())) .map(Expression::::Polynomial); - let (inputs, tables) = lookup.iter().cloned().unzip::<_, _, Vec<_>, Vec<_>>(); + let (inputs, tables) = lookup + .iter() + .map(|(input, table)| (input, table)) + .unzip::<_, _, Vec<_>, Vec<_>>(); let [input, table] = &[inputs, tables].map(|exprs| { chain![ - exprs.first().cloned(), + exprs.first().cloned().cloned(), exprs .into_iter() .skip(1) diff --git a/plonkish_backend/src/accumulation/sangria/hyperplonk.rs b/plonkish_backend/src/accumulation/sangria/hyperplonk.rs index 1ecf0092..80a44714 100644 --- a/plonkish_backend/src/accumulation/sangria/hyperplonk.rs +++ b/plonkish_backend/src/accumulation/sangria/hyperplonk.rs @@ -7,8 +7,8 @@ pub(crate) mod test { HyperPlonk, }, pcs::{ - multilinear::Zeromorph, - univariate::{UnivariateIpa, UnivariateKzg}, + multilinear::{Gemini, MultilinearIpa, MultilinearKzg, Zeromorph}, + univariate::UnivariateKzg, }, util::{ expression::rotate::BinaryField, @@ -53,10 +53,8 @@ pub(crate) mod test { }; } - //tests!(ipa, MultilinearIpa); - //tests!(kzg, MultilinearKzg); - //tests!(gemini_kzg, Gemini>); + tests!(ipa, MultilinearIpa); + tests!(kzg, MultilinearKzg); + tests!(gemini_kzg, Gemini>); tests!(zeromorph_kzg, Zeromorph>); - //tests!(gemini_ipa, Gemini>); - tests!(zeromorph_ipa, Zeromorph>); } diff --git a/plonkish_backend/src/backend/hyperplonk.rs b/plonkish_backend/src/backend/hyperplonk.rs index 8b1e0f30..48c8296a 100644 --- a/plonkish_backend/src/backend/hyperplonk.rs +++ b/plonkish_backend/src/backend/hyperplonk.rs @@ -135,7 +135,7 @@ where let mut witness_polys = Vec::with_capacity(pp.num_witness_polys.iter().sum()); let mut witness_comms = Vec::with_capacity(witness_polys.len()); let mut challenges = Vec::with_capacity(pp.num_challenges.iter().sum::() + 4); - // For each round, generate multi-linear polynomials from witness columns and commit + // For each round, generate multi-linear polynomials from witness columns and commit for (round, (num_witness_polys, num_challenges)) in pp .num_witness_polys .iter() @@ -162,7 +162,7 @@ where // beta is used to compress the polynomials in the lookup argument let beta = transcript.squeeze_challenge(); - // Generate a compressed multilinear polynomial for each lookup in the vector of lookups + // Generate a compressed multilinear polynomial for each lookup in the vector of lookups let timer = start_timer(|| format!("lookup_compressed_polys-{}", pp.lookups.len())); let lookup_compressed_polys = { let max_lookup_width = pp.lookups.iter().map(Vec::len).max().unwrap_or_default(); @@ -218,7 +218,7 @@ where ] .collect_vec(); challenges.extend([beta, gamma, alpha]); - // Prove the zero check is satisfied for the expression wrt the polynomials + // Prove the zero check is satisfied for the expression wrt the polynomials let (points, evals) = prove_zero_check( pp.num_instances.len(), &pp.expression, @@ -241,7 +241,7 @@ where ] .collect_vec(); let timer = start_timer(|| format!("pcs_batch_open-{}", evals.len())); - // Open all polynomials at the points from the zero check and give the opening proofs + // Open all polynomials at the points from the zero check and give the opening proofs Pcs::batch_open(&pp.pcs, polys, comms, &points, &evals, transcript)?; end_timer(timer); // Proof is saved in transcript @@ -298,7 +298,7 @@ where let y = transcript.squeeze_challenges(vp.num_vars); challenges.extend([beta, gamma, alpha]); - // Verify the zero check for the constraints defined in the expression + // Verify the zero check for the constraints defined in the expression let (points, evals) = verify_zero_check( vp.num_vars, &vp.expression, @@ -320,7 +320,7 @@ where &lookup_h_permutation_z_comms, ] .collect_vec(); - // Verify the opening proofs for the polynomials commitments + // Verify the opening proofs for the polynomials commitments Pcs::batch_verify(&vp.pcs, comms, &points, &evals, transcript)?; Ok(()) @@ -344,14 +344,21 @@ mod test { test::run_plonkish_backend, }, pcs::{ - multilinear::Zeromorph, - univariate::{UnivariateIpa, UnivariateKzg}, + multilinear::{ + Gemini, MultilinearBrakedown, MultilinearHyrax, MultilinearIpa, MultilinearKzg, + Zeromorph, + }, + univariate::UnivariateKzg, }, util::{ - expression::rotate::BinaryField, test::seeded_std_rng, transcript::Keccak256Transcript, + code::BrakedownSpec6, expression::rotate::BinaryField, hash::Keccak256, + test::seeded_std_rng, transcript::Keccak256Transcript, }, }; - use halo2_curves::{bn256::Bn256, grumpkin}; + use halo2_curves::{ + bn256::{self, Bn256}, + grumpkin, + }; macro_rules! tests { ($suffix:ident, $pcs:ty, $num_vars_range:expr) => { @@ -376,12 +383,10 @@ mod test { }; } - //tests!(brakedown, MultilinearBrakedown); - //tests!(hyrax, MultilinearHyrax, 5..16); - //tests!(ipa, MultilinearIpa); - //tests!(kzg, MultilinearKzg); - //tests!(gemini_kzg, Gemini>); + tests!(brakedown, MultilinearBrakedown); + tests!(hyrax, MultilinearHyrax, 5..16); + tests!(ipa, MultilinearIpa); + tests!(kzg, MultilinearKzg); + tests!(gemini_kzg, Gemini>); tests!(zeromorph_kzg, Zeromorph>); - //tests!(gemini_ipa, Gemini>); - tests!(zeromorph_ipa, Zeromorph>); } diff --git a/plonkish_backend/src/backend/hyperplonk/preprocessor.rs b/plonkish_backend/src/backend/hyperplonk/preprocessor.rs index 2e3edbc9..6aa7bc05 100644 --- a/plonkish_backend/src/backend/hyperplonk/preprocessor.rs +++ b/plonkish_backend/src/backend/hyperplonk/preprocessor.rs @@ -46,7 +46,7 @@ pub(crate) fn preprocess>( let num_vars = circuit_info.k; let poly_size = 1 << num_vars; - // Batch size for the polynomial commitment scheme + // Batch size for the polynomial commitment scheme let batch_size = batch_size(circuit_info); // Trim the parameters for the PCS to those necessary for the size of the circuit let (pcs_pp, pcs_vp) = Pcs::trim(param, poly_size, batch_size)?; @@ -171,7 +171,7 @@ pub(super) fn max_degree( .unwrap() } -//generate lookup constraints using logup GKR +//generate lookup constraints using logup GKR pub(super) fn lookup_constraints( circuit_info: &PlonkishCircuitInfo, beta: &Expression, @@ -186,19 +186,23 @@ pub(super) fn lookup_constraints( .zip(m_offset..) .zip(h_offset..) .flat_map(|((lookup, m), h)| { - // make m and h into polynomials, these are created during proving + // make m and h into polynomials, these are created during proving let [m, h] = &[m, h] .map(|poly| Query::new(poly, Rotation::cur())) .map(Expression::::Polynomial); // separate the input and tables from the lookup - let (inputs, tables) = lookup.iter().cloned().unzip::<_, _, Vec<_>, Vec<_>>(); + let (inputs, tables) = lookup + .iter() + .map(|(input, table)| (input, table)) + .unzip::<_, _, Vec<_>, Vec<_>>(); + // Returns a distributed power expression for the input and table, with base beta, i.e. inputs[0] + \beta inputs[1] + \beta^2 inputs[2] + ... let input = &Expression::distribute_powers(inputs, beta); let table = &Expression::distribute_powers(tables, beta); // h[i] = (gamma + input[i])^-1 - m[i] * (gamma + table[i])^-1 [h * (input + gamma) * (table + gamma) - (table + gamma) + m * (input + gamma)] }) .collect_vec(); - // Every expression that must be proved in the sum check argument + // Every expression that must be proved in the sum check argument let sum_check = (h_offset..) .take(circuit_info.lookups.len()) .map(|h| Query::new(h, Rotation::cur()).into()) @@ -222,7 +226,7 @@ pub(crate) fn permutation_constraints( // The offset is set to the total number of instance columns in the circuit let permutation_offset = circuit_info.num_poly(); let z_offset = permutation_offset + permutation_polys.len() + num_builtin_witness_polys; - // Represent all columns in permutation argument with polynomials + // Represent all columns in permutation argument with polynomials let polys = permutation_polys .iter() .map(|idx| Expression::Polynomial(Query::new(*idx, Rotation::cur()))) @@ -248,12 +252,12 @@ pub(crate) fn permutation_constraints( let z_0_next = Expression::::Polynomial(Query::new(z_offset, Rotation::next())); let l_0 = &Expression::::lagrange(0); let one = &Expression::one(); - // Create the constraints for the permutation argument + // Create the constraints for the permutation argument // The contraints here are the like those from the halo2 gitbook but the matrix Z_0 Z_1 ... Z_{b-1} is transposed let constraints = chain![ zs.first().map(|z_0| l_0 * (z_0 - one)), polys - //iterating over b elements which are vectors of length m + //iterating over b elements which are vectors of length m .chunks(chunk_size) .zip(ids.chunks(chunk_size)) .zip(permutations.chunks(chunk_size)) @@ -280,7 +284,7 @@ pub(crate) fn permutation_constraints( (num_chunks, constraints) } -// Generate multi-linear permutation polynomials for permutation argument +// Generate multi-linear permutation polynomials for permutation argument pub(crate) fn permutation_polys( num_vars: usize, permutation_polys: &[usize], @@ -294,8 +298,7 @@ pub(crate) fn permutation_polys( } poly_index }; - // Permutations will be the matrix defining all permutation polynomials. - // As we start with the identity permutation, all entries have value of the index within the matrix. + // permutations will be the matrix defining all permutation polynomials. As we start with the identity permutation, all entries have value of the index within the matrix. let mut permutations = (0..permutation_polys.len() as u64) .map(|idx| { steps(F::from(idx << num_vars)) @@ -311,7 +314,7 @@ pub(crate) fn permutation_polys( mem::swap(&mut permutations[poly_index[i]][j], &mut last); } } - // We generate a multilinear polynomial from each column of the permutation matrix. + // We generate a multilinear polynomial from each column of the permutation matrix. permutations .into_iter() .map(MultilinearPolynomial::new) diff --git a/plonkish_backend/src/backend/hyperplonk/prover.rs b/plonkish_backend/src/backend/hyperplonk/prover.rs index 162d1a7e..52fd4462 100644 --- a/plonkish_backend/src/backend/hyperplonk/prover.rs +++ b/plonkish_backend/src/backend/hyperplonk/prover.rs @@ -57,7 +57,7 @@ pub(crate) fn lookup_compressed_polys> let polys = polys.iter().map(Borrow::borrow).collect_vec(); let num_vars = polys[0].num_vars(); - // This is the sum of all elements in the input and table + // This is the sum of all elements in the input and table let expression = lookups .iter() .flat_map(|lookup| lookup.iter().map(|(input, table)| (input + table))) @@ -124,14 +124,17 @@ pub(super) fn lookup_compressed_poly>( }; // split inputs and tables into separate vectors - let (inputs, tables) = lookup.iter().cloned().unzip::<_, _, Vec<_>, Vec<_>>(); + let (inputs, tables) = lookup + .iter() + .map(|(input, table)| (input, table)) + .unzip::<_, _, Vec<_>, Vec<_>>(); let timer = start_timer(|| "compressed_input_poly"); - let compressed_input_poly = compress(&inputs.iter().collect::>()); + let compressed_input_poly = compress(&inputs); end_timer(timer); let timer = start_timer(|| "compressed_table_poly"); - let compressed_table_poly = compress(&tables.iter().collect::>()); + let compressed_table_poly = compress(&tables); end_timer(timer); [compressed_input_poly, compressed_table_poly] @@ -170,7 +173,7 @@ pub(super) fn lookup_m_poly( .and_modify(|count| *count += 1) .or_insert(1); } else { - // If the input is not found in the table, the lookup is invalid + // If the input is not found in the table, the lookup is invalid *valid = false; break; } diff --git a/plonkish_backend/src/backend/hyperplonk/util.rs b/plonkish_backend/src/backend/hyperplonk/util.rs index e80be052..96d1d995 100644 --- a/plonkish_backend/src/backend/hyperplonk/util.rs +++ b/plonkish_backend/src/backend/hyperplonk/util.rs @@ -34,7 +34,7 @@ pub fn vanilla_plonk_circuit_info( preprocess_polys: [Vec; 5], permutations: Vec>, ) -> PlonkishCircuitInfo { - let [pi, q_l, q_r, q_m, q_o, q_c, w_l, w_r, w_o]: &[Expression; 9] = + let [pi, q_l, q_r, q_m, q_o, q_c, w_l, w_r, w_o] = &array::from_fn(|poly| Query::new(poly, Rotation::cur())).map(Expression::Polynomial); PlonkishCircuitInfo { k: num_vars, diff --git a/plonkish_backend/src/backend/unihyperplonk.rs b/plonkish_backend/src/backend/unihyperplonk.rs index a8f90396..d8737c45 100644 --- a/plonkish_backend/src/backend/unihyperplonk.rs +++ b/plonkish_backend/src/backend/unihyperplonk.rs @@ -413,7 +413,6 @@ mod test { ($suffix:ident, $pcs:ty, $additive:literal, $num_vars_range:expr) => { paste::paste! { #[test] - #[ignore = "we do not currently use UniHyperPlonk"] fn []() { run_plonkish_backend::<_, UniHyperPlonk<$pcs, $additive>, Keccak256Transcript<_>, _>($num_vars_range, |num_vars| { rand_vanilla_plonk_circuit::<_, Lexical>(num_vars, seeded_std_rng(), seeded_std_rng()) @@ -421,7 +420,6 @@ mod test { } #[test] - #[ignore = "we do not currently use UniHyperPlonk"] fn []() { run_plonkish_backend::<_, UniHyperPlonk<$pcs, $additive>, Keccak256Transcript<_>, _>($num_vars_range, |num_vars| { rand_vanilla_plonk_w_lookup_circuit::<_, Lexical>(num_vars, seeded_std_rng(), seeded_std_rng()) diff --git a/plonkish_backend/src/frontend/halo2.rs b/plonkish_backend/src/frontend/halo2.rs index 8b2ef2e0..371febbb 100644 --- a/plonkish_backend/src/frontend/halo2.rs +++ b/plonkish_backend/src/frontend/halo2.rs @@ -56,10 +56,11 @@ pub struct Halo2Circuit> { row_mapping: Vec, } + impl> Halo2Circuit { // Generate a new Halo2Circuit from a circuit of type C that implements CircuitExt trait, which extends the Circuit trait from halo2 pub fn new(k: usize, circuit: C) -> Self { - // Obtain constraint system cs and config from circuit + // Obtain constraint system cs and config from circuit let (cs, config) = { let mut cs = ConstraintSystem::default(); let config = C::configure(&mut cs); @@ -105,9 +106,9 @@ impl> AsRef for Halo2Circuit { } } -// Implement PlonkishCircuit trait from backend for Halo2Circuit struct +// Implement PlonkishCircuit trait from backend for Halo2Circuit struct impl> PlonkishCircuit for Halo2Circuit { - // Get PlonkishCircuitInfo from a Halo2 Circuit without preprocessing, i.e. setting fixed/ selector columns or copy constraints. + // Get PlonkishCircuitInfo from a Halo2 Circuit without preprocessing, i.e. setting fixed/ selector columns or copy constraints. fn circuit_info_without_preprocess(&self) -> Result, crate::Error> { let Self { k, @@ -118,7 +119,7 @@ impl> PlonkishCircuit for Halo2Circuit { } = self; // Generate indices of advice columns so that they are ordered by phase let advice_idx = advice_idx(cs); - // Convert expressions from halo2 to backend + // Convert expressions from halo2 to backend let constraints = cs .gates() .iter() @@ -128,7 +129,7 @@ impl> PlonkishCircuit for Halo2Circuit { }) }) .collect(); - // Convert lookup expressions from halo2 to backend + // Convert lookup expressions from halo2 to backend let lookups = cs .lookups() .iter() @@ -148,12 +149,12 @@ impl> PlonkishCircuit for Halo2Circuit { .collect(); let num_instances = instances.iter().map(Vec::len).collect_vec(); - // Set preprocess_polys, initialized to 0, with 2^k rows. + // Set preprocess_polys, initialized to 0, with 2^k rows. let preprocess_polys = vec![vec![F::ZERO; 1 << k]; cs.num_selectors() + cs.num_fixed_columns()]; - //Obtain indices of columns from the contraint system + //Obtain indices of columns from the contraint system let column_idx = column_idx(cs); - // Initialize permutations defining copy constraints + // Initialize permutations defining copy constraints let permutations = cs .permutation() .get_columns() @@ -177,7 +178,7 @@ impl> PlonkishCircuit for Halo2Circuit { }) } - // Get PlonkishCircuitInfo from a Halo2 Circuit with preprocessing, i.e. setting fixed/ selector columns or copy constraints. + // Get PlonkishCircuitInfo from a Halo2 Circuit with preprocessing, i.e. setting fixed/ selector columns or copy constraints. fn circuit_info(&self) -> Result, crate::Error> { let Self { k, @@ -192,9 +193,9 @@ impl> PlonkishCircuit for Halo2Circuit { let mut circuit_info = self.circuit_info_without_preprocess()?; let num_instances = instances.iter().map(Vec::len).collect_vec(); - //Obtain indices of columns from the contraint system + //Obtain indices of columns from the contraint system let column_idx = column_idx(cs); - // Obtain initial permutations from constraint system, for now no copy constraints are set + // Obtain initial permutations from constraint system, for now no copy constraints are set let permutation_column_idx = cs .permutation() .get_columns() @@ -234,7 +235,7 @@ impl> PlonkishCircuit for Halo2Circuit { }), ] .collect(); - // Obtain the copy constraints from the preprocess collector + // Obtain the copy constraints from the preprocess collector circuit_info.permutations = preprocess_collector.permutation.into_cycles(); Ok(circuit_info) @@ -245,6 +246,7 @@ impl> PlonkishCircuit for Halo2Circuit { &self.instances } + // Synthesize a circuit for a particular phase with an instance and witness of the circuit, and challenges fn synthesize(&self, phase: usize, challenges: &[F]) -> Result>, crate::Error> { let instances = self.instances.iter().map(Vec::as_slice).collect_vec(); @@ -254,7 +256,7 @@ impl> PlonkishCircuit for Halo2Circuit { advice_idx_in_phase: &self.advice_idx_in_phase, challenge_idx: &self.challenge_idx, instances: instances.as_slice(), - // all advice columns are initialized to zero, there are 2^k rows and self.num_witness_polys[phase] columns + // all advice columns are initialized to zero, there are 2^k rows and self.num_witness_polys[phase] columns advices: vec![vec![F::ZERO.into(); 1 << self.k]; self.num_witness_polys[phase]], challenges, row_mapping: &self.row_mapping, @@ -409,7 +411,7 @@ impl<'a, F: Field> Assignment for PreprocessCollector<'a, F> { Ok(()) } - // Challenges are created later + // Challenges are created later fn get_challenge(&self, _: Challenge) -> Value { Value::unknown() } @@ -630,6 +632,7 @@ impl<'a, F: Field> Assignment for WitnessCollector<'a, F> { fn pop_namespace(&mut self, _: Option) {} } + // Output index of each advice column in the matrix such that columns are ordered by phase (with all advice columms at the end of the matrix) fn advice_idx(cs: &ConstraintSystem) -> Vec { // Order cs.advice_column_phase() such that cs.advice_column_phase()[i] <= cs.advice_column_phase()[i+1] and add the new index to the advice_offset (total number of columns - num advice columns) for each element. @@ -704,7 +707,7 @@ fn phase_offsets(phases: &[u8]) -> Vec { .collect() } -//convert from an expression defined in halo2 to an expression defined in backend +//convert from an expression defined in halo2 to an expression defined in backend fn convert_expression( cs: &ConstraintSystem, advice_idx: &[usize], diff --git a/plonkish_backend/src/frontend/halo2/circuit.rs b/plonkish_backend/src/frontend/halo2/circuit.rs index cd1c6211..4352e8aa 100644 --- a/plonkish_backend/src/frontend/halo2/circuit.rs +++ b/plonkish_backend/src/frontend/halo2/circuit.rs @@ -53,7 +53,7 @@ mod vanilla_plonk { } #[derive(Clone, Default)] - pub struct VanillaPlonk(Vec<[Assigned; 8]>); + pub struct VanillaPlonk(usize, Vec<[Assigned; 8]>); impl Circuit for VanillaPlonk { type Config = VanillaPlonkConfig; @@ -76,7 +76,7 @@ mod vanilla_plonk { layouter.assign_region( || "", |mut region| { - for (offset, values) in self.0.iter().enumerate() { + for (offset, values) in self.1.iter().enumerate() { let (selectors, wires) = values.split_at(config.selectors.len()); for (column, value) in config.selectors.into_iter().zip(selectors.iter().copied()) @@ -114,11 +114,11 @@ mod vanilla_plonk { .collect_vec(), ] .collect(); - Self(values) + Self(k, values) } fn instances(&self) -> Vec> { - let [q_l, q_r, q_m, q_o, q_c, w_l, w_r, w_o] = self.0[0]; + let [q_l, q_r, q_m, q_o, q_c, w_l, w_r, w_o] = self.1[0]; let pi = (-(q_l * w_l + q_r * w_r + q_m * w_l * w_r + q_o * w_o + q_c)).evaluate(); vec![vec![pi]] } diff --git a/plonkish_backend/src/pcs/multilinear/brakedown.rs b/plonkish_backend/src/pcs/multilinear/brakedown.rs index de7d69b7..39f961c1 100644 --- a/plonkish_backend/src/pcs/multilinear/brakedown.rs +++ b/plonkish_backend/src/pcs/multilinear/brakedown.rs @@ -448,13 +448,11 @@ mod test { type Pcs = MultilinearBrakedown; #[test] - #[ignore = "we do not currently use brakedown"] fn commit_open_verify() { run_commit_open_verify::<_, Pcs, Keccak256Transcript<_>>(); } #[test] - #[ignore = "we do not currently use brakedown"] fn batch_commit_open_verify() { run_batch_commit_open_verify::<_, Pcs, Keccak256Transcript<_>>(); } diff --git a/plonkish_backend/src/pcs/multilinear/gemini.rs b/plonkish_backend/src/pcs/multilinear/gemini.rs index 4fdadac2..99c866f8 100644 --- a/plonkish_backend/src/pcs/multilinear/gemini.rs +++ b/plonkish_backend/src/pcs/multilinear/gemini.rs @@ -5,7 +5,7 @@ use crate::{ pcs::{ multilinear::additive, univariate::{ - err_too_large_degree, ipa::UnivariateIpa, UnivariateIpaCommitment, UnivariateKzg, + err_too_large_deree, ipa::UnivariateIpa, UnivariateIpaCommitment, UnivariateKzg, UnivariateKzgCommitment, }, Evaluation, Point, PolynomialCommitmentScheme, @@ -58,7 +58,7 @@ where fn commit(pp: &Self::ProverParam, poly: &Self::Polynomial) -> Result { if pp.degree() + 1 < poly.evals().len() { let got = poly.evals().len() - 1; - return Err(err_too_large_degree("commit", pp.degree(), got)); + return Err(err_too_large_deree("commit", pp.degree(), got)); } Ok(UnivariateKzg::commit_monomial(pp, poly.evals())) @@ -85,7 +85,7 @@ where let num_vars = point.len(); if pp.degree() + 1 < poly.evals().len() { let got = poly.evals().len() - 1; - return Err(err_too_large_degree("open", pp.degree(), got)); + return Err(err_too_large_deree("open", pp.degree(), got)); } if cfg!(feature = "sanity-check") { @@ -254,14 +254,10 @@ where fn commit(pp: &Self::ProverParam, poly: &Self::Polynomial) -> Result { if pp.degree() + 1 < poly.evals().len() { let got = poly.evals().len() - 1; - return Err(err_too_large_degree("commit", pp.degree(), got)); + return Err(err_too_large_deree("commit", pp.degree(), got)); } let uni_poly = UnivariatePolynomial::monomial(poly.evals().to_vec()); - if uni_poly.coeffs().is_empty() { - return Ok(UnivariateIpaCommitment::::default()); - } - UnivariateIpa::commit(pp, &uni_poly) } @@ -286,7 +282,7 @@ where let num_vars = point.len(); if pp.degree() + 1 < poly.evals().len() { let got = poly.evals().len() - 1; - return Err(err_too_large_degree("open", pp.degree(), got)); + return Err(err_too_large_deree("open", pp.degree(), got)); } if cfg!(feature = "sanity-check") { @@ -443,14 +439,12 @@ mod test { type GemIpaPcs = Gemini>; #[test] - #[ignore = "we do not currently use gemini"] fn commit_open_verify() { run_commit_open_verify::<_, GemKzgPcs, Keccak256Transcript<_>>(); run_commit_open_verify::<_, GemIpaPcs, Keccak256Transcript<_>>(); } #[test] - #[ignore = "we do not currently use gemini"] fn batch_commit_open_verify() { run_batch_commit_open_verify::<_, GemKzgPcs, Keccak256Transcript<_>>(); run_batch_commit_open_verify::<_, GemIpaPcs, Keccak256Transcript<_>>(); diff --git a/plonkish_backend/src/pcs/multilinear/hyrax.rs b/plonkish_backend/src/pcs/multilinear/hyrax.rs index f5fceae6..45e3ecb0 100644 --- a/plonkish_backend/src/pcs/multilinear/hyrax.rs +++ b/plonkish_backend/src/pcs/multilinear/hyrax.rs @@ -324,13 +324,11 @@ mod test { type Pcs = MultilinearHyrax; #[test] - #[ignore = "we do not currently use hyrax"] fn commit_open_verify() { run_commit_open_verify::<_, Pcs, Keccak256Transcript<_>>(); } #[test] - #[ignore = "we do not currently use hyrax"] fn batch_commit_open_verify() { run_batch_commit_open_verify::<_, Pcs, Keccak256Transcript<_>>(); } diff --git a/plonkish_backend/src/pcs/multilinear/ipa.rs b/plonkish_backend/src/pcs/multilinear/ipa.rs index 2c681273..a62c58b6 100644 --- a/plonkish_backend/src/pcs/multilinear/ipa.rs +++ b/plonkish_backend/src/pcs/multilinear/ipa.rs @@ -136,9 +136,7 @@ where fn commit(pp: &Self::ProverParam, poly: &Self::Polynomial) -> Result { validate_input("commit", pp.num_vars(), [poly], None)?; - Ok(MultilinearIpaCommitment( - variable_base_msm(poly.evals(), pp.g()).into(), - )) + Ok(variable_base_msm(poly.evals(), pp.g()).into()).map(MultilinearIpaCommitment) } fn batch_commit<'a>( @@ -243,13 +241,11 @@ mod test { type Pcs = MultilinearIpa; #[test] - #[ignore = "we do not currently use multilinear IPA"] fn commit_open_verify() { run_commit_open_verify::<_, Pcs, Keccak256Transcript<_>>(); } #[test] - #[ignore = "we do not currently use multilinear IPA"] fn batch_commit_open_verify() { run_batch_commit_open_verify::<_, Pcs, Keccak256Transcript<_>>(); } diff --git a/plonkish_backend/src/pcs/multilinear/kzg.rs b/plonkish_backend/src/pcs/multilinear/kzg.rs index 216cd485..3c375b4c 100644 --- a/plonkish_backend/src/pcs/multilinear/kzg.rs +++ b/plonkish_backend/src/pcs/multilinear/kzg.rs @@ -241,9 +241,8 @@ where fn commit(pp: &Self::ProverParam, poly: &Self::Polynomial) -> Result { validate_input("commit", pp.num_vars(), [poly], None)?; - Ok(MultilinearKzgCommitment( - variable_base_msm(poly.evals(), pp.eq(poly.num_vars())).into(), - )) + Ok(variable_base_msm(poly.evals(), pp.eq(poly.num_vars())).into()) + .map(MultilinearKzgCommitment) } fn batch_commit<'a>( @@ -376,13 +375,11 @@ mod test { type Pcs = MultilinearKzg; #[test] - #[ignore = "we do not currently use multilinear KZG"] fn commit_open_verify() { run_commit_open_verify::<_, Pcs, Keccak256Transcript<_>>(); } #[test] - #[ignore = "we do not currently use multilinear KZG"] fn batch_commit_open_verify() { run_batch_commit_open_verify::<_, Pcs, Keccak256Transcript<_>>(); } diff --git a/plonkish_backend/src/pcs/multilinear/zeromorph.rs b/plonkish_backend/src/pcs/multilinear/zeromorph.rs index 929993b0..81a71d69 100644 --- a/plonkish_backend/src/pcs/multilinear/zeromorph.rs +++ b/plonkish_backend/src/pcs/multilinear/zeromorph.rs @@ -3,7 +3,7 @@ use crate::{ pcs::{ multilinear::{additive, quotients}, univariate::{ - err_too_large_degree, UnivariateIpa, UnivariateIpaCommitment, UnivariateKzg, + err_too_large_deree, UnivariateIpa, UnivariateIpaCommitment, UnivariateKzg, UnivariateKzgProverParam, UnivariateKzgVerifierParam, }, Evaluation, Point, PolynomialCommitmentScheme, @@ -112,7 +112,7 @@ where fn commit(pp: &Self::ProverParam, poly: &Self::Polynomial) -> Result { if pp.degree() + 1 < poly.evals().len() { let got = poly.evals().len() - 1; - return Err(err_too_large_degree("commit", pp.degree(), got)); + return Err(err_too_large_deree("commit", pp.degree(), got)); } Ok(UnivariateKzg::commit_monomial(&pp.commit_pp, poly.evals())) @@ -139,7 +139,7 @@ where let num_vars = poly.num_vars(); if pp.degree() + 1 < poly.evals().len() { let got = poly.evals().len() - 1; - return Err(err_too_large_degree("open", pp.degree(), got)); + return Err(err_too_large_deree("open", pp.degree(), got)); } if cfg!(feature = "sanity-check") { @@ -304,13 +304,11 @@ where fn commit(pp: &Self::ProverParam, poly: &Self::Polynomial) -> Result { if pp.degree() + 1 < poly.evals().len() { let got = poly.evals().len() - 1; - return Err(err_too_large_degree("commit", pp.degree(), got)); + return Err(err_too_large_deree("commit", pp.degree(), got)); } + let uni_poly = UnivariatePolynomial::monomial(poly.evals().to_vec()); - let bases = pp.monomial(); - Ok(UnivariateIpaCommitment( - variable_base_msm(poly.evals(), &bases[..poly.evals().len()]).into(), - )) + UnivariateIpa::commit(pp, &uni_poly) } fn batch_commit<'a>( @@ -334,7 +332,7 @@ where let num_vars = poly.num_vars(); if pp.degree() + 1 < poly.evals().len() { let got = poly.evals().len() - 1; - return Err(err_too_large_degree("open", pp.degree(), got)); + return Err(err_too_large_deree("open", pp.degree(), got)); } if cfg!(feature = "sanity-check") { diff --git a/plonkish_backend/src/pcs/univariate.rs b/plonkish_backend/src/pcs/univariate.rs index 00111d53..41465148 100644 --- a/plonkish_backend/src/pcs/univariate.rs +++ b/plonkish_backend/src/pcs/univariate.rs @@ -48,7 +48,7 @@ fn validate_input<'a, F: Field>( match poly.basis() { Monomial => { if param_degree < poly.degree() { - return Err(err_too_large_degree(function, param_degree, poly.degree())); + return Err(err_too_large_deree(function, param_degree, poly.degree())); } } Lagrange => { @@ -61,7 +61,7 @@ fn validate_input<'a, F: Field>( Ok(()) } -pub(super) fn err_too_large_degree(function: &str, upto: usize, got: usize) -> Error { +pub(super) fn err_too_large_deree(function: &str, upto: usize, got: usize) -> Error { Error::InvalidPcsParam(if function == "trim" { format!("Too large degree to {function} (param supports degree up to {upto} but got {got})") } else { diff --git a/plonkish_backend/src/pcs/univariate/hyrax.rs b/plonkish_backend/src/pcs/univariate/hyrax.rs index f621f078..32740105 100644 --- a/plonkish_backend/src/pcs/univariate/hyrax.rs +++ b/plonkish_backend/src/pcs/univariate/hyrax.rs @@ -1,7 +1,7 @@ use crate::{ pcs::{ univariate::{ - additive, err_too_large_degree, + additive, err_too_large_deree, ipa::{UnivariateIpa, UnivariateIpaCommitment, UnivariateIpaParam}, validate_input, }, @@ -153,7 +153,7 @@ where let batch_k = (poly_size * batch_size).next_power_of_two().ilog2() as usize; let row_k = div_ceil(batch_k, 2); if param.row_k() < row_k { - return Err(err_too_large_degree("trim", param.degree(), poly_size - 1)); + return Err(err_too_large_deree("trim", param.degree(), poly_size - 1)); } let (ipa_pp, ipa_vp) = UnivariateIpa::trim(¶m.ipa, 1 << row_k, 0)?; @@ -362,14 +362,12 @@ mod test { type GrumpkinPcs = UnivariateHyrax; #[test] - #[ignore = "we do not currently use hyrax"] fn commit_open_verify() { run_commit_open_verify::<_, PastaPcs, Keccak256Transcript<_>>(); run_commit_open_verify::<_, GrumpkinPcs, Keccak256Transcript<_>>(); } #[test] - #[ignore = "we do not currently use hyrax"] fn batch_commit_open_verify() { run_batch_commit_open_verify::<_, PastaPcs, Keccak256Transcript<_>>(); run_batch_commit_open_verify::<_, GrumpkinPcs, Keccak256Transcript<_>>(); diff --git a/plonkish_backend/src/pcs/univariate/ipa.rs b/plonkish_backend/src/pcs/univariate/ipa.rs index 9eed7951..7f5782ef 100644 --- a/plonkish_backend/src/pcs/univariate/ipa.rs +++ b/plonkish_backend/src/pcs/univariate/ipa.rs @@ -1,6 +1,6 @@ use crate::{ pcs::{ - univariate::{additive, err_too_large_degree, validate_input}, + univariate::{additive, err_too_large_deree, validate_input}, Additive, Evaluation, Point, PolynomialCommitmentScheme, }, poly::{ @@ -136,7 +136,7 @@ where let k = poly_size.ilog2() as usize; if param.monomial.len() < poly_size { - return Err(err_too_large_degree("trim", param.degree(), poly_size - 1)); + return Err(err_too_large_deree("trim", param.degree(), poly_size - 1)); } let monomial = param.monomial[..poly_size].to_vec(); @@ -156,9 +156,7 @@ where let coeffs = poly.coeffs(); let bases = pp.monomial(); - Ok(UnivariateIpaCommitment( - variable_base_msm(coeffs, &bases[..coeffs.len()]).into(), - )) + Ok(variable_base_msm(coeffs, &bases[..coeffs.len()]).into()).map(UnivariateIpaCommitment) } fn batch_commit<'a>( diff --git a/plonkish_backend/src/pcs/univariate/kzg.rs b/plonkish_backend/src/pcs/univariate/kzg.rs index c11f68a0..646cca43 100644 --- a/plonkish_backend/src/pcs/univariate/kzg.rs +++ b/plonkish_backend/src/pcs/univariate/kzg.rs @@ -1,6 +1,6 @@ use crate::{ pcs::{ - univariate::{additive, err_too_large_degree, monomial_g_to_lagrange_g, validate_input}, + univariate::{additive, err_too_large_deree, monomial_g_to_lagrange_g, validate_input}, Additive, Evaluation, Point, PolynomialCommitmentScheme, }, poly::univariate::{UnivariateBasis::*, UnivariatePolynomial}, @@ -252,7 +252,7 @@ where assert!(poly_size.is_power_of_two()); if param.monomial_g1.len() < poly_size { - return Err(err_too_large_degree("trim", param.degree(), poly_size - 1)); + return Err(err_too_large_deree("trim", param.degree(), poly_size - 1)); } let monomial_g1 = param.monomial_g1[..poly_size].to_vec(); diff --git a/plonkish_backend/src/piop/sum_check/classic/coeff.rs b/plonkish_backend/src/piop/sum_check/classic/coeff.rs index 555069aa..091aa2a1 100644 --- a/plonkish_backend/src/piop/sum_check/classic/coeff.rs +++ b/plonkish_backend/src/piop/sum_check/classic/coeff.rs @@ -205,7 +205,9 @@ fn poly<'a, F: PrimeField>( ) -> &'a MultilinearPolynomial { match expr { Expression::CommonPolynomial(CommonPolynomial::EqXY(idx)) => &state.eq_xys[*idx], - Expression::Polynomial(query) if query.rotation() == Rotation::cur() => &state.polys[query], + Expression::Polynomial(query) if query.rotation() == Rotation::cur() => { + &state.polys[&query] + } _ => unimplemented!(), } } diff --git a/plonkish_backend/src/util/code/brakedown.rs b/plonkish_backend/src/util/code/brakedown.rs index 47e9e4f5..9e47b434 100644 --- a/plonkish_backend/src/util/code/brakedown.rs +++ b/plonkish_backend/src/util/code/brakedown.rs @@ -371,7 +371,6 @@ mod test { #[rustfmt::skip] #[test] - #[ignore = "we do not currently use brakedown"] fn spec_127_bit_field() { assert_spec_correct::(127, 0.02, 6, 33, 13265, 2); assert_spec_correct::(127, 0.03, 7, 26, 8768, 2); @@ -383,7 +382,6 @@ mod test { #[rustfmt::skip] #[test] - #[ignore = "we do not currently use brakedown"] fn spec_254_bit_field() { assert_spec_correct::(254, 0.02, 6, 33, 13265, 1); assert_spec_correct::(254, 0.03, 7, 26, 8768, 1); diff --git a/plonkish_backend/src/util/expression.rs b/plonkish_backend/src/util/expression.rs index c4e51789..ff727eb7 100644 --- a/plonkish_backend/src/util/expression.rs +++ b/plonkish_backend/src/util/expression.rs @@ -118,7 +118,7 @@ impl Expression { ) }; match self { - Expression::Constant(scalar) => constant(scalar.clone()), + Expression::Constant(scalar) => constant(scalar.clone()), Expression::CommonPolynomial(poly) => common_poly(*poly), Expression::Polynomial(query) => poly(*query), Expression::Challenge(index) => challenge(*index), diff --git a/rust-toolchain b/rust-toolchain index 6174fee8..837f16a7 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.79.0 \ No newline at end of file +1.73.0 \ No newline at end of file From dbdd662e38832aceabd1e1ca34e3575de1b265bd Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Fri, 20 Dec 2024 18:21:22 +0000 Subject: [PATCH 06/35] remove old parameters with pasta curves --- .../circuits/poseidongadget/poseidon/pow5.rs | 7 +- .../poseidongadget/poseidon/primitives.rs | 13 +- .../poseidongadget/poseidon/primitives/fp.rs | 1431 ----------------- .../poseidongadget/poseidon/primitives/fq.rs | 1431 ----------------- .../poseidon/primitives/p128pow5t3.rs | 320 ---- .../poseidon/primitives/test_vectors.rs | 1261 --------------- 6 files changed, 8 insertions(+), 4455 deletions(-) delete mode 100644 plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/fp.rs delete mode 100644 plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/fq.rs delete mode 100644 plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/p128pow5t3.rs delete mode 100644 plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/test_vectors.rs diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs index 1e91434c..eaf8599c 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs @@ -601,7 +601,7 @@ mod tests { use super::{PoseidonInstructions, Pow5Chip, Pow5Config, StateWord}; use crate::circuits::poseidongadget::poseidon::{ - primitives::{self as poseidon, ConstantLength, P128Pow5T3 as OrchardNullifier, BN256param as newParam, Spec}, + primitives::{self as poseidon, ConstantLength, BN256param as newParam, Spec}, Hash, }; use std::convert::TryInto; @@ -910,6 +910,7 @@ mod tests { } } + /*#[ignore] #[test] fn poseidon_hash() { let rng = OsRng; @@ -928,6 +929,7 @@ mod tests { assert_eq!(prover.verify(), Ok(())) } + #[ignore] #[test] fn poseidon_hash_longer_input() { let rng = OsRng; @@ -946,6 +948,7 @@ mod tests { assert_eq!(prover.verify(), Ok(())) } + #[ignore] #[test] fn hash_test_vectors() { for tv in crate::circuits::poseidongadget::poseidon::primitives::test_vectors::fp::hash() { @@ -986,6 +989,6 @@ mod tests { halo2_proofs::dev::CircuitLayout::default() .render(6, &circuit, &root) .unwrap(); - } + }*/ } diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives.rs index 5582de6f..0eb4bb5c 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives.rs @@ -9,17 +9,9 @@ use ff::FromUniformBytes; use ff::PrimeField; use halo2_proofs::arithmetic::Field; -pub(crate) mod fp; -pub(crate) mod fq; pub(crate) mod grain; pub(crate) mod mds; -#[cfg(test)] -pub(crate) mod test_vectors; - -mod p128pow5t3; -pub use p128pow5t3::P128Pow5T3; - mod bn256param; pub use bn256param::BN256param; @@ -389,10 +381,11 @@ impl, const T: usize, const RATE: usize, cons #[cfg(test)] mod tests { - use super::{permute, ConstantLength, Hash, P128Pow5T3 as OrchardNullifier, Spec}; + use super::{permute, ConstantLength, Hash, Spec}; use ff::PrimeField; use halo2_curves::pasta::pallas; + /*#[ignore] #[test] fn orchard_spec_equivalence() { let message = [pallas::Base::from(6), pallas::Base::from(42)]; @@ -407,5 +400,5 @@ mod tests { let mut state = [message[0], message[1], pallas::Base::from_u128(2 << 64)]; permute::<_, OrchardNullifier, 3, 2>(&mut state, &mds, &round_constants); assert_eq!(state[0], result); - } + }*/ } diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/fp.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/fp.rs deleted file mode 100644 index 1bda4a9c..00000000 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/fp.rs +++ /dev/null @@ -1,1431 +0,0 @@ -//! Constants for using Poseidon with the Pallas field. -//! -//! The constants can be reproduced by running the following Sage script from -//! [this repository](https://github.com/daira/pasta-hadeshash): -//! -//! ```text -//! $ sage generate_parameters_grain.sage 1 0 255 3 8 56 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001 -//! ``` -use halo2_curves::pasta::pallas; - -// Number of round constants: 192 -// Round constants for GF(p): -pub(crate) const ROUND_CONSTANTS: [[pallas::Base; 3]; 64] = [ - [ - pallas::Base::from_raw([ - 0x5753_8c25_9642_6303, - 0x4e71_162f_3100_3b70, - 0x353f_628f_76d1_10f3, - 0x360d_7470_611e_473d, - ]), - pallas::Base::from_raw([ - 0xbdb7_4213_bf63_188b, - 0x4908_ac2f_12eb_e06f, - 0x5dc3_c6c5_febf_aa31, - 0x2bab_94d7_ae22_2d13, - ]), - pallas::Base::from_raw([ - 0x0939_d927_53cc_5dc8, - 0xef77_e7d7_3676_6c5d, - 0x2bf0_3e1a_29aa_871f, - 0x150c_93fe_f652_fb1c, - ]), - ], - [ - pallas::Base::from_raw([ - 0x1425_9dce_5377_82b2, - 0x03cc_0a60_141e_894e, - 0x955d_55db_56dc_57c1, - 0x3270_661e_6892_8b3a, - ]), - pallas::Base::from_raw([ - 0xce9f_b9ff_c345_afb3, - 0xb407_c370_f2b5_a1cc, - 0xa0b7_afe4_e205_7299, - 0x073f_116f_0412_2e25, - ]), - pallas::Base::from_raw([ - 0x8eba_d76f_c715_54d8, - 0x55c9_cd20_61ae_93ca, - 0x7aff_d09c_1f53_f5fd, - 0x2a32_ec5c_4ee5_b183, - ]), - ], - [ - pallas::Base::from_raw([ - 0x2d8c_cbe2_92ef_eead, - 0x634d_24fc_6e25_59f2, - 0x651e_2cfc_7406_28ca, - 0x2703_26ee_039d_f19e, - ]), - pallas::Base::from_raw([ - 0xa068_fc37_c182_e274, - 0x8af8_95bc_e012_f182, - 0xdc10_0fe7_fcfa_5491, - 0x27c6_642a_c633_bc66, - ]), - pallas::Base::from_raw([ - 0x9ca1_8682_e26d_7ff9, - 0x710e_1fb6_ab97_6a45, - 0xd27f_5739_6989_129d, - 0x1bdf_d8b0_1401_c70a, - ]), - ], - [ - pallas::Base::from_raw([ - 0xc832_d824_261a_35ea, - 0xf4f6_fb3f_9054_d373, - 0x14b9_d6a9_c84d_d678, - 0x162a_14c6_2f9a_89b8, - ]), - pallas::Base::from_raw([ - 0xf798_2466_7b5b_6bec, - 0xac0a_1fc7_1e2c_f0c0, - 0x2af6_f79e_3127_feea, - 0x2d19_3e0f_76de_586b, - ]), - pallas::Base::from_raw([ - 0x5d0b_f58d_c8a4_aa94, - 0x4fef_f829_8499_0ff8, - 0x8169_6ef1_104e_674f, - 0x044c_a3cc_4a85_d73b, - ]), - ], - [ - pallas::Base::from_raw([ - 0x6198_785f_0cd6_b9af, - 0xb8d9_e2d4_f314_f46f, - 0x1d04_5341_6d3e_235c, - 0x1cba_f2b3_71da_c6a8, - ]), - pallas::Base::from_raw([ - 0x343e_0761_0f3f_ede5, - 0x293c_4ab0_38fd_bbdc, - 0x0e6c_49d0_61b6_b5f4, - 0x1d5b_2777_692c_205b, - ]), - pallas::Base::from_raw([ - 0xf60e_971b_8d73_b04f, - 0x06a9_adb0_c1e6_f962, - 0xaa30_535b_dd74_9a7e, - 0x2e9b_dbba_3dd3_4bff, - ]), - ], - [ - pallas::Base::from_raw([ - 0x035a_1366_1f22_418b, - 0xde40_fbe2_6d04_7b05, - 0x8bd5_bae3_6969_299f, - 0x2de1_1886_b180_11ca, - ]), - pallas::Base::from_raw([ - 0xbc99_8884_ba96_a721, - 0x2ab9_395c_449b_e947, - 0x0d5b_4a3f_1841_dcd8, - 0x2e07_de17_80b8_a70d, - ]), - pallas::Base::from_raw([ - 0x825e_4c2b_b749_25ca, - 0x2504_40a9_9d6b_8af3, - 0xbbdb_63db_d52d_ad16, - 0x0f69_f185_4d20_ca0c, - ]), - ], - [ - pallas::Base::from_raw([ - 0x816c_0594_22dc_705e, - 0x6ce5_1135_07f9_6de9, - 0x0d13_5dc6_39fb_09a4, - 0x2eb1_b254_17fe_1767, - ]), - pallas::Base::from_raw([ - 0xb8b1_bdf4_953b_d82c, - 0xff36_c661_d26c_c42d, - 0x8c24_cb44_c3fa_b48a, - 0x115c_d0a0_643c_fb98, - ]), - pallas::Base::from_raw([ - 0xde80_1612_311d_04cd, - 0xbb57_ddf1_4e0f_958a, - 0x066d_7378_b999_868b, - 0x26ca_293f_7b2c_462d, - ]), - ], - [ - pallas::Base::from_raw([ - 0xf520_9d14_b248_20ca, - 0x0f16_0bf9_f71e_967f, - 0x2a83_0aa1_6241_2cd9, - 0x17bf_1b93_c4c7_e01a, - ]), - pallas::Base::from_raw([ - 0x05c8_6f2e_7dc2_93c5, - 0xe03c_0354_bd8c_fd38, - 0xa24f_8456_369c_85df, - 0x35b4_1a7a_c4f3_c571, - ]), - pallas::Base::from_raw([ - 0x72ac_156a_f435_d09e, - 0x64e1_4d3b_eb2d_ddde, - 0x4359_2799_4849_bea9, - 0x3b14_8008_0523_c439, - ]), - ], - [ - pallas::Base::from_raw([ - 0x2716_18d8_74b1_4c6d, - 0x08e2_8644_2a2d_3eb2, - 0x4950_856d_c907_d575, - 0x2cc6_8100_31dc_1b0d, - ]), - pallas::Base::from_raw([ - 0x91f3_18c0_9f0c_b566, - 0x9e51_7aa9_3b78_341d, - 0x0596_18e2_afd2_ef99, - 0x25bd_bbed_a1bd_e8c1, - ]), - pallas::Base::from_raw([ - 0xc631_3487_073f_7f7b, - 0x2a5e_d0a2_7b61_926c, - 0xb95f_33c2_5dde_8ac0, - 0x392a_4a87_58e0_6ee8, - ]), - ], - [ - pallas::Base::from_raw([ - 0xe7bb_cef0_2eb5_866c, - 0x5e6a_6fd1_5db8_9365, - 0x9aa6_111f_4de0_0948, - 0x272a_5587_8a08_442b, - ]), - pallas::Base::from_raw([ - 0x9b92_5b3c_5b21_e0e2, - 0xa6eb_ba01_1694_dd12, - 0xefa1_3c4e_60e2_6239, - 0x2d5b_308b_0cf0_2cdf, - ]), - pallas::Base::from_raw([ - 0xef38_c57c_3116_73ac, - 0x44df_f42f_18b4_6c56, - 0xdd5d_293d_72e2_e5f2, - 0x1654_9fc6_af2f_3b72, - ]), - ], - [ - pallas::Base::from_raw([ - 0x9b71_26d9_b468_60df, - 0x7639_8265_3442_0311, - 0xfa69_c3a2_ad52_f76d, - 0x1b10_bb7a_82af_ce39, - ]), - pallas::Base::from_raw([ - 0x90d2_7f6a_00b7_dfc8, - 0xd1b3_6968_ba04_05c0, - 0xc79c_2df7_dc98_a3be, - 0x0f1e_7505_ebd9_1d2f, - ]), - pallas::Base::from_raw([ - 0xff45_7756_b819_bb20, - 0x797f_d6e3_f18e_b1ca, - 0x537a_7497_a3b4_3f46, - 0x2f31_3faf_0d3f_6187, - ]), - ], - [ - pallas::Base::from_raw([ - 0xf0bc_3e73_2ecb_26f6, - 0x5cad_11eb_f0f7_ceb8, - 0xfa3c_a61c_0ed1_5bc5, - 0x3a5c_bb6d_e450_b481, - ]), - pallas::Base::from_raw([ - 0x8655_27cb_ca91_5982, - 0x51ba_a6e2_0f89_2b62, - 0xd920_86e2_53b4_39d6, - 0x3dab_54bc_9bef_688d, - ]), - pallas::Base::from_raw([ - 0x3680_45ac_f2b7_1ae3, - 0x4c24_b33b_410f_efd4, - 0xe280_d316_7012_3f74, - 0x06db_fb42_b979_884d, - ]), - ], - [ - pallas::Base::from_raw([ - 0xa7fc_32d2_2f18_b9d3, - 0xb8d2_de72_e3d2_c9ec, - 0xc6f0_39ea_1973_a63e, - 0x068d_6b46_08aa_e810, - ]), - pallas::Base::from_raw([ - 0x2b5d_fcc5_5725_55df, - 0xb868_a7d7_e1f1_f69a, - 0x0ee2_58c9_b8fd_fccd, - 0x366e_bfaf_a3ad_381c, - ]), - pallas::Base::from_raw([ - 0xe6bc_229e_95bc_76b1, - 0x7ef6_6d89_d044_d022, - 0x04db_3024_f41d_3f56, - 0x3967_8f65_512f_1ee4, - ]), - ], - [ - pallas::Base::from_raw([ - 0xe534_c88f_e53d_85fe, - 0xcf82_c25f_99dc_01a4, - 0xd58b_7750_a3bc_2fe1, - 0x2166_8f01_6a80_63c0, - ]), - pallas::Base::from_raw([ - 0x4bef_429b_c533_1608, - 0xe34d_ea56_439f_e195, - 0x1bc7_4936_3e98_a768, - 0x39d0_0994_a8a5_046a, - ]), - pallas::Base::from_raw([ - 0x770c_956f_60d8_81b3, - 0xb163_d416_05d3_9f99, - 0x6b20_3bbe_12fb_3425, - 0x1f9d_bdc3_f843_1263, - ]), - ], - [ - pallas::Base::from_raw([ - 0x9794_a9f7_c336_eab2, - 0xbe0b_c829_fe5e_66c6, - 0xe5f1_7b9e_0ee0_cab6, - 0x0277_45a9_cddf_ad95, - ]), - pallas::Base::from_raw([ - 0x5202_5657_abd8_aee0, - 0x2fa4_3fe2_0a45_c78d, - 0x788d_695c_61e9_3212, - 0x1cec_0803_c504_b635, - ]), - pallas::Base::from_raw([ - 0xd387_2a95_59a0_3a73, - 0xed50_82c8_dbf3_1365, - 0x7207_7448_ef87_cc6e, - 0x1235_23d7_5e9f_abc1, - ]), - ], - [ - pallas::Base::from_raw([ - 0x0017_79e3_a1d3_57f4, - 0x27fe_ba35_975e_e7e5, - 0xf419_b848_e5d6_94bf, - 0x1723_d145_2c9c_f02d, - ]), - pallas::Base::from_raw([ - 0x9dab_1ee4_dcf9_6622, - 0x21c3_f776_f572_836d, - 0xfcc0_573d_7e61_3694, - 0x1739_d180_a160_10bd, - ]), - pallas::Base::from_raw([ - 0x7029_0452_042d_048d, - 0xfafa_96fb_eb0a_b893, - 0xacce_3239_1794_b627, - 0x2d4e_6354_da9c_c554, - ]), - ], - [ - pallas::Base::from_raw([ - 0x670b_cf6f_8b48_5dcd, - 0x8f3b_d43f_9926_0621, - 0x4a86_9553_c9d0_07f8, - 0x153e_e614_2e53_5e33, - ]), - pallas::Base::from_raw([ - 0xd258_d2e2_b778_2172, - 0x968a_d442_4af8_3700, - 0x635e_f7e7_a430_b486, - 0x0c45_bfd3_a69a_aa65, - ]), - pallas::Base::from_raw([ - 0x0e56_33d2_51f7_3307, - 0x6897_ac0a_8ffa_5ff1, - 0xf2d5_6aec_8314_4600, - 0x0adf_d53b_256a_6957, - ]), - ], - [ - pallas::Base::from_raw([ - 0xac9d_36a8_b751_6d63, - 0x3f87_b28f_1c1b_e4bd, - 0x8cd1_726b_7cba_b8ee, - 0x315d_2ac8_ebdb_ac3c, - ]), - pallas::Base::from_raw([ - 0x299c_e44e_a423_d8e1, - 0xc9bb_60d1_f695_9879, - 0xcfae_c23d_2b16_883f, - 0x1b84_7271_2d02_eef4, - ]), - pallas::Base::from_raw([ - 0xc4a5_4041_98ad_f70c, - 0x367d_2c54_e369_28c9, - 0xbd0b_70fa_2255_eb6f, - 0x3c1c_d07e_fda6_ff24, - ]), - ], - [ - pallas::Base::from_raw([ - 0xbbe5_23ae_f9ab_107a, - 0x4a16_073f_738f_7e0c, - 0x687f_4e51_b2e1_dcd3, - 0x1360_52d2_6bb3_d373, - ]), - pallas::Base::from_raw([ - 0x676c_36c2_4ef9_67dd, - 0x7b3c_fbb8_7303_2681, - 0xc1bd_d859_a123_2a1d, - 0x16c9_6bee_f6a0_a848, - ]), - pallas::Base::from_raw([ - 0x067e_ec7f_2d63_40c4, - 0x0123_87ba_b4f1_662d, - 0x2ab7_fed8_f499_a9fb, - 0x284b_38c5_7ff6_5c26, - ]), - ], - [ - pallas::Base::from_raw([ - 0xaf1d_ff20_4c92_2f86, - 0xfc06_772c_1c04_11a6, - 0x39e2_4219_8897_d17c, - 0x0c59_93d1_75e8_1f66, - ]), - pallas::Base::from_raw([ - 0xbbf5_3f67_b1f8_7b15, - 0xf248_87ad_48e1_7759, - 0xfcda_655d_1ba9_c8f9, - 0x03bf_7a3f_7bd0_43da, - ]), - pallas::Base::from_raw([ - 0x9b5c_d09e_36d8_be62, - 0x4c8f_9cbe_69f0_e827, - 0xb0cf_9995_67f0_0e73, - 0x3188_fe4e_e9f9_fafb, - ]), - ], - [ - pallas::Base::from_raw([ - 0xafea_99a2_ec6c_595a, - 0x3af5_bf77_c1c4_2652, - 0x5a39_768c_480d_61e1, - 0x171f_528c_cf65_8437, - ]), - pallas::Base::from_raw([ - 0x5a05_63b9_b8e9_f1d5, - 0x812c_3286_ee70_0067, - 0x196e_4185_9b35_ef88, - 0x12f4_175c_4ab4_5afc, - ]), - pallas::Base::from_raw([ - 0x0e74_d4d3_6911_8b79, - 0x7e23_e1aa_be96_cfab, - 0x8f8f_dcf8_00a9_ac69, - 0x3a50_9e15_5cb7_ebfd, - ]), - ], - [ - pallas::Base::from_raw([ - 0x9871_2c65_678c_fd30, - 0x984b_c8f2_e4c1_b69e, - 0x1a89_920e_2504_c3b3, - 0x10f2_a685_df4a_27c8, - ]), - pallas::Base::from_raw([ - 0xe8a1_6728_cc9d_4918, - 0x5457_3c93_33c5_6321, - 0x1d8d_93d5_4ab9_1a0e, - 0x09e5_f497_90c8_a0e2, - ]), - pallas::Base::from_raw([ - 0x609a_7403_47cf_5fea, - 0x42d1_7ed6_ee0f_ab7e, - 0x2bf3_5705_d9f8_4a34, - 0x352d_69be_d80e_e3e5, - ]), - ], - [ - pallas::Base::from_raw([ - 0x3a75_8af6_fa84_e0e8, - 0xc634_debd_281b_76a6, - 0x4915_62fa_f2b1_90d3, - 0x058e_e73b_a9f3_f293, - ]), - pallas::Base::from_raw([ - 0x621a_1325_10a4_3904, - 0x092c_b921_19bc_76be, - 0xcd0f_1fc5_5b1a_3250, - 0x232f_99cc_911e_ddd9, - ]), - pallas::Base::from_raw([ - 0xc3b9_7c1e_301b_c213, - 0xf9ef_d52c_a6bc_2961, - 0x86c2_2c6c_5d48_69f0, - 0x201b_eed7_b8f3_ab81, - ]), - ], - [ - pallas::Base::from_raw([ - 0xbf6b_3431_ba94_e9bc, - 0x2938_8842_744a_1210, - 0xa1c9_291d_5860_2f51, - 0x1376_dce6_5800_30c6, - ]), - pallas::Base::from_raw([ - 0x6454_843c_5486_d7b3, - 0x072b_a8b0_2d92_e722, - 0x2b33_56c3_8238_f761, - 0x1793_199e_6fd6_ba34, - ]), - pallas::Base::from_raw([ - 0x06a3_f1d3_b433_311b, - 0x3c66_160d_c62a_acac, - 0x9fee_9c20_c87a_67df, - 0x22de_7a74_88dc_c735, - ]), - ], - [ - pallas::Base::from_raw([ - 0x30d6_e3fd_516b_47a8, - 0xdbe0_b77f_ae77_e1d0, - 0xdf8f_f37f_e2d8_edf8, - 0x3514_d5e9_066b_b160, - ]), - pallas::Base::from_raw([ - 0x1937_7427_137a_81c7, - 0xff45_3d6f_900f_144a, - 0xf919_a00d_abbf_5fa5, - 0x30cd_3006_931a_d636, - ]), - pallas::Base::from_raw([ - 0x5b6a_7422_0692_b506, - 0x8f9e_4b2c_ae2e_bb51, - 0x41f8_1a5c_f613_c8df, - 0x253d_1a5c_5293_4127, - ]), - ], - [ - pallas::Base::from_raw([ - 0x73f6_66cb_86a4_8e8e, - 0x851b_3a59_c990_fafc, - 0xa35e_9613_e7f5_fe92, - 0x035b_461c_02d7_9d19, - ]), - pallas::Base::from_raw([ - 0x7cfb_f86a_3aa0_4780, - 0x92b1_283c_2d5f_ccde, - 0x5bc0_0eed_d56b_93e0, - 0x23a9_9280_79d1_75bd, - ]), - pallas::Base::from_raw([ - 0xf1e4_ccd7_3fa0_0a82, - 0xb5e2_ea34_36ee_f957, - 0xf159_4a07_63c6_11ab, - 0x13a7_785a_e134_ea92, - ]), - ], - [ - pallas::Base::from_raw([ - 0xbbf0_4f52_52de_4279, - 0x3889_c578_6344_6d88, - 0x4962_ae3c_0da1_7e31, - 0x39fc_e308_b7d4_3c57, - ]), - pallas::Base::from_raw([ - 0x3b57_e344_89b5_3fad, - 0xbef0_0a08_c6ed_38d2, - 0xc0fd_f016_62f6_0d22, - 0x1aae_1883_3f8e_1d3a, - ]), - pallas::Base::from_raw([ - 0x5551_3e03_3398_513f, - 0x27c1_b3fd_8f85_d8a8, - 0x8b2e_80c0_64fd_83ed, - 0x1a76_1ce8_2400_af01, - ]), - ], - [ - pallas::Base::from_raw([ - 0x5244_ca74_9b73_e481, - 0xdcf6_af28_30a5_0287, - 0x16dd_1a87_ca22_e1cc, - 0x275a_03e4_5add_a7c3, - ]), - pallas::Base::from_raw([ - 0x58a2_53cf_b6a9_5786, - 0x07e5_6145_3fc5_648b, - 0xeb08_e47e_5fea_bcf8, - 0x2e5a_10f0_8b5a_b8bb, - ]), - pallas::Base::from_raw([ - 0xe033_d82c_efe7_8ce3, - 0xc141_a5b6_d594_bec4, - 0xb84e_9c33_3b29_32f1, - 0x1459_cb85_8720_8473, - ]), - ], - [ - pallas::Base::from_raw([ - 0x5cec_7e7b_338f_be1b, - 0x52f9_332f_bffc_fbbd, - 0x7b92_ce81_0e14_a400, - 0x193a_e592_1d78_b5de, - ]), - pallas::Base::from_raw([ - 0x6022_4be6_7248_e82c, - 0x3743_84f4_a072_8205, - 0x8911_1fb2_c466_0281, - 0x3097_898a_5d00_11a4, - ]), - pallas::Base::from_raw([ - 0x5499_80de_8629_30f5, - 0x1979_b2d1_c465_b4d9, - 0x5717_82fd_96ce_54b4, - 0x378d_97bf_8c86_4ae7, - ]), - ], - [ - pallas::Base::from_raw([ - 0x37ea_32a9_71d1_7884, - 0xdbc7_f5cb_4609_3421, - 0x8813_6287_ce37_6b08, - 0x2eb0_4ea7_c01d_97ec, - ]), - pallas::Base::from_raw([ - 0xead3_726f_1af2_e7b0, - 0x861c_bda4_7680_4e6c, - 0x2302_a1c2_2e49_baec, - 0x3642_5347_ea03_f641, - ]), - pallas::Base::from_raw([ - 0xecd6_27e5_9590_d09e, - 0x3f5b_5ca5_a19a_9701, - 0xcc99_6cd8_5c98_a1d8, - 0x26b7_2df4_7408_ad42, - ]), - ], - [ - pallas::Base::from_raw([ - 0x59be_ce31_f0a3_1e95, - 0xde01_212e_e458_8f89, - 0x1f05_636c_610b_89aa, - 0x1301_80e4_4e29_24db, - ]), - pallas::Base::from_raw([ - 0x9ea8_e7bc_7926_3550, - 0xdf77_93cc_89e5_b52f, - 0x7327_5aca_ed5f_579c, - 0x219e_9773_7d39_79ba, - ]), - pallas::Base::from_raw([ - 0x9c12_635d_f251_d153, - 0x3b06_72dd_7d42_cbb4, - 0x3461_363f_81c4_89a2, - 0x3cdb_9359_8a5c_a528, - ]), - ], - [ - pallas::Base::from_raw([ - 0x2861_ce16_f219_d5a9, - 0x4ad0_4470_45a7_c5aa, - 0x2072_4b92_7a0c_a81c, - 0x0e59_e6f3_32d7_ed37, - ]), - pallas::Base::from_raw([ - 0x43b0_a3fc_ff20_36bd, - 0x172c_c07b_9d33_fbf9, - 0x3d73_6946_7222_697a, - 0x1b06_4342_d51a_4275, - ]), - pallas::Base::from_raw([ - 0x3eb3_1022_8a0e_5f6c, - 0x78fa_9fb9_1712_21b7, - 0x2f36_3c55_b288_2e0b, - 0x30b8_2a99_8cbd_8e8a, - ]), - ], - [ - pallas::Base::from_raw([ - 0xe46f_6d42_9874_0107, - 0x8ad7_1ea7_15be_0573, - 0x63df_7a76_e858_a4aa, - 0x23e4_ab37_183a_cba4, - ]), - pallas::Base::from_raw([ - 0xfca9_95e2_b599_14a1, - 0xacfe_1464_0de0_44f2, - 0x5d33_094e_0bed_a75b, - 0x2795_d5c5_fa42_8022, - ]), - pallas::Base::from_raw([ - 0xc26d_909d_ee8b_53c0, - 0xa668_7c3d_f16c_8fe4, - 0xd765_f26d_d03f_4c45, - 0x3001_ca40_1e89_601c, - ]), - ], - [ - pallas::Base::from_raw([ - 0xe7fe_a6bd_f347_1380, - 0xe84b_5beb_ae4e_501d, - 0xf7bf_86e8_9280_827f, - 0x0072_e45c_c676_b08e, - ]), - pallas::Base::from_raw([ - 0xd0c5_4dde_b26b_86c0, - 0xb648_29e2_d40e_41bd, - 0xe2ab_e4c5_18ce_599e, - 0x13de_7054_8487_4bb5, - ]), - pallas::Base::from_raw([ - 0x3891_5b43_2a99_59a5, - 0x82bb_18e5_af1b_05bb, - 0x3159_50f1_211d_efe8, - 0x0408_a9fc_f9d6_1abf, - ]), - ], - [ - pallas::Base::from_raw([ - 0x3407_0cbe_e268_86a0, - 0xae4d_23b0_b41b_e9a8, - 0xbb4e_4a14_00cc_d2c4, - 0x2780_b9e7_5b55_676e, - ]), - pallas::Base::from_raw([ - 0x9405_5920_98b4_056f, - 0xdc4d_8fbe_fe24_405a, - 0xf803_33ec_8563_4ac9, - 0x3a57_0d4d_7c4e_7ac3, - ]), - pallas::Base::from_raw([ - 0x78d2_b247_8995_20b4, - 0xe2cc_1507_bebd_cc62, - 0xf347_c247_fcf0_9294, - 0x0c13_cca7_cb1f_9d2c, - ]), - ], - [ - pallas::Base::from_raw([ - 0x2e8c_88f7_7074_70e0, - 0x0b50_bb2e_b82d_f74d, - 0xd261_4a19_7c6b_794b, - 0x14f5_9baa_03cd_0ca4, - ]), - pallas::Base::from_raw([ - 0xbe52_476e_0a16_f3be, - 0xa51d_54ed_e661_67f5, - 0x6f54_6e17_04c3_9c60, - 0x307d_efee_925d_fb43, - ]), - pallas::Base::from_raw([ - 0x380b_67d8_0473_dce3, - 0x6611_0683_6adf_e5e7, - 0x7a07_e767_4b5a_2621, - 0x1960_cd51_1a91_e060, - ]), - ], - [ - pallas::Base::from_raw([ - 0x15aa_f1f7_7125_89dd, - 0xb8ee_335d_8828_4cbe, - 0xca2a_d0fb_5667_2500, - 0x2301_ef9c_63ea_84c5, - ]), - pallas::Base::from_raw([ - 0x5e68_478c_4d60_27a9, - 0xc861_82d1_b424_6b58, - 0xd10f_4cd5_2be9_7f6b, - 0x029a_5a47_da79_a488, - ]), - pallas::Base::from_raw([ - 0x2cc4_f962_eaae_2260, - 0xf97f_e46b_6a92_5428, - 0x2360_d17d_890e_55cb, - 0x32d7_b16a_7f11_cc96, - ]), - ], - [ - pallas::Base::from_raw([ - 0xc0ca_b915_d536_3d9f, - 0xa5f2_404c_d7b3_5eb0, - 0x18e8_57a9_8d49_8cf7, - 0x2670_3e48_c03b_81ca, - ]), - pallas::Base::from_raw([ - 0xf691_123a_e112_b928, - 0xf443_88bd_6b89_221e, - 0x88ac_8d25_a246_03f1, - 0x0486_82a3_5b32_65bc, - ]), - pallas::Base::from_raw([ - 0x3ab7_defc_b8d8_03e2, - 0x91d6_e171_5164_775e, - 0xd72c_ddc6_cf06_b507, - 0x06b1_3904_41fa_7030, - ]), - ], - [ - pallas::Base::from_raw([ - 0xbcd7_9541_4a6e_2e86, - 0x43b3_60f6_386a_86d7, - 0x1689_426d_ce05_fcd8, - 0x31aa_0eeb_868c_626d, - ]), - pallas::Base::from_raw([ - 0xed77_f5d5_76b9_9cc3, - 0x90ef_d8f4_1b20_78b2, - 0x057a_bad3_764c_104b, - 0x2394_64f7_5bf7_b6af, - ]), - pallas::Base::from_raw([ - 0xb2cb_4873_07c1_cecf, - 0xa5cc_47c5_9654_b2a7, - 0xa45e_19ed_813a_54ab, - 0x0a64_d4c0_4fd4_26bd, - ]), - ], - [ - pallas::Base::from_raw([ - 0x1f73_1532_2f65_8735, - 0x777c_7a92_1a06_2e9d, - 0x576a_4ad2_5986_0fb1, - 0x21fb_bdbb_7367_0734, - ]), - pallas::Base::from_raw([ - 0x6743_2400_3fc5_2146, - 0x5b86_d294_63d3_1564, - 0xd937_1ca2_eb95_acf3, - 0x31b8_6f3c_f017_05d4, - ]), - pallas::Base::from_raw([ - 0x7045_f48a_a4eb_4f6f, - 0x1354_1d65_157e_e1ce, - 0x05ef_1736_d090_56f6, - 0x2bfd_e533_5437_7c91, - ]), - ], - [ - pallas::Base::from_raw([ - 0x5a13_a58d_2001_1e2f, - 0xf4d5_239c_11d0_eafa, - 0xd558_f36e_65f8_eca7, - 0x1233_ca93_6ec2_4671, - ]), - pallas::Base::from_raw([ - 0x6e70_af0a_7a92_4b3a, - 0x8780_58d0_234a_576f, - 0xc437_846d_8e0b_2b30, - 0x27d4_52a4_3ac7_dea2, - ]), - pallas::Base::from_raw([ - 0xa025_76b9_4392_f980, - 0x6a30_641a_1c3d_87b2, - 0xe816_ea8d_a493_e0fa, - 0x2699_dba8_2184_e413, - ]), - ], - [ - pallas::Base::from_raw([ - 0x608c_6f7a_61b5_6e55, - 0xf185_8466_4f8c_ab49, - 0xc398_8bae_e42e_4b10, - 0x36c7_22f0_efcc_8803, - ]), - pallas::Base::from_raw([ - 0x6e49_ac17_0dbb_7fcd, - 0x85c3_8899_a7b5_a833, - 0x08b0_f2ec_89cc_aa37, - 0x02b3_ff48_861e_339b, - ]), - pallas::Base::from_raw([ - 0xa8c5_ae03_ad98_e405, - 0x6fc3_ff4c_49eb_59ad, - 0x6016_2f44_27bc_657b, - 0x0b70_d061_d58d_8a7f, - ]), - ], - [ - pallas::Base::from_raw([ - 0x2e06_cc4a_f33b_0a06, - 0xad3d_e8be_46ed_9693, - 0xf875_3ade_b9d7_cee2, - 0x3fc2_a13f_127f_96a4, - ]), - pallas::Base::from_raw([ - 0xc120_80ac_117e_e15f, - 0x00cb_3d62_1e17_1d80, - 0x1bd6_3434_ac8c_419f, - 0x0c41_a6e4_8dd2_3a51, - ]), - pallas::Base::from_raw([ - 0x9685_213e_9692_f5e1, - 0x72aa_ad7e_4e75_339d, - 0xed44_7653_7169_084e, - 0x2de8_072a_6bd8_6884, - ]), - ], - [ - pallas::Base::from_raw([ - 0x0ad0_1184_567b_027c, - 0xb81c_f735_cc9c_39c0, - 0x9d34_96a3_d9fe_05ec, - 0x0355_7a8f_7b38_a17f, - ]), - pallas::Base::from_raw([ - 0x45bc_b5ac_0082_6abc, - 0x060f_4336_3d81_8e54, - 0xee97_6d34_282f_1a37, - 0x0b5f_5955_2f49_8735, - ]), - pallas::Base::from_raw([ - 0x2f29_09e1_7e22_b0df, - 0xf5d6_46e5_7507_e548, - 0xfedb_b185_70dc_7300, - 0x0e29_23a5_fee7_b878, - ]), - ], - [ - pallas::Base::from_raw([ - 0xf71e_ed73_f15b_3326, - 0xcf1c_b37c_3b03_2af6, - 0xc787_be97_020a_7fdd, - 0x1d78_5005_a7a0_0592, - ]), - pallas::Base::from_raw([ - 0x0acf_bfb2_23f8_f00d, - 0xa590_b88a_3b06_0294, - 0x0ba5_fedc_b8f2_5bd2, - 0x1ad7_72c2_73d9_c6df, - ]), - pallas::Base::from_raw([ - 0xc1ce_13d6_0f2f_5031, - 0x8105_10eb_61f0_672d, - 0xa78f_3275_c278_234b, - 0x027b_d647_85fc_bd2a, - ]), - ], - [ - pallas::Base::from_raw([ - 0x8337_f5e0_7923_a853, - 0xe224_3134_6945_7b8e, - 0xce6f_8ffe_a103_1b6d, - 0x2080_0f44_1b4a_0526, - ]), - pallas::Base::from_raw([ - 0xa33d_7bed_89a4_408a, - 0x36cd_c8ee_d662_ad37, - 0x6eea_2cd4_9f43_12b4, - 0x3d5a_d61d_7b65_f938, - ]), - pallas::Base::from_raw([ - 0x3bbb_ae94_cc19_5284, - 0x1df9_6cc0_3ea4_b26d, - 0x02c5_f91b_e4dd_8e3d, - 0x1333_8bc3_51fc_46dd, - ]), - ], - [ - pallas::Base::from_raw([ - 0xc527_1c29_7852_819e, - 0x646c_49f9_b46c_bf19, - 0xb87d_b1e2_af3e_a923, - 0x25e5_2be5_07c9_2760, - ]), - pallas::Base::from_raw([ - 0x5c38_0ab7_01b5_2ea9, - 0xa34c_83a3_485c_6b2d, - 0x7109_6d8b_1b98_3c98, - 0x1c49_2d64_c157_aaa4, - ]), - pallas::Base::from_raw([ - 0xa20c_0b3d_a0da_4ca3, - 0xd434_87bc_288d_f682, - 0xf4e6_c5e7_a573_f592, - 0x0c5b_8015_7999_2718, - ]), - ], - [ - pallas::Base::from_raw([ - 0x7ea3_3c93_e408_33cf, - 0x584e_9e62_a7f9_554e, - 0x6869_5c0c_d7cb_f43d, - 0x1090_b1b4_d2be_be7a, - ]), - pallas::Base::from_raw([ - 0xe383_e1ec_3baa_8d69, - 0x1b21_8e35_ecf2_328e, - 0x68f5_ce5c_bed1_9cad, - 0x33e3_8018_a801_387a, - ]), - pallas::Base::from_raw([ - 0xb76b_0b3d_787e_e953, - 0x5f4a_02d2_8729_e3ae, - 0xeef8_d83d_0e87_6bac, - 0x1654_af18_772b_2da5, - ]), - ], - [ - pallas::Base::from_raw([ - 0xef7c_e6a0_1326_5477, - 0xbb08_9387_0367_ec6c, - 0x4474_2de8_8c5a_b0d5, - 0x1678_be3c_c9c6_7993, - ]), - pallas::Base::from_raw([ - 0xaf5d_4789_3348_f766, - 0xdaf1_8183_55b1_3b4f, - 0x7ff9_c6be_546e_928a, - 0x3780_bd1e_01f3_4c22, - ]), - pallas::Base::from_raw([ - 0xa123_8032_0d7c_c1de, - 0x5d11_e69a_a6c0_b98c, - 0x0786_018e_7cb7_7267, - 0x1e83_d631_5c9f_125b, - ]), - ], - [ - pallas::Base::from_raw([ - 0x1799_603e_855c_e731, - 0xc486_894d_76e0_c33b, - 0x160b_4155_2f29_31c8, - 0x354a_fd0a_2f9d_0b26, - ]), - pallas::Base::from_raw([ - 0x8b99_7ee0_6be1_bff3, - 0x60b0_0dbe_1fac_ed07, - 0x2d8a_ffa6_2905_c5a5, - 0x00cd_6d29_f166_eadc, - ]), - pallas::Base::from_raw([ - 0x08d0_6419_1708_2f2c, - 0xc60d_0197_3f18_3057, - 0xdbe0_e3d7_cdbc_66ef, - 0x1d62_1935_2768_e3ae, - ]), - ], - [ - pallas::Base::from_raw([ - 0xfa08_dd98_0638_7577, - 0xafe3_ca1d_b8d4_f529, - 0xe48d_2370_d7d1_a142, - 0x1463_36e2_5db5_181d, - ]), - pallas::Base::from_raw([ - 0xa901_d3ce_84de_0ad4, - 0x022e_54b4_9c13_d907, - 0x997a_2116_3e2e_43df, - 0x0005_d8e0_85fd_72ee, - ]), - pallas::Base::from_raw([ - 0x1c36_f313_4196_4484, - 0x6f8e_bc1d_2296_021a, - 0x0dd5_e61c_8a4e_8642, - 0x364e_97c7_a389_3227, - ]), - ], - [ - pallas::Base::from_raw([ - 0xd7a0_0c03_d2e0_baaa, - 0xfa97_ec80_ad30_7a52, - 0x561c_6fff_1534_6878, - 0x0118_9910_671b_c16b, - ]), - pallas::Base::from_raw([ - 0x63fd_8ac5_7a95_ca8c, - 0x4c0f_7e00_1df4_90aa, - 0x5229_dfaa_0123_1a45, - 0x162a_7c80_f4d2_d12e, - ]), - pallas::Base::from_raw([ - 0x32e6_9efb_22f4_0b96, - 0xcaff_31b4_fda3_2124, - 0x2604_e4af_b09f_8603, - 0x2a0d_6c09_5766_66bb, - ]), - ], - [ - pallas::Base::from_raw([ - 0xc0a0_180f_8cbf_c0d2, - 0xf444_d10d_63a7_4e2c, - 0xe16a_4d60_3d5a_808e, - 0x0978_e5c5_1e1e_5649, - ]), - pallas::Base::from_raw([ - 0x03f4_460e_bc35_1b6e, - 0x0508_7d90_3bda_cfd1, - 0xebe1_9bbd_ce25_1011, - 0x1bdc_ee3a_aca9_cd25, - ]), - pallas::Base::from_raw([ - 0xf619_64bf_3ade_7670, - 0x0c94_7321_e007_5e3f, - 0xe494_7914_0b19_44fd, - 0x1862_cccb_70b5_b885, - ]), - ], - [ - pallas::Base::from_raw([ - 0xc326_7da6_e94a_dc50, - 0x39ee_99c1_cc6e_5dda, - 0xbc26_cc88_3a19_87e1, - 0x1f3e_91d8_63c1_6922, - ]), - pallas::Base::from_raw([ - 0x0f85_b4ac_2c36_7406, - 0xfa66_1465_c656_ad99, - 0xef5c_08f8_478f_663a, - 0x1af4_7a48_a601_6a49, - ]), - pallas::Base::from_raw([ - 0x0eab_cd87_e7d0_1b15, - 0x1c36_98b0_a2e3_da10, - 0x009d_5733_8c69_3505, - 0x3c8e_e901_956e_3d3f, - ]), - ], - [ - pallas::Base::from_raw([ - 0x8b94_7721_8967_3476, - 0xe10c_e2b7_069f_4dbd, - 0x68d0_b024_f591_b520, - 0x1660_a8cd_e7fe_c553, - ]), - pallas::Base::from_raw([ - 0x9d8d_0f67_fdaa_79d5, - 0x3963_c2c1_f558_6e2f, - 0x1303_9363_34dd_1132, - 0x0f6d_9919_29d5_e4e7, - ]), - pallas::Base::from_raw([ - 0x7a43_3091_e1ce_2d3a, - 0x4e7f_da77_0712_f343, - 0xcc62_5eaa_ab52_b4dc, - 0x02b9_cea1_921c_d9f6, - ]), - ], - [ - pallas::Base::from_raw([ - 0x3797_b2d8_3760_43b3, - 0xd8ca_f468_976f_0472, - 0x214f_7c67_84ac_b565, - 0x14a3_23b9_9b90_0331, - ]), - pallas::Base::from_raw([ - 0x347f_ef2c_00f0_953a, - 0x718b_7fbc_7788_af78, - 0xec01_ea79_642d_5760, - 0x1904_76b5_80cb_9277, - ]), - pallas::Base::from_raw([ - 0xff4e_7e6f_b268_dfd7, - 0x9660_902b_6008_7651, - 0xa424_63d3_0b44_2b6f, - 0x090a_3a9d_869d_2eef, - ]), - ], - [ - pallas::Base::from_raw([ - 0xf983_387e_a045_6203, - 0xe365_0013_04f9_a11e, - 0x0dbe_8fd2_270a_6795, - 0x3877_a955_8636_7567, - ]), - pallas::Base::from_raw([ - 0x39c0_af0f_e01f_4a06, - 0x6011_8c53_a218_1352, - 0x5df3_9a2c_c63d_dc0a, - 0x2d89_4691_240f_e953, - ]), - pallas::Base::from_raw([ - 0x1aca_9eaf_9bba_9850, - 0x5914_e855_eeb4_4aa1, - 0x7ef7_1780_2016_6189, - 0x21b9_c182_92bd_bc59, - ]), - ], - [ - pallas::Base::from_raw([ - 0x33f5_09a7_4ad9_d39b, - 0x272e_1cc6_c36a_2968, - 0x505a_05f2_a6ae_834c, - 0x2fe7_6be7_cff7_23e2, - ]), - pallas::Base::from_raw([ - 0x0df9_fa97_277f_a8b4, - 0xd15b_ff84_0dda_e8a5, - 0x9299_81d7_cfce_253b, - 0x187a_a448_f391_e3ca, - ]), - pallas::Base::from_raw([ - 0xf0c6_6af5_ffc7_3736, - 0x663c_cf7b_2ffe_4b5e, - 0x007a_b3aa_3617_f422, - 0x0b70_83ad_7517_07bf, - ]), - ], - [ - pallas::Base::from_raw([ - 0x2f9b_20f1_fbd4_9791, - 0x1975_b962_f6cb_8e0b, - 0x3bc4_ca99_02c5_2acb, - 0x030d_dbb4_7049_3f16, - ]), - pallas::Base::from_raw([ - 0x3a1c_62ca_8fbf_2525, - 0x8fb8_ab9d_60ea_17b2, - 0x950b_0ab1_8d35_46df, - 0x3130_fbaf_fb5a_a82a, - ]), - pallas::Base::from_raw([ - 0x43a8_7618_0dc3_82e0, - 0x15ce_2ead_2fcd_051e, - 0x4f74_d74b_ac2e_e457, - 0x337f_5447_07c4_30f0, - ]), - ], - [ - pallas::Base::from_raw([ - 0x26de_98a8_736d_1d11, - 0x7d8e_471a_9fb9_5fef, - 0xac9d_91b0_930d_ac75, - 0x3499_7991_9015_394f, - ]), - pallas::Base::from_raw([ - 0xccfc_b618_31d5_c775, - 0x3bf9_3da6_fff3_1d95, - 0x2305_cd7a_921e_c5f1, - 0x027c_c4ef_e3fb_35dd, - ]), - pallas::Base::from_raw([ - 0xc3fa_2629_635d_27de, - 0x67f1_c6b7_3147_64af, - 0x61b7_1a36_9868_2ad2, - 0x037f_9f23_6595_4c5b, - ]), - ], - [ - pallas::Base::from_raw([ - 0x77c5_b024_8483_71ae, - 0x6041_4abe_362d_01c9, - 0x10f1_cc6d_f8b4_bcd7, - 0x1f69_7cac_4d07_feb7, - ]), - pallas::Base::from_raw([ - 0x786a_dd24_4aa0_ef29, - 0x3145_c478_0631_09d6, - 0x26e6_c851_fbd5_72a6, - 0x267a_750f_e5d7_cfbc, - ]), - pallas::Base::from_raw([ - 0x180e_2b4d_3e75_6f65, - 0xaf28_5fa8_2ce4_fae5, - 0x678c_9996_d9a4_72c8, - 0x0c91_feab_4a43_193a, - ]), - ], - [ - pallas::Base::from_raw([ - 0x79c4_7c57_3ac4_10f7, - 0x7e3b_83af_4a4b_a3ba, - 0x2186_c303_8ea0_5e69, - 0x1745_569a_0a3e_3014, - ]), - pallas::Base::from_raw([ - 0x1e03_8852_2696_191f, - 0xfdff_66c6_f3b5_ffe1, - 0xeca5_1207_78a5_6711, - 0x2986_3d54_6e7e_7c0d, - ]), - pallas::Base::from_raw([ - 0x2f22_5e63_66bf_e390, - 0xa79a_03df_8339_94c6, - 0xbf06_bae4_9ef8_53f6, - 0x1148_d6ab_2bd0_0192, - ]), - ], - [ - pallas::Base::from_raw([ - 0xf4f6_331a_8b26_5d15, - 0xf745_f45d_350d_41d4, - 0xe18b_1499_060d_a366, - 0x02e0_e121_b0f3_dfef, - ]), - pallas::Base::from_raw([ - 0x078a_e6aa_1510_54b7, - 0x6904_0173_6d44_a653, - 0xb89e_f73a_40a2_b274, - 0x0d0a_a46e_76a6_a278, - ]), - pallas::Base::from_raw([ - 0x9a4d_532c_7b6e_0958, - 0x392d_de71_0f1f_06db, - 0xeee5_45f3_fa6d_3d08, - 0x1394_3675_b04a_a986, - ]), - ], - [ - pallas::Base::from_raw([ - 0x961f_c818_dcbb_66b5, - 0xc9f2_b325_7530_dafe, - 0xd97a_11d6_3088_f5d9, - 0x2901_ec61_942d_34aa, - ]), - pallas::Base::from_raw([ - 0xfdf5_44b9_63d1_fdc7, - 0x22ff_a2a2_af9f_a3e3, - 0xf431_d544_34a3_e0cf, - 0x2020_4a21_05d2_2e7e, - ]), - pallas::Base::from_raw([ - 0x1211_b9e2_190d_6852, - 0xa004_abe8_e015_28c4, - 0x5c1e_3e9e_27a5_71c3, - 0x3a8a_6282_9512_1d5c, - ]), - ], -]; -// Secure MDS: 0 -// n: 255 -// t: 3 -// N: 765 -// Result Algorithm 1: -// [True, 0] -// Result Algorithm 2: -// [True, None] -// Result Algorithm 3: -// [True, None] -// Prime number: 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001 -// MDS matrix: -pub(crate) const MDS: [[pallas::Base; 3]; 3] = [ - [ - pallas::Base::from_raw([ - 0x323f_2486_d7e1_1b63, - 0x97d7_a0ab_2385_0b56, - 0xb3d5_9fbd_c8c9_ead4, - 0x0ab5_e5b8_74a6_8de7, - ]), - pallas::Base::from_raw([ - 0x8eca_5596_e996_ab5e, - 0x240d_4a7c_bf73_5736, - 0x293f_0f0d_886c_7954, - 0x3191_6628_e58a_5abb, - ]), - pallas::Base::from_raw([ - 0x19d1_cf25_d8e8_345d, - 0xa0a3_b71a_5fb1_5735, - 0xd803_952b_bb36_4fdf, - 0x07c0_45d5_f5e9_e5a6, - ]), - ], - [ - pallas::Base::from_raw([ - 0xd049_cdc8_d085_167c, - 0x3a0a_4640_48bd_770a, - 0xf8e2_4f66_822c_2d9f, - 0x2331_6263_0ebf_9ed7, - ]), - pallas::Base::from_raw([ - 0x4022_7011_3e04_7a2e, - 0x78f8_365c_85bb_ab07, - 0xb366_6454_8d60_957d, - 0x25ca_e259_9892_a8b0, - ]), - pallas::Base::from_raw([ - 0xf84d_806f_685f_747a, - 0x9aad_3d82_62ef_d83f, - 0x7493_8717_989a_1957, - 0x22f5_b5e1_e608_1c97, - ]), - ], - [ - pallas::Base::from_raw([ - 0xfee7_a994_4f84_dbe4, - 0x2168_0eab_c56b_c15d, - 0xf333_aa91_c383_3464, - 0x2e29_dd59_c64b_1037, - ]), - pallas::Base::from_raw([ - 0xc771_effa_4326_3664, - 0xcbea_f48b_3a06_24c3, - 0x92d1_5e7d_ceef_1665, - 0x1d1a_ab4e_c1cd_6788, - ]), - pallas::Base::from_raw([ - 0x1563_9415_f6e8_5ef1, - 0x7587_2c39_b59a_31f6, - 0x51e0_cbea_d655_16b9, - 0x3bf7_6308_6a18_9364, - ]), - ], -]; - -pub(crate) const MDS_INV: [[pallas::Base; 3]; 3] = [ - [ - pallas::Base::from_raw([ - 0xc6de_463c_d140_4e6b, - 0x4543_705f_35e9_8ab5, - 0xcc59_ffd0_0de8_6443, - 0x2cc0_57f3_fa14_687a, - ]), - pallas::Base::from_raw([ - 0x1718_4041_7cab_7576, - 0xfadb_f8ae_7ae2_4796, - 0x5fd7_2b55_df20_8385, - 0x32e7_c439_f2f9_67e5, - ]), - pallas::Base::from_raw([ - 0x9426_45bd_7d44_64e0, - 0x1403_db6f_5030_2040, - 0xf461_778a_bf6c_91fa, - 0x2eae_5df8_c311_5969, - ]), - ], - [ - pallas::Base::from_raw([ - 0xa1ca_1516_a4a1_a6a0, - 0x13f0_74fd_e9a1_8b29, - 0xdb18_b4ae_fe68_d26d, - 0x07bf_3684_8106_7199, - ]), - pallas::Base::from_raw([ - 0xe824_25bc_1b23_a059, - 0xbb1d_6504_0c85_c1bf, - 0x018a_918b_9dac_5dad, - 0x2aec_6906_c63f_3cf1, - ]), - pallas::Base::from_raw([ - 0xe054_1adf_238e_0781, - 0x76b2_a713_9db7_1b36, - 0x1215_944a_64a2_46b2, - 0x0952_e024_3aec_2af0, - ]), - ], - [ - pallas::Base::from_raw([ - 0x2a41_8d8d_73a7_c908, - 0xaef9_112e_952f_dbb5, - 0x723a_63a0_c09d_ab26, - 0x2fcb_ba6f_9159_a219, - ]), - pallas::Base::from_raw([ - 0x76ef_ab42_d4fb_a90b, - 0xc5e4_960d_7424_cd37, - 0xb4dd_d4b4_d645_2256, - 0x1ec7_3725_74f3_851b, - ]), - pallas::Base::from_raw([ - 0xadc8_933c_6f3c_72ee, - 0x87a7_435d_30f8_be81, - 0x3c26_fa4b_7d25_b1e4, - 0x0d0c_2efd_6472_f12a, - ]), - ], -]; diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/fq.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/fq.rs deleted file mode 100644 index f3a70686..00000000 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/fq.rs +++ /dev/null @@ -1,1431 +0,0 @@ -//! Constants for using Poseidon with the Vesta field. -//! -//! The constants can be reproduced by running the following Sage script from -//! [this repository](https://github.com/daira/pasta-hadeshash): -//! -//! ```text -//! sage generate_parameters_grain.sage 1 0 255 3 8 56 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 -//! ``` -use halo2_curves::pasta::vesta; - -// Number of round constants: 192 -// Round constants for GF(p): -pub(crate) const ROUND_CONSTANTS: [[vesta::Base; 3]; 64] = [ - [ - vesta::Base::from_raw([ - 0x5753_8c25_9642_6303, - 0x4e71_162f_3100_3b70, - 0x353f_628f_76d1_10f3, - 0x360d_7470_611e_473d, - ]), - vesta::Base::from_raw([ - 0xbdb7_4213_bf63_188b, - 0x4908_ac2f_12eb_e06f, - 0x5dc3_c6c5_febf_aa31, - 0x2bab_94d7_ae22_2d13, - ]), - vesta::Base::from_raw([ - 0x0939_d927_53cc_5dc8, - 0xef77_e7d7_3676_6c5d, - 0x2bf0_3e1a_29aa_871f, - 0x150c_93fe_f652_fb1c, - ]), - ], - [ - vesta::Base::from_raw([ - 0x1425_9dce_5377_82b2, - 0x03cc_0a60_141e_894e, - 0x955d_55db_56dc_57c1, - 0x3270_661e_6892_8b3a, - ]), - vesta::Base::from_raw([ - 0xce9f_b9ff_c345_afb3, - 0xb407_c370_f2b5_a1cc, - 0xa0b7_afe4_e205_7299, - 0x073f_116f_0412_2e25, - ]), - vesta::Base::from_raw([ - 0x8eba_d76f_c715_54d8, - 0x55c9_cd20_61ae_93ca, - 0x7aff_d09c_1f53_f5fd, - 0x2a32_ec5c_4ee5_b183, - ]), - ], - [ - vesta::Base::from_raw([ - 0x2d8c_cbe2_92ef_eead, - 0x634d_24fc_6e25_59f2, - 0x651e_2cfc_7406_28ca, - 0x2703_26ee_039d_f19e, - ]), - vesta::Base::from_raw([ - 0xa068_fc37_c182_e274, - 0x8af8_95bc_e012_f182, - 0xdc10_0fe7_fcfa_5491, - 0x27c6_642a_c633_bc66, - ]), - vesta::Base::from_raw([ - 0x9ca1_8682_e26d_7ff9, - 0x710e_1fb6_ab97_6a45, - 0xd27f_5739_6989_129d, - 0x1bdf_d8b0_1401_c70a, - ]), - ], - [ - vesta::Base::from_raw([ - 0xc832_d824_261a_35ea, - 0xf4f6_fb3f_9054_d373, - 0x14b9_d6a9_c84d_d678, - 0x162a_14c6_2f9a_89b8, - ]), - vesta::Base::from_raw([ - 0xf798_2466_7b5b_6bec, - 0xac0a_1fc7_1e2c_f0c0, - 0x2af6_f79e_3127_feea, - 0x2d19_3e0f_76de_586b, - ]), - vesta::Base::from_raw([ - 0x5d0b_f58d_c8a4_aa94, - 0x4fef_f829_8499_0ff8, - 0x8169_6ef1_104e_674f, - 0x044c_a3cc_4a85_d73b, - ]), - ], - [ - vesta::Base::from_raw([ - 0x6198_785f_0cd6_b9af, - 0xb8d9_e2d4_f314_f46f, - 0x1d04_5341_6d3e_235c, - 0x1cba_f2b3_71da_c6a8, - ]), - vesta::Base::from_raw([ - 0x343e_0761_0f3f_ede5, - 0x293c_4ab0_38fd_bbdc, - 0x0e6c_49d0_61b6_b5f4, - 0x1d5b_2777_692c_205b, - ]), - vesta::Base::from_raw([ - 0xf60e_971b_8d73_b04f, - 0x06a9_adb0_c1e6_f962, - 0xaa30_535b_dd74_9a7e, - 0x2e9b_dbba_3dd3_4bff, - ]), - ], - [ - vesta::Base::from_raw([ - 0x035a_1366_1f22_418b, - 0xde40_fbe2_6d04_7b05, - 0x8bd5_bae3_6969_299f, - 0x2de1_1886_b180_11ca, - ]), - vesta::Base::from_raw([ - 0xbc99_8884_ba96_a721, - 0x2ab9_395c_449b_e947, - 0x0d5b_4a3f_1841_dcd8, - 0x2e07_de17_80b8_a70d, - ]), - vesta::Base::from_raw([ - 0x825e_4c2b_b749_25ca, - 0x2504_40a9_9d6b_8af3, - 0xbbdb_63db_d52d_ad16, - 0x0f69_f185_4d20_ca0c, - ]), - ], - [ - vesta::Base::from_raw([ - 0x816c_0594_22dc_705e, - 0x6ce5_1135_07f9_6de9, - 0x0d13_5dc6_39fb_09a4, - 0x2eb1_b254_17fe_1767, - ]), - vesta::Base::from_raw([ - 0xb8b1_bdf4_953b_d82c, - 0xff36_c661_d26c_c42d, - 0x8c24_cb44_c3fa_b48a, - 0x115c_d0a0_643c_fb98, - ]), - vesta::Base::from_raw([ - 0xde80_1612_311d_04cd, - 0xbb57_ddf1_4e0f_958a, - 0x066d_7378_b999_868b, - 0x26ca_293f_7b2c_462d, - ]), - ], - [ - vesta::Base::from_raw([ - 0xf520_9d14_b248_20ca, - 0x0f16_0bf9_f71e_967f, - 0x2a83_0aa1_6241_2cd9, - 0x17bf_1b93_c4c7_e01a, - ]), - vesta::Base::from_raw([ - 0x05c8_6f2e_7dc2_93c5, - 0xe03c_0354_bd8c_fd38, - 0xa24f_8456_369c_85df, - 0x35b4_1a7a_c4f3_c571, - ]), - vesta::Base::from_raw([ - 0x72ac_156a_f435_d09e, - 0x64e1_4d3b_eb2d_ddde, - 0x4359_2799_4849_bea9, - 0x3b14_8008_0523_c439, - ]), - ], - [ - vesta::Base::from_raw([ - 0x2716_18d8_74b1_4c6d, - 0x08e2_8644_2a2d_3eb2, - 0x4950_856d_c907_d575, - 0x2cc6_8100_31dc_1b0d, - ]), - vesta::Base::from_raw([ - 0x91f3_18c0_9f0c_b566, - 0x9e51_7aa9_3b78_341d, - 0x0596_18e2_afd2_ef99, - 0x25bd_bbed_a1bd_e8c1, - ]), - vesta::Base::from_raw([ - 0xc631_3487_073f_7f7b, - 0x2a5e_d0a2_7b61_926c, - 0xb95f_33c2_5dde_8ac0, - 0x392a_4a87_58e0_6ee8, - ]), - ], - [ - vesta::Base::from_raw([ - 0xe7bb_cef0_2eb5_866c, - 0x5e6a_6fd1_5db8_9365, - 0x9aa6_111f_4de0_0948, - 0x272a_5587_8a08_442b, - ]), - vesta::Base::from_raw([ - 0x9b92_5b3c_5b21_e0e2, - 0xa6eb_ba01_1694_dd12, - 0xefa1_3c4e_60e2_6239, - 0x2d5b_308b_0cf0_2cdf, - ]), - vesta::Base::from_raw([ - 0xef38_c57c_3116_73ac, - 0x44df_f42f_18b4_6c56, - 0xdd5d_293d_72e2_e5f2, - 0x1654_9fc6_af2f_3b72, - ]), - ], - [ - vesta::Base::from_raw([ - 0x9b71_26d9_b468_60df, - 0x7639_8265_3442_0311, - 0xfa69_c3a2_ad52_f76d, - 0x1b10_bb7a_82af_ce39, - ]), - vesta::Base::from_raw([ - 0x90d2_7f6a_00b7_dfc8, - 0xd1b3_6968_ba04_05c0, - 0xc79c_2df7_dc98_a3be, - 0x0f1e_7505_ebd9_1d2f, - ]), - vesta::Base::from_raw([ - 0xff45_7756_b819_bb20, - 0x797f_d6e3_f18e_b1ca, - 0x537a_7497_a3b4_3f46, - 0x2f31_3faf_0d3f_6187, - ]), - ], - [ - vesta::Base::from_raw([ - 0xf0bc_3e73_2ecb_26f6, - 0x5cad_11eb_f0f7_ceb8, - 0xfa3c_a61c_0ed1_5bc5, - 0x3a5c_bb6d_e450_b481, - ]), - vesta::Base::from_raw([ - 0x8655_27cb_ca91_5982, - 0x51ba_a6e2_0f89_2b62, - 0xd920_86e2_53b4_39d6, - 0x3dab_54bc_9bef_688d, - ]), - vesta::Base::from_raw([ - 0x3680_45ac_f2b7_1ae3, - 0x4c24_b33b_410f_efd4, - 0xe280_d316_7012_3f74, - 0x06db_fb42_b979_884d, - ]), - ], - [ - vesta::Base::from_raw([ - 0xa7fc_32d2_2f18_b9d3, - 0xb8d2_de72_e3d2_c9ec, - 0xc6f0_39ea_1973_a63e, - 0x068d_6b46_08aa_e810, - ]), - vesta::Base::from_raw([ - 0x2b5d_fcc5_5725_55df, - 0xb868_a7d7_e1f1_f69a, - 0x0ee2_58c9_b8fd_fccd, - 0x366e_bfaf_a3ad_381c, - ]), - vesta::Base::from_raw([ - 0xe6bc_229e_95bc_76b1, - 0x7ef6_6d89_d044_d022, - 0x04db_3024_f41d_3f56, - 0x3967_8f65_512f_1ee4, - ]), - ], - [ - vesta::Base::from_raw([ - 0xe534_c88f_e53d_85fe, - 0xcf82_c25f_99dc_01a4, - 0xd58b_7750_a3bc_2fe1, - 0x2166_8f01_6a80_63c0, - ]), - vesta::Base::from_raw([ - 0x4bef_429b_c533_1608, - 0xe34d_ea56_439f_e195, - 0x1bc7_4936_3e98_a768, - 0x39d0_0994_a8a5_046a, - ]), - vesta::Base::from_raw([ - 0x770c_956f_60d8_81b3, - 0xb163_d416_05d3_9f99, - 0x6b20_3bbe_12fb_3425, - 0x1f9d_bdc3_f843_1263, - ]), - ], - [ - vesta::Base::from_raw([ - 0x9794_a9f7_c336_eab2, - 0xbe0b_c829_fe5e_66c6, - 0xe5f1_7b9e_0ee0_cab6, - 0x0277_45a9_cddf_ad95, - ]), - vesta::Base::from_raw([ - 0x5202_5657_abd8_aee0, - 0x2fa4_3fe2_0a45_c78d, - 0x788d_695c_61e9_3212, - 0x1cec_0803_c504_b635, - ]), - vesta::Base::from_raw([ - 0xd387_2a95_59a0_3a73, - 0xed50_82c8_dbf3_1365, - 0x7207_7448_ef87_cc6e, - 0x1235_23d7_5e9f_abc1, - ]), - ], - [ - vesta::Base::from_raw([ - 0x0017_79e3_a1d3_57f4, - 0x27fe_ba35_975e_e7e5, - 0xf419_b848_e5d6_94bf, - 0x1723_d145_2c9c_f02d, - ]), - vesta::Base::from_raw([ - 0x9dab_1ee4_dcf9_6622, - 0x21c3_f776_f572_836d, - 0xfcc0_573d_7e61_3694, - 0x1739_d180_a160_10bd, - ]), - vesta::Base::from_raw([ - 0x7029_0452_042d_048d, - 0xfafa_96fb_eb0a_b893, - 0xacce_3239_1794_b627, - 0x2d4e_6354_da9c_c554, - ]), - ], - [ - vesta::Base::from_raw([ - 0x670b_cf6f_8b48_5dcd, - 0x8f3b_d43f_9926_0621, - 0x4a86_9553_c9d0_07f8, - 0x153e_e614_2e53_5e33, - ]), - vesta::Base::from_raw([ - 0xd258_d2e2_b778_2172, - 0x968a_d442_4af8_3700, - 0x635e_f7e7_a430_b486, - 0x0c45_bfd3_a69a_aa65, - ]), - vesta::Base::from_raw([ - 0x0e56_33d2_51f7_3307, - 0x6897_ac0a_8ffa_5ff1, - 0xf2d5_6aec_8314_4600, - 0x0adf_d53b_256a_6957, - ]), - ], - [ - vesta::Base::from_raw([ - 0xac9d_36a8_b751_6d63, - 0x3f87_b28f_1c1b_e4bd, - 0x8cd1_726b_7cba_b8ee, - 0x315d_2ac8_ebdb_ac3c, - ]), - vesta::Base::from_raw([ - 0x299c_e44e_a423_d8e1, - 0xc9bb_60d1_f695_9879, - 0xcfae_c23d_2b16_883f, - 0x1b84_7271_2d02_eef4, - ]), - vesta::Base::from_raw([ - 0xc4a5_4041_98ad_f70c, - 0x367d_2c54_e369_28c9, - 0xbd0b_70fa_2255_eb6f, - 0x3c1c_d07e_fda6_ff24, - ]), - ], - [ - vesta::Base::from_raw([ - 0xbbe5_23ae_f9ab_107a, - 0x4a16_073f_738f_7e0c, - 0x687f_4e51_b2e1_dcd3, - 0x1360_52d2_6bb3_d373, - ]), - vesta::Base::from_raw([ - 0x676c_36c2_4ef9_67dd, - 0x7b3c_fbb8_7303_2681, - 0xc1bd_d859_a123_2a1d, - 0x16c9_6bee_f6a0_a848, - ]), - vesta::Base::from_raw([ - 0x067e_ec7f_2d63_40c4, - 0x0123_87ba_b4f1_662d, - 0x2ab7_fed8_f499_a9fb, - 0x284b_38c5_7ff6_5c26, - ]), - ], - [ - vesta::Base::from_raw([ - 0xaf1d_ff20_4c92_2f86, - 0xfc06_772c_1c04_11a6, - 0x39e2_4219_8897_d17c, - 0x0c59_93d1_75e8_1f66, - ]), - vesta::Base::from_raw([ - 0xbbf5_3f67_b1f8_7b15, - 0xf248_87ad_48e1_7759, - 0xfcda_655d_1ba9_c8f9, - 0x03bf_7a3f_7bd0_43da, - ]), - vesta::Base::from_raw([ - 0x9b5c_d09e_36d8_be62, - 0x4c8f_9cbe_69f0_e827, - 0xb0cf_9995_67f0_0e73, - 0x3188_fe4e_e9f9_fafb, - ]), - ], - [ - vesta::Base::from_raw([ - 0xafea_99a2_ec6c_595a, - 0x3af5_bf77_c1c4_2652, - 0x5a39_768c_480d_61e1, - 0x171f_528c_cf65_8437, - ]), - vesta::Base::from_raw([ - 0x5a05_63b9_b8e9_f1d5, - 0x812c_3286_ee70_0067, - 0x196e_4185_9b35_ef88, - 0x12f4_175c_4ab4_5afc, - ]), - vesta::Base::from_raw([ - 0x0e74_d4d3_6911_8b79, - 0x7e23_e1aa_be96_cfab, - 0x8f8f_dcf8_00a9_ac69, - 0x3a50_9e15_5cb7_ebfd, - ]), - ], - [ - vesta::Base::from_raw([ - 0x9871_2c65_678c_fd30, - 0x984b_c8f2_e4c1_b69e, - 0x1a89_920e_2504_c3b3, - 0x10f2_a685_df4a_27c8, - ]), - vesta::Base::from_raw([ - 0xe8a1_6728_cc9d_4918, - 0x5457_3c93_33c5_6321, - 0x1d8d_93d5_4ab9_1a0e, - 0x09e5_f497_90c8_a0e2, - ]), - vesta::Base::from_raw([ - 0x609a_7403_47cf_5fea, - 0x42d1_7ed6_ee0f_ab7e, - 0x2bf3_5705_d9f8_4a34, - 0x352d_69be_d80e_e3e5, - ]), - ], - [ - vesta::Base::from_raw([ - 0x3a75_8af6_fa84_e0e8, - 0xc634_debd_281b_76a6, - 0x4915_62fa_f2b1_90d3, - 0x058e_e73b_a9f3_f293, - ]), - vesta::Base::from_raw([ - 0x621a_1325_10a4_3904, - 0x092c_b921_19bc_76be, - 0xcd0f_1fc5_5b1a_3250, - 0x232f_99cc_911e_ddd9, - ]), - vesta::Base::from_raw([ - 0xc3b9_7c1e_301b_c213, - 0xf9ef_d52c_a6bc_2961, - 0x86c2_2c6c_5d48_69f0, - 0x201b_eed7_b8f3_ab81, - ]), - ], - [ - vesta::Base::from_raw([ - 0xbf6b_3431_ba94_e9bc, - 0x2938_8842_744a_1210, - 0xa1c9_291d_5860_2f51, - 0x1376_dce6_5800_30c6, - ]), - vesta::Base::from_raw([ - 0x6454_843c_5486_d7b3, - 0x072b_a8b0_2d92_e722, - 0x2b33_56c3_8238_f761, - 0x1793_199e_6fd6_ba34, - ]), - vesta::Base::from_raw([ - 0x06a3_f1d3_b433_311b, - 0x3c66_160d_c62a_acac, - 0x9fee_9c20_c87a_67df, - 0x22de_7a74_88dc_c735, - ]), - ], - [ - vesta::Base::from_raw([ - 0x30d6_e3fd_516b_47a8, - 0xdbe0_b77f_ae77_e1d0, - 0xdf8f_f37f_e2d8_edf8, - 0x3514_d5e9_066b_b160, - ]), - vesta::Base::from_raw([ - 0x1937_7427_137a_81c7, - 0xff45_3d6f_900f_144a, - 0xf919_a00d_abbf_5fa5, - 0x30cd_3006_931a_d636, - ]), - vesta::Base::from_raw([ - 0x5b6a_7422_0692_b506, - 0x8f9e_4b2c_ae2e_bb51, - 0x41f8_1a5c_f613_c8df, - 0x253d_1a5c_5293_4127, - ]), - ], - [ - vesta::Base::from_raw([ - 0x73f6_66cb_86a4_8e8e, - 0x851b_3a59_c990_fafc, - 0xa35e_9613_e7f5_fe92, - 0x035b_461c_02d7_9d19, - ]), - vesta::Base::from_raw([ - 0x7cfb_f86a_3aa0_4780, - 0x92b1_283c_2d5f_ccde, - 0x5bc0_0eed_d56b_93e0, - 0x23a9_9280_79d1_75bd, - ]), - vesta::Base::from_raw([ - 0xf1e4_ccd7_3fa0_0a82, - 0xb5e2_ea34_36ee_f957, - 0xf159_4a07_63c6_11ab, - 0x13a7_785a_e134_ea92, - ]), - ], - [ - vesta::Base::from_raw([ - 0xbbf0_4f52_52de_4279, - 0x3889_c578_6344_6d88, - 0x4962_ae3c_0da1_7e31, - 0x39fc_e308_b7d4_3c57, - ]), - vesta::Base::from_raw([ - 0x3b57_e344_89b5_3fad, - 0xbef0_0a08_c6ed_38d2, - 0xc0fd_f016_62f6_0d22, - 0x1aae_1883_3f8e_1d3a, - ]), - vesta::Base::from_raw([ - 0x5551_3e03_3398_513f, - 0x27c1_b3fd_8f85_d8a8, - 0x8b2e_80c0_64fd_83ed, - 0x1a76_1ce8_2400_af01, - ]), - ], - [ - vesta::Base::from_raw([ - 0x5244_ca74_9b73_e481, - 0xdcf6_af28_30a5_0287, - 0x16dd_1a87_ca22_e1cc, - 0x275a_03e4_5add_a7c3, - ]), - vesta::Base::from_raw([ - 0x58a2_53cf_b6a9_5786, - 0x07e5_6145_3fc5_648b, - 0xeb08_e47e_5fea_bcf8, - 0x2e5a_10f0_8b5a_b8bb, - ]), - vesta::Base::from_raw([ - 0xe033_d82c_efe7_8ce3, - 0xc141_a5b6_d594_bec4, - 0xb84e_9c33_3b29_32f1, - 0x1459_cb85_8720_8473, - ]), - ], - [ - vesta::Base::from_raw([ - 0x5cec_7e7b_338f_be1b, - 0x52f9_332f_bffc_fbbd, - 0x7b92_ce81_0e14_a400, - 0x193a_e592_1d78_b5de, - ]), - vesta::Base::from_raw([ - 0x6022_4be6_7248_e82c, - 0x3743_84f4_a072_8205, - 0x8911_1fb2_c466_0281, - 0x3097_898a_5d00_11a4, - ]), - vesta::Base::from_raw([ - 0x5499_80de_8629_30f5, - 0x1979_b2d1_c465_b4d9, - 0x5717_82fd_96ce_54b4, - 0x378d_97bf_8c86_4ae7, - ]), - ], - [ - vesta::Base::from_raw([ - 0x37ea_32a9_71d1_7884, - 0xdbc7_f5cb_4609_3421, - 0x8813_6287_ce37_6b08, - 0x2eb0_4ea7_c01d_97ec, - ]), - vesta::Base::from_raw([ - 0xead3_726f_1af2_e7b0, - 0x861c_bda4_7680_4e6c, - 0x2302_a1c2_2e49_baec, - 0x3642_5347_ea03_f641, - ]), - vesta::Base::from_raw([ - 0xecd6_27e5_9590_d09e, - 0x3f5b_5ca5_a19a_9701, - 0xcc99_6cd8_5c98_a1d8, - 0x26b7_2df4_7408_ad42, - ]), - ], - [ - vesta::Base::from_raw([ - 0x59be_ce31_f0a3_1e95, - 0xde01_212e_e458_8f89, - 0x1f05_636c_610b_89aa, - 0x1301_80e4_4e29_24db, - ]), - vesta::Base::from_raw([ - 0x9ea8_e7bc_7926_3550, - 0xdf77_93cc_89e5_b52f, - 0x7327_5aca_ed5f_579c, - 0x219e_9773_7d39_79ba, - ]), - vesta::Base::from_raw([ - 0x9c12_635d_f251_d153, - 0x3b06_72dd_7d42_cbb4, - 0x3461_363f_81c4_89a2, - 0x3cdb_9359_8a5c_a528, - ]), - ], - [ - vesta::Base::from_raw([ - 0x2861_ce16_f219_d5a9, - 0x4ad0_4470_45a7_c5aa, - 0x2072_4b92_7a0c_a81c, - 0x0e59_e6f3_32d7_ed37, - ]), - vesta::Base::from_raw([ - 0x43b0_a3fc_ff20_36bd, - 0x172c_c07b_9d33_fbf9, - 0x3d73_6946_7222_697a, - 0x1b06_4342_d51a_4275, - ]), - vesta::Base::from_raw([ - 0x3eb3_1022_8a0e_5f6c, - 0x78fa_9fb9_1712_21b7, - 0x2f36_3c55_b288_2e0b, - 0x30b8_2a99_8cbd_8e8a, - ]), - ], - [ - vesta::Base::from_raw([ - 0xe46f_6d42_9874_0107, - 0x8ad7_1ea7_15be_0573, - 0x63df_7a76_e858_a4aa, - 0x23e4_ab37_183a_cba4, - ]), - vesta::Base::from_raw([ - 0xfca9_95e2_b599_14a1, - 0xacfe_1464_0de0_44f2, - 0x5d33_094e_0bed_a75b, - 0x2795_d5c5_fa42_8022, - ]), - vesta::Base::from_raw([ - 0xc26d_909d_ee8b_53c0, - 0xa668_7c3d_f16c_8fe4, - 0xd765_f26d_d03f_4c45, - 0x3001_ca40_1e89_601c, - ]), - ], - [ - vesta::Base::from_raw([ - 0xe7fe_a6bd_f347_1380, - 0xe84b_5beb_ae4e_501d, - 0xf7bf_86e8_9280_827f, - 0x0072_e45c_c676_b08e, - ]), - vesta::Base::from_raw([ - 0xd0c5_4dde_b26b_86c0, - 0xb648_29e2_d40e_41bd, - 0xe2ab_e4c5_18ce_599e, - 0x13de_7054_8487_4bb5, - ]), - vesta::Base::from_raw([ - 0x3891_5b43_2a99_59a5, - 0x82bb_18e5_af1b_05bb, - 0x3159_50f1_211d_efe8, - 0x0408_a9fc_f9d6_1abf, - ]), - ], - [ - vesta::Base::from_raw([ - 0x3407_0cbe_e268_86a0, - 0xae4d_23b0_b41b_e9a8, - 0xbb4e_4a14_00cc_d2c4, - 0x2780_b9e7_5b55_676e, - ]), - vesta::Base::from_raw([ - 0x9405_5920_98b4_056f, - 0xdc4d_8fbe_fe24_405a, - 0xf803_33ec_8563_4ac9, - 0x3a57_0d4d_7c4e_7ac3, - ]), - vesta::Base::from_raw([ - 0x78d2_b247_8995_20b4, - 0xe2cc_1507_bebd_cc62, - 0xf347_c247_fcf0_9294, - 0x0c13_cca7_cb1f_9d2c, - ]), - ], - [ - vesta::Base::from_raw([ - 0x2e8c_88f7_7074_70e0, - 0x0b50_bb2e_b82d_f74d, - 0xd261_4a19_7c6b_794b, - 0x14f5_9baa_03cd_0ca4, - ]), - vesta::Base::from_raw([ - 0xbe52_476e_0a16_f3be, - 0xa51d_54ed_e661_67f5, - 0x6f54_6e17_04c3_9c60, - 0x307d_efee_925d_fb43, - ]), - vesta::Base::from_raw([ - 0x380b_67d8_0473_dce3, - 0x6611_0683_6adf_e5e7, - 0x7a07_e767_4b5a_2621, - 0x1960_cd51_1a91_e060, - ]), - ], - [ - vesta::Base::from_raw([ - 0x15aa_f1f7_7125_89dd, - 0xb8ee_335d_8828_4cbe, - 0xca2a_d0fb_5667_2500, - 0x2301_ef9c_63ea_84c5, - ]), - vesta::Base::from_raw([ - 0x5e68_478c_4d60_27a9, - 0xc861_82d1_b424_6b58, - 0xd10f_4cd5_2be9_7f6b, - 0x029a_5a47_da79_a488, - ]), - vesta::Base::from_raw([ - 0x2cc4_f962_eaae_2260, - 0xf97f_e46b_6a92_5428, - 0x2360_d17d_890e_55cb, - 0x32d7_b16a_7f11_cc96, - ]), - ], - [ - vesta::Base::from_raw([ - 0xc0ca_b915_d536_3d9f, - 0xa5f2_404c_d7b3_5eb0, - 0x18e8_57a9_8d49_8cf7, - 0x2670_3e48_c03b_81ca, - ]), - vesta::Base::from_raw([ - 0xf691_123a_e112_b928, - 0xf443_88bd_6b89_221e, - 0x88ac_8d25_a246_03f1, - 0x0486_82a3_5b32_65bc, - ]), - vesta::Base::from_raw([ - 0x3ab7_defc_b8d8_03e2, - 0x91d6_e171_5164_775e, - 0xd72c_ddc6_cf06_b507, - 0x06b1_3904_41fa_7030, - ]), - ], - [ - vesta::Base::from_raw([ - 0xbcd7_9541_4a6e_2e86, - 0x43b3_60f6_386a_86d7, - 0x1689_426d_ce05_fcd8, - 0x31aa_0eeb_868c_626d, - ]), - vesta::Base::from_raw([ - 0xed77_f5d5_76b9_9cc3, - 0x90ef_d8f4_1b20_78b2, - 0x057a_bad3_764c_104b, - 0x2394_64f7_5bf7_b6af, - ]), - vesta::Base::from_raw([ - 0xb2cb_4873_07c1_cecf, - 0xa5cc_47c5_9654_b2a7, - 0xa45e_19ed_813a_54ab, - 0x0a64_d4c0_4fd4_26bd, - ]), - ], - [ - vesta::Base::from_raw([ - 0x1f73_1532_2f65_8735, - 0x777c_7a92_1a06_2e9d, - 0x576a_4ad2_5986_0fb1, - 0x21fb_bdbb_7367_0734, - ]), - vesta::Base::from_raw([ - 0x6743_2400_3fc5_2146, - 0x5b86_d294_63d3_1564, - 0xd937_1ca2_eb95_acf3, - 0x31b8_6f3c_f017_05d4, - ]), - vesta::Base::from_raw([ - 0x7045_f48a_a4eb_4f6f, - 0x1354_1d65_157e_e1ce, - 0x05ef_1736_d090_56f6, - 0x2bfd_e533_5437_7c91, - ]), - ], - [ - vesta::Base::from_raw([ - 0x5a13_a58d_2001_1e2f, - 0xf4d5_239c_11d0_eafa, - 0xd558_f36e_65f8_eca7, - 0x1233_ca93_6ec2_4671, - ]), - vesta::Base::from_raw([ - 0x6e70_af0a_7a92_4b3a, - 0x8780_58d0_234a_576f, - 0xc437_846d_8e0b_2b30, - 0x27d4_52a4_3ac7_dea2, - ]), - vesta::Base::from_raw([ - 0xa025_76b9_4392_f980, - 0x6a30_641a_1c3d_87b2, - 0xe816_ea8d_a493_e0fa, - 0x2699_dba8_2184_e413, - ]), - ], - [ - vesta::Base::from_raw([ - 0x608c_6f7a_61b5_6e55, - 0xf185_8466_4f8c_ab49, - 0xc398_8bae_e42e_4b10, - 0x36c7_22f0_efcc_8803, - ]), - vesta::Base::from_raw([ - 0x6e49_ac17_0dbb_7fcd, - 0x85c3_8899_a7b5_a833, - 0x08b0_f2ec_89cc_aa37, - 0x02b3_ff48_861e_339b, - ]), - vesta::Base::from_raw([ - 0xa8c5_ae03_ad98_e405, - 0x6fc3_ff4c_49eb_59ad, - 0x6016_2f44_27bc_657b, - 0x0b70_d061_d58d_8a7f, - ]), - ], - [ - vesta::Base::from_raw([ - 0x2e06_cc4a_f33b_0a06, - 0xad3d_e8be_46ed_9693, - 0xf875_3ade_b9d7_cee2, - 0x3fc2_a13f_127f_96a4, - ]), - vesta::Base::from_raw([ - 0xc120_80ac_117e_e15f, - 0x00cb_3d62_1e17_1d80, - 0x1bd6_3434_ac8c_419f, - 0x0c41_a6e4_8dd2_3a51, - ]), - vesta::Base::from_raw([ - 0x9685_213e_9692_f5e1, - 0x72aa_ad7e_4e75_339d, - 0xed44_7653_7169_084e, - 0x2de8_072a_6bd8_6884, - ]), - ], - [ - vesta::Base::from_raw([ - 0x0ad0_1184_567b_027c, - 0xb81c_f735_cc9c_39c0, - 0x9d34_96a3_d9fe_05ec, - 0x0355_7a8f_7b38_a17f, - ]), - vesta::Base::from_raw([ - 0x45bc_b5ac_0082_6abc, - 0x060f_4336_3d81_8e54, - 0xee97_6d34_282f_1a37, - 0x0b5f_5955_2f49_8735, - ]), - vesta::Base::from_raw([ - 0x2f29_09e1_7e22_b0df, - 0xf5d6_46e5_7507_e548, - 0xfedb_b185_70dc_7300, - 0x0e29_23a5_fee7_b878, - ]), - ], - [ - vesta::Base::from_raw([ - 0xf71e_ed73_f15b_3326, - 0xcf1c_b37c_3b03_2af6, - 0xc787_be97_020a_7fdd, - 0x1d78_5005_a7a0_0592, - ]), - vesta::Base::from_raw([ - 0x0acf_bfb2_23f8_f00d, - 0xa590_b88a_3b06_0294, - 0x0ba5_fedc_b8f2_5bd2, - 0x1ad7_72c2_73d9_c6df, - ]), - vesta::Base::from_raw([ - 0xc1ce_13d6_0f2f_5031, - 0x8105_10eb_61f0_672d, - 0xa78f_3275_c278_234b, - 0x027b_d647_85fc_bd2a, - ]), - ], - [ - vesta::Base::from_raw([ - 0x8337_f5e0_7923_a853, - 0xe224_3134_6945_7b8e, - 0xce6f_8ffe_a103_1b6d, - 0x2080_0f44_1b4a_0526, - ]), - vesta::Base::from_raw([ - 0xa33d_7bed_89a4_408a, - 0x36cd_c8ee_d662_ad37, - 0x6eea_2cd4_9f43_12b4, - 0x3d5a_d61d_7b65_f938, - ]), - vesta::Base::from_raw([ - 0x3bbb_ae94_cc19_5284, - 0x1df9_6cc0_3ea4_b26d, - 0x02c5_f91b_e4dd_8e3d, - 0x1333_8bc3_51fc_46dd, - ]), - ], - [ - vesta::Base::from_raw([ - 0xc527_1c29_7852_819e, - 0x646c_49f9_b46c_bf19, - 0xb87d_b1e2_af3e_a923, - 0x25e5_2be5_07c9_2760, - ]), - vesta::Base::from_raw([ - 0x5c38_0ab7_01b5_2ea9, - 0xa34c_83a3_485c_6b2d, - 0x7109_6d8b_1b98_3c98, - 0x1c49_2d64_c157_aaa4, - ]), - vesta::Base::from_raw([ - 0xa20c_0b3d_a0da_4ca3, - 0xd434_87bc_288d_f682, - 0xf4e6_c5e7_a573_f592, - 0x0c5b_8015_7999_2718, - ]), - ], - [ - vesta::Base::from_raw([ - 0x7ea3_3c93_e408_33cf, - 0x584e_9e62_a7f9_554e, - 0x6869_5c0c_d7cb_f43d, - 0x1090_b1b4_d2be_be7a, - ]), - vesta::Base::from_raw([ - 0xe383_e1ec_3baa_8d69, - 0x1b21_8e35_ecf2_328e, - 0x68f5_ce5c_bed1_9cad, - 0x33e3_8018_a801_387a, - ]), - vesta::Base::from_raw([ - 0xb76b_0b3d_787e_e953, - 0x5f4a_02d2_8729_e3ae, - 0xeef8_d83d_0e87_6bac, - 0x1654_af18_772b_2da5, - ]), - ], - [ - vesta::Base::from_raw([ - 0xef7c_e6a0_1326_5477, - 0xbb08_9387_0367_ec6c, - 0x4474_2de8_8c5a_b0d5, - 0x1678_be3c_c9c6_7993, - ]), - vesta::Base::from_raw([ - 0xaf5d_4789_3348_f766, - 0xdaf1_8183_55b1_3b4f, - 0x7ff9_c6be_546e_928a, - 0x3780_bd1e_01f3_4c22, - ]), - vesta::Base::from_raw([ - 0xa123_8032_0d7c_c1de, - 0x5d11_e69a_a6c0_b98c, - 0x0786_018e_7cb7_7267, - 0x1e83_d631_5c9f_125b, - ]), - ], - [ - vesta::Base::from_raw([ - 0x1799_603e_855c_e731, - 0xc486_894d_76e0_c33b, - 0x160b_4155_2f29_31c8, - 0x354a_fd0a_2f9d_0b26, - ]), - vesta::Base::from_raw([ - 0x8b99_7ee0_6be1_bff3, - 0x60b0_0dbe_1fac_ed07, - 0x2d8a_ffa6_2905_c5a5, - 0x00cd_6d29_f166_eadc, - ]), - vesta::Base::from_raw([ - 0x08d0_6419_1708_2f2c, - 0xc60d_0197_3f18_3057, - 0xdbe0_e3d7_cdbc_66ef, - 0x1d62_1935_2768_e3ae, - ]), - ], - [ - vesta::Base::from_raw([ - 0xfa08_dd98_0638_7577, - 0xafe3_ca1d_b8d4_f529, - 0xe48d_2370_d7d1_a142, - 0x1463_36e2_5db5_181d, - ]), - vesta::Base::from_raw([ - 0xa901_d3ce_84de_0ad4, - 0x022e_54b4_9c13_d907, - 0x997a_2116_3e2e_43df, - 0x0005_d8e0_85fd_72ee, - ]), - vesta::Base::from_raw([ - 0x1c36_f313_4196_4484, - 0x6f8e_bc1d_2296_021a, - 0x0dd5_e61c_8a4e_8642, - 0x364e_97c7_a389_3227, - ]), - ], - [ - vesta::Base::from_raw([ - 0xd7a0_0c03_d2e0_baaa, - 0xfa97_ec80_ad30_7a52, - 0x561c_6fff_1534_6878, - 0x0118_9910_671b_c16b, - ]), - vesta::Base::from_raw([ - 0x63fd_8ac5_7a95_ca8c, - 0x4c0f_7e00_1df4_90aa, - 0x5229_dfaa_0123_1a45, - 0x162a_7c80_f4d2_d12e, - ]), - vesta::Base::from_raw([ - 0x32e6_9efb_22f4_0b96, - 0xcaff_31b4_fda3_2124, - 0x2604_e4af_b09f_8603, - 0x2a0d_6c09_5766_66bb, - ]), - ], - [ - vesta::Base::from_raw([ - 0xc0a0_180f_8cbf_c0d2, - 0xf444_d10d_63a7_4e2c, - 0xe16a_4d60_3d5a_808e, - 0x0978_e5c5_1e1e_5649, - ]), - vesta::Base::from_raw([ - 0x03f4_460e_bc35_1b6e, - 0x0508_7d90_3bda_cfd1, - 0xebe1_9bbd_ce25_1011, - 0x1bdc_ee3a_aca9_cd25, - ]), - vesta::Base::from_raw([ - 0xf619_64bf_3ade_7670, - 0x0c94_7321_e007_5e3f, - 0xe494_7914_0b19_44fd, - 0x1862_cccb_70b5_b885, - ]), - ], - [ - vesta::Base::from_raw([ - 0xc326_7da6_e94a_dc50, - 0x39ee_99c1_cc6e_5dda, - 0xbc26_cc88_3a19_87e1, - 0x1f3e_91d8_63c1_6922, - ]), - vesta::Base::from_raw([ - 0x0f85_b4ac_2c36_7406, - 0xfa66_1465_c656_ad99, - 0xef5c_08f8_478f_663a, - 0x1af4_7a48_a601_6a49, - ]), - vesta::Base::from_raw([ - 0x0eab_cd87_e7d0_1b15, - 0x1c36_98b0_a2e3_da10, - 0x009d_5733_8c69_3505, - 0x3c8e_e901_956e_3d3f, - ]), - ], - [ - vesta::Base::from_raw([ - 0x8b94_7721_8967_3476, - 0xe10c_e2b7_069f_4dbd, - 0x68d0_b024_f591_b520, - 0x1660_a8cd_e7fe_c553, - ]), - vesta::Base::from_raw([ - 0x9d8d_0f67_fdaa_79d5, - 0x3963_c2c1_f558_6e2f, - 0x1303_9363_34dd_1132, - 0x0f6d_9919_29d5_e4e7, - ]), - vesta::Base::from_raw([ - 0x7a43_3091_e1ce_2d3a, - 0x4e7f_da77_0712_f343, - 0xcc62_5eaa_ab52_b4dc, - 0x02b9_cea1_921c_d9f6, - ]), - ], - [ - vesta::Base::from_raw([ - 0x3797_b2d8_3760_43b3, - 0xd8ca_f468_976f_0472, - 0x214f_7c67_84ac_b565, - 0x14a3_23b9_9b90_0331, - ]), - vesta::Base::from_raw([ - 0x347f_ef2c_00f0_953a, - 0x718b_7fbc_7788_af78, - 0xec01_ea79_642d_5760, - 0x1904_76b5_80cb_9277, - ]), - vesta::Base::from_raw([ - 0xff4e_7e6f_b268_dfd7, - 0x9660_902b_6008_7651, - 0xa424_63d3_0b44_2b6f, - 0x090a_3a9d_869d_2eef, - ]), - ], - [ - vesta::Base::from_raw([ - 0xf983_387e_a045_6203, - 0xe365_0013_04f9_a11e, - 0x0dbe_8fd2_270a_6795, - 0x3877_a955_8636_7567, - ]), - vesta::Base::from_raw([ - 0x39c0_af0f_e01f_4a06, - 0x6011_8c53_a218_1352, - 0x5df3_9a2c_c63d_dc0a, - 0x2d89_4691_240f_e953, - ]), - vesta::Base::from_raw([ - 0x1aca_9eaf_9bba_9850, - 0x5914_e855_eeb4_4aa1, - 0x7ef7_1780_2016_6189, - 0x21b9_c182_92bd_bc59, - ]), - ], - [ - vesta::Base::from_raw([ - 0x33f5_09a7_4ad9_d39b, - 0x272e_1cc6_c36a_2968, - 0x505a_05f2_a6ae_834c, - 0x2fe7_6be7_cff7_23e2, - ]), - vesta::Base::from_raw([ - 0x0df9_fa97_277f_a8b4, - 0xd15b_ff84_0dda_e8a5, - 0x9299_81d7_cfce_253b, - 0x187a_a448_f391_e3ca, - ]), - vesta::Base::from_raw([ - 0xf0c6_6af5_ffc7_3736, - 0x663c_cf7b_2ffe_4b5e, - 0x007a_b3aa_3617_f422, - 0x0b70_83ad_7517_07bf, - ]), - ], - [ - vesta::Base::from_raw([ - 0x2f9b_20f1_fbd4_9791, - 0x1975_b962_f6cb_8e0b, - 0x3bc4_ca99_02c5_2acb, - 0x030d_dbb4_7049_3f16, - ]), - vesta::Base::from_raw([ - 0x3a1c_62ca_8fbf_2525, - 0x8fb8_ab9d_60ea_17b2, - 0x950b_0ab1_8d35_46df, - 0x3130_fbaf_fb5a_a82a, - ]), - vesta::Base::from_raw([ - 0x43a8_7618_0dc3_82e0, - 0x15ce_2ead_2fcd_051e, - 0x4f74_d74b_ac2e_e457, - 0x337f_5447_07c4_30f0, - ]), - ], - [ - vesta::Base::from_raw([ - 0x26de_98a8_736d_1d11, - 0x7d8e_471a_9fb9_5fef, - 0xac9d_91b0_930d_ac75, - 0x3499_7991_9015_394f, - ]), - vesta::Base::from_raw([ - 0xccfc_b618_31d5_c775, - 0x3bf9_3da6_fff3_1d95, - 0x2305_cd7a_921e_c5f1, - 0x027c_c4ef_e3fb_35dd, - ]), - vesta::Base::from_raw([ - 0xc3fa_2629_635d_27de, - 0x67f1_c6b7_3147_64af, - 0x61b7_1a36_9868_2ad2, - 0x037f_9f23_6595_4c5b, - ]), - ], - [ - vesta::Base::from_raw([ - 0x77c5_b024_8483_71ae, - 0x6041_4abe_362d_01c9, - 0x10f1_cc6d_f8b4_bcd7, - 0x1f69_7cac_4d07_feb7, - ]), - vesta::Base::from_raw([ - 0x786a_dd24_4aa0_ef29, - 0x3145_c478_0631_09d6, - 0x26e6_c851_fbd5_72a6, - 0x267a_750f_e5d7_cfbc, - ]), - vesta::Base::from_raw([ - 0x180e_2b4d_3e75_6f65, - 0xaf28_5fa8_2ce4_fae5, - 0x678c_9996_d9a4_72c8, - 0x0c91_feab_4a43_193a, - ]), - ], - [ - vesta::Base::from_raw([ - 0x79c4_7c57_3ac4_10f7, - 0x7e3b_83af_4a4b_a3ba, - 0x2186_c303_8ea0_5e69, - 0x1745_569a_0a3e_3014, - ]), - vesta::Base::from_raw([ - 0x1e03_8852_2696_191f, - 0xfdff_66c6_f3b5_ffe1, - 0xeca5_1207_78a5_6711, - 0x2986_3d54_6e7e_7c0d, - ]), - vesta::Base::from_raw([ - 0x2f22_5e63_66bf_e390, - 0xa79a_03df_8339_94c6, - 0xbf06_bae4_9ef8_53f6, - 0x1148_d6ab_2bd0_0192, - ]), - ], - [ - vesta::Base::from_raw([ - 0xf4f6_331a_8b26_5d15, - 0xf745_f45d_350d_41d4, - 0xe18b_1499_060d_a366, - 0x02e0_e121_b0f3_dfef, - ]), - vesta::Base::from_raw([ - 0x078a_e6aa_1510_54b7, - 0x6904_0173_6d44_a653, - 0xb89e_f73a_40a2_b274, - 0x0d0a_a46e_76a6_a278, - ]), - vesta::Base::from_raw([ - 0x9a4d_532c_7b6e_0958, - 0x392d_de71_0f1f_06db, - 0xeee5_45f3_fa6d_3d08, - 0x1394_3675_b04a_a986, - ]), - ], - [ - vesta::Base::from_raw([ - 0x961f_c818_dcbb_66b5, - 0xc9f2_b325_7530_dafe, - 0xd97a_11d6_3088_f5d9, - 0x2901_ec61_942d_34aa, - ]), - vesta::Base::from_raw([ - 0xfdf5_44b9_63d1_fdc7, - 0x22ff_a2a2_af9f_a3e3, - 0xf431_d544_34a3_e0cf, - 0x2020_4a21_05d2_2e7e, - ]), - vesta::Base::from_raw([ - 0x1211_b9e2_190d_6852, - 0xa004_abe8_e015_28c4, - 0x5c1e_3e9e_27a5_71c3, - 0x3a8a_6282_9512_1d5c, - ]), - ], -]; - -// n: 255 -// t: 3 -// N: 765 -// Result Algorithm 1: -// [True, 0] -// Result Algorithm 2: -// [True, None] -// Result Algorithm 3: -// [True, None] -// Prime number: 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 -// MDS matrix: -pub(crate) const MDS: [[vesta::Base; 3]; 3] = [ - [ - vesta::Base::from_raw([ - 0xeb4f_1f74_2963_421f, - 0x5f71_0afc_43dd_c5f6, - 0x9191_3f56_cf21_af2b, - 0x1853_b497_7c6f_a227, - ]), - vesta::Base::from_raw([ - 0x45e5_1db6_ac6f_e4a7, - 0x5a0f_a4df_a500_bcad, - 0x63f4_84c1_0fcf_0586, - 0x3d83_1189_cfbb_c452, - ]), - vesta::Base::from_raw([ - 0xd188_37f9_8347_f137, - 0x3f89_65c7_8083_8a94, - 0x4ba8_8b9e_4017_19c0, - 0x3a0e_3f84_d3c1_77d8, - ]), - ], - [ - vesta::Base::from_raw([ - 0x84fd_7923_337c_f77e, - 0x2896_f8d0_fd5c_9a75, - 0x8e9d_c529_f471_8f83, - 0x35e2_6e39_8450_6279, - ]), - vesta::Base::from_raw([ - 0x3eb9_24f5_6fff_7908, - 0x3641_cecf_3a2a_5a8a, - 0x00cd_7dbe_a799_70ab, - 0x10a8_1663_02cb_753c, - ]), - vesta::Base::from_raw([ - 0xb672_27c1_a141_ae94, - 0x198e_1aee_777e_2521, - 0xf434_92ce_5121_4b00, - 0x314f_762a_506d_321b, - ]), - ], - [ - vesta::Base::from_raw([ - 0xabcb_d614_eaf5_eba1, - 0xa90f_28b0_cb31_76fb, - 0xcb2e_ab86_ef31_d915, - 0x07b8_5627_c832_782a, - ]), - vesta::Base::from_raw([ - 0xc255_efd0_06b5_db1c, - 0xb5d9_85dc_1630_a4b2, - 0x9756_4e1b_5d1a_c72f, - 0x2a2d_e13e_70f2_7e16, - ]), - vesta::Base::from_raw([ - 0xcffd_f529_3334_29fc, - 0x21e3_af7e_f123_32cd, - 0xfff5_40a8_7327_c7ce, - 0x2c60_94d1_c6e1_caba, - ]), - ], -]; - -pub(crate) const MDS_INV: [[vesta::Base; 3]; 3] = [ - [ - vesta::Base::from_raw([ - 0xb204_ddc6_5e58_2044, - 0x47a6_0484_b0a9_9c91, - 0xcaf5_4d78_24c1_200e, - 0x36df_4950_21cf_7828, - ]), - vesta::Base::from_raw([ - 0x6a6b_94ad_aa0d_9c9e, - 0xe2cd_38b9_59d4_61ff, - 0xe43e_c4bf_3e0d_f00c, - 0x034f_beae_4650_c2c7, - ]), - vesta::Base::from_raw([ - 0xa862_7a02_8c1a_f7d6, - 0x841b_ebf1_a15b_746e, - 0x1fd5_6832_d0ab_5570, - 0x20a8_64d6_790f_7c1c, - ]), - ], - [ - vesta::Base::from_raw([ - 0x3470_d5c5_53bc_9d20, - 0x1f95_660f_eb5d_b121, - 0xdd31_97ac_c894_9076, - 0x2d08_703d_48ec_d7dc, - ]), - vesta::Base::from_raw([ - 0x6b5b_42b0_67d8_30f3, - 0x6169_b6fa_721a_470e, - 0xeff3_18a2_8983_158a, - 0x2db1_0ecd_507a_2f27, - ]), - vesta::Base::from_raw([ - 0xfbae_b537_d278_4760, - 0x0068_e709_07e7_089d, - 0x926a_5fc0_cc1e_f726, - 0x0c8a_58c0_6473_cdfa, - ]), - ], - [ - vesta::Base::from_raw([ - 0x3a5a_ca10_7129_6e61, - 0x4ad4_442e_96c9_d5e8, - 0x5432_f0c0_b908_a411, - 0x2a64_2dca_695d_744d, - ]), - vesta::Base::from_raw([ - 0x1bd9_bfcb_be02_5ff1, - 0x24f6_ad43_b703_ad90, - 0xebb7_238d_f00d_17e7, - 0x114e_c796_fb40_3f5f, - ]), - vesta::Base::from_raw([ - 0x67f0_642e_14a9_c3bf, - 0xf6a6_9176_7069_7a97, - 0x0408_110d_c66e_b147, - 0x2825_e067_5968_dbeb, - ]), - ], -]; diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/p128pow5t3.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/p128pow5t3.rs deleted file mode 100644 index b3493199..00000000 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/p128pow5t3.rs +++ /dev/null @@ -1,320 +0,0 @@ -use halo2_proofs::arithmetic::Field; -use halo2_curves::pasta::{pallas::Base as Fp, vesta::Base as Fq}; - -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". -/// -/// The standard specification for this set of parameters (on either of the Pasta -/// fields) uses $R_F = 8, R_P = 56$. This is conveniently an even number of -/// partial rounds, making it easier to construct a Halo 2 circuit. -#[derive(Debug)] -pub struct P128Pow5T3; - -impl Spec for P128Pow5T3 { - fn full_rounds() -> usize { - 8 - } - - fn partial_rounds() -> usize { - 56 - } - - fn sbox(val: Fp) -> Fp { - val.pow_vartime([5]) - } - - fn secure_mds() -> usize { - unimplemented!() - } - - fn constants() -> (Vec<[Fp; 3]>, Mds, Mds) { - ( - super::fp::ROUND_CONSTANTS[..].to_vec(), - super::fp::MDS, - super::fp::MDS_INV, - ) - } -} - -impl Spec for P128Pow5T3 { - fn full_rounds() -> usize { - 8 - } - - fn partial_rounds() -> usize { - 56 - } - - fn sbox(val: Fq) -> Fq { - val.pow_vartime([5]) - } - - fn secure_mds() -> usize { - unimplemented!() - } - - fn constants() -> (Vec<[Fq; 3]>, Mds, Mds) { - ( - super::fq::ROUND_CONSTANTS[..].to_vec(), - super::fq::MDS, - super::fq::MDS_INV, - ) - } -} - -#[cfg(test)] -mod tests { - #![allow(dead_code)] - use super::{ - super::{fp, fq}, - Fp, Fq, - }; - use crate::circuits::poseidongadget::poseidon::primitives::{ - generate_constants, permute, ConstantLength, Hash, Mds, Spec, - }; - use ff::PrimeField; - use ff::{Field, FromUniformBytes}; - use std::marker::PhantomData; - - /// The same Poseidon specification as poseidon::P128Pow5T3, but constructed - /// such that its constants will be generated at runtime. - #[derive(Debug)] - pub struct P128Pow5T3Gen(PhantomData); - - impl P128Pow5T3Gen { - pub fn new() -> Self { - P128Pow5T3Gen(PhantomData) - } - } - - impl + Ord, const SECURE_MDS: usize> Spec - for P128Pow5T3Gen - { - fn full_rounds() -> usize { - 8 - } - - fn partial_rounds() -> usize { - 56 - } - - fn sbox(val: F) -> F { - val.pow_vartime([5]) - } - - fn secure_mds() -> usize { - SECURE_MDS - } - - fn constants() -> (Vec<[F; 3]>, Mds, Mds) { - generate_constants::<_, Self, 3, 2>() - } - } - - #[test] - fn verify_constants() { - fn verify_constants_helper + Ord>( - expected_round_constants: [[F; 3]; 64], - expected_mds: [[F; 3]; 3], - expected_mds_inv: [[F; 3]; 3], - ) { - let (round_constants, mds, mds_inv) = P128Pow5T3Gen::::constants(); - - for (actual, expected) in round_constants - .iter() - .flatten() - .zip(expected_round_constants.iter().flatten()) - { - assert_eq!(actual, expected); - } - - for (actual, expected) in mds.iter().flatten().zip(expected_mds.iter().flatten()) { - assert_eq!(actual, expected); - } - - for (actual, expected) in mds_inv - .iter() - .flatten() - .zip(expected_mds_inv.iter().flatten()) - { - assert_eq!(actual, expected); - } - } - - verify_constants_helper(fp::ROUND_CONSTANTS, fp::MDS, fp::MDS_INV); - verify_constants_helper(fq::ROUND_CONSTANTS, fq::MDS, fq::MDS_INV); - } - - #[test] - fn test_against_reference() { - { - // , using parameters from - // `generate_parameters_grain.sage 1 0 255 3 8 56 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001`. - // The test vector is generated by `sage poseidonperm_x5_pallas_3.sage --rust` - - let mut 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 expected_output = [ - Fp::from_raw([ - 0xaeb1_bc02_4aec_a456, - 0xf7e6_9a71_d0b6_42a0, - 0x94ef_b364_f966_240f, - 0x2a52_6acd_0b64_b453, - ]), - Fp::from_raw([ - 0x012a_3e96_28e5_b82a, - 0xdcd4_2e7f_bed9_dafe, - 0x76ff_7dae_343d_5512, - 0x13c5_d156_8b4a_a430, - ]), - Fp::from_raw([ - 0x3590_29a1_d34e_9ddd, - 0xf7cf_dfe1_bda4_2c7b, - 0x256f_cd59_7984_561a, - 0x0a49_c868_c697_6544, - ]), - ]; - - permute::, 3, 2>(&mut input, &fp::MDS, &fp::ROUND_CONSTANTS); - assert_eq!(input, expected_output); - } - - { - // , using parameters from - // `generate_parameters_grain.sage 1 0 255 3 8 56 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001`. - // The test vector is generated by `sage poseidonperm_x5_vesta_3.sage --rust` - - let mut input = [ - Fq::from_raw([ - 0x0000_0000_0000_0000, - 0x0000_0000_0000_0000, - 0x0000_0000_0000_0000, - 0x0000_0000_0000_0000, - ]), - Fq::from_raw([ - 0x0000_0000_0000_0001, - 0x0000_0000_0000_0000, - 0x0000_0000_0000_0000, - 0x0000_0000_0000_0000, - ]), - Fq::from_raw([ - 0x0000_0000_0000_0002, - 0x0000_0000_0000_0000, - 0x0000_0000_0000_0000, - 0x0000_0000_0000_0000, - ]), - ]; - - let expected_output = [ - Fq::from_raw([ - 0x0eb0_8ea8_13be_be59, - 0x4d43_d197_3dd3_36c6, - 0xeddd_74f2_2f8f_2ff7, - 0x315a_1f4c_db94_2f7c, - ]), - Fq::from_raw([ - 0xf9f1_26e6_1ea1_65f1, - 0x413e_e0eb_7bbd_2198, - 0x642a_dee0_dd13_aa48, - 0x3be4_75f2_d764_2bde, - ]), - Fq::from_raw([ - 0x14d5_4237_2a7b_a0d9, - 0x5019_bfd4_e042_3fa0, - 0x117f_db24_20d8_ea60, - 0x25ab_8aec_e953_7168, - ]), - ]; - - permute::, 3, 2>(&mut input, &fq::MDS, &fq::ROUND_CONSTANTS); - assert_eq!(input, expected_output); - } - } - - #[test] - fn permute_test_vectors() { - { - let (round_constants, mds, _) = super::P128Pow5T3::constants(); - - for tv in crate::circuits::poseidongadget::poseidon::primitives::test_vectors::fp::permute() { - let mut state = [ - Fp::from_repr(tv.initial_state[0]).unwrap(), - Fp::from_repr(tv.initial_state[1]).unwrap(), - Fp::from_repr(tv.initial_state[2]).unwrap(), - ]; - - permute::(&mut state, &mds, &round_constants); - - for (expected, actual) in tv.final_state.iter().zip(state.iter()) { - assert_eq!(&actual.to_repr(), expected); - } - } - } - - { - let (round_constants, mds, _) = super::P128Pow5T3::constants(); - - for tv in crate::circuits::poseidongadget::poseidon::primitives::test_vectors::fq::permute() { - let mut state = [ - Fq::from_repr(tv.initial_state[0]).unwrap(), - Fq::from_repr(tv.initial_state[1]).unwrap(), - Fq::from_repr(tv.initial_state[2]).unwrap(), - ]; - - permute::(&mut state, &mds, &round_constants); - - for (expected, actual) in tv.final_state.iter().zip(state.iter()) { - assert_eq!(&actual.to_repr(), expected); - } - } - } - } - - #[test] - fn hash_test_vectors() { - for tv in crate::circuits::poseidongadget::poseidon::primitives::test_vectors::fp::hash() { - let message = [ - Fp::from_repr(tv.input[0]).unwrap(), - Fp::from_repr(tv.input[1]).unwrap(), - ]; - - let result = - Hash::<_, super::P128Pow5T3, ConstantLength<2>, 3, 2>::init().hash(message); - - assert_eq!(result.to_repr(), tv.output); - } - - for tv in crate::circuits::poseidongadget::poseidon::primitives::test_vectors::fq::hash() { - let message = [ - Fq::from_repr(tv.input[0]).unwrap(), - Fq::from_repr(tv.input[1]).unwrap(), - ]; - - let result = - Hash::<_, super::P128Pow5T3, ConstantLength<2>, 3, 2>::init().hash(message); - - assert_eq!(result.to_repr(), tv.output); - } - } -} diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/test_vectors.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/test_vectors.rs deleted file mode 100644 index 1c345a48..00000000 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/test_vectors.rs +++ /dev/null @@ -1,1261 +0,0 @@ -//! Test vectors for [`OrchardNullifier`]. - -pub(crate) struct PermuteTestVector { - pub(crate) initial_state: [[u8; 32]; 3], - pub(crate) final_state: [[u8; 32]; 3], -} - -pub(crate) struct HashTestVector { - pub(crate) input: [[u8; 32]; 2], - pub(crate) output: [u8; 32], -} - -pub(crate) mod fp { - use super::*; - - pub(crate) fn permute() -> Vec { - use PermuteTestVector as TestVector; - - // From https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/orchard_poseidon/permute/fp.py - vec![ - TestVector { - initial_state: [ - [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ], - [ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ], - [ - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ], - ], - final_state: [ - [ - 0x56, 0xa4, 0xec, 0x4a, 0x02, 0xbc, 0xb1, 0xae, 0xa0, 0x42, 0xb6, 0xd0, - 0x71, 0x9a, 0xe6, 0xf7, 0x0f, 0x24, 0x66, 0xf9, 0x64, 0xb3, 0xef, 0x94, - 0x53, 0xb4, 0x64, 0x0b, 0xcd, 0x6a, 0x52, 0x2a, - ], - [ - 0x2a, 0xb8, 0xe5, 0x28, 0x96, 0x3e, 0x2a, 0x01, 0xfe, 0xda, 0xd9, 0xbe, - 0x7f, 0x2e, 0xd4, 0xdc, 0x12, 0x55, 0x3d, 0x34, 0xae, 0x7d, 0xff, 0x76, - 0x30, 0xa4, 0x4a, 0x8b, 0x56, 0xd1, 0xc5, 0x13, - ], - [ - 0xdd, 0x9d, 0x4e, 0xd3, 0xa1, 0x29, 0x90, 0x35, 0x7b, 0x2c, 0xa4, 0xbd, - 0xe1, 0xdf, 0xcf, 0xf7, 0x1a, 0x56, 0x84, 0x79, 0x59, 0xcd, 0x6f, 0x25, - 0x44, 0x65, 0x97, 0xc6, 0x68, 0xc8, 0x49, 0x0a, - ], - ], - }, - TestVector { - initial_state: [ - [ - 0x5c, 0x7a, 0x8f, 0x73, 0xad, 0xfc, 0x70, 0xfb, 0x3f, 0x13, 0x94, 0x49, - 0xac, 0x6b, 0x57, 0x07, 0x4c, 0x4d, 0x6e, 0x66, 0xb1, 0x64, 0x93, 0x9d, - 0xaf, 0xfa, 0x2e, 0xf6, 0xee, 0x69, 0x21, 0x08, - ], - [ - 0x1a, 0xdd, 0x86, 0xb3, 0xf2, 0xe1, 0xbd, 0xa6, 0x2a, 0x5d, 0x2e, 0x0e, - 0x98, 0x2b, 0x77, 0xe6, 0xb0, 0xef, 0x9c, 0xa3, 0xf2, 0x49, 0x88, 0xc7, - 0xb3, 0x53, 0x42, 0x01, 0xcf, 0xb1, 0xcd, 0x0d, - ], - [ - 0xbd, 0x69, 0xb8, 0x25, 0x32, 0xb6, 0x94, 0x0f, 0xf2, 0x59, 0x0f, 0x67, - 0x9b, 0xa9, 0xc7, 0x27, 0x1f, 0xe0, 0x1f, 0x7e, 0x9c, 0x8e, 0x36, 0xd6, - 0xa5, 0xe2, 0x9d, 0x4e, 0x30, 0xa7, 0x35, 0x14, - ], - ], - final_state: [ - [ - 0xd0, 0x6e, 0x2f, 0x83, 0x38, 0x92, 0x8a, 0x7e, 0xe7, 0x38, 0x0c, 0x77, - 0x92, 0x80, 0x87, 0xcd, 0xa2, 0xfd, 0x29, 0x61, 0xa1, 0x52, 0x69, 0x03, - 0x7a, 0x22, 0xd6, 0xd1, 0x20, 0xae, 0xdd, 0x21, - ], - [ - 0x29, 0x55, 0xa4, 0x5f, 0x41, 0x6f, 0x10, 0xd6, 0xbc, 0x79, 0xac, 0x94, - 0xd0, 0xc0, 0x69, 0xc9, 0x49, 0xe5, 0xf4, 0xbd, 0x09, 0x48, 0x1e, 0x1f, - 0x36, 0x8c, 0xb9, 0xb8, 0xee, 0x51, 0x14, 0x0d, - ], - [ - 0x0d, 0x83, 0x76, 0xbb, 0xe9, 0xd6, 0x5d, 0x2b, 0x1e, 0x13, 0x6f, 0xb7, - 0xd9, 0x82, 0xab, 0x87, 0xc5, 0x1c, 0x40, 0x30, 0x44, 0xbe, 0x5c, 0x79, - 0x9d, 0x56, 0xbb, 0x68, 0xac, 0xf9, 0x5b, 0x10, - ], - ], - }, - TestVector { - initial_state: [ - [ - 0xbc, 0x50, 0x98, 0x42, 0x55, 0xd6, 0xaf, 0xbe, 0x9e, 0xf9, 0x28, 0x48, - 0xed, 0x5a, 0xc0, 0x08, 0x62, 0xc2, 0xfa, 0x7b, 0x2f, 0xec, 0xbc, 0xb6, - 0x4b, 0x69, 0x68, 0x91, 0x2a, 0x63, 0x81, 0x0e, - ], - [ - 0x3d, 0xc1, 0x66, 0xd5, 0x6a, 0x1d, 0x62, 0xf5, 0xa8, 0xd7, 0x55, 0x1d, - 0xb5, 0xfd, 0x93, 0x13, 0xe8, 0xc7, 0x20, 0x3d, 0x99, 0x6a, 0xf7, 0xd4, - 0x77, 0x08, 0x37, 0x56, 0xd5, 0x9a, 0xf8, 0x0d, - ], - [ - 0x05, 0xa7, 0x45, 0xf4, 0x5d, 0x7f, 0xf6, 0xdb, 0x10, 0xbc, 0x67, 0xfd, - 0xf0, 0xf0, 0x3e, 0xbf, 0x81, 0x30, 0xab, 0x33, 0x36, 0x26, 0x97, 0xb0, - 0xe4, 0xe4, 0xc7, 0x63, 0xcc, 0xb8, 0xf6, 0x36, - ], - ], - final_state: [ - [ - 0x0b, 0x77, 0xec, 0x53, 0x07, 0x14, 0x5a, 0x0c, 0x05, 0x2d, 0xc7, 0xa9, - 0xd6, 0xf9, 0x6a, 0xc3, 0x41, 0xae, 0x72, 0x64, 0x08, 0x32, 0xd5, 0x8e, - 0x51, 0xeb, 0x92, 0xa4, 0x17, 0x80, 0x17, 0x12, - ], - [ - 0x3b, 0x52, 0x3f, 0x44, 0xf0, 0x0e, 0x46, 0x3f, 0x8b, 0x0f, 0xd7, 0xd4, - 0xfc, 0x0e, 0x28, 0x0c, 0xdb, 0xde, 0xb9, 0x27, 0xf1, 0x81, 0x68, 0x07, - 0x7b, 0xb3, 0x62, 0xf2, 0x67, 0x5a, 0x2e, 0x18, - ], - [ - 0x95, 0x7a, 0x97, 0x06, 0xff, 0xcc, 0x35, 0x15, 0x64, 0xae, 0x80, 0x2a, - 0x99, 0x11, 0x31, 0x4c, 0x05, 0xe2, 0x3e, 0x22, 0xaf, 0xcf, 0x83, 0x40, - 0x59, 0xdf, 0x80, 0xfa, 0xc1, 0x05, 0x76, 0x26, - ], - ], - }, - TestVector { - initial_state: [ - [ - 0x49, 0x5c, 0x22, 0x2f, 0x7f, 0xba, 0x1e, 0x31, 0xde, 0xfa, 0x3d, 0x5a, - 0x57, 0xef, 0xc2, 0xe1, 0xe9, 0xb0, 0x1a, 0x03, 0x55, 0x87, 0xd5, 0xfb, - 0x1a, 0x38, 0xe0, 0x1d, 0x94, 0x90, 0x3d, 0x3c, - ], - [ - 0x3d, 0x0a, 0xd3, 0x36, 0x1f, 0xec, 0x09, 0x77, 0x90, 0xd9, 0xbe, 0x0e, - 0x42, 0x98, 0x8d, 0x7d, 0x25, 0xc9, 0xa1, 0x38, 0xf4, 0x9b, 0x1a, 0x53, - 0x7e, 0xdc, 0xf0, 0x4b, 0xe3, 0x4a, 0x98, 0x11, - ], - [ - 0xa4, 0xaf, 0x9d, 0xb6, 0xd2, 0x7b, 0x50, 0x72, 0x83, 0x5f, 0x0c, 0x3e, - 0x88, 0x39, 0x5e, 0xd7, 0xa4, 0x1b, 0x00, 0x52, 0xad, 0x80, 0x84, 0xa8, - 0xb9, 0xda, 0x94, 0x8d, 0x32, 0x0d, 0xad, 0x16, - ], - ], - final_state: [ - [ - 0x67, 0x80, 0x08, 0x3f, 0x7f, 0x82, 0xcb, 0x42, 0x54, 0xe7, 0xb6, 0x6f, - 0x4b, 0x83, 0x84, 0x6a, 0xc9, 0x77, 0x3f, 0xb9, 0xc3, 0x9c, 0x6e, 0xc9, - 0x81, 0x8b, 0x06, 0x22, 0x23, 0x09, 0x55, 0x2a, - ], - [ - 0xa5, 0xf9, 0xa5, 0x7e, 0x2c, 0x40, 0xb1, 0x58, 0xd8, 0x16, 0x53, 0x43, - 0xe6, 0x02, 0x65, 0x2c, 0x3e, 0xfc, 0x0b, 0x64, 0xdd, 0xca, 0xee, 0xe5, - 0xce, 0x3d, 0x95, 0x1f, 0xd5, 0x9f, 0x50, 0x08, - ], - [ - 0xdc, 0xa4, 0x64, 0x36, 0x12, 0x7c, 0x47, 0x7e, 0x83, 0x95, 0x0f, 0xa0, - 0x7c, 0xc6, 0x8a, 0x56, 0x6e, 0x54, 0x18, 0x55, 0xad, 0xc2, 0x68, 0x52, - 0x97, 0x87, 0x35, 0x24, 0x88, 0x92, 0x1e, 0x3b, - ], - ], - }, - TestVector { - initial_state: [ - [ - 0x4d, 0x54, 0x31, 0xe6, 0x43, 0x7d, 0x0b, 0x5b, 0xed, 0xbb, 0xcd, 0xaf, - 0x34, 0x5b, 0x86, 0xc4, 0x12, 0x1f, 0xc0, 0x0f, 0xe7, 0xf2, 0x35, 0x73, - 0x42, 0x76, 0xd3, 0x8d, 0x47, 0xf1, 0xe1, 0x11, - ], - [ - 0xdd, 0x0c, 0x7a, 0x1d, 0x81, 0x1c, 0x7d, 0x9c, 0xd4, 0x6d, 0x37, 0x7b, - 0x3f, 0xde, 0xab, 0x3f, 0xb6, 0x79, 0xf3, 0xdc, 0x60, 0x1d, 0x00, 0x82, - 0x85, 0xed, 0xcb, 0xda, 0xe6, 0x9c, 0xe8, 0x3c, - ], - [ - 0x19, 0xe4, 0xaa, 0xc0, 0x35, 0x90, 0x17, 0xec, 0x85, 0xa1, 0x83, 0xd2, - 0x20, 0x53, 0xdb, 0x33, 0xf7, 0x34, 0x76, 0xf2, 0x1a, 0x48, 0x2e, 0xc9, - 0x37, 0x83, 0x65, 0xc8, 0xf7, 0x39, 0x3c, 0x14, - ], - ], - final_state: [ - [ - 0x89, 0x99, 0x8e, 0x5e, 0x0f, 0xa1, 0x95, 0x2a, 0x40, 0xb8, 0xb5, 0x2b, - 0x62, 0xd9, 0x45, 0x70, 0xa4, 0x9a, 0x7d, 0x91, 0xdd, 0x22, 0x6d, 0x69, - 0x2b, 0xc9, 0xb1, 0xa6, 0x13, 0xc9, 0x08, 0x30, - ], - [ - 0xd0, 0xee, 0x44, 0xd9, 0xa9, 0x0d, 0x90, 0x79, 0xef, 0xfb, 0x24, 0x86, - 0xd3, 0xd8, 0x4d, 0x1a, 0x18, 0x4e, 0xdf, 0x14, 0x97, 0x0b, 0xac, 0x36, - 0xc7, 0x48, 0x04, 0xc7, 0xff, 0xbe, 0xe5, 0x0b, - ], - [ - 0x04, 0x81, 0x45, 0xa6, 0x61, 0xce, 0x78, 0x7c, 0x7e, 0x12, 0x2a, 0xc6, - 0x44, 0x7e, 0x9b, 0xa3, 0x93, 0xd3, 0x67, 0xac, 0x05, 0x4f, 0xaa, 0xc5, - 0xb7, 0xb5, 0xf7, 0x19, 0x2b, 0x2f, 0xde, 0x21, - ], - ], - }, - TestVector { - initial_state: [ - [ - 0xe2, 0x88, 0x53, 0x15, 0xeb, 0x46, 0x71, 0x09, 0x8b, 0x79, 0x53, 0x5e, - 0x79, 0x0f, 0xe5, 0x3e, 0x29, 0xfe, 0xf2, 0xb3, 0x76, 0x66, 0x97, 0xac, - 0x32, 0xb4, 0xf4, 0x73, 0xf4, 0x68, 0xa0, 0x08, - ], - [ - 0xe6, 0x23, 0x89, 0xfc, 0x16, 0x57, 0xe0, 0xde, 0xf0, 0xb6, 0x32, 0xc6, - 0xae, 0x25, 0xf9, 0xf7, 0x83, 0xb2, 0x7d, 0xb5, 0x9a, 0x4a, 0x15, 0x3d, - 0x88, 0x2d, 0x2b, 0x21, 0x03, 0x59, 0x65, 0x15, - ], - [ - 0xeb, 0x94, 0x94, 0xc6, 0xd2, 0x27, 0xe2, 0x16, 0x3b, 0x46, 0x99, 0xd9, - 0x91, 0xf4, 0x33, 0xbf, 0x94, 0x86, 0xa7, 0xaf, 0xcf, 0x4a, 0x0d, 0x9c, - 0x73, 0x1e, 0x98, 0x5d, 0x99, 0x58, 0x9c, 0x0b, - ], - ], - final_state: [ - [ - 0xce, 0x2d, 0x1f, 0x8d, 0x67, 0x7f, 0xfb, 0xfd, 0x73, 0xb2, 0x35, 0xe8, - 0xc6, 0x87, 0xfb, 0x42, 0x18, 0x7f, 0x78, 0x81, 0xc3, 0xce, 0x9c, 0x79, - 0x4f, 0x2b, 0xd4, 0x61, 0x40, 0xf7, 0xcc, 0x2a, - ], - [ - 0xaf, 0x82, 0x92, 0x39, 0xb6, 0xd5, 0x5d, 0x5f, 0x43, 0xec, 0x6f, 0x32, - 0xb8, 0x4a, 0x2a, 0x01, 0x1e, 0x64, 0xc5, 0x74, 0x73, 0x9f, 0x87, 0xcb, - 0x47, 0xdc, 0x70, 0x23, 0x83, 0xfa, 0x5a, 0x34, - ], - [ - 0x03, 0xd1, 0x08, 0x5b, 0x21, 0x4c, 0x69, 0xb8, 0xbf, 0xe8, 0x91, 0x02, - 0xbd, 0x61, 0x7e, 0xce, 0x0c, 0x54, 0x00, 0x17, 0x96, 0x40, 0x41, 0x05, - 0xc5, 0x33, 0x30, 0xd2, 0x49, 0x58, 0x1d, 0x0f, - ], - ], - }, - TestVector { - initial_state: [ - [ - 0xb7, 0x38, 0xe8, 0xaa, 0x0a, 0x15, 0x26, 0xa5, 0xbd, 0xef, 0x61, 0x31, - 0x20, 0x37, 0x2e, 0x83, 0x1a, 0x20, 0xda, 0x8a, 0xba, 0x18, 0xd1, 0xdb, - 0xeb, 0xbc, 0x86, 0x2d, 0xed, 0x42, 0x43, 0x1e, - ], - [ - 0x91, 0x47, 0x69, 0x30, 0xe3, 0x38, 0x5c, 0xd3, 0xe3, 0x37, 0x9e, 0x38, - 0x53, 0xd9, 0x34, 0x67, 0xe0, 0x01, 0xaf, 0xa2, 0xfb, 0x8d, 0xc3, 0x43, - 0x6d, 0x75, 0xa4, 0xa6, 0xf2, 0x65, 0x72, 0x10, - ], - [ - 0x4b, 0x19, 0x22, 0x32, 0xec, 0xb9, 0xf0, 0xc0, 0x24, 0x11, 0xe5, 0x25, - 0x96, 0xbc, 0x5e, 0x90, 0x45, 0x7e, 0x74, 0x59, 0x39, 0xff, 0xed, 0xbd, - 0x12, 0x86, 0x3c, 0xe7, 0x1a, 0x02, 0xaf, 0x11, - ], - ], - final_state: [ - [ - 0x5f, 0xcc, 0xd8, 0x7d, 0x2f, 0x66, 0x7b, 0x9e, 0xe3, 0x88, 0xf3, 0x4c, - 0x1c, 0x71, 0x06, 0x87, 0x12, 0x7b, 0xff, 0x5b, 0x02, 0x21, 0xfd, 0x8a, - 0x52, 0x94, 0x88, 0x66, 0x91, 0x57, 0x94, 0x2b, - ], - [ - 0x89, 0x62, 0xb5, 0x80, 0x30, 0xaa, 0x63, 0x52, 0xd9, 0x90, 0xf3, 0xb9, - 0x00, 0x1c, 0xcb, 0xe8, 0x8a, 0x56, 0x27, 0x58, 0x1b, 0xbf, 0xb9, 0x01, - 0xac, 0x4a, 0x6a, 0xed, 0xfa, 0xe5, 0xc6, 0x34, - ], - [ - 0x7c, 0x0b, 0x76, 0x59, 0xf2, 0x4c, 0x98, 0xaf, 0x31, 0x0e, 0x3e, 0x8d, - 0x82, 0xb5, 0xf3, 0x99, 0x43, 0x3c, 0xdd, 0xa5, 0x8f, 0x48, 0xd9, 0xef, - 0x8d, 0xd0, 0xca, 0x86, 0x42, 0x72, 0xda, 0x3f, - ], - ], - }, - TestVector { - initial_state: [ - [ - 0x7b, 0x41, 0x7a, 0xdb, 0x63, 0xb3, 0x71, 0x22, 0xa5, 0xbf, 0x62, 0xd2, - 0x6f, 0x1e, 0x7f, 0x26, 0x8f, 0xb8, 0x6b, 0x12, 0xb5, 0x6d, 0xa9, 0xc3, - 0x82, 0x85, 0x7d, 0xee, 0xcc, 0x40, 0xa9, 0x0d, - ], - [ - 0x5e, 0x29, 0x35, 0x39, 0x71, 0xb3, 0x49, 0x94, 0xb6, 0x21, 0xb0, 0xb2, - 0x61, 0xae, 0xb3, 0x78, 0x6d, 0xd9, 0x84, 0xd5, 0x67, 0xdb, 0x28, 0x57, - 0xb9, 0x27, 0xb7, 0xfa, 0xe2, 0xdb, 0x58, 0x31, - ], - [ - 0x05, 0x41, 0x5d, 0x46, 0x42, 0x78, 0x9d, 0x38, 0xf5, 0x0b, 0x8d, 0xbc, - 0xc1, 0x29, 0xca, 0xb3, 0xd1, 0x7d, 0x19, 0xf3, 0x35, 0x5b, 0xcf, 0x73, - 0xce, 0xcb, 0x8c, 0xb8, 0xa5, 0xda, 0x01, 0x30, - ], - ], - final_state: [ - [ - 0x9e, 0xe1, 0xad, 0xdc, 0x6f, 0x64, 0xda, 0xb6, 0xac, 0xdc, 0xea, 0xec, - 0xc1, 0xfb, 0xbc, 0x8a, 0x32, 0x45, 0x8e, 0x49, 0xc1, 0x9e, 0x79, 0x85, - 0x56, 0xc6, 0x4b, 0x59, 0x8b, 0xa6, 0xff, 0x14, - ], - [ - 0x42, 0xcc, 0x10, 0x36, 0x4f, 0xd6, 0x59, 0xc3, 0xcc, 0x77, 0x25, 0x84, - 0xdb, 0x91, 0xc4, 0x9a, 0x38, 0x67, 0x2b, 0x69, 0x24, 0x93, 0xb9, 0x07, - 0x5f, 0x16, 0x53, 0xca, 0x1f, 0xae, 0x1c, 0x33, - ], - [ - 0xff, 0x41, 0xf3, 0x51, 0x80, 0x14, 0x56, 0xc4, 0x96, 0x0b, 0x39, 0x3a, - 0xff, 0xa8, 0x62, 0x13, 0xa7, 0xea, 0xc0, 0x6c, 0x66, 0x21, 0x3b, 0x45, - 0xc3, 0xb5, 0x0e, 0xc6, 0x48, 0xd6, 0x7d, 0x0d, - ], - ], - }, - TestVector { - initial_state: [ - [ - 0x71, 0x52, 0xf1, 0x39, 0x36, 0xa2, 0x70, 0x57, 0x26, 0x70, 0xdc, 0x82, - 0xd3, 0x90, 0x26, 0xc6, 0xcb, 0x4c, 0xd4, 0xb0, 0xf7, 0xf5, 0xaa, 0x2a, - 0x4f, 0x5a, 0x53, 0x41, 0xec, 0x5d, 0xd7, 0x15, - ], - [ - 0x40, 0x6f, 0x2f, 0xdd, 0x2a, 0xfa, 0x73, 0x3f, 0x5f, 0x64, 0x1c, 0x8c, - 0x21, 0x86, 0x2a, 0x1b, 0xaf, 0xce, 0x26, 0x09, 0xd9, 0xee, 0xcf, 0xa1, - 0x58, 0xcf, 0xb5, 0xcd, 0x79, 0xf8, 0x80, 0x08, - ], - [ - 0xe2, 0x15, 0xdc, 0x7d, 0x96, 0x57, 0xba, 0xd3, 0xfb, 0x88, 0xb0, 0x1e, - 0x99, 0x38, 0x44, 0x54, 0x36, 0x24, 0xc2, 0x5f, 0xa9, 0x59, 0xcc, 0x97, - 0x48, 0x9c, 0xe7, 0x57, 0x45, 0x82, 0x4b, 0x37, - ], - ], - final_state: [ - [ - 0x63, 0x09, 0x15, 0xd7, 0xd8, 0x25, 0xeb, 0x74, 0x37, 0xb0, 0xe4, 0x6e, - 0x37, 0x28, 0x6a, 0x88, 0xb3, 0x89, 0xdc, 0x69, 0x85, 0x93, 0x07, 0x11, - 0x6d, 0x34, 0x7b, 0x98, 0xca, 0x14, 0x5c, 0x31, - ], - [ - 0xaa, 0x58, 0x1b, 0xae, 0xe9, 0x4f, 0xb5, 0x46, 0xa7, 0x61, 0xf1, 0x7a, - 0x5d, 0x6e, 0xaa, 0x70, 0x29, 0x52, 0x78, 0x42, 0xf3, 0x1c, 0x39, 0x87, - 0xb8, 0x68, 0xed, 0x7d, 0xaf, 0xfd, 0xb5, 0x34, - ], - [ - 0x7d, 0xc1, 0x17, 0xb3, 0x39, 0x1a, 0xab, 0x85, 0xde, 0x9f, 0x42, 0x4d, - 0xb6, 0x65, 0x1e, 0x00, 0x45, 0xab, 0x79, 0x98, 0xf2, 0x8e, 0x54, 0x10, - 0x15, 0x35, 0x90, 0x61, 0x99, 0xce, 0x1f, 0x1a, - ], - ], - }, - TestVector { - initial_state: [ - [ - 0x86, 0x8c, 0x53, 0x23, 0x9c, 0xfb, 0xdf, 0x73, 0xca, 0xec, 0x65, 0x60, - 0x40, 0x37, 0x31, 0x4f, 0xaa, 0xce, 0xb5, 0x62, 0x18, 0xc6, 0xbd, 0x30, - 0xf8, 0x37, 0x4a, 0xc1, 0x33, 0x86, 0x79, 0x3f, - ], - [ - 0x21, 0xa9, 0xfb, 0x80, 0xad, 0x03, 0xbc, 0x0c, 0xda, 0x4a, 0x44, 0x94, - 0x6c, 0x00, 0xe1, 0xb1, 0xa1, 0xdf, 0x0e, 0x5b, 0x87, 0xb5, 0xbe, 0xce, - 0x47, 0x7a, 0x70, 0x96, 0x49, 0xe9, 0x50, 0x06, - ], - [ - 0x04, 0x91, 0x39, 0x48, 0x25, 0x64, 0xf1, 0x85, 0xc7, 0x90, 0x0e, 0x83, - 0xc7, 0x38, 0x07, 0x0a, 0xf6, 0x55, 0x6d, 0xf6, 0xed, 0x4b, 0x4d, 0xdd, - 0x3d, 0x9a, 0x69, 0xf5, 0x33, 0x57, 0xd7, 0x36, - ], - ], - final_state: [ - [ - 0x6a, 0x5a, 0x19, 0x19, 0xa4, 0x49, 0xa5, 0xe0, 0x29, 0x71, 0x1f, 0x48, - 0x8a, 0xdb, 0xd6, 0xb0, 0x3e, 0x5c, 0x92, 0x7b, 0x6f, 0x9d, 0x9d, 0x35, - 0xc5, 0xb3, 0xcc, 0xeb, 0x76, 0x60, 0x52, 0x03, - ], - [ - 0x80, 0x47, 0x5b, 0x46, 0x89, 0x59, 0x61, 0x47, 0xab, 0x2a, 0xdf, 0x01, - 0x73, 0xdb, 0x28, 0x9b, 0x3a, 0x26, 0xa1, 0x04, 0x84, 0x21, 0x73, 0xe8, - 0x8b, 0xdb, 0xfe, 0xc0, 0x4a, 0x28, 0x67, 0x1b, - ], - [ - 0x1e, 0xf3, 0xc8, 0xd0, 0xf5, 0x44, 0x44, 0xf5, 0x55, 0xb1, 0x5f, 0x7b, - 0xc9, 0xfa, 0x4f, 0xfa, 0x0f, 0x56, 0x7c, 0x0f, 0x19, 0xac, 0x7d, 0x0f, - 0xf9, 0x44, 0xfd, 0x36, 0x42, 0x6e, 0x32, 0x3a, - ], - ], - }, - TestVector { - initial_state: [ - [ - 0x7d, 0x4f, 0x5c, 0xcb, 0x01, 0x64, 0x3c, 0x31, 0xdb, 0x84, 0x5e, 0xec, - 0xd5, 0xd6, 0x3d, 0xc1, 0x6a, 0x95, 0xe3, 0x02, 0x5b, 0x97, 0x92, 0xff, - 0xf7, 0xf2, 0x44, 0xfc, 0x71, 0x62, 0x69, 0x39, - ], - [ - 0x26, 0xd6, 0x2e, 0x95, 0x96, 0xfa, 0x82, 0x5c, 0x6b, 0xf2, 0x1a, 0xff, - 0x9e, 0x68, 0x62, 0x5a, 0x19, 0x24, 0x40, 0xea, 0x06, 0x82, 0x81, 0x23, - 0xd9, 0x78, 0x84, 0x80, 0x6f, 0x15, 0xfa, 0x08, - ], - [ - 0xd9, 0x52, 0x75, 0x4a, 0x23, 0x64, 0xb6, 0x66, 0xff, 0xc3, 0x0f, 0xdb, - 0x01, 0x47, 0x86, 0xda, 0x3a, 0x61, 0x28, 0xae, 0xf7, 0x84, 0xa6, 0x46, - 0x10, 0xa8, 0x9d, 0x1a, 0x70, 0x99, 0x21, 0x2d, - ], - ], - final_state: [ - [ - 0x1b, 0x4a, 0xc9, 0xbe, 0xf5, 0x6b, 0xdb, 0x6f, 0xb4, 0x2d, 0x3e, 0x3c, - 0xd3, 0xa2, 0xac, 0x70, 0xa4, 0xc4, 0x0c, 0x42, 0x5b, 0x0b, 0xd6, 0x67, - 0x9c, 0xa5, 0x7b, 0x30, 0x7e, 0xf1, 0xd4, 0x2f, - ], - [ - 0x1a, 0x2e, 0xf4, 0x11, 0x94, 0xaa, 0xa2, 0x34, 0x32, 0xe0, 0x86, 0xed, - 0x8a, 0xdb, 0xd1, 0xde, 0xec, 0x3c, 0x7c, 0xb3, 0x96, 0xde, 0x35, 0xba, - 0xe9, 0x5a, 0xaf, 0x5a, 0x08, 0xa0, 0xec, 0x36, - ], - [ - 0x68, 0xeb, 0x80, 0xc7, 0x3e, 0x2c, 0xcb, 0xde, 0xe1, 0xba, 0x71, 0x24, - 0x77, 0x61, 0xd5, 0xb5, 0xec, 0xc6, 0x20, 0xe6, 0xe4, 0x8e, 0x00, 0x3b, - 0x02, 0x3d, 0x9f, 0x55, 0x61, 0x66, 0x2f, 0x20, - ], - ], - }, - ] - } - - pub(crate) fn hash() -> Vec { - use HashTestVector as TestVector; - - // From https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/orchard_poseidon/hash/fp.py - vec![ - TestVector { - input: [ - [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ], - [ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ], - ], - output: [ - 0x83, 0x58, 0xd7, 0x11, 0xa0, 0x32, 0x9d, 0x38, 0xbe, 0xcd, 0x54, 0xfb, 0xa7, - 0xc2, 0x83, 0xed, 0x3e, 0x08, 0x9a, 0x39, 0xc9, 0x1b, 0x6a, 0x9d, 0x10, 0xef, - 0xb0, 0x2b, 0xc3, 0xf1, 0x2f, 0x06, - ], - }, - TestVector { - input: [ - [ - 0x5c, 0x7a, 0x8f, 0x73, 0xad, 0xfc, 0x70, 0xfb, 0x3f, 0x13, 0x94, 0x49, - 0xac, 0x6b, 0x57, 0x07, 0x4c, 0x4d, 0x6e, 0x66, 0xb1, 0x64, 0x93, 0x9d, - 0xaf, 0xfa, 0x2e, 0xf6, 0xee, 0x69, 0x21, 0x08, - ], - [ - 0x1a, 0xdd, 0x86, 0xb3, 0xf2, 0xe1, 0xbd, 0xa6, 0x2a, 0x5d, 0x2e, 0x0e, - 0x98, 0x2b, 0x77, 0xe6, 0xb0, 0xef, 0x9c, 0xa3, 0xf2, 0x49, 0x88, 0xc7, - 0xb3, 0x53, 0x42, 0x01, 0xcf, 0xb1, 0xcd, 0x0d, - ], - ], - output: [ - 0xdb, 0x26, 0x75, 0xff, 0x3e, 0xf8, 0xfe, 0x30, 0xc4, 0xd5, 0xde, 0x61, 0xca, - 0xc0, 0x2a, 0x8e, 0xf1, 0xa0, 0x85, 0x23, 0xbe, 0x92, 0x39, 0x4b, 0x79, 0xd2, - 0x67, 0x26, 0x30, 0x3b, 0xe6, 0x03, - ], - }, - TestVector { - input: [ - [ - 0xbd, 0x69, 0xb8, 0x25, 0x32, 0xb6, 0x94, 0x0f, 0xf2, 0x59, 0x0f, 0x67, - 0x9b, 0xa9, 0xc7, 0x27, 0x1f, 0xe0, 0x1f, 0x7e, 0x9c, 0x8e, 0x36, 0xd6, - 0xa5, 0xe2, 0x9d, 0x4e, 0x30, 0xa7, 0x35, 0x14, - ], - [ - 0xbc, 0x50, 0x98, 0x42, 0x55, 0xd6, 0xaf, 0xbe, 0x9e, 0xf9, 0x28, 0x48, - 0xed, 0x5a, 0xc0, 0x08, 0x62, 0xc2, 0xfa, 0x7b, 0x2f, 0xec, 0xbc, 0xb6, - 0x4b, 0x69, 0x68, 0x91, 0x2a, 0x63, 0x81, 0x0e, - ], - ], - output: [ - 0xf5, 0x12, 0x1d, 0x1e, 0x1d, 0x5c, 0xfe, 0x8d, 0xa8, 0x96, 0xac, 0x0f, 0x9c, - 0x18, 0x3d, 0x76, 0x00, 0x31, 0xf6, 0xef, 0x8c, 0x7a, 0x41, 0xe6, 0x5e, 0xb0, - 0x07, 0xcd, 0xdc, 0x1d, 0x14, 0x3d, - ], - }, - TestVector { - input: [ - [ - 0x3d, 0xc1, 0x66, 0xd5, 0x6a, 0x1d, 0x62, 0xf5, 0xa8, 0xd7, 0x55, 0x1d, - 0xb5, 0xfd, 0x93, 0x13, 0xe8, 0xc7, 0x20, 0x3d, 0x99, 0x6a, 0xf7, 0xd4, - 0x77, 0x08, 0x37, 0x56, 0xd5, 0x9a, 0xf8, 0x0d, - ], - [ - 0x05, 0xa7, 0x45, 0xf4, 0x5d, 0x7f, 0xf6, 0xdb, 0x10, 0xbc, 0x67, 0xfd, - 0xf0, 0xf0, 0x3e, 0xbf, 0x81, 0x30, 0xab, 0x33, 0x36, 0x26, 0x97, 0xb0, - 0xe4, 0xe4, 0xc7, 0x63, 0xcc, 0xb8, 0xf6, 0x36, - ], - ], - output: [ - 0xa4, 0x16, 0xa5, 0xe7, 0x13, 0x51, 0x36, 0xa0, 0x50, 0x56, 0x90, 0x00, 0x58, - 0xfa, 0x50, 0xbf, 0x18, 0x6a, 0xd7, 0x33, 0x90, 0xac, 0xe6, 0x32, 0x3d, 0x8d, - 0x81, 0xaa, 0x8a, 0xdb, 0xd4, 0x11, - ], - }, - TestVector { - input: [ - [ - 0x49, 0x5c, 0x22, 0x2f, 0x7f, 0xba, 0x1e, 0x31, 0xde, 0xfa, 0x3d, 0x5a, - 0x57, 0xef, 0xc2, 0xe1, 0xe9, 0xb0, 0x1a, 0x03, 0x55, 0x87, 0xd5, 0xfb, - 0x1a, 0x38, 0xe0, 0x1d, 0x94, 0x90, 0x3d, 0x3c, - ], - [ - 0x3d, 0x0a, 0xd3, 0x36, 0x1f, 0xec, 0x09, 0x77, 0x90, 0xd9, 0xbe, 0x0e, - 0x42, 0x98, 0x8d, 0x7d, 0x25, 0xc9, 0xa1, 0x38, 0xf4, 0x9b, 0x1a, 0x53, - 0x7e, 0xdc, 0xf0, 0x4b, 0xe3, 0x4a, 0x98, 0x11, - ], - ], - output: [ - 0x1a, 0xba, 0xf3, 0x06, 0xfe, 0xd0, 0x5f, 0xa8, 0x92, 0x84, 0x8c, 0x49, 0xf6, - 0xba, 0x10, 0x41, 0x63, 0x43, 0x3f, 0x3f, 0x63, 0x31, 0x08, 0xa1, 0x3b, 0xc1, - 0x5b, 0x2a, 0x1d, 0x55, 0xd4, 0x0c, - ], - }, - TestVector { - input: [ - [ - 0xa4, 0xaf, 0x9d, 0xb6, 0xd2, 0x7b, 0x50, 0x72, 0x83, 0x5f, 0x0c, 0x3e, - 0x88, 0x39, 0x5e, 0xd7, 0xa4, 0x1b, 0x00, 0x52, 0xad, 0x80, 0x84, 0xa8, - 0xb9, 0xda, 0x94, 0x8d, 0x32, 0x0d, 0xad, 0x16, - ], - [ - 0x4d, 0x54, 0x31, 0xe6, 0x43, 0x7d, 0x0b, 0x5b, 0xed, 0xbb, 0xcd, 0xaf, - 0x34, 0x5b, 0x86, 0xc4, 0x12, 0x1f, 0xc0, 0x0f, 0xe7, 0xf2, 0x35, 0x73, - 0x42, 0x76, 0xd3, 0x8d, 0x47, 0xf1, 0xe1, 0x11, - ], - ], - output: [ - 0x04, 0xa1, 0x8a, 0xeb, 0x59, 0x3f, 0x79, 0x0b, 0x76, 0xa3, 0x99, 0xb7, 0xc1, - 0x52, 0x8a, 0xcd, 0xed, 0xe9, 0x3b, 0x3b, 0x2c, 0x49, 0x6b, 0xd7, 0x1b, 0xd5, - 0x87, 0xcb, 0xd7, 0xcf, 0xdf, 0x35, - ], - }, - TestVector { - input: [ - [ - 0xdd, 0x0c, 0x7a, 0x1d, 0x81, 0x1c, 0x7d, 0x9c, 0xd4, 0x6d, 0x37, 0x7b, - 0x3f, 0xde, 0xab, 0x3f, 0xb6, 0x79, 0xf3, 0xdc, 0x60, 0x1d, 0x00, 0x82, - 0x85, 0xed, 0xcb, 0xda, 0xe6, 0x9c, 0xe8, 0x3c, - ], - [ - 0x19, 0xe4, 0xaa, 0xc0, 0x35, 0x90, 0x17, 0xec, 0x85, 0xa1, 0x83, 0xd2, - 0x20, 0x53, 0xdb, 0x33, 0xf7, 0x34, 0x76, 0xf2, 0x1a, 0x48, 0x2e, 0xc9, - 0x37, 0x83, 0x65, 0xc8, 0xf7, 0x39, 0x3c, 0x14, - ], - ], - output: [ - 0x11, 0x03, 0xcc, 0xdc, 0x00, 0xd0, 0xf3, 0x5f, 0x65, 0x83, 0x14, 0x11, 0x6b, - 0xc2, 0xbc, 0xd9, 0x43, 0x74, 0xa9, 0x1f, 0xf9, 0x87, 0x7e, 0x70, 0x66, 0x33, - 0x29, 0x04, 0x2b, 0xd2, 0xf6, 0x1f, - ], - }, - TestVector { - input: [ - [ - 0xe2, 0x88, 0x53, 0x15, 0xeb, 0x46, 0x71, 0x09, 0x8b, 0x79, 0x53, 0x5e, - 0x79, 0x0f, 0xe5, 0x3e, 0x29, 0xfe, 0xf2, 0xb3, 0x76, 0x66, 0x97, 0xac, - 0x32, 0xb4, 0xf4, 0x73, 0xf4, 0x68, 0xa0, 0x08, - ], - [ - 0xe6, 0x23, 0x89, 0xfc, 0x16, 0x57, 0xe0, 0xde, 0xf0, 0xb6, 0x32, 0xc6, - 0xae, 0x25, 0xf9, 0xf7, 0x83, 0xb2, 0x7d, 0xb5, 0x9a, 0x4a, 0x15, 0x3d, - 0x88, 0x2d, 0x2b, 0x21, 0x03, 0x59, 0x65, 0x15, - ], - ], - output: [ - 0xf8, 0xf8, 0xc6, 0x5f, 0x43, 0x7c, 0x45, 0xbe, 0xac, 0x11, 0xeb, 0x7d, 0x9e, - 0x47, 0x58, 0x6d, 0x87, 0x9a, 0xfd, 0x6f, 0x93, 0x04, 0x35, 0xbe, 0x0c, 0x01, - 0xd1, 0x9c, 0x89, 0x5b, 0x8d, 0x10, - ], - }, - TestVector { - input: [ - [ - 0xeb, 0x94, 0x94, 0xc6, 0xd2, 0x27, 0xe2, 0x16, 0x3b, 0x46, 0x99, 0xd9, - 0x91, 0xf4, 0x33, 0xbf, 0x94, 0x86, 0xa7, 0xaf, 0xcf, 0x4a, 0x0d, 0x9c, - 0x73, 0x1e, 0x98, 0x5d, 0x99, 0x58, 0x9c, 0x0b, - ], - [ - 0xb7, 0x38, 0xe8, 0xaa, 0x0a, 0x15, 0x26, 0xa5, 0xbd, 0xef, 0x61, 0x31, - 0x20, 0x37, 0x2e, 0x83, 0x1a, 0x20, 0xda, 0x8a, 0xba, 0x18, 0xd1, 0xdb, - 0xeb, 0xbc, 0x86, 0x2d, 0xed, 0x42, 0x43, 0x1e, - ], - ], - output: [ - 0x5a, 0xeb, 0x48, 0x96, 0x21, 0xb0, 0x2e, 0x8e, 0x69, 0x27, 0xb9, 0x4f, 0xd2, - 0x9a, 0x61, 0x01, 0x83, 0xdf, 0x7f, 0x42, 0x87, 0xe9, 0xcb, 0xf1, 0xcc, 0xc8, - 0x81, 0xd7, 0xd0, 0xb7, 0x38, 0x27, - ], - }, - TestVector { - input: [ - [ - 0x91, 0x47, 0x69, 0x30, 0xe3, 0x38, 0x5c, 0xd3, 0xe3, 0x37, 0x9e, 0x38, - 0x53, 0xd9, 0x34, 0x67, 0xe0, 0x01, 0xaf, 0xa2, 0xfb, 0x8d, 0xc3, 0x43, - 0x6d, 0x75, 0xa4, 0xa6, 0xf2, 0x65, 0x72, 0x10, - ], - [ - 0x4b, 0x19, 0x22, 0x32, 0xec, 0xb9, 0xf0, 0xc0, 0x24, 0x11, 0xe5, 0x25, - 0x96, 0xbc, 0x5e, 0x90, 0x45, 0x7e, 0x74, 0x59, 0x39, 0xff, 0xed, 0xbd, - 0x12, 0x86, 0x3c, 0xe7, 0x1a, 0x02, 0xaf, 0x11, - ], - ], - output: [ - 0xb0, 0x14, 0x47, 0x20, 0xf5, 0xf2, 0xa2, 0x5d, 0x49, 0x2a, 0x50, 0x4e, 0xc0, - 0x73, 0x7f, 0x09, 0x7e, 0xd8, 0x52, 0x17, 0x4f, 0x55, 0xf5, 0x86, 0x30, 0x91, - 0x30, 0x6c, 0x1a, 0xf2, 0x00, 0x35, - ], - }, - TestVector { - input: [ - [ - 0x7b, 0x41, 0x7a, 0xdb, 0x63, 0xb3, 0x71, 0x22, 0xa5, 0xbf, 0x62, 0xd2, - 0x6f, 0x1e, 0x7f, 0x26, 0x8f, 0xb8, 0x6b, 0x12, 0xb5, 0x6d, 0xa9, 0xc3, - 0x82, 0x85, 0x7d, 0xee, 0xcc, 0x40, 0xa9, 0x0d, - ], - [ - 0x5e, 0x29, 0x35, 0x39, 0x71, 0xb3, 0x49, 0x94, 0xb6, 0x21, 0xb0, 0xb2, - 0x61, 0xae, 0xb3, 0x78, 0x6d, 0xd9, 0x84, 0xd5, 0x67, 0xdb, 0x28, 0x57, - 0xb9, 0x27, 0xb7, 0xfa, 0xe2, 0xdb, 0x58, 0x31, - ], - ], - output: [ - 0xbb, 0xbe, 0xb7, 0x42, 0xd6, 0xe7, 0xc0, 0x1a, 0xdb, 0xf4, 0xd3, 0x85, 0x5e, - 0x35, 0xfe, 0xc4, 0x62, 0x04, 0x30, 0x89, 0xc1, 0x8b, 0xa8, 0x02, 0x90, 0x64, - 0x7b, 0xb0, 0xe5, 0x81, 0xad, 0x11, - ], - }, - ] - } -} - -pub(crate) mod fq { - use super::*; - - pub(crate) fn permute() -> Vec { - use PermuteTestVector as TestVector; - - // From https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/orchard_poseidon/permute/fq.py - vec![ - TestVector { - initial_state: [ - [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ], - [ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ], - [ - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ], - ], - final_state: [ - [ - 0x59, 0xbe, 0xbe, 0x13, 0xa8, 0x8e, 0xb0, 0x0e, 0xc6, 0x36, 0xd3, 0x3d, - 0x97, 0xd1, 0x43, 0x4d, 0xf7, 0x2f, 0x8f, 0x2f, 0xf2, 0x74, 0xdd, 0xed, - 0x7c, 0x2f, 0x94, 0xdb, 0x4c, 0x1f, 0x5a, 0x31, - ], - [ - 0xf1, 0x65, 0xa1, 0x1e, 0xe6, 0x26, 0xf1, 0xf9, 0x98, 0x21, 0xbd, 0x7b, - 0xeb, 0xe0, 0x3e, 0x41, 0x48, 0xaa, 0x13, 0xdd, 0xe0, 0xde, 0x2a, 0x64, - 0xde, 0x2b, 0x64, 0xd7, 0xf2, 0x75, 0xe4, 0x3b, - ], - [ - 0xd9, 0xa0, 0x7b, 0x2a, 0x37, 0x42, 0xd5, 0x14, 0xa0, 0x3f, 0x42, 0xe0, - 0xd4, 0xbf, 0x19, 0x50, 0x60, 0xea, 0xd8, 0x20, 0x24, 0xdb, 0x7f, 0x11, - 0x68, 0x71, 0x53, 0xe9, 0xec, 0x8a, 0xab, 0x25, - ], - ], - }, - TestVector { - initial_state: [ - [ - 0x5c, 0x7a, 0x8f, 0x73, 0x79, 0x42, 0x57, 0x08, 0x7e, 0x63, 0x4c, 0x49, - 0xac, 0x6b, 0x57, 0x07, 0x4c, 0x4d, 0x6e, 0x66, 0xb1, 0x64, 0x93, 0x9d, - 0xaf, 0xfa, 0x2e, 0xf6, 0xee, 0x69, 0x21, 0x08, - ], - [ - 0x1a, 0xdd, 0x86, 0xb3, 0x8a, 0x6d, 0x8a, 0xc0, 0xa6, 0xfd, 0x9e, 0x0d, - 0x98, 0x2b, 0x77, 0xe6, 0xb0, 0xef, 0x9c, 0xa3, 0xf2, 0x49, 0x88, 0xc7, - 0xb3, 0x53, 0x42, 0x01, 0xcf, 0xb1, 0xcd, 0x0d, - ], - [ - 0xbd, 0x69, 0xb8, 0x25, 0xca, 0x41, 0x61, 0x29, 0x6e, 0xfa, 0x7f, 0x66, - 0x9b, 0xa9, 0xc7, 0x27, 0x1f, 0xe0, 0x1f, 0x7e, 0x9c, 0x8e, 0x36, 0xd6, - 0xa5, 0xe2, 0x9d, 0x4e, 0x30, 0xa7, 0x35, 0x14, - ], - ], - final_state: [ - [ - 0xcd, 0x8f, 0x83, 0x92, 0xdf, 0xc7, 0x72, 0x8f, 0x5f, 0x6d, 0x85, 0x4c, - 0xc4, 0x60, 0x70, 0xa4, 0x0c, 0xba, 0x7a, 0x80, 0x33, 0x2d, 0xdc, 0x65, - 0xcb, 0xe2, 0x4a, 0xc3, 0xde, 0x23, 0x5e, 0x0e, - ], - [ - 0xc2, 0x53, 0xe5, 0x95, 0x3c, 0x83, 0xaa, 0x8a, 0x23, 0xd4, 0xd5, 0x58, - 0x7f, 0xbf, 0xc0, 0x7e, 0x78, 0x33, 0x1f, 0x7d, 0x46, 0xd1, 0xf5, 0xfa, - 0x54, 0x4d, 0x6a, 0xbd, 0xd4, 0x24, 0x1b, 0x27, - ], - [ - 0xb8, 0xc8, 0x33, 0x9b, 0xf9, 0x47, 0x2a, 0xd1, 0xc5, 0x27, 0xb7, 0x5e, - 0x99, 0x81, 0x2c, 0xa9, 0x1c, 0x5c, 0xbd, 0x7f, 0x4d, 0x46, 0x6f, 0x1a, - 0x13, 0x5a, 0x67, 0x50, 0x66, 0x76, 0x64, 0x34, - ], - ], - }, - TestVector { - initial_state: [ - [ - 0xbc, 0x50, 0x98, 0x42, 0xb9, 0xa7, 0x62, 0xe5, 0x58, 0xea, 0x51, 0x47, - 0xed, 0x5a, 0xc0, 0x08, 0x62, 0xc2, 0xfa, 0x7b, 0x2f, 0xec, 0xbc, 0xb6, - 0x4b, 0x69, 0x68, 0x91, 0x2a, 0x63, 0x81, 0x0e, - ], - [ - 0x3d, 0xc1, 0x66, 0xd5, 0x6a, 0x1d, 0x62, 0xf5, 0xa8, 0xd7, 0x55, 0x1d, - 0xb5, 0xfd, 0x93, 0x13, 0xe8, 0xc7, 0x20, 0x3d, 0x99, 0x6a, 0xf7, 0xd4, - 0x77, 0x08, 0x37, 0x56, 0xd5, 0x9a, 0xf8, 0x0d, - ], - [ - 0x05, 0xa7, 0x45, 0xf4, 0x29, 0xc5, 0xdc, 0xe8, 0x4e, 0x0c, 0x20, 0xfd, - 0xf0, 0xf0, 0x3e, 0xbf, 0x81, 0x30, 0xab, 0x33, 0x36, 0x26, 0x97, 0xb0, - 0xe4, 0xe4, 0xc7, 0x63, 0xcc, 0xb8, 0xf6, 0x36, - ], - ], - final_state: [ - [ - 0xa3, 0x5b, 0x56, 0x64, 0x62, 0x4a, 0x78, 0x49, 0x9e, 0xce, 0xe0, 0xfa, - 0x05, 0x18, 0x79, 0xa2, 0xad, 0x1c, 0xa4, 0x53, 0x9b, 0x5b, 0xd2, 0xa4, - 0x67, 0xe2, 0xea, 0x8d, 0x4e, 0x2d, 0x40, 0x08, - ], - [ - 0x36, 0xc2, 0x21, 0x7a, 0xe5, 0x75, 0xaa, 0xf8, 0xf2, 0x54, 0xd6, 0xe0, - 0x60, 0x10, 0x1c, 0xdc, 0x85, 0xaa, 0x39, 0x3c, 0x09, 0x54, 0x3b, 0xf0, - 0x48, 0x99, 0x7a, 0x7c, 0x5c, 0xb9, 0x27, 0x02, - ], - [ - 0x38, 0x12, 0x7e, 0xbe, 0xaf, 0x11, 0xae, 0x56, 0x64, 0x47, 0x14, 0x05, - 0x29, 0x3b, 0x60, 0x1c, 0x43, 0xf0, 0x3e, 0x8e, 0x40, 0x78, 0x11, 0x3a, - 0x63, 0x37, 0x10, 0x11, 0x9f, 0x9a, 0x1b, 0x1f, - ], - ], - }, - TestVector { - initial_state: [ - [ - 0x49, 0x5c, 0x22, 0x2f, 0x7f, 0xba, 0x1e, 0x31, 0xde, 0xfa, 0x3d, 0x5a, - 0x57, 0xef, 0xc2, 0xe1, 0xe9, 0xb0, 0x1a, 0x03, 0x55, 0x87, 0xd5, 0xfb, - 0x1a, 0x38, 0xe0, 0x1d, 0x94, 0x90, 0x3d, 0x3c, - ], - [ - 0x3d, 0x0a, 0xd3, 0x36, 0xeb, 0x31, 0xf0, 0x83, 0xce, 0x29, 0x77, 0x0e, - 0x42, 0x98, 0x8d, 0x7d, 0x25, 0xc9, 0xa1, 0x38, 0xf4, 0x9b, 0x1a, 0x53, - 0x7e, 0xdc, 0xf0, 0x4b, 0xe3, 0x4a, 0x98, 0x11, - ], - [ - 0xa4, 0xaf, 0x9d, 0xb6, 0x36, 0x4d, 0x03, 0x99, 0x3d, 0x50, 0x35, 0x3d, - 0x88, 0x39, 0x5e, 0xd7, 0xa4, 0x1b, 0x00, 0x52, 0xad, 0x80, 0x84, 0xa8, - 0xb9, 0xda, 0x94, 0x8d, 0x32, 0x0d, 0xad, 0x16, - ], - ], - final_state: [ - [ - 0x5c, 0x76, 0x63, 0x4f, 0xc7, 0x1a, 0x43, 0x7a, 0x3c, 0xc7, 0x89, 0x9d, - 0xb3, 0xb5, 0x1c, 0xea, 0xe6, 0x9a, 0xd0, 0x0b, 0x14, 0x96, 0xa6, 0x80, - 0x32, 0xd3, 0x83, 0x17, 0x37, 0x08, 0x79, 0x18, - ], - [ - 0xd3, 0xcc, 0x4e, 0xab, 0x45, 0x0a, 0xac, 0xc4, 0x5f, 0x9b, 0x32, 0x7e, - 0xbb, 0x9a, 0x50, 0xb8, 0x59, 0xca, 0x08, 0x0e, 0x10, 0x6b, 0x54, 0xc3, - 0x1c, 0x09, 0xc2, 0x1e, 0x1d, 0x79, 0xdf, 0x2a, - ], - [ - 0x09, 0x1e, 0x8f, 0x1e, 0xe9, 0xba, 0x00, 0xa3, 0xe3, 0xcf, 0x85, 0xd5, - 0xd6, 0x95, 0x3d, 0x25, 0xe0, 0x1e, 0x8b, 0xdb, 0x43, 0xde, 0x0f, 0xb7, - 0x30, 0x82, 0x4e, 0x6a, 0x8f, 0x69, 0x7e, 0x1c, - ], - ], - }, - TestVector { - initial_state: [ - [ - 0x4d, 0x54, 0x31, 0xe6, 0xdb, 0x08, 0xd8, 0x74, 0x69, 0x5c, 0x3e, 0xaf, - 0x34, 0x5b, 0x86, 0xc4, 0x12, 0x1f, 0xc0, 0x0f, 0xe7, 0xf2, 0x35, 0x73, - 0x42, 0x76, 0xd3, 0x8d, 0x47, 0xf1, 0xe1, 0x11, - ], - [ - 0xdd, 0x0c, 0x7a, 0x1d, 0xe5, 0xed, 0x2f, 0xc3, 0x8e, 0x5e, 0x60, 0x7a, - 0x3f, 0xde, 0xab, 0x3f, 0xb6, 0x79, 0xf3, 0xdc, 0x60, 0x1d, 0x00, 0x82, - 0x85, 0xed, 0xcb, 0xda, 0xe6, 0x9c, 0xe8, 0x3c, - ], - [ - 0x19, 0xe4, 0xaa, 0xc0, 0xcd, 0x1b, 0xe4, 0x05, 0x02, 0x42, 0xf4, 0xd1, - 0x20, 0x53, 0xdb, 0x33, 0xf7, 0x34, 0x76, 0xf2, 0x1a, 0x48, 0x2e, 0xc9, - 0x37, 0x83, 0x65, 0xc8, 0xf7, 0x39, 0x3c, 0x14, - ], - ], - final_state: [ - [ - 0x00, 0xff, 0x3c, 0x20, 0xd5, 0xac, 0x28, 0x33, 0xe6, 0xd3, 0x84, 0x27, - 0xd0, 0x44, 0x06, 0x17, 0x9e, 0x31, 0xf3, 0xde, 0xd0, 0xe0, 0x33, 0xab, - 0x4f, 0x51, 0xfc, 0xb4, 0x28, 0xf8, 0x39, 0x1b, - ], - [ - 0x2a, 0x63, 0x7a, 0xa0, 0x4f, 0xb8, 0x0d, 0x9c, 0x50, 0xf3, 0x16, 0xb6, - 0x36, 0x7f, 0xa4, 0xf6, 0xed, 0x52, 0xd0, 0x7c, 0x99, 0xa1, 0x30, 0x29, - 0xd9, 0x3f, 0xae, 0xd3, 0xdd, 0x1e, 0xbc, 0x2f, - ], - [ - 0x12, 0x31, 0x54, 0xbb, 0x87, 0x60, 0x13, 0x94, 0x5f, 0x54, 0x69, 0x34, - 0x9d, 0x5f, 0xc3, 0xfc, 0xfc, 0xc9, 0xd2, 0xda, 0xb8, 0x06, 0x43, 0x0d, - 0x49, 0x69, 0x46, 0xf3, 0xbf, 0x2b, 0x61, 0x11, - ], - ], - }, - TestVector { - initial_state: [ - [ - 0xe2, 0x88, 0x53, 0x15, 0xeb, 0x46, 0x71, 0x09, 0x8b, 0x79, 0x53, 0x5e, - 0x79, 0x0f, 0xe5, 0x3e, 0x29, 0xfe, 0xf2, 0xb3, 0x76, 0x66, 0x97, 0xac, - 0x32, 0xb4, 0xf4, 0x73, 0xf4, 0x68, 0xa0, 0x08, - ], - [ - 0xe6, 0x23, 0x89, 0xfc, 0xe2, 0x9c, 0xc6, 0xeb, 0x2e, 0x07, 0xeb, 0xc5, - 0xae, 0x25, 0xf9, 0xf7, 0x83, 0xb2, 0x7d, 0xb5, 0x9a, 0x4a, 0x15, 0x3d, - 0x88, 0x2d, 0x2b, 0x21, 0x03, 0x59, 0x65, 0x15, - ], - [ - 0xeb, 0x94, 0x94, 0xc6, 0x6a, 0xb3, 0xae, 0x30, 0xb7, 0xe6, 0x09, 0xd9, - 0x91, 0xf4, 0x33, 0xbf, 0x94, 0x86, 0xa7, 0xaf, 0xcf, 0x4a, 0x0d, 0x9c, - 0x73, 0x1e, 0x98, 0x5d, 0x99, 0x58, 0x9c, 0x0b, - ], - ], - final_state: [ - [ - 0xe7, 0x1e, 0xb4, 0x88, 0x51, 0xd7, 0x73, 0xb5, 0xa3, 0xb5, 0xd2, 0xb6, - 0xf6, 0xeb, 0x01, 0xc3, 0x79, 0x3f, 0x2f, 0xeb, 0xdf, 0xd1, 0xb9, 0x53, - 0xf0, 0x6f, 0xa9, 0x59, 0xc7, 0x26, 0xbc, 0x18, - ], - [ - 0x37, 0x71, 0xf8, 0x29, 0xfb, 0xf2, 0x74, 0x87, 0xf1, 0xdf, 0x2b, 0x5e, - 0xe9, 0x94, 0x97, 0x0b, 0x14, 0xd7, 0x13, 0xce, 0xae, 0x73, 0xa6, 0x33, - 0x95, 0x78, 0x4d, 0xcd, 0xf9, 0xaa, 0x30, 0x30, - ], - [ - 0x48, 0x06, 0xaf, 0xf7, 0x5e, 0xd3, 0xc6, 0xb9, 0x72, 0x1b, 0xc5, 0x23, - 0x0d, 0xd7, 0x76, 0xf9, 0x27, 0x44, 0x62, 0x90, 0x97, 0xcf, 0x5c, 0x2b, - 0x7f, 0x14, 0x2c, 0xf2, 0x74, 0xa5, 0x07, 0x37, - ], - ], - }, - TestVector { - initial_state: [ - [ - 0xb7, 0x38, 0xe8, 0xaa, 0xd6, 0x5a, 0x0c, 0xb2, 0xfb, 0x3f, 0x1a, 0x31, - 0x20, 0x37, 0x2e, 0x83, 0x1a, 0x20, 0xda, 0x8a, 0xba, 0x18, 0xd1, 0xdb, - 0xeb, 0xbc, 0x86, 0x2d, 0xed, 0x42, 0x43, 0x1e, - ], - [ - 0x91, 0x47, 0x69, 0x30, 0xaf, 0x7e, 0x42, 0xe0, 0x21, 0x88, 0x56, 0x38, - 0x53, 0xd9, 0x34, 0x67, 0xe0, 0x01, 0xaf, 0xa2, 0xfb, 0x8d, 0xc3, 0x43, - 0x6d, 0x75, 0xa4, 0xa6, 0xf2, 0x65, 0x72, 0x10, - ], - [ - 0x4b, 0x19, 0x22, 0x32, 0xec, 0xb9, 0xf0, 0xc0, 0x24, 0x11, 0xe5, 0x25, - 0x96, 0xbc, 0x5e, 0x90, 0x45, 0x7e, 0x74, 0x59, 0x39, 0xff, 0xed, 0xbd, - 0x12, 0x86, 0x3c, 0xe7, 0x1a, 0x02, 0xaf, 0x11, - ], - ], - final_state: [ - [ - 0x9d, 0x58, 0x16, 0x08, 0x94, 0x8a, 0xd0, 0x15, 0xf5, 0x38, 0x82, 0xc0, - 0x2d, 0x22, 0x40, 0x2f, 0x71, 0xbd, 0x52, 0x7a, 0xb6, 0xb0, 0xbd, 0xab, - 0x5e, 0xaf, 0xef, 0x0c, 0xd9, 0x41, 0xe8, 0x33, - ], - [ - 0xf4, 0x69, 0xd9, 0x80, 0x6d, 0x0b, 0x9d, 0x92, 0x46, 0x6b, 0xbd, 0xe4, - 0x90, 0x4b, 0x88, 0x2d, 0x29, 0xcc, 0x45, 0x6d, 0xef, 0xa4, 0x77, 0x3f, - 0x5d, 0x9a, 0x92, 0x79, 0x6c, 0x60, 0xed, 0x1d, - ], - [ - 0x3c, 0xf1, 0xa7, 0x38, 0x35, 0xf9, 0x42, 0x5d, 0x46, 0x87, 0xa0, 0x9b, - 0xea, 0xcf, 0x48, 0x9a, 0xa6, 0x0e, 0xcb, 0xfc, 0xae, 0xa0, 0x61, 0xc9, - 0x7e, 0xd3, 0x72, 0x86, 0x1c, 0x08, 0x0a, 0x3d, - ], - ], - }, - TestVector { - initial_state: [ - [ - 0x7b, 0x41, 0x7a, 0xdb, 0xfb, 0x3e, 0x3e, 0x3c, 0x21, 0x60, 0xd3, 0xd1, - 0x6f, 0x1e, 0x7f, 0x26, 0x8f, 0xb8, 0x6b, 0x12, 0xb5, 0x6d, 0xa9, 0xc3, - 0x82, 0x85, 0x7d, 0xee, 0xcc, 0x40, 0xa9, 0x0d, - ], - [ - 0x5e, 0x29, 0x35, 0x39, 0x3d, 0xf9, 0x2f, 0xa1, 0xf4, 0x71, 0x68, 0xb2, - 0x61, 0xae, 0xb3, 0x78, 0x6d, 0xd9, 0x84, 0xd5, 0x67, 0xdb, 0x28, 0x57, - 0xb9, 0x27, 0xb7, 0xfa, 0xe2, 0xdb, 0x58, 0x31, - ], - [ - 0x05, 0x41, 0x5d, 0x46, 0x42, 0x78, 0x9d, 0x38, 0xf5, 0x0b, 0x8d, 0xbc, - 0xc1, 0x29, 0xca, 0xb3, 0xd1, 0x7d, 0x19, 0xf3, 0x35, 0x5b, 0xcf, 0x73, - 0xce, 0xcb, 0x8c, 0xb8, 0xa5, 0xda, 0x01, 0x30, - ], - ], - final_state: [ - [ - 0x73, 0x2c, 0x01, 0x83, 0x41, 0x7f, 0xdf, 0x33, 0x43, 0xc1, 0xef, 0x69, - 0xfd, 0xf6, 0xb3, 0xe7, 0xfd, 0x52, 0x9e, 0xe8, 0x44, 0x63, 0x48, 0xf2, - 0x78, 0x50, 0x74, 0xaf, 0xe2, 0x97, 0xe5, 0x39, - ], - [ - 0xc0, 0x33, 0xd0, 0x1c, 0xb2, 0x29, 0x7f, 0x14, 0xdc, 0xcf, 0x8a, 0x37, - 0xc8, 0x90, 0x02, 0x09, 0x46, 0x5c, 0xc7, 0x41, 0x24, 0x50, 0xe0, 0xb0, - 0x82, 0x84, 0xf9, 0xaa, 0xa1, 0x18, 0xde, 0x34, - ], - [ - 0x17, 0xf9, 0xa6, 0x65, 0x38, 0x93, 0xea, 0x76, 0xbe, 0x60, 0x00, 0x20, - 0xb8, 0xff, 0xbf, 0xd9, 0x53, 0xae, 0x4a, 0x94, 0xad, 0x00, 0x10, 0x43, - 0x37, 0xb9, 0xf7, 0xde, 0x69, 0x88, 0x60, 0x31, - ], - ], - }, - TestVector { - initial_state: [ - [ - 0x71, 0x52, 0xf1, 0x39, 0x36, 0xa2, 0x70, 0x57, 0x26, 0x70, 0xdc, 0x82, - 0xd3, 0x90, 0x26, 0xc6, 0xcb, 0x4c, 0xd4, 0xb0, 0xf7, 0xf5, 0xaa, 0x2a, - 0x4f, 0x5a, 0x53, 0x41, 0xec, 0x5d, 0xd7, 0x15, - ], - [ - 0x40, 0x6f, 0x2f, 0xdd, 0x2a, 0xfa, 0x73, 0x3f, 0x5f, 0x64, 0x1c, 0x8c, - 0x21, 0x86, 0x2a, 0x1b, 0xaf, 0xce, 0x26, 0x09, 0xd9, 0xee, 0xcf, 0xa1, - 0x58, 0xcf, 0xb5, 0xcd, 0x79, 0xf8, 0x80, 0x08, - ], - [ - 0xe2, 0x15, 0xdc, 0x7d, 0x62, 0x9d, 0xa0, 0xe0, 0x39, 0xd9, 0x68, 0x1e, - 0x99, 0x38, 0x44, 0x54, 0x36, 0x24, 0xc2, 0x5f, 0xa9, 0x59, 0xcc, 0x97, - 0x48, 0x9c, 0xe7, 0x57, 0x45, 0x82, 0x4b, 0x37, - ], - ], - final_state: [ - [ - 0x16, 0x0a, 0x24, 0x98, 0x48, 0x62, 0xea, 0xe0, 0xa3, 0x33, 0x50, 0x7b, - 0x36, 0x11, 0x93, 0x13, 0x71, 0xc6, 0x1d, 0x8e, 0x65, 0x71, 0x38, 0xcf, - 0xb2, 0xfa, 0x3b, 0x0f, 0x4d, 0xe5, 0xed, 0x3b, - ], - [ - 0xc5, 0xbd, 0x5a, 0x00, 0x44, 0xb6, 0xdb, 0xfe, 0x88, 0xb6, 0x97, 0xf7, - 0x1e, 0xa0, 0x55, 0xb4, 0xe2, 0x32, 0x42, 0x66, 0x6b, 0xf4, 0xe1, 0xb0, - 0x27, 0x52, 0xee, 0xce, 0x08, 0xfb, 0xe8, 0x05, - ], - [ - 0x30, 0x34, 0xdc, 0x8e, 0x8d, 0x4f, 0x6e, 0x33, 0x53, 0x83, 0xb9, 0x01, - 0x35, 0x8a, 0xe4, 0xb7, 0x5f, 0xcc, 0xc7, 0x22, 0x69, 0xdb, 0x83, 0x37, - 0x89, 0xce, 0xd4, 0xc0, 0xad, 0x83, 0x25, 0x1e, - ], - ], - }, - TestVector { - initial_state: [ - [ - 0x86, 0x8c, 0x53, 0x23, 0x9c, 0xfb, 0xdf, 0x73, 0xca, 0xec, 0x65, 0x60, - 0x40, 0x37, 0x31, 0x4f, 0xaa, 0xce, 0xb5, 0x62, 0x18, 0xc6, 0xbd, 0x30, - 0xf8, 0x37, 0x4a, 0xc1, 0x33, 0x86, 0x79, 0x3f, - ], - [ - 0x21, 0xa9, 0xfb, 0x80, 0xad, 0x03, 0xbc, 0x0c, 0xda, 0x4a, 0x44, 0x94, - 0x6c, 0x00, 0xe1, 0xb1, 0xa1, 0xdf, 0x0e, 0x5b, 0x87, 0xb5, 0xbe, 0xce, - 0x47, 0x7a, 0x70, 0x96, 0x49, 0xe9, 0x50, 0x06, - ], - [ - 0x04, 0x91, 0x39, 0x48, 0xf1, 0xa9, 0xd7, 0x92, 0x05, 0xe1, 0xc6, 0x82, - 0xc7, 0x38, 0x07, 0x0a, 0xf6, 0x55, 0x6d, 0xf6, 0xed, 0x4b, 0x4d, 0xdd, - 0x3d, 0x9a, 0x69, 0xf5, 0x33, 0x57, 0xd7, 0x36, - ], - ], - final_state: [ - [ - 0x63, 0xe6, 0x3f, 0x14, 0xcc, 0x49, 0xec, 0x8f, 0x59, 0x93, 0x33, 0xae, - 0x04, 0x2c, 0xb4, 0x0c, 0x6f, 0xa8, 0x5f, 0x2d, 0x67, 0x64, 0xde, 0xad, - 0x13, 0x16, 0x44, 0x04, 0x97, 0x8b, 0x12, 0x03, - ], - [ - 0xc5, 0x61, 0xf3, 0x87, 0xb4, 0xaa, 0x32, 0x60, 0x09, 0x0f, 0x01, 0x73, - 0x88, 0x01, 0xb5, 0x34, 0xbe, 0x39, 0x6a, 0x13, 0xee, 0x11, 0x6b, 0x21, - 0xdb, 0x76, 0x10, 0x69, 0x59, 0x3d, 0xb6, 0x2f, - ], - [ - 0x10, 0x1a, 0x4b, 0xfd, 0x56, 0x89, 0xd5, 0x5a, 0xa7, 0x0e, 0xcf, 0x44, - 0x6d, 0xc3, 0x1a, 0x89, 0xbc, 0x62, 0xde, 0xb7, 0xed, 0x36, 0xf5, 0x49, - 0x19, 0x9c, 0xe1, 0x7b, 0xac, 0xe7, 0x32, 0x1b, - ], - ], - }, - TestVector { - initial_state: [ - [ - 0x7d, 0x4f, 0x5c, 0xcb, 0x99, 0xef, 0x08, 0x4b, 0x57, 0x25, 0xcf, 0xeb, - 0xd5, 0xd6, 0x3d, 0xc1, 0x6a, 0x95, 0xe3, 0x02, 0x5b, 0x97, 0x92, 0xff, - 0xf7, 0xf2, 0x44, 0xfc, 0x71, 0x62, 0x69, 0x39, - ], - [ - 0x26, 0xd6, 0x2e, 0x95, 0x96, 0xfa, 0x82, 0x5c, 0x6b, 0xf2, 0x1a, 0xff, - 0x9e, 0x68, 0x62, 0x5a, 0x19, 0x24, 0x40, 0xea, 0x06, 0x82, 0x81, 0x23, - 0xd9, 0x78, 0x84, 0x80, 0x6f, 0x15, 0xfa, 0x08, - ], - [ - 0xd9, 0x52, 0x75, 0x4a, 0xef, 0xa9, 0x9c, 0x73, 0x3d, 0x14, 0xc8, 0xda, - 0x01, 0x47, 0x86, 0xda, 0x3a, 0x61, 0x28, 0xae, 0xf7, 0x84, 0xa6, 0x46, - 0x10, 0xa8, 0x9d, 0x1a, 0x70, 0x99, 0x21, 0x2d, - ], - ], - final_state: [ - [ - 0x45, 0xed, 0x54, 0x17, 0x40, 0x7b, 0xfd, 0xb7, 0x97, 0xbc, 0xfe, 0x70, - 0x74, 0xdf, 0xf8, 0x0e, 0x32, 0xa5, 0x62, 0xed, 0x88, 0x73, 0x78, 0x1d, - 0xbc, 0xf4, 0xf6, 0x7e, 0x06, 0xbe, 0x0c, 0x23, - ], - [ - 0x13, 0x2f, 0x3f, 0x55, 0xd8, 0xfb, 0xfd, 0x46, 0x7b, 0x2a, 0xe2, 0x2b, - 0x8c, 0x64, 0x93, 0x43, 0x64, 0xcf, 0x9c, 0x4a, 0x0b, 0x07, 0xed, 0xb4, - 0x02, 0x87, 0xc3, 0x92, 0xc9, 0xc1, 0x45, 0x12, - ], - [ - 0xd0, 0x51, 0xc3, 0x7f, 0xf6, 0x4c, 0xad, 0xa2, 0xb4, 0x82, 0xf1, 0x1f, - 0x85, 0x64, 0x39, 0x6b, 0x75, 0xe3, 0xf8, 0x1b, 0x35, 0x52, 0xd8, 0x9a, - 0xf4, 0x92, 0xcf, 0x00, 0x52, 0x3c, 0x04, 0x15, - ], - ], - }, - ] - } - - pub(crate) fn hash() -> Vec { - use HashTestVector as TestVector; - - // From https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/orchard_poseidon/hash/fq.py - vec![ - TestVector { - input: [ - [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ], - [ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ], - ], - output: [ - 0x4e, 0x68, 0xf6, 0x85, 0x70, 0x29, 0x57, 0xf3, 0xbf, 0x54, 0x6b, 0x7a, 0x09, - 0x01, 0x31, 0x4e, 0x51, 0x4f, 0x19, 0x5e, 0xe3, 0xb1, 0x64, 0x46, 0x22, 0x77, - 0x9d, 0x93, 0xdf, 0x96, 0xba, 0x15, - ], - }, - TestVector { - input: [ - [ - 0x5c, 0x7a, 0x8f, 0x73, 0x79, 0x42, 0x57, 0x08, 0x7e, 0x63, 0x4c, 0x49, - 0xac, 0x6b, 0x57, 0x07, 0x4c, 0x4d, 0x6e, 0x66, 0xb1, 0x64, 0x93, 0x9d, - 0xaf, 0xfa, 0x2e, 0xf6, 0xee, 0x69, 0x21, 0x08, - ], - [ - 0x1a, 0xdd, 0x86, 0xb3, 0x8a, 0x6d, 0x8a, 0xc0, 0xa6, 0xfd, 0x9e, 0x0d, - 0x98, 0x2b, 0x77, 0xe6, 0xb0, 0xef, 0x9c, 0xa3, 0xf2, 0x49, 0x88, 0xc7, - 0xb3, 0x53, 0x42, 0x01, 0xcf, 0xb1, 0xcd, 0x0d, - ], - ], - output: [ - 0x0c, 0x0a, 0xd9, 0x0a, 0x2e, 0x0c, 0xba, 0x0e, 0xe6, 0xa5, 0x5a, 0xc5, 0x38, - 0xa4, 0x35, 0xc9, 0x39, 0x04, 0x98, 0xae, 0xb5, 0x30, 0x3e, 0x3d, 0xad, 0x70, - 0x3a, 0xd1, 0xdc, 0xdb, 0x43, 0x2b, - ], - }, - TestVector { - input: [ - [ - 0xbd, 0x69, 0xb8, 0x25, 0xca, 0x41, 0x61, 0x29, 0x6e, 0xfa, 0x7f, 0x66, - 0x9b, 0xa9, 0xc7, 0x27, 0x1f, 0xe0, 0x1f, 0x7e, 0x9c, 0x8e, 0x36, 0xd6, - 0xa5, 0xe2, 0x9d, 0x4e, 0x30, 0xa7, 0x35, 0x14, - ], - [ - 0xbc, 0x50, 0x98, 0x42, 0xb9, 0xa7, 0x62, 0xe5, 0x58, 0xea, 0x51, 0x47, - 0xed, 0x5a, 0xc0, 0x08, 0x62, 0xc2, 0xfa, 0x7b, 0x2f, 0xec, 0xbc, 0xb6, - 0x4b, 0x69, 0x68, 0x91, 0x2a, 0x63, 0x81, 0x0e, - ], - ], - output: [ - 0xa6, 0x0c, 0xc8, 0xb8, 0x53, 0xaf, 0xce, 0xdb, 0xa1, 0x44, 0x65, 0xd5, 0x31, - 0xc7, 0x3c, 0xbc, 0xe1, 0x9e, 0x46, 0x0b, 0xa8, 0x04, 0x62, 0x2d, 0xf5, 0x21, - 0x23, 0x1d, 0xa1, 0x21, 0xc6, 0x08, - ], - }, - TestVector { - input: [ - [ - 0x3d, 0xc1, 0x66, 0xd5, 0x6a, 0x1d, 0x62, 0xf5, 0xa8, 0xd7, 0x55, 0x1d, - 0xb5, 0xfd, 0x93, 0x13, 0xe8, 0xc7, 0x20, 0x3d, 0x99, 0x6a, 0xf7, 0xd4, - 0x77, 0x08, 0x37, 0x56, 0xd5, 0x9a, 0xf8, 0x0d, - ], - [ - 0x05, 0xa7, 0x45, 0xf4, 0x29, 0xc5, 0xdc, 0xe8, 0x4e, 0x0c, 0x20, 0xfd, - 0xf0, 0xf0, 0x3e, 0xbf, 0x81, 0x30, 0xab, 0x33, 0x36, 0x26, 0x97, 0xb0, - 0xe4, 0xe4, 0xc7, 0x63, 0xcc, 0xb8, 0xf6, 0x36, - ], - ], - output: [ - 0xad, 0xa8, 0xca, 0xe4, 0x6a, 0x04, 0x2d, 0x00, 0xb0, 0x2e, 0x33, 0xc3, 0x6e, - 0x65, 0x8c, 0x22, 0x13, 0xfe, 0x81, 0x34, 0x53, 0x8b, 0x56, 0x03, 0x19, 0xe9, - 0x99, 0xf3, 0xf5, 0x82, 0x90, 0x00, - ], - }, - TestVector { - input: [ - [ - 0x49, 0x5c, 0x22, 0x2f, 0x7f, 0xba, 0x1e, 0x31, 0xde, 0xfa, 0x3d, 0x5a, - 0x57, 0xef, 0xc2, 0xe1, 0xe9, 0xb0, 0x1a, 0x03, 0x55, 0x87, 0xd5, 0xfb, - 0x1a, 0x38, 0xe0, 0x1d, 0x94, 0x90, 0x3d, 0x3c, - ], - [ - 0x3d, 0x0a, 0xd3, 0x36, 0xeb, 0x31, 0xf0, 0x83, 0xce, 0x29, 0x77, 0x0e, - 0x42, 0x98, 0x8d, 0x7d, 0x25, 0xc9, 0xa1, 0x38, 0xf4, 0x9b, 0x1a, 0x53, - 0x7e, 0xdc, 0xf0, 0x4b, 0xe3, 0x4a, 0x98, 0x11, - ], - ], - output: [ - 0x19, 0x94, 0x9f, 0xc7, 0x74, 0x04, 0x99, 0x37, 0x00, 0x58, 0x12, 0x7d, 0x04, - 0x0f, 0x11, 0x24, 0x5e, 0xba, 0x6c, 0x37, 0x80, 0xe9, 0x3e, 0x26, 0x16, 0xf4, - 0xc1, 0x77, 0x56, 0x30, 0x78, 0x2d, - ], - }, - TestVector { - input: [ - [ - 0xa4, 0xaf, 0x9d, 0xb6, 0x36, 0x4d, 0x03, 0x99, 0x3d, 0x50, 0x35, 0x3d, - 0x88, 0x39, 0x5e, 0xd7, 0xa4, 0x1b, 0x00, 0x52, 0xad, 0x80, 0x84, 0xa8, - 0xb9, 0xda, 0x94, 0x8d, 0x32, 0x0d, 0xad, 0x16, - ], - [ - 0x4d, 0x54, 0x31, 0xe6, 0xdb, 0x08, 0xd8, 0x74, 0x69, 0x5c, 0x3e, 0xaf, - 0x34, 0x5b, 0x86, 0xc4, 0x12, 0x1f, 0xc0, 0x0f, 0xe7, 0xf2, 0x35, 0x73, - 0x42, 0x76, 0xd3, 0x8d, 0x47, 0xf1, 0xe1, 0x11, - ], - ], - output: [ - 0x29, 0x6e, 0xba, 0xb4, 0xb4, 0x5a, 0xb9, 0x20, 0x97, 0xa7, 0xe6, 0xe7, 0xcc, - 0x6d, 0xd7, 0xd4, 0x7a, 0x12, 0x3e, 0x85, 0x50, 0xa3, 0x3d, 0xf1, 0x20, 0xcc, - 0xa5, 0x38, 0x90, 0x67, 0x1b, 0x21, - ], - }, - TestVector { - input: [ - [ - 0xdd, 0x0c, 0x7a, 0x1d, 0xe5, 0xed, 0x2f, 0xc3, 0x8e, 0x5e, 0x60, 0x7a, - 0x3f, 0xde, 0xab, 0x3f, 0xb6, 0x79, 0xf3, 0xdc, 0x60, 0x1d, 0x00, 0x82, - 0x85, 0xed, 0xcb, 0xda, 0xe6, 0x9c, 0xe8, 0x3c, - ], - [ - 0x19, 0xe4, 0xaa, 0xc0, 0xcd, 0x1b, 0xe4, 0x05, 0x02, 0x42, 0xf4, 0xd1, - 0x20, 0x53, 0xdb, 0x33, 0xf7, 0x34, 0x76, 0xf2, 0x1a, 0x48, 0x2e, 0xc9, - 0x37, 0x83, 0x65, 0xc8, 0xf7, 0x39, 0x3c, 0x14, - ], - ], - output: [ - 0xa8, 0x87, 0x6e, 0x8d, 0x2f, 0x30, 0x0a, 0x62, 0x05, 0x4b, 0x49, 0x4c, 0x8f, - 0x21, 0xc1, 0xd0, 0xad, 0xbd, 0xac, 0x89, 0xbf, 0x2a, 0xad, 0x9f, 0x3c, 0x1b, - 0x10, 0xc4, 0x78, 0x8c, 0x2d, 0x3d, - ], - }, - TestVector { - input: [ - [ - 0xe2, 0x88, 0x53, 0x15, 0xeb, 0x46, 0x71, 0x09, 0x8b, 0x79, 0x53, 0x5e, - 0x79, 0x0f, 0xe5, 0x3e, 0x29, 0xfe, 0xf2, 0xb3, 0x76, 0x66, 0x97, 0xac, - 0x32, 0xb4, 0xf4, 0x73, 0xf4, 0x68, 0xa0, 0x08, - ], - [ - 0xe6, 0x23, 0x89, 0xfc, 0xe2, 0x9c, 0xc6, 0xeb, 0x2e, 0x07, 0xeb, 0xc5, - 0xae, 0x25, 0xf9, 0xf7, 0x83, 0xb2, 0x7d, 0xb5, 0x9a, 0x4a, 0x15, 0x3d, - 0x88, 0x2d, 0x2b, 0x21, 0x03, 0x59, 0x65, 0x15, - ], - ], - output: [ - 0xc2, 0xda, 0xcb, 0x1e, 0xea, 0xed, 0x88, 0x0b, 0x87, 0xd0, 0x4d, 0xd9, 0x61, - 0x95, 0x73, 0x0e, 0x98, 0xbd, 0x0f, 0x14, 0x77, 0x7b, 0x3e, 0xf0, 0xda, 0x40, - 0xe4, 0xc0, 0x87, 0xb1, 0x9d, 0x28, - ], - }, - TestVector { - input: [ - [ - 0xeb, 0x94, 0x94, 0xc6, 0x6a, 0xb3, 0xae, 0x30, 0xb7, 0xe6, 0x09, 0xd9, - 0x91, 0xf4, 0x33, 0xbf, 0x94, 0x86, 0xa7, 0xaf, 0xcf, 0x4a, 0x0d, 0x9c, - 0x73, 0x1e, 0x98, 0x5d, 0x99, 0x58, 0x9c, 0x0b, - ], - [ - 0xb7, 0x38, 0xe8, 0xaa, 0xd6, 0x5a, 0x0c, 0xb2, 0xfb, 0x3f, 0x1a, 0x31, - 0x20, 0x37, 0x2e, 0x83, 0x1a, 0x20, 0xda, 0x8a, 0xba, 0x18, 0xd1, 0xdb, - 0xeb, 0xbc, 0x86, 0x2d, 0xed, 0x42, 0x43, 0x1e, - ], - ], - output: [ - 0x5a, 0x55, 0xe3, 0x08, 0x2e, 0x55, 0xa5, 0x66, 0xb9, 0xca, 0xb1, 0xca, 0xf4, - 0x48, 0xf7, 0x0f, 0x8c, 0x9a, 0x53, 0xa1, 0xc9, 0xf6, 0x9e, 0x2a, 0x80, 0xdd, - 0xb8, 0x58, 0x3f, 0x99, 0x01, 0x26, - ], - }, - TestVector { - input: [ - [ - 0x91, 0x47, 0x69, 0x30, 0xaf, 0x7e, 0x42, 0xe0, 0x21, 0x88, 0x56, 0x38, - 0x53, 0xd9, 0x34, 0x67, 0xe0, 0x01, 0xaf, 0xa2, 0xfb, 0x8d, 0xc3, 0x43, - 0x6d, 0x75, 0xa4, 0xa6, 0xf2, 0x65, 0x72, 0x10, - ], - [ - 0x4b, 0x19, 0x22, 0x32, 0xec, 0xb9, 0xf0, 0xc0, 0x24, 0x11, 0xe5, 0x25, - 0x96, 0xbc, 0x5e, 0x90, 0x45, 0x7e, 0x74, 0x59, 0x39, 0xff, 0xed, 0xbd, - 0x12, 0x86, 0x3c, 0xe7, 0x1a, 0x02, 0xaf, 0x11, - ], - ], - output: [ - 0xca, 0xc6, 0x68, 0x8a, 0x3d, 0x2a, 0x7d, 0xca, 0xe1, 0xd4, 0x60, 0x1f, 0x9b, - 0xf0, 0x6d, 0x58, 0x00, 0x8f, 0x24, 0x85, 0x6a, 0xe6, 0x00, 0xf0, 0xe0, 0x90, - 0x07, 0x23, 0xaf, 0xa1, 0x20, 0x03, - ], - }, - TestVector { - input: [ - [ - 0x7b, 0x41, 0x7a, 0xdb, 0xfb, 0x3e, 0x3e, 0x3c, 0x21, 0x60, 0xd3, 0xd1, - 0x6f, 0x1e, 0x7f, 0x26, 0x8f, 0xb8, 0x6b, 0x12, 0xb5, 0x6d, 0xa9, 0xc3, - 0x82, 0x85, 0x7d, 0xee, 0xcc, 0x40, 0xa9, 0x0d, - ], - [ - 0x5e, 0x29, 0x35, 0x39, 0x3d, 0xf9, 0x2f, 0xa1, 0xf4, 0x71, 0x68, 0xb2, - 0x61, 0xae, 0xb3, 0x78, 0x6d, 0xd9, 0x84, 0xd5, 0x67, 0xdb, 0x28, 0x57, - 0xb9, 0x27, 0xb7, 0xfa, 0xe2, 0xdb, 0x58, 0x31, - ], - ], - output: [ - 0xd7, 0xe7, 0x83, 0x91, 0x97, 0x83, 0xb0, 0x8b, 0x5f, 0xad, 0x08, 0x9d, 0x57, - 0x1e, 0xc1, 0x8f, 0xb4, 0x63, 0x28, 0x53, 0x99, 0x3f, 0x35, 0xe3, 0xee, 0x54, - 0x3d, 0x4e, 0xed, 0xf6, 0x5f, 0x38, - ], - }, - ] - } -} From de2be28e08a1ffd1d4759279506aac5add35883c Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Mon, 6 Jan 2025 09:28:42 +0000 Subject: [PATCH 07/35] fix: lint error --- plonkish_backend/src/util/expression.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plonkish_backend/src/util/expression.rs b/plonkish_backend/src/util/expression.rs index ff727eb7..c4e51789 100644 --- a/plonkish_backend/src/util/expression.rs +++ b/plonkish_backend/src/util/expression.rs @@ -118,7 +118,7 @@ impl Expression { ) }; match self { - Expression::Constant(scalar) => constant(scalar.clone()), + Expression::Constant(scalar) => constant(scalar.clone()), Expression::CommonPolynomial(poly) => common_poly(*poly), Expression::Polynomial(query) => poly(*query), Expression::Challenge(index) => challenge(*index), From 52dca76062c13068d6af9f1aeaeb9a3f6a327843 Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Mon, 6 Jan 2025 11:41:23 +0000 Subject: [PATCH 08/35] fix: lint error --- plonkish_backend/src/frontend/halo2.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plonkish_backend/src/frontend/halo2.rs b/plonkish_backend/src/frontend/halo2.rs index 371febbb..f3a93dae 100644 --- a/plonkish_backend/src/frontend/halo2.rs +++ b/plonkish_backend/src/frontend/halo2.rs @@ -707,7 +707,7 @@ fn phase_offsets(phases: &[u8]) -> Vec { .collect() } -//convert from an expression defined in halo2 to an expression defined in backend +//convert from an expression defined in halo2 to an expression defined in backend fn convert_expression( cs: &ConstraintSystem, advice_idx: &[usize], From 4ae29bd7f5f42979007816b27d8761648908fb68 Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Mon, 6 Jan 2025 11:46:13 +0000 Subject: [PATCH 09/35] fix: lint errors --- plonkish_backend/src/frontend/halo2.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/plonkish_backend/src/frontend/halo2.rs b/plonkish_backend/src/frontend/halo2.rs index f3a93dae..73040db8 100644 --- a/plonkish_backend/src/frontend/halo2.rs +++ b/plonkish_backend/src/frontend/halo2.rs @@ -60,7 +60,7 @@ pub struct Halo2Circuit> { impl> Halo2Circuit { // Generate a new Halo2Circuit from a circuit of type C that implements CircuitExt trait, which extends the Circuit trait from halo2 pub fn new(k: usize, circuit: C) -> Self { - // Obtain constraint system cs and config from circuit + // Obtain constraint system cs and config from circuit let (cs, config) = { let mut cs = ConstraintSystem::default(); let config = C::configure(&mut cs); @@ -106,7 +106,7 @@ impl> AsRef for Halo2Circuit { } } -// Implement PlonkishCircuit trait from backend for Halo2Circuit struct +// Implement PlonkishCircuit trait from backend for Halo2Circuit struct impl> PlonkishCircuit for Halo2Circuit { // Get PlonkishCircuitInfo from a Halo2 Circuit without preprocessing, i.e. setting fixed/ selector columns or copy constraints. fn circuit_info_without_preprocess(&self) -> Result, crate::Error> { @@ -119,7 +119,7 @@ impl> PlonkishCircuit for Halo2Circuit { } = self; // Generate indices of advice columns so that they are ordered by phase let advice_idx = advice_idx(cs); - // Convert expressions from halo2 to backend + // Convert expressions from halo2 to backend let constraints = cs .gates() .iter() @@ -129,7 +129,7 @@ impl> PlonkishCircuit for Halo2Circuit { }) }) .collect(); - // Convert lookup expressions from halo2 to backend + // Convert lookup expressions from halo2 to backend let lookups = cs .lookups() .iter() @@ -149,12 +149,12 @@ impl> PlonkishCircuit for Halo2Circuit { .collect(); let num_instances = instances.iter().map(Vec::len).collect_vec(); - // Set preprocess_polys, initialized to 0, with 2^k rows. + // Set preprocess_polys, initialized to 0, with 2^k rows. let preprocess_polys = vec![vec![F::ZERO; 1 << k]; cs.num_selectors() + cs.num_fixed_columns()]; - //Obtain indices of columns from the contraint system + //Obtain indices of columns from the contraint system let column_idx = column_idx(cs); - // Initialize permutations defining copy constraints + // Initialize permutations defining copy constraints let permutations = cs .permutation() .get_columns() @@ -178,7 +178,7 @@ impl> PlonkishCircuit for Halo2Circuit { }) } - // Get PlonkishCircuitInfo from a Halo2 Circuit with preprocessing, i.e. setting fixed/ selector columns or copy constraints. + // Get PlonkishCircuitInfo from a Halo2 Circuit with preprocessing, i.e. setting fixed/ selector columns or copy constraints. fn circuit_info(&self) -> Result, crate::Error> { let Self { k, @@ -193,9 +193,9 @@ impl> PlonkishCircuit for Halo2Circuit { let mut circuit_info = self.circuit_info_without_preprocess()?; let num_instances = instances.iter().map(Vec::len).collect_vec(); - //Obtain indices of columns from the contraint system + //Obtain indices of columns from the contraint system let column_idx = column_idx(cs); - // Obtain initial permutations from constraint system, for now no copy constraints are set + // Obtain initial permutations from constraint system, for now no copy constraints are set let permutation_column_idx = cs .permutation() .get_columns() @@ -256,7 +256,7 @@ impl> PlonkishCircuit for Halo2Circuit { advice_idx_in_phase: &self.advice_idx_in_phase, challenge_idx: &self.challenge_idx, instances: instances.as_slice(), - // all advice columns are initialized to zero, there are 2^k rows and self.num_witness_polys[phase] columns + // all advice columns are initialized to zero, there are 2^k rows and self.num_witness_polys[phase] columns advices: vec![vec![F::ZERO.into(); 1 << self.k]; self.num_witness_polys[phase]], challenges, row_mapping: &self.row_mapping, @@ -411,7 +411,7 @@ impl<'a, F: Field> Assignment for PreprocessCollector<'a, F> { Ok(()) } - // Challenges are created later + // Challenges are created later fn get_challenge(&self, _: Challenge) -> Value { Value::unknown() } From 3ed3925498d517913df2813fe84e1c92e0aa00d9 Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Mon, 6 Jan 2025 11:49:24 +0000 Subject: [PATCH 10/35] fix: lint errors --- plonkish_backend/src/frontend/halo2.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/plonkish_backend/src/frontend/halo2.rs b/plonkish_backend/src/frontend/halo2.rs index 73040db8..9d6dcacc 100644 --- a/plonkish_backend/src/frontend/halo2.rs +++ b/plonkish_backend/src/frontend/halo2.rs @@ -27,7 +27,6 @@ pub mod circuit; #[cfg(test)] mod test; - pub trait CircuitExt: Circuit { fn rand(_k: usize, _rng: impl RngCore) -> Self where @@ -56,7 +55,6 @@ pub struct Halo2Circuit> { row_mapping: Vec, } - impl> Halo2Circuit { // Generate a new Halo2Circuit from a circuit of type C that implements CircuitExt trait, which extends the Circuit trait from halo2 pub fn new(k: usize, circuit: C) -> Self { @@ -108,7 +106,7 @@ impl> AsRef for Halo2Circuit { // Implement PlonkishCircuit trait from backend for Halo2Circuit struct impl> PlonkishCircuit for Halo2Circuit { - // Get PlonkishCircuitInfo from a Halo2 Circuit without preprocessing, i.e. setting fixed/ selector columns or copy constraints. + // Get PlonkishCircuitInfo from a Halo2 Circuit without preprocessing, i.e. setting fixed/ selector columns or copy constraints. fn circuit_info_without_preprocess(&self) -> Result, crate::Error> { let Self { k, @@ -246,7 +244,6 @@ impl> PlonkishCircuit for Halo2Circuit { &self.instances } - // Synthesize a circuit for a particular phase with an instance and witness of the circuit, and challenges fn synthesize(&self, phase: usize, challenges: &[F]) -> Result>, crate::Error> { let instances = self.instances.iter().map(Vec::as_slice).collect_vec(); @@ -632,7 +629,6 @@ impl<'a, F: Field> Assignment for WitnessCollector<'a, F> { fn pop_namespace(&mut self, _: Option) {} } - // Output index of each advice column in the matrix such that columns are ordered by phase (with all advice columms at the end of the matrix) fn advice_idx(cs: &ConstraintSystem) -> Vec { // Order cs.advice_column_phase() such that cs.advice_column_phase()[i] <= cs.advice_column_phase()[i+1] and add the new index to the advice_offset (total number of columns - num advice columns) for each element. From 2fa3680318b75d765c1acd5f94303459d6081f24 Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Mon, 6 Jan 2025 11:51:19 +0000 Subject: [PATCH 11/35] fix: lint errors --- plonkish_backend/src/frontend/halo2.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plonkish_backend/src/frontend/halo2.rs b/plonkish_backend/src/frontend/halo2.rs index 9d6dcacc..4f5f3a42 100644 --- a/plonkish_backend/src/frontend/halo2.rs +++ b/plonkish_backend/src/frontend/halo2.rs @@ -233,7 +233,7 @@ impl> PlonkishCircuit for Halo2Circuit { }), ] .collect(); - // Obtain the copy constraints from the preprocess collector + // Obtain the copy constraints from the preprocess collector circuit_info.permutations = preprocess_collector.permutation.into_cycles(); Ok(circuit_info) From 8a72d56fdc458e3206f04d066deec1a026aeedb7 Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Mon, 6 Jan 2025 12:44:14 +0000 Subject: [PATCH 12/35] fix: lint errors --- plonkish_backend/src/backend/hyperplonk.rs | 10 +++++----- .../src/backend/hyperplonk/preprocessor.rs | 18 +++++++++--------- .../src/backend/hyperplonk/prover.rs | 4 ++-- .../src/backend/hyperplonk/verifier.rs | 4 ++-- .../circuits/poseidongadget/poseidon/pow5.rs | 16 ++++++++-------- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/plonkish_backend/src/backend/hyperplonk.rs b/plonkish_backend/src/backend/hyperplonk.rs index 48c8296a..7b274c1f 100644 --- a/plonkish_backend/src/backend/hyperplonk.rs +++ b/plonkish_backend/src/backend/hyperplonk.rs @@ -135,7 +135,7 @@ where let mut witness_polys = Vec::with_capacity(pp.num_witness_polys.iter().sum()); let mut witness_comms = Vec::with_capacity(witness_polys.len()); let mut challenges = Vec::with_capacity(pp.num_challenges.iter().sum::() + 4); - // For each round, generate multi-linear polynomials from witness columns and commit + // For each round, generate multi-linear polynomials from witness columns and commit for (round, (num_witness_polys, num_challenges)) in pp .num_witness_polys .iter() @@ -162,7 +162,7 @@ where // beta is used to compress the polynomials in the lookup argument let beta = transcript.squeeze_challenge(); - // Generate a compressed multilinear polynomial for each lookup in the vector of lookups + // Generate a compressed multilinear polynomial for each lookup in the vector of lookups let timer = start_timer(|| format!("lookup_compressed_polys-{}", pp.lookups.len())); let lookup_compressed_polys = { let max_lookup_width = pp.lookups.iter().map(Vec::len).max().unwrap_or_default(); @@ -218,7 +218,7 @@ where ] .collect_vec(); challenges.extend([beta, gamma, alpha]); - // Prove the zero check is satisfied for the expression wrt the polynomials + // Prove the zero check is satisfied for the expression wrt the polynomials let (points, evals) = prove_zero_check( pp.num_instances.len(), &pp.expression, @@ -241,7 +241,7 @@ where ] .collect_vec(); let timer = start_timer(|| format!("pcs_batch_open-{}", evals.len())); - // Open all polynomials at the points from the zero check and give the opening proofs + // Open all polynomials at the points from the zero check and give the opening proofs Pcs::batch_open(&pp.pcs, polys, comms, &points, &evals, transcript)?; end_timer(timer); // Proof is saved in transcript @@ -298,7 +298,7 @@ where let y = transcript.squeeze_challenges(vp.num_vars); challenges.extend([beta, gamma, alpha]); - // Verify the zero check for the constraints defined in the expression + // Verify the zero check for the constraints defined in the expression let (points, evals) = verify_zero_check( vp.num_vars, &vp.expression, diff --git a/plonkish_backend/src/backend/hyperplonk/preprocessor.rs b/plonkish_backend/src/backend/hyperplonk/preprocessor.rs index 6aa7bc05..d0b094bf 100644 --- a/plonkish_backend/src/backend/hyperplonk/preprocessor.rs +++ b/plonkish_backend/src/backend/hyperplonk/preprocessor.rs @@ -46,7 +46,7 @@ pub(crate) fn preprocess>( let num_vars = circuit_info.k; let poly_size = 1 << num_vars; - // Batch size for the polynomial commitment scheme + // Batch size for the polynomial commitment scheme let batch_size = batch_size(circuit_info); // Trim the parameters for the PCS to those necessary for the size of the circuit let (pcs_pp, pcs_vp) = Pcs::trim(param, poly_size, batch_size)?; @@ -171,7 +171,7 @@ pub(super) fn max_degree( .unwrap() } -//generate lookup constraints using logup GKR +//generate lookup constraints using logup GKR pub(super) fn lookup_constraints( circuit_info: &PlonkishCircuitInfo, beta: &Expression, @@ -202,7 +202,7 @@ pub(super) fn lookup_constraints( [h * (input + gamma) * (table + gamma) - (table + gamma) + m * (input + gamma)] }) .collect_vec(); - // Every expression that must be proved in the sum check argument + // Every expression that must be proved in the sum check argument let sum_check = (h_offset..) .take(circuit_info.lookups.len()) .map(|h| Query::new(h, Rotation::cur()).into()) @@ -226,7 +226,7 @@ pub(crate) fn permutation_constraints( // The offset is set to the total number of instance columns in the circuit let permutation_offset = circuit_info.num_poly(); let z_offset = permutation_offset + permutation_polys.len() + num_builtin_witness_polys; - // Represent all columns in permutation argument with polynomials + // Represent all columns in permutation argument with polynomials let polys = permutation_polys .iter() .map(|idx| Expression::Polynomial(Query::new(*idx, Rotation::cur()))) @@ -252,12 +252,12 @@ pub(crate) fn permutation_constraints( let z_0_next = Expression::::Polynomial(Query::new(z_offset, Rotation::next())); let l_0 = &Expression::::lagrange(0); let one = &Expression::one(); - // Create the constraints for the permutation argument + // Create the constraints for the permutation argument // The contraints here are the like those from the halo2 gitbook but the matrix Z_0 Z_1 ... Z_{b-1} is transposed let constraints = chain![ zs.first().map(|z_0| l_0 * (z_0 - one)), polys - //iterating over b elements which are vectors of length m + //iterating over b elements which are vectors of length m .chunks(chunk_size) .zip(ids.chunks(chunk_size)) .zip(permutations.chunks(chunk_size)) @@ -284,7 +284,7 @@ pub(crate) fn permutation_constraints( (num_chunks, constraints) } -// Generate multi-linear permutation polynomials for permutation argument +// Generate multi-linear permutation polynomials for permutation argument pub(crate) fn permutation_polys( num_vars: usize, permutation_polys: &[usize], @@ -298,7 +298,7 @@ pub(crate) fn permutation_polys( } poly_index }; - // permutations will be the matrix defining all permutation polynomials. As we start with the identity permutation, all entries have value of the index within the matrix. + // permutations will be the matrix defining all permutation polynomials. As we start with the identity permutation, all entries have value of the index within the matrix. let mut permutations = (0..permutation_polys.len() as u64) .map(|idx| { steps(F::from(idx << num_vars)) @@ -314,7 +314,7 @@ pub(crate) fn permutation_polys( mem::swap(&mut permutations[poly_index[i]][j], &mut last); } } - // We generate a multilinear polynomial from each column of the permutation matrix. + // We generate a multilinear polynomial from each column of the permutation matrix. permutations .into_iter() .map(MultilinearPolynomial::new) diff --git a/plonkish_backend/src/backend/hyperplonk/prover.rs b/plonkish_backend/src/backend/hyperplonk/prover.rs index 52fd4462..f74f6e91 100644 --- a/plonkish_backend/src/backend/hyperplonk/prover.rs +++ b/plonkish_backend/src/backend/hyperplonk/prover.rs @@ -57,7 +57,7 @@ pub(crate) fn lookup_compressed_polys> let polys = polys.iter().map(Borrow::borrow).collect_vec(); let num_vars = polys[0].num_vars(); - // This is the sum of all elements in the input and table + // This is the sum of all elements in the input and table let expression = lookups .iter() .flat_map(|lookup| lookup.iter().map(|(input, table)| (input + table))) @@ -173,7 +173,7 @@ pub(super) fn lookup_m_poly( .and_modify(|count| *count += 1) .or_insert(1); } else { - // If the input is not found in the table, the lookup is invalid + // If the input is not found in the table, the lookup is invalid *valid = false; break; } diff --git a/plonkish_backend/src/backend/hyperplonk/verifier.rs b/plonkish_backend/src/backend/hyperplonk/verifier.rs index d730b2cb..f9f6049e 100644 --- a/plonkish_backend/src/backend/hyperplonk/verifier.rs +++ b/plonkish_backend/src/backend/hyperplonk/verifier.rs @@ -48,7 +48,7 @@ pub(crate) fn verify_sum_check( y: &[F], transcript: &mut impl FieldTranscriptRead, ) -> Result<(Vec>, Vec>), Error> { - // In description of the sum check protocol in https://eprint.iacr.org/2022/1355.pdf, + // In description of the sum check protocol in https://eprint.iacr.org/2022/1355.pdf, // x_eval corresponds to the v in the final check, x is \alpha_1, ..., \alpha_{\mu} the challenges during the sum check protocol let (x_eval, x) = ClassicSumCheck::, BinaryField>::verify( &(), @@ -82,7 +82,7 @@ pub(crate) fn verify_sum_check( )); } - // Obtain points and evaluations for which we need to verify the opening proofs + // Obtain points and evaluations for which we need to verify the opening proofs let point_offset = point_offset(&pcs_query); let evals = pcs_query .iter() diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs index eaf8599c..0bb68411 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs @@ -588,13 +588,13 @@ impl Pow5State { mod tests { use group::ff::{Field, PrimeField}; use halo2_proofs::{ - circuit::{Layouter, SimpleFloorPlanner, Value}, + circuit::{Layouter,SimpleFloorPlanner,Value}, dev::MockProver, plonk::{Circuit, ConstraintSystem, Error,keygen_vk,keygen_pk,create_proof,verify_proof}, - poly::kzg::{commitment::{KZGCommitmentScheme,ParamsKZG},multiopen::{ProverGWC, VerifierGWC},strategy::SingleStrategy,}, - transcript::{Blake2bRead, Blake2bWrite, Challenge255, TranscriptReadBuffer, TranscriptWriterBuffer}, + poly::kzg::{commitment::{KZGCommitmentScheme,ParamsKZG},multiopen::{ProverGWC,VerifierGWC},strategy::SingleStrategy,}, + transcript::{Blake2bRead,Blake2bWrite,Challenge255,TranscriptReadBuffer,TranscriptWriterBuffer}, }; - use halo2_curves::pasta::{pallas, Fp}; + use halo2_curves::pasta::{pallas,Fp}; use halo2_curves::bn256::{Bn256,Fr,Fq}; use halo2_curves::grumpkin; use rand::rngs::OsRng; @@ -725,10 +725,10 @@ mod tests { fn instances(&self) -> Vec> { /*let mut expected_final_state = (0..7) - .map(|idx| Fq::from(idx as u64)) - .collect::>() - .try_into() - .unwrap();*/ + .map(|idx| Fq::from(idx as u64)) + .collect::>() + .try_into() + .unwrap();*/ Vec::new() } } From 18f41e000348ecd32863efdb4ba256338a8705f4 Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Mon, 6 Jan 2025 13:21:24 +0000 Subject: [PATCH 13/35] fix: lint errors --- plonkish_backend/src/backend/hyperplonk.rs | 2 +- .../src/backend/hyperplonk/preprocessor.rs | 2 +- .../src/circuits/poseidongadget.rs | 2 +- .../circuits/poseidongadget/poseidon/pow5.rs | 54 ++++++++++--------- .../poseidon/primitives/bn256param.rs | 41 ++++++++------ .../src/circuits/poseidongadget/utilities.rs | 6 +-- .../poseidongadget/utilities/cond_swap.rs | 4 +- 7 files changed, 62 insertions(+), 49 deletions(-) diff --git a/plonkish_backend/src/backend/hyperplonk.rs b/plonkish_backend/src/backend/hyperplonk.rs index 7b274c1f..01994f1a 100644 --- a/plonkish_backend/src/backend/hyperplonk.rs +++ b/plonkish_backend/src/backend/hyperplonk.rs @@ -320,7 +320,7 @@ where &lookup_h_permutation_z_comms, ] .collect_vec(); - // Verify the opening proofs for the polynomials commitments + // Verify the opening proofs for the polynomials commitments Pcs::batch_verify(&vp.pcs, comms, &points, &evals, transcript)?; Ok(()) diff --git a/plonkish_backend/src/backend/hyperplonk/preprocessor.rs b/plonkish_backend/src/backend/hyperplonk/preprocessor.rs index d0b094bf..eb546f15 100644 --- a/plonkish_backend/src/backend/hyperplonk/preprocessor.rs +++ b/plonkish_backend/src/backend/hyperplonk/preprocessor.rs @@ -186,7 +186,7 @@ pub(super) fn lookup_constraints( .zip(m_offset..) .zip(h_offset..) .flat_map(|((lookup, m), h)| { - // make m and h into polynomials, these are created during proving + // make m and h into polynomials, these are created during proving let [m, h] = &[m, h] .map(|poly| Query::new(poly, Rotation::cur())) .map(Expression::::Polynomial); diff --git a/plonkish_backend/src/circuits/poseidongadget.rs b/plonkish_backend/src/circuits/poseidongadget.rs index 98453f11..430d0ec4 100644 --- a/plonkish_backend/src/circuits/poseidongadget.rs +++ b/plonkish_backend/src/circuits/poseidongadget.rs @@ -11,4 +11,4 @@ #![deny(unsafe_code)] pub mod poseidon; -pub mod utilities; \ No newline at end of file +pub mod utilities; diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs index 0bb68411..b40e3ee4 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs @@ -587,37 +587,44 @@ impl Pow5State { #[cfg(test)] mod tests { use group::ff::{Field, PrimeField}; + use halo2_curves::pasta::{pallas, Fp}; + use halo2_curves::bn256::{Bn256, Fr, Fq}; + use halo2_curves::grumpkin; use halo2_proofs::{ - circuit::{Layouter,SimpleFloorPlanner,Value}, + circuit::{Layouter, SimpleFloorPlanner, Value}, dev::MockProver, - plonk::{Circuit, ConstraintSystem, Error,keygen_vk,keygen_pk,create_proof,verify_proof}, - poly::kzg::{commitment::{KZGCommitmentScheme,ParamsKZG},multiopen::{ProverGWC,VerifierGWC},strategy::SingleStrategy,}, - transcript::{Blake2bRead,Blake2bWrite,Challenge255,TranscriptReadBuffer,TranscriptWriterBuffer}, + plonk::{ + create_proof, keygen_pk, keygen_vk, verify_proof, Circuit, ConstraintSystem, Error, + }, + poly::kzg::{ + commitment::{KZGCommitmentScheme, ParamsKZG}, + multiopen::{ProverGWC, VerifierGWC}, + strategy::SingleStrategy, + }, + transcript::{ + Blake2bRead, Blake2bWrite, Challenge255, TranscriptReadBuffer, TranscriptWriterBuffer, + }, }; - use halo2_curves::pasta::{pallas,Fp}; - use halo2_curves::bn256::{Bn256,Fr,Fq}; - use halo2_curves::grumpkin; use rand::rngs::OsRng; use super::{PoseidonInstructions, Pow5Chip, Pow5Config, StateWord}; use crate::circuits::poseidongadget::poseidon::{ - primitives::{self as poseidon, ConstantLength, BN256param as newParam, Spec}, + primitives::{self as poseidon, BN256param as newParam, ConstantLength, Spec}, Hash, }; use std::convert::TryInto; use std::marker::PhantomData; - use crate::backend::{ - hyperplonk::HyperPlonk, - PlonkishCircuit, - PlonkishBackend, - }; + use crate::backend::{hyperplonk::HyperPlonk, PlonkishCircuit, PlonkishBackend,}; use crate::{ - frontend::halo2::{CircuitExt,Halo2Circuit}, - pcs::{multilinear::{MultilinearKzg,Zeromorph},univariate::{UnivariateKzg,UnivariateIpa}}, + frontend::halo2::{CircuitExt, Halo2Circuit}, + pcs::{ + multilinear::{MultilinearKzg, Zeromorph}, + univariate::{UnivariateKzg, UnivariateIpa}, + }, util::{ - transcript::{InMemoryTranscript,Keccak256Transcript}, + transcript::{InMemoryTranscript, Keccak256Transcript}, test::seeded_std_rng, } }; @@ -722,7 +729,6 @@ mod tests { } impl CircuitExt for PermuteCircuit::, 5, 4> { - fn instances(&self) -> Vec> { /*let mut expected_final_state = (0..7) .map(|idx| Fq::from(idx as u64)) @@ -733,7 +739,7 @@ mod tests { } } - /* #[test] + /* #[test] fn poseidon_permute() { let k = 6; let circuit = PermuteCircuit::(PhantomData); @@ -743,14 +749,15 @@ mod tests { #[test] fn poseidon_permute_new_param() { type Pb = HyperPlonk>>; - let circuit = Halo2Circuit::new::(6, PermuteCircuit::, 5, 4>(PhantomData)); + let circuit = + Halo2Circuit::new::(6, PermuteCircuit::, 5, 4>(PhantomData)); let param = Pb::setup(&circuit.circuit_info().unwrap(), seeded_std_rng()).unwrap(); let (pp, vp) = Pb::preprocess(¶m, &circuit.circuit_info().unwrap()).unwrap(); let proof = { - let mut transcript = Keccak256Transcript::new(()); - Pb::prove(&pp, &circuit, &mut transcript, seeded_std_rng()).unwrap(); - transcript.into_proof() - }; + let mut transcript = Keccak256Transcript::new(()); + Pb::prove(&pp, &circuit, &mut transcript, seeded_std_rng()).unwrap(); + transcript.into_proof() + }; let result = { let mut transcript = Keccak256Transcript::from_proof((), proof.as_slice()); Pb::verify(&vp, circuit.instances(), &mut transcript, seeded_std_rng()) @@ -990,5 +997,4 @@ mod tests { .render(6, &circuit, &root) .unwrap(); }*/ - } diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs index 38825fcd..e8df8276 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs @@ -1,8 +1,9 @@ // TO DO: don't want to use two lines below -use halo2_proofs::arithmetic::Field; use super::{Mds, Spec}; -use halo2_curves::bn256::Fr; use crate::circuits::poseidongadget::poseidon::primitives::generate_constants; +use halo2_curves::bn256::Fr; +use halo2_proofs::arithmetic::Field; + // To do rewrite this below /// Poseidon-128 using the $x^5$ S-box, with a width of 3 field elements, and the @@ -13,9 +14,11 @@ use crate::circuits::poseidongadget::poseidon::primitives::generate_constants; /// partial rounds, making it easier to construct a Halo 2 circuit. #[derive(Debug)] // Do we have to specify width and rate generically? -pub struct BN256param; +pub struct BN256param; -impl Spec for BN256param { +impl Spec + for BN256param +{ fn full_rounds() -> usize { 8 } @@ -51,7 +54,6 @@ impl Spec fo // TO DO Remove both - #[cfg(test)] mod tests { #![allow(dead_code)] @@ -66,15 +68,25 @@ mod tests { /// such that its constants will be generated at runtime. #[derive(Debug)] // to do change Field to Fr? - pub struct BN256paramGen(PhantomData); + pub struct BN256paramGen( + PhantomData, + ); - impl BN256paramGen { + impl + BN256paramGen + { pub fn new() -> Self { BN256paramGen(PhantomData) } } - impl + Ord, const SECURE_MDS: usize> Spec for BN256paramGen { + impl< + const T: usize, + const R: usize, + F: FromUniformBytes<64> + Ord, + const SECURE_MDS: usize, + > Spec for BN256paramGen + { fn full_rounds() -> usize { 8 } @@ -117,14 +129,14 @@ mod tests { #[test] #[ignore] fn test_against_reference() { - // TO DO: write this as in p128pow5t3.rs once we have the constants manually generated + // TO DO: write this as in p128pow5t3.rs once we have the constants manually generated } #[test] #[ignore] fn permute_test_vectors() { - /* macro_rules! permute_test_vectors { + /* macro_rules! permute_test_vectors { ($t:expr) => { { r = $t - 1; @@ -148,18 +160,13 @@ mod tests { }; } - for t in 1..7 { permute_test_vectors!(t); - }*/ - - } #[test] #[ignore] - // Generate test vectors for the permutation and adapt this - fn hash_test_vectors() { - } + // Generate test vectors for the permutation and adapt this + fn hash_test_vectors() {} } diff --git a/plonkish_backend/src/circuits/poseidongadget/utilities.rs b/plonkish_backend/src/circuits/poseidongadget/utilities.rs index c105d20e..eeeddd86 100644 --- a/plonkish_backend/src/circuits/poseidongadget/utilities.rs +++ b/plonkish_backend/src/circuits/poseidongadget/utilities.rs @@ -239,13 +239,13 @@ mod tests { use super::*; use ff::FromUniformBytes; use group::ff::{Field, PrimeField}; + use halo2_curves::pasta::pallas; use halo2_proofs::{ circuit::{Layouter, SimpleFloorPlanner}, dev::{FailureLocation, MockProver, VerifyFailure}, plonk::{Any, Circuit, ConstraintSystem, Constraints, Error, Selector}, poly::Rotation, }; - use halo2_curves::pasta::pallas; use proptest::prelude::*; use rand::rngs::OsRng; use std::convert::TryInto; @@ -314,13 +314,13 @@ mod tests { for i in 0..8 { let circuit: MyCircuit<8> = MyCircuit(i); - let prover = MockProver::::run::<_,true>(3, &circuit, vec![]).unwrap(); + let prover = MockProver::::run::<_, true>(3, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); } { let circuit: MyCircuit<8> = MyCircuit(8); - let prover = MockProver::::run::<_,true>(3, &circuit, vec![]).unwrap(); + let prover = MockProver::::run::<_, true>(3, &circuit, vec![]).unwrap(); assert_eq!( prover.verify(), Err(vec![VerifyFailure::ConstraintNotSatisfied { diff --git a/plonkish_backend/src/circuits/poseidongadget/utilities/cond_swap.rs b/plonkish_backend/src/circuits/poseidongadget/utilities/cond_swap.rs index c937f3eb..0198bf0c 100644 --- a/plonkish_backend/src/circuits/poseidongadget/utilities/cond_swap.rs +++ b/plonkish_backend/src/circuits/poseidongadget/utilities/cond_swap.rs @@ -190,12 +190,12 @@ mod tests { use super::{CondSwapChip, CondSwapConfig, CondSwapInstructions}; use ff::PrimeField; use group::ff::Field; + use halo2_curves::pasta::pallas::Base; use halo2_proofs::{ circuit::{Layouter, SimpleFloorPlanner, Value}, dev::MockProver, plonk::{Circuit, ConstraintSystem, Error}, }; - use halo2_curves::pasta::pallas::Base; use rand::rngs::OsRng; #[test] @@ -282,7 +282,7 @@ mod tests { b: Value::known(Base::random(rng)), swap: Value::known(false), }; - let prover = MockProver::::run::<_,true>(3, &circuit, vec![]).unwrap(); + let prover = MockProver::::run::<_, true>(3, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); } } From 2738b66d8874d67038dfd0b113e16449c7fbc84e Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Mon, 6 Jan 2025 13:34:43 +0000 Subject: [PATCH 14/35] fix: lint errors --- .../circuits/poseidongadget/poseidon/pow5.rs | 16 ++++++++-------- .../poseidon/primitives/bn256param.rs | 19 +++++++++---------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs index b40e3ee4..f387a706 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs @@ -587,9 +587,9 @@ impl Pow5State { #[cfg(test)] mod tests { use group::ff::{Field, PrimeField}; - use halo2_curves::pasta::{pallas, Fp}; use halo2_curves::bn256::{Bn256, Fr, Fq}; use halo2_curves::grumpkin; + use halo2_curves::pasta::{pallas, Fp}; use halo2_proofs::{ circuit::{Layouter, SimpleFloorPlanner, Value}, dev::MockProver, @@ -615,18 +615,18 @@ mod tests { use std::convert::TryInto; use std::marker::PhantomData; - use crate::backend::{hyperplonk::HyperPlonk, PlonkishCircuit, PlonkishBackend,}; + use crate::backend::{hyperplonk::HyperPlonk, PlonkishBackend, PlonkishCircuit}; use crate::{ frontend::halo2::{CircuitExt, Halo2Circuit}, pcs::{ multilinear::{MultilinearKzg, Zeromorph}, - univariate::{UnivariateKzg, UnivariateIpa}, + univariate::{UnivariateIpa, UnivariateKzg}, }, util::{ - transcript::{InMemoryTranscript, Keccak256Transcript}, test::seeded_std_rng, - } + transcript::{InMemoryTranscript, Keccak256Transcript}, + }, }; struct PermuteCircuit, const WIDTH: usize, const RATE: usize>( @@ -728,7 +728,7 @@ mod tests { } } - impl CircuitExt for PermuteCircuit::, 5, 4> { + impl CircuitExt for PermuteCircuit, 5, 4> { fn instances(&self) -> Vec> { /*let mut expected_final_state = (0..7) .map(|idx| Fq::from(idx as u64)) @@ -749,8 +749,8 @@ mod tests { #[test] fn poseidon_permute_new_param() { type Pb = HyperPlonk>>; - let circuit = - Halo2Circuit::new::(6, PermuteCircuit::, 5, 4>(PhantomData)); + let circuit = + Halo2Circuit::new::(6, PermuteCircuit::, 5, 4>(PhantomData)); let param = Pb::setup(&circuit.circuit_info().unwrap(), seeded_std_rng()).unwrap(); let (pp, vp) = Pb::preprocess(¶m, &circuit.circuit_info().unwrap()).unwrap(); let proof = { diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs index e8df8276..0d43b256 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs @@ -4,7 +4,6 @@ use crate::circuits::poseidongadget::poseidon::primitives::generate_constants; use halo2_curves::bn256::Fr; use halo2_proofs::arithmetic::Field; - // To do rewrite this below /// 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". @@ -16,8 +15,8 @@ use halo2_proofs::arithmetic::Field; // Do we have to specify width and rate generically? pub struct BN256param; -impl Spec - for BN256param +impl Spec + for BN256param { fn full_rounds() -> usize { 8 @@ -73,7 +72,7 @@ mod tests { ); impl - BN256paramGen + BN256paramGen { pub fn new() -> Self { BN256paramGen(PhantomData) @@ -82,15 +81,15 @@ mod tests { impl< const T: usize, - const R: usize, - F: FromUniformBytes<64> + Ord, + const R: usize, + F: FromUniformBytes<64> + Ord, const SECURE_MDS: usize, - > Spec for BN256paramGen + > Spec for BN256paramGen { fn full_rounds() -> usize { 8 } - + fn partial_rounds() -> usize { //TO DO: we need an even number of partial rounds - can we round up match T { @@ -105,11 +104,11 @@ mod tests { _ => unimplemented!(), } } - + fn sbox(val: F) -> F { val.pow_vartime([5]) } - + fn secure_mds() -> usize { SECURE_MDS } From 26edf8dc527673c40a5823dbe952b3163f7888a7 Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Mon, 6 Jan 2025 13:42:34 +0000 Subject: [PATCH 15/35] fix: lint errors --- .../src/circuits/poseidongadget/poseidon/pow5.rs | 4 ++-- .../poseidongadget/poseidon/primitives/bn256param.rs | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs index f387a706..eaa05231 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs @@ -587,7 +587,7 @@ impl Pow5State { #[cfg(test)] mod tests { use group::ff::{Field, PrimeField}; - use halo2_curves::bn256::{Bn256, Fr, Fq}; + use halo2_curves::bn256::{Bn256, Fq, Fr}; use halo2_curves::grumpkin; use halo2_curves::pasta::{pallas, Fp}; use halo2_proofs::{ @@ -616,7 +616,7 @@ mod tests { use std::marker::PhantomData; use crate::backend::{hyperplonk::HyperPlonk, PlonkishBackend, PlonkishCircuit}; - + use crate::{ frontend::halo2::{CircuitExt, Halo2Circuit}, pcs::{ diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs index 0d43b256..da3021c2 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs @@ -16,7 +16,7 @@ use halo2_proofs::arithmetic::Field; pub struct BN256param; impl Spec - for BN256param + for BN256param { fn full_rounds() -> usize { 8 @@ -71,7 +71,7 @@ mod tests { PhantomData, ); - impl + impl BN256paramGen { pub fn new() -> Self { @@ -84,7 +84,7 @@ mod tests { const R: usize, F: FromUniformBytes<64> + Ord, const SECURE_MDS: usize, - > Spec for BN256paramGen + > Spec for BN256paramGen { fn full_rounds() -> usize { 8 @@ -108,11 +108,11 @@ mod tests { fn sbox(val: F) -> F { val.pow_vartime([5]) } - + fn secure_mds() -> usize { SECURE_MDS } - + fn constants() -> (Vec<[F; T]>, Mds, Mds) { // TO DO: manually generate the constants here generate_constants::<_, Self, T, R>() From b79d9a647c60ee287de952e4adf82faa47a365da Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Mon, 6 Jan 2025 14:00:23 +0000 Subject: [PATCH 16/35] change rust version --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 837f16a7..5c8c298b 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.73.0 \ No newline at end of file +1.75.0 \ No newline at end of file From 8680902b37c9f23f219830b805c86231ad193a64 Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Mon, 6 Jan 2025 14:38:54 +0000 Subject: [PATCH 17/35] change version back --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 5c8c298b..837f16a7 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.75.0 \ No newline at end of file +1.73.0 \ No newline at end of file From dfd012662a748437cbd84cf54680fb3c4b4274bd Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Mon, 6 Jan 2025 14:52:59 +0000 Subject: [PATCH 18/35] remove unnecessary imports --- .../circuits/poseidongadget/poseidon/pow5.rs | 22 +++++-------------- .../poseidongadget/poseidon/primitives.rs | 6 ++--- .../poseidon/primitives/bn256param.rs | 3 +-- 3 files changed, 9 insertions(+), 22 deletions(-) diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs index eaa05231..21330408 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs @@ -586,26 +586,14 @@ impl Pow5State { #[cfg(test)] mod tests { - use group::ff::{Field, PrimeField}; - use halo2_curves::bn256::{Bn256, Fq, Fr}; - use halo2_curves::grumpkin; - use halo2_curves::pasta::{pallas, Fp}; + use halo2_curves::bn256::{Bn256, Fr}; + use halo2_curves::pasta::Fp; use halo2_proofs::{ circuit::{Layouter, SimpleFloorPlanner, Value}, - dev::MockProver, plonk::{ - create_proof, keygen_pk, keygen_vk, verify_proof, Circuit, ConstraintSystem, Error, - }, - poly::kzg::{ - commitment::{KZGCommitmentScheme, ParamsKZG}, - multiopen::{ProverGWC, VerifierGWC}, - strategy::SingleStrategy, - }, - transcript::{ - Blake2bRead, Blake2bWrite, Challenge255, TranscriptReadBuffer, TranscriptWriterBuffer, + Circuit, ConstraintSystem, Error, }, }; - use rand::rngs::OsRng; use super::{PoseidonInstructions, Pow5Chip, Pow5Config, StateWord}; use crate::circuits::poseidongadget::poseidon::{ @@ -620,8 +608,8 @@ mod tests { use crate::{ frontend::halo2::{CircuitExt, Halo2Circuit}, pcs::{ - multilinear::{MultilinearKzg, Zeromorph}, - univariate::{UnivariateIpa, UnivariateKzg}, + multilinear::Zeromorph, + univariate::UnivariateKzg, }, util::{ test::seeded_std_rng, diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives.rs index 0eb4bb5c..c81f35e0 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives.rs @@ -381,9 +381,9 @@ impl, const T: usize, const RATE: usize, cons #[cfg(test)] mod tests { - use super::{permute, ConstantLength, Hash, Spec}; - use ff::PrimeField; - use halo2_curves::pasta::pallas; + //use super::{permute, ConstantLength, Hash, Spec}; + //use ff::PrimeField; + //use halo2_curves::pasta::pallas; /*#[ignore] #[test] diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs index da3021c2..3282122f 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs @@ -57,9 +57,8 @@ impl Spec mod tests { #![allow(dead_code)] use crate::circuits::poseidongadget::poseidon::primitives::{ - generate_constants, permute, ConstantLength, Hash, Mds, Spec, + generate_constants, Mds, Spec, }; - use ff::PrimeField; use ff::{Field, FromUniformBytes}; use std::marker::PhantomData; From c1b82de156b5646487467f287b3f28465797485d Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Mon, 6 Jan 2025 14:56:38 +0000 Subject: [PATCH 19/35] fix: lint error --- .../src/circuits/poseidongadget/poseidon/pow5.rs | 9 ++------- .../poseidongadget/poseidon/primitives/bn256param.rs | 4 +--- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs index 21330408..f0fdccd5 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs @@ -590,9 +590,7 @@ mod tests { use halo2_curves::pasta::Fp; use halo2_proofs::{ circuit::{Layouter, SimpleFloorPlanner, Value}, - plonk::{ - Circuit, ConstraintSystem, Error, - }, + plonk::{Circuit, ConstraintSystem, Error}, }; use super::{PoseidonInstructions, Pow5Chip, Pow5Config, StateWord}; @@ -607,10 +605,7 @@ mod tests { use crate::{ frontend::halo2::{CircuitExt, Halo2Circuit}, - pcs::{ - multilinear::Zeromorph, - univariate::UnivariateKzg, - }, + pcs::{multilinear::Zeromorph, univariate::UnivariateKzg}, util::{ test::seeded_std_rng, transcript::{InMemoryTranscript, Keccak256Transcript}, diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs index 3282122f..5e2cf605 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs @@ -56,9 +56,7 @@ impl Spec #[cfg(test)] mod tests { #![allow(dead_code)] - use crate::circuits::poseidongadget::poseidon::primitives::{ - generate_constants, Mds, Spec, - }; + use crate::circuits::poseidongadget::poseidon::primitives::{generate_constants, Mds, Spec}; use ff::{Field, FromUniformBytes}; use std::marker::PhantomData; From 3002187bdc5fbf5359381748a5f4bf887bdf825f Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Mon, 6 Jan 2025 15:04:43 +0000 Subject: [PATCH 20/35] fix: change version back --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 837f16a7..6174fee8 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.73.0 \ No newline at end of file +1.79.0 \ No newline at end of file From f5ae9e0965cc9eb0e2f70fb6411e08d927b629a6 Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Mon, 6 Jan 2025 15:27:32 +0000 Subject: [PATCH 21/35] Revert "Revert "Merge remote-tracking branch 'origin/main' into lydia/poseidoncircuit"" This reverts commit b6f0f995a2843e504268c87a25d7702cfe7c0028. --- .../src/accumulation/protostar/hyperplonk.rs | 12 +++++---- .../protostar/hyperplonk/preprocessor.rs | 7 ++--- .../src/accumulation/sangria/hyperplonk.rs | 12 +++++---- plonkish_backend/src/backend/hyperplonk.rs | 27 ++++++++----------- .../src/backend/hyperplonk/preprocessor.rs | 9 +++---- .../src/backend/hyperplonk/prover.rs | 9 +++---- .../src/backend/hyperplonk/util.rs | 2 +- plonkish_backend/src/backend/unihyperplonk.rs | 2 ++ .../src/frontend/halo2/circuit.rs | 8 +++--- .../src/pcs/multilinear/brakedown.rs | 2 ++ .../src/pcs/multilinear/gemini.rs | 16 +++++++---- plonkish_backend/src/pcs/multilinear/hyrax.rs | 2 ++ plonkish_backend/src/pcs/multilinear/ipa.rs | 6 ++++- plonkish_backend/src/pcs/multilinear/kzg.rs | 7 +++-- .../src/pcs/multilinear/zeromorph.rs | 16 ++++++----- plonkish_backend/src/pcs/univariate.rs | 4 +-- plonkish_backend/src/pcs/univariate/hyrax.rs | 6 +++-- plonkish_backend/src/pcs/univariate/ipa.rs | 8 +++--- plonkish_backend/src/pcs/univariate/kzg.rs | 4 +-- .../src/piop/sum_check/classic/coeff.rs | 4 +-- plonkish_backend/src/util/code/brakedown.rs | 2 ++ 21 files changed, 90 insertions(+), 75 deletions(-) diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs index 221cab44..5b61df25 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs @@ -595,8 +595,8 @@ pub(crate) mod test { HyperPlonk, }, pcs::{ - multilinear::{Gemini, MultilinearIpa, MultilinearKzg, Zeromorph}, - univariate::UnivariateKzg, + multilinear::Zeromorph, + univariate::{UnivariateIpa, UnivariateKzg}, }, util::{ expression::rotate::BinaryField, @@ -641,8 +641,10 @@ pub(crate) mod test { }; } - tests!(ipa, MultilinearIpa); - tests!(kzg, MultilinearKzg); - tests!(gemini_kzg, Gemini>); + //tests!(ipa, MultilinearIpa); + //tests!(kzg, MultilinearKzg); + //tests!(gemini_kzg, Gemini>); tests!(zeromorph_kzg, Zeromorph>); + //tests!(gemini_ipa, Gemini>); + tests!(zeromorph_ipa, Zeromorph>); } diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs index 83d212d4..3179205e 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs @@ -352,13 +352,10 @@ pub(crate) fn lookup_constraints( let [m, h_input, h_table] = &[m, h, h + 1] .map(|poly| Query::new(poly, Rotation::cur())) .map(Expression::::Polynomial); - let (inputs, tables) = lookup - .iter() - .map(|(input, table)| (input, table)) - .unzip::<_, _, Vec<_>, Vec<_>>(); + let (inputs, tables) = lookup.iter().cloned().unzip::<_, _, Vec<_>, Vec<_>>(); let [input, table] = &[inputs, tables].map(|exprs| { chain![ - exprs.first().cloned().cloned(), + exprs.first().cloned(), exprs .into_iter() .skip(1) diff --git a/plonkish_backend/src/accumulation/sangria/hyperplonk.rs b/plonkish_backend/src/accumulation/sangria/hyperplonk.rs index 80a44714..1ecf0092 100644 --- a/plonkish_backend/src/accumulation/sangria/hyperplonk.rs +++ b/plonkish_backend/src/accumulation/sangria/hyperplonk.rs @@ -7,8 +7,8 @@ pub(crate) mod test { HyperPlonk, }, pcs::{ - multilinear::{Gemini, MultilinearIpa, MultilinearKzg, Zeromorph}, - univariate::UnivariateKzg, + multilinear::Zeromorph, + univariate::{UnivariateIpa, UnivariateKzg}, }, util::{ expression::rotate::BinaryField, @@ -53,8 +53,10 @@ pub(crate) mod test { }; } - tests!(ipa, MultilinearIpa); - tests!(kzg, MultilinearKzg); - tests!(gemini_kzg, Gemini>); + //tests!(ipa, MultilinearIpa); + //tests!(kzg, MultilinearKzg); + //tests!(gemini_kzg, Gemini>); tests!(zeromorph_kzg, Zeromorph>); + //tests!(gemini_ipa, Gemini>); + tests!(zeromorph_ipa, Zeromorph>); } diff --git a/plonkish_backend/src/backend/hyperplonk.rs b/plonkish_backend/src/backend/hyperplonk.rs index 01994f1a..8b1e0f30 100644 --- a/plonkish_backend/src/backend/hyperplonk.rs +++ b/plonkish_backend/src/backend/hyperplonk.rs @@ -344,21 +344,14 @@ mod test { test::run_plonkish_backend, }, pcs::{ - multilinear::{ - Gemini, MultilinearBrakedown, MultilinearHyrax, MultilinearIpa, MultilinearKzg, - Zeromorph, - }, - univariate::UnivariateKzg, + multilinear::Zeromorph, + univariate::{UnivariateIpa, UnivariateKzg}, }, util::{ - code::BrakedownSpec6, expression::rotate::BinaryField, hash::Keccak256, - test::seeded_std_rng, transcript::Keccak256Transcript, + expression::rotate::BinaryField, test::seeded_std_rng, transcript::Keccak256Transcript, }, }; - use halo2_curves::{ - bn256::{self, Bn256}, - grumpkin, - }; + use halo2_curves::{bn256::Bn256, grumpkin}; macro_rules! tests { ($suffix:ident, $pcs:ty, $num_vars_range:expr) => { @@ -383,10 +376,12 @@ mod test { }; } - tests!(brakedown, MultilinearBrakedown); - tests!(hyrax, MultilinearHyrax, 5..16); - tests!(ipa, MultilinearIpa); - tests!(kzg, MultilinearKzg); - tests!(gemini_kzg, Gemini>); + //tests!(brakedown, MultilinearBrakedown); + //tests!(hyrax, MultilinearHyrax, 5..16); + //tests!(ipa, MultilinearIpa); + //tests!(kzg, MultilinearKzg); + //tests!(gemini_kzg, Gemini>); tests!(zeromorph_kzg, Zeromorph>); + //tests!(gemini_ipa, Gemini>); + tests!(zeromorph_ipa, Zeromorph>); } diff --git a/plonkish_backend/src/backend/hyperplonk/preprocessor.rs b/plonkish_backend/src/backend/hyperplonk/preprocessor.rs index eb546f15..2e3edbc9 100644 --- a/plonkish_backend/src/backend/hyperplonk/preprocessor.rs +++ b/plonkish_backend/src/backend/hyperplonk/preprocessor.rs @@ -191,11 +191,7 @@ pub(super) fn lookup_constraints( .map(|poly| Query::new(poly, Rotation::cur())) .map(Expression::::Polynomial); // separate the input and tables from the lookup - let (inputs, tables) = lookup - .iter() - .map(|(input, table)| (input, table)) - .unzip::<_, _, Vec<_>, Vec<_>>(); - // Returns a distributed power expression for the input and table, with base beta, i.e. inputs[0] + \beta inputs[1] + \beta^2 inputs[2] + ... + let (inputs, tables) = lookup.iter().cloned().unzip::<_, _, Vec<_>, Vec<_>>(); let input = &Expression::distribute_powers(inputs, beta); let table = &Expression::distribute_powers(tables, beta); // h[i] = (gamma + input[i])^-1 - m[i] * (gamma + table[i])^-1 @@ -298,7 +294,8 @@ pub(crate) fn permutation_polys( } poly_index }; - // permutations will be the matrix defining all permutation polynomials. As we start with the identity permutation, all entries have value of the index within the matrix. + // Permutations will be the matrix defining all permutation polynomials. + // As we start with the identity permutation, all entries have value of the index within the matrix. let mut permutations = (0..permutation_polys.len() as u64) .map(|idx| { steps(F::from(idx << num_vars)) diff --git a/plonkish_backend/src/backend/hyperplonk/prover.rs b/plonkish_backend/src/backend/hyperplonk/prover.rs index f74f6e91..162d1a7e 100644 --- a/plonkish_backend/src/backend/hyperplonk/prover.rs +++ b/plonkish_backend/src/backend/hyperplonk/prover.rs @@ -124,17 +124,14 @@ pub(super) fn lookup_compressed_poly>( }; // split inputs and tables into separate vectors - let (inputs, tables) = lookup - .iter() - .map(|(input, table)| (input, table)) - .unzip::<_, _, Vec<_>, Vec<_>>(); + let (inputs, tables) = lookup.iter().cloned().unzip::<_, _, Vec<_>, Vec<_>>(); let timer = start_timer(|| "compressed_input_poly"); - let compressed_input_poly = compress(&inputs); + let compressed_input_poly = compress(&inputs.iter().collect::>()); end_timer(timer); let timer = start_timer(|| "compressed_table_poly"); - let compressed_table_poly = compress(&tables); + let compressed_table_poly = compress(&tables.iter().collect::>()); end_timer(timer); [compressed_input_poly, compressed_table_poly] diff --git a/plonkish_backend/src/backend/hyperplonk/util.rs b/plonkish_backend/src/backend/hyperplonk/util.rs index 96d1d995..e80be052 100644 --- a/plonkish_backend/src/backend/hyperplonk/util.rs +++ b/plonkish_backend/src/backend/hyperplonk/util.rs @@ -34,7 +34,7 @@ pub fn vanilla_plonk_circuit_info( preprocess_polys: [Vec; 5], permutations: Vec>, ) -> PlonkishCircuitInfo { - let [pi, q_l, q_r, q_m, q_o, q_c, w_l, w_r, w_o] = + let [pi, q_l, q_r, q_m, q_o, q_c, w_l, w_r, w_o]: &[Expression; 9] = &array::from_fn(|poly| Query::new(poly, Rotation::cur())).map(Expression::Polynomial); PlonkishCircuitInfo { k: num_vars, diff --git a/plonkish_backend/src/backend/unihyperplonk.rs b/plonkish_backend/src/backend/unihyperplonk.rs index d8737c45..a8f90396 100644 --- a/plonkish_backend/src/backend/unihyperplonk.rs +++ b/plonkish_backend/src/backend/unihyperplonk.rs @@ -413,6 +413,7 @@ mod test { ($suffix:ident, $pcs:ty, $additive:literal, $num_vars_range:expr) => { paste::paste! { #[test] + #[ignore = "we do not currently use UniHyperPlonk"] fn []() { run_plonkish_backend::<_, UniHyperPlonk<$pcs, $additive>, Keccak256Transcript<_>, _>($num_vars_range, |num_vars| { rand_vanilla_plonk_circuit::<_, Lexical>(num_vars, seeded_std_rng(), seeded_std_rng()) @@ -420,6 +421,7 @@ mod test { } #[test] + #[ignore = "we do not currently use UniHyperPlonk"] fn []() { run_plonkish_backend::<_, UniHyperPlonk<$pcs, $additive>, Keccak256Transcript<_>, _>($num_vars_range, |num_vars| { rand_vanilla_plonk_w_lookup_circuit::<_, Lexical>(num_vars, seeded_std_rng(), seeded_std_rng()) diff --git a/plonkish_backend/src/frontend/halo2/circuit.rs b/plonkish_backend/src/frontend/halo2/circuit.rs index 4352e8aa..cd1c6211 100644 --- a/plonkish_backend/src/frontend/halo2/circuit.rs +++ b/plonkish_backend/src/frontend/halo2/circuit.rs @@ -53,7 +53,7 @@ mod vanilla_plonk { } #[derive(Clone, Default)] - pub struct VanillaPlonk(usize, Vec<[Assigned; 8]>); + pub struct VanillaPlonk(Vec<[Assigned; 8]>); impl Circuit for VanillaPlonk { type Config = VanillaPlonkConfig; @@ -76,7 +76,7 @@ mod vanilla_plonk { layouter.assign_region( || "", |mut region| { - for (offset, values) in self.1.iter().enumerate() { + for (offset, values) in self.0.iter().enumerate() { let (selectors, wires) = values.split_at(config.selectors.len()); for (column, value) in config.selectors.into_iter().zip(selectors.iter().copied()) @@ -114,11 +114,11 @@ mod vanilla_plonk { .collect_vec(), ] .collect(); - Self(k, values) + Self(values) } fn instances(&self) -> Vec> { - let [q_l, q_r, q_m, q_o, q_c, w_l, w_r, w_o] = self.1[0]; + let [q_l, q_r, q_m, q_o, q_c, w_l, w_r, w_o] = self.0[0]; let pi = (-(q_l * w_l + q_r * w_r + q_m * w_l * w_r + q_o * w_o + q_c)).evaluate(); vec![vec![pi]] } diff --git a/plonkish_backend/src/pcs/multilinear/brakedown.rs b/plonkish_backend/src/pcs/multilinear/brakedown.rs index 39f961c1..de7d69b7 100644 --- a/plonkish_backend/src/pcs/multilinear/brakedown.rs +++ b/plonkish_backend/src/pcs/multilinear/brakedown.rs @@ -448,11 +448,13 @@ mod test { type Pcs = MultilinearBrakedown; #[test] + #[ignore = "we do not currently use brakedown"] fn commit_open_verify() { run_commit_open_verify::<_, Pcs, Keccak256Transcript<_>>(); } #[test] + #[ignore = "we do not currently use brakedown"] fn batch_commit_open_verify() { run_batch_commit_open_verify::<_, Pcs, Keccak256Transcript<_>>(); } diff --git a/plonkish_backend/src/pcs/multilinear/gemini.rs b/plonkish_backend/src/pcs/multilinear/gemini.rs index 99c866f8..4fdadac2 100644 --- a/plonkish_backend/src/pcs/multilinear/gemini.rs +++ b/plonkish_backend/src/pcs/multilinear/gemini.rs @@ -5,7 +5,7 @@ use crate::{ pcs::{ multilinear::additive, univariate::{ - err_too_large_deree, ipa::UnivariateIpa, UnivariateIpaCommitment, UnivariateKzg, + err_too_large_degree, ipa::UnivariateIpa, UnivariateIpaCommitment, UnivariateKzg, UnivariateKzgCommitment, }, Evaluation, Point, PolynomialCommitmentScheme, @@ -58,7 +58,7 @@ where fn commit(pp: &Self::ProverParam, poly: &Self::Polynomial) -> Result { if pp.degree() + 1 < poly.evals().len() { let got = poly.evals().len() - 1; - return Err(err_too_large_deree("commit", pp.degree(), got)); + return Err(err_too_large_degree("commit", pp.degree(), got)); } Ok(UnivariateKzg::commit_monomial(pp, poly.evals())) @@ -85,7 +85,7 @@ where let num_vars = point.len(); if pp.degree() + 1 < poly.evals().len() { let got = poly.evals().len() - 1; - return Err(err_too_large_deree("open", pp.degree(), got)); + return Err(err_too_large_degree("open", pp.degree(), got)); } if cfg!(feature = "sanity-check") { @@ -254,10 +254,14 @@ where fn commit(pp: &Self::ProverParam, poly: &Self::Polynomial) -> Result { if pp.degree() + 1 < poly.evals().len() { let got = poly.evals().len() - 1; - return Err(err_too_large_deree("commit", pp.degree(), got)); + return Err(err_too_large_degree("commit", pp.degree(), got)); } let uni_poly = UnivariatePolynomial::monomial(poly.evals().to_vec()); + if uni_poly.coeffs().is_empty() { + return Ok(UnivariateIpaCommitment::::default()); + } + UnivariateIpa::commit(pp, &uni_poly) } @@ -282,7 +286,7 @@ where let num_vars = point.len(); if pp.degree() + 1 < poly.evals().len() { let got = poly.evals().len() - 1; - return Err(err_too_large_deree("open", pp.degree(), got)); + return Err(err_too_large_degree("open", pp.degree(), got)); } if cfg!(feature = "sanity-check") { @@ -439,12 +443,14 @@ mod test { type GemIpaPcs = Gemini>; #[test] + #[ignore = "we do not currently use gemini"] fn commit_open_verify() { run_commit_open_verify::<_, GemKzgPcs, Keccak256Transcript<_>>(); run_commit_open_verify::<_, GemIpaPcs, Keccak256Transcript<_>>(); } #[test] + #[ignore = "we do not currently use gemini"] fn batch_commit_open_verify() { run_batch_commit_open_verify::<_, GemKzgPcs, Keccak256Transcript<_>>(); run_batch_commit_open_verify::<_, GemIpaPcs, Keccak256Transcript<_>>(); diff --git a/plonkish_backend/src/pcs/multilinear/hyrax.rs b/plonkish_backend/src/pcs/multilinear/hyrax.rs index 45e3ecb0..f5fceae6 100644 --- a/plonkish_backend/src/pcs/multilinear/hyrax.rs +++ b/plonkish_backend/src/pcs/multilinear/hyrax.rs @@ -324,11 +324,13 @@ mod test { type Pcs = MultilinearHyrax; #[test] + #[ignore = "we do not currently use hyrax"] fn commit_open_verify() { run_commit_open_verify::<_, Pcs, Keccak256Transcript<_>>(); } #[test] + #[ignore = "we do not currently use hyrax"] fn batch_commit_open_verify() { run_batch_commit_open_verify::<_, Pcs, Keccak256Transcript<_>>(); } diff --git a/plonkish_backend/src/pcs/multilinear/ipa.rs b/plonkish_backend/src/pcs/multilinear/ipa.rs index a62c58b6..2c681273 100644 --- a/plonkish_backend/src/pcs/multilinear/ipa.rs +++ b/plonkish_backend/src/pcs/multilinear/ipa.rs @@ -136,7 +136,9 @@ where fn commit(pp: &Self::ProverParam, poly: &Self::Polynomial) -> Result { validate_input("commit", pp.num_vars(), [poly], None)?; - Ok(variable_base_msm(poly.evals(), pp.g()).into()).map(MultilinearIpaCommitment) + Ok(MultilinearIpaCommitment( + variable_base_msm(poly.evals(), pp.g()).into(), + )) } fn batch_commit<'a>( @@ -241,11 +243,13 @@ mod test { type Pcs = MultilinearIpa; #[test] + #[ignore = "we do not currently use multilinear IPA"] fn commit_open_verify() { run_commit_open_verify::<_, Pcs, Keccak256Transcript<_>>(); } #[test] + #[ignore = "we do not currently use multilinear IPA"] fn batch_commit_open_verify() { run_batch_commit_open_verify::<_, Pcs, Keccak256Transcript<_>>(); } diff --git a/plonkish_backend/src/pcs/multilinear/kzg.rs b/plonkish_backend/src/pcs/multilinear/kzg.rs index 3c375b4c..216cd485 100644 --- a/plonkish_backend/src/pcs/multilinear/kzg.rs +++ b/plonkish_backend/src/pcs/multilinear/kzg.rs @@ -241,8 +241,9 @@ where fn commit(pp: &Self::ProverParam, poly: &Self::Polynomial) -> Result { validate_input("commit", pp.num_vars(), [poly], None)?; - Ok(variable_base_msm(poly.evals(), pp.eq(poly.num_vars())).into()) - .map(MultilinearKzgCommitment) + Ok(MultilinearKzgCommitment( + variable_base_msm(poly.evals(), pp.eq(poly.num_vars())).into(), + )) } fn batch_commit<'a>( @@ -375,11 +376,13 @@ mod test { type Pcs = MultilinearKzg; #[test] + #[ignore = "we do not currently use multilinear KZG"] fn commit_open_verify() { run_commit_open_verify::<_, Pcs, Keccak256Transcript<_>>(); } #[test] + #[ignore = "we do not currently use multilinear KZG"] fn batch_commit_open_verify() { run_batch_commit_open_verify::<_, Pcs, Keccak256Transcript<_>>(); } diff --git a/plonkish_backend/src/pcs/multilinear/zeromorph.rs b/plonkish_backend/src/pcs/multilinear/zeromorph.rs index 81a71d69..929993b0 100644 --- a/plonkish_backend/src/pcs/multilinear/zeromorph.rs +++ b/plonkish_backend/src/pcs/multilinear/zeromorph.rs @@ -3,7 +3,7 @@ use crate::{ pcs::{ multilinear::{additive, quotients}, univariate::{ - err_too_large_deree, UnivariateIpa, UnivariateIpaCommitment, UnivariateKzg, + err_too_large_degree, UnivariateIpa, UnivariateIpaCommitment, UnivariateKzg, UnivariateKzgProverParam, UnivariateKzgVerifierParam, }, Evaluation, Point, PolynomialCommitmentScheme, @@ -112,7 +112,7 @@ where fn commit(pp: &Self::ProverParam, poly: &Self::Polynomial) -> Result { if pp.degree() + 1 < poly.evals().len() { let got = poly.evals().len() - 1; - return Err(err_too_large_deree("commit", pp.degree(), got)); + return Err(err_too_large_degree("commit", pp.degree(), got)); } Ok(UnivariateKzg::commit_monomial(&pp.commit_pp, poly.evals())) @@ -139,7 +139,7 @@ where let num_vars = poly.num_vars(); if pp.degree() + 1 < poly.evals().len() { let got = poly.evals().len() - 1; - return Err(err_too_large_deree("open", pp.degree(), got)); + return Err(err_too_large_degree("open", pp.degree(), got)); } if cfg!(feature = "sanity-check") { @@ -304,11 +304,13 @@ where fn commit(pp: &Self::ProverParam, poly: &Self::Polynomial) -> Result { if pp.degree() + 1 < poly.evals().len() { let got = poly.evals().len() - 1; - return Err(err_too_large_deree("commit", pp.degree(), got)); + return Err(err_too_large_degree("commit", pp.degree(), got)); } - let uni_poly = UnivariatePolynomial::monomial(poly.evals().to_vec()); - UnivariateIpa::commit(pp, &uni_poly) + let bases = pp.monomial(); + Ok(UnivariateIpaCommitment( + variable_base_msm(poly.evals(), &bases[..poly.evals().len()]).into(), + )) } fn batch_commit<'a>( @@ -332,7 +334,7 @@ where let num_vars = poly.num_vars(); if pp.degree() + 1 < poly.evals().len() { let got = poly.evals().len() - 1; - return Err(err_too_large_deree("open", pp.degree(), got)); + return Err(err_too_large_degree("open", pp.degree(), got)); } if cfg!(feature = "sanity-check") { diff --git a/plonkish_backend/src/pcs/univariate.rs b/plonkish_backend/src/pcs/univariate.rs index 41465148..00111d53 100644 --- a/plonkish_backend/src/pcs/univariate.rs +++ b/plonkish_backend/src/pcs/univariate.rs @@ -48,7 +48,7 @@ fn validate_input<'a, F: Field>( match poly.basis() { Monomial => { if param_degree < poly.degree() { - return Err(err_too_large_deree(function, param_degree, poly.degree())); + return Err(err_too_large_degree(function, param_degree, poly.degree())); } } Lagrange => { @@ -61,7 +61,7 @@ fn validate_input<'a, F: Field>( Ok(()) } -pub(super) fn err_too_large_deree(function: &str, upto: usize, got: usize) -> Error { +pub(super) fn err_too_large_degree(function: &str, upto: usize, got: usize) -> Error { Error::InvalidPcsParam(if function == "trim" { format!("Too large degree to {function} (param supports degree up to {upto} but got {got})") } else { diff --git a/plonkish_backend/src/pcs/univariate/hyrax.rs b/plonkish_backend/src/pcs/univariate/hyrax.rs index 32740105..f621f078 100644 --- a/plonkish_backend/src/pcs/univariate/hyrax.rs +++ b/plonkish_backend/src/pcs/univariate/hyrax.rs @@ -1,7 +1,7 @@ use crate::{ pcs::{ univariate::{ - additive, err_too_large_deree, + additive, err_too_large_degree, ipa::{UnivariateIpa, UnivariateIpaCommitment, UnivariateIpaParam}, validate_input, }, @@ -153,7 +153,7 @@ where let batch_k = (poly_size * batch_size).next_power_of_two().ilog2() as usize; let row_k = div_ceil(batch_k, 2); if param.row_k() < row_k { - return Err(err_too_large_deree("trim", param.degree(), poly_size - 1)); + return Err(err_too_large_degree("trim", param.degree(), poly_size - 1)); } let (ipa_pp, ipa_vp) = UnivariateIpa::trim(¶m.ipa, 1 << row_k, 0)?; @@ -362,12 +362,14 @@ mod test { type GrumpkinPcs = UnivariateHyrax; #[test] + #[ignore = "we do not currently use hyrax"] fn commit_open_verify() { run_commit_open_verify::<_, PastaPcs, Keccak256Transcript<_>>(); run_commit_open_verify::<_, GrumpkinPcs, Keccak256Transcript<_>>(); } #[test] + #[ignore = "we do not currently use hyrax"] fn batch_commit_open_verify() { run_batch_commit_open_verify::<_, PastaPcs, Keccak256Transcript<_>>(); run_batch_commit_open_verify::<_, GrumpkinPcs, Keccak256Transcript<_>>(); diff --git a/plonkish_backend/src/pcs/univariate/ipa.rs b/plonkish_backend/src/pcs/univariate/ipa.rs index 7f5782ef..9eed7951 100644 --- a/plonkish_backend/src/pcs/univariate/ipa.rs +++ b/plonkish_backend/src/pcs/univariate/ipa.rs @@ -1,6 +1,6 @@ use crate::{ pcs::{ - univariate::{additive, err_too_large_deree, validate_input}, + univariate::{additive, err_too_large_degree, validate_input}, Additive, Evaluation, Point, PolynomialCommitmentScheme, }, poly::{ @@ -136,7 +136,7 @@ where let k = poly_size.ilog2() as usize; if param.monomial.len() < poly_size { - return Err(err_too_large_deree("trim", param.degree(), poly_size - 1)); + return Err(err_too_large_degree("trim", param.degree(), poly_size - 1)); } let monomial = param.monomial[..poly_size].to_vec(); @@ -156,7 +156,9 @@ where let coeffs = poly.coeffs(); let bases = pp.monomial(); - Ok(variable_base_msm(coeffs, &bases[..coeffs.len()]).into()).map(UnivariateIpaCommitment) + Ok(UnivariateIpaCommitment( + variable_base_msm(coeffs, &bases[..coeffs.len()]).into(), + )) } fn batch_commit<'a>( diff --git a/plonkish_backend/src/pcs/univariate/kzg.rs b/plonkish_backend/src/pcs/univariate/kzg.rs index 646cca43..c11f68a0 100644 --- a/plonkish_backend/src/pcs/univariate/kzg.rs +++ b/plonkish_backend/src/pcs/univariate/kzg.rs @@ -1,6 +1,6 @@ use crate::{ pcs::{ - univariate::{additive, err_too_large_deree, monomial_g_to_lagrange_g, validate_input}, + univariate::{additive, err_too_large_degree, monomial_g_to_lagrange_g, validate_input}, Additive, Evaluation, Point, PolynomialCommitmentScheme, }, poly::univariate::{UnivariateBasis::*, UnivariatePolynomial}, @@ -252,7 +252,7 @@ where assert!(poly_size.is_power_of_two()); if param.monomial_g1.len() < poly_size { - return Err(err_too_large_deree("trim", param.degree(), poly_size - 1)); + return Err(err_too_large_degree("trim", param.degree(), poly_size - 1)); } let monomial_g1 = param.monomial_g1[..poly_size].to_vec(); diff --git a/plonkish_backend/src/piop/sum_check/classic/coeff.rs b/plonkish_backend/src/piop/sum_check/classic/coeff.rs index 091aa2a1..555069aa 100644 --- a/plonkish_backend/src/piop/sum_check/classic/coeff.rs +++ b/plonkish_backend/src/piop/sum_check/classic/coeff.rs @@ -205,9 +205,7 @@ fn poly<'a, F: PrimeField>( ) -> &'a MultilinearPolynomial { match expr { Expression::CommonPolynomial(CommonPolynomial::EqXY(idx)) => &state.eq_xys[*idx], - Expression::Polynomial(query) if query.rotation() == Rotation::cur() => { - &state.polys[&query] - } + Expression::Polynomial(query) if query.rotation() == Rotation::cur() => &state.polys[query], _ => unimplemented!(), } } diff --git a/plonkish_backend/src/util/code/brakedown.rs b/plonkish_backend/src/util/code/brakedown.rs index 9e47b434..47e9e4f5 100644 --- a/plonkish_backend/src/util/code/brakedown.rs +++ b/plonkish_backend/src/util/code/brakedown.rs @@ -371,6 +371,7 @@ mod test { #[rustfmt::skip] #[test] + #[ignore = "we do not currently use brakedown"] fn spec_127_bit_field() { assert_spec_correct::(127, 0.02, 6, 33, 13265, 2); assert_spec_correct::(127, 0.03, 7, 26, 8768, 2); @@ -382,6 +383,7 @@ mod test { #[rustfmt::skip] #[test] + #[ignore = "we do not currently use brakedown"] fn spec_254_bit_field() { assert_spec_correct::(254, 0.02, 6, 33, 13265, 1); assert_spec_correct::(254, 0.03, 7, 26, 8768, 1); From dcf5921d869891923b8a81622b3dfc123b1b56f3 Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Mon, 6 Jan 2025 17:09:50 +0000 Subject: [PATCH 22/35] working full hash test --- .../circuits/poseidongadget/poseidon/pow5.rs | 67 ++++++++++++------- 1 file changed, 43 insertions(+), 24 deletions(-) diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs index f0fdccd5..31a8a428 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs @@ -586,13 +586,14 @@ impl Pow5State { #[cfg(test)] mod tests { + use ff::Field; use halo2_curves::bn256::{Bn256, Fr}; - use halo2_curves::pasta::Fp; use halo2_proofs::{ circuit::{Layouter, SimpleFloorPlanner, Value}, plonk::{Circuit, ConstraintSystem, Error}, }; + use rand::rngs::OsRng; use super::{PoseidonInstructions, Pow5Chip, Pow5Config, StateWord}; use crate::circuits::poseidongadget::poseidon::{ primitives::{self as poseidon, BN256param as newParam, ConstantLength, Spec}, @@ -808,22 +809,22 @@ mod tests { } struct HashCircuit< - S: Spec, + S: Spec, const WIDTH: usize, const RATE: usize, const L: usize, > { - message: Value<[Fp; L]>, + message: Value<[Fr; L]>, // For the purpose of this test, witness the result. // TODO: Move this into an instance column. - output: Value, + output: Value, _spec: PhantomData, } - impl, const WIDTH: usize, const RATE: usize, const L: usize> - Circuit for HashCircuit + impl, const WIDTH: usize, const RATE: usize, const L: usize> + Circuit for HashCircuit { - type Config = Pow5Config; + type Config = Pow5Config; type FloorPlanner = SimpleFloorPlanner; #[cfg(feature = "circuit-params")] type Params = (); @@ -836,7 +837,7 @@ mod tests { } } - fn configure(meta: &mut ConstraintSystem) -> Pow5Config { + fn configure(meta: &mut ConstraintSystem) -> Pow5Config { let state = (0..WIDTH).map(|_| meta.advice_column()).collect::>(); let partial_sbox = meta.advice_column(); @@ -856,8 +857,8 @@ mod tests { fn synthesize( &self, - config: Pow5Config, - mut layouter: impl Layouter, + config: Pow5Config, + mut layouter: impl Layouter, ) -> Result<(), Error> { let chip = Pow5Chip::construct(config.clone()); @@ -900,26 +901,44 @@ mod tests { } } - /*#[ignore] + impl CircuitExt for HashCircuit, 5, 4, 4> { + fn instances(&self) -> Vec> { + /*let mut expected_final_state = (0..7) + .map(|idx| Fq::from(idx as u64)) + .collect::>() + .try_into() + .unwrap();*/ + Vec::new() + } + } + #[test] fn poseidon_hash() { - let rng = OsRng; - - let message = [Fp::random(rng), Fp::random(rng)]; + let message = [Fr::random(OsRng), Fr::random(OsRng),Fr::random(OsRng),Fr::random(OsRng)]; let output = - poseidon::Hash::<_, OrchardNullifier, ConstantLength<2>, 3, 2>::init().hash(message); - - let k = 6; - let circuit = HashCircuit:: { - message: Value::known(message), - output: Value::known(output), - _spec: PhantomData, + poseidon::Hash::<_, newParam<5, 4, 0>, ConstantLength<4>, 5, 4>::init().hash(message); + type Pb = HyperPlonk>>; + let circuit = + Halo2Circuit::new::(6, HashCircuit::, 5, 4, 4> { + message: Value::known(message), + output: Value::known(output), + _spec: PhantomData, + }); + let param = Pb::setup(&circuit.circuit_info().unwrap(), seeded_std_rng()).unwrap(); + let (pp, vp) = Pb::preprocess(¶m, &circuit.circuit_info().unwrap()).unwrap(); + let proof = { + let mut transcript = Keccak256Transcript::new(()); + Pb::prove(&pp, &circuit, &mut transcript, seeded_std_rng()).unwrap(); + transcript.into_proof() }; - let prover = MockProver::run::<_, true>(k, &circuit, vec![]).unwrap(); - assert_eq!(prover.verify(), Ok(())) + let result = { + let mut transcript = Keccak256Transcript::from_proof((), proof.as_slice()); + Pb::verify(&vp, circuit.instances(), &mut transcript, seeded_std_rng()) + }; + assert_eq!(result, Ok(())) } - #[ignore] + /*#[ignore] #[test] fn poseidon_hash_longer_input() { let rng = OsRng; From bd0f57dc487093b7d9a7ba9b489142299cda41df Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Mon, 6 Jan 2025 17:14:38 +0000 Subject: [PATCH 23/35] fix lint errors --- .../circuits/poseidongadget/poseidon/pow5.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs index 31a8a428..79465c7c 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs @@ -593,12 +593,12 @@ mod tests { plonk::{Circuit, ConstraintSystem, Error}, }; - use rand::rngs::OsRng; use super::{PoseidonInstructions, Pow5Chip, Pow5Config, StateWord}; use crate::circuits::poseidongadget::poseidon::{ primitives::{self as poseidon, BN256param as newParam, ConstantLength, Spec}, Hash, }; + use rand::rngs::OsRng; use std::convert::TryInto; use std::marker::PhantomData; @@ -914,16 +914,23 @@ mod tests { #[test] fn poseidon_hash() { - let message = [Fr::random(OsRng), Fr::random(OsRng),Fr::random(OsRng),Fr::random(OsRng)]; + let message = [ + Fr::random(OsRng), + Fr::random(OsRng), + Fr::random(OsRng), + Fr::random(OsRng) + ]; let output = poseidon::Hash::<_, newParam<5, 4, 0>, ConstantLength<4>, 5, 4>::init().hash(message); type Pb = HyperPlonk>>; - let circuit = - Halo2Circuit::new::(6, HashCircuit::, 5, 4, 4> { + let circuit = Halo2Circuit::new::( + 6, + HashCircuit::, 5, 4, 4> { message: Value::known(message), output: Value::known(output), _spec: PhantomData, - }); + } + ); let param = Pb::setup(&circuit.circuit_info().unwrap(), seeded_std_rng()).unwrap(); let (pp, vp) = Pb::preprocess(¶m, &circuit.circuit_info().unwrap()).unwrap(); let proof = { From d5fb490909310bfd7ae8a2f44e94ae4219f0a53a Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Mon, 6 Jan 2025 17:16:45 +0000 Subject: [PATCH 24/35] fix lint errors --- .../src/circuits/poseidongadget/poseidon/pow5.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs index 79465c7c..92b42025 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs @@ -918,18 +918,18 @@ mod tests { Fr::random(OsRng), Fr::random(OsRng), Fr::random(OsRng), - Fr::random(OsRng) + Fr::random(OsRng), ]; let output = poseidon::Hash::<_, newParam<5, 4, 0>, ConstantLength<4>, 5, 4>::init().hash(message); type Pb = HyperPlonk>>; let circuit = Halo2Circuit::new::( - 6, + 6, HashCircuit::, 5, 4, 4> { message: Value::known(message), output: Value::known(output), _spec: PhantomData, - } + }, ); let param = Pb::setup(&circuit.circuit_info().unwrap(), seeded_std_rng()).unwrap(); let (pp, vp) = Pb::preprocess(¶m, &circuit.circuit_info().unwrap()).unwrap(); From f1449a6a6b54789b21566ae7a9be796d30d5a157 Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Mon, 6 Jan 2025 17:17:42 +0000 Subject: [PATCH 25/35] fix lint errors --- plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs index 92b42025..dc299c7b 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs @@ -915,7 +915,7 @@ mod tests { #[test] fn poseidon_hash() { let message = [ - Fr::random(OsRng), + Fr::random(OsRng), Fr::random(OsRng), Fr::random(OsRng), Fr::random(OsRng), From e2e7a5646aaf6ae0434812ff38ca9db9376e6277 Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Wed, 8 Jan 2025 13:26:31 +0000 Subject: [PATCH 26/35] chore: poseidon longer input tests and delete unnecessary ones --- .../circuits/poseidongadget/poseidon/pow5.rs | 94 ++++++++----------- 1 file changed, 39 insertions(+), 55 deletions(-) diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs index dc299c7b..be703b3a 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs @@ -350,6 +350,7 @@ impl< )?, _ => panic!("Input is not padded"), }; + // TO DO: the Synthesis error in poseidon_hash_longer_input occurs here when i =1 (the input is padding) constraint_var .copy_advice( || format!("load input_{i}"), @@ -861,7 +862,6 @@ mod tests { mut layouter: impl Layouter, ) -> Result<(), Error> { let chip = Pow5Chip::construct(config.clone()); - let message = layouter.assign_region( || "load message", |mut region| { @@ -884,6 +884,7 @@ mod tests { chip, layouter.namespace(|| "init"), )?; + //TO DO: add_input called here leading to error in poseidon_hash_longer_input let output = hasher.hash(layouter.namespace(|| "hash"), message)?; layouter.assign_region( @@ -912,6 +913,17 @@ mod tests { } } + impl CircuitExt for HashCircuit, 3, 2, 3> { + fn instances(&self) -> Vec> { + /*let mut expected_final_state = (0..7) + .map(|idx| Fq::from(idx as u64)) + .collect::>() + .try_into() + .unwrap();*/ + Vec::new() + } + } + #[test] fn poseidon_hash() { let message = [ @@ -945,65 +957,37 @@ mod tests { assert_eq!(result, Ok(())) } - /*#[ignore] + // This test is ignored because there is an error that should be fixed. + #[ignore] #[test] fn poseidon_hash_longer_input() { - let rng = OsRng; - - let message = [Fp::random(rng), Fp::random(rng), Fp::random(rng)]; + let message = [ + Fr::random(OsRng), + Fr::random(OsRng), + Fr::random(OsRng), + ]; let output = - poseidon::Hash::<_, OrchardNullifier, ConstantLength<3>, 3, 2>::init().hash(message); - - let k = 7; - let circuit = HashCircuit:: { - message: Value::known(message), - output: Value::known(output), - _spec: PhantomData, - }; - let prover = MockProver::run::<_, true>(k, &circuit, vec![]).unwrap(); - assert_eq!(prover.verify(), Ok(())) - } - - #[ignore] - #[test] - fn hash_test_vectors() { - for tv in crate::circuits::poseidongadget::poseidon::primitives::test_vectors::fp::hash() { - let message = [ - pallas::Base::from_repr(tv.input[0]).unwrap(), - pallas::Base::from_repr(tv.input[1]).unwrap(), - ]; - let output = poseidon::Hash::<_, OrchardNullifier, ConstantLength<2>, 3, 2>::init() - .hash(message); - - let k = 6; - let circuit = HashCircuit:: { + poseidon::Hash::<_, newParam<3, 2, 0>, ConstantLength<3>, 3, 2>::init().hash(message); + type Pb = HyperPlonk>>; + let circuit = Halo2Circuit::new::( + 7, + HashCircuit::, 3, 2, 3> { message: Value::known(message), output: Value::known(output), _spec: PhantomData, - }; - let prover = MockProver::run::<_, true>(k, &circuit, vec![]).unwrap(); - assert_eq!(prover.verify(), Ok(())); - } - } - - #[cfg(feature = "test-dev-graph")] - #[test] - fn print_poseidon_chip() { - use plotters::prelude::*; - - let root = BitMapBackend::new("poseidon-chip-layout.png", (1024, 768)).into_drawing_area(); - root.fill(&WHITE).unwrap(); - let root = root - .titled("Poseidon Chip Layout", ("sans-serif", 60)) - .unwrap(); - - let circuit = HashCircuit:: { - message: Value::unknown(), - output: Value::unknown(), - _spec: PhantomData, + }, + ); + let param = Pb::setup(&circuit.circuit_info().unwrap(), seeded_std_rng()).unwrap(); + let (pp, vp) = Pb::preprocess(¶m, &circuit.circuit_info().unwrap()).unwrap(); + let proof = { + let mut transcript = Keccak256Transcript::new(()); + Pb::prove(&pp, &circuit, &mut transcript, seeded_std_rng()).unwrap(); + transcript.into_proof() }; - halo2_proofs::dev::CircuitLayout::default() - .render(6, &circuit, &root) - .unwrap(); - }*/ + let result = { + let mut transcript = Keccak256Transcript::from_proof((), proof.as_slice()); + Pb::verify(&vp, circuit.instances(), &mut transcript, seeded_std_rng()) + }; + assert_eq!(result, Ok(())) + } } From 351e3678ad1a202834d2500a3d6ac48768b84456 Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Wed, 8 Jan 2025 13:53:48 +0000 Subject: [PATCH 27/35] fix: lint error --- .../src/circuits/poseidongadget/poseidon/pow5.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs index be703b3a..8ba546fb 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs @@ -957,15 +957,11 @@ mod tests { assert_eq!(result, Ok(())) } - // This test is ignored because there is an error that should be fixed. + // This test is ignored because there is an error that should be fixed. The error is on line 353 of this file, in the add_input function. #[ignore] #[test] fn poseidon_hash_longer_input() { - let message = [ - Fr::random(OsRng), - Fr::random(OsRng), - Fr::random(OsRng), - ]; + let message = [Fr::random(OsRng), Fr::random(OsRng), Fr::random(OsRng)]; let output = poseidon::Hash::<_, newParam<3, 2, 0>, ConstantLength<3>, 3, 2>::init().hash(message); type Pb = HyperPlonk>>; From 95ecf4ee02860a9209454c0e4851f0c08b7954f0 Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Wed, 8 Jan 2025 16:30:10 +0000 Subject: [PATCH 28/35] test for all input lengths using macros --- .../circuits/poseidongadget/poseidon/pow5.rs | 184 +++++++++++------- 1 file changed, 117 insertions(+), 67 deletions(-) diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs index 8ba546fb..5397b436 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs @@ -713,42 +713,65 @@ mod tests { } } - impl CircuitExt for PermuteCircuit, 5, 4> { - fn instances(&self) -> Vec> { - /*let mut expected_final_state = (0..7) - .map(|idx| Fq::from(idx as u64)) - .collect::>() - .try_into() - .unwrap();*/ - Vec::new() + macro_rules! impl_circuit_ext { + ($($n:expr, $m:expr),*) => { + $( + impl CircuitExt for PermuteCircuit, $n, $m> { + fn instances(&self) -> Vec> { + /*let mut expected_final_state = (0..7) + .map(|idx| Fq::from(idx as u64)) + .collect::>() + .try_into() + .unwrap();*/ + Vec::new() + } + } + )* } } + + impl_circuit_ext!( + 2, 1, + 3, 2, + 4, 3, + 5, 4, + 6, 5, + 7, 6 + ); - /* #[test] - fn poseidon_permute() { - let k = 6; - let circuit = PermuteCircuit::(PhantomData); - let prover = MockProver::run::<_, true>(k, &circuit, vec![]).unwrap(); - assert_eq!(prover.verify(), Ok(())) - }*/ #[test] - fn poseidon_permute_new_param() { + fn poseidon_permute() { type Pb = HyperPlonk>>; - let circuit = - Halo2Circuit::new::(6, PermuteCircuit::, 5, 4>(PhantomData)); - let param = Pb::setup(&circuit.circuit_info().unwrap(), seeded_std_rng()).unwrap(); - let (pp, vp) = Pb::preprocess(¶m, &circuit.circuit_info().unwrap()).unwrap(); - let proof = { - let mut transcript = Keccak256Transcript::new(()); - Pb::prove(&pp, &circuit, &mut transcript, seeded_std_rng()).unwrap(); - transcript.into_proof() - }; - let result = { - let mut transcript = Keccak256Transcript::from_proof((), proof.as_slice()); - Pb::verify(&vp, circuit.instances(), &mut transcript, seeded_std_rng()) - }; - assert_eq!(result, Ok(())) - //assert!(false) + macro_rules! test_poseidon_permute { + ($i:expr, $j:expr) => { + { + let circuit = Halo2Circuit::new::(6, PermuteCircuit::, $j, $i>(PhantomData)); + let param = Pb::setup(&circuit.circuit_info().unwrap(), seeded_std_rng()).unwrap(); + let (pp, vp) = Pb::preprocess(¶m, &circuit.circuit_info().unwrap()).unwrap(); + let proof = { + let mut transcript = Keccak256Transcript::new(()); + Pb::prove(&pp, &circuit, &mut transcript, seeded_std_rng()).unwrap(); + transcript.into_proof() + }; + let result = { + let mut transcript = Keccak256Transcript::from_proof((), proof.as_slice()); + Pb::verify(&vp, circuit.instances(), &mut transcript, seeded_std_rng()) + }; + assert_eq!(result, Ok(())) + } + }; + } + for i in 2..7 { + match i { + 1 => test_poseidon_permute!(1,2), + 2 => test_poseidon_permute!(2,3), + 3 => test_poseidon_permute!(3,4), + 4 => test_poseidon_permute!(4,5), + 5 => test_poseidon_permute!(5,6), + 6 => test_poseidon_permute!(6,7), + _ => unreachable!(), + } + } /*let k =6; let circuit = PermuteCircuit::, 7, 6>(PhantomData); @@ -902,16 +925,31 @@ mod tests { } } - impl CircuitExt for HashCircuit, 5, 4, 4> { - fn instances(&self) -> Vec> { - /*let mut expected_final_state = (0..7) - .map(|idx| Fq::from(idx as u64)) - .collect::>() - .try_into() - .unwrap();*/ - Vec::new() + macro_rules! impl_circuit_ext { + ($($n:expr, $m:expr),*) => { + $( + impl CircuitExt for HashCircuit, $n, $m, $m> { + fn instances(&self) -> Vec> { + /*let mut expected_final_state = (0..7) + .map(|idx| Fq::from(idx as u64)) + .collect::>() + .try_into() + .unwrap();*/ + Vec::new() + } + } + )* } } + + impl_circuit_ext!( + 2, 1, + 3, 2, + 4, 3, + 5, 4, + 6, 5, + 7, 6 + ); impl CircuitExt for HashCircuit, 3, 2, 3> { fn instances(&self) -> Vec> { @@ -926,35 +964,47 @@ mod tests { #[test] fn poseidon_hash() { - let message = [ - Fr::random(OsRng), - Fr::random(OsRng), - Fr::random(OsRng), - Fr::random(OsRng), - ]; - let output = - poseidon::Hash::<_, newParam<5, 4, 0>, ConstantLength<4>, 5, 4>::init().hash(message); type Pb = HyperPlonk>>; - let circuit = Halo2Circuit::new::( - 6, - HashCircuit::, 5, 4, 4> { - message: Value::known(message), - output: Value::known(output), - _spec: PhantomData, - }, - ); - let param = Pb::setup(&circuit.circuit_info().unwrap(), seeded_std_rng()).unwrap(); - let (pp, vp) = Pb::preprocess(¶m, &circuit.circuit_info().unwrap()).unwrap(); - let proof = { - let mut transcript = Keccak256Transcript::new(()); - Pb::prove(&pp, &circuit, &mut transcript, seeded_std_rng()).unwrap(); - transcript.into_proof() - }; - let result = { - let mut transcript = Keccak256Transcript::from_proof((), proof.as_slice()); - Pb::verify(&vp, circuit.instances(), &mut transcript, seeded_std_rng()) - }; - assert_eq!(result, Ok(())) + macro_rules! test_poseidon_hash { + ($i:expr, $j:expr) => { + { + let message: [Fr; $i] = [Fr::random(OsRng); $i]; + let output = + poseidon::Hash::<_, newParam<$j, $i, 0>, ConstantLength<$i>, $j, $i>::init().hash(message); + let circuit = Halo2Circuit::new::( + 6, + HashCircuit::, $j, $i, $i> { + message: Value::known(message), + output: Value::known(output), + _spec: PhantomData, + }, + ); + let param = Pb::setup(&circuit.circuit_info().unwrap(), seeded_std_rng()).unwrap(); + let (pp, vp) = Pb::preprocess(¶m, &circuit.circuit_info().unwrap()).unwrap(); + let proof = { + let mut transcript = Keccak256Transcript::new(()); + Pb::prove(&pp, &circuit, &mut transcript, seeded_std_rng()).unwrap(); + transcript.into_proof() + }; + let result = { + let mut transcript = Keccak256Transcript::from_proof((), proof.as_slice()); + Pb::verify(&vp, circuit.instances(), &mut transcript, seeded_std_rng()) + }; + assert_eq!(result, Ok(())) + } + }; + } + for i in 2..7 { + match i { + 1 => test_poseidon_hash!(1,2), + 2 => test_poseidon_hash!(2,3), + 3 => test_poseidon_hash!(3,4), + 4 => test_poseidon_hash!(4,5), + 5 => test_poseidon_hash!(5,6), + 6 => test_poseidon_hash!(6,7), + _ => unreachable!(), + } + } } // This test is ignored because there is an error that should be fixed. The error is on line 353 of this file, in the add_input function. From b187f219f5c95802fcb3bf7282db62e0c43e492b Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Wed, 8 Jan 2025 16:36:25 +0000 Subject: [PATCH 29/35] fix: lint errors --- .../circuits/poseidongadget/poseidon/pow5.rs | 129 ++++++++---------- 1 file changed, 57 insertions(+), 72 deletions(-) diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs index 5397b436..ff23fef8 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs @@ -730,45 +730,39 @@ mod tests { } } - impl_circuit_ext!( - 2, 1, - 3, 2, - 4, 3, - 5, 4, - 6, 5, - 7, 6 - ); + impl_circuit_ext!(2, 1, 3, 2, 4, 3, 5, 4, 6, 5, 7, 6); #[test] fn poseidon_permute() { type Pb = HyperPlonk>>; macro_rules! test_poseidon_permute { - ($i:expr, $j:expr) => { - { - let circuit = Halo2Circuit::new::(6, PermuteCircuit::, $j, $i>(PhantomData)); - let param = Pb::setup(&circuit.circuit_info().unwrap(), seeded_std_rng()).unwrap(); - let (pp, vp) = Pb::preprocess(¶m, &circuit.circuit_info().unwrap()).unwrap(); - let proof = { - let mut transcript = Keccak256Transcript::new(()); - Pb::prove(&pp, &circuit, &mut transcript, seeded_std_rng()).unwrap(); - transcript.into_proof() - }; - let result = { - let mut transcript = Keccak256Transcript::from_proof((), proof.as_slice()); - Pb::verify(&vp, circuit.instances(), &mut transcript, seeded_std_rng()) - }; - assert_eq!(result, Ok(())) - } - }; + ($i:expr, $j:expr) => {{ + let circuit = Halo2Circuit::new::( + 6, + PermuteCircuit::, $j, $i>(PhantomData) + ); + let param = Pb::setup(&circuit.circuit_info().unwrap(), seeded_std_rng()).unwrap(); + let (pp, vp) = Pb::preprocess(¶m, &circuit.circuit_info().unwrap()).unwrap(); + let proof = { + let mut transcript = Keccak256Transcript::new(()); + Pb::prove(&pp, &circuit, &mut transcript, seeded_std_rng()).unwrap(); + transcript.into_proof() + }; + let result = { + let mut transcript = Keccak256Transcript::from_proof((), proof.as_slice()); + Pb::verify(&vp, circuit.instances(), &mut transcript, seeded_std_rng()) + }; + assert_eq!(result, Ok(())) + }}; } for i in 2..7 { match i { - 1 => test_poseidon_permute!(1,2), - 2 => test_poseidon_permute!(2,3), - 3 => test_poseidon_permute!(3,4), - 4 => test_poseidon_permute!(4,5), - 5 => test_poseidon_permute!(5,6), - 6 => test_poseidon_permute!(6,7), + 1 => test_poseidon_permute!(1, 2), + 2 => test_poseidon_permute!(2, 3), + 3 => test_poseidon_permute!(3, 4), + 4 => test_poseidon_permute!(4, 5), + 5 => test_poseidon_permute!(5, 6), + 6 => test_poseidon_permute!(6, 7), _ => unreachable!(), } } @@ -942,14 +936,7 @@ mod tests { } } - impl_circuit_ext!( - 2, 1, - 3, 2, - 4, 3, - 5, 4, - 6, 5, - 7, 6 - ); + impl_circuit_ext!(2, 1, 3, 2, 4, 3, 5, 4, 6, 5, 7, 6); impl CircuitExt for HashCircuit, 3, 2, 3> { fn instances(&self) -> Vec> { @@ -966,42 +953,40 @@ mod tests { fn poseidon_hash() { type Pb = HyperPlonk>>; macro_rules! test_poseidon_hash { - ($i:expr, $j:expr) => { - { - let message: [Fr; $i] = [Fr::random(OsRng); $i]; - let output = - poseidon::Hash::<_, newParam<$j, $i, 0>, ConstantLength<$i>, $j, $i>::init().hash(message); - let circuit = Halo2Circuit::new::( - 6, - HashCircuit::, $j, $i, $i> { - message: Value::known(message), - output: Value::known(output), - _spec: PhantomData, - }, - ); - let param = Pb::setup(&circuit.circuit_info().unwrap(), seeded_std_rng()).unwrap(); - let (pp, vp) = Pb::preprocess(¶m, &circuit.circuit_info().unwrap()).unwrap(); - let proof = { - let mut transcript = Keccak256Transcript::new(()); - Pb::prove(&pp, &circuit, &mut transcript, seeded_std_rng()).unwrap(); - transcript.into_proof() - }; - let result = { - let mut transcript = Keccak256Transcript::from_proof((), proof.as_slice()); - Pb::verify(&vp, circuit.instances(), &mut transcript, seeded_std_rng()) - }; - assert_eq!(result, Ok(())) - } - }; + ($i:expr, $j:expr) => {{ + let message: [Fr; $i] = [Fr::random(OsRng); $i]; + let output = + poseidon::Hash::<_, newParam<$j, $i, 0>, ConstantLength<$i>, $j, $i>::init().hash(message); + let circuit = Halo2Circuit::new::( + 6, + HashCircuit::, $j, $i, $i> { + message: Value::known(message), + output: Value::known(output), + _spec: PhantomData, + }, + ); + let param = Pb::setup(&circuit.circuit_info().unwrap(), seeded_std_rng()).unwrap(); + let (pp, vp) = Pb::preprocess(¶m, &circuit.circuit_info().unwrap()).unwrap(); + let proof = { + let mut transcript = Keccak256Transcript::new(()); + Pb::prove(&pp, &circuit, &mut transcript, seeded_std_rng()).unwrap(); + transcript.into_proof() + }; + let result = { + let mut transcript = Keccak256Transcript::from_proof((), proof.as_slice()); + Pb::verify(&vp, circuit.instances(), &mut transcript, seeded_std_rng()) + }; + assert_eq!(result, Ok(())) + }}; } for i in 2..7 { match i { - 1 => test_poseidon_hash!(1,2), - 2 => test_poseidon_hash!(2,3), - 3 => test_poseidon_hash!(3,4), - 4 => test_poseidon_hash!(4,5), - 5 => test_poseidon_hash!(5,6), - 6 => test_poseidon_hash!(6,7), + 1 => test_poseidon_hash!(1, 2), + 2 => test_poseidon_hash!(2, 3), + 3 => test_poseidon_hash!(3, 4), + 4 => test_poseidon_hash!(4, 5), + 5 => test_poseidon_hash!(5, 6), + 6 => test_poseidon_hash!(6, 7), _ => unreachable!(), } } From 3b518837cf3f4b7a9a48174a671b47a94a93c3ca Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Wed, 8 Jan 2025 16:39:23 +0000 Subject: [PATCH 30/35] fix: lint error --- .../src/circuits/poseidongadget/poseidon/pow5.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs index ff23fef8..ced3ed1f 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs @@ -738,8 +738,8 @@ mod tests { macro_rules! test_poseidon_permute { ($i:expr, $j:expr) => {{ let circuit = Halo2Circuit::new::( - 6, - PermuteCircuit::, $j, $i>(PhantomData) + 6, + PermuteCircuit::, $j, $i>(PhantomData), ); let param = Pb::setup(&circuit.circuit_info().unwrap(), seeded_std_rng()).unwrap(); let (pp, vp) = Pb::preprocess(¶m, &circuit.circuit_info().unwrap()).unwrap(); @@ -935,7 +935,7 @@ mod tests { )* } } - + impl_circuit_ext!(2, 1, 3, 2, 4, 3, 5, 4, 6, 5, 7, 6); impl CircuitExt for HashCircuit, 3, 2, 3> { @@ -956,7 +956,8 @@ mod tests { ($i:expr, $j:expr) => {{ let message: [Fr; $i] = [Fr::random(OsRng); $i]; let output = - poseidon::Hash::<_, newParam<$j, $i, 0>, ConstantLength<$i>, $j, $i>::init().hash(message); + poseidon::Hash::<_, newParam<$j, $i, 0>, ConstantLength<$i>, $j, $i>::init() + .hash(message); let circuit = Halo2Circuit::new::( 6, HashCircuit::, $j, $i, $i> { From 0defc6a9465effe5598233e0b55e2fa6a6824cf4 Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Wed, 8 Jan 2025 16:40:39 +0000 Subject: [PATCH 31/35] fix: lint error --- plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs index ced3ed1f..1c3f7e05 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs @@ -729,7 +729,7 @@ mod tests { )* } } - + impl_circuit_ext!(2, 1, 3, 2, 4, 3, 5, 4, 6, 5, 7, 6); #[test] From ec339c1af45db000c07109f6fb32a072e385d9a4 Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Wed, 8 Jan 2025 17:05:36 +0000 Subject: [PATCH 32/35] remove unnecessary tests and change test to BN256 --- .../poseidongadget/poseidon/primitives.rs | 21 ++++---- .../poseidon/primitives/bn256param.rs | 49 ------------------- 2 files changed, 10 insertions(+), 60 deletions(-) diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives.rs index c81f35e0..ceb5ef56 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives.rs @@ -381,24 +381,23 @@ impl, const T: usize, const RATE: usize, cons #[cfg(test)] mod tests { - //use super::{permute, ConstantLength, Hash, Spec}; - //use ff::PrimeField; - //use halo2_curves::pasta::pallas; + use super::{permute, ConstantLength, Hash, Spec, BN256param}; + use ff::PrimeField; + use halo2_curves::bn256::Fr; - /*#[ignore] #[test] - fn orchard_spec_equivalence() { - let message = [pallas::Base::from(6), pallas::Base::from(42)]; + fn bn256_spec_equivalence() { + let message = [Fr::from(6), Fr::from(42)]; - let (round_constants, mds, _) = OrchardNullifier::constants(); + let (round_constants, mds, _) = BN256param::<3,2,0>::constants(); - let hasher = Hash::<_, OrchardNullifier, ConstantLength<2>, 3, 2>::init(); + let hasher = Hash::<_, BN256param<3, 2, 0>, ConstantLength<2>, 3, 2>::init(); let result = hasher.hash(message); // The result should be equivalent to just directly applying the permutation and // taking the first state element as the output. - let mut state = [message[0], message[1], pallas::Base::from_u128(2 << 64)]; - permute::<_, OrchardNullifier, 3, 2>(&mut state, &mds, &round_constants); + let mut state = [message[0], message[1], Fr::from_u128(2 << 64)]; + permute::<_, BN256param<3, 2, 0>, 3, 2>(&mut state, &mds, &round_constants); assert_eq!(state[0], result); - }*/ + } } diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs index 5e2cf605..481fc414 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs @@ -116,53 +116,4 @@ mod tests { } } - #[test] - #[ignore] - fn verify_constants() { - // TO DO: write this as in p128pow5t3.rs once we have the constants manually generated - } - - #[test] - #[ignore] - fn test_against_reference() { - // TO DO: write this as in p128pow5t3.rs once we have the constants manually generated - } - - #[test] - #[ignore] - fn permute_test_vectors() { - - /* macro_rules! permute_test_vectors { - ($t:expr) => { - { - r = $t - 1; - let (round_constants, mds, _) = super::BN256param::<$t,r>::constants(); - - // Generate test vectors for the permutation - for tv in crate::frontend::halo2::poseidongadget::poseidon::primitives::test_vectors::fp::permute() { - let mut state = [ - Fp::from_repr(tv.initial_state[0]).unwrap(), - Fp::from_repr(tv.initial_state[1]).unwrap(), - Fp::from_repr(tv.initial_state[2]).unwrap(), - ]; - - permute::, $t, r>(&mut state, &mds, &round_constants); - - for (expected, actual) in tv.final_state.iter().zip(state.iter()) { - assert_eq!(&actual.to_repr(), expected); - } - } - } - - }; - } - for t in 1..7 { - permute_test_vectors!(t); - }*/ - } - - #[test] - #[ignore] - // Generate test vectors for the permutation and adapt this - fn hash_test_vectors() {} } From cbfa4cebff8392ce0887cfdcaf05153c89818903 Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Wed, 8 Jan 2025 17:10:31 +0000 Subject: [PATCH 33/35] fix lint errors --- .../src/circuits/poseidongadget/poseidon/primitives.rs | 4 ++-- .../circuits/poseidongadget/poseidon/primitives/bn256param.rs | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives.rs index ceb5ef56..23d1b92c 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives.rs @@ -381,7 +381,7 @@ impl, const T: usize, const RATE: usize, cons #[cfg(test)] mod tests { - use super::{permute, ConstantLength, Hash, Spec, BN256param}; + use super::{permute, BN256param, ConstantLength, Hash, Spec}; use ff::PrimeField; use halo2_curves::bn256::Fr; @@ -389,7 +389,7 @@ mod tests { fn bn256_spec_equivalence() { let message = [Fr::from(6), Fr::from(42)]; - let (round_constants, mds, _) = BN256param::<3,2,0>::constants(); + let (round_constants, mds, _) = BN256param::<3, 2, 0>::constants(); let hasher = Hash::<_, BN256param<3, 2, 0>, ConstantLength<2>, 3, 2>::init(); let result = hasher.hash(message); diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs index 481fc414..cac79fb3 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/primitives/bn256param.rs @@ -115,5 +115,4 @@ mod tests { generate_constants::<_, Self, T, R>() } } - } From c6de962a3833290164eec1c618ff1f9c0546e1ca Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Wed, 8 Jan 2025 17:31:40 +0000 Subject: [PATCH 34/35] remove comments --- .../circuits/poseidongadget/poseidon/pow5.rs | 73 ------------------- 1 file changed, 73 deletions(-) diff --git a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs index 1c3f7e05..68669357 100644 --- a/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs +++ b/plonkish_backend/src/circuits/poseidongadget/poseidon/pow5.rs @@ -718,11 +718,6 @@ mod tests { $( impl CircuitExt for PermuteCircuit, $n, $m> { fn instances(&self) -> Vec> { - /*let mut expected_final_state = (0..7) - .map(|idx| Fq::from(idx as u64)) - .collect::>() - .try_into() - .unwrap();*/ Vec::new() } } @@ -766,64 +761,6 @@ mod tests { _ => unreachable!(), } } - - /*let k =6; - let circuit = PermuteCircuit::, 7, 6>(PhantomData); - let prover = MockProver::run::<_, false>(k, &circuit, vec![]).unwrap(); - //assert_eq!(prover.verify(), Ok(())) - prover.assert_satisfied()*/ - - /*let k =6; - let circuit = PermuteCircuit::, 7, 6>(PhantomData); - let prover = MockProver::run::<_, true>(k, &circuit, vec![]).unwrap(); - //assert_eq!(prover.verify(), Ok(())) - prover.assert_satisfied()*/ - - /*let k =6; - let params = ParamsKZG::::setup(k, seeded_std_rng()); - let circuit = PermuteCircuit::, 7, 6>(PhantomData); - let vk = - keygen_vk::<_, _, _, true>(¶ms, &circuit).expect("keygen_vk should not fail"); - let pk = keygen_pk::<_, _, _, true>(¶ms, vk, &circuit) - .expect("keygen_pk should not fail"); - let instances_vec: Vec<&[Fr]> = Vec::new(); - let instances: &[&[Fr]] = &instances_vec; - let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); - create_proof::< - KZGCommitmentScheme, - ProverGWC<'_, Bn256>, - _, - _, - _, - _, - true, - >( - ¶ms, - &pk, - &[circuit], - &[instances], - seeded_std_rng(), - &mut transcript, - ) - .expect("prover should not fail"); - let proof = transcript.finalize(); - let strategy = SingleStrategy::new(¶ms); - let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]); - let result = verify_proof::< - KZGCommitmentScheme, - VerifierGWC<'_, Bn256>, - _, - _, - SingleStrategy<'_, Bn256>, - true, - >( - ¶ms, - pk.get_vk(), - strategy, - &[instances], - &mut transcript - ).is_ok(); - assert!(result)*/ } struct HashCircuit< @@ -924,11 +861,6 @@ mod tests { $( impl CircuitExt for HashCircuit, $n, $m, $m> { fn instances(&self) -> Vec> { - /*let mut expected_final_state = (0..7) - .map(|idx| Fq::from(idx as u64)) - .collect::>() - .try_into() - .unwrap();*/ Vec::new() } } @@ -940,11 +872,6 @@ mod tests { impl CircuitExt for HashCircuit, 3, 2, 3> { fn instances(&self) -> Vec> { - /*let mut expected_final_state = (0..7) - .map(|idx| Fq::from(idx as u64)) - .collect::>() - .try_into() - .unwrap();*/ Vec::new() } } From 6767cee6fe485f95ad407becf7f77097a7afcaa8 Mon Sep 17 00:00:00 2001 From: Lydia Garms Date: Wed, 8 Jan 2025 17:35:53 +0000 Subject: [PATCH 35/35] remove comments --- plonkish_backend/Cargo.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/plonkish_backend/Cargo.toml b/plonkish_backend/Cargo.toml index 98519583..3670971d 100644 --- a/plonkish_backend/Cargo.toml +++ b/plonkish_backend/Cargo.toml @@ -16,7 +16,6 @@ serde = { version = "1.0", features = ["derive"] } bincode = "1.3.3" sha3 = "0.10.6" poseidon = { git = "https://github.com/han0110/poseidon", branch = "feature/with-spec" } -# TO DO - remove these 4 lines? ff = { version = "0.13", features = ["bits"] } group = "0.13" proptest = { version = "1.0.0", optional = true } @@ -35,7 +34,6 @@ halo2_proofs = { git = "https://github.com/han0110/halo2.git", branch = "feature paste = "1.0.11" criterion = "0.4.0" pprof = { version = "0.11.0", features = ["criterion", "flamegraph"] } -# remove below line? proptest = "1.0.0" [features]