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.
11 KiB
name, description
| name | description |
|---|---|
| elliptic-curves | 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:
- Closure: For all a, b ∈ G, the result a · b is also in G
- Associativity: (a · b) · c = a · (b · c)
- Identity: There exists e ∈ G such that e · a = a · e = a
- 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?
- Koblitz curve: a = 0 enables faster computation (no ax term)
- Special prime: p = 2²⁵⁶ - 2³² - 977 allows efficient modular reduction
- Deterministic construction: Not randomly generated, reducing backdoor concerns
- ~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
// 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:
- Field arithmetic: 5×52-bit limbs for 64-bit platforms
- Scalar arithmetic: 4×64-bit representation
- Endomorphism: GLV decomposition enabled by default
- Batch inversion: Amortizes expensive inversions
- SafeGCD: Constant-time modular inverse
- 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
- k reuse in ECDSA: Immediately leaks private key
- Weak random k: Partially leaks key over multiple signatures
- Invalid curve points: Validate points are on curve
- Small subgroup attacks: Check point order (cofactor = 1 helps)
- Timing leaks: Non-constant-time scalar multiplication
References
For detailed implementations, see:
references/secp256k1-parameters.md- Full curve parametersreferences/algorithms.md- Detailed algorithm pseudocodereferences/security.md- Security analysis and attack vectors