Skip to content

Ed25519 verification strictness differs between Rust and Go #12

@OkeyAmy

Description

@OkeyAmy

The Problem

The Rust core (drs-core) uses ed25519-dalek with verify_strict(). The Go verifier (drs-verify) uses stdlib crypto/ed25519.Verify(). These do not accept the same set of signatures.

verify_strict rejects:

  • Non-canonical S values (S >= L, where L is the Ed25519 group order)
  • Small-order public keys (8 torsion points)
  • Uses the cofactored verification equation: [8][S]B = [8]R + [8][k]A

Go's crypto/ed25519.Verify does none of this. It accepts signatures that Rust rejects.

This means a signature verified by Go may fail when verified by Rust — or worse, an attacker can craft a signature that Go accepts but Rust rejects, creating inconsistent verification outcomes across layers.


Where It Breaks

Layer File Call
Rust drs-core/src/crypto/ed25519.rs verify_strict()
Go drs-verify/pkg/verify/chain.go:456 ed25519.Verify(pubKey, msg, sig)

What Must Change

  1. Document the divergence — Identify the exact differences between Go stdlib ed25519.Verify and ed25519-dalek verify_strict. Which non-canonical inputs does each accept or reject?

  2. Evaluate stricter Go verification — Options:

    • Use filippo.io/edwards25519 to implement strict verification in Go
    • Use ed25519consensus from the Cosmos SDK (implements ZIP-215 + cofactored verification)
    • Accept the divergence and document it as a known difference
  3. Add test vectors — Cover the edge cases: non-canonical S values, small-order keys, mixed-order points. Both layers must produce the same result for the same input.

  4. Write the assessment in drs-verify/docs/component.md as required by the audit.


Severity

MEDIUM

In practice, legitimate Ed25519 implementations produce canonical signatures. The risk is adversarial: a party deliberately crafting non-canonical signatures to exploit the divergence. The blast radius depends on whether both layers verify the same bundles in production.

Metadata

Metadata

Assignees

No one assigned

    Labels

    mediumMedium severitysecuritySecurity vulnerability or hardening

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions