Motivation
In my previous job, I advised students on bachelor theses. Topics, I offered, included the implementation of post-quantum cryptography schemes in rust. One student chose to implement Saber in rust. Today, I am proud to announce our 1.0 release of rusty-saber, a pure-rust implementation of the Saber KEM.
rusty-saber
Saber
Saber is a third-NIST-round post-quantum key encapsulation mechanism to negotiate a secret key between two parties.
API
The API consists of some constants that define the size of buffers as well as the three KEM steps (key generation, encryption, decryption) and an RNG implementation AesState
.
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;
To run the negotiation, you need to allocate all buffers and then use a proper seed (like /dev/urandom
). We left out fetching a proper seed in the example code:
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
Then, we run the KEM:
// 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);
The assert shows the surprising property of a KEM: the shared secret of both parties is the same.
Characteristics
The README file lists some properties:
-
It depends on sha3 as SHA-3 implementation and aes as AES block cipher (used as RNG) implementation
-
It passes the 100 testcases of the C reference implementation
-
The C reference implementation is included in this distribution since it is used for tests
-
It implements the three variants: LightSaber, Saber, FireSaber
-
The KEM takes about 25 milliseconds (all three variants) 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
-
It uses roughly 16% more runtime than the C implementation.
Conclusion
I am proud of this work and glad to see some progress in the intersection of rust and PQC. Thank you Lukas for this awesome journey!