# ntrust-native A safe pure-rust implementation of the NTRU post-quantum scheme. * NTRU is a lattice-based key encapsulation mechanism (KEM) * The implementation is based on the NTRU reference implementation of NIST round 3 * The implementation does not utilize any concurrency techniques (SIMD/threading/…, except maybe auto-vectorization on your CPU) * It depends on `tiny-keccak` as SHA-3 implementation and `aes` as AES block cipher (used as RNG) implementation * It passes the 100 testcases of the C reference implementation * It implements the NTRU-HPS (Hoffstein-Pipher-Silverman) scheme in three variants * It implements the NTRU-HRSS (Hülsing-Rijneveld-Schanck-Schwabe) scheme in one variant * The implementation takes between 20 milliseconds (`ntruhps2048509`) and 45 milliseconds (`ntruhps4096821`) to run on a modern computer * The implementation is constant-time on software instruction level * The random number generator is based on AES256 in counter mode * NTRUst is the name of a WebAssembly implementation. Thus, this implementation is called `ntrust-native`. ## Who should use it? Anyone, how wants to use the NTRU scheme to negotiate a key between two parties. ## How does one use it? Add this to your `Cargo.toml`: ```toml [dependencies] ntrust-native = "1.0" ``` To use a specific NTRU variant, you need to import it with the corresponding feature flag: ```toml [dependencies] ntrust-native = { version = "1.0", features = ["ntruhrss701"] } ``` The `simple` example illustrates the API: ```rust use ntrust_native::AesState; use ntrust_native::{crypto_kem_dec, crypto_kem_enc, crypto_kem_keypair}; use ntrust_native::{CRYPTO_BYTES, CRYPTO_CIPHERTEXTBYTES, CRYPTO_PUBLICKEYBYTES, CRYPTO_SECRETKEYBYTES}; use std::error; fn main() -> Result<(), Box> { let mut rng = AesState::new(); let mut pk = [0u8; CRYPTO_PUBLICKEYBYTES]; let mut sk = [0u8; CRYPTO_SECRETKEYBYTES]; let mut ct = [0u8; CRYPTO_CIPHERTEXTBYTES]; let mut ss_alice = [0u8; CRYPTO_BYTES]; let mut ss_bob = [0u8; CRYPTO_BYTES]; crypto_kem_keypair(&mut pk, &mut sk, &mut rng)?; crypto_kem_enc(&mut ct, &mut ss_bob, &pk, &mut rng)?; crypto_kem_dec(&mut ss_alice, &ct, &sk)?; assert_eq!(ss_bob, ss_alice); Ok(()) } ``` ## How does one run it? This library comes with two examples: ```bash $ cargo run --example simple ``` The output annotates messages with Alice/Bob to illustrate which data is processed by which party. The `katkem` example implements the classic request/response file structure which is part of the NIST PQC framework. ```bash $ cargo run --example katkem PQCkemKAT_935.req PQCkemKAT_935.rsp $ cargo run --example katkem PQCkemKAT_935.rsp ``` The different variants (`ntruhps2048509`, `ntruhps2048677`, `ntruhps4096821`, `ntruhrss701`) can be enabled through feature flags: ```bash $ cargo run --example katkem --features ntruhrss701 -- PQCkemKAT_1450.req PQCkemKAT_1450.rsp ``` `ntruhps2048509` is the default variant. You cannot enable two variants simultaneously. ## How fast is it? All data uses clock cycles as unit. The rust implementation has the following clock-cycle count characteristics (the smaller the better):
complete KEMkeypairencdec
ntruhps204850919,980,85514,105,680472,9091,122,414
ntruhps204867727,478,93924,077,519895,9302,333,079
ntruhps409682142,083,12536,882,7831,487,4013,367,818
ntruhrss70132,433,99328,506,984828,1622,919,074
The C reference implementation has the following clock-cycle count characteristics (the smaller the better):
complete KEMkeypairencdec
ntruhps204850915,912,90012,139,200811,6511,812,650
ntruhps204867728,911,50022,233,6001,520,6403,668,860
ntruhps409682141,914,80032,138,3002,089,3505,908,570
ntruhrss70128,966,60023,134,7001,368,2703,462,640
The tests were done on a Lenovo Thinkpad x260 (Intel Core i5-6200U CPU @ 2.30GHz). In the case of rust, [criterion 0.3.5](https://crates.io/crates/criterion) has been used as given in `benches/` and in case of C, Google's [benchmark](https://github.com/google/benchmark/blob/v1.6.1/docs/perf_counters.md) with PFM support and disabled CPU frequency scaling. Our summary is that both implementations have comparable runtime. rust is a little bit slower (but uses many copy operations for type safety you could replace with `unsafe {}` code). You can run the benchmark suite yourself with the `bench` subcommand and optionally some variant feature flag: ```bash $ cargo bench --features ntruhrss701 ``` ## Where is the source code? On [github](https://github.com/prokls/ntrust-native). ## What is the content's license? [MIT License](LICENSE.txt) ## Changelog * **2022-05-04 version 1.0.1:** documentation fix * **2022-05-03 version 1.0.0:** public release ## Where can I ask you to fix a bug? On [github](https://github.com/prokls/ntrust-native/issues).