Skip to content

Commit 10b3dd9

Browse files
Fix WRITE_DIVMOD_SEGMENT hint (#2078)
* Minor fixes - use CAIRO_PRIME * Add error handling * Update CHANGELOG.md
1 parent f2b63ff commit 10b3dd9

File tree

3 files changed

+34
-32
lines changed

3 files changed

+34
-32
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#### Upcoming Changes
44

5+
* fix: Use Cairo prime instead of SECP_P in WRITE_DIVMOD_SEGMENT hint [#2078](https://github.com/lambdaclass/cairo-vm/pull/2078)
56

67
* feat: add support for alias identifiers destination in program serde [#2071](https://github.com/lambdaclass/cairo-vm/pull/2071)
78

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,23 @@
11
use core::str::FromStr;
22

3-
use super::{
4-
hint_utils::get_relocatable_from_var_name,
5-
secp::{bigint_utils::BigInt3, secp_utils::SECP_P},
6-
};
3+
use super::{hint_utils::get_relocatable_from_var_name, secp::bigint_utils::BigInt3};
74
use crate::{
85
hint_processor::hint_processor_definition::HintReference,
96
serde::deserialize_program::ApTracking,
107
types::relocatable::MaybeRelocatable,
8+
utils::CAIRO_PRIME,
119
vm::{errors::hint_errors::HintError, vm_core::VirtualMachine},
1210
Felt252,
1311
};
1412
use crate::{
15-
stdlib::{collections::HashMap, ops::Deref, prelude::*},
13+
stdlib::{collections::HashMap, prelude::*},
1614
types::exec_scope::ExecutionScopes,
1715
};
1816
use lazy_static::lazy_static;
19-
use num_bigint::BigInt;
17+
use num_bigint::{BigInt, BigUint};
2018
use num_integer::Integer;
2119
use num_traits::FromPrimitive;
22-
use num_traits::Zero;
20+
use num_traits::Signed;
2321

2422
lazy_static! {
2523
static ref BLS_BASE: BigInt = BigInt::from_u64(2).unwrap().pow(86);
@@ -50,21 +48,21 @@ pub fn write_div_mod_segment(
5048
) -> Result<(), HintError> {
5149
let a = bls_pack(
5250
&BigInt3::from_var_name("a", vm, ids_data, ap_tracking)?,
53-
&SECP_P,
51+
&CAIRO_PRIME,
5452
);
5553
let b = bls_pack(
5654
&BigInt3::from_var_name("b", vm, ids_data, ap_tracking)?,
57-
&SECP_P,
55+
&CAIRO_PRIME,
5856
);
5957
let (q, r) = (a * b).div_mod_floor(&BLS_PRIME);
6058
let q_reloc = get_relocatable_from_var_name("q", vm, ids_data, ap_tracking)?;
6159
let res_reloc = get_relocatable_from_var_name("res", vm, ids_data, ap_tracking)?;
6260

63-
let q_arg: Vec<MaybeRelocatable> = bls_split(q)
61+
let q_arg: Vec<MaybeRelocatable> = bls_split(q)?
6462
.into_iter()
6563
.map(|ref n| Felt252::from(n).into())
6664
.collect::<Vec<MaybeRelocatable>>();
67-
let res_arg: Vec<MaybeRelocatable> = bls_split(r)
65+
let res_arg: Vec<MaybeRelocatable> = bls_split(r)?
6866
.into_iter()
6967
.map(|ref n| Felt252::from(n).into())
7068
.collect::<Vec<MaybeRelocatable>>();
@@ -74,35 +72,36 @@ pub fn write_div_mod_segment(
7472
Ok(())
7573
}
7674

77-
fn bls_split(mut num: BigInt) -> Vec<BigInt> {
78-
use num_traits::Signed;
79-
let mut a = Vec::new();
75+
fn bls_split(mut num: BigInt) -> Result<Vec<BigInt>, HintError> {
76+
let mut canonical = Vec::new();
8077
for _ in 0..2 {
81-
let residue = &num % BLS_BASE.deref();
82-
num /= BLS_BASE.deref();
83-
a.push(residue);
78+
let (new_num, residue) = num.div_rem(&BLS_BASE);
79+
num = new_num;
80+
canonical.push(residue);
81+
}
82+
83+
if num.abs() >= BigInt::from(1u128 << 127) {
84+
return Err(HintError::BlsSplitError(Box::new(num)));
8485
}
85-
assert!(num.abs() < BigInt::from_u128(1 << 127).unwrap());
86-
a.push(num);
87-
a
86+
87+
canonical.push(num);
88+
Ok(canonical)
8889
}
8990

90-
fn as_int(value: BigInt, prime: &BigInt) -> BigInt {
91-
let half_prime = prime / 2u32;
92-
if value > half_prime {
93-
value - prime
94-
} else {
91+
fn as_int(value: BigInt, prime: &BigUint) -> BigInt {
92+
let half_prime: BigInt = (prime / 2u32).into();
93+
let prime: BigInt = prime.clone().into();
94+
if value < half_prime {
9595
value
96+
} else {
97+
value - prime
9698
}
9799
}
98100

99-
fn bls_pack(z: &BigInt3, prime: &BigInt) -> BigInt {
100-
let limbs = &z.limbs;
101-
limbs
101+
fn bls_pack(z: &BigInt3, prime: &BigUint) -> BigInt {
102+
z.limbs
102103
.iter()
103104
.enumerate()
104-
.fold(BigInt::zero(), |acc, (i, limb)| {
105-
let limb_as_int = as_int(limb.to_bigint(), prime);
106-
acc + limb_as_int * &BLS_BASE.pow(i as u32)
107-
})
105+
.map(|(i, limb)| as_int(limb.to_bigint(), prime) * &BLS_BASE.pow(i as u32))
106+
.sum()
108107
}

vm/src/vm/errors/hint_errors.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,8 @@ pub enum HintError {
196196
EmptyNibbles,
197197
#[error("circuit evalution: {0}")]
198198
CircuitEvaluationFailed(Box<str>),
199+
#[error("high limb magnitude should be smaller than 2 ** 127: {0}")]
200+
BlsSplitError(Box<BigInt>),
199201
}
200202

201203
#[cfg(test)]

0 commit comments

Comments
 (0)