1use crate::crypto::{sha256, QuantumSignatureVerifyingKey};
8use crate::error::{MLError, Result};
9use std::collections::HashMap;
10use std::fmt;
11use std::time::{Duration, SystemTime, UNIX_EPOCH};
12
13#[derive(Debug, Clone, Copy, PartialEq)]
15pub enum ConsensusType {
16 QuantumProofOfWork,
18
19 QuantumProofOfStake,
21
22 QuantumByzantineAgreement,
24
25 QuantumFederated,
27}
28
29#[derive(Debug, Clone)]
31pub struct Transaction {
32 pub sender: Vec<u8>,
37
38 pub recipient: Vec<u8>,
40
41 pub amount: f64,
43
44 pub data: Vec<u8>,
46
47 timestamp: u64,
49
50 signature: Option<Vec<u8>>,
53}
54
55impl Transaction {
56 pub fn new(sender: Vec<u8>, recipient: Vec<u8>, amount: f64, data: Vec<u8>) -> Self {
58 let timestamp = SystemTime::now()
59 .duration_since(UNIX_EPOCH)
60 .unwrap_or(Duration::from_secs(0))
61 .as_secs();
62
63 Transaction {
64 sender,
65 recipient,
66 amount,
67 data,
68 timestamp,
69 signature: None,
70 }
71 }
72
73 pub fn sign(&mut self, signature: Vec<u8>) -> Result<()> {
76 self.signature = Some(signature);
77 Ok(())
78 }
79
80 fn signing_message(&self) -> Vec<u8> {
83 let mut message = Vec::new();
84 message.extend_from_slice(&self.sender);
85 message.extend_from_slice(&self.recipient);
86 message.extend_from_slice(&self.amount.to_be_bytes());
87 message.extend_from_slice(&self.timestamp.to_be_bytes());
88 message.extend_from_slice(&self.data);
89 message
90 }
91
92 pub fn verify(&self) -> Result<bool> {
99 let signature = match &self.signature {
100 Some(signature) => signature,
101 None => return Ok(false),
102 };
103 let verifying_key = match QuantumSignatureVerifyingKey::from_bytes(&self.sender) {
104 Ok(key) => key,
105 Err(_) => return Ok(false),
106 };
107 verifying_key.verify(&self.signing_message(), signature)
108 }
109
110 pub fn hash(&self) -> Vec<u8> {
115 let mut preimage = self.signing_message();
116 if let Some(signature) = &self.signature {
121 preimage.extend_from_slice(signature);
122 }
123 sha256::digest(&preimage).to_vec()
124 }
125}
126
127#[derive(Debug, Clone)]
129pub struct Block {
130 pub index: usize,
132
133 pub previous_hash: Vec<u8>,
135
136 pub timestamp: u64,
138
139 pub transactions: Vec<Transaction>,
141
142 pub nonce: u64,
144
145 pub hash: Vec<u8>,
147}
148
149impl Block {
150 pub fn new(index: usize, previous_hash: Vec<u8>, transactions: Vec<Transaction>) -> Self {
152 let timestamp = SystemTime::now()
153 .duration_since(UNIX_EPOCH)
154 .unwrap_or(Duration::from_secs(0))
155 .as_secs();
156
157 let mut block = Block {
158 index,
159 previous_hash,
160 timestamp,
161 transactions,
162 nonce: 0,
163 hash: Vec::new(),
164 };
165
166 block.hash = block.calculate_hash();
167
168 block
169 }
170
171 pub fn calculate_hash(&self) -> Vec<u8> {
178 let mut preimage = Vec::new();
179
180 preimage.extend_from_slice(&(self.index as u64).to_be_bytes());
181 preimage.extend_from_slice(&self.previous_hash);
182 preimage.extend_from_slice(&self.timestamp.to_be_bytes());
183
184 for transaction in &self.transactions {
185 preimage.extend_from_slice(&transaction.hash());
186 }
187
188 preimage.extend_from_slice(&self.nonce.to_be_bytes());
189
190 sha256::digest(&preimage).to_vec()
191 }
192
193 pub fn mine(&mut self, difficulty: usize) -> Result<()> {
195 let target_len = (difficulty / 8 + 1).min(self.hash.len());
201 let target = vec![0u8; target_len];
202
203 while self.hash[0..target_len] != target[..] {
204 self.nonce += 1;
205 self.hash = self.calculate_hash();
206
207 if self.nonce > 1_000_000 {
209 return Err(MLError::MLOperationError(
210 "Mining took too long. Consider reducing difficulty.".to_string(),
211 ));
212 }
213 }
214
215 Ok(())
216 }
217
218 pub fn verify(&self, previous_hash: &[u8]) -> Result<bool> {
220 if self.previous_hash != previous_hash {
224 return Ok(false);
225 }
226
227 let calculated_hash = self.calculate_hash();
228 if self.hash != calculated_hash {
229 return Ok(false);
230 }
231
232 for transaction in &self.transactions {
233 if !transaction.verify()? {
234 return Ok(false);
235 }
236 }
237
238 Ok(true)
239 }
240}
241
242#[derive(Debug, Clone)]
244pub struct SmartContract {
245 pub bytecode: Vec<u8>,
247
248 pub owner: Vec<u8>,
250
251 pub state: HashMap<Vec<u8>, Vec<u8>>,
253}
254
255impl SmartContract {
256 pub fn new(bytecode: Vec<u8>, owner: Vec<u8>) -> Self {
258 SmartContract {
259 bytecode,
260 owner,
261 state: HashMap::new(),
262 }
263 }
264
265 pub fn execute(&mut self, input: &[u8]) -> Result<Vec<u8>> {
267 if input.is_empty() {
271 return Err(MLError::InvalidParameter("Input is empty".to_string()));
272 }
273
274 let operation = input[0];
275
276 match operation {
277 0 => {
278 if input.len() < 3 {
280 return Err(MLError::InvalidParameter("Invalid store input".to_string()));
281 }
282
283 let key = vec![input[1]];
284 let value = vec![input[2]];
285
286 self.state.insert(key, value.clone());
287
288 Ok(value)
289 }
290 1 => {
291 if input.len() < 2 {
293 return Err(MLError::InvalidParameter("Invalid load input".to_string()));
294 }
295
296 let key = vec![input[1]];
297
298 let value = self.state.get(&key).ok_or_else(|| {
299 MLError::MLOperationError(format!("Key not found: {:?}", key))
300 })?;
301
302 Ok(value.clone())
303 }
304 _ => Err(MLError::InvalidParameter(format!(
305 "Invalid operation: {}",
306 operation
307 ))),
308 }
309 }
310}
311
312#[derive(Debug, Clone)]
314pub struct QuantumToken {
315 pub name: String,
317
318 pub symbol: String,
320
321 pub total_supply: u64,
323
324 pub balances: HashMap<Vec<u8>, u64>,
326}
327
328impl QuantumToken {
329 pub fn new(name: &str, symbol: &str, total_supply: u64, owner: Vec<u8>) -> Self {
331 let mut balances = HashMap::new();
332 balances.insert(owner, total_supply);
333
334 QuantumToken {
335 name: name.to_string(),
336 symbol: symbol.to_string(),
337 total_supply,
338 balances,
339 }
340 }
341
342 pub fn transfer(&mut self, from: &[u8], to: &[u8], amount: u64) -> Result<()> {
344 let from_balance = *self.balances.get(from).ok_or_else(|| {
346 MLError::MLOperationError(format!("From address not found: {:?}", from))
347 })?;
348
349 if from_balance < amount {
350 return Err(MLError::MLOperationError(format!(
351 "Insufficient balance: {} < {}",
352 from_balance, amount
353 )));
354 }
355
356 self.balances.insert(from.to_vec(), from_balance - amount);
358
359 let to_balance = self.balances.entry(to.to_vec()).or_insert(0);
361 *to_balance += amount;
362
363 Ok(())
364 }
365
366 pub fn balance_of(&self, address: &[u8]) -> u64 {
368 self.balances.get(address).cloned().unwrap_or(0)
369 }
370}
371
372#[derive(Debug, Clone)]
374pub struct QuantumBlockchain {
375 pub chain: Vec<Block>,
377
378 pub pending_transactions: Vec<Transaction>,
380
381 pub difficulty: usize,
383
384 pub consensus: ConsensusType,
386
387 pub nodes: Vec<String>,
389}
390
391impl QuantumBlockchain {
392 pub fn new(consensus: ConsensusType, difficulty: usize) -> Self {
394 let genesis_block = Block::new(0, vec![0u8; 32], Vec::new());
396
397 QuantumBlockchain {
398 chain: vec![genesis_block],
399 pending_transactions: Vec::new(),
400 difficulty,
401 consensus,
402 nodes: Vec::new(),
403 }
404 }
405
406 pub fn add_transaction(&mut self, transaction: Transaction) -> Result<()> {
408 if !transaction.verify()? {
410 return Err(MLError::MLOperationError(
411 "Transaction verification failed".to_string(),
412 ));
413 }
414
415 self.pending_transactions.push(transaction);
416
417 Ok(())
418 }
419
420 pub fn mine_block(&mut self) -> Result<Block> {
422 if self.pending_transactions.is_empty() {
423 return Err(MLError::MLOperationError(
424 "No pending transactions to mine".to_string(),
425 ));
426 }
427
428 let transactions = self.pending_transactions.clone();
429 self.pending_transactions.clear();
430
431 let previous_block = self
432 .chain
433 .last()
434 .ok_or_else(|| MLError::MLOperationError("Blockchain is empty".to_string()))?;
435
436 let mut block = Block::new(self.chain.len(), previous_block.hash.clone(), transactions);
437
438 match self.consensus {
440 ConsensusType::QuantumProofOfWork => {
441 block.mine(self.difficulty)?;
442 }
443 _ => {
444 block.hash = block.calculate_hash();
446 }
447 }
448
449 self.chain.push(block.clone());
450
451 Ok(block)
452 }
453
454 pub fn verify(&self) -> Result<bool> {
456 for i in 1..self.chain.len() {
457 let current_block = &self.chain[i];
458 let previous_block = &self.chain[i - 1];
459
460 if !current_block.verify(&previous_block.hash)? {
461 return Ok(false);
462 }
463 }
464
465 Ok(true)
466 }
467
468 pub fn verify_chain(&self) -> Result<bool> {
470 self.verify()
471 }
472
473 pub fn tamper_with_block(
475 &self,
476 block_index: usize,
477 sender: &str,
478 amount: f64,
479 ) -> Result<QuantumBlockchain> {
480 if block_index >= self.chain.len() {
481 return Err(MLError::MLOperationError(format!(
482 "Block index out of range: {}",
483 block_index
484 )));
485 }
486
487 let mut tampered = self.clone();
488
489 let tampered_transaction = Transaction::new(
491 sender.as_bytes().to_vec(),
492 vec![1, 2, 3, 4],
493 amount,
494 Vec::new(),
495 );
496
497 if !tampered.chain[block_index].transactions.is_empty() {
499 tampered.chain[block_index].transactions[0] = tampered_transaction;
500 } else {
501 tampered.chain[block_index]
502 .transactions
503 .push(tampered_transaction);
504 }
505
506 let hash = tampered.chain[block_index].calculate_hash();
508 tampered.chain[block_index].hash = hash;
509
510 Ok(tampered)
511 }
512}
513
514impl fmt::Display for ConsensusType {
515 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
516 match self {
517 ConsensusType::QuantumProofOfWork => write!(f, "Quantum Proof of Work"),
518 ConsensusType::QuantumProofOfStake => write!(f, "Quantum Proof of Stake"),
519 ConsensusType::QuantumByzantineAgreement => write!(f, "Quantum Byzantine Agreement"),
520 ConsensusType::QuantumFederated => write!(f, "Quantum Federated Consensus"),
521 }
522 }
523}
524
525#[cfg(test)]
526mod integrity_regression_tests {
527 use super::*;
528 use crate::crypto::QuantumSignature;
529
530 fn signed_transaction(
531 signer: &QuantumSignature,
532 recipient: Vec<u8>,
533 amount: f64,
534 ) -> Transaction {
535 let mut tx = Transaction::new(signer.public_key_bytes(), recipient, amount, Vec::new());
536 let signature = signer.sign(&tx.signing_message()).expect("sign");
537 tx.sign(signature).expect("attach signature");
538 tx
539 }
540
541 #[test]
545 fn transaction_verify_checks_the_real_signature() {
546 let signer = QuantumSignature::new(64, "lamport-test").expect("key generation");
547 let mut tx = signed_transaction(&signer, vec![9, 9, 9], 42.0);
548 assert!(tx.verify().expect("verify should not error"));
549
550 tx.amount = 999.0;
552 assert!(!tx.verify().expect("verify should not error"));
553 }
554
555 #[test]
556 fn transaction_without_signature_never_verifies() {
557 let tx = Transaction::new(vec![1, 2, 3], vec![4, 5, 6], 1.0, Vec::new());
558 assert!(!tx.verify().expect("verify should not error"));
559 }
560
561 #[test]
566 fn transaction_hash_is_fixed_size_and_diffuses_small_changes() {
567 let signer = QuantumSignature::new(64, "lamport-test").expect("key generation");
568 let tx_a = signed_transaction(&signer, vec![9, 9, 9], 42.0);
569 let mut tx_b = tx_a.clone();
570 tx_b.amount = 42.000001;
571
572 let hash_a = tx_a.hash();
573 let hash_b = tx_b.hash();
574 assert_eq!(hash_a.len(), 32, "expected a 32-byte SHA-256 digest");
575 assert_eq!(hash_b.len(), 32, "expected a 32-byte SHA-256 digest");
576 assert_ne!(hash_a, hash_b);
577
578 let differing_bits: u32 = hash_a
582 .iter()
583 .zip(hash_b.iter())
584 .map(|(a, b)| (a ^ b).count_ones())
585 .sum();
586 assert!(
587 differing_bits > 32,
588 "expected substantial bit diffusion, got {differing_bits} differing bits"
589 );
590 }
591
592 #[test]
595 fn mined_chain_with_signed_transactions_verifies() {
596 let signer = QuantumSignature::new(48, "lamport-test").expect("key generation");
597 let mut blockchain = QuantumBlockchain::new(ConsensusType::QuantumProofOfWork, 8);
598
599 blockchain
600 .add_transaction(signed_transaction(&signer, vec![1, 2, 3], 5.0))
601 .expect("adding a validly signed transaction should succeed");
602 blockchain.mine_block().expect("mining should succeed");
603
604 assert!(blockchain.verify().expect("chain should verify"));
605 }
606
607 #[test]
610 fn add_transaction_rejects_unsigned_transaction() {
611 let mut blockchain = QuantumBlockchain::new(ConsensusType::QuantumProofOfWork, 8);
612 let unsigned = Transaction::new(vec![1, 2, 3], vec![4, 5, 6], 1.0, Vec::new());
613 assert!(blockchain.add_transaction(unsigned).is_err());
614 }
615}