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, tomstdenis@gmail.com, http://libtomcrypt.com
10 */
11
12 #define DESC_DEF_ONLY
13 #include "tomcrypt.h"
14
15 #ifdef TFM_DESC
16
17 #include <tfm.h>
18
19 static const struct {
20 int tfm_code, ltc_code;
21 } tfm_to_ltc_codes[] = {
22 { FP_OKAY , CRYPT_OK},
23 { FP_MEM , CRYPT_MEM},
24 { FP_VAL , CRYPT_INVALID_ARG},
25 };
26
27 /**
28 Convert a tfm 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 */
tfm_to_ltc_error(int err)32 static int tfm_to_ltc_error(int err)
33 {
34 int x;
35
36 for (x = 0; x < (int)(sizeof(tfm_to_ltc_codes)/sizeof(tfm_to_ltc_codes[0])); x++) {
37 if (err == tfm_to_ltc_codes[x].tfm_code) {
38 return tfm_to_ltc_codes[x].ltc_code;
39 }
40 }
41 return CRYPT_ERROR;
42 }
43
init(void ** a)44 static int init(void **a)
45 {
46 LTC_ARGCHK(a != NULL);
47
48 *a = XCALLOC(1, sizeof(fp_int));
49 if (*a == NULL) {
50 return CRYPT_MEM;
51 }
52 fp_init(*a);
53 return CRYPT_OK;
54 }
55
deinit(void * a)56 static void deinit(void *a)
57 {
58 LTC_ARGCHKVD(a != NULL);
59 XFREE(a);
60 }
61
neg(void * a,void * b)62 static int neg(void *a, void *b)
63 {
64 LTC_ARGCHK(a != NULL);
65 LTC_ARGCHK(b != NULL);
66 fp_neg(((fp_int*)a), ((fp_int*)b));
67 return CRYPT_OK;
68 }
69
copy(void * a,void * b)70 static int copy(void *a, void *b)
71 {
72 LTC_ARGCHK(a != NULL);
73 LTC_ARGCHK(b != NULL);
74 fp_copy(a, b);
75 return CRYPT_OK;
76 }
77
init_copy(void ** a,void * b)78 static int init_copy(void **a, void *b)
79 {
80 if (init(a) != CRYPT_OK) {
81 return CRYPT_MEM;
82 }
83 return copy(b, *a);
84 }
85
86 /* ---- trivial ---- */
set_int(void * a,unsigned long b)87 static int set_int(void *a, unsigned long b)
88 {
89 LTC_ARGCHK(a != NULL);
90 fp_set(a, b);
91 return CRYPT_OK;
92 }
93
get_int(void * a)94 static unsigned long get_int(void *a)
95 {
96 fp_int *A;
97 LTC_ARGCHK(a != NULL);
98 A = a;
99 return A->used > 0 ? A->dp[0] : 0;
100 }
101
get_digit(void * a,int n)102 static unsigned long get_digit(void *a, int n)
103 {
104 fp_int *A;
105 LTC_ARGCHK(a != NULL);
106 A = a;
107 return (n >= A->used || n < 0) ? 0 : A->dp[n];
108 }
109
get_digit_count(void * a)110 static int get_digit_count(void *a)
111 {
112 fp_int *A;
113 LTC_ARGCHK(a != NULL);
114 A = a;
115 return A->used;
116 }
117
compare(void * a,void * b)118 static int compare(void *a, void *b)
119 {
120 int ret;
121 LTC_ARGCHK(a != NULL);
122 LTC_ARGCHK(b != NULL);
123 ret = fp_cmp(a, b);
124 switch (ret) {
125 case FP_LT: return LTC_MP_LT;
126 case FP_EQ: return LTC_MP_EQ;
127 case FP_GT: return LTC_MP_GT;
128 }
129 return 0;
130 }
131
compare_d(void * a,unsigned long b)132 static int compare_d(void *a, unsigned long b)
133 {
134 int ret;
135 LTC_ARGCHK(a != NULL);
136 ret = fp_cmp_d(a, b);
137 switch (ret) {
138 case FP_LT: return LTC_MP_LT;
139 case FP_EQ: return LTC_MP_EQ;
140 case FP_GT: return LTC_MP_GT;
141 }
142 return 0;
143 }
144
count_bits(void * a)145 static int count_bits(void *a)
146 {
147 LTC_ARGCHK(a != NULL);
148 return fp_count_bits(a);
149 }
150
count_lsb_bits(void * a)151 static int count_lsb_bits(void *a)
152 {
153 LTC_ARGCHK(a != NULL);
154 return fp_cnt_lsb(a);
155 }
156
twoexpt(void * a,int n)157 static int twoexpt(void *a, int n)
158 {
159 LTC_ARGCHK(a != NULL);
160 fp_2expt(a, n);
161 return CRYPT_OK;
162 }
163
164 /* ---- conversions ---- */
165
166 /* read ascii string */
read_radix(void * a,const char * b,int radix)167 static int read_radix(void *a, const char *b, int radix)
168 {
169 LTC_ARGCHK(a != NULL);
170 LTC_ARGCHK(b != NULL);
171 return tfm_to_ltc_error(fp_read_radix(a, (char *)b, radix));
172 }
173
174 /* write one */
write_radix(void * a,char * b,int radix)175 static int write_radix(void *a, char *b, int radix)
176 {
177 LTC_ARGCHK(a != NULL);
178 LTC_ARGCHK(b != NULL);
179 return tfm_to_ltc_error(fp_toradix(a, b, radix));
180 }
181
182 /* get size as unsigned char string */
unsigned_size(void * a)183 static unsigned long unsigned_size(void *a)
184 {
185 LTC_ARGCHK(a != NULL);
186 return fp_unsigned_bin_size(a);
187 }
188
189 /* store */
unsigned_write(void * a,unsigned char * b)190 static int unsigned_write(void *a, unsigned char *b)
191 {
192 LTC_ARGCHK(a != NULL);
193 LTC_ARGCHK(b != NULL);
194 fp_to_unsigned_bin(a, b);
195 return CRYPT_OK;
196 }
197
198 /* read */
unsigned_read(void * a,unsigned char * b,unsigned long len)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 fp_read_unsigned_bin(a, b, len);
204 return CRYPT_OK;
205 }
206
207 /* add */
add(void * a,void * b,void * c)208 static int add(void *a, void *b, void *c)
209 {
210 LTC_ARGCHK(a != NULL);
211 LTC_ARGCHK(b != NULL);
212 LTC_ARGCHK(c != NULL);
213 fp_add(a, b, c);
214 return CRYPT_OK;
215 }
216
addi(void * a,unsigned long b,void * c)217 static int addi(void *a, unsigned long b, void *c)
218 {
219 LTC_ARGCHK(a != NULL);
220 LTC_ARGCHK(c != NULL);
221 fp_add_d(a, b, c);
222 return CRYPT_OK;
223 }
224
225 /* sub */
sub(void * a,void * b,void * c)226 static int sub(void *a, void *b, void *c)
227 {
228 LTC_ARGCHK(a != NULL);
229 LTC_ARGCHK(b != NULL);
230 LTC_ARGCHK(c != NULL);
231 fp_sub(a, b, c);
232 return CRYPT_OK;
233 }
234
subi(void * a,unsigned long b,void * c)235 static int subi(void *a, unsigned long b, void *c)
236 {
237 LTC_ARGCHK(a != NULL);
238 LTC_ARGCHK(c != NULL);
239 fp_sub_d(a, b, c);
240 return CRYPT_OK;
241 }
242
243 /* mul */
mul(void * a,void * b,void * c)244 static int mul(void *a, void *b, void *c)
245 {
246 LTC_ARGCHK(a != NULL);
247 LTC_ARGCHK(b != NULL);
248 LTC_ARGCHK(c != NULL);
249 fp_mul(a, b, c);
250 return CRYPT_OK;
251 }
252
muli(void * a,unsigned long b,void * c)253 static int muli(void *a, unsigned long b, void *c)
254 {
255 LTC_ARGCHK(a != NULL);
256 LTC_ARGCHK(c != NULL);
257 fp_mul_d(a, b, c);
258 return CRYPT_OK;
259 }
260
261 /* sqr */
sqr(void * a,void * b)262 static int sqr(void *a, void *b)
263 {
264 LTC_ARGCHK(a != NULL);
265 LTC_ARGCHK(b != NULL);
266 fp_sqr(a, b);
267 return CRYPT_OK;
268 }
269
270 /* div */
divide(void * a,void * b,void * c,void * d)271 static int divide(void *a, void *b, void *c, void *d)
272 {
273 LTC_ARGCHK(a != NULL);
274 LTC_ARGCHK(b != NULL);
275 return tfm_to_ltc_error(fp_div(a, b, c, d));
276 }
277
div_2(void * a,void * b)278 static int div_2(void *a, void *b)
279 {
280 LTC_ARGCHK(a != NULL);
281 LTC_ARGCHK(b != NULL);
282 fp_div_2(a, b);
283 return CRYPT_OK;
284 }
285
286 /* modi */
modi(void * a,unsigned long b,unsigned long * c)287 static int modi(void *a, unsigned long b, unsigned long *c)
288 {
289 fp_digit tmp;
290 int err;
291
292 LTC_ARGCHK(a != NULL);
293 LTC_ARGCHK(c != NULL);
294
295 if ((err = tfm_to_ltc_error(fp_mod_d(a, b, &tmp))) != CRYPT_OK) {
296 return err;
297 }
298 *c = tmp;
299 return CRYPT_OK;
300 }
301
302 /* gcd */
gcd(void * a,void * b,void * c)303 static int gcd(void *a, void *b, void *c)
304 {
305 LTC_ARGCHK(a != NULL);
306 LTC_ARGCHK(b != NULL);
307 LTC_ARGCHK(c != NULL);
308 fp_gcd(a, b, c);
309 return CRYPT_OK;
310 }
311
312 /* lcm */
lcm(void * a,void * b,void * c)313 static int lcm(void *a, void *b, void *c)
314 {
315 LTC_ARGCHK(a != NULL);
316 LTC_ARGCHK(b != NULL);
317 LTC_ARGCHK(c != NULL);
318 fp_lcm(a, b, c);
319 return CRYPT_OK;
320 }
321
mulmod(void * a,void * b,void * c,void * d)322 static int mulmod(void *a, void *b, void *c, void *d)
323 {
324 LTC_ARGCHK(a != NULL);
325 LTC_ARGCHK(b != NULL);
326 LTC_ARGCHK(c != NULL);
327 LTC_ARGCHK(d != NULL);
328 return tfm_to_ltc_error(fp_mulmod(a,b,c,d));
329 }
330
sqrmod(void * a,void * b,void * c)331 static int sqrmod(void *a, void *b, void *c)
332 {
333 LTC_ARGCHK(a != NULL);
334 LTC_ARGCHK(b != NULL);
335 LTC_ARGCHK(c != NULL);
336 return tfm_to_ltc_error(fp_sqrmod(a,b,c));
337 }
338
339 /* invmod */
invmod(void * a,void * b,void * c)340 static int invmod(void *a, void *b, void *c)
341 {
342 LTC_ARGCHK(a != NULL);
343 LTC_ARGCHK(b != NULL);
344 LTC_ARGCHK(c != NULL);
345 return tfm_to_ltc_error(fp_invmod(a, b, c));
346 }
347
348 /* setup */
montgomery_setup(void * a,void ** b)349 static int montgomery_setup(void *a, void **b)
350 {
351 int err;
352 LTC_ARGCHK(a != NULL);
353 LTC_ARGCHK(b != NULL);
354 *b = XCALLOC(1, sizeof(fp_digit));
355 if (*b == NULL) {
356 return CRYPT_MEM;
357 }
358 if ((err = tfm_to_ltc_error(fp_montgomery_setup(a, (fp_digit *)*b))) != CRYPT_OK) {
359 XFREE(*b);
360 }
361 return err;
362 }
363
364 /* get normalization value */
montgomery_normalization(void * a,void * b)365 static int montgomery_normalization(void *a, void *b)
366 {
367 LTC_ARGCHK(a != NULL);
368 LTC_ARGCHK(b != NULL);
369 fp_montgomery_calc_normalization(a, b);
370 return CRYPT_OK;
371 }
372
373 /* reduce */
montgomery_reduce(void * a,void * b,void * c)374 static int montgomery_reduce(void *a, void *b, void *c)
375 {
376 LTC_ARGCHK(a != NULL);
377 LTC_ARGCHK(b != NULL);
378 LTC_ARGCHK(c != NULL);
379 fp_montgomery_reduce(a, b, *((fp_digit *)c));
380 return CRYPT_OK;
381 }
382
383 /* clean up */
montgomery_deinit(void * a)384 static void montgomery_deinit(void *a)
385 {
386 XFREE(a);
387 }
388
exptmod(void * a,void * b,void * c,void * d)389 static int exptmod(void *a, void *b, void *c, void *d)
390 {
391 LTC_ARGCHK(a != NULL);
392 LTC_ARGCHK(b != NULL);
393 LTC_ARGCHK(c != NULL);
394 LTC_ARGCHK(d != NULL);
395 return tfm_to_ltc_error(fp_exptmod(a,b,c,d));
396 }
397
isprime(void * a,int * b)398 static int isprime(void *a, int *b)
399 {
400 LTC_ARGCHK(a != NULL);
401 LTC_ARGCHK(b != NULL);
402 *b = (fp_isprime(a) == FP_YES) ? LTC_MP_YES : LTC_MP_NO;
403 return CRYPT_OK;
404 }
405
406 #if defined(MECC) && defined(MECC_ACCEL)
407
tfm_ecc_projective_dbl_point(ecc_point * P,ecc_point * R,void * modulus,void * Mp)408 static int tfm_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *Mp)
409 {
410 fp_int t1, t2;
411 fp_digit mp;
412
413 LTC_ARGCHK(P != NULL);
414 LTC_ARGCHK(R != NULL);
415 LTC_ARGCHK(modulus != NULL);
416 LTC_ARGCHK(Mp != NULL);
417
418 mp = *((fp_digit*)Mp);
419
420 fp_init(&t1);
421 fp_init(&t2);
422
423 if (P != R) {
424 fp_copy(P->x, R->x);
425 fp_copy(P->y, R->y);
426 fp_copy(P->z, R->z);
427 }
428
429 /* t1 = Z * Z */
430 fp_sqr(R->z, &t1);
431 fp_montgomery_reduce(&t1, modulus, mp);
432 /* Z = Y * Z */
433 fp_mul(R->z, R->y, R->z);
434 fp_montgomery_reduce(R->z, modulus, mp);
435 /* Z = 2Z */
436 fp_add(R->z, R->z, R->z);
437 if (fp_cmp(R->z, modulus) != FP_LT) {
438 fp_sub(R->z, modulus, R->z);
439 }
440
441 /* &t2 = X - T1 */
442 fp_sub(R->x, &t1, &t2);
443 if (fp_cmp_d(&t2, 0) == FP_LT) {
444 fp_add(&t2, modulus, &t2);
445 }
446 /* T1 = X + T1 */
447 fp_add(&t1, R->x, &t1);
448 if (fp_cmp(&t1, modulus) != FP_LT) {
449 fp_sub(&t1, modulus, &t1);
450 }
451 /* T2 = T1 * T2 */
452 fp_mul(&t1, &t2, &t2);
453 fp_montgomery_reduce(&t2, modulus, mp);
454 /* T1 = 2T2 */
455 fp_add(&t2, &t2, &t1);
456 if (fp_cmp(&t1, modulus) != FP_LT) {
457 fp_sub(&t1, modulus, &t1);
458 }
459 /* T1 = T1 + T2 */
460 fp_add(&t1, &t2, &t1);
461 if (fp_cmp(&t1, modulus) != FP_LT) {
462 fp_sub(&t1, modulus, &t1);
463 }
464
465 /* Y = 2Y */
466 fp_add(R->y, R->y, R->y);
467 if (fp_cmp(R->y, modulus) != FP_LT) {
468 fp_sub(R->y, modulus, R->y);
469 }
470 /* Y = Y * Y */
471 fp_sqr(R->y, R->y);
472 fp_montgomery_reduce(R->y, modulus, mp);
473 /* T2 = Y * Y */
474 fp_sqr(R->y, &t2);
475 fp_montgomery_reduce(&t2, modulus, mp);
476 /* T2 = T2/2 */
477 if (fp_isodd(&t2)) {
478 fp_add(&t2, modulus, &t2);
479 }
480 fp_div_2(&t2, &t2);
481 /* Y = Y * X */
482 fp_mul(R->y, R->x, R->y);
483 fp_montgomery_reduce(R->y, modulus, mp);
484
485 /* X = T1 * T1 */
486 fp_sqr(&t1, R->x);
487 fp_montgomery_reduce(R->x, modulus, mp);
488 /* X = X - Y */
489 fp_sub(R->x, R->y, R->x);
490 if (fp_cmp_d(R->x, 0) == FP_LT) {
491 fp_add(R->x, modulus, R->x);
492 }
493 /* X = X - Y */
494 fp_sub(R->x, R->y, R->x);
495 if (fp_cmp_d(R->x, 0) == FP_LT) {
496 fp_add(R->x, modulus, R->x);
497 }
498
499 /* Y = Y - X */
500 fp_sub(R->y, R->x, R->y);
501 if (fp_cmp_d(R->y, 0) == FP_LT) {
502 fp_add(R->y, modulus, R->y);
503 }
504 /* Y = Y * T1 */
505 fp_mul(R->y, &t1, R->y);
506 fp_montgomery_reduce(R->y, modulus, mp);
507 /* Y = Y - T2 */
508 fp_sub(R->y, &t2, R->y);
509 if (fp_cmp_d(R->y, 0) == FP_LT) {
510 fp_add(R->y, modulus, R->y);
511 }
512
513 return CRYPT_OK;
514 }
515
516 /**
517 Add two ECC points
518 @param P The point to add
519 @param Q The point to add
520 @param R [out] The destination of the double
521 @param modulus The modulus of the field the ECC curve is in
522 @param mp The "b" value from montgomery_setup()
523 @return CRYPT_OK on success
524 */
tfm_ecc_projective_add_point(ecc_point * P,ecc_point * Q,ecc_point * R,void * modulus,void * Mp)525 static int tfm_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *Mp)
526 {
527 fp_int t1, t2, x, y, z;
528 fp_digit mp;
529
530 LTC_ARGCHK(P != NULL);
531 LTC_ARGCHK(Q != NULL);
532 LTC_ARGCHK(R != NULL);
533 LTC_ARGCHK(modulus != NULL);
534 LTC_ARGCHK(Mp != NULL);
535
536 mp = *((fp_digit*)Mp);
537
538 fp_init(&t1);
539 fp_init(&t2);
540 fp_init(&x);
541 fp_init(&y);
542 fp_init(&z);
543
544 /* should we dbl instead? */
545 fp_sub(modulus, Q->y, &t1);
546 if ( (fp_cmp(P->x, Q->x) == FP_EQ) &&
547 (Q->z != NULL && fp_cmp(P->z, Q->z) == FP_EQ) &&
548 (fp_cmp(P->y, Q->y) == FP_EQ || fp_cmp(P->y, &t1) == FP_EQ)) {
549 return tfm_ecc_projective_dbl_point(P, R, modulus, Mp);
550 }
551
552 fp_copy(P->x, &x);
553 fp_copy(P->y, &y);
554 fp_copy(P->z, &z);
555
556 /* if Z is one then these are no-operations */
557 if (Q->z != NULL) {
558 /* T1 = Z' * Z' */
559 fp_sqr(Q->z, &t1);
560 fp_montgomery_reduce(&t1, modulus, mp);
561 /* X = X * T1 */
562 fp_mul(&t1, &x, &x);
563 fp_montgomery_reduce(&x, modulus, mp);
564 /* T1 = Z' * T1 */
565 fp_mul(Q->z, &t1, &t1);
566 fp_montgomery_reduce(&t1, modulus, mp);
567 /* Y = Y * T1 */
568 fp_mul(&t1, &y, &y);
569 fp_montgomery_reduce(&y, modulus, mp);
570 }
571
572 /* T1 = Z*Z */
573 fp_sqr(&z, &t1);
574 fp_montgomery_reduce(&t1, modulus, mp);
575 /* T2 = X' * T1 */
576 fp_mul(Q->x, &t1, &t2);
577 fp_montgomery_reduce(&t2, modulus, mp);
578 /* T1 = Z * T1 */
579 fp_mul(&z, &t1, &t1);
580 fp_montgomery_reduce(&t1, modulus, mp);
581 /* T1 = Y' * T1 */
582 fp_mul(Q->y, &t1, &t1);
583 fp_montgomery_reduce(&t1, modulus, mp);
584
585 /* Y = Y - T1 */
586 fp_sub(&y, &t1, &y);
587 if (fp_cmp_d(&y, 0) == FP_LT) {
588 fp_add(&y, modulus, &y);
589 }
590 /* T1 = 2T1 */
591 fp_add(&t1, &t1, &t1);
592 if (fp_cmp(&t1, modulus) != FP_LT) {
593 fp_sub(&t1, modulus, &t1);
594 }
595 /* T1 = Y + T1 */
596 fp_add(&t1, &y, &t1);
597 if (fp_cmp(&t1, modulus) != FP_LT) {
598 fp_sub(&t1, modulus, &t1);
599 }
600 /* X = X - T2 */
601 fp_sub(&x, &t2, &x);
602 if (fp_cmp_d(&x, 0) == FP_LT) {
603 fp_add(&x, modulus, &x);
604 }
605 /* T2 = 2T2 */
606 fp_add(&t2, &t2, &t2);
607 if (fp_cmp(&t2, modulus) != FP_LT) {
608 fp_sub(&t2, modulus, &t2);
609 }
610 /* T2 = X + T2 */
611 fp_add(&t2, &x, &t2);
612 if (fp_cmp(&t2, modulus) != FP_LT) {
613 fp_sub(&t2, modulus, &t2);
614 }
615
616 /* if Z' != 1 */
617 if (Q->z != NULL) {
618 /* Z = Z * Z' */
619 fp_mul(&z, Q->z, &z);
620 fp_montgomery_reduce(&z, modulus, mp);
621 }
622
623 /* Z = Z * X */
624 fp_mul(&z, &x, &z);
625 fp_montgomery_reduce(&z, modulus, mp);
626
627 /* T1 = T1 * X */
628 fp_mul(&t1, &x, &t1);
629 fp_montgomery_reduce(&t1, modulus, mp);
630 /* X = X * X */
631 fp_sqr(&x, &x);
632 fp_montgomery_reduce(&x, modulus, mp);
633 /* T2 = T2 * x */
634 fp_mul(&t2, &x, &t2);
635 fp_montgomery_reduce(&t2, modulus, mp);
636 /* T1 = T1 * X */
637 fp_mul(&t1, &x, &t1);
638 fp_montgomery_reduce(&t1, modulus, mp);
639
640 /* X = Y*Y */
641 fp_sqr(&y, &x);
642 fp_montgomery_reduce(&x, modulus, mp);
643 /* X = X - T2 */
644 fp_sub(&x, &t2, &x);
645 if (fp_cmp_d(&x, 0) == FP_LT) {
646 fp_add(&x, modulus, &x);
647 }
648
649 /* T2 = T2 - X */
650 fp_sub(&t2, &x, &t2);
651 if (fp_cmp_d(&t2, 0) == FP_LT) {
652 fp_add(&t2, modulus, &t2);
653 }
654 /* T2 = T2 - X */
655 fp_sub(&t2, &x, &t2);
656 if (fp_cmp_d(&t2, 0) == FP_LT) {
657 fp_add(&t2, modulus, &t2);
658 }
659 /* T2 = T2 * Y */
660 fp_mul(&t2, &y, &t2);
661 fp_montgomery_reduce(&t2, modulus, mp);
662 /* Y = T2 - T1 */
663 fp_sub(&t2, &t1, &y);
664 if (fp_cmp_d(&y, 0) == FP_LT) {
665 fp_add(&y, modulus, &y);
666 }
667 /* Y = Y/2 */
668 if (fp_isodd(&y)) {
669 fp_add(&y, modulus, &y);
670 }
671 fp_div_2(&y, &y);
672
673 fp_copy(&x, R->x);
674 fp_copy(&y, R->y);
675 fp_copy(&z, R->z);
676
677 return CRYPT_OK;
678 }
679
680
681 #endif
682
683 const ltc_math_descriptor tfm_desc = {
684
685 "TomsFastMath",
686 (int)DIGIT_BIT,
687
688 &init,
689 &init_copy,
690 &deinit,
691
692 &neg,
693 ©,
694
695 &set_int,
696 &get_int,
697 &get_digit,
698 &get_digit_count,
699 &compare,
700 &compare_d,
701 &count_bits,
702 &count_lsb_bits,
703 &twoexpt,
704
705 &read_radix,
706 &write_radix,
707 &unsigned_size,
708 &unsigned_write,
709 &unsigned_read,
710
711 &add,
712 &addi,
713 &sub,
714 &subi,
715 &mul,
716 &muli,
717 &sqr,
718 ÷,
719 &div_2,
720 &modi,
721 &gcd,
722 &lcm,
723
724 &mulmod,
725 &sqrmod,
726 &invmod,
727
728 &montgomery_setup,
729 &montgomery_normalization,
730 &montgomery_reduce,
731 &montgomery_deinit,
732
733 &exptmod,
734 &isprime,
735
736 #ifdef MECC
737 #ifdef MECC_FP
738 <c_ecc_fp_mulmod,
739 #else
740 <c_ecc_mulmod,
741 #endif /* MECC_FP */
742 #ifdef MECC_ACCEL
743 &tfm_ecc_projective_add_point,
744 &tfm_ecc_projective_dbl_point,
745 #else
746 <c_ecc_projective_add_point,
747 <c_ecc_projective_dbl_point,
748 #endif /* MECC_ACCEL */
749 <c_ecc_map,
750 #ifdef LTC_ECC_SHAMIR
751 #ifdef MECC_FP
752 <c_ecc_fp_mul2add,
753 #else
754 <c_ecc_mul2add,
755 #endif /* MECC_FP */
756 #else
757 NULL,
758 #endif /* LTC_ECC_SHAMIR */
759 #else
760 NULL, NULL, NULL, NULL, NULL,
761 #endif /* MECC */
762
763 #ifdef MRSA
764 &rsa_make_key,
765 &rsa_exptmod,
766 #else
767 NULL, NULL
768 #endif
769
770 };
771
772
773 #endif
774
775 /* $Source: /cvs/libtom/libtomcrypt/src/math/tfm_desc.c,v $ */
776 /* $Revision: 1.26 $ */
777 /* $Date: 2006/12/03 00:39:56 $ */
778