椭圆曲线算法secp256k1 是如何生成公钥和私钥的?

作者:冯祥
链接:https://www.zhihu.com/question/22399196/answer/96016340
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

实际上椭圆曲线密码是一种公钥密码算法,公钥密码算法最根本的原理是利用信息的不对称性:即掌握私钥的人在整个通信过程中掌握最多的信息【上(开)帝(图)视(可)角(耻)】,一切的运算对他而言都是没有秘密的。为了让别人能给自己发送加密的信息,私钥拥有者把信息的一部分公开披露,披露的信息记为公钥。显而易见,一个公钥密码算法安全的必要条件(非充分)是“由公钥不能反推出私钥”。
/* 先看一个栗子:
小明就读于小学二年级,会计算加法,但是不会计算除法。你是小明的怪蜀黍大强,你想出一道题给他做,让他虽然能理解题目意思但是做起来有难度:
强:“小明小明,过来,叔叔问你,1+1等于几?”
明:“叔叔的大学白念了吧,我幼儿园就会了,等于2。”
强:“那考你个难的,7+7等于几?”
明:“切,你当人家上课啃铅笔头,下课帮小红写作业都是白干的是吧。手指都不用数,等 于14呗。”
强:“行,有叔叔当年的风采,那叔叔再问你,几个7相加等于56?”
明:“……”,默默掏出草稿纸、铅笔、手指头、脚趾头,进行了10分钟的深度计算:2个7等于14,3个7等于21,4个7等于28……。“叔叔,我算出来了,是8个,对不对?”
强:“好小子,叔叔就不信考不倒你。几个7相加等于864192?” 你心中默念,以小明的计算能力,要算到这个数恐怕得一年半载的。
明:“叔叔好厉害呀,我算不出来。”
//明天去考考小红看她会不会算几个7等于56,不会算我就交她,嘿嘿。”
*/
与上述例子相同的是,椭圆曲线密码也是一个基于加法阶数难求问题的密码方案。 对于椭圆曲线密码来讲,椭圆曲线的基点就是例子里面的7,而私钥就是基点的加法阶数(例子里面的8),公钥是基点(7)进行对应阶数的加法(8次)得到的结果(56)。
与上述例子不同的是椭圆曲线密码里的加法建立在 “有限域上的二元三次曲线上的点”上 ,组成一个“有限加法循环群”。(好拗口的一句话。。)具体的说,这个加法的几何定义如下面两个图,两个点的加法结果是指这两点的连线和曲线的交点关于x轴的镜像。

椭圆曲线算法secp256k1 是如何生成公钥和私钥的?_第1张图片

图1:两个不同的点相加

 

椭圆曲线算法secp256k1 是如何生成公钥和私钥的?_第2张图片

图二:两个相同的点相加

 

看完这两幅图,默默思考1秒钟,你可能要问(炸)了(毛):为啥要这么定义加法?我还是喜欢小明的那个加法题,不喜欢这个。
之所以这么定义,原因有两个:
(1)给你求逆向运算(由公钥计算私钥)的时候制造困难。要是像小明一样在整数群里做加法,恐怕这密码体制只能用来给小红写信。
(2)为了构造一个封闭的“较好的”代数结构,简化正向运算(由私钥计算公钥的运算)。要是单纯为了求解困难,那可以定义五光十色的加法,但是加法定义的随性将导致了运算的复杂。为了能用一些最基本的运算:比如结合律、比如减法,才这么定义让这些点构成一个群。

行了,有了加法以后,我们只需要考虑两件事:
(1)如何正向计算(由私钥计算公钥)
确定椭圆曲线一个点作为基点P,由于所有的点构成一个有限群,那么基点P必然可以作为一个生成元生成一个子群。记这个子群的阶数为n,也就是说P点累加n次得到群的单位元(无穷远点),记做nP=0。(注意此处0只是一个代号,代指无穷远点,因为我们习惯了用0来表示加法单位元。)
正向计算的定义很简单,私钥为; 基点为点;公钥点Q定义为个相加:(原谅我公式写不好)

先说相加,最不济的算法就是直接相加K次,求解完毕,好一点的方法是使用二进制梯子来加,这样需要进行t次倍点(相同点相加)和t/2次点加(不同点相加),其中

椭圆曲线算法secp256k1 是如何生成公钥和私钥的?_第3张图片

当然还有更好的算法,比如说非相邻表示法(NAF)、窗口法等,此处不多说。

 

再说第二个问题,怎么用代数的方法求出两点相加。这恐怕得用一点高中数学了,此处直接上公式:
以域特征不等于2或3的定义在素数域GF(p)上曲线为例,曲线方程为:

椭圆曲线算法secp256k1 是如何生成公钥和私钥的?_第4张图片

椭圆曲线算法secp256k1 是如何生成公钥和私钥的?_第5张图片

从这两公式可以看到,要求点相加,只需要进行一些有限域的加减乘除即可。
事实上,加减乘除复杂度的关系如下:除法>乘法>加减。为了提高运算效率,往往在运算中把一个点的坐标保留分数的形式如:。运算过程中一直保留分数,直到运算结束再做一次除法,回到有限域,这种算法叫做投影坐标。
有了投影坐标以后,一次正向计算(私钥求公钥)其实就是一系列的乘法、加法、减法。当然,此处的乘法、加法、减法都是素数域上的运算。为了快速计算素数域乘法(实际上就是模乘),又诞生了一系列算法:蒙哥马利模乘算法,Barrett模乘算法等,都是通过预计算加快求模速度的算法。

 



(2)逆向计算(公钥反推私钥)有多难:
密码学家都既是大强也是小明,大强给小明出了题,必须让他算不出来,小明懂的东西一天天变多、计算速度一天天变快,大强的题也得一天天变复杂。
据本人的了解,目前由椭圆曲线公钥求解私钥的最有效算法复杂度为,其中是阶数的最大素因子。当参数选的足够好让时,以目前的计算能力,攻破椭圆曲线是不现实的。
但是,小明哪天长大,谁知道呢?小明哪天有了(量子)计算器,怎么难倒他呢?

转载于:https://my.oschina.net/u/3152070/blog/1577730

你可能感兴趣的:(java,区块链,c/c++)