├── .gitignore
├── BB84QKD
├── BB84Alice.py
├── BB84Bob.py
├── BB84Teleportation
│ ├── BB84AliceTeleportation.py
│ ├── BB84BobTeleportation.py
│ └── teleportation.py
└── readme.md
├── Basic_Examples
├── EPR_Teleportation
│ ├── Test_Alice.py
│ ├── Test_Bob.py
│ ├── readme.md
│ └── teleportation.py
├── States
│ ├── Bellstates.py
│ ├── nPartyGHZstates.py
│ └── readme.md
└── readme.md
├── DeviceIndependentQKD
├── README.md
├── diqkd.py
└── utils.py
├── QuantumAnonTransmission
├── anon_trans.py
├── readme.md
└── utils.py
├── QuantumBitCommitment
├── A0.py
├── A1.py
├── A2.py
├── B0.py
├── B1.py
├── B2.py
├── BitCommitment_readme.md
└── commitmentstart.sh
├── QuantumCheques
├── A_party.py
├── B_party.py
├── README.md
├── figures
│ ├── team.jpg
│ └── title.jpg
├── one_way_function.py
├── quantum_cheque.py
├── quantum_cheques_presentation.pdf
├── setup.py
└── swap_test.py
├── QuantumCoinFlipping
├── CoinFlippingAlice.py
├── CoinFlippingBob.py
└── readme.md
├── QuantumCoinFlippingPappa
├── 1_Honest_Participants
│ ├── aliceCoin.py
│ ├── bobCoin.py
│ ├── config.txt
│ └── run.sh
├── 2_Cheating_Alice
│ ├── aliceCoin.py
│ ├── bobCoin.py
│ ├── config.txt
│ └── run.sh
├── 3_Cheating_Bob
│ ├── aliceCoin.py
│ ├── bobCoin.py
│ ├── config.txt
│ └── run.sh
├── 4_Ideal_Coin_Flipping
│ ├── aliceCoin.py
│ ├── bobCoin.py
│ └── run.sh
├── README.md
└── __init__.py
├── QuantumLeaderElection
├── README.txt
├── fourPartyLeaderElection.py
└── nPartyLeaderElection.py
├── QuantumNumberGeneration
├── quantum_number_generation.py
└── readme.md
├── QuantumStateTeleportation
├── quantum_state_teleportation.py
└── readme.md
├── QuantumToken
├── QuantumToken.md
├── QuantumTokenBank.py
├── QuantumTokenClient.py
└── QuantumTokenMerchant.py
├── README.md
├── UBQC
├── README.md
├── angle.py
├── circuit_projetq.py
├── circuits
│ ├── circuit1.json
│ ├── circuit2.json
│ ├── circuit3.json
│ ├── circuit4.json
│ ├── circuit5.json
│ ├── circuit6.json
│ ├── circuit7.json
│ ├── circuit8.json
│ ├── circuit9.json
│ ├── circuitCNOT.json
│ ├── circuitH.json
│ ├── circuitRX.json
│ ├── circuitRZ.json
│ ├── circuitRZ1.json
│ ├── circuitRZ_test.json
│ ├── circuitSWAP.json
│ └── circuitT.json
├── clientMBQC.py
├── clientUBQC.py
├── docs
│ ├── im1.svg
│ ├── im1.tex
│ ├── im10.svg
│ ├── im10.tex
│ ├── im11.svg
│ ├── im11.tex
│ ├── im12.svg
│ ├── im12.tex
│ ├── im13.svg
│ ├── im13.tex
│ ├── im14.svg
│ ├── im14.tex
│ ├── im15.svg
│ ├── im15.tex
│ ├── im16.svg
│ ├── im16.tex
│ ├── im16bis.svg
│ ├── im16bis.tex
│ ├── im17.svg
│ ├── im17.tex
│ ├── im18.svg
│ ├── im18.tex
│ ├── im19.svg
│ ├── im19.tex
│ ├── im2.svg
│ ├── im2.tex
│ ├── im20.svg
│ ├── im20.tex
│ ├── im21.svg
│ ├── im21.tex
│ ├── im3.svg
│ ├── im3.tex
│ ├── im4.svg
│ ├── im4.tex
│ ├── im5.svg
│ ├── im5.tex
│ ├── im6.svg
│ ├── im6.tex
│ ├── im7.svg
│ ├── im7.tex
│ ├── im8.svg
│ ├── im8.tex
│ ├── im9.svg
│ ├── im9.tex
│ ├── readme.tex
│ ├── script.sh
│ └── svgs
│ │ ├── 17de0d63787245126004f04d9b080bea.svg
│ │ ├── 3369485e5fd1f281f6f6a547fa661280.svg
│ │ ├── 4fa3ac8fe93c68be3fe7ab53bdeb2efa.svg
│ │ ├── 59efeb0f4f5d484a9b8a404d5bdac544.svg
│ │ ├── 5fc34debe9fe8c2254296f70d46bf923.svg
│ │ └── f50853d41be7d55874e952eb0d80c53e.svg
├── flow.py
├── graph.py
├── mbqc.py
├── measurement.py
├── runMBQC.sh
├── runUBQC.sh
├── script.sh
├── serverMBQC.py
├── serverUBQC.py
└── settings.json
├── UnclonableEncryption
├── readme.org
└── unclonableencryption.py
├── WeakStringErasure
├── WSEAlice.py
├── WSEBob.py
└── readme.md
├── WiesnerQuantumMoney
├── WQM1.py
├── WQM2.py
└── WQMreadme.md
└── shell.nix
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | *.egg-info/
24 | .installed.cfg
25 | *.egg
26 | MANIFEST
27 |
28 | # PyInstaller
29 | # Usually these files are written by a python script from a template
30 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
31 | *.manifest
32 | *.spec
33 |
34 | # Installer logs
35 | pip-log.txt
36 | pip-delete-this-directory.txt
37 |
38 | # Unit test / coverage reports
39 | htmlcov/
40 | .tox/
41 | .coverage
42 | .coverage.*
43 | .cache
44 | nosetests.xml
45 | coverage.xml
46 | *.cover
47 | .hypothesis/
48 | .pytest_cache/
49 |
50 | # Translations
51 | *.mo
52 | *.pot
53 |
54 | # Django stuff:
55 | *.log
56 | local_settings.py
57 | db.sqlite3
58 |
59 | # Flask stuff:
60 | instance/
61 | .webassets-cache
62 |
63 | # Scrapy stuff:
64 | .scrapy
65 |
66 | # Sphinx documentation
67 | docs/_build/
68 |
69 | # PyBuilder
70 | target/
71 |
72 | # Jupyter Notebook
73 | .ipynb_checkpoints
74 |
75 | # pyenv
76 | .python-version
77 |
78 | # celery beat schedule file
79 | celerybeat-schedule
80 |
81 | # SageMath parsed files
82 | *.sage.py
83 |
84 | # Environments
85 | .env
86 | .venv
87 | env/
88 | venv/
89 | ENV/
90 | env.bak/
91 | venv.bak/
92 |
93 | # Spyder project settings
94 | .spyderproject
95 | .spyproject
96 |
97 | # Rope project settings
98 | .ropeproject
99 |
100 | # mkdocs documentation
101 | /site
102 |
103 | # mypy
104 | .mypy_cache/
105 |
--------------------------------------------------------------------------------
/BB84QKD/BB84Alice.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from math import ceil, log, sqrt
3 | from random import randint, random, sample
4 | from multiprocessing import pool
5 | from cqc.pythonLib import CQCConnection, qubit
6 |
7 |
8 |
9 | bits_alice = []
10 | basis_alice = []
11 | test = []
12 | mesaj = []
13 |
14 |
15 |
16 | def preperation_Alice():
17 | with CQCConnection("Alice") as Alice:
18 | for i in range(100):
19 | random_bits_alice = randint(0,1)
20 | random_basis_alice = randint(0,1)
21 | bits_alice.append(random_bits_alice)
22 | basis_alice.append(random_basis_alice)
23 |
24 | q = qubit(Alice)
25 |
26 | if random_bits_alice == 1:
27 | q.X()
28 |
29 | if random_basis_alice == 1:
30 | q.H()
31 | Alice.sendQubit(q, "Bob")
32 |
33 | '''
34 | if (random_basis_alice == 0 ):
35 | basis_alice.append('X')
36 | elif (random_basis_alice == 1):
37 | basis_alice.append('Z')
38 | '''
39 | test.append(random_bits_alice)
40 | Alice.flush()
41 | Alice.sendClassical("Bob", basis_alice)
42 | print ("bits of alice:", bits_alice)
43 | print("sended basis by alice",basis_alice)
44 |
45 | if __name__ == "__main__":
46 |
47 | preperation_Alice()
48 |
--------------------------------------------------------------------------------
/BB84QKD/BB84Bob.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from math import ceil, log, sqrt
3 | from random import randint, random, sample
4 | from multiprocessing import Pool
5 | from cqc.pythonLib import CQCConnection, qubit
6 |
7 | correct_basis = []
8 | correct_key = []
9 | bits_alice = []
10 | basis_alice = []
11 | bits_bob = []
12 | basis_bob = []
13 | received = []
14 |
15 | def preparation_Bob():
16 | with CQCConnection("Bob") as Bob:
17 | for i in range(100):
18 |
19 | q = Bob.recvQubit()
20 | random_basis_bob = randint(0,1)
21 | basis_bob.append(random_basis_bob)
22 | if random_basis_bob == 1:
23 | q.H()
24 | m = q.measure()
25 | received.append(m)
26 |
27 | r = Bob.recvClassical()
28 | basis_alice[:] = list(r)
29 |
30 | print ("basis of bob ", basis_bob)
31 | print ("measurement results of bob: ",received)
32 | print ("received basis by bob ",basis_alice)
33 |
34 | def calculate():
35 | error = 0
36 | for i in range(len(received)):
37 | if (basis_alice[i] == basis_bob[i]):
38 | correct_basis.append(i)
39 | correct_key.append(received[i])
40 | else:
41 | error = error + 1
42 | print ("Correct Basis: ", correct_basis)
43 | print ("Correct Key :", correct_key)
44 | print ("error:", error)
45 | error_percentage = error/len(received) # maximum value is 1
46 | print("error_percentage", error_percentage)
47 | size = ceil(sqrt(len(correct_basis)))
48 | print ("size: ", size)
49 | global qber
50 | global qber2
51 | qber = error_percentage/size # lies btween 0 and 1
52 | print("qber:", qber)
53 |
54 | def secureKeyRate(x):
55 | return ((-x)*log(x, 2) - (1-x)*log(1-x, 2))
56 |
57 |
58 | if __name__ == "__main__":
59 |
60 | preparation_Bob()
61 | calculate()
62 |
63 |
--------------------------------------------------------------------------------
/BB84QKD/BB84Teleportation/BB84AliceTeleportation.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from math import ceil, log, sqrt
3 | from random import randint, random, sample
4 | from multiprocessing import pool
5 | from cqc.pythonLib import CQCConnection, qubit
6 | from teleportation import send_teleportation
7 | from time import sleep
8 |
9 |
10 | bits_alice = []
11 | basis_alice = []
12 | test = []
13 | mesaj = []
14 | wait = 1
15 |
16 |
17 | def preperation_Alice():
18 | with CQCConnection("Alice") as location:
19 | for i in range(10):
20 | random_bits_alice = randint(0,1)
21 | random_basis_alice = randint(0,1)
22 | bits_alice.append(random_bits_alice)
23 | basis_alice.append(random_basis_alice)
24 |
25 | q = qubit(location)
26 | if random_bits_alice == 1:
27 | q.X()
28 |
29 | if random_basis_alice == 1:
30 | q.H()
31 | #Alice.sendQubit(q, "Bob")
32 | send_teleportation(q,location,'Bob')
33 | test.append(random_bits_alice)
34 | location.flush()
35 | print ("Step 1 ok")
36 | sleep(wait)
37 | location.sendClassical("Bob", basis_alice)
38 | print ("Step 2 ok")
39 | print ("bits of alice:", bits_alice)
40 | print("sended basis by alice",basis_alice)
41 |
42 | if __name__ == "__main__":
43 |
44 | preperation_Alice()
45 |
46 |
--------------------------------------------------------------------------------
/BB84QKD/BB84Teleportation/BB84BobTeleportation.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from math import ceil, log, sqrt
3 | from random import randint, random, sample
4 | from multiprocessing import Pool
5 | from cqc.pythonLib import CQCConnection, qubit
6 | from teleportation import accept_teleportation
7 | from time import sleep
8 |
9 | correct_basis = []
10 | correct_key = []
11 | bits_alice = []
12 | basis_alice = []
13 | bits_bob = []
14 | basis_bob = []
15 | received = []
16 | wait = 1
17 |
18 | def preparation_Bob():
19 | with CQCConnection("Bob") as location:
20 | for i in range(10):
21 |
22 | #q = Bob.recvQubit()
23 | q = accept_teleportation(location)
24 | random_basis_bob = randint(0,1)
25 | basis_bob.append(random_basis_bob)
26 | if random_basis_bob == 1:
27 | q.H()
28 | m = q.measure()
29 | received.append(m)
30 | sleep(wait)
31 | r = location.recvClassical()
32 | basis_alice[:] = list(r)
33 |
34 | print ("basis of bob ", basis_bob)
35 | print ("measurement results of bob: ",received)
36 | print ("received basis by bob ",basis_alice)
37 |
38 | def calculate():
39 | error = 0
40 | for i in range(len(received)):
41 | if (basis_alice[i] == basis_bob[i]):
42 | correct_basis.append(i)
43 | correct_key.append(received[i])
44 | else:
45 | error = error + 1
46 | print ("Correct Basis: ", correct_basis)
47 | print ("Correct Key :", correct_key)
48 | print ("error:", error)
49 | error_percentage = error/len(received) # maximum value is 1
50 | print("error_percentage", error_percentage)
51 | size = ceil(sqrt(len(correct_basis)))
52 | print ("size: ", size)
53 | global qber
54 | global qber2
55 | qber = error_percentage/size # lies between 0 and 1
56 | print("qber:", qber)
57 |
58 |
59 | if __name__ == "__main__":
60 |
61 | preparation_Bob()
62 | print ("Preparation is ok :)")
63 | calculate()
64 |
--------------------------------------------------------------------------------
/BB84QKD/BB84Teleportation/teleportation.py:
--------------------------------------------------------------------------------
1 | from cqc.pythonLib import CQCConnection, qubit
2 | from time import sleep
3 |
4 | wait = 2
5 | def send_teleportation(q,sender,receiver):
6 | qA = sender.createEPR(receiver)
7 | #q = qubit(location)
8 | q.cnot(qA)
9 | q.H()
10 | a = q.measure()
11 | b = qA.measure()
12 | # print('Corrections were sent at', location, ':', [a, b]) #
13 | # print("location,location_string, location2, location_string2", location,location_string,location2,location_string2)
14 | sender.sendClassical(receiver, [a, b])
15 | print('Corrections were sent at', sender, ':', [a, b]) #
16 | return [a,b]
17 |
18 |
19 |
20 | def accept_teleportation(receiver):
21 | qB = receiver.recvEPR()
22 | message = list(receiver.recvClassical())
23 | print("data: ", message)
24 | if message[1] == 1:
25 | qB.X()
26 | if message[0] == 1:
27 | qB.Z()
28 |
29 |
30 | return qB
31 |
32 |
33 |
34 | # if __name__ == '__main__':
35 |
36 | # with CQCConnection("Alice") as location:
37 | # q = qubit(location)
38 | # send_teleportation(q,location,'Bob')
39 |
--------------------------------------------------------------------------------
/BB84QKD/readme.md:
--------------------------------------------------------------------------------
1 | In this example BB84 protocol was implemented with using CQC library (Simulaqron) and Pyhton
2 |
3 | In the BB84Alice.py part:
4 |
5 | 1)Alice produces a secret key (100 bit)
6 |
7 | 2)For encoding the secret key ALice produce her basis (100 basis)
8 |
9 | 3)Then Alice creates a fresh qubit.
10 |
11 | 3.1) If Alice's bits equal 1 --> Alice applies X gate for her qubit
12 |
13 | 3.2) If Alice's basis equal 1 --> Alice applies H gate for her qubit
14 |
15 | 3.3) And ALice sends her qubit to Bob
16 |
17 |
18 | 4) Alice send her basis to Bob
19 |
20 | In the BB84Bob.py part:
21 |
22 | 1)Bob receive qubit from Alice
23 |
24 | 2)Bob produces his basis and he saves in the basis_bob list
25 |
26 | 2.1)If Bob basis equal to 1-->Bob apply H gate for his qubit
27 |
28 | 3)Bob measures the qubit and saves in the received list
29 |
30 | 4)Bob receive classical message from Alice and he saves in the basis_alice list
31 |
32 |
33 | (Note: Dont worry before the saving in basis_alice list used basis_alice[:]
34 | because basis_alice is a global variable)
35 |
36 | In the calculation function:
37 |
38 | 1)If alice_basis and bob_basis equal saved the correct values
39 | and for testing save the correct index
40 |
41 | 1.a)If it is not equal than this is an arror
42 |
43 | 2)And some calculaton such as error percentage
44 |
45 | NB: To allow processing the example (100 qubits sent) you should set
46 | simulaqron number of qubits to 100 to be on the safe side and not
47 | risking exhausting the number of available qubits at any of the
48 | nodes. This can be done with the following command:
49 |
50 | simulaqron set max-qubits 100
51 |
52 | before starting simulaqron.
--------------------------------------------------------------------------------
/Basic_Examples/EPR_Teleportation/Test_Alice.py:
--------------------------------------------------------------------------------
1 | from cqc.pythonLib import CQCConnection, qubit
2 | from teleportation import send_teleportation
3 |
4 | if __name__ == '__main__':
5 | with CQCConnection("Alice") as location:
6 | q = qubit(location)
7 | send_teleportation(q,location,'Bob')
8 |
--------------------------------------------------------------------------------
/Basic_Examples/EPR_Teleportation/Test_Bob.py:
--------------------------------------------------------------------------------
1 | from cqc.pythonLib import CQCConnection, qubit
2 | from teleportation import accept_teleportation
3 |
4 | if __name__ == '__main__':
5 | with CQCConnection("Bob") as location:
6 | q = accept_teleportation(location)
7 | m = q.measure()
8 | print("m", m)
9 |
--------------------------------------------------------------------------------
/Basic_Examples/EPR_Teleportation/readme.md:
--------------------------------------------------------------------------------
1 | In this example, we aimed to use EPR pair with teleportation instead of using fresh qubit
2 | While we are using fresh qubit(we are sending or receiving), we could not that which qubit comes from who
3 | Because of this reason we wanted to use EPR pairs and teleportation. It can be difficult to create
4 | an EPR pairs and teleporting for all codes in every time. So we designed a fuction for this.
5 | And when you need to use, EPR pairs, you can use the function directly
6 |
--------------------------------------------------------------------------------
/Basic_Examples/EPR_Teleportation/teleportation.py:
--------------------------------------------------------------------------------
1 | from cqc.pythonLib import CQCConnection, qubit
2 |
3 | def send_teleportation(q,sender,receiver):
4 | qA = sender.createEPR(receiver)
5 | q.cnot(qA)
6 | q.H()
7 | a = q.measure()
8 | b = qA.measure()
9 | sender.sendClassical(receiver, [a, b])
10 | print('Corrections were sent at', sender, ':', [a, b])
11 | return [a,b]
12 |
13 | def accept_teleportation(receiver):
14 | qB = receiver.recvEPR()
15 | message = list(receiver.recvClassical())
16 | print("data: ", message)
17 | if message[1] == 1:
18 | qB.X()
19 | if message[0] == 1:
20 | qB.Z()
21 | return qB
22 |
--------------------------------------------------------------------------------
/Basic_Examples/States/Bellstates.py:
--------------------------------------------------------------------------------
1 | from cqc.pythonLib import CQCConnection, qubit
2 |
3 | def generate_bell_pair():
4 |
5 | with CQCConnection("Alice") as Alice:
6 | qubit1 = qubit(Alice)
7 | qubit2 = qubit(Alice)
8 | qubit1.H()
9 | qubit1.cnot(qubit2)
10 | n = qubit1.measure()
11 | Alice.sendQubit(qubit2, "Bob")
12 | to_print = "App {}:Part 1: Measurement outcome is: {}".format(Alice.name, n)
13 | print("| " + to_print + " |")
14 |
15 | with CQCConnection("Bob") as Bob:
16 | qubit3 = Bob.recvQubit()
17 | m = qubit3.measure()
18 | to_print = "App {}:Part 1: Measurement outcome is: {}".format(Bob.name, m)
19 | print("| " + to_print + " |")
20 |
21 |
22 | if __name__ == "__main__":
23 |
24 | generate_bell_pair()
25 |
--------------------------------------------------------------------------------
/Basic_Examples/States/nPartyGHZstates.py:
--------------------------------------------------------------------------------
1 | from cqc.pythonLib import CQCConnection, qubit
2 |
3 |
4 | '''
5 | This code provide generating GHZ states according to number of inputs from users
6 | 1)If users give 2 names, code will stop because GHZ states need 3 party at least
7 | 2)After finishing names, first Alice start to creating EPR states except herself
8 | 3)According to numbers of inputs, other parties accept EPR states and produced a fresh qubit and then apply cnot gate
9 | finally they measure their qubits
10 | 4)Again after contolling the number of inputs, parties send qubits to other parties (except themselves)
11 | '''
12 |
13 |
14 | arr = [] # Here an empty array was defined and users can give name. After finishing names, users should press enter
15 | veri = input("Add person")
16 | while veri:
17 | arr.append(veri)
18 | veri = input("Add person")
19 |
20 | if len(arr) == 2:
21 | print("For Generating GHZ state party number should be 3 at least!!! Please try again")
22 | raise SystemExit
23 |
24 |
25 | def main():
26 | with CQCConnection("Alice") as Alice:
27 | for i in range(len(arr)):
28 | if 'Alice' != arr[i]:
29 | qEPR = Alice.createEPR(arr[i])
30 | m = qEPR.measure()
31 | to_print = "App {}:Part 1: Measurement outcome is: {}".format(arr[0], m)
32 | print("| " + to_print + " |")
33 |
34 | with CQCConnection("Bob") as Bob:
35 | qBEPR = Bob.recvEPR()
36 | print("OK 1")
37 | qnew = qubit(Bob)
38 | qBEPR.cnot(qnew)
39 | m = qBEPR.measure()
40 | to_print2 = "App {}: Part 2: Measurement outcome is: {}".format(arr[1], m)
41 | print("| " + to_print2 + " |")
42 | for i in range(len(arr)):
43 | if 'Alice' != arr[i] and 'Bob' != arr[i]:
44 | qnew = qubit(Bob)
45 | Bob.sendQubit(qnew, arr[i])
46 |
47 | with CQCConnection("Eve") as Eve:
48 | if len(arr) >= 3:
49 | qEEPR = Eve.recvEPR()
50 | print("OK 2")
51 | qnew = Eve.recvQubit()
52 | qEEPR.cnot(qnew)
53 | m = qEEPR.measure()
54 | to_print3 = "App {}: Part 3: Measurement outcome is: {}".format(arr[2], m)
55 | print("| " + to_print3 + " |")
56 | for i in range(len(arr)):
57 | if 'Alice' != arr[i] and 'Bob' != arr[i] and 'Eve' != arr[i]:
58 | qnew = qubit(Eve)
59 | Eve.sendQubit(qnew, arr[i])
60 |
61 | with CQCConnection("David") as David:
62 | if len(arr) >= 4:
63 | qDEPR = David.recvEPR()
64 | print("OK 3")
65 | qnew = David.recvQubit()
66 | qDEPR.cnot(qnew)
67 | m = qDEPR.measure()
68 | to_print4 = "App {}: Part 4: Measurement outcome is: {}".format(arr[3], m)
69 | print("| " + to_print4 + " |")
70 | for i in range(len(arr)):
71 | if 'Alice' != arr[i] and 'Bob' != arr[i] and 'Eve' != arr[i] and 'David' != arr[i]:
72 | qnew = qubit(David)
73 | David.sendQubit(qnew, arr[i])
74 |
75 | with CQCConnection("Charlie") as Charlie:
76 | if len(arr) >= 5:
77 | qCEPR = Charlie.recvEPR()
78 | print("OK 4")
79 | qnew = Charlie.recvQubit()
80 | qCEPR.cnot(qnew)
81 | m = qCEPR.measure()
82 | to_print5 = "App {}: Part 5: Measurement outcome is: {}".format(arr[4], m)
83 | print("| " + to_print5 + " |")
84 |
85 |
86 | if __name__ == "__main__":
87 |
88 | main()
89 |
--------------------------------------------------------------------------------
/Basic_Examples/States/readme.md:
--------------------------------------------------------------------------------
1 | For Bellstates code:
2 |
3 | You can start simulaqron with default mode
4 | Of course code can be divided 2 parts such as Alice part and Bob part easily
5 | And of course Alice can produce one qubit and it can send qubit to Bob.
6 | After Bob receiving the qubit it can produce an another qubit
7 | and the code can continue this type. THis is not a problem
8 |
9 | For nPartyGHZStates code:
10 |
11 | This code provide generating GHZ states according to number of inputs from users
12 | 1)If users give 2 names, code will stop because GHZ states need 3 party at least
13 | 2)After finishing names, first Alice start to creating EPR states except herself
14 | 3)According to numbers of inputs, other parties accept EPR states and produced a fresh qubit and then apply cnot gate
15 | finally they measure their qubits
16 | 4)Again after contolling the number of inputs, parties send qubits to other parties (except themselves)
17 |
18 | Please do not forgat to start simulaqron with names that you want to use
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/Basic_Examples/readme.md:
--------------------------------------------------------------------------------
1 | In this folder, basic examples will be shared instead of quantum protocols.
2 | For instance, generating Bell pair or GHZ states are not protocols.
3 | These can be just requirements for creating a protocols.
4 | When you want to write a protocol and you need some basics structure, then we will waiting you in here :)
5 |
6 |
--------------------------------------------------------------------------------
/DeviceIndependentQKD/README.md:
--------------------------------------------------------------------------------
1 | # Device Independent Quantum Key Distribution
2 | The code in this directory provides an implementation of the DIQKD
3 | protocol (excluding error correction and privacy amplification) as
4 | described in the [Quantum Protocol
5 | Zoo](https://wiki.veriqloud.fr/index.php?title=Device-Independent_Quantum_Key_Distribution),
6 | using Netsquid.
7 |
8 | The steps of 'Distribution and measurement' and 'Parameter estimation'
9 | are implemented. At the end of the protocol, both Alice and Bob agree
10 | upon a secure key or agree to abort.
11 |
12 | # Requirements
13 | - 2 Nodes capable of single-qubit measurements in upto 3 bases (2 for Alice, 3 for Bob)
14 | - A source generating EPR pairs
15 | - Quantum channels from the source to each node
16 | - Authenticated public classical channel between Alice and Bob
17 |
18 | # Changing protocol parameters
19 | Protocol and simulation parameters are defined in utils.py and can be modified as desired
20 |
21 | # Running
22 | `python diqkd.py`
23 | - Requirement: Installation of the [NetSquid package](https://netsquid.org/)
24 | - Running: The code can be run by executing diqkd.py
25 | - Expected output:
26 | - Parameter estimation
27 | - Observed CHSH wins
28 | - Threshold CHSH wins
29 | - Success / Failure messages
30 | - Length of key distributed
31 | - Number of protocol rounds
32 |
--------------------------------------------------------------------------------
/DeviceIndependentQKD/utils.py:
--------------------------------------------------------------------------------
1 | #Define protocol parameters and utility functions
2 | import math
3 | import numpy as np
4 | gamma = 0.2 #Fraction of test rounds
5 | w_exp = (2+math.sqrt(2))/ 4 #Expected winning probability of CHSH game in an honest implementation
6 | del_est = 1e-3 #Width of statistical interval for the Bell test (Smaller value leads to higher value of CHSH threshold and thus a tighter security bound)
7 | m = 1000 #Number of blocks
8 | s_max = math.ceil(1/gamma) #Maximum rounds in a block
9 | dist_AS = 4 / 1000 #Length of channel between Alice and Source in km
10 | dist_AB = 400 / 1000 #Length of channel between Alice and Bob in km
11 | dist_BS = 400 / 1000 #Length of channel between Bob and Source in km
12 |
13 | #Establish all connections between the given nodes and the source
14 | def set_up_network(alice,bob,source,channel1,channel2,channel3,qchannel1,qchannel2):
15 |
16 | #Set up ports
17 | alice.add_ports(['cout_source','cout_bob','cin_bob','qin_source'])
18 | bob.add_ports(['cout_alice','cin_alice','qin_source'])
19 |
20 | #Connect nodes to channels
21 | #Connect all of Alice's ports
22 | alice.ports['cout_source'].connect(channel1.ports['send'])
23 | alice.ports['cout_bob'].connect(channel2.ports['send'])
24 | alice.ports['cin_bob'].connect(channel3.ports['recv'])
25 | alice.ports['qin_source'].connect(qchannel1.ports['recv'])
26 |
27 | #Connect all of Bob's ports
28 | bob.ports['cout_alice'].connect(channel3.ports['send'])
29 | bob.ports['cin_alice'].connect(channel2.ports['recv'])
30 | bob.ports['qin_source'].connect(qchannel2.ports['recv'])
31 |
32 | #Connect all of the EPR Source's ports
33 | source.ports['qout0'].connect(qchannel1.ports['send'])
34 | source.ports['qout1'].connect(qchannel2.ports['send'])
35 | source.ports['trigger'].connect(channel1.ports['recv'])
36 |
37 |
38 | def random_bit(gamma):
39 | return np.random.choice([0,1], p = [1 - gamma, gamma])
40 |
--------------------------------------------------------------------------------
/QuantumAnonTransmission/anon_trans.py:
--------------------------------------------------------------------------------
1 | #This file contains the main code for the protocol
2 |
3 | import netsquid as ns
4 | import numpy as np
5 | import sys
6 | from utils import *
7 |
8 | #Default size of network, sender id, receiver id, quantum message state
9 | num_nodes = 5
10 | sender_id = 0
11 | dest_id = 4
12 | message_state = ns.y0
13 |
14 |
15 | if(len(sys.argv) == 6):
16 | #If appropriate number of arguments, simulate with command line arguments
17 | num_nodes = int(sys.argv[1])
18 | sender_id = int(sys.argv[2])
19 | dest_id = int(sys.argv[3])
20 | alpha = complex(sys.argv[4])
21 | beta = complex(sys.argv[5])
22 | message_state = np.array([alpha,beta])
23 | state_norm = np.sqrt(pow(abs(alpha),2)+pow(abs(beta),2))
24 | message_state /= state_norm
25 |
26 | else:
27 | #Simulate with default values
28 | print('Simulating with default values')
29 |
30 | print('Number of nodes:',num_nodes)
31 | print('Sender id: \t',sender_id)
32 | print('Receiver id: \t',dest_id)
33 | print('State to be transmitted:',message_state)
34 | print('\nStarting simulation\n===================\n')
35 |
36 |
37 | #Assign message state to qubit
38 | message_qubit = ns.qubits.create_qubits(num_qubits = 1, no_state = True)[0]
39 | ns.qubits.assign_qstate(message_qubit, message_state)
40 |
41 | nodes = setup_network(num_nodes) #Setup network
42 | nodes[sender_id].send(dest_id,message_qubit) #Send message_qubit to dest_id
43 | nodes[dest_id].receive() #Receive message
44 |
45 |
46 | #Start simulation
47 | for i in range(num_nodes):
48 | nodes[i].start()
49 |
50 |
51 | run_stats = ns.sim_run(duration = 1600)
52 | #print(run_stats)
53 |
--------------------------------------------------------------------------------
/QuantumAnonTransmission/readme.md:
--------------------------------------------------------------------------------
1 | # Quantum Anonymous Transmission
2 | The code in this directory provides an implementation of GHZ-based Quantum Anonymous Transmission as described in the [Quantum Protocol Zoo](https://wiki.veriqloud.fr/index.php?title=GHZ-based_Quantum_Anonymous_Transmission), using Netsquid. The protocol anonymously transmits a qubit from the sender to the receiver.
3 |
4 | # Requirements
5 | - All nodes in the network should be able to perform single-qubit gates, the CNOT gate, and single-qubit measurements
6 | - A trusted GHZ-state source
7 | - Quantum channels from the source to each node
8 | - Each node should be able to broadcast classical messages to the other nodes in the network
9 |
10 | # Running
11 | - Requirement: Installation of the [NetSquid package](https://netsquid.org/)
12 | - Running: The code can be run by executing anon_trans.py
13 | ```
14 | python3 anon_trans.py
15 | ```
16 |
17 | - By executing the above command, the code runs with the following default parameters
18 | - Number of nodes in the network: 5
19 | - Id of sender node: 0
20 | - Id of receiver node: 4
21 | - Message state to be transmitted: $$\frac{1}{\sqrt{2}}(\left|0\right\rangle + i\left|1\right\rangle)$$
22 | - The user can specify the 4 parameters by providing them as command line arguments. For example,
23 | ```
24 | python3 anon_trans.py 5 0 4 0.707 0.707j
25 | ```
26 | runs the code with the default parameters. The arguments in order are as follows:
27 | - Number of nodes (more than 2) or ```num_nodes```
28 | - Id of sender (should range from 0 to ```num_nodes-1```)
29 | - Id of receiver (should range from 0 to ```num_nodes-1```)
30 | -  (Complex number)
31 | -  (Complex number),
32 |
33 | where the message state to be transmitted is . The input message state need not be normalized, as normalization is performed by the code. For example, the above command would be equivalent to:
34 | ```
35 | python3 anon_trans.py 5 0 4 1 1j
36 | ```
37 | - Expected output:
38 | - Simulation parameters
39 | - Confirmation of state reception
--------------------------------------------------------------------------------
/QuantumBitCommitment/A0.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from math import ceil, log, sqrt
3 | from random import randint, random, sample
4 | from cqc.pythonLib import CQCConnection, qubit
5 | from time import sleep
6 |
7 | aclassic = []
8 | aclassbasis = []
9 | wait = 1
10 |
11 | '''
12 | In prep_Alice funtion:
13 | produced n bit and saved in aclassic list
14 | produced n basis and saved in aclassbasis list
15 | produced n fresh qubits and according to produced bit and basis, (conditionally) applied gates and sent to B0
16 | aclassic list was sent to A1 and A2
17 | aclassbasis list was sent to A1 and A2
18 | '''
19 |
20 |
21 | def prep_Alice():
22 |
23 | with CQCConnection("A0") as A0:
24 |
25 | for i in range(10):
26 | random_bits_alice = randint(0,1)
27 | random_basis_alice = randint(0,1)
28 | aclassic.append(random_bits_alice)
29 | aclassbasis.append(random_basis_alice)
30 | q = qubit(A0)
31 |
32 | if random_bits_alice == 1:
33 | q.X()
34 | if random_basis_alice == 1:
35 | q.H()
36 | A0.sendQubit(q, "B0")
37 | # , close_after=False
38 | A0.flush()
39 | sleep(wait)
40 | A0.sendClassical("A1",aclassic)
41 | print ("Aclassic was sent to A1")
42 | sleep(wait)
43 | A0.sendClassical("A1",aclassbasis)
44 | print ("AclassicBASIS was sent to A1")
45 | sleep(wait)
46 | A0.sendClassical("A2",aclassic)
47 | print ("Aclassic was sent to A2")
48 | sleep(wait)
49 | A0.sendClassical("A2",aclassbasis)
50 | print ("AclassicBASIS was sent to A2")
51 | # print ("HELLO")
52 |
53 |
54 | if __name__ == "__main__":
55 | prep_Alice()
56 |
57 |
--------------------------------------------------------------------------------
/QuantumBitCommitment/A1.py:
--------------------------------------------------------------------------------
1 | from cqc.pythonLib import CQCConnection, qubit
2 | from time import sleep
3 | aclassic = []
4 | aclassbasis = []
5 | received1 = []
6 | wait = 1
7 |
8 | '''
9 | A1, first accepts knowledges(aclassic and aclassbasis) from A0
10 | After waiting a specific time for second phase this time A1 accepts
11 | the knowledges from B1 and it does some tests
12 | after these tests A1 sends knowledge to A2.
13 | '''
14 |
15 |
16 | def part_A1():
17 |
18 | with CQCConnection("A1") as A1:
19 | sleep(wait)
20 | aclassic[:] = list(A1.recvClassical())
21 | print ("aclassic for A1:", aclassic)
22 | sleep(wait)
23 | aclassbasis[:] = list(A1.recvClassical())
24 | print ("aclassicbasis for A1:", aclassbasis)
25 | sleep(5)
26 |
27 | sleep(wait)
28 | c = A1.recvClassical()
29 | received1[:] = list(c)
30 | print ("received1 was transformed for A1:", received1)
31 | sleep(wait)
32 | commitment = A1.recvClassical()[0]
33 | print ("commitment for A1:", commitment)
34 |
35 | cheat = False
36 | for i in range(len(aclassic)):
37 | if (commitment == aclassbasis[i]):
38 | if (aclassic[i] == received1[i]):
39 | print("qubit", i, "is OK!")
40 | continue
41 | else:
42 | print("Bob is Cheating")
43 | cheat = True
44 | break
45 | sleep(wait)
46 | A1.sendClassical("A2", received1)
47 |
48 |
49 | if __name__ == "__main__":
50 | part_A1()
51 |
--------------------------------------------------------------------------------
/QuantumBitCommitment/A2.py:
--------------------------------------------------------------------------------
1 | from cqc.pythonLib import CQCConnection, qubit
2 | from time import sleep
3 |
4 | aclassic = []
5 | aclassbasis = []
6 | received2 = []
7 | received1 = []
8 | wait = 1
9 |
10 | '''
11 | A2 is the last station of this protocol
12 | First, A2 accepts the knowledge from A0
13 | After waiting a specific time for second phase,
14 | Second A2 accepts the knowledge from B2
15 | Third A2 accepts the knowledge from A1
16 | And A2 compares the knowledge that he received A1 and B2
17 | '''
18 |
19 |
20 | def part_A2():
21 |
22 | with CQCConnection("A2") as A2:
23 | sleep(wait)
24 | aclassic[:] = list(A2.recvClassical())
25 | sleep(wait)
26 | aclassbasis[:] = list(A2.recvClassical())
27 |
28 | print ("aclassic for A2:", aclassic)
29 | print ("aclassicbasis for A2:", aclassbasis)
30 |
31 | sleep(5)
32 |
33 | sleep(wait)
34 | received2[:] = list(A2.recvClassical())
35 | print ("received1 for A2:", received2)
36 | sleep(wait)
37 | commitment = A2.recvClassical()[0]
38 | print ("commitment for A2:", commitment)
39 |
40 |
41 | sleep(wait)
42 | received1[:] = list(A2.recvClassical())
43 | if(received2 != received1):
44 | cheat = True
45 | print("Something is wrong!")
46 | else:
47 | print("Something is really GOOD!")
48 |
49 | if __name__ == "__main__":
50 | part_A2()
51 |
--------------------------------------------------------------------------------
/QuantumBitCommitment/B0.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from math import ceil, log, sqrt
3 | from random import randint, random, sample
4 | from cqc.pythonLib import CQCConnection, qubit
5 | from time import sleep
6 |
7 | measurement = []
8 | agent1_ = []
9 | agent2_ = []
10 | wait = 1
11 |
12 | '''
13 | In the prep_Bob function
14 | commitmentment bit was produced as commitment
15 | sent qubits from A0 were accepted and
16 | according to commitment applied H gate and
17 | measured and saved in measurement list.
18 | Measurement list was sent B1 and B2
19 | commitment bit was sent B1 and B2
20 | '''
21 |
22 | def prep_Bob():
23 |
24 | with CQCConnection("B0") as B0:
25 | commitment = randint(0,1)
26 | for i in range(10):
27 | q = B0.recvQubit()
28 |
29 | if commitment == 1:
30 | q.H()
31 | a = q.measure()
32 | measurement.append(a)
33 | print("qubit received")
34 | sleep(wait)
35 | B0.sendClassical("B1", measurement)
36 | print("a sent to B1")
37 | sleep(wait)
38 | B0.sendClassical("B2", measurement)
39 | print("a sent to B2")
40 | sleep(wait)
41 | B0.sendClassical("B1",commitment)
42 | print("commitment sent to B1")
43 | sleep(wait)
44 | B0.sendClassical("B2",commitment)
45 | print("commitment sent to B2")
46 | print ("HELLO2")
47 | if __name__ == "__main__":
48 |
49 | prep_Bob()
50 |
51 |
--------------------------------------------------------------------------------
/QuantumBitCommitment/B1.py:
--------------------------------------------------------------------------------
1 | from cqc.pythonLib import CQCConnection, qubit
2 | from time import sleep
3 | received1 = []
4 | wait = 1
5 |
6 | '''
7 | B1 accepts measurement list and commitment bit
8 | And sleep(5) is a time space for second phase
9 | After space time B1 sends to all knowledge(accepted commitment
10 | bit and accepted measurement list) to A1
11 | '''
12 |
13 | def Agent1_recv():
14 |
15 | with CQCConnection("B1") as B1:
16 | sleep(wait)
17 | r = B1.recvClassical()
18 | print ("B1 ACCEPTS measurement list from B0:")
19 | received1[:] = list(r)
20 | print ("B1 TRANSFORMES LIST")
21 | sleep(wait)
22 | commitment = B1.recvClassical()[0]
23 | print ("received commitment from B0:", commitment)
24 |
25 | sleep(5)
26 | sleep(wait)
27 | B1.sendClassical("A1", received1)
28 | print ("received by A1:", received1)
29 | sleep(wait)
30 | B1.sendClassical("A1",commitment)
31 | print ("commitment by A1:", commitment)
32 |
33 | if __name__ == "__main__":
34 | Agent1_recv()
35 |
--------------------------------------------------------------------------------
/QuantumBitCommitment/B2.py:
--------------------------------------------------------------------------------
1 | from cqc.pythonLib import CQCConnection, qubit
2 | from time import sleep
3 | received2 = []
4 | wait = 1
5 |
6 | '''
7 | B2 accepts the knowledges from B0
8 | and after waiting a specific time
9 | it sends knowledge(accepted measurement list
10 | and accepted commitment bit) to A2
11 | '''
12 |
13 | def Agent2_recv():
14 |
15 | with CQCConnection("B2") as B2:
16 | sleep(wait)
17 | r = B2.recvClassical()
18 | print ("B2 ACCEPTS measurement list as r:")
19 | received2[:] = list(r)
20 | print ("B2 TRANSFORMES LIST:")
21 | sleep(wait)
22 | commitment = B2.recvClassical()[0]
23 | print ("received commitment by Agent2:", commitment)
24 |
25 | sleep(5)
26 | sleep(wait)
27 | B2.sendClassical("A2", received2)
28 | print ("received by B1:", received2)
29 | sleep(wait)
30 | B2.sendClassical("A2", commitment)
31 | print ("commitment by B1:", commitment)
32 |
33 |
34 | if __name__ == "__main__":
35 | Agent2_recv()
36 |
--------------------------------------------------------------------------------
/QuantumBitCommitment/BitCommitment_readme.md:
--------------------------------------------------------------------------------
1 | Code for Quantum Bit Commitment Protocol has 6 players which are named A0, B0, A1, B1, A2, B2.
2 | Suppose that A1 and A2 are agents of A0 and B1 and B2 are agents of B0
3 |
4 | In the A0.py code:
5 |
6 | 1)For producing n qubits from BB84 states and sending to B0, random bits and random basis were produced
7 |
8 | 2)After sending the qubits to B0, all random bits and random basis were sent to A1 and A2(A1 and A2 can be thought A0's agents)
9 |
10 | In the B0.py code:
11 |
12 | 1)Bit for commitment was produced
13 |
14 | 2)If commitment bit is equal to 1, B0 accepts qubit after applying H gate and then measured the qubit.
15 | If commitment bit is not equal to 1, then B0 just measures
16 |
17 | 3)After these steps, B0 sends all knowledge(outcomes of measurements and the commitment bit) to its all agents (B1 and B2)
18 |
19 | In the B1.py code:
20 |
21 | 1)B1 accepts all classical messages and sends the all accepted classical messages to A1
22 |
23 | In the B2.py code:
24 |
25 | 1)B2 accepts all classical messages and sends the all accepted classical messages to A2
26 |
27 | In the A1.py code:
28 |
29 | 1)A1 accepts all messages which were sent to it
30 |
31 | 1.1)Check that: if the receieved commitment bit is equal to received basis
32 |
33 | 1.2)Check that: if the classic bits and received bits is equal-->If it yes, then ok
34 | 1.2.1) If it is not, then Eve is here
35 |
36 | 2) And finally A1 sends the received knowledge to A2
37 |
38 | In the A2.py code:
39 |
40 | 1)A2 receives all messages which were sent to it
41 |
42 | 2)Check that: received knowledge from A1 and receieved knowledge from B2 is equal or not
43 |
44 | 2.1)If it is OK, then commitment is OK:)
45 | 2.2)If it is not OK, then something is wrong :(
46 |
47 | In this protocol cheating was not used. Because of this reason, if you want to be sure that the code is correct, then you should'nt see that: "Bob is cheating"
48 | Note that: This readme file for just an outline. For detailed knowledges were added in the code.
49 | And for running the code, you should use this line:
50 |
51 | simulaqron reset && simulaqron set max-qubits 200 && simulaqron start --nodes A0,A1,A2,B0,B1,B2
52 |
53 |
--------------------------------------------------------------------------------
/QuantumBitCommitment/commitmentstart.sh:
--------------------------------------------------------------------------------
1 | python3 A0.py &
2 | python3 B0.py &
3 | python3 B1.py &
4 | python3 B2.py &
5 | python3 A1.py &
6 | python3 A2.py &
7 |
--------------------------------------------------------------------------------
/QuantumCheques/A_party.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from math import ceil, log, sqrt
3 | from random import randint, random, sample
4 | from multiprocessing import pool
5 | from cqc.pythonLib import CQCConnection, qubit
6 |
7 |
8 | def A_party(num_bits, conn):
9 |
10 | bits_alice = []
11 | basis_alice = []
12 |
13 | def preperation_Alice():
14 | for i in range(num_bits):
15 | random_bits_alice = randint(0,1)
16 | random_basis_alice = randint(0,1)
17 | bits_alice.append(random_bits_alice)
18 | basis_alice.append(random_basis_alice)
19 |
20 | q = qubit(conn)
21 |
22 | if random_bits_alice == 1:
23 | q.X()
24 |
25 | if random_basis_alice == 1:
26 | q.H()
27 | conn.sendQubit(q, "Bob")
28 | print("bits Alice:",bits_alice)
29 | print("basis Alice:",basis_alice)
30 |
31 | def compare_basis(basis_alice,basis_bob):
32 | matchList=[]
33 | for i in range(len(basis_alice)):
34 | if basis_alice[i] == basis_bob[i]: #measure in standard basis
35 | matchList.append(i)
36 | else:
37 | pass
38 | return matchList
39 |
40 | def rec_com_send():
41 | basis_bob = conn.recvClassical()
42 | #print(basis_bob)
43 | matchList=compare_basis(basis_alice,basis_bob)
44 | print("matchList=",matchList)
45 | conn.sendClassical("Bob", matchList)
46 | return matchList
47 |
48 | def keygen(matchList):
49 | key_A=[]
50 | for i in matchList:
51 | key_A.append(bits_alice[i]) #quantum state 0,+:0 1,-:1
52 |
53 | key_A = ''.join(map(str, key_A))
54 | return key_A
55 |
56 | preperation_Alice()
57 | return keygen(rec_com_send())
58 |
59 |
60 |
--------------------------------------------------------------------------------
/QuantumCheques/B_party.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from math import ceil, log, sqrt
3 | from random import randint, random, sample
4 | from multiprocessing import Pool
5 | from cqc.pythonLib import CQCConnection, qubit
6 |
7 |
8 | def B_party(num_bits, conn):
9 |
10 | basis_bob = []
11 | res_measure = []
12 |
13 | def preparation_Bob():
14 | q_arr = []
15 | for i in range(num_bits):
16 | q = conn.recvQubit()
17 | q_arr.append(q)
18 |
19 |
20 | for i in range(num_bits):
21 | random_basis_bob = randint(0,1)
22 | basis_bob.append(random_basis_bob)
23 | if random_basis_bob == 1:
24 | q_arr[i].H()
25 | m = q_arr[i].measure()
26 | res_measure.append(m)
27 |
28 | print ("basis Bob: ", basis_bob)
29 | print ("measurement results of Bob: ",res_measure)
30 |
31 |
32 | def send_basis_toA():
33 | conn.sendClassical("Alice", basis_bob)
34 |
35 | def rec_keygen():
36 | matchList = conn.recvClassical()
37 | key_B=[]
38 | for i in matchList:
39 | key_B.append(res_measure[i])
40 | key_B = ''.join(map(str, key_B))
41 | print("key_B=",key_B)
42 | return key_B
43 |
44 | preparation_Bob()
45 | send_basis_toA()
46 | return rec_keygen()
47 |
--------------------------------------------------------------------------------
/QuantumCheques/README.md:
--------------------------------------------------------------------------------
1 | # quantumwinter
2 |
3 |
4 |
5 | This Hackaton was a first [Pan-European-Hackaton](https://labs.ripe.net/Members/ulka_athale_1/take-part-in-pan-european-quantum-internet-hackathon) on the Quantum Technologies and more especially on the telecommunications domain.
6 | Five countries have been implied;Netherlands, Switzerland, Italy, Ireland, Bosnia-Herzegovina and France.
7 | It was not a competition but much more a moment of collaboration.
8 |
9 | The team called "Quantum Winter" secured financial transactions by using the quantum cheques protocol which consists of several building blocks like SWAP test, BB84 QKD, quantum one way function etc.
10 |
11 | The final project implemented is "Quantum-Cheque Protocol" that is present on the Quantum Protocol Zoo repository.
12 | [Quantum Cheque Protocol](https://wiki.veriqloud.fr/index.php?title=Quantum_Cheque)
13 |
14 | settings for simulaqron:
15 | ```
16 | simulaqron reset && simulaqron stop && simulaqron set backend projectq && simulaqron set max-qubits 50 && simulaqron set recv-timeout 1000 && simulaqron start
17 | ```
18 |
19 | to ensure swap_test is working :
20 | ```
21 | python swap_test.py
22 | ```
23 |
24 | to start a cheque protocol holder Alice send M dollars using a quantum M$ cheque to Charlie through bank Bob :
25 | ```
26 | python quantum_cheque.py
27 | ```
28 |
29 |
30 |
31 | Team Quantum Winter:
32 | - Nicolas GAUDE
33 | - Michel NOWAK
34 | - Rhea PAREKH
35 | - ChinTe LIAO
36 | - Hop DINH
37 | - Amar MOUFFOK
38 |
--------------------------------------------------------------------------------
/QuantumCheques/figures/team.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quantumprotocolzoo/protocols/3367ceeb8a4d9825b979203190e254ca57fe0e74/QuantumCheques/figures/team.jpg
--------------------------------------------------------------------------------
/QuantumCheques/figures/title.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quantumprotocolzoo/protocols/3367ceeb8a4d9825b979203190e254ca57fe0e74/QuantumCheques/figures/title.jpg
--------------------------------------------------------------------------------
/QuantumCheques/one_way_function.py:
--------------------------------------------------------------------------------
1 | from cqc.pythonLib import CQCConnection, qubit
2 |
3 |
4 | def one_way_function(conn, BB84_key, db_id, r, M):
5 | owf_state = qubit(conn)
6 |
7 | BB84_key = int(BB84_key, 2)
8 | owf_key = bin(BB84_key)[2:] + bin(db_id)[2:] + bin(r)[2:] + bin(M)[2:]
9 | owf_key = int(abs(hash(str(owf_key))))
10 | # p1 , p2, p3 are prime numbers , so coprimes
11 | # thus rotation X(key%p1) and Y(key%p2) and Z(key%p3) are independant
12 | p1 = 33179
13 | p2 = 32537
14 | p3 = 31259
15 | owf_state.rot_X(owf_key%p1%256)
16 | owf_state.rot_Y(owf_key%p2%256)
17 | owf_state.rot_Z(owf_key%p3%256)
18 | return owf_state
19 |
--------------------------------------------------------------------------------
/QuantumCheques/quantum_cheques_presentation.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quantumprotocolzoo/protocols/3367ceeb8a4d9825b979203190e254ca57fe0e74/QuantumCheques/quantum_cheques_presentation.pdf
--------------------------------------------------------------------------------
/QuantumCheques/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup, find_packages
2 |
3 |
4 | setup(name='quantumwinter',
5 | version='0.1',
6 | description='Quantum Winter',
7 | author='Michel Nowak',
8 | author_email='michel.nowak@prevision.io',
9 | license='MIT',
10 | packages=['quantumwinter'],
11 | zip_safe=False)
12 |
13 |
14 |
--------------------------------------------------------------------------------
/QuantumCheques/swap_test.py:
--------------------------------------------------------------------------------
1 | from one_way_function import one_way_function
2 | from cqc.pythonLib import CQCConnection, qubit
3 | import random
4 | import tqdm
5 |
6 |
7 | def T(q):
8 | # T = RZ(pi/4) * e(i*pi/8)
9 | q.rot_Z(256//8)
10 | return
11 |
12 |
13 | def invT(q):
14 | # T* == RZ(-pi/4) * e(i*pi/8)
15 | q.rot_Z(256 - 256//8)
16 | return
17 |
18 |
19 | def CSWAP(q0, q1, q2):
20 | # fredkin implementation from :
21 | # https://www.mathstat.dal.ca/~selinger/quipper/doc/QuipperLib-GateDecompositions.html
22 | q2.cnot(q1)
23 | q2.H()
24 | T(q0)
25 | T(q1)
26 | T(q2)
27 | q1.cnot(q0)
28 | q2.cnot(q1)
29 | q0.cnot(q2)
30 | invT(q1)
31 | T(q2)
32 | q0.cnot(q1)
33 | invT(q0)
34 | invT(q1)
35 | q2.cnot(q1)
36 | q0.cnot(q2)
37 | q1.cnot(q0)
38 | q2.H()
39 | q2.cnot(q1)
40 | return
41 |
42 |
43 | def swap_test(conn, q1, q2):
44 | # swap_test implementation from :
45 | # https://en.wikipedia.org/wiki/Swap_test
46 |
47 | q0 = qubit(conn)
48 | q0.H()
49 | CSWAP(q0, q1, q2)
50 | q0.H()
51 | m = q0.measure()
52 |
53 | # collaspse everything after swap_test to avoid :
54 | # cqc.pythonLib.CQCNoQubitError: No more qubits available
55 | q1.measure()
56 | q2.measure()
57 |
58 | return m
59 |
60 |
61 | def main():
62 | # Initialize the connection
63 | with CQCConnection("Alice") as Alice:
64 | BB84_key = "10"
65 | db_id = 1
66 | M = 2
67 | res_same = []
68 | res_diff = []
69 | for i in tqdm.tqdm(range(1000)):
70 | salt = random.randint(0, 1000)
71 | epsilon = random.randint(1,10)
72 | q1 = one_way_function(Alice, BB84_key, db_id, salt, M)
73 | q2 = one_way_function(Alice, BB84_key, db_id, salt, M)
74 | m_same = swap_test(Alice, q1,q2)
75 | q1 = one_way_function(Alice, BB84_key, db_id, salt, M)
76 | q2 = one_way_function(Alice, BB84_key, db_id, salt + epsilon, M)
77 | m_diff = swap_test(Alice, q1,q2)
78 | res_same.append(m_same)
79 | res_diff.append(m_diff)
80 | print(res_same,res_diff)
81 | score_same = sum(res_same)/len(res_same)
82 | score_diff = sum(res_diff)/len(res_diff)
83 | print('swap_test score for identical state', score_same)
84 | print('swap_test score for different state', score_diff)
85 |
86 |
87 | if __name__ == "__main__":
88 | # execute only if run as a script
89 | main()
90 |
91 |
--------------------------------------------------------------------------------
/QuantumCoinFlipping/CoinFlippingAlice.py:
--------------------------------------------------------------------------------
1 | from random import randint
2 | from cqc.pythonLib import CQCConnection, qubit
3 | from time import sleep
4 | from math import pi, sqrt, acos
5 |
6 | m = 3
7 | n = 2
8 | step = 14
9 | estep = 256 - step
10 | Bob_qubits = [ [] for i in range(n) ]
11 | Alice_recv_qubits = [ [] for i in range(n) ]
12 | wait = 0.5
13 |
14 | def prep_Alice():
15 |
16 | with CQCConnection("Alice") as Alice:
17 |
18 | a_bits = [randint(0,1) for j in range(m)]
19 | c_bits = [[randint(0,1) for j in range(m)] for i in range(n)]
20 |
21 | print ("Step 1 is OK! in Alice Part")
22 | print ("a_bits:", a_bits)
23 | print ("c_bits:", c_bits)
24 |
25 | print ("Step 2 is starting")
26 | for i in range(n):
27 | for j in range(m):
28 | q_1 = qubit(Alice)
29 | q_2 = qubit(Alice)
30 |
31 | if (c_bits[i][j] == 0):
32 | q_1.rot_X(step)
33 | q_2.rot_X(estep)
34 | else:
35 | q_1.rot_X(estep)
36 | q_2.rot_X(step)
37 |
38 | Alice.sendQubit(q_1, "Bob")
39 | Alice.sendQubit(q_2, "Bob")
40 |
41 | bob_q1 = Alice.recvQubit()
42 | bob_q2 = Alice.recvQubit()
43 |
44 | Bob_qubits[i].append( (bob_q1,bob_q2) )
45 | Alice.flush()
46 |
47 | print ("Step 3 is starting")
48 | for i in range(n):
49 | for j in range(m):
50 |
51 | e_ij = a_bits[j] ^ c_bits[i][j]
52 | print ("e_ij", e_ij)
53 | sleep(wait)
54 | Alice.sendClassical("Bob", e_ij)
55 | print("Alice is trying to accept f_ij:")
56 | sleep(wait)
57 | f_ij = Alice.recvClassical()[0]
58 | print("Accepted f_ij By Alice:", f_ij)
59 | alice_qubit = Alice.recvQubit()
60 | print("Alice receive qubit:", alice_qubit)
61 | Alice_recv_qubits[i].append(alice_qubit)
62 |
63 | print("The code can work until the if condition")
64 | if f_ij == 0:
65 | Alice.sendQubit(Bob_qubits[i][j][1], "Bob")
66 | Bob_qubits[i][j] = Bob_qubits[i][j][0]
67 | else:
68 | Alice.sendQubit(Bob_qubits[i][j][0], "Bob")
69 | Bob_qubits[i][j] = Bob_qubits[i][j][1]
70 |
71 | print ("Step 4 is starting")
72 | b_tilde = []
73 | for j in range(m):
74 | sleep(wait)
75 | Alice.sendClassical("Bob", a_bits[j])
76 | print ("Alice sent classical message: ", a_bits[j])
77 | sleep(wait)
78 | b_j = Alice.recvClassical()[0]
79 | print ("Alice receive classical message: ", b_j)
80 | for i in range(n):
81 | if b_j == 0:
82 | Bob_qubits[i][j].rot_X(estep)
83 | res = Bob_qubits[i][j].measure()
84 | print ("res1", res)
85 | else:
86 | Bob_qubits[i][j].rot_X(step)
87 | res = Bob_qubits[i][j].measure()
88 | print ("res2", res)
89 | if res != 0:
90 | print("Cheating!")
91 | break
92 |
93 | b_tilde.append(b_j)
94 |
95 | a_j_bar = 1 - a_bits[j]
96 | for i in range(n):
97 | if a_j_bar == 0:
98 | Alice_recv_qubits[i][j].rot_X(estep)
99 | res = Alice_recv_qubits[i][j].measure()
100 | print ("res1", res)
101 | else:
102 | Alice_recv_qubits[i][j].rot_X(step)
103 | res = Alice_recv_qubits[i][j].measure()
104 | print ("res2", res)
105 |
106 | if res != 0:
107 | print("Cheating!")
108 | break
109 |
110 | for i in range(m):
111 | if i==0:
112 | A = a_bits[i]
113 | else:
114 | A = A ^ a_bits[i]
115 |
116 | for i in range(m):
117 | if i==0:
118 | B_tilde = b_tilde[i]
119 | else:
120 | B_tilde = B_tilde ^ b_tilde[i]
121 |
122 | return A, B_tilde
123 |
124 | if __name__ == "__main__":
125 | A, B_tilde = prep_Alice()
126 | x = A ^ B_tilde
127 | print("Shared coin toss is ", x)
128 |
129 |
130 |
131 |
--------------------------------------------------------------------------------
/QuantumCoinFlipping/CoinFlippingBob.py:
--------------------------------------------------------------------------------
1 | from random import randint
2 | from cqc.pythonLib import CQCConnection, qubit
3 | from time import sleep
4 | from math import pi, sqrt, acos
5 |
6 | m = 3
7 | n = 2
8 | step = 14
9 | estep = 256 - step
10 | wait = 0.5
11 | Alice_qubits = [ [] for i in range(n) ]
12 | Bob_recv_qubits = [ [] for i in range(n) ]
13 |
14 | def prep_Bob():
15 |
16 | with CQCConnection("Bob") as Bob:
17 |
18 | b_bits = [randint(0,1) for j in range(m)]
19 | d_bits = [[randint(0,1) for j in range(m)] for i in range(n)]
20 |
21 | print ("Step 1 is OK! in Bob Part ")
22 | print ("b_bits", b_bits)
23 | print ("d_bits", d_bits)
24 |
25 | print ("Step 2 is starting")
26 | for i in range(n):
27 | for j in range(m):
28 | q_1 = qubit(Bob)
29 | q_2 = qubit(Bob)
30 |
31 | if (d_bits[i][j] == 0):
32 | q_1.rot_X(step)
33 | q_2.rot_X(estep)
34 | else:
35 | q_1.rot_X(estep)
36 | q_2.rot_X(step)
37 |
38 | alice_q1 = Bob.recvQubit()
39 | alice_q2 = Bob.recvQubit()
40 |
41 | Bob.sendQubit(q_1, "Alice")
42 | Bob.sendQubit(q_2, "Alice")
43 |
44 | Alice_qubits[i].append( (alice_q1,alice_q2) )
45 | Bob.flush()
46 |
47 | print("Step 3 is starting")
48 | for i in range(n):
49 | for j in range(m):
50 | f_ij = b_bits[j] ^ d_bits[i][j]
51 | print ("f_ij", f_ij)
52 | sleep(wait)
53 | e_ij = Bob.recvClassical()[0]
54 | print("Accepted e_ij By Bob:", e_ij)
55 | sleep(wait)
56 | Bob.sendClassical("Alice", f_ij)
57 | print("Bob sent the message:", f_ij)
58 |
59 | print("The code can work until the if condition")
60 | if e_ij == 0:
61 | Bob.sendQubit(Alice_qubits[i][j][1], "Alice")
62 | Alice_qubits[i][j] = Alice_qubits[i][j][0]
63 | else:
64 | Bob.sendQubit(Alice_qubits[i][j][0], "Alice")
65 | Alice_qubits[i][j] = Alice_qubits[i][j][1]
66 |
67 | bob_qubit = Bob.recvQubit()
68 | print("Bob receive qubit:", bob_qubit)
69 | Bob_recv_qubits[i].append(bob_qubit)
70 |
71 | print("Step 4 is starting")
72 | a_tilde = []
73 | for j in range(m):
74 | sleep(wait)
75 | a_j = Bob.recvClassical()[0]
76 | print("Bob receive message a_j: ", a_j)
77 | sleep(wait)
78 | Bob.sendClassical("Alice", b_bits[j])
79 | print ("Bob sent classical message:", b_bits[j])
80 |
81 | for i in range(n):
82 | if a_j == 0:
83 | Alice_qubits[i][j].rot_X(estep)
84 | res = Alice_qubits[i][j].measure()
85 | print("res1", res)
86 | else:
87 | Alice_qubits[i][j].rot_X(step)
88 | res = Alice_qubits[i][j].measure()
89 | print("res2", res)
90 | if res != 0:
91 | print("Cheating!")
92 | break
93 |
94 | a_tilde.append(a_j)
95 |
96 | b_j_bar = 1 - b_bits[j]
97 | for i in range(n):
98 | if b_j_bar == 0:
99 | Bob_recv_qubits[i][j].rot_X(estep)
100 | res = Bob_recv_qubits[i][j].measure()
101 | print ("res1", res)
102 | else:
103 | Bob_recv_qubits[i][j].rot_X(step)
104 | res = Bob_recv_qubits[i][j].measure()
105 | print ("res2", res)
106 | if res != 0:
107 | print("Cheating!")
108 | break
109 |
110 | for i in range(m):
111 | if i==0:
112 | B = b_bits[i]
113 | else:
114 | B = B ^ b_bits[i]
115 |
116 | for i in range(m):
117 | if i==0:
118 | A_tilde = a_tilde[i]
119 | else:
120 | A_tilde = A_tilde ^ a_tilde[i]
121 |
122 | return B, A_tilde
123 |
124 | if __name__ == "__main__":
125 | B, A_tilde = prep_Bob()
126 | x = B ^ A_tilde
127 | print("Shared coin toss is ", x)
128 |
129 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/QuantumCoinFlipping/readme.md:
--------------------------------------------------------------------------------
1 | For implementing Quantum Protocol Zoo's Quantum Coin Flipping protocol,
2 | "Unconditionally Secure Quantum Coin Tossing" was used.
3 | For running the code, you should use this command
4 |
5 | simulaqron reset && simulaqron set max-qubits 200 && simulaqron set backend projectq && simulaqron start
6 |
7 |
8 | In the CoinFlippingAlice code:
9 |
10 | In the first step:
11 | 1) Alice produces random bits which are called a_bits from j to m
12 | 2) Alice produces other random bits which are called c_bits for each a_bits from i to n
13 |
14 | In the second step:
15 | 1) Alice produces 2 qubits
16 | 2) After producing qubits, according to c_bits value applied rot_X
17 | Note: at this point 14 degree was used as angle in order to provide the paper's steps:
18 | "Unconditionally Secure Quantum Coin Tossing"
19 | 3) Alice sends Bob qubits
20 | 4) By the way, after these steps, Alice accepts the qubits from Bob
21 |
22 | In the third step:
23 | 1) Alice send Bob the xor a_bits^cbits as classical message
24 | 2) After sending xor bits, Alice accepts classical messages and qubits from Bob.
25 | 3) According to accepted classical message's value from Bob, Alice sends qubits to Bob
26 |
27 |
28 | In the fourth and fifth steps:
29 | 1) Alice send Bob a_bits as classical message
30 | 2) Alie also accepts classical message from Bob
31 | 3) According to accepted message value, applied rot_X
32 | 4) And then qubits were measured
33 |
34 | and the same thing was done for opposite a_bits. This time
35 | 1) According to opposite a_bits(which is called a_j_bar) applied rot_X
36 | 2) After applying rot_X, qubits were measured
37 |
38 | In the final step:
39 | The final bit of each of the party is the xor of xor of the random bits,
40 | they prepared in the first step and xor of the bits they measured in the fourth step.
41 | This final bit is the random bit which has come up in the 'coin toss'.
42 | Thus ends the protocol.
43 |
44 |
45 | In the CoinFlippingBob code:
46 |
47 | In the first step:
48 | 1) Bob produces random bits which are called b_bits from j to m
49 | 2) Bob produces other random bits which are called d_bits for each b_bits from i to n
50 |
51 | In the second step:
52 | 1) Bob produces 2 qubits
53 | 2) After producing qubits, according to d_bits value applied rot_X
54 | Note: at this point 14 degree was used as angle in order to provide the paper's steps:
55 | "Unconditionally Secure Quantum Coin Tossing"
56 | 3) Bob sends qubits to Alice
57 | 4) By the way, after these steps, Bob accepts the qubits from Alice
58 |
59 | In the third step:
60 | Note: In this part queue of process related to simulaqron-cqc architecture
61 | 1) Bob should accept the xor a_bits^cbits e_ij as classical message from Alice
62 | 2) Bob send Alice the xor b_bits^dbits as classical message f_ij
63 | 3) According to value of e_ij from Alice, Bob sends qubits to Alice
64 |
65 | In the fourth and fifth steps:
66 | 1) Bob accepts a_bits as a classical message from Alice
67 | 2) Bob sends b-bits as a classical message to Alice
68 | 3) According to value of accepted a_bits. applied rotX
69 | 4) And qubits were measured
70 |
71 | the same process was done for opposite b_bits. This time
72 | 1) According to opposite b_bits (which is called b_j_bar) applied rot_X
73 | 2) After applying rot_X, qubits were measured
74 |
75 | In the final step:
76 | The final bit of each of the party is the xor of xor of the random bits,
77 | they prepared in the first step and xor of the bits they measured in the fourth step.
78 | This final bit is the random bit which has come up in the 'coin toss'.
79 | Thus ends the protocol.
80 |
81 | Results of these 2 final steps should be same
82 |
--------------------------------------------------------------------------------
/QuantumCoinFlippingPappa/1_Honest_Participants/aliceCoin.py:
--------------------------------------------------------------------------------
1 | from cqc.pythonLib import CQCConnection, qubit
2 |
3 | import random
4 | import numpy
5 | import math
6 | #########################################
7 | #
8 | # FUNCTIONS
9 | #
10 | def ACKSend(name, target, data):
11 | name.sendClassical(target, data)
12 | while bytes(name.recvClassical(msg_size=3)) != b'ACK':
13 | pass
14 |
15 | def ACKRecv(name, target):
16 | data = list(name.recvClassical())
17 | name.sendClassical(target, list(b'ACK'))
18 | return data
19 |
20 | def addNoise(q, noise):
21 | if random.random()transmission:
33 | q.measure()
34 | measurements[0].append('-')
35 | measurements[1].append('-')
36 | else:
37 | m=measureInBasis(q, beta[k], y)
38 | measurements[beta[k]].append(m)
39 | measurements[(beta[k]+1)%2].append('-')
40 | ACKSend(name, target, list(b'ACK'))
41 | return measurements
42 |
43 | def J(measurements, K):
44 | m00=K+1
45 | m01=K+1
46 | m10=K+1
47 | m11=K+1
48 | if measurements[0].count(0)>0:
49 | m00=measurements[0].index(0)
50 | if measurements[0].count(1)>0:
51 | m01=measurements[0].index(1)
52 | if measurements[1].count(0)>0:
53 | m10=measurements[1].index(0)
54 | if measurements[1].count(1)>0:
55 | m11=measurements[1].index(1)
56 | if min(m00,m01,m10,m11)==K+1:
57 | print("No Measurements made")
58 | else:
59 | return min(m00,m01,m10,m11)
60 | #########################################
61 | #
62 | # MAIN
63 | #
64 | def prep_bob():
65 | # Get parameters
66 | config=numpy.loadtxt("config.txt")
67 | K=int(config[0])
68 | y=float(config[1])
69 | transmission=float(config[2])
70 |
71 | # Create string: beta_i in {0,1}
72 | beta=[]
73 | for k in range (0,K):
74 | beta.append(random.randint(0,1))
75 | b=random.randint(0,1)
76 |
77 | # Initialise connection
78 | with CQCConnection("Bob") as Bob:
79 |
80 | # Bob performs the quantum part of the protocol until he makes a successful measurement
81 | measurements=coinFlipBob(Bob, "Alice", beta, y, K, transmission)
82 | # Bob calculates the position of his first successful measurement
83 | j=J(measurements, K)
84 | b=random.randint(0,1)
85 |
86 | # Bob sends the random bit, b, and j
87 | print("Bob sends b={} and j={}".format(b,j))
88 | ACKSend(Bob, "Alice", [b,j])
89 |
90 | # Bob receives c_j and alpha_j
91 | data=list(ACKRecv(Bob, "Alice"))
92 | alpha_j=data[0]
93 | c_j=data[1]
94 |
95 | # Bob computes the outcome of the coin flip
96 | if beta[j] ==alpha_j and measurements[beta[j]][j]==c_j:
97 | COIN=(b+c_j) % 2
98 | elif beta[j] != alpha_j:
99 | COIN=(b+c_j) % 2
100 | print("Basis different")
101 | else:
102 | COIN=9
103 | print("ABORT")
104 |
105 | if COIN!=9:
106 | if COIN:
107 | winner="Bob"
108 | else:
109 | winner="Alice"
110 |
111 | to_print="{} WINS".format(winner)
112 | print("|"+"-"*(len(to_print)+2)+"|")
113 | print("| "+to_print+" |")
114 | print("|"+"-"*(len(to_print)+2)+"|")
115 |
116 |
117 | if __name__ == "__main__":
118 | prep_bob()
119 |
--------------------------------------------------------------------------------
/QuantumCoinFlippingPappa/1_Honest_Participants/config.txt:
--------------------------------------------------------------------------------
1 | 50
2 | 0.9
3 | 0.1
4 | 0.05
--------------------------------------------------------------------------------
/QuantumCoinFlippingPappa/1_Honest_Participants/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | python aliceCoin.py &
3 | python bobCoin.py &
4 |
--------------------------------------------------------------------------------
/QuantumCoinFlippingPappa/2_Cheating_Alice/aliceCoin.py:
--------------------------------------------------------------------------------
1 | from cqc.pythonLib import CQCConnection, qubit
2 |
3 | import random
4 | import numpy
5 | import math
6 | #########################################
7 | #
8 | # FUNCTIONS
9 | #
10 | def ACKSend(name, target, data):
11 | name.sendClassical(target, data)
12 | while bytes(name.recvClassical(msg_size=3)) != b'ACK':
13 | pass
14 |
15 | def ACKRecv(name, target):
16 | data = list(name.recvClassical())
17 | name.sendClassical(target, list(b'ACK'))
18 | return data
19 |
20 | def addNoise(q, noise):
21 | if random.random()transmission:
37 | q.measure()
38 | measurements[0].append('-')
39 | measurements[1].append('-')
40 | else:
41 | m=measureInBasis(q, beta[k], y)
42 | measurements[beta[k]].append(m)
43 | measurements[(beta[k]+1)%2].append('-')
44 | ACKSend(name, target, list(b'ACK'))
45 | return measurements
46 |
47 | def J(measurements, K):
48 | m00=K+1
49 | m01=K+1
50 | m10=K+1
51 | m11=K+1
52 | if measurements[0].count(0)>0:
53 | m00=measurements[0].index(0)
54 | if measurements[0].count(1)>0:
55 | m01=measurements[0].index(1)
56 | if measurements[1].count(0)>0:
57 | m10=measurements[1].index(0)
58 | if measurements[1].count(1)>0:
59 | m11=measurements[1].index(1)
60 | if min(m00,m01,m10,m11)==K+1:
61 | print("No Measurements made: ABORT")
62 | else:
63 | return min(m00,m01,m10,m11)
64 | #########################################
65 | #
66 | # MAIN
67 | #
68 | def prep_bob():
69 | # Get parameters
70 | config=numpy.loadtxt("config.txt")
71 | K=int(config[0])
72 | y=float(config[1])
73 | transmission=float(config[2])
74 |
75 | # Create string: beta_i in {0,1}
76 | beta=[]
77 | for k in range (0,K):
78 | beta.append(random.randint(0,1))
79 | b=random.randint(0,1)
80 |
81 | # Initialise connection
82 | with CQCConnection("Bob") as Bob:
83 |
84 | # Bob performs the quantum part of the protocol until he makes a successful measurement
85 | measurements=coinFlipBob(Bob, "Alice", beta, y, K, transmission)
86 |
87 | # Bob calculates the position of his first successful measurement
88 | j=J(measurements, K)
89 | b=random.randint(0,1)
90 |
91 | # Bob sends the random bit, b, and j
92 | print("Bob sends b={} and j={}".format(b,j))
93 | ACKSend(Bob, "Alice", [b,j])
94 |
95 | # Bob receives c_j and alpha_j
96 | data=list(ACKRecv(Bob, "Alice"))
97 | alpha_j=data[0]
98 | c_j=data[1]
99 |
100 | # Bob computes the outcome of the coin flip
101 | if beta[j] ==alpha_j and measurements[beta[j]][j]==c_j:
102 | COIN=(b+c_j) % 2
103 | elif beta[j] != alpha_j:
104 | COIN=(b+c_j) % 2
105 | print("Basis different")
106 | else:
107 | COIN=9
108 | print("BOB detects cheating: ABORT")
109 |
110 | if COIN!=9:
111 | if COIN:
112 | winner="Bob"
113 | else:
114 | winner="Alice"
115 |
116 | to_print="{} WINS".format(winner)
117 | print("|"+"-"*(len(to_print)+2)+"|")
118 | print("| "+to_print+" |")
119 | print("|"+"-"*(len(to_print)+2)+"|")
120 |
121 | if __name__ == "__main__" :
122 | prep_bob()
123 |
--------------------------------------------------------------------------------
/QuantumCoinFlippingPappa/2_Cheating_Alice/config.txt:
--------------------------------------------------------------------------------
1 | 50
2 | 0.9
3 | 0.1
4 | 0.05
--------------------------------------------------------------------------------
/QuantumCoinFlippingPappa/2_Cheating_Alice/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | python aliceCoin.py &
3 | python bobCoin.py &
4 |
--------------------------------------------------------------------------------
/QuantumCoinFlippingPappa/3_Cheating_Bob/aliceCoin.py:
--------------------------------------------------------------------------------
1 | from cqc.pythonLib import CQCConnection, qubit
2 |
3 | import random
4 | import numpy
5 | import math
6 | #########################################
7 | #
8 | # FUNCTIONS
9 | #
10 | def ACKSend(name, target, data):
11 | name.sendClassical(target, data)
12 | while bytes(name.recvClassical(msg_size=3)) != b'ACK':
13 | pass
14 |
15 | def ACKRecv(name, target):
16 | data = list(name.recvClassical())
17 | name.sendClassical(target, list(b'ACK'))
18 | return data
19 |
20 | def addNoise(q, noise):
21 | if random.random()transmission:
26 | q.measure()
27 | measurements[0].append('-')
28 | measurements[1].append('-')
29 | else:
30 | measurements[beta[k]].append(q.measure())
31 | measurements[(beta[k]+1)%2].append('-')
32 | ACKSend(name, target, list(b'ACK'))
33 | return measurements
34 |
35 | def J(measurements, K):
36 | m00=K+1
37 | m01=K+1
38 | m10=K+1
39 | m11=K+1
40 | if measurements[0].count(0)>0:
41 | m00=measurements[0].index(0)
42 | if measurements[0].count(1)>0:
43 | m01=measurements[0].index(1)
44 | if measurements[1].count(0)>0:
45 | m10=measurements[1].index(0)
46 | if measurements[1].count(1)>0:
47 | m11=measurements[1].index(1)
48 | if min(m00,m01,m10,m11)==K+1:
49 | print("No Measurements made")
50 | else:
51 | return min(m00,m01,m10,m11)
52 | #########################################
53 | #
54 | # MAIN
55 | #
56 | def prep_bob():
57 | # Get parameters
58 | config=numpy.loadtxt("config.txt")
59 | K=int(config[0])
60 | transmission=float(config[2])
61 |
62 | # Create string: beta_i in {0,1}
63 | beta=[]
64 | for k in range (0,K):
65 | beta.append(random.randint(0,1))
66 |
67 | # Initialise connection
68 | with CQCConnection("Bob") as Bob:
69 |
70 | # Bob performs the quantum part of the protocol until he makes a successful measurement
71 | measurements=coinFlipBob(Bob, "Alice", beta, K, transmission)
72 |
73 | # Bob calculates the position of his first successful measurement
74 | j=J(measurements, K)
75 | b=(measurements[beta[j]][j]+1)%2
76 | print("Bob measured {}".format(measurements[beta[j]][j]))
77 |
78 | # Bob sends the random bit, b, and j
79 | print("Bob sends b={} and j={}".format(b,j))
80 | ACKSend(Bob, "Alice", [b,j])
81 |
82 | # Bob receives c_j and alpha_j
83 | data=list(ACKRecv(Bob, "Alice"))
84 | alpha_j=data[0]
85 | c_j=data[1]
86 |
87 | # Bob computes the outcome of the coin flip
88 | COIN=(b+c_j) % 2
89 |
90 | if COIN:
91 | winner="Bob"
92 | else:
93 | winner="Alice"
94 |
95 | to_print="{} WINS".format(winner)
96 | print("|"+"-"*(len(to_print)+2)+"|")
97 | print("| "+to_print+" |")
98 | print("|"+"-"*(len(to_print)+2)+"|")
99 |
100 |
101 | if __name__ == "__main__":
102 | prep_bob()
103 |
--------------------------------------------------------------------------------
/QuantumCoinFlippingPappa/3_Cheating_Bob/config.txt:
--------------------------------------------------------------------------------
1 | 50
2 | 0.9
3 | 0.1
4 | 0.05
--------------------------------------------------------------------------------
/QuantumCoinFlippingPappa/3_Cheating_Bob/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | python aliceCoin.py &
3 | python bobCoin.py &
4 |
--------------------------------------------------------------------------------
/QuantumCoinFlippingPappa/4_Ideal_Coin_Flipping/aliceCoin.py:
--------------------------------------------------------------------------------
1 | from cqc.pythonLib import CQCConnection, qubit
2 |
3 | import random
4 | import numpy
5 | import math
6 | #########################################
7 | #
8 | # FUNCTIONS
9 | #
10 | def ACKSend(name, target, data):
11 | name.sendClassical(target, data)
12 | while bytes(name.recvClassical(msg_size=3)) != b'ACK':
13 | pass
14 |
15 | def ACKRecv(name, target):
16 | data = list(name.recvClassical())
17 | name.sendClassical(target, list(b'ACK'))
18 | return data
19 |
20 | def prepareQubit(name, alpha, c, y):
21 | q=qubit(name)
22 | if c==0:
23 | q.rot_Y(round((256/math.pi)*math.acos(math.sqrt(y))))
24 | q.rot_Z(128*alpha)
25 | elif c==1:
26 | q.rot_Y(round((256/math.pi)*math.acos(math.sqrt(1-y))))
27 | q.rot_Z(128*((alpha+1)%2))
28 | return q
29 |
30 | def QcoinFlipAlice(name, target, aliceString,y):
31 | q=prepareQubit(name, aliceString[0], aliceString[1], y)
32 | name.sendQubit(q, target)
33 | ACKRecv(name, target)
34 |
35 | #########################################
36 | #
37 | # MAIN
38 | #
39 | def prep_alice():
40 | # Get parameters
41 | y=0.9
42 |
43 | # Choose two bits: alpha in {0,1} and c in {0,1}
44 | aliceString=[random.randint(0,1),random.randint(0,1)]
45 |
46 | # Initialise connection
47 | with CQCConnection("Alice") as Alice:
48 |
49 | # Alice performs the quantum part of the protocol until Bob makes a successful measurement
50 | QcoinFlipAlice(Alice, "Bob", aliceString, y)
51 |
52 | # Alice receives the random bit and the position of first successful measurement from Bob
53 | data=list(ACKRecv(Alice, "Bob"))
54 | b=data[0]
55 |
56 | # Alice sends c and alpha
57 | print("Alice sends alpha={} and c={}".format(aliceString[0],aliceString[1]))
58 | ACKSend(Alice, "Bob", aliceString)
59 |
60 | # Alice computes the outcome of the coin flip
61 | COIN=(b+aliceString[1]) % 2
62 |
63 |
64 | if __name__ == "__main__":
65 | prep_alice()
66 |
--------------------------------------------------------------------------------
/QuantumCoinFlippingPappa/4_Ideal_Coin_Flipping/bobCoin.py:
--------------------------------------------------------------------------------
1 | from cqc.pythonLib import CQCConnection, qubit
2 |
3 | import random
4 | import numpy
5 | import math
6 | #########################################
7 | #
8 | # FUNCTIONS
9 | #
10 | def ACKSend(name, target, data):
11 | name.sendClassical(target, data)
12 | while bytes(name.recvClassical(msg_size=3)) != b'ACK':
13 | pass
14 | return 1
15 |
16 | def ACKRecv(name, target):
17 | data = list(name.recvClassical())
18 | name.sendClassical(target, list(b'ACK'))
19 | return data
20 |
21 | def measureInBasis(q, beta, y):
22 | q.rot_Z(128*beta)
23 | q.rot_Y(256-round((256/math.pi)*math.acos(math.sqrt(y))))
24 | m=q.measure()
25 | return m
26 |
27 | def coinFlipBob(name, target, beta, y):
28 | q=name.recvQubit()
29 | m=measureInBasis(q, beta, y)
30 | measurement=[beta,m]
31 | ACKSend(name, target, list(b'ACK'))
32 | return measurement
33 |
34 | #########################################
35 | #
36 | # MAIN
37 | #
38 | def prep_bob():
39 | # Get parameters
40 | y=0.9
41 |
42 | # Create string: beta_i in {0,1}
43 | beta=random.randint(0,1)
44 |
45 | # Initialise connection
46 | with CQCConnection("Bob") as Bob:
47 |
48 | # Bob performs the quantum part of the protocol until he makes a successful measurement
49 | measurement=coinFlipBob(Bob, "Alice", beta, y)
50 |
51 | # Bob calculates the position of his first successful measurement
52 | b=random.randint(0,1)
53 |
54 | # Bob sends the random bit, b, and j
55 | print("Bob sends b={}".format(b))
56 | ACKSend(Bob, "Alice", [b])
57 |
58 | # Bob receives c_j and alpha_j
59 | data=list(ACKRecv(Bob, "Alice"))
60 | alpha=data[0]
61 | c=data[1]
62 |
63 | # Bob computes the outcome of the coin flip
64 | if beta == alpha and measurement[1]==c:
65 | COIN=(b+c) % 2
66 | elif beta != alpha:
67 | COIN=(b+c) % 2
68 | print("Basis different")
69 | else:
70 | COIN=9
71 | print("ABORT")
72 |
73 | if COIN!=9:
74 | if COIN:
75 | winner="Bob"
76 | else:
77 | winner="Alice"
78 |
79 | to_print="{} WINS".format(winner)
80 | print("|"+"-"*(len(to_print)+2)+"|")
81 | print("| "+to_print+" |")
82 | print("|"+"-"*(len(to_print)+2)+"|")
83 |
84 | if __name__ == "__main__":
85 | prep_bob()
86 |
--------------------------------------------------------------------------------
/QuantumCoinFlippingPappa/4_Ideal_Coin_Flipping/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | python aliceCoin.py &
3 | python bobCoin.py &
4 |
--------------------------------------------------------------------------------
/QuantumCoinFlippingPappa/README.md:
--------------------------------------------------------------------------------
1 |
2 | ==================================
3 | Quantum Coin Flipping Protocol
4 | ==================================
5 |
6 | This project contains the SimulaQron implementation of the quantum coin flipping protocol based on the following papers:
7 |
8 | "Practical Quantum Coin Flipping" - A. Pappa et al.
9 | https://arxiv.org/abs/1106.1099
10 |
11 | "Experimental plug&play quantum coin flipping" - A. Pappa et al.
12 | https://www.nature.com/articles/ncomms4717
13 |
14 |
15 | The protocol is an implementation of the basic coin flipping protocol described in the papers above. In the implementation, Alice's source was assummed to be a single photon source which meant that Bob always received at most one qubit from a pulse.
16 |
17 | DESCRIPTION OF PROTOCOL
18 | =======================
19 |
20 | - Alice chooses K pairs (alpha_i, c_i) where i=1,...,K. Alpha_i will correspond to the basis the ith pulse will be prepared in and c_i will correspond to the state of that pulse (see notes).
21 | - Alice sends the states to Bob who picks a random basis beta_i to measure each pulse in. Due to the lossy nature of the quantum channel, his first successful measurement may not be of the first photon.
22 | - If he makes at least one successful measurement from the K pulses, he sends to Alice the position of the first successful measurement, j, and a random bit b.
23 | - Alice replies to Bob with the basis and the state of that qubit, (alpha_j, c_j).
24 | - If alpha_j=beta_j and Bob's outcome is the same as the one Alice declares, or if alpha_j =/= beta_j, both parties agree that the coin value is c_j XOR b. If they did measure in the same basis but Alice's declared c_j is different from Bob's measurement, Bob aborts.
25 |
26 | IMPLEMENTATION
27 | ==============
28 |
29 | The implementation makes use of the Develop branch of SimulaQron although should in theory run in the ProBeta version.
30 |
31 | The code makes use of arbitrary rotations, thus it is necessary to use a simulation backend that has this capability, such as projectq. You can then start simulaqron using the following commands:
32 | simulaqron reset
33 | simulaqron set backend projectq
34 | simulaqron start
35 |
36 | The project contains four versions: all parties are honest, Alice attempts to cheat, Bob attempts to cheat, ideal coin flipping. These can be run going into the desired folder in command line and running
37 |
38 | sh run.sh
39 |
40 | The simulation files also contain a config file which defines the parameters of each run. The file has the following format:
41 |
42 | (K - number of pulses [integer])
43 | (y - security parameter [float])
44 | (F - channel loss [float])
45 | (qber - qubit error rate [float])
46 |
47 | It should be noted that the code for ACKSend and ACKRecv were borrowed from the QChat project by Matthew Skrzypczyk (http://www.simulaqron.org/competition/).
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/QuantumCoinFlippingPappa/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quantumprotocolzoo/protocols/3367ceeb8a4d9825b979203190e254ca57fe0e74/QuantumCoinFlippingPappa/__init__.py
--------------------------------------------------------------------------------
/QuantumLeaderElection/README.txt:
--------------------------------------------------------------------------------
1 | # Coin Flip Leader Election
2 |
3 | ## How to run
4 |
5 | ```
6 | sh $NETSIM/run/startAll.sh
7 | ./run.sh
8 | ```
9 |
10 | Note that you need to give the nodes a few seconds to start up after running
11 | the first command.
12 |
13 | ## Explanation
14 |
15 | It is possible to elect a leader from a collection of N nodes by performing a
16 | series of coin flips as explained in [this
17 | paper](https://arxiv.org/abs/0910.4952v2).
18 |
--------------------------------------------------------------------------------
/QuantumLeaderElection/fourPartyLeaderElection.py:
--------------------------------------------------------------------------------
1 | from cqc.pythonLib_protocols.coinflip_leader import CoinflipConsensus
2 |
3 |
4 | def main():
5 | """
6 | Creates array of four people and elects a leader among them using
7 | the CoinFlipConsensus protocol.
8 | """
9 | arr = ["Alice", "Bob", "Charlie", "David"]
10 | leaderChooser = CoinflipConsensus(arr)
11 | return leaderChooser.leader()
12 |
13 |
14 | # Runs 20 rounds of leader election and prints the results.
15 | d = dict()
16 | d["Alice"] = 0
17 | d["Bob"] = 0
18 | d["Charlie"] = 0
19 | d["David"] = 0
20 | for i in range(0, 20):
21 | if i % 10 == 0:
22 | print(i)
23 | d[main()] += 1
24 | print(d)
25 |
--------------------------------------------------------------------------------
/QuantumLeaderElection/nPartyLeaderElection.py:
--------------------------------------------------------------------------------
1 | from cqc.pythonLib_protocols.coinflip_leader import CoinflipConsensus
2 |
3 |
4 | def main():
5 |
6 | leaderChooser = CoinflipConsensus(arr) # Elects a leader from array that you declared
7 | return leaderChooser.leader()
8 |
9 | # For 12-13-14-15 lines: After seeing "Add person" sentence, you can add person that how many person you want to add.
10 | # After adding one person you should press "enter" and then you can continue to add person with press enter
11 | # If you want to cancel from adding person you should press enter again
12 | # After enter the all name that you wanted to add you should press "enter"
13 | # Note that: you should use name from cqc's names space such as Alice, Bob, David, Eve Charlie.., you cant't use name randomly such as Gozde, Axel ...
14 | arr = [] # Here an empty array was defined
15 | veri = input("Add person")
16 | while veri:
17 | arr.append(veri)
18 | veri = input("Add person")
19 |
20 |
21 | # giving a value for each leader
22 | d = dict()
23 | for veri in arr:
24 | d[veri] = 0
25 |
26 | # Runs 20 rounds of leader election and prints the results.
27 | for i in range(0, 20):
28 | if i % 10 == 0:
29 | print(i)
30 | d[main()] += 1
31 |
32 |
33 | print(d)
34 |
--------------------------------------------------------------------------------
/QuantumNumberGeneration/quantum_number_generation.py:
--------------------------------------------------------------------------------
1 | from cqc.pythonLib import CQCConnection, qubit
2 |
3 | #####################################################################################################
4 | #In this example, we produce fresh coin/random number with using quantum logical gates.
5 | # While creating quantum random generator, steps of coin analogy was used.For this
6 | # 1) a new qubit was produced and this stpe similar to fishing coin
7 | # 2) applied hadamard gate, this step can be equal that tossing a coin in air
8 | # 3)Finally measured qubit and this is like that we can learn now the coin's result like head or tail
9 |
10 |
11 | def qrng(location_string='Alice') :
12 | with CQCConnection(location_string) as location:
13 | q = qubit(location)
14 | q.H()
15 | number = q.measure()
16 | print('Outcome of the measurement at', location, ':', number) ;
17 | return number
18 |
19 | def test():
20 | print('Returned List of Quantum Random Numbers', [ qrng() for i in range(10)] )
21 |
22 | if __name__ == '__main__': test()
23 |
24 | ##################################################################################################
25 |
--------------------------------------------------------------------------------
/QuantumNumberGeneration/readme.md:
--------------------------------------------------------------------------------
1 | We connect a node (Alice) and create a fresh qubit then apply a Hadamard gate.
2 | After measuring the qubit, we repeat the process 10 times(in the for loop)and
3 | finally we create an empty list in order to saving the quantum numbers or coins
4 | and the quantum numbers/coins are printed in the screen
5 |
--------------------------------------------------------------------------------
/QuantumStateTeleportation/quantum_state_teleportation.py:
--------------------------------------------------------------------------------
1 | from cqc.pythonLib import CQCConnection, qubit
2 | import argparse
3 |
4 | '''
5 | This function(generate_bell_pair) for creating a bell pair from two qubit.
6 | For this 1) created qubit from Alice for will create message state
7 | 2)created qubit from Bob for recreating the message state
8 | 3)applied Hadamard gate for qubit1
9 | 4)appled cnot gate
10 | '''
11 |
12 |
13 | def generate_bell_pair():
14 | with CQCConnection("Alice") as Alice:
15 | qubit1 = qubit(Alice)
16 | with CQCConnection("Bob") as Bob:
17 | qubit2 = qubit(Alice)
18 | qubit1.H()
19 | qubit1.cnot(qubit2)
20 | return qubit1, qubit2
21 |
22 |
23 | '''
24 | In this furnction one of the entangled qubit was used as an input.
25 | And a message value is a bit (value 0 or 1) was used as an input.
26 | 1)A new fresh qubit was produced
27 | 2)If message value is equal 1, then qubit is set to positive
28 | by flipping the base state with X gate
29 | 3)original qubit and message bit was entangled
30 | 4)Message qubit was put in superpositon
31 | 5)they were measured
32 | 6)Finally the qubits turn into normal bits
33 | '''
34 |
35 |
36 | def create_message(qubit1, message = 0):
37 | with CQCConnection("Alice") as Alice:
38 | qubit_send = qubit(Alice)
39 | qubit1 = qubit(Alice)
40 | if message == 1:
41 | qubit_send.X()
42 | qubit_send.cnot(qubit1)
43 | qubit_send.H()
44 | a = qubit_send.measure()
45 | b = qubit1.measure()
46 | classical_encoded_message = [int(a), int(b)]
47 | return classical_encoded_message
48 |
49 |
50 | '''
51 | With This function, message is accepted and transformed classical
52 | encoded message. Second qubit from bell pair was used.
53 | 1)According to the 2 message value applied X or Z gate
54 | 2)qubits was measured
55 | 3)converted to int
56 | '''
57 |
58 |
59 | def message_reciever(message, qubit2):
60 | with CQCConnection("Bob") as Bob:
61 | qubit2 = qubit(Bob)
62 | if message[1] == 1:
63 | qubit2.X()
64 | if message[0] == 1:
65 | qubit2.Z()
66 | d = qubit2.measure()
67 | recieve_bit = d
68 | recieve_bit = int(d)
69 | return recieve_bit
70 |
71 |
72 | '''
73 | In this function
74 | 1) created bell pair
75 | 2)created message
76 | 3)After sending message reciever, results are returned
77 | '''
78 |
79 |
80 | def send_recieve(bit = 0):
81 | with CQCConnection("Alice") as Alice:
82 | with CQCConnection("Bob") as Bob:
83 | qubit2 = qubit(Bob)
84 | qubit1 = qubit(Alice)
85 | qubit1, qubit2 = generate_bell_pair()
86 | classical_encoded_message = create_message(qubit1 = qubit1, message = bit)
87 | return message_reciever(classical_encoded_message, qubit2)
88 |
89 |
90 | '''
91 | This is the last function of sending message with
92 | using Quantum State Teleportation in CQC
93 | 1)When user run the code with a message, firstly message
94 | transformed binary encoded message
95 | 2)binary message is divided into a list
96 | 3)iterated through each word and each bit
97 | 4)And thanks to send_recieve funtionbacking tho original letter
98 | '''
99 |
100 |
101 | def send_all_message(message = 'hello'):
102 | binary_encoded_message = [bin(ord(x))[2:].zfill(8) for x in message]
103 | print('Message to send: ', message)
104 | print('Binary message to send: ', binary_encoded_message)
105 | received_bytes_list = []
106 | for letter in binary_encoded_message:
107 | received_bits = ''
108 | for bit in letter:
109 | received_bits = received_bits + str(send_recieve(int(bit)))
110 | received_bytes_list.append(received_bits)
111 | binary_to_string = ''.join([chr(int(x, 2)) for x in received_bytes_list])
112 | print('Received Binary message: ', received_bytes_list)
113 | print('Received message: ', binary_to_string)
114 |
115 |
116 | '''
117 | Now user can run the code with like this sentence
118 | python3 quantum_state_teleportation.py -m deneme
119 | NOte that I prefered the one words a message
120 | I have not tried the code more than one words.
121 | Bests!!
122 | '''
123 |
124 |
125 | if __name__ == "__main__":
126 | parser = argparse.ArgumentParser(description='Send a message using Quantum State Teleportation with CQC')
127 | requiredNamed = parser.add_argument_group('Required arguments')
128 | requiredNamed.add_argument('-m','--message',required=True, help='message')
129 | args = parser.parse_args()
130 | send_all_message(args.message)
131 |
--------------------------------------------------------------------------------
/QuantumStateTeleportation/readme.md:
--------------------------------------------------------------------------------
1 | In this example, aimed the sending a message with using quantum state teleportation.
2 | Code has 5 function and almost all function includes all of basics command in cqc like:
3 | generating fresh qubit,
4 | applying quantum gates,
5 | measuring.
6 | In the code you can find detailed knowlegde and I didn't divide the code as 2 parts for ALice and Bob.
7 | However if you want, of course you can but I dont it
8 | You can use the code with this sentence: python3 quantum_state_teleportation.py -m message Happy coding!!
9 |
--------------------------------------------------------------------------------
/QuantumToken/QuantumToken.md:
--------------------------------------------------------------------------------
1 | # Outline
2 | In this directory you will find the files implementing the Quantum Token protocol:
3 | - https://wiki.veriqloud.fr/index.php?title=Quantum_Token for an operational description
4 | - Experimental investigation of practical unforgeable quantum money https://arxiv.org/pdf/1705.01428.pdf for more details.
5 |
6 | The protocol has 3 players: Bank (Alice), Client (Eve) and Merchant (Bob)
7 |
8 | Before starting simulaqron run `simulaqron set max-qubits 100`
9 |
10 | # Preparing and distributing the money
11 | In the QuantumTokenBank.py code:
12 |
13 | 1) Bank(Alice) prepares the money. For this:
14 |
15 | -Bank prepares randombits and randombits2 and saves in a different list
16 |
17 | -Bank prepares randombasis for encoding the bits and saves in a list
18 |
19 | -Bank produces 2 fresh qubits as qubit1 and qubit2.
20 |
21 | -Bank applies the gates according to the values of bits and basis
22 |
23 | -Bank saves these 2 qubits in a list which is called token
24 |
25 | 2) Finally bank sends qubits to client
26 |
27 | In the QuantumTokenClient.py code:
28 |
29 | 1) Client(Eve) receives qubits and then sends Merchant qubits.
30 |
31 | # Using the money
32 | After giving money to Merchant second stage is starting
33 |
34 | In the QuantumTokenMerchant.py code:
35 |
36 | 1) Merchant(Bob) accepts qubits from Client
37 |
38 | 2) Merchant produces a bit randomly
39 |
40 | 3) According to the value of random bit, Merchant apply quantum gates
41 |
42 | 4) After applying gates, Merchant measures the qubits
43 |
44 | 5) After measuring qubits, the result of measurement and random bit are sent to Bank
45 |
46 | In the QuantumTokenBank.py code:
47 |
48 | 1) Bank accepts qubits and bit from Merchant
49 |
50 | 2) After that Bank should check the values for preventing cheating. For this:
51 |
52 | -Bank looks value of accepted bit from Merchant and if it is equal to zero, then:
53 |
54 | -Bank looks value of its basis values
55 |
56 | -If these two values equal zero then:
57 |
58 | -Bank checks values of accepted bit and basis
59 |
60 | -If these two values different then:
61 |
62 | -Cheating!!
63 | -If these value of basis is not equal zero then:
64 |
65 | -cheating !!
66 |
67 | -If value of accepted bit is not equal to zero then:
68 |
69 | -If value of accepted bit and basis are different from each other, then:
70 |
71 | -If that bank basis is equal zero
72 |
73 | -If value of accepted bit and bank basis are different, then:
74 |
75 | -Cheating
76 |
77 | -If bank basis is not equal zero, then:
78 |
79 | !Cheating
80 |
81 |
82 |
--------------------------------------------------------------------------------
/QuantumToken/QuantumTokenBank.py:
--------------------------------------------------------------------------------
1 | from random import randint, random, sample
2 | from time import sleep
3 | from cqc.pythonLib import CQCConnection, qubit
4 |
5 |
6 | cheating = 0
7 | wait = 2
8 | N = 2
9 | M = 8
10 | random_pair_number = []
11 | Bank_bits2 = [ [] for i in range(M) ]
12 | Bank_bits = [ [] for i in range(M) ]
13 | Bank_basis = [[] for j in range(M)]
14 | token = [[] for i in range(M)]
15 | outcomes_from_merchant = []
16 | s = []
17 | def distributing_money():
18 | global cheating
19 | print("The first part is starting and The bank prepare the money")
20 | with CQCConnection("Alice") as Alice:
21 | for serial in range(M):
22 | for j in range(N):
23 | random_bits = randint(0,1)
24 | random_bits2 = randint(0,1)
25 | random_basis = randint(0,1)
26 | Bank_bits2[serial].append(random_bits2)
27 | Bank_bits[serial].append(random_bits)
28 | Bank_basis[serial].append(random_basis)
29 | q1 = qubit(Alice)
30 | q2 = qubit(Alice)
31 | if random_bits == 1:
32 | q1.X()
33 | if random_bits2 == 1:
34 | q2.X()
35 | if random_basis == 1:
36 | q1.H()
37 | else:
38 | q2.H()
39 | token[j].append((q1,q2))
40 | Alice.sendQubit(q1, "Eve")
41 | Alice.sendQubit(q2, "Eve")
42 | Alice.flush()
43 | print("Bank sent qubits pairs/token to Client")
44 | sleep(wait)
45 | for serial in range(M):
46 | for j in range(N):
47 | outcomes_from_merchant = list(Alice.recvClassical())
48 | print ("The bank accepts the bits and base from merchant: ", outcomes_from_merchant)
49 |
50 | if outcomes_from_merchant[2] == 0:
51 | which_qubit_to_check = Bank_basis[serial][j]
52 | if which_qubit_to_check == 0:
53 | if Bank_bits[serial][j] != outcomes_from_merchant[0]:
54 | print("1. Cheating")
55 | cheating += 1
56 | else:
57 | if Bank_bits2[serial][j] != outcomes_from_merchant[1]:
58 | print("2. Cheating")
59 | cheating += 1
60 | else:
61 | which_qubit_to_check = 1 - Bank_basis[serial][j]
62 | if which_qubit_to_check == 0:
63 | if Bank_bits[serial][j] != outcomes_from_merchant[0]:
64 | print("3. Cheating")
65 | cheating += 1
66 | else:
67 | if Bank_bits2[serial][j] != outcomes_from_merchant[1]:
68 | print(Bank_bits2[serial][j])
69 | print(outcomes_from_merchant[1])
70 | print("4. Cheating")
71 | cheating += 1
72 | if (cheating > 0):
73 | print ("There is cheating here :( Money rejected", cheating)
74 | else:
75 | print ("There is no cheating, super! :) Money accepted")
76 | print ("End of protocol !")
77 |
78 | if __name__ == "__main__":
79 | distributing_money()
80 |
--------------------------------------------------------------------------------
/QuantumToken/QuantumTokenClient.py:
--------------------------------------------------------------------------------
1 | from random import randint, random, sample
2 | from time import sleep
3 | from cqc.pythonLib import CQCConnection, qubit
4 |
5 |
6 |
7 | M = 8
8 | N = 2
9 | wait = 2
10 | basis = []
11 | serialnumbers = []
12 | accepted_basis = []
13 | measurements = []
14 | trueindex = []
15 | truebits = []
16 | Bob_recv = [ [] for i in range(8) ]
17 | bank_bits_pairs = [[] for i in range(N)]
18 | accepted_qubits = []
19 | def use_money():
20 | with CQCConnection("Eve") as Eve:
21 | print("Client part is starting: ")
22 | for serial in range(M):
23 | for j in range(N):
24 | q1 = Eve.recvQubit()
25 | q2 = Eve.recvQubit()
26 | # accepted_qubits[j].append((q1,q2))
27 | # Eve.sendQubit(accepted_qubits[j],"Bob")
28 | Eve.sendQubit(q1, "Bob")
29 | Eve.sendQubit(q2, "Bob")
30 |
31 | print("The client(Eve) gave money to Merchant(Bob)")
32 | print ("Second stage is starting: ")
33 |
34 |
35 |
36 | if __name__ == "__main__":
37 | use_money()
38 |
--------------------------------------------------------------------------------
/QuantumToken/QuantumTokenMerchant.py:
--------------------------------------------------------------------------------
1 | from random import randint, random, sample
2 | from time import sleep
3 | from cqc.pythonLib import CQCConnection, qubit
4 |
5 |
6 | M = 8
7 | N = 2
8 | wait = 2
9 | results_of_qubit = [ [] for i in range(M) ]
10 | accepted_qubits_from_client = []
11 |
12 | def merchants():
13 | with CQCConnection("Bob") as Bob:
14 |
15 | for serial in range(M):
16 | for j in range(N):
17 | q1 = Bob.recvQubit()
18 | q2 = Bob.recvQubit()
19 | random_bit = randint(0,1)
20 | if random_bit == 1:
21 | q1.H()
22 | q2.H()
23 | m1 = q1.measure()
24 | m2 = q2.measure()
25 | results_of_qubit[j].append((m1, m2,random_bit))
26 | for serial in range(M):
27 | for j in range(N):
28 | sleep(wait)
29 | Bob.sendClassical("Alice", results_of_qubit[j][serial])
30 | print("Now the merchant sent the outcomes and basis to the bank: ",results_of_qubit[j][serial] )
31 | sleep(wait)
32 | print("Now the merchant sent all")
33 |
34 |
35 | if __name__ == "__main__":
36 | merchants()
37 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This repository contains code for implementing protocols described in
2 | the quantum protocol zoo (http://wiki.veriqloud.fr). Starting with a
3 | few of them, they will be progressively added and enhanced in terms of
4 | robustness and usability.
5 |
6 | The software stack used is based on python / simulaqron / cqc.
7 |
8 | The master branch is tagged with release numbers that will be
9 | increasing in sequence with the software maturity.
10 |
11 | We will be testing our releases on the machines available to us. Thus
12 | some bugs might (will) slip through. Feel free to send bug reports /
13 | suggestions.
14 |
15 | # Contributing
16 |
17 | Contributions are welcome.
18 |
19 | If you want to make such contribution please raise an issue stating
20 | what you would like to implement / correct / fix. We will then have
21 | the opportunity to make your suggestions fit into the overall
22 | development plan. Once everything is clear for you, fork the repo and
23 | startworking from the develop branch. We are using (and ask you as
24 | well) the popular branching model described by Vincent Driessen
25 | https://nvie.com/posts/a-successful-git-branching-model.
26 |
27 | If you have questions, raise issues !
--------------------------------------------------------------------------------
/UBQC/angle.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 |
4 | def measure_angle(i, seq, outcome_array, input_angle, computation_angle):
5 | """Angle to measrue qubit i
6 |
7 | :i: qubit to measure
8 | :outcome_array: list of qubit outcomes
9 | :input_angle: random angle in radians that was generated for measuring
10 | :computation_angle: actual computation angle in radians (hidden by input_angle)
11 | """
12 | c = 0
13 | s = 0
14 | for gate in seq:
15 | if gate.type == "X" and gate.qubit == i:
16 | c += outcome_array[i]
17 | elif gate.type == "Z" and gate.qubit == i:
18 | s += outcome_array[i]
19 | elif gate.type=="M" and gate.qubit==i:
20 | c+=gate.X_idxs #takes into account the extra arrays of M which contained xtra Xs due to commutation
21 | elif gate.type=="M" and gate.qubit==i:
22 | s+=gate.Z_idxs #same for Z
23 |
24 | return input_angle + ((-1) ** c) * (computation_angle) + (s * 128) #SimulaQron takes one step of angle as pi/255, hence the given description
25 |
26 |
27 |
28 | def measure_angle2(M, outcome_array, input_angle):
29 | """Angle to measrue qubit i
30 |
31 | :M: gate object
32 | :outcome_array: list of qubit outcomes
33 | :input_angle: random angle in radians that was generated for measuring
34 | """
35 | c = 0
36 | s = 0
37 | computation_angle = M.angle
38 | for q in M.X_idxs:
39 | if q==0:
40 | c += 1
41 | else:
42 | c += outcome_array[q-1]
43 | for q in M.Z_idxs:
44 | if q==0:
45 | s += 1
46 | else:
47 | s += outcome_array[q-1]
48 |
49 | return (input_angle + ((-1) ** c) * (computation_angle) + (s * 128) ) % 256 #SimulaQron takes one step of angle as pi/255, hence the given description
50 |
--------------------------------------------------------------------------------
/UBQC/circuit_projetq.py:
--------------------------------------------------------------------------------
1 | #use setting.json
2 | from projectq import MainEngine
3 | from projectq.backends import CircuitDrawer
4 | from projectq.ops import H, CNOT, Measure, X, Z, CZ
5 | import json
6 |
7 | def apply_gate(gate,qubits,b,i):
8 | if gate == "H":
9 | H | b[qubits[0][i]-1]
10 | elif gate == "X":
11 | X | b[qubits[0][i]-1]
12 | elif gate == "Z":
13 | Z | b[qubits[0][i]-1]
14 | elif gate == "CX":
15 | CNOT | (b[qubits[0][i]-1], b[qubits[1][i]-1])
16 | elif gate == "CZ":
17 | CZ | (b[qubits[0][i]-1], b[qubits[1][i]-1])
18 | return b
19 |
20 |
21 |
22 | def load_circuit(path):
23 | with open(path, "r") as circ:
24 | circuit = json.load(circ)
25 | nGates = len(circuit["gates"])
26 | gates = []
27 | qubits = []
28 | qubits_1 = []
29 | qubits_2 = []
30 | angles = []
31 | for g in range(0, nGates):
32 | qubits = qubits + circuit["gates"][g]["qbits"]
33 | qubits_1 = qubits_1 + [int(circuit["gates"][g]["qbits"][0])]
34 | if len(circuit["gates"][g]["qbits"]) == 1:
35 | qubits_2 = qubits_2 + [0]
36 | else:
37 | qubits_2 = qubits_2 + [int(circuit["gates"][g]["qbits"][1])]
38 | gates = gates + [circuit["gates"][g]["type"]]
39 | if gates[g] == 'T' :
40 | angles = angles + [32]
41 | if gates[g] == 'R_Z':
42 | angles = angles + [int(circuit["gates"][g]["angle"])]
43 |
44 | #print("qubits {}".format(qubits))
45 | nqbits = len(set(qubits))
46 | return gates, [qubits_1, qubits_2], nqbits, angles
47 |
48 | def create_circuit(eng,path):
49 | result = load_circuit(path)
50 | gates = result[0]
51 | #print("gates = {} ".format(gates))
52 | qubits = result[1]
53 | #print("qubits = {} ".format(qubits))
54 | nqbits = result[2]
55 | angles = result[3]
56 |
57 | b = []
58 | for i in range(nqbits):
59 | q = eng.allocate_qubit()
60 | b.append(q)
61 |
62 |
63 | ngates = len(gates)
64 | for i in range(ngates):
65 | if qubits[1][i] != 0:
66 | apply_gate(gates[i],qubits,b,i)
67 | else :
68 | apply_gate(gates[i],qubits,b,i)
69 |
70 | return b
71 |
72 |
73 |
74 | # create a main compiler engine
75 | def create_eng(path):
76 | drawing_engine = CircuitDrawer()
77 | eng = MainEngine(drawing_engine)
78 |
79 | create_circuit(eng,path)
80 |
81 | eng.flush()
82 | with open('circuit.tex', 'w') as f:
83 | #print >> f, 'Filename:', filename # Python 2.x
84 | #print('Filename:', filename, file=f) # Python 3.x
85 | print(drawing_engine.get_latex(), file=f)
86 |
87 | if __name__ == "__main__":
88 | path = "circuits/circuit9.json"
89 | create_eng(path)
--------------------------------------------------------------------------------
/UBQC/circuits/circuit1.json:
--------------------------------------------------------------------------------
1 | {
2 | "gates": [
3 | {
4 | "name": "g1",
5 | "type": "H",
6 | "qbits": ["1"]
7 | },
8 | {
9 | "name": "g2",
10 | "type": "H",
11 | "qbits": ["1"]
12 | },
13 | {
14 | "name": "g3",
15 | "type": "CX",
16 | "qbits": ["1","2"]
17 | },
18 | {
19 | "name": "g4",
20 | "type": "X",
21 | "qbits": ["1"]
22 | },
23 | {
24 | "name": "g5",
25 | "type": "Z",
26 | "qbits": ["2"]
27 | },
28 | {
29 | "name": "g6",
30 | "type": "CZ",
31 | "qbits": ["1","2"]
32 | }
33 | ]
34 | }
35 |
--------------------------------------------------------------------------------
/UBQC/circuits/circuit2.json:
--------------------------------------------------------------------------------
1 | {
2 | "gates": [
3 | {
4 | "name": "g1",
5 | "type": "CX",
6 | "qbits": [1, 2]
7 | },
8 | {
9 | "name": "g2",
10 | "type": "CX",
11 | "qbits": [2, 1]
12 | },
13 | {
14 | "name": "g3",
15 | "type": "CX",
16 | "qbits": [1, 2]
17 | }
18 |
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/UBQC/circuits/circuit3.json:
--------------------------------------------------------------------------------
1 | {
2 | "gates": [
3 | {
4 | "name": "g1",
5 | "type": "H",
6 | "qbits": ["1"]
7 | },
8 | {
9 | "name": "g2",
10 | "type": "H",
11 | "qbits": ["1"]
12 | },
13 | {
14 | "name": "g3",
15 | "type": "CX",
16 | "qbits": ["1","2"]
17 | },
18 | {
19 | "name": "g4",
20 | "type": "X",
21 | "qbits": ["1"]
22 | },
23 | {
24 | "name": "g5",
25 | "type": "Z",
26 | "qbits": ["2"]
27 | },
28 | {
29 | "name": "g6",
30 | "type": "CZ",
31 | "qbits": ["1","2"]
32 | }
33 | ]
34 | }
35 |
--------------------------------------------------------------------------------
/UBQC/circuits/circuit4.json:
--------------------------------------------------------------------------------
1 | {
2 | "gates": [
3 | {
4 | "name": "g1",
5 | "type": "H",
6 | "qbits": ["1"]
7 | },
8 | {
9 | "name": "g2",
10 | "type": "H",
11 | "qbits": ["2"]
12 | },
13 | {
14 | "name": "g3",
15 | "type": "CZ",
16 | "qbits": ["1","2"]
17 | },
18 | {
19 | "name": "g4",
20 | "type": "H",
21 | "qbits": ["2"]
22 | }
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/UBQC/circuits/circuit5.json:
--------------------------------------------------------------------------------
1 | {
2 | "gates": [
3 | {
4 | "name": "g1",
5 | "type": "H",
6 | "qbits": ["1"]
7 | },
8 | {
9 | "name": "g2",
10 | "type": "Z",
11 | "qbits": ["1"]
12 | },
13 | {
14 | "name": "g3",
15 | "type": "H",
16 | "qbits": ["1"]
17 | }
18 |
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/UBQC/circuits/circuit6.json:
--------------------------------------------------------------------------------
1 | {
2 | "gates": [
3 | {
4 | "name": "g1",
5 | "type": "CX",
6 | "qbits": ["1","2"]
7 | },
8 | {
9 | "name": "g2",
10 | "type": "Z",
11 | "qbits": ["1"]
12 | }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/UBQC/circuits/circuit7.json:
--------------------------------------------------------------------------------
1 | {
2 | "gates": [
3 | {
4 | "name": "g1",
5 | "type": "CX",
6 | "qbits": [1, 2]
7 | },
8 | {
9 | "name": "g2",
10 | "type": "CX",
11 | "qbits": [2, 1]
12 | },
13 | {
14 | "name": "g3",
15 | "type": "CX",
16 | "qbits": [1, 2]
17 | },
18 | {
19 | "name": "g4",
20 | "type": "H",
21 | "qbits": [1]
22 | }
23 |
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/UBQC/circuits/circuit8.json:
--------------------------------------------------------------------------------
1 | {
2 | "gates": [
3 | {
4 | "name": "g1",
5 | "type": "H",
6 | "qbits": [1]
7 | },
8 | {
9 | "name": "g2",
10 | "type": "CX",
11 | "qbits": [1, 2]
12 | }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/UBQC/circuits/circuit9.json:
--------------------------------------------------------------------------------
1 | {
2 | "gates": [
3 | {
4 | "name": "g1",
5 | "type": "H",
6 | "qbits": [1]
7 | },
8 | {
9 | "name": "g2",
10 | "type": "H",
11 | "qbits": [2]
12 | },
13 | {
14 | "name": "g3",
15 | "type": "CZ",
16 | "qbits": [1, 2]
17 | },
18 | {
19 | "name": "g4",
20 | "type": "H",
21 | "qbits": [2]
22 | }
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/UBQC/circuits/circuitCNOT.json:
--------------------------------------------------------------------------------
1 | {
2 | "gates": [
3 | {
4 | "name": "g1",
5 | "type": "CX",
6 | "qbits": ["1","2"]
7 | }
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/UBQC/circuits/circuitH.json:
--------------------------------------------------------------------------------
1 | {
2 | "gates": [
3 | {
4 | "name": "g1",
5 | "type": "H",
6 | "qbits": ["1"]
7 | }
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/UBQC/circuits/circuitRX.json:
--------------------------------------------------------------------------------
1 | {
2 | "gates": [
3 | {
4 | "name": "g1",
5 | "type": "R_X",
6 | "qbits": ["1"],
7 | "angle": "128"
8 | }
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/UBQC/circuits/circuitRZ.json:
--------------------------------------------------------------------------------
1 | {
2 | "gates": [
3 | {
4 | "name": "g1",
5 | "type": "T",
6 | "qbits": ["1"]
7 | },
8 | {
9 | "name": "g1",
10 | "type": "R_Z",
11 | "qbits": ["1"],
12 | "angle": "160"
13 | }
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/UBQC/circuits/circuitRZ1.json:
--------------------------------------------------------------------------------
1 | {
2 | "gates": [
3 | {
4 | "name": "g1",
5 | "type": "R_Z",
6 | "qbits": ["1"],
7 | "angle": "128"
8 | }
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/UBQC/circuits/circuitRZ_test.json:
--------------------------------------------------------------------------------
1 | {
2 | "gates": [
3 | {
4 | "name": "g1",
5 | "type": "T",
6 | "qbits": ["1"],
7 | "angle": "32"
8 | },
9 | {
10 | "name": "g2",
11 | "type": "CX",
12 | "qbits": ["1","2"]
13 | }
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/UBQC/circuits/circuitSWAP.json:
--------------------------------------------------------------------------------
1 | {
2 | "gates": [
3 | {
4 | "name": "g1",
5 | "type": "CX",
6 | "qbits": [1, 2]
7 | },
8 | {
9 | "name": "g2",
10 | "type": "CX",
11 | "qbits": [2, 1]
12 | },
13 | {
14 | "name": "g3",
15 | "type": "CX",
16 | "qbits": [1, 2]
17 | }
18 |
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/UBQC/circuits/circuitT.json:
--------------------------------------------------------------------------------
1 | {
2 | "gates": [
3 | {
4 | "name": "g1",
5 | "type": "T",
6 | "qbits": ["1"]
7 | }
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/UBQC/docs/im1.svg:
--------------------------------------------------------------------------------
1 |
2 |
19 |
--------------------------------------------------------------------------------
/UBQC/docs/im1.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pts, a4paper]{article}
2 | \usepackage[utf8]{inputenc}
3 | %\usepackage{algorithm,algorithmicx,algpseudocode}
4 | \usepackage{amssymb}
5 | \usepackage{latexsym}
6 | \usepackage{braket}
7 | %\usepackage{cryptocode}
8 | \usepackage[english]{babel}
9 | \setlength{\parindent}{4 em}
10 | \setlength{\parskip}{1 em}
11 | \renewcommand{\baselinestretch}{1.0}
12 | \usepackage[margin=1.0in]{geometry}
13 | \usepackage{float}
14 | \floatstyle{boxed}
15 | \usepackage{amsmath}
16 | \usepackage{caption}
17 | \usepackage[superscript, biblabel, nomove]{cite}
18 | \usepackage{mathtools}
19 | \title{ \begin{large}
20 | \textbf{Flow Construction}
21 | \end{large}
22 | }
23 | %\author{}
24 | %document
25 | \date{}
26 | \begin{document}
27 | \thispagestyle{empty}
28 | $\phi$
29 | \end{document}
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/UBQC/docs/im10.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pts, a4paper]{article}
2 | \usepackage[utf8]{inputenc}
3 | %\usepackage{algorithm,algorithmicx,algpseudocode}
4 | \usepackage{amssymb}
5 | \usepackage{latexsym}
6 | \usepackage{braket}
7 | %\usepackage{cryptocode}
8 | \usepackage[english]{babel}
9 | \setlength{\parindent}{4 em}
10 | \setlength{\parskip}{1 em}
11 | \renewcommand{\baselinestretch}{1.0}
12 | \usepackage[margin=1.0in]{geometry}
13 | \usepackage{float}
14 | \floatstyle{boxed}
15 | \usepackage{amsmath}
16 | \usepackage{caption}
17 | \usepackage[superscript, biblabel, nomove]{cite}
18 | \usepackage{mathtools}
19 | \title{ \begin{large}
20 | \textbf{Flow Construction}
21 | \end{large}
22 | }
23 | %\author{}
24 | %document
25 | \date{}
26 | \begin{document}
27 | \thispagestyle{empty}
28 | %$CX|\psi\rangle=X^{s_3}_4Z^{s_2}_4Z^{s_2}_1M_3(0)M_2(0)CZ_{34}CZ_{23}CZ_{13}|\psi\rangle_{12}|+\rangle_3|+\rangle_4$
29 | $CX_{12}=I_1\otimes H_2CZ_{12}I_1\otimes H_2$
30 | \end{document}
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/UBQC/docs/im11.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pts, a4paper]{article}
2 | \usepackage[utf8]{inputenc}
3 | %\usepackage{algorithm,algorithmicx,algpseudocode}
4 | \usepackage{amssymb}
5 | \usepackage{latexsym}
6 | \usepackage{braket}
7 | %\usepackage{cryptocode}
8 | \usepackage[english]{babel}
9 | \setlength{\parindent}{4 em}
10 | \setlength{\parskip}{1 em}
11 | \renewcommand{\baselinestretch}{1.0}
12 | \usepackage[margin=1.0in]{geometry}
13 | \usepackage{float}
14 | \floatstyle{boxed}
15 | \usepackage{amsmath}
16 | \usepackage{caption}
17 | \usepackage[superscript, biblabel, nomove]{cite}
18 | \usepackage{mathtools}
19 | \title{ \begin{large}
20 | \textbf{Flow Construction}
21 | \end{large}
22 | }
23 | %\author{}
24 | %document
25 | \date{}
26 | \begin{document}
27 | \thispagestyle{empty}
28 | $J(\alpha)|\psi\rangle=X^{s_1}_2M_1(−\alpha)CZ_{12}|\psi\rangle_1|+\rangle_2$
29 | \end{document}
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/UBQC/docs/im12.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pts, a4paper]{article}
2 | \usepackage[utf8]{inputenc}
3 | %\usepackage{algorithm,algorithmicx,algpseudocode}
4 | \usepackage{amssymb}
5 | \usepackage{latexsym}
6 | \usepackage{braket}
7 | %\usepackage{cryptocode}
8 | \usepackage[english]{babel}
9 | \setlength{\parindent}{4 em}
10 | \setlength{\parskip}{1 em}
11 | \renewcommand{\baselinestretch}{1.0}
12 | \usepackage[margin=1.0in]{geometry}
13 | \usepackage{float}
14 | \floatstyle{boxed}
15 | \usepackage{amsmath}
16 | \usepackage{caption}
17 | \usepackage[superscript, biblabel, nomove]{cite}
18 | \usepackage{mathtools}
19 | \title{ \begin{large}
20 | \textbf{Flow Construction}
21 | \end{large}
22 | }
23 | %\author{}
24 | %document
25 | \date{}
26 | \begin{document}
27 | \thispagestyle{empty}
28 | $R_X(\alpha) = J(\alpha)H, R_Z(\alpha) = HJ(\alpha), H=J(0)$
29 | \end{document}
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/UBQC/docs/im13.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pts, a4paper]{article}
2 | \usepackage[utf8]{inputenc}
3 | %\usepackage{algorithm,algorithmicx,algpseudocode}
4 | \usepackage{amssymb}
5 | \usepackage{latexsym}
6 | \usepackage{braket}
7 | %\usepackage{cryptocode}
8 | \usepackage[english]{babel}
9 | \setlength{\parindent}{4 em}
10 | \setlength{\parskip}{1 em}
11 | \renewcommand{\baselinestretch}{1.0}
12 | \usepackage[margin=1.0in]{geometry}
13 | \usepackage{float}
14 | \floatstyle{boxed}
15 | \usepackage{amsmath}
16 | \usepackage{caption}
17 | \usepackage[superscript, biblabel, nomove]{cite}
18 | \usepackage{mathtools}
19 | \title{ \begin{large}
20 | \textbf{Flow Construction}
21 | \end{large}
22 | }
23 | %\author{}
24 | %document
25 | \date{}
26 | \begin{document}
27 | \thispagestyle{empty}
28 | $\bigotimes_{i\in I}R_Z(\alpha_i)|\psi_i\rangle\bigotimes_{i\in N\setminus I}|+_{\alpha_i}\rangle$
29 | \end{document}
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/UBQC/docs/im14.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pts, a4paper]{article}
2 | \usepackage[utf8]{inputenc}
3 | %\usepackage{algorithm,algorithmicx,algpseudocode}
4 | \usepackage{amssymb}
5 | \usepackage{latexsym}
6 | \usepackage{braket}
7 | %\usepackage{cryptocode}
8 | \usepackage[english]{babel}
9 | \setlength{\parindent}{4 em}
10 | \setlength{\parskip}{1 em}
11 | \renewcommand{\baselinestretch}{1.0}
12 | \usepackage[margin=1.0in]{geometry}
13 | \usepackage{float}
14 | \floatstyle{boxed}
15 | \usepackage{amsmath}
16 | \usepackage{caption}
17 | \usepackage[superscript, biblabel, nomove]{cite}
18 | \usepackage{mathtools}
19 | \title{ \begin{large}
20 | \textbf{Flow Construction}
21 | \end{large}
22 | }
23 | %\author{}
24 | %document
25 | \date{}
26 | \begin{document}
27 | \thispagestyle{empty}
28 | $|\psi_i\rangle, i\in I$
29 | \end{document}
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/UBQC/docs/im15.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pts, a4paper]{article}
2 | \usepackage[utf8]{inputenc}
3 | %\usepackage{algorithm,algorithmicx,algpseudocode}
4 | \usepackage{amssymb}
5 | \usepackage{latexsym}
6 | \usepackage{braket}
7 | %\usepackage{cryptocode}
8 | \usepackage[english]{babel}
9 | \setlength{\parindent}{4 em}
10 | \setlength{\parskip}{1 em}
11 | \renewcommand{\baselinestretch}{1.0}
12 | \usepackage[margin=1.0in]{geometry}
13 | \usepackage{float}
14 | \floatstyle{boxed}
15 | \usepackage{amsmath}
16 | \usepackage{caption}
17 | \usepackage[superscript, biblabel, nomove]{cite}
18 | \usepackage{mathtools}
19 | \title{ \begin{large}
20 | \textbf{Flow Construction}
21 | \end{large}
22 | }
23 | %\author{}
24 | %document
25 | \date{}
26 | \begin{document}
27 | \thispagestyle{empty}
28 | $\alpha_i, i\in N$
29 | \end{document}
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/UBQC/docs/im16.svg:
--------------------------------------------------------------------------------
1 |
2 |
50 |
--------------------------------------------------------------------------------
/UBQC/docs/im16.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pts, a4paper]{article}
2 | \usepackage[utf8]{inputenc}
3 | %\usepackage{algorithm,algorithmicx,algpseudocode}
4 | \usepackage{amssymb}
5 | \usepackage{latexsym}
6 | \usepackage{braket}
7 | %\usepackage{cryptocode}
8 | \usepackage[english]{babel}
9 | \setlength{\parindent}{4 em}
10 | \setlength{\parskip}{1 em}
11 | \renewcommand{\baselinestretch}{1.0}
12 | \usepackage[margin=1.0in]{geometry}
13 | \usepackage{float}
14 | \floatstyle{boxed}
15 | \usepackage{amsmath}
16 | \usepackage{caption}
17 | \usepackage[superscript, biblabel, nomove]{cite}
18 | \usepackage{mathtools}
19 | \title{ \begin{large}
20 | \textbf{Flow Construction}
21 | \end{large}
22 | }
23 | %\author{}
24 | %document
25 | \date{}
26 | \begin{document}
27 | \thispagestyle{empty}
28 | $[0,2\pi]$
29 | \end{document}
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/UBQC/docs/im16bis.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pts, a4paper]{article}
2 | \usepackage[utf8]{inputenc}
3 | %\usepackage{algorithm,algorithmicx,algpseudocode}
4 | \usepackage{amssymb}
5 | \usepackage{latexsym}
6 | \usepackage{braket}
7 | %\usepackage{cryptocode}
8 | \usepackage[english]{babel}
9 | \setlength{\parindent}{4 em}
10 | \setlength{\parskip}{1 em}
11 | \renewcommand{\baselinestretch}{1.0}
12 | \usepackage[margin=1.0in]{geometry}
13 | \usepackage{float}
14 | \floatstyle{boxed}
15 | \usepackage{amsmath}
16 | \usepackage{caption}
17 | \usepackage[superscript, biblabel, nomove]{cite}
18 | \usepackage{mathtools}
19 | \title{ \begin{large}
20 | \textbf{Flow Construction}
21 | \end{large}
22 | }
23 | %\author{}
24 | %document
25 | \date{}
26 | \begin{document}
27 | \thispagestyle{empty}
28 | $i = 0,\ldots,|N\setminus O|-1$
29 | \end{document}
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/UBQC/docs/im17.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pts, a4paper]{article}
2 | \usepackage[utf8]{inputenc}
3 | %\usepackage{algorithm,algorithmicx,algpseudocode}
4 | \usepackage{amssymb}
5 | \usepackage{latexsym}
6 | \usepackage{braket}
7 | %\usepackage{cryptocode}
8 | \usepackage[english]{babel}
9 | \setlength{\parindent}{4 em}
10 | \setlength{\parskip}{1 em}
11 | \renewcommand{\baselinestretch}{1.0}
12 | \usepackage[margin=1.0in]{geometry}
13 | \usepackage{float}
14 | \floatstyle{boxed}
15 | \usepackage{amsmath}
16 | \usepackage{caption}
17 | \usepackage[superscript, biblabel, nomove]{cite}
18 | \usepackage{mathtools}
19 | \title{ \begin{large}
20 | \textbf{Flow Construction}
21 | \end{large}
22 | }
23 | %\author{}
24 | %document
25 | \date{}
26 | \begin{document}
27 | \thispagestyle{empty}
28 | $r_i\in\{0,1\}$
29 | \end{document}
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/UBQC/docs/im18.svg:
--------------------------------------------------------------------------------
1 |
2 |
28 |
--------------------------------------------------------------------------------
/UBQC/docs/im18.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pts, a4paper]{article}
2 | \usepackage[utf8]{inputenc}
3 | %\usepackage{algorithm,algorithmicx,algpseudocode}
4 | \usepackage{amssymb}
5 | \usepackage{latexsym}
6 | \usepackage{braket}
7 | %\usepackage{cryptocode}
8 | \usepackage[english]{babel}
9 | \setlength{\parindent}{4 em}
10 | \setlength{\parskip}{1 em}
11 | \renewcommand{\baselinestretch}{1.0}
12 | \usepackage[margin=1.0in]{geometry}
13 | \usepackage{float}
14 | \floatstyle{boxed}
15 | \usepackage{amsmath}
16 | \usepackage{caption}
17 | \usepackage[superscript, biblabel, nomove]{cite}
18 | \usepackage{mathtools}
19 | \title{ \begin{large}
20 | \textbf{Flow Construction}
21 | \end{large}
22 | }
23 | %\author{}
24 | %document
25 | \date{}
26 | \begin{document}
27 | \thispagestyle{empty}
28 | $\delta_i$
29 | \end{document}
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/UBQC/docs/im19.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pts, a4paper]{article}
2 | \usepackage[utf8]{inputenc}
3 | %\usepackage{algorithm,algorithmicx,algpseudocode}
4 | \usepackage{amssymb}
5 | \usepackage{latexsym}
6 | \usepackage{braket}
7 | %\usepackage{cryptocode}
8 | \usepackage[english]{babel}
9 | \setlength{\parindent}{4 em}
10 | \setlength{\parskip}{1 em}
11 | \renewcommand{\baselinestretch}{1.0}
12 | \usepackage[margin=1.0in]{geometry}
13 | \usepackage{float}
14 | \floatstyle{boxed}
15 | \usepackage{amsmath}
16 | \usepackage{caption}
17 | \usepackage[superscript, biblabel, nomove]{cite}
18 | \usepackage{mathtools}
19 | \title{ \begin{large}
20 | \textbf{Flow Construction}
21 | \end{large}
22 | }
23 | %\author{}
24 | %document
25 | \date{}
26 | \begin{document}
27 | \thispagestyle{empty}
28 | $\delta_i = \alpha_i + (-1)^{\bigoplus_{k\in DX} s_k \oplus r_k}\phi_i+r_i\pi +(\bigoplus_{k\in DZ} s_k \oplus r_k)\pi$
29 | \end{document}
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/UBQC/docs/im2.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pts, a4paper]{article}
2 | \usepackage[utf8]{inputenc}
3 | %\usepackage{algorithm,algorithmicx,algpseudocode}
4 | \usepackage{amssymb}
5 | \usepackage{latexsym}
6 | \usepackage{braket}
7 | %\usepackage{cryptocode}
8 | \usepackage[english]{babel}
9 | \setlength{\parindent}{4 em}
10 | \setlength{\parskip}{1 em}
11 | \renewcommand{\baselinestretch}{1.0}
12 | \usepackage[margin=1.0in]{geometry}
13 | \usepackage{float}
14 | \floatstyle{boxed}
15 | \usepackage{amsmath}
16 | \usepackage{caption}
17 | \usepackage[superscript, biblabel, nomove]{cite}
18 | \usepackage{mathtools}
19 | \title{ \begin{large}
20 | \textbf{Flow Construction}
21 | \end{large}
22 | }
23 | %\author{}
24 | %document
25 | \date{}
26 | \begin{document}
27 | \thispagestyle{empty}
28 | $(|+_\delta>, |-_\delta>)$
29 | \end{document}
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/UBQC/docs/im20.svg:
--------------------------------------------------------------------------------
1 |
2 |
28 |
--------------------------------------------------------------------------------
/UBQC/docs/im20.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pts, a4paper]{article}
2 | \usepackage[utf8]{inputenc}
3 | %\usepackage{algorithm,algorithmicx,algpseudocode}
4 | \usepackage{amssymb}
5 | \usepackage{latexsym}
6 | \usepackage{braket}
7 | %\usepackage{cryptocode}
8 | \usepackage[english]{babel}
9 | \setlength{\parindent}{4 em}
10 | \setlength{\parskip}{1 em}
11 | \renewcommand{\baselinestretch}{1.0}
12 | \usepackage[margin=1.0in]{geometry}
13 | \usepackage{float}
14 | \floatstyle{boxed}
15 | \usepackage{amsmath}
16 | \usepackage{caption}
17 | \usepackage[superscript, biblabel, nomove]{cite}
18 | \usepackage{mathtools}
19 | \title{ \begin{large}
20 | \textbf{Flow Construction}
21 | \end{large}
22 | }
23 | %\author{}
24 | %document
25 | \date{}
26 | \begin{document}
27 | \thispagestyle{empty}
28 | $r_i$
29 | \end{document}
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/UBQC/docs/im21.svg:
--------------------------------------------------------------------------------
1 |
2 |
28 |
--------------------------------------------------------------------------------
/UBQC/docs/im21.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pts, a4paper]{article}
2 | \usepackage[utf8]{inputenc}
3 | %\usepackage{algorithm,algorithmicx,algpseudocode}
4 | \usepackage{amssymb}
5 | \usepackage{latexsym}
6 | \usepackage{braket}
7 | %\usepackage{cryptocode}
8 | \usepackage[english]{babel}
9 | \setlength{\parindent}{4 em}
10 | \setlength{\parskip}{1 em}
11 | \renewcommand{\baselinestretch}{1.0}
12 | \usepackage[margin=1.0in]{geometry}
13 | \usepackage{float}
14 | \floatstyle{boxed}
15 | \usepackage{amsmath}
16 | \usepackage{caption}
17 | \usepackage[superscript, biblabel, nomove]{cite}
18 | \usepackage{mathtools}
19 | \title{ \begin{large}
20 | \textbf{Flow Construction}
21 | \end{large}
22 | }
23 | %\author{}
24 | %document
25 | \date{}
26 | \begin{document}
27 | \thispagestyle{empty}
28 | $s_i$
29 | \end{document}
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/UBQC/docs/im3.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pts, a4paper]{article}
2 | \usepackage[utf8]{inputenc}
3 | %\usepackage{algorithm,algorithmicx,algpseudocode}
4 | \usepackage{amssymb}
5 | \usepackage{latexsym}
6 | \usepackage{braket}
7 | %\usepackage{cryptocode}
8 | \usepackage[english]{babel}
9 | \setlength{\parindent}{4 em}
10 | \setlength{\parskip}{1 em}
11 | \renewcommand{\baselinestretch}{1.0}
12 | \usepackage[margin=1.0in]{geometry}
13 | \usepackage{float}
14 | \floatstyle{boxed}
15 | \usepackage{amsmath}
16 | \usepackage{caption}
17 | \usepackage[superscript, biblabel, nomove]{cite}
18 | \usepackage{mathtools}
19 | \title{ \begin{large}
20 | \textbf{Flow Construction}
21 | \end{large}
22 | }
23 | %\author{}
24 | %document
25 | \date{}
26 | \begin{document}
27 | \thispagestyle{empty}
28 | $|+_\delta> = \frac{1}{\sqrt{2}}(|0> + e^{i\delta}|1>)$, $|-_\delta> = \frac{1}{\sqrt{2}}(|0> - e^{i\delta}|1>)$
29 | \end{document}
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/UBQC/docs/im4.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pts, a4paper]{article}
2 | \usepackage[utf8]{inputenc}
3 | %\usepackage{algorithm,algorithmicx,algpseudocode}
4 | \usepackage{amssymb}
5 | \usepackage{latexsym}
6 | \usepackage{braket}
7 | %\usepackage{cryptocode}
8 | \usepackage[english]{babel}
9 | \setlength{\parindent}{4 em}
10 | \setlength{\parskip}{1 em}
11 | \renewcommand{\baselinestretch}{1.0}
12 | \usepackage[margin=1.0in]{geometry}
13 | \usepackage{float}
14 | \floatstyle{boxed}
15 | \usepackage{amsmath}
16 | \usepackage{caption}
17 | \usepackage[superscript, biblabel, nomove]{cite}
18 | \usepackage{mathtools}
19 | \title{ \begin{large}
20 | \textbf{Flow Construction}
21 | \end{large}
22 | }
23 | %\author{}
24 | %document
25 | \date{}
26 | \begin{document}
27 | \thispagestyle{empty}
28 | $\delta=(-1)^{\bigoplus_{j\in DX} s_j}\phi+(\bigoplus_{j\in DZ}s_j)\pi$
29 | \end{document}
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/UBQC/docs/im5.svg:
--------------------------------------------------------------------------------
1 |
2 |
28 |
--------------------------------------------------------------------------------
/UBQC/docs/im5.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pts, a4paper]{article}
2 | \usepackage[utf8]{inputenc}
3 | %\usepackage{algorithm,algorithmicx,algpseudocode}
4 | \usepackage{amssymb}
5 | \usepackage{latexsym}
6 | \usepackage{braket}
7 | %\usepackage{cryptocode}
8 | \usepackage[english]{babel}
9 | \setlength{\parindent}{4 em}
10 | \setlength{\parskip}{1 em}
11 | \renewcommand{\baselinestretch}{1.0}
12 | \usepackage[margin=1.0in]{geometry}
13 | \usepackage{float}
14 | \floatstyle{boxed}
15 | \usepackage{amsmath}
16 | \usepackage{caption}
17 | \usepackage[superscript, biblabel, nomove]{cite}
18 | \usepackage{mathtools}
19 | \title{ \begin{large}
20 | \textbf{Flow Construction}
21 | \end{large}
22 | }
23 | %\author{}
24 | %document
25 | \date{}
26 | \begin{document}
27 | \thispagestyle{empty}
28 | $s_j$
29 | \end{document}
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/UBQC/docs/im6.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pts, a4paper]{article}
2 | \usepackage[utf8]{inputenc}
3 | %\usepackage{algorithm,algorithmicx,algpseudocode}
4 | \usepackage{amssymb}
5 | \usepackage{latexsym}
6 | \usepackage{braket}
7 | %\usepackage{cryptocode}
8 | \usepackage[english]{babel}
9 | \setlength{\parindent}{4 em}
10 | \setlength{\parskip}{1 em}
11 | \renewcommand{\baselinestretch}{1.0}
12 | \usepackage[margin=1.0in]{geometry}
13 | \usepackage{float}
14 | \floatstyle{boxed}
15 | \usepackage{amsmath}
16 | \usepackage{caption}
17 | \usepackage[superscript, biblabel, nomove]{cite}
18 | \usepackage{mathtools}
19 | \title{ \begin{large}
20 | \textbf{Flow Construction}
21 | \end{large}
22 | }
23 | %\author{}
24 | %document
25 | \date{}
26 | \begin{document}
27 | \thispagestyle{empty}
28 | $|\psi_{out}\rangle=\prod_{j\in O}X^{\bigoplus_{k\in LX}s_k}_j Z^{\bigoplus_{k\in LZ}s_k}_j \prod_{j\in N\setminus O} M_j(\delta) \prod_{(i,j) \in S} CZ_{ij}|\psi_{in}\rangle_{I}|+\rangle_{N\setminus I}$
29 | \end{document}
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/UBQC/docs/im7.svg:
--------------------------------------------------------------------------------
1 |
2 |
28 |
--------------------------------------------------------------------------------
/UBQC/docs/im7.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pts, a4paper]{article}
2 | \usepackage[utf8]{inputenc}
3 | %\usepackage{algorithm,algorithmicx,algpseudocode}
4 | \usepackage{amssymb}
5 | \usepackage{latexsym}
6 | \usepackage{braket}
7 | %\usepackage{cryptocode}
8 | \usepackage[english]{babel}
9 | \setlength{\parindent}{4 em}
10 | \setlength{\parskip}{1 em}
11 | \renewcommand{\baselinestretch}{1.0}
12 | \usepackage[margin=1.0in]{geometry}
13 | \usepackage{float}
14 | \floatstyle{boxed}
15 | \usepackage{amsmath}
16 | \usepackage{caption}
17 | \usepackage[superscript, biblabel, nomove]{cite}
18 | \usepackage{mathtools}
19 | \title{ \begin{large}
20 | \textbf{Flow Construction}
21 | \end{large}
22 | }
23 | %\author{}
24 | %document
25 | \date{}
26 | \begin{document}
27 | \thispagestyle{empty}
28 | $s_k$
29 | \end{document}
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/UBQC/docs/im8.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pts, a4paper]{article}
2 | \usepackage[utf8]{inputenc}
3 | %\usepackage{algorithm,algorithmicx,algpseudocode}
4 | \usepackage{amssymb}
5 | \usepackage{latexsym}
6 | \usepackage{braket}
7 | %\usepackage{cryptocode}
8 | \usepackage[english]{babel}
9 | \setlength{\parindent}{4 em}
10 | \setlength{\parskip}{1 em}
11 | \renewcommand{\baselinestretch}{1.0}
12 | \usepackage[margin=1.0in]{geometry}
13 | \usepackage{float}
14 | \floatstyle{boxed}
15 | \usepackage{amsmath}
16 | \usepackage{caption}
17 | \usepackage[superscript, biblabel, nomove]{cite}
18 | \usepackage{mathtools}
19 | \title{ \begin{large}
20 | \textbf{Flow Construction}
21 | \end{large}
22 | }
23 | %\author{}
24 | %document
25 | \date{}
26 | \begin{document}
27 | \thispagestyle{empty}
28 | $|\psi_{in}\rangle$
29 | \end{document}
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/UBQC/docs/im9.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pts, a4paper]{article}
2 | \usepackage[utf8]{inputenc}
3 | %\usepackage{algorithm,algorithmicx,algpseudocode}
4 | \usepackage{amssymb}
5 | \usepackage{latexsym}
6 | \usepackage{braket}
7 | %\usepackage{cryptocode}
8 | \usepackage[english]{babel}
9 | \setlength{\parindent}{4 em}
10 | \setlength{\parskip}{1 em}
11 | \renewcommand{\baselinestretch}{1.0}
12 | \usepackage[margin=1.0in]{geometry}
13 | \usepackage{float}
14 | \floatstyle{boxed}
15 | \usepackage{amsmath}
16 | \usepackage{caption}
17 | \usepackage[superscript, biblabel, nomove]{cite}
18 | \usepackage{mathtools}
19 | \title{ \begin{large}
20 | \textbf{Flow Construction}
21 | \end{large}
22 | }
23 | %\author{}
24 | %document
25 | \date{}
26 | \begin{document}
27 | \thispagestyle{empty}
28 | $H|\psi\rangle=X^{s_1}_2M_1(0)CZ_{12}|\psi\rangle_1|+\rangle_2$
29 | \end{document}
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/UBQC/docs/readme.tex:
--------------------------------------------------------------------------------
1 | \documentclass[10pts, a4paper]{article}
2 | \usepackage[utf8]{inputenc}
3 | %\usepackage{algorithm,algorithmicx,algpseudocode}
4 | \usepackage{amssymb}
5 | \usepackage{latexsym}
6 | \usepackage{braket}
7 | %\usepackage{cryptocode}
8 | \usepackage[english]{babel}
9 | \setlength{\parindent}{4 em}
10 | \setlength{\parskip}{1 em}
11 | \renewcommand{\baselinestretch}{1.0}
12 | \usepackage[margin=1.0in]{geometry}
13 | \usepackage{float}
14 | \floatstyle{boxed}
15 | \usepackage{amsmath}
16 | \usepackage{caption}
17 | \usepackage[superscript, biblabel, nomove]{cite}
18 | \usepackage{mathtools}
19 | \title{ \begin{large}
20 | \textbf{Flow Construction}
21 | \end{large}
22 | }
23 | %\author{}
24 | %document
25 | \date{}
26 | \begin{document}
27 | \maketitle
28 | Interpret Flow notations MBQC as follows. There are four kinds of outputs:
29 | \begin{itemize}
30 | \item E [i,j]: entangle qubits i and j using Controlled Phase. \\
31 | Lets denote by E the total set of edges $\{i,j\}$.
32 | \item M i $\phi$ DepX DepZ: Qubit i is measured in the $(|+_\alpha>, |-_\alpha>)$ basis, where\\
33 | $|+_\alpha> = \frac{1}{\sqrt{2}}(|0> + e^{i\alpha}|1>)$,\\
34 | $|-_\alpha> = \frac{1}{\sqrt{2}}(|0> - e^{i\alpha}|1>)$ \\
35 | and $\alpha=(-1)^{\sum_{j\in DepX} s_j \textnormal{ mod 2}}\phi+\sum_{j\in DepZ}s_j\pi$ where $s_j$ is the measurement outcome of qubit j and DepX and DepZ two lists of indexes.
36 | \item X j i: Operation of conditional X on qubit j depending on measurement outcome of qubit i\\
37 | Lets denote by K the total set of such indexes i.
38 | \item Z j i: Operation of conditional Z on qubit j depending on measurement outcome of qubit i\\
39 | Lets denote by T the total set of such indexes i.
40 | \end{itemize}
41 | Finally the resut of the computation is \\
42 | $|\psi_{out}>_O = \prod_{j\in O}X^{\sum_{k\in K}s_k \textnormal{ mod 2}}_j Z^{\sum_{k\in T}s_k \textnormal{ mod 2}}_j \prod_{j\in N-O} M_j(\alpha(\phi,DepX,DepZ)) \prod_{(i,j) \in E} CZ_{ij}|+>_{N-I}|\psi_i>_{i\in I}$, where $s_k$ is the measurement outcome on qubit $k$, O is the set of output qubits, I the set of input qubits, N the total set of qubit encoded into the graph state defined by $E$.
43 | \end{document}
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/UBQC/docs/script.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | for i in `seq 21`
3 | do xelatex im$i.tex
4 | pdfcrop im$i.pdf
5 | pdf2svg im$i-crop.pdf im$i.svg
6 | done
7 |
8 | #rm -f *.aux *.log *-crop.pdf *.pdf
--------------------------------------------------------------------------------
/UBQC/docs/svgs/4fa3ac8fe93c68be3fe7ab53bdeb2efa.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/UBQC/docs/svgs/59efeb0f4f5d484a9b8a404d5bdac544.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/UBQC/docs/svgs/f50853d41be7d55874e952eb0d80c53e.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/UBQC/flow.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | from measurement import load_and_convert_circuit
3 | from copy import deepcopy
4 |
5 | class Gate:
6 | """Represents gate being applied to qubits/conditions"""
7 |
8 | def __init__(self, gate_type, args):
9 | self.type = gate_type
10 | if gate_type == "E":
11 | self.qubits = args[0]
12 | elif gate_type == "M":
13 | self.qubit = args[0]
14 | self.angle = args[1]
15 | self.X_idxs = []
16 | self.Z_idxs = []
17 | elif gate_type == "X":
18 | self.qubit = args[0]
19 | self.power_idx = args[1]
20 | elif gate_type == "Z":
21 | self.qubit = args[0]
22 | self.power_idx = args[1]
23 | elif gate_type == "R":
24 | self.qubit = args[0]
25 | self.angle = args[1]
26 | self.axis = args[2]
27 |
28 | def printinfo(self):
29 | if self.type == "E":
30 | print("\t", self.type, self.qubits)
31 | elif self.type == "M":
32 | print("\t", self.type, self.qubit, self.angle, self.X_idxs, self.Z_idxs)
33 | elif self.type == "X":
34 | print("\t", self.type, self.qubit, self.power_idx)
35 | elif self.type == "Z":
36 | print("\t", self.type, self.qubit, self.power_idx)
37 |
38 |
39 | def _measurement_dictionary_to_sequence(dictionary):
40 | seq = []
41 | gates = dictionary["gates"]
42 | qubits = dictionary["qubits"]
43 | conditions = dictionary["conditions"]
44 |
45 | for i in range(len(gates)):
46 | if gates[i] == "E":
47 | seq.append(Gate("E", [[qubits[0][i], qubits[1][i]]]))
48 | elif gates[i] == "M":
49 | seq.append(Gate("M", [qubits[0][i], conditions[i]]))
50 | elif gates[i] in ("X", "Y", "Z"):
51 | seq.append(Gate(gates[i], [qubits[0][i], conditions[i]]))
52 |
53 | return seq
54 |
55 |
56 | def _construct_flow_from_sequence(seq):
57 | seq = deepcopy(seq)
58 | N = len(seq)
59 | i = 1
60 | while i < N:
61 | if seq[i].type == "E":
62 | if (seq[i - 1].type == "E") | (i==0):
63 | i = i + 1
64 | continue
65 |
66 | if (seq[i - 1].type == "Z") | (
67 | (seq[i].qubits[0] != seq[i - 1].qubit)
68 | & (seq[i].qubits[1] != seq[i - 1].qubit)
69 | ):
70 | # print('condition E commute')
71 | seq[i - 1], seq[i] = seq[i], seq[i - 1]
72 | i = i - 1
73 | continue
74 | elif seq[i - 1].type == "X":
75 | if seq[i].qubits[0] == seq[i - 1].qubit:
76 | # print('condition 1')
77 | seq[i - 1], seq[i] = seq[i], seq[i - 1]
78 | seq.insert(i, Gate("Z", [seq[i - 1].qubits[1], seq[i].power_idx]))
79 | i = i - 1
80 | N = len(seq)
81 | continue
82 | elif seq[i].qubits[1] == seq[i - 1].qubit:
83 | # print('condition 2')
84 | seq[i - 1], seq[i] = seq[i], seq[i - 1]
85 | seq.insert(i, Gate("Z", [seq[i - 1].qubits[0], seq[i].power_idx]))
86 | i = i - 1
87 | N = len(seq)
88 | continue
89 |
90 | elif seq[i].type == "M":
91 | if (seq[i - 1].type == "M") | (seq[i - 1].type == "E"):
92 | i = i + 1
93 | continue
94 | elif seq[i].qubit != seq[i - 1].qubit:
95 | # print('condition M commute')
96 | seq[i - 1], seq[i] = seq[i], seq[i - 1]
97 | i = i - 1
98 | continue
99 | elif seq[i - 1].type == "X":
100 | # print('condition X++')
101 | seq[i].X_idxs.append(seq[i - 1].power_idx)
102 | del seq[i - 1]
103 | N = len(seq)
104 | i = i - 1
105 | continue
106 | elif seq[i - 1].type == "Z":
107 | # print('condition Z++')
108 | seq[i].Z_idxs.append(seq[i - 1].power_idx)
109 | del seq[i - 1]
110 | N = len(seq)
111 | i = i - 1
112 | continue
113 |
114 | i = i + 1
115 | N = len(seq)
116 |
117 | return seq
118 |
119 |
120 | def count_qubits_in_sequence(seq):
121 | qubits = set()
122 | for gate in seq:
123 | try:
124 | qubit_pair = gate.qubits
125 | qubits.add(qubit_pair[0])
126 | qubits.add(qubit_pair[1])
127 | except AttributeError:
128 | qubits.add(gate.qubit)
129 | return len(qubits)
130 |
131 |
132 | def circuit_file_to_flow(path):
133 | result = load_and_convert_circuit(path)
134 | seq_in = _measurement_dictionary_to_sequence(result)
135 | #for s in seq_in:
136 | # s.printinfo()
137 | seq_out = _construct_flow_from_sequence(seq_in)
138 | return seq_out, result["qout_final"]
139 |
140 |
141 | if __name__ == "__main__":
142 | seq_out = circuit_file_to_flow("./circuits/circuitCNOT.json")
143 | qubits_needed = count_qubits_in_sequence(seq_out)
144 | print("qubits needed: {}".format(qubits_needed))
145 | print("----- out -----")
146 | for s in seq_out:
147 | s.printinfo()
148 |
--------------------------------------------------------------------------------
/UBQC/graph.py:
--------------------------------------------------------------------------------
1 | import networkx as nx
2 | import numpy as np
3 | import matplotlib.pyplot as plt
4 |
5 | def cluster1D(n):
6 | G = nx.Graph()
7 | G.add_node(0,pos=(0,0))
8 | for i in range(n-1):
9 | G.add_node(i+1,pos=(i+1,0))
10 | G.add_edge(i,i+1)
11 | return G
12 |
13 | #nb(qubits) = n*n
14 | def cluster2D(n):
15 | G = nx.Graph()
16 | for j in range(n) :
17 | if j ==0 :
18 | G.add_node(j*n,pos=(j,n-1))
19 | for i in range(n-1):
20 | G.add_node(j*n+i+1,pos=(j,n-i-2))
21 | G.add_edge(j*n+i,j*n+i+1)
22 | else :
23 | G.add_node(j*n,pos=(j,n-1))
24 | for i in range(n-1):
25 | G.add_node(j*n+i+1,pos=(j,n-i-2))
26 | G.add_edge(j*n+i,j*n+i+1)
27 | G.add_edge(j*n+i,(j-1)*n+i)
28 | G.add_edge(j*n+i+1,(j-1)*n+i+1)
29 | return G
30 |
31 | def draw_graph(Edges):
32 | G = nx.Graph()
33 | for E in Edges:
34 | G.add_edge(E[0],E[1])
35 | nx.draw(G,with_labels = True)
36 | plt.show(block = False)
37 |
38 |
39 | #G = cluster2D(5)
40 | #pos=nx.get_node_attributes(G,'pos')
41 | #print(pos)
42 | #pos = nx.circular_layout(G)
43 | #nx.draw(G, pos, with_labels = True)
44 | #nx.draw(G, pos, with_labels = True)
45 | #plt.show()
46 |
47 | #Edges = [[2, 3], [1, 3], [3, 4], [1, 5], [4, 5], [5, 6], [4, 7], [6, 7], [7, 8]]
48 | ##for E in Edges:
49 | # G.add_edge(E[0],E[1])
50 | #draw_graph(G,Edges)
51 | #nx.draw(G, with_labels = True)
52 | #plt.show()
53 |
54 | def draw_graph_pos(Edges,ninput,nqubits):
55 | #plt.show()
56 | G = nx.Graph()
57 | Nodes = []
58 | l = 0
59 | c = 0
60 | nNodes = 0
61 | colors = []
62 | nEdges = len(Edges)
63 | len_edg = 0;
64 | for i in range(ninput):
65 | G.add_node(i+1,pos=(0,i))
66 | colors.append('blue')
67 | Nodes.append(i+1)
68 | nNodes = len(set(Nodes))
69 | New_Nodes = []
70 | for E in Edges:
71 | if E[0] <= ninput:
72 | if New_Nodes.count(E[1]) == 0:
73 | G.add_node(E[1],pos=(1,l))
74 | colors.append('gray')
75 | New_Nodes.append(E[1])
76 | #print("E = {} l = {} New_Nodes = {}".format(E,l,New_Nodes))
77 | l+=1
78 | G.add_edge(E[0],E[1])
79 | len_edg+=1
80 | #print("Ajoute E = {}".format(E))
81 | Nodes = Nodes + New_Nodes
82 | #print("Nodes = {}".format(Nodes))
83 |
84 |
85 | c = 2
86 | l = 0
87 | print("nNodes = {}".format(nNodes))
88 | while(len_edg != nEdges ):
89 | Temp_Nodes = []
90 | for E in Edges:
91 | if New_Nodes.count(E[0]) == 1:
92 | if Nodes.count(E[1]) == 0:
93 | if Temp_Nodes.count(E[1]) == 0:
94 | G.add_node(E[1],pos=(c,l))
95 | colors.append('gray')
96 | l+=1
97 | Temp_Nodes.append(E[1])
98 | #print("E = {} l = {} Temp_Nodes = {}".format(E,l,Temp_Nodes))
99 | G.add_edge(E[0],E[1])
100 | len_edg+=1
101 | #print("Ajoute E = {}".format(E))
102 | New_Nodes = Temp_Nodes
103 | Nodes = Nodes + New_Nodes
104 | #print("Nodes = {} New_Nodes = {}".format(Nodes,New_Nodes))
105 | #print("nNodes = {}".format(nNodes))
106 | c+=1
107 | l=0
108 |
109 | pos=nx.get_node_attributes(G,'pos')
110 | #splt.ion()
111 | #plt.show()
112 | nx.draw(G,pos,node_color=colors,with_labels = True)
113 | plt.pause(0.001)
114 | return G,pos,colors
115 |
116 | def update_graph(G,pos,colors,idx_output):
117 | for node in G:
118 | if idx_output.count(node-1):
119 | colors[node-1]='red'
120 | #plt.ion()
121 | #plt.show()
122 | nx.draw(G,pos,node_color=colors,with_labels = True)
123 | plt.pause(0.001)
124 |
125 | if __name__ == "__main__":
126 |
127 | Edges = [[1, 3], [3, 4], [2, 5], [4, 5], [5, 6], [4, 6]]
128 | ninput = 2
129 | nqubits = 6
130 | result=draw_graph_pos(Edges,ninput,nqubits)
131 | idx_output = [3,5]
132 | update_graph(result[0],result[1],result[2],idx_output)
133 | plt.show()
--------------------------------------------------------------------------------
/UBQC/mbqc.py:
--------------------------------------------------------------------------------
1 | import numpy as np, random, sys
2 | from pathlib import Path
3 |
4 | from angle import measure_angle2
5 |
6 | #only for testing with maibn
7 | from cqc.pythonLib import CQCConnection, qubit
8 |
9 | #only for mbqc function :
10 | from flow import circuit_file_to_flow, count_qubits_in_sequence
11 |
12 |
13 | def mbqc(node, circuit, input_qubits):
14 | """runs a given circuit using measurement based quantum computing
15 |
16 | :node: CQCConnection
17 | :circuit: path to circuit json file
18 | :input_qubits: list of input qubits on which the circuit will run. Must belong to node
19 |
20 | :return: list of output qubits
21 | """
22 |
23 | seq_out = circuit_file_to_flow(str(circuit))
24 | nQubits = count_qubits_in_sequence(seq_out)
25 |
26 | E1=[]
27 | E2=[]
28 |
29 | for s in seq_out:
30 | #s.printinfo()
31 | if s.type=="E":
32 | E1.append(s.qubits[0])
33 | E2.append(s.qubits[1])
34 |
35 | outcome = nQubits * [-1] # Outcome of each qubit measurement will be stored in this outcome list
36 |
37 | # generate the rest of the qubits for the graph state
38 | qubits = []
39 | for i in range(nQubits):
40 | if (i < len(input_qubits)):
41 | qubits.append(input_qubits[i])
42 | else:
43 | q = qubit(node)
44 | q.H() #|+> state
45 | qubits.append(q)
46 |
47 | # entangle all the qubits
48 | for i,j in zip(E1,E2):
49 | qubits[i-1].cphase(qubits[j-1])
50 |
51 | # run the measurements and corrections
52 | for s in seq_out:
53 | if s.type=='E':
54 | continue
55 | else:
56 | q = qubits[s.qubit-1]
57 | if s.type=='M':
58 | angle = measure_angle2(s, outcome, 0)
59 | q.rot_Z(-int(angle)%256)
60 | q.rot_Y(256-64) # to make the measurement along in the |+> |-> basis
61 | outcome[s.qubit-1] = qubits[s.qubit-1].measure()
62 | elif s.type=='Z':
63 | if (s.power_idx == 0):
64 | q.Z()
65 | elif outcome[s.power_idx-1]==1:
66 | q.Z()
67 | elif s.type=='X':
68 | if (s.power_idx == 0):
69 | q.X()
70 | elif outcome[s.power_idx-1]==1:
71 | q.X()
72 |
73 | print(outcome)
74 | output_qubits = [qubits[i] for i,n in enumerate(outcome) if n==-1] # get the qubits which have not been measured
75 | return output_qubits
76 |
77 | def measure_mbqc(seq_out, nQubits, qubits):
78 |
79 | outcome = nQubits * [-1]
80 |
81 | for s in seq_out:
82 | if s.type=='E':
83 | continue
84 | else:
85 | q = qubits[s.qubit-1]
86 | if s.type=='M':
87 | angle = measure_angle2(s, outcome, 0)
88 | #print("angle = %d " % angle)
89 | q.rot_Z(-int(angle)%256)
90 | q.rot_Y(256-64) # to make the measurement along in the |+> |-> basis
91 | outcome[s.qubit-1] = qubits[s.qubit-1].measure()
92 | elif s.type=='Z':
93 | if (s.power_idx == 0):
94 | q.Z()
95 | elif outcome[s.power_idx-1]==1:
96 | q.Z()
97 | elif s.type=='X':
98 | if (s.power_idx == 0):
99 | q.X()
100 | elif outcome[s.power_idx-1]==1:
101 | q.X()
102 |
103 | #print(outcome)
104 | output_qubits = [qubits[i] for i,n in enumerate(outcome) if n==-1] # get the qubits which have not been measured
105 | output_idx = [i for i,n in enumerate(outcome) if n==-1] # get the index, used only for updating the graph.
106 | return output_qubits, output_idx
107 |
108 |
109 |
110 |
111 | if __name__ == "__main__":
112 |
113 | for i in range(10):
114 | with CQCConnection("Alice") as Alice:
115 |
116 | # generate the input qubits for the circuit
117 | q1 = qubit(Alice)
118 | q2 = qubit(Alice)
119 | q1.H()
120 | q2.X()
121 |
122 | #out = mbqc(Alice, "../ubqc/circuits/CNOT.json", [q1, q2])
123 | #out = mbqc(Alice, "../ubqc/circuits/circuitRZ.json", [q1, q2])
124 | out = mbqc(Alice, "circuits/circuit1.json", [q1,q2])
125 |
126 | # measure the output qubits
127 | final_result = []
128 | for q in out:
129 | #q.rot_Z(32)
130 | #q.H()
131 | final_result.append(q.measure())
132 |
133 | print('MBQC outcome:', final_result)
134 | Alice.close()
135 |
136 |
137 |
138 |
139 |
--------------------------------------------------------------------------------
/UBQC/runMBQC.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | python serverMBQC.py -d &
4 | python clientMBQC.py -d
5 |
--------------------------------------------------------------------------------
/UBQC/runUBQC.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | python serverUBQC.py -d &
4 | python clientUBQC.py -d
5 |
--------------------------------------------------------------------------------
/UBQC/script.sh:
--------------------------------------------------------------------------------
1 | #open two terminal, run script.sh in one and output bob to the other one (run tty to know /dev/pts/$i)
2 | #!/bin/bash
3 |
4 | #Example 1 : execute CNOT gate on |+0> using MBQC. Expect [0,0] or [1,1] as measurement each time
5 | # for i in `seq 25`
6 | # do
7 | # python serverMBQC.py >/dev/pts/2 &
8 | # python clientMBQC.py -c circuits/circuitCNOT.json -i H,I
9 | # done
10 |
11 |
12 | #Example 2 : execute SWAP gate on |+-> using UBQC amd measure in the X basis. Expect [1,0] as measurement each time
13 | for i in `seq 10`
14 | do
15 | # python serverUBQC.py >/dev/pts/0 &
16 | python serverUBQC.py &
17 | python clientUBQC.py -c circuits/circuitSWAP.json -i I,Z -o H,H
18 | done
--------------------------------------------------------------------------------
/UBQC/serverMBQC.py:
--------------------------------------------------------------------------------
1 | import json
2 | import numpy as np
3 | import matplotlib.pyplot as plt
4 | from matplotlib.pyplot import ion,show
5 | import pickle
6 | import argparse
7 | from argparse import RawTextHelpFormatter
8 | from graph import draw_graph_pos, update_graph
9 | from mbqc import measure_mbqc
10 | from cqc.pythonLib import CQCConnection, qubit
11 |
12 |
13 | parser=argparse.ArgumentParser(
14 | # description='''Description. '''#,
15 | # epilog="""All's well that ends well."""
16 | #)
17 | description='''Description.\nexample : python serverMBQC.py -d''',
18 | formatter_class=RawTextHelpFormatter
19 | )
20 | parser.add_argument('-d','--draw', action="store_true", help='draw the graph')
21 | args=parser.parse_args()
22 |
23 |
24 | with CQCConnection("Bob") as Bob:
25 | msg="OK"
26 | data_ok = pickle.dumps(msg)
27 |
28 | nQubits = Bob.recvClassical()
29 | nQubits = int.from_bytes(nQubits, byteorder="little")
30 | print("Bob Received: Number of qubits = {} ".format(nQubits))
31 |
32 | Bob.sendClassical("Alice", data_ok)
33 |
34 | ninput = Bob.recvClassical()
35 | ninput = int.from_bytes(ninput, byteorder="little")
36 | print("Bob Received: Number of input states = {}".format(ninput))
37 |
38 | Bob.sendClassical("Alice", data_ok)
39 |
40 | # #Edges = []
41 | # recvd_data = Bob.recvClassical()
42 | # Edges = pickle.loads(recvd_data)
43 | # print("Bob Received: Edges = {}".format(Edges))
44 | # recvd_data = Bob.recvClassical()
45 | # data = pickle.loads(recvd_data)
46 | # print("Bob Received: = {}".format(data))
47 |
48 | recvd_data = Bob.recvClassical()
49 | seq_out = pickle.loads(recvd_data)
50 | print("Server Received: seq_out")
51 | Bob.sendClassical("Alice", data_ok)
52 |
53 | Edges = []
54 | for s in seq_out:
55 | s.printinfo()
56 | if s.type == "E":
57 | Edges.append(s.qubits)
58 |
59 | print("E= {}".format(Edges))
60 | #print("Server receiving input states")
61 | qubits = []
62 | for i in range(ninput):
63 | q = Bob.recvQubit()
64 | Bob.sendClassical("Alice", data_ok)
65 | qubits.append(q)
66 | print("Server Received: qubit received.")
67 |
68 |
69 | print("Server creates graph state")
70 | for i in range(ninput,nQubits):
71 | q = qubit(Bob)
72 | q.H() #|+> state
73 | qubits.append(q)
74 | #qout_idx = list(range(nQubits))
75 | for E in Edges:
76 | qubits[E[0]-1].cphase(qubits[E[1]-1])
77 |
78 | #Comment to not draw the graph
79 | if(args.draw):
80 | G1 = draw_graph_pos(Edges,ninput,nQubits)
81 |
82 |
83 | print("Server makes adaptive measurements and corrections")
84 | result = measure_mbqc(seq_out,nQubits,qubits)
85 | qout = result[0]
86 | #print("idx_output ",result[1])
87 |
88 | #comment to not draw/update the graph
89 | if(args.draw):
90 | idx_output = result[1]
91 | update_graph(G1[0],G1[1],G1[2],idx_output)
92 |
93 | noutput = len(qout)
94 |
95 | print("Server Sending: Number of output qubits = {}".format(noutput))
96 | Bob.sendClassical("Alice", noutput)
97 |
98 | for q in qout:
99 | Bob.sendQubit(q,"Alice")
100 | recvd_data = Bob.recvClassical()
101 | data = pickle.loads(recvd_data)
102 | if data != "OK":
103 | print("Server received : {} ".format(data))
104 |
105 | if(args.draw):
106 | plt.show()
107 | Bob.close()
108 |
--------------------------------------------------------------------------------
/UBQC/serverUBQC.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import json
3 | #import struct
4 | import time
5 | import pickle
6 | import argparse
7 | from argparse import RawTextHelpFormatter
8 | import matplotlib.pyplot as plt
9 | from matplotlib.pyplot import ion,show
10 | from graph import draw_graph_pos, update_graph
11 | from cqc.pythonLib import CQCConnection, qubit
12 |
13 |
14 | parser=argparse.ArgumentParser(
15 | # description='''Description. '''#,
16 | # epilog="""All's well that ends well."""
17 | #)
18 | description='''Description.\nexample : python serverUBQC.py -d''',
19 | formatter_class=RawTextHelpFormatter
20 | )
21 | parser.add_argument('-d','--draw', action="store_true", help='draw the graph')
22 | args=parser.parse_args()
23 |
24 |
25 | qubits = []
26 | num_measurements = 4
27 | outcome = []
28 |
29 | client_name = "Alice"
30 |
31 | with CQCConnection("Bob") as Server:
32 | # Client first defines number of qubits needed for their circuit
33 | nQubits = Server.recvClassical()
34 | nQubits = int.from_bytes(nQubits, byteorder="little")
35 | print("Server Received (classical): Create {} qubits".format(nQubits))
36 |
37 | # We need to receive all qubits from client
38 | for i in range(nQubits):
39 | qubits.append(Server.recvQubit())
40 | print("Server Received (quntum): qubits received")
41 |
42 | # Client next defines the number of measurments to be performed
43 | nMeasurement = Server.recvClassical()
44 | nMeasurement = int.from_bytes(nMeasurement, byteorder="little")
45 | print(
46 | "Server Received (classical): Client asking to perform {} measurements".format(
47 | nMeasurement
48 | )
49 | )
50 |
51 | # First step of MBQC is entangling qubits into a graph state
52 | E = []
53 | E1 = Server.recvClassical()
54 | print("Server Received (classical): List of 1st Qubits to Entangle".format(nQubits))
55 | E2 = Server.recvClassical()
56 | print("Server Received (classical): List of 2nd Qubits to Entangle".format(nQubits))
57 | print("Server Entangling...")
58 | for i, j in zip(E1, E2):
59 | qubit_i = qubits[i - 1]
60 | qubit_j = qubits[j - 1]
61 | qubit_i.cphase(qubit_j)
62 | E.append([i,j])
63 | print("entg qubit {} with qubit {}".format(i, j))
64 | print("E= {}".format(E))
65 |
66 | if(args.draw):
67 | G1 = draw_graph_pos(E,nQubits-nMeasurement,nQubits)
68 |
69 | # Server is ready to measure!
70 | print("Server Measuring...")
71 | qout_idx = list(range(nQubits))
72 | #print("{} {}".format(qout_idx,nQubits))
73 | for i in range(nMeasurement):
74 | # Each measurement has has a qubit index (between 0 and nQubits)
75 | qubit_n = int.from_bytes(Server.recvClassical(), "little")
76 | # Each measurement has an angle to measure in degrees
77 | angle = int.from_bytes(Server.recvClassical(), "little")
78 | qout_idx.remove(qubit_n-1)
79 | #print("{}".format(qout_idx))
80 | print("Server Measuring qubit {} using angle {}".format(qubit_n, angle))
81 | #qubits[qubit_n-1].rot_Z(angle)
82 | qubits[qubit_n-1].rot_Z(-int(angle)%256)
83 | qubits[qubit_n-1].rot_Y(256-64) # to make the measurement along in the |+> |-> basis
84 | m = qubits[qubit_n-1].measure()
85 |
86 | time.sleep(0.1)
87 | print("Server Sending (classical): result of measurement {}".format(m))
88 | Server.sendClassical(client_name, m)
89 |
90 | for i in range(nQubits-nMeasurement):
91 | print("Server Sending (quantum): qubit {}".format(qout_idx[i]+1))
92 | Server.sendQubit(qubits[qout_idx[i]], client_name)
93 | recv_data = Server.recvClassical() #recv ok from the client
94 | data = pickle.loads(recv_data)
95 | print("message = {} ".format(data))
96 |
97 | if(args.draw):
98 | update_graph(G1[0],G1[1],G1[2],qout_idx)
99 | plt.show()
100 |
101 | sys.exit(0)
102 |
--------------------------------------------------------------------------------
/UBQC/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "control": {
3 | "shadow": false,
4 | "size": 0.1
5 | },
6 | "gate_shadow": true,
7 | "gates": {
8 | "AllocateQubitGate": {
9 | "allocate_at_zero": false,
10 | "draw_id": false,
11 | "height": 0.15,
12 | "offset": 0.1,
13 | "pre_offset": 0.1,
14 | "width": 0.2
15 | },
16 | "DeallocateQubitGate": {
17 | "height": 0.15,
18 | "offset": 0.2,
19 | "pre_offset": 0.1,
20 | "width": 0.2
21 | },
22 | "EntangleGate": {
23 | "offset": 0.2,
24 | "pre_offset": 0.2,
25 | "width": 1.8
26 | },
27 | "HGate": {
28 | "offset": 0.3,
29 | "pre_offset": 0.1,
30 | "width": 0.5
31 | },
32 | "MeasureGate": {
33 | "height": 0.5,
34 | "offset": 0.2,
35 | "pre_offset": 0.2,
36 | "width": 0.75
37 | },
38 | "Ph": {
39 | "height": 0.8,
40 | "offset": 0.3,
41 | "pre_offset": 0.2,
42 | "width": 1.0
43 | },
44 | "Rx": {
45 | "height": 0.8,
46 | "offset": 0.3,
47 | "pre_offset": 0.2,
48 | "width": 1.0
49 | },
50 | "Ry": {
51 | "height": 0.8,
52 | "offset": 0.3,
53 | "pre_offset": 0.2,
54 | "width": 1.0
55 | },
56 | "Rz": {
57 | "height": 0.8,
58 | "offset": 0.3,
59 | "pre_offset": 0.2,
60 | "width": 1.0
61 | },
62 | "SqrtSwapGate": {
63 | "height": 0.35,
64 | "offset": 0.1,
65 | "width": 0.35
66 | },
67 | "SqrtXGate": {
68 | "offset": 0.3,
69 | "pre_offset": 0.1,
70 | "width": 0.7
71 | },
72 | "SwapGate": {
73 | "height": 0.35,
74 | "offset": 0.1,
75 | "width": 0.35
76 | },
77 | "XGate": {
78 | "height": 0.35,
79 | "offset": 0.1,
80 | "width": 0.35
81 | }
82 | },
83 | "lines": {
84 | "double_classical": true,
85 | "double_lines_sep": 0.04,
86 | "init_quantum": true,
87 | "style": "very thin"
88 | }
89 | }
--------------------------------------------------------------------------------
/UnclonableEncryption/readme.org:
--------------------------------------------------------------------------------
1 | #+TITLE: Uncloneable Encryption
2 |
3 | The code in this directory provides an implementation of the basic steps required in the uncloneable encryption protocol. It performs the classical part of the algorithm (that is it defines the values of the bits and bases that are chosen to encode the classical message using a BB84 encoding type). The receiver would use its secret bits to perform the operation in reverse and check that the message has not been tempered with.
4 |
5 | The quantum encoding / sending / decoding being a plain request to an elementary quantum functionality (BB84 encoding / decoding) it has not been implemented and will we left to the user.
6 |
7 | Below, we dig a little bit more into how to pick the classical error correcting codes to use in the protocol.
8 |
9 | * Code picking
10 | Take $C_1$ and $C_2$ s.t. $C_2^\perp \subset C_1$.
11 |
12 | For $C_i$ we denote $H_i$ the parity check matrix, and $G_i$ the generating matrix. That is, the rows of $G_i$ generate $C_i$ by linear combinations, and we have the property that $H_i . G_i^T = 0_{N-K, K}$ (or $0_{N-K', K'}$ for i = 2).
13 |
14 | Now we chose $c_1$ an $N-K$ bit string at random. We encode our message $x$ in a $N$ bit string $y$ chosen at random provided that $y$ belongs to the coset $C_1^{c_1}$ of $C_1$ defined by $c_1$ and to the coset associated to $x$ of $C_1^{c_1}/C_2^\perp$.
15 |
16 | How to do in practice?
17 |
18 | The conditions above on $y$ are the following:
19 |
20 | $$H_1.y = c_1$$ and
21 | $$K_2.y = x$$
22 |
23 | where $K_2$ is a block matrix such that $G_2 = \left( \frac{H_1}{K_2}\right)$. $G_2$ can always be writen in this way as $C_2^\perp \subset C_1$. [$C_2^\perp$ parity check is $G_2$ and its generating matrix is $H_2$. Since $C_2^\perp \subset C_1$, we have $H_1 . H_2^T = 0_{N-K, N-K'}$ which in turn implies that we can choose the first $N-K$ parity check equations of $C2^\perp$ to be defined by $H_1$. That is the first $N-K$ lines of $G_2$ are $H_1$. The $K'+K-N$ independent remaining ones define $K_2$.]
24 |
25 | * Closer to practice
26 | ** Preprocessing of the codes
27 |
28 |
29 | Similarly, the generating matrix of $G_1$ can be chosen so that its first $N-K'$ rows are $H_2$, while the rest $K+K'-N$ lines which defines a submatrix $K_2$ satisfy $H_1 K_2^T = 0$ and $K_1 K_2^T = I$.
30 |
31 | In short, $K_1$ is such that for a codeword of $C_1$ it will determine which coset of $C_2^\perp$ it is associated to. $K_2$ will allow to change coset while staying in $C_1$.
32 |
33 | ## Encoding
34 | 1. We pick $c_1$ a length-$(N-K)$ bit string at random. Then, because $C_1$ can be easily decoded, we find $y_0$ such that $H_1 y_0^T = c_1^T$.
35 |
36 | 1. We also compute $y_1$ such that $K_1 (y_0 + y_1) = 0$. This is easily done since $K_1 K_2^T = I$.
37 |
38 | 1. Now we want to send $x$, a $(K+K'-N)$-bit string. We construct the vector $y_2 = x K_2$.
39 |
40 | 1. Then we pick $z$ a $(N-K')$-bit string at random and construct $y_3 = z H_2$.
41 |
42 | Then we form $y = y_0 + y_1 + y_2 + y_3$.
43 |
44 | Here $y_0$ moves to a coset of $C_1$ with syndrome $c_1$.
45 |
46 | $y_1$ stays in the same coset of $C_1$ but moves to the coset of $C_2^\perp$ with all zero syndrome.
47 |
48 | $y_2$ picks the coset of $C_2\perp$ associated to the chosen syndrome $x$, which is equivalent to finding a representative of the chosen coset of $C_1/C_2^\perp$.
49 |
50 | $y_3$ stays in the same coset of $C_2/C_2^\perp$ but changes representative at random.
51 | """
52 |
--------------------------------------------------------------------------------
/UnclonableEncryption/unclonableencryption.py:
--------------------------------------------------------------------------------
1 | # pip install qiskit
2 |
3 | import numpy as np
4 |
5 | #import matplotlib.pyplot as plt
6 | # from qiskit import *
7 |
8 | # Global Variables describing message and authentication
9 |
10 | n = 2
11 | r = 2
12 | s = int(n/r)
13 | len_k = s
14 | len_e = n+s
15 |
16 | # ECC for (n + s = 3)
17 |
18 | # Classical Error Correction Matrices
19 |
20 | # C2 = Dual of hamming code (3->7)
21 | # C2_perp = hamming code (4->7)
22 |
23 | G_p = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1], [0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 0, 1]]
24 | H_p = [[0, 0, 0, 1, 1, 1, 1], [0, 1, 1, 0, 0, 1, 1], [1, 0, 1, 0, 1, 0, 1]]
25 | K = [[0, 0, 0, 1, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0]]
26 |
27 | '''
28 | # C2 = Dual of repetition code (2->3)
29 | # C2_perp = repetition code (1->3)
30 |
31 | G_p = [1, 1, 1]
32 | H_p = [[1, 1, 0], [0, 1, 1]]
33 | K = [[0, 1, 1], [0, 0, 1]]
34 | '''
35 |
36 |
37 |
38 | def GenKey():
39 | return np.random.randint(0, 2, len_k), np.random.randint(0, 2, len_e), np.random.randint(0, 2, len(G_p))
40 |
41 | def ConvToInt(arr):
42 | res = int("".join(str(x) for x in arr), 2)
43 | return res
44 |
45 | k, e, b = GenKey()
46 | print(k)
47 | print(e)
48 | print(b)
49 |
50 |
51 |
52 | def Send():
53 |
54 | def GenMsg():
55 | return np.random.randint(0, 2, n)
56 |
57 | msg = GenMsg()
58 | print("Actual Message: ", msg)
59 |
60 | def MakeMi(message):
61 | m = []
62 | for i in range(0,n,s):
63 | m.append(ConvToInt(message[i:i+s]))
64 | return m
65 |
66 | def MakeMr():
67 | m = MakeMi(msg)
68 | f_k = 0
69 |
70 | for i in range(0,r):
71 | f_k += m[i]*(ConvToInt(k)**(r-i))
72 |
73 | f_k = f_k%(2**s)
74 | return (2**s - f_k)%(2**s)
75 |
76 | def MakeMsgToSend():
77 | msgToSend=msg
78 | Mr = bin(MakeMr())[2:].zfill(s)
79 | msgToSend = np.array(np.append(msgToSend, list(Mr)), dtype=int)
80 | XORed_msg = ConvToInt(msgToSend) ^ ConvToInt(e)
81 | y = list(bin(XORed_msg)[2:].zfill(len(e)))
82 | return (np.array(y, dtype=int))
83 |
84 | y = MakeMsgToSend()
85 | print("Message to be sent (without EC): ", y)
86 |
87 | z0 = np.mod(np.matmul(np.transpose(y), K), 2)
88 | random_choice = np.random.randint(0, 2, 4)
89 | z = np.mod(z0 + np.matmul(G_p, np.transpose(random_choice)), 2)
90 | print("Message to be sent (with EC): ", z)
91 |
92 | return z
93 |
94 | def Receive(received_msg):
95 | y_dec = np.mod(np.matmul(H_p, np.transpose(received_msg)), 2)
96 | print("Received message after EC: ", y_dec)
97 |
98 | XORed_msg_dec = ConvToInt(y_dec) ^ ConvToInt(e)
99 | Mis_dec = list(bin(XORed_msg_dec)[2:].zfill(len(e)))
100 | Mis_dec = np.array([int(x) for x in Mis_dec])
101 | print("Actual message received: ", Mis_dec[:-s])
102 | return Mis_dec[:-s]
103 |
104 | def main():
105 | sent_message = Send()
106 | print("Send and Receive the message with bits to be sent in the X basis if the corresponding bit in b is 0, else in the Z basis.")
107 | received_message = Receive(sent_message)
108 |
109 | if __name__ == "__main__":
110 | main()
111 |
112 |
113 |
114 |
--------------------------------------------------------------------------------
/WeakStringErasure/WSEAlice.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from random import randint, random, sample
3 | from cqc.pythonLib import CQCConnection, qubit
4 | from multiprocessing import Pool
5 | from time import sleep
6 |
7 | deltat = 5
8 | bits_alice = []
9 | basis_alice = []
10 |
11 |
12 | def prep_Alice():
13 |
14 | with CQCConnection("Alice") as Alice:
15 | print("Starting")
16 | for i in range(10):
17 | random_bits_alice = randint(0,1)
18 | random_basis_alice = randint(0,1)
19 | bits_alice.append(random_bits_alice)
20 | basis_alice.append(random_basis_alice)
21 | q = qubit(Alice)
22 | if random_bits_alice == 1:
23 | q.X()
24 | if random_basis_alice == 1:
25 | q.H()
26 | Alice.sendQubit(q, "Bob")
27 | print("Qubits were sent")
28 | Alice.flush()
29 |
30 |
31 | print("Now Alice and Bob are waiting on time:")
32 | sleep(deltat)
33 | # Alice.sendClassical("Bob", bits_alice)
34 | print("Alice sends her basis as classical messages: ", basis_alice)
35 | Alice.sendClassical("Bob", basis_alice)
36 |
37 | if __name__ == "__main__":
38 |
39 | prep_Alice()
40 |
41 |
--------------------------------------------------------------------------------
/WeakStringErasure/WSEBob.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from random import randint, random, sample
3 | from cqc.pythonLib import CQCConnection, qubit
4 | from multiprocessing import Pool
5 | from time import sleep
6 |
7 |
8 | deltat = 5
9 | receivedbasisbybob = []
10 | basis_bob = []
11 | receivebits = []
12 | trueindex = []
13 | truebits = []
14 | def prep_Bob():
15 |
16 | with CQCConnection("Bob") as Bob:
17 | print("Starting")
18 | for i in range(10):
19 | q = Bob.recvQubit()
20 | random_basis_bob = randint(0,1)
21 | basis_bob.append(random_basis_bob)
22 | if random_basis_bob == 1:
23 | q.H()
24 | m = q.measure()
25 | receivebits.append(m)
26 | print("received bits: ", receivebits)
27 | print("Basis produced by Bob: ",basis_bob)
28 | print("Now Alice and Bob are waiting on time:")
29 | sleep(deltat)
30 | r = Bob.recvClassical()
31 | receivedbasisbybob[:] = list(r)
32 | print("Received basis by Bob: ", receivedbasisbybob)
33 |
34 | for i in range(len(receivebits)):
35 | if(receivedbasisbybob[i] == basis_bob[i]):
36 | print(i)
37 | trueindex.append(i)
38 | truebits.append(basis_bob[i])
39 | print("The final index: ", trueindex)
40 | print("The final bits: ",truebits)
41 |
42 | if __name__ == "__main__":
43 |
44 | prep_Bob()
45 |
--------------------------------------------------------------------------------
/WeakStringErasure/readme.md:
--------------------------------------------------------------------------------
1 | In this part, we implemented Weak String Erasure protocol.
2 | You can find the detailed knowledge from here: https://wiki.veriqloud.fr/index.php?title=Weak_String_Erasure
3 |
4 | In the WSEAlice.py code:
5 | 1)First, Alice produces n bits and n basis randomly
6 | 2)Alice produces fresh qubits
7 | 3)According to values of bits and basis, applied X or H gate
8 | 4)Alice sends qubits to Bob
9 | After these steps the second part begins for Alice
10 | 5)For security Alice and Bob wait for a specific time
11 | 6)After this Alice send her basis to Bob
12 |
13 |
14 | In the WSEBob.py code:
15 | 1)First Bob receive qubits
16 | 2)Bob produces his basis randomly
17 | 3)According to values of Bob's basis, Bob applies H gate
18 | After these steps the second part begins for Bob
19 | 4)For security Alice and Bob wait for a specific time
20 | 5)Bob receivebasis from Alice
21 | 6)if basis bob and received basis from alice are equal to each other, the ture values and indexes are saved in new lists
22 |
--------------------------------------------------------------------------------
/WiesnerQuantumMoney/WQM1.py:
--------------------------------------------------------------------------------
1 | from random import randint, random, sample
2 | from time import sleep
3 | from cqc.pythonLib import CQCConnection, qubit
4 |
5 |
6 |
7 | wait = 2
8 | N = 10
9 | M = 2
10 | Alice_bits = [ [] for i in range(M) ]
11 | Alice_basis = [[] for j in range(M)]
12 | def preperation_and_controlling():
13 | print("The first part is starting and The bank prepare the moneys")
14 | with CQCConnection("Alice") as Alice:
15 | for serial in range(M):
16 | for j in range(N):
17 | random_bits = randint(0,1)
18 | random_basis = randint(0,1)
19 | Alice_bits[serial].append(random_bits)
20 | Alice_basis[serial].append(random_basis)
21 | q = qubit(Alice)
22 |
23 | if random_bits == 1:
24 | q.X()
25 |
26 | if random_basis == 1:
27 | q.H()
28 | Alice.sendQubit(q, "Bob")
29 |
30 | Alice.flush()
31 | print("Alice_bits ", Alice_bits)
32 | print("Alice_basis ", Alice_basis)
33 | print("Second part is starting: ")
34 | sleep(wait)
35 | serial = Alice.recvClassical()[0]
36 | print("Alice received classical message: ",serial)
37 | sleep(wait)
38 | for j in range(N):
39 | q = Alice.recvQubit()
40 | if Alice_basis[serial][j] == 1:
41 | q.H()
42 | m = q.measure()
43 | if m != Alice_bits[serial][j]:
44 | print("cheating! for this bit: ", m)
45 | print("The money is secure:", m)
46 |
47 |
48 | if __name__ == "__main__":
49 | preperation_and_controlling()
50 |
51 |
--------------------------------------------------------------------------------
/WiesnerQuantumMoney/WQM2.py:
--------------------------------------------------------------------------------
1 | from random import randint, random, sample
2 | from time import sleep
3 | from cqc.pythonLib import CQCConnection, qubit
4 |
5 | M = 2
6 | N = 10
7 | wait = 2
8 | basis = []
9 | serialnumbers = []
10 | accepted_basis = []
11 | measurements = []
12 | trueindex = []
13 | truebits = []
14 | Bob_recv = [ [] for i in range(N) ]
15 |
16 | def usage_money():
17 | with CQCConnection("Bob") as Bob:
18 | for serial in range(M):
19 | for j in range(N):
20 | q = Bob.recvQubit()
21 | Bob_recv[serial].append(q)
22 | sleep(wait)
23 | print("Second part is starting")
24 | serial = randint(0,M-1)
25 | sleep(wait)
26 | Bob.sendClassical("Alice", serial)
27 | print("serial has been sent: ", serial)
28 | sleep(wait)
29 | for j in range(N):
30 | Bob.sendQubit(Bob_recv[serial][j], "Alice")
31 | print("qubits have been sent!")
32 |
33 | if __name__ == "__main__":
34 | usage_money()
35 |
36 |
--------------------------------------------------------------------------------
/WiesnerQuantumMoney/WQMreadme.md:
--------------------------------------------------------------------------------
1 | In this part, we implemented protocol of Wiesner Quantum Money
2 | You can find the detailed knowledge from here: http://users.cms.caltech.edu/~vidick/teaching/120_qcrypto/wiesner.pdf
3 |
4 |
5 | For the first part:
6 | In the WQM1.py code:
7 | suppose that: Alice is a bank and Bob is the user
8 |
9 | 1)Bank(Alice) prepares the banknotes from the BB84 states with a unique serial number
10 | 2)Bank(Alice) send the qubits to user(Bob)
11 | Note that: In this code M = number of banknotes and N is the number of qubits for each banknotes
12 |
13 | In the WQM2.py code:
14 |
15 | 1)Bob recv qubits
16 | 2)Bob saves the qubits in a list with serial numbers
17 |
18 | For the second part:
19 | In the WQM2.py
20 | 1)Bob chooses the serial number between 0 and M(numberof banknotes)-1
21 | 2)Bob sends the serial number to the Bank(Alice)
22 | 3)Then Bob send the al qubits to the Bank with serial numbers to the Bank
23 |
24 | In the WQM1.py
25 | 1)The bank first accepts the serial number
26 | 2)Then receive qubits and measures
27 | (Before the measuring, bank applies the Hadamard gate according to value of basis)
28 | 3)If the result of measurement is not equal to the bits of banks then CHEATING!!
29 | 4)If the result of measurement is equal to the bits of banks then MONEY IS SECURE!
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/shell.nix:
--------------------------------------------------------------------------------
1 | with import { };
2 |
3 | stdenv.mkDerivation {
4 | name = "std-python";
5 | buildInputs = [
6 | # System requirements.
7 | readline
8 |
9 | # Python requirements (enough to get a virtualenv going).
10 | stdenv.cc.cc.lib
11 | python38Full
12 | python38Packages.virtualenv
13 | python38Packages.pip
14 | python38Packages.setuptools
15 | python38Packages.numpy
16 | python38Packages.pandas
17 | python38Packages.scipy
18 | python38Packages.cython
19 | python38Packages.cysignals
20 | ];
21 | src = null;
22 | shellHook = ''
23 | # Allow the use of wheels.
24 | SOURCE_DATE_EPOCH=$(date +%s)
25 |
26 | # Augment the dynamic linker path
27 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${R}/lib/R/lib:${readline}/lib:$(nix eval --raw nixpkgs.stdenv.cc.cc.lib)/lib
28 | '';
29 | }
30 |
--------------------------------------------------------------------------------