From 2dc3599271edf7b2c22cdfa4532206746d49d169 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Wed, 4 May 2016 18:26:21 -0600 Subject: [PATCH] Transplant of libzcash. --- src/init.cpp | 18 ++-- src/init.h | 4 +- src/main.cpp | 2 +- src/primitives/transaction.cpp | 86 ++++++++---------- src/primitives/transaction.h | 18 ++-- src/rpcrawtransaction.cpp | 2 +- src/test/coins_tests.cpp | 8 +- src/test/test_bitcoin.cpp | 2 +- src/test/transaction_tests.cpp | 52 +++++------ src/wallet/rpcwallet.cpp | 157 +++++++++++++++++---------------- src/wallet/wallet.cpp | 39 ++++---- src/wallet/wallet.h | 5 +- src/zcbenchmarks.cpp | 56 +++++------- 13 files changed, 212 insertions(+), 237 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 2735ee0fd..4edd6b50c 100644 --- a/src/init.cpp +++ b/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. diff --git a/src/init.h b/src/init.h index fcc946265..cfc88255b 100644 --- a/src/init.h +++ b/src/init.h @@ -8,7 +8,7 @@ #include -#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(); diff --git a/src/main.cpp b/src/main.cpp index b8ba5b6e8..9491d83a0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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"); } diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index b6998b1e5..0fe8ad61d 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -9,72 +9,56 @@ #include "tinyformat.h" #include "utilstrencodings.h" -#include "zerocash/PourProver.h" -#include "zerocash/PourTransaction.h" - -template -boost::array, N> uint256_to_array(const boost::array& in) { - boost::array, N> result; - for (size_t i = 0; i < N; i++) { - result[i] = std::vector(in[i].begin(), in[i].end()); - } - - return result; -} - -template -boost::array unsigned_char_vector_array_to_uint256_array(const boost::array, N>& in) { - boost::array 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& inputs, - const boost::array& outputs, + const boost::array& inputs, + const boost::array& outputs, CAmount vpub_old, CAmount vpub_new) : vpub_old(vpub_old), vpub_new(vpub_new), anchor(anchor) { - PourTransaction pourtx(params, - std::vector(pubKeyHash.begin(), pubKeyHash.end()), - std::vector(anchor.begin(), anchor.end()), - std::vector(inputs.begin(), inputs.end()), - std::vector(outputs.begin(), outputs.end()), - vpub_old, - vpub_new); - - boost::array, ZC_NUM_JS_INPUTS> serials_bv; - boost::array, ZC_NUM_JS_OUTPUTS> commitments_bv; - boost::array, 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); + boost::array notes; + + params.loadProvingKey(); + proof = params.prove( + inputs, + outputs, + notes, + ciphertexts, + ephemeralKey, + pubKeyHash, + randomSeed, + macs, + serials, + commitments, + vpub_old, + vpub_new, + anchor + ); } bool CPourTx::Verify( - ZerocashParams& params, + ZCJoinSplit& params, const uint256& pubKeyHash ) const { - return PourProver::VerifyProof( - params, - std::vector(pubKeyHash.begin(), pubKeyHash.end()), - std::vector(anchor.begin(), anchor.end()), + return params.verify( + proof, + pubKeyHash, + randomSeed, + macs, + serials, + commitments, vpub_old, vpub_new, - uint256_to_array(serials), - uint256_to_array(commitments), - uint256_to_array(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); diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index f90a2760e..79dbe8336 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -13,14 +13,9 @@ #include -#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& inputs, - const boost::array& outputs, + const boost::array& inputs, + const boost::array& 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; diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 844031acd..d2f3b94fa 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -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); } diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index a599843f0..7ab975b94 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -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) diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 5b5944cd3..eb5ba6b92 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -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(); diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 57bc1ac15..f39f85ff4 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -25,15 +25,11 @@ #include #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 inputs = { - PourInput(coin, addr, path), - PourInput(INCREMENTAL_MERKLE_TREE_DEPTH) // dummy input of zero value + boost::array inputs = { + libzcash::JSInput(witness, note, k), + libzcash::JSInput() // dummy input of zero value }; - boost::array outputs = { - PourOutput(50), - PourOutput(50) + boost::array 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) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index b74367846..898677680 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -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 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> 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 vpourin; - std::vector vpourout; - - uint256 anchor; + std::vector vpourin; + std::vector vpourout; + std::vector notes; + std::vector keys; + std::vector commitments; BOOST_FOREACH(const Pair& s, inputs) { - CDataStream ssData(ParseHexV(s.name_, "bucket"), SER_NETWORK, PROTOCOL_VERSION); - uint64_t value; - std::vector rho; - std::vector 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 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> 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; } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index fbdbb25a8..7698d329f 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -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 commitments, + std::vector>& witnesses, uint256 &final_anchor) { + witnesses.resize(commitments.size()); CBlockIndex* pindex = chainActive.Genesis(); ZCIncrementalMerkleTree tree; - boost::optional 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); + tree.append(bucket_commitment); + BOOST_FOREACH(boost::optional& wit, witnesses) { + if (wit) { + wit->append(bucket_commitment); + } + } + + size_t i = 0; + BOOST_FOREACH(uint256& commitment, commitments) { if (bucket_commitment == commitment) { - witness = tree.witness(); + witnesses.at(i) = tree.witness(); } + i++; } } } } - if (witness) { - current_anchor = witness->root(); - } else { - current_anchor = tree.root(); - } + 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; + final_anchor = current_anchor; - return true; + BOOST_FOREACH(boost::optional& wit, witnesses) { + if (wit) { + assert(final_anchor == wit->root()); + } } - - return false; } /** diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 3d908ea25..e0fb8de92 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -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 commitments, + std::vector>& witnesses, + uint256 &final_anchor); int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false); void ReacceptWalletTransactions(); void ResendWalletTransactions(int64_t nBestBlockTime); diff --git a/src/zcbenchmarks.cpp b/src/zcbenchmarks.cpp index b66c21f1f..aed0612e1 100644 --- a/src/zcbenchmarks.cpp +++ b/src/zcbenchmarks.cpp @@ -1,9 +1,5 @@ -#include "zerocash/IncrementalMerkleTree.h" - #include #include -#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 vpourin; - std::vector 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(); }