Changeset View
Changeset View
Standalone View
Standalone View
src/test/sigencoding_tests.cpp
Show All 13 Lines | |||||
static valtype SignatureWithHashType(valtype vchSig, SigHashType sigHash) { | static valtype SignatureWithHashType(valtype vchSig, SigHashType sigHash) { | ||||
vchSig.push_back(static_cast<uint8_t>(sigHash.getRawSigHashType())); | vchSig.push_back(static_cast<uint8_t>(sigHash.getRawSigHashType())); | ||||
return vchSig; | return vchSig; | ||||
} | } | ||||
static void CheckSignatureEncodingWithSigHashType(const valtype &vchSig, | static void CheckSignatureEncodingWithSigHashType(const valtype &vchSig, | ||||
uint32_t flags) { | uint32_t flags) { | ||||
ScriptError err = SCRIPT_ERR_OK; | ScriptError err = SCRIPT_ERR_OK; | ||||
BOOST_CHECK(CheckDataSignatureEncoding(vchSig, flags, &err)); | BOOST_CHECK(CheckDataECDSASignatureEncoding(vchSig, flags, &err)); | ||||
const bool hasForkId = (flags & SCRIPT_ENABLE_SIGHASH_FORKID) != 0; | const bool hasForkId = (flags & SCRIPT_ENABLE_SIGHASH_FORKID) != 0; | ||||
const bool hasStrictEnc = (flags & SCRIPT_VERIFY_STRICTENC) != 0; | const bool hasStrictEnc = (flags & SCRIPT_VERIFY_STRICTENC) != 0; | ||||
std::vector<BaseSigHashType> allBaseTypes{ | std::vector<BaseSigHashType> allBaseTypes{ | ||||
BaseSigHashType::ALL, BaseSigHashType::NONE, BaseSigHashType::SINGLE}; | BaseSigHashType::ALL, BaseSigHashType::NONE, BaseSigHashType::SINGLE}; | ||||
std::vector<SigHashType> baseSigHashes; | std::vector<SigHashType> baseSigHashes; | ||||
for (const BaseSigHashType baseType : allBaseTypes) { | for (const BaseSigHashType baseType : allBaseTypes) { | ||||
const SigHashType baseSigHash = SigHashType().withBaseType(baseType); | const SigHashType baseSigHash = SigHashType().withBaseType(baseType); | ||||
baseSigHashes.push_back(baseSigHash); | baseSigHashes.push_back(baseSigHash); | ||||
baseSigHashes.push_back(baseSigHash.withAnyoneCanPay(true)); | baseSigHashes.push_back(baseSigHash.withAnyoneCanPay(true)); | ||||
} | } | ||||
for (const SigHashType baseSigHash : baseSigHashes) { | for (const SigHashType baseSigHash : baseSigHashes) { | ||||
// Check the signature with the proper forkid flag. | // Check the signature with the proper forkid flag. | ||||
SigHashType sigHash = baseSigHash.withForkId(hasForkId); | SigHashType sigHash = baseSigHash.withForkId(hasForkId); | ||||
valtype validSig = SignatureWithHashType(vchSig, sigHash); | valtype validSig = SignatureWithHashType(vchSig, sigHash); | ||||
BOOST_CHECK(CheckTransactionSignatureEncoding(validSig, flags, &err)); | BOOST_CHECK(CheckTransactionECDSASignatureEncoding(validSig, flags, &err)); | ||||
// If we have strict encoding, we prevent the use of undefined flags. | // If we have strict encoding, we prevent the use of undefined flags. | ||||
std::array<SigHashType, 2> undefSigHashes{ | std::array<SigHashType, 2> undefSigHashes{ | ||||
{SigHashType(sigHash.getRawSigHashType() | 0x20), | {SigHashType(sigHash.getRawSigHashType() | 0x20), | ||||
sigHash.withBaseType(BaseSigHashType::UNSUPPORTED)}}; | sigHash.withBaseType(BaseSigHashType::UNSUPPORTED)}}; | ||||
for (SigHashType undefSigHash : undefSigHashes) { | for (SigHashType undefSigHash : undefSigHashes) { | ||||
valtype undefSighash = SignatureWithHashType(vchSig, undefSigHash); | valtype undefSighash = SignatureWithHashType(vchSig, undefSigHash); | ||||
BOOST_CHECK_EQUAL( | BOOST_CHECK_EQUAL( | ||||
CheckTransactionSignatureEncoding(undefSighash, flags, &err), | CheckTransactionECDSASignatureEncoding(undefSighash, flags, &err), | ||||
!hasStrictEnc); | !hasStrictEnc); | ||||
if (hasStrictEnc) { | if (hasStrictEnc) { | ||||
BOOST_CHECK_EQUAL(err, SCRIPT_ERR_SIG_HASHTYPE); | BOOST_CHECK_EQUAL(err, SCRIPT_ERR_SIG_HASHTYPE); | ||||
} | } | ||||
} | } | ||||
// If we check strict encoding, then invalid forkid is an error. | // If we check strict encoding, then invalid forkid is an error. | ||||
SigHashType invalidSigHash = baseSigHash.withForkId(!hasForkId); | SigHashType invalidSigHash = baseSigHash.withForkId(!hasForkId); | ||||
valtype invalidSig = SignatureWithHashType(vchSig, invalidSigHash); | valtype invalidSig = SignatureWithHashType(vchSig, invalidSigHash); | ||||
BOOST_CHECK_EQUAL( | BOOST_CHECK_EQUAL( | ||||
CheckTransactionSignatureEncoding(invalidSig, flags, &err), | CheckTransactionECDSASignatureEncoding(invalidSig, flags, &err), | ||||
!hasStrictEnc); | !hasStrictEnc); | ||||
if (hasStrictEnc) { | if (hasStrictEnc) { | ||||
BOOST_CHECK_EQUAL(err, hasForkId ? SCRIPT_ERR_MUST_USE_FORKID | BOOST_CHECK_EQUAL(err, hasForkId ? SCRIPT_ERR_MUST_USE_FORKID | ||||
: SCRIPT_ERR_ILLEGAL_FORKID); | : SCRIPT_ERR_ILLEGAL_FORKID); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(checksignatureencoding_test) { | ||||
}; | }; | ||||
// If we add many more flags, this loop can get too expensive, but we can | // If we add many more flags, this loop can get too expensive, but we can | ||||
// rewrite in the future to randomly pick a set of flags to evaluate. | // rewrite in the future to randomly pick a set of flags to evaluate. | ||||
for (uint32_t flags = 0; flags < (1U << 17); flags++) { | for (uint32_t flags = 0; flags < (1U << 17); flags++) { | ||||
ScriptError err = SCRIPT_ERR_OK; | ScriptError err = SCRIPT_ERR_OK; | ||||
// Empty sig is always valid. | // Empty sig is always valid. | ||||
BOOST_CHECK(CheckDataSignatureEncoding({}, flags, &err)); | BOOST_CHECK(CheckDataECDSASignatureEncoding({}, flags, &err)); | ||||
BOOST_CHECK(CheckTransactionSignatureEncoding({}, flags, &err)); | BOOST_CHECK(CheckTransactionECDSASignatureEncoding({}, flags, &err)); | ||||
// Signature are valid as long as the forkid flag is correct. | // Signature are valid as long as the forkid flag is correct. | ||||
CheckSignatureEncodingWithSigHashType(minimalSig, flags); | CheckSignatureEncodingWithSigHashType(minimalSig, flags); | ||||
if (flags & SCRIPT_VERIFY_LOW_S) { | if (flags & SCRIPT_VERIFY_LOW_S) { | ||||
// If we do enforce low S, then high S sigs are rejected. | // If we do enforce low S, then high S sigs are rejected. | ||||
BOOST_CHECK(!CheckDataSignatureEncoding(highSSig, flags, &err)); | BOOST_CHECK(!CheckDataECDSASignatureEncoding(highSSig, flags, &err)); | ||||
BOOST_CHECK_EQUAL(err, SCRIPT_ERR_SIG_HIGH_S); | BOOST_CHECK_EQUAL(err, SCRIPT_ERR_SIG_HIGH_S); | ||||
} else { | } else { | ||||
// If we do not enforce low S, then high S sigs are accepted. | // If we do not enforce low S, then high S sigs are accepted. | ||||
CheckSignatureEncodingWithSigHashType(highSSig, flags); | CheckSignatureEncodingWithSigHashType(highSSig, flags); | ||||
} | } | ||||
for (const valtype &nonDERSig : nonDERSigs) { | for (const valtype &nonDERSig : nonDERSigs) { | ||||
if (flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | | if (flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | | ||||
SCRIPT_VERIFY_STRICTENC)) { | SCRIPT_VERIFY_STRICTENC)) { | ||||
// If we get any of the dersig flags, the non canonical dersig | // If we get any of the dersig flags, the non canonical dersig | ||||
// signature fails. | // signature fails. | ||||
BOOST_CHECK( | BOOST_CHECK( | ||||
!CheckDataSignatureEncoding(nonDERSig, flags, &err)); | !CheckDataECDSASignatureEncoding(nonDERSig, flags, &err)); | ||||
BOOST_CHECK_EQUAL(err, SCRIPT_ERR_SIG_DER); | BOOST_CHECK_EQUAL(err, SCRIPT_ERR_SIG_DER); | ||||
} else { | } else { | ||||
// If we do not check, then it is accepted. | // If we do not check, then it is accepted. | ||||
BOOST_CHECK(CheckDataSignatureEncoding(nonDERSig, flags, &err)); | BOOST_CHECK(CheckDataECDSASignatureEncoding(nonDERSig, flags, &err)); | ||||
} | } | ||||
} | } | ||||
for (const valtype &nonDERSig : nonParsableSigs) { | for (const valtype &nonDERSig : nonParsableSigs) { | ||||
if (flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | | if (flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | | ||||
SCRIPT_VERIFY_STRICTENC)) { | SCRIPT_VERIFY_STRICTENC)) { | ||||
// If we get any of the dersig flags, the high S but non dersig | // If we get any of the dersig flags, the high S but non dersig | ||||
// signature fails. | // signature fails. | ||||
BOOST_CHECK( | BOOST_CHECK( | ||||
!CheckDataSignatureEncoding(nonDERSig, flags, &err)); | !CheckDataECDSASignatureEncoding(nonDERSig, flags, &err)); | ||||
BOOST_CHECK_EQUAL(err, SCRIPT_ERR_SIG_DER); | BOOST_CHECK_EQUAL(err, SCRIPT_ERR_SIG_DER); | ||||
} else { | } else { | ||||
// If we do not check, then it is accepted. | // If we do not check, then it is accepted. | ||||
BOOST_CHECK(CheckDataSignatureEncoding(nonDERSig, flags, &err)); | BOOST_CHECK(CheckDataECDSASignatureEncoding(nonDERSig, flags, &err)); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(checkpubkeyencoding_test) { | BOOST_AUTO_TEST_CASE(checkpubkeyencoding_test) { | ||||
valtype compressedKey0{0x02, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, | valtype compressedKey0{0x02, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, | ||||
0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, | 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, | ||||
▲ Show 20 Lines • Show All 148 Lines • Show Last 20 Lines |