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.

Examples

Secp256k1 Key Derivation

Derive public keys from private keys using elliptic curve point multiplication. Every Ethereum account’s public key and address are derived from a 32-byte private key.

Overview

Secp256k1 key derivation computes:
Where:
  • private_key is a 256-bit scalar (secret)
  • G is the secp256k1 generator point (public constant)
  • * denotes elliptic curve point multiplication (scalar multiplication)
  • public_key is a point on the curve (x, y coordinates)
This operation is:
  • One-way - Easy to compute public from private, infeasible to reverse
  • Deterministic - Same private key always produces same public key
  • Trapdoor - Knowing the private key makes verification trivial

API

derivePublicKey(privateKey)

Derive the 64-byte uncompressed public key from a private key. Parameters:
  • privateKey (Uint8Array) - 32-byte private key (0 < key < n)
Returns: Uint8Array - 64-byte public key (x || y coordinates, no prefix) Throws:
  • InvalidPrivateKeyError - Key wrong length, zero, or >= curve order
Example:

isValidPrivateKey(privateKey)

Check if a byte array is a valid secp256k1 private key. Parameters:
  • privateKey (Uint8Array) - Candidate private key
Returns: boolean
  • true - Key is valid (32 bytes, 0 < key < n)
  • false - Key is invalid
Example:

isValidPublicKey(publicKey)

Check if a byte array is a valid secp256k1 public key. Parameters:
  • publicKey (Uint8Array) - Candidate public key
Returns: boolean
  • true - Key is valid (64 bytes, point on curve)
  • false - Key is invalid
Example:

Algorithm Details

Elliptic Curve Point Multiplication

Scalar multiplication computes k * P (point P added to itself k times): Naive approach (slow):
Double-and-add (fast):
For secp256k1, point operations use:
  • Point addition: P + Q (combining two different points)
  • Point doubling: 2P (adding point to itself)
  • Affine coordinates: (x, y) satisfying y² = x³ + 7 mod p

Private Key Validation

A valid private key must satisfy:
Where n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 (curve order). Invalid keys:
  • Zero (0x0000...0000) - No corresponding public key
  • >= n - Wraps around modulo n, ambiguous
  • Wrong length - Must be exactly 32 bytes

Public Key Format

Public keys are curve points (x, y) where:
With p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F (field prime). Uncompressed (64 bytes): x || y
  • Our internal format (no prefix)
  • Both coordinates included
Compressed (33 bytes): prefix || x
  • Prefix 0x02 (y is even) or 0x03 (y is odd)
  • Reconstructs y from x using curve equation
Standard uncompressed (65 bytes): 0x04 || x || y
  • Common in other libraries
  • Our API strips the 0x04 prefix

Ethereum Address Derivation

Ethereum addresses are derived from public keys:
Important: Ethereum addresses use the last 20 bytes of the Keccak256 hash, not the first 20 bytes.

Security Considerations

Private Key Generation

⚠️ Use cryptographically secure random for private key generation: Correct:
Incorrect:
Entropy sources:
  • crypto.getRandomValues() (browser)
  • crypto.randomBytes() (Node.js)
  • Hardware RNG (HSM, Secure Enclave)
  • Dice rolls + hashing (offline generation)
Never use:
  • Math.random() - Predictable, not cryptographic
  • Timestamps - Low entropy, predictable
  • User input alone - Biased, low entropy

Key Storage

⚠️ Protect private keys at rest and in transit: Best practices:
  • Store in hardware wallets (Ledger, Trezor)
  • Use Secure Enclave / TPM on mobile/desktop
  • Encrypt with strong passphrase (AES-256-GCM)
  • Never log, print, or transmit unencrypted
  • Use key derivation (BIP32/BIP44) for backups
Avoid:
  • Plain text files
  • Environment variables (leaks in logs)
  • Version control (git history)
  • Clipboard (malware can read)
  • Screenshots (OCR readable)

Side-Channel Resistance

Public key derivation can leak private keys through timing attacks if not constant-time: Vulnerable (non-constant-time):
Secure (constant-time):
Implementation notes:
  • TypeScript (@noble/curves): Constant-time ✅
  • Zig (custom): ⚠️ NOT constant-time, unaudited

Test Vectors

Known Private Key = 1

Deterministic Derivation

Different Keys = Different Public Keys

Edge Cases

Performance

Elliptic curve point multiplication is computationally expensive:
  • 256-bit scalar - Requires ~256 point doublings + ~128 additions (average)
  • Modular arithmetic - All operations modulo large primes
Typical derivation time:
  • TypeScript (@noble/curves): ~0.5-1ms per key
  • Zig (native): ~0.2-0.5ms per key
  • WASM (portable): ~1-2ms per key
For batch key derivation, consider:
  • Precomputing common multiples of G
  • Using windowed algorithms (NAF, wNAF)
  • Hardware acceleration (if available)