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#29 #986

Merged
merged 7 commits into from
Apr 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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