From e3cdebe515e4dc4ee6e16e01bd8af25135939798 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 23 Sep 2024 20:15:32 +0100 Subject: [PATCH] feat: swap endianness in-place in keccak implementation (#6128) # Description ## Problem\* Resolves ## Summary\* This PR removes the `temp` array created when swapping the endianness of the `block_bytes` array and just swaps the values in place. This removes some unnecessary reads/writes from brillig. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- noir_stdlib/src/hash/keccak.nr | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/noir_stdlib/src/hash/keccak.nr b/noir_stdlib/src/hash/keccak.nr index c3321b62693..96e53429ac5 100644 --- a/noir_stdlib/src/hash/keccak.nr +++ b/noir_stdlib/src/hash/keccak.nr @@ -35,32 +35,19 @@ pub(crate) fn keccak256(input: [u8; N], message_size: u32) -> [u8; 3 block_bytes[message_size] = 1; block_bytes[real_blocks_bytes - 1] = 0x80; - // keccak lanes interpret memory as little-endian integers, - // means we need to swap our byte ordering let num_limbs = max_blocks * LIMBS_PER_BLOCK; //max_blocks_length / WORD_SIZE; - for i in 0..num_limbs { - let mut temp = [0; WORD_SIZE]; - let word_size_times_i = WORD_SIZE * i; - for j in 0..WORD_SIZE { - temp[j] = block_bytes[word_size_times_i+j]; - } - for j in 0..WORD_SIZE { - block_bytes[word_size_times_i + j] = temp[7 - j]; - } - } - let mut sliced_buffer = Vec::new(); // populate a vector of 64-bit limbs from our byte array for i in 0..num_limbs { - let word_size_times_i = i * WORD_SIZE; - let ws_times_i_plus_7 = word_size_times_i + 7; + let limb_start = WORD_SIZE * i; + let mut sliced = 0; - if (word_size_times_i + WORD_SIZE > max_blocks_length) { - let slice_size = max_blocks_length - word_size_times_i; + if (limb_start + WORD_SIZE > max_blocks_length) { + let slice_size = max_blocks_length - limb_start; let byte_shift = (WORD_SIZE - slice_size) * 8; let mut v = 1; for k in 0..slice_size { - sliced += v * (block_bytes[ws_times_i_plus_7-k] as Field); + sliced += v * (block_bytes[limb_start+k] as Field); v *= 256; } let w = 1 << (byte_shift as u8); @@ -68,7 +55,7 @@ pub(crate) fn keccak256(input: [u8; N], message_size: u32) -> [u8; 3 } else { let mut v = 1; for k in 0..WORD_SIZE { - sliced += v * (block_bytes[ws_times_i_plus_7-k] as Field); + sliced += v * (block_bytes[limb_start+k] as Field); v *= 256; } } @@ -156,4 +143,3 @@ mod tests { assert_eq(keccak256(input, 13), result); } } -