Skip to content

Commit

Permalink
Add NewHint#26
Browse files Browse the repository at this point in the history
  • Loading branch information
MegaRedHand committed Apr 14, 2023
1 parent 741a208 commit 610f170
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 33 deletions.
54 changes: 54 additions & 0 deletions cairo_programs/ed25519_field.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,51 @@ func verify_zero{range_check_ptr}(val: UnreducedBigInt3) {
return ();
}

// Source: https://github.com/myBraavos/efficient-secp256r1/blob/73cca4d53730cb8b2dcf34e36c7b8f34b96b3230/src/secp256r1/ec.cairo#L106
func verify_zero_alt{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 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
%}
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);

Expand All @@ -59,8 +104,17 @@ func test_verify_zero{range_check_ptr: felt}() {
return ();
}

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

verify_zero_alt(val);

return ();
}

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

return ();
}
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ impl HintProcessor for BuiltinHintProcessor {
hint_code::BLAKE2S_COMPUTE => {
compute_blake2s(vm, &hint_data.ids_data, &hint_data.ap_tracking)
}
hint_code::VERIFY_ZERO_V1 | hint_code::VERIFY_ZERO_V2 => {
hint_code::VERIFY_ZERO_V1 | hint_code::VERIFY_ZERO_V2 | hint_code::VERIFY_ZERO_V3 => {
verify_zero(vm, &hint_data.ids_data, &hint_data.ap_tracking)
}
hint_code::NONDET_BIGINT3 => {
Expand Down
6 changes: 6 additions & 0 deletions src/hint_processor/builtin_hint_processor/hint_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,12 @@ 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_V3: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import 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 REDUCE: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
value = pack(ids.x, PRIME) % SECP_P"#;
Expand Down
53 changes: 21 additions & 32 deletions src/hint_processor/builtin_hint_processor/secp/field_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,38 +154,27 @@ mod tests {
#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn run_verify_zero_ok() {
let hint_code = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\n\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_matches!(
run_hint!(vm, ids_data, hint_code, exec_scopes_ref!()),
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_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)];
let hint_codes = vec![
"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\n\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",
"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",
"from starkware.cairo.common.cairo_secp.secp_utils import pack\n\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",
];
for hint_code in hint_codes {
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_matches!(
run_hint!(vm, ids_data, hint_code, exec_scopes_ref!()),
Ok(())
);
//Check hint memory inserts
//ids.q
check_memory![vm.segments.memory, ((1, 9), 0)];
}
}

#[test]
Expand Down

0 comments on commit 610f170

Please sign in to comment.