https://www.zhihu.com/question/26662683
作者:Kalafinaian
链接:https://www.zhihu.com/question/26662683/answer/325511510
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Oblivious 何処へ行くの
赞同 1159 条评论
分享
收藏感谢
收起
用户标识
密码学 话题的优秀回答者
47 人赞同了该回答
RSA请移步至这个答案,包含对题主问题的解答:
RSA的公钥和私钥到底哪个才是用来加密和哪个用来解密? - 刘巍然的回答
密码学里讲的椭圆曲线(EC),是解析式形如 的曲线,其中x的定义域通常在整数集合上【注1】,不是解析几何里讲的椭圆。
如果视曲线上的点P:(x,y)为一个元素,则整数a对P的乘法定义为:
这里的“+”是一个比较特殊的计算,对于已知不同两点P,Q, P+Q是这么算的:
如果P=Q, P+Q的算法稍有不同:
具体过程用代数式表达如下:(需考虑P=Q的情况)
以上算法和图片引自 Understanding Cryptography by C.Paar,
P = (x1,y1), Q=(x2,y2), +和-在算法中为普通四则运算,除法在中进行。
链接
《深入浅出密码学――常用加密技术原理与应用(安全技术经典译丛)》(美)帕尔,(美)佩尔茨尔 著,马小婷 译
附上C.Paar讲解EC的在线视频,需要翻墙:http://www.youtube.com/watch?v=3S9eZRHjP8g
根据这种加法运算,可以定义一个新的"离散对数问题":
已知G为EC上的一个点,EC参数和点K1已知,求满足的整数k2。
EC所生成的群,通常用来代替基于“离散对数问题”的加密方案或者数字签名中用到的群。比如EC-ElGamal,是把原来ElGama中使用的替换为相应阶数的椭圆曲线群。加密解密过程如下:
上图引自http://www.uam.es/personal_pdi/ciencias/fchamizo/asignaturas/cripto1011/ecc.pdf
概要翻译:
曲线参数A,B已知,点G已知,公钥为K1,
加密时选取一个随机整数r, 生成密文
解密时,用私钥k2参与计算,解出明文
安全性证明我就不写了,请参考原始论文。
【注1】密码学中一般考虑椭圆曲线定义在Finite Field上的情况,包括Integer Field。例如,定义一个EC为,且, 其中p为素数。
但实际上,椭圆曲线本身可以定义在实数空间甚至复数空间上。
赞同 472 条评论
分享
收藏感谢
收起
12 人赞同了该回答
文章来自我的博客,稍作修改。文章阅读需要高中数学知识以及对计算复杂度有基本概念。不要求了解群论相关内容。
离散对数和椭圆曲线加密原理 - 那些零零散散的算法 - CSDN博客blog.csdn.net
序言
不管是RSA还是ECC或者其它,公钥加密算法都是依赖于某个正向计算很简单(多项式时间复杂度),而逆向计算很难(指数级时间复杂度)的数学问题。
现代公钥加密系统中,离散对数加密和椭圆曲线加密形式比较相似,在这里一并介绍。
离散对数问题
我们在中学里学的对数问题是指,
给定正实数a和a^x,求x。也就是计算x=log(a^x)。
这是实数域上的对数问题,不是什么难算的东西,随便按一下计算器结果就出来了。
而离散对数问题是指这样的问题:
给定素数p和正整数g,知道g^x mod p的值,求x
对于符合特定条件的p和g,当x非常大时,使用传统计算机求x需要花费的时间会长到无法承受。
Diffie–Hellman密钥交换
Diffie–Hellman密钥交换(以下简称DH)是用于双方在可能被窃听环境下安全交换密钥的一种方法。
算法的安全性是由上面提到的离散对数难题保证。
具体算法流程如下:
- 小红和小明约定p和g的值
- 小红生成私钥x,计算g^x mod p作为公钥公布出去
- 小明生成私钥y,计算g^y mod p作为公钥公布出去
- 小红得知g^y mod p后,计算
- 小明得到g^x mod p后,计算
- 双方都得到了相同的密钥s,交换完毕
流程中,x和y始终由两人自行保管的,第三方窃听得到的只有p、g、g^x mod p和g^y mod p这几个值。
上面说过,离散对数是很难算的,所以第三方不能由这些信息计算出x或y,也就没办法计算出密钥s了。
椭圆曲线
中学的时候我们学过圆锥曲线,比如椭圆、双曲线和抛物线。因为描述这些曲线的方程都是二次方程,圆锥曲线又被称为二次曲线。而椭圆曲线是则是由三次方程描述的一些曲线。更准确地说,椭圆曲线是由下面的方程描述的曲线:
需要注意的是,椭圆曲线之所以叫“椭圆曲线”,是因为其曲线方程跟利用微积分计算椭圆周长的公式相似。实际上它的图像跟椭圆完全不搭边。
下图是椭圆曲线y^2=x^3-x+1的图像
椭圆曲线有这样的两个性质:
- 关于X轴对称
- 画一条直线跟椭圆曲线相交,它们最多有三个交点
椭圆曲线上的运算
由于椭圆曲线加密进行的运算实际上都是在椭圆曲线上进行的,所以接下来需要定义一些椭圆曲线上的运算。
必须注意的是,这里把这些运算称为“加法”和“乘法”仅仅是方便描述,他们跟平时认知的加法和乘法完全是两码事,完全可以给他们取其它名字(比如”乘法“和”幂运算“等)。
- 首先定义坐标系中距离X轴无穷远点为椭圆曲线上的一个特殊点,称为0点(零点)。
那么此时上述第二条性质可以加强为:过曲线上任意两点(可重合)的直线必定与曲线相交于第三点。 - 然后定义椭圆曲线上点的加法。设椭圆曲线上有两点,A和B点,那么作过这两点的直线与该曲线相交于第三点(C点),然后关于X轴对称得到D点,则D为这两个点的和,记作D=A+B。很明显,D点也在该曲线上。所以椭圆曲线上两点之和也是曲线上的点。
特别地,如果两点重合,则作椭圆曲线在A点处的切线,与曲线相交于第二点(B点),然后关于X轴对称得到C点,则C点为A点与自身的和,记作C=A+A
那么关于这个加法,我们可以得到以下结论:
- A+B=B+A
交换律。直线是没有方向的,因此从A出发作过B点的直线与从B点出发作过A点的直线是相同的。 - (A+B)+C=A+(B+C)
结合律。这个结论并不直观,需要较为复杂的证明,此处不做介绍,有兴趣的可以看看这里。
- 对于曲线上任意一点A,都存在曲线上另一点B,使得A+B=0
因为曲线关于X轴对称,所以曲线上总有另一点B使得过A、B的直线垂直于X轴,也就是该直线与曲线交于0点,所以A+B=0。
- A+0=A
因为0点是距离X轴无穷远的点,所以过A点与0点的直线是垂直于X轴的,它与曲线相交于另一点B点,那么B点关于X轴对称的点就是A点,即A点和0点之和就是A点自身。
然后在加法的基础上,定义椭圆曲线上点的乘法。
设P是椭圆曲线上的一个点,那么正整数k乘以点P的结果由下面的式子定义,注意式子中的加法是上面提到的椭圆曲线上点的加法:
1P=P 2P=P+P
3P=2P+P
...
kP=(k-1)P+P
从程序实现的角度来考虑,假设有这么一个函数:
Point add(Point A, Point B) {...}
函数参数是两个椭圆曲线上的点,返回值是过两个点的直线与椭圆曲线相交的第三个点关于X轴对称的点。
那么按照如下方式调用函数:
Point result = P;
for (int i = 0; i < k - 1; i++)
result = add(P, result);
sendTo((result, P), others);
也就是通过不断地迭代相加,就可以得到kP。
这个乘法满足以下性质:
对于任意正整数k和j,有
这个性质在椭圆曲线密钥交换中会利用到。
椭圆曲线上的离散对数问题
定义了基本的加法和乘法运算后,我们可以由此得到椭圆曲线加密依赖的数学难题。
k为正整数,P是椭圆曲线上的点(称为基点),已知kP和P,计算k
上面我们提到过椭圆曲线上点的加法满足结合律,那么,我们可以用快速幂的方法来计算kP,时间复杂度为 ,因此计算kP并不困难。这个问题的难度在于,对于第三方而言,只知道kP和P的值,想要反过来求出k的值,目前没有比枚举k的值好太多的算法。如果k特别大(比如在区间[2^255, 2^256]上),那么需要枚举的次数甚至已经远远超出天文数字的概念了。
如果我们改一种记法,把椭圆曲线上点的加法记作乘法,原来的乘法就变成了幂运算,那么上述难题的形式跟离散对数问题应该是一致的。即:
k为正整数,P是椭圆曲线上的点,已知P^k和P,计算k=log(P^k)。
尽管两者形式一致,但是他们并不等价。实际上这个问题比大整数质因子分解(RSA)和离散对数(DH)难题都要难得多,以致于同样的安全强度下,椭圆曲线加密的密钥比RSA和DH的要短不少,这是椭圆曲线加密的一大优势。
有限域上的椭圆曲线
但是密码学中,并不能使用上面介绍的实数域上的椭圆曲线。因为
1. 实数域上的椭圆曲线是连续的,有无限个点,密码学要求有限点。
2. 实数域上的椭圆曲线的运算有误差,不精确。密码学要求精确。
所以我们需要引入有限域上的椭圆曲线。
所谓有限域上的椭圆曲线,简单来说就是满足下面式子要求的曲线(x, y, a, b都是小于素数p的非负整数):
对比一下原先的椭圆曲线的方程:
可以看到这个只是对原式进行了简单的取模处理而已。
下图是椭圆曲线y^2 = x^3 - x + 1对素数97取模后的图像(图片来自参考文献A (relatively easy to understand) primer on elliptic curve cryptography,如果不介意英文的话这是一篇非常值得一读的介绍ECC的文章)
原本连续的曲线变成了离散的点,基本已经面目全非了,但是依然可以看到它是关于某条水平直线(y=97/2)对称的。
而且上面定义的椭圆曲线的加法仍然可用(当然乘法也可以)(图片来自参考文献)。
注意:密码学中有限域上的椭圆曲线一般有两种,一种是定义在以素数p为模的有限域GF(p),也就是上面介绍的;另一种则是定义在特征为2的有限域GF(2^m)上,篇幅所限,这里就不介绍了。
基于椭圆曲线的DH密钥交换(ECDH)
ECDH跟DH的流程基本是一致的。
- 小红和小明约定使用某条椭圆曲线(包括曲线参数,有限域参数以及基点P等)
- 小红生成私钥x,计算xP作为公钥公布出去
- 小明生成私钥y,计算yP作为公钥公布出去
- 小红得知yP后,计算
- 小明得到xP后,计算
- 双方都得到了相同的密钥s(因为s是一个点,实际上会取s的横坐标值作为密钥),交换完毕。
由于计算椭圆曲线上的离散对数是很难的,所以第三方没办法在只知道xP和yP的情况下计算出x或y的值。
实际应用中,我们并不需要关心椭圆曲线的众多参数如何选取(要选对参数对于普通使用者来说并不现实),只要从密码学家们精心挑选的一堆曲线中选择一个就行了。一般来说曲线Curve25519,prime256v1是比较常用的,比特币选择secp256k1则是因为它效率较高,并且其参数是可预测的,降低了包含后门的可能性。
参考文献
A (relatively easy to understand) primer on elliptic curve cryptography
Wikipedia: Elliptic curve cryptography
文中除引用图外,其它作图均使用GeoGebra完成。