group: CofactorGroup::mul_by_cofactor -> CofactorGroup::clear_cofactor

The generic API now only guarantees that the torsion component is
cleared deterministically; group elements may be multiplied by multiples
of the cofactor (not necessarily the actual cofactor), as long as the
choice of multiplier is fixed for a given implementation.
This commit is contained in:
Jack Grigg 2020-08-12 08:02:29 +01:00
parent 18b1ce7401
commit 1e8fd4da68
3 changed files with 13 additions and 5 deletions

View File

@ -399,7 +399,7 @@ impl PrimeGroup for Fr {}
impl CofactorGroup for Fr {
type Subgroup = Fr;
fn mul_by_cofactor(&self) -> Self::Subgroup {
fn clear_cofactor(&self) -> Self::Subgroup {
*self
}

View File

@ -17,10 +17,16 @@ pub trait CofactorGroup:
/// If `Self` implements `PrimeGroup`, then `Self::Subgroup` may be `Self`.
type Subgroup: PrimeGroup<Scalar = Self::Scalar> + Into<Self>;
/// Returns `[h] self`, where `h` is the cofactor of the group.
/// Maps `self` to the prime-order subgroup by clearing any torsion component.
///
/// This function computes `[k.h] self`; that is, this function multiplies `self` by a
/// multiple of the cofactor (not necessarily the actual cofactor).
///
/// This function is deterministic: `k` is fixed for a given implementation, and the
/// map defined by this function is opaque, but well-defined.
///
/// If `Self` implements [`PrimeGroup`], this returns `self`.
fn mul_by_cofactor(&self) -> Self::Subgroup;
fn clear_cofactor(&self) -> Self::Subgroup;
/// Returns `self` if it is contained in the prime-order subgroup.
///
@ -33,7 +39,7 @@ pub trait CofactorGroup:
/// - `true` if `self` is in the torsion subgroup.
/// - `false` if `self` is not in the torsion subgroup.
fn is_small_order(&self) -> Choice {
self.mul_by_cofactor().is_identity()
self.clear_cofactor().is_identity()
}
/// Determines if this element is "torsion free", i.e., is contained in the

View File

@ -1024,7 +1024,9 @@ macro_rules! curve_impl {
impl CofactorGroup for $projective {
type Subgroup = $subgroup;
fn mul_by_cofactor(&self) -> Self::Subgroup {
fn clear_cofactor(&self) -> Self::Subgroup {
// This implementation uses the cofactor directly, and differs from the
// bls12_381 crate which uses a multiple of the cofactor.
$subgroup($affine::from(*self).scale_by_cofactor().into())
}