Bintou's Blog

Reader, Writer and Thinker.

0%

引言

中国剩余定理用于高效求解一元同余方程组,基本所有标准数论书都会讲解。之所以本博客还有存在的价值,是因为本人认为学习一个定理的最好方式是重新发现该定理。还有,在教学过程中,学生们总问,“为什么数学家们会想到这样的定理”,诸如此类的问题。我试图展示,即使是非常著名的大定理可能也只是源自于正常的思路,并不神秘。以下内容试图达到以上两个小目标,如果读者能从中找到一点乐趣就善莫大焉咯。

阅读本文的基础包括:模算术运算、同余理论、费尔马小定理、欧拉定理以及扩展欧几里得算法。也许阅读本文只需要一点点时间,不大好估计,因为实在是很简单。

求解一元同余方程组

先看求解一元同余方程组的实例,假定需要解以下方程组: \[\begin{eqnarray*} x &\equiv& 2 \pmod{5} \\ x &\equiv& 3 \pmod{7} \end{eqnarray*}\]

有一种平凡的解决方法如下:

  • 从一个同余式中得到\(x = 5t + 2\)\(t \in \mathbb{N}\)

  • \(x\)代入第二个同余式得到:$ 5t + 2 $;

  • 整理可得:\(5t \equiv 1 \pmod{7}\)

  • 上式两边同乘\(5^{-1}\)得到\(t = 7s + 3\)\(s \in \mathbb{N}\)

  • 最后,\(x = 35s + 17\),即\(x \equiv 17 \pmod{35}\)

以上例子告诉我们,解同余方程组是非常简单的工作。然而,从算法的角度看,这不是一种好的解法。中国剩余定理给出了一种简洁、高效的解决方案。

中国剩余定理--数论角度

对任意的一元同余方程组,中国剩余定理(Chinese Remainder Theorem,简记为CRT), 告诉我们,对特定的模数总是有唯一解,并给出了一种高效的求解方法。先看以下定理的描述。

中国剩余定理

\(p\)\(q\)是互素的两个正整数,\(n = pq\)。对任意的\(a \in \mathbb{Z}_p\)\(b \in \mathbb{Z}_q\),存在 唯一解\(x\)\(0 \leq x < n\)使得: \[\begin{eqnarray*} x &\equiv& a \pmod{p}\\ x &\equiv& b \pmod{q}\end{eqnarray*} \]

然而,在给出整个定理证明之前,让我们试图重新“发明”这个定理的证明。希望在这一节当中,读者可以享受到发明定理的乐趣,这比读懂一个证明要快乐得多。所以,在我提示大家要停下来思考的时候,请尽量跟我的节奏走。

我们的任务是解以上两个同余方程,让我们先考察其中一个同余式。比如,设\(p\)为一个整数,对任意的\(a \in \mathbb{Z}_p\), 所要求解的\(x\)要满足方程 \[x \equiv a \pmod{p}\] 那么,\(x\)应该长什么模样?答案之一,当然是存在\(k\in \mathbb{Z}\),使得\(x = a +kp\)。这是之前例子的方法。还有没有其他答案?

其实,求解\(x\)是要问,给定\(a\)\(p\),在模\(p\)的情况下,什么数会与\(a\)同余?或者说,试图找一个值\(a'\),使得 \[ a a' \equiv a \pmod{p}\] 第一印象应该是选一个模\(p\)等于\(1\)的数\(a'\),当然\(a'\)不能简单地等于1。

大家能回顾一下线性代数中相似矩阵的定义吗?对两个\(n\times n\)矩阵\(A\)\(B\),如果存在一个可逆的\(n\times n\)矩阵\(C\)使得: \[A = C^{-1}BC\] 则称\(A\)\(B\)为相似矩阵。回到同余式\(x \equiv a \pmod{p}\),我们能发现\(x\)\(a\)相似数吗?建议读者在此处暂停阅读,自己思考一段时间。

继续刚才的问题,对于整数\(a\),在可逆矩阵的启发下,对应的可逆数(与相似矩阵的可逆矩阵对应)难道不应该是模\(p\)下互为乘法逆元的整数\(c\)\(c^{-1}\)吗?也就是说,对任意的\(c\in \mathbb{N}\),如果\(gcd(c,p)=1\),则存在唯一乘法逆元\(c^{-1}\in \mathbb{N}\),使得\(c c^{-1} \equiv 1 \pmod{p}\)。如果\(x = c c^{-1} a\),称整数\(x\)\(a\)相似。为什么相似,因为\(x\)\(a\)\(p\)同余,且不等。注意,给定\(a\),可以构造多个不同的\(x\)与之相似。

对于满足两个同余式\(x \equiv a \pmod{p}\)\(x \equiv b \pmod{q}\)的解\(x\),大致形式应该是既与\(a\)相似又与\(b\)相似。 分别相似并不难构造,难点是同时满足相似性。比如令\(x = c_1 c_1^{-1}a + c_2c_2^{-1}b\),其中\(c_1 c_1^{-1} \equiv 1 \pmod{p}\)\(c_2 c_2^{-1} \equiv 1 \pmod{q}\)。现在\(x\)\(p\)会得到\(a\),但是$ c_2 c_2^{-1} b$多出来的部分不知道是什么,不大可能是\(0\)\(x\)\(q\)会得到\(b\), 但是又多出了\(c_1 c_1^{-1}a\)。怎么解决?也就是说,在模\(p\)(或者模\(q\))的同时要使那些讨厌的部分消失。怎么能做到? 建议读者在此处暂停阅读,自己思考一段时间。

相信答案并不难得到。如果把\(c_2c_2^{-1}b\)这一项中的\(c_2\)人为设置为\(p\),在模\(p\)的时候,这一项就被消去了。 同理,把\(c_1c_1^{-1}a\)这一项中的\(c_1\)人为设置为\(q\)即可。这也大致解释了,为什么定理的条件需要\(p\)\(q\)互素。 如果你想出来了,恭喜你,请看以下证明。以下定理与证明都是教科书式的东西,如果懂了可以跳过,没有什么特别的内容。

中国剩余定理的证明

使用构造法。因为\(p\)\(q\)互素,则存在\(p^{-1}\)\(q^{-1}\) 分别使得\(p p^{-1} \equiv 1 \pmod{q}\)\(qq^{-1} \equiv 1 \pmod{p}\)。 令整数\(x\)为: \[ x = a q q^{-1} + b p p^{-1} \] 容易验证,\(x\)同时满足两个同余式。最后需要证明在模\(n = pq\)情况下,\(x\)是唯一解。即需要证明如果存另一个解,它也必然与\(x\)\(n\)同余。假设\(\exists y \neq x\)是另一个解,则存在\(t \in \mathbb{N}\)使得\((y - x ) = tp\)。此时是把\(x\)\(y\)理解为\(a + kp\)的形式。类似,如果把\(x\)\(y\)理解为\(b + kq\)的形式,则存在\(s \in \mathbb{N}\)使得\((y - x ) = sq\)。因为\(p\)\(q\)互素,则存在某个\(k \in \mathbb{N}\),使得\((y - x) = kpq\)。因此,\(y \equiv x \pmod{n}\)。证完!

中国剩余定理--推广版

\(m_1, m_2, \cdots, m_n\)是两两互素的整数,对以下\(n\)个同余式的同余方程组 \[\begin{eqnarray*} x &\equiv& a_1 \pmod{m_1}\\ &\cdots& \\ x &\equiv& a_n \pmod{m_n}\end{eqnarray*}\] 存在模\(M\)的唯一解,其中\(M = m_1 m_2 \cdots m_n\)

中国剩余定理--推广版的证明

构造法。令\(M= \prod_{i = 1}^{n} m_i\),记\(b_i = M/m_i\)。 存在\(b_i ^{-1}\)使得\(b_i b_i ^{-1} \equiv 1 \pmod{m_i}\)。则 \[x = \sum_{i=1}^{n} a_i b_i b_i^{-1}\pmod{M}\] 是方程组的唯一解。

斌头剩余定理

本博客有意思的部分开始了!或者也可以说是最没意思的部分,因为以下内容不会出现在标准教科书当中。稍微把中国剩余定理的要求增强一点点,要求同余方程组的模数分别是不同的素数,然后可以继续大开脑洞,请跟上思路。

在证明中国剩余定理的时候我们问:给定\(a\)\(p\),找一个值\(a'\),使得 \[ a a' \equiv a \pmod{p}\] 利用乘法逆元构造一个\(1\)并不是唯一选择。费尔马小定理告诉我们,如果\(p\)是素数,存在\(c\in \mathbb{Z}\)\(gcd(c,p)=1\)使得: \[ c^{p-1} \equiv 1 \pmod{p}\] 所以,使用某个数\(b\)\(p-1\)次方也能构造出一个\(a\)的相似数。那么,构造出来的\(x\)大致可以是这个形式: \[a c_1^{p-1} + bc_2^{q-1}\] 请问,\(c_1\)\(c_2\)分别选择什么可以使得同余方程组得到满足呢?

有了以上的经验,答案很容易想到:分别取\(q\)\(p\)即可。于是我们很可能会得到一个斌头剩余定理

斌头剩余定理--初始化版本

\(p\)\(q\)是不等的两个素数,\(n = pq\)。对任意的\(a \in \mathbb{Z}_p\)\(b \in \mathbb{Z}_q\),存在 唯一解\(x\)\(0 \leq x < n\)使得: \[\begin{eqnarray*}x &\equiv& a \pmod{p}\\ x &\equiv& b \pmod{q}\end{eqnarray*}\]\(x = (a q^{p-1} + b p^{q-1}) \bmod{n}\)

请验证该定理是否成立?对了,这里唯一性还需要证明吗?不需要,唯一性与\(x\)的构造无关。

故事还没有完,因为以上假设\(p\)\(q\)是不等的两个素数,这要求比中国剩余定理还差一步的距离。如果使用中国剩余定理的标准设定,设\(p\)\(q\)是不等的且互素的整数,斌头剩余定理就失败了!怎么挽救呢?费尔马小定理是什么定理的特例?欧拉定理!哇哦,欧拉挽救了斌头。欧拉定理说的是,如果\(gcd(p,q)= 1\),则:

\[q^{\phi(p)} \equiv 1 \pmod{p}\]

\(\phi\)是欧拉函数。所以,相似数的构造可以使用欧拉定理这个\(1\)

斌头剩余定理--最终版

\(p\)\(q\)是不等的且互素的整数,\(n = pq\)。对任意的\(a \in \mathbb{Z}_p\)\(b \in \mathbb{Z}_q\),存在 唯一解\(x\)\(0 \leq x < n\)使得: \[\begin{eqnarray*}x &\equiv& a \pmod{p}\\ x &\equiv& b \pmod{q}\end{eqnarray*}\]\(x = (a q^{\phi(p)} + b p^{\phi(q)}) \bmod{n}\)

请读者论证

  • 斌头剩余定理是正确的。请编程实现相关算法并计算。

  • 斌头剩余定理实在是没有用处的定理。请说明理由。

  • 斌头剩余定理能有效帮助大家记忆中国剩余定理,无需理由!

中国剩余定理--抽象代数的角度

中国剩余定理是一种高效的工具,在特定的时候,它也是一种抽象的表达,是从代数的角度认识某些数字系统的方法。在很多情况下,当我们说“哦,这是中国剩余定理!”的时候,我们并不一定在说“这里有一种高效的计算方法”,而往往是说“这类数值可看为具有这样的形式”。从抽象代数的角度去看CRT,就是学习如何把CRT看为一种“语言”。为避免本文过长,就留待以后再说了。

总结

中华文化源远流长,其中孙子定理又称中国剩余定理是这种文化里的一颗闪亮的明星。中国剩余定理与中国的关系就好比超奇异椭圆曲线与奇异的关系一样密切。中国剩余定理是中国的!

懂中国剩余定理的人实在很多,但是懂斌头剩余定理的就不见诸科技文献报道,颇为可惜,哈哈哈,于是就有了这篇博客。正如博客里面已经论述,斌头剩余定理实在是没有用处的定理。在此只能道歉,“老师教了一堆没用的东西”这句话在此有效。学习嘛,无非就是发现乐趣,没用就没用吧。

向各位隆重介绍一位好朋友:Sage,一种功能强大的数学软件系统,大概将其看为Maple、Mathematica、Magma或者Matlab的兄弟软件即可。它是功能强大、操作方便的自由开源软件。如果你能交上这样的朋友,并善于利用它,它一定能给你很大的帮助。

如何使用Sage?

方法1--在线使用

通过浏览器访问SageMathCell(无需帐号登录,缺点就是不能保存文档。)或者SageMathCell(需要通过帐号登录,可保存相关文档。),即可享受Sage的各种功能!最近,这个网站Collaborative Calculation in the Cloud也不错。

方法2--下载安装

下载Sage源代码或安装包,在Linux下或者在Mac OS下安装一个Sage,很方便。

方法3--Windows下

如果你是忠实的Windows用户,其实也很方便,卸载Windows再装一个Linux呗。其实,开玩笑的,Sage可以在Windows下安装。

Sage能干什么?

1. 计算

实际情况就是,我们学了计算机,懂这个那个,但是不精通计算,对不?Sage主要在计算上帮我们大忙。你总不会以为下面这些工作你很“精通”吧?

例子0,来一个容易的,求两个整数之和或者积。

1
2
3
4
sage: 123456789 + 987654321
1111111110
sage: 111111111*111111111
12345678987654321

例子1,想知道2的1000次方是多少?

1
2
sage: 2**1000
10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376

例子2,想知道2的1279次方减1是否素数?

1
2
sage: is_prime(2**1279 - 1)
True

例子3,对函数 \(f(x) = x^x\) 进行求导。

1
2
sage: derivative(x^x, x)
x^x*(log(x) + 1)

例子4,对某个矩阵求其逆矩阵,或者求矩阵的特征值。

1
2
3
4
5
6
7
8
sage:  A = Matrix([[1,0,0,0],[1,1,0,0],[1,2,1,0],[1,3,3,1]])
sage: A.inverse()
[ 1 0 0 0]
[-1 1 0 0]
[ 1 -2 1 0]
[-1 3 -3 1]
sage: A.eigenvalues()
[1, 1, 1, 1]

例子5,作图。一个命令作出的正态分布图。

1
sage: plot(gs(x, 3, 1), x, 0, 10)
正态分布图

gs这个函数定义如下,完全是Python的语法:

1
2
3
4
def gs(x,mu,sigma):
a = 1/(sqrt(2*3.1415926)*sigma)
b = -(x - mu)^2/(2*sigma^2)
return a*exp(b)

当然,例子还有很多,数不胜数。然而,怎么举例都显得小看了Sage,因为它几乎无所不能。其实,学习使用Sage除了让它帮忙计算,还主要因为它可以帮助我们......

2. 教学

Sage可以帮助我们学习。学什么?使用Sage进行教学的大学课程包括但肯定定不局限于此:

  1. 高等数学: 求导数、求积分、求极限、作图.....

  2. 线性代数: 高斯消元、Eigenvalue、Determinant.....

  3. 概率论

  4. 算法设计

  5. 计算机安全学

  6. 组合数学、数论、离散数学

  7. 抽象代数

Sage在教学中的好处就是,把所有的理论都通过可以实践的程序呈现出来,把抽象的内容以直观的方法表现出来,增强课本的可读性,增强学习的趣味性,也可提高学习者的主动性。比如,我用它这样教椭圆曲线密码学

3. 编程

Sage是一门强大的编程语言,语法与Python基本相同。你甚至可以把Sage理解为扩展了非常多功能的Python。同时,Sage与很多计算机软件、程序设计语言有非常优雅的结合,比如,Sage的输出可以方便地与LaTex结合在一起。

由于Python已经得到广泛应用,无论是老程序员还是新入门者,选择Sage都显得非常恰当。老程序员会更容易上手,无需改变什么;而新入门者也无需担心选择Sage所带来的局限性。

4. 科研

Sage当然是科研的好帮手:统计、高精度计算、仿真建模等。比如,我用Sage来建模,研究超奇异椭圆曲线的秘钥交换算法 。大学生参加数学建模比赛、CTF比赛都可以使用它,大家能不关注?

如何学习Sage

目前国外大量的教材支持Sage的使用,因为Sage是开源的自由软件。因此,建议是在网上检索相关的教材。其次,Sage的网页上已经集结了海量的教材,微积分、线性代数、数论等各种指南应有尽有。加上,Sage的使用本身就非常简单,稍微掌握一点命令就可以工作,入门门槛极低,大家完全有能力自己学习。也许这个简明友好的入门能立即拉近你与Sage的距离,请不要犹豫地点开它!这一份教程也非常不错,只可惜,看起来它一直停留在没有完成的状态。

另外,如果有人向你推荐MATLAB,你就可以在向他请教的同时,适时向他推荐一把Sage:开源的,免费,避免用盗版。

Sage的缺点

Sage的缺陷也是很明显的,主要体现在:很多功能还有待完善;有不少功能需要统一或者协调一致性;开源同时也带来了开发的困难。W. Stein,Sage的一位重要的开发者对Sage的未来也表示了担忧和负面的评价。他已经离开高校,成立公司专注于Sage开发。

困难是有的,缺点是有的。然而,只要人类还充满对自由的渴望,开源自由软件就会有美好的未来。

资源


2020年4月修改。

引言

本文简单介绍椭圆曲线密码学的基本内容,目标是直观、简化,忽略严谨性。切记,简单是为了导向严肃而不是庸俗。

阅读以下内容,在有群论与密码学的基础上,大概需要1个小时。如果没有密码学基础,可忽略密码学,而重点关注椭圆曲线的定义与相关计算。建议安装SageMath,在阅读过程中尝试运行相关代码,以助理解。

什么是椭圆曲线?

忽略严谨性,简单而言,

所谓椭圆曲线就是满足以下方程的点(即序对\((x,y)\))形成的集合。 \[y^2 = x^3 + ax + b\]

其中,要求 \(\Delta = 4a^3 + 27b^2 \ne 0\),暂时不解释,大家先接受并记得这个常量。如果\(a\)\(b\)是实数,则\(x\)\(y\)自然是实数。让我们看看这样的点形成什么样的曲线。

1
2
3
sage: a = -5; b = 4
sage: E1 = EllipticCurve(RR, [a, b])
sage: show(plot(E1, hue=.9))
实数域R上的椭圆曲线

如果改变\(a\)\(b\)的值,可以得到其他的曲线,比如:

1
2
3
sage: a = 2; b = 3
sage: E2 = EllipticCurve(RR, [a, b])
sage: show(plot(E2, hue=.9))
实数域R上的椭圆曲线

还可以选取随机的\(a\)\(b\),去看看曲线长什么样。比如我们完全无法预测以下曲线的模样:

1
2
sage: E3 = EllipticCurve(RR,[RR.random_element(), RR.random_element()])
sage: show(plot(E3, hue=.9))

实数域R上的椭圆曲线

通过以上的图,我们得到了对椭圆曲线的第一印象:长得很不椭圆。有一点可能大家已经注意到:曲线沿\(X\)轴对称

但是,这些曲线还不是我们最关心的,我们更关心的是,如果\(a\)\(b\)落在有限域\(F\)上的情形。本文主要考虑的有限域是素域\(F_p\)\(p\)是素数。因为我大部分的学生对有限域的概念比较陌生,而恰巧他们都精通 略微了解有限群。于是,我这样说,设\(a, b \in Z_p^*\)\(p\)是一个素数。有限域\(F_p\)\(Z_p^*\)多了一个加法(\(Z_p\)是加法群啊!)和\(0\)元,仅此而已,不要慌!其实是我很慌......

比如,我们运行以下代码。

1
2
3
4
sage: p = 137 #p是一个素数
sage: F = GF(p) #一种有限域,也可以用 F = FiniteField(p)命令
sage: E137 = EllipticCurve(F, [F.random_element(), F.random_element()])
sage: show(plot(E137, hue=.9))
有限域GF(137)上的椭圆曲线

这幅图告诉我们,原来椭圆曲线所谓的“曲线”既不“曲”,也不成线,而是离散点的集合。到底有多少个点呢?这是椭圆曲线研究关心的大问题。对我们而言,只需要知道以上曲线大概的点数即可。可以使用以下命令。

1
sage: E137.points()

椭圆曲线群及其基本运算

看到这里,你至少知道椭圆曲线就是一堆”乱七八糟“点的集合,这有什么用呢?暂时还没什么用,直到我们说,椭圆曲线上的点在加法上成群。首先,我们再一次给出椭圆曲线的定义。

\(\mathbb{F}\)为有限域,设 \(a, b \in \mathbb{F}\)为常数,它们使得 \(\Delta = 4a^3 + 27b^2 \ne 0\)。非奇异椭圆曲线 \(E\) 是满足方程 \(y^2 = x^3 + ax + b\)上的解集合 \(\{(x, y) \in \mathbb{F} \times \mathbb{F}\}\) 加上一个称为”无穷远点“的特殊点 \(\mathcal{O}\) ,并且\(E\)在加法上形成交换群。

所谓无穷远点\(\mathcal{O}\)就是加法的单位元。这里的内涵比较丰富,暂时可以不管。我们迫切要做的是把点的加法定义出来。在定义前,先规定一些表示法。\(P,Q \in E\)表示曲线\(E\)上的两个点,注意,点是一个序对\((x,y)\)。所谓加法(群上点的加法)就是给定\(P\)\(Q\)\(R\),使得\(R = P + Q\)。加法有两种情形。

加法1:P != Q

如图所示,给定不同的点\(P\)\(Q\),作\(P\)\(Q\)的连线,该线与\(E\)相交于某个点,把这个点沿\(X\)轴翻转就得到了点\(R\)。这个\(R = P + Q\)

椭圆曲线加法

具体到数值计算,设 \(P = (x_1, y_1)\)\(Q = (x_2, y_2)\)\(R = (x_3, y_3)\),则

  • 计算连线\(L\)的斜率\(\lambda = (y_2 – y_1) / (x_2 – x_1)\)\(L\)可记为: \[y = \lambda(x - x_1) + y_1;\]
  • \(L\)\(E\) 相交的另一个点:将\(L\)的方程(用斜率\(\lambda\)\(x\)表达的\(y\))代入椭圆曲线方程: \[(\lambda(x - x_1) + y_1)^2 = x^3 + ax + b,\] 整理可得: \[0 = x^3 - \lambda^2 x^2 + \cdots ;\]
  • 因为以上方程是一个三次方程,它有三个不同的根,所以, \[ x^3 + \lambda^2 x^2 + \cdots = (x - x_1)(x - x_2)(x - x_3 ) = x^3 - (x_1 + x_2 + x_3) x^2 + \cdots = 0 \]
  • 因此,可得:\(x_3 = \lambda^2 - x_1 - x_2\),进而可得\(y_3 = \lambda(x_1 - x_3) - y_1\)。注意,这里已经做了值的翻转!

注意,三次方程就一定有三个不同的根,难道不能是重根吗?很希望大家能问这个问题,只是因为我的学生基本都知道原因,所以上课从来没人问,所以我上课也从来都不解释,以至于我也差不多要忘记了:三次方程的判别式 \(\Delta=4a^3 + 27b^2 \ne 0\) 已经确保了重根不会出现。

加法2:P == Q

如图所示,此时,只给定了一个点\(P\),我们要计算\(R = P + P\)

椭圆曲线加法

首先,沿点\(P\)作曲线的切线,与\(E\)相交于某点,然后沿\(X\)轴翻转该点就得到\(R\)。具体计算如下:

  • \(\lambda = (3x_1^2 + a) / 2y_1\)
  • $ x_3 = ^2 - 2x_1$, \(y_3 = \lambda(x_1 – x_3) - y_1\)

具体推导与解释就不再展开,鼓励大家自己先推导,也可参考相关教科书。

无穷远点到底是什么?

我们知道\(\mathcal{O}\)是群的单位元,也就是说\(P + Q = \mathcal{O}\),如果\(P\)\(Q\)互为逆元。而\(P\)\(Q\)互为逆元意味着,它们曲线上是沿\(X\)轴对称的两个点,那么它们的连线永远是垂直于\(X\)轴的线。与\(X\)轴垂直的线与曲线在哪里还能相交出一个点呢?理论上就只能在无穷远的地方。直观上,\(\mathcal{O}\)就代表所有垂直于\(X\)轴的线在曲线上的交点。

逆元与无穷远点

椭圆曲线群满足的属性

最简单来说,因为\(E\)是交换群,它必然满足所有的群公理:

  • 单位元:\(P + \mathcal{O} = \mathcal{O} + P = P\);

  • 逆元:\(P + (-P) = \mathcal{O}\), 其中 \(P = (x, y)\), \(-P = (x, -y)\);

  • 结合律:\(P + (Q + R) = (P + Q) + R\);

  • 交换律:\(P + Q = Q + P\);

在有限域\(\mathbb{F}\)上的椭圆曲线

不知道讲到这里大家是否会提出这样的异议:没错,如果椭圆曲线是在实数域上\(\mathbb{R}\),以上推导基本没什么问题,但是我们知道,如果椭圆曲线落在\(\mathbb{F}\)上,曲线是离散点的集合,那么做连线、切线、求斜率等等,这一系列我们都做不到啊!?

答案是,说得没错,这一系列几何意义确实很难体现。但是,不要忘记,所有的域都可以做加减乘除运算。只需要把所有相关操作“平移”到域上即可!

试举一个曲线\(E_{137}\)的例子。设\(a = 3\)\(b=4\),曲线方程是:\(y^2 = x^3 + 3x + 4b\),给定两个点\(P = (x_1=18,y_1=100)\)\(Q=(x_2=20,y_2=114)\),求\(R = P + Q\)

解法如下:

  • \(\lambda = (y_2 – y_1) / (x_2 – x_1) = (114 - 100)/(20 - 18) = 7\)
  • \(x_3 = \lambda^2 - x_1 - x_2 = 7^2 - 18 - 20 = 11\)
  • \(y_3 = \lambda(x_1 - x_3) - y_1 = 7(18-11) - 100 = 86\) ;注意,所有加减乘除都是域上运算!

所以,\(R =(x_3,y_3)=(11, 86)\)。大家可以通过SageMath进行验证:

1
2
3
4
5
6
sage: p = 137
sage: F = GF(p)
sage: E137 = EllipticCurve(F, [3,4])
sage: P = E137(18,100)
sage: Q = E137(20,114)
sage: R = P + Q; R

椭圆曲线密码学

说了这么多,椭圆曲线与密码学怎么关联起来呢?首先,我们需要以下概念。

椭圆曲线离散对数问题.

\(E\)是有限域 \(\mathbb{F}\) 上的椭圆曲线,且\(P \in E(\mathbb{F})\)。假定 \(Q\)\(P\)的倍数,则所谓椭圆曲线离散对数问题(ECDLP)就是要计算\(n\in \mathbb{F}\) 使得 \(nP = Q\)

注意,\(nP = \underbrace{p + p + \cdots + p}_n\),就是\(n\)\(p\)相加。这是容易的,至于怎么做,效率如何,这个请读者自己思考。但是我们相信,求解ECDLP问题是困难的,即求解ECDLP计算上不可行。通俗讲,就是没有高效的算法可以完成这个任务。

其次,我们回忆1975年密码学的一次革命性创新:Diffie-Hellman密钥交换协议。Diffie-Hellman密钥交换协议的安全性建立在离散对数问题的困难性之上。只需要把椭圆曲线平移到Diffie-Hellman即可。

ECC版本的Diffie-Hellman协议

1
2
3
4
5
6
7
8
9
10
11
sage: p = next_prime(randrange(10^40)) #获得一个大素数
sage: print(p)
sage: F = FiniteField(p)
sage: E = EllipticCurve(F, [F.random_element(), F.random_element()])
sage: P = E.random_element()
sage: print(P)
sage: b = randrange(1000); b #Bob的私钥
sage: B = b*P #Bob的公钥
sage: a = randrange(1000); a #Alice的私钥
sage: A = a*P #Alice的公钥
sage: if(a*B == b*A): print("We share a common secret.") #密钥交换成功.

以此类推,把ECDLP平移到其他基于DLP的密码学算法上去,可以得到ECDSA(数字签名协议)等等。当然,椭圆曲线密码学并不仅仅如此而已。2000年后,基于椭圆曲线的Pairing还有一大系列的基于身份的公钥密码学。目前,基于椭圆曲线理论研究后量子安全密码学也是一大热点。


20200410下午

引言

超奇异同源Diffie-Hellman (SIDH) 密钥交换算法是后量子安全密码研究的一大重点。本文简介SIDH的基本思路与构造,为对此后量子安全算法有兴趣的读者展示该算法的一种概貌。阅读本文不需要椭圆曲线知识,但是需要一些简单的群论知识,比如,群、子群、群同态、群同构等。

Diffie-Hellman算法

目前应用最广泛的密钥交换协议是Diffie-Hellman (DH) 算法,其思路如图所示,任何一本密码学教材都有具体过程的描述,本文不再赘述。如果不懂DH算法,也没必要阅读本文。

Diffie-Hellman基本协议

一般来说,DH算法中使用的群\(G\)可以是\(Z_p^*\)乘法群,也可以使用椭圆曲线群。DH算法的安全性建立在离散对数问题(DLP)的难解性,该算法不能抗量子攻击也在于DLP有多项式时间的量子算法。因此,在后量子时代,必须使用新的构造。

构造新型Diffie-Hellman算法的思路

构造新算法的思路往往源于对现有算法的高度抽象。DH算法可以抽象为这样一种过程:

Alice的秘密是\(a\),她的计算先做→,得到\(g^a\),再做↓,得到\(g^{ab}\)。而Bob的秘密是\(b\),他先做↓,再做→。殊途同归得到\(g^{ab}\)。进一步扩展这种思路,我们寻求这样一种群结构,如下图所示:

抽象Diffie-Hellman

这是一种抽象描述,但是它表达了一种直观的思路。\(G\)是公共参数,Alice的秘密是\(A\),Bob的秘密是\(B\)。比如,假想这样的情况,\(G\)是一个乘法群,\(A\)\(B\)\(G\)的正规子群。Alice和Bob如果还是按照上面的做法,都可以计算出商群\(G/AB\)\(AB\)理解为\(A \cap B\)。必须承认,这还不是DH,因为要算出\(A \cap B\),就必须有\(A\)\(B\),也就是说Alice和Bob都不能隐藏自己的秘密。不过,数学家的理想就是要构造出这样一幅交换图,且满足以下两种属性:

  • 给定\(G\)\(G/A\)\(B\),可以算出\(G/AB\);给定\(G\)\(G/B\)\(A\),可以算出\(G/AB\)

  • 给定\(G\)\(G/A\) (或\(G/B\)),求\(A\) (或\(B\)) 是困难性问题,即不存在量子多项式时间算法。

    基本SIDH

基本上SIDH算法就是满足此要求的一种构造。再次强调,不要被上面的例子误导,这里的\(G\)\(A\)\(G/A\) 等表达都是抽象结构的符号表达,并没有明确含义。以下的SIDH构造描述就是要给出其相对具体的构造。

SIDH构造的简化版本

SIDH的基本代数结构是超奇异椭圆曲线群\(E\)和超奇异同源(Isogeny)\(\phi\) 。基本思路如下图所示:

基本SIDH

首先,超奇异椭圆曲线群\(E\)理解为一个群即可,所谓”超奇异“这个概念可以暂时不理会它,知道要求椭圆曲线满足”超奇异“这个要求是为了安全性即可。其次,构造用到的超奇异同源\(\phi : E \mapsto E'\)是从群\(E\)到群\(E'\)的一种群同态。算法类似DH算法分为以下两个步骤:

  • 首先,Alice选取一个点\(R_A \in E\)\(\langle R_A \rangle\)确定了群\(E\)的一个子群,然后可以计算得到一个从\(E\)映射到其子群\(E_A\)的同源\(\phi_A: E \mapsto E_A\),这是Alice的秘密信息。Alice发送公开信息\(E_A\)给Bob。

  • 同样,Bob选择点\(R_B\in E\),然后计算得到\(\phi_B: E \mapsto E_B\) ,把公开信息\(E_B\)发送给Alice。

最终Alice算出\(E_{BA}\) (\(E/\langle R_B, R_A \rangle\) ),Bob算出\(E_{AB}\) (\(E/\langle R_A, R_B \rangle\) )。解释一下,上图中的\(E/\langle R_A \rangle\)\(E/\langle R_B \rangle\)分别是\(E_A\)\(E_B\),这样表达是为了与之前的表达一致,其实这里并不是做商群,而是表达说\(\phi_A\)的Kernel是\(\langle R_A \rangle\)。目前的科技文献大多使用这种表达。

再解释一下\(E_{BA}\)是什么。上面说到,\(E_A\)是曲线群\(E\)的子群,它由Isogeny \(\phi_A\)决定,可理解为群同态\(\phi_A\)映射到\(E\)上的像 (Image)形成的子群。同理,\(E_{BA}\)是Isogeny \(\phi_{BA}\) 映射到\(E\)上的子群,而Isogeny \(\phi_{BA}\) 是由\(\langle R_B, R_A \rangle\)决定的,即Isogeny \(\phi_{BA}\) 的Kernel是\(\langle R_B, R_A \rangle\)

慢着,Alice怎么算出\(E_{BA}\) (\(E/\langle R_B, R_A \rangle\) )?对,Alice有\(E_B\)但是并没有\(R_B\),所以她并不显然能算出\(E_{BA}\)。当然,我们还有很多的问题并没有说清楚,还需要进一步细化解释。如果阅读到这里还基本能跟上思路且还保持兴趣的请看下图。

SIDH

SIDH构造的细化版本

为了满足Alice在没有Bob的秘密信息的情况下能计算出\(E_{BA}\) 的要求,SIDH需要使用更多的参数设计和相关计算。算法增加描述如下:

SIDH参数设计

首先,选择超奇异椭圆曲线\(E\)作为公开参数。然后Alice随机选择两个元素\(P_A, Q_A \in E\),并公开作为自己的公共参数。同样,Bob也随机选择两个元素$ P_B, Q_B E$ 并公开。

Alice的操作

  • 随机选择两个整数\(s_A\)\(t_A\)作为秘密信息,计算 \(R_A = s_A P_A + t_A Q_A\in E\),并由\(R_A\)计算得到一个从\(E\)映射到其子群\(E_A\)的同源 \(\phi_A: E \mapsto E_A\),这也是Alice的秘密信息;
  • 获取Bob的公开信息,并计算\(\phi_A(P_B)\)\(\phi_A(Q_B)\),这些是公开信息;
  • Alice发送公开信息\(E_A\)\(\phi_A(P_B)\)\(\phi_A(Q_B)\)给Bob。

Bob的操作

  • 随机选择两个整数\(s_B\)\(t_B\)作为秘密信息,计算\(R_B = s_B P_B + t_B Q_B \in E\),并由\(R_B\)计算得到一个从\(E\)映射到其子群\(E_B\)的同源 \(\phi_B: E \mapsto E_B\),这也是Bob的秘密信息;
  • 获取Alice的公开信息,计算\(\phi_B(P_A)\)\(\phi_B(Q_A)\),这些是公开信息;
  • Bob发送公开信息\(E_B\)\(\phi_B(P_A)\)\(\phi_B(Q_A)\)给Alice。

秘密值的计算

Alice计算子群\(E_{BA}\) ,方法如下:

  • 注意,此时Alice掌握的信息是\(s_A\)\(t_A\)\(R_A\)\(\phi_B(P_A)\)\(\phi_B(Q_A)\) ,她想计算得到\(\phi_B(R_A)\) 。并且要强调,\(\phi_B\) 是一种群同态。
  • 于是,利用群同态的属性可计算得到:\(\phi_B(R_A) = \phi_B(s_A P_A + t_A Q_A) = s_A \phi_B(P_A) + t_A \phi_B(Q_A)\)
  • 根据\(\phi_B(R_A)\) 计算\(E_{BA}\)\(E_{BA}\)是曲线群\(E\) 的子群,是以\(\phi_B (R_A)\) 为Kernel的群同态映射到\(E\)上的子群。这个群同态也就是Isogeny,这个Isogeny我们记为 $ _{BA}$ 。终于我们明白了什么是\(E_{BA}\)

类似地,Bob可以计算子群\(E_{AB}\)

  • \(\phi_A(R_B) = s_B \phi_A(P_B) + t_B \phi_A(Q_B)\)
  • 由此可计算得 \(E_{AB}\)

最后冲顶的一步,计算秘密值。首先要明确,很可能\(E_{BA} \ne E_{AB}\),至少它们不显然相等!其次,\(E_{BA}\) 同构于\(E_{AB}\) 。然后利用同构曲线的一个属性:所有同构曲线的 J-Invariant值相同。于是Alice和Bob分别计算\(J(E_{BA})\)\(J(E_{AB})\) ,这就是他们共同拥有的秘密。J-Invariant的计算定义可在标准教科书中找到,本文把它视为黑盒子使用。

Sage代码展示SIDH的思路

以下展示在Sage下可运行的SIDH代码片段,通过代码运行让读者强化对以上算法描述的理解。

参数设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#选取一条在素域k上的超奇异椭圆曲线
lA, lB = 2, 3
eA, eB = 6, 7
p = lA ^ eA * lB ^ eB - 1
assert p.is_prime()
assert p % 4 == 3
k = GF(p) # 注意,这里并不是标准做法,只是因为Sage的局限不得已;
E = EllipticCurve(k, [1, 0]) #选取曲线
E
E.is_supersingular() # 看看所生成的曲线是否超奇异.
print(E.j_invariant())

#选取四个随机点作为公共参数
points = []
while len(points) != 4:
p = E.random_point()
if p not in points:
points.append(p)
PA, PB, QA, QB = points
PA, PB, QA, QB

Alice 的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#Alice选择两个随机数并计算自己的秘密值RA
#RA定义了phi_A的kernel
sA, tA = 123, 525
RA = sA * PA + tA * QA
print(RA)

#phiA就是同源也是群同态
phiA = E.isogeny(RA)

#Alice的公共信息EA
EA = phiA.codomain()
print(E.is_isogenous(EA)) # 确认EA与E同源.

#Alice发送以下值给Bob
EA, phiA_PB, phiA_QB = EA, phiA(PB), phiA(QB)
EA, phiA_PB, phiA_QB

Bob的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#Bob的工作类似
sB, tB = 812, 580
RB = sB * PB + tB * QB
print RB

# phiB就是从E到EB同态映射,Kernel是RB
phiB = E.isogeny(RB)
print phiB
EB = phiB.codomain()
print EB
print E.is_isogenous(EB)

# Bob发送以下信息给Alice:
EB, phiB_PA, phiB_QA = EB, phiB(PA), phiB(QA)
EB, phiB_PA, phiB_QA

秘密值计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Alice计算秘密值
R_BA = sA * phiB_PA + tA * phiB_QA
print R_BA
phiBA = EB.isogeny(R_BA)
print phiBA
KA = phiBA.codomain().j_invariant()

# Bob计算秘密值
R_AB = sB * phiA_PB + tB * phiA_QB
print R_AB
phiAB = EA.isogeny(R_AB)
print phiB
KB = phiAB.codomain().j_invariant()

#测试秘密值是否相等
if KA == KB:
print "Success!"

总结

本文试图对SIDH算法进行最直观的描述,让初具群论知识的从业者对此算法稍有认识。正因为强调直观、直白,自然忽略了其中许多深入的知识,包括:曲线参数的选取,计算同源的具体算法,为什么SIDH可抗量子攻击等。简而言之,本文旨在抛砖引玉,能引起读者兴趣就足够了,其内涵有限,作为“茶余饭后”的聊资很恰当,但绝不是严肃的科技文献。有兴趣者可在ePrint等网站获取更多的科技论文进行研究。

致谢

本文内容插图截取自David Urbanik的文献 。代码源自Lvh的Blog,总算找回这个网站,我撰写的内容则基本与Lvh没关系。

--