more entropy

This commit is contained in:
pointbiz 2013-12-09 19:30:16 -04:00
parent 4f11d4fb62
commit db6d3e9acc
6 changed files with 130 additions and 30 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -21,6 +21,7 @@ body { font-family: Arial; }
.answer { padding: 0 15px 10px 25px; text-align: left; display: none; font-size: 80%; }
.faq { border: 0; border-top: 2px solid green; }
#seedpoolarea { display: none; }
#keyarea { height: 250px; font-family: Arial; }
#keyarea .pubaddress { float: none; display: block; padding: 0; height: auto; }
#keyarea .label { text-decoration: none; }
@ -183,4 +184,5 @@ body { font-family: Arial; }
#detailprivwif { width: 285px; word-wrap: break-word; }
#detailprivwifcomp { width: 285px; word-wrap: break-word; text-align: right; }
#detailarea .privqr .item { width: 285px; }
#seedpoolarea { display: none; }
}

View file

@ -2,7 +2,7 @@ ninja.seeder = {
// number of mouse movements to wait for
seedLimit: (function () {
var num = Crypto.util.randomBytes(12)[11];
return 50 + Math.floor(num);
return 100 + Math.floor(num);
})(),
seedCount: 0, // counter
@ -24,6 +24,12 @@ ninja.seeder = {
document.getElementById("generate").style.display = "none";
document.getElementById("menu").style.visibility = "visible";
}
if (SecureRandom.poolCopyOnInit != null) {
document.getElementById("seedpool").innerHTML = Crypto.util.bytesToHex(SecureRandom.poolCopyOnInit);
}
else {
document.getElementById("seedpool").innerHTML = Crypto.util.bytesToHex(SecureRandom.pool);
}
},
// If user has not moved the mouse or if they are on a mobile device

View file

@ -21,5 +21,9 @@ if (ninja.getQueryString()["testnet"] == "true" || ninja.getQueryString()["testn
Bitcoin.ECKey.privateKeyPrefix = 0xEF; // testnet
ninja.testnetMode = true;
}
if (ninja.getQueryString()["showseedpool"] == "true" || ninja.getQueryString()["showseedpool"] == "1") {
document.getElementById("seedpoolarea").style.display = "block";
}
// if users does not move mouse after random amount of time then generate the key anyway.
setTimeout(ninja.seeder.forceGenerate, ninja.seeder.seedLimit * 20);
setTimeout(ninja.seeder.forceGenerate, ninja.seeder.seedLimit * 100);

View file

@ -17,6 +17,7 @@
sr.state;
sr.pool;
sr.pptr;
sr.poolCopyOnInit;
// Pool size must be a multiple of 4 and greater than 32.
// An array of bytes the size of the pool will be passed to init()
@ -46,8 +47,9 @@
sr.seedTime();
sr.state = sr.ArcFour(); // Plug in your RNG constructor here
sr.state.init(sr.pool);
sr.poolCopyOnInit = [];
for (sr.pptr = 0; sr.pptr < sr.pool.length; ++sr.pptr)
sr.pool[sr.pptr] = 0;
sr.poolCopyOnInit[sr.pptr] = sr.pool[sr.pptr];
sr.pptr = 0;
}
// TODO: allow reseeding after first request
@ -56,13 +58,17 @@
// Mix in a 32-bit integer into the pool
sr.seedInt = function (x) {
sr.pool[sr.pptr++] ^= x & 255;
sr.pool[sr.pptr++] ^= (x >> 8) & 255;
sr.pool[sr.pptr++] ^= (x >> 16) & 255;
sr.pool[sr.pptr++] ^= (x >> 24) & 255;
if (sr.pptr >= sr.poolSize) sr.pptr -= sr.poolSize;
sr.seedInt8(x);
sr.seedInt8((x >> 8));
sr.seedInt8((x >> 16));
sr.seedInt8((x >> 24));
}
// Mix in a 8-bit integer into the pool
sr.seedInt8 = function (x) {
sr.pool[sr.pptr++] ^= x & 255;
if (sr.pptr >= sr.poolSize) sr.pptr -= sr.poolSize;
}
// Arcfour is a PRNG
sr.ArcFour = function () {
@ -110,11 +116,14 @@
sr.pool = new Array();
sr.pptr = 0;
var t;
if (navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) {
// Extract entropy (256 bits) from NS4 RNG if available
var z = window.crypto.random(32);
for (t = 0; t < z.length; ++t)
sr.pool[sr.pptr++] = z.charCodeAt(t) & 255;
if (window.crypto && window.crypto.getRandomValues) {
try {
// Use webcrypto if available
var ua = new Uint8Array(32);
window.crypto.getRandomValues(ua);
for (t = 0; t < 32; ++t)
sr.pool[sr.pptr++] = ua[t];
} catch (e) { alert(e); }
}
while (sr.pptr < sr.poolSize) { // extract some randomness from Math.random()
t = Math.floor(65536 * Math.random());
@ -124,7 +133,35 @@
sr.pptr = 0;
sr.seedTime();
// entropy
sr.seedInt(window.screenX);
sr.seedInt(window.screenY);
var entropyStr = "";
// screen size and color depth: ~4.8 to ~5.4 bits
entropyStr += (window.screen.height * window.screen.width * window.screen.colorDepth);
entropyStr += (window.screen.availHeight * window.screen.availWidth * window.screen.pixelDepth);
// time zone offset: ~4 bits
var dateObj = new Date();
var timeZoneOffset = dateObj.getTimezoneOffset();
entropyStr += timeZoneOffset;
// user agent: ~8.3 to ~11.6 bits
entropyStr += navigator.userAgent;
// browser plugin details: ~16.2 to ~21.8 bits
var pluginsStr = "";
for (var i = 0; i < navigator.plugins.length; i++) {
pluginsStr += navigator.plugins[i].name + " " + navigator.plugins[i].filename + " " + navigator.plugins[i].description + " " + navigator.plugins[i].version + ", ";
}
var mimeTypesStr = "";
for (var i = 0; i < navigator.mimeTypes.length; i++) {
mimeTypesStr += navigator.mimeTypes[i].description + " " + navigator.mimeTypes[i].type + " " + navigator.mimeTypes[i].suffixes + ", ";
}
entropyStr += pluginsStr + mimeTypesStr;
// cookies and storage: 1 bit
entropyStr += navigator.cookieEnabled + typeof (sessionStorage) + typeof (localStorage);
var entropyBytes = Crypto.SHA256(entropyStr, { asBytes: true });
sr.seedInt8(entropyBytes[0]);
sr.seedInt8(entropyBytes[1]);
sr.seedInt8(entropyBytes[2]);
sr.seedInt8(entropyBytes[3]);
sr.seedInt8(entropyBytes[4]);
sr.seedInt8(entropyBytes[5]);
}
})();