Skip to content

Link from AffinePoint,ProjectivePoint and Scalar to curve type #1995

Closed as not planned

Description

@daxpedda

I was considering finally moving the GroupDigest trait to ProjectivePoint itself.
This wasn't really possible before because GroupDigest still included hash_to_scalar(), but this is moved away in RustCrypto/elliptic-curves#1389.

However, I noticed that there is no way to access the curve type itself, e.g. NistP256, from ProjectivePoint. The same applies to Scalar. This would be needed to access traits that are on the curve type but not on the point or scalar. In this case MapToCurve::SecurityLevel.

Therefor, I propose adding a new trait:

pub trait AssociatedCurve {
    type Curve: Curve;
}

which would be implemented for AffinePoint,ProjectivePoint and Scalar.

Ideally, this could just be an associated type on Curve, CurveAffine and Field, but they don't seem to deal with this sort of ZST for a curve AFAICS. Its also moving quite slow in comparison to RustCrypto.

Activity

  1. tarcieri commented on Sep 4, 2025

    @tarcieri
    Member

    #1911 seems relevant here.

    I'll say the general idea of even having the ZST and functions impl'd on it permits access to the entire family of types. I've generally thought of it as a top-down hierarchy where elliptic-curve is solely additive upon group.

    Needing to go from one of the members of that family of types back to the ZST seems like a potential sign the functionality should be factored off of the ZST, or if that doesn't make sense, perhaps it should stay there.

  2. daxpedda commented on Sep 4, 2025

    @daxpedda
    ContributorAuthor

    I will give more context then.

    Before RustCrypto/elliptic-curves#1389, the reason why we had this trait on the ZST instead of ProjectivePoint, is because it included hash_to_scalar(). Calling ProjectivePoint::hash_to_scalar() seems a bit messed up to me.

    After RustCrypto/elliptic-curves#1389, hash_to_scalar() is a separate standalone function. It seems obvious to me that ProjectivePoint::hash_from_bytes() and ProjectivePoint::encode_from_bytes() (both returning ProjectivePoint) seem better then NistP256::hash_from_bytes() returning a ProjectivePoint.

    The problem arises when we implement GroupDigest for ProjectivePoint (instead of the ZST), we don't have access to MapToCurve. So we could move MapToCurve to ProjectivePoint as well, but then hash_to_scalar() can't access MapToCurve::SecurityLevel. We could also require the standalone functions to require the ZST instead of ProjectivePoint and Scalar. Ergo hash_to_scalar::<NistP256, ...>(...) instead of hash_to_scalar::<Scalar, ...>(...), which is fine of course.

    However, I believe the ideal scenario would be something like this:

    impl MapToCurveParameters for NistP256 {
        type SecurityLevel;
    }
    
    impl MapToCurve for ProjectivePoint {
        type FieldElement;
        type Length;
    
        fn map_to_curve(element: Self::FieldElement) -> Self;
    }
    
    impl GroupDigest for ProjectivePoint: AssociatedCurve {
        const HASH_TO_CURVE_DST;
        const ENCODE_TO_CURVE_DST;
    
        type ExpandMsg: ExpandMsg<<Self::Curve as MapToCurveParameters>::SecurityLevel>;
    }

    Considering its totally possible to find other solutions to move GroupDigest to ProjectivePoint, if this is the only motivation, we can close this issue.

  3. daxpedda commented on Sep 16, 2025

    @daxpedda
    ContributorAuthor

    I'm gonna go ahead and close this.

    I should mention that the original motivation is diminished as well if we want to move GroupDigest to Point<C> instead. See #1900 (comment).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions