Skip to content

Commit

Permalink
Add new keccak hints + update import paths (#883)
Browse files Browse the repository at this point in the history
* Add cache to keccak builtin

* Temporaryly unhide recursive layout for debugging

* Use same keccak method as the one used in keccak_utils

* Make keccak builtin work

* Fix visisbility

* Small refactor

* Refactor

* Refactor

* Add tests

* Fix address management

* Add test program

* Clippy + Update tests

* Remove unused import

* Remove uneeded Rc

* Make error less specific

* Add integration test

* Add proposed changes

* Add new hints

* Add test program

* Move constants

* Add keccak hints;

* Fix overflowing operation

* Add more hints

* Add unit tests

* Add integration test

* Update import paths in cairo programs used for testing

* Update hints with new import paths

* Add newline at end of file

* Clippy

* Clean imports

* Re-hide recursive layout

* Update src/hint_processor/builtin_hint_processor/keccak_utils.rs

Co-authored-by: Mario Rugiero <mario.rugiero@lambdaclass.com>

* Add suggested change + fix conflicts

* Update src/hint_processor/builtin_hint_processor/keccak_utils.rs

Co-authored-by: Mario Rugiero <mario.rugiero@lambdaclass.com>

* Fix

* Use u64 in split_n_bytes hints

* Use starknet_with_keccak layout when running cairo-lang

* Fix relative path in compare_vm_state script

---------

Co-authored-by: Mario Rugiero <mario.rugiero@lambdaclass.com>
  • Loading branch information
fmoletta and Oppen committed Mar 15, 2023
1 parent 110395c commit 637b733
Show file tree
Hide file tree
Showing 15 changed files with 432 additions and 118 deletions.
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ $(TEST_PROOF_DIR)/%.json: $(TEST_PROOF_DIR)/%.cairo
cairo-compile --cairo_path="$(TEST_PROOF_DIR):$(PROOF_BENCH_DIR)" $< --output $@ --proof_mode

$(TEST_PROOF_DIR)/%.rs.trace $(TEST_PROOF_DIR)/%.rs.memory: $(TEST_PROOF_DIR)/%.json $(RELBIN)
cargo llvm-cov run -p cairo-vm-cli --release --no-report -- --layout all --proof_mode $< --trace_file $@ --memory_file $(@D)/$(*F).rs.memory
cargo llvm-cov run -p cairo-vm-cli --release --no-report -- --layout all_cairo --proof_mode $< --trace_file $@ --memory_file $(@D)/$(*F).rs.memory

$(TEST_PROOF_DIR)/%.trace $(TEST_PROOF_DIR)/%.memory: $(TEST_PROOF_DIR)/%.json
cairo-run --layout all_cairo --proof_mode --program $< --trace_file $@ --memory_file $(@D)/$(*F).memory
cairo-run --layout starknet_with_keccak --proof_mode --program $< --trace_file $@ --memory_file $(@D)/$(*F).memory

$(PROOF_BENCH_DIR)/%.json: $(PROOF_BENCH_DIR)/%.cairo
cairo-compile --cairo_path="$(TEST_PROOF_DIR):$(PROOF_BENCH_DIR)" $< --output $@ --proof_mode
Expand Down Expand Up @@ -68,10 +68,10 @@ $(TEST_DIR)/%.json: $(TEST_DIR)/%.cairo
cairo-compile --cairo_path="$(TEST_DIR):$(BENCH_DIR)" $< --output $@

$(TEST_DIR)/%.rs.trace $(TEST_DIR)/%.rs.memory: $(TEST_DIR)/%.json $(RELBIN)
cargo llvm-cov run -p cairo-vm-cli --release --no-report -- --layout all $< --trace_file $@ --memory_file $(@D)/$(*F).rs.memory
cargo llvm-cov run -p cairo-vm-cli --release --no-report -- --layout all_cairo $< --trace_file $@ --memory_file $(@D)/$(*F).rs.memory

$(TEST_DIR)/%.trace $(TEST_DIR)/%.memory: $(TEST_DIR)/%.json
cairo-run --layout all_cairo --program $< --trace_file $@ --memory_file $(@D)/$(*F).memory
cairo-run --layout starknet_with_keccak --program $< --trace_file $@ --memory_file $(@D)/$(*F).memory

$(BENCH_DIR)/%.json: $(BENCH_DIR)/%.cairo
cairo-compile --cairo_path="$(TEST_DIR):$(BENCH_DIR)" $< --output $@
Expand Down
4 changes: 2 additions & 2 deletions cairo_programs/cairo_finalize_keccak.cairo
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
%builtins range_check bitwise

from starkware.cairo.common.cairo_keccak.keccak import keccak, finalize_keccak
from starkware.cairo.common.cairo_keccak.keccak import cairo_keccak, finalize_keccak
from starkware.cairo.common.uint256 import Uint256
from starkware.cairo.common.cairo_builtins import BitwiseBuiltin
from starkware.cairo.common.alloc import alloc
Expand All @@ -18,7 +18,7 @@ func main{range_check_ptr: felt, bitwise_ptr: BitwiseBuiltin*}() {

let n_bytes = 16;

let (res: Uint256) = keccak{keccak_ptr=keccak_ptr}(inputs=inputs, n_bytes=n_bytes);
let (res: Uint256) = cairo_keccak{keccak_ptr=keccak_ptr}(inputs=inputs, n_bytes=n_bytes);

assert res.low = 293431514620200399776069983710520819074;
assert res.high = 317109767021952548743448767588473366791;
Expand Down
2 changes: 1 addition & 1 deletion cairo_programs/keccak_add_uint256.cairo
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
%builtins output range_check bitwise

from starkware.cairo.common.cairo_keccak.keccak import keccak_add_uint256
from starkware.cairo.common.keccak_utils.keccak_utils import keccak_add_uint256
from starkware.cairo.common.uint256 import Uint256
from starkware.cairo.common.cairo_builtins import BitwiseBuiltin
from starkware.cairo.common.alloc import alloc
Expand Down
5 changes: 3 additions & 2 deletions cairo_programs/keccak_integration_tests.cairo
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
%builtins range_check bitwise

from starkware.cairo.common.keccak import unsafe_keccak, unsafe_keccak_finalize, KeccakState
from starkware.cairo.common.cairo_keccak.keccak import keccak_add_uint256, keccak, finalize_keccak
from starkware.cairo.common.cairo_keccak.keccak import cairo_keccak, finalize_keccak
from starkware.cairo.common.keccak_utils.keccak_utils import keccak_add_uint256
from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.uint256 import Uint256
from starkware.cairo.common.cairo_builtins import BitwiseBuiltin
Expand Down Expand Up @@ -56,7 +57,7 @@ func test_integration{range_check_ptr: felt, bitwise_ptr: BitwiseBuiltin*}(iter:
let (keccak_ptr: felt*) = alloc();
let keccak_ptr_start = keccak_ptr;

let res_2: Uint256 = keccak{keccak_ptr=keccak_ptr}(data_3, 16);
let res_2: Uint256 = cairo_keccak{keccak_ptr=keccak_ptr}(data_3, 16);

finalize_keccak(keccak_ptr_start=keccak_ptr_start, keccak_ptr_end=keccak_ptr);

Expand Down
19 changes: 19 additions & 0 deletions cairo_programs/keccak_uint256.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
%builtins range_check bitwise keccak
from starkware.cairo.common.cairo_builtins import KeccakBuiltin, BitwiseBuiltin
from starkware.cairo.common.builtin_keccak.keccak import keccak_uint256s
from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.uint256 import Uint256

func main{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, keccak_ptr: KeccakBuiltin*}() {
let elements: Uint256* = alloc();
assert elements[0] = Uint256(713458135386519, 18359173571);
assert elements[1] = Uint256(1536741637546373185, 84357893467438914);
assert elements[2] = Uint256(2842949328439284983294, 39248298942938492384);
assert elements[3] = Uint256(27518568234293478923754395731931, 981587843715983274);
assert elements[4] = Uint256(326848123647324823482, 93453458349589345);
let (res) = keccak_uint256s(5, elements);
assert res.high = 23012215180764429403047187376747988760;
assert res.low = 13431206634823648732212765105043225161;

return ();
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ use crate::{
},
find_element_hint::{find_element, search_sorted_lower},
hint_code,
keccak_utils::{unsafe_keccak, unsafe_keccak_finalize},
keccak_utils::{
split_input, split_n_bytes, split_output, split_output_mid_low_high, unsafe_keccak,
unsafe_keccak_finalize,
},
math_utils::*,
memcpy_hint_utils::{
add_segment, enter_scope, exit_scope, memcpy_continue_copying, memcpy_enter_scope,
Expand Down Expand Up @@ -136,7 +139,6 @@ impl HintProcessor for BuiltinHintProcessor {
constants,
);
}

match &*hint_data.code {
hint_code::ADD_SEGMENT => add_segment(vm),
hint_code::IS_NN => is_nn(vm, &hint_data.ids_data, &hint_data.ap_tracking),
Expand Down Expand Up @@ -439,6 +441,33 @@ impl HintProcessor for BuiltinHintProcessor {
hint_code::VERIFY_ECDSA_SIGNATURE => {
verify_ecdsa_signature(vm, &hint_data.ids_data, &hint_data.ap_tracking)
}
hint_code::SPLIT_OUTPUT_0 => {
split_output(vm, &hint_data.ids_data, &hint_data.ap_tracking, 0)
}
hint_code::SPLIT_OUTPUT_1 => {
split_output(vm, &hint_data.ids_data, &hint_data.ap_tracking, 1)
}
hint_code::SPLIT_INPUT_3 => {
split_input(vm, &hint_data.ids_data, &hint_data.ap_tracking, 3, 1)
}
hint_code::SPLIT_INPUT_6 => {
split_input(vm, &hint_data.ids_data, &hint_data.ap_tracking, 6, 2)
}
hint_code::SPLIT_INPUT_9 => {
split_input(vm, &hint_data.ids_data, &hint_data.ap_tracking, 9, 3)
}
hint_code::SPLIT_INPUT_12 => {
split_input(vm, &hint_data.ids_data, &hint_data.ap_tracking, 12, 4)
}
hint_code::SPLIT_INPUT_15 => {
split_input(vm, &hint_data.ids_data, &hint_data.ap_tracking, 15, 5)
}
hint_code::SPLIT_N_BYTES => {
split_n_bytes(vm, &hint_data.ids_data, &hint_data.ap_tracking, constants)
}
hint_code::SPLIT_OUTPUT_MID_LOW_HIGH => {
split_output_mid_low_high(vm, &hint_data.ids_data, &hint_data.ap_tracking)
}
hint_code::NONDET_N_GREATER_THAN_10 => {
n_greater_than_10(vm, &hint_data.ids_data, &hint_data.ap_tracking)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,13 @@ use num_traits::{ToPrimitive, Zero};

// Constants in package "starkware.cairo.common.cairo_keccak.keccak".
const BYTES_IN_WORD: &str = "starkware.cairo.common.cairo_keccak.keccak.BYTES_IN_WORD";
const KECCAK_FULL_RATE_IN_BYTES: &str =
const KECCAK_FULL_RATE_IN_BYTES_CAIRO_KECCAK: &str =
"starkware.cairo.common.cairo_keccak.keccak.KECCAK_FULL_RATE_IN_BYTES";
const KECCAK_FULL_RATE_IN_BYTES_BUILTIN_KECCAK: &str =
"starkware.cairo.common.builtin_keccak.keccak.KECCAK_FULL_RATE_IN_BYTES";

const KECCAK_FULL_RATE_IN_BYTES: &str = "KECCAK_FULL_RATE_IN_BYTES";

const KECCAK_STATE_SIZE_FELTS: &str =
"starkware.cairo.common.cairo_keccak.keccak.KECCAK_STATE_SIZE_FELTS";

Expand Down Expand Up @@ -110,7 +115,8 @@ pub fn compare_keccak_full_rate_in_bytes_nondet(
let n_bytes = n_bytes.as_ref();

let keccak_full_rate_in_bytes = constants
.get(KECCAK_FULL_RATE_IN_BYTES)
.get(KECCAK_FULL_RATE_IN_BYTES_CAIRO_KECCAK)
.or_else(|| constants.get(KECCAK_FULL_RATE_IN_BYTES_BUILTIN_KECCAK))
.ok_or(HintError::MissingConstant(KECCAK_FULL_RATE_IN_BYTES))?;
let value = Felt::new((n_bytes >= keccak_full_rate_in_bytes) as usize);
insert_value_into_ap(vm, value)
Expand Down Expand Up @@ -328,7 +334,7 @@ mod tests {
ids_data,
hint_code,
exec_scopes_ref!(),
&[(KECCAK_FULL_RATE_IN_BYTES, Felt::new(136))]
&[(KECCAK_FULL_RATE_IN_BYTES_CAIRO_KECCAK, Felt::new(136))]
.into_iter()
.map(|(k, v)| (k.to_string(), v))
.collect()
Expand Down Expand Up @@ -357,7 +363,7 @@ mod tests {
ids_data,
hint_code,
exec_scopes_ref!(),
&[(KECCAK_FULL_RATE_IN_BYTES, Felt::new(136))]
&[(KECCAK_FULL_RATE_IN_BYTES_CAIRO_KECCAK, Felt::new(136))]
.into_iter()
.map(|(k, v)| (k.to_string(), v))
.collect()
Expand Down Expand Up @@ -385,7 +391,7 @@ mod tests {
ids_data,
hint_code,
exec_scopes_ref!(),
&[(KECCAK_FULL_RATE_IN_BYTES, Felt::new(136))]
&[(KECCAK_FULL_RATE_IN_BYTES_CAIRO_KECCAK, Felt::new(136))]
.into_iter()
.map(|(k, v)| (k.to_string(), v))
.collect()
Expand Down
23 changes: 22 additions & 1 deletion src/hint_processor/builtin_hint_processor/hint_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ pub(crate) const COMPARE_BYTES_IN_WORD_NONDET: &str =
pub(crate) const COMPARE_KECCAK_FULL_RATE_IN_BYTES_NONDET: &str =
r#"memory[ap] = to_felt_or_relocatable(ids.n_bytes >= ids.KECCAK_FULL_RATE_IN_BYTES)"#;

pub(crate) const BLOCK_PERMUTATION: &str = r#"from starkware.cairo.common.cairo_keccak.keccak_utils import keccak_func
pub(crate) const BLOCK_PERMUTATION: &str = r#"from starkware.cairo.common.keccak_utils.keccak_utils import keccak_func
_keccak_state_size_felts = int(ids.KECCAK_STATE_SIZE_FELTS)
assert 0 <= _keccak_state_size_felts < 100
Expand Down Expand Up @@ -542,6 +542,27 @@ pub(crate) const TEMPORARY_ARRAY: &str = r#"ids.temporary_array = segments.add_t
pub(crate) const VERIFY_ECDSA_SIGNATURE: &str =
r#"ecdsa_builtin.add_signature(ids.ecdsa_ptr.address_, (ids.signature_r, ids.signature_s))"#;

pub(crate) const SPLIT_OUTPUT_0: &str = "ids.output0_low = ids.output0 & ((1 << 128) - 1)
ids.output0_high = ids.output0 >> 128";
pub(crate) const SPLIT_OUTPUT_1: &str = "ids.output1_low = ids.output1 & ((1 << 128) - 1)
ids.output1_high = ids.output1 >> 128";

pub(crate) const SPLIT_INPUT_3: &str = "ids.high3, ids.low3 = divmod(memory[ids.inputs + 3], 256)";
pub(crate) const SPLIT_INPUT_6: &str =
"ids.high6, ids.low6 = divmod(memory[ids.inputs + 6], 256 ** 2)";
pub(crate) const SPLIT_INPUT_9: &str =
"ids.high9, ids.low9 = divmod(memory[ids.inputs + 9], 256 ** 3)";
pub(crate) const SPLIT_INPUT_12: &str =
"ids.high12, ids.low12 = divmod(memory[ids.inputs + 12], 256 ** 4)";
pub(crate) const SPLIT_INPUT_15: &str =
"ids.high15, ids.low15 = divmod(memory[ids.inputs + 15], 256 ** 5)";

pub(crate) const SPLIT_N_BYTES: &str =
"ids.n_words_to_copy, ids.n_bytes_left = divmod(ids.n_bytes, ids.BYTES_IN_WORD)";
pub(crate) const SPLIT_OUTPUT_MID_LOW_HIGH: &str =
"tmp, ids.output1_low = divmod(ids.output1, 256 ** 7)
ids.output1_high, ids.output1_mid = divmod(tmp, 2 ** 128)";

pub(crate) const NONDET_N_GREATER_THAN_10: &str =
"memory[ap] = to_felt_or_relocatable(ids.n >= 10)";
pub(crate) const NONDET_N_GREATER_THAN_2: &str = "memory[ap] = to_felt_or_relocatable(ids.n >= 2)";
Expand Down
Loading

0 comments on commit 637b733

Please sign in to comment.