2022-06-30 13:30:24 +00:00
|
|
|
use ff::PrimeFieldBits;
|
|
|
|
use group::Group;
|
2022-06-07 04:02:10 +00:00
|
|
|
|
2022-06-30 13:30:24 +00:00
|
|
|
use crate::prep_bits;
|
2022-06-07 04:02:10 +00:00
|
|
|
|
2022-07-15 05:26:07 +00:00
|
|
|
pub(crate) fn pippenger<G: Group>(pairs: &[(G::Scalar, G)], window: u8) -> G
|
|
|
|
where
|
|
|
|
G::Scalar: PrimeFieldBits,
|
|
|
|
{
|
2022-06-30 13:30:24 +00:00
|
|
|
let bits = prep_bits(pairs, window);
|
2022-06-07 04:02:10 +00:00
|
|
|
|
|
|
|
let mut res = G::identity();
|
2022-06-30 13:30:24 +00:00
|
|
|
for n in (0 .. bits[0].len()).rev() {
|
|
|
|
for _ in 0 .. window {
|
2022-06-07 04:02:10 +00:00
|
|
|
res = res.double();
|
|
|
|
}
|
|
|
|
|
2022-06-30 13:30:24 +00:00
|
|
|
let mut buckets = vec![G::identity(); 2_usize.pow(window.into())];
|
|
|
|
for p in 0 .. bits.len() {
|
|
|
|
buckets[usize::from(bits[p][n])] += pairs[p].1;
|
2022-06-07 04:02:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let mut intermediate_sum = G::identity();
|
|
|
|
for b in (1 .. buckets.len()).rev() {
|
|
|
|
intermediate_sum += buckets[b];
|
|
|
|
res += intermediate_sum;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
res
|
|
|
|
}
|
|
|
|
|
2022-07-15 05:26:07 +00:00
|
|
|
pub(crate) fn pippenger_vartime<G: Group>(pairs: &[(G::Scalar, G)], window: u8) -> G
|
|
|
|
where
|
|
|
|
G::Scalar: PrimeFieldBits,
|
|
|
|
{
|
2022-06-30 13:30:24 +00:00
|
|
|
let bits = prep_bits(pairs, window);
|
2022-06-07 04:02:10 +00:00
|
|
|
|
|
|
|
let mut res = G::identity();
|
2022-06-30 13:30:24 +00:00
|
|
|
for n in (0 .. bits[0].len()).rev() {
|
|
|
|
if n != (bits[0].len() - 1) {
|
|
|
|
for _ in 0 .. window {
|
2022-06-07 04:02:10 +00:00
|
|
|
res = res.double();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-30 13:30:24 +00:00
|
|
|
let mut buckets = vec![G::identity(); 2_usize.pow(window.into())];
|
|
|
|
for p in 0 .. bits.len() {
|
|
|
|
let nibble = usize::from(bits[p][n]);
|
2022-06-07 04:02:10 +00:00
|
|
|
if nibble != 0 {
|
2022-06-30 13:30:24 +00:00
|
|
|
buckets[nibble] += pairs[p].1;
|
2022-06-07 04:02:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut intermediate_sum = G::identity();
|
|
|
|
for b in (1 .. buckets.len()).rev() {
|
|
|
|
intermediate_sum += buckets[b];
|
|
|
|
res += intermediate_sum;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
res
|
|
|
|
}
|