Crates.io | rusty-saber |
lib.rs | rusty-saber |
version | 1.0.0 |
source | src |
created_at | 2022-03-05 13:47:23.508325 |
updated_at | 2022-03-05 13:47:23.508325 |
description | Pure rust implementation of the PQC scheme Saber |
homepage | |
repository | https://github.com/lkiem/rusty_saber |
max_upload_size | |
id | 544019 |
size | 182,060 |
A safe pure-rust implementation of the Saber post-quantum scheme.
sha3
as SHA-3 implementation and aes
as AES block cipher (used as RNG) implementationAnyone, how wants to utilize Saber to negotiate a symmetric key between two parties.
Add this to your Cargo.toml
:
[dependencies]
rusty-saber = "1.0"
To use a specific Saber variant, you need to import it with the corresponding feature flag:
[dependencies]
rusty-saber = { version = "1.0", features = ["lightsaber"] }
Feature flags for the three variants are called lightsaber
, saber
, and firesaber
respectively.
The simple
example illustrates the API:
use rusty_saber::api::{
CRYPTO_BYTES, CRYPTO_CIPHERTEXTBYTES, CRYPTO_PUBLICKEYBYTES, CRYPTO_SECRETKEYBYTES,
};
use rusty_saber::kem::{crypto_kem_dec, crypto_kem_enc, crypto_kem_keypair};
use rusty_saber::rng::AesState;
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
let mut pk = [0u8; CRYPTO_PUBLICKEYBYTES];
let mut sk = [0u8; CRYPTO_SECRETKEYBYTES];
let mut ct = [0u8; CRYPTO_CIPHERTEXTBYTES];
let mut ss_a = [0u8; CRYPTO_BYTES];
let mut ss_b = [0u8; CRYPTO_BYTES];
let mut rng = AesState::new();
//rng.randombytes_init([0u8; 48]); // TODO use a proper seed (like bytes from /dev/urandom) here
// Party a: generate public key `pk` and secret key `sk`
crypto_kem_keypair(&mut pk, &mut sk, &mut rng)?;
// Party b: generate a shared secret `ss_a` and ciphertext `ct` from the public key `pk`
crypto_kem_enc(&mut ct, &mut ss_a, &mut pk, &mut rng)?;
// Party a: derive the same shared secret `ss_b` from the ciphertext `ct` and the secret key `sk`
crypto_kem_dec(&mut ss_b, &mut ct, &mut sk)?;
assert_eq!(ss_a, ss_b);
Ok(())
}
This library comes with two examples:
$ cargo run --example simple
The pqcgenkat_kem
example implements the classic request/response file structure which is part of the NIST PQC framework.
$ cargo run --example pqcgenkat_kem
$ ls *.r??
PQCkemKAT_2304.req PQCkemKAT_2304.rsp
$ tail -n 2 PQCkemKAT_2304.rsp
ss = E5256B4F25816367FBE235E47C25ABB78195CEF7DE3F9C77926839F209CDF652
The different variants can be enabled through feature flags:
$ cargo run --example pqcgenkat_kem --features lightsaber
$ ls *.r??
PQCkemKAT_1568.req PQCkemKAT_1568.rsp
saber
is the default variant. Unfortunately, you cannot enable two variants simultaneously.
Yes. You can run unittests with the following commands:
$ cargo test --features cref,lightsaber
$ cargo test --features cref
$ cargo test --features cref,firesaber
It compares the output of function calls with its C equivalent.
Besides unittests, you can generate the pqcgenkat_kem
req/rsp files and compare them to the ones generated by the C reference implementation.
We verified that they are equivalent.
Yes, but it takes roughly 16.2% more runtime than the C implementation. Here, data is always mentioned with clock cycles as unit. The rust implementation has the following clock-cycle count characteristics (the smaller the better):
complete KEM | keypair | enc | dec | |
lightsaber | 329,964 | 86,665 | 116,139 | 121,433 |
saber | 586,544 | 182,183 | 216,528 | 232,882 |
firesaber | 923,330 | 282,467 | 318,043 | 335,297 |
The C reference implementation has the following clock-cycle count characteristics (the smaller the better):
complete KEM | keypair | enc | dec | |
lightsaber | 284,558 | 72,785 | 95,936 | 115,837 |
saber | 509,361 | 140,370 | 174,995 | 193,996 |
firesaber | 785,548 | 222,955 | 268,561 | 294,032 |
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 has been used as given in benches/
and in case of C, the rudimentary code utilizing the TSC register provided with the reference implementation is used. I disabled CPU frequency scaling before running experiments. You can run the benchmark suite yourself with the bench
subcommand, the cref
feature and optionally some variant feature flag:
$ cargo bench --features cref,lightsaber
$ cargo bench --features cref
$ cargo bench --features cref,firesaber
On github.
On github.