rust_qrng 0.1.2

Tsotchkes quantum random number generator library with cryptographic, financial, and gaming applications converted to Rust
Documentation
use crate::QuantumRNG;
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};

pub fn derive_key(secret: &[u8], salt: &[u8], iterations: u32) -> Vec<u8> {
    const KEY_SIZE: usize = 32;
    const MAX_BUFFER_SIZE: usize = 128;
    const QUANTUM_MIX: u32 = 50; // 50% quantum mixing like the C version
    
    // Initialize quantum RNG with deterministic seed based on secret and salt
    let mut hasher = DefaultHasher::new();
    secret.hash(&mut hasher);
    salt.hash(&mut hasher);
    let _seed = hasher.finish();
    
    let mut rng = QuantumRNG::new();
    
    // Create memory buffer similar to C version
    let mut memory_buffer = vec![0u8; MAX_BUFFER_SIZE];
    
    // Main iteration loop (similar to C version)
    for i in 0..iterations {
        let mut pos = 0;
        
        // Copy secret (password equivalent)
        let secret_len = std::cmp::min(secret.len(), MAX_BUFFER_SIZE - pos - salt.len() - 4);
        memory_buffer[pos..pos + secret_len].copy_from_slice(&secret[..secret_len]);
        pos += secret_len;
        
        // Copy salt
        let salt_len = std::cmp::min(salt.len(), MAX_BUFFER_SIZE - pos - 4);
        memory_buffer[pos..pos + salt_len].copy_from_slice(&salt[..salt_len]);
        pos += salt_len;
        
        // Copy iteration counter
        let counter_bytes = i.to_le_bytes();
        if pos + counter_bytes.len() <= MAX_BUFFER_SIZE {
            memory_buffer[pos..pos + counter_bytes.len()].copy_from_slice(&counter_bytes);
            pos += counter_bytes.len();
        }
        
        // Apply quantum mixing to the used portion of the buffer
        quantum_mix(&mut memory_buffer[..pos], &mut rng, QUANTUM_MIX);
    }
    
    // Final key derivation - copy the first KEY_SIZE bytes
    let mut derived_key = vec![0u8; KEY_SIZE];
    let copy_len = std::cmp::min(KEY_SIZE, memory_buffer.len());
    derived_key[..copy_len].copy_from_slice(&memory_buffer[..copy_len]);
    
    // Final quantum mixing pass on the derived key
    quantum_mix(&mut derived_key, &mut rng, QUANTUM_MIX);
    
    derived_key
}

// Quantum mixing function similar to C version
fn quantum_mix(data: &mut [u8], rng: &mut QuantumRNG, mix_factor: u32) {
    const QUANTUM_CHUNK_SIZE: usize = 32;
    
    for chunk in data.chunks_mut(QUANTUM_CHUNK_SIZE) {
        let quantum_bytes = rng.generate_random_bytes(chunk.len());
        let mixing_bytes = rng.generate_random_bytes(chunk.len());
        
        for (i, byte) in chunk.iter_mut().enumerate() {
            let quantum_byte = quantum_bytes[i];
            let mixing_byte = mixing_bytes[i];
            
            // Safe arithmetic to avoid overflow
            let original = *byte as u32;
            let quantum_mix = (quantum_byte as u32 + mixing_byte as u32) % 256;
            
            let mixed = (original * (100 - mix_factor) + quantum_mix * mix_factor) / 100;
            *byte = (mixed % 256) as u8;
        }
    }
}