Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

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

DSApriv*
dsagen(DSApub *opub)
{
        DSApub *pub;
        DSApriv *priv;
        mpint *exp;
        mpint *g;
        mpint *r;
        int bits;

        priv = dsaprivalloc();
        pub = &priv->pub;

        if(opub != nil){
                pub->p = mpcopy(opub->p);
                pub->q = mpcopy(opub->q);
        } else {
                pub->p = mpnew(0);
                pub->q = mpnew(0);
                DSAprimes(pub->q, pub->p, nil);
        }
        bits = Dbits*pub->p->top;

        pub->alpha = mpnew(0);
        pub->key = mpnew(0);
        priv->secret = mpnew(0);

        // find a generator alpha of the multiplicative
        // group Z*p, i.e., of order n = p-1.  We use the
        // fact that q divides p-1 to reduce the exponent.
        exp = mpnew(0);
        g = mpnew(0);
        r = mpnew(0);
        mpsub(pub->p, mpone, exp);
        mpdiv(exp, pub->q, exp, r);
        if(mpcmp(r, mpzero) != 0)
                sysfatal("dsagen foul up");
        while(1){
                mprand(bits, genrandom, g);
                mpmod(g, pub->p, g);
                mpexp(g, exp, pub->p, pub->alpha);
                if(mpcmp(pub->alpha, mpone) != 0)
                        break;
        }
        mpfree(g);
        mpfree(exp);

        // create the secret key
        mprand(bits, genrandom, priv->secret);
        mpmod(priv->secret, pub->p, priv->secret);
        mpexp(pub->alpha, priv->secret, pub->p, pub->key);

        return priv;
}