Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
dannywillems committed Oct 15, 2024
1 parent fe76cbf commit 0c4a444
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 51 deletions.
30 changes: 17 additions & 13 deletions mvpoly/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ pub trait MVPoly<F: PrimeField, const N: usize, const D: usize>:
/// speed up the computation.
fn eval(&self, x: &[F; N]) -> F;


/// Build the univariate polynomial `x_i` from the variable `i`.
/// The conversion into the type `usize` is unspecified by this trait. It
/// is left to the trait implementation.
Expand All @@ -93,7 +92,12 @@ pub trait MVPoly<F: PrimeField, const N: usize, const D: usize>:
/// used.
/// For [crate::monomials], the output must be the index of the variable,
/// starting from `0`.
fn from_variable<Column: Into<usize>>(var: Variable<Column>) -> Self;
///
/// The parameter `offset_next_row` is an optional argument that is used to
/// support the case where the "next row" is used. In this case, the type
/// parameter `N` must include this offset (i.e. if 4 variables are in ued,
/// N should be at least `8 = 2 * 4`).
fn from_variable<Column: Into<usize>>(var: Variable<Column>, offset_next_row: Option<usize>) -> Self;

fn from_constant<ChallengeTerm: Clone>(op: Operations<ConstantExprInner<F, ChallengeTerm>>) -> Self {
use kimchi::circuits::expr::Operations::*;
Expand Down Expand Up @@ -145,7 +149,7 @@ pub trait MVPoly<F: PrimeField, const N: usize, const D: usize>:
/// "the expression framework".
/// In the near future, the "expression framework" should be moved also into
/// this library.
fn from_expr<Column: Into<usize>, ChallengeTerm: Clone>(expr: Expr<ConstantExpr<F, ChallengeTerm>, Column>) -> Self {
fn from_expr<Column: Into<usize>, ChallengeTerm: Clone>(expr: Expr<ConstantExpr<F, ChallengeTerm>, Column>, offset_next_row: Option<usize>) -> Self {
use kimchi::circuits::expr::Operations::*;

match expr {
Expand All @@ -159,36 +163,36 @@ pub trait MVPoly<F: PrimeField, const N: usize, const D: usize>:
}
ExprInner::Constant(c) => Self::from_constant(c),
ExprInner::Cell(var) => {
Self::from_variable(var)
Self::from_variable::<Column>(var, offset_next_row)
}
}
}
Add(e1, e2) => {
let p1 = Self::from_expr(*e1);
let p2 = Self::from_expr(*e2);
let p1 = Self::from_expr::<Column, ChallengeTerm>(*e1, offset_next_row);
let p2 = Self::from_expr::<Column, ChallengeTerm>(*e2, offset_next_row);
p1 + p2
}
Sub(e1, e2) => {
let p1 = Self::from_expr(*e1);
let p2 = Self::from_expr(*e2);
let p1 = Self::from_expr::<Column, ChallengeTerm>(*e1, offset_next_row);
let p2 = Self::from_expr::<Column, ChallengeTerm>(*e2, offset_next_row);
p1 - p2
}
Mul(e1, e2) => {
let p1 = Self::from_expr(*e1);
let p2 = Self::from_expr(*e2);
let p1 = Self::from_expr::<Column, ChallengeTerm>(*e1, offset_next_row);
let p2 = Self::from_expr::<Column, ChallengeTerm>(*e2, offset_next_row);
p1 * p2
}
Double(p) => {
let p = Self::from_expr(*p);
let p = Self::from_expr::<Column, ChallengeTerm>(*p, offset_next_row);
p.double()
}
Square(p) => {
let p = Self::from_expr(*p);
let p = Self::from_expr::<Column, ChallengeTerm>(*p, offset_next_row);
p.clone() * p.clone()
}
Pow(c, e) => {
// FIXME: dummy implementation
let p = Self::from_expr(*c);
let p = Self::from_expr::<Column, ChallengeTerm>(*c, offset_next_row);
let mut result = p.clone();
for _ in 0..e {
result = result.clone() * p.clone();
Expand Down
24 changes: 17 additions & 7 deletions mvpoly/src/monomials.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,16 +356,26 @@ impl<const N: usize, const D: usize, F: PrimeField> MVPoly<F, N, D> for Sparse<F
prime::Dense::random(rng, max_degree).into()
}

fn from_variable<Column: Into<usize>>(var: Variable<Column>) -> Self {
fn from_variable<Column: Into<usize>>(
var: Variable<Column>,
offset_next_row: Option<usize>,
) -> Self {
let Variable { col, row } = var;
assert_eq!(
row,
CurrOrNext::Curr,
"Only current row is supported for now. You cannot reference the next row"
);
if row == CurrOrNext::Next {
assert!(
offset_next_row.is_some(),
"The offset must be provided for the next row"
);
}
let var_usize: usize = col.into();
let mut monomials = HashMap::new();
let exponents: [usize; N] = std::array::from_fn(|i| if i == var_usize { 1 } else { 0 });
let offset = if row == CurrOrNext::Curr {
0
} else {
offset_next_row.unwrap()
};
let exponents: [usize; N] =
std::array::from_fn(|i| if i == offset + var_usize { 1 } else { 0 });
monomials.insert(exponents, F::one());
Self { monomials }
}
Expand Down
28 changes: 19 additions & 9 deletions mvpoly/src/prime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,22 +338,32 @@ impl<F: PrimeField, const N: usize, const D: usize> MVPoly<F, N, D> for Dense<F,
})
}

fn from_variable<Column: Into<usize>>(var: Variable<Column>) -> Self {
fn from_variable<Column: Into<usize>>(
var: Variable<Column>,
offset_next_row: Option<usize>,
) -> Self {
let Variable { col, row } = var;
assert_eq!(
row,
CurrOrNext::Curr,
"Only current row is supported for now. You cannot reference the next row"
);
if row == CurrOrNext::Next {
assert!(
offset_next_row.is_some(),
"The offset for the next row must be provided"
);
}
let offset = if row == CurrOrNext::Curr {
0
} else {
offset_next_row.unwrap()
};
let var_usize: usize = col.into();
let idx = var_usize + offset;
let mut res = Self::zero();
let mut prime_gen = PrimeNumberGenerator::new();
let primes = prime_gen.get_first_nth_primes(N);
let var_usize: usize = col.into();
assert!(primes.contains(&var_usize), "The usize representation of the variable must be a prime number, and unique for each variable");
assert!(primes.contains(&idx), "The usize representation of the variable must be a prime number, and unique for each variable");
let inv_var = res
.normalized_indices
.iter()
.position(|&x| x == var_usize)
.position(|&x| x == idx)
.unwrap();
res[inv_var] = F::one();
res
Expand Down
17 changes: 10 additions & 7 deletions mvpoly/tests/monomials.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,10 +466,13 @@ fn test_build_from_variable() {

let mut rng = o1_utils::tests::make_test_rng(None);
let idx: usize = rng.gen_range(0..4);
let p = Sparse::<Fp, 4, 3>::from_variable(Variable {
col: Column::X(idx),
row: CurrOrNext::Curr,
});
let p = Sparse::<Fp, 4, 3>::from_variable::<Column>(
Variable {
col: Column::X(idx),
row: CurrOrNext::Curr,
},
None,
);

let eval: [Fp; 4] = std::array::from_fn(|_i| Fp::rand(&mut rng));

Expand Down Expand Up @@ -599,7 +602,7 @@ fn test_from_expr_ec_addition() {
// - Constraint 1: λ (X1 - X2) - Y1 + Y2 = 0
let expression = lambda.clone() * (x1.clone() - x2.clone()) - (y1.clone() - y2.clone());

let p = Sparse::<Fp, 7, 2>::from_expr(expression);
let p = Sparse::<Fp, 7, 2>::from_expr::<Column, BerkeleyChallengeTerm>(expression, None);
let random_evaluation: [Fp; 7] = std::array::from_fn(|_| Fp::rand(&mut rng));
let eval = p.eval(&random_evaluation);
let exp_eval = {
Expand All @@ -612,7 +615,7 @@ fn test_from_expr_ec_addition() {
{
// - Constraint 2: X3 + X1 + X2 - λ^2 = 0
let expr = x3.clone() + x1.clone() + x2.clone() - lambda.clone() * lambda.clone();
let p = Sparse::<Fp, 7, 2>::from_expr(expr);
let p = Sparse::<Fp, 7, 2>::from_expr::<Column, BerkeleyChallengeTerm>(expr, None);
let random_evaluation: [Fp; 7] = std::array::from_fn(|_| Fp::rand(&mut rng));
let eval = p.eval(&random_evaluation);
let exp_eval = {
Expand All @@ -624,7 +627,7 @@ fn test_from_expr_ec_addition() {
{
// - Constraint 3: Y3 - λ (X1 - X3) + Y1 = 0
let expr = y3.clone() - lambda.clone() * (x1.clone() - x3.clone()) + y1.clone();
let p = Sparse::<Fp, 7, 2>::from_expr(expr);
let p = Sparse::<Fp, 7, 2>::from_expr::<Column, BerkeleyChallengeTerm>(expr, None);
let random_evaluation: [Fp; 7] = std::array::from_fn(|_| Fp::rand(&mut rng));
let eval = p.eval(&random_evaluation);
let exp_eval = {
Expand Down
39 changes: 24 additions & 15 deletions mvpoly/tests/prime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,10 +264,13 @@ fn test_from_variable_column() {
}
}

let p = Dense::<Fp, 4, 5>::from_variable(Variable {
col: Column::X(0),
row: CurrOrNext::Curr,
});
let p = Dense::<Fp, 4, 5>::from_variable::<Column>(
Variable {
col: Column::X(0),
row: CurrOrNext::Curr,
},
None,
);
assert_eq!(p[0], Fp::zero());
assert_eq!(p[1], Fp::one());
assert_eq!(p[2], Fp::zero());
Expand All @@ -276,21 +279,27 @@ fn test_from_variable_column() {
assert_eq!(p[5], Fp::zero());

// Test for z variable (index 3)
let p = Dense::<Fp, 4, 5>::from_variable(Variable {
col: Column::X(1),
row: CurrOrNext::Curr,
});
let p = Dense::<Fp, 4, 5>::from_variable::<Column>(
Variable {
col: Column::X(1),
row: CurrOrNext::Curr,
},
None,
);
assert_eq!(p[0], Fp::zero());
assert_eq!(p[1], Fp::zero());
assert_eq!(p[2], Fp::one());
assert_eq!(p[3], Fp::zero());
assert_eq!(p[4], Fp::zero());

// Test for w variable (index 5)
let p = Dense::<Fp, 4, 5>::from_variable(Variable {
col: Column::X(2),
row: CurrOrNext::Curr,
});
let p = Dense::<Fp, 4, 5>::from_variable::<Column>(
Variable {
col: Column::X(2),
row: CurrOrNext::Curr,
},
None,
);
assert_eq!(p[0], Fp::zero());
assert_eq!(p[1], Fp::zero());
assert_eq!(p[2], Fp::zero());
Expand Down Expand Up @@ -459,7 +468,7 @@ fn test_from_expr_ec_addition() {
// - Constraint 1: λ (X1 - X2) - Y1 + Y2 = 0
let expression = lambda.clone() * (x1.clone() - x2.clone()) - (y1.clone() - y2.clone());

let p = Dense::<Fp, 7, 2>::from_expr(expression);
let p = Dense::<Fp, 7, 2>::from_expr::<Column, BerkeleyChallengeTerm>(expression, None);
let random_evaluation: [Fp; 7] = std::array::from_fn(|_| Fp::rand(&mut rng));
let eval = p.eval(&random_evaluation);
let exp_eval = {
Expand All @@ -472,7 +481,7 @@ fn test_from_expr_ec_addition() {
{
// - Constraint 2: X3 + X1 + X2 - λ^2 = 0
let expr = x3.clone() + x1.clone() + x2.clone() - lambda.clone() * lambda.clone();
let p = Dense::<Fp, 7, 2>::from_expr(expr);
let p = Dense::<Fp, 7, 2>::from_expr::<Column, BerkeleyChallengeTerm>(expr, None);
let random_evaluation: [Fp; 7] = std::array::from_fn(|_| Fp::rand(&mut rng));
let eval = p.eval(&random_evaluation);
let exp_eval = {
Expand All @@ -484,7 +493,7 @@ fn test_from_expr_ec_addition() {
{
// - Constraint 3: Y3 - λ (X1 - X3) + Y1 = 0
let expr = y3.clone() - lambda.clone() * (x1.clone() - x3.clone()) + y1.clone();
let p = Dense::<Fp, 7, 2>::from_expr(expr);
let p = Dense::<Fp, 7, 2>::from_expr::<Column, BerkeleyChallengeTerm>(expr, None);
let random_evaluation: [Fp; 7] = std::array::from_fn(|_| Fp::rand(&mut rng));
let eval = p.eval(&random_evaluation);
let exp_eval = {
Expand Down

0 comments on commit 0c4a444

Please sign in to comment.