Ed25519 (Bouncy Castle Library 1.85 API Specification)
Date: 2026-07-12

org.bouncycastle.math.ec.rfc8032

## Class Ed25519

- java.lang.Object
- - org.bouncycastle.math.ec.rfc8032.Ed25519

-     public abstract class Ed25519
      extends java.lang.Object

  A low-level implementation of the Ed25519, Ed25519ctx, and Ed25519ph instantiations of the Edwards-Curve Digital Signature Algorithm specified in RFC 8032.

  The implementation strategy is mostly drawn from Mike Hamburg, "Fast and compact elliptic-curve cryptography", notably the "signed multi-comb" algorithm (for scalar multiplication by a fixed point), the "half Niels coordinates" (for precomputed points), and the "extensible coordinates" (for accumulators). Standard extended coordinates are used during precomputations, needing only a single extra point addition formula.

  Algorithm map.

  - Key generation — `generatePrivateKey` returns a 32-byte seed; `generatePublicKey` (via `scalarMultBaseEncoded`) computes `A = s * B` where `s` is the SHA-512-expanded clamped secret scalar (RFC 8032 sec. 5.1.5), using the constant-time signed multi-comb `scalarMultBase`.
  - Signing — `sign` computes `R = r * B` (signed multi-comb) where `r = SHA-512(prefix || M) mod L`, then `S = (r + k * s) mod L` (RFC 8032 sec. 5.1.6). Reduction modulo `L` uses `Scalar25519.reduce512` (Barrett-style, straight-line). No variable-base scalar multiplication is performed.
  - Verification — `verify` uses the basis reduction algorithm of Pornin via `Scalar25519.reduceBasisVar` then evaluates the combined relation with Strauss-Shamir's trick in `scalarMultStraus128Var`. Both routines are deliberately variable-time and operate only on public material (signature, message, public key).
  - Coordinates — the precomputed base-point comb table lives in half-Niels form; signing-side accumulators use extensible (twisted Edwards) coordinates so each step needs only one extra point-addition formula. Verification re-uses projective extended coordinates throughout.

  Side-channel scope. The signing path (which operates on the secret seed, the derived secret scalar, and the secret per-message nonce) is written to be constant-time at the Java level: the comb `scalarMultBase` walks all precomputed entries via mask-based `cmov` rather than a secret-indexed array load, conditional sign application uses XOR-with-mask `cnegate`, scalar recoding via `toSignedDigits` uses mask-driven `caddTo`, and `Scalar25519.reduce512` is fully unrolled straight-line arithmetic. This is sufficient against a remote network timing attacker but is not a substitute for a constant-time native implementation against a co-located cache-line-resolution adversary — JVM-level timing variance from JIT, GC and cache eviction is not addressable in pure Java. Verification routines (those suffixed `Var`) are deliberately variable-time and operate only on public material.

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `static class` | `Ed25519.Algorithm`
    `static class` | `Ed25519.ExpandedKey` Methods that work with expanded format for private keys (xk/xkOff) i.e.
    `static class` | `Ed25519.PublicPoint`

  - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `static int` | `PREHASH_SIZE`
    `static int` | `PUBLIC_KEY_SIZE`
    `static int` | `SECRET_KEY_SIZE`
    `static int` | `SIGNATURE_SIZE`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `Ed25519()`

  - ### Method Summary

    All Methods Static Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `static Digest` | `createPrehash()`
    `static void` | `encodePublicPoint(Ed25519.PublicPoint publicPoint, byte[] pk, int pkOff)`
    `static void` | `generatePrivateKey(java.security.SecureRandom random, byte[] k)`
    `static Ed25519.PublicPoint` | `generatePublicKey(byte[] sk, int skOff)`
    `static void` | `generatePublicKey(byte[] sk, int skOff, byte[] pk, int pkOff)`
    `static void` | `precompute()`
    `static void` | `scalarMultBaseYZ(X25519.Friend friend, byte[] k, int kOff, int[] y, int[] z)` NOTE: Only for use by X25519
    `static void` | `sign(byte[] sk, int skOff, byte[] ctx, byte[] m, int mOff, int mLen, byte[] sig, int sigOff)`
    `static void` | `sign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte[] m, int mOff, int mLen, byte[] sig, int sigOff)`
    `static void` | `sign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] m, int mOff, int mLen, byte[] sig, int sigOff)`
    `static void` | `sign(byte[] sk, int skOff, byte[] m, int mOff, int mLen, byte[] sig, int sigOff)`
    `static void` | `signPrehash(byte[] sk, int skOff, byte[] ctx, byte[] ph, int phOff, byte[] sig, int sigOff)`
    `static void` | `signPrehash(byte[] sk, int skOff, byte[] ctx, Digest ph, byte[] sig, int sigOff)`
    `static void` | `signPrehash(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte[] ph, int phOff, byte[] sig, int sigOff)`
    `static void` | `signPrehash(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, Digest ph, byte[] sig, int sigOff)`
    `static boolean` | `validatePublicKeyFull(byte[] pk, int pkOff)`
    `static Ed25519.PublicPoint` | `validatePublicKeyFullExport(byte[] pk, int pkOff)`
    `static boolean` | `validatePublicKeyPartial(byte[] pk, int pkOff)`
    `static Ed25519.PublicPoint` | `validatePublicKeyPartialExport(byte[] pk, int pkOff)`
    `static boolean` | `verify(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, byte[] m, int mOff, int mLen)`
    `static boolean` | `verify(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] m, int mOff, int mLen)`
    `static boolean` | `verify(byte[] sig, int sigOff, Ed25519.PublicPoint publicPoint, byte[] ctx, byte[] m, int mOff, int mLen)`
    `static boolean` | `verify(byte[] sig, int sigOff, Ed25519.PublicPoint publicPoint, byte[] m, int mOff, int mLen)`
    `static boolean` | `verifyPrehash(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, byte[] ph, int phOff)`
    `static boolean` | `verifyPrehash(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, Digest ph)`
    `static boolean` | `verifyPrehash(byte[] sig, int sigOff, Ed25519.PublicPoint publicPoint, byte[] ctx, byte[] ph, int phOff)`
    `static boolean` | `verifyPrehash(byte[] sig, int sigOff, Ed25519.PublicPoint publicPoint, byte[] ctx, Digest ph)`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Field Detail

    - #### PREHASH_SIZE

          public static final int PREHASH_SIZE

      See Also:
        Constant Field Values

    - #### PUBLIC_KEY_SIZE

          public static final int PUBLIC_KEY_SIZE

      See Also:
        Constant Field Values

    - #### SECRET_KEY_SIZE

          public static final int SECRET_KEY_SIZE

      See Also:
        Constant Field Values

    - #### SIGNATURE_SIZE

          public static final int SIGNATURE_SIZE

      See Also:
        Constant Field Values

  - ### Constructor Detail

    - #### Ed25519

          public Ed25519()

  - ### Method Detail

    - #### createPrehash

          public static Digest createPrehash()

    - #### encodePublicPoint

          public static void encodePublicPoint(Ed25519.PublicPoint publicPoint,
                                               byte[] pk,
                                               int pkOff)

    - #### generatePrivateKey

          public static void generatePrivateKey(java.security.SecureRandom random,
                                                byte[] k)

    - #### generatePublicKey

          public static void generatePublicKey(byte[] sk,
                                               int skOff,
                                               byte[] pk,
                                               int pkOff)

    - #### generatePublicKey

          public static Ed25519.PublicPoint generatePublicKey(byte[] sk,
                                                              int skOff)

    - #### precompute

          public static void precompute()

    - #### scalarMultBaseYZ

          public static void scalarMultBaseYZ(X25519.Friend friend,
                                              byte[] k,
                                              int kOff,
                                              int[] y,
                                              int[] z)

      NOTE: Only for use by X25519

    - #### sign

          public static void sign(byte[] sk,
                                  int skOff,
                                  byte[] m,
                                  int mOff,
                                  int mLen,
                                  byte[] sig,
                                  int sigOff)

    - #### sign

          public static void sign(byte[] sk,
                                  int skOff,
                                  byte[] pk,
                                  int pkOff,
                                  byte[] m,
                                  int mOff,
                                  int mLen,
                                  byte[] sig,
                                  int sigOff)

    - #### sign

          public static void sign(byte[] sk,
                                  int skOff,
                                  byte[] ctx,
                                  byte[] m,
                                  int mOff,
                                  int mLen,
                                  byte[] sig,
                                  int sigOff)

    - #### sign

          public static void sign(byte[] sk,
                                  int skOff,
                                  byte[] pk,
                                  int pkOff,
                                  byte[] ctx,
                                  byte[] m,
                                  int mOff,
                                  int mLen,
                                  byte[] sig,
                                  int sigOff)

    - #### signPrehash

          public static void signPrehash(byte[] sk,
                                         int skOff,
                                         byte[] ctx,
                                         byte[] ph,
                                         int phOff,
                                         byte[] sig,
                                         int sigOff)

    - #### signPrehash

          public static void signPrehash(byte[] sk,
                                         int skOff,
                                         byte[] pk,
                                         int pkOff,
                                         byte[] ctx,
                                         byte[] ph,
                                         int phOff,
                                         byte[] sig,
                                         int sigOff)

    - #### signPrehash

          public static void signPrehash(byte[] sk,
                                         int skOff,
                                         byte[] ctx,
                                         Digest ph,
                                         byte[] sig,
                                         int sigOff)

    - #### signPrehash

          public static void signPrehash(byte[] sk,
                                         int skOff,
                                         byte[] pk,
                                         int pkOff,
                                         byte[] ctx,
                                         Digest ph,
                                         byte[] sig,
                                         int sigOff)

    - #### validatePublicKeyFull

          public static boolean validatePublicKeyFull(byte[] pk,
                                                      int pkOff)

    - #### validatePublicKeyFullExport

          public static Ed25519.PublicPoint validatePublicKeyFullExport(byte[] pk,
                                                                        int pkOff)

    - #### validatePublicKeyPartial

          public static boolean validatePublicKeyPartial(byte[] pk,
                                                         int pkOff)

    - #### validatePublicKeyPartialExport

          public static Ed25519.PublicPoint validatePublicKeyPartialExport(byte[] pk,
                                                                           int pkOff)

    - #### verify

          public static boolean verify(byte[] sig,
                                       int sigOff,
                                       byte[] pk,
                                       int pkOff,
                                       byte[] m,
                                       int mOff,
                                       int mLen)

    - #### verify

          public static boolean verify(byte[] sig,
                                       int sigOff,
                                       Ed25519.PublicPoint publicPoint,
                                       byte[] m,
                                       int mOff,
                                       int mLen)

    - #### verify

          public static boolean verify(byte[] sig,
                                       int sigOff,
                                       byte[] pk,
                                       int pkOff,
                                       byte[] ctx,
                                       byte[] m,
                                       int mOff,
                                       int mLen)

    - #### verify

          public static boolean verify(byte[] sig,
                                       int sigOff,
                                       Ed25519.PublicPoint publicPoint,
                                       byte[] ctx,
                                       byte[] m,
                                       int mOff,
                                       int mLen)

    - #### verifyPrehash

          public static boolean verifyPrehash(byte[] sig,
                                              int sigOff,
                                              byte[] pk,
                                              int pkOff,
                                              byte[] ctx,
                                              byte[] ph,
                                              int phOff)

    - #### verifyPrehash

          public static boolean verifyPrehash(byte[] sig,
                                              int sigOff,
                                              Ed25519.PublicPoint publicPoint,
                                              byte[] ctx,
                                              byte[] ph,
                                              int phOff)

    - #### verifyPrehash

          public static boolean verifyPrehash(byte[] sig,
                                              int sigOff,
                                              byte[] pk,
                                              int pkOff,
                                              byte[] ctx,
                                              Digest ph)

    - #### verifyPrehash

          public static boolean verifyPrehash(byte[] sig,
                                              int sigOff,
                                              Ed25519.PublicPoint publicPoint,
                                              byte[] ctx,
                                              Digest ph)