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}