PHP WebShell
Текущая директория: /usr/lib/node_modules/bitgo/node_modules/asmcrypto.js/src/random
Просмотр файла: random.js
import { ISAAC } from './isaac';
import { FloatArray, is_buffer, is_typed_array } from '../utils';
import { get_pbkdf2_hmac_sha256_instance } from '../pbkdf2/pbkdf2-hmac-sha256';
import { SecurityError } from '../errors';
var _global_console = typeof console !== 'undefined' ? console : undefined,
_global_date_now = Date.now,
_global_math_random = Math.random,
_global_performance = typeof performance !== 'undefined' ? performance : undefined,
_global_crypto = typeof crypto !== 'undefined' ? crypto : typeof msCrypto !== 'undefined' ? msCrypto : undefined,
_global_crypto_getRandomValues;
if (_global_crypto !== undefined) _global_crypto_getRandomValues = _global_crypto.getRandomValues;
var _isaac_rand = ISAAC.rand,
_isaac_seed = ISAAC.seed,
_isaac_counter = 0,
_isaac_weak_seeded = false,
_isaac_seeded = false;
var _random_estimated_entropy = 0,
_random_required_entropy = 256,
_random_warn_callstacks = {};
export var _random_skip_system_rng_warning = false;
export var _random_allow_weak = false;
var _hires_now;
if (_global_performance !== undefined) {
_hires_now = function() {
return (1000 * _global_performance.now()) | 0;
};
} else {
var _hires_epoch = (1000 * _global_date_now()) | 0;
_hires_now = function() {
return (1000 * _global_date_now() - _hires_epoch) | 0;
};
}
/**
* weak_seed
*
* Seeds RNG with native `crypto.getRandomValues` output or with high-resolution
* time and single `Math.random()` value, and various other sources.
*
* We estimate this may give at least ~50 bits of unpredictableness,
* but this has not been analysed thoroughly or precisely.
*/
function Random_weak_seed() {
if (_global_crypto !== undefined) {
buffer = new Uint8Array(32);
_global_crypto_getRandomValues.call(_global_crypto, buffer);
_isaac_seed(buffer);
} else {
// Some clarification about brute-force attack cost:
// - entire bitcoin network operates at ~10^16 hash guesses per second;
// - each PBKDF2 iteration requires the same number of hashing operations as bitcoin nonce guess;
// - attacker having such a hashing power is able to break worst-case 50 bits of the randomness in ~3 hours;
// Sounds sad though attacker having such a hashing power more likely would prefer to mine bitcoins.
var buffer = new FloatArray(3),
i,
t;
buffer[0] = _global_math_random();
buffer[1] = _global_date_now();
buffer[2] = _hires_now();
buffer = new Uint8Array(buffer.buffer);
var salt = '';
if (typeof location !== 'undefined') {
salt += location.href;
} else if (typeof process !== 'undefined') {
salt += process.pid + process.title;
}
var pbkdf2 = get_pbkdf2_hmac_sha256_instance();
for (i = 0; i < 100; i++) {
buffer = pbkdf2.reset({ password: buffer }).generate(salt, 1000, 32).result;
t = _hires_now();
(buffer[0] ^= t >>> 24), (buffer[1] ^= t >>> 16), (buffer[2] ^= t >>> 8), (buffer[3] ^= t);
}
_isaac_seed(buffer);
}
_isaac_counter = 0;
_isaac_weak_seeded = true;
}
/**
* seed
*
* Seeds PRNG with supplied random values if these values have enough entropy.
*
* A false return value means the RNG is currently insecure; however a true
* return value does not mean it is necessarily secure (depending on how you
* collected the seed) though asmCrypto will be forced to assume this.
*
* The input buffer will be zeroed to discourage reuse. You should not copy it
* or use it anywhere else before passing it into this function.
*
* **DISCLAIMER!** Seeding with a poor values is an easiest way shoot your legs, so
* do not seed until you're know what entropy is and how to obtail high-quality random values,
* **DO NOT SEED WITH CONSTANT VALUE! YOU'LL GET NO RANDOMNESS FROM CONSTANT!**
*/
export function Random_seed(seed) {
if (!is_buffer(seed) && !is_typed_array(seed)) throw new TypeError('bad seed type');
var bpos = seed.byteOffset || 0,
blen = seed.byteLength || seed.length,
buff = new Uint8Array(seed.buffer || seed, bpos, blen);
_isaac_seed(buff);
_isaac_counter = 0;
// don't let the user use these bytes again
var nonzero = 0;
for (var i = 0; i < buff.length; i++) {
nonzero |= buff[i];
buff[i] = 0;
}
if (nonzero !== 0) {
// TODO we could make a better estimate, but half-length is a prudent
// simple measure that seems unlikely to over-estimate
_random_estimated_entropy += 4 * blen;
}
_isaac_seeded = _random_estimated_entropy >= _random_required_entropy;
return _isaac_seeded;
}
/**
* getValues
*
* Populates the buffer with cryptographically secure random values. These are
* calculated using `crypto.getRandomValues` if it is available, as well as our
* own ISAAC PRNG implementation.
*
* If the former is not available (older browsers such as IE10 [1]), then the
* latter *must* be seeded using `Random.seed`, unless `asmCrypto.random.allowWeak` is true.
*
* *We assume the system RNG is strong*; if you cannot afford this risk, then
* you should also seed ISAAC using `Random.seed`. This is advisable for very
* important situations, such as generation of long-term secrets. See also [2].
*
* [1] https://developer.mozilla.org/en-US/docs/Web/API/window.crypto.getRandomValues
* [2] https://en.wikipedia.org/wiki/Dual_EC_DRBG
*
* In all cases, we opportunistically seed using various arbitrary sources
* such as high-resolution time and one single value from the insecure
* Math.random(); however this is not reliable as a strong security measure.
*/
export function Random_getValues(buffer) {
// opportunistically seed ISAAC with a weak seed; this hopefully makes an
// attack harder in the case where the system RNG is weak *and* we haven't
// seeded ISAAC. but don't make any guarantees to the user about this.
if (!_isaac_weak_seeded) Random_weak_seed();
// if we have no strong sources then the RNG is weak, handle it
if (!_isaac_seeded && _global_crypto === undefined) {
if (!_random_allow_weak) throw new SecurityError('No strong PRNGs available. Use asmCrypto.random.seed().');
if (_global_console !== undefined)
_global_console.error(
'No strong PRNGs available; your security is greatly lowered. Use asmCrypto.random.seed().',
);
}
// separate warning about assuming system RNG strong
if (
!_random_skip_system_rng_warning &&
!_isaac_seeded &&
_global_crypto !== undefined &&
_global_console !== undefined
) {
// Hacky way to get call stack
var s = new Error().stack;
_random_warn_callstacks[s] |= 0;
if (!_random_warn_callstacks[s]++)
_global_console.warn(
'asmCrypto PRNG not seeded; your security relies on your system PRNG. If this is not acceptable, use asmCrypto.random.seed().',
);
}
// proceed to get random values
if (!is_buffer(buffer) && !is_typed_array(buffer)) throw new TypeError('unexpected buffer type');
var bpos = buffer.byteOffset || 0,
blen = buffer.byteLength || buffer.length,
bytes = new Uint8Array(buffer.buffer || buffer, bpos, blen),
i,
r;
// apply system rng
if (_global_crypto !== undefined) _global_crypto_getRandomValues.call(_global_crypto, bytes);
// apply isaac rng
for (i = 0; i < blen; i++) {
if ((i & 3) === 0) {
if (_isaac_counter >= 0x10000000000) Random_weak_seed();
r = _isaac_rand();
_isaac_counter++;
}
bytes[i] ^= r;
r >>>= 8;
}
return buffer;
}
/**
* getNumber
*
* A drop-in `Math.random` replacement.
* Intended for prevention of random material leakage out of the user's host.
*/
export function Random_getNumber() {
if (!_isaac_weak_seeded || _isaac_counter >= 0x10000000000) Random_weak_seed();
var n = (0x100000 * _isaac_rand() + (_isaac_rand() >>> 12)) / 0x10000000000000;
_isaac_counter += 2;
return n;
}
Object.defineProperty(Random_getNumber, 'allowWeak', {
get: function() {
return _random_allow_weak;
},
set: function(a) {
_random_allow_weak = a;
},
});
Object.defineProperty(Random_getNumber, 'skipSystemRNGWarning', {
get: function() {
return _random_skip_system_rng_warning;
},
set: function(w) {
_random_skip_system_rng_warning = w;
},
});
Object.defineProperty(Random_getValues, 'allowWeak', {
get: function() {
return _random_allow_weak;
},
set: function(a) {
_random_allow_weak = a;
},
});
Object.defineProperty(Random_getValues, 'skipSystemRNGWarning', {
get: function() {
return _random_skip_system_rng_warning;
},
set: function(w) {
_random_skip_system_rng_warning = w;
},
});
Random_getNumber.seed = Random_seed;
Random_getValues.seed = Random_seed;
Выполнить команду
Для локальной разработки. Не используйте в интернете!