use crate::{PrimeCurveParams, ProjectivePoint};
use elliptic_curve::Scalar;
use elliptic_curve::ops::LinearCombination;
#[cfg(feature = "basepoint-table")]
use crate::PrimeCurveWithBasepointTable;
pub trait MulBackend<C: PrimeCurveParams> {
#[inline]
fn mul_by_generator(k: &Scalar<C>) -> ProjectivePoint<C> {
ProjectivePoint::GENERATOR * k
}
#[inline]
fn mul_by_generator_vartime(k: &Scalar<C>) -> ProjectivePoint<C> {
ProjectivePoint::GENERATOR.mul_vartime(k)
}
#[inline]
fn mul_by_generator_and_mul_add_vartime(
a: &Scalar<C>,
b_scalar: &Scalar<C>,
b_point: &ProjectivePoint<C>,
) -> ProjectivePoint<C> {
ProjectivePoint::<C>::lincomb_vartime(&[
(ProjectivePoint::GENERATOR, *a),
(*b_point, *b_scalar),
])
}
}
#[derive(Clone, Copy, Debug)]
pub struct VariableOnly;
impl<C: PrimeCurveParams> MulBackend<C> for VariableOnly {}
#[derive(Clone, Copy, Debug)]
#[cfg(feature = "basepoint-table")]
pub struct PrecomputedTables<const WINDOW_SIZE: usize>;
#[cfg(feature = "basepoint-table")]
impl<C, const WINDOW_SIZE: usize> MulBackend<C> for PrecomputedTables<WINDOW_SIZE>
where
C: PrimeCurveParams + PrimeCurveWithBasepointTable<WINDOW_SIZE>,
{
#[inline]
fn mul_by_generator(k: &Scalar<C>) -> ProjectivePoint<C> {
C::BASEPOINT_TABLE.mul(k)
}
#[inline]
fn mul_by_generator_vartime(k: &Scalar<C>) -> ProjectivePoint<C> {
C::BASEPOINT_TABLE.mul_vartime(k)
}
}