comparison libtommath/bn_mp_prime_is_prime.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 a36e545fb43d
children
comparison
equal deleted inserted replaced
1691:2d3745d58843 1692:1051e4eea25a
1 #include "tommath_private.h" 1 #include "tommath_private.h"
2 #ifdef BN_MP_PRIME_IS_PRIME_C 2 #ifdef BN_MP_PRIME_IS_PRIME_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 5
15 /* portable integer log of two with small footprint */ 6 /* portable integer log of two with small footprint */
16 static unsigned int s_floor_ilog2(int value) 7 static unsigned int s_floor_ilog2(int value)
17 { 8 {
18 unsigned int r = 0; 9 unsigned int r = 0;
21 } 12 }
22 return r; 13 return r;
23 } 14 }
24 15
25 16
26 int mp_prime_is_prime(const mp_int *a, int t, int *result) 17 mp_err mp_prime_is_prime(const mp_int *a, int t, mp_bool *result)
27 { 18 {
28 mp_int b; 19 mp_int b;
29 int ix, err, res, p_max = 0, size_a, len; 20 int ix, p_max = 0, size_a, len;
21 mp_bool res;
22 mp_err err;
30 unsigned int fips_rand, mask; 23 unsigned int fips_rand, mask;
31 24
32 /* default to no */ 25 /* default to no */
33 *result = MP_NO; 26 *result = MP_NO;
34
35 /* valid value of t? */
36 if (t > PRIME_SIZE) {
37 return MP_VAL;
38 }
39 27
40 /* Some shortcuts */ 28 /* Some shortcuts */
41 /* N > 3 */ 29 /* N > 3 */
42 if (a->used == 1) { 30 if (a->used == 1) {
43 if ((a->dp[0] == 0u) || (a->dp[0] == 1u)) { 31 if ((a->dp[0] == 0u) || (a->dp[0] == 1u)) {
44 *result = 0; 32 *result = MP_NO;
45 return MP_OKAY; 33 return MP_OKAY;
46 } 34 }
47 if (a->dp[0] == 2u) { 35 if (a->dp[0] == 2u) {
48 *result = 1; 36 *result = MP_YES;
49 return MP_OKAY; 37 return MP_OKAY;
50 } 38 }
51 } 39 }
52 40
53 /* N must be odd */ 41 /* N must be odd */
54 if (mp_iseven(a) == MP_YES) { 42 if (MP_IS_EVEN(a)) {
55 return MP_OKAY; 43 return MP_OKAY;
56 } 44 }
57 /* N is not a perfect square: floor(sqrt(N))^2 != N */ 45 /* N is not a perfect square: floor(sqrt(N))^2 != N */
58 if ((err = mp_is_square(a, &res)) != MP_OKAY) { 46 if ((err = mp_is_square(a, &res)) != MP_OKAY) {
59 return err; 47 return err;
60 } 48 }
61 if (res != 0) { 49 if (res != MP_NO) {
62 return MP_OKAY; 50 return MP_OKAY;
63 } 51 }
64 52
65 /* is the input equal to one of the primes in the table? */ 53 /* is the input equal to one of the primes in the table? */
66 for (ix = 0; ix < PRIME_SIZE; ix++) { 54 for (ix = 0; ix < PRIVATE_MP_PRIME_TAB_SIZE; ix++) {
67 if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) { 55 if (mp_cmp_d(a, s_mp_prime_tab[ix]) == MP_EQ) {
68 *result = MP_YES; 56 *result = MP_YES;
69 return MP_OKAY; 57 return MP_OKAY;
70 } 58 }
71 } 59 }
72 #ifdef MP_8BIT 60 #ifdef MP_8BIT
73 /* The search in the loop above was exhaustive in this case */ 61 /* The search in the loop above was exhaustive in this case */
74 if ((a->used == 1) && (PRIME_SIZE >= 31)) { 62 if ((a->used == 1) && (PRIVATE_MP_PRIME_TAB_SIZE >= 31)) {
75 return MP_OKAY; 63 return MP_OKAY;
76 } 64 }
77 #endif 65 #endif
78 66
79 /* first perform trial division */ 67 /* first perform trial division */
80 if ((err = mp_prime_is_divisible(a, &res)) != MP_OKAY) { 68 if ((err = s_mp_prime_is_divisible(a, &res)) != MP_OKAY) {
81 return err; 69 return err;
82 } 70 }
83 71
84 /* return if it was trivially divisible */ 72 /* return if it was trivially divisible */
85 if (res == MP_YES) { 73 if (res == MP_YES) {
112 goto LBL_B; 100 goto LBL_B;
113 } 101 }
114 102
115 /* 103 /*
116 * Both, the Frobenius-Underwood test and the the Lucas-Selfridge test are quite 104 * Both, the Frobenius-Underwood test and the the Lucas-Selfridge test are quite
117 * slow so if speed is an issue, define LTM_USE_FIPS_ONLY to use M-R tests with 105 * slow so if speed is an issue, define LTM_USE_ONLY_MR to use M-R tests with
118 * bases 2, 3 and t random bases. 106 * bases 2, 3 and t random bases.
119 */ 107 */
120 #ifndef LTM_USE_FIPS_ONLY 108 #ifndef LTM_USE_ONLY_MR
121 if (t >= 0) { 109 if (t >= 0) {
122 /* 110 /*
123 * Use a Frobenius-Underwood test instead of the Lucas-Selfridge test for 111 * Use a Frobenius-Underwood test instead of the Lucas-Selfridge test for
124 * MP_8BIT (It is unknown if the Lucas-Selfridge test works with 16-bit 112 * MP_8BIT (It is unknown if the Lucas-Selfridge test works with 16-bit
125 * integers but the necesssary analysis is on the todo-list). 113 * integers but the necesssary analysis is on the todo-list).
147 if (t == 0) { 135 if (t == 0) {
148 t = 1; 136 t = 1;
149 } 137 }
150 138
151 /* 139 /*
152 abs(t) extra rounds of M-R to extend the range of primes it can find if t < 0.
153 Only recommended if the input range is known to be < 3317044064679887385961981 140 Only recommended if the input range is known to be < 3317044064679887385961981
154 141
155 It uses the bases for a deterministic M-R test if input < 3317044064679887385961981 142 It uses the bases necessary for a deterministic M-R test if the input is
143 smaller than 3317044064679887385961981
156 The caller has to check the size. 144 The caller has to check the size.
157 145 TODO: can be made a bit finer grained but comparing is not free.
158 Not for cryptographic use because with known bases strong M-R pseudoprimes can
159 be constructed. Use at least one M-R test with a random base (t >= 1).
160
161 The 1119 bit large number
162
163 80383745745363949125707961434194210813883768828755814583748891752229742737653\
164 33652186502336163960045457915042023603208766569966760987284043965408232928738\
165 79185086916685732826776177102938969773947016708230428687109997439976544144845\
166 34115587245063340927902227529622941498423068816854043264575340183297861112989\
167 60644845216191652872597534901
168
169 has been constructed by F. Arnault (F. Arnault, "Rabin-Miller primality test:
170 composite numbers which pass it.", Mathematics of Computation, 1995, 64. Jg.,
171 Nr. 209, S. 355-361), is a semiprime with the two factors
172
173 40095821663949960541830645208454685300518816604113250877450620473800321707011\
174 96242716223191597219733582163165085358166969145233813917169287527980445796800\
175 452592031836601
176
177 20047910831974980270915322604227342650259408302056625438725310236900160853505\
178 98121358111595798609866791081582542679083484572616906958584643763990222898400\
179 226296015918301
180
181 and it is a strong pseudoprime to all forty-six prime M-R bases up to 200
182
183 It does not fail the strong Bailley-PSP test as implemented here, it is just
184 given as an example, if not the reason to use the BPSW-test instead of M-R-tests
185 with a sequence of primes 2...n.
186
187 */ 146 */
188 if (t < 0) { 147 if (t < 0) {
189 t = -t;
190 /* 148 /*
191 Sorenson, Jonathan; Webster, Jonathan (2015). 149 Sorenson, Jonathan; Webster, Jonathan (2015).
192 "Strong Pseudoprimes to Twelve Prime Bases". 150 "Strong Pseudoprimes to Twelve Prime Bases".
193 */ 151 */
194 /* 0x437ae92817f9fc85b7e5 = 318665857834031151167461 */ 152 /* 0x437ae92817f9fc85b7e5 = 318665857834031151167461 */
210 err = MP_VAL; 168 err = MP_VAL;
211 goto LBL_B; 169 goto LBL_B;
212 } 170 }
213 } 171 }
214 172
215 /* for compatibility with the current API (well, compatible within a sign's width) */
216 if (p_max < t) {
217 p_max = t;
218 }
219
220 if (p_max > PRIME_SIZE) {
221 err = MP_VAL;
222 goto LBL_B;
223 }
224 /* we did bases 2 and 3 already, skip them */ 173 /* we did bases 2 and 3 already, skip them */
225 for (ix = 2; ix < p_max; ix++) { 174 for (ix = 2; ix < p_max; ix++) {
226 mp_set(&b, ltm_prime_tab[ix]); 175 mp_set(&b, s_mp_prime_tab[ix]);
227 if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) { 176 if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) {
228 goto LBL_B; 177 goto LBL_B;
229 } 178 }
230 if (res == MP_NO) { 179 if (res == MP_NO) {
231 goto LBL_B; 180 goto LBL_B;
294 #ifdef MP_8BIT 243 #ifdef MP_8BIT
295 /* 244 /*
296 * One 8-bit digit is too small, so concatenate two if the size of 245 * One 8-bit digit is too small, so concatenate two if the size of
297 * unsigned int allows for it. 246 * unsigned int allows for it.
298 */ 247 */
299 if (((sizeof(unsigned int) * CHAR_BIT)/2) >= (sizeof(mp_digit) * CHAR_BIT)) { 248 if ((MP_SIZEOF_BITS(unsigned int)/2) >= MP_SIZEOF_BITS(mp_digit)) {
300 if ((err = mp_rand(&b, 1)) != MP_OKAY) { 249 if ((err = mp_rand(&b, 1)) != MP_OKAY) {
301 goto LBL_B; 250 goto LBL_B;
302 } 251 }
303 fips_rand <<= sizeof(mp_digit) * CHAR_BIT; 252 fips_rand <<= MP_SIZEOF_BITS(mp_digit);
304 fips_rand |= (unsigned int) b.dp[0]; 253 fips_rand |= (unsigned int) b.dp[0];
305 fips_rand &= mask; 254 fips_rand &= mask;
306 } 255 }
307 #endif 256 #endif
308 if (fips_rand > (unsigned int)(INT_MAX - DIGIT_BIT)) { 257 if (fips_rand > (unsigned int)(INT_MAX - MP_DIGIT_BIT)) {
309 len = INT_MAX / DIGIT_BIT; 258 len = INT_MAX / MP_DIGIT_BIT;
310 } else { 259 } else {
311 len = (((int)fips_rand + DIGIT_BIT) / DIGIT_BIT); 260 len = (((int)fips_rand + MP_DIGIT_BIT) / MP_DIGIT_BIT);
312 } 261 }
313 /* Unlikely. */ 262 /* Unlikely. */
314 if (len < 0) { 263 if (len < 0) {
315 ix--; 264 ix--;
316 continue; 265 continue;
361 mp_clear(&b); 310 mp_clear(&b);
362 return err; 311 return err;
363 } 312 }
364 313
365 #endif 314 #endif
366
367 /* ref: HEAD -> master, tag: v1.1.0 */
368 /* git commit: 08549ad6bc8b0cede0b357a9c341c5c6473a9c55 */
369 /* commit time: 2019-01-28 20:32:32 +0100 */