1 /*
2 * Copyright (c) 2001, 2002 X-Way Rights BV
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 */
19
20 /*!\file dsa.c
21 * \brief Digital Signature Algorithm.
22 * \ingroup DL_m DL_dsa_m
23 */
24
25 #define BEECRYPT_DLL_EXPORT
26
27 #if HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include "beecrypt/dsa.h"
32 #include "beecrypt/dldp.h"
33
dsasign(const mpbarrett * p,const mpbarrett * q,const mpnumber * g,randomGeneratorContext * rgc,const mpnumber * hm,const mpnumber * x,mpnumber * r,mpnumber * s)34 int dsasign(const mpbarrett* p, const mpbarrett* q, const mpnumber* g, randomGeneratorContext* rgc, const mpnumber* hm, const mpnumber* x, mpnumber* r, mpnumber* s)
35 {
36 register size_t psize = p->size;
37 register size_t qsize = q->size;
38
39 register mpw* ptemp;
40 register mpw* qtemp;
41
42 register mpw* pwksp;
43 register mpw* qwksp;
44
45 register int rc = -1;
46
47 ptemp = (mpw*) malloc((5*psize+2)*sizeof(mpw));
48 if (ptemp == (mpw*) 0)
49 return rc;
50
51 qtemp = (mpw*) malloc((9*qsize+6)*sizeof(mpw));
52 if (qtemp == (mpw*) 0)
53 {
54 free(ptemp);
55 return rc;
56 }
57
58 pwksp = ptemp+psize;
59 qwksp = qtemp+3*qsize;
60
61 /* allocate r */
62 mpnfree(r);
63 mpnsize(r, qsize);
64
65 /* get a random k, invertible modulo q; store k @ qtemp, inv(k) @ qtemp+qsize */
66 mpbrndinv_w(q, rgc, qtemp, qtemp+qsize, qwksp);
67
68 /* g^k mod p */
69 mpbpowmod_w(p, g->size, g->data, qsize, qtemp, ptemp, pwksp);
70
71 /* (g^k mod p) mod q - simple modulo */
72 mpmod(qtemp+2*qsize, psize, ptemp, qsize, q->modl, pwksp);
73 mpcopy(qsize, r->data, qtemp+psize+qsize);
74
75 /* allocate s */
76 mpnfree(s);
77 mpnsize(s, qsize);
78
79 /* x*r mod q */
80 mpbmulmod_w(q, x->size, x->data, r->size, r->data, qtemp, qwksp);
81
82 /* add h(m) mod q */
83 mpbaddmod_w(q, qsize, qtemp, hm->size, hm->data, qtemp+2*qsize, qwksp);
84
85 /* multiply inv(k) mod q */
86 mpbmulmod_w(q, qsize, qtemp+qsize, qsize, qtemp+2*qsize, s->data, qwksp);
87
88 rc = 0;
89
90 free(qtemp);
91 free(ptemp);
92
93 return rc;
94 }
95
dsavrfy(const mpbarrett * p,const mpbarrett * q,const mpnumber * g,const mpnumber * hm,const mpnumber * y,const mpnumber * r,const mpnumber * s)96 int dsavrfy(const mpbarrett* p, const mpbarrett* q, const mpnumber* g, const mpnumber* hm, const mpnumber* y, const mpnumber* r, const mpnumber* s)
97 {
98 register size_t psize = p->size;
99 register size_t qsize = q->size;
100
101 register mpw* ptemp;
102 register mpw* qtemp;
103
104 register mpw* pwksp;
105 register mpw* qwksp;
106
107 register int rc = 0;
108
109 /* h(m) shouldn't contain more bits than q */
110 if (mpbits(hm->size, hm->data) > mpbits(q->size, q->modl))
111 return rc;
112
113 /* check 0 < r < q */
114 if (mpz(r->size, r->data))
115 return rc;
116
117 if (mpgex(r->size, r->data, qsize, q->modl))
118 return rc;
119
120 /* check 0 < s < q */
121 if (mpz(s->size, s->data))
122 return rc;
123
124 if (mpgex(s->size, s->data, qsize, q->modl))
125 return rc;
126
127 ptemp = (mpw*) malloc((6*psize+2)*sizeof(mpw));
128 if (ptemp == (mpw*) 0)
129 return rc;
130
131 qtemp = (mpw*) malloc((8*qsize+6)*sizeof(mpw));
132 if (qtemp == (mpw*) 0)
133 {
134 free(ptemp);
135 return rc;
136 }
137
138 pwksp = ptemp+2*psize;
139 qwksp = qtemp+2*qsize;
140
141 mpsetx(qsize, qtemp+qsize, s->size, s->data);
142
143 /* compute w = inv(s) mod q */
144 if (mpextgcd_w(qsize, q->modl, qtemp+qsize, qtemp, qwksp))
145 {
146 /* compute u1 = h(m)*w mod q */
147 mpbmulmod_w(q, hm->size, hm->data, qsize, qtemp, qtemp+qsize, qwksp);
148
149 /* compute u2 = r*w mod q */
150 mpbmulmod_w(q, r->size, r->data, qsize, qtemp, qtemp, qwksp);
151
152 /* compute g^u1 mod p */
153 mpbpowmod_w(p, g->size, g->data, qsize, qtemp+qsize, ptemp, pwksp);
154
155 /* compute y^u2 mod p */
156 mpbpowmod_w(p, y->size, y->data, qsize, qtemp, ptemp+psize, pwksp);
157
158 /* multiply mod p */
159 mpbmulmod_w(p, psize, ptemp, psize, ptemp+psize, ptemp, pwksp);
160
161 /* modulo q */
162 mpmod(ptemp+psize, psize, ptemp, qsize, q->modl, pwksp);
163
164 rc = mpeqx(r->size, r->data, psize, ptemp+psize);
165 }
166
167 free(qtemp);
168 free(ptemp);
169
170 return rc;
171 }
172
dsaparamMake(dsaparam * dp,randomGeneratorContext * rgc,size_t psize)173 int dsaparamMake(dsaparam* dp, randomGeneratorContext* rgc, size_t psize)
174 {
175 /* psize must be >= 512 and <= 1024 */
176 if ((psize < 512) || (psize > 1024))
177 return -1;
178
179 /* psize must be a multiple of 64 */
180 if ((psize & 0x3f) != 0)
181 return -1;
182
183 return dldp_pgoqMake(dp, rgc, psize, 160, 1);
184 }
185