Example #1
0
 internal EthECDSASignature(ECDSASignature signature)
 {
     ECDSASignature = signature;
 }
Example #2
0
 internal EthECDSASignature(BigInteger[] rs)
 {
     ECDSASignature = new ECDSASignature(rs);
 }
Example #3
0
 public TransactionSignature(byte[] sigSigHash)
 {
     _Signature = ECDSASignature.FromDER(sigSigHash);
     _SigHash   = (SigHash)sigSigHash[sigSigHash.Length - 1];
 }
Example #4
0
        //Sign transaction using private key
        public byte[] SignTx(Key priv)
        {
            //Get serialized transaction
            byte[] tx = this.Serialize();

            //Debugging
            Console.WriteLine("Serialized Tx: ");
            foreach (byte b in tx)
            {
                Console.Write((int)b + " ");
            }
            Console.WriteLine();

            //Generate ECDSA signature
            ECDsaSigner            signer     = new ECDsaSigner(new HMacDsaKCalculator(new Sha256Digest()));
            ECPrivateKeyParameters privateKey = new ECPrivateKeyParameters(new BigInteger(1, priv.ToBytes()), domain);

            signer.Init(true, privateKey);
            BigInteger[] components = signer.GenerateSignature(this.Hash);

            //Debugging
            Console.WriteLine("Hash value: ");
            foreach (byte b in this.Hash)
            {
                Console.Write((int)b + " ");
            }
            Console.WriteLine();
            Console.WriteLine(components[0] + " " + components[1]);
            ECDSASignature ecdsaSignature = new ECDSASignature(components[0], components[1]).ToCanonicalised();

            //Encode to DER
            byte[] sigs = ecdsaSignature.EncodeToDER();

            //Debugging
            Console.WriteLine("Signature: ");
            foreach (byte b in sigs)
            {
                Console.Write((int)b + " ");
            }
            Console.WriteLine();

            byte[] sigsLen   = BitConverter.GetBytes(sigs.Length);
            byte[] pubKey    = priv.PubKey.ToBytes();
            byte[] pubKeyLen = BitConverter.GetBytes(pubKey.Length);

            //Reverse to big endian
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(sigsLen);
                Array.Reverse(pubKeyLen);
            }

            //Format: sigLen + sigs + pubKeyLen + pubKey + serialized Tx
            List <byte> result = new List <byte>();

            result.AddRange(sigsLen);
            result.AddRange(sigs);
            result.AddRange(pubKeyLen);
            result.AddRange(pubKey);
            result.AddRange(tx);

            Console.WriteLine("Signed bytes: ");
            foreach (byte b in result)
            {
                Console.Write((int)b + " ");
            }
            Console.WriteLine();

            Console.WriteLine("Signed Transaction: " + Convert.ToBase64String(result.ToArray()));

            return(result.ToArray());
        }
Example #5
0
 public void Sign(ECKey key)
 {
     signature  = key.SignAndCalculateV(RawHash);
     rlpEncoded = null;
 }
        public async Task PosCoinViewRuleFailsAsync()
        {
            var unspentOutputs = new Dictionary <OutPoint, UnspentOutput>();

            ConsensusManager consensusManager = await this.CreateConsensusManagerAsync(unspentOutputs);

            // The keys used by miner 1 and miner 2.
            var minerKey1 = new Key();
            var minerKey2 = new Key();

            // The scriptPubKeys (P2PK) of the miners.
            Script scriptPubKey1 = minerKey1.PubKey.ScriptPubKey;
            Script scriptPubKey2 = minerKey2.PubKey.ScriptPubKey;

            // Create the block that we want to validate.
            Block block = this.network.Consensus.ConsensusFactory.CreateBlock();

            // Add dummy first transaction.
            Transaction transaction = this.network.CreateTransaction();

            transaction.Inputs.Add(TxIn.CreateCoinbase(this.ChainIndexer.Tip.Height + 1));
            transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null));
            Assert.True(transaction.IsCoinBase);

            // Add first transaction to block.
            block.Transactions.Add(transaction);

            // Create a previous transaction with scriptPubKey outputs.
            Transaction prevTransaction = this.network.CreateTransaction();

            uint blockTime = (this.ChainIndexer.Tip.Header.Time + 60) & ~this.network.Consensus.ProofOfStakeTimestampMask;

            // To avoid violating the transaction timestamp consensus rule
            // we need to ensure that the transaction used for the coinstake's
            // input occurs well before the block time (as the coinstake time
            // is set to the block time)
            if (prevTransaction is IPosTransactionWithTime posTrx)
            {
                posTrx.Time = blockTime - 100;
            }

            // Coins sent to miner 2.
            prevTransaction.Outputs.Add(new TxOut(Money.COIN * 5_000_000, scriptPubKey2));
            // Coins sent to miner 1.
            prevTransaction.Outputs.Add(new TxOut(Money.COIN * 10_000_000, scriptPubKey1));

            // Record the spendable outputs.
            unspentOutputs.Add(new OutPoint(prevTransaction, 0), new UnspentOutput(new OutPoint(prevTransaction, 0), new Coins(1, prevTransaction.Outputs[0], prevTransaction.IsCoinBase)));
            unspentOutputs.Add(new OutPoint(prevTransaction, 1), new UnspentOutput(new OutPoint(prevTransaction, 1), new Coins(1, prevTransaction.Outputs[1], prevTransaction.IsCoinBase)));

            // Create coin stake transaction.
            Transaction coinstakeTransaction = this.network.CreateTransaction();

            coinstakeTransaction.Inputs.Add(new TxIn(new OutPoint(prevTransaction, 0)));
            coinstakeTransaction.Inputs.Add(new TxIn(new OutPoint(prevTransaction, 1)));

            // Coinstake marker.
            coinstakeTransaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null));
            // Normal pay to public key that belongs to the second miner with value that
            // equals to the sum of the inputs.
            coinstakeTransaction.Outputs.Add(new TxOut(Money.COIN * 15_000_000, scriptPubKey2));

            // The second miner signs the first transaction input which requires minerKey2.
            // Miner 2 will not have minerKey1 so we leave the second ScriptSig empty/invalid.
            new TransactionBuilder(this.network)
            .AddKeys(minerKey2)
            .AddCoins(new Coin(new OutPoint(prevTransaction, 0), prevTransaction.Outputs[0]))
            .SignTransactionInPlace(coinstakeTransaction);

            Assert.True(coinstakeTransaction.IsCoinStake);

            // Add second transaction to block.
            block.Transactions.Add(coinstakeTransaction);

            // Finalize the block and add it to the chain.
            block.Header.HashPrevBlock = this.ChainIndexer.Tip.HashBlock;
            block.Header.Time          = blockTime;
            block.Header.Bits          = block.Header.GetWorkRequired(this.network, this.ChainIndexer.Tip);
            block.SetPrivatePropertyValue("BlockSize", 1L);
            block.UpdateMerkleRoot();
            Assert.True(BlockStake.IsProofOfStake(block));
            // Add a signature to the block.
            ECDSASignature signature = minerKey2.Sign(block.GetHash());

            (block as PosBlock).BlockSignature = new BlockSignature {
                Signature = signature.ToDER()
            };

            // Execute the rule and check the outcome against what is expected.
            ConsensusException error = await Assert.ThrowsAsync <ConsensusException>(async() => await consensusManager.BlockMinedAsync(block));

            Assert.Equal(ConsensusErrors.BadTransactionScriptError.Message, error.Message);
        }
 public Script GenerateScriptSig(ECDSASignature signature)
 {
     return(GenerateScriptSig(new TransactionSignature(signature, SigHash.All)));
 }
Example #8
0
 public bool Verify(uint256 hash, ECDSASignature sig)
 {
     return(ECKey.Verify(hash, sig));
 }
 internal EthECDSASignature(ECDSASignature signature)
 {
     _ecdsaSignature = signature;
 }
Example #10
0
        public static ECKey RecoverFromSignature(int recId, ECDSASignature sig, uint256 message, bool compressed)
        {
            if (recId < 0)
            {
                throw new ArgumentException("recId should be positive");
            }
            if (sig.R.SignValue < 0)
            {
                throw new ArgumentException("r should be positive");
            }
            if (sig.S.SignValue < 0)
            {
                throw new ArgumentException("s should be positive");
            }
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }


            var curve = ECKey.Secp256k1;

            // 1.0 For j from 0 to h   (h == recId here and the loop is outside this function)
            //   1.1 Let x = r + jn

            var n = curve.N;
            var i = NBitcoin.BouncyCastle.Math.BigInteger.ValueOf((long)recId / 2);
            var x = sig.R.Add(i.Multiply(n));

            //   1.2. Convert the integer x to an octet string X of length mlen using the conversion routine
            //        specified in Section 2.3.7, where mlen = ⌈(log2 p)/8⌉ or mlen = ⌈m/8⌉.
            //   1.3. Convert the octet string (16 set binary digits)||X to an elliptic curve point R using the
            //        conversion routine specified in Section 2.3.4. If this conversion routine outputs “invalid”, then
            //        do another iteration of Step 1.
            //
            // More concisely, what these points mean is to use X as a compressed public key.
            var prime = ((SecP256K1Curve)curve.Curve).QQ;

            if (x.CompareTo(prime) >= 0)
            {
                return(null);
            }

            // Compressed keys require you to know an extra bit of data about the y-coord as there are two possibilities.
            // So it's encoded in the recId.
            ECPoint R = DecompressKey(x, (recId & 1) == 1);

            //   1.4. If nR != point at infinity, then do another iteration of Step 1 (callers responsibility).

            if (!R.Multiply(n).IsInfinity)
            {
                return(null);
            }

            //   1.5. Compute e from M using Steps 2 and 3 of ECDSA signature verification.
            var e = new NBitcoin.BouncyCastle.Math.BigInteger(1, message.ToBytes());
            //   1.6. For k from 1 to 2 do the following.   (loop is outside this function via iterating recId)
            //   1.6.1. Compute a candidate public key as:
            //               Q = mi(r) * (sR - eG)
            //
            // Where mi(x) is the modular multiplicative inverse. We transform this into the following:
            //               Q = (mi(r) * s ** R) + (mi(r) * -e ** G)
            // Where -e is the modular additive inverse of e, that is z such that z + e = 0 (mod n). In the above equation
            // ** is point multiplication and + is point addition (the EC group operator).
            //
            // We can find the additive inverse by subtracting e from zero then taking the mod. For example the additive
            // inverse of 3 modulo 11 is 8 because 3 + 8 mod 11 = 0, and -3 mod 11 = 8.

            var     eInv     = NBitcoin.BouncyCastle.Math.BigInteger.Zero.Subtract(e).Mod(n);
            var     rInv     = sig.R.ModInverse(n);
            var     srInv    = rInv.Multiply(sig.S).Mod(n);
            var     eInvrInv = rInv.Multiply(eInv).Mod(n);
            ECPoint q        = ECAlgorithms.SumOfTwoMultiplies(curve.G, eInvrInv, R, srInv);

            q = q.Normalize();
            if (compressed)
            {
                q = new SecP256K1Point(curve.Curve, q.XCoord, q.YCoord, true);
            }
            return(new ECKey(q.GetEncoded(), false));
        }
 internal EthECDSASignature(BigInteger r, BigInteger s, byte v)
 {
     _ecdsaSignature   = new ECDSASignature(r, s);
     _ecdsaSignature.V = v;
 }
        private BOLT11PaymentRequest(string str, Network network)
        {
            if (str == null)
            {
                throw new ArgumentNullException(nameof(str));
            }
            if (network == null)
            {
                throw new ArgumentNullException(nameof(network));
            }
            if (str.StartsWith("lightning:", StringComparison.OrdinalIgnoreCase))
            {
                str = str.Substring("lightning:".Length);
            }
            var decoded = InternalBech32Encoder.Instance.DecodeData(str);
            var hrp     = decoded.HumanReadablePart.ToLowerInvariant();

            Prefix        = hrp;
            MinimumAmount = LightMoney.Zero;
            if (Prefix.Length == 0)
            {
                throw new FormatException("Invalid BOLT11: No prefix");
            }
            ulong amount           = 0;
            int   firstNumberIndex = -1;

            for (int i = 0; i < Prefix.Length; i++)
            {
                int digit = Array.IndexOf(digits, Prefix[i]);
                if (digit != -1)
                {
                    if (firstNumberIndex == -1)
                    {
                        firstNumberIndex = i;
                    }
                    amount *= 10;
                    amount += (uint)digit;
                }
                else if (firstNumberIndex != -1)
                {
                    break;
                }
            }

            if (firstNumberIndex != -1)
            {
                LightMoneyUnit unit = LightMoneyUnit.BTC;
                switch (Prefix[Prefix.Length - 1])
                {
                case 'm':
                    unit = LightMoneyUnit.MilliBTC;
                    break;

                case 'u':
                    unit = LightMoneyUnit.Micro;
                    break;

                case 'n':
                    unit = LightMoneyUnit.Nano;
                    break;

                case 'p':
                    unit = LightMoneyUnit.MilliSatoshi;
                    if (amount % 10 != 0)
                    {
                        throw new FormatException("Pico BTC denomination which is not a multiple of 10 is not supported by BTCPayServer.Lightning");
                    }
                    amount = amount / 10UL;
                    break;

                default:
                    if (Array.IndexOf(digits, Prefix[Prefix.Length - 1]) == -1)
                    {
                        throw new FormatException("Invalid BOLT11: invalid amount multiplier");
                    }
                    unit = LightMoneyUnit.BTC;
                    break;
                }
                MinimumAmount = LightMoney.FromUnit(amount, unit);
                Prefix        = Prefix.Substring(0, firstNumberIndex);
                if (Prefix.Length == 0)
                {
                    throw new FormatException("Invalid BOLT11: No prefix");
                }
            }

            if (_Prefixes.TryGetValue((network.NetworkSet.CryptoCode, network.NetworkType), out var expectedPrefix) &&
                expectedPrefix != Prefix)
            {
                throw new FormatException("Invalid BOLT11: Invalid prefix");
            }

            var bitArray = new BitArray(decoded.Data.Length * 5);

            for (int di = 0; di < decoded.Data.Length; di++)
            {
                bitArray.Set(di * 5 + 0, ((decoded.Data[di] >> 4) & 0x01) == 1);
                bitArray.Set(di * 5 + 1, ((decoded.Data[di] >> 3) & 0x01) == 1);
                bitArray.Set(di * 5 + 2, ((decoded.Data[di] >> 2) & 0x01) == 1);
                bitArray.Set(di * 5 + 3, ((decoded.Data[di] >> 1) & 0x01) == 1);
                bitArray.Set(di * 5 + 4, ((decoded.Data[di] >> 0) & 0x01) == 1);
            }

            var reader = new BitReader(bitArray);

            reader.Position = reader.Count - 520 - 30;
            if (reader.Position < 0)
            {
                throw new FormatException("Invalid BOLT11: Invalid size");
            }

            if (!reader.CanConsume(65))
            {
                throw new FormatException("Invalid BOLT11: Invalid size");
            }
            var rs = reader.ReadBytes(65);

            _OriginalFormat = rs;
            ECDSASignature  = new ECDSASignature(
                new NBitcoin.BouncyCastle.Math.BigInteger(1, rs, 0, 32),
                new NBitcoin.BouncyCastle.Math.BigInteger(1, rs, 32, 32));
            RecoveryId = rs[rs.Length - 1];

            reader.Position = 0;
            Timestamp       = Utils.UnixTimeToDateTime(reader.ReadULongBE(35));

            void AssertSize(int c)
            {
                if (!reader.CanConsume(c))
                {
                    throw new FormatException("Invalid BOLT11: invalid size");
                }
            }

            ExpiryDate         = Timestamp + TimeSpan.FromHours(1);
            MinFinalCLTVExpiry = 9;
            var fallbackAddresses = new List <BitcoinAddress>();
            var routes            = new List <RouteInformation>();

            while (reader.Position != reader.Count - 520 - 30)
            {
                AssertSize(5 + 10);
                var tag  = reader.ReadULongBE(5);
                var size = (int)(reader.ReadULongBE(10) * 5);
                AssertSize(size);
                var afterReadPosition = reader.Position + size;
                switch (tag)
                {
                case 1:
                    if (size != 52 * 5)
                    {
                        break;
                    }
                    if (PaymentHash != null)
                    {
                        throw new FormatException("Invalid BOLT11: Duplicate 'p'");
                    }
                    PaymentHash = new uint256(reader.ReadBytes(32), false);
                    break;

                case 6:
                    ExpiryDate = Timestamp + TimeSpan.FromSeconds(reader.ReadULongBE(size));
                    break;

                case 13:
                    var bytesCount = size / 8;
                    var bytes      = reader.ReadBytes(bytesCount);
                    try
                    {
                        ShortDescription = UTF8NoBOM.GetString(bytes, 0, bytesCount);
                    }
                    catch
                    {
                    }
                    break;

                case 19:
                    if (size != 53 * 5)
                    {
                        break;
                    }
                    ExplicitPayeePubKey = new PubKey(reader.ReadBytes(33));
                    break;

                case 24:
                    var value = reader.ReadULongBE(size);
                    if (value > int.MaxValue)
                    {
                        break;
                    }
                    MinFinalCLTVExpiry = (int)value;
                    break;

                case 9:
                    if (size < 5)
                    {
                        break;
                    }
                    var version = reader.ReadULongBE(5);
                    switch (version)
                    {
                    case 0:
                        if (size == 5 + (20 * 8))
                        {
                            fallbackAddresses.Add(new BitcoinWitPubKeyAddress(new WitKeyId(reader.ReadBytes(20)), network));
                        }
                        else if (size == 5 + (32 * 8) + 4)
                        {
                            fallbackAddresses.Add(new BitcoinWitScriptAddress(new WitScriptId(reader.ReadBytes(32)), network));
                        }
                        break;

                    case 17:
                        if (size != 5 + (20 * 8))
                        {
                            break;
                        }
                        fallbackAddresses.Add(new BitcoinPubKeyAddress(new KeyId(reader.ReadBytes(20)), network));
                        break;

                    case 18:
                        if (size != 5 + (20 * 8))
                        {
                            break;
                        }
                        fallbackAddresses.Add(new BitcoinScriptAddress(new ScriptId(reader.ReadBytes(20)), network));
                        break;

                    default:
                        break;
                    }
                    break;

                case 23:
                    if (size != 52 * 5)
                    {
                        break;
                    }
                    DescriptionHash = new uint256(reader.ReadBytes(32), true);
                    break;

                case 3:
                    if (size < 264 + 64 + 32 + 32 + 16)
                    {
                        break;
                    }
                    var positionBefore   = reader.Position;
                    var routeInformation = new RouteInformation(reader, size);
                    var readen           = reader.Position - positionBefore;
                    if (size - readen >= 5)
                    {
                        break;
                    }
                    routes.Add(routeInformation);
                    break;
                }
                var skip = afterReadPosition - reader.Position;
                if (skip < 0)
                {
                    throw new FormatException("Invalid BOLT11: Invalid size");
                }
                reader.Consume(skip);
            }

            reader = new BitReader(bitArray, bitArray.Count - 520 - 30);
            int byteCount = Math.DivRem(reader.Count, 8, out var remainder);

            if (remainder != 0)
            {
                byteCount++;
            }
            var hashedData = UTF8NoBOM.GetBytes(hrp).Concat(reader.ReadBytes(byteCount)).ToArray();

            Hash              = new uint256(Hashes.SHA256(hashedData));
            Routes            = routes;
            FallbackAddresses = fallbackAddresses;
        }
Example #13
0
        /// <summary>
        /// Verify message signed using signmessage from bitcoincore
        /// </summary>
        /// <param name="message">The message</param>
        /// <param name="signature">The signature</param>
        /// <returns>True if signatures is valid</returns>
        public bool VerifyMessage(byte[] messageBytes, string signature)
        {
            ECDSASignature sig = DecodeSigString(signature);

            return(this.VerifyMessage(messageBytes, sig));
        }
Example #14
0
 public EthECDSASignature(byte[] derSig)
 {
     ECDSASignature = new ECDSASignature(derSig);
 }
 public TransactionSignature(byte[] sigSigHash)
 {
     _Signature = ECDSASignature.FromDER(sigSigHash.Take(sigSigHash.Length - 1).ToArray()).MakeCanonical();
     _SigHash   = (SigHash)sigSigHash[sigSigHash.Length - 1];
 }
Example #16
0
 public byte[] ToDER()
 {
     return(ECDSASignature.ToDER());
 }
Example #17
0
        public void key_test1()
        {
            BitcoinSecret bsecret1  = Network.Main.CreateBitcoinSecret(strSecret1);
            BitcoinSecret bsecret2  = Network.Main.CreateBitcoinSecret(strSecret2);
            BitcoinSecret bsecret1C = Network.Main.CreateBitcoinSecret(strSecret1C);
            BitcoinSecret bsecret2C = Network.Main.CreateBitcoinSecret(strSecret2C);

            Assert.Throws <FormatException>(() => Network.Main.CreateBitcoinSecret(strAddressBad));

            Key key1 = bsecret1.PrivateKey;

            Assert.True(key1.IsCompressed == false);
            Assert.True(bsecret1.Copy(true).PrivateKey.IsCompressed == true);
            Assert.True(bsecret1.Copy(true).Copy(false).IsCompressed == false);
            Assert.True(bsecret1.Copy(true).Copy(false).ToString() == bsecret1.ToString());
            Key key2 = bsecret2.PrivateKey;

            Assert.True(key2.IsCompressed == false);
            Key key1C = bsecret1C.PrivateKey;

            Assert.True(key1C.IsCompressed == true);
            Key key2C = bsecret2C.PrivateKey;

            Assert.True(key1C.IsCompressed == true);

            PubKey pubkey1  = key1.PubKey;
            PubKey pubkey2  = key2.PubKey;
            PubKey pubkey1C = key1C.PubKey;
            PubKey pubkey2C = key2C.PubKey;

            Assert.True(addr1.Hash == pubkey1.Hash);
            Assert.True(addr2.Hash == pubkey2.Hash);
            Assert.True(addr1C.Hash == pubkey1C.Hash);
            Assert.True(addr2C.Hash == pubkey2C.Hash);



            for (int n = 0; n < 16; n++)
            {
                string strMsg = String.Format("Very secret message {0}: 11", n);
                if (n == 10)
                {
                    //Test one long message
                    strMsg = String.Join(",", Enumerable.Range(0, 2000).Select(i => i.ToString()).ToArray());
                }
                uint256 hashMsg = Hashes.Hash256(TestUtils.ToBytes(strMsg));

                // normal signatures

                ECDSASignature sign1 = null, sign2 = null, sign1C = null, sign2C = null;
                List <Task>    tasks = new List <Task>();
                tasks.Add(Task.Run(() => sign1  = key1.Sign(hashMsg)));
                tasks.Add(Task.Run(() => sign2  = key2.Sign(hashMsg)));
                tasks.Add(Task.Run(() => sign1C = key1C.Sign(hashMsg)));
                tasks.Add(Task.Run(() => sign2C = key2C.Sign(hashMsg)));
                Task.WaitAll(tasks.ToArray());
                tasks.Clear();

                tasks.Add(Task.Run(() => Assert.True(pubkey1.Verify(hashMsg, sign1))));
                tasks.Add(Task.Run(() => Assert.True(pubkey2.Verify(hashMsg, sign2))));
                tasks.Add(Task.Run(() => Assert.True(pubkey1C.Verify(hashMsg, sign1C))));
                tasks.Add(Task.Run(() => Assert.True(pubkey2C.Verify(hashMsg, sign2C))));
                Task.WaitAll(tasks.ToArray());
                tasks.Clear();

                tasks.Add(Task.Run(() => Assert.True(pubkey1.Verify(hashMsg, sign1))));
                tasks.Add(Task.Run(() => Assert.True(!pubkey1.Verify(hashMsg, sign2))));
                tasks.Add(Task.Run(() => Assert.True(pubkey1.Verify(hashMsg, sign1C))));
                tasks.Add(Task.Run(() => Assert.True(!pubkey1.Verify(hashMsg, sign2C))));

                tasks.Add(Task.Run(() => Assert.True(!pubkey2.Verify(hashMsg, sign1))));
                tasks.Add(Task.Run(() => Assert.True(pubkey2.Verify(hashMsg, sign2))));
                tasks.Add(Task.Run(() => Assert.True(!pubkey2.Verify(hashMsg, sign1C))));
                tasks.Add(Task.Run(() => Assert.True(pubkey2.Verify(hashMsg, sign2C))));

                tasks.Add(Task.Run(() => Assert.True(pubkey1C.Verify(hashMsg, sign1))));
                tasks.Add(Task.Run(() => Assert.True(!pubkey1C.Verify(hashMsg, sign2))));
                tasks.Add(Task.Run(() => Assert.True(pubkey1C.Verify(hashMsg, sign1C))));
                tasks.Add(Task.Run(() => Assert.True(!pubkey1C.Verify(hashMsg, sign2C))));

                tasks.Add(Task.Run(() => Assert.True(!pubkey2C.Verify(hashMsg, sign1))));
                tasks.Add(Task.Run(() => Assert.True(pubkey2C.Verify(hashMsg, sign2))));
                tasks.Add(Task.Run(() => Assert.True(!pubkey2C.Verify(hashMsg, sign1C))));
                tasks.Add(Task.Run(() => Assert.True(pubkey2C.Verify(hashMsg, sign2C))));

                Task.WaitAll(tasks.ToArray());
                tasks.Clear();

                // compact signatures (with key recovery)

                byte[] csign1 = null, csign2 = null, csign1C = null, csign2C = null;

                tasks.Add(Task.Run(() => csign1  = key1.SignCompact(hashMsg)));
                tasks.Add(Task.Run(() => csign2  = key2.SignCompact(hashMsg)));
                tasks.Add(Task.Run(() => csign1C = key1C.SignCompact(hashMsg)));
                tasks.Add(Task.Run(() => csign2C = key2C.SignCompact(hashMsg)));
                Task.WaitAll(tasks.ToArray());
                tasks.Clear();

                PubKey rkey1 = null, rkey2 = null, rkey1C = null, rkey2C = null;
                tasks.Add(Task.Run(() => rkey1  = PubKey.RecoverCompact(hashMsg, csign1)));
                tasks.Add(Task.Run(() => rkey2  = PubKey.RecoverCompact(hashMsg, csign2)));
                tasks.Add(Task.Run(() => rkey1C = PubKey.RecoverCompact(hashMsg, csign1C)));
                tasks.Add(Task.Run(() => rkey2C = PubKey.RecoverCompact(hashMsg, csign2C)));
                Task.WaitAll(tasks.ToArray());
                tasks.Clear();

                Assert.True(rkey1.ToHex() == pubkey1.ToHex());
                Assert.True(rkey2.ToHex() == pubkey2.ToHex());
                Assert.True(rkey1C.ToHex() == pubkey1C.ToHex());
                Assert.True(rkey2C.ToHex() == pubkey2C.ToHex());
            }
        }
Example #18
0
 public bool Verify(uint256 hash, byte[] sig)
 {
     return(Verify(hash, ECDSASignature.FromDER(sig)));
 }
Example #19
0
        private static int CalculateRecId(ECKey eckey, ECDSASignature signature, byte[] hash)
        {
            var thisKey = eckey.GetPubKey(false);

            return(CalculateRecId(signature, hash, thisKey));
        }
Example #20
0
 public Transaction(byte[] nonce, byte[] gasPrice, byte[] gasLimit, byte[] receiveAddress, byte[] value,
                    byte[] data, byte[] r, byte[] s, byte v) : this(nonce, gasPrice, gasLimit, receiveAddress, value, data)
 {
     signature = EthECDSASignatureFactory.FromComponents(r, s, v);
 }
Example #21
0
 internal EthECDSASignature(BigInteger r, BigInteger s)
 {
     ECDSASignature = new ECDSASignature(r, s);
 }
Example #22
0
 public TransactionSignature(ECDSASignature signature)
     : this(signature, SigHash.All)
 {
 }
Example #23
0
 public EthECDSASignature(BigInteger r, BigInteger s, byte[] v)
 {
     ECDSASignature   = new ECDSASignature(r, s);
     ECDSASignature.V = v;
 }
Example #24
0
 public TransactionSignature(byte[] sig, SigHash sigHash)
 {
     _Signature = ECDSASignature.FromDER(sig);
     _SigHash   = sigHash;
 }
Example #25
0
        public void RunRule_ProvenHeadersActive_And_ValidProvenHeader_NoErrorsAreThrown()
        {
            // Setup private key.
            var mnemonic   = new Mnemonic(Wordlist.English, WordCount.Twelve);
            Key privateKey = mnemonic.DeriveExtKey().PrivateKey;

            // Setup previous chained header.
            PosBlock          prevPosBlock          = new PosBlockBuilder(this.network, privateKey).Build();
            ProvenBlockHeader prevProvenBlockHeader = new ProvenBlockHeaderBuilder(prevPosBlock, this.network).Build();
            var previousChainedHeader = new ChainedHeader(prevProvenBlockHeader, prevProvenBlockHeader.GetHash(), null);

            previousChainedHeader.SetPrivatePropertyValue("Height", this.options.ProvenHeadersActivationHeight + 1);

            // Setup proven header with valid coinstake.
            PosBlock posBlock = new PosBlockBuilder(this.network, privateKey).Build();

            posBlock.UpdateMerkleRoot();
            posBlock.Header.HashPrevBlock = prevProvenBlockHeader.GetHash();
            posBlock.Header.Bits          = 16777216;

            // Update signature.
            ECDSASignature signature = privateKey.Sign(posBlock.Header.GetHash());

            posBlock.BlockSignature = new BlockSignature {
                Signature = signature.ToDER()
            };

            ProvenBlockHeader provenBlockHeader = new ProvenBlockHeaderBuilder(posBlock, this.network).Build();

            provenBlockHeader.HashPrevBlock  = prevProvenBlockHeader.GetHash();
            provenBlockHeader.Coinstake.Time = provenBlockHeader.Time;

            // Setup chained header and move it to the height higher than proven header activation height.
            this.ruleContext.ValidationContext.ChainedHeaderToValidate = new ChainedHeader(provenBlockHeader, provenBlockHeader.GetHash(), previousChainedHeader);
            this.ruleContext.ValidationContext.ChainedHeaderToValidate.SetPrivatePropertyValue("Height", this.options.ProvenHeadersActivationHeight + 2);

            // Setup coinstake transaction with a valid stake age.
            uint unspentOutputsHeight = (uint)this.options.ProvenHeadersActivationHeight + 10;
            var  unspentOutputs       = new UnspentOutputs(unspentOutputsHeight, new Transaction())
            {
                Outputs = new[] { new TxOut(new Money(100), privateKey.PubKey) }
            };

            this.coinView
            .Setup(m => m.FetchCoinsAsync(It.IsAny <uint256[]>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(new FetchCoinsResponse(new[] { unspentOutputs }, posBlock.GetHash()));

            // Setup stake validator to pass stake age check.
            this.stakeValidator
            .Setup(m => m.IsConfirmedInNPrevBlocks(It.IsAny <UnspentOutputs>(), It.IsAny <ChainedHeader>(), It.IsAny <long>()))
            .Returns(true);

            // Setup stake validator to pass signature validation.
            this.stakeValidator
            .Setup(m => m.VerifySignature(It.IsAny <UnspentOutputs>(), It.IsAny <Transaction>(), It.IsAny <int>(), It.IsAny <ScriptVerify>()))
            .Returns(true);

            // Setup stake validator to pass stake kernel hash validation.
            this.stakeChain.Setup(m => m.Get(It.IsAny <uint256>())).Returns(new BlockStake());
            this.stakeValidator
            .Setup(m => m.CheckStakeKernelHash(It.IsAny <PosRuleContext>(), It.IsAny <uint>(), It.IsAny <uint256>(), It.IsAny <UnspentOutputs>(), It.IsAny <OutPoint>(), It.IsAny <uint>()));

            // When we run the validation rule, we should not hit any errors.
            Action ruleValidation = () => this.consensusRules.RegisterRule <ProvenHeaderCoinstakeRule>().Run(this.ruleContext);

            ruleValidation.Should().NotThrow();
        }