crypto: add random.js.
This commit is contained in:
parent
28acda024a
commit
1edb5aa4cf
@ -10,11 +10,9 @@
|
||||
var elliptic = require('elliptic');
|
||||
var bn = require('bn.js');
|
||||
var utils = require('../utils/utils');
|
||||
var random = require('./random');
|
||||
var assert = utils.assert;
|
||||
var crypto, secp256k1;
|
||||
|
||||
if (!utils.isBrowser)
|
||||
crypto = require('crypto');
|
||||
var secp256k1;
|
||||
|
||||
try {
|
||||
if (+process.env.BCOIN_USE_ELLIPTIC !== 1)
|
||||
@ -67,9 +65,9 @@ ec.curve = ec.elliptic.curve;
|
||||
ec.generatePrivateKey = function generatePrivateKey() {
|
||||
var key, priv;
|
||||
|
||||
if (secp256k1 && crypto) {
|
||||
if (secp256k1) {
|
||||
do {
|
||||
priv = crypto.randomBytes(32);
|
||||
priv = random.randomBytes(32);
|
||||
} while (!secp256k1.privateKeyVerify(priv));
|
||||
} else {
|
||||
key = ec.elliptic.genKeyPair();
|
||||
@ -110,7 +108,7 @@ ec.publicKeyConvert = function publicKeyConvert(key, compressed) {
|
||||
if (secp256k1)
|
||||
return secp256k1.publicKeyConvert(key, compressed);
|
||||
|
||||
point = ec.elliptic.curve.decodePoint(key);
|
||||
point = ec.curve.decodePoint(key);
|
||||
|
||||
return new Buffer(point.encode('array', compressed !== false));
|
||||
};
|
||||
@ -190,51 +188,34 @@ ec.ecdh = function ecdh(pub, priv) {
|
||||
*/
|
||||
|
||||
ec.recover = function recover(msg, sig, j, compressed) {
|
||||
var keys = [];
|
||||
var i, point, key;
|
||||
var point, key;
|
||||
|
||||
if (typeof j === 'boolean') {
|
||||
compressed = j;
|
||||
j = null;
|
||||
}
|
||||
if (!j)
|
||||
j = 0;
|
||||
|
||||
if (secp256k1) {
|
||||
try {
|
||||
sig = secp256k1.signatureImport(sig);
|
||||
} catch (e) {
|
||||
;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i <= 3; i++) {
|
||||
if (j != null && j !== i)
|
||||
continue;
|
||||
|
||||
if (secp256k1) {
|
||||
try {
|
||||
key = secp256k1.recover(msg, sig, i, compressed);
|
||||
} catch (e) {
|
||||
continue;
|
||||
}
|
||||
keys.push(key);
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
point = ec.elliptic.recoverPubKey(msg, sig, i);
|
||||
key = secp256k1.recover(msg, sig, j, compressed);
|
||||
} catch (e) {
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
key = ec.elliptic.keyPair({ pub: point });
|
||||
key = key.getPublic(compressed !== false, 'array');
|
||||
keys.push(new Buffer(key));
|
||||
return key;
|
||||
}
|
||||
|
||||
if (j != null)
|
||||
return keys[0];
|
||||
try {
|
||||
point = ec.elliptic.recoverPubKey(msg, sig, j);
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
|
||||
return keys;
|
||||
key = point.encode('array', compressed !== false);
|
||||
|
||||
return new Buffer(key);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -243,10 +224,8 @@ ec.recover = function recover(msg, sig, j, compressed) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
ec.random = function random(size) {
|
||||
if (crypto)
|
||||
return crypto.randomBytes(size);
|
||||
return new Buffer(elliptic.rand(size));
|
||||
ec.random = function _random(size) {
|
||||
return random.randomBytes(size);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -259,8 +238,7 @@ ec.random = function random(size) {
|
||||
*/
|
||||
|
||||
ec.rand = function rand(min, max) {
|
||||
var num = ec.random(4).readUInt32LE(0, true);
|
||||
return Math.floor((num / 0x100000000) * (max - min) + min);
|
||||
return random.randomInt(min, max);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -362,7 +340,7 @@ ec.privateKeyVerify = function privateKeyVerify(key) {
|
||||
|
||||
key = new bn(key);
|
||||
|
||||
return key.cmpn(0) !== 0 && key.cmp(ec.elliptic.curve.n) < 0;
|
||||
return key.cmpn(0) !== 0 && key.cmp(ec.curve.n) < 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -521,7 +499,7 @@ ec.toLowS = function toLowS(sig) {
|
||||
// If S is greater than half the order,
|
||||
// it's too high.
|
||||
if (sig.s.cmp(ec.elliptic.nh) > 0)
|
||||
sig.s = ec.elliptic.n.sub(sig.s);
|
||||
sig.s = ec.curve.n.sub(sig.s);
|
||||
|
||||
return new Buffer(sig.toDER());
|
||||
};
|
||||
|
||||
69
lib/crypto/random.js
Normal file
69
lib/crypto/random.js
Normal file
@ -0,0 +1,69 @@
|
||||
/*!
|
||||
* random.js - pseudorandom byte generation for bcoin.
|
||||
* Copyright (c) 2016, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*
|
||||
* Parts of this software are based on brorand:
|
||||
* https://github.com/indutny/brorand
|
||||
* Copyright (c) 2014, Fedor Indutny (MIT License).
|
||||
*/
|
||||
|
||||
var random, crypto, global;
|
||||
|
||||
try {
|
||||
crypto = require('crypto');
|
||||
} catch (e) {
|
||||
;
|
||||
}
|
||||
|
||||
if (crypto) {
|
||||
random = function random(n) {
|
||||
return crypto.randomBytes(n);
|
||||
};
|
||||
} else {
|
||||
if (typeof window !== 'undefined')
|
||||
global = window;
|
||||
else if (typeof self !== 'undefined')
|
||||
global = self;
|
||||
|
||||
if (!global)
|
||||
throw new Error('Unknown global.');
|
||||
|
||||
crypto = global.crypto || global.msCrypto;
|
||||
|
||||
if (crypto && crypto.getRandomValues) {
|
||||
random = function random(n) {
|
||||
var data = new Uint8Array(n);
|
||||
crypto.getRandomValues(data);
|
||||
return new Buffer(data.buffer);
|
||||
};
|
||||
} else {
|
||||
// Out of luck here. Use bad randomness for now.
|
||||
// Possibly fall back to randy in the future:
|
||||
// https://github.com/deestan/randy
|
||||
random = function random(n) {
|
||||
var data = new Buffer(n);
|
||||
var i;
|
||||
|
||||
for (i = 0; i < data.length; i++)
|
||||
data[i] = ((Math.random() * 0x100000000) >>> 0) % 256;
|
||||
|
||||
return data;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function randomInt(min, max) {
|
||||
var num = random(4).readUInt32LE(0, true);
|
||||
return Math.floor((num / 0x100000000) * (max - min) + min);
|
||||
}
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
exports = random;
|
||||
exports.randomBytes = random;
|
||||
exports.randomInt = randomInt;
|
||||
|
||||
module.exports = random;
|
||||
@ -11,6 +11,7 @@ var elliptic = require('elliptic');
|
||||
var Signature = require('elliptic/lib/elliptic/ec/signature');
|
||||
var hmacDRBG = require('elliptic/lib/elliptic/hmac-drbg');
|
||||
var ec = require('./ec');
|
||||
var random = require('./random');
|
||||
var curve = elliptic.ec('secp256k1').curve;
|
||||
var sha256 = require('./crypto').sha256;
|
||||
|
||||
@ -109,7 +110,7 @@ schnorr.sign = function sign(msg, key, hash, pubnonce) {
|
||||
throw new Error('Bad private key.');
|
||||
|
||||
while (!sig) {
|
||||
k = new bn(ec.random(32));
|
||||
k = new bn(random.randomBytes(32));
|
||||
sig = schnorr._sign(msg, prv, k, hash, pubnonce);
|
||||
}
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
var bcoin = require('../env');
|
||||
var utils = require('../utils/utils');
|
||||
var ec = require('../crypto/ec');
|
||||
var random = require('../crypto/random');
|
||||
var assert = utils.assert;
|
||||
var constants = bcoin.constants;
|
||||
var BufferWriter = require('../utils/writer');
|
||||
@ -168,7 +169,7 @@ Mnemonic.prototype.toKey = function toKey(passphrase, network) {
|
||||
|
||||
Mnemonic.prototype.getEntropy = function getEntropy() {
|
||||
if (!this.entropy)
|
||||
this.entropy = ec.random(this.bits / 8);
|
||||
this.entropy = random.randomBytes(this.bits / 8);
|
||||
|
||||
assert(this.bits / 8 === this.entropy.length);
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
var bcoin = require('../env');
|
||||
var utils = require('../utils/utils');
|
||||
var ec = require('../crypto/ec');
|
||||
var random = require('../crypto/random');
|
||||
var assert = utils.assert;
|
||||
var constants = bcoin.constants;
|
||||
var networks = bcoin.networks;
|
||||
@ -577,7 +578,7 @@ HDPrivateKey.fromKey = function fromKey(key, entropy, network) {
|
||||
|
||||
HDPrivateKey.generate = function generate(network) {
|
||||
var key = ec.generatePrivateKey();
|
||||
var entropy = ec.random(32);
|
||||
var entropy = random.randomBytes(32);
|
||||
return HDPrivateKey.fromKey(key, entropy, network);
|
||||
};
|
||||
|
||||
|
||||
@ -15,6 +15,7 @@ var constants = bcoin.constants;
|
||||
var http = require('./');
|
||||
var HTTPBase = http.base;
|
||||
var utils = require('../utils/utils');
|
||||
var random = require('../crypto/random');
|
||||
var assert = utils.assert;
|
||||
var RPC; /*= require('./rpc'); - load lazily */
|
||||
|
||||
@ -57,7 +58,7 @@ function HTTPServer(options) {
|
||||
this.rpc = null;
|
||||
|
||||
if (!this.apiKey)
|
||||
this.apiKey = utils.toBase58(bcoin.ec.random(20));
|
||||
this.apiKey = utils.toBase58(random.randomBytes(20));
|
||||
|
||||
assert(typeof this.apiKey === 'string', 'API key must be a string.');
|
||||
assert(this.apiKey.length <= 200, 'API key must be under 200 bytes.');
|
||||
@ -233,6 +234,9 @@ HTTPServer.prototype._init = function _init() {
|
||||
if (params.fee)
|
||||
options.fee = utils.satoshi(params.fee);
|
||||
|
||||
if (params.hardFee)
|
||||
options.hardFee = utils.satoshi(params.hardFee);
|
||||
|
||||
if (params.maxFee)
|
||||
options.maxFee = utils.satoshi(params.maxFee);
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@ var utils = require('../utils/utils');
|
||||
var assert = utils.assert;
|
||||
var BufferWriter = require('../utils/writer');
|
||||
var BufferReader = require('../utils/reader');
|
||||
var random = require('../crypto/random');
|
||||
var VerifyError = bcoin.errors.VerifyError;
|
||||
|
||||
/**
|
||||
@ -299,7 +300,7 @@ Mempool.prototype.limitOrphans = function limitOrphans() {
|
||||
var i, hash;
|
||||
|
||||
while (this.totalOrphans > constants.mempool.MAX_ORPHAN_TX) {
|
||||
i = bcoin.ec.rand(0, orphans.length);
|
||||
i = random.randomInt(0, orphans.length);
|
||||
hash = orphans[i];
|
||||
orphans.splice(i, 1);
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var bcoin = require('../env');
|
||||
var utils = require('../utils/utils');
|
||||
var random = require('../crypto/random');
|
||||
var assert = utils.assert;
|
||||
var constants = bcoin.constants;
|
||||
|
||||
@ -118,7 +119,7 @@ BIP150.prototype.reply = function reply(payload) {
|
||||
throw new Error('Auth failure.');
|
||||
|
||||
if (!this.peerIdentity)
|
||||
return bcoin.ec.random(32);
|
||||
return random.randomBytes(32);
|
||||
|
||||
sig = bcoin.ec.toDER(data);
|
||||
msg = this.hash(this.output.sid, type, this.peerIdentity);
|
||||
@ -126,7 +127,7 @@ BIP150.prototype.reply = function reply(payload) {
|
||||
result = bcoin.ec.verify(msg, sig, this.peerIdentity);
|
||||
|
||||
if (!result)
|
||||
return bcoin.ec.random(32);
|
||||
return random.randomBytes(32);
|
||||
|
||||
if (this.isAuthed()) {
|
||||
this.auth = true;
|
||||
|
||||
@ -14,6 +14,7 @@ var utils = require('../utils/utils');
|
||||
var assert = utils.assert;
|
||||
var BufferReader = require('../utils/reader');
|
||||
var BufferWriter = require('../utils/writer');
|
||||
var random = require('../crypto/random');
|
||||
var TXDB = require('./txdb');
|
||||
var Path = require('./path');
|
||||
|
||||
@ -905,7 +906,8 @@ Wallet.prototype.importKey = function importKey(account, ring, passphrase, callb
|
||||
* @param {Boolean} options.confirmed - Select only confirmed coins.
|
||||
* @param {Boolean} options.free - Do not apply a fee if the
|
||||
* transaction priority is high enough to be considered free.
|
||||
* @param {Amount?} options.fee - Use a hard fee rather than calculating one.
|
||||
* @param {Amount?} options.hardFee - Use a hard fee rather than
|
||||
* calculating one.
|
||||
* @param {Number|Boolean} options.subtractFee - Whether to subtract the
|
||||
* fee from existing outputs rather than adding more inputs.
|
||||
*/
|
||||
@ -967,11 +969,12 @@ Wallet.prototype.fund = function fund(tx, options, callback, force) {
|
||||
round: options.round,
|
||||
confirmed: options.confirmed,
|
||||
free: options.free,
|
||||
fee: options.fee,
|
||||
hardFee: options.hardFee,
|
||||
subtractFee: options.subtractFee,
|
||||
changeAddress: account.changeAddress.getAddress(),
|
||||
height: self.db.height,
|
||||
rate: rate,
|
||||
maxFee: options.maxFee,
|
||||
m: account.m,
|
||||
n: account.n,
|
||||
witness: account.witness,
|
||||
@ -2377,7 +2380,7 @@ MasterKey.prototype.encrypt = function encrypt(passphrase, callback) {
|
||||
return callback();
|
||||
|
||||
data = this.key.toExtended();
|
||||
iv = bcoin.ec.random(16);
|
||||
iv = random.randomBytes(16);
|
||||
|
||||
this.stop();
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user