Secure.js 2.9 KB

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