Why does this throw “CryptoMaterial: this object contains invalid values” in C++, but works fine in python

145 views
Skip to first unread message

jacob...@outlook.com

unread,
May 26, 2014, 10:56:05 PM5/26/14
to cryptop...@googlegroups.com
Perhaps some of you could help with this question on stackoverflow? I am a bit new to using cryptographic algorithms in Crypto++, it seems to work in python fine.

https://stackoverflow.com/questions/23878893/why-does-this-throw-cryptomaterial-this-object-contains-invalid-values-in-c

--JH

Jeffrey Walton

unread,
Jun 18, 2014, 1:42:31 AM6/18/14
to cryptop...@googlegroups.com


On Monday, May 26, 2014 10:56:05 PM UTC-4, jacob...@outlook.com wrote:
Perhaps some of you could help with this question on stackoverflow? I am a bit new to using cryptographic algorithms in Crypto++, it seems to work in python fine.

https://stackoverflow.com/questions/23878893/why-does-this-throw-cryptomaterial-this-object-contains-invalid-values-in-c
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
Reply all
Reply to author
Forward
0 new messages