Bitcoin Core 31.99.0
P2P Digital Currency
bip32.cpp
Go to the documentation of this file.
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 <algorithm>
11#include <cstdint>
12#include <optional>
13#include <span>
14#include <sstream>
15#include <string_view>
16
18{
19 const std::string_view raw{elem.begin(), elem.end()};
20 if (elem.empty()) {
21 return util::Unexpected{strprintf("Key path value '%s' is not valid", raw)};
22 }
23
24 bool is_hardened = false;
25 const char last = elem.back();
26 if (last == '\'' || last == 'h') {
27 elem = elem.first(elem.size() - 1);
28 is_hardened = true;
29 }
30
31 const auto number{ToIntegral<uint32_t>(std::string_view{elem.begin(), elem.end()})};
32 if (!number) {
33 return util::Unexpected{strprintf("Key path value '%s' is not a valid uint32", raw)};
34 }
35 if (*number >= BIP32_HARDENED_FLAG) {
36 return util::Unexpected{strprintf("Key path value %u is out of range", *number)};
37 }
38 return KeyPathElement{*number, is_hardened};
39}
40
41bool ParseHDKeypath(const std::string& keypath_str, std::vector<uint32_t>& keypath)
42{
43 std::stringstream ss(keypath_str);
44 std::string item;
45 bool first = true;
46 while (std::getline(ss, item, '/') || std::getline(ss, item, 'h')) {
47 if (item.compare("m") == 0) {
48 if (first) {
49 first = false;
50 continue;
51 }
52 return false;
53 }
54 const auto parsed{ParseKeyPathElement(std::span<const char>{item.data(), item.size()})};
55 if (!parsed) return false;
56 keypath.push_back(parsed->ChildNumber());
57 first = false;
58 }
59 return true;
60}
61
62std::string FormatHDKeypath(const std::vector<uint32_t>& path, bool apostrophe)
63{
64 std::string ret;
65 for (auto i : path) {
66 ret += strprintf("/%i", (i << 1) >> 1);
67 if (i >> 31) ret += apostrophe ? '\'' : 'h';
68 }
69 return ret;
70}
71
72std::string WriteHDKeypath(const std::vector<uint32_t>& keypath, bool apostrophe)
73{
74 return "m" + FormatHDKeypath(keypath, apostrophe);
75}
76
77bool HasHardenedDerivation(std::span<const uint32_t> keypath)
78{
79 return std::any_of(keypath.begin(), keypath.end(), [](uint32_t index) {
80 return index >> 31;
81 });
82}
bool ParseHDKeypath(const std::string &keypath_str, std::vector< uint32_t > &keypath)
Parse an HD keypaths like "m/7/0'/2000".
Definition: bip32.cpp:41
std::string FormatHDKeypath(const std::vector< uint32_t > &path, bool apostrophe)
Definition: bip32.cpp:62
std::string WriteHDKeypath(const std::vector< uint32_t > &keypath, bool apostrophe)
Write HD keypaths as strings.
Definition: bip32.cpp:72
util::Expected< KeyPathElement, std::string > ParseKeyPathElement(std::span< const char > elem)
Parse a single key path element like "0", "0'", or "0h".
Definition: bip32.cpp:17
bool HasHardenedDerivation(std::span< const uint32_t > keypath)
Whether a parsed HD keypath contains at least one hardened derivation step.
Definition: bip32.cpp:77
static constexpr uint32_t BIP32_HARDENED_FLAG
BIP32 hardened derivation flag (2^31)
Definition: bip32.h:17
int ret
The util::Expected class provides a standard way for low-level functions to return either error value...
Definition: expected.h:44
The util::Unexpected class represents an unexpected value stored in util::Expected.
Definition: expected.h:21
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1172