Add a trait for multiscalar multiplication with precomputation.

This commit is contained in:
Henry de Valence 2018-05-03 15:31:08 -07:00
parent ff0dc4a3db
commit 98e713ef91

View file

@ -224,6 +224,166 @@ pub trait VartimeMultiscalarMul {
}
}
/// A trait for constant-time multiscalar multiplication with precomputation.
///
/// A general multiscalar multiplication with precomputation can be written as
/// $$
/// Q = a_1 A_1 + \cdots + a_n A_n + b_1 B_1 + \cdots + b_m B_m,
/// $$
/// where the \\(B_i\\) are *static* points, for which precomputation
/// is possible, and the \\(A_j\\) are *dynamic* points, for which
/// precomputation is not possible.
pub trait PrecomputedMultiscalarMul: Sized {
/// The type of point to be multiplied, e.g., `RistrettoPoint`.
type Point;
/// Given the static points \\( B_i \\), perform precomputation
/// and return the precomputation data.
fn new<I>(static_points: I) -> Self
where
I: IntoIterator,
I::Item: Borrow<Self::Point>;
/// Given `static_scalars`, an iterator of (possibly secret)
/// scalars \\(b_i\\), `dynamic_scalars`, an iterator of (possibly
/// secret) scalars \\(a_i\\), and `dynamic_points`, an iterator
/// of points \\(A_i\\), compute
/// $$
/// Q = a_1 A_1 + \cdots + a_n A_n + b_1 B_1 + \cdots + b_m B_m,
/// $$
/// where the \\(B_j\\) are the points that were supplied to `new`.
///
/// It is an error to call this function with iterators of
/// inconsistent lengths.
///
/// The trait bound aims for maximum flexibility: the inputs must be
/// convertable to iterators (`I: IntoIter`), and the iterator's items
/// must be `Borrow<Scalar>` (or `Borrow<Point>`), to allow
/// iterators returning either `Scalar`s or `&Scalar`s.
fn mixed_multiscalar_mul<I, J, K>(
&self,
static_scalars: I,
dynamic_scalars: J,
dynamic_points: K,
) -> Self::Point
where
I: IntoIterator,
I::Item: Borrow<Scalar>,
J: IntoIterator,
J::Item: Borrow<Scalar>,
K: IntoIterator,
K::Item: Borrow<Self::Point>;
/// Given `static_scalars`, an iterator of (possibly secret)
/// scalars \\(b_i\\), compute
/// $$
/// Q = b_1 B_1 + \cdots + b_m B_m,
/// $$
/// where the \\(B_j\\) are the points that were supplied to `new`.
///
/// It is an error to call this function with iterators of
/// inconsistent lengths.
///
/// The trait bound aims for maximum flexibility: the input must
/// be convertable to iterators (`I: IntoIter`), and the
/// iterator's items must be `Borrow<Scalar>`, to allow iterators
/// returning either `Scalar`s or `&Scalar`s.
fn multiscalar_mul<I>(&self, static_scalars: I) -> Self::Point
where
I: IntoIterator,
I::Item: Borrow<Scalar>,
{
use core::iter;
Self::mixed_multiscalar_mul(
self,
static_scalars,
iter::empty::<Scalar>(),
iter::empty::<Self::Point>(),
)
}
}
/// A trait for variable-time multiscalar multiplication with precomputation.
///
/// A general multiscalar multiplication with precomputation can be written as
/// $$
/// Q = a_1 A_1 + \cdots + a_n A_n + b_1 B_1 + \cdots + b_m B_m,
/// $$
/// where the \\(B_i\\) are *static* points, for which precomputation
/// is possible, and the \\(A_j\\) are *dynamic* points, for which
/// precomputation is not possible.
pub trait VartimePrecomputedMultiscalarMul: Sized {
/// The type of point to be multiplied, e.g., `RistrettoPoint`.
type Point;
/// Given the static points \\( B_i \\), perform precomputation
/// and return the precomputation data.
fn new<I>(static_points: I) -> Self
where
I: IntoIterator,
I::Item: Borrow<Self::Point>;
/// Given `static_scalars`, an iterator of public scalars
/// \\(b_i\\), `dynamic_scalars`, an iterator of public scalars
/// \\(a_i\\), and `dynamic_points`, an iterator of points
/// \\(A_i\\), compute
/// $$
/// Q = a_1 A_1 + \cdots + a_n A_n + b_1 B_1 + \cdots + b_m B_m,
/// $$
/// where the \\(B_j\\) are the points that were supplied to `new`.
///
/// It is an error to call this function with iterators of
/// inconsistent lengths.
///
/// The trait bound aims for maximum flexibility: the inputs must be
/// convertable to iterators (`I: IntoIter`), and the iterator's items
/// must be `Borrow<Scalar>` (or `Borrow<Point>`), to allow
/// iterators returning either `Scalar`s or `&Scalar`s.
fn vartime_mixed_multiscalar_mul<I, J, K>(
&self,
static_scalars: I,
dynamic_scalars: J,
dynamic_points: K,
) -> Self::Point
where
I: IntoIterator,
I::Item: Borrow<Scalar>,
J: IntoIterator,
J::Item: Borrow<Scalar>,
K: IntoIterator,
K::Item: Borrow<Self::Point>;
/// Given `static_scalars`, an iterator of public scalars
/// \\(b_i\\), compute
/// $$
/// Q = b_1 B_1 + \cdots + b_m B_m,
/// $$
/// where the \\(B_j\\) are the points that were supplied to `new`.
///
/// It is an error to call this function with iterators of
/// inconsistent lengths.
///
/// The trait bound aims for maximum flexibility: the input must
/// be convertable to iterators (`I: IntoIter`), and the
/// iterator's items must be `Borrow<Scalar>`, to allow iterators
/// returning either `Scalar`s or `&Scalar`s.
fn vartime_multiscalar_mul<I>(&self, static_scalars: I) -> Self::Point
where
I: IntoIterator,
I::Item: Borrow<Scalar>,
{
use core::iter;
Self::vartime_mixed_multiscalar_mul(
self,
static_scalars,
iter::empty::<Scalar>(),
iter::empty::<Self::Point>(),
)
}
}
// ------------------------------------------------------------------------
// Private Traits
// ------------------------------------------------------------------------