refactor: crypto.
This commit is contained in:
parent
63e6a97de3
commit
d4cc22e1c5
@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
var Address = require('../lib/primitives/address');
|
||||
var crypto = require('../lib/crypto/crypto');
|
||||
var random = require('../lib/crypto/random');
|
||||
var bench = require('./bench');
|
||||
|
||||
var i, end, addr;
|
||||
@ -10,7 +10,7 @@ var addrs = [];
|
||||
|
||||
end = bench('serialize');
|
||||
for (i = 0; i < 100000; i++) {
|
||||
addr = Address.fromProgram(0, crypto.randomBytes(20));
|
||||
addr = Address.fromProgram(0, random.randomBytes(20));
|
||||
addrs.push(addr.toBech32());
|
||||
}
|
||||
end(i);
|
||||
|
||||
@ -1,13 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
var chachapoly = require('../lib/crypto/chachapoly');
|
||||
var crypto = require('../lib/crypto/crypto');
|
||||
var ChaCha20 = require('../lib/crypto/chacha20');
|
||||
var Poly1305 = require('../lib/crypto/poly1305');
|
||||
var digest = require('../lib/crypto/digest');
|
||||
var bench = require('./bench');
|
||||
var i, chacha, iv, poly, key, data, end;
|
||||
|
||||
console.log('note: rate measured in kb/s');
|
||||
|
||||
chacha = new chachapoly.ChaCha20();
|
||||
chacha = new ChaCha20();
|
||||
key = Buffer.allocUnsafe(32);
|
||||
key.fill(2);
|
||||
iv = Buffer.from('0102030405060708', 'hex');
|
||||
@ -20,7 +21,7 @@ for (i = 0; i < 1000000; i++)
|
||||
chacha.encrypt(data);
|
||||
end(i * 32 / 1024);
|
||||
|
||||
poly = new chachapoly.Poly1305();
|
||||
poly = new Poly1305();
|
||||
key = Buffer.allocUnsafe(32);
|
||||
key.fill(2);
|
||||
poly.init(key);
|
||||
@ -45,5 +46,5 @@ end(i * 32 / 1024);
|
||||
// For reference:
|
||||
end = bench('sha256');
|
||||
for (i = 0; i < 1000000; i++)
|
||||
crypto.hash256(data);
|
||||
digest.hash256(data);
|
||||
end(i * 32 / 1024);
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var crypto = require('../lib/crypto/crypto');
|
||||
var random = require('../lib/crypto/random');
|
||||
var Script = require('../lib/script/script');
|
||||
var bench = require('./bench');
|
||||
var opcodes = Script.opcodes;
|
||||
@ -24,7 +24,7 @@ Script.fromPubkeyhashOld = function fromScripthash(hash) {
|
||||
|
||||
hashes = [];
|
||||
for (i = 0; i < 100000; i++)
|
||||
hashes.push(crypto.randomBytes(20));
|
||||
hashes.push(random.randomBytes(20));
|
||||
|
||||
end = bench('old');
|
||||
for (i = 0; i < hashes.length; i++)
|
||||
|
||||
@ -9,7 +9,7 @@ var MTX = require('../lib/primitives/mtx');
|
||||
var Coin = require('../lib/primitives/coin');
|
||||
var CoinView = require('../lib/coins/coinview');
|
||||
var encoding = require('../lib/utils/encoding');
|
||||
var crypto = require('../lib/crypto/crypto');
|
||||
var random = require('../lib/crypto/random');
|
||||
var bench = require('./bench');
|
||||
|
||||
var json = require('../test/data/block300025.json');
|
||||
@ -117,11 +117,11 @@ for (i = 0; i < 100; i++) {
|
||||
},
|
||||
script: [
|
||||
Buffer.allocUnsafe(9),
|
||||
crypto.randomBytes(33)
|
||||
random.randomBytes(33)
|
||||
]
|
||||
});
|
||||
tx.addOutput({
|
||||
address: Address.fromHash(crypto.randomBytes(20)),
|
||||
address: Address.fromHash(random.randomBytes(20)),
|
||||
value: 0
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
var bench = require('./bench');
|
||||
var crypto = require('../lib/crypto/crypto');
|
||||
var random = require('../lib/crypto/random');
|
||||
var WalletDB = require('../lib/wallet/walletdb');
|
||||
var MTX = require('../lib/primitives/mtx');
|
||||
var Outpoint = require('../lib/primitives/outpoint');
|
||||
var walletdb;
|
||||
|
||||
function dummy() {
|
||||
var hash = crypto.randomBytes(32).toString('hex');
|
||||
var hash = random.randomBytes(32).toString('hex');
|
||||
return new Outpoint(hash, 0);
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ var net = require('net');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var IOServer = require('socket.io');
|
||||
var util = require('../lib/utils/util');
|
||||
var crypto = require('../lib/crypto/crypto');
|
||||
var digest = require('../lib/crypto/digest');
|
||||
var IP = require('../lib/utils/ip');
|
||||
var BufferWriter = require('../lib/utils/writer');
|
||||
|
||||
@ -100,7 +100,7 @@ WSProxy.prototype._handleConnect = function _handleConnect(ws, port, host, nonce
|
||||
pow.writeString(host, 'ascii');
|
||||
pow = pow.render();
|
||||
|
||||
if (crypto.hash256(pow).compare(this.target) > 0) {
|
||||
if (digest.hash256(pow).compare(this.target) > 0) {
|
||||
this.log('Client did not solve proof of work (%s).', state.host);
|
||||
ws.emit('tcp close');
|
||||
ws.disconnect();
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
var crypto = require('bcoin/lib/crypto/crypto');
|
||||
var random = require('bcoin/lib/crypto/random');
|
||||
var WalletDB = require('bcoin/lib/wallet/walletdb');
|
||||
var MTX = require('bcoin/lib/primitives/mtx');
|
||||
var Outpoint = require('bcoin/lib/primitives/outpoint');
|
||||
var walletdb;
|
||||
|
||||
function dummy() {
|
||||
var hash = crypto.randomBytes(32).toString('hex');
|
||||
var hash = random.randomBytes(32).toString('hex');
|
||||
return new Outpoint(hash, 0);
|
||||
}
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
var assert = require('assert');
|
||||
var util = require('../utils/util');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var x509 = require('./x509');
|
||||
var PEM = require('../utils/pem');
|
||||
var protobuf = require('../utils/protobuf');
|
||||
@ -195,7 +195,7 @@ PaymentRequest.prototype.signatureData = function signatureData() {
|
||||
|
||||
PaymentRequest.prototype.signatureHash = function signatureHash() {
|
||||
var alg = this.getAlgorithm();
|
||||
return crypto.hash(alg.hash, this.signatureData());
|
||||
return digest.hash(alg.hash, this.signatureData());
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -10,7 +10,7 @@ var assert = require('assert');
|
||||
var ASN1 = require('../utils/asn1');
|
||||
var PEM = require('../utils/pem');
|
||||
var util = require('../utils/util');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var pk = require('./pk');
|
||||
var certs = require('./certs');
|
||||
|
||||
@ -127,7 +127,7 @@ x509.getCAName = function getCAName(cert) {
|
||||
*/
|
||||
|
||||
x509.isTrusted = function isTrusted(cert) {
|
||||
var fingerprint = crypto.sha256(cert.raw);
|
||||
var fingerprint = digest.sha256(cert.raw);
|
||||
var hash = fingerprint.toString('hex');
|
||||
return x509.trusted[hash] === true;
|
||||
};
|
||||
@ -155,7 +155,7 @@ x509.setTrust = function setTrust(certs) {
|
||||
|
||||
cert = x509.parse(cert);
|
||||
|
||||
hash = crypto.sha256(cert.raw);
|
||||
hash = digest.sha256(cert.raw);
|
||||
hash = hash.toString('hex');
|
||||
|
||||
x509.trusted[hash] = true;
|
||||
|
||||
@ -11,7 +11,7 @@ var assert = require('assert');
|
||||
var BN = require('../crypto/bn');
|
||||
var consensus = require('../protocol/consensus');
|
||||
var util = require('../utils/util');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var encoding = require('../utils/encoding');
|
||||
var BufferReader = require('../utils/reader');
|
||||
var StaticWriter = require('../utils/staticwriter');
|
||||
@ -405,7 +405,7 @@ ChainEntry.prototype.toRaw = function toRaw() {
|
||||
|
||||
ChainEntry.prototype.fromRaw = function fromRaw(data) {
|
||||
var br = new BufferReader(data, true);
|
||||
var hash = crypto.hash256(br.readBytes(80));
|
||||
var hash = digest.hash256(br.readBytes(80));
|
||||
|
||||
br.seek(-80);
|
||||
|
||||
|
||||
174
lib/crypto/aead.js
Normal file
174
lib/crypto/aead.js
Normal file
@ -0,0 +1,174 @@
|
||||
/*!
|
||||
* aead.js - aead for bcoin
|
||||
* Copyright (c) 2016-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var ChaCha20 = require('./chacha20');
|
||||
var Poly1305 = require('./poly1305');
|
||||
|
||||
/**
|
||||
* AEAD (used for bip151)
|
||||
* @alias module:crypto.AEAD
|
||||
* @constructor
|
||||
* @see https://github.com/openssh/openssh-portable
|
||||
* @see https://tools.ietf.org/html/rfc7539#section-2.8
|
||||
*/
|
||||
|
||||
function AEAD() {
|
||||
if (!(this instanceof AEAD))
|
||||
return new AEAD();
|
||||
|
||||
this.chacha20 = new ChaCha20();
|
||||
this.poly1305 = new Poly1305();
|
||||
this.aadLen = 0;
|
||||
this.cipherLen = 0;
|
||||
this.polyKey = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the AEAD with a key and iv.
|
||||
* @param {Buffer} key
|
||||
* @param {Buffer} iv - IV / packet sequence number.
|
||||
*/
|
||||
|
||||
AEAD.prototype.init = function init(key, iv) {
|
||||
var polyKey = Buffer.allocUnsafe(32);
|
||||
polyKey.fill(0);
|
||||
|
||||
this.chacha20.init(key, iv);
|
||||
this.chacha20.encrypt(polyKey);
|
||||
this.poly1305.init(polyKey);
|
||||
|
||||
// We need to encrypt a full block
|
||||
// to get the cipher in the correct state.
|
||||
this.chacha20.encrypt(Buffer.allocUnsafe(32));
|
||||
|
||||
// Counter should be one.
|
||||
assert(this.chacha20.getCounter() === 1);
|
||||
|
||||
// Expose for debugging.
|
||||
this.polyKey = polyKey;
|
||||
|
||||
this.aadLen = 0;
|
||||
this.cipherLen = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the aad (will be finalized
|
||||
* on an encrypt/decrypt call).
|
||||
* @param {Buffer} aad
|
||||
*/
|
||||
|
||||
AEAD.prototype.aad = function _aad(aad) {
|
||||
assert(this.cipherLen === 0, 'Cannot update aad.');
|
||||
this.poly1305.update(aad);
|
||||
this.aadLen += aad.length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Encrypt a piece of data.
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
AEAD.prototype.encrypt = function encrypt(data) {
|
||||
if (this.cipherLen === 0)
|
||||
this.pad16(this.aadLen);
|
||||
|
||||
this.chacha20.encrypt(data);
|
||||
this.poly1305.update(data);
|
||||
this.cipherLen += data.length;
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decrypt a piece of data.
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
AEAD.prototype.decrypt = function decrypt(data) {
|
||||
if (this.cipherLen === 0)
|
||||
this.pad16(this.aadLen);
|
||||
|
||||
this.cipherLen += data.length;
|
||||
this.poly1305.update(data);
|
||||
this.chacha20.encrypt(data);
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Authenticate data without decrypting.
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
AEAD.prototype.auth = function auth(data) {
|
||||
if (this.cipherLen === 0)
|
||||
this.pad16(this.aadLen);
|
||||
|
||||
this.cipherLen += data.length;
|
||||
this.poly1305.update(data);
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Finalize the aead and generate a MAC.
|
||||
* @returns {Buffer} MAC
|
||||
*/
|
||||
|
||||
AEAD.prototype.finish = function finish() {
|
||||
var len = Buffer.allocUnsafe(16);
|
||||
var lo, hi;
|
||||
|
||||
// The RFC says these are supposed to be
|
||||
// uint32le, but their own fucking test
|
||||
// cases fail unless they are uint64le's.
|
||||
lo = this.aadLen % 0x100000000;
|
||||
hi = (this.aadLen - lo) / 0x100000000;
|
||||
len.writeUInt32LE(lo, 0, true);
|
||||
len.writeUInt32LE(hi, 4, true);
|
||||
|
||||
lo = this.cipherLen % 0x100000000;
|
||||
hi = (this.cipherLen - lo) / 0x100000000;
|
||||
len.writeUInt32LE(lo, 8, true);
|
||||
len.writeUInt32LE(hi, 12, true);
|
||||
|
||||
if (this.cipherLen === 0)
|
||||
this.pad16(this.aadLen);
|
||||
|
||||
this.pad16(this.cipherLen);
|
||||
this.poly1305.update(len);
|
||||
|
||||
return this.poly1305.finish();
|
||||
};
|
||||
|
||||
/**
|
||||
* Pad a chunk before updating mac.
|
||||
* @private
|
||||
* @param {Number} size
|
||||
*/
|
||||
|
||||
AEAD.prototype.pad16 = function pad16(size) {
|
||||
var pad;
|
||||
|
||||
size %= 16;
|
||||
|
||||
if (size === 0)
|
||||
return;
|
||||
|
||||
pad = Buffer.allocUnsafe(16 - size);
|
||||
pad.fill(0);
|
||||
|
||||
this.poly1305.update(pad);
|
||||
};
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
module.exports = AEAD;
|
||||
1329
lib/crypto/aes-browser.js
Normal file
1329
lib/crypto/aes-browser.js
Normal file
File diff suppressed because it is too large
Load Diff
1367
lib/crypto/aes.js
1367
lib/crypto/aes.js
File diff suppressed because it is too large
Load Diff
@ -1,177 +0,0 @@
|
||||
/*!
|
||||
* backend-browser.js - browser crypto backend for bcoin
|
||||
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var hashjs = require('hash.js');
|
||||
var aes = require('./aes');
|
||||
var sha256 = require('./sha256');
|
||||
var crypto = global.crypto || global.msCrypto || {};
|
||||
var subtle = crypto.subtle && crypto.subtle.importKey ? crypto.subtle : {};
|
||||
var backend = exports;
|
||||
|
||||
/*
|
||||
* Hashing
|
||||
*/
|
||||
|
||||
backend.hash = function hash(alg, data) {
|
||||
var hash;
|
||||
|
||||
if (alg === 'sha256')
|
||||
return sha256.digest(data);
|
||||
|
||||
hash = hashjs[alg];
|
||||
|
||||
assert(hash != null, 'Unknown algorithm.');
|
||||
|
||||
return Buffer.from(hash().update(data).digest());
|
||||
};
|
||||
|
||||
backend.ripemd160 = function ripemd160(data) {
|
||||
return backend.hash('ripemd160', data);
|
||||
};
|
||||
|
||||
backend.sha1 = function sha1(data) {
|
||||
return backend.hash('sha1', data);
|
||||
};
|
||||
|
||||
backend.sha256 = function _sha256(data) {
|
||||
return sha256.digest(data);
|
||||
};
|
||||
|
||||
backend.hash160 = function hash160(data) {
|
||||
return backend.hash('ripemd160', sha256.digest(data));
|
||||
};
|
||||
|
||||
backend.hash256 = function hash256(data) {
|
||||
return sha256.hash256(data);
|
||||
};
|
||||
|
||||
backend.hmac = function _hmac(alg, data, key) {
|
||||
var hash = hashjs[alg];
|
||||
var hmac;
|
||||
|
||||
assert(hash != null, 'Unknown algorithm.');
|
||||
|
||||
hmac = hashjs.hmac(hash, key);
|
||||
|
||||
return Buffer.from(hmac.update(data).digest());
|
||||
};
|
||||
|
||||
/*
|
||||
* Key Derivation
|
||||
*/
|
||||
|
||||
backend.pbkdf2 = function pbkdf2(key, salt, iter, len, alg) {
|
||||
var size = backend.hash(alg, Buffer.alloc(0)).length;
|
||||
var blocks = Math.ceil(len / size);
|
||||
var out = Buffer.allocUnsafe(len);
|
||||
var buf = Buffer.allocUnsafe(salt.length + 4);
|
||||
var block = Buffer.allocUnsafe(size);
|
||||
var pos = 0;
|
||||
var i, j, k, mac;
|
||||
|
||||
salt.copy(buf, 0);
|
||||
|
||||
for (i = 0; i < blocks; i++) {
|
||||
buf.writeUInt32BE(i + 1, salt.length, true);
|
||||
mac = backend.hmac(alg, buf, key);
|
||||
mac.copy(block, 0);
|
||||
for (j = 1; j < iter; j++) {
|
||||
mac = backend.hmac(alg, mac, key);
|
||||
for (k = 0; k < size; k++)
|
||||
block[k] ^= mac[k];
|
||||
}
|
||||
block.copy(out, pos);
|
||||
pos += size;
|
||||
}
|
||||
|
||||
return out;
|
||||
};
|
||||
|
||||
backend.pbkdf2Async = function pbkdf2Async(key, salt, iter, len, alg) {
|
||||
var algo = { name: 'PBKDF2' };
|
||||
var use = ['deriveBits'];
|
||||
var name = backend.getHash(alg);
|
||||
var length = len * 8;
|
||||
var options, promise;
|
||||
|
||||
options = {
|
||||
name: 'PBKDF2',
|
||||
salt: salt,
|
||||
iterations: iter,
|
||||
hash: name
|
||||
};
|
||||
|
||||
promise = subtle.importKey('raw', key, algo, false, use);
|
||||
|
||||
return promise.then(function(key) {
|
||||
return subtle.deriveBits(options, key, length);
|
||||
}).then(function(result) {
|
||||
return Buffer.from(result);
|
||||
});
|
||||
};
|
||||
|
||||
if (!subtle.deriveBits)
|
||||
backend.pbkdf2Async = backend.pbkdf2;
|
||||
|
||||
/*
|
||||
* Ciphers
|
||||
*/
|
||||
|
||||
backend.encipher = function encipher(data, key, iv) {
|
||||
return aes.cbc.encrypt(data, key, iv);
|
||||
};
|
||||
|
||||
backend.decipher = function decipher(data, key, iv) {
|
||||
try {
|
||||
return aes.cbc.decrypt(data, key, iv);
|
||||
} catch (e) {
|
||||
throw new Error('Bad key for decryption.');
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Misc
|
||||
*/
|
||||
|
||||
backend.randomBytes = function randomBytes(n) {
|
||||
var data = new Uint8Array(n);
|
||||
crypto.getRandomValues(data);
|
||||
return Buffer.from(data.buffer);
|
||||
};
|
||||
|
||||
if (!crypto.getRandomValues) {
|
||||
// Out of luck here. Use bad randomness for now.
|
||||
backend.randomBytes = function randomBytes(n) {
|
||||
var data = Buffer.allocUnsafe(n);
|
||||
var i;
|
||||
|
||||
for (i = 0; i < data.length; i++)
|
||||
data[i] = Math.floor(Math.random() * 256);
|
||||
|
||||
return data;
|
||||
};
|
||||
}
|
||||
|
||||
backend.getHash = function getHash(name) {
|
||||
switch (name) {
|
||||
case 'sha1':
|
||||
return 'SHA-1';
|
||||
case 'sha256':
|
||||
return 'SHA-256';
|
||||
case 'sha384':
|
||||
return 'SHA-384';
|
||||
case 'sha512':
|
||||
return 'SHA-512';
|
||||
default:
|
||||
throw new Error('Algorithm not supported: ' + name);
|
||||
}
|
||||
};
|
||||
|
||||
backend.crypto = crypto;
|
||||
backend.subtle = subtle;
|
||||
@ -1,102 +0,0 @@
|
||||
/*!
|
||||
* backend.js - crypto backend for bcoin
|
||||
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var util = require('../utils/util');
|
||||
var co = require('../utils/co');
|
||||
var crypto = require('crypto');
|
||||
var native = require('../utils/native').binding;
|
||||
var backend = exports;
|
||||
|
||||
if (!crypto.pbkdf2Sync)
|
||||
throw new Error('This modules requires node.js v0.11.0 or above.');
|
||||
|
||||
/*
|
||||
* Hashing
|
||||
*/
|
||||
|
||||
backend.hash = function hash(alg, data) {
|
||||
return crypto.createHash(alg).update(data).digest();
|
||||
};
|
||||
|
||||
backend.ripemd160 = function ripemd160(data) {
|
||||
return backend.hash('ripemd160', data);
|
||||
};
|
||||
|
||||
backend.sha1 = function sha1(data) {
|
||||
return backend.hash('sha1', data);
|
||||
};
|
||||
|
||||
backend.sha256 = function sha256(data) {
|
||||
return backend.hash('sha256', data);
|
||||
};
|
||||
|
||||
backend.hash160 = function hash160(data) {
|
||||
return backend.ripemd160(backend.sha256(data));
|
||||
};
|
||||
|
||||
backend.hash256 = function hash256(data) {
|
||||
return backend.sha256(backend.sha256(data));
|
||||
};
|
||||
|
||||
backend.hmac = function hmac(alg, data, key) {
|
||||
var hmac = crypto.createHmac(alg, key);
|
||||
return hmac.update(data).digest();
|
||||
};
|
||||
|
||||
if (native) {
|
||||
backend.hash = native.hash;
|
||||
backend.hmac = native.hmac;
|
||||
backend.ripemd160 = native.ripemd160;
|
||||
backend.sha1 = native.sha1;
|
||||
backend.sha256 = native.sha256;
|
||||
backend.hash160 = native.hash160;
|
||||
backend.hash256 = native.hash256;
|
||||
}
|
||||
|
||||
/*
|
||||
* Key Derivation
|
||||
*/
|
||||
|
||||
backend.pbkdf2 = function pbkdf2(key, salt, iter, len, alg) {
|
||||
return crypto.pbkdf2Sync(key, salt, iter, len, alg);
|
||||
};
|
||||
|
||||
backend.pbkdf2Async = function pbkdf2Async(key, salt, iter, len, alg) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
crypto.pbkdf2(key, salt, iter, len, alg, co.wrap(resolve, reject));
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* Ciphers
|
||||
*/
|
||||
|
||||
backend.encipher = function encipher(data, key, iv) {
|
||||
var cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
|
||||
return util.concat(cipher.update(data), cipher.final());
|
||||
};
|
||||
|
||||
backend.decipher = function decipher(data, key, iv) {
|
||||
var decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
|
||||
try {
|
||||
return util.concat(decipher.update(data), decipher.final());
|
||||
} catch (e) {
|
||||
throw new Error('Bad key for decryption.');
|
||||
}
|
||||
};
|
||||
|
||||
if (native) {
|
||||
backend.encipher = native.encipher;
|
||||
backend.decipher = native.decipher;
|
||||
}
|
||||
|
||||
/*
|
||||
* Misc
|
||||
*/
|
||||
|
||||
backend.randomBytes = crypto.randomBytes;
|
||||
@ -6,4 +6,14 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @module crypto.BN
|
||||
*/
|
||||
|
||||
/**
|
||||
* bn.js
|
||||
* @constructor
|
||||
* @see https://github.com/indutny/bn.js
|
||||
*/
|
||||
|
||||
module.exports = require('bn.js');
|
||||
|
||||
39
lib/crypto/ccmp.js
Normal file
39
lib/crypto/ccmp.js
Normal file
@ -0,0 +1,39 @@
|
||||
/*!
|
||||
* ccmp.js - constant-time compare for bcoin
|
||||
* Copyright (c) 2016-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* memcmp in constant time (can only return true or false).
|
||||
* This protects us against timing attacks when
|
||||
* comparing an input against a secret string.
|
||||
* @alias module:crypto.ccmp
|
||||
* @see https://cryptocoding.net/index.php/Coding_rules
|
||||
* @see `$ man 3 memcmp` (NetBSD's consttime_memequal)
|
||||
* @param {Buffer} a
|
||||
* @param {Buffer} b
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
module.exports = function ccmp(a, b) {
|
||||
var i, res;
|
||||
|
||||
if (!Buffer.isBuffer(a))
|
||||
return false;
|
||||
|
||||
if (!Buffer.isBuffer(b))
|
||||
return false;
|
||||
|
||||
if (b.length === 0)
|
||||
return a.length === 0;
|
||||
|
||||
res = a.length ^ b.length;
|
||||
|
||||
for (i = 0; i < a.length; i++)
|
||||
res |= a[i] ^ b[i % b.length];
|
||||
|
||||
return res === 0;
|
||||
};
|
||||
209
lib/crypto/chacha20.js
Normal file
209
lib/crypto/chacha20.js
Normal file
@ -0,0 +1,209 @@
|
||||
/*!
|
||||
* chacha20.js - chacha20 for bcoin
|
||||
* Copyright (c) 2016-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var native = require('../utils/native').binding;
|
||||
|
||||
var BIG_ENDIAN = new Int8Array(new Int16Array([1]).buffer)[0] === 0;
|
||||
|
||||
/**
|
||||
* ChaCha20 (used for bip151)
|
||||
* @alias module:crypto.ChaCha20
|
||||
* @constructor
|
||||
* @see https://tools.ietf.org/html/rfc7539#section-2
|
||||
*/
|
||||
|
||||
function ChaCha20() {
|
||||
if (!(this instanceof ChaCha20))
|
||||
return new ChaCha20();
|
||||
|
||||
this.state = new Uint32Array(16);
|
||||
this.stream = new Uint32Array(16);
|
||||
this.bytes = new Uint8Array(this.stream.buffer);
|
||||
|
||||
if (BIG_ENDIAN)
|
||||
this.bytes = Buffer.allocUnsafe(64);
|
||||
|
||||
this.pos = 0;
|
||||
this.ivSize = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize chacha20 with a key, iv, and counter.
|
||||
* @param {Buffer} key
|
||||
* @param {Buffer} iv
|
||||
* @param {Number} counter
|
||||
*/
|
||||
|
||||
ChaCha20.prototype.init = function init(key, iv, counter) {
|
||||
if (key)
|
||||
this.initKey(key);
|
||||
|
||||
if (iv)
|
||||
this.initIV(iv, counter);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set key.
|
||||
* @param {Buffer} key
|
||||
*/
|
||||
|
||||
ChaCha20.prototype.initKey = function initKey(key) {
|
||||
this.state[0] = 0x61707865;
|
||||
this.state[1] = 0x3320646e;
|
||||
this.state[2] = 0x79622d32;
|
||||
this.state[3] = 0x6b206574;
|
||||
|
||||
this.state[4] = key.readUInt32LE(0, true);
|
||||
this.state[5] = key.readUInt32LE(4, true);
|
||||
this.state[6] = key.readUInt32LE(8, true);
|
||||
this.state[7] = key.readUInt32LE(12, true);
|
||||
this.state[8] = key.readUInt32LE(16, true);
|
||||
this.state[9] = key.readUInt32LE(20, true);
|
||||
this.state[10] = key.readUInt32LE(24, true);
|
||||
this.state[11] = key.readUInt32LE(28, true);
|
||||
|
||||
this.state[12] = 0;
|
||||
|
||||
this.pos = 0xffffffff;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set IV and counter.
|
||||
* @param {Buffer} iv
|
||||
* @param {Number} counter
|
||||
*/
|
||||
|
||||
ChaCha20.prototype.initIV = function initIV(iv, counter) {
|
||||
if (iv.length === 8) {
|
||||
this.state[13] = 0;
|
||||
this.state[14] = iv.readUInt32LE(0, true);
|
||||
this.state[15] = iv.readUInt32LE(4, true);
|
||||
} else if (iv.length === 12) {
|
||||
this.state[13] = iv.readUInt32LE(0, true);
|
||||
this.state[14] = iv.readUInt32LE(4, true);
|
||||
this.state[15] = iv.readUInt32LE(8, true);
|
||||
} else {
|
||||
assert(false, 'Bad iv size.');
|
||||
}
|
||||
|
||||
this.ivSize = iv.length * 8;
|
||||
|
||||
this.setCounter(counter);
|
||||
};
|
||||
|
||||
/**
|
||||
* Encrypt/decrypt data.
|
||||
* @param {Buffer} data - Will be mutated.
|
||||
*/
|
||||
|
||||
ChaCha20.prototype.encrypt = function encrypt(data) {
|
||||
var i, j;
|
||||
|
||||
for (i = 0; i < data.length; i++) {
|
||||
if (this.pos >= 64) {
|
||||
for (j = 0; j < 16; j++)
|
||||
this.stream[j] = this.state[j];
|
||||
|
||||
for (j = 0; j < 10; j++) {
|
||||
qround(this.stream, 0, 4, 8, 12);
|
||||
qround(this.stream, 1, 5, 9, 13);
|
||||
qround(this.stream, 2, 6, 10, 14);
|
||||
qround(this.stream, 3, 7, 11, 15);
|
||||
qround(this.stream, 0, 5, 10, 15);
|
||||
qround(this.stream, 1, 6, 11, 12);
|
||||
qround(this.stream, 2, 7, 8, 13);
|
||||
qround(this.stream, 3, 4, 9, 14);
|
||||
}
|
||||
|
||||
for (j = 0; j < 16; j++) {
|
||||
this.stream[j] += this.state[j];
|
||||
if (BIG_ENDIAN)
|
||||
this.bytes.writeUInt32LE(this.stream[j], j * 4, true);
|
||||
}
|
||||
|
||||
this.state[12]++;
|
||||
|
||||
if (this.state[12] === 0) {
|
||||
assert(this.ivSize === 64, 'Counter overflow.');
|
||||
this.state[13]++;
|
||||
assert(this.state[13] !== 0, 'Counter overflow.');
|
||||
}
|
||||
|
||||
this.pos = 0;
|
||||
}
|
||||
|
||||
data[i] ^= this.bytes[this.pos++];
|
||||
}
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Artificially set the counter.
|
||||
* @param {Number} counter
|
||||
*/
|
||||
|
||||
ChaCha20.prototype.setCounter = function setCounter(counter) {
|
||||
var lo, hi;
|
||||
|
||||
if (!counter)
|
||||
counter = 0;
|
||||
|
||||
lo = counter % 0x100000000;
|
||||
hi = (counter - lo) / 0x100000000;
|
||||
|
||||
this.state[12] = lo;
|
||||
|
||||
if (this.ivSize === 64)
|
||||
this.state[13] = hi;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the counter as a uint64.
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
ChaCha20.prototype.getCounter = function getCounter() {
|
||||
var lo = this.state[12];
|
||||
var hi = this.state[13];
|
||||
if (this.ivSize === 64)
|
||||
return hi * 0x100000000 + lo;
|
||||
return lo;
|
||||
};
|
||||
|
||||
if (native)
|
||||
ChaCha20 = native.ChaCha20;
|
||||
|
||||
/*
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function qround(x, a, b, c, d) {
|
||||
x[a] += x[b];
|
||||
x[d] = rotl32(x[d] ^ x[a], 16);
|
||||
|
||||
x[c] += x[d];
|
||||
x[b] = rotl32(x[b] ^ x[c], 12);
|
||||
|
||||
x[a] += x[b];
|
||||
x[d] = rotl32(x[d] ^ x[a], 8);
|
||||
|
||||
x[c] += x[d];
|
||||
x[b] = rotl32(x[b] ^ x[c], 7);
|
||||
}
|
||||
|
||||
function rotl32(w, b) {
|
||||
return (w << b) | (w >>> (32 - b));
|
||||
}
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
module.exports = ChaCha20;
|
||||
@ -1,667 +0,0 @@
|
||||
/*!
|
||||
* chachapoly.js - chacha20/poly1305 for bcoin
|
||||
* Copyright (c) 2016-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var native = require('../utils/native').binding;
|
||||
|
||||
var BIG_ENDIAN = new Int8Array(new Int16Array([1]).buffer)[0] === 0;
|
||||
|
||||
/**
|
||||
* @module crypto/chachapoly
|
||||
*/
|
||||
|
||||
/**
|
||||
* ChaCha20 (used for bip151)
|
||||
* @see https://tools.ietf.org/html/rfc7539#section-2
|
||||
* @alias module:crypto/chachapoly.ChaCha20
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
function ChaCha20() {
|
||||
if (!(this instanceof ChaCha20))
|
||||
return new ChaCha20();
|
||||
|
||||
this.state = new Uint32Array(16);
|
||||
this.stream = new Uint32Array(16);
|
||||
this.bytes = new Uint8Array(this.stream.buffer);
|
||||
|
||||
if (BIG_ENDIAN)
|
||||
this.bytes = Buffer.allocUnsafe(64);
|
||||
|
||||
this.pos = 0;
|
||||
this.ivSize = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize chacha20 with a key, iv, and counter.
|
||||
* @param {Buffer} key
|
||||
* @param {Buffer} iv
|
||||
* @param {Number} counter
|
||||
*/
|
||||
|
||||
ChaCha20.prototype.init = function init(key, iv, counter) {
|
||||
if (key)
|
||||
this.initKey(key);
|
||||
|
||||
if (iv)
|
||||
this.initIV(iv, counter);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set key.
|
||||
* @param {Buffer} key
|
||||
*/
|
||||
|
||||
ChaCha20.prototype.initKey = function initKey(key) {
|
||||
this.state[0] = 0x61707865;
|
||||
this.state[1] = 0x3320646e;
|
||||
this.state[2] = 0x79622d32;
|
||||
this.state[3] = 0x6b206574;
|
||||
|
||||
this.state[4] = key.readUInt32LE(0, true);
|
||||
this.state[5] = key.readUInt32LE(4, true);
|
||||
this.state[6] = key.readUInt32LE(8, true);
|
||||
this.state[7] = key.readUInt32LE(12, true);
|
||||
this.state[8] = key.readUInt32LE(16, true);
|
||||
this.state[9] = key.readUInt32LE(20, true);
|
||||
this.state[10] = key.readUInt32LE(24, true);
|
||||
this.state[11] = key.readUInt32LE(28, true);
|
||||
|
||||
this.state[12] = 0;
|
||||
|
||||
this.pos = 0xffffffff;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set IV and counter.
|
||||
* @param {Buffer} iv
|
||||
* @param {Number} counter
|
||||
*/
|
||||
|
||||
ChaCha20.prototype.initIV = function initIV(iv, counter) {
|
||||
if (iv.length === 8) {
|
||||
this.state[13] = 0;
|
||||
this.state[14] = iv.readUInt32LE(0, true);
|
||||
this.state[15] = iv.readUInt32LE(4, true);
|
||||
} else if (iv.length === 12) {
|
||||
this.state[13] = iv.readUInt32LE(0, true);
|
||||
this.state[14] = iv.readUInt32LE(4, true);
|
||||
this.state[15] = iv.readUInt32LE(8, true);
|
||||
} else {
|
||||
assert(false, 'Bad iv size.');
|
||||
}
|
||||
|
||||
this.ivSize = iv.length * 8;
|
||||
|
||||
this.setCounter(counter);
|
||||
};
|
||||
|
||||
/**
|
||||
* Encrypt/decrypt data.
|
||||
* @param {Buffer} data - Will be mutated.
|
||||
*/
|
||||
|
||||
ChaCha20.prototype.encrypt = function encrypt(data) {
|
||||
var i, j;
|
||||
|
||||
for (i = 0; i < data.length; i++) {
|
||||
if (this.pos >= 64) {
|
||||
for (j = 0; j < 16; j++)
|
||||
this.stream[j] = this.state[j];
|
||||
|
||||
for (j = 0; j < 10; j++) {
|
||||
qround(this.stream, 0, 4, 8, 12);
|
||||
qround(this.stream, 1, 5, 9, 13);
|
||||
qround(this.stream, 2, 6, 10, 14);
|
||||
qround(this.stream, 3, 7, 11, 15);
|
||||
qround(this.stream, 0, 5, 10, 15);
|
||||
qround(this.stream, 1, 6, 11, 12);
|
||||
qround(this.stream, 2, 7, 8, 13);
|
||||
qround(this.stream, 3, 4, 9, 14);
|
||||
}
|
||||
|
||||
for (j = 0; j < 16; j++) {
|
||||
this.stream[j] += this.state[j];
|
||||
if (BIG_ENDIAN)
|
||||
this.bytes.writeUInt32LE(this.stream[j], j * 4, true);
|
||||
}
|
||||
|
||||
this.state[12]++;
|
||||
|
||||
if (this.state[12] === 0) {
|
||||
assert(this.ivSize === 64, 'Counter overflow.');
|
||||
this.state[13]++;
|
||||
assert(this.state[13] !== 0, 'Counter overflow.');
|
||||
}
|
||||
|
||||
this.pos = 0;
|
||||
}
|
||||
|
||||
data[i] ^= this.bytes[this.pos++];
|
||||
}
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Artificially set the counter.
|
||||
* @param {Number} counter
|
||||
*/
|
||||
|
||||
ChaCha20.prototype.setCounter = function setCounter(counter) {
|
||||
var lo, hi;
|
||||
|
||||
if (!counter)
|
||||
counter = 0;
|
||||
|
||||
lo = counter % 0x100000000;
|
||||
hi = (counter - lo) / 0x100000000;
|
||||
|
||||
this.state[12] = lo;
|
||||
|
||||
if (this.ivSize === 64)
|
||||
this.state[13] = hi;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the counter as a uint64.
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
ChaCha20.prototype.getCounter = function getCounter() {
|
||||
var lo = this.state[12];
|
||||
var hi = this.state[13];
|
||||
if (this.ivSize === 64)
|
||||
return hi * 0x100000000 + lo;
|
||||
return lo;
|
||||
};
|
||||
|
||||
if (native)
|
||||
ChaCha20 = native.ChaCha20;
|
||||
|
||||
/*
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function qround(x, a, b, c, d) {
|
||||
x[a] += x[b];
|
||||
x[d] = rotl32(x[d] ^ x[a], 16);
|
||||
|
||||
x[c] += x[d];
|
||||
x[b] = rotl32(x[b] ^ x[c], 12);
|
||||
|
||||
x[a] += x[b];
|
||||
x[d] = rotl32(x[d] ^ x[a], 8);
|
||||
|
||||
x[c] += x[d];
|
||||
x[b] = rotl32(x[b] ^ x[c], 7);
|
||||
}
|
||||
|
||||
function rotl32(w, b) {
|
||||
return (w << b) | (w >>> (32 - b));
|
||||
}
|
||||
|
||||
/**
|
||||
* Poly1305 (used for bip151)
|
||||
* @see https://github.com/floodyberry/poly1305-donna
|
||||
* @see https://tools.ietf.org/html/rfc7539#section-2.5
|
||||
* @alias module:crypto/chachapoly.Poly1305
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
function Poly1305() {
|
||||
if (!(this instanceof Poly1305))
|
||||
return new Poly1305();
|
||||
|
||||
this.r = new Uint16Array(10);
|
||||
this.h = new Uint16Array(10);
|
||||
this.pad = new Uint16Array(8);
|
||||
this.fin = 0;
|
||||
this.leftover = 0;
|
||||
this.buffer = Buffer.allocUnsafe(16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize poly1305 with a key.
|
||||
* @param {Buffer} key
|
||||
*/
|
||||
|
||||
Poly1305.prototype.init = function init(key) {
|
||||
var t0, t1, t2, t3, t4, t5, t6, t7, i;
|
||||
|
||||
// r &= 0xffffffc0ffffffc0ffffffc0fffffff
|
||||
t0 = key.readUInt16LE(0, true);
|
||||
t1 = key.readUInt16LE(2, true);
|
||||
t2 = key.readUInt16LE(4, true);
|
||||
t3 = key.readUInt16LE(6, true);
|
||||
t4 = key.readUInt16LE(8, true);
|
||||
t5 = key.readUInt16LE(10, true);
|
||||
t6 = key.readUInt16LE(12, true);
|
||||
t7 = key.readUInt16LE(14, true);
|
||||
|
||||
this.r[0] = t0 & 0x1fff;
|
||||
this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff;
|
||||
this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03;
|
||||
this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff;
|
||||
this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff;
|
||||
this.r[5] = (t4 >>> 1) & 0x1ffe;
|
||||
this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff;
|
||||
this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81;
|
||||
this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff;
|
||||
this.r[9] = (t7 >>> 5) & 0x007f;
|
||||
|
||||
// h = 0
|
||||
for (i = 0; i < 10; i++)
|
||||
this.h[i] = 0;
|
||||
|
||||
// save pad for later
|
||||
for (i = 0; i < 8; i++)
|
||||
this.pad[i] = key.readUInt16LE(16 + (2 * i), true);
|
||||
|
||||
this.leftover = 0;
|
||||
this.fin = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Process 16 byte blocks.
|
||||
* @param {Buffer} data - Blocks.
|
||||
* @param {Number} bytes - Size.
|
||||
* @param {Number} m - Offset pointer.
|
||||
*/
|
||||
|
||||
Poly1305.prototype.blocks = function blocks(data, bytes, m) {
|
||||
var hibit = this.fin ? 0 : (1 << 11); // 1 << 128
|
||||
var d = new Uint32Array(10);
|
||||
var i, j, t0, t1, t2, t3, t4, t5, t6, t7, c;
|
||||
|
||||
while (bytes >= 16) {
|
||||
// h += m[i]
|
||||
t0 = data.readUInt16LE(m + 0, true);
|
||||
t1 = data.readUInt16LE(m + 2, true);
|
||||
t2 = data.readUInt16LE(m + 4, true);
|
||||
t3 = data.readUInt16LE(m + 6, true);
|
||||
t4 = data.readUInt16LE(m + 8, true);
|
||||
t5 = data.readUInt16LE(m + 10, true);
|
||||
t6 = data.readUInt16LE(m + 12, true);
|
||||
t7 = data.readUInt16LE(m + 14, true);
|
||||
|
||||
this.h[0] += t0 & 0x1fff;
|
||||
this.h[1] += ((t0 >>> 13) | (t1 << 3)) & 0x1fff;
|
||||
this.h[2] += ((t1 >>> 10) | (t2 << 6)) & 0x1fff;
|
||||
this.h[3] += ((t2 >>> 7) | (t3 << 9)) & 0x1fff;
|
||||
this.h[4] += ((t3 >>> 4) | (t4 << 12)) & 0x1fff;
|
||||
this.h[5] += ((t4 >>> 1)) & 0x1fff;
|
||||
this.h[6] += ((t4 >>> 14) | (t5 << 2)) & 0x1fff;
|
||||
this.h[7] += ((t5 >>> 11) | (t6 << 5)) & 0x1fff;
|
||||
this.h[8] += ((t6 >>> 8) | (t7 << 8)) & 0x1fff;
|
||||
this.h[9] += ((t7 >>> 5)) | hibit;
|
||||
|
||||
// h *= r, (partial) h %= p
|
||||
for (i = 0, c = 0; i < 10; i++) {
|
||||
d[i] = c;
|
||||
for (j = 0; j < 10; j++) {
|
||||
d[i] += this.h[j] * (j <= i
|
||||
? this.r[i - j]
|
||||
: 5 * this.r[i + 10 - j]);
|
||||
// Sum(h[i] * r[i] * 5) will overflow slightly
|
||||
// above 6 products with an unclamped r, so
|
||||
// carry at 5
|
||||
if (j === 4) {
|
||||
c = d[i] >>> 13;
|
||||
d[i] &= 0x1fff;
|
||||
}
|
||||
}
|
||||
c += d[i] >>> 13;
|
||||
d[i] &= 0x1fff;
|
||||
}
|
||||
c = (c << 2) + c; // c *= 5
|
||||
c += d[0];
|
||||
d[0] = (c & 0x1fff);
|
||||
c = c >>> 13;
|
||||
d[1] += c;
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
this.h[i] = d[i];
|
||||
|
||||
m += 16;
|
||||
bytes -= 16;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the MAC with data (will be
|
||||
* processed as 16 byte blocks).
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
Poly1305.prototype.update = function update(data) {
|
||||
var bytes = data.length;
|
||||
var m = 0;
|
||||
var i, want;
|
||||
|
||||
// handle leftover
|
||||
if (this.leftover) {
|
||||
want = 16 - this.leftover;
|
||||
if (want > bytes)
|
||||
want = bytes;
|
||||
for (i = 0; i < want; i++)
|
||||
this.buffer[this.leftover + i] = data[m + i];
|
||||
bytes -= want;
|
||||
m += want;
|
||||
this.leftover += want;
|
||||
if (this.leftover < 16)
|
||||
return;
|
||||
this.blocks(this.buffer, 16, 0);
|
||||
this.leftover = 0;
|
||||
}
|
||||
|
||||
// process full blocks
|
||||
if (bytes >= 16) {
|
||||
want = bytes & ~(16 - 1);
|
||||
this.blocks(data, want, m);
|
||||
m += want;
|
||||
bytes -= want;
|
||||
}
|
||||
|
||||
// store leftover
|
||||
if (bytes) {
|
||||
for (i = 0; i < bytes; i++)
|
||||
this.buffer[this.leftover + i] = data[m + i];
|
||||
this.leftover += bytes;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Finalize and return a 16-byte MAC.
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
Poly1305.prototype.finish = function finish() {
|
||||
var mac = Buffer.allocUnsafe(16);
|
||||
var g = new Uint16Array(10);
|
||||
var c, mask, f, i;
|
||||
|
||||
// process the remaining block
|
||||
if (this.leftover) {
|
||||
i = this.leftover;
|
||||
this.buffer[i++] = 1;
|
||||
for (; i < 16; i++)
|
||||
this.buffer[i] = 0;
|
||||
this.fin = 1;
|
||||
this.blocks(this.buffer, 16, 0);
|
||||
}
|
||||
|
||||
// fully carry h
|
||||
c = this.h[1] >>> 13;
|
||||
this.h[1] &= 0x1fff;
|
||||
for (i = 2; i < 10; i++) {
|
||||
this.h[i] += c;
|
||||
c = this.h[i] >>> 13;
|
||||
this.h[i] &= 0x1fff;
|
||||
}
|
||||
this.h[0] += c * 5;
|
||||
c = this.h[0] >>> 13;
|
||||
this.h[0] &= 0x1fff;
|
||||
this.h[1] += c;
|
||||
c = this.h[1] >>> 13;
|
||||
this.h[1] &= 0x1fff;
|
||||
this.h[2] += c;
|
||||
|
||||
// compute h + -p
|
||||
g[0] = this.h[0] + 5;
|
||||
c = g[0] >>> 13;
|
||||
g[0] &= 0x1fff;
|
||||
for (i = 1; i < 10; i++) {
|
||||
g[i] = this.h[i] + c;
|
||||
c = g[i] >>> 13;
|
||||
g[i] &= 0x1fff;
|
||||
}
|
||||
|
||||
// select h if h < p, or h + -p if h >= p
|
||||
mask = (c ^ 1) - 1;
|
||||
for (i = 0; i < 10; i++)
|
||||
g[i] &= mask;
|
||||
mask = ~mask;
|
||||
for (i = 0; i < 10; i++)
|
||||
this.h[i] = (this.h[i] & mask) | g[i];
|
||||
|
||||
// h = h % (2^128)
|
||||
this.h[0] = ((this.h[0]) | (this.h[1] << 13)) & 0xffff;
|
||||
this.h[1] = ((this.h[1] >>> 3) | (this.h[2] << 10)) & 0xffff;
|
||||
this.h[2] = ((this.h[2] >>> 6) | (this.h[3] << 7)) & 0xffff;
|
||||
this.h[3] = ((this.h[3] >>> 9) | (this.h[4] << 4)) & 0xffff;
|
||||
this.h[4] = ((this.h[4] >>> 12)
|
||||
| (this.h[5] << 1) | (this.h[6] << 14)) & 0xffff;
|
||||
this.h[5] = ((this.h[6] >>> 2) | (this.h[7] << 11)) & 0xffff;
|
||||
this.h[6] = ((this.h[7] >>> 5) | (this.h[8] << 8)) & 0xffff;
|
||||
this.h[7] = ((this.h[8] >>> 8) | (this.h[9] << 5)) & 0xffff;
|
||||
|
||||
// mac = (h + pad) % (2^128)
|
||||
f = this.h[0] + this.pad[0];
|
||||
this.h[0] = f;
|
||||
for (i = 1; i < 8; i++) {
|
||||
f = this.h[i] + this.pad[i] + (f >>> 16);
|
||||
this.h[i] = f;
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
mac.writeUInt16LE(this.h[i], i * 2, true);
|
||||
|
||||
// zero out the state
|
||||
for (i = 0; i < 10; i++)
|
||||
this.h[i] = 0;
|
||||
for (i = 0; i < 10; i++)
|
||||
this.r[i] = 0;
|
||||
for (i = 0; i < 8; i++)
|
||||
this.pad[i] = 0;
|
||||
|
||||
return mac;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a MAC for a message and key.
|
||||
* @param {Buffer} msg
|
||||
* @param {Buffer} key
|
||||
* @returns {Buffer} MAC
|
||||
*/
|
||||
|
||||
Poly1305.auth = function auth(msg, key) {
|
||||
var poly = new Poly1305();
|
||||
poly.init(key);
|
||||
poly.update(msg);
|
||||
return poly.finish();
|
||||
};
|
||||
|
||||
/**
|
||||
* Compare two MACs in constant time.
|
||||
* @param {Buffer} mac1
|
||||
* @param {Buffer} mac2
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
Poly1305.verify = function verify(mac1, mac2) {
|
||||
var dif = 0;
|
||||
var i;
|
||||
|
||||
// Compare in constant time.
|
||||
for (i = 0; i < 16; i++)
|
||||
dif |= mac1[i] ^ mac2[i];
|
||||
|
||||
dif = (dif - 1) >>> 31;
|
||||
|
||||
return (dif & 1) !== 0;
|
||||
};
|
||||
|
||||
if (native)
|
||||
Poly1305 = native.Poly1305;
|
||||
|
||||
/**
|
||||
* AEAD (used for bip151)
|
||||
* @exports AEAD
|
||||
* @see https://github.com/openssh/openssh-portable
|
||||
* @see https://tools.ietf.org/html/rfc7539#section-2.8
|
||||
* @alias module:crypto/chachapoly.AEAD
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
function AEAD() {
|
||||
if (!(this instanceof AEAD))
|
||||
return new AEAD();
|
||||
|
||||
this.chacha20 = new ChaCha20();
|
||||
this.poly1305 = new Poly1305();
|
||||
this.aadLen = 0;
|
||||
this.cipherLen = 0;
|
||||
this.polyKey = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the AEAD with a key and iv.
|
||||
* @param {Buffer} key
|
||||
* @param {Buffer} iv - IV / packet sequence number.
|
||||
*/
|
||||
|
||||
AEAD.prototype.init = function init(key, iv) {
|
||||
var polyKey = Buffer.allocUnsafe(32);
|
||||
polyKey.fill(0);
|
||||
|
||||
this.chacha20.init(key, iv);
|
||||
this.chacha20.encrypt(polyKey);
|
||||
this.poly1305.init(polyKey);
|
||||
|
||||
// We need to encrypt a full block
|
||||
// to get the cipher in the correct state.
|
||||
this.chacha20.encrypt(Buffer.allocUnsafe(32));
|
||||
|
||||
// Counter should be one.
|
||||
assert(this.chacha20.getCounter() === 1);
|
||||
|
||||
// Expose for debugging.
|
||||
this.polyKey = polyKey;
|
||||
|
||||
this.aadLen = 0;
|
||||
this.cipherLen = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the aad (will be finalized
|
||||
* on an encrypt/decrypt call).
|
||||
* @param {Buffer} aad
|
||||
*/
|
||||
|
||||
AEAD.prototype.aad = function _aad(aad) {
|
||||
assert(this.cipherLen === 0, 'Cannot update aad.');
|
||||
this.poly1305.update(aad);
|
||||
this.aadLen += aad.length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Encrypt a piece of data.
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
AEAD.prototype.encrypt = function encrypt(data) {
|
||||
if (this.cipherLen === 0)
|
||||
this.pad16(this.aadLen);
|
||||
|
||||
this.chacha20.encrypt(data);
|
||||
this.poly1305.update(data);
|
||||
this.cipherLen += data.length;
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decrypt a piece of data.
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
AEAD.prototype.decrypt = function decrypt(data) {
|
||||
if (this.cipherLen === 0)
|
||||
this.pad16(this.aadLen);
|
||||
|
||||
this.cipherLen += data.length;
|
||||
this.poly1305.update(data);
|
||||
this.chacha20.encrypt(data);
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Authenticate data without decrypting.
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
AEAD.prototype.auth = function auth(data) {
|
||||
if (this.cipherLen === 0)
|
||||
this.pad16(this.aadLen);
|
||||
|
||||
this.cipherLen += data.length;
|
||||
this.poly1305.update(data);
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Finalize the aead and generate a MAC.
|
||||
* @returns {Buffer} MAC
|
||||
*/
|
||||
|
||||
AEAD.prototype.finish = function finish() {
|
||||
var len = Buffer.allocUnsafe(16);
|
||||
var lo, hi;
|
||||
|
||||
// The RFC says these are supposed to be
|
||||
// uint32le, but their own fucking test
|
||||
// cases fail unless they are uint64le's.
|
||||
lo = this.aadLen % 0x100000000;
|
||||
hi = (this.aadLen - lo) / 0x100000000;
|
||||
len.writeUInt32LE(lo, 0, true);
|
||||
len.writeUInt32LE(hi, 4, true);
|
||||
|
||||
lo = this.cipherLen % 0x100000000;
|
||||
hi = (this.cipherLen - lo) / 0x100000000;
|
||||
len.writeUInt32LE(lo, 8, true);
|
||||
len.writeUInt32LE(hi, 12, true);
|
||||
|
||||
if (this.cipherLen === 0)
|
||||
this.pad16(this.aadLen);
|
||||
|
||||
this.pad16(this.cipherLen);
|
||||
this.poly1305.update(len);
|
||||
|
||||
return this.poly1305.finish();
|
||||
};
|
||||
|
||||
/**
|
||||
* Pad a chunk before updating mac.
|
||||
* @private
|
||||
* @param {Number} size
|
||||
*/
|
||||
|
||||
AEAD.prototype.pad16 = function pad16(size) {
|
||||
var pad;
|
||||
|
||||
size %= 16;
|
||||
|
||||
if (size === 0)
|
||||
return;
|
||||
|
||||
pad = Buffer.allocUnsafe(16 - size);
|
||||
pad.fill(0);
|
||||
|
||||
this.poly1305.update(pad);
|
||||
};
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
exports.ChaCha20 = ChaCha20;
|
||||
exports.Poly1305 = Poly1305;
|
||||
exports.AEAD = AEAD;
|
||||
34
lib/crypto/cleanse.js
Normal file
34
lib/crypto/cleanse.js
Normal file
@ -0,0 +1,34 @@
|
||||
/*!
|
||||
* cleanse.js - memzero for bcoin
|
||||
* Copyright (c) 2016-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @module crypto.cleanse
|
||||
*/
|
||||
|
||||
var native = require('../utils/native').binding;
|
||||
var counter = 0;
|
||||
|
||||
/**
|
||||
* A maybe-secure memzero.
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
module.exports = function cleanse(data) {
|
||||
var ctr = counter;
|
||||
var i;
|
||||
|
||||
for (i = 0; i < data.length; i++) {
|
||||
data[i] = ctr & 0xff;
|
||||
ctr += i;
|
||||
}
|
||||
|
||||
counter = ctr >>> 0;
|
||||
};
|
||||
|
||||
if (native)
|
||||
exports.cleanse = native.cleanse;
|
||||
@ -1,451 +0,0 @@
|
||||
/*!
|
||||
* crypto.js - crypto for bcoin
|
||||
* Copyright (c) 2014-2015, Fedor Indutny (MIT License)
|
||||
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var backend = require('./backend');
|
||||
var native = require('../utils/native').binding;
|
||||
var scrypt = require('./scrypt');
|
||||
|
||||
/**
|
||||
* @exports crypto/crypto
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
var crypto = exports;
|
||||
|
||||
/**
|
||||
* Hash with chosen algorithm.
|
||||
* @function
|
||||
* @param {String} alg
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
crypto.hash = backend.hash;
|
||||
|
||||
/**
|
||||
* Hash with ripemd160.
|
||||
* @function
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
crypto.ripemd160 = backend.ripemd160;
|
||||
|
||||
/**
|
||||
* Hash with sha1.
|
||||
* @function
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
crypto.sha1 = backend.sha1;
|
||||
|
||||
/**
|
||||
* Hash with sha256.
|
||||
* @function
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
crypto.sha256 = backend.sha256;
|
||||
|
||||
/**
|
||||
* Hash with sha256 and ripemd160 (OP_HASH160).
|
||||
* @function
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
crypto.hash160 = backend.hash160;
|
||||
|
||||
/**
|
||||
* Hash with sha256 twice (OP_HASH256).
|
||||
* @function
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
crypto.hash256 = backend.hash256;
|
||||
|
||||
/**
|
||||
* Create an HMAC.
|
||||
* @function
|
||||
* @param {String} alg
|
||||
* @param {Buffer} data
|
||||
* @param {Buffer} key
|
||||
* @returns {Buffer} HMAC
|
||||
*/
|
||||
|
||||
crypto.hmac = backend.hmac;
|
||||
|
||||
/**
|
||||
* Perform key derivation using PBKDF2.
|
||||
* @function
|
||||
* @param {Buffer} key
|
||||
* @param {Buffer} salt
|
||||
* @param {Number} iter
|
||||
* @param {Number} len
|
||||
* @param {String} alg
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
crypto.pbkdf2 = backend.pbkdf2;
|
||||
|
||||
/**
|
||||
* Execute pbkdf2 asynchronously.
|
||||
* @function
|
||||
* @param {Buffer} key
|
||||
* @param {Buffer} salt
|
||||
* @param {Number} iter
|
||||
* @param {Number} len
|
||||
* @param {String} alg
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
crypto.pbkdf2Async = backend.pbkdf2Async;
|
||||
|
||||
/**
|
||||
* Perform key derivation using scrypt.
|
||||
* @function
|
||||
* @param {Buffer} passwd
|
||||
* @param {Buffer} salt
|
||||
* @param {Number} N
|
||||
* @param {Number} r
|
||||
* @param {Number} p
|
||||
* @param {Number} len
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
crypto.scrypt = scrypt.scrypt;
|
||||
|
||||
/**
|
||||
* Execute scrypt asynchronously.
|
||||
* @function
|
||||
* @param {Buffer} passwd
|
||||
* @param {Buffer} salt
|
||||
* @param {Number} N
|
||||
* @param {Number} r
|
||||
* @param {Number} p
|
||||
* @param {Number} len
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
crypto.scryptAsync = scrypt.scryptAsync;
|
||||
|
||||
/**
|
||||
* Perform hkdf extraction.
|
||||
* @param {Buffer} ikm
|
||||
* @param {Buffer} key
|
||||
* @param {String} alg
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
crypto.hkdfExtract = function hkdfExtract(ikm, key, alg) {
|
||||
return crypto.hmac(alg, ikm, key);
|
||||
};
|
||||
|
||||
/**
|
||||
* Perform hkdf expansion.
|
||||
* @param {Buffer} prk
|
||||
* @param {Buffer} info
|
||||
* @param {Number} len
|
||||
* @param {String} alg
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
crypto.hkdfExpand = function hkdfExpand(prk, info, len, alg) {
|
||||
var size = crypto.hash(alg, Buffer.alloc(0)).length;
|
||||
var blocks = Math.ceil(len / size);
|
||||
var i, okm, buf, out;
|
||||
|
||||
if (blocks > 255)
|
||||
throw new Error('Too many blocks.');
|
||||
|
||||
okm = Buffer.allocUnsafe(len);
|
||||
|
||||
if (blocks === 0)
|
||||
return okm;
|
||||
|
||||
buf = Buffer.allocUnsafe(size + info.length + 1);
|
||||
|
||||
// First round:
|
||||
info.copy(buf, size);
|
||||
buf[buf.length - 1] = 1;
|
||||
out = crypto.hmac(alg, buf.slice(size), prk);
|
||||
out.copy(okm, 0);
|
||||
|
||||
for (i = 1; i < blocks; i++) {
|
||||
out.copy(buf, 0);
|
||||
buf[buf.length - 1]++;
|
||||
out = crypto.hmac(alg, buf, prk);
|
||||
out.copy(okm, i * size);
|
||||
}
|
||||
|
||||
return okm;
|
||||
};
|
||||
|
||||
/**
|
||||
* Build a merkle tree from leaves.
|
||||
* Note that this will mutate the `leaves` array!
|
||||
* @param {Buffer[]} leaves
|
||||
* @returns {MerkleTree}
|
||||
*/
|
||||
|
||||
crypto.createMerkleTree = function createMerkleTree(leaves) {
|
||||
var nodes = leaves;
|
||||
var size = leaves.length;
|
||||
var malleated = false;
|
||||
var i, j, k, hash, left, right, lr;
|
||||
|
||||
if (size === 0) {
|
||||
hash = Buffer.allocUnsafe(32);
|
||||
hash.fill(0);
|
||||
nodes.push(hash);
|
||||
return new MerkleTree(nodes, malleated);
|
||||
}
|
||||
|
||||
lr = Buffer.allocUnsafe(64);
|
||||
|
||||
for (j = 0; size > 1; size = ((size + 1) / 2) | 0) {
|
||||
for (i = 0; i < size; i += 2) {
|
||||
k = Math.min(i + 1, size - 1);
|
||||
left = nodes[j + i];
|
||||
right = nodes[j + k];
|
||||
|
||||
if (k === i + 1 && k + 1 === size
|
||||
&& left.equals(right)) {
|
||||
malleated = true;
|
||||
}
|
||||
|
||||
left.copy(lr, 0);
|
||||
right.copy(lr, 32);
|
||||
|
||||
hash = crypto.hash256(lr);
|
||||
|
||||
nodes.push(hash);
|
||||
}
|
||||
j += size;
|
||||
}
|
||||
|
||||
return new MerkleTree(nodes, malleated);
|
||||
};
|
||||
|
||||
if (native)
|
||||
crypto.createMerkleTree = native.createMerkleTree;
|
||||
|
||||
/**
|
||||
* Calculate merkle root from leaves.
|
||||
* @param {Buffer[]} leaves
|
||||
* @returns {MerkleRoot}
|
||||
*/
|
||||
|
||||
crypto.createMerkleRoot = function createMerkleRoot(leaves) {
|
||||
var tree = crypto.createMerkleTree(leaves);
|
||||
var hash = tree.nodes[tree.nodes.length - 1];
|
||||
var malleated = tree.malleated;
|
||||
return new MerkleRoot(hash, malleated);
|
||||
};
|
||||
|
||||
/**
|
||||
* Collect a merkle branch at vector index.
|
||||
* @param {Number} index
|
||||
* @param {Buffer[]} leaves
|
||||
* @returns {Buffer[]} branch
|
||||
*/
|
||||
|
||||
crypto.createMerkleBranch = function createMerkleBranch(index, leaves) {
|
||||
var size = leaves.length;
|
||||
var tree = crypto.createMerkleTree(leaves);
|
||||
var branch = [];
|
||||
var j = 0;
|
||||
var i;
|
||||
|
||||
for (; size > 1; size = (size + 1) / 2 | 0) {
|
||||
i = Math.min(index ^ 1, size - 1);
|
||||
branch.push(tree.nodes[j + i]);
|
||||
index >>>= 1;
|
||||
j += size;
|
||||
}
|
||||
|
||||
return branch;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check a merkle branch at vector index.
|
||||
* @param {Buffer} hash
|
||||
* @param {Buffer[]} branch
|
||||
* @param {Number} index
|
||||
* @returns {Buffer} Hash.
|
||||
*/
|
||||
|
||||
crypto.verifyMerkleBranch = function verifyMerkleBranch(hash, branch, index) {
|
||||
var i, otherside, lr;
|
||||
|
||||
if (branch.length === 0)
|
||||
return hash;
|
||||
|
||||
lr = Buffer.allocUnsafe(64);
|
||||
|
||||
for (i = 0; i < branch.length; i++) {
|
||||
otherside = branch[i];
|
||||
|
||||
if (index & 1) {
|
||||
otherside.copy(lr, 0);
|
||||
hash.copy(lr, 32);
|
||||
} else {
|
||||
hash.copy(lr, 0);
|
||||
otherside.copy(lr, 32);
|
||||
}
|
||||
|
||||
hash = crypto.hash256(lr);
|
||||
index >>>= 1;
|
||||
}
|
||||
|
||||
return hash;
|
||||
};
|
||||
|
||||
if (native)
|
||||
crypto.verifyMerkleBranch = native.verifyMerkleBranch;
|
||||
|
||||
/**
|
||||
* Encrypt with aes-256-cbc.
|
||||
* @function
|
||||
* @param {Buffer} data
|
||||
* @param {Buffer} key - 256 bit key.
|
||||
* @param {Buffer} iv - 128 bit initialization vector.
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
crypto.encipher = backend.encipher;
|
||||
|
||||
/**
|
||||
* Decrypt with aes-256-cbc.
|
||||
* @function
|
||||
* @param {Buffer} data
|
||||
* @param {Buffer} key - 256 bit key.
|
||||
* @param {Buffer} iv - 128 bit initialization vector.
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
crypto.decipher = backend.decipher;
|
||||
|
||||
/**
|
||||
* memcmp in constant time (can only return true or false).
|
||||
* This protects us against timing attacks when
|
||||
* comparing an input against a secret string.
|
||||
* @see https://cryptocoding.net/index.php/Coding_rules
|
||||
* @see `$ man 3 memcmp` (NetBSD's consttime_memequal)
|
||||
* @param {Buffer} a
|
||||
* @param {Buffer} b
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
crypto.ccmp = function ccmp(a, b) {
|
||||
var i, res;
|
||||
|
||||
if (!Buffer.isBuffer(a))
|
||||
return false;
|
||||
|
||||
if (!Buffer.isBuffer(b))
|
||||
return false;
|
||||
|
||||
if (b.length === 0)
|
||||
return a.length === 0;
|
||||
|
||||
res = a.length ^ b.length;
|
||||
|
||||
for (i = 0; i < a.length; i++)
|
||||
res |= a[i] ^ b[i % b.length];
|
||||
|
||||
return res === 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* A maybe-secure memzero.
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
crypto.cleanse = function cleanse(data) {
|
||||
var ctr = crypto._counter;
|
||||
var i;
|
||||
|
||||
for (i = 0; i < data.length; i++) {
|
||||
data[i] = ctr & 0xff;
|
||||
ctr += i;
|
||||
}
|
||||
|
||||
crypto._counter = ctr >>> 0;
|
||||
};
|
||||
|
||||
crypto._counter = 0;
|
||||
|
||||
if (native)
|
||||
crypto.cleanse = native.cleanse;
|
||||
|
||||
/**
|
||||
* Generate some random bytes.
|
||||
* @function
|
||||
* @param {Number} size
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
crypto.randomBytes = backend.randomBytes;
|
||||
|
||||
/**
|
||||
* Generate a random uint32.
|
||||
* Probably more cryptographically sound than
|
||||
* `Math.random()`.
|
||||
* @function
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
crypto.randomInt = function randomInt() {
|
||||
return crypto.randomBytes(4).readUInt32LE(0, true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a random number within a range.
|
||||
* Probably more cryptographically sound than
|
||||
* `Math.random()`.
|
||||
* @function
|
||||
* @param {Number} min - Inclusive.
|
||||
* @param {Number} max - Exclusive.
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
crypto.randomRange = function randomRange(min, max) {
|
||||
var num = crypto.randomInt();
|
||||
return Math.floor((num / 0x100000000) * (max - min) + min);
|
||||
};
|
||||
|
||||
/**
|
||||
* Merkle Tree
|
||||
* @constructor
|
||||
* @ignore
|
||||
* @param {Buffer[]} nodes
|
||||
* @param {Boolean} malleated
|
||||
*/
|
||||
|
||||
function MerkleTree(nodes, malleated) {
|
||||
this.nodes = nodes;
|
||||
this.malleated = malleated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merkle Root
|
||||
* @constructor
|
||||
* @ignore
|
||||
* @param {Buffer} hash
|
||||
* @param {Boolean} malleated
|
||||
*/
|
||||
|
||||
function MerkleRoot(hash, malleated) {
|
||||
this.hash = hash;
|
||||
this.malleated = malleated;
|
||||
}
|
||||
105
lib/crypto/digest-browser.js
Normal file
105
lib/crypto/digest-browser.js
Normal file
@ -0,0 +1,105 @@
|
||||
/*!
|
||||
* digest-browser.js - hash functions for bcoin
|
||||
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @module crypto.digest-browser
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
var assert = require('assert');
|
||||
var hashjs = require('hash.js');
|
||||
var sha256 = require('./sha256');
|
||||
|
||||
/**
|
||||
* Hash with chosen algorithm.
|
||||
* @param {String} alg
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.hash = function _hash(alg, data) {
|
||||
var hash;
|
||||
|
||||
if (alg === 'sha256')
|
||||
return sha256.digest(data);
|
||||
|
||||
hash = hashjs[alg];
|
||||
|
||||
assert(hash != null, 'Unknown algorithm.');
|
||||
|
||||
return Buffer.from(hash().update(data).digest());
|
||||
};
|
||||
|
||||
/**
|
||||
* Hash with ripemd160.
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.ripemd160 = function ripemd160(data) {
|
||||
return exports.hash('ripemd160', data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Hash with sha1.
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.sha1 = function sha1(data) {
|
||||
return exports.hash('sha1', data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Hash with sha256.
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.sha256 = function _sha256(data) {
|
||||
return sha256.digest(data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Hash with sha256 and ripemd160 (OP_HASH160).
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.hash160 = function hash160(data) {
|
||||
return exports.hash('ripemd160', sha256.digest(data));
|
||||
};
|
||||
|
||||
/**
|
||||
* Hash with sha256 twice (OP_HASH256).
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.hash256 = function hash256(data) {
|
||||
return sha256.hash256(data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an HMAC.
|
||||
* @param {String} alg
|
||||
* @param {Buffer} data
|
||||
* @param {Buffer} key
|
||||
* @returns {Buffer} HMAC
|
||||
*/
|
||||
|
||||
exports.hmac = function _hmac(alg, data, key) {
|
||||
var hash = hashjs[alg];
|
||||
var hmac;
|
||||
|
||||
assert(hash != null, 'Unknown algorithm.');
|
||||
|
||||
hmac = hashjs.hmac(hash, key);
|
||||
|
||||
return Buffer.from(hmac.update(data).digest());
|
||||
};
|
||||
98
lib/crypto/digest.js
Normal file
98
lib/crypto/digest.js
Normal file
@ -0,0 +1,98 @@
|
||||
/*!
|
||||
* digest.js - hash functions for bcoin
|
||||
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @module crypto.digest
|
||||
*/
|
||||
|
||||
var crypto = require('crypto');
|
||||
var native = require('../utils/native').binding;
|
||||
|
||||
/**
|
||||
* Hash with chosen algorithm.
|
||||
* @param {String} alg
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.hash = function hash(alg, data) {
|
||||
return crypto.createHash(alg).update(data).digest();
|
||||
};
|
||||
|
||||
/**
|
||||
* Hash with ripemd160.
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.ripemd160 = function ripemd160(data) {
|
||||
return exports.hash('ripemd160', data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Hash with sha1.
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.sha1 = function sha1(data) {
|
||||
return exports.hash('sha1', data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Hash with sha256.
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.sha256 = function sha256(data) {
|
||||
return exports.hash('sha256', data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Hash with sha256 and ripemd160 (OP_HASH160).
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.hash160 = function hash160(data) {
|
||||
return exports.ripemd160(exports.sha256(data));
|
||||
};
|
||||
|
||||
/**
|
||||
* Hash with sha256 twice (OP_HASH256).
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.hash256 = function hash256(data) {
|
||||
return exports.sha256(exports.sha256(data));
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an HMAC.
|
||||
* @param {String} alg
|
||||
* @param {Buffer} data
|
||||
* @param {Buffer} key
|
||||
* @returns {Buffer} HMAC
|
||||
*/
|
||||
|
||||
exports.hmac = function hmac(alg, data, key) {
|
||||
var hmac = crypto.createHmac(alg, key);
|
||||
return hmac.update(data).digest();
|
||||
};
|
||||
|
||||
if (native) {
|
||||
exports.hash = native.hash;
|
||||
exports.hmac = native.hmac;
|
||||
exports.ripemd160 = native.ripemd160;
|
||||
exports.sha1 = native.sha1;
|
||||
exports.sha256 = native.sha256;
|
||||
exports.hash160 = native.hash160;
|
||||
exports.hash256 = native.hash256;
|
||||
}
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
var assert = require('assert');
|
||||
var elliptic = require('elliptic');
|
||||
var backend = require('./backend');
|
||||
var digest = require('./digest');
|
||||
|
||||
/**
|
||||
* Verify ECDSA signature.
|
||||
@ -34,7 +34,7 @@ exports.verify = function verify(curve, alg, msg, sig, key) {
|
||||
assert(Buffer.isBuffer(key));
|
||||
|
||||
ec = elliptic.ec(curve);
|
||||
hash = backend.hash(alg, msg);
|
||||
hash = digest.hash(alg, msg);
|
||||
|
||||
try {
|
||||
return ec.verify(hash, sig, key);
|
||||
@ -62,7 +62,7 @@ exports.sign = function sign(curve, alg, msg, key) {
|
||||
assert(Buffer.isBuffer(key));
|
||||
|
||||
ec = elliptic.ec(curve);
|
||||
hash = backend.hash(alg, msg);
|
||||
hash = digest.hash(alg, msg);
|
||||
|
||||
sig = ec.sign(hash, key, { canonical: true });
|
||||
|
||||
|
||||
65
lib/crypto/hkdf.js
Normal file
65
lib/crypto/hkdf.js
Normal file
@ -0,0 +1,65 @@
|
||||
/*!
|
||||
* hkdf.js - hkdf for bcoin
|
||||
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @module crypto/hkdf
|
||||
*/
|
||||
|
||||
var digest = require('./digest');
|
||||
|
||||
/**
|
||||
* Perform hkdf extraction.
|
||||
* @param {Buffer} ikm
|
||||
* @param {Buffer} key
|
||||
* @param {String} alg
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.extract = function extract(ikm, key, alg) {
|
||||
return digest.hmac(alg, ikm, key);
|
||||
};
|
||||
|
||||
/**
|
||||
* Perform hkdf expansion.
|
||||
* @param {Buffer} prk
|
||||
* @param {Buffer} info
|
||||
* @param {Number} len
|
||||
* @param {String} alg
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.expand = function expand(prk, info, len, alg) {
|
||||
var size = digest.hash(alg, Buffer.alloc(0)).length;
|
||||
var blocks = Math.ceil(len / size);
|
||||
var i, okm, buf, out;
|
||||
|
||||
if (blocks > 255)
|
||||
throw new Error('Too many blocks.');
|
||||
|
||||
okm = Buffer.allocUnsafe(len);
|
||||
|
||||
if (blocks === 0)
|
||||
return okm;
|
||||
|
||||
buf = Buffer.allocUnsafe(size + info.length + 1);
|
||||
|
||||
// First round:
|
||||
info.copy(buf, size);
|
||||
buf[buf.length - 1] = 1;
|
||||
out = digest.hmac(alg, buf.slice(size), prk);
|
||||
out.copy(okm, 0);
|
||||
|
||||
for (i = 1; i < blocks; i++) {
|
||||
out.copy(buf, 0);
|
||||
buf[buf.length - 1]++;
|
||||
out = digest.hmac(alg, buf, prk);
|
||||
out.copy(okm, i * size);
|
||||
}
|
||||
|
||||
return okm;
|
||||
};
|
||||
@ -8,7 +8,7 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var backend = require('./backend');
|
||||
var digest = require('./digest');
|
||||
|
||||
/*
|
||||
* Constants
|
||||
@ -73,8 +73,8 @@ HmacDRBG.prototype.iterate = function iterate() {
|
||||
this.V.copy(data, 0);
|
||||
data[HASH_SIZE] = 0x00;
|
||||
|
||||
this.K = backend.hmac(HASH_ALG, data, this.K);
|
||||
this.V = backend.hmac(HASH_ALG, this.V, this.K);
|
||||
this.K = digest.hmac(HASH_ALG, data, this.K);
|
||||
this.V = digest.hmac(HASH_ALG, this.V, this.K);
|
||||
};
|
||||
|
||||
HmacDRBG.prototype.update = function update(seed) {
|
||||
@ -87,13 +87,13 @@ HmacDRBG.prototype.update = function update(seed) {
|
||||
data[HASH_SIZE] = 0x00;
|
||||
seed.copy(data, HASH_SIZE + 1);
|
||||
|
||||
this.K = backend.hmac(HASH_ALG, data, this.K);
|
||||
this.V = backend.hmac(HASH_ALG, this.V, this.K);
|
||||
this.K = digest.hmac(HASH_ALG, data, this.K);
|
||||
this.V = digest.hmac(HASH_ALG, this.V, this.K);
|
||||
|
||||
data[HASH_SIZE] = 0x01;
|
||||
|
||||
this.K = backend.hmac(HASH_ALG, data, this.K);
|
||||
this.V = backend.hmac(HASH_ALG, this.V, this.K);
|
||||
this.K = digest.hmac(HASH_ALG, data, this.K);
|
||||
this.V = digest.hmac(HASH_ALG, this.V, this.K);
|
||||
};
|
||||
|
||||
HmacDRBG.prototype.generate = function generate(len) {
|
||||
@ -104,7 +104,7 @@ HmacDRBG.prototype.generate = function generate(len) {
|
||||
throw new Error('Reseed is required.');
|
||||
|
||||
while (pos < len) {
|
||||
this.V = backend.hmac(HASH_ALG, this.V, this.K);
|
||||
this.V = digest.hmac(HASH_ALG, this.V, this.K);
|
||||
this.V.copy(data, pos);
|
||||
pos += HASH_SIZE;
|
||||
}
|
||||
|
||||
@ -1,349 +1,50 @@
|
||||
/*!
|
||||
* crypto/index.js - crypto for bcoin
|
||||
* Copyright (c) 2014-2016, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @module crypto
|
||||
*/
|
||||
|
||||
var crypto = require('./crypto');
|
||||
|
||||
/**
|
||||
* Crypto module.
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
exports.crypto = crypto;
|
||||
|
||||
/**
|
||||
* Hash with chosen algorithm.
|
||||
* @function
|
||||
* @param {String} alg
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.hash = crypto.hash;
|
||||
|
||||
/**
|
||||
* Hash with ripemd160.
|
||||
* @function
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.ripemd160 = crypto.ripemd160;
|
||||
|
||||
/**
|
||||
* Hash with sha1.
|
||||
* @function
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.sha1 = crypto.sha1;
|
||||
|
||||
/**
|
||||
* Hash with sha256.
|
||||
* @function
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.sha256 = crypto.sha256;
|
||||
|
||||
/**
|
||||
* Hash with sha256 and ripemd160 (OP_HASH160).
|
||||
* @function
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.hash160 = crypto.hash160;
|
||||
|
||||
/**
|
||||
* Hash with sha256 twice (OP_HASH256).
|
||||
* @function
|
||||
* @param {Buffer} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.hash256 = crypto.hash256;
|
||||
|
||||
/**
|
||||
* Create an HMAC.
|
||||
* @function
|
||||
* @param {String} alg
|
||||
* @param {Buffer} data
|
||||
* @param {Buffer} key
|
||||
* @returns {Buffer} HMAC
|
||||
*/
|
||||
|
||||
exports.hmac = crypto.hmac;
|
||||
|
||||
/**
|
||||
* Perform key derivation using PBKDF2.
|
||||
* @function
|
||||
* @param {Buffer} key
|
||||
* @param {Buffer} salt
|
||||
* @param {Number} iter
|
||||
* @param {Number} len
|
||||
* @param {String} alg
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.pbkdf2 = crypto.pbkdf2;
|
||||
|
||||
/**
|
||||
* Execute pbkdf2 asynchronously.
|
||||
* @function
|
||||
* @param {Buffer} key
|
||||
* @param {Buffer} salt
|
||||
* @param {Number} iter
|
||||
* @param {Number} len
|
||||
* @param {String} alg
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
exports.pbkdf2Async = crypto.pbkdf2Async;
|
||||
|
||||
/**
|
||||
* Perform key derivation using scrypt.
|
||||
* @function
|
||||
* @param {Buffer} passwd
|
||||
* @param {Buffer} salt
|
||||
* @param {Number} N
|
||||
* @param {Number} r
|
||||
* @param {Number} p
|
||||
* @param {Number} len
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.scrypt = crypto.scrypt;
|
||||
|
||||
/**
|
||||
* Execute scrypt asynchronously.
|
||||
* @function
|
||||
* @param {Buffer} passwd
|
||||
* @param {Buffer} salt
|
||||
* @param {Number} N
|
||||
* @param {Number} r
|
||||
* @param {Number} p
|
||||
* @param {Number} len
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
exports.scryptAsync = crypto.scryptAsync;
|
||||
|
||||
/**
|
||||
* Perform hkdf extraction.
|
||||
* @function
|
||||
* @param {Buffer} ikm
|
||||
* @param {Buffer} key
|
||||
* @param {String} alg
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.hkdfExtract = crypto.hkdfExtract;
|
||||
|
||||
/**
|
||||
* Perform hkdf expansion.
|
||||
* @function
|
||||
* @param {Buffer} prk
|
||||
* @param {Buffer} info
|
||||
* @param {Number} len
|
||||
* @param {String} alg
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.hkdfExpand = crypto.hkdfExpand;
|
||||
|
||||
/**
|
||||
* Build a merkle tree from leaves.
|
||||
* Note that this will mutate the `leaves` array!
|
||||
* @function
|
||||
* @param {Buffer[]} leaves
|
||||
* @returns {MerkleTree}
|
||||
*/
|
||||
|
||||
exports.createMerkleTree = crypto.createMerkleTree;
|
||||
|
||||
/**
|
||||
* Calculate merkle root from leaves.
|
||||
* @function
|
||||
* @param {Buffer[]} leaves
|
||||
* @returns {MerkleRoot}
|
||||
*/
|
||||
|
||||
exports.createMerkleRoot = crypto.createMerkleRoot;
|
||||
|
||||
/**
|
||||
* Collect a merkle branch at vector index.
|
||||
* @function
|
||||
* @param {Number} index
|
||||
* @param {Buffer[]} leaves
|
||||
* @returns {Buffer[]} branch
|
||||
*/
|
||||
|
||||
exports.createMerkleBranch = crypto.createMerkleBranch;
|
||||
|
||||
/**
|
||||
* Check a merkle branch at vector index.
|
||||
* @function
|
||||
* @param {Buffer} hash
|
||||
* @param {Buffer[]} branch
|
||||
* @param {Number} index
|
||||
* @returns {Buffer} Hash.
|
||||
*/
|
||||
|
||||
exports.verifyMerkleBranch = crypto.verifyMerkleBranch;
|
||||
|
||||
/**
|
||||
* Encrypt with aes-256-cbc.
|
||||
* @function
|
||||
* @param {Buffer} data
|
||||
* @param {Buffer} key - 256 bit key.
|
||||
* @param {Buffer} iv - 128 bit initialization vector.
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.encipher = crypto.encipher;
|
||||
|
||||
/**
|
||||
* Decrypt with aes-256-cbc.
|
||||
* @function
|
||||
* @param {Buffer} data
|
||||
* @param {Buffer} key - 256 bit key.
|
||||
* @param {Buffer} iv - 128 bit initialization vector.
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.decipher = crypto.decipher;
|
||||
|
||||
/**
|
||||
* memcmp in constant time (can only return true or false).
|
||||
* This protects us against timing attacks when
|
||||
* comparing an input against a secret string.
|
||||
* @function
|
||||
* @see https://cryptocoding.net/index.php/Coding_rules
|
||||
* @see `$ man 3 memcmp` (NetBSD's consttime_memequal)
|
||||
* @param {Buffer} a
|
||||
* @param {Buffer} b
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
exports.ccmp = crypto.ccmp;
|
||||
|
||||
/**
|
||||
* A maybe-secure memzero.
|
||||
* @function
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
exports.cleanse = crypto.cleanse;
|
||||
|
||||
/**
|
||||
* Generate some random bytes.
|
||||
* @function
|
||||
* @param {Number} size
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.randomBytes = crypto.randomBytes;
|
||||
|
||||
/**
|
||||
* Generate a random uint32.
|
||||
* Probably more cryptographically sound than
|
||||
* `Math.random()`.
|
||||
* @function
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
exports.randomInt = crypto.randomInt;
|
||||
|
||||
/**
|
||||
* Generate a random number within a range.
|
||||
* Probably more cryptographically sound than
|
||||
* `Math.random()`.
|
||||
* @function
|
||||
* @param {Number} min - Inclusive.
|
||||
* @param {Number} max - Exclusive.
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
exports.randomRange = crypto.randomRange;
|
||||
|
||||
/**
|
||||
* chachapoly module
|
||||
* @see module:crypto/chachapoly
|
||||
*/
|
||||
|
||||
exports.chachapoly = require('./chachapoly');
|
||||
|
||||
/**
|
||||
* ChaCha20
|
||||
* @see module:crypto/chachapoly.ChaCha20
|
||||
*/
|
||||
|
||||
exports.ChaCha20 = exports.chachapoly.ChaCha20;
|
||||
|
||||
/**
|
||||
* Poly1305
|
||||
* @see module:crypto/chachapoly.Poly1305
|
||||
*/
|
||||
|
||||
exports.Poly1305 = exports.chachapoly.Poly1305;
|
||||
|
||||
/**
|
||||
* AEAD
|
||||
* @see module:crypto/chachapoly.AEAD
|
||||
*/
|
||||
|
||||
exports.AEAD = exports.chachapoly.AEAD;
|
||||
|
||||
/**
|
||||
* BN
|
||||
* @see https://github.com/indutny/bn.js
|
||||
*/
|
||||
var digest = require('./digest');
|
||||
var random = require('./random');
|
||||
var aes = require('./aes');
|
||||
|
||||
exports.aes = require('./aes');
|
||||
exports.AEAD = require('./aead');
|
||||
exports.BN = require('./bn');
|
||||
|
||||
/**
|
||||
* RSA
|
||||
* @see module:crypto/rsa
|
||||
*/
|
||||
|
||||
exports.rsa = require('./rsa');
|
||||
|
||||
/**
|
||||
* ECDSA
|
||||
* @see module:crypto/ecdsa
|
||||
*/
|
||||
|
||||
exports.ccmp = require('./ccmp');
|
||||
exports.ChaCha20 = require('./chacha20');
|
||||
exports.cleanse = require('./cleanse');
|
||||
exports.digest = require('./digest');
|
||||
exports.ecdsa = require('./ecdsa');
|
||||
|
||||
/**
|
||||
* secp256k1 module
|
||||
* @see module:crypto/secp256k1
|
||||
*/
|
||||
|
||||
exports.secp256k1 = require('./secp256k1');
|
||||
|
||||
/**
|
||||
* schnorr module
|
||||
* @see module:crypto/schnorr
|
||||
*/
|
||||
|
||||
exports.hkdf = require('./hkdf');
|
||||
exports.HmacDRBG = require('./hmac-drbg');
|
||||
exports.merkle = require('./merkle');
|
||||
exports.pbkdf2 = require('./pbkdf2');
|
||||
exports.Poly1305 = require('./poly1305');
|
||||
exports.random = require('./random');
|
||||
exports.rsa = require('./rsa');
|
||||
exports.schnorr = require('./schnorr');
|
||||
|
||||
/**
|
||||
* siphash module
|
||||
* @see module:crypto/siphash
|
||||
*/
|
||||
|
||||
exports.scrypt = require('./scrypt');
|
||||
exports.secp256k1 = require('./secp256k1');
|
||||
exports.siphash = require('./siphash');
|
||||
|
||||
/**
|
||||
* siphash256
|
||||
* @see module:crypto/siphash.siphash256
|
||||
*/
|
||||
exports.hash = digest.hash;
|
||||
exports.ripemd160 = digest.ripemd160;
|
||||
exports.sha1 = digest.sha1;
|
||||
exports.sha256 = digest.sha256;
|
||||
exports.hash160 = digest.hash160;
|
||||
exports.hash256 = digest.hash256;
|
||||
exports.hmac = digest.hmac;
|
||||
|
||||
exports.siphash256 = exports.siphash.siphash256;
|
||||
exports.encipher = aes.encipher;
|
||||
exports.decipher = aes.decipher;
|
||||
|
||||
exports.randomBytes = random.randomBytes;
|
||||
exports.randomInt = random.randomInt;
|
||||
exports.randomRange = random.randomRange;
|
||||
|
||||
164
lib/crypto/merkle.js
Normal file
164
lib/crypto/merkle.js
Normal file
@ -0,0 +1,164 @@
|
||||
/*!
|
||||
* merkle.js - merkle trees for bcoin
|
||||
* Copyright (c) 2014-2015, Fedor Indutny (MIT License)
|
||||
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @module crypto/merkle
|
||||
*/
|
||||
|
||||
var digest = require('./digest');
|
||||
var native = require('../utils/native').binding;
|
||||
|
||||
/**
|
||||
* Build a merkle tree from leaves.
|
||||
* Note that this will mutate the `leaves` array!
|
||||
* @param {Buffer[]} leaves
|
||||
* @returns {MerkleTree}
|
||||
*/
|
||||
|
||||
exports.createTree = function createTree(leaves) {
|
||||
var nodes = leaves;
|
||||
var size = leaves.length;
|
||||
var malleated = false;
|
||||
var i, j, k, hash, left, right, lr;
|
||||
|
||||
if (size === 0) {
|
||||
hash = Buffer.allocUnsafe(32);
|
||||
hash.fill(0);
|
||||
nodes.push(hash);
|
||||
return new MerkleTree(nodes, malleated);
|
||||
}
|
||||
|
||||
lr = Buffer.allocUnsafe(64);
|
||||
|
||||
for (j = 0; size > 1; size = ((size + 1) / 2) | 0) {
|
||||
for (i = 0; i < size; i += 2) {
|
||||
k = Math.min(i + 1, size - 1);
|
||||
left = nodes[j + i];
|
||||
right = nodes[j + k];
|
||||
|
||||
if (k === i + 1 && k + 1 === size
|
||||
&& left.equals(right)) {
|
||||
malleated = true;
|
||||
}
|
||||
|
||||
left.copy(lr, 0);
|
||||
right.copy(lr, 32);
|
||||
|
||||
hash = digest.hash256(lr);
|
||||
|
||||
nodes.push(hash);
|
||||
}
|
||||
j += size;
|
||||
}
|
||||
|
||||
return new MerkleTree(nodes, malleated);
|
||||
};
|
||||
|
||||
if (native)
|
||||
exports.createTree = native.createMerkleTree;
|
||||
|
||||
/**
|
||||
* Calculate merkle root from leaves.
|
||||
* @param {Buffer[]} leaves
|
||||
* @returns {MerkleRoot}
|
||||
*/
|
||||
|
||||
exports.createRoot = function createRoot(leaves) {
|
||||
var tree = exports.createTree(leaves);
|
||||
var hash = tree.nodes[tree.nodes.length - 1];
|
||||
var malleated = tree.malleated;
|
||||
return new MerkleRoot(hash, malleated);
|
||||
};
|
||||
|
||||
/**
|
||||
* Collect a merkle branch at vector index.
|
||||
* @param {Number} index
|
||||
* @param {Buffer[]} leaves
|
||||
* @returns {Buffer[]} branch
|
||||
*/
|
||||
|
||||
exports.createBranch = function createBranch(index, leaves) {
|
||||
var size = leaves.length;
|
||||
var tree = exports.createTree(leaves);
|
||||
var branch = [];
|
||||
var j = 0;
|
||||
var i;
|
||||
|
||||
for (; size > 1; size = (size + 1) / 2 | 0) {
|
||||
i = Math.min(index ^ 1, size - 1);
|
||||
branch.push(tree.nodes[j + i]);
|
||||
index >>>= 1;
|
||||
j += size;
|
||||
}
|
||||
|
||||
return branch;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check a merkle branch at vector index.
|
||||
* @param {Buffer} hash
|
||||
* @param {Buffer[]} branch
|
||||
* @param {Number} index
|
||||
* @returns {Buffer} Hash.
|
||||
*/
|
||||
|
||||
exports.verifyBranch = function verifyBranch(hash, branch, index) {
|
||||
var i, otherside, lr;
|
||||
|
||||
if (branch.length === 0)
|
||||
return hash;
|
||||
|
||||
lr = Buffer.allocUnsafe(64);
|
||||
|
||||
for (i = 0; i < branch.length; i++) {
|
||||
otherside = branch[i];
|
||||
|
||||
if (index & 1) {
|
||||
otherside.copy(lr, 0);
|
||||
hash.copy(lr, 32);
|
||||
} else {
|
||||
hash.copy(lr, 0);
|
||||
otherside.copy(lr, 32);
|
||||
}
|
||||
|
||||
hash = digest.hash256(lr);
|
||||
index >>>= 1;
|
||||
}
|
||||
|
||||
return hash;
|
||||
};
|
||||
|
||||
if (native)
|
||||
exports.verifyBranch = native.verifyMerkleBranch;
|
||||
|
||||
/**
|
||||
* Merkle Tree
|
||||
* @constructor
|
||||
* @ignore
|
||||
* @param {Buffer[]} nodes
|
||||
* @param {Boolean} malleated
|
||||
*/
|
||||
|
||||
function MerkleTree(nodes, malleated) {
|
||||
this.nodes = nodes;
|
||||
this.malleated = malleated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merkle Root
|
||||
* @constructor
|
||||
* @ignore
|
||||
* @param {Buffer} hash
|
||||
* @param {Boolean} malleated
|
||||
*/
|
||||
|
||||
function MerkleRoot(hash, malleated) {
|
||||
this.hash = hash;
|
||||
this.malleated = malleated;
|
||||
}
|
||||
108
lib/crypto/pbkdf2-browser.js
Normal file
108
lib/crypto/pbkdf2-browser.js
Normal file
@ -0,0 +1,108 @@
|
||||
/*!
|
||||
* pbkdf2.js - pbkdf2 for bcoin
|
||||
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @module crypto.pbkdf2-browser
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
var digest = require('./digest');
|
||||
var crypto = global.crypto || global.msCrypto || {};
|
||||
var subtle = crypto.subtle && crypto.subtle.importKey ? crypto.subtle : {};
|
||||
|
||||
/**
|
||||
* Perform key derivation using PBKDF2.
|
||||
* @param {Buffer} key
|
||||
* @param {Buffer} salt
|
||||
* @param {Number} iter
|
||||
* @param {Number} len
|
||||
* @param {String} alg
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.derive = function derive(key, salt, iter, len, alg) {
|
||||
var size = digest.hash(alg, Buffer.alloc(0)).length;
|
||||
var blocks = Math.ceil(len / size);
|
||||
var out = Buffer.allocUnsafe(len);
|
||||
var buf = Buffer.allocUnsafe(salt.length + 4);
|
||||
var block = Buffer.allocUnsafe(size);
|
||||
var pos = 0;
|
||||
var i, j, k, mac;
|
||||
|
||||
salt.copy(buf, 0);
|
||||
|
||||
for (i = 0; i < blocks; i++) {
|
||||
buf.writeUInt32BE(i + 1, salt.length, true);
|
||||
mac = digest.hmac(alg, buf, key);
|
||||
mac.copy(block, 0);
|
||||
for (j = 1; j < iter; j++) {
|
||||
mac = digest.hmac(alg, mac, key);
|
||||
for (k = 0; k < size; k++)
|
||||
block[k] ^= mac[k];
|
||||
}
|
||||
block.copy(out, pos);
|
||||
pos += size;
|
||||
}
|
||||
|
||||
return out;
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute pbkdf2 asynchronously.
|
||||
* @param {Buffer} key
|
||||
* @param {Buffer} salt
|
||||
* @param {Number} iter
|
||||
* @param {Number} len
|
||||
* @param {String} alg
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
exports.deriveAsync = function deriveAsync(key, salt, iter, len, alg) {
|
||||
var algo = { name: 'PBKDF2' };
|
||||
var use = ['deriveBits'];
|
||||
var name = getHash(alg);
|
||||
var length = len * 8;
|
||||
var options, promise;
|
||||
|
||||
options = {
|
||||
name: 'PBKDF2',
|
||||
salt: salt,
|
||||
iterations: iter,
|
||||
hash: name
|
||||
};
|
||||
|
||||
promise = subtle.importKey('raw', key, algo, false, use);
|
||||
|
||||
return promise.then(function(key) {
|
||||
return subtle.deriveBits(options, key, length);
|
||||
}).then(function(result) {
|
||||
return Buffer.from(result);
|
||||
});
|
||||
};
|
||||
|
||||
if (!subtle.deriveBits)
|
||||
exports.pbkdf2Async = exports.pbkdf2;
|
||||
|
||||
/*
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function getHash(name) {
|
||||
switch (name) {
|
||||
case 'sha1':
|
||||
return 'SHA-1';
|
||||
case 'sha256':
|
||||
return 'SHA-256';
|
||||
case 'sha384':
|
||||
return 'SHA-384';
|
||||
case 'sha512':
|
||||
return 'SHA-512';
|
||||
default:
|
||||
throw new Error('Algorithm not supported: ' + name);
|
||||
}
|
||||
}
|
||||
44
lib/crypto/pbkdf2.js
Normal file
44
lib/crypto/pbkdf2.js
Normal file
@ -0,0 +1,44 @@
|
||||
/*!
|
||||
* pbkdf2.js - pbkdf2 for bcoin
|
||||
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @module crypto.pbkdf2
|
||||
*/
|
||||
|
||||
var co = require('../utils/co');
|
||||
var crypto = require('crypto');
|
||||
|
||||
/**
|
||||
* Perform key derivation using PBKDF2.
|
||||
* @param {Buffer} key
|
||||
* @param {Buffer} salt
|
||||
* @param {Number} iter
|
||||
* @param {Number} len
|
||||
* @param {String} alg
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.derive = function derive(key, salt, iter, len, alg) {
|
||||
return crypto.pbkdf2Sync(key, salt, iter, len, alg);
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute pbkdf2 asynchronously.
|
||||
* @param {Buffer} key
|
||||
* @param {Buffer} salt
|
||||
* @param {Number} iter
|
||||
* @param {Number} len
|
||||
* @param {String} alg
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
exports.deriveAsync = function deriveAsync(key, salt, iter, len, alg) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
crypto.pbkdf2(key, salt, iter, len, alg, co.wrap(resolve, reject));
|
||||
});
|
||||
};
|
||||
309
lib/crypto/poly1305.js
Normal file
309
lib/crypto/poly1305.js
Normal file
@ -0,0 +1,309 @@
|
||||
/*!
|
||||
* poly1305.js - poly1305 for bcoin
|
||||
* Copyright (c) 2016-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var native = require('../utils/native').binding;
|
||||
|
||||
/**
|
||||
* Poly1305 (used for bip151)
|
||||
* @alias module:crypto.Poly1305
|
||||
* @constructor
|
||||
* @see https://github.com/floodyberry/poly1305-donna
|
||||
* @see https://tools.ietf.org/html/rfc7539#section-2.5
|
||||
*/
|
||||
|
||||
function Poly1305() {
|
||||
if (!(this instanceof Poly1305))
|
||||
return new Poly1305();
|
||||
|
||||
this.r = new Uint16Array(10);
|
||||
this.h = new Uint16Array(10);
|
||||
this.pad = new Uint16Array(8);
|
||||
this.fin = 0;
|
||||
this.leftover = 0;
|
||||
this.buffer = Buffer.allocUnsafe(16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize poly1305 with a key.
|
||||
* @param {Buffer} key
|
||||
*/
|
||||
|
||||
Poly1305.prototype.init = function init(key) {
|
||||
var t0, t1, t2, t3, t4, t5, t6, t7, i;
|
||||
|
||||
// r &= 0xffffffc0ffffffc0ffffffc0fffffff
|
||||
t0 = key.readUInt16LE(0, true);
|
||||
t1 = key.readUInt16LE(2, true);
|
||||
t2 = key.readUInt16LE(4, true);
|
||||
t3 = key.readUInt16LE(6, true);
|
||||
t4 = key.readUInt16LE(8, true);
|
||||
t5 = key.readUInt16LE(10, true);
|
||||
t6 = key.readUInt16LE(12, true);
|
||||
t7 = key.readUInt16LE(14, true);
|
||||
|
||||
this.r[0] = t0 & 0x1fff;
|
||||
this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff;
|
||||
this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03;
|
||||
this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff;
|
||||
this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff;
|
||||
this.r[5] = (t4 >>> 1) & 0x1ffe;
|
||||
this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff;
|
||||
this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81;
|
||||
this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff;
|
||||
this.r[9] = (t7 >>> 5) & 0x007f;
|
||||
|
||||
// h = 0
|
||||
for (i = 0; i < 10; i++)
|
||||
this.h[i] = 0;
|
||||
|
||||
// save pad for later
|
||||
for (i = 0; i < 8; i++)
|
||||
this.pad[i] = key.readUInt16LE(16 + (2 * i), true);
|
||||
|
||||
this.leftover = 0;
|
||||
this.fin = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Process 16 byte blocks.
|
||||
* @param {Buffer} data - Blocks.
|
||||
* @param {Number} bytes - Size.
|
||||
* @param {Number} m - Offset pointer.
|
||||
*/
|
||||
|
||||
Poly1305.prototype.blocks = function blocks(data, bytes, m) {
|
||||
var hibit = this.fin ? 0 : (1 << 11); // 1 << 128
|
||||
var d = new Uint32Array(10);
|
||||
var i, j, t0, t1, t2, t3, t4, t5, t6, t7, c;
|
||||
|
||||
while (bytes >= 16) {
|
||||
// h += m[i]
|
||||
t0 = data.readUInt16LE(m + 0, true);
|
||||
t1 = data.readUInt16LE(m + 2, true);
|
||||
t2 = data.readUInt16LE(m + 4, true);
|
||||
t3 = data.readUInt16LE(m + 6, true);
|
||||
t4 = data.readUInt16LE(m + 8, true);
|
||||
t5 = data.readUInt16LE(m + 10, true);
|
||||
t6 = data.readUInt16LE(m + 12, true);
|
||||
t7 = data.readUInt16LE(m + 14, true);
|
||||
|
||||
this.h[0] += t0 & 0x1fff;
|
||||
this.h[1] += ((t0 >>> 13) | (t1 << 3)) & 0x1fff;
|
||||
this.h[2] += ((t1 >>> 10) | (t2 << 6)) & 0x1fff;
|
||||
this.h[3] += ((t2 >>> 7) | (t3 << 9)) & 0x1fff;
|
||||
this.h[4] += ((t3 >>> 4) | (t4 << 12)) & 0x1fff;
|
||||
this.h[5] += ((t4 >>> 1)) & 0x1fff;
|
||||
this.h[6] += ((t4 >>> 14) | (t5 << 2)) & 0x1fff;
|
||||
this.h[7] += ((t5 >>> 11) | (t6 << 5)) & 0x1fff;
|
||||
this.h[8] += ((t6 >>> 8) | (t7 << 8)) & 0x1fff;
|
||||
this.h[9] += ((t7 >>> 5)) | hibit;
|
||||
|
||||
// h *= r, (partial) h %= p
|
||||
for (i = 0, c = 0; i < 10; i++) {
|
||||
d[i] = c;
|
||||
for (j = 0; j < 10; j++) {
|
||||
d[i] += this.h[j] * (j <= i
|
||||
? this.r[i - j]
|
||||
: 5 * this.r[i + 10 - j]);
|
||||
// Sum(h[i] * r[i] * 5) will overflow slightly
|
||||
// above 6 products with an unclamped r, so
|
||||
// carry at 5
|
||||
if (j === 4) {
|
||||
c = d[i] >>> 13;
|
||||
d[i] &= 0x1fff;
|
||||
}
|
||||
}
|
||||
c += d[i] >>> 13;
|
||||
d[i] &= 0x1fff;
|
||||
}
|
||||
c = (c << 2) + c; // c *= 5
|
||||
c += d[0];
|
||||
d[0] = (c & 0x1fff);
|
||||
c = c >>> 13;
|
||||
d[1] += c;
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
this.h[i] = d[i];
|
||||
|
||||
m += 16;
|
||||
bytes -= 16;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the MAC with data (will be
|
||||
* processed as 16 byte blocks).
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
Poly1305.prototype.update = function update(data) {
|
||||
var bytes = data.length;
|
||||
var m = 0;
|
||||
var i, want;
|
||||
|
||||
// handle leftover
|
||||
if (this.leftover) {
|
||||
want = 16 - this.leftover;
|
||||
if (want > bytes)
|
||||
want = bytes;
|
||||
for (i = 0; i < want; i++)
|
||||
this.buffer[this.leftover + i] = data[m + i];
|
||||
bytes -= want;
|
||||
m += want;
|
||||
this.leftover += want;
|
||||
if (this.leftover < 16)
|
||||
return;
|
||||
this.blocks(this.buffer, 16, 0);
|
||||
this.leftover = 0;
|
||||
}
|
||||
|
||||
// process full blocks
|
||||
if (bytes >= 16) {
|
||||
want = bytes & ~(16 - 1);
|
||||
this.blocks(data, want, m);
|
||||
m += want;
|
||||
bytes -= want;
|
||||
}
|
||||
|
||||
// store leftover
|
||||
if (bytes) {
|
||||
for (i = 0; i < bytes; i++)
|
||||
this.buffer[this.leftover + i] = data[m + i];
|
||||
this.leftover += bytes;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Finalize and return a 16-byte MAC.
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
Poly1305.prototype.finish = function finish() {
|
||||
var mac = Buffer.allocUnsafe(16);
|
||||
var g = new Uint16Array(10);
|
||||
var c, mask, f, i;
|
||||
|
||||
// process the remaining block
|
||||
if (this.leftover) {
|
||||
i = this.leftover;
|
||||
this.buffer[i++] = 1;
|
||||
for (; i < 16; i++)
|
||||
this.buffer[i] = 0;
|
||||
this.fin = 1;
|
||||
this.blocks(this.buffer, 16, 0);
|
||||
}
|
||||
|
||||
// fully carry h
|
||||
c = this.h[1] >>> 13;
|
||||
this.h[1] &= 0x1fff;
|
||||
for (i = 2; i < 10; i++) {
|
||||
this.h[i] += c;
|
||||
c = this.h[i] >>> 13;
|
||||
this.h[i] &= 0x1fff;
|
||||
}
|
||||
this.h[0] += c * 5;
|
||||
c = this.h[0] >>> 13;
|
||||
this.h[0] &= 0x1fff;
|
||||
this.h[1] += c;
|
||||
c = this.h[1] >>> 13;
|
||||
this.h[1] &= 0x1fff;
|
||||
this.h[2] += c;
|
||||
|
||||
// compute h + -p
|
||||
g[0] = this.h[0] + 5;
|
||||
c = g[0] >>> 13;
|
||||
g[0] &= 0x1fff;
|
||||
for (i = 1; i < 10; i++) {
|
||||
g[i] = this.h[i] + c;
|
||||
c = g[i] >>> 13;
|
||||
g[i] &= 0x1fff;
|
||||
}
|
||||
|
||||
// select h if h < p, or h + -p if h >= p
|
||||
mask = (c ^ 1) - 1;
|
||||
for (i = 0; i < 10; i++)
|
||||
g[i] &= mask;
|
||||
mask = ~mask;
|
||||
for (i = 0; i < 10; i++)
|
||||
this.h[i] = (this.h[i] & mask) | g[i];
|
||||
|
||||
// h = h % (2^128)
|
||||
this.h[0] = ((this.h[0]) | (this.h[1] << 13)) & 0xffff;
|
||||
this.h[1] = ((this.h[1] >>> 3) | (this.h[2] << 10)) & 0xffff;
|
||||
this.h[2] = ((this.h[2] >>> 6) | (this.h[3] << 7)) & 0xffff;
|
||||
this.h[3] = ((this.h[3] >>> 9) | (this.h[4] << 4)) & 0xffff;
|
||||
this.h[4] = ((this.h[4] >>> 12)
|
||||
| (this.h[5] << 1) | (this.h[6] << 14)) & 0xffff;
|
||||
this.h[5] = ((this.h[6] >>> 2) | (this.h[7] << 11)) & 0xffff;
|
||||
this.h[6] = ((this.h[7] >>> 5) | (this.h[8] << 8)) & 0xffff;
|
||||
this.h[7] = ((this.h[8] >>> 8) | (this.h[9] << 5)) & 0xffff;
|
||||
|
||||
// mac = (h + pad) % (2^128)
|
||||
f = this.h[0] + this.pad[0];
|
||||
this.h[0] = f;
|
||||
for (i = 1; i < 8; i++) {
|
||||
f = this.h[i] + this.pad[i] + (f >>> 16);
|
||||
this.h[i] = f;
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
mac.writeUInt16LE(this.h[i], i * 2, true);
|
||||
|
||||
// zero out the state
|
||||
for (i = 0; i < 10; i++)
|
||||
this.h[i] = 0;
|
||||
for (i = 0; i < 10; i++)
|
||||
this.r[i] = 0;
|
||||
for (i = 0; i < 8; i++)
|
||||
this.pad[i] = 0;
|
||||
|
||||
return mac;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a MAC for a message and key.
|
||||
* @param {Buffer} msg
|
||||
* @param {Buffer} key
|
||||
* @returns {Buffer} MAC
|
||||
*/
|
||||
|
||||
Poly1305.auth = function auth(msg, key) {
|
||||
var poly = new Poly1305();
|
||||
poly.init(key);
|
||||
poly.update(msg);
|
||||
return poly.finish();
|
||||
};
|
||||
|
||||
/**
|
||||
* Compare two MACs in constant time.
|
||||
* @param {Buffer} mac1
|
||||
* @param {Buffer} mac2
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
Poly1305.verify = function verify(mac1, mac2) {
|
||||
var dif = 0;
|
||||
var i;
|
||||
|
||||
// Compare in constant time.
|
||||
for (i = 0; i < 16; i++)
|
||||
dif |= mac1[i] ^ mac2[i];
|
||||
|
||||
dif = (dif - 1) >>> 31;
|
||||
|
||||
return (dif & 1) !== 0;
|
||||
};
|
||||
|
||||
if (native)
|
||||
Poly1305 = native.Poly1305;
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
module.exports = Poly1305;
|
||||
64
lib/crypto/random-browser.js
Normal file
64
lib/crypto/random-browser.js
Normal file
@ -0,0 +1,64 @@
|
||||
/*!
|
||||
* random-browser.js - randomness for bcoin
|
||||
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @module crypto.random-browser
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
var crypto = global.crypto || global.msCrypto || {};
|
||||
|
||||
/**
|
||||
* Generate some random bytes.
|
||||
* @param {Number} size
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.randomBytes = function randomBytes(n) {
|
||||
var data = new Uint8Array(n);
|
||||
crypto.getRandomValues(data);
|
||||
return Buffer.from(data.buffer);
|
||||
};
|
||||
|
||||
if (!crypto.getRandomValues) {
|
||||
// Out of luck here. Use bad randomness for now.
|
||||
exports.randomBytes = function randomBytes(n) {
|
||||
var data = Buffer.allocUnsafe(n);
|
||||
var i;
|
||||
|
||||
for (i = 0; i < data.length; i++)
|
||||
data[i] = Math.floor(Math.random() * 256);
|
||||
|
||||
return data;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random uint32.
|
||||
* Probably more cryptographically sound than
|
||||
* `Math.random()`.
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
exports.randomInt = function randomInt() {
|
||||
return exports.randomBytes(4).readUInt32LE(0, true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a random number within a range.
|
||||
* Probably more cryptographically sound than
|
||||
* `Math.random()`.
|
||||
* @param {Number} min - Inclusive.
|
||||
* @param {Number} max - Exclusive.
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
exports.randomRange = function randomRange(min, max) {
|
||||
var num = exports.randomInt();
|
||||
return Math.floor((num / 0x100000000) * (max - min) + min);
|
||||
};
|
||||
44
lib/crypto/random.js
Normal file
44
lib/crypto/random.js
Normal file
@ -0,0 +1,44 @@
|
||||
/*!
|
||||
* random.js - randomness for bcoin
|
||||
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @module crypto.random
|
||||
*/
|
||||
|
||||
var crypto = require('crypto');
|
||||
|
||||
/*
|
||||
* Misc
|
||||
*/
|
||||
|
||||
exports.randomBytes = crypto.randomBytes;
|
||||
|
||||
/**
|
||||
* Generate a random uint32.
|
||||
* Probably more cryptographically sound than
|
||||
* `Math.random()`.
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
exports.randomInt = function randomInt() {
|
||||
return exports.randomBytes(4).readUInt32LE(0, true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a random number within a range.
|
||||
* Probably more cryptographically sound than
|
||||
* `Math.random()`.
|
||||
* @param {Number} min - Inclusive.
|
||||
* @param {Number} max - Exclusive.
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
exports.randomRange = function randomRange(min, max) {
|
||||
var num = exports.randomInt();
|
||||
return Math.floor((num / 0x100000000) * (max - min) + min);
|
||||
};
|
||||
@ -9,7 +9,8 @@
|
||||
var assert = require('assert');
|
||||
var BN = require('./bn');
|
||||
var ASN1 = require('../utils/asn1');
|
||||
var backend = require('./backend');
|
||||
var digest = require('./digest');
|
||||
var ccmp = require('./ccmp');
|
||||
|
||||
/**
|
||||
* @exports crypto/rsa
|
||||
@ -55,7 +56,7 @@ rsa.verify = function verify(alg, msg, sig, key) {
|
||||
if (!prefix)
|
||||
throw new Error('Unknown PKCS prefix.');
|
||||
|
||||
hash = backend.hash(alg, msg);
|
||||
hash = digest.hash(alg, msg);
|
||||
len = prefix.length + hash.length;
|
||||
pub = ASN1.parseRSAPublic(key);
|
||||
|
||||
@ -71,8 +72,8 @@ rsa.verify = function verify(alg, msg, sig, key) {
|
||||
|
||||
ok = ceq(em[0], 0x00);
|
||||
ok &= ceq(em[1], 0x01);
|
||||
ok &= backend.ccmp(em.slice(k - hash.length, k), hash);
|
||||
ok &= backend.ccmp(em.slice(k - len, k - hash.length), prefix);
|
||||
ok &= ccmp(em.slice(k - hash.length, k), hash);
|
||||
ok &= ccmp(em.slice(k - len, k - hash.length), prefix);
|
||||
ok &= ceq(em[k - len - 1], 0x00);
|
||||
|
||||
for (i = 2; i < k - len - 1; i++)
|
||||
@ -101,7 +102,7 @@ rsa.sign = function sign(alg, msg, key) {
|
||||
if (!prefix)
|
||||
throw new Error('Unknown PKCS prefix.');
|
||||
|
||||
hash = backend.hash(alg, msg);
|
||||
hash = digest.hash(alg, msg);
|
||||
len = prefix.length + hash.length;
|
||||
priv = ASN1.parseRSAPrivate(key);
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ var elliptic = require('elliptic');
|
||||
var Signature = require('elliptic/lib/elliptic/ec/signature');
|
||||
var BN = require('./bn');
|
||||
var HmacDRBG = require('./hmac-drbg');
|
||||
var sha256 = require('./backend').sha256;
|
||||
var sha256 = require('./digest').sha256;
|
||||
var curve = elliptic.ec('secp256k1').curve;
|
||||
var POOL64 = Buffer.allocUnsafe(64);
|
||||
|
||||
|
||||
@ -35,19 +35,17 @@
|
||||
|
||||
/**
|
||||
* @module crypto/scrypt
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
var co = require('../utils/co');
|
||||
var backend = require('./backend');
|
||||
var pbkdf2 = require('./pbkdf2');
|
||||
var native = require('../utils/native').binding;
|
||||
var U32Array = typeof Uint32Array === 'function' ? Uint32Array : Array;
|
||||
|
||||
/**
|
||||
* Javascript scrypt implementation. Scrypt is
|
||||
* used in bip38. Bcoin doesn't support bip38
|
||||
* yet, but here it is, just in case.
|
||||
* @alias module:crypto/scrypt.scrypt
|
||||
* @alias module:crypto/scrypt.derive
|
||||
* @param {Buffer} passwd
|
||||
* @param {Buffer} salt
|
||||
* @param {Number} N
|
||||
@ -57,7 +55,7 @@ var U32Array = typeof Uint32Array === 'function' ? Uint32Array : Array;
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
function scrypt(passwd, salt, N, r, p, len) {
|
||||
function derive(passwd, salt, N, r, p, len) {
|
||||
var i, B, V, XY;
|
||||
|
||||
if (r * p >= (1 << 30))
|
||||
@ -72,20 +70,63 @@ function scrypt(passwd, salt, N, r, p, len) {
|
||||
XY = Buffer.allocUnsafe(256 * r);
|
||||
V = Buffer.allocUnsafe(128 * r * N);
|
||||
|
||||
B = backend.pbkdf2(passwd, salt, 1, p * 128 * r, 'sha256');
|
||||
B = pbkdf2.derive(passwd, salt, 1, p * 128 * r, 'sha256');
|
||||
|
||||
for (i = 0; i < p; i++)
|
||||
smix(B, i * 128 * r, r, N, V, XY);
|
||||
|
||||
return backend.pbkdf2(passwd, B, 1, len, 'sha256');
|
||||
return pbkdf2.derive(passwd, B, 1, len, 'sha256');
|
||||
}
|
||||
|
||||
if (native)
|
||||
scrypt = native.scrypt;
|
||||
derive = native.scrypt;
|
||||
|
||||
/**
|
||||
* Asynchronous scrypt implementation.
|
||||
* @alias module:crypto/scrypt.deriveAsync
|
||||
* @function
|
||||
* @param {Buffer} passwd
|
||||
* @param {Buffer} salt
|
||||
* @param {Number} N
|
||||
* @param {Number} r
|
||||
* @param {Number} p
|
||||
* @param {Number} len
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
async function deriveAsync(passwd, salt, N, r, p, len) {
|
||||
var i, B, V, XY;
|
||||
|
||||
if (r * p >= (1 << 30))
|
||||
throw new Error('EFBIG');
|
||||
|
||||
if ((N & (N - 1)) !== 0 || N === 0)
|
||||
throw new Error('EINVAL');
|
||||
|
||||
if (N > 0xffffffff)
|
||||
throw new Error('EINVAL');
|
||||
|
||||
XY = Buffer.allocUnsafe(256 * r);
|
||||
V = Buffer.allocUnsafe(128 * r * N);
|
||||
|
||||
B = await pbkdf2.deriveAsync(passwd, salt, 1, p * 128 * r, 'sha256');
|
||||
|
||||
for (i = 0; i < p; i++)
|
||||
await smixAsync(B, i * 128 * r, r, N, V, XY);
|
||||
|
||||
return await pbkdf2.deriveAsync(passwd, B, 1, len, 'sha256');
|
||||
}
|
||||
|
||||
if (native)
|
||||
deriveAsync = native.scryptAsync;
|
||||
|
||||
/*
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function salsa20_8(B) {
|
||||
var B32 = new U32Array(16);
|
||||
var x = new U32Array(16);
|
||||
var B32 = new Uint32Array(16);
|
||||
var x = new Uint32Array(16);
|
||||
var i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
@ -192,54 +233,6 @@ function smix(B, Bo, r, N, V, XY) {
|
||||
blkcpy(B, X, Bo, 0, 128 * r);
|
||||
}
|
||||
|
||||
function blkcpy(dest, src, s1, s2, len) {
|
||||
src.copy(dest, s1, s2, s2 + len);
|
||||
}
|
||||
|
||||
function blkxor(dest, src, s1, s2, len) {
|
||||
for (var i = 0; i < len; i++)
|
||||
dest[s1 + i] ^= src[s2 + i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronous scrypt implementation.
|
||||
* @alias module:crypto/scrypt.scryptAsync
|
||||
* @function
|
||||
* @param {Buffer} passwd
|
||||
* @param {Buffer} salt
|
||||
* @param {Number} N
|
||||
* @param {Number} r
|
||||
* @param {Number} p
|
||||
* @param {Number} len
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
async function scryptAsync(passwd, salt, N, r, p, len) {
|
||||
var i, B, V, XY;
|
||||
|
||||
if (r * p >= (1 << 30))
|
||||
throw new Error('EFBIG');
|
||||
|
||||
if ((N & (N - 1)) !== 0 || N === 0)
|
||||
throw new Error('EINVAL');
|
||||
|
||||
if (N > 0xffffffff)
|
||||
throw new Error('EINVAL');
|
||||
|
||||
XY = Buffer.allocUnsafe(256 * r);
|
||||
V = Buffer.allocUnsafe(128 * r * N);
|
||||
|
||||
B = await backend.pbkdf2Async(passwd, salt, 1, p * 128 * r, 'sha256');
|
||||
|
||||
for (i = 0; i < p; i++)
|
||||
await smixAsync(B, i * 128 * r, r, N, V, XY);
|
||||
|
||||
return await backend.pbkdf2Async(passwd, B, 1, len, 'sha256');
|
||||
}
|
||||
|
||||
if (native)
|
||||
scryptAsync = native.scryptAsync;
|
||||
|
||||
async function smixAsync(B, Bo, r, N, V, XY) {
|
||||
var X = XY;
|
||||
var Y = XY;
|
||||
@ -264,12 +257,18 @@ async function smixAsync(B, Bo, r, N, V, XY) {
|
||||
blkcpy(B, X, Bo, 0, 128 * r);
|
||||
}
|
||||
|
||||
function blkcpy(dest, src, s1, s2, len) {
|
||||
src.copy(dest, s1, s2, s2 + len);
|
||||
}
|
||||
|
||||
function blkxor(dest, src, s1, s2, len) {
|
||||
for (var i = 0; i < len; i++)
|
||||
dest[s1 + i] ^= src[s2 + i];
|
||||
}
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
exports = scrypt;
|
||||
exports.scrypt = scrypt;
|
||||
exports.scryptAsync = scryptAsync;
|
||||
|
||||
module.exports = exports;
|
||||
exports.derive = derive;
|
||||
exports.deriveAsync = deriveAsync;
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var backend = require('./backend');
|
||||
var random = require('./random');
|
||||
var secp256k1 = require('secp256k1');
|
||||
|
||||
/**
|
||||
@ -47,7 +47,7 @@ ec.generatePrivateKey = function generatePrivateKey() {
|
||||
var priv;
|
||||
|
||||
do {
|
||||
priv = backend.randomBytes(32);
|
||||
priv = random.randomBytes(32);
|
||||
} while (!secp256k1.privateKeyVerify(priv));
|
||||
|
||||
return priv;
|
||||
|
||||
@ -1,3 +1,9 @@
|
||||
/*!
|
||||
* hd/index.js - hd keys for bcoin
|
||||
* Copyright (c) 2014-2016, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = require('./hd');
|
||||
|
||||
@ -8,7 +8,10 @@
|
||||
|
||||
var assert = require('assert');
|
||||
var util = require('../utils/util');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var cleanse = require('../crypto/cleanse');
|
||||
var random = require('../crypto/random');
|
||||
var pbkdf2 = require('../crypto/pbkdf2');
|
||||
var StaticWriter = require('../utils/staticwriter');
|
||||
var BufferReader = require('../utils/reader');
|
||||
var encoding = require('../utils/encoding');
|
||||
@ -123,7 +126,7 @@ Mnemonic.prototype.destroy = function destroy() {
|
||||
this.bits = common.MIN_ENTROPY;
|
||||
this.language = 'english';
|
||||
if (this.entropy) {
|
||||
crypto.cleanse(this.entropy);
|
||||
cleanse(this.entropy);
|
||||
this.entropy = null;
|
||||
}
|
||||
this.phrase = null;
|
||||
@ -147,7 +150,7 @@ Mnemonic.prototype.toSeed = function toSeed(passphrase) {
|
||||
phrase = nfkd(this.getPhrase());
|
||||
passwd = nfkd('mnemonic' + passphrase);
|
||||
|
||||
return crypto.pbkdf2(
|
||||
return pbkdf2.derive(
|
||||
Buffer.from(phrase, 'utf8'),
|
||||
Buffer.from(passwd, 'utf8'),
|
||||
2048, 64, 'sha512');
|
||||
@ -160,7 +163,7 @@ Mnemonic.prototype.toSeed = function toSeed(passphrase) {
|
||||
|
||||
Mnemonic.prototype.getEntropy = function getEntropy() {
|
||||
if (!this.entropy)
|
||||
this.entropy = crypto.randomBytes(this.bits / 8);
|
||||
this.entropy = random.randomBytes(this.bits / 8);
|
||||
|
||||
assert(this.bits / 8 === this.entropy.length);
|
||||
|
||||
@ -194,7 +197,7 @@ Mnemonic.prototype.getPhrase = function getPhrase() {
|
||||
// the checksum bits.
|
||||
entropy = Buffer.allocUnsafe(Math.ceil(bits / 8));
|
||||
ent.copy(entropy, 0);
|
||||
crypto.sha256(ent).copy(entropy, ent.length);
|
||||
digest.sha256(ent).copy(entropy, ent.length);
|
||||
|
||||
// Build the mnemonic by reading
|
||||
// 11 bit indexes from the entropy.
|
||||
@ -268,7 +271,7 @@ Mnemonic.prototype.fromPhrase = function fromPhrase(phrase) {
|
||||
|
||||
entropy = ent.slice(0, ent.length - cbytes);
|
||||
ent = ent.slice(ent.length - cbytes);
|
||||
chk = crypto.sha256(entropy);
|
||||
chk = digest.sha256(entropy);
|
||||
|
||||
for (i = 0; i < cbits; i++) {
|
||||
bit = i % 8;
|
||||
|
||||
@ -8,7 +8,9 @@
|
||||
|
||||
var assert = require('assert');
|
||||
var util = require('../utils/util');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var cleanse = require('../crypto/cleanse');
|
||||
var random = require('../crypto/random');
|
||||
var secp256k1 = require('../crypto/secp256k1');
|
||||
var Network = require('../protocol/network');
|
||||
var StaticWriter = require('../utils/staticwriter');
|
||||
@ -149,13 +151,13 @@ HDPrivateKey.prototype.destroy = function destroy(pub) {
|
||||
this.depth = 0;
|
||||
this.childIndex = 0;
|
||||
|
||||
crypto.cleanse(this.parentFingerPrint);
|
||||
crypto.cleanse(this.chainCode);
|
||||
crypto.cleanse(this.privateKey);
|
||||
crypto.cleanse(this.publicKey);
|
||||
cleanse(this.parentFingerPrint);
|
||||
cleanse(this.chainCode);
|
||||
cleanse(this.privateKey);
|
||||
cleanse(this.publicKey);
|
||||
|
||||
if (this.fingerPrint) {
|
||||
crypto.cleanse(this.fingerPrint);
|
||||
cleanse(this.fingerPrint);
|
||||
this.fingerPrint = null;
|
||||
}
|
||||
|
||||
@ -208,7 +210,7 @@ HDPrivateKey.prototype.derive = function derive(index, hardened) {
|
||||
|
||||
data = bw.render();
|
||||
|
||||
hash = crypto.hmac('sha512', data, this.chainCode);
|
||||
hash = digest.hmac('sha512', data, this.chainCode);
|
||||
left = hash.slice(0, 32);
|
||||
right = hash.slice(32, 64);
|
||||
|
||||
@ -219,7 +221,7 @@ HDPrivateKey.prototype.derive = function derive(index, hardened) {
|
||||
}
|
||||
|
||||
if (!this.fingerPrint)
|
||||
this.fingerPrint = crypto.hash160(this.publicKey).slice(0, 4);
|
||||
this.fingerPrint = digest.hash160(this.publicKey).slice(0, 4);
|
||||
|
||||
child = new HDPrivateKey();
|
||||
child.network = this.network;
|
||||
@ -465,7 +467,7 @@ HDPrivateKey.prototype.fromSeed = function fromSeed(seed, network) {
|
||||
throw new Error('Entropy not in range.');
|
||||
}
|
||||
|
||||
hash = crypto.hmac('sha512', seed, common.SEED_SALT);
|
||||
hash = digest.hmac('sha512', seed, common.SEED_SALT);
|
||||
left = hash.slice(0, 32);
|
||||
right = hash.slice(32, 64);
|
||||
|
||||
@ -583,7 +585,7 @@ HDPrivateKey.fromKey = function fromKey(key, entropy, network) {
|
||||
|
||||
HDPrivateKey.generate = function generate(network) {
|
||||
var key = secp256k1.generatePrivateKey();
|
||||
var entropy = crypto.randomBytes(32);
|
||||
var entropy = random.randomBytes(32);
|
||||
return HDPrivateKey.fromKey(key, entropy, network);
|
||||
};
|
||||
|
||||
|
||||
@ -8,7 +8,8 @@
|
||||
|
||||
var assert = require('assert');
|
||||
var util = require('../utils/util');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var cleanse = require('../crypto/cleanse');
|
||||
var secp256k1 = require('../crypto/secp256k1');
|
||||
var Network = require('../protocol/network');
|
||||
var StaticWriter = require('../utils/staticwriter');
|
||||
@ -129,12 +130,12 @@ HDPublicKey.prototype.destroy = function destroy() {
|
||||
this.depth = 0;
|
||||
this.childIndex = 0;
|
||||
|
||||
crypto.cleanse(this.parentFingerPrint);
|
||||
crypto.cleanse(this.chainCode);
|
||||
crypto.cleanse(this.publicKey);
|
||||
cleanse(this.parentFingerPrint);
|
||||
cleanse(this.chainCode);
|
||||
cleanse(this.publicKey);
|
||||
|
||||
if (this.fingerPrint) {
|
||||
crypto.cleanse(this.fingerPrint);
|
||||
cleanse(this.fingerPrint);
|
||||
this.fingerPrint = null;
|
||||
}
|
||||
|
||||
@ -175,7 +176,7 @@ HDPublicKey.prototype.derive = function derive(index, hardened) {
|
||||
bw.writeU32BE(index);
|
||||
data = bw.render();
|
||||
|
||||
hash = crypto.hmac('sha512', data, this.chainCode);
|
||||
hash = digest.hmac('sha512', data, this.chainCode);
|
||||
left = hash.slice(0, 32);
|
||||
right = hash.slice(32, 64);
|
||||
|
||||
@ -186,7 +187,7 @@ HDPublicKey.prototype.derive = function derive(index, hardened) {
|
||||
}
|
||||
|
||||
if (!this.fingerPrint)
|
||||
this.fingerPrint = crypto.hash160(this.publicKey).slice(0, 4);
|
||||
this.fingerPrint = digest.hash160(this.publicKey).slice(0, 4);
|
||||
|
||||
child = new HDPublicKey();
|
||||
child.network = this.network;
|
||||
|
||||
@ -19,7 +19,8 @@ var co = require('../utils/co');
|
||||
var Validator = require('../utils/validator');
|
||||
var List = require('../utils/list');
|
||||
var fs = require('../utils/fs');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var ccmp = require('../crypto/ccmp');
|
||||
var ListItem = List.Item;
|
||||
|
||||
/**
|
||||
@ -198,14 +199,14 @@ HTTPBase.prototype.basicAuth = function basicAuth(options) {
|
||||
if (typeof user === 'string')
|
||||
user = Buffer.from(user, 'utf8');
|
||||
assert(Buffer.isBuffer(user));
|
||||
user = crypto.hash256(user);
|
||||
user = digest.hash256(user);
|
||||
}
|
||||
|
||||
if (typeof pass === 'string')
|
||||
pass = Buffer.from(pass, 'utf8');
|
||||
|
||||
assert(Buffer.isBuffer(pass));
|
||||
pass = crypto.hash256(pass);
|
||||
pass = digest.hash256(pass);
|
||||
|
||||
if (!realm)
|
||||
realm = 'server';
|
||||
@ -220,7 +221,7 @@ HTTPBase.prototype.basicAuth = function basicAuth(options) {
|
||||
|
||||
return async function(req, res) {
|
||||
var auth = req.headers['authorization'];
|
||||
var parts, username, password, digest;
|
||||
var parts, username, password, hash;
|
||||
|
||||
if (!auth)
|
||||
return fail(res);
|
||||
@ -240,17 +241,17 @@ HTTPBase.prototype.basicAuth = function basicAuth(options) {
|
||||
password = parts.join(':');
|
||||
|
||||
if (user) {
|
||||
digest = Buffer.from(username, 'utf8');
|
||||
digest = crypto.hash256(digest);
|
||||
hash = Buffer.from(username, 'utf8');
|
||||
hash = digest.hash256(hash);
|
||||
|
||||
if (!crypto.ccmp(digest, user))
|
||||
if (!ccmp(hash, user))
|
||||
return fail(res);
|
||||
}
|
||||
|
||||
digest = Buffer.from(password, 'utf8');
|
||||
digest = crypto.hash256(digest);
|
||||
hash = Buffer.from(password, 'utf8');
|
||||
hash = digest.hash256(hash);
|
||||
|
||||
if (!crypto.ccmp(digest, pass))
|
||||
if (!ccmp(hash, pass))
|
||||
return fail(res);
|
||||
|
||||
req.username = username;
|
||||
|
||||
@ -8,7 +8,8 @@
|
||||
|
||||
var util = require('../utils/util');
|
||||
var co = require('../utils/co');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var ccmp = require('../crypto/ccmp');
|
||||
var assert = require('assert');
|
||||
var common = require('../blockchain/common');
|
||||
var secp256k1 = require('../crypto/secp256k1');
|
||||
@ -2065,16 +2066,16 @@ RPC.prototype.verifyMessage = async function verifyMessage(args, help) {
|
||||
addr = parseAddress(b58, this.network);
|
||||
|
||||
msg = Buffer.from(MAGIC_STRING + msg, 'utf8');
|
||||
msg = crypto.hash256(msg);
|
||||
msg = digest.hash256(msg);
|
||||
|
||||
key = secp256k1.recover(msg, sig, 0, true);
|
||||
|
||||
if (!key)
|
||||
return false;
|
||||
|
||||
key = crypto.hash160(key);
|
||||
key = digest.hash160(key);
|
||||
|
||||
return crypto.ccmp(key, addr.hash);
|
||||
return ccmp(key, addr.hash);
|
||||
};
|
||||
|
||||
RPC.prototype.signMessageWithPrivkey = async function signMessageWithPrivkey(args, help) {
|
||||
@ -2090,7 +2091,7 @@ RPC.prototype.signMessageWithPrivkey = async function signMessageWithPrivkey(arg
|
||||
|
||||
key = parseSecret(key, this.network);
|
||||
msg = Buffer.from(MAGIC_STRING + msg, 'utf8');
|
||||
msg = crypto.hash256(msg);
|
||||
msg = digest.hash256(msg);
|
||||
|
||||
sig = key.sign(msg);
|
||||
|
||||
|
||||
@ -15,7 +15,9 @@ var Amount = require('../btc/amount');
|
||||
var Bloom = require('../utils/bloom');
|
||||
var TX = require('../primitives/tx');
|
||||
var Outpoint = require('../primitives/outpoint');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var random = require('../crypto/random');
|
||||
var ccmp = require('../crypto/ccmp');
|
||||
var Network = require('../protocol/network');
|
||||
var Validator = require('../utils/validator');
|
||||
var pkg = require('../pkg');
|
||||
@ -389,7 +391,7 @@ HTTPServer.prototype.handleSocket = function handleSocket(socket) {
|
||||
throw new Error('Already authed.');
|
||||
|
||||
if (!this.options.noAuth) {
|
||||
if (!crypto.ccmp(hash256(key), hash))
|
||||
if (!ccmp(hash256(key), hash))
|
||||
throw new Error('Bad key.');
|
||||
}
|
||||
|
||||
@ -739,7 +741,7 @@ function HTTPOptions(options) {
|
||||
this.network = Network.primary;
|
||||
this.logger = null;
|
||||
this.node = null;
|
||||
this.apiKey = base58.encode(crypto.randomBytes(20));
|
||||
this.apiKey = base58.encode(random.randomBytes(20));
|
||||
this.apiHash = hash256(this.apiKey);
|
||||
this.noAuth = false;
|
||||
|
||||
@ -854,7 +856,7 @@ function hash256(data) {
|
||||
if (data.length > 200)
|
||||
return Buffer.alloc(0);
|
||||
|
||||
return crypto.hash256(Buffer.from(data, 'utf8'));
|
||||
return digest.hash256(Buffer.from(data, 'utf8'));
|
||||
}
|
||||
|
||||
function enforce(value, msg) {
|
||||
|
||||
@ -11,7 +11,7 @@ var AsyncObject = require('../utils/asyncobject');
|
||||
var common = require('../blockchain/common');
|
||||
var policy = require('../protocol/policy');
|
||||
var util = require('../utils/util');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var random = require('../crypto/random');
|
||||
var errors = require('../protocol/errors');
|
||||
var Bloom = require('../utils/bloom');
|
||||
var Address = require('../primitives/address');
|
||||
@ -1667,7 +1667,7 @@ Mempool.prototype.limitOrphans = function limitOrphans() {
|
||||
if (this.totalOrphans < this.options.maxOrphans)
|
||||
return false;
|
||||
|
||||
index = crypto.randomRange(0, hashes.length);
|
||||
index = random.randomRange(0, hashes.length);
|
||||
hash = hashes[index];
|
||||
|
||||
this.logger.debug('Removing orphan %s from mempool.', util.revHex(hash));
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
|
||||
/**
|
||||
* Hash until the nonce overflows.
|
||||
@ -27,7 +27,7 @@ function mine(data, target, min, max) {
|
||||
// The heart and soul of the miner: match the target.
|
||||
while (nonce <= max) {
|
||||
// Hash and test against the next target.
|
||||
if (rcmp(crypto.hash256(data), target) <= 0)
|
||||
if (rcmp(digest.hash256(data), target) <= 0)
|
||||
return nonce;
|
||||
|
||||
// Increment the nonce to get a different hash.
|
||||
|
||||
@ -9,7 +9,8 @@
|
||||
|
||||
var assert = require('assert');
|
||||
var util = require('../utils/util');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var merkle = require('../crypto/merkle');
|
||||
var BN = require('../crypto/bn');
|
||||
var StaticWriter = require('../utils/staticwriter');
|
||||
var Address = require('../primitives/address');
|
||||
@ -181,13 +182,13 @@ BlockTemplate.prototype.getWitnessHash = function getWitnessHash() {
|
||||
leaves.push(item.tx.witnessHash());
|
||||
}
|
||||
|
||||
root = crypto.createMerkleRoot(leaves);
|
||||
root = merkle.createRoot(leaves);
|
||||
|
||||
assert(!root.malleated);
|
||||
|
||||
data = util.concat(root.hash, nonce);
|
||||
|
||||
return crypto.hash256(data);
|
||||
return digest.hash256(data);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -389,7 +390,7 @@ BlockTemplate.prototype.getRawCoinbase = function getRawCoinbase(nonce1, nonce2)
|
||||
|
||||
BlockTemplate.prototype.getRoot = function getRoot(nonce1, nonce2) {
|
||||
var raw = this.getRawCoinbase(nonce1, nonce2);
|
||||
var hash = crypto.hash256(raw);
|
||||
var hash = digest.hash256(raw);
|
||||
return this.tree.withFirst(hash);
|
||||
};
|
||||
|
||||
@ -426,7 +427,7 @@ BlockTemplate.prototype.getHeader = function getHeader(root, ts, nonce) {
|
||||
BlockTemplate.prototype.getProof = function getProof(nonce1, nonce2, ts, nonce) {
|
||||
var root = this.getRoot(nonce1, nonce2);
|
||||
var data = this.getHeader(root, ts, nonce);
|
||||
var hash = crypto.hash256(data);
|
||||
var hash = digest.hash256(data);
|
||||
return new BlockProof(hash, root, nonce1, nonce2, ts, nonce);
|
||||
};
|
||||
|
||||
@ -705,7 +706,7 @@ MerkleTree.prototype.withFirst = function withFirst(hash) {
|
||||
for (i = 0; i < this.steps.length; i++) {
|
||||
step = this.steps[i];
|
||||
data = util.concat(hash, step);
|
||||
hash = crypto.hash256(data);
|
||||
hash = digest.hash256(data);
|
||||
}
|
||||
|
||||
return hash;
|
||||
@ -773,7 +774,7 @@ MerkleTree.prototype.fromLeaves = function fromLeaves(leaves) {
|
||||
|
||||
for (i = 2; i < len; i += 2) {
|
||||
data = util.concat(leaves[i], leaves[i + 1]);
|
||||
hash = crypto.hash256(data);
|
||||
hash = digest.hash256(data);
|
||||
hashes.push(hash);
|
||||
}
|
||||
|
||||
|
||||
@ -13,7 +13,9 @@ var path = require('path');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var util = require('../utils/util');
|
||||
var co = require('../utils/co');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var random = require('../crypto/random');
|
||||
var ccmp = require('../crypto/ccmp');
|
||||
var packets = require('./packets');
|
||||
var secp256k1 = require('../crypto/secp256k1');
|
||||
var StaticWriter = require('../utils/staticwriter');
|
||||
@ -131,7 +133,7 @@ BIP150.prototype.challenge = function challenge(hash) {
|
||||
|
||||
msg = this.hash(this.input.sid, type, this.publicKey);
|
||||
|
||||
if (!crypto.ccmp(hash, msg))
|
||||
if (!ccmp(hash, msg))
|
||||
return encoding.ZERO_SIG64;
|
||||
|
||||
if (this.isAuthed()) {
|
||||
@ -165,7 +167,7 @@ BIP150.prototype.reply = function reply(data) {
|
||||
throw new Error('Auth failure.');
|
||||
|
||||
if (!this.peerIdentity)
|
||||
return crypto.randomBytes(32);
|
||||
return random.randomBytes(32);
|
||||
|
||||
sig = secp256k1.toDER(data);
|
||||
msg = this.hash(this.output.sid, type, this.peerIdentity);
|
||||
@ -173,7 +175,7 @@ BIP150.prototype.reply = function reply(data) {
|
||||
result = secp256k1.verify(msg, sig, this.peerIdentity);
|
||||
|
||||
if (!result)
|
||||
return crypto.randomBytes(32);
|
||||
return random.randomBytes(32);
|
||||
|
||||
if (this.isAuthed()) {
|
||||
this.auth = true;
|
||||
@ -257,7 +259,7 @@ BIP150.prototype.rekey = function rekey(sid, key, req, res) {
|
||||
key.copy(seed, 32);
|
||||
req.copy(seed, 64);
|
||||
res.copy(seed, 97);
|
||||
return crypto.hash256(seed);
|
||||
return digest.hash256(seed);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -301,7 +303,7 @@ BIP150.prototype.hash = function hash(sid, ch, key) {
|
||||
sid.copy(data, 0);
|
||||
data[32] = ch.charCodeAt(0);
|
||||
key.copy(data, 33);
|
||||
return crypto.hash256(data);
|
||||
return digest.hash256(data);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -325,7 +327,7 @@ BIP150.prototype.findAuthorized = function findAuthorized(hash) {
|
||||
// XXX Do we really need a constant
|
||||
// time compare here? Do it just to
|
||||
// be safe I guess.
|
||||
if (crypto.ccmp(msg, hash))
|
||||
if (ccmp(msg, hash))
|
||||
return key;
|
||||
}
|
||||
};
|
||||
@ -454,7 +456,7 @@ BIP150.address = function address(key) {
|
||||
var bw = new StaticWriter(27);
|
||||
bw.writeU8(0x0f);
|
||||
bw.writeU16BE(0xff01);
|
||||
bw.writeBytes(crypto.hash160(key));
|
||||
bw.writeBytes(digest.hash160(key));
|
||||
bw.writeChecksum();
|
||||
return base58.encode(bw.render());
|
||||
};
|
||||
|
||||
@ -12,14 +12,17 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var util = require('../utils/util');
|
||||
var co = require('../utils/co');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var assert = require('assert');
|
||||
var chachapoly = require('../crypto/chachapoly');
|
||||
var packets = require('./packets');
|
||||
var digest = require('../crypto/digest');
|
||||
var ChaCha20 = require('../crypto/chacha20');
|
||||
var Poly1305 = require('../crypto/poly1305');
|
||||
var AEAD = require('../crypto/aead');
|
||||
var hkdf = require('../crypto/hkdf');
|
||||
var secp256k1 = require('../crypto/secp256k1');
|
||||
var packets = require('./packets');
|
||||
var StaticWriter = require('../utils/staticwriter');
|
||||
var BufferReader = require('../utils/reader');
|
||||
var encoding = require('../utils/encoding');
|
||||
@ -74,8 +77,8 @@ function BIP151Stream(cipher) {
|
||||
this.cipher = cipher;
|
||||
}
|
||||
|
||||
this.chacha = new chachapoly.ChaCha20();
|
||||
this.aead = new chachapoly.AEAD();
|
||||
this.chacha = new ChaCha20();
|
||||
this.aead = new AEAD();
|
||||
this.tag = null;
|
||||
this.seq = 0;
|
||||
this.iv = Buffer.allocUnsafe(8);
|
||||
@ -100,10 +103,10 @@ BIP151Stream.prototype.init = function init(publicKey) {
|
||||
bw.writeBytes(this.secret);
|
||||
bw.writeU8(this.cipher);
|
||||
|
||||
this.prk = crypto.hkdfExtract(bw.render(), HKDF_SALT, 'sha256');
|
||||
this.k1 = crypto.hkdfExpand(this.prk, INFO_KEY1, 32, 'sha256');
|
||||
this.k2 = crypto.hkdfExpand(this.prk, INFO_KEY2, 32, 'sha256');
|
||||
this.sid = crypto.hkdfExpand(this.prk, INFO_SID, 32, 'sha256');
|
||||
this.prk = hkdf.extract(bw.render(), HKDF_SALT, 'sha256');
|
||||
this.k1 = hkdf.expand(this.prk, INFO_KEY1, 32, 'sha256');
|
||||
this.k2 = hkdf.expand(this.prk, INFO_KEY2, 32, 'sha256');
|
||||
this.sid = hkdf.expand(this.prk, INFO_SID, 32, 'sha256');
|
||||
|
||||
this.seq = 0;
|
||||
|
||||
@ -153,10 +156,10 @@ BIP151Stream.prototype.rekey = function rekey(k1, k2) {
|
||||
this.sid.copy(seed, 0);
|
||||
|
||||
this.k1.copy(seed, 32);
|
||||
this.k1 = crypto.hash256(seed);
|
||||
this.k1 = digest.hash256(seed);
|
||||
|
||||
this.k2.copy(seed, 32);
|
||||
this.k2 = crypto.hash256(seed);
|
||||
this.k2 = digest.hash256(seed);
|
||||
} else {
|
||||
this.k1 = k1;
|
||||
this.k2 = k2;
|
||||
@ -279,7 +282,7 @@ BIP151Stream.prototype.finish = function finish() {
|
||||
*/
|
||||
|
||||
BIP151Stream.prototype.verify = function verify(tag) {
|
||||
return chachapoly.Poly1305.verify(this.tag, tag);
|
||||
return Poly1305.verify(this.tag, tag);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -17,7 +17,7 @@ var BufferWriter = require('../utils/writer');
|
||||
var StaticWriter = require('../utils/staticwriter');
|
||||
var encoding = require('../utils/encoding');
|
||||
var consensus = require('../protocol/consensus');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var siphash256 = require('../crypto/siphash').siphash256;
|
||||
var AbstractBlock = require('../primitives/abstractblock');
|
||||
var TX = require('../primitives/tx');
|
||||
@ -412,7 +412,7 @@ CompactBlock.prototype.hasIndex = function hasIndex(index) {
|
||||
|
||||
CompactBlock.prototype.initKey = function initKey() {
|
||||
var data = util.concat(this.abbr(), this.keyNonce);
|
||||
var hash = crypto.sha256(data);
|
||||
var hash = digest.sha256(data);
|
||||
this.sipKey = hash.slice(0, 16);
|
||||
};
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
var assert = require('assert');
|
||||
var Network = require('../protocol/network');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
|
||||
/**
|
||||
* Protocol packet framer
|
||||
@ -55,7 +55,7 @@ Framer.prototype.packet = function packet(cmd, payload, checksum) {
|
||||
packet.writeUInt32LE(payload.length, 16, true);
|
||||
|
||||
if (!checksum)
|
||||
checksum = crypto.hash256(payload);
|
||||
checksum = digest.hash256(payload);
|
||||
|
||||
// Checksum
|
||||
checksum.copy(packet, 20, 0, 4);
|
||||
|
||||
@ -11,7 +11,7 @@ var assert = require('assert');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var Network = require('../protocol/network');
|
||||
var util = require('../utils/util');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var common = require('./common');
|
||||
var packets = require('./packets');
|
||||
|
||||
@ -98,7 +98,7 @@ Parser.prototype.parse = function parse(data) {
|
||||
return;
|
||||
}
|
||||
|
||||
checksum = crypto.hash256(data).readUInt32LE(0, true);
|
||||
checksum = digest.hash256(data).readUInt32LE(0, true);
|
||||
|
||||
if (checksum !== this.header.checksum) {
|
||||
this.waiting = 24;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
var util = require('../utils/util');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var BufferWriter = require('../utils/writer');
|
||||
var assert = require('assert');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
@ -129,7 +129,7 @@ ProxySocket.prototype.connect = function connect(port, host) {
|
||||
nonce++;
|
||||
assert(nonce <= 0xffffffff, 'Could not create socket.');
|
||||
pow.writeUInt32LE(nonce, 0, true);
|
||||
} while (crypto.hash256(pow).compare(this.target) > 0);
|
||||
} while (digest.hash256(pow).compare(this.target) > 0);
|
||||
|
||||
util.log('Solved proof of work: %d', nonce);
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
var assert = require('assert');
|
||||
var util = require('../utils/util');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var StaticWriter = require('../utils/staticwriter');
|
||||
var InvItem = require('./invitem');
|
||||
var encoding = require('../utils/encoding');
|
||||
@ -160,7 +160,7 @@ AbstractBlock.prototype.hash = function hash(enc) {
|
||||
var hex;
|
||||
|
||||
if (!hash) {
|
||||
hash = crypto.hash256(this.abbr());
|
||||
hash = digest.hash256(this.abbr());
|
||||
if (!this.mutable)
|
||||
this._hash = hash;
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ var assert = require('assert');
|
||||
var Network = require('../protocol/network');
|
||||
var encoding = require('../utils/encoding');
|
||||
var util = require('../utils/util');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var BufferReader = require('../utils/reader');
|
||||
var StaticWriter = require('../utils/staticwriter');
|
||||
var base58 = require('../utils/base58');
|
||||
@ -411,7 +411,7 @@ Address.fromBech32 = function fromBech32(data, network) {
|
||||
|
||||
Address.prototype.fromScript = function fromScript(script) {
|
||||
if (script.isPubkey()) {
|
||||
this.hash = crypto.hash160(script.get(0));
|
||||
this.hash = digest.hash160(script.get(0));
|
||||
this.type = Address.types.PUBKEYHASH;
|
||||
this.version = -1;
|
||||
return this;
|
||||
@ -471,14 +471,14 @@ Address.prototype.fromWitness = function fromWitness(witness) {
|
||||
// We're pretty much screwed here
|
||||
// since we can't get the version.
|
||||
if (witness.isPubkeyhashInput()) {
|
||||
this.hash = crypto.hash160(witness.get(1));
|
||||
this.hash = digest.hash160(witness.get(1));
|
||||
this.type = Address.types.WITNESS;
|
||||
this.version = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (witness.isScripthashInput()) {
|
||||
this.hash = crypto.sha256(witness.get(witness.length - 1));
|
||||
this.hash = digest.sha256(witness.get(witness.length - 1));
|
||||
this.type = Address.types.WITNESS;
|
||||
this.version = 0;
|
||||
return this;
|
||||
@ -493,14 +493,14 @@ Address.prototype.fromWitness = function fromWitness(witness) {
|
||||
|
||||
Address.prototype.fromInputScript = function fromInputScript(script) {
|
||||
if (script.isPubkeyhashInput()) {
|
||||
this.hash = crypto.hash160(script.get(1));
|
||||
this.hash = digest.hash160(script.get(1));
|
||||
this.type = Address.types.PUBKEYHASH;
|
||||
this.version = -1;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (script.isScripthashInput()) {
|
||||
this.hash = crypto.hash160(script.get(script.length - 1));
|
||||
this.hash = digest.hash160(script.get(script.length - 1));
|
||||
this.type = Address.types.SCRIPTHASH;
|
||||
this.version = -1;
|
||||
return this;
|
||||
|
||||
@ -10,7 +10,8 @@
|
||||
var assert = require('assert');
|
||||
var util = require('../utils/util');
|
||||
var encoding = require('../utils/encoding');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var merkle = require('../crypto/merkle');
|
||||
var consensus = require('../protocol/consensus');
|
||||
var AbstractBlock = require('./abstractblock');
|
||||
var VerifyResult = require('../protocol/errors').VerifyResult;
|
||||
@ -293,7 +294,7 @@ Block.prototype.createMerkleRoot = function createMerkleRoot(enc) {
|
||||
leaves.push(tx.hash());
|
||||
}
|
||||
|
||||
root = crypto.createMerkleRoot(leaves);
|
||||
root = merkle.createRoot(leaves);
|
||||
|
||||
if (root.malleated)
|
||||
return null;
|
||||
@ -333,14 +334,14 @@ Block.prototype.createCommitmentHash = function createCommitmentHash(enc) {
|
||||
leaves.push(tx.witnessHash());
|
||||
}
|
||||
|
||||
root = crypto.createMerkleRoot(leaves);
|
||||
root = merkle.createRoot(leaves);
|
||||
|
||||
// Note: malleation check ignored here.
|
||||
// assert(!root.malleated);
|
||||
|
||||
data = util.concat(root.hash, nonce);
|
||||
|
||||
hash = crypto.hash256(data);
|
||||
hash = digest.hash256(data);
|
||||
|
||||
return enc === 'hex'
|
||||
? hash.toString('hex')
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
var assert = require('assert');
|
||||
var encoding = require('../utils/encoding');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var Network = require('../protocol/network');
|
||||
var BufferReader = require('../utils/reader');
|
||||
var StaticWriter = require('../utils/staticwriter');
|
||||
@ -418,7 +418,7 @@ KeyRing.prototype.getProgram = function getProgram() {
|
||||
|
||||
if (!this._program) {
|
||||
if (!this.script) {
|
||||
hash = crypto.hash160(this.publicKey);
|
||||
hash = digest.hash160(this.publicKey);
|
||||
program = Script.fromProgram(0, hash);
|
||||
} else {
|
||||
hash = this.script.sha256();
|
||||
@ -564,7 +564,7 @@ KeyRing.prototype.getScriptAddress = function getScriptAddress(enc) {
|
||||
|
||||
KeyRing.prototype.getKeyHash = function getKeyHash(enc) {
|
||||
if (!this._keyHash)
|
||||
this._keyHash = crypto.hash160(this.publicKey);
|
||||
this._keyHash = digest.hash160(this.publicKey);
|
||||
|
||||
return enc === 'hex'
|
||||
? this._keyHash.toString('hex')
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
var assert = require('assert');
|
||||
var util = require('../utils/util');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var AbstractBlock = require('./abstractblock');
|
||||
var VerifyResult = require('../protocol/errors').VerifyResult;
|
||||
var BufferReader = require('../utils/reader');
|
||||
@ -243,7 +243,7 @@ MerkleBlock.prototype.extractTree = function extractTree() {
|
||||
left.copy(buf, 0);
|
||||
right.copy(buf, 32);
|
||||
|
||||
return crypto.hash256(buf);
|
||||
return digest.hash256(buf);
|
||||
}
|
||||
|
||||
if (totalTX === 0)
|
||||
@ -602,7 +602,7 @@ MerkleBlock.fromMatches = function fromMatches(block, matches) {
|
||||
left.copy(buf, 0);
|
||||
right.copy(buf, 32);
|
||||
|
||||
return crypto.hash256(buf);
|
||||
return digest.hash256(buf);
|
||||
}
|
||||
|
||||
function traverse(height, pos, leaves, matches) {
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
var assert = require('assert');
|
||||
var util = require('../utils/util');
|
||||
var encoding = require('../utils/encoding');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var secp256k1 = require('../crypto/secp256k1');
|
||||
var Amount = require('../btc/amount');
|
||||
var Network = require('../protocol/network');
|
||||
@ -188,7 +188,7 @@ TX.prototype.hash = function _hash(enc) {
|
||||
var hex;
|
||||
|
||||
if (!hash) {
|
||||
hash = crypto.hash256(this.toNormal());
|
||||
hash = digest.hash256(this.toNormal());
|
||||
if (!this.mutable)
|
||||
this._hash = hash;
|
||||
}
|
||||
@ -222,7 +222,7 @@ TX.prototype.witnessHash = function witnessHash(enc) {
|
||||
return this.hash(enc);
|
||||
|
||||
if (!hash) {
|
||||
hash = crypto.hash256(this.toRaw());
|
||||
hash = digest.hash256(this.toRaw());
|
||||
if (!this.mutable)
|
||||
this._whash = hash;
|
||||
}
|
||||
@ -563,7 +563,7 @@ TX.prototype.signatureHashV0 = function signatureHashV0(index, prev, type) {
|
||||
// Append the hash type.
|
||||
bw.writeU32(type);
|
||||
|
||||
return crypto.hash256(bw.render());
|
||||
return digest.hash256(bw.render());
|
||||
};
|
||||
|
||||
/**
|
||||
@ -644,7 +644,7 @@ TX.prototype.signatureHashV1 = function signatureHashV1(index, prev, value, type
|
||||
input.prevout.toWriter(bw);
|
||||
}
|
||||
|
||||
prevouts = crypto.hash256(bw.render());
|
||||
prevouts = digest.hash256(bw.render());
|
||||
|
||||
if (!this.mutable)
|
||||
this._hashPrevouts = prevouts;
|
||||
@ -664,7 +664,7 @@ TX.prototype.signatureHashV1 = function signatureHashV1(index, prev, value, type
|
||||
bw.writeU32(input.sequence);
|
||||
}
|
||||
|
||||
sequences = crypto.hash256(bw.render());
|
||||
sequences = digest.hash256(bw.render());
|
||||
|
||||
if (!this.mutable)
|
||||
this._hashSequence = sequences;
|
||||
@ -690,14 +690,14 @@ TX.prototype.signatureHashV1 = function signatureHashV1(index, prev, value, type
|
||||
output.toWriter(bw);
|
||||
}
|
||||
|
||||
outputs = crypto.hash256(bw.render());
|
||||
outputs = digest.hash256(bw.render());
|
||||
|
||||
if (!this.mutable)
|
||||
this._hashOutputs = outputs;
|
||||
}
|
||||
} else if ((type & 0x1f) === Script.hashType.SINGLE && index < this.outputs.length) {
|
||||
output = this.outputs[index];
|
||||
outputs = crypto.hash256(output.toRaw());
|
||||
outputs = digest.hash256(output.toRaw());
|
||||
}
|
||||
|
||||
input = this.inputs[index];
|
||||
@ -717,7 +717,7 @@ TX.prototype.signatureHashV1 = function signatureHashV1(index, prev, value, type
|
||||
bw.writeU32(this.locktime);
|
||||
bw.writeU32(type);
|
||||
|
||||
return crypto.hash256(bw.render());
|
||||
return digest.hash256(bw.render());
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -12,7 +12,8 @@ var BN = require('../crypto/bn');
|
||||
var consensus = require('../protocol/consensus');
|
||||
var policy = require('../protocol/policy');
|
||||
var util = require('../utils/util');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var merkle = require('../crypto/merkle');
|
||||
var BufferWriter = require('../utils/writer');
|
||||
var BufferReader = require('../utils/reader');
|
||||
var StaticWriter = require('../utils/staticwriter');
|
||||
@ -1058,35 +1059,35 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
|
||||
if (stack.length === 0)
|
||||
throw new ScriptError('INVALID_STACK_OPERATION', op, ip);
|
||||
|
||||
stack.push(crypto.ripemd160(stack.pop()));
|
||||
stack.push(digest.ripemd160(stack.pop()));
|
||||
break;
|
||||
}
|
||||
case opcodes.OP_SHA1: {
|
||||
if (stack.length === 0)
|
||||
throw new ScriptError('INVALID_STACK_OPERATION', op, ip);
|
||||
|
||||
stack.push(crypto.sha1(stack.pop()));
|
||||
stack.push(digest.sha1(stack.pop()));
|
||||
break;
|
||||
}
|
||||
case opcodes.OP_SHA256: {
|
||||
if (stack.length === 0)
|
||||
throw new ScriptError('INVALID_STACK_OPERATION', op, ip);
|
||||
|
||||
stack.push(crypto.sha256(stack.pop()));
|
||||
stack.push(digest.sha256(stack.pop()));
|
||||
break;
|
||||
}
|
||||
case opcodes.OP_HASH160: {
|
||||
if (stack.length === 0)
|
||||
throw new ScriptError('INVALID_STACK_OPERATION', op, ip);
|
||||
|
||||
stack.push(crypto.hash160(stack.pop()));
|
||||
stack.push(digest.hash160(stack.pop()));
|
||||
break;
|
||||
}
|
||||
case opcodes.OP_HASH256: {
|
||||
if (stack.length === 0)
|
||||
throw new ScriptError('INVALID_STACK_OPERATION', op, ip);
|
||||
|
||||
stack.push(crypto.hash256(stack.pop()));
|
||||
stack.push(digest.hash256(stack.pop()));
|
||||
break;
|
||||
}
|
||||
case opcodes.OP_CODESEPARATOR: {
|
||||
@ -1836,7 +1837,7 @@ Script.prototype.getAddress = function getAddress() {
|
||||
*/
|
||||
|
||||
Script.prototype.hash160 = function hash160(enc) {
|
||||
var hash = crypto.hash160(this.toRaw());
|
||||
var hash = digest.hash160(this.toRaw());
|
||||
if (enc === 'hex')
|
||||
hash = hash.toString('hex');
|
||||
return hash;
|
||||
@ -1849,7 +1850,7 @@ Script.prototype.hash160 = function hash160(enc) {
|
||||
*/
|
||||
|
||||
Script.prototype.sha256 = function sha256(enc) {
|
||||
var hash = crypto.sha256(this.toRaw());
|
||||
var hash = digest.sha256(this.toRaw());
|
||||
if (enc === 'hex')
|
||||
hash = hash.toString('hex');
|
||||
return hash;
|
||||
@ -2083,7 +2084,7 @@ Script.prototype.forWitness = function() {
|
||||
return this;
|
||||
|
||||
if (this.isPubkey()) {
|
||||
hash = crypto.hash160(this.get(0));
|
||||
hash = digest.hash160(this.get(0));
|
||||
return Script.fromProgram(0, hash);
|
||||
}
|
||||
|
||||
@ -2923,7 +2924,7 @@ Script.verifyProgram = function verifyProgram(witness, output, flags, tx, i, val
|
||||
|
||||
witnessScript = stack.pop();
|
||||
|
||||
if (!crypto.sha256(witnessScript).equals(program.data))
|
||||
if (!digest.sha256(witnessScript).equals(program.data))
|
||||
throw new ScriptError('WITNESS_PROGRAM_MISMATCH');
|
||||
|
||||
redeem = new Script(witnessScript);
|
||||
@ -3073,15 +3074,15 @@ Script.verifyMast = function verifyMast(program, stack, output, flags, tx, i, va
|
||||
if ((scripts.written + script.length) > consensus.MAX_SCRIPT_SIZE)
|
||||
throw new ScriptError('SCRIPT_SIZE');
|
||||
}
|
||||
scriptRoot.writeBytes(crypto.hash256(script));
|
||||
scriptRoot.writeBytes(digest.hash256(script));
|
||||
scripts.writeBytes(script);
|
||||
}
|
||||
|
||||
scriptRoot = crypto.hash256(scriptRoot.render());
|
||||
scriptRoot = crypto.verifyMerkleBranch(scriptRoot, path, pos);
|
||||
scriptRoot = digest.hash256(scriptRoot.render());
|
||||
scriptRoot = merkle.verifyBranch(scriptRoot, path, pos);
|
||||
|
||||
mastRoot.writeBytes(scriptRoot);
|
||||
mastRoot = crypto.hash256(mastRoot.render());
|
||||
mastRoot = digest.hash256(mastRoot.render());
|
||||
|
||||
if (!mastRoot.equals(program.data))
|
||||
throw new ScriptError('WITNESS_PROGRAM_MISMATCH');
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
var assert = require('assert');
|
||||
var Int64 = require('./int64');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var siphash24 = require('../crypto/siphash');
|
||||
var SCRATCH = Buffer.allocUnsafe(64);
|
||||
var DUMMY = Buffer.allocUnsafe(0);
|
||||
@ -28,7 +28,7 @@ function GCSFilter() {
|
||||
}
|
||||
|
||||
GCSFilter.prototype.hash = function _hash(enc) {
|
||||
var hash = crypto.hash256(this.data);
|
||||
var hash = digest.hash256(this.data);
|
||||
return enc === 'hex' ? hash.toString('hex') : hash;
|
||||
};
|
||||
|
||||
@ -37,7 +37,7 @@ GCSFilter.prototype.header = function header(prev) {
|
||||
var hash = this.hash();
|
||||
hash.copy(data, 0);
|
||||
prev.copy(data, 32);
|
||||
return crypto.hash256(data);
|
||||
return digest.hash256(data);
|
||||
};
|
||||
|
||||
GCSFilter.prototype.match = function match(key, data) {
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
var assert = require('assert');
|
||||
var encoding = require('./encoding');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
|
||||
/**
|
||||
* An object that allows reading of buffers in a sane manner.
|
||||
@ -673,7 +673,7 @@ BufferReader.prototype.readNullString = function readNullString(enc) {
|
||||
BufferReader.prototype.createChecksum = function createChecksum() {
|
||||
var start = this.stack[this.stack.length - 1] || 0;
|
||||
var data = this.data.slice(start, this.offset);
|
||||
return crypto.hash256(data).readUInt32LE(0, true);
|
||||
return digest.hash256(data).readUInt32LE(0, true);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
var assert = require('assert');
|
||||
var encoding = require('./encoding');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
|
||||
/**
|
||||
* Statically allocated buffer writer.
|
||||
@ -417,7 +417,7 @@ StaticWriter.prototype.writeNullString = function writeNullString(value, enc) {
|
||||
|
||||
StaticWriter.prototype.writeChecksum = function writeChecksum() {
|
||||
var data = this.data.slice(0, this.written);
|
||||
var hash = crypto.hash256(data);
|
||||
var hash = digest.hash256(data);
|
||||
hash.copy(this.data, this.written, 0, 4);
|
||||
this.written += 4;
|
||||
};
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
var assert = require('assert');
|
||||
var encoding = require('./encoding');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
|
||||
/*
|
||||
* Constants
|
||||
@ -101,7 +101,7 @@ BufferWriter.prototype.render = function render(keep) {
|
||||
case BYTES: off += op.value.copy(data, off); break;
|
||||
case STR: off += data.write(op.value, off, op.enc); break;
|
||||
case CHECKSUM:
|
||||
off += crypto.hash256(data.slice(0, off)).copy(data, off, 0, 4);
|
||||
off += digest.hash256(data.slice(0, off)).copy(data, off, 0, 4);
|
||||
break;
|
||||
case FILL:
|
||||
data.fill(op.value, off, off + op.size);
|
||||
|
||||
@ -14,7 +14,9 @@ var base58 = require('../utils/base58');
|
||||
var MTX = require('../primitives/mtx');
|
||||
var Outpoint = require('../primitives/outpoint');
|
||||
var Script = require('../script/script');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var random = require('../crypto/random');
|
||||
var ccmp = require('../crypto/ccmp');
|
||||
var Network = require('../protocol/network');
|
||||
var Validator = require('../utils/validator');
|
||||
var common = require('./common');
|
||||
@ -887,7 +889,7 @@ HTTPServer.prototype.handleSocket = function handleSocket(socket) {
|
||||
|
||||
if (!self.options.noAuth) {
|
||||
hash = hash256(key);
|
||||
if (!crypto.ccmp(hash, self.options.apiHash))
|
||||
if (!ccmp(hash, self.options.apiHash))
|
||||
throw new Error('Bad key.');
|
||||
}
|
||||
|
||||
@ -973,7 +975,7 @@ function HTTPOptions(options) {
|
||||
this.network = Network.primary;
|
||||
this.logger = null;
|
||||
this.walletdb = null;
|
||||
this.apiKey = base58.encode(crypto.randomBytes(20));
|
||||
this.apiKey = base58.encode(random.randomBytes(20));
|
||||
this.apiHash = hash256(this.apiKey);
|
||||
this.serviceHash = this.apiHash;
|
||||
this.noAuth = false;
|
||||
@ -1094,7 +1096,7 @@ function hash256(data) {
|
||||
if (data.length > 200)
|
||||
return Buffer.alloc(0);
|
||||
|
||||
return crypto.hash256(Buffer.from(data, 'utf8'));
|
||||
return digest.hash256(Buffer.from(data, 'utf8'));
|
||||
}
|
||||
|
||||
function enforce(value, msg) {
|
||||
|
||||
@ -9,7 +9,11 @@
|
||||
var assert = require('assert');
|
||||
var util = require('../utils/util');
|
||||
var Lock = require('../utils/lock');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var random = require('../crypto/random');
|
||||
var cleanse = require('../crypto/cleanse');
|
||||
var aes = require('../crypto/aes');
|
||||
var pbkdf2 = require('../crypto/pbkdf2');
|
||||
var scrypt = require('../crypto/scrypt');
|
||||
var BufferReader = require('../utils/reader');
|
||||
var StaticWriter = require('../utils/staticwriter');
|
||||
var encoding = require('../utils/encoding');
|
||||
@ -199,7 +203,7 @@ MasterKey.prototype._unlock = async function _unlock(passphrase, timeout) {
|
||||
assert(this.encrypted);
|
||||
|
||||
key = await this.derive(passphrase);
|
||||
data = crypto.decipher(this.ciphertext, key, this.iv);
|
||||
data = aes.decipher(this.ciphertext, key, this.iv);
|
||||
|
||||
this.fromKeyRaw(data);
|
||||
|
||||
@ -259,9 +263,9 @@ MasterKey.prototype.derive = async function derive(passwd) {
|
||||
|
||||
switch (this.alg) {
|
||||
case MasterKey.alg.PBKDF2:
|
||||
return await crypto.pbkdf2Async(passwd, salt, N, 32, 'sha256');
|
||||
return await pbkdf2.deriveAsync(passwd, salt, N, 32, 'sha256');
|
||||
case MasterKey.alg.SCRYPT:
|
||||
return await crypto.scryptAsync(passwd, salt, N, r, p, 32);
|
||||
return await scrypt.deriveAsync(passwd, salt, N, r, p, 32);
|
||||
default:
|
||||
throw new Error('Unknown algorithm: ' + this.alg);
|
||||
}
|
||||
@ -281,7 +285,7 @@ MasterKey.prototype.encipher = function encipher(data, iv) {
|
||||
if (typeof iv === 'string')
|
||||
iv = Buffer.from(iv, 'hex');
|
||||
|
||||
return crypto.encipher(data, this.aesKey, iv.slice(0, 16));
|
||||
return aes.encipher(data, this.aesKey, iv.slice(0, 16));
|
||||
};
|
||||
|
||||
/**
|
||||
@ -298,7 +302,7 @@ MasterKey.prototype.decipher = function decipher(data, iv) {
|
||||
if (typeof iv === 'string')
|
||||
iv = Buffer.from(iv, 'hex');
|
||||
|
||||
return crypto.decipher(data, this.aesKey, iv.slice(0, 16));
|
||||
return aes.decipher(data, this.aesKey, iv.slice(0, 16));
|
||||
};
|
||||
|
||||
/**
|
||||
@ -338,7 +342,7 @@ MasterKey.prototype._lock = function lock() {
|
||||
}
|
||||
|
||||
if (this.aesKey) {
|
||||
crypto.cleanse(this.aesKey);
|
||||
cleanse(this.aesKey);
|
||||
this.aesKey = null;
|
||||
}
|
||||
};
|
||||
@ -386,7 +390,7 @@ MasterKey.prototype._decrypt = async function decrypt(passphrase, clean) {
|
||||
this._lock();
|
||||
|
||||
key = await this.derive(passphrase);
|
||||
data = crypto.decipher(this.ciphertext, key, this.iv);
|
||||
data = aes.decipher(this.ciphertext, key, this.iv);
|
||||
|
||||
this.fromKeyRaw(data);
|
||||
this.encrypted = false;
|
||||
@ -394,7 +398,7 @@ MasterKey.prototype._decrypt = async function decrypt(passphrase, clean) {
|
||||
this.ciphertext = null;
|
||||
|
||||
if (!clean) {
|
||||
crypto.cleanse(key);
|
||||
cleanse(key);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -433,12 +437,12 @@ MasterKey.prototype._encrypt = async function encrypt(passphrase, clean) {
|
||||
throw new Error('No passphrase provided.');
|
||||
|
||||
data = this.toKeyRaw();
|
||||
iv = crypto.randomBytes(16);
|
||||
iv = random.randomBytes(16);
|
||||
|
||||
this.stop();
|
||||
|
||||
key = await this.derive(passphrase);
|
||||
data = crypto.encipher(data, key, iv);
|
||||
data = aes.encipher(data, key, iv);
|
||||
|
||||
this.key = null;
|
||||
this.mnemonic = null;
|
||||
@ -447,7 +451,7 @@ MasterKey.prototype._encrypt = async function encrypt(passphrase, clean) {
|
||||
this.ciphertext = data;
|
||||
|
||||
if (!clean) {
|
||||
crypto.cleanse(key);
|
||||
cleanse(key);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
var assert = require('assert');
|
||||
var fs = require('../utils/fs');
|
||||
var util = require('../utils/util');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var Amount = require('../btc/amount');
|
||||
var Script = require('../script/script');
|
||||
var Address = require('../primitives/address');
|
||||
@ -1484,7 +1484,7 @@ RPC.prototype.signMessage = async function signMessage(args, help) {
|
||||
throw new RPCError(errs.WALLET_UNLOCK_NEEDED, 'Wallet is locked.');
|
||||
|
||||
msg = Buffer.from(MAGIC_STRING + msg, 'utf8');
|
||||
msg = crypto.hash256(msg);
|
||||
msg = digest.hash256(msg);
|
||||
|
||||
sig = ring.sign(msg);
|
||||
|
||||
|
||||
@ -13,7 +13,8 @@ var Network = require('../protocol/network');
|
||||
var util = require('../utils/util');
|
||||
var encoding = require('../utils/encoding');
|
||||
var Lock = require('../utils/lock');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var digest = require('../crypto/digest');
|
||||
var cleanse = require('../crypto/cleanse');
|
||||
var BufferReader = require('../utils/reader');
|
||||
var StaticWriter = require('../utils/staticwriter');
|
||||
var base58 = require('../utils/base58');
|
||||
@ -408,12 +409,12 @@ Wallet.prototype._encrypt = async function encrypt(passphrase) {
|
||||
try {
|
||||
await this.db.encryptKeys(this, key);
|
||||
} catch (e) {
|
||||
crypto.cleanse(key);
|
||||
cleanse(key);
|
||||
this.drop();
|
||||
throw e;
|
||||
}
|
||||
|
||||
crypto.cleanse(key);
|
||||
cleanse(key);
|
||||
|
||||
this.save();
|
||||
|
||||
@ -450,12 +451,12 @@ Wallet.prototype._decrypt = async function decrypt(passphrase) {
|
||||
try {
|
||||
await this.db.decryptKeys(this, key);
|
||||
} catch (e) {
|
||||
crypto.cleanse(key);
|
||||
cleanse(key);
|
||||
this.drop();
|
||||
throw e;
|
||||
}
|
||||
|
||||
crypto.cleanse(key);
|
||||
cleanse(key);
|
||||
|
||||
this.save();
|
||||
|
||||
@ -621,7 +622,7 @@ Wallet.prototype.getID = function getID() {
|
||||
bw.writeBytes(key.publicKey);
|
||||
bw.writeU32(this.network.magic);
|
||||
|
||||
hash = crypto.hash160(bw.render());
|
||||
hash = digest.hash160(bw.render());
|
||||
|
||||
bw = new StaticWriter(27);
|
||||
bw.writeU8(0x03);
|
||||
@ -653,7 +654,7 @@ Wallet.prototype.getToken = function getToken(nonce) {
|
||||
bw.writeBytes(key.privateKey);
|
||||
bw.writeU32(nonce);
|
||||
|
||||
return crypto.hash256(bw.render());
|
||||
return digest.hash256(bw.render());
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -13,7 +13,8 @@ var util = require('../utils/util');
|
||||
var Lock = require('../utils/lock');
|
||||
var LRU = require('../utils/lru');
|
||||
var encoding = require('../utils/encoding');
|
||||
var crypto = require('../crypto/crypto');
|
||||
var ccmp = require('../crypto/ccmp');
|
||||
var aes = require('../crypto/aes');
|
||||
var Network = require('../protocol/network');
|
||||
var Path = require('./path');
|
||||
var common = require('./common');
|
||||
@ -1011,7 +1012,7 @@ WalletDB.prototype.auth = async function auth(wid, token) {
|
||||
}
|
||||
|
||||
// Compare in constant time:
|
||||
if (!crypto.ccmp(token, wallet.token))
|
||||
if (!ccmp(token, wallet.token))
|
||||
throw new Error('WDB: Authentication error.');
|
||||
|
||||
return wallet;
|
||||
@ -1422,7 +1423,7 @@ WalletDB.prototype.encryptKeys = async function encryptKeys(wallet, key) {
|
||||
iv = iv.slice(0, 16);
|
||||
|
||||
path = path.clone();
|
||||
path.data = crypto.encipher(path.data, key, iv);
|
||||
path.data = aes.encipher(path.data, key, iv);
|
||||
path.encrypted = true;
|
||||
|
||||
wallet.pathCache.push(path.hash, path);
|
||||
@ -1456,7 +1457,7 @@ WalletDB.prototype.decryptKeys = async function decryptKeys(wallet, key) {
|
||||
iv = iv.slice(0, 16);
|
||||
|
||||
path = path.clone();
|
||||
path.data = crypto.decipher(path.data, key, iv);
|
||||
path.data = aes.decipher(path.data, key, iv);
|
||||
path.encrypted = false;
|
||||
|
||||
wallet.pathCache.push(path.hash, path);
|
||||
|
||||
@ -175,6 +175,6 @@ jobs.mine = function _mine(data, target, min, max) {
|
||||
*/
|
||||
|
||||
jobs.scrypt = function _scrypt(passwd, salt, N, r, p, len) {
|
||||
var key = scrypt(passwd, salt, N, r, p, len);
|
||||
var key = scrypt.derive(passwd, salt, N, r, p, len);
|
||||
return new packets.ScryptResultPacket(key);
|
||||
};
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
var assert = require('assert');
|
||||
var encoding = require('../lib/utils/encoding');
|
||||
var BufferReader = require('../lib/utils/reader');
|
||||
var crypto = require('../lib/crypto/crypto');
|
||||
var digest = require('../lib/crypto/digest');
|
||||
var util = require('../lib/utils/util');
|
||||
var LDB = require('../lib/db/ldb');
|
||||
var BN = require('../lib/crypto/bn');
|
||||
@ -42,7 +42,7 @@ async function checkVersion() {
|
||||
|
||||
function entryFromRaw(data) {
|
||||
var p = new BufferReader(data, true);
|
||||
var hash = crypto.hash256(p.readBytes(80));
|
||||
var hash = digest.hash256(p.readBytes(80));
|
||||
var entry = {};
|
||||
|
||||
p.seek(-80);
|
||||
|
||||
@ -78,9 +78,12 @@
|
||||
"socket.io": "./browser/empty.js",
|
||||
"./lib/bcoin": "./lib/bcoin-browser.js",
|
||||
"./lib/blockchain/layout.js": "./lib/blockchain/layout-browser.js",
|
||||
"./lib/crypto/backend.js": "./lib/crypto/backend-browser.js",
|
||||
"./lib/crypto/secp256k1.js": "./lib/crypto/secp256k1-elliptic.js",
|
||||
"./lib/crypto/aes.js": "./lib/crypto/aes-browser.js",
|
||||
"./lib/crypto/digest.js": "./lib/crypto/digest-browser.js",
|
||||
"./lib/crypto/pbkdf2.js": "./lib/crypto/pbkdf2-browser.js",
|
||||
"./lib/crypto/random.js": "./lib/crypto/random-browser.js",
|
||||
"./lib/crypto/rsa.js": "./lib/crypto/rsa-browser.js",
|
||||
"./lib/crypto/secp256k1.js": "./lib/crypto/secp256k1-elliptic.js",
|
||||
"./lib/db/backends.js": "./lib/db/backends-browser.js",
|
||||
"./lib/hd/wordlist": "./lib/hd/wordlist-browser.js",
|
||||
"./lib/http/base": "./browser/empty.js",
|
||||
|
||||
@ -1,21 +1,22 @@
|
||||
var assert = require('assert');
|
||||
var bcoin = require('../');
|
||||
var util = bcoin.util;
|
||||
var Script = bcoin.script;
|
||||
var Stack = bcoin.stack;
|
||||
var Witness = bcoin.witness;
|
||||
var Input = bcoin.input;
|
||||
var Output = bcoin.output;
|
||||
var Outpoint = bcoin.outpoint;
|
||||
var TX = bcoin.tx;
|
||||
var crypto = bcoin.crypto;
|
||||
var consensus = bcoin.consensus;
|
||||
var util = require('../lib/utils/util');
|
||||
var Script = require('../lib/script/script');
|
||||
var Stack = require('../lib/script/stack');
|
||||
var Witness = require('../lib/script/witness');
|
||||
var Input = require('../lib/primitives/input');
|
||||
var Output = require('../lib/primitives/output');
|
||||
var Outpoint = require('../lib/primitives/outpoint');
|
||||
var TX = require('../lib/primitives/tx');
|
||||
var digest = require('../lib/crypto/digest');
|
||||
var random = require('../lib/crypto/random');
|
||||
var consensus = require('../lib/protocol/consensus');
|
||||
|
||||
var MANDATORY = Script.flags.MANDATORY_VERIFY_FLAGS | Script.flags.VERIFY_WITNESS;
|
||||
var STANDARD = Script.flags.STANDARD_VERIFY_FLAGS;
|
||||
|
||||
function randomOutpoint() {
|
||||
var hash = crypto.randomBytes(32).toString('hex');
|
||||
var hash = random.randomBytes(32).toString('hex');
|
||||
return new Outpoint(hash, util.random(0, 0xffffffff));
|
||||
}
|
||||
|
||||
@ -61,7 +62,7 @@ function randomWitness(redeem) {
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
len = util.random(0, 100);
|
||||
witness.push(crypto.randomBytes(len));
|
||||
witness.push(random.randomBytes(len));
|
||||
}
|
||||
|
||||
if (redeem)
|
||||
@ -79,7 +80,7 @@ function randomInputScript(redeem) {
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
len = util.random(0, 100);
|
||||
script.push(crypto.randomBytes(len));
|
||||
script.push(random.randomBytes(len));
|
||||
}
|
||||
|
||||
if (redeem)
|
||||
@ -92,7 +93,7 @@ function randomInputScript(redeem) {
|
||||
|
||||
function randomOutputScript() {
|
||||
var size = util.random(1, 10000);
|
||||
return Script.fromRaw(crypto.randomBytes(size));
|
||||
return Script.fromRaw(random.randomBytes(size));
|
||||
}
|
||||
|
||||
function isPushOnly(script) {
|
||||
@ -121,11 +122,11 @@ function isPushOnly(script) {
|
||||
|
||||
function randomPubkey() {
|
||||
var len = util.random(0, 2) === 0 ? 33 : 65;
|
||||
return Script.fromPubkey(crypto.randomBytes(len));
|
||||
return Script.fromPubkey(random.randomBytes(len));
|
||||
}
|
||||
|
||||
function randomPubkeyhash() {
|
||||
return Script.fromPubkeyhash(crypto.randomBytes(20));
|
||||
return Script.fromPubkeyhash(random.randomBytes(20));
|
||||
}
|
||||
|
||||
function randomMultisig() {
|
||||
@ -136,28 +137,28 @@ function randomMultisig() {
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
len = util.random(0, 2) === 0 ? 33 : 65;
|
||||
keys.push(crypto.randomBytes(len));
|
||||
keys.push(random.randomBytes(len));
|
||||
}
|
||||
|
||||
return Script.fromMultisig(m, n, keys);
|
||||
}
|
||||
|
||||
function randomScripthash() {
|
||||
return Script.fromScripthash(crypto.randomBytes(20));
|
||||
return Script.fromScripthash(random.randomBytes(20));
|
||||
}
|
||||
|
||||
function randomWitnessPubkeyhash() {
|
||||
return Script.fromProgram(0, crypto.randomBytes(20));
|
||||
return Script.fromProgram(0, random.randomBytes(20));
|
||||
}
|
||||
|
||||
function randomWitnessScripthash() {
|
||||
return Script.fromProgram(0, crypto.randomBytes(32));
|
||||
return Script.fromProgram(0, random.randomBytes(32));
|
||||
}
|
||||
|
||||
function randomProgram() {
|
||||
var version = util.random(0, 16);
|
||||
var size = util.random(2, 41);
|
||||
return Script.fromProgram(version, crypto.randomBytes(size));
|
||||
return Script.fromProgram(version, random.randomBytes(size));
|
||||
}
|
||||
|
||||
function randomRedeem() {
|
||||
|
||||
@ -1,13 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var crypto = require('../lib/crypto/crypto');
|
||||
var digest = require('../lib/crypto/digest');
|
||||
var aes = require('../lib/crypto/aes');
|
||||
var pbkdf2 = require('../lib/crypto/pbkdf2');
|
||||
var nativeCrypto = require('crypto');
|
||||
|
||||
describe('AES', function() {
|
||||
function pbkdf2key(passphrase, iterations, dkLen, ivLen, alg) {
|
||||
var key = crypto.pbkdf2(passphrase, '', iterations, dkLen + ivLen, 'sha512');
|
||||
var key = pbkdf2.derive(passphrase, '', iterations, dkLen + ivLen, 'sha512');
|
||||
return {
|
||||
key: key.slice(0, dkLen),
|
||||
iv: key.slice(dkLen, dkLen + ivLen)
|
||||
@ -69,7 +70,7 @@ describe('AES', function() {
|
||||
passphrase = Buffer.from(passphrase, 'utf8');
|
||||
|
||||
key = pbkdf2key(passphrase, 2048, 32, 16);
|
||||
return crypto.encipher(data, key.key, key.iv);
|
||||
return aes.encipher(data, key.key, key.iv);
|
||||
}
|
||||
|
||||
function bdecrypt(data, passphrase) {
|
||||
@ -85,7 +86,7 @@ describe('AES', function() {
|
||||
passphrase = Buffer.from(passphrase, 'utf8');
|
||||
|
||||
key = pbkdf2key(passphrase, 2048, 32, 16);
|
||||
return crypto.decipher(data, key.key, key.iv);
|
||||
return aes.decipher(data, key.key, key.iv);
|
||||
}
|
||||
|
||||
function encrypt(data, passphrase) {
|
||||
@ -102,7 +103,7 @@ describe('AES', function() {
|
||||
|
||||
key = pbkdf2key(passphrase, 2048, 32, 16);
|
||||
|
||||
return aes.cbc.encrypt(data, key.key, key.iv);
|
||||
return aes.encipher(data, key.key, key.iv);
|
||||
}
|
||||
|
||||
function decrypt(data, passphrase) {
|
||||
@ -119,19 +120,19 @@ describe('AES', function() {
|
||||
|
||||
key = pbkdf2key(passphrase, 2048, 32, 16);
|
||||
|
||||
return aes.cbc.decrypt(data, key.key, key.iv);
|
||||
return aes.decipher(data, key.key, key.iv);
|
||||
}
|
||||
|
||||
it('should encrypt and decrypt a hash with 2 blocks', function() {
|
||||
var hash = crypto.sha256(Buffer.alloc(0));
|
||||
var hash = digest.sha256(Buffer.alloc(0));
|
||||
var enchash = encrypt(hash, 'foo');
|
||||
var dechash = decrypt(enchash, 'foo');
|
||||
|
||||
var hash2 = crypto.sha256(Buffer.alloc(0));
|
||||
var hash2 = digest.sha256(Buffer.alloc(0));
|
||||
var enchash2 = nencrypt(hash2, 'foo');
|
||||
var dechash2 = ndecrypt(enchash2, 'foo');
|
||||
|
||||
var hash3 = crypto.sha256(Buffer.alloc(0));
|
||||
var hash3 = digest.sha256(Buffer.alloc(0));
|
||||
var enchash3 = bencrypt(hash3, 'foo');
|
||||
var dechash3 = bdecrypt(enchash3, 'foo');
|
||||
|
||||
@ -142,11 +143,11 @@ describe('AES', function() {
|
||||
});
|
||||
|
||||
it('should encrypt and decrypt a hash with uneven blocks', function() {
|
||||
var hash = Buffer.concat([crypto.sha256(Buffer.alloc(0)), Buffer.from([1,2,3])]);
|
||||
var hash = Buffer.concat([digest.sha256(Buffer.alloc(0)), Buffer.from([1,2,3])]);
|
||||
var enchash = encrypt(hash, 'foo');
|
||||
var dechash = decrypt(enchash, 'foo');
|
||||
|
||||
var hash2 = Buffer.concat([crypto.sha256(Buffer.alloc(0)), Buffer.from([1,2,3])]);
|
||||
var hash2 = Buffer.concat([digest.sha256(Buffer.alloc(0)), Buffer.from([1,2,3])]);
|
||||
var enchash2 = nencrypt(hash2, 'foo');
|
||||
var dechash2 = ndecrypt(enchash2, 'foo');
|
||||
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var chachapoly = require('../lib/crypto/chachapoly');
|
||||
var ChaCha20 = chachapoly.ChaCha20;
|
||||
var Poly1305 = chachapoly.Poly1305;
|
||||
var AEAD = chachapoly.AEAD;
|
||||
var ChaCha20 = require('../lib/crypto/chacha20');
|
||||
var Poly1305 = require('../lib/crypto/poly1305');
|
||||
var AEAD = require('../lib/crypto/aead');
|
||||
|
||||
describe('ChaCha20 / Poly1305 / AEAD', function() {
|
||||
function testChaCha(options) {
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
var assert = require('assert');
|
||||
var fs = require('../lib/utils/fs');
|
||||
var GCSFilter = require('../lib/utils/gcs');
|
||||
var crypto = require('../lib/crypto/crypto');
|
||||
var random = require('../lib/crypto/random');
|
||||
var Block = require('../lib/primitives/block');
|
||||
var Outpoint = require('../lib/primitives/outpoint');
|
||||
var Address = require('../lib/primitives/address');
|
||||
@ -12,7 +12,7 @@ var raw = fs.readFileSync(__dirname + '/data/block928927.raw');
|
||||
var block = Block.fromRaw(raw);
|
||||
|
||||
describe('GCS', function() {
|
||||
var key = crypto.randomBytes(16);
|
||||
var key = random.randomBytes(16);
|
||||
var P = 20;
|
||||
var filter1, filter2, filter3, filter4, filter5;
|
||||
var contents1, contents2;
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
var assert = require('assert');
|
||||
var HD = require('../lib/hd');
|
||||
var base58 = require('../lib/utils/base58');
|
||||
var crypto = require('../lib/crypto/crypto');
|
||||
var pbkdf2 = require('../lib/crypto/pbkdf2');
|
||||
var vectors = require('./data/hd.json');
|
||||
var vector1 = vectors.vector1;
|
||||
var vector2 = vectors.vector2;
|
||||
@ -21,7 +21,7 @@ describe('HD', function() {
|
||||
var master, child1, child2, child3, child4, child5, child6;
|
||||
|
||||
it('should create a pbkdf2 seed', function() {
|
||||
var seed = crypto.pbkdf2(vectors.phrase, 'mnemonicfoo', 2048, 64, 'sha512');
|
||||
var seed = pbkdf2.derive(vectors.phrase, 'mnemonicfoo', 2048, 64, 'sha512');
|
||||
assert.equal(seed.toString('hex'), vectors.seed);
|
||||
});
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
var assert = require('assert');
|
||||
var encoding = require('../lib/utils/encoding');
|
||||
var crypto = require('../lib/crypto/crypto');
|
||||
var random = require('../lib/crypto/random');
|
||||
var MempoolEntry = require('../lib/mempool/mempoolentry');
|
||||
var Mempool = require('../lib/mempool/mempool');
|
||||
var Chain = require('../lib/blockchain/chain');
|
||||
@ -161,7 +161,7 @@ describe('Mempool', function() {
|
||||
tx.addOutput(w.getAddress(), 10000);
|
||||
|
||||
prev = Script.fromPubkey(kp.publicKey);
|
||||
prevHash = crypto.randomBytes(32).toString('hex');
|
||||
prevHash = random.randomBytes(32).toString('hex');
|
||||
|
||||
tx.addCoin(dummy(prev, prevHash));
|
||||
tx.setLocktime(200);
|
||||
@ -187,7 +187,7 @@ describe('Mempool', function() {
|
||||
tx.addOutput(w.getAddress(), 10000);
|
||||
|
||||
prev = Script.fromPubkey(kp.publicKey);
|
||||
prevHash = crypto.randomBytes(32).toString('hex');
|
||||
prevHash = random.randomBytes(32).toString('hex');
|
||||
|
||||
tx.addCoin(dummy(prev, prevHash));
|
||||
tx.setLocktime(200);
|
||||
@ -220,7 +220,7 @@ describe('Mempool', function() {
|
||||
tx.addOutput(w.getAddress(), 10000);
|
||||
|
||||
prev = Script.fromProgram(0, kp.getKeyHash());
|
||||
prevHash = crypto.randomBytes(32).toString('hex');
|
||||
prevHash = random.randomBytes(32).toString('hex');
|
||||
|
||||
tx.addCoin(dummy(prev, prevHash));
|
||||
|
||||
@ -252,7 +252,7 @@ describe('Mempool', function() {
|
||||
tx.addOutput(w.getAddress(), 10000);
|
||||
|
||||
prev = Script.fromPubkey(kp.publicKey);
|
||||
prevHash = crypto.randomBytes(32).toString('hex');
|
||||
prevHash = random.randomBytes(32).toString('hex');
|
||||
|
||||
tx.addCoin(dummy(prev, prevHash));
|
||||
|
||||
@ -283,7 +283,7 @@ describe('Mempool', function() {
|
||||
tx.addOutput(w.getAddress(), 10000);
|
||||
|
||||
prev = Script.fromProgram(0, kp.getKeyHash());
|
||||
prevHash = crypto.randomBytes(32).toString('hex');
|
||||
prevHash = random.randomBytes(32).toString('hex');
|
||||
|
||||
tx.addCoin(dummy(prev, prevHash));
|
||||
|
||||
@ -310,7 +310,7 @@ describe('Mempool', function() {
|
||||
tx.addOutput(w.getAddress(), 10000);
|
||||
|
||||
prev = Script.fromPubkey(kp.publicKey);
|
||||
prevHash = crypto.randomBytes(32).toString('hex');
|
||||
prevHash = random.randomBytes(32).toString('hex');
|
||||
|
||||
tx.addCoin(dummy(prev, prevHash));
|
||||
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var scrypt = require('../lib/crypto/crypto').scrypt;
|
||||
var scrypt = require('../lib/crypto/scrypt');
|
||||
|
||||
describe('Scrypt', function() {
|
||||
it('should perform scrypt with N=16', function() {
|
||||
var pass = Buffer.from('');
|
||||
var salt = Buffer.from('');
|
||||
var result = scrypt(pass, salt, 16, 1, 1, 64);
|
||||
var result = scrypt.derive(pass, salt, 16, 1, 1, 64);
|
||||
assert.equal(result.toString('hex'), ''
|
||||
+ '77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3f'
|
||||
+ 'ede21442fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628'
|
||||
@ -17,7 +17,7 @@ describe('Scrypt', function() {
|
||||
it('should perform scrypt with N=1024', function() {
|
||||
var pass = Buffer.from('password');
|
||||
var salt = Buffer.from('NaCl');
|
||||
var result = scrypt(pass, salt, 1024, 8, 16, 64);
|
||||
var result = scrypt.derive(pass, salt, 1024, 8, 16, 64);
|
||||
assert.equal(result.toString('hex'), ''
|
||||
+ 'fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e773'
|
||||
+ '76634b3731622eaf30d92e22a3886ff109279d9830dac727afb9'
|
||||
@ -27,7 +27,7 @@ describe('Scrypt', function() {
|
||||
it('should perform scrypt with N=16384', function() {
|
||||
var pass = Buffer.from('pleaseletmein');
|
||||
var salt = Buffer.from('SodiumChloride');
|
||||
var result = scrypt(pass, salt, 16384, 8, 1, 64);
|
||||
var result = scrypt.derive(pass, salt, 16384, 8, 1, 64);
|
||||
assert.equal(result.toString('hex'), ''
|
||||
+ '7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b54'
|
||||
+ '3f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d'
|
||||
@ -38,7 +38,7 @@ describe('Scrypt', function() {
|
||||
// it('should perform scrypt with N=1048576', function() {
|
||||
// var pass = Buffer.from('pleaseletmein');
|
||||
// var salt = Buffer.from('SodiumChloride');
|
||||
// var result = scrypt(pass, salt, 1048576, 8, 1, 64);
|
||||
// var result = scrypt.derive(pass, salt, 1048576, 8, 1, 64);
|
||||
// assert.equal(result.toString('hex'), ''
|
||||
// + '2101cb9b6a511aaeaddbbe09cf70f881ec568d574a2ffd4dabe5'
|
||||
// + 'ee9820adaa478e56fd8f4ba5d09ffa1c6d927c40f4c337304049'
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
var assert = require('assert');
|
||||
var util = require('../lib/utils/util');
|
||||
var encoding = require('../lib/utils/encoding');
|
||||
var crypto = require('../lib/crypto/crypto');
|
||||
var random = require('../lib/crypto/random');
|
||||
var consensus = require('../lib/protocol/consensus');
|
||||
var TX = require('../lib/primitives/tx');
|
||||
var Coin = require('../lib/primitives/coin');
|
||||
@ -355,7 +355,7 @@ describe('TX', function() {
|
||||
});
|
||||
|
||||
function createInput(value, view) {
|
||||
var hash = crypto.randomBytes(32).toString('hex');
|
||||
var hash = random.randomBytes(32).toString('hex');
|
||||
var output = new Output();
|
||||
output.value = value;
|
||||
view.addOutput(hash, 0, output);
|
||||
|
||||
@ -5,7 +5,8 @@ var BN = require('../lib/crypto/bn');
|
||||
var secp256k1 = require('../lib/crypto/secp256k1');
|
||||
var base58 = require('../lib/utils/base58');
|
||||
var encoding = require('../lib/utils/encoding');
|
||||
var crypto = require('../lib/crypto/crypto');
|
||||
var digest = require('../lib/crypto/digest');
|
||||
var hkdf = require('../lib/crypto/hkdf');
|
||||
var schnorr = require('../lib/crypto/schnorr');
|
||||
var Amount = require('../lib/btc/amount');
|
||||
var consensus = require('../lib/protocol/consensus');
|
||||
@ -271,8 +272,8 @@ describe('Utils', function() {
|
||||
salt = Buffer.from(salt, 'hex');
|
||||
info = Buffer.from(info, 'hex');
|
||||
|
||||
prk = crypto.hkdfExtract(ikm, salt, alg);
|
||||
okm = crypto.hkdfExpand(prk, info, len, alg);
|
||||
prk = hkdf.extract(ikm, salt, alg);
|
||||
okm = hkdf.expand(prk, info, len, alg);
|
||||
|
||||
assert.equal(prk.toString('hex'), prkE);
|
||||
assert.equal(okm.toString('hex'), okmE);
|
||||
@ -313,8 +314,8 @@ describe('Utils', function() {
|
||||
salt = Buffer.from(salt, 'hex');
|
||||
info = Buffer.from(info, 'hex');
|
||||
|
||||
prk = crypto.hkdfExtract(ikm, salt, alg);
|
||||
okm = crypto.hkdfExpand(prk, info, len, alg);
|
||||
prk = hkdf.extract(ikm, salt, alg);
|
||||
okm = hkdf.expand(prk, info, len, alg);
|
||||
|
||||
assert.equal(prk.toString('hex'), prkE);
|
||||
assert.equal(okm.toString('hex'), okmE);
|
||||
@ -323,7 +324,7 @@ describe('Utils', function() {
|
||||
it('should do proper schnorr', function() {
|
||||
var key = secp256k1.generatePrivateKey();
|
||||
var pub = secp256k1.publicKeyCreate(key, true);
|
||||
var msg = crypto.hash256(Buffer.from('foo', 'ascii'));
|
||||
var msg = digest.hash256(Buffer.from('foo', 'ascii'));
|
||||
var sig = schnorr.sign(msg, key);
|
||||
assert(schnorr.verify(msg, sig, pub));
|
||||
assert.deepEqual(schnorr.recover(sig, msg), pub);
|
||||
|
||||
@ -4,7 +4,8 @@ var assert = require('assert');
|
||||
var consensus = require('../lib/protocol/consensus');
|
||||
var util = require('../lib/utils/util');
|
||||
var encoding = require('../lib/utils/encoding');
|
||||
var crypto = require('../lib/crypto/crypto');
|
||||
var digest = require('../lib/crypto/digest');
|
||||
var random = require('../lib/crypto/random');
|
||||
var WalletDB = require('../lib/wallet/walletdb');
|
||||
var Address = require('../lib/primitives/address');
|
||||
var MTX = require('../lib/primitives/mtx');
|
||||
@ -30,8 +31,8 @@ function nextBlock(height) {
|
||||
if (height == null)
|
||||
height = globalHeight++;
|
||||
|
||||
hash = crypto.hash256(encoding.U32(height)).toString('hex');
|
||||
prev = crypto.hash256(encoding.U32(height - 1)).toString('hex');
|
||||
hash = digest.hash256(encoding.U32(height)).toString('hex');
|
||||
prev = digest.hash256(encoding.U32(height - 1)).toString('hex');
|
||||
|
||||
return {
|
||||
hash: hash,
|
||||
@ -46,7 +47,7 @@ function nextBlock(height) {
|
||||
|
||||
function dummy(hash) {
|
||||
if (!hash)
|
||||
hash = crypto.randomBytes(32).toString('hex');
|
||||
hash = random.randomBytes(32).toString('hex');
|
||||
|
||||
return Input.fromOutpoint(new Outpoint(hash, 0));
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user