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::RngCore;
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.
77    ///
78    /// This function is non-deterministic, and samples from the user-provided RNG.
79    fn random(rng: impl RngCore) -> Self;
80
81    /// Returns the additive identity, also known as the "neutral element".
82    fn identity() -> Self;
83
84    /// Returns a fixed generator of the prime-order subgroup.
85    fn generator() -> Self;
86
87    /// Determines if this point is the identity.
88    fn is_identity(&self) -> Choice;
89
90    /// Doubles this element.
91    #[must_use]
92    fn double(&self) -> Self;
93}
94
95/// Efficient representation of an elliptic curve point guaranteed.
96pub trait Curve:
97    Group + GroupOps<<Self as Curve>::AffineRepr> + GroupOpsOwned<<Self as Curve>::AffineRepr>
98{
99    /// The affine representation for this elliptic curve.
100    type AffineRepr;
101
102    /// Converts a batch of projective elements into affine elements. This function will
103    /// panic if `p.len() != q.len()`.
104    fn batch_normalize(p: &[Self], q: &mut [Self::AffineRepr]) {
105        assert_eq!(p.len(), q.len());
106
107        for (p, q) in p.iter().zip(q.iter_mut()) {
108            *q = p.to_affine();
109        }
110    }
111
112    /// Converts this element into its affine representation.
113    fn to_affine(&self) -> Self::AffineRepr;
114}
115
116pub trait GroupEncoding: Sized {
117    /// The encoding of group elements.
118    ///
119    /// The `Default` implementation is not required to return a valid point encoding. The
120    /// bound is present to enable encodings to be constructed generically:
121    /// ```
122    /// # use group::GroupEncoding;
123    /// # use subtle::CtOption;
124    /// # struct G;
125    /// # impl GroupEncoding for G {
126    /// #     type Repr = [u8; 0];
127    /// #     fn from_bytes(bytes: &Self::Repr) -> CtOption<Self> { unimplemented!() }
128    /// #     fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption<Self> { unimplemented!() }
129    /// #     fn to_bytes(&self) -> Self::Repr { unimplemented!() }
130    /// # }
131    /// # let buf = &[0u8; 0][..];
132    /// let mut encoding = <G as GroupEncoding>::Repr::default();
133    /// encoding.as_mut().copy_from_slice(buf);
134    /// ```
135    ///
136    /// It is recommended that the default should be the all-zeroes encoding.
137    type Repr: Copy + Default + Send + Sync + 'static + AsRef<[u8]> + AsMut<[u8]>;
138
139    /// Attempts to deserialize a group element from its encoding.
140    fn from_bytes(bytes: &Self::Repr) -> CtOption<Self>;
141
142    /// Attempts to deserialize a group element, not checking if the element is valid.
143    ///
144    /// **This is dangerous to call unless you trust the bytes you are reading; otherwise,
145    /// API invariants may be broken.** Please consider using
146    /// [`GroupEncoding::from_bytes`] instead.
147    fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption<Self>;
148
149    /// Converts this element into its byte encoding. This may or may not support
150    /// encoding the identity.
151    // TODO: Figure out how to handle identity encoding generically.
152    fn to_bytes(&self) -> Self::Repr;
153}
154
155/// Affine representation of a point on an elliptic curve that has a defined uncompressed
156/// encoding.
157pub trait UncompressedEncoding: Sized {
158    type Uncompressed: Default + AsRef<[u8]> + AsMut<[u8]>;
159
160    /// Attempts to deserialize an element from its uncompressed encoding.
161    fn from_uncompressed(bytes: &Self::Uncompressed) -> CtOption<Self>;
162
163    /// Attempts to deserialize an uncompressed element, not checking if the element is in
164    /// the correct subgroup.
165    ///
166    /// **This is dangerous to call unless you trust the bytes you are reading; otherwise,
167    /// API invariants may be broken.** Please consider using
168    /// [`UncompressedEncoding::from_uncompressed`] instead.
169    fn from_uncompressed_unchecked(bytes: &Self::Uncompressed) -> CtOption<Self>;
170
171    /// Converts this element into its uncompressed encoding, so long as it's not
172    /// the point at infinity.
173    fn to_uncompressed(&self) -> Self::Uncompressed;
174}