Auto merge of #3232 - ebfull:3207-sapling-validation, r=str4d
Sapling validation **Also review https://github.com/zcash/librustzcash/pull/7** This is an attempt to tackle much of https://github.com/zcash/zcash/issues/3065
This commit is contained in:
@@ -3,8 +3,8 @@ $(package)_version=0.1
|
|||||||
$(package)_download_path=https://github.com/zcash/$(package)/archive/
|
$(package)_download_path=https://github.com/zcash/$(package)/archive/
|
||||||
$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz
|
$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz
|
||||||
$(package)_download_file=$($(package)_git_commit).tar.gz
|
$(package)_download_file=$($(package)_git_commit).tar.gz
|
||||||
$(package)_sha256_hash=c5442a57d8961aab12fd395a5004edbb96b973511fab3949a087faa2a865a002
|
$(package)_sha256_hash=65363973dfbdde3bc9cb4427724db399c201f580eb42fb02b0b86e043931c90b
|
||||||
$(package)_git_commit=ef676eff5084d394e6c6eaf2b9d9817effe662a7
|
$(package)_git_commit=5e220695e5961c8619a1095a3b9022509c6c9b9d
|
||||||
$(package)_dependencies=rust $(rust_crates)
|
$(package)_dependencies=rust $(rust_crates)
|
||||||
$(package)_patches=cargo.config
|
$(package)_patches=cargo.config
|
||||||
|
|
||||||
|
|||||||
66
src/main.cpp
66
src/main.cpp
@@ -47,6 +47,8 @@ using namespace std;
|
|||||||
# error "Zcash cannot be compiled without assertions."
|
# error "Zcash cannot be compiled without assertions."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "librustzcash.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Global state
|
* Global state
|
||||||
*/
|
*/
|
||||||
@@ -953,18 +955,25 @@ bool ContextualCheckTransaction(const CTransaction& tx, CValidationState &state,
|
|||||||
REJECT_INVALID, "bad-txns-oversize");
|
REJECT_INVALID, "bad-txns-oversize");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(tx.IsCoinBase() || tx.vjoinsplit.empty())) {
|
uint256 dataToBeSigned;
|
||||||
|
|
||||||
|
if (!tx.vjoinsplit.empty() ||
|
||||||
|
!tx.vShieldedSpend.empty() ||
|
||||||
|
!tx.vShieldedOutput.empty())
|
||||||
|
{
|
||||||
auto consensusBranchId = CurrentEpochBranchId(nHeight, Params().GetConsensus());
|
auto consensusBranchId = CurrentEpochBranchId(nHeight, Params().GetConsensus());
|
||||||
// Empty output script.
|
// Empty output script.
|
||||||
CScript scriptCode;
|
CScript scriptCode;
|
||||||
uint256 dataToBeSigned;
|
|
||||||
try {
|
try {
|
||||||
dataToBeSigned = SignatureHash(scriptCode, tx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);
|
dataToBeSigned = SignatureHash(scriptCode, tx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);
|
||||||
} catch (std::logic_error ex) {
|
} catch (std::logic_error ex) {
|
||||||
return state.DoS(100, error("CheckTransaction(): error computing signature hash"),
|
return state.DoS(100, error("CheckTransaction(): error computing signature hash"),
|
||||||
REJECT_INVALID, "error-computing-signature-hash");
|
REJECT_INVALID, "error-computing-signature-hash");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tx.vjoinsplit.empty())
|
||||||
|
{
|
||||||
BOOST_STATIC_ASSERT(crypto_sign_PUBLICKEYBYTES == 32);
|
BOOST_STATIC_ASSERT(crypto_sign_PUBLICKEYBYTES == 32);
|
||||||
|
|
||||||
// We rely on libsodium to check that the signature is canonical.
|
// We rely on libsodium to check that the signature is canonical.
|
||||||
@@ -977,6 +986,59 @@ bool ContextualCheckTransaction(const CTransaction& tx, CValidationState &state,
|
|||||||
REJECT_INVALID, "bad-txns-invalid-joinsplit-signature");
|
REJECT_INVALID, "bad-txns-invalid-joinsplit-signature");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!tx.vShieldedSpend.empty() ||
|
||||||
|
!tx.vShieldedOutput.empty())
|
||||||
|
{
|
||||||
|
auto ctx = librustzcash_sapling_verification_ctx_init();
|
||||||
|
|
||||||
|
for (const SpendDescription &spend : tx.vShieldedSpend) {
|
||||||
|
if (!librustzcash_sapling_check_spend(
|
||||||
|
ctx,
|
||||||
|
spend.cv.begin(),
|
||||||
|
spend.anchor.begin(),
|
||||||
|
spend.nullifier.begin(),
|
||||||
|
spend.rk.begin(),
|
||||||
|
spend.zkproof.begin(),
|
||||||
|
spend.spendAuthSig.begin(),
|
||||||
|
dataToBeSigned.begin()
|
||||||
|
))
|
||||||
|
{
|
||||||
|
librustzcash_sapling_verification_ctx_free(ctx);
|
||||||
|
return state.DoS(100, error("ContextualCheckTransaction(): Sapling spend description invalid"),
|
||||||
|
REJECT_INVALID, "bad-txns-sapling-spend-description-invalid");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const OutputDescription &output : tx.vShieldedOutput) {
|
||||||
|
if (!librustzcash_sapling_check_output(
|
||||||
|
ctx,
|
||||||
|
output.cv.begin(),
|
||||||
|
output.cm.begin(),
|
||||||
|
output.ephemeralKey.begin(),
|
||||||
|
output.zkproof.begin()
|
||||||
|
))
|
||||||
|
{
|
||||||
|
librustzcash_sapling_verification_ctx_free(ctx);
|
||||||
|
return state.DoS(100, error("ContextualCheckTransaction(): Sapling output description invalid"),
|
||||||
|
REJECT_INVALID, "bad-txns-sapling-output-description-invalid");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!librustzcash_sapling_final_check(
|
||||||
|
ctx,
|
||||||
|
tx.valueBalance,
|
||||||
|
tx.bindingSig.begin(),
|
||||||
|
dataToBeSigned.begin()
|
||||||
|
))
|
||||||
|
{
|
||||||
|
librustzcash_sapling_verification_ctx_free(ctx);
|
||||||
|
return state.DoS(100, error("ContextualCheckTransaction(): Sapling binding signature invalid"),
|
||||||
|
REJECT_INVALID, "bad-txns-sapling-binding-signature-invalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
librustzcash_sapling_verification_ctx_free(ctx);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user