This comprehensive cheat sheet covers Q# fundamentals with a specialized focus on Quantum Key Distribution (QKD) protocols like BB84 and E91. Perfect for quantum developers and cryptography enthusiasts.
namespace QKD {
open Microsoft.Quantum.Core;
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Canon;
@EntryPoint()
operation Main() : Unit {
Message("Welcome to Quantum Key Distribution!");
// Your quantum code here
use qubit = Qubit() {
H(qubit); // Create superposition
let result = M(qubit); // Measure qubit
Message($"Measured: {result}");
Reset(qubit); // Always reset!
}
}
}
namespace
@EntryPoint()
marks where execution beginsReset()
qubits before releasing themMessage()
to print outputType | Description | QKD Usage | Example |
---|---|---|---|
Qubit |
Single quantum bit | Photon carrying information | use q = Qubit(); |
Qubit[] |
Array of qubits | Multiple photons/qubits | use qs = Qubit[4]; |
Result |
Measurement outcome | Bit values (0 or 1) | Zero , One |
Bool |
Classical bit | Key bits, basis choices | true , false |
Int |
Integer numbers | Counters, indices | 42 , 0 , -5 |
Pauli |
Measurement basis | X-basis, Z-basis | PauliX , PauliZ |
// Create |0โฉ state (default)
use qubit = Qubit(); // Automatically in |0โฉ
// Create |1โฉ state
X(qubit); // Apply NOT gate: |0โฉ โ |1โฉ
// Create superposition |+โฉ = (|0โฉ + |1โฉ)/โ2
H(qubit); // Hadamard gate
// Create superposition |โโฉ = (|0โฉ โ |1โฉ)/โ2
X(qubit);
H(qubit);
// Standard (Z-basis) measurement: measures |0โฉ or |1โฉ
let result = M(qubit);
// X-basis measurement: measures |+โฉ or |โโฉ
H(qubit); // Rotate to Z-basis
let result = M(qubit); // Then measure
// Check measurement result
if result == Zero {
Message("Measured 0");
} else {
Message("Measured 1");
}
Random qubits in random bases
Qubits in random bases
Keep matching basis results
Shared secret from matches
operation AlicePrepareQubits(bits : Bool[], bases : Bool[]) : Qubit[] {
mutable qubits = [];
for i in 0..Length(bits)-1 {
use qubit = Qubit();
// Prepare bit value (0 or 1)
if bits[i] {
X(qubit); // Prepare |1โฉ
}
// else qubit is already |0โฉ
// Choose basis (false = Z-basis, true = X-basis)
if bases[i] {
H(qubit); // Rotate to X-basis
}
set qubits += [qubit];
}
return qubits;
}
operation BobMeasureQubits(qubits : Qubit[], bases : Bool[]) : Bool[] {
mutable results = [];
for i in 0..Length(qubits)-1 {
// Choose measurement basis
if bases[i] {
H(qubits[i]); // Measure in X-basis
}
// else measure in Z-basis (default)
let result = M(qubits[i]);
let bit = result == One;
set results += [bit];
Reset(qubits[i]);
}
return results;
}
operation GenerateRandomBit() : Bool {
use qubit = Qubit() {
H(qubit); // Create superposition
let result = M(qubit); // Random measurement
Reset(qubit);
return result == One; // Convert to Bool
}
}
operation GenerateRandomBits(count : Int) : Bool[] {
mutable bits = [];
for _ in 1..count {
set bits += [GenerateRandomBit()];
}
return bits;
}
// โ
CORRECT: Always use this pattern
use qubit = Qubit() {
// Do quantum operations
H(qubit);
let result = M(qubit);
// Reset before automatic release
Reset(qubit);
} // Qubit automatically released here
// โ WRONG: Forgetting to reset
use qubit = Qubit() {
H(qubit);
let result = M(qubit);
// Missing Reset(qubit)!
}
// โ WRONG: Using qubit after measurement without reset
let result1 = M(qubit);
H(qubit); // This might not work as expected!
use qubit = Qubit() { ... Reset(qubit); }
H(qubit)
for superpositionX(qubit)
for bit flipM(qubit)
for measurementif result == One { ... }
open Microsoft.Quantum.Core; // Basic Q# features
open Microsoft.Quantum.Intrinsic; // H, X, M gates
open Microsoft.Quantum.Canon; // Standard operations
open Microsoft.Quantum.Arrays; // Array manipulation
open Microsoft.Quantum.Convert; // Type conversions
open Microsoft.Quantum.Math; // Random numbers
open Microsoft.Quantum.Measurement; // Advanced measurements
@EntryPoint()
operation BB84Demo() : Unit {
let keyLength = 8; // Short key for demo
Message("=== BB84 Quantum Key Distribution Demo ===");
// 1. Alice generates random bits and bases
let aliceBits = GenerateRandomBits(keyLength);
let aliceBases = GenerateRandomBits(keyLength);
Message($"Alice's bits: {aliceBits}");
Message($"Alice's bases: {aliceBases}");
// 2. Alice prepares qubits
let qubits = AlicePrepareQubits(aliceBits, aliceBases);
// 3. Bob chooses random measurement bases
let bobBases = GenerateRandomBits(keyLength);
Message($"Bob's bases: {bobBases}");
// 4. Bob measures qubits
let bobBits = BobMeasureQubits(qubits, bobBases);
Message($"Bob's bits: {bobBits}");
// 5. Extract secret key (matching bases only)
let secretKey = ExtractSecretKey(aliceBits, bobBits, aliceBases, bobBases);
Message($"Secret key: {secretKey}");
Message($"Key length: {Length(secretKey)} bits");
}
// Print variable values
Message($"Current bit: {bit}");
Message($"Key length: {Length(secretKey)}");
// Print arrays
Message($"Alice's key: {aliceKey}");
// Simulator-only: Show quantum state
DumpMachine(); // Shows full quantum state
operation TestBB84() : Unit {
// Test with known values
let testBits = [true, false, true, false];
let testBases = [false, false, true, true]; // Z, Z, X, X
let qubits = AlicePrepareQubits(testBits, testBases);
let results = BobMeasureQubits(qubits, testBases); // Same bases
// Results should match when bases are same
for i in 0..Length(testBits)-1 {
if testBits[i] != results[i] {
Message($"ERROR: Bit {i} doesn't match!");
}
}
Message("BB84 test completed!");
}
open Microsoft.Quantum.Arrays;
let length = Length(myArray); // Get array size
let firstElement = Head(myArray); // Get first element
let restElements = Tail(myArray); // Get all but first
let combined = array1 + array2; // Concatenate arrays
open Microsoft.Quantum.Convert;
let boolArray = ResultArrayAsBoolArray(results);
let intValue = BoolArrayAsInt(boolArray);
let resultArray = BoolArrayAsResultArray(boolArray);
open Microsoft.Quantum.Math;
let randomFloat = RandomReal(); // Random [0,1)
let randomInt = RandomInt(10); // Random [0,9]
let squareRoot = Sqrt(4.0); // = 2.0
// Immutable binding (can't change)
let numberOfPhotons = 100;
let secretBit = true;
// Mutable variable (can change)
mutable matchingBases = 0;
set matchingBases = matchingBases + 1;
// Arrays
let aliceBits = [true, false, true, false];
mutable keyBits = [];
set keyBits += [true]; // Add element to array
// Process array of qubits
for i in 0..Length(qubits)-1 {
H(qubits[i]);
let result = M(qubits[i]);
Message($"Qubit {i}: {result}");
}
// Repeat until condition
mutable attempts = 0;
repeat {
// Try quantum operation
set attempts = attempts + 1;
} until attempts >= maxAttempts;
// Single qubit measurement
let bit = M(qubit) == One;
// Multiple qubits at once
let results = MeasureEachZ(qubits);
let bits = ResultArrayAsBoolArray(results);
operation MeasureInRandomBasis(qubit : Qubit) : (Bool, Bool) {
let basisChoice = GenerateRandomBit(); // Random basis
if basisChoice {
H(qubit); // Measure in X-basis
}
// else measure in Z-basis
let measurementResult = M(qubit) == One;
Reset(qubit);
return (measurementResult, basisChoice);
}
Create a function that prepares a qubit in state |+โฉ and measures it in Z-basis.
Show what happens when Alice prepares in X-basis but Bob measures in Z-basis.
Implement a simple eavesdropping detection by comparing error rates.
Implement BB84 with 4 qubits and trace through the entire protocol.
Perfect for GitHub Pages deployment โข Optimized for learning and reference