Quick Start
Installation & Basic Usage
# Install dependencies pip install numpy scipy matplotlib # Clone repository git clone https://github.com/alovladi007/PIC-Based-CV-QKD-Link-Optimizer.git cd PIC-Based-CV-QKD-Link-Optimizer # Run basic simulation python -m qkd.cli simulate --distance 25 --variance 4 # Output: # Distance: 25.0 km # Key rate: 0.0892 bits/symbol # Throughput @ 16 GBaud: 1427 Mbps
Example 1: Basic Key Rate Calculation
Calculate asymptotic secret key rate for a metropolitan CV-QKD link.
"""
Basic CV-QKD Key Rate Calculation
Metropolitan link example (25 km)
"""
import numpy as np
from qkd.secret_key import KeyRateCalculator, ChannelParams
# System parameters
params = ChannelParams(
distance_km=25, # Fiber distance
fiber_loss_db_km=0.2, # Standard SMF-28
pic_loss_db=6.0, # PIC insertion loss
excess_noise=0.01, # SNU
variance=4.0, # Modulation variance (SNU)
detector_qe=0.60, # Balanced detector QE
electronic_noise=0.01 # SNU
)
# Calculate key rate
calc = KeyRateCalculator(reconciliation_efficiency=0.95)
key_rate = calc.asymptotic_rate(params)
# Results
symbol_rate = 16e9 # 16 GBaud
throughput = key_rate * symbol_rate / 1e6 # Mbps
print(f"=== Metropolitan CV-QKD Link ===")
print(f"Distance: {params.distance_km} km")
print(f"Key rate: {key_rate:.4f} bits/symbol")
print(f"Throughput: {throughput:.0f} Mbps")
print(f"\nBreakdown:")
print(f" I_AB: {calc.mutual_information(params):.4f}")
print(f" χ_BE: {calc.holevo_bound(params):.4f}")
Expected output: Key rate ~0.089 bits/symbol, Throughput ~1424 Mbps
Example 2: Distance Sweep Analysis
Generate key rate vs distance curves for performance analysis.
"""
Distance Sweep Analysis
Generate key rate vs distance curves
"""
import numpy as np
import matplotlib.pyplot as plt
from qkd.secret_key import KeyRateCalculator, ChannelParams
calc = KeyRateCalculator(reconciliation_efficiency=0.95)
# Sweep parameters
distances = np.arange(1, 101)
excess_noise_values = [0.005, 0.01, 0.02]
plt.figure(figsize=(10, 6))
for xi in excess_noise_values:
key_rates = []
for d in distances:
params = ChannelParams(
distance_km=d,
excess_noise=xi,
variance=4.0,
detector_qe=0.6
)
key_rates.append(calc.asymptotic_rate(params))
plt.semilogy(distances, key_rates, label=f'ξ = {xi} SNU')
plt.xlabel('Distance (km)')
plt.ylabel('Key Rate (bits/symbol)')
plt.title('CV-QKD Key Rate vs Distance')
plt.legend()
plt.grid(True, alpha=0.3)
plt.xlim([0, 100])
plt.ylim([1e-4, 1])
plt.savefig('distance_sweep.png', dpi=150)
plt.show()
Example 3: PIC Loss Budget Design
Design and analyze a photonic integrated circuit loss budget.
"""
PIC Loss Budget Analysis
Design transmitter and receiver PICs
"""
from qkd.pic_budget import PICLossBudget
# Create transmitter budget
tx_budget = PICLossBudget(name="Alice TX")
tx_budget.add_component("Edge coupler", 2.0)
tx_budget.add_component("Si waveguide (1cm)", 0.5)
tx_budget.add_component("IQ modulator (LiNbO3)", 3.5)
tx_budget.add_component("VOA", 0.5)
tx_budget.add_component("Output edge coupler", 2.0)
# Create receiver budget
rx_budget = PICLossBudget(name="Bob RX")
rx_budget.add_component("Edge coupler", 2.0)
rx_budget.add_component("Polarization controller", 0.5)
rx_budget.add_component("90° optical hybrid", 1.0)
rx_budget.add_component("LO tap & routing", 3.0)
rx_budget.add_component("Balanced PD coupling", 0.5)
# Total system PIC loss
total_pic_loss = tx_budget.total_loss() + rx_budget.total_loss()
print("=== Transmitter PIC ===")
print(tx_budget.summary())
print(f"Total: {tx_budget.total_loss():.1f} dB\n")
print("=== Receiver PIC ===")
print(rx_budget.summary())
print(f"Total: {rx_budget.total_loss():.1f} dB\n")
print(f"=== System PIC Loss: {total_pic_loss:.1f} dB ===")
print(f"Transmittance: {10**(-total_pic_loss/10):.4f}")
Example 4: Finite-Size Security Analysis
Calculate secure key rates with finite-size corrections.
"""
Finite-Size Security Analysis
Compare asymptotic vs practical key rates
"""
import numpy as np
from qkd.secret_key import KeyRateCalculator, ChannelParams
from qkd.finite_size import FiniteSizeAnalyzer
# Channel parameters
params = ChannelParams(
distance_km=25,
excess_noise=0.01,
variance=4.0,
detector_qe=0.6
)
# Asymptotic calculation
calc = KeyRateCalculator(reconciliation_efficiency=0.95)
k_asymptotic = calc.asymptotic_rate(params)
# Finite-size for different block sizes
block_sizes = [1e6, 1e7, 1e8, 1e9, 1e10]
print("=== Finite-Size Analysis ===")
print(f"{'Block Size':<12} {'Key Rate':<12} {'Penalty':<10}")
print("-" * 34)
for N in block_sizes:
analyzer = FiniteSizeAnalyzer(
block_size=N,
pe_fraction=0.10,
epsilon_sec=1e-10,
attack_model="collective"
)
k_finite = analyzer.key_rate(params)
penalty = (k_asymptotic - k_finite) / k_asymptotic * 100
print(f"10^{int(np.log10(N)):<10} {k_finite:.4f} {penalty:.1f}%")
print(f"\nAsymptotic: {k_asymptotic:.4f} bits/symbol")
Example 5: Detector Parameter Optimization
Optimize detector parameters for maximum performance.
"""
Detector Optimization
Find optimal detector parameters for given channel
"""
import numpy as np
from scipy.optimize import minimize
from qkd.secret_key import KeyRateCalculator, ChannelParams
calc = KeyRateCalculator(reconciliation_efficiency=0.95)
def neg_key_rate(x, distance):
"""Negative key rate (for minimization)"""
qe, v_el = x
if qe < 0.3 or qe > 0.95 or v_el < 0.001 or v_el > 0.05:
return 1.0 # Penalty for out of bounds
params = ChannelParams(
distance_km=distance,
excess_noise=0.01,
variance=4.0,
detector_qe=qe,
electronic_noise=v_el
)
return -calc.asymptotic_rate(params)
# Optimize for 50 km link
result = minimize(
neg_key_rate,
x0=[0.6, 0.01], # Initial guess
args=(50,),
method='Nelder-Mead',
options={'xatol': 1e-4}
)
opt_qe, opt_vel = result.x
opt_rate = -result.fun
print("=== Detector Optimization (50 km) ===")
print(f"Optimal QE: {opt_qe:.2f}")
print(f"Optimal electronic noise: {opt_vel:.4f} SNU")
print(f"Maximum key rate: {opt_rate:.4f} bits/symbol")
# Compare with typical values
typical_params = ChannelParams(
distance_km=50, excess_noise=0.01,
variance=4.0, detector_qe=0.6, electronic_noise=0.01
)
typical_rate = calc.asymptotic_rate(typical_params)
improvement = (opt_rate - typical_rate) / typical_rate * 100
print(f"Improvement over typical: {improvement:.1f}%")
Example 6: Complete End-to-End Simulation
Full CV-QKD simulation with state preparation, transmission, and key extraction.
"""
Complete CV-QKD Simulation
End-to-end key generation pipeline
"""
import numpy as np
from qkd.gmcs import GMCSTransmitter, GMCSReceiver, QuantumChannel
from qkd.post_processing import ParameterEstimator, Reconciliation
from qkd.secret_key import KeyRateCalculator
# Simulation parameters
N_SYMBOLS = 100000
DISTANCE_KM = 25
VARIANCE = 4.0
SEED = 42
print("=== CV-QKD End-to-End Simulation ===\n")
# 1. Alice prepares states
print("1. State Preparation (Alice)")
alice = GMCSTransmitter(variance=VARIANCE, seed=SEED)
states = alice.prepare_states(N_SYMBOLS)
x_alice, p_alice = alice.get_modulation_data()
print(f" Generated {N_SYMBOLS} coherent states")
print(f" Variance: {np.var(x_alice):.2f} SNU")
# 2. Quantum channel transmission
print("\n2. Quantum Channel")
channel = QuantumChannel(
distance_km=DISTANCE_KM,
fiber_loss_db_km=0.2,
excess_noise=0.01
)
print(f" Distance: {DISTANCE_KM} km")
print(f" Transmittance: {channel.transmittance():.4f}")
# 3. Bob measures
print("\n3. Measurement (Bob)")
bob = GMCSReceiver(
detection_mode="homodyne",
quantum_efficiency=0.6,
electronic_noise=0.01
)
x_bob = bob.measure(states, channel)
print(f" Detection mode: homodyne")
print(f" Correlation: {np.corrcoef(x_alice, x_bob)[0,1]:.4f}")
# 4. Parameter estimation
print("\n4. Parameter Estimation")
estimator = ParameterEstimator(pe_fraction=0.10)
estimated_params = estimator.estimate(x_alice, x_bob)
print(f" Estimated transmittance: {estimated_params['T']:.4f}")
print(f" Estimated excess noise: {estimated_params['xi']:.4f} SNU")
# 5. Key rate calculation
print("\n5. Key Rate")
calc = KeyRateCalculator(reconciliation_efficiency=0.95)
key_rate = calc.asymptotic_rate_from_estimates(estimated_params)
print(f" Asymptotic rate: {key_rate:.4f} bits/symbol")
# 6. Summary
print("\n=== Summary ===")
n_key_bits = int(key_rate * N_SYMBOLS * 0.9) # 90% for key gen
print(f"Expected key length: {n_key_bits} bits")
print(f"Throughput @ 16 GBaud: {key_rate * 16000:.0f} Mbps")
Example 7: Export Results to CSV
Export simulation results for further analysis.
"""
Export Results to CSV
Generate comprehensive parameter sweep data
"""
import pandas as pd
import numpy as np
from qkd.secret_key import KeyRateCalculator, ChannelParams
from datetime import datetime
calc = KeyRateCalculator(reconciliation_efficiency=0.95)
# Parameter ranges
distances = np.arange(1, 101, 5)
excess_noises = [0.005, 0.01, 0.015, 0.02]
variances = [2, 4, 8]
# Generate results
results = []
for d in distances:
for xi in excess_noises:
for va in variances:
params = ChannelParams(
distance_km=d,
excess_noise=xi,
variance=va,
detector_qe=0.6
)
kr = calc.asymptotic_rate(params)
results.append({
'distance_km': d,
'excess_noise_snu': xi,
'variance_snu': va,
'key_rate': kr,
'throughput_mbps': kr * 16000
})
# Create DataFrame
df = pd.DataFrame(results)
# Add metadata
metadata = {
'generated': datetime.now().isoformat(),
'reconciliation_efficiency': 0.95,
'detector_qe': 0.6,
'fiber_loss_db_km': 0.2,
'pic_loss_db': 6.0
}
# Save to CSV
filename = f"cvqkd_results_{datetime.now():%Y%m%d_%H%M%S}.csv"
df.to_csv(filename, index=False)
print(f"Results saved to {filename}")
print(f"Total configurations: {len(df)}")
print(f"\nSample data:")
print(df.head(10))