-
Notifications
You must be signed in to change notification settings - Fork 251
/
lib.rs
186 lines (153 loc) · 6.67 KB
/
lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
// Catch documentation errors caused by code changes.
#![deny(intra_doc_link_resolution_failure)]
use ff::{Field, PrimeField};
use rand::RngCore;
use std::fmt;
use std::iter::Sum;
use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
use subtle::{Choice, CtOption};
pub mod tests;
mod wnaf;
pub use self::wnaf::Wnaf;
/// A helper trait for types with a group operation.
pub trait GroupOps<Rhs = Self, Output = Self>:
Add<Rhs, Output = Output> + Sub<Rhs, Output = Output> + AddAssign<Rhs> + SubAssign<Rhs>
{
}
impl<T, Rhs, Output> GroupOps<Rhs, Output> for T where
T: Add<Rhs, Output = Output> + Sub<Rhs, Output = Output> + AddAssign<Rhs> + SubAssign<Rhs>
{
}
/// A helper trait for references with a group operation.
pub trait GroupOpsOwned<Rhs = Self, Output = Self>: for<'r> GroupOps<&'r Rhs, Output> {}
impl<T, Rhs, Output> GroupOpsOwned<Rhs, Output> for T where T: for<'r> GroupOps<&'r Rhs, Output> {}
/// A helper trait for types implementing group scalar multiplication.
pub trait ScalarMul<Rhs, Output = Self>: Mul<Rhs, Output = Output> + MulAssign<Rhs> {}
impl<T, Rhs, Output> ScalarMul<Rhs, Output> for T where T: Mul<Rhs, Output = Output> + MulAssign<Rhs>
{}
/// A helper trait for references implementing group scalar multiplication.
///
/// This trait, in combination with `ScalarMul`, is necessary to address type constraint
/// issues in `pairing::Engine` (specifically, to ensure that [`ff::ScalarEngine::Fr`] is
/// correctly constrained to implement these traits required by [`Group::Scalar`]).
pub trait ScalarMulOwned<Rhs, Output = Self>: for<'r> ScalarMul<&'r Rhs, Output> {}
impl<T, Rhs, Output> ScalarMulOwned<Rhs, Output> for T where T: for<'r> ScalarMul<&'r Rhs, Output> {}
/// This trait represents an element of a cryptographic group.
pub trait Group:
Clone
+ Copy
+ fmt::Debug
+ fmt::Display
+ Eq
+ Sized
+ Send
+ Sync
+ 'static
+ Sum
+ for<'a> Sum<&'a Self>
+ Neg<Output = Self>
+ GroupOps
+ GroupOpsOwned
+ GroupOps<<Self as Group>::Subgroup>
+ GroupOpsOwned<<Self as Group>::Subgroup>
+ ScalarMul<<Self as Group>::Scalar>
+ ScalarMulOwned<<Self as Group>::Scalar>
{
/// The large prime-order subgroup in which cryptographic operations are performed.
/// If `Self` implements `PrimeGroup`, then `Self::Subgroup` may be `Self`.
type Subgroup: PrimeGroup;
/// Scalars modulo the order of [`Group::Subgroup`].
type Scalar: PrimeField;
/// Returns an element chosen uniformly at random using a user-provided RNG.
fn random<R: RngCore + ?Sized>(rng: &mut R) -> Self;
/// Returns the additive identity, also known as the "neutral element".
fn identity() -> Self;
/// Returns a fixed generator of the prime-order subgroup.
fn generator() -> Self::Subgroup;
/// Determines if this point is the identity.
fn is_identity(&self) -> Choice;
/// Doubles this element.
#[must_use]
fn double(&self) -> Self;
}
/// This trait represents an element of a prime-order cryptographic group.
pub trait PrimeGroup: Group {}
/// Projective representation of an elliptic curve point guaranteed to be
/// in the correct prime order subgroup.
pub trait CurveProjective:
Group
+ GroupOps<<Self as CurveProjective>::Affine>
+ GroupOpsOwned<<Self as CurveProjective>::Affine>
{
type Base: Field;
type Affine: CurveAffine<Projective = Self, Scalar = Self::Scalar>
+ Mul<Self::Scalar, Output = Self>
+ for<'r> Mul<Self::Scalar, Output = Self>;
/// Converts a batch of projective elements into affine elements. This function will
/// panic if `p.len() != q.len()`.
fn batch_normalize(p: &[Self], q: &mut [Self::Affine]);
/// Converts this element into its affine representation.
fn to_affine(&self) -> Self::Affine;
/// Recommends a wNAF window table size given a scalar. Always returns a number
/// between 2 and 22, inclusive.
fn recommended_wnaf_for_scalar(scalar: &Self::Scalar) -> usize;
/// Recommends a wNAF window size given the number of scalars you intend to multiply
/// a base by. Always returns a number between 2 and 22, inclusive.
fn recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize;
}
/// Affine representation of an elliptic curve point guaranteed to be
/// in the correct prime order subgroup.
pub trait CurveAffine:
Copy
+ Clone
+ Sized
+ Send
+ Sync
+ fmt::Debug
+ fmt::Display
+ PartialEq
+ Eq
+ 'static
+ Neg<Output = Self>
+ Mul<<Self as CurveAffine>::Scalar, Output = <Self as CurveAffine>::Projective>
+ for<'r> Mul<<Self as CurveAffine>::Scalar, Output = <Self as CurveAffine>::Projective>
{
type Scalar: PrimeField;
type Base: Field;
type Projective: CurveProjective<Affine = Self, Scalar = Self::Scalar>;
type Uncompressed: Default + AsRef<[u8]> + AsMut<[u8]>;
type Compressed: Default + AsRef<[u8]> + AsMut<[u8]>;
/// Returns the additive identity.
fn identity() -> Self;
/// Returns a fixed generator of unknown exponent.
fn generator() -> Self;
/// Determines if this point represents the point at infinity; the
/// additive identity.
fn is_identity(&self) -> Choice;
/// Converts this element into its affine representation.
fn to_projective(&self) -> Self::Projective;
/// Attempts to deserialize an element from its compressed encoding.
fn from_compressed(bytes: &Self::Compressed) -> CtOption<Self>;
/// Attempts to deserialize a compressed element, not checking if the element is in
/// the correct subgroup.
///
/// **This is dangerous to call unless you trust the bytes you are reading; otherwise,
/// API invariants may be broken.** Please consider using
/// [`CurveAffine::from_compressed`] instead.
fn from_compressed_unchecked(bytes: &Self::Compressed) -> CtOption<Self>;
/// Converts this element into its compressed encoding, so long as it's not
/// the point at infinity.
fn to_compressed(&self) -> Self::Compressed;
/// Attempts to deserialize an element from its uncompressed encoding.
fn from_uncompressed(bytes: &Self::Uncompressed) -> CtOption<Self>;
/// Attempts to deserialize an uncompressed element, not checking if the element is in
/// the correct subgroup.
///
/// **This is dangerous to call unless you trust the bytes you are reading; otherwise,
/// API invariants may be broken.** Please consider using
/// [`CurveAffine::from_uncompressed`] instead.
fn from_uncompressed_unchecked(bytes: &Self::Uncompressed) -> CtOption<Self>;
/// Converts this element into its uncompressed encoding, so long as it's not
/// the point at infinity.
fn to_uncompressed(&self) -> Self::Uncompressed;
}