Skip to main content

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