diff --git a/CHANGELOG.md b/CHANGELOG.md index 12df582fb4..ab458d240a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,14 +2,33 @@ #### Upcoming Changes +Add missing hint on vrf.json lib [#1053](https://github.com/lambdaclass/cairo-rs/pull/1053): + + `BuiltinHintProcessor` now supports the following hint: + + ```python + %{ + from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack + SECP_P = 2**255-19 + + slope = pack(ids.slope, PRIME) + x = pack(ids.point.x, PRIME) + y = pack(ids.point.y, PRIME) + + value = new_x = (pow(slope, 2, SECP_P) - 2 * x) % SECP_P + %} + ``` + * Implement hint on 0.6.0.json whitelist [#1044](https://github.com/lambdaclass/cairo-rs/pull/1044): `BuiltinHintProcessor` now supports the following hints: + ``` %{ ids.a_lsb = ids.a & 1 ids.b_lsb = ids.b & 1 %} + ``` * Implement hint for `starkware.cairo.common.cairo_keccak.keccak._block_permutation` as described by whitelist `starknet/security/whitelists/cairo_keccak.json` [#1046](https://github.com/lambdaclass/cairo-rs/pull/1046) diff --git a/cairo_programs/ec_double_assign_new_x_v3.cairo b/cairo_programs/ec_double_assign_new_x_v3.cairo new file mode 100644 index 0000000000..7474dd7550 --- /dev/null +++ b/cairo_programs/ec_double_assign_new_x_v3.cairo @@ -0,0 +1,80 @@ +from starkware.cairo.common.cairo_secp.bigint import BigInt3, nondet_bigint3, UnreducedBigInt3 +from cairo_programs.compute_slope_v2 import verify_zero, unreduced_mul +from cairo_programs.compute_doubling_slope_v2 import compute_doubling_slope, EcPoint, unreduced_sqr + +// Computes the addition of a given point to itself. +// +// Arguments: +// point - the point to operate on. +// +// Returns: +// res - a point representing point + point. +func ec_double{range_check_ptr}(point: EcPoint) -> (res: EcPoint) { + // The zero point. + if (point.x.d0 == 0) { + if (point.x.d1 == 0) { + if (point.x.d2 == 0) { + return (res=point); + } + } + } + + let (slope: BigInt3) = compute_doubling_slope(point); + let (slope_sqr: UnreducedBigInt3) = unreduced_sqr(slope); + + %{ + from starkware.cairo.common.cairo_secp.secp_utils import pack + SECP_P = 2**255-19 + + slope = pack(ids.slope, PRIME) + x = pack(ids.point.x, PRIME) + y = pack(ids.point.y, PRIME) + + value = new_x = (pow(slope, 2, SECP_P) - 2 * x) % SECP_P + %} + + let (new_x: BigInt3) = nondet_bigint3(); + + %{ value = new_y = (slope * (x - new_x) - y) % SECP_P %} + let (new_y: BigInt3) = nondet_bigint3(); + + verify_zero( + UnreducedBigInt3( + d0=slope_sqr.d0 - new_x.d0 - 2 * point.x.d0, + d1=slope_sqr.d1 - new_x.d1 - 2 * point.x.d1, + d2=slope_sqr.d2 - new_x.d2 - 2 * point.x.d2, + ), + ); + + let (x_diff_slope: UnreducedBigInt3) = unreduced_mul( + BigInt3(d0=point.x.d0 - new_x.d0, d1=point.x.d1 - new_x.d1, d2=point.x.d2 - new_x.d2), slope + ); + + verify_zero( + UnreducedBigInt3( + d0=x_diff_slope.d0 - point.y.d0 - new_y.d0, + d1=x_diff_slope.d1 - point.y.d1 - new_y.d1, + d2=x_diff_slope.d2 - point.y.d2 - new_y.d2, + ), + ); + + return (res=EcPoint(new_x, new_y)); +} + +func main{range_check_ptr}() { + let x = BigInt3(1,2,3); + let y = BigInt3(4,5,6); + let p = EcPoint(x, y); + + let (r) = ec_double(p); + + assert r.x.d0 = 15463639180909693576579425; + assert r.x.d1 = 18412232947780787290771221; + assert r.x.d2 = 2302636566907525872042731; + + assert r.y.d0 = 62720835442754730087165024; + assert r.y.d1 = 51587896485732116326812460; + assert r.y.d2 = 1463255073263285938516131; + + 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 a23fb91925..000a125433 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 @@ -519,8 +519,21 @@ impl HintProcessor for BuiltinHintProcessor { &SECP_P, ), hint_code::EC_DOUBLE_ASSIGN_NEW_X_V1 | hint_code::EC_DOUBLE_ASSIGN_NEW_X_V2 => { - ec_double_assign_new_x(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking) + ec_double_assign_new_x( + vm, + exec_scopes, + &hint_data.ids_data, + &hint_data.ap_tracking, + &SECP_P, + ) } + hint_code::EC_DOUBLE_ASSIGN_NEW_X_V3 => ec_double_assign_new_x( + vm, + exec_scopes, + &hint_data.ids_data, + &hint_data.ap_tracking, + &SECP_P_V2, + ), hint_code::EC_DOUBLE_ASSIGN_NEW_Y => ec_double_assign_new_y(exec_scopes), hint_code::KECCAK_WRITE_ARGS => { keccak_write_args(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 00ddb675b7..666282aee7 100644 --- a/src/hint_processor/builtin_hint_processor/hint_code.rs +++ b/src/hint_processor/builtin_hint_processor/hint_code.rs @@ -696,6 +696,15 @@ y = pack(ids.point.y, PRIME) value = new_x = (pow(slope, 2, SECP_P) - 2 * x) % SECP_P"#; +pub const EC_DOUBLE_ASSIGN_NEW_X_V3: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import pack +SECP_P = 2**255-19 + +slope = pack(ids.slope, PRIME) +x = pack(ids.point.x, PRIME) +y = pack(ids.point.y, PRIME) + +value = new_x = (pow(slope, 2, SECP_P) - 2 * x) % SECP_P"#; + pub const EC_DOUBLE_ASSIGN_NEW_Y: &str = r#"value = new_y = (slope * (x - new_x) - y) % SECP_P"#; pub const SHA256_INPUT: &str = r#"ids.full_word = int(ids.n_bytes >= 4)"#; 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 422253e40b..64bd962360 100644 --- a/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs +++ b/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs @@ -210,18 +210,19 @@ pub fn ec_double_assign_new_x( exec_scopes: &mut ExecutionScopes, ids_data: &HashMap, ap_tracking: &ApTracking, + secp_p: &BigInt, ) -> Result<(), HintError> { - exec_scopes.insert_value("SECP_P", 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 let point = EcPoint::from_var_name("point", vm, ids_data, ap_tracking)?; - let slope = slope.pack86(); - let x = point.x.pack86(); - let y = point.y.pack86(); + let slope = slope.pack86().mod_floor(secp_p); + let x = point.x.pack86().mod_floor(secp_p); + let y = point.y.pack86().mod_floor(secp_p); - let value = (slope.pow(2) - (&x << 1u32)).mod_floor(&SECP_P); + let value = (slope.pow(2) - (&x << 1u32)).mod_floor(secp_p); //Assign variables to vm scope exec_scopes.insert_value("slope", slope); @@ -238,14 +239,15 @@ Implements hint: */ pub fn ec_double_assign_new_y(exec_scopes: &mut ExecutionScopes) -> Result<(), HintError> { //Get variables from vm scope - let (slope, x, new_x, y) = ( + let (slope, x, new_x, y, secp_p) = ( exec_scopes.get::("slope")?, exec_scopes.get::("x")?, exec_scopes.get::("new_x")?, exec_scopes.get::("y")?, + exec_scopes.get::("SECP_P")?, ); - let value = (slope * (x - new_x) - y).mod_floor(&SECP_P); + let value = (slope * (x - new_x) - y).mod_floor(&secp_p); exec_scopes.insert_value("value", value.clone()); exec_scopes.insert_value("new_y", value); Ok(()) @@ -855,7 +857,8 @@ mod tests { ( "y", bigint_str!("4310143708685312414132851373791311001152018708061750480") - ) + ), + ("SECP_P", (*SECP_P).clone()) ]; //Execute the hint assert_matches!( diff --git a/src/tests/cairo_run_test.rs b/src/tests/cairo_run_test.rs index 65fae7c704..3b4b1a2701 100644 --- a/src/tests/cairo_run_test.rs +++ b/src/tests/cairo_run_test.rs @@ -883,3 +883,10 @@ fn cairo_run_compute_doubling_slope_v2_test() { let program_data = include_bytes!("../../cairo_programs/compute_doubling_slope_v2.json"); run_program_simple(program_data.as_slice()); } + +#[test] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +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()); +}