123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840 |
- /*
- * Copyright 2018 Scytl Secure Electronic Voting SA
- *
- * All rights reserved
- *
- * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
- */
- var cryptoPRNG = (function() {
- 'use strict';
- return {
- _collectorsStarted: false,
- _collectors: [],
- _events: [],
- _entropy: '',
- _entropyCounter: 0,
- _maxEntropyCounter: 0,
- _collectorHashUpdater: null,
- _hashUpdaterInterval: 0,
- _fullEntropyCallback: null,
- _tools: null,
- _seedLength: 0,
- _prng: null,
- _privateKeyPem: '',
- _pinEntropy: 0,
- _usePrivateKeyEntropy: false,
- /**
- * Initializes all the round object fields.
- *
- * @function
- * @param hashUpdaterInterval
- * the interval, in millis, that the function that replaces the
- * current entropy content by an hash is called. By default it is
- * initialized to 5000.
- * @param maxEntropyCounter
- * number of maximum bits used to determine when the collectors
- * should stop collecting entropy. By default it is initialized
- * to 256.
- */
- _initAndStart: function(hashUpdaterInterval, fullEntropyCallback) {
- this._collectorsStarted = false;
- this._collectors = [];
- this._events = [];
- this._entropy = '';
- this._entropyCounter = 0;
- this._maxEntropyCounter = 256;
- this._collectorHashUpdater = null;
- this._hashUpdaterInterval =
- (hashUpdaterInterval ? hashUpdaterInterval : 1000);
- this._fullEntropyCallback = fullEntropyCallback;
- this._tools = cryptoPRNG.Tools.init();
- this._initCollectors();
- this._startCollectors();
- },
- /**
- * adds a new collector to the list of available connectors
- *
- * @param collector
- * must return an object that implements the startCollector and
- * stopCollector methods
- */
- _addCollector: function(collector) {
- this._collectors.push(collector);
- },
- /**
- * adds a new event to the list of available events
- *
- * @param type
- * event type
- * @param listener
- * function that will be executed
- */
- _addEvent: function(type, listener) {
- this._events.push({'type': type, 'listener': listener});
- },
- /**
- * Initializes the random generator with the web kit random collector if
- * available.
- *
- * If it is not, it considers the rest of collectors: ajax calls collector,
- * JS calls execution collector, navigator information collector, math
- * random collector, web kit random collector, mouse events collectors, key
- * events collectors, load event collector, scroll collector)
- */
- _initCollectors: function() {
- if (this._noWindow()) {
- this._addNonWindowEntropyCollectors();
- return;
- }
- var _crypto = this._getCrypto();
- if ((_crypto) && (_crypto.getRandomValues)) {
- this._addCollector(cryptoPRNG.Collectors.getWebKitRandomCollector(
- _crypto, this._maxEntropyCounter));
- } else {
- this._addNonWindowEntropyCollectors();
- // The API detects and delivers accelerometer data 50 times per
- // second
- if (window.DeviceOrientationEvent) {
- // Listen for the device orientation event and handle
- // DeviceOrientationEvent object
- this._addEvent(
- 'deviceorientation',
- cryptoPRNG.Collectors.getDeviceOrientationCollector);
- } else if (window.OrientationEvent) {
- // Listen for the MozOrientation event and handle
- // OrientationData object
- this._addEvent(
- 'MozOrientation',
- cryptoPRNG.Collectors.getDeviceOrientationCollector);
- }
- if (window.DeviceMotionEvent) {
- this._addEvent(
- 'devicemotion', cryptoPRNG.Collectors.getDeviceMotionCollector);
- }
- }
- },
- _addNonWindowEntropyCollectors: function() {
- if (this._usePrivateKeyEntropy) {
- this._addCollector(cryptoPRNG.Collectors.getPrivateKeyCollector(
- this._privateKeyPem, this._pinEntropy));
- }
- this._addCollector(cryptoPRNG.Collectors.getAjaxCollector());
- this._addCollector(cryptoPRNG.Collectors.getJSExecutionCollector());
- this._addCollector(cryptoPRNG.Collectors.getNavigatorInfoCollector());
- this._addCollector(cryptoPRNG.Collectors.getMathRandomCollector());
- // mouse events collectors
- this._addEvent('mousemove', cryptoPRNG.Collectors.getMouseMoveCollector);
- this._addEvent(
- 'mousewheel', cryptoPRNG.Collectors.getMouseWheelCollector);
- this._addEvent('mouseup', cryptoPRNG.Collectors.getMouseUpCollector);
- this._addEvent('mousedown', cryptoPRNG.Collectors.getMouseDownCollector);
- this._addEvent(
- 'touchstart', cryptoPRNG.Collectors.getTouchStartCollector);
- this._addEvent('touchmove', cryptoPRNG.Collectors.getTouchMoveCollector);
- this._addEvent('touchend', cryptoPRNG.Collectors.getTouchEndCollector);
- this._addEvent(
- 'gesturestart', cryptoPRNG.Collectors.getGestureStartCollector);
- this._addEvent(
- 'gestureend', cryptoPRNG.Collectors.getGestureEndCollector);
- // keyboard events collectors
- this._addEvent('keyup', cryptoPRNG.Collectors.getKeyUpCollector);
- this._addEvent('keydown', cryptoPRNG.Collectors.getKeyDownCollector);
- // page events collectors
- this._addEvent('load', cryptoPRNG.Collectors.getLoadCollector);
- this._addEvent('scroll', cryptoPRNG.Collectors.getScrollCollector);
- // requests collector collectors
- this._addEvent('beforeload', cryptoPRNG.Collectors.getRequestsCollector);
- },
- _getCrypto: function() {
- return window.crypto || window.msCrypto;
- },
- _noWindow: function() {
- return (typeof window === 'undefined');
- },
- /**
- * Start the collectors
- */
- _startCollectors: function() {
- if (this._collectorsStarted) {
- return;
- }
- var i = 0;
- // start all the collectors
- while (i < this._collectors.length) {
- try {
- this._collectors[i].startCollector();
- } catch (e) {
- // do not do anything about any exception that is thrown
- // by the execution of the collectors
- }
- i++;
- }
- i = 0;
- // start all the events
- while (i < this._events.length) {
- try {
- if (window.addEventListener) {
- window.addEventListener(
- this._events[i].type, this._events[i].listener, false);
- } else if (document.attachEvent) {
- document.attachEvent(
- 'on' + this._events[i].type, this._events[i].listener);
- }
- } catch (e) {
- // do not do anything about any exception that is thrown
- // by the execution of the events
- }
- i++;
- }
- this._tools._mdUpdate.start();
- this._collectorHashUpdater = setInterval(function() {
- cryptoPRNG._hashUpdater();
- }, this._hashUpdaterInterval);
- this._collectorsStarted = true;
- },
- /**
- * Stop the collectors
- */
- _stopCollectors: function() {
- if (!this._collectorsStarted) {
- return;
- }
- var i = 0;
- while (i < this._collectors.length) {
- try {
- this._collectors[i].stopCollector();
- } catch (e) {
- // do not do anything about any exception that is thrown
- // by the execution of the collectors
- }
- i++;
- }
- i = 0;
- while (i < this._events.length) {
- try {
- if (window.removeEventListener) {
- window.removeEventListener(
- this._events[i].type, this._events[i].listener, false);
- } else if (document.detachEvent) {
- document.detachEvent(
- 'on' + this._events[i].type, this._events[i].listener);
- }
- } catch (e) {
- // do not do anything about any exception that is thrown
- // by the remove of the events
- }
- i++;
- }
- if (this._collectorHashUpdater) {
- clearInterval(this._collectorHashUpdater);
- }
- this._collectorsStarted = false;
- },
- /**
- * Usually this method is called from the collectors and events. It adds
- * entropy to the already collected entropy and increments the entropy
- * counter
- *
- * @param data
- * the entropy data to be added
- * @param entropyCounter
- * the entropy counter to be added
- */
- _collectEntropy: function(data, entropyCounter) {
- this._entropy += data;
- this._entropyCounter += (entropyCounter ? entropyCounter : 0);
- // if the entropy counter has reach the limit, update the hash and stop
- // the collectors
- if (this._entropyCounter >= this._maxEntropyCounter &&
- this._collectorsStarted) {
- this._hashUpdater();
- }
- },
- /**
- * Sets the entropy data with the hash that is created using the current
- * entropy data value. If the entropy counter has reached the max entropy
- * counter set, it stops the collectors
- *
- * @return the generated entropy hash
- */
- _hashUpdater: function() {
- var entropyHash = this._updateEntropyHash();
- if (this._entropyCounter >= this._maxEntropyCounter &&
- this._collectorsStarted) {
- entropyHash = this._stopCollectEntropy();
- var newPRNG = new cryptoPRNG.PRNG(entropyHash, this._tools);
- if (this._fullEntropyCallback) {
- this._fullEntropyCallback(newPRNG);
- } else {
- this._prng = newPRNG;
- }
- }
- return entropyHash;
- },
- _stopCollectEntropy: function() {
- // stop collecting entropy
- this._stopCollectors();
- var entropyHash = this._updateEntropyHash();
- this._entropy = '';
- this._entropyCounter = 0;
- return entropyHash;
- },
- _updateEntropyHash: function() {
- var digester = this._tools._mdUpdate;
- digester.update(this._entropy);
- var entropyHash = forge.util.bytesToHex(digester.digest().getBytes());
- this._entropy = entropyHash;
- return entropyHash;
- },
- /**
- * Set Private Key and an Entropy it adds to be used to collect Entropy. The
- * amount of randomness(entropy) depends on the pin that is used for Private
- * Key generating.
- *
- * @function
- * @param privateKey
- * {string} private key, as string in PEM format.
- * @param pinEntropy
- * the amount of randomness that can be extracted from the
- * Private Key.
- */
- setDataForPrivateKeyEntropyCollector: function(privateKeyPem, pinEntropy) {
- if (privateKeyPem && (!isNaN(pinEntropy)) && (pinEntropy > 0)) {
- this._privateKeyPem = privateKeyPem;
- this._pinEntropy = pinEntropy;
- this._usePrivateKeyEntropy = true;
- }
- },
- /**
- * Initializes collectors and starts them. Set Private Key and Entropy
- * before if this information should be used to collect Entropy.
- */
- startEntropyCollection: function(entropyCollectorCallback) {
- var hashUpdaterInterval = 1000;
- this._initAndStart(hashUpdaterInterval, entropyCollectorCallback);
- },
- /**
- * In the case that the maximum amount of entropy had been reached before
- * calling this method, it does not do anything, and a false is returned.
- * Otherwise, this method creates a PRNG if the collectors have not gathered
- * the maximum amount of entropy. In addition, it stops the collectors.
- *
- * This method return a true if the maximum entropy was already reached and
- * false in other case.
- */
- stopEntropyCollectionAndCreatePRNG: function() {
- var generatedWithMaximumEntropy = true;
- if (!this._prng) {
- var entropyHash = this._stopCollectEntropy();
- this._prng = new cryptoPRNG.PRNG(entropyHash, this._tools);
- generatedWithMaximumEntropy = false;
- }
- return generatedWithMaximumEntropy;
- },
- /**
- * This method creates a PRNG from a given seed, in Hexadecimal format. This
- * method is to be used from a Worker, which has received the seed from the
- * main thread.
- *
- * @param seed
- * A string of 64 characters. It represents a 32-byte array in
- * Hexadecimal.
- *
- */
- createPRNGFromSeed: function(seed) {
- this._prng = new cryptoPRNG.PRNG(seed, this._tools);
- },
- /**
- * Generates a random array of bytes, which is then formatted to hexadecimal
- * This method is to be called from the main thread, and the given string is
- * to be passed to a Worker.
- */
- generateRandomSeedInHex: function(lengthSeed) {
- this._seedLength = (lengthSeed ? lengthSeed : 32);
- var seedInBytes = this._prng.generate(this._seedLength);
- return forge.util.bytesToHex(seedInBytes);
- },
- getPRNG: function() {
- if (!this._prng) {
- throw new Error('The PRNG has not been initialized yet');
- }
- return this._prng;
- },
- getEntropyCollectedAsPercentage: function() {
- if (this._entropyCounter >= this._maxEntropyCounter) {
- return 100;
- }
- return this._entropyCounter * 100 / this._maxEntropyCounter;
- }
- };
- })();
- cryptoPRNG.Tools = (function() {
- 'use strict';
- return {
- _mdUpdate: null,
- _mdReseed: null,
- _formatKey: null,
- _formatSeed: null,
- _cipher: null,
- init: function() {
- this._mdUpdate = forge.md.sha256.create();
- this._mdReseed = forge.md.sha256.create();
- this._formatKey = function(key) {
- // convert the key into 32-bit integers
- var tmp = forge.util.createBuffer(key);
- key = [
- tmp.getInt32(),
- tmp.getInt32(),
- tmp.getInt32(),
- tmp.getInt32(),
- tmp.getInt32(),
- tmp.getInt32(),
- tmp.getInt32(),
- tmp.getInt32()
- ];
- // return the expanded key
- return forge.aes._expandKey(key, false);
- };
- this._formatSeed = function(seed) {
- // convert seed into 32-bit integers
- var tmp = forge.util.createBuffer(seed);
- seed = [
- tmp.getInt32(),
- tmp.getInt32(),
- tmp.getInt32(),
- tmp.getInt32()
- ];
- return seed;
- };
- this._cipher = function(key, counter) {
- var aes_output = [];
- forge.aes._updateBlock(
- this._formatKey(key), this._formatSeed('' + counter), aes_output,
- false);
- var aes_buffer = forge.util.createBuffer();
- aes_buffer.putInt32(aes_output[0]);
- aes_buffer.putInt32(aes_output[1]);
- aes_buffer.putInt32(aes_output[2]);
- aes_buffer.putInt32(aes_output[3]);
- return aes_buffer.getBytes();
- };
- return this;
- }
- };
- })();
- cryptoPRNG.PRNG = function(entropyHash, tools) {
- 'use strict';
- this._key = '';
- this._counter = 0;
- this._tools = null;
- if (tools) {
- this._tools = tools;
- } else {
- this._tools = cryptoPRNG.Tools.init();
- }
- this._entropyHash = entropyHash;
- };
- cryptoPRNG.PRNG.prototype = (function() {
- 'use strict';
- return {
- /**
- * Generates a random array of bytes using the gathered entropy data.
- *
- * @param count
- * the total number of random bytes to generate
- */
- generate: function(count) {
- var keyAux;
- if (this._key === null || this._key === '') {
- this._reseed();
- }
- // buffer where to store the random bytes
- var b = forge.util.createBuffer();
- var limitReach = 1;
- while (b.length() < count) {
- b.putBytes(this._tools._cipher(this._key, this._counter));
- this._counter++;
- if (b.length >= (limitReach * Math.pow(2, 20))) {
- keyAux = this._key;
- this._key = '';
- for (var i = 0; i < 2; i++) {
- this._key += this._tools._cipher(keyAux, this._counter);
- this._counter++;
- }
- limitReach++;
- }
- }
- // do it two times to ensure a key with 256 bits
- keyAux = this._key;
- this._key = '';
- for (var j = 0; j < 2; j++) {
- this._key += this._tools._cipher(keyAux, this._counter);
- this._counter++;
- }
- return b.getBytes(count);
- },
- /**
- * Reseeds the generator
- */
- _reseed: function() {
- var digester = this._tools._mdReseed;
- digester.start();
- digester.update(this._entropyHash);
- digester.update(this._key);
- this._key = forge.util.bytesToHex(digester.digest().getBytes());
- this._counter++;
- }
- };
- })();
- cryptoPRNG.Collectors = (function() {
- 'use strict';
- var MIN_MATH_ROUND_ENTROPY_FACTOR = 1000000;
- function _getMathRoundWithEntropy(data) {
- return Math.round(data * MIN_MATH_ROUND_ENTROPY_FACTOR);
- }
- return {
- getAjaxCollector: function() {
- return {
- startCollector: function() {
- // if jQuery is included
- if (window.jQuery !== undefined) {
- $(window)
- .ajaxStart(function() {
- cryptoPRNG._collectEntropy((+new Date()), 1);
- })
- .ajaxComplete(function() {
- cryptoPRNG._collectEntropy((+new Date()), 1);
- });
- }
- },
- stopCollector: function() {
- // if jQuery is included
- if (window.jQuery !== undefined) {
- $(window).unbind('ajaxStart');
- $(window).unbind('ajaxComplete');
- }
- return true;
- }
- };
- },
- getJSExecutionCollector: function() {
- return {
- _collectTimeout: null,
- startCollector: function() {
- var timer_start = (+new Date()), timer_end;
- this._collectTimeout = (function collect() {
- timer_end = (+new Date());
- var total_time = timer_end - timer_start;
- // because of browser baseline time checks we limit it
- if (total_time > 20) {
- cryptoPRNG._collectEntropy((+new Date()), 1);
- }
- timer_start = timer_end;
- return setTimeout(collect, 0);
- })();
- },
- stopCollector: function() {
- clearTimeout(this._collectTimeout);
- }
- };
- },
- getNavigatorInfoCollector: function() {
- return {
- startCollector: function() {
- if (typeof(navigator) !== 'undefined') {
- var _navString = '';
- for (var key in navigator) {
- if (typeof key !== 'undefined') {
- try {
- if (typeof(navigator[key]) === 'string') {
- _navString += navigator[key];
- }
- } catch (e) {
- // ignore any kind of exception
- }
- }
- }
- cryptoPRNG._collectEntropy(_navString, 1);
- }
- },
- stopCollector: function() {
- // just executed once, so no need to execute nothing more
- return true;
- }
- };
- },
- getMathRandomCollector: function() {
- return {
- startCollector: function() {
- cryptoPRNG._collectEntropy(Math.random(), 0);
- },
- stopCollector: function() {
- // just executed once, so no need to execute nothing more
- return true;
- }
- };
- },
- getPrivateKeyCollector: function(privateKeyPem, pinEntropy) {
- var privateKey = forge.pki.privateKeyFromPem(privateKeyPem);
- return {
- pkCollector: true,
- startCollector: function() {
- cryptoPRNG._collectEntropy(privateKey.d, pinEntropy);
- },
- stopCollector: function() {
- // just executed once, so no need to execute nothing more
- return true;
- }
- };
- },
- getWebKitRandomCollector: function(globalCrypto, entropyQuantity) {
- return {
- startCollector: function() {
- var numPositions = entropyQuantity / 32;
- // get cryptographically strong entropy in Webkit
- var ab = new Uint32Array(numPositions);
- globalCrypto.getRandomValues(ab);
- var data = '';
- for (var i = 0; i < ab.length; i++) {
- data += '' + (ab[i]);
- }
- cryptoPRNG._collectEntropy(data, entropyQuantity);
- },
- stopCollector: function() {
- // just executed once, so no need to execute nothing more
- return true;
- }
- };
- },
- getMouseMoveCollector: function(ev) {
- // to ensure compatibility with IE 8
- ev = ev || window.event;
- cryptoPRNG._collectEntropy(
- (ev.x || ev.clientX || ev.offsetX || 0) +
- (ev.y || ev.clientY || ev.offsetY || 0) + (+new Date()),
- 3);
- },
- getMouseWheelCollector: function(ev) {
- ev = ev || window.event;
- cryptoPRNG._collectEntropy((ev.offsetY || 0) + (+new Date()), 3);
- },
- getMouseDownCollector: function(ev) {
- ev = ev || window.event;
- cryptoPRNG._collectEntropy(
- (ev.x || ev.clientX || ev.offsetX || 0) +
- (ev.y || ev.clientY || ev.offsetY || 0) + (+new Date()),
- 3);
- },
- getMouseUpCollector: function(ev) {
- ev = ev || window.event;
- cryptoPRNG._collectEntropy(
- (ev.x || ev.clientX || ev.offsetX || 0) +
- (ev.y || ev.clientY || ev.offsetY || 0) + (+new Date()),
- 3);
- },
- getTouchStartCollector: function(ev) {
- ev = ev || window.event;
- cryptoPRNG._collectEntropy(
- (ev.touches[0].pageX || ev.clientX || 0) +
- (ev.touches[0].pageY || ev.clientY || 0) + (+new Date()),
- 5);
- },
- getTouchMoveCollector: function(ev) {
- ev = ev || window.event;
- cryptoPRNG._collectEntropy(
- (ev.touches[0].pageX || ev.clientX || 0) +
- (ev.touches[0].pageY || ev.clientY || 0) + (+new Date()),
- 3);
- },
- getTouchEndCollector: function() {
- cryptoPRNG._collectEntropy((+new Date()), 1);
- },
- getGestureStartCollector: function(ev) {
- ev = ev || window.event;
- cryptoPRNG._collectEntropy(
- (ev.touches[0].pageX || ev.clientX || 0) +
- (ev.touches[0].pageY || ev.clientY || 0) + (+new Date()),
- 5);
- },
- getGestureEndCollector: function() {
- cryptoPRNG._collectEntropy((+new Date()), 1);
- },
- motionX: null,
- motionY: null,
- motionZ: null,
- getDeviceMotionCollector: function(ev) {
- ev = ev || window.event;
- var acceleration = ev.accelerationIncludingGravity;
- var currentX = (_getMathRoundWithEntropy(acceleration.x) || 0);
- var currentY = (_getMathRoundWithEntropy(acceleration.y) || 0);
- var currentZ = (_getMathRoundWithEntropy(acceleration.z) || 0);
- var rotation = ev.rotationRate;
- if (rotation !== null) {
- currentX += _getMathRoundWithEntropy(rotation.alpha);
- currentY += _getMathRoundWithEntropy(rotation.beta);
- currentZ += _getMathRoundWithEntropy(rotation.gamma);
- }
- // The API detects and delivers accelerometer data 50 times per
- // second
- // even if there is any event related, so this is
- // a way to control if it really changed or not
- if ((cryptoPRNG.Collectors.motionX === null) ||
- (cryptoPRNG.Collectors.motionY === null) ||
- (cryptoPRNG.Collectors.motionZ === null) ||
- (cryptoPRNG.Collectors.motionX !== currentX) ||
- (cryptoPRNG.Collectors.motionY !== currentY) ||
- (cryptoPRNG.Collectors.motionZ !== currentZ)) {
- cryptoPRNG.Collectors.motionX = currentX;
- cryptoPRNG.Collectors.motionY = currentY;
- cryptoPRNG.Collectors.motionZ = currentZ;
- cryptoPRNG._collectEntropy(
- currentX + currentY + currentZ + (+new Date()), 1);
- }
- },
- deviceOrientationX: null,
- deviceOrientationY: null,
- deviceOrientationZ: null,
- getDeviceOrientationCollector: function(ev) {
- ev = ev || window.event;
- var currentX =
- (_getMathRoundWithEntropy(ev.gamma) ||
- _getMathRoundWithEntropy(ev.x) || 0);
- var currentY =
- (_getMathRoundWithEntropy(ev.beta) ||
- _getMathRoundWithEntropy(ev.y) || 0);
- var currentZ =
- (_getMathRoundWithEntropy(ev.alpha) ||
- _getMathRoundWithEntropy(ev.z) || 0);
- // The API detects and delivers accelerometer data 50 times per
- // second
- // even if there is any event related, so this is
- // a way to control if it really changed or not
- if ((cryptoPRNG.Collectors.deviceOrientationX === null) ||
- (cryptoPRNG.Collectors.deviceOrientationY === null) ||
- (cryptoPRNG.Collectors.deviceOrientationZ === null) ||
- (cryptoPRNG.Collectors.deviceOrientationX !== currentX) ||
- (cryptoPRNG.Collectors.deviceOrientationY !== currentY) ||
- (cryptoPRNG.Collectors.deviceOrientationZ !== currentZ)) {
- cryptoPRNG.Collectors.deviceOrientationX = currentX;
- cryptoPRNG.Collectors.deviceOrientationY = currentY;
- cryptoPRNG.Collectors.deviceOrientationZ = currentZ;
- cryptoPRNG._collectEntropy(
- currentX + currentY + currentZ + (+new Date()), 1);
- }
- },
- getKeyDownCollector: function(ev) {
- ev = ev || window.event;
- cryptoPRNG._collectEntropy((ev.keyCode) + (+new Date()), 3);
- },
- getKeyUpCollector: function(ev) {
- ev = ev || window.event;
- cryptoPRNG._collectEntropy((ev.keyCode) + (+new Date()), 3);
- },
- getLoadCollector: function(ev) {
- ev = ev || window.event;
- cryptoPRNG._collectEntropy((ev.keyCode) + (+new Date()), 3);
- },
- getScrollCollector: function(ev) {
- ev = ev || window.event;
- cryptoPRNG._collectEntropy((ev.keyCode) + (+new Date()), 3);
- },
- getRequestsCollector: function(ev) {
- ev = ev || window.event;
- cryptoPRNG._collectEntropy((ev.keyCode) + (+new Date()), 3);
- }
- };
- })();
|