Mercurial > dropbear
comparison libtommath/bn_mp_exptmod.c @ 1692:1051e4eea25a
Update LibTomMath to 1.2.0 (#84)
* update C files
* update other files
* update headers
* update makefiles
* remove mp_set/get_double()
* use ltm 1.2.0 API
* update ltm_desc
* use bundled tommath if system-tommath is too old
* XMALLOC etc. were changed to MP_MALLOC etc.
author | Steffen Jaeckel <s@jaeckel.eu> |
---|---|
date | Tue, 26 May 2020 17:36:47 +0200 |
parents | f52919ffd3b1 |
children |
comparison
equal
deleted
inserted
replaced
1691:2d3745d58843 | 1692:1051e4eea25a |
---|---|
1 #include "tommath_private.h" | 1 #include "tommath_private.h" |
2 #ifdef BN_MP_EXPTMOD_C | 2 #ifdef BN_MP_EXPTMOD_C |
3 /* LibTomMath, multiple-precision integer library -- Tom St Denis | 3 /* LibTomMath, multiple-precision integer library -- Tom St Denis */ |
4 * | 4 /* SPDX-License-Identifier: Unlicense */ |
5 * LibTomMath is a library that provides multiple-precision | |
6 * integer arithmetic as well as number theoretic functionality. | |
7 * | |
8 * The library was designed directly after the MPI library by | |
9 * Michael Fromberger but has been written from scratch with | |
10 * additional optimizations in place. | |
11 * | |
12 * SPDX-License-Identifier: Unlicense | |
13 */ | |
14 | |
15 | 5 |
16 /* this is a shell function that calls either the normal or Montgomery | 6 /* this is a shell function that calls either the normal or Montgomery |
17 * exptmod functions. Originally the call to the montgomery code was | 7 * exptmod functions. Originally the call to the montgomery code was |
18 * embedded in the normal function but that wasted alot of stack space | 8 * embedded in the normal function but that wasted alot of stack space |
19 * for nothing (since 99% of the time the Montgomery code would be called) | 9 * for nothing (since 99% of the time the Montgomery code would be called) |
20 */ | 10 */ |
21 int mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y) | 11 mp_err mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y) |
22 { | 12 { |
23 int dr; | 13 int dr; |
24 | 14 |
25 /* modulus P must be positive */ | 15 /* modulus P must be positive */ |
26 if (P->sign == MP_NEG) { | 16 if (P->sign == MP_NEG) { |
27 return MP_VAL; | 17 return MP_VAL; |
28 } | 18 } |
29 | 19 |
30 /* if exponent X is negative we have to recurse */ | 20 /* if exponent X is negative we have to recurse */ |
31 if (X->sign == MP_NEG) { | 21 if (X->sign == MP_NEG) { |
32 #ifdef BN_MP_INVMOD_C | |
33 mp_int tmpG, tmpX; | 22 mp_int tmpG, tmpX; |
34 int err; | 23 mp_err err; |
35 | 24 |
36 /* first compute 1/G mod P */ | 25 if (!MP_HAS(MP_INVMOD)) { |
37 if ((err = mp_init(&tmpG)) != MP_OKAY) { | 26 return MP_VAL; |
38 return err; | |
39 } | 27 } |
40 if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) { | 28 |
41 mp_clear(&tmpG); | 29 if ((err = mp_init_multi(&tmpG, &tmpX, NULL)) != MP_OKAY) { |
42 return err; | 30 return err; |
43 } | 31 } |
44 | 32 |
33 /* first compute 1/G mod P */ | |
34 if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) { | |
35 goto LBL_ERR; | |
36 } | |
37 | |
45 /* now get |X| */ | 38 /* now get |X| */ |
46 if ((err = mp_init(&tmpX)) != MP_OKAY) { | |
47 mp_clear(&tmpG); | |
48 return err; | |
49 } | |
50 if ((err = mp_abs(X, &tmpX)) != MP_OKAY) { | 39 if ((err = mp_abs(X, &tmpX)) != MP_OKAY) { |
51 mp_clear_multi(&tmpG, &tmpX, NULL); | 40 goto LBL_ERR; |
52 return err; | |
53 } | 41 } |
54 | 42 |
55 /* and now compute (1/G)**|X| instead of G**X [X < 0] */ | 43 /* and now compute (1/G)**|X| instead of G**X [X < 0] */ |
56 err = mp_exptmod(&tmpG, &tmpX, P, Y); | 44 err = mp_exptmod(&tmpG, &tmpX, P, Y); |
45 LBL_ERR: | |
57 mp_clear_multi(&tmpG, &tmpX, NULL); | 46 mp_clear_multi(&tmpG, &tmpX, NULL); |
58 return err; | 47 return err; |
59 #else | |
60 /* no invmod */ | |
61 return MP_VAL; | |
62 #endif | |
63 } | 48 } |
64 | 49 |
65 /* modified diminished radix reduction */ | 50 /* modified diminished radix reduction */ |
66 #if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_C) | 51 if (MP_HAS(MP_REDUCE_IS_2K_L) && MP_HAS(MP_REDUCE_2K_L) && MP_HAS(S_MP_EXPTMOD) && |
67 if (mp_reduce_is_2k_l(P) == MP_YES) { | 52 (mp_reduce_is_2k_l(P) == MP_YES)) { |
68 return s_mp_exptmod(G, X, P, Y, 1); | 53 return s_mp_exptmod(G, X, P, Y, 1); |
69 } | 54 } |
70 #endif | |
71 | 55 |
72 #ifdef BN_MP_DR_IS_MODULUS_C | 56 /* is it a DR modulus? default to no */ |
73 /* is it a DR modulus? */ | 57 dr = (MP_HAS(MP_DR_IS_MODULUS) && (mp_dr_is_modulus(P) == MP_YES)) ? 1 : 0; |
74 dr = mp_dr_is_modulus(P); | |
75 #else | |
76 /* default to no */ | |
77 dr = 0; | |
78 #endif | |
79 | 58 |
80 #ifdef BN_MP_REDUCE_IS_2K_C | |
81 /* if not, is it a unrestricted DR modulus? */ | 59 /* if not, is it a unrestricted DR modulus? */ |
82 if (dr == 0) { | 60 if (MP_HAS(MP_REDUCE_IS_2K) && (dr == 0)) { |
83 dr = mp_reduce_is_2k(P) << 1; | 61 dr = (mp_reduce_is_2k(P) == MP_YES) ? 2 : 0; |
84 } | 62 } |
85 #endif | |
86 | 63 |
87 /* if the modulus is odd or dr != 0 use the montgomery method */ | 64 /* if the modulus is odd or dr != 0 use the montgomery method */ |
88 #ifdef BN_MP_EXPTMOD_FAST_C | 65 if (MP_HAS(S_MP_EXPTMOD_FAST) && (MP_IS_ODD(P) || (dr != 0))) { |
89 if ((mp_isodd(P) == MP_YES) || (dr != 0)) { | 66 return s_mp_exptmod_fast(G, X, P, Y, dr); |
90 return mp_exptmod_fast(G, X, P, Y, dr); | 67 } else if (MP_HAS(S_MP_EXPTMOD)) { |
91 } else { | |
92 #endif | |
93 #ifdef BN_S_MP_EXPTMOD_C | |
94 /* otherwise use the generic Barrett reduction technique */ | 68 /* otherwise use the generic Barrett reduction technique */ |
95 return s_mp_exptmod(G, X, P, Y, 0); | 69 return s_mp_exptmod(G, X, P, Y, 0); |
96 #else | 70 } else { |
97 /* no exptmod for evens */ | 71 /* no exptmod for evens */ |
98 return MP_VAL; | 72 return MP_VAL; |
99 #endif | |
100 #ifdef BN_MP_EXPTMOD_FAST_C | |
101 } | 73 } |
102 #endif | |
103 } | 74 } |
104 | 75 |
105 #endif | 76 #endif |
106 | |
107 /* ref: HEAD -> master, tag: v1.1.0 */ | |
108 /* git commit: 08549ad6bc8b0cede0b357a9c341c5c6473a9c55 */ | |
109 /* commit time: 2019-01-28 20:32:32 +0100 */ |