Skip to main content

Try it Live

Run X25519 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.

Overview

X25519 is an elliptic curve Diffie-Hellman (ECDH) key exchange over Curve25519, enabling two parties to establish a shared secret over an insecure channel. Ethereum context: Not on Ethereum - Used for encrypted peer-to-peer communications (e.g., Whisper, Waku). Not part of core protocol. Curve: Montgomery curve v² = u³ + 486662u² + u over prime field 2²⁵⁵ - 19 Key features:
  • Fast: One of the fastest elliptic curve operations available
  • Simple: Single scalar multiplication, no complex point arithmetic
  • Secure: 128-bit security level with built-in protection against timing attacks
  • Small keys: 32-byte public and secret keys
  • No signatures: X25519 is for key exchange only (use Ed25519 for signatures)
  • Implementations: Native Zig (3KB), WASM via wasm-loader
Modern usage: TLS 1.3, WireGuard, Signal Protocol, SSH, Tor, WhatsApp, iMessage, and nearly all modern encrypted communications.

Quick Start

API Reference

Key Generation

generateKeypair()

Generate a random X25519 keypair using cryptographically secure random number generator. Parameters: None Returns: { secretKey: Uint8Array, publicKey: Uint8Array }
  • secretKey - 32-byte secret key
  • publicKey - 32-byte public key

keypairFromSeed(seed)

Generate deterministic X25519 keypair from a 32-byte seed. Parameters:
  • seed (Uint8Array) - 32-byte seed for deterministic generation
Returns: { secretKey: Uint8Array, publicKey: Uint8Array } Throws:
  • InvalidSecretKeyError - Seed wrong length
  • X25519Error - Keypair generation failed

generateSecretKey()

Generate a random 32-byte secret key. Parameters: None Returns: Uint8Array - 32-byte secret key

derivePublicKey(secretKey)

Derive public key from secret key. Parameters:
  • secretKey (Uint8Array) - 32-byte secret key
Returns: Uint8Array - 32-byte public key Throws:
  • InvalidSecretKeyError - Secret key invalid

Key Exchange

scalarmult(secretKey, publicKey)

Perform X25519 scalar multiplication to compute shared secret. This is the core ECDH operation. Parameters:
  • secretKey (Uint8Array) - Your 32-byte secret key
  • publicKey (Uint8Array) - Their 32-byte public key
Returns: Uint8Array - 32-byte shared secret Throws:
  • InvalidSecretKeyError - Secret key invalid
  • InvalidPublicKeyError - Public key invalid
  • X25519Error - Scalar multiplication failed

Validation

validateSecretKey(secretKey)

Check if a byte array is a valid X25519 secret key. Parameters:
  • secretKey (Uint8Array) - Candidate secret key
Returns: boolean - true if valid (32 bytes)

validatePublicKey(publicKey)

Check if a byte array is a valid X25519 public key. Parameters:
  • publicKey (Uint8Array) - Candidate public key
Returns: boolean - true if valid (32 bytes, valid curve point)

Constants

Security Considerations

Critical Warnings

⚠️ Shared secret derivation: The raw X25519 output should always be used with a Key Derivation Function (KDF) like HKDF before using as a symmetric key. Never use the shared secret directly.
⚠️ No authentication: X25519 provides secrecy but not authentication. An attacker can perform a man-in-the-middle attack if you don’t verify the peer’s public key (e.g., via signatures or certificates). ⚠️ One-time use: Shared secrets should be ephemeral. Generate new keypairs for each session (forward secrecy). ⚠️ Small subgroup attacks: X25519 is designed to be resistant, but always validate public keys received from untrusted sources. ⚠️ Use cryptographically secure random: Never use Math.random() for key generation. Use crypto.getRandomValues().

TypeScript Implementation

The TypeScript implementation uses @noble/curves/ed25519 (x25519 export) by Paul Miller:
  • Security audited and production-ready
  • Constant-time operations to prevent timing attacks
  • Montgomery ladder for scalar multiplication
  • Built-in clamping and validation
  • ~15KB minified

Test Vectors

RFC 7748 Test Vectors

Iteration Test (RFC 7748)

Deterministic Keypair Generation

Implementation Details

TypeScript

Library: @noble/curves/ed25519 (x25519 export) by Paul Miller
  • Audit status: Security audited, production-ready
  • Standard: RFC 7748 compliant
  • Features: Constant-time Montgomery ladder, automatic clamping
  • Size: ~15KB minified (tree-shakeable)
  • Performance: Fastest JavaScript X25519 implementation
Key design:
  • Uses Montgomery curve representation internally
  • Automatic scalar clamping (bits 0, 1, 2, 255 cleared; bit 254 set)
  • Constant-time to prevent timing attacks
  • Validates all inputs

Zig

Implementation: std.crypto.dh.X25519 from Zig standard library
  • Status: Production-ready, audited
  • Standard: RFC 7748 compliant
  • Features: Constant-time, optimized for all architectures
  • Integration: Available via FFI and WASM
Zig wrapper provides allocator-based API for memory management.

WASM

X25519 operations available in WASM builds:
  • ReleaseSmall: Size-optimized
  • ReleaseFast: Performance-optimized

Protocol Integration Examples

Signal Protocol (Double Ratchet)

WireGuard VPN

TLS 1.3 Key Exchange

Web3 Usage

X25519 appears in Web3 infrastructure (not core protocol):

Encrypted Communication

  • Decentralized messaging: Status, Matrix use X25519 for E2E encryption
  • Wallet-to-wallet encryption: Encrypted direct messages between addresses
  • IPFS/Filecoin: Encrypted file storage with X25519 key exchange

Layer 2 and Privacy

  • State channels: Encrypted off-chain communication
  • Rollup operators: Secure operator-to-operator communication
  • Privacy protocols: Aztec, Tornado Cash use X25519 for encrypted notes

Cross-chain Integration

  • Cosmos IBC: X25519 for encrypted cross-chain messages
  • Polkadot parachains: X25519 in XCM encrypted channels

X25519 vs Ed25519

X25519 and Ed25519 are related but different - both use Curve25519 but for different purposes: Use both together:

X25519 vs P256 ECDH

When to use X25519:
  • New protocols and applications
  • Maximum performance
  • Simple, secure-by-default design
  • Modern encrypted communications (Signal, WireGuard)
When to use P256 ECDH:
  • Enterprise/government compliance (FIPS)
  • Hardware acceleration needed (TPM, Secure Enclave)
  • Legacy system compatibility
  • WebAuthn integration

Error Handling

All X25519 functions throw typed errors that extend CryptoError:
All error classes have:
  • name - Error class name (e.g., "InvalidSecretKeyError")
  • code - Machine-readable error code
  • message - Human-readable description
  • docsPath - Link to relevant documentation