Encryption and identity

How do Ed25519 signatures work?

An Ed25519 signature is a 64-byte value computed from a message and a 32-byte private key with EdDSA on the edwards25519 curve. The signer derives a secret number and a per-message nonce by hashing the key and the message with SHA-512, so the same key and message always give the same signature. Anyone holding the 32-byte public key can verify it by checking a single curve equation.

Learning objectives

After reading this article you will be able to:

  • Describe how Ed25519 derives a key pair, a nonce and a 64-byte signature
  • Explain why the verification equation holds and why the range check on S matters
  • Identify what a valid Ed25519 signature does not prove, such as freshness or key ownership

What a signature has to do

A digital signature lets anyone who holds a public key check two things about a message: that it was produced with the matching private key, and that it has not changed since. NIST’s Digital Signature Standard, FIPS 186-5, says signatures detect unauthorised modification of data and authenticate the identity of the signer. It approves EdDSA, the family Ed25519 belongs to, and points to RFC 8032 for the algorithm itself.

RFC 8032 describes EdDSA as a variant of Schnorr’s signature system on Edwards curves. You do not need the curve mathematics to follow how it works. Three ideas are enough:

  • There is a fixed starting point on the curve, called B.
  • Multiplying B by a whole number s gives another point, written [s]B. This is quick to compute.
  • Points can be added, and [a]B + [b]B is the same point as [a + b]B.

Going the other way, from [s]B back to s, is what NIST’s key management guidance means when it says that determining the private key from the public key is computationally infeasible.

Making a key pair

RFC 8032 generates an Ed25519 key pair in three steps:

  1. The private key is 32 bytes of cryptographically secure random data.
  2. The private key is hashed with SHA-512, giving 64 bytes. The first 32 bytes, with a few bits cleared and set, become a secret number s. The second 32 bytes, called the prefix, are kept for signing.
  3. The public key A is the point [s]B, encoded in 32 bytes.

This is the only step that needs randomness. Because the private key is hashed before use, the RFC notes that a few missing bits of entropy do not constitute a disaster, but key generation still needs a good source of randomness.

Signing a message

To sign a message M, the signer:

  1. Hashes the prefix together with M using SHA-512 and reads the result as a number r. This is the nonce for this signature.
  2. Computes the point R = [r]B.
  3. Hashes R, A and M together to get a number k.
  4. Computes S = (r + k × s) mod L, where L is the order of B.
  5. Outputs R followed by S, 32 bytes each, as the 64-byte signature.

The nonce comes from the private key and the message, not from a random number generator. RFC 8032 calls EdDSA signatures deterministic and explains why that matters: it protects against attacks that arise from signing with bad randomness, whose effects can range up to full private key compromise. One consequence is that signing the same message twice with the same key gives exactly the same signature.

Verifying a signature

The verifier has the public key A, the message M and the 64-byte signature. RFC 8032 has the verifier:

  1. Split the signature into R and S, decode R and A as points, and reject the signature if decoding fails or if S is not smaller than L.
  2. Recompute k by hashing R, A and M.
  3. Check that [8][S]B equals [8]R + [8][k]A.

The equation holds for an honest signature because S was built as r + k × s, so [S]B equals [r]B plus [k][s]B, which is R + [k]A. Because k is a hash of the message as well as R and A, changing a single byte of M changes k, so a signature made for one message does not verify for another.

Two details in the verification steps carry security weight:

  • The range check on S. RFC 8032 says this check is what makes Ed25519 signatures non-malleable. Without it, anyone could add a multiple of L to S and produce a second valid signature for the same message and key.
  • The factor of 8. This is the curve’s cofactor. The RFC says checking [S]B = R + [k]A without it is sufficient but not required, and warns that implementations disagreeing about the exact set of valid signatures could open up, for example, fingerprinting attacks.

RFC 8032 also defines two variants: Ed25519ph, which signs a hash of the message and is mainly useful for interoperating with legacy APIs, and Ed25519ctx, which adds a context string so that signatures made for one protocol or purpose are kept separate from those made for another.

What a valid signature proves

A valid signature tells you that whoever holds the private key for A signed exactly these bytes. It does not tell you:

  • Who holds the key. That needs a separate binding, such as a certificate, a comparison in person, or a self-certifying identifier that the application already trusts.
  • That the message is fresh. A signature over fixed data can be copied and presented again. Protocols that need freshness have the signer sign a new challenge each time.
  • Anything about secrecy. A signed message is still readable by anyone who sees it. Hiding it needs encryption, which usually begins with key agreement.

The mandatory cipher suite of MLS (RFC 9420), the group messaging standard, uses Ed25519 for signatures. RFC 8032 places Ed25519 at around the 128-bit security level and states plainly that a sufficiently large quantum computer would be able to break it.

Frequently asked questions

Does Ed25519 need a random number for each signature?

No. The nonce is derived by hashing part of the hashed private key together with the message, so signing needs no random number generator. Randomness is still needed once, to generate the private key.

Is Ed25519 approved by NIST?

Yes. FIPS 186-5, NIST's Digital Signature Standard, approves EdDSA as specified in RFC 8032, with additional requirements of its own.

Sources

Build it with Offline Protocol

The identity and sessions reference documents signData, which signs bytes with a device's Ed25519 identity key and returns a 64-byte signature, and verifySignature, which checks a signature against a public key.

Read the identity API reference