123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- /*
- * 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
- */
- cryptolib.modules.primitives = cryptolib.modules.primitives || {};
- /**
- * @namespace primitives/securerandom
- */
- cryptolib.modules.primitives.securerandom = function(box) {
- 'use strict';
- box.primitives = box.primitives || {};
- box.primitives.securerandom = {};
- /**
- * A module that holds secure random functionalities.
- *
- * @exports primitives/securerandom
- */
- box.primitives.securerandom.factory = {};
- var policies = {
- secureRandom: {provider: box.policies.primitives.secureRandom.provider}
- };
- var converters, exceptions;
- cryptolib('commons', function(box) {
- converters = new box.commons.utils.Converters();
- exceptions = box.commons.exceptions;
- });
- /**
- * A factory class for creating random generators.
- *
- * @class
- */
- box.primitives.securerandom.factory.SecureRandomFactory = function() {
- };
- box.primitives.securerandom.factory.SecureRandomFactory.prototype = {
- /**
- * Instantiates a random byte generator.
- *
- * @function
- * @returns {primitives/securerandom.CryptoScytlRandomBytes}
- */
- getCryptoRandomBytes: function() {
- try {
- if (policies.secureRandom.provider ===
- Config.primitives.secureRandom.provider.SCYTL) {
- return this.getCryptoScytlRandomBytes();
- } else {
- throw new exceptions.CryptoLibException(
- 'No suitable provider was provided.');
- }
- } catch (error) {
- throw new exceptions.CryptoLibException(
- 'A CryptoRandomBytes could not be obtained.', error);
- }
- },
- /**
- * Instantiates a Scytl random byte generator.
- *
- * @function
- * @returns {primitives/securerandom.CryptoScytlRandomBytes}
- */
- getCryptoScytlRandomBytes: function() {
- return new CryptoScytlRandomBytes();
- },
- /**
- * Instantiates a random integer generator.
- *
- * @function
- * @returns {primitives/securerandom.CryptoScytlRandomBytes}
- */
- getCryptoRandomInteger: function() {
- try {
- if (policies.secureRandom.provider ===
- Config.primitives.secureRandom.provider.SCYTL) {
- return this.getCryptoScytlRandomInteger();
- } else {
- throw new exceptions.CryptoLibException(
- 'No suitable provider was provided.');
- }
- } catch (error) {
- throw new exceptions.CryptoLibException(
- 'A CryptoRandomBytes could not be obtained.', error);
- }
- },
- /**
- * Instantiates a Scytl random integer generator.
- *
- * @function
- * @returns {primitives/securerandom.CryptoScytlRandomBytes}
- */
- getCryptoScytlRandomInteger: function() {
- return new CryptoScytlRandomInteger();
- }
- };
- var validate = function(length) {
- try {
- if (typeof length !== 'number') {
- throw new exceptions.CryptoLibException(
- 'The given length is not a number');
- }
- if (length < 1) {
- throw new exceptions.CryptoLibException(
- 'The given length should be a strictly positive integer.');
- }
- if (length > box.MAXIMUM_LENGTH_TO_GENERATE_DATA) {
- throw new exceptions.CryptoLibException(
- 'The given length should be lower than or equal to ' +
- box.MAXIMUM_LENGTH_TO_GENERATE_DATA);
- }
- } catch (error) {
- throw new exceptions.CryptoLibException(
- 'Random generation failed.', error);
- }
- };
- /**
- * The SCYTL Bytes Random Generator
- *
- * @class
- * @memberof primitives/securerandom
- */
- function CryptoScytlRandomBytes() {}
- CryptoScytlRandomBytes.prototype = {
- /**
- * Generates secure random bytes.
- *
- * @function
- * @param {number}
- * numBytes number of bytes to be generated..
- * @returns {string} secure random string.
- */
- nextRandom: function(length) {
- validate(length);
- var randomBytes = box.prng.generate(length);
- return randomBytes.toString();
- },
- /**
- * Method to be compliant with the Forge library.
- *
- * @function
- * @param {number}
- * numBytes number of bytes to be generated..
- * @returns {string} secure random string.
- */
- getBytesSync: function(length) {
- return this.nextRandom(length);
- }
- };
- /**
- * The SCYTL Integer Random Generator
- *
- * @class
- * @memberof primitives/securerandom
- */
- function CryptoScytlRandomInteger() {}
- CryptoScytlRandomInteger.prototype = {
- /**
- * Generates a secure random big integer (Forge).
- *
- * @function
- * @params {number} length the bit length of the random integer.
- * @returns {object} secure random big integer.
- */
- nextRandom: function(length) {
- validate(length);
- var n = ((new box.forge.jsbn.BigInteger('10')).pow(length))
- .subtract(box.forge.jsbn.BigInteger.ONE);
- var bitLength = n.bitLength();
- var numberOfBytes = bitLength / box.NUMBER_OF_BITS_PER_BYTE;
- numberOfBytes = Math.floor(numberOfBytes);
- var modBytes = bitLength % box.NUMBER_OF_BITS_PER_BYTE;
- if (modBytes !== 0) {
- numberOfBytes++;
- }
- var generatedInteger;
- do {
- var randomBytes = box.prng.generate(numberOfBytes);
- randomBytes = '\x00' + randomBytes;
- randomBytes = converters.bytesFromString(randomBytes);
- generatedInteger = new box.forge.jsbn.BigInteger(randomBytes);
- } while ((generatedInteger.compareTo(forge.jsbn.BigInteger.ZERO) <= 0) ||
- (generatedInteger.compareTo(n) > 0));
- return generatedInteger;
- },
- /**
- * Generates a secure random big integer according to the specified bit
- * length.
- *
- * @function
- * @params {number} bitsLength the bit length of the random integer.
- * @returns {object} Secure random big integer.
- */
- nextRandomByBits: function(bitsLength) {
- var byteLength = Math.ceil(bitsLength / box.NUMBER_OF_BITS_PER_BYTE);
- var modBytes = box.NUMBER_OF_BITS_PER_BYTE -
- (bitsLength % box.NUMBER_OF_BITS_PER_BYTE);
- var randomBytes = box.prng.generate(byteLength);
- randomBytes = '\x00' + randomBytes;
- randomBytes = converters.bytesFromString(randomBytes);
- var generatedInteger = new box.forge.jsbn.BigInteger(randomBytes);
- generatedInteger = generatedInteger.shiftRight(modBytes);
- return generatedInteger;
- }
- };
- };
|