Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

#include "os.h"
#include <mp.h>
#include <libsec.h>

RSApriv*
rsafill(mpint *n, mpint *e, mpint *d, mpint *p, mpint *q)
{
        mpint *c2, *kq, *kp, *x;
        RSApriv *rsa;

        // make sure we're not being hoodwinked
        if(!probably_prime(p, 10) || !probably_prime(q, 10)){
                werrstr("rsafill: p or q not prime");
                return nil;
        }
        x = mpnew(0);
        mpmul(p, q, x);
        if(mpcmp(n, x) != 0){
                werrstr("rsafill: n != p*q");
                mpfree(x);
                return nil;
        }
        c2 = mpnew(0);
        mpsub(p, mpone, c2);
        mpsub(q, mpone, x);
        mpmul(c2, x, x);
        mpmul(e, d, c2);
        mpmod(c2, x, x);
        if(mpcmp(x, mpone) != 0){
                werrstr("rsafill: e*d != 1 mod (p-1)*(q-1)");
                mpfree(x);
                mpfree(c2);
                return nil;
        }

        // compute chinese remainder coefficient
        mpinvert(p, q, c2);

        // for crt a**k mod p == (a**(k mod p-1)) mod p
        kq = mpnew(0);
        kp = mpnew(0);
        mpsub(p, mpone, x);
        mpmod(d, x, kp);
        mpsub(q, mpone, x);
        mpmod(d, x, kq);

        rsa = rsaprivalloc();
        rsa->pub.ek = mpcopy(e);
        rsa->pub.n = mpcopy(n);
        rsa->dk = mpcopy(d);
        rsa->kp = kp;
        rsa->kq = kq;
        rsa->p = mpcopy(p);
        rsa->q = mpcopy(q);
        rsa->c2 = c2;

        mpfree(x);

        return rsa;
}