ddn.crypto.internal.ed25519ct

Constant-time Ed25519 signing and public-key derivation.

This module implements the secret-bearing half of RFC 8032 Ed25519 on top of the fixed-width field arithmetic in fe25519:

  • Scalars are reduced and multiplied modulo the group order

    L with byte-limb schoolbook arithmetic and a fixed-iteration shift-subtract reduction. Every conditional operation selects through masks; loop counts never depend on secret data.

  • Points live in extended twisted-Edwards coordinates over

    Fe25519. The single addition formula is the unified (complete, for a = -1 square and d non-square) add-2008-hwcd construction, used for both addition and doubling exactly as in widely reviewed minimal implementations, so no input-dependent case analysis exists.

  • Scalar multiplication runs a fixed 256-iteration

    conditional-swap ladder over that unified addition, again with a constant iteration count and branch-free selection.

  • Every secret scalar, expanded key half, and ladder point is

    wiped through Fe25519.wipe or volatile byte stores as soon as it is consumed; no secret material waits for garbage collection.

Security

Note

as with fe25519 and ddn.crypto.ct,

structural constant-time design is necessary but not sufficient proof; compilers and CPUs may still introduce timing variations. The BigInt verification paths in ddn.crypto.signature.ed25519 operate on public data only and are intentionally unchanged.

Types 1

private structGe25519

A point of the Ed25519 curve in extended coordinates (X : Y : Z : T) with affine x = X/Z, y = Y/Z, and xy = T/Z.

Methods
Ge25519 identity() static pure nothrow @safe @nogcReturns: the neutral element (0).
Ge25519 basePoint() static pure nothrow @safe @nogcReturns: the Ed25519 base point.
void wipe() @trusted nothrow @nogcWipes all four coordinates.
void cswap(uint doSwap, ref Ge25519 other) nothrow @safe @nogcConditionally swaps this point with another.

Functions 19

private fnvoid wipeBytes(ubyte[] bytes) @trusted nothrow @nogcWipes a fixed-size secret byte buffer with volatile stores.
private fnvoid shiftRight1(ref ubyte[64] v) pure nothrow @safe @nogcShifts a 64-byte little-endian value right by one bit.
private fnvoid shiftLeft1(ref ubyte[64] v) pure nothrow @safe @nogcShifts a 64-byte little-endian value left by one bit.
private fnvoid condSub(ref ubyte[64] t, scope const ref ubyte[64] d) nothrow @trusted @nogcSubtracts d from t when t >= d, branchlessly.
fnubyte[32] scReduce(scope const ref ubyte[64] w) nothrow @trusted @nogcReduces a 512-bit little-endian integer modulo the group order.
fnubyte[32] scMul(scope const ref ubyte[32] a, scope const ref ubyte[32] b) nothrow @trusted @nogcMultiplies two scalars modulo the group order.
fnubyte[32] scMulAdd(scope const ref ubyte[32] x, scope const ref ubyte[32] y, scope const ref ubyte[32] z) nothrow @trusted @nogcComputes x + y * z mod L.
fnuint scBit(scope const ref ubyte[32] s, int i) pure nothrow @safe @nogcExtracts one bit of a little-endian scalar.
private fnFe25519 feConstant(string hex) pure nothrow @safe @nogcLoads a field element from 64 little-endian hex digits.
private fnubyte hexNibble(char c) pure nothrow @safe @nogc
private fnFe25519 curveD() pure nothrow @safe @nogcThe curve constant d as a field element.
private fnFe25519 invertSecret(scope const ref Fe25519 value) nothrow @trusted @nogcInverts a secret field element while wiping each replaced accumulator.
private fnGe25519 geAdd(scope const ref Ge25519 p, scope const ref Ge25519 q) nothrow @trusted @nogcUnified twisted-Edwards point addition (and doubling).
private fnubyte[32] geEncode(scope const ref Ge25519 p) nothrow @trusted @nogcEncodes a point in the 32-byte compressed form.
private fnubyte[32] geScalarMultBase(scope const ref ubyte[32] scalar) nothrow @safe @nogcMultiplies the base point by a scalar with a fixed conditional-swap ladder.
fnubyte[32] ed25519PublicCT(scope const(ubyte)[] seed) @trustedDerives the Ed25519 public key of a private seed.
fnubyte[64] ed25519SignCT(scope const(ubyte)[] seed, scope const(ubyte)[] message) @trustedProduces an RFC 8032 Ed25519 signature.
private fnvoid enforceSeed(scope const(ubyte)[] seed) @safe pureValidates the private seed length.
private fnubyte[32] expandAndClamp(scope const(ubyte)[] seed) @trustedExpands and clamps a seed into the secret scalar.

Variables 1

varubyte[32] SC_L

The Ed25519 group order L = 2^252 + 27742317777372353535851937790883648493 as 32 little-endian bytes.