vendredi 2 mars 2018

Node secure randomness implementations

I'm trying to generate secure randomness in Node as a personal challenge. I was wondering if the following implementations are correctly random or they have some flaws.

const crypto = require('crypto');

const secureRandomFloat = (bytes = 6) => {
  const size = Math.pow(2, bytes * 8);
  const hexString = crypto.randomBytes(bytes).toString('hex');
  const randInt = parseInt(hexString, 16);
  return randInt / size;
}

export const secureRandomIntRange = (min, max) => {
  const range = max - min + 1;
  // use an amount of bytes that will cover the range we need
  const bytes = Math.ceil(Math.log(range) / Math.log(256));
  const size = Math.pow(2, bytes * 8);
  // this is the "tail" of possible numbers. Using them that would
  // give us more chances to get lower values when using modulo
  const excess = size % range;

  let validRand = false;
  let hexString;
  let randInt;
  while (!validRand) {
    hexString = crypto.randomBytes(bytes).toString('hex');
    randInt = parseInt(hexString, 16);
    validRand = randInt + excess < size;
  }

  return min + randInt % range;
}

const secureRandomChoice = arr => {
  // This is to check that the "arr" is iterable, like an array
  // or a string, etc.
  if (arr == null) return null;
  if (typeof arr[Symbol.iterator] !== 'function') return null;
  if (!arr.hasOwnProperty('length')) return null;

  // use an amount of bytes that will cover the range we need
  const bytes = Math.ceil(Math.log(arr.length) / Math.log(256));

  const randIdx = secureRandomIntRange(0, arr.length - 1, bytes);
  return arr[randIdx];
}

I've done some testing with a million iterations and results seem to be random, but I don't know if I'm missing something.

Are these implementations going to give me pseudo-randomness?




Aucun commentaire:

Enregistrer un commentaire