Skip to content
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

feat(hints): add NewHint#22 #1003

Merged
merged 8 commits into from
Apr 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,16 @@
* Added dynamic layout [#879](https://github.com/lambdaclass/cairo-rs/pull/879)
* `get_segment_size` was exposed [#934](https://github.com/lambdaclass/cairo-rs/pull/934)

* Add missing hint on cairo_secp lib [#1003](https://github.com/lambdaclass/cairo-rs/pull/1003):

`BuiltinHintProcessor` now supports the following hint:

```python
from starkware.cairo.common.cairo_secp.secp_utils import pack

x = pack(ids.x, PRIME) % SECP_P
```

* Add missing hint on cairo_secp lib [#996](https://github.com/lambdaclass/cairo-rs/pull/996):

`BuiltinHintProcessor` now supports the following hint:
Expand Down
49 changes: 49 additions & 0 deletions cairo_programs/is_zero_pack.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
%builtins range_check

from starkware.cairo.common.cairo_secp.bigint import BigInt3, UnreducedBigInt3, nondet_bigint3
from starkware.cairo.common.cairo_secp.field import unreduced_mul, verify_zero

func is_zero_pack{range_check_ptr}(x: BigInt3) -> (res: felt) {
// just to import SECP_P
%{
from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack

value = pack(ids.x, PRIME) % SECP_P
%}
%{
from starkware.cairo.common.cairo_secp.secp_utils import pack

x = pack(ids.x, PRIME) % SECP_P
%}
if (nondet %{ x == 0 %} != 0) {
return (res=1);
}
return (res=0);
}

func test_is_zero_pack{range_check_ptr}() -> () {
let zero = BigInt3(0, 0, 0);

let (res: felt) = is_zero_pack(zero);
assert res = 1;

let one = BigInt3(1, 0, 0);

let (res: felt) = is_zero_pack(one);
assert res = 0;

let secp256k1_prime = BigInt3(
77371252455336262886226991, 77371252455336267181195263, 19342813113834066795298815
);

let (res: felt) = is_zero_pack(secp256k1_prime);
assert res = 1;

return ();
}

func main{range_check_ptr}() -> () {
test_is_zero_pack();

return ();
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use crate::{
},
field_utils::{
is_zero_assign_scope_variables, is_zero_assign_scope_variables_external_const,
is_zero_nondet, is_zero_pack, reduce, verify_zero,
is_zero_nondet, is_zero_pack, is_zero_pack_external_secp, reduce, verify_zero,
verify_zero_with_external_const,
},
signature::{
Expand Down Expand Up @@ -351,6 +351,12 @@ impl HintProcessor for BuiltinHintProcessor {
hint_code::IS_ZERO_PACK => {
is_zero_pack(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking)
}
hint_code::IS_ZERO_PACK_EXTERNAL_SECP => is_zero_pack_external_secp(
vm,
exec_scopes,
&hint_data.ids_data,
&hint_data.ap_tracking,
),
hint_code::IS_ZERO_NONDET => is_zero_nondet(vm, exec_scopes),
hint_code::IS_ZERO_ASSIGN_SCOPE_VARS => is_zero_assign_scope_variables(exec_scopes),
hint_code::IS_ZERO_ASSIGN_SCOPE_VARS_EXTERNAL_SECP => {
Expand Down
4 changes: 4 additions & 0 deletions src/hint_processor/builtin_hint_processor/hint_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,10 @@ pub const IS_ZERO_PACK: &str = r#"from starkware.cairo.common.cairo_secp.secp_ut

x = pack(ids.x, PRIME) % SECP_P"#;

pub const IS_ZERO_PACK_EXTERNAL_SECP: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import pack

x = pack(ids.x, PRIME) % SECP_P"#;

pub const IS_ZERO_ASSIGN_SCOPE_VARS: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P
from starkware.python.math_utils import div_mod

Expand Down
11 changes: 5 additions & 6 deletions src/hint_processor/builtin_hint_processor/secp/ec_utils.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::{
any_box,
hint_processor::{
builtin_hint_processor::{
hint_utils::{
Expand Down Expand Up @@ -59,7 +58,7 @@ pub fn ec_negate(
ids_data: &HashMap<String, HintReference>,
ap_tracking: &ApTracking,
) -> Result<(), HintError> {
exec_scopes.assign_or_update_variable("SECP_P", any_box!(SECP_P.clone()));
exec_scopes.insert_value("SECP_P", SECP_P.clone());
//ids.point
let point_y = (get_relocatable_from_var_name("point", vm, ids_data, ap_tracking)? + 3i32)?;
let y_bigint3 = BigInt3::from_base_addr(point_y, "point.y", vm)?;
Expand Down Expand Up @@ -88,7 +87,7 @@ pub fn compute_doubling_slope(
ap_tracking: &ApTracking,
point_alias: &str,
) -> Result<(), HintError> {
exec_scopes.assign_or_update_variable("SECP_P", any_box!(SECP_P.clone()));
exec_scopes.insert_value("SECP_P", SECP_P.clone());
//ids.point
let point = EcPoint::from_var_name(point_alias, vm, ids_data, ap_tracking)?;

Expand Down Expand Up @@ -120,7 +119,7 @@ pub fn compute_slope(
point0_alias: &str,
point1_alias: &str,
) -> Result<(), HintError> {
exec_scopes.assign_or_update_variable("SECP_P", any_box!(SECP_P.clone()));
exec_scopes.insert_value("SECP_P", SECP_P.clone());
//ids.point0
let point0 = EcPoint::from_var_name(point0_alias, vm, ids_data, ap_tracking)?;
//ids.point1
Expand Down Expand Up @@ -154,7 +153,7 @@ pub fn ec_double_assign_new_x(
ids_data: &HashMap<String, HintReference>,
ap_tracking: &ApTracking,
) -> Result<(), HintError> {
exec_scopes.assign_or_update_variable("SECP_P", any_box!(SECP_P.clone()));
exec_scopes.insert_value("SECP_P", SECP_P.clone());
//ids.slope
let slope = BigInt3::from_var_name("slope", vm, ids_data, ap_tracking)?;
//ids.point
Expand Down Expand Up @@ -213,7 +212,7 @@ pub fn fast_ec_add_assign_new_x(
ids_data: &HashMap<String, HintReference>,
ap_tracking: &ApTracking,
) -> Result<(), HintError> {
exec_scopes.assign_or_update_variable("SECP_P", any_box!(SECP_P.clone()));
exec_scopes.insert_value("SECP_P", SECP_P.clone());
//ids.slope
let slope = BigInt3::from_var_name("slope", vm, ids_data, ap_tracking)?;
//ids.point0
Expand Down
89 changes: 54 additions & 35 deletions src/hint_processor/builtin_hint_processor/secp/field_utils.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
use crate::any_box;
use crate::stdlib::{collections::HashMap, prelude::*};

use crate::{
hint_processor::{
builtin_hint_processor::hint_utils::{insert_value_from_var_name, insert_value_into_ap},
builtin_hint_processor::{
hint_utils::{insert_value_from_var_name, insert_value_into_ap},
secp::{
bigint_utils::BigInt3,
secp_utils::{pack, SECP_P},
},
},
hint_processor_definition::HintReference,
},
math_utils::div_mod,
serde::deserialize_program::ApTracking,
stdlib::{collections::HashMap, prelude::*},
types::exec_scope::ExecutionScopes,
vm::{errors::hint_errors::HintError, vm_core::VirtualMachine},
};
Expand All @@ -16,9 +20,6 @@ use num_bigint::BigInt;
use num_integer::Integer;
use num_traits::{One, Zero};

use super::secp_utils::SECP_P;
use super::{bigint_utils::BigInt3, secp_utils::pack};

/*
Implements hint:
%{
Expand All @@ -35,7 +36,7 @@ pub fn verify_zero(
ids_data: &HashMap<String, HintReference>,
ap_tracking: &ApTracking,
) -> Result<(), HintError> {
exec_scopes.assign_or_update_variable("SECP_P", any_box!(SECP_P.clone()));
exec_scopes.insert_value("SECP_P", SECP_P.clone());
let val = pack(BigInt3::from_var_name("val", vm, ids_data, ap_tracking)?);
let (q, r) = val.div_rem(&SECP_P);
if !r.is_zero() {
Expand Down Expand Up @@ -85,7 +86,7 @@ pub fn reduce(
ids_data: &HashMap<String, HintReference>,
ap_tracking: &ApTracking,
) -> Result<(), HintError> {
exec_scopes.assign_or_update_variable("SECP_P", any_box!(SECP_P.clone()));
exec_scopes.insert_value("SECP_P", SECP_P.clone());
let value = pack(BigInt3::from_var_name("x", vm, ids_data, ap_tracking)?);
exec_scopes.insert_value("value", value.mod_floor(&SECP_P));
Ok(())
Expand All @@ -105,13 +106,26 @@ pub fn is_zero_pack(
ids_data: &HashMap<String, HintReference>,
ap_tracking: &ApTracking,
) -> Result<(), HintError> {
exec_scopes.assign_or_update_variable("SECP_P", any_box!(SECP_P.clone()));
exec_scopes.insert_value("SECP_P", SECP_P.clone());
let x_packed = pack(BigInt3::from_var_name("x", vm, ids_data, ap_tracking)?);
let x = x_packed.mod_floor(&SECP_P);
exec_scopes.insert_value("x", x);
Ok(())
}

pub fn is_zero_pack_external_secp(
vm: &mut VirtualMachine,
exec_scopes: &mut ExecutionScopes,
ids_data: &HashMap<String, HintReference>,
ap_tracking: &ApTracking,
) -> Result<(), HintError> {
let secp_p = exec_scopes.get_ref("SECP_P")?;
let x_packed = pack(BigInt3::from_var_name("x", vm, ids_data, ap_tracking)?);
let x = x_packed.mod_floor(secp_p);
exec_scopes.insert_value("x", x);
Ok(())
}

/*
Implements hint:
in .cairo program
Expand Down Expand Up @@ -145,7 +159,7 @@ Implements hint:
%}
*/
pub fn is_zero_assign_scope_variables(exec_scopes: &mut ExecutionScopes) -> Result<(), HintError> {
exec_scopes.assign_or_update_variable("SECP_P", any_box!(SECP_P.clone()));
exec_scopes.insert_value("SECP_P", SECP_P.clone());
//Get `x` variable from vm scope
let x = exec_scopes.get::<BigInt>("x")?;

Expand Down Expand Up @@ -370,36 +384,41 @@ mod tests {
#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn run_is_zero_pack_ok() {
let hint_code = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\n\nx = pack(ids.x, PRIME) % SECP_P";
let mut vm = vm_with_range_check!();

//Initialize fp
vm.run_context.fp = 15;

//Create hint data
let ids_data = HashMap::from([("x".to_string(), HintReference::new_simple(-5))]);
//Insert ids.x.d0, ids.x.d1, ids.x.d2 into memory
vm.segments = segments![
((1, 10), 232113757366008801543585_i128),
((1, 11), 232113757366008801543585_i128),
((1, 12), 232113757366008801543585_i128)
let mut exec_scopes = ExecutionScopes::new();
let hint_codes = vec![
hint_code::IS_ZERO_PACK,
// NOTE: this one requires IS_ZERO_ASSIGN_SCOPE_VARS to execute first.
hint_code::IS_ZERO_PACK_EXTERNAL_SECP,
];
for hint_code in hint_codes {
let mut vm = vm_with_range_check!();

let mut exec_scopes = ExecutionScopes::new();
//Initialize fp
vm.run_context.fp = 15;

//Execute the hint
assert_matches!(run_hint!(vm, ids_data, hint_code, &mut exec_scopes), Ok(()));
//Create hint data
let ids_data = HashMap::from([("x".to_string(), HintReference::new_simple(-5))]);
//Insert ids.x.d0, ids.x.d1, ids.x.d2 into memory
vm.segments = segments![
((1, 10), 232113757366008801543585_i128),
((1, 11), 232113757366008801543585_i128),
((1, 12), 232113757366008801543585_i128)
];

//Check 'x' is defined in the vm scope
check_scope!(
&exec_scopes,
[(
"x",
bigint_str!(
//Execute the hint
assert_matches!(run_hint!(vm, ids_data, hint_code, &mut exec_scopes), Ok(()));

//Check 'x' is defined in the vm scope
check_scope!(
&exec_scopes,
[(
"x",
bigint_str!(
"1389505070847794345082847096905107459917719328738389700703952672838091425185"
)
)]
);
)]
);
}
}

#[test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ pub fn get_point_from_x(
ap_tracking: &ApTracking,
constants: &HashMap<String, Felt252>,
) -> Result<(), HintError> {
exec_scopes.assign_or_update_variable("SECP_P", any_box!(SECP_P.clone()));
exec_scopes.insert_value("SECP_P", SECP_P.clone());
#[allow(deprecated)]
let beta = constants
.get(BETA)
Expand Down
7 changes: 7 additions & 0 deletions src/tests/cairo_run_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1343,3 +1343,10 @@ fn cairo_run_is_zero() {
let program_data = include_bytes!("../../cairo_programs/is_zero.json");
run_program_simple(program_data.as_slice());
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn cairo_run_is_zero_pack() {
let program_data = include_bytes!("../../cairo_programs/is_zero_pack.json");
run_program_simple(program_data.as_slice());
}