import { __commonJS } from "../../../_virtual/rolldown_runtime.mjs";
import { require_forge } from "./forge.mjs";
import { require_util } from "./util.mjs";
import { require_lib } from "../lib.mjs";

//#region ../../node_modules/node-forge/lib/prng.js
var require_prng = /* @__PURE__ */ __commonJS({ "../../node_modules/node-forge/lib/prng.js": ((exports, module) => {
	/**
	* A javascript implementation of a cryptographically-secure
	* Pseudo Random Number Generator (PRNG). The Fortuna algorithm is followed
	* here though the use of SHA-256 is not enforced; when generating an
	* a PRNG context, the hashing algorithm and block cipher used for
	* the generator are specified via a plugin.
	*
	* @author Dave Longley
	*
	* Copyright (c) 2010-2014 Digital Bazaar, Inc.
	*/
	var forge = require_forge();
	require_util();
	var _crypto = null;
	if (forge.util.isNodejs && !forge.options.usePureJavaScript && !process.versions["node-webkit"]) _crypto = require_lib();
	var prng = module.exports = forge.prng = forge.prng || {};
	/**
	* Creates a new PRNG context.
	*
	* A PRNG plugin must be passed in that will provide:
	*
	* 1. A function that initializes the key and seed of a PRNG context. It
	*   will be given a 16 byte key and a 16 byte seed. Any key expansion
	*   or transformation of the seed from a byte string into an array of
	*   integers (or similar) should be performed.
	* 2. The cryptographic function used by the generator. It takes a key and
	*   a seed.
	* 3. A seed increment function. It takes the seed and returns seed + 1.
	* 4. An api to create a message digest.
	*
	* For an example, see random.js.
	*
	* @param plugin the PRNG plugin to use.
	*/
	prng.create = function(plugin) {
		var ctx = {
			plugin,
			key: null,
			seed: null,
			time: null,
			reseeds: 0,
			generated: 0,
			keyBytes: ""
		};
		var md = plugin.md;
		var pools = new Array(32);
		for (var i = 0; i < 32; ++i) pools[i] = md.create();
		ctx.pools = pools;
		ctx.pool = 0;
		/**
		* Generates random bytes. The bytes may be generated synchronously or
		* asynchronously. Web workers must use the asynchronous interface or
		* else the behavior is undefined.
		*
		* @param count the number of random bytes to generate.
		* @param [callback(err, bytes)] called once the operation completes.
		*
		* @return count random bytes as a string.
		*/
		ctx.generate = function(count, callback) {
			if (!callback) return ctx.generateSync(count);
			var cipher = ctx.plugin.cipher;
			var increment = ctx.plugin.increment;
			var formatKey = ctx.plugin.formatKey;
			var formatSeed = ctx.plugin.formatSeed;
			var b = forge.util.createBuffer();
			ctx.key = null;
			generate();
			function generate(err) {
				if (err) return callback(err);
				if (b.length() >= count) return callback(null, b.getBytes(count));
				if (ctx.generated > 1048575) ctx.key = null;
				if (ctx.key === null) return forge.util.nextTick(function() {
					_reseed(generate);
				});
				var bytes = cipher(ctx.key, ctx.seed);
				ctx.generated += bytes.length;
				b.putBytes(bytes);
				ctx.key = formatKey(cipher(ctx.key, increment(ctx.seed)));
				ctx.seed = formatSeed(cipher(ctx.key, ctx.seed));
				forge.util.setImmediate(generate);
			}
		};
		/**
		* Generates random bytes synchronously.
		*
		* @param count the number of random bytes to generate.
		*
		* @return count random bytes as a string.
		*/
		ctx.generateSync = function(count) {
			var cipher = ctx.plugin.cipher;
			var increment = ctx.plugin.increment;
			var formatKey = ctx.plugin.formatKey;
			var formatSeed = ctx.plugin.formatSeed;
			ctx.key = null;
			var b = forge.util.createBuffer();
			while (b.length() < count) {
				if (ctx.generated > 1048575) ctx.key = null;
				if (ctx.key === null) _reseedSync();
				var bytes = cipher(ctx.key, ctx.seed);
				ctx.generated += bytes.length;
				b.putBytes(bytes);
				ctx.key = formatKey(cipher(ctx.key, increment(ctx.seed)));
				ctx.seed = formatSeed(cipher(ctx.key, ctx.seed));
			}
			return b.getBytes(count);
		};
		/**
		* Private function that asynchronously reseeds a generator.
		*
		* @param callback(err) called once the operation completes.
		*/
		function _reseed(callback) {
			if (ctx.pools[0].messageLength >= 32) {
				_seed();
				return callback();
			}
			var needed = 32 - ctx.pools[0].messageLength << 5;
			ctx.seedFile(needed, function(err, bytes) {
				if (err) return callback(err);
				ctx.collect(bytes);
				_seed();
				callback();
			});
		}
		/**
		* Private function that synchronously reseeds a generator.
		*/
		function _reseedSync() {
			if (ctx.pools[0].messageLength >= 32) return _seed();
			var needed = 32 - ctx.pools[0].messageLength << 5;
			ctx.collect(ctx.seedFileSync(needed));
			_seed();
		}
		/**
		* Private function that seeds a generator once enough bytes are available.
		*/
		function _seed() {
			ctx.reseeds = ctx.reseeds === 4294967295 ? 0 : ctx.reseeds + 1;
			var md$1 = ctx.plugin.md.create();
			md$1.update(ctx.keyBytes);
			var _2powK = 1;
			for (var k = 0; k < 32; ++k) {
				if (ctx.reseeds % _2powK === 0) {
					md$1.update(ctx.pools[k].digest().getBytes());
					ctx.pools[k].start();
				}
				_2powK = _2powK << 1;
			}
			ctx.keyBytes = md$1.digest().getBytes();
			md$1.start();
			md$1.update(ctx.keyBytes);
			var seedBytes = md$1.digest().getBytes();
			ctx.key = ctx.plugin.formatKey(ctx.keyBytes);
			ctx.seed = ctx.plugin.formatSeed(seedBytes);
			ctx.generated = 0;
		}
		/**
		* The built-in default seedFile. This seedFile is used when entropy
		* is needed immediately.
		*
		* @param needed the number of bytes that are needed.
		*
		* @return the random bytes.
		*/
		function defaultSeedFile(needed) {
			var getRandomValues = null;
			var globalScope = forge.util.globalScope;
			var _crypto$1 = globalScope.crypto || globalScope.msCrypto;
			if (_crypto$1 && _crypto$1.getRandomValues) getRandomValues = function(arr) {
				return _crypto$1.getRandomValues(arr);
			};
			var b = forge.util.createBuffer();
			if (getRandomValues) while (b.length() < needed) {
				var count = Math.max(1, Math.min(needed - b.length(), 65536) / 4);
				var entropy = new Uint32Array(Math.floor(count));
				try {
					getRandomValues(entropy);
					for (var i$1 = 0; i$1 < entropy.length; ++i$1) b.putInt32(entropy[i$1]);
				} catch (e) {
					if (!(typeof QuotaExceededError !== "undefined" && e instanceof QuotaExceededError)) throw e;
				}
			}
			if (b.length() < needed) {
				var hi, lo, next;
				var seed = Math.floor(Math.random() * 65536);
				while (b.length() < needed) {
					lo = 16807 * (seed & 65535);
					hi = 16807 * (seed >> 16);
					lo += (hi & 32767) << 16;
					lo += hi >> 15;
					lo = (lo & 2147483647) + (lo >> 31);
					seed = lo & 4294967295;
					for (var i$1 = 0; i$1 < 3; ++i$1) {
						next = seed >>> (i$1 << 3);
						next ^= Math.floor(Math.random() * 256);
						b.putByte(next & 255);
					}
				}
			}
			return b.getBytes(needed);
		}
		if (_crypto) {
			ctx.seedFile = function(needed, callback) {
				_crypto.randomBytes(needed, function(err, bytes) {
					if (err) return callback(err);
					callback(null, bytes.toString());
				});
			};
			ctx.seedFileSync = function(needed) {
				return _crypto.randomBytes(needed).toString();
			};
		} else {
			ctx.seedFile = function(needed, callback) {
				try {
					callback(null, defaultSeedFile(needed));
				} catch (e) {
					callback(e);
				}
			};
			ctx.seedFileSync = defaultSeedFile;
		}
		/**
		* Adds entropy to a prng ctx's accumulator.
		*
		* @param bytes the bytes of entropy as a string.
		*/
		ctx.collect = function(bytes) {
			var count = bytes.length;
			for (var i$1 = 0; i$1 < count; ++i$1) {
				ctx.pools[ctx.pool].update(bytes.substr(i$1, 1));
				ctx.pool = ctx.pool === 31 ? 0 : ctx.pool + 1;
			}
		};
		/**
		* Collects an integer of n bits.
		*
		* @param i the integer entropy.
		* @param n the number of bits in the integer.
		*/
		ctx.collectInt = function(i$1, n) {
			var bytes = "";
			for (var x = 0; x < n; x += 8) bytes += String.fromCharCode(i$1 >> x & 255);
			ctx.collect(bytes);
		};
		/**
		* Registers a Web Worker to receive immediate entropy from the main thread.
		* This method is required until Web Workers can access the native crypto
		* API. This method should be called twice for each created worker, once in
		* the main thread, and once in the worker itself.
		*
		* @param worker the worker to register.
		*/
		ctx.registerWorker = function(worker) {
			if (worker === self) ctx.seedFile = function(needed, callback) {
				function listener$1(e) {
					var data = e.data;
					if (data.forge && data.forge.prng) {
						self.removeEventListener("message", listener$1);
						callback(data.forge.prng.err, data.forge.prng.bytes);
					}
				}
				self.addEventListener("message", listener$1);
				self.postMessage({ forge: { prng: { needed } } });
			};
			else {
				var listener = function(e) {
					var data = e.data;
					if (data.forge && data.forge.prng) ctx.seedFile(data.forge.prng.needed, function(err, bytes) {
						worker.postMessage({ forge: { prng: {
							err,
							bytes
						} } });
					});
				};
				worker.addEventListener("message", listener);
			}
		};
		return ctx;
	};
}) });

//#endregion
export default require_prng();

export { require_prng };
//# sourceMappingURL=prng.mjs.map