import perceval as pcvl
from perceval import BS, catalog, PERM, Circuit, Processor, pdisplay, PS, BasicState
from perceval.rendering.circuit import SymbSkin, DisplayConfig
from exqalibur import FockState
import numpy as np
from numpy import pi
from typing import Optional, Dict, List, Tuple
DisplayConfig.select_skin(SymbSkin)
Challenge 4: Inversion
1 Before we begin…
= {
qubits "00": BasicState([1, 0, 1, 0]),
}
def measure2p(processor: Processor, input_state: Optional[FockState] = None) -> None:
if input_state is None:
= qubits["00"]
input_state
# We enforce the rule: the sum of photons per pair of rails must be equal to 1.
"[0,1]==1 & [2,3]==1"))
processor.set_postselection(pcvl.utils.PostSelect(0)
processor.min_detected_photons_filter(
# Finally, we take the measurement:
processor.with_input(input_state)= pcvl.algorithm.Sampler(processor)
measure2p_s
print(f"Input: {qubits_[input_state]}")
for k, v in measure2p_s.probs()["results"].items():
print(f"> {qubits_[k]}: {round(v, 2)}")
= BS.H()
H = BS.Rx
RX = BS.Ry
RY = catalog["klm cnot"].build_processor()
CNOT = PERM([1, 0])
NOT = Circuit(2, "HP") // H // (1, PS(-pi/2))
HP = lambda x: [2*x, 2*x+1]
q = pi/3
theta = pi/5 gamma
2 The final scene
It’s time to finish this dreadful series of challenges. This time, no new concepts. Just two circuits and one goal: add the two missing parts to get the expected results. Good luck… may the odds be in your favor…
= Circuit(2, "S1")
step_one = Processor("SLOS", 4)
p_step_one 0), H)
p_step_one.add(q(1), step_one)
p_step_one.add(q(1), RX(-gamma))
p_step_one.add(q(0) + q(1), CNOT)
p_step_one.add(q(2], PS(theta))
p_step_one.add([0) + q(1), CNOT)
p_step_one.add(q(0), H)
p_step_one.add(q(0), RX(theta))
p_step_one.add(q( pdisplay(p_step_one)
print("Expected result: {|1,0,0,1>: 1.0}")
=qubits["00"]) measure2p(p_step_one, input_state
= Circuit(2, "S2")
step_two = Processor("SLOS", 4)
p_step_two 0), H)
p_step_two.add(q(1), HP)
p_step_two.add(q(1), RY(theta))
p_step_two.add(q(0) + q(1), CNOT)
p_step_two.add(q(1), RY(-theta))
p_step_two.add(q(0), H)
p_step_two.add(q(1) + q(0), CNOT)
p_step_two.add(q(1), step_two)
p_step_two.add(q( pdisplay(p_step_two)
print("Expected result: {|1,0,0,1>: 0.93, |0,1,0,1>: 0.07})")
=qubits["00"]) measure2p(p_step_two, input_state
3 Flag recovery
import requests as rq
def circuit_to_list(circuit: Circuit) -> List[List[Tuple[float, float]]]:
return [[(x.real, x.imag) for x in l] for l in np.array(circuit.compute_unitary())]
= {
d "step_one": circuit_to_list(step_one),
"step_two": circuit_to_list(step_two),
}
= ...
URL # URL = "https://perceval.challenges.404ctf.fr"
+ "/healthcheck").json() rq.get(URL
+ "/challenges/4", json=d).json() rq.post(URL