/// <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> /// <param name="message"></param> /// <returns></returns> unsafe public static Signature Sign(ReadOnlySpan <byte> privateKey, ReadOnlySpan <byte> message) { if (privateKey.Length != 32) { throw new InvalidPrivateKeyException("私钥长度必须是32字节"); } if (message.Length != 32) { throw new InvalidMessageException("消息长度必须是32字节"); } var dA = ModN.U256(privateKey, bigEndian: true); var msg = ModN.U256(message, bigEndian: true); var tempPrivKey = CreatePrivateKey(); var tempPubKey = CreatePublicKey(tempPrivKey); var k = new U256(tempPrivKey, bigEndian: true); var S = ModN.Div(ModN.Add(msg, ModN.Mul(dA, tempPubKey.x)), k); tempPrivKey.AsSpan().Clear(); Clear(&dA); Clear(&k); return(new Signature(tempPubKey.x, S)); }