Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14864702
D1621.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
42 KB
Subscribers
None
D1621.id.diff
View Options
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
Details
Attached
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)
Attached To
D1621: Implement OP_CHECKDATASIG and OP_CHECKDATASIGVERIFY
Event Timeline
Log In to Comment