Пример #1
0
        /// <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             = new U256N(privateKey);
            var         msg            = new U256N(message);
            Span <byte> tempPrivateKey = stackalloc byte[32];

            CreatePrivateKey(tempPrivateKey);
            var   k = new U256N(tempPrivateKey);
            var   p = (Point)EllipticCurve.MulG(k);
            U256N R = p.X.Value;
            U256N S = (msg + dA * R) / k;

            if (p.Y.Value.v0 % 2 != 0)
            {
                S = -S;
            }
            return(new Signature(R, S));
        }
Пример #2
0
        /// <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   = new U256N(message);
            var S_inv = ~(U256N)signature.S;
            var u1    = S_inv * msg;
            var u2    = S_inv * signature.R;
            var P     = EllipticCurve.MulG(u1) + new JacobianPoint(publicKey.X, publicKey.Y) * u2;

            return(P.X == signature.R * (P.Z ^ 2));
        }
Пример #3
0
        /// <summary>
        /// 从(消息,签名)恢复公钥
        /// </summary>
        /// <param name="message"></param>
        /// <param name="signature"></param>
        /// <returns></returns>
        unsafe public static PublicKey RecoverPublicKey(ReadOnlySpan <byte> message, Signature signature)
        {
            if (message.Length != 32)
            {
                throw new InvalidMessageException("消息长度必须是32字节");
            }

            U256N s  = signature.S;
            var   m  = new U256N(message);
            var   rY = EllipticCurve.GetY(signature.R);

            if (rY.Value.v0 % 2 != 0)
            {
                s = -s;
            }

            var rP    = new JacobianPoint(signature.R, rY);
            var r_inv = ~new U256N(signature.R);
            var u1    = EllipticCurve.MulG(-m * r_inv);
            var u2    = s * r_inv;
            var p     = (Point)(rP * u2 + u1);

            return(new PublicKey(p.X, p.Y));
        }