1use core::ops::Mul;
2
3use num::{BigUint, One};
4
5use super::{utils::biguint_to_bits_le, AffinePoint, EllipticCurve};
6
7impl<E: EllipticCurve> AffinePoint<E> {
8 pub fn scalar_mul(&self, scalar: &BigUint) -> Self {
9 let power_two_modulus = BigUint::one() << E::nb_scalar_bits();
10 let scalar = scalar % &power_two_modulus;
11 let mut result = E::ec_neutral();
12 let mut temp = self.clone();
13 let bits = biguint_to_bits_le(&scalar, E::nb_scalar_bits());
14 for bit in bits {
15 if bit {
16 result = result.map_or_else(|| Some(temp.clone()), |r| Some(&r + &temp));
17 }
18 temp = &temp + &temp;
19 }
20 result.expect("Scalar multiplication failed")
21 }
22}
23
24impl<E: EllipticCurve> Mul<&BigUint> for &AffinePoint<E> {
25 type Output = AffinePoint<E>;
26
27 fn mul(self, scalar: &BigUint) -> AffinePoint<E> {
28 self.scalar_mul(scalar)
29 }
30}
31
32impl<E: EllipticCurve> Mul<BigUint> for &AffinePoint<E> {
33 type Output = AffinePoint<E>;
34
35 fn mul(self, scalar: BigUint) -> AffinePoint<E> {
36 self.scalar_mul(&scalar)
37 }
38}
39
40impl<E: EllipticCurve> Mul<BigUint> for AffinePoint<E> {
41 type Output = AffinePoint<E>;
42
43 fn mul(self, scalar: BigUint) -> AffinePoint<E> {
44 self.scalar_mul(&scalar)
45 }
46}