From 08c4151f12cc4fe1831da2eba6c854948a17c3d8 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Thu, 7 Nov 2024 14:10:36 +0000 Subject: [PATCH] feat: remove a bunch of unnecessary bytecode from unconstrained ops (#50) --- src/fns/unconstrained_helpers.nr | 72 +++++++++++++++----------------- 1 file changed, 34 insertions(+), 38 deletions(-) diff --git a/src/fns/unconstrained_helpers.nr b/src/fns/unconstrained_helpers.nr index d19c204..67d3fc4 100644 --- a/src/fns/unconstrained_helpers.nr +++ b/src/fns/unconstrained_helpers.nr @@ -4,6 +4,8 @@ use crate::utils::u60_representation::U60Repr; use crate::fns::unconstrained_ops::{__add, __eq, __mul, __neg, __one, __pow}; use crate::params::BigNumParams as P; +global TWO_POW_60: u64 = 0x1000000000000000; + /** * In this file: * @@ -39,24 +41,22 @@ pub(crate) unconstrained fn __validate_gt_remainder( let underflow = b_u60.gte(a_u60); b_u60 += U60Repr::one(); assert(underflow == false, "BigNum::validate_gt check fails"); - let mut addend_u60: U60Repr = U60Repr { limbs: [0; 2 * N] }; let mut result_u60: U60Repr = U60Repr { limbs: [0; 2 * N] }; - let mut carry: u64 = 0; let mut carry_in: u64 = 0; - let mut borrow: u64 = 0; let mut borrow_in: u64 = 0; let mut borrow_flags: [bool; N] = [false; N]; let mut carry_flags: [bool; N] = [false; N]; for i in 0..2 * N { - let mut add_term: u64 = a_u60.limbs[i] + addend_u60.limbs[i] + carry_in; - carry = (add_term >= 0x1000000000000000) as u64; - add_term -= (carry as u64 * 0x1000000000000000); - result_u60.limbs[i] = add_term; - carry_in = carry as u64; - borrow = ((b_u60.limbs[i] + borrow_in) > result_u60.limbs[i]) as u64; - let sub = (borrow << 60) + result_u60.limbs[i] - b_u60.limbs[i] - borrow_in; - result_u60.limbs[i] = sub; + let mut add_term: u64 = a_u60.limbs[i] + carry_in; + let mut carry = (add_term >= TWO_POW_60) as u64; + add_term -= carry * TWO_POW_60; + carry_in = carry; + + let sub_term = b_u60.limbs[i] + borrow_in; + let mut borrow = (sub_term > add_term) as u64; + result_u60.limbs[i] = borrow * TWO_POW_60 + add_term - sub_term; + borrow_in = borrow; if ((i & 1) == 1) { @@ -80,14 +80,14 @@ pub(crate) unconstrained fn __neg_with_flags( let x_u60: U60Repr = U60Repr::from(val); let mut result_u60: U60Repr = U60Repr { limbs: [0; 2 * N] }; - let mut borrow: u64 = 0; let mut borrow_in: u64 = 0; let mut borrow_flags: [bool; N] = [false; N]; for i in 0..2 * N { - borrow = ((x_u60.limbs[i] + borrow_in) > params.modulus_u60.limbs[i]) as u64; - let sub = (borrow << 60) + params.modulus_u60.limbs[i] - x_u60.limbs[i] - borrow_in; - result_u60.limbs[i] = sub; + let sub_term = x_u60.limbs[i] + borrow_in; + let borrow = (sub_term > params.modulus_u60.limbs[i]) as u64; + result_u60.limbs[i] = borrow * TWO_POW_60 + params.modulus_u60.limbs[i] - sub_term; + borrow_in = borrow; if ((i & 1) == 1) { borrow_flags[i / 2] = borrow as bool; @@ -115,21 +115,19 @@ pub(crate) unconstrained fn __add_with_flags( subtrahend_u60 = params.modulus_u60; } - let mut carry: u64 = 0; let mut carry_in: u64 = 0; - let mut borrow: u64 = 0; let mut borrow_in: u64 = 0; let mut borrow_flags: [bool; N] = [false; N]; let mut carry_flags: [bool; N] = [false; N]; for i in 0..2 * N { let mut add_term: u64 = a_u60.limbs[i] + b_u60.limbs[i] + carry_in; - carry = (add_term >= 0x1000000000000000) as u64; - add_term -= (carry as u64 * 0x1000000000000000); - result_u60.limbs[i] = add_term; - carry_in = carry as u64; - borrow = ((subtrahend_u60.limbs[i] + borrow_in) > result_u60.limbs[i]) as u64; - let sub = (borrow << 60) + result_u60.limbs[i] - subtrahend_u60.limbs[i] - borrow_in; - result_u60.limbs[i] = sub; + let mut carry = (add_term >= TWO_POW_60) as u64; + add_term -= carry * TWO_POW_60; + carry_in = carry; + + let sub_term = subtrahend_u60.limbs[i] + borrow_in; + let mut borrow = (sub_term > add_term) as u64; + result_u60.limbs[i] = borrow * TWO_POW_60 + add_term - sub_term; borrow_in = borrow; if ((i & 1) == 1) { @@ -157,28 +155,26 @@ pub(crate) unconstrained fn __sub_with_flags( let underflow = b_u60.gte(a_u60 + U60Repr::one()); - let mut addend_u60: U60Repr = U60Repr { limbs: [0; 2 * N] }; + let addend_u60: U60Repr = if underflow { + params.modulus_u60 + } else { + U60Repr { limbs: [0; 2 * N] } + }; let mut result_u60: U60Repr = U60Repr { limbs: [0; 2 * N] }; - if underflow { - addend_u60 = params.modulus_u60; - } - - let mut carry: u64 = 0; let mut carry_in: u64 = 0; - let mut borrow: u64 = 0; let mut borrow_in: u64 = 0; let mut borrow_flags: [bool; N] = [false; N]; let mut carry_flags: [bool; N] = [false; N]; for i in 0..2 * N { let mut add_term: u64 = a_u60.limbs[i] + addend_u60.limbs[i] + carry_in; - carry = (add_term >= 0x1000000000000000) as u64; - add_term -= (carry as u64 * 0x1000000000000000); - result_u60.limbs[i] = add_term; - carry_in = carry as u64; - borrow = ((b_u60.limbs[i] + borrow_in) > result_u60.limbs[i]) as u64; - let sub = (borrow << 60) + result_u60.limbs[i] - b_u60.limbs[i] - borrow_in; - result_u60.limbs[i] = sub; + let mut carry = (add_term >= TWO_POW_60) as u64; + add_term -= carry * TWO_POW_60; + carry_in = carry; + + let sub_term = b_u60.limbs[i] + borrow_in; + let mut borrow = (sub_term > add_term) as u64; + result_u60.limbs[i] = borrow * TWO_POW_60 + add_term - sub_term; borrow_in = borrow; if ((i & 1) == 1) {