Changeset View
Changeset View
Standalone View
Standalone View
src/test/sigencoding_tests.cpp
Show First 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | for (const SigHashType baseSigHash : baseSigHashes) { | ||||
!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); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// Use LCG to probe pseudorandom flag patterns: | |||||
// first 0x00000000, | |||||
// then 0x14057b7e, | |||||
// then 0x1a08ee11, | |||||
// ... | |||||
// With 4096 iterations, for every possible quadruple of flags you can | |||||
// name, there are at least 199 iterations with all four flags on, and at | |||||
// least 195 iterations with all four flags off. | |||||
class LCGflags { | |||||
uint64_t state; | |||||
uint64_t Advance() { | |||||
uint64_t oldstate = state; | |||||
state = oldstate * 6364136223846793005 + 1442695040888963407; | |||||
return oldstate; | |||||
} | |||||
public: | |||||
LCGflags(uint64_t initialstate = 0) : state(initialstate) {} | |||||
uint32_t GetFlags() { return Advance() >> 32; } | |||||
}; | |||||
deadalnix: Put that in a header file (there is probably an existing one that can be leveraged for this.)… | |||||
BOOST_AUTO_TEST_CASE(test_lcg) { | |||||
LCGflags lcg; | |||||
// We want that the first iteration is all-0 flags which is a special | |||||
// case we want for sure being done. | |||||
BOOST_REQUIRE_EQUAL(lcg.GetFlags(), 0x00000000); | |||||
for (int i = 0; i < 99; i++) { | |||||
lcg.GetFlags(); | |||||
} | |||||
// Make sure the LCG is producing expected value after many iterations. | |||||
// This ensures mul and add overflows are acting as expected on this | |||||
// architecture. | |||||
BOOST_REQUIRE_EQUAL(lcg.GetFlags(), 0xf306b780); | |||||
} | |||||
BOOST_AUTO_TEST_CASE(checksignatureencoding_test) { | BOOST_AUTO_TEST_CASE(checksignatureencoding_test) { | ||||
valtype minimalSig{0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01}; | valtype minimalSig{0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01}; | ||||
valtype highSSig{ | valtype highSSig{ | ||||
0x30, 0x45, 0x02, 0x20, 0x3e, 0x45, 0x16, 0xda, 0x72, 0x53, 0xcf, 0x06, | 0x30, 0x45, 0x02, 0x20, 0x3e, 0x45, 0x16, 0xda, 0x72, 0x53, 0xcf, 0x06, | ||||
0x8e, 0xff, 0xec, 0x6b, 0x95, 0xc4, 0x12, 0x21, 0xc0, 0xcf, 0x3a, 0x8e, | 0x8e, 0xff, 0xec, 0x6b, 0x95, 0xc4, 0x12, 0x21, 0xc0, 0xcf, 0x3a, 0x8e, | ||||
0x6c, 0xcb, 0x8c, 0xbf, 0x17, 0x25, 0xb5, 0x62, 0xe9, 0xaf, 0xde, 0x2c, | 0x6c, 0xcb, 0x8c, 0xbf, 0x17, 0x25, 0xb5, 0x62, 0xe9, 0xaf, 0xde, 0x2c, | ||||
0x02, 0x21, 0x00, 0xab, 0x1e, 0x3d, 0xa7, 0x3d, 0x67, 0xe3, 0x20, 0x45, | 0x02, 0x21, 0x00, 0xab, 0x1e, 0x3d, 0xa7, 0x3d, 0x67, 0xe3, 0x20, 0x45, | ||||
0xa2, 0x0e, 0x0b, 0x99, 0x9e, 0x04, 0x99, 0x78, 0xea, 0x8d, 0x6e, 0xe5, | 0xa2, 0x0e, 0x0b, 0x99, 0x9e, 0x04, 0x99, 0x78, 0xea, 0x8d, 0x6e, 0xe5, | ||||
▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | std::vector<valtype> nonParsableSigs{ | ||||
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 | LCGflags lcg; | ||||
// rewrite in the future to randomly pick a set of flags to evaluate. | for (int i = 0; i < 4096; i++) { | ||||
for (uint32_t flags = 0; flags < (1U << 17); flags++) { | uint32_t flags = lcg.GetFlags(); | ||||
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)); | ||||
BOOST_CHECK(CheckTransactionECDSASignatureEncoding({}, 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. | ||||
▲ Show 20 Lines • Show All 148 Lines • ▼ Show 20 Lines | std::vector<valtype> invalidKeys{ | ||||
0x9a, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xde, | 0x9a, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xde, | ||||
0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x0f, 0xff}, | 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x0f, 0xff}, | ||||
// Full key, compressed key size. | // Full key, compressed key size. | ||||
{0x04, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, | {0x04, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, | ||||
0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0xab, 0xba, 0x9a, | 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0xab, 0xba, 0x9a, | ||||
0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0}, | 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0}, | ||||
}; | }; | ||||
// If we add many more flags, this loop can get too expensive, but we can | LCGflags lcg; | ||||
// rewrite in the future to randomly pick a set of flags to evaluate. | for (int i = 0; i < 4096; i++) { | ||||
for (uint32_t flags = 0; flags < (1U << 17); flags++) { | uint32_t flags = lcg.GetFlags(); | ||||
ScriptError err = SCRIPT_ERR_OK; | ScriptError err = SCRIPT_ERR_OK; | ||||
// Compressed pubkeys are always valid. | // Compressed pubkeys are always valid. | ||||
BOOST_CHECK(CheckPubKeyEncoding(compressedKey0, flags, &err)); | BOOST_CHECK(CheckPubKeyEncoding(compressedKey0, flags, &err)); | ||||
BOOST_CHECK(CheckPubKeyEncoding(compressedKey1, flags, &err)); | BOOST_CHECK(CheckPubKeyEncoding(compressedKey1, flags, &err)); | ||||
// If SCRIPT_VERIFY_COMPRESSED_PUBKEYTYPE is specified, full key are | // If SCRIPT_VERIFY_COMPRESSED_PUBKEYTYPE is specified, full key are | ||||
// disabled. | // disabled. | ||||
Show All 25 Lines |
Put that in a header file (there is probably an existing one that can be leveraged for this.), Migrate the radix test to use it and make it have its own test. This can be done in its own diff or in that one.
rename GetFlags and just do the advancing in there. Just call it next() or something.