openzeppelin_crypto/curve/te/
mod.rs

1//! This module contains definitions for the [Twisted Edwards model] of the
2//! curve.
3//!
4//! [Twisted Edwards model]: https://www.hyperelliptic.org/EFD/g1p/auto-twisted.html
5use num_traits::Zero;
6
7mod affine;
8pub use affine::*;
9
10mod projective;
11pub use projective::*;
12
13pub mod instance;
14
15use crate::{
16    bits::BitIteratorBE,
17    curve::AffineRepr,
18    field::{group::AdditiveGroup, prime::PrimeField},
19};
20
21/// Constants and convenience functions
22/// that define the [Twisted Edwards model] of the curve.
23///
24/// In this model, the curve equation is `a * x² + y² = 1 + d * x² * y²`, for
25/// constants `a` and `d`.
26///
27/// [Twisted Edwards model]: https://www.hyperelliptic.org/EFD/g1p/auto-twisted.html
28pub trait TECurveConfig: super::CurveConfig {
29    /// Coefficient `a` of the curve equation.
30    const COEFF_A: Self::BaseField;
31    /// Coefficient `d` of the curve equation.
32    const COEFF_D: Self::BaseField;
33    /// Generator of the prime-order subgroup.
34    const GENERATOR: Affine<Self>;
35
36    /// Model parameters for the Montgomery curve that is birationally
37    /// equivalent to this curve.
38    type MontCurveConfig: MontCurveConfig<BaseField = Self::BaseField>;
39
40    /// Helper method for computing `elem * Self::COEFF_A`.
41    ///
42    /// The default implementation should be overridden only if
43    /// the product can be computed faster than standard field multiplication
44    /// (eg: via doubling if `COEFF_A == 2`, or if `COEFF_A.is_zero()`).
45    #[inline(always)]
46    fn mul_by_a(elem: Self::BaseField) -> Self::BaseField {
47        elem * Self::COEFF_A
48    }
49
50    /// Checks that the current point is in the prime order subgroup, assuming
51    /// the point is already on the curve.
52    fn is_in_prime_order_subgroup(item: &Affine<Self>) -> bool {
53        Self::mul_affine(item, Self::ScalarField::characteristic()).is_zero()
54    }
55
56    /// Performs cofactor clearing.
57    /// The default method is simply to multiply by the cofactor.
58    /// For some curve families though, it is sufficient to multiply
59    /// by a smaller scalar.
60    fn clear_cofactor(item: &Affine<Self>) -> Affine<Self> {
61        item.mul_by_cofactor()
62    }
63
64    /// Default implementation of group multiplication for projective
65    /// coordinates.
66    fn mul_projective(
67        base: &Projective<Self>,
68        scalar: impl BitIteratorBE,
69    ) -> Projective<Self> {
70        let mut res = Projective::zero();
71        for b in scalar.bit_be_trimmed_iter() {
72            res.double_in_place();
73            if b {
74                res += base;
75            }
76        }
77
78        res
79    }
80
81    /// Default implementation of group multiplication for affine
82    /// coordinates.
83    fn mul_affine(
84        base: &Affine<Self>,
85        scalar: impl BitIteratorBE,
86    ) -> Projective<Self> {
87        let mut res = Projective::zero();
88        for b in scalar.bit_be_trimmed_iter() {
89            res.double_in_place();
90            if b {
91                res += base;
92            }
93        }
94
95        res
96    }
97}
98
99/// Constants and convenience functions that collectively define the [Montgomery model](https://www.hyperelliptic.org/EFD/g1p/auto-montgom.html)
100/// of the curve.
101///
102/// In this model, the curve equation is `b * y² = x³ + a * x² + x`, for
103/// constants `a` and `b`.
104pub trait MontCurveConfig: super::CurveConfig {
105    /// Coefficient `a` of the curve equation.
106    const COEFF_A: Self::BaseField;
107    /// Coefficient `b` of the curve equation.
108    const COEFF_B: Self::BaseField;
109
110    /// Model parameters for the Twisted Edwards curve that is birationally
111    /// equivalent to this curve.
112    type TECurveConfig: TECurveConfig<BaseField = Self::BaseField>;
113}