OpenSSL密码库算法笔记——第1.2.1章 经典乘法

所谓的经典乘法就是在小学的时候学到的那一套做乘法的方法。如果假设被乘数a和乘数b为:

                         …………(1.1)

则经典乘法是这样做的:

                      …………(1.2)

即分别做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) 计算 (u,v)= r_{i+j}+a_{i}b_{j}+c

2.2.2) 令r_{i+j}\leftarrow v,c\leftarrow u

2.3)r_{j+m}\leftarrow u

step3:   r_{n+m-1},...,r_{1},r_{0}返回。

───────────────────────────────────────

其中的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 _wordsbn_mul_add_words的比较见下表:

Bn_mul _words (rp, ap, num, w)

bn_mul_add_words (rp, ap, num, w)

a\times b_{0}时用

a\times b_{i}时用

表1.1 bn_mul _wordsbn_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)来实现。请注意这里的参数lh前后代表的意思不一样:

                  …………(1.3)

这里的h32表示h32比特,h16表示h16比特,其余同理。

说明(2)、(3)可归纳为下表:

函数名称

数学表达式

调用情况

mul         (r, a, bl, bh, c )

a_{j}\times b_{0}

mul_add (r, a, bl, bh, c )

a_{j}\times b_{i}

mul64     (l, h, bl, bh  )

最底层

表1.2 bn_mulbn_mul_addmul64的比较

关于上述函数与宏定义的关系请参见§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 主要是被乘法运算调用,作为一个内部子函数来调用,基本上没有作为独立的函数在用。请注意区别。

猜你喜欢

转载自blog.csdn.net/samsho2/article/details/85838994