From 86659d36a16610af2bda70cb3aec3b07288385d3 Mon Sep 17 00:00:00 2001 From: Tom French Date: Wed, 6 Nov 2024 14:46:21 +0000 Subject: [PATCH 1/2] chore: add reproduction case for bignum test failure --- .../regression_bignum/Nargo.toml | 7 ++ .../regression_bignum/src/main.nr | 64 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 test_programs/execution_success/regression_bignum/Nargo.toml create mode 100644 test_programs/execution_success/regression_bignum/src/main.nr diff --git a/test_programs/execution_success/regression_bignum/Nargo.toml b/test_programs/execution_success/regression_bignum/Nargo.toml new file mode 100644 index 00000000000..5cadd364e43 --- /dev/null +++ b/test_programs/execution_success/regression_bignum/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "regression_bignum" +version = "0.1.0" +type = "bin" +authors = [""] + +[dependencies] diff --git a/test_programs/execution_success/regression_bignum/src/main.nr b/test_programs/execution_success/regression_bignum/src/main.nr new file mode 100644 index 00000000000..aea1ad3f47d --- /dev/null +++ b/test_programs/execution_success/regression_bignum/src/main.nr @@ -0,0 +1,64 @@ +pub struct U60Repr { + limbs: [u64; N * NumSegments], +} + +fn main() { + let numerator = + [790096867046896348, 1063071665130103641, 602707730209562162, 996751591622961462, 28650, 0]; + let denominator = [12, 0, 0, 0, 0, 0]; + + unsafe { __udiv_mod(numerator) }; + + let result = unsafe { __validate_gt_remainder(denominator) }; + assert(result[4] == 0); + assert(result[5] == 0); +} + +unconstrained fn __udiv_mod(remainder_u60: [u64; 2 * N]) { + let bit_difference = get_msb(remainder_u60); + let mut accumulator_u60: U60Repr = U60Repr { limbs: [0; N * 2] }; + accumulator_u60.limbs[0] = 1; + accumulator_u60 = shl(accumulator_u60, bit_difference); +} + +unconstrained fn __validate_gt_remainder(a_u60: [u64; N]) -> [u64; N] { + let mut addend_u60: [u64; N] = [0; N]; + let mut result_u60: [u64; N] = [0; N]; + + for i in 0..N { + result_u60[i] = a_u60[i] + addend_u60[i]; + } + + result_u60 +} + +unconstrained fn get_msb(val: [u64; N]) -> u32 { + let mut count = 0; + for i in 0..N { + let v = val[(N - 1) - i]; + if (v > 0) { + count = 60 * ((N - 1) - i); + break; + } + } + count +} + +fn shl(val: U60Repr, shift: u32) -> U60Repr { + let mut result: U60Repr = U60Repr { limbs: [0; 2 * N] }; + + let num_shifted_limbs = shift / 60; + let limb_shift = (shift % 60) as u8; + + let mask: u64 = (1 as u64 << 60) - 1; + let value = val.limbs[0]; + + result.limbs[num_shifted_limbs] = (value << limb_shift) & mask; + + for i in 1..((N * 2) - num_shifted_limbs) { + let value = val.limbs[i]; + let upshift = (value << limb_shift) & mask; + result.limbs[i + num_shifted_limbs] = upshift; + } + result +} From 5eb795731a57c4403c9d6a9bd1eb2c5586e9a0f7 Mon Sep 17 00:00:00 2001 From: Tom French Date: Wed, 6 Nov 2024 15:28:55 +0000 Subject: [PATCH 2/2] chore: more reductions --- .../regression_bignum/src/main.nr | 45 +++++++------------ 1 file changed, 16 insertions(+), 29 deletions(-) diff --git a/test_programs/execution_success/regression_bignum/src/main.nr b/test_programs/execution_success/regression_bignum/src/main.nr index aea1ad3f47d..013ab6b2023 100644 --- a/test_programs/execution_success/regression_bignum/src/main.nr +++ b/test_programs/execution_success/regression_bignum/src/main.nr @@ -1,64 +1,51 @@ -pub struct U60Repr { - limbs: [u64; N * NumSegments], -} - fn main() { let numerator = [790096867046896348, 1063071665130103641, 602707730209562162, 996751591622961462, 28650, 0]; - let denominator = [12, 0, 0, 0, 0, 0]; - unsafe { __udiv_mod(numerator) }; + let denominator = [12, 0, 0, 0, 0, 0]; let result = unsafe { __validate_gt_remainder(denominator) }; assert(result[4] == 0); assert(result[5] == 0); } -unconstrained fn __udiv_mod(remainder_u60: [u64; 2 * N]) { +unconstrained fn __udiv_mod(remainder_u60: [u64; 6]) { let bit_difference = get_msb(remainder_u60); - let mut accumulator_u60: U60Repr = U60Repr { limbs: [0; N * 2] }; - accumulator_u60.limbs[0] = 1; - accumulator_u60 = shl(accumulator_u60, bit_difference); + let accumulator_u60: [u64; 6] = shl(bit_difference); } -unconstrained fn __validate_gt_remainder(a_u60: [u64; N]) -> [u64; N] { - let mut addend_u60: [u64; N] = [0; N]; - let mut result_u60: [u64; N] = [0; N]; +unconstrained fn __validate_gt_remainder(a_u60: [u64; 6]) -> [u64; 6] { + let mut addend_u60: [u64; 6] = [0; 6]; + let mut result_u60: [u64; 6] = [0; 6]; - for i in 0..N { + for i in 0..6 { result_u60[i] = a_u60[i] + addend_u60[i]; } result_u60 } -unconstrained fn get_msb(val: [u64; N]) -> u32 { +unconstrained fn get_msb(val: [u64; 6]) -> u32 { let mut count = 0; - for i in 0..N { - let v = val[(N - 1) - i]; + for i in 0..6 { + let v = val[(6 - 1) - i]; if (v > 0) { - count = 60 * ((N - 1) - i); + count = 60 * ((6 - 1) - i); break; } } count } -fn shl(val: U60Repr, shift: u32) -> U60Repr { - let mut result: U60Repr = U60Repr { limbs: [0; 2 * N] }; - +unconstrained fn shl(shift: u32) -> [u64; 6] { let num_shifted_limbs = shift / 60; let limb_shift = (shift % 60) as u8; - let mask: u64 = (1 as u64 << 60) - 1; - let value = val.limbs[0]; - - result.limbs[num_shifted_limbs] = (value << limb_shift) & mask; + let mut result = [0; 6]; + result[num_shifted_limbs] = (1 << limb_shift); - for i in 1..((N * 2) - num_shifted_limbs) { - let value = val.limbs[i]; - let upshift = (value << limb_shift) & mask; - result.limbs[i + num_shifted_limbs] = upshift; + for i in 1..(6 - num_shifted_limbs) { + result[i + num_shifted_limbs] = 0; } result }