Add functions for generating BIP-44 and ZIP-32 keypaths

This commit is contained in:
Kris Nuttycombe 2021-11-22 11:56:49 -07:00
parent 87eeee0607
commit 48446b5e39
4 changed files with 29 additions and 13 deletions

View File

@ -4,6 +4,10 @@
#include "bip44.h"
HDKeyPath libzcash::Bip44TransparentAccountKeyPath(uint32_t bip44CoinType, libzcash::AccountId accountId) {
return "m/44'/" + std::to_string(bip44CoinType) + "'/" + std::to_string(accountId) + "'";
}
std::optional<std::pair<CExtKey, HDKeyPath>> libzcash::DeriveBip44TransparentAccountKey(const HDSeed& seed, uint32_t bip44CoinType, libzcash::AccountId accountId) {
auto rawSeed = seed.RawSeed();
auto m = CExtKey::Master(rawSeed.data(), rawSeed.size());
@ -21,7 +25,7 @@ std::optional<std::pair<CExtKey, HDKeyPath>> libzcash::DeriveBip44TransparentAcc
auto result = m_44h_cth.value().Derive(accountId | HARDENED_KEY_LIMIT);
if (!result.has_value()) return std::nullopt;
auto hdKeypath = "m/44'/" + std::to_string(bip44CoinType) + "'/" + std::to_string(accountId) + "'";
auto hdKeypath = libzcash::Bip44TransparentAccountKeyPath(bip44CoinType, accountId);
return std::make_pair(result.value(), hdKeypath);
}

View File

@ -9,6 +9,8 @@
namespace libzcash {
HDKeyPath Bip44TransparentAccountKeyPath(uint32_t bip44CoinType, libzcash::AccountId accountId);
std::optional<std::pair<CExtKey, HDKeyPath>> DeriveBip44TransparentAccountKey(const HDSeed& seed, uint32_t bip44CoinType, libzcash::AccountId accountId);
class Bip44AccountChains {

View File

@ -173,10 +173,7 @@ std::pair<SaplingExtendedSpendingKey, HDKeyPath> SaplingExtendedSpendingKey::For
// Derive account key at the given account index
auto xsk = m_32h_cth.Derive(accountId | HARDENED_KEY_LIMIT);
// Create new metadata
auto hdKeypath = "m/32'/" + std::to_string(bip44CoinType) + "'/" + std::to_string(accountId) + "'";
return std::make_pair(xsk, hdKeypath);
return std::make_pair(xsk, libzcash::Zip32AccountKeyPath(bip44CoinType, accountId));
}
std::pair<SaplingExtendedSpendingKey, HDKeyPath> SaplingExtendedSpendingKey::Legacy(const HDSeed& seed, uint32_t bip44CoinType, uint32_t addressIndex) {
@ -198,13 +195,7 @@ std::pair<SaplingExtendedSpendingKey, HDKeyPath> SaplingExtendedSpendingKey::Leg
// Derive key at the specified address index
auto xsk = m_32h_cth_l.Derive(addressIndex | HARDENED_KEY_LIMIT);
// Create new metadata
auto hdKeypath = "m/32'/"
+ std::to_string(bip44CoinType) + "'/"
+ std::to_string(ZCASH_LEGACY_ACCOUNT) + "'/"
+ std::to_string(addressIndex) + "'";
return std::make_pair(xsk, hdKeypath);
return std::make_pair(xsk, libzcash::Zip32AccountKeyPath(bip44CoinType, ZCASH_LEGACY_ACCOUNT, addressIndex));
}
SaplingExtendedFullViewingKey SaplingExtendedSpendingKey::ToXFVK() const
@ -219,6 +210,17 @@ SaplingExtendedFullViewingKey SaplingExtendedSpendingKey::ToXFVK() const
return ret;
}
HDKeyPath Zip32AccountKeyPath(
uint32_t bip44CoinType,
libzcash::AccountId accountId,
std::optional<uint32_t> legacyAddressIndex) {
HDKeyPath addrSuffix = "";
if (legacyAddressIndex.has_value()) {
addrSuffix = "/" + std::to_string(legacyAddressIndex.value()) + "'";
}
return "m/32'/" + std::to_string(bip44CoinType) + "'/" + std::to_string(accountId) + "'" + addrSuffix;
}
std::optional<unsigned long> ParseHDKeypathAccount(uint32_t purpose, uint32_t coinType, const std::string& keyPath) {
std::regex pattern("m/" + std::to_string(purpose) + "'/" + std::to_string(coinType) + "'/([0-9]+)'.*");
std::smatch matches;

View File

@ -240,7 +240,15 @@ struct SaplingExtendedSpendingKey {
}
};
std::optional<unsigned long> ParseHDKeypathAccount(uint32_t purpose, uint32_t coinType, const std::string& keyPath);
HDKeyPath Zip32AccountKeyPath(
uint32_t bip44CoinType,
libzcash::AccountId accountId,
std::optional<uint32_t> legacyAddressIndex = std::nullopt);
std::optional<unsigned long> ParseHDKeypathAccount(
uint32_t purpose,
uint32_t coinType,
const std::string& keyPath);
} //namespace libzcash