[483] | 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 | // Initializes an instance of a secure random generator. |
---|
| 18 | // prng: Function |
---|
| 19 | // function that returns an instance of PRNG (pseudo random 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 | }); |
---|