Shor算法是一种量子算法,用于分解大整数为素数的乘积。这是一个量子计算课程辅导员发布的英文笔记的翻译版本。
在公钥密码学中,Alice发布一个公钥,Bob使用该公钥来加密消息。然后,Alice使用她的私钥来解密消息。这依赖于密码学的非对称性:使用公钥加密消息很容易,但在没有私钥的情况下解密消息却很困难。这又依赖于单向函数的存在。
- 单向函数是指那些正向计算容易,但反向计算困难的函数。例如,RSA公钥加密系统使用因数分解作为单向函数:将两个素数 和 相乘得到一个合数 很容易,但反过来,将一个合数 分解为因数 和 却在数学上非常困难。
- 事实上,已知的最好的经典因数分解算法——数域筛法(number field sieve)需要 次操作,其中 ,即 的比特数。
- 对于密码学应用来说,单向函数的数学定义至关重要,即它们在平均情况下必须难以反转,而不仅仅是在最坏情况下难以反转。
1994年,Peter Shor发明了一种量子算法,可以在多项式时间内分解整数。这仍然是量子计算最重要和最令人印象深刻的潜在应用之一。Shor的算法建立在之前的查询复杂性算法之上,并基于两个关键见解:
- 量子傅里叶变换算法可以用来解决阶(和周期)查找的数学问题。
- 因数分解问题可以归约为阶/周期查找问题。
让我们来看一个周期函数:
其中 和 是正整数,且 小于 ,并且它们没有公因数。周期或阶()是满足以下条件的最小(非零)整数:
Shor的解决方案是对酉算子使用量子相位估计:
为了理解这如何有用,让我们看看 的特征态可能是什么样子。如果我们从状态 开始,我们可以看到每次应用 都会将寄存器的状态乘以 (模 ),并且在应用 次后,我们将再次到达状态 。例如,当 和 时:
因此,这个循环中的状态叠加态()将是 的特征态:
这个特征态的特征值为1,这并不是很有趣。一个更有趣的特征态可能是每个计算基态的相位都不同的情况。具体来说,让我们看看在第k个状态的相位与k成正比的情况:
当, 时,我们可以看到这个特征态的形式:
(我们可以看到相位的分母中出现了 。)
这是一个特别有趣的特征值,因为它包含了 。实际上,必须包含 以确保 个计算基态之间的相位差是相等的。这并不是唯一具有这种行为的特征态;为了进一步推广这一点,我们可以将一个整数 乘以这个相位差,这将在我们的特征值中体现出来:
我们现在对于每个整数 (其中 )都有一个唯一的特征态。非常方便的是,如果我们将所有这些特征态相加,不同的相位会抵消掉所有的计算基态,除了 :
为此,我们将看一个较小的例子,其中 且 。在这种情况下,:
由于计算基态 是这些特征态的叠加,这意味着如果我们使用状态 对 进行量子相位估计(QPE),我们将测量一个相位:
其中 是 到 之间的一个随机整数。我们最终使用算法在 上找到 。
- 并不是所有的因数分解问题都很难;我们可以立即发现一个偶数,并知道它的一个因数是2。实际上,选择难以分解的数字有特定的标准,但基本思路是选择两个大素数的乘积。
- 一个通用的因数分解算法首先会检查是否有因数分解的捷径(这个数是偶数吗?这个数是 的形式吗?),然后在最坏的情况下使用 Shor 的周期查找算法。由于我们旨在关注算法的量子部分,我们将直接跳到 是两个素数的乘积的情况。
- 第一步是选择一个介于 和 之间的随机数 。我们可以选择 ,它不是 的非平凡因数(如果是,则将 除以这个 并重新开始)。
- 接下来,我们对 和 进行 Shor 的阶数查找算法。记住,我们测量的相位将是 ,其中并且 是 到 之间的一个随机整数。如果 不是偶数,我们不能继续,必须尝试不同的 值。
- 现在我们有了 ,我们可能可以用它来找到 的一个因数。因为:那么:这意味着 必须整除 。如果 也是偶数,那么我们可以写成:那么 和 或 的最大公约数很可能是 的一个适当因数。如果在最后一步中,我们通过连分数算法找到 。那么我们有:10 和 15 的(非平凡)最大公约数是 5,12 和 15 的(非平凡)最大公约数是 3。然后我们可以验证 ,表明我们已经成功地将 15 分解为 5 和 3。
为了解释阶数查找问题以及如何使用相位估计来解决它,解释一些数论中的基本概念并引入一些方便的符号将非常有帮助。
首先,对于任何给定的正整数 ,我们定义一个集合:
例如,,,,等等。
这些是数字的集合,但我们可以将它们看作不仅仅是集合。特别地,我们可以考虑在 上的算术运算,例如加法和乘法——如果我们同意总是取模 的结果,那么当我们执行这些运算时,我们将始终保持在这个集合内。(加法和乘法这两个特定的运算,都是取模 的,将 变成一个环,这是代数中一种基本重要的对象。)
例如,3 和 5 是 的元素,如果我们将它们相乘,我们得到 ,除以 7 余 1。
有时我们将其表示如下:
但我们也可以简单地写成 ,前提是已经明确我们在 中工作,以使我们的符号尽可能简单和清晰。
例如,以下是 的加法和乘法表:
加法表:
乘法表:
在 的 个元素中,满足 的元素 是特殊的。通常包含这些元素的集合用星号表示,如下所示:
如果我们将注意力集中在乘法运算上,集合 形成一个群——特别是一个阿贝尔群——这是代数中另一种重要的对象。关于这些集合的一个基本事实(实际上关于有限群的一般事实)是,如果我们选择任何元素 并反复将 自乘,我们最终总会得到数字 1。
举个例子,设 。我们有 ,因为 ,并且如果我们将 5 自乘,我们得到 1(如上表所示)。
再举一个例子,设 。如果我们遍历从 0 到 20 的数字,这些是与 21 的最大公约数等于 1 的数字:
对于这些元素中的每一个,都可以将该数字提升到一个正整数幂以得到 1。
以下是这些元素满足条件的最小幂次:
自然地,我们在所有这些方程中都在 中工作,我们没有写出来——我们认为这是隐含的,以避免使事情变得混乱。在整个课程中,我们将继续这样做。
你可以检查上面的每一个方程,以及这些是使方程成立的最小正整数幂次,使用以下代码单元(根据需要更改数字)。
N = 21
a = 17
max_power = 12
print("k \t a^k \n ")
for k in range(1, max_power+1):
print(f"{k} \t {a**k % N}")
注意,在我们回到 1 之后,循环重复——这是有道理的,因为将 1 乘以 会将我们带回 ,这是我们开始的地方。
虽然这对于课程的目的并不是必需的,但我们也可以检查当 时,我们永远不会回到 1——所以我们依赖于 这一事实来使其工作。
现在我们可以陈述阶数查找问题。
输入:正整数 和 ,满足
输出:最小的正整数 ,使得
或者,用我们刚才介绍的符号来说,我们给定 ,并且我们正在寻找最小的正整数 ,使得 。这个数 被称为 模 的阶数。
为了将阶数查找问题与相位估计联系起来,让我们考虑一个系统上的操作,其经典状态对应于 ,我们通过一个固定的元素 进行乘法。
需要明确的是,我们在 中进行乘法,所以在方程右侧的态矢量中隐含地取模 。例如,如果 且 ,我们有:
只要 ,这就是一个酉操作。它将标准基态 的元素重新排列,因此作为矩阵,它是一个置换矩阵。从其定义可以看出,这个操作是确定性的,一个简单的方法来证明它是可逆的就是考虑 模 的阶数 ,并认识到 的逆是 。
还有另一种不需要任何 知识的方法来考虑逆——毕竟,这是我们试图计算的。对于每个元素 ,总有一个唯一的元素 满足 。我们将这个元素 表示为 ,并且可以高效地计算出来。(欧几里得最大公约数算法的扩展在 的平方成本下完成。)因此,
因此,操作 是确定性的和可逆的。这意味着它由一个置换矩阵描述,因此是酉的。
现在让我们考虑操作 的特征向量和特征值,假设 。正如刚才所论证的,这一假设告诉我们 是酉的。 有 个特征值,可能包括重复多次的相同特征值,通常在选择相应的特征向量时有一定的自由度——但我们不需要担心所有的可能性。让我们从简单的开始,先确定 的一个特征向量。
这里的 是 模 的阶数——在本文的其余部分也是如此。与此特征向量相关的特征值是 1,因为当我们乘以 时它不会改变。
这是因为 ,所以每个标准基态 被移到 ,对于 ,并且 被移回到 。非正式地说,就像我们在慢慢搅拌 ,但它已经完全搅拌好了,所以没有任何变化。
这是 的另一个特征向量。在阶数查找和相位估计的背景下,这个特征向量更有趣。
或者,我们可以用求和来写这个向量,如下所示:
这里我们看到复数 自然地出现了,这是由于模 乘法的底层结构。这次相应的特征值是 。为了看到这一点,我们可以首先这样计算:
然后,因为 并且 ,我们看到
所以 。
使用相同的推理,我们可以确定 的其他特征向量/特征值对。实际上,对于任何选择的 ,我们有
是 的一个特征向量,其相应的特征值是 。
还有其他特征向量,例如 ,其特征值为 1,但我们只关心我们刚刚确定的特征向量 。
为了对给定的 解决阶数查找问题,我们可以将相位估计过程应用于操作 。为此,我们不仅需要用量子电路高效地实现 ,还需要实现 、、 等,直到获得足够精确的估计。这里我们将解释如何做到这一点,并稍后确定需要多少精度。
让我们从操作 本身开始。自然地,因为我们使用量子电路模型,我们将使用二进制表示法来编码 到 之间的数字。我们需要编码的最大数字是 ,所以我们需要的位数是:
例如,如果 ,我们有 。以下是 的元素作为长度为 5 的二进制字符串的编码:
现在,以下是 作为一个 量子比特操作的精确定义:
关键是,虽然我们只关心 如何作用于 ,但我们确实需要指定它如何作用于剩余的 个标准基态——我们需要以仍然给我们一个酉操作的方式来做到这一点。定义 使其对剩余的标准基态不做任何操作可以实现这一点。
使用上一课中讨论的整数乘法和除法算法,以及它们的可逆、无垃圾实现方法,我们可以构建一个量子电路来执行 ,对于任何选择的 ,其成本为 。以下是实现这一点的一种方法。
我们构建一个电路来执行操作:
其中
使用在 Qiskit 教程 中描述的方法。这给我们一个大小为 的电路。
- 我们使用 个交换门逐个交换量子比特来交换两个 量子比特系统。
- 类似于第一步,我们可以构建一个电路来执行操作:其中 是 在 中的逆。
通过初始化底部的 个量子比特并组合这三个步骤,我们得到以下变换:
我们得到的电路的总成本是 。
为了执行 、、 等操作,我们可以使用完全相同的方法,只需将 替换为 、、 等作为 的元素。也就是说,对于我们选择的任何幂 ,我们可以通过计算 ,然后使用 的电路来创建 的电路,而不是迭代 的电路 次。
计算 的幂是上一课中提到的模幂运算问题。这个计算可以通过使用模幂运算法(在计算数论中通常称为幂算法)在经典计算机上完成。这次我们不需要用量子电路可逆地实现这个算法,只需要在经典计算机上完成它。
我们很幸运这是可能的。我们实际上将迭代 大量次的问题(这可能是我们在相位估计中选择的数 的指数级)卸载到一个高效的经典计算中。就我们运行的量子电路而言, 迭代 次的成本只是 的成本,对于 ——因此成本是 。
对于相位估计问题中任意选择的量子电路,这通常是不可能的,导致相位估计的成本是我们在相位估计中使用的数 的指数级。通过计算数论的力量,在当前情况下的成本是 的线性级。
为了理解如何使用相位估计来解决阶数查找问题,让我们从假设我们在操作 上运行相位估计过程并使用特征向量 开始。事实证明,获得这个特征向量并不容易,所以这不会是故事的结尾——但从这里开始是有帮助的。 对应于特征向量 的特征值是
也就是说,,其中 。因此,如果我们在 上运行相位估计过程并使用特征向量 ,我们将得到 的近似值。通过计算倒数,我们将能够知道 ——前提是我们的近似值足够好。
更准确地说,当我们使用 个控制量子比特运行相位估计过程时,我们得到一个数字 ,我们将 作为 的猜测,在这种情况下是 。为了从这个近似值中找出 ,自然的做法是计算我们的近似值的倒数并四舍五入到最接近的整数。
例如,假设 ,我们使用特征向量 在 上执行相位估计,使用 个控制比特。 的最佳 5 位近似值是 ,我们有很大的机会(在这种情况下约为 68%)从相位估计中得到结果 。我们有
四舍五入到最接近的整数得到 6,这是正确答案。
另一方面,如果我们使用的精度不够,我们可能得不到正确答案。例如,如果我们在相位估计中使用 个控制量子比特,我们可能得到 的最佳 4 位近似值,即 。取倒数得到
四舍五入到最接近的整数得到错误答案 5。
我们需要多少精度才能得到正确答案? 我们知道阶数 是一个整数,直观地说,我们需要足够的精度来区分 与附近的可能值,包括 和 。我们需要关注的最接近 的数字是 ,这两个数字之间的距离是
因此,如果我们想确保不将 误认为 ,只需使用足够的精度来保证最佳近似 到 比到 更接近。如果我们使用足够的精度,使得
这样误差小于 和 之间距离的一半,那么 将比任何其他可能值(包括 和 )更接近 。
我们可以如下双重检查这一点。假设
对于满足
的 。当我们取倒数时,我们得到
通过在分子中取最大值并在分母中取最小值,我们可以如下界定我们与 的距离。
我们距离 小于 ,因此如预期的那样,我们在四舍五入时会得到 。
不幸的是,因为我们还不知道 是多少,我们不能用它来告诉我们需要多少精度。我们可以做的是利用 必须小于 这一事实来确保我们使用足够的精度。特别地,如果我们使用足够的精度来保证最佳近似 到 满足
那么当我们取倒数时,我们将有足够的精度来正确确定 。
取 可以确保我们有很大的机会使用前面描述的方法获得具有这种精度的估计。(如果我们对成功概率的下限为 40% 感到满意,那么取 就足够了。)
正如我们刚才所看到的,如果我们有 的特征向量 ,我们将能够通过相位估计来了解 ,只要我们使用足够的控制量子比特来获得足够的精度来做到这一点。不幸的是,获得特征向量 并不容易,所以我们需要找出如何继续。
假设我们像上面一样进行,只是用特征向量 代替 ,对于我们选择考虑的任何 。我们从相位估计过程中得到的结果将是一个近似值
在假设我们不知道 或 的情况下,这可能会或可能不会允许我们识别 。例如,如果 ,我们将得到一个接近 0 的近似值 ,这不幸地告诉我们什么都没有。然而,这是一个不寻常的情况;对于其他 值,我们至少能够了解一些关于 的信息。
我们可以使用一种称为连分数算法的算法将我们的近似值 转换为附近的分数——如果近似值足够好,包括 。我们不会在这里解释连分数算法。相反,这里是关于该算法的一个已知事实的陈述。
给定一个整数 和一个实数 ,最多有一个整数对 满足 且 ,并且满足 。给定 和 ,连分数算法找到 和 (或者报告它们不存在)。
该算法可以实现为大小为 的布尔电路。
如果我们有一个非常接近的近似值 到 ,并且我们为 和 运行连分数算法,我们将得到 和 ,如事实中所述。仔细阅读该事实使我们得出结论:
因此,我们不一定能知道 和 ,我们只知道最简形式的 。
例如,正如我们已经注意到的,我们不会从 中学到任何东西。但这是唯一一个发生这种情况的 值。当 非零时,它可能与 有公因数——但我们从连分数算法中得到的数 必须能整除 。
这并不明显,但这是一个已知的事实,如果我们有能力学习 和 ,对于 ,其中 是均匀随机选择的,那么我们很可能在几次采样后恢复 。特别地,如果我们对 的猜测是我们观察到的所有 值的最小公倍数,那么我们很可能是正确的。一些 值不好,因为它们与 共享公因数,当我们学习 和 时,这些公因数对我们是隐藏的。但随机选择的 不太可能长时间隐藏 的因数,并且我们猜测 不正确的概率随着样本数量的增加而指数下降。
到目前为止,我们还没有解决如何获得 的特征向量 来运行相位估计过程的问题。事实证明,我们不需要创建它们。我们将做的是在状态 上运行相位估计过程,这里的 是数字 1 的 n 位二进制编码,代替 的特征向量 。
到目前为止,我们已经讨论了在特定特征向量上运行相位估计过程,但没有什么能阻止我们在不是 特征向量的输入状态上运行该过程,这就是我们在这里用状态 所做的。(除非 ,否则 的 没有 作为特征向量,这是我们将避免的 的选择。)
以下方程有助于解释为什么我们选择状态 代替特征向量:
通过将右侧与标准基态的内积并使用前面提到的公式可以验证这一点。
更详细地说,假设我们用状态 代替特征向量 运行相位估计过程。在执行量子傅里叶变换后,这使我们得到状态:
其中
表示在执行量子傅里叶变换的逆变换后顶部 个量子比特的状态。因此,当测量顶部 个量子比特时,我们得到一个近似值 到 ,其中 是均匀随机选择的。
正如我们已经讨论过的,这使我们在几次独立运行后能够以很高的置信度了解 ,这是我们的目标。
实现每个受控幺正操作 的成本是 。有 个受控幺正操作,因此受控幺正操作的总成本是 。此外,我们有 个 Hadamard 门(其成本为 ),量子傅里叶变换的成本为 。因此,受控幺正操作的成本主导了整个过程的成本——因此总成本为 。
除了量子电路本身,还有一些需要执行的经典计算。这包括在 中计算幂 ,其中 ,这些是创建受控幺正门所需的,以及将 的近似值转换为分数的连分数算法。在这两种情况下,这些计算都可以通过成本为 的布尔电路来执行。
通常,所有这些界限都可以使用渐近快速算法来改进;这些界限假设我们使用的是基本算术运算的标准算法。
最后我们需要讨论的是如何通过解决阶数查找问题来帮助我们进行因数分解。这部分完全是经典的——它与量子计算没有特别的关系。
基本思路是,我们想要分解数字 ,并且我们可以递归地进行分解。具体来说,我们可以专注于分裂 的任务,这意味着找到任意两个整数 使得 。如果 是素数,这是不可能的,但我们可以首先使用素性测试算法高效地测试 是否为素数,如果 不是素数,我们将尝试分裂它。一旦我们分裂了 ,我们可以简单地对 和 进行递归,直到我们所有的因数都是素数,并且我们获得 的素数分解。
分裂偶数很容易:我们只需输出 2 和 。 分裂完全幂次也很容易,这意味着数字的形式为 ,其中整数 ,只需近似根 等,并检查附近的整数作为 的嫌疑人。我们不需要超过 步,因为此时根会下降到 2 以下,不会揭示其他候选者。
我们可以做这两件事是很好的,因为阶数查找对偶数或素数幂没有帮助,其中数字 恰好是素数。 如果 是奇数且不是素数幂,阶数查找允许我们分裂 。
输入一个奇数、合数且不是素数幂的整数 。迭代以下步骤:
- 随机选择 。
- 计算 。
- 如果 ,则输出 和 并停止。否则继续下一步,知道 。
- 设 为 模 的阶数。(这里我们需要阶数查找。)
- 如果 是偶数:
- 计算
- 计算 。
- 如果 ,则输出 和 并停止。
- 如果到达此点,迭代未能找到 的因数。
该算法的迭代可能未能找到 的因数。具体来说,这在两种情况下发生:
- 模 的阶数是奇数。
- 模 的阶数是偶数且 。
使用基本数论可以证明,对于随机选择的 ,至少有 1/2 的概率这两种情况都不会发生。事实上,对于 的不同素因数的数量 ,概率最多为 。这就是为什么假设 不是素数幂很重要。假设 是奇数也是必要的,这就是为什么(简单的) 是偶数的情况必须单独处理。
因此,如果我们重复该过程 次,每次随机选择 ,我们将以至少 的概率成功分裂 。
我们不会详细分析这个过程,但这里是基本思路。如果我们选择的 使得 模 的阶数 是偶数,那么考虑数字 和 是有意义的。
使用公式 ,我们得出结论:
根据阶数的定义,我们知道 ,这意味着 整除 。因此, 整除数字 ,这意味着 的每个素因数必须要么整除 ,要么整除 (或两者都整除)。
对于随机选择的 ,我们很可能会有 的素因数同时整除这两个项,这使我们能够通过计算 来分裂 。