本文是对 超奇异椭圆曲线同源密钥协商理论研究 的工程向补充
在SIDH受攻击后,本文已过时。
0.关键操作
0.复数运算( 里的任意元素长这样: , 其中 , )
1.素数判定(p是否为素数)
2.超奇异判定(E是否为超奇异椭圆曲线)
3.j-invariant计算
4.Weil pairing计算(为了检验P与Q是否线性无关)
5.倍点、点加、随机点的选取
6.复数运算
7.计算挠群
8.根据kernel计算同源映射(Velu’s formula)
9.等等……
SIDH最核心的一步就是计算同源(也是前量子公钥密码没有的操作)
同源本质上是一个态射,是一个比较抽象的“东西”,那么怎么构造它呢?
所幸我们有Velu’s formula
0.1.Velu’s formula确定isogeny
以下是利用Velu’s formula计算isogeny的过程
0.1.0.准备工作
通过同构映射:
构造与SIDH所用曲线(Montgomery Form):
同构的曲线(Weierstrass Form):
与kernel:
G,一个的子群
0.1.1.分割G
1.丢弃单位元O
2.构造 为 G[2],即G的2-挠群,R为剩下所有点的集合
3*.二等分R,分别命名为 ,如果 , 那么
0.1.2.计算系数
1.令 ,计算:
- 如果 , 令 ,否则令
- 令
- 计算
0.1.3.构造codomain
得到
图为Codomain和Image的区别,不过在SIDH中这两个相等,因为isogeny是满射(surjective)。
0.1.4.计算image
由上得到一个isogeny
使得对 中任意一点Q有:
其中
1.程序流程图
我少有画程序流程图的经验,欢迎指正。
以下是Alice的操作,Bob与之类似
2.Sagemath代码展示
这里的代码搬自bintou的博客,有极少量的修改
2.1.参数设置
1 | #选取一条在素域k上的超奇异椭圆曲线,这里f = 1 |
2.2.Alice的操作
1 | #Alice选择两个随机数并计算自己的秘密值RA |
2.3.Bob的操作
1 | #Bob的工作类似 |
2.4.秘密值计算
1 | # Alice计算秘密值 |
3.各种来源的代码分析
3.0.C/Cython/Python/Sagemath缝合代码
链接内含 SIDH创始人之一De Feo 撰写的代码,融合了C/Cython/Python/Sagemath。
sagemath负责参数生成,python负责同源计算策略的计算,C负责关键算术运算(利用GMP库),密钥交换于Cython内完成
3.1.sidh-crypto的代码
是github上的organization,具体成员没有公开,但不难发现SIDH创始人之一David Jao是其中之一。
以下主要分析它的C代码sidh-crypto/sidh-c-reference: SIDH C reference implementation,为行文方便,文件名只截取了最后一部分。
包括密钥协商和加解密(SIKE?)两大部分,暂只分析密钥协商部分。
clear等释放内存的函数就不提及了
dlp.h: solve ECDLP
由于SIDH选取的素数p,减1后的 p-1属于smooth number,所以其ECDLP问题可以用Pohlig–Hellman algorithm解决。
curve.h:
曲线相关
-
输入参数a和b,构造椭圆曲线:y^2 = x^3 + a * x^2 + b * x + c(这里选用的是Weierstrass form曲线,且域特征不等于2或3,且c=0)
-
求j-invariant
-
判断点是否落在曲线上
点相关
- 生成零点、设置零点(即无穷远点)
- 指定生成一点(射影坐标,即有xyz三个参数)
- 令Q = P
- 判断点是否为零点(即无穷远点,z==0)
- 求逆元,即输入(x,y)输出(x,-y)
- 判断点的阶是否为2
- 判断两点是否相等
- 点加,有两种:输入有斜率;输入无斜率
- 点减,即input:P,Q ; output:P+(-Q)
- 倍点,有2倍点和任意倍
- 随机生成一点
public_param.h
公共参数相关的函数
- 初始化公共参数(给它们赋值0)
- 从文件中读取公共参数
- 输出公共参数:
private_key.h
- 根据公钥生成私钥,大概就是由P和Q得到kernel的生成元R = [m]P+[n]Q,其中 存在逆元
isogeny.h
- 用生成元计算isogeny
- 把domain的点P 同源映射 到codomain上,有两种方法:velu和kohel
- 计算kernel的partition
- 计算共享曲线E,有两种:naive和strategy,naive的最后大概要650000ms,strategy的话大概是250000ms
3.2.Microsoft的代码
微软在GitHub上的开源软件仓库中的代码,还没看
4.运行时间测量与比较
运行环境:WSL2 c语言
该密钥生成方案并不快(相比对称密码和传统DH),我参考了知乎的说法,选用了<time.h>的clock_gettime()来测量运行时间 时间测量方法?- 知乎 (zhihu.com)
以下是一个demo
1 | /* |
最后会输出一段代码运行消耗的微秒数(microseconds)
但在我把它套在test_key_exchange上时(sidh-crypto的代码),发现报错:
1 | error: ‘CLOCK_MONOTONIC’ undeclared |
在头文件前面加上这个宏定义就好了(可能是gcc版本问题?
1 |
最后我测出来key_exchange的时间大概是(只是本地执行密钥交换的时间,公共参数初始化没算在内,用了**-O2**)
略大于 250000 ms(0.25秒)
在github上(随便)找了个ECDH的实现
测了一下它的速度100次,同样用的是 -O2 :
平均 38613.17 ms(0.038秒)
可以发现差距还是很大的,相差一个数量级。
5.优化方向
摘自[6]:目前,对于SIDH的优化计算主要从以下3个角度来展开:探索适合的域的形式;借助不同曲线形式、不同坐标形式的优势;利用一些特殊技巧,如加法链、Weil限制和双线性对等去优化
具体而言,有
(1)有限域的运算:任何加速底层的有限域的基本算术方法都能加快SIDH的实现。
(2)标量乘:即倍点运算
(3)曲线以及坐标的类型:不同的曲线模型以及不同的坐标形式,其上的点加、倍点、同源和同源曲线的代数操作的计算量是不同的
(4)同源和同源曲线的计算:在SIDH中,Alice和Bob均需要计算-同源和同源曲线。对于-同源的计算,需要进行e次 -同源的复合。显然复合次数越少,计算速度越快。对于同源曲线的计算,当 较大时,直接利用同源曲线公式计算效率较低。
(5)压缩公钥和恢复公钥的计算量:暂时忽略。
6.毕设相关
大概的毕设思路
第一章 椭圆曲线及其倍点运算介绍
第二章 SIDH的理论解析
第三章 SIDH的代码实现
第四章 SIDH的后续优化
第五章 结论
参考
[1] 后量子安全密钥交换协议SIDH简介 | Bintou’s Blog
[2] Efficient Implementations of A Quantum-Resistant Key-Exchange Protocol on Embedder systems
[3] Efficient algorithms for supersingular isogeny Diffie-Hellman
[4] A Friendly Introduction to Supersingular Isogeny Diffie-Hellman
[5] Vélu’s Formulas for SIDH - Maria Corte-Real Santos (mariascrs.com)
[6] 椭圆曲线同源的有效计算研究进展
[7] Quantum Computation and Quantum Information