2017-11-23 11:20:20 -08:00
|
|
|
#ifndef ZC_ADDRESS_H_
|
|
|
|
#define ZC_ADDRESS_H_
|
2016-05-04 17:25:42 -07:00
|
|
|
|
|
|
|
#include "uint256.h"
|
2016-05-16 08:50:31 -07:00
|
|
|
#include "uint252.h"
|
2016-05-04 17:25:42 -07:00
|
|
|
#include "serialize.h"
|
|
|
|
|
2018-04-25 18:51:17 -07:00
|
|
|
#include <boost/variant.hpp>
|
|
|
|
|
2016-05-04 17:25:42 -07:00
|
|
|
namespace libzcash {
|
2018-04-25 18:51:17 -07:00
|
|
|
class InvalidEncoding {
|
|
|
|
public:
|
|
|
|
friend bool operator==(const InvalidEncoding &a, const InvalidEncoding &b) { return true; }
|
|
|
|
friend bool operator<(const InvalidEncoding &a, const InvalidEncoding &b) { return true; }
|
|
|
|
};
|
2016-05-04 17:25:42 -07:00
|
|
|
|
2016-08-16 03:55:06 -07:00
|
|
|
const size_t SerializedPaymentAddressSize = 64;
|
2017-03-01 11:20:42 -08:00
|
|
|
const size_t SerializedViewingKeySize = 64;
|
2016-08-16 03:55:06 -07:00
|
|
|
const size_t SerializedSpendingKeySize = 32;
|
|
|
|
|
2018-05-17 06:13:29 -07:00
|
|
|
typedef std::array<unsigned char, 11> diversifier_t;
|
|
|
|
|
2018-04-25 18:51:17 -07:00
|
|
|
class SproutPaymentAddress {
|
2016-05-04 17:25:42 -07:00
|
|
|
public:
|
|
|
|
uint256 a_pk;
|
|
|
|
uint256 pk_enc;
|
|
|
|
|
2018-04-25 18:51:17 -07:00
|
|
|
SproutPaymentAddress() : a_pk(), pk_enc() { }
|
|
|
|
SproutPaymentAddress(uint256 a_pk, uint256 pk_enc) : a_pk(a_pk), pk_enc(pk_enc) { }
|
2016-05-04 17:25:42 -07:00
|
|
|
|
|
|
|
ADD_SERIALIZE_METHODS;
|
|
|
|
|
|
|
|
template <typename Stream, typename Operation>
|
2018-04-15 20:09:19 -07:00
|
|
|
inline void SerializationOp(Stream& s, Operation ser_action) {
|
2016-05-04 17:25:42 -07:00
|
|
|
READWRITE(a_pk);
|
|
|
|
READWRITE(pk_enc);
|
|
|
|
}
|
2016-08-08 18:34:58 -07:00
|
|
|
|
2016-08-09 22:47:13 -07:00
|
|
|
//! Get the 256-bit SHA256d hash of this payment address.
|
|
|
|
uint256 GetHash() const;
|
|
|
|
|
2018-04-25 18:51:17 -07:00
|
|
|
friend inline bool operator==(const SproutPaymentAddress& a, const SproutPaymentAddress& b) {
|
2016-08-31 16:38:43 -07:00
|
|
|
return a.a_pk == b.a_pk && a.pk_enc == b.pk_enc;
|
|
|
|
}
|
2018-04-25 18:51:17 -07:00
|
|
|
friend inline bool operator<(const SproutPaymentAddress& a, const SproutPaymentAddress& b) {
|
2016-08-31 16:38:43 -07:00
|
|
|
return (a.a_pk < b.a_pk ||
|
|
|
|
(a.a_pk == b.a_pk && a.pk_enc < b.pk_enc));
|
|
|
|
}
|
2016-05-04 17:25:42 -07:00
|
|
|
};
|
|
|
|
|
2017-02-23 10:27:41 -08:00
|
|
|
class ReceivingKey : public uint256 {
|
2016-05-04 17:25:42 -07:00
|
|
|
public:
|
2017-02-23 19:01:00 -08:00
|
|
|
ReceivingKey() { }
|
2017-02-23 10:27:41 -08:00
|
|
|
ReceivingKey(uint256 sk_enc) : uint256(sk_enc) { }
|
2016-05-04 17:25:42 -07:00
|
|
|
|
2017-02-23 19:01:00 -08:00
|
|
|
uint256 pk_enc() const;
|
|
|
|
};
|
|
|
|
|
2018-04-25 18:51:17 -07:00
|
|
|
class SproutViewingKey {
|
2017-02-23 19:01:00 -08:00
|
|
|
public:
|
|
|
|
uint256 a_pk;
|
|
|
|
ReceivingKey sk_enc;
|
|
|
|
|
2018-04-25 18:51:17 -07:00
|
|
|
SproutViewingKey() : a_pk(), sk_enc() { }
|
|
|
|
SproutViewingKey(uint256 a_pk, ReceivingKey sk_enc) : a_pk(a_pk), sk_enc(sk_enc) { }
|
2017-02-23 19:01:00 -08:00
|
|
|
|
|
|
|
ADD_SERIALIZE_METHODS;
|
|
|
|
|
|
|
|
template <typename Stream, typename Operation>
|
2018-04-15 20:09:19 -07:00
|
|
|
inline void SerializationOp(Stream& s, Operation ser_action) {
|
2017-02-23 19:01:00 -08:00
|
|
|
READWRITE(a_pk);
|
|
|
|
READWRITE(sk_enc);
|
|
|
|
}
|
|
|
|
|
2018-04-25 18:51:17 -07:00
|
|
|
SproutPaymentAddress address() const;
|
2017-02-23 19:01:00 -08:00
|
|
|
|
2018-04-25 18:51:17 -07:00
|
|
|
friend inline bool operator==(const SproutViewingKey& a, const SproutViewingKey& b) {
|
2017-02-23 19:01:00 -08:00
|
|
|
return a.a_pk == b.a_pk && a.sk_enc == b.sk_enc;
|
|
|
|
}
|
2018-04-25 18:51:17 -07:00
|
|
|
friend inline bool operator<(const SproutViewingKey& a, const SproutViewingKey& b) {
|
2017-02-23 19:01:00 -08:00
|
|
|
return (a.a_pk < b.a_pk ||
|
|
|
|
(a.a_pk == b.a_pk && a.sk_enc < b.sk_enc));
|
|
|
|
}
|
2016-05-04 17:25:42 -07:00
|
|
|
};
|
|
|
|
|
2018-04-25 18:51:17 -07:00
|
|
|
class SproutSpendingKey : public uint252 {
|
2016-05-04 17:25:42 -07:00
|
|
|
public:
|
2018-04-25 18:51:17 -07:00
|
|
|
SproutSpendingKey() : uint252() { }
|
|
|
|
SproutSpendingKey(uint252 a_sk) : uint252(a_sk) { }
|
2016-05-04 17:25:42 -07:00
|
|
|
|
2018-04-25 18:51:17 -07:00
|
|
|
static SproutSpendingKey random();
|
2016-05-04 17:25:42 -07:00
|
|
|
|
2017-02-23 10:27:41 -08:00
|
|
|
ReceivingKey receiving_key() const;
|
2018-04-25 18:51:17 -07:00
|
|
|
SproutViewingKey viewing_key() const;
|
|
|
|
SproutPaymentAddress address() const;
|
2016-05-04 17:25:42 -07:00
|
|
|
};
|
|
|
|
|
2018-04-25 18:51:17 -07:00
|
|
|
typedef boost::variant<InvalidEncoding, SproutPaymentAddress> PaymentAddress;
|
|
|
|
typedef boost::variant<InvalidEncoding, SproutViewingKey> ViewingKey;
|
|
|
|
typedef boost::variant<InvalidEncoding, SproutSpendingKey> SpendingKey;
|
|
|
|
|
2018-05-17 06:13:29 -07:00
|
|
|
//! Sapling functions.
|
|
|
|
class SaplingPaymentAddress {
|
|
|
|
public:
|
|
|
|
diversifier_t d;
|
|
|
|
uint256 pk_d;
|
|
|
|
|
|
|
|
SaplingPaymentAddress() : d(), pk_d() { }
|
|
|
|
SaplingPaymentAddress(diversifier_t d, uint256 pk_d) : d(d), pk_d(pk_d) { }
|
|
|
|
|
|
|
|
ADD_SERIALIZE_METHODS;
|
|
|
|
|
|
|
|
template <typename Stream, typename Operation>
|
|
|
|
inline void SerializationOp(Stream& s, Operation ser_action) {
|
|
|
|
READWRITE(d);
|
|
|
|
READWRITE(pk_d);
|
|
|
|
}
|
|
|
|
|
|
|
|
friend inline bool operator==(const SaplingPaymentAddress& a, const SaplingPaymentAddress& b) {
|
|
|
|
return a.d == b.d && a.pk_d == b.pk_d;
|
|
|
|
}
|
|
|
|
friend inline bool operator<(const SaplingPaymentAddress& a, const SaplingPaymentAddress& b) {
|
|
|
|
return (a.d < b.d ||
|
|
|
|
(a.d == b.d && a.pk_d < b.pk_d));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-06-04 04:59:07 -07:00
|
|
|
class SaplingIncomingViewingKey : public uint256 {
|
2018-05-17 06:13:29 -07:00
|
|
|
public:
|
2018-06-04 04:59:07 -07:00
|
|
|
SaplingIncomingViewingKey() : uint256() { }
|
|
|
|
SaplingIncomingViewingKey(uint256 ivk) : uint256(ivk) { }
|
2018-05-17 06:13:29 -07:00
|
|
|
|
|
|
|
// Can pass in diversifier for Sapling addr
|
2018-06-04 07:47:46 -07:00
|
|
|
boost::optional<SaplingPaymentAddress> address(diversifier_t d) const;
|
2018-05-17 06:13:29 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
class SaplingFullViewingKey {
|
|
|
|
public:
|
|
|
|
uint256 ak;
|
|
|
|
uint256 nk;
|
|
|
|
uint256 ovk;
|
|
|
|
|
|
|
|
SaplingFullViewingKey() : ak(), nk(), ovk() { }
|
|
|
|
SaplingFullViewingKey(uint256 ak, uint256 nk, uint256 ovk) : ak(ak), nk(nk), ovk(ovk) { }
|
|
|
|
|
|
|
|
ADD_SERIALIZE_METHODS;
|
|
|
|
|
|
|
|
template <typename Stream, typename Operation>
|
|
|
|
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
|
|
|
READWRITE(ak);
|
|
|
|
READWRITE(nk);
|
|
|
|
READWRITE(ovk);
|
|
|
|
}
|
|
|
|
|
2018-06-04 04:59:07 -07:00
|
|
|
SaplingIncomingViewingKey in_viewing_key() const;
|
2018-05-17 06:13:29 -07:00
|
|
|
|
|
|
|
friend inline bool operator==(const SaplingFullViewingKey& a, const SaplingFullViewingKey& b) {
|
|
|
|
return a.ak == b.ak && a.nk == b.nk && a.ovk == b.ovk;
|
|
|
|
}
|
|
|
|
friend inline bool operator<(const SaplingFullViewingKey& a, const SaplingFullViewingKey& b) {
|
|
|
|
return (a.ak < b.ak ||
|
|
|
|
(a.ak == b.ak && a.nk < b.nk) ||
|
|
|
|
(a.ak == b.ak && a.nk == b.nk && a.ovk < b.ovk));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class SaplingExpandedSpendingKey {
|
|
|
|
public:
|
|
|
|
uint256 ask;
|
|
|
|
uint256 nsk;
|
|
|
|
uint256 ovk;
|
|
|
|
|
|
|
|
SaplingExpandedSpendingKey() : ask(), nsk(), ovk() { }
|
|
|
|
SaplingExpandedSpendingKey(uint256 ask, uint256 nsk, uint256 ovk) : ask(ask), nsk(nsk), ovk(ovk) { }
|
|
|
|
|
|
|
|
ADD_SERIALIZE_METHODS;
|
|
|
|
|
|
|
|
template <typename Stream, typename Operation>
|
|
|
|
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
|
|
|
READWRITE(ask);
|
|
|
|
READWRITE(nsk);
|
|
|
|
READWRITE(ovk);
|
|
|
|
}
|
|
|
|
|
|
|
|
SaplingFullViewingKey full_viewing_key() const;
|
|
|
|
|
|
|
|
friend inline bool operator==(const SaplingExpandedSpendingKey& a, const SaplingExpandedSpendingKey& b) {
|
|
|
|
return a.ask == b.ask && a.nsk == b.nsk && a.ovk == b.ovk;
|
|
|
|
}
|
|
|
|
friend inline bool operator<(const SaplingExpandedSpendingKey& a, const SaplingExpandedSpendingKey& b) {
|
|
|
|
return (a.ask < b.ask ||
|
|
|
|
(a.ask == b.ask && a.nsk < b.nsk) ||
|
|
|
|
(a.ask == b.ask && a.nsk == b.nsk && a.ovk < b.ovk));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class SaplingSpendingKey : public uint256 {
|
|
|
|
public:
|
|
|
|
SaplingSpendingKey() : uint256() { }
|
|
|
|
SaplingSpendingKey(uint256 sk) : uint256(sk) { }
|
|
|
|
|
|
|
|
static SaplingSpendingKey random();
|
|
|
|
|
|
|
|
SaplingExpandedSpendingKey expanded_spending_key() const;
|
|
|
|
SaplingFullViewingKey full_viewing_key() const;
|
|
|
|
|
|
|
|
// Can derive Sapling addr from default diversifier
|
2018-06-04 07:47:46 -07:00
|
|
|
boost::optional<SaplingPaymentAddress> default_address() const;
|
2018-05-17 06:13:29 -07:00
|
|
|
};
|
|
|
|
|
2016-05-04 17:25:42 -07:00
|
|
|
}
|
|
|
|
|
2018-04-25 18:51:17 -07:00
|
|
|
/** Check whether a PaymentAddress is not an InvalidEncoding. */
|
|
|
|
bool IsValidPaymentAddress(const libzcash::PaymentAddress& zaddr);
|
|
|
|
|
|
|
|
/** Check whether a ViewingKey is not an InvalidEncoding. */
|
|
|
|
bool IsValidViewingKey(const libzcash::ViewingKey& vk);
|
|
|
|
|
|
|
|
/** Check whether a SpendingKey is not an InvalidEncoding. */
|
|
|
|
bool IsValidSpendingKey(const libzcash::SpendingKey& zkey);
|
|
|
|
|
2017-11-23 11:20:20 -08:00
|
|
|
#endif // ZC_ADDRESS_H_
|