Skip to content

Commit b5ae251

Browse files
MegaRedHandfmolettaOppen
authored
feat(hints): add NewHint#30 (#984)
* Add `COMPUTE_SLOPE_WHITELIST` hint * Update changelog * Fix: add missing return to cairo program * Separate changelog item and description Co-authored-by: fmoletta <[email protected]> * Format --------- Co-authored-by: fmoletta <[email protected]> Co-authored-by: Mario Rugiero <[email protected]>
1 parent a36797f commit b5ae251

File tree

6 files changed

+180
-5
lines changed

6 files changed

+180
-5
lines changed

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,21 @@
5858
* 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)
5959

6060

61+
* Add missing hint on cairo_secp lib [#984]:
62+
63+
`BuiltinHintProcessor` now supports the following hint:
64+
```python
65+
from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
66+
from starkware.python.math_utils import div_mod
67+
68+
# Compute the slope.
69+
x0 = pack(ids.pt0.x, PRIME)
70+
y0 = pack(ids.pt0.y, PRIME)
71+
x1 = pack(ids.pt1.x, PRIME)
72+
y1 = pack(ids.pt1.y, PRIME)
73+
value = slope = div_mod(y0 - y1, x0 - x1, SECP_P)
74+
```
75+
6176
* Implement hints on uint384 lib (Part 2) [#971](https://github.com/lambdaclass/cairo-rs/pull/971)
6277

6378
`BuiltinHintProcessor` now supports the following hint:

cairo_programs/ed25519_ec.cairo

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
%builtins range_check
2+
3+
// Source: https://github.com/NilFoundation/cairo-ed25519/blob/fee64a1a60b2e07b3b5c20df57f31d7ffcb29ac9/ed25519_ec.cairo
4+
5+
from starkware.cairo.common.serialize import serialize_word
6+
from starkware.cairo.common.cairo_secp.bigint import BigInt3, UnreducedBigInt3, nondet_bigint3
7+
from starkware.cairo.common.cairo_secp.field import (
8+
is_zero,
9+
unreduced_mul,
10+
unreduced_sqr,
11+
verify_zero,
12+
)
13+
14+
// Represents a point on the elliptic curve.
15+
// The zero point is represented using pt.x=0, as there is no point on the curve with this x value.
16+
struct EcPoint {
17+
x: BigInt3,
18+
y: BigInt3,
19+
}
20+
21+
// Returns the slope of the line connecting the two given points.
22+
// The slope is used to compute pt0 + pt1.
23+
// Assumption: pt0.x != pt1.x (mod secp256k1_prime).
24+
func compute_slope{range_check_ptr: felt}(pt0: EcPoint, pt1: EcPoint) -> (slope: BigInt3) {
25+
%{
26+
from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
27+
from starkware.python.math_utils import div_mod
28+
29+
# Compute the slope.
30+
x0 = pack(ids.pt0.x, PRIME)
31+
y0 = pack(ids.pt0.y, PRIME)
32+
x1 = pack(ids.pt1.x, PRIME)
33+
y1 = pack(ids.pt1.y, PRIME)
34+
value = slope = div_mod(y0 - y1, x0 - x1, SECP_P)
35+
%}
36+
let (slope) = nondet_bigint3();
37+
38+
let x_diff = BigInt3(d0=pt0.x.d0 - pt1.x.d0, d1=pt0.x.d1 - pt1.x.d1, d2=pt0.x.d2 - pt1.x.d2);
39+
let (x_diff_slope: UnreducedBigInt3) = unreduced_mul(x_diff, slope);
40+
41+
verify_zero(
42+
UnreducedBigInt3(
43+
d0=x_diff_slope.d0 - pt0.y.d0 + pt1.y.d0,
44+
d1=x_diff_slope.d1 - pt0.y.d1 + pt1.y.d1,
45+
d2=x_diff_slope.d2 - pt0.y.d2 + pt1.y.d2,
46+
),
47+
);
48+
49+
return (slope=slope);
50+
}
51+
52+
func test_compute_slope{range_check_ptr: felt}() {
53+
let x0 = BigInt3(d0=1, d1=5, d2=10);
54+
let y0 = BigInt3(d0=2, d1=4, d2=20);
55+
56+
let pt0 = EcPoint(x=x0, y=y0);
57+
58+
let x1 = BigInt3(d0=3, d1=3, d2=3);
59+
let y1 = BigInt3(d0=3, d1=5, d2=22);
60+
61+
let pt1 = EcPoint(x=x1, y=y1);
62+
63+
// Compute slope
64+
let (slope) = compute_slope(pt0, pt1);
65+
66+
assert slope = BigInt3(
67+
d0=39919528597790922692721903, d1=31451568879578276714332055, d2=6756007504256943629292535
68+
);
69+
70+
return ();
71+
}
72+
73+
func main{range_check_ptr: felt}() {
74+
test_compute_slope();
75+
76+
return ();
77+
}

src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -361,9 +361,22 @@ impl HintProcessor for BuiltinHintProcessor {
361361
hint_code::EC_DOUBLE_SCOPE => {
362362
compute_doubling_slope(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking)
363363
}
364-
hint_code::COMPUTE_SLOPE => {
365-
compute_slope(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking)
366-
}
364+
hint_code::COMPUTE_SLOPE => compute_slope(
365+
vm,
366+
exec_scopes,
367+
&hint_data.ids_data,
368+
&hint_data.ap_tracking,
369+
"point0",
370+
"point1",
371+
),
372+
hint_code::COMPUTE_SLOPE_WHITELIST => compute_slope(
373+
vm,
374+
exec_scopes,
375+
&hint_data.ids_data,
376+
&hint_data.ap_tracking,
377+
"pt0",
378+
"pt1",
379+
),
367380
hint_code::EC_DOUBLE_ASSIGN_NEW_X => {
368381
ec_double_assign_new_x(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking)
369382
}

src/hint_processor/builtin_hint_processor/hint_code.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,16 @@ x1 = pack(ids.point1.x, PRIME)
477477
y1 = pack(ids.point1.y, PRIME)
478478
value = slope = line_slope(point1=(x0, y0), point2=(x1, y1), p=SECP_P)"#;
479479

480+
pub(crate) const COMPUTE_SLOPE_WHITELIST: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
481+
from starkware.python.math_utils import div_mod
482+
483+
# Compute the slope.
484+
x0 = pack(ids.pt0.x, PRIME)
485+
y0 = pack(ids.pt0.y, PRIME)
486+
x1 = pack(ids.pt1.x, PRIME)
487+
y1 = pack(ids.pt1.y, PRIME)
488+
value = slope = div_mod(y0 - y1, x0 - x1, SECP_P)"#;
489+
480490
pub(crate) const EC_DOUBLE_ASSIGN_NEW_X: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
481491
482492
slope = pack(ids.slope, PRIME)

src/hint_processor/builtin_hint_processor/secp/ec_utils.rs

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,13 @@ pub fn compute_slope(
113113
exec_scopes: &mut ExecutionScopes,
114114
ids_data: &HashMap<String, HintReference>,
115115
ap_tracking: &ApTracking,
116+
point0_alias: &str,
117+
point1_alias: &str,
116118
) -> Result<(), HintError> {
117119
//ids.point0
118-
let point0 = EcPoint::from_var_name("point0", vm, ids_data, ap_tracking)?;
120+
let point0 = EcPoint::from_var_name(point0_alias, vm, ids_data, ap_tracking)?;
119121
//ids.point1
120-
let point1 = EcPoint::from_var_name("point1", vm, ids_data, ap_tracking)?;
122+
let point1 = EcPoint::from_var_name(point1_alias, vm, ids_data, ap_tracking)?;
121123

122124
let value = line_slope(
123125
&(pack(point0.x), pack(point0.y)),
@@ -406,6 +408,57 @@ mod tests {
406408
);
407409
}
408410

411+
#[test]
412+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
413+
fn run_compute_slope_wdivmod_ok() {
414+
let hint_code = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\nfrom starkware.python.math_utils import div_mod\n\n# Compute the slope.\nx0 = pack(ids.pt0.x, PRIME)\ny0 = pack(ids.pt0.y, PRIME)\nx1 = pack(ids.pt1.x, PRIME)\ny1 = pack(ids.pt1.y, PRIME)\nvalue = slope = div_mod(y0 - y1, x0 - x1, SECP_P)";
415+
let mut vm = vm_with_range_check!();
416+
417+
// Insert ids.pt0 and ids.pt1 into memory
418+
vm.segments = segments![
419+
((1, 0), 134),
420+
((1, 1), 5123),
421+
((1, 2), 140),
422+
((1, 3), 1232),
423+
((1, 4), 4652),
424+
((1, 5), 720),
425+
((1, 6), 156),
426+
((1, 7), 6545),
427+
((1, 8), 100010),
428+
((1, 9), 1123),
429+
((1, 10), 1325),
430+
((1, 11), 910)
431+
];
432+
433+
// Initialize fp
434+
vm.run_context.fp = 14;
435+
let ids_data = HashMap::from([
436+
("pt0".to_string(), HintReference::new_simple(-14)),
437+
("pt1".to_string(), HintReference::new_simple(-8)),
438+
]);
439+
let mut exec_scopes = ExecutionScopes::new();
440+
441+
// Execute the hint
442+
assert_matches!(run_hint!(vm, ids_data, hint_code, &mut exec_scopes), Ok(()));
443+
check_scope!(
444+
&exec_scopes,
445+
[
446+
(
447+
"value",
448+
bigint_str!(
449+
"41419765295989780131385135514529906223027172305400087935755859001910844026631"
450+
)
451+
),
452+
(
453+
"slope",
454+
bigint_str!(
455+
"41419765295989780131385135514529906223027172305400087935755859001910844026631"
456+
)
457+
)
458+
]
459+
);
460+
}
461+
409462
#[test]
410463
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
411464
fn run_ec_double_assign_new_x_ok() {

src/tests/cairo_run_test.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,3 +1294,10 @@ fn cairo_run_uint384() {
12941294
let program_data = include_bytes!("../../cairo_programs/uint384.json");
12951295
run_program_simple(program_data.as_slice());
12961296
}
1297+
1298+
#[test]
1299+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1300+
fn cairo_run_ed25519_ec() {
1301+
let program_data = include_bytes!("../../cairo_programs/ed25519_ec.json");
1302+
run_program_simple(program_data.as_slice());
1303+
}

0 commit comments

Comments
 (0)