Example #1
0
        public static PubKey RecoverCompact(uint256 hash, byte[] signatureEncoded)
        {
            if (signatureEncoded.Length < 65)
            {
                throw new ArgumentException("Signature truncated, expected 65 bytes and got " + signatureEncoded.Length);
            }


            int header = signatureEncoded[0];

            // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y,
            //                  0x1D = second key with even y, 0x1E = second key with odd y

            if (header < 27 || header > 34)
            {
                throw new ArgumentException("Header byte out of range: " + header);
            }

            var  sig        = DecodeSig(signatureEncoded);
            bool compressed = false;

            if (header >= 31)
            {
                compressed = true;
                header    -= 4;
            }
            int recId = header - 27;

            ECKey key = ECKey.RecoverFromSignature(recId, sig, hash, compressed);

            return(key.GetPubKey(compressed));
        }
Example #2
0
        public byte[] SignCompact(uint256 hash)
        {
            var sig = _ECKey.Sign(hash);
            // Now we have to work backwards to figure out the recId needed to recover the signature.
            int recId = -1;

            for (int i = 0; i < 4; i++)
            {
                ECKey k = ECKey.RecoverFromSignature(i, sig, hash, IsCompressed);
                if (k != null && k.GetPubKey(IsCompressed).ToHex() == PubKey.ToHex())
                {
                    recId = i;
                    break;
                }
            }

            if (recId == -1)
            {
                throw new InvalidOperationException("Could not construct a recoverable key. This should never happen.");
            }

            int headerByte = recId + 27 + (IsCompressed ? 4 : 0);

            byte[] sigData = new byte[65];              // 1 header + 32 bytes for R + 32 bytes for S

            sigData[0] = (byte)headerByte;

            Array.Copy(Utils.BigIntegerToBytes(sig.R, 32), 0, sigData, 1, 32);
            Array.Copy(Utils.BigIntegerToBytes(sig.S, 32), 0, sigData, 33, 32);
            return(sigData);
        }
Example #3
0
        public void RecoverySignature()
        {
            ECKey key = ECKey.FromPrivateKey(this.privatekey);

            ECDSASignature signature = key.Sign(signature_message);

            signature.Should().NotBeNull();

            key.Verify(signature_message, signature).Should().BeTrue();
            ECKey.RecoverFromSignature(signature, signature_message, false).PublicKey.SequenceEqual(key.PublicKey).Should().BeTrue();
        }
Example #4
0
        public static long CheckWeight(Permission permission, List <ByteString> signature, byte[] hash, List <ByteString> approve_list)
        {
            long result = 0;

            if (signature.Count > permission.Keys.Count)
            {
                throw new PermissionException(
                          "Signature count is" + signature.Count +
                          "more than key counts of permission" + permission.Keys.Count);
            }

            Dictionary <ByteString, long> signature_weight = new Dictionary <ByteString, long>();

            foreach (ByteString sign in signature)
            {
                if (sign.Length < 65)
                {
                    throw new SignatureFormatException("Signature size is" + sign.Length);
                }

                ECKey ec_key = ECKey.RecoverFromSignature(ECDSASignature.ExtractECDSASignature(sign.ToByteArray()),
                                                          hash,
                                                          false);

                byte[] publickey = ec_key.PublicKey;
                byte[] address   = Wallet.PublickKeyToAddress(ec_key.PublicKey);

                long weight = GetWeight(permission, address);
                if (weight == 0)
                {
                    throw new PermissionException(
                              sign.ToByteArray().ToHexString()
                              + "is signed by"
                              + Wallet.AddressToBase58(address)
                              + "but it is not contained of permission.");
                }

                if (signature_weight.ContainsKey(sign))
                {
                    throw new PermissionException(Wallet.AddressToBase58(address) + " has signed twice");
                }

                signature_weight.Add(sign, weight);
                if (approve_list != null)
                {
                    approve_list.Add(ByteString.CopyFrom(publickey));
                }
                result += weight;
            }

            return(result);
        }
Example #5
0
        public static PubKey RecoverCompact(uint256 hash, byte[] signatureEncoded)
        {
#if HAS_SPAN
            if (signatureEncoded.Length != 65)
            {
                throw new ArgumentException(paramName: nameof(signatureEncoded), message: "Signature truncated, expected 65");
            }
            Span <byte> msg = stackalloc byte[32];
            hash.ToBytes(msg);
            var  s     = signatureEncoded.AsSpan();
            int  recid = (s[0] - 27) & 3;
            bool fComp = ((s[0] - 27) & 4) != 0;
            Secp256k1.ECPubKey pubkey;
            Secp256k1.SecpRecoverableECDSASignature sig;
            if (Secp256k1.SecpRecoverableECDSASignature.TryCreateFromCompact(s.Slice(1), recid, out sig) && sig is Secp256k1.SecpRecoverableECDSASignature &&
                Secp256k1.ECPubKey.TryRecover(NBitcoinContext.Instance, sig, msg, out pubkey) && pubkey is Secp256k1.ECPubKey)
            {
                return(new PubKey(pubkey, fComp));
            }
            throw new InvalidOperationException("Impossible to recover the public key");
#else
            if (signatureEncoded.Length < 65)
            {
                throw new ArgumentException("Signature truncated, expected 65 bytes and got " + signatureEncoded.Length);
            }


            int header = signatureEncoded[0];

            // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y,
            //                  0x1D = second key with even y, 0x1E = second key with odd y

            if (header < 27 || header > 34)
            {
                throw new ArgumentException("Header byte out of range: " + header);
            }

            var  sig        = DecodeSig(signatureEncoded);
            bool compressed = false;

            if (header >= 31)
            {
                compressed = true;
                header    -= 4;
            }
            int recId = header - 27;

            ECKey key = ECKey.RecoverFromSignature(recId, sig, hash, compressed);
            return(key.GetPubKey(compressed));
#endif
        }
Example #6
0
        public byte[] SignCompact(uint256 hash, bool forceLowR)
        {
            if (hash is null)
            {
                throw new ArgumentNullException(nameof(hash));
            }
            AssertNotDisposed();
#if HAS_SPAN
            Span <byte> vchSig = stackalloc byte[65];
            int         rec    = -1;
            var         sig    = new Secp256k1.SecpRecoverableECDSASignature(_ECKey.Sign(hash, forceLowR, out rec), rec);
            sig.WriteToSpanCompact(vchSig.Slice(1), out int recid);
            vchSig[0] = (byte)(27 + rec + (IsCompressed ? 4 : 0));
            return(vchSig.ToArray());
#else
            var sig = _ECKey.Sign(hash, forceLowR);
            // Now we have to work backwards to figure out the recId needed to recover the signature.
            int recId = -1;
            for (int i = 0; i < 4; i++)
            {
                ECKey k = ECKey.RecoverFromSignature(i, sig, hash, IsCompressed);
                if (k != null && k.GetPubKey(IsCompressed).ToHex() == PubKey.ToHex())
                {
                    recId = i;
                    break;
                }
            }

            if (recId == -1)
            {
                throw new InvalidOperationException("Could not construct a recoverable key. This should never happen.");
            }

            int headerByte = recId + 27 + (IsCompressed ? 4 : 0);

            byte[] sigData = new byte[65];              // 1 header + 32 bytes for R + 32 bytes for S

            sigData[0] = (byte)headerByte;
#pragma warning disable 618
            Array.Copy(Utils.BigIntegerToBytes(sig.R, 32), 0, sigData, 1, 32);
            Array.Copy(Utils.BigIntegerToBytes(sig.S, 32), 0, sigData, 33, 32);
#pragma warning restore 618
            return(sigData);
#endif
        }
Example #7
0
        public CompactSignature SignCompact(uint256 hash, bool forceLowR)
        {
            if (hash is null)
            {
                throw new ArgumentNullException(nameof(hash));
            }
            if (!IsCompressed)
            {
                throw new InvalidOperationException("This operation is only supported on compressed pubkey");
            }
            AssertNotDisposed();
#if HAS_SPAN
            byte[] sigBytes = new byte[64];
            var    sig      = new Secp256k1.SecpRecoverableECDSASignature(_ECKey.Sign(hash, forceLowR, out var rec), rec);
            sig.WriteToSpanCompact(sigBytes, out _);
            return(new CompactSignature(rec, sigBytes));
#else
            var sig = _ECKey.Sign(hash, forceLowR);
            // Now we have to work backwards to figure out the recId needed to recover the signature.
            int recId = -1;
            for (int i = 0; i < 4; i++)
            {
                ECKey k = ECKey.RecoverFromSignature(i, sig, hash);
                if (k != null && k.GetPubKey(true).ToHex() == PubKey.ToHex())
                {
                    recId = i;
                    break;
                }
            }

            if (recId == -1)
            {
                throw new InvalidOperationException("Could not construct a recoverable key. This should never happen.");
            }
#pragma warning disable 618
            byte[] sigData = new byte[64];              // 1 header + 32 bytes for R + 32 bytes for S
            Array.Copy(Utils.BigIntegerToBytes(sig.R, 32), 0, sigData, 0, 32);
            Array.Copy(Utils.BigIntegerToBytes(sig.S, 32), 0, sigData, 32, 32);
#pragma warning restore 618
            return(new CompactSignature(recId, sigData));
#endif
        }
        public static int CalculateRecId(this ECKey key, ECDSASignature signature, byte[] hash)
        {
            var recId   = -1;
            var thisKey = key.GetPubKey(false); // compressed

            for (var i = 0; i < 4; i++)
            {
                var k = ECKey.RecoverFromSignature(i, signature, hash, false).GetPubKey(false);
                if (k != null && Enumerable.SequenceEqual(k, thisKey))
                {
                    recId = i;
                    break;
                }
            }
            if (recId == -1)
            {
                throw new Exception("Could not construct a recoverable key. This should never happen.");
            }
            return(recId);
        }
Example #9
0
 //Note: Y coordinates can only be forced, so it is assumed 0 and 1 will be the recId (even if implementation allows for 2 and 3)
 internal int CalculateRecId(ECDSASignature signature, byte[] hash)
 {
   var recId = -1;
   var thisKey = _ecKey.GetPubKey(false); // compressed
   for (var i = 0; i \      {
     var rec = ECKey.RecoverFromSignature(i, signature, hash, false);
     if (rec != null)
     {
       var k = rec.GetPubKey(false);
       if (k != null && k.SequenceEqual(thisKey))
       {
         recId = i;
         break;
       }
     }
   }
   if (recId == -1)
     throw new Exception("Could not construct a recoverable key. This should never happen.");
   return recId;
 }
Example #10
0
        private static int CalculateRecId(ECDSASignature signature, byte[] hash, byte[] uncompressedPublicKey)
        {
            var recId = -1;

            for (var i = 0; i < 4; i++)
            {
                var rec = ECKey.RecoverFromSignature(i, signature, hash, false);
                var k   = rec?.GetPubKey(false);
                if (k != null && k.SequenceEqual(uncompressedPublicKey))
                {
                    recId = i;
                    break;
                }
            }
            if (recId == -1)
            {
                throw new ArgumentException("Could not construct a recoverable key. This should never happen.");
            }
            return(recId);
        }
Example #11
0
 public static NasECKey RecoverFromSignature(NasECDSASignature signature, int recId, byte[] hash)
 {
     return(new NasECKey(ECKey.RecoverFromSignature(recId, signature.ECDSASignature, hash, false)));
 }
Example #12
0
        //public static int GetRecIdFromVChain(byte[] vChain, BigInteger chainId)
        //{
        //    return GetRecIdFromVChain(vChain.ToBigIntegerFromRLPDecoded(), chainId);
        //}

        public static NasECKey RecoverFromSignature(NasECDSASignature signature, byte[] hash)
        {
            return(new NasECKey(ECKey.RecoverFromSignature(GetRecIdFromV(signature.V), signature.ECDSASignature, hash,
                                                           false)));
        }
Example #13
0
 public static EthECKey RecoverFromSignature(EthECDSASignature signature, byte[] hash, BigInteger chainId)
 {
     return(new EthECKey(ECKey.RecoverFromSignature(GetRecIdFromVChain(signature.V, chainId),
                                                    signature.ECDSASignature, hash, false)));
 }
Example #14
0
 public static EthECKey RecoverFromSignature(EthECDSASignature signature, int recId, byte[] hash)
 {
   return new EthECKey(ECKey.RecoverFromSignature(recId, signature.ECDSASignature, hash, false));
 }
Example #15
0
 public static EthECKey RecoverFromParityYSignature(EthECDSASignature signature, byte[] hash)
 {
     return(new EthECKey(ECKey.RecoverFromSignature(signature.V.ToIntFromRLPDecoded(), signature.ECDSASignature, hash,
                                                    false)));
 }
Example #16
0
        public static PubKey RecoverFromSignature(int recId, ECDSASignature sig, uint256 hash, bool compressed)
        {
            ECKey key = ECKey.RecoverFromSignature(recId, sig, hash, compressed);

            return(key?.GetPubKey(compressed));
        }