Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(hints): add NewHint#30 #984

Merged
merged 9 commits into from
Apr 14, 2023
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());
}