Browse Source

Extend Joinsplit tests to Groth

pull/4/head
Ariel Gabizon 6 years ago
parent
commit
589479fd33
  1. 213
      src/gtest/test_joinsplit.cpp

213
src/gtest/test_joinsplit.cpp

@ -10,7 +10,7 @@
#include "streams.h" #include "streams.h"
#include "version.h" #include "version.h"
#include "serialize.h" #include "serialize.h"
#include "primitives/transaction.h"
#include "zcash/JoinSplit.hpp" #include "zcash/JoinSplit.hpp"
#include "zcash/Note.hpp" #include "zcash/Note.hpp"
#include "zcash/NoteEncryption.hpp" #include "zcash/NoteEncryption.hpp"
@ -22,6 +22,40 @@ using namespace libzcash;
extern ZCJoinSplit* params; extern ZCJoinSplit* params;
typedef std::array<JSDescription, 2> SproutProofs;
// Make both the PHGR and Groth proof for a Sprout statement,
// and store the results in JSDescription objects.
SproutProofs makeSproutProofs(
ZCJoinSplit& js,
const std::array<JSInput, 2>& inputs,
const std::array<JSOutput, 2>& outputs,
const uint256& joinSplitPubKey,
uint64_t vpub_old,
uint64_t vpub_new,
const uint256& rt
){
//Making the PHGR proof
JSDescription phgr(false, js, joinSplitPubKey, rt, inputs, outputs, vpub_old, vpub_new);
//Making the Groth proof
JSDescription groth(true, js, joinSplitPubKey, rt, inputs, outputs, vpub_old, vpub_new);
return {phgr, groth};
}
bool verifySproutProofs(
ZCJoinSplit& js,
const SproutProofs& jsdescs,
const uint256& joinSplitPubKey
)
{
auto verifier = libzcash::ProofVerifier::Strict();
bool phgrPassed = jsdescs[0].Verify(js, verifier, joinSplitPubKey);
bool grothPassed = jsdescs[1].Verify(js, verifier, joinSplitPubKey);
return phgrPassed && grothPassed;
}
void test_full_api(ZCJoinSplit* js) void test_full_api(ZCJoinSplit* js)
{ {
// Create verification context. // Create verification context.
@ -35,17 +69,11 @@ void test_full_api(ZCJoinSplit* js)
ZCIncrementalMerkleTree tree; ZCIncrementalMerkleTree tree;
// Set up a JoinSplit description // Set up a JoinSplit description
uint256 ephemeralKey;
uint256 randomSeed;
uint64_t vpub_old = 10; uint64_t vpub_old = 10;
uint64_t vpub_new = 0; uint64_t vpub_new = 0;
uint256 joinSplitPubKey = random_uint256(); uint256 joinSplitPubKey = random_uint256();
std::array<uint256, 2> macs;
std::array<uint256, 2> nullifiers;
std::array<uint256, 2> commitments;
uint256 rt = tree.root(); uint256 rt = tree.root();
std::array<ZCNoteEncryption::Ciphertext, 2> ciphertexts; SproutProofs jsdescs;
SproutProof proof;
{ {
std::array<JSInput, 2> inputs = { std::array<JSInput, 2> inputs = {
@ -60,118 +88,87 @@ void test_full_api(ZCJoinSplit* js)
std::array<SproutNote, 2> output_notes; std::array<SproutNote, 2> output_notes;
// Perform the proof // Perform the proofs
proof = js->prove( jsdescs = makeSproutProofs(
false, *js,
inputs, inputs,
outputs, outputs,
output_notes,
ciphertexts,
ephemeralKey,
joinSplitPubKey, joinSplitPubKey,
randomSeed,
macs,
nullifiers,
commitments,
vpub_old, vpub_old,
vpub_new, vpub_new,
rt rt
); );
} }
auto sprout_proof = boost::get<PHGRProof>(proof); // Verify both PHGR and Groth Proof:
ASSERT_TRUE(verifySproutProofs(*js, jsdescs, joinSplitPubKey));
// Verify the transaction: // Run tests using both phgr and groth as basis for field values
ASSERT_TRUE(js->verify( for (auto jsdesc : jsdescs)
sprout_proof, {
verifier, ZCIncrementalMerkleTree tree;
joinSplitPubKey, SproutProofs jsdescs2;
randomSeed, // Recipient should decrypt
macs, // Now the recipient should spend the money again
nullifiers, auto h_sig = js->h_sig(jsdesc.randomSeed, jsdesc.nullifiers, joinSplitPubKey);
commitments, ZCNoteDecryption decryptor(recipient_key.receiving_key());
vpub_old,
vpub_new, auto note_pt = SproutNotePlaintext::decrypt(
rt decryptor,
)); jsdesc.ciphertexts[0],
jsdesc.ephemeralKey,
h_sig,
0
);
// Recipient should decrypt auto decrypted_note = note_pt.note(recipient_addr);
// Now the recipient should spend the money again
auto h_sig = js->h_sig(randomSeed, nullifiers, joinSplitPubKey);
ZCNoteDecryption decryptor(recipient_key.receiving_key());
auto note_pt = SproutNotePlaintext::decrypt( ASSERT_TRUE(decrypted_note.value() == 10);
decryptor,
ciphertexts[0],
ephemeralKey,
h_sig,
0
);
auto decrypted_note = note_pt.note(recipient_addr); // Insert the commitments from the last tx into the tree
tree.append(jsdesc.commitments[0]);
auto witness_recipient = tree.witness();
tree.append(jsdesc.commitments[1]);
witness_recipient.append(jsdesc.commitments[1]);
vpub_old = 0;
vpub_new = 1;
rt = tree.root();
auto joinSplitPubKey2 = random_uint256();
ASSERT_TRUE(decrypted_note.value() == 10); {
std::array<JSInput, 2> inputs = {
JSInput(), // dummy input
JSInput(witness_recipient, decrypted_note, recipient_key)
};
// Insert the commitments from the last tx into the tree SproutSpendingKey second_recipient = SproutSpendingKey::random();
tree.append(commitments[0]); SproutPaymentAddress second_addr = second_recipient.address();
auto witness_recipient = tree.witness();
tree.append(commitments[1]);
witness_recipient.append(commitments[1]);
vpub_old = 0;
vpub_new = 1;
rt = tree.root();
joinSplitPubKey = random_uint256();
{ std::array<JSOutput, 2> outputs = {
std::array<JSInput, 2> inputs = { JSOutput(second_addr, 9),
JSInput(), // dummy input JSOutput() // dummy output
JSInput(witness_recipient, decrypted_note, recipient_key) };
};
SproutSpendingKey second_recipient = SproutSpendingKey::random(); std::array<SproutNote, 2> output_notes;
SproutPaymentAddress second_addr = second_recipient.address();
std::array<JSOutput, 2> outputs = {
JSOutput(second_addr, 9),
JSOutput() // dummy output
};
std::array<SproutNote, 2> output_notes; // Perform the proofs
jsdescs2 = makeSproutProofs(
*js,
inputs,
outputs,
joinSplitPubKey2,
vpub_old,
vpub_new,
rt
);
// Perform the proof }
proof = js->prove(
false,
inputs,
outputs,
output_notes,
ciphertexts,
ephemeralKey,
joinSplitPubKey,
randomSeed,
macs,
nullifiers,
commitments,
vpub_old,
vpub_new,
rt
);
}
sprout_proof = boost::get<PHGRProof>(proof);
// Verify the transaction: // Verify both PHGR and Groth Proof:
ASSERT_TRUE(js->verify( ASSERT_TRUE(verifySproutProofs(*js, jsdescs2, joinSplitPubKey2));
sprout_proof, }
verifier,
joinSplitPubKey,
randomSeed,
macs,
nullifiers,
commitments,
vpub_old,
vpub_new,
rt
));
} }
// Invokes the API (but does not compute a proof) // Invokes the API (but does not compute a proof)
@ -194,6 +191,7 @@ void invokeAPI(
std::array<SproutNote, 2> output_notes; std::array<SproutNote, 2> output_notes;
// PHGR
SproutProof proof = js->prove( SproutProof proof = js->prove(
false, false,
inputs, inputs,
@ -211,6 +209,25 @@ void invokeAPI(
rt, rt,
false false
); );
// Groth
proof = js->prove(
true,
inputs,
outputs,
output_notes,
ciphertexts,
ephemeralKey,
joinSplitPubKey,
randomSeed,
macs,
nullifiers,
commitments,
vpub_old,
vpub_new,
rt,
false
);
} }
void invokeAPIFailure( void invokeAPIFailure(

Loading…
Cancel
Save