dedup decode keys and addresses

This commit is contained in:
Alfredo Garcia 2020-02-06 16:13:54 -03:00
parent 2f8cf61a2a
commit 750078ae67
1 changed files with 55 additions and 63 deletions

View File

@ -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();
} }