From caf069ef7fcb2f8cf7362f2fd875f94a9accd41b Mon Sep 17 00:00:00 2001 From: Mario Rugiero Date: Mon, 24 Apr 2023 23:13:41 -0300 Subject: [PATCH] feat(hints): "full word" from cairo_keccak.json --- CHANGELOG.md | 8 ++++ cairo_programs/_keccak_alternative_hint.cairo | 14 +++++++ .../builtin_hint_processor_definition.rs | 5 ++- .../cairo_keccak/keccak_hints.rs | 41 ++++++++++++++++++- .../builtin_hint_processor/hint_code.rs | 2 + 5 files changed, 68 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 128205ee8d..d4efd76da2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ #### Upcoming Changes +* Implement hint for `starkware.cairo.common.cairo_keccak.keccak._copy_inputs` as described by whitelist `starknet/security/whitelists/cairo_keccak.json` [#1058](https://github.com/lambdaclass/cairo-rs/pull/1058) + + `BuiltinHintProcessor` now supports the following hint: + + ```python + %{ ids.full_word = int(ids.n_bytes >= 8) %} + ``` + * Implement hint for `starkware.cairo.common.cairo_keccak.keccak._block_permutation` as described by whitelist `starknet/security/whitelists/cairo_keccak.json` [#1046](https://github.com/lambdaclass/cairo-rs/pull/1046) `BuiltinHintProcessor` now supports the following hint: diff --git a/cairo_programs/_keccak_alternative_hint.cairo b/cairo_programs/_keccak_alternative_hint.cairo index d3f725af38..d89ba6c8d2 100644 --- a/cairo_programs/_keccak_alternative_hint.cairo +++ b/cairo_programs/_keccak_alternative_hint.cairo @@ -113,6 +113,20 @@ func run_cairo_keccak{output_ptr: felt*, range_check_ptr, bitwise_ptr: BitwiseBu _prepare_block{keccak_ptr=output_ptr}(inputs=inputs, n_bytes=n_bytes, state=state); _block_permutation_cairo_keccak{keccak_ptr=output_ptr}(); + local full_word: felt; + %{ ids.full_word = int(ids.n_bytes >= 8) %} + assert full_word = 1; + + let n_bytes = 8; + local full_word: felt; + %{ ids.full_word = int(ids.n_bytes >= 8) %} + assert full_word = 1; + + let n_bytes = 7; + local full_word: felt; + %{ ids.full_word = int(ids.n_bytes >= 8) %} + assert full_word = 0; + return (); } diff --git a/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs b/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs index 6589272b46..0b6fead174 100644 --- a/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs +++ b/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs @@ -22,7 +22,7 @@ use crate::{ }, cairo_keccak::keccak_hints::{ block_permutation_v1, block_permutation_v2, cairo_keccak_finalize_v1, - cairo_keccak_finalize_v2, compare_bytes_in_word_nondet, + cairo_keccak_finalize_v2, cairo_keccak_is_full_word, compare_bytes_in_word_nondet, compare_keccak_full_rate_in_bytes_nondet, keccak_write_args, }, dict_hint_utils::{ @@ -522,6 +522,9 @@ impl HintProcessor for BuiltinHintProcessor { hint_code::SHA256_FINALIZE => { sha256_finalize(vm, &hint_data.ids_data, &hint_data.ap_tracking) } + hint_code::CAIRO_KECCAK_INPUT_IS_FULL_WORD => { + cairo_keccak_is_full_word(vm, &hint_data.ids_data, &hint_data.ap_tracking) + } hint_code::COMPARE_KECCAK_FULL_RATE_IN_BYTES_NONDET => { compare_keccak_full_rate_in_bytes_nondet( vm, diff --git a/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs b/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs index 1df1b0dcdc..771a0c4361 100644 --- a/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs +++ b/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs @@ -7,7 +7,8 @@ use crate::{ felt::Felt252, hint_processor::{ builtin_hint_processor::hint_utils::{ - get_integer_from_var_name, get_ptr_from_var_name, insert_value_into_ap, + get_integer_from_var_name, get_ptr_from_var_name, insert_value_from_var_name, + insert_value_into_ap, }, hint_processor_definition::HintReference, }, @@ -181,6 +182,24 @@ pub(crate) fn block_permutation_v1( Ok(()) } +/* +Implements hint: + %{ + ids.full_word = int(ids.n_bytes >= 8) + %} +*/ +pub(crate) fn cairo_keccak_is_full_word( + vm: &mut VirtualMachine, + ids_data: &HashMap, + ap_tracking: &ApTracking, +) -> Result<(), HintError> { + let n_bytes = get_integer_from_var_name("n_bytes", vm, ids_data, ap_tracking)? + .to_usize() + .unwrap_or(8); // Hack: if it doesn't fit `usize` then it's >= 8 + let full_word = Felt252::from((n_bytes >= 8) as usize); + insert_value_from_var_name("full_word", &full_word, vm, ids_data, ap_tracking) +} + /* Implements hint: %{ @@ -362,10 +381,30 @@ mod tests { vm::vm_core::VirtualMachine, }; use assert_matches::assert_matches; + use rstest::*; #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::*; + #[rstest] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[case(0, 0)] + #[case(1, 0)] + #[case(7, 0)] + #[case(8, 1)] + #[case(16, 1)] + #[case(usize::MAX as i128, 1)] + #[case(i128::MAX, 1)] + fn cairo_keccak_is_full_word(#[case] n_bytes: i128, #[case] full_bytes: usize) { + let hint_code = "ids.full_word = int(ids.n_bytes >= 8)"; + let mut vm = vm_with_range_check!(); + vm.segments = segments![((1, 1), n_bytes)]; + vm.run_context.fp = 2; + let ids_data = ids_data!["full_word", "n_bytes"]; + assert_matches!(run_hint!(vm, ids_data, hint_code), Ok(())); + check_memory![vm.segments.memory, ((1, 0), full_bytes)]; + } + #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn keccak_write_args_valid_test() { diff --git a/src/hint_processor/builtin_hint_processor/hint_code.rs b/src/hint_processor/builtin_hint_processor/hint_code.rs index 1bb2a0b63e..ff13e451eb 100644 --- a/src/hint_processor/builtin_hint_processor/hint_code.rs +++ b/src/hint_processor/builtin_hint_processor/hint_code.rs @@ -750,6 +750,8 @@ output_values = keccak_func(memory.get_range( ids.keccak_ptr_start, _keccak_state_size_felts)) segments.write_arg(ids.output, output_values)"#; +pub const CAIRO_KECCAK_INPUT_IS_FULL_WORD: &str = r#"ids.full_word = int(ids.n_bytes >= 8)"#; + pub const CAIRO_KECCAK_FINALIZE_V1: &str = r#"# Add dummy pairs of input and output. _keccak_state_size_felts = int(ids.KECCAK_STATE_SIZE_FELTS) _block_size = int(ids.BLOCK_SIZE)