Pure-Rust Poly1305 MAC implementation for no_std and bare-metal targets.
The standard poly1305 crate (from RustCrypto) fails 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 the crate uses SIMD intrinsics that aren't available on all targets. This pure-Rust implementation avoids SIMD entirely, making it portable to any Rust target.
- 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 implementation
- RFC 8439 compliant: Passes official test vectors
- Simple API: Drop-in replacement for other Poly1305 implementations
- 128-bit authentication tag
- One-time MAC (key must be unique per message)
- Constant-time operations (no secret-dependent branches)
- ~10 cycles/byte on modern x86_64
Add to your Cargo.toml:
[dependencies]
poly1305-nostd = "0.1"use poly1305_nostd::Poly1305;
let key = [0u8; 32]; // Must be unique per message
let message = b"Hello, world!";
let tag = Poly1305::mac(&key, message);
assert_eq!(tag.len(), 16);use poly1305_nostd::Poly1305;
let key = [0u8; 32];
let mut poly = Poly1305::new(&key);
poly.update(b"Hello, ");
poly.update(b"world!");
let tag = poly.finalize();Poly1305 is a one-time authenticator designed by Daniel J. Bernstein:
- Clamp the 'r' portion of the key
- Process message in 16-byte blocks
- Accumulate:
a = ((a + block) * r) mod (2^130 - 5) - Add 's' portion of key:
tag = (a + s) mod 2^128
- Uses 26-bit limb representation for field arithmetic
- Field operations modulo
2^130 - 5 - Avoids arithmetic overflow through careful reduction
- No heap allocations
On modern x86_64 CPUs:
- ~10 cycles/byte for bulk operations
- ~2 µs for 1 KB message
(Performance varies by target; bare-metal may differ)
Tested on:
x86_64-unknown-none(bare-metal)x86_64-unknown-linux-gnu(std)- Other targets should work but are untested
Run the test suite:
cargo testIncludes RFC 8439 test vectors.
Licensed under Apache License 2.0.
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.