diff --git a/plonky2/src/gadgets/curve_windowed_mul.rs b/plonky2/src/gadgets/curve_windowed_mul.rs index 0a461cd7..d6212108 100644 --- a/plonky2/src/gadgets/curve_windowed_mul.rs +++ b/plonky2/src/gadgets/curve_windowed_mul.rs @@ -23,16 +23,20 @@ impl, const D: usize> CircuitBuilder { &mut self, p: &AffinePointTarget, ) -> Vec> { - let mut multiples = vec![self.constant_affine_point(C::GENERATOR_AFFINE)]; - let mut cur = p.clone(); - for _pow in 0..WINDOW_SIZE { - for existing in multiples.clone() { - multiples.push(self.curve_add(&cur, &existing)); - } - cur = self.curve_double(&cur); - } + let neg = { + let mut g = C::GENERATOR_AFFINE; + g.y = -g.y; + self.constant_affine_point(g) + }; - multiples + let mut multiples = vec![self.constant_affine_point(C::GENERATOR_AFFINE)]; + for i in 1..1 << WINDOW_SIZE { + multiples.push(self.curve_add(p, &multiples[i - 1])); + } + for i in 1..1 << WINDOW_SIZE { + multiples[i] = self.curve_add(&neg, &multiples[i]); + } + multiples } pub fn random_access_curve_points( @@ -107,8 +111,7 @@ impl, const D: usize> CircuitBuilder { let zero = self.zero(); let windows = self.split_nonnative_to_4_bit_limbs(n); - let m = C::ScalarField::BITS / WINDOW_SIZE; - for i in (0..m).rev() { + for i in (0..windows.len()).rev() { result = self.curve_repeated_double(&result, WINDOW_SIZE); let window = windows[i]; diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index ff975659..b3842539 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -150,6 +150,7 @@ impl, const D: usize> CircuitBuilder { /// generate the final witness (a grid of wire values), these virtual targets will go away. pub fn add_virtual_target(&mut self) -> Target { let index = self.virtual_target_index; + self.virtual_target_index += 1; Target::VirtualTarget { index } }