ark_ec/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2#![warn(
3    unused,
4    future_incompatible,
5    nonstandard_style,
6    rust_2018_idioms,
7    rust_2021_compatibility
8)]
9#![forbid(unsafe_code)]
10#![allow(
11    clippy::op_ref,
12    clippy::suspicious_op_assign_impl,
13    clippy::many_single_char_names
14)]
15#![doc = include_str!("../README.md")]
16
17#[macro_use]
18extern crate ark_std;
19
20use ark_ff::{
21    fields::{Field, PrimeField},
22    UniformRand,
23};
24use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
25use ark_std::{
26    fmt::{Debug, Display},
27    hash::Hash,
28    ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign},
29    vec::*,
30};
31pub use scalar_mul::{variable_base::VariableBaseMSM, ScalarMul};
32use zeroize::Zeroize;
33
34pub use ark_ff::AdditiveGroup;
35
36pub mod models;
37pub use self::models::*;
38
39pub mod scalar_mul;
40
41/// Provides a `HashToCurve` trait and implementations of this trait via
42/// different hashing strategies.
43pub mod hashing;
44
45pub mod pairing;
46
47/// Represents (elements of) a group of prime order `r`.
48pub trait PrimeGroup: AdditiveGroup<Scalar = Self::ScalarField> {
49    /// The scalar field `F_r`, where `r` is the order of this group.
50    type ScalarField: PrimeField;
51
52    /// Returns a fixed generator of this group.
53    #[must_use]
54    fn generator() -> Self;
55
56    /// Performs scalar multiplication of this element.
57    fn mul_bigint(&self, other: impl AsRef<[u64]>) -> Self;
58
59    /// Computes `other * self`, where `other` is a *big-endian*
60    /// bit representation of some integer.
61    fn mul_bits_be(&self, other: impl Iterator<Item = bool>) -> Self {
62        let mut res = Self::zero();
63        for b in other.skip_while(|b| !b) {
64            // skip leading zeros
65            res.double_in_place();
66            if b {
67                res += self;
68            }
69        }
70        res
71    }
72}
73
74/// An opaque representation of an elliptic curve group element that is suitable
75/// for efficient group arithmetic.
76///
77/// The point is guaranteed to be in the correct prime order subgroup.
78pub trait CurveGroup:
79    PrimeGroup
80    + Add<Self::Affine, Output = Self>
81    + AddAssign<Self::Affine>
82    + Sub<Self::Affine, Output = Self>
83    + SubAssign<Self::Affine>
84    + VariableBaseMSM
85    + ScalarMul<MulBase = Self::Affine>
86    + From<Self::Affine>
87    + Into<Self::Affine>
88    + core::iter::Sum<Self::Affine>
89    + for<'a> core::iter::Sum<&'a Self::Affine>
90{
91    type Config: CurveConfig<ScalarField = Self::ScalarField, BaseField = Self::BaseField>;
92    /// The field over which this curve is defined.
93    type BaseField: Field;
94    /// The affine representation of this element.
95    type Affine: AffineRepr<
96            Config = Self::Config,
97            Group = Self,
98            ScalarField = Self::ScalarField,
99            BaseField = Self::BaseField,
100        > + From<Self>
101        + Into<Self>;
102
103    /// Type representing an element of the full elliptic curve group, not just the
104    /// prime order subgroup.
105    type FullGroup;
106
107    /// Normalizes a slice of group elements into affine.
108    #[must_use]
109    fn normalize_batch(v: &[Self]) -> Vec<Self::Affine>;
110
111    /// Converts `self` into the affine representation.
112    fn into_affine(self) -> Self::Affine {
113        self.into()
114    }
115}
116
117/// The canonical representation of an elliptic curve group element.
118/// This should represent the affine coordinates of the point corresponding
119/// to this group element.
120///
121/// The point is guaranteed to be in the correct prime order subgroup.
122pub trait AffineRepr:
123    Eq
124    + 'static
125    + Sized
126    + CanonicalSerialize
127    + CanonicalDeserialize
128    + Copy
129    + Clone
130    + Default
131    + UniformRand
132    + Send
133    + Sync
134    + Hash
135    + Debug
136    + Display
137    + Zeroize
138    + Neg
139    + From<<Self as AffineRepr>::Group>
140    + Into<<Self as AffineRepr>::Group>
141    + Add<Self, Output = Self::Group>
142    + for<'a> Add<&'a Self, Output = Self::Group>
143    + Add<Self::Group, Output = Self::Group>
144    + for<'a> Add<&'a Self::Group, Output = Self::Group>
145    + Sub<Self, Output = Self::Group>
146    + for<'a> Sub<&'a Self, Output = Self::Group>
147    + Sub<Self::Group, Output = Self::Group>
148    + for<'a> Sub<&'a Self::Group, Output = Self::Group>
149    + Mul<Self::ScalarField, Output = Self::Group>
150    + for<'a> Mul<&'a Self::ScalarField, Output = Self::Group>
151{
152    type Config: CurveConfig<ScalarField = Self::ScalarField, BaseField = Self::BaseField>;
153    type ScalarField: PrimeField + Into<<Self::ScalarField as PrimeField>::BigInt>;
154    /// The finite field over which this curve is defined.
155    type BaseField: Field;
156
157    /// The projective representation of points on this curve.
158    type Group: CurveGroup<
159            Config = Self::Config,
160            Affine = Self,
161            ScalarField = Self::ScalarField,
162            BaseField = Self::BaseField,
163        > + From<Self>
164        + Into<Self>
165        + MulAssign<Self::ScalarField>; // needed due to https://github.com/rust-lang/rust/issues/69640
166
167    /// Returns the x and y coordinates of this affine point.
168    fn xy(&self) -> Option<(Self::BaseField, Self::BaseField)>;
169
170    /// Returns the x coordinate of this affine point.
171    fn x(&self) -> Option<Self::BaseField> {
172        self.xy().map(|(x, _)| x)
173    }
174
175    /// Returns the y coordinate of this affine point.
176    fn y(&self) -> Option<Self::BaseField> {
177        self.xy().map(|(_, y)| y)
178    }
179
180    /// Returns the point at infinity.
181    fn zero() -> Self;
182
183    /// Is `self` the point at infinity?
184    fn is_zero(&self) -> bool {
185        self.xy().is_none()
186    }
187
188    /// Returns a fixed generator of unknown exponent.
189    #[must_use]
190    fn generator() -> Self;
191
192    /// Converts self into the projective representation.
193    fn into_group(self) -> Self::Group {
194        self.into()
195    }
196
197    /// Returns a group element if the set of bytes forms a valid group element,
198    /// otherwise returns None. This function is primarily intended for sampling
199    /// random group elements from a hash-function or RNG output.
200    fn from_random_bytes(bytes: &[u8]) -> Option<Self>;
201
202    /// Performs scalar multiplication of this element with mixed addition.
203    #[must_use]
204    fn mul_bigint(&self, by: impl AsRef<[u64]>) -> Self::Group;
205
206    /// Performs cofactor clearing.
207    /// The default method is simply to multiply by the cofactor.
208    /// For some curve families more efficient methods exist.
209    #[must_use]
210    fn clear_cofactor(&self) -> Self;
211
212    /// Multiplies this element by the cofactor and output the
213    /// resulting projective element.
214    #[must_use]
215    fn mul_by_cofactor_to_group(&self) -> Self::Group;
216
217    /// Multiplies this element by the cofactor.
218    #[must_use]
219    fn mul_by_cofactor(&self) -> Self {
220        self.mul_by_cofactor_to_group().into()
221    }
222
223    /// Multiplies this element by the inverse of the cofactor in
224    /// `Self::ScalarField`.
225    #[must_use]
226    fn mul_by_cofactor_inv(&self) -> Self {
227        self.mul_bigint(Self::Config::COFACTOR_INV.into_bigint())
228            .into()
229    }
230}
231
232/// Wrapper trait representing a cycle of elliptic curves (E1, E2) such that
233/// the base field of E1 is the scalar field of E2, and the scalar field of E1
234/// is the base field of E2.
235pub trait CurveCycle
236where
237    Self::E1: MulAssign<<Self::E2 as CurveGroup>::BaseField>,
238    Self::E2: MulAssign<<Self::E1 as CurveGroup>::BaseField>,
239{
240    type E1: CurveGroup<
241        BaseField = <Self::E2 as PrimeGroup>::ScalarField,
242        ScalarField = <Self::E2 as CurveGroup>::BaseField,
243    >;
244    type E2: CurveGroup;
245}
246
247/// A cycle of curves where both curves are pairing-friendly.
248pub trait PairingFriendlyCycle: CurveCycle {
249    type Engine1: pairing::Pairing<
250        G1 = Self::E1,
251        G1Affine = <Self::E1 as CurveGroup>::Affine,
252        ScalarField = <Self::E1 as PrimeGroup>::ScalarField,
253    >;
254
255    type Engine2: pairing::Pairing<
256        G1 = Self::E2,
257        G1Affine = <Self::E2 as CurveGroup>::Affine,
258        ScalarField = <Self::E2 as PrimeGroup>::ScalarField,
259    >;
260}