diff --git a/src/hash.rs b/src/hash.rs index bb59957d..e90cdb0a 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -69,10 +69,12 @@ impl CircuitBuilder { let mut state = [zero; SPONGE_WIDTH]; // Absorb all input chunks. - for input_chunk in inputs.chunks(SPONGE_WIDTH - 1) { + for input_chunk in inputs.chunks(SPONGE_RATE) { + // Overwrite the first r elements with the inputs. This differs from a standard sponge, + // where we would xor or add in the inputs. This is a well-known variant, though, + // sometimes called "overwrite mode". for i in 0..input_chunk.len() { - // TODO: These adds are wasteful. Maybe GMiMCGate should have separates wires to be added in. - state[i] = self.add(state[i], input_chunk[i]); + state[i] = input_chunk[i]; } state = self.permute(state); } @@ -80,7 +82,7 @@ impl CircuitBuilder { // Squeeze until we have the desired number of outputs. let mut outputs = Vec::new(); loop { - for i in 0..(SPONGE_WIDTH - 1) { + for i in 0..SPONGE_RATE { outputs.push(state[i]); if outputs.len() == num_outputs { return outputs; @@ -118,7 +120,7 @@ pub fn hash_n_to_m(mut inputs: Vec, num_outputs: usize, pad: bool) let mut state = [F::ZERO; SPONGE_WIDTH]; // Absorb all input chunks. - for input_chunk in inputs.chunks(SPONGE_WIDTH - 1) { + for input_chunk in inputs.chunks(SPONGE_RATE) { for i in 0..input_chunk.len() { state[i] += input_chunk[i]; } @@ -128,7 +130,7 @@ pub fn hash_n_to_m(mut inputs: Vec, num_outputs: usize, pad: bool) // Squeeze until we have the desired number of outputs. let mut outputs = Vec::new(); loop { - for i in 0..(SPONGE_WIDTH - 1) { + for i in 0..SPONGE_RATE { outputs.push(state[i]); if outputs.len() == num_outputs { return outputs; diff --git a/src/plonk_challenger.rs b/src/plonk_challenger.rs index 4a5a99f1..b745150d 100644 --- a/src/plonk_challenger.rs +++ b/src/plonk_challenger.rs @@ -79,9 +79,11 @@ impl Challenger { /// Absorb any buffered inputs. After calling this, the input buffer will be empty. fn absorb_buffered_inputs(&mut self) { for input_chunk in self.input_buffer.chunks(SPONGE_RATE) { - // Add the inputs to our sponge state. + // Overwrite the first r elements with the inputs. This differs from a standard sponge, + // where we would xor or add in the inputs. This is a well-known variant, though, + // sometimes called "overwrite mode". for (i, &input) in input_chunk.iter().enumerate() { - self.sponge_state[i] = self.sponge_state[i] + input; + self.sponge_state[i] = input; } // Apply the permutation. @@ -177,10 +179,11 @@ impl RecursiveChallenger { builder: &mut CircuitBuilder, ) { for input_chunk in self.input_buffer.chunks(SPONGE_RATE) { - // Add the inputs to our sponge state. + // Overwrite the first r elements with the inputs. This differs from a standard sponge, + // where we would xor or add in the inputs. This is a well-known variant, though, + // sometimes called "overwrite mode". for (i, &input) in input_chunk.iter().enumerate() { - // TODO: These adds are wasteful. Maybe GMiMCGate should have separates wires to be added in. - self.sponge_state[i] = builder.add(self.sponge_state[i], input); + self.sponge_state[i] = input; } // Apply the permutation.