diff --git a/src/main.cpp b/src/main.cpp index 9491d83a0..bee39267f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -956,13 +956,26 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state) return state.DoS(10, error("CheckTransaction(): prevout is null"), REJECT_INVALID, "bad-txns-prevout-null"); + // TODO: #966. + if (tx.vpour.size() > 0) { + static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001")); + // Empty output script. + CScript scriptCode; + uint256 dataToBeSigned = SignatureHash(scriptCode, tx, NOT_AN_INPUT, SIGHASH_ALL); + if (dataToBeSigned == one) { + return state.DoS(100, error("CheckTransaction(): error computing signature hash"), + REJECT_INVALID, "error-computing-signature-hash"); + } + + // Add the signature + tx.joinSplitPubKey.Verify(dataToBeSigned, tx.joinSplitSig); + } + // Ensure that zk-SNARKs verify if (state.PerformPourVerification()) { BOOST_FOREACH(const CPourTx &pour, tx.vpour) { - // TODO: #808 - uint256 pubKeyHash; - + uint256 pubKeyHash = tx.joinSplitPubKey.GetZcashHash(); if (!pour.Verify(*pzcashParams, pubKeyHash)) { return state.DoS(100, error("CheckTransaction(): pour does not verify"), REJECT_INVALID, "bad-txns-pour-verification-failed"); diff --git a/src/pubkey.h b/src/pubkey.h index bee4dd991..ed0de8d63 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -251,13 +251,12 @@ public: return hash; } - // TODO: implement this to verify the shorter kind of signature - // TODO: make sure to check the s value thing etc. - // TODO: this used to have "const" at the end, what does that mean?? - bool Verify(const uint256& hash, const std::vector& vchSig) + bool Verify(const uint256& hash, const std::vector& vchSig) const { - // TODO implement signature verification. - return false; + // TODO: make sure to check the s < 0xffff.... value thing etc. + // TODO: use compact signatures (maybe just use the secp256k1 API + // instead of these classes). + return pubKey.Verify(hash, vchSig); } }; diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 209642d98..ae3fbd43a 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1083,7 +1083,9 @@ public: // to the transaction. // ::Serialize(s, txTo.vpour, nType, nVersion); - ::Serialize(s, txTo.joinSplitPubKey, nType, nVersion); + if (txTo.vpour.size() > 0) { + ::Serialize(s, txTo.joinSplitPubKey, nType, nVersion); + } } } }; @@ -1093,7 +1095,7 @@ public: uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) { static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001")); - if (nIn >= txTo.vin.size()) { + if (nIn >= txTo.vin.size() && nIn != NOT_AN_INPUT) { // nIn out of range return one; } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 946199a52..2e7d9a0a3 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2682,7 +2682,7 @@ Value zc_raw_pour(const json_spirit::Array& params, bool fHelp) } // Add the signature - joinSplitPrivKey.SignCompact(dataToBeSigned, mtx.joinSplitSig); + joinSplitPrivKey.Sign(dataToBeSigned, mtx.joinSplitSig); CTransaction rawTx(mtx);