Outline
This is intended to facilitate the deployment of quantum-resistant cryptography as per the Quantum Computing Cybersecurity Preparedness Act (12/22) of the United States of America. Note it does not include our enhanced designs, which are subject to patents, and available separately as commercial packages.
Usage
First add the qrc-opensource-rs crate to your Cargo.toml:
Features
Feature List
Feature Usage
Examples
View our Documentation for further information on how to impliment this crate at Docs.rs
Asymmetric
Cipher
Kyber
Based on the C reference branch of PQ-Crystals Kyber; including base code, comments, and api. Removed the K=2 parameter, and added a K=5. The NIST '512' parameter has fallen below the threshold required by NIST PQ S1 minimum. The new K5 parameter may have a better chance of long-term security, with only a small increase in cost.
The NIST Post Quantum Competition Round 3 Finalists. The Kyber website. The Kyber Algorithm Specification.
Date: January 10, 2018 C - Updated: Stiepan A. Kovac - July 2, 2021 Rust Translation: Matt Warminger - 2024 Updated: Matt Warminger - April 23, 2025
The primary public api for the Kyber CCA-secure Key Encapsulation Mechanism implementation:
use ;
let mut seed = ;
qrc_rcrng_generate;
let publickey = &mut ;
let privatekey = &mut ;
let secret1 = &mut ;
let secret2 = &mut ;
let ciphertext = &mut ;
qrc_kyber_generate_keypair;
qrc_kyber_encrypt;
qrc_kyber_decrypt;
McEliece
Classic McEliece is a KEM designed for IND-CCA2 security at a very high security level, even against quantum computers. The KEM is built conservatively from a PKE designed for OW-CPA security, namely Niederreiter's dual version of McEliece's PKE using binary Goppa codes. Every level of the construction is designed so that future cryptographic auditors can be confident in the long-term security of post-quantum public-key encryption.
Based entirely on the C reference branch of Dilithium taken from the NIST Post Quantum Competition Round 3 submission. The NIST Post Quantum Competition Round 3 Finalists. The McEliece website. The McEliece Algorithm Specification.
Authors: Daniel J. Bernstein, Tung Chou, Tanja Lange, and Peter Schwabe. Updated: Stiepan A. Kovac - June 28 2021 Rust Translation: Matt Warminger - 2024 Updated: Matt Warminger - April 23, 2025
The primary public api for the Niederreiter dual form of the McEliece asymmetric cipher implementation:
use ;
let mut seed = ;
qrc_rcrng_generate;
let publickey = &mut vec!;
let privatekey = &mut vec!;
let secret1 = &mut ;
let secret2 = &mut ;
let ciphertext = &mut ;
qrc_mceliece_generate_keypair;
qrc_mceliece_encrypt;
qrc_mceliece_decrypt;
Signature
SphincsPlus
Based entirely on the C reference branch of SPHINCS+ taken from the NIST Post Quantum Competition Round 3 submission. The NIST Post Quantum Competition Round 3 Finalists. The SPHINCS+ website. The SPHINCS+ Algorithm Specification.
Date: June 14, 2018 Updated: February 7, 2024 Rust Translation: Matt Warminger - 2024 Updated: Matt Warminger - April 23, 2025
The primary public api for the Sphincs+ asymmetric signature scheme implementation:
use ;
let privatekey = &mut ;
let publickey = &mut ;
let hash = &mut ;
qrc_rcrng_generate;
let mut hashlen = 0;
let sig = &mut ;
let mut siglen = 0;
qrc_sphincsplus_generate_keypair;
qrc_sphincsplus_sign;
qrc_sphincsplus_verify;
Cipher
AES
Rust Translation: Matt Warminger - 2024 Updated: Matt Warminger - April 23, 2025
The primary public api for the AES implementation:
use ;
let ctx = &mut default;
let msg = &mut ;
qrc_rcrng_generate;
let plain = &mut ;
let nonce = &mut ;
qrc_rcrng_generate;
let cipher = &mut ;
let key = &mut ;
qrc_rcrng_generate;
let kp = QrcAesKeyparams ;
qrc_aes_initialize;
qrc_aes_ctrbe_transform;
qrc_aes_initialize;
qrc_aes_ctrbe_transform;
qrc_aes_dispose;
use ;
let ctx = &mut default;
let msg = &mut ;
qrc_rcrng_generate;
let plain = &mut ;
let nonce = &mut ;
qrc_rcrng_generate;
let cipher = &mut ;
let key = &mut ;
qrc_rcrng_generate;
let aad = &mut ;
qrc_rcrng_generate;
let kp = QrcAesKeyparams ;
qrc_aes_hba256_initialize;
qrc_aes_hba256_set_associated;
qrc_aes_hba256_transform;
qrc_aes_hba256_initialize;
qrc_aes_hba256_set_associated;
qrc_aes_hba256_transform;
use ;
let ctx = &mut default;
let msg = &mut ;
qrc_rcrng_generate;
let plain = &mut ;
let iv = &mut ;
qrc_rcrng_generate;
let cipher = &mut ;
let key = &mut ;
qrc_rcrng_generate;
let kp = QrcAesKeyparams ;
qrc_aes_initialize;
/* cbc api */
qrc_aes_cbc_encrypt_block;
/* ecb api */
qrc_aes_ecb_encrypt_block;
qrc_aes_initialize;
/* cbc api */
qrc_aes_cbc_decrypt_block;
/* ecb api */
qrc_aes_ecb_decrypt_block;
qrc_aes_dispose;
ChaCha
Key sizes are 128- and 256-bit (16 and 32 byte). The nonce must be 64-bits in length (8 bytes).
Author: John Underhill - April 7, 2018 Rust Translation: Matt Warminger - 2025 Updated: Matt Warminger - April 23, 2025
An implementation of the ChaChaPoly20 stream cipher by Daniel J. Bernstein.
use ;
let out = &mut ;
let msg = &mut ;
qrc_rcrng_generate;
let key = &mut ;
qrc_rcrng_generate;
let nonce = &mut ;
qrc_rcrng_generate;
let ctx = &mut default;
let kp = &mut default;
kp.key = key.to_vec;
kp.keylen = QRC_CHACHA_KEY256_SIZE;
kp.nonce = nonce.to_vec;
qrc_chacha_initialize);
qrc_chacha_transform;
qrc_chacha_dispose;
CSX
An EXPERIMENTAL vectorized, 64-bit, 40-round stream cipher CSX512 implementation based on ChaCha. This cipher uses KMAC-512 to authenticate the cipher-text stream in an encrypt-then-mac authentication configuration. The CSX (authenticated Cipher Stream, ChaCha eXtended) cipher, is a hybrid of the ChaCha stream cipher, using 64-bit integers, a 1024-bit block and a 512-bit key. \n
The pseudo-random bytes generator used by this cipher is the Keccak cSHAKE extended output function (XOF). The cSHAKE XOF is implemented in the 512-bit form of that function, and used to expand the input cipher-key into the cipher and MAC keys. CSX-512 uses a 512-bit input key, an a 16 byte nonce, and an optional tweak; the info parameter, up to 48 bytes in length.
This is a 'tweakable cipher', the initialization parameters; qrc_csx_keyparams, include an info parameter that can be used as a secondary user input. Internally, the info parameter is used to customize the cSHAKE output, using the cSHAKE 'custom' parameter to pre-initialize the SHAKE state. The info parameter can be tweaked, with a user defined string 'info' in an qrc_csx_keyparams structure passed to the csx_intitialize(state,keyparams,encrypt). This tweak can be used as a 'domain key', or to differentiate cipher-text output from other implementations, or as a secondary secret-key input.
CSX is an authenticated encryption with associated data (AEAD) stream cipher. The cSHAKE key-expansion function generates a key for the keyed hash-based MAC function; KMAC, used to generate the authentication code, which is appended to the cipher-text output of an encryption call. In decryption mode, before decryption is performed, an internal mac code is calculated, and compared to the code embedded in the cipher-text. If authentication fails, the cipher-text is not decrypted, and the qrc_csx_transform(state,out,in,inlen) function returns a boolean false value. The qrc_csx_set_associated(state,in,inlen) function can be used to add additional data to the MAC generators input, like packet-header data, or a custom code or counter.
For authentication CSX can use either the standard form of KMAC, which uses 24 rounds, or the default authentication setting; a reduced-rounds version of KMAC that uses half the number of permutation rounds KMAC-R12. To enable the standard from of KMAC, pass the QRC_RCS_AUTH_KMAC as a compiler definition, or unrem the definition in this header file. To run CSX without authentication, remove the QRC_RCS_AUTHENTICATED in this header file.
The CSX-512, known answer vectors are taken from The CEX++ Cryptographic Library <br>
See the documentation and the csx_test.h tests for usage examples.
Author: John Underhill - May 2, 2020 Updated: Stiepan A Kovac - October 13, 2021 Rust Translation: Matt Warminger - 2025 Updated: Matt Warminger - April 23, 2025
An implementation of the ChaChaPoly20 stream cipher by Daniel J. Bernstein.
use ;
let ad = &mut ;
let enc = &mut ;
let dec = &mut ;
let key = &mut ;
let msg = &mut ;
qrc_rcrng_generate;
let nce = &mut ;
qrc_rcrng_generate;
let state = &mut default;
let kp = &mut default;
kp.key = key.to_vec;
kp.keylen = QRC_CSX_KEY_SIZE;
kp.nonce = nce.to_vec;
qrc_csx_initialize;
qrc_csx_set_associated;
qrc_csx_transform;
qrc_csx_initialize;
qrc_csx_set_associated;
qrc_csx_transform;
qrc_csx_dispose;
Digest
Sha2
The SHA2 and HMAC implementations use two different forms of api: short-form and long-form. The short-form api, which initializes the state, processes a message, and finalizes by producing output, all in a single function call, for example; qrc_sha512_compute(), the entire message array is processed and the hash code is written to the output array. The long-form api uses an initialization call to prepare the state, a update call to process the message, and the finalize call, which finalizes the state and generates a hash or mac-code. The HKDF key derivation functions HKDF(HMAC(SHA2-256/512)), use only the short-form api, single-call functions, to generate pseudo-random to an output array. Each of the function families (SHA2, HMAC, HKDF), have a corresponding set of reference constants associated with that member, example; QRC_HKDF_256_KEY_SIZE is the minimum expected HKDF-256 key size in bytes, QRC_HMAC_512_MAC_SIZE is the minimum size of the HMAC-512 output mac-code output array.
NIST: The SHA-2 Standard Analysis of SIMD Applicability to SHA Algorithms
Author: John Underhill - May 23, 2019 Updated: Stiepan A Kovac - Jul 11, 2024 Rust Translation: Matt Warminger - 2024 Updated: Matt Warminger - April 23, 2025
The primary public api for SHA2 Implementation:
use ;
let hash = &mut ;
let info = &mut ;
qrc_rcrng_generate;
let key = &mut ;
qrc_rcrng_generate;
/* compact api */
qrc_hkdf512_expand;
use ;
let hash = &mut ;
let msg = &mut ;
qrc_rcrng_generate;
let key = &mut ;
qrc_rcrng_generate;
/* compact api */
qrc_hmac512_compute;
/* test long-form api */
let ctx = &mut default;
qrc_hmac512_initialize;
qrc_hmac512_blockfinalize;
use ;
let hash = &mut ;
let msg = &mut ;
qrc_rcrng_generate;
/* compact api */
qrc_sha512_compute;
/* long-form api */
let ctx = &mut default;
qrc_sha512_initialize;
qrc_sha512_update;
qrc_sha512_finalize;
Sha3
The SHA3, SHAKE, cSHAKE, and KMAC implementations all share two forms of api: short-form and long-form. The short-form api, which initializes the state, processes a message, and finalizes by producing output, all in a single function call, for example; qrc_sha3_compute512(), the entire message array is processed and the hash code is written to the output array. The long-form api uses an initialization call to prepare the state, a blockupdate call if the message is longer than a single message block, and the finalize call, which finalizes the state and generates a hash, mac-code, or an array of pseudo-random. Each of the function families (SHA3, SHAKE, KMAC), have a corresponding set of reference constants associated with that member, example; SHAKE_256_KEY is the minimum expected SHAKE-256 key size in bytes, QRC_KMAC_512_MAC_SIZE is the minimum size of the KMAC-512 output mac-code output array, and QRC_KECCAK_512_RATE is the SHA3-512 message absorption rate.
NIST: SHA3 Fips202 NIST: SP800-185 NIST: SHA3 Keccak Submission NIST: SHA3 Keccak Slides NIST: SHA3 Third-Round Report Team Keccak: Specifications summary
Author: John Underhill - October 27, 2019 Updated: Stiepan A Kovac - 19, 2021 Rust Translation: Matt Warminger - 2024 Updated: Matt Warminger - April 23, 2025
The primary public api for SHA3 digest, SHAKE, cSHAKE, and KMAC implementation:
use ;
let hash = &mut ;
let msg = &mut ;
qrc_rcrng_generate;
/* compact api */
qrc_sha3_compute512;
/* long-form api */
let ctx = &mut default;
qrc_sha3_initialize;
qrc_sha3_update;
qrc_sha3_finalize;
qrc_keccak_dispose;
use ;
let hash = &mut ;
let msg = &mut ;
qrc_rcrng_generate;
let key = &mut ;
qrc_rcrng_generate;
let cust = &mut ;
qrc_rcrng_generate;
/* compact api */
qrc_kmac512_compute;
/* long-form api */
let ctx = &mut default;
qrc_kmac_initialize;
qrc_kmac_update;
qrc_kmac_finalize;
qrc_keccak_dispose;
use ;
let hash = &mut ;
let msg = &mut ;
qrc_rcrng_generate;
let cust = &mut ;
qrc_rcrng_generate;
/* compact api */
qrc_cshake512_compute;
/* long-form api */
let ctx = &mut default;
qrc_cshake_initialize;
qrc_cshake_squeezeblocks;
qrc_keccak_dispose;
use ;
let hash = &mut ;
let msg = &mut ;
qrc_rcrng_generate;
/* compact api */
qrc_shake512_compute;
/* long-form api */
let ctx = &mut default;
qrc_shake_initialize;
qrc_shake_squeezeblocks;
qrc_keccak_dispose;
use ;
let hash = &mut ;
let msg = &mut ;
qrc_rcrng_generate;
let key = &mut ;
qrc_rcrng_generate;
let cust = &mut ;
qrc_rcrng_generate;
/* long-form api */
let ctx = &mut default;
qrc_kpa_initialize;
qrc_kpa_update;
qrc_kpa_finalize;
DRGB
CSG
CSG uses the Keccak cSHAKE XOF function to produce pseudo-random bytes from a seeded custom SHAKE generator. If a 32-byte key is used, the implementation uses the cSHAKE-256 implementation for pseudo-random generation, if a 64-byte key is used, the generator uses cSHAKE-512. An optional predictive resistance feature, enabled through the initialize function, injects random bytes into the generator at initialization and 1MB intervals, creating a non-deterministic pseudo-random output. Pseudo random bytes are cached internally, and the generator can be initialized and then reused without requiring re-initialization in an online configuration. The generator can be updated with new seed material, which is absorbed into the Keccak state.
NIST: SHA3 Fips202 NIST: SP800-185 NIST: SHA3 Keccak Submission NIST: SHA3 Keccak Slides NIST: SHA3 Third-Round Report Team Keccak: Specifications summary
Rust Translation: Matt Warminger - 2025 Updated: Matt Warminger - April 23, 2025
CSG pseudo-random bytes generator:
use ;
let seed = &mut ;
qrc_rcrng_generate;
let add = &mut ;
qrc_rcrng_generate;
let out = &mut ;
let ctx = &mut default;
qrc_csg_initialize;
qrc_csg_update;
qrc_csg_generate;
qrc_csg_dispose;
HCG
HCG has a similar configuration to the HKDF Expand pseudo-random generator, but with a 128-bit nonce, and a default info parameter.
The HKDF Scheme: Cryptographic Extraction and Key Derivation RFC 2104 HMAC: Keyed-Hashing for Message Authentication Fips 198-1: The Keyed-Hash Message Authentication Code (HMAC) Fips 180-4: Secure Hash Standard (SHS)
Author: John Underhill - August 31, 2020 Rust Translation: Matt Warminger - 2025 Updated: Matt Warminger - April 23, 2025
HCG pseudo-random bytes generator:
use ;
let seed = &mut ;
qrc_rcrng_generate;
let add = &mut ;
qrc_rcrng_generate;
let out = &mut ;
let ctx = &mut default;
qrc_hcg_initialize;
qrc_hcg_update;
qrc_hcg_generate;
qrc_hcg_dispose;
SCB
CSG uses the Keccak cSHAKE XOF function to produce pseudo-random bytes from a seeded custom SHAKE generator. If a 32-byte key is used, the implementation uses the cSHAKE-256 implementation for pseudo-random generation, if a 64-byte key is used, the generator uses cSHAKE-512. The CPU cost feature is an iteration count in the cost mechanism, it determines the number of times both the state absorption and memory expansion functions execute. The Memory cost, is the maximum number of megabytes the internal cache is expanded to, during execution of the cost mechanism. The maximum values of Memory and CPU cost should be determined based on the estimated capability of an adversary, if set too high, the application will become unsuable, if set too low, it may fall within their computational capabilities. The recommended low-threshold parameters are c:500, m:100. The generator can be updated with new seed material, which is absorbed into the Keccak state.
NIST: SHA3 Fips202 NIST: SP800-185 NIST: SHA3 Keccak Submission NIST: SHA3 Keccak Slides NIST: SHA3 Third-Round Report Team Keccak: Specifications summary
Rust Translation: Matt Warminger - 2025 Updated: Matt Warminger - April 23, 2025
An implementation of the SHAKE Cost Based SCB key derivation function:
use ;
let seed = &mut ;
qrc_rcrng_generate;
let add = &mut ;
qrc_rcrng_generate;
let out = &mut ;
let ctx = &mut default;
qrc_scb_initialize;
qrc_scb_generate;
qrc_scb_dispose;
Mac
Poly1305
Rust Translation: Matt Warminger - 2024 Updated: Matt Warminger - April 23, 2025
The primary public api for the Poly1305 implementation:
use ;
let key = &mut ;
qrc_rcrng_generate;
let mac = &mut ;
let msg = &mut ;
qrc_rcrng_generate;
/* compact api */
qrc_poly1305_compute;
/* long-form api */
let ctx = &mut default;
qrc_poly1305_initialize;
qrc_poly1305_update;
qrc_poly1305_finalize;
Numerics
Donna128
Rust Translation: Matt Warminger - 2025 Updated: Matt Warminger - April 23, 2025
The primary public api for the Donna128 implementation:
use ;
let mut out = ;
let mut x = default;
qrc_rcrng_generate;
x.high = u64from_le_bytes;
qrc_rcrng_generate;
x.low = u64from_le_bytes;
x = qrc_donna128_shift_right;
x = qrc_donna128_shift_left;
use ;
let mut out = ;
let mut x = default;
qrc_rcrng_generate;
x.high = u64from_le_bytes;
qrc_rcrng_generate;
x.low = u64from_le_bytes;
qrc_rcrng_generate;
let y = qrc_donna128_andl;
let mut out = ;
let mut x = default;
qrc_rcrng_generate;
x.high = u64from_le_bytes;
qrc_rcrng_generate;
x.low = u64from_le_bytes;
qrc_rcrng_generate;
let y = qrc_donna128_andh;
use ;
let mut out = ;
let mut x = default;
qrc_rcrng_generate;
x.high = u64from_le_bytes;
qrc_rcrng_generate;
x.low = u64from_le_bytes;
qrc_rcrng_generate;
x = qrc_donna128_multiply;
use ;
let mut out = ;
let mut x = default;
let mut y = default;
qrc_rcrng_generate;
x.high = u64from_le_bytes;
qrc_rcrng_generate;
x.low = u64from_le_bytes;
qrc_rcrng_generate;
y.high = u64from_le_bytes;
qrc_rcrng_generate;
y.low = u64from_le_bytes;
qrc_rcrng_generate;
x = qrc_donna128_add;
use ;
let mut out = ;
let mut x = default;
let mut y = default;
qrc_rcrng_generate;
x.high = u64from_le_bytes;
qrc_rcrng_generate;
x.low = u64from_le_bytes;
qrc_rcrng_generate;
y.high = u64from_le_bytes;
qrc_rcrng_generate;
y.low = u64from_le_bytes;
qrc_rcrng_generate;
x = qrc_donna128_or;
PRNG
SecRand
Rust Translation: Matt Warminger - 2024 Updated: Matt Warminger - April 23, 2025
implementation of an secure pseudo-random generator:
use ;
let seed= &mut ;
qrc_rcrng_generate;
let out = &mut ;
let secrand_state = &mut default;
qrc_secrand_initialize;
qrc_secrand_generate;
qrc_secrand_destroy;
use ;
let seed = &mut ;
qrc_rcrng_generate;
let out = &mut ;
let asymmetric_state = &mut default;
qrc_secrand_initialize;
qrc_asymmetric_secrand_generate;
qrc_secrand_destroy;
NistRng
Rust Translation: Matt Warminger - 2025 Updated: Matt Warminger - April 23, 2025
use ;
let seed: &mut = &mut ;
qrc_rcrng_generate;
let out = &mut ;
let nistrng_state = &mut default;
qrc_nistrng_prng_initialize;
qrc_nistrng_prng_generate;
use ;
let seed: &mut = &mut ;
qrc_rcrng_generate;
let out = &mut ;
let asymmetric_state = &mut default;
qrc_nistrng_prng_initialize;
qrc_asymmetric_nistrng_generate;
Provider
RcRng
Rust Translation: Matt Warminger - 2024 Updated: Matt Warminger - April 23, 2025
Resource RNG:
use qrc_rcrng_generate;
let out = &mut ;
qrc_rcrng_generate;
OsRng
Rust Translation: Matt Warminger - 2024 Updated: Matt Warminger - April 23, 2025
OSRing RNG:
use qrc_osrng_generate;
let out = &mut ;
qrc_osrng_generate;
TrRng
Rust Translation: Matt Warminger - 2024 Updated: Matt Warminger - April 23, 2025
Thread RNG:
use qrc_trrng_generate;
let out = &mut ;
qrc_trrng_generate;
Roadmap
NOTE The package is under active development. As such, it is likely to remain volatile until a 1.0.0 release.
Todo:
License
The contents of this repository are licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3. See LICENSE for more information on the license.