qcrypto cross-platform Rust library designed for the design, simulation, and validation of Quantum Cryptography protocols.
Unlike general-purpose quantum simulators that focus on state-vector evolution for logical circuits, qcrypto is architected around Density Matrices and Kraus Operators. This design choice enables the precise simulation of open quantum systems, decoherence, noisy channels, and generalized measurements (POVMs), which are critical for validating the physical security of cryptographic protocols.
The library is implemented in 100% Safe Rust, eliminating external dependencies.
- Density Matrix Formalism: Native support for mixed states, enabling the simulation of statistical ensembles and entanglement degradation.
- Open Quantum Systems: Implementation of quantum channels (Bit Flip, Phase Damping, Amplitude Damping, Depolarizing) satisfying the Trace-Preserving condition.
- Generalized Measurements: Support for Positive Operator-Valued Measures (POVM), essential for protocols like B92 and unambiguous state discrimination.
- Efficient Operator Expansion: Native implementation of optimized algorithms to extend single-qubit operator matrices to multi-qubit composite systems.
- Reproducible Simulations: A Thread-Local RNG system (
qcrypto::rng) allows researchers to lock simulations to deterministic entropy sequences to exactly replicate experimental protocol runs.
To use qcrypto in your Rust project, you can easily add it via Cargo.
Run the following command in your project directory:
cargo add qcryptoqcrypto is built upon a mathematically rigorous foundation, avoiding common simplifications found in other simulators. The core components are designed to handle open quantum systems and mixed states natively.
QuantumState: Represents the state of the system using Density Matrices. Unlike state-vector simulators, this allows for the accurate representation of mixed states, statistical ensembles, and decoherence effects.QuantumChannel: Models physical noise and decoherence (e.g., Bit Flip, Phase Damping, Amplitude Damping) using Kraus Operators. It ensures the evolution is Trace-Preserving by verifying.Measurement: A generalized measurement framework supporting both standard Projective Measurements and Positive Operator-Valued Measures (POVM). This is crucial for implementing optimal discrimination strategies and ambiguous state detection.Gate: Provides standard unitary operations and allows for the definition of custom single and multi-qubit unitaries.Sampler: Permits to run multiple shots of measurements using aMeasurementandQuantumChannel.
The library includes reference implementations for standard and novel quantum cryptographic schemes.
The standard protocol for Quantum Key Distribution. The implementation supports:
- Intercept-Resend attacks.
- Real-time QBER (Quantum Bit Error Rate) estimation.
- Sifting and error reconciliation simulation.
An implementation of B92 utilizing generalized measurements for Unambiguous State Discrimination.
- Mechanism: Constructs the optimal POVM such that inconclusive results are explicitly handled.
- Yield: Achieves the optimal theoretical sifting rate (approx. 29.3% for standard non-orthogonal states), strictly outperforming standard projective measurements in a noiseless channel.
A reference implementation of the protocol described in "Conjugate Coding Based Designated Verifier Quantum Zero Knowledge Proof for User Authentication".
This protocol establishes a Quantum Zero-Knowledge Proof (QZKP) for identity authentication without revealing the prover's secret key.
- Security Model: Relies on the uncertainty principle of conjugate coding (Computational vs. Hadamard bases).
- Properties:
- Completeness: Honest provers are accepted with probability approaching 1 (adjusted for channel noise models).
- Soundness: The probability of a dishonest prover successfully impersonating an identity follows a binomial distribution , decaying exponentially with key length .
- Zero-Knowledge: The designated verifier gains no information about the long-term secret due to the ephemeral masking .
use qcrypto::{QuantumState, Gate, Measurement, QuantumChannel, errors::*};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 1. Initialize a pure qubit state |0><0|
let mut rho = QuantumState::new(1);
// 2. Apply Hadamard Gate -> |+><+|
rho.apply(&Gate::h(), &[0])?;
// 3. Evolve through an Amplitude Damping Channel (gamma = 0.3)
// This transforms the pure state into a mixed state.
let channel = QuantumChannel::amplitude_damping(0.3)?;
rho.apply_channel(&channel, &[0])?;
println!("State Purity (Tr(rho^2)): {:.4}", rho.purity());
// Purity will be < 1.0 due to the non-unitary channel evolution.
// 4. Measure in the Z basis
let measurement = Measurement::z_basis();
let outcome = rho.measure(&measurement, &[0])?;
println!("Measurement Outcome: {}", outcome.index);
println!("State Purity (Tr(rho^2)): {:.4}", rho.purity());
// Purity will be 1 because it has been proyected to a pure state
Ok(())
}use qcrypto::protocols::qia_qzkp;
use qcrypto::{QuantumChannel, errors::*};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let n_qubits = 1024;
let threshold = 0.85; // Acceptance threshold based on expected QBER
// Simulate a realistic channel with 5% noise
let noisy_channel = QuantumChannel::bit_flip(0.05)?;
let result = qia_qzkp::run(n_qubits, &noisy_channel, threshold)?;
println!("Protocol Accuracy: {:.2}%", result.accuracy * 100.0);
println!("Authenticated: {}", result.authenticated);
Ok(())
}For testing and research, it is often critical to perfectly reproduce a specific run of a protocol (yielding identical keys and error distributions). qcrypto provides a high-performance Thread-Local Deterministic RNG that does not require you to pass RNG instances to every function.
use qcrypto::protocols::qkd::bbm92;
use qcrypto::{QuantumChannel, rng::set_global_seed};
fn main() {
let channel = QuantumChannel::depolarizing(0.1)?;
// Lock the RNG for this thread to a specific seed
set_global_seed(42);
// Every call to bbm92::run or QuantumState::measure on this thread
// will now be 100% deterministic and reproducible.
let result = bbm92::run(1000, &channel, 0.1, 0.2)?;
// Running this program tomorrow will yield the exact same QBER and key.
println!("Deterministically reproducible QBER: {:.2}%", result.qber);
}For statistical analysis, it is often necessary to run a protocol multiple times across different parameters (e.g., varying noise levels) and store the results.
use qcrypto::protocols::qkd::bb84;
use qcrypto::{QuantumChannel, errors::*};
use std::fs::File;
use std::io::Write;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let num_qubits = 1000;
let eve_ratio = 0.0;
let check_ratio = 0.2;
let num_executions = 50;
let noise_levels = [0.0, 0.05, 0.10, 0.15];
// Create a CSV file for output
let mut file = File::create("bb84_results.csv")?;
writeln!(file, "Noise,Execution,QBER,EstablishedKeyLength")?;
// Iterate over different noise configurations
for &noise in &noise_levels {
let channel = QuantumChannel::depolarizing(noise)?;
// Run the protocol multiple times for each configuration
for execution in 1..=num_executions {
let result = bb84::run(num_qubits, &channel, eve_ratio, check_ratio)?;
// Write the extracted data to the CSV
writeln!(
file,
"{:.2},{},{:.2},{}",
noise, execution, result.qber, result.established_key.len()
)?;
}
}
println!("Simulation complete. Data saved to bb84_results.csv");
Ok(())
}If you use this software in your research or project, please cite it using the information in CITATION. Additionally, if you use the QIA-QZKP module in your research, please cite the original paper:
Garcia-Diaz, J., Escanez-Exposito, D., Caballero-Gil, P., & Molina-Gil, J. (2025). Conjugate Coding Based Designated Verifier Quantum Zero Knowledge Proof for User Authentication.
This project is licensed under the MIT License. See the LICENSE file for details.
Contributions are welcome! Please open an issue or submit a pull request on GitHub.