Page MenuHomePhabricator

D1621.id.diff
No OneTemporary

D1621.id.diff

diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
--- a/src/script/interpreter.cpp
+++ b/src/script/interpreter.cpp
@@ -911,6 +911,62 @@
}
} break;
+ case OP_CHECKDATASIG:
+ case OP_CHECKDATASIGVERIFY: {
+ // Make sure this remains an error before activation.
+ if ((flags & SCRIPT_ENABLE_CHECKDATASIG) == 0) {
+ return set_error(serror, SCRIPT_ERR_BAD_OPCODE);
+ }
+
+ // (sig message pubkey -- bool)
+ if (stack.size() < 3) {
+ return set_error(
+ serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ }
+
+ valtype &vchSig = stacktop(-3);
+ valtype &vchMessage = stacktop(-2);
+ valtype &vchPubKey = stacktop(-1);
+
+ // The size of the message must be 32 bytes.
+ if (vchMessage.size() != 32) {
+ return set_error(serror,
+ SCRIPT_ERR_INVALID_OPERAND_SIZE);
+ }
+
+ if (!CheckDataSignatureEncoding(vchSig, flags,
+ serror) ||
+ !CheckPubKeyEncoding(vchPubKey, flags, serror)) {
+ // serror is set
+ return false;
+ }
+
+ bool fSuccess = false;
+ if (vchSig.size()) {
+ uint256 message(vchMessage);
+ CPubKey pubkey(vchPubKey);
+ fSuccess = pubkey.Verify(message, vchSig);
+ }
+
+ if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) &&
+ vchSig.size()) {
+ return set_error(serror, SCRIPT_ERR_SIG_NULLFAIL);
+ }
+
+ popstack(stack);
+ popstack(stack);
+ popstack(stack);
+ stack.push_back(fSuccess ? vchTrue : vchFalse);
+ if (opcode == OP_CHECKDATASIGVERIFY) {
+ if (fSuccess) {
+ popstack(stack);
+ } else {
+ return set_error(serror,
+ SCRIPT_ERR_CHECKDATASIGVERIFY);
+ }
+ }
+ } break;
+
case OP_CHECKMULTISIG:
case OP_CHECKMULTISIGVERIFY: {
// ([sig ...] num_of_signatures [pubkey ...]
@@ -1045,10 +1101,6 @@
}
} break;
- case OP_CHECKDATASIG:
- case OP_CHECKDATASIGVERIFY:
- return set_error(serror, SCRIPT_ERR_BAD_OPCODE);
-
//
// Byte string operations
//
diff --git a/src/script/script_error.h b/src/script/script_error.h
--- a/src/script/script_error.h
+++ b/src/script/script_error.h
@@ -31,6 +31,7 @@
SCRIPT_ERR_EQUALVERIFY,
SCRIPT_ERR_CHECKMULTISIGVERIFY,
SCRIPT_ERR_CHECKSIGVERIFY,
+ SCRIPT_ERR_CHECKDATASIGVERIFY,
SCRIPT_ERR_NUMEQUALVERIFY,
/* Logical/Format/Canonical errors */
diff --git a/src/script/script_error.cpp b/src/script/script_error.cpp
--- a/src/script/script_error.cpp
+++ b/src/script/script_error.cpp
@@ -20,6 +20,8 @@
return "Script failed an OP_CHECKMULTISIGVERIFY operation";
case SCRIPT_ERR_CHECKSIGVERIFY:
return "Script failed an OP_CHECKSIGVERIFY operation";
+ case SCRIPT_ERR_CHECKDATASIGVERIFY:
+ return "Script failed an OP_CHECKDATASIGVERIFY operation";
case SCRIPT_ERR_NUMEQUALVERIFY:
return "Script failed an OP_NUMEQUALVERIFY operation";
case SCRIPT_ERR_SCRIPT_SIZE:
diff --git a/src/test/checkdatasig_tests.cpp b/src/test/checkdatasig_tests.cpp
--- a/src/test/checkdatasig_tests.cpp
+++ b/src/test/checkdatasig_tests.cpp
@@ -19,36 +19,224 @@
std::array<uint32_t, 3> flagset{
{0, STANDARD_SCRIPT_VERIFY_FLAGS, MANDATORY_SCRIPT_VERIFY_FLAGS}};
+const uint8_t vchPrivkey[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+
+struct KeyData {
+ CKey privkey, privkeyC;
+ CPubKey pubkey, pubkeyC, pubkeyH;
+
+ KeyData() {
+ privkey.Set(vchPrivkey, vchPrivkey + 32, false);
+ privkeyC.Set(vchPrivkey, vchPrivkey + 32, true);
+ pubkey = privkey.GetPubKey();
+ pubkeyH = privkey.GetPubKey();
+ pubkeyC = privkeyC.GetPubKey();
+ *const_cast<uint8_t *>(&pubkeyH[0]) = 0x06 | (pubkeyH[64] & 1);
+ }
+};
+
+static void CheckError(uint32_t flags, const stacktype &original_stack,
+ const CScript &script, ScriptError expected) {
+ BaseSignatureChecker sigchecker;
+ ScriptError err = SCRIPT_ERR_OK;
+ stacktype stack{original_stack};
+ bool r = EvalScript(stack, script, flags, sigchecker, &err);
+ BOOST_CHECK(!r);
+ BOOST_CHECK_EQUAL(err, expected);
+}
+
+static void CheckPass(uint32_t flags, const stacktype &original_stack,
+ const CScript &script, const stacktype &expected) {
+ BaseSignatureChecker sigchecker;
+ ScriptError err = SCRIPT_ERR_OK;
+ stacktype stack{original_stack};
+ bool r = EvalScript(stack, script, flags, sigchecker, &err);
+ BOOST_CHECK(r);
+ BOOST_CHECK_EQUAL(err, SCRIPT_ERR_OK);
+ BOOST_CHECK(stack == expected);
+}
+
/**
* General utility functions to check for script passing/failing.
*/
static void CheckTestResultForAllFlags(const stacktype &original_stack,
const CScript &script,
const stacktype &expected) {
- BaseSignatureChecker sigchecker;
-
for (uint32_t flags : flagset) {
- // The opcode are not implemented yet, so we get a bad opcode error when
- // passing the activation flag.
- ScriptError err = SCRIPT_ERR_OK;
- stacktype stack{original_stack};
- bool r = EvalScript(stack, script, flags | SCRIPT_ENABLE_CHECKDATASIG,
- sigchecker, &err);
- BOOST_CHECK(!r);
- BOOST_CHECK_EQUAL(err, SCRIPT_ERR_BAD_OPCODE);
+ // Make sure that we get a bad opcode when the activation flag is not
+ // passed.
+ CheckError(flags, original_stack, script, SCRIPT_ERR_BAD_OPCODE);
+
+ // The script execute as expected if the opcodes are activated.
+ CheckPass(flags | SCRIPT_ENABLE_CHECKDATASIG, original_stack, script,
+ expected);
+ }
+}
+static void CheckErrorForAllFlags(const stacktype &original_stack,
+ const CScript &script, ScriptError expected) {
+ for (uint32_t flags : flagset) {
// Make sure that we get a bad opcode when the activation flag is not
// passed.
- stack = original_stack;
- r = EvalScript(stack, script, flags, sigchecker, &err);
- BOOST_CHECK(!r);
- BOOST_CHECK_EQUAL(err, SCRIPT_ERR_BAD_OPCODE);
+ CheckError(flags, original_stack, script, SCRIPT_ERR_BAD_OPCODE);
+
+ // The script generates the proper error if the opcodes are activated.
+ CheckError(flags | SCRIPT_ENABLE_CHECKDATASIG, original_stack, script,
+ expected);
}
}
BOOST_AUTO_TEST_CASE(checkdatasig_test) {
- CheckTestResultForAllFlags({}, CScript() << OP_CHECKDATASIG, {});
- CheckTestResultForAllFlags({}, CScript() << OP_CHECKDATASIGVERIFY, {});
+ // Empty stack.
+ CheckErrorForAllFlags({}, CScript() << OP_CHECKDATASIG,
+ SCRIPT_ERR_INVALID_STACK_OPERATION);
+ CheckErrorForAllFlags({{0x00}}, CScript() << OP_CHECKDATASIG,
+ SCRIPT_ERR_INVALID_STACK_OPERATION);
+ CheckErrorForAllFlags({{0x00}, {0x00}}, CScript() << OP_CHECKDATASIG,
+ SCRIPT_ERR_INVALID_STACK_OPERATION);
+ CheckErrorForAllFlags({}, CScript() << OP_CHECKDATASIGVERIFY,
+ SCRIPT_ERR_INVALID_STACK_OPERATION);
+ CheckErrorForAllFlags({{0x00}}, CScript() << OP_CHECKDATASIGVERIFY,
+ SCRIPT_ERR_INVALID_STACK_OPERATION);
+ CheckErrorForAllFlags({{0x00}, {0x00}}, CScript() << OP_CHECKDATASIGVERIFY,
+ SCRIPT_ERR_INVALID_STACK_OPERATION);
+
+ // Check invalid message sizes.
+ for (valtype message; message.size() < 42; message.push_back(0x00)) {
+ if (message.size() == 32) {
+ // 32 is the expected size, skip.
+ continue;
+ }
+
+ CheckErrorForAllFlags({{0x00}, message, {0x00}},
+ CScript() << OP_CHECKDATASIG,
+ SCRIPT_ERR_INVALID_OPERAND_SIZE);
+
+ CheckErrorForAllFlags({{0x00}, message, {0x00}},
+ CScript() << OP_CHECKDATASIGVERIFY,
+ SCRIPT_ERR_INVALID_OPERAND_SIZE);
+ }
+
+ // Check various pubkey encoding.
+ const valtype message(32, 0x00);
+
+ KeyData kd;
+ valtype pubkey = ToByteVector(kd.pubkey);
+ valtype pubkeyC = ToByteVector(kd.pubkeyC);
+ valtype pubkeyH = ToByteVector(kd.pubkeyH);
+
+ CheckTestResultForAllFlags({{}, message, pubkey},
+ CScript() << OP_CHECKDATASIG, {{}});
+ CheckTestResultForAllFlags({{}, message, pubkeyC},
+ CScript() << OP_CHECKDATASIG, {{}});
+ CheckErrorForAllFlags({{}, message, pubkey},
+ CScript() << OP_CHECKDATASIGVERIFY,
+ SCRIPT_ERR_CHECKDATASIGVERIFY);
+ CheckErrorForAllFlags({{}, message, pubkeyC},
+ CScript() << OP_CHECKDATASIGVERIFY,
+ SCRIPT_ERR_CHECKDATASIGVERIFY);
+
+ // Flags dependent checks.
+ const CScript script = CScript() << OP_CHECKDATASIG << OP_NOT << OP_VERIFY;
+ const CScript scriptverify = CScript() << OP_CHECKDATASIGVERIFY;
+
+ // Check valid signatures.
+ const uint256 one(uint256S(
+ "0000000000000000000000000000000000000000000000000000000000000001"));
+ const uint256 two(uint256S(
+ "0000000000000000000000000000000000000000000000000000000000000002"));
+
+ valtype validsig;
+ kd.privkey.Sign(one, validsig);
+
+ CheckTestResultForAllFlags({validsig, ToByteVector(one), pubkey},
+ CScript() << OP_CHECKDATASIG, {{0x01}});
+ CheckTestResultForAllFlags({validsig, ToByteVector(one), pubkey},
+ CScript() << OP_CHECKDATASIGVERIFY, {});
+
+ const valtype minimalsig{0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01};
+ const valtype nondersig{0x30, 0x80, 0x06, 0x02, 0x01,
+ 0x01, 0x02, 0x01, 0x01};
+ const valtype highSSig{
+ 0x30, 0x45, 0x02, 0x20, 0x3e, 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, 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};
+
+ // 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.
+ for (uint32_t flags = 0; flags < (1U << 17); flags++) {
+ // Make sure we activate the opcodes.
+ flags |= SCRIPT_ENABLE_CHECKDATASIG;
+
+ if (flags & SCRIPT_VERIFY_STRICTENC) {
+ // When strict encoding is enforced, hybrid key are invalid.
+ CheckError(flags, {{}, message, pubkeyH}, script,
+ SCRIPT_ERR_PUBKEYTYPE);
+ CheckError(flags, {{}, message, pubkeyH}, scriptverify,
+ SCRIPT_ERR_PUBKEYTYPE);
+ } else {
+ // When strict encoding is not enforced, hybrid key are valid.
+ CheckPass(flags, {{}, message, pubkeyH}, script, {});
+ CheckError(flags, {{}, message, pubkeyH}, scriptverify,
+ SCRIPT_ERR_CHECKDATASIGVERIFY);
+ }
+
+ if (flags & SCRIPT_VERIFY_NULLFAIL) {
+ // When strict encoding is enforced, hybrid key are invalid.
+ CheckError(flags, {minimalsig, message, pubkey}, script,
+ SCRIPT_ERR_SIG_NULLFAIL);
+ CheckError(flags, {minimalsig, message, pubkey}, scriptverify,
+ SCRIPT_ERR_SIG_NULLFAIL);
+
+ // Invalid message cause checkdatasig to fail.
+ CheckError(flags, {validsig, ToByteVector(two), pubkey}, script,
+ SCRIPT_ERR_SIG_NULLFAIL);
+ CheckError(flags, {validsig, ToByteVector(two), pubkey},
+ scriptverify, SCRIPT_ERR_SIG_NULLFAIL);
+ } else {
+ // When nullfail is not enforced, invalid signature are just false.
+ CheckPass(flags, {minimalsig, message, pubkey}, script, {});
+ CheckError(flags, {minimalsig, message, pubkey}, scriptverify,
+ SCRIPT_ERR_CHECKDATASIGVERIFY);
+
+ // Invalid message cause checkdatasig to fail.
+ CheckPass(flags, {validsig, ToByteVector(two), pubkey}, script, {});
+ CheckError(flags, {validsig, ToByteVector(two), pubkey},
+ scriptverify, SCRIPT_ERR_CHECKDATASIGVERIFY);
+ }
+
+ if (flags & SCRIPT_VERIFY_LOW_S) {
+ // If we do enforce low S, then high S sigs are rejected.
+ CheckError(flags, {highSSig, message, pubkey}, script,
+ SCRIPT_ERR_SIG_HIGH_S);
+ CheckError(flags, {highSSig, message, pubkey}, scriptverify,
+ SCRIPT_ERR_SIG_HIGH_S);
+ } else {
+ // If we do not enforce low S, then high S sigs are accepted.
+ CheckPass(flags, {highSSig, message, pubkey}, script, {});
+ CheckError(flags, {highSSig, message, pubkey}, scriptverify,
+ SCRIPT_ERR_CHECKDATASIGVERIFY);
+ }
+
+ 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.
+ CheckError(flags, {nondersig, message, pubkey}, script,
+ SCRIPT_ERR_SIG_DER);
+ CheckError(flags, {nondersig, message, pubkey}, scriptverify,
+ SCRIPT_ERR_SIG_DER);
+ } else {
+ // If we do not check, then it is accepted.
+ CheckPass(flags, {nondersig, message, pubkey}, script, {});
+ CheckError(flags, {nondersig, message, pubkey}, scriptverify,
+ SCRIPT_ERR_CHECKDATASIGVERIFY);
+ }
+ }
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json
--- a/src/test/data/script_tests.json
+++ b/src/test/data/script_tests.json
@@ -1036,6 +1036,115 @@
["1 1 ADD", "0 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"],
["11 1 ADD 12 SUB", "11 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"],
+["CHECKDATASIG"],
+["", "CHECKDATASIG", "P2SH,STRICTENC,NULLFAIL,CHECKDATASIG", "INVALID_STACK_OPERATION"],
+["0", "CHECKDATASIG", "P2SH,STRICTENC,NULLFAIL,CHECKDATASIG", "INVALID_STACK_OPERATION"],
+["0 0", "CHECKDATASIG", "P2SH,STRICTENC,NULLFAIL,CHECKDATASIG", "INVALID_STACK_OPERATION"],
+["0 0 0", "CHECKDATASIG", "P2SH,STRICTENC,NULLFAIL,CHECKDATASIG", "OPERAND_SIZE"],
+[
+ "0 0x21 0x000000000000000000000000000000000000000000000000000000000000000001",
+ "0 CHECKDATASIG",
+ "P2SH,STRICTENC,NULLFAIL,CHECKDATASIG",
+ "OPERAND_SIZE"
+],
+[
+ "0 0x1f 0x00000000000000000000000000000000000000000000000000000000000001",
+ "0 CHECKDATASIG",
+ "P2SH,STRICTENC,NULLFAIL,CHECKDATASIG",
+ "OPERAND_SIZE"
+],
+[
+ "0 0x20 0x0000000000000000000000000000000000000000000000000000000000000001",
+ "0 CHECKDATASIG",
+ "P2SH,STRICTENC,NULLFAIL,CHECKDATASIG",
+ "PUBKEYTYPE"
+],
+[
+ "0 0x20 0x0000000000000000000000000000000000000000000000000000000000000001",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIG",
+ "P2SH,STRICTENC,NULLFAIL,CHECKDATASIG",
+ "EVAL_FALSE"
+],
+[
+ "0x08 0x3006020101020101 0x20 0x0000000000000000000000000000000000000000000000000000000000000001",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIG",
+ "P2SH,STRICTENC,CHECKDATASIG",
+ "EVAL_FALSE", "Check that NULLFAIL trigger only when specified"
+],
+[
+ "0x08 0x3006020101020101 0x20 0x0000000000000000000000000000000000000000000000000000000000000001",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIG",
+ "P2SH,STRICTENC,NULLFAIL,CHECKDATASIG",
+ "NULLFAIL"
+],
+[
+ "0x09 0x300602010102010101 0x20 0x0000000000000000000000000000000000000000000000000000000000000001",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIG",
+ "P2SH,STRICTENC,NULLFAIL,CHECKDATASIG",
+ "SIG_DER", "Ensure that sighashtype is ignored"
+],
+[
+ "0x09 0x300702010102020001 0x20 0x0000000000000000000000000000000000000000000000000000000000000001",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIG",
+ "P2SH,STRICTENC,NULLFAIL,CHECKDATASIG",
+ "SIG_DER", "Non cannonical DER encoding"
+],
+
+["CHECKDATASIGVERIFY"],
+["", "CHECKDATASIGVERIFY 1", "P2SH,STRICTENC,CHECKDATASIG", "INVALID_STACK_OPERATION"],
+["0", "CHECKDATASIGVERIFY 1", "P2SH,STRICTENC,NULLFAIL,CHECKDATASIG", "INVALID_STACK_OPERATION"],
+["0 0", "CHECKDATASIGVERIFY 1", "P2SH,STRICTENC,NULLFAIL,CHECKDATASIG", "INVALID_STACK_OPERATION"],
+["0 0 0", "CHECKDATASIGVERIFY 1", "P2SH,STRICTENC,NULLFAIL,CHECKDATASIG", "OPERAND_SIZE"],
+[
+ "0 0x21 0x000000000000000000000000000000000000000000000000000000000000000001",
+ "0 CHECKDATASIGVERIFY 1",
+ "P2SH,STRICTENC,NULLFAIL,CHECKDATASIG",
+ "OPERAND_SIZE"
+],
+[
+ "0 0x1f 0x00000000000000000000000000000000000000000000000000000000000001",
+ "0 CHECKDATASIGVERIFY 1",
+ "P2SH,STRICTENC,NULLFAIL,CHECKDATASIG",
+ "OPERAND_SIZE"
+],
+[
+ "0 0x20 0x0000000000000000000000000000000000000000000000000000000000000001",
+ "0 CHECKDATASIGVERIFY 1",
+ "P2SH,STRICTENC,NULLFAIL,CHECKDATASIG",
+ "PUBKEYTYPE"
+],
+[
+ "0 0x20 0x0000000000000000000000000000000000000000000000000000000000000001",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIGVERIFY 1",
+ "P2SH,STRICTENC,NULLFAIL,CHECKDATASIG",
+ "CHECKDATASIGVERIFY"
+],
+[
+ "0x08 0x3006020101020101 0x20 0x0000000000000000000000000000000000000000000000000000000000000001",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIGVERIFY 1",
+ "P2SH,STRICTENC,CHECKDATASIG",
+ "CHECKDATASIGVERIFY", "Check that NULLFAIL trigger only when specified"
+],
+[
+ "0x08 0x3006020101020101 0x20 0x0000000000000000000000000000000000000000000000000000000000000001",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIGVERIFY 1",
+ "P2SH,STRICTENC,NULLFAIL,CHECKDATASIG",
+ "NULLFAIL"
+],
+[
+ "0x09 0x300602010102010101 0x20 0x0000000000000000000000000000000000000000000000000000000000000001",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIGVERIFY 1",
+ "P2SH,STRICTENC,NULLFAIL,CHECKDATASIG",
+ "SIG_DER", "Ensure that sighashtype is ignored"
+],
+[
+ "0x09 0x300702010102020001 0x20 0x0000000000000000000000000000000000000000000000000000000000000001",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIGVERIFY 1",
+ "P2SH,STRICTENC,NULLFAIL,CHECKDATASIG",
+ "SIG_DER", "Non cannonical DER encoding"
+],
+
+["ADD"],
["2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "UNKNOWN_ERROR", "arithmetic operands must be in range [-2^31...2^31] "],
["-2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "UNKNOWN_ERROR", "arithmetic operands must be in range [-2^31...2^31] "],
["2147483647 DUP ADD", "4294967294 NUMEQUAL", "P2SH,STRICTENC", "UNKNOWN_ERROR", "NUMEQUAL must be in numeric range"],
@@ -1069,9 +1178,7 @@
["0x50","1", "P2SH,STRICTENC", "BAD_OPCODE", "opcode 0x50 is reserved"],
["1", "IF CHECKDATASIG ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"],
-["1", "IF CHECKDATASIG ELSE 1 ENDIF", "P2SH,STRICTENC,CHECKDATASIG", "BAD_OPCODE"],
["1", "IF CHECKDATASIGVERIFY ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"],
-["1", "IF CHECKDATASIGVERIFY ELSE 1 ENDIF", "P2SH,STRICTENC,CHECKDATASIG", "BAD_OPCODE"],
["1", "IF 0xbc ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE", "opcodes >= FIRST_UNDEFINED_OP_VALUE invalid if executed"],
["1", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"],
["1", "IF 0xbe ELSE 1 ENDIF", "P2SH,STRICTENC", "BAD_OPCODE"],
@@ -2119,6 +2226,174 @@
"EVAL_FALSE",
"P2PK REPLAY PROTECTED"
],
+[
+ "0x46 0x30440220052a549456efe256a8c190650648e7ebdd46161f330830733fc7c674aeb7d3da0220519999b4f25b37de557a9c909cb5b155d1f0b11293b0890236696bfa0bd310e1 0x20 0x0100000000000000000000000000000000000000000000000000000000000000",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIG",
+ "CHECKDATASIG,NULLFAIL,STRICTENC",
+ "OK",
+ "Standard CHECKDATASIG"
+],
+[
+ "0x46 0x30440220052a549456efe256a8c190650648e7ebdd46161f330830733fc7c674aeb7d3da0220519999b4f25b37de557a9c909cb5b155d1f0b11293b0890236696bfa0bd310e1 0x20 0x0200000000000000000000000000000000000000000000000000000000000000",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIG NOT",
+ "CHECKDATASIG,NULLFAIL,STRICTENC",
+ "NULLFAIL",
+ "CHECKDATASIG with NULLFAIL flags"
+],
+[
+ "0x46 0x30440220052a549456efe256a8c190650648e7ebdd46161f330830733fc7c674aeb7d3da0220519999b4f25b37de557a9c909cb5b155d1f0b11293b0890236696bfa0bd310e1 0x20 0x0200000000000000000000000000000000000000000000000000000000000000",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIG NOT",
+ "CHECKDATASIG,STRICTENC",
+ "OK",
+ "CHECKDATASIG without NULLFAIL flags"
+],
+[
+ "0 0x20 0x0100000000000000000000000000000000000000000000000000000000000000",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIG NOT",
+ "CHECKDATASIG,NULLFAIL,STRICTENC",
+ "OK",
+ "CHECKDATASIG empty signature"
+],
+[
+ "0x47 0x30450220052a549456efe256a8c190650648e7ebdd46161f330830733fc7c674aeb7d3da022100ae66664b0da4c821aa85636f634a4ea8e8be2bd41b9817398968f292c4633060 0x20 0x0100000000000000000000000000000000000000000000000000000000000000",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIG",
+ "CHECKDATASIG,NULLFAIL,STRICTENC",
+ "OK",
+ "CHECKDATASIG with High S but no Low S"
+],
+[
+ "0x47 0x30450220052a549456efe256a8c190650648e7ebdd46161f330830733fc7c674aeb7d3da022100ae66664b0da4c821aa85636f634a4ea8e8be2bd41b9817398968f292c4633060 0x20 0x0100000000000000000000000000000000000000000000000000000000000000",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIG",
+ "CHECKDATASIG,LOW_S,NULLFAIL,STRICTENC",
+ "SIG_HIGH_S",
+ "CHECKDATASIG with High S"
+],
+[
+ "0x46 0x30440220e54f8b4dc9b45e1e76207fd0062f3f8b09381e6131d9be3781d2a791fe889c96022038ff0a5f76c1b972149700568ea98b2932e163b5debc78814fc7f1b89f7bcf02 0x20 0x0100000000000000000000000000000000000000000000000000000000000000",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIG",
+ "CHECKDATASIG,NULLFAIL",
+ "OK",
+ "CHECKDATASIG with too little R padding but no DERSIG"
+],
+[
+ "0x46 0x30440220e54f8b4dc9b45e1e76207fd0062f3f8b09381e6131d9be3781d2a791fe889c96022038ff0a5f76c1b972149700568ea98b2932e163b5debc78814fc7f1b89f7bcf02 0x20 0x0100000000000000000000000000000000000000000000000000000000000000",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIG",
+ "CHECKDATASIG,NULLFAIL,STRICTENC",
+ "SIG_DER",
+ "CHECKDATASIG with too little R padding"
+],
+[
+ "0x46 0x304402201f9ab6bce51855179000754f239bcdc91682e556275514ec72a6b429b8972da2022076ba6228144dbaaeffb5e58ead6281a56bd4e3ae05f0890d1bbb5dad8f61b1ac 0x20 0x0100000000000000000000000000000000000000000000000000000000000000",
+ "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKDATASIG",
+ "CHECKDATASIG,NULLFAIL",
+ "OK",
+ "CHECKDATASIG with hybrid pubkey but no STRICTENC"
+],
+[
+ "0x46 0x304402201f9ab6bce51855179000754f239bcdc91682e556275514ec72a6b429b8972da2022076ba6228144dbaaeffb5e58ead6281a56bd4e3ae05f0890d1bbb5dad8f61b1ac 0x20 0x0100000000000000000000000000000000000000000000000000000000000000",
+ "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKDATASIG",
+ "CHECKDATASIG,NULLFAIL,STRICTENC",
+ "PUBKEYTYPE",
+ "CHECKDATASIG with hybrid pubkey"
+],
+[
+ "0x46 0x304402201f9ab6bce51854179000754f239bcdc91682e556275514ec72a6b429b8972da2022076ba6228144dbaaeffb5e58ead6281a56bd4e3ae05f0890d1bbb5dad8f61b1ac 0x20 0x0100000000000000000000000000000000000000000000000000000000000000",
+ "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKDATASIG NOT",
+ "CHECKDATASIG",
+ "OK",
+ "CHECKDATASIG with invalid hybrid pubkey but no STRICTENC"
+],
+[
+ "0x46 0x304402201f9ab6bce51854179000754f239bcdc91682e556275514ec72a6b429b8972da2022076ba6228144dbaaeffb5e58ead6281a56bd4e3ae05f0890d1bbb5dad8f61b1ac 0x20 0x0100000000000000000000000000000000000000000000000000000000000000",
+ "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKDATASIG",
+ "CHECKDATASIG,NULLFAIL,STRICTENC",
+ "PUBKEYTYPE",
+ "CHECKDATASIG with invalid hybrid pubkey"
+],
+[
+ "0x46 0x30440220052a549456efe256a8c190650648e7ebdd46161f330830733fc7c674aeb7d3da0220519999b4f25b37de557a9c909cb5b155d1f0b11293b0890236696bfa0bd310e1 0x20 0x0100000000000000000000000000000000000000000000000000000000000000",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIGVERIFY 1",
+ "CHECKDATASIG,NULLFAIL,STRICTENC",
+ "OK",
+ "Standard CHECKDATASIGVERIFY"
+],
+[
+ "0x46 0x30440220052a549456efe256a8c190650648e7ebdd46161f330830733fc7c674aeb7d3da0220519999b4f25b37de557a9c909cb5b155d1f0b11293b0890236696bfa0bd310e1 0x20 0x0200000000000000000000000000000000000000000000000000000000000000",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIGVERIFY 1",
+ "CHECKDATASIG,NULLFAIL,STRICTENC",
+ "NULLFAIL",
+ "CHECKDATASIGVERIFY with NULLFAIL flags"
+],
+[
+ "0x46 0x30440220052a549456efe256a8c190650648e7ebdd46161f330830733fc7c674aeb7d3da0220519999b4f25b37de557a9c909cb5b155d1f0b11293b0890236696bfa0bd310e1 0x20 0x0200000000000000000000000000000000000000000000000000000000000000",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIGVERIFY 1",
+ "CHECKDATASIG,STRICTENC",
+ "CHECKDATASIGVERIFY",
+ "CHECKDATASIGVERIFY without NULLFAIL flags"
+],
+[
+ "0 0x20 0x0100000000000000000000000000000000000000000000000000000000000000",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIGVERIFY 1",
+ "CHECKDATASIG,NULLFAIL,STRICTENC",
+ "CHECKDATASIGVERIFY",
+ "CHECKDATASIGVERIFY empty signature"
+],
+[
+ "0x47 0x30450220052a549456efe256a8c190650648e7ebdd46161f330830733fc7c674aeb7d3da022100ae66664b0da4c821aa85636f634a4ea8e8be2bd41b9817398968f292c4633060 0x20 0x0100000000000000000000000000000000000000000000000000000000000000",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIGVERIFY 1",
+ "CHECKDATASIG,NULLFAIL,STRICTENC",
+ "OK",
+ "CHECKDATASIG with High S but no Low S"
+],
+[
+ "0x47 0x30450220052a549456efe256a8c190650648e7ebdd46161f330830733fc7c674aeb7d3da022100ae66664b0da4c821aa85636f634a4ea8e8be2bd41b9817398968f292c4633060 0x20 0x0100000000000000000000000000000000000000000000000000000000000000",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIGVERIFY 1",
+ "CHECKDATASIG,LOW_S,NULLFAIL,STRICTENC",
+ "SIG_HIGH_S",
+ "CHECKDATASIG with High S"
+],
+[
+ "0x46 0x30440220e54f8b4dc9b45e1e76207fd0062f3f8b09381e6131d9be3781d2a791fe889c96022038ff0a5f76c1b972149700568ea98b2932e163b5debc78814fc7f1b89f7bcf02 0x20 0x0100000000000000000000000000000000000000000000000000000000000000",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIGVERIFY 1",
+ "CHECKDATASIG,NULLFAIL",
+ "OK",
+ "CHECKDATASIGVERIFY with too little R padding but no DERSIG"
+],
+[
+ "0x46 0x30440220e54f8b4dc9b45e1e76207fd0062f3f8b09381e6131d9be3781d2a791fe889c96022038ff0a5f76c1b972149700568ea98b2932e163b5debc78814fc7f1b89f7bcf02 0x20 0x0100000000000000000000000000000000000000000000000000000000000000",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKDATASIGVERIFY 1",
+ "CHECKDATASIG,NULLFAIL,STRICTENC",
+ "SIG_DER",
+ "CHECKDATASIGVERIFY with too little R padding"
+],
+[
+ "0x46 0x304402201f9ab6bce51855179000754f239bcdc91682e556275514ec72a6b429b8972da2022076ba6228144dbaaeffb5e58ead6281a56bd4e3ae05f0890d1bbb5dad8f61b1ac 0x20 0x0100000000000000000000000000000000000000000000000000000000000000",
+ "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKDATASIGVERIFY 1",
+ "CHECKDATASIG,NULLFAIL",
+ "OK",
+ "CHECKDATASIGVERIFY with hybrid pubkey but no STRICTENC"
+],
+[
+ "0x46 0x304402201f9ab6bce51855179000754f239bcdc91682e556275514ec72a6b429b8972da2022076ba6228144dbaaeffb5e58ead6281a56bd4e3ae05f0890d1bbb5dad8f61b1ac 0x20 0x0100000000000000000000000000000000000000000000000000000000000000",
+ "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKDATASIGVERIFY 1",
+ "CHECKDATASIG,NULLFAIL,STRICTENC",
+ "PUBKEYTYPE",
+ "CHECKDATASIGVERIFY with hybrid pubkey"
+],
+[
+ "0x46 0x304402201f9ab6bce51854179000754f239bcdc91682e556275514ec72a6b429b8972da2022076ba6228144dbaaeffb5e58ead6281a56bd4e3ae05f0890d1bbb5dad8f61b1ac 0x20 0x0100000000000000000000000000000000000000000000000000000000000000",
+ "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKDATASIGVERIFY 1",
+ "CHECKDATASIG",
+ "CHECKDATASIGVERIFY",
+ "CHECKDATASIGVERIFY with invalid hybrid pubkey but no STRICTENC"
+],
+[
+ "0x46 0x304402201f9ab6bce51854179000754f239bcdc91682e556275514ec72a6b429b8972da2022076ba6228144dbaaeffb5e58ead6281a56bd4e3ae05f0890d1bbb5dad8f61b1ac 0x20 0x0100000000000000000000000000000000000000000000000000000000000000",
+ "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKDATASIGVERIFY 1",
+ "CHECKDATASIG,NULLFAIL,STRICTENC",
+ "PUBKEYTYPE",
+ "CHECKDATASIGVERIFY with invalid hybrid pubkey"
+],
["CHECKSEQUENCEVERIFY tests"],
["", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "INVALID_STACK_OPERATION", "CSV automatically fails on a empty stack"],
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -61,6 +61,7 @@
{SCRIPT_ERR_EQUALVERIFY, "EQUALVERIFY"},
{SCRIPT_ERR_CHECKMULTISIGVERIFY, "CHECKMULTISIGVERIFY"},
{SCRIPT_ERR_CHECKSIGVERIFY, "CHECKSIGVERIFY"},
+ {SCRIPT_ERR_CHECKDATASIGVERIFY, "CHECKDATASIGVERIFY"},
{SCRIPT_ERR_NUMEQUALVERIFY, "NUMEQUALVERIFY"},
{SCRIPT_ERR_BAD_OPCODE, "BAD_OPCODE"},
{SCRIPT_ERR_DISABLED_OPCODE, "DISABLED_OPCODE"},
@@ -318,6 +319,11 @@
return *this;
}
+ TestBuilder &Push(const uint256 &hash) {
+ DoPush(ToByteVector(hash));
+ return *this;
+ }
+
TestBuilder &Push(const CScript &_script) {
DoPush(std::vector<uint8_t>(_script.begin(), _script.end()));
return *this;
@@ -336,6 +342,12 @@
return *this;
}
+ TestBuilder &PushDataSig(const CKey &key, const uint256 &hash,
+ unsigned int lenR = 32, unsigned int lenS = 32) {
+ DoPush(DoSign(key, hash, lenR, lenS));
+ return *this;
+ }
+
TestBuilder &Push(const CPubKey &pubkey) {
DoPush(std::vector<uint8_t>(pubkey.begin(), pubkey.end()));
return *this;
@@ -1114,6 +1126,185 @@
SCRIPT_ENABLE_SIGHASH_FORKID)
.ScriptError(SCRIPT_ERR_EVAL_FALSE));
+ // Test OP_CHECKDATASIG
+ static const uint256 one(uint256S(
+ "0000000000000000000000000000000000000000000000000000000000000001"));
+ static const uint256 two(uint256S(
+ "0000000000000000000000000000000000000000000000000000000000000002"));
+ const uint32_t checkdatasigflags = SCRIPT_VERIFY_STRICTENC |
+ SCRIPT_VERIFY_NULLFAIL |
+ SCRIPT_ENABLE_CHECKDATASIG;
+
+ tests.push_back(
+ TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKDATASIG,
+ "Standard CHECKDATASIG", checkdatasigflags)
+ .PushDataSig(keys.key1, one)
+ .Push(one));
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C)
+ << OP_CHECKDATASIG << OP_NOT,
+ "CHECKDATASIG with NULLFAIL flags",
+ checkdatasigflags)
+ .PushDataSig(keys.key1, one)
+ .Push(two)
+ .ScriptError(SCRIPT_ERR_SIG_NULLFAIL));
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C)
+ << OP_CHECKDATASIG << OP_NOT,
+ "CHECKDATASIG without NULLFAIL flags",
+ checkdatasigflags & ~SCRIPT_VERIFY_NULLFAIL)
+ .PushDataSig(keys.key1, one)
+ .Push(two));
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C)
+ << OP_CHECKDATASIG << OP_NOT,
+ "CHECKDATASIG empty signature",
+ checkdatasigflags)
+ .Num(0)
+ .Push(one));
+ tests.push_back(
+ TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKDATASIG,
+ "CHECKDATASIG with High S but no Low S", checkdatasigflags)
+ .PushDataSig(keys.key1, one, 32, 33)
+ .Push(one));
+ tests.push_back(
+ TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKDATASIG,
+ "CHECKDATASIG with High S",
+ checkdatasigflags | SCRIPT_VERIFY_LOW_S)
+ .PushDataSig(keys.key1, one, 32, 33)
+ .Push(one)
+ .ScriptError(SCRIPT_ERR_SIG_HIGH_S));
+ tests.push_back(
+ TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKDATASIG,
+ "CHECKDATASIG with too little R padding but no DERSIG",
+ checkdatasigflags & ~SCRIPT_VERIFY_STRICTENC)
+ .PushDataSig(keys.key1, one, 33, 32)
+ .EditPush(1, "45022100", "440220")
+ .Push(one));
+ tests.push_back(
+ TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKDATASIG,
+ "CHECKDATASIG with too little R padding", checkdatasigflags)
+ .PushDataSig(keys.key1, one, 33, 32)
+ .EditPush(1, "45022100", "440220")
+ .Push(one)
+ .ScriptError(SCRIPT_ERR_SIG_DER));
+ tests.push_back(
+ TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKDATASIG,
+ "CHECKDATASIG with hybrid pubkey but no STRICTENC",
+ checkdatasigflags & ~SCRIPT_VERIFY_STRICTENC)
+ .PushDataSig(keys.key0, one)
+ .Push(one));
+ tests.push_back(
+ TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKDATASIG,
+ "CHECKDATASIG with hybrid pubkey", checkdatasigflags)
+ .PushDataSig(keys.key0, one)
+ .Push(one)
+ .ScriptError(SCRIPT_ERR_PUBKEYTYPE));
+ tests.push_back(
+ TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKDATASIG
+ << OP_NOT,
+ "CHECKDATASIG with invalid hybrid pubkey but no STRICTENC",
+ SCRIPT_ENABLE_CHECKDATASIG)
+ .PushDataSig(keys.key0, one)
+ .DamagePush(10)
+ .Push(one));
+ tests.push_back(
+ TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKDATASIG,
+ "CHECKDATASIG with invalid hybrid pubkey",
+ checkdatasigflags)
+ .PushDataSig(keys.key0, one)
+ .DamagePush(10)
+ .Push(one)
+ .ScriptError(SCRIPT_ERR_PUBKEYTYPE));
+
+ // Test OP_CHECKDATASIGVERIFY
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C)
+ << OP_CHECKDATASIGVERIFY << OP_TRUE,
+ "Standard CHECKDATASIGVERIFY",
+ checkdatasigflags)
+ .PushDataSig(keys.key1, one)
+ .Push(one));
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C)
+ << OP_CHECKDATASIGVERIFY << OP_TRUE,
+ "CHECKDATASIGVERIFY with NULLFAIL flags",
+ checkdatasigflags)
+ .PushDataSig(keys.key1, one)
+ .Push(two)
+ .ScriptError(SCRIPT_ERR_SIG_NULLFAIL));
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C)
+ << OP_CHECKDATASIGVERIFY << OP_TRUE,
+ "CHECKDATASIGVERIFY without NULLFAIL flags",
+ checkdatasigflags & ~SCRIPT_VERIFY_NULLFAIL)
+ .PushDataSig(keys.key1, one)
+ .Push(two)
+ .ScriptError(SCRIPT_ERR_CHECKDATASIGVERIFY));
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C)
+ << OP_CHECKDATASIGVERIFY << OP_TRUE,
+ "CHECKDATASIGVERIFY empty signature",
+ checkdatasigflags)
+ .Num(0)
+ .Push(one)
+ .ScriptError(SCRIPT_ERR_CHECKDATASIGVERIFY));
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C)
+ << OP_CHECKDATASIGVERIFY << OP_TRUE,
+ "CHECKDATASIG with High S but no Low S",
+ checkdatasigflags)
+ .PushDataSig(keys.key1, one, 32, 33)
+ .Push(one));
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C)
+ << OP_CHECKDATASIGVERIFY << OP_TRUE,
+ "CHECKDATASIG with High S",
+ checkdatasigflags | SCRIPT_VERIFY_LOW_S)
+ .PushDataSig(keys.key1, one, 32, 33)
+ .Push(one)
+ .ScriptError(SCRIPT_ERR_SIG_HIGH_S));
+ tests.push_back(
+ TestBuilder(
+ CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKDATASIGVERIFY
+ << OP_TRUE,
+ "CHECKDATASIGVERIFY with too little R padding but no DERSIG",
+ checkdatasigflags & ~SCRIPT_VERIFY_STRICTENC)
+ .PushDataSig(keys.key1, one, 33, 32)
+ .EditPush(1, "45022100", "440220")
+ .Push(one));
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C)
+ << OP_CHECKDATASIGVERIFY << OP_TRUE,
+ "CHECKDATASIGVERIFY with too little R padding",
+ checkdatasigflags)
+ .PushDataSig(keys.key1, one, 33, 32)
+ .EditPush(1, "45022100", "440220")
+ .Push(one)
+ .ScriptError(SCRIPT_ERR_SIG_DER));
+ tests.push_back(
+ TestBuilder(CScript() << ToByteVector(keys.pubkey0H)
+ << OP_CHECKDATASIGVERIFY << OP_TRUE,
+ "CHECKDATASIGVERIFY with hybrid pubkey but no STRICTENC",
+ checkdatasigflags & ~SCRIPT_VERIFY_STRICTENC)
+ .PushDataSig(keys.key0, one)
+ .Push(one));
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H)
+ << OP_CHECKDATASIGVERIFY << OP_TRUE,
+ "CHECKDATASIGVERIFY with hybrid pubkey",
+ checkdatasigflags)
+ .PushDataSig(keys.key0, one)
+ .Push(one)
+ .ScriptError(SCRIPT_ERR_PUBKEYTYPE));
+ tests.push_back(
+ TestBuilder(
+ CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKDATASIGVERIFY
+ << OP_TRUE,
+ "CHECKDATASIGVERIFY with invalid hybrid pubkey but no STRICTENC",
+ SCRIPT_ENABLE_CHECKDATASIG)
+ .PushDataSig(keys.key0, one)
+ .DamagePush(10)
+ .Push(one)
+ .ScriptError(SCRIPT_ERR_CHECKDATASIGVERIFY));
+ tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H)
+ << OP_CHECKDATASIGVERIFY << OP_TRUE,
+ "CHECKDATASIGVERIFY with invalid hybrid pubkey",
+ checkdatasigflags)
+ .PushDataSig(keys.key0, one)
+ .DamagePush(10)
+ .Push(one)
+ .ScriptError(SCRIPT_ERR_PUBKEYTYPE));
+
std::set<std::string> tests_set;
{

File Metadata

Mime Type
text/plain
Expires
Tue, May 20, 21:41 (10 h, 25 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5865991
Default Alt Text
D1621.id.diff (42 KB)

Event Timeline