Mercurial > dropbear
comparison libtomcrypt/src/math/tfm_desc.c @ 382:0cbe8f6dbf9e
propagate from branch 'au.asn.ucc.matt.ltc.dropbear' (head 2af22fb4e878750b88f80f90d439b316d229796f)
to branch 'au.asn.ucc.matt.dropbear' (head 02c413252c90e9de8e03d91e9939dde3029f5c0a)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 11 Jan 2007 02:41:05 +0000 |
parents | |
children | f849a5ca2efc |
comparison
equal
deleted
inserted
replaced
379:b66a00272a90 | 382:0cbe8f6dbf9e |
---|---|
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 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 */ | |
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 | |
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 | |
56 static void deinit(void *a) | |
57 { | |
58 LTC_ARGCHKVD(a != NULL); | |
59 XFREE(a); | |
60 } | |
61 | |
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 | |
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 | |
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 ---- */ | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
145 static int count_bits(void *a) | |
146 { | |
147 LTC_ARGCHK(a != NULL); | |
148 return fp_count_bits(a); | |
149 } | |
150 | |
151 static int count_lsb_bits(void *a) | |
152 { | |
153 LTC_ARGCHK(a != NULL); | |
154 return fp_cnt_lsb(a); | |
155 } | |
156 | |
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 */ | |
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 */ | |
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 */ | |
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 */ | |
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 */ | |
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 */ | |
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 | |
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 */ | |
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 | |
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 */ | |
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 | |
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 */ | |
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 */ | |
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 | |
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 */ | |
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 */ | |
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 */ | |
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 | |
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 | |
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 */ | |
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 */ | |
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 */ | |
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 */ | |
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 */ | |
384 static void montgomery_deinit(void *a) | |
385 { | |
386 XFREE(a); | |
387 } | |
388 | |
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 | |
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 | |
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 */ | |
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 $ */ |