Remove scriptPubKey/scriptSig from CPourTx, and add randomSeed.

This commit is contained in:
Sean Bowe 2016-05-04 18:26:19 -06:00
parent 5a2db9e283
commit 2140639309
9 changed files with 544 additions and 565 deletions

View File

@ -960,7 +960,10 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
if (state.PerformPourVerification()) { if (state.PerformPourVerification()) {
BOOST_FOREACH(const CPourTx &pour, tx.vpour) { BOOST_FOREACH(const CPourTx &pour, tx.vpour) {
if (!pour.Verify(*pzerocashParams)) { // TODO: #808
uint256 pubKeyHash;
if (!pour.Verify(*pzerocashParams, pubKeyHash)) {
return state.DoS(100, error("CheckTransaction(): pour does not verify"), return state.DoS(100, error("CheckTransaction(): pour does not verify"),
REJECT_INVALID, "bad-txns-pour-verification-failed"); REJECT_INVALID, "bad-txns-pour-verification-failed");
} }

View File

@ -33,22 +33,15 @@ 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 uint256& pubKeyHash,
const uint256& anchor, const uint256& anchor,
const boost::array<PourInput, ZC_NUM_JS_INPUTS>& inputs, const boost::array<PourInput, ZC_NUM_JS_INPUTS>& inputs,
const boost::array<PourOutput, ZC_NUM_JS_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) : vpub_old(vpub_old), vpub_new(vpub_new), anchor(anchor)
{ {
uint256 scriptPubKeyHash;
{
CHashWriter ss(SER_GETHASH, 0);
ss << scriptPubKey;
scriptPubKeyHash = ss.GetHash();
}
PourTransaction pourtx(params, PourTransaction pourtx(params,
std::vector<unsigned char>(scriptPubKeyHash.begin(), scriptPubKeyHash.end()), std::vector<unsigned char>(pubKeyHash.begin(), pubKeyHash.end()),
std::vector<unsigned char>(anchor.begin(), anchor.end()), std::vector<unsigned char>(anchor.begin(), anchor.end()),
std::vector<PourInput>(inputs.begin(), inputs.end()), std::vector<PourInput>(inputs.begin(), inputs.end()),
std::vector<PourOutput>(outputs.begin(), outputs.end()), std::vector<PourOutput>(outputs.begin(), outputs.end()),
@ -65,18 +58,13 @@ CPourTx::CPourTx(ZerocashParams& params,
macs = unsigned_char_vector_array_to_uint256_array(macs_bv); macs = unsigned_char_vector_array_to_uint256_array(macs_bv);
} }
bool CPourTx::Verify(ZerocashParams& params) const { bool CPourTx::Verify(
// Compute the hash of the scriptPubKey. ZerocashParams& params,
uint256 scriptPubKeyHash; const uint256& pubKeyHash
{ ) const {
CHashWriter ss(SER_GETHASH, 0);
ss << scriptPubKey;
scriptPubKeyHash = ss.GetHash();
}
return PourProver::VerifyProof( return PourProver::VerifyProof(
params, params,
std::vector<unsigned char>(scriptPubKeyHash.begin(), scriptPubKeyHash.end()), std::vector<unsigned char>(pubKeyHash.begin(), pubKeyHash.end()),
std::vector<unsigned char>(anchor.begin(), anchor.end()), std::vector<unsigned char>(anchor.begin(), anchor.end()),
vpub_old, vpub_old,
vpub_new, vpub_new,

View File

@ -30,14 +30,6 @@ public:
CAmount vpub_old; CAmount vpub_old;
CAmount vpub_new; CAmount vpub_new;
// These scripts are used to bind a Pour to the outer
// transaction it is placed in. The Pour will
// authenticate the hash of the scriptPubKey, and the
// provided scriptSig with be appended during
// transaction verification.
CScript scriptPubKey;
CScript scriptSig;
// Pours are always anchored to a root in the bucket // Pours are always anchored to a root in the bucket
// commitment tree at some point in the blockchain // commitment tree at some point in the blockchain
// history or in the history of the current // history or in the history of the current
@ -66,6 +58,9 @@ public:
// Ephemeral key // Ephemeral key
uint256 ephemeralKey; uint256 ephemeralKey;
// Random seed
uint256 randomSeed;
// 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.
@ -78,7 +73,7 @@ public:
CPourTx(): vpub_old(0), vpub_new(0) { } CPourTx(): vpub_old(0), vpub_new(0) { }
CPourTx(ZerocashParams& params, CPourTx(ZerocashParams& params,
const CScript& scriptPubKey, const uint256& pubKeyHash,
const uint256& rt, const uint256& rt,
const boost::array<PourInput, ZC_NUM_JS_INPUTS>& inputs, const boost::array<PourInput, ZC_NUM_JS_INPUTS>& inputs,
const boost::array<PourOutput, ZC_NUM_JS_OUTPUTS>& outputs, const boost::array<PourOutput, ZC_NUM_JS_OUTPUTS>& outputs,
@ -87,7 +82,7 @@ public:
); );
// Verifies that the pour proof is correct. // Verifies that the pour proof is correct.
bool Verify(ZerocashParams& params) const; bool Verify(ZerocashParams& params, const uint256& pubKeyHash) const;
ADD_SERIALIZE_METHODS; ADD_SERIALIZE_METHODS;
@ -95,13 +90,12 @@ public:
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(vpub_old); READWRITE(vpub_old);
READWRITE(vpub_new); READWRITE(vpub_new);
READWRITE(scriptPubKey);
READWRITE(scriptSig);
READWRITE(anchor); READWRITE(anchor);
READWRITE(serials); READWRITE(serials);
READWRITE(commitments); READWRITE(commitments);
READWRITE(ciphertexts); READWRITE(ciphertexts);
READWRITE(ephemeralKey); READWRITE(ephemeralKey);
READWRITE(randomSeed);
READWRITE(macs); READWRITE(macs);
READWRITE(proof); READWRITE(proof);
} }
@ -111,13 +105,12 @@ public:
return ( return (
a.vpub_old == b.vpub_old && a.vpub_old == b.vpub_old &&
a.vpub_new == b.vpub_new && a.vpub_new == b.vpub_new &&
a.scriptPubKey == b.scriptPubKey &&
a.scriptSig == b.scriptSig &&
a.anchor == b.anchor && a.anchor == b.anchor &&
a.serials == b.serials && a.serials == b.serials &&
a.commitments == b.commitments && a.commitments == b.commitments &&
a.ciphertexts == b.ciphertexts && a.ciphertexts == b.ciphertexts &&
a.ephemeralKey == b.ephemeralKey && a.ephemeralKey == b.ephemeralKey &&
a.randomSeed == b.randomSeed &&
a.macs == b.macs && a.macs == b.macs &&
a.proof == b.proof a.proof == b.proof
); );

View File

@ -124,19 +124,9 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry)
pour.push_back(Pair("vpub_old", ValueFromAmount(pourtx.vpub_old))); pour.push_back(Pair("vpub_old", ValueFromAmount(pourtx.vpub_old)));
pour.push_back(Pair("vpub_new", ValueFromAmount(pourtx.vpub_new))); pour.push_back(Pair("vpub_new", ValueFromAmount(pourtx.vpub_new)));
{ // TODO: #808
Object o; uint256 pubKeyHash;
ScriptPubKeyToJSON(pourtx.scriptPubKey, o, true); pour.push_back(Pair("valid", pourtx.Verify(*pzerocashParams, pubKeyHash)));
pour.push_back(Pair("scriptPubKey", o));
}
{
Object o;
ScriptPubKeyToJSON(pourtx.scriptSig, o, true);
pour.push_back(Pair("scriptSig", o));
}
pour.push_back(Pair("valid", pourtx.Verify(*pzerocashParams)));
vpour.push_back(pour); vpour.push_back(pour);
} }

File diff suppressed because one or more lines are too long

View File

@ -124,12 +124,12 @@ void static RandomTransaction(CMutableTransaction &tx, bool fSingle) {
} else { } else {
pourtx.vpub_new = insecure_rand() % 100000000; pourtx.vpub_new = insecure_rand() % 100000000;
} }
RandomScript(pourtx.scriptPubKey);
RandomScript(pourtx.scriptSig);
pourtx.anchor = GetRandHash(); pourtx.anchor = GetRandHash();
pourtx.serials[0] = GetRandHash(); pourtx.serials[0] = GetRandHash();
pourtx.serials[1] = GetRandHash(); pourtx.serials[1] = GetRandHash();
pourtx.ephemeralKey = GetRandHash(); pourtx.ephemeralKey = GetRandHash();
pourtx.randomSeed = GetRandHash();
pourtx.ciphertexts[0] = {insecure_rand() % 100, insecure_rand() % 100}; pourtx.ciphertexts[0] = {insecure_rand() % 100, insecure_rand() % 100};
pourtx.ciphertexts[1] = {insecure_rand() % 100, insecure_rand() % 100}; pourtx.ciphertexts[1] = {insecure_rand() % 100, insecure_rand() % 100};
pourtx.macs[0] = GetRandHash(); pourtx.macs[0] = GetRandHash();

View File

@ -335,7 +335,7 @@ BOOST_AUTO_TEST_CASE(test_basic_pour_verification)
auto path = witness.path(); auto path = witness.path();
// create CPourTx // create CPourTx
CScript scriptPubKey; uint256 pubKeyHash;
boost::array<PourInput, ZC_NUM_JS_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
@ -346,8 +346,8 @@ BOOST_AUTO_TEST_CASE(test_basic_pour_verification)
}; };
{ {
CPourTx pourtx(p, scriptPubKey, uint256(rt), inputs, outputs, 0, 0); CPourTx pourtx(p, pubKeyHash, uint256(rt), inputs, outputs, 0, 0);
BOOST_CHECK(pourtx.Verify(p)); BOOST_CHECK(pourtx.Verify(p, pubKeyHash));
CDataStream ss(SER_DISK, CLIENT_VERSION); CDataStream ss(SER_DISK, CLIENT_VERSION);
ss << pourtx; ss << pourtx;
@ -356,20 +356,20 @@ BOOST_AUTO_TEST_CASE(test_basic_pour_verification)
ss >> pourtx_deserialized; ss >> pourtx_deserialized;
BOOST_CHECK(pourtx_deserialized == pourtx); BOOST_CHECK(pourtx_deserialized == pourtx);
BOOST_CHECK(pourtx_deserialized.Verify(p)); BOOST_CHECK(pourtx_deserialized.Verify(p, pubKeyHash));
} }
{ {
// Ensure that the balance equation is working. // Ensure that the balance equation is working.
BOOST_CHECK_THROW(CPourTx(p, scriptPubKey, uint256(rt), inputs, outputs, 10, 0), std::invalid_argument); BOOST_CHECK_THROW(CPourTx(p, pubKeyHash, uint256(rt), inputs, outputs, 10, 0), std::invalid_argument);
BOOST_CHECK_THROW(CPourTx(p, scriptPubKey, uint256(rt), inputs, outputs, 0, 10), std::invalid_argument); BOOST_CHECK_THROW(CPourTx(p, pubKeyHash, uint256(rt), inputs, outputs, 0, 10), std::invalid_argument);
} }
{ {
// Ensure that it won't verify if the root is changed. // Ensure that it won't verify if the root is changed.
auto test = CPourTx(p, scriptPubKey, uint256(rt), inputs, outputs, 0, 0); auto test = CPourTx(p, pubKeyHash, uint256(rt), inputs, outputs, 0, 0);
test.anchor = GetRandHash(); test.anchor = GetRandHash();
BOOST_CHECK(!test.Verify(p)); BOOST_CHECK(!test.Verify(p, pubKeyHash));
} }
} }

View File

@ -2646,16 +2646,17 @@ Value zc_raw_pour(const json_spirit::Array& params, bool fHelp)
throw runtime_error("unsupported pour input/output counts"); throw runtime_error("unsupported pour input/output counts");
} }
CScript scriptPubKey; // TODO: #808
uint256 pubKeyHash;
CPourTx pourtx(*pzerocashParams, CPourTx pourtx(*pzerocashParams,
scriptPubKey, pubKeyHash,
anchor, anchor,
{vpourin[0], vpourin[1]}, {vpourin[0], vpourin[1]},
{vpourout[0], vpourout[1]}, {vpourout[0], vpourout[1]},
vpub_old, vpub_old,
vpub_new); vpub_new);
assert(pourtx.Verify(*pzerocashParams)); assert(pourtx.Verify(*pzerocashParams, pubKeyHash));
CMutableTransaction mtx(tx); CMutableTransaction mtx(tx);
mtx.nVersion = 2; mtx.nVersion = 2;

View File

@ -65,7 +65,8 @@ double benchmark_parameter_loading()
double benchmark_create_joinsplit() double benchmark_create_joinsplit()
{ {
CScript scriptPubKey; // TODO: #808
uint256 pubKeyHash;
std::vector<PourInput> vpourin; std::vector<PourInput> vpourin;
std::vector<PourOutput> vpourout; std::vector<PourOutput> vpourout;
@ -83,21 +84,24 @@ double benchmark_create_joinsplit()
timer_start(); timer_start();
CPourTx pourtx(*pzerocashParams, CPourTx pourtx(*pzerocashParams,
scriptPubKey, pubKeyHash,
anchor, anchor,
{vpourin[0], vpourin[1]}, {vpourin[0], vpourin[1]},
{vpourout[0], vpourout[1]}, {vpourout[0], vpourout[1]},
0, 0,
0); 0);
double ret = timer_stop(); double ret = timer_stop();
assert(pourtx.Verify(*pzerocashParams));
assert(pourtx.Verify(*pzerocashParams, pubKeyHash));
return ret; return ret;
} }
double benchmark_verify_joinsplit(const CPourTx &joinsplit) double benchmark_verify_joinsplit(const CPourTx &joinsplit)
{ {
timer_start(); timer_start();
joinsplit.Verify(*pzerocashParams); // TODO: #808
uint256 pubKeyHash;
joinsplit.Verify(*pzerocashParams, pubKeyHash);
return timer_stop(); return timer_stop();
} }