Return std::optional<CExtKey> from CExtKey::Master
Master key generation is fallible, but the type of master key generation did not previously reflect that the generated key might be invalid.
This commit is contained in:
parent
f6a8461047
commit
0c38ad9200
|
@ -290,7 +290,7 @@ std::optional<CExtKey> CExtKey::Derive(unsigned int _nChild) const {
|
|||
}
|
||||
}
|
||||
|
||||
CExtKey CExtKey::Master(const unsigned char *seed, unsigned int nSeedLen) {
|
||||
std::optional<CExtKey> CExtKey::Master(const unsigned char *seed, unsigned int nSeedLen) {
|
||||
CExtKey xk;
|
||||
static const unsigned char hashkey[] = {'B','i','t','c','o','i','n',' ','s','e','e','d'};
|
||||
std::vector<unsigned char, secure_allocator<unsigned char>> vout(64);
|
||||
|
@ -301,7 +301,11 @@ CExtKey CExtKey::Master(const unsigned char *seed, unsigned int nSeedLen) {
|
|||
xk.nChild = 0;
|
||||
memset(xk.vchFingerprint, 0, sizeof(xk.vchFingerprint));
|
||||
|
||||
return xk;
|
||||
if (xk.key.IsValid()) {
|
||||
return xk;
|
||||
} else {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
CExtPubKey CExtKey::Neuter() const {
|
||||
|
|
|
@ -166,7 +166,7 @@ struct CExtKey {
|
|||
a.key == b.key;
|
||||
}
|
||||
|
||||
static CExtKey Master(const unsigned char* seed, unsigned int nSeedLen);
|
||||
static std::optional<CExtKey> Master(const unsigned char* seed, unsigned int nSeedLen);
|
||||
|
||||
void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const;
|
||||
void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
|
||||
|
|
|
@ -80,7 +80,7 @@ TestVector test2 =
|
|||
|
||||
void RunTest(const TestVector &test) {
|
||||
std::vector<unsigned char> seed = ParseHex(test.strHexMaster);
|
||||
CExtKey key = CExtKey::Master(&seed[0], seed.size());
|
||||
CExtKey key = CExtKey::Master(&seed[0], seed.size()).value();
|
||||
CExtPubKey pubkey = key.Neuter();
|
||||
KeyIO keyIO(Params());
|
||||
for (const TestDerivation &derive : test.vDerive) {
|
||||
|
|
|
@ -74,10 +74,11 @@ std::optional<AccountKey> AccountKey::ForAccount(
|
|||
AccountId accountId) {
|
||||
auto rawSeed = seed.RawSeed();
|
||||
auto m = CExtKey::Master(rawSeed.data(), rawSeed.size());
|
||||
if (!m.has_value()) return std::nullopt;
|
||||
|
||||
// We use a fixed keypath scheme of m/44'/coin_type'/account'
|
||||
// Derive m/44'
|
||||
auto m_44h = m.Derive(44 | HARDENED_KEY_LIMIT);
|
||||
auto m_44h = m.value().Derive(44 | HARDENED_KEY_LIMIT);
|
||||
if (!m_44h.has_value()) return std::nullopt;
|
||||
|
||||
// Derive m/44'/coin_type'
|
||||
|
|
Loading…
Reference in New Issue