]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libsec/port/dh.c
libsec: generalize pbkdf2_hmac_sha1() to pbkdf2_x() passing the hmac as an argument
[plan9front.git] / sys / src / libsec / port / dh.c
1 #include "os.h"
2 #include <mp.h>
3 #include <libsec.h>
4
5 mpint*
6 dh_new(DHstate *dh, mpint *p, mpint *q, mpint *g)
7 {
8         mpint *pm1;
9         int n;
10
11         memset(dh, 0, sizeof(*dh));
12         if(mpcmp(g, mpone) <= 0)
13                 return nil;
14
15         n = mpsignif(p);
16         pm1 = mpnew(n);
17         mpsub(p, mpone, pm1);
18         dh->p = mpcopy(p);
19         dh->g = mpcopy(g);
20         dh->q = mpcopy(q != nil ? q : pm1);
21         dh->x = mpnew(mpsignif(dh->q));
22         dh->y = mpnew(n);
23         for(;;){
24                 mpnrand(dh->q, genrandom, dh->x);
25                 mpexp(dh->g, dh->x, dh->p, dh->y);
26                 if(mpcmp(dh->y, mpone) > 0 && mpcmp(dh->y, pm1) < 0)
27                         break;
28         }
29         mpfree(pm1);
30
31         return dh->y;
32 }
33
34 mpint*
35 dh_finish(DHstate *dh, mpint *y)
36 {
37         mpint *k = nil;
38
39         if(y == nil || dh->x == nil || dh->p == nil || dh->q == nil)
40                 goto Out;
41
42         /* y > 1 */
43         if(mpcmp(y, mpone) <= 0)
44                 goto Out;
45
46         k = mpnew(mpsignif(dh->p));
47
48         /* y < p-1 */
49         mpsub(dh->p, mpone, k);
50         if(mpcmp(y, k) >= 0){
51 Bad:
52                 mpfree(k);
53                 k = nil;
54                 goto Out;
55         }
56
57         /* y**q % p == 1 if q < p-1 */
58         if(mpcmp(dh->q, k) < 0){
59                 mpexp(y, dh->q, dh->p, k);
60                 if(mpcmp(k, mpone) != 0)
61                         goto Bad;
62         }
63
64         mpexp(y, dh->x, dh->p, k);
65
66 Out:
67         mpfree(dh->p);
68         mpfree(dh->q);
69         mpfree(dh->g);
70         mpfree(dh->x);
71         mpfree(dh->y);
72         memset(dh, 0, sizeof(*dh));
73         return k;
74 }