Skip to content

Commit

Permalink
feat(hints): add NewHint#29 (#986)
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

* Add `EC_DOUBLE_SCOPE_WHITELIST` hint

* Update changelog

* Add missing newline
  • Loading branch information
MegaRedHand authored Apr 15, 2023
1 parent b5ae251 commit 1a89550
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 4 deletions.
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,33 @@

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

* Move `Memory` into `MemorySegmentManager` [#830](/~https://github.com/lambdaclass/cairo-rs/pull/830)
* Structural changes:
* Remove `memory: Memory` field from `VirtualMachine`
Expand Down
48 changes: 48 additions & 0 deletions cairo_programs/ed25519_ec.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,37 @@ struct EcPoint {
y: BigInt3,
}

// Returns the slope of the elliptic curve at the given point.
// The slope is used to compute pt + pt.
// Assumption: pt != 0.
func compute_doubling_slope{range_check_ptr}(pt: EcPoint) -> (slope: BigInt3) {
// Note that y cannot be zero: assume that it is, then pt = -pt, so 2 * pt = 0, which
// contradicts the fact that the size of the curve is odd.
%{
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)
%}
let (slope: BigInt3) = nondet_bigint3();

let (x_sqr: UnreducedBigInt3) = unreduced_sqr(pt.x);
let (slope_y: UnreducedBigInt3) = unreduced_mul(slope, pt.y);

verify_zero(
UnreducedBigInt3(
d0=3 * x_sqr.d0 - 2 * slope_y.d0,
d1=3 * x_sqr.d1 - 2 * slope_y.d1,
d2=3 * x_sqr.d2 - 2 * slope_y.d2,
),
);

return (slope=slope);
}

// 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).
Expand Down Expand Up @@ -49,6 +80,22 @@ func compute_slope{range_check_ptr: felt}(pt0: EcPoint, pt1: EcPoint) -> (slope:
return (slope=slope);
}

func test_compute_double_slope{range_check_ptr: felt}() {
let x = BigInt3(d0=33, d1=24, d2=12412);
let y = BigInt3(d0=3232, d1=122, d2=31415);

let pt = EcPoint(x=x, y=y);

// Compute slope
let (slope) = compute_doubling_slope(pt);

assert slope = BigInt3(
d0=56007611085086895200895667, d1=15076814030975805918069142, d2=6556143173243739984479201
);

return ();
}

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);
Expand All @@ -71,6 +118,7 @@ func test_compute_slope{range_check_ptr: felt}() {
}

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

return ();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,9 +358,20 @@ impl HintProcessor for BuiltinHintProcessor {
hint_code::EC_NEGATE => {
ec_negate(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking)
}
hint_code::EC_DOUBLE_SCOPE => {
compute_doubling_slope(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking)
}
hint_code::EC_DOUBLE_SCOPE => compute_doubling_slope(
vm,
exec_scopes,
&hint_data.ids_data,
&hint_data.ap_tracking,
"point",
),
hint_code::EC_DOUBLE_SCOPE_WHITELIST => compute_doubling_slope(
vm,
exec_scopes,
&hint_data.ids_data,
&hint_data.ap_tracking,
"pt",
),
hint_code::COMPUTE_SLOPE => compute_slope(
vm,
exec_scopes,
Expand Down
8 changes: 8 additions & 0 deletions src/hint_processor/builtin_hint_processor/hint_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,14 @@ x = pack(ids.point.x, PRIME)
y = pack(ids.point.y, PRIME)
value = slope = ec_double_slope(point=(x, y), alpha=0, p=SECP_P)"#;

pub(crate) const EC_DOUBLE_SCOPE_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.
x = pack(ids.pt.x, PRIME)
y = pack(ids.pt.y, PRIME)
value = slope = div_mod(3 * x ** 2, 2 * y, SECP_P)"#;

pub(crate) const COMPUTE_SLOPE: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
from starkware.python.math_utils import line_slope
Expand Down
44 changes: 43 additions & 1 deletion src/hint_processor/builtin_hint_processor/secp/ec_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,10 @@ pub fn compute_doubling_slope(
exec_scopes: &mut ExecutionScopes,
ids_data: &HashMap<String, HintReference>,
ap_tracking: &ApTracking,
point_alias: &str,
) -> Result<(), HintError> {
//ids.point
let point = EcPoint::from_var_name("point", vm, ids_data, ap_tracking)?;
let point = EcPoint::from_var_name(point_alias, vm, ids_data, ap_tracking)?;

let value = ec_double_slope(&(pack(point.x), pack(point.y)), &BigInt::zero(), &SECP_P);
exec_scopes.insert_value("value", value.clone());
Expand Down Expand Up @@ -357,6 +358,47 @@ mod tests {
);
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn run_compute_doubling_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.\nx = pack(ids.pt.x, PRIME)\ny = pack(ids.pt.y, PRIME)\nvalue = slope = div_mod(3 * x ** 2, 2 * y, SECP_P)";
let mut vm = vm_with_range_check!();
vm.segments = segments![
((1, 0), 614323u64),
((1, 1), 5456867u64),
((1, 2), 101208u64),
((1, 3), 773712524u64),
((1, 4), 77371252u64),
((1, 5), 5298795u64)
];

//Initialize fp
vm.run_context.fp = 1;

let ids_data = ids_data!["pt"];
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!(
"40442433062102151071094722250325492738932110061897694430475034100717288403728"
)
),
(
"slope",
bigint_str!(
"40442433062102151071094722250325492738932110061897694430475034100717288403728"
)
)
]
);
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn run_compute_slope_ok() {
Expand Down

0 comments on commit 1a89550

Please sign in to comment.