标签:
在素域椭圆曲线运算过程中,256位加法和减法运算结果常常位于区间[0,p)之外的情形,需要做+p或是-p的运算
256位NIST素域椭圆曲线参数p的生成公式为:
p = 2^256 ? 2^224 + 2^192 + 2^96 ? 1
按照符号将此式分解得:
p = (2^256 + 2^192 + 2^96) - (2^224 + 1)
转化为16进制并按64位分节,变成下面的形式:
+: 0000000000000001 0000000000000000 0000000100000000 0000000000000000 -: 0000000100000000 0000000000000000 0000000000000000 0000000000000001 =: ffffffff00000001 0000000000000000 00000000ffffffff ffffffffffffffff
仔细观察可以发现,所涉及64位加法和减法中,只出现一个64位立即数:
0000000100000000
假设某次256位减法最终发生借位,其低256位数值保存于寄存器r8:r11中,现在需要+p运算以修正之,若是用构成p的4个立即数直接运算的话,其代码如下:
addq $0xffffffffffffffff, %r8 adcq $0xffffffff, %r9 adcq $0x0, %r10 adcq $0xffffffff00000001, %r11
由x64指令特性可知,这么书写是不允许的,只有操作寄存器rax才可以使用大于32位的立即数,通过前面的分析可知,可以将4个加法转化为3个加法和4个减法来实现,其代码如下:
movq $0x100000000, %rax addq %rax, %r9 adcq $0x0, %r10 adcq $0x1, %r11 #--- subq $0x1, %r8 sbbq $0, %r9 sbbq $0, %r10 sbbq %rax, %r11
有没有其它方法呢?当然有,比如可以预先将素数p的4个64位数值保存于寄存器r12:r15中,其代码如下:
addq %r12, %r8 adcq %r13, %r9 adcq %r14, %r10 adcq %r15, %r11
为了一个256位常数牺牲4个通用寄存器是万不得已的选择,除非此运算占据整体运算的大部分,才值得这么做,比如对素数p求乘法逆时,超过80%的运算都是+/-p,此时有必要将素数p直接保存在通用寄存器中以便随时使用。
256位NIST素域椭圆曲线运算优化细节之一(单个素数p的加减法)
标签:
原文地址:http://my.oschina.net/safedead/blog/515386