more desprout, ugh
This commit is contained in:
@@ -1042,10 +1042,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||||||
if (mapArgs.count("-developerencryptwallet")) {
|
if (mapArgs.count("-developerencryptwallet")) {
|
||||||
fprintf(stderr,"%s wallet encryption error\n", __FUNCTION__);
|
fprintf(stderr,"%s wallet encryption error\n", __FUNCTION__);
|
||||||
return InitError(_("Wallet encryption requires -experimentalfeatures."));
|
return InitError(_("Wallet encryption requires -experimentalfeatures."));
|
||||||
}
|
//TODO: make this non experimental
|
||||||
else if (mapArgs.count("-paymentdisclosure")) {
|
|
||||||
fprintf(stderr,"%s payment disclosure error\n", __FUNCTION__);
|
|
||||||
return InitError(_("Payment disclosure requires -experimentalfeatures."));
|
|
||||||
} else if (mapArgs.count("-zmergetoaddress")) {
|
} else if (mapArgs.count("-zmergetoaddress")) {
|
||||||
fprintf(stderr,"%s zmerge error\n", __FUNCTION__);
|
fprintf(stderr,"%s zmerge error\n", __FUNCTION__);
|
||||||
return InitError(_("RPC method z_mergetoaddress requires -experimentalfeatures."));
|
return InitError(_("RPC method z_mergetoaddress requires -experimentalfeatures."));
|
||||||
|
|||||||
@@ -164,8 +164,6 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
|||||||
{ "kvupdate", 4 },
|
{ "kvupdate", 4 },
|
||||||
{ "z_importkey", 2 },
|
{ "z_importkey", 2 },
|
||||||
{ "z_importviewingkey", 2 },
|
{ "z_importviewingkey", 2 },
|
||||||
{ "z_getpaymentdisclosure", 1},
|
|
||||||
{ "z_getpaymentdisclosure", 2},
|
|
||||||
{ "z_listsentbyaddress", 1},
|
{ "z_listsentbyaddress", 1},
|
||||||
{ "z_listsentbyaddress", 2},
|
{ "z_listsentbyaddress", 2},
|
||||||
{ "z_listsentbyaddress", 3},
|
{ "z_listsentbyaddress", 3},
|
||||||
|
|||||||
@@ -669,11 +669,7 @@ static const CRPCCommand vRPCCommands[] =
|
|||||||
{ "wallet", "z_importviewingkey", &z_importviewingkey, true },
|
{ "wallet", "z_importviewingkey", &z_importviewingkey, true },
|
||||||
{ "wallet", "z_exportwallet", &z_exportwallet, true },
|
{ "wallet", "z_exportwallet", &z_exportwallet, true },
|
||||||
{ "wallet", "z_importwallet", &z_importwallet, true },
|
{ "wallet", "z_importwallet", &z_importwallet, true },
|
||||||
{ "wallet", "opreturn_burn", &opreturn_burn, true },
|
{ "wallet", "opreturn_burn", &opreturn_burn, true }
|
||||||
|
|
||||||
// TODO: rearrange into another category
|
|
||||||
{ "disclosure", "z_getpaymentdisclosure", &z_getpaymentdisclosure, true },
|
|
||||||
{ "disclosure", "z_validatepaymentdisclosure", &z_validatepaymentdisclosure, true }
|
|
||||||
#endif // ENABLE_WALLET
|
#endif // ENABLE_WALLET
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,6 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "paymentdisclosuredb.h"
|
|
||||||
int32_t komodo_blockheight(uint256 hash);
|
int32_t komodo_blockheight(uint256 hash);
|
||||||
|
|
||||||
using namespace libzcash;
|
using namespace libzcash;
|
||||||
|
|||||||
@@ -49,7 +49,6 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "paymentdisclosuredb.h"
|
|
||||||
#include <boost/optional/optional_io.hpp>
|
#include <boost/optional/optional_io.hpp>
|
||||||
|
|
||||||
using namespace libzcash;
|
using namespace libzcash;
|
||||||
@@ -142,9 +141,8 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany(
|
|||||||
LogPrint("zrpc", "%s: z_sendmany initialized\n", getId());
|
LogPrint("zrpc", "%s: z_sendmany initialized\n", getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Enable payment disclosure if requested
|
// Enable payment disclosure if requested
|
||||||
paymentDisclosureMode = fExperimentalMode && GetBoolArg("-paymentdisclosure", true);
|
paymentDisclosureMode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncRPCOperation_sendmany::~AsyncRPCOperation_sendmany() {
|
AsyncRPCOperation_sendmany::~AsyncRPCOperation_sendmany() {
|
||||||
|
|||||||
@@ -8309,9 +8309,6 @@ extern UniValue z_importviewingkey(const UniValue& params, bool fHelp, const CPu
|
|||||||
extern UniValue z_exportwallet(const UniValue& params, bool fHelp, const CPubKey& mypk);
|
extern UniValue z_exportwallet(const UniValue& params, bool fHelp, const CPubKey& mypk);
|
||||||
extern UniValue z_importwallet(const UniValue& params, bool fHelp, const CPubKey& mypk);
|
extern UniValue z_importwallet(const UniValue& params, bool fHelp, const CPubKey& mypk);
|
||||||
|
|
||||||
extern UniValue z_getpaymentdisclosure(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcdisclosure.cpp
|
|
||||||
extern UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp, const CPubKey& mypk);
|
|
||||||
|
|
||||||
static const CRPCCommand commands[] =
|
static const CRPCCommand commands[] =
|
||||||
{ // category name actor (function) okSafeMode
|
{ // category name actor (function) okSafeMode
|
||||||
// --------------------- ------------------------ ----------------------- ----------
|
// --------------------- ------------------------ ----------------------- ----------
|
||||||
@@ -8380,10 +8377,7 @@ static const CRPCCommand commands[] =
|
|||||||
{ "wallet", "z_getinfo", &z_getinfo, true },
|
{ "wallet", "z_getinfo", &z_getinfo, true },
|
||||||
{ "wallet", "z_listsentbyaddress", &z_listsentbyaddress, true },
|
{ "wallet", "z_listsentbyaddress", &z_listsentbyaddress, true },
|
||||||
{ "wallet", "z_listreceivedbyaddress", &z_listreceivedbyaddress, true },
|
{ "wallet", "z_listreceivedbyaddress", &z_listreceivedbyaddress, true },
|
||||||
{ "wallet", "z_getnotescount", &z_getnotescount, false },
|
{ "wallet", "z_getnotescount", &z_getnotescount, false }
|
||||||
// TODO: rearrange into another category
|
|
||||||
{ "disclosure", "z_getpaymentdisclosure", &z_getpaymentdisclosure, true },
|
|
||||||
{ "disclosure", "z_validatepaymentdisclosure", &z_validatepaymentdisclosure, true }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// Copyright (c) 2019-2020 The Hush developers
|
||||||
#include "JoinSplit.hpp"
|
#include "JoinSplit.hpp"
|
||||||
#include "prf.h"
|
#include "prf.h"
|
||||||
#include "sodium.h"
|
#include "sodium.h"
|
||||||
@@ -28,6 +29,7 @@ public:
|
|||||||
JoinSplitCircuit() {}
|
JoinSplitCircuit() {}
|
||||||
~JoinSplitCircuit() {}
|
~JoinSplitCircuit() {}
|
||||||
|
|
||||||
|
/*
|
||||||
SproutProof prove(
|
SproutProof prove(
|
||||||
const std::array<JSInput, NumInputs>& inputs,
|
const std::array<JSInput, NumInputs>& inputs,
|
||||||
const std::array<JSOutput, NumOutputs>& outputs,
|
const std::array<JSOutput, NumOutputs>& outputs,
|
||||||
@@ -45,169 +47,13 @@ public:
|
|||||||
bool computeProof,
|
bool computeProof,
|
||||||
uint256 *out_esk // Payment disclosure
|
uint256 *out_esk // Payment disclosure
|
||||||
) {
|
) {
|
||||||
if (vpub_old > MAX_MONEY) {
|
|
||||||
throw std::invalid_argument("nonsensical vpub_old value");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vpub_new > MAX_MONEY) {
|
|
||||||
throw std::invalid_argument("nonsensical vpub_new value");
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t lhs_value = vpub_old;
|
|
||||||
uint64_t rhs_value = vpub_new;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < NumInputs; i++) {
|
|
||||||
// Sanity checks of input
|
|
||||||
{
|
|
||||||
// If note has nonzero value
|
|
||||||
if (inputs[i].note.value() != 0) {
|
|
||||||
// The witness root must equal the input root.
|
|
||||||
if (inputs[i].witness.root() != rt) {
|
|
||||||
throw std::invalid_argument("joinsplit not anchored to the correct root");
|
|
||||||
}
|
|
||||||
|
|
||||||
// The tree must witness the correct element
|
|
||||||
if (inputs[i].note.cm() != inputs[i].witness.element()) {
|
|
||||||
throw std::invalid_argument("witness of wrong element for joinsplit input");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure we have the key to this note.
|
|
||||||
if (inputs[i].note.a_pk != inputs[i].key.address().a_pk) {
|
|
||||||
throw std::invalid_argument("input note not authorized to spend with given key");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Balance must be sensical
|
|
||||||
if (inputs[i].note.value() > MAX_MONEY) {
|
|
||||||
throw std::invalid_argument("nonsensical input note value");
|
|
||||||
}
|
|
||||||
|
|
||||||
lhs_value += inputs[i].note.value();
|
|
||||||
|
|
||||||
if (lhs_value > MAX_MONEY) {
|
|
||||||
throw std::invalid_argument("nonsensical left hand size of joinsplit balance");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute nullifier of input
|
|
||||||
out_nullifiers[i] = inputs[i].nullifier();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sample randomSeed
|
|
||||||
out_randomSeed = random_uint256();
|
|
||||||
|
|
||||||
// Compute h_sig
|
|
||||||
uint256 h_sig = this->h_sig(out_randomSeed, out_nullifiers, joinSplitPubKey);
|
|
||||||
|
|
||||||
// Sample phi
|
|
||||||
uint252 phi = random_uint252();
|
|
||||||
|
|
||||||
// Compute notes for outputs
|
|
||||||
for (size_t i = 0; i < NumOutputs; i++) {
|
|
||||||
// Sanity checks of output
|
|
||||||
{
|
|
||||||
if (outputs[i].value > MAX_MONEY) {
|
|
||||||
throw std::invalid_argument("nonsensical output value");
|
|
||||||
}
|
|
||||||
|
|
||||||
rhs_value += outputs[i].value;
|
|
||||||
|
|
||||||
if (rhs_value > MAX_MONEY) {
|
|
||||||
throw std::invalid_argument("nonsensical right hand side of joinsplit balance");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sample r
|
|
||||||
uint256 r = random_uint256();
|
|
||||||
|
|
||||||
out_notes[i] = outputs[i].note(phi, r, i, h_sig);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lhs_value != rhs_value) {
|
|
||||||
throw std::invalid_argument("invalid joinsplit balance");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute the output commitments
|
|
||||||
for (size_t i = 0; i < NumOutputs; i++) {
|
|
||||||
out_commitments[i] = out_notes[i].cm();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encrypt the ciphertexts containing the note
|
|
||||||
// plaintexts to the recipients of the value.
|
|
||||||
{
|
|
||||||
ZCNoteEncryption encryptor(h_sig);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < NumOutputs; i++) {
|
|
||||||
SproutNotePlaintext pt(out_notes[i], outputs[i].memo);
|
|
||||||
|
|
||||||
out_ciphertexts[i] = pt.encrypt(encryptor, outputs[i].addr.pk_enc);
|
|
||||||
}
|
|
||||||
|
|
||||||
out_ephemeralKey = encryptor.get_epk();
|
|
||||||
|
|
||||||
// !!! Payment disclosure START
|
|
||||||
if (out_esk != nullptr) {
|
|
||||||
*out_esk = encryptor.get_esk();
|
|
||||||
}
|
|
||||||
// !!! Payment disclosure END
|
|
||||||
}
|
|
||||||
|
|
||||||
// Authenticate h_sig with each of the input
|
|
||||||
// spending keys, producing macs which protect
|
|
||||||
// against malleability.
|
|
||||||
for (size_t i = 0; i < NumInputs; i++) {
|
|
||||||
out_macs[i] = PRF_pk(inputs[i].key, i, h_sig);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!computeProof) {
|
|
||||||
return GrothProof();
|
|
||||||
}
|
|
||||||
|
|
||||||
GrothProof proof;
|
GrothProof proof;
|
||||||
|
|
||||||
CDataStream ss1(SER_NETWORK, PROTOCOL_VERSION);
|
|
||||||
ss1 << inputs[0].witness.path();
|
|
||||||
std::vector<unsigned char> auth1(ss1.begin(), ss1.end());
|
|
||||||
|
|
||||||
CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION);
|
|
||||||
ss2 << inputs[1].witness.path();
|
|
||||||
std::vector<unsigned char> auth2(ss2.begin(), ss2.end());
|
|
||||||
|
|
||||||
librustzcash_sprout_prove(
|
|
||||||
proof.begin(),
|
|
||||||
|
|
||||||
phi.begin(),
|
|
||||||
rt.begin(),
|
|
||||||
h_sig.begin(),
|
|
||||||
|
|
||||||
inputs[0].key.begin(),
|
|
||||||
inputs[0].note.value(),
|
|
||||||
inputs[0].note.rho.begin(),
|
|
||||||
inputs[0].note.r.begin(),
|
|
||||||
auth1.data(),
|
|
||||||
|
|
||||||
inputs[1].key.begin(),
|
|
||||||
inputs[1].note.value(),
|
|
||||||
inputs[1].note.rho.begin(),
|
|
||||||
inputs[1].note.r.begin(),
|
|
||||||
auth2.data(),
|
|
||||||
|
|
||||||
out_notes[0].a_pk.begin(),
|
|
||||||
out_notes[0].value(),
|
|
||||||
out_notes[0].r.begin(),
|
|
||||||
|
|
||||||
out_notes[1].a_pk.begin(),
|
|
||||||
out_notes[1].value(),
|
|
||||||
out_notes[1].r.begin(),
|
|
||||||
|
|
||||||
vpub_old,
|
|
||||||
vpub_new
|
|
||||||
);
|
|
||||||
|
|
||||||
return proof;
|
return proof;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
template<size_t NumInputs, size_t NumOutputs>
|
template<size_t NumInputs, size_t NumOutputs>
|
||||||
JoinSplit<NumInputs, NumOutputs>* JoinSplit<NumInputs, NumOutputs>::Prepared()
|
JoinSplit<NumInputs, NumOutputs>* JoinSplit<NumInputs, NumOutputs>::Prepared()
|
||||||
{
|
{
|
||||||
@@ -250,4 +96,5 @@ uint256 JoinSplit<NumInputs, NumOutputs>::h_sig(
|
|||||||
template class JoinSplit<ZC_NUM_JS_INPUTS,
|
template class JoinSplit<ZC_NUM_JS_INPUTS,
|
||||||
ZC_NUM_JS_OUTPUTS>;
|
ZC_NUM_JS_OUTPUTS>;
|
||||||
|
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
// Copyright (c) 2019-2020 The Hush developers
|
||||||
|
|
||||||
#include "Note.hpp"
|
#include "Note.hpp"
|
||||||
#include "prf.h"
|
#include "prf.h"
|
||||||
#include "crypto/sha256.h"
|
#include "crypto/sha256.h"
|
||||||
@@ -11,6 +13,7 @@
|
|||||||
|
|
||||||
using namespace libzcash;
|
using namespace libzcash;
|
||||||
|
|
||||||
|
/*
|
||||||
SproutNote::SproutNote() {
|
SproutNote::SproutNote() {
|
||||||
a_pk = random_uint256();
|
a_pk = random_uint256();
|
||||||
rho = random_uint256();
|
rho = random_uint256();
|
||||||
@@ -39,6 +42,7 @@ uint256 SproutNote::cm() const {
|
|||||||
uint256 SproutNote::nullifier(const SproutSpendingKey& a_sk) const {
|
uint256 SproutNote::nullifier(const SproutSpendingKey& a_sk) const {
|
||||||
return PRF_nf(a_sk, rho);
|
return PRF_nf(a_sk, rho);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// Construct and populate Sapling note for a given payment address and value.
|
// Construct and populate Sapling note for a given payment address and value.
|
||||||
SaplingNote::SaplingNote(const SaplingPaymentAddress& address, const uint64_t value) : BaseNote(value) {
|
SaplingNote::SaplingNote(const SaplingPaymentAddress& address, const uint64_t value) : BaseNote(value) {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
// Copyright (c) 2019-2020 The Hush developers
|
|
||||||
/*
|
/*
|
||||||
Hush uses SHA256Compress as a PRF for various components
|
Zcash uses SHA256Compress as a PRF for various components
|
||||||
within the zkSNARK circuit.
|
within the zkSNARK circuit.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -12,6 +11,13 @@ within the zkSNARK circuit.
|
|||||||
|
|
||||||
#include <array>
|
#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
|
//! Sapling functions
|
||||||
uint256 PRF_ask(const uint256& sk);
|
uint256 PRF_ask(const uint256& sk);
|
||||||
uint256 PRF_nsk(const uint256& sk);
|
uint256 PRF_nsk(const uint256& sk);
|
||||||
|
|||||||
Reference in New Issue
Block a user