An educational and scalable quantum cryptanalysis suite developed by Yiğit Mert YILMAZ as part of the Microsoft AI Innovators Summer Internship Program (Quantum Programming Onboarding Track).
Live Interactive Demo · Directory Structure · System Architecture · Circuit Schematics · Results Report · Quickstart
Note
This project was engineered by Yiğit Mert YILMAZ for the Microsoft AI Innovators Summer Internship Program (Quantum Programming Onboarding Track). It implements a parameterized Grover's search algorithm, Hilbert space wave-function tomography, and empirical overcooking analysis on the Microsoft Azure Quantum QDK local simulator.
Table of Contents (Click to expand)
- Problem Context and Quantum Cryptanalysis Motivation
- Project Directory Structure
- System Architecture and Pipeline Design
- Quantum Circuit Implementation
- State Vector and Wave-Function Evolution
- The Overcooking Phenomenon and Hilbert Space Geometry
- Quantitative Benchmark Matrix
- Asymptotic Scaling and Cryptanalytic Implications
- Interactive Terminal Demonstration Modes
- Azure Quantum Cloud Integration
- Engineering Decisions and Q# Best Practices
- What I Learned and Internship Insights
- Quickstart and Installation
- License and Author Acknowledgments
In classical computing, finding a secret
┌───────────────────────────────────────────────────────────────────────────────────┐
│ THE UNSTRUCTURED SEARCH BOTTLENECK │
│ │
│ [CLASSICAL BRUTE-FORCE: O(N)] [QUANTUM GROVER SEARCH: O(√N)] │
│ • Sequential trial-and-error • Parallel state superposition │
│ • Average queries: (N + 1) / 2 • Optimal query bound: ~π/4 * √N │
│ • N = 4 (2-bit): 2.50 queries • N = 4 (2-bit): 1 query (100.0%) │
│ • N = 8 (3-bit): 4.50 queries • N = 8 (3-bit): 2 queries (~94.5%) │
│ • N = 256 (8-bit): ~128 queries • N = 256 (8-bit): ~12 queries (10.7x) │
└───────────────────────────────────────────────────────────────────────────────────┘
Quantum PIN Cracker maps the cryptographic search space onto quantum registers and applies Grover's Algorithm:
-
2-Qubit Baseline (
$N=4$ ): Solves the search in exactly 1 query with 100% certainty. -
3-Qubit Scaling (
$N=8$ ): Solves the search in 2 queries with ~94.5% certainty, demonstrating quadratic quantum acceleration ($\mathcal{O}(\sqrt{N})$).
ms-quantum-pin-cracker/
├── docs/
│ ├── assets/ # 5 Publication-grade 300-DPI visual assets
│ │ ├── hilbert_space_rotation.png # 2D Hilbert space vector rotation
│ │ ├── overcooking_curve.png # Overcooking empirical vs theoretical curve
│ │ ├── quantum_vs_classical.png # Classical vs Quantum query comparison
│ │ ├── scaling_complexity_curve.png # Asymptotic query growth (N=4 to N=256)
│ │ └── state_vector_evolution.png # 4-stage amplitude distribution
│ └── results.md # Comprehensive laboratory benchmark report
├── scripts/
│ ├── azure_submission.py # Azure Quantum Workspace cloud submission template
│ ├── generate_charts.py # Visual chart generation script (300 DPI)
│ ├── interactive_cracker.py # Live 60FPS wave-function visualizer & race engine
│ └── run_benchmark.py # Automated Monte Carlo & overcooking test runner
├── src/
│ ├── Main.qs # EntryPoint & statistical sweep loop
│ └── Operations.qs # Superposition, Oracle & Diffusion operators
├── .gitignore # Git ignore rules for Python, QDK, and build artifacts
├── LICENSE # MIT License
├── qsharp.json # Modern QDK project manifest
├── requirements.txt # Categorized Python dependencies
└── README.md # Primary documentation
┌────────────────────────────────────────────────────────────────────────────────────────┐
│ MICROSOFT QUANTUM PIN CRACKER SUITE │
│ │
│ [1] ORCHESTRATION LAYER (Python) [2] QUANTUM CORE (Microsoft Q#) │
│ ┌─────────────────────────────────┐ ┌────────────────────────────────────────────┐ │
│ │ scripts/run_benchmark.py │ │ src/Main.qs (@EntryPoint) │ │
│ │ (Monte Carlo & Sweep Runner) │──>│ (Allocates Qubit[n], Manages Lifecycles) │ │
│ ├─────────────────────────────────┤ ├────────────────────────────────────────────┤ │
│ │ scripts/interactive_cracker.py │ │ src/Operations.qs │ │
│ │ (60FPS Tomography & Race Engine)│ │ • PrepareSuperposition (Hadamard Gates) │ │
│ ├─────────────────────────────────┤ │ • MarkTargetPIN (X + Controlled Z Oracle) │ │
│ │ scripts/generate_charts.py │ │ • ApplyDiffusion (Inversion About Mean) │ │
│ │ (5x Publication-Grade Assets) │ │ • Safe Deallocation with ResetAll │ │
│ ├─────────────────────────────────┤ └────────────────────────────────────────────┘ │
│ │ scripts/azure_submission.py │ │
│ │ (Azure Cloud QPU Dispatcher) │ │
│ └─────────────────────────────────┘ │
└────────────────────────────────────────────────────────────────────────────────────────┘
flowchart TD
subgraph Host ["Python Orchestration Layer"]
CLI["scripts/run_benchmark.py"]
GUI["scripts/interactive_cracker.py"]
Viz["scripts/generate_charts.py"]
Cloud["scripts/azure_submission.py"]
end
subgraph QSharp ["Azure Quantum QDK Engine"]
M["src/Main.qs (@EntryPoint)"]
OP["src/Operations.qs"]
subgraph Circuit ["Q# Unitary Operations"]
SUP["PrepareSuperposition (H ⊗ n)"]
ORA["MarkTargetPIN (X + Controlled-Z)"]
DIF["ApplyDiffusion (2|s⟩⟨s| - I)"]
end
end
subgraph Output ["Artifacts & Documentation"]
RES["docs/results.md"]
PNG["docs/assets/*.png (5x Charts)"]
end
CLI -->|Compiles & Executes| M
GUI -->|Live Tomography| M
M --> OP
OP --> SUP --> ORA --> DIF
CLI -->|Generates Data| RES
Viz -->|Renders 300-DPI| PNG
Cloud -.->|Optional Dispatch| AzureQ["Real Cloud QPU (IonQ / Rigetti)"]
flowchart LR
subgraph Inputs ["Registers"]
q0["|q₀⟩ = |0⟩"]
q1["|q₁⟩ = |0⟩"]
q2["|q₂⟩ = |0⟩"]
end
subgraph Superpos ["1. Superposition"]
H0["H"]
H1["H"]
H2["H"]
end
subgraph Oracle ["2. Oracle (e.g. Target |101⟩)"]
X1_pre["X"]
CZ["Controlled-Z"]
X1_post["X"]
end
subgraph Diffusion ["3. Diffusion (Inversion about Mean)"]
DH0["H"] --> DX0["X"] --> DCZ["Controlled-Z"] --> DX0_["X"] --> DH0_["H"]
DH1["H"] --> DX1["X"] -.-> DCZ -.-> DX1_["X"] --> DH1_["H"]
DH2["H"] --> DX2["X"] -.-> DCZ -.-> DX2_["X"] --> DH2_["H"]
end
subgraph Readout ["4. Measurement"]
M0["M(q₀) ➔ Bit 0"]
M1["M(q₁) ➔ Bit 1"]
M2["M(q₂) ➔ Bit 2"]
end
q0 --> H0 --> Oracle
q1 --> H1 --> X1_pre --> CZ --> X1_post --> Diffusion
q2 --> H2 --> Oracle
Diffusion --> Readout
Unlike hardcoded solutions, our Oracle supports any arbitrary 3-bit PIN (000 through 111) via
operation MarkTargetPIN3Qubits(qubits : Qubit[], target : Bool[]) : Unit is Adj + Ctl {
// 1. Bit-conditioning: flip qubits where the target bit is '0'
for i in 0..2 {
if not target[i] { X(qubits[i]); }
}
// 2. Multi-Controlled Z: inverts phase only when all control qubits are |1⟩
Controlled Z([qubits[0], qubits[1]], qubits[2]);
// 3. Uncomputation: restore basis states while retaining inverted phase
for i in 0..2 {
if not target[i] { X(qubits[i]); }
}
}Reflects state amplitudes around the mean (
operation ApplyDiffusion3Qubits(qubits : Qubit[]) : Unit is Adj + Ctl {
H(qubits[0]); H(qubits[1]); H(qubits[2]);
X(qubits[0]); X(qubits[1]); X(qubits[2]);
Controlled Z([qubits[0], qubits[1]], qubits[2]);
X(qubits[0]); X(qubits[1]); X(qubits[2]);
H(qubits[0]); H(qubits[1]); H(qubits[2]);
}sequenceDiagram
autonumber
actor Driver as Main.qs (@EntryPoint)
participant Q as Qubit Register |000⟩
participant H as Superposition (H ⊗ n)
participant Ora as Oracle (Phase Kickback)
participant Dif as Diffusion (2|s⟩⟨s| - I)
participant Meas as Measurement & ResetAll
Driver->>Q: Allocate 3 Qubits via use block (|000⟩)
Q->>H: Apply H ⊗ H ⊗ H (8 equal amplitudes = 1/√8)
loop Optimal Iterations (R = 2 for N=8)
H->>Ora: Invert phase of secret PIN |101⟩ (alpha -> -alpha)
Ora->>Dif: Invert amplitudes about mean (Constructive interference)
end
Dif->>Meas: Collapse wave function (Target amplitude ~0.97, P ~94.5%)
Meas->>Driver: Return Cracked PIN: '101'
Driver->>Q: Explicit ResetAll(qs) memory release
The probability amplitude
-
Initial Uniform Superposition: Equal distribution (
$\alpha_i = 1/\sqrt{8} \approx 0.3536, P = 12.5%$ ). -
Oracle Phase Inversion: Sign inversion of target PIN
$|101\rangle$ ($\alpha_{101} \to -0.3536$ ). -
Diffusion Iteration 1: Constructive boost to
$\alpha_{101} \approx 0.8840$ ($P \approx 78.1%$ ). -
Diffusion Iteration 2 (Optimal): Final amplification to
$\alpha_{101} \approx 0.9724$ ($P \approx 94.53%$ ).
In quantum computing, more iterations do not equal higher accuracy. Grover search operates as a geometric rotation in a 2D Hilbert subspace spanned by the uniform superposition
| Iteration Count ( |
Regime Description | State Angle ( |
Theoretical Success Rate | Empirical Success Rate | Measured Count |
|---|---|---|---|---|---|
| Under-rotated | 389 / 500 | ||||
| Optimal Peak | 485 / 500 | ||||
| Over-rotated | 156 / 500 | ||||
| Severely Decayed | 7 / 500 |
| Scale | Register | Search Space ( |
Classical Queries (Avg) | Quantum Queries ( |
Success Rate | Speedup Advantage |
|---|---|---|---|---|---|---|
| Phase 1 Baseline | 2 Qubits | 4 states (00-11) |
2.50 queries | 1 query | 100.0% | |
| Phase 2 Scaling | 3 Qubits | 8 states (000-111) |
4.50 queries | 2 queries | 95.1% |
For complete numerical tables across all 8 individual PIN states, see docs/results.md.
As key sizes scale from
- At
$N=256$ , classical search requires$\approx 128$ queries on average. - Grover search requires only
$\approx 12$ queries, demonstrating a$10.7\times$ speedup factor.
The project includes a standalone CLI demonstration engine (scripts/interactive_cracker.py) with zero-flicker 60FPS ANSI rendering:
# Mode 1: Direct quantum state vector evolution for PIN '101'
python scripts/interactive_cracker.py 101
# Mode 2: Live side-by-side race (Classical Brute-Force vs Quantum Grover)
python scripts/interactive_cracker.py --race 101
# Mode 3: Live Overcooking demonstration (k=1 to k=4 decay)
python scripts/interactive_cracker.py --overcookThe circuit is fully compatible with cloud QPU backends via Azure Quantum:
from azure.quantum import Workspace
workspace = Workspace(
resource_id="<YOUR_AZURE_QUANTUM_RESOURCE_ID>",
location="eastus"
)
# Connect to cloud simulators or QPUs (e.g., IonQ, Rigetti, Quantinuum)
target = workspace.get_targets("ionq.simulator")
print(f"Target Availability: {target.current_availability}")1. Safe Qubit Lifecycle Management with ResetAll
QDK throws strict runtime exceptions if released qubits remain entangled or in non-zero states. Every execution path enforces ResetAll(qs) immediately after measurement before exiting the use block.
2. Modularity and Educational Inline Commenting
In accordance with qsharp-code-style, the main entry point is separated from core unitary gates, and every gate is commented with the mathematical/physical "Why" (e.g., phase kickback, basis change).
3. Arbitrary PIN Support via Dynamic Basis Inversion
Rather than hardcoding |111⟩, pre/post-conditioning Controlled Z gate to mark any arbitrary PIN dynamically.
Throughout this Microsoft Quantum onboarding project:
- Quantum State Geometry: Grasped that amplitude amplification is a continuous rotation in Hilbert space, demystifying why over-rotating leads to catastrophic fidelity loss.
- Q# & QIR Toolchain: Mastered writing, compiling, and testing native Q# algorithms using modern QDK and Python bindings.
- Resource Discipline: Learned the critical importance of uncomputing ancillary states and explicitly resetting quantum registers.
- Operating System: Windows 10/11, macOS, or Linux
- Python: 3.10, 3.11, or 3.12
- Hardware: Standard CPU (runs locally on Microsoft Quantum QDK Simulator)
git clone https://github.com/rbvwolf/ms-quantum-pin-cracker.git
cd ms-quantum-pin-cracker
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txtpython scripts/run_benchmark.pypython scripts/generate_charts.pyThis project is licensed under the MIT License. See the LICENSE file for complete details.
Developed by Yiğit Mert YILMAZ
Microsoft AI Innovators Summer Internship Program (Quantum Programming Onboarding Track)
LinkedIn Profile · GitHub Profile




