@@ -186,11 +186,17 @@ bool static IsLowDERSignature(const valtype &vchSig, ScriptError* serror) {
186186 return true ;
187187}
188188
189- bool static IsDefinedHashtypeSignature (const valtype &vchSig) {
189+ bool static IsDefinedHashtypeSignature (const valtype &vchSig, unsigned int flags ) {
190190 if (vchSig.size () == 0 ) {
191191 return false ;
192192 }
193193 unsigned char nHashType = vchSig[vchSig.size () - 1 ] & (~(SIGHASH_ANYONECANPAY));
194+
195+ // ELEMENTS: Only allow SIGHASH_RANGEPROOF if the flag is set (after dynafed activation).
196+ if ((flags & SCRIPT_SIGHASH_RANGEPROOF) == SCRIPT_SIGHASH_RANGEPROOF) {
197+ nHashType = nHashType & (~(SIGHASH_RANGEPROOF));
198+ }
199+
194200 if (nHashType < SIGHASH_ALL || nHashType > SIGHASH_SINGLE)
195201 return false ;
196202
@@ -216,7 +222,7 @@ bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, unsigned i
216222 } else if ((flags & SCRIPT_VERIFY_LOW_S) != 0 && !IsLowDERSignature (vchSigCopy, serror)) {
217223 // serror is set
218224 return false ;
219- } else if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsDefinedHashtypeSignature (vchSigCopy)) {
225+ } else if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsDefinedHashtypeSignature (vchSigCopy, flags )) {
220226 return set_error (serror, SCRIPT_ERR_SIG_HASHTYPE);
221227 }
222228 return true ;
@@ -368,7 +374,7 @@ static bool EvalChecksigPreTapscript(const valtype& vchSig, const valtype& vchPu
368374 // serror is set
369375 return false ;
370376 }
371- fSuccess = checker.CheckECDSASignature (vchSig, vchPubKey, scriptCode, sigversion);
377+ fSuccess = checker.CheckECDSASignature (vchSig, vchPubKey, scriptCode, sigversion, flags );
372378
373379 if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && vchSig.size ())
374380 return set_error (serror, SCRIPT_ERR_SIG_NULLFAIL);
@@ -1466,7 +1472,7 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
14661472 }
14671473
14681474 // Check signature
1469- bool fOk = checker.CheckECDSASignature (vchSig, vchPubKey, scriptCode, sigversion);
1475+ bool fOk = checker.CheckECDSASignature (vchSig, vchPubKey, scriptCode, sigversion, flags );
14701476
14711477 if (fOk ) {
14721478 isig++;
@@ -1647,13 +1653,15 @@ class CTransactionSignatureSerializer
16471653 const CScript& scriptCode; // !< output script being consumed
16481654 const unsigned int nIn; // !< input index of txTo being signed
16491655 const bool fAnyoneCanPay ; // !< whether the hashtype has the SIGHASH_ANYONECANPAY flag set
1656+ const bool fRangeproof ; // !< whether the hashtype has the SIGHASH_RANGEPROOF flag set
16501657 const bool fHashSingle ; // !< whether the hashtype is SIGHASH_SINGLE
16511658 const bool fHashNone ; // !< whether the hashtype is SIGHASH_NONE
16521659
16531660public:
1654- CTransactionSignatureSerializer (const T& txToIn, const CScript& scriptCodeIn, unsigned int nInIn, int nHashTypeIn) :
1661+ CTransactionSignatureSerializer (const T& txToIn, const CScript& scriptCodeIn, unsigned int nInIn, int nHashTypeIn, unsigned int flags ) :
16551662 txTo (txToIn), scriptCode(scriptCodeIn), nIn(nInIn),
16561663 fAnyoneCanPay (!!(nHashTypeIn & SIGHASH_ANYONECANPAY)),
1664+ fRangeproof (!!(flags & SCRIPT_SIGHASH_RANGEPROOF) && !!(nHashTypeIn & SIGHASH_RANGEPROOF)),
16571665 fHashSingle ((nHashTypeIn & 0x1f ) == SIGHASH_SINGLE),
16581666 fHashNone ((nHashTypeIn & 0x1f ) == SIGHASH_NONE) {}
16591667
@@ -1710,11 +1718,23 @@ class CTransactionSignatureSerializer
17101718 /* * Serialize an output of txTo */
17111719 template <typename S>
17121720 void SerializeOutput (S &s, unsigned int nOutput) const {
1713- if (fHashSingle && nOutput != nIn)
1721+ if (fHashSingle && nOutput != nIn) {
17141722 // Do not lock-in the txout payee at other indices as txin
17151723 ::Serialize (s, CTxOut());
1716- else
1724+ } else {
17171725 ::Serialize (s, txTo.vout[nOutput]);
1726+
1727+ // Serialize rangeproof
1728+ if (fRangeproof ) {
1729+ if (nOutput < txTo.witness .vtxoutwit .size ()) {
1730+ ::Serialize (s, txTo.witness.vtxoutwit[nOutput].vchRangeproof);
1731+ ::Serialize (s, txTo.witness.vtxoutwit[nOutput].vchSurjectionproof);
1732+ } else {
1733+ ::Serialize (s, (unsigned char ) 0);
1734+ ::Serialize (s, (unsigned char ) 0);
1735+ }
1736+ }
1737+ }
17181738 }
17191739
17201740 /* * Serialize txTo */
@@ -1803,6 +1823,20 @@ uint256 GetSpentScriptsSHA256(const std::vector<CTxOut>& outputs_spent)
18031823 return ss.GetSHA256 ();
18041824}
18051825
1826+ template <class T >
1827+ uint256 GetRangeproofsHash (const T& txTo) {
1828+ CHashWriter ss (SER_GETHASH, 0 );
1829+ for (size_t i = 0 ; i < txTo.vout .size (); i++) {
1830+ if (i < txTo.witness .vtxoutwit .size ()) {
1831+ ss << txTo.witness .vtxoutwit [i].vchRangeproof ;
1832+ ss << txTo.witness .vtxoutwit [i].vchSurjectionproof ;
1833+ } else {
1834+ ss << (unsigned char ) 0 ;
1835+ ss << (unsigned char ) 0 ;
1836+ }
1837+ }
1838+ return ss.GetHash ();
1839+ }
18061840
18071841} // namespace
18081842
@@ -1850,6 +1884,7 @@ void PrecomputedTransactionData::Init(const T& txTo, std::vector<CTxOut>&& spent
18501884 hashSequence = SHA256Uint256 (m_sequences_single_hash);
18511885 hashIssuance = SHA256Uint256 (GetIssuanceSHA256 (txTo));
18521886 hashOutputs = SHA256Uint256 (m_outputs_single_hash);
1887+ hashRangeproofs = GetRangeproofsHash (txTo);
18531888 m_bip143_segwit_ready = true ;
18541889 }
18551890 if (uses_bip341_taproot) {
@@ -1962,7 +1997,7 @@ bool SignatureHashSchnorr(uint256& hash_out, const ScriptExecutionData& execdata
19621997}
19631998
19641999template <class T >
1965- uint256 SignatureHash (const CScript& scriptCode, const T& txTo, unsigned int nIn, int nHashType, const CConfidentialValue& amount, SigVersion sigversion, const PrecomputedTransactionData* cache)
2000+ uint256 SignatureHash (const CScript& scriptCode, const T& txTo, unsigned int nIn, int nHashType, const CConfidentialValue& amount, SigVersion sigversion, unsigned int flags, const PrecomputedTransactionData* cache)
19662001{
19672002 assert (nIn < txTo.vin .size ());
19682003
@@ -1971,7 +2006,9 @@ uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn
19712006 uint256 hashSequence;
19722007 uint256 hashIssuance;
19732008 uint256 hashOutputs;
2009+ uint256 hashRangeproofs;
19742010 const bool cacheready = cache && cache->m_bip143_segwit_ready ;
2011+ bool fRangeproof = !!(flags & SCRIPT_SIGHASH_RANGEPROOF) && !!(nHashType & SIGHASH_RANGEPROOF);
19752012
19762013 if (!(nHashType & SIGHASH_ANYONECANPAY)) {
19772014 hashPrevouts = cacheready ? cache->hashPrevouts : SHA256Uint256 (GetPrevoutsSHA256 (txTo));
@@ -1987,10 +2024,26 @@ uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn
19872024
19882025 if ((nHashType & 0x1f ) != SIGHASH_SINGLE && (nHashType & 0x1f ) != SIGHASH_NONE) {
19892026 hashOutputs = cacheready ? cache->hashOutputs : SHA256Uint256 (GetOutputsSHA256 (txTo));
2027+
2028+ if (fRangeproof ) {
2029+ hashRangeproofs = cacheready ? cache->hashRangeproofs : SHA256Uint256 (GetRangeproofsHash (txTo));
2030+ }
19902031 } else if ((nHashType & 0x1f ) == SIGHASH_SINGLE && nIn < txTo.vout .size ()) {
19912032 CHashWriter ss (SER_GETHASH, 0 );
19922033 ss << txTo.vout [nIn];
19932034 hashOutputs = ss.GetHash ();
2035+
2036+ if (fRangeproof ) {
2037+ CHashWriter ss (SER_GETHASH, 0 );
2038+ if (nIn < txTo.witness .vtxoutwit .size ()) {
2039+ ss << txTo.witness .vtxoutwit [nIn].vchRangeproof ;
2040+ ss << txTo.witness .vtxoutwit [nIn].vchSurjectionproof ;
2041+ } else {
2042+ ss << (unsigned char ) 0 ;
2043+ ss << (unsigned char ) 0 ;
2044+ }
2045+ hashRangeproofs = ss.GetHash ();
2046+ }
19942047 }
19952048
19962049 CHashWriter ss (SER_GETHASH, 0 );
@@ -2019,6 +2072,11 @@ uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn
20192072 }
20202073 // Outputs (none/one/all, depending on flags)
20212074 ss << hashOutputs;
2075+ if (fRangeproof ) {
2076+ // This addition must be conditional because it was added after
2077+ // the segwit sighash was specified.
2078+ ss << hashRangeproofs;
2079+ }
20222080 // Locktime
20232081 ss << txTo.nLockTime ;
20242082 // Sighash type
@@ -2036,7 +2094,7 @@ uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn
20362094 }
20372095
20382096 // Wrapper to serialize only the necessary parts of the transaction being signed
2039- CTransactionSignatureSerializer<T> txTmp (txTo, scriptCode, nIn, nHashType);
2097+ CTransactionSignatureSerializer<T> txTmp (txTo, scriptCode, nIn, nHashType, flags );
20402098
20412099 // Serialize and hash
20422100 CHashWriter ss (SER_GETHASH, 0 );
@@ -2057,7 +2115,7 @@ bool GenericTransactionSignatureChecker<T>::VerifySchnorrSignature(Span<const un
20572115}
20582116
20592117template <class T >
2060- bool GenericTransactionSignatureChecker<T>::CheckECDSASignature(const std::vector<unsigned char >& vchSigIn, const std::vector<unsigned char >& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const
2118+ bool GenericTransactionSignatureChecker<T>::CheckECDSASignature(const std::vector<unsigned char >& vchSigIn, const std::vector<unsigned char >& vchPubKey, const CScript& scriptCode, SigVersion sigversion, unsigned int flags ) const
20612119{
20622120 CPubKey pubkey (vchPubKey);
20632121 if (!pubkey.IsValid ())
@@ -2070,7 +2128,7 @@ bool GenericTransactionSignatureChecker<T>::CheckECDSASignature(const std::vecto
20702128 int nHashType = vchSig.back ();
20712129 vchSig.pop_back ();
20722130
2073- uint256 sighash = SignatureHash (scriptCode, *txTo, nIn, nHashType, amount, sigversion, this ->txdata );
2131+ uint256 sighash = SignatureHash (scriptCode, *txTo, nIn, nHashType, amount, sigversion, flags, this ->txdata );
20742132
20752133 if (!VerifyECDSASignature (vchSig, pubkey, sighash))
20762134 return false ;
0 commit comments