Changeset View
Changeset View
Standalone View
Standalone View
src/test/sigencoding_tests.cpp
Show First 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | 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, | ||||
0x48, 0x0d, 0x48, 0x5f, 0xcf, 0x2c, 0xe0, 0xd0, 0x3b, 0x2e, 0xf0}; | 0x48, 0x0d, 0x48, 0x5f, 0xcf, 0x2c, 0xe0, 0xd0, 0x3b, 0x2e, 0xf0}; | ||||
std::vector<valtype> nonDERSigs{ | |||||
// Non canonical total length. | |||||
{0x30, 0x80, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01}, | |||||
// Zero length R. | |||||
{0x30, 0x2f, 0x02, 0x00, 0x02, 0x21, 0x00, 0xab, 0x1e, 0x3d, | |||||
0xa7, 0x3d, 0x67, 0xe3, 0x20, 0x45, 0xa2, 0x0e, 0x0b, 0x99, | |||||
0x9e, 0x04, 0x99, 0x78, 0xea, 0x8d, 0x6e, 0xe5, 0x48, 0x0d, | |||||
0x48, 0x5f, 0xcf, 0x2c, 0xe0, 0xd0, 0x3b, 0x2e, 0xf0}, | |||||
// Non canonical length for R. | |||||
{0x30, 0x31, 0x02, 0x80, 0x01, 0x6c, 0x02, 0x21, 0x00, 0xab, 0x1e, | |||||
0x3d, 0xa7, 0x3d, 0x67, 0xe3, 0x20, 0x45, 0xa2, 0x0e, 0x0b, 0x99, | |||||
0x9e, 0x04, 0x99, 0x78, 0xea, 0x8d, 0x6e, 0xe5, 0x48, 0x0d, 0x48, | |||||
0x5f, 0xcf, 0x2c, 0xe0, 0xd0, 0x3b, 0x2e, 0xf0}, | |||||
// Negative R. | |||||
{0x30, 0x30, 0x02, 0x01, 0x80, 0x02, 0x21, 0x00, 0xab, 0x1e, | |||||
0x3d, 0xa7, 0x3d, 0x67, 0xe3, 0x20, 0x45, 0xa2, 0x0e, 0x0b, | |||||
0x99, 0x9e, 0x04, 0x99, 0x78, 0xea, 0x8d, 0x6e, 0xe5, 0x48, | |||||
0x0d, 0x48, 0x5f, 0xcf, 0x2c, 0xe0, 0xd0, 0x3b, 0x2e, 0xf0}, | |||||
// Null prefixed R. | |||||
{0x30, 0x31, 0x02, 0x02, 0x00, 0x01, 0x02, 0x21, 0x00, 0xab, 0x1e, | |||||
0x3d, 0xa7, 0x3d, 0x67, 0xe3, 0x20, 0x45, 0xa2, 0x0e, 0x0b, 0x99, | |||||
0x9e, 0x04, 0x99, 0x78, 0xea, 0x8d, 0x6e, 0xe5, 0x48, 0x0d, 0x48, | |||||
0x5f, 0xcf, 0x2c, 0xe0, 0xd0, 0x3b, 0x2e, 0xf0}, | |||||
// Zero length S. | |||||
{0x30, 0x2f, 0x02, 0x21, 0x00, 0xab, 0x1e, 0x3d, 0xa7, 0x3d, | |||||
0x67, 0xe3, 0x20, 0x45, 0xa2, 0x0e, 0x0b, 0x99, 0x9e, 0x04, | |||||
0x99, 0x78, 0xea, 0x8d, 0x6e, 0xe5, 0x48, 0x0d, 0x48, 0x5f, | |||||
0xcf, 0x2c, 0xe0, 0xd0, 0x3b, 0x2e, 0xf0, 0x02, 0x00}, | |||||
// Non canonical length for S. | |||||
{0x30, 0x31, 0x02, 0x21, 0x00, 0xab, 0x1e, 0x3d, 0xa7, 0x3d, 0x67, | |||||
0xe3, 0x20, 0x45, 0xa2, 0x0e, 0x0b, 0x99, 0x9e, 0x04, 0x99, 0x78, | |||||
0xea, 0x8d, 0x6e, 0xe5, 0x48, 0x0d, 0x48, 0x5f, 0xcf, 0x2c, 0xe0, | |||||
0xd0, 0x3b, 0x2e, 0xf0, 0x02, 0x80, 0x01, 0x6c}, | |||||
// Negative S. | |||||
{0x30, 0x30, 0x02, 0x21, 0x00, 0xab, 0x1e, 0x3d, 0xa7, 0x3d, | |||||
0x67, 0xe3, 0x20, 0x45, 0xa2, 0x0e, 0x0b, 0x99, 0x9e, 0x04, | |||||
0x99, 0x78, 0xea, 0x8d, 0x6e, 0xe5, 0x48, 0x0d, 0x48, 0x5f, | |||||
0xcf, 0x2c, 0xe0, 0xd0, 0x3b, 0x2e, 0xf0, 0x02, 0x01, 0x80}, | |||||
// Null prefixed S. | |||||
{0x30, 0x31, 0x02, 0x21, 0x00, 0xab, 0x1e, 0x3d, 0xa7, 0x3d, 0x67, | |||||
0xe3, 0x20, 0x45, 0xa2, 0x0e, 0x0b, 0x99, 0x9e, 0x04, 0x99, 0x78, | |||||
0xea, 0x8d, 0x6e, 0xe5, 0x48, 0x0d, 0x48, 0x5f, 0xcf, 0x2c, 0xe0, | |||||
0xd0, 0x3b, 0x2e, 0xf0, 0x02, 0x02, 0x00, 0x01}, | |||||
}; | |||||
std::vector<valtype> nonParsableSigs{ | |||||
// Too short. | |||||
{0x30}, | |||||
{0x30, 0x06}, | |||||
{0x30, 0x06, 0x02}, | |||||
{0x30, 0x06, 0x02, 0x01}, | |||||
{0x30, 0x06, 0x02, 0x01, 0x01}, | |||||
{0x30, 0x06, 0x02, 0x01, 0x01, 0x02}, | |||||
{0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01}, | |||||
// Invalid type (must be 0x30, coumpound). | |||||
{0x42, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01}, | |||||
// Invalid sizes. | |||||
{0x30, 0x05, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01}, | |||||
{0x30, 0x07, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01}, | |||||
// Invalid R and S sizes. | |||||
{0x30, 0x06, 0x02, 0x00, 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, 0x02, 0x01}, | |||||
// Invalid R and S types. | |||||
{0x30, 0x06, 0x42, 0x01, 0x01, 0x02, 0x01, 0x01}, | |||||
{0x30, 0x06, 0x02, 0x01, 0x01, 0x42, 0x01, 0x01}, | |||||
// Too long. | |||||
{0x30, 0x47, 0x02, 0x21, 0x00, 0x8e, 0x45, 0x16, 0xda, 0x72, 0x53, | |||||
0xcf, 0x06, 0x8e, 0xff, 0xec, 0x6b, 0x95, 0xc4, 0x12, 0x21, 0xc0, | |||||
0xcf, 0x3a, 0x8e, 0x6c, 0xcb, 0x8c, 0xbf, 0x17, 0x25, 0xb5, 0x62, | |||||
0xe9, 0xaf, 0xde, 0x2c, 0x02, 0x22, 0x00, 0xab, 0x1e, 0x3d, 0x00, | |||||
0xa7, 0x3d, 0x67, 0xe3, 0x20, 0x45, 0xa2, 0x0e, 0x0b, 0x99, 0x9e, | |||||
0x04, 0x99, 0x78, 0xea, 0x8d, 0x6e, 0xe5, 0x48, 0x0d, 0x48, 0x5f, | |||||
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(CheckSignatureEncoding({}, flags, &err)); | BOOST_CHECK(CheckSignatureEncoding({}, 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, | CheckSignatureErrorForAllSigHashType(highSSig, flags, | ||||
SCRIPT_ERR_SIG_HIGH_S); | 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) { | |||||
if (flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | | |||||
SCRIPT_VERIFY_STRICTENC)) { | |||||
// If we get any of the dersig flags, the non canonical dersig | |||||
// signature fails. | |||||
CheckSignatureErrorForAllSigHashType(nonDERSig, flags, | |||||
SCRIPT_ERR_SIG_DER); | |||||
} else { | |||||
// If we do not check, then it is accepted. | |||||
CheckSignatureEncodingWithSigHashType(nonDERSig, flags); | |||||
} | |||||
} | |||||
for (const valtype &nonDERSig : nonParsableSigs) { | |||||
if (flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | | |||||
SCRIPT_VERIFY_STRICTENC)) { | |||||
// If we get any of the dersig flags, the invalid signature | |||||
// fails. | |||||
CheckSignatureErrorForAllSigHashType(nonDERSig, flags, | |||||
SCRIPT_ERR_SIG_DER); | |||||
} else { | |||||
// If we do not check, then it is accepted even though it cannot | |||||
// even be parsed. | |||||
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, | ||||
0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, | 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, | ||||
0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0}; | 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0}; | ||||
▲ Show 20 Lines • Show All 147 Lines • Show Last 20 Lines |