x25519-nostd
Pure-Rust X25519 (Curve25519) elliptic curve Diffie-Hellman implementation for no_std and bare-metal targets.
Why This Crate Exists
The standard curve25519-dalek and x25519-dalek crates (from RustCrypto) fail to compile on certain bare-metal targets like x86_64-unknown-none with LLVM errors:
LLVM ERROR: Do not know how to split the result of this operator!
This happens because these crates use SIMD intrinsics that aren't available on all targets. This pure-Rust implementation avoids SIMD entirely, making it portable to any Rust target.
Features
- 100% Pure Rust: No assembly, no SIMD, no platform-specific code
no_stdcompatible: Works in bare-metal and embedded environments- Constant-time: Side-channel resistant Montgomery ladder
- RFC 7748 compliant: Passes official test vectors
- Simple API: Drop-in replacement for other X25519 implementations
Security Properties
- 128-bit security level
- Constant-time operations (resistant to timing attacks)
- 32-byte keys (compact and efficient)
- ~100k operations/sec on modern CPUs
Usage
Add to your Cargo.toml:
[]
= "0.1"
Key Exchange
use ;
// Alice generates a keypair
let alice_secret = ; // In practice, use secure random
let alice_public = public_key;
// Bob generates a keypair
let bob_secret = ;
let bob_public = public_key;
// Both compute the same shared secret
let alice_shared = diffie_hellman;
let bob_shared = diffie_hellman;
assert_eq!;
WireGuard-style Usage
use ;
// Generate static keypair
let static_secret = ;
let static_public = public_key;
// Compute shared secret with peer
let peer_public = ;
let shared_secret = diffie_hellman;
// Use shared_secret with a KDF (like BLAKE2s or HKDF)
Algorithm
X25519 performs scalar multiplication on Curve25519:
- Curve equation:
y² = x³ + 486662x² + x - Prime field:
p = 2^255 - 19 - Base point:
u = 9 - Scalar clamping:
s[0] &= 248, s[31] &= 127, s[31] |= 64
Uses the Montgomery ladder for constant-time scalar multiplication.
Implementation Details
- Field elements represented as 5 limbs of 51 bits each (255 bits total)
- Montgomery ladder for constant-time point multiplication
- Field arithmetic modulo
2^255 - 19 - Inversion using Fermat's little theorem:
a^(p-2) ≡ a^(-1) (mod p) - No heap allocations
Performance
On modern x86_64 CPUs:
- ~100k key exchanges per second
- ~10 µs per scalar multiplication
(Performance varies by target; bare-metal may differ)
Compatibility
Tested on:
x86_64-unknown-none(bare-metal)x86_64-unknown-linux-gnu(std)- Other targets should work but are untested
Security Notes
- Never reuse secret keys: Generate new ephemeral keys for each session
- Use a KDF: The raw shared secret should be passed through HKDF or similar
- Validate public keys: Check for small-subgroup attacks in your protocol
- Use secure randomness: Never use weak RNGs for key generation
Testing
Run the test suite:
Includes RFC 7748 test vectors.
License
Licensed under Apache License 2.0.
References
- RFC 7748: Elliptic Curves for Security
- Curve25519: new Diffie-Hellman speed records
- WireGuard: Next Generation Kernel Network Tunnel
Contributing
Contributions welcome! This crate was extracted from a bare-metal OS project to help the Rust embedded and bare-metal community overcome LLVM SIMD limitations.