Securinets Quals CTF 2023 - 0-8-4 Quantum Writeup
While on a mission, one of our teams discovered a weird suitecase locked with a 7-character password. The object had this matrix carved on its side, barely readable:
0.7056 | 0. | 0. | 0.9 |
0. | 0.5318 | 0.168 | 0. |
0. | 0.168 | -1.1246 | 0. |
0.9 | 0. | 0. | 0.7882 |
After analysis, we found out that the suitecase was emitting a transmission containing more informations, and we are convinced that the password is supposed to be the real part of the smallest eigenvalue, that needs to be calculated from the unitary matrix of the quantum circuit which corresponds to some simulation with suitcase matrix.
The transmission also stated some weird conditions: the trotter number is 1 and the simulation is done at t=1???
I don’t know what that means exacly but I figued maybe you will?
Flag format: Securinets{XXXXXXX}
Author: mida0ui
Decomposing Hamiltonian into Pauli Terms
import numpy as np
import itertools
import functools as ft
from numpy.linalg import eig
from qiskit import *
def decompose_ham_to_pauli(H):
= int(np.log2(len(H)))
n = 2 ** n
N
# Sanity Checks
if H.shape != (N, N):
raise ValueError(
"The Hamiltonian should have shape (2**n, 2**n), for any qubit number n>=1"
)
if not np.allclose(H, H.conj().T):
raise ValueError("The Hamiltonian is not Hermitian")
= np.eye(2, 2, dtype=complex)
sI = np.array([[0, 1], [1, 0]], dtype=complex)
sX = np.array([[1, 0], [0,-1]], dtype=complex)
sZ = complex(0,-1)*np.matmul(sZ,sX)
sY = [sI, sX, sY, sZ]
paulis = ['I', 'X', 'Y', 'Z']
paulis_label = []
obs = []
coeffs = []
matrix
for term in itertools.product(paulis, repeat=n):
= [pauli for pauli in term]
matrices = np.trace(ft.reduce(np.kron, matrices) @ H) / N
coeff = np.real_if_close(coeff).item()
coeff
if not np.allclose(coeff, 0):
coeffs.append(coeff)''.join([paulis_label[[i for i, x in enumerate(paulis)
obs.append(if np.all(x == t)][0]]+str(idx) for idx, t in enumerate(reversed(term))]))
reduce(np.kron, matrices))
matrix.append(ft.
return obs, coeffs , matrix
= np.array([
H0 0.7056 , 0. , 0. , 0.9 ],
[ 0. , 0.5318 , 0.168 , 0. ],
[ 0. , 0.168 , -1.1246 , 0. ],
[0.9 , 0. , 0. , 0.7882 ]
[
])
= decompose_ham_to_pauli(H0)
a, b , c print(a,b)
['I0I1', 'Z0I1', 'X0X1', 'Y0Y1', 'I0Z1', 'Z0Z1'] [0.22525, -0.43475, 0.534, -0.366, 0.39345, 0.52165]
Hamiltonian Simulation
This code applies to any Hamiltonian, not just this task
from qiskit import *
from qiskit.circuit.library import U2Gate
from qiskit.quantum_info.operators import Operator, Pauli
def exp_all_z(circuit, quantum_register, pauli_idexes, control_qubit=None, t=1):
if len(pauli_idexes)== 0:
return
# the controlled_exp(iIt) special case
if len(pauli_idexes) == 0 and control_qubit is not None:
circuit.add_register(control_qubit.register)
circuit.u1(t, control_qubit)return
# the first CNOTs
for i in range(len(pauli_idexes) - 1):
+ 1]])
circuit.cx(quantum_register[pauli_idexes[i]], quantum_register[pauli_idexes[i
# Rz gate
if control_qubit is None:
#print(pauli_idexes)
-2 * t, quantum_register[pauli_idexes[-1]])
circuit.rz(else:
circuit.add_register(control_qubit.register)-2 * t, control_qubit, quantum_register[pauli_idexes[-1]])
circuit.crz(
# the second CNOTs
for i in reversed(range(len(pauli_idexes) - 1)):
+ 1]])
circuit.cx(quantum_register[pauli_idexes[i]], quantum_register[pauli_idexes[i
def exp_pauli(pauli, quantum_register, control_qubit=None, t=1):
if len(pauli) != len(quantum_register):
raise Exception("Pauli string doesn't match to the quantum register")
= QuantumCircuit(quantum_register)
pauli_circuit = QuantumCircuit(quantum_register)
circuit_bracket = []
pauli_idexes
for i in range(len(quantum_register)):
if pauli[i] == 'I':
continue
elif pauli[i] == 'Z':
pauli_idexes.append(i)elif pauli[i] == 'X':
circuit_bracket.h(quantum_register[i])
pauli_idexes.append(i)elif pauli[i] == 'Y':
/ 2, np.pi / 2), [quantum_register[i]])
circuit_bracket.append(U2Gate(np.pi
pauli_idexes.append(i)
&= circuit_bracket
pauli_circuit
exp_all_z(pauli_circuit, quantum_register, pauli_idexes, control_qubit, t)&= circuit_bracket
pauli_circuit
return pauli_circuit
def hamiltonian_simulation(hamiltonian, quantum_register=None, control_qubit=None, t=1, trotter_number=1):
if quantum_register is None:
= QuantumRegister(len(list(hamiltonian.keys())[0]))
quantum_register if control_qubit in quantum_register:
raise Exception("the control qubit is in the target register")
= t / trotter_number
delta_t = QuantumCircuit(quantum_register)
exp_hamiltonian = QuantumCircuit(quantum_register)
exp_delta_t
for pauli in hamiltonian:
= hamiltonian[pauli]
weight &= exp_pauli(pauli, quantum_register, control_qubit, weight * delta_t)
exp_delta_t
for i in range(trotter_number):
&= exp_delta_t
exp_hamiltonian
return exp_hamiltonian
= {"II": 0.22525, "ZI": -0.43475, "XX": 0.534, "YY": -0.366, "IZ": 0.39345, "ZZ": 0.52165}
hamiltonian
= QuantumRegister(2, 'q')
quantum_register = hamiltonian_simulation(hamiltonian, quantum_register, t= 1)
circuit
print(circuit)
= Operator(circuit)
op = op.to_matrix()
hamiltonian_matrix
=eig(hamiltonian_matrix)
w,vprint('E-value:', w)
print('E-vector', v)
w.sort()print(w[0])
┌────────────┐┌───┐ ┌───┐┌─────────────┐ »
q_0: ┤ Rz(0.8695) ├┤ H ├──■──────────────────■──┤ H ├┤ U2(π/2,π/2) ├──■──»
└───┬───┬────┘└───┘┌─┴─┐┌────────────┐┌─┴─┐├───┤├─────────────┤┌─┴─┐»
q_1: ────┤ H ├──────────┤ X ├┤ Rz(-1.068) ├┤ X ├┤ H ├┤ U2(π/2,π/2) ├┤ X ├»
└───┘ └───┘└────────────┘└───┘└───┘└─────────────┘└───┘»
« ┌─────────────┐
«q_0: ───────────────■──┤ U2(π/2,π/2) ├─────────────────■───────────────────■──
« ┌───────────┐┌─┴─┐├─────────────┤┌─────────────┐┌─┴─┐┌─────────────┐┌─┴─┐
«q_1: ┤ Rz(0.732) ├┤ X ├┤ U2(π/2,π/2) ├┤ Rz(-0.7869) ├┤ X ├┤ Rz(-1.0433) ├┤ X ├
« └───────────┘└───┘└─────────────┘└─────────────┘└───┘└─────────────┘└───┘
E-value: [0.92902529-0.37001624j 0.14792497+0.98899859j 0.20660057-0.97842537j
0.94942492+0.31399415j]
E-vector [[ 7.18591252e-01+0.00000000e+00j 4.70253625e-01+5.12335965e-01j
-2.50284233e-17-2.85363428e-17j 1.45587101e-16+5.50711599e-17j]
[-2.11885760e-17+1.21782362e-17j 2.40755729e-17+7.62058536e-18j
-1.12796042e-01+4.66112698e-03j 9.93607230e-01+0.00000000e+00j]
[-6.58636545e-18+4.88403480e-17j 4.17816855e-17-2.91119216e-17j
9.93607230e-01+0.00000000e+00j 1.12796042e-01+4.66112698e-03j]
[-4.70253625e-01+5.12335965e-01j 7.18591252e-01+0.00000000e+00j
9.35231913e-17-7.66091811e-18j -5.45225695e-17+9.51397128e-17j]]
(0.14792496868373806+0.9889985862679043j)
Flag: Securinets{0.14792}
gg idek for solving this challenge!
- Title: Securinets Quals CTF 2023 - 0-8-4 Quantum Writeup
- Author: ADM-MIDA0UI
- Created at: 2023-08-06 20:00:00
- Updated at: 2024-05-17 21:05:17
- Link: https://admida0ui.de/2023/08/06/0-8-4/
- License: This work is licensed under CC BY-NC-SA 4.0.