Example #1
0
 public byte[] SignHashed(byte[] messageHash, byte[] privateKey, bool useNewChainId)
 {
     if (privateKey.Length != 32)
     {
         throw new ArgumentException(nameof(privateKey));
     }
     if (messageHash.Length != 32)
     {
         throw new ArgumentException(nameof(messageHash));
     }
     return(EcSign.Benchmark(() =>
     {
         var sig = new byte[65];
         if (!Secp256K1.SignRecoverable(sig, messageHash, privateKey))
         {
             throw new Exception("secp256k1.sign_recoverable failed");
         }
         var serialized = new byte[64];
         if (!Secp256K1.RecoverableSignatureSerializeCompact(serialized, out var recId, sig))
         {
             throw new Exception("Cannot serialize recoverable signature: how did it happen?");
         }
         recId = TransactionUtils.ChainId(useNewChainId) * 2 + 35 + recId;
         var recIdBytes = new byte[useNewChainId ? 2 : 1];
         var fullBin = recId.ToBytes().ToArray();
         if (useNewChainId)
         {
             recIdBytes[0] = fullBin[1];
             recIdBytes[1] = fullBin[0];
         }
         else
         {
             recIdBytes[0] = fullBin[0];
         }
         return serialized.Concat(recIdBytes).ToArray();
     }));
 }
Example #2
0
 public byte[] RecoverSignatureHashed(byte[] messageHash, byte[] signature, bool useNewChainId)
 {
     if (messageHash.Length != 32)
     {
         throw new ArgumentException(nameof(messageHash));
     }
     if (signature.Length != SignatureSize(useNewChainId))
     {
         throw new ArgumentException(nameof(signature));
     }
     return(EcRecover.Benchmark(() =>
     {
         var parsedSig = new byte[65];
         var pk = new byte[64];
         var encodedRecId = RestoreEncodedRecIdFromSignatureBuffer(signature);
         var recId = (encodedRecId - 36) / 2 / TransactionUtils.ChainId(useNewChainId);
         if (recId < 0 || recId > 3)
         {
             throw new Exception($"Invalid recId={recId}: : recId >= 0 && recId <= 3 ");
         }
         if (!Secp256K1.RecoverableSignatureParseCompact(parsedSig, signature.Take(64).ToArray(), recId))
         {
             throw new ArgumentException(nameof(signature));
         }
         if (!Secp256K1.Recover(pk, parsedSig, messageHash))
         {
             throw new ArgumentException("Bad signature");
         }
         var result = new byte[33];
         if (!Secp256K1.PublicKeySerialize(result, pk, Flags.SECP256K1_EC_COMPRESSED))
         {
             throw new Exception("Cannot serialize recovered public key: how did it happen?");
         }
         return result;
     }));
 }
Example #3
0
        public bool VerifySignatureHashed(byte[] messageHash, byte[] signature, byte[] publicKey, bool useNewChainId)
        {
            if (messageHash.Length != 32 || signature.Length != SignatureSize(useNewChainId))
            {
                return(false);
            }
            return(EcVerify.Benchmark(() =>
            {
                var pk = new byte[64];
                if (!Secp256K1.PublicKeyParse(pk, publicKey))
                {
                    return false;
                }

                var publicKeySerialized = new byte[33];
                if (!Secp256K1.PublicKeySerialize(publicKeySerialized, pk, Flags.SECP256K1_EC_COMPRESSED))
                {
                    throw new Exception("Cannot serialize parsed key: how did it happen?");
                }

                var parsedSig = new byte[65];
                var recId = (RestoreEncodedRecIdFromSignatureBuffer(signature) - 36) / 2 / TransactionUtils.ChainId(useNewChainId);
                if (recId < 0 || recId > 3)
                {
                    throw new Exception($"Invalid recId={recId}: : recId >= 0 && recId <= 3 ");
                }
                if (!Secp256K1.RecoverableSignatureParseCompact(parsedSig, signature.Take(64).ToArray(), recId))
                {
                    return false;
                }

                return Secp256K1.Verify(parsedSig.Take(64).ToArray(), messageHash, pk);
            }));
        }