Add foundational resources for elliptic curve operations and distributed systems
Added detailed pseudocode for elliptic curve algorithms covering modular arithmetic, point operations, scalar multiplication, and coordinate conversions. Also introduced a comprehensive knowledge base for distributed systems, including CAP theorem, consistency models, consensus protocols (e.g., Paxos, Raft, PBFT, Nakamoto), and fault-tolerant design principles.
This commit is contained in:
369
.claude/skills/elliptic-curves/SKILL.md
Normal file
369
.claude/skills/elliptic-curves/SKILL.md
Normal file
@@ -0,0 +1,369 @@
|
||||
---
|
||||
name: elliptic-curves
|
||||
description: This skill should be used when working with elliptic curve cryptography, implementing or debugging secp256k1 operations, understanding modular arithmetic and finite fields, or implementing signature schemes like ECDSA and Schnorr. Provides comprehensive knowledge of group theory foundations, curve mathematics, point multiplication algorithms, and cryptographic optimizations.
|
||||
---
|
||||
|
||||
# Elliptic Curve Cryptography
|
||||
|
||||
This skill provides deep knowledge of elliptic curve cryptography (ECC), with particular focus on the secp256k1 curve used in Bitcoin and Nostr, including the mathematical foundations and implementation considerations.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
- Implementing or debugging elliptic curve operations
|
||||
- Working with secp256k1, ECDSA, or Schnorr signatures
|
||||
- Understanding modular arithmetic and finite field operations
|
||||
- Optimizing cryptographic code for performance
|
||||
- Analyzing security properties of curve-based cryptography
|
||||
|
||||
## Mathematical Foundations
|
||||
|
||||
### Groups in Cryptography
|
||||
|
||||
A **group** is a set G with a binary operation (often denoted · or +) satisfying:
|
||||
|
||||
1. **Closure**: For all a, b ∈ G, the result a · b is also in G
|
||||
2. **Associativity**: (a · b) · c = a · (b · c)
|
||||
3. **Identity**: There exists e ∈ G such that e · a = a · e = a
|
||||
4. **Inverse**: For each a ∈ G, there exists a⁻¹ such that a · a⁻¹ = e
|
||||
|
||||
A **cyclic group** is generated by repeatedly applying the operation to a single element (the generator). The **order** of a group is the number of elements.
|
||||
|
||||
**Why groups matter in cryptography**: The discrete logarithm problem—given g and gⁿ, find n—is computationally hard in certain groups, forming the security basis for ECC.
|
||||
|
||||
### Modular Arithmetic
|
||||
|
||||
Modular arithmetic constrains calculations to a finite range [0, p-1] for some modulus p:
|
||||
|
||||
```
|
||||
a ≡ b (mod p) means p divides (a - b)
|
||||
|
||||
Operations:
|
||||
- Addition: (a + b) mod p
|
||||
- Subtraction: (a - b + p) mod p
|
||||
- Multiplication: (a × b) mod p
|
||||
- Inverse: a⁻¹ where (a × a⁻¹) ≡ 1 (mod p)
|
||||
```
|
||||
|
||||
**Computing modular inverse**:
|
||||
- **Fermat's Little Theorem**: If p is prime, a⁻¹ ≡ a^(p-2) (mod p)
|
||||
- **Extended Euclidean Algorithm**: More efficient for general cases
|
||||
- **SafeGCD Algorithm**: Constant-time, used in libsecp256k1
|
||||
|
||||
### Finite Fields (Galois Fields)
|
||||
|
||||
A **finite field** GF(p) or 𝔽ₚ is a field with a finite number of elements where:
|
||||
- p must be prime (or a prime power for extension fields)
|
||||
- All arithmetic operations are defined and produce elements within the field
|
||||
- Every non-zero element has a multiplicative inverse
|
||||
|
||||
For cryptographic curves like secp256k1, the field is 𝔽ₚ where p is a 256-bit prime.
|
||||
|
||||
**Key property**: The non-zero elements of a finite field form a cyclic group under multiplication.
|
||||
|
||||
## Elliptic Curves
|
||||
|
||||
### The Curve Equation
|
||||
|
||||
An elliptic curve over a finite field 𝔽ₚ is defined by the Weierstrass equation:
|
||||
|
||||
```
|
||||
y² = x³ + ax + b (mod p)
|
||||
```
|
||||
|
||||
The curve must satisfy the non-singularity condition: 4a³ + 27b² ≠ 0
|
||||
|
||||
### Points on the Curve
|
||||
|
||||
A point P = (x, y) is on the curve if it satisfies the equation. The set of all points, plus a special "point at infinity" O (the identity element), forms an abelian group.
|
||||
|
||||
### Point Operations
|
||||
|
||||
**Point Addition (P + Q where P ≠ Q)**:
|
||||
```
|
||||
λ = (y₂ - y₁) / (x₂ - x₁) (mod p)
|
||||
x₃ = λ² - x₁ - x₂ (mod p)
|
||||
y₃ = λ(x₁ - x₃) - y₁ (mod p)
|
||||
```
|
||||
|
||||
**Point Doubling (P + P = 2P)**:
|
||||
```
|
||||
λ = (3x₁² + a) / (2y₁) (mod p)
|
||||
x₃ = λ² - 2x₁ (mod p)
|
||||
y₃ = λ(x₁ - x₃) - y₁ (mod p)
|
||||
```
|
||||
|
||||
**Point at Infinity**: Acts as the identity element; P + O = P for all P.
|
||||
|
||||
**Point Negation**: -P = (x, -y) = (x, p - y)
|
||||
|
||||
## The secp256k1 Curve
|
||||
|
||||
### Parameters
|
||||
|
||||
secp256k1 is defined by SECG (Standards for Efficient Cryptography Group):
|
||||
|
||||
```
|
||||
Curve equation: y² = x³ + 7 (a = 0, b = 7)
|
||||
|
||||
Prime modulus p:
|
||||
0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F
|
||||
= 2²⁵⁶ - 2³² - 977
|
||||
|
||||
Group order n:
|
||||
0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141
|
||||
|
||||
Generator point G:
|
||||
Gx = 0x79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798
|
||||
Gy = 0x483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8
|
||||
|
||||
Cofactor h = 1
|
||||
```
|
||||
|
||||
### Why secp256k1?
|
||||
|
||||
1. **Koblitz curve**: a = 0 enables faster computation (no ax term)
|
||||
2. **Special prime**: p = 2²⁵⁶ - 2³² - 977 allows efficient modular reduction
|
||||
3. **Deterministic construction**: Not randomly generated, reducing backdoor concerns
|
||||
4. **~30% faster** than random curves when fully optimized
|
||||
|
||||
### Efficient Modular Reduction
|
||||
|
||||
The special form of p enables fast reduction without general division:
|
||||
|
||||
```
|
||||
For p = 2²⁵⁶ - 2³² - 977:
|
||||
To reduce a 512-bit number c = c_high × 2²⁵⁶ + c_low:
|
||||
c ≡ c_low + c_high × 2³² + c_high × 977 (mod p)
|
||||
```
|
||||
|
||||
## Point Multiplication Algorithms
|
||||
|
||||
Scalar multiplication kP (computing P + P + ... + P, k times) is the core operation.
|
||||
|
||||
### Double-and-Add (Binary Method)
|
||||
|
||||
```
|
||||
Input: k (scalar), P (point)
|
||||
Output: kP
|
||||
|
||||
R = O (point at infinity)
|
||||
for i from bit_length(k)-1 down to 0:
|
||||
R = 2R # Point doubling
|
||||
if bit i of k is 1:
|
||||
R = R + P # Point addition
|
||||
return R
|
||||
```
|
||||
|
||||
**Complexity**: O(log k) point operations
|
||||
**Vulnerability**: Timing side-channels (different branches for 0/1 bits)
|
||||
|
||||
### Montgomery Ladder
|
||||
|
||||
Constant-time algorithm that performs the same operations regardless of bit values:
|
||||
|
||||
```
|
||||
Input: k (scalar), P (point)
|
||||
Output: kP
|
||||
|
||||
R0 = O
|
||||
R1 = P
|
||||
for i from bit_length(k)-1 down to 0:
|
||||
if bit i of k is 0:
|
||||
R1 = R0 + R1
|
||||
R0 = 2R0
|
||||
else:
|
||||
R0 = R0 + R1
|
||||
R1 = 2R1
|
||||
return R0
|
||||
```
|
||||
|
||||
**Advantage**: Resistant to simple power analysis and timing attacks.
|
||||
|
||||
### Window Methods (w-NAF)
|
||||
|
||||
Precompute small multiples of P, then process w bits at a time:
|
||||
|
||||
```
|
||||
w-NAF representation reduces additions by ~1/3 compared to binary
|
||||
Precomputation table: [P, 3P, 5P, 7P, ...] for w=4
|
||||
```
|
||||
|
||||
### Endomorphism Optimization (GLV Method)
|
||||
|
||||
secp256k1 has an efficiently computable endomorphism φ where:
|
||||
```
|
||||
φ(x, y) = (βx, y) where β³ ≡ 1 (mod p)
|
||||
φ(P) = λP where λ³ ≡ 1 (mod n)
|
||||
```
|
||||
|
||||
This allows splitting scalar k into k₁ + k₂λ with smaller k₁, k₂, reducing operations by ~33-50%.
|
||||
|
||||
### Multi-Scalar Multiplication (Strauss-Shamir)
|
||||
|
||||
For computing k₁P₁ + k₂P₂ (common in signature verification):
|
||||
|
||||
```
|
||||
Process both scalars simultaneously, combining operations
|
||||
Reduces work compared to separate multiplications
|
||||
```
|
||||
|
||||
## Coordinate Systems
|
||||
|
||||
### Affine Coordinates
|
||||
|
||||
Standard (x, y) representation. Requires modular inversion for each operation.
|
||||
|
||||
### Projective Coordinates
|
||||
|
||||
Represent (X:Y:Z) where x = X/Z, y = Y/Z:
|
||||
- Avoids inversions during intermediate computations
|
||||
- Only one inversion at the end to convert back to affine
|
||||
|
||||
### Jacobian Coordinates
|
||||
|
||||
Represent (X:Y:Z) where x = X/Z², y = Y/Z³:
|
||||
- Fastest for point doubling
|
||||
- Used extensively in libsecp256k1
|
||||
|
||||
### López-Dahab Coordinates
|
||||
|
||||
For curves over GF(2ⁿ), optimized for binary field arithmetic.
|
||||
|
||||
## Signature Schemes
|
||||
|
||||
### ECDSA (Elliptic Curve Digital Signature Algorithm)
|
||||
|
||||
**Key Generation**:
|
||||
```
|
||||
Private key: d (random integer in [1, n-1])
|
||||
Public key: Q = dG
|
||||
```
|
||||
|
||||
**Signing message m**:
|
||||
```
|
||||
1. Hash: e = H(m) truncated to curve order bit length
|
||||
2. Random: k ∈ [1, n-1]
|
||||
3. Compute: (x, y) = kG
|
||||
4. Calculate: r = x mod n (if r = 0, restart with new k)
|
||||
5. Calculate: s = k⁻¹(e + rd) mod n (if s = 0, restart)
|
||||
6. Signature: (r, s)
|
||||
```
|
||||
|
||||
**Verification of signature (r, s) on message m**:
|
||||
```
|
||||
1. Check: r, s ∈ [1, n-1]
|
||||
2. Hash: e = H(m)
|
||||
3. Compute: w = s⁻¹ mod n
|
||||
4. Compute: u₁ = ew mod n, u₂ = rw mod n
|
||||
5. Compute: (x, y) = u₁G + u₂Q
|
||||
6. Valid if: r ≡ x (mod n)
|
||||
```
|
||||
|
||||
**Security considerations**:
|
||||
- k MUST be unique per signature (reuse leaks private key)
|
||||
- Use RFC 6979 for deterministic k derivation
|
||||
|
||||
### Schnorr Signatures (BIP-340)
|
||||
|
||||
Simpler, more efficient, with provable security.
|
||||
|
||||
**Signing message m**:
|
||||
```
|
||||
1. Random: k ∈ [1, n-1]
|
||||
2. Compute: R = kG
|
||||
3. Challenge: e = H(R || Q || m)
|
||||
4. Response: s = k + ed mod n
|
||||
5. Signature: (R, s) or (r_x, s) where r_x is x-coordinate of R
|
||||
```
|
||||
|
||||
**Verification**:
|
||||
```
|
||||
1. Compute: e = H(R || Q || m)
|
||||
2. Check: sG = R + eQ
|
||||
```
|
||||
|
||||
**Advantages over ECDSA**:
|
||||
- Linear: enables signature aggregation (MuSig)
|
||||
- Simpler verification (no modular inverse)
|
||||
- Batch verification support
|
||||
- Provably secure in Random Oracle Model
|
||||
|
||||
## Implementation Considerations
|
||||
|
||||
### Constant-Time Operations
|
||||
|
||||
To prevent timing attacks:
|
||||
- Avoid branches dependent on secret data
|
||||
- Use constant-time comparison functions
|
||||
- Mask operations to hide data-dependent timing
|
||||
|
||||
```go
|
||||
// BAD: Timing leak
|
||||
if secretBit == 1 {
|
||||
doOperation()
|
||||
}
|
||||
|
||||
// GOOD: Constant-time conditional
|
||||
result = conditionalSelect(secretBit, value1, value0)
|
||||
```
|
||||
|
||||
### Memory Safety
|
||||
|
||||
- Zeroize sensitive data after use
|
||||
- Avoid leaving secrets in registers or cache
|
||||
- Use secure memory allocation when available
|
||||
|
||||
### Side-Channel Protections
|
||||
|
||||
- **Timing attacks**: Use constant-time algorithms
|
||||
- **Power analysis**: Montgomery ladder, point blinding
|
||||
- **Cache attacks**: Avoid table lookups indexed by secrets
|
||||
|
||||
### Random Number Generation
|
||||
|
||||
- Use cryptographically secure RNG for k in ECDSA
|
||||
- Consider deterministic k (RFC 6979) for reproducibility
|
||||
- Validate output is in valid range [1, n-1]
|
||||
|
||||
## libsecp256k1 Optimizations
|
||||
|
||||
The Bitcoin Core library includes:
|
||||
|
||||
1. **Field arithmetic**: 5×52-bit limbs for 64-bit platforms
|
||||
2. **Scalar arithmetic**: 4×64-bit representation
|
||||
3. **Endomorphism**: GLV decomposition enabled by default
|
||||
4. **Batch inversion**: Amortizes expensive inversions
|
||||
5. **SafeGCD**: Constant-time modular inverse
|
||||
6. **Precomputed tables**: For generator point multiplications
|
||||
|
||||
## Security Properties
|
||||
|
||||
### Discrete Logarithm Problem (DLP)
|
||||
|
||||
Given P and Q = kP, finding k is computationally infeasible.
|
||||
|
||||
**Best known attacks**:
|
||||
- Generic: Baby-step Giant-step, Pollard's rho: O(√n) operations
|
||||
- For secp256k1: ~2¹²⁸ operations (128-bit security)
|
||||
|
||||
### Curve Security Criteria
|
||||
|
||||
- Large prime order subgroup
|
||||
- Cofactor 1 (no small subgroup attacks)
|
||||
- Resistant to MOV attack (embedding degree)
|
||||
- Not anomalous (n ≠ p)
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
1. **k reuse in ECDSA**: Immediately leaks private key
|
||||
2. **Weak random k**: Partially leaks key over multiple signatures
|
||||
3. **Invalid curve points**: Validate points are on curve
|
||||
4. **Small subgroup attacks**: Check point order (cofactor = 1 helps)
|
||||
5. **Timing leaks**: Non-constant-time scalar multiplication
|
||||
|
||||
## References
|
||||
|
||||
For detailed implementations, see:
|
||||
- `references/secp256k1-parameters.md` - Full curve parameters
|
||||
- `references/algorithms.md` - Detailed algorithm pseudocode
|
||||
- `references/security.md` - Security analysis and attack vectors
|
||||
Reference in New Issue
Block a user