From 47e7b3470e77361874750c05400fbfcf7ce6c39c Mon Sep 17 00:00:00 2001 From: mfachal <647731+mfachal@users.noreply.github.com> Date: Wed, 26 Apr 2023 20:18:12 -0300 Subject: [PATCH 1/4] Newhint#17 & Newhint#18 imports of SECP256R1_ALPHA and SECP256R1_N (#1026) * WIP newhint#17 and newhint#18 * WIP cairo program * add secp256r1 testing programs and newhint#17 and #18 * update changelog * remove program using unimplemented hint * add correct constants to test program * fix broken test when executing hint #25 with different context * Update CHANGELOG.md Co-authored-by: Mario Rugiero * merge * add unit test for import alpha --------- Co-authored-by: Mario Rugiero --- CHANGELOG.md | 13 ++++ cairo_programs/secp256r1_div_mod_n.cairo | 75 +++++++++++++++++++ .../builtin_hint_processor_definition.rs | 5 +- .../builtin_hint_processor/hint_code.rs | 6 ++ .../builtin_hint_processor/secp/ec_utils.rs | 47 +++++++++++- .../builtin_hint_processor/secp/secp_utils.rs | 2 +- .../builtin_hint_processor/secp/signature.rs | 10 ++- src/tests/cairo_run_test.rs | 7 ++ 8 files changed, 159 insertions(+), 6 deletions(-) create mode 100644 cairo_programs/secp256r1_div_mod_n.cairo diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e0f90c404..dae41525e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -354,6 +354,19 @@ Add missing hint on vrf.json lib [#1053](https://github.com/lambdaclass/cairo-rs * Remove duplicated tests in cairo_run_test * BREAKING CHANGE: `MemorySegmentManager.get_memory_holes` now also receives the amount of builtins in the vm. Signature is now `pub fn get_memory_holes(&self, builtin_count: usize) -> Result` +* Add missing hints on cairo_secp lib [#1026](https://github.com/lambdaclass/cairo-rs/pull/1026): + + `BuiltinHintProcessor` now supports the following hints: + + ```python + from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_ALPHA as ALPHA + ``` + and: + + ```python + from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_N as N + ``` + * Add missing hint on vrf.json lib [#1043](https://github.com/lambdaclass/cairo-rs/pull/1043): `BuiltinHintProcessor` now supports the following hint: diff --git a/cairo_programs/secp256r1_div_mod_n.cairo b/cairo_programs/secp256r1_div_mod_n.cairo new file mode 100644 index 0000000000..ab77e03570 --- /dev/null +++ b/cairo_programs/secp256r1_div_mod_n.cairo @@ -0,0 +1,75 @@ +%builtins range_check + +// Sources: https://github.com/myBraavos/efficient-secp256r1/blob/main/src/secp256r1/signature.cairo#L48 +// Sources: https://github.com/myBraavos/efficient-secp256r1/blob/main/src/secp256r1/ec.cairo#L32 + +from starkware.cairo.common.cairo_secp.bigint import BigInt3, nondet_bigint3, BASE, bigint_mul + +// N = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551 +const N0 = 0x179e84f3b9cac2fc632551; +const N1 = 0x3ffffffffffef39beab69c; +const N2 = 0xffffffff00000000fffff; + +func div_mod_n{range_check_ptr}(a: BigInt3, b: BigInt3) -> (res: BigInt3) { + %{ from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_N as N %} + // Hint 24 + %{ + from starkware.cairo.common.cairo_secp.secp_utils import pack + from starkware.python.math_utils import div_mod, safe_div + + a = pack(ids.a, PRIME) + b = pack(ids.b, PRIME) + value = res = div_mod(a, b, N) + %} + let (res) = nondet_bigint3(); + // Hint 25 + %{ + value = k_plus_one = safe_div(res * b - a, N) + 1 + %} + let (k_plus_one) = nondet_bigint3(); + let k = BigInt3(d0=k_plus_one.d0 - 1, d1=k_plus_one.d1, d2=k_plus_one.d2); + + let (res_b) = bigint_mul(res, b); + let n = BigInt3(N0, N1, N2); + let (k_n) = bigint_mul(k, n); + + // We should now have res_b = k_n + a. Since the numbers are in unreduced form, + // we should handle the carry. + + tempvar carry1 = (res_b.d0 - k_n.d0 - a.d0) / BASE; + assert [range_check_ptr + 0] = carry1 + 2 ** 127; + + tempvar carry2 = (res_b.d1 - k_n.d1 - a.d1 + carry1) / BASE; + assert [range_check_ptr + 1] = carry2 + 2 ** 127; + + tempvar carry3 = (res_b.d2 - k_n.d2 - a.d2 + carry2) / BASE; + assert [range_check_ptr + 2] = carry3 + 2 ** 127; + + tempvar carry4 = (res_b.d3 - k_n.d3 + carry3) / BASE; + assert [range_check_ptr + 3] = carry4 + 2 ** 127; + + assert res_b.d4 - k_n.d4 + carry4 = 0; + + let range_check_ptr = range_check_ptr + 4; + + return (res=res); +} + +func test_div_mod_n{range_check_ptr: felt}() { + let a: BigInt3 = BigInt3(100, 99, 98); + let b: BigInt3 = BigInt3(10, 9, 8); + + let (res) = div_mod_n(a, b); + + assert res = BigInt3( + 17710125265123803206911742, 47938808641831879622633720, 16714845192957993827873659 + ); + + return (); +} + +func main{range_check_ptr: felt}() { + test_div_mod_n(); + + return (); +} diff --git a/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs b/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs index c3c9a2bcea..40e537bd27 100644 --- a/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs +++ b/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs @@ -52,7 +52,8 @@ use crate::{ bigint_utils::{bigint_to_uint256, hi_max_bitlen, nondet_bigint3}, ec_utils::{ compute_doubling_slope, compute_slope, di_bit, fast_ec_add_assign_new_x, - fast_ec_add_assign_new_y, import_secp256r1_p, quad_bit, + fast_ec_add_assign_new_y, import_secp256r1_alpha, import_secp256r1_n, + import_secp256r1_p, quad_bit, }, field_utils::{ is_zero_assign_scope_variables, is_zero_assign_scope_variables_external_const, @@ -673,6 +674,8 @@ impl HintProcessor for BuiltinHintProcessor { hint_code::UINT256_MUL_DIV_MOD => { uint256_mul_div_mod(vm, &hint_data.ids_data, &hint_data.ap_tracking) } + hint_code::IMPORT_SECP256R1_ALPHA => import_secp256r1_alpha(exec_scopes), + hint_code::IMPORT_SECP256R1_N => import_secp256r1_n(exec_scopes), hint_code::UINT512_UNSIGNED_DIV_REM => { uint512_unsigned_div_rem(vm, &hint_data.ids_data, &hint_data.ap_tracking) } diff --git a/src/hint_processor/builtin_hint_processor/hint_code.rs b/src/hint_processor/builtin_hint_processor/hint_code.rs index 612a88b690..229323f78e 100644 --- a/src/hint_processor/builtin_hint_processor/hint_code.rs +++ b/src/hint_processor/builtin_hint_processor/hint_code.rs @@ -1049,6 +1049,12 @@ ids.remainder.d2 = remainder_split[2]"#; pub const UINT384_SIGNED_NN: &str = "memory[ap] = 1 if 0 <= (ids.a.d2 % PRIME) < 2 ** 127 else 0"; +pub const IMPORT_SECP256R1_ALPHA: &str = + "from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_ALPHA as ALPHA"; + +pub const IMPORT_SECP256R1_N: &str = + "from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_N as N"; + pub const UINT384_GET_SQUARE_ROOT: &str = "from starkware.python.math_utils import is_quad_residue, sqrt diff --git a/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs b/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs index 51d977e156..f80fe6caf1 100644 --- a/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs +++ b/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs @@ -5,7 +5,10 @@ use crate::{ get_integer_from_var_name, get_relocatable_from_var_name, insert_value_from_var_name, insert_value_into_ap, }, - secp::{bigint_utils::BigInt3, secp_utils::SECP_P}, + secp::{ + bigint_utils::BigInt3, + secp_utils::{SECP256R1_ALPHA, SECP256R1_N, SECP_P}, + }, }, hint_processor_definition::HintReference, }, @@ -18,6 +21,7 @@ use crate::{ use felt::Felt252; use num_bigint::BigInt; use num_integer::Integer; + use num_traits::{One, ToPrimitive, Zero}; use super::secp_utils::SECP256R1_P; @@ -333,6 +337,24 @@ pub fn ec_mul_inner( insert_value_into_ap(vm, scalar) } +/* +Implements hint: +%{ from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_ALPHA as ALPHA %} +*/ +pub fn import_secp256r1_alpha(exec_scopes: &mut ExecutionScopes) -> Result<(), HintError> { + exec_scopes.insert_value("ALPHA", SECP256R1_ALPHA.clone()); + Ok(()) +} + +/* +Implements hint: +%{ from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_N as N %} +*/ +pub fn import_secp256r1_n(exec_scopes: &mut ExecutionScopes) -> Result<(), HintError> { + exec_scopes.insert_value("N", SECP256R1_N.clone()); + Ok(()) +} + /* Implements hint: %{ @@ -435,6 +457,7 @@ mod tests { }; use assert_matches::assert_matches; + use num_bigint::BigUint; #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::*; @@ -1142,4 +1165,26 @@ mod tests { // Check hint memory inserts check_memory![vm.segments.memory, ((1, 3), 2)]; } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn run_import_secp256r1_alpha() { + let hint_code = "from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_ALPHA as ALPHA"; + let mut vm = vm_with_range_check!(); + + //Initialize fp + vm.run_context.fp = 1; + //Create hint_data + let ids_data = ids_data!["point"]; + let mut exec_scopes = ExecutionScopes::new(); + //Execute the hint + assert_matches!(run_hint!(vm, ids_data, hint_code, &mut exec_scopes), Ok(())); + //Check 'ALPHA' is defined in the vm scope + assert_matches!( + exec_scopes.get::("ALPHA"), + Ok(x) if x == biguint_str!( + "115792089210356248762697446949407573530086143415290314195533631308867097853948" + ) + ); + } } diff --git a/src/hint_processor/builtin_hint_processor/secp/secp_utils.rs b/src/hint_processor/builtin_hint_processor/secp/secp_utils.rs index 155b9f4976..967e6da3e8 100644 --- a/src/hint_processor/builtin_hint_processor/secp/secp_utils.rs +++ b/src/hint_processor/builtin_hint_processor/secp/secp_utils.rs @@ -61,7 +61,7 @@ lazy_static! { "115792089210356248762697446949407573530086143415290314195533631308867097853951" ).unwrap(); //SECP256R1_N = 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551 - pub(crate) static ref SECP256R1_N: BigUint = BigUint::from_str( + pub(crate) static ref SECP256R1_N: BigInt = BigInt::from_str( "115792089210356248762697446949407573529996955224135760342422259061068512044369" ).unwrap(); //SECP256R1_ALPHA = 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC diff --git a/src/hint_processor/builtin_hint_processor/secp/signature.rs b/src/hint_processor/builtin_hint_processor/secp/signature.rs index b8f369ca1c..d4a2d3b0a4 100644 --- a/src/hint_processor/builtin_hint_processor/secp/signature.rs +++ b/src/hint_processor/builtin_hint_processor/secp/signature.rs @@ -81,7 +81,9 @@ pub fn div_mod_n_safe_div( let b = exec_scopes.get_ref::(b_alias)?; let res = exec_scopes.get_ref::("res")?; - let value = safe_div_bigint(&(res * b - a), &N)?.add(to_add); + let n = exec_scopes.get("N")?; + + let value = safe_div_bigint(&(res * b - a), &n)?.add(to_add); exec_scopes.insert_value("value", value); Ok(()) @@ -151,6 +153,7 @@ pub fn pack_modn_div_modn( let value = div_mod(&x, &s, &N); exec_scopes.insert_value("x", x); exec_scopes.insert_value("s", s); + exec_scopes.insert_value("N", N.clone()); exec_scopes.insert_value("value", value.clone()); exec_scopes.insert_value("res", value); Ok(()) @@ -218,7 +221,8 @@ mod tests { let mut exec_scopes = scope![ ("a", BigInt::zero()), ("b", BigInt::one()), - ("res", BigInt::one()) + ("res", BigInt::one()), + ("N", N.clone()) ]; assert_matches!( div_mod_n_safe_div( @@ -308,6 +312,7 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn pack_modn_div_modn_ok() { let hint_code = hint_code::PACK_MODN_DIV_MODN; + let mut exec_scopes = scope![("N", N.clone())]; let mut vm = vm!(); vm.segments = segments![ @@ -320,7 +325,6 @@ mod tests { ]; vm.run_context.fp = 3; let ids_data = non_continuous_ids_data![("x", -3), ("s", 0)]; - let mut exec_scopes = ExecutionScopes::new(); assert_matches!(run_hint!(vm, ids_data, hint_code, &mut exec_scopes), Ok(())); assert_matches!(div_mod_n_safe_div(&mut exec_scopes, "x", "s", 0), Ok(())); } diff --git a/src/tests/cairo_run_test.rs b/src/tests/cairo_run_test.rs index 9d8c6d4e41..e237566c28 100644 --- a/src/tests/cairo_run_test.rs +++ b/src/tests/cairo_run_test.rs @@ -793,6 +793,13 @@ fn is_zero() { run_program_simple(program_data.as_slice()); } +#[test] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +fn cairo_run_secp256r1_div_mod_n() { + let program_data = include_bytes!("../../cairo_programs/secp256r1_div_mod_n.json"); + run_program_simple(program_data.as_slice()); +} + #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn is_zero_pack() { From 45a43aa8923c7efeed834eb19832e22b8b2d4c09 Mon Sep 17 00:00:00 2001 From: fmoletta <99273364+fmoletta@users.noreply.github.com> Date: Thu, 27 Apr 2023 02:31:30 +0300 Subject: [PATCH 2/4] feat(hints): Add alternative hint string for nondet_bigint3 (#1071) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add alternative hint string for nondet_bigint_3 * Add integration test * Rename test file * Add changelog entry * Fix hint * Update CHANGELOG.md Co-authored-by: Tomás <47506558+MegaRedHand@users.noreply.github.com> --------- Co-authored-by: Mario Rugiero Co-authored-by: Tomás <47506558+MegaRedHand@users.noreply.github.com> --- CHANGELOG.md | 13 +++++- cairo_programs/nondet_bigint3_v2.cairo | 45 +++++++++++++++++++ .../builtin_hint_processor_definition.rs | 2 +- .../builtin_hint_processor/hint_code.rs | 5 ++- src/tests/cairo_run_test.rs | 7 +++ 5 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 cairo_programs/nondet_bigint3_v2.cairo diff --git a/CHANGELOG.md b/CHANGELOG.md index dae41525e4..2c605e7234 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ #### Upcoming Changes +* Add alternative hint code for nondet_bigint3 hint [#1071](https://github.com/lambdaclass/cairo-rs/pull/1071) + + `BuiltinHintProcessor` now supports the following hint: + + ```python + %{ + from starkware.cairo.common.cairo_secp.secp_utils import split + segments.write_arg(ids.res.address_, split(value)) + %} + ``` + * Add missing hint on vrf.json lib [#1052](https://github.com/lambdaclass/cairo-rs/pull/1052): `BuiltinHintProcessor` now supports the following hint: @@ -19,7 +30,7 @@ value = new_x = (pow(slope, 2, SECP_P) - x0 - x1) % SECP_P ``` -Add missing hint on vrf.json lib [#1053](https://github.com/lambdaclass/cairo-rs/pull/1053): +* Add missing hint on vrf.json lib [#1053](https://github.com/lambdaclass/cairo-rs/pull/1053): `BuiltinHintProcessor` now supports the following hint: diff --git a/cairo_programs/nondet_bigint3_v2.cairo b/cairo_programs/nondet_bigint3_v2.cairo new file mode 100644 index 0000000000..45bbb2a9c0 --- /dev/null +++ b/cairo_programs/nondet_bigint3_v2.cairo @@ -0,0 +1,45 @@ +%builtins range_check + +from starkware.cairo.common.cairo_secp.bigint import BigInt3, BASE + +// Hint arguments: value. +func nondet_bigint3{range_check_ptr}() -> (res: BigInt3) { + // The result should be at the end of the stack after the function returns. + let res: BigInt3 = [cast(ap + 5, BigInt3*)]; + %{ + from starkware.cairo.common.cairo_secp.secp_utils import split + segments.write_arg(ids.res.address_, split(value)) + %} + // The maximal possible sum of the limbs, assuming each of them is in the range [0, BASE). + const MAX_SUM = 3 * (BASE - 1); + assert [range_check_ptr] = MAX_SUM - (res.d0 + res.d1 + res.d2); + + // Prepare the result at the end of the stack. + tempvar range_check_ptr = range_check_ptr + 4; + [range_check_ptr - 3] = res.d0, ap++; + [range_check_ptr - 2] = res.d1, ap++; + [range_check_ptr - 1] = res.d2, ap++; + static_assert &res + BigInt3.SIZE == ap; + return (res=res); +} + +func main{range_check_ptr}() { + alloc_locals; + // Take these hints from div_mod_n just to have a value in scope + local a: BigInt3 = BigInt3(1,2,3); + local b: BigInt3 = BigInt3(4,5,6); + %{ + from starkware.cairo.common.cairo_secp.secp_utils import N, pack + from starkware.python.math_utils import div_mod, safe_div + + a = pack(ids.a, PRIME) + b = pack(ids.b, PRIME) + value = res = div_mod(a, b, N) + %} + let (r) = nondet_bigint3(); + assert r.d0 = 46511138620617205537268188; + assert r.d1 = 26286155657000021849694253; + assert r.d2 = 3102515549921694024741409; + return(); +} + diff --git a/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs b/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs index 40e537bd27..ba666d33c2 100644 --- a/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs +++ b/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs @@ -297,7 +297,7 @@ impl HintProcessor for BuiltinHintProcessor { &hint_data.ids_data, &hint_data.ap_tracking, ), - hint_code::NONDET_BIGINT3 => { + hint_code::NONDET_BIGINT3_V1 | hint_code::NONDET_BIGINT3_V2 => { nondet_bigint3(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking) } hint_code::REDUCE => { diff --git a/src/hint_processor/builtin_hint_processor/hint_code.rs b/src/hint_processor/builtin_hint_processor/hint_code.rs index 229323f78e..cdb44bc186 100644 --- a/src/hint_processor/builtin_hint_processor/hint_code.rs +++ b/src/hint_processor/builtin_hint_processor/hint_code.rs @@ -471,10 +471,13 @@ new_state = blake2s_compress( segments.write_arg(ids.output, new_state)"#; -pub const NONDET_BIGINT3: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import split +pub const NONDET_BIGINT3_V1: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import split segments.write_arg(ids.res.address_, split(value))"#; +pub const NONDET_BIGINT3_V2: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import split +segments.write_arg(ids.res.address_, split(value))"#; + pub const VERIFY_ZERO_V1: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack q, r = divmod(pack(ids.val, PRIME), SECP_P) diff --git a/src/tests/cairo_run_test.rs b/src/tests/cairo_run_test.rs index e237566c28..ef3903621b 100644 --- a/src/tests/cairo_run_test.rs +++ b/src/tests/cairo_run_test.rs @@ -904,3 +904,10 @@ fn ec_double_assign_new_x_v3() { let program_data = include_bytes!("../../cairo_programs/ec_double_assign_new_x_v3.json"); run_program_simple(program_data.as_slice()); } + +#[test] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +fn nondet_bigint3_v2() { + let program_data = include_bytes!("../../cairo_programs/nondet_bigint3_v2.json"); + run_program_simple(program_data.as_slice()); +} From 1dc3fe470c4ef4a7ed3e9c8eed6b7bbfb0e2f4aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s?= <47506558+MegaRedHand@users.noreply.github.com> Date: Thu, 27 Apr 2023 10:41:47 -0300 Subject: [PATCH 3/4] feat: add `Program` method for iterating identifiers (#1079) * Add `Program::iter_identifiers` * Add unit test * Update changelog * Change &String -> &str --- CHANGELOG.md | 2 ++ src/types/program.rs | 71 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c605e7234..4fc42c5c86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -126,6 +126,8 @@ segments.write_arg(ids.blake2s_ptr_end, padding) %} +* Add `Program::iter_identifiers(&self) -> Iterator` to get an iterator over the program's identifiers [#1079](https://github.com/lambdaclass/cairo-rs/pull/1079) + * Implement hint on `assert_le_felt` for versions 0.6.0 and 0.8.2 [#1047](https://github.com/lambdaclass/cairo-rs/pull/1047): `BuiltinHintProcessor` now supports the following hints: diff --git a/src/types/program.rs b/src/types/program.rs index 3683bb3cfe..3d29aeaa60 100644 --- a/src/types/program.rs +++ b/src/types/program.rs @@ -124,6 +124,13 @@ impl Program { pub fn get_identifier(&self, id: &str) -> Option<&Identifier> { self.shared_program_data.identifiers.get(id) } + + pub fn iter_identifiers(&self) -> impl Iterator { + self.shared_program_data + .identifiers + .iter() + .map(|(cairo_type, identifier)| (cairo_type.as_str(), identifier)) + } } impl Default for Program { @@ -429,6 +436,70 @@ mod tests { ); } + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn iter_identifiers() { + let reference_manager = ReferenceManager { + references: Vec::new(), + }; + + let builtins: Vec = Vec::new(); + + let data: Vec = vec![ + mayberelocatable!(5189976364521848832), + mayberelocatable!(1000), + mayberelocatable!(5189976364521848832), + mayberelocatable!(2000), + mayberelocatable!(5201798304953696256), + mayberelocatable!(2345108766317314046), + ]; + + let mut identifiers: HashMap = HashMap::new(); + + identifiers.insert( + String::from("__main__.main"), + Identifier { + pc: Some(0), + type_: Some(String::from("function")), + value: None, + full_name: None, + members: None, + cairo_type: None, + }, + ); + + identifiers.insert( + String::from("__main__.main.SIZEOF_LOCALS"), + Identifier { + pc: None, + type_: Some(String::from("const")), + value: Some(Felt252::zero()), + full_name: None, + members: None, + cairo_type: None, + }, + ); + + let program = Program::new( + builtins, + data, + None, + HashMap::new(), + reference_manager, + identifiers.clone(), + Vec::new(), + None, + ) + .unwrap(); + + let collected_identifiers: HashMap<_, _> = program + .iter_identifiers() + .map(|(cairo_type, identifier)| (cairo_type.to_string(), identifier.clone())) + .collect(); + + assert_eq!(collected_identifiers, identifiers); + } + #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn new_program_with_invalid_identifiers() { From 0fad948c9bf33939376b073456dfecb22c7404e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s?= <47506558+MegaRedHand@users.noreply.github.com> Date: Thu, 27 Apr 2023 10:56:44 -0300 Subject: [PATCH 4/4] feat(hints): add NewHint#19 (#1057) * Add NewHint#19 * Update changelog * Allow trailing commas in check_scope macro * Fix: was trying to get BigUint from exec_scopes --- CHANGELOG.md | 14 ++ cairo_programs/ec_double_slope.cairo | 212 ++++++++++++++++++ .../builtin_hint_processor_definition.rs | 17 +- .../builtin_hint_processor/hint_code.rs | 14 +- .../builtin_hint_processor/secp/ec_utils.rs | 152 +++++++++---- .../builtin_hint_processor/secp/secp_utils.rs | 2 +- src/tests/cairo_run_test.rs | 7 + src/utils.rs | 2 +- 8 files changed, 370 insertions(+), 50 deletions(-) create mode 100644 cairo_programs/ec_double_slope.cairo diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fc42c5c86..67f5c8302b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -430,6 +430,20 @@ ids.flag = 1 if k > 0 else 0 ``` +* Add missing hint on cairo_secp lib [#1057](https://github.com/lambdaclass/cairo-rs/pull/1057): + + `BuiltinHintProcessor` now supports the following hint: + + ```python + from starkware.cairo.common.cairo_secp.secp_utils import pack + from starkware.python.math_utils import ec_double_slope + + # Compute the slope. + x = pack(ids.point.x, PRIME) + y = pack(ids.point.y, PRIME) + value = slope = ec_double_slope(point=(x, y), alpha=ALPHA, p=SECP_P) + ``` + * Add missing hint on uint256_improvements lib [#1025](https://github.com/lambdaclass/cairo-rs/pull/1025): `BuiltinHintProcessor` now supports the following hint: diff --git a/cairo_programs/ec_double_slope.cairo b/cairo_programs/ec_double_slope.cairo new file mode 100644 index 0000000000..1017748233 --- /dev/null +++ b/cairo_programs/ec_double_slope.cairo @@ -0,0 +1,212 @@ +%builtins range_check + +// Source: https://github.com/rdubois-crypto/efficient-secp256r1/blob/4b74807c5e91f1ed4cb00a1c973be05c63986e61/src/secp256r1/ec.cairo +from starkware.cairo.common.cairo_secp.bigint import BigInt3, UnreducedBigInt3, nondet_bigint3 +from starkware.cairo.common.cairo_secp.ec import EcPoint + +// src.secp256r1.constants +// SECP_REM is defined by the equation: +// secp256r1_prime = 2 ** 256 - SECP_REM. +const SECP_REM = 2 ** 224 - 2 ** 192 - 2 ** 96 + 1; + +const BASE = 2 ** 86; + +// A = 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc +const A0 = 0x3ffffffffffffffffffffc; +const A1 = 0x3ff; +const A2 = 0xffffffff0000000100000; + +// Constants for unreduced_mul/sqr +const s2 = (-(2 ** 76)) - 2 ** 12; +const s1 = (-(2 ** 66)) + 4; +const s0 = 2 ** 56; + +const r2 = 2 ** 54 - 2 ** 22; +const r1 = -(2 ** 12); +const r0 = 4; + +// src.secp256r1.field +// Adapt from starkware.cairo.common.math's assert_250_bit +func assert_165_bit{range_check_ptr}(value) { + const UPPER_BOUND = 2 ** 165; + const SHIFT = 2 ** 128; + const HIGH_BOUND = UPPER_BOUND / SHIFT; + + let low = [range_check_ptr]; + let high = [range_check_ptr + 1]; + + %{ + from starkware.cairo.common.math_utils import as_int + + # Correctness check. + value = as_int(ids.value, PRIME) % PRIME + assert value < ids.UPPER_BOUND, f'{value} is outside of the range [0, 2**250).' + + # Calculation for the assertion. + ids.high, ids.low = divmod(ids.value, ids.SHIFT) + %} + + assert [range_check_ptr + 2] = HIGH_BOUND - 1 - high; + + assert value = high * SHIFT + low; + + let range_check_ptr = range_check_ptr + 3; + return (); +} + +// src.secp256r1.field +// Computes the multiplication of two big integers, given in BigInt3 representation, modulo the +// secp256r1 prime. +// +// Arguments: +// x, y - the two BigInt3 to operate on. +// +// Returns: +// x * y in an UnreducedBigInt3 representation (the returned limbs may be above 3 * BASE). +// +// This means that if unreduced_mul is called on the result of nondet_bigint3, or the difference +// between two such results, we have: +// Soundness guarantee: the limbs are in the range (). +// Completeness guarantee: the limbs are in the range (). +func unreduced_mul(a: BigInt3, b: BigInt3) -> (res_low: UnreducedBigInt3) { + tempvar twice_d2 = a.d2 * b.d2; + tempvar d1d2 = a.d2 * b.d1 + a.d1 * b.d2; + return ( + UnreducedBigInt3( + d0=a.d0 * b.d0 + s0 * twice_d2 + r0 * d1d2, + d1=a.d1 * b.d0 + a.d0 * b.d1 + s1 * twice_d2 + r1 * d1d2, + d2=a.d2 * b.d0 + a.d1 * b.d1 + a.d0 * b.d2 + s2 * twice_d2 + r2 * d1d2, + ), + ); +} + +// src.secp256r1.field +// Computes the square of a big integer, given in BigInt3 representation, modulo the +// secp256r1 prime. +// +// Has the same guarantees as in unreduced_mul(a, a). +func unreduced_sqr(a: BigInt3) -> (res_low: UnreducedBigInt3) { + tempvar twice_d2 = a.d2 * a.d2; + tempvar twice_d1d2 = a.d2 * a.d1 + a.d1 * a.d2; + tempvar d1d0 = a.d1 * a.d0; + return ( + UnreducedBigInt3( + d0=a.d0 * a.d0 + s0 * twice_d2 + r0 * twice_d1d2, + d1=d1d0 + d1d0 + s1 * twice_d2 + r1 * twice_d1d2, + d2=a.d2 * a.d0 + a.d1 * a.d1 + a.d0 * a.d2 + s2 * twice_d2 + r2 * twice_d1d2, + ), + ); +} + +// src.secp256r1.field +// Verifies that the given unreduced value is equal to zero modulo the secp256r1 prime. +// +// Completeness assumption: val's limbs are in the range (-2**210.99, 2**210.99). +// Soundness assumption: val's limbs are in the range (-2**250, 2**250). +func verify_zero{range_check_ptr}(val: UnreducedBigInt3) { + alloc_locals; + local q; + // local q_sign; + let q_sign = 1; + // original: + // %{ from starkware.cairo.common.cairo_secp.secp_utils import SECP256R1_P as SECP_P %} + // %{ + // from starkware.cairo.common.cairo_secp.secp_utils import pack + + // q, r = divmod(pack(ids.val, PRIME), SECP_P) + // assert r == 0, f"verify_zero: Invalid input {ids.val.d0, ids.val.d1, ids.val.d2}." + // if q >= 0: + // ids.q = q % PRIME + // ids.q_sign = 1 + // else: + // ids.q = (0-q) % PRIME + // ids.q_sign = -1 % PRIME + // %} + %{ from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_P as SECP_P %} + %{ + from starkware.cairo.common.cairo_secp.secp_utils import pack + + q, r = divmod(pack(ids.val, PRIME), SECP_P) + assert r == 0, f"verify_zero: Invalid input {ids.val.d0, ids.val.d1, ids.val.d2}." + ids.q = q % PRIME + %} + // assert_250_bit(q); // 256K steps + // assert_le_felt(q, 2**165); // 275K steps + assert_165_bit(q); + assert q_sign * (val.d2 + val.d1 / BASE + val.d0 / BASE ** 2) = q * ( + (BASE / 4) - SECP_REM / BASE ** 2 + ); + // Multiply by BASE**2 both sides: + // (q_sign) * val = q * (BASE**3 / 4 - SECP_REM) + // = q * (2**256 - SECP_REM) = q * secp256r1_prime = 0 mod secp256r1_prime + return (); +} + +// Computes the slope of the elliptic curve at a given point. +// The slope is used to compute point + point. +// +// Arguments: +// point - the point to operate on. +// +// Returns: +// slope - the slope of the curve at point, in BigInt3 representation. +// +// Assumption: point != 0. +func compute_doubling_slope{range_check_ptr}(point: EcPoint) -> (slope: BigInt3) { + // Note that y cannot be zero: assume that it is, then point = -point, so 2 * point = 0, which + // contradicts the fact that the size of the curve is odd. + // originals: + // %{ from starkware.cairo.common.cairo_secp.secp_utils import SECP256R1_P as SECP_P %} + // %{ from starkware.cairo.common.cairo_secp.secp_utils import SECP256R1_ALPHA as ALPHA %} + %{ from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_P as SECP_P %} + %{ from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_ALPHA as ALPHA %} + %{ + from starkware.cairo.common.cairo_secp.secp_utils import pack + from starkware.python.math_utils import ec_double_slope + + # Compute the slope. + x = pack(ids.point.x, PRIME) + y = pack(ids.point.y, PRIME) + value = slope = ec_double_slope(point=(x, y), alpha=ALPHA, p=SECP_P) + %} + let (slope: BigInt3) = nondet_bigint3(); + + let (x_sqr: UnreducedBigInt3) = unreduced_sqr(point.x); + let (slope_y: UnreducedBigInt3) = unreduced_mul(slope, point.y); + verify_zero( + UnreducedBigInt3( + d0=3 * x_sqr.d0 + A0 - 2 * slope_y.d0, + d1=3 * x_sqr.d1 + A1 - 2 * slope_y.d1, + d2=3 * x_sqr.d2 + A2 - 2 * slope_y.d2, + ), + ); + + return (slope=slope); +} + +func test_doubling_slope{range_check_ptr}() { + let point = EcPoint(BigInt3(614323, 5456867, 101208), BigInt3(773712524, 77371252, 5298795)); + + let (slope) = compute_doubling_slope(point); + + assert slope = BigInt3( + 64081873649130491683833713, 34843994309543177837008178, 16548672716077616016846383 + ); + + let point = EcPoint( + BigInt3(51215, 36848548548458, 634734734), BigInt3(26362, 263724839599, 901297012) + ); + + let (slope) = compute_doubling_slope(point); + + assert slope = BigInt3( + 71848883893335852660776740, 75644451964360469099209675, 547087410329256463669633 + ); + + return (); +} + +func main{range_check_ptr}() { + test_doubling_slope(); + return (); +} diff --git a/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs b/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs index ba666d33c2..f2a3fe4c48 100644 --- a/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs +++ b/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs @@ -6,8 +6,9 @@ use super::{ field_arithmetic::{u256_get_square_root, u384_get_square_root, uint384_div}, secp::{ ec_utils::{ - compute_slope_and_assing_secp_p, ec_double_assign_new_y, ec_mul_inner, - ec_negate_embedded_secp_p, ec_negate_import_secp_p, + compute_doubling_slope_external_consts, compute_slope_and_assing_secp_p, + ec_double_assign_new_y, ec_mul_inner, ec_negate_embedded_secp_p, + ec_negate_import_secp_p, }, secp_utils::{ALPHA, ALPHA_V2, SECP_P, SECP_P_V2}, }, @@ -455,7 +456,7 @@ impl HintProcessor for BuiltinHintProcessor { &hint_data.ids_data, &hint_data.ap_tracking, ), - hint_code::EC_DOUBLE_SCOPE_V1 => compute_doubling_slope( + hint_code::EC_DOUBLE_SLOPE_V1 => compute_doubling_slope( vm, exec_scopes, &hint_data.ids_data, @@ -464,7 +465,7 @@ impl HintProcessor for BuiltinHintProcessor { &SECP_P, &ALPHA, ), - hint_code::EC_DOUBLE_SCOPE_V2 => compute_doubling_slope( + hint_code::EC_DOUBLE_SLOPE_V2 => compute_doubling_slope( vm, exec_scopes, &hint_data.ids_data, @@ -473,7 +474,7 @@ impl HintProcessor for BuiltinHintProcessor { &SECP_P_V2, &ALPHA_V2, ), - hint_code::EC_DOUBLE_SCOPE_WHITELIST => compute_doubling_slope( + hint_code::EC_DOUBLE_SLOPE_V3 => compute_doubling_slope( vm, exec_scopes, &hint_data.ids_data, @@ -482,6 +483,12 @@ impl HintProcessor for BuiltinHintProcessor { &SECP_P, &ALPHA, ), + hint_code::EC_DOUBLE_SLOPE_EXTERNAL_CONSTS => compute_doubling_slope_external_consts( + vm, + exec_scopes, + &hint_data.ids_data, + &hint_data.ap_tracking, + ), hint_code::COMPUTE_SLOPE_V1 => compute_slope_and_assing_secp_p( vm, exec_scopes, diff --git a/src/hint_processor/builtin_hint_processor/hint_code.rs b/src/hint_processor/builtin_hint_processor/hint_code.rs index cdb44bc186..80cde7b140 100644 --- a/src/hint_processor/builtin_hint_processor/hint_code.rs +++ b/src/hint_processor/builtin_hint_processor/hint_code.rs @@ -615,7 +615,7 @@ y = pack(ids.point.y, PRIME) % SECP_P # The modulo operation in python always returns a nonnegative number. value = (-y) % SECP_P"#; -pub const EC_DOUBLE_SCOPE_V1: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack +pub const EC_DOUBLE_SLOPE_V1: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack from starkware.python.math_utils import ec_double_slope # Compute the slope. @@ -623,7 +623,7 @@ x = pack(ids.point.x, PRIME) y = pack(ids.point.y, PRIME) value = slope = ec_double_slope(point=(x, y), alpha=0, p=SECP_P)"#; -pub const EC_DOUBLE_SCOPE_V2: &str = r#"from starkware.python.math_utils import ec_double_slope +pub const EC_DOUBLE_SLOPE_V2: &str = r#"from starkware.python.math_utils import ec_double_slope from starkware.cairo.common.cairo_secp.secp_utils import pack SECP_P = 2**255-19 @@ -632,7 +632,7 @@ x = pack(ids.point.x, PRIME) y = pack(ids.point.y, PRIME) value = slope = ec_double_slope(point=(x, y), alpha=42204101795669822316448953119945047945709099015225996174933988943478124189485, p=SECP_P)"#; -pub const EC_DOUBLE_SCOPE_WHITELIST: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack +pub const EC_DOUBLE_SLOPE_V3: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack from starkware.python.math_utils import div_mod # Compute the slope. @@ -640,6 +640,14 @@ x = pack(ids.pt.x, PRIME) y = pack(ids.pt.y, PRIME) value = slope = div_mod(3 * x ** 2, 2 * y, SECP_P)"#; +pub const EC_DOUBLE_SLOPE_EXTERNAL_CONSTS: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import pack +from starkware.python.math_utils import ec_double_slope + +# Compute the slope. +x = pack(ids.point.x, PRIME) +y = pack(ids.point.y, PRIME) +value = slope = ec_double_slope(point=(x, y), alpha=ALPHA, p=SECP_P)"#; + pub const COMPUTE_SLOPE_V1: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack from starkware.python.math_utils import line_slope diff --git a/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs b/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs index f80fe6caf1..1888aa8750 100644 --- a/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs +++ b/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs @@ -138,6 +138,35 @@ pub fn compute_doubling_slope( Ok(()) } +/* +Implements hint: +%{ + from starkware.cairo.common.cairo_secp.secp_utils import pack + from starkware.python.math_utils import ec_double_slope + + # Compute the slope. + x = pack(ids.point.x, PRIME) + y = pack(ids.point.y, PRIME) + value = slope = ec_double_slope(point=(x, y), alpha=ALPHA, p=SECP_P) +%} +*/ +pub fn compute_doubling_slope_external_consts( + vm: &mut VirtualMachine, + exec_scopes: &mut ExecutionScopes, + ids_data: &HashMap, + ap_tracking: &ApTracking, +) -> Result<(), HintError> { + //ids.point + let point = EcPoint::from_var_name("point", vm, ids_data, ap_tracking)?; + let secp_p: BigInt = exec_scopes.get("SECP_P")?; + let alpha: BigInt = exec_scopes.get("ALPHA")?; + + let value = ec_double_slope(&(point.x.pack86(), point.y.pack86()), &alpha, &secp_p); + exec_scopes.insert_value("value", value.clone()); + exec_scopes.insert_value("slope", value); + Ok(()) +} + /* Implements hint: %{ @@ -457,7 +486,6 @@ mod tests { }; use assert_matches::assert_matches; - use num_bigint::BigUint; #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::*; @@ -538,14 +566,14 @@ mod tests { ( "value", bigint_str!( - "40442433062102151071094722250325492738932110061897694430475034100717288403728" - ) + "40442433062102151071094722250325492738932110061897694430475034100717288403728" + ) ), ( "slope", bigint_str!( - "40442433062102151071094722250325492738932110061897694430475034100717288403728" - ) + "40442433062102151071094722250325492738932110061897694430475034100717288403728" + ) ) ] ); @@ -554,7 +582,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn run_ec_double_scope_v2_hint_ok() { - let hint_code = hint_code::EC_DOUBLE_SCOPE_V2; + let hint_code = hint_code::EC_DOUBLE_SLOPE_V2; let mut vm = vm_with_range_check!(); vm.segments = segments![ ((1, 0), 512), @@ -579,14 +607,14 @@ mod tests { ( "value", bigint_str!( - "48268701472940295594394094960749868325610234644833445333946260403470540790234" - ) + "48268701472940295594394094960749868325610234644833445333946260403470540790234" + ) ), ( "slope", bigint_str!( - "48268701472940295594394094960749868325610234644833445333946260403470540790234" - ) + "48268701472940295594394094960749868325610234644833445333946260403470540790234" + ) ), ("SECP_P", SECP_P_V2.clone()) ] @@ -621,19 +649,63 @@ mod tests { ( "value", bigint_str!( - "40442433062102151071094722250325492738932110061897694430475034100717288403728" - ) + "40442433062102151071094722250325492738932110061897694430475034100717288403728" + ) ), ( "slope", bigint_str!( - "40442433062102151071094722250325492738932110061897694430475034100717288403728" - ) + "40442433062102151071094722250325492738932110061897694430475034100717288403728" + ) ) ] ); } + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn run_compute_doubling_slope_with_custom_consts_ok() { + let hint_code = hint_code::EC_DOUBLE_SLOPE_EXTERNAL_CONSTS; + let mut vm = vm_with_range_check!(); + vm.segments = segments![ + ((1, 0), 614323u64), + ((1, 1), 5456867u64), + ((1, 2), 101208u64), + ((1, 3), 773712524u64), + ((1, 4), 77371252u64), + ((1, 5), 5298795u64) + ]; + + //Initialize fp + vm.run_context.fp = 1; + + let ids_data = ids_data!["point"]; + let mut exec_scopes = ExecutionScopes::new(); + + exec_scopes.insert_value("SECP_P", SECP256R1_P.clone()); + exec_scopes.insert_value("ALPHA", SECP256R1_ALPHA.clone()); + + //Execute the hint + assert_matches!(run_hint!(vm, ids_data, hint_code, &mut exec_scopes), Ok(())); + check_scope!( + &exec_scopes, + [ + ( + "value", + bigint_str!( + "99065496658741969395000079476826955370154683653966841736214499259699304892273" + ) + ), + ( + "slope", + bigint_str!( + "99065496658741969395000079476826955370154683653966841736214499259699304892273" + ) + ), + ], + ); + } + #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn run_compute_slope_ok() { @@ -672,14 +744,14 @@ mod tests { ( "value", bigint_str!( - "41419765295989780131385135514529906223027172305400087935755859001910844026631" - ) + "41419765295989780131385135514529906223027172305400087935755859001910844026631" + ) ), ( "slope", bigint_str!( - "41419765295989780131385135514529906223027172305400087935755859001910844026631" - ) + "41419765295989780131385135514529906223027172305400087935755859001910844026631" + ) ) ] ); @@ -727,14 +799,14 @@ mod tests { ( "value", bigint_str!( - "39376930140709393693483102164172662915882483986415749881375763965703119677959" - ) + "39376930140709393693483102164172662915882483986415749881375763965703119677959" + ) ), ( "slope", bigint_str!( - "39376930140709393693483102164172662915882483986415749881375763965703119677959" - ) + "39376930140709393693483102164172662915882483986415749881375763965703119677959" + ) ) ] ); @@ -778,14 +850,14 @@ mod tests { ( "value", bigint_str!( - "41419765295989780131385135514529906223027172305400087935755859001910844026631" - ) + "41419765295989780131385135514529906223027172305400087935755859001910844026631" + ) ), ( "slope", bigint_str!( - "41419765295989780131385135514529906223027172305400087935755859001910844026631" - ) + "41419765295989780131385135514529906223027172305400087935755859001910844026631" + ) ) ] ); @@ -897,14 +969,14 @@ mod tests { ( "value", bigint_str!( - "7948634220683381957329555864604318996476649323793038777651086572350147290350" - ) + "7948634220683381957329555864604318996476649323793038777651086572350147290350" + ) ), ( "new_y", bigint_str!( - "7948634220683381957329555864604318996476649323793038777651086572350147290350" - ) + "7948634220683381957329555864604318996476649323793038777651086572350147290350" + ) ) ] ); @@ -954,14 +1026,14 @@ mod tests { ( "value", bigint_str!( - "8891838197222656627233627110766426698842623939023296165598688719819499152657" - ) + "8891838197222656627233627110766426698842623939023296165598688719819499152657" + ) ), ( "new_x", bigint_str!( - "8891838197222656627233627110766426698842623939023296165598688719819499152657" - ) + "8891838197222656627233627110766426698842623939023296165598688719819499152657" + ) ) ] ); @@ -1009,14 +1081,14 @@ mod tests { ( "value", bigint_str!( - "7948634220683381957329555864604318996476649323793038777651086572350147290350" - ) + "7948634220683381957329555864604318996476649323793038777651086572350147290350" + ) ), ( "new_y", bigint_str!( - "7948634220683381957329555864604318996476649323793038777651086572350147290350" - ) + "7948634220683381957329555864604318996476649323793038777651086572350147290350" + ) ) ] ); @@ -1181,8 +1253,8 @@ mod tests { assert_matches!(run_hint!(vm, ids_data, hint_code, &mut exec_scopes), Ok(())); //Check 'ALPHA' is defined in the vm scope assert_matches!( - exec_scopes.get::("ALPHA"), - Ok(x) if x == biguint_str!( + exec_scopes.get::("ALPHA"), + Ok(x) if x == bigint_str!( "115792089210356248762697446949407573530086143415290314195533631308867097853948" ) ); diff --git a/src/hint_processor/builtin_hint_processor/secp/secp_utils.rs b/src/hint_processor/builtin_hint_processor/secp/secp_utils.rs index 967e6da3e8..03607b8fd5 100644 --- a/src/hint_processor/builtin_hint_processor/secp/secp_utils.rs +++ b/src/hint_processor/builtin_hint_processor/secp/secp_utils.rs @@ -65,7 +65,7 @@ lazy_static! { "115792089210356248762697446949407573529996955224135760342422259061068512044369" ).unwrap(); //SECP256R1_ALPHA = 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC - pub(crate) static ref SECP256R1_ALPHA: BigUint = BigUint::from_str( + pub(crate) static ref SECP256R1_ALPHA: BigInt = BigInt::from_str( "115792089210356248762697446949407573530086143415290314195533631308867097853948" ).unwrap(); } diff --git a/src/tests/cairo_run_test.rs b/src/tests/cairo_run_test.rs index ef3903621b..1885053a54 100644 --- a/src/tests/cairo_run_test.rs +++ b/src/tests/cairo_run_test.rs @@ -911,3 +911,10 @@ fn nondet_bigint3_v2() { let program_data = include_bytes!("../../cairo_programs/nondet_bigint3_v2.json"); run_program_simple(program_data.as_slice()); } + +#[test] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +fn cairo_run_ec_double_slope() { + let program_data = include_bytes!("../../cairo_programs/ec_double_slope.json"); + run_program_simple_with_memory_holes(program_data.as_slice(), 0); +} diff --git a/src/utils.rs b/src/utils.rs index 0501c463bf..28a06d431b 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -424,7 +424,7 @@ pub mod test_utils { pub(crate) use add_segments; macro_rules! check_scope { - ( $exec_scope: expr, [ $( ($name: expr, $val: expr)),* ] ) => { + ( $exec_scope: expr, [ $( ($name: expr, $val: expr)),*$(,)? ] $(,)? ) => { $( check_scope_value($exec_scope, $name, $val); )*