380
|
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis |
|
2 * |
|
3 * LibTomCrypt is a library that provides various cryptographic |
|
4 * algorithms in a highly modular and flexible manner. |
|
5 * |
|
6 * The library is free for all purposes without any express |
|
7 * guarantee it works. |
|
8 * |
|
9 * Tom St Denis, [email protected], http://libtomcrypt.com |
|
10 */ |
|
11 |
|
12 #define DESC_DEF_ONLY |
|
13 #include "tomcrypt.h" |
|
14 |
|
15 #ifdef LTM_DESC |
|
16 |
|
17 #include <tommath.h> |
|
18 |
|
19 static const struct { |
|
20 int mpi_code, ltc_code; |
|
21 } mpi_to_ltc_codes[] = { |
|
22 { MP_OKAY , CRYPT_OK}, |
|
23 { MP_MEM , CRYPT_MEM}, |
|
24 { MP_VAL , CRYPT_INVALID_ARG}, |
|
25 }; |
|
26 |
|
27 /** |
|
28 Convert a MPI error to a LTC error (Possibly the most powerful function ever! Oh wait... no) |
|
29 @param err The error to convert |
|
30 @return The equivalent LTC error code or CRYPT_ERROR if none found |
|
31 */ |
|
32 static int mpi_to_ltc_error(int err) |
|
33 { |
|
34 int x; |
|
35 |
|
36 for (x = 0; x < (int)(sizeof(mpi_to_ltc_codes)/sizeof(mpi_to_ltc_codes[0])); x++) { |
|
37 if (err == mpi_to_ltc_codes[x].mpi_code) { |
|
38 return mpi_to_ltc_codes[x].ltc_code; |
|
39 } |
|
40 } |
|
41 return CRYPT_ERROR; |
|
42 } |
|
43 |
|
44 static int init(void **a) |
|
45 { |
|
46 int err; |
|
47 |
|
48 LTC_ARGCHK(a != NULL); |
|
49 |
|
50 *a = XCALLOC(1, sizeof(mp_int)); |
|
51 if (*a == NULL) { |
|
52 return CRYPT_MEM; |
|
53 } |
|
54 |
|
55 if ((err = mpi_to_ltc_error(mp_init(*a))) != CRYPT_OK) { |
|
56 XFREE(*a); |
|
57 } |
|
58 return err; |
|
59 } |
|
60 |
|
61 static void deinit(void *a) |
|
62 { |
|
63 LTC_ARGCHKVD(a != NULL); |
|
64 mp_clear(a); |
|
65 XFREE(a); |
|
66 } |
|
67 |
|
68 static int neg(void *a, void *b) |
|
69 { |
|
70 LTC_ARGCHK(a != NULL); |
|
71 LTC_ARGCHK(b != NULL); |
|
72 return mpi_to_ltc_error(mp_neg(a, b)); |
|
73 } |
|
74 |
|
75 static int copy(void *a, void *b) |
|
76 { |
|
77 LTC_ARGCHK(a != NULL); |
|
78 LTC_ARGCHK(b != NULL); |
|
79 return mpi_to_ltc_error(mp_copy(a, b)); |
|
80 } |
|
81 |
|
82 static int init_copy(void **a, void *b) |
|
83 { |
|
84 if (init(a) != CRYPT_OK) { |
|
85 return CRYPT_MEM; |
|
86 } |
|
87 return copy(b, *a); |
|
88 } |
|
89 |
|
90 /* ---- trivial ---- */ |
|
91 static int set_int(void *a, unsigned long b) |
|
92 { |
|
93 LTC_ARGCHK(a != NULL); |
|
94 return mpi_to_ltc_error(mp_set_int(a, b)); |
|
95 } |
|
96 |
|
97 static unsigned long get_int(void *a) |
|
98 { |
|
99 LTC_ARGCHK(a != NULL); |
|
100 return mp_get_int(a); |
|
101 } |
|
102 |
|
103 static unsigned long get_digit(void *a, int n) |
|
104 { |
|
105 mp_int *A; |
|
106 LTC_ARGCHK(a != NULL); |
|
107 A = a; |
|
108 return (n >= A->used || n < 0) ? 0 : A->dp[n]; |
|
109 } |
|
110 |
|
111 static int get_digit_count(void *a) |
|
112 { |
|
113 mp_int *A; |
|
114 LTC_ARGCHK(a != NULL); |
|
115 A = a; |
|
116 return A->used; |
|
117 } |
|
118 |
|
119 static int compare(void *a, void *b) |
|
120 { |
|
121 int ret; |
|
122 LTC_ARGCHK(a != NULL); |
|
123 LTC_ARGCHK(b != NULL); |
|
124 ret = mp_cmp(a, b); |
|
125 switch (ret) { |
|
126 case MP_LT: return LTC_MP_LT; |
|
127 case MP_EQ: return LTC_MP_EQ; |
|
128 case MP_GT: return LTC_MP_GT; |
|
129 } |
|
130 return 0; |
|
131 } |
|
132 |
|
133 static int compare_d(void *a, unsigned long b) |
|
134 { |
|
135 int ret; |
|
136 LTC_ARGCHK(a != NULL); |
|
137 ret = mp_cmp_d(a, b); |
|
138 switch (ret) { |
|
139 case MP_LT: return LTC_MP_LT; |
|
140 case MP_EQ: return LTC_MP_EQ; |
|
141 case MP_GT: return LTC_MP_GT; |
|
142 } |
|
143 return 0; |
|
144 } |
|
145 |
|
146 static int count_bits(void *a) |
|
147 { |
|
148 LTC_ARGCHK(a != NULL); |
|
149 return mp_count_bits(a); |
|
150 } |
|
151 |
|
152 static int count_lsb_bits(void *a) |
|
153 { |
|
154 LTC_ARGCHK(a != NULL); |
|
155 return mp_cnt_lsb(a); |
|
156 } |
|
157 |
|
158 |
|
159 static int twoexpt(void *a, int n) |
|
160 { |
|
161 LTC_ARGCHK(a != NULL); |
|
162 return mpi_to_ltc_error(mp_2expt(a, n)); |
|
163 } |
|
164 |
|
165 /* ---- conversions ---- */ |
|
166 |
|
167 /* read ascii string */ |
|
168 static int read_radix(void *a, const char *b, int radix) |
|
169 { |
|
170 LTC_ARGCHK(a != NULL); |
|
171 LTC_ARGCHK(b != NULL); |
|
172 return mpi_to_ltc_error(mp_read_radix(a, b, radix)); |
|
173 } |
|
174 |
|
175 /* write one */ |
|
176 static int write_radix(void *a, char *b, int radix) |
|
177 { |
|
178 LTC_ARGCHK(a != NULL); |
|
179 LTC_ARGCHK(b != NULL); |
|
180 return mpi_to_ltc_error(mp_toradix(a, b, radix)); |
|
181 } |
|
182 |
|
183 /* get size as unsigned char string */ |
|
184 static unsigned long unsigned_size(void *a) |
|
185 { |
|
186 LTC_ARGCHK(a != NULL); |
|
187 return mp_unsigned_bin_size(a); |
|
188 } |
|
189 |
|
190 /* store */ |
|
191 static int unsigned_write(void *a, unsigned char *b) |
|
192 { |
|
193 LTC_ARGCHK(a != NULL); |
|
194 LTC_ARGCHK(b != NULL); |
|
195 return mpi_to_ltc_error(mp_to_unsigned_bin(a, b)); |
|
196 } |
|
197 |
|
198 /* read */ |
|
199 static int unsigned_read(void *a, unsigned char *b, unsigned long len) |
|
200 { |
|
201 LTC_ARGCHK(a != NULL); |
|
202 LTC_ARGCHK(b != NULL); |
|
203 return mpi_to_ltc_error(mp_read_unsigned_bin(a, b, len)); |
|
204 } |
|
205 |
|
206 /* add */ |
|
207 static int add(void *a, void *b, void *c) |
|
208 { |
|
209 LTC_ARGCHK(a != NULL); |
|
210 LTC_ARGCHK(b != NULL); |
|
211 LTC_ARGCHK(c != NULL); |
|
212 return mpi_to_ltc_error(mp_add(a, b, c)); |
|
213 } |
|
214 |
|
215 static int addi(void *a, unsigned long b, void *c) |
|
216 { |
|
217 LTC_ARGCHK(a != NULL); |
|
218 LTC_ARGCHK(c != NULL); |
|
219 return mpi_to_ltc_error(mp_add_d(a, b, c)); |
|
220 } |
|
221 |
|
222 /* sub */ |
|
223 static int sub(void *a, void *b, void *c) |
|
224 { |
|
225 LTC_ARGCHK(a != NULL); |
|
226 LTC_ARGCHK(b != NULL); |
|
227 LTC_ARGCHK(c != NULL); |
|
228 return mpi_to_ltc_error(mp_sub(a, b, c)); |
|
229 } |
|
230 |
|
231 static int subi(void *a, unsigned long b, void *c) |
|
232 { |
|
233 LTC_ARGCHK(a != NULL); |
|
234 LTC_ARGCHK(c != NULL); |
|
235 return mpi_to_ltc_error(mp_sub_d(a, b, c)); |
|
236 } |
|
237 |
|
238 /* mul */ |
|
239 static int mul(void *a, void *b, void *c) |
|
240 { |
|
241 LTC_ARGCHK(a != NULL); |
|
242 LTC_ARGCHK(b != NULL); |
|
243 LTC_ARGCHK(c != NULL); |
|
244 return mpi_to_ltc_error(mp_mul(a, b, c)); |
|
245 } |
|
246 |
|
247 static int muli(void *a, unsigned long b, void *c) |
|
248 { |
|
249 LTC_ARGCHK(a != NULL); |
|
250 LTC_ARGCHK(c != NULL); |
|
251 return mpi_to_ltc_error(mp_mul_d(a, b, c)); |
|
252 } |
|
253 |
|
254 /* sqr */ |
|
255 static int sqr(void *a, void *b) |
|
256 { |
|
257 LTC_ARGCHK(a != NULL); |
|
258 LTC_ARGCHK(b != NULL); |
|
259 return mpi_to_ltc_error(mp_sqr(a, b)); |
|
260 } |
|
261 |
|
262 /* div */ |
|
263 static int divide(void *a, void *b, void *c, void *d) |
|
264 { |
|
265 LTC_ARGCHK(a != NULL); |
|
266 LTC_ARGCHK(b != NULL); |
|
267 return mpi_to_ltc_error(mp_div(a, b, c, d)); |
|
268 } |
|
269 |
|
270 static int div_2(void *a, void *b) |
|
271 { |
|
272 LTC_ARGCHK(a != NULL); |
|
273 LTC_ARGCHK(b != NULL); |
|
274 return mpi_to_ltc_error(mp_div_2(a, b)); |
|
275 } |
|
276 |
|
277 /* modi */ |
|
278 static int modi(void *a, unsigned long b, unsigned long *c) |
|
279 { |
|
280 mp_digit tmp; |
|
281 int err; |
|
282 |
|
283 LTC_ARGCHK(a != NULL); |
|
284 LTC_ARGCHK(c != NULL); |
|
285 |
|
286 if ((err = mpi_to_ltc_error(mp_mod_d(a, b, &tmp))) != CRYPT_OK) { |
|
287 return err; |
|
288 } |
|
289 *c = tmp; |
|
290 return CRYPT_OK; |
|
291 } |
|
292 |
|
293 /* gcd */ |
|
294 static int gcd(void *a, void *b, void *c) |
|
295 { |
|
296 LTC_ARGCHK(a != NULL); |
|
297 LTC_ARGCHK(b != NULL); |
|
298 LTC_ARGCHK(c != NULL); |
|
299 return mpi_to_ltc_error(mp_gcd(a, b, c)); |
|
300 } |
|
301 |
|
302 /* lcm */ |
|
303 static int lcm(void *a, void *b, void *c) |
|
304 { |
|
305 LTC_ARGCHK(a != NULL); |
|
306 LTC_ARGCHK(b != NULL); |
|
307 LTC_ARGCHK(c != NULL); |
|
308 return mpi_to_ltc_error(mp_lcm(a, b, c)); |
|
309 } |
|
310 |
|
311 static int mulmod(void *a, void *b, void *c, void *d) |
|
312 { |
|
313 LTC_ARGCHK(a != NULL); |
|
314 LTC_ARGCHK(b != NULL); |
|
315 LTC_ARGCHK(c != NULL); |
|
316 LTC_ARGCHK(d != NULL); |
|
317 return mpi_to_ltc_error(mp_mulmod(a,b,c,d)); |
|
318 } |
|
319 |
|
320 static int sqrmod(void *a, void *b, void *c) |
|
321 { |
|
322 LTC_ARGCHK(a != NULL); |
|
323 LTC_ARGCHK(b != NULL); |
|
324 LTC_ARGCHK(c != NULL); |
|
325 return mpi_to_ltc_error(mp_sqrmod(a,b,c)); |
|
326 } |
|
327 |
|
328 /* invmod */ |
|
329 static int invmod(void *a, void *b, void *c) |
|
330 { |
|
331 LTC_ARGCHK(a != NULL); |
|
332 LTC_ARGCHK(b != NULL); |
|
333 LTC_ARGCHK(c != NULL); |
|
334 return mpi_to_ltc_error(mp_invmod(a, b, c)); |
|
335 } |
|
336 |
|
337 /* setup */ |
|
338 static int montgomery_setup(void *a, void **b) |
|
339 { |
|
340 int err; |
|
341 LTC_ARGCHK(a != NULL); |
|
342 LTC_ARGCHK(b != NULL); |
|
343 *b = XCALLOC(1, sizeof(mp_digit)); |
|
344 if (*b == NULL) { |
|
345 return CRYPT_MEM; |
|
346 } |
|
347 if ((err = mpi_to_ltc_error(mp_montgomery_setup(a, (mp_digit *)*b))) != CRYPT_OK) { |
|
348 XFREE(*b); |
|
349 } |
|
350 return err; |
|
351 } |
|
352 |
|
353 /* get normalization value */ |
|
354 static int montgomery_normalization(void *a, void *b) |
|
355 { |
|
356 LTC_ARGCHK(a != NULL); |
|
357 LTC_ARGCHK(b != NULL); |
|
358 return mpi_to_ltc_error(mp_montgomery_calc_normalization(a, b)); |
|
359 } |
|
360 |
|
361 /* reduce */ |
|
362 static int montgomery_reduce(void *a, void *b, void *c) |
|
363 { |
|
364 LTC_ARGCHK(a != NULL); |
|
365 LTC_ARGCHK(b != NULL); |
|
366 LTC_ARGCHK(c != NULL); |
|
367 return mpi_to_ltc_error(mp_montgomery_reduce(a, b, *((mp_digit *)c))); |
|
368 } |
|
369 |
|
370 /* clean up */ |
|
371 static void montgomery_deinit(void *a) |
|
372 { |
|
373 XFREE(a); |
|
374 } |
|
375 |
|
376 static int exptmod(void *a, void *b, void *c, void *d) |
|
377 { |
|
378 LTC_ARGCHK(a != NULL); |
|
379 LTC_ARGCHK(b != NULL); |
|
380 LTC_ARGCHK(c != NULL); |
|
381 LTC_ARGCHK(d != NULL); |
|
382 return mpi_to_ltc_error(mp_exptmod(a,b,c,d)); |
|
383 } |
|
384 |
|
385 static int isprime(void *a, int *b) |
|
386 { |
|
387 int err; |
|
388 LTC_ARGCHK(a != NULL); |
|
389 LTC_ARGCHK(b != NULL); |
|
390 err = mpi_to_ltc_error(mp_prime_is_prime(a, 8, b)); |
|
391 *b = (*b == MP_YES) ? LTC_MP_YES : LTC_MP_NO; |
|
392 return err; |
|
393 } |
|
394 |
|
395 const ltc_math_descriptor ltm_desc = { |
|
396 |
|
397 "LibTomMath", |
|
398 (int)DIGIT_BIT, |
|
399 |
|
400 &init, |
|
401 &init_copy, |
|
402 &deinit, |
|
403 |
|
404 &neg, |
|
405 ©, |
|
406 |
|
407 &set_int, |
|
408 &get_int, |
|
409 &get_digit, |
|
410 &get_digit_count, |
|
411 &compare, |
|
412 &compare_d, |
|
413 &count_bits, |
|
414 &count_lsb_bits, |
|
415 &twoexpt, |
|
416 |
|
417 &read_radix, |
|
418 &write_radix, |
|
419 &unsigned_size, |
|
420 &unsigned_write, |
|
421 &unsigned_read, |
|
422 |
|
423 &add, |
|
424 &addi, |
|
425 &sub, |
|
426 &subi, |
|
427 &mul, |
|
428 &muli, |
|
429 &sqr, |
|
430 ÷, |
|
431 &div_2, |
|
432 &modi, |
|
433 &gcd, |
|
434 &lcm, |
|
435 |
|
436 &mulmod, |
|
437 &sqrmod, |
|
438 &invmod, |
|
439 |
|
440 &montgomery_setup, |
|
441 &montgomery_normalization, |
|
442 &montgomery_reduce, |
|
443 &montgomery_deinit, |
|
444 |
|
445 &exptmod, |
|
446 &isprime, |
|
447 |
|
448 #ifdef MECC |
|
449 #ifdef MECC_FP |
|
450 <c_ecc_fp_mulmod, |
|
451 #else |
|
452 <c_ecc_mulmod, |
|
453 #endif |
|
454 <c_ecc_projective_add_point, |
|
455 <c_ecc_projective_dbl_point, |
|
456 <c_ecc_map, |
|
457 #ifdef LTC_ECC_SHAMIR |
|
458 #ifdef MECC_FP |
|
459 <c_ecc_fp_mul2add, |
|
460 #else |
|
461 <c_ecc_mul2add, |
|
462 #endif /* MECC_FP */ |
|
463 #else |
|
464 NULL, |
|
465 #endif /* LTC_ECC_SHAMIR */ |
|
466 #else |
|
467 NULL, NULL, NULL, NULL, NULL, |
|
468 #endif /* MECC */ |
|
469 |
|
470 #ifdef MRSA |
|
471 &rsa_make_key, |
|
472 &rsa_exptmod, |
|
473 #else |
|
474 NULL, NULL |
|
475 #endif |
|
476 }; |
|
477 |
|
478 |
|
479 #endif |
|
480 |
|
481 /* $Source: /cvs/libtom/libtomcrypt/src/math/ltm_desc.c,v $ */ |
|
482 /* $Revision: 1.29 $ */ |
|
483 /* $Date: 2006/12/03 00:39:56 $ */ |