public void testSignAndVerify1_NB()
        {
            //Single hash
            string fullURL = "https://btcpaytest.indiesquare.net/tokens";

            byte[] data       = Encoding.UTF8.GetBytes(fullURL);
            byte[] singleHash = null;
            using (var hash256 = SHA256.Create())
            {
                var bytes = Encoding.UTF8.GetBytes(fullURL);
                singleHash = hash256.ComputeHash(bytes);
            }

            //string sig = _nbKey.SignMessage(fullURL);//Double hashed and base64 but NOT DER
            //byte[] doubleHashedSig = Convert.FromBase64String(sig);

            ECDSASignature eCDSA     = _nbKey.Sign(new uint256(singleHash));
            string         sigDERStr = KeyUtils.bytesToHex(eCDSA.ToDER());

            // bitpay verify
            Assert.IsTrue(_ecKey.Verify(singleHash, eCDSA.ToDER()));

            //NBitcoin verify
            PubKey pubk = _nbKey.PubKey;

            Assert.IsTrue(pubk.Verify(new uint256(singleHash), new ECDSASignature(eCDSA.ToDER())));
            //Assert.IsTrue(pubk.Verify(doubleHash, new ECDSASignature(doubleHashedSig)));//NOT DER
        }
示例#2
0
        public void ToFromDer()
        {
            var signature = new ECDSASignature(
                TestUtils.HexToBigInteger("657912a72d3ac8169fe8eaecd5ab401c94fc9981717e3e6dd4971889f785790c"),
                TestUtils.HexToBigInteger("00ed3bf3456eb76677fd899c8ccd1cc6d1ebc631b94c42f7c4578f28590d651c6e"));

            var expected = Encoders.Hex.GetBytes("30450220657912a72d3ac8169fe8eaecd5ab401c94fc9981717e3e6dd4971889f785790c022100ed3bf3456eb76677fd899c8ccd1cc6d1ebc631b94c42f7c4578f28590d651c6e");

            CollectionAssert.AreEqual(expected, signature.ToDER());

            var signature1 = ECDSASignature.FromDER(signature.ToDER());

            Assert.AreEqual(signature.R, signature1.R);
            Assert.AreEqual(signature.S, signature1.S);
        }
        public void RunAsync_ProofOfStakeBlock_PayToPubKeyScriptPassesBlockSignatureValidation_DoesNotThrowException()
        {
            Block block = KnownNetworks.StratisMain.Consensus.ConsensusFactory.CreateBlock();

            block.Transactions.Add(KnownNetworks.StratisMain.CreateTransaction());

            Transaction transaction = KnownNetworks.StratisMain.CreateTransaction();

            transaction.Inputs.Add(new TxIn()
            {
                PrevOut   = new OutPoint(new uint256(15), 1),
                ScriptSig = new Script()
            });

            transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null));
            var scriptPubKeyOut = new Script(Op.GetPushOp(this.key.PubKey.ToBytes(true)), OpcodeType.OP_CHECKSIG);

            transaction.Outputs.Add(new TxOut(Money.Zero, scriptPubKeyOut));
            block.Transactions.Add(transaction);

            ECDSASignature signature = this.key.Sign(block.GetHash());

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

            this.ruleContext.ValidationContext.BlockToValidate = block;
            Assert.True(BlockStake.IsProofOfStake(this.ruleContext.ValidationContext.BlockToValidate));

            this.consensusRules.RegisterRule <PosBlockSignatureRule>().Run(this.ruleContext);
        }
示例#4
0
        public async Task RunAsync_ProofOfStakeBlock_OpCountBelowTwo_ThrowsBadBlockSignatureConsensusErrorExceptionAsync()
        {
            var block = new Block();

            block.Transactions.Add(new Transaction());

            var transaction = new Transaction();

            transaction.Inputs.Add(new TxIn()
            {
                PrevOut   = new OutPoint(new uint256(15), 1),
                ScriptSig = new Script()
            });

            transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null));
            transaction.Outputs.Add(new TxOut(Money.Zero, new Script(new Op()
            {
                Code = OpcodeType.OP_RETURN
            })));
            block.Transactions.Add(transaction);

            ECDSASignature signature = this.key.Sign(block.GetHash());

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

            this.ruleContext.BlockValidationContext.Block = block;
            Assert.True(BlockStake.IsProofOfStake(this.ruleContext.BlockValidationContext.Block));

            var exception = await Assert.ThrowsAsync <ConsensusErrorException>(() => this.consensusRules.RegisterRule <PosBlockSignatureRule>().RunAsync(this.ruleContext));

            Assert.Equal(ConsensusErrors.BadBlockSignature, exception.ConsensusError);
        }
        public void CanSerializeInJson()
        {
            var k = new Key();

            CanSerializeInJsonCore(DateTimeOffset.UtcNow);
            CanSerializeInJsonCore(new byte[] { 1, 2, 3 });
            CanSerializeInJsonCore(k);
            CanSerializeInJsonCore(Money.Coins(5.0m));
            CanSerializeInJsonCore(k.PubKey.GetAddress(KnownNetworks.Main));
            CanSerializeInJsonCore(new KeyPath("1/2"));
            CanSerializeInJsonCore(KnownNetworks.Main);
            CanSerializeInJsonCore(new uint256(RandomUtils.GetBytes(32)));
            CanSerializeInJsonCore(new uint160(RandomUtils.GetBytes(20)));
            CanSerializeInJsonCore(new AssetId(k.PubKey));
            CanSerializeInJsonCore(k.PubKey.ScriptPubKey);
            CanSerializeInJsonCore(new Key().PubKey.WitHash.GetAddress(KnownNetworks.Main));
            CanSerializeInJsonCore(new Key().PubKey.WitHash.ScriptPubKey.GetWitScriptAddress(KnownNetworks.Main));
            ECDSASignature sig = k.Sign(new uint256(RandomUtils.GetBytes(32)));

            CanSerializeInJsonCore(sig);
            CanSerializeInJsonCore(new TransactionSignature(sig, SigHash.All));
            CanSerializeInJsonCore(k.PubKey.Hash);
            CanSerializeInJsonCore(k.PubKey.ScriptPubKey.Hash);
            CanSerializeInJsonCore(k.PubKey.WitHash);
            CanSerializeInJsonCore(k);
            CanSerializeInJsonCore(k.PubKey);
            CanSerializeInJsonCore(new WitScript(new Script(Op.GetPushOp(sig.ToDER()), Op.GetPushOp(sig.ToDER()))));
            CanSerializeInJsonCore(new LockTime(1));
            CanSerializeInJsonCore(new LockTime(DateTime.UtcNow));
        }
示例#6
0
        public async Task RunAsync_ProofOfStakeBlock_PayToPubKeyScriptPassesBlockSignatureValidation_DoesNotThrowExceptionAsync()
        {
            var block = new Block();

            block.Transactions.Add(new Transaction());

            var transaction = new Transaction();

            transaction.Inputs.Add(new TxIn()
            {
                PrevOut   = new OutPoint(new uint256(15), 1),
                ScriptSig = new Script()
            });

            transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null));
            Script scriptPubKeyOut = new Script(Op.GetPushOp(this.key.PubKey.ToBytes(true)), OpcodeType.OP_CHECKSIG);

            transaction.Outputs.Add(new TxOut(Money.Zero, scriptPubKeyOut));
            block.Transactions.Add(transaction);

            ECDSASignature signature = this.key.Sign(block.GetHash());

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

            this.ruleContext.BlockValidationContext.Block = block;
            Assert.True(BlockStake.IsProofOfStake(this.ruleContext.BlockValidationContext.Block));

            await this.consensusRules.RegisterRule <PosBlockSignatureRule>().RunAsync(this.ruleContext);
        }
示例#7
0
        public async Task RunAsync_ProofOfStakeBlock_ScriptKeyPassesBlockSignatureValidation_DoesNotThrowExceptionAsync()
        {
            var block = Network.StratisMain.Consensus.ConsensusFactory.CreateBlock();

            block.Transactions.Add(Network.StratisMain.Consensus.ConsensusFactory.CreateTransaction());

            var transaction = Network.StratisMain.Consensus.ConsensusFactory.CreateTransaction();

            transaction.Inputs.Add(new TxIn()
            {
                PrevOut   = new OutPoint(new uint256(15), 1),
                ScriptSig = new Script()
            });

            transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null));
            // push op_return to note external dependancy in front of pay to pubkey script so it does not match pay to pubkey template.
            Script scriptPubKeyOut = new Script(OpcodeType.OP_RETURN, Op.GetPushOp(this.key.PubKey.ToBytes(true)), OpcodeType.OP_CHECKSIG);

            transaction.Outputs.Add(new TxOut(Money.Zero, scriptPubKeyOut));
            block.Transactions.Add(transaction);

            ECDSASignature signature = this.key.Sign(block.GetHash());

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

            this.ruleContext.BlockValidationContext.Block = block;
            Assert.True(BlockStake.IsProofOfStake(this.ruleContext.BlockValidationContext.Block));

            await this.consensusRules.RegisterRule <PosBlockSignatureRule>().RunAsync(this.ruleContext);
        }
示例#8
0
        public async Task RunAsync_ProofOfStakeBlock_FirstOpInScriptPubKeyNotOP_Return_ThrowsBadBlockSignatureConsensusErrorExceptionAsync()
        {
            var block = Network.StratisMain.Consensus.ConsensusFactory.CreateBlock();

            block.Transactions.Add(Network.StratisMain.Consensus.ConsensusFactory.CreateTransaction());

            var transaction = Network.StratisMain.Consensus.ConsensusFactory.CreateTransaction();

            transaction.Inputs.Add(new TxIn()
            {
                PrevOut   = new OutPoint(new uint256(15), 1),
                ScriptSig = new Script()
            });

            transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null));
            transaction.Outputs.Add(new TxOut(Money.Zero, new Script(new Op()
            {
                Code = OpcodeType.OP_CHECKSIG
            })));
            block.Transactions.Add(transaction);

            ECDSASignature signature = this.key.Sign(block.GetHash());

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

            this.ruleContext.BlockValidationContext.Block = block;
            Assert.True(BlockStake.IsProofOfStake(this.ruleContext.BlockValidationContext.Block));

            var exception = await Assert.ThrowsAsync <ConsensusErrorException>(() => this.consensusRules.RegisterRule <PosBlockSignatureRule>().RunAsync(this.ruleContext));

            Assert.Equal(ConsensusErrors.BadBlockSignature, exception.ConsensusError);
        }
示例#9
0
        public async Task RunAsync_ProofOfStakeBlock_CoinStakePayToPubScriptKeyInvalid_ThrowsBadBlockSignatureConsensusErrorExceptionAsync()
        {
            var block = new Block();

            block.Transactions.Add(new Transaction());

            var transaction = new Transaction();

            transaction.Inputs.Add(new TxIn()
            {
                PrevOut   = new OutPoint(new uint256(15), 1),
                ScriptSig = new Script()
            });

            // use different key with PayToPubKey script
            transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null));
            Script scriptPubKeyOut = new Script(Op.GetPushOp(new Key().PubKey.ToBytes(true)), OpcodeType.OP_CHECKSIG);

            transaction.Outputs.Add(new TxOut(Money.Zero, scriptPubKeyOut));
            block.Transactions.Add(transaction);

            ECDSASignature signature = this.key.Sign(block.GetHash());

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

            this.ruleContext.BlockValidationContext.Block = block;
            Assert.True(BlockStake.IsProofOfStake(this.ruleContext.BlockValidationContext.Block));

            var exception = await Assert.ThrowsAsync <ConsensusErrorException>(() => this.consensusRules.RegisterRule <PosBlockSignatureRule>().RunAsync(this.ruleContext));

            Assert.Equal(ConsensusErrors.BadBlockSignature, exception.ConsensusError);
        }
示例#10
0
        public void SerializeDeserializeCompact(ECDSASignature signature)
        {
            var b = signature.ToCompact();

            ECDSASignature.TryParseFromCompact(b, out var signature2);
            Assert.True(signature.ToDER().SequenceEqual(signature2.ToDER()));
        }
示例#11
0
        public void can_always_recover_pubkey_from_signature_when_stopping_at_null()
        {
            var rand = new Random();

            for (int i = 0; i < 1000; i++)
            {
                var      key   = new Key();
                PosBlock block = new PosBlock(new BlockHeader()
                {
                    Time = (uint)rand.Next()
                });
                ECDSASignature signature = key.Sign(block.GetHash());
                block.BlockSignature = new BlockSignature {
                    Signature = signature.ToDER()
                };
                Assert.True(key.PubKey.Verify(block.GetHash(), new ECDSASignature(block.BlockSignature.Signature)));
                signature = ECDSASignature.FromDER(block.BlockSignature.Signature);
                bool match = false;
                for (int recId = 0; !match; recId++)
                {
                    PubKey pubKeyForSig = PubKey.RecoverFromSignature(recId, signature, block.GetHash(), true);
                    if (pubKeyForSig == null)
                    {
                        break;
                    }

                    match = pubKeyForSig == key.PubKey;
                }
                Assert.True(match);
            }
        }
        public void RunAsync_ProofOfStakeBlock_NoOpsInScriptPubKey_ThrowsBadBlockSignatureConsensusErrorException()
        {
            Block block = KnownNetworks.StratisMain.Consensus.ConsensusFactory.CreateBlock();

            block.Transactions.Add(KnownNetworks.StratisMain.CreateTransaction());

            Transaction transaction = KnownNetworks.StratisMain.CreateTransaction();

            transaction.Inputs.Add(new TxIn()
            {
                PrevOut   = new OutPoint(new uint256(15), 1),
                ScriptSig = new Script()
            });

            transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null));
            transaction.Outputs.Add(new TxOut(Money.Zero, new Script()));
            block.Transactions.Add(transaction);

            ECDSASignature signature = this.key.Sign(block.GetHash());

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

            this.ruleContext.ValidationContext.BlockToValidate = block;
            Assert.True(BlockStake.IsProofOfStake(this.ruleContext.ValidationContext.BlockToValidate));

            ConsensusErrorException exception = Assert.Throws <ConsensusErrorException>(() => this.consensusRules.RegisterRule <PosBlockSignatureRule>().Run(this.ruleContext));

            Assert.Equal(ConsensusErrors.BadBlockSignature, exception.ConsensusError);
        }
        public void RunAsync_ProofOfStakeBlock_CoinStakePayToPubScriptKeyInvalid_ThrowsBadBlockSignatureConsensusErrorException()
        {
            Block block = KnownNetworks.StratisMain.Consensus.ConsensusFactory.CreateBlock();

            block.Transactions.Add(KnownNetworks.StratisMain.CreateTransaction());

            Transaction transaction = KnownNetworks.StratisMain.CreateTransaction();

            transaction.Inputs.Add(new TxIn()
            {
                PrevOut   = new OutPoint(new uint256(15), 1),
                ScriptSig = new Script()
            });

            // use different key with PayToPubKey script
            transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null));
            var scriptPubKeyOut = new Script(Op.GetPushOp(new Key().PubKey.ToBytes(true)), OpcodeType.OP_CHECKSIG);

            transaction.Outputs.Add(new TxOut(Money.Zero, scriptPubKeyOut));
            block.Transactions.Add(transaction);

            ECDSASignature signature = this.key.Sign(block.GetHash());

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

            this.ruleContext.ValidationContext.BlockToValidate = block;
            Assert.True(BlockStake.IsProofOfStake(this.ruleContext.ValidationContext.BlockToValidate));

            ConsensusErrorException exception = Assert.Throws <ConsensusErrorException>(() => this.consensusRules.RegisterRule <PosBlockSignatureRule>().Run(this.ruleContext));

            Assert.Equal(ConsensusErrors.BadBlockSignature, exception.ConsensusError);
        }
示例#14
0
        //private IEnumerator postWithSignature(String uri, String json)
        //{
        //    Debug.Log(" postWithSignature() is called.");

        //    yield  return this.post(uri, json, true);
        //}

        private IEnumerator post(String uri, String json, bool signatureRequired = false)
        {
            Debug.Log(" post() is called URI:" + uri);
            Debug.Log(" post() is called signatureRequired: " + signatureRequired);
            Debug.Log(" post() is called json before: " + json);
            json = unicodeToAscii(json);
            Debug.Log(" post() is called json after : " + json);
            using (UnityWebRequest httpClient = new UnityWebRequest(_baseUrl + uri, UnityWebRequest.kHttpVerbPOST))
            {
                httpClient.SetRequestHeader("x-accept-version", BITPAY_API_VERSION);
                httpClient.SetRequestHeader("x-bitpay-plugin-info", BITPAY_PLUGIN_INFO);
                httpClient.SetRequestHeader("Content-Type", "application/json");
                if (signatureRequired)
                {
                    //String signature = KeyUtils.sign(_ecKey, _baseUrl + uri + json);
                    string text       = _baseUrl + uri + json;
                    byte[] singleHash = null;
                    using (var hash256 = SHA256.Create())
                    {
                        var bytes = Encoding.UTF8.GetBytes(text);
                        singleHash = hash256.ComputeHash(bytes);
                    }
                    ECDSASignature eCDSA  = _ecKey.Sign(new uint256(singleHash));
                    string         newsig = KeyUtils.bytesToHex(eCDSA.ToDER());

                    httpClient.SetRequestHeader("x-signature", newsig);
                    //                    byte[] pubkBytes = _ecKey.PubKey;
                    byte[] pubkBytes = _ecKey.PubKey.Decompress().ToBytes();

                    httpClient.SetRequestHeader("x-identity", KeyUtils.bytesToHex(pubkBytes));
                    Debug.Log("POST HEADER:data:" + _baseUrl + uri + json);
                    Debug.Log("POST HEADER:x-signature:" + newsig);
                    Debug.Log("POST HEADER:x-identity(hex pubk):" + KeyUtils.bytesToHex(pubkBytes));
                }

                UploadHandlerRaw uH = new UploadHandlerRaw(System.Text.Encoding.UTF8.GetBytes(json));
                httpClient.uploadHandler   = uH;
                httpClient.downloadHandler = (DownloadHandler) new DownloadHandlerBuffer();
                UnityWebRequestAsyncOperation uwr = httpClient.SendWebRequest();// send request

                while (!uwr.isDone)
                {
                    //   Debug.Log(uwr.progress);
                    yield return(null);
                }

                if (httpClient.isNetworkError || httpClient.isHttpError)
                {
                    Debug.Log("post Error:" + httpClient.error);
                    Debug.Log("post Status:" + httpClient.responseCode);
                    yield return(httpClient.downloadHandler.text); // return donwloadhandler.text
                }
                else
                {
                    //  Debug.Log("postWithSignature(): Ready to download");
                    yield return(httpClient.downloadHandler.text); // return donwloadhandler.text
                }
            }
        }
        public void Sign(Key key, PoABlockHeader header)
        {
            ECDSASignature signature = key.Sign(header.GetHash());

            header.BlockSignature = new BlockSignature {
                Signature = signature.ToDER()
            };
        }
        public byte[] ToBytes()
        {
            var sig    = _Signature.ToDER();
            var result = new byte[sig.Length + 1];

            Array.Copy(sig, 0, result, 0, sig.Length);
            result[result.Length - 1] = (byte)_SigHash;
            return(result);
        }
        public void MultipleSignatureWays()
        {
            var privKeyStr = Encoders.Hex.DecodeData("8e812436a0e3323166e1f0e8ba79e19e217b2c4a53c970d4cca0cfb1078979df");
            Key key        = new Key(privKeyStr);

            Assert.AreEqual("04a5bb3b28466f578e6e93fbfd5f75cee1ae86033aa4bbea690e3312c087181eb366f9a1d1d6a437a9bf9fc65ec853b9fd60fa322be3997c47144eb20da658b3d1", key.PubKey.Decompress().ToHex());

            var messageToSign = "159817a085f113d099d3d93c051410e9bfe043cc5c20e43aa9a083bf73660145";
            var messageBytes  = Encoders.Hex.DecodeData(messageToSign);

            ECDSASignature signature = key.Sign(new uint256(messageBytes), true);

            SecpECDSASignature.TryCreateFromDer(signature.ToDER(), out SecpECDSASignature sig);
            var(r, s) = sig;

            var R = r.ToBytes();
            var S = s.ToBytes();

            Assert.AreEqual("38b7dac5ee932ac1bf2bc62c05b792cd93c3b4af61dc02dbb4b93dacb758123f", R.ToHexString());
            Assert.AreEqual("08bf123eabe77480787d664ca280dc1f20d9205725320658c39c6c143fd5642d", S.ToHexString());

            // Compact signature
            byte[] signatureCompact = key.SignCompact(new uint256(messageBytes), true);
            if (signatureCompact.Length != 65)
            {
                throw new ArgumentException(paramName: nameof(signatureCompact), message: "Signature truncated, expected 65");
            }

            var ss = signatureCompact.AsSpan();

            int recid = (ss[0] - 27) & 3;

            if (!(
                    SecpRecoverableECDSASignature.TryCreateFromCompact(ss.Slice(1), recid, out SecpRecoverableECDSASignature sigR) && sigR is SecpRecoverableECDSASignature
                    )
                )
            {
                throw new InvalidOperationException("Impossible to recover the public key");
            }

            // V from comapct signature
            var(r1, s1, v1) = sigR;

            Assert.AreEqual(v1, 0);

            // Recoverable signature with Secp256k1 lib
            NBitcoin.Secp256k1.ECPrivKey privKey = Context.Instance.CreateECPrivKey(new Scalar(key.ToBytes()));
            Assert.AreEqual(key.PubKey.ToBytes(), privKey.CreatePubKey().ToBytes());

            privKey.TrySignRecoverable(messageBytes, out SecpRecoverableECDSASignature sigRec);

            var(r2, s2, v2) = sigRec;

            Assert.AreEqual(r2, r);
            Assert.AreEqual(s2, s);
            Assert.AreEqual(v2, v1);
        }
        /// <summary>
        /// This helper creates a coin staking block containing a coin staking transaction built according to
        /// the parameters and with valid first input and output. The block signature is created correctly with the
        /// private key corresponding to the public key.
        /// </summary>
        /// <param name="useCompressedKey">Determines whether the second transaction output will include a compressed
        /// (versus uncompressed) public key.</param>
        /// <param name="includeSecondPush">Determines whether the second transaction output will include a small integer
        /// after the public key.</param>
        /// <param name="expectFailure">Determines whether we expect failure (versus success).</param>
        private void ProofOfStakeBlock_CoinStakeTestHelper(bool useCompressedKey, bool includeSecondPush, bool expectFailure)
        {
            Block block = KnownNetworks.StratisMain.Consensus.ConsensusFactory.CreateBlock();

            // Add a dummy coinbase transaction.
            block.Transactions.Add(KnownNetworks.StratisMain.CreateTransaction());

            // Build a coinstake transaction.
            Transaction coinStakeTransaction = KnownNetworks.StratisMain.CreateTransaction();

            coinStakeTransaction.Inputs.Add(new TxIn()
            {
                PrevOut   = new OutPoint(new uint256(15), 1),
                ScriptSig = new Script()
            });

            // First output of coinstake transaction is a special marker.
            coinStakeTransaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null));

            // Second (unspendable) output.
            // Depending on the test case use either a compressed public key or an uncompressed public key.
            var pubKey  = useCompressedKey ? this.key.PubKey.Compress() : this.key.PubKey.Decompress();
            var opCodes = new List <Op> {
                OpcodeType.OP_RETURN, Op.GetPushOp(pubKey.ToBytes(true))
            };

            // Depending on the test case add a second push of some small integer.
            if (includeSecondPush)
            {
                opCodes.Add(Op.GetPushOp(new byte[] { 123 }));
            }
            coinStakeTransaction.Outputs.Add(new TxOut(Money.Zero, new Script(opCodes)));

            // Add the coinstake transaction.
            block.Transactions.Add(coinStakeTransaction);

            // Add a signature to the block.
            ECDSASignature signature = this.key.Sign(block.GetHash());

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

            // Execute the PosBlockSignatureRule.
            this.ruleContext.ValidationContext.BlockToValidate = block;
            Assert.True(BlockStake.IsProofOfStake(this.ruleContext.ValidationContext.BlockToValidate));

            if (expectFailure)
            {
                ConsensusErrorException exception = Assert.Throws <ConsensusErrorException>(() =>
                                                                                            this.consensusRules.RegisterRule <PosBlockSignatureRule>().Run(this.ruleContext));
                Assert.Equal(ConsensusErrors.BadBlockSignature, exception.ConsensusError);
                return;
            }

            this.consensusRules.RegisterRule <PosBlockSignatureRule>().Run(this.ruleContext);
        }
示例#19
0
        static byte[] GetSignature(uint256 hashToSign, Key key)
        {
            var            signature = key.Sign(hashToSign, SigHash.All);
            ECDSASignature ecdsaSig  = signature.Signature;

            byte[] derSig   = ecdsaSig.ToDER();
            byte[] finalSig = new byte[derSig.Length + 1];
            Array.Copy(derSig, 0, finalSig, 0, derSig.Length);
            finalSig[finalSig.Length - 1] = (byte)SigHash.All;
            return(finalSig);
        }
示例#20
0
        private IEnumerator get(String uri, Dictionary <string, string> parameters = null)
        {
            String fullURL = _baseUrl + uri;

            Debug.Log("get() is called with " + fullURL);
            Debug.Log("get() is called parameters:" + parameters.Count);

            if (parameters != null)
            {
                fullURL += "?";
                foreach (KeyValuePair <string, string> entry in parameters)
                {
                    Debug.Log("get():  getting URL parameter :" + entry.Key + "=" + entry.Value);
                    fullURL += entry.Key + "=" + entry.Value + "&";
                }
                fullURL = fullURL.Substring(0, fullURL.Length - 1);
            }

            using (UnityWebRequest httpClient = UnityWebRequest.Get(fullURL)) {
                httpClient.SetRequestHeader("x-accept-version", BITPAY_API_VERSION);
                httpClient.SetRequestHeader("x-bitpay-plugin-info", BITPAY_PLUGIN_INFO);
//                httpClient.SetRequestHeader("Content-Type", "application/json");
                //                    String signature = KeyUtils.sign(_ecKey, fullURL);

                //string signature = _ecKey.SignMessage(fullURL);
                string text       = fullURL;
                byte[] singleHash = null;
                using (var hash256 = SHA256.Create())
                {
                    var bytes = Encoding.UTF8.GetBytes(text);
                    singleHash = hash256.ComputeHash(bytes);
                }
                ECDSASignature eCDSA  = _ecKey.Sign(new uint256(singleHash));
                string         newsig = KeyUtils.bytesToHex(eCDSA.ToDER());

                httpClient.SetRequestHeader("x-signature", newsig);
//                    httpClient.SetRequestHeader("x-signature", signature);
                //                    byte[] pubkBytes = _ecKey.PubKey;
                byte[] pubkBytes = _ecKey.PubKey.Decompress().ToBytes();
                httpClient.SetRequestHeader("x-identity", KeyUtils.bytesToHex(pubkBytes));
                Debug.Log("GET HEADER:URL+data =" + fullURL);
                Debug.Log("GET HEADER:x-signature:" + newsig);
                Debug.Log("GET HEADER:x-identity(hex pubk):" + KeyUtils.bytesToHex(pubkBytes));

                yield return(httpClient.SendWebRequest());     // send request

                yield return(httpClient.downloadHandler.text); // return donwloadhandler
            }
        }
示例#21
0
        public static void SignBlock(this SlimBlock slimBlock, Key blockSignatureKey)
        {
            if (slimBlock.IsProofOfStake)
            {
                var headerBytes = slimBlock.SlimBlockHeader.SerializeTo80Bytes();
                slimBlock.SlimBlockHeader.Data = headerBytes; // the Data field is used in serialization

                var            headerHash     = Hashes.DoubleSHA256(headerBytes);
                ECDSASignature signature      = blockSignatureKey.Sign(headerHash);
                var            blockSignature = new NBitcoin.Altcoins.X1Crypto.X1BlockSignature {
                    Signature = signature.ToDER()
                };
                slimBlock.SignatureBytes = blockSignature.ToBytes();
            }
            else
            {
                slimBlock.SignatureBytes = new[] { (byte)0 }; // VarString with length of zero, zero encoded as as VarInt
            }
        }
        public void ECDSASignatureIsOnlyBip66DER()
        {
            var invalidBIP66DER = HexToByteArray("302402107777777777777777777777777777777702108777777777777777777777777777777701");
            // Encodes:
            // SEQUENCE {
            //	 INTEGER 0x77777777777777777777777777777777,
            //   INTEGER 0x87777777777777777777777777777777 // -1 exponent :(
            // }
            // BOOLEAN FALSE
            var coercedSignature = new ECDSASignature(invalidBIP66DER);

            var validBIP66DER = HexToByteArray("302502107777777777777777777777777777777702110087777777777777777777777777777777");

            // Should coerce to this valid DER encoding:
            // SEQUENCE {
            //	 INTEGER 0x77777777777777777777777777777777,
            //   INTEGER 0x0087777777777777777777777777777777 // +1 exponent :)
            // }
            Assert.True(coercedSignature.ToDER().SequenceEqual(validBIP66DER));
        }
        public void testSignAndVerify2_NB()
        {
            //Double Hash
            string fullURL = "https://btcpaytest.indiesquare.net/tokens";

            byte[]  data       = Encoding.UTF8.GetBytes(fullURL);
            uint256 doubleHash = Hashes.Hash256(data);

            //Sign
            ECDSASignature eCDSA     = _nbKey.Sign(doubleHash);
            string         sigDERStr = KeyUtils.bytesToHex(eCDSA.ToDER());

            // bitpay verify
            Assert.IsTrue(_ecKey.Verify(doubleHash.ToBytes(), Encoders.Hex.DecodeData(sigDERStr)));

            //NBitcoin verify
            PubKey pubk = _nbKey.PubKey;

            Assert.IsTrue(pubk.Verify(doubleHash, new ECDSASignature(Encoders.Hex.DecodeData(sigDERStr))));
            //Assert.IsTrue(pubk.Verify(doubleHash, new ECDSASignature(doubleHashedSig)));//NOT DER
        }
示例#24
0
        public void Run_IsNotCanonicalBlockSignature_ThrowsBadBlockSignatureConsensusErrorException()
        {
            Block block = KnownNetworks.StratisMain.Consensus.ConsensusFactory.CreateBlock();

            block.Transactions.Add(KnownNetworks.StratisMain.CreateTransaction());

            Transaction transaction = KnownNetworks.StratisMain.CreateTransaction();

            transaction.Inputs.Add(new TxIn()
            {
                PrevOut   = new OutPoint(new uint256(15), 1),
                ScriptSig = new Script()
            });

            transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null));
            var scriptPubKeyOut = new Script(Op.GetPushOp(this.key.PubKey.ToBytes(true)), OpcodeType.OP_CHECKSIG);

            transaction.Outputs.Add(new TxOut(Money.Zero, scriptPubKeyOut));
            block.Transactions.Add(transaction);

            ECDSASignature signature = this.key.Sign(block.GetHash());

            signature = signature.MakeNonCanonical();

            // Ensure the non-canonical signature is still a valid signature for the block, just in the wrong format.
            Assert.True(this.key.PubKey.Verify(block.GetHash(), signature));
            Assert.False(signature.IsLowS);

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

            this.ruleContext.ValidationContext.BlockToValidate = block;
            Assert.True(BlockStake.IsProofOfStake(this.ruleContext.ValidationContext.BlockToValidate));

            ConsensusErrorException exception = Assert.Throws <ConsensusErrorException>(() => this.consensusRules.RegisterRule <PosBlockSignatureRepresentationRule>().Run(this.ruleContext));

            Assert.Equal(ConsensusErrors.BadBlockSignature, exception.ConsensusError);
        }
        public PosBlockBuilder(Network network, Key privateKey = null)
        {
            if (privateKey == null)
            {
                var mnemonic = new Mnemonic(Wordlist.English, WordCount.Twelve);
                privateKey = mnemonic.DeriveExtKey().PrivateKey;
            }

            // Create coinstake Tx.
            Transaction previousTx = network.CreateTransaction();

            previousTx.AddOutput(new TxOut());
            Transaction coinstakeTx = network.CreateTransaction();

            coinstakeTx.AddOutput(new TxOut(0, Script.Empty));
            coinstakeTx.AddOutput(new TxOut(50, new Script()));
            coinstakeTx.AddInput(previousTx, 0);

            // Create coinbase Tx.
            Transaction coinBaseTx = network.CreateTransaction();

            coinBaseTx.AddOutput(100, new Script());
            coinBaseTx.AddInput(new TxIn());

            var block = (PosBlock)network.CreateBlock();

            block.AddTransaction(coinBaseTx);
            block.AddTransaction(coinstakeTx);

            ECDSASignature signature = privateKey.Sign(block.Header.GetHash());

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

            this.posBlock = block;
        }
        public async Task RunAsync_ProofOfStakeBlock_ScriptKeyDoesNotPassCompressedUncompresedKeyValidation_ThrowsBadBlockSignatureConsensusErrorExceptionAsync()
        {
            Block block = Network.StratisMain.Consensus.ConsensusFactory.CreateBlock();

            block.Transactions.Add(Network.StratisMain.Consensus.ConsensusFactory.CreateTransaction());

            Transaction transaction = Network.StratisMain.Consensus.ConsensusFactory.CreateTransaction();

            transaction.Inputs.Add(new TxIn()
            {
                PrevOut   = new OutPoint(new uint256(15), 1),
                ScriptSig = new Script()
            });

            transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null));
            transaction.Outputs.Add(new TxOut(Money.Zero, new Script(new Op()
            {
                Code = OpcodeType.OP_RETURN
            }, new Op()
            {
                PushData = new byte[] { 0x11 }
            })));
            block.Transactions.Add(transaction);

            ECDSASignature signature = this.key.Sign(block.GetHash());

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

            this.ruleContext.ValidationContext.Block = block;
            Assert.True(BlockStake.IsProofOfStake(this.ruleContext.ValidationContext.Block));

            ConsensusErrorException exception = await Assert.ThrowsAsync <ConsensusErrorException>(() => this.consensusRules.RegisterRule <PosBlockSignatureRule>().RunAsync(this.ruleContext));

            Assert.Equal(ConsensusErrors.BadBlockSignature, exception.ConsensusError);
        }
示例#27
0
        public async Task RunAsync_ProofOfStakeBlock_ScriptKeyDoesNotPassBlockSignatureValidation_ThrowsBadBlockSignatureConsensusErrorExceptionAsync()
        {
            var block = new Block();

            block.Transactions.Add(new Transaction());

            var transaction = new Transaction();

            transaction.Inputs.Add(new TxIn()
            {
                PrevOut   = new OutPoint(new uint256(15), 1),
                ScriptSig = new Script()
            });

            transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null));

            // push op_return to note external dependancy in front of pay to pubkey script so it does not match pay to pubkey template.
            // use a different key to generate the script so it does not pass validation.
            Script scriptPubKeyOut = new Script(OpcodeType.OP_RETURN, Op.GetPushOp(new Key().PubKey.ToBytes(true)), OpcodeType.OP_CHECKSIG);

            transaction.Outputs.Add(new TxOut(Money.Zero, scriptPubKeyOut));
            block.Transactions.Add(transaction);

            ECDSASignature signature = this.key.Sign(block.GetHash());

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

            this.ruleContext.BlockValidationContext.Block = block;
            Assert.True(BlockStake.IsProofOfStake(this.ruleContext.BlockValidationContext.Block));

            var exception = await Assert.ThrowsAsync <ConsensusErrorException>(() => this.consensusRules.RegisterRule <PosBlockSignatureRule>().RunAsync(this.ruleContext));

            Assert.Equal(ConsensusErrors.BadBlockSignature, exception.ConsensusError);
        }
示例#28
0
 public byte[] ToDER()
 {
     return(ECDSASignature.ToDER());
 }
        public async Task StraxCoinViewRuleFailsAsync()
        {
            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) & ~PosConsensusOptions.StakeTimestampMask;

            // 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));

            // Cirrus reward output
            coinstakeTransaction.Outputs.Add(new TxOut(this.network.Consensus.ProofOfStakeReward * StraxCoinviewRule.CirrusRewardPercentage / 100, StraxCoinstakeRule.CirrusRewardScript));

            // 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);
        }
示例#30
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());

                Assert.True(sign1.IsLowR && sign1.ToDER().Length <= 70);
                Assert.True(sign2.IsLowR && sign2.ToDER().Length <= 70);
                Assert.True(sign1C.IsLowR && sign1C.ToDER().Length <= 70);
                Assert.True(sign2C.IsLowR && sign2C.ToDER().Length <= 70);
            }
        }