From 3d31e09cbb63984da88828b8acebba64e04f7a2d Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 19 Sep 2017 18:12:25 -0700 Subject: [PATCH] Split key_io (address/key encodings) off from base58 --- src/Makefile.am | 2 + src/base58.cpp | 249 +------------------------------------ src/base58.h | 33 +---- src/bitcoin-tx.cpp | 2 +- src/core_write.cpp | 2 +- src/httprpc.cpp | 2 +- src/key_io.cpp | 254 ++++++++++++++++++++++++++++++++++++++ src/key_io.h | 40 ++++++ src/rpcmisc.cpp | 2 +- src/rpcrawtransaction.cpp | 2 +- src/rpcserver.cpp | 2 +- src/test/base58_tests.cpp | 1 + src/test/bip32_tests.cpp | 2 +- src/test/bloom_tests.cpp | 2 +- src/test/key_tests.cpp | 2 +- src/test/rpc_tests.cpp | 2 +- src/wallet/rpcdump.cpp | 2 +- src/wallet/rpcwallet.cpp | 2 +- src/wallet/wallet.cpp | 2 +- src/wallet/walletdb.cpp | 2 +- 20 files changed, 315 insertions(+), 292 deletions(-) create mode 100644 src/key_io.cpp create mode 100644 src/key_io.h diff --git a/src/Makefile.am b/src/Makefile.am index 8cc654c37..0d2a7a7eb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -152,6 +152,7 @@ BITCOIN_CORE_H = \ httpserver.h \ init.h \ key.h \ + key_io.h \ keystore.h \ dbwrapper.h \ limitedmap.h \ @@ -368,6 +369,7 @@ libbitcoin_common_a_SOURCES = \ core_write.cpp \ hash.cpp \ key.cpp \ + key_io.cpp \ keystore.cpp \ netbase.cpp \ primitives/block.cpp \ diff --git a/src/base58.cpp b/src/base58.cpp index a37139486..137ce2c9e 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -4,21 +4,12 @@ #include "base58.h" -#include "hash.h" -#include "script/script.h" -#include "uint256.h" +#include +#include -#include "version.h" -#include "streams.h" - -#include -#include - -#include #include #include - /** All alphanumeric characters except for "0", "I", "O", and "l" */ static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; @@ -143,239 +134,3 @@ bool DecodeBase58Check(const std::string& str, std::vector& vchRe { return DecodeBase58Check(str.c_str(), vchRet); } - -namespace -{ -class DestinationEncoder : public boost::static_visitor -{ -private: - const CChainParams& m_params; - -public: - DestinationEncoder(const CChainParams& params) : m_params(params) {} - - std::string operator()(const CKeyID& id) const - { - std::vector data = m_params.Base58Prefix(CChainParams::PUBKEY_ADDRESS); - data.insert(data.end(), id.begin(), id.end()); - return EncodeBase58Check(data); - } - - std::string operator()(const CScriptID& id) const - { - std::vector data = m_params.Base58Prefix(CChainParams::SCRIPT_ADDRESS); - data.insert(data.end(), id.begin(), id.end()); - return EncodeBase58Check(data); - } - - std::string operator()(const CNoDestination& no) const { return ""; } -}; - -CTxDestination DecodeDestination(const std::string& str, const CChainParams& params) -{ - std::vector data; - uint160 hash; - if (DecodeBase58Check(str, data)) { - // base58-encoded Bitcoin addresses. - // Public-key-hash-addresses have version 0 (or 111 testnet). - // The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key. - const std::vector& pubkey_prefix = params.Base58Prefix(CChainParams::PUBKEY_ADDRESS); - if (data.size() == hash.size() + pubkey_prefix.size() && std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin())) { - std::copy(data.begin() + pubkey_prefix.size(), data.end(), hash.begin()); - return CKeyID(hash); - } - // Script-hash-addresses have version 5 (or 196 testnet). - // The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script. - const std::vector& script_prefix = params.Base58Prefix(CChainParams::SCRIPT_ADDRESS); - if (data.size() == hash.size() + script_prefix.size() && std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) { - std::copy(data.begin() + script_prefix.size(), data.end(), hash.begin()); - return CScriptID(hash); - } - } - return CNoDestination(); -} -} // namespace - -CKey DecodeSecret(const std::string& str) -{ - CKey key; - std::vector data; - if (DecodeBase58Check(str, data)) { - const std::vector& privkey_prefix = Params().Base58Prefix(CChainParams::SECRET_KEY); - if ((data.size() == 32 + privkey_prefix.size() || (data.size() == 33 + privkey_prefix.size() && data.back() == 1)) && - std::equal(privkey_prefix.begin(), privkey_prefix.end(), data.begin())) { - bool compressed = data.size() == 33 + privkey_prefix.size(); - key.Set(data.begin() + privkey_prefix.size(), data.begin() + privkey_prefix.size() + 32, compressed); - } - } - memory_cleanse(data.data(), data.size()); - return key; -} - -std::string EncodeSecret(const CKey& key) -{ - assert(key.IsValid()); - std::vector data = Params().Base58Prefix(CChainParams::SECRET_KEY); - data.insert(data.end(), key.begin(), key.end()); - if (key.IsCompressed()) { - data.push_back(1); - } - std::string ret = EncodeBase58Check(data); - memory_cleanse(data.data(), data.size()); - return ret; -} - -CExtPubKey DecodeExtPubKey(const std::string& str) -{ - CExtPubKey key; - std::vector data; - if (DecodeBase58Check(str, data)) { - const std::vector& prefix = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY); - if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin())) { - key.Decode(data.data() + prefix.size()); - } - } - return key; -} - -std::string EncodeExtPubKey(const CExtPubKey& key) -{ - std::vector data = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY); - size_t size = data.size(); - data.resize(size + BIP32_EXTKEY_SIZE); - key.Encode(data.data() + size); - std::string ret = EncodeBase58Check(data); - return ret; -} - -CExtKey DecodeExtKey(const std::string& str) -{ - CExtKey key; - std::vector data; - if (DecodeBase58Check(str, data)) { - const std::vector& prefix = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY); - if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin())) { - key.Decode(data.data() + prefix.size()); - } - } - return key; -} - -std::string EncodeExtKey(const CExtKey& key) -{ - std::vector data = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY); - size_t size = data.size(); - data.resize(size + BIP32_EXTKEY_SIZE); - key.Encode(data.data() + size); - std::string ret = EncodeBase58Check(data); - memory_cleanse(data.data(), data.size()); - return ret; -} - -std::string EncodeDestination(const CTxDestination& dest) -{ - return boost::apply_visitor(DestinationEncoder(Params()), dest); -} - -CTxDestination DecodeDestination(const std::string& str) -{ - return DecodeDestination(str, Params()); -} - -bool IsValidDestinationString(const std::string& str, const CChainParams& params) -{ - return IsValidDestination(DecodeDestination(str, params)); -} - -bool IsValidDestinationString(const std::string& str) -{ - return IsValidDestinationString(str, Params()); -} - -std::string EncodePaymentAddress(const libzcash::PaymentAddress& zaddr) -{ - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << zaddr; - std::vector data = Params().Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS); - data.insert(data.end(), ss.begin(), ss.end()); - return EncodeBase58Check(data); -} - -boost::optional DecodePaymentAddress(const std::string& str) -{ - std::vector data; - if (DecodeBase58Check(str, data)) { - const std::vector& zaddr_prefix = Params().Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS); - if ((data.size() == libzcash::SerializedPaymentAddressSize + zaddr_prefix.size()) && - std::equal(zaddr_prefix.begin(), zaddr_prefix.end(), data.begin())) { - CSerializeData serialized(data.begin() + zaddr_prefix.size(), data.end()); - CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION); - libzcash::PaymentAddress ret; - ss >> ret; - return ret; - } - } - return boost::none; -} - -std::string EncodeViewingKey(const libzcash::ViewingKey& vk) -{ - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << vk; - std::vector data = Params().Base58Prefix(CChainParams::ZCVIEWING_KEY); - data.insert(data.end(), ss.begin(), ss.end()); - std::string ret = EncodeBase58Check(data); - memory_cleanse(data.data(), data.size()); - return ret; -} - -boost::optional DecodeViewingKey(const std::string& str) -{ - std::vector data; - if (DecodeBase58Check(str, data)) { - const std::vector& vk_prefix = Params().Base58Prefix(CChainParams::ZCVIEWING_KEY); - if ((data.size() == libzcash::SerializedViewingKeySize + vk_prefix.size()) && - std::equal(vk_prefix.begin(), vk_prefix.end(), data.begin())) { - CSerializeData serialized(data.begin() + vk_prefix.size(), data.end()); - CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION); - libzcash::ViewingKey ret; - ss >> ret; - memory_cleanse(serialized.data(), serialized.size()); - memory_cleanse(data.data(), data.size()); - return ret; - } - } - memory_cleanse(data.data(), data.size()); - return boost::none; -} - -std::string EncodeSpendingKey(const libzcash::SpendingKey& zkey) -{ - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << zkey; - std::vector data = Params().Base58Prefix(CChainParams::ZCSPENDING_KEY); - data.insert(data.end(), ss.begin(), ss.end()); - std::string ret = EncodeBase58Check(data); - memory_cleanse(data.data(), data.size()); - return ret; -} - -boost::optional DecodeSpendingKey(const std::string& str) -{ - std::vector data; - if (DecodeBase58Check(str, data)) { - const std::vector& zkey_prefix = Params().Base58Prefix(CChainParams::ZCSPENDING_KEY); - if ((data.size() == libzcash::SerializedSpendingKeySize + zkey_prefix.size()) && - std::equal(zkey_prefix.begin(), zkey_prefix.end(), data.begin())) { - CSerializeData serialized(data.begin() + zkey_prefix.size(), data.end()); - CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION); - libzcash::SpendingKey ret; - ss >> ret; - memory_cleanse(serialized.data(), serialized.size()); - memory_cleanse(data.data(), data.size()); - return ret; - } - } - memory_cleanse(data.data(), data.size()); - return boost::none; -} diff --git a/src/base58.h b/src/base58.h index 60a887dcf..3c926fca0 100644 --- a/src/base58.h +++ b/src/base58.h @@ -14,13 +14,6 @@ #ifndef BITCOIN_BASE58_H #define BITCOIN_BASE58_H -#include "chainparams.h" -#include "key.h" -#include "pubkey.h" -#include "script/standard.h" -#include "support/allocators/zeroafterfree.h" -#include "zcash/Address.hpp" - #include #include @@ -57,34 +50,12 @@ std::string EncodeBase58Check(const std::vector& vchIn); * Decode a base58-encoded string (psz) that includes a checksum into a byte * vector (vchRet), return true if decoding is successful */ -inline bool DecodeBase58Check(const char* psz, std::vector& vchRet); +bool DecodeBase58Check(const char* psz, std::vector& vchRet); /** * Decode a base58-encoded string (str) that includes a checksum into a byte * vector (vchRet), return true if decoding is successful */ -inline bool DecodeBase58Check(const std::string& str, std::vector& vchRet); - -CKey DecodeSecret(const std::string& str); -std::string EncodeSecret(const CKey& key); - -CExtKey DecodeExtKey(const std::string& str); -std::string EncodeExtKey(const CExtKey& extkey); -CExtPubKey DecodeExtPubKey(const std::string& str); -std::string EncodeExtPubKey(const CExtPubKey& extpubkey); - -std::string EncodeDestination(const CTxDestination& dest); -CTxDestination DecodeDestination(const std::string& str); -bool IsValidDestinationString(const std::string& str); -bool IsValidDestinationString(const std::string& str, const CChainParams& params); - -std::string EncodePaymentAddress(const libzcash::PaymentAddress& zaddr); -boost::optional DecodePaymentAddress(const std::string& str); - -std::string EncodeViewingKey(const libzcash::ViewingKey& vk); -boost::optional DecodeViewingKey(const std::string& str); - -std::string EncodeSpendingKey(const libzcash::SpendingKey& zkey); -boost::optional DecodeSpendingKey(const std::string& str); +bool DecodeBase58Check(const std::string& str, std::vector& vchRet); #endif // BITCOIN_BASE58_H diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index aa2523039..3ee3c0169 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -2,12 +2,12 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "base58.h" #include "clientversion.h" #include "coins.h" #include "consensus/consensus.h" #include "consensus/upgrades.h" #include "core_io.h" +#include "key_io.h" #include "keystore.h" #include "primitives/transaction.h" #include "script/script.h" diff --git a/src/core_write.cpp b/src/core_write.cpp index df1f83456..43344656b 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -4,7 +4,7 @@ #include "core_io.h" -#include "base58.h" +#include "key_io.h" #include "primitives/transaction.h" #include "script/script.h" #include "script/standard.h" diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 6d37fdfac..ade815788 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -1,8 +1,8 @@ #include "httprpc.h" -#include "base58.h" #include "chainparams.h" #include "httpserver.h" +#include "key_io.h" #include "rpcprotocol.h" #include "rpcserver.h" #include "random.h" diff --git a/src/key_io.cpp b/src/key_io.cpp new file mode 100644 index 000000000..77d63cca4 --- /dev/null +++ b/src/key_io.cpp @@ -0,0 +1,254 @@ +// Copyright (c) 2014-2016 The Bitcoin Core developers +// Copyright (c) 2016-2018 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include +#include +#include