mirror of
https://github.com/saymrwulf/curve25519-dalek-source.git
synced 2026-09-06 20:41:14 +00:00
33 lines
1.1 KiB
Rust
33 lines
1.1 KiB
Rust
|
|
#![allow(non_snake_case)]
|
||
|
|
|
||
|
|
use traits::Identity;
|
||
|
|
use scalar::Scalar;
|
||
|
|
use edwards::EdwardsPoint;
|
||
|
|
use curve_models::ProjectiveNielsPoint;
|
||
|
|
use scalar_mul::window::LookupTable;
|
||
|
|
|
||
|
|
/// Perform constant-time, variable-base scalar multiplication.
|
||
|
|
pub(crate) fn mul(point: &EdwardsPoint, scalar: &Scalar) -> EdwardsPoint {
|
||
|
|
// Construct a lookup table of [P,2P,3P,4P,5P,6P,7P,8P]
|
||
|
|
let lookup_table = LookupTable::<ProjectiveNielsPoint>::from(point);
|
||
|
|
// Setting s = scalar, compute
|
||
|
|
//
|
||
|
|
// s = s_0 + s_1*16^1 + ... + s_63*16^63,
|
||
|
|
//
|
||
|
|
// with `-8 ≤ s_i < 8` for `0 ≤ i < 63` and `-8 ≤ s_63 ≤ 8`.
|
||
|
|
let scalar_digits = scalar.to_radix_16();
|
||
|
|
// Compute s*P as
|
||
|
|
//
|
||
|
|
// s*P = P*(s_0 + s_1*16^1 + s_2*16^2 + ... + s_63*16^63)
|
||
|
|
// s*P = P*s_0 + P*s_1*16^1 + P*s_2*16^2 + ... + P*s_63*16^63
|
||
|
|
// s*P = P*s_0 + 16*(P*s_1 + 16*(P*s_2 + 16*( ... + P*s_63)...))
|
||
|
|
//
|
||
|
|
// We sum right-to-left.
|
||
|
|
let mut Q = EdwardsPoint::identity();
|
||
|
|
for i in (0..64).rev() {
|
||
|
|
Q = Q.mul_by_pow_2(4);
|
||
|
|
Q = (&Q + &lookup_table.select(scalar_digits[i])).to_extended();
|
||
|
|
}
|
||
|
|
Q
|
||
|
|
}
|