1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
use core::ops::Mul;

use num::{BigUint, One};

use super::utils::biguint_to_bits_le;
use super::AffinePoint;
use super::EllipticCurve;

impl<E: EllipticCurve> AffinePoint<E> {
    pub fn scalar_mul(&self, scalar: &BigUint) -> Self {
        let power_two_modulus = BigUint::one() << E::nb_scalar_bits();
        let scalar = scalar % &power_two_modulus;
        let mut result = E::ec_neutral();
        let mut temp = self.clone();
        let bits = biguint_to_bits_le(&scalar, E::nb_scalar_bits());
        for bit in bits {
            if bit {
                result = result.map_or_else(|| Some(temp.clone()), |r| Some(&r + &temp));
            }
            temp = &temp + &temp;
        }
        result.expect("Scalar multiplication failed")
    }
}

impl<E: EllipticCurve> Mul<&BigUint> for &AffinePoint<E> {
    type Output = AffinePoint<E>;

    fn mul(self, scalar: &BigUint) -> AffinePoint<E> {
        self.scalar_mul(scalar)
    }
}

impl<E: EllipticCurve> Mul<BigUint> for &AffinePoint<E> {
    type Output = AffinePoint<E>;

    fn mul(self, scalar: BigUint) -> AffinePoint<E> {
        self.scalar_mul(&scalar)
    }
}

impl<E: EllipticCurve> Mul<BigUint> for AffinePoint<E> {
    type Output = AffinePoint<E>;

    fn mul(self, scalar: BigUint) -> AffinePoint<E> {
        self.scalar_mul(&scalar)
    }
}