From c559f4de34d47ceeeca909ca1292200ef49cde1b Mon Sep 17 00:00:00 2001
From: A N U S H <54374648+anushkrishnav@users.noreply.github.com>
Date: Sun, 11 Apr 2021 13:58:42 +0000
Subject: [PATCH] final touch
---
QPower/Quantum_Steganography.ipynb | 5376 ++++++++++++++++++++++++++++
QPower/README.md | 19 +
2 files changed, 5395 insertions(+)
create mode 100644 QPower/Quantum_Steganography.ipynb
create mode 100644 QPower/README.md
diff --git a/QPower/Quantum_Steganography.ipynb b/QPower/Quantum_Steganography.ipynb
new file mode 100644
index 0000000..7397dfc
--- /dev/null
+++ b/QPower/Quantum_Steganography.ipynb
@@ -0,0 +1,5376 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit import *\n",
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "from qiskit.visualization import plot_histogram\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Create the quantum circuit for the BB84_keys: "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Creating registers with n qubits\n",
+ "n =7 # for a local backend n can go as up as 23, after that it raises a Memory Error\n",
+ "qr = QuantumRegister(n, name='qr')\n",
+ "cr = ClassicalRegister(n, name='cr')\n",
+ "\n",
+ "qc = QuantumCircuit(qr, cr, name='QC')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## QRNG"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ " \n",
+ " \n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "\"\\nqr2 = QuantumRegister(n, name='qr')\\ncr2= ClassicalRegister(n, name='cr')\\nqc2 = QuantumCircuit(qr2, cr2, name='QC')\\nfor i in range(n):\\n qc2.h(i)\\n qc2.measure(qr2,cr2)\\nqc2.draw(output='mpl')\\nsimulator = Aer.get_backend('qasm_simulator')\\nexecute(qc2, backend = simulator)\\nresult = execute(qc2, backend = simulator).result()\\nk=list(result.get_counts(qc2))[0]\\nprint(k)\\n\""
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "\"\"\"\n",
+ "qr2 = QuantumRegister(n, name='qr')\n",
+ "cr2= ClassicalRegister(n, name='cr')\n",
+ "qc2 = QuantumCircuit(qr2, cr2, name='QC')\n",
+ "for i in range(n):\n",
+ " qc2.h(i)\n",
+ " qc2.measure(qr2,cr2)\n",
+ "qc2.draw(output='mpl')\n",
+ "simulator = Aer.get_backend('qasm_simulator')\n",
+ "execute(qc2, backend = simulator)\n",
+ "result = execute(qc2, backend = simulator).result()\n",
+ "k=list(result.get_counts(qc2))[0]\n",
+ "print(k)\n",
+ "\"\"\"\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# BB84 Protocol :"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "\n",
+ "# Generate a random number in the range of available qubits [0,65536))\n",
+ "alice_key = np.random.randint(0,2**n)#here we can remplace by a key from a quantum key generator\n",
+ "\n",
+ "\n",
+ "alice_key = np.binary_repr(alice_key,n) \n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "0010101\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(alice_key)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "for i in range(len(alice_key)):\n",
+ " if alice_key[i]=='1':\n",
+ " qc.x(qr[i])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Choose random basis (Sender) :"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Alice Basis ['S', 'S', 'S', 'H', 'S', 'S', 'S']\n"
+ ]
+ },
+ {
+ "data": {
+ "image/svg+xml": [
+ "\n",
+ "\n",
+ "\n"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "B=[]\n",
+ "for i in range(len(alice_key)):\n",
+ "\n",
+ " if 0.5 < np.random.random():\n",
+ " qc.h(qr[i])\n",
+ " B.append(\"H\")\n",
+ " else:\n",
+ " B.append(\"S\")\n",
+ " pass\n",
+ " \n",
+ "qc.barrier() \n",
+ "print(\"Alice Basis\",B)\n",
+ "%config InlineBackend.figure_format = 'svg'\n",
+ "qc.draw(output='mpl')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Choose random basis (Receiver) :"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Bob Basis ['S', 'S', 'H', 'S', 'S', 'H', 'H']\n"
+ ]
+ },
+ {
+ "data": {
+ "image/svg+xml": [
+ "\n",
+ "\n",
+ "\n"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "C=[]\n",
+ "for i in range(len(alice_key)):\n",
+ " if 0.5 < np.random.random():\n",
+ " qc.h(qr[i])\n",
+ " C.append(\"H\")\n",
+ " \n",
+ " else:\n",
+ " C.append(\"S\")\n",
+ "qc.barrier()\n",
+ "for i in range(len(alice_key)):\n",
+ " qc.measure(qr[i],cr[i])\n",
+ "print(\"Bob Basis\",C)\n",
+ "qc.draw(output='mpl')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Bob key : 0010000\n",
+ "Bob Basis ['S', 'S', 'H', 'S', 'S', 'H', 'H']\n",
+ "Alice key : 0010101\n",
+ "Alice Basis : ['S', 'S', 'S', 'H', 'S', 'S', 'S']\n"
+ ]
+ }
+ ],
+ "source": [
+ "simulator = Aer.get_backend('qasm_simulator')\n",
+ "execute(qc, backend = simulator)\n",
+ "result = execute(qc, backend = simulator).result()\n",
+ "print(\"Bob key :\",list(result.get_counts(qc))[0])\n",
+ "print(\"Bob Basis\",C)\n",
+ "\n",
+ "print(\"Alice key :\",alice_key)\n",
+ "print(\"Alice Basis :\",B)\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Sifting the key"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "sifted key 001\n",
+ "Basis [0, 1, 4]\n"
+ ]
+ }
+ ],
+ "source": [
+ "def sifted_key(A_basis,B_basis,key): \n",
+ " correct_basis=[]\n",
+ " sifted_key=''\n",
+ "\n",
+ " for i in range(len(A_basis)):\n",
+ " if A_basis[i]==B_basis[i]:\n",
+ " correct_basis.append(i)\n",
+ " sifted_key+=key[i]\n",
+ " else:\n",
+ " pass \n",
+ " return sifted_key,correct_basis\n",
+ "a=sifted_key(B,C,alice_key)\n",
+ "print(\"sifted key\",a[0])\n",
+ "print(\"Basis\",a[1])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "BB84_key=a[0]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Encoding the Secret Message into the QC"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def wordToBV(s) :\n",
+ " #convert text to binary\n",
+ " a_byte_array = bytearray(s, \"utf8\")\n",
+ " byte_list = []\n",
+ "\n",
+ "\n",
+ " for byte in a_byte_array:\n",
+ " binary_representation = bin(byte)\n",
+ " byte_list.append(binary_representation[9-n:])\n",
+ " #chop off the \"0b\" at the beginning. can also truncate the binary to fit on a device with N qubits\n",
+ " #binary has 2 extra digits for \"0b\", so it starts at 9 for our 7 bit operation. \n",
+ "\n",
+ " print(byte_list)\n",
+ " \n",
+ " circuit_array = []\n",
+ " \n",
+ " length = len(byte_list) \n",
+ " \n",
+ " for i in range(length):\n",
+ " \n",
+ " s = byte_list[i]\n",
+ "\n",
+ "\n",
+ " #do all this stuff for every letter\n",
+ "\n",
+ " # We need a circuit with n qubits, plus one ancilla qubit\n",
+ " # Also need n classical bits to write the output to\n",
+ " bv_circuit = QuantumCircuit(n+1, n)\n",
+ "\n",
+ " # put ancilla in state |->\n",
+ " bv_circuit.h(n)\n",
+ " bv_circuit.z(n)\n",
+ "\n",
+ " # Apply Hadamard gates before querying the oracle\n",
+ " for i in range(n):\n",
+ " bv_circuit.h(i)\n",
+ "\n",
+ " # Apply barrier \n",
+ " bv_circuit.barrier()\n",
+ "\n",
+ " # Apply the inner-product oracle\n",
+ " s = s[::-1] # reverse s to fit qiskit's qubit ordering\n",
+ " for q in range(n):\n",
+ " if s[q] == '0':\n",
+ " bv_circuit.i(q)\n",
+ " else:\n",
+ " bv_circuit.cx(q, n)\n",
+ "\n",
+ " # Apply barrier \n",
+ " bv_circuit.barrier()\n",
+ "\n",
+ " #Apply Hadamard gates after querying the oracle\n",
+ " for i in range(n):\n",
+ " bv_circuit.h(i)\n",
+ "\n",
+ " # Measurement\n",
+ " for i in range(n):\n",
+ " bv_circuit.measure(i, i)\n",
+ " \n",
+ " circuit_array.append(bv_circuit)\n",
+ "\n",
+ " \n",
+ " return circuit_array"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "['1010001', '1101001', '1110011', '1101011', '1101001', '1110100']\n"
+ ]
+ },
+ {
+ "data": {
+ "image/svg+xml": [
+ "\n",
+ "\n",
+ "\n"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 13,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "circuit_to_run = wordToBV('Qiskit')#Secret Msg\n",
+ "circuit_to_run[0].draw(output='mpl')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/svg+xml": [
+ "\n",
+ "\n",
+ "\n"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 14,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "backend = BasicAer.get_backend('qasm_simulator')\n",
+ "shots = 4096\n",
+ "results = execute(circuit_to_run[::-1], backend=backend, shots=shots).result()\n",
+ "answer = results.get_counts()\n",
+ "\n",
+ "plot_histogram(answer)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Steganographic encoder/decoder :"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "\n",
+ "\n",
+ "\n",
+ "def encrypt(BB84_key, letter):\n",
+ " \"\"\"Calculates XOR\"\"\"\n",
+ " b = int(BB84_key, 2)\n",
+ " x = ord(letter)\n",
+ " return format(b ^ x, \"b\")\n",
+ "\n",
+ "\n",
+ "def stega_encoder(LM, carrier_msg):\n",
+ " \"\"\"Encodes LM bits message into carrier_msg\"\"\"\n",
+ " message = \"\"\n",
+ " size = len(LM[0])\n",
+ " i = 0\n",
+ " for j, bitstring in enumerate(LM):\n",
+ " for k, digit in enumerate(bitstring):\n",
+ " while (not carrier_msg[i].isalpha()):\n",
+ " message += carrier_msg[i]\n",
+ " i += 1\n",
+ "\n",
+ " if digit == \"1\":\n",
+ " letter = carrier_msg[i].upper()\n",
+ " message += letter\n",
+ " else:\n",
+ " message += carrier_msg[i]\n",
+ "\n",
+ " i += 1\n",
+ " \n",
+ " if i < len(carrier_msg):\n",
+ " message += carrier_msg[i:]\n",
+ "\n",
+ " return message\n",
+ "\n",
+ "\n",
+ "def stega_decoder(new_carrier_msg, BB84_key):\n",
+ " \"\"\"Decodes secret message from new_carrier_msg\"\"\"\n",
+ "\n",
+ " b = int(BB84_key, 2)\n",
+ "\n",
+ " message = \"\"\n",
+ " bitstring = \"\"\n",
+ " for char in new_carrier_msg:\n",
+ " if char.isalpha():\n",
+ " if char.isupper():\n",
+ " bitstring += \"1\"\n",
+ " else:\n",
+ " bitstring += \"0\"\n",
+ "\n",
+ " if len(bitstring) == 7:\n",
+ " x = int(bitstring, 2)\n",
+ " message += chr(b ^ x)\n",
+ " bitstring = \"\"\n",
+ "\n",
+ " return message"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'1110000'"
+ ]
+ },
+ "execution_count": 16,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "encrypt(BB84_key,'q')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "secret_msg='q'\n",
+ "L=[]\n",
+ "for c in secret_msg:\n",
+ " L.append(encrypt(BB84_key,c))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "carrier_msg='aaaaaaa'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "new_carrier_msg=stega_encoder(L, carrier_msg)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'q'"
+ ]
+ },
+ "execution_count": 21,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "stega_decoder(new_carrier_msg, BB84_key)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.7.6"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/QPower/README.md b/QPower/README.md
new file mode 100644
index 0000000..c46b83c
--- /dev/null
+++ b/QPower/README.md
@@ -0,0 +1,19 @@
+# Quantum Steganography
+
+We are **Team QPower** and this project was made as part of IBM's Creative challenge at QC Hack 2021.
+
+
+## Project Idea
+
+We have implemented Quantum Steganography using qiskit in this project.
+
+The idea is to encode the sender's text(secret message) using the concept of interference. The secret message is encoded based on the cover file(a text sentence in this case). An interactive working implementation is available here: [https://qc-hacks.herokuapp.com/](https://qc-hacks.herokuapp.com/).
+
+We have chosen our cover file and the secret message to be in text formats to make it easier for new learners to understand the concept of quantum steganography while also trying it out interactively in a console.
+
+## Implementation Details
+
+The encoder circuit is based on 7 qubits but our interactive application has an option to create circuits based on the number of qubits selected and view them instantaneously.
+
+
+You can now play around with this tool and chat with your friends using **Quantum Steganography**. Isn't it cool?