Secure.js 2.6 KB

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