diff --git a/cairo_vm_hints/src/hint_processor/mod.rs b/cairo_vm_hints/src/hint_processor/mod.rs index 390019c0..c6c79adb 100644 --- a/cairo_vm_hints/src/hint_processor/mod.rs +++ b/cairo_vm_hints/src/hint_processor/mod.rs @@ -99,6 +99,8 @@ impl CustomHintProcessor { hints.insert(lib::segments::SEGMENTS_ADD_EVM_MEMORIZER_OFFSET.into(), lib::segments::segments_add_evm_memorizer_offset); hints.insert(lib::segments::SEGMENTS_ADD_EVM_STARKNET_MEMORIZER_INDEX.into(), lib::segments::segments_add_evm_starknet_memorizer_index); hints.insert(lib::segments::SEGMENTS_ADD_STARKNET_MEMORIZER_OFFSET.into(), lib::segments::segments_add_starknet_memorizer_offset); + hints.insert(lib::merkle::HINT_TARGET_TASK_HASH.into(), lib::merkle::hint_target_task_hash); + hints.insert(lib::merkle::HINT_IS_LEFT_SMALLER.into(), lib::merkle::hint_is_left_smaller); hints } diff --git a/cairo_vm_hints/src/hints/lib/merkle/mod.rs b/cairo_vm_hints/src/hints/lib/merkle/mod.rs new file mode 100644 index 00000000..2b4d7ea3 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/merkle/mod.rs @@ -0,0 +1,107 @@ +use crate::hints::vars; +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{ + get_relocatable_from_var_name, insert_value_from_var_name, +}; +use cairo_vm::types::relocatable::MaybeRelocatable; +use cairo_vm::{ + types::exec_scope::ExecutionScopes, + vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, + Felt252, +}; +use num_bigint::BigUint; +use std::collections::HashMap; + +const FELT_TWO_POW_128: Felt252 = + Felt252::from_hex_unchecked("0x0100000000000000000000000000000000"); + +pub const HINT_TARGET_TASK_HASH: &str = + "target_task_hash = hex(ids.task_hash.low + ids.task_hash.high*2**128)[2:] print(f\"Task Hash: 0x{target_task_hash}\")"; + +pub fn hint_target_task_hash( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let task_hash = vm + .get_continuous_range( + get_relocatable_from_var_name( + vars::ids::TASK_HASH, + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?, + 2, + )? + .into_iter() + .map(|x| x.get_int().unwrap()) + .collect::>(); + + let target_task_hash = + task_hash[0].to_biguint() + FELT_TWO_POW_128.to_biguint() * task_hash[1].to_biguint(); + + // TODO: add appropriate logger + println!("Task Hash: 0x{:x}", target_task_hash); + + Ok(()) +} + +pub const HINT_IS_LEFT_SMALLER: &str = + "def flip_endianess(val): val_hex = hex(val)[2:] if len(val_hex) % 2: val_hex = '0' + val_hex # Convert hex string to bytes byte_data = bytes.fromhex(val_hex) num = int.from_bytes(byte_data, byteorder=\"little\") return num # In LE Uint256, the low and high are reversed left = flip_endianess(ids.left.low) * 2**128 + flip_endianess(ids.left.high) right = flip_endianess(ids.right.low) * 2**128 + flip_endianess(ids.right.high) # Compare the values to derive correct hashing order if left < right: ids.is_left_smaller = 1 #print(f\"H({hex(left)}, {hex(right)}\") else: #print(f\"H({hex(right)}, {hex(left)}\") ids.is_left_smaller = 0"; + +pub fn hint_is_left_smaller( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let left = vm + .get_continuous_range( + get_relocatable_from_var_name( + vars::ids::LEFT, + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?, + 2, + )? + .into_iter() + .map(|x| x.get_int().unwrap()) + .collect::>(); + + let right = vm + .get_continuous_range( + get_relocatable_from_var_name( + vars::ids::RIGHT, + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?, + 2, + )? + .into_iter() + .map(|x| x.get_int().unwrap()) + .collect::>(); + + let left_flipped = BigUint::from_bytes_le(&left[0].to_bytes_be()) + * FELT_TWO_POW_128.to_biguint() + + BigUint::from_bytes_le(&left[1].to_bytes_be()); + let right_flipped = BigUint::from_bytes_le(&right[1].to_bytes_be()) + * FELT_TWO_POW_128.to_biguint() + + BigUint::from_bytes_le(&right[1].to_bytes_be()); + + let insert = if left_flipped < right_flipped { + Felt252::ONE + } else { + Felt252::ZERO + }; + + insert_value_from_var_name( + vars::ids::IS_LEFT_SMALLER, + MaybeRelocatable::Int(insert), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ) +} diff --git a/cairo_vm_hints/src/hints/lib/mod.rs b/cairo_vm_hints/src/hints/lib/mod.rs index 598627c8..c9df03d0 100644 --- a/cairo_vm_hints/src/hints/lib/mod.rs +++ b/cairo_vm_hints/src/hints/lib/mod.rs @@ -1,5 +1,6 @@ pub mod contract_bootloader; pub mod decoder; +pub mod merkle; pub mod print; pub mod rlp; pub mod segments; diff --git a/cairo_vm_hints/src/hints/vars.rs b/cairo_vm_hints/src/hints/vars.rs index be27ee93..c76cffc3 100644 --- a/cairo_vm_hints/src/hints/vars.rs +++ b/cairo_vm_hints/src/hints/vars.rs @@ -15,8 +15,10 @@ pub mod ids { 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_LEFT_SMALLER: &str = "ids.is_left_smaller"; pub(crate) const IS_LONG: &str = "ids.is_long"; pub(crate) const ITEM_TYPE: &str = "ids.item_type"; + pub(crate) const LEFT: &str = "ids.left"; 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"; @@ -27,11 +29,13 @@ pub mod ids { pub(crate) const R: &str = "ids.r"; pub(crate) const RESULT: &str = "result"; pub(crate) const RETURN_BUILTIN_PTRS: &str = "return_builtin_ptrs"; + pub(crate) const RIGHT: &str = "ids.right"; 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 TASK_HASH: &str = "ids.task_hash"; pub(crate) const VALUE_LEN: &str = "ids.value_len"; pub(crate) const VALUE: &str = "ids.value"; }