Document multiexp

Bumps the crate version to enable publishing.
This commit is contained in:
Luke Parker 2022-11-07 18:31:20 -05:00
parent be61bff074
commit d714f2202d
No known key found for this signature in database
GPG key ID: F9F1386DB1E119B6
4 changed files with 20 additions and 5 deletions

2
Cargo.lock generated
View file

@ -4695,7 +4695,7 @@ dependencies = [
[[package]]
name = "multiexp"
version = "0.2.1"
version = "0.2.2"
dependencies = [
"dalek-ff-group",
"ff",

View file

@ -1,6 +1,6 @@
[package]
name = "multiexp"
version = "0.2.1"
version = "0.2.2"
description = "Multiexponentation algorithms for ff/group"
license = "MIT"
repository = "https://github.com/serai-dex/serai/tree/develop/crypto/multiexp"

View file

@ -7,19 +7,21 @@ use group::Group;
use crate::{multiexp, multiexp_vartime};
#[cfg(feature = "batch")]
/// A batch verifier intended to verify a series of statements are each equivalent to zero.
#[derive(Clone, Zeroize)]
pub struct BatchVerifier<Id: Copy + Zeroize, G: Group + Zeroize>(Vec<(Id, Vec<(G::Scalar, G)>)>);
#[cfg(feature = "batch")]
impl<Id: Copy + Zeroize, G: Group + Zeroize> BatchVerifier<Id, G>
where
<G as Group>::Scalar: PrimeFieldBits + Zeroize,
{
/// Create a new batch verifier, expected to verify the following amount of statements.
/// This is a size hint and is not required to be accurate.
pub fn new(capacity: usize) -> BatchVerifier<Id, G> {
BatchVerifier(Vec::with_capacity(capacity))
}
/// Queue a statement for batch verification.
pub fn queue<R: RngCore + CryptoRng, I: IntoIterator<Item = (G::Scalar, G)>>(
&mut self,
rng: &mut R,
@ -71,6 +73,7 @@ where
self.0.push((id, pairs.into_iter().map(|(scalar, point)| (scalar * u, point)).collect()));
}
/// Perform batch verification, returning a boolean of if the statements equaled zero.
#[must_use]
pub fn verify_core(&self) -> bool {
let mut flat = self.0.iter().flat_map(|pairs| pairs.1.iter()).cloned().collect::<Vec<_>>();
@ -79,12 +82,14 @@ where
res
}
/// Perform batch verification, zeroizing the statements verified.
pub fn verify(mut self) -> bool {
let res = self.verify_core();
self.zeroize();
res
}
/// Perform batch verification in variable time.
#[must_use]
pub fn verify_vartime(&self) -> bool {
multiexp_vartime(&self.0.iter().flat_map(|pairs| pairs.1.iter()).cloned().collect::<Vec<_>>())
@ -92,6 +97,9 @@ where
.into()
}
/// Perform a binary search to identify which statement does not equal 0, returning None if all
/// statements do. This function will only return the ID of one invalid statement, even if
/// multiple are invalid.
// A constant time variant may be beneficial for robust protocols
pub fn blame_vartime(&self) -> Option<Id> {
let mut slice = self.0.as_slice();
@ -115,12 +123,16 @@ where
.map(|(id, _)| *id)
}
/// Perform constant time batch verification, and if verification fails, identify one faulty
/// statement in variable time.
pub fn verify_with_vartime_blame(mut self) -> Result<(), Id> {
let res = if self.verify_core() { Ok(()) } else { Err(self.blame_vartime().unwrap()) };
self.zeroize();
res
}
/// Perform variable time batch verification, and if verification fails, identify one faulty
/// statement in variable time.
pub fn verify_vartime_with_vartime_blame(&self) -> Result<(), Id> {
if self.verify_vartime() {
Ok(())

View file

@ -160,7 +160,8 @@ fn algorithm(len: usize) -> Algorithm {
}
}
// Performs a multiexp, automatically selecting the optimal algorithm based on amount of pairs
/// Performs a multiexponentation, automatically selecting the optimal algorithm based on the
/// amount of pairs.
pub fn multiexp<G: Group>(pairs: &[(G::Scalar, G)]) -> G
where
G::Scalar: PrimeFieldBits + Zeroize,
@ -173,6 +174,8 @@ where
}
}
/// Performs a multiexponentation in variable time, automatically selecting the optimal algorithm
/// based on the amount of pairs.
pub fn multiexp_vartime<G: Group>(pairs: &[(G::Scalar, G)]) -> G
where
G::Scalar: PrimeFieldBits,