Sign in

Digital signatures and signature recovery

A blockchain transaction travels across an open network with no return address, no email header, no session cookie. Yet every node receiving it has to decide: did this transaction come from someone authorised to spend these funds? The mechanism that answers that question, billions of times per day across every public chain, is the topic of this lesson. It's also the operational pay-off for everything you've learned so far about key pairs.

The problem

You hold a private key. You want to tell the network "move some value from my account to this other account." The network has never met you. It will never meet you. It cannot ask for your password because there is no password and no one to receive it.

What you can send is a transaction plus a signature on that transaction. Anyone with your public key can then check whether the signature is valid for that exact transaction. If it is, the network accepts that the transaction came from whoever holds the private key that pairs with the public key in question. If it isn't, the transaction is rejected and the network doesn't ask twice.

For this to work, the signature scheme must guarantee three things:

  1. Only the holder of the private key can produce a valid signature for a given message.
  2. Anyone with the public key can verify that a given signature was produced for that message by that private key.
  3. The signature is tied to the exact message. Change one bit of the transaction and the same signature no longer verifies. There is no replaying old signatures on different transactions.

These three properties are exactly what the public-key math from earlier in the module can deliver. The same key-pair construction that powered the encryption examples works in the opposite direction: instead of encrypting to the public key, you sign with the private key, and anyone verifies against the public key. Different goal, same underlying mathematical asymmetry.

How sign and verify work

A signature scheme has two operations.

Sign takes the private key and a message and produces a signature, which is just a short value, typically 64 or 65 bytes.

Verify takes the public key, the message, and the signature, and returns either "valid" or "invalid."

Sign private key your secret message the transaction sign private key + message signature 64 or 65 bytes Verify public key share freely message the transaction signature 64 or 65 bytes verify ✓ / ✗

Verifying does not require the private key. This is the entire point. The wallet that sent the transaction holds the private key, every node in the world that validates the transaction has only the public key, the message, and the signature; the protocol works because verification with just those three values is enough.

The most common signature scheme on the chains you'll meet is ECDSA, the Elliptic Curve Digital Signature Algorithm, used with the same secp256k1 curve that produces the key pairs. ECDSA is the workhorse: every transaction on the largest chain families produces one. Ed25519 has its own integrated signing scheme (technically called EdDSA) and is used by some newer chains.

For both schemes the operational properties are the same: sign with the private key, verify with the public key, signatures are ~64 bytes, signing is fast, verification is fast, and forgery without the private key is computationally infeasible.

Where ECDSA hides a trap

Inside ECDSA's signing operation there's a random value called the nonce. Each signature needs a fresh nonce. If you ever sign two different messages with the same nonce by accident, an attacker who sees both signatures can mathematically recover your private key. This is not a theoretical attack, it has been used to drain real wallets.

The fix is a standard called RFC 6979, which makes the nonce a deterministic function of the private key and the message instead of relying on the device's random number generator. Every modern wallet uses this. You don't have to remember the standard, you do need to know that "weak randomness in signature generation" is a real category of historical wallet break, and that it's the reason RFC 6979 exists.

Signature recovery: the operational pay-off

The verify operation above takes the public key as an input. For a blockchain to use this, every transaction would need to carry the sender's public key, which would bloat every transaction and require the network to look up which public keys belong to which accounts.

There is a better trick.

ECDSA has a property called public-key recovery. Given a signature and the message, you can directly recover the public key that signed it, with no other input. The public key falls out of the signature itself.

message the transaction signature 65 bytes with recovery id recover message + signature public key the signer's identity

The extra byte in the signature is a recovery id that disambiguates between the two mathematically valid public keys that any ECDSA signature could in principle map to. With that extra byte, recovery is unambiguous.

This is why blockchain transactions don't carry the sender's public key. The network derives it on the fly from the signature itself. The recovered public key, hashed in a chain-specific way, becomes the sender address. If the chain's state shows that this address has the funds being moved, the transaction is accepted. If not, rejected.

On many chains the recovery operation is exposed to smart-contract code as a built-in primitive (most famously named ecrecover) and is one of the most-called functions in the whole system. Every transaction triggers it. Every "did this user sign this message?" check uses it.

What you know now

Three properties are now real to you instead of abstract.

Authentication on a blockchain works without identity in the traditional sense. No usernames, no central registry of who-is-who. Just private keys, signatures, and recovered public keys. If the math checks out, the transaction is yours.

Signatures bind to exact messages. You cannot reuse a signature on a different transaction. You cannot tamper with a transaction without invalidating its signature. The integrity comes from the math, not from a trusted intermediary.

Recovery is the trick that makes the protocol-level math practical. Without it, every transaction would need to carry a public key. With it, the network derives the signer's identity from the signature itself. This is the operational primitive that the next two lessons (and effectively every chain you'll touch) build on.

Where this goes next

You've now seen the four cryptographic primitives the rest of the course will keep returning to: hash functions, encoding schemes, public-key cryptography, and digital signatures with recovery. The remaining lessons in this module wire these together into the practical structures real wallets and chains use: derivation paths, Merkle trees, and a brief note on the quantum threat to all of the above.