From 438369d27151f2b05dd40a972c3b991a09118500 Mon Sep 17 00:00:00 2001 From: Conrado Gouvea Date: Wed, 6 Mar 2024 17:47:54 -0300 Subject: [PATCH 01/16] created zcash_script_verify_prehashed; compiles --- depend/zcash/src/script/interpreter.cpp | 638 +++++++++++++---------- depend/zcash/src/script/interpreter.h | 56 +- depend/zcash/src/script/zcash_script.cpp | 73 ++- depend/zcash/src/script/zcash_script.h | 15 + 4 files changed, 454 insertions(+), 328 deletions(-) diff --git a/depend/zcash/src/script/interpreter.cpp b/depend/zcash/src/script/interpreter.cpp index b97249f8b..d5fb71d45 100644 --- a/depend/zcash/src/script/interpreter.cpp +++ b/depend/zcash/src/script/interpreter.cpp @@ -7,10 +7,10 @@ #include "interpreter.h" #include "consensus/upgrades.h" -#include "primitives/transaction.h" #include "crypto/ripemd160.h" #include "crypto/sha1.h" #include "crypto/sha256.h" +#include "primitives/transaction.h" #include "pubkey.h" #include "script/script.h" #include "uint256.h" @@ -23,7 +23,8 @@ using namespace std; typedef vector valtype; -namespace { +namespace +{ inline bool set_success(ScriptError* ret) { @@ -39,16 +40,14 @@ inline bool set_error(ScriptError* ret, const ScriptError serror) return false; } -} // anon namespace +} // namespace bool CastToBool(const valtype& vch) { - for (unsigned int i = 0; i < vch.size(); i++) - { - if (vch[i] != 0) - { + for (unsigned int i = 0; i < vch.size(); i++) { + if (vch[i] != 0) { // Can be negative zero - if (i == vch.size()-1 && vch[i] == 0x80) + if (i == vch.size() - 1 && vch[i] == 0x80) return false; return true; } @@ -60,8 +59,8 @@ bool CastToBool(const valtype& vch) * Script is a stack machine (like Forth) that evaluates a predicate * returning a bool indicating valid or not. There are no loops. */ -#define stacktop(i) (stack.at(stack.size()+(i))) -#define altstacktop(i) (altstack.at(altstack.size()+(i))) +#define stacktop(i) (stack.at(stack.size() + (i))) +#define altstacktop(i) (altstack.at(altstack.size() + (i))) static inline void popstack(vector& stack) { if (stack.empty()) @@ -69,7 +68,8 @@ static inline void popstack(vector& stack) stack.pop_back(); } -bool static IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) { +bool static IsCompressedOrUncompressedPubKey(const valtype& vchPubKey) +{ if (vchPubKey.size() < CPubKey::COMPRESSED_PUBLIC_KEY_SIZE) { // Non-canonical public key: too short return false; @@ -85,8 +85,8 @@ bool static IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) { return false; } } else { - // Non-canonical public key: neither compressed nor uncompressed - return false; + // Non-canonical public key: neither compressed nor uncompressed + return false; } return true; } @@ -101,7 +101,8 @@ bool static IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) { * * This function is consensus-critical since BIP66. */ -bool static IsValidSignatureEncoding(const std::vector &sig) { +bool static IsValidSignatureEncoding(const std::vector& sig) +{ // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] [sighash] // * total-length: 1-byte length descriptor of everything that follows, // excluding the sighash byte. @@ -115,58 +116,73 @@ bool static IsValidSignatureEncoding(const std::vector &sig) { // signature) // Minimum and maximum size constraints. - if (sig.size() < 9) return false; - if (sig.size() > 73) return false; + if (sig.size() < 9) + return false; + if (sig.size() > 73) + return false; // A signature is of type 0x30 (compound). - if (sig[0] != 0x30) return false; + if (sig[0] != 0x30) + return false; // Make sure the length covers the entire signature. - if (sig[1] != sig.size() - 3) return false; + if (sig[1] != sig.size() - 3) + return false; // Extract the length of the R element. unsigned int lenR = sig[3]; // Make sure the length of the S element is still inside the signature. - if (5 + lenR >= sig.size()) return false; + if (5 + lenR >= sig.size()) + return false; // Extract the length of the S element. unsigned int lenS = sig[5 + lenR]; // Verify that the length of the signature matches the sum of the length // of the elements. - if ((size_t)(lenR + lenS + 7) != sig.size()) return false; + if ((size_t)(lenR + lenS + 7) != sig.size()) + return false; // Check whether the R element is an integer. - if (sig[2] != 0x02) return false; + if (sig[2] != 0x02) + return false; // Zero-length integers are not allowed for R. - if (lenR == 0) return false; + if (lenR == 0) + return false; // Negative numbers are not allowed for R. - if (sig[4] & 0x80) return false; + if (sig[4] & 0x80) + return false; // Null bytes at the start of R are not allowed, unless R would // otherwise be interpreted as a negative number. - if (lenR > 1 && (sig[4] == 0x00) && !(sig[5] & 0x80)) return false; + if (lenR > 1 && (sig[4] == 0x00) && !(sig[5] & 0x80)) + return false; // Check whether the S element is an integer. - if (sig[lenR + 4] != 0x02) return false; + if (sig[lenR + 4] != 0x02) + return false; // Zero-length integers are not allowed for S. - if (lenS == 0) return false; + if (lenS == 0) + return false; // Negative numbers are not allowed for S. - if (sig[lenR + 6] & 0x80) return false; + if (sig[lenR + 6] & 0x80) + return false; // Null bytes at the start of S are not allowed, unless S would otherwise be // interpreted as a negative number. - if (lenS > 1 && (sig[lenR + 6] == 0x00) && !(sig[lenR + 7] & 0x80)) return false; + if (lenS > 1 && (sig[lenR + 6] == 0x00) && !(sig[lenR + 7] & 0x80)) + return false; return true; } -bool static IsLowDERSignature(const valtype &vchSig, ScriptError* serror) { +bool static IsLowDERSignature(const valtype& vchSig, ScriptError* serror) +{ if (!IsValidSignatureEncoding(vchSig)) { return set_error(serror, SCRIPT_ERR_SIG_DER); } @@ -180,7 +196,8 @@ bool static IsLowDERSignature(const valtype &vchSig, ScriptError* serror) { return CPubKey::CheckLowS(vchSigCopy); } -bool static IsDefinedHashtypeSignature(const valtype &vchSig) { +bool static IsDefinedHashtypeSignature(const valtype& vchSig) +{ if (vchSig.size() == 0) { return false; } @@ -191,7 +208,8 @@ bool static IsDefinedHashtypeSignature(const valtype &vchSig) { return true; } -bool CheckSignatureEncoding(const vector &vchSig, unsigned int flags, ScriptError* serror) { +bool CheckSignatureEncoding(const vector& vchSig, unsigned int flags, ScriptError* serror) +{ // Empty signature. Not strictly DER encoded, but allowed to provide a // compact way to provide an invalid signature for use with CHECK(MULTI)SIG if (vchSig.size() == 0) { @@ -208,14 +226,16 @@ bool CheckSignatureEncoding(const vector &vchSig, unsigned int fl return true; } -bool static CheckPubKeyEncoding(const valtype &vchSig, unsigned int flags, ScriptError* serror) { +bool static CheckPubKeyEncoding(const valtype& vchSig, unsigned int flags, ScriptError* serror) +{ if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsCompressedOrUncompressedPubKey(vchSig)) { return set_error(serror, SCRIPT_ERR_PUBKEYTYPE); } return true; } -bool static CheckMinimalPush(const valtype& data, opcodetype opcode) { +bool static CheckMinimalPush(const valtype& data, opcodetype opcode) +{ if (data.size() == 0) { // Could have used OP_0. return opcode == OP_0; @@ -239,7 +259,7 @@ bool static CheckMinimalPush(const valtype& data, opcodetype opcode) { } bool EvalScript( - vector >& stack, + vector>& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, @@ -266,10 +286,8 @@ bool EvalScript( int nOpCount = 0; bool fRequireMinimal = (flags & SCRIPT_VERIFY_MINIMALDATA) != 0; - try - { - while (pc < pend) - { + try { + while (pc < pend) { bool fExec = !count(vfExec.begin(), vfExec.end(), false); // @@ -308,8 +326,7 @@ bool EvalScript( } stack.push_back(vchPushValue); } else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF)) - switch (opcode) - { + switch (opcode) { // // Push value // @@ -329,15 +346,13 @@ bool EvalScript( case OP_13: case OP_14: case OP_15: - case OP_16: - { + case OP_16: { // ( -- value) CScriptNum bn((int)opcode - (int)(OP_1 - 1)); stack.push_back(bn.getvch()); // The result of these opcodes should always be the minimal way to push the data // they push, so no need for a CheckMinimalPush here. - } - break; + } break; // @@ -346,8 +361,7 @@ bool EvalScript( case OP_NOP: break; - case OP_CHECKLOCKTIMEVERIFY: - { + case OP_CHECKLOCKTIMEVERIFY: { if (!(flags & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)) { // not enabled; treat as a NOP2 if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) { @@ -388,21 +402,24 @@ bool EvalScript( break; } - case OP_NOP1: case OP_NOP3: case OP_NOP4: case OP_NOP5: - case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10: - { + case OP_NOP1: + case OP_NOP3: + case OP_NOP4: + case OP_NOP5: + case OP_NOP6: + case OP_NOP7: + case OP_NOP8: + case OP_NOP9: + case OP_NOP10: { if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS); - } - break; + } break; case OP_IF: - case OP_NOTIF: - { + case OP_NOTIF: { // if [statements] [else [statements]] endif bool fValue = false; - if (fExec) - { + if (fExec) { if (stack.size() < 1) return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); valtype& vch = stacktop(-1); @@ -412,27 +429,21 @@ bool EvalScript( popstack(stack); } vfExec.push_back(fValue); - } - break; + } break; - case OP_ELSE: - { + case OP_ELSE: { if (vfExec.empty()) return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); vfExec.back() = !vfExec.back(); - } - break; + } break; - case OP_ENDIF: - { + case OP_ENDIF: { if (vfExec.empty()) return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); vfExec.pop_back(); - } - break; + } break; - case OP_VERIFY: - { + case OP_VERIFY: { // (true -- ) or // (false -- false) and return if (stack.size() < 1) @@ -442,49 +453,39 @@ bool EvalScript( popstack(stack); else return set_error(serror, SCRIPT_ERR_VERIFY); - } - break; + } break; - case OP_RETURN: - { + case OP_RETURN: { return set_error(serror, SCRIPT_ERR_OP_RETURN); - } - break; + } break; // // Stack ops // - case OP_TOALTSTACK: - { + case OP_TOALTSTACK: { if (stack.size() < 1) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); altstack.push_back(stacktop(-1)); popstack(stack); - } - break; + } break; - case OP_FROMALTSTACK: - { + case OP_FROMALTSTACK: { if (altstack.size() < 1) return set_error(serror, SCRIPT_ERR_INVALID_ALTSTACK_OPERATION); stack.push_back(altstacktop(-1)); popstack(altstack); - } - break; + } break; - case OP_2DROP: - { + case OP_2DROP: { // (x1 x2 -- ) if (stack.size() < 2) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); popstack(stack); popstack(stack); - } - break; + } break; - case OP_2DUP: - { + case OP_2DUP: { // (x1 x2 -- x1 x2 x1 x2) if (stack.size() < 2) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); @@ -492,11 +493,9 @@ bool EvalScript( valtype vch2 = stacktop(-1); stack.push_back(vch1); stack.push_back(vch2); - } - break; + } break; - case OP_3DUP: - { + case OP_3DUP: { // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3) if (stack.size() < 3) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); @@ -506,11 +505,9 @@ bool EvalScript( stack.push_back(vch1); stack.push_back(vch2); stack.push_back(vch3); - } - break; + } break; - case OP_2OVER: - { + case OP_2OVER: { // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2) if (stack.size() < 4) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); @@ -518,92 +515,74 @@ bool EvalScript( valtype vch2 = stacktop(-3); stack.push_back(vch1); stack.push_back(vch2); - } - break; + } break; - case OP_2ROT: - { + case OP_2ROT: { // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2) if (stack.size() < 6) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch1 = stacktop(-6); valtype vch2 = stacktop(-5); - stack.erase(stack.end()-6, stack.end()-4); + stack.erase(stack.end() - 6, stack.end() - 4); stack.push_back(vch1); stack.push_back(vch2); - } - break; + } break; - case OP_2SWAP: - { + case OP_2SWAP: { // (x1 x2 x3 x4 -- x3 x4 x1 x2) if (stack.size() < 4) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); swap(stacktop(-4), stacktop(-2)); swap(stacktop(-3), stacktop(-1)); - } - break; + } break; - case OP_IFDUP: - { + case OP_IFDUP: { // (x - 0 | x x) if (stack.size() < 1) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch = stacktop(-1); if (CastToBool(vch)) stack.push_back(vch); - } - break; + } break; - case OP_DEPTH: - { + case OP_DEPTH: { // -- stacksize CScriptNum bn(stack.size()); stack.push_back(bn.getvch()); - } - break; + } break; - case OP_DROP: - { + case OP_DROP: { // (x -- ) if (stack.size() < 1) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); popstack(stack); - } - break; + } break; - case OP_DUP: - { + case OP_DUP: { // (x -- x x) if (stack.size() < 1) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch = stacktop(-1); stack.push_back(vch); - } - break; + } break; - case OP_NIP: - { + case OP_NIP: { // (x1 x2 -- x2) if (stack.size() < 2) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); stack.erase(stack.end() - 2); - } - break; + } break; - case OP_OVER: - { + case OP_OVER: { // (x1 x2 -- x1 x2 x1) if (stack.size() < 2) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch = stacktop(-2); stack.push_back(vch); - } - break; + } break; case OP_PICK: - case OP_ROLL: - { + case OP_ROLL: { // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn) // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn) if (stack.size() < 2) @@ -612,15 +591,13 @@ bool EvalScript( popstack(stack); if (n < 0 || n >= (int)stack.size()) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - valtype vch = stacktop(-n-1); + valtype vch = stacktop(-n - 1); if (opcode == OP_ROLL) - stack.erase(stack.end()-n-1); + stack.erase(stack.end() - n - 1); stack.push_back(vch); - } - break; + } break; - case OP_ROT: - { + case OP_ROT: { // (x1 x2 x3 -- x2 x3 x1) // x2 x1 x3 after first swap // x2 x3 x1 after second swap @@ -628,38 +605,31 @@ bool EvalScript( return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); swap(stacktop(-3), stacktop(-2)); swap(stacktop(-2), stacktop(-1)); - } - break; + } break; - case OP_SWAP: - { + case OP_SWAP: { // (x1 x2 -- x2 x1) if (stack.size() < 2) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); swap(stacktop(-2), stacktop(-1)); - } - break; + } break; - case OP_TUCK: - { + case OP_TUCK: { // (x1 x2 -- x2 x1 x2) if (stack.size() < 2) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch = stacktop(-1); - stack.insert(stack.end()-2, vch); - } - break; + stack.insert(stack.end() - 2, vch); + } break; - case OP_SIZE: - { + case OP_SIZE: { // (in -- in size) if (stack.size() < 1) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); CScriptNum bn(stacktop(-1).size()); stack.push_back(bn.getvch()); - } - break; + } break; // @@ -667,31 +637,30 @@ bool EvalScript( // case OP_EQUAL: case OP_EQUALVERIFY: - //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL - { - // (x1 x2 - bool) - if (stack.size() < 2) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - valtype& vch1 = stacktop(-2); - valtype& vch2 = stacktop(-1); - bool fEqual = (vch1 == vch2); - // OP_NOTEQUAL is disabled because it would be too easy to say - // something like n != 1 and have some wiseguy pass in 1 with extra - // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001) - //if (opcode == OP_NOTEQUAL) - // fEqual = !fEqual; - popstack(stack); - popstack(stack); - stack.push_back(fEqual ? vchTrue : vchFalse); - if (opcode == OP_EQUALVERIFY) + // case OP_NOTEQUAL: // use OP_NUMNOTEQUAL { - if (fEqual) - popstack(stack); - else - return set_error(serror, SCRIPT_ERR_EQUALVERIFY); + // (x1 x2 - bool) + if (stack.size() < 2) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype& vch1 = stacktop(-2); + valtype& vch2 = stacktop(-1); + bool fEqual = (vch1 == vch2); + // OP_NOTEQUAL is disabled because it would be too easy to say + // something like n != 1 and have some wiseguy pass in 1 with extra + // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001) + // if (opcode == OP_NOTEQUAL) + // fEqual = !fEqual; + popstack(stack); + popstack(stack); + stack.push_back(fEqual ? vchTrue : vchFalse); + if (opcode == OP_EQUALVERIFY) { + if (fEqual) + popstack(stack); + else + return set_error(serror, SCRIPT_ERR_EQUALVERIFY); + } } - } - break; + break; // @@ -702,26 +671,38 @@ bool EvalScript( case OP_NEGATE: case OP_ABS: case OP_NOT: - case OP_0NOTEQUAL: - { + case OP_0NOTEQUAL: { // (in -- out) if (stack.size() < 1) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); CScriptNum bn(stacktop(-1), fRequireMinimal); - switch (opcode) - { - case OP_1ADD: bn += bnOne; break; - case OP_1SUB: bn -= bnOne; break; - case OP_NEGATE: bn = -bn; break; - case OP_ABS: if (bn < bnZero) bn = -bn; break; - case OP_NOT: bn = (bn == bnZero); break; - case OP_0NOTEQUAL: bn = (bn != bnZero); break; - default: assert(!"invalid opcode"); break; + switch (opcode) { + case OP_1ADD: + bn += bnOne; + break; + case OP_1SUB: + bn -= bnOne; + break; + case OP_NEGATE: + bn = -bn; + break; + case OP_ABS: + if (bn < bnZero) + bn = -bn; + break; + case OP_NOT: + bn = (bn == bnZero); + break; + case OP_0NOTEQUAL: + bn = (bn != bnZero); + break; + default: + assert(!"invalid opcode"); + break; } popstack(stack); stack.push_back(bn.getvch()); - } - break; + } break; case OP_ADD: case OP_SUB: @@ -735,16 +716,14 @@ bool EvalScript( case OP_LESSTHANOREQUAL: case OP_GREATERTHANOREQUAL: case OP_MIN: - case OP_MAX: - { + case OP_MAX: { // (x1 x2 -- out) if (stack.size() < 2) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); CScriptNum bn1(stacktop(-2), fRequireMinimal); CScriptNum bn2(stacktop(-1), fRequireMinimal); CScriptNum bn(0); - switch (opcode) - { + switch (opcode) { case OP_ADD: bn = bn1 + bn2; break; @@ -753,35 +732,56 @@ bool EvalScript( bn = bn1 - bn2; break; - case OP_BOOLAND: bn = (bn1 != bnZero && bn2 != bnZero); break; - case OP_BOOLOR: bn = (bn1 != bnZero || bn2 != bnZero); break; - case OP_NUMEQUAL: bn = (bn1 == bn2); break; - case OP_NUMEQUALVERIFY: bn = (bn1 == bn2); break; - case OP_NUMNOTEQUAL: bn = (bn1 != bn2); break; - case OP_LESSTHAN: bn = (bn1 < bn2); break; - case OP_GREATERTHAN: bn = (bn1 > bn2); break; - case OP_LESSTHANOREQUAL: bn = (bn1 <= bn2); break; - case OP_GREATERTHANOREQUAL: bn = (bn1 >= bn2); break; - case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break; - case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break; - default: assert(!"invalid opcode"); break; + case OP_BOOLAND: + bn = (bn1 != bnZero && bn2 != bnZero); + break; + case OP_BOOLOR: + bn = (bn1 != bnZero || bn2 != bnZero); + break; + case OP_NUMEQUAL: + bn = (bn1 == bn2); + break; + case OP_NUMEQUALVERIFY: + bn = (bn1 == bn2); + break; + case OP_NUMNOTEQUAL: + bn = (bn1 != bn2); + break; + case OP_LESSTHAN: + bn = (bn1 < bn2); + break; + case OP_GREATERTHAN: + bn = (bn1 > bn2); + break; + case OP_LESSTHANOREQUAL: + bn = (bn1 <= bn2); + break; + case OP_GREATERTHANOREQUAL: + bn = (bn1 >= bn2); + break; + case OP_MIN: + bn = (bn1 < bn2 ? bn1 : bn2); + break; + case OP_MAX: + bn = (bn1 > bn2 ? bn1 : bn2); + break; + default: + assert(!"invalid opcode"); + break; } popstack(stack); popstack(stack); stack.push_back(bn.getvch()); - if (opcode == OP_NUMEQUALVERIFY) - { + if (opcode == OP_NUMEQUALVERIFY) { if (CastToBool(stacktop(-1))) popstack(stack); else return set_error(serror, SCRIPT_ERR_NUMEQUALVERIFY); } - } - break; + } break; - case OP_WITHIN: - { + case OP_WITHIN: { // (x min max -- out) if (stack.size() < 3) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); @@ -793,8 +793,7 @@ bool EvalScript( popstack(stack); popstack(stack); stack.push_back(fValue ? vchTrue : vchFalse); - } - break; + } break; // @@ -804,8 +803,7 @@ bool EvalScript( case OP_SHA1: case OP_SHA256: case OP_HASH160: - case OP_HASH256: - { + case OP_HASH256: { // (in -- hash) if (stack.size() < 1) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); @@ -823,21 +821,19 @@ bool EvalScript( CHash256().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash)); popstack(stack); stack.push_back(vchHash); - } - break; + } break; case OP_CHECKSIG: - case OP_CHECKSIGVERIFY: - { + case OP_CHECKSIGVERIFY: { // (sig pubkey -- bool) if (stack.size() < 2) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - valtype& vchSig = stacktop(-2); + valtype& vchSig = stacktop(-2); valtype& vchPubKey = stacktop(-1); if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) { - //serror is set + // serror is set return false; } bool fSuccess = checker.CheckSig(vchSig, vchPubKey, script, consensusBranchId); @@ -845,19 +841,16 @@ bool EvalScript( popstack(stack); popstack(stack); stack.push_back(fSuccess ? vchTrue : vchFalse); - if (opcode == OP_CHECKSIGVERIFY) - { + if (opcode == OP_CHECKSIGVERIFY) { if (fSuccess) popstack(stack); else return set_error(serror, SCRIPT_ERR_CHECKSIGVERIFY); } - } - break; + } break; case OP_CHECKMULTISIG: - case OP_CHECKMULTISIGVERIFY: - { + case OP_CHECKMULTISIGVERIFY: { // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool) int i = 1; @@ -884,9 +877,8 @@ bool EvalScript( return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); bool fSuccess = true; - while (fSuccess && nSigsCount > 0) - { - valtype& vchSig = stacktop(-isig); + while (fSuccess && nSigsCount > 0) { + valtype& vchSig = stacktop(-isig); valtype& vchPubKey = stacktop(-ikey); // Note how this makes the exact order of pubkey/signature evaluation @@ -932,27 +924,23 @@ bool EvalScript( stack.push_back(fSuccess ? vchTrue : vchFalse); - if (opcode == OP_CHECKMULTISIGVERIFY) - { + if (opcode == OP_CHECKMULTISIGVERIFY) { if (fSuccess) popstack(stack); else return set_error(serror, SCRIPT_ERR_CHECKMULTISIGVERIFY); } - } - break; + } break; default: return set_error(serror, SCRIPT_ERR_BAD_OPCODE); - } + } // Size limits if (stack.size() + altstack.size() > 1000) return set_error(serror, SCRIPT_ERR_STACK_SIZE); } - } - catch (...) - { + } catch (...) { return set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); } @@ -962,13 +950,15 @@ bool EvalScript( return set_success(serror); } -namespace { +namespace +{ /** * Wrapper that serializes like CTransaction, but with the modifications * required for the signature hash done in-place */ -class CTransactionSignatureSerializer { +class CTransactionSignatureSerializer +{ private: const CTransaction& txTo; //!< reference to the spending transaction (the one being serialized) const CScript& scriptCode; //!< output script being consumed @@ -978,23 +968,24 @@ class CTransactionSignatureSerializer { const bool fHashNone; //!< whether the hashtype is SIGHASH_NONE public: - CTransactionSignatureSerializer(const CTransaction &txToIn, const CScript &scriptCodeIn, unsigned int nInIn, int nHashTypeIn) : - txTo(txToIn), scriptCode(scriptCodeIn), nIn(nInIn), - fAnyoneCanPay(!!(nHashTypeIn & SIGHASH_ANYONECANPAY)), - fHashSingle((nHashTypeIn & 0x1f) == SIGHASH_SINGLE), - fHashNone((nHashTypeIn & 0x1f) == SIGHASH_NONE) {} + CTransactionSignatureSerializer(const CTransaction& txToIn, const CScript& scriptCodeIn, unsigned int nInIn, int nHashTypeIn) : txTo(txToIn), scriptCode(scriptCodeIn), nIn(nInIn), + fAnyoneCanPay(!!(nHashTypeIn & SIGHASH_ANYONECANPAY)), + fHashSingle((nHashTypeIn & 0x1f) == SIGHASH_SINGLE), + fHashNone((nHashTypeIn & 0x1f) == SIGHASH_NONE) {} /** Serialize the passed scriptCode */ - template - void SerializeScriptCode(S &s) const { + template + void SerializeScriptCode(S& s) const + { auto size = scriptCode.size(); ::WriteCompactSize(s, size); s.write((char*)&scriptCode.begin()[0], size); } /** Serialize an input of txTo */ - template - void SerializeInput(S &s, unsigned int nInput) const { + template + void SerializeInput(S& s, unsigned int nInput) const + { // In case of SIGHASH_ANYONECANPAY, only the input being signed is serialized if (fAnyoneCanPay) nInput = nIn; @@ -1016,8 +1007,9 @@ class CTransactionSignatureSerializer { } /** Serialize an output of txTo */ - template - void SerializeOutput(S &s, unsigned int nOutput) const { + template + void SerializeOutput(S& s, unsigned int nOutput) const + { if (fHashSingle && nOutput != nIn) // Do not lock-in the txout payee at other indices as txin ::Serialize(s, CTxOut()); @@ -1026,20 +1018,21 @@ class CTransactionSignatureSerializer { } /** Serialize txTo */ - template - void Serialize(S &s) const { + template + void Serialize(S& s) const + { // Serialize nVersion ::Serialize(s, txTo.nVersion); // Serialize vin unsigned int nInputs = fAnyoneCanPay ? 1 : txTo.vin.size(); ::WriteCompactSize(s, nInputs); for (unsigned int nInput = 0; nInput < nInputs; nInput++) - SerializeInput(s, nInput); + SerializeInput(s, nInput); // Serialize vout - unsigned int nOutputs = fHashNone ? 0 : (fHashSingle ? nIn+1 : txTo.vout.size()); + unsigned int nOutputs = fHashNone ? 0 : (fHashSingle ? nIn + 1 : txTo.vout.size()); ::WriteCompactSize(s, nOutputs); for (unsigned int nOutput = 0; nOutput < nOutputs; nOutput++) - SerializeOutput(s, nOutput); + SerializeOutput(s, nOutput); // Serialize nLockTime ::Serialize(s, txTo.nLockTime); @@ -1063,19 +1056,20 @@ class CTransactionSignatureSerializer { }; const unsigned char ZCASH_PREVOUTS_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] = - {'Z','c','a','s','h','P','r','e','v','o','u','t','H','a','s','h'}; + {'Z', 'c', 'a', 's', 'h', 'P', 'r', 'e', 'v', 'o', 'u', 't', 'H', 'a', 's', 'h'}; const unsigned char ZCASH_SEQUENCE_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] = - {'Z','c','a','s','h','S','e','q','u','e','n','c','H','a','s','h'}; + {'Z', 'c', 'a', 's', 'h', 'S', 'e', 'q', 'u', 'e', 'n', 'c', 'H', 'a', 's', 'h'}; const unsigned char ZCASH_OUTPUTS_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] = - {'Z','c','a','s','h','O','u','t','p','u','t','s','H','a','s','h'}; + {'Z', 'c', 'a', 's', 'h', 'O', 'u', 't', 'p', 'u', 't', 's', 'H', 'a', 's', 'h'}; const unsigned char ZCASH_JOINSPLITS_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] = - {'Z','c','a','s','h','J','S','p','l','i','t','s','H','a','s','h'}; + {'Z', 'c', 'a', 's', 'h', 'J', 'S', 'p', 'l', 'i', 't', 's', 'H', 'a', 's', 'h'}; const unsigned char ZCASH_SHIELDED_SPENDS_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] = - {'Z','c','a','s','h','S','S','p','e','n','d','s','H','a','s','h'}; + {'Z', 'c', 'a', 's', 'h', 'S', 'S', 'p', 'e', 'n', 'd', 's', 'H', 'a', 's', 'h'}; const unsigned char ZCASH_SHIELDED_OUTPUTS_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] = - {'Z','c','a','s','h','S','O','u','t','p','u','t','H','a','s','h'}; + {'Z', 'c', 'a', 's', 'h', 'S', 'O', 'u', 't', 'p', 'u', 't', 'H', 'a', 's', 'h'}; -uint256 GetPrevoutHash(const CTransaction& txTo) { +uint256 GetPrevoutHash(const CTransaction& txTo) +{ CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_PREVOUTS_HASH_PERSONALIZATION); for (unsigned int n = 0; n < txTo.vin.size(); n++) { ss << txTo.vin[n].prevout; @@ -1083,7 +1077,8 @@ uint256 GetPrevoutHash(const CTransaction& txTo) { return ss.GetHash(); } -uint256 GetSequenceHash(const CTransaction& txTo) { +uint256 GetSequenceHash(const CTransaction& txTo) +{ CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_SEQUENCE_HASH_PERSONALIZATION); for (unsigned int n = 0; n < txTo.vin.size(); n++) { ss << txTo.vin[n].nSequence; @@ -1091,7 +1086,8 @@ uint256 GetSequenceHash(const CTransaction& txTo) { return ss.GetHash(); } -uint256 GetOutputsHash(const CTransaction& txTo) { +uint256 GetOutputsHash(const CTransaction& txTo) +{ CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_OUTPUTS_HASH_PERSONALIZATION); for (unsigned int n = 0; n < txTo.vout.size(); n++) { ss << txTo.vout[n]; @@ -1099,7 +1095,8 @@ uint256 GetOutputsHash(const CTransaction& txTo) { return ss.GetHash(); } -uint256 GetJoinSplitsHash(const CTransaction& txTo) { +uint256 GetJoinSplitsHash(const CTransaction& txTo) +{ CBLAKE2bWriter ss(SER_GETHASH, static_cast(txTo.GetHeader()), ZCASH_JOINSPLITS_HASH_PERSONALIZATION); for (unsigned int n = 0; n < txTo.vJoinSplit.size(); n++) { ss << txTo.vJoinSplit[n]; @@ -1108,7 +1105,8 @@ uint256 GetJoinSplitsHash(const CTransaction& txTo) { return ss.GetHash(); } -uint256 GetShieldedSpendsHash(const CTransaction& txTo) { +uint256 GetShieldedSpendsHash(const CTransaction& txTo) +{ CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_SHIELDED_SPENDS_HASH_PERSONALIZATION); for (const auto& spend : txTo.GetSaplingSpends()) { ss << spend.cv(); @@ -1120,7 +1118,8 @@ uint256 GetShieldedSpendsHash(const CTransaction& txTo) { return ss.GetHash(); } -uint256 GetShieldedOutputsHash(const CTransaction& txTo) { +uint256 GetShieldedOutputsHash(const CTransaction& txTo) +{ CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_SHIELDED_OUTPUTS_HASH_PERSONALIZATION); auto ssRs = ToRustStream(ss); for (const auto& output : txTo.GetSaplingOutputs()) { @@ -1129,12 +1128,11 @@ uint256 GetShieldedOutputsHash(const CTransaction& txTo) { return ss.GetHash(); } -} // anon namespace +} // namespace PrecomputedTransactionData::PrecomputedTransactionData( const CTransaction& txTo, - const std::vector& allPrevOutputs) : - preTx(nullptr, zcash_transaction_precomputed_free) + const std::vector& allPrevOutputs) : preTx(nullptr, zcash_transaction_precomputed_free) { CDataStream sAllPrevOutputs(SER_NETWORK, PROTOCOL_VERSION); sAllPrevOutputs << allPrevOutputs; @@ -1147,8 +1145,7 @@ PrecomputedTransactionData::PrecomputedTransactionData( PrecomputedTransactionData::PrecomputedTransactionData( const CTransaction& txTo, const unsigned char* allPrevOutputs, - size_t allPrevOutputsLen) : - preTx(nullptr, zcash_transaction_precomputed_free) + size_t allPrevOutputsLen) : preTx(nullptr, zcash_transaction_precomputed_free) { SetPrecomputed(txTo, allPrevOutputs, allPrevOutputsLen); } @@ -1266,11 +1263,10 @@ uint256 SignatureHash( // in the transaction itself. uint256 hash; if (!zcash_transaction_zip244_signature_digest( - txdata.preTx.get(), - nHashType, - nIn, - hash.begin())) - { + txdata.preTx.get(), + nHashType, + nIn, + hash.begin())) { throw std::logic_error("We should not reach here."); } return hash; @@ -1314,7 +1310,7 @@ uint256 SignatureHash( uint32_t leConsensusBranchId = htole32(consensusBranchId); unsigned char personalization[16] = {}; memcpy(personalization, "ZcashSigHash", 12); - memcpy(personalization+12, &leConsensusBranchId, 4); + memcpy(personalization + 12, &leConsensusBranchId, 4); CBLAKE2bWriter ss(SER_GETHASH, 0, personalization); // Header @@ -1347,7 +1343,7 @@ uint256 SignatureHash( // If this hash is for a transparent input signature // (i.e. not for txTo.joinSplitSig): - if (nIn != NOT_AN_INPUT){ + if (nIn != NOT_AN_INPUT) { // The input being signed (replacing the scriptSig with scriptCode + amount) // The prevout may already be contained in hashPrevout, and the nSequence // may already be contained in hashSequence. @@ -1378,7 +1374,9 @@ uint256 SignatureHash( } bool TransactionSignatureChecker::VerifySignature( - const std::vector& vchSig, const CPubKey& pubkey, const uint256& sighash) const + const std::vector& vchSig, + const CPubKey& pubkey, + const uint256& sighash) const { return pubkey.Verify(sighash, vchSig); } @@ -1423,9 +1421,8 @@ bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) con // unless the type of nLockTime being tested is the same as // the nLockTime in the transaction. if (!( - (txTo->nLockTime < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) || - (txTo->nLockTime >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD) - )) + (txTo->nLockTime < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) || + (txTo->nLockTime >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD))) return false; // Now that we know we're comparing apples-to-apples, the @@ -1449,6 +1446,74 @@ bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) con return true; } +bool PrehashedTransactionSignatureChecker::VerifySignature( + const std::vector& vchSig, + const CPubKey& pubkey, + const uint256& sighash) const +{ + return pubkey.Verify(sighash, vchSig); +} + +bool PrehashedTransactionSignatureChecker::CheckSig( + const vector& vchSigIn, + const vector& vchPubKey, + const CScript& scriptCode, + uint32_t consensusBranchId) const +{ + CPubKey pubkey(vchPubKey); + if (!pubkey.IsValid()) + return false; + + // Hash type is one byte tacked on to the end of the signature + vector vchSig(vchSigIn); + if (vchSig.empty()) + return false; + int nHashType = vchSig.back(); + vchSig.pop_back(); + + std::array sighashArray; + std::copy_n(this->sighash, sighashArray.size(), sighashArray.begin()); + uint256 sighash = uint256::FromRawBytes(sighashArray); + if (!VerifySignature(vchSig, pubkey, sighash)) + return false; + + return true; +} + +bool PrehashedTransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) const +{ + // There are two times of nLockTime: lock-by-blockheight + // and lock-by-blocktime, distinguished by whether + // nLockTime < LOCKTIME_THRESHOLD. + // + // We want to compare apples to apples, so fail the script + // unless the type of nLockTime being tested is the same as + // the nLockTime in the transaction. + if (!( + (this->nLockTime < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) || + (this->nLockTime >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD))) + return false; + + // Now that we know we're comparing apples-to-apples, the + // comparison is a simple numeric one. + if (nLockTime > this->nLockTime) + return false; + + // Finally the nLockTime feature can be disabled and thus + // CHECKLOCKTIMEVERIFY bypassed if every txin has been + // finalized by setting nSequence to maxint. The + // transaction would be allowed into the blockchain, making + // the opcode ineffective. + // + // Testing if this vin is not final is sufficient to + // prevent this condition. Alternatively we could test all + // inputs, but testing just this input minimizes the data + // required to prove correct CHECKLOCKTIMEVERIFY execution. + if (this->isFinal) + return false; + + return true; +} bool VerifyScript( const CScript& scriptSig, @@ -1464,7 +1529,7 @@ bool VerifyScript( return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY); } - vector > stack, stackCopy; + vector> stack, stackCopy; if (!EvalScript(stack, scriptSig, flags, checker, consensusBranchId, serror)) // serror is set return false; @@ -1479,8 +1544,7 @@ bool VerifyScript( return set_error(serror, SCRIPT_ERR_EVAL_FALSE); // Additional validation for spend-to-script-hash transactions: - if ((flags & SCRIPT_VERIFY_P2SH) && scriptPubKey.IsPayToScriptHash()) - { + if ((flags & SCRIPT_VERIFY_P2SH) && scriptPubKey.IsPayToScriptHash()) { // scriptSig must be literals-only or validation fails if (!scriptSig.IsPushOnly()) return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY); diff --git a/depend/zcash/src/script/interpreter.h b/depend/zcash/src/script/interpreter.h index 4c2743f8c..1c365f716 100644 --- a/depend/zcash/src/script/interpreter.h +++ b/depend/zcash/src/script/interpreter.h @@ -7,15 +7,15 @@ #ifndef BITCOIN_SCRIPT_INTERPRETER_H #define BITCOIN_SCRIPT_INTERPRETER_H -#include "script_error.h" #include "primitives/transaction.h" +#include "script_error.h" #include -#include +#include #include #include -#include +#include class CPubKey; class CScript; @@ -26,8 +26,7 @@ class uint256; const unsigned int NOT_AN_INPUT = UINT_MAX; /** Signature hash types/flags */ -enum -{ +enum { SIGHASH_ALL = 1, SIGHASH_NONE = 2, SIGHASH_SINGLE = 3, @@ -35,12 +34,11 @@ enum }; /** Script verification flags */ -enum -{ - SCRIPT_VERIFY_NONE = 0, +enum { + SCRIPT_VERIFY_NONE = 0, // Evaluate P2SH subscripts (softfork safe, BIP16). - SCRIPT_VERIFY_P2SH = (1U << 0), + SCRIPT_VERIFY_P2SH = (1U << 0), // Passing a non-strict-DER signature or one with undefined hashtype to a checksig operation causes script failure. // Evaluating a pubkey that is not (0x04 + 64 bytes) or (0x02 or 0x03 + 32 bytes) by checksig causes script failure. @@ -49,11 +47,11 @@ enum // Passing a non-strict-DER signature to a checksig operation causes script failure (softfork safe, BIP62 rule 1) // In Zcash this is required, and validation of non-strict-DER signatures is not implemented. - //SCRIPT_VERIFY_DERSIG = (1U << 2), + // SCRIPT_VERIFY_DERSIG = (1U << 2), // Passing a non-strict-DER signature or one with S > order/2 to a checksig operation causes script failure // (softfork safe, BIP62 rule 5). - SCRIPT_VERIFY_LOW_S = (1U << 3), + SCRIPT_VERIFY_LOW_S = (1U << 3), // verify dummy stack item consumed by CHECKMULTISIG is of zero-length (softfork safe, BIP62 rule 7). SCRIPT_VERIFY_NULLDUMMY = (1U << 4), @@ -76,7 +74,7 @@ enum // discouraged NOPs fails the script. This verification flag will never be // a mandatory flag applied to scripts in a block. NOPs that are not // executed, e.g. within an unexecuted IF ENDIF block, are *not* rejected. - SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1U << 7), + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1U << 7), // Require that only a single stack element remains after evaluation. This changes the success criterion from // "At least one stack element must remain, and when interpreted as a boolean, it must be true" to @@ -91,10 +89,9 @@ enum SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), }; -bool CheckSignatureEncoding(const std::vector &vchSig, unsigned int flags, ScriptError* serror); +bool CheckSignatureEncoding(const std::vector& vchSig, unsigned int flags, ScriptError* serror); -struct PrecomputedTransactionData -{ +struct PrecomputedTransactionData { uint256 hashPrevouts, hashSequence, hashOutputs, hashJoinSplits, hashShieldedSpends, hashShieldedOutputs; /** Precomputed transaction parts. */ std::unique_ptr preTx; @@ -115,8 +112,7 @@ struct PrecomputedTransactionData size_t allPrevOutputsLen); }; -enum SigVersion -{ +enum SigVersion { SIGVERSION_SPROUT = 0, SIGVERSION_OVERWINTER = 1, SIGVERSION_SAPLING = 2, @@ -124,7 +120,7 @@ enum SigVersion }; uint256 SignatureHash( - const CScript &scriptCode, + const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, @@ -146,7 +142,7 @@ class BaseSignatureChecker virtual bool CheckLockTime(const CScriptNum& nLockTime) const { - return false; + return false; } virtual ~BaseSignatureChecker() {} @@ -178,8 +174,28 @@ class MutableTransactionSignatureChecker : public TransactionSignatureChecker MutableTransactionSignatureChecker(const CMutableTransaction* txToIn, const PrecomputedTransactionData& txdataIn, unsigned int nInIn, const CAmount& amount) : TransactionSignatureChecker(&txTo, txdataIn, nInIn, amount), txTo(*txToIn) {} }; +class PrehashedTransactionSignatureChecker : public BaseSignatureChecker +{ +private: + const unsigned char* sighash; + unsigned int sighashLen; + const CScriptNum& nLockTime; + bool isFinal; + unsigned int nIn; + const CAmount amount; + +protected: + virtual bool VerifySignature(const std::vector& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; + +public: + PrehashedTransactionSignatureChecker(const unsigned char* sighash, unsigned int sighashLen, const CScriptNum& nLockTime, bool isFinal, unsigned int nInIn, const CAmount& amountIn) : sighash(sighash), sighashLen(sighashLen), nLockTime(nLockTime), isFinal(isFinal), nIn(nInIn), amount(amountIn) {} + bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode, uint32_t consensusBranchId) const; + bool CheckLockTime(const CScriptNum& nLockTime) const; +}; + + bool EvalScript( - std::vector >& stack, + std::vector>& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, diff --git a/depend/zcash/src/script/zcash_script.cpp b/depend/zcash/src/script/zcash_script.cpp index bdb855324..c1801ce3a 100644 --- a/depend/zcash/src/script/zcash_script.cpp +++ b/depend/zcash/src/script/zcash_script.cpp @@ -12,7 +12,8 @@ #include "script/interpreter.h" #include "version.h" -namespace { +namespace +{ inline int set_error(zcash_script_error* ret, zcash_script_error serror) { if (ret) @@ -25,17 +26,15 @@ inline int set_error(zcash_script_error* ret, zcash_script_error serror) unsigned int GetLegacySigOpCount(const CTransaction& tx) { unsigned int nSigOps = 0; - for (const CTxIn& txin : tx.vin) - { + for (const CTxIn& txin : tx.vin) { nSigOps += txin.scriptSig.GetSigOpCount(false); } - for (const CTxOut& txout : tx.vout) - { + for (const CTxOut& txout : tx.vout) { nSigOps += txout.scriptPubKey.GetSigOpCount(false); } return nSigOps; } -} +} // namespace struct PrecomputedTransaction { const CTransaction tx; @@ -53,8 +52,8 @@ void* zcash_script_new_precomputed_tx( zcash_script_error* err) { try { - const char* txToEnd = (const char *)(txTo + txToLen); - RustDataStream stream((const char *)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); + const char* txToEnd = (const char*)(txTo + txToLen); + RustDataStream stream((const char*)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); CTransaction tx; stream >> tx; if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) { @@ -87,8 +86,8 @@ void* zcash_script_new_precomputed_tx_v5( { CTransaction tx; try { - const char* txToEnd = (const char *)(txTo + txToLen); - RustDataStream stream((const char *)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); + const char* txToEnd = (const char*)(txTo + txToLen); + RustDataStream stream((const char*)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); stream >> tx; if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) { set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); @@ -145,16 +144,19 @@ int zcash_script_verify_precomputed( } int zcash_script_verify( - const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, + const unsigned char* scriptPubKey, + unsigned int scriptPubKeyLen, int64_t amount, - const unsigned char *txTo, unsigned int txToLen, - unsigned int nIn, unsigned int flags, + const unsigned char* txTo, + unsigned int txToLen, + unsigned int nIn, + unsigned int flags, uint32_t consensusBranchId, zcash_script_error* err) { try { - const char* txToEnd = (const char *)(txTo + txToLen); - RustDataStream stream((const char *)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); + const char* txToEnd = (const char*)(txTo + txToLen); + RustDataStream stream((const char*)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); CTransaction tx; stream >> tx; if (nIn >= tx.vin.size()) @@ -165,7 +167,7 @@ int zcash_script_verify( return set_error(err, zcash_script_ERR_TX_VERSION); } - // Regardless of the verification result, the tx did not error. + // Regardless of the verification result, the tx did not error. set_error(err, zcash_script_ERR_OK); // This is a pre-v5 tx, so the PrecomputedTransactionData constructor // field `allPrevOutputs` is not used. @@ -182,6 +184,35 @@ int zcash_script_verify( } } +int zcash_script_verify_prehashed( + const unsigned char* sighash, + unsigned int sighashLen, + int64_t nLockTime, + uint8_t isFinal, + const unsigned char* scriptPubKey, + unsigned int scriptPubKeyLen, + const unsigned char* scriptSig, + unsigned int scriptSigLen, + int64_t amount, + unsigned int nIn, + unsigned int flags, + uint32_t consensusBranchId, + zcash_script_error* err) +{ + try { + CScriptNum nLockTimeNum = CScriptNum(nLockTime); + return VerifyScript( + CScript(scriptSig, scriptSig + scriptSigLen), + CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), + flags, + PrehashedTransactionSignatureChecker(sighash, sighashLen, nLockTimeNum, isFinal != 0, nIn, amount), + consensusBranchId, + NULL); + } catch (const std::exception&) { + return set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing + } +} + int zcash_script_verify_v5( const unsigned char* txTo, unsigned int txToLen, @@ -194,8 +225,8 @@ int zcash_script_verify_v5( { CTransaction tx; try { - const char* txToEnd = (const char *)(txTo + txToLen); - RustDataStream stream((const char *)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); + const char* txToEnd = (const char*)(txTo + txToLen); + RustDataStream stream((const char*)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); stream >> tx; if (nIn >= tx.vin.size()) return set_error(err, zcash_script_ERR_TX_INDEX); @@ -253,13 +284,13 @@ unsigned int zcash_script_legacy_sigop_count_precomputed( } unsigned int zcash_script_legacy_sigop_count( - const unsigned char *txTo, + const unsigned char* txTo, unsigned int txToLen, zcash_script_error* err) { try { - const char* txToEnd = (const char *)(txTo + txToLen); - RustDataStream stream((const char *)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); + const char* txToEnd = (const char*)(txTo + txToLen); + RustDataStream stream((const char*)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); CTransaction tx; stream >> tx; if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) { diff --git a/depend/zcash/src/script/zcash_script.h b/depend/zcash/src/script/zcash_script.h index c12ca78f1..3239a6c79 100644 --- a/depend/zcash/src/script/zcash_script.h +++ b/depend/zcash/src/script/zcash_script.h @@ -133,6 +133,21 @@ EXPORT_SYMBOL int zcash_script_verify( uint32_t consensusBranchId, zcash_script_error* err); +EXPORT_SYMBOL int zcash_script_verify_prehashed( + const unsigned char* sighash, + unsigned int sighashLen, + int64_t nLockTime, + uint8_t isFinal, + const unsigned char* scriptPubKey, + unsigned int scriptPubKeyLen, + const unsigned char* scriptSig, + unsigned int scriptSigLen, + int64_t amount, + unsigned int nIn, + unsigned int flags, + uint32_t consensusBranchId, + zcash_script_error* err); + /// Returns 1 if the input nIn of the serialized transaction pointed to by /// txTo correctly spends the matching output in allPrevOutputs under /// the additional constraints specified by flags. Must be used for V5 transactions; From 112d0854e60f2b358f936ebf7990a26772f986b1 Mon Sep 17 00:00:00 2001 From: Conrado Gouvea Date: Tue, 16 Apr 2024 16:57:07 -0300 Subject: [PATCH 02/16] removed unneded code; callback API --- build.rs | 20 +- depend/zcash/src/script/interpreter.cpp | 84 +++- depend/zcash/src/script/interpreter.h | 19 + depend/zcash/src/script/zcash_script.cpp | 509 +++++++++++++---------- depend/zcash/src/script/zcash_script.h | 144 ++++--- src/lib.rs | 96 ++--- 6 files changed, 518 insertions(+), 354 deletions(-) diff --git a/build.rs b/build.rs index e4b85cc89..ac11c5db5 100644 --- a/build.rs +++ b/build.rs @@ -206,25 +206,25 @@ fn main() -> Result<()> { .file("depend/zcash/src/amount.cpp") .file("depend/zcash/src/uint256.cpp") .file("depend/zcash/src/pubkey.cpp") - .file("depend/zcash/src/hash.cpp") - .file("depend/zcash/src/streams_rust.cpp") - .file("depend/zcash/src/zip317.cpp") - .file("depend/zcash/src/primitives/transaction.cpp") + // .file("depend/zcash/src/hash.cpp") + // .file("depend/zcash/src/streams_rust.cpp") + //.file("depend/zcash/src/zip317.cpp") + // .file("depend/zcash/src/primitives/transaction.cpp") .file("depend/zcash/src/crypto/ripemd160.cpp") .file("depend/zcash/src/crypto/sha1.cpp") .file("depend/zcash/src/crypto/sha256.cpp") - .file("depend/zcash/src/crypto/sha512.cpp") - .file("depend/zcash/src/crypto/hmac_sha512.cpp") + // .file("depend/zcash/src/crypto/sha512.cpp") + // .file("depend/zcash/src/crypto/hmac_sha512.cpp") .file("depend/zcash/src/script/interpreter.cpp") .file("depend/zcash/src/script/script.cpp") .file("depend/zcash/src/script/script_error.cpp") - .file("depend/zcash/src/support/cleanse.cpp") + // .file("depend/zcash/src/support/cleanse.cpp") .file("depend/zcash/src/zcash/cache.cpp") // A subset of the files generated by gen_cxxbridge // which are required by zcash_script. - .file(gen_path.join("src/blake2b.cpp")) - .file(gen_path.join("src/bridge.cpp")) - .file(gen_path.join("src/streams.cpp")) + // .file(gen_path.join("src/blake2b.cpp")) + // .file(gen_path.join("src/bridge.cpp")) + // .file(gen_path.join("src/streams.cpp")) .compile("libzcash_script.a"); Ok(()) diff --git a/depend/zcash/src/script/interpreter.cpp b/depend/zcash/src/script/interpreter.cpp index d5fb71d45..ce0d82f19 100644 --- a/depend/zcash/src/script/interpreter.cpp +++ b/depend/zcash/src/script/interpreter.cpp @@ -1515,6 +1515,82 @@ bool PrehashedTransactionSignatureChecker::CheckLockTime(const CScriptNum& nLock return true; } +bool CallbackTransactionSignatureChecker::VerifySignature( + const std::vector& vchSig, + const CPubKey& pubkey, + const uint256& sighash) const +{ + return pubkey.Verify(sighash, vchSig); +} + +bool CallbackTransactionSignatureChecker::CheckSig( + const vector& vchSigIn, + const vector& vchPubKey, + const CScript& scriptCode, + uint32_t consensusBranchId) const +{ + CPubKey pubkey(vchPubKey); + if (!pubkey.IsValid()) + return false; + + // Hash type is one byte tacked on to the end of the signature + vector vchSig(vchSigIn); + if (vchSig.empty()) + return false; + int nHashType = vchSig.back(); + vchSig.pop_back(); + + uint256 sighash; + try { + std::array sighashArray; + auto scriptBase = static_cast(scriptCode); + this->sighash(sighashArray.begin(), this->tx, &scriptBase[0], scriptBase.size(), nHashType); + sighash = uint256::FromRawBytes(sighashArray); + } catch (logic_error ex) { + return false; + } + + if (!VerifySignature(vchSig, pubkey, sighash)) + return false; + + return true; +} + +bool CallbackTransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) const +{ + // There are two times of nLockTime: lock-by-blockheight + // and lock-by-blocktime, distinguished by whether + // nLockTime < LOCKTIME_THRESHOLD. + // + // We want to compare apples to apples, so fail the script + // unless the type of nLockTime being tested is the same as + // the nLockTime in the transaction. + if (!( + (this->nLockTime < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) || + (this->nLockTime >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD))) + return false; + + // Now that we know we're comparing apples-to-apples, the + // comparison is a simple numeric one. + if (nLockTime > this->nLockTime) + return false; + + // Finally the nLockTime feature can be disabled and thus + // CHECKLOCKTIMEVERIFY bypassed if every txin has been + // finalized by setting nSequence to maxint. The + // transaction would be allowed into the blockchain, making + // the opcode ineffective. + // + // Testing if this vin is not final is sufficient to + // prevent this condition. Alternatively we could test all + // inputs, but testing just this input minimizes the data + // required to prove correct CHECKLOCKTIMEVERIFY execution. + if (this->isFinal) + return false; + + return true; +} + bool VerifyScript( const CScript& scriptSig, const CScript& scriptPubKey, @@ -1539,9 +1615,9 @@ bool VerifyScript( // serror is set return false; if (stack.empty()) - return set_error(serror, SCRIPT_ERR_EVAL_FALSE); + return set_error(serror, (ScriptError_t)(SCRIPT_ERR_EVAL_FALSE + 101)); if (CastToBool(stack.back()) == false) - return set_error(serror, SCRIPT_ERR_EVAL_FALSE); + return set_error(serror, (ScriptError_t)(SCRIPT_ERR_EVAL_FALSE + 102)); // Additional validation for spend-to-script-hash transactions: if ((flags & SCRIPT_VERIFY_P2SH) && scriptPubKey.IsPayToScriptHash()) { @@ -1565,9 +1641,9 @@ bool VerifyScript( // serror is set return false; if (stack.empty()) - return set_error(serror, SCRIPT_ERR_EVAL_FALSE); + return set_error(serror, (ScriptError_t)(SCRIPT_ERR_EVAL_FALSE + 103)); if (!CastToBool(stack.back())) - return set_error(serror, SCRIPT_ERR_EVAL_FALSE); + return set_error(serror, (ScriptError_t)(SCRIPT_ERR_EVAL_FALSE + 104)); } // The CLEANSTACK check is only performed after potential P2SH evaluation, diff --git a/depend/zcash/src/script/interpreter.h b/depend/zcash/src/script/interpreter.h index 1c365f716..b221faa97 100644 --- a/depend/zcash/src/script/interpreter.h +++ b/depend/zcash/src/script/interpreter.h @@ -193,6 +193,25 @@ class PrehashedTransactionSignatureChecker : public BaseSignatureChecker bool CheckLockTime(const CScriptNum& nLockTime) const; }; +class CallbackTransactionSignatureChecker : public BaseSignatureChecker +{ +private: + const void* tx; + void (*sighash)(unsigned char* sighash, const void* tx, const unsigned char* scriptCode, unsigned int scriptCodeLen, int hashType); + const CScriptNum& nLockTime; + bool isFinal; + unsigned int nIn; + const CAmount amount; + +protected: + virtual bool VerifySignature(const std::vector& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; + +public: + CallbackTransactionSignatureChecker(const void* tx, void (*sighash)(unsigned char* sighash, const void* tx, const unsigned char* scriptCode, unsigned int scriptCodeLen, int hashType), const CScriptNum& nLockTime, bool isFinal, unsigned int nInIn, const CAmount& amountIn) : tx(tx), sighash(sighash), nLockTime(nLockTime), isFinal(isFinal), nIn(nInIn), amount(amountIn) {} + bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode, uint32_t consensusBranchId) const; + bool CheckLockTime(const CScriptNum& nLockTime) const; +}; + bool EvalScript( std::vector>& stack, diff --git a/depend/zcash/src/script/zcash_script.cpp b/depend/zcash/src/script/zcash_script.cpp index c1801ce3a..960dcec5b 100644 --- a/depend/zcash/src/script/zcash_script.cpp +++ b/depend/zcash/src/script/zcash_script.cpp @@ -6,9 +6,9 @@ #include "zcash_script.h" -#include "consensus/upgrades.h" -#include "primitives/transaction.h" -#include "pubkey.h" +// #include "consensus/upgrades.h" +// #include "primitives/transaction.h" +// #include "pubkey.h" #include "script/interpreter.h" #include "version.h" @@ -21,172 +21,207 @@ inline int set_error(zcash_script_error* ret, zcash_script_error serror) return 0; } -// Copy of GetLegacySigOpCount from main.cpp commit c4b2ef7c4. -// Replace with the copy from src/consensus/tx_verify.{cpp,h} after backporting that refactor. -unsigned int GetLegacySigOpCount(const CTransaction& tx) -{ - unsigned int nSigOps = 0; - for (const CTxIn& txin : tx.vin) { - nSigOps += txin.scriptSig.GetSigOpCount(false); - } - for (const CTxOut& txout : tx.vout) { - nSigOps += txout.scriptPubKey.GetSigOpCount(false); - } - return nSigOps; -} +// // Copy of GetLegacySigOpCount from main.cpp commit c4b2ef7c4. +// // Replace with the copy from src/consensus/tx_verify.{cpp,h} after backporting that refactor. +// unsigned int GetLegacySigOpCount(const CTransaction& tx) +// { +// unsigned int nSigOps = 0; +// for (const CTxIn& txin : tx.vin) { +// nSigOps += txin.scriptSig.GetSigOpCount(false); +// } +// for (const CTxOut& txout : tx.vout) { +// nSigOps += txout.scriptPubKey.GetSigOpCount(false); +// } +// return nSigOps; +// } } // namespace -struct PrecomputedTransaction { - const CTransaction tx; - const PrecomputedTransactionData txdata; +// struct PrecomputedTransaction { +// const CTransaction tx; +// const PrecomputedTransactionData txdata; - PrecomputedTransaction( - CTransaction txIn, - const unsigned char* allPrevOutputs, - size_t allPrevOutputsLen) : tx(txIn), txdata(txIn, allPrevOutputs, allPrevOutputsLen) {} -}; +// PrecomputedTransaction( +// CTransaction txIn, +// const unsigned char* allPrevOutputs, +// size_t allPrevOutputsLen) : tx(txIn), txdata(txIn, allPrevOutputs, allPrevOutputsLen) {} +// }; -void* zcash_script_new_precomputed_tx( - const unsigned char* txTo, - unsigned int txToLen, - zcash_script_error* err) -{ - try { - const char* txToEnd = (const char*)(txTo + txToLen); - RustDataStream stream((const char*)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); - CTransaction tx; - stream >> tx; - if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) { - set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); - return nullptr; - } - if (tx.nVersion >= ZIP225_TX_VERSION) { - set_error(err, zcash_script_ERR_TX_VERSION); - return nullptr; - } +// void* zcash_script_new_precomputed_tx( +// const unsigned char* txTo, +// unsigned int txToLen, +// zcash_script_error* err) +// { +// try { +// const char* txToEnd = (const char*)(txTo + txToLen); +// RustDataStream stream((const char*)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); +// CTransaction tx; +// stream >> tx; +// if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) { +// set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); +// return nullptr; +// } +// if (tx.nVersion >= ZIP225_TX_VERSION) { +// set_error(err, zcash_script_ERR_TX_VERSION); +// return nullptr; +// } - // Deserializing the tx did not error. - set_error(err, zcash_script_ERR_OK); - // This is a pre-v5 tx, so the PrecomputedTransactionData constructor - // field `allPrevOutputs` is not used. - auto preTx = new PrecomputedTransaction(tx, nullptr, 0); - return preTx; - } catch (const std::exception&) { - set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing - return nullptr; - } -} +// // Deserializing the tx did not error. +// set_error(err, zcash_script_ERR_OK); +// // This is a pre-v5 tx, so the PrecomputedTransactionData constructor +// // field `allPrevOutputs` is not used. +// auto preTx = new PrecomputedTransaction(tx, nullptr, 0); +// return preTx; +// } catch (const std::exception&) { +// set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing +// return nullptr; +// } +// } -void* zcash_script_new_precomputed_tx_v5( - const unsigned char* txTo, - unsigned int txToLen, - const unsigned char* allPrevOutputs, - unsigned int allPrevOutputsLen, - zcash_script_error* err) -{ - CTransaction tx; - try { - const char* txToEnd = (const char*)(txTo + txToLen); - RustDataStream stream((const char*)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); - stream >> tx; - if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) { - set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); - return nullptr; - } - } catch (const std::exception&) { - set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing - return nullptr; - } +// void* zcash_script_new_precomputed_tx_v5( +// const unsigned char* txTo, +// unsigned int txToLen, +// const unsigned char* allPrevOutputs, +// unsigned int allPrevOutputsLen, +// zcash_script_error* err) +// { +// CTransaction tx; +// try { +// const char* txToEnd = (const char*)(txTo + txToLen); +// RustDataStream stream((const char*)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); +// stream >> tx; +// if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) { +// set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); +// return nullptr; +// } +// } catch (const std::exception&) { +// set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing +// return nullptr; +// } - try { - auto preTx = new PrecomputedTransaction(tx, allPrevOutputs, allPrevOutputsLen); - // Deserializing the tx did not error. - set_error(err, zcash_script_ERR_OK); - return preTx; - } catch (const std::exception&) { - // We had some error when parsing allPrevOutputs inside the - // PrecomputedTransactionData constructor. - set_error(err, zcash_script_ERR_ALL_PREV_OUTPUTS_DESERIALIZE); - return nullptr; - } -} +// try { +// auto preTx = new PrecomputedTransaction(tx, allPrevOutputs, allPrevOutputsLen); +// // Deserializing the tx did not error. +// set_error(err, zcash_script_ERR_OK); +// return preTx; +// } catch (const std::exception&) { +// // We had some error when parsing allPrevOutputs inside the +// // PrecomputedTransactionData constructor. +// set_error(err, zcash_script_ERR_ALL_PREV_OUTPUTS_DESERIALIZE); +// return nullptr; +// } +// } -void zcash_script_free_precomputed_tx(void* pre_preTx) -{ - PrecomputedTransaction* preTx = static_cast(pre_preTx); - delete preTx; - preTx = nullptr; -} +// void zcash_script_free_precomputed_tx(void* pre_preTx) +// { +// PrecomputedTransaction* preTx = static_cast(pre_preTx); +// delete preTx; +// preTx = nullptr; +// } -int zcash_script_verify_precomputed( - const void* pre_preTx, - unsigned int nIn, - const unsigned char* scriptPubKey, - unsigned int scriptPubKeyLen, - int64_t amount, - unsigned int flags, - uint32_t consensusBranchId, - zcash_script_error* err) -{ - const PrecomputedTransaction* preTx = static_cast(pre_preTx); - if (nIn >= preTx->tx.vin.size()) - return set_error(err, zcash_script_ERR_TX_INDEX); +// int zcash_script_verify_precomputed( +// const void* pre_preTx, +// unsigned int nIn, +// const unsigned char* scriptPubKey, +// unsigned int scriptPubKeyLen, +// int64_t amount, +// unsigned int flags, +// uint32_t consensusBranchId, +// zcash_script_error* err) +// { +// const PrecomputedTransaction* preTx = static_cast(pre_preTx); +// if (nIn >= preTx->tx.vin.size()) +// return set_error(err, zcash_script_ERR_TX_INDEX); - // Regardless of the verification result, the tx did not error. - set_error(err, zcash_script_ERR_OK); - return VerifyScript( - preTx->tx.vin[nIn].scriptSig, - CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), - flags, - TransactionSignatureChecker(&preTx->tx, preTx->txdata, nIn, amount), - consensusBranchId, - NULL); -} +// // Regardless of the verification result, the tx did not error. +// set_error(err, zcash_script_ERR_OK); +// return VerifyScript( +// preTx->tx.vin[nIn].scriptSig, +// CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), +// flags, +// TransactionSignatureChecker(&preTx->tx, preTx->txdata, nIn, amount), +// consensusBranchId, +// NULL); +// } + +// int zcash_script_verify( +// const unsigned char* scriptPubKey, +// unsigned int scriptPubKeyLen, +// int64_t amount, +// const unsigned char* txTo, +// unsigned int txToLen, +// unsigned int nIn, +// unsigned int flags, +// uint32_t consensusBranchId, +// zcash_script_error* err) +// { +// try { +// const char* txToEnd = (const char*)(txTo + txToLen); +// RustDataStream stream((const char*)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); +// CTransaction tx; +// stream >> tx; +// if (nIn >= tx.vin.size()) +// return set_error(err, zcash_script_ERR_TX_INDEX); +// if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) +// return set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); +// if (tx.nVersion >= ZIP225_TX_VERSION) { +// return set_error(err, zcash_script_ERR_TX_VERSION); +// } -int zcash_script_verify( +// // Regardless of the verification result, the tx did not error. +// set_error(err, zcash_script_ERR_OK); +// // This is a pre-v5 tx, so the PrecomputedTransactionData constructor +// // field `allPrevOutputs` is not used. +// PrecomputedTransactionData txdata(tx, {}); +// return VerifyScript( +// tx.vin[nIn].scriptSig, +// CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), +// flags, +// TransactionSignatureChecker(&tx, txdata, nIn, amount), +// consensusBranchId, +// NULL); +// } catch (const std::exception&) { +// return set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing +// } +// } + +int zcash_script_verify_prehashed( + const unsigned char* sighash, + unsigned int sighashLen, + int64_t nLockTime, + uint8_t isFinal, const unsigned char* scriptPubKey, unsigned int scriptPubKeyLen, + const unsigned char* scriptSig, + unsigned int scriptSigLen, int64_t amount, - const unsigned char* txTo, - unsigned int txToLen, unsigned int nIn, unsigned int flags, uint32_t consensusBranchId, zcash_script_error* err) { try { - const char* txToEnd = (const char*)(txTo + txToLen); - RustDataStream stream((const char*)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); - CTransaction tx; - stream >> tx; - if (nIn >= tx.vin.size()) - return set_error(err, zcash_script_ERR_TX_INDEX); - if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) - return set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); - if (tx.nVersion >= ZIP225_TX_VERSION) { - return set_error(err, zcash_script_ERR_TX_VERSION); - } - - // Regardless of the verification result, the tx did not error. set_error(err, zcash_script_ERR_OK); - // This is a pre-v5 tx, so the PrecomputedTransactionData constructor - // field `allPrevOutputs` is not used. - PrecomputedTransactionData txdata(tx, {}); - return VerifyScript( - tx.vin[nIn].scriptSig, + CScriptNum nLockTimeNum = CScriptNum(nLockTime); + ScriptError script_err = SCRIPT_ERR_OK; + bool r = VerifyScript( + CScript(scriptSig, scriptSig + scriptSigLen), CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), flags, - TransactionSignatureChecker(&tx, txdata, nIn, amount), + PrehashedTransactionSignatureChecker(sighash, sighashLen, nLockTimeNum, isFinal != 0, nIn, amount), consensusBranchId, - NULL); + &script_err); + if (!r) { + return set_error(err, (zcash_script_error_t)((zcash_script_error_t)1000 + (zcash_script_error_t)script_err)); + } + return r; } catch (const std::exception&) { - return set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing + return set_error(err, zcash_script_ERR_VERIFY_SCRIPT); // Error deserializing } } -int zcash_script_verify_prehashed( - const unsigned char* sighash, - unsigned int sighashLen, +int zcash_script_verify_callback( + const void* tx, + void (*sighash)(unsigned char* sighash, const void* tx, const unsigned char* scriptCode, unsigned int scriptCodeLen, int hashType), int64_t nLockTime, uint8_t isFinal, const unsigned char* scriptPubKey, @@ -200,112 +235,126 @@ int zcash_script_verify_prehashed( zcash_script_error* err) { try { + set_error(err, zcash_script_ERR_OK); CScriptNum nLockTimeNum = CScriptNum(nLockTime); - return VerifyScript( + ScriptError script_err = SCRIPT_ERR_OK; + bool r = VerifyScript( CScript(scriptSig, scriptSig + scriptSigLen), CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), flags, - PrehashedTransactionSignatureChecker(sighash, sighashLen, nLockTimeNum, isFinal != 0, nIn, amount), + CallbackTransactionSignatureChecker(tx, sighash, nLockTimeNum, isFinal != 0, nIn, amount), consensusBranchId, - NULL); + &script_err); + if (!r) { + return set_error(err, (zcash_script_error_t)((zcash_script_error_t)1000 + (zcash_script_error_t)script_err)); + } + return r; } catch (const std::exception&) { - return set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing + return set_error(err, zcash_script_ERR_VERIFY_SCRIPT); // Error deserializing } } -int zcash_script_verify_v5( - const unsigned char* txTo, - unsigned int txToLen, - const unsigned char* allPrevOutputs, - unsigned int allPrevOutputsLen, - unsigned int nIn, - unsigned int flags, - uint32_t consensusBranchId, - zcash_script_error* err) -{ - CTransaction tx; - try { - const char* txToEnd = (const char*)(txTo + txToLen); - RustDataStream stream((const char*)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); - stream >> tx; - if (nIn >= tx.vin.size()) - return set_error(err, zcash_script_ERR_TX_INDEX); - if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) - return set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); - } catch (const std::exception&) { - return set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing - } +// int zcash_script_verify_v5( +// const unsigned char* txTo, +// unsigned int txToLen, +// const unsigned char* allPrevOutputs, +// unsigned int allPrevOutputsLen, +// unsigned int nIn, +// unsigned int flags, +// uint32_t consensusBranchId, +// zcash_script_error* err) +// { +// CTransaction tx; +// try { +// const char* txToEnd = (const char*)(txTo + txToLen); +// RustDataStream stream((const char*)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); +// stream >> tx; +// if (nIn >= tx.vin.size()) +// return set_error(err, zcash_script_ERR_TX_INDEX); +// if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) +// return set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); +// } catch (const std::exception&) { +// return set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing +// } - std::vector prevOutputs; - try { - // TODO: we can swap this second deserialization for an FFI call by - // fetching this through PrecomputedTransactionData. Simplicity for now. - CDataStream sAllPrevOutputs( - reinterpret_cast(allPrevOutputs), - reinterpret_cast(allPrevOutputs + allPrevOutputsLen), - SER_NETWORK, - PROTOCOL_VERSION); - sAllPrevOutputs >> prevOutputs; - if (!(tx.IsCoinBase() ? prevOutputs.empty() : tx.vin.size() == prevOutputs.size())) { - return set_error(err, zcash_script_ERR_ALL_PREV_OUTPUTS_SIZE_MISMATCH); - } - } catch (const std::exception&) { - // We had some error when parsing allPrevOutputs inside the - // PrecomputedTransactionData constructor. - return set_error(err, zcash_script_ERR_ALL_PREV_OUTPUTS_DESERIALIZE); - } +// std::vector prevOutputs; +// try { +// // TODO: we can swap this second deserialization for an FFI call by +// // fetching this through PrecomputedTransactionData. Simplicity for now. +// CDataStream sAllPrevOutputs( +// reinterpret_cast(allPrevOutputs), +// reinterpret_cast(allPrevOutputs + allPrevOutputsLen), +// SER_NETWORK, +// PROTOCOL_VERSION); +// sAllPrevOutputs >> prevOutputs; +// if (!(tx.IsCoinBase() ? prevOutputs.empty() : tx.vin.size() == prevOutputs.size())) { +// return set_error(err, zcash_script_ERR_ALL_PREV_OUTPUTS_SIZE_MISMATCH); +// } +// } catch (const std::exception&) { +// // We had some error when parsing allPrevOutputs inside the +// // PrecomputedTransactionData constructor. +// return set_error(err, zcash_script_ERR_ALL_PREV_OUTPUTS_DESERIALIZE); +// } - try { - // Regardless of the verification result, the tx did not error. - set_error(err, zcash_script_ERR_OK); - PrecomputedTransactionData txdata(tx, allPrevOutputs, allPrevOutputsLen); - return VerifyScript( - tx.vin[nIn].scriptSig, - prevOutputs[nIn].scriptPubKey, - flags, - TransactionSignatureChecker(&tx, txdata, nIn, prevOutputs[nIn].nValue), - consensusBranchId, - NULL); - } catch (const std::exception&) { - return set_error(err, zcash_script_ERR_VERIFY_SCRIPT); // Error during script verification - } -} +// try { +// // Regardless of the verification result, the tx did not error. +// set_error(err, zcash_script_ERR_OK); +// PrecomputedTransactionData txdata(tx, allPrevOutputs, allPrevOutputsLen); +// return VerifyScript( +// tx.vin[nIn].scriptSig, +// prevOutputs[nIn].scriptPubKey, +// flags, +// TransactionSignatureChecker(&tx, txdata, nIn, prevOutputs[nIn].nValue), +// consensusBranchId, +// NULL); +// } catch (const std::exception&) { +// return set_error(err, zcash_script_ERR_VERIFY_SCRIPT); // Error during script verification +// } +// } -unsigned int zcash_script_legacy_sigop_count_precomputed( - const void* pre_preTx, - zcash_script_error* err) -{ - const PrecomputedTransaction* preTx = static_cast(pre_preTx); +// unsigned int zcash_script_legacy_sigop_count_precomputed( +// const void* pre_preTx, +// zcash_script_error* err) +// { +// const PrecomputedTransaction* preTx = static_cast(pre_preTx); - // The current implementation of this method never errors. - set_error(err, zcash_script_ERR_OK); +// // The current implementation of this method never errors. +// set_error(err, zcash_script_ERR_OK); - return GetLegacySigOpCount(preTx->tx); -} +// return GetLegacySigOpCount(preTx->tx); +// } -unsigned int zcash_script_legacy_sigop_count( - const unsigned char* txTo, - unsigned int txToLen, - zcash_script_error* err) -{ - try { - const char* txToEnd = (const char*)(txTo + txToLen); - RustDataStream stream((const char*)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); - CTransaction tx; - stream >> tx; - if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) { - set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); - return UINT_MAX; - } +// unsigned int zcash_script_legacy_sigop_count( +// const unsigned char* txTo, +// unsigned int txToLen, +// zcash_script_error* err) +// { +// try { +// const char* txToEnd = (const char*)(txTo + txToLen); +// RustDataStream stream((const char*)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); +// CTransaction tx; +// stream >> tx; +// if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) { +// set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); +// return UINT_MAX; +// } - // Deserializing the tx did not error. - set_error(err, zcash_script_ERR_OK); +// // Deserializing the tx did not error. +// set_error(err, zcash_script_ERR_OK); - return GetLegacySigOpCount(tx); - } catch (const std::exception&) { - set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing - return UINT_MAX; - } +// return GetLegacySigOpCount(tx); +// } catch (const std::exception&) { +// set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing +// return UINT_MAX; +// } +// } + +unsigned int zcash_script_legacy_sigop_count_script( + const unsigned char* script, + unsigned int scriptLen) +{ + CScript cscript = CScript(script, script + scriptLen); + return cscript.GetSigOpCount(false); } unsigned int zcash_script_version() diff --git a/depend/zcash/src/script/zcash_script.h b/depend/zcash/src/script/zcash_script.h index 3239a6c79..b5b145110 100644 --- a/depend/zcash/src/script/zcash_script.h +++ b/depend/zcash/src/script/zcash_script.h @@ -11,23 +11,23 @@ #if defined(BUILD_BITCOIN_INTERNAL) && defined(HAVE_CONFIG_H) #include "config/bitcoin-config.h" - #if defined(_WIN32) - #if defined(DLL_EXPORT) - #if defined(HAVE_FUNC_ATTRIBUTE_DLLEXPORT) - #define EXPORT_SYMBOL __declspec(dllexport) - #else - #define EXPORT_SYMBOL - #endif - #endif - #elif defined(HAVE_FUNC_ATTRIBUTE_VISIBILITY) - #define EXPORT_SYMBOL __attribute__ ((visibility ("default"))) - #endif +#if defined(_WIN32) +#if defined(DLL_EXPORT) +#if defined(HAVE_FUNC_ATTRIBUTE_DLLEXPORT) +#define EXPORT_SYMBOL __declspec(dllexport) +#else +#define EXPORT_SYMBOL +#endif +#endif +#elif defined(HAVE_FUNC_ATTRIBUTE_VISIBILITY) +#define EXPORT_SYMBOL __attribute__((visibility("default"))) +#endif #elif defined(MSC_VER) && !defined(STATIC_LIBZCASHCONSENSUS) - #define EXPORT_SYMBOL __declspec(dllimport) +#define EXPORT_SYMBOL __declspec(dllimport) #endif #ifndef EXPORT_SYMBOL - #define EXPORT_SYMBOL +#define EXPORT_SYMBOL #endif #ifdef __cplusplus @@ -36,8 +36,7 @@ extern "C" { #define ZCASH_SCRIPT_API_VER 3 -typedef enum zcash_script_error_t -{ +typedef enum zcash_script_error_t { zcash_script_ERR_OK = 0, zcash_script_ERR_TX_INDEX, zcash_script_ERR_TX_SIZE_MISMATCH, @@ -50,10 +49,9 @@ typedef enum zcash_script_error_t } zcash_script_error; /** Script verification flags */ -enum -{ - zcash_script_SCRIPT_FLAGS_VERIFY_NONE = 0, - zcash_script_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts +enum { + zcash_script_SCRIPT_FLAGS_VERIFY_NONE = 0, + zcash_script_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts zcash_script_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), // enable CHECKLOCKTIMEVERIFY (BIP65) }; @@ -69,10 +67,10 @@ enum /// after this function returns. /// /// If not NULL, err will contain an error/success code for the operation. -void* zcash_script_new_precomputed_tx( - const unsigned char* txTo, - unsigned int txToLen, - zcash_script_error* err); +// void* zcash_script_new_precomputed_tx( +// const unsigned char* txTo, +// unsigned int txToLen, +// zcash_script_error* err); /// Deserializes the given transaction and precomputes values to improve /// script verification performance. Must be used for V5 transactions; @@ -88,16 +86,16 @@ void* zcash_script_new_precomputed_tx( /// zcash_script_free_precomputed_tx once you are done. /// /// If not NULL, err will contain an error/success code for the operation. -void* zcash_script_new_precomputed_tx_v5( - const unsigned char* txTo, - unsigned int txToLen, - const unsigned char* allPrevOutputs, - unsigned int allPrevOutputsLen, - zcash_script_error* err); +// void* zcash_script_new_precomputed_tx_v5( +// const unsigned char* txTo, +// unsigned int txToLen, +// const unsigned char* allPrevOutputs, +// unsigned int allPrevOutputsLen, +// zcash_script_error* err); /// Frees a precomputed transaction previously created with /// zcash_script_new_precomputed_tx. -void zcash_script_free_precomputed_tx(void* preTx); +// void zcash_script_free_precomputed_tx(void* preTx); /// Returns 1 if the input nIn of the precomputed transaction pointed to by /// preTx correctly spends the scriptPubKey pointed to by scriptPubKey under @@ -106,15 +104,15 @@ void zcash_script_free_precomputed_tx(void* preTx); /// If not NULL, err will contain an error/success code for the operation. /// Note that script verification failure is indicated by err being set to /// zcash_script_ERR_OK and a return value of 0. -EXPORT_SYMBOL int zcash_script_verify_precomputed( - const void* preTx, - unsigned int nIn, - const unsigned char* scriptPubKey, - unsigned int scriptPubKeyLen, - int64_t amount, - unsigned int flags, - uint32_t consensusBranchId, - zcash_script_error* err); +// EXPORT_SYMBOL int zcash_script_verify_precomputed( +// const void* preTx, +// unsigned int nIn, +// const unsigned char* scriptPubKey, +// unsigned int scriptPubKeyLen, +// int64_t amount, +// unsigned int flags, +// uint32_t consensusBranchId, +// zcash_script_error* err); /// Returns 1 if the input nIn of the serialized transaction pointed to by /// txTo correctly spends the scriptPubKey pointed to by scriptPubKey under @@ -125,13 +123,16 @@ EXPORT_SYMBOL int zcash_script_verify_precomputed( /// If not NULL, err will contain an error/success code for the operation. /// Note that script verification failure is indicated by err being set to /// zcash_script_ERR_OK and a return value of 0. -EXPORT_SYMBOL int zcash_script_verify( - const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, - int64_t amount, - const unsigned char *txTo, unsigned int txToLen, - unsigned int nIn, unsigned int flags, - uint32_t consensusBranchId, - zcash_script_error* err); +// EXPORT_SYMBOL int zcash_script_verify( +// const unsigned char* scriptPubKey, +// unsigned int scriptPubKeyLen, +// int64_t amount, +// const unsigned char* txTo, +// unsigned int txToLen, +// unsigned int nIn, +// unsigned int flags, +// uint32_t consensusBranchId, +// zcash_script_error* err); EXPORT_SYMBOL int zcash_script_verify_prehashed( const unsigned char* sighash, @@ -148,6 +149,21 @@ EXPORT_SYMBOL int zcash_script_verify_prehashed( uint32_t consensusBranchId, zcash_script_error* err); +EXPORT_SYMBOL int zcash_script_verify_callback( + const void* tx, + void (*sighash)(unsigned char* sighash, const void* tx, const unsigned char* scriptCode, unsigned int scriptCodeLen, int hashType), + int64_t nLockTime, + uint8_t isFinal, + const unsigned char* scriptPubKey, + unsigned int scriptPubKeyLen, + const unsigned char* scriptSig, + unsigned int scriptSigLen, + int64_t amount, + unsigned int nIn, + unsigned int flags, + uint32_t consensusBranchId, + zcash_script_error* err); + /// Returns 1 if the input nIn of the serialized transaction pointed to by /// txTo correctly spends the matching output in allPrevOutputs under /// the additional constraints specified by flags. Must be used for V5 transactions; @@ -162,15 +178,15 @@ EXPORT_SYMBOL int zcash_script_verify_prehashed( /// If not NULL, err will contain an error/success code for the operation. /// Note that script verification failure is indicated by err being set to /// zcash_script_ERR_OK and a return value of 0. -EXPORT_SYMBOL int zcash_script_verify_v5( - const unsigned char* txTo, - unsigned int txToLen, - const unsigned char* allPrevOutputs, - unsigned int allPrevOutputsLen, - unsigned int nIn, - unsigned int flags, - uint32_t consensusBranchId, - zcash_script_error* err); +// EXPORT_SYMBOL int zcash_script_verify_v5( +// const unsigned char* txTo, +// unsigned int txToLen, +// const unsigned char* allPrevOutputs, +// unsigned int allPrevOutputsLen, +// unsigned int nIn, +// unsigned int flags, +// uint32_t consensusBranchId, +// zcash_script_error* err); /// Returns the number of transparent signature operations in the /// transparent inputs and outputs of the precomputed transaction @@ -178,9 +194,9 @@ EXPORT_SYMBOL int zcash_script_verify_v5( /// /// Returns UINT_MAX on error, so that invalid transactions don't pass the Zcash consensus rules. /// If not NULL, err will contain an error/success code for the operation. -EXPORT_SYMBOL unsigned int zcash_script_legacy_sigop_count_precomputed( - const void* preTx, - zcash_script_error* err); +// EXPORT_SYMBOL unsigned int zcash_script_legacy_sigop_count_precomputed( +// const void* preTx, +// zcash_script_error* err); /// Returns the number of transparent signature operations in the /// transparent inputs and outputs of the serialized transaction @@ -188,10 +204,14 @@ EXPORT_SYMBOL unsigned int zcash_script_legacy_sigop_count_precomputed( /// /// Returns UINT_MAX on error. /// If not NULL, err will contain an error/success code for the operation. -EXPORT_SYMBOL unsigned int zcash_script_legacy_sigop_count( - const unsigned char *txTo, - unsigned int txToLen, - zcash_script_error* err); +// EXPORT_SYMBOL unsigned int zcash_script_legacy_sigop_count( +// const unsigned char* txTo, +// unsigned int txToLen, +// zcash_script_error* err); + +EXPORT_SYMBOL unsigned int zcash_script_legacy_sigop_count_script( + const unsigned char* script, + unsigned int scriptLen); /// Returns the current version of the zcash_script library. EXPORT_SYMBOL unsigned int zcash_script_version(); diff --git a/src/lib.rs b/src/lib.rs index cd39a5d94..f9d8af635 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,61 +14,61 @@ // Use the generated C++ bindings include!(concat!(env!("OUT_DIR"), "/bindings.rs")); -// Include the items from depend/zcash/src/rust/src/rustzcash.rs (librustzcash/lib.rs) -// that we need +// // Include the items from depend/zcash/src/rust/src/rustzcash.rs (librustzcash/lib.rs) +// // that we need use ::sapling::circuit::{ OutputParameters, OutputVerifyingKey, SpendParameters, SpendVerifyingKey, }; -/// The code that uses this constant is not called by zcash_script. -static mut SAPLING_SPEND_VK: Option = None; -/// The code that uses this constant is not called by zcash_script. -static mut SAPLING_OUTPUT_VK: Option = None; -/// The code that uses this constant is not called by zcash_script. -static mut SAPLING_SPEND_PARAMS: Option = None; -/// The code that uses this constant is not called by zcash_script. -static mut SAPLING_OUTPUT_PARAMS: Option = None; - -/// The code that uses this constant is not called by zcash_script. -static mut ORCHARD_PK: Option = None; -/// The code that uses this constant is not called by zcash_script. -static mut ORCHARD_VK: Option = None; - -/// Converts CtOption into Option -fn de_ct(ct: subtle::CtOption) -> Option { - if ct.is_some().into() { - Some(ct.unwrap()) - } else { - None - } -} - -/// The size of a Groth16 Sapling proof. -const GROTH_PROOF_SIZE: usize = 48 // π_A - + 96 // π_B - + 48; // π_C +// /// The code that uses this constant is not called by zcash_script. +// static mut SAPLING_SPEND_VK: Option = None; +// /// The code that uses this constant is not called by zcash_script. +// static mut SAPLING_OUTPUT_VK: Option = None; +// /// The code that uses this constant is not called by zcash_script. +// static mut SAPLING_SPEND_PARAMS: Option = None; +// /// The code that uses this constant is not called by zcash_script. +// static mut SAPLING_OUTPUT_PARAMS: Option = None; + +// /// The code that uses this constant is not called by zcash_script. +// static mut ORCHARD_PK: Option = None; +// /// The code that uses this constant is not called by zcash_script. +// static mut ORCHARD_VK: Option = None; + +// /// Converts CtOption into Option +// fn de_ct(ct: subtle::CtOption) -> Option { +// if ct.is_some().into() { +// Some(ct.unwrap()) +// } else { +// None +// } +// } + +// /// The size of a Groth16 Sapling proof. +// const GROTH_PROOF_SIZE: usize = 48 // π_A +// + 96 // π_B +// + 48; // π_C // Include the modules from depend/zcash/src/rust (librustzcash) that we need -mod blake2b; -mod bridge; -mod bundlecache; -mod incremental_merkle_tree; -mod merkle_frontier; -mod note_encryption; -mod orchard_bundle; -mod params; -mod sapling; -mod streams; -mod test_harness_ffi; -mod wallet; -mod wallet_scanner; -mod zcashd_orchard; - -mod builder_ffi; -mod orchard_ffi; -mod streams_ffi; -mod transaction_ffi; +// mod blake2b; +// mod bridge; +// mod bundlecache; +// mod incremental_merkle_tree; +// mod merkle_frontier; +// mod note_encryption; +// mod orchard_bundle; +// mod params; +// mod sapling; +// mod streams; +// mod test_harness_ffi; +// mod wallet; +// mod wallet_scanner; +// mod zcashd_orchard; + +// mod builder_ffi; +// mod orchard_ffi; +// mod streams_ffi; +// mod transaction_ffi; #[cfg(test)] mod tests { From 132d58f5ea5fc78692a53289e6e54c4b5a56639f Mon Sep 17 00:00:00 2001 From: Conrado Gouvea Date: Wed, 22 May 2024 16:44:06 -0300 Subject: [PATCH 03/16] revert formatting changes to interpreter.cpp/.h --- depend/zcash/src/script/interpreter.cpp | 570 ++++++++++++------------ depend/zcash/src/script/interpreter.h | 36 +- 2 files changed, 307 insertions(+), 299 deletions(-) diff --git a/depend/zcash/src/script/interpreter.cpp b/depend/zcash/src/script/interpreter.cpp index ce0d82f19..91fe0a18f 100644 --- a/depend/zcash/src/script/interpreter.cpp +++ b/depend/zcash/src/script/interpreter.cpp @@ -7,10 +7,10 @@ #include "interpreter.h" #include "consensus/upgrades.h" +#include "primitives/transaction.h" #include "crypto/ripemd160.h" #include "crypto/sha1.h" #include "crypto/sha256.h" -#include "primitives/transaction.h" #include "pubkey.h" #include "script/script.h" #include "uint256.h" @@ -23,8 +23,7 @@ using namespace std; typedef vector valtype; -namespace -{ +namespace { inline bool set_success(ScriptError* ret) { @@ -40,14 +39,16 @@ inline bool set_error(ScriptError* ret, const ScriptError serror) return false; } -} // namespace +} // anon namespace bool CastToBool(const valtype& vch) { - for (unsigned int i = 0; i < vch.size(); i++) { - if (vch[i] != 0) { + for (unsigned int i = 0; i < vch.size(); i++) + { + if (vch[i] != 0) + { // Can be negative zero - if (i == vch.size() - 1 && vch[i] == 0x80) + if (i == vch.size()-1 && vch[i] == 0x80) return false; return true; } @@ -59,8 +60,8 @@ bool CastToBool(const valtype& vch) * Script is a stack machine (like Forth) that evaluates a predicate * returning a bool indicating valid or not. There are no loops. */ -#define stacktop(i) (stack.at(stack.size() + (i))) -#define altstacktop(i) (altstack.at(altstack.size() + (i))) +#define stacktop(i) (stack.at(stack.size()+(i))) +#define altstacktop(i) (altstack.at(altstack.size()+(i))) static inline void popstack(vector& stack) { if (stack.empty()) @@ -68,8 +69,7 @@ static inline void popstack(vector& stack) stack.pop_back(); } -bool static IsCompressedOrUncompressedPubKey(const valtype& vchPubKey) -{ +bool static IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) { if (vchPubKey.size() < CPubKey::COMPRESSED_PUBLIC_KEY_SIZE) { // Non-canonical public key: too short return false; @@ -85,8 +85,8 @@ bool static IsCompressedOrUncompressedPubKey(const valtype& vchPubKey) return false; } } else { - // Non-canonical public key: neither compressed nor uncompressed - return false; + // Non-canonical public key: neither compressed nor uncompressed + return false; } return true; } @@ -101,8 +101,7 @@ bool static IsCompressedOrUncompressedPubKey(const valtype& vchPubKey) * * This function is consensus-critical since BIP66. */ -bool static IsValidSignatureEncoding(const std::vector& sig) -{ +bool static IsValidSignatureEncoding(const std::vector &sig) { // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] [sighash] // * total-length: 1-byte length descriptor of everything that follows, // excluding the sighash byte. @@ -116,73 +115,58 @@ bool static IsValidSignatureEncoding(const std::vector& sig) // signature) // Minimum and maximum size constraints. - if (sig.size() < 9) - return false; - if (sig.size() > 73) - return false; + if (sig.size() < 9) return false; + if (sig.size() > 73) return false; // A signature is of type 0x30 (compound). - if (sig[0] != 0x30) - return false; + if (sig[0] != 0x30) return false; // Make sure the length covers the entire signature. - if (sig[1] != sig.size() - 3) - return false; + if (sig[1] != sig.size() - 3) return false; // Extract the length of the R element. unsigned int lenR = sig[3]; // Make sure the length of the S element is still inside the signature. - if (5 + lenR >= sig.size()) - return false; + if (5 + lenR >= sig.size()) return false; // Extract the length of the S element. unsigned int lenS = sig[5 + lenR]; // Verify that the length of the signature matches the sum of the length // of the elements. - if ((size_t)(lenR + lenS + 7) != sig.size()) - return false; + if ((size_t)(lenR + lenS + 7) != sig.size()) return false; // Check whether the R element is an integer. - if (sig[2] != 0x02) - return false; + if (sig[2] != 0x02) return false; // Zero-length integers are not allowed for R. - if (lenR == 0) - return false; + if (lenR == 0) return false; // Negative numbers are not allowed for R. - if (sig[4] & 0x80) - return false; + if (sig[4] & 0x80) return false; // Null bytes at the start of R are not allowed, unless R would // otherwise be interpreted as a negative number. - if (lenR > 1 && (sig[4] == 0x00) && !(sig[5] & 0x80)) - return false; + if (lenR > 1 && (sig[4] == 0x00) && !(sig[5] & 0x80)) return false; // Check whether the S element is an integer. - if (sig[lenR + 4] != 0x02) - return false; + if (sig[lenR + 4] != 0x02) return false; // Zero-length integers are not allowed for S. - if (lenS == 0) - return false; + if (lenS == 0) return false; // Negative numbers are not allowed for S. - if (sig[lenR + 6] & 0x80) - return false; + if (sig[lenR + 6] & 0x80) return false; // Null bytes at the start of S are not allowed, unless S would otherwise be // interpreted as a negative number. - if (lenS > 1 && (sig[lenR + 6] == 0x00) && !(sig[lenR + 7] & 0x80)) - return false; + if (lenS > 1 && (sig[lenR + 6] == 0x00) && !(sig[lenR + 7] & 0x80)) return false; return true; } -bool static IsLowDERSignature(const valtype& vchSig, ScriptError* serror) -{ +bool static IsLowDERSignature(const valtype &vchSig, ScriptError* serror) { if (!IsValidSignatureEncoding(vchSig)) { return set_error(serror, SCRIPT_ERR_SIG_DER); } @@ -196,8 +180,7 @@ bool static IsLowDERSignature(const valtype& vchSig, ScriptError* serror) return CPubKey::CheckLowS(vchSigCopy); } -bool static IsDefinedHashtypeSignature(const valtype& vchSig) -{ +bool static IsDefinedHashtypeSignature(const valtype &vchSig) { if (vchSig.size() == 0) { return false; } @@ -208,8 +191,7 @@ bool static IsDefinedHashtypeSignature(const valtype& vchSig) return true; } -bool CheckSignatureEncoding(const vector& vchSig, unsigned int flags, ScriptError* serror) -{ +bool CheckSignatureEncoding(const vector &vchSig, unsigned int flags, ScriptError* serror) { // Empty signature. Not strictly DER encoded, but allowed to provide a // compact way to provide an invalid signature for use with CHECK(MULTI)SIG if (vchSig.size() == 0) { @@ -226,16 +208,14 @@ bool CheckSignatureEncoding(const vector& vchSig, unsigned int fl return true; } -bool static CheckPubKeyEncoding(const valtype& vchSig, unsigned int flags, ScriptError* serror) -{ +bool static CheckPubKeyEncoding(const valtype &vchSig, unsigned int flags, ScriptError* serror) { if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsCompressedOrUncompressedPubKey(vchSig)) { return set_error(serror, SCRIPT_ERR_PUBKEYTYPE); } return true; } -bool static CheckMinimalPush(const valtype& data, opcodetype opcode) -{ +bool static CheckMinimalPush(const valtype& data, opcodetype opcode) { if (data.size() == 0) { // Could have used OP_0. return opcode == OP_0; @@ -259,7 +239,7 @@ bool static CheckMinimalPush(const valtype& data, opcodetype opcode) } bool EvalScript( - vector>& stack, + vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, @@ -286,8 +266,10 @@ bool EvalScript( int nOpCount = 0; bool fRequireMinimal = (flags & SCRIPT_VERIFY_MINIMALDATA) != 0; - try { - while (pc < pend) { + try + { + while (pc < pend) + { bool fExec = !count(vfExec.begin(), vfExec.end(), false); // @@ -326,7 +308,8 @@ bool EvalScript( } stack.push_back(vchPushValue); } else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF)) - switch (opcode) { + switch (opcode) + { // // Push value // @@ -346,13 +329,15 @@ bool EvalScript( case OP_13: case OP_14: case OP_15: - case OP_16: { + case OP_16: + { // ( -- value) CScriptNum bn((int)opcode - (int)(OP_1 - 1)); stack.push_back(bn.getvch()); // The result of these opcodes should always be the minimal way to push the data // they push, so no need for a CheckMinimalPush here. - } break; + } + break; // @@ -361,7 +346,8 @@ bool EvalScript( case OP_NOP: break; - case OP_CHECKLOCKTIMEVERIFY: { + case OP_CHECKLOCKTIMEVERIFY: + { if (!(flags & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)) { // not enabled; treat as a NOP2 if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) { @@ -402,24 +388,21 @@ bool EvalScript( break; } - case OP_NOP1: - case OP_NOP3: - case OP_NOP4: - case OP_NOP5: - case OP_NOP6: - case OP_NOP7: - case OP_NOP8: - case OP_NOP9: - case OP_NOP10: { + case OP_NOP1: case OP_NOP3: case OP_NOP4: case OP_NOP5: + case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10: + { if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS); - } break; + } + break; case OP_IF: - case OP_NOTIF: { + case OP_NOTIF: + { // if [statements] [else [statements]] endif bool fValue = false; - if (fExec) { + if (fExec) + { if (stack.size() < 1) return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); valtype& vch = stacktop(-1); @@ -429,21 +412,27 @@ bool EvalScript( popstack(stack); } vfExec.push_back(fValue); - } break; + } + break; - case OP_ELSE: { + case OP_ELSE: + { if (vfExec.empty()) return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); vfExec.back() = !vfExec.back(); - } break; + } + break; - case OP_ENDIF: { + case OP_ENDIF: + { if (vfExec.empty()) return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); vfExec.pop_back(); - } break; + } + break; - case OP_VERIFY: { + case OP_VERIFY: + { // (true -- ) or // (false -- false) and return if (stack.size() < 1) @@ -453,39 +442,49 @@ bool EvalScript( popstack(stack); else return set_error(serror, SCRIPT_ERR_VERIFY); - } break; + } + break; - case OP_RETURN: { + case OP_RETURN: + { return set_error(serror, SCRIPT_ERR_OP_RETURN); - } break; + } + break; // // Stack ops // - case OP_TOALTSTACK: { + case OP_TOALTSTACK: + { if (stack.size() < 1) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); altstack.push_back(stacktop(-1)); popstack(stack); - } break; + } + break; - case OP_FROMALTSTACK: { + case OP_FROMALTSTACK: + { if (altstack.size() < 1) return set_error(serror, SCRIPT_ERR_INVALID_ALTSTACK_OPERATION); stack.push_back(altstacktop(-1)); popstack(altstack); - } break; + } + break; - case OP_2DROP: { + case OP_2DROP: + { // (x1 x2 -- ) if (stack.size() < 2) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); popstack(stack); popstack(stack); - } break; + } + break; - case OP_2DUP: { + case OP_2DUP: + { // (x1 x2 -- x1 x2 x1 x2) if (stack.size() < 2) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); @@ -493,9 +492,11 @@ bool EvalScript( valtype vch2 = stacktop(-1); stack.push_back(vch1); stack.push_back(vch2); - } break; + } + break; - case OP_3DUP: { + case OP_3DUP: + { // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3) if (stack.size() < 3) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); @@ -505,9 +506,11 @@ bool EvalScript( stack.push_back(vch1); stack.push_back(vch2); stack.push_back(vch3); - } break; + } + break; - case OP_2OVER: { + case OP_2OVER: + { // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2) if (stack.size() < 4) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); @@ -515,74 +518,92 @@ bool EvalScript( valtype vch2 = stacktop(-3); stack.push_back(vch1); stack.push_back(vch2); - } break; + } + break; - case OP_2ROT: { + case OP_2ROT: + { // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2) if (stack.size() < 6) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch1 = stacktop(-6); valtype vch2 = stacktop(-5); - stack.erase(stack.end() - 6, stack.end() - 4); + stack.erase(stack.end()-6, stack.end()-4); stack.push_back(vch1); stack.push_back(vch2); - } break; + } + break; - case OP_2SWAP: { + case OP_2SWAP: + { // (x1 x2 x3 x4 -- x3 x4 x1 x2) if (stack.size() < 4) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); swap(stacktop(-4), stacktop(-2)); swap(stacktop(-3), stacktop(-1)); - } break; + } + break; - case OP_IFDUP: { + case OP_IFDUP: + { // (x - 0 | x x) if (stack.size() < 1) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch = stacktop(-1); if (CastToBool(vch)) stack.push_back(vch); - } break; + } + break; - case OP_DEPTH: { + case OP_DEPTH: + { // -- stacksize CScriptNum bn(stack.size()); stack.push_back(bn.getvch()); - } break; + } + break; - case OP_DROP: { + case OP_DROP: + { // (x -- ) if (stack.size() < 1) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); popstack(stack); - } break; + } + break; - case OP_DUP: { + case OP_DUP: + { // (x -- x x) if (stack.size() < 1) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch = stacktop(-1); stack.push_back(vch); - } break; + } + break; - case OP_NIP: { + case OP_NIP: + { // (x1 x2 -- x2) if (stack.size() < 2) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); stack.erase(stack.end() - 2); - } break; + } + break; - case OP_OVER: { + case OP_OVER: + { // (x1 x2 -- x1 x2 x1) if (stack.size() < 2) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch = stacktop(-2); stack.push_back(vch); - } break; + } + break; case OP_PICK: - case OP_ROLL: { + case OP_ROLL: + { // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn) // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn) if (stack.size() < 2) @@ -591,13 +612,15 @@ bool EvalScript( popstack(stack); if (n < 0 || n >= (int)stack.size()) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - valtype vch = stacktop(-n - 1); + valtype vch = stacktop(-n-1); if (opcode == OP_ROLL) - stack.erase(stack.end() - n - 1); + stack.erase(stack.end()-n-1); stack.push_back(vch); - } break; + } + break; - case OP_ROT: { + case OP_ROT: + { // (x1 x2 x3 -- x2 x3 x1) // x2 x1 x3 after first swap // x2 x3 x1 after second swap @@ -605,31 +628,38 @@ bool EvalScript( return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); swap(stacktop(-3), stacktop(-2)); swap(stacktop(-2), stacktop(-1)); - } break; + } + break; - case OP_SWAP: { + case OP_SWAP: + { // (x1 x2 -- x2 x1) if (stack.size() < 2) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); swap(stacktop(-2), stacktop(-1)); - } break; + } + break; - case OP_TUCK: { + case OP_TUCK: + { // (x1 x2 -- x2 x1 x2) if (stack.size() < 2) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch = stacktop(-1); - stack.insert(stack.end() - 2, vch); - } break; + stack.insert(stack.end()-2, vch); + } + break; - case OP_SIZE: { + case OP_SIZE: + { // (in -- in size) if (stack.size() < 1) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); CScriptNum bn(stacktop(-1).size()); stack.push_back(bn.getvch()); - } break; + } + break; // @@ -637,30 +667,31 @@ bool EvalScript( // case OP_EQUAL: case OP_EQUALVERIFY: - // case OP_NOTEQUAL: // use OP_NUMNOTEQUAL + //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL + { + // (x1 x2 - bool) + if (stack.size() < 2) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype& vch1 = stacktop(-2); + valtype& vch2 = stacktop(-1); + bool fEqual = (vch1 == vch2); + // OP_NOTEQUAL is disabled because it would be too easy to say + // something like n != 1 and have some wiseguy pass in 1 with extra + // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001) + //if (opcode == OP_NOTEQUAL) + // fEqual = !fEqual; + popstack(stack); + popstack(stack); + stack.push_back(fEqual ? vchTrue : vchFalse); + if (opcode == OP_EQUALVERIFY) { - // (x1 x2 - bool) - if (stack.size() < 2) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - valtype& vch1 = stacktop(-2); - valtype& vch2 = stacktop(-1); - bool fEqual = (vch1 == vch2); - // OP_NOTEQUAL is disabled because it would be too easy to say - // something like n != 1 and have some wiseguy pass in 1 with extra - // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001) - // if (opcode == OP_NOTEQUAL) - // fEqual = !fEqual; - popstack(stack); - popstack(stack); - stack.push_back(fEqual ? vchTrue : vchFalse); - if (opcode == OP_EQUALVERIFY) { - if (fEqual) - popstack(stack); - else - return set_error(serror, SCRIPT_ERR_EQUALVERIFY); - } + if (fEqual) + popstack(stack); + else + return set_error(serror, SCRIPT_ERR_EQUALVERIFY); } - break; + } + break; // @@ -671,38 +702,26 @@ bool EvalScript( case OP_NEGATE: case OP_ABS: case OP_NOT: - case OP_0NOTEQUAL: { + case OP_0NOTEQUAL: + { // (in -- out) if (stack.size() < 1) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); CScriptNum bn(stacktop(-1), fRequireMinimal); - switch (opcode) { - case OP_1ADD: - bn += bnOne; - break; - case OP_1SUB: - bn -= bnOne; - break; - case OP_NEGATE: - bn = -bn; - break; - case OP_ABS: - if (bn < bnZero) - bn = -bn; - break; - case OP_NOT: - bn = (bn == bnZero); - break; - case OP_0NOTEQUAL: - bn = (bn != bnZero); - break; - default: - assert(!"invalid opcode"); - break; + switch (opcode) + { + case OP_1ADD: bn += bnOne; break; + case OP_1SUB: bn -= bnOne; break; + case OP_NEGATE: bn = -bn; break; + case OP_ABS: if (bn < bnZero) bn = -bn; break; + case OP_NOT: bn = (bn == bnZero); break; + case OP_0NOTEQUAL: bn = (bn != bnZero); break; + default: assert(!"invalid opcode"); break; } popstack(stack); stack.push_back(bn.getvch()); - } break; + } + break; case OP_ADD: case OP_SUB: @@ -716,14 +735,16 @@ bool EvalScript( case OP_LESSTHANOREQUAL: case OP_GREATERTHANOREQUAL: case OP_MIN: - case OP_MAX: { + case OP_MAX: + { // (x1 x2 -- out) if (stack.size() < 2) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); CScriptNum bn1(stacktop(-2), fRequireMinimal); CScriptNum bn2(stacktop(-1), fRequireMinimal); CScriptNum bn(0); - switch (opcode) { + switch (opcode) + { case OP_ADD: bn = bn1 + bn2; break; @@ -732,56 +753,35 @@ bool EvalScript( bn = bn1 - bn2; break; - case OP_BOOLAND: - bn = (bn1 != bnZero && bn2 != bnZero); - break; - case OP_BOOLOR: - bn = (bn1 != bnZero || bn2 != bnZero); - break; - case OP_NUMEQUAL: - bn = (bn1 == bn2); - break; - case OP_NUMEQUALVERIFY: - bn = (bn1 == bn2); - break; - case OP_NUMNOTEQUAL: - bn = (bn1 != bn2); - break; - case OP_LESSTHAN: - bn = (bn1 < bn2); - break; - case OP_GREATERTHAN: - bn = (bn1 > bn2); - break; - case OP_LESSTHANOREQUAL: - bn = (bn1 <= bn2); - break; - case OP_GREATERTHANOREQUAL: - bn = (bn1 >= bn2); - break; - case OP_MIN: - bn = (bn1 < bn2 ? bn1 : bn2); - break; - case OP_MAX: - bn = (bn1 > bn2 ? bn1 : bn2); - break; - default: - assert(!"invalid opcode"); - break; + case OP_BOOLAND: bn = (bn1 != bnZero && bn2 != bnZero); break; + case OP_BOOLOR: bn = (bn1 != bnZero || bn2 != bnZero); break; + case OP_NUMEQUAL: bn = (bn1 == bn2); break; + case OP_NUMEQUALVERIFY: bn = (bn1 == bn2); break; + case OP_NUMNOTEQUAL: bn = (bn1 != bn2); break; + case OP_LESSTHAN: bn = (bn1 < bn2); break; + case OP_GREATERTHAN: bn = (bn1 > bn2); break; + case OP_LESSTHANOREQUAL: bn = (bn1 <= bn2); break; + case OP_GREATERTHANOREQUAL: bn = (bn1 >= bn2); break; + case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break; + case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break; + default: assert(!"invalid opcode"); break; } popstack(stack); popstack(stack); stack.push_back(bn.getvch()); - if (opcode == OP_NUMEQUALVERIFY) { + if (opcode == OP_NUMEQUALVERIFY) + { if (CastToBool(stacktop(-1))) popstack(stack); else return set_error(serror, SCRIPT_ERR_NUMEQUALVERIFY); } - } break; + } + break; - case OP_WITHIN: { + case OP_WITHIN: + { // (x min max -- out) if (stack.size() < 3) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); @@ -793,7 +793,8 @@ bool EvalScript( popstack(stack); popstack(stack); stack.push_back(fValue ? vchTrue : vchFalse); - } break; + } + break; // @@ -803,7 +804,8 @@ bool EvalScript( case OP_SHA1: case OP_SHA256: case OP_HASH160: - case OP_HASH256: { + case OP_HASH256: + { // (in -- hash) if (stack.size() < 1) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); @@ -821,19 +823,21 @@ bool EvalScript( CHash256().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash)); popstack(stack); stack.push_back(vchHash); - } break; + } + break; case OP_CHECKSIG: - case OP_CHECKSIGVERIFY: { + case OP_CHECKSIGVERIFY: + { // (sig pubkey -- bool) if (stack.size() < 2) return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - valtype& vchSig = stacktop(-2); + valtype& vchSig = stacktop(-2); valtype& vchPubKey = stacktop(-1); if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) { - // serror is set + //serror is set return false; } bool fSuccess = checker.CheckSig(vchSig, vchPubKey, script, consensusBranchId); @@ -841,16 +845,19 @@ bool EvalScript( popstack(stack); popstack(stack); stack.push_back(fSuccess ? vchTrue : vchFalse); - if (opcode == OP_CHECKSIGVERIFY) { + if (opcode == OP_CHECKSIGVERIFY) + { if (fSuccess) popstack(stack); else return set_error(serror, SCRIPT_ERR_CHECKSIGVERIFY); } - } break; + } + break; case OP_CHECKMULTISIG: - case OP_CHECKMULTISIGVERIFY: { + case OP_CHECKMULTISIGVERIFY: + { // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool) int i = 1; @@ -877,8 +884,9 @@ bool EvalScript( return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); bool fSuccess = true; - while (fSuccess && nSigsCount > 0) { - valtype& vchSig = stacktop(-isig); + while (fSuccess && nSigsCount > 0) + { + valtype& vchSig = stacktop(-isig); valtype& vchPubKey = stacktop(-ikey); // Note how this makes the exact order of pubkey/signature evaluation @@ -924,23 +932,27 @@ bool EvalScript( stack.push_back(fSuccess ? vchTrue : vchFalse); - if (opcode == OP_CHECKMULTISIGVERIFY) { + if (opcode == OP_CHECKMULTISIGVERIFY) + { if (fSuccess) popstack(stack); else return set_error(serror, SCRIPT_ERR_CHECKMULTISIGVERIFY); } - } break; + } + break; default: return set_error(serror, SCRIPT_ERR_BAD_OPCODE); - } + } // Size limits if (stack.size() + altstack.size() > 1000) return set_error(serror, SCRIPT_ERR_STACK_SIZE); } - } catch (...) { + } + catch (...) + { return set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); } @@ -950,15 +962,13 @@ bool EvalScript( return set_success(serror); } -namespace -{ +namespace { /** * Wrapper that serializes like CTransaction, but with the modifications * required for the signature hash done in-place */ -class CTransactionSignatureSerializer -{ +class CTransactionSignatureSerializer { private: const CTransaction& txTo; //!< reference to the spending transaction (the one being serialized) const CScript& scriptCode; //!< output script being consumed @@ -968,24 +978,23 @@ class CTransactionSignatureSerializer const bool fHashNone; //!< whether the hashtype is SIGHASH_NONE public: - CTransactionSignatureSerializer(const CTransaction& txToIn, const CScript& scriptCodeIn, unsigned int nInIn, int nHashTypeIn) : txTo(txToIn), scriptCode(scriptCodeIn), nIn(nInIn), - fAnyoneCanPay(!!(nHashTypeIn & SIGHASH_ANYONECANPAY)), - fHashSingle((nHashTypeIn & 0x1f) == SIGHASH_SINGLE), - fHashNone((nHashTypeIn & 0x1f) == SIGHASH_NONE) {} + CTransactionSignatureSerializer(const CTransaction &txToIn, const CScript &scriptCodeIn, unsigned int nInIn, int nHashTypeIn) : + txTo(txToIn), scriptCode(scriptCodeIn), nIn(nInIn), + fAnyoneCanPay(!!(nHashTypeIn & SIGHASH_ANYONECANPAY)), + fHashSingle((nHashTypeIn & 0x1f) == SIGHASH_SINGLE), + fHashNone((nHashTypeIn & 0x1f) == SIGHASH_NONE) {} /** Serialize the passed scriptCode */ - template - void SerializeScriptCode(S& s) const - { + template + void SerializeScriptCode(S &s) const { auto size = scriptCode.size(); ::WriteCompactSize(s, size); s.write((char*)&scriptCode.begin()[0], size); } /** Serialize an input of txTo */ - template - void SerializeInput(S& s, unsigned int nInput) const - { + template + void SerializeInput(S &s, unsigned int nInput) const { // In case of SIGHASH_ANYONECANPAY, only the input being signed is serialized if (fAnyoneCanPay) nInput = nIn; @@ -1007,9 +1016,8 @@ class CTransactionSignatureSerializer } /** Serialize an output of txTo */ - template - void SerializeOutput(S& s, unsigned int nOutput) const - { + template + void SerializeOutput(S &s, unsigned int nOutput) const { if (fHashSingle && nOutput != nIn) // Do not lock-in the txout payee at other indices as txin ::Serialize(s, CTxOut()); @@ -1018,21 +1026,20 @@ class CTransactionSignatureSerializer } /** Serialize txTo */ - template - void Serialize(S& s) const - { + template + void Serialize(S &s) const { // Serialize nVersion ::Serialize(s, txTo.nVersion); // Serialize vin unsigned int nInputs = fAnyoneCanPay ? 1 : txTo.vin.size(); ::WriteCompactSize(s, nInputs); for (unsigned int nInput = 0; nInput < nInputs; nInput++) - SerializeInput(s, nInput); + SerializeInput(s, nInput); // Serialize vout - unsigned int nOutputs = fHashNone ? 0 : (fHashSingle ? nIn + 1 : txTo.vout.size()); + unsigned int nOutputs = fHashNone ? 0 : (fHashSingle ? nIn+1 : txTo.vout.size()); ::WriteCompactSize(s, nOutputs); for (unsigned int nOutput = 0; nOutput < nOutputs; nOutput++) - SerializeOutput(s, nOutput); + SerializeOutput(s, nOutput); // Serialize nLockTime ::Serialize(s, txTo.nLockTime); @@ -1056,20 +1063,19 @@ class CTransactionSignatureSerializer }; const unsigned char ZCASH_PREVOUTS_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] = - {'Z', 'c', 'a', 's', 'h', 'P', 'r', 'e', 'v', 'o', 'u', 't', 'H', 'a', 's', 'h'}; + {'Z','c','a','s','h','P','r','e','v','o','u','t','H','a','s','h'}; const unsigned char ZCASH_SEQUENCE_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] = - {'Z', 'c', 'a', 's', 'h', 'S', 'e', 'q', 'u', 'e', 'n', 'c', 'H', 'a', 's', 'h'}; + {'Z','c','a','s','h','S','e','q','u','e','n','c','H','a','s','h'}; const unsigned char ZCASH_OUTPUTS_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] = - {'Z', 'c', 'a', 's', 'h', 'O', 'u', 't', 'p', 'u', 't', 's', 'H', 'a', 's', 'h'}; + {'Z','c','a','s','h','O','u','t','p','u','t','s','H','a','s','h'}; const unsigned char ZCASH_JOINSPLITS_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] = - {'Z', 'c', 'a', 's', 'h', 'J', 'S', 'p', 'l', 'i', 't', 's', 'H', 'a', 's', 'h'}; + {'Z','c','a','s','h','J','S','p','l','i','t','s','H','a','s','h'}; const unsigned char ZCASH_SHIELDED_SPENDS_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] = - {'Z', 'c', 'a', 's', 'h', 'S', 'S', 'p', 'e', 'n', 'd', 's', 'H', 'a', 's', 'h'}; + {'Z','c','a','s','h','S','S','p','e','n','d','s','H','a','s','h'}; const unsigned char ZCASH_SHIELDED_OUTPUTS_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] = - {'Z', 'c', 'a', 's', 'h', 'S', 'O', 'u', 't', 'p', 'u', 't', 'H', 'a', 's', 'h'}; + {'Z','c','a','s','h','S','O','u','t','p','u','t','H','a','s','h'}; -uint256 GetPrevoutHash(const CTransaction& txTo) -{ +uint256 GetPrevoutHash(const CTransaction& txTo) { CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_PREVOUTS_HASH_PERSONALIZATION); for (unsigned int n = 0; n < txTo.vin.size(); n++) { ss << txTo.vin[n].prevout; @@ -1077,8 +1083,7 @@ uint256 GetPrevoutHash(const CTransaction& txTo) return ss.GetHash(); } -uint256 GetSequenceHash(const CTransaction& txTo) -{ +uint256 GetSequenceHash(const CTransaction& txTo) { CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_SEQUENCE_HASH_PERSONALIZATION); for (unsigned int n = 0; n < txTo.vin.size(); n++) { ss << txTo.vin[n].nSequence; @@ -1086,8 +1091,7 @@ uint256 GetSequenceHash(const CTransaction& txTo) return ss.GetHash(); } -uint256 GetOutputsHash(const CTransaction& txTo) -{ +uint256 GetOutputsHash(const CTransaction& txTo) { CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_OUTPUTS_HASH_PERSONALIZATION); for (unsigned int n = 0; n < txTo.vout.size(); n++) { ss << txTo.vout[n]; @@ -1095,8 +1099,7 @@ uint256 GetOutputsHash(const CTransaction& txTo) return ss.GetHash(); } -uint256 GetJoinSplitsHash(const CTransaction& txTo) -{ +uint256 GetJoinSplitsHash(const CTransaction& txTo) { CBLAKE2bWriter ss(SER_GETHASH, static_cast(txTo.GetHeader()), ZCASH_JOINSPLITS_HASH_PERSONALIZATION); for (unsigned int n = 0; n < txTo.vJoinSplit.size(); n++) { ss << txTo.vJoinSplit[n]; @@ -1105,8 +1108,7 @@ uint256 GetJoinSplitsHash(const CTransaction& txTo) return ss.GetHash(); } -uint256 GetShieldedSpendsHash(const CTransaction& txTo) -{ +uint256 GetShieldedSpendsHash(const CTransaction& txTo) { CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_SHIELDED_SPENDS_HASH_PERSONALIZATION); for (const auto& spend : txTo.GetSaplingSpends()) { ss << spend.cv(); @@ -1118,8 +1120,7 @@ uint256 GetShieldedSpendsHash(const CTransaction& txTo) return ss.GetHash(); } -uint256 GetShieldedOutputsHash(const CTransaction& txTo) -{ +uint256 GetShieldedOutputsHash(const CTransaction& txTo) { CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_SHIELDED_OUTPUTS_HASH_PERSONALIZATION); auto ssRs = ToRustStream(ss); for (const auto& output : txTo.GetSaplingOutputs()) { @@ -1128,11 +1129,12 @@ uint256 GetShieldedOutputsHash(const CTransaction& txTo) return ss.GetHash(); } -} // namespace +} // anon namespace PrecomputedTransactionData::PrecomputedTransactionData( const CTransaction& txTo, - const std::vector& allPrevOutputs) : preTx(nullptr, zcash_transaction_precomputed_free) + const std::vector& allPrevOutputs) : + preTx(nullptr, zcash_transaction_precomputed_free) { CDataStream sAllPrevOutputs(SER_NETWORK, PROTOCOL_VERSION); sAllPrevOutputs << allPrevOutputs; @@ -1145,7 +1147,8 @@ PrecomputedTransactionData::PrecomputedTransactionData( PrecomputedTransactionData::PrecomputedTransactionData( const CTransaction& txTo, const unsigned char* allPrevOutputs, - size_t allPrevOutputsLen) : preTx(nullptr, zcash_transaction_precomputed_free) + size_t allPrevOutputsLen) : + preTx(nullptr, zcash_transaction_precomputed_free) { SetPrecomputed(txTo, allPrevOutputs, allPrevOutputsLen); } @@ -1263,10 +1266,11 @@ uint256 SignatureHash( // in the transaction itself. uint256 hash; if (!zcash_transaction_zip244_signature_digest( - txdata.preTx.get(), - nHashType, - nIn, - hash.begin())) { + txdata.preTx.get(), + nHashType, + nIn, + hash.begin())) + { throw std::logic_error("We should not reach here."); } return hash; @@ -1310,7 +1314,7 @@ uint256 SignatureHash( uint32_t leConsensusBranchId = htole32(consensusBranchId); unsigned char personalization[16] = {}; memcpy(personalization, "ZcashSigHash", 12); - memcpy(personalization + 12, &leConsensusBranchId, 4); + memcpy(personalization+12, &leConsensusBranchId, 4); CBLAKE2bWriter ss(SER_GETHASH, 0, personalization); // Header @@ -1343,7 +1347,7 @@ uint256 SignatureHash( // If this hash is for a transparent input signature // (i.e. not for txTo.joinSplitSig): - if (nIn != NOT_AN_INPUT) { + if (nIn != NOT_AN_INPUT){ // The input being signed (replacing the scriptSig with scriptCode + amount) // The prevout may already be contained in hashPrevout, and the nSequence // may already be contained in hashSequence. @@ -1374,9 +1378,7 @@ uint256 SignatureHash( } bool TransactionSignatureChecker::VerifySignature( - const std::vector& vchSig, - const CPubKey& pubkey, - const uint256& sighash) const + const std::vector& vchSig, const CPubKey& pubkey, const uint256& sighash) const { return pubkey.Verify(sighash, vchSig); } @@ -1421,8 +1423,9 @@ bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) con // unless the type of nLockTime being tested is the same as // the nLockTime in the transaction. if (!( - (txTo->nLockTime < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) || - (txTo->nLockTime >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD))) + (txTo->nLockTime < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) || + (txTo->nLockTime >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD) + )) return false; // Now that we know we're comparing apples-to-apples, the @@ -1605,7 +1608,7 @@ bool VerifyScript( return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY); } - vector> stack, stackCopy; + vector > stack, stackCopy; if (!EvalScript(stack, scriptSig, flags, checker, consensusBranchId, serror)) // serror is set return false; @@ -1620,7 +1623,8 @@ bool VerifyScript( return set_error(serror, (ScriptError_t)(SCRIPT_ERR_EVAL_FALSE + 102)); // Additional validation for spend-to-script-hash transactions: - if ((flags & SCRIPT_VERIFY_P2SH) && scriptPubKey.IsPayToScriptHash()) { + if ((flags & SCRIPT_VERIFY_P2SH) && scriptPubKey.IsPayToScriptHash()) + { // scriptSig must be literals-only or validation fails if (!scriptSig.IsPushOnly()) return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY); diff --git a/depend/zcash/src/script/interpreter.h b/depend/zcash/src/script/interpreter.h index b221faa97..526f77c89 100644 --- a/depend/zcash/src/script/interpreter.h +++ b/depend/zcash/src/script/interpreter.h @@ -7,15 +7,15 @@ #ifndef BITCOIN_SCRIPT_INTERPRETER_H #define BITCOIN_SCRIPT_INTERPRETER_H -#include "primitives/transaction.h" #include "script_error.h" +#include "primitives/transaction.h" #include -#include +#include #include #include -#include +#include class CPubKey; class CScript; @@ -26,7 +26,8 @@ class uint256; const unsigned int NOT_AN_INPUT = UINT_MAX; /** Signature hash types/flags */ -enum { +enum +{ SIGHASH_ALL = 1, SIGHASH_NONE = 2, SIGHASH_SINGLE = 3, @@ -34,11 +35,12 @@ enum { }; /** Script verification flags */ -enum { - SCRIPT_VERIFY_NONE = 0, +enum +{ + SCRIPT_VERIFY_NONE = 0, // Evaluate P2SH subscripts (softfork safe, BIP16). - SCRIPT_VERIFY_P2SH = (1U << 0), + SCRIPT_VERIFY_P2SH = (1U << 0), // Passing a non-strict-DER signature or one with undefined hashtype to a checksig operation causes script failure. // Evaluating a pubkey that is not (0x04 + 64 bytes) or (0x02 or 0x03 + 32 bytes) by checksig causes script failure. @@ -47,11 +49,11 @@ enum { // Passing a non-strict-DER signature to a checksig operation causes script failure (softfork safe, BIP62 rule 1) // In Zcash this is required, and validation of non-strict-DER signatures is not implemented. - // SCRIPT_VERIFY_DERSIG = (1U << 2), + //SCRIPT_VERIFY_DERSIG = (1U << 2), // Passing a non-strict-DER signature or one with S > order/2 to a checksig operation causes script failure // (softfork safe, BIP62 rule 5). - SCRIPT_VERIFY_LOW_S = (1U << 3), + SCRIPT_VERIFY_LOW_S = (1U << 3), // verify dummy stack item consumed by CHECKMULTISIG is of zero-length (softfork safe, BIP62 rule 7). SCRIPT_VERIFY_NULLDUMMY = (1U << 4), @@ -74,7 +76,7 @@ enum { // discouraged NOPs fails the script. This verification flag will never be // a mandatory flag applied to scripts in a block. NOPs that are not // executed, e.g. within an unexecuted IF ENDIF block, are *not* rejected. - SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1U << 7), + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1U << 7), // Require that only a single stack element remains after evaluation. This changes the success criterion from // "At least one stack element must remain, and when interpreted as a boolean, it must be true" to @@ -89,9 +91,10 @@ enum { SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), }; -bool CheckSignatureEncoding(const std::vector& vchSig, unsigned int flags, ScriptError* serror); +bool CheckSignatureEncoding(const std::vector &vchSig, unsigned int flags, ScriptError* serror); -struct PrecomputedTransactionData { +struct PrecomputedTransactionData +{ uint256 hashPrevouts, hashSequence, hashOutputs, hashJoinSplits, hashShieldedSpends, hashShieldedOutputs; /** Precomputed transaction parts. */ std::unique_ptr preTx; @@ -112,7 +115,8 @@ struct PrecomputedTransactionData { size_t allPrevOutputsLen); }; -enum SigVersion { +enum SigVersion +{ SIGVERSION_SPROUT = 0, SIGVERSION_OVERWINTER = 1, SIGVERSION_SAPLING = 2, @@ -120,7 +124,7 @@ enum SigVersion { }; uint256 SignatureHash( - const CScript& scriptCode, + const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, @@ -142,7 +146,7 @@ class BaseSignatureChecker virtual bool CheckLockTime(const CScriptNum& nLockTime) const { - return false; + return false; } virtual ~BaseSignatureChecker() {} @@ -214,7 +218,7 @@ class CallbackTransactionSignatureChecker : public BaseSignatureChecker bool EvalScript( - std::vector>& stack, + std::vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, From f00debe4bbe7573ab841ce498441110e87389bfe Mon Sep 17 00:00:00 2001 From: Conrado Gouvea Date: Wed, 22 May 2024 17:06:08 -0300 Subject: [PATCH 04/16] remove prehashed code --- depend/zcash/src/script/interpreter.cpp | 69 ------------------------ depend/zcash/src/script/interpreter.h | 19 ------- depend/zcash/src/script/zcash_script.cpp | 35 ------------ depend/zcash/src/script/zcash_script.h | 15 ------ 4 files changed, 138 deletions(-) diff --git a/depend/zcash/src/script/interpreter.cpp b/depend/zcash/src/script/interpreter.cpp index 91fe0a18f..1e581738c 100644 --- a/depend/zcash/src/script/interpreter.cpp +++ b/depend/zcash/src/script/interpreter.cpp @@ -1449,75 +1449,6 @@ bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) con return true; } -bool PrehashedTransactionSignatureChecker::VerifySignature( - const std::vector& vchSig, - const CPubKey& pubkey, - const uint256& sighash) const -{ - return pubkey.Verify(sighash, vchSig); -} - -bool PrehashedTransactionSignatureChecker::CheckSig( - const vector& vchSigIn, - const vector& vchPubKey, - const CScript& scriptCode, - uint32_t consensusBranchId) const -{ - CPubKey pubkey(vchPubKey); - if (!pubkey.IsValid()) - return false; - - // Hash type is one byte tacked on to the end of the signature - vector vchSig(vchSigIn); - if (vchSig.empty()) - return false; - int nHashType = vchSig.back(); - vchSig.pop_back(); - - std::array sighashArray; - std::copy_n(this->sighash, sighashArray.size(), sighashArray.begin()); - uint256 sighash = uint256::FromRawBytes(sighashArray); - if (!VerifySignature(vchSig, pubkey, sighash)) - return false; - - return true; -} - -bool PrehashedTransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) const -{ - // There are two times of nLockTime: lock-by-blockheight - // and lock-by-blocktime, distinguished by whether - // nLockTime < LOCKTIME_THRESHOLD. - // - // We want to compare apples to apples, so fail the script - // unless the type of nLockTime being tested is the same as - // the nLockTime in the transaction. - if (!( - (this->nLockTime < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) || - (this->nLockTime >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD))) - return false; - - // Now that we know we're comparing apples-to-apples, the - // comparison is a simple numeric one. - if (nLockTime > this->nLockTime) - return false; - - // Finally the nLockTime feature can be disabled and thus - // CHECKLOCKTIMEVERIFY bypassed if every txin has been - // finalized by setting nSequence to maxint. The - // transaction would be allowed into the blockchain, making - // the opcode ineffective. - // - // Testing if this vin is not final is sufficient to - // prevent this condition. Alternatively we could test all - // inputs, but testing just this input minimizes the data - // required to prove correct CHECKLOCKTIMEVERIFY execution. - if (this->isFinal) - return false; - - return true; -} - bool CallbackTransactionSignatureChecker::VerifySignature( const std::vector& vchSig, const CPubKey& pubkey, diff --git a/depend/zcash/src/script/interpreter.h b/depend/zcash/src/script/interpreter.h index 526f77c89..563949843 100644 --- a/depend/zcash/src/script/interpreter.h +++ b/depend/zcash/src/script/interpreter.h @@ -178,25 +178,6 @@ class MutableTransactionSignatureChecker : public TransactionSignatureChecker MutableTransactionSignatureChecker(const CMutableTransaction* txToIn, const PrecomputedTransactionData& txdataIn, unsigned int nInIn, const CAmount& amount) : TransactionSignatureChecker(&txTo, txdataIn, nInIn, amount), txTo(*txToIn) {} }; -class PrehashedTransactionSignatureChecker : public BaseSignatureChecker -{ -private: - const unsigned char* sighash; - unsigned int sighashLen; - const CScriptNum& nLockTime; - bool isFinal; - unsigned int nIn; - const CAmount amount; - -protected: - virtual bool VerifySignature(const std::vector& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; - -public: - PrehashedTransactionSignatureChecker(const unsigned char* sighash, unsigned int sighashLen, const CScriptNum& nLockTime, bool isFinal, unsigned int nInIn, const CAmount& amountIn) : sighash(sighash), sighashLen(sighashLen), nLockTime(nLockTime), isFinal(isFinal), nIn(nInIn), amount(amountIn) {} - bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode, uint32_t consensusBranchId) const; - bool CheckLockTime(const CScriptNum& nLockTime) const; -}; - class CallbackTransactionSignatureChecker : public BaseSignatureChecker { private: diff --git a/depend/zcash/src/script/zcash_script.cpp b/depend/zcash/src/script/zcash_script.cpp index 960dcec5b..b96c3c17c 100644 --- a/depend/zcash/src/script/zcash_script.cpp +++ b/depend/zcash/src/script/zcash_script.cpp @@ -184,41 +184,6 @@ inline int set_error(zcash_script_error* ret, zcash_script_error serror) // } // } -int zcash_script_verify_prehashed( - const unsigned char* sighash, - unsigned int sighashLen, - int64_t nLockTime, - uint8_t isFinal, - const unsigned char* scriptPubKey, - unsigned int scriptPubKeyLen, - const unsigned char* scriptSig, - unsigned int scriptSigLen, - int64_t amount, - unsigned int nIn, - unsigned int flags, - uint32_t consensusBranchId, - zcash_script_error* err) -{ - try { - set_error(err, zcash_script_ERR_OK); - CScriptNum nLockTimeNum = CScriptNum(nLockTime); - ScriptError script_err = SCRIPT_ERR_OK; - bool r = VerifyScript( - CScript(scriptSig, scriptSig + scriptSigLen), - CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), - flags, - PrehashedTransactionSignatureChecker(sighash, sighashLen, nLockTimeNum, isFinal != 0, nIn, amount), - consensusBranchId, - &script_err); - if (!r) { - return set_error(err, (zcash_script_error_t)((zcash_script_error_t)1000 + (zcash_script_error_t)script_err)); - } - return r; - } catch (const std::exception&) { - return set_error(err, zcash_script_ERR_VERIFY_SCRIPT); // Error deserializing - } -} - int zcash_script_verify_callback( const void* tx, void (*sighash)(unsigned char* sighash, const void* tx, const unsigned char* scriptCode, unsigned int scriptCodeLen, int hashType), diff --git a/depend/zcash/src/script/zcash_script.h b/depend/zcash/src/script/zcash_script.h index b5b145110..6c74f3bd8 100644 --- a/depend/zcash/src/script/zcash_script.h +++ b/depend/zcash/src/script/zcash_script.h @@ -134,21 +134,6 @@ enum { // uint32_t consensusBranchId, // zcash_script_error* err); -EXPORT_SYMBOL int zcash_script_verify_prehashed( - const unsigned char* sighash, - unsigned int sighashLen, - int64_t nLockTime, - uint8_t isFinal, - const unsigned char* scriptPubKey, - unsigned int scriptPubKeyLen, - const unsigned char* scriptSig, - unsigned int scriptSigLen, - int64_t amount, - unsigned int nIn, - unsigned int flags, - uint32_t consensusBranchId, - zcash_script_error* err); - EXPORT_SYMBOL int zcash_script_verify_callback( const void* tx, void (*sighash)(unsigned char* sighash, const void* tx, const unsigned char* scriptCode, unsigned int scriptCodeLen, int hashType), From 23ecfadc21f4821915d8bea1f7ebe99097ddacd4 Mon Sep 17 00:00:00 2001 From: Conrado Gouvea Date: Wed, 22 May 2024 17:44:17 -0300 Subject: [PATCH 05/16] moving code around --- depend/zcash/src/script/zcash_script.cpp | 78 ++++++++++++------------ depend/zcash/src/script/zcash_script.h | 72 +++++++++++----------- 2 files changed, 76 insertions(+), 74 deletions(-) diff --git a/depend/zcash/src/script/zcash_script.cpp b/depend/zcash/src/script/zcash_script.cpp index b96c3c17c..5db1fd85f 100644 --- a/depend/zcash/src/script/zcash_script.cpp +++ b/depend/zcash/src/script/zcash_script.cpp @@ -183,42 +183,7 @@ inline int set_error(zcash_script_error* ret, zcash_script_error serror) // return set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing // } // } - -int zcash_script_verify_callback( - const void* tx, - void (*sighash)(unsigned char* sighash, const void* tx, const unsigned char* scriptCode, unsigned int scriptCodeLen, int hashType), - int64_t nLockTime, - uint8_t isFinal, - const unsigned char* scriptPubKey, - unsigned int scriptPubKeyLen, - const unsigned char* scriptSig, - unsigned int scriptSigLen, - int64_t amount, - unsigned int nIn, - unsigned int flags, - uint32_t consensusBranchId, - zcash_script_error* err) -{ - try { - set_error(err, zcash_script_ERR_OK); - CScriptNum nLockTimeNum = CScriptNum(nLockTime); - ScriptError script_err = SCRIPT_ERR_OK; - bool r = VerifyScript( - CScript(scriptSig, scriptSig + scriptSigLen), - CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), - flags, - CallbackTransactionSignatureChecker(tx, sighash, nLockTimeNum, isFinal != 0, nIn, amount), - consensusBranchId, - &script_err); - if (!r) { - return set_error(err, (zcash_script_error_t)((zcash_script_error_t)1000 + (zcash_script_error_t)script_err)); - } - return r; - } catch (const std::exception&) { - return set_error(err, zcash_script_ERR_VERIFY_SCRIPT); // Error deserializing - } -} - +// // int zcash_script_verify_v5( // const unsigned char* txTo, // unsigned int txToLen, @@ -314,6 +279,12 @@ int zcash_script_verify_callback( // } // } +unsigned int zcash_script_version() +{ + // Just use the API version for now + return ZCASH_SCRIPT_API_VER; +} + unsigned int zcash_script_legacy_sigop_count_script( const unsigned char* script, unsigned int scriptLen) @@ -322,8 +293,37 @@ unsigned int zcash_script_legacy_sigop_count_script( return cscript.GetSigOpCount(false); } -unsigned int zcash_script_version() +int zcash_script_verify_callback( + const void* tx, + void (*sighash)(unsigned char* sighash, const void* tx, const unsigned char* scriptCode, unsigned int scriptCodeLen, int hashType), + int64_t nLockTime, + uint8_t isFinal, + const unsigned char* scriptPubKey, + unsigned int scriptPubKeyLen, + const unsigned char* scriptSig, + unsigned int scriptSigLen, + int64_t amount, + unsigned int nIn, + unsigned int flags, + uint32_t consensusBranchId, + zcash_script_error* err) { - // Just use the API version for now - return ZCASH_SCRIPT_API_VER; + try { + set_error(err, zcash_script_ERR_OK); + CScriptNum nLockTimeNum = CScriptNum(nLockTime); + ScriptError script_err = SCRIPT_ERR_OK; + bool r = VerifyScript( + CScript(scriptSig, scriptSig + scriptSigLen), + CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), + flags, + CallbackTransactionSignatureChecker(tx, sighash, nLockTimeNum, isFinal != 0, nIn, amount), + consensusBranchId, + &script_err); + if (!r) { + return set_error(err, (zcash_script_error_t)((zcash_script_error_t)1000 + (zcash_script_error_t)script_err)); + } + return r; + } catch (const std::exception&) { + return set_error(err, zcash_script_ERR_VERIFY_SCRIPT); // Error deserializing + } } diff --git a/depend/zcash/src/script/zcash_script.h b/depend/zcash/src/script/zcash_script.h index 6c74f3bd8..449a2ea9e 100644 --- a/depend/zcash/src/script/zcash_script.h +++ b/depend/zcash/src/script/zcash_script.h @@ -11,23 +11,23 @@ #if defined(BUILD_BITCOIN_INTERNAL) && defined(HAVE_CONFIG_H) #include "config/bitcoin-config.h" -#if defined(_WIN32) -#if defined(DLL_EXPORT) -#if defined(HAVE_FUNC_ATTRIBUTE_DLLEXPORT) -#define EXPORT_SYMBOL __declspec(dllexport) -#else -#define EXPORT_SYMBOL -#endif -#endif -#elif defined(HAVE_FUNC_ATTRIBUTE_VISIBILITY) -#define EXPORT_SYMBOL __attribute__((visibility("default"))) -#endif + #if defined(_WIN32) + #if defined(DLL_EXPORT) + #if defined(HAVE_FUNC_ATTRIBUTE_DLLEXPORT) + #define EXPORT_SYMBOL __declspec(dllexport) + #else + #define EXPORT_SYMBOL + #endif + #endif + #elif defined(HAVE_FUNC_ATTRIBUTE_VISIBILITY) + #define EXPORT_SYMBOL __attribute__ ((visibility ("default"))) + #endif #elif defined(MSC_VER) && !defined(STATIC_LIBZCASHCONSENSUS) -#define EXPORT_SYMBOL __declspec(dllimport) + #define EXPORT_SYMBOL __declspec(dllimport) #endif #ifndef EXPORT_SYMBOL -#define EXPORT_SYMBOL + #define EXPORT_SYMBOL #endif #ifdef __cplusplus @@ -36,7 +36,8 @@ extern "C" { #define ZCASH_SCRIPT_API_VER 3 -typedef enum zcash_script_error_t { +typedef enum zcash_script_error_t +{ zcash_script_ERR_OK = 0, zcash_script_ERR_TX_INDEX, zcash_script_ERR_TX_SIZE_MISMATCH, @@ -49,9 +50,10 @@ typedef enum zcash_script_error_t { } zcash_script_error; /** Script verification flags */ -enum { - zcash_script_SCRIPT_FLAGS_VERIFY_NONE = 0, - zcash_script_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts +enum +{ + zcash_script_SCRIPT_FLAGS_VERIFY_NONE = 0, + zcash_script_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts zcash_script_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), // enable CHECKLOCKTIMEVERIFY (BIP65) }; @@ -133,22 +135,7 @@ enum { // unsigned int flags, // uint32_t consensusBranchId, // zcash_script_error* err); - -EXPORT_SYMBOL int zcash_script_verify_callback( - const void* tx, - void (*sighash)(unsigned char* sighash, const void* tx, const unsigned char* scriptCode, unsigned int scriptCodeLen, int hashType), - int64_t nLockTime, - uint8_t isFinal, - const unsigned char* scriptPubKey, - unsigned int scriptPubKeyLen, - const unsigned char* scriptSig, - unsigned int scriptSigLen, - int64_t amount, - unsigned int nIn, - unsigned int flags, - uint32_t consensusBranchId, - zcash_script_error* err); - +// /// Returns 1 if the input nIn of the serialized transaction pointed to by /// txTo correctly spends the matching output in allPrevOutputs under /// the additional constraints specified by flags. Must be used for V5 transactions; @@ -194,12 +181,27 @@ EXPORT_SYMBOL int zcash_script_verify_callback( // unsigned int txToLen, // zcash_script_error* err); +/// Returns the current version of the zcash_script library. +EXPORT_SYMBOL unsigned int zcash_script_version(); + EXPORT_SYMBOL unsigned int zcash_script_legacy_sigop_count_script( const unsigned char* script, unsigned int scriptLen); -/// Returns the current version of the zcash_script library. -EXPORT_SYMBOL unsigned int zcash_script_version(); +EXPORT_SYMBOL int zcash_script_verify_callback( + const void* tx, + void (*sighash)(unsigned char* sighash, const void* tx, const unsigned char* scriptCode, unsigned int scriptCodeLen, int hashType), + int64_t nLockTime, + uint8_t isFinal, + const unsigned char* scriptPubKey, + unsigned int scriptPubKeyLen, + const unsigned char* scriptSig, + unsigned int scriptSigLen, + int64_t amount, + unsigned int nIn, + unsigned int flags, + uint32_t consensusBranchId, + zcash_script_error* err); #ifdef __cplusplus } // extern "C" From 1741fd72d7ecd40863ce6e7ea585801fc1168d62 Mon Sep 17 00:00:00 2001 From: Conrado Gouvea Date: Wed, 22 May 2024 17:53:35 -0300 Subject: [PATCH 06/16] use #if 0 instead of commenting out to make diff clearer --- depend/zcash/src/script/zcash_script.cpp | 490 ++++++++++++----------- depend/zcash/src/script/zcash_script.h | 93 +++-- 2 files changed, 293 insertions(+), 290 deletions(-) diff --git a/depend/zcash/src/script/zcash_script.cpp b/depend/zcash/src/script/zcash_script.cpp index 5db1fd85f..b322f8715 100644 --- a/depend/zcash/src/script/zcash_script.cpp +++ b/depend/zcash/src/script/zcash_script.cpp @@ -6,14 +6,15 @@ #include "zcash_script.h" -// #include "consensus/upgrades.h" -// #include "primitives/transaction.h" -// #include "pubkey.h" +#if 0 +#include "consensus/upgrades.h" +#include "primitives/transaction.h" +#include "pubkey.h" +#endif #include "script/interpreter.h" #include "version.h" -namespace -{ +namespace { inline int set_error(zcash_script_error* ret, zcash_script_error serror) { if (ret) @@ -21,263 +22,266 @@ inline int set_error(zcash_script_error* ret, zcash_script_error serror) return 0; } -// // Copy of GetLegacySigOpCount from main.cpp commit c4b2ef7c4. -// // Replace with the copy from src/consensus/tx_verify.{cpp,h} after backporting that refactor. -// unsigned int GetLegacySigOpCount(const CTransaction& tx) -// { -// unsigned int nSigOps = 0; -// for (const CTxIn& txin : tx.vin) { -// nSigOps += txin.scriptSig.GetSigOpCount(false); -// } -// for (const CTxOut& txout : tx.vout) { -// nSigOps += txout.scriptPubKey.GetSigOpCount(false); -// } -// return nSigOps; -// } -} // namespace +#if 0 +// Copy of GetLegacySigOpCount from main.cpp commit c4b2ef7c4. +// Replace with the copy from src/consensus/tx_verify.{cpp,h} after backporting that refactor. +unsigned int GetLegacySigOpCount(const CTransaction& tx) +{ + unsigned int nSigOps = 0; + for (const CTxIn& txin : tx.vin) + { + nSigOps += txin.scriptSig.GetSigOpCount(false); + } + for (const CTxOut& txout : tx.vout) + { + nSigOps += txout.scriptPubKey.GetSigOpCount(false); + } + return nSigOps; +} +#endif +} -// struct PrecomputedTransaction { -// const CTransaction tx; -// const PrecomputedTransactionData txdata; +#if 0 +struct PrecomputedTransaction { + const CTransaction tx; + const PrecomputedTransactionData txdata; -// PrecomputedTransaction( -// CTransaction txIn, -// const unsigned char* allPrevOutputs, -// size_t allPrevOutputsLen) : tx(txIn), txdata(txIn, allPrevOutputs, allPrevOutputsLen) {} -// }; + PrecomputedTransaction( + CTransaction txIn, + const unsigned char* allPrevOutputs, + size_t allPrevOutputsLen) : tx(txIn), txdata(txIn, allPrevOutputs, allPrevOutputsLen) {} +}; -// void* zcash_script_new_precomputed_tx( -// const unsigned char* txTo, -// unsigned int txToLen, -// zcash_script_error* err) -// { -// try { -// const char* txToEnd = (const char*)(txTo + txToLen); -// RustDataStream stream((const char*)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); -// CTransaction tx; -// stream >> tx; -// if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) { -// set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); -// return nullptr; -// } -// if (tx.nVersion >= ZIP225_TX_VERSION) { -// set_error(err, zcash_script_ERR_TX_VERSION); -// return nullptr; -// } +void* zcash_script_new_precomputed_tx( + const unsigned char* txTo, + unsigned int txToLen, + zcash_script_error* err) +{ + try { + const char* txToEnd = (const char *)(txTo + txToLen); + RustDataStream stream((const char *)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); + CTransaction tx; + stream >> tx; + if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) { + set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); + return nullptr; + } + if (tx.nVersion >= ZIP225_TX_VERSION) { + set_error(err, zcash_script_ERR_TX_VERSION); + return nullptr; + } -// // Deserializing the tx did not error. -// set_error(err, zcash_script_ERR_OK); -// // This is a pre-v5 tx, so the PrecomputedTransactionData constructor -// // field `allPrevOutputs` is not used. -// auto preTx = new PrecomputedTransaction(tx, nullptr, 0); -// return preTx; -// } catch (const std::exception&) { -// set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing -// return nullptr; -// } -// } + // Deserializing the tx did not error. + set_error(err, zcash_script_ERR_OK); + // This is a pre-v5 tx, so the PrecomputedTransactionData constructor + // field `allPrevOutputs` is not used. + auto preTx = new PrecomputedTransaction(tx, nullptr, 0); + return preTx; + } catch (const std::exception&) { + set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing + return nullptr; + } +} -// void* zcash_script_new_precomputed_tx_v5( -// const unsigned char* txTo, -// unsigned int txToLen, -// const unsigned char* allPrevOutputs, -// unsigned int allPrevOutputsLen, -// zcash_script_error* err) -// { -// CTransaction tx; -// try { -// const char* txToEnd = (const char*)(txTo + txToLen); -// RustDataStream stream((const char*)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); -// stream >> tx; -// if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) { -// set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); -// return nullptr; -// } -// } catch (const std::exception&) { -// set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing -// return nullptr; -// } +void* zcash_script_new_precomputed_tx_v5( + const unsigned char* txTo, + unsigned int txToLen, + const unsigned char* allPrevOutputs, + unsigned int allPrevOutputsLen, + zcash_script_error* err) +{ + CTransaction tx; + try { + const char* txToEnd = (const char *)(txTo + txToLen); + RustDataStream stream((const char *)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); + stream >> tx; + if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) { + set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); + return nullptr; + } + } catch (const std::exception&) { + set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing + return nullptr; + } -// try { -// auto preTx = new PrecomputedTransaction(tx, allPrevOutputs, allPrevOutputsLen); -// // Deserializing the tx did not error. -// set_error(err, zcash_script_ERR_OK); -// return preTx; -// } catch (const std::exception&) { -// // We had some error when parsing allPrevOutputs inside the -// // PrecomputedTransactionData constructor. -// set_error(err, zcash_script_ERR_ALL_PREV_OUTPUTS_DESERIALIZE); -// return nullptr; -// } -// } + try { + auto preTx = new PrecomputedTransaction(tx, allPrevOutputs, allPrevOutputsLen); + // Deserializing the tx did not error. + set_error(err, zcash_script_ERR_OK); + return preTx; + } catch (const std::exception&) { + // We had some error when parsing allPrevOutputs inside the + // PrecomputedTransactionData constructor. + set_error(err, zcash_script_ERR_ALL_PREV_OUTPUTS_DESERIALIZE); + return nullptr; + } +} -// void zcash_script_free_precomputed_tx(void* pre_preTx) -// { -// PrecomputedTransaction* preTx = static_cast(pre_preTx); -// delete preTx; -// preTx = nullptr; -// } +void zcash_script_free_precomputed_tx(void* pre_preTx) +{ + PrecomputedTransaction* preTx = static_cast(pre_preTx); + delete preTx; + preTx = nullptr; +} -// int zcash_script_verify_precomputed( -// const void* pre_preTx, -// unsigned int nIn, -// const unsigned char* scriptPubKey, -// unsigned int scriptPubKeyLen, -// int64_t amount, -// unsigned int flags, -// uint32_t consensusBranchId, -// zcash_script_error* err) -// { -// const PrecomputedTransaction* preTx = static_cast(pre_preTx); -// if (nIn >= preTx->tx.vin.size()) -// return set_error(err, zcash_script_ERR_TX_INDEX); +int zcash_script_verify_precomputed( + const void* pre_preTx, + unsigned int nIn, + const unsigned char* scriptPubKey, + unsigned int scriptPubKeyLen, + int64_t amount, + unsigned int flags, + uint32_t consensusBranchId, + zcash_script_error* err) +{ + const PrecomputedTransaction* preTx = static_cast(pre_preTx); + if (nIn >= preTx->tx.vin.size()) + return set_error(err, zcash_script_ERR_TX_INDEX); -// // Regardless of the verification result, the tx did not error. -// set_error(err, zcash_script_ERR_OK); -// return VerifyScript( -// preTx->tx.vin[nIn].scriptSig, -// CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), -// flags, -// TransactionSignatureChecker(&preTx->tx, preTx->txdata, nIn, amount), -// consensusBranchId, -// NULL); -// } + // Regardless of the verification result, the tx did not error. + set_error(err, zcash_script_ERR_OK); + return VerifyScript( + preTx->tx.vin[nIn].scriptSig, + CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), + flags, + TransactionSignatureChecker(&preTx->tx, preTx->txdata, nIn, amount), + consensusBranchId, + NULL); +} -// int zcash_script_verify( -// const unsigned char* scriptPubKey, -// unsigned int scriptPubKeyLen, -// int64_t amount, -// const unsigned char* txTo, -// unsigned int txToLen, -// unsigned int nIn, -// unsigned int flags, -// uint32_t consensusBranchId, -// zcash_script_error* err) -// { -// try { -// const char* txToEnd = (const char*)(txTo + txToLen); -// RustDataStream stream((const char*)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); -// CTransaction tx; -// stream >> tx; -// if (nIn >= tx.vin.size()) -// return set_error(err, zcash_script_ERR_TX_INDEX); -// if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) -// return set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); -// if (tx.nVersion >= ZIP225_TX_VERSION) { -// return set_error(err, zcash_script_ERR_TX_VERSION); -// } +int zcash_script_verify( + const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, + int64_t amount, + const unsigned char *txTo, unsigned int txToLen, + unsigned int nIn, unsigned int flags, + uint32_t consensusBranchId, + zcash_script_error* err) +{ + try { + const char* txToEnd = (const char *)(txTo + txToLen); + RustDataStream stream((const char *)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); + CTransaction tx; + stream >> tx; + if (nIn >= tx.vin.size()) + return set_error(err, zcash_script_ERR_TX_INDEX); + if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) + return set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); + if (tx.nVersion >= ZIP225_TX_VERSION) { + return set_error(err, zcash_script_ERR_TX_VERSION); + } + + // Regardless of the verification result, the tx did not error. + set_error(err, zcash_script_ERR_OK); + // This is a pre-v5 tx, so the PrecomputedTransactionData constructor + // field `allPrevOutputs` is not used. + PrecomputedTransactionData txdata(tx, {}); + return VerifyScript( + tx.vin[nIn].scriptSig, + CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), + flags, + TransactionSignatureChecker(&tx, txdata, nIn, amount), + consensusBranchId, + NULL); + } catch (const std::exception&) { + return set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing + } +} -// // Regardless of the verification result, the tx did not error. -// set_error(err, zcash_script_ERR_OK); -// // This is a pre-v5 tx, so the PrecomputedTransactionData constructor -// // field `allPrevOutputs` is not used. -// PrecomputedTransactionData txdata(tx, {}); -// return VerifyScript( -// tx.vin[nIn].scriptSig, -// CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), -// flags, -// TransactionSignatureChecker(&tx, txdata, nIn, amount), -// consensusBranchId, -// NULL); -// } catch (const std::exception&) { -// return set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing -// } -// } -// -// int zcash_script_verify_v5( -// const unsigned char* txTo, -// unsigned int txToLen, -// const unsigned char* allPrevOutputs, -// unsigned int allPrevOutputsLen, -// unsigned int nIn, -// unsigned int flags, -// uint32_t consensusBranchId, -// zcash_script_error* err) -// { -// CTransaction tx; -// try { -// const char* txToEnd = (const char*)(txTo + txToLen); -// RustDataStream stream((const char*)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); -// stream >> tx; -// if (nIn >= tx.vin.size()) -// return set_error(err, zcash_script_ERR_TX_INDEX); -// if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) -// return set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); -// } catch (const std::exception&) { -// return set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing -// } +int zcash_script_verify_v5( + const unsigned char* txTo, + unsigned int txToLen, + const unsigned char* allPrevOutputs, + unsigned int allPrevOutputsLen, + unsigned int nIn, + unsigned int flags, + uint32_t consensusBranchId, + zcash_script_error* err) +{ + CTransaction tx; + try { + const char* txToEnd = (const char *)(txTo + txToLen); + RustDataStream stream((const char *)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); + stream >> tx; + if (nIn >= tx.vin.size()) + return set_error(err, zcash_script_ERR_TX_INDEX); + if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) + return set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); + } catch (const std::exception&) { + return set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing + } -// std::vector prevOutputs; -// try { -// // TODO: we can swap this second deserialization for an FFI call by -// // fetching this through PrecomputedTransactionData. Simplicity for now. -// CDataStream sAllPrevOutputs( -// reinterpret_cast(allPrevOutputs), -// reinterpret_cast(allPrevOutputs + allPrevOutputsLen), -// SER_NETWORK, -// PROTOCOL_VERSION); -// sAllPrevOutputs >> prevOutputs; -// if (!(tx.IsCoinBase() ? prevOutputs.empty() : tx.vin.size() == prevOutputs.size())) { -// return set_error(err, zcash_script_ERR_ALL_PREV_OUTPUTS_SIZE_MISMATCH); -// } -// } catch (const std::exception&) { -// // We had some error when parsing allPrevOutputs inside the -// // PrecomputedTransactionData constructor. -// return set_error(err, zcash_script_ERR_ALL_PREV_OUTPUTS_DESERIALIZE); -// } + std::vector prevOutputs; + try { + // TODO: we can swap this second deserialization for an FFI call by + // fetching this through PrecomputedTransactionData. Simplicity for now. + CDataStream sAllPrevOutputs( + reinterpret_cast(allPrevOutputs), + reinterpret_cast(allPrevOutputs + allPrevOutputsLen), + SER_NETWORK, + PROTOCOL_VERSION); + sAllPrevOutputs >> prevOutputs; + if (!(tx.IsCoinBase() ? prevOutputs.empty() : tx.vin.size() == prevOutputs.size())) { + return set_error(err, zcash_script_ERR_ALL_PREV_OUTPUTS_SIZE_MISMATCH); + } + } catch (const std::exception&) { + // We had some error when parsing allPrevOutputs inside the + // PrecomputedTransactionData constructor. + return set_error(err, zcash_script_ERR_ALL_PREV_OUTPUTS_DESERIALIZE); + } -// try { -// // Regardless of the verification result, the tx did not error. -// set_error(err, zcash_script_ERR_OK); -// PrecomputedTransactionData txdata(tx, allPrevOutputs, allPrevOutputsLen); -// return VerifyScript( -// tx.vin[nIn].scriptSig, -// prevOutputs[nIn].scriptPubKey, -// flags, -// TransactionSignatureChecker(&tx, txdata, nIn, prevOutputs[nIn].nValue), -// consensusBranchId, -// NULL); -// } catch (const std::exception&) { -// return set_error(err, zcash_script_ERR_VERIFY_SCRIPT); // Error during script verification -// } -// } + try { + // Regardless of the verification result, the tx did not error. + set_error(err, zcash_script_ERR_OK); + PrecomputedTransactionData txdata(tx, allPrevOutputs, allPrevOutputsLen); + return VerifyScript( + tx.vin[nIn].scriptSig, + prevOutputs[nIn].scriptPubKey, + flags, + TransactionSignatureChecker(&tx, txdata, nIn, prevOutputs[nIn].nValue), + consensusBranchId, + NULL); + } catch (const std::exception&) { + return set_error(err, zcash_script_ERR_VERIFY_SCRIPT); // Error during script verification + } +} -// unsigned int zcash_script_legacy_sigop_count_precomputed( -// const void* pre_preTx, -// zcash_script_error* err) -// { -// const PrecomputedTransaction* preTx = static_cast(pre_preTx); +unsigned int zcash_script_legacy_sigop_count_precomputed( + const void* pre_preTx, + zcash_script_error* err) +{ + const PrecomputedTransaction* preTx = static_cast(pre_preTx); -// // The current implementation of this method never errors. -// set_error(err, zcash_script_ERR_OK); + // The current implementation of this method never errors. + set_error(err, zcash_script_ERR_OK); -// return GetLegacySigOpCount(preTx->tx); -// } + return GetLegacySigOpCount(preTx->tx); +} -// unsigned int zcash_script_legacy_sigop_count( -// const unsigned char* txTo, -// unsigned int txToLen, -// zcash_script_error* err) -// { -// try { -// const char* txToEnd = (const char*)(txTo + txToLen); -// RustDataStream stream((const char*)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); -// CTransaction tx; -// stream >> tx; -// if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) { -// set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); -// return UINT_MAX; -// } +unsigned int zcash_script_legacy_sigop_count( + const unsigned char *txTo, + unsigned int txToLen, + zcash_script_error* err) +{ + try { + const char* txToEnd = (const char *)(txTo + txToLen); + RustDataStream stream((const char *)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); + CTransaction tx; + stream >> tx; + if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) { + set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); + return UINT_MAX; + } -// // Deserializing the tx did not error. -// set_error(err, zcash_script_ERR_OK); + // Deserializing the tx did not error. + set_error(err, zcash_script_ERR_OK); -// return GetLegacySigOpCount(tx); -// } catch (const std::exception&) { -// set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing -// return UINT_MAX; -// } -// } + return GetLegacySigOpCount(tx); + } catch (const std::exception&) { + set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing + return UINT_MAX; + } +} +#endif unsigned int zcash_script_version() { diff --git a/depend/zcash/src/script/zcash_script.h b/depend/zcash/src/script/zcash_script.h index 449a2ea9e..475a0f3ee 100644 --- a/depend/zcash/src/script/zcash_script.h +++ b/depend/zcash/src/script/zcash_script.h @@ -57,6 +57,7 @@ enum zcash_script_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), // enable CHECKLOCKTIMEVERIFY (BIP65) }; +#if 0 /// Deserializes the given transaction and precomputes values to improve /// script verification performance. /// @@ -69,10 +70,10 @@ enum /// after this function returns. /// /// If not NULL, err will contain an error/success code for the operation. -// void* zcash_script_new_precomputed_tx( -// const unsigned char* txTo, -// unsigned int txToLen, -// zcash_script_error* err); +void* zcash_script_new_precomputed_tx( + const unsigned char* txTo, + unsigned int txToLen, + zcash_script_error* err); /// Deserializes the given transaction and precomputes values to improve /// script verification performance. Must be used for V5 transactions; @@ -88,16 +89,16 @@ enum /// zcash_script_free_precomputed_tx once you are done. /// /// If not NULL, err will contain an error/success code for the operation. -// void* zcash_script_new_precomputed_tx_v5( -// const unsigned char* txTo, -// unsigned int txToLen, -// const unsigned char* allPrevOutputs, -// unsigned int allPrevOutputsLen, -// zcash_script_error* err); +void* zcash_script_new_precomputed_tx_v5( + const unsigned char* txTo, + unsigned int txToLen, + const unsigned char* allPrevOutputs, + unsigned int allPrevOutputsLen, + zcash_script_error* err); /// Frees a precomputed transaction previously created with /// zcash_script_new_precomputed_tx. -// void zcash_script_free_precomputed_tx(void* preTx); +void zcash_script_free_precomputed_tx(void* preTx); /// Returns 1 if the input nIn of the precomputed transaction pointed to by /// preTx correctly spends the scriptPubKey pointed to by scriptPubKey under @@ -106,15 +107,15 @@ enum /// If not NULL, err will contain an error/success code for the operation. /// Note that script verification failure is indicated by err being set to /// zcash_script_ERR_OK and a return value of 0. -// EXPORT_SYMBOL int zcash_script_verify_precomputed( -// const void* preTx, -// unsigned int nIn, -// const unsigned char* scriptPubKey, -// unsigned int scriptPubKeyLen, -// int64_t amount, -// unsigned int flags, -// uint32_t consensusBranchId, -// zcash_script_error* err); +EXPORT_SYMBOL int zcash_script_verify_precomputed( + const void* preTx, + unsigned int nIn, + const unsigned char* scriptPubKey, + unsigned int scriptPubKeyLen, + int64_t amount, + unsigned int flags, + uint32_t consensusBranchId, + zcash_script_error* err); /// Returns 1 if the input nIn of the serialized transaction pointed to by /// txTo correctly spends the scriptPubKey pointed to by scriptPubKey under @@ -125,17 +126,14 @@ enum /// If not NULL, err will contain an error/success code for the operation. /// Note that script verification failure is indicated by err being set to /// zcash_script_ERR_OK and a return value of 0. -// EXPORT_SYMBOL int zcash_script_verify( -// const unsigned char* scriptPubKey, -// unsigned int scriptPubKeyLen, -// int64_t amount, -// const unsigned char* txTo, -// unsigned int txToLen, -// unsigned int nIn, -// unsigned int flags, -// uint32_t consensusBranchId, -// zcash_script_error* err); -// +EXPORT_SYMBOL int zcash_script_verify( + const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, + int64_t amount, + const unsigned char *txTo, unsigned int txToLen, + unsigned int nIn, unsigned int flags, + uint32_t consensusBranchId, + zcash_script_error* err); + /// Returns 1 if the input nIn of the serialized transaction pointed to by /// txTo correctly spends the matching output in allPrevOutputs under /// the additional constraints specified by flags. Must be used for V5 transactions; @@ -150,15 +148,15 @@ enum /// If not NULL, err will contain an error/success code for the operation. /// Note that script verification failure is indicated by err being set to /// zcash_script_ERR_OK and a return value of 0. -// EXPORT_SYMBOL int zcash_script_verify_v5( -// const unsigned char* txTo, -// unsigned int txToLen, -// const unsigned char* allPrevOutputs, -// unsigned int allPrevOutputsLen, -// unsigned int nIn, -// unsigned int flags, -// uint32_t consensusBranchId, -// zcash_script_error* err); +EXPORT_SYMBOL int zcash_script_verify_v5( + const unsigned char* txTo, + unsigned int txToLen, + const unsigned char* allPrevOutputs, + unsigned int allPrevOutputsLen, + unsigned int nIn, + unsigned int flags, + uint32_t consensusBranchId, + zcash_script_error* err); /// Returns the number of transparent signature operations in the /// transparent inputs and outputs of the precomputed transaction @@ -166,9 +164,9 @@ enum /// /// Returns UINT_MAX on error, so that invalid transactions don't pass the Zcash consensus rules. /// If not NULL, err will contain an error/success code for the operation. -// EXPORT_SYMBOL unsigned int zcash_script_legacy_sigop_count_precomputed( -// const void* preTx, -// zcash_script_error* err); +EXPORT_SYMBOL unsigned int zcash_script_legacy_sigop_count_precomputed( + const void* preTx, + zcash_script_error* err); /// Returns the number of transparent signature operations in the /// transparent inputs and outputs of the serialized transaction @@ -176,10 +174,11 @@ enum /// /// Returns UINT_MAX on error. /// If not NULL, err will contain an error/success code for the operation. -// EXPORT_SYMBOL unsigned int zcash_script_legacy_sigop_count( -// const unsigned char* txTo, -// unsigned int txToLen, -// zcash_script_error* err); +EXPORT_SYMBOL unsigned int zcash_script_legacy_sigop_count( + const unsigned char* txTo, + unsigned int txToLen, + zcash_script_error* err); +#endif /// Returns the current version of the zcash_script library. EXPORT_SYMBOL unsigned int zcash_script_version(); From 53ff7ea44e0f6e49a57d51317c01a07128173b75 Mon Sep 17 00:00:00 2001 From: Conrado Gouvea Date: Fri, 24 May 2024 11:38:47 -0300 Subject: [PATCH 07/16] tmp --- depend/zcash/src/script/interpreter.cpp | 26 ++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/depend/zcash/src/script/interpreter.cpp b/depend/zcash/src/script/interpreter.cpp index 1e581738c..7c8d0f2bb 100644 --- a/depend/zcash/src/script/interpreter.cpp +++ b/depend/zcash/src/script/interpreter.cpp @@ -23,6 +23,8 @@ using namespace std; typedef vector valtype; +static void dump(const void *p, size_t len) { const unsigned char *a = (const unsigned char*) p; size_t i; for (i = 0; i < len; i++) { printf("%02X", a[i]); } puts(""); } + namespace { inline bool set_success(ScriptError* ret) @@ -1402,7 +1404,14 @@ bool TransactionSignatureChecker::CheckSig( uint256 sighash; try { + puts("scriptCode:"); + dump(&*scriptCode.begin(), scriptCode.size()); + printf("nIn = %d\n", nIn); + printf("nHashType = %d\n", nHashType); + printf("amount = %ld\n", amount); + printf("consensusBranchId = %d\n", consensusBranchId); sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, consensusBranchId, this->txdata); + printf("sighash = %s\n", sighash.GetHex().c_str()); } catch (logic_error ex) { return false; } @@ -1478,8 +1487,12 @@ bool CallbackTransactionSignatureChecker::CheckSig( try { std::array sighashArray; auto scriptBase = static_cast(scriptCode); + puts("scriptCode:"); + dump(&scriptBase[0], scriptBase.size()); + printf("nHashType = %d\n", nHashType); this->sighash(sighashArray.begin(), this->tx, &scriptBase[0], scriptBase.size(), nHashType); sighash = uint256::FromRawBytes(sighashArray); + printf("sighash = %s\n", sighash.GetHex().c_str()); } catch (logic_error ex) { return false; } @@ -1572,13 +1585,24 @@ bool VerifyScript( CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end()); popstack(stack); + printf("stack: %ld\n", stack.size()); + for (int i = 0; i < stack.size(); i++) { + dump(&*stack[i].begin(), stack[i].size()); + } + puts("pubKey2:"); + dump(&*pubKey2.begin(), pubKey2.size()); + printf("flags: %d\n", flags); + printf("consensusBranchId: %d\n", flags); if (!EvalScript(stack, pubKey2, flags, checker, consensusBranchId, serror)) // serror is set return false; if (stack.empty()) return set_error(serror, (ScriptError_t)(SCRIPT_ERR_EVAL_FALSE + 103)); - if (!CastToBool(stack.back())) + if (!CastToBool(stack.back())) { + puts("CastToBool failed!"); return set_error(serror, (ScriptError_t)(SCRIPT_ERR_EVAL_FALSE + 104)); + } + puts("CastToBool worked!"); } // The CLEANSTACK check is only performed after potential P2SH evaluation, From 5443ed205246e3a550b2284ba1f9e7a620210819 Mon Sep 17 00:00:00 2001 From: Conrado Gouvea Date: Fri, 24 May 2024 14:07:09 -0300 Subject: [PATCH 08/16] remove debug prints --- depend/zcash/src/script/interpreter.cpp | 26 +------------------------ 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/depend/zcash/src/script/interpreter.cpp b/depend/zcash/src/script/interpreter.cpp index 7c8d0f2bb..1e581738c 100644 --- a/depend/zcash/src/script/interpreter.cpp +++ b/depend/zcash/src/script/interpreter.cpp @@ -23,8 +23,6 @@ using namespace std; typedef vector valtype; -static void dump(const void *p, size_t len) { const unsigned char *a = (const unsigned char*) p; size_t i; for (i = 0; i < len; i++) { printf("%02X", a[i]); } puts(""); } - namespace { inline bool set_success(ScriptError* ret) @@ -1404,14 +1402,7 @@ bool TransactionSignatureChecker::CheckSig( uint256 sighash; try { - puts("scriptCode:"); - dump(&*scriptCode.begin(), scriptCode.size()); - printf("nIn = %d\n", nIn); - printf("nHashType = %d\n", nHashType); - printf("amount = %ld\n", amount); - printf("consensusBranchId = %d\n", consensusBranchId); sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, consensusBranchId, this->txdata); - printf("sighash = %s\n", sighash.GetHex().c_str()); } catch (logic_error ex) { return false; } @@ -1487,12 +1478,8 @@ bool CallbackTransactionSignatureChecker::CheckSig( try { std::array sighashArray; auto scriptBase = static_cast(scriptCode); - puts("scriptCode:"); - dump(&scriptBase[0], scriptBase.size()); - printf("nHashType = %d\n", nHashType); this->sighash(sighashArray.begin(), this->tx, &scriptBase[0], scriptBase.size(), nHashType); sighash = uint256::FromRawBytes(sighashArray); - printf("sighash = %s\n", sighash.GetHex().c_str()); } catch (logic_error ex) { return false; } @@ -1585,24 +1572,13 @@ bool VerifyScript( CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end()); popstack(stack); - printf("stack: %ld\n", stack.size()); - for (int i = 0; i < stack.size(); i++) { - dump(&*stack[i].begin(), stack[i].size()); - } - puts("pubKey2:"); - dump(&*pubKey2.begin(), pubKey2.size()); - printf("flags: %d\n", flags); - printf("consensusBranchId: %d\n", flags); if (!EvalScript(stack, pubKey2, flags, checker, consensusBranchId, serror)) // serror is set return false; if (stack.empty()) return set_error(serror, (ScriptError_t)(SCRIPT_ERR_EVAL_FALSE + 103)); - if (!CastToBool(stack.back())) { - puts("CastToBool failed!"); + if (!CastToBool(stack.back())) return set_error(serror, (ScriptError_t)(SCRIPT_ERR_EVAL_FALSE + 104)); - } - puts("CastToBool worked!"); } // The CLEANSTACK check is only performed after potential P2SH evaluation, From ae20f1499353eb5dff08ff53041bc3ad54dadd7a Mon Sep 17 00:00:00 2001 From: Conrado Gouvea Date: Fri, 24 May 2024 14:16:29 -0300 Subject: [PATCH 09/16] cleanups --- depend/zcash/src/script/interpreter.cpp | 8 ++++---- depend/zcash/src/script/zcash_script.cpp | 14 +++++--------- depend/zcash/src/script/zcash_script.h | 4 ++-- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/depend/zcash/src/script/interpreter.cpp b/depend/zcash/src/script/interpreter.cpp index 1e581738c..9cfb757a5 100644 --- a/depend/zcash/src/script/interpreter.cpp +++ b/depend/zcash/src/script/interpreter.cpp @@ -1549,9 +1549,9 @@ bool VerifyScript( // serror is set return false; if (stack.empty()) - return set_error(serror, (ScriptError_t)(SCRIPT_ERR_EVAL_FALSE + 101)); + return set_error(serror, SCRIPT_ERR_EVAL_FALSE); if (CastToBool(stack.back()) == false) - return set_error(serror, (ScriptError_t)(SCRIPT_ERR_EVAL_FALSE + 102)); + return set_error(serror, SCRIPT_ERR_EVAL_FALSE); // Additional validation for spend-to-script-hash transactions: if ((flags & SCRIPT_VERIFY_P2SH) && scriptPubKey.IsPayToScriptHash()) @@ -1576,9 +1576,9 @@ bool VerifyScript( // serror is set return false; if (stack.empty()) - return set_error(serror, (ScriptError_t)(SCRIPT_ERR_EVAL_FALSE + 103)); + return set_error(serror, SCRIPT_ERR_EVAL_FALSE); if (!CastToBool(stack.back())) - return set_error(serror, (ScriptError_t)(SCRIPT_ERR_EVAL_FALSE + 104)); + return set_error(serror, SCRIPT_ERR_EVAL_FALSE); } // The CLEANSTACK check is only performed after potential P2SH evaluation, diff --git a/depend/zcash/src/script/zcash_script.cpp b/depend/zcash/src/script/zcash_script.cpp index b322f8715..670e8c2f9 100644 --- a/depend/zcash/src/script/zcash_script.cpp +++ b/depend/zcash/src/script/zcash_script.cpp @@ -298,8 +298,8 @@ unsigned int zcash_script_legacy_sigop_count_script( } int zcash_script_verify_callback( - const void* tx, - void (*sighash)(unsigned char* sighash, const void* tx, const unsigned char* scriptCode, unsigned int scriptCodeLen, int hashType), + const void* ctx, + void (*sighash)(unsigned char* sighash, const void* ctx, const unsigned char* scriptCode, unsigned int scriptCodeLen, int hashType), int64_t nLockTime, uint8_t isFinal, const unsigned char* scriptPubKey, @@ -316,18 +316,14 @@ int zcash_script_verify_callback( set_error(err, zcash_script_ERR_OK); CScriptNum nLockTimeNum = CScriptNum(nLockTime); ScriptError script_err = SCRIPT_ERR_OK; - bool r = VerifyScript( + return VerifyScript( CScript(scriptSig, scriptSig + scriptSigLen), CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), flags, - CallbackTransactionSignatureChecker(tx, sighash, nLockTimeNum, isFinal != 0, nIn, amount), + CallbackTransactionSignatureChecker(ctx, sighash, nLockTimeNum, isFinal != 0, nIn, amount), consensusBranchId, &script_err); - if (!r) { - return set_error(err, (zcash_script_error_t)((zcash_script_error_t)1000 + (zcash_script_error_t)script_err)); - } - return r; } catch (const std::exception&) { - return set_error(err, zcash_script_ERR_VERIFY_SCRIPT); // Error deserializing + return set_error(err, zcash_script_ERR_VERIFY_SCRIPT); } } diff --git a/depend/zcash/src/script/zcash_script.h b/depend/zcash/src/script/zcash_script.h index 475a0f3ee..351dc5a79 100644 --- a/depend/zcash/src/script/zcash_script.h +++ b/depend/zcash/src/script/zcash_script.h @@ -188,8 +188,8 @@ EXPORT_SYMBOL unsigned int zcash_script_legacy_sigop_count_script( unsigned int scriptLen); EXPORT_SYMBOL int zcash_script_verify_callback( - const void* tx, - void (*sighash)(unsigned char* sighash, const void* tx, const unsigned char* scriptCode, unsigned int scriptCodeLen, int hashType), + const void* ctx, + void (*sighash)(unsigned char* sighash, const void* ctx, const unsigned char* scriptCode, unsigned int scriptCodeLen, int hashType), int64_t nLockTime, uint8_t isFinal, const unsigned char* scriptPubKey, From 8676b2a9ff700c4add23043f73d393e283d6b501 Mon Sep 17 00:00:00 2001 From: Conrado Gouvea Date: Fri, 24 May 2024 17:51:38 -0300 Subject: [PATCH 10/16] deleted unneeded rust files --- src/blake2b.rs | 1 - src/bridge.rs | 1 - src/builder_ffi.rs | 1 - src/bundlecache.rs | 3 -- src/incremental_merkle_tree.rs | 1 - src/lib.rs | 57 ---------------------------------- src/merkle_frontier.rs | 1 - src/note_encryption.rs | 1 - src/orchard_bundle.rs | 1 - src/orchard_ffi.rs | 1 - src/params.rs | 1 - src/sapling.rs | 3 -- src/streams.rs | 1 - src/streams_ffi.rs | 1 - src/test_harness_ffi.rs | 1 - src/transaction_ffi.rs | 1 - src/wallet.rs | 1 - src/wallet_scanner.rs | 1 - src/zcashd_orchard.rs | 1 - 19 files changed, 79 deletions(-) delete mode 100644 src/blake2b.rs delete mode 100644 src/bridge.rs delete mode 100644 src/builder_ffi.rs delete mode 100644 src/bundlecache.rs delete mode 100644 src/incremental_merkle_tree.rs delete mode 100644 src/merkle_frontier.rs delete mode 100644 src/note_encryption.rs delete mode 100644 src/orchard_bundle.rs delete mode 100644 src/orchard_ffi.rs delete mode 100644 src/params.rs delete mode 100644 src/sapling.rs delete mode 100644 src/streams.rs delete mode 100644 src/streams_ffi.rs delete mode 100644 src/test_harness_ffi.rs delete mode 100644 src/transaction_ffi.rs delete mode 100644 src/wallet.rs delete mode 100644 src/wallet_scanner.rs delete mode 100644 src/zcashd_orchard.rs diff --git a/src/blake2b.rs b/src/blake2b.rs deleted file mode 100644 index 3410d1b13..000000000 --- a/src/blake2b.rs +++ /dev/null @@ -1 +0,0 @@ -include!("../depend/zcash/src/rust/src/blake2b.rs"); diff --git a/src/bridge.rs b/src/bridge.rs deleted file mode 100644 index 83a5aa20e..000000000 --- a/src/bridge.rs +++ /dev/null @@ -1 +0,0 @@ -include!("../depend/zcash/src/rust/src/bridge.rs"); diff --git a/src/builder_ffi.rs b/src/builder_ffi.rs deleted file mode 100644 index e44fa5bf1..000000000 --- a/src/builder_ffi.rs +++ /dev/null @@ -1 +0,0 @@ -include!("../depend/zcash/src/rust/src/builder_ffi.rs"); diff --git a/src/bundlecache.rs b/src/bundlecache.rs deleted file mode 100644 index 01173034b..000000000 --- a/src/bundlecache.rs +++ /dev/null @@ -1,3 +0,0 @@ -#![allow(dead_code)] - -include!("../depend/zcash/src/rust/src/bundlecache.rs"); diff --git a/src/incremental_merkle_tree.rs b/src/incremental_merkle_tree.rs deleted file mode 100644 index c3076ba63..000000000 --- a/src/incremental_merkle_tree.rs +++ /dev/null @@ -1 +0,0 @@ -include!("../depend/zcash/src/rust/src/incremental_merkle_tree.rs"); diff --git a/src/lib.rs b/src/lib.rs index f9d8af635..3f53fa8c9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,63 +13,6 @@ // Use the generated C++ bindings include!(concat!(env!("OUT_DIR"), "/bindings.rs")); - -// // Include the items from depend/zcash/src/rust/src/rustzcash.rs (librustzcash/lib.rs) -// // that we need - -use ::sapling::circuit::{ - OutputParameters, OutputVerifyingKey, SpendParameters, SpendVerifyingKey, -}; - -// /// The code that uses this constant is not called by zcash_script. -// static mut SAPLING_SPEND_VK: Option = None; -// /// The code that uses this constant is not called by zcash_script. -// static mut SAPLING_OUTPUT_VK: Option = None; -// /// The code that uses this constant is not called by zcash_script. -// static mut SAPLING_SPEND_PARAMS: Option = None; -// /// The code that uses this constant is not called by zcash_script. -// static mut SAPLING_OUTPUT_PARAMS: Option = None; - -// /// The code that uses this constant is not called by zcash_script. -// static mut ORCHARD_PK: Option = None; -// /// The code that uses this constant is not called by zcash_script. -// static mut ORCHARD_VK: Option = None; - -// /// Converts CtOption into Option -// fn de_ct(ct: subtle::CtOption) -> Option { -// if ct.is_some().into() { -// Some(ct.unwrap()) -// } else { -// None -// } -// } - -// /// The size of a Groth16 Sapling proof. -// const GROTH_PROOF_SIZE: usize = 48 // π_A -// + 96 // π_B -// + 48; // π_C - -// Include the modules from depend/zcash/src/rust (librustzcash) that we need -// mod blake2b; -// mod bridge; -// mod bundlecache; -// mod incremental_merkle_tree; -// mod merkle_frontier; -// mod note_encryption; -// mod orchard_bundle; -// mod params; -// mod sapling; -// mod streams; -// mod test_harness_ffi; -// mod wallet; -// mod wallet_scanner; -// mod zcashd_orchard; - -// mod builder_ffi; -// mod orchard_ffi; -// mod streams_ffi; -// mod transaction_ffi; - #[cfg(test)] mod tests { pub use super::zcash_script_error_t; diff --git a/src/merkle_frontier.rs b/src/merkle_frontier.rs deleted file mode 100644 index 7af85eb83..000000000 --- a/src/merkle_frontier.rs +++ /dev/null @@ -1 +0,0 @@ -include!("../depend/zcash/src/rust/src/merkle_frontier.rs"); diff --git a/src/note_encryption.rs b/src/note_encryption.rs deleted file mode 100644 index 4657dfa35..000000000 --- a/src/note_encryption.rs +++ /dev/null @@ -1 +0,0 @@ -include!("../depend/zcash/src/rust/src/note_encryption.rs"); diff --git a/src/orchard_bundle.rs b/src/orchard_bundle.rs deleted file mode 100644 index 0ae3b226f..000000000 --- a/src/orchard_bundle.rs +++ /dev/null @@ -1 +0,0 @@ -include!("../depend/zcash/src/rust/src/orchard_bundle.rs"); diff --git a/src/orchard_ffi.rs b/src/orchard_ffi.rs deleted file mode 100644 index a63a834c1..000000000 --- a/src/orchard_ffi.rs +++ /dev/null @@ -1 +0,0 @@ -include!("../depend/zcash/src/rust/src/orchard_ffi.rs"); diff --git a/src/params.rs b/src/params.rs deleted file mode 100644 index 870533ff7..000000000 --- a/src/params.rs +++ /dev/null @@ -1 +0,0 @@ -include!("../depend/zcash/src/rust/src/params.rs"); diff --git a/src/sapling.rs b/src/sapling.rs deleted file mode 100644 index 1628a6e51..000000000 --- a/src/sapling.rs +++ /dev/null @@ -1,3 +0,0 @@ -// Note that don't include the original file directly; but rather -// a copy of sapling.rs with name changed. See build.rs for the explanation. -include!(concat!(env!("OUT_DIR"), "/rust/sapling/mod.rs")); diff --git a/src/streams.rs b/src/streams.rs deleted file mode 100644 index 804d00707..000000000 --- a/src/streams.rs +++ /dev/null @@ -1 +0,0 @@ -include!("../depend/zcash/src/rust/src/streams.rs"); diff --git a/src/streams_ffi.rs b/src/streams_ffi.rs deleted file mode 100644 index 1e8edd9a6..000000000 --- a/src/streams_ffi.rs +++ /dev/null @@ -1 +0,0 @@ -include!("../depend/zcash/src/rust/src/streams_ffi.rs"); diff --git a/src/test_harness_ffi.rs b/src/test_harness_ffi.rs deleted file mode 100644 index 35a4fedf6..000000000 --- a/src/test_harness_ffi.rs +++ /dev/null @@ -1 +0,0 @@ -include!("../depend/zcash/src/rust/src/test_harness_ffi.rs"); diff --git a/src/transaction_ffi.rs b/src/transaction_ffi.rs deleted file mode 100644 index 317599c51..000000000 --- a/src/transaction_ffi.rs +++ /dev/null @@ -1 +0,0 @@ -include!("../depend/zcash/src/rust/src/transaction_ffi.rs"); diff --git a/src/wallet.rs b/src/wallet.rs deleted file mode 100644 index 334b3fc4b..000000000 --- a/src/wallet.rs +++ /dev/null @@ -1 +0,0 @@ -include!("../depend/zcash/src/rust/src/wallet.rs"); diff --git a/src/wallet_scanner.rs b/src/wallet_scanner.rs deleted file mode 100644 index 037828f64..000000000 --- a/src/wallet_scanner.rs +++ /dev/null @@ -1 +0,0 @@ -include!("../depend/zcash/src/rust/src/wallet_scanner.rs"); diff --git a/src/zcashd_orchard.rs b/src/zcashd_orchard.rs deleted file mode 100644 index bd3ebd06c..000000000 --- a/src/zcashd_orchard.rs +++ /dev/null @@ -1 +0,0 @@ -include!("../depend/zcash/src/rust/src/zcashd_orchard.rs"); From 153eb35d1aa710b70a5396b542e155c5bbc4635f Mon Sep 17 00:00:00 2001 From: Conrado Gouvea Date: Fri, 24 May 2024 18:21:10 -0300 Subject: [PATCH 11/16] remove unneeded dependencies --- Cargo.lock | 1777 ++++------------------------------------------------ Cargo.toml | 31 - build.rs | 13 - 3 files changed, 129 insertions(+), 1692 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 85d76e3dc..8c0f6bfcd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,39 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "aead" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" -dependencies = [ - "crypto-common", - "generic-array", -] - -[[package]] -name = "aes" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[package]] -name = "ahash" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b79b82693f705137f8fb9b37871d99e4f9a7df12b917eed79c3d3954830a60b" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "aho-corasick" version = "1.0.5" @@ -44,64 +11,13 @@ dependencies = [ "memchr", ] -[[package]] -name = "arrayref" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" - -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "base64ct" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" - -[[package]] -name = "bech32" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" - -[[package]] -name = "bellman" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afceed28bac7f9f5a508bca8aeeff51cdfa4770c0b967ac55c621e2ddfd6171" -dependencies = [ - "bitvec", - "blake2s_simd", - "byteorder", - "crossbeam-channel", - "ff", - "group", - "lazy_static", - "log", - "num_cpus", - "pairing", - "rand_core", - "rayon", - "subtle", -] - [[package]] name = "bindgen" version = "0.69.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" dependencies = [ - "bitflags 2.4.0", + "bitflags", "cexpr", "clang-sys", "itertools", @@ -118,143 +34,12 @@ dependencies = [ "which", ] -[[package]] -name = "bip0039" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef0f0152ec5cf17f49a5866afaa3439816207fd4f0a224c0211ffaf5e278426" -dependencies = [ - "hmac", - "pbkdf2", - "rand", - "sha2", - "unicode-normalization", - "zeroize", -] - -[[package]] -name = "bit-set" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - -[[package]] -name = "blake2b_simd" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" -dependencies = [ - "arrayref", - "arrayvec", - "constant_time_eq", -] - -[[package]] -name = "blake2s_simd" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94230421e395b9920d23df13ea5d77a20e1725331f90fbbf6df6040b33f756ae" -dependencies = [ - "arrayref", - "arrayvec", - "constant_time_eq", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bls12_381" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc6d6292be3a19e6379786dac800f551e5865a5bb51ebbe3064ab80433f403" -dependencies = [ - "ff", - "group", - "pairing", - "rand_core", - "subtle", -] - -[[package]] -name = "bridgetree" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbfcb6c5a091e80cb3d3b0c1a7f126af4631cd5065b1f9929b139f1be8f3fb62" -dependencies = [ - "incrementalmerkletree", -] - -[[package]] -name = "bs58" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" -dependencies = [ - "sha2", - "tinyvec", -] - -[[package]] -name = "bumpalo" -version = "3.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "cbc" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" -dependencies = [ - "cipher", -] - [[package]] name = "cc" version = "1.0.95" @@ -281,41 +66,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "chacha20" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[package]] -name = "chacha20poly1305" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" -dependencies = [ - "aead", - "chacha20", - "cipher", - "poly1305", - "zeroize", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", - "zeroize", -] - [[package]] name = "clang-sys" version = "1.6.1" @@ -337,92 +87,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "constant_time_eq" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" - -[[package]] -name = "cpufeatures" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" -dependencies = [ - "libc", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "cxx" -version = "1.0.113" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "048948e14bc2c2652ec606c8e3bb913407f0187288fb351a0b2d972beaf12070" -dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", -] - [[package]] name = "cxx-gen" version = "0.7.121" @@ -435,59 +99,12 @@ dependencies = [ "syn 2.0.58", ] -[[package]] -name = "cxxbridge-flags" -version = "1.0.113" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af40b0467c68d3d9fb7550ef984edc8ad47252f703ef0f1f2d1052e0e4af8793" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.113" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743446286141c9f6d4497c493c01234eb848e14d2e20866ae9811eae0630cb9" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", - "subtle", -] - -[[package]] -name = "document-features" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef5282ad69563b5fc40319526ba27e0e7363d552a896f0297d54f767717f9b95" -dependencies = [ - "litrs", -] - [[package]] name = "either" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" -[[package]] -name = "equihash" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab579d7cf78477773b03e80bc2f89702ef02d7112c711d54ca93dcdce68533d5" -dependencies = [ - "blake2b_simd", - "byteorder", -] - [[package]] name = "errno" version = "0.3.3" @@ -500,1183 +117,246 @@ dependencies = [ ] [[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "f4jumble" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a83e8d7fd0c526af4aad893b7c9fe41e2699ed8a776a6c74aecdeafe05afc75" -dependencies = [ - "blake2b_simd", -] - -[[package]] -name = "fastrand" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" - -[[package]] -name = "ff" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" -dependencies = [ - "bitvec", - "rand_core", - "subtle", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "fpe" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c4b37de5ae15812a764c958297cfc50f5c010438f60c6ce75d11b802abd404" -dependencies = [ - "cbc", - "cipher", - "libm", - "num-bigint", - "num-integer", - "num-traits", -] - -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff", - "memuse", - "rand_core", - "subtle", -] - -[[package]] -name = "halo2_gadgets" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126a150072b0c38c7b573fe3eaf0af944a7fed09e154071bf2436d3f016f7230" -dependencies = [ - "arrayvec", - "bitvec", - "ff", - "group", - "halo2_proofs", - "lazy_static", - "pasta_curves", - "rand", - "subtle", - "uint", -] - -[[package]] -name = "halo2_legacy_pdqsort" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47716fe1ae67969c5e0b2ef826f32db8c3be72be325e1aa3c1951d06b5575ec5" - -[[package]] -name = "halo2_proofs" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b867a8d9bbb85fca76fff60652b5cd19b853a1c4d0665cb89bee68b18d2caf0" -dependencies = [ - "blake2b_simd", - "ff", - "group", - "halo2_legacy_pdqsort", - "maybe-rayon", - "pasta_curves", - "rand_core", - "tracing", -] - -[[package]] -name = "hdwallet" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a03ba7d4c9ea41552cd4351965ff96883e629693ae85005c501bb4b9e1c48a7" -dependencies = [ - "lazy_static", - "rand_core", - "ring", - "secp256k1", - "thiserror", -] - -[[package]] -name = "hermit-abi" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] - -[[package]] -name = "home" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "incrementalmerkletree" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "361c467824d4d9d4f284be4b2608800839419dccc4d4608f28345237fe354623" -dependencies = [ - "either", - "proptest", -] - -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "generic-array", -] - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "jobserver" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" -dependencies = [ - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "jubjub" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8499f7a74008aafbecb2a2e608a3e13e4dd3e84df198b604451efe93f2de6e61" -dependencies = [ - "bitvec", - "bls12_381", - "ff", - "group", - "rand_core", - "subtle", -] - -[[package]] -name = "known-folders" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b6f1427d9c43b1cce87434c4d9eca33f43bdbb6246a762aa823a582f74c1684" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -dependencies = [ - "spin", -] - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] -name = "libc" -version = "0.2.148" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" - -[[package]] -name = "libloading" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] - -[[package]] -name = "libm" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" - -[[package]] -name = "link-cplusplus" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9" -dependencies = [ - "cc", -] - -[[package]] -name = "linux-raw-sys" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" - -[[package]] -name = "litrs" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" - -[[package]] -name = "log" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" - -[[package]] -name = "maybe-rayon" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" -dependencies = [ - "cfg-if", - "rayon", -] - -[[package]] -name = "memchr" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" - -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - -[[package]] -name = "memuse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2145869435ace5ea6ea3d35f59be559317ec9a0d04e1812d5f185a87b6d36f1a" -dependencies = [ - "nonempty", -] - -[[package]] -name = "metrics" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fde3af1a009ed76a778cb84fdef9e7dbbdf5775ae3e4cc1f434a6a307f6f76c5" -dependencies = [ - "ahash", - "metrics-macros", - "portable-atomic", -] - -[[package]] -name = "metrics-macros" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddece26afd34c31585c74a4db0630c376df271c285d682d1e55012197830b6df" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", -] - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "nonempty" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7" - -[[package]] -name = "num-bigint" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" -dependencies = [ - "autocfg", - "libm", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "orchard" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb255c3ffdccd3c84fe9ebed72aef64fdc72e6a3e4180dd411002d47abaad42" -dependencies = [ - "aes", - "bitvec", - "blake2b_simd", - "ff", - "fpe", - "group", - "halo2_gadgets", - "halo2_proofs", - "hex", - "incrementalmerkletree", - "lazy_static", - "memuse", - "nonempty", - "pasta_curves", - "proptest", - "rand", - "reddsa", - "serde", - "subtle", - "tracing", - "zcash_note_encryption", - "zcash_spec", - "zip32", -] - -[[package]] -name = "pairing" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" -dependencies = [ - "group", -] - -[[package]] -name = "password-hash" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d791538a6dcc1e7cb7fe6f6b58aca40e7f79403c45b2bc274008b5e647af1d8" -dependencies = [ - "base64ct", - "rand_core", - "subtle", -] - -[[package]] -name = "pasta_curves" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e57598f73cc7e1b2ac63c79c517b31a0877cd7c402cdcaa311b5208de7a095" -dependencies = [ - "blake2b_simd", - "ff", - "group", - "lazy_static", - "rand", - "static_assertions", - "subtle", -] - -[[package]] -name = "pbkdf2" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271779f35b581956db91a3e55737327a03aa051e90b1c47aeb189508533adfd7" -dependencies = [ - "digest", - "password-hash", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" - -[[package]] -name = "poly1305" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" -dependencies = [ - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "portable-atomic" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31114a898e107c51bb1609ffaf55a0e011cf6a4d7f1170d0015a165082c0338b" - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "prettyplease" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" -dependencies = [ - "proc-macro2", - "syn 2.0.58", -] - -[[package]] -name = "proc-macro2" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "proptest" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e35c06b98bf36aba164cc17cb25f7e232f5c4aeea73baa14b8a9f0d92dbfa65" -dependencies = [ - "bit-set", - "bitflags 1.3.2", - "byteorder", - "lazy_static", - "num-traits", - "rand", - "rand_chacha", - "rand_xorshift", - "regex-syntax 0.6.29", - "rusty-fork", - "tempfile", - "unarray", -] - -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - -[[package]] -name = "quote" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_xorshift" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" -dependencies = [ - "rand_core", -] - -[[package]] -name = "rayon" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - -[[package]] -name = "reddsa" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78a5191930e84973293aa5f532b513404460cd2216c1cfb76d08748c15b40b02" -dependencies = [ - "blake2b_simd", - "byteorder", - "group", - "hex", - "jubjub", - "pasta_curves", - "rand_core", - "serde", - "thiserror", - "zeroize", -] - -[[package]] -name = "redjubjub" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a60db2c3bc9c6fd1e8631fee75abc008841d27144be744951d6b9b75f9b569c" -dependencies = [ - "rand_core", - "reddsa", - "serde", - "thiserror", - "zeroize", -] - -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "regex" -version = "1.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax 0.7.5", -] - -[[package]] -name = "regex-automata" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax 0.7.5", -] - -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" - -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin", - "untrusted", - "web-sys", - "winapi", -] - -[[package]] -name = "ripemd" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" -dependencies = [ - "digest", -] - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustix" -version = "0.38.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662" -dependencies = [ - "bitflags 2.4.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys", -] - -[[package]] -name = "rusty-fork" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" -dependencies = [ - "fnv", - "quick-error", - "tempfile", - "wait-timeout", -] - -[[package]] -name = "sapling-crypto" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02f4270033afcb0c74c5c7d59c73cfd1040367f67f224fe7ed9a919ae618f1b7" -dependencies = [ - "aes", - "bellman", - "bitvec", - "blake2b_simd", - "blake2s_simd", - "bls12_381", - "byteorder", - "document-features", - "ff", - "fpe", - "group", - "hex", - "incrementalmerkletree", - "jubjub", - "lazy_static", - "memuse", - "proptest", - "rand", - "rand_core", - "redjubjub", - "subtle", - "tracing", - "zcash_note_encryption", - "zcash_spec", - "zip32", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "secp256k1" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4124a35fe33ae14259c490fd70fa199a32b9ce9502f2ee6bc4f81ec06fa65894" -dependencies = [ - "secp256k1-sys", -] - -[[package]] -name = "secp256k1-sys" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" -dependencies = [ - "cc", -] - -[[package]] -name = "serde" -version = "1.0.188" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.188" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", -] - -[[package]] -name = "sha2" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "shlex" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" - -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "syn" -version = "1.0.109" +name = "errno-dragonfly" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "cc", + "libc", ] [[package]] -name = "syn" -version = "2.0.58" +name = "glob" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] -name = "tap" -version = "1.0.1" +name = "hex" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] -name = "tempfile" -version = "3.8.0" +name = "home" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" dependencies = [ - "cfg-if", - "fastrand", - "redox_syscall", - "rustix", "windows-sys", ] [[package]] -name = "termcolor" -version = "1.2.0" +name = "itertools" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" dependencies = [ - "winapi-util", + "either", ] [[package]] -name = "thiserror" -version = "1.0.48" +name = "jobserver" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" dependencies = [ - "thiserror-impl", + "libc", ] [[package]] -name = "thiserror-impl" -version = "1.0.48" +name = "lazy_static" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", -] +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] -name = "tinyvec" -version = "1.6.0" +name = "lazycell" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] -name = "tinyvec_macros" -version = "0.1.1" +name = "libc" +version = "0.2.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" [[package]] -name = "tracing" -version = "0.1.37" +name = "libloading" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" dependencies = [ "cfg-if", - "pin-project-lite", - "tracing-attributes", - "tracing-core", + "winapi", ] [[package]] -name = "tracing-attributes" -version = "0.1.26" +name = "linux-raw-sys" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", -] +checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" [[package]] -name = "tracing-core" -version = "0.1.31" +name = "log" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" -dependencies = [ - "once_cell", -] +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] -name = "typenum" -version = "1.17.0" +name = "memchr" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" [[package]] -name = "uint" -version = "0.9.5" +name = "minimal-lexical" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] -name = "unarray" -version = "0.1.4" +name = "nom" +version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] [[package]] -name = "unicode-ident" -version = "1.0.12" +name = "once_cell" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] -name = "unicode-normalization" -version = "0.1.22" +name = "prettyplease" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ - "tinyvec", + "proc-macro2", + "syn 2.0.58", ] [[package]] -name = "unicode-width" -version = "0.1.10" +name = "proc-macro2" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +dependencies = [ + "unicode-ident", +] [[package]] -name = "universal-hash" -version = "0.5.1" +name = "quote" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ - "crypto-common", - "subtle", + "proc-macro2", ] [[package]] -name = "untrusted" -version = "0.7.1" +name = "regex" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] [[package]] -name = "version_check" -version = "0.9.4" +name = "regex-automata" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] [[package]] -name = "wait-timeout" -version = "0.2.0" +name = "regex-syntax" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" -dependencies = [ - "libc", -] +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +name = "rustc-hash" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] -name = "wasm-bindgen" -version = "0.2.87" +name = "rustix" +version = "0.38.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662" dependencies = [ - "cfg-if", - "wasm-bindgen-macro", + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", ] [[package]] -name = "wasm-bindgen-backend" -version = "0.2.87" +name = "shlex" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" + +[[package]] +name = "syn" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "bumpalo", - "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.58", - "wasm-bindgen-shared", + "unicode-ident", ] [[package]] -name = "wasm-bindgen-macro" -version = "0.2.87" +name = "syn" +version = "2.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" dependencies = [ + "proc-macro2", "quote", - "wasm-bindgen-macro-support", + "unicode-ident", ] [[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.87" +name = "termcolor" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", - "wasm-bindgen-backend", - "wasm-bindgen-shared", + "winapi-util", ] [[package]] -name = "wasm-bindgen-shared" -version = "0.2.87" +name = "unicode-ident" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "web-sys" -version = "0.3.64" +name = "unicode-width" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" -dependencies = [ - "js-sys", - "wasm-bindgen", -] +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" [[package]] name = "which" @@ -1787,213 +467,14 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "xdg" -version = "2.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" - -[[package]] -name = "zcash_address" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8944af5c206cf2e37020ad54618e1825501b98548d35a638b73e0ec5762df8d5" -dependencies = [ - "bech32", - "bs58", - "f4jumble", - "zcash_encoding", -] - -[[package]] -name = "zcash_encoding" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f03391b81727875efa6ac0661a20883022b6fba92365dc121c48fa9b00c5aac0" -dependencies = [ - "byteorder", - "nonempty", -] - -[[package]] -name = "zcash_note_encryption" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b4580cd6cee12e44421dac43169be8d23791650816bdb34e6ddfa70ac89c1c5" -dependencies = [ - "chacha20", - "chacha20poly1305", - "cipher", - "rand_core", - "subtle", -] - -[[package]] -name = "zcash_primitives" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9070e084570bb78aed4f8d71fd6254492e62c87a5d01e084183980e98117092d" -dependencies = [ - "aes", - "bip0039", - "blake2b_simd", - "byteorder", - "document-features", - "equihash", - "ff", - "fpe", - "group", - "hdwallet", - "hex", - "incrementalmerkletree", - "jubjub", - "memuse", - "nonempty", - "orchard", - "proptest", - "rand", - "rand_core", - "redjubjub", - "ripemd", - "sapling-crypto", - "secp256k1", - "sha2", - "subtle", - "tracing", - "zcash_address", - "zcash_encoding", - "zcash_note_encryption", - "zcash_spec", - "zip32", -] - -[[package]] -name = "zcash_proofs" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a02eb1f151d9b9a6e16408d2c55ff440bd2fb232b7377277146d0fa2df9bc8" -dependencies = [ - "bellman", - "blake2b_simd", - "bls12_381", - "document-features", - "group", - "home", - "jubjub", - "known-folders", - "lazy_static", - "rand_core", - "redjubjub", - "sapling-crypto", - "tracing", - "xdg", - "zcash_primitives", -] - [[package]] name = "zcash_script" version = "0.1.16" dependencies = [ - "bellman", "bindgen", - "blake2b_simd", - "blake2s_simd", - "bls12_381", - "bridgetree", - "byteorder", "cc", - "crossbeam-channel", - "cxx", "cxx-gen", - "group", "hex", - "incrementalmerkletree", - "jubjub", "lazy_static", - "libc", - "memuse", - "metrics", - "orchard", - "rand", - "rand_core", - "rayon", - "redjubjub", - "sapling-crypto", - "subtle", "syn 1.0.109", - "tracing", - "zcash_address", - "zcash_encoding", - "zcash_note_encryption", - "zcash_primitives", - "zcash_proofs", -] - -[[package]] -name = "zcash_spec" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7a3bf58b673cb3dacd8ae09ba345998923a197ab0da70d6239d8e8838949e9b" -dependencies = [ - "blake2b_simd", -] - -[[package]] -name = "zerocopy" -version = "0.7.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", -] - -[[package]] -name = "zeroize" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", -] - -[[package]] -name = "zip32" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4226d0aee9c9407c27064dfeec9d7b281c917de3374e1e5a2e2cfad9e09de19e" -dependencies = [ - "blake2b_simd", - "memuse", - "subtle", ] diff --git a/Cargo.toml b/Cargo.toml index 9e1a131f5..36a34306f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,35 +49,6 @@ path = "src/lib.rs" external-secp = [] [dependencies] -# All these dependencies must match the versions in: -# https://github.com/zcash/zcash/blob//Cargo.toml -bellman = "0.14" -blake2b_simd = "1" -blake2s_simd = "1" -bls12_381 = "0.8" -byteorder = "1" -crossbeam-channel = "0.5" -cxx = { version = "=1.0.113", features = ["c++17"] } -group = "0.13" -incrementalmerkletree = "0.5" -jubjub = "0.10" -libc = "0.2" -memuse = "0.2" -metrics = "0.21" -orchard = "0.7" -rand_core = "0.6" -rayon = "1.5" -redjubjub = "0.7" -sapling = { package = "sapling-crypto", version = "0.1", features = ["temporary-zcashd"] } -subtle = "2.2" -tracing = "0.1" -zcash_address = "0.3" -zcash_encoding = "0.2" -zcash_note_encryption = "0.4" -zcash_primitives = { version = "=0.14.0", features = ["temporary-zcashd", "transparent-inputs"] } -zcash_proofs = { version = "=0.14.0", features = ["directories"] } -bridgetree = "0.4" -rand = "0.8" [build-dependencies] # The `bindgen` dependency should automatically upgrade to match the version used by zebra-state's `rocksdb` dependency in: @@ -101,8 +72,6 @@ syn = { version = "1.0.109", features = ["full", "printing"] } # Treat minor versions with a zero major version as compatible (cargo doesn't by default). hex = ">= 0.4.3" lazy_static = "1.4.0" -incrementalmerkletree = { version = "0.5", features = ["test-dependencies"] } -zcash_primitives = { version = "=0.14.0", features = ["temporary-zcashd", "transparent-inputs", "test-dependencies"] } [[package.metadata.release.pre-release-replacements]] file = "CHANGELOG.md" diff --git a/build.rs b/build.rs index ac11c5db5..a2d7713f3 100644 --- a/build.rs +++ b/build.rs @@ -206,25 +206,12 @@ fn main() -> Result<()> { .file("depend/zcash/src/amount.cpp") .file("depend/zcash/src/uint256.cpp") .file("depend/zcash/src/pubkey.cpp") - // .file("depend/zcash/src/hash.cpp") - // .file("depend/zcash/src/streams_rust.cpp") - //.file("depend/zcash/src/zip317.cpp") - // .file("depend/zcash/src/primitives/transaction.cpp") .file("depend/zcash/src/crypto/ripemd160.cpp") .file("depend/zcash/src/crypto/sha1.cpp") .file("depend/zcash/src/crypto/sha256.cpp") - // .file("depend/zcash/src/crypto/sha512.cpp") - // .file("depend/zcash/src/crypto/hmac_sha512.cpp") .file("depend/zcash/src/script/interpreter.cpp") .file("depend/zcash/src/script/script.cpp") .file("depend/zcash/src/script/script_error.cpp") - // .file("depend/zcash/src/support/cleanse.cpp") - .file("depend/zcash/src/zcash/cache.cpp") - // A subset of the files generated by gen_cxxbridge - // which are required by zcash_script. - // .file(gen_path.join("src/blake2b.cpp")) - // .file(gen_path.join("src/bridge.cpp")) - // .file(gen_path.join("src/streams.cpp")) .compile("libzcash_script.a"); Ok(()) From c9e201a55936a8081387491a6b11e6aa8cd75963 Mon Sep 17 00:00:00 2001 From: Conrado Gouvea Date: Fri, 24 May 2024 21:20:00 -0300 Subject: [PATCH 12/16] remove more unneeded files --- Cargo.lock | 63 +-- Cargo.toml | 48 ++- build.rs | 132 +------ depend/zcash/src/hash.h | 48 --- depend/zcash/src/script/interpreter.cpp | 493 ------------------------ depend/zcash/src/script/interpreter.h | 64 +-- depend/zcash/src/serialize.h | 72 ---- 7 files changed, 39 insertions(+), 881 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8c0f6bfcd..645606228 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,7 +30,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.58", + "syn", "which", ] @@ -77,28 +77,6 @@ dependencies = [ "libloading", ] -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] - -[[package]] -name = "cxx-gen" -version = "0.7.121" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "383ecb9f96a536a1c7a2a61c5786f583da84f9240da149d78d005a4413c9a71e" -dependencies = [ - "codespan-reporting", - "proc-macro2", - "quote", - "syn 2.0.58", -] - [[package]] name = "either" version = "1.9.0" @@ -240,7 +218,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn 2.0.58", + "syn", ] [[package]] @@ -315,17 +293,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.58" @@ -337,27 +304,12 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "termcolor" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" -dependencies = [ - "winapi-util", -] - [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" -[[package]] -name = "unicode-width" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" - [[package]] name = "which" version = "4.4.2" @@ -386,15 +338,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -473,8 +416,6 @@ version = "0.1.16" dependencies = [ "bindgen", "cc", - "cxx-gen", "hex", "lazy_static", - "syn 1.0.109", ] diff --git a/Cargo.toml b/Cargo.toml index 36a34306f..621baf9a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,29 +16,40 @@ include = [ "build.rs", "src/*.rs", "/depend/check_uint128_t.c", - "/depend/zcash/src/script/zcash_script.h", - "/depend/zcash/src/script/zcash_script.cpp", - "/depend/zcash/src/utilstrencodings.cpp", - "/depend/zcash/src/uint256.cpp", - "/depend/zcash/src/pubkey.cpp", - "/depend/zcash/src/hash.cpp", - "/depend/zcash/src/primitives/transaction.cpp", + "/depend/zcash/src/amount.cpp", + "/depend/zcash/src/amount.h", + "/depend/zcash/src/compat/byteswap.h", + "/depend/zcash/src/compat/endian.h", + "/depend/zcash/src/consensus/consensus.h", + "/depend/zcash/src/crypto/common.h", "/depend/zcash/src/crypto/ripemd160.cpp", + "/depend/zcash/src/crypto/ripemd160.h", "/depend/zcash/src/crypto/sha1.cpp", + "/depend/zcash/src/crypto/sha1.h", "/depend/zcash/src/crypto/sha256.cpp", - "/depend/zcash/src/crypto/sha512.cpp", - "/depend/zcash/src/crypto/hmac_sha512.cpp", + "/depend/zcash/src/crypto/sha256.h", + "/depend/zcash/src/hash.h", + "/depend/zcash/src/key_constants.h", + "/depend/zcash/src/prevector.h", + "/depend/zcash/src/primitives/transaction.h", + "/depend/zcash/src/pubkey.cpp", + "/depend/zcash/src/pubkey.h", "/depend/zcash/src/script/interpreter.cpp", - "/depend/zcash/src/script/script.cpp", + "/depend/zcash/src/script/interpreter.h", "/depend/zcash/src/script/script_error.cpp", - "/depend/zcash/src/", - "/depend/zcash/src/rust/include/", - "/depend/zcash/src/secp256k1/include/", + "/depend/zcash/src/script/script_error.h", + "/depend/zcash/src/script/script.cpp", + "/depend/zcash/src/script/script.h", + "/depend/zcash/src/script/zcash_script.cpp", + "/depend/zcash/src/script/zcash_script.h", "/depend/zcash/src/secp256k1/", - "/depend/zcash/src/support/cleanse.cpp", - "/depend/zcash/src/support/cleanse.h", - "/depend/zcash/src/rust/gen/", - "/depend/expected/include/", + "/depend/zcash/src/serialize.h", + "/depend/zcash/src/tinyformat.h", + "/depend/zcash/src/uint256.cpp", + "/depend/zcash/src/uint256.h", + "/depend/zcash/src/util/strencodings.cpp", + "/depend/zcash/src/util/strencodings.h", + "/depend/zcash/src/version.h", ] [lib] @@ -61,9 +72,6 @@ bindgen = ">= 0.64.0" # so they are configured to automatically upgrade to match Zebra. # But we try to use the latest versions here, to catch any bugs in `zcash_script`'s CI. cc = { version = "1.0.94", features = ["parallel"] } -# Treat minor versions with a zero major version as compatible (cargo doesn't by default). -cxx-gen = ">= 0.7.107" -syn = { version = "1.0.109", features = ["full", "printing"] } [dev-dependencies] # These dependencies are shared with a lot of other Zebra dependencies. diff --git a/build.rs b/build.rs index a2d7713f3..a088526ba 100644 --- a/build.rs +++ b/build.rs @@ -1,8 +1,6 @@ //! Build script for zcash_script. -use std::{env, fmt, fs, io::Read, path::PathBuf}; - -use syn::__private::ToTokens; +use std::{env, fmt, path::PathBuf}; type Result = std::result::Result; @@ -47,125 +45,8 @@ fn bindgen_headers() -> Result<()> { Ok(()) } -/// Use cxx_gen to generate headers and source files for FFI bindings, -/// just like zcash does (see depend/zcash/src/Makefile.am). -/// (Note that zcash uses the cxxbridge-cmd binary, while we use the -/// cxx_gen library, but the result is the same.) -/// -/// We could use [`cxx_build`](https://cxx.rs/tutorial.html#compiling-the-c-code-with-cargo) -/// to do this automatically. But zcash uses the -/// [manual approach](https://cxx.rs/tutorial.html#c-generated-code) which -/// creates the headers with non-standard names and paths (e.g. "blake2b.h", -/// instead of "blake2b.rs.h" which what cxx_build would create). This would -/// requires us to rename/link files which is awkward. -/// -/// Note that we must generate the files in the target dir (OUT_DIR) and not in -/// any source folder, because `cargo package` does not allow that. -/// (This is in contrast to zcash which generates in `depend/zcash/src/rust/gen/`) -fn gen_cxxbridge() -> Result<()> { - let out_path = env::var("OUT_DIR").map_err(Error::Env)?; - let out_path = PathBuf::from(out_path).join("gen"); - let src_out_path = PathBuf::from(&out_path).join("src"); - let header_out_path = PathBuf::from(&out_path).join("include").join("rust"); - - // These must match `CXXBRIDGE_RS` in depend/zcash/src/Makefile.am - let filenames = [ - "blake2b", - "ed25519", - "equihash", - "streams", - "bridge", - "sapling/zip32", - ]; - - // The output folder must exist - fs::create_dir_all(&src_out_path).unwrap(); - fs::create_dir_all(&header_out_path).unwrap(); - - // Generate the generic header file - fs::write(header_out_path.join("cxx.h"), cxx_gen::HEADER).unwrap(); - - // Generate the source and header for each bridge file - for filename in filenames { - println!( - "cargo:rerun-if-changed=depend/zcash/src/rust/src/{}.rs", - filename - ); - - let mut file = - fs::File::open(format!("depend/zcash/src/rust/src/{}.rs", filename).as_str()).unwrap(); - let mut content = String::new(); - file.read_to_string(&mut content).unwrap(); - - let ast = syn::parse_file(&content).unwrap(); - let token_stream = ast.to_token_stream(); - let mut opt = cxx_gen::Opt::default(); - opt.include.push(cxx_gen::Include { - path: "rust/cxx.h".to_string(), - kind: cxx_gen::IncludeKind::Quoted, - }); - let output = cxx_gen::generate_header_and_cc(token_stream, &opt).unwrap_or_else(|err| { - panic!( - "invalid bridge file {filename}: {err}. Try updating `filenames` to match zcashd" - ) - }); - - let header_path = header_out_path.join(format!("{}.h", filename)); - // Create output dir if does not exist (since `filename` can have a subdir) - fs::create_dir_all(header_path.parent().unwrap()).unwrap(); - fs::write(header_path, output.header).unwrap(); - - let src_path = src_out_path.join(format!("{}.cpp", filename)); - // Create output dir if does not exist (since `filename` can have a subdir) - fs::create_dir_all(src_path.parent().unwrap()).unwrap(); - fs::write(src_path, output.implementation).unwrap(); - } - Ok(()) -} - fn main() -> Result<()> { bindgen_headers()?; - gen_cxxbridge()?; - - let rust_path = env::var("OUT_DIR").map_err(Error::Env)?; - let rust_path = PathBuf::from(rust_path).join("rust"); - - // We want to compile `depend/zcash/src/rust/src/sapling.rs`, which we used - // to do in `src/sapling.rs` by just including it. However, now that it has - // submodules, that approach doesn't work because for some reason Rust - // searches for the submodules in `depend/zcash/src/rust/src/` instead of - // `depend/zcash/src/rust/src/sapling/` where they are located. This can - // be solved if `depend/zcash/src/rust/src/sapling.rs` is renamed to - // `depend/zcash/src/rust/src/sapling/mod.rs`. But we can't do that directly - // because we can't change the source tree inside `build.rs`. Therefore we - // copy the required files to OUT_DIR, with a renamed sapling.rs, and include - // the copied file instead (see src/sapling.rs). - // See also https://stackoverflow.com/questions/77310390/how-to-include-a-source-file-that-has-modules - fs::create_dir_all(rust_path.join("sapling")).unwrap(); - for filename in &["sapling.rs", "sapling/spec.rs", "sapling/zip32.rs"] { - println!( - "cargo:rerun-if-changed=depend/zcash/src/rust/src/{}.rs", - filename - ); - } - fs::copy( - "depend/zcash/src/rust/src/sapling.rs", - rust_path.join("sapling/mod.rs"), - ) - .unwrap(); - fs::copy( - "depend/zcash/src/rust/src/sapling/spec.rs", - rust_path.join("sapling/spec.rs"), - ) - .unwrap(); - fs::copy( - "depend/zcash/src/rust/src/sapling/zip32.rs", - rust_path.join("sapling/zip32.rs"), - ) - .unwrap(); - - let gen_path = env::var("OUT_DIR").map_err(Error::Env)?; - let gen_path = PathBuf::from(gen_path).join("gen"); let target = env::var("TARGET").expect("TARGET was not set"); let mut base_config = cc::Build::new(); @@ -177,7 +58,6 @@ fn main() -> Result<()> { .include("depend/zcash/src/rust/include/") .include("depend/zcash/src/secp256k1/include/") .include("depend/expected/include/") - .include(&gen_path.join("include")) .flag_if_supported("-Wno-implicit-fallthrough") .flag_if_supported("-Wno-catch-value") .flag_if_supported("-Wno-reorder") @@ -201,17 +81,17 @@ fn main() -> Result<()> { } base_config - .file("depend/zcash/src/script/zcash_script.cpp") - .file("depend/zcash/src/util/strencodings.cpp") .file("depend/zcash/src/amount.cpp") - .file("depend/zcash/src/uint256.cpp") - .file("depend/zcash/src/pubkey.cpp") .file("depend/zcash/src/crypto/ripemd160.cpp") .file("depend/zcash/src/crypto/sha1.cpp") .file("depend/zcash/src/crypto/sha256.cpp") + .file("depend/zcash/src/pubkey.cpp") .file("depend/zcash/src/script/interpreter.cpp") - .file("depend/zcash/src/script/script.cpp") .file("depend/zcash/src/script/script_error.cpp") + .file("depend/zcash/src/script/script.cpp") + .file("depend/zcash/src/script/zcash_script.cpp") + .file("depend/zcash/src/uint256.cpp") + .file("depend/zcash/src/util/strencodings.cpp") .compile("libzcash_script.a"); Ok(()) diff --git a/depend/zcash/src/hash.h b/depend/zcash/src/hash.h index 106a97620..8a24b8fdf 100644 --- a/depend/zcash/src/hash.h +++ b/depend/zcash/src/hash.h @@ -16,10 +16,6 @@ #include -#include -#include -#include - typedef uint256 ChainCode; /** A hasher class for Bitcoin's 256-bit hash (double SHA-256). */ @@ -157,50 +153,6 @@ class CHashWriter }; -/** A writer stream (for serialization) that computes a 256-bit BLAKE2b hash. */ -class CBLAKE2bWriter -{ -private: - rust::Box state; - -public: - int nType; - int nVersion; - - CBLAKE2bWriter(int nTypeIn, int nVersionIn, const unsigned char* personal) : - nType(nTypeIn), - nVersion(nVersionIn), - state(blake2b::init(32, {personal, blake2b::PERSONALBYTES})) {} - - int GetType() const { return nType; } - int GetVersion() const { return nVersion; } - - void write_u8(const unsigned char* pch, size_t size) - { - state->update({pch, size}); - } - - CBLAKE2bWriter& write(const char *pch, size_t size) { - state->update({(const unsigned char*)pch, size}); - return (*this); - } - - // invalidates the object - uint256 GetHash() { - uint256 result; - state->finalize({result.begin(), result.size()}); - return result; - } - - template - CBLAKE2bWriter& operator<<(const T& obj) { - // Serialize to this stream - ::Serialize(*this, obj); - return (*this); - } -}; - - /** Compute the 256-bit hash of an object's serialization. */ template uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION) diff --git a/depend/zcash/src/script/interpreter.cpp b/depend/zcash/src/script/interpreter.cpp index 9cfb757a5..d4683bfc2 100644 --- a/depend/zcash/src/script/interpreter.cpp +++ b/depend/zcash/src/script/interpreter.cpp @@ -6,8 +6,6 @@ #include "interpreter.h" -#include "consensus/upgrades.h" -#include "primitives/transaction.h" #include "crypto/ripemd160.h" #include "crypto/sha1.h" #include "crypto/sha256.h" @@ -15,10 +13,6 @@ #include "script/script.h" #include "uint256.h" -#include -#include -#include - using namespace std; typedef vector valtype; @@ -962,493 +956,6 @@ bool EvalScript( return set_success(serror); } -namespace { - -/** - * Wrapper that serializes like CTransaction, but with the modifications - * required for the signature hash done in-place - */ -class CTransactionSignatureSerializer { -private: - const CTransaction& txTo; //!< reference to the spending transaction (the one being serialized) - const CScript& scriptCode; //!< output script being consumed - const unsigned int nIn; //!< input index of txTo being signed - const bool fAnyoneCanPay; //!< whether the hashtype has the SIGHASH_ANYONECANPAY flag set - const bool fHashSingle; //!< whether the hashtype is SIGHASH_SINGLE - const bool fHashNone; //!< whether the hashtype is SIGHASH_NONE - -public: - CTransactionSignatureSerializer(const CTransaction &txToIn, const CScript &scriptCodeIn, unsigned int nInIn, int nHashTypeIn) : - txTo(txToIn), scriptCode(scriptCodeIn), nIn(nInIn), - fAnyoneCanPay(!!(nHashTypeIn & SIGHASH_ANYONECANPAY)), - fHashSingle((nHashTypeIn & 0x1f) == SIGHASH_SINGLE), - fHashNone((nHashTypeIn & 0x1f) == SIGHASH_NONE) {} - - /** Serialize the passed scriptCode */ - template - void SerializeScriptCode(S &s) const { - auto size = scriptCode.size(); - ::WriteCompactSize(s, size); - s.write((char*)&scriptCode.begin()[0], size); - } - - /** Serialize an input of txTo */ - template - void SerializeInput(S &s, unsigned int nInput) const { - // In case of SIGHASH_ANYONECANPAY, only the input being signed is serialized - if (fAnyoneCanPay) - nInput = nIn; - // Serialize the prevout - ::Serialize(s, txTo.vin[nInput].prevout); - // Serialize the script - assert(nInput != NOT_AN_INPUT); - if (nInput != nIn) - // Blank out other inputs' signatures - ::Serialize(s, CScriptBase()); - else - SerializeScriptCode(s); - // Serialize the nSequence - if (nInput != nIn && (fHashSingle || fHashNone)) - // let the others update at will - ::Serialize(s, (int)0); - else - ::Serialize(s, txTo.vin[nInput].nSequence); - } - - /** Serialize an output of txTo */ - template - void SerializeOutput(S &s, unsigned int nOutput) const { - if (fHashSingle && nOutput != nIn) - // Do not lock-in the txout payee at other indices as txin - ::Serialize(s, CTxOut()); - else - ::Serialize(s, txTo.vout[nOutput]); - } - - /** Serialize txTo */ - template - void Serialize(S &s) const { - // Serialize nVersion - ::Serialize(s, txTo.nVersion); - // Serialize vin - unsigned int nInputs = fAnyoneCanPay ? 1 : txTo.vin.size(); - ::WriteCompactSize(s, nInputs); - for (unsigned int nInput = 0; nInput < nInputs; nInput++) - SerializeInput(s, nInput); - // Serialize vout - unsigned int nOutputs = fHashNone ? 0 : (fHashSingle ? nIn+1 : txTo.vout.size()); - ::WriteCompactSize(s, nOutputs); - for (unsigned int nOutput = 0; nOutput < nOutputs; nOutput++) - SerializeOutput(s, nOutput); - // Serialize nLockTime - ::Serialize(s, txTo.nLockTime); - - // Serialize vJoinSplit - if (txTo.nVersion >= 2) { - // - // SIGHASH_* functions will hash portions of - // the transaction for use in signatures. This - // keeps the JoinSplit cryptographically bound - // to the transaction. - // - ::Serialize(s, txTo.vJoinSplit); - if (txTo.vJoinSplit.size() > 0) { - ::Serialize(s, txTo.joinSplitPubKey); - - CTransaction::joinsplit_sig_t nullSig = {}; - ::Serialize(s, nullSig); - } - } - } -}; - -const unsigned char ZCASH_PREVOUTS_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] = - {'Z','c','a','s','h','P','r','e','v','o','u','t','H','a','s','h'}; -const unsigned char ZCASH_SEQUENCE_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] = - {'Z','c','a','s','h','S','e','q','u','e','n','c','H','a','s','h'}; -const unsigned char ZCASH_OUTPUTS_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] = - {'Z','c','a','s','h','O','u','t','p','u','t','s','H','a','s','h'}; -const unsigned char ZCASH_JOINSPLITS_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] = - {'Z','c','a','s','h','J','S','p','l','i','t','s','H','a','s','h'}; -const unsigned char ZCASH_SHIELDED_SPENDS_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] = - {'Z','c','a','s','h','S','S','p','e','n','d','s','H','a','s','h'}; -const unsigned char ZCASH_SHIELDED_OUTPUTS_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] = - {'Z','c','a','s','h','S','O','u','t','p','u','t','H','a','s','h'}; - -uint256 GetPrevoutHash(const CTransaction& txTo) { - CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_PREVOUTS_HASH_PERSONALIZATION); - for (unsigned int n = 0; n < txTo.vin.size(); n++) { - ss << txTo.vin[n].prevout; - } - return ss.GetHash(); -} - -uint256 GetSequenceHash(const CTransaction& txTo) { - CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_SEQUENCE_HASH_PERSONALIZATION); - for (unsigned int n = 0; n < txTo.vin.size(); n++) { - ss << txTo.vin[n].nSequence; - } - return ss.GetHash(); -} - -uint256 GetOutputsHash(const CTransaction& txTo) { - CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_OUTPUTS_HASH_PERSONALIZATION); - for (unsigned int n = 0; n < txTo.vout.size(); n++) { - ss << txTo.vout[n]; - } - return ss.GetHash(); -} - -uint256 GetJoinSplitsHash(const CTransaction& txTo) { - CBLAKE2bWriter ss(SER_GETHASH, static_cast(txTo.GetHeader()), ZCASH_JOINSPLITS_HASH_PERSONALIZATION); - for (unsigned int n = 0; n < txTo.vJoinSplit.size(); n++) { - ss << txTo.vJoinSplit[n]; - } - ss << txTo.joinSplitPubKey; - return ss.GetHash(); -} - -uint256 GetShieldedSpendsHash(const CTransaction& txTo) { - CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_SHIELDED_SPENDS_HASH_PERSONALIZATION); - for (const auto& spend : txTo.GetSaplingSpends()) { - ss << spend.cv(); - ss << spend.anchor(); - ss << spend.nullifier(); - ss << spend.rk(); - ss << spend.zkproof(); - } - return ss.GetHash(); -} - -uint256 GetShieldedOutputsHash(const CTransaction& txTo) { - CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_SHIELDED_OUTPUTS_HASH_PERSONALIZATION); - auto ssRs = ToRustStream(ss); - for (const auto& output : txTo.GetSaplingOutputs()) { - output.serialize_v4(*ssRs); - } - return ss.GetHash(); -} - -} // anon namespace - -PrecomputedTransactionData::PrecomputedTransactionData( - const CTransaction& txTo, - const std::vector& allPrevOutputs) : - preTx(nullptr, zcash_transaction_precomputed_free) -{ - CDataStream sAllPrevOutputs(SER_NETWORK, PROTOCOL_VERSION); - sAllPrevOutputs << allPrevOutputs; - SetPrecomputed( - txTo, - reinterpret_cast(sAllPrevOutputs.data()), - sAllPrevOutputs.size()); -} - -PrecomputedTransactionData::PrecomputedTransactionData( - const CTransaction& txTo, - const unsigned char* allPrevOutputs, - size_t allPrevOutputsLen) : - preTx(nullptr, zcash_transaction_precomputed_free) -{ - SetPrecomputed(txTo, allPrevOutputs, allPrevOutputsLen); -} - -void PrecomputedTransactionData::SetPrecomputed( - const CTransaction& txTo, - const unsigned char* allPrevOutputs, - size_t allPrevOutputsLen) -{ - bool isOverwinterV3 = - txTo.fOverwintered && - txTo.nVersionGroupId == OVERWINTER_VERSION_GROUP_ID && - txTo.nVersion == OVERWINTER_TX_VERSION; - bool isSaplingV4 = - txTo.fOverwintered && - txTo.nVersionGroupId == SAPLING_VERSION_GROUP_ID && - txTo.nVersion == SAPLING_TX_VERSION; - - if (!txTo.fOverwintered || isOverwinterV3 || isSaplingV4) { - hashPrevouts = GetPrevoutHash(txTo); - hashSequence = GetSequenceHash(txTo); - hashOutputs = GetOutputsHash(txTo); - hashJoinSplits = GetJoinSplitsHash(txTo); - hashShieldedSpends = GetShieldedSpendsHash(txTo); - hashShieldedOutputs = GetShieldedOutputsHash(txTo); - } else { - // TODO: If we already have this serialized, use it. - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << txTo; - preTx.reset(zcash_transaction_precomputed_init( - reinterpret_cast(ss.data()), - ss.size(), allPrevOutputs, allPrevOutputsLen)); - if (preTx == nullptr) { - throw std::ios_base::failure("Invalid arguments to PrecomputedTransactionData"); - } - } -} - -SigVersion SignatureHashVersion(const CTransaction& txTo) -{ - if (txTo.fOverwintered) { - if (txTo.nVersionGroupId == ZIP225_VERSION_GROUP_ID) { - return SIGVERSION_ZIP244; - } else if (txTo.nVersionGroupId == SAPLING_VERSION_GROUP_ID) { - return SIGVERSION_SAPLING; - } else { - return SIGVERSION_OVERWINTER; - } - } else { - return SIGVERSION_SPROUT; - } -} - -uint256 SignatureHash( - const CScript& scriptCode, - const CTransaction& txTo, - unsigned int nIn, - int nHashType, - const CAmount& amount, - uint32_t consensusBranchId, - const PrecomputedTransactionData& txdata) -{ - if (nIn >= txTo.vin.size() && nIn != NOT_AN_INPUT) { - // nIn out of range - throw logic_error("input index is out of range"); - } - - auto sigversion = SignatureHashVersion(txTo); - - if (sigversion == SIGVERSION_ZIP244) { - // ZIP 244, S.2: transparent_sig_digest - // - // If we are producing a hash for either a coinbase transaction, or a - // non-coinbase transaction that has no transparent inputs, the value of - // transparent_sig_digest is identical to the value specified in section - // T.2. - // - // https://zips.z.cash/zip-0244#s-2-transparent-sig-digest - if (txTo.IsCoinBase() || txTo.vin.empty()) { - // This situation only applies to shielded signatures. - assert(nIn == NOT_AN_INPUT); - assert(nHashType == SIGHASH_ALL); - // The signature digest is just the txid! No need to cross the FFI. - return txTo.GetHash(); - } else { - // S.2a: hash_type - // - // The following restrictions apply, which cause validation failure - // if violated: - // - Using any undefined hash_type (not 0x01, 0x02, 0x03, 0x81, - // 0x82, or 0x83). - // - Using SIGHASH_SINGLE without a "corresponding output" (an - // output with the same index as the input being verified). - switch (nHashType) { - case SIGHASH_SINGLE: - case SIGHASH_ANYONECANPAY | SIGHASH_SINGLE: - if (nIn >= txTo.vout.size()) { - throw std::logic_error( - "ZIP 244: Used SIGHASH_SINGLE without a corresponding output"); - } - case SIGHASH_ALL: - case SIGHASH_NONE: - case SIGHASH_ANYONECANPAY | SIGHASH_ALL: - case SIGHASH_ANYONECANPAY | SIGHASH_NONE: - break; - default: - throw std::logic_error("ZIP 244: Used undefined hash_type"); - } - - // The amount parameter is ignored; we extract it from allPrevOutputs. - // - Note to future developers: if we ever replace the C++ logic for - // pre-v5 transactions with Rust logic, make sure signrawtransaction - // is updated to know about it! - // The consensusBranchId parameter is ignored; we use the value stored - // in the transaction itself. - uint256 hash; - if (!zcash_transaction_zip244_signature_digest( - txdata.preTx.get(), - nHashType, - nIn, - hash.begin())) - { - throw std::logic_error("We should not reach here."); - } - return hash; - } - } else if (sigversion == SIGVERSION_OVERWINTER || sigversion == SIGVERSION_SAPLING) { - uint256 hashPrevouts; - uint256 hashSequence; - uint256 hashOutputs; - uint256 hashJoinSplits; - uint256 hashShieldedSpends; - uint256 hashShieldedOutputs; - - if (!(nHashType & SIGHASH_ANYONECANPAY)) { - hashPrevouts = txdata.hashPrevouts; - } - - if (!(nHashType & SIGHASH_ANYONECANPAY) && (nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { - hashSequence = txdata.hashSequence; - } - - if ((nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { - hashOutputs = txdata.hashOutputs; - } else if ((nHashType & 0x1f) == SIGHASH_SINGLE && nIn < txTo.vout.size()) { - CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_OUTPUTS_HASH_PERSONALIZATION); - ss << txTo.vout[nIn]; - hashOutputs = ss.GetHash(); - } - - if (!txTo.vJoinSplit.empty()) { - hashJoinSplits = txdata.hashJoinSplits; - } - - if (txTo.GetSaplingSpendsCount() > 0) { - hashShieldedSpends = txdata.hashShieldedSpends; - } - - if (txTo.GetSaplingOutputsCount() > 0) { - hashShieldedOutputs = txdata.hashShieldedOutputs; - } - - uint32_t leConsensusBranchId = htole32(consensusBranchId); - unsigned char personalization[16] = {}; - memcpy(personalization, "ZcashSigHash", 12); - memcpy(personalization+12, &leConsensusBranchId, 4); - - CBLAKE2bWriter ss(SER_GETHASH, 0, personalization); - // Header - ss << txTo.GetHeader(); - // Version group ID - ss << txTo.nVersionGroupId; - // Input prevouts/nSequence (none/all, depending on flags) - ss << hashPrevouts; - ss << hashSequence; - // Outputs (none/one/all, depending on flags) - ss << hashOutputs; - // JoinSplits - ss << hashJoinSplits; - if (sigversion == SIGVERSION_SAPLING) { - // Spend descriptions - ss << hashShieldedSpends; - // Output descriptions - ss << hashShieldedOutputs; - } - // Locktime - ss << txTo.nLockTime; - // Expiry height - ss << txTo.nExpiryHeight; - if (sigversion == SIGVERSION_SAPLING) { - // Sapling value balance - ss << txTo.GetValueBalanceSapling(); - } - // Sighash type - ss << nHashType; - - // If this hash is for a transparent input signature - // (i.e. not for txTo.joinSplitSig): - if (nIn != NOT_AN_INPUT){ - // The input being signed (replacing the scriptSig with scriptCode + amount) - // The prevout may already be contained in hashPrevout, and the nSequence - // may already be contained in hashSequence. - ss << txTo.vin[nIn].prevout; - ss << static_cast(scriptCode); - ss << amount; - ss << txTo.vin[nIn].nSequence; - } - - return ss.GetHash(); - } - - // Check for invalid use of SIGHASH_SINGLE - if ((nHashType & 0x1f) == SIGHASH_SINGLE) { - if (nIn >= txTo.vout.size()) { - // nOut out of range - throw logic_error("no matching output for SIGHASH_SINGLE"); - } - } - - // Wrapper to serialize only the necessary parts of the transaction being signed - CTransactionSignatureSerializer txTmp(txTo, scriptCode, nIn, nHashType); - - // Serialize and hash - CHashWriter ss(SER_GETHASH, 0); - ss << txTmp << nHashType; - return ss.GetHash(); -} - -bool TransactionSignatureChecker::VerifySignature( - const std::vector& vchSig, const CPubKey& pubkey, const uint256& sighash) const -{ - return pubkey.Verify(sighash, vchSig); -} - -bool TransactionSignatureChecker::CheckSig( - const vector& vchSigIn, - const vector& vchPubKey, - const CScript& scriptCode, - uint32_t consensusBranchId) const -{ - CPubKey pubkey(vchPubKey); - if (!pubkey.IsValid()) - return false; - - // Hash type is one byte tacked on to the end of the signature - vector vchSig(vchSigIn); - if (vchSig.empty()) - return false; - int nHashType = vchSig.back(); - vchSig.pop_back(); - - uint256 sighash; - try { - sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, consensusBranchId, this->txdata); - } catch (logic_error ex) { - return false; - } - - if (!VerifySignature(vchSig, pubkey, sighash)) - return false; - - return true; -} - -bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) const -{ - // There are two times of nLockTime: lock-by-blockheight - // and lock-by-blocktime, distinguished by whether - // nLockTime < LOCKTIME_THRESHOLD. - // - // We want to compare apples to apples, so fail the script - // unless the type of nLockTime being tested is the same as - // the nLockTime in the transaction. - if (!( - (txTo->nLockTime < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) || - (txTo->nLockTime >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD) - )) - return false; - - // Now that we know we're comparing apples-to-apples, the - // comparison is a simple numeric one. - if (nLockTime > (int64_t)txTo->nLockTime) - return false; - - // Finally the nLockTime feature can be disabled and thus - // CHECKLOCKTIMEVERIFY bypassed if every txin has been - // finalized by setting nSequence to maxint. The - // transaction would be allowed into the blockchain, making - // the opcode ineffective. - // - // Testing if this vin is not final is sufficient to - // prevent this condition. Alternatively we could test all - // inputs, but testing just this input minimizes the data - // required to prove correct CHECKLOCKTIMEVERIFY execution. - if (txTo->vin[nIn].IsFinal()) - return false; - - return true; -} - bool CallbackTransactionSignatureChecker::VerifySignature( const std::vector& vchSig, const CPubKey& pubkey, diff --git a/depend/zcash/src/script/interpreter.h b/depend/zcash/src/script/interpreter.h index 563949843..3a535b667 100644 --- a/depend/zcash/src/script/interpreter.h +++ b/depend/zcash/src/script/interpreter.h @@ -8,18 +8,17 @@ #define BITCOIN_SCRIPT_INTERPRETER_H #include "script_error.h" -#include "primitives/transaction.h" - -#include #include #include #include #include +#include "script/script.h" +#include "amount.h" + class CPubKey; class CScript; -class CTransaction; class uint256; /** Special case nIn for signing JoinSplits. */ @@ -93,28 +92,6 @@ enum bool CheckSignatureEncoding(const std::vector &vchSig, unsigned int flags, ScriptError* serror); -struct PrecomputedTransactionData -{ - uint256 hashPrevouts, hashSequence, hashOutputs, hashJoinSplits, hashShieldedSpends, hashShieldedOutputs; - /** Precomputed transaction parts. */ - std::unique_ptr preTx; - - PrecomputedTransactionData( - const CTransaction& tx, - const std::vector& allPrevOutputs); - - PrecomputedTransactionData( - const CTransaction& tx, - const unsigned char* allPrevOutputs, - size_t allPrevOutputsLen); - -private: - void SetPrecomputed( - const CTransaction& tx, - const unsigned char* allPrevOutputs, - size_t allPrevOutputsLen); -}; - enum SigVersion { SIGVERSION_SPROUT = 0, @@ -123,15 +100,6 @@ enum SigVersion SIGVERSION_ZIP244 = 3, }; -uint256 SignatureHash( - const CScript &scriptCode, - const CTransaction& txTo, - unsigned int nIn, - int nHashType, - const CAmount& amount, - uint32_t consensusBranchId, - const PrecomputedTransactionData& txdata); - class BaseSignatureChecker { public: @@ -152,32 +120,6 @@ class BaseSignatureChecker virtual ~BaseSignatureChecker() {} }; -class TransactionSignatureChecker : public BaseSignatureChecker -{ -private: - const CTransaction* txTo; - unsigned int nIn; - const CAmount amount; - const PrecomputedTransactionData& txdata; - -protected: - virtual bool VerifySignature(const std::vector& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; - -public: - TransactionSignatureChecker(const CTransaction* txToIn, const PrecomputedTransactionData& txdataIn, unsigned int nInIn, const CAmount& amountIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(txdataIn) {} - bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode, uint32_t consensusBranchId) const; - bool CheckLockTime(const CScriptNum& nLockTime) const; -}; - -class MutableTransactionSignatureChecker : public TransactionSignatureChecker -{ -private: - const CTransaction txTo; - -public: - MutableTransactionSignatureChecker(const CMutableTransaction* txToIn, const PrecomputedTransactionData& txdataIn, unsigned int nInIn, const CAmount& amount) : TransactionSignatureChecker(&txTo, txdataIn, nInIn, amount), txTo(*txToIn) {} -}; - class CallbackTransactionSignatureChecker : public BaseSignatureChecker { private: diff --git a/depend/zcash/src/serialize.h b/depend/zcash/src/serialize.h index 11db3714a..95ac7eda9 100644 --- a/depend/zcash/src/serialize.h +++ b/depend/zcash/src/serialize.h @@ -26,8 +26,6 @@ #include -#include - #include "prevector.h" static const unsigned int MAX_SIZE = 0x02000000; @@ -587,25 +585,6 @@ template void Unserialize(Stream& os, std::shared_p template void Serialize(Stream& os, const std::unique_ptr& p); template void Unserialize(Stream& os, std::unique_ptr& p); -/** - * ed25519::SigningKey - */ -template void Serialize(Stream& os, const ed25519::SigningKey& item); -template void Unserialize(Stream& is, ed25519::SigningKey& item); - -/** - * ed25519::VerificationKey - */ -template void Serialize(Stream& os, const ed25519::VerificationKey& item); -template void Unserialize(Stream& is, ed25519::VerificationKey& item); - -/** - * ed25519::Signature - */ -template void Serialize(Stream& os, const ed25519::Signature& item); -template void Unserialize(Stream& is, ed25519::Signature& item); - - /** * If none of the specialized versions above matched, default to calling member function. @@ -975,57 +954,6 @@ void Unserialize(Stream& is, std::shared_ptr& p) -/** - * ed25519::SigningKey - */ -template -void Serialize(Stream& os, const ed25519::SigningKey& sk) -{ - Serialize(os, sk.bytes); -} - -template -void Unserialize(Stream& is, ed25519::SigningKey& sk) -{ - Unserialize(is, sk.bytes); -} - - - -/** - * ed25519::VerificationKey - */ -template -void Serialize(Stream& os, const ed25519::VerificationKey& vk) -{ - Serialize(os, vk.bytes); -} - -template -void Unserialize(Stream& is, ed25519::VerificationKey& vk) -{ - Unserialize(is, vk.bytes); -} - - - -/** - * ed25519::Signature - */ -template -void Serialize(Stream& os, const ed25519::Signature& sig) -{ - Serialize(os, sig.bytes); -} - -template -void Unserialize(Stream& is, ed25519::Signature& sig) -{ - Unserialize(is, sig.bytes); -} - - - /** * Support for ADD_SERIALIZE_METHODS and READWRITE macro */ From fa2cb992c76305039b382e77df7a1584060b1a1e Mon Sep 17 00:00:00 2001 From: Conrado Gouvea Date: Mon, 27 May 2024 13:59:56 -0300 Subject: [PATCH 13/16] add new tests and remove old ones --- src/lib.rs | 244 ++++++++++++++++------------------------------------- 1 file changed, 74 insertions(+), 170 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 3f53fa8c9..569734316 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,71 +15,71 @@ include!(concat!(env!("OUT_DIR"), "/bindings.rs")); #[cfg(test)] mod tests { + use std::ffi::{c_int, c_uint, c_void}; + pub use super::zcash_script_error_t; use hex::FromHex; lazy_static::lazy_static! { - pub static ref SCRIPT_PUBKEY: Vec = >::from_hex("76a914f47cac1e6fec195c055994e8064ffccce0044dd788ac").unwrap(); - pub static ref SCRIPT_TX: Vec = >::from_hex("0400008085202f8901fcaf44919d4a17f6181a02a7ebe0420be6f7dad1ef86755b81d5a9567456653c010000006a473044022035224ed7276e61affd53315eca059c92876bc2df61d84277cafd7af61d4dbf4002203ed72ea497a9f6b38eb29df08e830d99e32377edb8a574b8a289024f0241d7c40121031f54b095eae066d96b2557c1f99e40e967978a5fd117465dbec0986ca74201a6feffffff020050d6dc0100000017a9141b8a9bda4b62cd0d0582b55455d0778c86f8628f870d03c812030000001976a914e4ff5512ffafe9287992a1cd177ca6e408e0300388ac62070d0095070d000000000000000000000000").expect("Block bytes are in valid hex representation"); + pub static ref SCRIPT_PUBKEY: Vec = >::from_hex("a914c117756dcbe144a12a7c33a77cfa81aa5aeeb38187").unwrap(); + pub static ref SCRIPT_SIG: Vec = >::from_hex("00483045022100d2ab3e6258fe244fa442cfb38f6cef9ac9a18c54e70b2f508e83fa87e20d040502200eead947521de943831d07a350e45af8e36c2166984a8636f0a8811ff03ed09401473044022013e15d865010c257eef133064ef69a780b4bc7ebe6eda367504e806614f940c3022062fdbc8c2d049f91db2042d6c9771de6f1ef0b3b1fea76c1ab5542e44ed29ed8014c69522103b2cc71d23eb30020a4893982a1e2d352da0d20ee657fa02901c432758909ed8f21029d1e9a9354c0d2aee9ffd0f0cea6c39bbf98c4066cf143115ba2279d0ba7dabe2103e32096b63fd57f3308149d238dcbb24d8d28aad95c0e4e74e3e5e6a11b61bcc453ae").expect("Block bytes are in valid hex representation"); } - /// Manually encode all previous outputs for a single output. - fn encode_all_prev_outputs(amount: i64, script_pub_key: &[u8]) -> (Vec, *const u8) { - // Number of transactions (CompactSize) - let mut all_prev_outputs = vec![1]; - // Amount as 8 little-endian bytes - all_prev_outputs.extend(amount.to_le_bytes().iter().cloned()); - // Length of the pub key script (CompactSize) - all_prev_outputs.push(script_pub_key.len() as u8); - // Pub key script - all_prev_outputs.extend(script_pub_key.iter().cloned()); - let all_prev_outputs_ptr = all_prev_outputs.as_ptr(); - (all_prev_outputs, all_prev_outputs_ptr) + extern "C" fn sighash( + s: *mut u8, + ctx: *const c_void, + _script_code: *const u8, + _script_code_len: c_uint, + _hash_type: c_int, + ) { + unsafe { + assert!(ctx.is_null()); + let sighash = + hex::decode("e8c7bdac77f6bb1f3aba2eaa1fada551a9c8b3b5ecd1ef86e6e58a5f1aab952c") + .unwrap(); + std::ptr::copy_nonoverlapping(sighash.as_ptr(), s, sighash.len()); + } } - pub fn verify_script( - script_pub_key: &[u8], - amount: i64, - tx_to: &[u8], - nIn: u32, - flags: u32, - consensus_branch_id: u32, - ) -> Result<(), zcash_script_error_t> { - let script_ptr = script_pub_key.as_ptr(); - let script_len = script_pub_key.len(); - let tx_to_ptr = tx_to.as_ptr(); - let tx_to_len = tx_to.len(); - let mut err = 0; - - let ret = unsafe { - super::zcash_script_verify( - script_ptr, - script_len as u32, - amount, - tx_to_ptr, - tx_to_len as u32, - nIn, - flags, - consensus_branch_id, - &mut err, - ) - }; - - if ret != 1 { - return Err(err); + extern "C" fn invalid_sighash( + s: *mut u8, + ctx: *const c_void, + _script_code: *const u8, + _script_code_len: c_uint, + _hash_type: c_int, + ) { + unsafe { + assert!(ctx.is_null()); + let sighash = + hex::decode("08c7bdac77f6bb1f3aba2eaa1fada551a9c8b3b5ecd1ef86e6e58a5f1aab952c") + .unwrap(); + std::ptr::copy_nonoverlapping(sighash.as_ptr(), s, sighash.len()); } + } - // Also test with the V5 API - - let (all_prev_outputs, all_prev_outputs_ptr) = - encode_all_prev_outputs(amount, script_pub_key); + #[test] + fn it_works() { + let nLockTime: i64 = 2410374; + let isFinal: u8 = 1; + let script_pub_key = &*SCRIPT_PUBKEY; + let script_sig = &*SCRIPT_SIG; + let amount: i64 = 1550280000; + let nIn: c_uint = 0; + let flags: c_uint = 513; + let consensus_branch_id: u32 = 0xc2d6d0b4; + let mut err = 0; let ret = unsafe { - super::zcash_script_verify_v5( - tx_to_ptr, - tx_to_len as u32, - all_prev_outputs_ptr, - all_prev_outputs.len() as _, + super::zcash_script_verify_callback( + std::ptr::null(), + Some(sighash), + nLockTime, + isFinal, + script_pub_key.as_ptr(), + script_pub_key.len() as c_uint, + script_sig.as_ptr(), + script_sig.len() as c_uint, + amount, nIn, flags, consensus_branch_id, @@ -87,135 +87,39 @@ mod tests { ) }; - if ret == 1 { - Ok(()) - } else { - Err(err) - } + assert!(ret == 1); } - pub fn verify_script_precompute( - script_pub_key: &[u8], - amount: i64, - tx_to: &[u8], - nIn: u32, - flags: u32, - consensus_branch_id: u32, - ) -> Result<(), zcash_script_error_t> { - let script_ptr = script_pub_key.as_ptr(); - let script_len = script_pub_key.len(); - let tx_to_ptr = tx_to.as_ptr(); - let tx_to_len = tx_to.len(); + #[test] + fn it_fails_on_invalid_sighash() { + let nLockTime: i64 = 2410374; + let isFinal: u8 = 1; + let script_pub_key = &*SCRIPT_PUBKEY; + let script_sig = &*SCRIPT_SIG; + let amount: i64 = 1550280000; + let nIn: c_uint = 0; + let flags: c_uint = 513; + let consensus_branch_id: u32 = 0xc2d6d0b4; let mut err = 0; - let precomputed = - unsafe { super::zcash_script_new_precomputed_tx(tx_to_ptr, tx_to_len as _, &mut err) }; - let ret = unsafe { - super::zcash_script_verify_precomputed( - precomputed, - nIn, - script_ptr, - script_len as _, + super::zcash_script_verify_callback( + std::ptr::null(), + Some(invalid_sighash), + nLockTime, + isFinal, + script_pub_key.as_ptr(), + script_pub_key.len() as c_uint, + script_sig.as_ptr(), + script_sig.len() as c_uint, amount, - flags, - consensus_branch_id, - &mut err, - ) - }; - - unsafe { super::zcash_script_free_precomputed_tx(precomputed) }; - - if ret != 1 { - return Err(err); - } - - // Also test with the V5 API - - let (all_prev_outputs, all_prev_outputs_ptr) = - encode_all_prev_outputs(amount, script_pub_key); - - let precomputed = unsafe { - super::zcash_script_new_precomputed_tx_v5( - tx_to_ptr, - tx_to_len as _, - all_prev_outputs_ptr, - all_prev_outputs.len() as _, - &mut err, - ) - }; - - let ret = unsafe { - super::zcash_script_verify_precomputed( - precomputed, nIn, - script_ptr, - script_len as u32, - amount, flags, consensus_branch_id, &mut err, ) }; - unsafe { super::zcash_script_free_precomputed_tx(precomputed) }; - - if ret == 1 { - Ok(()) - } else { - Err(err) - } - } - - #[test] - fn it_works() { - let coin = i64::pow(10, 8); - let script_pub_key = &*SCRIPT_PUBKEY; - let amount = 212 * coin; - let tx_to = &*SCRIPT_TX; - let nIn = 0; - let flags = 1; - let branch_id = 0x2bb40e60; - - verify_script(script_pub_key, amount, tx_to, nIn, flags, branch_id).unwrap(); - } - - #[test] - fn it_works_precomputed() { - let coin = i64::pow(10, 8); - let script_pub_key = &*SCRIPT_PUBKEY; - let amount = 212 * coin; - let tx_to = &*SCRIPT_TX; - let nIn = 0; - let flags = 1; - let branch_id = 0x2bb40e60; - - verify_script_precompute(script_pub_key, amount, tx_to, nIn, flags, branch_id).unwrap(); - } - - #[test] - fn it_doesnt_work() { - let coin = i64::pow(10, 8); - let script_pub_key = &*SCRIPT_PUBKEY; - let amount = 212 * coin; - let tx_to = &*SCRIPT_TX; - let nIn = 0; - let flags = 1; - let branch_id = 0x2bb40e61; - - verify_script(script_pub_key, amount, tx_to, nIn, flags, branch_id).unwrap_err(); - } - - #[test] - fn it_doesnt_work_precomputed() { - let coin = i64::pow(10, 8); - let script_pub_key = &*SCRIPT_PUBKEY; - let amount = 212 * coin; - let tx_to = &*SCRIPT_TX; - let nIn = 0; - let flags = 1; - let branch_id = 0x2bb40e61; - - verify_script_precompute(script_pub_key, amount, tx_to, nIn, flags, branch_id).unwrap_err(); + assert!(ret != 1); } } From 9d2da3703bb1a0e76721332df33b4d9d3ce24ed5 Mon Sep 17 00:00:00 2001 From: Conrado Gouvea Date: Mon, 27 May 2024 19:32:44 -0300 Subject: [PATCH 14/16] remove unneded params; add sighashLen to callback --- depend/zcash/src/script/interpreter.cpp | 2 +- depend/zcash/src/script/interpreter.h | 6 ++-- depend/zcash/src/script/zcash_script.cpp | 11 ++++---- depend/zcash/src/script/zcash_script.h | 36 +++++++++++++++++++++--- src/lib.rs | 24 ++++++---------- 5 files changed, 48 insertions(+), 31 deletions(-) diff --git a/depend/zcash/src/script/interpreter.cpp b/depend/zcash/src/script/interpreter.cpp index d4683bfc2..edc16a637 100644 --- a/depend/zcash/src/script/interpreter.cpp +++ b/depend/zcash/src/script/interpreter.cpp @@ -985,7 +985,7 @@ bool CallbackTransactionSignatureChecker::CheckSig( try { std::array sighashArray; auto scriptBase = static_cast(scriptCode); - this->sighash(sighashArray.begin(), this->tx, &scriptBase[0], scriptBase.size(), nHashType); + this->sighash(sighashArray.begin(), sighashArray.size(), this->tx, &scriptBase[0], scriptBase.size(), nHashType); sighash = uint256::FromRawBytes(sighashArray); } catch (logic_error ex) { return false; diff --git a/depend/zcash/src/script/interpreter.h b/depend/zcash/src/script/interpreter.h index 3a535b667..11dfce592 100644 --- a/depend/zcash/src/script/interpreter.h +++ b/depend/zcash/src/script/interpreter.h @@ -124,17 +124,15 @@ class CallbackTransactionSignatureChecker : public BaseSignatureChecker { private: const void* tx; - void (*sighash)(unsigned char* sighash, const void* tx, const unsigned char* scriptCode, unsigned int scriptCodeLen, int hashType); + void (*sighash)(unsigned char* sighash, unsigned int sighashLen, const void* tx, const unsigned char* scriptCode, unsigned int scriptCodeLen, int hashType); const CScriptNum& nLockTime; bool isFinal; - unsigned int nIn; - const CAmount amount; protected: virtual bool VerifySignature(const std::vector& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; public: - CallbackTransactionSignatureChecker(const void* tx, void (*sighash)(unsigned char* sighash, const void* tx, const unsigned char* scriptCode, unsigned int scriptCodeLen, int hashType), const CScriptNum& nLockTime, bool isFinal, unsigned int nInIn, const CAmount& amountIn) : tx(tx), sighash(sighash), nLockTime(nLockTime), isFinal(isFinal), nIn(nInIn), amount(amountIn) {} + CallbackTransactionSignatureChecker(const void* tx, void (*sighash)(unsigned char* sighash, unsigned int sighashLen, const void* tx, const unsigned char* scriptCode, unsigned int scriptCodeLen, int hashType), const CScriptNum& nLockTime, bool isFinal) : tx(tx), sighash(sighash), nLockTime(nLockTime), isFinal(isFinal) {} bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode, uint32_t consensusBranchId) const; bool CheckLockTime(const CScriptNum& nLockTime) const; }; diff --git a/depend/zcash/src/script/zcash_script.cpp b/depend/zcash/src/script/zcash_script.cpp index 670e8c2f9..8926cb394 100644 --- a/depend/zcash/src/script/zcash_script.cpp +++ b/depend/zcash/src/script/zcash_script.cpp @@ -299,17 +299,14 @@ unsigned int zcash_script_legacy_sigop_count_script( int zcash_script_verify_callback( const void* ctx, - void (*sighash)(unsigned char* sighash, const void* ctx, const unsigned char* scriptCode, unsigned int scriptCodeLen, int hashType), + void (*sighash)(unsigned char* sighash, unsigned int sighashLen, const void* ctx, const unsigned char* scriptCode, unsigned int scriptCodeLen, int hashType), int64_t nLockTime, uint8_t isFinal, const unsigned char* scriptPubKey, unsigned int scriptPubKeyLen, const unsigned char* scriptSig, unsigned int scriptSigLen, - int64_t amount, - unsigned int nIn, unsigned int flags, - uint32_t consensusBranchId, zcash_script_error* err) { try { @@ -320,8 +317,10 @@ int zcash_script_verify_callback( CScript(scriptSig, scriptSig + scriptSigLen), CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), flags, - CallbackTransactionSignatureChecker(ctx, sighash, nLockTimeNum, isFinal != 0, nIn, amount), - consensusBranchId, + CallbackTransactionSignatureChecker(ctx, sighash, nLockTimeNum, isFinal != 0), + // consensusBranchId is not longer used with the callback API; the argument + // was left there to minimize changes to interpreter.cpp + 0, &script_err); } catch (const std::exception&) { return set_error(err, zcash_script_ERR_VERIFY_SCRIPT); diff --git a/depend/zcash/src/script/zcash_script.h b/depend/zcash/src/script/zcash_script.h index 351dc5a79..658014f42 100644 --- a/depend/zcash/src/script/zcash_script.h +++ b/depend/zcash/src/script/zcash_script.h @@ -183,23 +183,51 @@ EXPORT_SYMBOL unsigned int zcash_script_legacy_sigop_count( /// Returns the current version of the zcash_script library. EXPORT_SYMBOL unsigned int zcash_script_version(); +/// Returns the number of transparent signature operations in the input or +/// output script pointed to by script. EXPORT_SYMBOL unsigned int zcash_script_legacy_sigop_count_script( const unsigned char* script, unsigned int scriptLen); +/// Returns 1 if the a transparent input correctly spends the matching output +/// under the additional constraints specified by flags. This function +/// receives only the required information to validate the spend and not +/// the transaction itself. In particular, the sighash for the spend +/// is obtained using a callback function. +/// +/// - ctx: an opaque pointer which is forwarded to the callback. It can be used +/// to store context regarding the spend (i.e. the transaction itself, +/// and any precomputed data). +/// - sighash: a callback function which is called to obtain the sighash. +/// - sighash: pointer to a buffer where the sighash must be written to. +/// - sighashLen: the length of the buffer. Will be 32. +/// - ctx: the same opaque pointer +/// - scriptCode: the scriptCode being validated. Note that this not always +/// matches scriptSig, i.e. for P2SH. +/// - scriptCodeLen: the length of the script. +/// - hashType: the hash type being used. +/// - nLockTime: the lock time of the transaction being validated. +/// - isFinal: a boolean indicating whether the input being validated is final +/// (i.e. its sequence number is 0xFFFFFFFF). +/// - scriptPubKey: the scriptPubKey of the output being spent. +/// - scriptPubKeyLen: the length of scriptPubKey. +/// - scriptSig: the scriptSig of the input being validated. +/// - scriptSigLen: the length of scriptSig. +/// - flags: the script verification flags to use. +/// - err: if not NULL, err will contain an error/success code for the operation. +/// +/// Note that script verification failure is indicated by err being set to +/// zcash_script_ERR_OK and a return value of 0. EXPORT_SYMBOL int zcash_script_verify_callback( const void* ctx, - void (*sighash)(unsigned char* sighash, const void* ctx, const unsigned char* scriptCode, unsigned int scriptCodeLen, int hashType), + void (*sighash)(unsigned char* sighash, unsigned int sighashLen, const void* ctx, const unsigned char* scriptCode, unsigned int scriptCodeLen, int hashType), int64_t nLockTime, uint8_t isFinal, const unsigned char* scriptPubKey, unsigned int scriptPubKeyLen, const unsigned char* scriptSig, unsigned int scriptSigLen, - int64_t amount, - unsigned int nIn, unsigned int flags, - uint32_t consensusBranchId, zcash_script_error* err); #ifdef __cplusplus diff --git a/src/lib.rs b/src/lib.rs index 569734316..cb4e03a64 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,7 +26,8 @@ mod tests { } extern "C" fn sighash( - s: *mut u8, + sighash_out: *mut u8, + sighash_out_len: c_uint, ctx: *const c_void, _script_code: *const u8, _script_code_len: c_uint, @@ -37,12 +38,14 @@ mod tests { let sighash = hex::decode("e8c7bdac77f6bb1f3aba2eaa1fada551a9c8b3b5ecd1ef86e6e58a5f1aab952c") .unwrap(); - std::ptr::copy_nonoverlapping(sighash.as_ptr(), s, sighash.len()); + assert!(sighash_out_len == sighash.len() as c_uint); + std::ptr::copy_nonoverlapping(sighash.as_ptr(), sighash_out, sighash.len()); } } extern "C" fn invalid_sighash( - s: *mut u8, + sighash_out: *mut u8, + sighash_out_len: c_uint, ctx: *const c_void, _script_code: *const u8, _script_code_len: c_uint, @@ -53,7 +56,8 @@ mod tests { let sighash = hex::decode("08c7bdac77f6bb1f3aba2eaa1fada551a9c8b3b5ecd1ef86e6e58a5f1aab952c") .unwrap(); - std::ptr::copy_nonoverlapping(sighash.as_ptr(), s, sighash.len()); + assert!(sighash_out_len == sighash.len() as c_uint); + std::ptr::copy_nonoverlapping(sighash.as_ptr(), sighash_out, sighash.len()); } } @@ -63,10 +67,7 @@ mod tests { let isFinal: u8 = 1; let script_pub_key = &*SCRIPT_PUBKEY; let script_sig = &*SCRIPT_SIG; - let amount: i64 = 1550280000; - let nIn: c_uint = 0; let flags: c_uint = 513; - let consensus_branch_id: u32 = 0xc2d6d0b4; let mut err = 0; let ret = unsafe { @@ -79,10 +80,7 @@ mod tests { script_pub_key.len() as c_uint, script_sig.as_ptr(), script_sig.len() as c_uint, - amount, - nIn, flags, - consensus_branch_id, &mut err, ) }; @@ -96,10 +94,7 @@ mod tests { let isFinal: u8 = 1; let script_pub_key = &*SCRIPT_PUBKEY; let script_sig = &*SCRIPT_SIG; - let amount: i64 = 1550280000; - let nIn: c_uint = 0; let flags: c_uint = 513; - let consensus_branch_id: u32 = 0xc2d6d0b4; let mut err = 0; let ret = unsafe { @@ -112,10 +107,7 @@ mod tests { script_pub_key.len() as c_uint, script_sig.as_ptr(), script_sig.len() as c_uint, - amount, - nIn, flags, - consensus_branch_id, &mut err, ) }; From ceba7ea26c086c88971beaa46eb3d4a21f409bec Mon Sep 17 00:00:00 2001 From: Conrado Gouvea Date: Mon, 27 May 2024 19:35:21 -0300 Subject: [PATCH 15/16] remove unneeded code --- depend/zcash/src/script/zcash_script.cpp | 265 ----------------------- depend/zcash/src/script/zcash_script.h | 125 +---------- 2 files changed, 1 insertion(+), 389 deletions(-) diff --git a/depend/zcash/src/script/zcash_script.cpp b/depend/zcash/src/script/zcash_script.cpp index 8926cb394..a19798d27 100644 --- a/depend/zcash/src/script/zcash_script.cpp +++ b/depend/zcash/src/script/zcash_script.cpp @@ -6,11 +6,6 @@ #include "zcash_script.h" -#if 0 -#include "consensus/upgrades.h" -#include "primitives/transaction.h" -#include "pubkey.h" -#endif #include "script/interpreter.h" #include "version.h" @@ -21,267 +16,7 @@ inline int set_error(zcash_script_error* ret, zcash_script_error serror) *ret = serror; return 0; } - -#if 0 -// Copy of GetLegacySigOpCount from main.cpp commit c4b2ef7c4. -// Replace with the copy from src/consensus/tx_verify.{cpp,h} after backporting that refactor. -unsigned int GetLegacySigOpCount(const CTransaction& tx) -{ - unsigned int nSigOps = 0; - for (const CTxIn& txin : tx.vin) - { - nSigOps += txin.scriptSig.GetSigOpCount(false); - } - for (const CTxOut& txout : tx.vout) - { - nSigOps += txout.scriptPubKey.GetSigOpCount(false); - } - return nSigOps; -} -#endif -} - -#if 0 -struct PrecomputedTransaction { - const CTransaction tx; - const PrecomputedTransactionData txdata; - - PrecomputedTransaction( - CTransaction txIn, - const unsigned char* allPrevOutputs, - size_t allPrevOutputsLen) : tx(txIn), txdata(txIn, allPrevOutputs, allPrevOutputsLen) {} -}; - -void* zcash_script_new_precomputed_tx( - const unsigned char* txTo, - unsigned int txToLen, - zcash_script_error* err) -{ - try { - const char* txToEnd = (const char *)(txTo + txToLen); - RustDataStream stream((const char *)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); - CTransaction tx; - stream >> tx; - if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) { - set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); - return nullptr; - } - if (tx.nVersion >= ZIP225_TX_VERSION) { - set_error(err, zcash_script_ERR_TX_VERSION); - return nullptr; - } - - // Deserializing the tx did not error. - set_error(err, zcash_script_ERR_OK); - // This is a pre-v5 tx, so the PrecomputedTransactionData constructor - // field `allPrevOutputs` is not used. - auto preTx = new PrecomputedTransaction(tx, nullptr, 0); - return preTx; - } catch (const std::exception&) { - set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing - return nullptr; - } -} - -void* zcash_script_new_precomputed_tx_v5( - const unsigned char* txTo, - unsigned int txToLen, - const unsigned char* allPrevOutputs, - unsigned int allPrevOutputsLen, - zcash_script_error* err) -{ - CTransaction tx; - try { - const char* txToEnd = (const char *)(txTo + txToLen); - RustDataStream stream((const char *)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); - stream >> tx; - if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) { - set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); - return nullptr; - } - } catch (const std::exception&) { - set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing - return nullptr; - } - - try { - auto preTx = new PrecomputedTransaction(tx, allPrevOutputs, allPrevOutputsLen); - // Deserializing the tx did not error. - set_error(err, zcash_script_ERR_OK); - return preTx; - } catch (const std::exception&) { - // We had some error when parsing allPrevOutputs inside the - // PrecomputedTransactionData constructor. - set_error(err, zcash_script_ERR_ALL_PREV_OUTPUTS_DESERIALIZE); - return nullptr; - } -} - -void zcash_script_free_precomputed_tx(void* pre_preTx) -{ - PrecomputedTransaction* preTx = static_cast(pre_preTx); - delete preTx; - preTx = nullptr; -} - -int zcash_script_verify_precomputed( - const void* pre_preTx, - unsigned int nIn, - const unsigned char* scriptPubKey, - unsigned int scriptPubKeyLen, - int64_t amount, - unsigned int flags, - uint32_t consensusBranchId, - zcash_script_error* err) -{ - const PrecomputedTransaction* preTx = static_cast(pre_preTx); - if (nIn >= preTx->tx.vin.size()) - return set_error(err, zcash_script_ERR_TX_INDEX); - - // Regardless of the verification result, the tx did not error. - set_error(err, zcash_script_ERR_OK); - return VerifyScript( - preTx->tx.vin[nIn].scriptSig, - CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), - flags, - TransactionSignatureChecker(&preTx->tx, preTx->txdata, nIn, amount), - consensusBranchId, - NULL); -} - -int zcash_script_verify( - const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, - int64_t amount, - const unsigned char *txTo, unsigned int txToLen, - unsigned int nIn, unsigned int flags, - uint32_t consensusBranchId, - zcash_script_error* err) -{ - try { - const char* txToEnd = (const char *)(txTo + txToLen); - RustDataStream stream((const char *)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); - CTransaction tx; - stream >> tx; - if (nIn >= tx.vin.size()) - return set_error(err, zcash_script_ERR_TX_INDEX); - if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) - return set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); - if (tx.nVersion >= ZIP225_TX_VERSION) { - return set_error(err, zcash_script_ERR_TX_VERSION); - } - - // Regardless of the verification result, the tx did not error. - set_error(err, zcash_script_ERR_OK); - // This is a pre-v5 tx, so the PrecomputedTransactionData constructor - // field `allPrevOutputs` is not used. - PrecomputedTransactionData txdata(tx, {}); - return VerifyScript( - tx.vin[nIn].scriptSig, - CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), - flags, - TransactionSignatureChecker(&tx, txdata, nIn, amount), - consensusBranchId, - NULL); - } catch (const std::exception&) { - return set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing - } -} - -int zcash_script_verify_v5( - const unsigned char* txTo, - unsigned int txToLen, - const unsigned char* allPrevOutputs, - unsigned int allPrevOutputsLen, - unsigned int nIn, - unsigned int flags, - uint32_t consensusBranchId, - zcash_script_error* err) -{ - CTransaction tx; - try { - const char* txToEnd = (const char *)(txTo + txToLen); - RustDataStream stream((const char *)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); - stream >> tx; - if (nIn >= tx.vin.size()) - return set_error(err, zcash_script_ERR_TX_INDEX); - if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) - return set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); - } catch (const std::exception&) { - return set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing - } - - std::vector prevOutputs; - try { - // TODO: we can swap this second deserialization for an FFI call by - // fetching this through PrecomputedTransactionData. Simplicity for now. - CDataStream sAllPrevOutputs( - reinterpret_cast(allPrevOutputs), - reinterpret_cast(allPrevOutputs + allPrevOutputsLen), - SER_NETWORK, - PROTOCOL_VERSION); - sAllPrevOutputs >> prevOutputs; - if (!(tx.IsCoinBase() ? prevOutputs.empty() : tx.vin.size() == prevOutputs.size())) { - return set_error(err, zcash_script_ERR_ALL_PREV_OUTPUTS_SIZE_MISMATCH); - } - } catch (const std::exception&) { - // We had some error when parsing allPrevOutputs inside the - // PrecomputedTransactionData constructor. - return set_error(err, zcash_script_ERR_ALL_PREV_OUTPUTS_DESERIALIZE); - } - - try { - // Regardless of the verification result, the tx did not error. - set_error(err, zcash_script_ERR_OK); - PrecomputedTransactionData txdata(tx, allPrevOutputs, allPrevOutputsLen); - return VerifyScript( - tx.vin[nIn].scriptSig, - prevOutputs[nIn].scriptPubKey, - flags, - TransactionSignatureChecker(&tx, txdata, nIn, prevOutputs[nIn].nValue), - consensusBranchId, - NULL); - } catch (const std::exception&) { - return set_error(err, zcash_script_ERR_VERIFY_SCRIPT); // Error during script verification - } -} - -unsigned int zcash_script_legacy_sigop_count_precomputed( - const void* pre_preTx, - zcash_script_error* err) -{ - const PrecomputedTransaction* preTx = static_cast(pre_preTx); - - // The current implementation of this method never errors. - set_error(err, zcash_script_ERR_OK); - - return GetLegacySigOpCount(preTx->tx); -} - -unsigned int zcash_script_legacy_sigop_count( - const unsigned char *txTo, - unsigned int txToLen, - zcash_script_error* err) -{ - try { - const char* txToEnd = (const char *)(txTo + txToLen); - RustDataStream stream((const char *)txTo, txToEnd, SER_NETWORK, PROTOCOL_VERSION); - CTransaction tx; - stream >> tx; - if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) { - set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH); - return UINT_MAX; - } - - // Deserializing the tx did not error. - set_error(err, zcash_script_ERR_OK); - - return GetLegacySigOpCount(tx); - } catch (const std::exception&) { - set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing - return UINT_MAX; - } } -#endif unsigned int zcash_script_version() { diff --git a/depend/zcash/src/script/zcash_script.h b/depend/zcash/src/script/zcash_script.h index 658014f42..d77528512 100644 --- a/depend/zcash/src/script/zcash_script.h +++ b/depend/zcash/src/script/zcash_script.h @@ -34,7 +34,7 @@ extern "C" { #endif -#define ZCASH_SCRIPT_API_VER 3 +#define ZCASH_SCRIPT_API_VER 4 typedef enum zcash_script_error_t { @@ -57,129 +57,6 @@ enum zcash_script_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), // enable CHECKLOCKTIMEVERIFY (BIP65) }; -#if 0 -/// Deserializes the given transaction and precomputes values to improve -/// script verification performance. -/// -/// This API cannot be used for v5+ transactions, and will return an error. -/// -/// Returns a pointer to the precomputed transaction. Free this with -/// zcash_script_free_precomputed_tx once you are done. -/// The precomputed transaction is guaranteed to not keep a reference to any -/// part of the input buffers, so they can be safely overwritten or deallocated -/// after this function returns. -/// -/// If not NULL, err will contain an error/success code for the operation. -void* zcash_script_new_precomputed_tx( - const unsigned char* txTo, - unsigned int txToLen, - zcash_script_error* err); - -/// Deserializes the given transaction and precomputes values to improve -/// script verification performance. Must be used for V5 transactions; -/// may also be used for previous versions. -/// -/// allPrevOutputs must point to the encoding of the vector of all outputs -/// from previous transactions that are spent by the inputs of the given transaction. -/// The outputs must be encoded as specified by Bitcoin. The full encoding will thus -/// consist of a CompactSize prefix containing the number of outputs, followed by -/// the concatenated outputs, each of them encoded as (value, CompactSize, pk_script). -/// -/// Returns a pointer to the precomputed transaction. Free this with -/// zcash_script_free_precomputed_tx once you are done. -/// -/// If not NULL, err will contain an error/success code for the operation. -void* zcash_script_new_precomputed_tx_v5( - const unsigned char* txTo, - unsigned int txToLen, - const unsigned char* allPrevOutputs, - unsigned int allPrevOutputsLen, - zcash_script_error* err); - -/// Frees a precomputed transaction previously created with -/// zcash_script_new_precomputed_tx. -void zcash_script_free_precomputed_tx(void* preTx); - -/// Returns 1 if the input nIn of the precomputed transaction pointed to by -/// preTx correctly spends the scriptPubKey pointed to by scriptPubKey under -/// the additional constraints specified by flags. -/// -/// If not NULL, err will contain an error/success code for the operation. -/// Note that script verification failure is indicated by err being set to -/// zcash_script_ERR_OK and a return value of 0. -EXPORT_SYMBOL int zcash_script_verify_precomputed( - const void* preTx, - unsigned int nIn, - const unsigned char* scriptPubKey, - unsigned int scriptPubKeyLen, - int64_t amount, - unsigned int flags, - uint32_t consensusBranchId, - zcash_script_error* err); - -/// Returns 1 if the input nIn of the serialized transaction pointed to by -/// txTo correctly spends the scriptPubKey pointed to by scriptPubKey under -/// the additional constraints specified by flags. -/// -/// This API cannot be used for v5+ transactions, and will return an error. -/// -/// If not NULL, err will contain an error/success code for the operation. -/// Note that script verification failure is indicated by err being set to -/// zcash_script_ERR_OK and a return value of 0. -EXPORT_SYMBOL int zcash_script_verify( - const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, - int64_t amount, - const unsigned char *txTo, unsigned int txToLen, - unsigned int nIn, unsigned int flags, - uint32_t consensusBranchId, - zcash_script_error* err); - -/// Returns 1 if the input nIn of the serialized transaction pointed to by -/// txTo correctly spends the matching output in allPrevOutputs under -/// the additional constraints specified by flags. Must be used for V5 transactions; -/// may also be used for previous versions. -/// -/// allPrevOutputs must point to the encoding of the vector of all outputs -/// from previous transactions that are spent by the inputs of the given transaction. -/// The outputs must be encoded as specified by Bitcoin. The full encoding will thus -/// consist of a CompactSize prefix containing the number of outputs, followed by -/// the concatenated outputs, each of them encoded as (value, CompactSize, pk_script). -/// -/// If not NULL, err will contain an error/success code for the operation. -/// Note that script verification failure is indicated by err being set to -/// zcash_script_ERR_OK and a return value of 0. -EXPORT_SYMBOL int zcash_script_verify_v5( - const unsigned char* txTo, - unsigned int txToLen, - const unsigned char* allPrevOutputs, - unsigned int allPrevOutputsLen, - unsigned int nIn, - unsigned int flags, - uint32_t consensusBranchId, - zcash_script_error* err); - -/// Returns the number of transparent signature operations in the -/// transparent inputs and outputs of the precomputed transaction -/// pointed to by preTx. -/// -/// Returns UINT_MAX on error, so that invalid transactions don't pass the Zcash consensus rules. -/// If not NULL, err will contain an error/success code for the operation. -EXPORT_SYMBOL unsigned int zcash_script_legacy_sigop_count_precomputed( - const void* preTx, - zcash_script_error* err); - -/// Returns the number of transparent signature operations in the -/// transparent inputs and outputs of the serialized transaction -/// pointed to by txTo. -/// -/// Returns UINT_MAX on error. -/// If not NULL, err will contain an error/success code for the operation. -EXPORT_SYMBOL unsigned int zcash_script_legacy_sigop_count( - const unsigned char* txTo, - unsigned int txToLen, - zcash_script_error* err); -#endif - /// Returns the current version of the zcash_script library. EXPORT_SYMBOL unsigned int zcash_script_version(); From 73f28bed340e698ea0eaad608548508ae4dcbc59 Mon Sep 17 00:00:00 2001 From: Conrado Gouvea Date: Mon, 27 May 2024 19:52:32 -0300 Subject: [PATCH 16/16] msvc fixes --- depend/zcash/src/pubkey.cpp | 6 ++++++ depend/zcash/src/pubkey.h | 6 ++++++ depend/zcash/src/script/interpreter.cpp | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/depend/zcash/src/pubkey.cpp b/depend/zcash/src/pubkey.cpp index 366dc44c0..55f862685 100644 --- a/depend/zcash/src/pubkey.cpp +++ b/depend/zcash/src/pubkey.cpp @@ -41,6 +41,8 @@ bool CPubKey::Verify(const uint256 &hash, const std::vector& vchS return secp256k1_ecdsa_verify(secp256k1_context_static, &sig, hash.begin(), &pubkey); } +#if 0 + bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector& vchSig) { if (vchSig.size() != COMPACT_SIGNATURE_SIZE) return false; @@ -138,6 +140,7 @@ bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild) const { out.nChild = _nChild; return pubkey.Derive(out.pubkey, out.chaincode, _nChild, chaincode); } +#endif /* static */ bool CPubKey::CheckLowS(const std::vector& vchSig) { secp256k1_ecdsa_signature sig; @@ -149,6 +152,7 @@ bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild) const { return (!secp256k1_ecdsa_signature_normalize(secp256k1_context_static, NULL, &sig)); } +#if 0 /* static */ std::optional CChainablePubKey::FromParts(ChainCode chaincode, CPubKey pubkey) { if (pubkey.IsCompressed()) { return CChainablePubKey(chaincode, pubkey); @@ -156,3 +160,5 @@ bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild) const { return std::nullopt; } } + +#endif \ No newline at end of file diff --git a/depend/zcash/src/pubkey.h b/depend/zcash/src/pubkey.h index 5a0e391bd..f6948f742 100644 --- a/depend/zcash/src/pubkey.h +++ b/depend/zcash/src/pubkey.h @@ -173,8 +173,10 @@ class CPubKey return size() > 0; } +#if 0 //! fully validate whether this is a valid public key (more expensive than IsValid()) bool IsFullyValid() const; +#endif //! Check whether this is a compressed public key. bool IsCompressed() const @@ -193,6 +195,7 @@ class CPubKey */ static bool CheckLowS(const std::vector& vchSig); +#if 0 //! Recover a public key from a compact signature. bool RecoverCompact(const uint256& hash, const std::vector& vchSig); @@ -201,8 +204,10 @@ class CPubKey //! Derive BIP32 child pubkey. bool Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const; +#endif }; +#if 0 class CChainablePubKey { private: ChainCode chaincode; @@ -303,5 +308,6 @@ struct CExtPubKey { Decode(code); } }; +#endif #endif // BITCOIN_PUBKEY_H diff --git a/depend/zcash/src/script/interpreter.cpp b/depend/zcash/src/script/interpreter.cpp index edc16a637..099042a17 100644 --- a/depend/zcash/src/script/interpreter.cpp +++ b/depend/zcash/src/script/interpreter.cpp @@ -985,7 +985,7 @@ bool CallbackTransactionSignatureChecker::CheckSig( try { std::array sighashArray; auto scriptBase = static_cast(scriptCode); - this->sighash(sighashArray.begin(), sighashArray.size(), this->tx, &scriptBase[0], scriptBase.size(), nHashType); + this->sighash(sighashArray.data(), sighashArray.size(), this->tx, &scriptBase[0], scriptBase.size(), nHashType); sighash = uint256::FromRawBytes(sighashArray); } catch (logic_error ex) { return false;