diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e53a69d7..788623c9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -158,7 +158,7 @@ #### Stdlib - Added `init_no_padding` procedure to `std::crypto::hashes::native` (#1313). -- [BREAKING] `native` module was renamed to the `pro`, `hash_memory` procedure was renamed to the `hash_memory_words` (#1368). +- [BREAKING] `native` module was renamed to the `rpo`, `hash_memory` procedure was renamed to the `hash_memory_words` (#1368). - Added `hash_memory` procedure to `std::crypto::hashes::rpo` (#1368). #### VM Internals diff --git a/stdlib/asm/crypto/hashes/rpo.masm b/stdlib/asm/crypto/hashes/rpo.masm index c852de82a..b0357d50c 100644 --- a/stdlib/asm/crypto/hashes/rpo.masm +++ b/stdlib/asm/crypto/hashes/rpo.masm @@ -5,6 +5,7 @@ #! #! Input: [] #! Ouptut: [PERM, PERM, PERM, ...] +#! #! Cycles: 12 export.init_no_padding padw padw padw @@ -14,7 +15,11 @@ end #! #! Input: [C, B, A, ...] #! Ouptut: [HASH, ...] -#! where: For the native RPO hasher HASH is B. +#! +#! Where : +#! - `A` is the capacity word that will be used by the hashing function. +#! - `B` is the hash output. +#! #! Cycles: 9 export.squeeze_digest # drop the first rate word (4 cycles) @@ -32,12 +37,14 @@ end #! This requires that `end_addr=start_addr + 2n + 1`, otherwise the procedure will enter an infinite #! loop. `end_addr` is not inclusive. #! -#! Stack transition: #! Input: [C, B, A, start_addr, end_addr, ...] #! Output: [C', B', A', end_addr, end_addr ...] -#! Cycles: 4 + 3 * words, where `words` is the `start_addr - end_addr - 1` #! -#! Where `A` is the capacity word that will be used by the hashing function, and `B'` the hash output. +#! Where : +#! - `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` export.absorb_double_words_from_memory dup.13 dup.13 neq # (4 cycles ) while.true @@ -50,12 +57,13 @@ end #! #! Requires `start_addr < end_addr`, `end_addr` is not inclusive. #! -#! Stack transition: #! Input: [start_addr, end_addr, ...] #! Output: [H, ...] +#! #! Cycles: -#! even words: 49 cycles + 3 * words -#! odd words: 61 cycles + 3 * words +#! - even words: 49 cycles + 3 * words +#! - 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 @@ -109,20 +117,16 @@ end #! #! Inputs: [ptr, num_elements] #! Outputs: [HASH] +#! #! Cycles: #! - If number of elements divides by 8: 47 cycles + 3 * words #! - Else: 180 cycles + 3 * words -#! -#! Panics if number of inputs equals 0. +#! where `words` is the number of quads of input values. export.hash_memory # move number of inputs to the top of the stack swap # => [num_elements, ptr] - # check that number of inputs greater than 0 - dup eq.0 assertz - # => [num_elements, ptr] - # get the number of double words u32divmod.8 swap # => [num_elements/8, num_elements%8, ptr] diff --git a/stdlib/tests/crypto/rpo.rs b/stdlib/tests/crypto/rpo.rs index fcc86e9c3..b1eac29e1 100644 --- a/stdlib/tests/crypto/rpo.rs +++ b/stdlib/tests/crypto/rpo.rs @@ -353,7 +353,7 @@ fn test_hash_memory() { } #[test] -fn test_hash_memory_fail() { +fn test_hash_memory_empty() { // try to hash 0 values let compute_inputs_hash = " use.std::crypto::hashes::rpo @@ -365,5 +365,5 @@ fn test_hash_memory_fail() { end "; - assert!(build_test!(compute_inputs_hash, &[]).execute().is_err()); + build_test!(compute_inputs_hash, &[]).expect_stack(&[0; 16]); }