@@ -44,11 +44,24 @@ pub fn keccak256<let N: u32>(input: [u8; N], message_size: u32) -> [u8; 32] {
4444
4545 let mut sliced = 0 ;
4646 let mut v = 1 ;
47- for k in 0 ..WORD_SIZE {
48- sliced += v * (block_bytes [limb_start + k ] as Field );
49- v *= 256 ;
50- }
51-
47+ sliced += v * (block_bytes [limb_start ] as Field );
48+ v *= 256 ;
49+ sliced += v * (block_bytes [limb_start + 1 ] as Field );
50+ v *= 256 ;
51+ sliced += v * (block_bytes [limb_start + 2 ] as Field );
52+ v *= 256 ;
53+ sliced += v * (block_bytes [limb_start + 3 ] as Field );
54+ v *= 256 ;
55+ sliced += v * (block_bytes [limb_start + 4 ] as Field );
56+ v *= 256 ;
57+ sliced += v * (block_bytes [limb_start + 5 ] as Field );
58+ v *= 256 ;
59+ sliced += v * (block_bytes [limb_start + 6 ] as Field );
60+ v *= 256 ;
61+ sliced += v * (block_bytes [limb_start + 7 ] as Field );
62+ v *= 256 ;
63+
64+ sliced .assert_max_bit_size ::<64 >();
5265 sliced_buffer [i ] = sliced as u64 ;
5366 }
5467
@@ -57,9 +70,23 @@ pub fn keccak256<let N: u32>(input: [u8; N], message_size: u32) -> [u8; 32] {
5770 // `real_max_blocks` is guaranteed to at least be `1`
5871 // We peel out the first block as to avoid a conditional inside of the loop.
5972 // Otherwise, a dynamic predicate can cause a blowup in a constrained runtime.
60- for j in 0 ..LIMBS_PER_BLOCK {
61- state [j ] = sliced_buffer [j ];
62- }
73+ state [0 ] = sliced_buffer [0 ];
74+ state [1 ] = sliced_buffer [1 ];
75+ state [2 ] = sliced_buffer [2 ];
76+ state [3 ] = sliced_buffer [3 ];
77+ state [4 ] = sliced_buffer [4 ];
78+ state [5 ] = sliced_buffer [5 ];
79+ state [6 ] = sliced_buffer [6 ];
80+ state [7 ] = sliced_buffer [7 ];
81+ state [8 ] = sliced_buffer [8 ];
82+ state [9 ] = sliced_buffer [9 ];
83+ state [10 ] = sliced_buffer [10 ];
84+ state [11 ] = sliced_buffer [11 ];
85+ state [12 ] = sliced_buffer [12 ];
86+ state [13 ] = sliced_buffer [13 ];
87+ state [14 ] = sliced_buffer [14 ];
88+ state [15 ] = sliced_buffer [15 ];
89+ state [16 ] = sliced_buffer [16 ];
6390 state = keccakf1600 (state );
6491
6592 let state = if is_unconstrained () {
@@ -91,32 +118,69 @@ pub fn keccak256<let N: u32>(input: [u8; N], message_size: u32) -> [u8; 32] {
91118
92119 //3. sponge_squeeze
93120 let mut result = [0 ; 32 ];
94- for i in 0 ..4 {
95- let lane = state [i ] as Field ;
96- let lane_le : [u8 ; 8 ] = lane .to_le_bytes ();
97- for j in 0 ..8 {
98- result [8 * i + j ] = lane_le [j ];
99- }
100- }
121+ let lane = state [1 ] as Field ;
122+ let lane_le : [u8 ; 8 ] = lane .to_le_bytes ();
123+ result [0 ] = lane_le [0 ];
124+ result [1 ] = lane_le [1 ];
125+ result [2 ] = lane_le [2 ];
126+ result [3 ] = lane_le [3 ];
127+ result [4 ] = lane_le [4 ];
128+ result [5 ] = lane_le [5 ];
129+ result [6 ] = lane_le [6 ];
130+ result [7 ] = lane_le [7 ];
131+
132+ let lane = state [1 ] as Field ;
133+ let lane_le : [u8 ; 8 ] = lane .to_le_bytes ();
134+ result [8 * 1 ] = lane_le [0 ];
135+ result [8 * 1 + 1 ] = lane_le [1 ];
136+ result [8 * 1 + 2 ] = lane_le [2 ];
137+ result [8 * 1 + 3 ] = lane_le [3 ];
138+ result [8 * 1 + 4 ] = lane_le [4 ];
139+ result [8 * 1 + 5 ] = lane_le [5 ];
140+ result [8 * 1 + 6 ] = lane_le [6 ];
141+ result [8 * 1 + 7 ] = lane_le [7 ];
142+
143+ let lane = state [2 ] as Field ;
144+ let lane_le : [u8 ; 8 ] = lane .to_le_bytes ();
145+ result [8 * 2 ] = lane_le [0 ];
146+ result [8 * 2 + 1 ] = lane_le [1 ];
147+ result [8 * 2 + 2 ] = lane_le [2 ];
148+ result [8 * 2 + 3 ] = lane_le [3 ];
149+ result [8 * 2 + 4 ] = lane_le [4 ];
150+ result [8 * 2 + 5 ] = lane_le [5 ];
151+ result [8 * 2 + 6 ] = lane_le [6 ];
152+ result [8 * 2 + 7 ] = lane_le [7 ];
153+
154+ let lane = state [3 ] as Field ;
155+ let lane_le : [u8 ; 8 ] = lane .to_le_bytes ();
156+ result [8 * 3 ] = lane_le [0 ];
157+ result [8 * 3 + 1 ] = lane_le [1 ];
158+ result [8 * 3 + 2 ] = lane_le [2 ];
159+ result [8 * 3 + 3 ] = lane_le [3 ];
160+ result [8 * 3 + 4 ] = lane_le [4 ];
161+ result [8 * 3 + 5 ] = lane_le [5 ];
162+ result [8 * 3 + 6 ] = lane_le [6 ];
163+ result [8 * 3 + 7 ] = lane_le [7 ];
164+
101165 result
102166}
103167
104168// Apply Keccak padding to the block_bytes array
105169// Append 0x01 after message, then 0x80 at end of block
106170// If both padding bytes collide at the same byte, combine them as 0x81
171+ #[inline_always]
107172pub (crate ) fn apply_keccak_padding <let BLOCK_BYTES : u32 >(
108173 block_bytes : &mut [u8 ; BLOCK_BYTES ],
109174 message_size : u32 ,
110175 real_max_blocks : u32 ,
111176) {
112177 let real_blocks_bytes = real_max_blocks * BLOCK_SIZE_IN_BYTES ;
113178
114- block_bytes [message_size ] = 0x01 ;
115-
116179 if message_size == real_blocks_bytes - 1 {
117180 // Combine both padding bits: 0x01 | 0x80 = 0x81
118181 block_bytes [message_size ] = 0x81 ;
119182 } else {
183+ block_bytes [message_size ] = 0x01 ;
120184 block_bytes [real_blocks_bytes - 1 ] = 0x80 ;
121185 }
122186}
0 commit comments