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