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}