Function curve25519_dalek::ristretto::multiscalar_mul
[−]
[src]
pub fn multiscalar_mul<I, J>(scalars: I, points: J) -> RistrettoPoint where
I: IntoIterator,
I::Item: Borrow<Scalar>,
J: IntoIterator,
J::Item: Borrow<RistrettoPoint>,
Given an iterator of (possibly secret) scalars and an iterator of (possibly secret) points, compute $$ Q = c_1 P_1 + \cdots + c_n P_n. $$
This function has the same behaviour as
vartime::multiscalar_mul
but is constant-time.
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<RistrettoPoint>
), to allow
iterators returning either Scalar
s or &Scalar
s.
use curve25519_dalek::{constants, ristretto}; use curve25519_dalek::scalar::Scalar; // Some scalars let a = Scalar::from_u64(87329482); let b = Scalar::from_u64(37264829); let c = Scalar::from_u64(98098098); // 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 = ristretto::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 = ristretto::multiscalar_mul(minus_abc, &[P,Q,R]); // Note: minus_abc.into_iter(): Iterator<Item=Scalar> assert_eq!(A1.compress(), (-A2).compress());