Remove crusty old "loadVerifyingKey"/"loadProvingKey" APIs and associated invariants.
This commit is contained in:
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#include "libsnark/common/default_types/r1cs_ppzksnark_pp.hpp"
|
#include "libsnark/common/default_types/r1cs_ppzksnark_pp.hpp"
|
||||||
#include "libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp"
|
#include "libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp"
|
||||||
|
#include "zcash/JoinSplit.hpp"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
struct ECCryptoClosure
|
struct ECCryptoClosure
|
||||||
{
|
{
|
||||||
@@ -12,11 +14,16 @@ struct ECCryptoClosure
|
|||||||
|
|
||||||
ECCryptoClosure instance_of_eccryptoclosure;
|
ECCryptoClosure instance_of_eccryptoclosure;
|
||||||
|
|
||||||
|
ZCJoinSplit* params;
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
assert(init_and_check_sodium() != -1);
|
assert(init_and_check_sodium() != -1);
|
||||||
libsnark::default_r1cs_ppzksnark_pp::init_public_params();
|
libsnark::default_r1cs_ppzksnark_pp::init_public_params();
|
||||||
libsnark::inhibit_profiling_info = true;
|
libsnark::inhibit_profiling_info = true;
|
||||||
libsnark::inhibit_profiling_counters = true;
|
libsnark::inhibit_profiling_counters = true;
|
||||||
|
boost::filesystem::path pk_path = ZC_GetParamsDir() / "sprout-proving.key";
|
||||||
|
boost::filesystem::path vk_path = ZC_GetParamsDir() / "sprout-verifying.key";
|
||||||
|
params = ZCJoinSplit::Prepared(vk_path.string(), pk_path.string());
|
||||||
|
|
||||||
testing::InitGoogleTest(&argc, argv);
|
testing::InitGoogleTest(&argc, argv);
|
||||||
return RUN_ALL_TESTS();
|
return RUN_ALL_TESTS();
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
#include "zcash/prf.h"
|
#include "zcash/prf.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#include "zcash/JoinSplit.hpp"
|
#include "zcash/JoinSplit.hpp"
|
||||||
#include "zcash/Note.hpp"
|
#include "zcash/Note.hpp"
|
||||||
@@ -13,6 +14,8 @@
|
|||||||
|
|
||||||
using namespace libzcash;
|
using namespace libzcash;
|
||||||
|
|
||||||
|
extern ZCJoinSplit* params;
|
||||||
|
|
||||||
void test_full_api(ZCJoinSplit* js)
|
void test_full_api(ZCJoinSplit* js)
|
||||||
{
|
{
|
||||||
// Create verification context.
|
// Create verification context.
|
||||||
@@ -219,8 +222,6 @@ void invokeAPIFailure(
|
|||||||
|
|
||||||
TEST(joinsplit, h_sig)
|
TEST(joinsplit, h_sig)
|
||||||
{
|
{
|
||||||
auto js = ZCJoinSplit::Unopened();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// by Taylor Hornby
|
// by Taylor Hornby
|
||||||
|
|
||||||
@@ -284,7 +285,7 @@ for test_input in TEST_VECTORS:
|
|||||||
};
|
};
|
||||||
|
|
||||||
BOOST_FOREACH(std::vector<std::string>& v, tests) {
|
BOOST_FOREACH(std::vector<std::string>& v, tests) {
|
||||||
auto expected = js->h_sig(
|
auto expected = ZCJoinSplit::h_sig(
|
||||||
uint256S(v[0]),
|
uint256S(v[0]),
|
||||||
{uint256S(v[1]), uint256S(v[2])},
|
{uint256S(v[1]), uint256S(v[2])},
|
||||||
uint256S(v[3])
|
uint256S(v[3])
|
||||||
@@ -292,8 +293,6 @@ for test_input in TEST_VECTORS:
|
|||||||
|
|
||||||
EXPECT_EQ(expected, uint256S(v[4]));
|
EXPECT_EQ(expected, uint256S(v[4]));
|
||||||
}
|
}
|
||||||
|
|
||||||
delete js;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void increment_note_witnesses(
|
void increment_note_witnesses(
|
||||||
@@ -311,8 +310,6 @@ void increment_note_witnesses(
|
|||||||
|
|
||||||
TEST(joinsplit, full_api_test)
|
TEST(joinsplit, full_api_test)
|
||||||
{
|
{
|
||||||
auto js = ZCJoinSplit::Generate();
|
|
||||||
|
|
||||||
{
|
{
|
||||||
std::vector<ZCIncrementalWitness> witnesses;
|
std::vector<ZCIncrementalWitness> witnesses;
|
||||||
ZCIncrementalMerkleTree tree;
|
ZCIncrementalMerkleTree tree;
|
||||||
@@ -331,7 +328,7 @@ TEST(joinsplit, full_api_test)
|
|||||||
increment_note_witnesses(note5.cm(), witnesses, tree);
|
increment_note_witnesses(note5.cm(), witnesses, tree);
|
||||||
|
|
||||||
// Should work
|
// Should work
|
||||||
invokeAPI(js,
|
invokeAPI(params,
|
||||||
{
|
{
|
||||||
JSInput(),
|
JSInput(),
|
||||||
JSInput()
|
JSInput()
|
||||||
@@ -345,7 +342,7 @@ TEST(joinsplit, full_api_test)
|
|||||||
tree.root());
|
tree.root());
|
||||||
|
|
||||||
// lhs > MAX_MONEY
|
// lhs > MAX_MONEY
|
||||||
invokeAPIFailure(js,
|
invokeAPIFailure(params,
|
||||||
{
|
{
|
||||||
JSInput(),
|
JSInput(),
|
||||||
JSInput()
|
JSInput()
|
||||||
@@ -360,7 +357,7 @@ TEST(joinsplit, full_api_test)
|
|||||||
"nonsensical vpub_old value");
|
"nonsensical vpub_old value");
|
||||||
|
|
||||||
// rhs > MAX_MONEY
|
// rhs > MAX_MONEY
|
||||||
invokeAPIFailure(js,
|
invokeAPIFailure(params,
|
||||||
{
|
{
|
||||||
JSInput(),
|
JSInput(),
|
||||||
JSInput()
|
JSInput()
|
||||||
@@ -375,7 +372,7 @@ TEST(joinsplit, full_api_test)
|
|||||||
"nonsensical vpub_new value");
|
"nonsensical vpub_new value");
|
||||||
|
|
||||||
// input witness for the wrong element
|
// input witness for the wrong element
|
||||||
invokeAPIFailure(js,
|
invokeAPIFailure(params,
|
||||||
{
|
{
|
||||||
JSInput(witnesses[0], note1, sk),
|
JSInput(witnesses[0], note1, sk),
|
||||||
JSInput()
|
JSInput()
|
||||||
@@ -391,7 +388,7 @@ TEST(joinsplit, full_api_test)
|
|||||||
|
|
||||||
// input witness doesn't match up with
|
// input witness doesn't match up with
|
||||||
// real root
|
// real root
|
||||||
invokeAPIFailure(js,
|
invokeAPIFailure(params,
|
||||||
{
|
{
|
||||||
JSInput(witnesses[1], note1, sk),
|
JSInput(witnesses[1], note1, sk),
|
||||||
JSInput()
|
JSInput()
|
||||||
@@ -406,7 +403,7 @@ TEST(joinsplit, full_api_test)
|
|||||||
"joinsplit not anchored to the correct root");
|
"joinsplit not anchored to the correct root");
|
||||||
|
|
||||||
// input is in the tree now! this should work
|
// input is in the tree now! this should work
|
||||||
invokeAPI(js,
|
invokeAPI(params,
|
||||||
{
|
{
|
||||||
JSInput(witnesses[1], note1, sk),
|
JSInput(witnesses[1], note1, sk),
|
||||||
JSInput()
|
JSInput()
|
||||||
@@ -420,7 +417,7 @@ TEST(joinsplit, full_api_test)
|
|||||||
tree.root());
|
tree.root());
|
||||||
|
|
||||||
// Wrong secret key
|
// Wrong secret key
|
||||||
invokeAPIFailure(js,
|
invokeAPIFailure(params,
|
||||||
{
|
{
|
||||||
JSInput(witnesses[1], note1, SpendingKey::random()),
|
JSInput(witnesses[1], note1, SpendingKey::random()),
|
||||||
JSInput()
|
JSInput()
|
||||||
@@ -435,7 +432,7 @@ TEST(joinsplit, full_api_test)
|
|||||||
"input note not authorized to spend with given key");
|
"input note not authorized to spend with given key");
|
||||||
|
|
||||||
// Absurd input value
|
// Absurd input value
|
||||||
invokeAPIFailure(js,
|
invokeAPIFailure(params,
|
||||||
{
|
{
|
||||||
JSInput(witnesses[3], note3, sk),
|
JSInput(witnesses[3], note3, sk),
|
||||||
JSInput()
|
JSInput()
|
||||||
@@ -450,7 +447,7 @@ TEST(joinsplit, full_api_test)
|
|||||||
"nonsensical input note value");
|
"nonsensical input note value");
|
||||||
|
|
||||||
// Absurd total input value
|
// Absurd total input value
|
||||||
invokeAPIFailure(js,
|
invokeAPIFailure(params,
|
||||||
{
|
{
|
||||||
JSInput(witnesses[4], note4, sk),
|
JSInput(witnesses[4], note4, sk),
|
||||||
JSInput(witnesses[5], note5, sk)
|
JSInput(witnesses[5], note5, sk)
|
||||||
@@ -465,7 +462,7 @@ TEST(joinsplit, full_api_test)
|
|||||||
"nonsensical left hand size of joinsplit balance");
|
"nonsensical left hand size of joinsplit balance");
|
||||||
|
|
||||||
// Absurd output value
|
// Absurd output value
|
||||||
invokeAPIFailure(js,
|
invokeAPIFailure(params,
|
||||||
{
|
{
|
||||||
JSInput(),
|
JSInput(),
|
||||||
JSInput()
|
JSInput()
|
||||||
@@ -480,7 +477,7 @@ TEST(joinsplit, full_api_test)
|
|||||||
"nonsensical output value");
|
"nonsensical output value");
|
||||||
|
|
||||||
// Absurd total output value
|
// Absurd total output value
|
||||||
invokeAPIFailure(js,
|
invokeAPIFailure(params,
|
||||||
{
|
{
|
||||||
JSInput(),
|
JSInput(),
|
||||||
JSInput()
|
JSInput()
|
||||||
@@ -495,7 +492,7 @@ TEST(joinsplit, full_api_test)
|
|||||||
"nonsensical right hand side of joinsplit balance");
|
"nonsensical right hand side of joinsplit balance");
|
||||||
|
|
||||||
// Absurd total output value
|
// Absurd total output value
|
||||||
invokeAPIFailure(js,
|
invokeAPIFailure(params,
|
||||||
{
|
{
|
||||||
JSInput(),
|
JSInput(),
|
||||||
JSInput()
|
JSInput()
|
||||||
@@ -510,22 +507,7 @@ TEST(joinsplit, full_api_test)
|
|||||||
"invalid joinsplit balance");
|
"invalid joinsplit balance");
|
||||||
}
|
}
|
||||||
|
|
||||||
test_full_api(js);
|
test_full_api(params);
|
||||||
|
|
||||||
js->saveProvingKey("./zcashTest.pk");
|
|
||||||
js->saveVerifyingKey("./zcashTest.vk");
|
|
||||||
|
|
||||||
delete js;
|
|
||||||
|
|
||||||
js = ZCJoinSplit::Unopened();
|
|
||||||
|
|
||||||
js->setProvingKeyPath("./zcashTest.pk");
|
|
||||||
js->loadProvingKey();
|
|
||||||
js->loadVerifyingKey("./zcashTest.vk");
|
|
||||||
|
|
||||||
test_full_api(js);
|
|
||||||
|
|
||||||
delete js;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(joinsplit, note_plaintexts)
|
TEST(joinsplit, note_plaintexts)
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
#include "zcash/JoinSplit.hpp"
|
|
||||||
|
|
||||||
ZCJoinSplit* params = ZCJoinSplit::Unopened();
|
|
||||||
|
|
||||||
int GenZero(int n)
|
int GenZero(int n)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -688,18 +688,14 @@ static void ZC_LoadParams()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pzcashParams = ZCJoinSplit::Unopened();
|
|
||||||
|
|
||||||
LogPrintf("Loading verifying key from %s\n", vk_path.string().c_str());
|
LogPrintf("Loading verifying key from %s\n", vk_path.string().c_str());
|
||||||
gettimeofday(&tv_start, 0);
|
gettimeofday(&tv_start, 0);
|
||||||
|
|
||||||
pzcashParams->loadVerifyingKey(vk_path.string());
|
pzcashParams = ZCJoinSplit::Prepared(vk_path.string(), pk_path.string());
|
||||||
|
|
||||||
gettimeofday(&tv_end, 0);
|
gettimeofday(&tv_end, 0);
|
||||||
elapsed = float(tv_end.tv_sec-tv_start.tv_sec) + (tv_end.tv_usec-tv_start.tv_usec)/float(1000000);
|
elapsed = float(tv_end.tv_sec-tv_start.tv_sec) + (tv_end.tv_usec-tv_start.tv_usec)/float(1000000);
|
||||||
LogPrintf("Loaded verifying key in %fs seconds.\n", elapsed);
|
LogPrintf("Loaded verifying key in %fs seconds.\n", elapsed);
|
||||||
|
|
||||||
pzcashParams->setProvingKeyPath(pk_path.string());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AppInitServers(boost::thread_group& threadGroup)
|
bool AppInitServers(boost::thread_group& threadGroup)
|
||||||
|
|||||||
@@ -20,9 +20,6 @@ JSDescription::JSDescription(ZCJoinSplit& params,
|
|||||||
{
|
{
|
||||||
boost::array<libzcash::Note, ZC_NUM_JS_OUTPUTS> notes;
|
boost::array<libzcash::Note, ZC_NUM_JS_OUTPUTS> notes;
|
||||||
|
|
||||||
if (computeProof) {
|
|
||||||
params.loadProvingKey();
|
|
||||||
}
|
|
||||||
proof = params.prove(
|
proof = params.prove(
|
||||||
inputs,
|
inputs,
|
||||||
outputs,
|
outputs,
|
||||||
|
|||||||
@@ -30,20 +30,30 @@ ZCJoinSplit *pzcashParams;
|
|||||||
extern bool fPrintToConsole;
|
extern bool fPrintToConsole;
|
||||||
extern void noui_connect();
|
extern void noui_connect();
|
||||||
|
|
||||||
|
JoinSplitTestingSetup::JoinSplitTestingSetup()
|
||||||
|
{
|
||||||
|
boost::filesystem::path pk_path = ZC_GetParamsDir() / "sprout-proving.key";
|
||||||
|
boost::filesystem::path vk_path = ZC_GetParamsDir() / "sprout-verifying.key";
|
||||||
|
pzcashParams = ZCJoinSplit::Prepared(vk_path.string(), pk_path.string());
|
||||||
|
}
|
||||||
|
|
||||||
|
JoinSplitTestingSetup::~JoinSplitTestingSetup()
|
||||||
|
{
|
||||||
|
delete pzcashParams;
|
||||||
|
}
|
||||||
|
|
||||||
BasicTestingSetup::BasicTestingSetup()
|
BasicTestingSetup::BasicTestingSetup()
|
||||||
{
|
{
|
||||||
assert(init_and_check_sodium() != -1);
|
assert(init_and_check_sodium() != -1);
|
||||||
ECC_Start();
|
ECC_Start();
|
||||||
pzcashParams = ZCJoinSplit::Unopened();
|
SetupEnvironment();
|
||||||
SetupEnvironment();
|
fPrintToDebugLog = false; // don't want to write to debug.log file
|
||||||
fPrintToDebugLog = false; // don't want to write to debug.log file
|
fCheckBlockIndex = true;
|
||||||
fCheckBlockIndex = true;
|
SelectParams(CBaseChainParams::MAIN);
|
||||||
SelectParams(CBaseChainParams::MAIN);
|
|
||||||
}
|
}
|
||||||
BasicTestingSetup::~BasicTestingSetup()
|
BasicTestingSetup::~BasicTestingSetup()
|
||||||
{
|
{
|
||||||
ECC_Stop();
|
ECC_Stop();
|
||||||
delete pzcashParams;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TestingSetup::TestingSetup()
|
TestingSetup::TestingSetup()
|
||||||
|
|||||||
@@ -30,4 +30,10 @@ struct TestingSetup: public BasicTestingSetup {
|
|||||||
~TestingSetup();
|
~TestingSetup();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Setup w.r.t. zk-SNARK API
|
||||||
|
struct JoinSplitTestingSetup: public BasicTestingSetup {
|
||||||
|
JoinSplitTestingSetup();
|
||||||
|
~JoinSplitTestingSetup();
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "data/tx_valid.json.h"
|
#include "data/tx_valid.json.h"
|
||||||
#include "test/test_bitcoin.h"
|
#include "test/test_bitcoin.h"
|
||||||
|
|
||||||
|
#include "init.h"
|
||||||
#include "clientversion.h"
|
#include "clientversion.h"
|
||||||
#include "consensus/validation.h"
|
#include "consensus/validation.h"
|
||||||
#include "core_io.h"
|
#include "core_io.h"
|
||||||
@@ -85,7 +86,7 @@ string FormatScriptFlags(unsigned int flags)
|
|||||||
return ret.substr(0, ret.size() - 1);
|
return ret.substr(0, ret.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_SUITE(transaction_tests, BasicTestingSetup)
|
BOOST_FIXTURE_TEST_SUITE(transaction_tests, JoinSplitTestingSetup)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(tx_valid)
|
BOOST_AUTO_TEST_CASE(tx_valid)
|
||||||
{
|
{
|
||||||
@@ -326,9 +327,6 @@ BOOST_AUTO_TEST_CASE(test_basic_joinsplit_verification)
|
|||||||
// Also, it's generally libzcash's job to ensure the
|
// Also, it's generally libzcash's job to ensure the
|
||||||
// integrity of the scheme through its own tests.
|
// integrity of the scheme through its own tests.
|
||||||
|
|
||||||
// construct the r1cs keypair
|
|
||||||
auto p = ZCJoinSplit::Generate();
|
|
||||||
|
|
||||||
// construct a merkle tree
|
// construct a merkle tree
|
||||||
ZCIncrementalMerkleTree merkleTree;
|
ZCIncrementalMerkleTree merkleTree;
|
||||||
|
|
||||||
@@ -362,8 +360,8 @@ BOOST_AUTO_TEST_CASE(test_basic_joinsplit_verification)
|
|||||||
auto verifier = libzcash::ProofVerifier::Strict();
|
auto verifier = libzcash::ProofVerifier::Strict();
|
||||||
|
|
||||||
{
|
{
|
||||||
JSDescription jsdesc(*p, pubKeyHash, rt, inputs, outputs, 0, 0);
|
JSDescription jsdesc(*pzcashParams, pubKeyHash, rt, inputs, outputs, 0, 0);
|
||||||
BOOST_CHECK(jsdesc.Verify(*p, verifier, pubKeyHash));
|
BOOST_CHECK(jsdesc.Verify(*pzcashParams, verifier, pubKeyHash));
|
||||||
|
|
||||||
CDataStream ss(SER_DISK, CLIENT_VERSION);
|
CDataStream ss(SER_DISK, CLIENT_VERSION);
|
||||||
ss << jsdesc;
|
ss << jsdesc;
|
||||||
@@ -372,20 +370,20 @@ BOOST_AUTO_TEST_CASE(test_basic_joinsplit_verification)
|
|||||||
ss >> jsdesc_deserialized;
|
ss >> jsdesc_deserialized;
|
||||||
|
|
||||||
BOOST_CHECK(jsdesc_deserialized == jsdesc);
|
BOOST_CHECK(jsdesc_deserialized == jsdesc);
|
||||||
BOOST_CHECK(jsdesc_deserialized.Verify(*p, verifier, pubKeyHash));
|
BOOST_CHECK(jsdesc_deserialized.Verify(*pzcashParams, verifier, pubKeyHash));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Ensure that the balance equation is working.
|
// Ensure that the balance equation is working.
|
||||||
BOOST_CHECK_THROW(JSDescription(*p, pubKeyHash, rt, inputs, outputs, 10, 0), std::invalid_argument);
|
BOOST_CHECK_THROW(JSDescription(*pzcashParams, pubKeyHash, rt, inputs, outputs, 10, 0), std::invalid_argument);
|
||||||
BOOST_CHECK_THROW(JSDescription(*p, pubKeyHash, rt, inputs, outputs, 0, 10), std::invalid_argument);
|
BOOST_CHECK_THROW(JSDescription(*pzcashParams, pubKeyHash, rt, inputs, outputs, 0, 10), std::invalid_argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Ensure that it won't verify if the root is changed.
|
// Ensure that it won't verify if the root is changed.
|
||||||
auto test = JSDescription(*p, pubKeyHash, rt, inputs, outputs, 0, 0);
|
auto test = JSDescription(*pzcashParams, pubKeyHash, rt, inputs, outputs, 0, 0);
|
||||||
test.anchor = GetRandHash();
|
test.anchor = GetRandHash();
|
||||||
BOOST_CHECK(!test.Verify(*p, verifier, pubKeyHash));
|
BOOST_CHECK(!test.Verify(*pzcashParams, verifier, pubKeyHash));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2543,12 +2543,6 @@ UniValue zc_benchmark(const UniValue& params, bool fHelp)
|
|||||||
|
|
||||||
std::vector<double> sample_times;
|
std::vector<double> sample_times;
|
||||||
|
|
||||||
if (benchmarktype == "createjoinsplit") {
|
|
||||||
/* Load the proving now key so that it doesn't happen as part of the
|
|
||||||
* first joinsplit. */
|
|
||||||
pzcashParams->loadProvingKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
JSDescription samplejoinsplit;
|
JSDescription samplejoinsplit;
|
||||||
|
|
||||||
if (benchmarktype == "verifyjoinsplit") {
|
if (benchmarktype == "verifyjoinsplit") {
|
||||||
|
|||||||
@@ -13,10 +13,8 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
libsnark::start_profiling();
|
libsnark::start_profiling();
|
||||||
|
|
||||||
auto p = ZCJoinSplit::Unopened();
|
auto p = ZCJoinSplit::Prepared((ZC_GetParamsDir() / "sprout-verifying.key").string(),
|
||||||
p->loadVerifyingKey((ZC_GetParamsDir() / "sprout-verifying.key").string());
|
(ZC_GetParamsDir() / "sprout-proving.key").string());
|
||||||
p->setProvingKeyPath((ZC_GetParamsDir() / "sprout-proving.key").string());
|
|
||||||
p->loadProvingKey();
|
|
||||||
|
|
||||||
// construct a proof.
|
// construct a proof.
|
||||||
|
|
||||||
@@ -32,4 +30,6 @@ int main(int argc, char **argv)
|
|||||||
0,
|
0,
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete p; // not that it matters
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,7 @@ int main(int argc, char **argv)
|
|||||||
std::string vkFile = argv[2];
|
std::string vkFile = argv[2];
|
||||||
std::string r1csFile = argv[3];
|
std::string r1csFile = argv[3];
|
||||||
|
|
||||||
auto p = ZCJoinSplit::Generate();
|
ZCJoinSplit::Generate(r1csFile, vkFile, pkFile);
|
||||||
|
|
||||||
p->saveProvingKey(pkFile);
|
|
||||||
p->saveVerifyingKey(vkFile);
|
|
||||||
p->saveR1CS(r1csFile);
|
|
||||||
|
|
||||||
delete p;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ CCriticalSection cs_ParamsIO;
|
|||||||
CCriticalSection cs_LoadKeys;
|
CCriticalSection cs_LoadKeys;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void saveToFile(std::string path, T& obj) {
|
void saveToFile(const std::string path, T& obj) {
|
||||||
LOCK(cs_ParamsIO);
|
LOCK(cs_ParamsIO);
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
@@ -42,7 +42,7 @@ void saveToFile(std::string path, T& obj) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void loadFromFile(std::string path, boost::optional<T>& objIn) {
|
void loadFromFile(const std::string path, T& objIn) {
|
||||||
LOCK(cs_ParamsIO);
|
LOCK(cs_ParamsIO);
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
@@ -69,77 +69,33 @@ public:
|
|||||||
typedef default_r1cs_ppzksnark_pp ppzksnark_ppT;
|
typedef default_r1cs_ppzksnark_pp ppzksnark_ppT;
|
||||||
typedef Fr<ppzksnark_ppT> FieldT;
|
typedef Fr<ppzksnark_ppT> FieldT;
|
||||||
|
|
||||||
boost::optional<r1cs_ppzksnark_proving_key<ppzksnark_ppT>> pk;
|
r1cs_ppzksnark_verification_key<ppzksnark_ppT> vk;
|
||||||
boost::optional<r1cs_ppzksnark_verification_key<ppzksnark_ppT>> vk;
|
r1cs_ppzksnark_processed_verification_key<ppzksnark_ppT> vk_precomp;
|
||||||
boost::optional<r1cs_ppzksnark_processed_verification_key<ppzksnark_ppT>> vk_precomp;
|
std::string pkPath;
|
||||||
boost::optional<std::string> pkPath;
|
|
||||||
|
|
||||||
JoinSplitCircuit() {}
|
JoinSplitCircuit(const std::string vkPath, const std::string pkPath) : pkPath(pkPath) {
|
||||||
|
loadFromFile(vkPath, vk);
|
||||||
|
vk_precomp = r1cs_ppzksnark_verifier_process_vk(vk);
|
||||||
|
}
|
||||||
~JoinSplitCircuit() {}
|
~JoinSplitCircuit() {}
|
||||||
|
|
||||||
void setProvingKeyPath(std::string path) {
|
static void generate(const std::string r1csPath,
|
||||||
pkPath = path;
|
const std::string vkPath,
|
||||||
}
|
const std::string pkPath)
|
||||||
|
{
|
||||||
void loadProvingKey() {
|
|
||||||
LOCK(cs_LoadKeys);
|
|
||||||
|
|
||||||
if (!pk) {
|
|
||||||
if (!pkPath) {
|
|
||||||
throw std::runtime_error("proving key path unknown");
|
|
||||||
}
|
|
||||||
loadFromFile(*pkPath, pk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void saveProvingKey(std::string path) {
|
|
||||||
if (pk) {
|
|
||||||
saveToFile(path, *pk);
|
|
||||||
} else {
|
|
||||||
throw std::runtime_error("cannot save proving key; key doesn't exist");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void loadVerifyingKey(std::string path) {
|
|
||||||
LOCK(cs_LoadKeys);
|
|
||||||
|
|
||||||
loadFromFile(path, vk);
|
|
||||||
|
|
||||||
processVerifyingKey();
|
|
||||||
}
|
|
||||||
void processVerifyingKey() {
|
|
||||||
vk_precomp = r1cs_ppzksnark_verifier_process_vk(*vk);
|
|
||||||
}
|
|
||||||
void saveVerifyingKey(std::string path) {
|
|
||||||
if (vk) {
|
|
||||||
saveToFile(path, *vk);
|
|
||||||
} else {
|
|
||||||
throw std::runtime_error("cannot save verifying key; key doesn't exist");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void saveR1CS(std::string path) {
|
|
||||||
auto r1cs = generate_r1cs();
|
|
||||||
|
|
||||||
saveToFile(path, r1cs);
|
|
||||||
}
|
|
||||||
|
|
||||||
r1cs_constraint_system<FieldT> generate_r1cs() {
|
|
||||||
protoboard<FieldT> pb;
|
protoboard<FieldT> pb;
|
||||||
|
|
||||||
joinsplit_gadget<FieldT, NumInputs, NumOutputs> g(pb);
|
joinsplit_gadget<FieldT, NumInputs, NumOutputs> g(pb);
|
||||||
g.generate_r1cs_constraints();
|
g.generate_r1cs_constraints();
|
||||||
|
|
||||||
return pb.get_constraint_system();
|
auto r1cs = pb.get_constraint_system();
|
||||||
}
|
|
||||||
|
|
||||||
void generate() {
|
saveToFile(r1csPath, r1cs);
|
||||||
LOCK(cs_LoadKeys);
|
|
||||||
|
|
||||||
const r1cs_constraint_system<FieldT> constraint_system = generate_r1cs();
|
r1cs_ppzksnark_keypair<ppzksnark_ppT> keypair = r1cs_ppzksnark_generator<ppzksnark_ppT>(r1cs);
|
||||||
r1cs_ppzksnark_keypair<ppzksnark_ppT> keypair = r1cs_ppzksnark_generator<ppzksnark_ppT>(constraint_system);
|
|
||||||
|
|
||||||
pk = keypair.pk;
|
saveToFile(vkPath, keypair.vk);
|
||||||
vk = keypair.vk;
|
saveToFile(pkPath, keypair.pk);
|
||||||
processVerifyingKey();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool verify(
|
bool verify(
|
||||||
@@ -154,10 +110,6 @@ public:
|
|||||||
uint64_t vpub_new,
|
uint64_t vpub_new,
|
||||||
const uint256& rt
|
const uint256& rt
|
||||||
) {
|
) {
|
||||||
if (!vk || !vk_precomp) {
|
|
||||||
throw std::runtime_error("JoinSplit verifying key not loaded");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto r1cs_proof = proof.to_libsnark_proof<r1cs_ppzksnark_proof<ppzksnark_ppT>>();
|
auto r1cs_proof = proof.to_libsnark_proof<r1cs_ppzksnark_proof<ppzksnark_ppT>>();
|
||||||
|
|
||||||
@@ -174,8 +126,8 @@ public:
|
|||||||
);
|
);
|
||||||
|
|
||||||
return verifier.check(
|
return verifier.check(
|
||||||
*vk,
|
vk,
|
||||||
*vk_precomp,
|
vk_precomp,
|
||||||
witness,
|
witness,
|
||||||
r1cs_proof
|
r1cs_proof
|
||||||
);
|
);
|
||||||
@@ -200,10 +152,6 @@ public:
|
|||||||
const uint256& rt,
|
const uint256& rt,
|
||||||
bool computeProof
|
bool computeProof
|
||||||
) {
|
) {
|
||||||
if (computeProof && !pk) {
|
|
||||||
throw std::runtime_error("JoinSplit proving key not loaded");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vpub_old > MAX_MONEY) {
|
if (vpub_old > MAX_MONEY) {
|
||||||
throw std::invalid_argument("nonsensical vpub_old value");
|
throw std::invalid_argument("nonsensical vpub_old value");
|
||||||
}
|
}
|
||||||
@@ -345,8 +293,11 @@ public:
|
|||||||
// estimate that it doesn't matter if we check every time.
|
// estimate that it doesn't matter if we check every time.
|
||||||
pb.constraint_system.swap_AB_if_beneficial();
|
pb.constraint_system.swap_AB_if_beneficial();
|
||||||
|
|
||||||
|
r1cs_ppzksnark_proving_key<ppzksnark_ppT> pk;
|
||||||
|
loadFromFile(pkPath, pk);
|
||||||
|
|
||||||
return ZCProof(r1cs_ppzksnark_prover<ppzksnark_ppT>(
|
return ZCProof(r1cs_ppzksnark_prover<ppzksnark_ppT>(
|
||||||
*pk,
|
pk,
|
||||||
primary_input,
|
primary_input,
|
||||||
aux_input,
|
aux_input,
|
||||||
pb.constraint_system
|
pb.constraint_system
|
||||||
@@ -355,20 +306,20 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<size_t NumInputs, size_t NumOutputs>
|
template<size_t NumInputs, size_t NumOutputs>
|
||||||
JoinSplit<NumInputs, NumOutputs>* JoinSplit<NumInputs, NumOutputs>::Generate()
|
void JoinSplit<NumInputs, NumOutputs>::Generate(const std::string r1csPath,
|
||||||
|
const std::string vkPath,
|
||||||
|
const std::string pkPath)
|
||||||
{
|
{
|
||||||
initialize_curve_params();
|
initialize_curve_params();
|
||||||
auto js = new JoinSplitCircuit<NumInputs, NumOutputs>();
|
JoinSplitCircuit<NumInputs, NumOutputs>::generate(r1csPath, vkPath, pkPath);
|
||||||
js->generate();
|
|
||||||
|
|
||||||
return js;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t NumInputs, size_t NumOutputs>
|
template<size_t NumInputs, size_t NumOutputs>
|
||||||
JoinSplit<NumInputs, NumOutputs>* JoinSplit<NumInputs, NumOutputs>::Unopened()
|
JoinSplit<NumInputs, NumOutputs>* JoinSplit<NumInputs, NumOutputs>::Prepared(const std::string vkPath,
|
||||||
|
const std::string pkPath)
|
||||||
{
|
{
|
||||||
initialize_curve_params();
|
initialize_curve_params();
|
||||||
return new JoinSplitCircuit<NumInputs, NumOutputs>();
|
return new JoinSplitCircuit<NumInputs, NumOutputs>(vkPath, pkPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t NumInputs, size_t NumOutputs>
|
template<size_t NumInputs, size_t NumOutputs>
|
||||||
|
|||||||
@@ -48,22 +48,17 @@ class JoinSplit {
|
|||||||
public:
|
public:
|
||||||
virtual ~JoinSplit() {}
|
virtual ~JoinSplit() {}
|
||||||
|
|
||||||
static JoinSplit<NumInputs, NumOutputs>* Generate();
|
static void Generate(const std::string r1csPath,
|
||||||
static JoinSplit<NumInputs, NumOutputs>* Unopened();
|
const std::string vkPath,
|
||||||
|
const std::string pkPath);
|
||||||
|
static JoinSplit<NumInputs, NumOutputs>* Prepared(const std::string vkPath,
|
||||||
|
const std::string pkPath);
|
||||||
|
|
||||||
static uint256 h_sig(const uint256& randomSeed,
|
static uint256 h_sig(const uint256& randomSeed,
|
||||||
const boost::array<uint256, NumInputs>& nullifiers,
|
const boost::array<uint256, NumInputs>& nullifiers,
|
||||||
const uint256& pubKeyHash
|
const uint256& pubKeyHash
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: #789
|
|
||||||
virtual void setProvingKeyPath(std::string) = 0;
|
|
||||||
virtual void loadProvingKey() = 0;
|
|
||||||
|
|
||||||
virtual void saveProvingKey(std::string path) = 0;
|
|
||||||
virtual void loadVerifyingKey(std::string path) = 0;
|
|
||||||
virtual void saveVerifyingKey(std::string path) = 0;
|
|
||||||
virtual void saveR1CS(std::string path) = 0;
|
|
||||||
|
|
||||||
virtual ZCProof prove(
|
virtual ZCProof prove(
|
||||||
const boost::array<JSInput, NumInputs>& inputs,
|
const boost::array<JSInput, NumInputs>& inputs,
|
||||||
const boost::array<JSOutput, NumOutputs>& outputs,
|
const boost::array<JSOutput, NumOutputs>& outputs,
|
||||||
|
|||||||
@@ -97,11 +97,7 @@ double benchmark_parameter_loading()
|
|||||||
struct timeval tv_start;
|
struct timeval tv_start;
|
||||||
timer_start(tv_start);
|
timer_start(tv_start);
|
||||||
|
|
||||||
auto newParams = ZCJoinSplit::Unopened();
|
auto newParams = ZCJoinSplit::Prepared(vk_path.string(), pk_path.string());
|
||||||
|
|
||||||
newParams->loadVerifyingKey(vk_path.string());
|
|
||||||
newParams->setProvingKeyPath(pk_path.string());
|
|
||||||
newParams->loadProvingKey();
|
|
||||||
|
|
||||||
double ret = timer_stop(tv_start);
|
double ret = timer_stop(tv_start);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user