bip32.cpp raw
1 // Copyright (c) 2019-present 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
5 #include <util/bip32.h>
6
7 #include <tinyformat.h>
8 #include <util/strencodings.h>
9
10 #include <cstdint>
11 #include <cstdio>
12 #include <optional>
13 #include <sstream>
14
15 bool ParseHDKeypath(const std::string& keypath_str, std::vector<uint32_t>& keypath)
16 {
17 std::stringstream ss(keypath_str);
18 std::string item;
19 bool first = true;
20 while (std::getline(ss, item, '/')) {
21 if (item.compare("m") == 0) {
22 if (first) {
23 first = false;
24 continue;
25 }
26 return false;
27 }
28 // Finds whether it is hardened
29 uint32_t path = 0;
30 size_t pos = item.find('\'');
31 if (pos != std::string::npos) {
32 // The hardened tick can only be in the last index of the string
33 if (pos != item.size() - 1) {
34 return false;
35 }
36 path |= 0x80000000;
37 item = item.substr(0, item.size() - 1); // Drop the last character which is the hardened tick
38 }
39
40 // Ensure this is only numbers
41 const auto number{ToIntegral<uint32_t>(item)};
42 if (!number) {
43 return false;
44 }
45 path |= *number;
46
47 keypath.push_back(path);
48 first = false;
49 }
50 return true;
51 }
52
53 std::string FormatHDKeypath(const std::vector<uint32_t>& path, bool apostrophe)
54 {
55 std::string ret;
56 for (auto i : path) {
57 ret += strprintf("/%i", (i << 1) >> 1);
58 if (i >> 31) ret += apostrophe ? '\'' : 'h';
59 }
60 return ret;
61 }
62
63 std::string WriteHDKeypath(const std::vector<uint32_t>& keypath, bool apostrophe)
64 {
65 return "m" + FormatHDKeypath(keypath, apostrophe);
66 }
67