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

ci: script to keep track of missing hints #1015

Merged
merged 1 commit into from
Apr 21, 2023
Merged
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
1 change: 1 addition & 0 deletions .github/codecov.yml
Original file line number Diff line number Diff line change
@@ -7,4 +7,5 @@ coverage:
ignore:
- src/vm/errors
- src/types/errors
- hint_accountant
- ./deps
28 changes: 28 additions & 0 deletions .github/workflows/hint_accountant.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Update missing hints tracking issue

on:
push:
branches: [ main ]

env:
CARGO_TERM_COLOR: always

jobs:
run:
runs-on: ubuntu-22.04
steps:
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@1.66.1
- name: Set up Cargo cache
uses: Swatinem/rust-cache@v2
- name: Checkout
uses: actions/checkout@v3
- name: Run the hint accounting script
run: cargo r -p hint_accountant | tee comment.md
- name: Update comment in tracking issue
uses: peter-evans/create-or-update-comment@v3
with:
issue-number: 1031
comment-id: 1518234161
body-path: comment.md
edit-mode: replace
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@
**/.DS_Store
**/*.svg
**/*.json
!hint_accountant/whitelists/*.json
!cairo_programs/manually_compiled/*.json
**/*.trace
**/*.memory
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = [".", "felt", "cairo-vm-cli", "./deps/parse-hyperlinks"]
members = [".", "cairo-vm-cli", "felt", "hint_accountant", "./deps/parse-hyperlinks"]

[package]
name = "cairo-vm"
11 changes: 11 additions & 0 deletions hint_accountant/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "hint_accountant"
version = "0.3.0-rc1"
edition = "2021"
license = "Apache-2.0"
description = "A script to check which whitelisted hints we're missing"

[dependencies]
cairo-vm = { path = "..", version = "0.3.0-rc1" }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
90 changes: 90 additions & 0 deletions hint_accountant/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#![deny(warnings)]
#![forbid(unsafe_code)]
use cairo_vm::{
hint_processor::{
builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor,
hint_processor_definition::HintProcessor,
},
serde::deserialize_program::ApTracking,
types::exec_scope::ExecutionScopes,
vm::{errors::hint_errors::HintError, vm_core::VirtualMachine},
with_std::collections::{HashMap, HashSet},
};
use serde::Deserialize;
use serde_json;
use serde_json::Value;

const WHITELISTS: [&'static str; 15] = [
include_str!("../whitelists/0.10.3.json"),
include_str!("../whitelists/0.6.0.json"),
include_str!("../whitelists/0.8.2.json"),
include_str!("../whitelists/384_bit_prime_field.json"),
include_str!("../whitelists/cairo_blake2s.json"),
include_str!("../whitelists/cairo_keccak.json"),
include_str!("../whitelists/cairo_secp.json"),
include_str!("../whitelists/cairo_sha256.json"),
include_str!("../whitelists/cairo_sha256_arbitrary_input_length.json"),
include_str!("../whitelists/ec_bigint.json"),
include_str!("../whitelists/ec_recover.json"),
include_str!("../whitelists/encode_packed.json"),
include_str!("../whitelists/latest.json"),
include_str!("../whitelists/uint256_improvements.json"),
include_str!("../whitelists/vrf.json"),
];

#[derive(Deserialize)]
struct AllowedHintExpression {
#[serde(rename(deserialize = "allowed_expressions"))]
_allowed_expressions: Option<Value>,
hint_lines: Vec<Box<str>>,
}

#[derive(Deserialize)]
struct Whitelist {
#[serde(rename(deserialize = "allowed_reference_expressions_for_hint"))]
allowed_hint_expressions: Vec<AllowedHintExpression>,
}

fn run() {
let mut vm = VirtualMachine::new(false);
let mut hint_executor = BuiltinHintProcessor::new_empty();
let (ap_tracking_data, reference_ids, references, mut exec_scopes, constants) = (
ApTracking::default(),
HashMap::new(),
HashMap::new(),
ExecutionScopes::new(),
HashMap::new(),
);
let missing_hints: HashSet<_> = WHITELISTS
.iter()
.flat_map(|wl| {
serde_json::from_str::<Whitelist>(wl)
.unwrap()
.allowed_hint_expressions
})
.map(|ahe| ahe.hint_lines.join("\n"))
.filter(|h| {
let hint_data = hint_executor
.compile_hint(&h, &ap_tracking_data, &reference_ids, &references)
.expect("this implementation is infallible");
matches!(
hint_executor.execute_hint(&mut vm, &mut exec_scopes, &hint_data, &constants),
Err(HintError::UnknownHint(_)),
)
})
.collect();

println!("{} missing hints:", missing_hints.len());
for hint in missing_hints.iter() {
println!("");
println!("```");
println!("%{{");
println!("{hint}");
println!("%}}");
println!("```");
}
}

fn main() {
run()
}
978 changes: 978 additions & 0 deletions hint_accountant/whitelists/0.10.3.json

Large diffs are not rendered by default.

549 changes: 549 additions & 0 deletions hint_accountant/whitelists/0.6.0.json

Large diffs are not rendered by default.

859 changes: 859 additions & 0 deletions hint_accountant/whitelists/0.8.2.json

Large diffs are not rendered by default.

223 changes: 223 additions & 0 deletions hint_accountant/whitelists/384_bit_prime_field.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
{
"allowed_reference_expressions_for_hint": [
{
"allowed_expressions": [],
"hint_lines": [
"def split(num: int, num_bits_shift: int, length: int):",
" a = []",
" for _ in range(length):",
" a.append( num & ((1 << num_bits_shift) - 1) )",
" num = num >> num_bits_shift",
" return tuple(a)",
"",
"def pack(z, num_bits_shift: int) -> int:",
" limbs = (z.d0, z.d1, z.d2)",
" return sum(limb << (num_bits_shift * i) for i, limb in enumerate(limbs))",
"",
"a = pack(ids.a, num_bits_shift = 128)",
"div = pack(ids.div, num_bits_shift = 128)",
"quotient, remainder = divmod(a, div)",
"",
"quotient_split = split(quotient, num_bits_shift=128, length=3)",
"assert len(quotient_split) == 3",
"",
"ids.quotient.d0 = quotient_split[0]",
"ids.quotient.d1 = quotient_split[1]",
"ids.quotient.d2 = quotient_split[2]",
"",
"remainder_split = split(remainder, num_bits_shift=128, length=3)",
"ids.remainder.d0 = remainder_split[0]",
"ids.remainder.d1 = remainder_split[1]",
"ids.remainder.d2 = remainder_split[2]"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"def split(num: int, num_bits_shift: int, length: int):",
" a = []",
" for _ in range(length):",
" a.append( num & ((1 << num_bits_shift) - 1) )",
" num = num >> num_bits_shift",
" return tuple(a)",
"",
"def pack(z, num_bits_shift: int) -> int:",
" limbs = (z.d0, z.d1, z.d2)",
" return sum(limb << (num_bits_shift * i) for i, limb in enumerate(limbs))",
"",
"a = pack(ids.a, num_bits_shift = 128)",
"b = pack(ids.b, num_bits_shift = 128)",
"p = pack(ids.p, num_bits_shift = 128)",
"",
"res = (a - b) % p",
"",
"",
"res_split = split(res, num_bits_shift=128, length=3)",
"",
"ids.res.d0 = res_split[0]",
"ids.res.d1 = res_split[1]",
"ids.res.d2 = res_split[2]"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.python.math_utils import div_mod",
"",
"def split(num: int, num_bits_shift: int, length: int):",
" a = []",
" for _ in range(length):",
" a.append( num & ((1 << num_bits_shift) - 1) )",
" num = num >> num_bits_shift",
" return tuple(a)",
"",
"def pack(z, num_bits_shift: int) -> int:",
" limbs = (z.d0, z.d1, z.d2)",
" return sum(limb << (num_bits_shift * i) for i, limb in enumerate(limbs))",
"",
"a = pack(ids.a, num_bits_shift = 128)",
"b = pack(ids.b, num_bits_shift = 128)",
"p = pack(ids.p, num_bits_shift = 128)",
"# For python3.8 and above the modular inverse can be computed as follows:",
"# b_inverse_mod_p = pow(b, -1, p)",
"# Instead we use the python3.7-friendly function div_mod from starkware.python.math_utils",
"b_inverse_mod_p = div_mod(1, b, p)",
"",
"",
"b_inverse_mod_p_split = split(b_inverse_mod_p, num_bits_shift=128, length=3)",
"",
"ids.b_inverse_mod_p.d0 = b_inverse_mod_p_split[0]",
"ids.b_inverse_mod_p.d1 = b_inverse_mod_p_split[1]",
"ids.b_inverse_mod_p.d2 = b_inverse_mod_p_split[2]"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"def split(num: int, num_bits_shift: int, length: int):",
" a = []",
" for _ in range(length):",
" a.append( num & ((1 << num_bits_shift) - 1) )",
" num = num >> num_bits_shift ",
" return tuple(a)",
"",
"def pack(z, num_bits_shift: int) -> int:",
" limbs = (z.d0, z.d1, z.d2)",
" return sum(limb << (num_bits_shift * i) for i, limb in enumerate(limbs))",
" ",
"def pack_extended(z, num_bits_shift: int) -> int:",
" limbs = (z.d0, z.d1, z.d2, z.d3, z.d4, z.d5)",
" return sum(limb << (num_bits_shift * i) for i, limb in enumerate(limbs))",
"",
"a = pack_extended(ids.a, num_bits_shift = 128)",
"div = pack(ids.div, num_bits_shift = 128)",
"",
"quotient, remainder = divmod(a, div)",
"",
"quotient_split = split(quotient, num_bits_shift=128, length=6)",
"",
"ids.quotient.d0 = quotient_split[0]",
"ids.quotient.d1 = quotient_split[1]",
"ids.quotient.d2 = quotient_split[2]",
"ids.quotient.d3 = quotient_split[3]",
"ids.quotient.d4 = quotient_split[4]",
"ids.quotient.d5 = quotient_split[5]",
"",
"remainder_split = split(remainder, num_bits_shift=128, length=3)",
"ids.remainder.d0 = remainder_split[0]",
"ids.remainder.d1 = remainder_split[1]",
"ids.remainder.d2 = remainder_split[2]"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.python.math_utils import isqrt",
"",
"def split(num: int, num_bits_shift: int, length: int):",
" a = []",
" for _ in range(length):",
" a.append( num & ((1 << num_bits_shift) - 1) )",
" num = num >> num_bits_shift",
" return tuple(a)",
"",
"def pack(z, num_bits_shift: int) -> int:",
" limbs = (z.d0, z.d1, z.d2)",
" return sum(limb << (num_bits_shift * i) for i, limb in enumerate(limbs))",
"",
"a = pack(ids.a, num_bits_shift=128)",
"root = isqrt(a)",
"assert 0 <= root < 2 ** 192",
"root_split = split(root, num_bits_shift=128, length=3)",
"ids.root.d0 = root_split[0]",
"ids.root.d1 = root_split[1]",
"ids.root.d2 = root_split[2]"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"memory[ap] = 1 if 0 <= (ids.a.d2 % PRIME) < 2 ** 127 else 0"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"sum_d0 = ids.a.d0 + ids.b.d0",
"ids.carry_d0 = 1 if sum_d0 >= ids.SHIFT else 0",
"sum_d1 = ids.a.d1 + ids.b.d1 + ids.carry_d0",
"ids.carry_d1 = 1 if sum_d1 >= ids.SHIFT else 0",
"sum_d2 = ids.a.d2 + ids.b.d2 + ids.carry_d1",
"ids.carry_d2 = 1 if sum_d2 >= ids.SHIFT else 0"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.python.math_utils import is_quad_residue, sqrt",
"",
"def split(num: int, num_bits_shift: int = 128, length: int = 3):",
" a = []",
" for _ in range(length):",
" a.append( num & ((1 << num_bits_shift) - 1) )",
" num = num >> num_bits_shift",
" return tuple(a)",
"",
"def pack(z, num_bits_shift: int = 128) -> int:",
" limbs = (z.d0, z.d1, z.d2)",
" return sum(limb << (num_bits_shift * i) for i, limb in enumerate(limbs))",
"",
"",
"generator = pack(ids.generator)",
"x = pack(ids.x)",
"p = pack(ids.p)",
"",
"success_x = is_quad_residue(x, p)",
"root_x = sqrt(x, p) if success_x else None",
"",
"success_gx = is_quad_residue(generator*x, p)",
"root_gx = sqrt(generator*x, p) if success_gx else None",
"",
"# Check that one is 0 and the other is 1",
"if x != 0:",
" assert success_x + success_gx ==1",
"",
"# `None` means that no root was found, but we need to transform these into a felt no matter what",
"if root_x == None:",
" root_x = 0",
"if root_gx == None:",
" root_gx = 0",
"ids.success_x = int(success_x)",
"ids.success_gx = int(success_gx)",
"split_root_x = split(root_x)",
"split_root_gx = split(root_gx)",
"ids.sqrt_x.d0 = split_root_x[0]",
"ids.sqrt_x.d1 = split_root_x[1]",
"ids.sqrt_x.d2 = split_root_x[2]",
"ids.sqrt_gx.d0 = split_root_gx[0]",
"ids.sqrt_gx.d1 = split_root_gx[1]",
"ids.sqrt_gx.d2 = split_root_gx[2]"
]
}
]
}
134 changes: 134 additions & 0 deletions hint_accountant/whitelists/cairo_blake2s.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
{
"allowed_reference_expressions_for_hint": [
{
"allowed_expressions": [
{
"expr": "[cast(ap + (-2), felt*)]",
"name": "blake2s.finalize_blake2s.__fp__"
},
{
"expr": "[cast(fp + (-5), starkware.cairo.common.cairo_builtins.BitwiseBuiltin**)]",
"name": "blake2s.finalize_blake2s.bitwise_ptr"
},
{
"expr": "[cast(fp + (-3), felt**)]",
"name": "blake2s.finalize_blake2s.blake2s_ptr_end"
},
{
"expr": "[cast(fp + (-4), felt**)]",
"name": "blake2s.finalize_blake2s.blake2s_ptr_start"
},
{
"expr": "[cast(ap + (-1), felt*)]",
"name": "blake2s.finalize_blake2s.n"
},
{
"expr": "[cast(fp + (-6), felt*)]",
"name": "blake2s.finalize_blake2s.range_check_ptr"
},
{
"expr": "[cast(ap + (-1), felt**)]",
"name": "blake2s.finalize_blake2s.sigma"
}
],
"hint_lines": [
"# Add dummy pairs of input and output.",
"from starkware.cairo.common.cairo_blake2s.blake2s_utils import IV, blake2s_compress",
"",
"_n_packed_instances = int(ids.N_PACKED_INSTANCES)",
"assert 0 <= _n_packed_instances < 20",
"_blake2s_input_chunk_size_felts = int(ids.BLAKE2S_INPUT_CHUNK_SIZE_FELTS)",
"assert 0 <= _blake2s_input_chunk_size_felts < 100",
"",
"message = [0] * _blake2s_input_chunk_size_felts",
"modified_iv = [IV[0] ^ 0x01010020] + IV[1:]",
"output = blake2s_compress(",
" message=message,",
" h=modified_iv,",
" t0=0,",
" t1=0,",
" f0=0xffffffff,",
" f1=0,",
")",
"padding = (message + modified_iv + [0, 0xffffffff] + output) * (_n_packed_instances - 1)",
"segments.write_arg(ids.blake2s_ptr_end, padding)"
]
},
{
"allowed_expressions": [
{
"expr": "cast([ap + (-10)] + 10, felt*)",
"name": "blake2s.blake2s.blake2s_ptr"
},
{
"expr": "[cast(fp + (-5), felt**)]",
"name": "blake2s.blake2s.blake2s_start"
},
{
"expr": "[cast(fp + (-4), felt**)]",
"name": "blake2s.blake2s.input"
},
{
"expr": "[cast(fp + (-3), felt*)]",
"name": "blake2s.blake2s.n_bytes"
},
{
"expr": "cast([ap + (-10)] + 10, felt*)",
"name": "blake2s.blake2s.output"
},
{
"expr": "[cast(ap + (-2), felt*)]",
"name": "blake2s.blake2s.range_check_ptr"
}
],
"hint_lines": [
"from starkware.cairo.common.cairo_blake2s.blake2s_utils import IV, blake2s_compress",
"",
"_blake2s_input_chunk_size_felts = int(ids.BLAKE2S_INPUT_CHUNK_SIZE_FELTS)",
"assert 0 <= _blake2s_input_chunk_size_felts < 100",
"",
"new_state = blake2s_compress(",
" message=memory.get_range(ids.blake2s_start, _blake2s_input_chunk_size_felts),",
" h=[IV[0] ^ 0x01010020] + IV[1:],",
" t0=ids.n_bytes,",
" t1=0,",
" f0=0xffffffff,",
" f1=0,",
")",
"",
"segments.write_arg(ids.output, new_state)"
]
},
{
"allowed_expressions": [
{
"expr": "[cast(fp + (-6), felt**)]",
"name": "blake2s._blake2s_input.blake2s_ptr"
},
{
"expr": "[cast(fp, felt*)]",
"name": "blake2s._blake2s_input.full_word"
},
{
"expr": "[cast(fp + (-5), felt**)]",
"name": "blake2s._blake2s_input.input"
},
{
"expr": "[cast(fp + (-4), felt*)]",
"name": "blake2s._blake2s_input.n_bytes"
},
{
"expr": "[cast(fp + (-3), felt*)]",
"name": "blake2s._blake2s_input.n_words"
},
{
"expr": "[cast(fp + (-7), felt*)]",
"name": "blake2s._blake2s_input.range_check_ptr"
}
],
"hint_lines": [
"ids.full_word = int(ids.n_bytes >= 4)"
]
}
]
}
187 changes: 187 additions & 0 deletions hint_accountant/whitelists/cairo_keccak.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
{
"allowed_reference_expressions_for_hint": [
{
"allowed_expressions": [
{
"expr": "[cast(fp + (-5), starkware.cairo.common.cairo_builtins.BitwiseBuiltin**)]",
"name": "keccak.finalize_keccak.bitwise_ptr"
},
{
"expr": "[cast(fp + (-3), felt**)]",
"name": "keccak.finalize_keccak.keccak_ptr_end"
},
{
"expr": "[cast(fp + (-4), felt**)]",
"name": "keccak.finalize_keccak.keccak_ptr_start"
},
{
"expr": "[cast(ap + (-1), felt*)]",
"name": "keccak.finalize_keccak.n"
},
{
"expr": "[cast(fp + (-6), felt*)]",
"name": "keccak.finalize_keccak.range_check_ptr"
}
],
"hint_lines": [
"# Add dummy pairs of input and output.",
"_keccak_state_size_felts = int(ids.KECCAK_STATE_SIZE_FELTS)",
"_block_size = int(ids.BLOCK_SIZE)",
"assert 0 <= _keccak_state_size_felts < 100",
"assert 0 <= _block_size < 1000",
"inp = [0] * _keccak_state_size_felts",
"padding = (inp + keccak_func(inp)) * _block_size",
"segments.write_arg(ids.keccak_ptr_end, padding)"
]
},
{
"allowed_expressions": [
{
"expr": "[cast(fp + (-4), felt**)]",
"name": "keccak.keccak.input"
},
{
"expr": "cast([ap + (-10)] + 9, felt*)",
"name": "keccak.keccak.keccak_ptr"
},
{
"expr": "[cast(fp + (-5), felt**)]",
"name": "keccak.keccak.keccak_ptr_start"
},
{
"expr": "[cast(fp + (-3), felt*)]",
"name": "keccak.keccak.n_bytes"
},
{
"expr": "cast([ap + (-10)] + 9, felt*)",
"name": "keccak.keccak.output"
},
{
"expr": "[cast(ap + (-2), felt*)]",
"name": "keccak.keccak.range_check_ptr"
}
],
"hint_lines": [
"from starkware.cairo.common.cairo_keccak.keccak_utils import keccak_func",
"_keccak_state_size_felts = int(ids.KECCAK_STATE_SIZE_FELTS)",
"assert 0 <= _keccak_state_size_felts < 100",
"output_values = keccak_func(memory.get_range(",
" ids.keccak_ptr_start, _keccak_state_size_felts))",
"segments.write_arg(ids.output, output_values)"
]
},
{
"allowed_expressions": [
{
"expr": "[cast(fp, felt*)]",
"name": "keccak._keccak_input.full_word"
},
{
"expr": "[cast(fp + (-5), felt**)]",
"name": "keccak._keccak_input.input"
},
{
"expr": "[cast(fp + (-6), felt**)]",
"name": "keccak._keccak_input.keccak_ptr"
},
{
"expr": "[cast(fp + (-4), felt*)]",
"name": "keccak._keccak_input.n_bytes"
},
{
"expr": "[cast(fp + (-3), felt*)]",
"name": "keccak._keccak_input.n_words"
},
{
"expr": "[cast(fp + (-7), felt*)]",
"name": "keccak._keccak_input.range_check_ptr"
}
],
"hint_lines": [
"ids.full_word = int(ids.n_bytes >= 8)"
]
},
{
"allowed_expressions": [
{
"expr": "[cast(ap, felt*)]",
"name": "memset.memset.continue_loop"
},
{
"expr": "[cast(fp + (-5), felt**)]",
"name": "memset.memset.dst"
},
{
"expr": "[cast(ap + (-1), memset.memset.LoopFrame*)]",
"name": "memset.memset.frame"
},
{
"expr": "[cast(fp + (-3), felt*)]",
"name": "memset.memset.n"
},
{
"expr": "cast(ap + 1, memset.memset.LoopFrame*)",
"name": "memset.memset.next_frame"
},
{
"expr": "[cast(fp + (-4), felt*)]",
"name": "memset.memset.value"
}
],
"hint_lines": [
"n -= 1",
"ids.continue_loop = 1 if n > 0 else 0"
]
},
{
"allowed_expressions": [
{
"expr": "[cast(fp + (-5), felt**)]",
"name": "memset.memset.dst"
},
{
"expr": "[cast(fp + (-3), felt*)]",
"name": "memset.memset.n"
},
{
"expr": "[cast(fp + (-4), felt*)]",
"name": "memset.memset.value"
}
],
"hint_lines": [
"vm_enter_scope({'n': ids.n})"
]
},
{
"allowed_expressions": [
{
"expr": "[cast(ap, felt*)]",
"name": "memset.memset.continue_loop"
},
{
"expr": "[cast(fp + (-5), felt**)]",
"name": "memset.memset.dst"
},
{
"expr": "[cast(ap + (-1), memset.memset.LoopFrame*)]",
"name": "memset.memset.frame"
},
{
"expr": "[cast(fp + (-3), felt*)]",
"name": "memset.memset.n"
},
{
"expr": "cast(ap + 1, memset.memset.LoopFrame*)",
"name": "memset.memset.next_frame"
},
{
"expr": "[cast(fp + (-4), felt*)]",
"name": "memset.memset.value"
}
],
"hint_lines": [
"vm_exit_scope()"
]
}
]
}
295 changes: 295 additions & 0 deletions hint_accountant/whitelists/cairo_secp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,295 @@
{
"allowed_reference_expressions_for_hint": [
{
"allowed_expressions": [],
"hint_lines": [
"ids.quad_bit = (",
" 8 * ((ids.scalar_v >> ids.m) & 1)",
" + 4 * ((ids.scalar_u >> ids.m) & 1)",
" + 2 * ((ids.scalar_v >> (ids.m - 1)) & 1)",
" + ((ids.scalar_u >> (ids.m - 1)) & 1)",
")"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"ids.len_hi = max(ids.scalar_u.d2.bit_length(), ids.scalar_v.d2.bit_length())-1"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"ids.dibit = ((ids.scalar_u >> ids.m) & 1) + 2 * ((ids.scalar_v >> ids.m) & 1)"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_P as SECP_P"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_ALPHA as ALPHA"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_N as N"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp_utils import pack",
"from starkware.python.math_utils import ec_double_slope",
"",
"# Compute the slope.",
"x = pack(ids.point.x, PRIME)",
"y = pack(ids.point.y, PRIME)",
"value = slope = ec_double_slope(point=(x, y), alpha=ALPHA, p=SECP_P)"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp_utils import pack",
"from starkware.python.math_utils import line_slope",
"",
"# Compute the slope.",
"x0 = pack(ids.point0.x, PRIME)",
"y0 = pack(ids.point0.y, PRIME)",
"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)"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp_utils import pack",
"",
"slope = pack(ids.slope, PRIME)",
"x0 = pack(ids.point0.x, PRIME)",
"x1 = pack(ids.point1.x, PRIME)",
"y0 = pack(ids.point0.y, PRIME)",
"",
"value = new_x = (pow(slope, 2, SECP_P) - x0 - x1) % SECP_P"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp_utils import pack",
"x = pack(ids.x, PRIME) % SECP_P"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.python.math_utils import div_mod",
"",
"value = x_inv = div_mod(1, x, SECP_P)"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp_utils import pack",
"from starkware.python.math_utils import div_mod, safe_div",
"",
"a = pack(ids.a, PRIME)",
"b = pack(ids.b, PRIME)",
"value = res = div_mod(a, b, N)"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"value = k_plus_one = safe_div(res * b - a, N) + 1"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"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"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp_utils import pack",
"",
"slope = pack(ids.slope, PRIME)",
"x = pack(ids.point.x, PRIME)",
"y = pack(ids.point.y, PRIME)",
"",
"value = new_x = (pow(slope, 2, SECP_P) - 2 * x) % SECP_P"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P",
"from starkware.python.math_utils import div_mod",
"",
"value = x_inv = div_mod(1, x, SECP_P)"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"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"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack",
"",
"slope = pack(ids.slope, PRIME)",
"x = pack(ids.pt.x, PRIME)",
"y = pack(ids.pt.y, PRIME)",
"",
"value = new_x = (pow(slope, 2, SECP_P) - 2 * x) % SECP_P"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack",
"",
"slope = pack(ids.slope, PRIME)",
"x0 = pack(ids.pt0.x, PRIME)",
"x1 = pack(ids.pt1.x, PRIME)",
"y0 = pack(ids.pt0.y, PRIME)",
"",
"value = new_x = (pow(slope, 2, SECP_P) - x0 - x1) % SECP_P"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"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)"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"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)"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack",
"x = pack(ids.x, PRIME) % SECP_P"
]
},
{
"allowed_expressions": [
{
"expr": "cast((10428087374290690730508609, 77371252455330678278691517, 19342813113834066795298815), secp_defs.BigInt3)",
"name": "secp.mul_s_inv.n"
}
],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp_utils import pack",
"from starkware.python.math_utils import div_mod, safe_div",
"",
"N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
"x = pack(ids.x, PRIME) % N",
"s = pack(ids.s, PRIME) % N",
"value = res = div_mod(x, s, N)"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp_utils import split",
"segments.write_arg(ids.res.address_, split(value))"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.math_utils import assert_integer",
"assert_integer(ids.a)",
"assert 0 <= ids.a % PRIME < range_check_builtin.bound, f'a = {ids.a} is out of range.'"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.math_utils import assert_integer",
"assert_integer(ids.value)",
"assert ids.value % PRIME != 0, f'assert_not_zero failed: {ids.value} = 0.'"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"memory[ap] = (ids.scalar % PRIME) % 2"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"memory[ap] = int(x == 0)"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"memory[ap] = to_felt_or_relocatable(x == 0)"
]
},
{
"allowed_expressions": [
{
"expr": "cast((10428087374290690730508609, 77371252455330678278691517, 19342813113834066795298815), secp_defs.BigInt3)",
"name": "secp.mul_s_inv.n"
}
],
"hint_lines": [
"value = k = safe_div(res * s - x, N)"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"value = new_y = (slope * (x - new_x) - y) % SECP_P"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"value = new_y = (slope * (x0 - new_x) - y0) % SECP_P"
]
}
]
}
123 changes: 123 additions & 0 deletions hint_accountant/whitelists/cairo_sha256.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
{
"allowed_reference_expressions_for_hint": [
{
"allowed_expressions": [
{
"expr": "[cast(ap + (-2), felt*)]",
"name": "sha256.finalize_sha256.__fp__"
},
{
"expr": "[cast(fp + (-5), starkware.cairo.common.cairo_builtins.BitwiseBuiltin**)]",
"name": "sha256.finalize_sha256.bitwise_ptr"
},
{
"expr": "[cast(ap + (-1), felt*)]",
"name": "sha256.finalize_sha256.n"
},
{
"expr": "[cast(fp + (-6), felt*)]",
"name": "sha256.finalize_sha256.range_check_ptr"
},
{
"expr": "[cast(ap + (-1), felt**)]",
"name": "sha256.finalize_sha256.round_constants"
},
{
"expr": "[cast(fp + (-3), felt**)]",
"name": "sha256.finalize_sha256.sha256_ptr_end"
},
{
"expr": "[cast(fp + (-4), felt**)]",
"name": "sha256.finalize_sha256.sha256_ptr_start"
}
],
"hint_lines": [
"# Add dummy pairs of input and output.",
"from starkware.cairo.common.cairo_sha256.sha256_utils import (",
" IV, compute_message_schedule, sha2_compress_function)",
"",
"_block_size = int(ids.BLOCK_SIZE)",
"assert 0 <= _block_size < 20",
"_sha256_input_chunk_size_felts = int(ids.SHA256_INPUT_CHUNK_SIZE_FELTS)",
"assert 0 <= _sha256_input_chunk_size_felts < 100",
"",
"message = [0] * _sha256_input_chunk_size_felts",
"w = compute_message_schedule(message)",
"output = sha2_compress_function(IV, w)",
"padding = (message + IV + output) * (_block_size - 1)",
"segments.write_arg(ids.sha256_ptr_end, padding)"
]
},
{
"allowed_expressions": [
{
"expr": "[cast(fp + (-4), felt**)]",
"name": "sha256.sha256.input"
},
{
"expr": "[cast(fp + (-3), felt*)]",
"name": "sha256.sha256.n_bytes"
},
{
"expr": "cast([ap + (-11)] + 10, felt*)",
"name": "sha256.sha256.output"
},
{
"expr": "[cast(ap + (-2), felt*)]",
"name": "sha256.sha256.range_check_ptr"
},
{
"expr": "cast([ap + (-11)] + 10, felt*)",
"name": "sha256.sha256.sha256_ptr"
},
{
"expr": "[cast(fp + (-5), felt**)]",
"name": "sha256.sha256.sha256_start"
}
],
"hint_lines": [
"from starkware.cairo.common.cairo_sha256.sha256_utils import (",
" IV, compute_message_schedule, sha2_compress_function)",
"",
"_sha256_input_chunk_size_felts = int(ids.SHA256_INPUT_CHUNK_SIZE_FELTS)",
"assert 0 <= _sha256_input_chunk_size_felts < 100",
"",
"w = compute_message_schedule(memory.get_range(",
" ids.sha256_start, _sha256_input_chunk_size_felts))",
"new_state = sha2_compress_function(IV, w)",
"segments.write_arg(ids.output, new_state)"
]
},
{
"allowed_expressions": [
{
"expr": "[cast(fp, felt*)]",
"name": "sha256._sha256_input.full_word"
},
{
"expr": "[cast(fp + (-5), felt**)]",
"name": "sha256._sha256_input.input"
},
{
"expr": "[cast(fp + (-4), felt*)]",
"name": "sha256._sha256_input.n_bytes"
},
{
"expr": "[cast(fp + (-3), felt*)]",
"name": "sha256._sha256_input.n_words"
},
{
"expr": "[cast(fp + (-7), felt*)]",
"name": "sha256._sha256_input.range_check_ptr"
},
{
"expr": "[cast(fp + (-6), felt**)]",
"name": "sha256._sha256_input.sha256_ptr"
}
],
"hint_lines": [
"ids.full_word = int(ids.n_bytes >= 4)"
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"allowed_reference_expressions_for_hint": [
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_sha256.sha256_utils import (",
" compute_message_schedule, sha2_compress_function)",
"",
"_sha256_input_chunk_size_felts = int(ids.SHA256_INPUT_CHUNK_SIZE_FELTS)",
"assert 0 <= _sha256_input_chunk_size_felts < 100",
"_sha256_state_size_felts = int(ids.SHA256_STATE_SIZE_FELTS)",
"assert 0 <= _sha256_state_size_felts < 100",
"w = compute_message_schedule(memory.get_range(",
" ids.sha256_start, _sha256_input_chunk_size_felts))",
"new_state = sha2_compress_function(memory.get_range(ids.state, _sha256_state_size_felts), w)",
"segments.write_arg(ids.output, new_state)"
]
}
]
}
33 changes: 33 additions & 0 deletions hint_accountant/whitelists/ec_bigint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"allowed_reference_expressions_for_hint": [
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp_utils import pack",
"from starkware.cairo.common.math_utils import as_int",
"from starkware.python.math_utils import div_mod, safe_div",
"",
"p = pack(ids.P, PRIME)",
"x = pack(ids.x, PRIME) + as_int(ids.x.d3, PRIME) * ids.BASE ** 3 + as_int(ids.x.d4, PRIME) * ids.BASE ** 4",
"y = pack(ids.y, PRIME)",
"",
"value = res = div_mod(x, y, p)"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp_utils import split",
"segments.write_arg(ids.res.address_, split(value))"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"k = safe_div(res * y - x, p)",
"value = k if k > 0 else 0 - k",
"ids.flag = 1 if k > 0 else 0"
]
}
]
}
48 changes: 48 additions & 0 deletions hint_accountant/whitelists/ec_recover.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"allowed_reference_expressions_for_hint": [
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp_utils import pack",
"from starkware.python.math_utils import div_mod, safe_div",
"",
"N = pack(ids.n, PRIME)",
"x = pack(ids.x, PRIME) % N",
"s = pack(ids.s, PRIME) % N",
"value = res = div_mod(x, s, N)"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp_utils import pack",
"from starkware.python.math_utils import div_mod, safe_div",
"",
"a = pack(ids.a, PRIME)",
"b = pack(ids.b, PRIME)",
"",
"value = res = a - b"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp_utils import pack",
"from starkware.python.math_utils import div_mod, safe_div",
"",
"a = pack(ids.a, PRIME)",
"b = pack(ids.b, PRIME)",
"product = a * b",
"m = pack(ids.m, PRIME)",
"",
"value = res = product % m"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"value = k = product // m"
]
}
]
}
11 changes: 11 additions & 0 deletions hint_accountant/whitelists/encode_packed.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"allowed_reference_expressions_for_hint": [
{
"allowed_expressions": [],
"hint_lines": [
"x = ids.x",
"ids.bit_length = x.bit_length()"
]
}
]
}
960 changes: 960 additions & 0 deletions hint_accountant/whitelists/latest.json

Large diffs are not rendered by default.

56 changes: 56 additions & 0 deletions hint_accountant/whitelists/uint256_improvements.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"allowed_reference_expressions_for_hint": [
{
"allowed_expressions": [],
"hint_lines": [
"a = (ids.a.high << 128) + ids.a.low",
"div = (ids.div.b23 << 128) + ids.div.b01",
"quotient, remainder = divmod(a, div)",
"",
"ids.quotient.low = quotient & ((1 << 128) - 1)",
"ids.quotient.high = quotient >> 128",
"ids.remainder.low = remainder & ((1 << 128) - 1)",
"ids.remainder.high = remainder >> 128"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"def split(num: int, num_bits_shift: int = 128, length: int = 2):",
" a = []",
" for _ in range(length):",
" a.append( num & ((1 << num_bits_shift) - 1) )",
" num = num >> num_bits_shift",
" return tuple(a)",
"",
"def pack(z, num_bits_shift: int = 128) -> int:",
" limbs = (z.low, z.high)",
" return sum(limb << (num_bits_shift * i) for i, limb in enumerate(limbs))",
"",
"a = pack(ids.a)",
"b = pack(ids.b)",
"res = (a - b)%2**256",
"res_split = split(res)",
"ids.res.low = res_split[0]",
"ids.res.high = res_split[1]"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.python.math_utils import isqrt",
"n = (ids.n.high << 128) + ids.n.low",
"root = isqrt(n)",
"assert 0 <= root < 2 ** 128",
"ids.root = root"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"res = ids.a + ids.b",
"ids.carry = 1 if res >= ids.SHIFT else 0"
]
}
]
}
293 changes: 293 additions & 0 deletions hint_accountant/whitelists/vrf.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,293 @@
{
"allowed_reference_expressions_for_hint": [
{
"allowed_expressions": [],
"hint_lines": [
"PRIME = 2**255 - 19",
"II = pow(2, (PRIME - 1) // 4, PRIME)",
"",
"xx = ids.xx.low + (ids.xx.high<<128)",
"x = pow(xx, (PRIME + 3) // 8, PRIME)",
"if (x * x - xx) % PRIME != 0:",
" x = (x * II) % PRIME",
"if x % 2 != 0:",
" x = PRIME - x",
"ids.x.low = x & ((1<<128)-1)",
"ids.x.high = x >> 128"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"def split(num: int, num_bits_shift: int, length: int):",
" a = []",
" for _ in range(length):",
" a.append( num & ((1 << num_bits_shift) - 1) )",
" num = num >> num_bits_shift",
" return tuple(a)",
"",
"def pack(z, num_bits_shift: int) -> int:",
" limbs = (z.low, z.high)",
" return sum(limb << (num_bits_shift * i) for i, limb in enumerate(limbs))",
"",
"def pack_extended(z, num_bits_shift: int) -> int:",
" limbs = (z.d0, z.d1, z.d2, z.d3)",
" return sum(limb << (num_bits_shift * i) for i, limb in enumerate(limbs))",
"",
"x = pack_extended(ids.x, num_bits_shift = 128)",
"div = pack(ids.div, num_bits_shift = 128)",
"",
"quotient, remainder = divmod(x, div)",
"",
"quotient_split = split(quotient, num_bits_shift=128, length=4)",
"",
"ids.quotient.d0 = quotient_split[0]",
"ids.quotient.d1 = quotient_split[1]",
"ids.quotient.d2 = quotient_split[2]",
"ids.quotient.d3 = quotient_split[3]",
"",
"remainder_split = split(remainder, num_bits_shift=128, length=2)",
"ids.remainder.low = remainder_split[0]",
"ids.remainder.high = remainder_split[1]"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"def pack_512(u, num_bits_shift: int) -> int:",
" limbs = (u.d0, u.d1, u.d2, u.d3)",
" return sum(limb << (num_bits_shift * i) for i, limb in enumerate(limbs))",
"",
"x = pack_512(ids.x, num_bits_shift = 128)",
"p = ids.p.low + (ids.p.high << 128)",
"x_inverse_mod_p = pow(x,-1, p)",
"",
"x_inverse_mod_p_split = (x_inverse_mod_p & ((1 << 128) - 1), x_inverse_mod_p >> 128)",
"",
"ids.x_inverse_mod_p.low = x_inverse_mod_p_split[0]",
"ids.x_inverse_mod_p.high = x_inverse_mod_p_split[1]"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.python.math_utils import div_mod",
"",
"def split(a: int):",
" return (a & ((1 << 128) - 1), a >> 128)",
"",
"def pack(z, num_bits_shift: int) -> int:",
" limbs = (z.low, z.high)",
" return sum(limb << (num_bits_shift * i) for i, limb in enumerate(limbs))",
"",
"a = pack(ids.a, 128)",
"b = pack(ids.b, 128)",
"p = pack(ids.p, 128)",
"# For python3.8 and above the modular inverse can be computed as follows:",
"# b_inverse_mod_p = pow(b, -1, p)",
"# Instead we use the python3.7-friendly function div_mod from starkware.python.math_utils",
"b_inverse_mod_p = div_mod(1, b, p)",
"",
"b_inverse_mod_p_split = split(b_inverse_mod_p)",
"",
"ids.b_inverse_mod_p.low = b_inverse_mod_p_split[0]",
"ids.b_inverse_mod_p.high = b_inverse_mod_p_split[1]"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.python.math_utils import is_quad_residue, sqrt",
"",
"def split(a: int):",
" return (a & ((1 << 128) - 1), a >> 128)",
"",
"def pack(z) -> int:",
" return z.low + (z.high << 128)",
"",
"generator = pack(ids.generator)",
"x = pack(ids.x)",
"p = pack(ids.p)",
"",
"success_x = is_quad_residue(x, p)",
"root_x = sqrt(x, p) if success_x else None",
"success_gx = is_quad_residue(generator*x, p)",
"root_gx = sqrt(generator*x, p) if success_gx else None",
"",
"# Check that one is 0 and the other is 1",
"if x != 0:",
" assert success_x + success_gx == 1",
"",
"# `None` means that no root was found, but we need to transform these into a felt no matter what",
"if root_x == None:",
" root_x = 0",
"if root_gx == None:",
" root_gx = 0",
"ids.success_x = int(success_x)",
"ids.success_gx = int(success_gx)",
"split_root_x = split(root_x)",
"# print('split root x', split_root_x)",
"split_root_gx = split(root_gx)",
"ids.sqrt_x.low = split_root_x[0]",
"ids.sqrt_x.high = split_root_x[1]",
"ids.sqrt_gx.low = split_root_gx[0]",
"ids.sqrt_gx.high = split_root_gx[1]"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"def split(num: int, num_bits_shift: int, length: int):",
" a = []",
" for _ in range(length):",
" a.append( num & ((1 << num_bits_shift) - 1) )",
" num = num >> num_bits_shift",
" return tuple(a)",
"",
"def pack(z, num_bits_shift: int) -> int:",
" limbs = (z.d0, z.d1, z.d2)",
" return sum(limb << (num_bits_shift * i) for i, limb in enumerate(limbs))",
"",
"def pack_extended(z, num_bits_shift: int) -> int:",
" limbs = (z.d0, z.d1, z.d2, z.d3, z.d4, z.d5)",
" return sum(limb << (num_bits_shift * i) for i, limb in enumerate(limbs))",
"",
"a = pack_extended(ids.a, num_bits_shift = 128)",
"div = pack(ids.div, num_bits_shift = 128)",
"",
"quotient, remainder = divmod(a, div)",
"",
"quotient_split = split(quotient, num_bits_shift=128, length=6)",
"",
"ids.quotient.d0 = quotient_split[0]",
"ids.quotient.d1 = quotient_split[1]",
"ids.quotient.d2 = quotient_split[2]",
"ids.quotient.d3 = quotient_split[3]",
"ids.quotient.d4 = quotient_split[4]",
"ids.quotient.d5 = quotient_split[5]",
"",
"remainder_split = split(remainder, num_bits_shift=128, length=3)",
"ids.remainder.d0 = remainder_split[0]",
"ids.remainder.d1 = remainder_split[1]",
"ids.remainder.d2 = remainder_split[2]"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"ids.low = ids.a & ((1<<128) - 1)",
"ids.high = ids.a >> 128"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"sum_low = ids.a.low + ids.b.low",
"ids.carry_low = 1 if sum_low >= ids.SHIFT else 0"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp_utils import pack",
"SECP_P = 2**255-19",
"to_assert = pack(ids.val, PRIME)",
"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"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp_utils import pack",
"SECP_P=2**255-19",
"",
"x = pack(ids.x, PRIME) % SECP_P"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp_utils import pack",
"SECP_P=2**255-19",
"",
"value = pack(ids.x, PRIME) % SECP_P"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"SECP_P=2**255-19",
"from starkware.python.math_utils import div_mod",
"",
"value = x_inv = div_mod(1, x, SECP_P)"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp_utils import pack",
"SECP_P = 2**255-19",
"",
"y = pack(ids.point.y, PRIME) % SECP_P",
"# The modulo operation in python always returns a nonnegative number.",
"value = (-y) % SECP_P"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp_utils import pack",
"SECP_P = 2**255-19",
"",
"slope = pack(ids.slope, PRIME)",
"x = pack(ids.point.x, PRIME)",
"y = pack(ids.point.y, PRIME)",
"",
"value = new_x = (pow(slope, 2, SECP_P) - 2 * x) % SECP_P"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.cairo.common.cairo_secp.secp_utils import pack",
"SECP_P = 2**255-19",
"",
"slope = pack(ids.slope, PRIME)",
"x0 = pack(ids.point0.x, PRIME)",
"x1 = pack(ids.point1.x, PRIME)",
"y0 = pack(ids.point0.y, PRIME)",
"",
"value = new_x = (pow(slope, 2, SECP_P) - x0 - x1) % SECP_P"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.python.math_utils import ec_double_slope",
"from starkware.cairo.common.cairo_secp.secp_utils import pack",
"SECP_P = 2**255-19",
"",
"# Compute the slope.",
"x = pack(ids.point.x, PRIME)",
"y = pack(ids.point.y, PRIME)",
"value = slope = ec_double_slope(point=(x, y), alpha=42204101795669822316448953119945047945709099015225996174933988943478124189485, p=SECP_P)"
]
},
{
"allowed_expressions": [],
"hint_lines": [
"from starkware.python.math_utils import line_slope",
"from starkware.cairo.common.cairo_secp.secp_utils import pack",
"SECP_P = 2**255-19",
"# Compute the slope.",
"x0 = pack(ids.point0.x, PRIME)",
"y0 = pack(ids.point0.y, PRIME)",
"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)"
]
}
]
}