Skip to content

Commit

Permalink
feat: keccak cairo1 helper (#752)
Browse files Browse the repository at this point in the history
  • Loading branch information
enitrat authored Mar 29, 2024
1 parent 53d5cf3 commit ecbbb90
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 0 deletions.
27 changes: 27 additions & 0 deletions crates/contracts/src/cairo1_helpers.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,27 @@ trait IHelpers<T> {
/// `Block number out of range` - If the block number is greater than `current_block - 10`.
/// `0`: The block number is inferior to `first_v0_12_0_block`.
fn get_block_hash(self: @T, block_number: u64) -> felt252;

/// Computes the keccak hash of the provided data.
///
/// The data is expected to be an array of full 64-bit words.
/// The last u64-word to hash may be incomplete and is provided separately.
/// # Arguments
///
/// * `words` - The full 64-bit words to hash.
/// * `last_input_word` - The last word to hash.
/// * `last_input_num_bytes` - The number of bytes in the last word.
///
/// # Returns
/// The EVM-compatible keccak hash of the provided data.
fn keccak(
self: @T, words: Array<u64>, last_input_word: u64, last_input_num_bytes: usize
) -> u256;
}

#[starknet::contract]
mod Cairo1Helpers {
use core::keccak::cairo_keccak;
use core::traits::Into;
use core::{starknet, starknet::SyscallResultTrait};
use evm::errors::EVMError;
Expand All @@ -47,6 +64,7 @@ mod Cairo1Helpers {
use evm::precompiles::sha256::Sha256;

use super::{IPrecompiles, IHelpers};
use utils::helpers::U256Trait;

#[storage]
struct Storage {}
Expand Down Expand Up @@ -76,5 +94,14 @@ mod Cairo1Helpers {
fn get_block_hash(self: @ContractState, block_number: u64) -> felt252 {
starknet::get_block_hash_syscall(block_number).unwrap_syscall()
}

fn keccak(
self: @ContractState,
mut words: Array<u64>,
last_input_word: u64,
last_input_num_bytes: usize
) -> u256 {
cairo_keccak(ref words, last_input_word, last_input_num_bytes).reverse_endianness()
}
}
}
1 change: 1 addition & 0 deletions crates/contracts/src/tests.cairo
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod test_cairo1_helpers;
mod test_contract_account;

mod test_data;
Expand Down
20 changes: 20 additions & 0 deletions crates/contracts/src/tests/test_cairo1_helpers.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use contracts::cairo1_helpers::Cairo1Helpers;
use utils::helpers::BytesUsedTrait;

#[test]
fn test_keccak() {
// "Hello world!"
// where:
// 8031924123371070792 == int.from_bytes(b'Hello wo', 'little')
// 560229490 == int.from_bytes(b'rld!', 'little')
let input = array![8031924123371070792];
let last_input_word: u64 = 560229490;
let last_input_num_bytes = last_input_word.bytes_used();
let state = Cairo1Helpers::contract_state_for_testing();

let res = Cairo1Helpers::Helpers::keccak(
@state, input, last_input_word, last_input_num_bytes.into()
);

assert_eq!(res, 0xecd0e108a98e192af1d2c25055f4e3bed784b5c877204e73219a5203251feaab);
}

0 comments on commit ecbbb90

Please sign in to comment.