mirror of
https://github.com/saymrwulf/curve25519-dalek-source.git
synced 2026-09-06 20:41:14 +00:00
Merge branch 'feature/rename-to-multiscalar-mul' into develop
This commit is contained in:
commit
d67e895619
5 changed files with 84 additions and 84 deletions
|
|
@ -238,7 +238,7 @@ impl ExtendedPoint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mult_by_pow_2(&self, k: u32) -> ExtendedPoint {
|
pub fn mul_by_pow_2(&self, k: u32) -> ExtendedPoint {
|
||||||
let mut tmp: ExtendedPoint = *self;
|
let mut tmp: ExtendedPoint = *self;
|
||||||
for _ in 0..k {
|
for _ in 0..k {
|
||||||
tmp = tmp.double();
|
tmp = tmp.double();
|
||||||
|
|
@ -397,7 +397,7 @@ impl<'a, 'b> Mul<&'b Scalar> for &'a ExtendedPoint {
|
||||||
let mut Q = ExtendedPoint::identity();
|
let mut Q = ExtendedPoint::identity();
|
||||||
for i in (0..64).rev() {
|
for i in (0..64).rev() {
|
||||||
// Q = 16*Q
|
// Q = 16*Q
|
||||||
Q = Q.mult_by_pow_2(4);
|
Q = Q.mul_by_pow_2(4);
|
||||||
// Q += P*s_i
|
// Q += P*s_i
|
||||||
Q = &Q + &lookup_table.select(scalar_digits[i]);
|
Q = &Q + &lookup_table.select(scalar_digits[i]);
|
||||||
}
|
}
|
||||||
|
|
@ -421,7 +421,7 @@ impl<'a, 'b> Mul<&'b Scalar> for &'a EdwardsBasepointTable {
|
||||||
P = &P + &tables[i/2].select(a[i]);
|
P = &P + &tables[i/2].select(a[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
P = P.mult_by_pow_2(4);
|
P = P.mul_by_pow_2(4);
|
||||||
|
|
||||||
for i in (0..64).filter(|x| x % 2 == 0) {
|
for i in (0..64).filter(|x| x % 2 == 0) {
|
||||||
P = &P + &tables[i/2].select(a[i]);
|
P = &P + &tables[i/2].select(a[i]);
|
||||||
|
|
@ -449,7 +449,7 @@ impl EdwardsBasepointTable {
|
||||||
for i in 0..32 {
|
for i in 0..32 {
|
||||||
// P = (16^2)^i * B
|
// P = (16^2)^i * B
|
||||||
table.0[i] = LookupTable::from(P);
|
table.0[i] = LookupTable::from(P);
|
||||||
P = P.mult_by_pow_2(8);
|
P = P.mul_by_pow_2(8);
|
||||||
}
|
}
|
||||||
table
|
table
|
||||||
}
|
}
|
||||||
|
|
@ -457,7 +457,7 @@ impl EdwardsBasepointTable {
|
||||||
|
|
||||||
/// Internal multiscalar code.
|
/// Internal multiscalar code.
|
||||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
#[cfg(any(feature = "alloc", feature = "std"))]
|
||||||
pub fn multiscalar_mult<I, J>(scalars: I, points: J) -> edwards::EdwardsPoint
|
pub fn multiscalar_mul<I, J>(scalars: I, points: J) -> edwards::EdwardsPoint
|
||||||
where I: IntoIterator,
|
where I: IntoIterator,
|
||||||
I::Item: Borrow<Scalar>,
|
I::Item: Borrow<Scalar>,
|
||||||
J: IntoIterator,
|
J: IntoIterator,
|
||||||
|
|
@ -508,7 +508,7 @@ pub fn multiscalar_mult<I, J>(scalars: I, points: J) -> edwards::EdwardsPoint
|
||||||
let mut Q = ExtendedPoint::identity();
|
let mut Q = ExtendedPoint::identity();
|
||||||
// XXX this algorithm makes no effort to be cache-aware; maybe it could be improved?
|
// XXX this algorithm makes no effort to be cache-aware; maybe it could be improved?
|
||||||
for j in (0..64).rev() {
|
for j in (0..64).rev() {
|
||||||
Q = Q.mult_by_pow_2(4);
|
Q = Q.mul_by_pow_2(4);
|
||||||
let it = scalar_digits.iter().zip(lookup_tables.iter());
|
let it = scalar_digits.iter().zip(lookup_tables.iter());
|
||||||
for (s_i, lookup_table_i) in it {
|
for (s_i, lookup_table_i) in it {
|
||||||
// Q = Q + s_{i,j} * P_i
|
// Q = Q + s_{i,j} * P_i
|
||||||
|
|
@ -551,7 +551,7 @@ pub mod vartime {
|
||||||
/// with x positive).
|
/// with x positive).
|
||||||
///
|
///
|
||||||
/// This is the same as calling the iterator-based function, but slightly faster.
|
/// This is the same as calling the iterator-based function, but slightly faster.
|
||||||
pub fn double_scalar_mult_basepoint(a: &Scalar,
|
pub fn double_scalar_mul_basepoint(a: &Scalar,
|
||||||
A: &edwards::EdwardsPoint,
|
A: &edwards::EdwardsPoint,
|
||||||
b: &Scalar) -> edwards::EdwardsPoint {
|
b: &Scalar) -> edwards::EdwardsPoint {
|
||||||
let a_naf = a.non_adjacent_form();
|
let a_naf = a.non_adjacent_form();
|
||||||
|
|
@ -597,7 +597,7 @@ pub mod vartime {
|
||||||
|
|
||||||
/// Internal multiscalar function
|
/// Internal multiscalar function
|
||||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
#[cfg(any(feature = "alloc", feature = "std"))]
|
||||||
pub fn multiscalar_mult<I, J>(scalars: I, points: J) -> edwards::EdwardsPoint
|
pub fn multiscalar_mul<I, J>(scalars: I, points: J) -> edwards::EdwardsPoint
|
||||||
where I: IntoIterator,
|
where I: IntoIterator,
|
||||||
I::Item: Borrow<Scalar>,
|
I::Item: Borrow<Scalar>,
|
||||||
J: IntoIterator,
|
J: IntoIterator,
|
||||||
|
|
@ -856,7 +856,7 @@ mod test {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn scalar_mult_vs_edwards_scalar_mult() {
|
fn scalar_mul_vs_edwards_scalar_mul() {
|
||||||
let B: ExtendedPoint = constants::ED25519_BASEPOINT_POINT.into();
|
let B: ExtendedPoint = constants::ED25519_BASEPOINT_POINT.into();
|
||||||
// some random bytes
|
// some random bytes
|
||||||
let s = Scalar::from_bits([233, 1, 233, 147, 113, 78, 244, 120, 40, 45, 103, 51, 224, 199, 189, 218, 96, 140, 211, 112, 39, 194, 73, 216, 173, 33, 102, 93, 76, 200, 84, 12]);
|
let s = Scalar::from_bits([233, 1, 233, 147, 113, 78, 244, 120, 40, 45, 103, 51, 224, 199, 189, 218, 96, 140, 211, 112, 39, 194, 73, 216, 173, 33, 102, 93, 76, 200, 84, 12]);
|
||||||
|
|
@ -868,7 +868,7 @@ mod test {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn scalar_mult_vs_basepoint_table_scalar_mult() {
|
fn scalar_mul_vs_basepoint_table_scalar_mul() {
|
||||||
let B: ExtendedPoint = constants::ED25519_BASEPOINT_POINT.into();
|
let B: ExtendedPoint = constants::ED25519_BASEPOINT_POINT.into();
|
||||||
let B_table = EdwardsBasepointTable::create(&B);
|
let B_table = EdwardsBasepointTable::create(&B);
|
||||||
// some random bytes
|
// some random bytes
|
||||||
|
|
@ -882,7 +882,7 @@ mod test {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn multiscalar_mult_vs_adding_scalar_mults() {
|
fn multiscalar_mul_vs_adding_scalar_muls() {
|
||||||
let B: ExtendedPoint = constants::ED25519_BASEPOINT_POINT.into();
|
let B: ExtendedPoint = constants::ED25519_BASEPOINT_POINT.into();
|
||||||
let s1 = Scalar::from_bits([233, 1, 233, 147, 113, 78, 244, 120, 40, 45, 103, 51, 224, 199, 189, 218, 96, 140, 211, 112, 39, 194, 73, 216, 173, 33, 102, 93, 76, 200, 84, 12]);
|
let s1 = Scalar::from_bits([233, 1, 233, 147, 113, 78, 244, 120, 40, 45, 103, 51, 224, 199, 189, 218, 96, 140, 211, 112, 39, 194, 73, 216, 173, 33, 102, 93, 76, 200, 84, 12]);
|
||||||
let s2 = Scalar::from_bits([165, 30, 79, 89, 58, 24, 195, 245, 248, 146, 203, 236, 119, 43, 64, 119, 196, 111, 188, 251, 248, 53, 234, 59, 215, 28, 218, 13, 59, 120, 14, 4]);
|
let s2 = Scalar::from_bits([165, 30, 79, 89, 58, 24, 195, 245, 248, 146, 203, 236, 119, 43, 64, 119, 196, 111, 188, 251, 248, 53, 234, 59, 215, 28, 218, 13, 59, 120, 14, 4]);
|
||||||
|
|
@ -892,7 +892,7 @@ mod test {
|
||||||
|
|
||||||
let R = &(&P1 * &s1) + &(&P2 * &s2);
|
let R = &(&P1 * &s1) + &(&P2 * &s2);
|
||||||
|
|
||||||
let R_multiscalar = multiscalar_mult(&[s1, s2], &[P1.into(), P2.into()]);
|
let R_multiscalar = multiscalar_mul(&[s1, s2], &[P1.into(), P2.into()]);
|
||||||
|
|
||||||
assert_eq!(edwards::EdwardsPoint::from(R).compress(),
|
assert_eq!(edwards::EdwardsPoint::from(R).compress(),
|
||||||
R_multiscalar.compress());
|
R_multiscalar.compress());
|
||||||
|
|
@ -902,7 +902,7 @@ mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn multiscalar_mult_vs_adding_scalar_mults() {
|
fn multiscalar_mul_vs_adding_scalar_muls() {
|
||||||
let B: ExtendedPoint = constants::ED25519_BASEPOINT_POINT.into();
|
let B: ExtendedPoint = constants::ED25519_BASEPOINT_POINT.into();
|
||||||
let s1 = Scalar::from_bits([233, 1, 233, 147, 113, 78, 244, 120, 40, 45, 103, 51, 224, 199, 189, 218, 96, 140, 211, 112, 39, 194, 73, 216, 173, 33, 102, 93, 76, 200, 84, 12]);
|
let s1 = Scalar::from_bits([233, 1, 233, 147, 113, 78, 244, 120, 40, 45, 103, 51, 224, 199, 189, 218, 96, 140, 211, 112, 39, 194, 73, 216, 173, 33, 102, 93, 76, 200, 84, 12]);
|
||||||
let s2 = Scalar::from_bits([165, 30, 79, 89, 58, 24, 195, 245, 248, 146, 203, 236, 119, 43, 64, 119, 196, 111, 188, 251, 248, 53, 234, 59, 215, 28, 218, 13, 59, 120, 14, 4]);
|
let s2 = Scalar::from_bits([165, 30, 79, 89, 58, 24, 195, 245, 248, 146, 203, 236, 119, 43, 64, 119, 196, 111, 188, 251, 248, 53, 234, 59, 215, 28, 218, 13, 59, 120, 14, 4]);
|
||||||
|
|
@ -912,7 +912,7 @@ mod test {
|
||||||
|
|
||||||
let R = &(&P1 * &s1) + &(&P2 * &s2);
|
let R = &(&P1 * &s1) + &(&P2 * &s2);
|
||||||
|
|
||||||
let R_multiscalar = vartime::multiscalar_mult(&[s1, s2], &[P1.into(), P2.into()]);
|
let R_multiscalar = vartime::multiscalar_mul(&[s1, s2], &[P1.into(), P2.into()]);
|
||||||
|
|
||||||
assert_eq!(edwards::EdwardsPoint::from(R).compress(),
|
assert_eq!(edwards::EdwardsPoint::from(R).compress(),
|
||||||
R_multiscalar.compress());
|
R_multiscalar.compress());
|
||||||
|
|
@ -972,7 +972,7 @@ mod bench {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn scalar_mult(b: &mut Bencher) {
|
fn scalar_mul(b: &mut Bencher) {
|
||||||
let B = &constants::ED25519_BASEPOINT_TABLE;
|
let B = &constants::ED25519_BASEPOINT_TABLE;
|
||||||
let P = ExtendedPoint::from(B * &Scalar::from_u64(83973422));
|
let P = ExtendedPoint::from(B * &Scalar::from_u64(83973422));
|
||||||
let s = Scalar::from_bits([233, 1, 233, 147, 113, 78, 244, 120, 40, 45, 103, 51, 224, 199, 189, 218, 96, 140, 211, 112, 39, 194, 73, 216, 173, 33, 102, 93, 76, 200, 84, 12]);
|
let s = Scalar::from_bits([233, 1, 233, 147, 113, 78, 244, 120, 40, 45, 103, 51, 224, 199, 189, 218, 96, 140, 211, 112, 39, 194, 73, 216, 173, 33, 102, 93, 76, 200, 84, 12]);
|
||||||
|
|
@ -997,7 +997,7 @@ mod bench {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn ten_fold_scalar_mult(b: &mut Bencher) {
|
fn ten_fold_scalar_mul(b: &mut Bencher) {
|
||||||
let mut csprng: OsRng = OsRng::new().unwrap();
|
let mut csprng: OsRng = OsRng::new().unwrap();
|
||||||
// Create 10 random scalars
|
// Create 10 random scalars
|
||||||
let scalars: Vec<_> = (0..10).map(|_| Scalar::random(&mut csprng)).collect();
|
let scalars: Vec<_> = (0..10).map(|_| Scalar::random(&mut csprng)).collect();
|
||||||
|
|
@ -1005,7 +1005,7 @@ mod bench {
|
||||||
let B = &constants::ED25519_BASEPOINT_TABLE;
|
let B = &constants::ED25519_BASEPOINT_TABLE;
|
||||||
let points: Vec<_> = scalars.iter().map(|s| B * s).collect();
|
let points: Vec<_> = scalars.iter().map(|s| B * s).collect();
|
||||||
|
|
||||||
b.iter(|| multiscalar_mult(&scalars, &points));
|
b.iter(|| multiscalar_mul(&scalars, &points));
|
||||||
}
|
}
|
||||||
|
|
||||||
mod vartime {
|
mod vartime {
|
||||||
|
|
@ -1013,18 +1013,18 @@ mod bench {
|
||||||
use super::{constants, Bencher, OsRng};
|
use super::{constants, Bencher, OsRng};
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn double_scalar_mult(b: &mut Bencher) {
|
fn double_scalar_mul(b: &mut Bencher) {
|
||||||
let mut csprng: OsRng = OsRng::new().unwrap();
|
let mut csprng: OsRng = OsRng::new().unwrap();
|
||||||
// Create 2 random scalars
|
// Create 2 random scalars
|
||||||
let s1 = Scalar::random(&mut csprng);
|
let s1 = Scalar::random(&mut csprng);
|
||||||
let s2 = Scalar::random(&mut csprng);
|
let s2 = Scalar::random(&mut csprng);
|
||||||
let P = &s1 * &constants::ED25519_BASEPOINT_TABLE;
|
let P = &s1 * &constants::ED25519_BASEPOINT_TABLE;
|
||||||
|
|
||||||
b.iter(|| vartime::double_scalar_mult_basepoint(&s2, &P, &s1) );
|
b.iter(|| vartime::double_scalar_mul_basepoint(&s2, &P, &s1) );
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn ten_fold_scalar_mult(b: &mut Bencher) {
|
fn ten_fold_scalar_mul(b: &mut Bencher) {
|
||||||
let mut csprng: OsRng = OsRng::new().unwrap();
|
let mut csprng: OsRng = OsRng::new().unwrap();
|
||||||
// Create 10 random scalars
|
// Create 10 random scalars
|
||||||
let scalars: Vec<_> = (0..10).map(|_| Scalar::random(&mut csprng)).collect();
|
let scalars: Vec<_> = (0..10).map(|_| Scalar::random(&mut csprng)).collect();
|
||||||
|
|
@ -1032,7 +1032,7 @@ mod bench {
|
||||||
let B = &constants::ED25519_BASEPOINT_TABLE;
|
let B = &constants::ED25519_BASEPOINT_TABLE;
|
||||||
let points: Vec<_> = scalars.iter().map(|s| B * s).collect();
|
let points: Vec<_> = scalars.iter().map(|s| B * s).collect();
|
||||||
|
|
||||||
b.iter(|| vartime::multiscalar_mult(&scalars, &points));
|
b.iter(|| vartime::multiscalar_mul(&scalars, &points));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_eight_torsion() {
|
fn test_eight_torsion() {
|
||||||
for i in 0..8 {
|
for i in 0..8 {
|
||||||
let Q = constants::EIGHT_TORSION[i].mult_by_pow_2(3);
|
let Q = constants::EIGHT_TORSION[i].mul_by_pow_2(3);
|
||||||
assert!(Q.is_valid());
|
assert!(Q.is_valid());
|
||||||
assert!(Q.is_identity());
|
assert!(Q.is_identity());
|
||||||
}
|
}
|
||||||
|
|
@ -114,7 +114,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_four_torsion() {
|
fn test_four_torsion() {
|
||||||
for i in (0..8).filter(|i| i % 2 == 0) {
|
for i in (0..8).filter(|i| i % 2 == 0) {
|
||||||
let Q = constants::EIGHT_TORSION[i].mult_by_pow_2(2);
|
let Q = constants::EIGHT_TORSION[i].mul_by_pow_2(2);
|
||||||
assert!(Q.is_valid());
|
assert!(Q.is_valid());
|
||||||
assert!(Q.is_identity());
|
assert!(Q.is_identity());
|
||||||
}
|
}
|
||||||
|
|
@ -123,7 +123,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_two_torsion() {
|
fn test_two_torsion() {
|
||||||
for i in (0..8).filter(|i| i % 4 == 0) {
|
for i in (0..8).filter(|i| i % 4 == 0) {
|
||||||
let Q = constants::EIGHT_TORSION[i].mult_by_pow_2(1);
|
let Q = constants::EIGHT_TORSION[i].mul_by_pow_2(1);
|
||||||
assert!(Q.is_valid());
|
assert!(Q.is_valid());
|
||||||
assert!(Q.is_identity());
|
assert!(Q.is_identity());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@
|
||||||
//! To test if a point is in \\( \mathcal E[\ell] \\), use
|
//! To test if a point is in \\( \mathcal E[\ell] \\), use
|
||||||
//! `EdwardsPoint::is_torsion_free()`.
|
//! `EdwardsPoint::is_torsion_free()`.
|
||||||
//!
|
//!
|
||||||
//! To multiply by the cofactor, use `EdwardsPoint::mult_by_cofactor()`.
|
//! To multiply by the cofactor, use `EdwardsPoint::mul_by_cofactor()`.
|
||||||
//!
|
//!
|
||||||
//! To avoid dealing with cofactors entirely, consider using Ristretto.
|
//! To avoid dealing with cofactors entirely, consider using Ristretto.
|
||||||
//!
|
//!
|
||||||
|
|
@ -57,10 +57,10 @@
|
||||||
//! `EdwardsBasepointTable`, which performs constant-time fixed-base
|
//! `EdwardsBasepointTable`, which performs constant-time fixed-base
|
||||||
//! scalar multiplication;
|
//! scalar multiplication;
|
||||||
//!
|
//!
|
||||||
//! * the `edwards::multiscalar_mult` function, which performs
|
//! * the `edwards::multiscalar_mul` function, which performs
|
||||||
//! constant-time variable-base multiscalar multiplication;
|
//! constant-time variable-base multiscalar multiplication;
|
||||||
//!
|
//!
|
||||||
//! * the `edwards::vartime::multiscalar_mult` function, which
|
//! * the `edwards::vartime::multiscalar_mul` function, which
|
||||||
//! performs variable-time variable-base multiscalar multiplication.
|
//! performs variable-time variable-base multiscalar multiplication.
|
||||||
//!
|
//!
|
||||||
//! ## Implementation
|
//! ## Implementation
|
||||||
|
|
@ -504,7 +504,7 @@ impl<'a, 'b> Mul<&'b Scalar> for &'a EdwardsPoint {
|
||||||
let mut Q = EdwardsPoint::identity();
|
let mut Q = EdwardsPoint::identity();
|
||||||
for i in (0..64).rev() {
|
for i in (0..64).rev() {
|
||||||
// Q <-- 16*Q
|
// Q <-- 16*Q
|
||||||
Q = Q.mult_by_pow_2(4);
|
Q = Q.mul_by_pow_2(4);
|
||||||
// Q <-- Q + P * s_i
|
// Q <-- Q + P * s_i
|
||||||
Q = (&Q + &lookup_table.select(scalar_digits[i])).to_extended()
|
Q = (&Q + &lookup_table.select(scalar_digits[i])).to_extended()
|
||||||
}
|
}
|
||||||
|
|
@ -533,7 +533,7 @@ impl<'a, 'b> Mul<&'b EdwardsPoint> for &'a Scalar {
|
||||||
/// $$
|
/// $$
|
||||||
///
|
///
|
||||||
/// This function has the same behaviour as
|
/// This function has the same behaviour as
|
||||||
/// `vartime::multiscalar_mult` but is constant-time.
|
/// `vartime::multiscalar_mul` but is constant-time.
|
||||||
///
|
///
|
||||||
/// It is an error to call this function with two iterators of different lengths.
|
/// It is an error to call this function with two iterators of different lengths.
|
||||||
///
|
///
|
||||||
|
|
@ -560,12 +560,12 @@ impl<'a, 'b> Mul<&'b EdwardsPoint> for &'a Scalar {
|
||||||
///
|
///
|
||||||
/// // A1 = a*P + b*Q + c*R
|
/// // A1 = a*P + b*Q + c*R
|
||||||
/// let abc = [a,b,c];
|
/// let abc = [a,b,c];
|
||||||
/// let A1 = edwards::multiscalar_mult(&abc, &[P,Q,R]);
|
/// let A1 = edwards::multiscalar_mul(&abc, &[P,Q,R]);
|
||||||
/// // Note: (&abc).into_iter(): Iterator<Item=&Scalar>
|
/// // Note: (&abc).into_iter(): Iterator<Item=&Scalar>
|
||||||
///
|
///
|
||||||
/// // A2 = (-a)*P + (-b)*Q + (-c)*R
|
/// // A2 = (-a)*P + (-b)*Q + (-c)*R
|
||||||
/// let minus_abc = abc.iter().map(|x| -x);
|
/// let minus_abc = abc.iter().map(|x| -x);
|
||||||
/// let A2 = edwards::multiscalar_mult(minus_abc, &[P,Q,R]);
|
/// let A2 = edwards::multiscalar_mul(minus_abc, &[P,Q,R]);
|
||||||
/// // Note: minus_abc.into_iter(): Iterator<Item=Scalar>
|
/// // Note: minus_abc.into_iter(): Iterator<Item=Scalar>
|
||||||
///
|
///
|
||||||
/// assert_eq!(A1.compress(), (-A2).compress());
|
/// assert_eq!(A1.compress(), (-A2).compress());
|
||||||
|
|
@ -573,7 +573,7 @@ impl<'a, 'b> Mul<&'b EdwardsPoint> for &'a Scalar {
|
||||||
// XXX later when we do more fancy multiscalar mults, we can delegate
|
// XXX later when we do more fancy multiscalar mults, we can delegate
|
||||||
// based on the iter's size hint -- hdevalence
|
// based on the iter's size hint -- hdevalence
|
||||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
#[cfg(any(feature = "alloc", feature = "std"))]
|
||||||
pub fn multiscalar_mult<I, J>(scalars: I, points: J) -> EdwardsPoint
|
pub fn multiscalar_mul<I, J>(scalars: I, points: J) -> EdwardsPoint
|
||||||
where I: IntoIterator,
|
where I: IntoIterator,
|
||||||
I::Item: Borrow<Scalar>,
|
I::Item: Borrow<Scalar>,
|
||||||
J: IntoIterator,
|
J: IntoIterator,
|
||||||
|
|
@ -583,7 +583,7 @@ pub fn multiscalar_mult<I, J>(scalars: I, points: J) -> EdwardsPoint
|
||||||
#[cfg(all(feature="nightly", all(feature="avx2_backend", target_feature="avx2")))] {
|
#[cfg(all(feature="nightly", all(feature="avx2_backend", target_feature="avx2")))] {
|
||||||
use backend::avx2::edwards as edwards_avx2;
|
use backend::avx2::edwards as edwards_avx2;
|
||||||
|
|
||||||
edwards_avx2::multiscalar_mult(scalars, points)
|
edwards_avx2::multiscalar_mul(scalars, points)
|
||||||
}
|
}
|
||||||
// Otherwise, proceed as normal:
|
// Otherwise, proceed as normal:
|
||||||
#[cfg(not(all(feature="nightly", all(feature="avx2_backend", target_feature="avx2"))))] {
|
#[cfg(not(all(feature="nightly", all(feature="avx2_backend", target_feature="avx2"))))] {
|
||||||
|
|
@ -633,7 +633,7 @@ pub fn multiscalar_mult<I, J>(scalars: I, points: J) -> EdwardsPoint
|
||||||
let mut Q = EdwardsPoint::identity();
|
let mut Q = EdwardsPoint::identity();
|
||||||
// XXX this impl makes no effort to be cache-aware; maybe it could be improved?
|
// XXX this impl makes no effort to be cache-aware; maybe it could be improved?
|
||||||
for j in (0..64).rev() {
|
for j in (0..64).rev() {
|
||||||
Q = Q.mult_by_pow_2(4);
|
Q = Q.mul_by_pow_2(4);
|
||||||
let it = scalar_digits.iter().zip(lookup_tables.iter());
|
let it = scalar_digits.iter().zip(lookup_tables.iter());
|
||||||
for (s_i, lookup_table_i) in it {
|
for (s_i, lookup_table_i) in it {
|
||||||
// R_i = s_{i,j} * P_i
|
// R_i = s_{i,j} * P_i
|
||||||
|
|
@ -693,7 +693,7 @@ impl EdwardsBasepointTable {
|
||||||
P = (&P + &tables[i/2].select(a[i])).to_extended();
|
P = (&P + &tables[i/2].select(a[i])).to_extended();
|
||||||
}
|
}
|
||||||
|
|
||||||
P = P.mult_by_pow_2(4);
|
P = P.mul_by_pow_2(4);
|
||||||
|
|
||||||
for i in (0..64).filter(|x| x % 2 == 0) {
|
for i in (0..64).filter(|x| x % 2 == 0) {
|
||||||
P = (&P + &tables[i/2].select(a[i])).to_extended();
|
P = (&P + &tables[i/2].select(a[i])).to_extended();
|
||||||
|
|
@ -733,7 +733,7 @@ impl EdwardsBasepointTable {
|
||||||
for i in 0..32 {
|
for i in 0..32 {
|
||||||
// P = (16^2)^i * B
|
// P = (16^2)^i * B
|
||||||
table.0[i] = LookupTable::from(&P);
|
table.0[i] = LookupTable::from(&P);
|
||||||
P = P.mult_by_pow_2(8);
|
P = P.mul_by_pow_2(8);
|
||||||
}
|
}
|
||||||
table
|
table
|
||||||
}
|
}
|
||||||
|
|
@ -750,12 +750,12 @@ impl EdwardsBasepointTable {
|
||||||
|
|
||||||
impl EdwardsPoint {
|
impl EdwardsPoint {
|
||||||
/// Multiply by the cofactor: return \\([8]P\\).
|
/// Multiply by the cofactor: return \\([8]P\\).
|
||||||
pub fn mult_by_cofactor(&self) -> EdwardsPoint {
|
pub fn mul_by_cofactor(&self) -> EdwardsPoint {
|
||||||
self.mult_by_pow_2(3)
|
self.mul_by_pow_2(3)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute \\([2\^k] P \\) by successive doublings. Requires \\( k > 0 \\).
|
/// Compute \\([2\^k] P \\) by successive doublings. Requires \\( k > 0 \\).
|
||||||
pub(crate) fn mult_by_pow_2(&self, k: u32) -> EdwardsPoint {
|
pub(crate) fn mul_by_pow_2(&self, k: u32) -> EdwardsPoint {
|
||||||
debug_assert!( k > 0 );
|
debug_assert!( k > 0 );
|
||||||
let mut r: CompletedPoint;
|
let mut r: CompletedPoint;
|
||||||
let mut s = self.to_projective();
|
let mut s = self.to_projective();
|
||||||
|
|
@ -790,7 +790,7 @@ impl EdwardsPoint {
|
||||||
/// assert_eq!(Q.is_small_order(), true);
|
/// assert_eq!(Q.is_small_order(), true);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn is_small_order(&self) -> bool {
|
pub fn is_small_order(&self) -> bool {
|
||||||
self.mult_by_cofactor().is_identity()
|
self.mul_by_cofactor().is_identity()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determine if this point is “torsion-free”, i.e., is contained in
|
/// Determine if this point is “torsion-free”, i.e., is contained in
|
||||||
|
|
@ -908,7 +908,7 @@ pub mod vartime {
|
||||||
/// $$
|
/// $$
|
||||||
///
|
///
|
||||||
/// This function has the same behaviour as
|
/// This function has the same behaviour as
|
||||||
/// `edwards::multiscalar_mult` but operates on non-secret data.
|
/// `edwards::multiscalar_mul` but operates on non-secret data.
|
||||||
///
|
///
|
||||||
/// It is an error to call this function with two iterators of different lengths.
|
/// It is an error to call this function with two iterators of different lengths.
|
||||||
///
|
///
|
||||||
|
|
@ -935,12 +935,12 @@ pub mod vartime {
|
||||||
///
|
///
|
||||||
/// // A1 = a*P + b*Q + c*R
|
/// // A1 = a*P + b*Q + c*R
|
||||||
/// let abc = [a,b,c];
|
/// let abc = [a,b,c];
|
||||||
/// let A1 = edwards::vartime::multiscalar_mult(&abc, &[P,Q,R]);
|
/// let A1 = edwards::vartime::multiscalar_mul(&abc, &[P,Q,R]);
|
||||||
/// // Note: (&abc).into_iter(): Iterator<Item=&Scalar>
|
/// // Note: (&abc).into_iter(): Iterator<Item=&Scalar>
|
||||||
///
|
///
|
||||||
/// // A2 = (-a)*P + (-b)*Q + (-c)*R
|
/// // A2 = (-a)*P + (-b)*Q + (-c)*R
|
||||||
/// let minus_abc = abc.iter().map(|x| -x);
|
/// let minus_abc = abc.iter().map(|x| -x);
|
||||||
/// let A2 = edwards::vartime::multiscalar_mult(minus_abc, &[P,Q,R]);
|
/// let A2 = edwards::vartime::multiscalar_mul(minus_abc, &[P,Q,R]);
|
||||||
/// // Note: minus_abc.into_iter(): Iterator<Item=Scalar>
|
/// // Note: minus_abc.into_iter(): Iterator<Item=Scalar>
|
||||||
///
|
///
|
||||||
/// assert_eq!(A1.compress(), (-A2).compress());
|
/// assert_eq!(A1.compress(), (-A2).compress());
|
||||||
|
|
@ -948,7 +948,7 @@ pub mod vartime {
|
||||||
// XXX later when we do more fancy multiscalar mults, we can delegate
|
// XXX later when we do more fancy multiscalar mults, we can delegate
|
||||||
// based on the iter's size hint -- hdevalence
|
// based on the iter's size hint -- hdevalence
|
||||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
#[cfg(any(feature = "alloc", feature = "std"))]
|
||||||
pub fn multiscalar_mult<I, J>(scalars: I, points: J) -> EdwardsPoint
|
pub fn multiscalar_mul<I, J>(scalars: I, points: J) -> EdwardsPoint
|
||||||
where I: IntoIterator,
|
where I: IntoIterator,
|
||||||
I::Item: Borrow<Scalar>,
|
I::Item: Borrow<Scalar>,
|
||||||
J: IntoIterator,
|
J: IntoIterator,
|
||||||
|
|
@ -958,7 +958,7 @@ pub mod vartime {
|
||||||
#[cfg(all(feature="nightly", all(feature="avx2_backend", target_feature="avx2")))] {
|
#[cfg(all(feature="nightly", all(feature="avx2_backend", target_feature="avx2")))] {
|
||||||
use backend::avx2::edwards as edwards_avx2;
|
use backend::avx2::edwards as edwards_avx2;
|
||||||
|
|
||||||
edwards_avx2::vartime::multiscalar_mult(scalars, points)
|
edwards_avx2::vartime::multiscalar_mul(scalars, points)
|
||||||
}
|
}
|
||||||
// Otherwise, proceed as normal:
|
// Otherwise, proceed as normal:
|
||||||
#[cfg(not(all(feature="nightly", all(feature="avx2_backend", target_feature="avx2"))))] {
|
#[cfg(not(all(feature="nightly", all(feature="avx2_backend", target_feature="avx2"))))] {
|
||||||
|
|
@ -993,7 +993,7 @@ pub mod vartime {
|
||||||
/// \\(aA+bB\\), where \\(B\\) is the Ed25519 basepoint (i.e., \\(B = (x,4/5)\\)
|
/// \\(aA+bB\\), where \\(B\\) is the Ed25519 basepoint (i.e., \\(B = (x,4/5)\\)
|
||||||
/// with x positive).
|
/// with x positive).
|
||||||
#[cfg(feature="precomputed_tables")]
|
#[cfg(feature="precomputed_tables")]
|
||||||
pub fn double_scalar_mult_basepoint(
|
pub fn double_scalar_mul_basepoint(
|
||||||
a: &Scalar,
|
a: &Scalar,
|
||||||
A: &EdwardsPoint,
|
A: &EdwardsPoint,
|
||||||
b: &Scalar,
|
b: &Scalar,
|
||||||
|
|
@ -1002,7 +1002,7 @@ pub mod vartime {
|
||||||
#[cfg(all(feature="nightly", all(feature="avx2_backend", target_feature="avx2")))] {
|
#[cfg(all(feature="nightly", all(feature="avx2_backend", target_feature="avx2")))] {
|
||||||
use backend::avx2::edwards as edwards_avx2;
|
use backend::avx2::edwards as edwards_avx2;
|
||||||
|
|
||||||
edwards_avx2::vartime::double_scalar_mult_basepoint(a, A, b)
|
edwards_avx2::vartime::double_scalar_mul_basepoint(a, A, b)
|
||||||
}
|
}
|
||||||
// Otherwise, proceed as normal:
|
// Otherwise, proceed as normal:
|
||||||
#[cfg(not(all(feature="nightly", all(feature="avx2_backend", target_feature="avx2"))))] {
|
#[cfg(not(all(feature="nightly", all(feature="avx2_backend", target_feature="avx2"))))] {
|
||||||
|
|
@ -1244,9 +1244,9 @@ mod test {
|
||||||
assert_eq!(aB_1.compress(), aB_2.compress());
|
assert_eq!(aB_1.compress(), aB_2.compress());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test scalar_mult versus a known scalar multiple from ed25519.py
|
/// Test scalar_mul versus a known scalar multiple from ed25519.py
|
||||||
#[test]
|
#[test]
|
||||||
fn scalar_mult_vs_ed25519py() {
|
fn scalar_mul_vs_ed25519py() {
|
||||||
let aB = &constants::ED25519_BASEPOINT_POINT * &A_SCALAR;
|
let aB = &constants::ED25519_BASEPOINT_POINT * &A_SCALAR;
|
||||||
assert_eq!(aB.compress(), A_TIMES_BASEPOINT);
|
assert_eq!(aB.compress(), A_TIMES_BASEPOINT);
|
||||||
}
|
}
|
||||||
|
|
@ -1275,10 +1275,10 @@ mod test {
|
||||||
constants::ED25519_BASEPOINT_COMPRESSED);
|
constants::ED25519_BASEPOINT_COMPRESSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test computing 16*basepoint vs mult_by_pow_2(4)
|
/// Test computing 16*basepoint vs mul_by_pow_2(4)
|
||||||
#[test]
|
#[test]
|
||||||
fn basepoint16_vs_mult_by_pow_2_4() {
|
fn basepoint16_vs_mul_by_pow_2_4() {
|
||||||
let bp16 = constants::ED25519_BASEPOINT_POINT.mult_by_pow_2(4);
|
let bp16 = constants::ED25519_BASEPOINT_POINT.mul_by_pow_2(4);
|
||||||
assert_eq!(bp16.compress(), BASE16_CMPRSSD);
|
assert_eq!(bp16.compress(), BASE16_CMPRSSD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1330,7 +1330,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn monte_carlo_overflow_underflow_debug_assert_test() {
|
fn monte_carlo_overflow_underflow_debug_assert_test() {
|
||||||
let mut P = constants::ED25519_BASEPOINT_POINT;
|
let mut P = constants::ED25519_BASEPOINT_POINT;
|
||||||
// N.B. each scalar_mult does 1407 field mults, 1024 field squarings,
|
// N.B. each scalar_mul does 1407 field mults, 1024 field squarings,
|
||||||
// so this does ~ 1M of each operation.
|
// so this does ~ 1M of each operation.
|
||||||
for _ in 0..1_000 {
|
for _ in 0..1_000 {
|
||||||
P *= &A_SCALAR;
|
P *= &A_SCALAR;
|
||||||
|
|
@ -1352,19 +1352,19 @@ mod test {
|
||||||
use super::super::*;
|
use super::super::*;
|
||||||
use super::{A_SCALAR, B_SCALAR, A_TIMES_BASEPOINT, DOUBLE_SCALAR_MULT_RESULT};
|
use super::{A_SCALAR, B_SCALAR, A_TIMES_BASEPOINT, DOUBLE_SCALAR_MULT_RESULT};
|
||||||
|
|
||||||
/// Test double_scalar_mult_vartime vs ed25519.py
|
/// Test double_scalar_mul_vartime vs ed25519.py
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature="precomputed_tables")]
|
#[cfg(feature="precomputed_tables")]
|
||||||
fn double_scalar_mult_basepoint_vs_ed25519py() {
|
fn double_scalar_mul_basepoint_vs_ed25519py() {
|
||||||
let A = A_TIMES_BASEPOINT.decompress().unwrap();
|
let A = A_TIMES_BASEPOINT.decompress().unwrap();
|
||||||
let result = vartime::double_scalar_mult_basepoint(&A_SCALAR, &A, &B_SCALAR);
|
let result = vartime::double_scalar_mul_basepoint(&A_SCALAR, &A, &B_SCALAR);
|
||||||
assert_eq!(result.compress(), DOUBLE_SCALAR_MULT_RESULT);
|
assert_eq!(result.compress(), DOUBLE_SCALAR_MULT_RESULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn multiscalar_mult_vs_ed25519py() {
|
fn multiscalar_mul_vs_ed25519py() {
|
||||||
let A = A_TIMES_BASEPOINT.decompress().unwrap();
|
let A = A_TIMES_BASEPOINT.decompress().unwrap();
|
||||||
let result = vartime::multiscalar_mult(
|
let result = vartime::multiscalar_mul(
|
||||||
&[A_SCALAR, B_SCALAR],
|
&[A_SCALAR, B_SCALAR],
|
||||||
&[A, constants::ED25519_BASEPOINT_POINT]
|
&[A, constants::ED25519_BASEPOINT_POINT]
|
||||||
);
|
);
|
||||||
|
|
@ -1372,13 +1372,13 @@ mod test {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn multiscalar_mult_vartime_vs_consttime() {
|
fn multiscalar_mul_vartime_vs_consttime() {
|
||||||
let A = A_TIMES_BASEPOINT.decompress().unwrap();
|
let A = A_TIMES_BASEPOINT.decompress().unwrap();
|
||||||
let result_vartime = vartime::multiscalar_mult(
|
let result_vartime = vartime::multiscalar_mul(
|
||||||
&[A_SCALAR, B_SCALAR],
|
&[A_SCALAR, B_SCALAR],
|
||||||
&[A, constants::ED25519_BASEPOINT_POINT]
|
&[A, constants::ED25519_BASEPOINT_POINT]
|
||||||
);
|
);
|
||||||
let result_consttime = multiscalar_mult(
|
let result_consttime = multiscalar_mul(
|
||||||
&[A_SCALAR, B_SCALAR],
|
&[A_SCALAR, B_SCALAR],
|
||||||
&[A, constants::ED25519_BASEPOINT_POINT]
|
&[A, constants::ED25519_BASEPOINT_POINT]
|
||||||
);
|
);
|
||||||
|
|
@ -1442,7 +1442,7 @@ mod bench {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn scalar_mult(b: &mut Bencher) {
|
fn scalar_mul(b: &mut Bencher) {
|
||||||
let B = &constants::ED25519_BASEPOINT_POINT;
|
let B = &constants::ED25519_BASEPOINT_POINT;
|
||||||
b.iter(|| B * &A_SCALAR);
|
b.iter(|| B * &A_SCALAR);
|
||||||
}
|
}
|
||||||
|
|
@ -1502,10 +1502,10 @@ mod bench {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn mult_by_cofactor(b: &mut Bencher) {
|
fn mul_by_cofactor(b: &mut Bencher) {
|
||||||
let p1 = constants::ED25519_BASEPOINT_POINT;
|
let p1 = constants::ED25519_BASEPOINT_POINT;
|
||||||
|
|
||||||
b.iter(|| p1.mult_by_cofactor());
|
b.iter(|| p1.mul_by_cofactor());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -1517,7 +1517,7 @@ mod bench {
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
#[cfg(feature="precomputed_tables")]
|
#[cfg(feature="precomputed_tables")]
|
||||||
fn ten_fold_scalar_mult(b: &mut Bencher) {
|
fn ten_fold_scalar_mul(b: &mut Bencher) {
|
||||||
let mut csprng: OsRng = OsRng::new().unwrap();
|
let mut csprng: OsRng = OsRng::new().unwrap();
|
||||||
// Create 10 random scalars
|
// Create 10 random scalars
|
||||||
let scalars: Vec<_> = (0..10).map(|_| Scalar::random(&mut csprng)).collect();
|
let scalars: Vec<_> = (0..10).map(|_| Scalar::random(&mut csprng)).collect();
|
||||||
|
|
@ -1525,7 +1525,7 @@ mod bench {
|
||||||
let B = &constants::ED25519_BASEPOINT_TABLE;
|
let B = &constants::ED25519_BASEPOINT_TABLE;
|
||||||
let points: Vec<_> = scalars.iter().map(|s| B * &s).collect();
|
let points: Vec<_> = scalars.iter().map(|s| B * &s).collect();
|
||||||
|
|
||||||
b.iter(|| multiscalar_mult(&scalars, &points));
|
b.iter(|| multiscalar_mul(&scalars, &points));
|
||||||
}
|
}
|
||||||
|
|
||||||
mod vartime {
|
mod vartime {
|
||||||
|
|
@ -1534,14 +1534,14 @@ mod bench {
|
||||||
use super::{Bencher, OsRng};
|
use super::{Bencher, OsRng};
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_double_scalar_mult_basepoint(b: &mut Bencher) {
|
fn bench_double_scalar_mul_basepoint(b: &mut Bencher) {
|
||||||
let A = A_TIMES_BASEPOINT.decompress().unwrap();
|
let A = A_TIMES_BASEPOINT.decompress().unwrap();
|
||||||
b.iter(|| vartime::double_scalar_mult_basepoint(&A_SCALAR, &A, &B_SCALAR));
|
b.iter(|| vartime::double_scalar_mul_basepoint(&A_SCALAR, &A, &B_SCALAR));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
#[cfg(feature="precomputed_tables")]
|
#[cfg(feature="precomputed_tables")]
|
||||||
fn ten_fold_scalar_mult(b: &mut Bencher) {
|
fn ten_fold_scalar_mul(b: &mut Bencher) {
|
||||||
let mut csprng: OsRng = OsRng::new().unwrap();
|
let mut csprng: OsRng = OsRng::new().unwrap();
|
||||||
// Create 10 random scalars
|
// Create 10 random scalars
|
||||||
let scalars: Vec<_> = (0..10).map(|_| Scalar::random(&mut csprng)).collect();
|
let scalars: Vec<_> = (0..10).map(|_| Scalar::random(&mut csprng)).collect();
|
||||||
|
|
@ -1555,7 +1555,7 @@ mod bench {
|
||||||
//
|
//
|
||||||
// Since this is a variable-time function, this means the
|
// Since this is a variable-time function, this means the
|
||||||
// benchmark is only useful as a ballpark measurement.
|
// benchmark is only useful as a ballpark measurement.
|
||||||
b.iter(|| vartime::multiscalar_mult(&scalars, &points));
|
b.iter(|| vartime::multiscalar_mul(&scalars, &points));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,10 +79,10 @@
|
||||||
//! `RistrettoBasepointTable`, which performs constant-time fixed-base
|
//! `RistrettoBasepointTable`, which performs constant-time fixed-base
|
||||||
//! scalar multiplication;
|
//! scalar multiplication;
|
||||||
//!
|
//!
|
||||||
//! * the `ristretto::multiscalar_mult` function, which performs
|
//! * the `ristretto::multiscalar_mul` function, which performs
|
||||||
//! constant-time variable-base multiscalar multiplication;
|
//! constant-time variable-base multiscalar multiplication;
|
||||||
//!
|
//!
|
||||||
//! * the `ristretto::vartime::multiscalar_mult` function, which
|
//! * the `ristretto::vartime::multiscalar_mul` function, which
|
||||||
//! performs variable-time variable-base multiscalar multiplication.
|
//! performs variable-time variable-base multiscalar multiplication.
|
||||||
//!
|
//!
|
||||||
//! ## Random Points and Hashing to Ristretto
|
//! ## Random Points and Hashing to Ristretto
|
||||||
|
|
@ -1085,7 +1085,7 @@ define_mul_variants!(LHS = Scalar, RHS = RistrettoPoint, Output = RistrettoPoint
|
||||||
/// $$
|
/// $$
|
||||||
///
|
///
|
||||||
/// This function has the same behaviour as
|
/// This function has the same behaviour as
|
||||||
/// `vartime::multiscalar_mult` but is constant-time.
|
/// `vartime::multiscalar_mul` but is constant-time.
|
||||||
///
|
///
|
||||||
/// It is an error to call this function with two iterators of different lengths.
|
/// It is an error to call this function with two iterators of different lengths.
|
||||||
///
|
///
|
||||||
|
|
@ -1112,25 +1112,25 @@ define_mul_variants!(LHS = Scalar, RHS = RistrettoPoint, Output = RistrettoPoint
|
||||||
///
|
///
|
||||||
/// // A1 = a*P + b*Q + c*R
|
/// // A1 = a*P + b*Q + c*R
|
||||||
/// let abc = [a,b,c];
|
/// let abc = [a,b,c];
|
||||||
/// let A1 = ristretto::multiscalar_mult(&abc, &[P,Q,R]);
|
/// let A1 = ristretto::multiscalar_mul(&abc, &[P,Q,R]);
|
||||||
/// // Note: (&abc).into_iter(): Iterator<Item=&Scalar>
|
/// // Note: (&abc).into_iter(): Iterator<Item=&Scalar>
|
||||||
///
|
///
|
||||||
/// // A2 = (-a)*P + (-b)*Q + (-c)*R
|
/// // A2 = (-a)*P + (-b)*Q + (-c)*R
|
||||||
/// let minus_abc = abc.iter().map(|x| -x);
|
/// let minus_abc = abc.iter().map(|x| -x);
|
||||||
/// let A2 = ristretto::multiscalar_mult(minus_abc, &[P,Q,R]);
|
/// let A2 = ristretto::multiscalar_mul(minus_abc, &[P,Q,R]);
|
||||||
/// // Note: minus_abc.into_iter(): Iterator<Item=Scalar>
|
/// // Note: minus_abc.into_iter(): Iterator<Item=Scalar>
|
||||||
///
|
///
|
||||||
/// assert_eq!(A1.compress(), (-A2).compress());
|
/// assert_eq!(A1.compress(), (-A2).compress());
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
#[cfg(any(feature = "alloc", feature = "std"))]
|
||||||
pub fn multiscalar_mult<I, J>(scalars: I, points: J) -> RistrettoPoint
|
pub fn multiscalar_mul<I, J>(scalars: I, points: J) -> RistrettoPoint
|
||||||
where I: IntoIterator,
|
where I: IntoIterator,
|
||||||
I::Item: Borrow<Scalar>,
|
I::Item: Borrow<Scalar>,
|
||||||
J: IntoIterator,
|
J: IntoIterator,
|
||||||
J::Item: Borrow<RistrettoPoint>,
|
J::Item: Borrow<RistrettoPoint>,
|
||||||
{
|
{
|
||||||
let extended_points = points.into_iter().map(|P| P.borrow().0);
|
let extended_points = points.into_iter().map(|P| P.borrow().0);
|
||||||
RistrettoPoint(edwards::multiscalar_mult(scalars, extended_points))
|
RistrettoPoint(edwards::multiscalar_mul(scalars, extended_points))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A precomputed table of multiples of a basepoint, used to accelerate
|
/// A precomputed table of multiples of a basepoint, used to accelerate
|
||||||
|
|
@ -1238,7 +1238,7 @@ pub mod vartime {
|
||||||
/// $$
|
/// $$
|
||||||
///
|
///
|
||||||
/// This function has the same behaviour as
|
/// This function has the same behaviour as
|
||||||
/// `vartime::multiscalar_mult` but is constant-time.
|
/// `vartime::multiscalar_mul` but is constant-time.
|
||||||
///
|
///
|
||||||
/// It is an error to call this function with two iterators of different lengths.
|
/// It is an error to call this function with two iterators of different lengths.
|
||||||
///
|
///
|
||||||
|
|
@ -1265,25 +1265,25 @@ pub mod vartime {
|
||||||
///
|
///
|
||||||
/// // A1 = a*P + b*Q + c*R
|
/// // A1 = a*P + b*Q + c*R
|
||||||
/// let abc = [a,b,c];
|
/// let abc = [a,b,c];
|
||||||
/// let A1 = ristretto::vartime::multiscalar_mult(&abc, &[P,Q,R]);
|
/// let A1 = ristretto::vartime::multiscalar_mul(&abc, &[P,Q,R]);
|
||||||
/// // Note: (&abc).into_iter(): Iterator<Item=&Scalar>
|
/// // Note: (&abc).into_iter(): Iterator<Item=&Scalar>
|
||||||
///
|
///
|
||||||
/// // A2 = (-a)*P + (-b)*Q + (-c)*R
|
/// // A2 = (-a)*P + (-b)*Q + (-c)*R
|
||||||
/// let minus_abc = abc.iter().map(|x| -x);
|
/// let minus_abc = abc.iter().map(|x| -x);
|
||||||
/// let A2 = ristretto::vartime::multiscalar_mult(minus_abc, &[P,Q,R]);
|
/// let A2 = ristretto::vartime::multiscalar_mul(minus_abc, &[P,Q,R]);
|
||||||
/// // Note: minus_abc.into_iter(): Iterator<Item=Scalar>
|
/// // Note: minus_abc.into_iter(): Iterator<Item=Scalar>
|
||||||
///
|
///
|
||||||
/// assert_eq!(A1.compress(), (-A2).compress());
|
/// assert_eq!(A1.compress(), (-A2).compress());
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
#[cfg(any(feature = "alloc", feature = "std"))]
|
||||||
pub fn multiscalar_mult<I, J>(scalars: I, points: J) -> RistrettoPoint
|
pub fn multiscalar_mul<I, J>(scalars: I, points: J) -> RistrettoPoint
|
||||||
where I: IntoIterator,
|
where I: IntoIterator,
|
||||||
I::Item: Borrow<Scalar>,
|
I::Item: Borrow<Scalar>,
|
||||||
J: IntoIterator,
|
J: IntoIterator,
|
||||||
J::Item: Borrow<RistrettoPoint>,
|
J::Item: Borrow<RistrettoPoint>,
|
||||||
{
|
{
|
||||||
let extended_points = points.into_iter().map(|P| P.borrow().0);
|
let extended_points = points.into_iter().map(|P| P.borrow().0);
|
||||||
RistrettoPoint(edwards::vartime::multiscalar_mult(scalars, extended_points))
|
RistrettoPoint(edwards::vartime::multiscalar_mul(scalars, extended_points))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1355,7 +1355,7 @@ mod test {
|
||||||
let bp_recaf = bp_compressed_ristretto.decompress().unwrap().0;
|
let bp_recaf = bp_compressed_ristretto.decompress().unwrap().0;
|
||||||
// Check that bp_recaf differs from bp by a point of order 4
|
// Check that bp_recaf differs from bp by a point of order 4
|
||||||
let diff = &constants::RISTRETTO_BASEPOINT_POINT.0 - &bp_recaf;
|
let diff = &constants::RISTRETTO_BASEPOINT_POINT.0 - &bp_recaf;
|
||||||
let diff4 = diff.mult_by_pow_2(2);
|
let diff4 = diff.mul_by_pow_2(2);
|
||||||
assert_eq!(diff4.compress(), CompressedEdwardsY::identity());
|
assert_eq!(diff4.compress(), CompressedEdwardsY::identity());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -828,7 +828,7 @@ mod test {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn scalar_multiply_by_one() {
|
fn scalar_mul_by_one() {
|
||||||
let test_scalar = &X * &Scalar::one();
|
let test_scalar = &X * &Scalar::one();
|
||||||
for i in 0..32 {
|
for i in 0..32 {
|
||||||
assert!(test_scalar[i] == X[i]);
|
assert!(test_scalar[i] == X[i]);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue