From 0da071c86c4e5d6700aca3cf0261ccb761580fba Mon Sep 17 00:00:00 2001 From: codyx Date: Mon, 2 Dec 2024 12:33:07 +0400 Subject: [PATCH 1/2] Add rlp hints --- cairo_vm_hints/src/hints/lib/mod.rs | 1 + .../src/hints/lib/rlp/cur_processed_words.rs | 34 +++++++++++ .../src/hints/lib/rlp/divmod_rlp.rs | 50 +++++++++++++++ .../src/hints/lib/rlp/divmod_value.rs | 50 +++++++++++++++ cairo_vm_hints/src/hints/lib/rlp/is_long.rs | 50 +++++++++++++++ cairo_vm_hints/src/hints/lib/rlp/item_type.rs | 61 +++++++++++++++++++ cairo_vm_hints/src/hints/lib/rlp/mod.rs | 5 ++ src/utils/rlp.cairo | 24 +++++--- 8 files changed, 267 insertions(+), 8 deletions(-) create mode 100644 cairo_vm_hints/src/hints/lib/rlp/cur_processed_words.rs create mode 100644 cairo_vm_hints/src/hints/lib/rlp/divmod_rlp.rs create mode 100644 cairo_vm_hints/src/hints/lib/rlp/divmod_value.rs create mode 100644 cairo_vm_hints/src/hints/lib/rlp/is_long.rs create mode 100644 cairo_vm_hints/src/hints/lib/rlp/item_type.rs create mode 100644 cairo_vm_hints/src/hints/lib/rlp/mod.rs diff --git a/cairo_vm_hints/src/hints/lib/mod.rs b/cairo_vm_hints/src/hints/lib/mod.rs index 585bd722..598627c8 100644 --- a/cairo_vm_hints/src/hints/lib/mod.rs +++ b/cairo_vm_hints/src/hints/lib/mod.rs @@ -1,4 +1,5 @@ pub mod contract_bootloader; pub mod decoder; pub mod print; +pub mod rlp; pub mod segments; diff --git a/cairo_vm_hints/src/hints/lib/rlp/cur_processed_words.rs b/cairo_vm_hints/src/hints/lib/rlp/cur_processed_words.rs new file mode 100644 index 00000000..ddba658d --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/rlp/cur_processed_words.rs @@ -0,0 +1,34 @@ +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{ + get_integer_from_var_name, insert_value_into_ap, +}; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use std::cmp::Ordering; +use std::collections::HashMap; +pub const HINT_CUR_PROCESSED_WORDS: &str = + "memory[ap] = 1 if (ids.value_len - ids.n_processed_words == 0) else 0"; + +pub fn hint_cur_processed_words( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let value_len = + get_integer_from_var_name("value_len", vm, &hint_data.ids_data, &hint_data.ap_tracking)?; + let n_processed_words = get_integer_from_var_name( + "n_processed_words", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + let insert = match (value_len - n_processed_words).cmp(&Felt252::ZERO) { + Ordering::Equal => Felt252::ONE, + _ => Felt252::ZERO, + }; + + insert_value_into_ap(vm, insert) +} diff --git a/cairo_vm_hints/src/hints/lib/rlp/divmod_rlp.rs b/cairo_vm_hints/src/hints/lib/rlp/divmod_rlp.rs new file mode 100644 index 00000000..4532ab2e --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/rlp/divmod_rlp.rs @@ -0,0 +1,50 @@ +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{ + get_integer_from_var_name, insert_value_from_var_name, +}; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::types::relocatable::{MaybeRelocatable, Relocatable}; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use starknet_types_core::felt::NonZeroFelt; +use std::collections::HashMap; + +pub const HINT_DIVMOD_RLP: &str = "ids.q, ids.r = divmod(memory[ids.rlp + ids.i], ids.devisor)"; + +pub fn hint_divmod_rlp( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let rlp: usize = + get_integer_from_var_name("rlp", vm, &hint_data.ids_data, &hint_data.ap_tracking)? + .try_into() + .unwrap(); + let i: usize = get_integer_from_var_name("i", vm, &hint_data.ids_data, &hint_data.ap_tracking)? + .try_into() + .unwrap(); + let devisor: Felt252 = + get_integer_from_var_name("devisor", vm, &hint_data.ids_data, &hint_data.ap_tracking)?; + + let value: Felt252 = *vm.get_integer(Relocatable { + segment_index: isize::default(), + offset: rlp + i, + })?; + + let (q, r) = value.div_rem(&NonZeroFelt::try_from(devisor).unwrap()); + insert_value_from_var_name( + "q", + MaybeRelocatable::Int(q), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + insert_value_from_var_name( + "r", + MaybeRelocatable::Int(r), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ) +} diff --git a/cairo_vm_hints/src/hints/lib/rlp/divmod_value.rs b/cairo_vm_hints/src/hints/lib/rlp/divmod_value.rs new file mode 100644 index 00000000..a12b2098 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/rlp/divmod_value.rs @@ -0,0 +1,50 @@ +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{ + get_integer_from_var_name, insert_value_from_var_name, +}; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::types::relocatable::{MaybeRelocatable, Relocatable}; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use starknet_types_core::felt::NonZeroFelt; +use std::collections::HashMap; + +pub const HINT_DIVMOD_VALUE: &str = "ids.q, ids.r = divmod(memory[ids.value + ids.i], ids.devisor)"; + +pub fn hint_divmod_value( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let value: usize = + get_integer_from_var_name("value", vm, &hint_data.ids_data, &hint_data.ap_tracking)? + .try_into() + .unwrap(); + let i: usize = get_integer_from_var_name("i", vm, &hint_data.ids_data, &hint_data.ap_tracking)? + .try_into() + .unwrap(); + let devisor: Felt252 = + get_integer_from_var_name("devisor", vm, &hint_data.ids_data, &hint_data.ap_tracking)?; + + let value: Felt252 = *vm.get_integer(Relocatable { + segment_index: isize::default(), + offset: value + i, + })?; + + let (q, r) = value.div_rem(&NonZeroFelt::try_from(devisor).unwrap()); + insert_value_from_var_name( + "q", + MaybeRelocatable::Int(q), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + insert_value_from_var_name( + "r", + MaybeRelocatable::Int(r), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ) +} diff --git a/cairo_vm_hints/src/hints/lib/rlp/is_long.rs b/cairo_vm_hints/src/hints/lib/rlp/is_long.rs new file mode 100644 index 00000000..02deea0e --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/rlp/is_long.rs @@ -0,0 +1,50 @@ +use cairo_vm::{ + hint_processor::builtin_hint_processor::{ + builtin_hint_processor_definition::HintProcessorData, + hint_utils::{get_integer_from_var_name, insert_value_from_var_name}, + }, + types::{exec_scope::ExecutionScopes, relocatable::MaybeRelocatable}, + vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, + Felt252, +}; +use std::collections::HashMap; + +const FELT_C0: Felt252 = Felt252::from_hex_unchecked("0xc0"); +const FELT_F6: Felt252 = Felt252::from_hex_unchecked("0xf6"); +const FELT_F7: Felt252 = Felt252::from_hex_unchecked("0xf7"); +const FELT_FF: Felt252 = Felt252::from_hex_unchecked("0xff"); + +pub const HINT_IS_LONG: &str = + "ids.is_long = 0 if 0xc0 <= ids.first_byte <= 0xf6 else 1 if 0xf7 <= ids.first_byte <= 0xff else assert False, 'Invalid RLP list'"; + +pub fn hint_is_long( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let first_byte = get_integer_from_var_name( + "first_byte", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + let insert = if FELT_C0 <= first_byte && first_byte <= FELT_F6 { + Felt252::ZERO + } else if FELT_F7 <= first_byte && first_byte <= FELT_FF { + Felt252::ONE + } else { + return Err(HintError::UnknownHint( + "Invalid RLP list".to_string().into_boxed_str(), + )); + }; + + insert_value_from_var_name( + "is_long", + MaybeRelocatable::Int(insert), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ) +} diff --git a/cairo_vm_hints/src/hints/lib/rlp/item_type.rs b/cairo_vm_hints/src/hints/lib/rlp/item_type.rs new file mode 100644 index 00000000..e28c6012 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/rlp/item_type.rs @@ -0,0 +1,61 @@ +use cairo_vm::{ + hint_processor::builtin_hint_processor::{ + builtin_hint_processor_definition::HintProcessorData, + hint_utils::{get_integer_from_var_name, insert_value_from_var_name}, + }, + types::{exec_scope::ExecutionScopes, relocatable::MaybeRelocatable}, + vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, + Felt252, +}; +use std::collections::HashMap; + +const FELT_7F: Felt252 = Felt252::from_hex_unchecked("0x7f"); +const FELT_80: Felt252 = Felt252::from_hex_unchecked("0x80"); +const FELT_B6: Felt252 = Felt252::from_hex_unchecked("0xb6"); +const FELT_B7: Felt252 = Felt252::from_hex_unchecked("0xb7"); +const FELT_BF: Felt252 = Felt252::from_hex_unchecked("0xbf"); +const FELT_C0: Felt252 = Felt252::from_hex_unchecked("0xc0"); +const FELT_F6: Felt252 = Felt252::from_hex_unchecked("0xf6"); +const FELT_F7: Felt252 = Felt252::from_hex_unchecked("0xf7"); +const FELT_FF: Felt252 = Felt252::from_hex_unchecked("0xff"); +const FELT_FOUR: Felt252 = Felt252::from_hex_unchecked("0x04"); + +pub const HINT_ITEM_TYPE: &str = "ids.item_type = 0 if ids.current_item <= 0x7f else 1 if 0x80 <= ids.current_item <= 0xb6 else 2 if 0xb7 <= ids.current_item <= 0xbf else 3 if 0xc0 <= ids.current_item <= 0xf6 else 4 if 0xf7 <= ids.current_item <= 0xff else assert False, 'Invalid RLP item'"; + +pub fn hint_item_type( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let current_item = get_integer_from_var_name( + "current_item", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + let insert = if current_item <= FELT_7F { + Felt252::ZERO + } else if FELT_80 <= current_item && current_item <= FELT_B6 { + Felt252::ONE // short string + } else if FELT_B7 <= current_item && current_item <= FELT_BF { + Felt252::TWO // long string + } else if FELT_C0 <= current_item && current_item <= FELT_F6 { + Felt252::THREE // short list + } else if FELT_F7 <= current_item && current_item <= FELT_FF { + FELT_FOUR // long list + } else { + return Err(HintError::UnknownHint( + "Invalid RLP item".to_string().into_boxed_str(), + )); + }; + + insert_value_from_var_name( + "item_type", + MaybeRelocatable::Int(insert), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ) +} diff --git a/cairo_vm_hints/src/hints/lib/rlp/mod.rs b/cairo_vm_hints/src/hints/lib/rlp/mod.rs new file mode 100644 index 00000000..a2ea9b97 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/rlp/mod.rs @@ -0,0 +1,5 @@ +pub mod cur_processed_words; +pub mod divmod_rlp; +pub mod divmod_value; +pub mod is_long; +pub mod item_type; diff --git a/src/utils/rlp.cairo b/src/utils/rlp.cairo index 1ad24142..6ba2329a 100644 --- a/src/utils/rlp.cairo +++ b/src/utils/rlp.cairo @@ -115,8 +115,10 @@ func rlp_list_retrieve{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, pow2_array let current_item = extract_byte_at_pos(rlp[item_starts_at_word], item_start_offset, pow2_array); local item_type: felt; + // %{ + // #print("current item:", hex(ids.current_item)) + // %} %{ - #print("current item:", hex(ids.current_item)) if ids.current_item <= 0x7f: ids.item_type = 0 # single byte elif 0x80 <= ids.current_item <= 0xb6: @@ -274,7 +276,7 @@ func chunk_to_felt_be{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, pow2_array: } let (q, r) = felt_divmod(value, 0x100); // remove trailing byte - %{ print("q:", hex(ids.q), "r:", hex(ids.r)) %} + // %{ print("q:", hex(ids.q), "r:", hex(ids.r)) %} // ensure we have a short string assert [range_check_ptr] = 8 - bytes_len; @@ -328,14 +330,14 @@ func decode_rlp_word_to_uint256{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, p ) -> Uint256 { alloc_locals; - %{ print("decode_rlp_word_to_uint256") %} - %{ print(hex(memory[ids.rlp])) %} + // %{ print("decode_rlp_word_to_uint256") %} + // %{ print(hex(memory[ids.rlp])) %} let (value, value_len, value_bytes_len) = rlp_list_retrieve( rlp=rlp, field=0, item_starts_at_byte=0, counter=0 ); - %{ print("value:", hex(memory[ids.value])) %} + // %{ print("value:", hex(memory[ids.value])) %} // convert to uint256 let result = le_chunks_to_uint256( @@ -452,8 +454,10 @@ func right_shift_le_chunks{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, pow2_a let r = [ap + 1]; %{ ids.q, ids.r = divmod(memory[ids.value + ids.i], ids.devisor) - #print(f"val={memory[ids.value + ids.i]} q={ids.q} r={ids.r} i={ids.i}") %} + // %{ + // #print(f"val={memory[ids.value + ids.i]} q={ids.q} r={ids.r} i={ids.i}") + // %} ap += 2; tempvar offset = 3 * n_processed_words; assert [range_check_ptr + offset] = q; @@ -522,8 +526,10 @@ func prepend_le_chunks{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, pow2_array let r = [ap + 1]; %{ ids.q, ids.r = divmod(memory[ids.rlp + ids.i], ids.devisor) - #print(f"val={hex(memory[ids.rlp + ids.i])} q/cur={hex(ids.q)} r={hex(ids.r)} i={ids.i}") %} + // %{ + // print(f"val={hex(memory[ids.rlp + ids.i])} q/cur={hex(ids.q)} r={hex(ids.r)} i={ids.i}") + // %} ap += 2; tempvar item_bytes_len = 3 * n_processed_words; assert [range_check_ptr + item_bytes_len] = q; @@ -612,8 +618,10 @@ func get_rlp_len{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, pow2_array: felt let current_item = extract_byte_at_pos(rlp[0], item_start_offset, pow2_array); local item_type: felt; + // %{ + // #print("current item:", hex(ids.current_item)) + // %} %{ - #print("current item:", hex(ids.current_item)) if ids.current_item <= 0x7f: ids.item_type = 0 # single byte elif 0x80 <= ids.current_item <= 0xb6: From 17adde91a09bddb53146e155a14908e07c4f0413 Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Mon, 2 Dec 2024 10:39:14 +0100 Subject: [PATCH 2/2] fixes & refactor --- cairo_vm_hints/src/hint_processor/mod.rs | 5 + .../src/hints/lib/rlp/cur_processed_words.rs | 34 ----- cairo_vm_hints/src/hints/lib/rlp/divmod.rs | 122 ++++++++++++++++++ .../src/hints/lib/rlp/divmod_rlp.rs | 50 ------- .../src/hints/lib/rlp/divmod_value.rs | 50 ------- cairo_vm_hints/src/hints/lib/rlp/is_long.rs | 50 ------- cairo_vm_hints/src/hints/lib/rlp/item_type.rs | 55 ++++++-- cairo_vm_hints/src/hints/lib/rlp/mod.rs | 19 ++- .../src/hints/lib/rlp/processed_words.rs | 45 +++++++ cairo_vm_hints/src/hints/vars.rs | 12 ++ src/utils/rlp.cairo | 8 +- 11 files changed, 242 insertions(+), 208 deletions(-) delete mode 100644 cairo_vm_hints/src/hints/lib/rlp/cur_processed_words.rs create mode 100644 cairo_vm_hints/src/hints/lib/rlp/divmod.rs delete mode 100644 cairo_vm_hints/src/hints/lib/rlp/divmod_rlp.rs delete mode 100644 cairo_vm_hints/src/hints/lib/rlp/divmod_value.rs delete mode 100644 cairo_vm_hints/src/hints/lib/rlp/is_long.rs create mode 100644 cairo_vm_hints/src/hints/lib/rlp/processed_words.rs diff --git a/cairo_vm_hints/src/hint_processor/mod.rs b/cairo_vm_hints/src/hint_processor/mod.rs index 247fd56c..db00a187 100644 --- a/cairo_vm_hints/src/hint_processor/mod.rs +++ b/cairo_vm_hints/src/hint_processor/mod.rs @@ -86,6 +86,11 @@ impl CustomHintProcessor { hints.insert(lib::decoder::evm::has_type_prefix::HINT_HAS_TYPE_PREFIX.into(), lib::decoder::evm::has_type_prefix::hint_has_type_prefix); hints.insert(lib::decoder::evm::is_byzantium::HINT_IS_BYZANTIUM.into(), lib::decoder::evm::is_byzantium::hint_is_byzantium); hints.insert(lib::decoder::evm::v_is_encoded::HINT_V_IS_ENCODED.into(), lib::decoder::evm::v_is_encoded::hint_v_is_encoded); + hints.insert(lib::rlp::divmod::HINT_DIVMOD_RLP.into(), lib::rlp::divmod::hint_divmod_rlp); + hints.insert(lib::rlp::divmod::HINT_DIVMOD_VALUE.into(), lib::rlp::divmod::hint_divmod_value); + hints.insert(lib::rlp::item_type::HINT_IS_LONG.into(), lib::rlp::item_type::hint_is_long); + hints.insert(lib::rlp::item_type::HINT_ITEM_TYPE.into(), lib::rlp::item_type::hint_item_type); + hints.insert(lib::rlp::processed_words::HINT_PROCESSED_WORDS.into(), lib::rlp::processed_words::hint_processed_words); hints.insert(lib::print::PROGRAM_HASH.into(), lib::print::program_hash); hints.insert(lib::segments::SEGMENTS_ADD.into(), lib::segments::segments_add); hints.insert(lib::segments::SEGMENTS_ADD_EVM_MEMORIZER_SEGMENT_INDEX.into(), lib::segments::segments_add_evm_memorizer_segment_index); diff --git a/cairo_vm_hints/src/hints/lib/rlp/cur_processed_words.rs b/cairo_vm_hints/src/hints/lib/rlp/cur_processed_words.rs deleted file mode 100644 index ddba658d..00000000 --- a/cairo_vm_hints/src/hints/lib/rlp/cur_processed_words.rs +++ /dev/null @@ -1,34 +0,0 @@ -use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; -use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{ - get_integer_from_var_name, insert_value_into_ap, -}; -use cairo_vm::types::exec_scope::ExecutionScopes; -use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; -use cairo_vm::Felt252; -use std::cmp::Ordering; -use std::collections::HashMap; -pub const HINT_CUR_PROCESSED_WORDS: &str = - "memory[ap] = 1 if (ids.value_len - ids.n_processed_words == 0) else 0"; - -pub fn hint_cur_processed_words( - vm: &mut VirtualMachine, - _exec_scope: &mut ExecutionScopes, - hint_data: &HintProcessorData, - _constants: &HashMap, -) -> Result<(), HintError> { - let value_len = - get_integer_from_var_name("value_len", vm, &hint_data.ids_data, &hint_data.ap_tracking)?; - let n_processed_words = get_integer_from_var_name( - "n_processed_words", - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - )?; - - let insert = match (value_len - n_processed_words).cmp(&Felt252::ZERO) { - Ordering::Equal => Felt252::ONE, - _ => Felt252::ZERO, - }; - - insert_value_into_ap(vm, insert) -} diff --git a/cairo_vm_hints/src/hints/lib/rlp/divmod.rs b/cairo_vm_hints/src/hints/lib/rlp/divmod.rs new file mode 100644 index 00000000..c0509748 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/rlp/divmod.rs @@ -0,0 +1,122 @@ +use cairo_vm::{ + hint_processor::builtin_hint_processor::{ + builtin_hint_processor_definition::HintProcessorData, + hint_utils::{ + get_integer_from_var_name, get_ptr_from_var_name, insert_value_from_var_name, + }, + }, + types::relocatable::MaybeRelocatable, +}; +use cairo_vm::{ + types::exec_scope::ExecutionScopes, + vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, + Felt252, +}; +use starknet_types_core::felt::NonZeroFelt; +use std::collections::HashMap; + +use crate::hints::vars; + +pub const HINT_DIVMOD_RLP: &str = "ids.q, ids.r = divmod(memory[ids.rlp + ids.i], ids.devisor)"; + +pub fn hint_divmod_rlp( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let rlp = get_ptr_from_var_name( + vars::ids::RLP, + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + let i: usize = get_integer_from_var_name( + vars::ids::I, + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )? + .try_into() + .unwrap(); + + let devisor = get_integer_from_var_name( + vars::ids::DEVISOR, + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + let (q, r) = vm + .get_integer((rlp + i)?)? + .div_rem(&NonZeroFelt::try_from(devisor).unwrap()); + + insert_value_from_var_name( + vars::ids::Q, + MaybeRelocatable::Int(q), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + insert_value_from_var_name( + vars::ids::R, + MaybeRelocatable::Int(r), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ) +} + +pub const HINT_DIVMOD_VALUE: &str = "ids.q, ids.r = divmod(memory[ids.value + ids.i], ids.devisor)"; + +pub fn hint_divmod_value( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let value = get_ptr_from_var_name( + vars::ids::VALUE, + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + let i: usize = get_integer_from_var_name( + vars::ids::I, + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )? + .try_into() + .unwrap(); + + let devisor = get_integer_from_var_name( + vars::ids::DEVISOR, + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + let (q, r) = vm + .get_integer((value + i)?)? + .div_rem(&NonZeroFelt::try_from(devisor).unwrap()); + + insert_value_from_var_name( + vars::ids::Q, + MaybeRelocatable::Int(q), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + insert_value_from_var_name( + vars::ids::R, + MaybeRelocatable::Int(r), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ) +} diff --git a/cairo_vm_hints/src/hints/lib/rlp/divmod_rlp.rs b/cairo_vm_hints/src/hints/lib/rlp/divmod_rlp.rs deleted file mode 100644 index 4532ab2e..00000000 --- a/cairo_vm_hints/src/hints/lib/rlp/divmod_rlp.rs +++ /dev/null @@ -1,50 +0,0 @@ -use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; -use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{ - get_integer_from_var_name, insert_value_from_var_name, -}; -use cairo_vm::types::exec_scope::ExecutionScopes; -use cairo_vm::types::relocatable::{MaybeRelocatable, Relocatable}; -use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; -use cairo_vm::Felt252; -use starknet_types_core::felt::NonZeroFelt; -use std::collections::HashMap; - -pub const HINT_DIVMOD_RLP: &str = "ids.q, ids.r = divmod(memory[ids.rlp + ids.i], ids.devisor)"; - -pub fn hint_divmod_rlp( - vm: &mut VirtualMachine, - _exec_scope: &mut ExecutionScopes, - hint_data: &HintProcessorData, - _constants: &HashMap, -) -> Result<(), HintError> { - let rlp: usize = - get_integer_from_var_name("rlp", vm, &hint_data.ids_data, &hint_data.ap_tracking)? - .try_into() - .unwrap(); - let i: usize = get_integer_from_var_name("i", vm, &hint_data.ids_data, &hint_data.ap_tracking)? - .try_into() - .unwrap(); - let devisor: Felt252 = - get_integer_from_var_name("devisor", vm, &hint_data.ids_data, &hint_data.ap_tracking)?; - - let value: Felt252 = *vm.get_integer(Relocatable { - segment_index: isize::default(), - offset: rlp + i, - })?; - - let (q, r) = value.div_rem(&NonZeroFelt::try_from(devisor).unwrap()); - insert_value_from_var_name( - "q", - MaybeRelocatable::Int(q), - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - )?; - insert_value_from_var_name( - "r", - MaybeRelocatable::Int(r), - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - ) -} diff --git a/cairo_vm_hints/src/hints/lib/rlp/divmod_value.rs b/cairo_vm_hints/src/hints/lib/rlp/divmod_value.rs deleted file mode 100644 index a12b2098..00000000 --- a/cairo_vm_hints/src/hints/lib/rlp/divmod_value.rs +++ /dev/null @@ -1,50 +0,0 @@ -use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; -use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{ - get_integer_from_var_name, insert_value_from_var_name, -}; -use cairo_vm::types::exec_scope::ExecutionScopes; -use cairo_vm::types::relocatable::{MaybeRelocatable, Relocatable}; -use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; -use cairo_vm::Felt252; -use starknet_types_core::felt::NonZeroFelt; -use std::collections::HashMap; - -pub const HINT_DIVMOD_VALUE: &str = "ids.q, ids.r = divmod(memory[ids.value + ids.i], ids.devisor)"; - -pub fn hint_divmod_value( - vm: &mut VirtualMachine, - _exec_scope: &mut ExecutionScopes, - hint_data: &HintProcessorData, - _constants: &HashMap, -) -> Result<(), HintError> { - let value: usize = - get_integer_from_var_name("value", vm, &hint_data.ids_data, &hint_data.ap_tracking)? - .try_into() - .unwrap(); - let i: usize = get_integer_from_var_name("i", vm, &hint_data.ids_data, &hint_data.ap_tracking)? - .try_into() - .unwrap(); - let devisor: Felt252 = - get_integer_from_var_name("devisor", vm, &hint_data.ids_data, &hint_data.ap_tracking)?; - - let value: Felt252 = *vm.get_integer(Relocatable { - segment_index: isize::default(), - offset: value + i, - })?; - - let (q, r) = value.div_rem(&NonZeroFelt::try_from(devisor).unwrap()); - insert_value_from_var_name( - "q", - MaybeRelocatable::Int(q), - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - )?; - insert_value_from_var_name( - "r", - MaybeRelocatable::Int(r), - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - ) -} diff --git a/cairo_vm_hints/src/hints/lib/rlp/is_long.rs b/cairo_vm_hints/src/hints/lib/rlp/is_long.rs deleted file mode 100644 index 02deea0e..00000000 --- a/cairo_vm_hints/src/hints/lib/rlp/is_long.rs +++ /dev/null @@ -1,50 +0,0 @@ -use cairo_vm::{ - hint_processor::builtin_hint_processor::{ - builtin_hint_processor_definition::HintProcessorData, - hint_utils::{get_integer_from_var_name, insert_value_from_var_name}, - }, - types::{exec_scope::ExecutionScopes, relocatable::MaybeRelocatable}, - vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, - Felt252, -}; -use std::collections::HashMap; - -const FELT_C0: Felt252 = Felt252::from_hex_unchecked("0xc0"); -const FELT_F6: Felt252 = Felt252::from_hex_unchecked("0xf6"); -const FELT_F7: Felt252 = Felt252::from_hex_unchecked("0xf7"); -const FELT_FF: Felt252 = Felt252::from_hex_unchecked("0xff"); - -pub const HINT_IS_LONG: &str = - "ids.is_long = 0 if 0xc0 <= ids.first_byte <= 0xf6 else 1 if 0xf7 <= ids.first_byte <= 0xff else assert False, 'Invalid RLP list'"; - -pub fn hint_is_long( - vm: &mut VirtualMachine, - _exec_scope: &mut ExecutionScopes, - hint_data: &HintProcessorData, - _constants: &HashMap, -) -> Result<(), HintError> { - let first_byte = get_integer_from_var_name( - "first_byte", - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - )?; - - let insert = if FELT_C0 <= first_byte && first_byte <= FELT_F6 { - Felt252::ZERO - } else if FELT_F7 <= first_byte && first_byte <= FELT_FF { - Felt252::ONE - } else { - return Err(HintError::UnknownHint( - "Invalid RLP list".to_string().into_boxed_str(), - )); - }; - - insert_value_from_var_name( - "is_long", - MaybeRelocatable::Int(insert), - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - ) -} diff --git a/cairo_vm_hints/src/hints/lib/rlp/item_type.rs b/cairo_vm_hints/src/hints/lib/rlp/item_type.rs index e28c6012..b6221b39 100644 --- a/cairo_vm_hints/src/hints/lib/rlp/item_type.rs +++ b/cairo_vm_hints/src/hints/lib/rlp/item_type.rs @@ -1,3 +1,6 @@ +use crate::hints::vars; + +use super::*; use cairo_vm::{ hint_processor::builtin_hint_processor::{ builtin_hint_processor_definition::HintProcessorData, @@ -9,16 +12,40 @@ use cairo_vm::{ }; use std::collections::HashMap; -const FELT_7F: Felt252 = Felt252::from_hex_unchecked("0x7f"); -const FELT_80: Felt252 = Felt252::from_hex_unchecked("0x80"); -const FELT_B6: Felt252 = Felt252::from_hex_unchecked("0xb6"); -const FELT_B7: Felt252 = Felt252::from_hex_unchecked("0xb7"); -const FELT_BF: Felt252 = Felt252::from_hex_unchecked("0xbf"); -const FELT_C0: Felt252 = Felt252::from_hex_unchecked("0xc0"); -const FELT_F6: Felt252 = Felt252::from_hex_unchecked("0xf6"); -const FELT_F7: Felt252 = Felt252::from_hex_unchecked("0xf7"); -const FELT_FF: Felt252 = Felt252::from_hex_unchecked("0xff"); -const FELT_FOUR: Felt252 = Felt252::from_hex_unchecked("0x04"); +pub const HINT_IS_LONG: &str = + "ids.is_long = 0 if 0xc0 <= ids.first_byte <= 0xf6 else 1 if 0xf7 <= ids.first_byte <= 0xff else assert False, 'Invalid RLP list'"; + +pub fn hint_is_long( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let first_byte = get_integer_from_var_name( + vars::ids::FIRST_BYTE, + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + let insert = if FELT_C0 <= first_byte && first_byte <= FELT_F6 { + Felt252::ZERO + } else if FELT_F7 <= first_byte && first_byte <= FELT_FF { + Felt252::ONE + } else { + return Err(HintError::UnknownIdentifier( + "Invalid RLP list".to_string().into_boxed_str(), + )); + }; + + insert_value_from_var_name( + vars::ids::IS_LONG, + MaybeRelocatable::Int(insert), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ) +} pub const HINT_ITEM_TYPE: &str = "ids.item_type = 0 if ids.current_item <= 0x7f else 1 if 0x80 <= ids.current_item <= 0xb6 else 2 if 0xb7 <= ids.current_item <= 0xbf else 3 if 0xc0 <= ids.current_item <= 0xf6 else 4 if 0xf7 <= ids.current_item <= 0xff else assert False, 'Invalid RLP item'"; @@ -29,7 +56,7 @@ pub fn hint_item_type( _constants: &HashMap, ) -> Result<(), HintError> { let current_item = get_integer_from_var_name( - "current_item", + vars::ids::CURRENT_ITEM, vm, &hint_data.ids_data, &hint_data.ap_tracking, @@ -44,15 +71,15 @@ pub fn hint_item_type( } else if FELT_C0 <= current_item && current_item <= FELT_F6 { Felt252::THREE // short list } else if FELT_F7 <= current_item && current_item <= FELT_FF { - FELT_FOUR // long list + FELT_4 // long list } else { - return Err(HintError::UnknownHint( + return Err(HintError::UnknownIdentifier( "Invalid RLP item".to_string().into_boxed_str(), )); }; insert_value_from_var_name( - "item_type", + vars::ids::ITEM_TYPE, MaybeRelocatable::Int(insert), vm, &hint_data.ids_data, diff --git a/cairo_vm_hints/src/hints/lib/rlp/mod.rs b/cairo_vm_hints/src/hints/lib/rlp/mod.rs index a2ea9b97..4d03df57 100644 --- a/cairo_vm_hints/src/hints/lib/rlp/mod.rs +++ b/cairo_vm_hints/src/hints/lib/rlp/mod.rs @@ -1,5 +1,16 @@ -pub mod cur_processed_words; -pub mod divmod_rlp; -pub mod divmod_value; -pub mod is_long; +pub mod divmod; pub mod item_type; +pub mod processed_words; + +use cairo_vm::Felt252; + +pub const FELT_4: Felt252 = Felt252::from_hex_unchecked("0x04"); +pub const FELT_7F: Felt252 = Felt252::from_hex_unchecked("0x7f"); +pub const FELT_80: Felt252 = Felt252::from_hex_unchecked("0x80"); +pub const FELT_B6: Felt252 = Felt252::from_hex_unchecked("0xb6"); +pub const FELT_B7: Felt252 = Felt252::from_hex_unchecked("0xb7"); +pub const FELT_BF: Felt252 = Felt252::from_hex_unchecked("0xbf"); +pub const FELT_C0: Felt252 = Felt252::from_hex_unchecked("0xc0"); +pub const FELT_F6: Felt252 = Felt252::from_hex_unchecked("0xf6"); +pub const FELT_F7: Felt252 = Felt252::from_hex_unchecked("0xf7"); +pub const FELT_FF: Felt252 = Felt252::from_hex_unchecked("0xff"); diff --git a/cairo_vm_hints/src/hints/lib/rlp/processed_words.rs b/cairo_vm_hints/src/hints/lib/rlp/processed_words.rs new file mode 100644 index 00000000..359a3db8 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/rlp/processed_words.rs @@ -0,0 +1,45 @@ +use cairo_vm::{ + hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData, + hint_processor::builtin_hint_processor::hint_utils::{ + get_integer_from_var_name, insert_value_into_ap, + }, +}; +use cairo_vm::{ + types::exec_scope::ExecutionScopes, + vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, + Felt252, +}; +use std::{cmp::Ordering, collections::HashMap}; + +use crate::hints::vars; + +pub const HINT_PROCESSED_WORDS: &str = + "memory[ap] = 1 if (ids.value_len - ids.n_processed_words == 0) else 0"; + +pub fn hint_processed_words( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let value_len = get_integer_from_var_name( + vars::ids::VALUE_LEN, + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + let n_processed_words = get_integer_from_var_name( + vars::ids::N_PROCESSED_WORDS, + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + let insert = match (value_len - n_processed_words).cmp(&Felt252::ZERO) { + Ordering::Equal => Felt252::ONE, + _ => Felt252::ZERO, + }; + + insert_value_into_ap(vm, insert) +} diff --git a/cairo_vm_hints/src/hints/vars.rs b/cairo_vm_hints/src/hints/vars.rs index 9ee8845f..38e0ca48 100644 --- a/cairo_vm_hints/src/hints/vars.rs +++ b/cairo_vm_hints/src/hints/vars.rs @@ -10,11 +10,23 @@ pub mod ids { pub(crate) const BUILTIN_PARAMS: &str = "builtin_params"; pub(crate) const BUILTIN_PTRS: &str = "builtin_ptrs"; pub(crate) const COMPILED_CLASS: &str = "compiled_class"; + pub(crate) const CURRENT_ITEM: &str = "ids.current_item"; + pub(crate) const DEVISOR: &str = "ids.devisor"; + pub(crate) const FIRST_BYTE: &str = "ids.first_byte"; + pub(crate) const I: &str = "ids.i"; + pub(crate) const IS_LONG: &str = "ids.is_long"; + pub(crate) const ITEM_TYPE: &str = "ids.item_type"; pub(crate) const N_BUILTINS: &str = "n_builtins"; + pub(crate) const N_PROCESSED_WORDS: &str = "ids.n_processed_words"; pub(crate) const N_SELECTED_BUILTINS: &str = "n_selected_builtins"; + pub(crate) const Q: &str = "ids.q"; + pub(crate) const R: &str = "ids.r"; pub(crate) const RETURN_BUILTIN_PTRS: &str = "return_builtin_ptrs"; + pub(crate) const RLP: &str = "ids.rlp"; pub(crate) const SELECT_BUILTIN: &str = "select_builtin"; pub(crate) const SELECTED_ENCODINGS: &str = "selected_encodings"; pub(crate) const SELECTED_PTRS: &str = "selected_ptrs"; pub(crate) const SYSCALL_PTR: &str = "syscall_ptr"; + pub(crate) const VALUE_LEN: &str = "ids.value_len"; + pub(crate) const VALUE: &str = "ids.value"; } diff --git a/src/utils/rlp.cairo b/src/utils/rlp.cairo index 6ba2329a..ad024ad3 100644 --- a/src/utils/rlp.cairo +++ b/src/utils/rlp.cairo @@ -452,9 +452,7 @@ func right_shift_le_chunks{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, pow2_a // Inlined felt_divmod (unsigned_div_rem). let q = [ap]; let r = [ap + 1]; - %{ - ids.q, ids.r = divmod(memory[ids.value + ids.i], ids.devisor) - %} + %{ ids.q, ids.r = divmod(memory[ids.value + ids.i], ids.devisor) %} // %{ // #print(f"val={memory[ids.value + ids.i]} q={ids.q} r={ids.r} i={ids.i}") // %} @@ -524,9 +522,7 @@ func prepend_le_chunks{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, pow2_array // Inlined felt_divmod (unsigned_div_rem). let q = [ap]; let r = [ap + 1]; - %{ - ids.q, ids.r = divmod(memory[ids.rlp + ids.i], ids.devisor) - %} + %{ ids.q, ids.r = divmod(memory[ids.rlp + ids.i], ids.devisor) %} // %{ // print(f"val={hex(memory[ids.rlp + ids.i])} q/cur={hex(ids.q)} r={hex(ids.r)} i={ids.i}") // %}