Skip to content

Ed25519 Keypairs

The part overview framed the whole problem: a single global state machine has no gatekeeper at the door, so the only thing standing between “you own this account” and “anyone can drain it” is a piece of math. This page names that math. Solana’s math is a specific signature scheme — Ed25519 — and every key, every address, and every signature on the chain is a consequence of choosing it.

We build one idea here and reuse it for the rest of the part: a keypair is two 32-byte numbers bound together by a one-way function. You publish one and hide the other. Get this page into your bones and the next three pages fall out of it — an address is literally the public key, signing is proving you hold the secret without revealing it, and a PDA is an address deliberately built to have no secret at all.

Strip away the tooling and a Solana keypair is two fixed-size byte strings:

secret key (seed) public key
┌──────────────┐ ┌──────────────┐
│ 32 bytes │ ───► │ 32 bytes │
│ kept secret │ one │ published │
│ = a scalar │ way │ = a curve │
│ number │ │ point │
└──────────────┘ └──────────────┘
hide this show this

The secret key — really a 32-byte random seed — is just a number. Not a special number, not a prime, not anything with structure: 256 random bits. The public key is a point on a curve called Curve25519 (in its twisted-Edwards form, which is where the name Ed25519 comes from). And there is a function that turns the first into the second — cheaply, in one direction only.

That function is scalar multiplication on the curve:

public_key = secret_scalar × G (G is a fixed, public "base point")

Read × as “add the base point G to itself secret_scalar times,” using the curve’s own peculiar addition rule. G is a constant everyone agrees on, baked into the standard. So the public key is fully determined by the secret: pick a random 256-bit number, multiply the base point by it, and the point you land on is your public key. Two 32-byte strings, joined by one multiplication.

Why 32 bytes for the public key when a point has two coordinates? Because Ed25519 stores a point in compressed form — the full y coordinate plus a single sign bit for x, packed into exactly 32 bytes. There is no “compressed vs. uncompressed” choice to make (a fork we will return to when we compare against Bitcoin); the encoding is one fixed shape. That single fact is why a Solana address fits in a 32-byte Pubkey with nothing left to decide.

The security of the entire chain rests on one asymmetry: secret → public is easy, and public → secret is infeasible.

secret_scalar ──── multiply by G ────► public_key cheap: microseconds
public_key ──── recover scalar ───► secret_scalar the discrete-log problem

Going forward — multiplying the base point by your secret — takes a fraction of a millisecond. Going backward — being handed a public key (a point) and asked which scalar produced it — is the elliptic-curve discrete logarithm problem, and for Curve25519 the best known attack costs on the order of 2^128 operations. That is not “a big number.” It is a number with no physical meaning: there is not enough energy in the reachable universe to count that high on any computer we can build. So publishing your public key leaks nothing about your secret.

This is the trapdoor that makes public-key cryptography work at all. You hand the whole world your public key — it is your address — and keep the seed. Anyone can verify a signature against your public key; only the holder of the seed can produce one. The asymmetry is the entire trust model of an account you never registered with anyone.

The 32-byte seed is the whole secret, but the running keypair does a little more with it. Ed25519’s key expansion hashes the seed and derives the scalar and a private “nonce prefix” from it — the mechanism that makes signing deterministic (more on that below). Conceptually:

32-byte seed
│ SHA-512(seed) → 64 bytes
├── first 32 bytes → clamp → secret scalar ──► × G ──► public key (32 bytes)
└── last 32 bytes → nonce prefix (used only when signing)

You never have to do this by hand — libraries do it — but two consequences matter. First, the seed is the master secret: everything else is derived from it, so whoever holds the seed holds the account. Second, the public key is a pure function of the seed, so a keypair is really just the seed; the public half is recomputable at will.

That is why the on-disk format packs both:

Solana keypair file = 64 bytes = [ 32-byte seed ][ 32-byte public key ]
└── secret ──┘└──── derived ───────┘

A Solana CLI keypair file is a JSON array of 64 numbers: the first 32 are the secret seed, the last 32 are the public key stored alongside it purely for convenience (so tools need not recompute it). Read that sentence twice, because it contains the danger: those first 32 bytes are the account. Anyone who reads that file owns everything the account holds. There is no password on it, no second factor — the file is the authority.

Terminal window
# Generate a keypair (writes the 64-byte JSON array to a file)
solana-keygen new --outfile my-wallet.json
# Recover just the public key from the file — note the secret never leaves the file
solana-keygen pubkey my-wallet.json
# → 9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM (32 bytes, base58)

Under the hood — why Ed25519, not Bitcoin’s secp256k1

Section titled “Under the hood — why Ed25519, not Bitcoin’s secp256k1”

Bitcoin and Ethereum sign with ECDSA over the secp256k1 curve. Solana deliberately chose a different scheme. The differences are not cosmetic — each one buys the throughput-and-safety bet the whole book is about.

  • Deterministic signatures, no per-signature nonce. ECDSA needs a fresh random number k for every signature, and if k is ever repeated or predictable, the secret key can be computed from two signatures. This has caused real key losses (see the incident below). Ed25519 derives its per-message nonce deterministically from the message and that private nonce prefix — there is no random k to get wrong. One entire, historically-devastating class of bug is designed out.
  • Fast batch verification. A validator processing thousands of transactions per block must verify a torrent of signatures. Ed25519 was built to verify many signatures at once far faster than checking each independently — which matters directly when your goal is hardware speed.
  • Fixed, small sizes with no encoding choices. Ed25519 keys are exactly 32 bytes and signatures exactly 64 bytes, always. secp256k1 public keys come in 33-byte compressed or 65-byte uncompressed forms, and its DER-encoded signatures are variable-length — an encoding surface that has itself been a source of bugs (transaction malleability). Solana’s fixed sizes make transaction layout, account addressing, and parsing dead simple.
  • Nothing-up-my-sleeve constants. Curve25519’s parameters were chosen from small, explainable numbers with public rationale, so there is little room to hide a backdoor in a “magic” constant. It is a curve you can trust because you can see where every number came from.

Here is the size contrast at a glance:

public key signature
Ed25519 (Solana) 32 bytes (fixed) 64 bytes (fixed)
secp256k1 (Bitcoin) 33 or 65 bytes ~70–72 bytes (variable, DER)

That fixed 32-byte public key is the reason a Solana address never needs a “which format?” question, and why the Pubkey at the heart of the account model is a plain [u8; 32].

The whole security story is the entropy behind the seed

Section titled “The whole security story is the entropy behind the seed”

Notice what the trapdoor does not protect you from. The math guarantees nobody can work backward from your public key. It guarantees nothing about a secret that was never random in the first place. If your 32-byte seed came from a predictable source — a passphrase, a hashed word, a broken RNG — then an attacker does not need to solve the discrete-log problem. They just guess the seed directly, and the 2^128 wall is irrelevant because you never stood behind it.

This is the brain-wallet lesson, and it is the one thing to carry off this page. A “brain wallet” derived a key by hashing a human-chosen phrase like correct horse battery staple. It felt secure because the output was a valid 256-bit key. But the input had only a few dozen bits of real entropy, so attackers pre-computed the keys for millions of likely phrases and swept every such wallet the instant it was funded. The curve was never attacked; the human was.

256-bit seed from a real CSPRNG → 2^256 possibilities → unguessable
256-bit seed from a passphrase → ~2^40 real choices → swept in minutes
(same 32 bytes out — but the entropy is a lie)

So the security of a Solana account is exactly the entropy of the number behind its seed — no more, no less. A key generated by solana-keygen draws from the operating system’s cryptographically secure random source; a key you invent in your head does not. The trapdoor is only a wall if the secret is a random point behind it.

  • Why does it exist? A global state machine has no login server — the only proof of ownership is a signature only the account holder can produce. Ed25519 is the specific asymmetric scheme Solana uses to make “I own this account” a mathematical, unforgeable fact rather than a permission granted by some authority.
  • What problem does it solve? It lets anyone verify authorship of a transaction against a public 32-byte key while the corresponding secret stays hidden, so accounts need no registration and no central gatekeeper — the trapdoor (secret → public easy, public → secret a ~2^128 wall) does the whole job.
  • What are the trade-offs? You gain deterministic signing (no risky nonce), fast batch verification, and fixed 32/64-byte sizes; you accept that the seed is the account — lose it or leak it and there is no recovery, no reset, no support line.
  • When should I avoid it? When you specifically need an address that no one can sign for — that is exactly a Program Derived Address, an address deliberately placed off the curve so it has no secret key at all. Ed25519 is for authority you hold; PDAs are for authority a program holds.
  • What breaks if I remove it? Everything downstream: addresses (which are Ed25519 public keys), transaction signing and verification, and the account-ownership model. Without a signature scheme, the runtime cannot tell an authorized write from a theft, and the shared global state has no owner.
  1. A Solana keypair is two 32-byte values. What is each one, mathematically — a number or a curve point — and which do you publish?
  2. Explain the one-way trapdoor in one sentence, naming the operation that is easy and the problem that makes the reverse infeasible.
  3. Give two distinct reasons Solana chose Ed25519 over Bitcoin’s secp256k1, and tie each to something the chain actually needs.
  4. A Solana keypair file holds 64 bytes. What are the two halves, and why is it accurate to say “the file is the account”?
  5. The curve gives you a ~2^128 security wall. Describe a situation where an attacker steals an account without touching that wall at all, and name the lesson.
Show answers
  1. The secret key is a 32-byte random seed, which expands to a scalar (a number); the public key is a 32-byte compressed point on the twisted-Edwards Curve25519, computed as scalar × G. You publish the public key and hide the seed.
  2. Computing public = secret × G (scalar multiplication on the curve) is cheap, but recovering the secret scalar from the public point is the elliptic-curve discrete-logarithm problem, ~2^128 work — so you can publish the public key without leaking the secret.
  3. Any two of: deterministic signatures (no per-signature random nonce k to reuse or predict — removes a whole key-loss bug class, which matters for a chain signing millions of transactions); fast batch verification (a validator verifies a flood of signatures per block, needed for hardware speed); fixed small sizes — 32-byte keys, 64-byte signatures, no compressed/uncompressed or DER encoding choice (simple, malleability-free transaction layout); nothing-up-my-sleeve constants (transparent parameters, hard to hide a backdoor).
  4. The first 32 bytes are the secret seed; the last 32 are the public key stored alongside for convenience (it is recomputable from the seed). It “is the account” because whoever reads those first 32 bytes can derive the keypair and sign anything — there is no password or second factor guarding it.
  5. If the seed was generated from a low-entropy source — a passphrase, a dictionary word, a broken RNG (a brain wallet) — the attacker just guesses the seed directly instead of inverting the curve, so the 2^128 wall never applies. The lesson: an account’s real security is the entropy behind its seed, not the strength of the curve.