Merge pull request #829 from eordano/review/keys
PrivateKey, PublicKey, Network linted
This commit is contained in:
commit
58f68ba8d2
@ -79,12 +79,22 @@ _.each(_.values(testnet), function(value) {
|
||||
* @member Network#getNetwork
|
||||
* Retrieves the network associated with a magic number or string.
|
||||
* @param {string|number|Network} arg
|
||||
* @param {string} key - if set, only check if the magic number associated with this name matches
|
||||
* @return Network
|
||||
*/
|
||||
function getNetwork(arg) {
|
||||
function getNetwork(arg, key) {
|
||||
if (arg === livenet || arg === testnet) {
|
||||
return arg;
|
||||
}
|
||||
if (key) {
|
||||
var networks = [livenet, testnet];
|
||||
for (var index in networks) {
|
||||
if (networks[index][key] === arg) {
|
||||
return networks[index];
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
return networkMaps[arg];
|
||||
}
|
||||
|
||||
|
||||
@ -15,7 +15,6 @@ var Random = require('./crypto/random');
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
*
|
||||
* // generate a new random key
|
||||
* var key = PrivateKey();
|
||||
*
|
||||
@ -29,12 +28,14 @@ var Random = require('./crypto/random');
|
||||
* var imported = PrivateKey.fromWIF(exported);
|
||||
* ```
|
||||
*
|
||||
* @param {String} data - The encoded data in various formats
|
||||
* @param {String} [network] - Either "livenet" or "testnet"
|
||||
* @param {string} data - The encoded data in various formats
|
||||
* @param {Network|string} [network] - a {@link Network} object, or a string with the network name
|
||||
* @returns {PrivateKey} A new valid instance of an PrivateKey
|
||||
* @constructor
|
||||
*/
|
||||
var PrivateKey = function PrivateKey(data, network) {
|
||||
/* jshint maxstatements: 20 */
|
||||
/* jshint maxcomplexity: 8 */
|
||||
|
||||
if (!(this instanceof PrivateKey)) {
|
||||
return new PrivateKey(data, network);
|
||||
@ -43,29 +44,7 @@ var PrivateKey = function PrivateKey(data, network) {
|
||||
return data;
|
||||
}
|
||||
|
||||
var info = {
|
||||
compressed: true,
|
||||
network: network ? Networks.get(network) : Networks.defaultNetwork
|
||||
};
|
||||
|
||||
// detect type of data
|
||||
if (_.isUndefined(data)){
|
||||
info.bn = PrivateKey._getRandomBN();
|
||||
} else if (data instanceof BN) {
|
||||
info.bn = data;
|
||||
} else if (data instanceof Buffer || data instanceof Uint8Array) {
|
||||
info = PrivateKey._transformBuffer(data, network);
|
||||
} else if (PrivateKey._isJSON(data)){
|
||||
info = PrivateKey._transformJSON(data);
|
||||
} else if (typeof(data) === 'string'){
|
||||
if (JSUtil.isHexa(data)) {
|
||||
info.bn = BN(new Buffer(data, 'hex'));
|
||||
} else {
|
||||
info = PrivateKey._transformWIF(data, network);
|
||||
}
|
||||
} else {
|
||||
throw new TypeError('First argument is an unrecognized data type.');
|
||||
}
|
||||
var info = this._classifyArguments(data, network);
|
||||
|
||||
// validation
|
||||
if (!info.bn || info.bn.cmp(0) === 0){
|
||||
@ -103,7 +82,43 @@ var PrivateKey = function PrivateKey(data, network) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal function to get a random BN
|
||||
* Internal helper to instantiate PrivateKey internal `info` object from
|
||||
* different kinds of arguments passed to the constructor.
|
||||
*
|
||||
* @param {*} data
|
||||
* @param {Network|string} [network] - a {@link Network} object, or a string with the network name
|
||||
* @return {Object}
|
||||
*/
|
||||
PrivateKey.prototype._classifyArguments = function(data, network) {
|
||||
/* jshint maxcomplexity: 10 */
|
||||
var info = {
|
||||
compressed: true,
|
||||
network: network ? Networks.get(network) : Networks.defaultNetwork
|
||||
};
|
||||
|
||||
// detect type of data
|
||||
if (_.isUndefined(data)){
|
||||
info.bn = PrivateKey._getRandomBN();
|
||||
} else if (data instanceof BN) {
|
||||
info.bn = data;
|
||||
} else if (data instanceof Buffer || data instanceof Uint8Array) {
|
||||
info = PrivateKey._transformBuffer(data, network);
|
||||
} else if (PrivateKey._isJSON(data)){
|
||||
info = PrivateKey._transformJSON(data);
|
||||
} else if (typeof(data) === 'string'){
|
||||
if (JSUtil.isHexa(data)) {
|
||||
info.bn = BN(new Buffer(data, 'hex'));
|
||||
} else {
|
||||
info = PrivateKey._transformWIF(data, network);
|
||||
}
|
||||
} else {
|
||||
throw new TypeError('First argument is an unrecognized data type.');
|
||||
}
|
||||
return info;
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal function to get a random Big Number (BN)
|
||||
*
|
||||
* @returns {BN} A new randomly generated BN
|
||||
* @private
|
||||
@ -127,14 +142,14 @@ PrivateKey._getRandomBN = function(){
|
||||
* @private
|
||||
*/
|
||||
PrivateKey._isJSON = function(json) {
|
||||
return JSUtil.isValidJSON(json) || (json.bn && json.network && json.compressed);
|
||||
return JSUtil.isValidJSON(json) || (json.bn && json.network);
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal function to transform a WIF Buffer into a private key
|
||||
*
|
||||
* @param {Buffer} buf - An WIF string
|
||||
* @param {String} [network] - Either "livenet" or "testnet"
|
||||
* @param {Network|string} [network] - a {@link Network} object, or a string with the network name
|
||||
* @returns {Object} An object with keys: bn, network and compressed
|
||||
* @private
|
||||
*/
|
||||
@ -150,6 +165,7 @@ PrivateKey._transformBuffer = function(buf, network) {
|
||||
throw new Error('Length of buffer must be 33 (uncompressed) or 34 (compressed)');
|
||||
}
|
||||
|
||||
info.network = Networks.get(buf[0], 'privatekey');
|
||||
if (buf[0] === Networks.livenet.privatekey) {
|
||||
info.network = Networks.livenet;
|
||||
} else if (buf[0] === Networks.testnet.privatekey) {
|
||||
@ -210,7 +226,7 @@ PrivateKey._transformJSON = function(json) {
|
||||
bn: bn,
|
||||
network: json.network,
|
||||
compressed: json.compressed
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
@ -245,6 +261,7 @@ PrivateKey.fromRandom = function(network) {
|
||||
PrivateKey.getValidationError = function(data, network) {
|
||||
var error;
|
||||
try {
|
||||
/* jshint nonew: false */
|
||||
new PrivateKey(data, network);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
|
||||
@ -9,11 +9,13 @@ var _ = require('lodash');
|
||||
var $ = require('./util/preconditions');
|
||||
|
||||
/**
|
||||
* Instantiate a PublicKey from a 'PrivateKey', 'Point', 'string', 'Buffer'.
|
||||
* Instantiate a PublicKey from a {@link PrivateKey}, {@link Point}, `string`, or `Buffer`.
|
||||
*
|
||||
* There are two internal properties, `network` and `compressed`, that deal with importing
|
||||
* a PublicKey from a PrivateKey in WIF format. More details described on {@link PrivateKey}
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
*
|
||||
* // instantiate from a private key
|
||||
* var key = PublicKey(privateKey, true);
|
||||
*
|
||||
@ -45,25 +47,7 @@ var PublicKey = function PublicKey(data, extra) {
|
||||
}
|
||||
extra = extra || {};
|
||||
|
||||
var info = {
|
||||
compressed: _.isUndefined(extra.compressed) || extra.compressed,
|
||||
network: _.isUndefined(extra.network) ? undefined : Network.get(extra.network)
|
||||
};
|
||||
|
||||
// detect type of data
|
||||
if (data instanceof Point) {
|
||||
info.point = data;
|
||||
} else if (PublicKey._isJSON(data)) {
|
||||
info = PublicKey._transformJSON(data);
|
||||
} else if (typeof(data) === 'string') {
|
||||
info = PublicKey._transformDER(new Buffer(data, 'hex'));
|
||||
} else if (PublicKey._isBuffer(data)) {
|
||||
info = PublicKey._transformDER(data);
|
||||
} else if (PublicKey._isPrivateKey(data)) {
|
||||
info = PublicKey._transformPrivateKey(data);
|
||||
} else {
|
||||
throw new TypeError('First argument is an unrecognized data format.');
|
||||
}
|
||||
var info = this._classifyArgs(data, extra);
|
||||
|
||||
// validation
|
||||
info.point.validate();
|
||||
@ -88,7 +72,36 @@ var PublicKey = function PublicKey(data, extra) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal function to detect if an object is a PrivateKey
|
||||
* Internal function to differentiate between arguments passed to the constructor
|
||||
* @param {*} data
|
||||
* @param {Object} extra
|
||||
*/
|
||||
PublicKey.prototype._classifyArgs = function(data, extra) {
|
||||
/* jshint maxcomplexity: 10 */
|
||||
var info = {
|
||||
compressed: _.isUndefined(extra.compressed) || extra.compressed,
|
||||
network: _.isUndefined(extra.network) ? undefined : Network.get(extra.network)
|
||||
};
|
||||
|
||||
// detect type of data
|
||||
if (data instanceof Point) {
|
||||
info.point = data;
|
||||
} else if (PublicKey._isJSON(data)) {
|
||||
info = PublicKey._transformJSON(data);
|
||||
} else if (typeof(data) === 'string') {
|
||||
info = PublicKey._transformDER(new Buffer(data, 'hex'));
|
||||
} else if (PublicKey._isBuffer(data)) {
|
||||
info = PublicKey._transformDER(data);
|
||||
} else if (PublicKey._isPrivateKey(data)) {
|
||||
info = PublicKey._transformPrivateKey(data);
|
||||
} else {
|
||||
throw new TypeError('First argument is an unrecognized data format.');
|
||||
}
|
||||
return info;
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal function to detect if an object is a {@link PrivateKey}
|
||||
*
|
||||
* @param {*} param - object to test
|
||||
* @returns {boolean}
|
||||
@ -147,6 +160,8 @@ PublicKey._transformPrivateKey = function(privkey) {
|
||||
* @private
|
||||
*/
|
||||
PublicKey._transformDER = function(buf, strict) {
|
||||
/* jshint maxstatements: 30 */
|
||||
/* jshint maxcomplexity: 12 */
|
||||
$.checkArgument(PublicKey._isBuffer(buf), new TypeError('Must be a hex buffer of DER encoded public key'));
|
||||
var info = {};
|
||||
|
||||
@ -165,7 +180,7 @@ PublicKey._transformDER = function(buf, strict) {
|
||||
}
|
||||
x = BN(xbuf);
|
||||
y = BN(ybuf);
|
||||
info.point = Point(x, y);
|
||||
info.point = new Point(x, y);
|
||||
info.compressed = false;
|
||||
} else if (buf[0] === 0x03) {
|
||||
xbuf = buf.slice(1);
|
||||
@ -314,6 +329,7 @@ PublicKey.fromX = function(odd, x) {
|
||||
PublicKey.getValidationError = function(data) {
|
||||
var error;
|
||||
try {
|
||||
/* jshint nonew: false */
|
||||
new PublicKey(data);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
var expect = require('chai').expect;
|
||||
var should = require('chai').should();
|
||||
var bitcore = require('..');
|
||||
var networks = bitcore.Networks;
|
||||
@ -21,4 +22,13 @@ describe('Networks', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('tests only for the specified key', function() {
|
||||
expect(networks.get(0x6f, 'pubkeyhash')).to.equal(networks.testnet);
|
||||
expect(networks.get(0x6f, 'privatekey')).to.equal(undefined);
|
||||
});
|
||||
|
||||
it('converts to string using the "name" property', function() {
|
||||
networks.livenet.toString().should.equal('livenet');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@ -17,10 +17,10 @@ var invalidbase58 = require('./data/bitcoind/base58_keys_invalid.json');
|
||||
describe('PrivateKey', function() {
|
||||
var hex = '96c132224121b509b7d0a16245e957d9192609c5637c6228311287b1be21627a';
|
||||
var buf = new Buffer(hex, 'hex');
|
||||
var enctestnet = 'cSdkPxkAjA4HDr5VHgsebAPDEh9Gyub4HK8UJr2DFGGqKKy4K5sG';
|
||||
var enctu = '92jJzK4tbURm1C7udQXxeCBvXHoHJstDXRxAMouPG1k1XUaXdsu';
|
||||
var enclivenet = 'L2Gkw3kKJ6N24QcDuH4XDqt9cTqsKTVNDGz1CRZhk9cq4auDUbJy';
|
||||
var encmu = '5JxgQaFM1FMd38cd14e3mbdxsdSa9iM2BV6DHBYsvGzxkTNQ7Un';
|
||||
var wifTestnet = 'cSdkPxkAjA4HDr5VHgsebAPDEh9Gyub4HK8UJr2DFGGqKKy4K5sG';
|
||||
var wifTestnetUncompressed = '92jJzK4tbURm1C7udQXxeCBvXHoHJstDXRxAMouPG1k1XUaXdsu';
|
||||
var wifLivenet = 'L2Gkw3kKJ6N24QcDuH4XDqt9cTqsKTVNDGz1CRZhk9cq4auDUbJy';
|
||||
var wifLivenetUncompressed = '5JxgQaFM1FMd38cd14e3mbdxsdSa9iM2BV6DHBYsvGzxkTNQ7Un';
|
||||
|
||||
it('should create a new random private key', function() {
|
||||
var a = new PrivateKey();
|
||||
@ -66,75 +66,82 @@ describe('PrivateKey', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should not be able to instantiate private key greater than N', function() {
|
||||
expect(function() {
|
||||
var n = Point.getN();
|
||||
var a = new PrivateKey(n);
|
||||
}).to.throw('Number must be less than N');
|
||||
});
|
||||
describe('instantiation', function() {
|
||||
it('should not be able to instantiate private key greater than N', function() {
|
||||
expect(function() {
|
||||
return new PrivateKey(Point.getN());
|
||||
}).to.throw('Number must be less than N');
|
||||
});
|
||||
|
||||
it('should not be able to instantiate private key because of network mismatch', function() {
|
||||
expect(function() {
|
||||
var a = new PrivateKey('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m', 'testnet');
|
||||
}).to.throw('Private key network mismatch');
|
||||
});
|
||||
it('should not be able to instantiate private key because of network mismatch', function() {
|
||||
expect(function() {
|
||||
return new PrivateKey('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m', 'testnet');
|
||||
}).to.throw('Private key network mismatch');
|
||||
});
|
||||
|
||||
it('should not be able to instantiate private key WIF is too long', function() {
|
||||
expect(function() {
|
||||
var buf = base58check.decode('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m');
|
||||
var buf2 = Buffer.concat([buf, new Buffer(0x01)]);
|
||||
var a = new PrivateKey(buf2);
|
||||
}).to.throw('Length of buffer must be 33 (uncompressed) or 34 (compressed');
|
||||
});
|
||||
it('should not be able to instantiate private key WIF is too long', function() {
|
||||
expect(function() {
|
||||
var buf = base58check.decode('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m');
|
||||
var buf2 = Buffer.concat([buf, new Buffer(0x01)]);
|
||||
return new PrivateKey(buf2);
|
||||
}).to.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() {
|
||||
expect(function() {
|
||||
var buf = base58check.decode('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m');
|
||||
var buf2 = Buffer.concat([new Buffer('ff', 'hex'), buf.slice(1, 33)]);
|
||||
var a = new PrivateKey(buf2);
|
||||
}).to.throw('Invalid network');
|
||||
});
|
||||
it('should not be able to instantiate private key WIF because of unknown network byte', function() {
|
||||
expect(function() {
|
||||
var buf = base58check.decode('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m');
|
||||
var buf2 = Buffer.concat([new Buffer('ff', 'hex'), buf.slice(1, 33)]);
|
||||
return new PrivateKey(buf2);
|
||||
}).to.throw('Invalid network');
|
||||
});
|
||||
|
||||
it('can be instantiated from a hex string', function() {
|
||||
var privhex = '906977a061af29276e40bf377042ffbde414e496ae2260bbf1fa9d085637bfff';
|
||||
var pubhex = '02a1633cafcc01ebfb6d78e39f687a1f0995c62fc95f51ead10a02ee0be551b5dc';
|
||||
var privkey = new PrivateKey(privhex);
|
||||
privkey.publicKey.toString().should.equal(pubhex);
|
||||
});
|
||||
it('can be instantiated from a hex string', function() {
|
||||
var privhex = '906977a061af29276e40bf377042ffbde414e496ae2260bbf1fa9d085637bfff';
|
||||
var pubhex = '02a1633cafcc01ebfb6d78e39f687a1f0995c62fc95f51ead10a02ee0be551b5dc';
|
||||
var privkey = new PrivateKey(privhex);
|
||||
privkey.publicKey.toString().should.equal(pubhex);
|
||||
});
|
||||
|
||||
it('should not be able to instantiate because of unrecognized data', function() {
|
||||
expect(function() {
|
||||
var a = new PrivateKey(new Error());
|
||||
}).to.throw('First argument is an unrecognized data type.');
|
||||
});
|
||||
it('should not be able to instantiate because of unrecognized data', function() {
|
||||
expect(function() {
|
||||
return new PrivateKey(new Error());
|
||||
}).to.throw('First argument is an unrecognized data type.');
|
||||
});
|
||||
|
||||
it('should not be able to instantiate with unknown network', function() {
|
||||
expect(function() {
|
||||
var a = new PrivateKey(BN(2), 'unknown');
|
||||
}).to.throw('Must specify the network ("livenet" or "testnet")');
|
||||
});
|
||||
it('should not be able to instantiate with unknown network', function() {
|
||||
expect(function() {
|
||||
return new PrivateKey(BN(2), 'unknown');
|
||||
}).to.throw('Must specify the network ("livenet" or "testnet")');
|
||||
});
|
||||
|
||||
it('should not create a zero private key', function() {
|
||||
expect(function() {
|
||||
var bn = BN(0);
|
||||
var privkey = new PrivateKey(bn);
|
||||
}).to.throw(TypeError);
|
||||
});
|
||||
it('should not create a zero private key', function() {
|
||||
expect(function() {
|
||||
var bn = BN(0);
|
||||
return new PrivateKey(bn);
|
||||
}).to.throw(TypeError);
|
||||
});
|
||||
|
||||
it('should create a livenet private key', function() {
|
||||
var privkey = new PrivateKey(BN.fromBuffer(buf), 'livenet');
|
||||
privkey.toString().should.equal(enclivenet);
|
||||
});
|
||||
it('should create a livenet private key', function() {
|
||||
var privkey = new PrivateKey(BN.fromBuffer(buf), 'livenet');
|
||||
privkey.toString().should.equal(wifLivenet);
|
||||
});
|
||||
|
||||
it('should create a default network private key', function() {
|
||||
var a = new PrivateKey(BN.fromBuffer(buf));
|
||||
a.network.should.equal(Networks.livenet);
|
||||
// change the default
|
||||
Networks.defaultNetwork = Networks.testnet;
|
||||
var b = new PrivateKey(BN.fromBuffer(buf));
|
||||
b.network.should.equal(Networks.testnet);
|
||||
// restore the default
|
||||
Networks.defaultNetwork = Networks.livenet;
|
||||
});
|
||||
|
||||
it('returns the same instance if a PrivateKey is provided (immutable)', function() {
|
||||
var privkey = new PrivateKey();
|
||||
new PrivateKey(privkey).should.equal(privkey);
|
||||
});
|
||||
|
||||
it('should create a default network private key', function() {
|
||||
var a = new PrivateKey(BN.fromBuffer(buf));
|
||||
a.network.should.equal(Networks.livenet);
|
||||
// change the default
|
||||
Networks.defaultNetwork = Networks.testnet;
|
||||
var b = new PrivateKey(BN.fromBuffer(buf));
|
||||
b.network.should.equal(Networks.testnet);
|
||||
// restore the default
|
||||
Networks.defaultNetwork = Networks.livenet;
|
||||
});
|
||||
|
||||
describe('#json', function() {
|
||||
@ -148,13 +155,37 @@ describe('PrivateKey', function() {
|
||||
PrivateKey.fromJSON(json).toJSON().should.deep.equal(json);
|
||||
});
|
||||
|
||||
it('an object with private key info can be also used as argument for "fromJSON"', function() {
|
||||
expect(PrivateKey._isJSON({bn: true, network: true})).to.equal(true);
|
||||
});
|
||||
|
||||
it('fails on invalid argument', function() {
|
||||
expect(function() {
|
||||
return PrivateKey.fromJSON('¹');
|
||||
}).to.throw();
|
||||
});
|
||||
|
||||
it('also accepts an object as argument', function() {
|
||||
expect(function() {
|
||||
return PrivateKey.fromJSON(new PrivateKey().toObject());
|
||||
}).to.not.throw();
|
||||
});
|
||||
});
|
||||
|
||||
it('coverage: public key cache', function() {
|
||||
expect(function() {
|
||||
var privateKey = new PrivateKey();
|
||||
/* jshint unused: false */
|
||||
var publicKey = privateKey.publicKey;
|
||||
return privateKey.publicKey;
|
||||
}).to.not.throw();
|
||||
});
|
||||
|
||||
describe('#toString', function() {
|
||||
|
||||
it('should output this address correctly', function() {
|
||||
var privkey = PrivateKey.fromWIF(encmu);
|
||||
privkey.toString().should.equal(encmu);
|
||||
var privkey = PrivateKey.fromWIF(wifLivenetUncompressed);
|
||||
privkey.toString().should.equal(wifLivenetUncompressed);
|
||||
});
|
||||
|
||||
});
|
||||
@ -177,14 +208,22 @@ describe('PrivateKey', function() {
|
||||
describe('#inspect', function() {
|
||||
it('should output known livenet address for console', function() {
|
||||
var privkey = PrivateKey.fromWIF('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m');
|
||||
privkey.inspect().should.equal('<PrivateKey: L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m, network: livenet>');
|
||||
privkey.inspect().should.equal(
|
||||
'<PrivateKey: L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m, network: livenet>'
|
||||
);
|
||||
});
|
||||
|
||||
it('should output known testnet address for console', function() {
|
||||
var privkey = PrivateKey.fromWIF('cR4qogdN9UxLZJXCNFNwDRRZNeLRWuds9TTSuLNweFVjiaE4gPaq');
|
||||
privkey.inspect().should.equal('<PrivateKey: cR4qogdN9UxLZJXCNFNwDRRZNeLRWuds9TTSuLNweFVjiaE4gPaq, network: testnet>');
|
||||
privkey.inspect().should.equal(
|
||||
'<PrivateKey: cR4qogdN9UxLZJXCNFNwDRRZNeLRWuds9TTSuLNweFVjiaE4gPaq, network: testnet>'
|
||||
);
|
||||
});
|
||||
|
||||
it('outputs "uncompressed" for uncompressed imported WIFs', function() {
|
||||
var privkey = PrivateKey.fromWIF(wifLivenetUncompressed);
|
||||
privkey.inspect().should.equal('<PrivateKey: ' + wifLivenetUncompressed + ', network: livenet, uncompressed>');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getValidationError', function(){
|
||||
@ -210,7 +249,7 @@ describe('PrivateKey', function() {
|
||||
describe('#toBuffer', function() {
|
||||
it('should output known buffer', function() {
|
||||
var privkey = new PrivateKey(BN.fromBuffer(buf), 'livenet');
|
||||
var b = privkey.toBuffer().toString('hex').should.equal(buf.toString('hex'));
|
||||
privkey.toBuffer().toString('hex').should.equal(buf.toString('hex'));
|
||||
});
|
||||
});
|
||||
|
||||
@ -237,8 +276,8 @@ describe('PrivateKey', function() {
|
||||
describe('#fromWIF', function() {
|
||||
|
||||
it('should parse this compressed testnet address correctly', function() {
|
||||
var privkey = PrivateKey.fromWIF(enclivenet);
|
||||
privkey.toWIF().should.equal(enclivenet);
|
||||
var privkey = PrivateKey.fromWIF(wifLivenet);
|
||||
privkey.toWIF().should.equal(wifLivenet);
|
||||
});
|
||||
|
||||
});
|
||||
@ -246,8 +285,8 @@ describe('PrivateKey', function() {
|
||||
describe('#toWIF', function() {
|
||||
|
||||
it('should parse this compressed testnet address correctly', function() {
|
||||
var privkey = PrivateKey.fromWIF(enctestnet);
|
||||
privkey.toWIF().should.equal(enctestnet);
|
||||
var privkey = PrivateKey.fromWIF(wifTestnet);
|
||||
privkey.toWIF().should.equal(wifTestnet);
|
||||
});
|
||||
|
||||
});
|
||||
@ -255,8 +294,8 @@ describe('PrivateKey', function() {
|
||||
describe('#fromString', function() {
|
||||
|
||||
it('should parse this uncompressed testnet address correctly', function() {
|
||||
var privkey = PrivateKey.fromString(enctu);
|
||||
privkey.toWIF().should.equal(enctu);
|
||||
var privkey = PrivateKey.fromString(wifTestnetUncompressed);
|
||||
privkey.toWIF().should.equal(wifTestnetUncompressed);
|
||||
});
|
||||
|
||||
});
|
||||
@ -264,13 +303,13 @@ describe('PrivateKey', function() {
|
||||
describe('#toString', function() {
|
||||
|
||||
it('should parse this uncompressed livenet address correctly', function() {
|
||||
var privkey = PrivateKey.fromString(encmu);
|
||||
privkey.toString().should.equal(encmu);
|
||||
var privkey = PrivateKey.fromString(wifLivenetUncompressed);
|
||||
privkey.toString().should.equal(wifLivenetUncompressed);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("#toPublicKey", function() {
|
||||
describe('#toPublicKey', function() {
|
||||
|
||||
it('should convert this known PrivateKey to known PublicKey', function() {
|
||||
var privhex = '906977a061af29276e40bf377042ffbde414e496ae2260bbf1fa9d085637bfff';
|
||||
@ -304,12 +343,12 @@ describe('PrivateKey', function() {
|
||||
});
|
||||
|
||||
it('creates an address as expected from WIF, livenet', function() {
|
||||
var privkey = new PrivateKey('5J2NYGstJg7aJQEqNwYp4enG5BSfFdKXVTtBLvHicnRGD5kjxi6')
|
||||
var privkey = new PrivateKey('5J2NYGstJg7aJQEqNwYp4enG5BSfFdKXVTtBLvHicnRGD5kjxi6');
|
||||
privkey.publicKey.toAddress().toString().should.equal('135bwugFCmhmNU3SeCsJeTqvo5ViymgwZ9');
|
||||
});
|
||||
|
||||
it('creates an address as expected from WIF, testnet', function() {
|
||||
var privkey = new PrivateKey('92VYMmwFLXRwXn5688edGxYYgMFsc3fUXYhGp17WocQhU6zG1kd')
|
||||
var privkey = new PrivateKey('92VYMmwFLXRwXn5688edGxYYgMFsc3fUXYhGp17WocQhU6zG1kd');
|
||||
privkey.publicKey.toAddress().toString().should.equal('moiAvLUw16qgrwhFGo1eDnXHC2wPMYiv7Y');
|
||||
});
|
||||
|
||||
|
||||
@ -1,83 +1,94 @@
|
||||
'use strict';
|
||||
|
||||
var should = require('chai').should();
|
||||
var expect = require('chai').expect;
|
||||
|
||||
var bitcore = require('..');
|
||||
var Point = bitcore.crypto.Point;
|
||||
var BN = bitcore.crypto.BN;
|
||||
var PublicKey = bitcore.PublicKey;
|
||||
var PrivateKey = bitcore.PrivateKey;
|
||||
|
||||
// DER uncompressed format
|
||||
/* jshint maxlen: 200 */
|
||||
|
||||
describe('PublicKey', function() {
|
||||
/* jshint maxstatements: 30 */
|
||||
|
||||
var invalidPoint = '0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';
|
||||
|
||||
it('should error because of missing data', function() {
|
||||
(function() {
|
||||
var pk = new PublicKey();
|
||||
}).should.throw('First argument is required, please include public key data.');
|
||||
describe('validating errors on creation', function() {
|
||||
it('errors if data is missing', function() {
|
||||
(function() {
|
||||
return new PublicKey();
|
||||
}).should.throw('First argument is required, please include public key data.');
|
||||
});
|
||||
|
||||
it('errors if an invalid point is provided', function() {
|
||||
(function() {
|
||||
return new PublicKey(invalidPoint);
|
||||
}).should.throw('Invalid x,y value for curve, cannot equal 0.');
|
||||
});
|
||||
|
||||
it('errors if a point not on the secp256k1 curve is provided', function() {
|
||||
(function() {
|
||||
return new PublicKey(new Point(1000, 1000));
|
||||
}).should.throw('Invalid y value for curve.');
|
||||
});
|
||||
|
||||
it('errors if the argument is of an unrecognized type', function() {
|
||||
(function() {
|
||||
return new PublicKey(new Error());
|
||||
}).should.throw('First argument is an unrecognized data format.');
|
||||
});
|
||||
});
|
||||
|
||||
it('should error because of an invalid point', function() {
|
||||
(function() {
|
||||
var pk = new PublicKey(invalidPoint);
|
||||
}).should.throw('Invalid x,y value for curve, cannot equal 0.');
|
||||
describe('instantiation', function() {
|
||||
it('from a private key', function() {
|
||||
var privhex = '906977a061af29276e40bf377042ffbde414e496ae2260bbf1fa9d085637bfff';
|
||||
var pubhex = '02a1633cafcc01ebfb6d78e39f687a1f0995c62fc95f51ead10a02ee0be551b5dc';
|
||||
var privkey = new PrivateKey(BN(new Buffer(privhex, 'hex')));
|
||||
var pk = new PublicKey(privkey);
|
||||
pk.toString().should.equal(pubhex);
|
||||
});
|
||||
|
||||
it('from a compressed public key', function() {
|
||||
var publicKeyHex = '031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a';
|
||||
var publicKey = new PublicKey(publicKeyHex);
|
||||
publicKey.toString().should.equal(publicKeyHex);
|
||||
});
|
||||
|
||||
it('from another publicKey', function() {
|
||||
var publicKeyHex = '031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a';
|
||||
var publicKey = new PublicKey(publicKeyHex);
|
||||
var publicKey2 = new PublicKey(publicKey);
|
||||
publicKey.should.equal(publicKey2);
|
||||
});
|
||||
|
||||
it('from a hex encoded DER string', function() {
|
||||
var pk = new PublicKey('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341');
|
||||
should.exist(pk.point);
|
||||
pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a');
|
||||
});
|
||||
|
||||
it('from a hex encoded DER buffer', function() {
|
||||
var pk = new PublicKey(new Buffer('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341', 'hex'));
|
||||
should.exist(pk.point);
|
||||
pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a');
|
||||
});
|
||||
|
||||
it('from a point', function() {
|
||||
var p = new Point('86a80a5a2bfc48dddde2b0bd88bd56b0b6ddc4e6811445b175b90268924d7d48',
|
||||
'3b402dfc89712cfe50963e670a0598e6b152b3cd94735001cdac6794975d3afd');
|
||||
var a = new PublicKey(p);
|
||||
should.exist(a.point);
|
||||
a.point.toString().should.equal(p.toString());
|
||||
var c = new PublicKey(p);
|
||||
should.exist(c.point);
|
||||
c.point.toString().should.equal(p.toString());
|
||||
});
|
||||
});
|
||||
|
||||
it('should error because of an invalid public key point, not on the secp256k1 curve', function() {
|
||||
(function() {
|
||||
var pk = new PublicKey(Point(1000, 1000));
|
||||
}).should.throw('Invalid y value for curve.');
|
||||
});
|
||||
|
||||
it('should error because of an unrecognized data type', function() {
|
||||
(function() {
|
||||
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 PrivateKey(BN(new Buffer(privhex, 'hex')));
|
||||
var pk = new PublicKey(privkey);
|
||||
pk.toString().should.equal(pubhex);
|
||||
});
|
||||
|
||||
it('should instantiate from a compressed public key', function() {
|
||||
var publicKeyHex = '031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a';
|
||||
var publicKey = new PublicKey(publicKeyHex);
|
||||
publicKey.toString().should.equal(publicKeyHex);
|
||||
});
|
||||
|
||||
it('should instantiate from another publicKey', function() {
|
||||
var publicKeyHex = '031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a';
|
||||
var publicKey = new PublicKey(publicKeyHex);
|
||||
var publicKey2 = new PublicKey(publicKey);
|
||||
publicKey.should.equal(publicKey2);
|
||||
});
|
||||
|
||||
it('should instantiate from a hex encoded DER string', function() {
|
||||
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 PublicKey(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('86a80a5a2bfc48dddde2b0bd88bd56b0b6ddc4e6811445b175b90268924d7d48',
|
||||
'3b402dfc89712cfe50963e670a0598e6b152b3cd94735001cdac6794975d3afd');
|
||||
var a = new PublicKey(p);
|
||||
should.exist(a.point);
|
||||
a.point.toString().should.equal(p.toString());
|
||||
var c = PublicKey(p);
|
||||
should.exist(c.point);
|
||||
c.point.toString().should.equal(p.toString());
|
||||
});
|
||||
|
||||
describe('#getValidationError', function(){
|
||||
|
||||
@ -107,8 +118,8 @@ describe('PublicKey', function() {
|
||||
describe('#fromPoint', function() {
|
||||
|
||||
it('should instantiate from a point', function() {
|
||||
var p = Point('86a80a5a2bfc48dddde2b0bd88bd56b0b6ddc4e6811445b175b90268924d7d48',
|
||||
'3b402dfc89712cfe50963e670a0598e6b152b3cd94735001cdac6794975d3afd');
|
||||
var p = new Point('86a80a5a2bfc48dddde2b0bd88bd56b0b6ddc4e6811445b175b90268924d7d48',
|
||||
'3b402dfc89712cfe50963e670a0598e6b152b3cd94735001cdac6794975d3afd');
|
||||
var b = PublicKey.fromPoint(p);
|
||||
should.exist(b.point);
|
||||
b.point.toString().should.equal(p.toString());
|
||||
@ -132,6 +143,18 @@ describe('PublicKey', function() {
|
||||
PublicKey.fromJSON(json).toJSON().should.deep.equal(json);
|
||||
});
|
||||
|
||||
it('fails if "y" is not provided', function() {
|
||||
expect(function() {
|
||||
return PublicKey.fromJSON('{"x": "1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a"}');
|
||||
}).to.throw();
|
||||
});
|
||||
|
||||
it('fails if invalid JSON is provided', function() {
|
||||
expect(function() {
|
||||
return PublicKey._transformJSON('¹');
|
||||
}).to.throw();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#fromPrivateKey', function() {
|
||||
@ -227,7 +250,7 @@ describe('PublicKey', function() {
|
||||
it('should error because odd was not included as a param', function() {
|
||||
var x = BN.fromBuffer(new Buffer('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex'));
|
||||
(function() {
|
||||
var pk = PublicKey.fromX(null, x);
|
||||
return PublicKey.fromX(null, x);
|
||||
}).should.throw('Must specify whether y is odd or not (true or false)');
|
||||
});
|
||||
|
||||
@ -312,26 +335,28 @@ describe('PublicKey', function() {
|
||||
|
||||
it('should not have an error if pubkey is valid', function() {
|
||||
var hex = '031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a';
|
||||
var pk = PublicKey.fromString(hex);
|
||||
expect(function() {
|
||||
return PublicKey.fromString(hex);
|
||||
}).to.not.throw();
|
||||
});
|
||||
|
||||
it('should throw an error if pubkey is invalid', function() {
|
||||
var hex = '041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a0000000000000000000000000000000000000000000000000000000000000000';
|
||||
(function() {
|
||||
var pk = PublicKey.fromString(hex);
|
||||
return PublicKey.fromString(hex);
|
||||
}).should.throw('Invalid x,y value for curve, cannot equal 0.');
|
||||
});
|
||||
|
||||
it('should throw an error if pubkey is invalid', function() {
|
||||
var hex = '041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a00000000000000000000000000000000000000000000000000000000000000FF';
|
||||
(function() {
|
||||
var pk = PublicKey.fromString(hex);
|
||||
return PublicKey.fromString(hex);
|
||||
}).should.throw('Invalid y value for curve.');
|
||||
});
|
||||
|
||||
it('should throw an error if pubkey is infinity', function() {
|
||||
(function() {
|
||||
var pk = new PublicKey(Point.getG().mul(Point.getN()));
|
||||
return new PublicKey(Point.getG().mul(Point.getN()));
|
||||
}).should.throw('Point cannot be equal to Infinity');
|
||||
});
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user