Skip to main content

group/
lib.rs

1#![no_std]
2// Catch documentation errors caused by code changes.
3#![deny(rustdoc::broken_intra_doc_links)]
4
5#[cfg(feature = "alloc")]
6#[macro_use]
7extern crate alloc;
8
9// Re-export ff to make version-matching easier.
10pub use ff;
11
12use core::fmt;
13use core::iter::Sum;
14use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
15use ff::PrimeField;
16use rand_core::{Rng, TryRng};
17use subtle::{Choice, CtOption};
18
19pub mod cofactor;
20pub mod prime;
21#[cfg(feature = "tests")]
22pub mod tests;
23
24#[cfg(feature = "alloc")]
25mod wnaf;
26#[cfg(feature = "alloc")]
27pub use self::wnaf::{Wnaf, WnafBase, WnafGroup, WnafScalar};
28
29/// A helper trait for types with a group operation.
30pub trait GroupOps<Rhs = Self, Output = Self>:
31    Add<Rhs, Output = Output> + Sub<Rhs, Output = Output> + AddAssign<Rhs> + SubAssign<Rhs>
32{
33}
34
35impl<T, Rhs, Output> GroupOps<Rhs, Output> for T where
36    T: Add<Rhs, Output = Output> + Sub<Rhs, Output = Output> + AddAssign<Rhs> + SubAssign<Rhs>
37{
38}
39
40/// A helper trait for references with a group operation.
41pub trait GroupOpsOwned<Rhs = Self, Output = Self>: for<'r> GroupOps<&'r Rhs, Output> {}
42impl<T, Rhs, Output> GroupOpsOwned<Rhs, Output> for T where T: for<'r> GroupOps<&'r Rhs, Output> {}
43
44/// A helper trait for types implementing group scalar multiplication.
45pub trait ScalarMul<Rhs, Output = Self>: Mul<Rhs, Output = Output> + MulAssign<Rhs> {}
46
47impl<T, Rhs, Output> ScalarMul<Rhs, Output> for T where T: Mul<Rhs, Output = Output> + MulAssign<Rhs>
48{}
49
50/// A helper trait for references implementing group scalar multiplication.
51pub trait ScalarMulOwned<Rhs, Output = Self>: for<'r> ScalarMul<&'r Rhs, Output> {}
52impl<T, Rhs, Output> ScalarMulOwned<Rhs, Output> for T where T: for<'r> ScalarMul<&'r Rhs, Output> {}
53
54/// This trait represents an element of a cryptographic group.
55pub trait Group:
56    Clone
57    + Copy
58    + fmt::Debug
59    + Eq
60    + Sized
61    + Send
62    + Sync
63    + 'static
64    + Sum
65    + for<'a> Sum<&'a Self>
66    + Neg<Output = Self>
67    + GroupOps
68    + GroupOpsOwned
69    + ScalarMul<<Self as Group>::Scalar>
70    + ScalarMulOwned<<Self as Group>::Scalar>
71{
72    /// Scalars modulo the order of this group's scalar field.
73    type Scalar: PrimeField;
74
75    /// Returns an element chosen uniformly at random from the non-identity elements of
76    /// this group using a user-provided infallible RNG.
77    ///
78    /// This is a convenience wrapper around [`Group::try_random`] for RNGs that cannot
79    /// fail. Use [`Group::try_random`] if your RNG may fail (for example, an OS-backed
80    /// entropy source).
81    fn random<R: Rng + ?Sized>(rng: &mut R) -> Self {
82        let Ok(out) = Self::try_random(rng);
83        out
84    }
85
86    /// Returns an element chosen uniformly at random from the non-identity elements of
87    /// this group using a user-provided fallible RNG.
88    ///
89    /// Returns `Err` propagating the RNG's error if the underlying RNG fails to produce
90    /// the randomness required to sample an element. Implementors of `Group` must
91    /// provide this method; [`Group::random`] is derived from it for infallible RNGs.
92    fn try_random<R: TryRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error>;
93
94    /// Returns the additive identity, also known as the "neutral element".
95    fn identity() -> Self;
96
97    /// Returns a fixed generator of the prime-order subgroup.
98    fn generator() -> Self;
99
100    /// Determines if this point is the identity.
101    fn is_identity(&self) -> Choice;
102
103    /// Doubles this element.
104    #[must_use]
105    fn double(&self) -> Self;
106
107    /// Multiply by the generator of the prime-order subgroup.
108    #[must_use]
109    fn mul_by_generator(scalar: &Self::Scalar) -> Self {
110        Self::generator() * scalar
111    }
112}
113
114/// Efficient representation of an elliptic curve point.
115pub trait Curve: Group + GroupOps<Self::Affine> + GroupOpsOwned<Self::Affine> {
116    /// The affine representation for this elliptic curve.
117    type Affine: CurveAffine<Curve = Self, Scalar = Self::Scalar>;
118
119    /// Converts a batch of projective elements into affine elements. This function will
120    /// panic if `p.len() != q.len()`.
121    fn batch_normalize(p: &[Self], q: &mut [Self::Affine]) {
122        assert_eq!(p.len(), q.len());
123
124        for (p, q) in p.iter().zip(q.iter_mut()) {
125            *q = p.to_affine();
126        }
127    }
128
129    /// Converts this element into its affine representation.
130    fn to_affine(&self) -> Self::Affine;
131}
132
133/// Affine representation of an elliptic curve point.
134pub trait CurveAffine:
135    GroupEncoding
136    + Copy
137    + fmt::Debug
138    + Eq
139    + Send
140    + Sync
141    + 'static
142    + Neg<Output = Self>
143    + Mul<<Self::Curve as Group>::Scalar, Output = Self::Curve>
144    + for<'r> Mul<&'r <Self::Curve as Group>::Scalar, Output = Self::Curve>
145{
146    /// The efficient representation for this elliptic curve.
147    type Curve: Curve<Affine = Self, Scalar = Self::Scalar>;
148
149    /// Scalars modulo the order of this group's scalar field.
150    ///
151    /// This associated type is temporary, and will be removed once downstream users have
152    /// migrated to using `Curve` as the primary generic bound.
153    type Scalar: PrimeField;
154
155    /// Returns the additive identity.
156    fn identity() -> Self;
157
158    /// Returns a fixed generator of unknown exponent.
159    fn generator() -> Self;
160
161    /// Determines if this point represents the additive identity.
162    fn is_identity(&self) -> Choice;
163
164    /// Converts this affine point to its efficient representation.
165    fn to_curve(&self) -> Self::Curve;
166}
167
168pub trait GroupEncoding: Sized {
169    /// The encoding of group elements.
170    ///
171    /// The `Default` implementation is not required to return a valid point encoding. The
172    /// bound is present to enable encodings to be constructed generically:
173    /// ```
174    /// # use group::GroupEncoding;
175    /// # use subtle::CtOption;
176    /// # struct G;
177    /// # impl GroupEncoding for G {
178    /// #     type Repr = [u8; 0];
179    /// #     fn from_bytes(bytes: &Self::Repr) -> CtOption<Self> { unimplemented!() }
180    /// #     fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption<Self> { unimplemented!() }
181    /// #     fn to_bytes(&self) -> Self::Repr { unimplemented!() }
182    /// # }
183    /// # let buf = &[0u8; 0][..];
184    /// let mut encoding = <G as GroupEncoding>::Repr::default();
185    /// encoding.as_mut().copy_from_slice(buf);
186    /// ```
187    ///
188    /// It is recommended that the default should be the all-zeroes encoding.
189    type Repr: Copy + Default + Send + Sync + 'static + AsRef<[u8]> + AsMut<[u8]>;
190
191    /// Attempts to deserialize a group element from its encoding.
192    fn from_bytes(bytes: &Self::Repr) -> CtOption<Self>;
193
194    /// Attempts to deserialize a group element, not checking if the element is valid.
195    ///
196    /// **This is dangerous to call unless you trust the bytes you are reading; otherwise,
197    /// API invariants may be broken.** Please consider using
198    /// [`GroupEncoding::from_bytes`] instead.
199    fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption<Self>;
200
201    /// Converts this element into its byte encoding. This may or may not support
202    /// encoding the identity.
203    // TODO: Figure out how to handle identity encoding generically.
204    fn to_bytes(&self) -> Self::Repr;
205}
206
207/// Affine representation of a point on an elliptic curve that has a defined uncompressed
208/// encoding.
209pub trait UncompressedEncoding: Sized {
210    type Uncompressed: Default + AsRef<[u8]> + AsMut<[u8]>;
211
212    /// Attempts to deserialize an element from its uncompressed encoding.
213    fn from_uncompressed(bytes: &Self::Uncompressed) -> CtOption<Self>;
214
215    /// Attempts to deserialize an uncompressed element, not checking if the element is in
216    /// the correct subgroup.
217    ///
218    /// **This is dangerous to call unless you trust the bytes you are reading; otherwise,
219    /// API invariants may be broken.** Please consider using
220    /// [`UncompressedEncoding::from_uncompressed`] instead.
221    fn from_uncompressed_unchecked(bytes: &Self::Uncompressed) -> CtOption<Self>;
222
223    /// Converts this element into its uncompressed encoding, so long as it's not
224    /// the point at infinity.
225    fn to_uncompressed(&self) -> Self::Uncompressed;
226}