forked from RuslanZavacky/srp-6a-demo
/
random.js
72 lines (60 loc) · 1.89 KB
/
random.js
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
var random16byteHex = (function() {
function random() {
var wordCount = 4;
var randomWords;
// First we're going to try to use a built-in CSPRNG
if (window.crypto && window.crypto.getRandomValues) {
randomWords = new Int32Array(wordCount);
window.crypto.getRandomValues(randomWords);
}
// Because of course IE calls it msCrypto instead of being standard
else if (window.msCrypto && window.msCrypto.getRandomValues) {
randomWords = new Int32Array(wordCount);
window.msCrypto.getRandomValues(randomWords);
}
// Last resort - we'll use isaac.js to get a random number. It's seeded from Math.random(),
// but we can run it for 100ms/0.1s to advance it a distance which will be dependent upon
// hardware and js engine. Also we will have the onkeyup skip a char worth of values.
else {
randomWords = [];
for (var i = 0; i < wordCount; i++) {
randomWords.push(isaac.rand());
}
}
var string = '';
for( var i=0; i<wordCount; i++ ) {
var int32 = randomWords[i];
if( int32 < 0 ) int32 = -1 * int32;
string = string + int32.toString(16);
}
return string;
};
function isCrypto() {
if (window.crypto && window.crypto.getRandomValues) {
return true;
}
else if (window.msCrypto && window.msCrypto.getRandomValues) {
return true;
} else {
return false;
}
};
var crypto = isCrypto();
function advance(ms) {
if( !crypto ) {
var start = Date.now();
var end = start + ms;
while( Date.now() < end ) {
var r = isaac.random() * 128 + (Date.now() - start);
isaac.prng(Math.floor(r));
}
}
}
return {
'random' : random,
'isCrypto' : crypto,
'advance' : advance
};
})();
// if it is isaac spend 0.1s advancing the stream
random16byteHex.advance(100);