Auto merge of #3251 - ebfull:sprout-groth16, r=ebfull
Sprout on Groth16 Depends on https://github.com/zcash/librustzcash/pull/6
This commit is contained in:
commit
29a75886c2
|
@ -3,8 +3,8 @@ $(package)_version=0.1
|
|||
$(package)_download_path=https://github.com/zcash/$(package)/archive/
|
||||
$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz
|
||||
$(package)_download_file=$($(package)_git_commit).tar.gz
|
||||
$(package)_sha256_hash=65363973dfbdde3bc9cb4427724db399c201f580eb42fb02b0b86e043931c90b
|
||||
$(package)_git_commit=5e220695e5961c8619a1095a3b9022509c6c9b9d
|
||||
$(package)_sha256_hash=e06fafcad8383b1f14bfb0c8e26d3d724e3dd5297e9e51f61deba7661b872bb9
|
||||
$(package)_git_commit=a64c850e6d86e1fb878ef01dc6ab7d170eee3b3a
|
||||
$(package)_dependencies=rust $(rust_crates)
|
||||
$(package)_patches=cargo.config
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "utilstrencodings.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/variant/get.hpp>
|
||||
|
||||
#include "zcash/prf.h"
|
||||
#include "util.h"
|
||||
|
@ -42,7 +43,7 @@ void test_full_api(ZCJoinSplit* js)
|
|||
boost::array<uint256, 2> commitments;
|
||||
uint256 rt = tree.root();
|
||||
boost::array<ZCNoteEncryption::Ciphertext, 2> ciphertexts;
|
||||
ZCProof proof;
|
||||
SproutProof proof;
|
||||
|
||||
{
|
||||
boost::array<JSInput, 2> inputs = {
|
||||
|
@ -59,6 +60,7 @@ void test_full_api(ZCJoinSplit* js)
|
|||
|
||||
// Perform the proof
|
||||
proof = js->prove(
|
||||
false,
|
||||
inputs,
|
||||
outputs,
|
||||
output_notes,
|
||||
|
@ -75,9 +77,11 @@ void test_full_api(ZCJoinSplit* js)
|
|||
);
|
||||
}
|
||||
|
||||
auto sprout_proof = boost::get<ZCProof>(proof);
|
||||
|
||||
// Verify the transaction:
|
||||
ASSERT_TRUE(js->verify(
|
||||
proof,
|
||||
sprout_proof,
|
||||
verifier,
|
||||
pubKeyHash,
|
||||
randomSeed,
|
||||
|
@ -134,6 +138,7 @@ void test_full_api(ZCJoinSplit* js)
|
|||
|
||||
// Perform the proof
|
||||
proof = js->prove(
|
||||
false,
|
||||
inputs,
|
||||
outputs,
|
||||
output_notes,
|
||||
|
@ -150,9 +155,11 @@ void test_full_api(ZCJoinSplit* js)
|
|||
);
|
||||
}
|
||||
|
||||
sprout_proof = boost::get<ZCProof>(proof);
|
||||
|
||||
// Verify the transaction:
|
||||
ASSERT_TRUE(js->verify(
|
||||
proof,
|
||||
sprout_proof,
|
||||
verifier,
|
||||
pubKeyHash,
|
||||
randomSeed,
|
||||
|
@ -185,7 +192,8 @@ void invokeAPI(
|
|||
|
||||
boost::array<SproutNote, 2> output_notes;
|
||||
|
||||
ZCProof proof = js->prove(
|
||||
SproutProof proof = js->prove(
|
||||
false,
|
||||
inputs,
|
||||
outputs,
|
||||
output_notes,
|
||||
|
|
|
@ -43,6 +43,7 @@ TEST(Transaction, JSDescriptionRandomized) {
|
|||
|
||||
{
|
||||
auto jsdesc = JSDescription::Randomized(
|
||||
false,
|
||||
*params, pubKeyHash, rt,
|
||||
inputs, outputs,
|
||||
inputMap, outputMap,
|
||||
|
@ -59,6 +60,7 @@ TEST(Transaction, JSDescriptionRandomized) {
|
|||
|
||||
{
|
||||
auto jsdesc = JSDescription::Randomized(
|
||||
false,
|
||||
*params, pubKeyHash, rt,
|
||||
inputs, outputs,
|
||||
inputMap, outputMap,
|
||||
|
@ -72,6 +74,7 @@ TEST(Transaction, JSDescriptionRandomized) {
|
|||
|
||||
{
|
||||
auto jsdesc = JSDescription::Randomized(
|
||||
false,
|
||||
*params, pubKeyHash, rt,
|
||||
inputs, outputs,
|
||||
inputMap, outputMap,
|
||||
|
|
|
@ -9,7 +9,11 @@
|
|||
#include "tinyformat.h"
|
||||
#include "utilstrencodings.h"
|
||||
|
||||
JSDescription::JSDescription(ZCJoinSplit& params,
|
||||
#include "librustzcash.h"
|
||||
|
||||
JSDescription::JSDescription(
|
||||
bool makeGrothProof,
|
||||
ZCJoinSplit& params,
|
||||
const uint256& pubKeyHash,
|
||||
const uint256& anchor,
|
||||
const boost::array<libzcash::JSInput, ZC_NUM_JS_INPUTS>& inputs,
|
||||
|
@ -23,6 +27,7 @@ JSDescription::JSDescription(ZCJoinSplit& params,
|
|||
boost::array<libzcash::SproutNote, ZC_NUM_JS_OUTPUTS> notes;
|
||||
|
||||
proof = params.prove(
|
||||
makeGrothProof,
|
||||
inputs,
|
||||
outputs,
|
||||
notes,
|
||||
|
@ -42,6 +47,7 @@ JSDescription::JSDescription(ZCJoinSplit& params,
|
|||
}
|
||||
|
||||
JSDescription JSDescription::Randomized(
|
||||
bool makeGrothProof,
|
||||
ZCJoinSplit& params,
|
||||
const uint256& pubKeyHash,
|
||||
const uint256& anchor,
|
||||
|
@ -66,6 +72,7 @@ JSDescription JSDescription::Randomized(
|
|||
MappedShuffle(outputs.begin(), outputMap.begin(), ZC_NUM_JS_OUTPUTS, gen);
|
||||
|
||||
return JSDescription(
|
||||
makeGrothProof,
|
||||
params, pubKeyHash, anchor, inputs, outputs,
|
||||
vpub_old, vpub_new, computeProof,
|
||||
esk // payment disclosure
|
||||
|
@ -105,7 +112,21 @@ public:
|
|||
|
||||
bool operator()(const libzcash::GrothProof& proof) const
|
||||
{
|
||||
return false;
|
||||
uint256 h_sig = params.h_sig(jsdesc.randomSeed, jsdesc.nullifiers, pubKeyHash);
|
||||
|
||||
return librustzcash_sprout_verify(
|
||||
proof.begin(),
|
||||
jsdesc.anchor.begin(),
|
||||
h_sig.begin(),
|
||||
jsdesc.macs[0].begin(),
|
||||
jsdesc.macs[1].begin(),
|
||||
jsdesc.nullifiers[0].begin(),
|
||||
jsdesc.nullifiers[1].begin(),
|
||||
jsdesc.commitments[0].begin(),
|
||||
jsdesc.commitments[1].begin(),
|
||||
jsdesc.vpub_old,
|
||||
jsdesc.vpub_new
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -36,15 +36,6 @@ static_assert(SAPLING_TX_VERSION >= SAPLING_MIN_TX_VERSION,
|
|||
static_assert(SAPLING_TX_VERSION <= SAPLING_MAX_TX_VERSION,
|
||||
"Sapling tx version must not be higher than maximum");
|
||||
|
||||
static constexpr size_t GROTH_PROOF_SIZE = (
|
||||
48 + // π_A
|
||||
96 + // π_B
|
||||
48); // π_C
|
||||
|
||||
namespace libzcash {
|
||||
typedef boost::array<unsigned char, GROTH_PROOF_SIZE> GrothProof;
|
||||
}
|
||||
|
||||
/**
|
||||
* A shielded input to a transaction. It contains data that describes a Spend transfer.
|
||||
*/
|
||||
|
@ -246,11 +237,13 @@ public:
|
|||
|
||||
// JoinSplit proof
|
||||
// This is a zk-SNARK which ensures that this JoinSplit is valid.
|
||||
boost::variant<libzcash::ZCProof, libzcash::GrothProof> proof;
|
||||
libzcash::SproutProof proof;
|
||||
|
||||
JSDescription(): vpub_old(0), vpub_new(0) { }
|
||||
|
||||
JSDescription(ZCJoinSplit& params,
|
||||
JSDescription(
|
||||
bool makeGrothProof,
|
||||
ZCJoinSplit& params,
|
||||
const uint256& pubKeyHash,
|
||||
const uint256& rt,
|
||||
const boost::array<libzcash::JSInput, ZC_NUM_JS_INPUTS>& inputs,
|
||||
|
@ -262,6 +255,7 @@ public:
|
|||
);
|
||||
|
||||
static JSDescription Randomized(
|
||||
bool makeGrothProof,
|
||||
ZCJoinSplit& params,
|
||||
const uint256& pubKeyHash,
|
||||
const uint256& rt,
|
||||
|
|
|
@ -372,7 +372,7 @@ BOOST_AUTO_TEST_CASE(test_basic_joinsplit_verification)
|
|||
auto verifier = libzcash::ProofVerifier::Strict();
|
||||
|
||||
{
|
||||
JSDescription jsdesc(*pzcashParams, pubKeyHash, rt, inputs, outputs, 0, 0);
|
||||
JSDescription jsdesc(false, *pzcashParams, pubKeyHash, rt, inputs, outputs, 0, 0);
|
||||
BOOST_CHECK(jsdesc.Verify(*pzcashParams, verifier, pubKeyHash));
|
||||
|
||||
CDataStream ss(SER_DISK, CLIENT_VERSION);
|
||||
|
@ -387,13 +387,13 @@ BOOST_AUTO_TEST_CASE(test_basic_joinsplit_verification)
|
|||
|
||||
{
|
||||
// Ensure that the balance equation is working.
|
||||
BOOST_CHECK_THROW(JSDescription(*pzcashParams, pubKeyHash, rt, inputs, outputs, 10, 0), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(JSDescription(*pzcashParams, pubKeyHash, rt, inputs, outputs, 0, 10), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(JSDescription(false, *pzcashParams, pubKeyHash, rt, inputs, outputs, 10, 0), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(JSDescription(false, *pzcashParams, pubKeyHash, rt, inputs, outputs, 0, 10), std::invalid_argument);
|
||||
}
|
||||
|
||||
{
|
||||
// Ensure that it won't verify if the root is changed.
|
||||
auto test = JSDescription(*pzcashParams, pubKeyHash, rt, inputs, outputs, 0, 0);
|
||||
auto test = JSDescription(false, *pzcashParams, pubKeyHash, rt, inputs, outputs, 0, 0);
|
||||
test.anchor = GetRandHash();
|
||||
BOOST_CHECK(!test.Verify(*pzcashParams, verifier, pubKeyHash));
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ CWalletTx GetValidReceive(ZCJoinSplit& params,
|
|||
|
||||
// Prepare JoinSplits
|
||||
uint256 rt;
|
||||
JSDescription jsdesc {params, mtx.joinSplitPubKey, rt,
|
||||
JSDescription jsdesc {false, params, mtx.joinSplitPubKey, rt,
|
||||
inputs, outputs, 2*value, 0, false};
|
||||
mtx.vjoinsplit.push_back(jsdesc);
|
||||
|
||||
|
@ -123,7 +123,7 @@ CWalletTx GetValidSpend(ZCJoinSplit& params,
|
|||
|
||||
// Prepare JoinSplits
|
||||
uint256 rt = tree.root();
|
||||
JSDescription jsdesc {params, mtx.joinSplitPubKey, rt,
|
||||
JSDescription jsdesc {false, params, mtx.joinSplitPubKey, rt,
|
||||
inputs, outputs, 0, value, false};
|
||||
mtx.vjoinsplit.push_back(jsdesc);
|
||||
|
||||
|
|
|
@ -768,6 +768,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(
|
|||
uint256 esk; // payment disclosure - secret
|
||||
|
||||
JSDescription jsdesc = JSDescription::Randomized(
|
||||
mtx.fOverwintered && (mtx.nVersion >= SAPLING_TX_VERSION),
|
||||
*pzcashParams,
|
||||
joinSplitPubKey_,
|
||||
anchor,
|
||||
|
|
|
@ -990,6 +990,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(
|
|||
uint256 esk; // payment disclosure - secret
|
||||
|
||||
JSDescription jsdesc = JSDescription::Randomized(
|
||||
mtx.fOverwintered && (mtx.nVersion >= SAPLING_TX_VERSION),
|
||||
*pzcashParams,
|
||||
joinSplitPubKey_,
|
||||
anchor,
|
||||
|
|
|
@ -359,6 +359,7 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf
|
|||
uint256 esk; // payment disclosure - secret
|
||||
|
||||
JSDescription jsdesc = JSDescription::Randomized(
|
||||
mtx.fOverwintered && (mtx.nVersion >= SAPLING_TX_VERSION),
|
||||
*pzcashParams,
|
||||
joinSplitPubKey_,
|
||||
anchor,
|
||||
|
|
|
@ -2640,7 +2640,8 @@ UniValue zc_sample_joinsplit(const UniValue& params, bool fHelp)
|
|||
|
||||
uint256 pubKeyHash;
|
||||
uint256 anchor = ZCIncrementalMerkleTree().root();
|
||||
JSDescription samplejoinsplit(*pzcashParams,
|
||||
JSDescription samplejoinsplit(true,
|
||||
*pzcashParams,
|
||||
pubKeyHash,
|
||||
anchor,
|
||||
{JSInput(), JSInput()},
|
||||
|
@ -2648,7 +2649,7 @@ UniValue zc_sample_joinsplit(const UniValue& params, bool fHelp)
|
|||
0,
|
||||
0);
|
||||
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
CDataStream ss(SER_NETWORK, SAPLING_TX_VERSION | (1 << 31));
|
||||
ss << samplejoinsplit;
|
||||
|
||||
return HexStr(ss.begin(), ss.end());
|
||||
|
@ -2693,7 +2694,7 @@ UniValue zc_benchmark(const UniValue& params, bool fHelp)
|
|||
JSDescription samplejoinsplit;
|
||||
|
||||
if (benchmarktype == "verifyjoinsplit") {
|
||||
CDataStream ss(ParseHexV(params[2].get_str(), "js"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
CDataStream ss(ParseHexV(params[2].get_str(), "js"), SER_NETWORK, SAPLING_TX_VERSION | (1 << 31));
|
||||
ss >> samplejoinsplit;
|
||||
}
|
||||
|
||||
|
@ -2991,7 +2992,8 @@ UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp)
|
|||
mtx.nVersion = 2;
|
||||
mtx.joinSplitPubKey = joinSplitPubKey;
|
||||
|
||||
JSDescription jsdesc(*pzcashParams,
|
||||
JSDescription jsdesc(false,
|
||||
*pzcashParams,
|
||||
joinSplitPubKey,
|
||||
anchor,
|
||||
{vjsin[0], vjsin[1]},
|
||||
|
@ -3667,7 +3669,13 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
|
|||
size_t txsize = 0;
|
||||
for (int i = 0; i < zaddrRecipients.size(); i++) {
|
||||
// TODO Check whether the recipient is a Sprout or Sapling address
|
||||
mtx.vjoinsplit.push_back(JSDescription());
|
||||
JSDescription jsdesc;
|
||||
|
||||
if (mtx.fOverwintered && (mtx.nVersion >= SAPLING_TX_VERSION)) {
|
||||
jsdesc.proof = GrothProof();
|
||||
}
|
||||
|
||||
mtx.vjoinsplit.push_back(jsdesc);
|
||||
}
|
||||
CTransaction tx(mtx);
|
||||
txsize += GetSerializeSize(tx, SER_NETWORK, tx.nVersion);
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
#include "sync.h"
|
||||
#include "amount.h"
|
||||
|
||||
#include "librustzcash.h"
|
||||
#include "streams.h"
|
||||
#include "version.h"
|
||||
|
||||
using namespace libsnark;
|
||||
|
||||
namespace libzcash {
|
||||
|
@ -135,7 +139,8 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
ZCProof prove(
|
||||
SproutProof prove(
|
||||
bool makeGrothProof,
|
||||
const boost::array<JSInput, NumInputs>& inputs,
|
||||
const boost::array<JSOutput, NumOutputs>& outputs,
|
||||
boost::array<SproutNote, NumOutputs>& out_notes,
|
||||
|
@ -266,6 +271,55 @@ public:
|
|||
out_macs[i] = PRF_pk(inputs[i].key, i, h_sig);
|
||||
}
|
||||
|
||||
if (makeGrothProof) {
|
||||
if (!computeProof) {
|
||||
return GrothProof();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (!computeProof) {
|
||||
return ZCProof();
|
||||
}
|
||||
|
|
|
@ -15,6 +15,14 @@
|
|||
|
||||
namespace libzcash {
|
||||
|
||||
static constexpr size_t GROTH_PROOF_SIZE = (
|
||||
48 + // π_A
|
||||
96 + // π_B
|
||||
48); // π_C
|
||||
|
||||
typedef boost::array<unsigned char, GROTH_PROOF_SIZE> GrothProof;
|
||||
typedef boost::variant<ZCProof, GrothProof> SproutProof;
|
||||
|
||||
class JSInput {
|
||||
public:
|
||||
ZCIncrementalWitness witness;
|
||||
|
@ -59,7 +67,8 @@ public:
|
|||
const uint256& pubKeyHash
|
||||
);
|
||||
|
||||
virtual ZCProof prove(
|
||||
virtual SproutProof prove(
|
||||
bool makeGrothProof,
|
||||
const boost::array<JSInput, NumInputs>& inputs,
|
||||
const boost::array<JSOutput, NumOutputs>& outputs,
|
||||
boost::array<SproutNote, NumOutputs>& out_notes,
|
||||
|
|
|
@ -116,7 +116,8 @@ double benchmark_create_joinsplit()
|
|||
|
||||
struct timeval tv_start;
|
||||
timer_start(tv_start);
|
||||
JSDescription jsdesc(*pzcashParams,
|
||||
JSDescription jsdesc(true,
|
||||
*pzcashParams,
|
||||
pubKeyHash,
|
||||
anchor,
|
||||
{JSInput(), JSInput()},
|
||||
|
|
Loading…
Reference in New Issue