Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

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

DSAsig*
dsasign(DSApriv *priv, mpint *m)
{
        DSApub *pub = &priv->pub;
        DSAsig *sig;
        mpint *qm1, *k, *kinv, *r, *s;
        mpint *q = pub->q, *p = pub->p, *alpha = pub->alpha;
        int qlen = mpsignif(q);

        qm1 = mpnew(0);
        kinv = mpnew(0);
        r = mpnew(0);
        s = mpnew(0);
        k = mpnew(0);
        mpsub(pub->q, mpone, qm1);

        // find a k that has an inverse mod q
        while(1){
                mprand(qlen, genrandom, k);
                if((mpcmp(mpone, k) > 0) || (mpcmp(k, pub->q) >= 0))
                        continue;
                mpextendedgcd(k, q, r, kinv, s);
                if(mpcmp(r, mpone) != 0)
                        sysfatal("dsasign: pub->q not prime");
                break;
        }

        // make kinv positive
        mpmod(kinv, pub->q, kinv);

        // r = ((alpha**k) mod p) mod q
        mpexp(alpha, k, p, r);
        mpmod(r, q, r);

        // s = (kinv*(m + ar)) mod q
        mpmul(r, priv->secret, s);
        mpadd(s, m, s);
        mpmul(s, kinv, s);
        mpmod(s, q, s);

        sig = dsasigalloc();
        sig->r = r;
        sig->s = s;
        mpfree(qm1);
        mpfree(k);
        mpfree(kinv);
        return sig;
}