use crate::{Result, QsshError};
use rand::{thread_rng, Rng, RngCore};
use std::collections::HashMap;
pub struct BB84Protocol {
error_threshold: f64,
min_key_length: usize,
}
impl BB84Protocol {
pub fn new() -> Self {
Self {
error_threshold: 0.11,
min_key_length: 256, }
}
pub fn prepare_qubits(&self, num_bits: usize) -> (Vec<bool>, Vec<bool>, Vec<bool>) {
let mut rng = thread_rng();
let alice_bits: Vec<bool> = (0..num_bits).map(|_| rng.gen()).collect();
let alice_bases: Vec<bool> = (0..num_bits).map(|_| rng.gen()).collect();
let qubits = alice_bits.clone();
(alice_bits, alice_bases, qubits)
}
pub fn measure_qubits(
&self,
qubits: &[bool],
alice_bases: &[bool],
) -> (Vec<bool>, Vec<bool>) {
let mut rng = thread_rng();
let bob_bases: Vec<bool> = (0..qubits.len()).map(|_| rng.gen()).collect();
let mut bob_bits = Vec::new();
for i in 0..qubits.len() {
if alice_bases[i] == bob_bases[i] {
bob_bits.push(qubits[i]);
} else {
bob_bits.push(rng.gen());
}
}
(bob_bits, bob_bases)
}
pub fn sift_keys(
&self,
alice_bits: &[bool],
alice_bases: &[bool],
bob_bits: &[bool],
bob_bases: &[bool],
) -> (Vec<bool>, Vec<bool>) {
let mut alice_sifted = Vec::new();
let mut bob_sifted = Vec::new();
for i in 0..alice_bits.len() {
if alice_bases[i] == bob_bases[i] {
alice_sifted.push(alice_bits[i]);
bob_sifted.push(bob_bits[i]);
}
}
(alice_sifted, bob_sifted)
}
pub fn estimate_error_rate(
&self,
alice_key: &[bool],
bob_key: &[bool],
sample_size: usize,
) -> Result<f64> {
if alice_key.len() < sample_size {
return Err(QsshError::Qkd("Insufficient key length for error estimation".into()));
}
let mut errors = 0;
for i in 0..sample_size {
if alice_key[i] != bob_key[i] {
errors += 1;
}
}
Ok(errors as f64 / sample_size as f64)
}
pub fn privacy_amplification(
&self,
key: Vec<bool>,
error_rate: f64,
) -> Vec<u8> {
let reduction_factor = 1.0 - error_rate * 2.0;
let final_length = ((key.len() as f64) * reduction_factor) as usize;
let mut result = Vec::new();
for chunk in key[..final_length].chunks(8) {
let mut byte = 0u8;
for (i, &bit) in chunk.iter().enumerate() {
if bit {
byte |= 1 << i;
}
}
result.push(byte);
}
result
}
pub async fn generate_key(&self, target_bits: usize) -> Result<Vec<u8>> {
let raw_bits = target_bits * 4;
let (alice_bits, alice_bases, qubits) = self.prepare_qubits(raw_bits);
let (bob_bits, bob_bases) = self.measure_qubits(&qubits, &alice_bases);
let (alice_sifted, bob_sifted) = self.sift_keys(
&alice_bits,
&alice_bases,
&bob_bits,
&bob_bases,
);
if alice_sifted.len() < self.min_key_length {
return Err(QsshError::Qkd("Insufficient sifted key length".into()));
}
let sample_size = alice_sifted.len() / 10;
let error_rate = self.estimate_error_rate(&alice_sifted, &bob_sifted, sample_size)?;
if error_rate > self.error_threshold {
return Err(QsshError::Qkd(format!(
"Error rate {} exceeds threshold {}",
error_rate, self.error_threshold
)));
}
let final_key = self.privacy_amplification(
alice_sifted[sample_size..].to_vec(),
error_rate,
);
if final_key.len() < target_bits / 8 {
return Err(QsshError::Qkd("Insufficient final key length".into()));
}
Ok(final_key[..target_bits / 8].to_vec())
}
}
pub struct E91Protocol {
error_threshold: f64,
}
impl E91Protocol {
pub fn new() -> Self {
Self {
error_threshold: 0.15, }
}
pub fn generate_entangled_pairs(&self, num_pairs: usize) -> (Vec<f64>, Vec<f64>) {
let mut rng = thread_rng();
let alice_angles: Vec<f64> = (0..num_pairs)
.map(|_| rng.gen::<f64>() * std::f64::consts::PI)
.collect();
let bob_angles = alice_angles.clone();
(alice_angles, bob_angles)
}
pub fn verify_bell_inequality(&self, measurements: &[(f64, f64)]) -> bool {
let correlation: f64 = measurements.iter()
.map(|(a, b)| (a - b).cos())
.sum::<f64>() / measurements.len() as f64;
correlation.abs() > 0.7071 }
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_bb84_key_generation() {
let protocol = BB84Protocol::new();
let key = protocol.generate_key(256).await;
assert!(key.is_ok());
let key = key.unwrap();
assert_eq!(key.len(), 32); }
#[test]
fn test_bb84_sifting() {
let protocol = BB84Protocol::new();
let alice_bits = vec![true, false, true, false];
let alice_bases = vec![true, true, false, false];
let bob_bits = vec![true, true, false, false];
let bob_bases = vec![true, false, false, true];
let (alice_sifted, bob_sifted) = protocol.sift_keys(
&alice_bits,
&alice_bases,
&bob_bits,
&bob_bases,
);
assert_eq!(alice_sifted.len(), 2);
assert_eq!(bob_sifted.len(), 2);
}
#[test]
fn test_e91_bell_verification() {
let protocol = E91Protocol::new();
let measurements = vec![
(0.0, 0.0),
(1.57, 1.57),
(0.785, 0.785),
];
assert!(protocol.verify_bell_inequality(&measurements));
}
}