在有限域运算中,我们需要频繁使用mod N运算。对于涉及连乘的指数运算,Montgomery Reduction能提供更好的性能优化。
Montgomery Reduction的核心思想是将运算数转换到一个特殊的Montgomery Form,其所有的除法运算都可以被显著简化。
让我们通过一个具体例子来理解:
设模数 N = 97,我们需要计算 (a⋅b)modN。传统方法需要对a⋅b的结果进行求余运算,这涉及到开销较大的除法运算。
- 选择R = 100(通常选择为2的幂,这里为便于演示选用100,我们仅需在10进制下取尾数和抹除尾部的00即可)
- 对于输入 a = 15, b = 32:
- Ta=aRmodN=45
- Tb=bRmodN=96
Montgomery乘法过程¶
计算Montgomery Form的乘积:
Tr=Ta⋅Tb=45⋅96=4320
结果转换:
- 由于经过了两次Montgomery Form转换,结果包含 R2 项,需要消除一个 R
- 我们需要在不改变 modN 结果的情况下调整 Tr ,使其能被 R 整除
- 我们可以给T加上若干次 N ,这样modN的结果仍然不会被影响,于是我们有了 T+xN
- 我们又需要合适的x,使得 T+xN 能被 R 整除
- 通过同余等式 T+xN≡0(modR),即 x=T⋅(−N1)modR
- 我们把 −N1 记为 N′,N′=−N1modR=67(提前计算)
- 上面求得的 x 即为Montgomery Reduction中的 m, t=T+mN
具体计算:
第一次Montgomery Reduction (aR⋅bR/R):
m=Tr⋅N′modR=4320⋅67mod100=289440mod100=40
(注:mod 100在10进制下就是取2位尾数)
t=(Tr+m⋅N)/R=(4320+40⋅97)/100=8200/100=82=abR
(注:除以100在10进制下就是抹掉尾部的00)
第二次Montgomery Reduction (abR/R):
m′=t⋅N′modR=82⋅67mod100=94
t′=(t+m′⋅N)/R=(82+94⋅97)/100=92=ab
优势分析¶
虽然单次运算时Montgomery Reduction似乎并未节省太多计算资源(转换到Montgomery Form时仍需mod N运算),但在需要连续模乘运算的场景下(如模幂运算),其优势就非常明显:
模幂运算示例:计算 a5modN
- 传统方法需要在每次乘法后进行mod N运算
- 使用Montgomery Form后:
- 初始转换:Ta=aRmodN
- 中间运算无需除法:Ta⋅Ta/R=(aR⋅aR)/R=a2R
- 只需在最后转换回原始形式
主要优势:
- 避免中间步骤的mod N运算
- 消除大部分除法运算
- 适合硬件实现(R选择2的幂时,除法和取模都可以用移位和位与运算完成)
- 特别适合需要连续模乘运算的场景
工程实现¶
在实际工程中,我们通常通过将元素a乘以R2来将其编码到Montgomery Form。这种方式的优点是:
Montgomery Reduction和乘法可以合并为统一的mul函数:
- mul(a,b)=ab/R
这样encode和decode都可以用同一个mul函数:
- encode(a)=mul(a,R2)=aR2/R=aR
- decode(Ta)=mul(Ta,1)=aR/R=a
这种统一的实现方式使代码更简洁,同时当R选择为2的幂时,所有的除法和取模运算都可以通过移位和位与运算高效完成。
对于模幂运算,我们可以看到Mont乘的优势:
传统算法:
a5=((((a⋅a)modN)⋅a)modN)⋅a)modN)⋅a)modN
每一步都需要进行昂贵的除法运算来求余
Montgomery算法:
- Ta=aRmodN
- Ta⋅Ta/R=a2R
- (a2R⋅aR)/R=a3R
- (a3R⋅aR)/R=a4R
- (a4R⋅aR)/R=a5R
- decode(a5R)=a5
所有中间步骤都只需要简单的移位操作,大大提升了性能。