When you have {n,e,d}, you should call Initialize(). Both RSA::PublicKey and RSA::PrivateKey provide the function overloads.
After loading the key, be sure to call Validate(3) to validate them. GPG keys might give you trouble because GPG uses Lim-Lee primes, and not safe primes.
*****
Initialize() will solve for p, q, d mod p-1, d mod q-1, etc for a private key. From rsa.cpp:
void InvertibleRSAFunction::Initialize(const Integer &n, const Integer &e, const Integer &d)
{
if (n.IsEven() || e.IsEven() | d.IsEven())
throw InvalidArgument("InvertibleRSAFunction: input is not a valid RSA private key");
m_n = n;
m_e = e;
m_d = d;
Integer r = --(d*e);
unsigned int s = 0;
while (r.IsEven())
{
r >>= 1;
s++;
}
ModularArithmetic modn(n);
for (Integer i = 2; ; ++i)
{
Integer a = modn.Exponentiate(i, r);
if (a == 1)
continue;
Integer b;
unsigned int j = 0;
while (a != n-1)
{
b = modn.Square(a);
if (b == 1)
{
m_p = GCD(a-1, n);
m_q = n/m_p;
m_dp = m_d % (m_p-1);
m_dq = m_d % (m_q-1);
m_u = m_q.InverseMod(m_p);
return;
}
if (++j == s)
throw InvalidArgument("InvertibleRSAFunction: input is not a valid RSA private key");
a = b;
}
}
}
*****
There's also an Initialize() that takes all the parameters. Given {n,e,d,p,q}, you can solve for the missing parameters and use it instead if you like.
void Initialize(const Integer &n, const Integer &e, const Integer &d,
const Integer &p, const Integer &q,
const Integer &dp, const Integer &dq, const Integer &u)
{m_n = n; m_e = e; m_d = d; m_p = p; m_q = q; m_dp = dp; m_dq = dq; m_u = u;}
Jeff