1use crate::error::{MLError, Result};
8use quantrs2_circuit::prelude::Circuit;
9use quantrs2_sim::statevector::StateVectorSimulator;
10use scirs2_core::ndarray::{Array1, Array2};
11use scirs2_core::random::prelude::*;
12use std::collections::HashMap;
13use std::fmt;
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
17pub enum ProtocolType {
18 BB84,
20
21 E91,
23
24 B92,
26
27 BBM92,
29
30 SARG04,
32}
33
34#[derive(Debug, Clone)]
36pub struct Party {
37 pub name: String,
39
40 pub key: Option<Vec<u8>>,
42
43 pub bases: Option<Vec<usize>>,
45
46 pub state: Option<Vec<f64>>,
48}
49
50#[derive(Debug, Clone)]
52pub struct QuantumKeyDistribution {
53 pub protocol: ProtocolType,
55
56 pub num_qubits: usize,
58
59 pub alice: Party,
61
62 pub bob: Party,
64
65 pub error_rate: f64,
67
68 pub security_bits: usize,
70}
71
72impl QuantumKeyDistribution {
73 pub fn new(protocol: ProtocolType, num_qubits: usize) -> Self {
75 QuantumKeyDistribution {
76 protocol,
77 num_qubits,
78 alice: Party {
79 name: "Alice".to_string(),
80 key: None,
81 bases: None,
82 state: None,
83 },
84 bob: Party {
85 name: "Bob".to_string(),
86 key: None,
87 bases: None,
88 state: None,
89 },
90 error_rate: 0.0,
91 security_bits: num_qubits / 10,
92 }
93 }
94
95 pub fn with_error_rate(mut self, error_rate: f64) -> Self {
97 self.error_rate = error_rate;
98 self
99 }
100
101 pub fn with_security_bits(mut self, security_bits: usize) -> Self {
103 self.security_bits = security_bits;
104 self
105 }
106
107 pub fn distribute_key(&mut self) -> Result<usize> {
109 match self.protocol {
110 ProtocolType::BB84 => self.bb84_protocol(),
111 ProtocolType::E91 => self.e91_protocol(),
112 ProtocolType::B92 => self.b92_protocol(),
113 ProtocolType::BBM92 => self.bbm92_protocol(),
114 ProtocolType::SARG04 => self.sarg04_protocol(),
115 }
116 }
117
118 fn bb84_protocol(&mut self) -> Result<usize> {
120 let alice_bits = (0..self.num_qubits)
125 .map(|_| {
126 if thread_rng().random::<f64>() > 0.5 {
127 1u8
128 } else {
129 0u8
130 }
131 })
132 .collect::<Vec<_>>();
133
134 let alice_bases = (0..self.num_qubits)
136 .map(|_| {
137 if thread_rng().random::<f64>() > 0.5 {
138 1usize
139 } else {
140 0usize
141 }
142 })
143 .collect::<Vec<_>>();
144
145 let bob_bases = (0..self.num_qubits)
146 .map(|_| {
147 if thread_rng().random::<f64>() > 0.5 {
148 1usize
149 } else {
150 0usize
151 }
152 })
153 .collect::<Vec<_>>();
154
155 let matching_bases = alice_bases
157 .iter()
158 .zip(bob_bases.iter())
159 .enumerate()
160 .filter_map(|(i, (a, b))| if a == b { Some(i) } else { None })
161 .collect::<Vec<_>>();
162
163 let mut key_bits = Vec::new();
165 for &i in &matching_bases {
166 if thread_rng().random::<f64>() > self.error_rate {
168 key_bits.push(alice_bits[i]);
169 } else {
170 key_bits.push(alice_bits[i] ^ 1);
172 }
173 }
174
175 let mut key_bytes = Vec::new();
177 for chunk in key_bits.chunks(8) {
178 let byte = chunk
179 .iter()
180 .enumerate()
181 .fold(0u8, |acc, (i, &bit)| acc | (bit << i));
182 key_bytes.push(byte);
183 }
184
185 self.alice.key = Some(key_bytes.clone());
187 self.bob.key = Some(key_bytes);
188
189 self.alice.bases = Some(alice_bases);
191 self.bob.bases = Some(bob_bases);
192
193 Ok(matching_bases.len())
194 }
195
196 fn e91_protocol(&mut self) -> Result<usize> {
198 let key_length = self.num_qubits / 3; let key_bytes = (0..key_length / 8 + 1)
204 .map(|_| thread_rng().random::<u8>())
205 .collect::<Vec<_>>();
206
207 self.alice.key = Some(key_bytes.clone());
209 self.bob.key = Some(key_bytes);
210
211 Ok(key_length)
212 }
213
214 fn b92_protocol(&mut self) -> Result<usize> {
216 let key_length = self.num_qubits / 4; let key_bytes = (0..key_length / 8 + 1)
222 .map(|_| thread_rng().random::<u8>())
223 .collect::<Vec<_>>();
224
225 self.alice.key = Some(key_bytes.clone());
227 self.bob.key = Some(key_bytes);
228
229 Ok(key_length)
230 }
231
232 fn bbm92_protocol(&mut self) -> Result<usize> {
240 let mut rng = thread_rng();
241
242 let alice_bases: Vec<usize> = (0..self.num_qubits)
244 .map(|_| if rng.random::<f64>() > 0.5 { 1 } else { 0 })
245 .collect();
246 let bob_bases: Vec<usize> = (0..self.num_qubits)
247 .map(|_| if rng.random::<f64>() > 0.5 { 1 } else { 0 })
248 .collect();
249
250 let alice_bits: Vec<u8> = (0..self.num_qubits)
252 .map(|_| if rng.random::<f64>() > 0.5 { 1 } else { 0 })
253 .collect();
254
255 let sifted_indices: Vec<usize> = (0..self.num_qubits)
257 .filter(|&i| alice_bases[i] == bob_bases[i])
258 .collect();
259 let key_length = sifted_indices.len();
260
261 let key_bytes: Vec<u8> = sifted_indices
263 .chunks(8)
264 .map(|chunk| {
265 chunk.iter().enumerate().fold(0u8, |acc, (bit_pos, &idx)| {
266 acc | (alice_bits[idx] << bit_pos)
267 })
268 })
269 .collect();
270
271 self.alice.key = Some(key_bytes.clone());
272 self.bob.key = Some(key_bytes);
274 Ok(key_length)
275 }
276
277 fn sarg04_protocol(&mut self) -> Result<usize> {
285 let mut rng = thread_rng();
286
287 let alice_bits: Vec<u8> = (0..self.num_qubits)
289 .map(|_| if rng.random::<f64>() > 0.5 { 1 } else { 0 })
290 .collect();
291 let alice_bases: Vec<usize> = (0..self.num_qubits)
292 .map(|_| if rng.random::<f64>() > 0.5 { 1 } else { 0 })
293 .collect();
294
295 let bob_conclusive: Vec<bool> = (0..self.num_qubits)
298 .map(|_| rng.random::<f64>() > 0.5)
299 .collect();
300
301 let bob_bases: Vec<usize> = (0..self.num_qubits)
303 .map(|_| if rng.random::<f64>() > 0.5 { 1 } else { 0 })
304 .collect();
305 let sifted_indices: Vec<usize> = (0..self.num_qubits)
306 .filter(|&i| bob_conclusive[i] && alice_bases[i] == bob_bases[i])
307 .collect();
308 let key_length = sifted_indices.len();
309
310 let key_bytes: Vec<u8> = sifted_indices
311 .chunks(8)
312 .map(|chunk| {
313 chunk.iter().enumerate().fold(0u8, |acc, (bit_pos, &idx)| {
314 acc | (alice_bits[idx] << bit_pos)
315 })
316 })
317 .collect();
318
319 self.alice.key = Some(key_bytes.clone());
320 self.bob.key = Some(key_bytes);
321 Ok(key_length)
322 }
323
324 pub fn verify_keys(&self) -> bool {
326 match (&self.alice.key, &self.bob.key) {
327 (Some(alice_key), Some(bob_key)) => alice_key == bob_key,
328 _ => false,
329 }
330 }
331
332 pub fn get_alice_key(&self) -> Option<Vec<u8>> {
334 self.alice.key.clone()
335 }
336
337 pub fn get_bob_key(&self) -> Option<Vec<u8>> {
339 self.bob.key.clone()
340 }
341}
342
343pub(crate) mod sha256 {
353 const ROUND_CONSTANTS: [u32; 64] = [
354 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4,
355 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe,
356 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f,
357 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
358 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
359 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
360 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116,
361 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
362 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7,
363 0xc67178f2,
364 ];
365
366 const INITIAL_HASH: [u32; 8] = [
367 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab,
368 0x5be0cd19,
369 ];
370
371 pub fn digest(message: &[u8]) -> [u8; 32] {
373 let bit_len = (message.len() as u64).wrapping_mul(8);
374 let mut padded = message.to_vec();
375 padded.push(0x80);
376 while padded.len() % 64 != 56 {
377 padded.push(0);
378 }
379 padded.extend_from_slice(&bit_len.to_be_bytes());
380
381 let mut hash_state = INITIAL_HASH;
382 for chunk in padded.chunks_exact(64) {
383 let mut schedule = [0u32; 64];
384 for i in 0..16 {
385 schedule[i] = u32::from_be_bytes([
386 chunk[i * 4],
387 chunk[i * 4 + 1],
388 chunk[i * 4 + 2],
389 chunk[i * 4 + 3],
390 ]);
391 }
392 for i in 16..64 {
393 let s0 = schedule[i - 15].rotate_right(7)
394 ^ schedule[i - 15].rotate_right(18)
395 ^ (schedule[i - 15] >> 3);
396 let s1 = schedule[i - 2].rotate_right(17)
397 ^ schedule[i - 2].rotate_right(19)
398 ^ (schedule[i - 2] >> 10);
399 schedule[i] = schedule[i - 16]
400 .wrapping_add(s0)
401 .wrapping_add(schedule[i - 7])
402 .wrapping_add(s1);
403 }
404
405 let (mut a, mut b, mut c, mut d, mut e, mut f, mut g, mut h) = (
406 hash_state[0],
407 hash_state[1],
408 hash_state[2],
409 hash_state[3],
410 hash_state[4],
411 hash_state[5],
412 hash_state[6],
413 hash_state[7],
414 );
415
416 for i in 0..64 {
417 let s1 = e.rotate_right(6) ^ e.rotate_right(11) ^ e.rotate_right(25);
418 let ch = (e & f) ^ ((!e) & g);
419 let temp1 = h
420 .wrapping_add(s1)
421 .wrapping_add(ch)
422 .wrapping_add(ROUND_CONSTANTS[i])
423 .wrapping_add(schedule[i]);
424 let s0 = a.rotate_right(2) ^ a.rotate_right(13) ^ a.rotate_right(22);
425 let maj = (a & b) ^ (a & c) ^ (b & c);
426 let temp2 = s0.wrapping_add(maj);
427
428 h = g;
429 g = f;
430 f = e;
431 e = d.wrapping_add(temp1);
432 d = c;
433 c = b;
434 b = a;
435 a = temp1.wrapping_add(temp2);
436 }
437
438 hash_state[0] = hash_state[0].wrapping_add(a);
439 hash_state[1] = hash_state[1].wrapping_add(b);
440 hash_state[2] = hash_state[2].wrapping_add(c);
441 hash_state[3] = hash_state[3].wrapping_add(d);
442 hash_state[4] = hash_state[4].wrapping_add(e);
443 hash_state[5] = hash_state[5].wrapping_add(f);
444 hash_state[6] = hash_state[6].wrapping_add(g);
445 hash_state[7] = hash_state[7].wrapping_add(h);
446 }
447
448 let mut result = [0u8; 32];
449 for (i, word) in hash_state.iter().enumerate() {
450 result[i * 4..i * 4 + 4].copy_from_slice(&word.to_be_bytes());
451 }
452 result
453 }
454
455 #[cfg(test)]
456 mod tests {
457 use super::digest;
458
459 fn to_hex(bytes: &[u8]) -> String {
460 bytes.iter().map(|b| format!("{b:02x}")).collect()
461 }
462
463 #[test]
464 fn matches_official_test_vectors() {
465 assert_eq!(
466 to_hex(&digest(b"")),
467 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
468 );
469 assert_eq!(
470 to_hex(&digest(b"abc")),
471 "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
472 );
473 assert_eq!(
474 to_hex(&digest(
475 b"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
476 )),
477 "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"
478 );
479 }
480 }
481}
482
483fn digest_bit(digest: &[u8; 32], bit_index: usize) -> u8 {
486 let byte = digest[bit_index / 8];
487 (byte >> (bit_index % 8)) & 1
488}
489
490fn lamport_bit_count(security_bits: usize) -> usize {
494 security_bits.clamp(8, 256)
495}
496
497#[derive(Debug, Clone, PartialEq)]
504pub struct QuantumSignatureVerifyingKey {
505 bit_count: usize,
506 public_key: Vec<[u8; 32]>,
507}
508
509impl QuantumSignatureVerifyingKey {
510 pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<bool> {
512 QuantumSignature::verify_with_public_key(
513 message,
514 signature,
515 &self.public_key,
516 self.bit_count,
517 )
518 }
519
520 pub fn to_bytes(&self) -> Vec<u8> {
524 let mut bytes = Vec::with_capacity(8 + self.public_key.len() * 32);
525 bytes.extend_from_slice(&(self.bit_count as u64).to_be_bytes());
526 for entry in &self.public_key {
527 bytes.extend_from_slice(entry);
528 }
529 bytes
530 }
531
532 pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
534 if bytes.len() < 8 {
535 return Err(MLError::InvalidParameter(
536 "Verifying key bytes too short".to_string(),
537 ));
538 }
539 let bit_count_bytes: [u8; 8] = bytes[0..8]
540 .try_into()
541 .map_err(|_| MLError::InvalidParameter("Malformed bit-count prefix".to_string()))?;
542 let bit_count = u64::from_be_bytes(bit_count_bytes) as usize;
543 let expected_len = 8 + bit_count * 2 * 32;
544 if bytes.len() != expected_len {
545 return Err(MLError::InvalidParameter(format!(
546 "Verifying key length mismatch: expected {expected_len} bytes, got {}",
547 bytes.len()
548 )));
549 }
550 let public_key = bytes[8..]
551 .chunks_exact(32)
552 .map(|chunk| {
553 let mut entry = [0u8; 32];
554 entry.copy_from_slice(chunk);
555 entry
556 })
557 .collect();
558 Ok(Self {
559 bit_count,
560 public_key,
561 })
562 }
563}
564
565#[derive(Debug, Clone)]
581pub struct QuantumSignature {
582 bit_count: usize,
584
585 algorithm: String,
587
588 public_key: Vec<[u8; 32]>,
591
592 private_key: Vec<[u8; 32]>,
595}
596
597impl QuantumSignature {
598 pub fn new(security_bits: usize, algorithm: &str) -> Result<Self> {
600 let bit_count = lamport_bit_count(security_bits);
601 let mut rng = thread_rng();
602 let private_key: Vec<[u8; 32]> = (0..bit_count * 2)
603 .map(|_| {
604 let mut secret = [0u8; 32];
605 for byte in secret.iter_mut() {
606 *byte = rng.random::<u8>();
607 }
608 secret
609 })
610 .collect();
611 let public_key: Vec<[u8; 32]> = private_key
612 .iter()
613 .map(|secret| sha256::digest(secret))
614 .collect();
615
616 Ok(QuantumSignature {
617 bit_count,
618 algorithm: algorithm.to_string(),
619 public_key,
620 private_key,
621 })
622 }
623
624 pub fn sign(&self, message: &[u8]) -> Result<Vec<u8>> {
627 let message_digest = sha256::digest(message);
628 let mut signature = Vec::with_capacity(self.bit_count * 32);
629 for bit_index in 0..self.bit_count {
630 let bit = digest_bit(&message_digest, bit_index);
631 let secret = &self.private_key[2 * bit_index + bit as usize];
632 signature.extend_from_slice(secret);
633 }
634 Ok(signature)
635 }
636
637 pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<bool> {
643 Self::verify_with_public_key(message, signature, &self.public_key, self.bit_count)
644 }
645
646 pub fn verifying_key(&self) -> QuantumSignatureVerifyingKey {
649 QuantumSignatureVerifyingKey {
650 bit_count: self.bit_count,
651 public_key: self.public_key.clone(),
652 }
653 }
654
655 pub fn public_key_bytes(&self) -> Vec<u8> {
658 self.verifying_key().to_bytes()
659 }
660
661 fn verify_with_public_key(
662 message: &[u8],
663 signature: &[u8],
664 public_key: &[[u8; 32]],
665 bit_count: usize,
666 ) -> Result<bool> {
667 if signature.len() != bit_count * 32 || public_key.len() != bit_count * 2 {
668 return Ok(false);
669 }
670 let message_digest = sha256::digest(message);
671 for bit_index in 0..bit_count {
672 let bit = digest_bit(&message_digest, bit_index);
673 let revealed_preimage = &signature[bit_index * 32..(bit_index + 1) * 32];
674 let expected_public_entry = public_key[2 * bit_index + bit as usize];
675 if sha256::digest(revealed_preimage) != expected_public_entry {
676 return Ok(false);
677 }
678 }
679 Ok(true)
680 }
681}
682
683#[derive(Debug, Clone)]
685pub struct QuantumAuthentication {
686 protocol: String,
688
689 security_bits: usize,
691
692 keys: HashMap<String, Vec<u8>>,
694}
695
696impl QuantumAuthentication {
697 pub fn new(protocol: &str, security_bits: usize) -> Self {
699 QuantumAuthentication {
700 protocol: protocol.to_string(),
701 security_bits,
702 keys: HashMap::new(),
703 }
704 }
705
706 pub fn add_party(&mut self, party_name: &str) -> Result<()> {
708 let key = (0..self.security_bits / 8 + 1)
710 .map(|_| thread_rng().random::<u8>())
711 .collect::<Vec<_>>();
712
713 self.keys.insert(party_name.to_string(), key);
714
715 Ok(())
716 }
717
718 pub fn authenticate(&self, party_name: &str, message: &[u8]) -> Result<Vec<u8>> {
720 let key = self
722 .keys
723 .get(party_name)
724 .ok_or_else(|| MLError::InvalidParameter(format!("Party {} not found", party_name)))?;
725
726 let mut tag = key.clone();
728
729 for (i, &byte) in message.iter().enumerate() {
731 if i < tag.len() {
732 tag[i] ^= byte;
733 }
734 }
735
736 Ok(tag)
737 }
738
739 pub fn verify(&self, party_name: &str, message: &[u8], tag: &[u8]) -> Result<bool> {
741 let expected_tag = self.authenticate(party_name, message)?;
743
744 let is_valid = tag.len() == expected_tag.len()
746 && tag.iter().zip(expected_tag.iter()).all(|(a, b)| a == b);
747
748 Ok(is_valid)
749 }
750}
751
752#[derive(Debug, Clone)]
754pub struct QSDC {
755 pub num_qubits: usize,
757
758 pub error_rate: f64,
760}
761
762impl QSDC {
763 pub fn new(num_qubits: usize) -> Self {
765 QSDC {
766 num_qubits,
767 error_rate: 0.01, }
769 }
770
771 pub fn with_error_rate(mut self, error_rate: f64) -> Self {
773 self.error_rate = error_rate;
774 self
775 }
776
777 pub fn transmit_message(&self, message: &[u8]) -> Result<Vec<u8>> {
779 let mut received = message.to_vec();
785
786 for byte in &mut received {
788 for bit_pos in 0..8 {
789 if thread_rng().random::<f64>() < self.error_rate {
790 *byte ^= 1 << bit_pos;
792 }
793 }
794 }
795
796 Ok(received)
797 }
798}
799
800pub fn encrypt_with_qkd(message: &[u8], key: Vec<u8>) -> Vec<u8> {
802 message
804 .iter()
805 .enumerate()
806 .map(|(i, &byte)| byte ^ key[i % key.len()])
807 .collect()
808}
809
810pub fn decrypt_with_qkd(encrypted: &[u8], key: Vec<u8>) -> Vec<u8> {
812 encrypt_with_qkd(encrypted, key)
814}
815
816impl fmt::Display for ProtocolType {
817 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
818 match self {
819 ProtocolType::BB84 => write!(f, "BB84"),
820 ProtocolType::E91 => write!(f, "E91"),
821 ProtocolType::B92 => write!(f, "B92"),
822 ProtocolType::BBM92 => write!(f, "BBM92"),
823 ProtocolType::SARG04 => write!(f, "SARG04"),
824 }
825 }
826}
827
828#[cfg(test)]
829mod signature_regression_tests {
830 use super::*;
831
832 #[test]
836 fn verify_succeeds_with_only_the_public_verifying_key() {
837 let signer = QuantumSignature::new(64, "lamport-test").expect("key generation");
838 let message = b"transfer 10 QBTC to bob";
839 let signature = signer.sign(message).expect("signing should succeed");
840
841 let verifying_key = signer.verifying_key();
845 assert!(verifying_key
846 .verify(message, &signature)
847 .expect("verification should succeed"));
848
849 let bytes = verifying_key.to_bytes();
852 let restored = QuantumSignatureVerifyingKey::from_bytes(&bytes).expect("deserialize");
853 assert!(restored
854 .verify(message, &signature)
855 .expect("verification should succeed after round-trip"));
856 }
857
858 #[test]
859 fn verify_rejects_tampered_message_or_signature() {
860 let signer = QuantumSignature::new(64, "lamport-test").expect("key generation");
861 let message = b"transfer 10 QBTC to bob";
862 let signature = signer.sign(message).expect("signing should succeed");
863 let verifying_key = signer.verifying_key();
864
865 let tampered_message = b"transfer 99 QBTC to mallory";
866 assert!(!verifying_key
867 .verify(tampered_message, &signature)
868 .expect("verification should not error"));
869
870 let mut tampered_signature = signature.clone();
871 tampered_signature[0] ^= 0xFF;
872 assert!(!verifying_key
873 .verify(message, &tampered_signature)
874 .expect("verification should not error"));
875
876 let other_signer = QuantumSignature::new(64, "lamport-test").expect("key generation");
879 let other_signature = other_signer.sign(message).expect("signing should succeed");
880 assert!(!verifying_key
881 .verify(message, &other_signature)
882 .expect("verification should not error"));
883 }
884}