mirror of
https://github.com/saymrwulf/pasta_curves-source.git
synced 2026-09-04 20:03:39 +00:00
Implement small_multiexp() in arithmetic.rs
This commit is contained in:
parent
153f721c1d
commit
f2fc068db0
2 changed files with 40 additions and 11 deletions
|
|
@ -180,6 +180,39 @@ fn multiexp_serial<C: CurveAffine>(coeffs: &[C::Scalar], bases: &[C], acc: &mut
|
|||
}
|
||||
}
|
||||
|
||||
/// Performs a small multi-exponentiation operation.
|
||||
/// Uses the double-and-add algorithm with doublings shared across points.
|
||||
|
||||
pub fn small_multiexp<C: CurveAffine>(coeffs: &[C::Scalar], bases: &[C]) -> C::Projective {
|
||||
// Gets the bit at position `i`. Bits are numbered from 0 (least significant) to 7 (most significant).
|
||||
fn get_bit_at(byte: u8, i: usize) -> bool {
|
||||
if i < 8 {
|
||||
((byte >> i) & 1u8) != 0
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
let coeffs: Vec<[u8; 32]> = coeffs.iter().map(|a| a.to_bytes()).collect();
|
||||
let mut acc = C::Projective::zero();
|
||||
|
||||
// for byte idx
|
||||
for byte_idx in (0..32).rev() {
|
||||
// for bit idx
|
||||
for bit_idx in (0..8).rev() {
|
||||
acc = acc.double();
|
||||
// for each coeff
|
||||
for coeff_idx in 0..coeffs.len() {
|
||||
if get_bit_at(coeffs[coeff_idx][byte_idx], bit_idx) {
|
||||
acc = acc + &bases[coeff_idx].to_projective();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
acc
|
||||
}
|
||||
|
||||
/// Performs a multi-exponentiation operation.
|
||||
///
|
||||
/// This function will panic if coeffs and bases have a different length.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use super::super::{Coeff, Polynomial};
|
||||
use super::{Blind, OpeningProof, Params};
|
||||
use crate::arithmetic::{
|
||||
best_multiexp, compute_inner_product, get_challenge_scalar, parallelize, Challenge, Curve,
|
||||
best_multiexp, compute_inner_product, get_challenge_scalar, small_multiexp, Challenge, Curve,
|
||||
CurveAffine, Field,
|
||||
};
|
||||
use crate::transcript::Hasher;
|
||||
|
|
@ -220,15 +220,11 @@ fn parallel_generator_collapse<C: CurveAffine>(
|
|||
challenge_inv: C::Scalar,
|
||||
) {
|
||||
let len = g.len() / 2;
|
||||
let (mut g_lo, g_hi) = g.split_at_mut(len);
|
||||
let (g_lo, g_hi) = g.split_at_mut(len);
|
||||
|
||||
parallelize(&mut g_lo, |g_lo, start| {
|
||||
let g_hi = &g_hi[start..];
|
||||
let mut tmp = Vec::with_capacity(g_lo.len());
|
||||
for (g_lo, g_hi) in g_lo.iter().zip(g_hi.iter()) {
|
||||
// TODO: could use multiexp
|
||||
tmp.push(((*g_lo) * challenge_inv) + &((*g_hi) * challenge));
|
||||
}
|
||||
C::Projective::batch_to_affine(&tmp, g_lo);
|
||||
});
|
||||
let mut tmp = Vec::with_capacity(g_lo.len());
|
||||
for (g_lo, g_hi) in g_lo.iter().zip(g_hi.iter()) {
|
||||
tmp.push(small_multiexp(&[challenge_inv, challenge], &[*g_lo, *g_hi]));
|
||||
}
|
||||
C::Projective::batch_to_affine(&tmp, g_lo);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue