Digital Signatures

Proving ownership without revealing your secret key

Difficulty: Beginner Mode

🎉 Prove You Own Your Bitcoin... Without Showing Your Secret!

Imagine your Bitcoin is locked in a treasure chest. Only you have the secret key. But how do you prove it's your chest without showing the secret key to everyone?

That's what a digital signature does! It's cryptographic proof that says "I own this" without revealing your secret.

Bitcoin has two ways to do this:
ECDSA (the original way, since 2009)
✨ Schnorr (the new way, since 2021) — smaller, faster, more private!

Bitcoin uses elliptic curve cryptography (secp256k1) for digital signatures. Private keys sign transactions, public keys verify signatures. The mathematical relationship is one-way: easy to derive public from private, impossible to reverse.

Two signature algorithms: ECDSA (original, 2009-present) and Schnorr (Taproot, 2021+). Schnorr enables signature aggregation and batch verification for improved efficiency and privacy.

Bitcoin originally implemented ECDSA (Elliptic Curve Digital Signature Algorithm) over secp256k1 curve. Private key k generates public key P = k·G where G is generator point. Signature (r,s) proves knowledge of k without revealing it. Verification: s⁻¹(H(m)·G + r·P) = R validates ownership.

BIP-340 (Schnorr): Introduced with Taproot (2021). Uses x-only pubkeys, tagged hashes, and enables linear aggregation via MuSig2. Signature verification: s·G = R + e·P where e = HashBIP0340/challenge(r || P || m).

🔑 Step 1: Generate Your Keys

Click the button to create your secret key and public key.

This demo shows ECDSA (the original signature scheme). We'll compare it with Schnorr signatures below.

ECDSA implementation: Generate random k per signature, compute (r,s) where r = x(k·G), s = k⁻¹(H(m) + r·x) mod n

Your Secret Key (never share this!)

Click "Generate Keys" to create

🔓 Your Public Key (totally safe to share!)

Appears automatically
✍️ Step 2: Say Something and Sign It
Create Digital Signature (ECDSA)

Type any message (pretend it's a Bitcoin payment):

This creates an "ECDSA signature" (the original Bitcoin method from 2009). We'll try Schnorr next!

Your Digital Signature:

Sign a message first

🎮 Step 3: The Verification Game

Now anyone can check that YOU really signed it. Try to break it — it's impossible!

Test signature verification - try changing the message or tampering with the signature!

Correct message + correct signature = ✅ Real!
Change anything = ❌ Fake!

✨ Schnorr Signatures: The 2021 Upgrade (Click to learn more)

✨ Schnorr Signatures: The 2021 Upgrade

You just tried ECDSA (the original way). Now let's try Schnorr — the 2021 upgrade that made Bitcoin better!

What makes Schnorr special? It's smaller, faster, and has a powerful feature: multiple people can sign together and it looks like just one person signed!

🎪 Signature Aggregation: The Key Feature
What You Do What the World Sees
1 person signs ✅ 1 tiny signature
3 people sign together ✅ Still 1 tiny signature!
100 people sign (CoinJoin) ✅ Still 1 tiny signature!
Complex smart contract ✅ Still 1 tiny signature!

🎉 That's the power! Everyone's complex transactions look exactly like a normal payment from one person. Total privacy!

Schnorr signatures (activated in Bitcoin via Taproot in 2021) are simpler, more efficient, and enable powerful features like signature aggregation and batch verification.

ECDSA (Old Way)

Signature: (r, s) where r and s are derived separately

Verification: Complex multi-step process

Size: ~72 bytes (DER-encoded)

Aggregation: ❌ Not possible

Malleability: ⚠️ Signature can be tweaked

Schnorr (New Way)

Signature: (R, s) where R is a curve point, s is scalar

Verification: Simple equation: s·G = R + e·P

Size: 64 bytes (always fixed)

Aggregation: ✅ Multiple signatures → 1 signature!

Malleability: ✅ Impossible to tweak

How Schnorr Signing Works
  1. Generate nonce: Pick random k, compute R = k·G
  2. Create challenge: e = Hash(R || P || m) where P is public key, m is message
  3. Compute signature: s = k + e·x (where x is private key)
  4. Output: Signature is (R, s)

Verification: Check if s·G = R + e·P. If true, signature is valid!

💡 Key Advantage: Linearity

Schnorr's linearity property allows signature aggregation: Multiple parties can combine their signatures into a single signature. This makes complex multisig setups look identical to single-key spends on-chain — massive privacy and efficiency gains!

Schnorr signatures (BIP-340) provide provable security, linearity enabling key and signature aggregation, and batch verification. Bitcoin's implementation uses secp256k1 curve with x-only public keys and tagged hashing.

Schnorr Signature Algorithm (BIP-340)
// Signing
k = random_scalar() // Random nonce
R = k·G // Nonce point
r = x(R) // x-only coordinate
e = int(HashBIP0340/challenge(r || P || m)) mod n // Tagged hash
s = (k + e·x) mod n // Signature scalar
return (r, s) // 64-byte signature

// Verification
e = int(HashBIP0340/challenge(r || P || m)) mod n
R' = s·G - e·P // Compute expected R
return x(R') == r && has_even_y(R') // Verify
BIP-340 Design Decisions
  • x-only pubkeys: 32 bytes instead of 33
  • Implicit y-parity: Always even y-coordinate
  • Tagged hashing: Prevents cross-protocol attacks
  • Nonce generation: RFC6979-style deterministic
  • Batch verification: Verify n signatures in ~1.5n time
Security Properties
  • SUF-CMA secure: Strong existential unforgeability under chosen message attack
  • Non-malleable: Cannot modify existing valid signatures
  • Provably secure: Security reduction to DLP
  • Linear: Enables MuSig2, FROST protocols
🔬 Key Aggregation with MuSig2

Pagg = P1 + P2 + ... + Pn (with key coefficient adjustments)
sagg = s1 + s2 + ... + sn mod n

Indistinguishable from single-key signature. Enables n-of-n multisig with constant O(1) space and verification time.

🎮 Try It Yourself!Schnorr Playground

Sign a message with Schnorr and watch multiple signatures combine into one!

R (nonce point): -
s (scalar): -
Signature (R||s): -

🌳 Taproot: Make Complex Look Simple (Click to learn more)

🌳 Taproot: Make Complex Look Simple

Taproot = The Invisible Smart Contract

It combines Schnorr with hidden backup plans. 99% of the time, you just use one simple signature. But if something goes wrong, you can reveal your backup plan.

New Address Type: Taproot addresses start with bc1p...

Click the button to create one

Two Ways to Spend Your Bitcoin:

✅ Key-path (the normal way):

Just one tiny Schnorr signature. Cheap and private. This is what 99% of people use!

🛑 Script-path (plan B):

Only reveal this if something goes wrong (like losing a key). Your backup plan stays hidden until you need it!

🎉 Privacy win: On the blockchain, everything looks like a normal single-person payment, even if it's actually a complex 10-person multisig!

Taproot outputs (P2TR) commit to a tweaked key that optionally includes a hidden script tree. You can spend via key-path (cheap) or reveal one Merkle branch (script-path).

How Taproot Works
  1. Start with internal key P: This is your base public key
  2. Add script commitments: Hash your script tree to get root t
  3. Tweak the key: Q = P + Hash(P||t)·G
  4. Create P2TR address: bc1p... from Q (x-only)

The tweaked key Q becomes the address. Scripts stay hidden in the hash until you need them.

Interactive: Spend Type
Real-World Example: 2-of-3 Multisig

Without Taproot: Everyone sees it's a 2-of-3 multisig. ~200 bytes on-chain.

With Taproot: If all 3 cooperate, use key-path (64 bytes, looks like single-sig). If one is unavailable, reveal script-path. Privacy + efficiency!

Taproot Construction (BIP-341)
// Key Construction
P = internal_pubkey // Base public key
t = tagged_hash("TapBranch", left_hash || right_hash) // Merkle root
tweak = tagged_hash("TapTweak", x(P) || t) // BIP-340 tagged hash
Q = lift_x(x(P) + tweak mod n) // Output key (x-only, even y)

// Key-path Spend
sig = Sign(sk + tweak, message) // Schnorr sig with tweaked key
witness: [sig] // 64 bytes only

// Script-path Spend
control_block = [parity || x(P) || merkle_proof]
witness: [script_inputs... || script || control_block]
verify: Hash(control_block[1:33] + hash(script) + proof) == t
Tapscript Changes (BIP-342)
  • OP_CHECKSIGADD: Replaces OP_CHECKMULTISIG
  • OP_SUCCESS: Reserved opcodes for soft forks
  • Schnorr-only: No ECDSA in Tapscript
  • Signature validation: Uses BIP-340 exclusively
MAST Benefits
  • Privacy: Unexecuted branches stay hidden
  • Efficiency: O(log n) witness size
  • Flexibility: Unlimited script alternatives
  • Composability: Combine with covenants
🔬 Implementation Note:

Taproot witness program: 1-byte version (0x01) + 32-byte x-only pubkey Q. SegWit v1 uses Bech32m encoding. Key-path spends are indistinguishable from each other regardless of hidden scripts.

📚 Summary: How Bitcoin Uses Digital Signatures
💼 Bitcoin Addresses: Derived from your public key. People send Bitcoin to your address.
✈️ Spending Bitcoin: When you spend, you create a signature with your private key. This proves you own the Bitcoin.
🔒 Old vs New:
  • ECDSA (2009-now): Original signatures, work great but bigger
  • Schnorr + Taproot (2021-now): Newer, smaller, more private — multisig looks like single-sig!
Component ECDSA (Legacy) Schnorr + Taproot
Address Type P2PKH (1...), P2WPKH (bc1q...) P2TR (bc1p...)
Signature Size ~72 bytes (DER encoded) 64 bytes (fixed)
Multisig Visible on-chain, multiple sigs Aggregated → looks like 1 sig
Privacy Lower (script types visible) Higher (key-path hides complexity)

Key Point: Every Bitcoin transaction input requires a valid signature. Schnorr + Taproot make complex smart contracts indistinguishable from simple payments.

Script Validation Opcodes:
OP_CHECKSIG: Verifies ECDSA signature against pubkey
OP_CHECKSIGVERIFY: Same but fails script if invalid
OP_CHECKMULTISIG: Verifies m-of-n ECDSA signatures
OP_CHECKSIGADD (Tapscript): Accumulator-based multisig for Schnorr

Taproot Signature Validation (BIP-341/342):
Key-path: Single Schnorr signature validates against tweaked pubkey Q
Script-path: Execute revealed script leaf (Tapscript), supports OP_CHECKSIGADD

Security Model:
ECDSA: SUF-CMA secure under Random Oracle Model + ECDLP hardness
Schnorr (BIP-340): SUF-CMA secure with tighter reduction, non-malleable
Both: ~128-bit security with secp256k1 (256-bit keys)

🎓 What You've Learned

✅ How digital signatures prove ownership without revealing secrets
✅ The difference between ECDSA (old) and Schnorr (new) signatures
✅ How Taproot makes complex Bitcoin transactions look simple
✅ Why Bitcoin's privacy and efficiency improved in 2021

✅ ECDSA signature generation and verification mechanics
✅ Schnorr's linearity property enables signature aggregation
✅ Taproot's key-path vs script-path spending trade-offs
✅ How MuSig2 enables efficient n-of-n multisig with Schnorr

✅ ECDSA: (r,s) where r = x(k·G), s = k⁻¹(H(m) + r·x) mod n
✅ Schnorr (BIP-340): (r,s) where s = k + e·x, e = HashBIP0340/challenge(r || P || m)
✅ Taproot (BIP-341): Q = P + HashTapTweak(P || t)·G
✅ MuSig2: Non-interactive n-of-n with key aggregation Pagg = ∑ aiPi

Want to dive deeper? Explore the other interactive demos!