轻轻松松搞懂椭圆曲线加密算法

作者:Jian Shuo Wang 发表于:2022-09-12 22:29 · 未分类

数学领域,我用吃奶的劲试着解释加密算法的数学原理,结果失败了,以至于需要写第二遍(有人没看懂?再次尝试讲解 RSA 加密算法)。

这些还只是算数。椭圆曲线这样的听起来就高大上的东西,我本以为我不可能搞懂了。结果,自学了一下,发现居然原理惊人的容易(至于类似于 RSA 那样的手工可以求解,等以后小梅老师教了我再说吧)。

得到公钥密钥

先假设有种特殊的方法,只可以算乘法,但是不可以算除法(怎么搞晚些再说,椭圆曲线不是还在候场呢嘛?),加密一下变得惊人的简单。

你随便像一个巨大的数 k 作为密钥 (谁都不告诉的秘密),然后选一个常数G(就跟 π 一样,所有的人都用同一个数),k 倍的 G,就是你的公钥 K。

搞定了。公钥 K 和私钥 k 都有了。

怎么加密呢?

随便找个随机数 r,如果需要加密消息 M,别人可以把两个数字传给你:

rG 和 M + rK

G 是那个常数,rG 是 r 倍的常数 G,而 K 是 k 倍的常数 G。上面两个数其实就是这样两个数:

rG 和 M + rkG

看到两边的差别了吧?除了 M 以外,左右两边 rG 和 rkG 只差一个密钥 k。

解密的时候,只需要把左边的数字 rG 乘以谁都不知道的密钥 k,就变成 rkG。右边的数字减去 rkG,不就是原始 M 就出来了?

简单吧?似乎有点太简单了吧?椭圆曲线呢?更重要的问题是,我公钥 K 都知道了,除以 G 不就知道你的密钥了吗?

椭圆曲线

椭圆曲线可以登场了。它其实就是努力地构造一个只能做加法乘法,却无法反向操作做除法的神奇设备。

我们先假设我们设置了一个屋子,里面放满了形状奇怪的弧形镜子。

从一个固定的众所周知的点 G,射出一束激光。这激光在镜面上接连不断的反射下去。我们把每反射一次,定义为一次乘法。比如反射了一百万次以后到达的某个镜面上的那个点,就定义它是原来的点乘以 1 百万。这样子,如果我们知道屋子里面的镜子怎么摆放的,算出 100万次反射后的点是可能的。

实际上肯定也不是真的算 100 万次反射,有快捷的算法,可以直接算到第 2 次反射,第 4 次,第 8 次,第 16 次,第 32 次这样。无论多大的数,就算 2 的 256 次方,也就最多 510 次计算就算出来了,因为可以不断地翻倍的方式去逼近。

但是如果给你一个最终的点,问这是最初的那个点多少次反射得来的?这问题就麻烦了。因为你没有一个大概的范围,只能一次一次的试,2 的 256 次方都试过,基本上宇宙都已经寿终正寝了。

大家可能猜出来了,这个布满镜子的屋子,就是椭圆曲线。比特币,以太币用的都是 secp256k1 的参数的规定屋子布置,就是光线在 y^2 = x ^3 -7 这样一条弯曲的镜面上来回反射。G 是一个 secp256k1 规范中定死的数。私钥 k 就是反射的次数。G 反射 k 次就是公钥 K 。我虽然知道光线的起始点G,也知道终止点 K,但是无法不通过穷举的方法算出来反射的次数。

这就构造了一个神奇的乘法,却无法做除法的运算。基于这种定义下的乘法运算,就是本文开始的那个简单得让人无法相信的加密算法。

注一:这里省略了最复杂的部分,就是椭圆曲线是连续的,而实际上所有点的坐标取值需要是整数,而且要在一个有限的范围里面,所以数学家们就在一定数字以上(这个也是规范里面写死的)就取模,就把所有的数字都筐在一个有限的可能性里面了。

注二:其实我们要传递的只是一个数字 m,M 就是从 x = m ,求出满足椭圆曲线的那个点。对方拿到 M 后,只取 x ,忽略 y 就可以了。

注二:要定一个椭圆曲线算法需要六个参数,每次都传递六个参数太复杂,干脆 SEC 这个组织就直接写死了这六个参数,结果大家都直接用这六个参数了,这个就是叫做 secp256k1 的设定。其中,椭圆曲线被设定为 y^2 = x^3 - 7,G 这个点的坐标就写死为 (x,y):

x=0x79BE667EF9 DCBBAC55A0 6295CE870B0 7029BFCDB2 DCE28D959F 2815B16F817 98

y=0x483ADA7726 A3C4655DA4 FBFC0E1108A 8FD17B448A6 8554199C47D08 FFB10D4B8

你要感兴趣拿 python 试试,x 的三次方减去 7 正好等于 y 的平方。其他的几个参数就先略去了(我也还没搞懂)