]> Git Repo - VerusCoin.git/commitdiff
libzcash: Add tests for API
authorSean Bowe <[email protected]>
Thu, 5 May 2016 00:26:16 +0000 (18:26 -0600)
committerSean Bowe <[email protected]>
Thu, 12 May 2016 22:44:30 +0000 (16:44 -0600)
src/Makefile.gtest.include
src/gtest/test_joinsplit.cpp [new file with mode: 0644]

index dd255a707e04b1f639dc572d3959a037758ffa76..2bd7806088db57a46073f6068d35a095495f664f 100644 (file)
@@ -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
 
diff --git a/src/gtest/test_joinsplit.cpp b/src/gtest/test_joinsplit.cpp
new file mode 100644 (file)
index 0000000..bc41a38
--- /dev/null
@@ -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);
+}
This page took 0.031309 seconds and 4 git commands to generate.