Skip to content

Commit

Permalink
feat(hints): add NewHint#30 (lambdaclass#984)
Browse files Browse the repository at this point in the history
* Add `COMPUTE_SLOPE_WHITELIST` hint

* Update changelog

* Fix: add missing return to cairo program

* Separate changelog item and description

Co-authored-by: fmoletta <99273364+fmoletta@users.noreply.github.com>

* Format

---------

Co-authored-by: fmoletta <99273364+fmoletta@users.noreply.github.com>
Co-authored-by: Mario Rugiero <mario.rugiero@lambdaclass.com>
  • Loading branch information
3 people authored and kariy committed Jun 23, 2023
1 parent b47f081 commit e01a9ed
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 5 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,21 @@
* 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
77 changes: 77 additions & 0 deletions cairo_programs/ed25519_ec.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
%builtins range_check

// Source: https://github.com/NilFoundation/cairo-ed25519/blob/fee64a1a60b2e07b3b5c20df57f31d7ffcb29ac9/ed25519_ec.cairo

from starkware.cairo.common.serialize import serialize_word
from starkware.cairo.common.cairo_secp.bigint import BigInt3, UnreducedBigInt3, nondet_bigint3
from starkware.cairo.common.cairo_secp.field import (
is_zero,
unreduced_mul,
unreduced_sqr,
verify_zero,
)

// Represents a point on the elliptic curve.
// The zero point is represented using pt.x=0, as there is no point on the curve with this x value.
struct EcPoint {
x: BigInt3,
y: BigInt3,
}

// Returns the slope of the line connecting the two given points.
// The slope is used to compute pt0 + pt1.
// Assumption: pt0.x != pt1.x (mod secp256k1_prime).
func compute_slope{range_check_ptr: felt}(pt0: EcPoint, pt1: EcPoint) -> (slope: BigInt3) {
%{
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)
%}
let (slope) = nondet_bigint3();

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);
let (x_diff_slope: UnreducedBigInt3) = unreduced_mul(x_diff, slope);

verify_zero(
UnreducedBigInt3(
d0=x_diff_slope.d0 - pt0.y.d0 + pt1.y.d0,
d1=x_diff_slope.d1 - pt0.y.d1 + pt1.y.d1,
d2=x_diff_slope.d2 - pt0.y.d2 + pt1.y.d2,
),
);

return (slope=slope);
}

func test_compute_slope{range_check_ptr: felt}() {
let x0 = BigInt3(d0=1, d1=5, d2=10);
let y0 = BigInt3(d0=2, d1=4, d2=20);

let pt0 = EcPoint(x=x0, y=y0);

let x1 = BigInt3(d0=3, d1=3, d2=3);
let y1 = BigInt3(d0=3, d1=5, d2=22);

let pt1 = EcPoint(x=x1, y=y1);

// Compute slope
let (slope) = compute_slope(pt0, pt1);

assert slope = BigInt3(
d0=39919528597790922692721903, d1=31451568879578276714332055, d2=6756007504256943629292535
);

return ();
}

func main{range_check_ptr: felt}() {
test_compute_slope();

return ();
}
Original file line number Diff line number Diff line change
Expand Up @@ -361,9 +361,22 @@ impl HintProcessor for BuiltinHintProcessor {
hint_code::EC_DOUBLE_SCOPE => {
compute_doubling_slope(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking)
}
hint_code::COMPUTE_SLOPE => {
compute_slope(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking)
}
hint_code::COMPUTE_SLOPE => compute_slope(
vm,
exec_scopes,
&hint_data.ids_data,
&hint_data.ap_tracking,
"point0",
"point1",
),
hint_code::COMPUTE_SLOPE_WHITELIST => compute_slope(
vm,
exec_scopes,
&hint_data.ids_data,
&hint_data.ap_tracking,
"pt0",
"pt1",
),
hint_code::EC_DOUBLE_ASSIGN_NEW_X => {
ec_double_assign_new_x(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking)
}
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 @@ -477,6 +477,16 @@ x1 = pack(ids.point1.x, PRIME)
y1 = pack(ids.point1.y, PRIME)
value = slope = line_slope(point1=(x0, y0), point2=(x1, y1), p=SECP_P)"#;

pub(crate) const COMPUTE_SLOPE_WHITELIST: &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.
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)"#;

pub(crate) const EC_DOUBLE_ASSIGN_NEW_X: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
slope = pack(ids.slope, PRIME)
Expand Down
57 changes: 55 additions & 2 deletions src/hint_processor/builtin_hint_processor/secp/ec_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,13 @@ pub fn compute_slope(
exec_scopes: &mut ExecutionScopes,
ids_data: &HashMap<String, HintReference>,
ap_tracking: &ApTracking,
point0_alias: &str,
point1_alias: &str,
) -> Result<(), HintError> {
//ids.point0
let point0 = EcPoint::from_var_name("point0", vm, ids_data, ap_tracking)?;
let point0 = EcPoint::from_var_name(point0_alias, vm, ids_data, ap_tracking)?;
//ids.point1
let point1 = EcPoint::from_var_name("point1", vm, ids_data, ap_tracking)?;
let point1 = EcPoint::from_var_name(point1_alias, vm, ids_data, ap_tracking)?;

let value = line_slope(
&(pack(point0.x), pack(point0.y)),
Expand Down Expand Up @@ -406,6 +408,57 @@ mod tests {
);
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn run_compute_slope_wdivmod_ok() {
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)";
let mut vm = vm_with_range_check!();

// Insert ids.pt0 and ids.pt1 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), 156),
((1, 7), 6545),
((1, 8), 100010),
((1, 9), 1123),
((1, 10), 1325),
((1, 11), 910)
];

// Initialize fp
vm.run_context.fp = 14;
let ids_data = HashMap::from([
("pt0".to_string(), HintReference::new_simple(-14)),
("pt1".to_string(), HintReference::new_simple(-8)),
]);
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,
[
(
"value",
bigint_str!(
"41419765295989780131385135514529906223027172305400087935755859001910844026631"
)
),
(
"slope",
bigint_str!(
"41419765295989780131385135514529906223027172305400087935755859001910844026631"
)
)
]
);
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn run_ec_double_assign_new_x_ok() {
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 @@ -1294,3 +1294,10 @@ fn cairo_run_uint384() {
let program_data = include_bytes!("../../cairo_programs/uint384.json");
run_program_simple(program_data.as_slice());
}

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

0 comments on commit e01a9ed

Please sign in to comment.