1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
# secp256k1 from Scratch — Learning Plan
Building Schnorr signatures on secp256k1 in Go, from first principles.
**Goal:** Understand the math deeply, not just copy formulas. End with a working (non-production) implementation compatible with Bitcoin Taproot and Nostr.
---
## Progress
### Part 1: Foundations
- [x] **Modular arithmetic** — clock math, remainders, finite sets
- [x] **Modular division/inverses** — finding multiplicative inverses
- [x] **What is an elliptic curve** — y² = x³ + 7, points as (x, y) pairs
### Part 2: Curve Operations
- [x] **Point addition** — adding two points geometrically and algebraically
- [x] **Point doubling** — special case when adding a point to itself
- [x] **The point at infinity** — identity element (like zero for addition)
- [x] **Scalar multiplication** — multiplying a point by an integer (repeated addition)
### Part 3: Key Pairs
- [x] **Generator point G** — the "starting point" everyone uses
- [x] **Private key** — just a random big number
- [x] **Public key** — private key × G (scalar multiplication)
- [x] **Why it's hard to reverse** — the discrete log problem
### Part 4: Schnorr Signatures (BIP-340)
- [x] **X-only public keys** — 32 bytes, implicit even y
- [x] **The signing algorithm** — nonce, challenge, response
- [x] **Why random nonce matters** — reuse = leaked private key
- [x] **The verification equation** — checking without knowing the private key
- [x] **Tagged hashes** — domain separation for security
### Part 5: Serialization
- [x] **Bech32 encoding** — human-readable format (npub, nsec)
- [x] **Hex and bytes** — raw formats
---
## Files
| File | Description |
|------|-------------|
| `field.go` | Modular arithmetic (mod p) |
| `point.go` | Curve points and operations |
| `keys.go` | Private/public key generation |
| `schnorr.go` | Schnorr signing and verification |
| `bech32.go` | Bech32 encoding (npub/nsec) |
---
## Compatibility
This implementation targets:
- **Bitcoin Taproot** (BIP-340 Schnorr)
- **Nostr** (NIP-01 uses BIP-340)
Not implemented: ECDSA (used by legacy Bitcoin, Ethereum)
### Compatibility Tests
Verified against `btcec/v2` (the library used by most Go Bitcoin/Nostr projects):
```bash
go get github.com/btcsuite/btcd/btcec/v2
go test -tags=compat ./...
```
Tests confirm:
- Key derivation produces identical public keys
- Signatures created here verify with btcec
- Signatures from btcec verify with our code
- All 14 official BIP-340 test vectors pass
---
## Resources
- [BIP-340: Schnorr Signatures](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki)
- secp256k1 parameters: p, n, G coordinates
- Test vectors from BIP-340 for verification
---
## Notes
*Learning project — do not use for real money or keys.*
|