From 35d0cbc5a6fdeff5186c39108b5e5df829f6f8ae Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Mon, 24 Nov 2014 17:23:09 -0500 Subject: [PATCH 1/4] Keys: Modified interface of Pubkey and Privkey so that an instance can be relied upon as valid. --- lib/bip32.js | 29 ++-- lib/privkey.js | 351 ++++++++++++++++++++++++++++++++++---------- lib/pubkey.js | 380 +++++++++++++++++++++++++++++++++++++----------- test/address.js | 21 +-- test/privkey.js | 201 ++++++++++++++++++------- test/pubkey.js | 208 ++++++++++++++++++-------- 6 files changed, 896 insertions(+), 294 deletions(-) diff --git a/lib/bip32.js b/lib/bip32.js index 7c4bc3940..157c80443 100644 --- a/lib/bip32.js +++ b/lib/bip32.js @@ -41,8 +41,8 @@ BIP32.prototype.fromRandom = function(networkstr) { this.parentfingerprint = new Buffer([0, 0, 0, 0]); this.childindex = new Buffer([0, 0, 0, 0]); this.chaincode = Random.getRandomBuffer(32); - this.privkey = Privkey().fromRandom(); - this.pubkey = new Pubkey().fromPrivkey(this.privkey); + this.privkey = Privkey.fromRandom(); + this.pubkey = Pubkey.fromPrivkey(this.privkey); this.hasprivkey = true; this.pubkeyhash = Hash.sha256ripemd160(this.pubkey.toBuffer()); this.buildxpubkey(); @@ -72,8 +72,8 @@ BIP32.prototype.fromSeed = function(bytes, networkstr) { this.childindex = new Buffer([0, 0, 0, 0]); this.chaincode = hash.slice(32, 64); this.version = networks[networkstr].bip32privkey; - this.privkey = new Privkey({bn: BN().fromBuffer(hash.slice(0, 32))}); - this.pubkey = new Pubkey().fromPrivkey(this.privkey); + this.privkey = new Privkey(BN().fromBuffer(hash.slice(0, 32))); + this.pubkey = Pubkey.fromPrivkey(this.privkey); this.hasprivkey = true; this.pubkeyhash = Hash.sha256ripemd160(this.pubkey.toBuffer()); @@ -105,12 +105,12 @@ BIP32.prototype.initFromBytes = function(bytes) { this.version == networks.testnet.bip32pubkey); if (isPrivate && keyBytes[0] == 0) { - this.privkey = new Privkey({bn: BN().fromBuffer(keyBytes.slice(1, 33))}); - this.pubkey = new Pubkey().fromPrivkey(this.privkey); + this.privkey = new Privkey(BN().fromBuffer(keyBytes.slice(1, 33))); + this.pubkey = Pubkey.fromPrivkey(this.privkey); this.pubkeyhash = Hash.sha256ripemd160(this.pubkey.toBuffer()); this.hasprivkey = true; } else if (isPublic && (keyBytes[0] == 0x02 || keyBytes[0] == 0x03)) { - this.pubkey = (new Pubkey()).fromDER(keyBytes); + this.pubkey = Pubkey.fromDER(keyBytes); this.pubkeyhash = Hash.sha256ripemd160(this.pubkey.toBuffer()); this.hasprivkey = false; } else { @@ -119,7 +119,7 @@ BIP32.prototype.initFromBytes = function(bytes) { this.buildxpubkey(); this.buildxprivkey(); -} +}; BIP32.prototype.buildxpubkey = function() { this.xpubkey = new Buffer([]); @@ -153,7 +153,7 @@ BIP32.prototype.buildxpubkey = function() { this.chaincode, this.pubkey.toBuffer() ]); -} +}; BIP32.prototype.xpubkeyString = function(format) { if (format === undefined || format === 'base58') { @@ -228,7 +228,7 @@ BIP32.prototype.derive = function(path) { } return bip32; -} +}; BIP32.prototype.deriveChild = function(i) { if (typeof i !== 'number') @@ -270,8 +270,8 @@ BIP32.prototype.deriveChild = function(i) { ret = new BIP32(); ret.chaincode = ir; - ret.privkey = new Privkey({bn: k}); - ret.pubkey = new Pubkey().fromPrivkey(ret.privkey); + ret.privkey = new Privkey(k); + ret.pubkey = Pubkey.fromPrivkey(ret.privkey); ret.hasprivkey = true; } else { @@ -284,8 +284,7 @@ BIP32.prototype.deriveChild = function(i) { var ilG = Point.getG().mul(il); var Kpar = this.pubkey.point; var Ki = ilG.add(Kpar); - var newpub = new Pubkey(); - newpub.point = Ki; + var newpub = Pubkey.fromPoint(Ki); ret = new BIP32(); ret.chaincode = ir; @@ -305,7 +304,7 @@ BIP32.prototype.deriveChild = function(i) { ret.buildxprivkey(); return ret; -} +}; BIP32.prototype.toString = function() { var isPrivate = diff --git a/lib/privkey.js b/lib/privkey.js index 5f024a892..a2203fdbc 100644 --- a/lib/privkey.js +++ b/lib/privkey.js @@ -5,107 +5,312 @@ var Point = require('./crypto/point'); var Random = require('./crypto/random'); var networks = require('./networks'); var base58check = require('./encoding/base58check'); +var Address = require('./address'); var Pubkey = require('./pubkey'); -var Privkey = function Privkey(bn) { - if (!(this instanceof Privkey)) - return new Privkey(bn); - if (bn instanceof BN) - this.bn = bn; - else if (bn) { - var obj = bn; - this.set(obj); +/** + * + * Bitcore Privkey + * + * Instantiate a Privkey from a BN, Buffer and WIF. + * + * @example + * + * var privkey = new Privkey(); + * + * @param {String} data - The encoded data in various formats + * @param {String} [network] - Either "mainnet" or "testnet" + * @param {Boolean} [compressed] - If the key is in compressed format + * @returns {Privkey} A new valid instance of an Privkey + */ +var Privkey = function Privkey(data, network, compressed) { + + if (!(this instanceof Privkey)) { + return new Privkey(data, network, compressed); } -}; -Privkey.prototype.set = function(obj) { - this.bn = obj.bn || this.bn; - this.networkstr = obj.networkstr || this.networkstr; - this.compressed = typeof obj.compressed !== 'undefined' ? obj.compressed : this.compressed; + var info = { + compressed: typeof(compressed) !== 'undefined' ? compressed : true, + network: network || 'mainnet' + }; + + // detect type of data + if (!data){ + info.bn = Privkey._getRandomBN(); + } else if (data instanceof BN) { + info.bn = data; + } else if (data instanceof Buffer) { + info = Privkey._transformBuffer(data, network, compressed); + } else if (typeof(data) === 'string'){ + info = Privkey._transformWIF(data, network, compressed); + } else { + throw new TypeError('First argument is an unrecognized data type.'); + } + + // validation + if (!info.bn.lt(Point.getN())) { + throw new TypeError('Number must be less than N'); + } + if (typeof(networks[info.network]) === 'undefined') { + throw new TypeError('Must specify the network ("mainnet" or "testnet")'); + } + if (typeof(info.compressed) !== 'boolean') { + throw new TypeError('Must specify whether the corresponding public key is compressed or not (true or false)'); + } + + this.bn = info.bn; + this.compressed = info.compressed; + this.network = info.network; + return this; + }; -Privkey.prototype.fromJSON = function(json) { - this.fromString(json); - return this; -}; - -Privkey.prototype.toJSON = function() { - return this.toString(); -}; - -Privkey.prototype.fromRandom = function() { +/** + * + * Internal function to get a random BN + * + * @returns {Object} An object with keys: bn, network and compressed + */ +Privkey._getRandomBN = function(){ + var condition; + var bn; do { var privbuf = Random.getRandomBuffer(32); - var bn = BN().fromBuffer(privbuf); - var condition = bn.lt(Point.getN()); + bn = BN().fromBuffer(privbuf); + condition = bn.lt(Point.getN()); } while (!condition); - this.set({ - bn: bn, - networkstr: 'mainnet', - compressed: true - }); - return this; + return bn; }; -Privkey.prototype.validate = function() { - if (!this.bn.lt(Point.getN())) - throw new Error('Number must be less than N'); - if (typeof networks[this.networkstr] === undefined) - throw new Error('Must specify the networkstr ("mainnet" or "testnet")'); - if (typeof this.compressed !== 'boolean') - throw new Error('Must specify whether the corresponding public key is compressed or not (true or false)'); +/** + * + * Internal function to transform a WIF Buffer into a private key + * + * @param {Buffer} buf - An WIF string + * @param {String} [network] - Either "mainnet" or "testnet" + * @param {String} [compressed] - If the private key is compressed + * @returns {Object} An object with keys: bn, network and compressed + */ +Privkey._transformBuffer = function(buf, network, compressed) { + + var info = {}; + + if (buf.length === 1 + 32 + 1 && buf[1 + 32 + 1 - 1] === 1) { + info.compressed = true; + } else if (buf.length === 1 + 32) { + info.compressed = false; + } else { + throw new Error('Length of buffer must be 33 (uncompressed) or 34 (compressed)'); + } + + if (buf[0] === networks.mainnet.privkey) { + info.network = 'mainnet'; + } else if (buf[0] === networks.testnet.privkey) { + info.network = 'testnet'; + } else { + throw new Error('Invalid network'); + } + + if (network && info.network !== network){ + throw TypeError('Private key network mismatch'); + } + + if (typeof(compressed) !== 'undefined' && info.compressed !== compressed){ + throw TypeError('Private key compression mismatch'); + } + + info.bn = BN.fromBuffer(buf.slice(1, 32 + 1)); + + return info; + }; +/** + * + * Internal function to transform a WIF string into a private key + * + * @param {String} buf - An WIF string + * @returns {Object} An object with keys: bn, network and compressed + */ +Privkey._transformWIF = function(str, network, compressed) { + return Privkey._transformBuffer(base58check.decode(str), network, compressed); +}; + +/** + * + * Instantiate a Privkey from a WIF string + * + * @param {String} str - The WIF encoded private key string + * @returns {Privkey} A new valid instance of Privkey + */ +Privkey.fromWIF = function(str) { + var info = Privkey._transformWIF(str); + return new Privkey(info.bn, info.network, info.compressed); +}; + +/** + * + * Instantiate a Privkey from a WIF JSON string + * + * @param {String} str - The WIF encoded private key string + * @returns {Privkey} A new valid instance of Privkey + */ +Privkey.fromJSON = function(json) { + var info = Privkey._transformWIF(json); + return new Privkey(info.bn, info.network, info.compressed); +}; + +/** + * + * Instantiate a Privkey from random bytes + * + * @param {String} [network] - Either "mainnet" or "testnet" + * @param {String} [compressed] - If the private key is compressed + * @returns {Privkey} A new valid instance of Privkey + */ +Privkey.fromRandom = function(network, compressed) { + var bn = Privkey._getRandomBN(); + return new Privkey(bn, network, compressed); +}; + +/** + * + * Instantiate a Privkey from a WIF string + * + * @param {String} str - The WIF encoded private key string + * @returns {Privkey} A new valid instance of Privkey + */ +Privkey.fromString = function(str) { + var info = Privkey._transformWIF(str); + return new Privkey(info.bn, info.network, info.compressed); +}; + +/** + * + * Check if there would be any errors when initializing a Privkey + * + * @param {String} data - The encoded data in various formats + * @param {String} [network] - Either "mainnet" or "testnet" + * @param {String} [compressed] - If the private key is compressed + * @returns {null|Error} An error if exists + */ + +Privkey.getValidationError = function(data, network, compressed) { + var error; + try { + new Privkey(data, network, compressed); + } catch (e) { + error = e; + } + return error; +}; + +/** + * + * Check if the parameters are valid + * + * @param {String} data - The encoded data in various formats + * @param {String} [network] - Either "mainnet" or "testnet" + * @param {String} [compressed] - If the private key is compressed + * @returns {Boolean} If the private key is would be valid + */ +Privkey.isValid = function(data, network, compressed){ + return !Privkey.getValidationError(data, network, compressed); +}; + +/** + * + * Will output the Privkey to a WIF string + * + * @returns {String} A WIP representation of the private key + */ Privkey.prototype.toWIF = function() { - var networkstr = this.networkstr; + var network = this.network; var compressed = this.compressed; - if (typeof this.networkstr === 'undefined') - networkstr = 'mainnet'; - if (typeof this.compressed === 'undefined') - compressed = true; - - var privbuf = this.bn.toBuffer({size: 32}); var buf; - if (compressed) - buf = Buffer.concat([new Buffer([networks[networkstr].privkey]), this.bn.toBuffer({size: 32}), new Buffer([0x01])]); - else - buf = Buffer.concat([new Buffer([networks[networkstr].privkey]), this.bn.toBuffer({size: 32})]); + if (compressed) { + buf = Buffer.concat([new Buffer([networks[network].privkey]), + this.bn.toBuffer({size: 32}), + new Buffer([0x01])]); + } else { + buf = Buffer.concat([new Buffer([networks[network].privkey]), + this.bn.toBuffer({size: 32})]); + } return base58check.encode(buf); }; -Privkey.prototype.fromWIF = function(str) { - var buf = base58check.decode(str); - - if (buf.length === 1 + 32 + 1 && buf[1 + 32 + 1 - 1] == 1) - this.compressed = true; - else if (buf.length === 1 + 32) - this.compressed = false; - else - throw new Error('Length of buffer must be 33 (uncompressed) or 34 (compressed)'); - - if (buf[0] === networks.mainnet.privkey) - this.networkstr = 'mainnet'; - else if (buf[0] === networks.testnet.privkey) - this.networkstr = 'testnet'; - else - throw new Error('Invalid networkstr'); - - this.bn = BN.fromBuffer(buf.slice(1, 32 + 1)); +/** + * + * Will return the private key as a BN instance + * + * @returns {BN} A BN instance of the private key + */ +Privkey.prototype.toBigNumber = function(){ + return this.bn; }; +/** + * + * Will return the private key as a BN buffer + * + * @returns {Buffer} A buffer of the private key + */ +Privkey.prototype.toBuffer = function(){ + return this.bn.toBuffer(); +}; + +/** + * + * Will return the corresponding public key + * + * @returns {Pubkey} A public key generated from the private key + */ +Privkey.prototype.toPubkey = function(){ + return Pubkey.fromPrivkey(this); +}; + +/** + * + * Will return an address for the private key + * + * @returns {Address} An address generated from the private key + */ +Privkey.prototype.toAddress = function() { + var pubkey = this.toPubkey(); + return Address.fromPubkey(pubkey, this.network); +}; + +/** + * + * Will output the Privkey to a WIF string + * + * @returns {String} A WIF representation of the private key + */ +Privkey.prototype.toJSON = function() { + return this.toString(); +}; + +/** + * + * Will output the Privkey to a WIF string + * + * @returns {String} A WIF representation of the private key + */ Privkey.prototype.toString = function() { return this.toWIF(); }; -Privkey.prototype.toPubkey = function() { - return new Pubkey().fromPrivkey(this); -} - -Privkey.prototype.fromString = function(str) { - this.fromWIF(str); +/** + * + * Will return a string formatted for the console + * + * @returns {String} Private key + */ +Privkey.prototype.inspect = function() { + return ''; }; module.exports = Privkey; diff --git a/lib/pubkey.js b/lib/pubkey.js index d9062a4ff..77a1f0f00 100644 --- a/lib/pubkey.js +++ b/lib/pubkey.js @@ -1,94 +1,300 @@ 'use strict'; var Point = require('./crypto/point'); -var bn = require('./crypto/bn'); +var BN = require('./crypto/bn'); -var Pubkey = function Pubkey(point) { - if (!(this instanceof Pubkey)) - return new Pubkey(point); - if (point instanceof Point) - this.point = point; - else if (point) { - var obj = point; - this.set(obj); +/** + * + * Bitcore Pubkey + * + * Instantiate a Pubkey from a 'Privkey', 'Point', 'string', 'Buffer'. + * + * @example + * + * var pubkey = new Pubkey(privkey, true); + * + * @param {String} data - The encoded data in various formats + * @param {String} [compressed] - If the public key is compressed + * @returns {Pubkey} A new valid instance of an Pubkey + */ +var Pubkey = function Pubkey(data, compressed) { + + if (!(this instanceof Pubkey)) { + return new Pubkey(data, compressed); } -}; -Pubkey.prototype.set = function(obj) { - if (obj.point && !obj.point.getX() && !obj.point.getY()) - throw new Error('Invalid point'); - this.point = obj.point || this.point; - this.compressed = typeof obj.compressed !== 'undefined' ? obj.compressed : this.compressed; + if (!data) { + throw new TypeError('First argument is required, please include public key data.'); + } + + var info = { + compressed: typeof(compressed) !== 'undefined' ? compressed : true + }; + + // detect type of data + if (data instanceof Point) { + info.point = data; + } else if (typeof(data) === 'string'){ + info = Pubkey._transformDER(new Buffer(data, 'hex' )); + } else if (data instanceof Buffer){ + info = Pubkey._transformDER(data); + } else if (data.constructor && (data.constructor.name && + data.constructor.name === 'Privkey')) { + info = Pubkey._transformPrivkey(data); + } else { + throw new TypeError('First argument is an unrecognized data format.'); + } + + // validation + if (info.point.isInfinity()){ + throw new Error('Point cannot be equal to Infinity'); + } + if (info.point.eq(Point(BN(0), BN(0)))){ + throw new Error('Point cannot be equal to 0, 0'); + } + + //https://www.iacr.org/archive/pkc2003/25670211/25670211.pdf + info.point.validate(); + + this.point = info.point; + this.compressed = info.compressed; + return this; + }; -Pubkey.prototype.fromJSON = function(json) { - this.fromBuffer(new Buffer(json, 'hex')); - return this; +/** + * + * Internal function to transform a private key into a public key point + * + * @param {Privkey} privkey - An instance of Privkey + * @returns {Object} An object with keys: point and compressed + */ +Pubkey._transformPrivkey = function(privkey) { + var info = {}; + if (!privkey.constructor || + (privkey.constructor.name && privkey.constructor.name !== 'Privkey')) { + throw new TypeError('Must be an instance of Privkey'); + } + info.point = Point.getG().mul(privkey.bn); + info.compressed = privkey.compressed; + return info; }; +/** + * + * Internal function to transform DER into a public key point + * + * @param {Buffer} buf - An hex encoded buffer + * @returns {Object} An object with keys: point and compressed + */ +Pubkey._transformDER = function(buf){ + var info = {}; + if (!(buf instanceof Buffer)){ + throw new TypeError('Must be a hex buffer of DER encoded public key'); + } + + var x; + var y; + var xbuf; + var ybuf; + + if (buf[0] === 0x04) { + xbuf = buf.slice(1, 33); + ybuf = buf.slice(33, 65); + if (xbuf.length !== 32 || ybuf.length !== 32 || buf.length !== 65) { + throw new TypeError('Length of x and y must be 32 bytes'); + } + x = BN(xbuf); + y = BN(ybuf); + info.point = Point(x, y); + info.compressed = false; + } else if (buf[0] === 0x03) { + xbuf = buf.slice(1); + x = BN(xbuf); + info = Pubkey._transformX(true, x); + info.compressed = true; + } else if (buf[0] == 0x02) { + xbuf = buf.slice(1); + x = BN(xbuf); + info = Pubkey._transformX(false, x); + info.compressed = true; + } else { + throw new TypeError('Invalid DER format pubkey'); + } + return info; +}; + +/** + * + * Internal function to transform X into a public key point + * + * @param {Boolean} odd - If the point is above or below the x axis + * @param {Point} x - The x point + * @returns {Object} An object with keys: point and compressed + */ +Pubkey._transformX = function(odd, x){ + var info = {}; + if (typeof odd !== 'boolean') { + throw new TypeError('Must specify whether y is odd or not (true or false)'); + } + info.point = Point.fromX(odd, x); + return info; +}; + +/** + * + * Instantiate a Pubkey from JSON + * + * @param {String} json - A JSON string of DER encoded pubkey + * @returns {Pubkey} A new valid instance of Pubkey + */ +Pubkey.fromJSON = function(json) { + var buf = new Buffer(json, 'hex'); + var info = Pubkey._transformDER(buf); + return new Pubkey(info.point, info.compressed); +}; + +/** + * + * Instantiate a Pubkey from a Privkey + * + * @param {Privkey} privkey - An instance of Privkey + * @returns {Pubkey} A new valid instance of Pubkey + */ +Pubkey.fromPrivkey = function(privkey) { + var info = Pubkey._transformPrivkey(privkey); + return new Pubkey(info.point, info.compressed); +}; + +/** + * + * Instantiate a Pubkey from a Buffer + * + * @param {Buffer} buf - A DER hex buffer + * @returns {Pubkey} A new valid instance of Pubkey + */ +Pubkey.fromBuffer = function(buf) { + var info = Pubkey._transformDER(buf); + return new Pubkey(info.point, info.compressed); +}; + +/** + * + * Instantiate a Pubkey from a Point + * + * @param {Point} point - A Point instance + * @returns {Pubkey} A new valid instance of Pubkey + */ +Pubkey.fromPoint = function(point){ + if (!(point instanceof Point)) { + throw new TypeError('First argument must be an instance of Point.'); + } + return new Pubkey(point); +}; + +/** + * + * Instantiate a Pubkey from a DER Buffer + * + * @param {Buffer} buf - A DER Buffer + * @returns {Pubkey} A new valid instance of Pubkey + */ +Pubkey.fromDER = function(buf) { + var info = Pubkey._transformDER(buf); + return new Pubkey(info.point, info.compressed); +}; + +/** + * + * Instantiate a Pubkey from a DER hex encoded string + * + * @param {String} str - A DER hex string + * @param {String} [encoding] - The type of string encoding + * @returns {Pubkey} A new valid instance of Pubkey + */ +Pubkey.fromString = function(str, encoding) { + var buf = new Buffer(str, encoding || 'hex'); + var info = Pubkey._transformDER(buf); + return new Pubkey(info.point, info.compressed); +}; + +/** + * + * Instantiate a Pubkey from an X Point + * + * @param {Boolean} odd - If the point is above or below the x axis + * @param {Point} x - The x point + * @returns {Pubkey} A new valid instance of Pubkey + */ +Pubkey.fromX = function(odd, x) { + var info = Pubkey._transformX(odd, x); + return new Pubkey(info.point, info.compressed); +}; + + +/** + * + * Check if there would be any errors when initializing a Pubkey + * + * @param {String} data - The encoded data in various formats + * @param {String} [compressed] - If the public key is compressed + * @returns {null|Error} An error if exists + */ +Pubkey.getValidationError = function(data, compressed) { + var error; + try { + new Pubkey(data, compressed); + } catch (e) { + error = e; + } + return error; +}; + +/** + * + * Check if the parameters are valid + * + * @param {String} data - The encoded data in various formats + * @param {String} [compressed] - If the public key is compressed + * @returns {Boolean} If the pubkey is would be valid + */ +Pubkey.isValid = function(data, compressed) { + return !Pubkey.getValidationError(data, compressed); +}; + +/** + * + * Will output the Pubkey to JSON + * + * @returns {String} A hex encoded string + */ Pubkey.prototype.toJSON = function() { return this.toBuffer().toString('hex'); }; -Pubkey.prototype.fromPrivkey = function(privkey) { - this.set({ - point: Point.getG().mul(privkey.bn), - compressed: privkey.compressed} - ); - return this; -}; - -Pubkey.prototype.fromBuffer = function(buf) { - return this.fromDER(buf); -}; - -Pubkey.prototype.fromDER = function(buf) { - if (buf[0] == 0x04) { - var xbuf = buf.slice(1, 33); - var ybuf = buf.slice(33, 65); - if (xbuf.length !== 32 || ybuf.length !== 32 || buf.length !== 65) - throw new Error('Length of x and y must be 32 bytes'); - var x = bn(xbuf); - var y = bn(ybuf); - this.point = Point(x, y); - this.compressed = false; - } else if (buf[0] == 0x03) { - var xbuf = buf.slice(1); - var x = bn(xbuf); - this.fromX(true, x); - this.compressed = true; - } else if (buf[0] == 0x02) { - var xbuf = buf.slice(1); - var x = bn(xbuf); - this.fromX(false, x); - this.compressed = true; - } else { - throw new Error('Invalid DER format pubkey'); - } - return this; -}; - -Pubkey.prototype.fromString = function( str , encoding ) { - var encoding = encoding || 'hex'; - this.fromDER( new Buffer(str, encoding ) ); -}; - -Pubkey.prototype.fromX = function(odd, x) { - if (typeof odd !== 'boolean') - throw new Error('Must specify whether y is odd or not (true or false)'); - this.point = Point.fromX(odd, x); -}; - +/** + * + * Will output the Pubkey to a Buffer + * + * @returns {Buffer} A DER hex encoded buffer + */ Pubkey.prototype.toBuffer = function() { var compressed = typeof this.compressed === 'undefined' ? true : this.compressed; return this.toDER(compressed); }; +/** + * + * Will output the Pubkey to a DER Buffer + * + * @returns {Buffer} A DER hex encoded buffer + */ Pubkey.prototype.toDER = function(compressed) { - compressed = typeof this.compressed === 'undefined' ? compressed : this.compressed; - if (typeof compressed !== 'boolean') - throw new Error('Must specify whether the public key is compressed or not (true or false)'); + compressed = typeof(compressed) !== 'undefined' ? compressed : this.compressed; + if (typeof compressed !== 'boolean') { + throw new TypeError('Must specify whether the public key is compressed or not (true or false)'); + } var x = this.point.getX(); var y = this.point.getY(); @@ -96,32 +302,40 @@ Pubkey.prototype.toDER = function(compressed) { var xbuf = x.toBuffer({size: 32}); var ybuf = y.toBuffer({size: 32}); + var prefix; if (!compressed) { - var prefix = new Buffer([0x04]); + prefix = new Buffer([0x04]); return Buffer.concat([prefix, xbuf, ybuf]); } else { var odd = ybuf[ybuf.length - 1] % 2; - if (odd) - var prefix = new Buffer([0x03]); - else - var prefix = new Buffer([0x02]); + if (odd) { + prefix = new Buffer([0x03]); + } else { + prefix = new Buffer([0x02]); + } return Buffer.concat([prefix, xbuf]); } }; +/** + * + * Will output the Pubkey to a DER encoded hex string + * + * @returns {String} A DER hex encoded string + */ Pubkey.prototype.toString = function() { var compressed = typeof this.compressed === 'undefined' ? true : this.compressed; return this.toDER(compressed).toString('hex'); }; -//https://www.iacr.org/archive/pkc2003/25670211/25670211.pdf -Pubkey.prototype.validate = function() { - if (this.point.isInfinity()) - throw new Error('point: Point cannot be equal to Infinity'); - if (this.point.eq(Point(bn(0), bn(0)))) - throw new Error('point: Point cannot be equal to 0, 0'); - this.point.validate(); - return this; +/** + * + * Will return a string formatted for the console + * + * @returns {String} Public key + */ +Pubkey.prototype.inspect = function() { + return ''; }; module.exports = Pubkey; diff --git a/test/address.js b/test/address.js index 6fb2019b1..b107be0f6 100644 --- a/test/address.js +++ b/test/address.js @@ -266,22 +266,15 @@ describe('Address', function() { }).should.throw('Address hashbuffers must be exactly 20 bytes.'); }); - it('should make this address from a compressed pubkey object', function() { - var pubkey = new Pubkey(); - pubkey.fromDER(new Buffer('0285e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004', - 'hex')); - var a = Address.fromPubkey(pubkey); - a.toString().should.equal('19gH5uhqY6DKrtkU66PsZPUZdzTd11Y7ke'); - var b = new Address(pubkey); - b.toString().should.equal('19gH5uhqY6DKrtkU66PsZPUZdzTd11Y7ke'); + it('should make this address from a compressed pubkey', function() { + var pubkey = Pubkey.fromDER(new Buffer('0285e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004', 'hex')); + var address = Address.fromPubkey(pubkey); + address.toString().should.equal('19gH5uhqY6DKrtkU66PsZPUZdzTd11Y7ke'); }); it('should make this address from an uncompressed pubkey', function() { - var pubkey = new Pubkey(); - pubkey.fromDER(new Buffer('0285e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004', - 'hex')); - pubkey.compressed = false; - var a = Address.fromPubkey(pubkey, 'mainnet', 'pubkeyhash'); + var pubkey = Pubkey.fromDER(new Buffer('0485e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004833fef26c8be4c4823754869ff4e46755b85d851077771c220e2610496a29d98', 'hex')); + var a = Address.fromPubkey(pubkey, 'mainnet'); a.toString().should.equal('16JXnhxjJUhxfyx4y6H4sFcxrgt8kQ8ewX'); var b = new Address(pubkey, 'mainnet', 'pubkeyhash'); b.toString().should.equal('16JXnhxjJUhxfyx4y6H4sFcxrgt8kQ8ewX'); @@ -310,7 +303,7 @@ describe('Address', function() { var address = new Address(str); var buffer = address.toBuffer(); var slice = buffer.slice(1); - var sliceString = slice.toString('hex') + var sliceString = slice.toString('hex'); sliceString.should.equal(pubkeyhash.toString('hex')); }); diff --git a/test/privkey.js b/test/privkey.js index 497fc9cce..1420f800e 100644 --- a/test/privkey.js +++ b/test/privkey.js @@ -5,7 +5,7 @@ var bitcore = require('..'); var BN = bitcore.crypto.BN; var Point = bitcore.crypto.Point; var Privkey = bitcore.Privkey; -var Pubkey = bitcore.Pubkey; +var base58check = bitcore.encoding.Base58Check; describe('Privkey', function() { var hex = '96c132224121b509b7d0a16245e957d9192609c5637c6228311287b1be21627a'; @@ -15,9 +15,78 @@ describe('Privkey', function() { var encmainnet = 'L2Gkw3kKJ6N24QcDuH4XDqt9cTqsKTVNDGz1CRZhk9cq4auDUbJy'; var encmu = '5JxgQaFM1FMd38cd14e3mbdxsdSa9iM2BV6DHBYsvGzxkTNQ7Un'; - it('should create an empty private key', function() { - var privkey = new Privkey(); - should.exist(privkey); + it('should create a new random private key', function() { + var a = new Privkey(); + should.exist(a); + should.exist(a.bn); + var b = Privkey(); + should.exist(b); + should.exist(b.bn); + }); + + it('should create a private key from WIF string', function() { + var a = new Privkey('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m'); + should.exist(a); + should.exist(a.bn); + }); + + it('should create a private key from WIF buffer', function() { + var a = new Privkey(base58check.decode('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m')); + should.exist(a); + should.exist(a.bn); + }); + + it('should not be able to instantiate private key greater than N', function() { + (function() { + var n = Point.getN(); + var a = new Privkey(n); + }).should.throw('Number must be less than N'); + }); + + it('should not be able to instantiate private key because of network mismatch', function() { + (function() { + var a = new Privkey('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m', 'testnet'); + }).should.throw('Private key network mismatch'); + }); + + it('should not be able to instantiate private key because of compression mismatch', function() { + (function() { + var a = new Privkey('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m', 'mainnet', false); + }).should.throw('Private key compression mismatch'); + }); + + it('should not be able to instantiate private key WIF is too long', function() { + (function() { + var buf = base58check.decode('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m'); + var buf2 = Buffer.concat([buf, new Buffer(0x01)]); + var a = new Privkey(buf2); + }).should.throw('Length of buffer must be 33 (uncompressed) or 34 (compressed'); + }); + + it('should not be able to instantiate private key WIF because of unknown network byte', function() { + (function() { + var buf = base58check.decode('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m'); + var buf2 = Buffer.concat([new Buffer(0x01, 'hex'), buf.slice(1, 33)]); + var a = new Privkey(buf2); + }).should.throw('Invalid network'); + }); + + it('should not be able to instantiate because compressed is non-boolean', function() { + (function() { + var a = new Privkey(null, 'testnet', 'compressed'); + }).should.throw('Must specify whether the corresponding public key is compressed or not (true or false)'); + }); + + it('should not be able to instantiate because of unrecognized data', function() { + (function() { + var a = new Privkey(new Error()); + }).should.throw('First argument is an unrecognized data type.'); + }); + + it('should not be able to instantiate with unknown network', function() { + (function() { + var a = new Privkey(null, 'unknown'); + }).should.throw('Must specify the network ("mainnet" or "testnet")'); }); it('should create a 0 private key with this convenience method', function() { @@ -27,47 +96,24 @@ describe('Privkey', function() { }); it('should create a mainnet private key', function() { - var privkey = new Privkey({ - bn: BN.fromBuffer(buf), - networkstr: 'mainnet', - compressed: true - }); + var privkey = new Privkey(BN.fromBuffer(buf), 'mainnet', true); privkey.toString().should.equal(encmainnet); }); it('should create an uncompressed testnet private key', function() { - var privkey = new Privkey({ - bn: BN.fromBuffer(buf), - networkstr: 'testnet', - compressed: false - }); + var privkey = new Privkey(BN.fromBuffer(buf), 'testnet', false); privkey.toString().should.equal(enctu); }); it('should create an uncompressed mainnet private key', function() { - var privkey = new Privkey({ - bn: BN.fromBuffer(buf), - networkstr: 'mainnet', - compressed: false - }); + var privkey = new Privkey(BN.fromBuffer(buf), 'mainnet', false); privkey.toString().should.equal(encmu); }); - describe('#set', function() { - - it('should set bn', function() { - should.exist(Privkey().set({ - bn: BN.fromBuffer(buf) - }).bn); - }); - - }); - describe('#fromJSON', function() { it('should input this address correctly', function() { - var privkey = new Privkey(); - privkey.fromJSON(encmu); + var privkey = Privkey.fromJSON(encmu); privkey.toWIF().should.equal(encmu); }); @@ -76,17 +122,80 @@ describe('Privkey', function() { describe('#toString', function() { it('should output this address correctly', function() { - var privkey = new Privkey(); - privkey.fromJSON(encmu); + var privkey = Privkey.fromJSON(encmu); privkey.toJSON().should.equal(encmu); }); }); + describe('#toAddress', function() { + it('should output this known mainnet address correctly', function() { + var privkey = Privkey.fromWIF('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m'); + var address = privkey.toAddress(); + address.toString().should.equal('1A6ut1tWnUq1SEQLMr4ttDh24wcbJ5o9TT'); + }); + + it('should output this known testnet address correctly', function() { + var privkey = Privkey.fromWIF('cR4qogdN9UxLZJXCNFNwDRRZNeLRWuds9TTSuLNweFVjiaE4gPaq'); + var address = privkey.toAddress(); + address.toString().should.equal('mtX8nPZZdJ8d3QNLRJ1oJTiEi26Sj6LQXS'); + }); + + }); + + describe('#inspect', function() { + it('should output known mainnet address for console', function() { + var privkey = Privkey.fromWIF('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m'); + privkey.inspect().should.equal(''); + }); + + it('should output known testnet address for console', function() { + var privkey = Privkey.fromWIF('cR4qogdN9UxLZJXCNFNwDRRZNeLRWuds9TTSuLNweFVjiaE4gPaq'); + privkey.inspect().should.equal(''); + }); + + }); + + describe('#getValidationError', function(){ + it('should get an error because private key greater than N', function() { + var n = Point.getN(); + var a = Privkey.getValidationError(n); + a.message.should.equal('Number must be less than N'); + }); + + it('should validate as false because private key greater than N', function() { + var n = Point.getN(); + var a = Privkey.isValid(n); + a.should.equal(false); + }); + + it('should validate as true', function() { + var a = Privkey.isValid('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m'); + a.should.equal(true); + }); + + }); + + describe('#toBuffer', function() { + it('should output known buffer', function() { + var privkey = new Privkey(BN.fromBuffer(buf), 'mainnet', true); + var b = privkey.toBuffer().toString('hex').should.equal(buf.toString('hex')); + }); + }); + + describe('#toBigNumber', function() { + it('should output known BN', function() { + var a = BN.fromBuffer(buf); + var privkey = new Privkey(a, 'mainnet', true); + var b = privkey.toBigNumber(); + b.toString('hex').should.equal(a.toString('hex')); + }); + }); + describe('#fromRandom', function() { it('should set bn gt 0 and lt n, and should be compressed', function() { - var privkey = Privkey().fromRandom(); + var privkey = Privkey.fromRandom(); privkey.bn.gt(BN(0)).should.equal(true); privkey.bn.lt(Point.getN()).should.equal(true); privkey.compressed.should.equal(true); @@ -97,8 +206,7 @@ describe('Privkey', function() { describe('#fromWIF', function() { it('should parse this compressed testnet address correctly', function() { - var privkey = new Privkey(); - privkey.fromWIF(encmainnet); + var privkey = Privkey.fromWIF(encmainnet); privkey.toWIF().should.equal(encmainnet); }); @@ -107,8 +215,7 @@ describe('Privkey', function() { describe('#toWIF', function() { it('should parse this compressed testnet address correctly', function() { - var privkey = new Privkey(); - privkey.fromWIF(enctestnet); + var privkey = Privkey.fromWIF(enctestnet); privkey.toWIF().should.equal(enctestnet); }); @@ -117,8 +224,7 @@ describe('Privkey', function() { describe('#fromString', function() { it('should parse this uncompressed testnet address correctly', function() { - var privkey = new Privkey(); - privkey.fromString(enctu); + var privkey = Privkey.fromString(enctu); privkey.toWIF().should.equal(enctu); }); @@ -127,8 +233,7 @@ describe('Privkey', function() { describe('#toString', function() { it('should parse this uncompressed mainnet address correctly', function() { - var privkey = new Privkey(); - privkey.fromString(encmu); + var privkey = Privkey.fromString(encmu); privkey.toString().should.equal(encmu); }); @@ -139,18 +244,14 @@ describe('Privkey', function() { it('should convert this known Privkey to known Pubkey', function() { var privhex = '906977a061af29276e40bf377042ffbde414e496ae2260bbf1fa9d085637bfff'; var pubhex = '02a1633cafcc01ebfb6d78e39f687a1f0995c62fc95f51ead10a02ee0be551b5dc'; - var privkey = new Privkey({ - bn: BN(new Buffer(privhex, 'hex')) - }); + var privkey = new Privkey(BN(new Buffer(privhex, 'hex'))); var pubkey = privkey.toPubkey(); pubkey.toString().should.equal(pubhex); }); it('should convert this known Privkey to known Pubkey and preserve compressed=true', function() { var privhex = '906977a061af29276e40bf377042ffbde414e496ae2260bbf1fa9d085637bfff'; - var privkey = new Privkey({ - bn: BN(new Buffer(privhex, 'hex')) - }); + var privkey = new Privkey(BN(new Buffer(privhex, 'hex'))); privkey.compressed = true; var pubkey = privkey.toPubkey(); pubkey.compressed.should.equal(true); @@ -158,9 +259,7 @@ describe('Privkey', function() { it('should convert this known Privkey to known Pubkey and preserve compressed=true', function() { var privhex = '906977a061af29276e40bf377042ffbde414e496ae2260bbf1fa9d085637bfff'; - var privkey = new Privkey({ - bn: BN(new Buffer(privhex, 'hex')) - }); + var privkey = new Privkey(BN(new Buffer(privhex, 'hex'))); privkey.compressed = false; var pubkey = privkey.toPubkey(); pubkey.compressed.should.equal(false); diff --git a/test/pubkey.js b/test/pubkey.js index be96a16e9..80fecf422 100644 --- a/test/pubkey.js +++ b/test/pubkey.js @@ -8,38 +8,101 @@ var Pubkey = bitcore.Pubkey; var Privkey = bitcore.Privkey; describe('Pubkey', function() { + + it('should error because of missing data', function() { + (function() { + var pk = new Pubkey(); + }).should.throw('First argument is required, please include public key data.'); + }); - it('should create a blank public key', function() { - var pk = new Pubkey(); - should.exist(pk); + it('should error because of an invalid point', function() { + (function() { + var pk = new Pubkey(Point()); + }).should.throw('Point cannot be equal to 0, 0'); + }); + + it('should error because of an invalid public key point, not on the secp256k1 curve', function() { + (function() { + var pk = new Pubkey(Point(1000, 1000)); + }).should.throw('Invalid y value of public key'); + }); + + it('should error because of an unrecognized data type', function() { + (function() { + var pk = new Pubkey(new Error()); + }).should.throw('First argument is an unrecognized data format.'); + }); + + it('should instantiate from a private key', function() { + var privhex = '906977a061af29276e40bf377042ffbde414e496ae2260bbf1fa9d085637bfff'; + var pubhex = '02a1633cafcc01ebfb6d78e39f687a1f0995c62fc95f51ead10a02ee0be551b5dc'; + var privkey = new Privkey(BN(new Buffer(privhex, 'hex'))); + var pk = new Pubkey(privkey); + pk.toString().should.equal(pubhex); + }); + + it('should instantiate from a hex encoded DER string', function() { + var pk = new Pubkey('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); + should.exist(pk.point); + pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); + }); + + it('should instantiate from a hex encoded DER buffer', function() { + var pk = new Pubkey(new Buffer('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341', 'hex')); + should.exist(pk.point); + pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); }); it('should create a public key with a point', function() { - var p = Point(); - var pk = new Pubkey({point: p}); - should.exist(pk.point); + var p = Point('86a80a5a2bfc48dddde2b0bd88bd56b0b6ddc4e6811445b175b90268924d7d48', + '3b402dfc89712cfe50963e670a0598e6b152b3cd94735001cdac6794975d3afd'); + var a = new Pubkey(p); + should.exist(a.point); + a.point.toString().should.equal(p.toString()); + var c = Pubkey(p); + should.exist(c.point); + c.point.toString().should.equal(p.toString()); }); - it('should create a public key with a point with this convenient method', function() { - var p = Point(); - var pk = new Pubkey(p); - should.exist(pk.point); - pk.point.toString().should.equal(p.toString()); - }); - - describe('#set', function() { - - it('should make a public key from a point', function() { - should.exist(Pubkey().set({point: Point.getG()}).point); + describe('#getValidationError', function(){ + it('should recieve an error message', function() { + var error = Pubkey.getValidationError(Point()); + should.exist(error); }); + it('should recieve a boolean as false', function() { + var valid = Pubkey.isValid(Point()); + valid.should.equal(false); + }); + + it('should recieve a boolean as true', function() { + var valid = Pubkey.isValid('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); + valid.should.equal(true); + }); + + }); + + describe('#fromPoint', function() { + + it('should instantiate from a point', function() { + var p = Point('86a80a5a2bfc48dddde2b0bd88bd56b0b6ddc4e6811445b175b90268924d7d48', + '3b402dfc89712cfe50963e670a0598e6b152b3cd94735001cdac6794975d3afd'); + var b = Pubkey.fromPoint(p); + should.exist(b.point); + b.point.toString().should.equal(p.toString()); + }); + + it('should error because paramater is not a point', function() { + (function() { + Pubkey.fromPoint(new Error()); + }).should.throw('First argument must be an instance of Point.'); + }); }); describe('#fromJSON', function() { it('should input this public key', function() { - var pk = new Pubkey(); - pk.fromJSON('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); + var pk = Pubkey.fromJSON('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); pk.point.getY().toString(16).should.equal('7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); }); @@ -49,9 +112,9 @@ describe('Pubkey', function() { describe('#toJSON', function() { it('should output this pubkey', function() { - var pk = new Pubkey(); var hex = '041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'; - pk.fromJSON(hex).toJSON().should.equal(hex); + var pk = Pubkey.fromJSON(hex); + pk.toJSON().should.equal(hex); }); }); @@ -59,7 +122,13 @@ describe('Pubkey', function() { describe('#fromPrivkey', function() { it('should make a public key from a privkey', function() { - should.exist(Pubkey().fromPrivkey(Privkey().fromRandom())); + should.exist(Pubkey.fromPrivkey(Privkey.fromRandom())); + }); + + it('should error because not an instance of privkey', function() { + (function() { + Pubkey.fromPrivkey(new Error()); + }).should.throw('Must be an instance of Privkey'); }); }); @@ -67,48 +136,54 @@ describe('Pubkey', function() { describe('#fromBuffer', function() { it('should parse this uncompressed public key', function() { - var pk = new Pubkey(); - pk.fromBuffer(new Buffer('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341', 'hex')); + var pk = Pubkey.fromBuffer(new Buffer('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341', 'hex')); pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); pk.point.getY().toString(16).should.equal('7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); }); it('should parse this compressed public key', function() { - var pk = new Pubkey(); - pk.fromBuffer(new Buffer('031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); + var pk = Pubkey.fromBuffer(new Buffer('031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); pk.point.getY().toString(16).should.equal('7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); }); it('should throw an error on this invalid public key', function() { - var pk = new Pubkey(); (function() { - pk.fromBuffer(new Buffer('091ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); + Pubkey.fromBuffer(new Buffer('091ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); }).should.throw(); }); + it('should throw error because not a buffer', function() { + (function() { + Pubkey.fromBuffer('091ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); + }).should.throw('Must be a hex buffer of DER encoded public key'); + }); + + it('should throw error because buffer is the incorrect length', function() { + (function() { + Pubkey.fromBuffer(new Buffer('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a34112', 'hex')); + }).should.throw('Length of x and y must be 32 bytes'); + }); + }); describe('#fromDER', function() { it('should parse this uncompressed public key', function() { - var pk = new Pubkey(); - pk.fromDER(new Buffer('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341', 'hex')); + var pk = Pubkey.fromDER(new Buffer('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341', 'hex')); pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); pk.point.getY().toString(16).should.equal('7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); }); it('should parse this compressed public key', function() { - var pk = new Pubkey(); - pk.fromDER(new Buffer('031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); + var pk = Pubkey.fromDER(new Buffer('031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); pk.point.getY().toString(16).should.equal('7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); }); it('should throw an error on this invalid public key', function() { - var pk = new Pubkey(); (function() { - pk.fromDER(new Buffer('091ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); + Pubkey.fromDER(new Buffer('091ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); }).should.throw(); }); @@ -117,8 +192,7 @@ describe('Pubkey', function() { describe('#fromString', function() { it('should parse this known valid public key', function() { - var pk = new Pubkey(); - pk.fromString('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); + var pk = Pubkey.fromString('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); pk.point.getY().toString(16).should.equal('7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); }); @@ -129,20 +203,26 @@ describe('Pubkey', function() { it('should create this known public key', function() { var x = BN.fromBuffer(new Buffer('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); - var pk = new Pubkey(); - pk.fromX(true, x); + var pk = Pubkey.fromX(true, x); pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); pk.point.getY().toString(16).should.equal('7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); }); + + it('should error because odd was not included as a param', function() { + var x = BN.fromBuffer(new Buffer('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); + (function() { + var pk = Pubkey.fromX(null, x); + }).should.throw('Must specify whether y is odd or not (true or false)'); + }); + }); describe('#toBuffer', function() { it('should return this compressed DER format', function() { var x = BN.fromBuffer(new Buffer('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); - var pk = new Pubkey(); - pk.fromX(true, x); + var pk = Pubkey.fromX(true, x); pk.toBuffer().toString('hex').should.equal('031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); }); @@ -152,54 +232,66 @@ describe('Pubkey', function() { it('should return this compressed DER format', function() { var x = BN.fromBuffer(new Buffer('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); - var pk = new Pubkey(); - pk.fromX(true, x); + var pk = Pubkey.fromX(true, x); pk.toDER(true).toString('hex').should.equal('031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); }); it('should return this uncompressed DER format', function() { var x = BN.fromBuffer(new Buffer('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); - var pk = new Pubkey(); - pk.fromX(true, x); + var pk = Pubkey.fromX(true, x); pk.toDER(false).toString('hex').should.equal('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); }); + it('should error because compressed param is invalid', function() { + var x = BN.fromBuffer(new Buffer('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); + var pk = Pubkey.fromX(true, x); + (function() { + pk.toDER('false'); //string not boolean + }).should.throw('Must specify whether the public key is compressed or not (true or false)'); + }); + }); describe('#toString', function() { it('should print this known public key', function() { var hex = '031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'; - var pk = new Pubkey(); - pk.fromString(hex); + var pk = Pubkey.fromString(hex); pk.toString().should.equal(hex); }); }); + describe('#inspect', function() { + it('should output known uncompressed pubkey for console', function() { + var pubkey = Pubkey.fromString('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); + pubkey.inspect().should.equal(''); + }); + + it('should output known compressed pubkey for console', function() { + var pubkey = Pubkey.fromString('031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); + pubkey.inspect().should.equal(''); + }); + + }); + describe('#validate', function() { - it('should not throw an error if pubkey is valid', function() { + it('should not have an error if pubkey is valid', function() { var hex = '031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'; - var pk = new Pubkey(); - pk.fromString(hex); - should.exist(pk.validate()); + var pk = Pubkey.fromString(hex); }); - it('should not throw an error if pubkey is invalid', function() { + it('should throw an error if pubkey is invalid', function() { var hex = '041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a0000000000000000000000000000000000000000000000000000000000000000'; - var pk = new Pubkey(); - pk.fromString(hex); (function() { - pk.validate(); + var pk = Pubkey.fromString(hex); }).should.throw('Invalid y value of public key'); }); - it('should not throw an error if pubkey is infinity', function() { - var pk = new Pubkey(); - pk.point = Point.getG().mul(Point.getN()); + it('should throw an error if pubkey is infinity', function() { (function() { - pk.validate(); + var pk = new Pubkey(Point.getG().mul(Point.getN())); }).should.throw('Point cannot be equal to Infinity'); }); From 85ce140aebb450ebd5090770ceaed7cd0f88fa0c Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Tue, 25 Nov 2014 13:21:53 -0500 Subject: [PATCH 2/4] Keys: Renamed Privkey to PrivateKey and Pubkey to PublicKey --- index.js | 4 +- lib/address.js | 28 +++--- lib/bip32.js | 24 ++--- lib/crypto/ecdsa.js | 4 +- lib/networks.js | 4 +- lib/{privkey.js => privatekey.js} | 122 ++++++++++++------------ lib/{pubkey.js => publickey.js} | 146 ++++++++++++++--------------- lib/script.js | 8 +- test/address.js | 22 ++--- test/crypto/ecdsa.js | 12 +-- test/{privkey.js => privatekey.js} | 92 +++++++++--------- test/{pubkey.js => publickey.js} | 94 +++++++++---------- test/script.js | 22 ++--- 13 files changed, 291 insertions(+), 291 deletions(-) rename lib/{privkey.js => privatekey.js} (61%) rename lib/{pubkey.js => publickey.js} (60%) rename test/{privkey.js => privatekey.js} (69%) rename test/{pubkey.js => publickey.js} (71%) diff --git a/index.js b/index.js index e6cfd6621..47092f77e 100644 --- a/index.js +++ b/index.js @@ -24,8 +24,8 @@ bitcore.Block = require('./lib/block'); bitcore.Blockheader = require('./lib/blockheader'); bitcore.Networks = require('./lib/networks'); bitcore.Opcode = require('./lib/opcode'); -bitcore.Privkey = require('./lib/privkey'); -bitcore.Pubkey = require('./lib/pubkey'); +bitcore.PrivateKey = require('./lib/privatekey'); +bitcore.PublicKey = require('./lib/publickey'); bitcore.Script = require('./lib/script'); bitcore.Signature = require('./lib/signature'); bitcore.Transaction = require('./lib/transaction'); diff --git a/lib/address.js b/lib/address.js index 5cf22a4aa..9d9185ce7 100644 --- a/lib/address.js +++ b/lib/address.js @@ -9,7 +9,7 @@ var Hash = require('./crypto/hash'); * Bitcore Address * * Instantiate an address from an address String or Buffer, a public key or script hash Buffer, - * or an instance of Pubkey or Script. + * or an instance of PublicKey or Script. * * @example * @@ -45,8 +45,8 @@ function Address(data, network, type) { info = Address._transformHash(data); } else if ((data instanceof Buffer || data instanceof Uint8Array) && data.length === 21) { info = Address._transformBuffer(data, network, type); - } else if (data.constructor && (data.constructor.name && data.constructor.name === 'Pubkey')) { - info = Address._transformPubkey(data); + } else if (data.constructor && (data.constructor.name && data.constructor.name === 'PublicKey')) { + info = Address._transformPublicKey(data); } else if (data.constructor && (data.constructor.name && data.constructor.name === 'Script')) { info = Address._transformScript(data); } else if (typeof(data) === 'string') { @@ -146,15 +146,15 @@ Address._transformBuffer = function(buffer, network, type){ /** * - * Internal function to transform a Pubkey + * Internal function to transform a PublicKey * - * @param {Pubkey} pubkey - An instance of Pubkey + * @param {PublicKey} pubkey - An instance of PublicKey * @returns {Object} An object with keys: hashBuffer, type */ -Address._transformPubkey = function(pubkey){ +Address._transformPublicKey = function(pubkey){ var info = {}; - if (!pubkey.constructor || (pubkey.constructor.name && pubkey.constructor.name !== 'Pubkey')) { - throw new TypeError('Address must be an instance of Pubkey.'); + if (!pubkey.constructor || (pubkey.constructor.name && pubkey.constructor.name !== 'PublicKey')) { + throw new TypeError('Address must be an instance of PublicKey.'); } info.hashBuffer = Hash.sha256ripemd160(pubkey.toBuffer()); info.type = 'pubkeyhash'; @@ -182,7 +182,7 @@ Address._transformScript = function(script){ * * Internal function to transform a bitcoin address string * - * @param {String} data - An instance of Pubkey + * @param {String} data - An instance of PublicKey * @param {String} [network] - The network: 'mainnet' or 'testnet' * @param {String} [type] - The type: 'pubkeyhash' or 'scripthash' * @returns {Object} An object with keys: hashBuffer, network and type @@ -198,14 +198,14 @@ Address._transformString = function(data, network, type){ /** * - * Instantiate an address from a Pubkey instance + * Instantiate an address from a PublicKey instance * - * @param {String} data - An instance of Pubkey + * @param {String} data - An instance of PublicKey * @param {String} network - The network: 'mainnet' or 'testnet' * @returns {Address} A new valid and frozen instance of an Address */ -Address.fromPubkey = function(data, network){ - var info = Address._transformPubkey(data); +Address.fromPublicKey = function(data, network){ + var info = Address._transformPublicKey(data); return new Address(info.hashBuffer, network, info.type); }; @@ -217,7 +217,7 @@ Address.fromPubkey = function(data, network){ * @param {String} network - The network: 'mainnet' or 'testnet' * @returns {Address} A new valid and frozen instance of an Address */ -Address.fromPubkeyHash = function(hash, network) { +Address.fromPublicKeyHash = function(hash, network) { var info = Address._transformHash(hash); return new Address(info.hashBuffer, network, 'pubkeyhash'); }; diff --git a/lib/bip32.js b/lib/bip32.js index 157c80443..ab5891a68 100644 --- a/lib/bip32.js +++ b/lib/bip32.js @@ -6,8 +6,8 @@ var Hash = require('./crypto/hash'); var Point = require('./crypto/point'); var Random = require('./crypto/random'); var BN = require('./crypto/bn'); -var Pubkey = require('./pubkey'); -var Privkey = require('./privkey'); +var PublicKey = require('./publickey'); +var PrivateKey = require('./privatekey'); var BIP32 = function BIP32(obj) { if (!(this instanceof BIP32)) @@ -41,8 +41,8 @@ BIP32.prototype.fromRandom = function(networkstr) { this.parentfingerprint = new Buffer([0, 0, 0, 0]); this.childindex = new Buffer([0, 0, 0, 0]); this.chaincode = Random.getRandomBuffer(32); - this.privkey = Privkey.fromRandom(); - this.pubkey = Pubkey.fromPrivkey(this.privkey); + this.privkey = PrivateKey.fromRandom(); + this.pubkey = PublicKey.fromPrivateKey(this.privkey); this.hasprivkey = true; this.pubkeyhash = Hash.sha256ripemd160(this.pubkey.toBuffer()); this.buildxpubkey(); @@ -72,8 +72,8 @@ BIP32.prototype.fromSeed = function(bytes, networkstr) { this.childindex = new Buffer([0, 0, 0, 0]); this.chaincode = hash.slice(32, 64); this.version = networks[networkstr].bip32privkey; - this.privkey = new Privkey(BN().fromBuffer(hash.slice(0, 32))); - this.pubkey = Pubkey.fromPrivkey(this.privkey); + this.privkey = new PrivateKey(BN().fromBuffer(hash.slice(0, 32))); + this.pubkey = PublicKey.fromPrivateKey(this.privkey); this.hasprivkey = true; this.pubkeyhash = Hash.sha256ripemd160(this.pubkey.toBuffer()); @@ -105,12 +105,12 @@ BIP32.prototype.initFromBytes = function(bytes) { this.version == networks.testnet.bip32pubkey); if (isPrivate && keyBytes[0] == 0) { - this.privkey = new Privkey(BN().fromBuffer(keyBytes.slice(1, 33))); - this.pubkey = Pubkey.fromPrivkey(this.privkey); + this.privkey = new PrivateKey(BN().fromBuffer(keyBytes.slice(1, 33))); + this.pubkey = PublicKey.fromPrivateKey(this.privkey); this.pubkeyhash = Hash.sha256ripemd160(this.pubkey.toBuffer()); this.hasprivkey = true; } else if (isPublic && (keyBytes[0] == 0x02 || keyBytes[0] == 0x03)) { - this.pubkey = Pubkey.fromDER(keyBytes); + this.pubkey = PublicKey.fromDER(keyBytes); this.pubkeyhash = Hash.sha256ripemd160(this.pubkey.toBuffer()); this.hasprivkey = false; } else { @@ -270,8 +270,8 @@ BIP32.prototype.deriveChild = function(i) { ret = new BIP32(); ret.chaincode = ir; - ret.privkey = new Privkey(k); - ret.pubkey = Pubkey.fromPrivkey(ret.privkey); + ret.privkey = new PrivateKey(k); + ret.pubkey = PublicKey.fromPrivateKey(ret.privkey); ret.hasprivkey = true; } else { @@ -284,7 +284,7 @@ BIP32.prototype.deriveChild = function(i) { var ilG = Point.getG().mul(il); var Kpar = this.pubkey.point; var Ki = ilG.add(Kpar); - var newpub = Pubkey.fromPoint(Ki); + var newpub = PublicKey.fromPoint(Ki); ret = new BIP32(); ret.chaincode = ir; diff --git a/lib/crypto/ecdsa.js b/lib/crypto/ecdsa.js index 886af0240..3f9c3d6a1 100644 --- a/lib/crypto/ecdsa.js +++ b/lib/crypto/ecdsa.js @@ -3,7 +3,7 @@ var BN = require('./bn'); var Point = require('./point'); var Random = require('./random'); -var Pubkey = require('../pubkey'); +var PublicKey = require('../publickey'); var Signature = require('../signature'); var ECDSA = function ECDSA(obj) { @@ -106,7 +106,7 @@ ECDSA.prototype.sig2pubkey = function() { //var Q = R.multiplyTwo(s, G, eNeg).mul(rInv); var Q = R.mul(s).add(G.mul(eNeg)).mul(rInv); - var pubkey = new Pubkey({point: Q}); + var pubkey = new PublicKey({point: Q}); pubkey.compressed = this.sig.compressed; pubkey.validate(); diff --git a/lib/networks.js b/lib/networks.js index 97afe9c45..7eee84e6b 100644 --- a/lib/networks.js +++ b/lib/networks.js @@ -5,7 +5,7 @@ exports.mainnet = { identity: 0x0f, identephem: 0x02, identpersist: 0x01, - privkey: 0x80, + privatekey: 0x80, scripthash: 0x05, bip32pubkey: 0x0488b21e, bip32privkey: 0x0488ade4, @@ -16,7 +16,7 @@ exports.testnet = { identity: 0x0f, identephem: 0x02, identpersist: 0x11, - privkey: 0xef, + privatekey: 0xef, scripthash: 0xc4, bip32pubkey: 0x043587cf, bip32privkey: 0x04358394, diff --git a/lib/privkey.js b/lib/privatekey.js similarity index 61% rename from lib/privkey.js rename to lib/privatekey.js index a2203fdbc..f064f3670 100644 --- a/lib/privkey.js +++ b/lib/privatekey.js @@ -6,27 +6,27 @@ var Random = require('./crypto/random'); var networks = require('./networks'); var base58check = require('./encoding/base58check'); var Address = require('./address'); -var Pubkey = require('./pubkey'); +var PublicKey = require('./publickey'); /** * - * Bitcore Privkey + * Bitcore PrivateKey * - * Instantiate a Privkey from a BN, Buffer and WIF. + * Instantiate a PrivateKey from a BN, Buffer and WIF. * * @example * - * var privkey = new Privkey(); + * var privateKey = new PrivateKey(); * * @param {String} data - The encoded data in various formats * @param {String} [network] - Either "mainnet" or "testnet" * @param {Boolean} [compressed] - If the key is in compressed format - * @returns {Privkey} A new valid instance of an Privkey + * @returns {PrivateKey} A new valid instance of an PrivateKey */ -var Privkey = function Privkey(data, network, compressed) { +var PrivateKey = function PrivateKey(data, network, compressed) { - if (!(this instanceof Privkey)) { - return new Privkey(data, network, compressed); + if (!(this instanceof PrivateKey)) { + return new PrivateKey(data, network, compressed); } var info = { @@ -36,13 +36,13 @@ var Privkey = function Privkey(data, network, compressed) { // detect type of data if (!data){ - info.bn = Privkey._getRandomBN(); + info.bn = PrivateKey._getRandomBN(); } else if (data instanceof BN) { info.bn = data; } else if (data instanceof Buffer) { - info = Privkey._transformBuffer(data, network, compressed); + info = PrivateKey._transformBuffer(data, network, compressed); } else if (typeof(data) === 'string'){ - info = Privkey._transformWIF(data, network, compressed); + info = PrivateKey._transformWIF(data, network, compressed); } else { throw new TypeError('First argument is an unrecognized data type.'); } @@ -72,7 +72,7 @@ var Privkey = function Privkey(data, network, compressed) { * * @returns {Object} An object with keys: bn, network and compressed */ -Privkey._getRandomBN = function(){ +PrivateKey._getRandomBN = function(){ var condition; var bn; do { @@ -92,7 +92,7 @@ Privkey._getRandomBN = function(){ * @param {String} [compressed] - If the private key is compressed * @returns {Object} An object with keys: bn, network and compressed */ -Privkey._transformBuffer = function(buf, network, compressed) { +PrivateKey._transformBuffer = function(buf, network, compressed) { var info = {}; @@ -104,9 +104,9 @@ Privkey._transformBuffer = function(buf, network, compressed) { throw new Error('Length of buffer must be 33 (uncompressed) or 34 (compressed)'); } - if (buf[0] === networks.mainnet.privkey) { + if (buf[0] === networks.mainnet.privatekey) { info.network = 'mainnet'; - } else if (buf[0] === networks.testnet.privkey) { + } else if (buf[0] === networks.testnet.privatekey) { info.network = 'testnet'; } else { throw new Error('Invalid network'); @@ -133,62 +133,62 @@ Privkey._transformBuffer = function(buf, network, compressed) { * @param {String} buf - An WIF string * @returns {Object} An object with keys: bn, network and compressed */ -Privkey._transformWIF = function(str, network, compressed) { - return Privkey._transformBuffer(base58check.decode(str), network, compressed); +PrivateKey._transformWIF = function(str, network, compressed) { + return PrivateKey._transformBuffer(base58check.decode(str), network, compressed); }; /** * - * Instantiate a Privkey from a WIF string + * Instantiate a PrivateKey from a WIF string * * @param {String} str - The WIF encoded private key string - * @returns {Privkey} A new valid instance of Privkey + * @returns {PrivateKey} A new valid instance of PrivateKey */ -Privkey.fromWIF = function(str) { - var info = Privkey._transformWIF(str); - return new Privkey(info.bn, info.network, info.compressed); +PrivateKey.fromWIF = function(str) { + var info = PrivateKey._transformWIF(str); + return new PrivateKey(info.bn, info.network, info.compressed); }; /** * - * Instantiate a Privkey from a WIF JSON string + * Instantiate a PrivateKey from a WIF JSON string * * @param {String} str - The WIF encoded private key string - * @returns {Privkey} A new valid instance of Privkey + * @returns {PrivateKey} A new valid instance of PrivateKey */ -Privkey.fromJSON = function(json) { - var info = Privkey._transformWIF(json); - return new Privkey(info.bn, info.network, info.compressed); +PrivateKey.fromJSON = function(json) { + var info = PrivateKey._transformWIF(json); + return new PrivateKey(info.bn, info.network, info.compressed); }; /** * - * Instantiate a Privkey from random bytes + * Instantiate a PrivateKey from random bytes * * @param {String} [network] - Either "mainnet" or "testnet" * @param {String} [compressed] - If the private key is compressed - * @returns {Privkey} A new valid instance of Privkey + * @returns {PrivateKey} A new valid instance of PrivateKey */ -Privkey.fromRandom = function(network, compressed) { - var bn = Privkey._getRandomBN(); - return new Privkey(bn, network, compressed); +PrivateKey.fromRandom = function(network, compressed) { + var bn = PrivateKey._getRandomBN(); + return new PrivateKey(bn, network, compressed); }; /** * - * Instantiate a Privkey from a WIF string + * Instantiate a PrivateKey from a WIF string * * @param {String} str - The WIF encoded private key string - * @returns {Privkey} A new valid instance of Privkey + * @returns {PrivateKey} A new valid instance of PrivateKey */ -Privkey.fromString = function(str) { - var info = Privkey._transformWIF(str); - return new Privkey(info.bn, info.network, info.compressed); +PrivateKey.fromString = function(str) { + var info = PrivateKey._transformWIF(str); + return new PrivateKey(info.bn, info.network, info.compressed); }; /** * - * Check if there would be any errors when initializing a Privkey + * Check if there would be any errors when initializing a PrivateKey * * @param {String} data - The encoded data in various formats * @param {String} [network] - Either "mainnet" or "testnet" @@ -196,10 +196,10 @@ Privkey.fromString = function(str) { * @returns {null|Error} An error if exists */ -Privkey.getValidationError = function(data, network, compressed) { +PrivateKey.getValidationError = function(data, network, compressed) { var error; try { - new Privkey(data, network, compressed); + new PrivateKey(data, network, compressed); } catch (e) { error = e; } @@ -215,27 +215,27 @@ Privkey.getValidationError = function(data, network, compressed) { * @param {String} [compressed] - If the private key is compressed * @returns {Boolean} If the private key is would be valid */ -Privkey.isValid = function(data, network, compressed){ - return !Privkey.getValidationError(data, network, compressed); +PrivateKey.isValid = function(data, network, compressed){ + return !PrivateKey.getValidationError(data, network, compressed); }; /** * - * Will output the Privkey to a WIF string + * Will output the PrivateKey to a WIF string * * @returns {String} A WIP representation of the private key */ -Privkey.prototype.toWIF = function() { +PrivateKey.prototype.toWIF = function() { var network = this.network; var compressed = this.compressed; var buf; if (compressed) { - buf = Buffer.concat([new Buffer([networks[network].privkey]), + buf = Buffer.concat([new Buffer([networks[network].privatekey]), this.bn.toBuffer({size: 32}), new Buffer([0x01])]); } else { - buf = Buffer.concat([new Buffer([networks[network].privkey]), + buf = Buffer.concat([new Buffer([networks[network].privatekey]), this.bn.toBuffer({size: 32})]); } @@ -248,7 +248,7 @@ Privkey.prototype.toWIF = function() { * * @returns {BN} A BN instance of the private key */ -Privkey.prototype.toBigNumber = function(){ +PrivateKey.prototype.toBigNumber = function(){ return this.bn; }; @@ -258,7 +258,7 @@ Privkey.prototype.toBigNumber = function(){ * * @returns {Buffer} A buffer of the private key */ -Privkey.prototype.toBuffer = function(){ +PrivateKey.prototype.toBuffer = function(){ return this.bn.toBuffer(); }; @@ -266,10 +266,10 @@ Privkey.prototype.toBuffer = function(){ * * Will return the corresponding public key * - * @returns {Pubkey} A public key generated from the private key + * @returns {PublicKey} A public key generated from the private key */ -Privkey.prototype.toPubkey = function(){ - return Pubkey.fromPrivkey(this); +PrivateKey.prototype.toPublicKey = function(){ + return PublicKey.fromPrivateKey(this); }; /** @@ -278,28 +278,28 @@ Privkey.prototype.toPubkey = function(){ * * @returns {Address} An address generated from the private key */ -Privkey.prototype.toAddress = function() { - var pubkey = this.toPubkey(); - return Address.fromPubkey(pubkey, this.network); +PrivateKey.prototype.toAddress = function() { + var pubkey = this.toPublicKey(); + return Address.fromPublicKey(pubkey, this.network); }; /** * - * Will output the Privkey to a WIF string + * Will output the PrivateKey to a WIF string * * @returns {String} A WIF representation of the private key */ -Privkey.prototype.toJSON = function() { +PrivateKey.prototype.toJSON = function() { return this.toString(); }; /** * - * Will output the Privkey to a WIF string + * Will output the PrivateKey to a WIF string * * @returns {String} A WIF representation of the private key */ -Privkey.prototype.toString = function() { +PrivateKey.prototype.toString = function() { return this.toWIF(); }; @@ -309,8 +309,8 @@ Privkey.prototype.toString = function() { * * @returns {String} Private key */ -Privkey.prototype.inspect = function() { - return ''; +PrivateKey.prototype.inspect = function() { + return ''; }; -module.exports = Privkey; +module.exports = PrivateKey; diff --git a/lib/pubkey.js b/lib/publickey.js similarity index 60% rename from lib/pubkey.js rename to lib/publickey.js index 77a1f0f00..194d5c238 100644 --- a/lib/pubkey.js +++ b/lib/publickey.js @@ -5,22 +5,22 @@ var BN = require('./crypto/bn'); /** * - * Bitcore Pubkey + * Bitcore PublicKey * - * Instantiate a Pubkey from a 'Privkey', 'Point', 'string', 'Buffer'. + * Instantiate a PublicKey from a 'PrivateKey', 'Point', 'string', 'Buffer'. * * @example * - * var pubkey = new Pubkey(privkey, true); + * var publicKey = new PublicKey(privkey, true); * * @param {String} data - The encoded data in various formats * @param {String} [compressed] - If the public key is compressed - * @returns {Pubkey} A new valid instance of an Pubkey + * @returns {PublicKey} A new valid instance of an PublicKey */ -var Pubkey = function Pubkey(data, compressed) { +var PublicKey = function PublicKey(data, compressed) { - if (!(this instanceof Pubkey)) { - return new Pubkey(data, compressed); + if (!(this instanceof PublicKey)) { + return new PublicKey(data, compressed); } if (!data) { @@ -35,12 +35,12 @@ var Pubkey = function Pubkey(data, compressed) { if (data instanceof Point) { info.point = data; } else if (typeof(data) === 'string'){ - info = Pubkey._transformDER(new Buffer(data, 'hex' )); + info = PublicKey._transformDER(new Buffer(data, 'hex' )); } else if (data instanceof Buffer){ - info = Pubkey._transformDER(data); + info = PublicKey._transformDER(data); } else if (data.constructor && (data.constructor.name && - data.constructor.name === 'Privkey')) { - info = Pubkey._transformPrivkey(data); + data.constructor.name === 'PrivateKey')) { + info = PublicKey._transformPrivateKey(data); } else { throw new TypeError('First argument is an unrecognized data format.'); } @@ -67,14 +67,14 @@ var Pubkey = function Pubkey(data, compressed) { * * Internal function to transform a private key into a public key point * - * @param {Privkey} privkey - An instance of Privkey + * @param {PrivateKey} privkey - An instance of PrivateKey * @returns {Object} An object with keys: point and compressed */ -Pubkey._transformPrivkey = function(privkey) { +PublicKey._transformPrivateKey = function(privkey) { var info = {}; if (!privkey.constructor || - (privkey.constructor.name && privkey.constructor.name !== 'Privkey')) { - throw new TypeError('Must be an instance of Privkey'); + (privkey.constructor.name && privkey.constructor.name !== 'PrivateKey')) { + throw new TypeError('Must be an instance of PrivateKey'); } info.point = Point.getG().mul(privkey.bn); info.compressed = privkey.compressed; @@ -88,7 +88,7 @@ Pubkey._transformPrivkey = function(privkey) { * @param {Buffer} buf - An hex encoded buffer * @returns {Object} An object with keys: point and compressed */ -Pubkey._transformDER = function(buf){ +PublicKey._transformDER = function(buf){ var info = {}; if (!(buf instanceof Buffer)){ throw new TypeError('Must be a hex buffer of DER encoded public key'); @@ -112,15 +112,15 @@ Pubkey._transformDER = function(buf){ } else if (buf[0] === 0x03) { xbuf = buf.slice(1); x = BN(xbuf); - info = Pubkey._transformX(true, x); + info = PublicKey._transformX(true, x); info.compressed = true; } else if (buf[0] == 0x02) { xbuf = buf.slice(1); x = BN(xbuf); - info = Pubkey._transformX(false, x); + info = PublicKey._transformX(false, x); info.compressed = true; } else { - throw new TypeError('Invalid DER format pubkey'); + throw new TypeError('Invalid DER format public key'); } return info; }; @@ -133,7 +133,7 @@ Pubkey._transformDER = function(buf){ * @param {Point} x - The x point * @returns {Object} An object with keys: point and compressed */ -Pubkey._transformX = function(odd, x){ +PublicKey._transformX = function(odd, x){ var info = {}; if (typeof odd !== 'boolean') { throw new TypeError('Must specify whether y is odd or not (true or false)'); @@ -144,107 +144,107 @@ Pubkey._transformX = function(odd, x){ /** * - * Instantiate a Pubkey from JSON + * Instantiate a PublicKey from JSON * - * @param {String} json - A JSON string of DER encoded pubkey - * @returns {Pubkey} A new valid instance of Pubkey + * @param {String} json - A JSON string of DER encoded public key + * @returns {PublicKey} A new valid instance of PublicKey */ -Pubkey.fromJSON = function(json) { +PublicKey.fromJSON = function(json) { var buf = new Buffer(json, 'hex'); - var info = Pubkey._transformDER(buf); - return new Pubkey(info.point, info.compressed); + var info = PublicKey._transformDER(buf); + return new PublicKey(info.point, info.compressed); }; /** * - * Instantiate a Pubkey from a Privkey + * Instantiate a PublicKey from a PrivateKey * - * @param {Privkey} privkey - An instance of Privkey - * @returns {Pubkey} A new valid instance of Pubkey + * @param {PrivateKey} privkey - An instance of PrivateKey + * @returns {PublicKey} A new valid instance of PublicKey */ -Pubkey.fromPrivkey = function(privkey) { - var info = Pubkey._transformPrivkey(privkey); - return new Pubkey(info.point, info.compressed); +PublicKey.fromPrivateKey = function(privkey) { + var info = PublicKey._transformPrivateKey(privkey); + return new PublicKey(info.point, info.compressed); }; /** * - * Instantiate a Pubkey from a Buffer + * Instantiate a PublicKey from a Buffer * * @param {Buffer} buf - A DER hex buffer - * @returns {Pubkey} A new valid instance of Pubkey + * @returns {PublicKey} A new valid instance of PublicKey */ -Pubkey.fromBuffer = function(buf) { - var info = Pubkey._transformDER(buf); - return new Pubkey(info.point, info.compressed); +PublicKey.fromBuffer = function(buf) { + var info = PublicKey._transformDER(buf); + return new PublicKey(info.point, info.compressed); }; /** * - * Instantiate a Pubkey from a Point + * Instantiate a PublicKey from a Point * * @param {Point} point - A Point instance - * @returns {Pubkey} A new valid instance of Pubkey + * @returns {PublicKey} A new valid instance of PublicKey */ -Pubkey.fromPoint = function(point){ +PublicKey.fromPoint = function(point){ if (!(point instanceof Point)) { throw new TypeError('First argument must be an instance of Point.'); } - return new Pubkey(point); + return new PublicKey(point); }; /** * - * Instantiate a Pubkey from a DER Buffer + * Instantiate a PublicKey from a DER Buffer * * @param {Buffer} buf - A DER Buffer - * @returns {Pubkey} A new valid instance of Pubkey + * @returns {PublicKey} A new valid instance of PublicKey */ -Pubkey.fromDER = function(buf) { - var info = Pubkey._transformDER(buf); - return new Pubkey(info.point, info.compressed); +PublicKey.fromDER = function(buf) { + var info = PublicKey._transformDER(buf); + return new PublicKey(info.point, info.compressed); }; /** * - * Instantiate a Pubkey from a DER hex encoded string + * Instantiate a PublicKey from a DER hex encoded string * * @param {String} str - A DER hex string * @param {String} [encoding] - The type of string encoding - * @returns {Pubkey} A new valid instance of Pubkey + * @returns {PublicKey} A new valid instance of PublicKey */ -Pubkey.fromString = function(str, encoding) { +PublicKey.fromString = function(str, encoding) { var buf = new Buffer(str, encoding || 'hex'); - var info = Pubkey._transformDER(buf); - return new Pubkey(info.point, info.compressed); + var info = PublicKey._transformDER(buf); + return new PublicKey(info.point, info.compressed); }; /** * - * Instantiate a Pubkey from an X Point + * Instantiate a PublicKey from an X Point * * @param {Boolean} odd - If the point is above or below the x axis * @param {Point} x - The x point - * @returns {Pubkey} A new valid instance of Pubkey + * @returns {PublicKey} A new valid instance of PublicKey */ -Pubkey.fromX = function(odd, x) { - var info = Pubkey._transformX(odd, x); - return new Pubkey(info.point, info.compressed); +PublicKey.fromX = function(odd, x) { + var info = PublicKey._transformX(odd, x); + return new PublicKey(info.point, info.compressed); }; /** * - * Check if there would be any errors when initializing a Pubkey + * Check if there would be any errors when initializing a PublicKey * * @param {String} data - The encoded data in various formats * @param {String} [compressed] - If the public key is compressed * @returns {null|Error} An error if exists */ -Pubkey.getValidationError = function(data, compressed) { +PublicKey.getValidationError = function(data, compressed) { var error; try { - new Pubkey(data, compressed); + new PublicKey(data, compressed); } catch (e) { error = e; } @@ -257,40 +257,40 @@ Pubkey.getValidationError = function(data, compressed) { * * @param {String} data - The encoded data in various formats * @param {String} [compressed] - If the public key is compressed - * @returns {Boolean} If the pubkey is would be valid + * @returns {Boolean} If the public key would be valid */ -Pubkey.isValid = function(data, compressed) { - return !Pubkey.getValidationError(data, compressed); +PublicKey.isValid = function(data, compressed) { + return !PublicKey.getValidationError(data, compressed); }; /** * - * Will output the Pubkey to JSON + * Will output the PublicKey to JSON * * @returns {String} A hex encoded string */ -Pubkey.prototype.toJSON = function() { +PublicKey.prototype.toJSON = function() { return this.toBuffer().toString('hex'); }; /** * - * Will output the Pubkey to a Buffer + * Will output the PublicKey to a Buffer * * @returns {Buffer} A DER hex encoded buffer */ -Pubkey.prototype.toBuffer = function() { +PublicKey.prototype.toBuffer = function() { var compressed = typeof this.compressed === 'undefined' ? true : this.compressed; return this.toDER(compressed); }; /** * - * Will output the Pubkey to a DER Buffer + * Will output the PublicKey to a DER Buffer * * @returns {Buffer} A DER hex encoded buffer */ -Pubkey.prototype.toDER = function(compressed) { +PublicKey.prototype.toDER = function(compressed) { compressed = typeof(compressed) !== 'undefined' ? compressed : this.compressed; if (typeof compressed !== 'boolean') { throw new TypeError('Must specify whether the public key is compressed or not (true or false)'); @@ -319,11 +319,11 @@ Pubkey.prototype.toDER = function(compressed) { /** * - * Will output the Pubkey to a DER encoded hex string + * Will output the PublicKey to a DER encoded hex string * * @returns {String} A DER hex encoded string */ -Pubkey.prototype.toString = function() { +PublicKey.prototype.toString = function() { var compressed = typeof this.compressed === 'undefined' ? true : this.compressed; return this.toDER(compressed).toString('hex'); }; @@ -334,8 +334,8 @@ Pubkey.prototype.toString = function() { * * @returns {String} Public key */ -Pubkey.prototype.inspect = function() { - return ''; +PublicKey.prototype.inspect = function() { + return ''; }; -module.exports = Pubkey; +module.exports = PublicKey; diff --git a/lib/script.js b/lib/script.js index 95a6ac4ce..a33a999aa 100644 --- a/lib/script.js +++ b/lib/script.js @@ -190,7 +190,7 @@ Script.prototype.isOpReturn = function() { } }; -Script.prototype.isPubkeyhashOut = function() { +Script.prototype.isPublicKeyHashOut = function() { if (this.chunks[0] === Opcode('OP_DUP').toNumber() && this.chunks[1] === Opcode('OP_HASH160').toNumber() && this.chunks[2].buf @@ -202,7 +202,7 @@ Script.prototype.isPubkeyhashOut = function() { } }; -Script.prototype.isPubkeyhashIn = function() { +Script.prototype.isPublicKeyHashIn = function() { if (this.chunks.length === 2 && this.chunks[0].buf && this.chunks[1].buf) { @@ -212,7 +212,7 @@ Script.prototype.isPubkeyhashIn = function() { } }; -Script.prototype.isScripthashOut = function() { +Script.prototype.isScriptHashOut = function() { if (this.chunks.length === 3 && this.chunks[0] === Opcode('OP_HASH160').toNumber() && this.chunks[1].buf @@ -225,7 +225,7 @@ Script.prototype.isScripthashOut = function() { }; //note that these are frequently indistinguishable from pubkeyhashin -Script.prototype.isScripthashIn = function() { +Script.prototype.isScriptHashIn = function() { var allpush = this.chunks.every(function(chunk) { return Buffer.isBuffer(chunk.buf); }); diff --git a/test/address.js b/test/address.js index b107be0f6..80f363f5c 100644 --- a/test/address.js +++ b/test/address.js @@ -3,7 +3,7 @@ var should = require('chai').should(); var bitcore = require('..'); -var Pubkey = bitcore.Pubkey; +var PublicKey = bitcore.PublicKey; var Address = bitcore.Address; var Script = bitcore.Script; @@ -211,7 +211,7 @@ describe('Address', function() { it('should error because of incorrect format for pubkey hash', function() { (function() { - var a = new Address.fromPubkeyHash('notahash'); + var a = new Address.fromPublicKeyHash('notahash'); }).should.throw('Address supplied is not a buffer.'); }); @@ -235,8 +235,8 @@ describe('Address', function() { it('should error because of incorrect type for pubkey transform', function() { (function() { - var info = Address._transformPubkey(new Buffer(20)); - }).should.throw('Address must be an instance of Pubkey.'); + var info = Address._transformPublicKey(new Buffer(20)); + }).should.throw('Address must be an instance of PublicKey.'); }); it('should error because of incorrect type for script transform', function() { @@ -253,8 +253,8 @@ describe('Address', function() { it('should make an address from a pubkey hash buffer', function() { var hash = pubkeyhash; //use the same hash - var a = Address.fromPubkeyHash(hash).toString().should.equal(str); - var b = Address.fromPubkeyHash(hash, 'testnet'); + var a = Address.fromPublicKeyHash(hash).toString().should.equal(str); + var b = Address.fromPublicKeyHash(hash, 'testnet'); b.network.should.equal('testnet'); b.type.should.equal('pubkeyhash'); var c = new Address(hash).toString().should.equal(str); @@ -262,19 +262,19 @@ describe('Address', function() { it('should throw an error for invalid length hashBuffer', function() { (function() { - var a = Address.fromPubkeyHash(buf); + var a = Address.fromPublicKeyHash(buf); }).should.throw('Address hashbuffers must be exactly 20 bytes.'); }); it('should make this address from a compressed pubkey', function() { - var pubkey = Pubkey.fromDER(new Buffer('0285e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004', 'hex')); - var address = Address.fromPubkey(pubkey); + var pubkey = PublicKey.fromDER(new Buffer('0285e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004', 'hex')); + var address = Address.fromPublicKey(pubkey); address.toString().should.equal('19gH5uhqY6DKrtkU66PsZPUZdzTd11Y7ke'); }); it('should make this address from an uncompressed pubkey', function() { - var pubkey = Pubkey.fromDER(new Buffer('0485e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004833fef26c8be4c4823754869ff4e46755b85d851077771c220e2610496a29d98', 'hex')); - var a = Address.fromPubkey(pubkey, 'mainnet'); + var pubkey = PublicKey.fromDER(new Buffer('0485e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004833fef26c8be4c4823754869ff4e46755b85d851077771c220e2610496a29d98', 'hex')); + var a = Address.fromPublicKey(pubkey, 'mainnet'); a.toString().should.equal('16JXnhxjJUhxfyx4y6H4sFcxrgt8kQ8ewX'); var b = new Address(pubkey, 'mainnet', 'pubkeyhash'); b.toString().should.equal('16JXnhxjJUhxfyx4y6H4sFcxrgt8kQ8ewX'); diff --git a/test/crypto/ecdsa.js b/test/crypto/ecdsa.js index f9436a30f..037f07ce3 100644 --- a/test/crypto/ecdsa.js +++ b/test/crypto/ecdsa.js @@ -5,8 +5,8 @@ var bitcore = require('../..'); var ECDSA = bitcore.ECDSA; var Hash = bitcore.Hash; var Keypair = bitcore.Keypair; -var Privkey = bitcore.Privkey; -var Pubkey = bitcore.Pubkey; +var PrivateKey = bitcore.PrivateKey; +var PublicKey = bitcore.PublicKey; var Signature = bitcore.Signature; var BN = bitcore.BN; var point = bitcore.Point; @@ -21,8 +21,8 @@ describe('ECDSA', function() { var ecdsa = new ECDSA(); ecdsa.hashbuf = Hash.sha256(new Buffer('test data')); ecdsa.keypair = new Keypair(); - ecdsa.keypair.privkey = new Privkey({bn: BN().fromBuffer(new Buffer('fee0a1f7afebf9d2a5a80c0c98a31c709681cce195cbcd06342b517970c0be1e', 'hex'))}); - ecdsa.keypair.pubkey = new Pubkey({ + ecdsa.keypair.privkey = new PrivateKey({bn: BN().fromBuffer(new Buffer('fee0a1f7afebf9d2a5a80c0c98a31c709681cce195cbcd06342b517970c0be1e', 'hex'))}); + ecdsa.keypair.pubkey = new PublicKey({ point: point(BN().fromBuffer(new Buffer('ac242d242d23be966085a2b2b893d989f824e06c9ad0395a8a52f055ba39abb2', 'hex')), BN().fromBuffer(new Buffer('4836ab292c105a711ed10fcfd30999c31ff7c02456147747e03e739ad527c380', 'hex'))) }); @@ -50,7 +50,7 @@ describe('ECDSA', function() { var s = BN('109412465507152403114191008482955798903072313614214706891149785278625167723646', 10); var ecdsa = new ECDSA(); ecdsa.keypair = new Keypair(); - ecdsa.keypair.privkey = Privkey(); + ecdsa.keypair.privkey = PrivateKey(); ecdsa.keypair.privkey.bn = BN().fromBuffer(Hash.sha256(new Buffer('test'))); ecdsa.keypair.privkey2pubkey(); ecdsa.hashbuf = hashbuf; @@ -121,7 +121,7 @@ describe('ECDSA', function() { it('should return an error if r, s are invalid', function() { var ecdsa = new ECDSA(); ecdsa.hashbuf = Hash.sha256(new Buffer('test')); - var pk = new Pubkey(); + var pk = new PublicKey(); pk.fromDER(new Buffer('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341', 'hex')); ecdsa.keypair = new Keypair(); ecdsa.keypair.pubkey = pk; diff --git a/test/privkey.js b/test/privatekey.js similarity index 69% rename from test/privkey.js rename to test/privatekey.js index 1420f800e..76663d3cf 100644 --- a/test/privkey.js +++ b/test/privatekey.js @@ -4,10 +4,10 @@ var should = require('chai').should(); var bitcore = require('..'); var BN = bitcore.crypto.BN; var Point = bitcore.crypto.Point; -var Privkey = bitcore.Privkey; +var PrivateKey = bitcore.PrivateKey; var base58check = bitcore.encoding.Base58Check; -describe('Privkey', function() { +describe('PrivateKey', function() { var hex = '96c132224121b509b7d0a16245e957d9192609c5637c6228311287b1be21627a'; var buf = new Buffer(hex, 'hex'); var enctestnet = 'cSdkPxkAjA4HDr5VHgsebAPDEh9Gyub4HK8UJr2DFGGqKKy4K5sG'; @@ -16,22 +16,22 @@ describe('Privkey', function() { var encmu = '5JxgQaFM1FMd38cd14e3mbdxsdSa9iM2BV6DHBYsvGzxkTNQ7Un'; it('should create a new random private key', function() { - var a = new Privkey(); + var a = new PrivateKey(); should.exist(a); should.exist(a.bn); - var b = Privkey(); + var b = PrivateKey(); should.exist(b); should.exist(b.bn); }); it('should create a private key from WIF string', function() { - var a = new Privkey('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m'); + var a = new PrivateKey('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m'); should.exist(a); should.exist(a.bn); }); it('should create a private key from WIF buffer', function() { - var a = new Privkey(base58check.decode('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m')); + var a = new PrivateKey(base58check.decode('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m')); should.exist(a); should.exist(a.bn); }); @@ -39,19 +39,19 @@ describe('Privkey', function() { it('should not be able to instantiate private key greater than N', function() { (function() { var n = Point.getN(); - var a = new Privkey(n); + var a = new PrivateKey(n); }).should.throw('Number must be less than N'); }); it('should not be able to instantiate private key because of network mismatch', function() { (function() { - var a = new Privkey('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m', 'testnet'); + var a = new PrivateKey('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m', 'testnet'); }).should.throw('Private key network mismatch'); }); it('should not be able to instantiate private key because of compression mismatch', function() { (function() { - var a = new Privkey('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m', 'mainnet', false); + var a = new PrivateKey('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m', 'mainnet', false); }).should.throw('Private key compression mismatch'); }); @@ -59,7 +59,7 @@ describe('Privkey', function() { (function() { var buf = base58check.decode('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m'); var buf2 = Buffer.concat([buf, new Buffer(0x01)]); - var a = new Privkey(buf2); + var a = new PrivateKey(buf2); }).should.throw('Length of buffer must be 33 (uncompressed) or 34 (compressed'); }); @@ -67,53 +67,53 @@ describe('Privkey', function() { (function() { var buf = base58check.decode('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m'); var buf2 = Buffer.concat([new Buffer(0x01, 'hex'), buf.slice(1, 33)]); - var a = new Privkey(buf2); + var a = new PrivateKey(buf2); }).should.throw('Invalid network'); }); it('should not be able to instantiate because compressed is non-boolean', function() { (function() { - var a = new Privkey(null, 'testnet', 'compressed'); + var a = new PrivateKey(null, 'testnet', 'compressed'); }).should.throw('Must specify whether the corresponding public key is compressed or not (true or false)'); }); it('should not be able to instantiate because of unrecognized data', function() { (function() { - var a = new Privkey(new Error()); + var a = new PrivateKey(new Error()); }).should.throw('First argument is an unrecognized data type.'); }); it('should not be able to instantiate with unknown network', function() { (function() { - var a = new Privkey(null, 'unknown'); + var a = new PrivateKey(null, 'unknown'); }).should.throw('Must specify the network ("mainnet" or "testnet")'); }); it('should create a 0 private key with this convenience method', function() { var bn = BN(0); - var privkey = new Privkey(bn); + var privkey = new PrivateKey(bn); privkey.bn.toString().should.equal(bn.toString()); }); it('should create a mainnet private key', function() { - var privkey = new Privkey(BN.fromBuffer(buf), 'mainnet', true); + var privkey = new PrivateKey(BN.fromBuffer(buf), 'mainnet', true); privkey.toString().should.equal(encmainnet); }); it('should create an uncompressed testnet private key', function() { - var privkey = new Privkey(BN.fromBuffer(buf), 'testnet', false); + var privkey = new PrivateKey(BN.fromBuffer(buf), 'testnet', false); privkey.toString().should.equal(enctu); }); it('should create an uncompressed mainnet private key', function() { - var privkey = new Privkey(BN.fromBuffer(buf), 'mainnet', false); + var privkey = new PrivateKey(BN.fromBuffer(buf), 'mainnet', false); privkey.toString().should.equal(encmu); }); describe('#fromJSON', function() { it('should input this address correctly', function() { - var privkey = Privkey.fromJSON(encmu); + var privkey = PrivateKey.fromJSON(encmu); privkey.toWIF().should.equal(encmu); }); @@ -122,7 +122,7 @@ describe('Privkey', function() { describe('#toString', function() { it('should output this address correctly', function() { - var privkey = Privkey.fromJSON(encmu); + var privkey = PrivateKey.fromJSON(encmu); privkey.toJSON().should.equal(encmu); }); @@ -130,13 +130,13 @@ describe('Privkey', function() { describe('#toAddress', function() { it('should output this known mainnet address correctly', function() { - var privkey = Privkey.fromWIF('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m'); + var privkey = PrivateKey.fromWIF('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m'); var address = privkey.toAddress(); address.toString().should.equal('1A6ut1tWnUq1SEQLMr4ttDh24wcbJ5o9TT'); }); it('should output this known testnet address correctly', function() { - var privkey = Privkey.fromWIF('cR4qogdN9UxLZJXCNFNwDRRZNeLRWuds9TTSuLNweFVjiaE4gPaq'); + var privkey = PrivateKey.fromWIF('cR4qogdN9UxLZJXCNFNwDRRZNeLRWuds9TTSuLNweFVjiaE4gPaq'); var address = privkey.toAddress(); address.toString().should.equal('mtX8nPZZdJ8d3QNLRJ1oJTiEi26Sj6LQXS'); }); @@ -145,13 +145,13 @@ describe('Privkey', function() { describe('#inspect', function() { it('should output known mainnet address for console', function() { - var privkey = Privkey.fromWIF('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m'); - privkey.inspect().should.equal(''); + var privkey = PrivateKey.fromWIF('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m'); + privkey.inspect().should.equal(''); }); it('should output known testnet address for console', function() { - var privkey = Privkey.fromWIF('cR4qogdN9UxLZJXCNFNwDRRZNeLRWuds9TTSuLNweFVjiaE4gPaq'); - privkey.inspect().should.equal(''); + var privkey = PrivateKey.fromWIF('cR4qogdN9UxLZJXCNFNwDRRZNeLRWuds9TTSuLNweFVjiaE4gPaq'); + privkey.inspect().should.equal(''); }); }); @@ -159,18 +159,18 @@ describe('Privkey', function() { describe('#getValidationError', function(){ it('should get an error because private key greater than N', function() { var n = Point.getN(); - var a = Privkey.getValidationError(n); + var a = PrivateKey.getValidationError(n); a.message.should.equal('Number must be less than N'); }); it('should validate as false because private key greater than N', function() { var n = Point.getN(); - var a = Privkey.isValid(n); + var a = PrivateKey.isValid(n); a.should.equal(false); }); it('should validate as true', function() { - var a = Privkey.isValid('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m'); + var a = PrivateKey.isValid('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m'); a.should.equal(true); }); @@ -178,7 +178,7 @@ describe('Privkey', function() { describe('#toBuffer', function() { it('should output known buffer', function() { - var privkey = new Privkey(BN.fromBuffer(buf), 'mainnet', true); + var privkey = new PrivateKey(BN.fromBuffer(buf), 'mainnet', true); var b = privkey.toBuffer().toString('hex').should.equal(buf.toString('hex')); }); }); @@ -186,7 +186,7 @@ describe('Privkey', function() { describe('#toBigNumber', function() { it('should output known BN', function() { var a = BN.fromBuffer(buf); - var privkey = new Privkey(a, 'mainnet', true); + var privkey = new PrivateKey(a, 'mainnet', true); var b = privkey.toBigNumber(); b.toString('hex').should.equal(a.toString('hex')); }); @@ -195,7 +195,7 @@ describe('Privkey', function() { describe('#fromRandom', function() { it('should set bn gt 0 and lt n, and should be compressed', function() { - var privkey = Privkey.fromRandom(); + var privkey = PrivateKey.fromRandom(); privkey.bn.gt(BN(0)).should.equal(true); privkey.bn.lt(Point.getN()).should.equal(true); privkey.compressed.should.equal(true); @@ -206,7 +206,7 @@ describe('Privkey', function() { describe('#fromWIF', function() { it('should parse this compressed testnet address correctly', function() { - var privkey = Privkey.fromWIF(encmainnet); + var privkey = PrivateKey.fromWIF(encmainnet); privkey.toWIF().should.equal(encmainnet); }); @@ -215,7 +215,7 @@ describe('Privkey', function() { describe('#toWIF', function() { it('should parse this compressed testnet address correctly', function() { - var privkey = Privkey.fromWIF(enctestnet); + var privkey = PrivateKey.fromWIF(enctestnet); privkey.toWIF().should.equal(enctestnet); }); @@ -224,7 +224,7 @@ describe('Privkey', function() { describe('#fromString', function() { it('should parse this uncompressed testnet address correctly', function() { - var privkey = Privkey.fromString(enctu); + var privkey = PrivateKey.fromString(enctu); privkey.toWIF().should.equal(enctu); }); @@ -233,35 +233,35 @@ describe('Privkey', function() { describe('#toString', function() { it('should parse this uncompressed mainnet address correctly', function() { - var privkey = Privkey.fromString(encmu); + var privkey = PrivateKey.fromString(encmu); privkey.toString().should.equal(encmu); }); }); - describe("#toPubkey", function() { + describe("#toPublicKey", function() { - it('should convert this known Privkey to known Pubkey', function() { + it('should convert this known PrivateKey to known PublicKey', function() { var privhex = '906977a061af29276e40bf377042ffbde414e496ae2260bbf1fa9d085637bfff'; var pubhex = '02a1633cafcc01ebfb6d78e39f687a1f0995c62fc95f51ead10a02ee0be551b5dc'; - var privkey = new Privkey(BN(new Buffer(privhex, 'hex'))); - var pubkey = privkey.toPubkey(); + var privkey = new PrivateKey(BN(new Buffer(privhex, 'hex'))); + var pubkey = privkey.toPublicKey(); pubkey.toString().should.equal(pubhex); }); - it('should convert this known Privkey to known Pubkey and preserve compressed=true', function() { + it('should convert this known PrivateKey to known PublicKey and preserve compressed=true', function() { var privhex = '906977a061af29276e40bf377042ffbde414e496ae2260bbf1fa9d085637bfff'; - var privkey = new Privkey(BN(new Buffer(privhex, 'hex'))); + var privkey = new PrivateKey(BN(new Buffer(privhex, 'hex'))); privkey.compressed = true; - var pubkey = privkey.toPubkey(); + var pubkey = privkey.toPublicKey(); pubkey.compressed.should.equal(true); }); - it('should convert this known Privkey to known Pubkey and preserve compressed=true', function() { + it('should convert this known PrivateKey to known PublicKey and preserve compressed=true', function() { var privhex = '906977a061af29276e40bf377042ffbde414e496ae2260bbf1fa9d085637bfff'; - var privkey = new Privkey(BN(new Buffer(privhex, 'hex'))); + var privkey = new PrivateKey(BN(new Buffer(privhex, 'hex'))); privkey.compressed = false; - var pubkey = privkey.toPubkey(); + var pubkey = privkey.toPublicKey(); pubkey.compressed.should.equal(false); }); diff --git a/test/pubkey.js b/test/publickey.js similarity index 71% rename from test/pubkey.js rename to test/publickey.js index 80fecf422..e9160f706 100644 --- a/test/pubkey.js +++ b/test/publickey.js @@ -4,51 +4,51 @@ var should = require('chai').should(); var bitcore = require('..'); var Point = bitcore.crypto.Point; var BN = bitcore.crypto.BN; -var Pubkey = bitcore.Pubkey; -var Privkey = bitcore.Privkey; +var PublicKey = bitcore.PublicKey; +var PrivateKey = bitcore.PrivateKey; -describe('Pubkey', function() { +describe('PublicKey', function() { it('should error because of missing data', function() { (function() { - var pk = new Pubkey(); + var pk = new PublicKey(); }).should.throw('First argument is required, please include public key data.'); }); it('should error because of an invalid point', function() { (function() { - var pk = new Pubkey(Point()); + var pk = new PublicKey(Point()); }).should.throw('Point cannot be equal to 0, 0'); }); it('should error because of an invalid public key point, not on the secp256k1 curve', function() { (function() { - var pk = new Pubkey(Point(1000, 1000)); + var pk = new PublicKey(Point(1000, 1000)); }).should.throw('Invalid y value of public key'); }); it('should error because of an unrecognized data type', function() { (function() { - var pk = new Pubkey(new Error()); + var pk = new PublicKey(new Error()); }).should.throw('First argument is an unrecognized data format.'); }); it('should instantiate from a private key', function() { var privhex = '906977a061af29276e40bf377042ffbde414e496ae2260bbf1fa9d085637bfff'; var pubhex = '02a1633cafcc01ebfb6d78e39f687a1f0995c62fc95f51ead10a02ee0be551b5dc'; - var privkey = new Privkey(BN(new Buffer(privhex, 'hex'))); - var pk = new Pubkey(privkey); + var privkey = new PrivateKey(BN(new Buffer(privhex, 'hex'))); + var pk = new PublicKey(privkey); pk.toString().should.equal(pubhex); }); it('should instantiate from a hex encoded DER string', function() { - var pk = new Pubkey('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); + var pk = new PublicKey('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); should.exist(pk.point); pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); }); it('should instantiate from a hex encoded DER buffer', function() { - var pk = new Pubkey(new Buffer('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341', 'hex')); + var pk = new PublicKey(new Buffer('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341', 'hex')); should.exist(pk.point); pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); }); @@ -56,27 +56,27 @@ describe('Pubkey', function() { it('should create a public key with a point', function() { var p = Point('86a80a5a2bfc48dddde2b0bd88bd56b0b6ddc4e6811445b175b90268924d7d48', '3b402dfc89712cfe50963e670a0598e6b152b3cd94735001cdac6794975d3afd'); - var a = new Pubkey(p); + var a = new PublicKey(p); should.exist(a.point); a.point.toString().should.equal(p.toString()); - var c = Pubkey(p); + var c = PublicKey(p); should.exist(c.point); c.point.toString().should.equal(p.toString()); }); describe('#getValidationError', function(){ it('should recieve an error message', function() { - var error = Pubkey.getValidationError(Point()); + var error = PublicKey.getValidationError(Point()); should.exist(error); }); it('should recieve a boolean as false', function() { - var valid = Pubkey.isValid(Point()); + var valid = PublicKey.isValid(Point()); valid.should.equal(false); }); it('should recieve a boolean as true', function() { - var valid = Pubkey.isValid('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); + var valid = PublicKey.isValid('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); valid.should.equal(true); }); @@ -87,14 +87,14 @@ describe('Pubkey', function() { it('should instantiate from a point', function() { var p = Point('86a80a5a2bfc48dddde2b0bd88bd56b0b6ddc4e6811445b175b90268924d7d48', '3b402dfc89712cfe50963e670a0598e6b152b3cd94735001cdac6794975d3afd'); - var b = Pubkey.fromPoint(p); + var b = PublicKey.fromPoint(p); should.exist(b.point); b.point.toString().should.equal(p.toString()); }); it('should error because paramater is not a point', function() { (function() { - Pubkey.fromPoint(new Error()); + PublicKey.fromPoint(new Error()); }).should.throw('First argument must be an instance of Point.'); }); }); @@ -102,7 +102,7 @@ describe('Pubkey', function() { describe('#fromJSON', function() { it('should input this public key', function() { - var pk = Pubkey.fromJSON('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); + var pk = PublicKey.fromJSON('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); pk.point.getY().toString(16).should.equal('7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); }); @@ -113,22 +113,22 @@ describe('Pubkey', function() { it('should output this pubkey', function() { var hex = '041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'; - var pk = Pubkey.fromJSON(hex); + var pk = PublicKey.fromJSON(hex); pk.toJSON().should.equal(hex); }); }); - describe('#fromPrivkey', function() { + describe('#fromPrivateKey', function() { it('should make a public key from a privkey', function() { - should.exist(Pubkey.fromPrivkey(Privkey.fromRandom())); + should.exist(PublicKey.fromPrivateKey(PrivateKey.fromRandom())); }); it('should error because not an instance of privkey', function() { (function() { - Pubkey.fromPrivkey(new Error()); - }).should.throw('Must be an instance of Privkey'); + PublicKey.fromPrivateKey(new Error()); + }).should.throw('Must be an instance of PrivateKey'); }); }); @@ -136,32 +136,32 @@ describe('Pubkey', function() { describe('#fromBuffer', function() { it('should parse this uncompressed public key', function() { - var pk = Pubkey.fromBuffer(new Buffer('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341', 'hex')); + var pk = PublicKey.fromBuffer(new Buffer('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341', 'hex')); pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); pk.point.getY().toString(16).should.equal('7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); }); it('should parse this compressed public key', function() { - var pk = Pubkey.fromBuffer(new Buffer('031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); + var pk = PublicKey.fromBuffer(new Buffer('031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); pk.point.getY().toString(16).should.equal('7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); }); it('should throw an error on this invalid public key', function() { (function() { - Pubkey.fromBuffer(new Buffer('091ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); + PublicKey.fromBuffer(new Buffer('091ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); }).should.throw(); }); it('should throw error because not a buffer', function() { (function() { - Pubkey.fromBuffer('091ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); + PublicKey.fromBuffer('091ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); }).should.throw('Must be a hex buffer of DER encoded public key'); }); it('should throw error because buffer is the incorrect length', function() { (function() { - Pubkey.fromBuffer(new Buffer('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a34112', 'hex')); + PublicKey.fromBuffer(new Buffer('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a34112', 'hex')); }).should.throw('Length of x and y must be 32 bytes'); }); @@ -170,20 +170,20 @@ describe('Pubkey', function() { describe('#fromDER', function() { it('should parse this uncompressed public key', function() { - var pk = Pubkey.fromDER(new Buffer('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341', 'hex')); + var pk = PublicKey.fromDER(new Buffer('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341', 'hex')); pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); pk.point.getY().toString(16).should.equal('7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); }); it('should parse this compressed public key', function() { - var pk = Pubkey.fromDER(new Buffer('031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); + var pk = PublicKey.fromDER(new Buffer('031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); pk.point.getY().toString(16).should.equal('7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); }); it('should throw an error on this invalid public key', function() { (function() { - Pubkey.fromDER(new Buffer('091ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); + PublicKey.fromDER(new Buffer('091ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); }).should.throw(); }); @@ -192,7 +192,7 @@ describe('Pubkey', function() { describe('#fromString', function() { it('should parse this known valid public key', function() { - var pk = Pubkey.fromString('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); + var pk = PublicKey.fromString('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); pk.point.getY().toString(16).should.equal('7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); }); @@ -203,7 +203,7 @@ describe('Pubkey', function() { it('should create this known public key', function() { var x = BN.fromBuffer(new Buffer('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); - var pk = Pubkey.fromX(true, x); + var pk = PublicKey.fromX(true, x); pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); pk.point.getY().toString(16).should.equal('7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); }); @@ -212,7 +212,7 @@ describe('Pubkey', function() { it('should error because odd was not included as a param', function() { var x = BN.fromBuffer(new Buffer('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); (function() { - var pk = Pubkey.fromX(null, x); + var pk = PublicKey.fromX(null, x); }).should.throw('Must specify whether y is odd or not (true or false)'); }); @@ -222,7 +222,7 @@ describe('Pubkey', function() { it('should return this compressed DER format', function() { var x = BN.fromBuffer(new Buffer('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); - var pk = Pubkey.fromX(true, x); + var pk = PublicKey.fromX(true, x); pk.toBuffer().toString('hex').should.equal('031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); }); @@ -232,19 +232,19 @@ describe('Pubkey', function() { it('should return this compressed DER format', function() { var x = BN.fromBuffer(new Buffer('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); - var pk = Pubkey.fromX(true, x); + var pk = PublicKey.fromX(true, x); pk.toDER(true).toString('hex').should.equal('031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); }); it('should return this uncompressed DER format', function() { var x = BN.fromBuffer(new Buffer('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); - var pk = Pubkey.fromX(true, x); + var pk = PublicKey.fromX(true, x); pk.toDER(false).toString('hex').should.equal('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); }); it('should error because compressed param is invalid', function() { var x = BN.fromBuffer(new Buffer('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); - var pk = Pubkey.fromX(true, x); + var pk = PublicKey.fromX(true, x); (function() { pk.toDER('false'); //string not boolean }).should.throw('Must specify whether the public key is compressed or not (true or false)'); @@ -256,7 +256,7 @@ describe('Pubkey', function() { it('should print this known public key', function() { var hex = '031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'; - var pk = Pubkey.fromString(hex); + var pk = PublicKey.fromString(hex); pk.toString().should.equal(hex); }); @@ -264,13 +264,13 @@ describe('Pubkey', function() { describe('#inspect', function() { it('should output known uncompressed pubkey for console', function() { - var pubkey = Pubkey.fromString('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); - pubkey.inspect().should.equal(''); + var pubkey = PublicKey.fromString('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); + pubkey.inspect().should.equal(''); }); it('should output known compressed pubkey for console', function() { - var pubkey = Pubkey.fromString('031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); - pubkey.inspect().should.equal(''); + var pubkey = PublicKey.fromString('031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); + pubkey.inspect().should.equal(''); }); }); @@ -279,19 +279,19 @@ describe('Pubkey', function() { it('should not have an error if pubkey is valid', function() { var hex = '031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'; - var pk = Pubkey.fromString(hex); + var pk = PublicKey.fromString(hex); }); it('should throw an error if pubkey is invalid', function() { var hex = '041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a0000000000000000000000000000000000000000000000000000000000000000'; (function() { - var pk = Pubkey.fromString(hex); + var pk = PublicKey.fromString(hex); }).should.throw('Invalid y value of public key'); }); it('should throw an error if pubkey is infinity', function() { (function() { - var pk = new Pubkey(Point.getG().mul(Point.getN())); + var pk = new PublicKey(Point.getG().mul(Point.getN())); }).should.throw('Point cannot be equal to Infinity'); }); diff --git a/test/script.js b/test/script.js index 601fdc4d1..b4ed14fe7 100644 --- a/test/script.js +++ b/test/script.js @@ -218,26 +218,26 @@ describe('Script', function() { }); - describe('#isPubkeyhashIn', function() { + describe('#isPublicKeyHashIn', function() { it('should classify this known pubkeyhashin', function() { - Script('73 0x3046022100bb3c194a30e460d81d34be0a230179c043a656f67e3c5c8bf47eceae7c4042ee0221008bf54ca11b2985285be0fd7a212873d243e6e73f5fad57e8eb14c4f39728b8c601 65 0x04e365859b3c78a8b7c202412b949ebca58e147dba297be29eee53cd3e1d300a6419bc780cc9aec0dc94ed194e91c8f6433f1b781ee00eac0ead2aae1e8e0712c6').isPubkeyhashIn().should.equal(true); + Script('73 0x3046022100bb3c194a30e460d81d34be0a230179c043a656f67e3c5c8bf47eceae7c4042ee0221008bf54ca11b2985285be0fd7a212873d243e6e73f5fad57e8eb14c4f39728b8c601 65 0x04e365859b3c78a8b7c202412b949ebca58e147dba297be29eee53cd3e1d300a6419bc780cc9aec0dc94ed194e91c8f6433f1b781ee00eac0ead2aae1e8e0712c6').isPublicKeyHashIn().should.equal(true); }); it('should classify this known non-pubkeyhashin', function() { - Script('73 0x3046022100bb3c194a30e460d81d34be0a230179c043a656f67e3c5c8bf47eceae7c4042ee0221008bf54ca11b2985285be0fd7a212873d243e6e73f5fad57e8eb14c4f39728b8c601 65 0x04e365859b3c78a8b7c202412b949ebca58e147dba297be29eee53cd3e1d300a6419bc780cc9aec0dc94ed194e91c8f6433f1b781ee00eac0ead2aae1e8e0712c6 OP_CHECKSIG').isPubkeyhashIn().should.equal(false); + Script('73 0x3046022100bb3c194a30e460d81d34be0a230179c043a656f67e3c5c8bf47eceae7c4042ee0221008bf54ca11b2985285be0fd7a212873d243e6e73f5fad57e8eb14c4f39728b8c601 65 0x04e365859b3c78a8b7c202412b949ebca58e147dba297be29eee53cd3e1d300a6419bc780cc9aec0dc94ed194e91c8f6433f1b781ee00eac0ead2aae1e8e0712c6 OP_CHECKSIG').isPublicKeyHashIn().should.equal(false); }); }); - describe('#isPubkeyhashOut', function() { + describe('#isPublicKeyHashOut', function() { it('should classify this known pubkeyhashout as pubkeyhashout', function() { - Script('OP_DUP OP_HASH160 20 0000000000000000000000000000000000000000 OP_EQUALVERIFY OP_CHECKSIG').isPubkeyhashOut().should.equal(true); + Script('OP_DUP OP_HASH160 20 0000000000000000000000000000000000000000 OP_EQUALVERIFY OP_CHECKSIG').isPublicKeyHashOut().should.equal(true); }); it('should classify this known non-pubkeyhashout as not pubkeyhashout', function() { - Script('OP_DUP OP_HASH160 20 0000000000000000000000000000000000000000').isPubkeyhashOut().should.equal(false) + Script('OP_DUP OP_HASH160 20 0000000000000000000000000000000000000000').isPublicKeyHashOut().should.equal(false) }); }); @@ -245,11 +245,11 @@ describe('Script', function() { describe('#isScripthashIn', function() { it('should classify this known scripthashin', function() { - Script('20 0000000000000000000000000000000000000000').isScripthashIn().should.equal(true); + Script('20 0000000000000000000000000000000000000000').isScriptHashIn().should.equal(true); }); it('should classify this known non-scripthashin', function() { - Script('20 0000000000000000000000000000000000000000 OP_CHECKSIG').isScripthashIn().should.equal(false); + Script('20 0000000000000000000000000000000000000000 OP_CHECKSIG').isScriptHashIn().should.equal(false); }); }); @@ -257,12 +257,12 @@ describe('Script', function() { describe('#isScripthashOut', function() { it('should classify this known pubkeyhashout as pubkeyhashout', function() { - Script('OP_HASH160 20 0x0000000000000000000000000000000000000000 OP_EQUAL').isScripthashOut().should.equal(true); + Script('OP_HASH160 20 0x0000000000000000000000000000000000000000 OP_EQUAL').isScriptHashOut().should.equal(true); }); it('should classify these known non-pubkeyhashout as not pubkeyhashout', function() { - Script('OP_HASH160 20 0x0000000000000000000000000000000000000000 OP_EQUAL OP_EQUAL').isScripthashOut().should.equal(false); - Script('OP_HASH160 21 0x000000000000000000000000000000000000000000 OP_EQUAL').isScripthashOut().should.equal(false); + Script('OP_HASH160 20 0x0000000000000000000000000000000000000000 OP_EQUAL OP_EQUAL').isScriptHashOut().should.equal(false); + Script('OP_HASH160 21 0x000000000000000000000000000000000000000000 OP_EQUAL').isScriptHashOut().should.equal(false); }); }); From 2a2dc8196d506360571b049fcb4920538b6c859f Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Tue, 25 Nov 2014 15:10:22 -0500 Subject: [PATCH 3/4] Crypto: Update ECDSA with to use PrivateKey and PublicKey --- lib/crypto/ecdsa.js | 17 +++++------------ lib/publickey.js | 4 ++-- test/crypto/ecdsa.js | 12 ++---------- 3 files changed, 9 insertions(+), 24 deletions(-) diff --git a/lib/crypto/ecdsa.js b/lib/crypto/ecdsa.js index 54d41fbe4..842be38e2 100644 --- a/lib/crypto/ecdsa.js +++ b/lib/crypto/ecdsa.js @@ -25,7 +25,7 @@ ECDSA.prototype.set = function(obj) { }; ECDSA.prototype.privkey2pubkey = function(){ - this.pubkey = PublicKey().fromPrivateKey(this.privkey); + this.pubkey = PublicKey.fromPrivateKey(this.privkey); }; ECDSA.prototype.calci = function() { @@ -35,6 +35,7 @@ ECDSA.prototype.calci = function() { try { Qprime = this.sig2pubkey(); } catch (e) { + console.log(e); continue; } if (Qprime.point.eq(this.pubkey.point)) { @@ -52,9 +53,9 @@ ECDSA.prototype.fromString = function(str) { if (obj.hashbuf) this.hashbuf = new Buffer(obj.hashbuf, 'hex'); if (obj.pubkey) - this.pubkey = PublicKey().fromString(obj.pubkey); + this.pubkey = PublicKey.fromString(obj.pubkey); if (obj.privkey) - this.privkey = PrivateKey().fromString(obj.privkey); + this.privkey = PrivateKey.fromString(obj.privkey); if (obj.sig) this.sig = Signature().fromString(obj.sig); if (obj.k) @@ -114,9 +115,7 @@ ECDSA.prototype.sig2pubkey = function() { //var Q = R.multiplyTwo(s, G, eNeg).mul(rInv); var Q = R.mul(s).add(G.mul(eNeg)).mul(rInv); - var pubkey = new PublicKey({point: Q}); - pubkey.compressed = this.sig.compressed; - pubkey.validate(); + var pubkey = PublicKey.fromPoint(Q, this.sig.compressed); return pubkey; }; @@ -125,12 +124,6 @@ ECDSA.prototype.sigError = function() { if (!Buffer.isBuffer(this.hashbuf) || this.hashbuf.length !== 32) return 'hashbuf must be a 32 byte buffer'; - try { - this.pubkey.validate(); - } catch (e) { - return 'Invalid pubkey: ' + e; - } - var r = this.sig.r; var s = this.sig.s; if (!(r.gt(0) && r.lt(Point.getN())) diff --git a/lib/publickey.js b/lib/publickey.js index 194d5c238..ea70b7dec 100644 --- a/lib/publickey.js +++ b/lib/publickey.js @@ -186,11 +186,11 @@ PublicKey.fromBuffer = function(buf) { * @param {Point} point - A Point instance * @returns {PublicKey} A new valid instance of PublicKey */ -PublicKey.fromPoint = function(point){ +PublicKey.fromPoint = function(point, compressed){ if (!(point instanceof Point)) { throw new TypeError('First argument must be an instance of Point.'); } - return new PublicKey(point); + return new PublicKey(point, compressed); }; /** diff --git a/test/crypto/ecdsa.js b/test/crypto/ecdsa.js index 7a8e0e576..5252a5f89 100644 --- a/test/crypto/ecdsa.js +++ b/test/crypto/ecdsa.js @@ -8,7 +8,6 @@ var PrivateKey = bitcore.PrivateKey; var PublicKey = bitcore.PublicKey; var Signature = bitcore.Signature; var BN = bitcore.crypto.BN; -var Point = bitcore.crypto.Point; describe('ECDSA', function() { @@ -20,7 +19,7 @@ describe('ECDSA', function() { var ecdsa = new ECDSA(); ecdsa.hashbuf = Hash.sha256(new Buffer('test data')); ecdsa.privkey = new PrivateKey(BN().fromBuffer(new Buffer('fee0a1f7afebf9d2a5a80c0c98a31c709681cce195cbcd06342b517970c0be1e', 'hex'))); - ecdsa.pubkey = new PublicKey(Point(BN().fromBuffer(new Buffer('ac242d242d23be966085a2b2b893d989f824e06c9ad0395a8a52f055ba39abb2', 'hex')))); + ecdsa.privkey2pubkey(); describe('#set', function() { @@ -105,17 +104,10 @@ describe('ECDSA', function() { ecdsa.sigError().should.equal('hashbuf must be a 32 byte buffer'); }); - it('should return an error if the pubkey is invalid', function() { - var ecdsa = new ECDSA(); - ecdsa.hashbuf = Hash.sha256(new Buffer('test')); - ecdsa.sigError().indexOf("Invalid pubkey").should.equal(0); - }); - it('should return an error if r, s are invalid', function() { var ecdsa = new ECDSA(); ecdsa.hashbuf = Hash.sha256(new Buffer('test')); - var pk = new PublicKey(); - pk.fromDER(new Buffer('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341', 'hex')); + var pk = PublicKey.fromDER(new Buffer('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341', 'hex')); ecdsa.pubkey = pk; ecdsa.sig = new Signature(); ecdsa.sig.r = BN(0); From 7de28610a5d9e7637a9ad6b3472b21f7a008a22f Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Tue, 25 Nov 2014 15:30:25 -0500 Subject: [PATCH 4/4] Keys: Fix browser data types --- lib/privatekey.js | 2 +- lib/publickey.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/privatekey.js b/lib/privatekey.js index f064f3670..dee392d02 100644 --- a/lib/privatekey.js +++ b/lib/privatekey.js @@ -39,7 +39,7 @@ var PrivateKey = function PrivateKey(data, network, compressed) { info.bn = PrivateKey._getRandomBN(); } else if (data instanceof BN) { info.bn = data; - } else if (data instanceof Buffer) { + } else if (data instanceof Buffer || data instanceof Uint8Array) { info = PrivateKey._transformBuffer(data, network, compressed); } else if (typeof(data) === 'string'){ info = PrivateKey._transformWIF(data, network, compressed); diff --git a/lib/publickey.js b/lib/publickey.js index 194d5c238..4b9f611a3 100644 --- a/lib/publickey.js +++ b/lib/publickey.js @@ -36,7 +36,7 @@ var PublicKey = function PublicKey(data, compressed) { info.point = data; } else if (typeof(data) === 'string'){ info = PublicKey._transformDER(new Buffer(data, 'hex' )); - } else if (data instanceof Buffer){ + } else if (data instanceof Buffer || data instanceof Uint8Array){ info = PublicKey._transformDER(data); } else if (data.constructor && (data.constructor.name && data.constructor.name === 'PrivateKey')) { @@ -90,7 +90,7 @@ PublicKey._transformPrivateKey = function(privkey) { */ PublicKey._transformDER = function(buf){ var info = {}; - if (!(buf instanceof Buffer)){ + if (!(buf instanceof Buffer) && !(buf instanceof Uint8Array)){ throw new TypeError('Must be a hex buffer of DER encoded public key'); }