ecdsa算法
ECC
椭圆曲线密码学算法(Elliptic curve cryptography,缩写为ECC),最初由Koblitz和Miller两人于1985年分别独立提出,是一种基于椭圆曲线数学的公开密钥加密算法,其数学基础是利用椭圆曲线上的有理点构成的Abel加法群上椭圆离散对数的计算困难性。
ECC的主要优势是在某些情况下它比其他的方法使用更小的密钥——比如RSA算法——提供相当的或更高等级的安全。
椭圆曲线
椭圆曲线的Weierstrass标准形式:
当判别式不为0,那么椭圆曲线就是非奇异的,即处处可导:
下图是非奇异的椭圆曲线示例。
椭圆曲线上的阿贝尔群
是一个集合,在集合中定义一个对两个元素的操作,记为"加",用表示,集合中两个元素和,“加”操作表示为,如果满足以下5个特性,就是一个阿贝尔群。
- 闭合性(closure): 若是中的元素,那么也是。
- 结合性(associativity): .
- 存在单位元(identity element 0):有.
- 每个元素都有一个相反数,对每个元素都存在使, 就是的相反数,可以表示为.
- 交换律:.
那么可以得到定义在椭圆曲线上的阿贝尔群。
- 一个椭圆曲线上的点是中的元素。
- 单位元定义为无穷远处的点。
- 一个点的相反数是关于轴对称的点。
- “加”定义为:是一条直线跟椭圆曲线相交的3个点,那么有,也就是.
当点加上它的相反数时,那么与椭圆曲线相交于无穷远点,也就是:
椭圆曲线的参数
上述内容简单说明了椭圆曲线算法的定义,但如果要将其转换为计算机能处理的离散算法,还需要做一些椭圆曲线参数上的限制。
椭圆曲线算法中的参数如下。
- 椭圆曲线中的系数.
- 有限域的大小是个素数.
- 子群基准点.
- 子群的阶.
- 子群的协因子.
有限域
之前的椭圆曲线是在实数域上的,并不适合计算机处理,所以我们必须把椭圆曲线变成离散的点。在ECC算法中选取模同余(为素数)的点来做“加”法。从而得到离散的有限域.
子群的基准点和子群的阶
首先需要定义一个椭圆曲线群的阶,表示该群中点的总量。
子群的基准点,其实就是椭圆曲线群中的任意一点,选取之后作为基准点。然后对其进行累加(可以转换为标量乘法)。
在有限域中,这样的加法会形成循环,也就是加到某一步,这时就得到一个基于基准点的子群,这个子群中一共有个点。此时就是这个子群的阶。
- 子群的阶就是子群中的元素个数,等价于,其是正整数,且是其中最小的1个,这个就是这个子群的阶。
- 根据拉格朗日定理,子群的阶,是父群阶的一个因子,比如一个椭圆曲线群有个元素,它的一个子群有n个元素,n能整除N.
子群的协因子
在实际使用中需要子群大一点,也就是的值大一点。但是根据基准点来计算,一个是范围太大,一个是没有直接公式可以计算子群的阶。所以实际中是先计算椭圆曲线群的阶,这个可以利用Schoof’s algorithm
算法计算,然后选取的一个较大的素因子作为子群的阶,令,就称做子群的协因子。在椭圆曲线中随机选择点,那么有。
因为总是任何一个的倍数。此时就可以选取作为这个子群的基准点了。方便快捷。
常用椭圆曲线参数
椭圆曲线的参数可以有多种配置方式,也就存在多种不同的曲线,例如secp256k1
、secp256r1
、Curve25519
等,不同曲线的安全性存在一些区别,在SafeCurves中有相关对比描述。
secp256k1
secp256k1
是高效密码组标准(SECG)协会开发的一套高效的椭圆曲线签名算法标准。在比特币流行之前,secp256k1
并未真正使用过。secp256k1
命名由几部分组成。
- sec来自SECG标准。
- p表示曲线坐标是素数域。
- 256表示素数是256位长。
- k表示它是Koblitz曲线的变体。
- 1表示它是第一个标准中该类型的曲线。
那为什么比特币要选择secp256k1
签名算法而不是其他已流行的算法呢?比特币开发者社区曾讨论过secp256k1
是否安全。中本聪没有明确解释,只是说道”有根据的推测”。从社区的讨论中,有推测是其它的曲线,比如secp256r1
中的参数是美国国安局精心挑选的,相当于安全性受到权威机构的干涉。总的来说选择secp256k1
是安全和性能考量的结果。以太坊沿用了比特币中的数字签名算法。
secp256k1
的参数如下。
secp256r1
secp256r1
是美国国家安全局建议使用的椭圆曲线,里面的r
代表曲线的参数是经过随机选取的。它也被称为NIST P-256
。
ECDSA算法
生成密钥对(genKey)
- 确定子群的阶数,基点.
- 选择随机数作为私钥,并计算出公钥.
这里计算很简单,但是根据公钥和基点却很难计算出私钥.
加密(encrypt)
- 准备要加密的数据,随机数.
- 计算密文:
解密(decrypt)
签名(sign)
- 对消息使用消息摘要算法,得到.
- 生成随机数,计算点.
- 取,若则重新选择随机数.
- 计算,若则重新选择随机数.
- 上述即为ECDSA签名。
验证(verify)
使用公钥和消息,对签名进行验证。
- 验证.
- 计算.
- 计算和.
- 计算.
- 判断,若相等则签名验证成功。
恢复(recover)
已知消息和签名,恢复计算出公钥。
- 验证
- 计算,其中,代入椭圆曲线方程计算获得.
- 计算.
- 计算和.
- 计算公钥
recoveryID
在计算的步骤可以看到,存在多个的取值可能性,导致存在多个的可能,因此计算得到的也存在多个可能的结果,需要通过和已知的公钥对比,确定哪一个是正确的。如果遍历的所有可能都未找到正确的,说明该消息和签名是不对应的,或者是一个未知的公钥。
为了确定正确的,需要遍历的所有可能取值,跑多轮recover
算法,这个时间开销是比较大的。为了提高recover
的时间效率,采用空间换时间的思路,在签名中增加一个值,用于快速确定,避免遍历查找试探,这个值就是recoveryId
。
由于,因此都可能是合法的原始x值,不同的椭圆曲线存在不同数量这样合法的x值,secp256k1
曲线存在两个可能。
每一个X轴坐标对应两个可能的Y坐标,因此secp256k1
曲线具备四种可能的。但是,对于一个值存在两个轴坐标的概率极低,低到几乎可以忽略,以太坊中就忽略了这两种小概率事件。
由于,是模的结果,是模的结果,值的范围是,值的范围是。如果也是曲线上的点,则的值必须小于,概率为,大约为,这个概率是非常小的。
参考资料
- 博客:ECC算法
- 博客:SM2算法第一篇:ECC加密算法
- 博客:一个数字引发的探索——ECDSA解析
- secp256k1参数:ECC SEC2
- hyperledger/fabric的关键机制——secp256r1
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)