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