File size: 4,522 Bytes
4888678 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
/* basic entropy accumulator */
var accum = (function() {
var pool, // randomness pool
time, // start timestamp
last; // last step timestamp
/* initialize with default pool */
function init() {
pool = [];
time = new Date().getTime();
last = time;
// use Math.random
pool.push((Math.random() * 0xffffffff)|0);
// use current time
pool.push(time|0);
}
/* perform one step */
function step() {
if (!to)
return;
if (pool.length >= 255) { // stop at 255 values (1 more is added on fetch)
stop();
return;
}
var now = new Date().getTime();
// use actual time difference
pool.push(now-last);
// always compute, occasionally use Math.random
var rnd = (Math.random() * 0xffffffff)|0;
if (now % 2)
pool[pool.length-1] += rnd;
last = now;
to = setTimeout(step, 100+Math.random()*512); // use hypothetical time difference
}
var to = null;
/* starts accumulating */
function start() {
if (to) return;
to = setTimeout(step, 100+Math.random()*512);
if (console.log)
console.log("bcrypt-isaac: collecting entropy...");
// install collectors
if (typeof window !== 'undefined' && window && window.addEventListener)
window.addEventListener("load", loadCollector, false),
window.addEventListener("mousemove", mouseCollector, false),
window.addEventListener("touchmove", touchCollector, false);
else if (typeof document !== 'undefined' && document && document.attachEvent)
document.attachEvent("onload", loadCollector),
document.attachEvent("onmousemove", mouseCollector);
}
/* stops accumulating */
function stop() {
if (!to) return;
clearTimeout(to); to = null;
// uninstall collectors
if (typeof window !== 'undefined' && window && window.removeEventListener)
window.removeEventListener("load", loadCollector, false),
window.removeEventListener("mousemove", mouseCollector, false),
window.removeEventListener("touchmove", touchCollector, false);
else if (typeof document !== 'undefined' && document && document.detachEvent)
document.detachEvent("onload", loadCollector),
document.detachEvent("onmousemove", mouseCollector);
}
/* fetches the randomness pool */
function fetch() {
// add overall time difference
pool.push((new Date().getTime()-time)|0);
var res = pool;
init();
if (console.log)
console.log("bcrypt-isaac: using "+res.length+"/256 samples of entropy");
// console.log(res);
return res;
}
/* adds the current time to the top of the pool */
function addTime() {
pool[pool.length-1] += new Date().getTime() - time;
}
/* page load collector */
function loadCollector() {
if (!to || pool.length >= 255)
return;
pool.push(0);
addTime();
}
/* mouse events collector */
function mouseCollector(ev) {
if (!to || pool.length >= 255)
return;
try {
var x = ev.x || ev.clientX || ev.offsetX || 0,
y = ev.y || ev.clientY || ev.offsetY || 0;
if (x != 0 || y != 0)
pool[pool.length-1] += ((x-mouseCollector.last[0]) ^ (y-mouseCollector.last[1])),
addTime(),
mouseCollector.last = [x,y];
} catch (e) {}
}
mouseCollector.last = [0,0];
/* touch events collector */
function touchCollector(ev) {
if (!to || pool.length >= 255)
return;
try {
var touch = ev.touches[0] || ev.changedTouches[0];
var x = touch.pageX || touch.clientX || 0,
y = touch.pageY || touch.clientY || 0;
if (x != 0 || y != 0)
pool[pool.length-1] += (x-touchCollector.last[0]) ^ (y-touchCollector.last[1]),
addTime(),
touchCollector.last = [x,y];
} catch (e) {}
}
touchCollector.last = [0,0];
init();
return {
"start": start,
"stop": stop,
"fetch": fetch
}
})();
|