Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement 0x20 - SHA3 Opcode #281

Merged
merged 31 commits into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e4c725c
testing herodotus fct
Quentash Sep 4, 2023
de98b54
preclean
Quentash Sep 5, 2023
ad153f7
cleaned code and tests
Quentash Sep 5, 2023
d0f3ef3
Merge branch 'main' into feat/sha3
Quentash Sep 5, 2023
098b586
merge main
Quentash Sep 5, 2023
39cc37a
forgot to change gas_limit back to 1k
Quentash Sep 5, 2023
5675256
review correction
Quentash Sep 8, 2023
8236936
Merge branch 'main' into feat/sha3
Quentash Sep 8, 2023
daa9d42
added helpers
Quentash Sep 12, 2023
ddcae3f
Merge branch 'main' into feat/sha3
Quentash Sep 12, 2023
66f36a1
soluce2 + check on memory load
Quentash Sep 12, 2023
c0fd0a5
typos
Quentash Sep 12, 2023
4deaf22
added internal sha3 tests
Quentash Sep 13, 2023
ed2a4d1
added helpers tests
Quentash Sep 13, 2023
3af3926
wrong error message
Quentash Sep 13, 2023
479dfaf
Merge branch 'main' into feat/sha3
Quentash Sep 13, 2023
c81a09f
used mod internal instead of trait
Quentash Sep 13, 2023
ecfc4e0
functions and comments rework
Quentash Sep 14, 2023
c4d1ff9
Merge branch 'main' into feat/sha3
Quentash Sep 14, 2023
02f1740
bug correction due to merge
Quentash Sep 14, 2023
dc95762
removed unnecessary computation
Quentash Sep 14, 2023
d9f6bc6
quick fix review
Quentash Sep 14, 2023
04bd9a1
corrected tests names
Quentash Sep 15, 2023
a0fddb5
Merge branch 'main' into feat/sha3
Quentash Sep 15, 2023
e321a0a
docs: added fn docs
enitrat Sep 18, 2023
cd224ff
made compute_words more verbose
Quentash Sep 20, 2023
b229e63
Made helper fcts on u256trait
Quentash Sep 21, 2023
45f4b18
modified comments
Quentash Sep 21, 2023
cfdf5b4
Ensured memory lenght
Quentash Sep 22, 2023
d323bf9
added memory size verification to tests
Quentash Sep 22, 2023
9e5b0b9
Merge branch 'main' into feat/sha3
Quentash Sep 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/evm/src/instructions.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ mod push_operations;
use push_operations::PushOperationsTrait;

mod sha3;
use sha3::Sha3Trait;

mod stop_and_arithmetic_operations;
use stop_and_arithmetic_operations::StopAndArithmeticOperationsTrait;
Expand Down
112 changes: 106 additions & 6 deletions crates/evm/src/instructions/sha3.cairo
Original file line number Diff line number Diff line change
@@ -1,10 +1,110 @@
//! SHA3.

// Internal imports
use evm::context::ExecutionContext;
use evm::context::ExecutionContextTrait;
use evm::context::{ExecutionContext, ExecutionContextTrait, BoxDynamicExecutionContextDestruct};
use evm::stack::StackTrait;
use evm::memory::{InternalMemoryTrait, MemoryTrait};
use evm::errors::EVMError;
use evm::helpers::U256IntoResultU32;
use keccak::{cairo_keccak, u128_split};
use utils::helpers::{u256_to_bytes_array};

/// SHA3 operation.
/// Hashes n bytes in memory at a given offset in memory.
/// # Specification: https://www.evm.codes/#20?fork=shanghai
fn exec_sha3(ref context: ExecutionContext) {}
use array::ArrayTrait;

#[generate_trait]
impl Sha3Impl of Sha3Trait {
/// SHA3 operation : Hashes n bytes in memory at a given offset in memory.
///
/// # Arguments
/// * `offset` - The offset in memory where to read the datas
/// * `size` - The amount of bytes to read
///
/// Format 32 bytes chunk of data read from memory into 64 bits chunk in little endian
/// to be able to call cairro_keccak.
///
/// # Specification: https://www.evm.codes/#20?fork=shanghai
fn exec_sha3(ref self: ExecutionContext) -> Result<(), EVMError> {
let offset: u32 = Into::<u256, Result<u32, EVMError>>::into((self.stack.pop()?))?;
let mut size: u32 = Into::<u256, Result<u32, EVMError>>::into((self.stack.pop()?))?;
let init_size = size;

let mut to_hash: Array<u64> = Default::default();
Eikix marked this conversation as resolved.
Show resolved Hide resolved
let mut last_input: u64 = 0;
let mut slot_to_read = offset;
loop {
if size < 32 {
break;
}
// Pad left the hash input with zeroes for out-of-bound bytes
if slot_to_read > self.memory.bytes_len {
to_hash.append(0);
to_hash.append(0);
to_hash.append(0);
to_hash.append(0);
slot_to_read += 32;
size -= 32;
continue;
}
// Load the 32 words and reverse the bytes order,
let mut loaded = self.memory.load_internal(slot_to_read);
loaded.low = integer::u128_byte_reverse(loaded.low);
loaded.high = integer::u128_byte_reverse(loaded.high);

// Split the loaded word into u64 to feed cairo_keccak
let (high_l, low_l) = u128_split(loaded.high);
let (high_h, low_h) = u128_split(loaded.low);
to_hash.append(low_l);
to_hash.append(high_l);
to_hash.append(low_h);
to_hash.append(high_h);

slot_to_read += 32;
size -= 32;
};

if size > 0 {
Quentash marked this conversation as resolved.
Show resolved Hide resolved
// Load the last 32 bytes chunk containing required bytes
let mut loaded: u256 = if slot_to_read > self.memory.bytes_len {
0
} else {
self.memory.load_internal(slot_to_read)
};

loaded.low = integer::u128_byte_reverse(loaded.low);
loaded.high = integer::u128_byte_reverse(loaded.high);
let (high_l, low_l) = u128_split(loaded.high);
let (high_h, low_h) = u128_split(loaded.low);

// Assign the last input accordingly to required bytes amount
if size < 8 {
last_input = low_l;
} else if size < 16 {
size -= 8;
to_hash.append(low_l);
last_input = high_l;
} else if size < 24 {
size -= 16;
to_hash.append(low_l);
to_hash.append(high_l);
last_input = low_h;
} else {
size -= 24;
to_hash.append(low_l);
to_hash.append(high_l);
to_hash.append(low_h);
last_input = high_h;
}
}

self.memory.ensure_length(offset + init_size);

let mut hash = cairo_keccak(ref to_hash, last_input, size);
hash.low = integer::u128_byte_reverse(hash.low);
hash.high = integer::u128_byte_reverse(hash.high);
let tmp = hash.low;
hash.low = hash.high;
hash.high = tmp;

self.stack.push(hash)
}
}
1 change: 1 addition & 0 deletions crates/evm/src/tests/test_instructions.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ mod test_block_information;
mod test_environment_information;
mod test_push_operations;
mod test_memory_operations;
mod test_sha3;
Loading
Loading