digest: avoid extra allocations.
This commit is contained in:
parent
2f51fd1c50
commit
37da047a34
@ -11,7 +11,6 @@
|
||||
*/
|
||||
|
||||
const crypto = require('crypto');
|
||||
const util = require('../utils/util');
|
||||
const native = require('../native').binding;
|
||||
|
||||
/**
|
||||
@ -24,7 +23,7 @@ const native = require('../native').binding;
|
||||
|
||||
exports.encipher = function encipher(data, key, iv) {
|
||||
let cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
|
||||
return util.concat(cipher.update(data), cipher.final());
|
||||
return Buffer.concat([cipher.update(data), cipher.final()]);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -38,7 +37,7 @@ exports.encipher = function encipher(data, key, iv) {
|
||||
exports.decipher = function _decipher(data, key, iv) {
|
||||
let decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
|
||||
try {
|
||||
return util.concat(decipher.update(data), decipher.final());
|
||||
return Buffer.concat([decipher.update(data), decipher.final()]);
|
||||
} catch (e) {
|
||||
throw new Error('Bad key for decryption.');
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
const assert = require('assert');
|
||||
const hashjs = require('hash.js');
|
||||
const sha256 = require('./sha256');
|
||||
const POOL64 = Buffer.allocUnsafe(64);
|
||||
|
||||
/**
|
||||
* Hash with chosen algorithm.
|
||||
@ -85,6 +86,25 @@ exports.hash256 = function hash256(data) {
|
||||
return sha256.hash256(data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Hash left and right hashes with hash256.
|
||||
* @param {Buffer} left
|
||||
* @param {Buffer} right
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.root256 = function root256(left, right) {
|
||||
let data = POOL64;
|
||||
|
||||
assert(left.length === 32);
|
||||
assert(right.length === 32);
|
||||
|
||||
left.copy(data, 0);
|
||||
right.copy(data, 32);
|
||||
|
||||
return exports.hash256(data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an HMAC.
|
||||
* @param {String} alg
|
||||
|
||||
@ -10,8 +10,10 @@
|
||||
* @module crypto.digest
|
||||
*/
|
||||
|
||||
const assert = require('assert');
|
||||
const crypto = require('crypto');
|
||||
const native = require('../native').binding;
|
||||
const POOL64 = Buffer.allocUnsafe(64);
|
||||
|
||||
/**
|
||||
* Hash with chosen algorithm.
|
||||
@ -74,6 +76,25 @@ exports.hash256 = function hash256(data) {
|
||||
return exports.sha256(exports.sha256(data));
|
||||
};
|
||||
|
||||
/**
|
||||
* Hash left and right hashes with hash256.
|
||||
* @param {Buffer} left
|
||||
* @param {Buffer} right
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.root256 = function root256(left, right) {
|
||||
let data = POOL64;
|
||||
|
||||
assert(left.length === 32);
|
||||
assert(right.length === 32);
|
||||
|
||||
left.copy(data, 0);
|
||||
right.copy(data, 32);
|
||||
|
||||
return exports.hash256(data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an HMAC.
|
||||
* @param {String} alg
|
||||
@ -95,4 +116,5 @@ if (native) {
|
||||
exports.sha256 = native.sha256;
|
||||
exports.hash160 = native.hash160;
|
||||
exports.hash256 = native.hash256;
|
||||
exports.root256 = native.root256;
|
||||
}
|
||||
|
||||
@ -25,7 +25,6 @@ exports.createTree = function createTree(leaves) {
|
||||
let nodes = leaves;
|
||||
let size = leaves.length;
|
||||
let malleated = false;
|
||||
let data;
|
||||
|
||||
if (size === 0) {
|
||||
let hash = Buffer.allocUnsafe(32);
|
||||
@ -34,8 +33,6 @@ exports.createTree = function createTree(leaves) {
|
||||
return [nodes, malleated];
|
||||
}
|
||||
|
||||
data = Buffer.allocUnsafe(64);
|
||||
|
||||
for (let j = 0; size > 1; size = (size + 1) >>> 1) {
|
||||
for (let i = 0; i < size; i += 2) {
|
||||
let k = Math.min(i + 1, size - 1);
|
||||
@ -48,10 +45,7 @@ exports.createTree = function createTree(leaves) {
|
||||
malleated = true;
|
||||
}
|
||||
|
||||
left.copy(data, 0);
|
||||
right.copy(data, 32);
|
||||
|
||||
hash = digest.hash256(data);
|
||||
hash = digest.root256(left, right);
|
||||
|
||||
nodes.push(hash);
|
||||
}
|
||||
@ -108,25 +102,17 @@ exports.createBranch = function createBranch(index, leaves) {
|
||||
*/
|
||||
|
||||
exports.verifyBranch = function verifyBranch(hash, branch, index) {
|
||||
let data;
|
||||
|
||||
if (branch.length === 0)
|
||||
return hash;
|
||||
|
||||
data = Buffer.allocUnsafe(64);
|
||||
|
||||
for (let i = 0; i < branch.length; i++) {
|
||||
let otherside = branch[i];
|
||||
|
||||
if (index & 1) {
|
||||
otherside.copy(data, 0);
|
||||
hash.copy(data, 32);
|
||||
} else {
|
||||
hash.copy(data, 0);
|
||||
otherside.copy(data, 32);
|
||||
}
|
||||
if (index & 1)
|
||||
hash = digest.root256(otherside, hash);
|
||||
else
|
||||
hash = digest.root256(hash, otherside);
|
||||
|
||||
hash = digest.hash256(data);
|
||||
index >>>= 1;
|
||||
}
|
||||
|
||||
|
||||
@ -276,18 +276,18 @@ Miner.prototype.assemble = function assemble(attempt) {
|
||||
if (tx.isCoinbase())
|
||||
throw new Error('Cannot add coinbase to block.');
|
||||
|
||||
for (let input of tx.inputs) {
|
||||
let prev = input.prevout.hash;
|
||||
for (let {prevout} of tx.inputs) {
|
||||
let hash = prevout.hash;
|
||||
|
||||
if (!this.mempool.hasEntry(prev))
|
||||
if (!this.mempool.hasEntry(hash))
|
||||
continue;
|
||||
|
||||
item.depCount += 1;
|
||||
|
||||
if (!depMap[prev])
|
||||
depMap[prev] = [];
|
||||
if (!depMap[hash])
|
||||
depMap[hash] = [];
|
||||
|
||||
depMap[prev].push(item);
|
||||
depMap[hash].push(item);
|
||||
}
|
||||
|
||||
if (item.depCount > 0)
|
||||
@ -344,7 +344,7 @@ Miner.prototype.assemble = function assemble(attempt) {
|
||||
if (!deps)
|
||||
continue;
|
||||
|
||||
for (item of deps) {
|
||||
for (let item of deps) {
|
||||
if (--item.depCount === 0)
|
||||
queue.insert(item);
|
||||
}
|
||||
|
||||
@ -173,7 +173,7 @@ BlockTemplate.fromOptions = function fromOptions(options) {
|
||||
BlockTemplate.prototype.getWitnessHash = function getWitnessHash() {
|
||||
let nonce = encoding.ZERO_HASH;
|
||||
let leaves = [];
|
||||
let root, malleated, data;
|
||||
let root, malleated;
|
||||
|
||||
leaves.push(encoding.ZERO_HASH);
|
||||
|
||||
@ -184,9 +184,7 @@ BlockTemplate.prototype.getWitnessHash = function getWitnessHash() {
|
||||
|
||||
assert(!malleated);
|
||||
|
||||
data = util.concat(root, nonce);
|
||||
|
||||
return digest.hash256(data);
|
||||
return digest.root256(root, nonce);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -697,10 +695,8 @@ function MerkleTree() {
|
||||
}
|
||||
|
||||
MerkleTree.prototype.withFirst = function withFirst(hash) {
|
||||
for (let step of this.steps) {
|
||||
let data = util.concat(hash, step);
|
||||
hash = digest.hash256(data);
|
||||
}
|
||||
for (let step of this.steps)
|
||||
hash = digest.root256(hash, step);
|
||||
return hash;
|
||||
};
|
||||
|
||||
@ -757,8 +753,7 @@ MerkleTree.prototype.fromLeaves = function fromLeaves(leaves) {
|
||||
leaves.push(leaves[len - 1]);
|
||||
|
||||
for (let i = 2; i < len; i += 2) {
|
||||
let data = util.concat(leaves[i], leaves[i + 1]);
|
||||
let hash = digest.hash256(data);
|
||||
let hash = digest.root256(leaves[i], leaves[i + 1]);
|
||||
hashes.push(hash);
|
||||
}
|
||||
|
||||
|
||||
@ -400,7 +400,7 @@ CompactBlock.prototype.hasIndex = function hasIndex(index) {
|
||||
*/
|
||||
|
||||
CompactBlock.prototype.initKey = function initKey() {
|
||||
let data = util.concat(this.abbr(), this.keyNonce);
|
||||
let data = Buffer.concat([this.abbr(), this.keyNonce]);
|
||||
let hash = digest.sha256(data);
|
||||
this.sipKey = hash.slice(0, 16);
|
||||
};
|
||||
|
||||
@ -20,6 +20,7 @@ const seeds = require('./seeds');
|
||||
const dns = require('./dns');
|
||||
const Logger = require('../node/logger');
|
||||
const fs = require('../utils/fs');
|
||||
const POOL32 = Buffer.allocUnsafe(32);
|
||||
|
||||
/**
|
||||
* Host List
|
||||
@ -459,7 +460,7 @@ HostList.prototype.getHost = function getHost() {
|
||||
HostList.prototype.freshBucket = function freshBucket(entry) {
|
||||
let addr = entry.addr;
|
||||
let src = entry.src;
|
||||
let data = util.concat(addr.raw, src.raw);
|
||||
let data = concat32(addr.raw, src.raw);
|
||||
let hash = murmur3(data, 0xfba4c795);
|
||||
let index = hash % this.fresh.length;
|
||||
return this.fresh[index];
|
||||
@ -1588,6 +1589,17 @@ HostListOptions.prototype.fromOptions = function fromOptions(options) {
|
||||
return this;
|
||||
};
|
||||
|
||||
/*
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function concat32(left, right) {
|
||||
let data = POOL32;
|
||||
left.copy(data, 0);
|
||||
right.copy(data, 32);
|
||||
return data;
|
||||
}
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
@ -298,7 +298,7 @@ Block.prototype.createMerkleRoot = function createMerkleRoot(enc) {
|
||||
*/
|
||||
|
||||
Block.prototype.createWitnessNonce = function createWitnessNonce() {
|
||||
return util.copy(encoding.ZERO_HASH);
|
||||
return Buffer.from(encoding.ZERO_HASH);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -311,7 +311,7 @@ Block.prototype.createWitnessNonce = function createWitnessNonce() {
|
||||
Block.prototype.createCommitmentHash = function createCommitmentHash(enc) {
|
||||
let nonce = this.getWitnessNonce();
|
||||
let leaves = [];
|
||||
let root, data, hash;
|
||||
let root, hash;
|
||||
|
||||
assert(nonce, 'No witness nonce present.');
|
||||
|
||||
@ -327,9 +327,7 @@ Block.prototype.createCommitmentHash = function createCommitmentHash(enc) {
|
||||
// Note: malleation check ignored here.
|
||||
// assert(!malleated);
|
||||
|
||||
data = util.concat(root, nonce);
|
||||
|
||||
hash = digest.hash256(data);
|
||||
hash = digest.root256(root, nonce);
|
||||
|
||||
return enc === 'hex'
|
||||
? hash.toString('hex')
|
||||
|
||||
@ -17,7 +17,6 @@ const consensus = require('../protocol/consensus');
|
||||
const AbstractBlock = require('./abstractblock');
|
||||
const Headers = require('./headers');
|
||||
const DUMMY = Buffer.from([0]);
|
||||
const POOL = Buffer.allocUnsafe(64);
|
||||
|
||||
/**
|
||||
* Represents a merkle (filtered) block.
|
||||
@ -200,7 +199,6 @@ MerkleBlock.prototype.extractTree = function extractTree() {
|
||||
let flags = this.flags;
|
||||
let totalTX = this.totalTX;
|
||||
let height = 0;
|
||||
let data = POOL;
|
||||
let root;
|
||||
|
||||
let width = (height) => {
|
||||
@ -246,10 +244,7 @@ MerkleBlock.prototype.extractTree = function extractTree() {
|
||||
right = left;
|
||||
}
|
||||
|
||||
left.copy(data, 0);
|
||||
right.copy(data, 32);
|
||||
|
||||
return digest.hash256(data);
|
||||
return digest.root256(left, right);
|
||||
};
|
||||
|
||||
if (totalTX === 0)
|
||||
@ -566,7 +561,6 @@ MerkleBlock.fromMatches = function fromMatches(block, matches) {
|
||||
let hashes = [];
|
||||
let totalTX = block.txs.length;
|
||||
let height = 0;
|
||||
let data = POOL;
|
||||
let flags, merkle;
|
||||
|
||||
let width = (height) => {
|
||||
@ -586,10 +580,7 @@ MerkleBlock.fromMatches = function fromMatches(block, matches) {
|
||||
else
|
||||
right = left;
|
||||
|
||||
left.copy(data, 0);
|
||||
right.copy(data, 32);
|
||||
|
||||
return digest.hash256(data);
|
||||
return digest.root256(left, right);
|
||||
};
|
||||
|
||||
let traverse = (height, pos, leaves, matches) => {
|
||||
|
||||
@ -451,7 +451,7 @@ TX.prototype.signatureHashV0 = function signatureHashV0(index, prev, type) {
|
||||
// Bitcoind used to return 1 as an error code:
|
||||
// it ended up being treated like a hash.
|
||||
if (index >= this.outputs.length)
|
||||
return util.copy(encoding.ONE_HASH);
|
||||
return Buffer.from(encoding.ONE_HASH);
|
||||
}
|
||||
|
||||
// Remove all code separators.
|
||||
|
||||
@ -131,8 +131,8 @@ SigCache.prototype.verify = function verify(msg, sig, key) {
|
||||
*/
|
||||
|
||||
function SigCacheEntry(sig, key) {
|
||||
this.sig = util.copy(sig);
|
||||
this.key = util.copy(key);
|
||||
this.sig = Buffer.from(sig);
|
||||
this.key = Buffer.from(key);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -16,32 +16,6 @@ const nodeUtil = require('util');
|
||||
|
||||
const util = exports;
|
||||
|
||||
/**
|
||||
* Clone a buffer.
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
util.copy = function copy(data) {
|
||||
let clone = Buffer.allocUnsafe(data.length);
|
||||
data.copy(clone, 0, 0, data.length);
|
||||
return clone;
|
||||
};
|
||||
|
||||
/**
|
||||
* Concatenate two buffers.
|
||||
* @param {Buffer} a
|
||||
* @param {Buffer} b
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
util.concat = function concat(a, b) {
|
||||
let data = Buffer.allocUnsafe(a.length + b.length);
|
||||
a.copy(data, 0);
|
||||
b.copy(data, a.length);
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return hrtime (shim for browser).
|
||||
* @param {Array} time
|
||||
@ -108,6 +82,8 @@ util.revHex = function revHex(data) {
|
||||
let out = '';
|
||||
|
||||
assert(typeof data === 'string');
|
||||
assert(data.length > 0);
|
||||
assert(data.length % 2 === 0);
|
||||
|
||||
for (let i = 0; i < data.length; i += 2)
|
||||
out = data.slice(i, i + 2) + out;
|
||||
@ -769,15 +745,6 @@ util.binaryRemove = function binaryRemove(items, item, compare) {
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ensure hidden-class mode for object.
|
||||
* @param {Object} obj
|
||||
*/
|
||||
|
||||
util.fastProp = function fastProp(obj) {
|
||||
({ __proto__: obj });
|
||||
};
|
||||
|
||||
/**
|
||||
* Quick test to see if a string is uppercase.
|
||||
* @param {String} str
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
"n64": "0.0.11"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"bcoin-native": "0.0.20",
|
||||
"bcoin-native": "0.0.21",
|
||||
"leveldown": "1.7.0-0",
|
||||
"secp256k1": "3.2.5",
|
||||
"socket.io": "2.0.1",
|
||||
|
||||
@ -12,7 +12,6 @@ const MTX = require('../lib/primitives/mtx');
|
||||
const MemWallet = require('./util/memwallet');
|
||||
const Network = require('../lib/protocol/network');
|
||||
const Output = require('../lib/primitives/output');
|
||||
const util = require('../lib/utils/util');
|
||||
const common = require('../lib/blockchain/common');
|
||||
const opcodes = Script.opcodes;
|
||||
|
||||
@ -547,7 +546,7 @@ describe('Chain', function() {
|
||||
|
||||
assert(output.script.isCommitment());
|
||||
|
||||
commit = util.copy(output.script.get(1));
|
||||
commit = Buffer.from(output.script.get(1));
|
||||
commit.fill(0, 10);
|
||||
output.script.set(1, commit);
|
||||
output.script.compile();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user