├── .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 | - ![\alpha](https://latex.codecogs.com/svg.latex?%5Calpha) (Complex number) 31 | - ![\beta](https://latex.codecogs.com/svg.latex?%5Cbeta) (Complex number), 32 | 33 | where the message state to be transmitted is ![\alpha\left|0\right\rangle + \beta\left|1\right\rangle](https://latex.codecogs.com/svg.latex?%5Calpha%7C0%5Crangle+%5Cbeta%7C1%5Crangle). 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 | title 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 | team 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 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 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 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 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 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 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 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 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 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 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 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 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 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 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 | --------------------------------------------------------------------------------