pub use bigint::{Invert, Reduce, modular::Retrieve};
pub use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Shr, ShrAssign, Sub, SubAssign};
use crate::CurveGroup;
use ff::{BatchInverter, Field};
use group::Group;
pub trait BatchInvert: Field {
fn batch_invert_in_place(elements: &mut [Self], scratch_space: &mut [Self]) -> Self {
BatchInverter::invert_with_external_scratch(elements, scratch_space)
}
}
pub trait Double: Sized {
#[must_use]
fn double(&self) -> Self;
#[inline]
fn double_in_place(&mut self) {
*self = self.double();
}
}
pub trait LinearCombination<PointsAndScalars>: CurveGroup
where
PointsAndScalars: AsRef<[(Self, Self::Scalar)]> + ?Sized,
{
fn lincomb(points_and_scalars: &PointsAndScalars) -> Self {
points_and_scalars
.as_ref()
.iter()
.copied()
.map(|(point, scalar)| point * scalar)
.sum()
}
fn lincomb_vartime(points_and_scalars: &PointsAndScalars) -> Self {
Self::lincomb(points_and_scalars)
}
}
pub trait MulVartime<Rhs = Self>: Mul<Rhs> {
fn mul_vartime(self, rhs: Rhs) -> <Self as Mul<Rhs>>::Output;
}
pub trait MulByGeneratorVartime: Group + for<'a> MulVartime<&'a Self::Scalar> {
fn mul_by_generator_vartime(scalar: &Self::Scalar) -> Self {
Self::generator().mul_vartime(scalar)
}
fn mul_by_generator_and_mul_add_vartime(a: &Self::Scalar, b: &Self::Scalar, p: &Self) -> Self {
Self::mul_by_generator_vartime(a) + p.mul_vartime(b)
}
}
pub trait ReduceNonZero<T>: Reduce<T> {
fn reduce_nonzero(n: &T) -> Self;
}