- 
                Notifications
    You must be signed in to change notification settings 
- Fork 200
chore(vm): unify Uint256 usage across u256 hints and split quotient via Uint512 #2237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| use super::secp::bigint_utils::Uint512; | ||
| use crate::Felt252; | ||
| use crate::{ | ||
| hint_processor::builtin_hint_processor::hint_utils::{ | ||
|  | @@ -43,6 +44,23 @@ impl<'a> Uint256<'a> { | |
| }) | ||
| } | ||
|  | ||
| pub(crate) fn from_base_addr_with_offsets( | ||
| addr: Relocatable, | ||
| name: &str, | ||
| vm: &'a VirtualMachine, | ||
| offset_low: usize, | ||
| offset_high: usize, | ||
| ) -> Result<Self, HintError> { | ||
| Ok(Self { | ||
| low: vm.get_integer((addr + offset_low)?).map_err(|_| { | ||
| HintError::IdentifierHasNoMember(Box::new((name.to_string(), "low".to_string()))) | ||
| })?, | ||
| high: vm.get_integer((addr + offset_high)?).map_err(|_| { | ||
| HintError::IdentifierHasNoMember(Box::new((name.to_string(), "high".to_string()))) | ||
| })?, | ||
| }) | ||
| } | ||
|  | ||
| pub(crate) fn from_var_name( | ||
| name: &str, | ||
| vm: &'a VirtualMachine, | ||
|  | @@ -311,12 +329,12 @@ pub fn uint256_signed_nn( | |
| ids_data: &HashMap<String, HintReference>, | ||
| ap_tracking: &ApTracking, | ||
| ) -> Result<(), HintError> { | ||
| let a_addr = get_relocatable_from_var_name("a", vm, ids_data, ap_tracking)?; | ||
| let a_high = vm.get_integer((a_addr + 1_usize)?)?; | ||
| let a = Uint256::from_var_name("a", vm, ids_data, ap_tracking)?; | ||
| let a_high = a.high; | ||
| //Main logic | ||
| //memory[ap] = 1 if 0 <= (ids.a.high % PRIME) < 2 ** 127 else 0 | ||
| let result: Felt252 = | ||
| if *a_high >= Felt252::ZERO && a_high.as_ref() <= &Felt252::from(i128::MAX) { | ||
| if *a_high.as_ref() >= Felt252::ZERO && a_high.as_ref() <= &Felt252::from(i128::MAX) { | ||
| Felt252::ONE | ||
| } else { | ||
| Felt252::ZERO | ||
|  | @@ -377,11 +395,15 @@ pub fn uint256_offseted_unsigned_div_rem( | |
| let a_low = a.low.as_ref(); | ||
| let a_high = a.high.as_ref(); | ||
|  | ||
| let div_addr = get_relocatable_from_var_name("div", vm, ids_data, ap_tracking)?; | ||
| let div_low = vm.get_integer((div_addr + div_offset_low)?)?; | ||
| let div_high = vm.get_integer((div_addr + div_offset_high)?)?; | ||
| let div_low = div_low.as_ref(); | ||
| let div_high = div_high.as_ref(); | ||
| let div = if div_offset_low == 0 && div_offset_high == 1 { | ||
| // Standard Uint256 layout | ||
| Uint256::from_var_name("div", vm, ids_data, ap_tracking)? | ||
| } else { | ||
| let div_addr = get_relocatable_from_var_name("div", vm, ids_data, ap_tracking)?; | ||
| Uint256::from_base_addr_with_offsets(div_addr, "div", vm, div_offset_low, div_offset_high)? | ||
| }; | ||
| let div_low = div.low.as_ref(); | ||
| let div_high = div.high.as_ref(); | ||
| 
      Comment on lines
    
      +398
     to 
      +406
    
   There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here could we call  Also, in this function we are packing the U256 into a bigint manually. Could you modify it to call  | ||
|  | ||
| //Main logic | ||
| //a = (ids.a.high << 128) + ids.a.low | ||
|  | @@ -428,68 +450,25 @@ pub fn uint256_mul_div_mod( | |
| ids_data: &HashMap<String, HintReference>, | ||
| ap_tracking: &ApTracking, | ||
| ) -> Result<(), HintError> { | ||
| // Extract variables | ||
| let a_addr = get_relocatable_from_var_name("a", vm, ids_data, ap_tracking)?; | ||
| let b_addr = get_relocatable_from_var_name("b", vm, ids_data, ap_tracking)?; | ||
| let div_addr = get_relocatable_from_var_name("div", vm, ids_data, ap_tracking)?; | ||
| let quotient_low_addr = | ||
| get_relocatable_from_var_name("quotient_low", vm, ids_data, ap_tracking)?; | ||
| let quotient_high_addr = | ||
| get_relocatable_from_var_name("quotient_high", vm, ids_data, ap_tracking)?; | ||
| let remainder_addr = get_relocatable_from_var_name("remainder", vm, ids_data, ap_tracking)?; | ||
|  | ||
| let a_low = vm.get_integer(a_addr)?; | ||
| let a_high = vm.get_integer((a_addr + 1_usize)?)?; | ||
| let b_low = vm.get_integer(b_addr)?; | ||
| let b_high = vm.get_integer((b_addr + 1_usize)?)?; | ||
| let div_low = vm.get_integer(div_addr)?; | ||
| let div_high = vm.get_integer((div_addr + 1_usize)?)?; | ||
| let a_low = a_low.as_ref(); | ||
| let a_high = a_high.as_ref(); | ||
| let b_low = b_low.as_ref(); | ||
| let b_high = b_high.as_ref(); | ||
| let div_low = div_low.as_ref(); | ||
| let div_high = div_high.as_ref(); | ||
|  | ||
| // Main Logic | ||
| let a = a_high.to_biguint().shl(128_usize) + a_low.to_biguint(); | ||
| let b = b_high.to_biguint().shl(128_usize) + b_low.to_biguint(); | ||
| let div = div_high.to_biguint().shl(128_usize) + div_low.to_biguint(); | ||
| // Read inputs via Uint256 helper | ||
| let a = Uint256::from_var_name("a", vm, ids_data, ap_tracking)?.pack(); | ||
| let b = Uint256::from_var_name("b", vm, ids_data, ap_tracking)?.pack(); | ||
| let div = Uint256::from_var_name("div", vm, ids_data, ap_tracking)?.pack(); | ||
| if div.is_zero() { | ||
| return Err(MathError::DividedByZero.into()); | ||
| } | ||
| let (quotient, remainder) = (a * b).div_mod_floor(&div); | ||
|  | ||
| // ids.quotient_low.low | ||
| vm.insert_value( | ||
| quotient_low_addr, | ||
| Felt252::from(&("ient & &BigUint::from(u128::MAX))), | ||
| )?; | ||
| // ids.quotient_low.high | ||
| vm.insert_value( | ||
| (quotient_low_addr + 1)?, | ||
| Felt252::from(&(("ient).shr(128_u32) & &BigUint::from(u128::MAX))), | ||
| )?; | ||
| // ids.quotient_high.low | ||
| vm.insert_value( | ||
| quotient_high_addr, | ||
| Felt252::from(&(("ient).shr(256_u32) & &BigUint::from(u128::MAX))), | ||
| )?; | ||
| // ids.quotient_high.high | ||
| vm.insert_value( | ||
| (quotient_high_addr + 1)?, | ||
| Felt252::from(&(("ient).shr(384_u32))), | ||
| )?; | ||
| //ids.remainder.low | ||
| vm.insert_value( | ||
| remainder_addr, | ||
| Felt252::from(&(&remainder & &BigUint::from(u128::MAX))), | ||
| )?; | ||
| //ids.remainder.high | ||
| vm.insert_value( | ||
| (remainder_addr + 1)?, | ||
| Felt252::from(&remainder.shr(128_u32)), | ||
| )?; | ||
| // Write quotient using Uint512 split into two Uint256 values | ||
| let q512 = Uint512::split("ient); | ||
| let q_low = Uint256::from_values(*q512.limbs[0].as_ref(), *q512.limbs[1].as_ref()); | ||
| let q_high = Uint256::from_values(*q512.limbs[2].as_ref(), *q512.limbs[3].as_ref()); | ||
| q_low.insert_from_var_name("quotient_low", vm, ids_data, ap_tracking)?; | ||
| q_high.insert_from_var_name("quotient_high", vm, ids_data, ap_tracking)?; | ||
|  | ||
| // Write remainder as Uint256 | ||
| let r_u256 = Uint256::from(&remainder); | ||
| r_u256.insert_from_var_name("remainder", vm, ids_data, ap_tracking)?; | ||
|  | ||
| Ok(()) | ||
| } | ||
|  | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would imply fetching
a.low, but not using it, right?