group/cofactor.rs
1use core::fmt;
2use core::ops::{Mul, Neg};
3use ff::PrimeField;
4use subtle::{Choice, CtOption};
5
6use crate::{prime::PrimeGroup, Curve, Group, GroupEncoding, GroupOps, GroupOpsOwned};
7
8/// This trait represents an element of a cryptographic group with a large prime-order
9/// subgroup and a comparatively-small cofactor.
10pub trait CofactorGroup:
11 Group
12 + GroupEncoding
13 + GroupOps<<Self as CofactorGroup>::Subgroup>
14 + GroupOpsOwned<<Self as CofactorGroup>::Subgroup>
15{
16 /// The large prime-order subgroup in which cryptographic operations are performed.
17 /// If `Self` implements `PrimeGroup`, then `Self::Subgroup` may be `Self`.
18 type Subgroup: PrimeGroup<Scalar = Self::Scalar> + Into<Self>;
19
20 /// Maps `self` to the prime-order subgroup by multiplying this element by some
21 /// `k`-multiple of the cofactor.
22 ///
23 /// The value `k` does not vary between inputs for a given implementation, but may
24 /// vary between different implementations of `CofactorGroup` because some groups have
25 /// more efficient methods of clearing the cofactor when `k` is allowed to be
26 /// different than `1`.
27 ///
28 /// If `Self` implements [`PrimeGroup`], this returns `self`.
29 fn clear_cofactor(&self) -> Self::Subgroup;
30
31 /// Returns `self` if it is contained in the prime-order subgroup.
32 ///
33 /// If `Self` implements [`PrimeGroup`], this returns `Some(self)`.
34 fn into_subgroup(self) -> CtOption<Self::Subgroup>;
35
36 /// Determines if this element is of small order.
37 ///
38 /// Returns:
39 /// - `true` if `self` is in the torsion subgroup.
40 /// - `false` if `self` is not in the torsion subgroup.
41 fn is_small_order(&self) -> Choice {
42 self.clear_cofactor().is_identity()
43 }
44
45 /// Determines if this element is "torsion free", i.e., is contained in the
46 /// prime-order subgroup.
47 ///
48 /// Returns:
49 /// - `true` if `self` has trivial torsion and is in the prime-order subgroup.
50 /// - `false` if `self` has non-zero torsion component and is not in the prime-order
51 /// subgroup.
52 fn is_torsion_free(&self) -> Choice;
53}
54
55/// Efficient representation of an elliptic curve point guaranteed to be
56/// in the correct prime order subgroup.
57pub trait CofactorCurve:
58 Curve<AffineRepr = <Self as CofactorCurve>::Affine> + CofactorGroup
59{
60 type Affine: CofactorCurveAffine<Curve = Self, Scalar = Self::Scalar>
61 + Mul<Self::Scalar, Output = Self>
62 + for<'r> Mul<&'r Self::Scalar, Output = Self>;
63}
64
65/// Affine representation of an elliptic curve point guaranteed to be
66/// in the correct prime order subgroup.
67pub trait CofactorCurveAffine:
68 GroupEncoding
69 + Copy
70 + Clone
71 + Sized
72 + Send
73 + Sync
74 + fmt::Debug
75 + PartialEq
76 + Eq
77 + 'static
78 + Neg<Output = Self>
79 + Mul<<Self as CofactorCurveAffine>::Scalar, Output = <Self as CofactorCurveAffine>::Curve>
80 + for<'r> Mul<
81 &'r <Self as CofactorCurveAffine>::Scalar,
82 Output = <Self as CofactorCurveAffine>::Curve,
83 >
84{
85 type Scalar: PrimeField;
86 type Curve: CofactorCurve<Affine = Self, Scalar = Self::Scalar>;
87
88 /// Returns the additive identity.
89 fn identity() -> Self;
90
91 /// Returns a fixed generator of unknown exponent.
92 fn generator() -> Self;
93
94 /// Determines if this point represents the point at infinity; the
95 /// additive identity.
96 fn is_identity(&self) -> Choice;
97
98 /// Converts this element to its curve representation.
99 fn to_curve(&self) -> Self::Curve;
100}