Skip to content

Commit

Permalink
refactor: update doc comments, add test for empty input
Browse files Browse the repository at this point in the history
  • Loading branch information
Fumuran committed Oct 9, 2024
1 parent 4cf59b6 commit b84ae42
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 42 deletions.
36 changes: 19 additions & 17 deletions stdlib/asm/crypto/hashes/rpo.masm
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ end

#! Hashes the memory `start_addr` to `end_addr` given an RPO state specified by 3 words.
#!
#! This requires that `end_addr=start_addr + 2n + 1`, otherwise the procedure will enter an infinite
#! loop. `end_addr` is not inclusive.
#! This requires that `end_addr = start_addr + 2n` where n = {0, 1, 2 ...}, otherwise the procedure
#! will enter an infinite loop.
#!
#! Input: [C, B, A, start_addr, end_addr, ...]
#! Output: [C', B', A', end_addr, end_addr ...]
Expand All @@ -44,7 +44,7 @@ end
#! - `A` is the capacity word that will be used by the hashing function.
#! - `B` is the hash output.
#!
#! Cycles: 4 + 3 * words, where `words` is the `start_addr - end_addr - 1`
#! Cycles: 4 + 3 * words, where `words` is the `start_addr - end_addr`
export.absorb_double_words_from_memory
dup.13 dup.13 neq # (4 cycles )
while.true
Expand All @@ -55,7 +55,7 @@ end

#! Hashes the memory `start_addr` to `end_addr`, handles odd number of elements.
#!
#! Requires `start_addr < end_addr`, `end_addr` is not inclusive.
#! Requires `start_addr end_addr`, `end_addr` is not inclusive.
#!
#! Input: [start_addr, end_addr, ...]
#! Output: [H, ...]
Expand All @@ -65,48 +65,50 @@ end
#! - odd words: 61 cycles + 3 * words
#! where `words` is the `start_addr - end_addr - 1`
export.hash_memory_words
# enforce `start_addr < end_addr`
dup.1 dup.1 u32assert2 u32gt assert
# enforce `start_addr end_addr`
dup.1 dup.1 u32assert2 u32gte assert

# figure out if the range is for an odd number of words (9 cycles)
dup.1 dup.1 sub is_odd
# stack: [is_odd, start_addr, end_addr, ...]
# => [is_odd, start_addr, end_addr, ...]

# make the start/end range even (4 cycles)
movup.2 dup.1 sub
# stack: [end_addr, is_odd, start_addr, ...]
# => [end_addr, is_odd, start_addr, ...]

# move start_addr to the right stack position (1 cycles)
movup.2
# stack: [start_addr, end_addr, is_odd, ...]
# => [start_addr, end_addr, is_odd, ...]

# prepare hasher state (14 cycles)
dup.2 mul.4 push.0.0.0 padw padw
# stack: [C, B, A, start_addr, end_addr, is_odd, ...]
# => [C, B, A, start_addr, end_addr, is_odd, ...]

# (4 + 3 * words cycles)
exec.absorb_double_words_from_memory
# => [C', B', A', end_addr, end_addr, is_odd, ...]

# (1 cycles)
movup.14
# => [is_odd, C', B', A', end_addr, end_addr, ...]

# handle the odd element, if any (12 cycles)
if.true
# start_addr and end_addr are equal after calling `absorb_double_words_from_memory`, and both point
# to the last element. Load the last word (6 cycles)
# start_addr and end_addr are equal after calling `absorb_double_words_from_memory`, and both
# point to the last element. Load the last word (6 cycles)
dropw dup.9 mem_loadw
# => [D, A', end_addr, end_addr, ...]

# set the padding (4 cycles)
padw

# (1 cycles)
hperm
# set the padding and compute the permutation (5 cycles)
padw hperm
end

exec.squeeze_digest
# => [HASH, end_addr, end_addr, ...]

# drop start_addr/end_addr (4 cycles)
movup.4 drop movup.4 drop
# => [HASH]
end

#! Computes hash of Felt values starting at the specified memory address.
Expand Down
63 changes: 38 additions & 25 deletions stdlib/tests/crypto/rpo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,6 @@ fn test_invalid_end_addr() {
err_msg: None,
}
);

// address range can not contain zero elements
let empty_range = "
use.std::crypto::hashes::rpo
begin
push.1000 # end address
push.1000 # start address
exec.rpo::hash_memory_words
end
";
let test = build_test!(empty_range, &[]);
expect_exec_error!(
test,
ExecutionError::FailedAssertion {
clk: 18.into(),
err_code: 0,
err_msg: None,
}
);
}

#[test]
Expand Down Expand Up @@ -354,16 +333,50 @@ fn test_hash_memory() {

#[test]
fn test_hash_memory_empty() {
// try to hash 0 values
let compute_inputs_hash = "
// absorb_double_words_from_memory
let source = "
use.std::crypto::hashes::rpo
begin
push.1000 # end address
push.1000 # start address
padw padw padw # hasher state
exec.rpo::absorb_double_words_from_memory
end
";

let mut expected_stack = vec![0; 12];
expected_stack.push(1000);
expected_stack.push(1000);

build_test!(source, &[]).expect_stack(&expected_stack);

// hash_memory_words
let source = "
use.std::crypto::hashes::rpo
begin
push.1000 # end address
push.1000 # start address
exec.rpo::hash_memory_words
end
";

build_test!(source, &[]).expect_stack(&[0; 4]);

// hash_memory
let source = "
use.std::crypto::hashes::rpo
begin
push.0.1000
push.0 # number of elements to hash
push.1000 # start address
exec.rpo::hash_memory
end
";

build_test!(compute_inputs_hash, &[]).expect_stack(&[0; 16]);
build_test!(source, &[]).expect_stack(&[0; 16]);
}

0 comments on commit b84ae42

Please sign in to comment.