对于大数操作来说,大数相加属于四则运算中最简单的,也是最好实现的。
话不多说,直接上国密的代码。
typedef unsigned long long uint64_t
typedef uint64_t SM2_BN[8];
void sm2_bn_add(SM2_BN r, const SM2_BN a, const SM2_BN b)
{
int i;
r[0] = a[0] + b[0];
for (i = 1; i < 8; i++) {
r[i] = a[i] + b[i] + (r[i-1] >> 32);
}
for (i = 0; i < 7; i++) {
r[i] &= 0xffffffff;
}
}
第一步,先计算最地位,将两数相加,注意,a[0]和b[0]只使用了低四位,高四位没有使用。
正常我们两个unsigned char 的数相加也需要用大于unsigned char的字节的数来存储,
r[0] = a[0] + b[0];
第二步,开始循环相加,结果r[i] 要加上前回相加的进位值,进位值使用(r[i-1] >> 32)来计算
r[i] = a[i] + b[i] + (r[i-1] >> 32);
第三步,将最后的结果,除数组最高r[7]的值不变,其他都取低四位,最高位不取低四位是为了保留最高位相加的总值,如果取低四位,最高位的进位值就丢了。
另外说一个规律性问题,两数相加。例如c = a + b. (a.b.c类型相同)
如果有进位,c就小于 a。
两数相加c = a - b (a.b.c类型相同); 如果有借位, 那么c > a;