Changeset View
Changeset View
Standalone View
Standalone View
src/test/sigencoding_tests.cpp
Show All 19 Lines | |||||
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; | ||||
const bool is64 = (vchSig.size() == 64); | |||||
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(CheckTransactionSignatureEncoding(validSig, flags, &err)); | ||||
BOOST_CHECK( | BOOST_CHECK_EQUAL(!is64, CheckTransactionECDSASignatureEncoding( | ||||
CheckTransactionECDSASignatureEncoding(validSig, flags, &err)); | 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), | CheckTransactionSignatureEncoding(undefSighash, flags, &err), | ||||
!hasStrictEnc); | !hasStrictEnc); | ||||
BOOST_CHECK_EQUAL(CheckTransactionECDSASignatureEncoding( | |||||
undefSighash, flags, &err), | |||||
!hasStrictEnc); | |||||
if (hasStrictEnc) { | if (hasStrictEnc) { | ||||
BOOST_CHECK_EQUAL(err, SCRIPT_ERR_SIG_HASHTYPE); | BOOST_CHECK_EQUAL(err, SCRIPT_ERR_SIG_HASHTYPE); | ||||
} | } | ||||
BOOST_CHECK_EQUAL(CheckTransactionECDSASignatureEncoding( | |||||
undefSighash, flags, &err), | |||||
!(hasStrictEnc || is64)); | |||||
if (is64 || hasStrictEnc) { | |||||
BOOST_CHECK_EQUAL(err, is64 ? SCRIPT_ERR_SIG_BADLENGTH | |||||
: 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), | CheckTransactionSignatureEncoding(invalidSig, flags, &err), | ||||
!hasStrictEnc); | !hasStrictEnc); | ||||
BOOST_CHECK_EQUAL( | |||||
CheckTransactionECDSASignatureEncoding(invalidSig, flags, &err), | |||||
!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); | ||||
} | } | ||||
BOOST_CHECK_EQUAL( | |||||
CheckTransactionECDSASignatureEncoding(invalidSig, flags, &err), | |||||
!(hasStrictEnc || is64)); | |||||
if (is64 || hasStrictEnc) { | |||||
BOOST_CHECK_EQUAL(err, is64 | |||||
? SCRIPT_ERR_SIG_BADLENGTH | |||||
: hasForkId ? SCRIPT_ERR_MUST_USE_FORKID | |||||
: SCRIPT_ERR_ILLEGAL_FORKID); | |||||
} | |||||
} | } | ||||
} | } | ||||
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, | ||||
▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | std::vector<valtype> nonParsableSigs{ | ||||
{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}, | ||||
}; | }; | ||||
valtype Zero64(64, 0); | |||||
MMIXLinearCongruentialGenerator lcg; | MMIXLinearCongruentialGenerator lcg; | ||||
for (int i = 0; i < 4096; i++) { | for (int i = 0; i < 4096; i++) { | ||||
uint32_t flags = lcg.next(); | uint32_t flags = lcg.next(); | ||||
ScriptError err = SCRIPT_ERR_OK; | ScriptError err = SCRIPT_ERR_OK; | ||||
// Empty sig is always valid. | // Empty sig is always validly encoded. | ||||
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)); | ||||
// Signatures are valid as long as the forkid flag is correct. | // 64-byte signatures are valid as long as the hashtype is correct. | ||||
CheckSignatureEncodingWithSigHashType(Zero64, flags); | |||||
// Signatures are valid as long as the hashtype 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(!CheckDataSignatureEncoding(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. | ||||
▲ Show 20 Lines • Show All 178 Lines • ▼ Show 20 Lines | for (int i = 0; i < 4096; i++) { | ||||
: SCRIPT_ERR_NONCOMPRESSED_PUBKEY); | : SCRIPT_ERR_NONCOMPRESSED_PUBKEY); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(checkschnorr_test) { | BOOST_AUTO_TEST_CASE(checkschnorr_test) { | ||||
// tests using 64 byte sigs (+hashtype byte where relevant) | // tests using 64 byte sigs (+hashtype byte where relevant) | ||||
valtype Zero64{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | valtype Zero64(64, 0); | ||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00}; | |||||
valtype DER64{0x30, 0x3e, 0x02, 0x1d, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, | valtype DER64{0x30, 0x3e, 0x02, 0x1d, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, | ||||
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, | 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, | ||||
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, | 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, | ||||
0x44, 0x44, 0x44, 0x02, 0x1d, 0x44, 0x44, 0x44, 0x44, 0x44, | 0x44, 0x44, 0x44, 0x02, 0x1d, 0x44, 0x44, 0x44, 0x44, 0x44, | ||||
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, | 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, | ||||
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, | 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, | ||||
0x44, 0x44, 0x44, 0x44}; | 0x44, 0x44, 0x44, 0x44}; | ||||
Show All 30 Lines |