OP_CHECKDATASIG and OP_CHECKDATASIGVERIFY check whether a signature is valid with respect to a message and and a public key. The message is restricted to exactly 256 bits, if longer messages are to be signed, it is recommended to sign it's hash.
This permits data to be imported into a script, and have its validity checked against some signing authority such as an "Oracle".
OP_CHECKDATASIG and OP_CHECKDATASIGVERIFY are designed to be implemented similarly to OP_CHECKSIG [1]. Conceptually, one could imagine OP_CHECKSIG functionality being replaced by OP_CHECKDATASIG, along with a separate Op Code to create a hash from the transaction based on the SigHash algorithm.
OP_CHECKDATASIG fails immediately if the stack is not well formed. To be well formed, the stack must
- contain at least three elements [
<msg>
,<pubKey>
,<sig>
] in this order where<msg>
is the top element and <msg>
must be a string of exactly 256 bits<pubKey>
must be a ... encoded public key<sig>
must be a DER encoded signature that- is in strict DER encoding as described in [2]
- the S-value of
<sig>
is at most the curve oder divided by 2 as described in [3]
If the stack is well formed, then OP_CHECKDATASIG pops the top three elements [<msg>
, <pubKey>
, <sig>
] from the stack and pushes true onto the stack if the signature is valid with respect to the message and the public key using the secp256k1 elliptic curve. Otherwise it pops three elements and pushes false onto the stack.
OP_CHECKDATASIGVERIFY uses the currently unused opcode number 186 (0xba in hex encoding)
Signature operations accounting for OP_CHECKDATASIG shall be calculated the same as OP_CHECKSIG. This means that each OP_CHECKDATASIG shall be counted as one SigOp.
<sig> <pubKey> <msg> OP_CHECKDATASIG
fails if 15 November 2018 protocol upgrade is not yet activated.<sig> <pubKey> OP_CHECKDATASIG
fails if fewer than 3 item on stack causes script failure<sig> <pubKey> <msg> OP_CHECKDATASIG
fails if<msg>
is not a string of 256 bits<sig> <pubKey> <msg> OP_CHECKDATASIG
fails if<pubKey>
is not a validly encoded public key (todo: more details about encoding).<sig> <pubKey> <msg> OP_CHECKDATASIG
fails if<sig>
is not a validly encoded signature with strict DER encoding.<sig> <pubKey> <msg> OP_CHECKDATASIG
fails if signature<sig>
does not pass the Low S check and is a non empty byte array.<sig> <pubKey> <msg> OP_CHECKDATASIG
fails if<sig>
is not an empty byte array, and does not pass signature validation of<msg>
and<pubKey>
(question: I would have expected that this case returns false instead of failing)<sig> <pubKey> <msg> OP_CHECKDATASIG
pops three elements and pushes false onto the stack if<sig>
is an empty byte array.<sig> <pubKey> <msg> OP_CHECKDATASIG
pops three elements and pushes true onto the stack if<sig>
is a valid signature of<msg>
and<pubKey>
.<sig> <pubKey> <msg> OP_CHECKDATASIG
pops three elements and pushes false onto the stack if<sig>
is not a valid signature of<msg>
and<pubKey>
.
OP_CHECKDATASIGVERIFY is equivalent to OP_CHECKDATASIG followed by OP_VERIFY. It leaves nothing on the stack, and will cause the script to fail immediately if the signature check does not pass.
OP_CHECKDATASIGVERIFY uses the currently unused opcode number 187 (0xbb in hex encoding)
Todo
<sig> <pubKey> <msg> OP_CHECKDATASIGVERIFY
fails if 15 November 2018 protocol upgrade is not yet activated.<sig> <pubKey> OP_CHECKDATASIGVERIFY
fails if fewer than 3 item on stack causes script failure<sig> <pubKey> <msg> OP_CHECKDATASIGVERIFY
fails if<msg>
is not a string of 256 bits<sig> <pubKey> <msg> OP_CHECKDATASIGVERIFY
fails if<pubKey>
is not a validly encoded public key (todo: more details about encoding).<sig> <pubKey> <msg> OP_CHECKDATASIGVERIFY
fails if is not a validly encoded signature with strict DER encoding.<sig> <pubKey> <msg> OP_CHECKDATASIGVERIFY
fails if signature<sig>
does not pass the Low S check and is a non empty byte array.<sig> <pubKey> <msg> OP_CHECKDATASIGVERIFY
fails if<sig>
is not an empty byte array, and does not pass signature validation of<msg>
and<pubKey>
.<sig> <pubKey> <msg> OP_CHECKDATASIGVERIFY
fails if is an empty byte array.<sig> <pubKey> <msg> OP_CHECKDATASIGVERIFY
pops the top three stack elements if is a valid signature of and .<sig> <pubKey> <msg> OP_CHECKDATASIG
fails if<sig>
is not a valid signature of<msg>
and<pubKey>
.
Note that the only test case that distinguishes between OP_CHECKDATASIG
and OP_CHECKDATASIGVERIFY
is the last one.
case OP_CHECKDATASIG:
case OP_CHECKSIGVERIFY: {
if (!enableCheckDataSig)
return set_error(serror, SCRIPT_ERR_BAD_OPCODE);
if (stack.size() < 3)
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
valtype &vchSig = stacktop(-3);
valtype &vchPubKey = stacktop(-2);
valtype &messageHash = stacktop(-1);
if (messageHash.size() != 32)
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
if (!CheckSignatureEncoding(vchSig, flags, serror)
|| !CheckPubKeyEncoding(vchPubKey, flags, serror)) {
// serror is set
return false;
}
bool fSuccess = checker.VerifySignature(vchSig, vchPubKey, messageHash);
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_CHECKSIGVERIFY);
}
}
} break;
This specification is based on Andrew Stone’s OP_DATASIGVERIFY proposal [4, 5]. It is modified from Stone's original proposal based on a synthesis of all the peer-review and feedback received [6].
List of differences from OP_DATASIGVERIFY proposal:
- Includes “non-verify” version, which does not immediately mark transaction as invalid if it fails, simply returns “False”. Returns “True” if successful. For verify behavior, use OP_CHECKDATASIGVERIFY.
- Does not leave input MessageHash on the stack, all three input values are removed.
- Order of inputs is different. Message hash input is the top stack item, rather than the bottom item.
- Takes Pubkey as input, rather the Pubkeyhash.
- Signature format same as OP_CHECKSIG, rather than Pubkey-recoverable signature.
- No “type” field with the signature. All signatures are treated as strict DER encoded ECDSA.
- Expects "MessageHash" to be a 256-bit hash, fails if it is not a 256-bit value.
[1] OP_CHECKSIG
[3] Low-S and Nullfail Specification
[4] Andrew Stone’s OP_DATASIGVERIFY