Download python/simulators/qiskit_simulation.py from Snapkitty/topological-quantum-computer: direct link, hf CLI and curl.
- Browser
- Download file 12.8 kB
-
https://huggingface.co/Snapkitty/topological-quantum-computer/resolve/main/python/simulators/qiskit_simulation.py
- Command line
-
hf download hf://Snapkitty/topological-quantum-computer/python/simulators/qiskit_simulation.py
-
curl -L -o qiskit_simulation.py https://huggingface.co/Snapkitty/topological-quantum-computer/resolve/main/python/simulators/qiskit_simulation.py
12.8 kB
| """ | |
| Qiskit Aer Simulator for SHA-520 Grover Circuits | |
| Provides interface to Qiskit Aer for realistic noise modeling | |
| and resource estimation on current quantum devices. | |
| Optional dependency: gracefully handles absence of Qiskit. | |
| """ | |
| from __future__ import annotations | |
| import sys | |
| import time | |
| import math | |
| from typing import Dict, Any, Optional, List, Tuple, TYPE_CHECKING | |
| QISKIT_AVAILABLE = False | |
| try: | |
| from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister | |
| from qiskit_aer import AerSimulator | |
| from qiskit_aer.noise import NoiseModel, depolarizing_error, amplitude_damping_error | |
| QISKIT_AVAILABLE = True | |
| except ImportError: | |
| QuantumCircuit = None # type: ignore | |
| QuantumRegister = None # type: ignore | |
| ClassicalRegister = None # type: ignore | |
| AerSimulator = None # type: ignore | |
| NoiseModel = None # type: ignore | |
| depolarizing_error = None # type: ignore | |
| amplitude_damping_error = None # type: ignore | |
| QuantumRegister = None # type: ignore | |
| NoiseModel = None # type: ignore | |
| if TYPE_CHECKING: | |
| from qiskit import QuantumCircuit, QuantumRegister | |
| from qiskit_aer.noise import NoiseModel | |
| def run_grover_simulation( | |
| rounds: int = 4, | |
| target_bits: int = 32, | |
| noise_model: Optional[str] = None, | |
| shots: int = 1024, | |
| seed: int = 42, | |
| ) -> Dict[str, Any]: | |
| """Run Grover SHA-520 simulation with Qiskit Aer. | |
| Parameters | |
| ---------- | |
| rounds : int | |
| SHA-520 round count | |
| target_bits : int | |
| Number of bits in search space | |
| noise_model : str, optional | |
| Noise model: None (ideal), 'depolarizing', 'realistic' | |
| shots : int | |
| Number of measurement shots | |
| seed : int | |
| Random seed | |
| Returns | |
| ------- | |
| dict | |
| Simulation results including counts, timing, resource metrics | |
| Raises | |
| ------ | |
| ImportError | |
| If Qiskit is not installed | |
| """ | |
| if not QISKIT_AVAILABLE: | |
| raise ImportError( | |
| "Qiskit not available. Install with: pip install qiskit qiskit-aer" | |
| ) | |
| # Build circuit | |
| circuit = _build_grover_circuit(target_bits, rounds) | |
| # Create simulator | |
| if noise_model is None: | |
| sim = AerSimulator(method='statevector', seed_simulator=seed) | |
| else: | |
| noise = _create_noise_model(noise_model) | |
| sim = AerSimulator(method='qasm', noise_model=noise, seed_simulator=seed) | |
| # Run simulation | |
| start_time = time.time() | |
| job = sim.run(circuit, shots=shots) | |
| result = job.result() | |
| elapsed = time.time() - start_time | |
| # Extract results | |
| counts = result.get_counts(circuit) | |
| # Analyze results | |
| analysis = _analyze_grover_results(counts, target_bits) | |
| return { | |
| "rounds": rounds, | |
| "target_bits": target_bits, | |
| "noise_model": noise_model, | |
| "shots": shots, | |
| "runtime_sec": elapsed, | |
| "circuit_depth": circuit.depth(), | |
| "circuit_width": circuit.num_qubits, | |
| "circuit_size": len(circuit.data), | |
| "counts": counts, | |
| "success_rate": analysis["success_rate"], | |
| "top_outcome": analysis["top_outcome"], | |
| "entropy": analysis["entropy"], | |
| "fidelity": analysis["fidelity"], | |
| } | |
| def _build_grover_circuit(n_qubits: int, rounds: int) -> "QuantumCircuit": | |
| """Build Grover circuit for SHA-520 preimage search. | |
| Parameters | |
| ---------- | |
| n_qubits : int | |
| Number of qubits in search space | |
| rounds : int | |
| SHA-520 rounds (for resource scaling) | |
| Returns | |
| ------- | |
| QuantumCircuit | |
| Qiskit circuit implementing Grover | |
| """ | |
| # Create quantum and classical registers | |
| q = QuantumRegister(n_qubits, 'q') | |
| c = ClassicalRegister(n_qubits, 'c') | |
| circuit = QuantumCircuit(q, c) | |
| # Compute Grover iterations | |
| iterations = int((math.pi / 4.0) * math.sqrt(2 ** n_qubits)) | |
| # Initialize superposition | |
| for i in range(n_qubits): | |
| circuit.h(q[i]) | |
| # Amplitude amplification iterations | |
| for _ in range(min(iterations, 5)): # Cap iterations for practical simulation | |
| # Oracle (simplified: mark state |00...01⟩) | |
| circuit.barrier() | |
| _add_oracle(circuit, q, n_qubits) | |
| # Diffusion operator | |
| circuit.barrier() | |
| _add_diffusion(circuit, q, n_qubits) | |
| # Measurement | |
| circuit.measure(q, c) | |
| return circuit | |
| def _add_oracle( | |
| circuit: "QuantumCircuit", | |
| qubits: "QuantumRegister", | |
| n_qubits: int, | |
| ) -> None: | |
| """Add oracle that marks |00...01⟩ state. | |
| Parameters | |
| ---------- | |
| circuit : QuantumCircuit | |
| Circuit to modify | |
| qubits : QuantumRegister | |
| Quantum register | |
| n_qubits : int | |
| Number of qubits | |
| """ | |
| # Mark |00...01⟩: apply Z only if all qubits except last are 0 | |
| # and last qubit is 1 | |
| # Flip last qubit (so we mark |00...00⟩ in computational basis) | |
| circuit.x(qubits[n_qubits - 1]) | |
| # Multi-controlled Z | |
| if n_qubits <= 3: | |
| # For small n, use direct implementation | |
| for i in range(n_qubits - 1): | |
| circuit.x(qubits[i]) | |
| # Apply multi-controlled-Z (decomposed from Toffoli chain if needed) | |
| if n_qubits == 2: | |
| circuit.h(qubits[1]) | |
| circuit.cx(qubits[0], qubits[1]) | |
| circuit.h(qubits[1]) | |
| elif n_qubits == 3: | |
| circuit.h(qubits[2]) | |
| circuit.mcx(list(qubits[:2]), qubits[2]) | |
| circuit.h(qubits[2]) | |
| else: | |
| # Multi-controlled Z via decomposition | |
| circuit.mcp(math.pi, list(qubits[:-1]), qubits[-1]) | |
| for i in range(n_qubits - 1): | |
| circuit.x(qubits[i]) | |
| circuit.x(qubits[n_qubits - 1]) | |
| def _add_diffusion( | |
| circuit: "QuantumCircuit", | |
| qubits: "QuantumRegister", | |
| n_qubits: int, | |
| ) -> None: | |
| """Add Grover diffusion operator. | |
| Implements D = 2|s⟩⟨s| - I. | |
| Parameters | |
| ---------- | |
| circuit : QuantumCircuit | |
| Circuit to modify | |
| qubits : QuantumRegister | |
| Quantum register | |
| n_qubits : int | |
| Number of qubits | |
| """ | |
| # Hadamard | |
| for i in range(n_qubits): | |
| circuit.h(qubits[i]) | |
| # X | |
| for i in range(n_qubits): | |
| circuit.x(qubits[i]) | |
| # Multi-controlled Z | |
| if n_qubits == 2: | |
| circuit.h(qubits[1]) | |
| circuit.cx(qubits[0], qubits[1]) | |
| circuit.h(qubits[1]) | |
| elif n_qubits <= 4: | |
| circuit.h(qubits[-1]) | |
| circuit.mcx(list(qubits[:-1]), qubits[-1]) | |
| circuit.h(qubits[-1]) | |
| else: | |
| circuit.mcp(math.pi, list(qubits[:-1]), qubits[-1]) | |
| # X | |
| for i in range(n_qubits): | |
| circuit.x(qubits[i]) | |
| # Hadamard | |
| for i in range(n_qubits): | |
| circuit.h(qubits[i]) | |
| def _create_noise_model(noise_type: str) -> Optional["NoiseModel"]: | |
| """Create noise model for simulation. | |
| Parameters | |
| ---------- | |
| noise_type : str | |
| Type: 'depolarizing', 'realistic', or None | |
| Returns | |
| ------- | |
| NoiseModel or None | |
| Qiskit NoiseModel | |
| """ | |
| if noise_type is None: | |
| return None | |
| noise = NoiseModel() | |
| if noise_type == 'depolarizing': | |
| # Single-qubit depolarizing noise (1% error) | |
| p_sq = 0.01 | |
| noise.add_all_qubit_quantum_error( | |
| depolarizing_error(p_sq, 1), ['h', 'x', 'y', 'z', 'rx', 'ry', 'rz'] | |
| ) | |
| # Two-qubit depolarizing noise (2% error) | |
| p_2q = 0.02 | |
| noise.add_all_qubit_quantum_error( | |
| depolarizing_error(p_2q, 2), ['cx', 'cz', 'swap'] | |
| ) | |
| elif noise_type == 'realistic': | |
| # Depolarizing + amplitude damping | |
| p_sq = 0.005 | |
| p_2q = 0.01 | |
| decay_rate = 0.001 | |
| # Single-qubit errors | |
| error_1q = depolarizing_error(p_sq, 1).compose( | |
| amplitude_damping_error(decay_rate) | |
| ) | |
| noise.add_all_qubit_quantum_error( | |
| error_1q, ['h', 'x', 'y', 'z', 'rx', 'ry', 'rz'] | |
| ) | |
| # Two-qubit errors | |
| error_2q = depolarizing_error(p_2q, 2) | |
| noise.add_all_qubit_quantum_error(error_2q, ['cx', 'cz', 'swap']) | |
| return noise | |
| def _analyze_grover_results( | |
| counts: Dict[str, int], | |
| target_bits: int, | |
| ) -> Dict[str, Any]: | |
| """Analyze Grover measurement results. | |
| Parameters | |
| ---------- | |
| counts : dict | |
| Measurement counts from Qiskit | |
| target_bits : int | |
| Number of qubits used | |
| Returns | |
| ------- | |
| dict | |
| Analysis metrics | |
| """ | |
| total_shots = sum(counts.values()) | |
| # Find outcome with highest probability | |
| max_outcome = max(counts, key=counts.get) | |
| max_count = counts[max_outcome] | |
| # Compute entropy | |
| import math | |
| probs = [c / total_shots for c in counts.values()] | |
| entropy = -sum(p * math.log2(p) for p in probs if p > 0) | |
| # Success rate: assume marked state is |00...01⟩ | |
| marked_state = '0' * (target_bits - 1) + '1' | |
| marked_count = counts.get(marked_state, 0) | |
| success_rate = marked_count / total_shots | |
| # Fidelity: uniformity in marked state vs others | |
| # For ideal Grover with one marked state, expect concentrated probability | |
| expected_prob = 1.0 / (2 ** target_bits) | |
| actual_prob_marked = marked_count / total_shots | |
| fidelity = min(1.0, actual_prob_marked / max(expected_prob, 0.01)) | |
| return { | |
| "success_rate": success_rate, | |
| "top_outcome": max_outcome, | |
| "top_probability": max_count / total_shots, | |
| "entropy": entropy, | |
| "fidelity": fidelity, | |
| "n_unique_outcomes": len(counts), | |
| } | |
| def estimate_circuit_resources( | |
| rounds: int, | |
| target_bits: int, | |
| ) -> Dict[str, Any]: | |
| """Estimate circuit resources without running simulation. | |
| Parameters | |
| ---------- | |
| rounds : int | |
| SHA-520 rounds | |
| target_bits : int | |
| Bits in search space | |
| Returns | |
| ------- | |
| dict | |
| Resource estimates | |
| """ | |
| iterations = int((math.pi / 4.0) * math.sqrt(2 ** target_bits)) | |
| # Oracle resources scale with rounds | |
| oracle_gates = 50 + rounds * 10 | |
| oracle_depth = 20 + rounds | |
| # Diffusion resources | |
| diffusion_gates = 4 * target_bits + 10 | |
| diffusion_depth = target_bits + 10 | |
| # Total for one iteration | |
| iter_gates = oracle_gates + diffusion_gates | |
| iter_depth = oracle_depth + diffusion_depth | |
| # Total | |
| total_gates = iterations * iter_gates + target_bits # +target_bits for initialization | |
| total_depth = iterations * iter_depth + target_bits | |
| return { | |
| "rounds": rounds, | |
| "target_bits": target_bits, | |
| "grover_iterations": iterations, | |
| "oracle_gates": oracle_gates, | |
| "oracle_depth": oracle_depth, | |
| "diffusion_gates": diffusion_gates, | |
| "diffusion_depth": diffusion_depth, | |
| "total_gates": total_gates, | |
| "total_depth": total_depth, | |
| "total_qubits": target_bits, | |
| } | |
| if __name__ == "__main__": | |
| print("Qiskit Aer Simulator for SHA-520 Grover") | |
| print("=" * 60) | |
| if not QISKIT_AVAILABLE: | |
| print("Qiskit not available. Install with:") | |
| print(" pip install qiskit qiskit-aer") | |
| print("\nDisplaying resource estimates instead...") | |
| # Resource estimates | |
| for bits in [8, 16, 32]: | |
| resources = estimate_circuit_resources(rounds=4, target_bits=bits) | |
| print(f"\n4-round SHA-520, {bits}-bit search:") | |
| print(f" Grover iterations: {resources['grover_iterations']}") | |
| print(f" Total circuit depth: {resources['total_depth']}") | |
| print(f" Total gates: {resources['total_gates']}") | |
| print(f" Qubits: {resources['total_qubits']}") | |
| # Try simulation if Qiskit available | |
| if QISKIT_AVAILABLE: | |
| print("\n" + "=" * 60) | |
| print("Running simulations...") | |
| try: | |
| result = run_grover_simulation( | |
| rounds=4, | |
| target_bits=8, | |
| noise_model=None, | |
| shots=1024, | |
| ) | |
| print(f"\nSimulation completed ({result['runtime_sec']:.2f}s):") | |
| print(f" Circuit depth: {result['circuit_depth']}") | |
| print(f" Circuit width: {result['circuit_width']}") | |
| print(f" Success rate: {result['success_rate']:.2%}") | |
| print(f" Top outcome: {result['top_outcome']}") | |
| print(f" Fidelity: {result['fidelity']:.3f}") | |
| except Exception as e: | |
| print(f"Simulation failed: {e}") | |