Trait curve25519_dalek::traits::MultiscalarMul
source · pub trait MultiscalarMul {
type Point;
// Required method
fn multiscalar_mul<I, J>(scalars: I, points: J) -> Self::Point
where I: IntoIterator,
I::Item: Borrow<Scalar>,
J: IntoIterator,
J::Item: Borrow<Self::Point>;
}
Expand description
A trait for constant-time multiscalar multiplication without precomputation.
Required Associated Types§
Required Methods§
sourcefn multiscalar_mul<I, J>(scalars: I, points: J) -> Self::Pointwhere
I: IntoIterator,
I::Item: Borrow<Scalar>,
J: IntoIterator,
J::Item: Borrow<Self::Point>,
fn multiscalar_mul<I, J>(scalars: I, points: J) -> Self::Pointwhere I: IntoIterator, I::Item: Borrow<Scalar>, J: IntoIterator, J::Item: Borrow<Self::Point>,
Given an iterator of (possibly secret) scalars and an iterator of public points, compute $$ Q = c_1 P_1 + \cdots + c_n P_n. $$
It is an error to call this function with two iterators of different lengths.
Examples
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.
use curve25519_dalek::constants;
use curve25519_dalek::traits::MultiscalarMul;
use curve25519_dalek::ristretto::RistrettoPoint;
use curve25519_dalek::scalar::Scalar;
// Some scalars
let a = Scalar::from(87329482u64);
let b = Scalar::from(37264829u64);
let c = Scalar::from(98098098u64);
// Some points
let P = constants::RISTRETTO_BASEPOINT_POINT;
let Q = P + P;
let R = P + Q;
// A1 = a*P + b*Q + c*R
let abc = [a,b,c];
let A1 = RistrettoPoint::multiscalar_mul(&abc, &[P,Q,R]);
// Note: (&abc).into_iter(): Iterator<Item=&Scalar>
// A2 = (-a)*P + (-b)*Q + (-c)*R
let minus_abc = abc.iter().map(|x| -x);
let A2 = RistrettoPoint::multiscalar_mul(minus_abc, &[P,Q,R]);
// Note: minus_abc.into_iter(): Iterator<Item=Scalar>
assert_eq!(A1.compress(), (-A2).compress());