现在我们来看看Montgomery乘法。简单来说,Montgomey乘法就是将经典乘法(见§1.2.1)和Montgomery约化(见§2.3)结合起来(可以参见[10,算法14.36])。
下面来简要介绍一下其算法思想。
和Montgomery约化一样,首先取一个正整数R > m,满足gcd(R,m)=1,通常取以简化计算。给定要做乘法的两个数x和y,,记
,。 …………(3.1)
的Montgomery约化是,等价于。
为了便于理解,举个例子简单解释一下。假设要计算,。首先,需要计算。然后,计算的Montgomery约化,即。接着,的Montgomery约化是。最后,的Montgomery约化是。乘以再模去m即得到。
整数x要转化成Montgomery数需要计算。在做Montgomery乘法前,所有输入和常数都应该转化成Montgomery数。事后,即做完所有的乘法后,再转化到整数,即乘以再模去m。因此,先来说明下Montgomery数与普通大整数之间的转换。将整数x映射成Montgomery整数需要计算,即计算的Montgomery约化。
───────────────────────────────────────
#define BN_to_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont)
功能: 将大数映射成Montgomery整数
输入: a【大数】,mont【Montgomery模数】
输出: r ← a×R mod mont
返回: 1【正常】 or 0【出错】
出处: bn.h
备注: 宏定义。#define BN_to_montgomery(r,a,mont,ctx)\
BN_mod_mul_montgomery((r),(a),&((mont)->RR),(mont))
───────────────────────────────────────
特殊地,当大整数退化为一个字时,将字映射成Montgomery整数的函数如下:
───────────────────────────────────────
#define BN_TO_MONTGOMERY_WORD(BIGNUM *r, BIGNUM *w, BN_MONT_CTX * mont)
功能: 将字映射成Montgomery整数
输入: w【字】,mont【Montgomery模数】
输出: r ← w×R mod mont
返回: 1【正常】 or 0【出错】
出处: bn_exp.c
备注: 宏定义。
───────────────────────────────────────
将Montgomery整数返回成普通整数,需要计算,即做的Montgomery约化。
───────────────────────────────────────
int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx)
功能: 将Montgomery整数返回成普通整数
输入: a【被模数】,mont【Montgomery模数】,ctx【临时变量】
输出: ret ← a/R mod mont
返回: 1【正常】 or 0【出错】
出处: bn_mont.c
───────────────────────────────────────
有了普通大整数与Montgomery数之间的转换,接下来该看看大家关心的Montgomery乘法了。
───────────────────────────────────────
int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_MONT_CTX *mont)
功能: 利用Montgomery约化做模乘
输入: a【被乘数】,b【乘数】,mont【Montgomery模数】
输出: r ← a×b mod mont
返回: 1【正常】 or 0【出错】
出处: bn_mont.c
───────────────────────────────────────
注意:这个Montgomery乘法其实是包含了模平方在内的。在函数体内部会判断a与b是否相等,如果a=b则先做平方再做Montgomery约化,否则,先做乘法再做Montgomery约化。