From 555d096e85053fa40037916cecd4180bb8bb9a63 Mon Sep 17 00:00:00 2001 From: Avory Date: Mon, 3 Mar 2025 13:27:23 +0200 Subject: [PATCH 1/6] Update mod.rs --- .../acir/src/native_types/expression/mod.rs | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/acvm-repo/acir/src/native_types/expression/mod.rs b/acvm-repo/acir/src/native_types/expression/mod.rs index cdb8974526f..862d30c1060 100644 --- a/acvm-repo/acir/src/native_types/expression/mod.rs +++ b/acvm-repo/acir/src/native_types/expression/mod.rs @@ -21,14 +21,13 @@ pub struct Expression { pub mul_terms: Vec<(F, Witness, Witness)>, pub linear_combinations: Vec<(F, Witness)>, - // TODO: rename q_c to `constant` moreover q_X is not clear to those who - // TODO are not familiar with PLONK - pub q_c: F, + // This is the constant term in the expression + pub constant: F, } impl Default for Expression { fn default() -> Self { - Expression { mul_terms: Vec::new(), linear_combinations: Vec::new(), q_c: F::zero() } + Expression { mul_terms: Vec::new(), linear_combinations: Vec::new(), constant: F::zero() } } } @@ -78,7 +77,7 @@ impl Expression { /// - f(x,y) = x + y would return `None` /// - f(x,y) = 5 would return `FieldElement(5)` pub fn to_const(&self) -> Option<&F> { - self.is_const().then_some(&self.q_c) + self.is_const().then_some(&self.constant) } /// Returns `true` if highest degree term in the expression is one or less. @@ -128,8 +127,8 @@ impl Expression { } impl Expression { - pub fn from_field(q_c: F) -> Self { - Self { q_c, ..Default::default() } + pub fn from_field(constant: F) -> Self { + Self { constant, ..Default::default() } } pub fn zero() -> Self { @@ -157,7 +156,7 @@ impl Expression { // ie where the constant term is 0 and the coefficient in front of the variable is // one. let (coefficient, variable) = self.linear_combinations[0]; - let constant = self.q_c; + let constant = self.constant; if coefficient.is_one() && constant.is_zero() { return Some(variable); @@ -172,16 +171,16 @@ impl Expression { return self.clone(); } else if self.is_const() { let kb = b * k; - return kb + self.q_c; + return kb + self.constant; } else if b.is_const() { - return self.clone() + (k * b.q_c); + return self.clone() + (k * b.constant); } let mut mul_terms: Vec<(F, Witness, Witness)> = Vec::with_capacity(self.mul_terms.len() + b.mul_terms.len()); let mut linear_combinations: Vec<(F, Witness)> = Vec::with_capacity(self.linear_combinations.len() + b.linear_combinations.len()); - let q_c = self.q_c + k * b.q_c; + let constant = self.constant + k * b.constant; //linear combinations let mut i1 = 0; //a @@ -272,7 +271,7 @@ impl Expression { i2 += 1; } - Expression { mul_terms, linear_combinations, q_c } + Expression { mul_terms, linear_combinations, constant } } /// Determine the width of this expression. @@ -332,7 +331,7 @@ impl Expression { impl From for Expression { fn from(constant: F) -> Self { - Expression { q_c: constant, linear_combinations: Vec::new(), mul_terms: Vec::new() } + Expression { constant, linear_combinations: Vec::new(), mul_terms: Vec::new() } } } @@ -344,7 +343,7 @@ impl From for Expression { /// can be seen as a univariate polynomial fn from(wit: Witness) -> Self { Expression { - q_c: F::zero(), + constant: F::zero(), linear_combinations: vec![(F::one(), wit)], mul_terms: Vec::new(), } @@ -372,7 +371,7 @@ mod tests { (FieldElement::from(4u128), Witness(4), Witness(5)), ], linear_combinations: vec![(FieldElement::from(4u128), Witness(4))], - q_c: FieldElement::one(), + constant: FieldElement::one(), }; let result = a.add_mul(k, &b); @@ -385,7 +384,7 @@ mod tests { (FieldElement::from(40u128), Witness(4), Witness(5)), ], linear_combinations: vec![(FieldElement::from(40u128), Witness(4))], - q_c: FieldElement::from(10u128) + constant: FieldElement::from(10u128) } ); } From 59ac56c3fc8b220611527200e062c6435d136fb9 Mon Sep 17 00:00:00 2001 From: Avory Date: Mon, 3 Mar 2025 13:29:13 +0200 Subject: [PATCH 2/6] Update redundant_range.rs --- acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs b/acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs index 67dce75411e..c6e5f2836c3 100644 --- a/acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs +++ b/acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs @@ -57,7 +57,7 @@ impl RangeOptimizer { // as a range opcode for the number of bits required to hold that value. if expr.is_degree_one_univariate() { let (k, witness) = expr.linear_combinations[0]; - let constant = expr.q_c; + let constant = expr.constant; let witness_value = -constant / k; if witness_value.is_zero() { From 7941857ed4b0f21144779af7d9a0725fd04068be Mon Sep 17 00:00:00 2001 From: Avory Date: Mon, 3 Mar 2025 13:29:36 +0200 Subject: [PATCH 3/6] Update csat.rs --- acvm-repo/acvm/src/compiler/transformers/csat.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acvm-repo/acvm/src/compiler/transformers/csat.rs b/acvm-repo/acvm/src/compiler/transformers/csat.rs index 8f890e4ca86..8da77d92833 100644 --- a/acvm-repo/acvm/src/compiler/transformers/csat.rs +++ b/acvm-repo/acvm/src/compiler/transformers/csat.rs @@ -242,7 +242,7 @@ impl CSatTransformer { // Add the rest of the elements back into the new_opcode new_opcode.mul_terms.extend(opcode.mul_terms); new_opcode.linear_combinations.extend(opcode.linear_combinations); - new_opcode.q_c = opcode.q_c; + new_opcode.constant = opcode.constant; new_opcode.sort(); new_opcode } From 47a66440d59e5066332ce250bd41176f016777ad Mon Sep 17 00:00:00 2001 From: Avory Date: Mon, 3 Mar 2025 13:30:01 +0200 Subject: [PATCH 4/6] Update arithmetic.rs --- acvm-repo/acvm/src/pwg/arithmetic.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/acvm-repo/acvm/src/pwg/arithmetic.rs b/acvm-repo/acvm/src/pwg/arithmetic.rs index a2921bcbc9b..d0cf0b883cb 100644 --- a/acvm-repo/acvm/src/pwg/arithmetic.rs +++ b/acvm-repo/acvm/src/pwg/arithmetic.rs @@ -48,7 +48,7 @@ impl ExpressionSolver { (MulTerm::OneUnknown(q, w1), OpcodeStatus::OpcodeSolvable(a, (b, w2))) => { if w1 == w2 { // We have one unknown so we can solve the equation - let total_sum = a + opcode.q_c; + let total_sum = a + opcode.constant; if (q + b).is_zero() { if !total_sum.is_zero() { Err(OpcodeResolutionError::UnsatisfiedConstrain { @@ -77,7 +77,7 @@ impl ExpressionSolver { // Hence the equation is solvable, since there is a single unknown // The equation is: partial_prod * unknown_var + sum + qC = 0 - let total_sum = sum + opcode.q_c; + let total_sum = sum + opcode.constant; if partial_prod.is_zero() { if !total_sum.is_zero() { Err(OpcodeResolutionError::UnsatisfiedConstrain { @@ -95,7 +95,7 @@ impl ExpressionSolver { (MulTerm::Solved(a), OpcodeStatus::OpcodeSatisfied(b)) => { // All the variables in the MulTerm are solved and the Fan-in is also solved // There is nothing to solve - if !(a + b + opcode.q_c).is_zero() { + if !(a + b + opcode.constant).is_zero() { Err(OpcodeResolutionError::UnsatisfiedConstrain { opcode_location: ErrorLocation::Unresolved, payload: None, @@ -111,7 +111,7 @@ impl ExpressionSolver { // The variables in the MulTerm are solved nad there is one unknown in the Fan-in // Hence the equation is solvable, since we have one unknown // The equation is total_prod + partial_sum + coeff * unknown_var + q_C = 0 - let total_sum = total_prod + partial_sum + opcode.q_c; + let total_sum = total_prod + partial_sum + opcode.constant; if coeff.is_zero() { if !total_sum.is_zero() { Err(OpcodeResolutionError::UnsatisfiedConstrain { @@ -233,17 +233,17 @@ impl ExpressionSolver { result.mul_terms.push((c, w1, w2)); } } - MulTerm::Solved(f) => result.q_c += f, + MulTerm::Solved(f) => result.constant += f, } } for &(c, w) in &expr.linear_combinations { if let Some(f) = ExpressionSolver::solve_fan_in_term_helper(&(c, w), initial_witness) { - result.q_c += f; + result.constant += f; } else if !c.is_zero() { result.linear_combinations.push((c, w)); } } - result.q_c += expr.q_c; + result.constant += expr.constant; result } } @@ -261,7 +261,7 @@ mod tests { let opcode_a = Expression { mul_terms: vec![], linear_combinations: vec![(FieldElement::one(), a)], - q_c: -FieldElement::one(), + constant: -FieldElement::one(), }; let mut values = WitnessMap::new(); @@ -285,7 +285,7 @@ mod tests { (-FieldElement::one(), c), (-FieldElement::one(), d), ], - q_c: FieldElement::zero(), + constant: FieldElement::zero(), }; let mut values = WitnessMap::new(); @@ -314,7 +314,7 @@ mod tests { (-FieldElement::one(), c), (-FieldElement::one(), d), ], - q_c: FieldElement::zero(), + constant: FieldElement::zero(), }; let e = Witness(4); @@ -325,7 +325,7 @@ mod tests { (-FieldElement::one(), a), (-FieldElement::one(), b), ], - q_c: FieldElement::zero(), + constant: FieldElement::zero(), }; let mut values = WitnessMap::new(); From a3ba35cf39141a5bf35d5d91712a438c4624dbcf Mon Sep 17 00:00:00 2001 From: Avory Date: Mon, 3 Mar 2025 13:30:26 +0200 Subject: [PATCH 5/6] Update opcodes.rs --- acvm-repo/acir/src/circuit/opcodes.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acvm-repo/acir/src/circuit/opcodes.rs b/acvm-repo/acir/src/circuit/opcodes.rs index dec58b5f90b..3cedb29f02c 100644 --- a/acvm-repo/acir/src/circuit/opcodes.rs +++ b/acvm-repo/acir/src/circuit/opcodes.rs @@ -35,12 +35,12 @@ pub enum Opcode { /// `w=(w_1,..w_n)` is a tuple of `n` witnesses, and `P` is a multi-variate /// polynomial of total degree at most `2`. /// - /// The coefficients `{q_M}_{i,j}, q_i,q_c` of the polynomial are known + /// The coefficients `{q_M}_{i,j}, q_i, constant` of the polynomial are known /// values which define the opcode. /// /// A general expression of assert-zero opcode is the following: /// ```text - /// \sum_{i,j} {q_M}_{i,j}w_iw_j + \sum_i q_iw_i +q_c = 0 + /// \sum_{i,j} {q_M}_{i,j}w_iw_j + \sum_i q_iw_i + constant = 0 /// ``` /// /// An assert-zero opcode can be used to: @@ -140,7 +140,7 @@ impl std::fmt::Display for Opcode { for i in &expr.linear_combinations { write!(f, "({}, _{}) ", i.0, i.1.witness_index())?; } - write!(f, "{}", expr.q_c)?; + write!(f, "{}", expr.constant)?; write!(f, " ]") } From 50ff3d5a5c5f2ea9618b3f5242e8148cffc96a4e Mon Sep 17 00:00:00 2001 From: Avory Date: Mon, 3 Mar 2025 13:30:47 +0200 Subject: [PATCH 6/6] Update operators.rs --- .../src/native_types/expression/operators.rs | 56 ++++++++++--------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/acvm-repo/acir/src/native_types/expression/operators.rs b/acvm-repo/acir/src/native_types/expression/operators.rs index a8f5dc8e7ad..f38bccac5aa 100644 --- a/acvm-repo/acir/src/native_types/expression/operators.rs +++ b/acvm-repo/acir/src/native_types/expression/operators.rs @@ -12,16 +12,20 @@ use super::Expression; impl Neg for &Expression { type Output = Expression; fn neg(self) -> Self::Output { - // XXX(med) : Implement an efficient way to do this + let mut mul_terms = self.mul_terms.clone(); + let mut linear_combinations = self.linear_combinations.clone(); - let mul_terms: Vec<_> = - self.mul_terms.iter().map(|(q_m, w_l, w_r)| (-*q_m, *w_l, *w_r)).collect(); + for (coeff, _, _) in mul_terms.iter_mut() { + *coeff = -*coeff; + } + + for (coeff, _) in linear_combinations.iter_mut() { + *coeff = -*coeff; + } - let linear_combinations: Vec<_> = - self.linear_combinations.iter().map(|(q_k, w_k)| (-*q_k, *w_k)).collect(); - let q_c = -self.q_c; + let constant = -self.constant; - Expression { mul_terms, linear_combinations, q_c } + Expression { mul_terms, linear_combinations, constant } } } @@ -31,9 +35,9 @@ impl Add for Expression { type Output = Self; fn add(self, rhs: F) -> Self::Output { // Increase the constant - let q_c = self.q_c + rhs; + let constant = self.constant + rhs; - Expression { mul_terms: self.mul_terms, q_c, linear_combinations: self.linear_combinations } + Expression { mul_terms: self.mul_terms, constant, linear_combinations: self.linear_combinations } } } @@ -41,9 +45,9 @@ impl Sub for Expression { type Output = Self; fn sub(self, rhs: F) -> Self::Output { // Increase the constant - let q_c = self.q_c - rhs; + let constant = self.constant - rhs; - Expression { mul_terms: self.mul_terms, q_c, linear_combinations: self.linear_combinations } + Expression { mul_terms: self.mul_terms, constant, linear_combinations: self.linear_combinations } } } @@ -59,9 +63,9 @@ impl Mul for &Expression { self.linear_combinations.iter().map(|(q_l, w_l)| (*q_l * rhs, *w_l)).collect(); // Scale the constant - let q_c = self.q_c * rhs; + let constant = self.constant * rhs; - Expression { mul_terms, q_c, linear_combinations: lin_combinations } + Expression { mul_terms, constant, linear_combinations: lin_combinations } } } @@ -119,16 +123,16 @@ impl Mul<&Expression> for &Expression { type Output = Option>; fn mul(self, rhs: &Expression) -> Self::Output { if self.is_const() { - return Some(rhs * self.q_c); + return Some(rhs * self.constant); } else if rhs.is_const() { - return Some(self * rhs.q_c); + return Some(self * rhs.constant); } else if !(self.is_linear() && rhs.is_linear()) { // `Expression`s can only represent terms which are up to degree 2. // We then disallow multiplication of `Expression`s which have degree 2 terms. return None; } - let mut output = Expression::from_field(self.q_c * rhs.q_c); + let mut output = Expression::from_field(self.constant * rhs.constant); //TODO to optimize... for lc in &self.linear_combinations { @@ -144,8 +148,8 @@ impl Mul<&Expression> for &Expression { let (b_c, b_w) = rhs.linear_combinations[i2]; // Apply scaling from multiplication - let a_c = rhs.q_c * a_c; - let b_c = self.q_c * b_c; + let a_c = rhs.constant * a_c; + let b_c = self.constant * b_c; let (coeff, witness) = match a_w.cmp(&b_w) { Ordering::Greater => { @@ -171,7 +175,7 @@ impl Mul<&Expression> for &Expression { } while i1 < self.linear_combinations.len() { let (a_c, a_w) = self.linear_combinations[i1]; - let coeff = rhs.q_c * a_c; + let coeff = rhs.constant * a_c; if !coeff.is_zero() { output.linear_combinations.push((coeff, a_w)); } @@ -179,7 +183,7 @@ impl Mul<&Expression> for &Expression { } while i2 < rhs.linear_combinations.len() { let (b_c, b_w) = rhs.linear_combinations[i2]; - let coeff = self.q_c * b_c; + let coeff = self.constant * b_c; if !coeff.is_zero() { output.linear_combinations.push((coeff, b_w)); } @@ -215,13 +219,13 @@ mod tests { let a = Expression { mul_terms: vec![], linear_combinations: vec![(FieldElement::from(2u128), Witness(2))], - q_c: FieldElement::from(2u128), + constant: FieldElement::from(2u128), }; let b = Expression { mul_terms: vec![], linear_combinations: vec![(FieldElement::from(4u128), Witness(4))], - q_c: FieldElement::one(), + constant: FieldElement::one(), }; assert_eq!( @@ -232,7 +236,7 @@ mod tests { (FieldElement::from(2u128), Witness(2)), (FieldElement::from(4u128), Witness(4)) ], - q_c: FieldElement::from(3u128) + constant: FieldElement::from(3u128) } ); @@ -245,13 +249,13 @@ mod tests { let a = Expression { mul_terms: vec![], linear_combinations: vec![(FieldElement::from(2u128), Witness(2))], - q_c: FieldElement::from(2u128), + constant: FieldElement::from(2u128), }; let b = Expression { mul_terms: vec![], linear_combinations: vec![(FieldElement::from(4u128), Witness(4))], - q_c: FieldElement::one(), + constant: FieldElement::one(), }; assert_eq!( @@ -262,7 +266,7 @@ mod tests { (FieldElement::from(2u128), Witness(2)), (FieldElement::from(8u128), Witness(4)) ], - q_c: FieldElement::from(2u128) + constant: FieldElement::from(2u128) } );