More optimizations

This commit is contained in:
wborgeaud 2021-08-09 12:39:37 +02:00
parent ed8dc9fdc7
commit 4b44578ffa
5 changed files with 69 additions and 17 deletions

View File

@ -105,6 +105,10 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
self.constant_extension(F::Extension::TWO)
}
pub fn neg_one_extension(&mut self) -> ExtensionTarget<D> {
self.constant_extension(F::Extension::NEG_ONE)
}
pub fn zero_ext_algebra(&mut self) -> ExtensionAlgebraTarget<D> {
self.constant_ext_algebra(ExtensionAlgebra::ZERO)
}

View File

@ -347,12 +347,13 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
self.mul_three_extension(x, x, x)
}
pub fn mul_ext_algebra(
/// Returns `a*b + c`.
pub fn mul_add_ext_algebra(
&mut self,
a: ExtensionAlgebraTarget<D>,
b: ExtensionAlgebraTarget<D>,
c: ExtensionAlgebraTarget<D>,
) -> ExtensionAlgebraTarget<D> {
let zero = self.zero_extension();
let mut inner = vec![vec![]; D];
let mut inner_w = vec![vec![]; D];
for i in 0..D {
@ -366,14 +367,23 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
let res = inner_w
.into_iter()
.zip(inner)
.map(|(vecs_w, vecs)| {
let acc = self.inner_product_extension(F::Extension::W, zero, vecs_w);
self.inner_product_extension(F::ONE, acc, vecs)
.zip(c.0)
.map(|((pairs_w, pairs), ci)| {
let acc = self.inner_product_extension(F::Extension::W, ci, pairs_w);
self.inner_product_extension(F::ONE, acc, pairs)
})
.collect::<Vec<_>>();
ExtensionAlgebraTarget(res.try_into().unwrap())
}
pub fn mul_ext_algebra(
&mut self,
a: ExtensionAlgebraTarget<D>,
b: ExtensionAlgebraTarget<D>,
) -> ExtensionAlgebraTarget<D> {
let zero = self.zero_ext_algebra();
self.mul_add_ext_algebra(a, b, zero)
}
/// Multiply 3 `ExtensionTarget`s with 1 `ArithmeticExtensionGate`s.
pub fn mul_three_extension(
@ -457,17 +467,42 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
self.mul_extension(a_ext, b)
}
/// Returns `a * b`, where `b` is in the extension of the extension field, and `a` is in the
/// Returns `a * b + c`, where `b,c` are in the extension algebra and `a` in the extension field.
/// extension field.
pub fn scalar_mul_add_ext_algebra(
&mut self,
a: ExtensionTarget<D>,
b: ExtensionAlgebraTarget<D>,
mut c: ExtensionAlgebraTarget<D>,
) -> ExtensionAlgebraTarget<D> {
for i in 0..D / 2 {
let res = self.double_arithmetic_extension(
F::ONE,
F::ONE,
a,
b.0[2 * i],
c.0[2 * i],
a,
b.0[2 * i + 1],
c.0[2 * i + 1],
);
c.0[2 * i] = res.0;
c.0[2 * i + 1] = res.1;
}
if D.is_odd() {
c.0[D - 1] = self.arithmetic_extension(F::ONE, F::ONE, a, b.0[D - 1], c.0[D - 1]);
}
c
}
/// Returns `a * b`, where `b,c` are in the extension algebra and `a` in the extension field.
pub fn scalar_mul_ext_algebra(
&mut self,
a: ExtensionTarget<D>,
mut b: ExtensionAlgebraTarget<D>,
b: ExtensionAlgebraTarget<D>,
) -> ExtensionAlgebraTarget<D> {
for i in 0..D {
b.0[i] = self.mul_extension(a, b.0[i]);
}
b
let zero = self.zero_ext_algebra();
self.scalar_mul_add_ext_algebra(a, b, zero)
}
/// Exponentiate `base` to the power of `2^power_log`.

View File

@ -50,8 +50,10 @@ impl<const D: usize> PolynomialCoeffsExtAlgebraTarget<D> {
{
let mut acc = builder.zero_ext_algebra();
for &c in self.0.iter().rev() {
let tmp = builder.scalar_mul_ext_algebra(point, acc);
acc = builder.add_ext_algebra(tmp, c);
// let tmp = builder.scalar_mul_ext_algebra(point, acc);
// acc = builder.add_ext_algebra(tmp, c);
acc = builder.scalar_mul_add_ext_algebra(point, acc, c);
// acc = builder.add_ext_algebra(tmp, c);
}
acc
}

View File

@ -160,6 +160,8 @@ impl<F: Extendable<D>, const D: usize, const R: usize> Gate<F, D> for GMiMCGate<
builder: &mut CircuitBuilder<F, D>,
vars: EvaluationTargets<D>,
) -> Vec<ExtensionTarget<D>> {
let one = builder.one_extension();
let neg_one = builder.neg_one_extension();
let mut constraints = Vec::with_capacity(self.num_constraints());
let swap = vars.local_wires[Self::WIRE_SWAP];
@ -195,8 +197,18 @@ impl<F: Extendable<D>, const D: usize, const R: usize> Gate<F, D> for GMiMCGate<
let cubing_input_wire = vars.local_wires[Self::wire_cubing_input(r)];
constraints.push(builder.sub_extension(cubing_input, cubing_input_wire));
let f = builder.cube_extension(cubing_input_wire);
addition_buffer = builder.add_extension(addition_buffer, f);
state[active] = builder.sub_extension(state[active], f);
let tmp = builder.double_arithmetic_extension(
F::ONE,
F::ONE,
one,
addition_buffer,
f,
neg_one,
f,
state[active],
);
addition_buffer = tmp.0;
state[active] = tmp.1;
}
for i in 0..W {

View File

@ -121,9 +121,8 @@ impl<F: Extendable<D>, const D: usize> Gate<F, D> for ReducingGate<D> {
let mut constraints = Vec::new();
let mut acc = old_acc;
for i in 0..self.num_coeffs {
let mut tmp = builder.mul_ext_algebra(acc, alpha);
let coeff = builder.convert_to_ext_algebra(coeffs[i]);
tmp = builder.add_ext_algebra(tmp, coeff);
let mut tmp = builder.mul_add_ext_algebra(acc, alpha, coeff);
tmp = builder.sub_ext_algebra(tmp, accs[i]);
constraints.push(tmp);
acc = accs[i];