Digital Signatures
DSA, ECDSA and Ed25519 — what a signature actually proves, why the per-signature nonce is the most dangerous value in applied cryptography, and the deterministic designs that removed the footgun.
A signature proves that whoever holds a specific private key saw a specific message — authenticity, integrity, and non-repudiation in one primitive. Unlike a MAC, verification requires no secret, so anyone can check it: that asymmetry is what makes certificates, code signing, and software update channels possible. The scheme mechanics are straightforward; the operational story is dominated by one value, the per-signature nonce.
What actually gets signed #
Never the message — always its hash. Signing rather than makes signatures constant-size and fast regardless of input length, but it means the signature is only as strong as the hash: a collision yields one signature valid for two different documents. This is precisely how the 2008 rogue-CA and 2012 Flame attacks worked — they attacked the hash, not the signature algorithm (see Merkle–Damgård).
DSA #
Descended from ElGamal and Schnorr, standardized in 1994 — and no longer approved. FIPS 186-5 (February 2023) removed DSA as an approved algorithm for signature generation, retaining it only to verify signatures that already exist; NIST cited lack of industry use and analyses showing DSA implementations are vulnerable when domain parameters are not properly generated. The current standard approves exactly three schemes: RSA, ECDSA and EdDSA. DSA is worth understanding anyway, because ECDSA is DSA with the group swapped and inherits its defining hazard.
It works in a prime-order subgroup: a large prime , a 160-bit (now 224/256-bit) prime dividing , and of order . Private key ; public key .
Sign message with a random per-signature secret :
Verify with and :
ECDSA is the same algebra with the multiplicative group replaced by an elliptic curve: becomes the x-coordinate of . Same equations, same nonce requirement, far smaller keys — which is why it took over TLS certificates, Bitcoin and Ethereum.
The nonce is the whole ballgame #
must be secret, unique, and unpredictable for every signature. Each property fails differently, and all three failures are total:
Reuse the same for two messages and the private key falls out algebraically. Two signatures , share — visibly, on the wire:
Leak a few bits of across many signatures and lattice reduction recovers — biased nonces need only ~100 signatures with a handful of known bits. Predict from a weak RNG and follows from a single signature.
- 2010 Sony ships the PS3 with a constant ECDSA nonce; fail0verflow extracts the console's master signing key at 27C3. Every "signed" firmware after that is forgeable.
- 2013 Android's
SecureRandomflaw repeats nonces in Bitcoin wallet signatures; thieves scan the public blockchain for repeatedrvalues and drain the affected wallets. - 2013+ Repeated-
rscanning becomes standing practice on public chains — every reuse is permanently visible to anyone. - 2022 CVE-2022-21449 ("Psychic Signatures"): Java 15–18 accepted
r = s = 0as valid for any message — a missing range check, not a nonce bug, but the same class of catastrophic verification failure.
The structural fix: deterministic and Edwards signatures #
RFC 6979 derives deterministically as HMAC-DRBG(private_key, H(m)). Same message and key always produce the same signature, no RNG is consulted at signing time, and the nonce is unpredictable to anyone without the private key. It is a drop-in change — the signatures remain standard ECDSA and verify with unmodified verifiers.
Ed25519 (RFC 8032) goes further, redesigning the scheme around the failure modes:
| Property | ECDSA | Ed25519 |
|---|---|---|
| Nonce | caller-supplied randomness | deterministic: |
| Point arithmetic | branchy, needs constant-time care | complete Edwards formulas, no special cases |
| Signature malleability | malleable (both and valid) | canonical form enforced |
| Signature / key size | 64 / 32 bytes (P-256) | 64 / 32 bytes |
| Encoding | ASN.1 DER — a parsing-bug generator | fixed-length octet strings |
| Verification pitfalls | point validation, zero checks | fewer edge cases; cofactor rules specified |
Comparing signature performance correctly #
ECDSA signing computes one fixed-base scalar multiplication plus modular arithmetic; verification combines two scalar multiplications. ECKCDSA and ECGDSA rearrange that algebra, so operation-count comparisons depend on whether inversion is performed in the scalar field or curve field, whether fixed-base tables are precomputed, and which coordinates avoid inversions during point multiplication.
That makes a symbolic count useful for explaining an implementation, but insufficient for choosing a scheme. Measure the exact curve, library, CPU, constant-time mode, precomputation memory, batch size, key/signature encoding, and verification workload. A faster formula with variable-time secret-dependent code is not an acceptable signing implementation.
The current NIST portfolio also extends beyond the classical schemes in FIPS 186-5: FIPS 204 standardizes ML-DSA and FIPS 205 standardizes SLH-DSA for post-quantum signatures. That is a migration choice with different key/signature sizes and deployment constraints, not an interchangeable “faster ECDSA.”
Source claims audit #
Seeded from a university lab manual (DSA/SSL lab, following Applied Cryptography). Status of its load-bearing claims:
| Claim from source | Status | Notes |
|---|---|---|
| DSA parameter definitions, sign/verify equations, verification identity | current | Matches FIPS 186; independently recomputed on toy parameters above |
| "DSA is used only for signatures, cannot be used for encryption" | current | Correct and worth stressing |
| "DSA is a variant of Schnorr and ElGamal signatures" | current | Accurate lineage |
| " is 512 to 1024 bits, multiple of 64; is 160 bits" | outdated | Those sizes are FIPS 186-2 era. FIPS 186-4 raised them to = 2048/3072 with = 224/256; FIPS 186-5 then dropped DSA entirely for signature generation |
| DSA presented as a current signature standard | outdated | Verified against FIPS 186-5 (2023): DSA is approved only for verifying existing signatures. Approved generation algorithms are RSA, ECDSA, EdDSA |
| " is chosen randomly, less than " | current but dangerously understated | Stated as a mechanical step with no warning. Nonce failure is the dominant real-world break; added above |
| "The standard specifies use of SHA" | needs updating | Meant SHA-1; current DSS specifies SHA-2/SHA-3. SHA-1 signatures are forbidden |
| DSA prime-generation procedure from a seed | current as history | The verifiable-seed idea persists; specific sizes superseded |
| Source omits ECDSA and EdDSA entirely | — | Added; ECDSA is what actually ships today, Ed25519 is the recommendation |
| Source omits nonce reuse consequences | — | Added: key recovery math plus the PS3 and Bitcoin incidents |