6 - 公钥加密介绍

公钥加密介绍

我的博客

原书:《Understanding Cryptography: A Text book for Students and Practitioners》

谁能借我一个能玩明白数论的脑子。

在我们学习公钥加密之前,我们需要介绍数据公钥加密与非对称加密是同一个范畴。

在第一章中介绍过,对称加密至少用了 4000 年了。而公钥加密相较而言,则是十分崭新的产物。在十九世纪七十年代出现。

6.1 对称加密与非对称加密对比

大部分公钥算法基于数论函数。这与对称加密是不同的,对称加密的目标并不是建立输入-输出的精确数学描述。

再看对称加密

在对称加密中,有下面两个特点:

  1. 加密与解密使用相同的密钥
  2. 加密与解密函数十分相似

在对称加密中有下面的几个问题:

密钥分发问题

在发送者与接收者之间必须使用一个安全的信息通道建立密钥。需要牢记的是,通讯链路并不是安全的,因此直接在信息通道上发送密钥是不可行的。

密钥数量问题

即便我们解决了密钥分发问题,我们还要处理海量的密钥。如果网络上 \(n\) 个用户的每一对用户都需要一把独有的密钥,那么需要 \(n\cdot (n-1)/2\) 把密钥,每一个用户必须必须保存好 \(n-1\) 把密钥。

不能防止作弊

发送者与接收者具有相同的能力,因为他们拿着同样的密钥。在电子商务应用这,我们需要证实发送者确实发送了特定的信息,比如一个液晶电视网络订单。如果我们仅使用对称加密,发送者后面改变了主意,那么发送者可以声称,接收者一方既供应商生成了这个 "虚假" 的订单。非对称可以实现这种不可抵赖的特性。

非对称加密原则

为了克服上面提到的对称加密中的缺点,Diffie、Hellman 与 Merkle 提出了一个革命性的提议具有下面的特点:加密信息的那位用户不需要令密钥保密。接收者则使用秘密保护的密钥解密密文。为了实现这样的系统,接收者发布一个公钥,所有人都知道这个公钥。接收者持有这个公钥对应的私钥,并使用这个私钥解密。因此接收者密钥 \(k\) 包含两个部分,公钥部分 \(k_{pub}\) 以及私钥部分 \(k_{pr}\)

此时,我们可以使用公钥加密算法,加密对称加密密钥,比如 AES 密钥。接收者对这一信息解密后,通讯双方就可以进行对称加密通讯了,对称加密比非对称加密更快。

讨论到这里,我们的问题就变成如何构建一个非对称算法。在第七、八与九章中,我们会介绍多个非对称策略。它们都是基于一个通用原则,单向函数,定义如下:

定义 6.1.1 单向函数

如果一个函数 \(f()\) 满足如下条件,那么这个函数是单向函数:

  1. \(y = f(x)\) 可以轻松计算
  2. \(x = f^{-1}(y)\) 不可计算

上面提到的 "轻松计算" 与 "不可计算" 并不准确。在数学术语中,我们可以说 \(y = f(x)\) 计算足够快,而 \(x = f^{-1}\) 在已知算法下计算需要极长时间。在公钥策略中,有两个十分流行的单向函数。第一个是整数因数分解问题,这是 RSA 的基石。给定两个大质数,可以轻松计算质数的积。然而,对这个积进行因数分解是十分困难的。另一个常用的单向函数是离散对数问题。

6.2 公钥加密实践

6.2.1 安全性机制

公钥策略不仅能够进行加密数据。主要功能如下列出:

公钥算法主要安全机制:

密钥建立 通过不安全的通道建立密钥,包括 DHKE 与 RSA 密钥传输协议。

不可抵赖 通过数字签名算法,可以提供不可抵赖性与信息完整性

用户验证 我们可以使用挑战-应答机制以及数字签名,来验证用户,比如银行的智能卡

加密 我们可以使用非对称算法进行加密

需要注意的是,对称运算也可以实现加密与用户验证,但是需要在密钥管理上费更多的功夫。非对称运算好像能够实现所有现代安全协议。即便事实却是如此,它主要的缺点在于,它的加密速度真的太慢了,一些块/流运算的加密速度能够达到公钥算法的上百倍甚至上千倍。因此,略为嘲讽地是,在实践中,很少使用公钥加密策略来进行数据加密。不过,在另一方面,对称运算在进行密钥建立以及信息不可抵赖中是有一点问题的。为了利用对称与非对称运算二者的优点,大部分实践中会使用混杂二者的策略。比如 SSL/TLS、IPsec 等网络安全协议。

6.2.2 剩下的问题:公钥认证

我们是如何确定我们拿到的公钥真的来自于某个人呢?实践中,这通常是通过证书实现的。简而言之,证书将公钥绑定到特定实体。

6.2.3 重要的公钥算法

在前面几章中,我们介绍了几种对称加密算法,除此之外,还有上百其他的对称加密算法。但在非对称运算算法中,情况则大不相同。在实践中,只有三种主要的公钥算法家族,可以归为如下几类:

实践中的公钥算法家族

整数因数分解策略 如 RSA

离散对数策略 如DHKE、DSA

椭圆曲线策略 如 ECDH、ECDSA

前两个家族在十九世纪七十年代中期提出,椭圆曲线策略则在十九世纪八十年代中期提出。如果选择何理的密钥长度、参数与操作数,这些策略都极其难以攻击。需要注意的是,这三个家族都可以提供密钥建立、通过数字签名的不可抵赖性以及对数据的加密等特性。

除了上面三个家族,也有基于其他原理提出的公钥策略,但是它们都无法保证对数学攻击的鲁棒性。

6.2.4 密钥长度与安全性层级

所有三个公钥算法家族都基于数论函数。它们需要不同长度的操作数与密钥长度。不出意外,越长的操作数与密钥,算法安全性越高。为了比较不同算法的安全性,引入安全等级这个概念。如果已知攻击需要 \(2^n\) 步,那么可以称算法安全等级为 n 位。这是十分直观的定义,因为拥有安全等级为 n 的对称算法需要 n 位密钥长度。在非对称加密中,运算强度与安全性并不像对称运算中那样直接。下表展示了不同密钥长度下的安全等级。

算法家族 运算系统 安全等级 80 安全等级 128 安全等级 192 安全等级 256
整数因数分解 RSA 1024 位 3072 位 7680 位 15360 位
离散对数策略 DHDSA 1024 位 3072 位 7680 位 15360 位
椭圆加密策略 ECDHECDSA 160 位 256 位 384 位 512 位
对称密钥量级 AES3DES 80 位 128 位 192 位 256 位

长的操作数意味着更长的计算消耗。三个算法家族的计算复杂度在比特长度变化时,计算量将会以立方级增加,比如在 RSA 中进行签名运算,3076 位的计算量将会是 1024 位计算量的 \(3^3\) 倍。在现代计算机中,10 毫秒到 100 毫秒的计算时长是常见的,但是在一些计算量有限的设备如小的 CPU 上,公钥策略性能将会是一个重要的瓶颈。

6.3 公钥算法的数论知识

6.3.1 欧几里得算法

我们以计算最大公除数问题 gcd: greatest common divisor 开始介绍。两个正整数 \(r_0\)\(r_1\) 的 gcd 表示为:

\[gcd(r_0,r_1) \]

它是同时能整除 \(r_0\)\(r_1\) 的最大除数。比如 \(gcd(21,9) = 3\)。对于比较小的数值,gcd 计算比较简单,可以通过查找各自的因数,进而查找最大的公因数即可。

例 6.1\(r_0 = 84,r_1 = 30\) 有:

\[r_0 = 84 = 2 \cdot 2\cdot 3 \cdot 7 \\ r_1 = 30 = 2\cdot 3\cdot 5 \]

gcd 是所有公共质因数的积:

\[2\cdot 3 = 6 = gcd(30,84) \]

对于在公钥策略中使用的比较大的数值,进行因数分解是比较困难的,计算 gcd 的方法是欧几里得算法。基于下面观测:

\[gcd(r_0,r_1) = gcd(r_0 - r_1,r_1) \]

我们假设 \(r_0 > r_1\),且二者均为正整数。这个特性可以简单证明,令 \(gcd(r_0,r_1) = g\),因为 \(g\) 可以同时整除 \(r_0\)\(r_1\),有 \(r_0 = g\cdot x\) 以及 \(r_1 = g\cdot y\),其中 \(x > y\),且 \(x\)\(y\) 互质,既,它们没有公因数。另外,\((x-y)\)\(y\) 也互质。且有:

\[gcd(r_0 - r_1, r_1) = gcd(g\cdot(x-y),g\cdot y) = g \]

例 6.2 依然令 \(r_0 = 84,r_1 = 30\)

\[r_0 - r_1 = 54 = 2\cdot 3\cdot 3\cdot 3 \\ r_1 = 30 = 2\cdot 3\cdot 5 \]

马上,我们可以进行如下的迭代:

\[gcd(r_0,r_1) = gcd(r_0-r_1,r_1) = gcd(r_0-2r_1,r_1) = ... = gcd(r_0 - mr_1,r_1) \]

只要 \(r_0 -mr_1 > 0\) 即可。如果我们选择最大的 \(m\),那么算法将进行最少的步骤。这是下面的情况:

\[gcd(r_0,r_1) = gcd(r_0 \quad mod\quad r_1,r_1) \]

因为第一项 \((r_0 \quad mod \quad r_1)\) 比第二项 \(r_1\) 更小,我们交换它们的位置:

\[gcd(r_0,r_1) = gcd(r_1,r_0 \quad mod \quad r_1) \]

通过这个过程,我们可以将从两个较大值中寻找 \(gcd\) 的问题,变成在两个较小的值中寻找 \(gcd\) 的问题。这个过程可以进行迭代,直到我们最后得到 \(gcd(r_1,0) -= r_1\)。因为每次迭代都是一个等式,那么最后一次迭代得到的结果就是最初问题的解:

\[gcd(r_0,r_1) = ... = gcd(r_l,0) = r_l \]

例 6.3\(r_0 = 27,r_1 = 21\)

\[gcd(27,21) = gcd(1\cdot 21 + 6,21) = gcd(21,6) \\ gcd(21,6) = gcd(3\cdot 6 + 3,6) = gcd(6,3) \\ gcd(6,3) = gcd(2\cdot 3 + 0,3) = gcd(3,0) = 3 \]

例 6.4\(r_0 = 973,r_1 = 301\)

\[gcd(973,301) = gcd(3\cdot 301 + 70, 301) = gcd(301,70) \\ gcd(301,70) = gcd(4\cdot 70 + 21,70) = gcd(70,21) \\ gcd(70,21) = gcd(3\cdot 21 + 7,21) = gcd(21,7) \\ gcd(21,7) = gcd(3\cdot 7 + 0,7) = gcd(7,0) \\ gcd(7,0) = 7 \\ gcd(973,301) = 7 \]

现在我们有了欧几里得算法,我们可以给这个算法一个正式的描述:

欧几里得算法

输入:正整数 \(r_0、r_1,r_0 > r_1\)

输出:\(gcd(r_0,r_1)\)

初始化:\(i = 1\)

算法:

\[do \\ \quad \quad \quad \quad \quad i = i+1 \\ \quad \quad \quad \quad \quad \quad \quad \quad \quad \quad r_i = r_{i-2} \quad mod \quad r_{i-1} \\ \quad \quad \quad \quad \quad \quad WHILE(r_i \neq 0) \\ \quad \quad \quad RETURN \\ \quad \quad \quad \quad \quad \quad \quad \quad \quad \ gcd(r_0,r_1) = r_i - 1 \]

注意到,算法在 \(r_i = 0\) 时终止。

6.3.2 扩展欧几里得算法

前面我们看到了寻找两个整数的 \(gcd\) 的方法,欧几里得算法不仅可以用来寻找 \(gcd\)。这个算法的扩展允许我们计算模反,这在公钥运算中十分重要。扩展欧几里得算法 EEA 计算下面形式的线性组合:

\[gcd(r_0,r_1) = s\cdot r_0 + t\cdot r_1 \]

其中 \(s\)\(t\) 为整数系数。这个等式通常称作丢番图方程。

问题变成,我们如何计算两个系数 \(s\)\(t\)。算法背后的思想是,我们进行标准的欧几里得算法,但是我们在每一次迭代中将余数 \(r_i\) 用下面的线性组合表示:

\[r_i = s_i r_0 + t_i r_1 \]

如果我们继续这个过程,我们将得到最后的迭代等式:

\[r_l = gcd(r_0,r_1) = s_l r_0 + t_l r_1 = s r_0 + t r_1 \]

例 6.5\(r_0 = 973,r_1 = 301\),下面我们在左边计算标准的欧几里得算法,在右侧我们计算系数 \(s_i\)\(t_i\) 满足 \(r_i = s_i r_0 + t_i r_1\)

\(i\) \(r_{i-2} = q_{i-1}\cdot r_{i-1} + r_i\) \(r_i = [s_i]r_0 + [t_i]r_1\)
\(2\) \(973 = 3\cdot 301 + 70\) \(70 = [1]r_0 +[-3]r_1\)
\(3\) $301 = 4\cdot 70 + 21 $ \(21 =301 - 4\cdot 70 = r_1 - 4(1r_0 - 3r_1) = [-4]r_0 + [13]r_1\)
\(4\) \(70 = 3\cdot 21 + 7\) \(7 = 70 - 3\cdot 21 = (1r_0 - 3r_1) - 3(-4r_0 + 13r_1) = [13]r_0 + [-42]r_1\)
\(21 = 3\cdot 7 + 0\)

算法计算得到三个参数 \(gcd(937,301) = 7,s = 13,t = -42\),可以一起表示为:

\[gcd(937,301) = 7 = [13]937 + [-42]301 = 12649 - 12642 \]

现在我们在每次迭代时得到递归公式,用来计算 \(s_i\)\(r_i\)。假设我们的迭代步为 \(i\),在前两个迭代我们可以计算:

\[r_{i-2} = [s_{i-2}]r_0 + [t_{i-2}]r_1 \\ r_{i-1} = [s_{i-1}]r_0 + [t_{i-1}]r_1 \]

那么在当前的迭代轮 \(i\),我们首先从 \(r_{i-1}\)\(r_{i-2}\) 中计算商 \(q_{i-1}\) 与新的余数 \(r_i\)

\[r_{i-2} = q_{i-1}r_{i-1} + r_i \]

等式可被重新写为:

\[r_i = r_{i-2} - q_{i-1}\cdot r_{i-1} \]

回到我们的目标,将新的余数 \(r_i\) 表示为 \(r_0\)\(r_1\) 的线性组合。我们可以用前面计算的线性组合替换 \(r_{i-2}\) 以及 \(r_{i-1}\) 得到:

\[r_i = (s_{i-2}r_0 + t_{i-2}r_1) - q_{i-1}(s_{i-1}r_0 + t_{i-1}r_1) \]

对上面的公式进行重新组织,我们可以得到:

\[r_i = [s_{i-2}-q_{i-1}s_{i-1}]r_0 + [t_{i-2}-q_{i-1}t_{i-2}]r_1 \\ r_i = [s_i]r_0 + [t_i]r_1 \]

上面的公式直接给到我们计算 \(s_i\)\(t_i\) 的公式,\(s_i = s_{i-2} - q_{i-1}s_{i-1}\) 以及 \(t_i = t_{i-2} - q_{i-1}t_{i-1}\),这个递归过程在 \(i \geq 2\) 下成立的。像所有的递归那样,我们需要初始值 \(s_0,s_1,t_0,t_1\),这些初始值可以是 \(s_0 = 1,s_1 = 0,t_0 = 0,t_1 = 1\)

扩展欧几里得算法 EEA

输入 正整数 \(r_0,r_1,r_0 > r_1\)

输出 \(gcd(r_0,r_1)\),以及 \(s,t\) 使得 \(gcd(r_0,r_1) = s\cdot r_0 + t \cdot r_1\)

初始化 \(s_0 = 1,t_0 = 1,s_1 = 0,t_1 = 1,i = 1\)

算法

\[DO\\ \quad \quad \quad i = i+1 \\ \quad \quad \quad \quad \quad \quad \quad \quad \quad r_i = r_{i-2}\quad mod \quad r_{i-1} \\ \quad \quad \quad \quad \quad \quad \quad \quad \quad q_{i-1} = (r_{i-2} - r_i)/r_{i-1} \\ \quad \quad \quad \quad \quad \quad \quad \quad \quad s_i = s_{i-2} - q_{i-1}\cdot s_{i-1} \\ \quad \quad \quad \quad \quad \quad \quad \quad t_i = t_{i-2} - q_{i-1}\cdot t_{i-1} \\ \quad \quad \quad \quad \quad WHILE \quad r_i \neq 0 \\ \quad \quad RETURN \\ \quad \quad \quad \quad \quad \quad \quad gcd(r_0,r_1) = r_{i-1} \\ \quad \quad \quad s = s_{i-1} \\ \quad \quad \quad t = t_{i-1} \]

就像在前面提到的,EEA 的主要应用是在非对称加密中计算一个整数的模反。我们已经在第一章的仿射运算中遇到过这个问题了,对于仿射运算,我们需要找到密钥 a 模 26 的模反。使用欧几里得算法,这是比较直观的。让我们假设我们希望计算 \(r_1 \quad mod\quad r_0,r_1 < r_0\) 的模反,第一章中已提到过只有在 \(gcd(r_0,r_1) = 1\) 时模反才存在。因此,如果我们应用 EEA,我们得到 \(s\cdot r_0 + t\cdot r_1 = 1 = gcd(r_0,r_1)\),令这个等式模 \(r_0\) 我们得到:

\[s\cdot r_0 + t\cdot r_1 = 1 \\ s\cdot 0 + t\cdot r_1 \equiv 1 \quad mod \quad r_0 \\ r_1 \cdot t \equiv 1 \quad mod \quad r_0 \]

上面的式子中明确定义了 \(r_1\) 的模反:

\[t = r_1^{-1} \quad mod \quad r_0 \]

因此,如果我们需要计算模反 \(a^{-1} \quad mod \quad m\),我们使用 EEA 算法,输入参数为 \(m\)\(a\),输出 \(t\) 就是我们的期望值。

例 6.6 我们的目标是计算 \(12^{-1} \quad mod \quad 67\),12 与 67 互质,既 \(gcd(61,12) = 1\),如果我们使用 EEA,我们得到 \(gcd(67,12) = 1 = s\cdot 67 + t \cdot 12\) 的系数 \(s\)\(t\)

\(i\) \(q_{i-1}\) \(r_i\) \(s_i\) \(t_i\)
2 5 7 1 -5
3 1 5 -1 6
4 1 2 2 -11
5 2 1 -5 28

我们得到线性表达:

\[-5 \cdot 67 + 28 \cdot 12 = 1 \]

这样,我们得到 12 的模反:

\[12 ^{-1} \equiv 28 \quad mod \quad 67 \]

这一结论可以轻松证明:

\[28 \cdot 12 = 336 \equiv 1 \quad mod \quad 67 \]

我们一般不需要 \(s\) 系数,所以在实践过程中并不会计算这个系数。

EEA 也可以用来计算伽罗瓦域的乘法逆元。这与 AES 算法中的 S 盒以及椭圆曲线的公钥算法有关。EEA 完全可以用来分析多项式。如果我们希望计算一个有限域 \(GF(2^m)\) 的逆,输入给算法的是域元素 \(A(x)\) 以及不可约多项式 \(P(x)\),EEA 计算辅助多项式 \(s(x)\)\(t(x)\),最大公共除数 \(gcd(P(x),A(x))\),有:

\[s(x)P(x) + t(x)A(x) = gcd(P(x),A(x)) = 1 \]

因为 \(P(x)\) 是不可约的,\(gcd\) 总等于 1。相似的,有辅助多项式 \(t(x)\)\(A(x)\) 的逆:

\[s(x)0 + t(x)A(x) \equiv 1 \quad mod \quad P(x) \\ t(x) \equiv A^{-1}(x) \quad mod \quad P(x) \]

例 6.7 我们希望在有限域 \(GF(2^3)\) 中寻找 \(A(x) = x^2\) 的逆,不可约多项式为 \(P(x) = x^3 + x + 1\)\(t(x)\) 的初始值为 \(t_0(x) = 0\)\(t_1(x) = 1\)

迭代 $r_{i-2}(x) = $ \([q_{i-1}(x)]r_{i-1}(x) + [r_i(x)]\) \(t_i(x)\)
2 \(x^3 + x + 1\) \([x]x^2 + [x+1]\) \(t_2 = t_0 - q_1 t_1 = 0 - x1 \equiv x\)
3 \(x^2\) \([x](x+1) + [x]\) \(t_3 = t_1 - q_2 t_2 = 1 - x(x) \equiv 1 + x^2\)
4 \(x+1\) \([1]x+[1]\) \(t_4 = t_2 - q_3 t_3 = x - 1(1 + x^2)\)
5 \(x\) \([x]1 + [0]\)

最后,可以计算得到逆 \(t_4(x)\)

\[A^{-1}(x) = t(x) = t_4(x) = x^2 + x + 1 \]

下面我们检验一下逆关系确实成立,这里我们会用到 \(x^3 \equiv x + 1 \quad mod \quad P(x)\) 以及 \(x^4 \equiv x^2 +x \quad mod \quad P(x)\)

\[t_4(x)\cdot x^2 = x^4 + x^3 + x^2 \\ \equiv (x^2 + x) + (x + 1) + x^2 \quad mod \quad P(x) \\ \equiv 1 \quad mod \quad P(x) \]

6.3.3 欧拉 Phi 函数

我们现在看另一个在公钥加密系统中使用的工具。我们考虑环 \(Z_m\) 是集合 \({0,1,...,m-1}\)。我们对这个集合中有多少数与 \(m\) 互质感兴趣。这可以使用欧拉 Phi 函数计算:

定义 6.3.1 欧拉 Phi 函数

\(Z_m\) 中与 \(m\) 互质的整数数量表示为 \(\phi(m)\)

例 6.8\(m = 6\),集合为 \(Z_6 = \{0,1,2,3,4,5\}\)

\[gcd(0,6) = 6 \\ gcd(1,6) = 1 \\ gcd(2,6) = 2 \\ gcd(3,6) = 3 \\ gcd(4,6) = 2 \\ gcd(5,6) = 1 \]

在这个集合中,有两个数与 6 互质,那么有 \(\phi(6) = 2\)

例 6.9\(m = 5\),集合为 \(Z_5 = \{0,1,2,3,4\}\)

\[gcd(0,5) = 5 \\ gcd(1,5) = 1 \\ gcd(2,5) = 1 \\ gcd(3,5) = 1 \\ gcd(4,5) = 1 \\ \]

在这个集合中,有四个数与 5 互质,那么有 \(\phi(5) = 4\)

像上面这样简单穷举所有的 \(gcd\) 的方式是低效的。幸运地是,如果我们知道 \(m\) 的因数分解,存在一种关系,可以更加简单计算我们想要的结果。

定理 6.3.1\(m\) 具有下面的规范因数

\[m = p_1^{e_1}\cdot p_2^{e_2}\cdot ... \cdot p_n^{e_n} \]

其中 \(p_i\) 为不同的质数,\(e_i\) 为正整数,那么有:

\[\phi(m) = \prod_{i=1}^n(p_i^{e_i} - p_i^{e_i - 1}) \]

因为 \(n\) 是不同的质因子的数量,即便 \(m\) 的数值很大,\(n\) 也很小。

例 6.10\(m = 240\),240 的典型因数可以表示为:

\[m = 240 = 16\cdot 15 = 2^4 \cdot 3 \cdot 5 = p_1^{e_1}\cdot p_2^{e_2}\cdot p_3^{e_3} \]

这里有三个不同的质因子,可知 \(n = 3\),欧拉 phi 函数有:

\[\phi(m) = (2^4 - 2^3)(3^1 - 3^0)(5^1 - 5^0) = 8\cdot 2\cdot 4 = 64 \]

这意味着,在 \({0,1,...,239}\) 集合中,有 64 个整数与 \(m = 240\) 互质。

需要注意的是,为了快速计算欧拉 phi 函数,我们需要知道 \(m\) 的因数分解。这在 RSA 算法的核心,如果我们知道某个数的因数分解,我们可以计算欧拉 phi 函数并解密密文,相反,如果我们不知道这个数的因数分解,那么我们不能计算欧拉 phi 函数,且不能解密。

6.3.4 费马小定理以及欧拉定理

下面我们介绍在公钥算法中十分重要的定理。

首先是费马小定理。

定理 6.3.2 费马小定理

\(a\) 是一个整数,\(p\) 为一个质数,那么:

\[a^p \equiv a\quad (mod \quad p) \]

算法在有限域 \(GF(p)\) 是模 \(p\) 的,因此,在有限域 \(GF(p)\) 中,定理可以表示为下面的形式:

\[a^{p-1} \equiv 1 \quad (mod \quad p) \]

这个公式在运算中是十分重要的,一个应用是计算一个有限域的逆,我们可以重写等式为 \(a\cdot a^{p-2} \equiv 1\quad (mod \quad p)\),这样,我们马上可以计算得到 \(a\) 对一个质数的模逆:

\[a^{-1} \equiv a^{p-2}\quad(mod \quad p) \]

需要注意的是,上面计算模逆的方法仅在 \(p\) 为质数时有效。

例 6.11\(p = 7,a = 2\),我们可以计算 \(a\) 的逆:

\[a^{p-2} = 2^5 = 32 \equiv 4\quad mod \quad 7 \]

易于证明:

\[2\cdot 4 \equiv 1 \quad mod \quad 7 \]

第二个定理是一般化的费马小定理,欧拉定理。

定理 6.3.3 欧拉定理

\(a\)\(m\) 为整数,\(gcd(a,m) = 1\),那么:

\[a^{\phi(m)}\equiv 1\quad(mod \quad m) \]

例 6.12\(m = 12,a = 5\),首先我们计算 \(m\) 的欧拉 phi 函数

\[\phi(12) = \phi(2^2\cdot 3)=(2^2 - 2^1)(3^1 - 3^0) = (4-2)(3-1) = 4 \]

现在我们可以校验欧拉定理:

\[5^{\phi(12)} = 5^4 = 25^2 = 625 \equiv 1 \quad mod \quad 12 \]

费马小定理是欧拉定理的特例。如果 \(p\) 是一个质数,\(\phi(p) = (p^1 - p^0) = p - 1\),如果我们在欧拉定理中使用这个值,我们可以得到 \(a^{\phi(p)} = a^{p-1}\equiv 1\quad (mod \quad p)\),既费马小定理。

posted @ 2023-03-21 22:51  ArvinDu  阅读(168)  评论(0编辑  收藏  举报