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