椭圆曲线数字签名算法

https://aaron67.cc/2020/09/30/ecdsa/

在文章非对称加密和签名认证中,我们介绍了双钥系统的两种应用场景:

  • 加密解密时,公钥用于加密,私钥用于解密
  • 身份认证时,私钥用于签名,公钥用于验证

椭圆曲线密码学(ECC,Elliptic Curve Cryptogphay)是一种流行的非对称加密算法,其背后的数学原理,是椭圆曲线上的离散对数难题。我们还知道,ECC 的私钥,本质是一个整数,其对应的公钥,是椭圆曲线上的一个点。

在将 ECC 作为双钥系统使用时,针对不同的应用场景,会涉及到不同的算法。常见的有

  • 在加密和解密时使用的椭圆曲线集成加密框架(ECIES,Elliptic Curve Integrated Encryption Schema)
  • 用于协商和交换公共密钥的椭圆曲线 Diffie-Hellman 密钥交换算法(ECDH,Elliptic Curve Diffie-Hellman Key Exchange)
  • 用于生成和验证数字签名的椭圆曲线数字签名算法(ECDSA,Elliptic Curve Digital Signature Algorithm)

本文将介绍并实现 ECDSA 的相关内容。

签名

用私钥 a a a 对消息 m m m 签名,得到的结果是两个整数 ( r , s ) (r, s) (r,s) ,计算过程如下。

  • 随机生成临时私钥 k k k,并计算其对应的公钥 K = k ⋅ G = ( x K , y K ) K = k \cdot G = (x_K, y_K) K=kG=(xK,yK)
  • 计算 r = x K   m o d   n r = x_K \bmod{n} r=xKmodn,若 r r r 为 0,则回到第一步
  • 计算消息 m m m 的哈希 e = h a s h ( m ) e = hash(m) e=hash(m),并将 e e e 的二进制序列转成一个整数
  • 计算 s = k − 1 ( e + r a )   m o d   n s = k^{-1}(e + ra) \bmod{n} s=k1(e+ra)modn,若 s s s 为 0,则回到第一步
  • 得到签名 ( r , s ) (r, s) (r,s)
import hashlib


def sha256(payload: bytes) -> bytes:
    return hashlib.sha256(payload).digest()


def double_sha256(payload: bytes) -> bytes:
    return sha256(sha256(payload))
import random


def hash_to_int(message: bytes) -> int:
    """Calculate the bitcoin double-sha256 hash of the message, return as an integer"""
    h = double_sha256(message)
    return int.from_bytes(h, byteorder='big')


def sign(private_key: int, message: bytes) -> tuple:
    """Create ECDSA signature (r, s)"""
    e = hash_to_int(message)
    r, s = 0, 0
    while not r or not s:
        k = random.randrange(1, curve.n)
        k_x, _ = scalar_multiply(k, curve.g)
        r = k_x % curve.n
        s = ((e + r * private_key) * modular_multiplicative_inverse(k, curve.n)) % curve.n
    return r, s

如果每次签名都使用相同的 k k k,当知道了消息 e 1 e_1 e1 e 2 e_2 e2 和签名 ( r 1 , s 1 ) (r_1, s_1) (r1,s1) ( r 2 , s 2 ) (r_2, s_2) (r2,s2) 时,有

  • r 1 = r 2 r_1 = r_2 r1=r2,因为 k k k 相同
  • 根据 s s s 的定义,有 s 1 − s 2 = k − 1 ( e 1 − e 2 )   m o d   n s_1 - s_2 = k^{-1}(e_1 - e_2) \bmod{n}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值