Rust
snapkitty
quantum-computing
vhdl
tlm-jxcl / python /p3q_simulator.py
SNAPKITTYWEST's picture
Sync with GitHub, license metadata from LICENSE files, commercial license notice
6e9bd63 verified
Raw History Blame Contribute Delete
3.9 kB
#!/usr/bin/env python3
"""
P3Q Quantum Simulator Backend
Classical simulation of OpenQASM circuits for P4 interlock testing.
NOT a quantum computer - pure classical simulation for verification.
"""
import numpy as np
from typing import Dict, List, Tuple, Optional
from dataclasses import dataclass
from enum import IntEnum
class QSimCommandType(IntEnum):
KEYGEN_256 = 0x01
NONCE_128 = 0x02
GROVER_AES4 = 0x03
AMP_EST_LEAKAGE = 0x04
class QSimStatus(IntEnum):
SUCCESS = 0x00
TIMEOUT = 0x01
ERROR = 0x02
UNSUPPORTED = 0xFF
@dataclass
class QSimCommand:
cmd_type: QSimCommandType
qubits: int
shots: int
params: bytes
event_id: int
@dataclass
class QSimResponse:
event_id: int
status: QSimStatus
data: bytes
shots_completed: int
class P3QSimulator:
"""Classical simulator for P3Q quantum circuits."""
def __init__(self, seed: Optional[int] = None):
self.rng = np.random.default_rng(seed)
self.max_qubits = 32
def execute(self, cmd: QSimCommand) -> QSimResponse:
if cmd.qubits > self.max_qubits:
return QSimResponse(cmd.event_id, QSimStatus.ERROR, b'', 0)
if cmd.cmd_type == QSimCommandType.KEYGEN_256:
return self._sim_keygen(cmd)
elif cmd.cmd_type == QSimCommandType.NONCE_128:
return self._sim_nonce(cmd)
elif cmd.cmd_type == QSimCommandType.GROVER_AES4:
return self._sim_grover_aes4(cmd)
elif cmd.cmd_type == QSimCommandType.AMP_EST_LEAKAGE:
return self._sim_amp_est(cmd)
else:
return QSimResponse(cmd.event_id, QSimStatus.UNSUPPORTED, b'', 0)
def _sim_keygen(self, cmd: QSimCommand) -> QSimResponse:
key_bytes = self.rng.bytes(32)
return QSimResponse(cmd.event_id, QSimStatus.SUCCESS, key_bytes, 1)
def _sim_nonce(self, cmd: QSimCommand) -> QSimResponse:
nonce_bytes = self.rng.bytes(16)
return QSimResponse(cmd.event_id, QSimStatus.SUCCESS, nonce_bytes, 1)
def _sim_grover_aes4(self, cmd: QSimCommand) -> QSimResponse:
if len(cmd.params) < 32:
return QSimResponse(cmd.event_id, QSimStatus.ERROR, b'', 0)
results = bytearray()
for _ in range(min(cmd.shots, 100)):
key = self.rng.bytes(16)
results.extend(key)
return QSimResponse(cmd.event_id, QSimStatus.SUCCESS, bytes(results), len(results)//16)
def _sim_amp_est(self, cmd: QSimCommand) -> QSimResponse:
m = min(cmd.qubits - 256, 10)
phase = self.rng.integers(0, 2**m)
phase_bytes = phase.to_bytes(4, 'big')
return QSimResponse(cmd.event_id, QSimStatus.SUCCESS, phase_bytes, cmd.shots)
def test_p4_interlock():
"""Test classical-quantum handshake with simulated P4 events."""
sim = P3QSimulator(seed=42)
cmd = QSimCommand(
cmd_type=QSimCommandType.KEYGEN_256,
qubits=256, shots=1, params=b'', event_id=0x00000001
)
rsp = sim.execute(cmd)
assert rsp.status == QSimStatus.SUCCESS
assert len(rsp.data) == 32
print(f"KeyGen: {rsp.data.hex()}")
cmd = QSimCommand(
cmd_type=QSimCommandType.NONCE_128,
qubits=128, shots=1, params=b'', event_id=0x00000002
)
rsp = sim.execute(cmd)
assert rsp.status == QSimStatus.SUCCESS
assert len(rsp.data) == 16
print(f"Nonce: {rsp.data.hex()}")
pt = bytes.fromhex("00112233445566778899aabbccddeeff")
ct = bytes.fromhex("69c4e0d86a7b0430d8cdb78070b4c55a")
cmd = QSimCommand(
cmd_type=QSimCommandType.GROVER_AES4,
qubits=512, shots=10, params=pt + ct, event_id=0x00000003
)
rsp = sim.execute(cmd)
assert rsp.status == QSimStatus.SUCCESS
print(f"Grover shots: {rsp.shots_completed}")
print("All P4 interlock tests passed.")
if __name__ == "__main__":
test_p4_interlock()