generateKeyPair method
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));
}