// Copyright (c) 2018 The Zcash developers // Copyright (c) 2019-2020 The Hush developers // Distributed under the GPLv3 software license, see the accompanying // file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html #ifndef ZCASH_ZIP32_H #define ZCASH_ZIP32_H #include "serialize.h" #include "support/allocators/secure.h" #include "uint256.h" #include "zcash/Address.hpp" #include const uint32_t ZIP32_HARDENED_KEY_LIMIT = 0x80000000; const size_t ZIP32_XFVK_SIZE = 169; const size_t ZIP32_XSK_SIZE = 169; typedef std::vector> RawHDSeed; class HDSeed { private: RawHDSeed seed; public: HDSeed() {} HDSeed(RawHDSeed& seedIn) : seed(seedIn) {} static HDSeed Random(size_t len = 32); bool IsNull() const { return seed.empty(); }; uint256 Fingerprint() const; RawHDSeed RawSeed() const { return seed; } friend bool operator==(const HDSeed& a, const HDSeed& b) { return a.seed == b.seed; } friend bool operator!=(const HDSeed& a, const HDSeed& b) { return !(a == b); } }; // This is not part of ZIP 32, but is here because it's linked to the HD seed. uint256 ovkForShieldingFromTaddr(HDSeed& seed); namespace libzcash { typedef blob88 diversifier_index_t; struct SaplingExtendedFullViewingKey { uint8_t depth; uint32_t parentFVKTag; uint32_t childIndex; uint256 chaincode; libzcash::SaplingFullViewingKey fvk; uint256 dk; ADD_SERIALIZE_METHODS; template inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(depth); READWRITE(parentFVKTag); READWRITE(childIndex); READWRITE(chaincode); READWRITE(fvk); READWRITE(dk); } boost::optional Derive(uint32_t i) const; // Returns the first index starting from j that generates a valid // payment address, along with the corresponding address. Returns // an error if the diversifier space is exhausted. boost::optional> Address(diversifier_index_t j) const; libzcash::SaplingPaymentAddress DefaultAddress() const; friend inline bool operator==(const SaplingExtendedFullViewingKey& a, const SaplingExtendedFullViewingKey& b) { return ( a.depth == b.depth && a.parentFVKTag == b.parentFVKTag && a.childIndex == b.childIndex && a.chaincode == b.chaincode && a.fvk == b.fvk && a.dk == b.dk); } friend inline bool operator<(const SaplingExtendedFullViewingKey& a, const SaplingExtendedFullViewingKey& b) { return (a.depth < b.depth || (a.depth == b.depth && a.childIndex < b.childIndex) || (a.depth == b.depth && a.childIndex == b.childIndex && a.fvk < b.fvk)); } }; struct SaplingExtendedSpendingKey { uint8_t depth; uint32_t parentFVKTag; uint32_t childIndex; uint256 chaincode; libzcash::SaplingExpandedSpendingKey expsk; uint256 dk; ADD_SERIALIZE_METHODS; template inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(depth); READWRITE(parentFVKTag); READWRITE(childIndex); READWRITE(chaincode); READWRITE(expsk); READWRITE(dk); } static SaplingExtendedSpendingKey Master(const HDSeed& seed); SaplingExtendedSpendingKey Derive(uint32_t i) const; SaplingExtendedFullViewingKey ToXFVK() const; libzcash::SaplingPaymentAddress DefaultAddress() const; friend bool operator==(const SaplingExtendedSpendingKey& a, const SaplingExtendedSpendingKey& b) { return a.depth == b.depth && a.parentFVKTag == b.parentFVKTag && a.childIndex == b.childIndex && a.chaincode == b.chaincode && a.expsk == b.expsk && a.dk == b.dk; } }; typedef boost::variant SpendingKey; } /** Check whether a SpendingKey is not an InvalidEncoding. */ bool IsValidSpendingKey(const libzcash::SpendingKey& zkey); #endif // ZCASH_ZIP32_H