1 /*
2  * Copyright (c) 2000, 2001, 2002 X-Way Rights BV
3  * Copyright (c) 2009 Bob Deblier
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  */
20 
21 /*!\file rsa.c
22  * \brief RSA algorithm.
23  * \author Bob Deblier <bob.deblier@telenet.be>
24  * \ingroup IF_m IF_rsa_m
25  */
26 
27 #define BEECRYPT_DLL_EXPORT
28 
29 #if HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32 
33 #include "beecrypt/rsa.h"
34 
rsapub(const mpbarrett * n,const mpnumber * e,const mpnumber * m,mpnumber * c)35 int rsapub(const mpbarrett* n, const mpnumber* e,
36            const mpnumber* m, mpnumber* c)
37 {
38 	register size_t size = n->size;
39 	register mpw* temp;
40 
41 	if (mpgex(m->size, m->data, n->size, n->modl))
42 		return -1;
43 
44 	temp = (mpw*) malloc((4*size+2)*sizeof(mpw));
45 
46 	if (temp)
47 	{
48 		mpnsize(c, size);
49 		mpbpowmod_w(n, m->size, m->data, e->size, e->data, c->data, temp);
50 
51 		free(temp);
52 
53 		return 0;
54 	}
55 	return -1;
56 }
57 
rsapri(const mpbarrett * n,const mpnumber * d,const mpnumber * c,mpnumber * m)58 int rsapri(const mpbarrett* n, const mpnumber* d,
59            const mpnumber* c, mpnumber* m)
60 {
61 	register size_t size = n->size;
62 	register mpw* temp;
63 
64 	if (mpgex(c->size, c->data, n->size, n->modl))
65 		return -1;
66 
67 	temp = (mpw*) malloc((4*size+2)*sizeof(mpw));
68 
69 	if (temp)
70 	{
71 		mpnsize(m, size);
72 		mpbpowmod_w(n, c->size, c->data, d->size, d->data, m->data, temp);
73 
74 		free(temp);
75 
76 		return 0;
77 	}
78 	return -1;
79 }
80 
rsapricrt(const mpbarrett * n,const mpbarrett * p,const mpbarrett * q,const mpnumber * dp,const mpnumber * dq,const mpnumber * qi,const mpnumber * c,mpnumber * m)81 int rsapricrt(const mpbarrett* n, const mpbarrett* p, const mpbarrett* q,
82               const mpnumber* dp, const mpnumber* dq, const mpnumber* qi,
83               const mpnumber* c, mpnumber* m)
84 {
85 	register size_t nsize = n->size;
86 	register size_t psize = p->size;
87 	register size_t qsize = q->size;
88 
89 	register mpw* ptemp;
90 	register mpw* qtemp;
91 
92 	if (mpgex(c->size, c->data, n->size, n->modl))
93 		return -1;
94 
95 	ptemp = (mpw*) malloc((6*psize+2)*sizeof(mpw));
96 	if (ptemp == (mpw*) 0)
97 		return -1;
98 
99 	qtemp = (mpw*) malloc((6*qsize+2)*sizeof(mpw));
100 	if (qtemp == (mpw*) 0)
101 	{
102 		free(ptemp);
103 		return -1;
104 	}
105 
106 	#pragma omp parallel sections
107 	{
108 		#pragma omp section
109 		{
110 		/* resize c for powmod p */
111 		mpsetx(psize*2, ptemp, c->size, c->data);
112 
113 		/* reduce modulo p before we powmod */
114 		mpbmod_w(p, ptemp, ptemp+psize, ptemp+2*psize);
115 
116 		/* compute j1 = c^dp mod p, store @ ptemp */
117 		mpbpowmod_w(p, psize, ptemp+psize, dp->size, dp->data, ptemp, ptemp+2*psize);
118 		}
119 
120 		#pragma omp section
121 		{
122 		/* resize c for powmod q */
123 		mpsetx(qsize*2, qtemp, c->size, c->data);
124 
125 		/* reduce modulo q before we powmod */
126 		mpbmod_w(q, qtemp, qtemp+qsize, qtemp+2*qsize);
127 
128 		/* compute j2 = c^dq mod q, store @ qtemp */
129 		mpbpowmod_w(q, qsize, qtemp+qsize, dq->size, dq->data, qtemp, qtemp+2*qsize);
130 		}
131 	}
132 
133 	/* compute j1-j2 mod p, store @ ptemp */
134 	mpbsubmod_w(p, psize, ptemp, qsize, qtemp, ptemp, ptemp+2*psize);
135 
136 	/* compute h = c*(j1-j2) mod p, store @ ptemp */
137 	mpbmulmod_w(p, psize, ptemp, psize, qi->data, ptemp, ptemp+2*psize);
138 
139 	/* make sure the message gets the proper size */
140 	mpnsize(m, nsize);
141 
142 	/* compute m = h*q + j2 */
143 	mpmul(m->data, psize, ptemp, qsize, q->modl);
144 	mpaddx(nsize, m->data, qsize, qtemp);
145 
146 	free(ptemp);
147 	free(qtemp);
148 
149 	return 0;
150 }
151 
rsavrfy(const mpbarrett * n,const mpnumber * e,const mpnumber * m,const mpnumber * c)152 int rsavrfy(const mpbarrett* n, const mpnumber* e,
153             const mpnumber* m, const mpnumber* c)
154 {
155 	int rc = 0;
156 	register size_t size = n->size;
157 
158 	register mpw* temp;
159 
160 	if (mpgex(m->size, m->data, n->size, n->modl))
161 		return rc;
162 
163 	if (mpgex(c->size, c->data, n->size, n->modl))
164 		return rc;
165 
166 	temp = (mpw*) malloc((5*size+2)*sizeof(mpw));
167 	if (temp)
168 	{
169 		mpbpowmod_w(n, m->size, m->data, e->size, e->data, temp, temp+size);
170 
171 		rc = mpeqx(size, temp, c->size, c->data);
172 
173 		free(temp);
174 	}
175 
176 	return rc;
177 }
178