diff --git a/src/base58.cpp b/src/base58.cpp index 46a03e0ab..996e49e3c 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -306,105 +306,90 @@ bool IsValidDestinationString(const std::string& str) return IsValidDestinationString(str, Params()); } -template -bool CZCEncoding::Set(const DATA_TYPE& addr) -{ - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << addr; - std::vector addrSerialized(ss.begin(), ss.end()); - assert(addrSerialized.size() == SER_SIZE); - SetData(Params().Base58Prefix(PREFIX), &addrSerialized[0], SER_SIZE); - return true; -} - -template -DATA_TYPE CZCEncoding::Get() const -{ - if (vchData.size() != SER_SIZE) { - throw std::runtime_error( - PrependName(" is invalid") - ); - } - - if (vchVersion != Params().Base58Prefix(PREFIX)) { - throw std::runtime_error( - PrependName(" is for wrong network type") - ); - } - - std::vector serialized(vchData.begin(), vchData.end()); - - CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION); - DATA_TYPE ret; - ss >> ret; - return ret; -} - -// Explicit instantiations for libzcash::PaymentAddress -template bool CZCEncoding::Set(const libzcash::PaymentAddress& addr); -template libzcash::PaymentAddress CZCEncoding::Get() const; - -// Explicit instantiations for libzcash::ViewingKey -template bool CZCEncoding::Set(const libzcash::ViewingKey& vk); -template libzcash::ViewingKey CZCEncoding::Get() const; - -// Explicit instantiations for libzcash::SpendingKey -template bool CZCEncoding::Set(const libzcash::SpendingKey& sk); -template libzcash::SpendingKey CZCEncoding::Get() const; - std::string EncodePaymentAddress(const libzcash::PaymentAddress& zaddr) { - return CZCPaymentAddress(zaddr).ToString(); + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << zaddr; + std::vector data = Params().Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS); + data.insert(data.end(), ss.begin(), ss.end()); + return EncodeBase58Check(data); } boost::optional DecodePaymentAddress(const std::string& str) { - CZCPaymentAddress addr(str); - try { - return addr.Get(); - } catch (const std::runtime_error&) { - return boost::none; + std::vector data; + if (DecodeBase58Check(str, data)) { + const std::vector& zaddr_prefix = Params().Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS); + if ((data.size() == libzcash::SerializedPaymentAddressSize + zaddr_prefix.size()) && + std::equal(zaddr_prefix.begin(), zaddr_prefix.end(), data.begin())) { + CSerializeData serialized(data.begin() + zaddr_prefix.size(), data.end()); + CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION); + libzcash::PaymentAddress ret; + ss >> ret; + return ret; + } } + return boost::none; } std::string EncodeViewingKey(const libzcash::ViewingKey& vk) { - return CZCViewingKey(vk).ToString(); + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << vk; + std::vector data = Params().Base58Prefix(CChainParams::ZCVIEWING_KEY); + data.insert(data.end(), ss.begin(), ss.end()); + std::string ret = EncodeBase58Check(data); + memory_cleanse(data.data(), data.size()); + return ret; } boost::optional DecodeViewingKey(const std::string& str) { - CZCViewingKey vk(str); - try { - return vk.Get(); - } catch (const std::runtime_error&) { - return boost::none; + std::vector data; + if (DecodeBase58Check(str, data)) { + const std::vector& vk_prefix = Params().Base58Prefix(CChainParams::ZCVIEWING_KEY); + if ((data.size() == libzcash::SerializedViewingKeySize + vk_prefix.size()) && + std::equal(vk_prefix.begin(), vk_prefix.end(), data.begin())) { + CSerializeData serialized(data.begin() + vk_prefix.size(), data.end()); + CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION); + libzcash::ViewingKey ret; + ss >> ret; + memory_cleanse(serialized.data(), serialized.size()); + memory_cleanse(data.data(), data.size()); + return ret; + } } + memory_cleanse(data.data(), data.size()); + return boost::none; } std::string EncodeSpendingKey(const libzcash::SpendingKey& zkey) { - return CZCSpendingKey(zkey).ToString(); + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << zkey; + std::vector data = Params().Base58Prefix(CChainParams::ZCSPENDING_KEY); + data.insert(data.end(), ss.begin(), ss.end()); + std::string ret = EncodeBase58Check(data); + memory_cleanse(data.data(), data.size()); + return ret; } boost::optional DecodeSpendingKey(const std::string& str) { - CZCSpendingKey key(str); - try { - return key.Get(); - } catch (const std::runtime_error&) { - return boost::none; + std::vector data; + if (DecodeBase58Check(str, data)) { + const std::vector& zkey_prefix = Params().Base58Prefix(CChainParams::ZCSPENDING_KEY); + if ((data.size() == libzcash::SerializedSpendingKeySize + zkey_prefix.size()) && + std::equal(zkey_prefix.begin(), zkey_prefix.end(), data.begin())) { + CSerializeData serialized(data.begin() + zkey_prefix.size(), data.end()); + CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION); + libzcash::SpendingKey ret; + ss >> ret; + memory_cleanse(serialized.data(), serialized.size()); + memory_cleanse(data.data(), data.size()); + return ret; + } } + memory_cleanse(data.data(), data.size()); + return boost::none; } diff --git a/src/base58.h b/src/base58.h index 0cc62b456..6ad323173 100644 --- a/src/base58.h +++ b/src/base58.h @@ -95,50 +95,6 @@ public: bool operator> (const CBase58Data& b58) const { return CompareTo(b58) > 0; } }; -template -class CZCEncoding : public CBase58Data { -protected: - virtual std::string PrependName(const std::string& s) const = 0; - -public: - bool Set(const DATA_TYPE& addr); - - DATA_TYPE Get() const; -}; - -class CZCPaymentAddress : public CZCEncoding { -protected: - std::string PrependName(const std::string& s) const { return "payment address" + s; } - -public: - CZCPaymentAddress() {} - - CZCPaymentAddress(const std::string& strAddress) { SetString(strAddress.c_str(), 2); } - CZCPaymentAddress(const libzcash::PaymentAddress& addr) { Set(addr); } -}; - -class CZCViewingKey : public CZCEncoding { -protected: - std::string PrependName(const std::string& s) const { return "viewing key" + s; } - -public: - CZCViewingKey() {} - - CZCViewingKey(const std::string& strViewingKey) { SetString(strViewingKey.c_str(), 3); } - CZCViewingKey(const libzcash::ViewingKey& vk) { Set(vk); } -}; - -class CZCSpendingKey : public CZCEncoding { -protected: - std::string PrependName(const std::string& s) const { return "spending key" + s; } - -public: - CZCSpendingKey() {} - - CZCSpendingKey(const std::string& strAddress) { SetString(strAddress.c_str(), 2); } - CZCSpendingKey(const libzcash::SpendingKey& addr) { Set(addr); } -}; - CKey DecodeSecret(const std::string& str); std::string EncodeSecret(const CKey& key);