Merge pull request #581 from braydonf/feature/keys-interface-rename
Keys: Modified interface of Pubkey and Privkey so that an instance can be relied upon as valid.
This commit is contained in:
commit
5ff732f52b
4
index.js
4
index.js
|
@ -24,8 +24,8 @@ bitcore.Block = require('./lib/block');
|
||||||
bitcore.Blockheader = require('./lib/blockheader');
|
bitcore.Blockheader = require('./lib/blockheader');
|
||||||
bitcore.Networks = require('./lib/networks');
|
bitcore.Networks = require('./lib/networks');
|
||||||
bitcore.Opcode = require('./lib/opcode');
|
bitcore.Opcode = require('./lib/opcode');
|
||||||
bitcore.Privkey = require('./lib/privkey');
|
bitcore.PrivateKey = require('./lib/privatekey');
|
||||||
bitcore.Pubkey = require('./lib/pubkey');
|
bitcore.PublicKey = require('./lib/publickey');
|
||||||
bitcore.Script = require('./lib/script');
|
bitcore.Script = require('./lib/script');
|
||||||
bitcore.Signature = require('./lib/signature');
|
bitcore.Signature = require('./lib/signature');
|
||||||
bitcore.Transaction = require('./lib/transaction');
|
bitcore.Transaction = require('./lib/transaction');
|
||||||
|
|
|
@ -9,7 +9,7 @@ var Hash = require('./crypto/hash');
|
||||||
* Bitcore Address
|
* Bitcore Address
|
||||||
*
|
*
|
||||||
* Instantiate an address from an address String or Buffer, a public key or script hash Buffer,
|
* 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
|
* @example
|
||||||
*
|
*
|
||||||
|
@ -45,8 +45,8 @@ function Address(data, network, type) {
|
||||||
info = Address._transformHash(data);
|
info = Address._transformHash(data);
|
||||||
} else if ((data instanceof Buffer || data instanceof Uint8Array) && data.length === 21) {
|
} else if ((data instanceof Buffer || data instanceof Uint8Array) && data.length === 21) {
|
||||||
info = Address._transformBuffer(data, network, type);
|
info = Address._transformBuffer(data, network, type);
|
||||||
} else if (data.constructor && (data.constructor.name && data.constructor.name === 'Pubkey')) {
|
} else if (data.constructor && (data.constructor.name && data.constructor.name === 'PublicKey')) {
|
||||||
info = Address._transformPubkey(data);
|
info = Address._transformPublicKey(data);
|
||||||
} else if (data.constructor && (data.constructor.name && data.constructor.name === 'Script')) {
|
} else if (data.constructor && (data.constructor.name && data.constructor.name === 'Script')) {
|
||||||
info = Address._transformScript(data);
|
info = Address._transformScript(data);
|
||||||
} else if (typeof(data) === 'string') {
|
} 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
|
* @returns {Object} An object with keys: hashBuffer, type
|
||||||
*/
|
*/
|
||||||
Address._transformPubkey = function(pubkey){
|
Address._transformPublicKey = function(pubkey){
|
||||||
var info = {};
|
var info = {};
|
||||||
if (!pubkey.constructor || (pubkey.constructor.name && pubkey.constructor.name !== 'Pubkey')) {
|
if (!pubkey.constructor || (pubkey.constructor.name && pubkey.constructor.name !== 'PublicKey')) {
|
||||||
throw new TypeError('Address must be an instance of Pubkey.');
|
throw new TypeError('Address must be an instance of PublicKey.');
|
||||||
}
|
}
|
||||||
info.hashBuffer = Hash.sha256ripemd160(pubkey.toBuffer());
|
info.hashBuffer = Hash.sha256ripemd160(pubkey.toBuffer());
|
||||||
info.type = 'pubkeyhash';
|
info.type = 'pubkeyhash';
|
||||||
|
@ -182,7 +182,7 @@ Address._transformScript = function(script){
|
||||||
*
|
*
|
||||||
* Internal function to transform a bitcoin address string
|
* 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} [network] - The network: 'mainnet' or 'testnet'
|
||||||
* @param {String} [type] - The type: 'pubkeyhash' or 'scripthash'
|
* @param {String} [type] - The type: 'pubkeyhash' or 'scripthash'
|
||||||
* @returns {Object} An object with keys: hashBuffer, network and type
|
* @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'
|
* @param {String} network - The network: 'mainnet' or 'testnet'
|
||||||
* @returns {Address} A new valid and frozen instance of an Address
|
* @returns {Address} A new valid and frozen instance of an Address
|
||||||
*/
|
*/
|
||||||
Address.fromPubkey = function(data, network){
|
Address.fromPublicKey = function(data, network){
|
||||||
var info = Address._transformPubkey(data);
|
var info = Address._transformPublicKey(data);
|
||||||
return new Address(info.hashBuffer, network, info.type);
|
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'
|
* @param {String} network - The network: 'mainnet' or 'testnet'
|
||||||
* @returns {Address} A new valid and frozen instance of an Address
|
* @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);
|
var info = Address._transformHash(hash);
|
||||||
return new Address(info.hashBuffer, network, 'pubkeyhash');
|
return new Address(info.hashBuffer, network, 'pubkeyhash');
|
||||||
};
|
};
|
||||||
|
|
33
lib/bip32.js
33
lib/bip32.js
|
@ -6,8 +6,8 @@ var Hash = require('./crypto/hash');
|
||||||
var Point = require('./crypto/point');
|
var Point = require('./crypto/point');
|
||||||
var Random = require('./crypto/random');
|
var Random = require('./crypto/random');
|
||||||
var BN = require('./crypto/bn');
|
var BN = require('./crypto/bn');
|
||||||
var Pubkey = require('./pubkey');
|
var PublicKey = require('./publickey');
|
||||||
var Privkey = require('./privkey');
|
var PrivateKey = require('./privatekey');
|
||||||
|
|
||||||
var BIP32 = function BIP32(obj) {
|
var BIP32 = function BIP32(obj) {
|
||||||
if (!(this instanceof BIP32))
|
if (!(this instanceof BIP32))
|
||||||
|
@ -41,8 +41,8 @@ BIP32.prototype.fromRandom = function(networkstr) {
|
||||||
this.parentfingerprint = new Buffer([0, 0, 0, 0]);
|
this.parentfingerprint = new Buffer([0, 0, 0, 0]);
|
||||||
this.childindex = new Buffer([0, 0, 0, 0]);
|
this.childindex = new Buffer([0, 0, 0, 0]);
|
||||||
this.chaincode = Random.getRandomBuffer(32);
|
this.chaincode = Random.getRandomBuffer(32);
|
||||||
this.privkey = Privkey().fromRandom();
|
this.privkey = PrivateKey.fromRandom();
|
||||||
this.pubkey = new Pubkey().fromPrivkey(this.privkey);
|
this.pubkey = PublicKey.fromPrivateKey(this.privkey);
|
||||||
this.hasprivkey = true;
|
this.hasprivkey = true;
|
||||||
this.pubkeyhash = Hash.sha256ripemd160(this.pubkey.toBuffer());
|
this.pubkeyhash = Hash.sha256ripemd160(this.pubkey.toBuffer());
|
||||||
this.buildxpubkey();
|
this.buildxpubkey();
|
||||||
|
@ -72,8 +72,8 @@ BIP32.prototype.fromSeed = function(bytes, networkstr) {
|
||||||
this.childindex = new Buffer([0, 0, 0, 0]);
|
this.childindex = new Buffer([0, 0, 0, 0]);
|
||||||
this.chaincode = hash.slice(32, 64);
|
this.chaincode = hash.slice(32, 64);
|
||||||
this.version = networks[networkstr].bip32privkey;
|
this.version = networks[networkstr].bip32privkey;
|
||||||
this.privkey = new Privkey({bn: BN().fromBuffer(hash.slice(0, 32))});
|
this.privkey = new PrivateKey(BN().fromBuffer(hash.slice(0, 32)));
|
||||||
this.pubkey = new Pubkey().fromPrivkey(this.privkey);
|
this.pubkey = PublicKey.fromPrivateKey(this.privkey);
|
||||||
this.hasprivkey = true;
|
this.hasprivkey = true;
|
||||||
this.pubkeyhash = Hash.sha256ripemd160(this.pubkey.toBuffer());
|
this.pubkeyhash = Hash.sha256ripemd160(this.pubkey.toBuffer());
|
||||||
|
|
||||||
|
@ -105,12 +105,12 @@ BIP32.prototype.initFromBytes = function(bytes) {
|
||||||
this.version == networks.testnet.bip32pubkey);
|
this.version == networks.testnet.bip32pubkey);
|
||||||
|
|
||||||
if (isPrivate && keyBytes[0] == 0) {
|
if (isPrivate && keyBytes[0] == 0) {
|
||||||
this.privkey = new Privkey({bn: BN().fromBuffer(keyBytes.slice(1, 33))});
|
this.privkey = new PrivateKey(BN().fromBuffer(keyBytes.slice(1, 33)));
|
||||||
this.pubkey = new Pubkey().fromPrivkey(this.privkey);
|
this.pubkey = PublicKey.fromPrivateKey(this.privkey);
|
||||||
this.pubkeyhash = Hash.sha256ripemd160(this.pubkey.toBuffer());
|
this.pubkeyhash = Hash.sha256ripemd160(this.pubkey.toBuffer());
|
||||||
this.hasprivkey = true;
|
this.hasprivkey = true;
|
||||||
} else if (isPublic && (keyBytes[0] == 0x02 || keyBytes[0] == 0x03)) {
|
} else if (isPublic && (keyBytes[0] == 0x02 || keyBytes[0] == 0x03)) {
|
||||||
this.pubkey = (new Pubkey()).fromDER(keyBytes);
|
this.pubkey = PublicKey.fromDER(keyBytes);
|
||||||
this.pubkeyhash = Hash.sha256ripemd160(this.pubkey.toBuffer());
|
this.pubkeyhash = Hash.sha256ripemd160(this.pubkey.toBuffer());
|
||||||
this.hasprivkey = false;
|
this.hasprivkey = false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -119,7 +119,7 @@ BIP32.prototype.initFromBytes = function(bytes) {
|
||||||
|
|
||||||
this.buildxpubkey();
|
this.buildxpubkey();
|
||||||
this.buildxprivkey();
|
this.buildxprivkey();
|
||||||
}
|
};
|
||||||
|
|
||||||
BIP32.prototype.buildxpubkey = function() {
|
BIP32.prototype.buildxpubkey = function() {
|
||||||
this.xpubkey = new Buffer([]);
|
this.xpubkey = new Buffer([]);
|
||||||
|
@ -153,7 +153,7 @@ BIP32.prototype.buildxpubkey = function() {
|
||||||
this.chaincode,
|
this.chaincode,
|
||||||
this.pubkey.toBuffer()
|
this.pubkey.toBuffer()
|
||||||
]);
|
]);
|
||||||
}
|
};
|
||||||
|
|
||||||
BIP32.prototype.xpubkeyString = function(format) {
|
BIP32.prototype.xpubkeyString = function(format) {
|
||||||
if (format === undefined || format === 'base58') {
|
if (format === undefined || format === 'base58') {
|
||||||
|
@ -228,7 +228,7 @@ BIP32.prototype.derive = function(path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return bip32;
|
return bip32;
|
||||||
}
|
};
|
||||||
|
|
||||||
BIP32.prototype.deriveChild = function(i) {
|
BIP32.prototype.deriveChild = function(i) {
|
||||||
if (typeof i !== 'number')
|
if (typeof i !== 'number')
|
||||||
|
@ -270,8 +270,8 @@ BIP32.prototype.deriveChild = function(i) {
|
||||||
ret = new BIP32();
|
ret = new BIP32();
|
||||||
ret.chaincode = ir;
|
ret.chaincode = ir;
|
||||||
|
|
||||||
ret.privkey = new Privkey({bn: k});
|
ret.privkey = new PrivateKey(k);
|
||||||
ret.pubkey = new Pubkey().fromPrivkey(ret.privkey);
|
ret.pubkey = PublicKey.fromPrivateKey(ret.privkey);
|
||||||
ret.hasprivkey = true;
|
ret.hasprivkey = true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -284,8 +284,7 @@ BIP32.prototype.deriveChild = function(i) {
|
||||||
var ilG = Point.getG().mul(il);
|
var ilG = Point.getG().mul(il);
|
||||||
var Kpar = this.pubkey.point;
|
var Kpar = this.pubkey.point;
|
||||||
var Ki = ilG.add(Kpar);
|
var Ki = ilG.add(Kpar);
|
||||||
var newpub = new Pubkey();
|
var newpub = PublicKey.fromPoint(Ki);
|
||||||
newpub.point = Ki;
|
|
||||||
|
|
||||||
ret = new BIP32();
|
ret = new BIP32();
|
||||||
ret.chaincode = ir;
|
ret.chaincode = ir;
|
||||||
|
@ -305,7 +304,7 @@ BIP32.prototype.deriveChild = function(i) {
|
||||||
ret.buildxprivkey();
|
ret.buildxprivkey();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
};
|
||||||
|
|
||||||
BIP32.prototype.toString = function() {
|
BIP32.prototype.toString = function() {
|
||||||
var isPrivate =
|
var isPrivate =
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
var BN = require('./bn');
|
var BN = require('./bn');
|
||||||
var Point = require('./point');
|
var Point = require('./point');
|
||||||
var Random = require('./random');
|
var Random = require('./random');
|
||||||
var Pubkey = require('../pubkey');
|
var PublicKey = require('../publickey');
|
||||||
var Privkey = require('../privkey');
|
var PrivateKey = require('../privatekey');
|
||||||
var Signature = require('../signature');
|
var Signature = require('../signature');
|
||||||
|
|
||||||
var ECDSA = function ECDSA(obj) {
|
var ECDSA = function ECDSA(obj) {
|
||||||
|
@ -25,7 +25,7 @@ ECDSA.prototype.set = function(obj) {
|
||||||
};
|
};
|
||||||
|
|
||||||
ECDSA.prototype.privkey2pubkey = function(){
|
ECDSA.prototype.privkey2pubkey = function(){
|
||||||
this.pubkey = Pubkey().fromPrivkey(this.privkey);
|
this.pubkey = PublicKey.fromPrivateKey(this.privkey);
|
||||||
};
|
};
|
||||||
|
|
||||||
ECDSA.prototype.calci = function() {
|
ECDSA.prototype.calci = function() {
|
||||||
|
@ -35,6 +35,7 @@ ECDSA.prototype.calci = function() {
|
||||||
try {
|
try {
|
||||||
Qprime = this.sig2pubkey();
|
Qprime = this.sig2pubkey();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (Qprime.point.eq(this.pubkey.point)) {
|
if (Qprime.point.eq(this.pubkey.point)) {
|
||||||
|
@ -52,9 +53,9 @@ ECDSA.prototype.fromString = function(str) {
|
||||||
if (obj.hashbuf)
|
if (obj.hashbuf)
|
||||||
this.hashbuf = new Buffer(obj.hashbuf, 'hex');
|
this.hashbuf = new Buffer(obj.hashbuf, 'hex');
|
||||||
if (obj.pubkey)
|
if (obj.pubkey)
|
||||||
this.pubkey = Pubkey().fromString(obj.pubkey);
|
this.pubkey = PublicKey.fromString(obj.pubkey);
|
||||||
if (obj.privkey)
|
if (obj.privkey)
|
||||||
this.privkey = Privkey().fromString(obj.privkey);
|
this.privkey = PrivateKey.fromString(obj.privkey);
|
||||||
if (obj.sig)
|
if (obj.sig)
|
||||||
this.sig = Signature().fromString(obj.sig);
|
this.sig = Signature().fromString(obj.sig);
|
||||||
if (obj.k)
|
if (obj.k)
|
||||||
|
@ -114,9 +115,7 @@ ECDSA.prototype.sig2pubkey = function() {
|
||||||
//var Q = R.multiplyTwo(s, G, eNeg).mul(rInv);
|
//var Q = R.multiplyTwo(s, G, eNeg).mul(rInv);
|
||||||
var Q = R.mul(s).add(G.mul(eNeg)).mul(rInv);
|
var Q = R.mul(s).add(G.mul(eNeg)).mul(rInv);
|
||||||
|
|
||||||
var pubkey = new Pubkey({point: Q});
|
var pubkey = PublicKey.fromPoint(Q, this.sig.compressed);
|
||||||
pubkey.compressed = this.sig.compressed;
|
|
||||||
pubkey.validate();
|
|
||||||
|
|
||||||
return pubkey;
|
return pubkey;
|
||||||
};
|
};
|
||||||
|
@ -125,12 +124,6 @@ ECDSA.prototype.sigError = function() {
|
||||||
if (!Buffer.isBuffer(this.hashbuf) || this.hashbuf.length !== 32)
|
if (!Buffer.isBuffer(this.hashbuf) || this.hashbuf.length !== 32)
|
||||||
return 'hashbuf must be a 32 byte buffer';
|
return 'hashbuf must be a 32 byte buffer';
|
||||||
|
|
||||||
try {
|
|
||||||
this.pubkey.validate();
|
|
||||||
} catch (e) {
|
|
||||||
return 'Invalid pubkey: ' + e;
|
|
||||||
}
|
|
||||||
|
|
||||||
var r = this.sig.r;
|
var r = this.sig.r;
|
||||||
var s = this.sig.s;
|
var s = this.sig.s;
|
||||||
if (!(r.gt(0) && r.lt(Point.getN()))
|
if (!(r.gt(0) && r.lt(Point.getN()))
|
||||||
|
|
|
@ -5,7 +5,7 @@ exports.mainnet = {
|
||||||
identity: 0x0f,
|
identity: 0x0f,
|
||||||
identephem: 0x02,
|
identephem: 0x02,
|
||||||
identpersist: 0x01,
|
identpersist: 0x01,
|
||||||
privkey: 0x80,
|
privatekey: 0x80,
|
||||||
scripthash: 0x05,
|
scripthash: 0x05,
|
||||||
bip32pubkey: 0x0488b21e,
|
bip32pubkey: 0x0488b21e,
|
||||||
bip32privkey: 0x0488ade4,
|
bip32privkey: 0x0488ade4,
|
||||||
|
@ -16,7 +16,7 @@ exports.testnet = {
|
||||||
identity: 0x0f,
|
identity: 0x0f,
|
||||||
identephem: 0x02,
|
identephem: 0x02,
|
||||||
identpersist: 0x11,
|
identpersist: 0x11,
|
||||||
privkey: 0xef,
|
privatekey: 0xef,
|
||||||
scripthash: 0xc4,
|
scripthash: 0xc4,
|
||||||
bip32pubkey: 0x043587cf,
|
bip32pubkey: 0x043587cf,
|
||||||
bip32privkey: 0x04358394,
|
bip32privkey: 0x04358394,
|
||||||
|
|
|
@ -0,0 +1,316 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var BN = require('./crypto/bn');
|
||||||
|
var Point = require('./crypto/point');
|
||||||
|
var Random = require('./crypto/random');
|
||||||
|
var networks = require('./networks');
|
||||||
|
var base58check = require('./encoding/base58check');
|
||||||
|
var Address = require('./address');
|
||||||
|
var PublicKey = require('./publickey');
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Bitcore PrivateKey
|
||||||
|
*
|
||||||
|
* Instantiate a PrivateKey from a BN, Buffer and WIF.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
*
|
||||||
|
* 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 {PrivateKey} A new valid instance of an PrivateKey
|
||||||
|
*/
|
||||||
|
var PrivateKey = function PrivateKey(data, network, compressed) {
|
||||||
|
|
||||||
|
if (!(this instanceof PrivateKey)) {
|
||||||
|
return new PrivateKey(data, network, compressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
var info = {
|
||||||
|
compressed: typeof(compressed) !== 'undefined' ? compressed : true,
|
||||||
|
network: network || 'mainnet'
|
||||||
|
};
|
||||||
|
|
||||||
|
// detect type of data
|
||||||
|
if (!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, compressed);
|
||||||
|
} else if (typeof(data) === 'string'){
|
||||||
|
info = PrivateKey._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;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Internal function to get a random BN
|
||||||
|
*
|
||||||
|
* @returns {Object} An object with keys: bn, network and compressed
|
||||||
|
*/
|
||||||
|
PrivateKey._getRandomBN = function(){
|
||||||
|
var condition;
|
||||||
|
var bn;
|
||||||
|
do {
|
||||||
|
var privbuf = Random.getRandomBuffer(32);
|
||||||
|
bn = BN().fromBuffer(privbuf);
|
||||||
|
condition = bn.lt(Point.getN());
|
||||||
|
} while (!condition);
|
||||||
|
return bn;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
PrivateKey._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.privatekey) {
|
||||||
|
info.network = 'mainnet';
|
||||||
|
} else if (buf[0] === networks.testnet.privatekey) {
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
PrivateKey._transformWIF = function(str, network, compressed) {
|
||||||
|
return PrivateKey._transformBuffer(base58check.decode(str), network, compressed);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Instantiate a PrivateKey from a WIF string
|
||||||
|
*
|
||||||
|
* @param {String} str - The WIF encoded private key string
|
||||||
|
* @returns {PrivateKey} A new valid instance of PrivateKey
|
||||||
|
*/
|
||||||
|
PrivateKey.fromWIF = function(str) {
|
||||||
|
var info = PrivateKey._transformWIF(str);
|
||||||
|
return new PrivateKey(info.bn, info.network, info.compressed);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Instantiate a PrivateKey from a WIF JSON string
|
||||||
|
*
|
||||||
|
* @param {String} str - The WIF encoded private key string
|
||||||
|
* @returns {PrivateKey} A new valid instance of PrivateKey
|
||||||
|
*/
|
||||||
|
PrivateKey.fromJSON = function(json) {
|
||||||
|
var info = PrivateKey._transformWIF(json);
|
||||||
|
return new PrivateKey(info.bn, info.network, info.compressed);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Instantiate a PrivateKey from random bytes
|
||||||
|
*
|
||||||
|
* @param {String} [network] - Either "mainnet" or "testnet"
|
||||||
|
* @param {String} [compressed] - If the private key is compressed
|
||||||
|
* @returns {PrivateKey} A new valid instance of PrivateKey
|
||||||
|
*/
|
||||||
|
PrivateKey.fromRandom = function(network, compressed) {
|
||||||
|
var bn = PrivateKey._getRandomBN();
|
||||||
|
return new PrivateKey(bn, network, compressed);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Instantiate a PrivateKey from a WIF string
|
||||||
|
*
|
||||||
|
* @param {String} str - The WIF encoded private key string
|
||||||
|
* @returns {PrivateKey} A new valid instance of PrivateKey
|
||||||
|
*/
|
||||||
|
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 PrivateKey
|
||||||
|
*
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
|
||||||
|
PrivateKey.getValidationError = function(data, network, compressed) {
|
||||||
|
var error;
|
||||||
|
try {
|
||||||
|
new PrivateKey(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
|
||||||
|
*/
|
||||||
|
PrivateKey.isValid = function(data, network, compressed){
|
||||||
|
return !PrivateKey.getValidationError(data, network, compressed);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Will output the PrivateKey to a WIF string
|
||||||
|
*
|
||||||
|
* @returns {String} A WIP representation of the private key
|
||||||
|
*/
|
||||||
|
PrivateKey.prototype.toWIF = function() {
|
||||||
|
var network = this.network;
|
||||||
|
var compressed = this.compressed;
|
||||||
|
|
||||||
|
var buf;
|
||||||
|
if (compressed) {
|
||||||
|
buf = Buffer.concat([new Buffer([networks[network].privatekey]),
|
||||||
|
this.bn.toBuffer({size: 32}),
|
||||||
|
new Buffer([0x01])]);
|
||||||
|
} else {
|
||||||
|
buf = Buffer.concat([new Buffer([networks[network].privatekey]),
|
||||||
|
this.bn.toBuffer({size: 32})]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return base58check.encode(buf);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Will return the private key as a BN instance
|
||||||
|
*
|
||||||
|
* @returns {BN} A BN instance of the private key
|
||||||
|
*/
|
||||||
|
PrivateKey.prototype.toBigNumber = function(){
|
||||||
|
return this.bn;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Will return the private key as a BN buffer
|
||||||
|
*
|
||||||
|
* @returns {Buffer} A buffer of the private key
|
||||||
|
*/
|
||||||
|
PrivateKey.prototype.toBuffer = function(){
|
||||||
|
return this.bn.toBuffer();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Will return the corresponding public key
|
||||||
|
*
|
||||||
|
* @returns {PublicKey} A public key generated from the private key
|
||||||
|
*/
|
||||||
|
PrivateKey.prototype.toPublicKey = function(){
|
||||||
|
return PublicKey.fromPrivateKey(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Will return an address for the private key
|
||||||
|
*
|
||||||
|
* @returns {Address} An address generated from the private key
|
||||||
|
*/
|
||||||
|
PrivateKey.prototype.toAddress = function() {
|
||||||
|
var pubkey = this.toPublicKey();
|
||||||
|
return Address.fromPublicKey(pubkey, this.network);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Will output the PrivateKey to a WIF string
|
||||||
|
*
|
||||||
|
* @returns {String} A WIF representation of the private key
|
||||||
|
*/
|
||||||
|
PrivateKey.prototype.toJSON = function() {
|
||||||
|
return this.toString();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Will output the PrivateKey to a WIF string
|
||||||
|
*
|
||||||
|
* @returns {String} A WIF representation of the private key
|
||||||
|
*/
|
||||||
|
PrivateKey.prototype.toString = function() {
|
||||||
|
return this.toWIF();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Will return a string formatted for the console
|
||||||
|
*
|
||||||
|
* @returns {String} Private key
|
||||||
|
*/
|
||||||
|
PrivateKey.prototype.inspect = function() {
|
||||||
|
return '<PrivateKey: ' + this.toString() + ', compressed: '+this.compressed+', network: '+this.network+'>';
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = PrivateKey;
|
111
lib/privkey.js
111
lib/privkey.js
|
@ -1,111 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var BN = require('./crypto/bn');
|
|
||||||
var Point = require('./crypto/point');
|
|
||||||
var Random = require('./crypto/random');
|
|
||||||
var networks = require('./networks');
|
|
||||||
var base58check = require('./encoding/base58check');
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
Privkey.prototype.fromJSON = function(json) {
|
|
||||||
this.fromString(json);
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
Privkey.prototype.toJSON = function() {
|
|
||||||
return this.toString();
|
|
||||||
};
|
|
||||||
|
|
||||||
Privkey.prototype.fromRandom = function() {
|
|
||||||
do {
|
|
||||||
var privbuf = Random.getRandomBuffer(32);
|
|
||||||
var bn = BN().fromBuffer(privbuf);
|
|
||||||
var condition = bn.lt(Point.getN());
|
|
||||||
} while (!condition);
|
|
||||||
this.set({
|
|
||||||
bn: bn,
|
|
||||||
networkstr: 'mainnet',
|
|
||||||
compressed: true
|
|
||||||
});
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
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)');
|
|
||||||
};
|
|
||||||
|
|
||||||
Privkey.prototype.toWIF = function() {
|
|
||||||
var networkstr = this.networkstr;
|
|
||||||
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})]);
|
|
||||||
|
|
||||||
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));
|
|
||||||
};
|
|
||||||
|
|
||||||
Privkey.prototype.toString = function() {
|
|
||||||
return this.toWIF();
|
|
||||||
};
|
|
||||||
|
|
||||||
Privkey.prototype.toPubkey = function() {
|
|
||||||
return new Pubkey().fromPrivkey(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
Privkey.prototype.fromString = function(str) {
|
|
||||||
this.fromWIF(str);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = Privkey;
|
|
127
lib/pubkey.js
127
lib/pubkey.js
|
@ -1,127 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var Point = require('./crypto/point');
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
Pubkey.prototype.fromJSON = function(json) {
|
|
||||||
this.fromBuffer(new Buffer(json, 'hex'));
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
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);
|
|
||||||
};
|
|
||||||
|
|
||||||
Pubkey.prototype.toBuffer = function() {
|
|
||||||
var compressed = typeof this.compressed === 'undefined' ? true : this.compressed;
|
|
||||||
return this.toDER(compressed);
|
|
||||||
};
|
|
||||||
|
|
||||||
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)');
|
|
||||||
|
|
||||||
var x = this.point.getX();
|
|
||||||
var y = this.point.getY();
|
|
||||||
|
|
||||||
var xbuf = x.toBuffer({size: 32});
|
|
||||||
var ybuf = y.toBuffer({size: 32});
|
|
||||||
|
|
||||||
if (!compressed) {
|
|
||||||
var 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]);
|
|
||||||
return Buffer.concat([prefix, xbuf]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = Pubkey;
|
|
|
@ -0,0 +1,341 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var Point = require('./crypto/point');
|
||||||
|
var BN = require('./crypto/bn');
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Bitcore PublicKey
|
||||||
|
*
|
||||||
|
* Instantiate a PublicKey from a 'PrivateKey', 'Point', 'string', 'Buffer'.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
*
|
||||||
|
* 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 {PublicKey} A new valid instance of an PublicKey
|
||||||
|
*/
|
||||||
|
var PublicKey = function PublicKey(data, compressed) {
|
||||||
|
|
||||||
|
if (!(this instanceof PublicKey)) {
|
||||||
|
return new PublicKey(data, 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 = PublicKey._transformDER(new Buffer(data, 'hex' ));
|
||||||
|
} else if (data instanceof Buffer || data instanceof Uint8Array){
|
||||||
|
info = PublicKey._transformDER(data);
|
||||||
|
} else if (data.constructor && (data.constructor.name &&
|
||||||
|
data.constructor.name === 'PrivateKey')) {
|
||||||
|
info = PublicKey._transformPrivateKey(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;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Internal function to transform a private key into a public key point
|
||||||
|
*
|
||||||
|
* @param {PrivateKey} privkey - An instance of PrivateKey
|
||||||
|
* @returns {Object} An object with keys: point and compressed
|
||||||
|
*/
|
||||||
|
PublicKey._transformPrivateKey = function(privkey) {
|
||||||
|
var info = {};
|
||||||
|
if (!privkey.constructor ||
|
||||||
|
(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;
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
PublicKey._transformDER = function(buf){
|
||||||
|
var info = {};
|
||||||
|
if (!(buf instanceof Buffer) && !(buf instanceof Uint8Array)){
|
||||||
|
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 = PublicKey._transformX(true, x);
|
||||||
|
info.compressed = true;
|
||||||
|
} else if (buf[0] == 0x02) {
|
||||||
|
xbuf = buf.slice(1);
|
||||||
|
x = BN(xbuf);
|
||||||
|
info = PublicKey._transformX(false, x);
|
||||||
|
info.compressed = true;
|
||||||
|
} else {
|
||||||
|
throw new TypeError('Invalid DER format public key');
|
||||||
|
}
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
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)');
|
||||||
|
}
|
||||||
|
info.point = Point.fromX(odd, x);
|
||||||
|
return info;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Instantiate a PublicKey from JSON
|
||||||
|
*
|
||||||
|
* @param {String} json - A JSON string of DER encoded public key
|
||||||
|
* @returns {PublicKey} A new valid instance of PublicKey
|
||||||
|
*/
|
||||||
|
PublicKey.fromJSON = function(json) {
|
||||||
|
var buf = new Buffer(json, 'hex');
|
||||||
|
var info = PublicKey._transformDER(buf);
|
||||||
|
return new PublicKey(info.point, info.compressed);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Instantiate a PublicKey from a PrivateKey
|
||||||
|
*
|
||||||
|
* @param {PrivateKey} privkey - An instance of PrivateKey
|
||||||
|
* @returns {PublicKey} A new valid instance of PublicKey
|
||||||
|
*/
|
||||||
|
PublicKey.fromPrivateKey = function(privkey) {
|
||||||
|
var info = PublicKey._transformPrivateKey(privkey);
|
||||||
|
return new PublicKey(info.point, info.compressed);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Instantiate a PublicKey from a Buffer
|
||||||
|
*
|
||||||
|
* @param {Buffer} buf - A DER hex buffer
|
||||||
|
* @returns {PublicKey} A new valid instance of PublicKey
|
||||||
|
*/
|
||||||
|
PublicKey.fromBuffer = function(buf) {
|
||||||
|
var info = PublicKey._transformDER(buf);
|
||||||
|
return new PublicKey(info.point, info.compressed);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Instantiate a PublicKey from a Point
|
||||||
|
*
|
||||||
|
* @param {Point} point - A Point instance
|
||||||
|
* @returns {PublicKey} A new valid instance of PublicKey
|
||||||
|
*/
|
||||||
|
PublicKey.fromPoint = function(point, compressed){
|
||||||
|
if (!(point instanceof Point)) {
|
||||||
|
throw new TypeError('First argument must be an instance of Point.');
|
||||||
|
}
|
||||||
|
return new PublicKey(point, compressed);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Instantiate a PublicKey from a DER Buffer
|
||||||
|
*
|
||||||
|
* @param {Buffer} buf - A DER Buffer
|
||||||
|
* @returns {PublicKey} A new valid instance of PublicKey
|
||||||
|
*/
|
||||||
|
PublicKey.fromDER = function(buf) {
|
||||||
|
var info = PublicKey._transformDER(buf);
|
||||||
|
return new PublicKey(info.point, info.compressed);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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 {PublicKey} A new valid instance of PublicKey
|
||||||
|
*/
|
||||||
|
PublicKey.fromString = function(str, encoding) {
|
||||||
|
var buf = new Buffer(str, encoding || 'hex');
|
||||||
|
var info = PublicKey._transformDER(buf);
|
||||||
|
return new PublicKey(info.point, info.compressed);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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 {PublicKey} A new valid instance of PublicKey
|
||||||
|
*/
|
||||||
|
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 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
|
||||||
|
*/
|
||||||
|
PublicKey.getValidationError = function(data, compressed) {
|
||||||
|
var error;
|
||||||
|
try {
|
||||||
|
new PublicKey(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 public key would be valid
|
||||||
|
*/
|
||||||
|
PublicKey.isValid = function(data, compressed) {
|
||||||
|
return !PublicKey.getValidationError(data, compressed);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Will output the PublicKey to JSON
|
||||||
|
*
|
||||||
|
* @returns {String} A hex encoded string
|
||||||
|
*/
|
||||||
|
PublicKey.prototype.toJSON = function() {
|
||||||
|
return this.toBuffer().toString('hex');
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Will output the PublicKey to a Buffer
|
||||||
|
*
|
||||||
|
* @returns {Buffer} A DER hex encoded buffer
|
||||||
|
*/
|
||||||
|
PublicKey.prototype.toBuffer = function() {
|
||||||
|
var compressed = typeof this.compressed === 'undefined' ? true : this.compressed;
|
||||||
|
return this.toDER(compressed);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Will output the PublicKey to a DER Buffer
|
||||||
|
*
|
||||||
|
* @returns {Buffer} A DER hex encoded buffer
|
||||||
|
*/
|
||||||
|
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)');
|
||||||
|
}
|
||||||
|
|
||||||
|
var x = this.point.getX();
|
||||||
|
var y = this.point.getY();
|
||||||
|
|
||||||
|
var xbuf = x.toBuffer({size: 32});
|
||||||
|
var ybuf = y.toBuffer({size: 32});
|
||||||
|
|
||||||
|
var prefix;
|
||||||
|
if (!compressed) {
|
||||||
|
prefix = new Buffer([0x04]);
|
||||||
|
return Buffer.concat([prefix, xbuf, ybuf]);
|
||||||
|
} else {
|
||||||
|
var odd = ybuf[ybuf.length - 1] % 2;
|
||||||
|
if (odd) {
|
||||||
|
prefix = new Buffer([0x03]);
|
||||||
|
} else {
|
||||||
|
prefix = new Buffer([0x02]);
|
||||||
|
}
|
||||||
|
return Buffer.concat([prefix, xbuf]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Will output the PublicKey to a DER encoded hex string
|
||||||
|
*
|
||||||
|
* @returns {String} A DER hex encoded string
|
||||||
|
*/
|
||||||
|
PublicKey.prototype.toString = function() {
|
||||||
|
var compressed = typeof this.compressed === 'undefined' ? true : this.compressed;
|
||||||
|
return this.toDER(compressed).toString('hex');
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Will return a string formatted for the console
|
||||||
|
*
|
||||||
|
* @returns {String} Public key
|
||||||
|
*/
|
||||||
|
PublicKey.prototype.inspect = function() {
|
||||||
|
return '<PublicKey: ' + this.toString() + ', compressed: '+this.compressed+'>';
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = PublicKey;
|
|
@ -190,7 +190,7 @@ Script.prototype.isOpReturn = function() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Script.prototype.isPubkeyhashOut = function() {
|
Script.prototype.isPublicKeyHashOut = function() {
|
||||||
if (this.chunks[0] === Opcode('OP_DUP').toNumber()
|
if (this.chunks[0] === Opcode('OP_DUP').toNumber()
|
||||||
&& this.chunks[1] === Opcode('OP_HASH160').toNumber()
|
&& this.chunks[1] === Opcode('OP_HASH160').toNumber()
|
||||||
&& this.chunks[2].buf
|
&& 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
|
if (this.chunks.length === 2
|
||||||
&& this.chunks[0].buf
|
&& this.chunks[0].buf
|
||||||
&& this.chunks[1].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
|
if (this.chunks.length === 3
|
||||||
&& this.chunks[0] === Opcode('OP_HASH160').toNumber()
|
&& this.chunks[0] === Opcode('OP_HASH160').toNumber()
|
||||||
&& this.chunks[1].buf
|
&& this.chunks[1].buf
|
||||||
|
@ -225,7 +225,7 @@ Script.prototype.isScripthashOut = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
//note that these are frequently indistinguishable from pubkeyhashin
|
//note that these are frequently indistinguishable from pubkeyhashin
|
||||||
Script.prototype.isScripthashIn = function() {
|
Script.prototype.isScriptHashIn = function() {
|
||||||
var allpush = this.chunks.every(function(chunk) {
|
var allpush = this.chunks.every(function(chunk) {
|
||||||
return Buffer.isBuffer(chunk.buf);
|
return Buffer.isBuffer(chunk.buf);
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
var should = require('chai').should();
|
var should = require('chai').should();
|
||||||
|
|
||||||
var bitcore = require('..');
|
var bitcore = require('..');
|
||||||
var Pubkey = bitcore.Pubkey;
|
var PublicKey = bitcore.PublicKey;
|
||||||
var Address = bitcore.Address;
|
var Address = bitcore.Address;
|
||||||
var Script = bitcore.Script;
|
var Script = bitcore.Script;
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ describe('Address', function() {
|
||||||
|
|
||||||
it('should error because of incorrect format for pubkey hash', function() {
|
it('should error because of incorrect format for pubkey hash', function() {
|
||||||
(function() {
|
(function() {
|
||||||
var a = new Address.fromPubkeyHash('notahash');
|
var a = new Address.fromPublicKeyHash('notahash');
|
||||||
}).should.throw('Address supplied is not a buffer.');
|
}).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() {
|
it('should error because of incorrect type for pubkey transform', function() {
|
||||||
(function() {
|
(function() {
|
||||||
var info = Address._transformPubkey(new Buffer(20));
|
var info = Address._transformPublicKey(new Buffer(20));
|
||||||
}).should.throw('Address must be an instance of Pubkey.');
|
}).should.throw('Address must be an instance of PublicKey.');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should error because of incorrect type for script transform', function() {
|
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() {
|
it('should make an address from a pubkey hash buffer', function() {
|
||||||
var hash = pubkeyhash; //use the same hash
|
var hash = pubkeyhash; //use the same hash
|
||||||
var a = Address.fromPubkeyHash(hash).toString().should.equal(str);
|
var a = Address.fromPublicKeyHash(hash).toString().should.equal(str);
|
||||||
var b = Address.fromPubkeyHash(hash, 'testnet');
|
var b = Address.fromPublicKeyHash(hash, 'testnet');
|
||||||
b.network.should.equal('testnet');
|
b.network.should.equal('testnet');
|
||||||
b.type.should.equal('pubkeyhash');
|
b.type.should.equal('pubkeyhash');
|
||||||
var c = new Address(hash).toString().should.equal(str);
|
var c = new Address(hash).toString().should.equal(str);
|
||||||
|
@ -262,26 +262,19 @@ describe('Address', function() {
|
||||||
|
|
||||||
it('should throw an error for invalid length hashBuffer', function() {
|
it('should throw an error for invalid length hashBuffer', function() {
|
||||||
(function() {
|
(function() {
|
||||||
var a = Address.fromPubkeyHash(buf);
|
var a = Address.fromPublicKeyHash(buf);
|
||||||
}).should.throw('Address hashbuffers must be exactly 20 bytes.');
|
}).should.throw('Address hashbuffers must be exactly 20 bytes.');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should make this address from a compressed pubkey object', function() {
|
it('should make this address from a compressed pubkey', function() {
|
||||||
var pubkey = new Pubkey();
|
var pubkey = PublicKey.fromDER(new Buffer('0285e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004', 'hex'));
|
||||||
pubkey.fromDER(new Buffer('0285e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004',
|
var address = Address.fromPublicKey(pubkey);
|
||||||
'hex'));
|
address.toString().should.equal('19gH5uhqY6DKrtkU66PsZPUZdzTd11Y7ke');
|
||||||
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 an uncompressed pubkey', function() {
|
it('should make this address from an uncompressed pubkey', function() {
|
||||||
var pubkey = new Pubkey();
|
var pubkey = PublicKey.fromDER(new Buffer('0485e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004833fef26c8be4c4823754869ff4e46755b85d851077771c220e2610496a29d98', 'hex'));
|
||||||
pubkey.fromDER(new Buffer('0285e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004',
|
var a = Address.fromPublicKey(pubkey, 'mainnet');
|
||||||
'hex'));
|
|
||||||
pubkey.compressed = false;
|
|
||||||
var a = Address.fromPubkey(pubkey, 'mainnet', 'pubkeyhash');
|
|
||||||
a.toString().should.equal('16JXnhxjJUhxfyx4y6H4sFcxrgt8kQ8ewX');
|
a.toString().should.equal('16JXnhxjJUhxfyx4y6H4sFcxrgt8kQ8ewX');
|
||||||
var b = new Address(pubkey, 'mainnet', 'pubkeyhash');
|
var b = new Address(pubkey, 'mainnet', 'pubkeyhash');
|
||||||
b.toString().should.equal('16JXnhxjJUhxfyx4y6H4sFcxrgt8kQ8ewX');
|
b.toString().should.equal('16JXnhxjJUhxfyx4y6H4sFcxrgt8kQ8ewX');
|
||||||
|
@ -310,7 +303,7 @@ describe('Address', function() {
|
||||||
var address = new Address(str);
|
var address = new Address(str);
|
||||||
var buffer = address.toBuffer();
|
var buffer = address.toBuffer();
|
||||||
var slice = buffer.slice(1);
|
var slice = buffer.slice(1);
|
||||||
var sliceString = slice.toString('hex')
|
var sliceString = slice.toString('hex');
|
||||||
sliceString.should.equal(pubkeyhash.toString('hex'));
|
sliceString.should.equal(pubkeyhash.toString('hex'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,10 @@ var should = require('chai').should();
|
||||||
var bitcore = require('../..');
|
var bitcore = require('../..');
|
||||||
var ECDSA = bitcore.crypto.ECDSA;
|
var ECDSA = bitcore.crypto.ECDSA;
|
||||||
var Hash = bitcore.crypto.Hash;
|
var Hash = bitcore.crypto.Hash;
|
||||||
var Privkey = bitcore.Privkey;
|
var PrivateKey = bitcore.PrivateKey;
|
||||||
var Pubkey = bitcore.Pubkey;
|
var PublicKey = bitcore.PublicKey;
|
||||||
var Signature = bitcore.Signature;
|
var Signature = bitcore.Signature;
|
||||||
var BN = bitcore.crypto.BN;
|
var BN = bitcore.crypto.BN;
|
||||||
var point = bitcore.crypto.Point;
|
|
||||||
|
|
||||||
describe('ECDSA', function() {
|
describe('ECDSA', function() {
|
||||||
|
|
||||||
|
@ -19,11 +18,8 @@ describe('ECDSA', function() {
|
||||||
|
|
||||||
var ecdsa = new ECDSA();
|
var ecdsa = new ECDSA();
|
||||||
ecdsa.hashbuf = Hash.sha256(new Buffer('test data'));
|
ecdsa.hashbuf = Hash.sha256(new Buffer('test data'));
|
||||||
ecdsa.privkey = new Privkey({bn: BN().fromBuffer(new Buffer('fee0a1f7afebf9d2a5a80c0c98a31c709681cce195cbcd06342b517970c0be1e', 'hex'))});
|
ecdsa.privkey = new PrivateKey(BN().fromBuffer(new Buffer('fee0a1f7afebf9d2a5a80c0c98a31c709681cce195cbcd06342b517970c0be1e', 'hex')));
|
||||||
ecdsa.pubkey = new Pubkey({
|
ecdsa.privkey2pubkey();
|
||||||
point: point(BN().fromBuffer(new Buffer('ac242d242d23be966085a2b2b893d989f824e06c9ad0395a8a52f055ba39abb2', 'hex')),
|
|
||||||
BN().fromBuffer(new Buffer('4836ab292c105a711ed10fcfd30999c31ff7c02456147747e03e739ad527c380', 'hex')))
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#set', function() {
|
describe('#set', function() {
|
||||||
|
|
||||||
|
@ -47,8 +43,7 @@ describe('ECDSA', function() {
|
||||||
var r = BN('71706645040721865894779025947914615666559616020894583599959600180037551395766', 10);
|
var r = BN('71706645040721865894779025947914615666559616020894583599959600180037551395766', 10);
|
||||||
var s = BN('109412465507152403114191008482955798903072313614214706891149785278625167723646', 10);
|
var s = BN('109412465507152403114191008482955798903072313614214706891149785278625167723646', 10);
|
||||||
var ecdsa = new ECDSA();
|
var ecdsa = new ECDSA();
|
||||||
ecdsa.privkey = Privkey();
|
ecdsa.privkey = PrivateKey(BN().fromBuffer(Hash.sha256(new Buffer('test'))));
|
||||||
ecdsa.privkey.bn = BN().fromBuffer(Hash.sha256(new Buffer('test')));
|
|
||||||
ecdsa.privkey2pubkey();
|
ecdsa.privkey2pubkey();
|
||||||
ecdsa.hashbuf = hashbuf;
|
ecdsa.hashbuf = hashbuf;
|
||||||
ecdsa.sig = new Signature({r: r, s: s});
|
ecdsa.sig = new Signature({r: r, s: s});
|
||||||
|
@ -109,17 +104,10 @@ describe('ECDSA', function() {
|
||||||
ecdsa.sigError().should.equal('hashbuf must be a 32 byte buffer');
|
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() {
|
it('should return an error if r, s are invalid', function() {
|
||||||
var ecdsa = new ECDSA();
|
var ecdsa = new ECDSA();
|
||||||
ecdsa.hashbuf = Hash.sha256(new Buffer('test'));
|
ecdsa.hashbuf = Hash.sha256(new Buffer('test'));
|
||||||
var pk = new Pubkey();
|
var pk = PublicKey.fromDER(new Buffer('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341', 'hex'));
|
||||||
pk.fromDER(new Buffer('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341', 'hex'));
|
|
||||||
ecdsa.pubkey = pk;
|
ecdsa.pubkey = pk;
|
||||||
ecdsa.sig = new Signature();
|
ecdsa.sig = new Signature();
|
||||||
ecdsa.sig.r = BN(0);
|
ecdsa.sig.r = BN(0);
|
||||||
|
|
|
@ -0,0 +1,270 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var should = require('chai').should();
|
||||||
|
var bitcore = require('..');
|
||||||
|
var BN = bitcore.crypto.BN;
|
||||||
|
var Point = bitcore.crypto.Point;
|
||||||
|
var PrivateKey = bitcore.PrivateKey;
|
||||||
|
var base58check = bitcore.encoding.Base58Check;
|
||||||
|
|
||||||
|
describe('PrivateKey', function() {
|
||||||
|
var hex = '96c132224121b509b7d0a16245e957d9192609c5637c6228311287b1be21627a';
|
||||||
|
var buf = new Buffer(hex, 'hex');
|
||||||
|
var enctestnet = 'cSdkPxkAjA4HDr5VHgsebAPDEh9Gyub4HK8UJr2DFGGqKKy4K5sG';
|
||||||
|
var enctu = '92jJzK4tbURm1C7udQXxeCBvXHoHJstDXRxAMouPG1k1XUaXdsu';
|
||||||
|
var encmainnet = 'L2Gkw3kKJ6N24QcDuH4XDqt9cTqsKTVNDGz1CRZhk9cq4auDUbJy';
|
||||||
|
var encmu = '5JxgQaFM1FMd38cd14e3mbdxsdSa9iM2BV6DHBYsvGzxkTNQ7Un';
|
||||||
|
|
||||||
|
it('should create a new random private key', function() {
|
||||||
|
var a = new PrivateKey();
|
||||||
|
should.exist(a);
|
||||||
|
should.exist(a.bn);
|
||||||
|
var b = PrivateKey();
|
||||||
|
should.exist(b);
|
||||||
|
should.exist(b.bn);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create a private key from WIF string', function() {
|
||||||
|
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 PrivateKey(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 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 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 PrivateKey('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 PrivateKey(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 PrivateKey(buf2);
|
||||||
|
}).should.throw('Invalid network');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not be able to instantiate because compressed is non-boolean', function() {
|
||||||
|
(function() {
|
||||||
|
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 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 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 PrivateKey(bn);
|
||||||
|
privkey.bn.toString().should.equal(bn.toString());
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create a mainnet private key', function() {
|
||||||
|
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 PrivateKey(BN.fromBuffer(buf), 'testnet', false);
|
||||||
|
privkey.toString().should.equal(enctu);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create an uncompressed mainnet private key', function() {
|
||||||
|
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 = PrivateKey.fromJSON(encmu);
|
||||||
|
privkey.toWIF().should.equal(encmu);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#toString', function() {
|
||||||
|
|
||||||
|
it('should output this address correctly', function() {
|
||||||
|
var privkey = PrivateKey.fromJSON(encmu);
|
||||||
|
privkey.toJSON().should.equal(encmu);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#toAddress', function() {
|
||||||
|
it('should output this known mainnet address correctly', function() {
|
||||||
|
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 = PrivateKey.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 = PrivateKey.fromWIF('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m');
|
||||||
|
privkey.inspect().should.equal('<PrivateKey: L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m, compressed: true, network: mainnet>');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should output known testnet address for console', function() {
|
||||||
|
var privkey = PrivateKey.fromWIF('cR4qogdN9UxLZJXCNFNwDRRZNeLRWuds9TTSuLNweFVjiaE4gPaq');
|
||||||
|
privkey.inspect().should.equal('<PrivateKey: cR4qogdN9UxLZJXCNFNwDRRZNeLRWuds9TTSuLNweFVjiaE4gPaq, compressed: true, network: testnet>');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#getValidationError', function(){
|
||||||
|
it('should get an error because private key greater than N', function() {
|
||||||
|
var n = Point.getN();
|
||||||
|
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 = PrivateKey.isValid(n);
|
||||||
|
a.should.equal(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should validate as true', function() {
|
||||||
|
var a = PrivateKey.isValid('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m');
|
||||||
|
a.should.equal(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#toBuffer', function() {
|
||||||
|
it('should output known buffer', function() {
|
||||||
|
var privkey = new PrivateKey(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 PrivateKey(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 = PrivateKey.fromRandom();
|
||||||
|
privkey.bn.gt(BN(0)).should.equal(true);
|
||||||
|
privkey.bn.lt(Point.getN()).should.equal(true);
|
||||||
|
privkey.compressed.should.equal(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#fromWIF', function() {
|
||||||
|
|
||||||
|
it('should parse this compressed testnet address correctly', function() {
|
||||||
|
var privkey = PrivateKey.fromWIF(encmainnet);
|
||||||
|
privkey.toWIF().should.equal(encmainnet);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#toWIF', function() {
|
||||||
|
|
||||||
|
it('should parse this compressed testnet address correctly', function() {
|
||||||
|
var privkey = PrivateKey.fromWIF(enctestnet);
|
||||||
|
privkey.toWIF().should.equal(enctestnet);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#fromString', function() {
|
||||||
|
|
||||||
|
it('should parse this uncompressed testnet address correctly', function() {
|
||||||
|
var privkey = PrivateKey.fromString(enctu);
|
||||||
|
privkey.toWIF().should.equal(enctu);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#toString', function() {
|
||||||
|
|
||||||
|
it('should parse this uncompressed mainnet address correctly', function() {
|
||||||
|
var privkey = PrivateKey.fromString(encmu);
|
||||||
|
privkey.toString().should.equal(encmu);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("#toPublicKey", function() {
|
||||||
|
|
||||||
|
it('should convert this known PrivateKey to known PublicKey', function() {
|
||||||
|
var privhex = '906977a061af29276e40bf377042ffbde414e496ae2260bbf1fa9d085637bfff';
|
||||||
|
var pubhex = '02a1633cafcc01ebfb6d78e39f687a1f0995c62fc95f51ead10a02ee0be551b5dc';
|
||||||
|
var privkey = new PrivateKey(BN(new Buffer(privhex, 'hex')));
|
||||||
|
var pubkey = privkey.toPublicKey();
|
||||||
|
pubkey.toString().should.equal(pubhex);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should convert this known PrivateKey to known PublicKey and preserve compressed=true', function() {
|
||||||
|
var privhex = '906977a061af29276e40bf377042ffbde414e496ae2260bbf1fa9d085637bfff';
|
||||||
|
var privkey = new PrivateKey(BN(new Buffer(privhex, 'hex')));
|
||||||
|
privkey.compressed = true;
|
||||||
|
var pubkey = privkey.toPublicKey();
|
||||||
|
pubkey.compressed.should.equal(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should convert this known PrivateKey to known PublicKey and preserve compressed=true', function() {
|
||||||
|
var privhex = '906977a061af29276e40bf377042ffbde414e496ae2260bbf1fa9d085637bfff';
|
||||||
|
var privkey = new PrivateKey(BN(new Buffer(privhex, 'hex')));
|
||||||
|
privkey.compressed = false;
|
||||||
|
var pubkey = privkey.toPublicKey();
|
||||||
|
pubkey.compressed.should.equal(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
171
test/privkey.js
171
test/privkey.js
|
@ -1,171 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var should = require('chai').should();
|
|
||||||
var bitcore = require('..');
|
|
||||||
var BN = bitcore.crypto.BN;
|
|
||||||
var Point = bitcore.crypto.Point;
|
|
||||||
var Privkey = bitcore.Privkey;
|
|
||||||
var Pubkey = bitcore.Pubkey;
|
|
||||||
|
|
||||||
describe('Privkey', function() {
|
|
||||||
var hex = '96c132224121b509b7d0a16245e957d9192609c5637c6228311287b1be21627a';
|
|
||||||
var buf = new Buffer(hex, 'hex');
|
|
||||||
var enctestnet = 'cSdkPxkAjA4HDr5VHgsebAPDEh9Gyub4HK8UJr2DFGGqKKy4K5sG';
|
|
||||||
var enctu = '92jJzK4tbURm1C7udQXxeCBvXHoHJstDXRxAMouPG1k1XUaXdsu';
|
|
||||||
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 0 private key with this convenience method', function() {
|
|
||||||
var bn = BN(0);
|
|
||||||
var privkey = new Privkey(bn);
|
|
||||||
privkey.bn.toString().should.equal(bn.toString());
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create a mainnet private key', function() {
|
|
||||||
var privkey = new Privkey({
|
|
||||||
bn: BN.fromBuffer(buf),
|
|
||||||
networkstr: 'mainnet',
|
|
||||||
compressed: 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
|
|
||||||
});
|
|
||||||
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
|
|
||||||
});
|
|
||||||
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);
|
|
||||||
privkey.toWIF().should.equal(encmu);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#toString', function() {
|
|
||||||
|
|
||||||
it('should output this address correctly', function() {
|
|
||||||
var privkey = new Privkey();
|
|
||||||
privkey.fromJSON(encmu);
|
|
||||||
privkey.toJSON().should.equal(encmu);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#fromRandom', function() {
|
|
||||||
|
|
||||||
it('should set bn gt 0 and lt n, and should be compressed', function() {
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#fromWIF', function() {
|
|
||||||
|
|
||||||
it('should parse this compressed testnet address correctly', function() {
|
|
||||||
var privkey = new Privkey();
|
|
||||||
privkey.fromWIF(encmainnet);
|
|
||||||
privkey.toWIF().should.equal(encmainnet);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#toWIF', function() {
|
|
||||||
|
|
||||||
it('should parse this compressed testnet address correctly', function() {
|
|
||||||
var privkey = new Privkey();
|
|
||||||
privkey.fromWIF(enctestnet);
|
|
||||||
privkey.toWIF().should.equal(enctestnet);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#fromString', function() {
|
|
||||||
|
|
||||||
it('should parse this uncompressed testnet address correctly', function() {
|
|
||||||
var privkey = new Privkey();
|
|
||||||
privkey.fromString(enctu);
|
|
||||||
privkey.toWIF().should.equal(enctu);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#toString', function() {
|
|
||||||
|
|
||||||
it('should parse this uncompressed mainnet address correctly', function() {
|
|
||||||
var privkey = new Privkey();
|
|
||||||
privkey.fromString(encmu);
|
|
||||||
privkey.toString().should.equal(encmu);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("#toPubkey", 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 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'))
|
|
||||||
});
|
|
||||||
privkey.compressed = true;
|
|
||||||
var pubkey = privkey.toPubkey();
|
|
||||||
pubkey.compressed.should.equal(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
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'))
|
|
||||||
});
|
|
||||||
privkey.compressed = false;
|
|
||||||
var pubkey = privkey.toPubkey();
|
|
||||||
pubkey.compressed.should.equal(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
208
test/pubkey.js
208
test/pubkey.js
|
@ -1,208 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
describe('Pubkey', function() {
|
|
||||||
|
|
||||||
it('should create a blank public key', function() {
|
|
||||||
var pk = new Pubkey();
|
|
||||||
should.exist(pk);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create a public key with a point', function() {
|
|
||||||
var p = Point();
|
|
||||||
var pk = new Pubkey({point: p});
|
|
||||||
should.exist(pk.point);
|
|
||||||
});
|
|
||||||
|
|
||||||
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('#fromJSON', function() {
|
|
||||||
|
|
||||||
it('should input this public key', function() {
|
|
||||||
var pk = new Pubkey();
|
|
||||||
pk.fromJSON('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341');
|
|
||||||
pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a');
|
|
||||||
pk.point.getY().toString(16).should.equal('7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341');
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#toJSON', function() {
|
|
||||||
|
|
||||||
it('should output this pubkey', function() {
|
|
||||||
var pk = new Pubkey();
|
|
||||||
var hex = '041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341';
|
|
||||||
pk.fromJSON(hex).toJSON().should.equal(hex);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#fromPrivkey', function() {
|
|
||||||
|
|
||||||
it('should make a public key from a privkey', function() {
|
|
||||||
should.exist(Pubkey().fromPrivkey(Privkey().fromRandom()));
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#fromBuffer', function() {
|
|
||||||
|
|
||||||
it('should parse this uncompressed public key', function() {
|
|
||||||
var pk = new Pubkey();
|
|
||||||
pk.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'));
|
|
||||||
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'));
|
|
||||||
}).should.throw();
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#fromDER', function() {
|
|
||||||
|
|
||||||
it('should parse this uncompressed public key', function() {
|
|
||||||
var pk = new Pubkey();
|
|
||||||
pk.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'));
|
|
||||||
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'));
|
|
||||||
}).should.throw();
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#fromString', function() {
|
|
||||||
|
|
||||||
it('should parse this known valid public key', function() {
|
|
||||||
var pk = new Pubkey();
|
|
||||||
pk.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 = new Pubkey();
|
|
||||||
pk.fromX(true, x);
|
|
||||||
pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a');
|
|
||||||
pk.point.getY().toString(16).should.equal('7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341');
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
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);
|
|
||||||
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 = new Pubkey();
|
|
||||||
pk.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);
|
|
||||||
pk.toDER(false).toString('hex').should.equal('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341');
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#toString', function() {
|
|
||||||
|
|
||||||
it('should print this known public key', function() {
|
|
||||||
var hex = '031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a';
|
|
||||||
var pk = new Pubkey();
|
|
||||||
pk.fromString(hex);
|
|
||||||
pk.toString().should.equal(hex);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#validate', function() {
|
|
||||||
|
|
||||||
it('should not throw an error if pubkey is valid', function() {
|
|
||||||
var hex = '031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a';
|
|
||||||
var pk = new Pubkey();
|
|
||||||
pk.fromString(hex);
|
|
||||||
should.exist(pk.validate());
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not throw an error if pubkey is invalid', function() {
|
|
||||||
var hex = '041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a0000000000000000000000000000000000000000000000000000000000000000';
|
|
||||||
var pk = new Pubkey();
|
|
||||||
pk.fromString(hex);
|
|
||||||
(function() {
|
|
||||||
pk.validate();
|
|
||||||
}).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());
|
|
||||||
(function() {
|
|
||||||
pk.validate();
|
|
||||||
}).should.throw('Point cannot be equal to Infinity');
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
|
@ -0,0 +1,300 @@
|
||||||
|
'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() {
|
||||||
|
|
||||||
|
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(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 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 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 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 error message', function() {
|
||||||
|
var error = PublicKey.getValidationError(Point());
|
||||||
|
should.exist(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should recieve a boolean as false', function() {
|
||||||
|
var valid = PublicKey.isValid(Point());
|
||||||
|
valid.should.equal(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should recieve a boolean as true', function() {
|
||||||
|
var valid = PublicKey.isValid('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341');
|
||||||
|
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('#fromJSON', function() {
|
||||||
|
|
||||||
|
it('should input this public key', function() {
|
||||||
|
var pk = PublicKey.fromJSON('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341');
|
||||||
|
pk.point.getX().toString(16).should.equal('1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a');
|
||||||
|
pk.point.getY().toString(16).should.equal('7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#toJSON', function() {
|
||||||
|
|
||||||
|
it('should output this pubkey', function() {
|
||||||
|
var hex = '041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341';
|
||||||
|
var pk = PublicKey.fromJSON(hex);
|
||||||
|
pk.toJSON().should.equal(hex);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
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');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
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(true).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.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 = 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)');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
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('<PublicKey: 041ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341, compressed: false>');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should output known compressed pubkey for console', function() {
|
||||||
|
var pubkey = PublicKey.fromString('031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a');
|
||||||
|
pubkey.inspect().should.equal('<PublicKey: 031ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a, compressed: true>');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
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 y value of public key');
|
||||||
|
});
|
||||||
|
|
||||||
|
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');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
|
@ -218,26 +218,26 @@ describe('Script', function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#isPubkeyhashIn', function() {
|
describe('#isPublicKeyHashIn', function() {
|
||||||
|
|
||||||
it('should classify this known pubkeyhashin', 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() {
|
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() {
|
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() {
|
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() {
|
describe('#isScripthashIn', function() {
|
||||||
|
|
||||||
it('should classify this known scripthashin', 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() {
|
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() {
|
describe('#isScripthashOut', function() {
|
||||||
|
|
||||||
it('should classify this known pubkeyhashout as pubkeyhashout', 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() {
|
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 20 0x0000000000000000000000000000000000000000 OP_EQUAL OP_EQUAL').isScriptHashOut().should.equal(false);
|
||||||
Script('OP_HASH160 21 0x000000000000000000000000000000000000000000 OP_EQUAL').isScripthashOut().should.equal(false);
|
Script('OP_HASH160 21 0x000000000000000000000000000000000000000000 OP_EQUAL').isScriptHashOut().should.equal(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue