1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- /*
- * 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
- */
- /* jshint node:true */
- 'use strict';
- var Tools = require('./tools');
- var validator = require('./input-validator');
- var codec = require('scytl-codec');
- var forge = require('node-forge');
- module.exports = Prng;
- /**
- * @class Prng
- * @classdesc A pseudo-random number generator that generates data, based on a
- * hash of the entropy that has been collected by various available
- * sources. This object is created and managed internally by the
- * secure random service.
- * @private
- * @param entropyHash
- * {Uint8Array} The hash of the collected entropy.
- */
- function Prng(entropyHash) {
- var tools_ = new Tools();
- var key_ = '';
- var counter_ = 0;
- /**
- * Generates some random bytes, using the gathered entropy data.
- *
- * @function nextBytes
- * @private
- * @param {number}
- * numBytes The number of bytes to generate.
- * @return {Uint8Array} The random bytes.
- */
- this.nextBytes = function(numBytes) {
- validator.checkIsPositiveNumber(
- numBytes, 'Number of random bytes to generate');
- var keyAux;
- if (key_ === null || key_ === '') {
- reseed();
- }
- // Buffer in which to store the random bytes.
- var b = forge.util.createBuffer();
- var limitReach = 1;
- while (b.length() < numBytes) {
- b.putBytes(tools_.cipher(key_, counter_));
- counter_++;
- if (b.length >= (limitReach * Math.pow(2, 20))) {
- keyAux = key_;
- key_ = '';
- for (var i = 0; i < 2; i++) {
- key_ += tools_.cipher(keyAux, counter_);
- counter_++;
- }
- limitReach++;
- }
- }
- // Do it twice to ensure a key with 256 bits.
- keyAux = key_;
- key_ = '';
- for (var j = 0; j < 2; j++) {
- key_ += tools_.cipher(keyAux, counter_);
- counter_++;
- }
- return codec.binaryDecode(b.getBytes(numBytes));
- };
- function reseed() {
- var digester = tools_.getReseedDigester();
- digester.start();
- digester.update(codec.hexEncode(entropyHash));
- digester.update(key_);
- key_ = codec.hexEncode(codec.binaryDecode(digester.digest().getBytes()));
- counter_++;
- }
- }
|