xref: /plan9/sys/src/libsec/port/egsign.c (revision 3ff48bf5ed603850fcd251ddf13025d23d693782)
180ee5cbfSDavid du Colombier #include "os.h"
280ee5cbfSDavid du Colombier #include <mp.h>
380ee5cbfSDavid du Colombier #include <libsec.h>
480ee5cbfSDavid du Colombier 
580ee5cbfSDavid du Colombier EGsig*
egsign(EGpriv * priv,mpint * m)680ee5cbfSDavid du Colombier egsign(EGpriv *priv, mpint *m)
780ee5cbfSDavid du Colombier {
880ee5cbfSDavid du Colombier 	EGpub *pub = &priv->pub;
980ee5cbfSDavid du Colombier 	EGsig *sig;
1080ee5cbfSDavid du Colombier 	mpint *pm1, *k, *kinv, *r, *s;
1180ee5cbfSDavid du Colombier 	mpint *p = pub->p, *alpha = pub->alpha;
129a747e4fSDavid du Colombier 	int plen = mpsignif(p);
1380ee5cbfSDavid du Colombier 
1480ee5cbfSDavid du Colombier 	pm1 = mpnew(0);
1580ee5cbfSDavid du Colombier 	kinv = mpnew(0);
1680ee5cbfSDavid du Colombier 	r = mpnew(0);
1780ee5cbfSDavid du Colombier 	s = mpnew(0);
18*3ff48bf5SDavid du Colombier 	k = mpnew(0);
1980ee5cbfSDavid du Colombier 	mpsub(p, mpone, pm1);
209a747e4fSDavid du Colombier 	while(1){
21*3ff48bf5SDavid du Colombier 		mprand(plen, genrandom, k);
229a747e4fSDavid du Colombier 		if((mpcmp(mpone, k) > 0) || (mpcmp(k, pm1) >= 0))
239a747e4fSDavid du Colombier 			continue;
2480ee5cbfSDavid du Colombier 		mpextendedgcd(k, pm1, r, kinv, s);
259a747e4fSDavid du Colombier 		if(mpcmp(r, mpone) != 0)
269a747e4fSDavid du Colombier 			continue;
279a747e4fSDavid du Colombier 		break;
2880ee5cbfSDavid du Colombier 	}
2980ee5cbfSDavid du Colombier 	mpmod(kinv, pm1, kinv);  // make kinv positive
3080ee5cbfSDavid du Colombier 	mpexp(alpha, k, p, r);
3180ee5cbfSDavid du Colombier 	mpmul(priv->secret, r, s);
3280ee5cbfSDavid du Colombier 	mpmod(s, pm1, s);
3380ee5cbfSDavid du Colombier 	mpsub(m, s, s);
3480ee5cbfSDavid du Colombier 	mpmul(kinv, s, s);
3580ee5cbfSDavid du Colombier 	mpmod(s, pm1, s);
3680ee5cbfSDavid du Colombier 	sig = egsigalloc();
3780ee5cbfSDavid du Colombier 	sig->r = r;
3880ee5cbfSDavid du Colombier 	sig->s = s;
3980ee5cbfSDavid du Colombier 	mpfree(pm1);
4080ee5cbfSDavid du Colombier 	mpfree(k);
4180ee5cbfSDavid du Colombier 	mpfree(kinv);
4280ee5cbfSDavid du Colombier 	return sig;
4380ee5cbfSDavid du Colombier }
44