var forge=require("./forge");require("./util");var _crypto=null;!forge.util.isNodejs||forge.options.usePureJavaScript||process.versions["node-webkit"]||(_crypto=require("crypto"));var prng=module.exports=forge.prng=forge.prng||{};prng.create=function(e){for(var r={plugin:e,key:null,seed:null,time:null,reseeds:0,generated:0,keyBytes:""},t=e.md,n=Array(32),o=0;o<32;++o)n[o]=t.create();function s(){r.reseeds=0xffffffff===r.reseeds?0:r.reseeds+1;var e=r.plugin.md.create();e.update(r.keyBytes);for(var t=1,n=0;n<32;++n)r.reseeds%t==0&&(e.update(r.pools[n].digest().getBytes()),r.pools[n].start()),t<<=1;r.keyBytes=e.digest().getBytes(),e.start(),e.update(r.keyBytes);var o=e.digest().getBytes();r.key=r.plugin.formatKey(r.keyBytes),r.seed=r.plugin.formatSeed(o),r.generated=0}function l(e){var r=null,t=forge.util.globalScope,n=t.crypto||t.msCrypto;n&&n.getRandomValues&&(r=function(e){return n.getRandomValues(e)});var o=forge.util.createBuffer();if(r)for(;o.length()<e;){var s=new Uint32Array(Math.floor(Math.max(1,Math.min(e-o.length(),65536)/4)));try{r(s);for(var l=0;l<s.length;++l)o.putInt32(s[l])}catch(e){if(!("u">typeof QuotaExceededError&&e instanceof QuotaExceededError))throw e}}if(o.length()<e)for(var f,a,g,u=Math.floor(65536*Math.random());o.length()<e;){u=0|(a=(0x7fffffff&(a=16807*(65535&u)+(((32767&(f=16807*(u>>16)))<<16)+(f>>15))))+(a>>31));for(var l=0;l<3;++l)g=u>>>(l<<3)^Math.floor(256*Math.random()),o.putByte(255&g)}return o.getBytes(e)}return r.pools=n,r.pool=0,r.generate=function(e,t){if(!t)return r.generateSync(e);var n=r.plugin.cipher,o=r.plugin.increment,l=r.plugin.formatKey,f=r.plugin.formatSeed,a=forge.util.createBuffer();r.key=null,function g(u){if(u)return t(u);if(a.length()>=e)return t(null,a.getBytes(e));if(r.generated>1048575&&(r.key=null),null===r.key)return forge.util.nextTick(function(){!function(e){if(r.pools[0].messageLength>=32)return s(),e();var t=32-r.pools[0].messageLength<<5;r.seedFile(t,function(t,n){if(t)return e(t);r.collect(n),s(),e()})}(g)});var i=n(r.key,r.seed);r.generated+=i.length,a.putBytes(i),r.key=l(n(r.key,o(r.seed))),r.seed=f(n(r.key,r.seed)),forge.util.setImmediate(g)}()},r.generateSync=function(e){var t=r.plugin.cipher,n=r.plugin.increment,o=r.plugin.formatKey,l=r.plugin.formatSeed;r.key=null;for(var f=forge.util.createBuffer();f.length()<e;){r.generated>1048575&&(r.key=null),null===r.key&&function(){if(r.pools[0].messageLength>=32)return s();var e=32-r.pools[0].messageLength<<5;r.collect(r.seedFileSync(e)),s()}();var a=t(r.key,r.seed);r.generated+=a.length,f.putBytes(a),r.key=o(t(r.key,n(r.seed))),r.seed=l(t(r.key,r.seed))}return f.getBytes(e)},_crypto?(r.seedFile=function(e,r){_crypto.randomBytes(e,function(e,t){if(e)return r(e);r(null,t.toString())})},r.seedFileSync=function(e){return _crypto.randomBytes(e).toString()}):(r.seedFile=function(e,r){try{r(null,l(e))}catch(e){r(e)}},r.seedFileSync=l),r.collect=function(e){for(var t=e.length,n=0;n<t;++n)r.pools[r.pool].update(e.substr(n,1)),r.pool=31===r.pool?0:r.pool+1},r.collectInt=function(e,t){for(var n="",o=0;o<t;o+=8)n+=String.fromCharCode(e>>o&255);r.collect(n)},r.registerWorker=function(e){e===self?r.seedFile=function(e,r){self.addEventListener("message",function e(t){var n=t.data;n.forge&&n.forge.prng&&(self.removeEventListener("message",e),r(n.forge.prng.err,n.forge.prng.bytes))}),self.postMessage({forge:{prng:{needed:e}}})}:e.addEventListener("message",function(t){var n=t.data;n.forge&&n.forge.prng&&r.seedFile(n.forge.prng.needed,function(r,t){e.postMessage({forge:{prng:{err:r,bytes:t}}})})})},r};