PageRenderTime 1313ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/src/key_io.cpp

https://github.com/bitcoin/bitcoin
C++ | 301 lines | 251 code | 35 blank | 15 comment | 68 complexity | 8ffc3ba5cba08370c52282fda3e2e0ee MD5 | raw file
  1. // Copyright (c) 2014-2021 The Bitcoin Core developers
  2. // Distributed under the MIT software license, see the accompanying
  3. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  4. #include <key_io.h>
  5. #include <base58.h>
  6. #include <bech32.h>
  7. #include <util/strencodings.h>
  8. #include <algorithm>
  9. #include <assert.h>
  10. #include <string.h>
  11. /// Maximum witness length for Bech32 addresses.
  12. static constexpr std::size_t BECH32_WITNESS_PROG_MAX_LEN = 40;
  13. namespace {
  14. class DestinationEncoder
  15. {
  16. private:
  17. const CChainParams& m_params;
  18. public:
  19. explicit DestinationEncoder(const CChainParams& params) : m_params(params) {}
  20. std::string operator()(const PKHash& id) const
  21. {
  22. std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
  23. data.insert(data.end(), id.begin(), id.end());
  24. return EncodeBase58Check(data);
  25. }
  26. std::string operator()(const ScriptHash& id) const
  27. {
  28. std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
  29. data.insert(data.end(), id.begin(), id.end());
  30. return EncodeBase58Check(data);
  31. }
  32. std::string operator()(const WitnessV0KeyHash& id) const
  33. {
  34. std::vector<unsigned char> data = {0};
  35. data.reserve(33);
  36. ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, id.begin(), id.end());
  37. return bech32::Encode(bech32::Encoding::BECH32, m_params.Bech32HRP(), data);
  38. }
  39. std::string operator()(const WitnessV0ScriptHash& id) const
  40. {
  41. std::vector<unsigned char> data = {0};
  42. data.reserve(53);
  43. ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, id.begin(), id.end());
  44. return bech32::Encode(bech32::Encoding::BECH32, m_params.Bech32HRP(), data);
  45. }
  46. std::string operator()(const WitnessV1Taproot& tap) const
  47. {
  48. std::vector<unsigned char> data = {1};
  49. data.reserve(53);
  50. ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, tap.begin(), tap.end());
  51. return bech32::Encode(bech32::Encoding::BECH32M, m_params.Bech32HRP(), data);
  52. }
  53. std::string operator()(const WitnessUnknown& id) const
  54. {
  55. if (id.version < 1 || id.version > 16 || id.length < 2 || id.length > 40) {
  56. return {};
  57. }
  58. std::vector<unsigned char> data = {(unsigned char)id.version};
  59. data.reserve(1 + (id.length * 8 + 4) / 5);
  60. ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, id.program, id.program + id.length);
  61. return bech32::Encode(bech32::Encoding::BECH32M, m_params.Bech32HRP(), data);
  62. }
  63. std::string operator()(const CNoDestination& no) const { return {}; }
  64. };
  65. CTxDestination DecodeDestination(const std::string& str, const CChainParams& params, std::string& error_str, std::vector<int>* error_locations)
  66. {
  67. std::vector<unsigned char> data;
  68. uint160 hash;
  69. error_str = "";
  70. // Note this will be false if it is a valid Bech32 address for a different network
  71. bool is_bech32 = (ToLower(str.substr(0, params.Bech32HRP().size())) == params.Bech32HRP());
  72. if (!is_bech32 && DecodeBase58Check(str, data, 21)) {
  73. // base58-encoded Bitcoin addresses.
  74. // Public-key-hash-addresses have version 0 (or 111 testnet).
  75. // The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key.
  76. const std::vector<unsigned char>& pubkey_prefix = params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
  77. if (data.size() == hash.size() + pubkey_prefix.size() && std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin())) {
  78. std::copy(data.begin() + pubkey_prefix.size(), data.end(), hash.begin());
  79. return PKHash(hash);
  80. }
  81. // Script-hash-addresses have version 5 (or 196 testnet).
  82. // The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script.
  83. const std::vector<unsigned char>& script_prefix = params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
  84. if (data.size() == hash.size() + script_prefix.size() && std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) {
  85. std::copy(data.begin() + script_prefix.size(), data.end(), hash.begin());
  86. return ScriptHash(hash);
  87. }
  88. // If the prefix of data matches either the script or pubkey prefix, the length must have been wrong
  89. if ((data.size() >= script_prefix.size() &&
  90. std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) ||
  91. (data.size() >= pubkey_prefix.size() &&
  92. std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin()))) {
  93. error_str = "Invalid length for Base58 address";
  94. } else {
  95. error_str = "Invalid prefix for Base58-encoded address";
  96. }
  97. return CNoDestination();
  98. } else if (!is_bech32) {
  99. // Try Base58 decoding without the checksum, using a much larger max length
  100. if (!DecodeBase58(str, data, 100)) {
  101. error_str = "Not a valid Bech32 or Base58 encoding";
  102. } else {
  103. error_str = "Invalid checksum or length of Base58 address";
  104. }
  105. return CNoDestination();
  106. }
  107. data.clear();
  108. const auto dec = bech32::Decode(str);
  109. if ((dec.encoding == bech32::Encoding::BECH32 || dec.encoding == bech32::Encoding::BECH32M) && dec.data.size() > 0) {
  110. // Bech32 decoding
  111. if (dec.hrp != params.Bech32HRP()) {
  112. error_str = "Invalid prefix for Bech32 address";
  113. return CNoDestination();
  114. }
  115. int version = dec.data[0]; // The first 5 bit symbol is the witness version (0-16)
  116. if (version == 0 && dec.encoding != bech32::Encoding::BECH32) {
  117. error_str = "Version 0 witness address must use Bech32 checksum";
  118. return CNoDestination();
  119. }
  120. if (version != 0 && dec.encoding != bech32::Encoding::BECH32M) {
  121. error_str = "Version 1+ witness address must use Bech32m checksum";
  122. return CNoDestination();
  123. }
  124. // The rest of the symbols are converted witness program bytes.
  125. data.reserve(((dec.data.size() - 1) * 5) / 8);
  126. if (ConvertBits<5, 8, false>([&](unsigned char c) { data.push_back(c); }, dec.data.begin() + 1, dec.data.end())) {
  127. if (version == 0) {
  128. {
  129. WitnessV0KeyHash keyid;
  130. if (data.size() == keyid.size()) {
  131. std::copy(data.begin(), data.end(), keyid.begin());
  132. return keyid;
  133. }
  134. }
  135. {
  136. WitnessV0ScriptHash scriptid;
  137. if (data.size() == scriptid.size()) {
  138. std::copy(data.begin(), data.end(), scriptid.begin());
  139. return scriptid;
  140. }
  141. }
  142. error_str = "Invalid Bech32 v0 address data size";
  143. return CNoDestination();
  144. }
  145. if (version == 1 && data.size() == WITNESS_V1_TAPROOT_SIZE) {
  146. static_assert(WITNESS_V1_TAPROOT_SIZE == WitnessV1Taproot::size());
  147. WitnessV1Taproot tap;
  148. std::copy(data.begin(), data.end(), tap.begin());
  149. return tap;
  150. }
  151. if (version > 16) {
  152. error_str = "Invalid Bech32 address witness version";
  153. return CNoDestination();
  154. }
  155. if (data.size() < 2 || data.size() > BECH32_WITNESS_PROG_MAX_LEN) {
  156. error_str = "Invalid Bech32 address data size";
  157. return CNoDestination();
  158. }
  159. WitnessUnknown unk;
  160. unk.version = version;
  161. std::copy(data.begin(), data.end(), unk.program);
  162. unk.length = data.size();
  163. return unk;
  164. }
  165. }
  166. // Perform Bech32 error location
  167. auto res = bech32::LocateErrors(str);
  168. error_str = res.first;
  169. if (error_locations) *error_locations = std::move(res.second);
  170. return CNoDestination();
  171. }
  172. } // namespace
  173. CKey DecodeSecret(const std::string& str)
  174. {
  175. CKey key;
  176. std::vector<unsigned char> data;
  177. if (DecodeBase58Check(str, data, 34)) {
  178. const std::vector<unsigned char>& privkey_prefix = Params().Base58Prefix(CChainParams::SECRET_KEY);
  179. if ((data.size() == 32 + privkey_prefix.size() || (data.size() == 33 + privkey_prefix.size() && data.back() == 1)) &&
  180. std::equal(privkey_prefix.begin(), privkey_prefix.end(), data.begin())) {
  181. bool compressed = data.size() == 33 + privkey_prefix.size();
  182. key.Set(data.begin() + privkey_prefix.size(), data.begin() + privkey_prefix.size() + 32, compressed);
  183. }
  184. }
  185. if (!data.empty()) {
  186. memory_cleanse(data.data(), data.size());
  187. }
  188. return key;
  189. }
  190. std::string EncodeSecret(const CKey& key)
  191. {
  192. assert(key.IsValid());
  193. std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::SECRET_KEY);
  194. data.insert(data.end(), key.begin(), key.end());
  195. if (key.IsCompressed()) {
  196. data.push_back(1);
  197. }
  198. std::string ret = EncodeBase58Check(data);
  199. memory_cleanse(data.data(), data.size());
  200. return ret;
  201. }
  202. CExtPubKey DecodeExtPubKey(const std::string& str)
  203. {
  204. CExtPubKey key;
  205. std::vector<unsigned char> data;
  206. if (DecodeBase58Check(str, data, 78)) {
  207. const std::vector<unsigned char>& prefix = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY);
  208. if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin())) {
  209. key.Decode(data.data() + prefix.size());
  210. }
  211. }
  212. return key;
  213. }
  214. std::string EncodeExtPubKey(const CExtPubKey& key)
  215. {
  216. std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY);
  217. size_t size = data.size();
  218. data.resize(size + BIP32_EXTKEY_SIZE);
  219. key.Encode(data.data() + size);
  220. std::string ret = EncodeBase58Check(data);
  221. return ret;
  222. }
  223. CExtKey DecodeExtKey(const std::string& str)
  224. {
  225. CExtKey key;
  226. std::vector<unsigned char> data;
  227. if (DecodeBase58Check(str, data, 78)) {
  228. const std::vector<unsigned char>& prefix = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY);
  229. if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin())) {
  230. key.Decode(data.data() + prefix.size());
  231. }
  232. }
  233. return key;
  234. }
  235. std::string EncodeExtKey(const CExtKey& key)
  236. {
  237. std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY);
  238. size_t size = data.size();
  239. data.resize(size + BIP32_EXTKEY_SIZE);
  240. key.Encode(data.data() + size);
  241. std::string ret = EncodeBase58Check(data);
  242. memory_cleanse(data.data(), data.size());
  243. return ret;
  244. }
  245. std::string EncodeDestination(const CTxDestination& dest)
  246. {
  247. return std::visit(DestinationEncoder(Params()), dest);
  248. }
  249. CTxDestination DecodeDestination(const std::string& str, std::string& error_msg, std::vector<int>* error_locations)
  250. {
  251. return DecodeDestination(str, Params(), error_msg, error_locations);
  252. }
  253. CTxDestination DecodeDestination(const std::string& str)
  254. {
  255. std::string error_msg;
  256. return DecodeDestination(str, error_msg);
  257. }
  258. bool IsValidDestinationString(const std::string& str, const CChainParams& params)
  259. {
  260. std::string error_msg;
  261. return IsValidDestination(DecodeDestination(str, params, error_msg, nullptr));
  262. }
  263. bool IsValidDestinationString(const std::string& str)
  264. {
  265. return IsValidDestinationString(str, Params());
  266. }