layout | title | date | activation | version |
---|---|---|---|---|
specification |
OP_CHECKDATASIG and OP_CHECKDATASIGVERIFY Specification |
2018-08-06 |
1542300000 |
0.1 |
OP_CHECKDATASIG and OP_CHECKDATASIGVERIFY check whether a signature is valid with respect to a message hash and and a public key. The message hash is restricted to exactly 256 bits.
OP_CHECKDATASIG 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 [<sig>
, <msgHash>
, <pubKey>
] in this order where <pubKey>
is the top element and
<pubKey>
must be a validly encoded public key<msgHash>
must be a string of exactly 256 bits<sig>
must follow the strict DER encoding as described in [2] and the S-value of<sig>
must be 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 [<sig>
, <msgHash>
, <pubKey>
] from the stack and pushes true onto the stack if the signature is valid with respect to the message hash and the public key using the secp256k1 elliptic curve. Otherwise, it pops three elements and pushes false onto the stack in the case that <sig>
is the empty string and fails in all other cases.
Nullfail is enforced the same as for OP_CHECKSIG [3]. If the signature does not match the supplied public key and message hash, and the signature is not an empty byte array, the entire script fails.
OP_CHECKDATASIG uses the previously 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 (1) SigOp.
Use of OP_CHECKDATASIG, unless occuring in an unexecuted OP_IF branch, will make the transaction invalid if it is included in a block where the median timestamp of the prior 11 blocks is less than 1542300000.
<sig> <msgHash> <pubKey> OP_CHECKDATASIG
fails if 15 November 2018 protocol upgrade is not yet activated.<sig> <msgHash> OP_CHECKDATASIG
fails if there are fewer than 3 item on stack.<sig> <msgHash> <pubKey> OP_CHECKDATASIG
fails if<msgHash>
is not a string of 256 bits (32 bytes).<sig> <msgHash> <pubKey> OP_CHECKDATASIG
fails if<pubKey>
is not a validly encoded public key.<sig> <msgHash> <pubKey> OP_CHECKDATASIG
fails if<sig>
is not a validly encoded signature with strict DER encoding.<sig> <msgHash> <pubKey> OP_CHECKDATASIG
fails if signature<sig>
is not empty and does not pass the Low S check.<sig> <msgHash> <pubKey> OP_CHECKDATASIG
fails if signature<sig>
is not empty and does not pass signature validation of<msg>
and<pubKey>
.<sig> <msgHash> <pubKey> OP_CHECKDATASIG
pops three elements and pushes false onto the stack if<sig>
is an empty byte array.<sig> <msgHash> <pubKey> OP_CHECKDATASIG
pops three elements and pushes true onto the stack if<sig>
is a valid signature of<msgHash>
with respect to<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 previously unused opcode number 187 (0xbb in hex encoding)
Signature operations accounting for OP_CHECKDATASIGVERIFY shall be calculated the same as OP_CHECKSIGVERIFY. This means that each OP_CHECKDATASIGVERIFY shall be counted as one (1) SigOp.
Use of OP_CHECKDATASIGVERIFY, unless occuring in an unexecuted OP_IF branch, will make the transaction invalid if it is included in a block where the median timestamp of the prior 11 blocks is less than 1542300000.
<sig> <msgHash> <pubKey> OP_CHECKDATASIGVERIFY
fails if 15 November 2018 protocol upgrade is not yet activated.<sig> <msgHash> OP_CHECKDATASIGVERIFY
fails if there are fewer than 3 item on stack.<sig> <msgHash> <pubKey> OP_CHECKDATASIGVERIFY
fails if<msgHash>
is not a string of 256 bits (32 bytes).<sig> <msgHash> <pubKey> OP_CHECKDATASIGVERIFY
fails if<pubKey>
is not a validly encoded public key.<sig> <msgHash> <pubKey> OP_CHECKDATASIGVERIFY
fails if<sig>
is not a validly encoded signature with strict DER encoding.<sig> <msgHash> <pubKey> OP_CHECKDATASIGVERIFY
fails if signature<sig>
is not empty and does not pass the Low S check.<sig> <msgHash> <pubKey> OP_CHECKDATASIGVERIFY
fails if<sig>
is not a valid signature of<msgHash>
with respect to<pubKey>
.<sig> <msgHash> <pubKey> OP_CHECKDATASIGVERIFY
pops the top three stack elements if<sig>
is a valid signature of<msgHash>
with respect to<pubKey>
.
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;
This specification is based on Andrew Stone’s OP_DATASIGVERIFY proposal [5, 6]. It is modified from Stone's original proposal based on a synthesis of all the peer-review and feedback received [7].
[1] OP_CHECKSIG
[3] Low-S and Nullfail Specification
[4] Bitcoin ABC implementation
[5] Andrew Stone’s OP_DATASIGVERIFY
I agree almost 100% with this proposal (I have not reviewed the source code, however). The only nitpick I can find is that I think it would be a little bit cleaner if OP_CHECKDATASIG would not hash the input data. While I understand that it is recommended to sign the hash of a document instead of the document itself (if it is long), I think this is a decision that should be left to the programmer. The semantics would become even simpler: "the public key is used to check the supplied signature against the data".
One more thing, you could consider changing the wording from "data" to "message". Means exactly the same thing but is more in line with the lingo used in crypto textbooks.