Browse Source

libzcash: Add tests for API

pull/145/head
Sean Bowe 8 years ago
parent
commit
5a2db9e283
  1. 1
      src/Makefile.gtest.include
  2. 213
      src/gtest/test_joinsplit.cpp

1
src/Makefile.gtest.include

@ -6,6 +6,7 @@ zcash_gtest_SOURCES = \
gtest/main.cpp \
gtest/test_tautology.cpp \
gtest/test_checktransaction.cpp \
gtest/test_joinsplit.cpp \
gtest/test_noteencryption.cpp \
gtest/test_merkletree.cpp

213
src/gtest/test_joinsplit.cpp

@ -0,0 +1,213 @@
#include <gtest/gtest.h>
#include "utilstrencodings.h"
#include "zcash/prf.h"
#include "zcash/JoinSplit.hpp"
#include "zcash/Note.hpp"
#include "zcash/NoteEncryption.hpp"
#include "zcash/IncrementalMerkleTree.hpp"
using namespace libzcash;
void test_full_api(ZCJoinSplit* js)
{
// The recipient's information.
SpendingKey recipient_key = SpendingKey::random();
PaymentAddress recipient_addr = recipient_key.address();
// Create the commitment tree
ZCIncrementalMerkleTree tree;
// Set up a JoinSplit description
uint256 ephemeralKey;
uint256 randomSeed;
uint64_t vpub_old = 10;
uint64_t vpub_new = 0;
uint256 pubKeyHash = random_uint256();
boost::array<uint256, 2> macs;
boost::array<uint256, 2> nullifiers;
boost::array<uint256, 2> commitments;
uint256 rt = tree.root();
boost::array<ZCNoteEncryption::Ciphertext, 2> ciphertexts;
std::string proof;
{
boost::array<JSInput, 2> inputs = {
JSInput(), // dummy input
JSInput() // dummy input
};
boost::array<JSOutput, 2> outputs = {
JSOutput(recipient_addr, 10),
JSOutput() // dummy output
};
boost::array<Note, 2> output_notes;
// Perform the proof
proof = js->prove(
inputs,
outputs,
output_notes,
ciphertexts,
ephemeralKey,
pubKeyHash,
randomSeed,
macs,
nullifiers,
commitments,
vpub_old,
vpub_new,
rt
);
}
// Verify the transaction:
ASSERT_TRUE(js->verify(
proof,
pubKeyHash,
randomSeed,
macs,
nullifiers,
commitments,
vpub_old,
vpub_new,
rt
));
// Recipient should decrypt
// Now the recipient should spend the money again
auto h_sig = js->h_sig(randomSeed, nullifiers, pubKeyHash);
ZCNoteDecryption decryptor(recipient_key.viewing_key());
auto note_pt = NotePlaintext::decrypt(
decryptor,
ciphertexts[0],
ephemeralKey,
h_sig,
0
);
auto decrypted_note = note_pt.note(recipient_addr);
ASSERT_TRUE(decrypted_note.value == 10);
// Insert the commitments from the last tx into the tree
tree.append(commitments[0]);
auto witness_recipient = tree.witness();
tree.append(commitments[1]);
witness_recipient.append(commitments[1]);
vpub_old = 0;
vpub_new = 1;
rt = tree.root();
pubKeyHash = random_uint256();
{
boost::array<JSInput, 2> inputs = {
JSInput(), // dummy input
JSInput(witness_recipient, decrypted_note, recipient_key)
};
SpendingKey second_recipient = SpendingKey::random();
PaymentAddress second_addr = second_recipient.address();
boost::array<JSOutput, 2> outputs = {
JSOutput(second_addr, 9),
JSOutput() // dummy output
};
boost::array<Note, 2> output_notes;
// Perform the proof
proof = js->prove(
inputs,
outputs,
output_notes,
ciphertexts,
ephemeralKey,
pubKeyHash,
randomSeed,
macs,
nullifiers,
commitments,
vpub_old,
vpub_new,
rt
);
}
// Verify the transaction:
ASSERT_TRUE(js->verify(
proof,
pubKeyHash,
randomSeed,
macs,
nullifiers,
commitments,
vpub_old,
vpub_new,
rt
));
}
TEST(joinsplit, full_api_test)
{
auto js = ZCJoinSplit::Generate();
test_full_api(js);
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)
{
uint256 a_sk = uint256S("f6da8716682d600f74fc16bd0187faad6a26b4aa4c24d5c055b216d94516847e");
uint256 a_pk = PRF_addr_a_pk(a_sk);
uint256 sk_enc = ZCNoteEncryption::generate_privkey(a_sk);
uint256 pk_enc = ZCNoteEncryption::generate_pubkey(sk_enc);
PaymentAddress addr_pk(a_pk, pk_enc);
uint256 h_sig;
ZCNoteEncryption encryptor(h_sig);
uint256 epk = encryptor.get_epk();
Note note(a_pk,
1945813,
random_uint256(),
random_uint256()
);
boost::array<unsigned char, ZCASH_MEMO_SIZE> memo;
NotePlaintext note_pt(note, memo);
ZCNoteEncryption::Ciphertext ct = note_pt.encrypt(encryptor, pk_enc);
ZCNoteDecryption decryptor(sk_enc);
auto decrypted = NotePlaintext::decrypt(decryptor, ct, epk, h_sig, 0);
auto decrypted_note = decrypted.note(addr_pk);
ASSERT_TRUE(decrypted_note.a_pk == note.a_pk);
ASSERT_TRUE(decrypted_note.rho == note.rho);
ASSERT_TRUE(decrypted_note.r == note.r);
ASSERT_TRUE(decrypted_note.value == note.value);
ASSERT_TRUE(decrypted.memo == note_pt.memo);
}
Loading…
Cancel
Save