Path: blob/main/notebooks/ch-algorithms/shor.ipynb
3855 views
Shor's Algorithm
Shor’s algorithm is famous for factoring integers in polynomial time. Since the best-known classical algorithm requires superpolynomial time to factor the product of two primes, the widely used cryptosystem, RSA, relies on factoring being impossible for large enough integers.
In this chapter we will focus on the quantum part of Shor’s algorithm, which actually solves the problem of period finding. Since a factoring problem can be turned into a period finding problem in polynomial time, an efficient period finding algorithm can be used to factor integers efficiently too. For now its enough to show that if we can compute the period of efficiently, then we can also efficiently factor. Since period finding is a worthy problem in its own right, we will first solve this, then discuss how this can be used to factor in section 5.
1. The Problem: Period Finding
Let’s look at the periodic function:
Reminder: Modulo & Modular Arithmetic (Click here to expand)
The modulo operation (abbreviated to 'mod') simply means to find the remainder when dividing one number by another. For example:
Since with remainder . (i.e. ). In Python, the modulo operation is denoted through the % symbol.
This behaviour is used in modular arithmetic, where numbers 'wrap round' after reaching a certain value (the modulus). Using modular arithmetic, we could write:
Note that here the applies to the entire equation (since it is in parenthesis), unlike the equation above where it only applied to the left-hand side of the equation.
where and are positive integers, is less than , and they have no common factors. The period, or order (), is the smallest (non-zero) integer such that:
We can see an example of this function plotted on the graph below. Note that the lines between points are to help see the periodicity and do not represent the intermediate values between the x-markers.
2. The Solution
Shor’s solution was to use quantum phase estimation on the unitary operator:
To see how this is helpful, let’s work out what an eigenstate of U might look like. If we started in the state , we can see that each successive application of U will multiply the state of our register by , and after applications we will arrive at the state again. For example with and :
So a superposition of the states in this cycle () would be an eigenstate of :
Click to Expand: Example with $a = 3$ and $N=35$
This eigenstate has an eigenvalue of 1, which isn’t very interesting. A more interesting eigenstate could be one in which the phase is different for each of these computational basis states. Specifically, let’s look at the case in which the phase of the th state is proportional to :
Click to Expand: Example with $a = 3$ and $N=35$
(We can see appears in the denominator of the phase.)
This is a particularly interesting eigenvalue as it contains . In fact, has to be included to make sure the phase differences between the computational basis states are equal. This is not the only eigenstate with this behaviour; to generalise this further, we can multiply an integer, , to this phase difference, which will show up in our eigenvalue:
Click to Expand: Example with $a = 3$ and $N=35$
We now have a unique eigenstate for each integer value of where Very conveniently, if we sum up all these eigenstates, the different phases cancel out all computational basis states except :
Click to Expand: Example with $a = 7$ and $N=15$
For this, we will look at a smaller example where and . In this case :
Since the computational basis state is a superposition of these eigenstates, which means if we do QPE on using the state , we will measure a phase:
Where is a random integer between and . We finally use the continued fractions algorithm on to find . The circuit diagram looks like this (note that this diagram uses Qiskit's qubit ordering convention):
We will next demonstrate Shor’s algorithm using Qiskit’s simulators. For this demonstration we will provide the circuits for without explanation, but in section 4 we will discuss how circuits for can be constructed efficiently.
3. Qiskit Implementation
In this example we will solve the period finding problem for and . We provide the circuits for where:
without explanation. To create , we will simply repeat the circuit times. In the next section we will discuss a general method for creating these circuits efficiently. The function c_amod15 returns the controlled-U gate for a, repeated power times.
We will use 8 counting qubits:
We also import the circuit for the QFT (you can read more about the QFT in the quantum Fourier transform chapter):
With these building blocks we can easily construct the circuit for Shor's algorithm:
Let's see what results we measure:
Since we have 8 qubits, these results correspond to measured phases of:
We can now use the continued fractions algorithm to attempt to find and . Python has this functionality built in: We can use the fractions module to turn a float into a Fraction object, for example:
Because this gives fractions that return the result exactly (in this case, 0.6660000...), this can give gnarly results like the one above. We can use the .limit_denominator() method to get the fraction that most closely resembles our float, with denominator below a certain value:
Much nicer! The order (r) must be less than N, so we will set the maximum denominator to be 15:
We can see that two of the measured eigenvalues provided us with the correct result: , and we can see that Shor’s algorithm has a chance of failing. These bad results are because , or because and are not coprime and instead of we are given a factor of . The easiest solution to this is to simply repeat the experiment until we get a satisfying result for .
Quick Exercise
Modify the circuit above for values of and . What results do you get and why?
4. Modular Exponentiation
You may have noticed that the method of creating the gates by repeating grows exponentially with and will not result in a polynomial time algorithm. We want a way to create the operator:
that grows polynomially with . Fortunately, calculating:
efficiently is possible. Classical computers can use an algorithm known as repeated squaring to calculate an exponential. In our case, since we are only dealing with exponentials of the form , the repeated squaring algorithm becomes very simple:
If an efficient algorithm is possible in Python, then we can use the same algorithm on a quantum computer. Unfortunately, despite scaling polynomially with , modular exponentiation circuits are not straightforward and are the bottleneck in Shor’s algorithm. A beginner-friendly implementation can be found in reference [1].
5. Factoring from Period Finding
Not all factoring problems are difficult; we can spot an even number instantly and know that one of its factors is 2. In fact, there are specific criteria for choosing numbers that are difficult to factor, but the basic idea is to choose the product of two large prime numbers.
A general factoring algorithm will first check to see if there is a shortcut to factoring the integer (is the number even? Is the number of the form ?), before using Shor’s period finding for the worst-case scenario. Since we aim to focus on the quantum part of the algorithm, we will jump straight to the case in which N is the product of two primes.
Example: Factoring 15
To see an example of factoring on a small number of qubits, we will factor 15, which we all know is the product of the not-so-large prime numbers 3 and 5.
The first step is to choose a random number, , between and :
Next we quickly check it isn't already a non-trivial factor of :
Great. Next, we do Shor's order finding algorithm for a = 7 and N = 15. Remember that the phase we measure will be where:
and is a random integer between 0 and .
From this phase, we can easily find a guess for :
Now we have , we might be able to use this to find a factor of . Since:
then:
which means must divide . And if is also even, then we can write:
(if is not even, we cannot go further and must try again with a different value for ). There is then a high probability that the greatest common divisor of and either , or is a proper factor of [2]:
The cell below repeats the algorithm until at least one factor of 15 is found. You should try re-running the cell a few times to see how it behaves.
6. References
Stephane Beauregard, Circuit for Shor's algorithm using 2n+3 qubits, arXiv:quant-ph/0205095
M. Nielsen and I. Chuang, Quantum Computation and Quantum Information, Cambridge Series on Information and the Natural Sciences (Cambridge University Press, Cambridge, 2000). (Page 633)