'use strict'; var should = require('chai').should(); var bitcore = require('..'); var Point = bitcore.crypto.Point; var BN = bitcore.crypto.BN; var PublicKey = bitcore.PublicKey; var PrivateKey = bitcore.PrivateKey; describe('PublicKey', function() { 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.'); }); 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.'); }); 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(){ it('should recieve an invalid point error', function() { var error = PublicKey.getValidationError(invalidPoint); should.exist(error); error.message.should.equal('Invalid x,y value for curve, cannot equal 0.'); }); it('should recieve a boolean as false', function() { var valid = PublicKey.isValid(invalidPoint); valid.should.equal(false); }); it('should recieve a boolean as true for uncompressed', function() { var valid = PublicKey.isValid('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); valid.should.equal(true); }); it('should recieve a boolean as true for compressed', function() { var valid = PublicKey.isValid('031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); valid.should.equal(true); }); }); describe('#fromPoint', function() { it('should instantiate from a point', function() { var p = Point('86a80a5a2bfc48dddde2b0bd88bd56b0b6ddc4e6811445b175b90268924d7d48', '3b402dfc89712cfe50963e670a0598e6b152b3cd94735001cdac6794975d3afd'); 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() { PublicKey.fromPoint(new Error()); }).should.throw('First argument must be an instance of Point.'); }); }); describe('#json', function() { it('should input/ouput json', function() { var json = JSON.stringify({ x: '1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', y: '7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341', compressed: false }); PublicKey.fromJSON(json).toJSON().should.deep.equal(json); }); }); describe('#fromPrivateKey', function() { it('should make a public key from a privkey', function() { should.exist(PublicKey.fromPrivateKey(PrivateKey.fromRandom())); }); it('should error because not an instance of privkey', function() { (function() { PublicKey.fromPrivateKey(new Error()); }).should.throw('Must be an instance of PrivateKey'); }); }); describe('#fromBuffer', function() { it('should parse this uncompressed public key', function() { 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 = 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() { PublicKey.fromBuffer(new Buffer('091ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); }).should.throw(); }); it('should throw error because not a buffer', function() { (function() { 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() { PublicKey.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 = 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 = 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() { PublicKey.fromDER(new Buffer('091ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); }).should.throw(); }); }); describe('#fromString', function() { it('should parse this known valid public key', function() { var pk = PublicKey.fromString('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); pk.point.getY().toString(16).should.equal('7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); }); }); describe('#fromX', function() { it('should create this known public key', function() { var x = BN.fromBuffer(new Buffer('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); var pk = PublicKey.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 = PublicKey.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 = PublicKey.fromX(true, x); pk.toBuffer().toString('hex').should.equal('031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); }); it('should return this uncompressed DER format', function() { var x = BN.fromBuffer(new Buffer('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); var pk = PublicKey.fromX(true, x); pk.toBuffer().toString('hex').should.equal('031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); }); }); describe('#toDER', function() { it('should return this compressed DER format', function() { var x = BN.fromBuffer(new Buffer('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a', 'hex')); var pk = PublicKey.fromX(true, x); pk.toDER().toString('hex').should.equal('031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); }); it('should return this uncompressed DER format', function() { var pk = PublicKey.fromString('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); pk.toDER().toString('hex').should.equal('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); }); }); describe('#toAddress', function() { it('should output this known mainnet address correctly', function() { var pk = new PublicKey('03c87bd0e162f26969da8509cafcb7b8c8d202af30b928c582e263dd13ee9a9781'); var address = pk.toAddress('livenet'); address.toString().should.equal('1A6ut1tWnUq1SEQLMr4ttDh24wcbJ5o9TT'); }); it('should output this known testnet address correctly', function() { var pk = new PublicKey('0293126ccc927c111b88a0fe09baa0eca719e2a3e087e8a5d1059163f5c566feef'); var address = pk.toAddress('testnet'); address.toString().should.equal('mtX8nPZZdJ8d3QNLRJ1oJTiEi26Sj6LQXS'); }); }); describe('#toString', function() { it('should print this known public key', function() { var hex = '031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'; var pk = PublicKey.fromString(hex); pk.toString().should.equal(hex); }); }); describe('#inspect', function() { it('should output known uncompressed pubkey for console', function() { var pubkey = PublicKey.fromString('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341'); pubkey.inspect().should.equal(''); }); it('should output known compressed pubkey for console', function() { var pubkey = PublicKey.fromString('031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'); pubkey.inspect().should.equal(''); }); it('should output known compressed pubkey with network for console', function() { var privkey = PrivateKey.fromWIF('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m'); var pubkey = new PublicKey(privkey); pubkey.inspect().should.equal(''); }); }); describe('#validate', function() { it('should not have an error if pubkey is valid', function() { var hex = '031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'; var pk = PublicKey.fromString(hex); }); it('should throw an error if pubkey is invalid', function() { var hex = '041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a0000000000000000000000000000000000000000000000000000000000000000'; (function() { var pk = 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); }).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())); }).should.throw('Point cannot be equal to Infinity'); }); }); });