generateKeyPair method

  1. @override
AsymmetricKeyPair<PublicKey, PrivateKey> generateKeyPair()
override

Generate a key pair.

Implementation

@override
AsymmetricKeyPair generateKeyPair() {
  BigInt p, q, n, e;

  // p and q values should have a length of half the strength in bits
  var strength = _params.bitStrength;
  var pbitlength = (strength + 1) ~/ 2;
  var qbitlength = strength - pbitlength;
  var mindiffbits = strength ~/ 3;

  e = _params.publicExponent;

  // TODO Consider generating safe primes for p, q (see DHParametersHelper.generateSafePrimes)
  // (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm")

  // generate p, prime and (p-1) relatively prime to e
  while (true) {
    p = generateProbablePrime(pbitlength, 1, _random);

    if (p % e == BigInt.one) {
      continue;
    }

    if (!_isProbablePrime(p, _params.certainty)) {
      continue;
    }

    if (e.gcd(p - BigInt.one) == BigInt.one) {
      break;
    }
  }

  // generate a modulus of the required length
  while (true) {
    // generate q, prime and (q-1) relatively prime to e, and not equal to p
    while (true) {
      q = generateProbablePrime(qbitlength, 1, _random);

      if ((q - p).abs().bitLength < mindiffbits) {
        continue;
      }

      if (q % e == BigInt.one) {
        continue;
      }

      if (!_isProbablePrime(q, _params.certainty)) {
        continue;
      }

      if (e.gcd(q - BigInt.one) == BigInt.one) {
        break;
      }
    }

    // calculate the modulus
    n = p * q;

    if (n.bitLength == _params.bitStrength) {
      break;
    }

    // if we get here our primes aren't big enough, make the largest of the two p and try again
    p = (p.compareTo(q) > 0) ? p : q;
  }

  // Swap p and q if necessary
  if (p < q) {
    var swap = p;
    p = q;
    q = swap;
  }

  // calculate the private exponent
  var pSub1 = p - BigInt.one;
  var qSub1 = q - BigInt.one;
  var phi = pSub1 * qSub1;
  var d = e.modInverse(phi);

  // ignore: deprecated_member_use_from_same_package
  return AsymmetricKeyPair(RSAPublicKey(n, e), RSAPrivateKey(n, d, p, q, e));
}