SM2的实现及优化(一)

这得从几个方面来讲

1.官方文档中的问题

这里就不贴官文了,在我另一篇文章中给了下载链接,做这个实现的估计也是人手一份了。

以下只解释了三个问题。

1.1第12页,有如下一行

SM2的实现及优化(一)_第1张图片

在上边的计算中有3*10^2 + 1它怎么就变成了3*5 + 1了呢

这里,其实少写了一些信息,这个椭圆曲线是基于素数域的一个曲线P的取值为19,那么所有大于19的数都应该对19进行取模。

以上图为例10^2=100>19于是有100=100%19=5,于是就有了3*10^2 + 1 = 3*5 + 1


1.2模逆的问题

还是1.1中的例子,最后一步为“16/4 = 4”如果认为这是普通的除法运算,那么将在后面运到相当大的问题。

如果不是搞加密的,对于模逆什么也不知道就像我一样,那么这就难理解了。

其实“16/4 = 4”这一步中间略写了好几步的内容,首先1/4怎么求

自己先去看一下模逆怎么求,官方的文档没给具体方法,但是写了一句,目前最快的求模逆的方法是用扩展欧几里德的方法,在这怎么实现不表了。

回到之前的问题4*5 mod 19 = 1, 所以在加密中其实1/4=5

继续往下16*5=80 mod 19 = 4,这结果其实是这么来的


1.3复杂度表示问题(23-24页)

此页中出现了不少的I、M、S,那么这代表什么呢,文档没说,翻了几篇国内的论文就只有直接用的,也没有解释。

也许仔细观察能猜出来代表的是什么意思。这里我给解释下

I 代表的是模逆运算

M代表乘法运算

S代表平方运算

其中各自的时间消耗关系大概为:

I=80M

S=0.8M

真实的关系得看你的大数运算库是怎么实现的,【这里我没有实测引用的别人测试结果】

2.大数计算问题

2.1对于大数的定义

这里的大数是没有小数部分的,用于记录的也就只有符号和数

从存储的角度设计,得添加一个数据占用空间

另外进制的问题,为了节省存储空间和循环的长度,最好采用256的进度,刚好利用char型的数据结构

2.2加减乖除模的实现

加减就是用笔算的方式来计算

乘法和平方可以类似处理,相比加法,可以用combo的方法来加速,就是并行运算

除法和模其实是一回事情

2.3模逆运算的实现

模逆运算所说最快的是扩展欧几里得,也有用蒙哥马利做的,和另一篇文章有点重了

2.4大数计算库的推荐

本人就测试过两一个openssl一个libtommath,只能用libtommath的原因很简单,就它这是公开源码的C小型数据库

openssl很快,真的很快,但没法移植

libtommath比我自己写的要快不少【http://download.csdn.net/detail/conquerwave/5529607】

3.倍点优化问题

3.1坐标系的问题

官方给了三种坐标系下的算法

仿射坐标系,标准坐标系,jacobian坐标系

我实现了第一、三种,第二种感觉和第三种类似,官方文档给出的时间复杂度后者要比前者快一点点,就没做第二种

仿射坐标最容易理解,但是它用了大量的求模逆运算,这是最占时间的

后两者通过坐标系的变换将模逆运算给化解掉了,但是求平方和乘法运算变多了

【在jacobian中,仿射坐标向jacobian坐标转换,将基点的Z数值设为1代入计算即可;jacobian坐标向仿射坐标的转换官大人给了方法】

实际测试,第一三种方法区别不大,在stm32f4上跑分别在4S左右、5S左右

3.2仿射坐标系的优化

这里的主要思想是通过加减乘除的方法来减少模逆的运算

具体实现可以在google中搜索【trading inversion for multiplication in elliptic curve cryptography】这论文中给了详细的方法

对应的中文论文可以搜【椭圆曲线密码体制中标量乘法的快速算法】

可以用那伪代码直接实现,不用怀疑

实现后的效果还是不理想

4.结尾

效果:

优化后的时间在PC跑,密钥生成+签名生成+验证,能达到300ms左右的程序

优化后的结果没有达到要求,还得继续

如果您有好的方法,希望能指点一下,万分感激

你可能感兴趣的:(SM2的实现及优化(一))