Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arrabbiata: move challenge semantic into its own module #3024

Merged
merged 1 commit into from
Feb 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions arrabbiata/src/challenge.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
use ark_ff::{Field, Zero};
use core::{
fmt::{Display, Formatter, Result},
ops::Index,
};
use kimchi::circuits::expr::AlphaChallengeTerm;
use serde::{Deserialize, Serialize};
use strum::EnumCount;
use strum_macros::EnumCount as EnumCountMacro;

#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, EnumCountMacro)]
pub enum ChallengeTerm {
/// Used to aggregate the constraints describing the relation. It is used to
/// enforce all constraints are satisfied at the same time.
/// Often noted `α`.
ConstraintRandomiser,
/// Both challenges used in the permutation argument
Beta,
Gamma,
/// Used to homogenize the constraints and allow the protocol to fold two
/// instances of the same relation into a new one.
/// Often noted `u` in the paper mentioning "folding protocols".
ConstraintHomogeniser,
/// Used by the accumulation protocol (folding) to perform a random linear
/// transformation of the witnesses and the public values.
/// Often noted `r` in the paper mentioning "folding protocols".
RelationRandomiser,
}

impl Display for ChallengeTerm {
fn fmt(&self, f: &mut Formatter) -> Result {
match self {
ChallengeTerm::ConstraintRandomiser => write!(f, "alpha"),
ChallengeTerm::Beta => write!(f, "beta"),
ChallengeTerm::Gamma => write!(f, "gamma"),
ChallengeTerm::ConstraintHomogeniser => write!(f, "u"),
ChallengeTerm::RelationRandomiser => write!(f, "r"),
}
}
}

pub struct Challenges<F> {
/// Used to aggregate the constraints describing the relation. It is used to
/// enforce all constraints are satisfied at the same time.
/// Often noted `α`.
pub constraint_randomiser: F,

/// Both challenges used in the permutation argument.
pub beta: F,
pub gamma: F,

/// Used to homogenize the constraints and allow the protocol to fold two
/// instances of the same relation into a new one.
/// Often noted `u` in the paper mentioning "folding protocols".
pub constraint_homogeniser: F,

/// Used by the accumulation protocol (folding) to perform a random linear
/// transformation of the witnesses and the public values.
/// Often noted `r` in the paper mentioning "folding protocols".
pub relation_randomiser: F,
}

impl<F> Index<usize> for Challenges<F> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it's outside the scope of the PR, but I don't like having Index, only Index should be used

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the comment.

type Output = F;

fn index(&self, index: usize) -> &Self::Output {
if index == 0 {
&self.constraint_randomiser
} else if index == 1 {
&self.beta
} else if index == 2 {
&self.gamma
} else if index == 3 {
&self.constraint_homogeniser
} else if index == 4 {
&self.relation_randomiser
} else {
panic!(
"Index out of bounds, only {} are defined",
ChallengeTerm::COUNT
)
}
}
}

impl<F: Zero> Default for Challenges<F> {
fn default() -> Self {
Self {
constraint_randomiser: F::zero(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit
Also outside of the scope, but the alpha field would better be called contraint_combiner.
The term constraint_randomiser indicates a prover coined random to achieve some zk property
same remark for relation_randomiser

Given that the field are documented it's nonentheless understandable

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Let me change this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #3031

beta: F::zero(),
gamma: F::zero(),
constraint_homogeniser: F::zero(),
relation_randomiser: F::zero(),
}
}
}

impl<F: Field> Index<ChallengeTerm> for Challenges<F> {
type Output = F;

fn index(&self, term: ChallengeTerm) -> &Self::Output {
match term {
ChallengeTerm::ConstraintRandomiser => &self.constraint_randomiser,
ChallengeTerm::Beta => &self.beta,
ChallengeTerm::Gamma => &self.gamma,
ChallengeTerm::ConstraintHomogeniser => &self.constraint_homogeniser,
ChallengeTerm::RelationRandomiser => &self.relation_randomiser,
}
}
}

impl<'a> AlphaChallengeTerm<'a> for ChallengeTerm {
const ALPHA: Self = Self::ConstraintRandomiser;
}
116 changes: 3 additions & 113 deletions arrabbiata/src/columns.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
use ark_ff::{Field, Zero};
use kimchi::circuits::expr::{AlphaChallengeTerm, CacheId, ConstantExpr, Expr, FormattedOutput};
use serde::{Deserialize, Serialize};
use std::{
collections::HashMap,
fmt::{Display, Formatter, Result},
ops::Index,
};
use strum::EnumCount;
use crate::challenge::ChallengeTerm;
use kimchi::circuits::expr::{CacheId, ConstantExpr, Expr, FormattedOutput};
use std::collections::HashMap;
use strum_macros::{EnumCount as EnumCountMacro, EnumIter};

use crate::NUMBER_OF_COLUMNS;
Expand Down Expand Up @@ -60,110 +54,6 @@ impl From<Column> for usize {
}
}

pub struct Challenges<F> {
/// Used to aggregate the constraints describing the relation. It is used to
/// enforce all constraints are satisfied at the same time.
/// Often noted `α`.
pub constraint_randomiser: F,

/// Both challenges used in the permutation argument.
pub beta: F,
pub gamma: F,

/// Used to homogenize the constraints and allow the protocol to fold two
/// instances of the same relation into a new one.
/// Often noted `u` in the paper mentioning "folding protocols".
pub constraint_homogeniser: F,

/// Used by the accumulation protocol (folding) to perform a random linear
/// transformation of the witnesses and the public values.
/// Often noted `r` in the paper mentioning "folding protocols".
pub relation_randomiser: F,
}

impl<F> Index<usize> for Challenges<F> {
type Output = F;

fn index(&self, index: usize) -> &Self::Output {
if index == 0 {
&self.constraint_randomiser
} else if index == 1 {
&self.beta
} else if index == 2 {
&self.gamma
} else if index == 3 {
&self.constraint_homogeniser
} else if index == 4 {
&self.relation_randomiser
} else {
panic!(
"Index out of bounds, only {} are defined",
ChallengeTerm::COUNT
)
}
}
}

impl<F: Zero> Default for Challenges<F> {
fn default() -> Self {
Self {
constraint_randomiser: F::zero(),
beta: F::zero(),
gamma: F::zero(),
constraint_homogeniser: F::zero(),
relation_randomiser: F::zero(),
}
}
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, EnumCountMacro)]
pub enum ChallengeTerm {
/// Used to aggregate the constraints describing the relation. It is used to
/// enforce all constraints are satisfied at the same time.
/// Often noted `α`.
ConstraintRandomiser,
/// Both challenges used in the permutation argument
Beta,
Gamma,
/// Used to homogenize the constraints and allow the protocol to fold two
/// instances of the same relation into a new one.
/// Often noted `u` in the paper mentioning "folding protocols".
ConstraintHomogeniser,
/// Used by the accumulation protocol (folding) to perform a random linear
/// transformation of the witnesses and the public values.
/// Often noted `r` in the paper mentioning "folding protocols".
RelationRandomiser,
}

impl Display for ChallengeTerm {
fn fmt(&self, f: &mut Formatter) -> Result {
match self {
ChallengeTerm::ConstraintRandomiser => write!(f, "alpha"),
ChallengeTerm::Beta => write!(f, "beta"),
ChallengeTerm::Gamma => write!(f, "gamma"),
ChallengeTerm::ConstraintHomogeniser => write!(f, "u"),
ChallengeTerm::RelationRandomiser => write!(f, "r"),
}
}
}
impl<F: Field> Index<ChallengeTerm> for Challenges<F> {
type Output = F;

fn index(&self, term: ChallengeTerm) -> &Self::Output {
match term {
ChallengeTerm::ConstraintRandomiser => &self.constraint_randomiser,
ChallengeTerm::Beta => &self.beta,
ChallengeTerm::Gamma => &self.gamma,
ChallengeTerm::ConstraintHomogeniser => &self.constraint_homogeniser,
ChallengeTerm::RelationRandomiser => &self.relation_randomiser,
}
}
}

impl<'a> AlphaChallengeTerm<'a> for ChallengeTerm {
const ALPHA: Self = Self::ConstraintRandomiser;
}

pub type E<Fp> = Expr<ConstantExpr<Fp, ChallengeTerm>, Column>;

// Code to allow for pretty printing of the expressions
Expand Down
1 change: 1 addition & 0 deletions arrabbiata/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use curve::PlonkSpongeConstants;
use mina_poseidon::constants::SpongeConstants;
use strum::EnumCount as _;

pub mod challenge;
pub mod column_env;
pub mod columns;
pub mod constraints;
Expand Down
3 changes: 2 additions & 1 deletion arrabbiata/src/witness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
use std::time::Instant;

use crate::{
columns::{Challenges, Column, Gadget},
challenge::Challenges,
columns::{Column, Gadget},
curve::{ArrabbiataCurve, PlonkSpongeConstants},
interpreter::{Instruction, InterpreterEnv, Side},
MAXIMUM_FIELD_SIZE_IN_BITS, NUMBER_OF_COLUMNS, NUMBER_OF_PUBLIC_INPUTS, NUMBER_OF_SELECTORS,
Expand Down
Loading