summaryrefslogtreecommitdiff
path: root/school/node_modules/node-forge/js/random.js
diff options
context:
space:
mode:
Diffstat (limited to 'school/node_modules/node-forge/js/random.js')
-rw-r--r--school/node_modules/node-forge/js/random.js237
1 files changed, 237 insertions, 0 deletions
diff --git a/school/node_modules/node-forge/js/random.js b/school/node_modules/node-forge/js/random.js
new file mode 100644
index 0000000..febc1fd
--- /dev/null
+++ b/school/node_modules/node-forge/js/random.js
@@ -0,0 +1,237 @@
+/**
+ * An API for getting cryptographically-secure random bytes. The bytes are
+ * generated using the Fortuna algorithm devised by Bruce Schneier and
+ * Niels Ferguson.
+ *
+ * Getting strong random bytes is not yet easy to do in javascript. The only
+ * truish random entropy that can be collected is from the mouse, keyboard, or
+ * from timing with respect to page loads, etc. This generator makes a poor
+ * attempt at providing random bytes when those sources haven't yet provided
+ * enough entropy to initially seed or to reseed the PRNG.
+ *
+ * @author Dave Longley
+ *
+ * Copyright (c) 2009-2014 Digital Bazaar, Inc.
+ */
+(function() {
+/* ########## Begin module implementation ########## */
+function initModule(forge) {
+
+// forge.random already defined
+if(forge.random && forge.random.getBytes) {
+ return;
+}
+
+(function(jQuery) {
+
+// the default prng plugin, uses AES-128
+var prng_aes = {};
+var _prng_aes_output = new Array(4);
+var _prng_aes_buffer = forge.util.createBuffer();
+prng_aes.formatKey = function(key) {
+ // convert the key into 32-bit integers
+ var tmp = forge.util.createBuffer(key);
+ key = new Array(4);
+ key[0] = tmp.getInt32();
+ key[1] = tmp.getInt32();
+ key[2] = tmp.getInt32();
+ key[3] = tmp.getInt32();
+
+ // return the expanded key
+ return forge.aes._expandKey(key, false);
+};
+prng_aes.formatSeed = function(seed) {
+ // convert seed into 32-bit integers
+ var tmp = forge.util.createBuffer(seed);
+ seed = new Array(4);
+ seed[0] = tmp.getInt32();
+ seed[1] = tmp.getInt32();
+ seed[2] = tmp.getInt32();
+ seed[3] = tmp.getInt32();
+ return seed;
+};
+prng_aes.cipher = function(key, seed) {
+ forge.aes._updateBlock(key, seed, _prng_aes_output, false);
+ _prng_aes_buffer.putInt32(_prng_aes_output[0]);
+ _prng_aes_buffer.putInt32(_prng_aes_output[1]);
+ _prng_aes_buffer.putInt32(_prng_aes_output[2]);
+ _prng_aes_buffer.putInt32(_prng_aes_output[3]);
+ return _prng_aes_buffer.getBytes();
+};
+prng_aes.increment = function(seed) {
+ // FIXME: do we care about carry or signed issues?
+ ++seed[3];
+ return seed;
+};
+prng_aes.md = forge.md.sha256;
+
+/**
+ * Creates a new PRNG.
+ */
+function spawnPrng() {
+ var ctx = forge.prng.create(prng_aes);
+
+ /**
+ * Gets random bytes. If a native secure crypto API is unavailable, this
+ * method tries to make the bytes more unpredictable by drawing from data that
+ * can be collected from the user of the browser, eg: mouse movement.
+ *
+ * If a callback is given, this method will be called asynchronously.
+ *
+ * @param count the number of random bytes to get.
+ * @param [callback(err, bytes)] called once the operation completes.
+ *
+ * @return the random bytes in a string.
+ */
+ ctx.getBytes = function(count, callback) {
+ return ctx.generate(count, callback);
+ };
+
+ /**
+ * Gets random bytes asynchronously. If a native secure crypto API is
+ * unavailable, this method tries to make the bytes more unpredictable by
+ * drawing from data that can be collected from the user of the browser,
+ * eg: mouse movement.
+ *
+ * @param count the number of random bytes to get.
+ *
+ * @return the random bytes in a string.
+ */
+ ctx.getBytesSync = function(count) {
+ return ctx.generate(count);
+ };
+
+ return ctx;
+}
+
+// create default prng context
+var _ctx = spawnPrng();
+
+// add other sources of entropy only if window.crypto.getRandomValues is not
+// available -- otherwise this source will be automatically used by the prng
+var _nodejs = (
+ typeof process !== 'undefined' && process.versions && process.versions.node);
+var getRandomValues = null;
+if(typeof window !== 'undefined') {
+ var _crypto = window.crypto || window.msCrypto;
+ if(_crypto && _crypto.getRandomValues) {
+ getRandomValues = function(arr) {
+ return _crypto.getRandomValues(arr);
+ };
+ }
+}
+if(forge.disableNativeCode || (!_nodejs && !getRandomValues)) {
+ // if this is a web worker, do not use weak entropy, instead register to
+ // receive strong entropy asynchronously from the main thread
+ if(typeof window === 'undefined' || window.document === undefined) {
+ // FIXME:
+ }
+
+ // get load time entropy
+ _ctx.collectInt(+new Date(), 32);
+
+ // add some entropy from navigator object
+ if(typeof(navigator) !== 'undefined') {
+ var _navBytes = '';
+ for(var key in navigator) {
+ try {
+ if(typeof(navigator[key]) == 'string') {
+ _navBytes += navigator[key];
+ }
+ } catch(e) {
+ /* Some navigator keys might not be accessible, e.g. the geolocation
+ attribute throws an exception if touched in Mozilla chrome://
+ context.
+
+ Silently ignore this and just don't use this as a source of
+ entropy. */
+ }
+ }
+ _ctx.collect(_navBytes);
+ _navBytes = null;
+ }
+
+ // add mouse and keyboard collectors if jquery is available
+ if(jQuery) {
+ // set up mouse entropy capture
+ jQuery().mousemove(function(e) {
+ // add mouse coords
+ _ctx.collectInt(e.clientX, 16);
+ _ctx.collectInt(e.clientY, 16);
+ });
+
+ // set up keyboard entropy capture
+ jQuery().keypress(function(e) {
+ _ctx.collectInt(e.charCode, 8);
+ });
+ }
+}
+
+/* Random API */
+if(!forge.random) {
+ forge.random = _ctx;
+} else {
+ // extend forge.random with _ctx
+ for(var key in _ctx) {
+ forge.random[key] = _ctx[key];
+ }
+}
+
+// expose spawn PRNG
+forge.random.createInstance = spawnPrng;
+
+})(typeof(jQuery) !== 'undefined' ? jQuery : null);
+
+} // end module implementation
+
+/* ########## Begin module wrapper ########## */
+var name = 'random';
+if(typeof define !== 'function') {
+ // NodeJS -> AMD
+ if(typeof module === 'object' && module.exports) {
+ var nodeJS = true;
+ define = function(ids, factory) {
+ factory(require, module);
+ };
+ } else {
+ // <script>
+ if(typeof forge === 'undefined') {
+ forge = {};
+ }
+ return initModule(forge);
+ }
+}
+// AMD
+var deps;
+var defineFunc = function(require, module) {
+ module.exports = function(forge) {
+ var mods = deps.map(function(dep) {
+ return require(dep);
+ }).concat(initModule);
+ // handle circular dependencies
+ forge = forge || {};
+ forge.defined = forge.defined || {};
+ if(forge.defined[name]) {
+ return forge[name];
+ }
+ forge.defined[name] = true;
+ for(var i = 0; i < mods.length; ++i) {
+ mods[i](forge);
+ }
+ return forge[name];
+ };
+};
+var tmpDefine = define;
+define = function(ids, factory) {
+ deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
+ if(nodeJS) {
+ delete define;
+ return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
+ }
+ define = tmpDefine;
+ return define.apply(null, Array.prototype.slice.call(arguments, 0));
+};
+define(['require', 'module', './aes', './md', './prng', './util'], function() {
+ defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
+});
+})();