libzcash: Add tests for API
This commit is contained in:
parent
dbab243725
commit
5a2db9e283
|
@ -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
|
||||
|
||||
|
|
|
@ -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…
Reference in New Issue