Skip to content

Commit

Permalink
encode_packed_256 test working
Browse files Browse the repository at this point in the history
  • Loading branch information
Okm165 committed Oct 22, 2024
1 parent 422e668 commit 87c955f
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 1 deletion.
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ bincode = { version = "2.0.0-rc.3", default-features = false, features = ["serde
cairo-vm = { git = "https://github.com/lambdaclass/cairo-vm", rev = "3fb0344ce038b3a68cae897c403d1f561cfe8da7", features = ["extensive_hints", "clap", "std"] }
clap = { version = "4.3.10", features = ["derive"] }
rand = "0.8"
sha3 = "0.10.8"
starknet-types-core = "0.1.7"
thiserror = "1.0.64"
1 change: 1 addition & 0 deletions cairo_vm_hints/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ bincode.workspace = true
cairo-vm.workspace = true
clap.workspace = true
rand.workspace = true
sha3.workspace = true
starknet-types-core.workspace = true
thiserror.workspace = true
5 changes: 5 additions & 0 deletions cairo_vm_hints/src/hint_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ fn run_hint(
tests::dw_hack::HINT_PRINT_NS => {
tests::dw_hack::hint_print_ns(vm, exec_scope, hint_data, constants)
}
tests::encode_packed_256::HINT_GENERATE_TEST_VECTOR => {
tests::encode_packed_256::hint_generate_test_vector(
vm, exec_scope, hint_data, constants,
)
}
_ => Err(HintError::UnknownHint(
hint_data.code.to_string().into_boxed_str(),
)),
Expand Down
111 changes: 111 additions & 0 deletions cairo_vm_hints/src/hints/tests/encode_packed_256.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData;
use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{
get_ptr_from_var_name, insert_value_from_var_name,
};
use cairo_vm::types::exec_scope::ExecutionScopes;
use cairo_vm::types::relocatable::MaybeRelocatable;
use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine};
use cairo_vm::Felt252;
use rand::Rng;
use sha3::Digest;
use sha3::Keccak256;
use std::collections::HashMap;

fn get_random() -> [u8; 32] {
let mut rng = rand::thread_rng();
let mut arr = [0u8; 32];
rng.fill(&mut arr);
arr
}

fn split_128(value: [u8; 32]) -> ([u8; 16], [u8; 16]) {
let mut lower = [0u8; 16];
let mut upper = [0u8; 16];

lower.copy_from_slice(&value[0..16]);
upper.copy_from_slice(&value[16..32]);

(lower, upper)
}

fn keccak(x: &[u8; 32], y: &[u8; 32]) -> [u8; 32] {
let mut hasher = Keccak256::new();
hasher.update(x);
hasher.update(y);
hasher.finalize().into()
}

pub const HINT_GENERATE_TEST_VECTOR: &str = "import sha3\nimport random\nfrom web3 import Web3\ndef split_128(a):\n \"\"\"Takes in value, returns uint256-ish tuple.\"\"\"\n return [a & ((1 << 128) - 1), a >> 128]\ndef write_uint256_array(ptr, array):\n counter = 0\n for uint in array:\n memory[ptr._reference_value+counter] = uint[0]\n memory[ptr._reference_value+counter+1] = uint[1]\n counter += 2\ndef generate_n_bit_random(n):\n return random.randint(2**(n-1), 2**n - 1)\n\n# Implementation of solitidy keccak256(encodedPacked(x, y)) in python.\ndef encode_packed_256_256(x_y):\n return int(Web3.solidityKeccak([\"uint256\", \"uint256\"], [x_y[0], x_y[1]]).hex(), 16)\n# Another implementation that uses sha3 directly and should be equal. \ndef keccak_256_256(x_y):\n k=sha3.keccak_256()\n k.update(x_y[0].to_bytes(32, 'big'))\n k.update(x_y[1].to_bytes(32, 'big'))\n return int.from_bytes(k.digest(), 'big')\n\n# Build Test vector [[x_1, y_1], [x_2, y_2], ..., [x_len, y_len]].\n\n# 256 random pairs of numbers, each pair having two random numbers of 1-256 bits.\nx_y_list = [[generate_n_bit_random(random.randint(1, 256)), generate_n_bit_random(random.randint(1, 256))] for _ in range(256)]\n# Adds 256 more pairs of equal bit length to the test vector.\nx_y_list += [[generate_n_bit_random(i), generate_n_bit_random(i)] for i in range(1,257)]\n\nkeccak_output_list = [encode_packed_256_256(x_y) for x_y in x_y_list]\nkeccak_result_list = [keccak_256_256(x_y) for x_y in x_y_list]\n\n# Sanity check on keccak implementations.\nassert all([keccak_output_list[i] == keccak_result_list[i] for i in range(len(keccak_output_list))])\n\n\n# Prepare x_array and y_array :\nx_array_split = [split_128(x_y[0]) for x_y in x_y_list]\ny_array_split = [split_128(x_y[1]) for x_y in x_y_list]\n# Write x_array : \nwrite_uint256_array(ids.x_array, x_array_split)\n# Write y_array :\nwrite_uint256_array(ids.y_array, y_array_split)\n\n# Prepare keccak_result_array :\nkeccak_result_list_split = [split_128(keccak_result) for keccak_result in keccak_result_list]\n# Write keccak_result_array :\nwrite_uint256_array(ids.keccak_result_array, keccak_result_list_split)\n\n# Write len :\nids.len = len(keccak_result_list)";

pub fn hint_generate_test_vector(
vm: &mut VirtualMachine,
_exec_scope: &mut ExecutionScopes,
hint_data: &HintProcessorData,
_constants: &HashMap<String, Felt252>,
) -> Result<(), HintError> {
let (x_list, y_list): (Vec<[u8; 32]>, Vec<[u8; 32]>) =
(0..256).map(|_| (get_random(), get_random())).unzip();

let keccak_result_list: Vec<[u8; 32]> = x_list
.iter()
.zip(y_list.iter())
.map(|(x, y)| keccak(x, y))
.collect();

let x_array_ptr =
get_ptr_from_var_name("x_array", vm, &hint_data.ids_data, &hint_data.ap_tracking)?;
let x_array: Vec<MaybeRelocatable> = x_list
.into_iter()
.flat_map(|x| {
let (xl, xh) = split_128(x);
[
MaybeRelocatable::Int(Felt252::from_bytes_be_slice(&xh)),
MaybeRelocatable::Int(Felt252::from_bytes_be_slice(&xl)),
]
})
.collect();
vm.segments.load_data(x_array_ptr, &x_array)?;

let y_array_ptr =
get_ptr_from_var_name("y_array", vm, &hint_data.ids_data, &hint_data.ap_tracking)?;
let y_array: Vec<MaybeRelocatable> = y_list
.into_iter()
.flat_map(|x| {
let (xl, xh) = split_128(x);
[
MaybeRelocatable::Int(Felt252::from_bytes_be_slice(&xh)),
MaybeRelocatable::Int(Felt252::from_bytes_be_slice(&xl)),
]
})
.collect();
vm.segments.load_data(y_array_ptr, &y_array)?;

let keccak_result_array_ptr = get_ptr_from_var_name(
"keccak_result_array",
vm,
&hint_data.ids_data,
&hint_data.ap_tracking,
)?;
let keccak_result_array: Vec<MaybeRelocatable> = keccak_result_list
.into_iter()
.flat_map(|x| {
let (xl, xh) = split_128(x);
[
MaybeRelocatable::Int(Felt252::from_bytes_be_slice(&xh)),
MaybeRelocatable::Int(Felt252::from_bytes_be_slice(&xl)),
]
})
.collect();
vm.segments
.load_data(keccak_result_array_ptr, &keccak_result_array)?;

insert_value_from_var_name(
"len",
MaybeRelocatable::Int(Felt252::from(keccak_result_array.len() / 2)),
vm,
&hint_data.ids_data,
&hint_data.ap_tracking,
)?;

Ok(())
}
1 change: 1 addition & 0 deletions cairo_vm_hints/src/hints/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod dw_hack;
pub mod encode_packed_256;
pub mod mmr_size_generate;
pub mod print;
File renamed without changes.
12 changes: 12 additions & 0 deletions cairo_vm_hints/src/tests/encode_packed_256.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use super::run_cairo_program;

#[test]
fn test() {
let cairo_runner = run_cairo_program(include_bytes!(
"../../../build/compiled_cairo_files/encode_packed_256_256_test.json"
))
.unwrap();

let execution_resources = cairo_runner.get_execution_resources().unwrap();
println!("n_steps: {}", execution_resources.n_steps)
}
3 changes: 2 additions & 1 deletion cairo_vm_hints/src/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod dw_hack_test;
pub mod dw_hack;
pub mod encode_packed_256;
pub mod is_valid_mmr_size;

use crate::ExtendedHintProcessor;
Expand Down

0 comments on commit 87c955f

Please sign in to comment.