-
Notifications
You must be signed in to change notification settings - Fork 128
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into feat(hint)/66-cairo_keccak_finalize_v2
- Loading branch information
Showing
8 changed files
with
489 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
%builtins range_check | ||
|
||
from starkware.cairo.common.cairo_secp.bigint import ( | ||
BigInt3, | ||
UnreducedBigInt3, | ||
UnreducedBigInt5, | ||
nondet_bigint3, | ||
bigint_mul, | ||
) | ||
from starkware.cairo.common.cairo_secp.constants import BASE | ||
|
||
func bigint_mul_u(x: UnreducedBigInt3, y: BigInt3) -> (res: UnreducedBigInt5) { | ||
return ( | ||
UnreducedBigInt5( | ||
d0=x.d0 * y.d0, | ||
d1=x.d0 * y.d1 + x.d1 * y.d0, | ||
d2=x.d0 * y.d2 + x.d1 * y.d1 + x.d2 * y.d0, | ||
d3=x.d1 * y.d2 + x.d2 * y.d1, | ||
d4=x.d2 * y.d2 | ||
), | ||
); | ||
} | ||
|
||
// Returns (x / y) % P | ||
func bigint_div_mod{range_check_ptr}(x: UnreducedBigInt5, y: UnreducedBigInt3, P: BigInt3) -> ( | ||
res: BigInt3 | ||
) { | ||
alloc_locals; | ||
local flag; | ||
%{ | ||
from starkware.cairo.common.cairo_secp.secp_utils import pack | ||
from starkware.cairo.common.math_utils import as_int | ||
from starkware.python.math_utils import div_mod, safe_div | ||
|
||
p = pack(ids.P, PRIME) | ||
x = pack(ids.x, PRIME) + as_int(ids.x.d3, PRIME) * ids.BASE ** 3 + as_int(ids.x.d4, PRIME) * ids.BASE ** 4 | ||
y = pack(ids.y, PRIME) | ||
|
||
value = res = div_mod(x, y, p) | ||
%} | ||
let (res) = nondet_bigint3(); | ||
|
||
%{ | ||
k = safe_div(res * y - x, p) | ||
value = k if k > 0 else 0 - k | ||
ids.flag = 1 if k > 0 else 0 | ||
%} | ||
let (k) = nondet_bigint3(); | ||
let (res_y) = bigint_mul_u(y, res); | ||
let (k_p) = bigint_mul(k, P); | ||
|
||
tempvar carry1 = (res_y.d0 - (2 * flag - 1) * k_p.d0 - x.d0) / BASE; | ||
assert [range_check_ptr + 0] = carry1 + 2 ** 127; | ||
|
||
tempvar carry2 = (res_y.d1 - (2 * flag - 1) * k_p.d1 - x.d1 + carry1) / BASE; | ||
assert [range_check_ptr + 1] = carry2 + 2 ** 127; | ||
|
||
tempvar carry3 = (res_y.d2 - (2 * flag - 1) * k_p.d2 - x.d2 + carry2) / BASE; | ||
assert [range_check_ptr + 2] = carry3 + 2 ** 127; | ||
|
||
tempvar carry4 = (res_y.d3 - (2 * flag - 1) * k_p.d3 - x.d3 + carry3) / BASE; | ||
assert [range_check_ptr + 3] = carry4 + 2 ** 127; | ||
|
||
assert res_y.d4 - (2 * flag - 1) * k_p.d4 - x.d4 + carry4 = 0; | ||
let range_check_ptr = range_check_ptr + 4; | ||
|
||
return (res=res); | ||
} | ||
|
||
// Check val = 0 mod n? | ||
func verify_urbigint5_zero{range_check_ptr}(val: UnreducedBigInt5, n: BigInt3) { | ||
let (res) = bigint_div_mod(val, UnreducedBigInt3(1, 0, 0), n); | ||
assert res.d0 = 0; | ||
assert res.d1 = 0; | ||
assert res.d2 = 0; | ||
return (); | ||
} | ||
|
||
func main{range_check_ptr: felt}() { | ||
let x = UnreducedBigInt5(0x38a23ca66202c8c2a72277, 0x6730e765376ff17ea8385, 0xca1ad489ab60ea581e6c1, 0, 0); | ||
let y = UnreducedBigInt3(0x20a4b46d3c5e24cda81f22, 0x967bf895824330d4273d0, 0x541e10c21560da25ada4c); | ||
let p = BigInt3(0x8a03bbfd25e8cd0364141, 0x3ffffffffffaeabb739abd, 0xfffffffffffffffffffff); | ||
|
||
let (actual : BigInt3) = bigint_div_mod(x, y, p); | ||
|
||
assert actual.d0 = 39016122801346771958523117; | ||
assert actual.d1 = 70716674902939638702535965; | ||
assert actual.d2 = 18303064213085914713888892; | ||
|
||
return (); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,225 @@ | ||
use crate::hint_processor::builtin_hint_processor::secp::bigint_utils::BigInt5; | ||
use crate::hint_processor::builtin_hint_processor::secp::secp_utils::BASE; | ||
use crate::math_utils::{div_mod, safe_div_bigint}; | ||
use crate::stdlib::collections::HashMap; | ||
use crate::stdlib::prelude::String; | ||
use crate::types::exec_scope::ExecutionScopes; | ||
use crate::{ | ||
hint_processor::{ | ||
builtin_hint_processor::secp::{bigint_utils::BigInt3, secp_utils::pack}, | ||
hint_processor_definition::HintReference, | ||
}, | ||
serde::deserialize_program::ApTracking, | ||
vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, | ||
}; | ||
use felt::Felt252; | ||
use num_bigint::BigInt; | ||
use num_bigint::ToBigInt; | ||
use num_traits::{One, Signed, Zero}; | ||
|
||
use super::hint_utils::insert_value_from_var_name; | ||
|
||
/// Implements hint: | ||
/// ```python | ||
/// from starkware.cairo.common.cairo_secp.secp_utils import pack | ||
/// from starkware.cairo.common.math_utils import as_int | ||
/// from starkware.python.math_utils import div_mod, safe_div | ||
/// | ||
/// p = pack(ids.P, PRIME) | ||
/// x = pack(ids.x, PRIME) + as_int(ids.x.d3, PRIME) * ids.BASE ** 3 + as_int(ids.x.d4, PRIME) * ids.BASE ** 4 | ||
/// y = pack(ids.y, PRIME) | ||
/// | ||
/// value = res = div_mod(x, y, p) | ||
/// ``` | ||
pub fn bigint_pack_div_mod_hint( | ||
vm: &mut VirtualMachine, | ||
exec_scopes: &mut ExecutionScopes, | ||
ids_data: &HashMap<String, HintReference>, | ||
ap_tracking: &ApTracking, | ||
) -> Result<(), HintError> { | ||
let p: BigInt = pack(BigInt3::from_var_name("P", vm, ids_data, ap_tracking)?); | ||
|
||
let x: BigInt = { | ||
let x_bigint5 = BigInt5::from_var_name("x", vm, ids_data, ap_tracking)?; | ||
let x_lower = BigInt3 { | ||
d0: x_bigint5.d0, | ||
d1: x_bigint5.d1, | ||
d2: x_bigint5.d2, | ||
}; | ||
let d3 = x_bigint5.d3.as_ref().to_biguint().to_bigint().unwrap(); | ||
let d4 = x_bigint5.d4.as_ref().to_biguint().to_bigint().unwrap(); | ||
pack(x_lower) + d3 * BigInt::from(BASE.pow(3)) + d4 * BigInt::from(BASE.pow(4)) | ||
}; | ||
let y: BigInt = pack(BigInt3::from_var_name("y", vm, ids_data, ap_tracking)?); | ||
|
||
let res = div_mod(&x, &y, &p); | ||
exec_scopes.insert_value("res", res.clone()); | ||
exec_scopes.insert_value("value", res); | ||
exec_scopes.insert_value("x", x); | ||
exec_scopes.insert_value("y", y); | ||
exec_scopes.insert_value("p", p); | ||
|
||
Ok(()) | ||
} | ||
|
||
/// Implements hint: | ||
/// ```python | ||
/// k = safe_div(res * y - x, p) | ||
/// value = k if k > 0 else 0 - k | ||
/// ids.flag = 1 if k > 0 else 0 | ||
/// ``` | ||
pub fn bigint_safe_div_hint( | ||
vm: &mut VirtualMachine, | ||
exec_scopes: &mut ExecutionScopes, | ||
ids_data: &HashMap<String, HintReference>, | ||
ap_tracking: &ApTracking, | ||
) -> Result<(), HintError> { | ||
let res = exec_scopes.get::<BigInt>("res")?; | ||
let y = exec_scopes.get::<BigInt>("y")?; | ||
let x = exec_scopes.get::<BigInt>("x")?; | ||
let p = exec_scopes.get::<BigInt>("p")?; | ||
|
||
let k = safe_div_bigint(&(res * y - x), &p)?; | ||
let (value, flag) = if k.is_positive() { | ||
(k.clone(), Felt252::one()) | ||
} else { | ||
(-k.clone(), Felt252::zero()) | ||
}; | ||
|
||
exec_scopes.insert_value("k", k); | ||
exec_scopes.insert_value("value", value); | ||
insert_value_from_var_name("flag", flag, vm, ids_data, ap_tracking)?; | ||
|
||
Ok(()) | ||
} | ||
|
||
#[cfg(test)] | ||
mod test { | ||
use crate::any_box; | ||
use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor; | ||
use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; | ||
use crate::hint_processor::builtin_hint_processor::hint_code; | ||
use crate::hint_processor::hint_processor_definition::HintProcessor; | ||
use crate::hint_processor::hint_processor_definition::HintReference; | ||
use crate::stdlib::collections::HashMap; | ||
use crate::types::exec_scope::ExecutionScopes; | ||
use crate::types::relocatable::MaybeRelocatable; | ||
use crate::utils::test_utils::*; | ||
use crate::vm::errors::memory_errors::MemoryError; | ||
use crate::vm::vm_core::VirtualMachine; | ||
use crate::vm::vm_memory::{memory::Memory, memory_segments::MemorySegmentManager}; | ||
use assert_matches::assert_matches; | ||
use num_bigint::BigInt; | ||
|
||
#[cfg(target_arch = "wasm32")] | ||
use wasm_bindgen_test::*; | ||
|
||
/// Input: | ||
/// x = UnreducedBigInt5(0x38a23ca66202c8c2a72277, 0x6730e765376ff17ea8385, 0xca1ad489ab60ea581e6c1, 0, 0); | ||
/// y = UnreducedBigInt3(0x20a4b46d3c5e24cda81f22, 0x967bf895824330d4273d0, 0x541e10c21560da25ada4c); | ||
/// p = BigInt3(0x8a03bbfd25e8cd0364141, 0x3ffffffffffaeabb739abd, 0xfffffffffffffffffffff); | ||
/// expected: value = res = 109567829260688255124154626727441144629993228404337546799996747905569082729709 (py int) | ||
#[test] | ||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] | ||
fn test_bigint_pack_div_mod_hint() { | ||
// Prepare the VM context: | ||
let ids_data = non_continuous_ids_data![ | ||
("x", 0), // located at `fp + 0`. | ||
("y", 5), // located at `fp + 5`. | ||
("P", 8) // located at `fp + 8`. | ||
]; | ||
|
||
let mut vm = vm!(); | ||
vm.run_context.fp = 0; | ||
add_segments!(vm, 11); // Alloc space for `ids.x`, `ids.y` and `ids.p`. | ||
vm.segments = segments![ | ||
((1, 0), 0x38a23ca66202c8c2a72277_i128), // x.d0 | ||
((1, 1), 0x6730e765376ff17ea8385_i128), // x.d1 | ||
((1, 2), 0xca1ad489ab60ea581e6c1_i128), // x.d2 | ||
((1, 3), 0_i128), // x.d3 | ||
((1, 4), 0_i128), // x.d4 | ||
((1, 5), 0x20a4b46d3c5e24cda81f22_i128), // y.d0 | ||
((1, 6), 0x967bf895824330d4273d0_i128), // y.d1 | ||
((1, 7), 0x541e10c21560da25ada4c_i128), // y.d2 | ||
((1, 8), 0x8a03bbfd25e8cd0364141_i128), // P.id0 | ||
((1, 9), 0x3ffffffffffaeabb739abd_i128), // P.id1 | ||
((1, 10), 0xfffffffffffffffffffff_i128), // P.id2 | ||
]; | ||
|
||
let mut exec_scopes = ExecutionScopes::new(); | ||
assert_matches!( | ||
run_hint!( | ||
vm, | ||
ids_data, | ||
hint_code::BIGINT_PACK_DIV_MOD, | ||
&mut exec_scopes | ||
), | ||
Ok(()) | ||
); | ||
|
||
let expected = bigint_str!( | ||
"109567829260688255124154626727441144629993228404337546799996747905569082729709" | ||
); | ||
assert_matches!(exec_scopes.get::<BigInt>("res"), Ok(x) if x == expected); | ||
assert_matches!(exec_scopes.get::<BigInt>("value"), Ok(x) if x == expected); | ||
assert_matches!(exec_scopes.get::<BigInt>("y"), Ok(x) if x == bigint_str!("38047400353360331012910998489219098987968251547384484838080352663220422975266")); | ||
assert_matches!(exec_scopes.get::<BigInt>("x"), Ok(x) if x == bigint_str!("91414600319290532004473480113251693728834511388719905794310982800988866814583")); | ||
assert_matches!(exec_scopes.get::<BigInt>("p"), Ok(x) if x == bigint_str!("115792089237316195423570985008687907852837564279074904382605163141518161494337")); | ||
} | ||
|
||
/// Input: | ||
/// res = 109567829260688255124154626727441144629993228404337546799996747905569082729709 | ||
/// y = 38047400353360331012910998489219098987968251547384484838080352663220422975266 | ||
/// x = 91414600319290532004473480113251693728834511388719905794310982800988866814583 | ||
/// p = 115792089237316195423570985008687907852837564279074904382605163141518161494337 | ||
/// Output: | ||
/// k = 36002209591245282109880156842267569109802494162594623391338581162816748840003 | ||
/// value = 36002209591245282109880156842267569109802494162594623391338581162816748840003 | ||
/// ids.flag = 1 | ||
#[test] | ||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] | ||
fn test_bigint_safe_div_hint() { | ||
let mut exec_scopes = ExecutionScopes::new(); | ||
exec_scopes.insert_value( | ||
"res", | ||
bigint_str!( | ||
"109567829260688255124154626727441144629993228404337546799996747905569082729709" | ||
), | ||
); | ||
exec_scopes.insert_value( | ||
"x", | ||
bigint_str!( | ||
"91414600319290532004473480113251693728834511388719905794310982800988866814583" | ||
), | ||
); | ||
exec_scopes.insert_value( | ||
"y", | ||
bigint_str!( | ||
"38047400353360331012910998489219098987968251547384484838080352663220422975266" | ||
), | ||
); | ||
exec_scopes.insert_value( | ||
"p", | ||
bigint_str!( | ||
"115792089237316195423570985008687907852837564279074904382605163141518161494337" | ||
), | ||
); | ||
|
||
let mut vm = vm!(); | ||
let ids_data = non_continuous_ids_data![("flag", 0)]; | ||
vm.run_context.fp = 0; | ||
add_segments!(vm, 2); // Alloc space for `flag` | ||
|
||
assert_matches!( | ||
run_hint!(vm, ids_data, hint_code::BIGINT_SAFE_DIV, &mut exec_scopes), | ||
Ok(()) | ||
); | ||
assert_matches!(exec_scopes.get::<BigInt>("k"), Ok(x) if x == bigint_str!("36002209591245282109880156842267569109802494162594623391338581162816748840003")); | ||
assert_matches!(exec_scopes.get::<BigInt>("value"), Ok(x) if x == bigint_str!("36002209591245282109880156842267569109802494162594623391338581162816748840003")); | ||
|
||
check_memory![vm.segments.memory, ((1, 0), 1)]; | ||
// let flag_result = get_integer_from_var_name("flag", vm, ids_data, ap_tracking); | ||
// assert!(flag_result.is_ok()); | ||
// assert_eq!(flag_result.unwrap().as_ref(), Felt252::one()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
pub mod bigint; | ||
pub mod blake2s_hash; | ||
pub mod blake2s_utils; | ||
pub mod builtin_hint_processor_definition; | ||
|
Oops, something went wrong.