Professional Documents
Culture Documents
Shor Medium
Shor Medium
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)
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.")
D = 1
while True:
if D * E % L == 1 and D != E and D != N:
break # D is private value
D += 1
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)
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)))
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]:
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]:
Measured periods: 0 4 5 6 7 8 9
10 11 12 13 14 15
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
Using RSA and Shor's Algorithm, you determine the private key to be:
(23, 15)
[ ]: