Example #1
0
        /// <summary>
        /// Sign the message with <see cref="ECKeyPair"/>. Only recovery id 0 or 1 is accepted, otherwise the method will continue to retry to sign til get recovery id is 0 or 1.
        /// </summary>
        /// <param name="message">message to be signed</param>
        /// <param name="keyPair"></param>
        /// <param name="needToHash">set true if the message to be hashed before signing. If it is true, hashed first,then sign. If it is false, signed directly.</param>
        /// <returns></returns>
        public static SignatureData SignMessage(byte[] message, ECKeyPair keyPair, bool needToHash)
        {
            var publicKey = keyPair.PublicKey;

            byte[] messageHash;
            messageHash = needToHash ? CryptoUtils.Blake2b(message) : message;
            int            recId = -1;
            ECDSASignature sig;

            sig = keyPair.Sign(messageHash);
            for (int i = 0; i < 4; i++)
            {
                var k = RecoverFromSignature(i, sig, messageHash);
                if (k != null && k.Equals(publicKey))
                {
                    recId = i;
                    break;
                }
            }

            if (recId == -1)
            {
                throw new SignException("Sign the data failed.");
            }

            if (recId == 2 || recId == 3)
            {
                throw new SignException("Recovery is not valid for VeChain MainNet.");
            }

            byte v = (byte)recId;
            var  r = ByteUtils.ToBytesPadded(sig.R, 32);
            var  s = ByteUtils.ToBytesPadded(sig.S, 32);

            return(new SignatureData(v, r, s));
        }