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

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

大多数内容来自于[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)

(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上。