dedup decode keys and addresses
This commit is contained in:
parent
2f8cf61a2a
commit
750078ae67
118
src/key_io.cpp
118
src/key_io.cpp
|
@ -270,36 +270,58 @@ std::string EncodePaymentAddress(const libzcash::PaymentAddress& zaddr)
|
||||||
return boost::apply_visitor(PaymentAddressEncoder(Params()), zaddr);
|
return boost::apply_visitor(PaymentAddressEncoder(Params()), zaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
libzcash::PaymentAddress DecodePaymentAddress(const std::string& str)
|
template<typename T1, typename T2, typename T3 = T2>
|
||||||
|
T1 DecodeAny(
|
||||||
|
CChainParams::Base58Type type,
|
||||||
|
size_t size,
|
||||||
|
const std::string& str,
|
||||||
|
boost::optional<std::pair<CChainParams::Bech32Type, size_t>> sapling)
|
||||||
{
|
{
|
||||||
std::vector<unsigned char> data;
|
std::vector<unsigned char> data;
|
||||||
if (DecodeBase58Check(str, data)) {
|
if (DecodeBase58Check(str, data)) {
|
||||||
const std::vector<unsigned char>& zaddr_prefix = Params().Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS);
|
const std::vector<unsigned char>& prefix = Params().Base58Prefix(type);
|
||||||
if ((data.size() == libzcash::SerializedSproutPaymentAddressSize + zaddr_prefix.size()) &&
|
if ((data.size() == size + prefix.size()) &&
|
||||||
std::equal(zaddr_prefix.begin(), zaddr_prefix.end(), data.begin())) {
|
std::equal(prefix.begin(), prefix.end(), data.begin())) {
|
||||||
CSerializeData serialized(data.begin() + zaddr_prefix.size(), data.end());
|
CSerializeData serialized(data.begin() + prefix.size(), data.end());
|
||||||
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
|
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
|
||||||
libzcash::SproutPaymentAddress ret;
|
T2 ret;
|
||||||
ss >> ret;
|
ss >> ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data.clear();
|
|
||||||
auto bech = bech32::Decode(str);
|
if (sapling) {
|
||||||
if (bech.first == Params().Bech32HRP(CChainParams::SAPLING_PAYMENT_ADDRESS) &&
|
data.clear();
|
||||||
bech.second.size() == ConvertedSaplingPaymentAddressSize) {
|
auto bech = bech32::Decode(str);
|
||||||
// Bech32 decoding
|
if (bech.first == Params().Bech32HRP(sapling.get().first) &&
|
||||||
data.reserve((bech.second.size() * 5) / 8);
|
bech.second.size() == sapling.get().second) {
|
||||||
if (ConvertBits<5, 8, false>([&](unsigned char c) { data.push_back(c); }, bech.second.begin(), bech.second.end())) {
|
// Bech32 decoding
|
||||||
CDataStream ss(data, SER_NETWORK, PROTOCOL_VERSION);
|
data.reserve((bech.second.size() * 5) / 8);
|
||||||
libzcash::SaplingPaymentAddress ret;
|
if (ConvertBits<5, 8, false>([&](unsigned char c) { data.push_back(c); }, bech.second.begin(), bech.second.end())) {
|
||||||
ss >> ret;
|
CDataStream ss(data, SER_NETWORK, PROTOCOL_VERSION);
|
||||||
return ret;
|
T3 ret;
|
||||||
|
ss >> ret;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memory_cleanse(data.data(), data.size());
|
||||||
return libzcash::InvalidEncoding();
|
return libzcash::InvalidEncoding();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
libzcash::PaymentAddress DecodePaymentAddress(const std::string& str)
|
||||||
|
{
|
||||||
|
return DecodeAny<libzcash::PaymentAddress,
|
||||||
|
libzcash::SproutPaymentAddress,
|
||||||
|
libzcash::SaplingPaymentAddress>(
|
||||||
|
CChainParams::ZCPAYMENT_ADDRRESS,
|
||||||
|
libzcash::SerializedSproutPaymentAddressSize,
|
||||||
|
str,
|
||||||
|
std::make_pair(CChainParams::SAPLING_PAYMENT_ADDRESS, ConvertedSaplingPaymentAddressSize)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
bool IsValidPaymentAddressString(const std::string& str) {
|
bool IsValidPaymentAddressString(const std::string& str) {
|
||||||
return IsValidPaymentAddress(DecodePaymentAddress(str));
|
return IsValidPaymentAddress(DecodePaymentAddress(str));
|
||||||
}
|
}
|
||||||
|
@ -311,22 +333,13 @@ std::string EncodeViewingKey(const libzcash::ViewingKey& vk)
|
||||||
|
|
||||||
libzcash::ViewingKey DecodeViewingKey(const std::string& str)
|
libzcash::ViewingKey DecodeViewingKey(const std::string& str)
|
||||||
{
|
{
|
||||||
std::vector<unsigned char> data;
|
return DecodeAny<libzcash::ViewingKey,
|
||||||
if (DecodeBase58Check(str, data)) {
|
libzcash::SproutViewingKey>(
|
||||||
const std::vector<unsigned char>& vk_prefix = Params().Base58Prefix(CChainParams::ZCVIEWING_KEY);
|
CChainParams::ZCVIEWING_KEY,
|
||||||
if ((data.size() == libzcash::SerializedSproutViewingKeySize + vk_prefix.size()) &&
|
libzcash::SerializedSproutViewingKeySize,
|
||||||
std::equal(vk_prefix.begin(), vk_prefix.end(), data.begin())) {
|
str,
|
||||||
CSerializeData serialized(data.begin() + vk_prefix.size(), data.end());
|
boost::none
|
||||||
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
|
);
|
||||||
libzcash::SproutViewingKey ret;
|
|
||||||
ss >> ret;
|
|
||||||
memory_cleanse(serialized.data(), serialized.size());
|
|
||||||
memory_cleanse(data.data(), data.size());
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
memory_cleanse(data.data(), data.size());
|
|
||||||
return libzcash::InvalidEncoding();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string EncodeSpendingKey(const libzcash::SpendingKey& zkey)
|
std::string EncodeSpendingKey(const libzcash::SpendingKey& zkey)
|
||||||
|
@ -336,34 +349,13 @@ std::string EncodeSpendingKey(const libzcash::SpendingKey& zkey)
|
||||||
|
|
||||||
libzcash::SpendingKey DecodeSpendingKey(const std::string& str)
|
libzcash::SpendingKey DecodeSpendingKey(const std::string& str)
|
||||||
{
|
{
|
||||||
std::vector<unsigned char> data;
|
|
||||||
if (DecodeBase58Check(str, data)) {
|
return DecodeAny<libzcash::SpendingKey,
|
||||||
const std::vector<unsigned char>& zkey_prefix = Params().Base58Prefix(CChainParams::ZCSPENDING_KEY);
|
libzcash::SproutSpendingKey,
|
||||||
if ((data.size() == libzcash::SerializedSproutSpendingKeySize + zkey_prefix.size()) &&
|
libzcash::SaplingExtendedSpendingKey>(
|
||||||
std::equal(zkey_prefix.begin(), zkey_prefix.end(), data.begin())) {
|
CChainParams::ZCSPENDING_KEY,
|
||||||
CSerializeData serialized(data.begin() + zkey_prefix.size(), data.end());
|
libzcash::SerializedSproutSpendingKeySize,
|
||||||
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
|
str,
|
||||||
libzcash::SproutSpendingKey ret;
|
std::make_pair(CChainParams::SAPLING_EXTENDED_SPEND_KEY, ConvertedSaplingExtendedSpendingKeySize)
|
||||||
ss >> ret;
|
);
|
||||||
memory_cleanse(serialized.data(), serialized.size());
|
|
||||||
memory_cleanse(data.data(), data.size());
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data.clear();
|
|
||||||
auto bech = bech32::Decode(str);
|
|
||||||
if (bech.first == Params().Bech32HRP(CChainParams::SAPLING_EXTENDED_SPEND_KEY) &&
|
|
||||||
bech.second.size() == ConvertedSaplingExtendedSpendingKeySize) {
|
|
||||||
// Bech32 decoding
|
|
||||||
data.reserve((bech.second.size() * 5) / 8);
|
|
||||||
if (ConvertBits<5, 8, false>([&](unsigned char c) { data.push_back(c); }, bech.second.begin(), bech.second.end())) {
|
|
||||||
CDataStream ss(data, SER_NETWORK, PROTOCOL_VERSION);
|
|
||||||
libzcash::SaplingExtendedSpendingKey ret;
|
|
||||||
ss >> ret;
|
|
||||||
memory_cleanse(data.data(), data.size());
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
memory_cleanse(data.data(), data.size());
|
|
||||||
return libzcash::InvalidEncoding();
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue