0% found this document useful (0 votes)
36 views7 pages

Shor Medium

This document outlines the steps to apply Shor's algorithm to factor the number 15 and decrypt an encrypted code. It generates the quantum circuit, runs it on a simulator, analyzes the output to find factors of 15, and uses the factors to decrypt the code.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
36 views7 pages

Shor Medium

This document outlines the steps to apply Shor's algorithm to factor the number 15 and decrypt an encrypted code. It generates the quantum circuit, runs it on a simulator, analyzes the output to find factors of 15, and uses the factors to decrypt the code.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

shor_medium

March 10, 2024

0.1 https://medium.com/qiskit/applying-shors-algorithm-bbdfd6f05f7d
0.1.1 Shor’s Algorithm
Shor’s algorithm is quantum algorithm used to find the period of cyclic or periodic functions. By
representing a product of two prime numbers, called the coprime, as a periodic function using the
modulo operator, and converting this equation into a form that a quantum computer can process,
Shor’s algorithm can determine the period of that function. Interestingly, using the period of this
function, a quantum computer could factor the coprime number. Using a quantum computer to
factor the extremely large numbers used in RSA is decades away and will require an error-corrected
device with many qubits— but today, we can at least use it to factor very small coprimes…like 15.
You review and write out each step from the notes:
Pick an integer, a, such that 1 < a < N and gcd(a, N) = 1.

0.1.2 Find the period of f(x) = a^x (mod N), where x is the function’s period
This is when you connect to your quantum computer and begin your period-finding circuit.

0.1.3 Second, you see U gates applying a unitary operator, U(x) = a^x (mod N), on
the target qubits controlled by the measurement qubits, which in your case is
U(x) = a^x mod 15
Third, you perform an inverse quantum Fourier transform on the measurement qubits. Fourth,
you measure the measurement qubits to hopefully return an exponent, x, which satisfies f(x) = a^x
(mod N).
Finally, you assemble the circuit, run it, and return possible exponents for period finding.

0.2 Factoring N
Now, you sort through the possible exponents, finding those which satisfy two constraints:

1
the exponent, x, must be even and a^(x/2) + 1 � 0 (mo
Using an applicable period, x, you can find nontrivial factors, P and Q , of N with gcd(a^(x/2) ±
1, N) .
Decrypting 213 This is the moment you’ve been waiting for! Quickly, you use the factors P and Q
to restore the incomplete private key.d N)

[1]: # imports for RSA


from numpy import gcd
from numpy.random import seed, randint
# imports for Shor
from qiskit import QuantumCircuit, Aer, execute
from qiskit.visualization import plot_histogram
from qiskit.circuit.library import QFT

[2]: code = 213


N = 15
print(f"You know 3 things:\n\t1. a company is going to report high earnings,",␣
↪f"\n\t2. that company's encrypted stock listing is `{code}`, and", f"\n\t3.␣

↪the key's coprime, N, is {N}.")

You know 3 things:


1. a company is going to report high earnings,
2. that company's encrypted stock listing is `213`, and
3. the key's coprime, N, is 15.

[3]: def rsa(P, Q):


N = P * Q # modulus <-- the hard number to crack!

if N % 2 == 0:
val = P if P % 2 == 0 else Q
raise ValueError(f"{N} can not be divisible by 2.",
f"{P} and {Q} are incompatible with Shor's Algorithm.")

L = (Q - 1) * (P - 1) # number of non-common factors (1, N)

for E in range(2, L): # between [2, L)


if gcd(L, E) * gcd(N, E) == 1: # coprime with both L and N
break # E is public value

D = 1
while True:
if D * E % L == 1 and D != E and D != N:
break # D is private value
D += 1

return ((E, N), (D, N))

2
def dec(code, key):
D, N = key
return "".join([chr(((d**D) % N) + ord('A'))
for d in [int(d) for d in str(code)]])

[4]: P = Q = 0

print("Guesses:")
for i in range(0, 5, 2):
print(f"\t{i//2 + 1}. {dec(code, (i, N))}")

Guesses:
1. BBB
2. EBJ
3. BBG

[5]: N = 15

[6]: seed(1)

a = randint(2, N) # 1 < a < N

if gcd(a, N) == 1: # a shares no factors


print(f"{1} < {a} < {N}, {1 < a < N}")
else: # a shares a factor
P = gcd(a, N)
Q = N // gcd(a, N)
print(f"P = {P}\nQ = {Q}\n\n",
f"{P} x {Q} = {N}, {P * Q == N}\n")
print("You got lucky! You can skip to the Decypting 213 section, I guess.␣
↪�")

1 < 7 < 15, True

[7]: def initialize_qubits(qc, n, m):


qc.h(range(n)) # apply hadamard gates
qc.x(n+m-1) # set qubit to 1

[8]: print(f"Which in your case is\n\tU(x) = a^x mod {N}")


def a_x_mod15(a, x):
if a not in [2,7,8,11,13]:
raise ValueError("'a' must be 2,7,8,11 or 13")
U = QuantumCircuit(4)
for iteration in range(x):
if a in [2,13]:
U.swap(0,1)
U.swap(1,2)
U.swap(2,3)

3
if a in [7,8]:
U.swap(2,3)
U.swap(1,2)
U.swap(0,1)
if a == 11:
U.swap(1,3)
U.swap(0,2)
if a in [7,11,13]:
for q in range(4):
U.x(q)
U = U.to_gate()
U.name = f"U({x})"
c_U = U.control()
return c_U
def modular_exponentiation(qc, n, m, a):
for x in range(n):
exponent = 2**x
qc.append(a_x_mod15(a, exponent),
[x] + list(range(n, n+m)))

Which in your case is


U(x) = a^x mod 15

[9]: def apply_iqft(qc, measurement_qubits):


qc.append(QFT(len(measurement_qubits),
do_swaps=False).inverse(),
measurement_qubits)

[10]: def measure(qc, n):


qc.measure(n, n)

[11]: def period_finder(n, m, a):

# set up quantum circuit


qc = QuantumCircuit(n+m, n)

# initialize the qubits


initialize_qubits(qc, n, m)
qc.barrier()

# apply modular exponentiation


modular_exponentiation(qc, n, m, a)
qc.barrier()

# apply inverse QFT


apply_iqft(qc, range(n))
qc.barrier()

4
# measure the n measurement qubits
measure(qc, range(n))

return qc

[12]: n = 4; m = 4

qc = period_finder(n, m, a)
qc.draw(output='mpl')

C:\Users\Chaitanya\anaconda3\Lib\site-
packages\qiskit\visualization\circuit\matplotlib.py:266: FutureWarning: The
default matplotlib drawer scheme will be changed to "iqp" in a following
release. To silence this warning, specify the current default explicitly as
style="clifford", or the new default as style="iqp".
self._style, def_font_ratio = load_style(self._style)
[12]:

[13]: simulator = Aer.get_backend('qasm_simulator')


counts = execute(qc, backend=simulator).result().get_counts(qc)

plot_histogram(counts)

C:\Users\Chaitanya\AppData\Local\Temp\ipykernel_134132\2714375574.py:1:
DeprecationWarning: The 'qiskit.Aer' entry point is deprecated and will be
removed in Qiskit 1.0. You should use 'qiskit_aer.Aer' directly instead.

5
simulator = Aer.get_backend('qasm_simulator')
C:\Users\Chaitanya\AppData\Local\Temp\ipykernel_134132\2714375574.py:2:
DeprecationWarning: The function ``qiskit.execute_function.execute()`` is
deprecated as of qiskit 0.46.0. It will be removed in the Qiskit 1.0 release.
This function combines ``transpile`` and ``backend.run``, which is covered by
``Sampler`` :mod:`~qiskit.primitives`. Alternatively, you can also run
:func:`.transpile` followed by ``backend.run()``.
counts = execute(qc, backend=simulator).result().get_counts(qc)
[13]:

[14]: # convert and add binary periods to list


counts_dec = sorted([int(measured_value[::-1], 2)
for measured_value in counts])

print("Measured periods:", end='\t')


for measured_value in counts_dec:
print(measured_value, end='\t')

Measured periods: 0 4 5 6 7 8 9
10 11 12 13 14 15

[15]: factors = set()

6
for x in counts_dec:
guesses = [gcd(int((a ** (measured_value/2))) + 1, N),
gcd(int((a ** (measured_value/2))) - 1, N)]
for guess in guesses:
# ignore trivial factors
if guess != 1 and guess != N and N % guess == 0:
factors.add(guess)

if len(factors):
P = factors.pop()
Q = factors.pop() if len(factors) else N // P
print(f"P = {P}\nQ = {Q}\n\n",
f"{P} x {Q} = {N}, {P * Q == N}")
else:
print("Shor's Algorithm Failed. Choose a different 'a'.")

P = 3
Q = 5

3 x 5 = 15, True

[16]: _, priv_key = rsa(P, Q)


print("Using RSA and Shor's Algorithm,",
f"you determine the private key to be:\n\t{priv_key}")

Using RSA and Shor's Algorithm, you determine the private key to be:
(23, 15)

[17]: dec_str = dec(code, priv_key)


print(f"You learn that the decrypted listing is {dec_str}!")

You learn that the decrypted listing is IBM!

[ ]:

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy