/// <summary> /// 使用公钥验证消息的签名是否正确 /// </summary> /// <param name="publicKey"></param> /// <param name="message"></param> /// <param name="signature"></param> /// <returns></returns> public static bool Verify(PublicKey publicKey, ReadOnlySpan <byte> message, Signature signature) { if (message.Length != 32) { throw new InvalidMessageException("消息长度必须是32字节"); } var msg = ModN.U256(message, bigEndian: true); var S_inv = ModN.Inverse(signature.S); var u1 = ModN.Mul(S_inv, msg); var u2 = ModN.Mul(S_inv, signature.R); var P = ModP.Add(ModP.MulG(u1), ModP.Mul(publicKey.ToPoint(), u2)); return(ModP.Equal(P.X, signature.R)); }
/// <summary> /// 根据私钥创建公钥 /// </summary> /// <param name="privateKey"></param> /// <returns></returns> unsafe public static PublicKey CreatePublicKey(ReadOnlySpan <byte> privateKey) { if (privateKey.Length != 32) { throw new InvalidPrivateKeyException("私钥长度必须是32字节"); } var k = new U256(privateKey, bigEndian: true); if (k.IsZero || k >= ModN.N) { throw new InvalidPrivateKeyException(); } var retPoint = ModP.MulG(k); Clear(&k); return(new PublicKey(ModP.ToU256(retPoint.X), ModP.ToU256(retPoint.Y))); }