# poly1305-nostd
Pure-Rust Poly1305 MAC implementation for `no_std` and bare-metal targets.
## Why This Crate Exists
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.
## Features
- **100% Pure Rust**: No assembly, no SIMD, no platform-specific code
- **`no_std` compatible**: 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
## Security Properties
- 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
## Usage
Add to your `Cargo.toml`:
```toml
[dependencies]
poly1305-nostd = "0.1"
```
### One-shot MAC
```rust
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);
```
### Incremental MAC
```rust
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();
```
## Algorithm
Poly1305 is a one-time authenticator designed by Daniel J. Bernstein:
1. Clamp the 'r' portion of the key
2. Process message in 16-byte blocks
3. Accumulate: `a = ((a + block) * r) mod (2^130 - 5)`
4. Add 's' portion of key: `tag = (a + s) mod 2^128`
## Implementation Details
- Uses 26-bit limb representation for field arithmetic
- Field operations modulo `2^130 - 5`
- Avoids arithmetic overflow through careful reduction
- No heap allocations
## Performance
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)
## Compatibility
Tested on:
- `x86_64-unknown-none` (bare-metal)
- `x86_64-unknown-linux-gnu` (std)
- Other targets should work but are untested
## Testing
Run the test suite:
```bash
cargo test
```
Includes RFC 8439 test vectors.
## License
Licensed under Apache License 2.0.
## References
- [RFC 8439: ChaCha20-Poly1305 AEAD](https://tools.ietf.org/html/rfc8439)
- [The Poly1305-AES message-authentication code](https://cr.yp.to/mac.html)
## 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.