diff --git a/zokrates_core/src/static_analysis/uint_optimizer.rs b/zokrates_core/src/static_analysis/uint_optimizer.rs index 232c44249..18b9aecf1 100644 --- a/zokrates_core/src/static_analysis/uint_optimizer.rs +++ b/zokrates_core/src/static_analysis/uint_optimizer.rs @@ -2,6 +2,7 @@ use crate::embed::FlatEmbed; use crate::zir::folder::*; use crate::zir::*; use std::collections::HashMap; +use std::ops::{BitAnd, Shl, Shr}; use zokrates_field::Field; #[derive(Default)] @@ -366,16 +367,12 @@ impl<'ast, T: Field> Folder<'ast, T> for UintOptimizer<'ast, T> { // reduce both terms let e = self.fold_uint_expression(e); - let e_max: u128 = e - .metadata - .clone() - .unwrap() - .max - .to_dec_string() - .parse() - .unwrap(); + let e_max: num_bigint::BigUint = e.metadata.as_ref().unwrap().max.to_biguint(); + let max = e_max + .shl(by as usize) + .bitand(&(2_u128.pow(range as u32) - 1).into()); - let max = T::from((e_max << by) & (2_u128.pow(range as u32) - 1)); + let max = T::try_from(max).unwrap(); UExpression::left_shift(force_reduce(e), by).with_max(max) } @@ -383,18 +380,12 @@ impl<'ast, T: Field> Folder<'ast, T> for UintOptimizer<'ast, T> { // reduce both terms let e = self.fold_uint_expression(e); - let e_max: u128 = e - .metadata - .clone() - .unwrap() - .max - .to_dec_string() - .parse() - .unwrap(); + let e_max: num_bigint::BigUint = e.metadata.as_ref().unwrap().max.to_biguint(); + let max = e_max + .bitand(&(2_u128.pow(range as u32) - 1).into()) + .shr(by as usize); - let max = (e_max & (2_u128.pow(range as u32) - 1)) >> by; - - let max = T::from(max); + let max = T::try_from(max).unwrap(); UExpression::right_shift(force_reduce(e), by).with_max(max) } @@ -727,7 +718,7 @@ mod tests { #[test] fn right_shift() { - fn right_shift_test(e_max: u128, by: u32, output_max: u32) { + fn right_shift_test>(e_max: U, by: u32, output_max: u32) { let left = e_with_max(e_max); let right = by; @@ -745,12 +736,12 @@ mod tests { right_shift_test(0xff_u128, 2, 0xff >> 2); right_shift_test(2, 2, 2 >> 2); - right_shift_test(0xffffffffffff_u128, 2, 0xffffffff >> 2); + right_shift_test(Bn128Field::max_unique_value(), 2, 0xffffffff >> 2); } #[test] fn left_shift() { - fn left_shift_test(e_max: u128, by: u32, output_max: u32) { + fn left_shift_test>(e_max: U, by: u32, output_max: u32) { let left = e_with_max(e_max); let right = by; @@ -768,7 +759,7 @@ mod tests { left_shift_test(0xff_u128, 2, 0xff << 2); left_shift_test(2, 2, 2 << 2); - left_shift_test(0xffffffffffff_u128, 2, 0xffffffff << 2); + left_shift_test(Bn128Field::max_unique_value(), 2, 0xffffffff << 2); } #[test]