Skip to content

Ed25519 validation criteria #55

Description

@tarcieri

Both the C and Java backends of this crate implement "ref10" validation criteria, i.e. the ones used by the original implementation of Ed25519 extracted from SUPERCOP.

The README of this crate notes that Ed25519 is described in RFC8032, however the validation criteria in the RFC differ from "ref10" in that they require all encoded field elements (i.e. base and scalar field elements) are canonical, i.e. the coordinate of R is less than p and s is less than l.

The goal of this change was to prevent malleability, however the handling of torsion components is un(der)specified in that it says implementations can effectively pick their own rules. This means some implementations allow malleability in the form of torsion components and different RFC8032-conforming implementations can make different decisions about which signatures are valid, as criticized in the blog post "It's 255:19AM. Do you know what your validation criteria are?".

I'll further note the README of this crate doesn't actually claim it conforms to RFC8032, only where one can find a specification about it. We've had suggestions to change our validation criteria away from "ref10" to RFC8032 (#54), however this crate is nearly a decade old (longer if you count the previous red25519 crate it descended from which predates RFC8032) and changing the validation criteria at this point would change the set of accepted signatures and in that regard can be considered a breaking change.

So, the question is: should we actually change our validation criteria at this point? I think one of two things should happen:

  1. We should either keep "ref10" validation criteria and document where we diverge from the RFC
  2. We should adopt RFC8032 validation criteria and update the README to say we actually implement the RFC, in which case both the C and Java backends need to be updated accordingly

The "255:19AM" blog post makes the case for ZIP-215 validation criteria which goes effectively in the reverse direction from RFC8032: it accepts certain non-canonical point encodings and uses cofactored verification, thereby permitting signatures involving points with torsion components.

I'm somewhat loathe to change the existing validation criteria without a major version bump. We could instead potentially introduce verify_strict or verify_rfc8032 which adds the additional checks, which could be implemented in pure Ruby, and then calls into the native extension(s).

Edit: I should probably also note that while "signature malleability" sounds scary, its security impact is highly application-dependent. For many ordinary uses of digital signatures it has little practical consequence. The extent to which it is worth addressing highly depends on the intended use case, i.e. does the application hash signatures and try to use the hash as some sort of identifier, which is a somewhat questionable thing to do vs using key fingerprints and/or hashes of the signed content as identifiers instead.

Activity

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