1 | // AMD-ID "dojox/math/random/Secure" |
---|
2 | define(["dojo"], function(dojo) { |
---|
3 | |
---|
4 | // Copyright (c) 2005 Tom Wu |
---|
5 | // All Rights Reserved. |
---|
6 | // See "LICENSE-BigInteger" for details. |
---|
7 | |
---|
8 | // Random number generator - requires a PRNG backend, e.g. prng4.js |
---|
9 | |
---|
10 | dojo.declare("dojox.math.random.Secure", null, { |
---|
11 | // summary: |
---|
12 | // Super simple implementation of a random number generator, |
---|
13 | // which relies on Math.random(). |
---|
14 | |
---|
15 | constructor: function(prng, noEvents){ |
---|
16 | // summary: |
---|
17 | // Intializes an instance of a secure random generator. |
---|
18 | // prng: Function: |
---|
19 | // function that returns an instance of PRNG (pseudorandom number generator) |
---|
20 | // with two methods: init(array) and next(). It should have a property "size" |
---|
21 | // to indicate the required pool size. |
---|
22 | // noEvents: Boolean?: |
---|
23 | // if false or absent, onclick and onkeypress event will be used to add |
---|
24 | // "randomness", otherwise events will not be used. |
---|
25 | this.prng = prng; |
---|
26 | |
---|
27 | // Initialize the pool with junk if needed. |
---|
28 | var p = this.pool = new Array(prng.size); |
---|
29 | this.pptr = 0; |
---|
30 | for(var i = 0, len = prng.size; i < len;) { // extract some randomness from Math.random() |
---|
31 | var t = Math.floor(65536 * Math.random()); |
---|
32 | p[i++] = t >>> 8; |
---|
33 | p[i++] = t & 255; |
---|
34 | } |
---|
35 | this.seedTime(); |
---|
36 | |
---|
37 | if(!noEvents){ |
---|
38 | this.h = [ |
---|
39 | dojo.connect(dojo.body(), "onclick", this, "seedTime"), |
---|
40 | dojo.connect(dojo.body(), "onkeypress", this, "seedTime") |
---|
41 | ]; |
---|
42 | } |
---|
43 | }, |
---|
44 | |
---|
45 | destroy: function(){ |
---|
46 | // summary: |
---|
47 | // Disconnects events, if any, preparing the object for GC. |
---|
48 | if(this.h){ |
---|
49 | dojo.forEach(this.h, dojo.disconnect); |
---|
50 | } |
---|
51 | }, |
---|
52 | |
---|
53 | nextBytes: function(/* Array */ byteArray){ |
---|
54 | // summary: |
---|
55 | // Fills in an array of bytes with random numbers |
---|
56 | // byteArray: Array: |
---|
57 | // array to be filled in with random numbers, only existing |
---|
58 | // elements will be filled. |
---|
59 | |
---|
60 | var state = this.state; |
---|
61 | |
---|
62 | if(!state){ |
---|
63 | this.seedTime(); |
---|
64 | state = this.state = this.prng(); |
---|
65 | state.init(this.pool); |
---|
66 | for(var p = this.pool, i = 0, len = p.length; i < len; p[i++] = 0); |
---|
67 | this.pptr = 0; |
---|
68 | //this.pool = null; |
---|
69 | } |
---|
70 | |
---|
71 | for(var i = 0, len = byteArray.length; i < len; ++i){ |
---|
72 | byteArray[i] = state.next(); |
---|
73 | } |
---|
74 | }, |
---|
75 | |
---|
76 | seedTime: function() { |
---|
77 | // summary: |
---|
78 | // Mix in the current time (w/milliseconds) into the pool |
---|
79 | this._seed_int(new Date().getTime()); |
---|
80 | }, |
---|
81 | |
---|
82 | _seed_int: function(x) { |
---|
83 | // summary: |
---|
84 | // Mix in a 32-bit integer into the pool |
---|
85 | var p = this.pool, i = this.pptr; |
---|
86 | p[i++] ^= x & 255; |
---|
87 | p[i++] ^= (x >> 8) & 255; |
---|
88 | p[i++] ^= (x >> 16) & 255; |
---|
89 | p[i++] ^= (x >> 24) & 255; |
---|
90 | if(i >= this.prng.size){ |
---|
91 | i -= this.prng.size; |
---|
92 | } |
---|
93 | this.pptr = i; |
---|
94 | } |
---|
95 | }); |
---|
96 | |
---|
97 | return dojox.math.random.Secure; |
---|
98 | }); |
---|