Rivide is a high-performance, zero-dependency, constant-time C99 Post-Quantum Cryptography (PQC) library. It implements the official NIST FIPS 203 (ML-KEM) and NIST FIPS 204 (ML-DSA) standards, engineered specifically for embedded systems, network security protocols, operating system kernels, and security-critical applications.
- NIST Post-Quantum Standards:
- ML-KEM (FIPS 203): Module-Lattice-Based Key Encapsulation Mechanism (ML-KEM-768 and ML-KEM-1024).
- ML-DSA (FIPS 204): Module-Lattice-Based Digital Signature Algorithm (ML-DSA-65 and ML-DSA-87).
- ISO C99 Standard Compliance: Written in clean, portable C99 (
-std=c99 -Wall -Wextra -Wpedantic -Werror). - Zero Dynamic Memory Allocation (0 Malloc): Never invokes
mallocor heap allocation. All buffers are fixed-size and caller-allocated on the stack. - Constant-Time Side-Channel Protection: Features constant-time comparisons (
rivide_ct_memcmp) and conditional selections (rivide_ct_select) to prevent timing side-channel attacks. - Secure Memory Cleansing: Prevents compiler dead-store elimination via volatile barriers (
rivide_cleanse) to guarantee zeroization of sensitive private keys in RAM. - Multi-Platform OS CSPRNG Engine: Queries kernel entropy sources natively (
getrandomon Linux,getentropyon macOS/BSD,BCryptGenRandomon Windows). - Built-in Symmetric Primitives: Autonomous implementations of Keccak-f[1600] (SHA3-256/512, SHAKE-128/256) and AES-128/256-GCM AEAD.
- Node.js Native Bindings: Zero-dependency, high-performance Node-API (N-API) bindings and npm package (
rivide) with full TypeScript definitions.
- Installation & Quick Start
- Code Tutorials & Usage Examples
- Node.js / JavaScript / TypeScript Bindings Quick Start
- Rust Native Bindings Quick Start
- Parameter & Specification Summary
- Master Makefile Command Automation
- Documentation Map
- License & Maintainers
Install build dependencies (GCC/Clang, CMake, Make):
# Ubuntu / Debian
sudo apt-get install -y build-essential cmake ctest clang-format clang-tidy
# Arch Linux / Manjaro
sudo pacman -S base-devel cmake clang
# macOS (Homebrew)
brew install cmake clang-formatOn Windows, install CMake and use the Visual Studio Developer Command Prompt.
Clone the repository and build using the master Makefile:
# Clone the repository
git clone https://github.com/mrvlous/rivide.git
cd rivide
# Compile static/shared libraries, test suite, KAT, and examples
make build
# Run automated unit test suite
make test
# Execute official NIST Known Answer Test (KAT) validation suite
make kat
# Execute demonstration applications
make run-examples
# Run performance benchmarks
make benchInstall static library archives and header files to system locations (e.g. /usr/local):
sudo make installInclude the unified master header in your C application:
#include "rivide/rivide.h"This example demonstrates post-quantum key exchange between Alice and Bob:
#include <stdio.h>
#include "rivide/rivide.h"
int main(void) {
rivide_status_t status;
/* 1. Initialize Rivide cryptographic library */
status = rivide_init();
if (status != RIVIDE_SUCCESS) {
fprintf(stderr, "Rivide initialization failed\n");
return 1;
}
/* 2. Allocate fixed-size key buffers (Zero Heap Allocation) */
uint8_t alice_pk[RIVIDE_ML_KEM_768_PK_BYTES];
uint8_t alice_sk[RIVIDE_ML_KEM_768_SK_BYTES];
uint8_t ciphertext[RIVIDE_ML_KEM_768_CT_BYTES];
uint8_t bob_shared_secret[RIVIDE_ML_KEM_768_SS_BYTES];
uint8_t alice_shared_secret[RIVIDE_ML_KEM_768_SS_BYTES];
/* 3. [Alice] Generate ML-KEM-768 keypair */
printf("[Alice] Generating ML-KEM-768 key pair...\n");
status = rivide_ml_kem_768_keygen(alice_pk, alice_sk);
if (status != RIVIDE_SUCCESS) return 1;
/* 4. [Bob] Encapsulate shared secret under Alice's public key */
printf("[Bob] Encapsulating shared secret...\n");
status = rivide_ml_kem_768_encaps(ciphertext, bob_shared_secret, alice_pk);
if (status != RIVIDE_SUCCESS) return 1;
/* 5. [Alice] Decapsulate ciphertext using her secret key */
printf("[Alice] Decapsulating shared secret...\n");
status = rivide_ml_kem_768_decaps(alice_shared_secret, ciphertext, alice_sk);
if (status != RIVIDE_SUCCESS) return 1;
/* 6. Verify matching shared secret (32 bytes) */
if (rivide_ct_memcmp(alice_shared_secret, bob_shared_secret, RIVIDE_ML_KEM_768_SS_BYTES) == 0) {
printf("SUCCESS: Shared secrets match! Quantum-safe key exchange complete.\n");
} else {
printf("ERROR: Shared secret mismatch!\n");
return 1;
}
/* 7. Securely cleanse private keys in RAM */
rivide_cleanse(alice_sk, sizeof(alice_sk));
return 0;
}Compile with: gcc -O3 main.c -lrivide -o kem_app
This example demonstrates signing and verifying messages using ML-DSA-65:
#include <stdio.h>
#include <string.h>
#include "rivide/rivide.h"
int main(void) {
rivide_status_t status;
/* 1. Initialize library */
rivide_init();
/* 2. Allocate fixed-size key and signature buffers */
uint8_t pk[RIVIDE_ML_DSA_65_PK_BYTES];
uint8_t sk[RIVIDE_ML_DSA_65_SK_BYTES];
uint8_t signature[RIVIDE_ML_DSA_65_SIG_BYTES];
size_t siglen = sizeof(signature);
const char *message = "Post-Quantum signed payload using Rivide library.";
size_t msglen = strlen(message);
/* 3. Generate ML-DSA-65 keypair */
printf("[Signer] Generating ML-DSA-65 key pair...\n");
status = rivide_ml_dsa_65_keygen(pk, sk);
if (status != RIVIDE_SUCCESS) return 1;
/* 4. Sign message */
printf("[Signer] Signing message...\n");
status = rivide_ml_dsa_65_sign(signature, &siglen, (const uint8_t *)message, msglen, sk);
if (status != RIVIDE_SUCCESS) return 1;
/* 5. Verify signature */
printf("[Verifier] Verifying signature...\n");
status = rivide_ml_dsa_65_verify(signature, siglen, (const uint8_t *)message, msglen, pk);
if (status == RIVIDE_SUCCESS) {
printf("SUCCESS: Signature is VALID!\n");
} else {
printf("ERROR: Signature verification failed!\n");
return 1;
}
/* 6. Securely wipe secret key */
rivide_cleanse(sk, sizeof(sk));
return 0;
}Compile with: gcc -O3 main.c -lrivide -o dsa_app
Rivide provides official native Node-API bindings for JavaScript and TypeScript developers via the rivide package:
# npm
npm install rivide
# pnpm
pnpm add rivide
# yarn
yarn add rivideimport { mlKem768, mlDsa65, utils } from 'rivide';
// ML-KEM-768 Key Exchange
const alice = mlKem768.keypair();
const bob = mlKem768.encaps(alice.publicKey);
const sharedSecret = mlKem768.decaps(bob.ciphertext, alice.secretKey);
// ML-DSA-65 Digital Signature
const signer = mlDsa65.keypair();
const signature = mlDsa65.sign('Quantum-Safe Contract', signer.secretKey);
const isValid = mlDsa65.verify(signature, 'Quantum-Safe Contract', signer.publicKey);
// Secure RAM Cleanup
utils.cleanse(alice.secretKey);
utils.cleanse(signer.secretKey);For full documentation and TypeScript usage, refer to the Node.js Bindings Guide.
Rivide provides official idiomatic Rust bindings via the rivide crate:
cargo add rivideuse rivide::kem::MlKem768;
use rivide::dsa::MlDsa65;
// ML-KEM-768 Key Exchange
let alice = MlKem768::keypair().expect("KeyGen failed");
let bob = MlKem768::encapsulate(&alice.public_key).expect("Encaps failed");
let shared_secret = MlKem768::decapsulate(&bob.ciphertext, &alice.secret_key).expect("Decaps failed");
assert_eq!(shared_secret, bob.shared_secret);
// ML-DSA-65 Digital Signature
let signer = MlDsa65::keypair().expect("KeyGen failed");
let signature = MlDsa65::sign(b"Quantum-Safe Transaction", &signer.secret_key).expect("Sign failed");
let is_valid = MlDsa65::verify(&signature, b"Quantum-Safe Transaction", &signer.public_key);
assert!(is_valid);For full documentation, refer to the Rust Bindings Guide.
| Algorithm | Standard | Public Key | Secret Key | Ciphertext / Signature | Shared Key / Security |
|---|---|---|---|---|---|
| ML-KEM-768 | NIST FIPS 203 | 1184 bytes |
2400 bytes |
1088 bytes |
32 bytes (Category 3 / AES-192) |
| ML-KEM-1024 | NIST FIPS 203 | 1568 bytes |
3168 bytes |
1568 bytes |
32 bytes (Category 5 / AES-256) |
| ML-DSA-65 | NIST FIPS 204 | 1952 bytes |
4032 bytes |
3309 bytes |
Category 3 / AES-192 equivalent |
| ML-DSA-87 | NIST FIPS 204 | 2592 bytes |
4896 bytes |
4627 bytes |
Category 5 / AES-256 equivalent |
The master Makefile provides simple automation targets:
| Command | Action |
|---|---|
make build |
Compile static library librivide.a, shared library, tests, KAT, and examples |
make test |
Run automated unit test suite using CTest |
make kat |
Execute official NIST Known Answer Test (KAT) validation suite |
make timing |
Execute Dudect constant-time statistical timing leakage verification |
make bench |
Compile and execute dedicated PQC performance benchmark subsystem |
make run-examples |
Build and execute demonstration applications sequentially |
make fuzz CC=clang |
Compile LLVM libFuzzer fuzzing targets with AddressSanitizer |
make node-build |
Compile Node-API native bindings addon using node-gyp |
make node-test |
Run automated Node.js test suite across all PQC primitives |
make node-bench |
Execute Node.js performance benchmarking suite |
make node-publish |
Publish Node.js native addon package to npm registry |
make rust-build |
Compile Rust native bindings crate using Cargo |
make rust-test |
Run automated Rust integration test suite and doc-tests |
make rust-examples |
Execute Rust demonstration examples |
make rust-bench |
Execute high-precision Rust performance benchmark suite |
make rust-pack |
Package and verify Rust crate tarball for crates.io |
make rust-publish |
Publish Rust crate to crates.io with bundled C source |
make format |
Auto-format all C/H files using .clang-format |
make check-format |
Verify code formatting against .clang-format rules |
make lint |
Run static code analysis using clang-tidy |
make check |
Check system environment for required dependencies |
make clean |
Delete build outputs and temporary artifacts |
For detailed architectural, algorithmic, and API documentation, refer to the docs/ portal:
- Master Documentation Portal
- Getting Started:
- Algorithms & Standards:
- Architecture & Design:
- Security & Hardening:
- Cross-Language API References:
- Performance Benchmarks:
- Testing & Verification:
- Real-World Integration Blueprints:
- Contribution Guidelines:
This project is licensed under the MIT License - see the LICENSE file for details.
- Author & Maintainer: Moh. Ananda Firmansyah Putra (@mrvlous)
- Maintainers Roster: MAINTAINERS
- Contributors & Credits: CREDITS