private static string GetBase58(PubKey blindingKey, BitcoinAddress address)
        {
            if (address == null)
            {
                throw new ArgumentNullException(nameof(address));
            }
            if (blindingKey == null)
            {
                throw new ArgumentNullException(nameof(blindingKey));
            }

            if (address is BitcoinBlindedAddress ba)
            {
                address = ba.UnblindedAddress;
            }
            if (!(address is IBase58Data))
            {
                byte          witVer;
                byte[]        witProg;
                var           blech32Encoder = address.Network.GetBech32Encoder(Bech32Type.BLINDED_ADDRESS, true);
                Bech32Encoder bech32Encoder  = null;
                switch (address)
                {
                case BitcoinWitPubKeyAddress _:
                    bech32Encoder = address.Network.GetBech32Encoder(Bech32Type.WITNESS_PUBKEY_ADDRESS, true);
                    break;

                case BitcoinWitScriptAddress _:
                    bech32Encoder = address.Network.GetBech32Encoder(Bech32Type.WITNESS_SCRIPT_ADDRESS, true);
                    break;

                default:
                    throw new ArgumentException($"no bech32 encoder for {address.GetType()} found");
                }

                witProg = bech32Encoder.Decode(address.ToString(), out witVer);
                return(blech32Encoder.Encode(witVer, blindingKey.ToBytes().Concat(witProg)));
            }
            else
            {
                var network = address.Network;
                var keyId   = address.ScriptPubKey.GetDestination();
                if (keyId == null)
                {
                    throw new ArgumentException("The passed address can't be reduced to a hash");
                }
                var bytes = address.Network.GetVersionBytes(Base58Type.BLINDED_ADDRESS, true).Concat(
                    network.GetVersionBytes(((IBase58Data)address).Type, true), blindingKey.ToBytes(),
                    keyId.ToBytes());
                return(NBitcoin.DataEncoders.Encoders.Base58Check.EncodeData(bytes));
            }
        }
        private static string GetBase58(PubKey blindingKey, BitcoinAddress address)
        {
            if (address == null)
            {
                throw new ArgumentNullException(nameof(address));
            }
            if (blindingKey == null)
            {
                throw new ArgumentNullException(nameof(blindingKey));
            }

            if (address is BitcoinBlindedAddress ba)
            {
                address = ba.UnblindedAddress;
            }
            if (!(address is IBase58Data))
            {
                byte          witVer;
                byte[]        witProg;
                var           blech32Encoder = address.Network.GetBech32Encoder(Bech32Type.BLINDED_ADDRESS, true);
                Bech32Encoder bech32Encoder;
                switch (address)
                {
                case BitcoinWitPubKeyAddress _:
                    bech32Encoder = address.Network.GetBech32Encoder(Bech32Type.WITNESS_PUBKEY_ADDRESS, true);
                    break;

                case BitcoinWitScriptAddress _:
                    bech32Encoder = address.Network.GetBech32Encoder(Bech32Type.WITNESS_SCRIPT_ADDRESS, true);
                    break;

                default:
                    throw new ArgumentException($"no bech32 encoder for {address.GetType()} found");
                }

                witProg = bech32Encoder.Decode(address.ToString(), out witVer);
                return(blech32Encoder.Encode(witVer, blindingKey.ToBytes().Concat(witProg)));
            }
            else
            {
                // Is Base58
                var network         = address.Network;
                var base58Unblinded = network.GetBase58CheckEncoder().DecodeData(address.ToString());
                var prefix          = network.GetVersionBytes(((IBase58Data)address).Type, true);
                var bytes           = address.Network.GetVersionBytes(Base58Type.BLINDED_ADDRESS, true).Concat(
                    prefix, blindingKey.ToBytes(),
                    base58Unblinded.Skip(prefix.Length).ToArray());
                return(network.GetBase58CheckEncoder().EncodeData(bytes));
            }
        }
Example #3
0
        public void base58_keys_valid_parse()
        {
            TestCase[] tests = TestCase.read_json(TestDataLocations.GetFileFromDataFolder("base58_keys_valid.json"));
            Network    network;

            foreach (TestCase test in tests)
            {
                string strTest = test.ToString();
                if (test.Count < 3) // Allow for extra stuff (useful for comments)
                {
                    Assert.True(false, "Bad test " + strTest);
                    continue;
                }

                string exp_base58string = (string)test[0];
                byte[] exp_payload      = TestUtils.ParseHex((string)test[1]);
                //const Object &metadata = test[2].get_obj();
                bool isPrivkey = (bool)test.GetDynamic(2).isPrivkey;
                bool isTestnet = (bool)test.GetDynamic(2).isTestnet;
                if (isTestnet)
                {
                    network = KnownNetworks.TestNet;
                }
                else
                {
                    network = KnownNetworks.Main;
                }

                if (isPrivkey)
                {
                    bool isCompressed = (bool)test.GetDynamic(2).isCompressed;

                    // Must be valid private key
                    // Note: CBitcoinSecret::SetString tests isValid, whereas CBitcoinAddress does not!
                    BitcoinSecret secret = network.CreateBitcoinSecret(exp_base58string);
                    //If not valid exception would throw

                    Key privkey = secret.PrivateKey;
                    Assert.True(privkey.IsCompressed == isCompressed, "compressed mismatch:" + strTest);
                    Assert.True(Utils.ArrayEqual(privkey.ToBytes(), exp_payload), "key mismatch:" + strTest);

                    // Private key must be invalid public key
                    Assert.Throws <FormatException>(() => network.CreateBitcoinAddress(exp_base58string));
                }
                else
                {
                    string exp_addrType = (string)test.GetDynamic(2).addrType; // "script" or "pubkey"
                                                                               // Must be valid public key
                    BitcoinAddress addr = network.CreateBitcoinAddress(exp_base58string);
                    Assert.True((addr is BitcoinScriptAddress) == (exp_addrType == "script"), "isScript mismatch" + strTest);

                    if (exp_addrType == "script")
                    {
                        Assert.True(addr.GetType() == typeof(BitcoinScriptAddress));
                    }
                    if (exp_addrType == "pubkey")
                    {
                        Assert.True(addr.GetType() == typeof(BitcoinPubKeyAddress));
                    }

                    Assert.Throws <FormatException>(() => network.CreateBitcoinSecret(exp_base58string));
                }
            }
        }