From fa30cc25ebd0bd3e86bc681d4bf031db2fd5a289 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Thu, 17 Oct 2024 15:04:39 +0200 Subject: [PATCH 1/7] Arrabbiata: intro the notion of ArrabbiataCurve Replicating the idea of KimchiCurve. --- arrabbiata/src/curve.rs | 73 +++++++++++++++++++++++++++++++++++++++ arrabbiata/src/lib.rs | 1 + arrabbiata/src/prover.rs | 7 ++-- arrabbiata/src/witness.rs | 17 ++++----- kimchi/src/curve.rs | 4 +-- 5 files changed, 88 insertions(+), 14 deletions(-) create mode 100644 arrabbiata/src/curve.rs diff --git a/arrabbiata/src/curve.rs b/arrabbiata/src/curve.rs new file mode 100644 index 0000000000..3a58ee22da --- /dev/null +++ b/arrabbiata/src/curve.rs @@ -0,0 +1,73 @@ +//! This file defines a trait similar to [kimchi::curve::KimchiCurve] for Pallas and +//! Vesta. It aims to define all the parameters that are needed by a curve to be +//! used in Arrabbiata. For instance, the sponge parameters, the endomorphism +//! coefficients, etc. +//! The goal of this trait is to parametrize the whole library with the +//! different curves. + +use ark_ec::short_weierstrass::Affine; +use kimchi::curve::{pallas_endos, vesta_endos}; +use mina_curves::pasta::curves::{pallas::PallasParameters, vesta::VestaParameters}; +use mina_poseidon::poseidon::ArithmeticSpongeParams; +use poly_commitment::commitment::{CommitmentCurve, EndoCurve}; + +/// Represents additional information that a curve needs in order to be used +/// with Arrabbiata. +pub trait ArrabbiataCurve: CommitmentCurve + EndoCurve { + /// A human readable name. + const NAME: &'static str; + + /// Provides the sponge params to be used with this curve. + fn sponge_params() -> &'static ArithmeticSpongeParams; + + /// Provides the sponge params to be used with the other curve. + fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams; + + /// Provides the coefficients for the curve endomorphism, called (q,r) in + /// some places. + fn endos() -> &'static (Self::BaseField, Self::ScalarField); + + /// Provides the coefficient for the curve endomorphism over the other + /// field, called q in some places. + fn other_curve_endo() -> &'static Self::ScalarField; +} + +impl ArrabbiataCurve for Affine { + const NAME: &'static str = "pallas"; + + fn sponge_params() -> &'static ArithmeticSpongeParams { + crate::poseidon_3_60_0_5_5_fq::static_params() + } + + fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams { + crate::poseidon_3_60_0_5_5_fp::static_params() + } + + fn endos() -> &'static (Self::BaseField, Self::ScalarField) { + pallas_endos() + } + + fn other_curve_endo() -> &'static Self::ScalarField { + &vesta_endos().0 + } +} + +impl ArrabbiataCurve for Affine { + const NAME: &'static str = "vesta"; + + fn sponge_params() -> &'static ArithmeticSpongeParams { + crate::poseidon_3_60_0_5_5_fp::static_params() + } + + fn other_curve_sponge_params() -> &'static ArithmeticSpongeParams { + crate::poseidon_3_60_0_5_5_fq::static_params() + } + + fn endos() -> &'static (Self::BaseField, Self::ScalarField) { + vesta_endos() + } + + fn other_curve_endo() -> &'static Self::ScalarField { + &pallas_endos().0 + } +} diff --git a/arrabbiata/src/lib.rs b/arrabbiata/src/lib.rs index e43a1b2fa0..654d0691fa 100644 --- a/arrabbiata/src/lib.rs +++ b/arrabbiata/src/lib.rs @@ -3,6 +3,7 @@ use strum::EnumCount as _; pub mod column_env; pub mod columns; pub mod constraints; +pub mod curve; pub mod interpreter; pub mod logup; pub mod poseidon_3_60_0_5_5_fp; diff --git a/arrabbiata/src/prover.rs b/arrabbiata/src/prover.rs index 7e9ea7b36b..9fbac08c9b 100644 --- a/arrabbiata/src/prover.rs +++ b/arrabbiata/src/prover.rs @@ -1,7 +1,6 @@ //! A prover for the folding/accumulation scheme -use crate::proof::Proof; -use ark_ec::AffineRepr; +use crate::{curve::ArrabbiataCurve, proof::Proof}; use ark_ff::PrimeField; use crate::witness::Env; @@ -12,8 +11,8 @@ use crate::witness::Env; pub fn prove< Fp: PrimeField, Fq: PrimeField, - E1: AffineRepr, - E2: AffineRepr, + E1: ArrabbiataCurve, + E2: ArrabbiataCurve, >( _env: &Env, ) -> Result { diff --git a/arrabbiata/src/witness.rs b/arrabbiata/src/witness.rs index 179e9d520a..e5bc957f18 100644 --- a/arrabbiata/src/witness.rs +++ b/arrabbiata/src/witness.rs @@ -1,4 +1,4 @@ -use ark_ec::{models::short_weierstrass::SWCurveConfig, AffineRepr}; +use ark_ec::models::short_weierstrass::SWCurveConfig; use ark_ff::PrimeField; use ark_poly::Evaluations; use kimchi::circuits::{domains::EvaluationDomains, gate::CurrOrNext}; @@ -6,12 +6,13 @@ use log::{debug, info}; use num_bigint::{BigInt, BigUint}; use num_integer::Integer; use o1_utils::field_helpers::FieldHelpers; -use poly_commitment::{commitment::CommitmentCurve, ipa::SRS, PolyComm, SRS as _}; +use poly_commitment::{ipa::SRS, PolyComm, SRS as _}; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use std::time::Instant; use crate::{ columns::{Column, Gadget}, + curve::ArrabbiataCurve, interpreter::{Instruction, InterpreterEnv, Side}, poseidon_3_60_0_5_5_fp, poseidon_3_60_0_5_5_fq, MAXIMUM_FIELD_SIZE_IN_BITS, NUMBER_OF_COLUMNS, NUMBER_OF_PUBLIC_INPUTS, NUMBER_OF_SELECTORS, NUMBER_OF_VALUES_TO_ABSORB_PUBLIC_IO, @@ -31,8 +32,8 @@ pub const IVC_STARTING_INSTRUCTION: Instruction = Instruction::Poseidon(0); pub struct Env< Fp: PrimeField, Fq: PrimeField, - E1: AffineRepr, - E2: AffineRepr, + E1: ArrabbiataCurve, + E2: ArrabbiataCurve, > { // ---------------- // Setup related (domains + SRS) @@ -184,8 +185,8 @@ pub struct Env< impl< Fp: PrimeField, Fq: PrimeField, - E1: CommitmentCurve, - E2: CommitmentCurve, + E1: ArrabbiataCurve, + E2: ArrabbiataCurve, > InterpreterEnv for Env where ::BaseField: PrimeField, @@ -755,8 +756,8 @@ where impl< Fp: PrimeField, Fq: PrimeField, - E1: CommitmentCurve, - E2: CommitmentCurve, + E1: ArrabbiataCurve, + E2: ArrabbiataCurve, > Env { pub fn new( diff --git a/kimchi/src/curve.rs b/kimchi/src/curve.rs index b82ce74ebb..ea863c3593 100644 --- a/kimchi/src/curve.rs +++ b/kimchi/src/curve.rs @@ -38,7 +38,7 @@ pub trait KimchiCurve: CommitmentCurve + EndoCurve { fn other_curve_generator() -> (Self::ScalarField, Self::ScalarField); } -fn vesta_endos() -> &'static ( +pub fn vesta_endos() -> &'static ( ::BaseField, ::ScalarField, ) { @@ -49,7 +49,7 @@ fn vesta_endos() -> &'static ( &VESTA_ENDOS } -fn pallas_endos() -> &'static ( +pub fn pallas_endos() -> &'static ( ::BaseField, ::ScalarField, ) { From 0d0e137b87cf69e868a369b9e76101e07abd6be6 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Thu, 17 Oct 2024 15:19:19 +0200 Subject: [PATCH 2/7] Arrabbiata: instantiate constraints env with ArrabbiataCurve --- arrabbiata/src/constraints.rs | 29 ++++++++++++++++------------- arrabbiata/tests/constraints.rs | 21 ++++++++++----------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/arrabbiata/src/constraints.rs b/arrabbiata/src/constraints.rs index d3a22655de..c0e8c6077a 100644 --- a/arrabbiata/src/constraints.rs +++ b/arrabbiata/src/constraints.rs @@ -1,10 +1,10 @@ use super::{columns::Column, interpreter::InterpreterEnv}; use crate::{ columns::{Gadget, E}, + curve::ArrabbiataCurve, interpreter::{self, Instruction, Side}, MAX_DEGREE, NUMBER_OF_COLUMNS, NUMBER_OF_PUBLIC_INPUTS, }; -use ark_ff::{Field, PrimeField}; use kimchi::circuits::{ expr::{ConstantTerm::Literal, Expr, ExprInner, Operations, Variable}, gate::CurrOrNext, @@ -14,8 +14,8 @@ use num_bigint::BigInt; use o1_utils::FieldHelpers; #[derive(Clone, Debug)] -pub struct Env { - pub poseidon_mds: Vec>, +pub struct Env { + pub poseidon_mds: Vec>, /// The parameter a is the coefficients of the elliptic curve in affine /// coordinates. // FIXME: this is ugly. Let use the curve as a parameter. Only lazy for now. @@ -23,14 +23,17 @@ pub struct Env { pub idx_var: usize, pub idx_var_next_row: usize, pub idx_var_pi: usize, - pub constraints: Vec>, + pub constraints: Vec>, pub activated_gadget: Option, } -impl Env { - pub fn new(poseidon_mds: Vec>, a: BigInt) -> Self { +impl Env { + pub fn new(poseidon_mds: Vec>, a: BigInt) -> Self { // This check might not be useful - assert!(a < Fp::modulus_biguint().into(), "a is too large"); + assert!( + a < C::ScalarField::modulus_biguint().into(), + "a is too large" + ); Self { poseidon_mds, a, @@ -48,10 +51,10 @@ impl Env { /// proof. /// The constraint environment must be instantiated only once, at the last step /// of the computation. -impl InterpreterEnv for Env { +impl InterpreterEnv for Env { type Position = (Column, CurrOrNext); - type Variable = E; + type Variable = E; fn allocate(&mut self) -> Self::Position { assert!(self.idx_var < NUMBER_OF_COLUMNS, "Maximum number of columns reached ({NUMBER_OF_COLUMNS}), increase the number of columns"); @@ -81,7 +84,7 @@ impl InterpreterEnv for Env { fn constant(&self, value: BigInt) -> Self::Variable { let v = value.to_biguint().unwrap(); - let v = Fp::from_biguint(&v).unwrap(); + let v = C::ScalarField::from_biguint(&v).unwrap(); let v_inner = Operations::from(Literal(v)); Self::Variable::constant(v_inner) } @@ -304,7 +307,7 @@ impl InterpreterEnv for Env { } } -impl Env { +impl Env { /// Get all the constraints for the IVC circuit, only. /// /// The following gadgets are used in the IVC circuit: @@ -317,7 +320,7 @@ impl Env { // the computation of the challenges. // FIXME: add a test checking that whatever the value given in parameter of // the gadget, the constraints are the same - pub fn get_all_constraints_for_ivc(&self) -> Vec> { + pub fn get_all_constraints_for_ivc(&self) -> Vec> { // Copying the instance we got in parameter, and making it mutable to // avoid modifying the original instance. let mut env = self.clone(); @@ -354,7 +357,7 @@ impl Env { // FIXME: the application should be given as an argument to handle Rust // zkApp. It is only for the PoC. // FIXME: the selectors are not added for now. - pub fn get_all_constraints(&self) -> Vec> { + pub fn get_all_constraints(&self) -> Vec> { let mut constraints = self.get_all_constraints_for_ivc(); // Copying the instance we got in parameter, and making it mutable to diff --git a/arrabbiata/tests/constraints.rs b/arrabbiata/tests/constraints.rs index 5ed9196b55..8febfc7495 100644 --- a/arrabbiata/tests/constraints.rs +++ b/arrabbiata/tests/constraints.rs @@ -1,18 +1,17 @@ -use num_bigint::BigInt; -use std::collections::HashMap; - use arrabbiata::{ columns::Gadget, constraints, interpreter::{self, Instruction}, poseidon_3_60_0_5_5_fp, poseidon_3_60_0_5_5_fq, }; -use mina_curves::pasta::fields::{Fp, Fq}; +use mina_curves::pasta::{curves::vesta::Vesta, Pallas}; +use num_bigint::BigInt; +use std::collections::HashMap; fn helper_compute_constraints_gadget(instr: Instruction, exp_constraints: usize) { let mut constraints_fp = { let poseidon_mds = poseidon_3_60_0_5_5_fp::static_params().mds.clone(); - constraints::Env::::new(poseidon_mds.to_vec(), BigInt::from(0_usize)) + constraints::Env::::new(poseidon_mds.to_vec(), BigInt::from(0_usize)) }; interpreter::run_ivc(&mut constraints_fp, instr); @@ -20,7 +19,7 @@ fn helper_compute_constraints_gadget(instr: Instruction, exp_constraints: usize) let mut constraints_fq = { let poseidon_mds = poseidon_3_60_0_5_5_fq::static_params().mds.clone(); - constraints::Env::::new(poseidon_mds.to_vec(), BigInt::from(0_usize)) + constraints::Env::::new(poseidon_mds.to_vec(), BigInt::from(0_usize)) }; interpreter::run_ivc(&mut constraints_fq, instr); assert_eq!(constraints_fq.constraints.len(), exp_constraints); @@ -29,7 +28,7 @@ fn helper_compute_constraints_gadget(instr: Instruction, exp_constraints: usize) fn helper_check_expected_degree_constraints(instr: Instruction, exp_degrees: HashMap) { let mut constraints_fp = { let poseidon_mds = poseidon_3_60_0_5_5_fp::static_params().mds.clone(); - constraints::Env::::new(poseidon_mds.to_vec(), BigInt::from(0_usize)) + constraints::Env::::new(poseidon_mds.to_vec(), BigInt::from(0_usize)) }; interpreter::run_ivc(&mut constraints_fp, instr); @@ -61,7 +60,7 @@ fn helper_gadget_number_of_columns_used( ) { let mut constraints_fp = { let poseidon_mds = poseidon_3_60_0_5_5_fp::static_params().mds.clone(); - constraints::Env::::new(poseidon_mds.to_vec(), BigInt::from(0_usize)) + constraints::Env::::new(poseidon_mds.to_vec(), BigInt::from(0_usize)) }; interpreter::run_ivc(&mut constraints_fp, instr); @@ -75,7 +74,7 @@ fn helper_gadget_number_of_columns_used( fn helper_check_gadget_activated(instr: Instruction, gadget: Gadget) { let mut constraints_fp = { let poseidon_mds = poseidon_3_60_0_5_5_fp::static_params().mds.clone(); - constraints::Env::::new(poseidon_mds.to_vec(), BigInt::from(0_usize)) + constraints::Env::::new(poseidon_mds.to_vec(), BigInt::from(0_usize)) }; interpreter::run_ivc(&mut constraints_fp, instr); @@ -119,7 +118,7 @@ fn test_gadget_elliptic_curve_addition() { fn test_ivc_total_number_of_constraints_ivc() { let constraints_fp = { let poseidon_mds = poseidon_3_60_0_5_5_fp::static_params().mds.clone(); - constraints::Env::::new(poseidon_mds.to_vec(), BigInt::from(0_usize)) + constraints::Env::::new(poseidon_mds.to_vec(), BigInt::from(0_usize)) }; let constraints = constraints_fp.get_all_constraints_for_ivc(); @@ -130,7 +129,7 @@ fn test_ivc_total_number_of_constraints_ivc() { fn test_degree_of_constraints_ivc() { let constraints_fp = { let poseidon_mds = poseidon_3_60_0_5_5_fp::static_params().mds.clone(); - constraints::Env::::new(poseidon_mds.to_vec(), BigInt::from(0_usize)) + constraints::Env::::new(poseidon_mds.to_vec(), BigInt::from(0_usize)) }; let constraints = constraints_fp.get_all_constraints_for_ivc(); From 555a772858e520b9f6710b58d808a891612f0a63 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Thu, 17 Oct 2024 15:32:06 +0200 Subject: [PATCH 3/7] Arrabiata/Constraints: use poseidon params from curve trait --- arrabbiata/src/constraints.rs | 6 ++---- arrabbiata/tests/constraints.rs | 36 +++++++-------------------------- 2 files changed, 9 insertions(+), 33 deletions(-) diff --git a/arrabbiata/src/constraints.rs b/arrabbiata/src/constraints.rs index c0e8c6077a..22b7b08f1e 100644 --- a/arrabbiata/src/constraints.rs +++ b/arrabbiata/src/constraints.rs @@ -15,7 +15,6 @@ use o1_utils::FieldHelpers; #[derive(Clone, Debug)] pub struct Env { - pub poseidon_mds: Vec>, /// The parameter a is the coefficients of the elliptic curve in affine /// coordinates. // FIXME: this is ugly. Let use the curve as a parameter. Only lazy for now. @@ -28,14 +27,13 @@ pub struct Env { } impl Env { - pub fn new(poseidon_mds: Vec>, a: BigInt) -> Self { + pub fn new(a: BigInt) -> Self { // This check might not be useful assert!( a < C::ScalarField::modulus_biguint().into(), "a is too large" ); Self { - poseidon_mds, a, idx_var: 0, idx_var_next_row: 0, @@ -183,7 +181,7 @@ impl InterpreterEnv for Env { } fn get_poseidon_mds_matrix(&mut self, i: usize, j: usize) -> Self::Variable { - let v = self.poseidon_mds[i][j]; + let v = C::sponge_params().mds[i][j]; let v_inner = Operations::from(Literal(v)); Self::Variable::constant(v_inner) } diff --git a/arrabbiata/tests/constraints.rs b/arrabbiata/tests/constraints.rs index 8febfc7495..6d992e4ba8 100644 --- a/arrabbiata/tests/constraints.rs +++ b/arrabbiata/tests/constraints.rs @@ -2,34 +2,24 @@ use arrabbiata::{ columns::Gadget, constraints, interpreter::{self, Instruction}, - poseidon_3_60_0_5_5_fp, poseidon_3_60_0_5_5_fq, }; use mina_curves::pasta::{curves::vesta::Vesta, Pallas}; use num_bigint::BigInt; use std::collections::HashMap; fn helper_compute_constraints_gadget(instr: Instruction, exp_constraints: usize) { - let mut constraints_fp = { - let poseidon_mds = poseidon_3_60_0_5_5_fp::static_params().mds.clone(); - constraints::Env::::new(poseidon_mds.to_vec(), BigInt::from(0_usize)) - }; + let mut constraints_fp = constraints::Env::::new(BigInt::from(0_usize)); interpreter::run_ivc(&mut constraints_fp, instr); assert_eq!(constraints_fp.constraints.len(), exp_constraints); - let mut constraints_fq = { - let poseidon_mds = poseidon_3_60_0_5_5_fq::static_params().mds.clone(); - constraints::Env::::new(poseidon_mds.to_vec(), BigInt::from(0_usize)) - }; + let mut constraints_fq = constraints::Env::::new(BigInt::from(0_usize)); interpreter::run_ivc(&mut constraints_fq, instr); assert_eq!(constraints_fq.constraints.len(), exp_constraints); } fn helper_check_expected_degree_constraints(instr: Instruction, exp_degrees: HashMap) { - let mut constraints_fp = { - let poseidon_mds = poseidon_3_60_0_5_5_fp::static_params().mds.clone(); - constraints::Env::::new(poseidon_mds.to_vec(), BigInt::from(0_usize)) - }; + let mut constraints_fp = constraints::Env::::new(BigInt::from(0_usize)); interpreter::run_ivc(&mut constraints_fp, instr); let mut actual_degrees: HashMap = HashMap::new(); @@ -58,10 +48,7 @@ fn helper_gadget_number_of_columns_used( exp_nb_columns: usize, exp_nb_public_input: usize, ) { - let mut constraints_fp = { - let poseidon_mds = poseidon_3_60_0_5_5_fp::static_params().mds.clone(); - constraints::Env::::new(poseidon_mds.to_vec(), BigInt::from(0_usize)) - }; + let mut constraints_fp = constraints::Env::::new(BigInt::from(0_usize)); interpreter::run_ivc(&mut constraints_fp, instr); let nb_columns = constraints_fp.idx_var; @@ -72,10 +59,7 @@ fn helper_gadget_number_of_columns_used( } fn helper_check_gadget_activated(instr: Instruction, gadget: Gadget) { - let mut constraints_fp = { - let poseidon_mds = poseidon_3_60_0_5_5_fp::static_params().mds.clone(); - constraints::Env::::new(poseidon_mds.to_vec(), BigInt::from(0_usize)) - }; + let mut constraints_fp = constraints::Env::::new(BigInt::from(0_usize)); interpreter::run_ivc(&mut constraints_fp, instr); assert_eq!(constraints_fp.activated_gadget, Some(gadget)); @@ -116,10 +100,7 @@ fn test_gadget_elliptic_curve_addition() { #[test] fn test_ivc_total_number_of_constraints_ivc() { - let constraints_fp = { - let poseidon_mds = poseidon_3_60_0_5_5_fp::static_params().mds.clone(); - constraints::Env::::new(poseidon_mds.to_vec(), BigInt::from(0_usize)) - }; + let constraints_fp = constraints::Env::::new(BigInt::from(0_usize)); let constraints = constraints_fp.get_all_constraints_for_ivc(); assert_eq!(constraints.len(), 28); @@ -127,10 +108,7 @@ fn test_ivc_total_number_of_constraints_ivc() { #[test] fn test_degree_of_constraints_ivc() { - let constraints_fp = { - let poseidon_mds = poseidon_3_60_0_5_5_fp::static_params().mds.clone(); - constraints::Env::::new(poseidon_mds.to_vec(), BigInt::from(0_usize)) - }; + let constraints_fp = constraints::Env::::new(BigInt::from(0_usize)); let constraints = constraints_fp.get_all_constraints_for_ivc(); From f0316f311f6a5e6076743fa5e2139996d7cedba5 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Thu, 17 Oct 2024 16:23:50 +0200 Subject: [PATCH 4/7] Arrabiata/Witness: use curve for poseidon parameters --- arrabbiata/src/witness.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/arrabbiata/src/witness.rs b/arrabbiata/src/witness.rs index e5bc957f18..4ad8a197ad 100644 --- a/arrabbiata/src/witness.rs +++ b/arrabbiata/src/witness.rs @@ -14,9 +14,9 @@ use crate::{ columns::{Column, Gadget}, curve::ArrabbiataCurve, interpreter::{Instruction, InterpreterEnv, Side}, - poseidon_3_60_0_5_5_fp, poseidon_3_60_0_5_5_fq, MAXIMUM_FIELD_SIZE_IN_BITS, NUMBER_OF_COLUMNS, - NUMBER_OF_PUBLIC_INPUTS, NUMBER_OF_SELECTORS, NUMBER_OF_VALUES_TO_ABSORB_PUBLIC_IO, - POSEIDON_ALPHA, POSEIDON_ROUNDS_FULL, POSEIDON_STATE_SIZE, + MAXIMUM_FIELD_SIZE_IN_BITS, NUMBER_OF_COLUMNS, NUMBER_OF_PUBLIC_INPUTS, NUMBER_OF_SELECTORS, + NUMBER_OF_VALUES_TO_ABSORB_PUBLIC_IO, POSEIDON_ALPHA, POSEIDON_ROUNDS_FULL, + POSEIDON_STATE_SIZE, }; pub const IVC_STARTING_INSTRUCTION: Instruction = Instruction::Poseidon(0); @@ -392,11 +392,11 @@ where i: usize, ) -> Self::Variable { let rc = if self.current_iteration % 2 == 0 { - poseidon_3_60_0_5_5_fp::static_params().round_constants[round][i] + E1::sponge_params().round_constants[round][i] .to_biguint() .into() } else { - poseidon_3_60_0_5_5_fq::static_params().round_constants[round][i] + E2::sponge_params().round_constants[round][i] .to_biguint() .into() }; @@ -405,13 +405,9 @@ where fn get_poseidon_mds_matrix(&mut self, i: usize, j: usize) -> Self::Variable { if self.current_iteration % 2 == 0 { - poseidon_3_60_0_5_5_fp::static_params().mds[i][j] - .to_biguint() - .into() + E1::sponge_params().mds[i][j].to_biguint().into() } else { - poseidon_3_60_0_5_5_fq::static_params().mds[i][j] - .to_biguint() - .into() + E2::sponge_params().mds[i][j].to_biguint().into() } } From bb851c535436d160fbe568507a5615f11001ec47 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Thu, 17 Oct 2024 17:04:02 +0200 Subject: [PATCH 5/7] Arrabbiata/Sponge: define PlonkSpongeConstants in curve and use it --- arrabbiata/src/curve.rs | 17 ++++++++++++++- arrabbiata/src/interpreter.rs | 35 +++++++++++++++++++------------ arrabbiata/src/lib.rs | 12 ----------- arrabbiata/src/main.rs | 7 +++++-- arrabbiata/src/witness.rs | 26 ++++++++++++----------- arrabbiata/tests/witness.rs | 33 ++++++++++------------------- arrabbiata/tests/witness_utils.rs | 15 ++++++++----- 7 files changed, 78 insertions(+), 67 deletions(-) diff --git a/arrabbiata/src/curve.rs b/arrabbiata/src/curve.rs index 3a58ee22da..5453dd298e 100644 --- a/arrabbiata/src/curve.rs +++ b/arrabbiata/src/curve.rs @@ -8,9 +8,24 @@ use ark_ec::short_weierstrass::Affine; use kimchi::curve::{pallas_endos, vesta_endos}; use mina_curves::pasta::curves::{pallas::PallasParameters, vesta::VestaParameters}; -use mina_poseidon::poseidon::ArithmeticSpongeParams; +use mina_poseidon::{constants::SpongeConstants, poseidon::ArithmeticSpongeParams}; use poly_commitment::commitment::{CommitmentCurve, EndoCurve}; +#[derive(Clone)] +pub struct PlonkSpongeConstants {} + +impl SpongeConstants for PlonkSpongeConstants { + const SPONGE_CAPACITY: usize = 1; + const SPONGE_WIDTH: usize = 3; + const SPONGE_RATE: usize = 2; + const PERM_ROUNDS_FULL: usize = 60; + const PERM_ROUNDS_PARTIAL: usize = 0; + const PERM_HALF_ROUNDS_FULL: usize = 0; + const PERM_SBOX: u32 = 5; + const PERM_FULL_MDS: bool = true; + const PERM_INITIAL_ARK: bool = false; +} + /// Represents additional information that a curve needs in order to be used /// with Arrabbiata. pub trait ArrabbiataCurve: CommitmentCurve + EndoCurve { diff --git a/arrabbiata/src/interpreter.rs b/arrabbiata/src/interpreter.rs index 025b2ac0a2..648eea6458 100644 --- a/arrabbiata/src/interpreter.rs +++ b/arrabbiata/src/interpreter.rs @@ -87,7 +87,8 @@ //! //! Hashing is a crucial part of the IVC scheme. The hash function the //! interpreter does use for the moment is an instance of the Poseidon hash -//! function with a fixed state size of [POSEIDON_STATE_SIZE]. Increasing the +//! function with a fixed state size of +//! [crate::curve::PlonkSpongeConstants::SPONGE_WIDTH]. Increasing the //! state size can be considered as it would potentially optimize the //! number of rounds, and allow hashing more data on one row. We leave this for //! future works. @@ -338,11 +339,11 @@ //! there. use crate::{ - columns::Gadget, MAXIMUM_FIELD_SIZE_IN_BITS, NUMBER_OF_COLUMNS, POSEIDON_ROUNDS_FULL, - POSEIDON_STATE_SIZE, + columns::Gadget, curve::PlonkSpongeConstants, MAXIMUM_FIELD_SIZE_IN_BITS, NUMBER_OF_COLUMNS, }; use ark_ff::{One, Zero}; use log::debug; +use mina_poseidon::constants::SpongeConstants; use num_bigint::BigInt; /// A list of instruction/gadget implemented in the interpreter. @@ -830,19 +831,23 @@ pub fn run_ivc(env: &mut E, instr: Instruction) { Instruction::Poseidon(curr_round) => { env.activate_gadget(Gadget::Poseidon); debug!("Executing instruction Poseidon({curr_round})"); - if curr_round < POSEIDON_ROUNDS_FULL { + if curr_round < PlonkSpongeConstants::PERM_ROUNDS_FULL { // Values to be absorbed are 0 when when the round is not zero, // i.e. when we are processing the rounds. - let values_to_absorb: Vec = (0..POSEIDON_STATE_SIZE - 1) + let values_to_absorb: Vec = (0..PlonkSpongeConstants::SPONGE_WIDTH + - 1) .map(|_i| { let pos = env.allocate_public_input(); // fetch_value_to_absorb is supposed to return 0 if curr_round != 0. unsafe { env.fetch_value_to_absorb(pos, curr_round) } }) .collect(); - let round_input_positions: Vec = - (0..POSEIDON_STATE_SIZE).map(|_i| env.allocate()).collect(); - let round_output_positions: Vec = (0..POSEIDON_STATE_SIZE) + let round_input_positions: Vec = (0 + ..PlonkSpongeConstants::SPONGE_WIDTH) + .map(|_i| env.allocate()) + .collect(); + let round_output_positions: Vec = (0 + ..PlonkSpongeConstants::SPONGE_WIDTH) .map(|_i| env.allocate_next_row()) .collect(); // If we are at the first round, we load the state from the environment. @@ -856,8 +861,9 @@ pub fn run_ivc(env: &mut E, instr: Instruction) { .enumerate() .map(|(i, pos)| { let res = env.load_poseidon_state(*pos, i); - // Absorb value. The capacity is POSEIDON_STATE_SIZE - 1 - if i < POSEIDON_STATE_SIZE - 1 { + // Absorb value. The capacity is + // PlonkSpongeConstants::SPONGE_WIDTH - 1 + if i < PlonkSpongeConstants::SPONGE_WIDTH - 1 { res + values_to_absorb[i].clone() } else { res @@ -882,7 +888,7 @@ pub fn run_ivc(env: &mut E, instr: Instruction) { let round = curr_round + idx_round; - let rcs: Vec = (0..POSEIDON_STATE_SIZE) + let rcs: Vec = (0..PlonkSpongeConstants::SPONGE_WIDTH) .map(|i| { let pos = env.allocate_public_input(); env.get_poseidon_round_constant(pos, round, i) @@ -915,7 +921,7 @@ pub fn run_ivc(env: &mut E, instr: Instruction) { // now, we will save the state at the end of the last round // and reload it at the beginning of the next Poseidon full // hash. - if round == POSEIDON_ROUNDS_FULL - 1 { + if round == PlonkSpongeConstants::PERM_ROUNDS_FULL - 1 { state.iter().enumerate().for_each(|(i, x)| { unsafe { env.save_poseidon_state(x.clone(), i) }; }); @@ -924,7 +930,10 @@ pub fn run_ivc(env: &mut E, instr: Instruction) { state }); } else { - panic!("Invalid index: it is supposed to be less than {POSEIDON_ROUNDS_FULL}"); + panic!( + "Invalid index: it is supposed to be less than {}", + PlonkSpongeConstants::PERM_ROUNDS_FULL + ); } } Instruction::NoOp => {} diff --git a/arrabbiata/src/lib.rs b/arrabbiata/src/lib.rs index 654d0691fa..dbc0d28bff 100644 --- a/arrabbiata/src/lib.rs +++ b/arrabbiata/src/lib.rs @@ -35,18 +35,6 @@ pub const NUMBER_OF_COLUMNS: usize = 15; /// to absorb. pub const NUMBER_OF_PUBLIC_INPUTS: usize = 15 + 2; -/// The low-exponentiation value used by the Poseidon hash function for the -/// substitution box. -/// -/// The value is used to perform initialisation checks with the fields. -pub const POSEIDON_ALPHA: u64 = 5; - -/// The number of full rounds in the Poseidon hash function. -pub const POSEIDON_ROUNDS_FULL: usize = 60; - -/// The number of elements in the state of the Poseidon hash function. -pub const POSEIDON_STATE_SIZE: usize = 3; - /// The maximum number of bits the fields can be. /// It is critical as we have some assumptions for the gadgets describing the /// IVC. diff --git a/arrabbiata/src/main.rs b/arrabbiata/src/main.rs index 150d56c4d5..de0ecf23c2 100644 --- a/arrabbiata/src/main.rs +++ b/arrabbiata/src/main.rs @@ -1,10 +1,12 @@ use arrabbiata::{ + curve::PlonkSpongeConstants, interpreter::{self, InterpreterEnv}, witness::Env, - IVC_CIRCUIT_SIZE, MIN_SRS_LOG2_SIZE, POSEIDON_STATE_SIZE, + IVC_CIRCUIT_SIZE, MIN_SRS_LOG2_SIZE, }; use log::{debug, info}; use mina_curves::pasta::{Fp, Fq, Pallas, Vesta}; +use mina_poseidon::constants::SpongeConstants; use num_bigint::BigInt; use std::time::Instant; @@ -47,7 +49,8 @@ pub fn main() { let domain_size = 1 << srs_log2_size; // FIXME: setup correctly the initial sponge state - let sponge_e1: [BigInt; POSEIDON_STATE_SIZE] = std::array::from_fn(|_i| BigInt::from(42u64)); + let sponge_e1: [BigInt; PlonkSpongeConstants::SPONGE_WIDTH] = + std::array::from_fn(|_i| BigInt::from(42u64)); // FIXME: make a setup phase to build the selectors let mut env = Env::::new( *srs_log2_size, diff --git a/arrabbiata/src/witness.rs b/arrabbiata/src/witness.rs index 4ad8a197ad..ee6d056f41 100644 --- a/arrabbiata/src/witness.rs +++ b/arrabbiata/src/witness.rs @@ -3,6 +3,7 @@ use ark_ff::PrimeField; use ark_poly::Evaluations; use kimchi::circuits::{domains::EvaluationDomains, gate::CurrOrNext}; use log::{debug, info}; +use mina_poseidon::constants::SpongeConstants; use num_bigint::{BigInt, BigUint}; use num_integer::Integer; use o1_utils::field_helpers::FieldHelpers; @@ -12,11 +13,10 @@ use std::time::Instant; use crate::{ columns::{Column, Gadget}, - curve::ArrabbiataCurve, + curve::{ArrabbiataCurve, PlonkSpongeConstants}, interpreter::{Instruction, InterpreterEnv, Side}, MAXIMUM_FIELD_SIZE_IN_BITS, NUMBER_OF_COLUMNS, NUMBER_OF_PUBLIC_INPUTS, NUMBER_OF_SELECTORS, - NUMBER_OF_VALUES_TO_ABSORB_PUBLIC_IO, POSEIDON_ALPHA, POSEIDON_ROUNDS_FULL, - POSEIDON_STATE_SIZE, + NUMBER_OF_VALUES_TO_ABSORB_PUBLIC_IO, }; pub const IVC_STARTING_INSTRUCTION: Instruction = Instruction::Poseidon(0); @@ -119,8 +119,8 @@ pub struct Env< /// public IO. // IMPROVEME: use a list of BigInt? It might be faster as the CPU will // already have in its cache the values, and we can use a flat array - pub sponge_e1: [BigInt; POSEIDON_STATE_SIZE], - pub sponge_e2: [BigInt; POSEIDON_STATE_SIZE], + pub sponge_e1: [BigInt; PlonkSpongeConstants::SPONGE_WIDTH], + pub sponge_e2: [BigInt; PlonkSpongeConstants::SPONGE_WIDTH], /// The current iteration of the IVC pub current_iteration: u64, @@ -759,23 +759,25 @@ impl< pub fn new( srs_log2_size: usize, z0: BigInt, - sponge_e1: [BigInt; 3], - sponge_e2: [BigInt; 3], + sponge_e1: [BigInt; PlonkSpongeConstants::SPONGE_WIDTH], + sponge_e2: [BigInt; PlonkSpongeConstants::SPONGE_WIDTH], ) -> Self { { assert!(Fp::MODULUS_BIT_SIZE <= MAXIMUM_FIELD_SIZE_IN_BITS.try_into().unwrap(), "The size of the field Fp is too large, it should be less than {MAXIMUM_FIELD_SIZE_IN_BITS}"); assert!(Fq::MODULUS_BIT_SIZE <= MAXIMUM_FIELD_SIZE_IN_BITS.try_into().unwrap(), "The size of the field Fq is too large, it should be less than {MAXIMUM_FIELD_SIZE_IN_BITS}"); let modulus_fp = Fp::modulus_biguint(); + let alpha = PlonkSpongeConstants::PERM_SBOX; assert!( - (modulus_fp - BigUint::from(1_u64)).gcd(&BigUint::from(POSEIDON_ALPHA)) + (modulus_fp - BigUint::from(1_u64)).gcd(&BigUint::from(alpha)) == BigUint::from(1_u64), - "The modulus of Fp should be coprime with {POSEIDON_ALPHA}" + "The modulus of Fp should be coprime with {alpha}" ); let modulus_fq = Fq::modulus_biguint(); + let alpha = PlonkSpongeConstants::PERM_SBOX; assert!( - (modulus_fq - BigUint::from(1_u64)).gcd(&BigUint::from(POSEIDON_ALPHA)) + (modulus_fq - BigUint::from(1_u64)).gcd(&BigUint::from(alpha)) == BigUint::from(1_u64), - "The modulus of Fq should be coprime with {POSEIDON_ALPHA}" + "The modulus of Fq should be coprime with {alpha}" ); } let srs_size = 1 << srs_log2_size; @@ -1012,7 +1014,7 @@ impl< pub fn fetch_next_instruction(&mut self) -> Instruction { match self.current_instruction { Instruction::Poseidon(i) => { - if i < POSEIDON_ROUNDS_FULL - 5 { + if i < PlonkSpongeConstants::PERM_ROUNDS_FULL - 5 { Instruction::Poseidon(i + 5) } else { // FIXME: we continue absorbing diff --git a/arrabbiata/tests/witness.rs b/arrabbiata/tests/witness.rs index 402cd9d9fa..dadeb7dee2 100644 --- a/arrabbiata/tests/witness.rs +++ b/arrabbiata/tests/witness.rs @@ -1,10 +1,11 @@ use ark_ec::{AffineRepr, Group}; use ark_ff::{PrimeField, UniformRand}; use arrabbiata::{ + curve::PlonkSpongeConstants, interpreter::{self, Instruction, InterpreterEnv}, poseidon_3_60_0_5_5_fp, witness::Env, - MAXIMUM_FIELD_SIZE_IN_BITS, POSEIDON_ROUNDS_FULL, POSEIDON_STATE_SIZE, + MAXIMUM_FIELD_SIZE_IN_BITS, }; use mina_curves::pasta::{Fp, Fq, Pallas, ProjectivePallas, Vesta}; use mina_poseidon::{constants::SpongeConstants, permutation::poseidon_block_cipher}; @@ -13,26 +14,11 @@ use o1_utils::FieldHelpers; use poly_commitment::{commitment::CommitmentCurve, PolyComm}; use rand::{CryptoRng, RngCore}; -// Used by the mina_poseidon library. Only for testing. -#[derive(Clone)] -pub struct PlonkSpongeConstants {} - -impl SpongeConstants for PlonkSpongeConstants { - const SPONGE_CAPACITY: usize = 1; - const SPONGE_WIDTH: usize = POSEIDON_STATE_SIZE; - const SPONGE_RATE: usize = 2; - const PERM_ROUNDS_FULL: usize = POSEIDON_ROUNDS_FULL; - const PERM_ROUNDS_PARTIAL: usize = 0; - const PERM_HALF_ROUNDS_FULL: usize = 0; - const PERM_SBOX: u32 = 5; - const PERM_FULL_MDS: bool = true; - const PERM_INITIAL_ARK: bool = false; -} - #[test] fn test_unit_witness_poseidon_next_row_gadget_one_full_hash() { let srs_log2_size = 6; - let sponge: [BigInt; POSEIDON_STATE_SIZE] = std::array::from_fn(|_i| BigInt::from(42u64)); + let sponge: [BigInt; PlonkSpongeConstants::SPONGE_WIDTH] = + std::array::from_fn(|_i| BigInt::from(42u64)); let mut env = Env::::new( srs_log2_size, BigInt::from(1u64), @@ -42,7 +28,7 @@ fn test_unit_witness_poseidon_next_row_gadget_one_full_hash() { env.current_instruction = Instruction::Poseidon(0); - (0..(POSEIDON_ROUNDS_FULL / 5)).for_each(|i| { + (0..(PlonkSpongeConstants::PERM_ROUNDS_FULL / 5)).for_each(|i| { interpreter::run_ivc(&mut env, Instruction::Poseidon(5 * i)); env.reset(); }); @@ -76,7 +62,8 @@ fn test_unit_witness_poseidon_next_row_gadget_one_full_hash() { #[test] fn test_unit_witness_elliptic_curve_addition() { let srs_log2_size = 6; - let sponge_e1: [BigInt; POSEIDON_STATE_SIZE] = std::array::from_fn(|_i| BigInt::from(42u64)); + let sponge_e1: [BigInt; PlonkSpongeConstants::SPONGE_WIDTH] = + std::array::from_fn(|_i| BigInt::from(42u64)); let mut env = Env::::new( srs_log2_size, BigInt::from(1u64), @@ -150,7 +137,8 @@ fn test_unit_witness_elliptic_curve_addition() { fn test_witness_double_elliptic_curve_point() { let mut rng = o1_utils::tests::make_test_rng(None); let srs_log2_size = 6; - let sponge_e1: [BigInt; POSEIDON_STATE_SIZE] = std::array::from_fn(|_i| BigInt::from(42u64)); + let sponge_e1: [BigInt; PlonkSpongeConstants::SPONGE_WIDTH] = + std::array::from_fn(|_i| BigInt::from(42u64)); let mut env = Env::::new( srs_log2_size, BigInt::from(1u64), @@ -186,7 +174,8 @@ where RNG: RngCore + CryptoRng, { let srs_log2_size = 10; - let sponge_e1: [BigInt; POSEIDON_STATE_SIZE] = std::array::from_fn(|_i| r.clone()); + let sponge_e1: [BigInt; PlonkSpongeConstants::SPONGE_WIDTH] = + std::array::from_fn(|_i| r.clone()); let mut env = Env::::new( srs_log2_size, BigInt::from(1u64), diff --git a/arrabbiata/tests/witness_utils.rs b/arrabbiata/tests/witness_utils.rs index 7d71aba2f4..1034014806 100644 --- a/arrabbiata/tests/witness_utils.rs +++ b/arrabbiata/tests/witness_utils.rs @@ -3,8 +3,9 @@ //! A user is expected to use the gadget methods. //! The API of the utilities is more subject to changes. -use arrabbiata::{interpreter::InterpreterEnv, witness::Env, POSEIDON_STATE_SIZE}; +use arrabbiata::{curve::PlonkSpongeConstants, interpreter::InterpreterEnv, witness::Env}; use mina_curves::pasta::{Fp, Fq, Pallas, Vesta}; +use mina_poseidon::constants::SpongeConstants; use num_bigint::BigInt; use o1_utils::FieldHelpers; @@ -14,7 +15,8 @@ fn test_constrain_boolean_witness_negative_value() { let srs_log2_size = 2; let mut env = { let z0 = BigInt::from(1u64); - let sponge_e1: [BigInt; POSEIDON_STATE_SIZE] = std::array::from_fn(|_i| BigInt::from(0u64)); + let sponge_e1: [BigInt; PlonkSpongeConstants::SPONGE_WIDTH] = + std::array::from_fn(|_i| BigInt::from(0u64)); Env::::new(srs_log2_size, z0, sponge_e1.clone(), sponge_e1.clone()) }; @@ -26,7 +28,8 @@ fn test_constrain_boolean_witness_positive_and_negative_modulus() { let srs_log2_size = 2; let mut env = { let z0 = BigInt::from(1u64); - let sponge_e1: [BigInt; POSEIDON_STATE_SIZE] = std::array::from_fn(|_i| BigInt::from(0u64)); + let sponge_e1: [BigInt; PlonkSpongeConstants::SPONGE_WIDTH] = + std::array::from_fn(|_i| BigInt::from(0u64)); Env::::new(srs_log2_size, z0, sponge_e1.clone(), sponge_e1.clone()) }; @@ -40,7 +43,8 @@ fn test_constrain_boolean_witness_positive_and_negative_modulus() { #[test] fn test_write_column_return_the_result_reduced_in_field() { let srs_log2_size = 6; - let sponge_e1: [BigInt; POSEIDON_STATE_SIZE] = std::array::from_fn(|_i| BigInt::from(42u64)); + let sponge_e1: [BigInt; PlonkSpongeConstants::SPONGE_WIDTH] = + std::array::from_fn(|_i| BigInt::from(42u64)); let mut env = Env::::new( srs_log2_size, BigInt::from(1u64), @@ -57,7 +61,8 @@ fn test_write_column_return_the_result_reduced_in_field() { #[test] fn test_write_public_return_the_result_reduced_in_field() { let srs_log2_size = 6; - let sponge_e1: [BigInt; POSEIDON_STATE_SIZE] = std::array::from_fn(|_i| BigInt::from(42u64)); + let sponge_e1: [BigInt; PlonkSpongeConstants::SPONGE_WIDTH] = + std::array::from_fn(|_i| BigInt::from(42u64)); let mut env = Env::::new( srs_log2_size, BigInt::from(1u64), From fd36b40babb843f52938559cd71f66f04f3d9796 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Thu, 17 Oct 2024 17:14:02 +0200 Subject: [PATCH 6/7] Arrabiata/curve: define SPONGE_CONSTANTS for ArrabiataCurve --- arrabbiata/src/curve.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arrabbiata/src/curve.rs b/arrabbiata/src/curve.rs index 5453dd298e..cc1a72b2c7 100644 --- a/arrabbiata/src/curve.rs +++ b/arrabbiata/src/curve.rs @@ -32,6 +32,13 @@ pub trait ArrabbiataCurve: CommitmentCurve + EndoCurve { /// A human readable name. const NAME: &'static str; + // FIXME: use this in the codebase. + // We might want to use different sponge constants for different curves. + // For now, it does use the same constants for both curves. + type SpongeConstants: SpongeConstants; + + const SPONGE_CONSTANTS: Self::SpongeConstants; + /// Provides the sponge params to be used with this curve. fn sponge_params() -> &'static ArithmeticSpongeParams; @@ -50,6 +57,10 @@ pub trait ArrabbiataCurve: CommitmentCurve + EndoCurve { impl ArrabbiataCurve for Affine { const NAME: &'static str = "pallas"; + type SpongeConstants = PlonkSpongeConstants; + + const SPONGE_CONSTANTS: Self::SpongeConstants = PlonkSpongeConstants {}; + fn sponge_params() -> &'static ArithmeticSpongeParams { crate::poseidon_3_60_0_5_5_fq::static_params() } @@ -70,6 +81,10 @@ impl ArrabbiataCurve for Affine { impl ArrabbiataCurve for Affine { const NAME: &'static str = "vesta"; + type SpongeConstants = PlonkSpongeConstants; + + const SPONGE_CONSTANTS: Self::SpongeConstants = PlonkSpongeConstants {}; + fn sponge_params() -> &'static ArithmeticSpongeParams { crate::poseidon_3_60_0_5_5_fp::static_params() } From ef5a1dc8b5da227f10b1f80bd46f76ef9903ad3a Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Thu, 17 Oct 2024 17:49:26 +0200 Subject: [PATCH 7/7] Arrabbiata: get rid of the `a` parameter in the constraints env --- arrabbiata/src/constraints.rs | 21 ++++++++++++++++++--- arrabbiata/tests/constraints.rs | 15 +++++++-------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/arrabbiata/src/constraints.rs b/arrabbiata/src/constraints.rs index 22b7b08f1e..02e1bc5e0e 100644 --- a/arrabbiata/src/constraints.rs +++ b/arrabbiata/src/constraints.rs @@ -5,6 +5,8 @@ use crate::{ interpreter::{self, Instruction, Side}, MAX_DEGREE, NUMBER_OF_COLUMNS, NUMBER_OF_PUBLIC_INPUTS, }; +use ark_ec::{short_weierstrass::SWCurveConfig, CurveConfig}; +use ark_ff::PrimeField; use kimchi::circuits::{ expr::{ConstantTerm::Literal, Expr, ExprInner, Operations, Variable}, gate::CurrOrNext, @@ -12,12 +14,12 @@ use kimchi::circuits::{ use log::debug; use num_bigint::BigInt; use o1_utils::FieldHelpers; +use poly_commitment::commitment::CommitmentCurve; #[derive(Clone, Debug)] pub struct Env { /// The parameter a is the coefficients of the elliptic curve in affine /// coordinates. - // FIXME: this is ugly. Let use the curve as a parameter. Only lazy for now. pub a: BigInt, pub idx_var: usize, pub idx_var_next_row: usize, @@ -26,9 +28,13 @@ pub struct Env { pub activated_gadget: Option, } -impl Env { - pub fn new(a: BigInt) -> Self { +impl Env +where + <::Params as CurveConfig>::BaseField: PrimeField, +{ + pub fn new() -> Self { // This check might not be useful + let a: BigInt = ::Params::COEFF_A.to_biguint().into(); assert!( a < C::ScalarField::modulus_biguint().into(), "a is too large" @@ -371,3 +377,12 @@ impl Env { constraints } } + +impl Default for Env +where + <::Params as CurveConfig>::BaseField: PrimeField, +{ + fn default() -> Self { + Self::new() + } +} diff --git a/arrabbiata/tests/constraints.rs b/arrabbiata/tests/constraints.rs index 6d992e4ba8..b15984fd86 100644 --- a/arrabbiata/tests/constraints.rs +++ b/arrabbiata/tests/constraints.rs @@ -4,22 +4,21 @@ use arrabbiata::{ interpreter::{self, Instruction}, }; use mina_curves::pasta::{curves::vesta::Vesta, Pallas}; -use num_bigint::BigInt; use std::collections::HashMap; fn helper_compute_constraints_gadget(instr: Instruction, exp_constraints: usize) { - let mut constraints_fp = constraints::Env::::new(BigInt::from(0_usize)); + let mut constraints_fp = constraints::Env::::new(); interpreter::run_ivc(&mut constraints_fp, instr); assert_eq!(constraints_fp.constraints.len(), exp_constraints); - let mut constraints_fq = constraints::Env::::new(BigInt::from(0_usize)); + let mut constraints_fq = constraints::Env::::new(); interpreter::run_ivc(&mut constraints_fq, instr); assert_eq!(constraints_fq.constraints.len(), exp_constraints); } fn helper_check_expected_degree_constraints(instr: Instruction, exp_degrees: HashMap) { - let mut constraints_fp = constraints::Env::::new(BigInt::from(0_usize)); + let mut constraints_fp = constraints::Env::::new(); interpreter::run_ivc(&mut constraints_fp, instr); let mut actual_degrees: HashMap = HashMap::new(); @@ -48,7 +47,7 @@ fn helper_gadget_number_of_columns_used( exp_nb_columns: usize, exp_nb_public_input: usize, ) { - let mut constraints_fp = constraints::Env::::new(BigInt::from(0_usize)); + let mut constraints_fp = constraints::Env::::new(); interpreter::run_ivc(&mut constraints_fp, instr); let nb_columns = constraints_fp.idx_var; @@ -59,7 +58,7 @@ fn helper_gadget_number_of_columns_used( } fn helper_check_gadget_activated(instr: Instruction, gadget: Gadget) { - let mut constraints_fp = constraints::Env::::new(BigInt::from(0_usize)); + let mut constraints_fp = constraints::Env::::new(); interpreter::run_ivc(&mut constraints_fp, instr); assert_eq!(constraints_fp.activated_gadget, Some(gadget)); @@ -100,7 +99,7 @@ fn test_gadget_elliptic_curve_addition() { #[test] fn test_ivc_total_number_of_constraints_ivc() { - let constraints_fp = constraints::Env::::new(BigInt::from(0_usize)); + let constraints_fp = constraints::Env::::new(); let constraints = constraints_fp.get_all_constraints_for_ivc(); assert_eq!(constraints.len(), 28); @@ -108,7 +107,7 @@ fn test_ivc_total_number_of_constraints_ivc() { #[test] fn test_degree_of_constraints_ivc() { - let constraints_fp = constraints::Env::::new(BigInt::from(0_usize)); + let constraints_fp = constraints::Env::::new(); let constraints = constraints_fp.get_all_constraints_for_ivc();