diff --git a/lib/bcoin/script.js b/lib/bcoin/script.js index ac520449..b5d83760 100644 --- a/lib/bcoin/script.js +++ b/lib/bcoin/script.js @@ -1082,8 +1082,9 @@ script.isPubkeyhash = function isPubkeyhash(s, hash) { return true; }; -script.isMultisig = function isMultisig(s, pubs) { - var m, n, keys, total; +script.isMultisig = function isMultisig(s, keys) { + var m, n, i, j; + var total = 0; s = script.subscript(s); @@ -1093,43 +1094,52 @@ script.isMultisig = function isMultisig(s, pubs) { if (s.length < 4) return false; - // compat - if (pubs && !utils.isBuffer(pubs[0])) - pubs = [pubs]; - - m = s[0]; - if (typeof m === 'number' && m >= 1 && m <= 15) - m = [m]; - if (!Array.isArray(m) || m.length !== 1) - return false; - m = m[0] || 0; - if (s[s.length - 1] !== 'checkmultisig') return false; - n = s[s.length - 2]; - if (typeof n === 'number' && n >= 1 && n <= 15) - n = [n]; - if (!Array.isArray(n) || n.length !== 1) + m = s[0]; + + if (Array.isArray(m)) { + if (m.length !== 1) + return false; + m = m[0]; + } + + if (!(m >= 1 && m <= 15)) + return false; + + n = s[s.length - 2]; + + if (Array.isArray(n)) { + if (n.length !== 1) + return false; + n = n[0]; + } + + if (!(n >= m && n <= 15)) return false; - n = n[0] || 0; if (n + 3 !== s.length) return false; - keys = s.slice(1, 1 + n); + for (i = 1; i < n + 1; i++) { + if (!Array.isArray(s[i])) + return false; + } - if (!keys.every(Array.isArray)) - return false; - - if (!pubs) + if (!keys) return true; - total = keys.filter(function(k) { - return pubs.some(function(pub) { - return utils.isEqual(k, pub); - }); - }).length; + keys = utils.sortKeys(keys); + + for (i = 1; i < n + 1; i++) { + for (j = 0; j < keys.length; j++) { + if (utils.isEqual(s[i], keys[j])) { + total++; + break; + } + } + } return total === n; }; @@ -1199,8 +1209,11 @@ script.isPubkeyInput = function isPubkeyInput(s, key, tx, i) { // Execute the script against our key's // checksig script to see if this is our input. // This will only work if the script verifies. - if (key) + if (key) { + assert(tx); + assert(i != null); return script.verify(s, [key, 'checksig'], tx, i); + } return true; }; @@ -1247,7 +1260,10 @@ script.isMultisigInput = function isMultisigInput(s, keys, tx, i) { // Execute the script against our pubkeys' // redeem script to see if this is our input. // This will only work if the script verifies. - if (keys && keys.length >= 2) { + if (keys) { + assert(keys.length >= 2); + assert(tx); + assert(i != null); o = script.redeem(keys, s.length - 1, keys.length); return script.verify(s, o, tx, i); } diff --git a/lib/bcoin/utils.js b/lib/bcoin/utils.js index 40a2d684..e08edbe8 100644 --- a/lib/bcoin/utils.js +++ b/lib/bcoin/utils.js @@ -754,7 +754,7 @@ utils.hidden = function hidden(obj, prop, value) { }; utils.sortKeys = function sortKeys(keys) { - return keys.sort(function(a, b) { + return keys.slice().sort(function(a, b) { return new bn(a).cmp(new bn(b)) > 0; }); };