sntrup-sys 0.1.1

Streamlined NTRU Prime, extracted from SUPERCOP with a deduplicated vendor tree, compiled via the cc crate
Documentation
# sntrup-sys

[![crates.io](https://img.shields.io/crates/v/sntrup-sys.svg)](https://crates.io/crates/sntrup-sys)
[![docs.rs](https://img.shields.io/docsrs/sntrup-sys)](https://docs.rs/sntrup-sys)
[![MSRV](https://img.shields.io/badge/MSRV-1.85-blue.svg)](Cargo.toml)
[![license](https://img.shields.io/badge/license-split%20%E2%80%94%20see%20LICENSE.md-yellow.svg)](LICENSE.md)

A standalone, single-algorithm Rust bindings to **Streamlined NTRU Prime**,
a post-quantum key encapsulation mechanism (KEM). The C reference implementation
is vendored from [SUPERCOP](https://bench.cr.yp.to/supercop.html) and
compiled with the [`cc`](https://crates.io/crates/cc) crate — no system package,
no submodule, no network access at build time. Portable ISO C11, no CPU-specific
intrinsics (yet), so it builds anywhere a C compiler does.

## Usage

```rust
let (pk, sk) = sntrup_sys::sntrup761::keypair();
let (ct, ss1) = sntrup_sys::sntrup761::encapsulate(&pk);
let ss2 = sntrup_sys::sntrup761::decapsulate(&ct, &sk);
assert_eq!(ss1, ss2);
```

Every parameter set exposes the same three functions plus
`PUBLIC_KEY_BYTES`/`SECRET_KEY_BYTES`/`CIPHERTEXT_BYTES`/`SHARED_SECRET_BYTES`
constants (see `src/lib.rs`).

## Parameter sets

All six are gated behind their own Cargo feature (all on by default), so
you can trim the build to just what you need with
`default-features = false, features = ["sntrup761"]`. Sizes in bytes:

| Parameter set | NIST category | Public key | Secret key | Ciphertext | Shared secret |
|---|:---:|---:|---:|---:|---:|
| `sntrup653`  | 1 |  994 | 1518 |  897 | 32 |
| `sntrup761`  | 2 | 1158 | 1763 | 1039 | 32 |
| `sntrup857`  | 3 | 1322 | 1999 | 1184 | 32 |
| `sntrup953`  | 4 | 1505 | 2254 | 1349 | 32 |
| `sntrup1013` | 4 | 1623 | 2417 | 1455 | 32 |
| `sntrup1277` | 5 | 2067 | 3059 | 1847 | 32 |

`sntrup761` is the one used in OpenSSH's `sntrup761x25519-sha512` hybrid
key exchange. Sizes are taken directly from each parameter set's `api.h`
and were confirmed by this crate's own build validation. NIST categories:
`sntrup761` = Category 2 is confirmed directly by
[liboqs](https://github.com/open-quantum-safe/liboqs/blob/main/docs/algorithms/kem/ntruprime.md);
the rest follow the same monotonic mapping commonly cited across the
NTRU Prime ecosystem — if the exact category matters for a compliance
requirement, verify against the
[official submission](https://ntruprime.cr.yp.to/).

Only the `ref` (portable ISO C11) implementation is included; SUPERCOP's
only alternative is x86-64-only hand-written assembly with avx2 feature,
which is on the to-do list for this crate.

## Benchmarking

```bash
cargo bench
```

Uses [`criterion`](https://crates.io/crates/criterion) to benchmark
keypair/encapsulate/decapsulate for every enabled parameter set, with
proper warm-up, iteration-count tuning, outlier rejection, and a confidence
interval, unlike a bare timer loop. Numbers are still environment-sensitive
(CPU, and the platform's random-number-source call overhead), so run it on
hardware you actually care about rather than trusting a number quoted here.
For a third-party reference point, SUPERCOP publishes its own cycle counts
for the `ref` implementation across many CPUs: <https://bench.cr.yp.to/results-kem.html>.

## Randomness

The vendored C code calls one external C function, `randombytes(unsigned
char *, unsigned long long)`, for all key-generation and encapsulation
randomness. `src/lib.rs` implements it via the `getrandom` crate (the OS
CSPRNG) — the one piece of "dependency" the vendored C itself doesn't supply,
by SUPERCOP's own convention.

## Platform notes

`build.rs` targets both compiler families that matter on Windows, not just
one:

- **GCC/Clang** (`*-gnu`, and any Unix target): uses `-include` to
  force-include each directory's `namespace.h` ahead of everything else,
  and `-D` for the `CRYPTO_NAMESPACE`-style defines.
- **MSVC's `cl.exe`** (`*-pc-windows-msvc` — the
  [Rust team's recommended Windows target]https://forge.rust-lang.org/infra/other-installation-methods.html#the-toolchains-available,
  not the `-gnu`/MinGW one): `cl.exe` doesn't understand `-include` at
  all — its equivalent is `/FI`, and it needs `/D` instead of `-D`.
  `build.rs` detects this from `TARGET` and switches spelling.

Getting the flags right wasn't quite the whole story, though: `cl.exe`
(real MSVC, not `clang-cl`) also doesn't understand the GCC/Clang
`__attribute__((...))` extension used in the vendored `cryptoint` headers
under `vendor/common/`. Since those files are untouched autogen output
(see [`vendor/NOTICE.md`](vendor/NOTICE.md)) and not something to hand-edit,
`vendor/common/namespace.h` neutralizes `__attribute__` to a no-op macro
specifically when `_MSC_VER` is defined and neither `__GNUC__` nor
`__clang__` is — i.e. only for real `cl.exe`, not `clang-cl`, which already
understands the extension natively. The same headers also contain inline
GCC-style `__asm__` blocks, but every one is already guarded behind
`#if defined(__GNUC__)` with a portable C fallback, and `cl.exe` never
defines `__GNUC__`, so those need no shim at all.

All of that said: this has only been **compiled and tested on `clang` on
macOS (arm64)** so far. The MSVC path above is a from-first-principles fix
for a real, checked incompatibility (verified by reading `cl.exe`'s actual
documented flag set and grepping every vendored file for GCC/Clang-only
constructs), not something run through an actual Windows/MSVC toolchain —
there isn't one available in this environment. Treat it as "should work,
please verify" rather than "verified," and file an issue with the actual
compiler error if it doesn't.

## Internals

`vendor/` is a deduplicated extraction from SUPERCOP: the generic helper
layer (SHA-512, sort networks, `crypto_declassify`, the `cryptoint`
headers) compiles once and is shared by every parameter set, while the
Streamlined NTRU Prime algorithm itself is stored once but compiled once
per parameter set (the object code genuinely differs — parameter sizes are
baked in at compile time). See [`vendor/NOTICE.md`](vendor/NOTICE.md) for
exactly what was changed from the original SUPERCOP sources, why the split
is drawn where it is, and how the extraction was validated — worth reading
before modifying anything under `vendor/`.

## License

This crate's own code (`build.rs`, `src/lib.rs`, `benches/`) is dual-licensed
under MIT ([`LICENSE-MIT`](LICENSE-MIT)) or Apache-2.0
([`LICENSE-APACHE`](LICENSE-APACHE)), at your option. The vendored
Streamlined NTRU Prime sources under `vendor/algo/` are **not** covered by
that — they're Daniel J. Bernstein and coauthors' code, and the only usage
grant on record from them is purpose-scoped to NIST's public review
process, not a general open-source release. See [`LICENSE.md`](LICENSE.md)
for the full split and [`vendor/NOTICE.md`](vendor/NOTICE.md) for the
source-by-source breakdown — read both before relying on this past
experimentation.