mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-11 18:23:09 +00:00
Replace rotation with exp in compute_evaluation
This commit is contained in:
parent
a74fce0196
commit
925c0bcb5c
@ -28,20 +28,23 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
debug_assert_eq!(last_evals.len(), 1 << arity_bits);
|
||||
|
||||
let g = F::primitive_root_of_unity(arity_bits);
|
||||
let gt = self.constant(g);
|
||||
|
||||
// The evaluation vector needs to be reordered first.
|
||||
let mut evals = last_evals.to_vec();
|
||||
reverse_index_bits_in_place(&mut evals);
|
||||
let mut old_x_index_bits = self.split_le(old_x_index, arity_bits);
|
||||
old_x_index_bits.reverse();
|
||||
let evals = self.rotate_left_from_bits(&old_x_index_bits, &evals);
|
||||
let start = self.exp_from_complement_bits(gt, &old_x_index_bits);
|
||||
let start = self.mul(start, x);
|
||||
let start = self.mul(start, gt);
|
||||
|
||||
// The answer is gotten by interpolating {(x*g^i, P(x*g^i))} and evaluating at beta.
|
||||
let points = g
|
||||
.powers()
|
||||
.map(|y| {
|
||||
let yt = self.constant(y);
|
||||
self.mul(x, yt)
|
||||
self.mul(start, yt)
|
||||
})
|
||||
.zip(evals)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@ -22,20 +22,21 @@ fn compute_evaluation<F: Field + Extendable<D>, const D: usize>(
|
||||
last_evals: &[F::Extension],
|
||||
beta: F::Extension,
|
||||
) -> F::Extension {
|
||||
debug_assert_eq!(last_evals.len(), 1 << arity_bits);
|
||||
let arity = 1 << arity_bits;
|
||||
debug_assert_eq!(last_evals.len(), arity);
|
||||
|
||||
let g = F::primitive_root_of_unity(arity_bits);
|
||||
|
||||
// The evaluation vector needs to be reordered first.
|
||||
let mut evals = last_evals.to_vec();
|
||||
reverse_index_bits_in_place(&mut evals);
|
||||
evals.rotate_left(reverse_bits(old_x_index, arity_bits));
|
||||
|
||||
let rev_x_index = reverse_bits(old_x_index, arity_bits);
|
||||
let start = x * g.exp((arity - rev_x_index) as u64);
|
||||
// The answer is gotten by interpolating {(x*g^i, P(x*g^i))} and evaluating at beta.
|
||||
let points = g
|
||||
.powers()
|
||||
.zip(evals)
|
||||
.map(|(y, e)| ((x * y).into(), e))
|
||||
.map(|(y, e)| ((start * y).into(), e))
|
||||
.collect::<Vec<_>>();
|
||||
let barycentric_weights = barycentric_weights(&points);
|
||||
interpolate(&points, beta, &barycentric_weights)
|
||||
|
||||
@ -155,14 +155,13 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
|
||||
// TODO: Optimize this, maybe with a new gate.
|
||||
// TODO: Test
|
||||
/// Exponentiate `base` to the power of `exponent`, where `exponent < 2^num_bits`.
|
||||
pub fn exp(&mut self, base: Target, exponent: Target, num_bits: usize) -> Target {
|
||||
/// Exponentiate `base` to the power of `exponent`, given by its little-endian bits.
|
||||
pub fn exp_from_bits(&mut self, base: Target, exponent_bits: &[Target]) -> Target {
|
||||
let mut current = base;
|
||||
let one_ext = self.one_extension();
|
||||
let mut product = self.one();
|
||||
let exponent_bits = self.split_le(exponent, num_bits);
|
||||
|
||||
for bit in exponent_bits.into_iter() {
|
||||
for &bit in exponent_bits {
|
||||
let current_ext = self.convert_to_ext(current);
|
||||
let multiplicand = self.select(bit, current_ext, one_ext);
|
||||
product = self.mul(product, multiplicand.0[0]);
|
||||
@ -172,6 +171,32 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
product
|
||||
}
|
||||
|
||||
// TODO: Optimize this, maybe with a new gate.
|
||||
// TODO: Test
|
||||
/// Exponentiate `base` to the power of `exponent`, given by its little-endian bits.
|
||||
pub fn exp_from_complement_bits(&mut self, base: Target, exponent_bits: &[Target]) -> Target {
|
||||
let mut current = base;
|
||||
let one_ext = self.one_extension();
|
||||
let mut product = self.one();
|
||||
|
||||
for &bit in exponent_bits {
|
||||
let current_ext = self.convert_to_ext(current);
|
||||
let multiplicand = self.select(bit, one_ext, current_ext);
|
||||
product = self.mul(product, multiplicand.0[0]);
|
||||
current = self.mul(current, current);
|
||||
}
|
||||
|
||||
product
|
||||
}
|
||||
|
||||
// TODO: Optimize this, maybe with a new gate.
|
||||
// TODO: Test
|
||||
/// Exponentiate `base` to the power of `exponent`, where `exponent < 2^num_bits`.
|
||||
pub fn exp(&mut self, base: Target, exponent: Target, num_bits: usize) -> Target {
|
||||
let exponent_bits = self.split_le(exponent, num_bits);
|
||||
self.exp_from_bits(base, &exponent_bits)
|
||||
}
|
||||
|
||||
/// Exponentiate `base` to the power of a known `exponent`.
|
||||
// TODO: Test
|
||||
pub fn exp_u64(&mut self, base: Target, exponent: u64) -> Target {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user