Changeset View
Changeset View
Standalone View
Standalone View
src/test/sigencoding_tests.cpp
Show All 10 Lines | |||||
BOOST_FIXTURE_TEST_SUITE(sigencoding_tests, BasicTestingSetup) | BOOST_FIXTURE_TEST_SUITE(sigencoding_tests, BasicTestingSetup) | ||||
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 | |||||
CheckSignatureErrorForAllSigHashType(const valtype &vchSig, uint32_t flags, | |||||
const ScriptError expected_error) { | |||||
ScriptError err = SCRIPT_ERR_OK; | |||||
BOOST_CHECK(!CheckDataSignatureEncoding(vchSig, flags, &err)); | |||||
BOOST_CHECK_EQUAL(err, expected_error); | |||||
for (int i = 0; i <= 0xff; i++) { | |||||
valtype sig = SignatureWithHashType(vchSig, SigHashType(i)); | |||||
BOOST_CHECK(!CheckTransactionSignatureEncoding(sig, flags, &err)); | |||||
BOOST_CHECK_EQUAL(err, expected_error); | |||||
} | |||||
} | |||||
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(CheckDataSignatureEncoding(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; | ||||
▲ Show 20 Lines • Show All 114 Lines • ▼ Show 20 Lines | std::vector<valtype> nonParsableSigs{ | ||||
// Invalid R and S sizes. | // Invalid R and S sizes. | ||||
{0x30, 0x06, 0x02, 0x00, 0x01, 0x02, 0x01, 0x01}, | {0x30, 0x06, 0x02, 0x00, 0x01, 0x02, 0x01, 0x01}, | ||||
{0x30, 0x06, 0x02, 0x02, 0x01, 0x02, 0x01, 0x01}, | {0x30, 0x06, 0x02, 0x02, 0x01, 0x02, 0x01, 0x01}, | ||||
{0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x00, 0x01}, | {0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x00, 0x01}, | ||||
{0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01}, | {0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01}, | ||||
// Invalid R and S types. | // Invalid R and S types. | ||||
{0x30, 0x06, 0x42, 0x01, 0x01, 0x02, 0x01, 0x01}, | {0x30, 0x06, 0x42, 0x01, 0x01, 0x02, 0x01, 0x01}, | ||||
{0x30, 0x06, 0x02, 0x01, 0x01, 0x42, 0x01, 0x01}, | {0x30, 0x06, 0x02, 0x01, 0x01, 0x42, 0x01, 0x01}, | ||||
// S out of bounds. | |||||
{0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00}, | |||||
// Too long. | // Too long. | ||||
{0x30, 0x47, 0x02, 0x21, 0x00, 0x8e, 0x45, 0x16, 0xda, 0x72, 0x53, | {0x30, 0x47, 0x02, 0x21, 0x00, 0x8e, 0x45, 0x16, 0xda, 0x72, 0x53, | ||||
0xcf, 0x06, 0x8e, 0xff, 0xec, 0x6b, 0x95, 0xc4, 0x12, 0x21, 0xc0, | 0xcf, 0x06, 0x8e, 0xff, 0xec, 0x6b, 0x95, 0xc4, 0x12, 0x21, 0xc0, | ||||
0xcf, 0x3a, 0x8e, 0x6c, 0xcb, 0x8c, 0xbf, 0x17, 0x25, 0xb5, 0x62, | 0xcf, 0x3a, 0x8e, 0x6c, 0xcb, 0x8c, 0xbf, 0x17, 0x25, 0xb5, 0x62, | ||||
0xe9, 0xaf, 0xde, 0x2c, 0x02, 0x22, 0x00, 0xab, 0x1e, 0x3d, 0x00, | 0xe9, 0xaf, 0xde, 0x2c, 0x02, 0x22, 0x00, 0xab, 0x1e, 0x3d, 0x00, | ||||
0xa7, 0x3d, 0x67, 0xe3, 0x20, 0x45, 0xa2, 0x0e, 0x0b, 0x99, 0x9e, | 0xa7, 0x3d, 0x67, 0xe3, 0x20, 0x45, 0xa2, 0x0e, 0x0b, 0x99, 0x9e, | ||||
0x04, 0x99, 0x78, 0xea, 0x8d, 0x6e, 0xe5, 0x48, 0x0d, 0x48, 0x5f, | 0x04, 0x99, 0x78, 0xea, 0x8d, 0x6e, 0xe5, 0x48, 0x0d, 0x48, 0x5f, | ||||
0xcf, 0x2c, 0xe0, 0xd0, 0x3b, 0x2e, 0xf0}, | 0xcf, 0x2c, 0xe0, 0xd0, 0x3b, 0x2e, 0xf0}, | ||||
}; | }; | ||||
// 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(CheckDataSignatureEncoding({}, flags, &err)); | ||||
BOOST_CHECK(CheckTransactionSignatureEncoding({}, flags, &err)); | BOOST_CHECK(CheckTransactionSignatureEncoding({}, 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. | ||||
CheckSignatureErrorForAllSigHashType(highSSig, flags, | BOOST_CHECK(!CheckDataSignatureEncoding(highSSig, flags, &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. | ||||
CheckSignatureErrorForAllSigHashType(nonDERSig, flags, | BOOST_CHECK( | ||||
SCRIPT_ERR_SIG_DER); | !CheckDataSignatureEncoding(nonDERSig, flags, &err)); | ||||
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. | ||||
CheckSignatureEncodingWithSigHashType(nonDERSig, flags); | BOOST_CHECK(CheckDataSignatureEncoding(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 invalid signature | // If we get any of the dersig flags, the high S but non dersig | ||||
// fails. | // signature fails. | ||||
CheckSignatureErrorForAllSigHashType(nonDERSig, flags, | BOOST_CHECK( | ||||
SCRIPT_ERR_SIG_DER); | !CheckDataSignatureEncoding(nonDERSig, flags, &err)); | ||||
BOOST_CHECK_EQUAL(err, SCRIPT_ERR_SIG_DER); | |||||
} else { | } else { | ||||
// If we do not check, then it is accepted even though it cannot | // If we do not check, then it is accepted. | ||||
// even be parsed. | BOOST_CHECK(CheckDataSignatureEncoding(nonDERSig, flags, &err)); | ||||
CheckSignatureEncodingWithSigHashType(nonDERSig, flags); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
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 149 Lines • Show Last 20 Lines |