Fix multiexp for 0-length batches

This commit is contained in:
Luke Parker
2022-07-07 00:22:19 -04:00
parent 26cee46950
commit fd817a6958

View File

@@ -56,6 +56,8 @@ pub(crate) fn prep_tables<G: Group>(
#[derive(Clone, Copy, PartialEq, Eq, Debug)] #[derive(Clone, Copy, PartialEq, Eq, Debug)]
enum Algorithm { enum Algorithm {
Null,
Single,
Straus(u8), Straus(u8),
Pippenger(u8) Pippenger(u8)
} }
@@ -107,7 +109,11 @@ Pippenger 8 is more efficient at 875 with 499µs per
*/ */
fn algorithm(len: usize) -> Algorithm { fn algorithm(len: usize) -> Algorithm {
#[cfg(not(debug_assertions))] #[cfg(not(debug_assertions))]
if len < 10 { if len == 0 {
Algorithm::Null
} else if len == 1 {
Algorithm::Single
} else if len < 10 {
// Straus 2 never showed a performance benefit, even with just 2 elements // Straus 2 never showed a performance benefit, even with just 2 elements
Algorithm::Straus(3) Algorithm::Straus(3)
} else if len < 20 { } else if len < 20 {
@@ -149,6 +155,8 @@ fn algorithm(len: usize) -> Algorithm {
// Performs a multiexp, automatically selecting the optimal algorithm based on amount of pairs // Performs a multiexp, automatically selecting the optimal algorithm based on amount of pairs
pub fn multiexp<G: Group>(pairs: &[(G::Scalar, G)]) -> G where G::Scalar: PrimeFieldBits { pub fn multiexp<G: Group>(pairs: &[(G::Scalar, G)]) -> G where G::Scalar: PrimeFieldBits {
match algorithm(pairs.len()) { match algorithm(pairs.len()) {
Algorithm::Null => Group::identity(),
Algorithm::Single => pairs[0].1 * pairs[0].0,
Algorithm::Straus(window) => straus(pairs, window), Algorithm::Straus(window) => straus(pairs, window),
Algorithm::Pippenger(window) => pippenger(pairs, window) Algorithm::Pippenger(window) => pippenger(pairs, window)
} }
@@ -156,6 +164,8 @@ pub fn multiexp<G: Group>(pairs: &[(G::Scalar, G)]) -> G where G::Scalar: PrimeF
pub fn multiexp_vartime<G: Group>(pairs: &[(G::Scalar, G)]) -> G where G::Scalar: PrimeFieldBits { pub fn multiexp_vartime<G: Group>(pairs: &[(G::Scalar, G)]) -> G where G::Scalar: PrimeFieldBits {
match algorithm(pairs.len()) { match algorithm(pairs.len()) {
Algorithm::Null => Group::identity(),
Algorithm::Single => pairs[0].1 * pairs[0].0,
Algorithm::Straus(window) => straus_vartime(pairs, window), Algorithm::Straus(window) => straus_vartime(pairs, window),
Algorithm::Pippenger(window) => pippenger_vartime(pairs, window) Algorithm::Pippenger(window) => pippenger_vartime(pairs, window)
} }