sp1_curves/
scalar_mul.rs

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}