A Robust Rust Library for CRYSTALS-Kyber Post-Quantum Cryptography.
β’ Website β’ Documentation β’ Report Bug β’ Request Feature β’ Contributing Guidelines
KyberLib is a robust Rust library designed for CRYSTALS-Kyber Post-Quantum Cryptography, offering strong security guarantees. This library is compatible with no_std
, making it suitable for embedded devices and avoids memory allocations. Additionally, it contains reference implementations with no unsafe code and provides an optimized AVX2 version by default on x86_64 platforms. You can also compile it to WebAssembly (WASM) using wasm-bindgen.
no_std
compatible: No dependence on the Rust standard library- Avoid allocations: Uses stack-based data structures only
- Configurable: Features to enable different parameter sets
- Optimised x86_64: Uses assembly for performance-critical code, including an optimised AVX2 version by default.
- Safe code: Reference implementations have no
unsafe
blocks - WebAssembly Support: Can be compiled to WASM using wasm-bindgen.
- Allocation-free Guarantee: KyberLib guarantees all its core cryptography operations are free of heap allocations.
- Assembly Optimizations: The x86_64 assembly implementations use AVX2 instructions for high performance.
- Security: KyberLib contains no unsafe code in its public API surface.
- Key Generation: Create public/private key pairs
- Encapsulation: Encapsulate a shared secret with a public key
- Decapsulation: Decapsulate a shared secret with a private key
- Key Exchange: Perform authenticated key exchanges
See Documentation for full API details.
It takes just a few minutes to get up and running with kyberlib
.
The minimum supported Rust toolchain version is currently Rust 1.60 or later (stable).
To install kyberlib
, you need to have the Rust toolchain installed on
your machine. You can install the Rust toolchain by following the
instructions on the Rust website.
Once you have the Rust toolchain installed, you can install kyberlib
using the following command:
cargo install kyberlib
To use the kyberlib
library in your project, add the following to your
Cargo.toml
file:
[dependencies]
kyberlib = "0.0.6"
Add the following to your main.rs
file:
extern crate kyberlib;
use kyberlib::*;
then you can use the functions in your application code.
For optimisations on x86 platforms enable the avx2
feature and the following RUSTFLAGS:
export RUSTFLAGS="-C target-feature=+aes,+avx2,+sse2,+sse4.1,+bmi2,+popcnt"
// Generate Keypair
let keys_bob = keypair(&mut rng)?;
// Alice encapsulates a shared secret using Bob's public key
let (ciphertext, shared_secret_alice) = encapsulate(&keys_bob.public, &mut rng)?;
// Bob decapsulates a shared secret using the ciphertext sent by Alice
let shared_secret_bob = decapsulate(&ciphertext, &keys_bob.secret)?;
assert_eq!(shared_secret_alice, shared_secret_bob);
let mut rng = rand::thread_rng();
// Initialize the key exchange structs
let mut alice = Uake::new();
let mut bob = Uake::new();
// Generate Bob's Keypair
let bob_keys = keypair(&mut rng)?;
// Alice initiates key exchange
let client_init = alice.client_init(&bob_keys.public, &mut rng)?;
// Bob authenticates and responds
let server_response = bob.server_receive(
client_init, &bob_keys.secret, &mut rng
)?;
// Alice decapsulates the shared secret
alice.client_confirm(server_response)?;
// Both key exchange structs now have the same shared secret
assert_eq!(alice.shared_secret, bob.shared_secret);
Follows the same workflow except Bob requires Alice's public keys:
let mut alice = Ake::new();
let mut bob = Ake::new();
let alice_keys = keypair(&mut rng)?;
let bob_keys = keypair(&mut rng)?;
let client_init = alice.client_init(&bob_keys.public, &mut rng)?;
let server_response = bob.server_receive(
client_init, &alice_keys.public, &bob_keys.secret, &mut rng
)?;
alice.client_confirm(server_response, &alice_keys.secret)?;
assert_eq!(alice.shared_secret, bob.shared_secret);
The KyberLib crate provides several macros to simplify common cryptographic operations:
-
kyberlib_generate_key_pair!
: Generates a public and private key pair for CCA-secure Kyber key encapsulation mechanism. -
kyberlib_encrypt_message!
: Generates cipher text and a shared secret for a given public key. -
kyberlib_decrypt_message!
: Generates a shared secret for a given cipher text and private key. -
kyberlib_uake_client_init!
: Initiates a Unilaterally Authenticated Key Exchange. -
kyberlib_uake_server_receive!
: Handles the output of akyberlib_uake_client_init()
request. -
kyberlib_uake_client_confirm!
: Decapsulates and authenticates the shared secret from the output ofkyberlib_uake_server_receive()
. -
kyberlib_ake_client_init!
: Initiates a Mutually Authenticated Key Exchange. -
kyberlib_ake_server_receive!
: Handles and authenticates the output of akyberlib_ake_client_init()
request. -
kyberlib_ake_client_confirm!
: Decapsulates and authenticates the shared secret from the output ofkyberlib_ake_server_receive()
.
See the macros module documentation for more details and usage examples.
The KyberLibError enum has two variants:
- InvalidInput - One or more inputs to a function are incorrectly sized. A possible cause of this is two parties using different security levels while trying to negotiate a key exchange.
- InvalidKey - Error when generating keys.
- Decapsulation - The ciphertext was unable to be authenticated. The shared secret was not decapsulated.
- RandomBytesGeneration - Error trying to fill random bytes (i.e., external (hardware) RNG modules can fail).
To get started with kyberlib
, you can use the examples provided in the
examples
directory of the project.
To run the examples, clone the repository and run the following command in your terminal from the project root directory.
Alice and Bob exchange public keys to derive a shared secret in a way that authenticates each party.
Run the following command in your terminal from the project root directory.
cargo run --example ake
Alice generates a keypair. Bob encapsulates a secret using Alice's public key. Alice decapsulates the secret using her private key. This allows secure communication.
Run the following command in your terminal from the project root directory.
cargo run --example kem
Alice and Bob exchange public information to derive a shared secret without authenticating each other. Provides confidentiality but not authentication.
Run the following command in your terminal from the project root directory.
cargo run --example uake
kyberlib
supports a variety of CPU architectures. It is supported and tested on MacOS, Linux, and Windows.
Info: Please check out our website for more information. You can find our documentation on docs.rs, lib.rs and crates.io.
For transparency into our release cycle and in striving to maintain
backward compatibility, kyberlib
follows semantic versioning.
KyberLib is distributed under the terms of both the MIT license and the Apache License (Version 2.0).
See LICENSE-APACHE and LICENSE-MIT for details.
We welcome all people who want to contribute. Please see the contributing instructions for more information.
Contributions in any form (issues, pull requests, etc.) to this project must adhere to the Rust's Code of Conduct.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
A big thank you to all the awesome contributors of kyberlib for their help and support.
This repo is a fork of the innovative Rust implementation of the Kyber post-quantum KEM from Argyle-Software/kyber. We are deeply grateful for the inspiration and contribution of the original project, which has provided a solid foundation for our work and study. Thank you! You can find the original repo here.
A special thank you goes to the Rust Reddit community for providing a lot of useful suggestions on how to improve this project.