lundi 25 octobre 2021

Create a random BigInt for Miller-Rabin test

I'm implementing a Miller Rabin primality test using JavaScript BigInts.

The basic algorithm is no problem - I have that done, but it requires a random number in the range 0 to (number being tested-3). I can't use Math.random() and scale since I'm using BigInt.

This doesn't need to be cryptographically secure, just random enough, so I've opted for generating a string of randomly selected hex digits and converting that to a BigInt.

Here's the code:

function getRandomBigint(lower, upper) {

    // Convert to hex strings so that we know how many digits to generate
    let hexDigits = new Array(upper.toString(16).length).fill('');
    let rand;
    let newDigits;
    do {
        // Fill the array with random hex digits and convert to a BigInt
        newDigits = hexDigits.map(()=>Math.floor(Math.random()*16).toString(16));
        rand = BigInt('0x'+newDigits.join(''));
    } while (rand < lower || rand > upper);
    return rand;
}

The problem here is that the generated number could be out of range. This function handles that (badly) by iterating until it gets a number in range. Obviously, that could potentially take a very long time. In practice it has never iterated more than a couple of dozen times before delivering a number, but the nature of randomness means that the problem is 'out there' waiting to bite me!

I could scale or truncate the result to get it in range, rather than iterating, but I am concerned that this would affect the randomness. I already have some evidence that this is not as random as it might be, but that might not matter in this application.

So, two questions:

  • is this random enough for Miller Rabin?
  • how to deal with results out of range?

This is a JavaScript-only project - no libraries, please.




Aucun commentaire:

Enregistrer un commentaire