Skip to main content

Try it Live

Run Secp256k1 examples in the interactive playground
This page is a placeholder. All examples on this page are currently AI-generated and are not correct. This documentation will be completed in the future with accurate, tested examples.

Secp256k1 Security

Security considerations, attack vectors, and best practices for elliptic curve cryptography with secp256k1.

Critical Warnings

⚠️ Zig Implementation NOT Audited The Zig implementation (src/crypto/secp256k1.zig) is:
  • UNAUDITED - No security review
  • NOT constant-time - Vulnerable to timing attacks
  • Educational only - Do not use in production
For production, use:
  1. TypeScript implementation (@noble/curves) - audited
  2. Hardware wallets (Ledger, Trezor)
  3. EVM precompiles (ecRecover)

Private Key Security

Generation

Use cryptographically secure random: Correct:
Never:
Entropy requirements:
  • Minimum 256 bits (32 bytes) of cryptographic randomness
  • Use OS-provided CSPRNG (crypto.getRandomValues)
  • Hardware RNG preferred (TPM, Secure Enclave)
  • For offline: dice rolls + hashing (256 rolls * 2.58 bits = 660 bits)

Storage

⚠️ Protect keys at rest: Best practices:
  • Hardware wallets: Store in Ledger/Trezor, never export
  • Encrypted keystores: AES-256-GCM with strong KDF (scrypt/argon2)
  • Secure Enclave: iOS/macOS hardware-backed storage
  • HSM: Enterprise hardware security modules
  • Environment isolation: Air-gapped for high-value keys
Avoid:
  • Plain text files
  • Environment variables (leak in logs)
  • Git repositories (permanent history)
  • Clipboard (malware can read)
  • Screenshots (OCR readable)
  • Cloud storage unencrypted
  • Browser localStorage unencrypted

Key Derivation

Use BIP32/BIP39 for backups:

Nonce Security

RFC 6979 Deterministic Nonces

Why deterministic? Random nonce generation has catastrophic failure modes: Nonce reuse leaks private key:
Real attacks:
  • PlayStation 3 hack (2010) - Sony reused k=4
  • Bitcoin theft - Bad RNG in Android wallet (2013)
  • Blockchain.info bug (2014) - Weak Java SecureRandom
RFC 6979 prevents this:
Benefits:
  • Same (message, key) always produces same nonce
  • No RNG required
  • Deterministic = testable
  • HMAC_DRBG provides cryptographic strength

Implementation Requirements

All implementations MUST:
  • Use RFC 6979 deterministic nonces
  • NEVER allow custom nonce input
  • NEVER reuse nonces across different messages
  • Validate nonce is in range [1, n-1]

Signature Malleability

Problem

ECDSA signatures have inherent malleability:
Attacks:
  • Transaction replay with modified txHash
  • Smart contract vulnerabilities (signature-based authentication)
  • Blockchain state inconsistency

Solution: Low-s Enforcement

Ethereum enforces s ≤ n/2 (BIP 62, EIP-2):
Our implementation:
  • sign() always produces low-s
  • verify() rejects high-s signatures
  • recoverPublicKey() rejects high-s

Side-Channel Attacks

Timing Attacks

Non-constant-time implementations leak secrets via execution time: Vulnerable:
Constant-time:
Attack scenario:
Mitigations:
  • Use constant-time libraries (@noble/curves ✅)
  • Avoid conditional branches on secrets
  • Use hardware wallets (constant-time guaranteed)
  • Avoid Zig implementation (⚠️ NOT constant-time)

Power Analysis

Differential Power Analysis (DPA):
  • Measure CPU power consumption during crypto ops
  • Correlate power spikes with bit operations
  • Recover secret keys after many measurements
Simple Power Analysis (SPA):
  • Single power trace reveals operation sequence
  • Identify point additions vs doublings
  • Reconstruct scalar multiplication pattern
Mitigations:
  • Hardware security (HSM, Secure Enclave)
  • Power randomization
  • Constant-time algorithms
  • Blinding techniques

Cache Timing Attacks

Memory access patterns leak information via cache hits/misses: Vulnerable:
Secure:
Real attacks:
  • Flush+Reload on AES T-tables
  • Prime+Probe on RSA/ECC

Message Hashing

Always Hash Before Signing

⚠️ Sign hashes, not raw messages: Vulnerable:
Secure:
Why?
  • ECDSA security requires random-looking messages
  • Raw messages may have structure attackers exploit
  • Hashing provides collision resistance
  • Fixed-length input simplifies validation

Hash Function Requirements

Use collision-resistant hash functions: Approved:
  • Keccak256 (Ethereum standard)
  • SHA-256 (Bitcoin, general use)
  • SHA-3 (NIST standard)
  • Blake2b (high performance)
Deprecated:
  • MD5 (broken - collisions trivial)
  • SHA-1 (broken - collisions practical)

Public Key Validation

Always Validate Public Keys

⚠️ Verify points are on curve:
Attacks if unvalidated:
  • Invalid curve attacks (point not on secp256k1)
  • Small subgroup attacks
  • Twist attacks (point on quadratic twist)

Check for Point at Infinity

Ethereum-Specific Considerations

EIP-155 Replay Protection

Problem: Signatures valid on one chain can be replayed on forks. Solution: Include chainId in v value:

ecRecover Gotchas

Precompile behavior:
  • Returns zero address on invalid signature (NOT error)
  • Always check return value != 0x0

EIP-191 Personal Sign

Prefix prevents signing raw transactions:

Best Practices Summary

DO

✅ Use hardware wallets for high-value keys ✅ Use @noble/curves (audited) for TypeScript ✅ Generate keys with crypto.getRandomValues() ✅ Store encrypted keystores (AES-256-GCM + scrypt) ✅ Validate all inputs (keys, signatures, hashes) ✅ Use RFC 6979 deterministic nonces ✅ Enforce low-s malleability protection ✅ Hash messages before signing ✅ Include EIP-155 chainId in signatures ✅ Use BIP39/BIP32 for backups ✅ Test with official test vectors

DON’T

❌ Use Math.random() for key generation ❌ Reuse nonces across messages ❌ Store private keys unencrypted ❌ Sign raw messages without hashing ❌ Skip public key validation ❌ Use Zig implementation in production (unaudited) ❌ Implement custom crypto (use audited libraries) ❌ Trust user-provided public keys without validation ❌ Ignore signature malleability ❌ Forget EIP-155 replay protection

Security Checklist

  • Keys generated with CSPRNG
  • Keys stored encrypted or in hardware
  • Using audited library (@noble/curves)
  • RFC 6979 deterministic nonces
  • Low-s enforcement enabled
  • Public keys validated (point on curve)
  • Messages hashed before signing
  • EIP-155 chainId in signatures
  • Test vectors passing
  • No custom crypto implementation
  • Side-channel mitigations in place
  • ecRecover zero-address checks