区块链应用:椭圆曲线数字签名算法ECDSA

2022-09-06  本文已影响0人  架构师老狼

1 椭圆曲线密码学

2 应用场景

3 ECC与RSA算法的优势对⽐

与经典的RSA、DSA等公钥密码体制相⽐,椭圆密码体制有以下优点:

4 数字签名与验证过程

5 代码验证

func NewKeyPair() (ecdsa.PrivateKey, []byte) {
    // 生产secp256椭圆曲线
    curve := elliptic.P256()

    // 产生一个结构体指针,结构体类型ecdsa.PrivateKey
    private, err := ecdsa.GenerateKey(curve, rand.Reader)

    if err != nil {
        log.Panic(err)
    }

    fmt.Println("私钥:%x\n", private)
    fmt.Println("私钥X:%x\n", private.X.Bytes())
    fmt.Println("私钥Y:%x\n", private.Y.Bytes())
    fmt.Println("私钥D:%x\n", private.D.Bytes())

    // x坐标与y坐标拼接在一起生成公钥
    publicKey := append(private.X.Bytes(), private.Y.Bytes()...)

    fmt.Println("公钥:%x\n", publicKey)

    return *private, publicKey
}
func MakeSignatureDerString(r, s string) string {
    // 获取R和S的⻓度
    lenSigR := len(r) / 2
    lenSigS := len(s) / 2
    // 计算DER序列的总⻓度
    lenSequence := lenSigR + lenSigS + 4
    // 将10进制⻓度转16进制字符串
    strLenSigR := DecimalToHex(int64(lenSigR))
    strLenSigS := DecimalToHex(int64(lenSigS))
    strLenSequence := DecimalToHex(int64(lenSequence))
    // 拼凑DER编码
    derString := "30" + strLenSequence
    derString = derString + "02" + strLenSigR + r
    derString = derString + "02" + strLenSigS + s
    derString = derString + "01"
    return derString
}
   privateKey, publicKey := NewKeyPair()

    msg := sha256.Sum256([]byte("ecc数组签名"))

    r, s, _ := ecdsa.Sign(rand.Reader, &privateKey, msg[:])

    strSigR := fmt.Sprintf("%x", r) // r.MarshalText()
    strSigS := fmt.Sprintf("%x", s) // s.MarshalText()

    fmt.Printf("r、s的10进制:%#v, %#v\n", r, s)
    fmt.Println("r、s的16进制:", strSigR, strSigS)

    //r和s拼接在⼀起,形成数字签名的der格式
    signatureDer := MakeSignatureDerString(strSigR, strSigS)
    //打印数字签名的16进制显示
    fmt.Println("数字签名DER格式为:", signatureDer)
func VerifySig(pubKey, message []byte, r, s *big.Int) bool {
    curve := elliptic.P256()
    //公钥的⻓度
    keyLen := len(pubKey)
    //前⼀半为x轴坐标,后⼀半为y轴坐标
    x := big.Int{}
    y := big.Int{}
    x.SetBytes(pubKey[:(keyLen / 2)])
    y.SetBytes(pubKey[(keyLen / 2):])
    rawPubKey := ecdsa.PublicKey{curve, &x, &y}
    //根据交易哈希、公钥、数字签名验证成功:
    // ecdsa.Verify func Verify(pub *PublicKey, hash[] byte, r * big.Int, s * big.Int) bool
    res := ecdsa.Verify(&rawPubKey, message, r, s)
    return res
}
上一篇下一篇

猜你喜欢

热点阅读