From 8e9b6122532079ecf71aafe448265797828b69cf Mon Sep 17 00:00:00 2001 From: joss-aztec <94053499+joss-aztec@users.noreply.github.com> Date: Fri, 16 Jun 2023 18:08:16 +0100 Subject: [PATCH] fix(ssa refactor): pad radix result (#1730) * fix(ssa refactor): pad radix result * chore(ssa refactor): cp working test * fix(ssa refactor): padding always at end --- .../test_data_ssa_refactor/to_le_bytes/Nargo.toml | 5 +++++ .../test_data_ssa_refactor/to_le_bytes/Prover.toml | 1 + .../test_data_ssa_refactor/to_le_bytes/src/main.nr | 14 ++++++++++++++ .../ssa_refactor/acir_gen/acir_ir/acir_variable.rs | 13 ++++++++++++- .../acir_gen/acir_ir/generated_acir.rs | 2 +- 5 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 crates/nargo_cli/tests/test_data_ssa_refactor/to_le_bytes/Nargo.toml create mode 100644 crates/nargo_cli/tests/test_data_ssa_refactor/to_le_bytes/Prover.toml create mode 100644 crates/nargo_cli/tests/test_data_ssa_refactor/to_le_bytes/src/main.nr diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/to_le_bytes/Nargo.toml b/crates/nargo_cli/tests/test_data_ssa_refactor/to_le_bytes/Nargo.toml new file mode 100644 index 00000000000..e0b467ce5da --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/to_le_bytes/Nargo.toml @@ -0,0 +1,5 @@ +[package] +authors = [""] +compiler_version = "0.1" + +[dependencies] \ No newline at end of file diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/to_le_bytes/Prover.toml b/crates/nargo_cli/tests/test_data_ssa_refactor/to_le_bytes/Prover.toml new file mode 100644 index 00000000000..07fe857ac7c --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/to_le_bytes/Prover.toml @@ -0,0 +1 @@ +x = "2040124" diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/to_le_bytes/src/main.nr b/crates/nargo_cli/tests/test_data_ssa_refactor/to_le_bytes/src/main.nr new file mode 100644 index 00000000000..a5476ec13bf --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/to_le_bytes/src/main.nr @@ -0,0 +1,14 @@ +use dep::std; + +fn main(x : Field) -> pub [u8; 4] { + // The result of this byte array will be little-endian + let byte_array = x.to_le_bytes(31); + let mut first_four_bytes = [0; 4]; + for i in 0..4 { + first_four_bytes[i] = byte_array[i]; + } + // Issue #617 fix + // We were incorrectly mapping our output array from bit decomposition functions during acir generation + first_four_bytes[3] = byte_array[31]; + first_four_bytes +} diff --git a/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/acir_variable.rs b/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/acir_variable.rs index 68bc94e8899..4e3cb9406e9 100644 --- a/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/acir_variable.rs +++ b/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/acir_variable.rs @@ -592,7 +592,8 @@ impl AcirContext { let input_expr = &self.vars[input_var].to_expression(); - let limbs = self.acir_ir.radix_le_decompose(input_expr, radix, limb_count)?; + let bit_size = u32::BITS - (radix - 1).leading_zeros(); + let limbs = self.acir_ir.radix_le_decompose(input_expr, radix, limb_count, bit_size)?; let mut limb_vars = vecmap(limbs, |witness| { let witness = self.add_data(AcirVarData::Witness(witness)); @@ -603,6 +604,16 @@ impl AcirContext { limb_vars.reverse(); } + // For legacy reasons (see #617) the to_radix interface supports 256 bits even though + // FieldElement::max_num_bits() is only 254 bits. Any limbs beyond the specified count + // become zero padding. + let max_decomposable_bits: u32 = 256; + let limb_count_with_padding = max_decomposable_bits / bit_size; + let zero = self.add_constant(FieldElement::zero()); + while limb_vars.len() < limb_count_with_padding as usize { + limb_vars.push(AcirValue::Var(zero, result_element_type)); + } + Ok(vec![AcirValue::Array(limb_vars.into())]) } diff --git a/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/generated_acir.rs b/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/generated_acir.rs index 44d50da12c6..19f8e95e6a7 100644 --- a/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/generated_acir.rs +++ b/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/generated_acir.rs @@ -269,8 +269,8 @@ impl GeneratedAcir { input_expr: &Expression, radix: u32, limb_count: u32, + bit_size: u32, ) -> Result, AcirGenError> { - let bit_size = u32::BITS - (radix - 1).leading_zeros(); let radix_big = BigUint::from(radix); assert_eq!( BigUint::from(2u128).pow(bit_size),