From 626c31911b5339edb22d4362458189216fdbc28e Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Fri, 28 Mar 2014 18:14:46 +1100 Subject: [PATCH 1/3] Removes dangerous private key throwaway --- src/eckey.js | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/eckey.js b/src/eckey.js index e7db1ba..8dd5cb1 100644 --- a/src/eckey.js +++ b/src/eckey.js @@ -28,7 +28,7 @@ ECKey.prototype.import = function (input,compressed) { this.priv = input instanceof ECKey ? input.priv : input instanceof BigInteger ? input.mod(ecparams.getN()) - : Array.isArray(input) ? fromBin(input.slice(0,32)) + : Array.isArray(input) ? fromBin(input.slice(0,32)) : typeof input != "string" ? null : input.length == 44 ? fromBin(convert.base64ToBytes(input)) : input.length == 51 && input[0] == '5' ? fromBin(base58.checkDecode(input)) @@ -42,7 +42,7 @@ ECKey.prototype.import = function (input,compressed) { compressed !== undefined ? compressed : input instanceof ECKey ? input.compressed : input instanceof BigInteger ? false - : Array.isArray(input) ? false + : Array.isArray(input) ? false : typeof input != "string" ? null : input.length == 44 ? false : input.length == 51 && input[0] == '5' ? false @@ -119,25 +119,23 @@ ECKey.prototype.verify = function(hash, sig) { } var ECPubKey = function(input, compressed) { - if (!(this instanceof ECPubKey)) { return new ECPubKey(input, compressed); } - if (!input) { - // Generate new key - var n = ecparams.getN(); - this.pub = ecparams.getG().multiply(ecdsa.getBigRandom(n)) - this.compressed = compressed || false; - } - else this.import(input,compressed) + if (!(this instanceof ECPubKey)) { + return new ECPubKey(input, compressed) + } + + this.import(input,compressed) } -ECPubKey.prototype.import = function(input,compressed) { +ECPubKey.prototype.import = function(input, compressed) { var decode = function(x) { return ECPointFp.decodeFrom(ecparams.getCurve(), x) } + this.pub = input instanceof ECPointFp ? input : input instanceof ECKey ? ecparams.getG().multiply(input.priv) : input instanceof ECPubKey ? input.pub : typeof input == "string" ? decode(convert.hexToBytes(input)) - : Array.isArray(input) ? decode(input) - : ecparams.getG().multiply(ecdsa.getBigRandom(ecparams.getN())) + : Array.isArray(input) ? decode(input) + : null this.compressed = compressed ? compressed @@ -147,11 +145,11 @@ ECPubKey.prototype.import = function(input,compressed) { } ECPubKey.prototype.add = function(key) { - return ECPubKey(this.pub.add(ECPubKey(key).pub),this.compressed) + return ECPubKey(this.pub.add(ECPubKey(key).pub), this.compressed) } ECPubKey.prototype.multiply = function(key) { - return ECPubKey(this.pub.multiply(ECKey(key).priv),this.compressed) + return ECPubKey(this.pub.multiply(ECKey(key).priv), this.compressed) } ECPubKey.prototype['export'] = function(format) { From 3fa43b83b6b668844c4d169e358584a24cc43531 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Fri, 28 Mar 2014 19:57:06 +1100 Subject: [PATCH 2/3] Comma consistency --- src/eckey.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/eckey.js b/src/eckey.js index 8dd5cb1..cf2f624 100644 --- a/src/eckey.js +++ b/src/eckey.js @@ -22,20 +22,20 @@ var ECKey = function (input, compressed) { else this.import(input,compressed) }; -ECKey.prototype.import = function (input,compressed) { - function has(li,v) { return li.indexOf(v) >= 0 } +ECKey.prototype.import = function (input, compressed) { + function has(li, v) { return li.indexOf(v) >= 0 } function fromBin(x) { return BigInteger.fromByteArrayUnsigned(x) } this.priv = input instanceof ECKey ? input.priv : input instanceof BigInteger ? input.mod(ecparams.getN()) - : Array.isArray(input) ? fromBin(input.slice(0,32)) + : Array.isArray(input) ? fromBin(input.slice(0, 32)) : typeof input != "string" ? null : input.length == 44 ? fromBin(convert.base64ToBytes(input)) : input.length == 51 && input[0] == '5' ? fromBin(base58.checkDecode(input)) : input.length == 51 && input[0] == '9' ? fromBin(base58.checkDecode(input)) - : input.length == 52 && has('LK',input[0]) ? fromBin(base58.checkDecode(input).slice(0,32)) - : input.length == 52 && input[0] == 'c' ? fromBin(base58.checkDecode(input).slice(0,32)) - : has([64,65],input.length) ? fromBin(convert.hexToBytes(input.slice(0,64))) + : input.length == 52 && has('LK', input[0]) ? fromBin(base58.checkDecode(input).slice(0, 32)) + : input.length == 52 && input[0] == 'c' ? fromBin(base58.checkDecode(input).slice(0, 32)) + : has([64,65],input.length) ? fromBin(convert.hexToBytes(input.slice(0, 64))) : null this.compressed = @@ -47,7 +47,7 @@ ECKey.prototype.import = function (input,compressed) { : input.length == 44 ? false : input.length == 51 && input[0] == '5' ? false : input.length == 51 && input[0] == '9' ? false - : input.length == 52 && has('LK',input[0]) ? true + : input.length == 52 && has('LK', input[0]) ? true : input.length == 52 && input[0] == 'c' ? true : input.length == 64 ? false : input.length == 65 ? true @@ -56,7 +56,7 @@ ECKey.prototype.import = function (input,compressed) { ECKey.prototype.getPub = function(compressed) { if (compressed === undefined) compressed = this.compressed - return ECPubKey(ecparams.getG().multiply(this.priv),compressed) + return ECPubKey(ecparams.getG().multiply(this.priv), compressed) } /** @@ -103,11 +103,11 @@ ECKey.prototype.getAddress = function(version) { } ECKey.prototype.add = function(key) { - return ECKey(this.priv.add(ECKey(key).priv),this.compressed) + return ECKey(this.priv.add(ECKey(key).priv), this.compressed) } ECKey.prototype.multiply = function(key) { - return ECKey(this.priv.multiply(ECKey(key).priv),this.compressed) + return ECKey(this.priv.multiply(ECKey(key).priv), this.compressed) } ECKey.prototype.sign = function(hash) { @@ -123,7 +123,7 @@ var ECPubKey = function(input, compressed) { return new ECPubKey(input, compressed) } - this.import(input,compressed) + this.import(input, compressed) } ECPubKey.prototype.import = function(input, compressed) { From 8fd06681efac8d13a65bb60294d0527bc014aa99 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Sat, 29 Mar 2014 19:32:57 +1100 Subject: [PATCH 3/3] Adds fail fast assertions for invalid input --- src/eckey.js | 134 +++++++++++++++++++++++++++------------------------ 1 file changed, 71 insertions(+), 63 deletions(-) diff --git a/src/eckey.js b/src/eckey.js index cf2f624..f617000 100644 --- a/src/eckey.js +++ b/src/eckey.js @@ -1,58 +1,64 @@ -var BigInteger = require('./jsbn/jsbn'); -var sec = require('./jsbn/sec'); -var base58 = require('./base58'); -var util = require('./util'); -var convert = require('./convert'); -var Address = require('./address'); -var ecdsa = require('./ecdsa'); -var ECPointFp = require('./jsbn/ec').ECPointFp; +var Address = require('./address') +var assert = require('assert') +var convert = require('./convert') +var base58 = require('./base58') +var BigInteger = require('./jsbn/jsbn') +var ecdsa = require('./ecdsa') +var ECPointFp = require('./jsbn/ec').ECPointFp +var sec = require('./jsbn/sec') var Network = require('./network') +var util = require('./util') -var ecparams = sec("secp256k1"); +var ecparams = sec("secp256k1") // input can be nothing, array of bytes, hex string, or base58 string var ECKey = function (input, compressed) { - if (!(this instanceof ECKey)) { return new ECKey(input, compressed); } - if (!input) { - // Generate new key - var n = ecparams.getN(); - this.priv = ecdsa.getBigRandom(n); - this.compressed = compressed || false; - } - else this.import(input,compressed) -}; + if (!(this instanceof ECKey)) { return new ECKey(input, compressed) } + if (!input) { + // Generate new key + var n = ecparams.getN() + this.priv = ecdsa.getBigRandom(n) + this.compressed = compressed || false + } + else this.import(input,compressed) +} ECKey.prototype.import = function (input, compressed) { - function has(li, v) { return li.indexOf(v) >= 0 } - function fromBin(x) { return BigInteger.fromByteArrayUnsigned(x) } - this.priv = - input instanceof ECKey ? input.priv - : input instanceof BigInteger ? input.mod(ecparams.getN()) - : Array.isArray(input) ? fromBin(input.slice(0, 32)) - : typeof input != "string" ? null - : input.length == 44 ? fromBin(convert.base64ToBytes(input)) - : input.length == 51 && input[0] == '5' ? fromBin(base58.checkDecode(input)) - : input.length == 51 && input[0] == '9' ? fromBin(base58.checkDecode(input)) - : input.length == 52 && has('LK', input[0]) ? fromBin(base58.checkDecode(input).slice(0, 32)) - : input.length == 52 && input[0] == 'c' ? fromBin(base58.checkDecode(input).slice(0, 32)) - : has([64,65],input.length) ? fromBin(convert.hexToBytes(input.slice(0, 64))) - : null - - this.compressed = - compressed !== undefined ? compressed - : input instanceof ECKey ? input.compressed - : input instanceof BigInteger ? false - : Array.isArray(input) ? false - : typeof input != "string" ? null - : input.length == 44 ? false - : input.length == 51 && input[0] == '5' ? false - : input.length == 51 && input[0] == '9' ? false - : input.length == 52 && has('LK', input[0]) ? true - : input.length == 52 && input[0] == 'c' ? true - : input.length == 64 ? false - : input.length == 65 ? true - : null -}; + function has(li, v) { return li.indexOf(v) >= 0 } + function fromBin(x) { return BigInteger.fromByteArrayUnsigned(x) } + + this.priv = + input instanceof ECKey ? input.priv + : input instanceof BigInteger ? input.mod(ecparams.getN()) + : Array.isArray(input) ? fromBin(input.slice(0, 32)) + : typeof input != "string" ? null + : input.length == 44 ? fromBin(convert.base64ToBytes(input)) + : input.length == 51 && input[0] == '5' ? fromBin(base58.checkDecode(input)) + : input.length == 51 && input[0] == '9' ? fromBin(base58.checkDecode(input)) + : input.length == 52 && has('LK', input[0]) ? fromBin(base58.checkDecode(input).slice(0, 32)) + : input.length == 52 && input[0] == 'c' ? fromBin(base58.checkDecode(input).slice(0, 32)) + : has([64,65],input.length) ? fromBin(convert.hexToBytes(input.slice(0, 64))) + : null + + assert(this.priv !== null) + + this.compressed = + compressed !== undefined ? compressed + : input instanceof ECKey ? input.compressed + : input instanceof BigInteger ? false + : Array.isArray(input) ? false + : typeof input != "string" ? null + : input.length == 44 ? false + : input.length == 51 && input[0] == '5' ? false + : input.length == 51 && input[0] == '9' ? false + : input.length == 52 && has('LK', input[0]) ? true + : input.length == 52 && input[0] == 'c' ? true + : input.length == 64 ? false + : input.length == 65 ? true + : null + + assert(this.compressed !== null) +} ECKey.prototype.getPub = function(compressed) { if (compressed === undefined) compressed = this.compressed @@ -127,21 +133,23 @@ var ECPubKey = function(input, compressed) { } ECPubKey.prototype.import = function(input, compressed) { - var decode = function(x) { return ECPointFp.decodeFrom(ecparams.getCurve(), x) } - - this.pub = - input instanceof ECPointFp ? input - : input instanceof ECKey ? ecparams.getG().multiply(input.priv) - : input instanceof ECPubKey ? input.pub - : typeof input == "string" ? decode(convert.hexToBytes(input)) - : Array.isArray(input) ? decode(input) - : null - - this.compressed = - compressed ? compressed - : input instanceof ECPointFp ? input.compressed - : input instanceof ECPubKey ? input.compressed - : (this.pub[0] < 4) + var decode = function(x) { return ECPointFp.decodeFrom(ecparams.getCurve(), x) } + + this.pub = + input instanceof ECPointFp ? input + : input instanceof ECKey ? ecparams.getG().multiply(input.priv) + : input instanceof ECPubKey ? input.pub + : typeof input == "string" ? decode(convert.hexToBytes(input)) + : Array.isArray(input) ? decode(input) + : null + + assert(this.pub !== null) + + this.compressed = + compressed ? compressed + : input instanceof ECPointFp ? input.compressed + : input instanceof ECPubKey ? input.compressed + : (this.pub[0] < 4) } ECPubKey.prototype.add = function(key) {