Change ciphertext length to match protocol spec, and refactor the use of constants.

This commit is contained in:
Sean Bowe
2016-05-04 18:25:38 -06:00
parent c9a2eea5e2
commit 5961dcb6da
11 changed files with 60 additions and 44 deletions

View File

@@ -5,6 +5,7 @@
#include "zcash/NoteEncryption.hpp" #include "zcash/NoteEncryption.hpp"
#include "zcash/prf.h" #include "zcash/prf.h"
#include "crypto/sha256.h"
class TestNoteDecryption : public ZCNoteDecryption { class TestNoteDecryption : public ZCNoteDecryption {
public: public:
@@ -28,8 +29,8 @@ TEST(noteencryption, api)
ASSERT_TRUE(b.get_epk() != c.get_epk()); ASSERT_TRUE(b.get_epk() != c.get_epk());
} }
boost::array<unsigned char, 216> message; boost::array<unsigned char, 201> message;
for (unsigned char i = 0; i < 216; i++) { for (unsigned char i = 0; i < 201; i++) {
// Fill the message with dummy data // Fill the message with dummy data
message[i] = (unsigned char) i; message[i] = (unsigned char) i;
} }

View File

@@ -35,8 +35,8 @@ boost::array<uint256, N> unsigned_char_vector_array_to_uint256_array(const boost
CPourTx::CPourTx(ZerocashParams& params, CPourTx::CPourTx(ZerocashParams& params,
const CScript& scriptPubKey, const CScript& scriptPubKey,
const uint256& anchor, const uint256& anchor,
const boost::array<PourInput, NUM_POUR_INPUTS>& inputs, const boost::array<PourInput, ZC_NUM_JS_INPUTS>& inputs,
const boost::array<PourOutput, NUM_POUR_OUTPUTS>& outputs, const boost::array<PourOutput, ZC_NUM_JS_OUTPUTS>& outputs,
CAmount vpub_old, CAmount vpub_old,
CAmount vpub_new) : scriptSig(), scriptPubKey(scriptPubKey), vpub_old(vpub_old), vpub_new(vpub_new), anchor(anchor) CAmount vpub_new) : scriptSig(), scriptPubKey(scriptPubKey), vpub_old(vpub_old), vpub_new(vpub_new), anchor(anchor)
{ {
@@ -55,9 +55,9 @@ CPourTx::CPourTx(ZerocashParams& params,
vpub_old, vpub_old,
vpub_new); vpub_new);
boost::array<std::vector<unsigned char>, NUM_POUR_INPUTS> serials_bv; boost::array<std::vector<unsigned char>, ZC_NUM_JS_INPUTS> serials_bv;
boost::array<std::vector<unsigned char>, NUM_POUR_OUTPUTS> commitments_bv; boost::array<std::vector<unsigned char>, ZC_NUM_JS_OUTPUTS> commitments_bv;
boost::array<std::vector<unsigned char>, NUM_POUR_INPUTS> macs_bv; boost::array<std::vector<unsigned char>, ZC_NUM_JS_INPUTS> macs_bv;
proof = pourtx.unpack(serials_bv, commitments_bv, macs_bv, ciphertexts, ephemeralKey); proof = pourtx.unpack(serials_bv, commitments_bv, macs_bv, ciphertexts, ephemeralKey);
serials = unsigned_char_vector_array_to_uint256_array(serials_bv); serials = unsigned_char_vector_array_to_uint256_array(serials_bv);
@@ -80,9 +80,9 @@ bool CPourTx::Verify(ZerocashParams& params) const {
std::vector<unsigned char>(anchor.begin(), anchor.end()), std::vector<unsigned char>(anchor.begin(), anchor.end()),
vpub_old, vpub_old,
vpub_new, vpub_new,
uint256_to_array<NUM_POUR_INPUTS>(serials), uint256_to_array<ZC_NUM_JS_INPUTS>(serials),
uint256_to_array<NUM_POUR_OUTPUTS>(commitments), uint256_to_array<ZC_NUM_JS_OUTPUTS>(commitments),
uint256_to_array<NUM_POUR_INPUTS>(macs), uint256_to_array<ZC_NUM_JS_INPUTS>(macs),
proof proof
); );
} }

View File

@@ -18,12 +18,10 @@
#include "zerocash/PourOutput.h" #include "zerocash/PourOutput.h"
#include "zcash/NoteEncryption.hpp" #include "zcash/NoteEncryption.hpp"
#include "zcash/Zcash.h"
using namespace libzerocash; using namespace libzerocash;
static const unsigned int NUM_POUR_INPUTS = 2;
static const unsigned int NUM_POUR_OUTPUTS = 2;
class CPourTx class CPourTx
{ {
public: public:
@@ -50,20 +48,20 @@ public:
// are derived from the secrets placed in the bucket // are derived from the secrets placed in the bucket
// and the secret spend-authority key known by the // and the secret spend-authority key known by the
// spender. // spender.
boost::array<uint256, NUM_POUR_INPUTS> serials; boost::array<uint256, ZC_NUM_JS_INPUTS> serials;
// Bucket commitments are introduced into the commitment // Bucket commitments are introduced into the commitment
// tree, blinding the public about the values and // tree, blinding the public about the values and
// destinations involved in the Pour. The presence of a // destinations involved in the Pour. The presence of a
// commitment in the bucket commitment tree is required // commitment in the bucket commitment tree is required
// to spend it. // to spend it.
boost::array<uint256, NUM_POUR_OUTPUTS> commitments; boost::array<uint256, ZC_NUM_JS_OUTPUTS> commitments;
// Ciphertexts // Ciphertexts
// These contain trapdoors, values and other information // These contain trapdoors, values and other information
// that the recipient needs, including a memo field. It // that the recipient needs, including a memo field. It
// is encrypted using the scheme implemented in crypto/NoteEncryption.cpp // is encrypted using the scheme implemented in crypto/NoteEncryption.cpp
boost::array<ZCNoteEncryption::Ciphertext, NUM_POUR_OUTPUTS> ciphertexts; boost::array<ZCNoteEncryption::Ciphertext, ZC_NUM_JS_OUTPUTS> ciphertexts;
// Ephemeral key // Ephemeral key
uint256 ephemeralKey; uint256 ephemeralKey;
@@ -71,7 +69,7 @@ public:
// MACs // MACs
// The verification of the pour requires these MACs // The verification of the pour requires these MACs
// to be provided as an input. // to be provided as an input.
boost::array<uint256, NUM_POUR_INPUTS> macs; boost::array<uint256, ZC_NUM_JS_INPUTS> macs;
// Pour proof // Pour proof
// This is a zk-SNARK which ensures that this pour is valid. // This is a zk-SNARK which ensures that this pour is valid.
@@ -82,8 +80,8 @@ public:
CPourTx(ZerocashParams& params, CPourTx(ZerocashParams& params,
const CScript& scriptPubKey, const CScript& scriptPubKey,
const uint256& rt, const uint256& rt,
const boost::array<PourInput, NUM_POUR_INPUTS>& inputs, const boost::array<PourInput, ZC_NUM_JS_INPUTS>& inputs,
const boost::array<PourOutput, NUM_POUR_OUTPUTS>& outputs, const boost::array<PourOutput, ZC_NUM_JS_OUTPUTS>& outputs,
CAmount vpub_old, CAmount vpub_old,
CAmount vpub_new CAmount vpub_new
); );

View File

@@ -336,11 +336,11 @@ BOOST_AUTO_TEST_CASE(test_basic_pour_verification)
// create CPourTx // create CPourTx
CScript scriptPubKey; CScript scriptPubKey;
boost::array<PourInput, NUM_POUR_INPUTS> inputs = { boost::array<PourInput, ZC_NUM_JS_INPUTS> inputs = {
PourInput(coin, addr, path), PourInput(coin, addr, path),
PourInput(INCREMENTAL_MERKLE_TREE_DEPTH) // dummy input of zero value PourInput(INCREMENTAL_MERKLE_TREE_DEPTH) // dummy input of zero value
}; };
boost::array<PourOutput, NUM_POUR_OUTPUTS> outputs = { boost::array<PourOutput, ZC_NUM_JS_OUTPUTS> outputs = {
PourOutput(50), PourOutput(50),
PourOutput(50) PourOutput(50)
}; };

View File

@@ -2610,7 +2610,7 @@ Value zc_raw_pour(const json_spirit::Array& params, bool fHelp)
vpourin.push_back(PourInput(input_coin, zcaddress, path)); vpourin.push_back(PourInput(input_coin, zcaddress, path));
} }
while (vpourin.size() < NUM_POUR_INPUTS) { while (vpourin.size() < ZC_NUM_JS_INPUTS) {
vpourin.push_back(PourInput(INCREMENTAL_MERKLE_TREE_DEPTH)); vpourin.push_back(PourInput(INCREMENTAL_MERKLE_TREE_DEPTH));
} }
@@ -2637,12 +2637,12 @@ Value zc_raw_pour(const json_spirit::Array& params, bool fHelp)
vpourout.push_back(output); vpourout.push_back(output);
} }
while (vpourout.size() < NUM_POUR_OUTPUTS) { while (vpourout.size() < ZC_NUM_JS_OUTPUTS) {
vpourout.push_back(PourOutput(0)); vpourout.push_back(PourOutput(0));
} }
// TODO // TODO
if (vpourout.size() != NUM_POUR_INPUTS || vpourin.size() != NUM_POUR_OUTPUTS) { if (vpourout.size() != ZC_NUM_JS_INPUTS || vpourin.size() != ZC_NUM_JS_OUTPUTS) {
throw runtime_error("unsupported pour input/output counts"); throw runtime_error("unsupported pour input/output counts");
} }

View File

@@ -8,8 +8,7 @@
#include "uint256.h" #include "uint256.h"
#include "serialize.h" #include "serialize.h"
static const unsigned int INCREMENTAL_MERKLE_TREE_DEPTH = 20; #include "Zcash.h"
static const unsigned int INCREMENTAL_MERKLE_TREE_DEPTH_TESTING = 4;
namespace libzcash { namespace libzcash {

View File

@@ -165,7 +165,7 @@ uint256 random_uint256()
return ret; return ret;
} }
template class NoteEncryption<ZC_V_SIZE + ZC_RHO_SIZE + ZC_R_SIZE + ZC_MEMO_SIZE>; template class NoteEncryption<ZCASH_NOTEPLAINTEXT_LEADING + ZCASH_V_SIZE + ZCASH_RHO_SIZE + ZCASH_R_SIZE + ZCASH_MEMO_SIZE>;
template class NoteDecryption<ZC_V_SIZE + ZC_RHO_SIZE + ZC_R_SIZE + ZC_MEMO_SIZE>; template class NoteDecryption<ZCASH_NOTEPLAINTEXT_LEADING + ZCASH_V_SIZE + ZCASH_RHO_SIZE + ZCASH_R_SIZE + ZCASH_MEMO_SIZE>;
} }

View File

@@ -9,7 +9,7 @@ https://github.com/zcash/zips/blob/master/protocol/protocol.pdf
#include <boost/array.hpp> #include <boost/array.hpp>
#include "uint256.h" #include "uint256.h"
#include "zerocash/Zerocash.h" #include "zcash/Zcash.h"
namespace libzcash { namespace libzcash {
@@ -73,7 +73,7 @@ uint256 random_uint256();
} }
typedef libzcash::NoteEncryption<ZC_V_SIZE + ZC_RHO_SIZE + ZC_R_SIZE + ZC_MEMO_SIZE> ZCNoteEncryption; typedef libzcash::NoteEncryption<ZCASH_NOTEPLAINTEXT_LEADING + ZCASH_V_SIZE + ZCASH_RHO_SIZE + ZCASH_R_SIZE + ZCASH_MEMO_SIZE> ZCNoteEncryption;
typedef libzcash::NoteDecryption<ZC_V_SIZE + ZC_RHO_SIZE + ZC_R_SIZE + ZC_MEMO_SIZE> ZCNoteDecryption; typedef libzcash::NoteDecryption<ZCASH_NOTEPLAINTEXT_LEADING + ZCASH_V_SIZE + ZCASH_RHO_SIZE + ZCASH_R_SIZE + ZCASH_MEMO_SIZE> ZCNoteDecryption;
#endif /* ZC_NOTE_ENCRYPTION_H_ */ #endif /* ZC_NOTE_ENCRYPTION_H_ */

18
src/zcash/Zcash.h Normal file
View File

@@ -0,0 +1,18 @@
#ifndef _ZCCONSTANTS_H_
#define _ZCCONSTANTS_H_
#define ZC_NUM_JS_INPUTS 2
#define ZC_NUM_JS_OUTPUTS 2
#define INCREMENTAL_MERKLE_TREE_DEPTH 20
#define INCREMENTAL_MERKLE_TREE_DEPTH_TESTING 4
// TODO: these constants should be 'ZC'
// for consistency, but I didn't want to
// interfere with the old constants
#define ZCASH_NOTEPLAINTEXT_LEADING 1
#define ZCASH_V_SIZE 8
#define ZCASH_RHO_SIZE 32
#define ZCASH_R_SIZE 32
#define ZCASH_MEMO_SIZE 128
#endif // _ZCCONSTANTS_H_

View File

@@ -2,6 +2,7 @@
#include <unistd.h> #include <unistd.h>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include "zcash/Zcash.h"
#include "zerocash/ZerocashParams.h" #include "zerocash/ZerocashParams.h"
#include "coins.h" #include "coins.h"
#include "util.h" #include "util.h"
@@ -69,19 +70,16 @@ double benchmark_create_joinsplit()
std::vector<PourInput> vpourin; std::vector<PourInput> vpourin;
std::vector<PourOutput> vpourout; std::vector<PourOutput> vpourout;
while (vpourin.size() < NUM_POUR_INPUTS) { while (vpourin.size() < ZC_NUM_JS_INPUTS) {
vpourin.push_back(PourInput(INCREMENTAL_MERKLE_TREE_DEPTH)); vpourin.push_back(PourInput(INCREMENTAL_MERKLE_TREE_DEPTH));
} }
while (vpourout.size() < NUM_POUR_OUTPUTS) { while (vpourout.size() < ZC_NUM_JS_OUTPUTS) {
vpourout.push_back(PourOutput(0)); vpourout.push_back(PourOutput(0));
} }
/* Get the anchor of an empty commitment tree. */ /* Get the anchor of an empty commitment tree. */
IncrementalMerkleTree blank_tree(INCREMENTAL_MERKLE_TREE_DEPTH); uint256 anchor = ZCIncrementalMerkleTree().root();
std::vector<unsigned char> newrt_v(32);
blank_tree.getRootValue(newrt_v);
uint256 anchor = uint256(newrt_v);
timer_start(); timer_start();
CPourTx pourtx(*pzerocashParams, CPourTx pourtx(*pzerocashParams,

View File

@@ -301,10 +301,11 @@ void PourTransaction::init(uint16_t version_num,
std::vector<unsigned char> memo(ZC_MEMO_SIZE, 0x00); std::vector<unsigned char> memo(ZC_MEMO_SIZE, 0x00);
plaintext_internals.insert(plaintext_internals.end(), memo.begin(), memo.end()); plaintext_internals.insert(plaintext_internals.end(), memo.begin(), memo.end());
assert(plaintext_internals.size() == 216); // This is all going away.
assert(plaintext_internals.size() >= 201);
boost::array<unsigned char, 216> pt; boost::array<unsigned char, 201> pt;
memcpy(&pt[0], &plaintext_internals[0], 216); memcpy(&pt[0], &plaintext_internals[0], 201);
this->ciphertext_1 = encryptor.encrypt(addr_1_new.getEncryptionPublicKey(), this->ciphertext_1 = encryptor.encrypt(addr_1_new.getEncryptionPublicKey(),
pt); pt);
@@ -318,10 +319,11 @@ void PourTransaction::init(uint16_t version_num,
std::vector<unsigned char> memo(ZC_MEMO_SIZE, 0x00); std::vector<unsigned char> memo(ZC_MEMO_SIZE, 0x00);
plaintext_internals.insert(plaintext_internals.end(), memo.begin(), memo.end()); plaintext_internals.insert(plaintext_internals.end(), memo.begin(), memo.end());
assert(plaintext_internals.size() == 216); // This is all going away.
assert(plaintext_internals.size() >= 201);
boost::array<unsigned char, 216> pt; boost::array<unsigned char, 201> pt;
memcpy(&pt[0], &plaintext_internals[0], 216); memcpy(&pt[0], &plaintext_internals[0], 201);
this->ciphertext_2 = encryptor.encrypt(addr_2_new.getEncryptionPublicKey(), this->ciphertext_2 = encryptor.encrypt(addr_2_new.getEncryptionPublicKey(),
pt); pt);