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 +}