Skip to main content

primeorder/
mul_backend.rs

1//! Scalar multiplication backends.
2
3use crate::{PrimeCurveParams, ProjectivePoint};
4use elliptic_curve::Scalar;
5use elliptic_curve::ops::LinearCombination;
6
7#[cfg(feature = "basepoint-table")]
8use crate::PrimeCurveWithBasepointTable;
9
10/// Scalar multiplication backend.
11pub trait MulBackend<C: PrimeCurveParams> {
12    /// Multiplication by the generator.
13    ///
14    /// This is overridable to make it possible to plug in a basepoint table.
15    #[inline]
16    fn mul_by_generator(k: &Scalar<C>) -> ProjectivePoint<C> {
17        ProjectivePoint::GENERATOR * k
18    }
19
20    /// Variable-time multiplication by the generator.
21    ///
22    /// This is overridable to make it possible to plug in a basepoint table.
23    #[inline]
24    fn mul_by_generator_vartime(k: &Scalar<C>) -> ProjectivePoint<C> {
25        ProjectivePoint::GENERATOR.mul_vartime(k)
26    }
27
28    /// Multiply `a` by the generator of the prime-order subgroup, adding the result to the point
29    /// `P` multiplied by the scalar `b`, i.e. compute `aG + bP`.
30    #[inline]
31    fn mul_by_generator_and_mul_add_vartime(
32        a: &Scalar<C>,
33        b_scalar: &Scalar<C>,
34        b_point: &ProjectivePoint<C>,
35    ) -> ProjectivePoint<C> {
36        ProjectivePoint::<C>::lincomb_vartime(&[
37            (ProjectivePoint::GENERATOR, *a),
38            (*b_point, *b_scalar),
39        ])
40    }
41}
42
43/// Simple backend that only supports variable-base scalar multiplication.
44#[derive(Clone, Copy, Debug)]
45pub struct VariableOnly;
46
47impl<C: PrimeCurveParams> MulBackend<C> for VariableOnly {}
48
49/// Backend based on precomputed tables.
50#[derive(Clone, Copy, Debug)]
51#[cfg(feature = "basepoint-table")]
52pub struct PrecomputedTables<const WINDOW_SIZE: usize>;
53
54#[cfg(feature = "basepoint-table")]
55impl<C, const WINDOW_SIZE: usize> MulBackend<C> for PrecomputedTables<WINDOW_SIZE>
56where
57    C: PrimeCurveParams + PrimeCurveWithBasepointTable<WINDOW_SIZE>,
58{
59    #[inline]
60    fn mul_by_generator(k: &Scalar<C>) -> ProjectivePoint<C> {
61        C::BASEPOINT_TABLE.mul(k)
62    }
63
64    #[inline]
65    fn mul_by_generator_vartime(k: &Scalar<C>) -> ProjectivePoint<C> {
66        C::BASEPOINT_TABLE.mul_vartime(k)
67    }
68}