Skip to content

Commit

Permalink
feat(hints): add NewHint#27 (#990)
Browse files Browse the repository at this point in the history
* Add NewHint#27

* Update changelog

* Fix changelog

Some of the entries were being repeated when merging changes, and were also originally misplaced in the 0.3.0-rc1 section

* Make hint codes public
  • Loading branch information
MegaRedHand committed Apr 17, 2023
1 parent 2f557b1 commit ddbeb8a
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 139 deletions.
131 changes: 52 additions & 79 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,58 @@
* 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 [#990](https://github.com/lambdaclass/cairo-rs/pull/990):

`BuiltinHintProcessor` now supports the following hint:
```python
from starkware.cairo.common.cairo_secp.secp_utils import pack

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
```

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

`BuiltinHintProcessor` now supports the following hint:
```python
from starkware.cairo.common.cairo_secp.secp_utils import SECP_P
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
```

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

`BuiltinHintProcessor` now supports the following hint:
```python
from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
from starkware.python.math_utils import div_mod

# Compute the slope.
x = pack(ids.pt.x, PRIME)
y = pack(ids.pt.y, PRIME)
value = slope = div_mod(3 * x ** 2, 2 * y, SECP_P)
```

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

`BuiltinHintProcessor` now supports the following hint:
```python
from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
from starkware.python.math_utils import div_mod

# Compute the slope.
x0 = pack(ids.pt0.x, PRIME)
y0 = pack(ids.pt0.y, PRIME)
x1 = pack(ids.pt1.x, PRIME)
y1 = pack(ids.pt1.y, PRIME)
value = slope = div_mod(y0 - y1, x0 - x1, SECP_P)
```

#### [0.3.0-rc1] - 2023-04-13
* Derive Deserialize for ExecutionResources [#922](https://github.com/lambdaclass/cairo-rs/pull/922)
* Remove builtin names from VirtualMachine.builtin_runners [#921](https://github.com/lambdaclass/cairo-rs/pull/921)
Expand Down Expand Up @@ -61,22 +113,6 @@
* after each step
* ExecutionResource operations: add and substract [#774](https://github.com/lambdaclass/cairo-rs/pull/774), multiplication [#908](https://github.com/lambdaclass/cairo-rs/pull/908) , and `AddAssign` [#914](https://github.com/lambdaclass/cairo-rs/pull/914)


* Add missing hint on cairo_secp lib [#984]:

`BuiltinHintProcessor` now supports the following hint:
```python
from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
from starkware.python.math_utils import div_mod

# Compute the slope.
x0 = pack(ids.pt0.x, PRIME)
y0 = pack(ids.pt0.y, PRIME)
x1 = pack(ids.pt1.x, PRIME)
y1 = pack(ids.pt1.y, PRIME)
value = slope = div_mod(y0 - y1, x0 - x1, SECP_P)
```

* Implement hints on uint384 lib (Part 2) [#971](https://github.com/lambdaclass/cairo-rs/pull/971)

`BuiltinHintProcessor` now supports the following hint:
Expand Down Expand Up @@ -228,69 +264,6 @@

Used by the common library function `uint256_mul_div_mod`

* Add missing hint on cairo_secp lib [#986]:

`BuiltinHintProcessor` now supports the following hint:
```python
from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
from starkware.python.math_utils import div_mod

# Compute the slope.
x = pack(ids.pt.x, PRIME)
y = pack(ids.pt.y, PRIME)
value = slope = div_mod(3 * x ** 2, 2 * y, SECP_P)
```

* Add missing hint on cairo_secp lib [#984]:
`BuiltinHintProcessor` now supports the following hint:
```python
from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
from starkware.python.math_utils import div_mod

# Compute the slope.
x0 = pack(ids.pt0.x, PRIME)
y0 = pack(ids.pt0.y, PRIME)
x1 = pack(ids.pt1.x, PRIME)
y1 = pack(ids.pt1.y, PRIME)
value = slope = div_mod(y0 - y1, x0 - x1, SECP_P)
```

* Add missing hint on cairo_secp lib [#989]:

`BuiltinHintProcessor` now supports the following hint:
```python
from starkware.cairo.common.cairo_secp.secp_utils import SECP_P
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
```

* Add missing hint on cairo_secp lib [#986]:
`BuiltinHintProcessor` now supports the following hint:
```python
from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
from starkware.python.math_utils import div_mod

# Compute the slope.
x = pack(ids.pt.x, PRIME)
y = pack(ids.pt.y, PRIME)
value = slope = div_mod(3 * x ** 2, 2 * y, SECP_P)
```

* Add missing hint on cairo_secp lib [#984]:
`BuiltinHintProcessor` now supports the following hint:
```python
from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
from starkware.python.math_utils import div_mod

# Compute the slope.
x0 = pack(ids.pt0.x, PRIME)
y0 = pack(ids.pt0.y, PRIME)
x1 = pack(ids.pt1.x, PRIME)
y1 = pack(ids.pt1.y, PRIME)
value = slope = div_mod(y0 - y1, x0 - x1, SECP_P)
```

* Move `Memory` into `MemorySegmentManager` [#830](https://github.com/lambdaclass/cairo-rs/pull/830)
* Structural changes:
* Remove `memory: Memory` field from `VirtualMachine`
Expand Down
83 changes: 83 additions & 0 deletions cairo_programs/efficient_secp256r1_ec.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
%builtins range_check

// Source: https://github.com/myBraavos/efficient-secp256r1/blob/73cca4d53730cb8b2dcf34e36c7b8f34b96b3230/src/secp256r1/ec.cairo#L127

from starkware.cairo.common.cairo_secp.bigint import BigInt3, UnreducedBigInt3, nondet_bigint3
from starkware.cairo.common.cairo_secp.ec import EcPoint, compute_doubling_slope
from starkware.cairo.common.cairo_secp.field import (
is_zero,
unreduced_mul,
unreduced_sqr,
verify_zero,
)

// 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

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: felt}() {
let x = BigInt3(235, 522, 111);
let y = BigInt3(1323, 15124, 796759);

let point = EcPoint(x, y);

let (res) = ec_double(point);

assert res = EcPoint(
BigInt3(64960503569511978748964127, 74077005698377320581054215, 17246103581201827820088765),
BigInt3(13476289913106792137931934, 29193128211607101710049068, 18079689234850912663169436),
);

return ();
}
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ impl HintProcessor for BuiltinHintProcessor {
"pt0",
"pt1",
),
hint_code::EC_DOUBLE_ASSIGN_NEW_X => {
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)
}
hint_code::EC_DOUBLE_ASSIGN_NEW_Y => ec_double_assign_new_y(exec_scopes),
Expand Down
10 changes: 9 additions & 1 deletion src/hint_processor/builtin_hint_processor/hint_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,15 @@ x1 = pack(ids.pt1.x, PRIME)
y1 = pack(ids.pt1.y, PRIME)
value = slope = div_mod(y0 - y1, x0 - x1, SECP_P)"#;

pub const EC_DOUBLE_ASSIGN_NEW_X: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
pub const EC_DOUBLE_ASSIGN_NEW_X_V1: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
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_X_V2: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import pack
slope = pack(ids.slope, PRIME)
x = pack(ids.point.x, PRIME)
Expand Down
119 changes: 61 additions & 58 deletions src/hint_processor/builtin_hint_processor/secp/ec_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,64 +504,67 @@ mod tests {
#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn run_ec_double_assign_new_x_ok() {
let hint_code = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\n\nslope = pack(ids.slope, PRIME)\nx = pack(ids.point.x, PRIME)\ny = pack(ids.point.y, PRIME)\n\nvalue = new_x = (pow(slope, 2, SECP_P) - 2 * x) % SECP_P";
let mut vm = vm_with_range_check!();

//Insert ids.point and ids.slope into memory
vm.segments = segments![
((1, 0), 134),
((1, 1), 5123),
((1, 2), 140),
((1, 3), 1232),
((1, 4), 4652),
((1, 5), 720),
((1, 6), 44186171158942157784255469_i128),
((1, 7), 54173758974262696047492534_i128),
((1, 8), 8106299688661572814170174_i128)
];

//Initialize fp
vm.run_context.fp = 10;
let ids_data = HashMap::from([
("point".to_string(), HintReference::new_simple(-10)),
("slope".to_string(), HintReference::new_simple(-4)),
]);
let mut exec_scopes = ExecutionScopes::new();

//Execute the hint
assert_matches!(run_hint!(vm, ids_data, hint_code, &mut exec_scopes), Ok(()));

check_scope!(
&exec_scopes,
[
(
"slope",
bigint_str!(
"48526828616392201132917323266456307435009781900148206102108934970258721901549"
)
),
(
"x",
bigint_str!("838083498911032969414721426845751663479194726707495046")
),
(
"y",
bigint_str!("4310143708685312414132851373791311001152018708061750480")
),
(
"value",
bigint_str!(
"59479631769792988345961122678598249997181612138456851058217178025444564264149"
)
),
(
"new_x",
bigint_str!(
"59479631769792988345961122678598249997181612138456851058217178025444564264149"
)
)
]
);
let hint_codes = vec!["from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\n\nslope = pack(ids.slope, PRIME)\nx = pack(ids.point.x, PRIME)\ny = pack(ids.point.y, PRIME)\n\nvalue = new_x = (pow(slope, 2, SECP_P) - 2 * x) % SECP_P", "from starkware.cairo.common.cairo_secp.secp_utils import pack\n\nslope = pack(ids.slope, PRIME)\nx = pack(ids.point.x, PRIME)\ny = pack(ids.point.y, PRIME)\n\nvalue = new_x = (pow(slope, 2, SECP_P) - 2 * x) % SECP_P"];

for hint_code in hint_codes {
let mut vm = vm_with_range_check!();

//Insert ids.point and ids.slope into memory
vm.segments = segments![
((1, 0), 134),
((1, 1), 5123),
((1, 2), 140),
((1, 3), 1232),
((1, 4), 4652),
((1, 5), 720),
((1, 6), 44186171158942157784255469_i128),
((1, 7), 54173758974262696047492534_i128),
((1, 8), 8106299688661572814170174_i128)
];

//Initialize fp
vm.run_context.fp = 10;
let ids_data = HashMap::from([
("point".to_string(), HintReference::new_simple(-10)),
("slope".to_string(), HintReference::new_simple(-4)),
]);
let mut exec_scopes = ExecutionScopes::new();

//Execute the hint
assert_matches!(run_hint!(vm, ids_data, hint_code, &mut exec_scopes), Ok(()));

check_scope!(
&exec_scopes,
[
(
"slope",
bigint_str!(
"48526828616392201132917323266456307435009781900148206102108934970258721901549"
)
),
(
"x",
bigint_str!("838083498911032969414721426845751663479194726707495046")
),
(
"y",
bigint_str!("4310143708685312414132851373791311001152018708061750480")
),
(
"value",
bigint_str!(
"59479631769792988345961122678598249997181612138456851058217178025444564264149"
)
),
(
"new_x",
bigint_str!(
"59479631769792988345961122678598249997181612138456851058217178025444564264149"
)
)
]
);
}
}

#[test]
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 @@ -1308,3 +1308,10 @@ fn cairo_run_ed25519_ec() {
let program_data = include_bytes!("../../cairo_programs/ed25519_ec.json");
run_program_simple(program_data.as_slice());
}

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

1 comment on commit ddbeb8a

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.30.

Benchmark suite Current: ddbeb8a Previous: 4271436 Ratio
cairo_run(cairo_programs/benchmarks/compare_arrays_200000.json) 3051376722 ns/iter (± 35485875) 2344252332 ns/iter (± 10584452) 1.30
cairo_run(cairo_programs/benchmarks/factorial_multirun.json) 3909951002 ns/iter (± 36814944) 2961651793 ns/iter (± 6297930) 1.32
cairo_run(cairo_programs/benchmarks/integration_builtins.json) 3253451926 ns/iter (± 37280460) 2441449038 ns/iter (± 6411481) 1.33
cairo_run(cairo_programs/benchmarks/linear_search.json) 3207743529 ns/iter (± 36305177) 2448147010 ns/iter (± 12539746) 1.31
cairo_run(cairo_programs/benchmarks/keccak_integration_benchmark.json) 2987059930 ns/iter (± 30073471) 2136215824 ns/iter (± 7491326) 1.40
cairo_run(cairo_programs/benchmarks/secp_integration_benchmark.json) 2842714756 ns/iter (± 30300357) 2049877561 ns/iter (± 6004767) 1.39
cairo_run(cairo_programs/benchmarks/blake2s_integration_benchmark.json) 2777936253 ns/iter (± 31461758) 2009792624 ns/iter (± 6501229) 1.38
cairo_run(cairo_programs/benchmarks/memory_integration_benchmark.json) 2244351927 ns/iter (± 24340545) 1705233848 ns/iter (± 3245078) 1.32
cairo_run(cairo_programs/benchmarks/uint256_integration_benchmark.json) 3892905071 ns/iter (± 63059880) 2950347731 ns/iter (± 6047063) 1.32
cairo_run(cairo_programs/benchmarks/set_integration_benchmark.json) 2448893131 ns/iter (± 34828922) 1582817337 ns/iter (± 17750904) 1.55

This comment was automatically generated by workflow using github-action-benchmark.

CC: @unbalancedparentheses

Please sign in to comment.