Fix style: move each static function to an appropiate namespace
This commit is contained in:
parent
53900f3196
commit
a2a51ecc0c
5
index.js
5
index.js
|
@ -18,7 +18,10 @@ bitcore.encoding.BufferReader = require('./lib/encoding/bufferreader');
|
||||||
bitcore.encoding.BufferWriter = require('./lib/encoding/bufferwriter');
|
bitcore.encoding.BufferWriter = require('./lib/encoding/bufferwriter');
|
||||||
bitcore.encoding.Varint = require('./lib/encoding/varint');
|
bitcore.encoding.Varint = require('./lib/encoding/varint');
|
||||||
|
|
||||||
bitcore.util = require('./lib/util');
|
bitcore.util = {};
|
||||||
|
bitcore.util.bitcoin = require('./lib/util/bitcoin');
|
||||||
|
bitcore.util.buffer = require('./lib/util/buffer');
|
||||||
|
bitcore.util.js = require('./lib/util/js');
|
||||||
|
|
||||||
// main bitcoin library
|
// main bitcoin library
|
||||||
bitcore.Address = require('./lib/address');
|
bitcore.Address = require('./lib/address');
|
||||||
|
|
|
@ -4,9 +4,10 @@ var BN = require('./bn');
|
||||||
var elliptic = require('elliptic');
|
var elliptic = require('elliptic');
|
||||||
|
|
||||||
var ec = elliptic.curves.secp256k1;
|
var ec = elliptic.curves.secp256k1;
|
||||||
var ecpoint = ec.curve.point.bind(ec.curve)
|
var ecpoint = ec.curve.point.bind(ec.curve);
|
||||||
var p = ec.curve.point();
|
var p = ec.curve.point();
|
||||||
var Curve = Object.getPrototypeOf(ec.curve);
|
|
||||||
|
var bufferUtil = require('../util/buffer');
|
||||||
|
|
||||||
var Point = function Point(x, y, isRed) {
|
var Point = function Point(x, y, isRed) {
|
||||||
return ecpoint(x, y, isRed);
|
return ecpoint(x, y, isRed);
|
||||||
|
@ -27,7 +28,6 @@ Point.getN = function() {
|
||||||
|
|
||||||
Point.prototype._getX = Point.prototype.getX;
|
Point.prototype._getX = Point.prototype.getX;
|
||||||
Point.prototype.getX = function() {
|
Point.prototype.getX = function() {
|
||||||
var n = BN(this._getX().toArray());
|
|
||||||
return BN(this._getX().toArray());
|
return BN(this._getX().toArray());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -38,15 +38,34 @@ Point.prototype.getY = function() {
|
||||||
|
|
||||||
//https://www.iacr.org/archive/pkc2003/25670211/25670211.pdf
|
//https://www.iacr.org/archive/pkc2003/25670211/25670211.pdf
|
||||||
Point.prototype.validate = function() {
|
Point.prototype.validate = function() {
|
||||||
|
/* jshint maxcomplexity: 8 */
|
||||||
var p2 = Point.fromX(this.getY().isOdd(), this.getX());
|
var p2 = Point.fromX(this.getY().isOdd(), this.getX());
|
||||||
if (!(p2.y.cmp(this.y) === 0))
|
if (p2.y.cmp(this.y) !== 0) {
|
||||||
throw new Error('Invalid y value of public key');
|
throw new Error('Invalid y value of public key');
|
||||||
if (!(this.getX().gt(-1) && this.getX().lt(Point.getN()))
|
}
|
||||||
||!(this.getY().gt(-1) && this.getY().lt(Point.getN())))
|
var xValidRange = (this.getX().gt(-1) && this.getX().lt(Point.getN()));
|
||||||
|
var yValidRange = (this.getY().gt(-1) && this.getY().lt(Point.getN()));
|
||||||
|
if (!(xValidRange && yValidRange)) {
|
||||||
throw new Error('Point does not lie on the curve');
|
throw new Error('Point does not lie on the curve');
|
||||||
if (!(this.mul(Point.getN()).isInfinity()))
|
}
|
||||||
|
if (!(this.mul(Point.getN()).isInfinity())) {
|
||||||
throw new Error('Point times N must be infinity');
|
throw new Error('Point times N must be infinity');
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Point.pointToCompressed = function pointToCompressed(point) {
|
||||||
|
var xbuf = point.getX().toBuffer({size: 32});
|
||||||
|
var ybuf = point.getY().toBuffer({size: 32});
|
||||||
|
|
||||||
|
var prefix;
|
||||||
|
var odd = ybuf[ybuf.length - 1] % 2;
|
||||||
|
if (odd) {
|
||||||
|
prefix = new Buffer([0x03]);
|
||||||
|
} else {
|
||||||
|
prefix = new Buffer([0x02]);
|
||||||
|
}
|
||||||
|
return bufferUtil.concat([prefix, xbuf]);
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = Point;
|
module.exports = Point;
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
|
||||||
|
var assert = require('assert');
|
||||||
|
var buffer = require('buffer');
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
|
|
||||||
var BN = require('./crypto/bn');
|
var BN = require('./crypto/bn');
|
||||||
var Base58 = require('./encoding/base58');
|
var Base58 = require('./encoding/base58');
|
||||||
var Base58Check = require('./encoding/base58check');
|
var Base58Check = require('./encoding/base58check');
|
||||||
|
@ -11,9 +15,8 @@ var Point = require('./crypto/point');
|
||||||
var PrivateKey = require('./privatekey');
|
var PrivateKey = require('./privatekey');
|
||||||
var Random = require('./crypto/random');
|
var Random = require('./crypto/random');
|
||||||
|
|
||||||
var assert = require('assert');
|
var bufferUtil = require('./util/buffer');
|
||||||
var buffer = require('buffer');
|
var jsUtil = require('./util/js');
|
||||||
var util = require('./util');
|
|
||||||
|
|
||||||
var MINIMUM_ENTROPY_BITS = 128;
|
var MINIMUM_ENTROPY_BITS = 128;
|
||||||
var BITS_TO_BYTES = 1/8;
|
var BITS_TO_BYTES = 1/8;
|
||||||
|
@ -29,10 +32,10 @@ function HDPrivateKey(arg) {
|
||||||
return new HDPrivateKey(arg);
|
return new HDPrivateKey(arg);
|
||||||
}
|
}
|
||||||
if (arg) {
|
if (arg) {
|
||||||
if (_.isString(arg) || buffer.Buffer.isBuffer(arg)) {
|
if (_.isString(arg) || bufferUtil.isBuffer(arg)) {
|
||||||
if (HDPrivateKey.isValidSerialized(arg)) {
|
if (HDPrivateKey.isValidSerialized(arg)) {
|
||||||
this._buildFromSerialized(arg);
|
this._buildFromSerialized(arg);
|
||||||
} else if (util.isValidJson(arg)) {
|
} else if (jsUtil.isValidJson(arg)) {
|
||||||
this._buildFromJson(arg);
|
this._buildFromJson(arg);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(HDPrivateKey.getSerializedError(arg));
|
throw new Error(HDPrivateKey.getSerializedError(arg));
|
||||||
|
@ -73,12 +76,12 @@ HDPrivateKey.prototype._deriveWithNumber = function(index, hardened) {
|
||||||
return cached;
|
return cached;
|
||||||
}
|
}
|
||||||
|
|
||||||
var indexBuffer = util.integerAsBuffer(index);
|
var indexBuffer = bufferUtil.integerAsBuffer(index);
|
||||||
var data;
|
var data;
|
||||||
if (hardened) {
|
if (hardened) {
|
||||||
data = buffer.Buffer.concat([new buffer.Buffer([0]), this.privateKey.toBuffer(), indexBuffer]);
|
data = bufferUtil.concat([new buffer.Buffer([0]), this.privateKey.toBuffer(), indexBuffer]);
|
||||||
} else {
|
} else {
|
||||||
data = buffer.Buffer.concat([this.publicKey.toBuffer(), indexBuffer]);
|
data = bufferUtil.concat([this.publicKey.toBuffer(), indexBuffer]);
|
||||||
}
|
}
|
||||||
var hash = Hash.sha512hmac(data, this._buffers.chainCode);
|
var hash = Hash.sha512hmac(data, this._buffers.chainCode);
|
||||||
var leftPart = BN().fromBuffer(hash.slice(0, 32), {size: 32});
|
var leftPart = BN().fromBuffer(hash.slice(0, 32), {size: 32});
|
||||||
|
@ -143,7 +146,7 @@ HDPrivateKey.isValidSerialized = function(data, network) {
|
||||||
*/
|
*/
|
||||||
HDPrivateKey.getSerializedError = function(data, network) {
|
HDPrivateKey.getSerializedError = function(data, network) {
|
||||||
/* jshint maxcomplexity: 10 */
|
/* jshint maxcomplexity: 10 */
|
||||||
if (!(_.isString(data) || buffer.Buffer.isBuffer(data))) {
|
if (!(_.isString(data) || bufferUtil.isBuffer(data))) {
|
||||||
return HDPrivateKey.Errors.InvalidArgument;
|
return HDPrivateKey.Errors.InvalidArgument;
|
||||||
}
|
}
|
||||||
if (!Base58.validCharacters(data)) {
|
if (!Base58.validCharacters(data)) {
|
||||||
|
@ -172,7 +175,7 @@ HDPrivateKey._validateNetwork = function(data, network) {
|
||||||
return HDPrivateKey.Errors.InvalidNetworkArgument;
|
return HDPrivateKey.Errors.InvalidNetworkArgument;
|
||||||
}
|
}
|
||||||
var version = data.slice(0, 4);
|
var version = data.slice(0, 4);
|
||||||
if (util.integerFromBuffer(version) !== network.xprivkey) {
|
if (bufferUtil.integerFromBuffer(version) !== network.xprivkey) {
|
||||||
return HDPrivateKey.Errors.InvalidNetwork;
|
return HDPrivateKey.Errors.InvalidNetwork;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -186,13 +189,13 @@ HDPrivateKey.prototype._buildFromObject = function(arg) {
|
||||||
/* jshint maxcomplexity: 12 */
|
/* jshint maxcomplexity: 12 */
|
||||||
// TODO: Type validation
|
// TODO: Type validation
|
||||||
var buffers = {
|
var buffers = {
|
||||||
version: arg.network ? util.integerAsBuffer(Network.get(arg.network).xprivkey) : arg.version,
|
version: arg.network ? bufferUtil.integerAsBuffer(Network.get(arg.network).xprivkey) : arg.version,
|
||||||
depth: util.integerAsSingleByteBuffer(arg.depth),
|
depth: bufferUtil.integerAsSingleByteBuffer(arg.depth),
|
||||||
parentFingerPrint: _.isNumber(arg.parentFingerPrint) ? util.integerAsBuffer(arg.parentFingerPrint) : arg.parentFingerPrint,
|
parentFingerPrint: _.isNumber(arg.parentFingerPrint) ? bufferUtil.integerAsBuffer(arg.parentFingerPrint) : arg.parentFingerPrint,
|
||||||
childIndex: _.isNumber(arg.childIndex) ? util.integerAsBuffer(arg.childIndex) : arg.childIndex,
|
childIndex: _.isNumber(arg.childIndex) ? bufferUtil.integerAsBuffer(arg.childIndex) : arg.childIndex,
|
||||||
chainCode: _.isString(arg.chainCode) ? util.hexToBuffer(arg.chainCode) : arg.chainCode,
|
chainCode: _.isString(arg.chainCode) ? bufferUtil.hexToBuffer(arg.chainCode) : arg.chainCode,
|
||||||
privateKey: (_.isString(arg.privateKey) && util.isHexa(arg.privateKey)) ? util.hexToBuffer(arg.privateKey) : arg.privateKey,
|
privateKey: (_.isString(arg.privateKey) && jsUtil.isHexa(arg.privateKey)) ? bufferUtil.hexToBuffer(arg.privateKey) : arg.privateKey,
|
||||||
checksum: arg.checksum ? (arg.checksum.length ? arg.checksum : util.integerAsBuffer(arg.checksum)) : undefined
|
checksum: arg.checksum ? (arg.checksum.length ? arg.checksum : bufferUtil.integerAsBuffer(arg.checksum)) : undefined
|
||||||
};
|
};
|
||||||
return this._buildFromBuffers(buffers);
|
return this._buildFromBuffers(buffers);
|
||||||
};
|
};
|
||||||
|
@ -220,8 +223,8 @@ HDPrivateKey.prototype._generateRandomly = function(network) {
|
||||||
HDPrivateKey.fromSeed = function(hexa, network) {
|
HDPrivateKey.fromSeed = function(hexa, network) {
|
||||||
/* jshint maxcomplexity: 8 */
|
/* jshint maxcomplexity: 8 */
|
||||||
|
|
||||||
if (util.isHexaString(hexa)) {
|
if (jsUtil.isHexaString(hexa)) {
|
||||||
hexa = util.hexToBuffer(hexa);
|
hexa = bufferUtil.hexToBuffer(hexa);
|
||||||
}
|
}
|
||||||
if (!Buffer.isBuffer(hexa)) {
|
if (!Buffer.isBuffer(hexa)) {
|
||||||
throw new Error(HDPrivateKey.Errors.InvalidEntropyArg);
|
throw new Error(HDPrivateKey.Errors.InvalidEntropyArg);
|
||||||
|
@ -269,7 +272,7 @@ HDPrivateKey.prototype._buildFromBuffers = function(arg) {
|
||||||
|
|
||||||
var sequence = [
|
var sequence = [
|
||||||
arg.version, arg.depth, arg.parentFingerPrint, arg.childIndex, arg.chainCode,
|
arg.version, arg.depth, arg.parentFingerPrint, arg.childIndex, arg.chainCode,
|
||||||
util.emptyBuffer(1), arg.privateKey
|
bufferUtil.emptyBuffer(1), arg.privateKey
|
||||||
];
|
];
|
||||||
if (!arg.checksum || !arg.checksum.length) {
|
if (!arg.checksum || !arg.checksum.length) {
|
||||||
arg.checksum = Base58Check.checksum(buffer.Buffer.concat(sequence));
|
arg.checksum = Base58Check.checksum(buffer.Buffer.concat(sequence));
|
||||||
|
@ -284,8 +287,8 @@ HDPrivateKey.prototype._buildFromBuffers = function(arg) {
|
||||||
} else {
|
} else {
|
||||||
this.xprivkey = arg.xprivkey;
|
this.xprivkey = arg.xprivkey;
|
||||||
}
|
}
|
||||||
this.network = Network.get(util.integerFromBuffer(arg.version));
|
this.network = Network.get(bufferUtil.integerFromBuffer(arg.version));
|
||||||
this.depth = util.integerFromSingleByteBuffer(arg.depth);
|
this.depth = bufferUtil.integerFromSingleByteBuffer(arg.depth);
|
||||||
this.privateKey = new PrivateKey(BN().fromBuffer(arg.privateKey));
|
this.privateKey = new PrivateKey(BN().fromBuffer(arg.privateKey));
|
||||||
this.publicKey = this.privateKey.toPublicKey();
|
this.publicKey = this.privateKey.toPublicKey();
|
||||||
|
|
||||||
|
@ -301,7 +304,7 @@ HDPrivateKey.prototype._buildFromBuffers = function(arg) {
|
||||||
HDPrivateKey._validateBufferArguments = function(arg) {
|
HDPrivateKey._validateBufferArguments = function(arg) {
|
||||||
var checkBuffer = function(name, size) {
|
var checkBuffer = function(name, size) {
|
||||||
var buff = arg[name];
|
var buff = arg[name];
|
||||||
assert(buffer.Buffer.isBuffer(buff), name + ' argument is not a buffer');
|
assert(bufferUtil.isBuffer(buff), name + ' argument is not a buffer');
|
||||||
assert(
|
assert(
|
||||||
buff.length === size,
|
buff.length === size,
|
||||||
name + ' has not the expected size: found ' + buff.length + ', expected ' + size
|
name + ' has not the expected size: found ' + buff.length + ', expected ' + size
|
||||||
|
@ -324,14 +327,14 @@ HDPrivateKey.prototype.toString = function() {
|
||||||
|
|
||||||
HDPrivateKey.prototype.toObject = function() {
|
HDPrivateKey.prototype.toObject = function() {
|
||||||
return {
|
return {
|
||||||
network: Network.get(util.integerFromBuffer(this._buffers.version)).name,
|
network: Network.get(bufferUtil.integerFromBuffer(this._buffers.version)).name,
|
||||||
depth: util.integerFromSingleByteBuffer(this._buffers.depth),
|
depth: bufferUtil.integerFromSingleByteBuffer(this._buffers.depth),
|
||||||
fingerPrint: util.integerFromBuffer(this.fingerPrint),
|
fingerPrint: bufferUtil.integerFromBuffer(this.fingerPrint),
|
||||||
parentFingerPrint: util.integerFromBuffer(this._buffers.parentFingerPrint),
|
parentFingerPrint: bufferUtil.integerFromBuffer(this._buffers.parentFingerPrint),
|
||||||
childIndex: util.integerFromBuffer(this._buffers.childIndex),
|
childIndex: bufferUtil.integerFromBuffer(this._buffers.childIndex),
|
||||||
chainCode: util.bufferToHex(this._buffers.chainCode),
|
chainCode: bufferUtil.bufferToHex(this._buffers.chainCode),
|
||||||
privateKey: this.privateKey.toBuffer().toString('hex'),
|
privateKey: this.privateKey.toBuffer().toString('hex'),
|
||||||
checksum: util.integerFromBuffer(this._buffers.checksum),
|
checksum: bufferUtil.integerFromBuffer(this._buffers.checksum),
|
||||||
xprivkey: this.xprivkey
|
xprivkey: this.xprivkey
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,8 +12,9 @@ var Point = require('./crypto/point');
|
||||||
var PublicKey = require('./publickey');
|
var PublicKey = require('./publickey');
|
||||||
|
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var buffer = require('buffer');
|
|
||||||
var util = require('./util');
|
var jsUtil = require('./util/js');
|
||||||
|
var bufferUtil = require('./util/buffer');
|
||||||
|
|
||||||
|
|
||||||
function HDPublicKey(arg) {
|
function HDPublicKey(arg) {
|
||||||
|
@ -26,10 +27,10 @@ function HDPublicKey(arg) {
|
||||||
return new HDPublicKey(arg);
|
return new HDPublicKey(arg);
|
||||||
}
|
}
|
||||||
if (arg) {
|
if (arg) {
|
||||||
if (_.isString(arg) || buffer.Buffer.isBuffer(arg)) {
|
if (_.isString(arg) || bufferUtil.isBuffer(arg)) {
|
||||||
if (HDPublicKey.isValidSerialized(arg)) {
|
if (HDPublicKey.isValidSerialized(arg)) {
|
||||||
return this._buildFromSerialized(arg);
|
return this._buildFromSerialized(arg);
|
||||||
} else if (util.isValidJson(arg)) {
|
} else if (jsUtil.isValidJson(arg)) {
|
||||||
return this._buildFromJson(arg);
|
return this._buildFromJson(arg);
|
||||||
} else {
|
} else {
|
||||||
var error = HDPublicKey.getSerializedError(arg);
|
var error = HDPublicKey.getSerializedError(arg);
|
||||||
|
@ -73,8 +74,8 @@ HDPublicKey.prototype._deriveWithNumber = function (index, hardened) {
|
||||||
return cached;
|
return cached;
|
||||||
}
|
}
|
||||||
|
|
||||||
var indexBuffer = util.integerAsBuffer(index);
|
var indexBuffer = bufferUtil.integerAsBuffer(index);
|
||||||
var data = buffer.Buffer.concat([this.publicKey.toBuffer(), indexBuffer]);
|
var data = bufferUtil.concat([this.publicKey.toBuffer(), indexBuffer]);
|
||||||
var hash = Hash.sha512hmac(data, this._buffers.chainCode);
|
var hash = Hash.sha512hmac(data, this._buffers.chainCode);
|
||||||
var leftPart = BN().fromBuffer(hash.slice(0, 32), {size: 32});
|
var leftPart = BN().fromBuffer(hash.slice(0, 32), {size: 32});
|
||||||
var chainCode = hash.slice(32, 64);
|
var chainCode = hash.slice(32, 64);
|
||||||
|
@ -140,7 +141,7 @@ HDPublicKey.isValidSerialized = function (data, network) {
|
||||||
HDPublicKey.getSerializedError = function (data, network) {
|
HDPublicKey.getSerializedError = function (data, network) {
|
||||||
/* jshint maxcomplexity: 10 */
|
/* jshint maxcomplexity: 10 */
|
||||||
/* jshint maxstatements: 20 */
|
/* jshint maxstatements: 20 */
|
||||||
if (!(_.isString(data) || buffer.Buffer.isBuffer(data))) {
|
if (!(_.isString(data) || bufferUtil.isBuffer(data))) {
|
||||||
return HDPublicKey.Errors.InvalidArgument;
|
return HDPublicKey.Errors.InvalidArgument;
|
||||||
}
|
}
|
||||||
if (!Base58.validCharacters(data)) {
|
if (!Base58.validCharacters(data)) {
|
||||||
|
@ -161,7 +162,7 @@ HDPublicKey.getSerializedError = function (data, network) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
network = Network.get(network) || Network.defaultNetwork;
|
network = Network.get(network) || Network.defaultNetwork;
|
||||||
if (util.integerFromBuffer(data.slice(0, 4)) === network.xprivkey) {
|
if (bufferUtil.integerFromBuffer(data.slice(0, 4)) === network.xprivkey) {
|
||||||
return HDPublicKey.Errors.ArgumentIsPrivateExtended;
|
return HDPublicKey.Errors.ArgumentIsPrivateExtended;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -173,7 +174,7 @@ HDPublicKey._validateNetwork = function (data, network) {
|
||||||
return HDPublicKey.Errors.InvalidNetworkArgument;
|
return HDPublicKey.Errors.InvalidNetworkArgument;
|
||||||
}
|
}
|
||||||
var version = data.slice(HDPublicKey.VersionStart, HDPublicKey.VersionEnd);
|
var version = data.slice(HDPublicKey.VersionStart, HDPublicKey.VersionEnd);
|
||||||
if (util.integerFromBuffer(version) !== network.xpubkey) {
|
if (bufferUtil.integerFromBuffer(version) !== network.xpubkey) {
|
||||||
return HDPublicKey.Errors.InvalidNetwork;
|
return HDPublicKey.Errors.InvalidNetwork;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -186,8 +187,8 @@ HDPublicKey.prototype._buildFromJson = function (arg) {
|
||||||
HDPublicKey.prototype._buildFromPrivate = function (arg) {
|
HDPublicKey.prototype._buildFromPrivate = function (arg) {
|
||||||
var args = _.clone(arg._buffers);
|
var args = _.clone(arg._buffers);
|
||||||
var point = Point.getG().mul(BN().fromBuffer(args.privateKey));
|
var point = Point.getG().mul(BN().fromBuffer(args.privateKey));
|
||||||
args.publicKey = util.pointToCompressed(point);
|
args.publicKey = Point.pointToCompressed(point);
|
||||||
args.version = util.integerAsBuffer(Network.get(util.integerFromBuffer(args.version)).xpubkey);
|
args.version = bufferUtil.integerAsBuffer(Network.get(bufferUtil.integerFromBuffer(args.version)).xpubkey);
|
||||||
args.privateKey = undefined;
|
args.privateKey = undefined;
|
||||||
args.checksum = undefined;
|
args.checksum = undefined;
|
||||||
args.xprivkey = undefined;
|
args.xprivkey = undefined;
|
||||||
|
@ -198,14 +199,14 @@ HDPublicKey.prototype._buildFromObject = function (arg) {
|
||||||
/* jshint maxcomplexity: 10 */
|
/* jshint maxcomplexity: 10 */
|
||||||
// TODO: Type validation
|
// TODO: Type validation
|
||||||
var buffers = {
|
var buffers = {
|
||||||
version: arg.network ? util.integerAsBuffer(Network.get(arg.network).xpubkey) : arg.version,
|
version: arg.network ? bufferUtil.integerAsBuffer(Network.get(arg.network).xpubkey) : arg.version,
|
||||||
depth: util.integerAsSingleByteBuffer(arg.depth),
|
depth: bufferUtil.integerAsSingleByteBuffer(arg.depth),
|
||||||
parentFingerPrint: _.isNumber(arg.parentFingerPrint) ? util.integerAsBuffer(arg.parentFingerPrint) : arg.parentFingerPrint,
|
parentFingerPrint: _.isNumber(arg.parentFingerPrint) ? bufferUtil.integerAsBuffer(arg.parentFingerPrint) : arg.parentFingerPrint,
|
||||||
childIndex: util.integerAsBuffer(arg.childIndex),
|
childIndex: bufferUtil.integerAsBuffer(arg.childIndex),
|
||||||
chainCode: _.isString(arg.chainCode) ? util.hexToBuffer(arg.chainCode) : arg.chainCode,
|
chainCode: _.isString(arg.chainCode) ? bufferUtil.hexToBuffer(arg.chainCode) : arg.chainCode,
|
||||||
publicKey: _.isString(arg.publicKey) ? util.hexToBuffer(arg.publicKey) :
|
publicKey: _.isString(arg.publicKey) ? bufferUtil.hexToBuffer(arg.publicKey) :
|
||||||
buffer.Buffer.isBuffer(arg.publicKey) ? arg.publicKey : arg.publicKey.toBuffer(),
|
bufferUtil.isBuffer(arg.publicKey) ? arg.publicKey : arg.publicKey.toBuffer(),
|
||||||
checksum: _.isNumber(arg.checksum) ? util.integerAsBuffer(arg.checksum) : arg.checksum
|
checksum: _.isNumber(arg.checksum) ? bufferUtil.integerAsBuffer(arg.checksum) : arg.checksum
|
||||||
};
|
};
|
||||||
return this._buildFromBuffers(buffers);
|
return this._buildFromBuffers(buffers);
|
||||||
};
|
};
|
||||||
|
@ -253,7 +254,7 @@ HDPublicKey.prototype._buildFromBuffers = function (arg) {
|
||||||
arg.version, arg.depth, arg.parentFingerPrint, arg.childIndex, arg.chainCode,
|
arg.version, arg.depth, arg.parentFingerPrint, arg.childIndex, arg.chainCode,
|
||||||
arg.publicKey
|
arg.publicKey
|
||||||
];
|
];
|
||||||
var concat = buffer.Buffer.concat(sequence);
|
var concat = bufferUtil.concat(sequence);
|
||||||
var checksum = Base58Check.checksum(concat);
|
var checksum = Base58Check.checksum(concat);
|
||||||
if (!arg.checksum || !arg.checksum.length) {
|
if (!arg.checksum || !arg.checksum.length) {
|
||||||
arg.checksum = checksum;
|
arg.checksum = checksum;
|
||||||
|
@ -264,13 +265,13 @@ HDPublicKey.prototype._buildFromBuffers = function (arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!arg.xpubkey) {
|
if (!arg.xpubkey) {
|
||||||
this.xpubkey = Base58Check.encode(buffer.Buffer.concat(sequence));
|
this.xpubkey = Base58Check.encode(bufferUtil.concat(sequence));
|
||||||
} else {
|
} else {
|
||||||
this.xpubkey = arg.xpubkey;
|
this.xpubkey = arg.xpubkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.network = Network.get(util.integerFromBuffer(arg.version));
|
this.network = Network.get(bufferUtil.integerFromBuffer(arg.version));
|
||||||
this.depth = util.integerFromSingleByteBuffer(arg.depth);
|
this.depth = bufferUtil.integerFromSingleByteBuffer(arg.depth);
|
||||||
this.publicKey = PublicKey.fromString(arg.publicKey);
|
this.publicKey = PublicKey.fromString(arg.publicKey);
|
||||||
this.fingerPrint = Hash.sha256ripemd160(this.publicKey.toBuffer()).slice(0, HDPublicKey.ParentFingerPrintSize);
|
this.fingerPrint = Hash.sha256ripemd160(this.publicKey.toBuffer()).slice(0, HDPublicKey.ParentFingerPrintSize);
|
||||||
|
|
||||||
|
@ -280,7 +281,7 @@ HDPublicKey.prototype._buildFromBuffers = function (arg) {
|
||||||
HDPublicKey._validateBufferArguments = function (arg) {
|
HDPublicKey._validateBufferArguments = function (arg) {
|
||||||
var checkBuffer = function(name, size) {
|
var checkBuffer = function(name, size) {
|
||||||
var buff = arg[name];
|
var buff = arg[name];
|
||||||
assert(buffer.Buffer.isBuffer(buff), name + ' argument is not a buffer, it\'s ' + typeof buff);
|
assert(bufferUtil.isBuffer(buff), name + ' argument is not a buffer, it\'s ' + typeof buff);
|
||||||
assert(
|
assert(
|
||||||
buff.length === size,
|
buff.length === size,
|
||||||
name + ' has not the expected size: found ' + buff.length + ', expected ' + size
|
name + ' has not the expected size: found ' + buff.length + ', expected ' + size
|
||||||
|
@ -303,14 +304,14 @@ HDPublicKey.prototype.toString = function () {
|
||||||
|
|
||||||
HDPublicKey.prototype.toObject = function () {
|
HDPublicKey.prototype.toObject = function () {
|
||||||
return {
|
return {
|
||||||
network: Network.get(util.integerFromBuffer(this._buffers.version)).name,
|
network: Network.get(bufferUtil.integerFromBuffer(this._buffers.version)).name,
|
||||||
depth: util.integerFromSingleByteBuffer(this._buffers.depth),
|
depth: bufferUtil.integerFromSingleByteBuffer(this._buffers.depth),
|
||||||
fingerPrint: util.integerFromBuffer(this.fingerPrint),
|
fingerPrint: bufferUtil.integerFromBuffer(this.fingerPrint),
|
||||||
parentFingerPrint: util.integerFromBuffer(this._buffers.parentFingerPrint),
|
parentFingerPrint: bufferUtil.integerFromBuffer(this._buffers.parentFingerPrint),
|
||||||
childIndex: util.integerFromBuffer(this._buffers.childIndex),
|
childIndex: bufferUtil.integerFromBuffer(this._buffers.childIndex),
|
||||||
chainCode: util.bufferToHex(this._buffers.chainCode),
|
chainCode: bufferUtil.bufferToHex(this._buffers.chainCode),
|
||||||
publicKey: this.publicKey.toString(),
|
publicKey: this.publicKey.toString(),
|
||||||
checksum: util.integerFromBuffer(this._buffers.checksum),
|
checksum: bufferUtil.integerFromBuffer(this._buffers.checksum),
|
||||||
xpubkey: this.xpubkey
|
xpubkey: this.xpubkey
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
81
lib/util.js
81
lib/util.js
|
@ -1,81 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var _ = require('lodash');
|
|
||||||
var buffer = require('buffer');
|
|
||||||
var assert = require('assert');
|
|
||||||
|
|
||||||
var isHexa = function isHexa(value) {
|
|
||||||
if (!_.isString(value)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return /^[0-9a-fA-F]+$/.test(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
var shallowEquals = function(obj1, obj2) {
|
|
||||||
var keys1 = _.keys(obj1);
|
|
||||||
var keys2 = _.keys(obj2);
|
|
||||||
if (_.size(keys1) !== _.size(keys2)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
var compare = function(key) { return obj1[key] === obj2[key]; };
|
|
||||||
return _.all(keys1, compare) && _.all(keys2, compare);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
shallowEquals: shallowEquals,
|
|
||||||
isValidJson: function isValidJson(arg) {
|
|
||||||
try {
|
|
||||||
JSON.parse(arg);
|
|
||||||
return true;
|
|
||||||
} catch (e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
emptyBuffer: function emptyBuffer(bytes) {
|
|
||||||
var result = new Buffer(bytes);
|
|
||||||
for (var i = 0; i < bytes; i++) {
|
|
||||||
result.write('\0', i);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
integerAsSingleByteBuffer: function integerAsSingleByteBuffer(integer) {
|
|
||||||
return new Buffer([integer & 0xff]);
|
|
||||||
},
|
|
||||||
integerAsBuffer: function integerAsBuffer(integer) {
|
|
||||||
var bytes = [];
|
|
||||||
bytes.push((integer >> 24) & 0xff);
|
|
||||||
bytes.push((integer >> 16) & 0xff);
|
|
||||||
bytes.push((integer >> 8) & 0xff);
|
|
||||||
bytes.push(integer & 0xff);
|
|
||||||
return new Buffer(bytes);
|
|
||||||
},
|
|
||||||
isHexa: isHexa,
|
|
||||||
isHexaString: isHexa,
|
|
||||||
|
|
||||||
integerFromBuffer: function integerFromBuffer(buffer) {
|
|
||||||
return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
|
|
||||||
},
|
|
||||||
integerFromSingleByteBuffer: function integerFromBuffer(buffer) {
|
|
||||||
return buffer[0];
|
|
||||||
},
|
|
||||||
bufferToHex: function bufferToHex(buffer) {
|
|
||||||
return buffer.toString('hex');
|
|
||||||
},
|
|
||||||
hexToBuffer: function hexToBuffer(string) {
|
|
||||||
assert(isHexa(string));
|
|
||||||
return new buffer.Buffer(string, 'hex');
|
|
||||||
},
|
|
||||||
pointToCompressed: function pointToCompressed(point) {
|
|
||||||
var xbuf = point.getX().toBuffer({size: 32});
|
|
||||||
var ybuf = point.getY().toBuffer({size: 32});
|
|
||||||
|
|
||||||
var prefix;
|
|
||||||
var odd = ybuf[ybuf.length - 1] % 2;
|
|
||||||
if (odd) {
|
|
||||||
prefix = new Buffer([0x03]);
|
|
||||||
} else {
|
|
||||||
prefix = new Buffer([0x02]);
|
|
||||||
}
|
|
||||||
return buffer.Buffer.concat([prefix, xbuf]);
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
/**
|
||||||
|
* @file util/bitcoin.js
|
||||||
|
* Contains utilities to handle magnitudes inside of bitcoin
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var SATOSHIS_PER_BTC = 1e8;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
/**
|
||||||
|
* @param number satoshis - amount of satoshis to convert
|
||||||
|
* @return string an exact representation of such amount, in form of a string
|
||||||
|
* (avoids duplicate representations in ieee756 of the same number)
|
||||||
|
*/
|
||||||
|
satoshisToBitcoin: function(satoshis) {
|
||||||
|
return satoshis / SATOSHIS_PER_BTC;
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,109 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var buffer = require('buffer');
|
||||||
|
var assert = require('assert');
|
||||||
|
|
||||||
|
var js = require('./js');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
/**
|
||||||
|
* Returns true if the given argument is an instance of a buffer. Tests for
|
||||||
|
* both node's Buffer and Uint8Array
|
||||||
|
*
|
||||||
|
* @param {*} arg
|
||||||
|
* @return {boolean}
|
||||||
|
*/
|
||||||
|
isBuffer: function isBuffer(arg) {
|
||||||
|
return buffer.Buffer.isBuffer(arg) || arg instanceof Uint8Array;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a zero-filled byte array
|
||||||
|
*
|
||||||
|
* @param {number} bytes
|
||||||
|
* @return {Buffer}
|
||||||
|
*/
|
||||||
|
emptyBuffer: function emptyBuffer(bytes) {
|
||||||
|
var result = new buffer.Buffer(bytes);
|
||||||
|
for (var i = 0; i < bytes; i++) {
|
||||||
|
result.write('\0', i);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Concatenates a buffer
|
||||||
|
*
|
||||||
|
* Shortcut for <tt>buffer.Buffer.concat</tt>
|
||||||
|
*/
|
||||||
|
concat: buffer.Buffer.concat,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms a number from 0 to 255 into a Buffer of size 1 with that value
|
||||||
|
*
|
||||||
|
* @param {number} integer
|
||||||
|
* @return {Buffer}
|
||||||
|
*/
|
||||||
|
integerAsSingleByteBuffer: function integerAsSingleByteBuffer(integer) {
|
||||||
|
return new buffer.Buffer([integer & 0xff]);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform a 4-byte integer into a Buffer of length 4.
|
||||||
|
*
|
||||||
|
* @param {number} integer
|
||||||
|
* @return {Buffer}
|
||||||
|
*/
|
||||||
|
integerAsBuffer: function integerAsBuffer(integer) {
|
||||||
|
var bytes = [];
|
||||||
|
bytes.push((integer >> 24) & 0xff);
|
||||||
|
bytes.push((integer >> 16) & 0xff);
|
||||||
|
bytes.push((integer >> 8) & 0xff);
|
||||||
|
bytes.push(integer & 0xff);
|
||||||
|
return new Buffer(bytes);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the first 4 values of a Buffer into a number, in little endian encoding
|
||||||
|
*
|
||||||
|
* @param {Buffer} buffer
|
||||||
|
* @return {number}
|
||||||
|
*/
|
||||||
|
integerFromBuffer: function integerFromBuffer(buffer) {
|
||||||
|
return buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms the first byte of an array into a number ranging from -128 to 127
|
||||||
|
* @param {Buffer} buffer
|
||||||
|
* @return {number}
|
||||||
|
*/
|
||||||
|
integerFromSingleByteBuffer: function integerFromBuffer(buffer) {
|
||||||
|
return buffer[0];
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms a buffer into a string with a number in hexa representation
|
||||||
|
*
|
||||||
|
* Shorthand for <tt>buffer.toString('hex')</tt>
|
||||||
|
*
|
||||||
|
* @param {Buffer} buffer
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
bufferToHex: function bufferToHex(buffer) {
|
||||||
|
return buffer.toString('hex');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms an hexa encoded string into a Buffer with binary values
|
||||||
|
*
|
||||||
|
* Shorthand for <tt>Buffer(string, 'hex')</tt>
|
||||||
|
*
|
||||||
|
* @param {string} string
|
||||||
|
* @return {Buffer}
|
||||||
|
*/
|
||||||
|
hexToBuffer: function hexToBuffer(string) {
|
||||||
|
assert(js.isHexa(string));
|
||||||
|
return new buffer.Buffer(string, 'hex');
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,35 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether a string contains only hexadecimal values
|
||||||
|
*
|
||||||
|
* @param {string} value
|
||||||
|
* @return {boolean} true if the string is the hexa representation of a number
|
||||||
|
*/
|
||||||
|
var isHexa = function isHexa(value) {
|
||||||
|
if (!_.isString(value)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return /^[0-9a-fA-F]+$/.test(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
/**
|
||||||
|
* Test if an argument is a valid JSON object. If it is, returns a truthy
|
||||||
|
* value (the json object decoded), so no double JSON.parse call is necessary
|
||||||
|
*
|
||||||
|
* @param {string} arg
|
||||||
|
* @return {Object|boolean} false if the argument is not a JSON string.
|
||||||
|
*/
|
||||||
|
isValidJson: function isValidJson(arg) {
|
||||||
|
try {
|
||||||
|
return JSON.parse(arg);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isHexa: isHexa,
|
||||||
|
isHexaString: isHexa
|
||||||
|
};
|
|
@ -6,7 +6,7 @@ var should = require('chai').should();
|
||||||
var expect = require('chai').expect;
|
var expect = require('chai').expect;
|
||||||
var bitcore = require('..');
|
var bitcore = require('..');
|
||||||
var buffer = require('buffer');
|
var buffer = require('buffer');
|
||||||
var util = bitcore.util;
|
var bufferUtil = bitcore.util.buffer;
|
||||||
var HDPrivateKey = bitcore.HDPrivateKey;
|
var HDPrivateKey = bitcore.HDPrivateKey;
|
||||||
var Base58Check = bitcore.encoding.Base58Check;
|
var Base58Check = bitcore.encoding.Base58Check;
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ describe('HDPrivate key interface', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('builds a json keeping the structure and same members', function() {
|
it('builds a json keeping the structure and same members', function() {
|
||||||
assert(util.shallowEquals(
|
assert(_.isEqual(
|
||||||
JSON.parse(new HDPrivateKey(json).toJson()),
|
JSON.parse(new HDPrivateKey(json).toJson()),
|
||||||
JSON.parse(new HDPrivateKey(xprivkey).toJson())
|
JSON.parse(new HDPrivateKey(xprivkey).toJson())
|
||||||
));
|
));
|
||||||
|
@ -130,7 +130,7 @@ describe('HDPrivate key interface', function() {
|
||||||
var privKey = new HDPrivateKey(xprivkey);
|
var privKey = new HDPrivateKey(xprivkey);
|
||||||
expect(function() {
|
expect(function() {
|
||||||
var buffers = privKey._buffers;
|
var buffers = privKey._buffers;
|
||||||
buffers.checksum = util.integerAsBuffer(0);
|
buffers.checksum = bufferUtil.integerAsBuffer(0);
|
||||||
return new HDPrivateKey(buffers);
|
return new HDPrivateKey(buffers);
|
||||||
}).to.throw(HDPrivateKey.Errors.InvalidB58Checksum);
|
}).to.throw(HDPrivateKey.Errors.InvalidB58Checksum);
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,7 +7,7 @@ var should = require('chai').should();
|
||||||
var expect = require('chai').expect;
|
var expect = require('chai').expect;
|
||||||
var bitcore = require('..');
|
var bitcore = require('..');
|
||||||
var buffer = require('buffer');
|
var buffer = require('buffer');
|
||||||
var util = bitcore.util;
|
var bufferUtil = bitcore.util.buffer;
|
||||||
var HDPrivateKey = bitcore.HDPrivateKey;
|
var HDPrivateKey = bitcore.HDPrivateKey;
|
||||||
var HDPublicKey = bitcore.HDPublicKey;
|
var HDPublicKey = bitcore.HDPublicKey;
|
||||||
var Base58Check = bitcore.encoding.Base58Check;
|
var Base58Check = bitcore.encoding.Base58Check;
|
||||||
|
@ -71,7 +71,7 @@ describe('HDPublicKey interface', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can generate a json that has a particular structure', function() {
|
it('can generate a json that has a particular structure', function() {
|
||||||
assert(util.shallowEquals(
|
assert(_.isEqual(
|
||||||
JSON.parse(new HDPublicKey(json).toJson()),
|
JSON.parse(new HDPublicKey(json).toJson()),
|
||||||
JSON.parse(new HDPublicKey(xpubkey).toJson())
|
JSON.parse(new HDPublicKey(xpubkey).toJson())
|
||||||
));
|
));
|
||||||
|
@ -83,7 +83,7 @@ describe('HDPublicKey interface', function() {
|
||||||
|
|
||||||
it('checks the checksum', function() {
|
it('checks the checksum', function() {
|
||||||
var buffers = new HDPublicKey(xpubkey)._buffers;
|
var buffers = new HDPublicKey(xpubkey)._buffers;
|
||||||
buffers.checksum = util.integerAsBuffer(1);
|
buffers.checksum = bufferUtil.integerAsBuffer(1);
|
||||||
expectFail(buffers, HDPublicKey.Errors.InvalidB58Checksum)();
|
expectFail(buffers, HDPublicKey.Errors.InvalidB58Checksum)();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue