Backward-only RNG

Asymmetric CSPRNG where the public key only works backward

by skibulk

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/big-integer/1.6.43/BigInteger.min.js"></script>

JavaScript

// https://crypto.stackexchange.com/questions/70998/asymmetric-csprng-where-the-public-key-only-works-backward

// SETUP -------------------------------------

// https://en.wikipedia.org/wiki/RSA_(cryptosystem)
// requires BigInteger.min.js: https://github.com/peterolson/BigInteger.js/
function generateRSAKeys(keysize) {
  function randomPrime(bits) {
    const min = bigInt(6074001000).shiftLeft(bits - 33);
    const max = bigInt.one.shiftLeft(bits).minus(1);
    for (;;) {
      const p = bigInt.randBetween(min, max);
      if (p.isProbablePrime(256)) {
        return p;
      }
    }
  }

  const e = bigInt(65537);
  let p;
  let q;
  let lambda;

  do {
    p = randomPrime(keysize / 2);
    q = randomPrime(keysize / 2);
    lambda = bigInt.lcm(p.minus(1), q.minus(1));
  } while (bigInt.gcd(e, lambda).notEquals(1) || p.minus(q).abs().shiftRight(
      keysize / 2 - 100).isZero());

  return {
    n: p.multiply(q), // public key (part I)
    e: e, // public key (part II)
    d: e.modInv(lambda), // private key
  };
}

// Make Math.random secure - Requires Chrome or Firefox.
// https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues
if (window.crypto.getRandomValues) {
  Math.random = function() {
    return window.crypto.getRandomValues(new Uint32Array(1))[0] / 4294967295;
  }
}

// RUN ---------------------------------------

console.clear();

// Generate Keys
/*
var keys = generateRSAKeys(2048);
console.log(keys);

var rsaPrivateKey = keys.d;
var rsaPublicKey = keys.e;
var rsaModulus = keys.n;
*/

// RSA 2048
var rsaPrivateKey =...