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#28 #989

Merged
merged 12 commits into from
Apr 15, 2023
36 changes: 36 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,42 @@
value = slope = div_mod(y0 - y1, x0 - x1, SECP_P)
```

* Add missing hint on cairo_secp lib [#989]:

`BuiltinHintProcessor` now supports the following hint:
```python
from starkware.cairo.common.cairo_secp.secp_utils import SECP_P
q, r = divmod(pack(ids.val, PRIME), SECP_P)
assert r == 0, f"verify_zero: Invalid input {ids.val.d0, ids.val.d1, ids.val.d2}."
ids.q = q % PRIME
```

* 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
66 changes: 66 additions & 0 deletions cairo_programs/ed25519_field.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
%builtins range_check

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

from starkware.cairo.common.cairo_secp.bigint import BASE, BigInt3, UnreducedBigInt3, nondet_bigint3
from starkware.cairo.common.cairo_secp.constants import SECP_REM

// Verifies that the given unreduced value is equal to zero modulo the secp256k1 prime.
// Completeness assumption: val's limbs are in the range (-2**210.99, 2**210.99).
Oppen marked this conversation as resolved.
Show resolved Hide resolved
// Soundness assumption: val's limbs are in the range (-2**250, 2**250).
func verify_zero{range_check_ptr}(val: UnreducedBigInt3) {
let x = val;
// Used just to import pack in scope
%{
from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack

value = pack(ids.x, PRIME) % SECP_P
%}
nondet_bigint3();

let q = [ap];
%{
from starkware.cairo.common.cairo_secp.secp_utils import SECP_P
q, r = divmod(pack(ids.val, PRIME), SECP_P)
assert r == 0, f"verify_zero: Invalid input {ids.val.d0, ids.val.d1, ids.val.d2}."
ids.q = q % PRIME
%}
let q_biased = [ap + 1];
q_biased = q + 2 ** 127, ap++;
[range_check_ptr] = q_biased, ap++;

tempvar r1 = (val.d0 + q * SECP_REM) / BASE;
assert [range_check_ptr + 1] = r1 + 2 ** 127;
// This implies r1 * BASE = val.d0 + q * SECP_REM (as integers).

tempvar r2 = (val.d1 + r1) / BASE;
assert [range_check_ptr + 2] = r2 + 2 ** 127;
// This implies r2 * BASE = val.d1 + r1 (as integers).
// Therefore, r2 * BASE**2 = val.d1 * BASE + r1 * BASE.

assert val.d2 = q * (BASE / 4) - r2;
// This implies q * BASE / 4 = val.d2 + r2 (as integers).
// Therefore,
// q * BASE**3 / 4 = val.d2 * BASE**2 + r2 * BASE ** 2 =
// val.d2 * BASE**2 + val.d1 * BASE + r1 * BASE =
// val.d2 * BASE**2 + val.d1 * BASE + val.d0 + q * SECP_REM =
// val + q * SECP_REM.
// Hence, val = q * (BASE**3 / 4 - SECP_REM) = q * (2**256 - SECP_REM).

let range_check_ptr = range_check_ptr + 3;
return ();
}

func test_verify_zero{range_check_ptr: felt}() {
let val = UnreducedBigInt3(0, 0, 0);

verify_zero(val);

return ();
}

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

return ();
}
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,9 @@ impl HintProcessor for BuiltinHintProcessor {
hint_code::BLAKE2S_COMPUTE => {
compute_blake2s(vm, &hint_data.ids_data, &hint_data.ap_tracking)
}
hint_code::VERIFY_ZERO => verify_zero(vm, &hint_data.ids_data, &hint_data.ap_tracking),
hint_code::VERIFY_ZERO_V1 | hint_code::VERIFY_ZERO_V2 => {
verify_zero(vm, &hint_data.ids_data, &hint_data.ap_tracking)
}
hint_code::NONDET_BIGINT3 => {
nondet_bigint3(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking)
}
Expand Down
7 changes: 6 additions & 1 deletion src/hint_processor/builtin_hint_processor/hint_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,12 +384,17 @@ pub(crate) const NONDET_BIGINT3: &str = r#"from starkware.cairo.common.cairo_sec

segments.write_arg(ids.res.address_, split(value))"#;

pub(crate) const VERIFY_ZERO: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
pub(crate) const VERIFY_ZERO_V1: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack

q, r = divmod(pack(ids.val, PRIME), SECP_P)
assert r == 0, f"verify_zero: Invalid input {ids.val.d0, ids.val.d1, ids.val.d2}."
ids.q = q % PRIME"#;

pub(crate) const VERIFY_ZERO_V2: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P
q, r = divmod(pack(ids.val, PRIME), SECP_P)
assert r == 0, f"verify_zero: Invalid input {ids.val.d0, ids.val.d1, ids.val.d2}."
ids.q = q % PRIME"#;

pub(crate) const REDUCE: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack

value = pack(ids.x, PRIME) % SECP_P"#;
Expand Down
17 changes: 17 additions & 0 deletions src/hint_processor/builtin_hint_processor/secp/field_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,23 @@ mod tests {
check_memory![vm.segments.memory, ((1, 9), 0)];
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn run_verify_zero_without_pack_ok() {
let hint_code = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P\nq, r = divmod(pack(ids.val, PRIME), SECP_P)\nassert r == 0, f\"verify_zero: Invalid input {ids.val.d0, ids.val.d1, ids.val.d2}.\"\nids.q = q % PRIME";
let mut vm = vm_with_range_check!();
//Initialize run_context
run_context!(vm, 0, 9, 9);
//Create hint data
let ids_data = non_continuous_ids_data![("val", -5), ("q", 0)];
vm.segments = segments![((1, 4), 0), ((1, 5), 0), ((1, 6), 0)];
//Execute the hint
assert!(run_hint!(vm, ids_data, hint_code, exec_scopes_ref!()).is_ok());
//Check hint memory inserts
//ids.q
check_memory![vm.segments.memory, ((1, 9), 0)];
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn run_verify_zero_error() {
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 @@ -1295,6 +1295,13 @@ fn cairo_run_uint384() {
run_program_simple(program_data.as_slice());
}

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

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