desprout
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Copyright (c) 2018 The Zcash developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2009-2014 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -44,29 +44,11 @@ using namespace libzcash;
|
||||
// Input UTXO is a tuple of txid, vout, amount, script
|
||||
typedef std::tuple<COutPoint, CAmount, CScript> MergeToAddressInputUTXO;
|
||||
|
||||
// Input JSOP is a tuple of JSOutpoint, note, amount, spending key
|
||||
typedef std::tuple<JSOutPoint, SproutNote, CAmount, SproutSpendingKey> MergeToAddressInputSproutNote;
|
||||
|
||||
typedef std::tuple<SaplingOutPoint, SaplingNote, CAmount, SaplingExpandedSpendingKey> MergeToAddressInputSaplingNote;
|
||||
|
||||
// A recipient is a tuple of address, memo (optional if zaddr)
|
||||
typedef std::tuple<std::string, std::string> MergeToAddressRecipient;
|
||||
|
||||
// Package of info which is passed to perform_joinsplit methods.
|
||||
struct MergeToAddressJSInfo {
|
||||
std::vector<JSInput> vjsin;
|
||||
std::vector<JSOutput> vjsout;
|
||||
std::vector<SproutNote> notes;
|
||||
std::vector<SproutSpendingKey> zkeys;
|
||||
CAmount vpub_old = 0;
|
||||
CAmount vpub_new = 0;
|
||||
};
|
||||
|
||||
// A struct to help us track the witness and anchor for a given JSOutPoint
|
||||
struct MergeToAddressWitnessAnchorData {
|
||||
boost::optional<SproutWitness> witness;
|
||||
uint256 anchor;
|
||||
};
|
||||
|
||||
class AsyncRPCOperation_mergetoaddress : public AsyncRPCOperation
|
||||
{
|
||||
@@ -116,7 +98,6 @@ private:
|
||||
std::unordered_map<std::string, MergeToAddressWitnessAnchorData> jsopWitnessAnchorMap;
|
||||
|
||||
std::vector<MergeToAddressInputUTXO> utxoInputs_;
|
||||
std::vector<MergeToAddressInputSproutNote> sproutNoteInputs_;
|
||||
std::vector<MergeToAddressInputSaplingNote> saplingNoteInputs_;
|
||||
|
||||
TransactionBuilder builder_;
|
||||
@@ -125,18 +106,6 @@ private:
|
||||
std::array<unsigned char, ZC_MEMO_SIZE> get_memo_from_hex_string(std::string s);
|
||||
bool main_impl();
|
||||
|
||||
// JoinSplit without any input notes to spend
|
||||
UniValue perform_joinsplit(MergeToAddressJSInfo&);
|
||||
|
||||
// JoinSplit with input notes to spend (JSOutPoints))
|
||||
UniValue perform_joinsplit(MergeToAddressJSInfo&, std::vector<JSOutPoint>&);
|
||||
|
||||
// JoinSplit where you have the witnesses and anchor
|
||||
UniValue perform_joinsplit(
|
||||
MergeToAddressJSInfo& info,
|
||||
std::vector<boost::optional<SproutWitness>> witnesses,
|
||||
uint256 anchor);
|
||||
|
||||
void sign_send_raw_transaction(UniValue obj); // throws exception if there was an error
|
||||
|
||||
void lock_utxos();
|
||||
@@ -180,24 +149,6 @@ public:
|
||||
return delegate->main_impl();
|
||||
}
|
||||
|
||||
UniValue perform_joinsplit(MergeToAddressJSInfo& info)
|
||||
{
|
||||
return delegate->perform_joinsplit(info);
|
||||
}
|
||||
|
||||
UniValue perform_joinsplit(MergeToAddressJSInfo& info, std::vector<JSOutPoint>& v)
|
||||
{
|
||||
return delegate->perform_joinsplit(info, v);
|
||||
}
|
||||
|
||||
UniValue perform_joinsplit(
|
||||
MergeToAddressJSInfo& info,
|
||||
std::vector<boost::optional<SproutWitness>> witnesses,
|
||||
uint256 anchor)
|
||||
{
|
||||
return delegate->perform_joinsplit(info, witnesses, anchor);
|
||||
}
|
||||
|
||||
void sign_send_raw_transaction(UniValue obj)
|
||||
{
|
||||
delegate->sign_send_raw_transaction(obj);
|
||||
|
||||
@@ -75,11 +75,6 @@ CWalletTx GetValidReceive(const libzcash::SproutSpendingKey& sk, CAmount value,
|
||||
return GetValidReceive(*params, sk, value, randomInputs, version);
|
||||
}
|
||||
|
||||
libzcash::SproutNote GetNote(const libzcash::SproutSpendingKey& sk,
|
||||
const CTransaction& tx, size_t js, size_t n) {
|
||||
return GetNote(*params, sk, tx, js, n);
|
||||
}
|
||||
|
||||
CWalletTx GetValidSpend(const libzcash::SproutSpendingKey& sk,
|
||||
const libzcash::SproutNote& note, CAmount value) {
|
||||
return GetValidSpend(*params, sk, note, value);
|
||||
|
||||
@@ -3123,7 +3123,7 @@ UniValue getalldata(const UniValue& params, bool fHelp,const CPubKey&)
|
||||
if (wtx.GetDepthInMainChain() < 0)
|
||||
continue;
|
||||
|
||||
if (wtx.mapSaplingNoteData.size() == 0 && wtx.mapSproutNoteData.size() == 0 && !wtx.IsTrusted())
|
||||
if (wtx.mapSaplingNoteData.size() == 0 && !wtx.IsTrusted())
|
||||
continue;
|
||||
|
||||
//Assign Immature
|
||||
@@ -3309,7 +3309,7 @@ UniValue getalldata(const UniValue& params, bool fHelp,const CPubKey&)
|
||||
if (!CheckFinalTx(wtx))
|
||||
continue;
|
||||
|
||||
if (wtx.mapSaplingNoteData.size() == 0 && wtx.mapSproutNoteData.size() == 0 && !wtx.IsTrusted())
|
||||
if (wtx.mapSaplingNoteData.size() == 0 && !wtx.IsTrusted())
|
||||
continue;
|
||||
|
||||
//Excude transactions with less confirmations than required
|
||||
|
||||
@@ -934,7 +934,7 @@ int CWallet::VerifyAndSetInitialWitness(const CBlockIndex* pindex, bool witnessO
|
||||
for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
|
||||
nWitnessTxIncrement += 1;
|
||||
|
||||
if (wtxItem.second.mapSproutNoteData.empty() && wtxItem.second.mapSaplingNoteData.empty())
|
||||
if (wtxItem.second.mapSaplingNoteData.empty())
|
||||
continue;
|
||||
|
||||
if (wtxItem.second.GetDepthInMainChain() > 0) {
|
||||
|
||||
@@ -236,82 +236,19 @@ public:
|
||||
std::string ToString() const;
|
||||
};
|
||||
|
||||
class SproutNoteData
|
||||
class SaplingNoteData
|
||||
{
|
||||
public:
|
||||
libzcash::SproutPaymentAddress address;
|
||||
|
||||
/**
|
||||
* Cached note nullifier. May not be set if the wallet was not unlocked when
|
||||
* this was SproutNoteData was created. If not set, we always assume that the
|
||||
* note has not been spent.
|
||||
*
|
||||
* It's okay to cache the nullifier in the wallet, because we are storing
|
||||
* the spending key there too, which could be used to derive this.
|
||||
* If the wallet is encrypted, this means that someone with access to the
|
||||
* locked wallet cannot spend notes, but can connect received notes to the
|
||||
* transactions they are spent in. This is the same security semantics as
|
||||
* for transparent addresses.
|
||||
*/
|
||||
boost::optional<uint256> nullifier;
|
||||
|
||||
/**
|
||||
* Cached incremental witnesses for spendable Notes.
|
||||
* Beginning of the list is the most recent witness.
|
||||
*/
|
||||
std::list<SproutWitness> witnesses;
|
||||
|
||||
/**
|
||||
* Block height corresponding to the most current witness.
|
||||
*
|
||||
* When we first create a SproutNoteData in CWallet::FindMySproutNotes, this is set to
|
||||
* When we first create a SaplingNoteData in CWallet::FindMySaplingNotes, this is set to
|
||||
* -1 as a placeholder. The next time CWallet::ChainTip is called, we can
|
||||
* determine what height the witness cache for this note is valid for (even
|
||||
* if no witnesses were cached), and so can set the correct value in
|
||||
* CWallet::BuildWitnessCache and CWallet::DecrementNoteWitnesses.
|
||||
*/
|
||||
int witnessHeight;
|
||||
|
||||
//In Memory Only
|
||||
bool witnessRootValidated;
|
||||
|
||||
SproutNoteData() : address(), nullifier(), witnessHeight {-1}, witnessRootValidated {false} { }
|
||||
SproutNoteData(libzcash::SproutPaymentAddress a) :
|
||||
address {a}, nullifier(), witnessHeight {-1}, witnessRootValidated {false} { }
|
||||
SproutNoteData(libzcash::SproutPaymentAddress a, uint256 n) :
|
||||
address {a}, nullifier {n}, witnessHeight {-1}, witnessRootValidated {false} { }
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
READWRITE(address);
|
||||
READWRITE(nullifier);
|
||||
READWRITE(witnesses);
|
||||
READWRITE(witnessHeight);
|
||||
}
|
||||
|
||||
friend bool operator<(const SproutNoteData& a, const SproutNoteData& b) {
|
||||
return (a.address < b.address ||
|
||||
(a.address == b.address && a.nullifier < b.nullifier));
|
||||
}
|
||||
|
||||
friend bool operator==(const SproutNoteData& a, const SproutNoteData& b) {
|
||||
return (a.address == b.address && a.nullifier == b.nullifier);
|
||||
}
|
||||
|
||||
friend bool operator!=(const SproutNoteData& a, const SproutNoteData& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
};
|
||||
|
||||
class SaplingNoteData
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* We initialize the height to -1 for the same reason as we do in SproutNoteData.
|
||||
* See the comment in that class for a full description.
|
||||
*/
|
||||
SaplingNoteData() : witnessHeight {-1}, nullifier() { }
|
||||
SaplingNoteData(libzcash::SaplingIncomingViewingKey ivk) : ivk {ivk}, witnessHeight {-1}, nullifier() { }
|
||||
SaplingNoteData(libzcash::SaplingIncomingViewingKey ivk, uint256 n) : ivk {ivk}, witnessHeight {-1}, nullifier(n) { }
|
||||
@@ -347,18 +284,11 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// NOTE: this sprout structure is serialized into wallet.dat, removing it would change wallet.dat format on disk :(
|
||||
typedef std::map<JSOutPoint, SproutNoteData> mapSproutNoteData_t;
|
||||
typedef std::map<SaplingOutPoint, SaplingNoteData> mapSaplingNoteData_t;
|
||||
|
||||
/** Decrypted note, its location in a transaction, and number of confirmations. */
|
||||
struct CSproutNotePlaintextEntry
|
||||
{
|
||||
JSOutPoint jsop;
|
||||
libzcash::SproutPaymentAddress address;
|
||||
libzcash::SproutNotePlaintext plaintext;
|
||||
int confirmations;
|
||||
};
|
||||
|
||||
/** Sapling note, its location in a transaction, and number of confirmations. */
|
||||
struct SaplingNoteEntry
|
||||
{
|
||||
@@ -824,7 +754,6 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
int SproutWitnessMinimumHeight(const uint256& nullifier, int nWitnessHeight, int nMinimumHeight);
|
||||
int SaplingWitnessMinimumHeight(const uint256& nullifier, int nWitnessHeight, int nMinimumHeight);
|
||||
|
||||
/**
|
||||
@@ -848,11 +777,11 @@ protected:
|
||||
try {
|
||||
for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
|
||||
auto wtx = wtxItem.second;
|
||||
// We skip transactions for which mapSproutNoteData and mapSaplingNoteData
|
||||
// are empty. This covers transactions that have no Sprout or Sapling data
|
||||
// We skip transactions for which mapSaplingNoteData
|
||||
// is empty. This covers transactions that have no Sapling data
|
||||
// (i.e. are purely transparent), as well as shielding and unshielding
|
||||
// transactions in which we only have transparent addresses involved.
|
||||
if (!(wtx.mapSproutNoteData.empty() && wtx.mapSaplingNoteData.empty())) {
|
||||
if (!(wtx.mapSaplingNoteData.empty())) {
|
||||
if (!walletdb.WriteTx(wtxItem.first, wtx)) {
|
||||
LogPrintf("SetBestChain(): Failed to write CWalletTx, aborting atomic write\n");
|
||||
walletdb.TxnAbort();
|
||||
@@ -1319,8 +1248,7 @@ public:
|
||||
bool LoadCryptedHDSeed(const uint256& seedFp, const std::vector<unsigned char>& seed);
|
||||
|
||||
/* Find notes filtered by payment address, min depth, ability to spend */
|
||||
void GetFilteredNotes(std::vector<CSproutNotePlaintextEntry>& sproutEntries,
|
||||
std::vector<SaplingNoteEntry>& saplingEntries,
|
||||
void GetFilteredNotes(std::vector<SaplingNoteEntry>& saplingEntries,
|
||||
std::string address,
|
||||
int minDepth=1,
|
||||
bool ignoreSpent=true,
|
||||
@@ -1328,8 +1256,7 @@ public:
|
||||
|
||||
/* Find notes filtered by payment addresses, min depth, max depth, if they are spent,
|
||||
if a spending key is required, and if they are locked */
|
||||
void GetFilteredNotes(std::vector<CSproutNotePlaintextEntry>& sproutEntries,
|
||||
std::vector<SaplingNoteEntry>& saplingEntries,
|
||||
void GetFilteredNotes(std::vector<SaplingNoteEntry>& saplingEntries,
|
||||
std::set<libzcash::PaymentAddress>& filterAddresses,
|
||||
int minDepth=1,
|
||||
int maxDepth=INT_MAX,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
|
||||
#ifndef ZC_ADDRESS_H_
|
||||
#define ZC_ADDRESS_H_
|
||||
|
||||
@@ -26,34 +28,6 @@ const size_t SerializedSaplingSpendingKeySize = 32;
|
||||
|
||||
typedef std::array<unsigned char, ZC_DIVERSIFIER_SIZE> diversifier_t;
|
||||
|
||||
class SproutPaymentAddress {
|
||||
public:
|
||||
uint256 a_pk;
|
||||
uint256 pk_enc;
|
||||
|
||||
SproutPaymentAddress() : a_pk(), pk_enc() { }
|
||||
SproutPaymentAddress(uint256 a_pk, uint256 pk_enc) : a_pk(a_pk), pk_enc(pk_enc) { }
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
READWRITE(a_pk);
|
||||
READWRITE(pk_enc);
|
||||
}
|
||||
|
||||
//! Get the 256-bit SHA256d hash of this payment address.
|
||||
uint256 GetHash() const;
|
||||
|
||||
friend inline bool operator==(const SproutPaymentAddress& a, const SproutPaymentAddress& b) {
|
||||
return a.a_pk == b.a_pk && a.pk_enc == b.pk_enc;
|
||||
}
|
||||
friend inline bool operator<(const SproutPaymentAddress& a, const SproutPaymentAddress& b) {
|
||||
return (a.a_pk < b.a_pk ||
|
||||
(a.a_pk == b.a_pk && a.pk_enc < b.pk_enc));
|
||||
}
|
||||
};
|
||||
|
||||
class ReceivingKey : public uint256 {
|
||||
public:
|
||||
ReceivingKey() { }
|
||||
@@ -62,45 +36,6 @@ public:
|
||||
uint256 pk_enc() const;
|
||||
};
|
||||
|
||||
class SproutViewingKey {
|
||||
public:
|
||||
uint256 a_pk;
|
||||
ReceivingKey sk_enc;
|
||||
|
||||
SproutViewingKey() : a_pk(), sk_enc() { }
|
||||
SproutViewingKey(uint256 a_pk, ReceivingKey sk_enc) : a_pk(a_pk), sk_enc(sk_enc) { }
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
READWRITE(a_pk);
|
||||
READWRITE(sk_enc);
|
||||
}
|
||||
|
||||
SproutPaymentAddress address() const;
|
||||
|
||||
friend inline bool operator==(const SproutViewingKey& a, const SproutViewingKey& b) {
|
||||
return a.a_pk == b.a_pk && a.sk_enc == b.sk_enc;
|
||||
}
|
||||
friend inline bool operator<(const SproutViewingKey& a, const SproutViewingKey& b) {
|
||||
return (a.a_pk < b.a_pk ||
|
||||
(a.a_pk == b.a_pk && a.sk_enc < b.sk_enc));
|
||||
}
|
||||
};
|
||||
|
||||
class SproutSpendingKey : public uint252 {
|
||||
public:
|
||||
SproutSpendingKey() : uint252() { }
|
||||
SproutSpendingKey(uint252 a_sk) : uint252(a_sk) { }
|
||||
|
||||
static SproutSpendingKey random();
|
||||
|
||||
ReceivingKey receiving_key() const;
|
||||
SproutViewingKey viewing_key() const;
|
||||
SproutPaymentAddress address() const;
|
||||
};
|
||||
|
||||
//! Sapling functions.
|
||||
class SaplingPaymentAddress {
|
||||
public:
|
||||
@@ -218,8 +153,8 @@ public:
|
||||
SaplingPaymentAddress default_address() const;
|
||||
};
|
||||
|
||||
typedef boost::variant<InvalidEncoding, SproutPaymentAddress, SaplingPaymentAddress> PaymentAddress;
|
||||
typedef boost::variant<InvalidEncoding, SproutViewingKey, SaplingIncomingViewingKey> ViewingKey;
|
||||
typedef boost::variant<InvalidEncoding, SaplingPaymentAddress> PaymentAddress;
|
||||
typedef boost::variant<InvalidEncoding, SaplingIncomingViewingKey> ViewingKey;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -246,24 +246,6 @@ uint256 JoinSplit<NumInputs, NumOutputs>::h_sig(
|
||||
return output;
|
||||
}
|
||||
|
||||
SproutNote JSOutput::note(const uint252& phi, const uint256& r, size_t i, const uint256& h_sig) const {
|
||||
uint256 rho = PRF_rho(phi, i, h_sig);
|
||||
|
||||
return SproutNote(addr.a_pk, value, rho, r);
|
||||
}
|
||||
|
||||
JSOutput::JSOutput() : addr(uint256(), uint256()), value(0) {
|
||||
SproutSpendingKey a_sk = SproutSpendingKey::random();
|
||||
addr = a_sk.address();
|
||||
}
|
||||
|
||||
JSInput::JSInput() : witness(SproutMerkleTree().witness()),
|
||||
key(SproutSpendingKey::random()) {
|
||||
note = SproutNote(key.address().a_pk, 0, random_uint256(), random_uint256());
|
||||
SproutMerkleTree dummy_tree;
|
||||
dummy_tree.append(note.cm());
|
||||
witness = dummy_tree.witness();
|
||||
}
|
||||
|
||||
template class JoinSplit<ZC_NUM_JS_INPUTS,
|
||||
ZC_NUM_JS_OUTPUTS>;
|
||||
|
||||
@@ -24,69 +24,13 @@ typedef std::array<unsigned char, GROTH_PROOF_SIZE> GrothProof;
|
||||
typedef boost::variant<PHGRProof, GrothProof> SproutProof;
|
||||
|
||||
class JSInput {
|
||||
public:
|
||||
SproutWitness witness;
|
||||
SproutNote note;
|
||||
SproutSpendingKey key;
|
||||
|
||||
JSInput();
|
||||
JSInput(SproutWitness witness,
|
||||
SproutNote note,
|
||||
SproutSpendingKey key) : witness(witness), note(note), key(key) { }
|
||||
|
||||
uint256 nullifier() const {
|
||||
return note.nullifier(key);
|
||||
}
|
||||
};
|
||||
|
||||
class JSOutput {
|
||||
public:
|
||||
SproutPaymentAddress addr;
|
||||
uint64_t value;
|
||||
std::array<unsigned char, ZC_MEMO_SIZE> memo = {{0xF6}}; // 0xF6 is invalid UTF8 as per spec, rest of array is 0x00
|
||||
|
||||
JSOutput();
|
||||
JSOutput(SproutPaymentAddress addr, uint64_t value) : addr(addr), value(value) { }
|
||||
|
||||
SproutNote note(const uint252& phi, const uint256& r, size_t i, const uint256& h_sig) const;
|
||||
};
|
||||
|
||||
template<size_t NumInputs, size_t NumOutputs>
|
||||
class JoinSplit {
|
||||
public:
|
||||
virtual ~JoinSplit() {}
|
||||
|
||||
static JoinSplit<NumInputs, NumOutputs>* Prepared();
|
||||
|
||||
static uint256 h_sig(const uint256& randomSeed,
|
||||
const std::array<uint256, NumInputs>& nullifiers,
|
||||
const uint256& joinSplitPubKey
|
||||
);
|
||||
|
||||
// Compute nullifiers, macs, note commitments & encryptions, and SNARK proof
|
||||
virtual SproutProof prove(
|
||||
const std::array<JSInput, NumInputs>& inputs,
|
||||
const std::array<JSOutput, NumOutputs>& outputs,
|
||||
std::array<SproutNote, NumOutputs>& out_notes,
|
||||
std::array<ZCNoteEncryption::Ciphertext, NumOutputs>& out_ciphertexts,
|
||||
uint256& out_ephemeralKey,
|
||||
const uint256& joinSplitPubKey,
|
||||
uint256& out_randomSeed,
|
||||
std::array<uint256, NumInputs>& out_hmacs,
|
||||
std::array<uint256, NumInputs>& out_nullifiers,
|
||||
std::array<uint256, NumOutputs>& out_commitments,
|
||||
uint64_t vpub_old,
|
||||
uint64_t vpub_new,
|
||||
const uint256& rt,
|
||||
bool computeProof = true,
|
||||
// For paymentdisclosure, we need to retrieve the esk.
|
||||
// Reference as non-const parameter with default value leads to compile error.
|
||||
// So use pointer for simplicity.
|
||||
uint256 *out_esk = nullptr
|
||||
) = 0;
|
||||
|
||||
protected:
|
||||
JoinSplit() {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
|
||||
#ifndef ZC_NOTE_H_
|
||||
#define ZC_NOTE_H_
|
||||
|
||||
@@ -22,25 +24,6 @@ public:
|
||||
inline uint64_t value() const { return value_; };
|
||||
};
|
||||
|
||||
class SproutNote : public BaseNote {
|
||||
public:
|
||||
uint256 a_pk;
|
||||
uint256 rho;
|
||||
uint256 r;
|
||||
|
||||
SproutNote(uint256 a_pk, uint64_t value, uint256 rho, uint256 r)
|
||||
: BaseNote(value), a_pk(a_pk), rho(rho), r(r) {}
|
||||
|
||||
SproutNote();
|
||||
|
||||
virtual ~SproutNote() {};
|
||||
|
||||
uint256 cm() const;
|
||||
|
||||
uint256 nullifier(const SproutSpendingKey& a_sk) const;
|
||||
};
|
||||
|
||||
|
||||
class SaplingNote : public BaseNote {
|
||||
public:
|
||||
diversifier_t d;
|
||||
@@ -74,48 +57,6 @@ public:
|
||||
inline const std::array<unsigned char, ZC_MEMO_SIZE> & memo() const { return memo_; }
|
||||
};
|
||||
|
||||
class SproutNotePlaintext : public BaseNotePlaintext {
|
||||
public:
|
||||
uint256 rho;
|
||||
uint256 r;
|
||||
|
||||
SproutNotePlaintext() {}
|
||||
|
||||
SproutNotePlaintext(const SproutNote& note, std::array<unsigned char, ZC_MEMO_SIZE> memo);
|
||||
|
||||
SproutNote note(const SproutPaymentAddress& addr) const;
|
||||
|
||||
virtual ~SproutNotePlaintext() {}
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
unsigned char leadingByte = 0x00;
|
||||
READWRITE(leadingByte);
|
||||
|
||||
if (leadingByte != 0x00) {
|
||||
throw std::ios_base::failure("lead byte of SproutNotePlaintext is not recognized");
|
||||
}
|
||||
|
||||
READWRITE(value_);
|
||||
READWRITE(rho);
|
||||
READWRITE(r);
|
||||
READWRITE(memo_);
|
||||
}
|
||||
|
||||
static SproutNotePlaintext decrypt(const ZCNoteDecryption& decryptor,
|
||||
const ZCNoteDecryption::Ciphertext& ciphertext,
|
||||
const uint256& ephemeralKey,
|
||||
const uint256& h_sig,
|
||||
unsigned char nonce
|
||||
);
|
||||
|
||||
ZCNoteEncryption::Ciphertext encrypt(ZCNoteEncryption& encryptor,
|
||||
const uint256& pk_enc
|
||||
) const;
|
||||
};
|
||||
|
||||
typedef std::pair<SaplingEncCiphertext, SaplingNoteEncryption> SaplingNotePlaintextEncryptionResult;
|
||||
|
||||
class SaplingNotePlaintext : public BaseNotePlaintext {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
/*
|
||||
Zcash uses SHA256Compress as a PRF for various components
|
||||
Hush uses SHA256Compress as a PRF for various components
|
||||
within the zkSNARK circuit.
|
||||
*/
|
||||
|
||||
@@ -11,13 +12,6 @@ within the zkSNARK circuit.
|
||||
|
||||
#include <array>
|
||||
|
||||
//! Sprout functions
|
||||
uint256 PRF_addr_a_pk(const uint252& a_sk);
|
||||
uint256 PRF_addr_sk_enc(const uint252& a_sk);
|
||||
uint256 PRF_nf(const uint252& a_sk, const uint256& rho);
|
||||
uint256 PRF_pk(const uint252& a_sk, size_t i0, const uint256& h_sig);
|
||||
uint256 PRF_rho(const uint252& phi, size_t i0, const uint256& h_sig);
|
||||
|
||||
//! Sapling functions
|
||||
uint256 PRF_ask(const uint256& sk);
|
||||
uint256 PRF_nsk(const uint256& sk);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// Copyright (c) 2018 The Zcash developers
|
||||
// Copyright (c) 2019-2020 The Hush developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -134,7 +135,7 @@ struct SaplingExtendedSpendingKey {
|
||||
}
|
||||
};
|
||||
|
||||
typedef boost::variant<InvalidEncoding, SproutSpendingKey, SaplingExtendedSpendingKey> SpendingKey;
|
||||
typedef boost::variant<InvalidEncoding, SaplingExtendedSpendingKey> SpendingKey;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user