mirror of
https://github.com/the-djmaze/snappymail.git
synced 2025-01-04 14:02:17 +08:00
65 lines
2 KiB
JavaScript
65 lines
2 KiB
JavaScript
// Random number generator - requires a PRNG backend, e.g. prng4.js
|
|
var rng_state;
|
|
var rng_pool;
|
|
var rng_pptr;
|
|
|
|
// Initialize the pool with junk if needed.
|
|
if(rng_pool == null) {
|
|
rng_pool = new Array();
|
|
rng_pptr = 0;
|
|
var t;
|
|
if(window.crypto && window.crypto.getRandomValues) {
|
|
// Extract entropy (2048 bits) from RNG if available
|
|
var z = new Uint32Array(256);
|
|
window.crypto.getRandomValues(z);
|
|
for (t = 0; t < z.length; ++t)
|
|
rng_pool[rng_pptr++] = z[t] & 255;
|
|
}
|
|
|
|
// Use mouse events for entropy, if we do not have enough entropy by the time
|
|
// we need it, entropy will be generated by Math.random.
|
|
var onMouseMoveListener = function(ev) {
|
|
this.count = this.count || 0;
|
|
if (this.count >= 256 || rng_pptr >= rng_psize) {
|
|
if (window.removeEventListener)
|
|
window.removeEventListener("mousemove", onMouseMoveListener);
|
|
else if (window.detachEvent)
|
|
window.detachEvent("onmousemove", onMouseMoveListener);
|
|
return;
|
|
}
|
|
this.count += 1;
|
|
var mouseCoordinates = ev.x + ev.y;
|
|
rng_pool[rng_pptr++] = mouseCoordinates & 255;
|
|
};
|
|
if (window.addEventListener)
|
|
window.addEventListener("mousemove", onMouseMoveListener);
|
|
else if (window.attachEvent)
|
|
window.attachEvent("onmousemove", onMouseMoveListener);
|
|
|
|
}
|
|
|
|
function rng_get_byte() {
|
|
if(rng_state == null) {
|
|
rng_state = prng_newstate();
|
|
// At this point, we may not have collected enough entropy. If not, fall back to Math.random
|
|
while (rng_pptr < rng_psize) {
|
|
var random = Math.floor(65536 * Math.random());
|
|
rng_pool[rng_pptr++] = random & 255;
|
|
}
|
|
rng_state.init(rng_pool);
|
|
for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr)
|
|
rng_pool[rng_pptr] = 0;
|
|
rng_pptr = 0;
|
|
}
|
|
// TODO: allow reseeding after first request
|
|
return rng_state.next();
|
|
}
|
|
|
|
function rng_get_bytes(ba) {
|
|
var i;
|
|
for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte();
|
|
}
|
|
|
|
function SecureRandom() {}
|
|
|
|
SecureRandom.prototype.nextBytes = rng_get_bytes;
|