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}