Ejemplo n.º 1
0
             )] // testcase generated by nsec build
        public void ShouldDecryptSameDataInBothBuilds1(string hexKey, string hexPlainText, string nonceAndMacAndCipherText)
        {
            var hex             = new NBitcoin.DataEncoders.HexEncoder();
            var key             = hex.DecodeData(hexKey);
            var plainText       = hex.DecodeData(hexPlainText);
            var result          = hex.DecodeData(nonceAndMacAndCipherText);
            var c               = new ChaCha20Poly1305CryptoAlgorithm();
            var actualPlainText = c.Decrypt(key, result);

            Assert.Equal(hex.EncodeData(plainText), hex.EncodeData(actualPlainText));
        }
Ejemplo n.º 2
0
        public string SignTransaction(string transactionHex, WalletUnsignedTransactionUnspent[] unspents, Keychain userKeychain)
        {
            var hexEncoder = new NBitcoin.DataEncoders.HexEncoder();
            var extKey     = ExtKey.Parse(userKeychain.ExtendedPrivateKey);
            var builder    = new TransactionBuilder().ContinueToBuild(Transaction.Parse(transactionHex));

            foreach (var unspent in unspents)
            {
                builder
                .AddCoins(new ScriptCoin(new OutPoint(uint256.Parse(unspent.TransactionHash), unspent.TransactionOutputIndex), new TxOut(unspent.Value, new Script(hexEncoder.DecodeData(unspent.Script))), new Script(hexEncoder.DecodeData(unspent.RedeemScript))))
                .AddKeys(extKey.Derive(KeyPath.Parse($"{userKeychain.Path}/0/0{unspent.ChainPath}")).PrivateKey);
            }
            return(builder.BuildTransaction(true).ToHex());
        }
Ejemplo n.º 3
0
        public IActionResult CreateReviewerAddressAsync([FromBody] CreateReviewerAddressRequest request)
        {
            Guard.NotNull(request, nameof(request));

            // checks the request is valid
            if (!this.ModelState.IsValid)
            {
                return(ModelStateErrors.BuildErrorResponse(this.ModelState));
            }

            try
            {
                // calculate the Manager password hash
                byte[] binaryPassword = System.Text.Encoding.ASCII.GetBytes(request.RsaPassword);

                Org.BouncyCastle.Crypto.Digests.Sha512Digest sha = new Org.BouncyCastle.Crypto.Digests.Sha512Digest();
                sha.BlockUpdate(binaryPassword, 0, binaryPassword.Length);

                byte[] shaOutput = new byte[512 / 8];
                sha.DoFinal(shaOutput, 0);

                NBitcoin.DataEncoders.HexEncoder he = new NBitcoin.DataEncoders.HexEncoder();
                string rsaPasswordHashHex           = he.EncodeData(shaOutput);

                // create the multisig address
                PubKey[] groupMemberKeys = request.SignaturePubKeys.Select(pubKeyHex => new PubKey(pubKeyHex)).ToArray();

                var scriptPubKey = PayToMultiSigTemplate
                                   .Instance
                                   .GenerateScriptPubKey(request.RequeiredSignatureCount, groupMemberKeys);

                PublicReviewerAddressModel model = new PublicReviewerAddressModel
                {
                    PublicApiUrl = request.PublicApiUrl
                };

                // check if the API is reachable and the address can be added to the watch list
                Uri apiRequestUri = new Uri(new Uri(model.PublicApiUrl), $"/api/WatchOnlyWallet/watch?address={scriptPubKey.Hash.GetAddress(this.network).ToString()}");
                try
                {
                    HttpWebRequest apiRequest = (HttpWebRequest)WebRequest.Create(apiRequestUri);

                    ASCIIEncoding encoding = new ASCIIEncoding();
                    string        postData = "";
                    byte[]        data     = encoding.GetBytes(postData);

                    apiRequest.Method        = "POST";
                    apiRequest.ContentType   = "application/x-www-form-urlencoded";
                    apiRequest.ContentLength = data.Length;

                    using (Stream stream = apiRequest.GetRequestStream())
                    {
                        stream.Write(data, 0, data.Length);
                    }

                    HttpWebResponse apiResponse = (HttpWebResponse)apiRequest.GetResponse();

                    string responseString = new StreamReader(apiResponse.GetResponseStream()).ReadToEnd();

                    if (apiResponse.StatusCode != HttpStatusCode.OK)
                    {
                        throw new Exception($"The API request '{apiRequestUri.ToString()}' returned the status code '{apiResponse.StatusCode}'.");
                    }
                }
                catch (Exception e)
                {
                    throw new Exception($"The API request '{apiRequestUri.ToString()}' returned an error '{e.Message}'.");
                }


                // generate the RSA keypair for the address
                AsymmetricCipherKeyPair rsaKeyPair = GetRSAKeyPairFromSeed(request.RsaPassword + scriptPubKey.Hash.GetAddress(this.network).ToString());

                RsaKeyParameters rsaPublicKey = rsaKeyPair.Public as RsaKeyParameters;
                RsaPublicKey     pbk          = new RsaPublicKey()
                {
                    Exponent = rsaPublicKey.Exponent.ToByteArrayUnsigned(),
                    Modulus  = rsaPublicKey.Modulus.ToByteArrayUnsigned()
                };

                RsaPrivateCrtKeyParameters rsaPrivateKey = rsaKeyPair.Private as RsaPrivateCrtKeyParameters;
                RsaPrivateKey prk = new RsaPrivateKey()
                {
                    DP             = rsaPrivateKey.DP.ToByteArrayUnsigned(),
                    DQ             = rsaPrivateKey.DQ.ToByteArrayUnsigned(),
                    Exponent       = rsaPrivateKey.Exponent.ToByteArrayUnsigned(),
                    Modulus        = rsaPrivateKey.Modulus.ToByteArrayUnsigned(),
                    P              = rsaPrivateKey.P.ToByteArrayUnsigned(),
                    PublicExponent = rsaPrivateKey.PublicExponent.ToByteArrayUnsigned(),
                    Q              = rsaPrivateKey.Q.ToByteArrayUnsigned(),
                    QInv           = rsaPrivateKey.QInv.ToByteArrayUnsigned()
                };

                // return all the information we have
                model = new PublicReviewerAddressModel
                {
                    Network            = this.network.ToString(),
                    Address            = scriptPubKey.Hash.GetAddress(this.network).ToString(),
                    PublicName         = request.PublicName,
                    GroupName          = request.GroupName,
                    ValidFrom          = request.ValidFrom.ToString("o"),
                    ValidUntil         = request.ValidUntil.ToString("o"),
                    ScriptPubKeyHex    = scriptPubKey.ToHex(),
                    RsaPublicKeyHex    = pbk.ToHex(),
                    RsaPrivateKeyHex   = prk.ToHex(),
                    RsaPasswordHashHex = rsaPasswordHashHex,
                    PublicApiUrl       = request.PublicApiUrl
                };

                ((WalletManager)this.walletManager).AddReviewerAddressToReviewerStore(model);

                return(this.Json(model));
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }
Ejemplo n.º 4
0
        public void Fork_multisig_BTV()
        {
            string addr  = "3CgCi4KGK4kx5dddLdQqKHN1nmACMKRrac";
            string priv1 = "LnvAY6k625rPTDrB8jDajWgicFSPoBYZssxWyXucXw7HjvCS3XtA";
            string priv2 = "Ln7dHCpAHCaJ4Y7DjamLH4B3MMozafH4Fa5U9xFsyHRXys1oV1UJ";
            string rds   = "5221023009742d61ebe747b295bab6a9268b9dcfbdfccdc0fcb747083068f4be57c6ef21039b1df4cbb3a9f77cc41f7cf807470498f5efd2b1ea46142d16b26fb5af7012e452ae";

            Key a = Key.Parse(priv1);
            Key b = Key.Parse(priv2);

            Script redeemscript = PayToMultiSigTemplate
                                  .Instance
                                  .GenerateScriptPubKey(2, new[] { b.PubKey, a.PubKey });

            var ad1 = a.PubKey.GetAddress(Network.Main).ToString();
            var ad2 = b.PubKey.GetAddress(Network.Main).ToString();

            // http://www.soroushjp.com/2014/12/20/bitcoin-multisig-the-hard-way-understanding-raw-multisignature-bitcoin-transactions/
            //How many required (M of N)
            //OpcodeType.OP_2

            var    h = new NBitcoin.DataEncoders.HexEncoder();
            Script redeemscript_fb = new Script(h.DecodeData(rds));

            string pubAddress = redeemscript.Hash.GetAddress(Network.Main).ToString();//.GetScriptAddress(Network.Main).ToString();

            Console.WriteLine("Address: " + pubAddress);

            Assert.AreEqual(addr, pubAddress);

            //Add some bitcoin to the multisig address
            var received = new Transaction();

            received.Outputs.Add(new TxOut(Money.Coins(1.0m), redeemscript.Hash));

            Coin coin = received.Outputs.AsCoins().First().ToScriptCoin(redeemscript);

            //Create a transaction requiring two signatories
            BitcoinAddress     dest    = new Key().PubKey.GetAddress(Network.Main);
            TransactionBuilder builder = new TransactionBuilder();

            Transaction utx =
                builder
                .AddCoins(coin)
                .Send(dest, Money.Coins(0.9999m))
                .SendFees(Money.Coins(0.0001m))
                .SetChange(redeemscript.Hash)
                .BuildTransaction(sign: false);

            Console.WriteLine("Unsigned:");
            Console.WriteLine(utx.ToHex());

            Transaction sa =
                builder
                .AddCoins(coin)
                .AddKeys(a)
                .SignTransaction(utx, SigHash.ForkIdBTV, "BTV");

            Console.WriteLine("sa:");
            Console.WriteLine(sa.ToHex());

            Transaction sb =
                builder
                .AddCoins(coin)
                .AddKeys(b)
                .SignTransaction(sa, SigHash.ForkIdBTV, "BTV");

            Console.WriteLine("sb:");
            Console.WriteLine(sb.ToHex());

            Transaction stx = //sb;
                              builder
                              .AddCoins(coin)
                              .AddKeys(a)
                              .AddKeys(b)
                              .SignTransaction(utx, SigHash.ForkIdBTV, "BTV");

            //    builder
            //        .AddCoins(coin)
            //        .CombineSignatures("BTV", sa, sb);

            Console.WriteLine("stx:");
            Console.WriteLine(stx.ToHex());

            var res = builder.Verify(stx, "BTV");

            Assert.IsTrue(res);
        }
Ejemplo n.º 5
0
        public async Task <WalletUnsignedTransaction> CreateTransactionAsync(Dictionary <string, long> recepients, long?fee = null, long?feeRate = null, int feeTxConfirmTarget = 2, int minConfirms = 1, bool enforceMinConfirmsForChange = true, long minUnspentSize = 5460, bool?instant = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            var hexEncoder = new NBitcoin.DataEncoders.HexEncoder();
            var builder    = new TransactionBuilder();

            builder.DustPrevention = true;
            var totalValue = recepients.Values.Sum();
            var unspents   = await GetUnspentListAsync(instant, totalValue, null, null, minUnspentSize, cancellationToken);

            var changeAddress = await CreateAddressAsync(1, cancellationToken);

            builder.SetChange(_client.Network.CreateBitcoinAddress(changeAddress.Address));
            foreach (var unspent in unspents.Unspents)
            {
                builder.AddCoins(new ScriptCoin(new OutPoint(uint256.Parse(unspent.TransactionHash), unspent.TransactionOutputIndex), new TxOut(unspent.Value, new Script(hexEncoder.DecodeData(unspent.Script))), new Script(hexEncoder.DecodeData(unspent.RedeemScript))));
            }
            foreach (var recipient in recepients)
            {
                builder.Send(_client.Network.CreateBitcoinAddress(recipient.Key), recipient.Value);
            }
            var billingFee = await GetBillingFeeAsync(totalValue, instant ?? false, cancellationToken);

            if (billingFee > 0)
            {
                var billingAddress = await _client.Billing.GetAddressAsync(cancellationToken);

                billingFee = (long)Math.Min(billingFee, totalValue * 0.002);
                builder.Send(_client.Network.CreateBitcoinAddress(billingAddress), billingFee);
            }
            long finnalFee = 0;

            if (fee.HasValue)
            {
                builder.SendFees(fee.Value);
                finnalFee = fee.Value;
            }
            else if (feeRate.HasValue)
            {
                var estimatedFeeRate = new FeeRate(feeRate.Value);
                builder.SendEstimatedFees(estimatedFeeRate);
                finnalFee = builder.EstimateFees(estimatedFeeRate).Satoshi;
            }
            else
            {
                var estimateFee = await _client.Transactions.EstimateFeesAsync(feeTxConfirmTarget, cancellationToken);

                var estimatedFeeRate = new FeeRate(estimateFee.FeePerKb);
                builder.SendEstimatedFees(estimatedFeeRate);
                finnalFee = builder.EstimateFees(estimatedFeeRate).Satoshi;
            }

            var transactionHex = builder.BuildTransaction(false).ToHex();

            return(new WalletUnsignedTransaction
            {
                WalletId = _id,
                TransactionHex = transactionHex,
                Fee = finnalFee,
                ChangeAddress = new WalletUnsignedTransactionAddress {
                    Address = changeAddress.Address, Path = changeAddress.Path
                },
                WalletKeychains = (await GetAsync()).Keychains.Keychains.Select(k => new WalletUnsignedTransactionKeychain {
                    ExtendedPublicKey = k.ExtendedPublicKey, Path = k.Path
                }).ToArray(),
                Unspents = unspents.Unspents.Select(u => new WalletUnsignedTransactionUnspent {
                    RedeemScript = u.RedeemScript, Script = u.Script, ChainPath = u.ChainPath, TransactionHash = u.TransactionHash, TransactionOutputIndex = u.TransactionOutputIndex, Value = u.Value
                }).ToArray()
            });
        }