Class Ed25519
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 —
generatePrivateKeyreturns a 32-byte seed;generatePublicKey(viascalarMultBaseEncoded) computesA = s * Bwheresis the SHA-512-expanded clamped secret scalar (RFC 8032 sec. 5.1.5), using the constant-time signed multi-combscalarMultBase. - Signing —
signcomputesR = r * B(signed multi-comb) wherer = SHA-512(prefix || M) mod L, thenS = (r + k * s) mod L(RFC 8032 sec. 5.1.6). Reduction moduloLusesScalar25519.reduce512(Barrett-style, straight-line). No variable-base scalar multiplication is performed. - Verification —
verifyuses the basis reduction algorithm of Pornin viaScalar25519.reduceBasisVarthen evaluates the combined relation with Strauss-Shamir's trick inscalarMultStraus128Var. 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 ClassesModifier and TypeClassDescriptionstatic final classstatic classMethods that work with expanded format for private keys (xk/xkOff) i.e.static final class -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intstatic final intstatic final intstatic final int -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic Digeststatic voidencodePublicPoint(Ed25519.PublicPoint publicPoint, byte[] pk, int pkOff) static voidgeneratePrivateKey(SecureRandom random, byte[] k) static Ed25519.PublicPointgeneratePublicKey(byte[] sk, int skOff) static voidgeneratePublicKey(byte[] sk, int skOff, byte[] pk, int pkOff) static voidstatic voidscalarMultBaseYZ(X25519.Friend friend, byte[] k, int kOff, int[] y, int[] z) NOTE: Only for use by X25519static voidsign(byte[] sk, int skOff, byte[] ctx, byte[] m, int mOff, int mLen, byte[] sig, int sigOff) static voidsign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte[] m, int mOff, int mLen, byte[] sig, int sigOff) static voidsign(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] m, int mOff, int mLen, byte[] sig, int sigOff) static voidsign(byte[] sk, int skOff, byte[] m, int mOff, int mLen, byte[] sig, int sigOff) static voidsignPrehash(byte[] sk, int skOff, byte[] ctx, byte[] ph, int phOff, byte[] sig, int sigOff) static voidsignPrehash(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, byte[] ph, int phOff, byte[] sig, int sigOff) static voidsignPrehash(byte[] sk, int skOff, byte[] pk, int pkOff, byte[] ctx, Digest ph, byte[] sig, int sigOff) static voidsignPrehash(byte[] sk, int skOff, byte[] ctx, Digest ph, byte[] sig, int sigOff) static booleanvalidatePublicKeyFull(byte[] pk, int pkOff) static Ed25519.PublicPointvalidatePublicKeyFullExport(byte[] pk, int pkOff) static booleanvalidatePublicKeyPartial(byte[] pk, int pkOff) static Ed25519.PublicPointvalidatePublicKeyPartialExport(byte[] pk, int pkOff) static booleanverify(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, byte[] m, int mOff, int mLen) static booleanverify(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] m, int mOff, int mLen) static booleanverify(byte[] sig, int sigOff, Ed25519.PublicPoint publicPoint, byte[] ctx, byte[] m, int mOff, int mLen) static booleanverify(byte[] sig, int sigOff, Ed25519.PublicPoint publicPoint, byte[] m, int mOff, int mLen) static booleanverifyPrehash(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, byte[] ph, int phOff) static booleanverifyPrehash(byte[] sig, int sigOff, byte[] pk, int pkOff, byte[] ctx, Digest ph) static booleanverifyPrehash(byte[] sig, int sigOff, Ed25519.PublicPoint publicPoint, byte[] ctx, byte[] ph, int phOff) static booleanverifyPrehash(byte[] sig, int sigOff, Ed25519.PublicPoint publicPoint, byte[] ctx, Digest ph)
-
Field Details
-
PREHASH_SIZE
public static final int PREHASH_SIZE- See Also:
-
PUBLIC_KEY_SIZE
public static final int PUBLIC_KEY_SIZE- See Also:
-
SECRET_KEY_SIZE
public static final int SECRET_KEY_SIZE- See Also:
-
SIGNATURE_SIZE
public static final int SIGNATURE_SIZE- See Also:
-
-
Constructor Details
-
Ed25519
public Ed25519()
-
-
Method Details
-
createPrehash
-
encodePublicPoint
-
generatePrivateKey
-
generatePublicKey
public static void generatePublicKey(byte[] sk, int skOff, byte[] pk, int pkOff) -
generatePublicKey
-
precompute
public static void precompute() -
scalarMultBaseYZ
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
-
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
-
validatePublicKeyPartial
public static boolean validatePublicKeyPartial(byte[] pk, int pkOff) -
validatePublicKeyPartialExport
-
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)
-