Transplant of libzcash.
This commit is contained in:
parent
2140639309
commit
2dc3599271
18
src/init.cpp
18
src/init.cpp
|
@ -52,7 +52,7 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
libzerocash::ZerocashParams *pzerocashParams = NULL;
|
||||
ZCJoinSplit* pzcashParams = NULL;
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
CWallet* pwalletMain = NULL;
|
||||
|
@ -605,24 +605,18 @@ static void ZC_LoadParams()
|
|||
boost::filesystem::path pk_path = ZC_GetParamsDir() / "zc-testnet-public-alpha-proving.key";
|
||||
boost::filesystem::path vk_path = ZC_GetParamsDir() / "zc-testnet-public-alpha-verification.key";
|
||||
|
||||
libzerocash::ZerocashParams::zerocash_pp::init_public_params();
|
||||
|
||||
pzcashParams = ZCJoinSplit::Unopened();
|
||||
|
||||
LogPrintf("Loading verification key from %s\n", vk_path.string().c_str());
|
||||
gettimeofday(&tv_start, 0);
|
||||
auto vk_loaded = libzerocash::ZerocashParams::LoadVerificationKeyFromFile(
|
||||
vk_path.string(),
|
||||
INCREMENTAL_MERKLE_TREE_DEPTH
|
||||
);
|
||||
|
||||
pzcashParams->loadVerifyingKey(vk_path.string());
|
||||
|
||||
gettimeofday(&tv_end, 0);
|
||||
elapsed = float(tv_end.tv_sec-tv_start.tv_sec) + (tv_end.tv_usec-tv_start.tv_usec)/float(1000000);
|
||||
LogPrintf("Loaded verification key in %fs seconds.\n", elapsed);
|
||||
|
||||
pzerocashParams = new libzerocash::ZerocashParams(
|
||||
INCREMENTAL_MERKLE_TREE_DEPTH,
|
||||
pk_path.string(),
|
||||
&vk_loaded
|
||||
);
|
||||
pzcashParams->setProvingKeyPath(pk_path.string());
|
||||
}
|
||||
|
||||
/** Initialize bitcoin.
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "zerocash/ZerocashParams.h"
|
||||
#include "zcash/JoinSplit.hpp"
|
||||
|
||||
class CScheduler;
|
||||
class CWallet;
|
||||
|
@ -19,7 +19,7 @@ class thread_group;
|
|||
} // namespace boost
|
||||
|
||||
extern CWallet* pwalletMain;
|
||||
extern libzerocash::ZerocashParams* pzerocashParams;
|
||||
extern ZCJoinSplit* pzcashParams;
|
||||
|
||||
void StartShutdown();
|
||||
bool ShutdownRequested();
|
||||
|
|
|
@ -963,7 +963,7 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
|
|||
// TODO: #808
|
||||
uint256 pubKeyHash;
|
||||
|
||||
if (!pour.Verify(*pzerocashParams, pubKeyHash)) {
|
||||
if (!pour.Verify(*pzcashParams, pubKeyHash)) {
|
||||
return state.DoS(100, error("CheckTransaction(): pour does not verify"),
|
||||
REJECT_INVALID, "bad-txns-pour-verification-failed");
|
||||
}
|
||||
|
|
|
@ -9,72 +9,56 @@
|
|||
#include "tinyformat.h"
|
||||
#include "utilstrencodings.h"
|
||||
|
||||
#include "zerocash/PourProver.h"
|
||||
#include "zerocash/PourTransaction.h"
|
||||
|
||||
template<std::size_t N>
|
||||
boost::array<std::vector<unsigned char>, N> uint256_to_array(const boost::array<uint256, N>& in) {
|
||||
boost::array<std::vector<unsigned char>, N> result;
|
||||
for (size_t i = 0; i < N; i++) {
|
||||
result[i] = std::vector<unsigned char>(in[i].begin(), in[i].end());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<std::size_t N>
|
||||
boost::array<uint256, N> unsigned_char_vector_array_to_uint256_array(const boost::array<std::vector<unsigned char>, N>& in) {
|
||||
boost::array<uint256, N> result;
|
||||
for (size_t i = 0; i < N; i++) {
|
||||
result[i] = uint256(in[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
CPourTx::CPourTx(ZerocashParams& params,
|
||||
CPourTx::CPourTx(ZCJoinSplit& params,
|
||||
const uint256& pubKeyHash,
|
||||
const uint256& anchor,
|
||||
const boost::array<PourInput, ZC_NUM_JS_INPUTS>& inputs,
|
||||
const boost::array<PourOutput, ZC_NUM_JS_OUTPUTS>& outputs,
|
||||
const boost::array<libzcash::JSInput, ZC_NUM_JS_INPUTS>& inputs,
|
||||
const boost::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS>& outputs,
|
||||
CAmount vpub_old,
|
||||
CAmount vpub_new) : vpub_old(vpub_old), vpub_new(vpub_new), anchor(anchor)
|
||||
{
|
||||
PourTransaction pourtx(params,
|
||||
std::vector<unsigned char>(pubKeyHash.begin(), pubKeyHash.end()),
|
||||
std::vector<unsigned char>(anchor.begin(), anchor.end()),
|
||||
std::vector<PourInput>(inputs.begin(), inputs.end()),
|
||||
std::vector<PourOutput>(outputs.begin(), outputs.end()),
|
||||
boost::array<libzcash::Note, ZC_NUM_JS_OUTPUTS> notes;
|
||||
|
||||
params.loadProvingKey();
|
||||
proof = params.prove(
|
||||
inputs,
|
||||
outputs,
|
||||
notes,
|
||||
ciphertexts,
|
||||
ephemeralKey,
|
||||
pubKeyHash,
|
||||
randomSeed,
|
||||
macs,
|
||||
serials,
|
||||
commitments,
|
||||
vpub_old,
|
||||
vpub_new);
|
||||
|
||||
boost::array<std::vector<unsigned char>, ZC_NUM_JS_INPUTS> serials_bv;
|
||||
boost::array<std::vector<unsigned char>, ZC_NUM_JS_OUTPUTS> commitments_bv;
|
||||
boost::array<std::vector<unsigned char>, ZC_NUM_JS_INPUTS> macs_bv;
|
||||
|
||||
proof = pourtx.unpack(serials_bv, commitments_bv, macs_bv, ciphertexts, ephemeralKey);
|
||||
serials = unsigned_char_vector_array_to_uint256_array(serials_bv);
|
||||
commitments = unsigned_char_vector_array_to_uint256_array(commitments_bv);
|
||||
macs = unsigned_char_vector_array_to_uint256_array(macs_bv);
|
||||
vpub_new,
|
||||
anchor
|
||||
);
|
||||
}
|
||||
|
||||
bool CPourTx::Verify(
|
||||
ZerocashParams& params,
|
||||
ZCJoinSplit& params,
|
||||
const uint256& pubKeyHash
|
||||
) const {
|
||||
return PourProver::VerifyProof(
|
||||
params,
|
||||
std::vector<unsigned char>(pubKeyHash.begin(), pubKeyHash.end()),
|
||||
std::vector<unsigned char>(anchor.begin(), anchor.end()),
|
||||
return params.verify(
|
||||
proof,
|
||||
pubKeyHash,
|
||||
randomSeed,
|
||||
macs,
|
||||
serials,
|
||||
commitments,
|
||||
vpub_old,
|
||||
vpub_new,
|
||||
uint256_to_array<ZC_NUM_JS_INPUTS>(serials),
|
||||
uint256_to_array<ZC_NUM_JS_OUTPUTS>(commitments),
|
||||
uint256_to_array<ZC_NUM_JS_INPUTS>(macs),
|
||||
proof
|
||||
anchor
|
||||
);
|
||||
}
|
||||
|
||||
uint256 CPourTx::h_sig(ZCJoinSplit& params, const uint256& pubKeyHash) const
|
||||
{
|
||||
return params.h_sig(randomSeed, serials, pubKeyHash);
|
||||
}
|
||||
|
||||
std::string COutPoint::ToString() const
|
||||
{
|
||||
return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,10), n);
|
||||
|
|
|
@ -13,14 +13,9 @@
|
|||
|
||||
#include <boost/array.hpp>
|
||||
|
||||
#include "zerocash/ZerocashParams.h"
|
||||
#include "zerocash/PourInput.h"
|
||||
#include "zerocash/PourOutput.h"
|
||||
|
||||
#include "zcash/NoteEncryption.hpp"
|
||||
#include "zcash/Zcash.h"
|
||||
|
||||
using namespace libzerocash;
|
||||
#include "zcash/JoinSplit.hpp"
|
||||
|
||||
class CPourTx
|
||||
{
|
||||
|
@ -72,17 +67,20 @@ public:
|
|||
|
||||
CPourTx(): vpub_old(0), vpub_new(0) { }
|
||||
|
||||
CPourTx(ZerocashParams& params,
|
||||
CPourTx(ZCJoinSplit& params,
|
||||
const uint256& pubKeyHash,
|
||||
const uint256& rt,
|
||||
const boost::array<PourInput, ZC_NUM_JS_INPUTS>& inputs,
|
||||
const boost::array<PourOutput, ZC_NUM_JS_OUTPUTS>& outputs,
|
||||
const boost::array<libzcash::JSInput, ZC_NUM_JS_INPUTS>& inputs,
|
||||
const boost::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS>& outputs,
|
||||
CAmount vpub_old,
|
||||
CAmount vpub_new
|
||||
);
|
||||
|
||||
// Verifies that the pour proof is correct.
|
||||
bool Verify(ZerocashParams& params, const uint256& pubKeyHash) const;
|
||||
bool Verify(ZCJoinSplit& params, const uint256& pubKeyHash) const;
|
||||
|
||||
// Returns the calculated h_sig
|
||||
uint256 h_sig(ZCJoinSplit& params, const uint256& pubKeyHash) const;
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry)
|
|||
|
||||
// TODO: #808
|
||||
uint256 pubKeyHash;
|
||||
pour.push_back(Pair("valid", pourtx.Verify(*pzerocashParams, pubKeyHash)));
|
||||
pour.push_back(Pair("valid", pourtx.Verify(*pzcashParams, pubKeyHash)));
|
||||
|
||||
vpour.push_back(pour);
|
||||
}
|
||||
|
|
|
@ -166,10 +166,12 @@ BOOST_AUTO_TEST_CASE(serials_test)
|
|||
|
||||
void appendRandomCommitment(ZCIncrementalMerkleTree &tree)
|
||||
{
|
||||
Address addr = Address::CreateNewRandomAddress();
|
||||
Coin coin(addr.getPublicAddress(), 100);
|
||||
libzcash::SpendingKey k = libzcash::SpendingKey::random();
|
||||
libzcash::PaymentAddress addr = k.address();
|
||||
|
||||
tree.append(uint256(coin.getCoinCommitment().getCommitmentValue()));
|
||||
libzcash::Note note(addr.a_pk, 0, uint256(), uint256());
|
||||
|
||||
tree.append(note.cm());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(anchors_flush_test)
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
CClientUIInterface uiInterface; // Declared but not defined in ui_interface.h
|
||||
CWallet* pwalletMain;
|
||||
libzerocash::ZerocashParams *pzerocashParams;
|
||||
ZCJoinSplit *pzcashParams;
|
||||
|
||||
extern bool fPrintToConsole;
|
||||
extern void noui_connect();
|
||||
|
|
|
@ -25,15 +25,11 @@
|
|||
#include <boost/assign/list_of.hpp>
|
||||
#include "json/json_spirit_writer_template.h"
|
||||
|
||||
#include "zerocash/ZerocashParams.h"
|
||||
#include "zerocash/PourInput.h"
|
||||
#include "zerocash/PourOutput.h"
|
||||
#include "zerocash/Address.h"
|
||||
#include "zerocash/Coin.h"
|
||||
#include "zcash/Note.hpp"
|
||||
#include "zcash/Address.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace json_spirit;
|
||||
using namespace libzerocash;
|
||||
|
||||
// In script_tests.cpp
|
||||
extern Array read_json(const std::string& jsondata);
|
||||
|
@ -311,19 +307,18 @@ BOOST_AUTO_TEST_CASE(test_basic_pour_verification)
|
|||
// the integrity of the scheme through its own tests.
|
||||
|
||||
// construct the r1cs keypair
|
||||
auto keypair = ZerocashParams::GenerateNewKeyPair(INCREMENTAL_MERKLE_TREE_DEPTH);
|
||||
ZerocashParams p(
|
||||
INCREMENTAL_MERKLE_TREE_DEPTH,
|
||||
&keypair
|
||||
);
|
||||
auto p = ZCJoinSplit::Generate();
|
||||
|
||||
// construct a merkle tree
|
||||
ZCIncrementalMerkleTree merkleTree;
|
||||
Address addr = Address::CreateNewRandomAddress();
|
||||
Coin coin(addr.getPublicAddress(), 100);
|
||||
|
||||
libzcash::SpendingKey k = libzcash::SpendingKey::random();
|
||||
libzcash::PaymentAddress addr = k.address();
|
||||
|
||||
libzcash::Note note(addr.a_pk, 100, uint256(), uint256());
|
||||
|
||||
// commitment from coin
|
||||
uint256 commitment(coin.getCoinCommitment().getCommitmentValue());
|
||||
uint256 commitment = note.cm();
|
||||
|
||||
// insert commitment into the merkle tree
|
||||
merkleTree.append(commitment);
|
||||
|
@ -332,22 +327,21 @@ BOOST_AUTO_TEST_CASE(test_basic_pour_verification)
|
|||
uint256 rt = merkleTree.root();
|
||||
|
||||
auto witness = merkleTree.witness();
|
||||
auto path = witness.path();
|
||||
|
||||
// create CPourTx
|
||||
uint256 pubKeyHash;
|
||||
boost::array<PourInput, ZC_NUM_JS_INPUTS> inputs = {
|
||||
PourInput(coin, addr, path),
|
||||
PourInput(INCREMENTAL_MERKLE_TREE_DEPTH) // dummy input of zero value
|
||||
boost::array<libzcash::JSInput, ZC_NUM_JS_INPUTS> inputs = {
|
||||
libzcash::JSInput(witness, note, k),
|
||||
libzcash::JSInput() // dummy input of zero value
|
||||
};
|
||||
boost::array<PourOutput, ZC_NUM_JS_OUTPUTS> outputs = {
|
||||
PourOutput(50),
|
||||
PourOutput(50)
|
||||
boost::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS> outputs = {
|
||||
libzcash::JSOutput(addr, 50),
|
||||
libzcash::JSOutput(addr, 50)
|
||||
};
|
||||
|
||||
{
|
||||
CPourTx pourtx(p, pubKeyHash, uint256(rt), inputs, outputs, 0, 0);
|
||||
BOOST_CHECK(pourtx.Verify(p, pubKeyHash));
|
||||
CPourTx pourtx(*p, pubKeyHash, rt, inputs, outputs, 0, 0);
|
||||
BOOST_CHECK(pourtx.Verify(*p, pubKeyHash));
|
||||
|
||||
CDataStream ss(SER_DISK, CLIENT_VERSION);
|
||||
ss << pourtx;
|
||||
|
@ -356,21 +350,23 @@ BOOST_AUTO_TEST_CASE(test_basic_pour_verification)
|
|||
ss >> pourtx_deserialized;
|
||||
|
||||
BOOST_CHECK(pourtx_deserialized == pourtx);
|
||||
BOOST_CHECK(pourtx_deserialized.Verify(p, pubKeyHash));
|
||||
BOOST_CHECK(pourtx_deserialized.Verify(*p, pubKeyHash));
|
||||
}
|
||||
|
||||
{
|
||||
// Ensure that the balance equation is working.
|
||||
BOOST_CHECK_THROW(CPourTx(p, pubKeyHash, uint256(rt), inputs, outputs, 10, 0), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(CPourTx(p, pubKeyHash, uint256(rt), inputs, outputs, 0, 10), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(CPourTx(*p, pubKeyHash, rt, inputs, outputs, 10, 0), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(CPourTx(*p, pubKeyHash, rt, inputs, outputs, 0, 10), std::invalid_argument);
|
||||
}
|
||||
|
||||
{
|
||||
// Ensure that it won't verify if the root is changed.
|
||||
auto test = CPourTx(p, pubKeyHash, uint256(rt), inputs, outputs, 0, 0);
|
||||
auto test = CPourTx(*p, pubKeyHash, rt, inputs, outputs, 0, 0);
|
||||
test.anchor = GetRandHash();
|
||||
BOOST_CHECK(!test.Verify(p, pubKeyHash));
|
||||
BOOST_CHECK(!test.Verify(*p, pubKeyHash));
|
||||
}
|
||||
|
||||
delete p;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_simple_pour_invalidity)
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
using namespace std;
|
||||
using namespace json_spirit;
|
||||
|
||||
using namespace libzcash;
|
||||
|
||||
int64_t nWalletUnlockTime;
|
||||
static CCriticalSection cs_nWalletUnlockTime;
|
||||
|
||||
|
@ -2385,7 +2387,7 @@ Value zc_benchmark(const json_spirit::Array& params, bool fHelp)
|
|||
if (benchmarktype == "createjoinsplit") {
|
||||
/* Load the proving now key so that it doesn't happen as part of the
|
||||
* first joinsplit. */
|
||||
pzerocashParams->loadProvingKey();
|
||||
pzcashParams->loadProvingKey();
|
||||
}
|
||||
|
||||
for (int i = 0; i < samplecount; i++) {
|
||||
|
@ -2454,14 +2456,12 @@ Value zc_raw_receive(const json_spirit::Array& params, bool fHelp)
|
|||
|
||||
LOCK(cs_main);
|
||||
|
||||
uint256 a_sk;
|
||||
uint256 sk_enc;
|
||||
SpendingKey k;
|
||||
|
||||
{
|
||||
CDataStream ssData(ParseHexV(params[0], "zcsecretkey"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
try {
|
||||
ssData >> a_sk;
|
||||
ssData >> sk_enc;
|
||||
ssData >> k;
|
||||
} catch(const std::exception &) {
|
||||
throw runtime_error(
|
||||
"zcsecretkey could not be decoded"
|
||||
|
@ -2469,12 +2469,10 @@ Value zc_raw_receive(const json_spirit::Array& params, bool fHelp)
|
|||
}
|
||||
}
|
||||
|
||||
libzerocash::PrivateAddress zcsecretkey(a_sk, sk_enc);
|
||||
libzerocash::Address zcaddress(zcsecretkey);
|
||||
|
||||
uint256 epk;
|
||||
unsigned char nonce;
|
||||
ZCNoteEncryption::Ciphertext ct;
|
||||
uint256 h_sig;
|
||||
|
||||
{
|
||||
CDataStream ssData(ParseHexV(params[1], "encrypted_bucket"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
|
@ -2482,6 +2480,7 @@ Value zc_raw_receive(const json_spirit::Array& params, bool fHelp)
|
|||
ssData >> nonce;
|
||||
ssData >> epk;
|
||||
ssData >> ct;
|
||||
ssData >> h_sig;
|
||||
} catch(const std::exception &) {
|
||||
throw runtime_error(
|
||||
"encrypted_bucket could not be decoded"
|
||||
|
@ -2489,32 +2488,40 @@ Value zc_raw_receive(const json_spirit::Array& params, bool fHelp)
|
|||
}
|
||||
}
|
||||
|
||||
libzerocash::Coin decrypted_bucket(ct, zcaddress, epk, nonce);
|
||||
ZCNoteDecryption decryptor(k.viewing_key());
|
||||
|
||||
std::vector<unsigned char> commitment_v = decrypted_bucket.getCoinCommitment().getCommitmentValue();
|
||||
uint256 commitment = uint256(commitment_v);
|
||||
NotePlaintext npt = NotePlaintext::decrypt(
|
||||
decryptor,
|
||||
ct,
|
||||
epk,
|
||||
h_sig,
|
||||
nonce
|
||||
);
|
||||
PaymentAddress payment_addr = k.address();
|
||||
Note decrypted_note = npt.note(payment_addr);
|
||||
|
||||
assert(pwalletMain != NULL);
|
||||
libzcash::MerklePath path;
|
||||
std::vector<boost::optional<ZCIncrementalWitness>> witnesses;
|
||||
uint256 anchor;
|
||||
auto found_in_chain = pwalletMain->WitnessBucketCommitment(commitment, path, anchor);
|
||||
|
||||
CAmount value_of_bucket = decrypted_bucket.getValue();
|
||||
uint256 commitment = decrypted_note.cm();
|
||||
pwalletMain->WitnessBucketCommitment(
|
||||
{commitment},
|
||||
witnesses,
|
||||
anchor
|
||||
);
|
||||
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
{
|
||||
ss << decrypted_bucket.getValue();
|
||||
ss << decrypted_bucket.getRho();
|
||||
ss << decrypted_bucket.getR();
|
||||
}
|
||||
ss << npt;
|
||||
|
||||
Object result;
|
||||
result.push_back(Pair("amount", ValueFromAmount(value_of_bucket)));
|
||||
result.push_back(Pair("amount", ValueFromAmount(decrypted_note.value)));
|
||||
result.push_back(Pair("bucket", HexStr(ss.begin(), ss.end())));
|
||||
result.push_back(Pair("exists", found_in_chain));
|
||||
result.push_back(Pair("exists", (bool) witnesses[0]));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Value zc_raw_pour(const json_spirit::Array& params, bool fHelp)
|
||||
{
|
||||
if (!EnsureWalletIsAvailable(fHelp)) {
|
||||
|
@ -2563,30 +2570,20 @@ Value zc_raw_pour(const json_spirit::Array& params, bool fHelp)
|
|||
if (params[4].get_real() != 0.0)
|
||||
vpub_new = AmountFromValue(params[4]);
|
||||
|
||||
std::vector<PourInput> vpourin;
|
||||
std::vector<PourOutput> vpourout;
|
||||
|
||||
uint256 anchor;
|
||||
std::vector<JSInput> vpourin;
|
||||
std::vector<JSOutput> vpourout;
|
||||
std::vector<Note> notes;
|
||||
std::vector<SpendingKey> keys;
|
||||
std::vector<uint256> commitments;
|
||||
|
||||
BOOST_FOREACH(const Pair& s, inputs)
|
||||
{
|
||||
CDataStream ssData(ParseHexV(s.name_, "bucket"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
uint64_t value;
|
||||
std::vector<unsigned char> rho;
|
||||
std::vector<unsigned char> r;
|
||||
|
||||
ssData >> value;
|
||||
ssData >> rho;
|
||||
ssData >> r;
|
||||
|
||||
uint256 a_sk;
|
||||
uint256 sk_enc;
|
||||
SpendingKey k;
|
||||
|
||||
{
|
||||
CDataStream ssData2(ParseHexV(s.value_, "zcsecretkey"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
CDataStream ssData(ParseHexV(s.value_, "zcsecretkey"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
try {
|
||||
ssData2 >> a_sk;
|
||||
ssData2 >> sk_enc;
|
||||
ssData >> k;
|
||||
} catch(const std::exception &) {
|
||||
throw runtime_error(
|
||||
"zcsecretkey could not be decoded"
|
||||
|
@ -2594,51 +2591,58 @@ Value zc_raw_pour(const json_spirit::Array& params, bool fHelp)
|
|||
}
|
||||
}
|
||||
|
||||
libzerocash::PrivateAddress zcsecretkey(a_sk, sk_enc);
|
||||
libzerocash::Address zcaddress(zcsecretkey);
|
||||
libzerocash::Coin input_coin(zcaddress.getPublicAddress(), value, rho, r);
|
||||
keys.push_back(k);
|
||||
|
||||
std::vector<unsigned char> commitment_v = input_coin.getCoinCommitment().getCommitmentValue();
|
||||
uint256 commitment = uint256(commitment_v);
|
||||
NotePlaintext npt;
|
||||
|
||||
libzcash::MerklePath path;
|
||||
assert(pwalletMain != NULL);
|
||||
if (!pwalletMain->WitnessBucketCommitment(commitment, path, anchor)) {
|
||||
throw std::runtime_error("Couldn't find bucket in the blockchain");
|
||||
{
|
||||
CDataStream ssData(ParseHexV(s.name_, "bucket"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
ssData >> npt;
|
||||
}
|
||||
|
||||
vpourin.push_back(PourInput(input_coin, zcaddress, path));
|
||||
PaymentAddress addr = k.address();
|
||||
Note note = npt.note(addr);
|
||||
notes.push_back(note);
|
||||
commitments.push_back(note.cm());
|
||||
}
|
||||
|
||||
uint256 anchor;
|
||||
std::vector<boost::optional<ZCIncrementalWitness>> witnesses;
|
||||
pwalletMain->WitnessBucketCommitment(commitments, witnesses, anchor);
|
||||
|
||||
assert(witnesses.size() == notes.size());
|
||||
assert(notes.size() == keys.size());
|
||||
|
||||
{
|
||||
for (size_t i = 0; i < witnesses.size(); i++) {
|
||||
if (!witnesses[i]) {
|
||||
throw runtime_error(
|
||||
"pour input could not be found in tree"
|
||||
);
|
||||
}
|
||||
|
||||
vpourin.push_back(JSInput(*witnesses[i], notes[i], keys[i]));
|
||||
}
|
||||
}
|
||||
|
||||
while (vpourin.size() < ZC_NUM_JS_INPUTS) {
|
||||
vpourin.push_back(PourInput(INCREMENTAL_MERKLE_TREE_DEPTH));
|
||||
vpourin.push_back(JSInput());
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const Pair& s, outputs)
|
||||
{
|
||||
libzerocash::PublicAddress addrTo;
|
||||
|
||||
PaymentAddress addrTo;
|
||||
{
|
||||
CDataStream ssData(ParseHexV(s.name_, "to_address"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
|
||||
uint256 pubAddressSecret;
|
||||
uint256 encryptionPublicKey;
|
||||
|
||||
ssData >> pubAddressSecret;
|
||||
ssData >> encryptionPublicKey;
|
||||
|
||||
addrTo = libzerocash::PublicAddress(pubAddressSecret, encryptionPublicKey);
|
||||
ssData >> addrTo;
|
||||
}
|
||||
CAmount nAmount = AmountFromValue(s.value_);
|
||||
|
||||
libzerocash::Coin coin(addrTo, nAmount);
|
||||
libzerocash::PourOutput output(coin, addrTo);
|
||||
|
||||
vpourout.push_back(output);
|
||||
vpourout.push_back(JSOutput(addrTo, nAmount));
|
||||
}
|
||||
|
||||
while (vpourout.size() < ZC_NUM_JS_OUTPUTS) {
|
||||
vpourout.push_back(PourOutput(0));
|
||||
vpourout.push_back(JSOutput());
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
@ -2648,7 +2652,7 @@ Value zc_raw_pour(const json_spirit::Array& params, bool fHelp)
|
|||
|
||||
// TODO: #808
|
||||
uint256 pubKeyHash;
|
||||
CPourTx pourtx(*pzerocashParams,
|
||||
CPourTx pourtx(*pzcashParams,
|
||||
pubKeyHash,
|
||||
anchor,
|
||||
{vpourin[0], vpourin[1]},
|
||||
|
@ -2656,7 +2660,7 @@ Value zc_raw_pour(const json_spirit::Array& params, bool fHelp)
|
|||
vpub_old,
|
||||
vpub_new);
|
||||
|
||||
assert(pourtx.Verify(*pzerocashParams, pubKeyHash));
|
||||
assert(pourtx.Verify(*pzcashParams, pubKeyHash));
|
||||
|
||||
CMutableTransaction mtx(tx);
|
||||
mtx.nVersion = 2;
|
||||
|
@ -2674,6 +2678,7 @@ Value zc_raw_pour(const json_spirit::Array& params, bool fHelp)
|
|||
ss2 << ((unsigned char) 0x00);
|
||||
ss2 << pourtx.ephemeralKey;
|
||||
ss2 << pourtx.ciphertexts[0];
|
||||
ss2 << pourtx.h_sig(*pzcashParams, pubKeyHash);
|
||||
|
||||
encryptedBucket1 = HexStr(ss2.begin(), ss2.end());
|
||||
}
|
||||
|
@ -2682,6 +2687,7 @@ Value zc_raw_pour(const json_spirit::Array& params, bool fHelp)
|
|||
ss2 << ((unsigned char) 0x01);
|
||||
ss2 << pourtx.ephemeralKey;
|
||||
ss2 << pourtx.ciphertexts[1];
|
||||
ss2 << pourtx.h_sig(*pzcashParams, pubKeyHash);
|
||||
|
||||
encryptedBucket2 = HexStr(ss2.begin(), ss2.end());
|
||||
}
|
||||
|
@ -2712,22 +2718,25 @@ Value zc_raw_keygen(const json_spirit::Array& params, bool fHelp)
|
|||
);
|
||||
}
|
||||
|
||||
auto zckeypair = libzerocash::Address::CreateNewRandomAddress();
|
||||
auto k = SpendingKey::random();
|
||||
auto addr = k.address();
|
||||
auto viewing_key = k.viewing_key();
|
||||
|
||||
CDataStream pub(SER_NETWORK, PROTOCOL_VERSION);
|
||||
CDataStream priv(SER_NETWORK, PROTOCOL_VERSION);
|
||||
CDataStream viewing(SER_NETWORK, PROTOCOL_VERSION);
|
||||
|
||||
pub << zckeypair.getPublicAddress().getPublicAddressSecret(); // a_pk
|
||||
pub << zckeypair.getPublicAddress().getEncryptionPublicKey(); // pk_enc
|
||||
|
||||
priv << zckeypair.getPrivateAddress().getAddressSecret(); // a_sk
|
||||
priv << zckeypair.getPrivateAddress().getEncryptionSecretKey(); // sk_enc
|
||||
pub << addr;
|
||||
priv << k;
|
||||
viewing << viewing_key;
|
||||
|
||||
std::string pub_hex = HexStr(pub.begin(), pub.end());
|
||||
std::string priv_hex = HexStr(priv.begin(), priv.end());
|
||||
std::string viewing_hex = HexStr(viewing.begin(), viewing.end());
|
||||
|
||||
Object result;
|
||||
result.push_back(Pair("zcaddress", pub_hex));
|
||||
result.push_back(Pair("zcsecretkey", priv_hex));
|
||||
result.push_back(Pair("zcviewingkey", viewing_hex));
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -1051,13 +1051,13 @@ bool CWalletTx::WriteToDisk(CWalletDB *pwalletdb)
|
|||
return pwalletdb->WriteTx(GetHash(), *this);
|
||||
}
|
||||
|
||||
bool CWallet::WitnessBucketCommitment(uint256 &commitment,
|
||||
libzcash::MerklePath &path,
|
||||
void CWallet::WitnessBucketCommitment(std::vector<uint256> commitments,
|
||||
std::vector<boost::optional<ZCIncrementalWitness>>& witnesses,
|
||||
uint256 &final_anchor)
|
||||
{
|
||||
witnesses.resize(commitments.size());
|
||||
CBlockIndex* pindex = chainActive.Genesis();
|
||||
ZCIncrementalMerkleTree tree;
|
||||
boost::optional<ZCIncrementalWitness> witness = boost::none;
|
||||
uint256 current_anchor;
|
||||
|
||||
while (pindex) {
|
||||
|
@ -1070,24 +1070,26 @@ bool CWallet::WitnessBucketCommitment(uint256 &commitment,
|
|||
{
|
||||
BOOST_FOREACH(const uint256 &bucket_commitment, pour.commitments)
|
||||
{
|
||||
if (witness) {
|
||||
witness->append(bucket_commitment);
|
||||
} else {
|
||||
tree.append(bucket_commitment);
|
||||
|
||||
if (bucket_commitment == commitment) {
|
||||
witness = tree.witness();
|
||||
BOOST_FOREACH(boost::optional<ZCIncrementalWitness>& wit, witnesses) {
|
||||
if (wit) {
|
||||
wit->append(bucket_commitment);
|
||||
}
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
BOOST_FOREACH(uint256& commitment, commitments) {
|
||||
if (bucket_commitment == commitment) {
|
||||
witnesses.at(i) = tree.witness();
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (witness) {
|
||||
current_anchor = witness->root();
|
||||
} else {
|
||||
current_anchor = tree.root();
|
||||
}
|
||||
|
||||
// Consistency check: we should be able to find the current tree
|
||||
// in our CCoins view.
|
||||
|
@ -1097,14 +1099,13 @@ bool CWallet::WitnessBucketCommitment(uint256 &commitment,
|
|||
pindex = chainActive.Next(pindex);
|
||||
}
|
||||
|
||||
if (witness) {
|
||||
path = witness->path();
|
||||
final_anchor = current_anchor;
|
||||
|
||||
return true;
|
||||
BOOST_FOREACH(boost::optional<ZCIncrementalWitness>& wit, witnesses) {
|
||||
if (wit) {
|
||||
assert(final_anchor == wit->root());
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -616,7 +616,10 @@ public:
|
|||
void SyncTransaction(const CTransaction& tx, const CBlock* pblock);
|
||||
bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate);
|
||||
void EraseFromWallet(const uint256 &hash);
|
||||
bool WitnessBucketCommitment(uint256 &commitment, libzcash::MerklePath& path, uint256 &final_anchor);
|
||||
void WitnessBucketCommitment(
|
||||
std::vector<uint256> commitments,
|
||||
std::vector<boost::optional<ZCIncrementalWitness>>& witnesses,
|
||||
uint256 &final_anchor);
|
||||
int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);
|
||||
void ReacceptWalletTransactions();
|
||||
void ResendWalletTransactions(int64_t nBestBlockTime);
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
#include "zerocash/IncrementalMerkleTree.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include "zcash/Zcash.h"
|
||||
#include "zerocash/ZerocashParams.h"
|
||||
#include "coins.h"
|
||||
#include "util.h"
|
||||
#include "init.h"
|
||||
|
@ -16,6 +12,11 @@
|
|||
|
||||
#include "zcbenchmarks.h"
|
||||
|
||||
#include "zcash/Zcash.h"
|
||||
#include "zcash/IncrementalMerkleTree.hpp"
|
||||
|
||||
using namespace libzcash;
|
||||
|
||||
struct timeval tv_start;
|
||||
|
||||
void timer_start()
|
||||
|
@ -47,20 +48,18 @@ double benchmark_parameter_loading()
|
|||
boost::filesystem::path vk_path = ZC_GetParamsDir() / "zc-testnet-public-alpha-verification.key";
|
||||
|
||||
timer_start();
|
||||
auto vk_loaded = libzerocash::ZerocashParams::LoadVerificationKeyFromFile(
|
||||
vk_path.string(),
|
||||
INCREMENTAL_MERKLE_TREE_DEPTH
|
||||
);
|
||||
auto pk_loaded = libzerocash::ZerocashParams::LoadProvingKeyFromFile(
|
||||
pk_path.string(),
|
||||
INCREMENTAL_MERKLE_TREE_DEPTH
|
||||
);
|
||||
libzerocash::ZerocashParams zerocashParams = libzerocash::ZerocashParams(
|
||||
INCREMENTAL_MERKLE_TREE_DEPTH,
|
||||
&pk_loaded,
|
||||
&vk_loaded
|
||||
);
|
||||
return timer_stop();
|
||||
|
||||
auto newParams = ZCJoinSplit::Unopened();
|
||||
|
||||
newParams->loadVerifyingKey(vk_path.string());
|
||||
newParams->setProvingKeyPath(pk_path.string());
|
||||
newParams->loadProvingKey();
|
||||
|
||||
double ret = timer_stop();
|
||||
|
||||
delete newParams;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
double benchmark_create_joinsplit()
|
||||
|
@ -68,31 +67,20 @@ double benchmark_create_joinsplit()
|
|||
// TODO: #808
|
||||
uint256 pubKeyHash;
|
||||
|
||||
std::vector<PourInput> vpourin;
|
||||
std::vector<PourOutput> vpourout;
|
||||
|
||||
while (vpourin.size() < ZC_NUM_JS_INPUTS) {
|
||||
vpourin.push_back(PourInput(INCREMENTAL_MERKLE_TREE_DEPTH));
|
||||
}
|
||||
|
||||
while (vpourout.size() < ZC_NUM_JS_OUTPUTS) {
|
||||
vpourout.push_back(PourOutput(0));
|
||||
}
|
||||
|
||||
/* Get the anchor of an empty commitment tree. */
|
||||
uint256 anchor = ZCIncrementalMerkleTree().root();
|
||||
|
||||
timer_start();
|
||||
CPourTx pourtx(*pzerocashParams,
|
||||
CPourTx pourtx(*pzcashParams,
|
||||
pubKeyHash,
|
||||
anchor,
|
||||
{vpourin[0], vpourin[1]},
|
||||
{vpourout[0], vpourout[1]},
|
||||
{JSInput(), JSInput()},
|
||||
{JSOutput(), JSOutput()},
|
||||
0,
|
||||
0);
|
||||
double ret = timer_stop();
|
||||
|
||||
assert(pourtx.Verify(*pzerocashParams, pubKeyHash));
|
||||
assert(pourtx.Verify(*pzcashParams, pubKeyHash));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -101,7 +89,7 @@ double benchmark_verify_joinsplit(const CPourTx &joinsplit)
|
|||
timer_start();
|
||||
// TODO: #808
|
||||
uint256 pubKeyHash;
|
||||
joinsplit.Verify(*pzerocashParams, pubKeyHash);
|
||||
joinsplit.Verify(*pzcashParams, pubKeyHash);
|
||||
return timer_stop();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue