Merge pull request #157 from mir-protocol/remove_reverse_limbs

Remove reversed limbs sum
This commit is contained in:
wborgeaud 2021-08-05 21:37:58 +02:00 committed by GitHub
commit a255c320ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 12 additions and 47 deletions

View File

@ -29,14 +29,6 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
self.range_check(x, (64 - leading_zeros) as usize); self.range_check(x, (64 - leading_zeros) as usize);
} }
pub(crate) fn reverse_limbs<const B: usize>(&mut self, x: Target, num_limbs: usize) -> Target {
let gate = self.add_gate(BaseSumGate::<B>::new(num_limbs), vec![]);
let sum = Target::wire(gate, BaseSumGate::<B>::WIRE_SUM);
self.route(x, sum);
Target::wire(gate, BaseSumGate::<B>::WIRE_REVERSED_SUM)
}
/// Takes an iterator of bits `(b_i)` and returns `sum b_i * 2^i`, i.e., /// Takes an iterator of bits `(b_i)` and returns `sum b_i * 2^i`, i.e.,
/// the number with little-endian bit representation given by `bits`. /// the number with little-endian bit representation given by `bits`.
pub(crate) fn le_sum( pub(crate) fn le_sum(
@ -119,9 +111,6 @@ mod tests {
builder.route(limbs[1], three); builder.route(limbs[1], three);
builder.route(limbs[2], five); builder.route(limbs[2], five);
builder.route(limbs[3], one); builder.route(limbs[3], one);
let rev = builder.constant(F::from_canonical_u64(11));
let revt = builder.reverse_limbs::<2>(xt, 9);
builder.route(revt, rev);
builder.assert_leading_zeros(xt, 64 - 9); builder.assert_leading_zeros(xt, 64 - 9);
let data = builder.build(); let data = builder.build();

View File

@ -11,8 +11,7 @@ use crate::plonk::circuit_builder::CircuitBuilder;
use crate::plonk::plonk_common::{reduce_with_powers, reduce_with_powers_ext_recursive}; use crate::plonk::plonk_common::{reduce_with_powers, reduce_with_powers_ext_recursive};
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
/// A gate which can decompose a number into base B little-endian limbs, /// A gate which can decompose a number into base B little-endian limbs.
/// and compute the limb-reversed (i.e. big-endian) sum.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct BaseSumGate<const B: usize> { pub struct BaseSumGate<const B: usize> {
num_limbs: usize, num_limbs: usize,
@ -24,8 +23,7 @@ impl<const B: usize> BaseSumGate<B> {
} }
pub const WIRE_SUM: usize = 0; pub const WIRE_SUM: usize = 0;
pub const WIRE_REVERSED_SUM: usize = 1; pub const START_LIMBS: usize = 1;
pub const START_LIMBS: usize = 2;
/// Returns the index of the `i`th limb wire. /// Returns the index of the `i`th limb wire.
pub fn limbs(&self) -> Range<usize> { pub fn limbs(&self) -> Range<usize> {
@ -40,13 +38,9 @@ impl<F: Extendable<D>, const D: usize, const B: usize> Gate<F, D> for BaseSumGat
fn eval_unfiltered(&self, vars: EvaluationVars<F, D>) -> Vec<F::Extension> { fn eval_unfiltered(&self, vars: EvaluationVars<F, D>) -> Vec<F::Extension> {
let sum = vars.local_wires[Self::WIRE_SUM]; let sum = vars.local_wires[Self::WIRE_SUM];
let reversed_sum = vars.local_wires[Self::WIRE_REVERSED_SUM]; let limbs = vars.local_wires[self.limbs()].to_vec();
let mut limbs = vars.local_wires[self.limbs()].to_vec();
let computed_sum = reduce_with_powers(&limbs, F::Extension::from_canonical_usize(B)); let computed_sum = reduce_with_powers(&limbs, F::Extension::from_canonical_usize(B));
limbs.reverse(); let mut constraints = vec![computed_sum - sum];
let computed_reversed_sum =
reduce_with_powers(&limbs, F::Extension::from_canonical_usize(B));
let mut constraints = vec![computed_sum - sum, computed_reversed_sum - reversed_sum];
for limb in limbs { for limb in limbs {
constraints.push( constraints.push(
(0..B) (0..B)
@ -59,12 +53,9 @@ impl<F: Extendable<D>, const D: usize, const B: usize> Gate<F, D> for BaseSumGat
fn eval_unfiltered_base(&self, vars: EvaluationVarsBase<F>) -> Vec<F> { fn eval_unfiltered_base(&self, vars: EvaluationVarsBase<F>) -> Vec<F> {
let sum = vars.local_wires[Self::WIRE_SUM]; let sum = vars.local_wires[Self::WIRE_SUM];
let reversed_sum = vars.local_wires[Self::WIRE_REVERSED_SUM]; let limbs = vars.local_wires[self.limbs()].to_vec();
let mut limbs = vars.local_wires[self.limbs()].to_vec();
let computed_sum = reduce_with_powers(&limbs, F::from_canonical_usize(B)); let computed_sum = reduce_with_powers(&limbs, F::from_canonical_usize(B));
limbs.reverse(); let mut constraints = vec![computed_sum - sum];
let computed_reversed_sum = reduce_with_powers(&limbs, F::from_canonical_usize(B));
let mut constraints = vec![computed_sum - sum, computed_reversed_sum - reversed_sum];
for limb in limbs { for limb in limbs {
constraints.push((0..B).map(|i| limb - F::from_canonical_usize(i)).product()); constraints.push((0..B).map(|i| limb - F::from_canonical_usize(i)).product());
} }
@ -78,15 +69,9 @@ impl<F: Extendable<D>, const D: usize, const B: usize> Gate<F, D> for BaseSumGat
) -> Vec<ExtensionTarget<D>> { ) -> Vec<ExtensionTarget<D>> {
let base = builder.constant(F::from_canonical_usize(B)); let base = builder.constant(F::from_canonical_usize(B));
let sum = vars.local_wires[Self::WIRE_SUM]; let sum = vars.local_wires[Self::WIRE_SUM];
let reversed_sum = vars.local_wires[Self::WIRE_REVERSED_SUM]; let limbs = vars.local_wires[self.limbs()].to_vec();
let mut limbs = vars.local_wires[self.limbs()].to_vec();
let computed_sum = reduce_with_powers_ext_recursive(builder, &limbs, base); let computed_sum = reduce_with_powers_ext_recursive(builder, &limbs, base);
limbs.reverse(); let mut constraints = vec![builder.sub_extension(computed_sum, sum)];
let computed_reversed_sum = reduce_with_powers_ext_recursive(builder, &limbs, base);
let mut constraints = vec![
builder.sub_extension(computed_sum, sum),
builder.sub_extension(computed_reversed_sum, reversed_sum),
];
for limb in limbs { for limb in limbs {
constraints.push({ constraints.push({
let mut acc = builder.one_extension(); let mut acc = builder.one_extension();
@ -116,9 +101,9 @@ impl<F: Extendable<D>, const D: usize, const B: usize> Gate<F, D> for BaseSumGat
vec![Box::new(gen)] vec![Box::new(gen)]
} }
// 2 for the sum and reversed sum, then `num_limbs` for the limbs. // 1 for the sum then `num_limbs` for the limbs.
fn num_wires(&self) -> usize { fn num_wires(&self) -> usize {
self.num_limbs + 2 1 + self.num_limbs
} }
fn num_constants(&self) -> usize { fn num_constants(&self) -> usize {
@ -130,9 +115,9 @@ impl<F: Extendable<D>, const D: usize, const B: usize> Gate<F, D> for BaseSumGat
B B
} }
// 2 for checking the sum and reversed sum, then `num_limbs` for range-checking the limbs. // 1 for checking the sum then `num_limbs` for range-checking the limbs.
fn num_constraints(&self) -> usize { fn num_constraints(&self) -> usize {
2 + self.num_limbs 1 + self.num_limbs
} }
} }
@ -167,15 +152,6 @@ impl<F: Field, const B: usize> SimpleGenerator<F> for BaseSplitGenerator<B> {
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let b_field = F::from_canonical_usize(B);
let reversed_sum = limbs_value
.iter()
.fold(F::ZERO, |acc, &x| acc * b_field + x);
out_buffer.set_target(
Target::wire(self.gate_index, BaseSumGate::<B>::WIRE_REVERSED_SUM),
reversed_sum,
);
for (b, b_value) in limbs.zip(limbs_value) { for (b, b_value) in limbs.zip(limbs_value) {
out_buffer.set_target(b, b_value); out_buffer.set_target(b, b_value);
} }