# How to factor 2048 bit RSA integers with less than a million noisy qubits
Source: https://arxiv.org/html/2505.15917v1
Kiwi News: https://news.kiwistand.com/stories/How-to-factor-2048-bit-RSA-integers-with-less-than-a-million-noisy-qubits?index=0x68335606e179406b6b777570cd21ad2e9ba664495e7190b49cdbc013f5a293629ff01b99
Submitted by misha on 2025-05-25 UTC, 1 upvote, 1 comment
## Summary
Craig Gidney estimates that a 2048 bit RSA integer could be factored in less than a week by a quantum computer with less than a million noisy qubits, down from the roughly 20 million qubits his 2019 co-authored estimate required. He attributes the qubit reduction mainly to approximate residue arithmetic from Chevignard, Fouque and Schrottenloher (2024), to yoked surface codes, and to magic state cultivation. The longer runtime comes mainly from more Toffoli gates and fewer magic state factories, though the paper reports a Toffoli count over 100 times lower than Chevignard, Fouque and Schrottenloher's 2024 method. The estimates assume a square grid of qubits, a 0.1% gate error rate, and a 1 microsecond surface code cycle time.
## Article
Craig Gidney
August 24, 2026
Abstract
Planning the transition to quantum-safe cryptosystems requires understanding the cost of quantum attacks on vulnerable cryptosystems. In Gidney+Ekerå 2019, I co-published an estimate stating that 2048 bit RSA integers could be factored in eight hours by a quantum computer with 20 million noisy qubits. In this paper, I substantially reduce the number of qubits required. I estimate that a 2048 bit RSA integer could be factored in less than a week by a quantum computer with less than a million noisy qubits. I make the same assumptions as in 2019: a square grid of qubits with nearest neighbor connections, a uniform gate error rate of 0.1%0.1\%, a surface code cycle time of 1 microsecond, and a control system reaction time of 1010 microseconds.
The qubit count reduction comes mainly from using approximate residue arithmetic (Chevignard+Fouque+Schrottenloher 2024), from storing idle logical qubits with yoked surface codes (Gidney+Newman+Brooks+Jones 2023), and from allocating less space to magic state distillation by using magic state cultivation (Gidney+Shutty+Jones 2024). The longer runtime is mainly due to performing more Toffoli gates and using fewer magic state factories compared to Gidney+Ekerå 2019. That said, I reduce the Toffoli count by over 100x compared to Chevignard+Fouque+Schrottenloher 2024.
Data availability: Code and assets created for this paper are available on Zenodo [Gid25].
1 Introduction
2 Methods
2.1 Approximate Residue Arithmetic
2.2 Approximate Period Finding
2.3 Ekerå-Håstad Period Finding
2.4 Arithmetic Optimizations
3 Results
3.1 Logical Costs
3.2 Physical Costs
4 Conclusion
5 Acknowledgments
References
A Detailed Mock-ups
A.1 Reference Python Implementation of Algorithm
A.2 Addition Operation
A.3 Phaseup Operation
A.4 Lookup Operation
A.5 Frequency Basis Measurement
Figure 1: Historical estimates, with comparable physical assumptions, of the physical qubit cost of factoring 2048 bit RSA integers. Includes overheads from fault tolerance, routing, and distillation. Results are from [Jon+12, Fow+12, OC17, GM19, GE21]. Results such as [Van+10] and [LN22] aren’t included because they target substantially different assumptions or cost models.
Figure 2: Pareto frontiers achieved by this paper for the Toffoli and logical qubit cost of factoring nn bit RSA integers, for various values of nn. This paper uses notably fewer logical qubits than [GE21] (points labeled “GE21”) and notably fewer Toffolis than [CFS24] (points labeled “CFS24”).
1 Introduction
In 1994, Peter Shor published a paper showing quantum computers could efficiently factor integers [Sho94], meaning the RSA cryptosystem [RSA78] wasn’t secure against quantum computers. Understanding the cost of quantum factoring is important for planning and coordinating the transition away from RSA, and other cryptosystems vulnerable to quantum computers. Correspondingly, since Shor’s paper, substantial effort has gone into understanding the cost of quantum factoring [Kni95, Bec+96, VBE96, Zal98, CW, Bea03, Zal06, Whi+09, Van+10, Fow+12, Jon+12, PG14, Eke16, HRS16, Gid17, OC17, GM19, Eke19, Eke21, GE21, LN22, MS22, Reg24, CFS24] (and more). A key metric is the number of qubits used by the algorithm, since this bounds the required size of quantum computer.
Historically, there was no known way to factor an nn bit number using fewer than 1.5n1.5n logical qubits [Zal06, Bea03, HRS16, Gid17]. Anecdotally, it was widely assumed that nn was the minimum possible because doing arithmetic modulo an nn bit number “required” an nn qubit register. May and Schlieper had shown in 2019 that in principle only a single output qubit was needed [MS22], but there was no known way to prepare a relevant output that didn’t involve intermediate values spanning nn qubits. In 2024, Chevignard and Fouque and Schrottenloher (CFS) solved this problem [CFS24]. They found a way to compute approximate modular exponentiations using only small intermediate values, destroying the anecdotal nn qubit arithmetic bottleneck. However, their method is incompatible with “qubit recycling” [PP00, ME99], reviving an old bottleneck on the number of input qubits. Shor’s original algorithm used 2n2n input qubits [Sho94], but Ekerå and Håstad proved in 2017 that (0.5+ϵ)n(0.5+\epsilon)n input qubits was sufficient for RSA integers [EH17]. So, by combining May et al’s result with Ekerå et al’s result, the CFS algorithm can factor nn bit RSA integers using only (0.5+ϵ)n(0.5+\epsilon)n logical qubits [CFS24].
A notable downside of [CFS24] was its gate count. In [GE21], it was estimated that a 2048 bit RSA integer could be factored using 3 billion Toffoli gates and a bit more than 3n3n logical qubits. Whereas [CFS24] uses 2 trillion Toffoli gates and a bit more than 0.5n0.5n logical qubits. So [CFS24] is paying roughly 1000x more Toffolis for a 6x reduction in space. This is a strikingly inefficient spacetime trade-off. However, as I’ll show in this paper, the trade-off can be made orders of magnitude more forgiving. In addition to optimizing the Toffoli count of the algorithm, I’ll provide a physical cost estimate showing it should be possible to factor 2048 bit RSA integers in less than a week using less than a million physical qubits (under the assumptions mentioned in the abstract).
The paper is structured as follows. In Section 2, I describe a streamlined version of the CFS algorithm. In Section 3, I estimate its cost. I first estimate Toffoli counts and logical qubit counts, and then convert these into physical qubit cost estimates accounting for the overhead of fault tolerance. Finally, in Section 4, I summarize my results. The paper also includes Appendix A, which shows more detailed mock-ups of the algorithm and its physical implementation.
2 Methods
Table 1: Various bits of mostly-Python-inspired notation used in this paper.
In this section, I present a variation of the CFS algorithm. The underlying ideas are the same, but many of the details are different. For example, I use fewer intermediate values and I extract the most significant bits of the result rather than the least significant bits.
Beware that, as in [GE21], for simplicity, I will describe everything in terms of period finding against f(e)=gemodNf(e)=g^{e}\bmod N (as in Shor’s original algorithm) despite actually intending to use Ekerå-Håstad-style period finding [EH17]. Ultimately everything decomposes into a series of quantum controlled multiplications, which fundamentally is what is actually being optimized, so what I describe will trivially translate.
2.1 Approximate Residue Arithmetic
Consider an integer LL equal to the product of many ℓ\ell-bit primes from a set PP:
L=∏p∈PpL=\prod_{p\in P}p (1)
∀p∈P:(len p=ℓ)∧IsPrime(p)\forall p\in P:(\text{len }p=\ell)\land\text{IsPrime(p)} (2)
A simple way to do arithmetic on a value modulo LL is to store the value as a 2s complement integer in a len L\text{len }L bit register, and when operating on this register add or subtract multiples of LL as appropriate to keep it in the range [0,L)[0,L). This requires Ω(logL)\Omega(\log L) bits of storage.
Residue arithmetic performs addition and multiplication modulo LL by separately performing the operations modulo each of the primes from PP. The final result can then be recovered using the Chinese remainder theorem. By the prime number theorem, PP can be chosen so that the bit length of primes in PP is ℓ=Θ(loglogL)\ell=\Theta(\log\log L). Therefore, using residue arithmetic introduces the possibility of arithmetic being exponentially more space efficient:
|P|=Θ(logLloglogL)|P|=\Theta\left(\frac{\log L}{\log\log L}\right) (3)
ℓ=Θ(loglogL)\ell=\Theta(\log\log L) (4)
In the context of Shor’s algorithm, the key operation we want to compute is a modular exponentiation V=gemodNV=g^{e}\bmod N. Here gg is a randomly chosen classical constant in [2,N)[2,N), ee is a uniformly superposed m=O(logN)m=O(\log N) qubit integer, and NN is the number to factor. The computation of VV can be decomposed into a series of multiplications controlled by the qubits of ee:
V=gemodN=(∏k=0m−1Mkek)modNV=g^{e}\bmod N=\left(\prod_{k=0}^{m-1}M_{k}^{e_{k}}\right)\bmod N (5)
m=O(logN)m=O(\log N) (6)
In the above equation, eke_{k} is the qubit at little-endian offset kk within the register ee and MkM_{k} is the classically precomputed constant
Mk=g(2k)modNM_{k}=g^{(2^{k})}\bmod N (7)
Because the factors of NN aren’t known, and because in practice those factors would be large, it’s not viable to perform residue arithmetic modulo NN. However, performing the arithmetic modulo any other modulus L≠NL\neq N creates an issue. If the accumulating product exceeds LL, then the register will wrap around. This shifts its value by a multiple of LL and, since LmodN≠0L\bmod N\neq 0, this offsets the tracked value relative to the true result mod NN. The following multiplications would then amplify this error out of control, ruining the computation. I fix this in a simple way, the same way Chevignard et al fix it, by picking LL to be larger than the largest possible product. This guarantees the wraparound issue never occurs:
With this promise about the size of LL, we can rewrite the computation of VV to use residue arithmetic. Instead of computing the product directly, we can compute it using a dot product between each residue rjr_{j} (the product modulo a prime from LL) and its contribution factor uju_{j} (the smallest positive integer satisfying ujmodpi=δi,ju_{j}\bmod p_{i}=\delta_{i,j}):
rj=(∏k=0m−1Mkek)modpjr_{j}=\left(\prod_{k=0}^{m-1}M_{k}^{e_{k}}\right)\bmod p_{j} (9)
uj=(L/pj)⋅MultiplicativeInversepj(L/pj)u_{j}=(L/p_{j})\cdot\text{MultiplicativeInverse}_{p_{j}}(L/p_{j}) (10)
V\displaystyle V =(∏k=0m−1Mkek)modLmodN\displaystyle=\left(\prod_{k=0}^{m-1}M_{k}^{e_{k}}\right)\bmod L\bmod N (11)
=(∑j=0|P|−1rjuj)modLmodN\displaystyle=\left(\sum_{j=0}^{|P|-1}r_{j}u_{j}\right)\bmod L\bmod N
To simplify later steps, I decompose rjr_{j} into its ℓ\ell bits rj,kr_{j,k}, and write VV in those terms:
rj=∑k=0ℓ−1rj,k≪kr_{j}=\sum_{k=0}^{\ell-1}r_{j,k}\ll k (12)
V=(∑j=0|P|−1∑k=0ℓ−1rj,k[uj≪k])modLmodNV=\left(\sum_{j=0}^{|P|-1}\sum_{k=0}^{\ell-1}r_{j,k}\Big[u_{j}\ll k\Big]\right)\bmod L\bmod N (13)
The computation of VV is now a sum modulo LL then modulo NN, instead of a product modulo NN. Crucially, this fixes the issue where errors early in the process would be amplified by later operations. As a result, we’re in a position to start using approximations.
Our goal now is to use approximations to extract the most significant bits of VV, without computing the entirety of VV. To quantify the error in these approximations, we’ll track its “modular deviation” ΔN(a−b)\Delta_{N}(a-b). The modular deviation is the minimum number of increments or decrements needed to turn aa into bb modulo NN, divided by NN:
ΔN(a−b)=min((a−b)modN,(b−a)modN)N\Delta_{N}(a-b)=\frac{\min((a-b)\bmod N,(b-a)\bmod N)}{N} (14)
To approximate additions modulo NN, we’ll truncate all values down to ff bits. When asked to add an offset ss into an accumulator, we’ll instead add (smodN)≫t(s\bmod N)\gg t where t=len N−ft=\text{len }N-f. The accumulator will be truncated to ff bits, and will be operated modulo N≫tN\gg t instead of modulo NN. At any time, the approximate result can be extracted by left shifting the accumulator’s value by tt.
Truncating introduces two sources of error. First, during additions, carries that would have propagated out of the removed part of the register into the kept part of the register will no longer happen. Second, the accumulating additions wrap around slightly too quickly due to (N≫t)≪t(N\gg t)\ll t being less than NN. For an individual truncated addition, both of these errors offset the approximate result by an amount O(2t)O(2^{t}), which is a modular deviation of O(2−f)O(2^{-f}). So the modular deviation is exponentially small in the number of kept bits, and will accumulate linearly with the number of operations, meaning a series of AA truncated additions has a modular deviation of at most O(A⋅2−f)O(A\cdot 2^{-f}):
t=(len N)−ft=(\text{len }N)-f (15)
S\displaystyle S =(∑k=0A−1sk)modN\displaystyle=\left(\sum_{k=0}^{A-1}s_{k}\right)\bmod N (16)
S~\displaystyle\widetilde{S} =(∑k=0A−1(skmodN)≫t)mod(N≫t)\displaystyle=\left(\sum_{k=0}^{A-1}(s_{k}\bmod N)\gg t\right)\bmod(N\gg t)
ΔN(S−(S~≪t))\displaystyle\Delta_{N}(S-(\tilde{S}\ll t)) ≤O(A⋅2−f)\displaystyle\leq O(A\cdot 2^{-f})
This kind of approximated accumulation isn’t quite directly applicable to the current expression for VV. The issue is that VV isn’t being accumulated modulo NN, it’s being accumulated modulo LL and only at the end is the modulo NN performed. If we were to accumulate only modulo NN, instead of modulo LL then modulo NN, then each time the accumulator would have wrapped modulo LL we’d miss an offset of LmodNL\bmod N. However, LL is the product of the primes in our residue system, and we get to choose these primes, so we can pull a trick. We can optimize LL such that LmodNL\bmod N has negligible modular deviation.
Numerically, it seems to be the case that picking random sets of small primes results in values of LmodNL\bmod N uniformly distributed over the range [1,N)[1,N). In cases I’ve tested, I’m consistently able to find an LL with deviation below 2−f2^{-f} with high probability by randomly sampling O(2f)O(2^{f}) sets of small primes. I conjecture this is true in general (see Assumption 1). I’ll show later in Equation 23 that the required value of ff grows logarithmically with the problem size len N\text{len }N. Assuming the conjecture and the promise that ff will grow like O(loglogN)O(\log\log N), an LL with sufficiently small deviation can be found in polynomial time:
ΔN(L)<2−f(by brute force random search for a satisfying P)\Delta_{N}(L)<2^{-f}\;\;\;\;\text{(by brute force random search for a satisfying $P$)} (17)
Assumption 1 (random search for small modular deviations is efficient): A set PP of small primes satisfying (∏P)≥Nm(\prod P)\geq N^{m} and ΔN(∏P)<2−f\Delta_{N}(\prod P)<2^{-f} can be found in O(2f⋅poly(m⋅len N))O(2^{f}\cdot\text{poly}(m\cdot\text{len }N)) expected time by randomly varying the primes included in PP.
As an example, here’s a set of 25000 primes I found in ten seconds using a 128 core machine. Each prime is 22 bits long, and the set achieves a modular deviation below 2−322^{-32} versus the RSA2048 challenge number [Wik24]:
P1\displaystyle P_{1} =PrimesBetween(3814620,222)\displaystyle=\text{PrimesBetween}(3814620,2^{22}) (18)
P2\displaystyle P_{2} ={2097769,3484783,3814501,3814543,3814561,3814583,3814609}\displaystyle=\{2097769,3484783,3814501,3814543,3814561,3814583,3814609\}
L\displaystyle L =∏(P1∪P2)\displaystyle=\prod(P_{1}\cup P_{2})
N\displaystyle N =RSA2048\displaystyle=\text{RSA}_{2048}
ΔN(L)\displaystyle\Delta_{N}(L) <2−32\displaystyle<2^{-32}
Given the promise that the modular deviation of the wraparound error is at most 2−f2^{-f}, we can generalize Equation 16 from approximating arithmetic modulo NN to approximating arithmetic modulo LL then modulo NN:
S\displaystyle S =(∑k=0A−1sk)modLmodN\displaystyle=\left(\sum_{k=0}^{A-1}s_{k}\right)\bmod L\bmod N (19)
S~\displaystyle\widetilde{S} =(∑k=0A−1(skmodLmodN)≫t)mod(N≫t)\displaystyle=\left(\sum_{k=0}^{A-1}(s_{k}\bmod L\bmod N)\gg t\right)\bmod(N\gg t)
ΔN(S−(S~≪t))\displaystyle\Delta_{N}(S-(\tilde{S}\ll t)) ≤O(A⋅2−f+A⋅ΔN(L))\displaystyle\leq O(A\cdot 2^{-f}+A\cdot\Delta_{N}(L))
≤O(A⋅2−f)\displaystyle\leq O(A\cdot 2^{-f})
We can now apply Equation 19 to Equation 13, producing an expression for V~≈V≫t\widetilde{V}\approx V\gg t:
V~\displaystyle\widetilde{V} =(∑j=0|P|−1∑k=0ℓ−1rj,k([(uj≪k)modLmodN]≫t))mod(N≫t)\displaystyle=\left(\sum_{j=0}^{|P|-1}\sum_{k=0}^{\ell-1}r_{j,k}\left(\Big[(u_{j}\ll k)\bmod L\bmod N\Big]\gg t\right)\right)\bmod(N\gg t) (20)
=(∑j=0|P|−1∑k=0ℓ−1rj,kCj,k)mod(N≫t)\displaystyle=\left(\sum_{j=0}^{|P|-1}\sum_{k=0}^{\ell-1}r_{j,k}C_{j,k}\right)\bmod(N\gg t)
So, by using truncated residue arithmetic, the modular exponentiation has been approximated into an ff-bit dot product between the bits of the residues and a table of classically precomputable constants Cj,kC_{j,k}:
Cj,k=([(uj≪k)modLmodN]≫t)mod(N≫t)C_{j,k}=\left(\Big[(u_{j}\ll k)\bmod L\bmod N\Big]\gg t\right)\bmod(N\gg t) (21)
The computation of V~\widetilde{V} incurs O(2−f)O(2^{-f}) modular deviation per truncated addition, and there are |P|⋅ℓ|P|\cdot\ell additions, so the total modular deviation of V~\widetilde{V} is at most
ΔN(V−(V~≪t))≤O(|P|⋅ℓ⋅2−f)\Delta_{N}(V-(\widetilde{V}\ll t))\leq O(|P|\cdot\ell\cdot 2^{-f}) (22)
It will be clear from the next subsection that, in order for period finding to work, it’s sufficient to achieve a constant total modular deviation (e.g. a modular deviation of 10%). Solving for ff in |P|⋅ℓ⋅2−f=O(1)|P|\cdot\ell\cdot 2^{-f}=O(1) after expanding terms using Equation 3, Equation 4, Equation 6, and Equation 8 gives a bound on the size of ff:
f=O(loglogN)f=O(\log\log N) (23)
See Figure 3 for working Python code that computes V~≈gemodN\widetilde{V}\approx g^{e}\bmod N using this method.
Figure 3: Example Python code that approximates V~≈gemodN\widetilde{V}\approx g^{e}\bmod N given a choice of PP and ff. Registers that would store quantum values during the quantum factoring are prefixed with “Q_”. All would-be-quantum registers are of size O(loglogN)O(\log\log N), except the input register Q_e. For simplicity, this code omits optimizations (like windowing) and crucial quantum details (like uncomputation). See Appendix A.1 for more detailed code.
import math
def approximate_modular_exponentiation(
g: int,
Q_e: int,
N: int,
P: list[int],
f: int,
) -> int:
"""Computes␣an␣approximate␣modular␣exponentiation.
␣␣␣␣Args:
␣␣␣␣␣␣␣␣g:␣The␣base␣of␣the␣exponentiation.
␣␣␣␣␣␣␣␣Q_e:␣The␣exponent.
␣␣␣␣␣␣␣␣N:␣The␣modulus.
␣␣␣␣␣␣␣␣P:␣Small␣primes␣for␣the␣residue␣arithmetic.
␣␣␣␣␣␣␣␣f:␣Kept␣bits␣during␣approximate␣accumulation.
␣␣␣␣Returns:
␣␣␣␣␣␣␣␣An␣approximation␣of␣pow(g,␣Q_e,␣N).
␣␣␣␣␣␣␣␣The␣modular␣deviation␣of␣the␣approximation␣is
␣␣␣␣␣␣␣␣at␣most␣3␣*␣Q_e.bit_length()␣/␣2**f␣.
␣␣␣␣"""
L = math.prod(P)
ell = max(p.bit_length() for p in P)
m = Q_e.bit_length()
t = N.bit_length() - f
assert L == math.lcm(*P) and L >= N ** m and (L % N) < (N >> f)
Q_total = 0
for p in P:
Q_residue = 1
for k in range(Q_e.bit_length()):
precomputed = pow(g, 1 << k, N) % p
if Q_e & (1 << k):
Q_residue *= precomputed
Q_residue %= p
u = (L // p) * pow(L // p, -1, p)
for k in range(ell):
precomputed = (((u << k) % L % N) >> t) % (N >> t)
if Q_residue & (1 << k):
Q_total += precomputed
Q_total %= N >> t
return Q_total << t
def test_approximate_modular_exponentiation():
import random
import sympy
N = int(
"15226050279225333605356183781326374297180681149613"
"80688657908494580122963258952897654000350692006139"
)
g = random.randrange(2, N)
Q_e = random.randrange(2**100)
P = [
*sympy.primerange(239382, 2**18),
131101,
131111,
131113,
131129,
131143,
131149,
131947,
182341,
239333,
239347,
]
f = 24
result = approximate_modular_exponentiation(g, Q_e, N, P, f)
error = result - pow(g, Q_e, N)
deviation = min(error % N, -error % N) / N
ell = max(p.bit_length() for p in P)
assert deviation <= 3 * len(P) * ell / 2**f
2.2 Approximate Period Finding
Shor’s algorithm, as usually described, performs period finding against a periodic function f(x)f(x). It relies crucially on the fact that f(x)f(x) is exactly periodic, with f(x+P)=f(x)f(x+P)=f(x) for all values of xx. In this paper I’m computing an approximation f~≈f\widetilde{f}\approx f, so I can only guarantee approximate periodicity:
∀x,y∈ℤ:ΔN(f~(x+yP)−f~(x))≤ϵ.\forall x,y\in\mathbb{Z}:\Delta_{N}\left(\widetilde{f}(x+yP)-\widetilde{f}(x)\right)\leq\epsilon. (24)
Exact period finding will fail if used on a function that only guarantees approximate periodicity, because the error in the approximation can make the function aperiodic. To fix this, we must avoid measuring the error. For example, instead of measuring the entire output of f~(x)\widetilde{f}(x) you could measure a truncated output f~(x)//(100Nϵ)\widetilde{f}(x)//(100N\epsilon). This could work, but causes two problems. The first problem is that truncating the output means more inputs will be consistent with it. This will cause the system to collapse to a large superposition of periodic signals, instead of a simple periodic signal. I’ll address this by analyzing the behavior of period finding against superpositions of periodic signals, as was done in [MS22]. The second problem with truncating the output is that the parts of the output that aren’t measured would need to be uncomputed, by running the modular exponentiation process backwards. The modular exponentiation is already the most expensive part of the algorithm, so this would double the execution costs. I’ll address this by using superposition masking.
Superposition masking uses sacrificial superpositions to control the information that can enter into a register or be revealed by measurements [Zal06, Gid19, JG20]. In the present context, we want to avoid learning the low bits of f~(x)\widetilde{f}(x). We can achieve this by measuring f~(x)+s\widetilde{f}(x)+s instead of f~(x)\widetilde{f}(x), where ss is a uniform superposition over a contiguous range [0,⌈SN⌉)[0,\lceil SN\rceil). I’ll address the value of SS later; for now note that larger values of SS will suppress error from the approximation but reduce the amount of information remaining for period finding.
Because f~(x)\widetilde{f}(x) happens to be computed with a series of additions into an output register, it’s possible to compute and measure f~(x)+s\widetilde{f}(x)+s without needing to then uncompute f~(x)\widetilde{f}(x) or ss. This is done by initializing the output register to ss (instead of 0), then adding the approximation f~(x)\widetilde{f}(x) into the output register, and then measuring the entire output register. To understand this process in detail, let’s analyze the states that occur as the algorithm progresses.
At the beginning of the algorithm, the output register is storing a uniform superposition (the mask). There is also the input register: an mm qubit register storing its own uniform superposition. Together these two registers form the initial state |ψ0⟩|\psi_{0}\rangle:
|ψ0⟩\displaystyle|\psi_{0}\rangle =|0:2m:1⟩⊗|0:⌈SN⌉:1⟩\displaystyle=|0:2^{m}:1\rangle\otimes|0:\lceil SN\rceil:1\rangle (25)
=12m⌈SN⌉∑e=02m−1∑s=0⌈SN⌉−1|e⟩⊗|s⟩\displaystyle=\frac{1}{\sqrt{2^{m}\lceil SN\rceil}}\sum_{e=0}^{2^{m}-1}\sum_{s=0}^{\lceil SN\rceil-1}|e\rangle\otimes|s\rangle
The algorithm now adds the approximation f~(e)\widetilde{f}(e) into the output register, modulo NN, forming the actual pre-measurement state |ψ1~⟩|\widetilde{\psi_{1}}\rangle:
|ψ1~⟩\displaystyle|\widetilde{\psi_{1}}\rangle =1⌈SN⌉2m∑e=02m−1∑s=0⌈SN⌉−1|e⟩⊗|(s+f~(e))modN⟩\displaystyle=\frac{1}{\sqrt{\lceil SN\rceil 2^{m}}}\sum_{e=0}^{2^{m}-1}\sum_{s=0}^{\lceil SN\rceil-1}|e\rangle\otimes|(s+\widetilde{f}(e))\bmod N\rangle (26)
If we had used ff instead of f~\widetilde{f}, we would have produced the ideal pre-measurement state |ψ1⟩|\psi_{1}\rangle:
|ψ1⟩\displaystyle|\psi_{1}\rangle =1⌈SN⌉2m∑e=02m−1∑s=0⌈SN⌉−1|e⟩⊗|(s+f(e))modN⟩\displaystyle=\frac{1}{\sqrt{\lceil SN\rceil 2^{m}}}\sum_{e=0}^{2^{m}-1}\sum_{s=0}^{\lceil SN\rceil-1}|e\rangle\otimes|(s+f(e))\bmod N\rangle (27)
Consider the infidelity 1−|⟨ψ1|ψ1~⟩|21-|\langle\psi_{1}|\widetilde{\psi_{1}}\rangle|^{2}. For each possible computational basis value ee of the input register, conditioning |ψ1~⟩|\widetilde{\psi_{1}}\rangle and |ψ1⟩|\psi_{1}\rangle on the input register storing ee produces a uniform superposition in the output register covering ⌈SN⌉\lceil SN\rceil contiguous values. If the maximum modular deviation of f~\widetilde{f} is ϵ\epsilon, then the conditioned ranges in |ψ1~⟩|\widetilde{\psi_{1}}\rangle are offset from the conditioned ranges in |ψ1⟩|\psi_{1}\rangle by at most NϵN\epsilon. The width of the ranges is at least S/ϵS/\epsilon times wider than the offset from the deviation. Therefore the infidelity between the two conditioned states is a most ϵ/S\epsilon/S. But this is true for every condition, and so also bounds the total infidelity between the two states:
1−|⟨ψ1|ψ1~⟩|2≤ϵ/S1-|\langle\psi_{1}|\widetilde{\psi_{1}}\rangle|^{2}\leq\epsilon/S (28)
We can treat this infidelity as contributing a chance of the algorithm failing, and thereby continue the analysis assuming we are working with the ideal state |ψ1⟩|\psi_{1}\rangle instead of the actual state |ψ1~⟩|\widetilde{\psi_{1}}\rangle. For example, if we set S=1000ϵS=1000\epsilon then |ψ1~⟩|\widetilde{\psi_{1}}\rangle would have 99.9% overlap with |ψ1⟩|\psi_{1}\rangle and so any success rate analysis we did with |ψ1⟩|\psi_{1}\rangle would produce a result within 0.1% of the true success rate.
The next step in the algorithm, which we’ll analyze with |ψ1⟩|\psi_{1}\rangle instead of |ψ1~⟩|\widetilde{\psi_{1}}\rangle, is to measure the output register. This produces some measurement result VV, and collapses the system into the post-measurement state |ψ2⟩|\psi_{2}\rangle. This state is a superposition of all the exponents whose masked output ranges overlapped with VV:
|ψ2⟩\displaystyle|\psi_{2}\rangle ∝∑e=02m−1|e⟩⋅int(0≤(V−f(e))modN<⌈NS⌉)\displaystyle\propto\sum_{e=0}^{2^{m}-1}|e\rangle\cdot\text{int}\left(0\leq(V-f(e))\bmod N<\lceil NS\rceil\right) (29)
Let PP be the period of ff, and let RR be the set of exponents less than PP that are consistent with the measured value VV. We can rewrite |ψ2⟩|\psi_{2}\rangle in these terms:
R={e∈ℕ|e
0k>0.
The sum over values of RR can be pushed rightward, so that it just counts how many values of RR are compatible with a choice of (r1,r2)(r_{1},r_{2}). When r1=r2r_{1}=r_{2}, there are (P−1w−1)\binom{P-1}{w-1} values of RR that satisfy r1∈R∧r2∈Rr_{1}\in R\land r_{2}\in R. When r1≠r2r_{1}\neq r_{2}, there are (P−2w−2)\binom{P-2}{w-2} satisfying values. This replaces the sum over values of RR with a choice of multiplier determined by r1=?r2r_{1}\stackrel{{\scriptstyle?}}{{=}}r_{2}:
E(|Bk>0|2)\displaystyle E(|B_{k>0}|^{2}) =1(Pw)wP∑r1=0P−1∑r2=0P−1eikr12π/Pe−ikr22π/P(∑R∈𝒫([0,P))|R|=wint(r1∈R∧r2∈R))\displaystyle=\frac{1}{\binom{P}{w}wP}\sum_{r_{1}=0}^{P-1}\sum_{r_{2}=0}^{P-1}e^{ikr_{1}2\pi/P}e^{-ikr_{2}2\pi/P}\left(\sum_{\begin{subarray}{c}R\in\mathcal{P}([0,P))\\ |R|=w\end{subarray}}\text{int}(r_{1}\in R\land r_{2}\in R)\right) (39)
=1(Pw)wP∑r1=0P−1∑r2=0P−1eir1k2π/Pe−ir2k2π/P{r1=r2→(P−1w−1)r1≠r2→(P−2w−2)\displaystyle=\frac{1}{\binom{P}{w}wP}\sum_{r_{1}=0}^{P-1}\sum_{r_{2}=0}^{P-1}e^{ir_{1}k2\pi/P}e^{-ir_{2}k2\pi/P}\begin{cases}r_{1}=r_{2}&\rightarrow\binom{P-1}{w-1}\\ r_{1}\neq r_{2}&\rightarrow\binom{P-2}{w-2}\end{cases}
Note that, for non-zero values of kk, the nested sum in the above equation would evaluate to 0 if the right side multiplier was replaced by a constant:
00|2)\displaystyle E(|B_{k>0}|^{2}) =(Pw)−11wP∑r=0P−1eirk2π/Pe−irk2π/P((P−1w−1)−(P−2w−2))\displaystyle=\binom{P}{w}^{-1}\frac{1}{wP}\sum_{r=0}^{P-1}e^{irk2\pi/P}e^{-irk2\pi/P}\left(\binom{P-1}{w-1}-\binom{P-2}{w-2}\right) (41)
=(Pw)−11wPP((P−1w−1)−(P−2w−2))\displaystyle=\binom{P}{w}^{-1}\frac{1}{wP}P\left(\binom{P-1}{w-1}-\binom{P-2}{w-2}\right)
=P−wP(P−1)\displaystyle=\frac{P-w}{P(P-1)}
In other words, when ww randomly chosen simple periodic signals are superposed, the system behaves as if β0\beta_{0} takes a w/Pw/P cut and then β1,…,βP−1\beta_{1},\dots,\beta_{P-1} equally split whats left:
E(|βk|2)={k=0→wP0 quint:
"""Quantum␣computes␣an␣approximate␣modular␣exponentation.
␣␣␣␣Args:
␣␣␣␣␣␣␣␣Q_exponent:␣The␣superposed␣exponent␣to␣exponentiate␣by.
␣␣␣␣␣␣␣␣conf:␣Problem␣configuration␣data,␣precomputed␣tables,␣etc.
␣␣␣␣␣␣␣␣qpu:␣Simulator␣instance␣being␣acted␣upon.
␣␣␣␣Returns:
␣␣␣␣␣␣␣␣The␣result␣of␣the␣approximate␣modular␣exponentation.
␣␣␣␣"""
Q_dlog: quint = qpu.alloc_quint(length=conf.len_dlog_accumulator)
Q_result: quint = qpu.alloc_quint(
length=conf.len_accumulator + 1,
scatter=True,
scatter_range=1 << conf.mask_bits,
)
loop1_vent = Lookup(np.zeros((conf.num_windows1, 1 << conf.window1), dtype=np.bool_))
for i in range(len(conf.periods)):
p = int(conf.periods[i])
loop1(
Q_dlog=Q_dlog,
Q_exponent=Q_exponent,
vent=loop1_vent,
i=i,
conf=conf,
)
Q_compressed = loop2(
Q_target=Q_dlog,
modulus=p - 1,
compressed_len=p.bit_length(),
)
Q_residue = loop3(
Q_dlog=Q_compressed,
i=i,
conf=conf,
qpu=qpu,
)
loop4(
Q_residue=Q_residue,
Q_acc=Q_result,
i=i,
conf=conf,
qpu=qpu,
)
unloop3(
Q_unresult=Q_residue,
Q_dlog=Q_compressed,
i=i,
conf=conf,
qpu=qpu,
)
unloop2(
Q_target=Q_dlog,
modulus=p - 1,
compressed_len=p.bit_length(),
)
loop1(
Q_dlog=Q_dlog,
Q_exponent=Q_exponent,
vent=loop1_vent,
i=len(conf.periods),
conf=conf,
)
Q_dlog.del_by_equal_to(0)
for j in range(conf.num_windows1):
Q_k = Q_exponent[j * conf.window1 :][: conf.window1]
qpu.z(loop1_vent[j, Q_k])
return Q_result
def loop1(
Q_dlog: quint,
conf: ExecutionConfig,
Q_exponent: quint,
i: int,
vent: Lookup,
) -> None:
"""Offsets␣Q_dlog␣to␣the␣discrete␣log␣of␣the␣next␣residue.
␣␣␣␣Args:
␣␣␣␣␣␣␣␣Q_dlog:␣The␣register␣to␣offset.
␣␣␣␣␣␣␣␣conf:␣Specifies␣details␣like␣the␣base␣of␣the␣exponent␣for␣the␣current
␣␣␣␣␣␣␣␣␣␣␣␣residue,␣window␣sizes,␣and␣precomputed␣tables.
␣␣␣␣␣␣␣␣Q_exponent:␣In␣the␣problem␣spec␣this␣is␣the␣value␣to␣exponentiate␣by,
␣␣␣␣␣␣␣␣␣␣␣␣but␣in␣this␣method␣it’s␣the␣value␣to␣use␣as␣addresses␣for␣table
␣␣␣␣␣␣␣␣␣␣␣␣lookups␣that␣get␣added␣together.
␣␣␣␣␣␣␣␣i:␣The␣iteration␣variable␣of␣the␣loop␣iterating␣over␣the␣primes␣in
␣␣␣␣␣␣␣␣␣␣␣␣the␣residue␣number␣system.␣Indexes␣the␣modulus␣and␣generator,
␣␣␣␣␣␣␣␣␣␣␣␣as␣well␣as␣related␣table␣data,␣from␣within␣‘conf‘.
␣␣␣␣␣␣␣␣vent:␣Where␣to␣dump␣deferred␣phase␣data␣for␣uncomputing␣lookups.
␣␣␣␣"""
for j in range(conf.num_windows1):
Q_k = Q_exponent[j * conf.window1 :][: conf.window1]
table = conf.lookup1[i, j].venting_into(vent[j])
Q_dlog += table[Q_k]
def loop2(
Q_target: quint,
modulus: int,
compressed_len: int,
) -> quint:
"""Compresses␣‘Q_target␣%␣modulus‘␣into␣a␣smaller␣part␣of␣‘Q_target‘.
␣␣␣␣Args:
␣␣␣␣␣␣␣␣Q_target:␣The␣register␣containing␣the␣remainder␣to␣compress.
␣␣␣␣␣␣␣␣compressed_len:␣How␣large␣the␣remainder␣should␣be
␣␣␣␣␣␣␣␣␣␣␣␣after␣compression.␣At␣least␣modulus.bit_length().
␣␣␣␣␣␣␣␣modulus:␣The␣modulus␣used␣in␣the␣remainder␣computation.
␣␣␣␣Returns:
␣␣␣␣␣␣␣␣The␣slice␣of␣‘Q_target‘␣that␣the␣remainder␣is␣in.
␣␣␣␣"""
n = len(Q_target)
while n > compressed_len:
n -= 1
threshold = modulus << (n - compressed_len)
Q_target[: n + 1] -= threshold
Q_target[:n] += Q_target[n].ghz_lookup(threshold)
return Q_target[:n]
def loop3(
conf: ExecutionConfig,
Q_dlog: quint,
i: int,
qpu: QPU,
) -> quint:
"""Computes␣‘pow(conf.generators[i],␣Q_exponent,␣conf.periods[i])‘.
␣␣␣␣Args:
␣␣␣␣␣␣␣␣conf:␣Specifies␣details␣like␣the␣base␣of␣the␣exponent␣for␣the␣current
␣␣␣␣␣␣␣␣␣␣␣␣residue,␣window␣sizes,␣and␣precomputed␣tables.
␣␣␣␣␣␣␣␣Q_dlog:␣Superposed␣value␣to␣exponentiate␣by.
␣␣␣␣␣␣␣␣i:␣The␣iteration␣variable␣of␣the␣loop␣iterating␣over␣the␣primes␣in
␣␣␣␣␣␣␣␣␣␣␣␣the␣residue␣number␣system.␣Indexes␣the␣modulus␣and␣generator,
␣␣␣␣␣␣␣␣␣␣␣␣as␣well␣as␣related␣table␣data,␣from␣within␣‘conf‘.
␣␣␣␣␣␣␣␣qpu:␣Simulator␣instance␣being␣acted␣upon.
␣␣␣␣Returns:
␣␣␣␣␣␣␣␣An␣allocated␣register␣containing␣the␣result␣of␣the␣exponentation.
␣␣␣␣"""
modulus = int(conf.periods[i])
Q_result = qpu.alloc_quint(length=modulus.bit_length() + 1)
Q_helper = qpu.alloc_quint(length=modulus.bit_length() + 1)
table = conf.lookup3c[i].venting_into_new_table()
Q_l = Q_dlog[: conf.window3a * 2]
Q_result ^= table[Q_l]
qpu.push_uncompute_info(table.vent)
for j in range(2, conf.num_windows3a):
Q_l1 = Q_dlog[j * conf.window3a :][: conf.window3a]
for k in range(conf.num_windows3b):
Q_l0 = Q_result[k * conf.window3b :][: conf.window3b]
Q_l = (Q_l1 << conf.window3b) | Q_l0
table = conf.lookup3a[i, j, k].venting_into_new_table()
Q_helper -= table[Q_l]
Q_helper[:-1] += Q_helper[-1].ghz_lookup(modulus)
phase_wrap = Q_helper[-1].mx_rz()
qpu.push_uncompute_info((phase_wrap, table.vent))
Q_result, Q_helper = Q_helper, Q_result
qpu.push_uncompute_info(Q_helper.mx_rz())
Q_helper.del_by_equal_to(0)
return Q_result
def loop4(
conf: ExecutionConfig,
Q_residue: quint,
Q_acc: quint,
i: int,
qpu: QPU,
) -> None:
"""Adds␣Q_residue’s␣approximate␣contribution␣into␣Q_result_accumulator.
␣␣␣␣Args:
␣␣␣␣␣␣␣␣conf:␣Specifies␣details␣like␣the␣base␣of␣the␣exponent␣for␣the␣current
␣␣␣␣␣␣␣␣␣␣␣␣residue,␣window␣sizes,␣and␣precomputed␣tables.
␣␣␣␣␣␣␣␣Q_residue:␣The␣residue␣of␣the␣exact␣total␣for␣the␣current␣modulus.
␣␣␣␣␣␣␣␣Q_acc:␣Where␣to␣add␣the␣residue’s␣approximate␣contributions.
␣␣␣␣␣␣␣␣i:␣The␣iteration␣variable␣of␣the␣loop␣iterating␣over␣the␣primes␣in
␣␣␣␣␣␣␣␣␣␣␣␣the␣residue␣number␣system.␣Indexes␣the␣modulus␣and␣generator,
␣␣␣␣␣␣␣␣␣␣␣␣as␣well␣as␣related␣table␣data,␣from␣within␣‘conf‘.
␣␣␣␣␣␣␣␣qpu:␣Simulator␣instance␣being␣acted␣upon.
␣␣␣␣"""
trunc = conf.truncated_modulus
for j in range(conf.num_windows4):
Q_k = Q_residue[j * conf.window4 :][: conf.window4]
table = conf.lookup4[i, j].venting_into_new_table()
table2 = trunc - table
Q_acc -= table[Q_k]
Q_acc[:-1] += Q_acc[-1].ghz_lookup(trunc)
if Q_acc[-1].mx_rz():
qpu.z(Q_acc[:-1] >= table2[Q_k])
qpu.z(table.vent[Q_k])
def unloop3(
Q_unresult: quint,
conf: ExecutionConfig,
Q_dlog: quint,
i: int,
qpu: QPU,
) -> None:
"""Uncomputes␣‘pow(conf.generators[i],␣Q_exponent,␣conf.periods[i])‘.
␣␣␣␣Args:
␣␣␣␣␣␣␣␣Q_unresult:␣The␣register␣to␣uncompute␣and␣delete.
␣␣␣␣␣␣␣␣conf:␣Specifies␣details␣like␣the␣base␣of␣the␣exponent␣for␣the␣current
␣␣␣␣␣␣␣␣␣␣␣␣residue,␣window␣sizes,␣and␣precomputed␣tables.
␣␣␣␣␣␣␣␣Q_dlog:␣Superposed␣value␣to␣exponentiate␣by.
␣␣␣␣␣␣␣␣i:␣The␣iteration␣variable␣of␣the␣loop␣iterating␣over␣the␣primes␣in
␣␣␣␣␣␣␣␣␣␣␣␣the␣residue␣number␣system.␣Indexes␣the␣modulus␣and␣generator,
␣␣␣␣␣␣␣␣␣␣␣␣as␣well␣as␣related␣table␣data,␣from␣within␣‘conf‘.
␣␣␣␣␣␣␣␣qpu:␣Simulator␣instance␣being␣acted␣upon.
␣␣␣␣"""
modulus = int(conf.periods[i])
Q_helper = qpu.alloc_quint(length=modulus.bit_length() + 1)
for j in range(2, conf.num_windows3a)[::-1]:
Q_l0 = Q_dlog[j * conf.window3a :][: conf.window3a]
for k in range(conf.num_windows3b)[::-1]:
Q_l1 = Q_unresult[k * conf.window3b :][: conf.window3b]
Q_l = (Q_l0 << conf.window3b) | Q_l1
table1 = conf.lookup3b[i, j, k].venting_into_new_table()
table2 = modulus - table1
Q_helper -= table2[Q_l]
Q_helper[:-1] += Q_helper[-1].ghz_lookup(modulus)
not_phase_wrap = Q_helper[-1].mx_rz()
qpu.z(not_phase_wrap)
if not_phase_wrap:
qpu.z(Q_helper[:-1] < table1[Q_l])
qpu.z(table1.vent[Q_l])
phase_mask_from_helper_during_compute = qpu.pop_uncompute_info()
qpu.cz(Q_helper, phase_mask_from_helper_during_compute)
Q_unresult, Q_helper = Q_helper, Q_unresult
for k in range(conf.num_windows3b)[::-1]:
Q_l1 = Q_unresult[k * conf.window3b :][: conf.window3b]
Q_l = (Q_l0 << conf.window3b) | Q_l1
phase_wrap, phase_table = qpu.pop_uncompute_info()
table1 = conf.lookup3a[i, j, k].venting_into(phase_table)
table2 = modulus - table1
Q_helper -= table2[Q_l]
Q_helper[:-1] += Q_helper[-1].ghz_lookup(modulus)
not_phase_wrap = Q_helper[-1].mx_rz()
qpu.z(not_phase_wrap)
if phase_wrap ^ not_phase_wrap:
qpu.z(Q_helper[:-1] < table1[Q_l])
qpu.z(phase_table[Q_l])
Q_helper.del_by_equal_to(0)
mx = Q_unresult.del_measure_x()
vent = qpu.pop_uncompute_info()
vent ^= conf.lookup3c[i].phase_corrections_for_mx(mx)
Q_l = Q_dlog[: conf.window3a * 2]
qpu.z(vent[Q_l])
def unloop2(
Q_target: quint,
modulus: int,
compressed_len: int,
) -> None:
"""Uncompresses␣‘Q_target␣%␣modulus‘␣from␣a␣smaller␣part␣of␣‘Q_target‘.
␣␣␣␣Args:
␣␣␣␣␣␣␣␣Q_target:␣The␣register␣containing␣the␣remainder␣to␣uncompress.
␣␣␣␣␣␣␣␣compressed_len:␣How␣large␣the␣remainder␣was
␣␣␣␣␣␣␣␣␣␣␣␣after␣compression.␣At␣least␣modulus.bit_length().
␣␣␣␣␣␣␣␣modulus:␣The␣modulus␣used␣in␣the␣remainder␣computation.
␣␣␣␣"""
n = compressed_len
while n < len(Q_target):
threshold = modulus << (n - compressed_len)
Q_target[:n] -= Q_target[n].ghz_lookup(threshold)
Q_target[: n + 1] += threshold
n += 1
A.2 Addition Operation
Given two inputs aa and bb, their sum s=a+bs=a+b satisfies this equation at each bit position kk:
sk+1\displaystyle s_{k+1} =((ak⊕sk)⋅(bk⊕sk))⊕(ak⊕bk⊕sk⊕ak+1⊕bk+1)\displaystyle=\left((a_{k}\oplus s_{k})\cdot(b_{k}\oplus s_{k})\right)\oplus(a_{k}\oplus b_{k}\oplus s_{k}\oplus a_{k+1}\oplus b_{k+1}) (54)
Note that the identity is built out of three Z parity products: P1=ZakZskP_{1}=Z_{a_{k}}Z_{s_{k}}, P2=ZbkZskP_{2}=Z_{b_{k}}Z_{s_{k}}, and P3=ZakZbkZskZak+1Zbk+1P_{3}=Z_{a_{k}}Z_{b_{k}}Z_{s_{k}}Z_{a_{k+1}}Z_{b_{k+1}}. This makes the identity interesting, when using lattice surgery, because Z parity products are relatively cheap to access [FG18, Lit18].
A circuit diagram based on Equation 54 is shown in Figure 8. The first half of the diagram is an out-of-place adder. It computes another qubit of ss, using qubits from aa and bb. The second half uncomputes a qubit of bb, using the fact that b=s−ab=s-a. Note that the diagram inlines details of a teleportation used to perform a Toffoli gate. Normally, teleported Toffolis are corrected using CX gates and CZ gates [Jon13, GF19]. The circuit instead applies corrections based on teleporting S gates into multi-qubit Pauli products. Also, the circuit defers corrections that only affect phases until uncomputing b=a−sb=a-s. This allows those corrections to be merged into similar corrections during the uncomputation, balancing out the circuit’s usage of delayed choice routing qubits. It uses 3 routing qubits during the computation and also 3 during the uncomputation, instead of 6 during the computation and 2 during the uncomputation [GF19].
Figure 9 shows how Equation 54 can be implemented as a ZX graph and then optimized into an efficient lattice surgery layout. (The diagram doesn’t include the delayed choice correction operations shown in Figure 8. They’re attached to the CCZ state before it enters the picture.) An important detail here is that the optimized graph has a different “calling convention” from the initial graph. Instead of the qubits of aa and bb being passed into the adder via input ports, and then returned via output ports, they are attached to the adder via a “Z port”. To pass a qubit into a Z port, Z-split the qubit into two qubits [BH17] then Z-merge one of them into the Z port. The remaining qubit stays behind, becoming the output qubit without moving. This calling convention is beneficial because it halves the number of ports.
The physical arrangement of the addition is as follows. The two registers to add are arranged on opposite sides of short hallways leading to the compute region. Conveniently, these hallways have a pitch of 3 surface code patches which matches the pitch of the adder building block and also the pitch of the magic state factories. The qubits within the hallways are ordered so that the least significant qubits are further away from the compute region. As the adder block executes, the hallway is used to access the next two input qubits and then the adder block produces a qubit of the sum, which is stored in the hallway between the two inputs used to produce it. The hallway fills in gradually as the sum is computed.
After the sum is computed, either of the inputs can be uncomputed using measurement based uncomputation as shown on the right hand side of Figure 8. In context of the overall algorithm, usually one of the inputs is the previous value of an accumulator and the other input is the result of a looking up an offset. So the previous accumulator value would be uncomputed as in Figure 8, and then the lookup value would be uncomputed using measurement based uncomputation creating phase corrections to be handled by a later phaseup operation, leaving behind only the new accumulator value. Lattice surgery mock-ups of this process are shown in Figure 10 and Figure 11.
Figure 8: A quantum circuit diagram of an adder including Clifford corrections. Boxes containing X/Z characters are multi-qubit Pauli product operators. Classical parities are shown using “C” operators. Boxes linked by vertical lines form controlled operations, meaning they only act on their common -1 eigenspaces. Click here to open this circuit in Quirk.
Figure 9: Adder building block diagrams. Top left is a ZX graph implementing Equation 54. Top right is the graph after merging input/output ports into Z ports. Bottom left is a complete 3-qubit adder built by attaching together multiple instances of the graph. Bottom right is an equivalent lattice surgery diagram.
Figure 10: Manual lattice surgery mock-up of adder compute and uncompute steps. Note that the steps tile horizontally, and Clifford corrections are being done after the operation (rather than in a reaction limited fashion). The uncomputation step assumes one of the inputs comes from a lookup, meaning its qubits can be removed by measurement based uncomputation with deferred phase corrections. Green highlights show CCZ-state-associated lattice surgery. Purple highlights show input-qubit-associated lattice surgery.
Figure 11: Manual lattice surgery mock-up of a 35 qubit inplace addition. Only intended to give a qualitative sense of the high level layout; some details are omitted and the 3d model likely contains some minor mistakes. Uses many copies of Figure 10. The offset BB can be deleted in tandem because in context it comes from a lookup addressed by qubits stored elsewhere.
A.3 Phaseup Operation
A “phaseup” is a quantum operation that negates the amplitude of computational basis states determined by a classical table of bits TT. A phaseup acts on an nn qubit address register and is driven by a 2n2^{n} bit table TT. Typically nn will be small, for example n=6n=6, due to the exponential size of the table. Phaseups appear when uncomputing table lookups with measurement based uncomputation [Ber+19].
PhaseupT\displaystyle\text{Phaseup}_{T} =∑k=02n−1negif(Tk)|k⟩⟨k|\displaystyle=\sum_{k=0}^{2^{n}-1}\text{negif}(T_{k})|k\rangle\langle k| (55)
For this paper, I imagined phaseups to be implemented by splitting the register into a low half LL (with the n//2n//2 least significant qubits) and a high half HH (with the n−n//2n-n//2 most significant qubits). This effectively reshapes TT into a 2len L×2len H2^{\text{len }L}\times 2^{\text{len }H} matrix, with rows/columns indexed by H,LH,L. Each half-register would then be expanded into its “power product”: a register storing every possible product that can be formed out of the original register’s qubits. For example, if LL was a three-qubit register storing the computational basis state |c,b,a⟩|c,b,a\rangle then its power product L∗L^{\ast} is the computational basis state |cba,cb,ca,c,ab,b,a,1⟩|cba,cb,ca,c,ab,b,a,1\rangle. Power products can be computed with a series of AND gates (for example, see the left side of Figure 12). Once the power products are computed, they can implement the phaseup operation using a series of “masked phase flips”. A masked phase flip is a multi-controlled Z gate, with the involved qubits determined by the positions of 1s within a binary mask mm:
MaskedPhaseFlipn(m)=∑k=02n−1negif(k&m=m)|k⟩⟨k|\text{MaskedPhaseFlip}_{n}(m)=\sum_{k=0}^{2^{n}-1}\text{negif}(k\;\&\;m=m)|k\rangle\langle k| (56)
To implement the desired phaseup in terms of masked phase flips, it’s necessary to determine the values of the masks. The data in TT lists whether or not to phase flip each possible value of the register pair (H,L)(H,L). We instead want an alternate form T¯\overline{T} that lists whether or not to include/exclude each possible masked phase flip (i.e. the coefficients of the phaseup’s EXOR polynomial [MP01]). Conveniently, this conversion corresponds to a matrix multiplication:
T¯=[1011]⊗len H⋅T⋅[1101]⊗len L(mod2)\overline{T}=\begin{bmatrix}1&0\\ 1&1\end{bmatrix}^{\otimes\text{len }H}\cdot T\cdot\begin{bmatrix}1&1\\ 0&1\end{bmatrix}^{\otimes\text{len }L}\pmod{2} (57)
PhaseupT\displaystyle\text{Phaseup}_{T} =∏l=0(len L∗)−1∏h=0(len H∗)−1CZ(Hh∗,Ll∗)T¯h,l\displaystyle=\prod_{l=0}^{(\text{len }L^{\ast})-1}\prod_{h=0}^{(\text{len }H^{\ast})-1}\text{CZ}(H^{\ast}_{h},L^{\ast}_{l})^{\overline{T}_{h,l}} (58)
In Figure 12 I show a circuit diagram of a phaseup implemented this way, including the data-driven CZ gates as well as the computation and uncomputation of the power products. Note that this circuit has optimized out the two trivial qubits L0∗=H0∗=|1⟩L^{*}_{0}=H^{\ast}_{0}=|1\rangle, resulting in some CZ gates becoming Z gates and one CZ gate becoming an irrelevant global phase (not shown). Also note that Figure 12 has grouped the many individual CZ gates into a few large multi-target CZ gates. This is beneficial because in lattice surgery the marginal cost of targeting a larger Pauli product is notably lower than the marginal cost of doing another gate [FG18, Lit18].
Figure 12: Circuit diagram of a phaseup. On the left, the input register is split into two halves and each half is expanded into its power product using AND gates. In the middle, the desired phase flips are encoded into the presence/absence of Z and CZ gates. On the right, the power products are uncomputed using measurement based uncomputation. Click here to open this circuit in Quirk.
I apply one key additional optimization beyond what’s shown Figure 12. I allow the AND computations that appear during the computation of the power product to “wander”. That is to say, I perform AND gates by gate teleportation but don’t correct the teleportation. An AND gate computes c=a⋅bc=a\cdot b, whereas a wandering AND gate computes c=(a⊕x)⋅(b⊕y)c=(a\oplus x)\cdot(b\oplus y) for measured random values xx and yy. Normally these xx and yy values are removed with corrective CNOT gates, performed on the quantum computer. Instead, I account for the CNOT gates by computing a correction matrix CC to be multiplied into T¯\overline{T}. (CC also affects the phase corrections performed during the uncomputation of the power products.) In other words, the CNOT corrections created by the wandering AND gates are handled by rewrites in the classical control system instead of by extra quantum gates. This is analogous to how [Lit18] skips performing Clifford gates by folding their effects into the Pauli product operators targeted by TT gates and measurement operations.
Because wandering AND gates are used when computing the power products, computing the power products has constant reaction depth. Instead of needing to separately correct each layer of AND gates, the corrections merge into a single massive change to the set of performed Z and CZ gates. Only the uncomputation needs to be corrected layer by layer. So, interestingly, the overall reaction depth of the phaseup is n/2±O(1)n/2\pm O(1) instead of n±O(1)n\pm O(1).
Overall, a phaseup can be done with 22n2\sqrt{2^{n}} AND gates, 22n2\sqrt{2^{n}} workspace qubits, and 2n\sqrt{2^{n}} multi-target CZ gates. This is reminiscent of the O(n)O(\sqrt{n}) costs of select-swap lookups [LKS24], which similarly starts by dividing the input register into two halves. See Figure 13 for a lattice surgery mock-up of a phaseup operation implemented in this way.
Figure 13: Manual mock-up of lattice surgery performing a phaseup operation. Only intended to give a qualitative sense of the high level layout; some details are omitted and the 3d model likely contains some minor mistakes. Address qubits are accented with purple, CCZ qubits are accented with green, output qubits are accented with red, and delays for control system reaction time are accented with black and white.
A.4 Lookup Operation
A lookup is an operation that initializes ww output qubits using values from a classical table storing 2n2^{n} ww-bit integers, indexed by an nn qubit quantum address:
LookupT=∑k=02n−1(|Tk⟩⊗|k⟩)⟨k|\text{Lookup}_{T}=\sum_{k=0}^{2^{n}-1}\Big(|T_{k}\rangle\otimes|k\rangle\Big)\langle k| (59)
For this paper, I imagined implementing lookups similar to phaseups. First, split the address register into two halves and compute the power product of each half. Second, perform multi-target Toffoli gates (one for each pair of control qubits from the two half registers) to initialize the output qubits. As in the phaseup, the AND gates in the power product computation are allowed to wander. But now the multi-target Toffoli gates are also allowed to wander. This creates dependencies between the different Toffoli gates, where the teleportation outcome of one can change the qubits that must be targeted by another. These changes can be accounted for by the classical control system, but the Toffolis must be carefully ordered to avoid having to redo work and to avoid incurring reaction delays.
After the Toffolis finish, the lookup is completed by measuring all ancillary qubits in the X basis. This creates an enormous number of phase corrections, but every one of these corrections corresponds to phase flipping some subset of the address values. Therefore all these corrections can be merged into a phaseup, which can be deferred and merged into the phaseup that appears in the uncomputation of the lookup later on.
I show a mock-up for the lattice surgery of a lookup in Figure 14.
Figure 14: Manual mock-up of lattice surgery for a lookup operation. Only intended to give a qualitative sense of the high level layout; some details are omitted and the 3d model likely contains some minor mistakes. 21 multi-target CX gates are included in the diagram, out of the 63 that would be performed by a lookup with 6 address qubits. The computation of the two power products isn’t shown. Green-accented pipes are CCZ qubits, purple-accented pipes are power product qubits, and black pipes are immobile qubits. One of the CCZ qubits pauses momentarily when leaving the factory, before rotating to become the target of a Toffoli state, to give time for the control system to update its targets in response to previous gate teleportations. One of the power products is keeping its qubits still, to be reached by one of the qubits of the CCZ state during each multi-target Toffoli. The other power product is proactively moving its qubits in front of the magic state factories, to intercept one qubit from each CCZ state.
A.5 Frequency Basis Measurement
A frequency basis measurement is implemented by performing an inverse Quantum Fourier transform (QFT) and then measuring in the computational basis. Because of the presence of the measurements, the deferred measurement principle can be used to merge the quadratically many controlled phase gates that normally appear in a QFT circuit into n−1n-1 phase gates with adaptively determined phase angles [PP00, ME99] (see Figure 16).
To implement phase gates, I use kickback from additions into a phase gradient state [KSV02, Gid16, Gid18, NSM20]. A phase gradient state is a gg qubit state where qubit kk is in the state Z2−k|+⟩Z^{2^{-k}}|+\rangle. Equivalently, it’s a uniform superposition where the amplitude for the computational basis state |k⟩|k\rangle has been phased by k/2nk/2^{n} turns:
|GRADg⟩=2−g/2∑k=02g−1|k⟩ei2πk/2g=⨂k=0g−1Z2−k|+⟩|\text{GRAD}_{g}\rangle=2^{-g/2}\sum_{k=0}^{2^{g}-1}|k\rangle e^{i2\pi k/2^{g}}=\bigotimes_{k=0}^{g-1}Z^{2^{-k}}|+\rangle (60)
If a classical constant CC is added into a gg qubit phase gradient state, controlled by a qubit qq, then phase kickback will phase qq by −C/2g-C/2^{g} turns while leaving the phase gradient state unchanged. CC is chosen by rounding the desired angle θ\theta to the nearest multiple of 2π/2g2\pi/2^{g}.
Rounding θ\theta introduces a per-rotation error. The maximum over/under rotation is π/2g\pi/2^{g} radians. The chance of a shot failure due to this rounding, across the n−1n-1 rotations done by the frequency basis measurement, is at most nπ2gn\frac{\pi}{2^{g}}.
Another source of error is the infidelity of the phase gradient state, due to approximate preparation. This error differs from the rounding error in that it only applies once per state, instead of once per use. The phase gradient state is an eigenstate of addition and, once prepared, is only used as the target of additions. Therefore the prepared state could be measured in the eigenbasis of addition without changing the behavior of the algorithm, projecting the prepared state into a perfect state with probability equal to its fidelity. So the phase gradient preparation contributes a shot failure probability no larger than the infidelity of the state, regardless of how many times the state is used.
To prepare phase gradient qubits, I use single qubit Clifford+T sequences [RS14]. I convert the sequences into a form that begins with a Pauli basis initialization, ends with a Clifford rotation, and otherwise alternates between performing TX±1T_{X}^{\pm 1} and TZ±1T_{Z}^{\pm 1} where TZ=Z1/4T_{Z}=Z^{1/4} and TX=X1/4T_{X}=X^{1/4}. In terms of lattice surgery, I imagine executing the sequence with the help of four neighboring patches. Each neighbor will repeatedly cultivate a T state, undergo a parity measurement against the target patch, and then undergo an adaptively chosen measurement. When a TX±1T_{X}^{\pm 1} gate is needed, an MXXM_{XX} measurement is performed between the target patch and one of its XX-boundary neighbors that has a T state ready. This measurement reveals whether or not the target was rotated by +45∘+45^{\circ} or −45∘-45^{\circ} around the XX axis. If it rotated in the correct direction, the neighboring patch is measured in the ZZ basis. Otherwise it’s measured in the Y basis, correcting the direction of the rotation [Lit18] (up to classically tracked Paulis). The same story occurs for TZ±1T_{Z}^{\pm 1} gates, but with X and Z swapped. This strategy results in lattice surgery operations spiraling around the target patch, with the neighbors taking turns contributing T states (see Figure 16).
Concretely, I would use the gate sequences shown in Table 7 to prepare the phase gradient state’s qubits. The first 11 qubits of the state are prepared using a total of 159 T gates. All further qubits, up to the desired length gg, are approximated to high fidelity by |+⟩|+\rangle states. This preparation has an infidelity of 5⋅10−65\cdot 10^{-6}, assuming perfect gates. If the T states powering the gates are cultivated to an infidelity of 10−7/410^{-7}/4, then inaccurate T gates will introduce an additional infidelity of 4⋅10−64\cdot 10^{-6}. So, in total, preparing the phase gradient state in this way contributes a less than 10−510^{-5} chance of algorithm failure. This chance could be reduced, by distilling better T states and using the more accurate gate sequences from Table 7. But ultimately the error costs and operation costs of the frequency basis measurement are completely negligible compared to other costs in the paper, so for the purposes of cost estimates I simply ignore it.
Figure 15: A frequency basis measurement implemented with adaptive phase gates [PP00, ME99] achieved by kickback from controlled addition of a classical constant into a phase gradient state [KSV02, Gid18]. The phase gradient state can be truncated, resulting in an approximate QFT [NSM20]. Click here to open this circuit in Quirk.
Figure 16: Manual mock-up of lattice surgery preparing a phase gradient state. Left: applying a TX±1T_{X}^{\pm 1} gate by magic state cultivation and teleportation. The sign of the exponent is controlled by picking the basis of the MY/ZM_{Y/Z} measurement, accounting for the result of the MXXM_{XX} pair measurement [Lit18, GF19]. Left middle: a central qubit can be surrounded with TX±1T_{X}^{\pm 1} and TZ±1T_{Z}^{\pm 1} gates taking turns operating on it. Middle: this process can be continued as long as needed. Right: many phase gradient qubits being prepared in parallel.
Qubit Index Init T Gate Directions Finish T Infidelity
(kk in Z2−k|+⟩Z^{2^{-k}}|+\rangle) Basis (the signs in TX±1,TZ±1,TX±1,TZ±1,…T_{X}^{\pm 1},T_{Z}^{\pm 1},T_{X}^{\pm 1},T_{Z}^{\pm 1},\dots) Clifford Count
00 RXR_{X} Z 0 0
11 RYR_{Y} 0 0
22 RZR_{Z} + H 1 0
33 RZR_{Z} +--++-++--+-+++-+----+ H,Y 22 5.8e-7
44 RZR_{Z} ++++-----+--+--+-++-++ H 22 5.7e-7
55 RZR_{Z} ++----++-++-++++++--- X 21 2.8e-8
66 RZR_{Z} ---++-++++---+++----- 21 3.2e-8
77 RZR_{Z} +-++--++---- H 12 5.0e-7
88 RZR_{Z} ++--++---++-++-+--+ X 19 5.3e-8
99 RZR_{Z} +--+--++-+-++---+---- 21 7.2e-7
1010 RZR_{Z} ++----+++++++----++- H 20 1.2e-7
1111 RXR_{X} 0 5.9e-7
1212 RXR_{X} 0 1.5e-7
Totals 159 3.4e-6
Table 6: Example decompositions of phase gradient qubit initializations, with a per-sequence infidelity target of 10−610^{-6}. Found using a meet-in-the-middle search. Each qubit is prepared with a Pauli basis initialization, then alternating TX±1T_{X}^{\pm 1} and TZ±1T_{Z}^{\pm 1} gates, then a Clifford rotation. The string of signs specifies the sign of each TX±1T_{X}^{\pm 1} and TZ±1T_{Z}^{\pm 1} gate in sequence, with the leftmost sign corresponding to the first TX±1T_{X}^{\pm 1} gate.
Qubit Index Init T Gate Directions Finish T Infidelity
(kk in Z2−k|+⟩Z^{2^{-k}}|+\rangle) Basis (the signs in TX±1,TZ±1,TX±1,TZ±1,…T_{X}^{\pm 1},T_{Z}^{\pm 1},T_{X}^{\pm 1},T_{Z}^{\pm 1},\dots) Clifford Count
00 RXR_{X} Z 0 0
11 RYR_{Y} 0 0
22 RZR_{Z} + H 1 0
33 RZR_{Z} +-+----++------++-+----+-----++-+++--+++----+++-++ H,Y 50 0
44 RZR_{Z} ----+++-+-+---+++-++--+-+-+-++++--+++-+-++--+- H,Z 46 4.1e-16
55 RZR_{Z} +-+--+----+---++-+++++--+++-++---++-++----+-++-+ S,H 48 6.8e-16
66 RZR_{Z} ---+++-------++--+++-+--++-++--+-+-+++++++----+-+ X 49 4.1e-17
77 RZR_{Z} ++---+++++--+---++++-+---+-++-+-+++-+++--++------+ H 50 6.9e-16
88 RZR_{Z} ++-++-+++--++-++-++++-++--++++++----------+-- Y 45 3.0e-16
99 RZR_{Z} +---+--++++++++--+--++--++-+-++---+-++----+-+-++ H 48 2.3e-16
1010 RZR_{Z} +++--+--+-+++++++-++++-+-++-+-+++-++---+++++-+--- 49 5.0e-17
1111 RZR_{Z} ++-+--++-++--++-----+-+-+-+---+++-------+-+--++ Z 47 9.7e-16
1212 RZR_{Z} ++------++++++--+--+-++-+----+-+++++--+++---+ Y 45 6.8e-16
1313 RZR_{Z} +++---+--++++-++--+++--++--+-++-+++++--+-++--+ H,Z 46 6.9e-16
1414 RZR_{Z} +++--+-----+++---++++-+-+++++-+++----+++---+-+--+ 49 3.9e-16
1515 RZR_{Z} +---++-+--+-++---+--+++-++-++++--++++-+++-+--+ H,Y 46 6.2e-16
1616 RZR_{Z} +--+-+-++--+++++-+-++---+++++-+-++++--+---+-++-+ H,Y 48 4.9e-16
1717 RZR_{Z} +-++----+---++++-+-+++-+-++++-+-+----+-++-- 43 5.3e-16
1818 RZR_{Z} ++---+--++--+---+--+-+---+---------++++++++--++-- X 49 1.8e-16
1919 RZR_{Z} +--+--+-+-+-------+---+--+---++-+--+-+++-+-+++-++ Z 49 1.3e-16
2020 RZR_{Z} ----+-++++--+-++--+++--+++--++-------+-+-+---++-- 49 9.7e-16
2121 RZR_{Z} ++---++-++-+--++----+-+-+--+-++++--++-++---+++++ H 48 6.1e-16
2222 RZR_{Z} +-++-+-+----+++--+-++--+-+-+-++-++---++-+--+++-+--++ H,Z 52 3.4e-16
2323 RZR_{Z} +++---+---+-+--++--+------+--++--+-+---+---+++- X 47 5.9e-16
2424 RZR_{Z} ++++-----+-++---+-+++---+-+-++++-+++-++++-++++--+ X 49 2.5e-16
2525 RZR_{Z} +-+-++---+++-++++-+-+-++++-+-+-++++-+++---++-+-++ 49 2.9e-16
2626 RXR_{X} 0 5.5e-16
2727 RXR_{X} 0 1.4e-16
Totals 1102 1.1e-14
Table 7: Same as Table 7 but with a per-qubit infidelity target of 10−1510^{-15}.
## Comments
**misha**: > In this paper, I reduced the expected number of qubits needed to break RSA2048 from 20 million to 1 million.