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