Skip to main content

primitives/algebra/elliptic_curve/
curve.rs

1use std::{hash::Hash, ops::ShrAssign};
2
3use derive_more::derive::Display;
4use elliptic_curve::{
5    group::{self, GroupEncoding},
6    ops::{Invert, MulByGenerator},
7    scalar::{FromUintUnchecked, IsHigh},
8    Curve as EllipticCurve,
9    FieldBytes,
10    ScalarPrimitive,
11};
12use ff::PrimeField;
13use subtle::{ConditionallySelectable, ConstantTimeEq, CtOption};
14
15use crate::algebra::{
16    field::{FieldElement, FieldExtension, SubfieldElement},
17    uniform_bytes::FromUniformBytes,
18};
19
20// Defines a curve that can be encoded and decoded into bytes.
21// This is a reduced version of the elliptic_curve::CurveArithmetic trait that is suitable for our
22// MPC purposes. In particular, we removed the AffinePoint type.
23pub trait Curve: EllipticCurve {
24    /// Whether this curve uses big-endian for its scalar encoding natively.
25    const SCALAR_BIG_ENDIAN: bool;
26    /// Whether this curve uses big-endian for its point encoding natively.
27    const POINT_BIG_ENDIAN: bool;
28
29    const BASE_FIELD_BIG_ENDIAN: bool;
30    /// Elliptic curve point in projective coordinates.
31    ///
32    /// Note: the following bounds are provided by [`group::Group`]:
33    /// - `'static`
34    /// - [`Copy`]
35    /// - [`Clone`]
36    /// - [`Debug`]
37    /// - [`Eq`]
38    /// - [`Sized`]
39    /// - [`Send`]
40    /// - [`Sync`]
41    type Point: ConditionallySelectable
42        + ConstantTimeEq
43        + Default
44        // Implemented differently for Dalek
45        // + DefaultIsZeroes
46
47        // These require Affine Repr
48        // + LinearCombination<[(Self::ProjectivePoint, Self::Scalar)]>
49        // + LinearCombination<[(Self::ProjectivePoint, Self::Scalar); 2]>
50        + MulByGenerator
51        + group::Group<Scalar = Self::Scalar>
52        + GroupEncoding
53        + Hash
54        + FromExtendedEdwards<BaseFieldElement = BaseFieldElement<Self>>
55        + ToExtendedEdwards<BaseFieldElement = BaseFieldElement<Self>>;
56
57    /// Scalar field modulo this curve's order.
58    ///
59    /// Note: the following bounds are provided by [`ff::Field`]:
60    /// - `'static`
61    /// - [`Copy`]
62    /// - [`Clone`]
63    /// - [`ConditionallySelectable`]
64    /// - [`ConstantTimeEq`]
65    /// - [`Debug`]
66    /// - [`Default`]
67    /// - [`Send`]
68    /// - [`Sync`]
69    type Scalar: AsRef<Self::Scalar>
70        // + DefaultIsZeroes
71        + From<ScalarPrimitive<Self>>
72        + FromUintUnchecked<Uint = Self::Uint>
73        + Into<FieldBytes<Self>>
74        + Into<ScalarPrimitive<Self>>
75        + Into<Self::Uint>
76        + Invert<Output = CtOption<Self::Scalar>>
77        + FromUniformBytes
78        + IsHigh
79        + PartialOrd
80        + ShrAssign<usize>
81        + PrimeField
82        + FieldExtension<Subfield = Self::Scalar>
83        + Hash;
84
85    type BaseField: PrimeField + FieldExtension + ShrAssign<usize> + FromUniformBytes + Hash;
86
87    fn hash_to_curve(bytes: &[u8]) -> Self::Point;
88}
89
90pub trait FromExtendedEdwards {
91    type BaseFieldElement;
92
93    fn from_extended_edwards(coordinates: [Self::BaseFieldElement; 4]) -> Option<Self>
94    where
95        Self: Sized;
96}
97
98#[derive(Display)]
99pub struct PointAtInfinityError;
100
101pub trait ToExtendedEdwards {
102    type BaseFieldElement;
103
104    fn to_extended_edwards(self) -> Result<[Self::BaseFieldElement; 4], PointAtInfinityError>;
105}
106
107/// The scalar field of the curve.
108pub type ScalarField<C> = <C as Curve>::Scalar;
109/// The base field (coordinates of the points) of the curve.
110pub type BaseField<C> = <C as Curve>::BaseField;
111
112/// The scalar field of the curve as a subfield element.
113pub type Scalar<C> = SubfieldElement<ScalarField<C>>;
114/// The base field of the curve as a subfield element.
115pub type BaseFieldElement<C> = SubfieldElement<BaseField<C>>;
116
117/// The scalar field of the curve as a field extension element.
118pub type ScalarAsExtension<C> = FieldElement<<C as Curve>::Scalar>;
119/// The base field of the curve as a field extension element.
120pub type BaseFieldAsExtension<C> = FieldElement<BaseField<C>>;