diff --git a/lib/protocol/constants.js b/lib/protocol/constants.js index c49f4697..03c401eb 100644 --- a/lib/protocol/constants.js +++ b/lib/protocol/constants.js @@ -777,7 +777,8 @@ exports.flags = { VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM: (1 << 12), VERIFY_MINIMALIF: (1 << 13), VERIFY_NULLFAIL: (1 << 14), - VERIFY_MAST: (1 << 15), // should be 1 << 13 + VERIFY_WITNESS_PUBKEYTYPE: (1 << 15), + VERIFY_MAST: (1 << 16), // should be 1 << 13 VERIFY_SEQUENCE: (1 << 0), MEDIAN_TIME_PAST: (1 << 1) }; @@ -804,11 +805,14 @@ exports.flags.STANDARD_VERIFY_FLAGS = 0 | exports.flags.VERIFY_NULLDUMMY | exports.flags.VERIFY_DISCOURAGE_UPGRADABLE_NOPS | exports.flags.VERIFY_CLEANSTACK + | exports.flags.VERIFY_MINIMALIF + | exports.flags.VERIFY_NULLFAIL | exports.flags.VERIFY_CHECKLOCKTIMEVERIFY - | exports.flags.VERIFY_LOW_S | exports.flags.VERIFY_CHECKSEQUENCEVERIFY + | exports.flags.VERIFY_LOW_S | exports.flags.VERIFY_WITNESS - | exports.flags.VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM; + | exports.flags.VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM + | exports.flags.VERIFY_WITNESS_PUBKEYTYPE; /** * Standard-not-mandatory flags. diff --git a/lib/script/script.js b/lib/script/script.js index 54341c48..feef16eb 100644 --- a/lib/script/script.js +++ b/lib/script/script.js @@ -978,7 +978,7 @@ Script.prototype.execute = function execute(stack, flags, tx, index, version) { subscript.removeData(sig); Script.validateSignature(sig, flags); - Script.validateKey(key, flags); + Script.validateKey(key, flags, version); if (sig.length > 0) { type = sig[sig.length - 1]; @@ -1057,7 +1057,7 @@ Script.prototype.execute = function execute(stack, flags, tx, index, version) { key = stack.top(-ikey); Script.validateSignature(sig, flags); - Script.validateKey(key, flags); + Script.validateKey(key, flags, version); if (sig.length > 0) { type = sig[sig.length - 1]; @@ -2713,7 +2713,7 @@ Script.isDummy = function isDummy(data) { * @throws {ScriptError} */ -Script.validateKey = function validateKey(key, flags) { +Script.validateKey = function validateKey(key, flags, version) { if (flags == null) flags = constants.flags.STANDARD_VERIFY_FLAGS; @@ -2724,6 +2724,31 @@ Script.validateKey = function validateKey(key, flags) { throw new ScriptError('PUBKEYTYPE'); } + if (version === 1) { + if (flags & constants.flags.VERIFY_WITNESS_PUBKEYTYPE) { + if (!Script.isCompressedEncoding(key)) + throw new ScriptError('WITNESS_PUBKEYTYPE'); + } + } + + return true; +}; + +/** + * Test whether the data element is a compressed key. + * @param {Buffer} key + * @returns {Boolean} + */ + +Script.isCompressedEncoding = function isCompressedEncoding(key) { + assert(Buffer.isBuffer(key)); + + if (key.length !== 33) + return false; + + if (key[0] !== 0x02 && key[0] !== 0x03) + return false; + return true; };