1//! Traits for arithmetic operations on elliptic curve field elements.
23pub use core::ops::{Add, AddAssign, Mul, Neg, Sub, SubAssign};
45use crypto_bigint::{ArrayEncoding, ByteArray, Integer};
67#[cfg(feature = "arithmetic")]
8use {group::Group, subtle::CtOption};
910#[cfg(feature = "digest")]
11use digest::FixedOutput;
1213/// Perform an inversion on a field element (i.e. base field element or scalar)
14pub trait Invert {
15/// Field element type
16type Output;
1718/// Invert a field element.
19fn invert(&self) -> Self::Output;
20}
2122#[cfg(feature = "arithmetic")]
23impl<F: ff::Field> Invert for F {
24type Output = CtOption<F>;
2526fn invert(&self) -> CtOption<F> {
27 ff::Field::invert(self)
28 }
29}
3031/// Linear combination.
32///
33/// This trait enables crates to provide an optimized implementation of
34/// linear combinations (e.g. Shamir's Trick), or otherwise provides a default
35/// non-optimized implementation.
36// TODO(tarcieri): replace this with a trait from the `group` crate? (see zkcrypto/group#25)
37#[cfg(feature = "arithmetic")]
38#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
39pub trait LinearCombination: Group {
40/// Calculates `x * k + y * l`.
41fn lincomb(x: &Self, k: &Self::Scalar, y: &Self, l: &Self::Scalar) -> Self {
42 (*x * k) + (*y * l)
43 }
44}
4546/// Modular reduction.
47pub trait Reduce<UInt: Integer + ArrayEncoding>: Sized {
48/// Perform a modular reduction, returning a field element.
49fn from_uint_reduced(n: UInt) -> Self;
5051/// Interpret the given byte array as a big endian integer and perform
52 /// a modular reduction.
53fn from_be_bytes_reduced(bytes: ByteArray<UInt>) -> Self {
54Self::from_uint_reduced(UInt::from_be_byte_array(bytes))
55 }
5657/// Interpret the given byte array as a little endian integer and perform a
58 /// modular reduction.
59fn from_le_bytes_reduced(bytes: ByteArray<UInt>) -> Self {
60Self::from_uint_reduced(UInt::from_le_byte_array(bytes))
61 }
6263/// Interpret a digest as a big endian integer and perform a modular
64 /// reduction.
65#[cfg(feature = "digest")]
66 #[cfg_attr(docsrs, doc(cfg(feature = "digest")))]
67fn from_be_digest_reduced<D>(digest: D) -> Self
68where
69D: FixedOutput<OutputSize = UInt::ByteSize>,
70 {
71Self::from_be_bytes_reduced(digest.finalize_fixed())
72 }
7374/// Interpret a digest as a little endian integer and perform a modular
75 /// reduction.
76#[cfg(feature = "digest")]
77 #[cfg_attr(docsrs, doc(cfg(feature = "digest")))]
78fn from_le_digest_reduced<D>(digest: D) -> Self
79where
80D: FixedOutput<OutputSize = UInt::ByteSize>,
81 {
82Self::from_le_bytes_reduced(digest.finalize_fixed())
83 }
84}
8586/// Modular reduction to a non-zero output.
87///
88/// This trait is primarily intended for use by curve implementations such
89/// as the `k256` and `p256` crates.
90///
91/// End users should use the [`Reduce`] impl on
92/// [`NonZeroScalar`][`crate::NonZeroScalar`] instead.
93pub trait ReduceNonZero<UInt: Integer + ArrayEncoding>: Sized {
94/// Perform a modular reduction, returning a field element.
95fn from_uint_reduced_nonzero(n: UInt) -> Self;
96}