Skip to content

Commit

Permalink
feat: perform compile-time euclidean division on constants (#3231)
Browse files Browse the repository at this point in the history
  • Loading branch information
TomAFrench authored and guipublic committed Oct 30, 2023
1 parent cd6c003 commit e5eda81
Show file tree
Hide file tree
Showing 7 changed files with 24 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -563,13 +563,36 @@ impl AcirContext {
// lhs = rhs * q + r
//
// If predicate is zero, `q_witness` and `r_witness` will be 0
let zero = self.add_constant(FieldElement::zero());
if self.var_to_expression(predicate)?.is_zero() {
return Ok((zero, zero));
}

match (self.var_to_expression(lhs)?.to_const(), self.var_to_expression(rhs)?.to_const()) {
// If `lhs` and `rhs` are known constants then we can calculate the result at compile time.
// `rhs` must be non-zero.
(Some(lhs_const), Some(rhs_const)) if rhs_const != FieldElement::zero() => {
let quotient = lhs_const.to_u128() / rhs_const.to_u128();
let remainder = lhs_const.to_u128() - quotient * rhs_const.to_u128();

let quotient_var = self.add_constant(FieldElement::from(quotient));
let remainder_var = self.add_constant(FieldElement::from(remainder));
return Ok((quotient_var, remainder_var));
}

// If `rhs` is one then the division is a noop.
(_, Some(rhs_const)) if rhs_const == FieldElement::one() => {
return Ok((lhs, zero));
}

_ => (),
}

// Check that we the rhs is not zero.
// Otherwise, when executing the brillig quotient we may attempt to divide by zero, causing a VM panic.
//
// When the predicate is 0, the equation always passes.
// When the predicate is 1, the rhs must not be 0.
let zero = self.add_constant(FieldElement::zero());
let one = self.add_constant(FieldElement::one());

let rhs_expr = self.var_to_expression(rhs)?;
Expand Down
Binary file modified tooling/nargo_cli/tests/acir_artifacts/conditional_1/target/acir.gz
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified tooling/nargo_cli/tests/acir_artifacts/slices/target/acir.gz
Binary file not shown.

0 comments on commit e5eda81

Please sign in to comment.