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