Horner's method

This commit is contained in:
Nicholas Ward 2021-09-30 10:17:51 -07:00
parent ffd069c6ce
commit 1af224d895

View File

@ -84,7 +84,8 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for U32ArithmeticG
let mut combined_low_limbs = F::Extension::ZERO;
let mut combined_high_limbs = F::Extension::ZERO;
let midpoint = Self::num_limbs() / 2;
for j in 0..Self::num_limbs() {
let base = F::Extension::from_canonical_u64(1u64 << Self::limb_bits());
for j in (0..Self::num_limbs()).rev() {
let this_limb = vars.local_wires[Self::wire_ith_output_jth_limb(i, j)];
let max_limb = 1 << Self::limb_bits();
let product = (0..max_limb)
@ -93,13 +94,9 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for U32ArithmeticG
constraints.push(product);
if j < midpoint {
let base = F::Extension::from_canonical_u64(1u64 << (j * Self::limb_bits()));
combined_low_limbs += base * this_limb;
combined_low_limbs = base * combined_low_limbs + this_limb;
} else {
let base = F::Extension::from_canonical_u64(
1u64 << ((j - midpoint) * Self::limb_bits()),
);
combined_high_limbs += base * this_limb;
combined_high_limbs = base * combined_high_limbs + this_limb;
}
}
constraints.push(combined_low_limbs - output_low);
@ -129,7 +126,8 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for U32ArithmeticG
let mut combined_low_limbs = F::ZERO;
let mut combined_high_limbs = F::ZERO;
let midpoint = Self::num_limbs() / 2;
for j in 0..Self::num_limbs() {
let base = F::from_canonical_u64(1u64 << Self::limb_bits());
for j in (0..Self::num_limbs()).rev() {
let this_limb = vars.local_wires[Self::wire_ith_output_jth_limb(i, j)];
let max_limb = 1 << Self::limb_bits();
let product = (0..max_limb)
@ -138,11 +136,9 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for U32ArithmeticG
constraints.push(product);
if j < midpoint {
let base = F::from_canonical_u64(1u64 << (j * Self::limb_bits()));
combined_low_limbs += base * this_limb;
combined_low_limbs = base * combined_low_limbs + this_limb;
} else {
let base = F::from_canonical_u64(1u64 << ((j - midpoint) * Self::limb_bits()));
combined_high_limbs += base * this_limb;
combined_high_limbs = base * combined_high_limbs + this_limb;
}
}
constraints.push(combined_low_limbs - output_low);
@ -178,7 +174,9 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for U32ArithmeticG
let mut combined_low_limbs = builder.zero_extension();
let mut combined_high_limbs = builder.zero_extension();
let midpoint = Self::num_limbs() / 2;
for j in 0..Self::num_limbs() {
let base = builder
.constant_extension(F::Extension::from_canonical_u64(1u64 << Self::limb_bits()));
for j in (0..Self::num_limbs()).rev() {
let this_limb = vars.local_wires[Self::wire_ith_output_jth_limb(i, j)];
let max_limb = 1 << Self::limb_bits();
@ -192,17 +190,11 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for U32ArithmeticG
constraints.push(product);
if j < midpoint {
let base = builder.constant_extension(F::Extension::from_canonical_u64(
1u64 << (j * Self::limb_bits()),
));
combined_low_limbs =
builder.mul_add_extension(base, this_limb, combined_low_limbs);
builder.mul_add_extension(base, combined_low_limbs, this_limb);
} else {
let base = builder.constant_extension(F::Extension::from_canonical_u64(
1u64 << ((j - midpoint) * Self::limb_bits()),
));
combined_high_limbs =
builder.mul_add_extension(base, this_limb, combined_high_limbs);
builder.mul_add_extension(base, combined_high_limbs, this_limb);
}
}