Lab1实验报告

侯博文PB20000054

实验目的

  1. 理解非对称加密算法
  2. 理解椭圆曲线算法ECC
  3. 实现比特币上的椭圆曲线secp256k1算法

实验内容

完成签名和验签对应的函数部分

预实现部分

type ECC interface { Sign(msg []byte, secKey *big.Int) (*Signature, error) VerifySignature(msg []byte, signature *Signature, pubkey *Point) bool }

实验过程

PART I 签名流程

  1. 我们已知z和满足eG=P的e。
  2. 随机选取k。
  3. 计算R=kG,及其x轴坐标r。
  4. 计算 s=(z+re)/k。
  5. (r,s) 即为签名结果。

代码部分如下

func (ecc *MyECC) Sign(msg []byte, secKey *big.Int) (*Signature, error) {

     // 计算消息的哈希值,用于生成签名
     z := crypto.Keccak256(msg)
     zInt := new(big.Int).SetBytes(z)

    // 生成随机数 k
    k, err := newRand()
    if err != nil {
	return nil, err
    }

    // 计算 kG
    P1 := Multi(G,k)
    r := P1.X

    // 计算 k^-1
    kInv := Inv(k, N)

    // 计算 s = (h + xr) / k
    xr := new(big.Int).Mul(secKey, r)       //xr
    zInt.Add(zInt, xr)                      //h+xr
    s := new(big.Int).Mul(kInv, zInt)       //(h + xr) / k
    s.Mod(s, N)                             //(h + xr) / k(mod N)

    // 生成签名对象

    if s != nil {
	return &Signature{s: s, r: r}, nil
    }
    return nil, fmt.Errorf("error generating signature")
}

PART II 验证流程

  1. 接收签名者提供的(r,s)作为签名,z是被签名的内容的哈希值。P是签名者的公钥(或者公开的点)。
  2. 计算 u=z/s 和 v=r/s。
  3. 计算 uG + vP = R。
  4. 如果R的x轴坐标等于r,则签名是有效的

代码实现如下:

func (ecc *MyECC) VerifySignature(msg []byte, signature *Signature, pubkey *Point) bool {
    // Step 1: 计算哈希值 z
    z := crypto.Keccak256(msg)
    zInt := new(big.Int).SetBytes(z)
    // Step 2: 计算参数 u = z / s, v = r / s
    sInv := new(big.Int).ModInverse(signature.s, N)
    u := new(big.Int).Mul(zInt, sInv)
    u.Mod(u, N)
    v := new(big.Int).Mul(signature.r, sInv)
    v.Mod(v, N)

    // Step 3: 计算点 R = u*G + v*P
    R := Add(Multi(G, u), Multi(pubkey, v))

    // Step 4: 验签
	    return R.X.Cmp(signature.r) == 0
}

实验总结