天天看点

第二十二个知识点:如何用蒙哥马利算法表示一个数字和多个相乘的数字

第二十二个知识点:如何用蒙哥马利算法表示一个数字和多个相乘的数字

这篇依旧是密码学实现细节部分中的.

大多数内容来自于[1].

安全和效率

密码学的目标是设计高度安全的密码学协议,但是同时这些协议也应该被有效率的实现.这样就可以一次一次快速执行而不会因为用户变得而慢下来,例如,在线商场和网络银行都有这种需求.因此我们采取了一些措施来减少加密的成本.这些代价较高的操作就包括正整数模数的算法,因为除法比较费时.

模余操作的代价

从现在开始我们给出\(x \mod n\)的概念,就是\(x\)除以\(n\)的余数,因此它是一个小于\(n\)的非负的整数.(等价于在\(Z/nZ\)的\(x\)类,等等).

注意这里Z/nZ是指模n下的所有剩余类集合的集合,也是一个群

.

让\(a,b \in Z\),假设我们知道\(a \mod n\)和\(b \mod n\).在许多密码学应用中,我们希望计算结果\(ab \mod n\).简单的方法就是先计算\(ab\),然后再模\(n\).但是如果我们需要很多个乘法,那么我们就需要多次的模.这会增加代价.例如,在RSA中,消息\(m\)的密文通过这样计算出来:\(c = m^e \mod pq\),其中\(p,q\)是大素数.通过乘\(e\) 次计算\(m\),每次要模\(pq\).最好是把复杂的模约简推迟到计算的最后.但是同时我们仅仅计算\(m^e\)再模\(n\),我们就会得到一个超级大的数.所以还是不行,我们需要更多的思考.

"蒙哥马利算法空间"

蒙哥马利将注意力集中在简化的模数上,典型的是2的幂.因此我们可以计算\(ab \mod n\):

  • 移动a和b到蒙哥马利空间(模上一些常数\(r\))
  • 在这个更好的空间中计算产品并执行模余
  • 把结果转换为所需的余数模\(n\)

为什么要是2的幂?假如说\(x\)是一个用二进制写成的整数(计算机),和\(r = 2^k\).对一些整数\(k > 0\).

  • 计算\(x \mod r\),仅仅是取了\(x\)的最右\(k\)个位.
  • 计算\(xr\),你需要把\(x\)的\(k\)位移动到最左边
  • 计算\(x/r\),你仅仅需要移动\(x\) 的\(k\)位移动到最右边

算法

让\(a,b,n,r\)都是正整数,其中\(gcd(n,r) = 1\),\(r>n\).我们计算\(ab \mod n\).

  • 使用扩展欧几里得算法找出\(r^{-1},n^{'}\).使得\(rr^{-1} = 1 + nn^{'}\)
  • 计算\(\overline{a} = ar \mod n\)和\(\overline{b} = br \mod n\)
  • 计算\(u = abr \mod n\):
    • \(t = \overline{a}\overline{b}\)
    • \(u = (t + (n^{'}t \mod t)*n)/r\)
    • if \(u \ge n\),then \(u=u-n\).
    • output \(u\)
  • Multiply \(u\) by \(r^{-1}\) and reduce modulo \(n\)

说明一下为什么计算的快:

  • 首先第一步能很快计算出来,就是欧几里得算法
  • 第二步和第四步都有一个乘法的运算,但是仅仅计算一次,在\(a^mb^n\)这种模式下非常有用
  • 第三部包括了三个整数的乘法,一个整数的加法.但是\(r = 2^k\).我们只需要丢弃k位然后右移即可.所有的这些操作都是很快的.

正确性证明

\(u = abr \mod n\)

\(= arbrr^{-1} \mod n\)

\(= tr^{-1} \mod n\)

\(= trr^{-1}/r \mod n​\)

\(= t*(1+nn^{'})/r \mod n\)

\(=((t + nn't)/r + mn) \: \mathrm{mod} \: n = (t + (n't + mr)n)/r \: \mathrm{mod} \: n\)

注意我们最后一步没有模\(n\).是因为\(n > r > 0\),我们知道\(n^2<rn,n^2+rn<2rn,(n^2+rn)/r<2n\).我们就只需要进行判断是否大于\(n\)就行.

这就给出了算法的正确性.

[1]http://www.hackersdelight.org/MontgomeryMultiplication.pdf

这里只是对蒙哥马利算法做了一个大概的描述,并且链接是失效的。之前我下载那个参考的pdf的时候,发现里面说的和实现的并不完全对。

为了防止误导,我推荐看这篇论文,很详细,Montgomery Arithmetic from a Software Perspective,实现起来也没有问题。

我最近打算写一个ECC的轮子,写完后我会把我的Montgomery算法的c++实现放在github上。

继续阅读