Skip to content

Commit

Permalink
feat(hints): NewHint#60 (#1052)
Browse files Browse the repository at this point in the history
* Add hint code

* Add cairo_programs/compute_slope_v2.cairo

* add hints code

* implement compute_slope_v2

* Implement VERIFY_ZERO_V3

* Add verify_zero_v3 unit tests

* Add COMPUTE_SLOPE_V2 unit test

* Update CHANGELOG.md

* cargo clippy

* Implement hint

* fmt

* Add changelog entry

* Add integration test

* cargo clippy

* Update cairo_run_test.rs

* Fix changelog

* Remove duplicated test

* fixes

* Fix fast_ec_add_assign_new_y

* Fix tests

* Clippy

---------

Co-authored-by: Pedro Fontana <[email protected]>
Co-authored-by: Mario Rugiero <[email protected]>
  • Loading branch information
3 people authored Apr 26, 2023
1 parent 0f57c5d commit 327ee7d
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 15 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,23 @@

#### Upcoming Changes

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

`BuiltinHintProcessor` now supports the following hint:

```python
%{
from starkware.cairo.common.cairo_secp.secp_utils import pack
SECP_P = 2**255-19

slope = pack(ids.slope, PRIME)
x0 = pack(ids.point0.x, PRIME)
x1 = pack(ids.point1.x, PRIME)
y0 = pack(ids.point0.y, PRIME)

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):

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

from starkware.cairo.common.cairo_secp.bigint import BigInt3, nondet_bigint3, UnreducedBigInt3
from starkware.cairo.common.cairo_secp.field import (
is_zero,
unreduced_sqr,
)
from cairo_programs.compute_slope_v2 import compute_slope, EcPoint, verify_zero, unreduced_mul
// Computes the addition of two given points.
//
// Arguments:
// point0, point1 - the points to operate on.
//
// Returns:
// res - the sum of the two points (point0 + point1).
//
// Assumption: point0.x != point1.x (however, point0 = point1 = 0 is allowed).
// Note that this means that the function cannot be used if point0 = point1 != 0
// (use ec_double() in this case) or point0 = -point1 != 0 (the result is 0 in this case).
func fast_ec_add{range_check_ptr}(point0: EcPoint, point1: EcPoint) -> (res: EcPoint) {
// Check whether point0 is the zero point.
if (point0.x.d0 == 0) {
if (point0.x.d1 == 0) {
if (point0.x.d2 == 0) {
return (res=point1);
}
}
}

// Check whether point1 is the zero point.
if (point1.x.d0 == 0) {
if (point1.x.d1 == 0) {
if (point1.x.d2 == 0) {
return (res=point0);
}
}
}

let (slope: BigInt3) = compute_slope(point0, point1);
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)
x0 = pack(ids.point0.x, PRIME)
x1 = pack(ids.point1.x, PRIME)
y0 = pack(ids.point0.y, PRIME)
value = new_x = (pow(slope, 2, SECP_P) - x0 - x1) % SECP_P
%}
let (new_x: BigInt3) = nondet_bigint3();

%{ value = new_y = (slope * (x0 - new_x) - y0) % SECP_P %}
let (new_y: BigInt3) = nondet_bigint3();

verify_zero(
UnreducedBigInt3(
d0=slope_sqr.d0 - new_x.d0 - point0.x.d0 - point1.x.d0,
d1=slope_sqr.d1 - new_x.d1 - point0.x.d1 - point1.x.d1,
d2=slope_sqr.d2 - new_x.d2 - point0.x.d2 - point1.x.d2,
),
);

let (x_diff_slope: UnreducedBigInt3) = unreduced_mul(
BigInt3(d0=point0.x.d0 - new_x.d0, d1=point0.x.d1 - new_x.d1, d2=point0.x.d2 - new_x.d2),
slope,
);

verify_zero(
UnreducedBigInt3(
d0=x_diff_slope.d0 - point0.y.d0 - new_y.d0,
d1=x_diff_slope.d1 - point0.y.d1 - new_y.d1,
d2=x_diff_slope.d2 - point0.y.d2 - new_y.d2,
),
);

return (res=EcPoint(new_x, new_y));
}

func main{range_check_ptr}() {
let x_0 = BigInt3(1,2,3);
let y_0 = BigInt3(4,5,6);
let p_0 = EcPoint(x_0, y_0);

let x_1 = BigInt3(7,8,9);
let y_1 = BigInt3(10,11,12);
let p_1 = EcPoint(x_1, y_1);

let (r) = fast_ec_add(p_0, p_1);

assert r.x.d0 = 77371252455336267181195238;
assert r.x.d1 = 77371252455336267181195253;
assert r.x.d2 = 9671406556917033397649395;

assert r.y.d0 = 4;
assert r.y.d1 = 7;
assert r.y.d2 = 9;

return ();
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ 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_negate_embedded_secp_p,
ec_negate_import_secp_p,
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},
},
Expand Down Expand Up @@ -51,9 +51,8 @@ use crate::{
secp::{
bigint_utils::{bigint_to_uint256, hi_max_bitlen, nondet_bigint3},
ec_utils::{
compute_doubling_slope, compute_slope, di_bit, ec_mul_inner,
fast_ec_add_assign_new_x, fast_ec_add_assign_new_y, import_secp256r1_p,
quad_bit,
compute_doubling_slope, compute_slope, di_bit, fast_ec_add_assign_new_x,
fast_ec_add_assign_new_y, import_secp256r1_p, quad_bit,
},
field_utils::{
is_zero_assign_scope_variables, is_zero_assign_scope_variables_external_const,
Expand Down Expand Up @@ -576,6 +575,14 @@ impl HintProcessor for BuiltinHintProcessor {
exec_scopes,
&hint_data.ids_data,
&hint_data.ap_tracking,
&SECP_P,
),
hint_code::FAST_EC_ADD_ASSIGN_NEW_X_V2 => fast_ec_add_assign_new_x(
vm,
exec_scopes,
&hint_data.ids_data,
&hint_data.ap_tracking,
&SECP_P_V2,
),
hint_code::FAST_EC_ADD_ASSIGN_NEW_Y => fast_ec_add_assign_new_y(exec_scopes),
hint_code::EC_MUL_INNER => {
Expand Down
10 changes: 10 additions & 0 deletions src/hint_processor/builtin_hint_processor/hint_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,16 @@ y0 = pack(ids.point0.y, PRIME)
value = new_x = (pow(slope, 2, SECP_P) - x0 - x1) % SECP_P"#;

pub const FAST_EC_ADD_ASSIGN_NEW_X_V2: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import pack
SECP_P = 2**255-19
slope = pack(ids.slope, PRIME)
x0 = pack(ids.point0.x, PRIME)
x1 = pack(ids.point1.x, PRIME)
y0 = pack(ids.point0.y, PRIME)
value = new_x = (pow(slope, 2, SECP_P) - x0 - x1) % SECP_P"#;

pub const FAST_EC_ADD_ASSIGN_NEW_Y: &str =
r#"value = new_y = (slope * (x0 - new_x) - y0) % SECP_P"#;

Expand Down
21 changes: 12 additions & 9 deletions src/hint_processor/builtin_hint_processor/secp/ec_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,21 +271,22 @@ pub fn fast_ec_add_assign_new_x(
exec_scopes: &mut ExecutionScopes,
ids_data: &HashMap<String, HintReference>,
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.point0
let point0 = EcPoint::from_var_name("point0", vm, ids_data, ap_tracking)?;
//ids.point1.x
let point1 = EcPoint::from_var_name("point1", vm, ids_data, ap_tracking)?;

let slope = slope.pack86();
let x0 = point0.x.pack86();
let x1 = point1.x.pack86();
let y0 = point0.y.pack86();
let slope = slope.pack86().mod_floor(secp_p);
let x0 = point0.x.pack86().mod_floor(secp_p);
let x1 = point1.x.pack86().mod_floor(secp_p);
let y0 = point0.y.pack86().mod_floor(secp_p);

let value = (&slope * &slope - &x0 - &x1).mod_floor(&SECP_P);
let value = (&slope * &slope - &x0 - &x1).mod_floor(secp_p);
//Assign variables to vm scope
exec_scopes.insert_value("slope", slope);
exec_scopes.insert_value("x0", x0);
Expand All @@ -302,13 +303,14 @@ Implements hint:
*/
pub fn fast_ec_add_assign_new_y(exec_scopes: &mut ExecutionScopes) -> Result<(), HintError> {
//Get variables from vm scope
let (slope, x0, new_x, y0) = (
let (slope, x0, new_x, y0, secp_p) = (
exec_scopes.get::<BigInt>("slope")?,
exec_scopes.get::<BigInt>("x0")?,
exec_scopes.get::<BigInt>("new_x")?,
exec_scopes.get::<BigInt>("y0")?,
exec_scopes.get::<BigInt>("SECP_P")?,
);
let value = (slope * (x0 - new_x) - y0).mod_floor(&SECP_P);
let value = (slope * (x0 - new_x) - y0).mod_floor(&secp_p);
exec_scopes.insert_value("value", value.clone());
exec_scopes.insert_value("new_y", value);

Expand Down Expand Up @@ -968,7 +970,8 @@ mod tests {
(
"y0",
bigint_str!("4310143708685312414132851373791311001152018708061750480")
)
),
("SECP_P", (*SECP_P).clone())
];

//Execute the hint
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ lazy_static! {
"115792089237316195423570985008687907853269984665640564039457584007908834671663"
)
.unwrap();

//SECP_P_V2 = 2**255-19
pub(crate) static ref SECP_P_V2: BigInt = BigInt::from_str(
"57896044618658097711785492504343953926634992332820282019728792003956564819949"
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 @@ -884,6 +884,13 @@ fn cairo_run_compute_doubling_slope_v2_test() {
run_program_simple(program_data.as_slice());
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn fast_ec_add_v2() {
let program_data = include_bytes!("../../cairo_programs/fast_ec_add_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() {
Expand Down

0 comments on commit 327ee7d

Please sign in to comment.