Skip to content

Commit

Permalink
feat: enable to_radix for any field element (noir-lang#1343)
Browse files Browse the repository at this point in the history
* Enable to_radix for any field element

* add integration test

* use proper bound during modulo (and small optimisation)

* update integration test
  • Loading branch information
guipublic authored and spalladino committed May 23, 2023
1 parent b7c1561 commit 7234d1f
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
x = "2040124"
_y = "0x2000000000000000000000000000000000000000000000000000000000000000"
23 changes: 18 additions & 5 deletions crates/nargo_cli/tests/test_data/to_bytes_integration/src/main.nr
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
use dep::std;

fn main(x : Field) {
fn main(x : Field, _y: Field) {
// The result of this byte array will be big-endian
let y: Field = 2040124;
let be_byte_array = y.to_be_bytes(31);
// The result of this byte array will be little-endian
let le_byte_array = x.to_le_bytes(31);

constrain le_byte_array[0] == 60;
constrain le_byte_array[0] == be_byte_array[30];
constrain le_byte_array[1] == be_byte_array[29];
constrain le_byte_array[2] == be_byte_array[28];
assert(le_byte_array[0] == 60);
assert(le_byte_array[0] == be_byte_array[30]);
assert(le_byte_array[1] == be_byte_array[29]);
assert(le_byte_array[2] == be_byte_array[28]);

let z = 0 - 1;
let p_bytes = std::field::modulus_le_bytes();
let z_bytes = z.to_le_bytes(32);
assert(p_bytes[10] == z_bytes[10]);
assert(p_bytes[0] == z_bytes[0] as u8 + 1 as u8);

let p_bits = std::field::modulus_le_bits();
let z_bits = z.to_le_bits(std::field::modulus_num_bits() as u32);
assert(z_bits[0] == 0);
assert(p_bits[100] == z_bits[100]);

_y.to_le_bits(std::field::modulus_num_bits() as u32);
}
11 changes: 8 additions & 3 deletions crates/noirc_evaluator/src/ssa/acir_gen/constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,8 @@ pub(crate) fn evaluate_constant_modulo(
) -> Expression {
let modulus = FieldElement::from(rhs as i128);
let modulus_exp = Expression::from_field(modulus);
let modulus_bits = bit_size_u128(rhs as u128);
assert_ne!(rhs, 0);
let modulus_bits = bit_size_u128((rhs - 1) as u128);
assert!(max_bits >= rhs, "max_bits = {max_bits}, rhs = {rhs}");
//0. Check for constant expression. This can happen through arithmetic simplifications
if let Some(a_c) = lhs.to_const() {
Expand All @@ -584,8 +585,12 @@ pub(crate) fn evaluate_constant_modulo(
modulus_bits,
evaluator,
);
try_range_constraint(b_witness, modulus_bits, evaluator);
try_range_constraint(c_witness, max_bits - modulus_bits, evaluator);
//if rhs is a power of 2, then we avoid this range check as it is redundant with the previous one.
if rhs & (rhs - 1) != 0 {
try_range_constraint(b_witness, modulus_bits, evaluator);
}
let c_bound = FieldElement::modulus() / BigUint::from(rhs) - BigUint::one();
try_range_constraint(c_witness, c_bound.bits() as u32, evaluator);

//2. Add the constraint lhs = b+q*rhs
let b_arith = b_witness.into();
Expand Down

0 comments on commit 7234d1f

Please sign in to comment.