所谓的经典乘法就是在小学的时候学到的那一套做乘法的方法。如果假设被乘数a和乘数b为:
则经典乘法是这样做的:
即分别做a×bi,再累加到r上。
算法如下:(参见[1]算法14.12)
───────────────────────────────────────
算法: 经典乘法
step1: 对i从0到(m+n-1),令ri←0。
step2: 对j从0到n-1,执行如下运算:
2.1) c←0。
2.2) 对于i从0到m-1,
2.2.1) 计算
2.2.2) 令。
2.3)。
step3: 返回。
───────────────────────────────────────
其中的u、v、c、ri都是32比特字,(u,v)表示u和v连接成的64比特数。
经典乘法的函数为:
───────────────────────────────────────
void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
功能: 经典乘法
输入: a,na【a的字长】,b,nb【b的字长】
输出: r=a×b
返回: -
出处: bn_mul.c
───────────────────────────────────────
说明:
(1)、由于乘积r的初始值为0,所以a×b0时不用累加,但是a×bi(i≠0)时累加是必不可少的。因此a×b0和a×bi(i≠0)可以分别用不带累加的函数BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)和带累加的函数BN_ULONG bn_mul_add_words (BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)实现。
bn_mul _words与bn_mul_add_words的比较见下表:
Bn_mul _words (rp, ap, num, w) |
bn_mul_add_words (rp, ap, num, w) |
时用 |
时用 |
表1.1 bn_mul _words与bn_mul_add_words的比较
(2)、a×b0和a×bi(i≠0)再拆分的更细就应该分别对应aj×b0和aj×bi(i≠0)。由于a×b0不用累加,所以拆分出来的aj×b0都不需要累加,可以用不带累加功能的宏定义#define mul(BN_ULONG r, BN_ULONG a, BN_ULONG bl, BN_ULONG bh, BN_ULONG c)来实现。而a×bi(i≠0)需要累加,所以拆分出来的aj×bi(i≠0)都需要累加,可以用宏定义#define mul_add (BN_ULONG r, BN_ULONG a, BN_ULONG bl, BN_ULONG bh, BN_ULONG c) 来实现。
(3)、归根到底,乘法的基础就是做字与字的乘法aj×bi,这个用宏定义#define mul64 (BN_ULONG l, BN_ULONG h, BN_ULONG bl, BN_ULONG bh)来实现。请注意这里的参数l和h前后代表的意思不一样:
…………(1.3)
这里的h32表示h为32比特,h16表示h为16比特,其余同理。
说明(2)、(3)可归纳为下表:
函数名称 |
数学表达式 |
调用情况 |
mul (r, a, bl, bh, c ) |
||
mul_add (r, a, bl, bh, c ) |
||
mul64 (l, h, bl, bh ) |
最底层 |
表1.2 bn_mul、bn_mul_add与mul64的比较
关于上述函数与宏定义的关系请参见§1.2.3。
当乘数退化成一个字的时候,可以使用大整数与字的乘法。
───────────────────────────────────────
BN_ULONG bn_mul_word(BIGNUM *a, BN_ULONG w)
功能: 大数与字的乘法
输入: a【大数】,w【字】
输出: a←a×w
返回: 1【正常】 or 0【出错】
出处: bn_word.c
───────────────────────────────────────
注意:这个函数的名称bn_mul_word和前面提到的bn_mul_words(见本小节对经典乘法函数bn_mul_normal的说明(1))很相似,功能也有些相似,都可以看作是做大整数(前者对应BIGNUM *而后者对应BN_ULONG *)与字的乘法。bn_mul_word(a,w)是做大整数与字的乘法a←a×w,而bn_mul_words 主要是被乘法运算调用,作为一个内部子函数来调用,基本上没有作为独立的函数在用。请注意区别。