github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/mpn/generic/powm.c (about) 1 /* mpn_powm -- Compute R = U^E mod M. 2 3 Contributed to the GNU project by Torbjorn Granlund. 4 5 THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY 6 SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST 7 GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE. 8 9 Copyright 2007-2012 Free Software Foundation, Inc. 10 11 This file is part of the GNU MP Library. 12 13 The GNU MP Library is free software; you can redistribute it and/or modify 14 it under the terms of either: 15 16 * the GNU Lesser General Public License as published by the Free 17 Software Foundation; either version 3 of the License, or (at your 18 option) any later version. 19 20 or 21 22 * the GNU General Public License as published by the Free Software 23 Foundation; either version 2 of the License, or (at your option) any 24 later version. 25 26 or both in parallel, as here. 27 28 The GNU MP Library is distributed in the hope that it will be useful, but 29 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 30 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 31 for more details. 32 33 You should have received copies of the GNU General Public License and the 34 GNU Lesser General Public License along with the GNU MP Library. If not, 35 see https://www.gnu.org/licenses/. */ 36 37 38 /* 39 BASIC ALGORITHM, Compute U^E mod M, where M < B^n is odd. 40 41 1. W <- U 42 43 2. T <- (B^n * U) mod M Convert to REDC form 44 45 3. Compute table U^1, U^3, U^5... of E-dependent size 46 47 4. While there are more bits in E 48 W <- power left-to-right base-k 49 50 51 TODO: 52 53 * Make getbits a macro, thereby allowing it to update the index operand. 54 That will simplify the code using getbits. (Perhaps make getbits' sibling 55 getbit then have similar form, for symmetry.) 56 57 * Write an itch function. Or perhaps get rid of tp parameter since the huge 58 pp area is allocated locally anyway? 59 60 * Choose window size without looping. (Superoptimize or think(tm).) 61 62 * Handle small bases with initial, reduction-free exponentiation. 63 64 * Call new division functions, not mpn_tdiv_qr. 65 66 * Consider special code for one-limb M. 67 68 * How should we handle the redc1/redc2/redc_n choice? 69 - redc1: T(binvert_1limb) + e * (n) * (T(mullo-1x1) + n*T(addmul_1)) 70 - redc2: T(binvert_2limbs) + e * (n/2) * (T(mullo-2x2) + n*T(addmul_2)) 71 - redc_n: T(binvert_nlimbs) + e * (T(mullo-nxn) + T(M(n))) 72 This disregards the addmul_N constant term, but we could think of 73 that as part of the respective mullo. 74 75 * When U (the base) is small, we should start the exponentiation with plain 76 operations, then convert that partial result to REDC form. 77 78 * When U is just one limb, should it be handled without the k-ary tricks? 79 We could keep a factor of B^n in W, but use U' = BU as base. After 80 multiplying by this (pseudo two-limb) number, we need to multiply by 1/B 81 mod M. 82 */ 83 84 #include "gmp.h" 85 #include "gmp-impl.h" 86 #include "longlong.h" 87 88 #undef MPN_REDC_1 89 #define MPN_REDC_1(rp, up, mp, n, invm) \ 90 do { \ 91 mp_limb_t cy; \ 92 cy = mpn_redc_1 (rp, up, mp, n, invm); \ 93 if (cy != 0) \ 94 mpn_sub_n (rp, rp, mp, n); \ 95 } while (0) 96 97 #undef MPN_REDC_2 98 #define MPN_REDC_2(rp, up, mp, n, mip) \ 99 do { \ 100 mp_limb_t cy; \ 101 cy = mpn_redc_2 (rp, up, mp, n, mip); \ 102 if (cy != 0) \ 103 mpn_sub_n (rp, rp, mp, n); \ 104 } while (0) 105 106 #if HAVE_NATIVE_mpn_addmul_2 || HAVE_NATIVE_mpn_redc_2 107 #define WANT_REDC_2 1 108 #endif 109 110 #define getbit(p,bi) \ 111 ((p[(bi - 1) / GMP_LIMB_BITS] >> (bi - 1) % GMP_LIMB_BITS) & 1) 112 113 static inline mp_limb_t 114 getbits (const mp_limb_t *p, mp_bitcnt_t bi, int nbits) 115 { 116 int nbits_in_r; 117 mp_limb_t r; 118 mp_size_t i; 119 120 if (bi < nbits) 121 { 122 return p[0] & (((mp_limb_t) 1 << bi) - 1); 123 } 124 else 125 { 126 bi -= nbits; /* bit index of low bit to extract */ 127 i = bi / GMP_NUMB_BITS; /* word index of low bit to extract */ 128 bi %= GMP_NUMB_BITS; /* bit index in low word */ 129 r = p[i] >> bi; /* extract (low) bits */ 130 nbits_in_r = GMP_NUMB_BITS - bi; /* number of bits now in r */ 131 if (nbits_in_r < nbits) /* did we get enough bits? */ 132 r += p[i + 1] << nbits_in_r; /* prepend bits from higher word */ 133 return r & (((mp_limb_t ) 1 << nbits) - 1); 134 } 135 } 136 137 static inline int 138 win_size (mp_bitcnt_t eb) 139 { 140 int k; 141 static mp_bitcnt_t x[] = {0,7,25,81,241,673,1793,4609,11521,28161,~(mp_bitcnt_t)0}; 142 for (k = 1; eb > x[k]; k++) 143 ; 144 return k; 145 } 146 147 /* Convert U to REDC form, U_r = B^n * U mod M */ 148 static void 149 redcify (mp_ptr rp, mp_srcptr up, mp_size_t un, mp_srcptr mp, mp_size_t n) 150 { 151 mp_ptr tp, qp; 152 TMP_DECL; 153 TMP_MARK; 154 155 TMP_ALLOC_LIMBS_2 (tp, un + n, qp, un + 1); 156 157 MPN_ZERO (tp, n); 158 MPN_COPY (tp + n, up, un); 159 mpn_tdiv_qr (qp, rp, 0L, tp, un + n, mp, n); 160 TMP_FREE; 161 } 162 163 /* rp[n-1..0] = bp[bn-1..0] ^ ep[en-1..0] mod mp[n-1..0] 164 Requires that mp[n-1..0] is odd. 165 Requires that ep[en-1..0] is > 1. 166 Uses scratch space at tp of MAX(mpn_binvert_itch(n),2n) limbs. */ 167 void 168 mpn_powm (mp_ptr rp, mp_srcptr bp, mp_size_t bn, 169 mp_srcptr ep, mp_size_t en, 170 mp_srcptr mp, mp_size_t n, mp_ptr tp) 171 { 172 mp_limb_t ip[2], *mip; 173 int cnt; 174 mp_bitcnt_t ebi; 175 int windowsize, this_windowsize; 176 mp_limb_t expbits; 177 mp_ptr pp, this_pp; 178 long i; 179 TMP_DECL; 180 181 ASSERT (en > 1 || (en == 1 && ep[0] > 1)); 182 ASSERT (n >= 1 && ((mp[0] & 1) != 0)); 183 184 TMP_MARK; 185 186 MPN_SIZEINBASE_2EXP(ebi, ep, en, 1); 187 188 #if 0 189 if (bn < n) 190 { 191 /* Do the first few exponent bits without mod reductions, 192 until the result is greater than the mod argument. */ 193 for (;;) 194 { 195 mpn_sqr (tp, this_pp, tn); 196 tn = tn * 2 - 1, tn += tp[tn] != 0; 197 if (getbit (ep, ebi) != 0) 198 mpn_mul (..., tp, tn, bp, bn); 199 ebi--; 200 } 201 } 202 #endif 203 204 windowsize = win_size (ebi); 205 206 #if WANT_REDC_2 207 if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_2_THRESHOLD)) 208 { 209 mip = ip; 210 binvert_limb (mip[0], mp[0]); 211 mip[0] = -mip[0]; 212 } 213 else if (BELOW_THRESHOLD (n, REDC_2_TO_REDC_N_THRESHOLD)) 214 { 215 mip = ip; 216 mpn_binvert (mip, mp, 2, tp); 217 mip[0] = -mip[0]; mip[1] = ~mip[1]; 218 } 219 #else 220 if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_N_THRESHOLD)) 221 { 222 mip = ip; 223 binvert_limb (mip[0], mp[0]); 224 mip[0] = -mip[0]; 225 } 226 #endif 227 else 228 { 229 mip = TMP_ALLOC_LIMBS (n); 230 mpn_binvert (mip, mp, n, tp); 231 } 232 233 pp = TMP_ALLOC_LIMBS (n << (windowsize - 1)); 234 235 this_pp = pp; 236 redcify (this_pp, bp, bn, mp, n); 237 238 /* Store b^2 at rp. */ 239 mpn_sqr (tp, this_pp, n); 240 #if WANT_REDC_2 241 if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_2_THRESHOLD)) 242 MPN_REDC_1 (rp, tp, mp, n, mip[0]); 243 else if (BELOW_THRESHOLD (n, REDC_2_TO_REDC_N_THRESHOLD)) 244 MPN_REDC_2 (rp, tp, mp, n, mip); 245 #else 246 if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_N_THRESHOLD)) 247 MPN_REDC_1 (rp, tp, mp, n, mip[0]); 248 #endif 249 else 250 mpn_redc_n (rp, tp, mp, n, mip); 251 252 /* Precompute odd powers of b and put them in the temporary area at pp. */ 253 for (i = (1 << (windowsize - 1)) - 1; i > 0; i--) 254 { 255 mpn_mul_n (tp, this_pp, rp, n); 256 this_pp += n; 257 #if WANT_REDC_2 258 if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_2_THRESHOLD)) 259 MPN_REDC_1 (this_pp, tp, mp, n, mip[0]); 260 else if (BELOW_THRESHOLD (n, REDC_2_TO_REDC_N_THRESHOLD)) 261 MPN_REDC_2 (this_pp, tp, mp, n, mip); 262 #else 263 if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_N_THRESHOLD)) 264 MPN_REDC_1 (this_pp, tp, mp, n, mip[0]); 265 #endif 266 else 267 mpn_redc_n (this_pp, tp, mp, n, mip); 268 } 269 270 expbits = getbits (ep, ebi, windowsize); 271 if (ebi < windowsize) 272 ebi = 0; 273 else 274 ebi -= windowsize; 275 276 count_trailing_zeros (cnt, expbits); 277 ebi += cnt; 278 expbits >>= cnt; 279 280 MPN_COPY (rp, pp + n * (expbits >> 1), n); 281 282 #define INNERLOOP \ 283 while (ebi != 0) \ 284 { \ 285 while (getbit (ep, ebi) == 0) \ 286 { \ 287 MPN_SQR (tp, rp, n); \ 288 MPN_REDUCE (rp, tp, mp, n, mip); \ 289 ebi--; \ 290 if (ebi == 0) \ 291 goto done; \ 292 } \ 293 \ 294 /* The next bit of the exponent is 1. Now extract the largest \ 295 block of bits <= windowsize, and such that the least \ 296 significant bit is 1. */ \ 297 \ 298 expbits = getbits (ep, ebi, windowsize); \ 299 this_windowsize = windowsize; \ 300 if (ebi < windowsize) \ 301 { \ 302 this_windowsize -= windowsize - ebi; \ 303 ebi = 0; \ 304 } \ 305 else \ 306 ebi -= windowsize; \ 307 \ 308 count_trailing_zeros (cnt, expbits); \ 309 this_windowsize -= cnt; \ 310 ebi += cnt; \ 311 expbits >>= cnt; \ 312 \ 313 do \ 314 { \ 315 MPN_SQR (tp, rp, n); \ 316 MPN_REDUCE (rp, tp, mp, n, mip); \ 317 this_windowsize--; \ 318 } \ 319 while (this_windowsize != 0); \ 320 \ 321 MPN_MUL_N (tp, rp, pp + n * (expbits >> 1), n); \ 322 MPN_REDUCE (rp, tp, mp, n, mip); \ 323 } 324 325 326 #if WANT_REDC_2 327 if (REDC_1_TO_REDC_2_THRESHOLD < MUL_TOOM22_THRESHOLD) 328 { 329 if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_2_THRESHOLD)) 330 { 331 if (REDC_1_TO_REDC_2_THRESHOLD < SQR_BASECASE_THRESHOLD 332 || BELOW_THRESHOLD (n, SQR_BASECASE_THRESHOLD)) 333 { 334 #undef MPN_MUL_N 335 #undef MPN_SQR 336 #undef MPN_REDUCE 337 #define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n) 338 #define MPN_SQR(r,a,n) mpn_mul_basecase (r,a,n,a,n) 339 #define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_1 (rp, tp, mp, n, mip[0]) 340 INNERLOOP; 341 } 342 else 343 { 344 #undef MPN_MUL_N 345 #undef MPN_SQR 346 #undef MPN_REDUCE 347 #define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n) 348 #define MPN_SQR(r,a,n) mpn_sqr_basecase (r,a,n) 349 #define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_1 (rp, tp, mp, n, mip[0]) 350 INNERLOOP; 351 } 352 } 353 else if (BELOW_THRESHOLD (n, MUL_TOOM22_THRESHOLD)) 354 { 355 if (MUL_TOOM22_THRESHOLD < SQR_BASECASE_THRESHOLD 356 || BELOW_THRESHOLD (n, SQR_BASECASE_THRESHOLD)) 357 { 358 #undef MPN_MUL_N 359 #undef MPN_SQR 360 #undef MPN_REDUCE 361 #define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n) 362 #define MPN_SQR(r,a,n) mpn_mul_basecase (r,a,n,a,n) 363 #define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_2 (rp, tp, mp, n, mip) 364 INNERLOOP; 365 } 366 else 367 { 368 #undef MPN_MUL_N 369 #undef MPN_SQR 370 #undef MPN_REDUCE 371 #define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n) 372 #define MPN_SQR(r,a,n) mpn_sqr_basecase (r,a,n) 373 #define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_2 (rp, tp, mp, n, mip) 374 INNERLOOP; 375 } 376 } 377 else if (BELOW_THRESHOLD (n, REDC_2_TO_REDC_N_THRESHOLD)) 378 { 379 #undef MPN_MUL_N 380 #undef MPN_SQR 381 #undef MPN_REDUCE 382 #define MPN_MUL_N(r,a,b,n) mpn_mul_n (r,a,b,n) 383 #define MPN_SQR(r,a,n) mpn_sqr (r,a,n) 384 #define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_2 (rp, tp, mp, n, mip) 385 INNERLOOP; 386 } 387 else 388 { 389 #undef MPN_MUL_N 390 #undef MPN_SQR 391 #undef MPN_REDUCE 392 #define MPN_MUL_N(r,a,b,n) mpn_mul_n (r,a,b,n) 393 #define MPN_SQR(r,a,n) mpn_sqr (r,a,n) 394 #define MPN_REDUCE(rp,tp,mp,n,mip) mpn_redc_n (rp, tp, mp, n, mip) 395 INNERLOOP; 396 } 397 } 398 else 399 { 400 if (BELOW_THRESHOLD (n, MUL_TOOM22_THRESHOLD)) 401 { 402 if (MUL_TOOM22_THRESHOLD < SQR_BASECASE_THRESHOLD 403 || BELOW_THRESHOLD (n, SQR_BASECASE_THRESHOLD)) 404 { 405 #undef MPN_MUL_N 406 #undef MPN_SQR 407 #undef MPN_REDUCE 408 #define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n) 409 #define MPN_SQR(r,a,n) mpn_mul_basecase (r,a,n,a,n) 410 #define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_1 (rp, tp, mp, n, mip[0]) 411 INNERLOOP; 412 } 413 else 414 { 415 #undef MPN_MUL_N 416 #undef MPN_SQR 417 #undef MPN_REDUCE 418 #define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n) 419 #define MPN_SQR(r,a,n) mpn_sqr_basecase (r,a,n) 420 #define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_1 (rp, tp, mp, n, mip[0]) 421 INNERLOOP; 422 } 423 } 424 else if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_2_THRESHOLD)) 425 { 426 #undef MPN_MUL_N 427 #undef MPN_SQR 428 #undef MPN_REDUCE 429 #define MPN_MUL_N(r,a,b,n) mpn_mul_n (r,a,b,n) 430 #define MPN_SQR(r,a,n) mpn_sqr (r,a,n) 431 #define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_1 (rp, tp, mp, n, mip[0]) 432 INNERLOOP; 433 } 434 else if (BELOW_THRESHOLD (n, REDC_2_TO_REDC_N_THRESHOLD)) 435 { 436 #undef MPN_MUL_N 437 #undef MPN_SQR 438 #undef MPN_REDUCE 439 #define MPN_MUL_N(r,a,b,n) mpn_mul_n (r,a,b,n) 440 #define MPN_SQR(r,a,n) mpn_sqr (r,a,n) 441 #define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_2 (rp, tp, mp, n, mip) 442 INNERLOOP; 443 } 444 else 445 { 446 #undef MPN_MUL_N 447 #undef MPN_SQR 448 #undef MPN_REDUCE 449 #define MPN_MUL_N(r,a,b,n) mpn_mul_n (r,a,b,n) 450 #define MPN_SQR(r,a,n) mpn_sqr (r,a,n) 451 #define MPN_REDUCE(rp,tp,mp,n,mip) mpn_redc_n (rp, tp, mp, n, mip) 452 INNERLOOP; 453 } 454 } 455 456 #else /* WANT_REDC_2 */ 457 458 if (REDC_1_TO_REDC_N_THRESHOLD < MUL_TOOM22_THRESHOLD) 459 { 460 if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_N_THRESHOLD)) 461 { 462 if (REDC_1_TO_REDC_N_THRESHOLD < SQR_BASECASE_THRESHOLD 463 || BELOW_THRESHOLD (n, SQR_BASECASE_THRESHOLD)) 464 { 465 #undef MPN_MUL_N 466 #undef MPN_SQR 467 #undef MPN_REDUCE 468 #define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n) 469 #define MPN_SQR(r,a,n) mpn_mul_basecase (r,a,n,a,n) 470 #define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_1 (rp, tp, mp, n, mip[0]) 471 INNERLOOP; 472 } 473 else 474 { 475 #undef MPN_MUL_N 476 #undef MPN_SQR 477 #undef MPN_REDUCE 478 #define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n) 479 #define MPN_SQR(r,a,n) mpn_sqr_basecase (r,a,n) 480 #define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_1 (rp, tp, mp, n, mip[0]) 481 INNERLOOP; 482 } 483 } 484 else if (BELOW_THRESHOLD (n, MUL_TOOM22_THRESHOLD)) 485 { 486 if (MUL_TOOM22_THRESHOLD < SQR_BASECASE_THRESHOLD 487 || BELOW_THRESHOLD (n, SQR_BASECASE_THRESHOLD)) 488 { 489 #undef MPN_MUL_N 490 #undef MPN_SQR 491 #undef MPN_REDUCE 492 #define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n) 493 #define MPN_SQR(r,a,n) mpn_mul_basecase (r,a,n,a,n) 494 #define MPN_REDUCE(rp,tp,mp,n,mip) mpn_redc_n (rp, tp, mp, n, mip) 495 INNERLOOP; 496 } 497 else 498 { 499 #undef MPN_MUL_N 500 #undef MPN_SQR 501 #undef MPN_REDUCE 502 #define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n) 503 #define MPN_SQR(r,a,n) mpn_sqr_basecase (r,a,n) 504 #define MPN_REDUCE(rp,tp,mp,n,mip) mpn_redc_n (rp, tp, mp, n, mip) 505 INNERLOOP; 506 } 507 } 508 else 509 { 510 #undef MPN_MUL_N 511 #undef MPN_SQR 512 #undef MPN_REDUCE 513 #define MPN_MUL_N(r,a,b,n) mpn_mul_n (r,a,b,n) 514 #define MPN_SQR(r,a,n) mpn_sqr (r,a,n) 515 #define MPN_REDUCE(rp,tp,mp,n,mip) mpn_redc_n (rp, tp, mp, n, mip) 516 INNERLOOP; 517 } 518 } 519 else 520 { 521 if (BELOW_THRESHOLD (n, MUL_TOOM22_THRESHOLD)) 522 { 523 if (MUL_TOOM22_THRESHOLD < SQR_BASECASE_THRESHOLD 524 || BELOW_THRESHOLD (n, SQR_BASECASE_THRESHOLD)) 525 { 526 #undef MPN_MUL_N 527 #undef MPN_SQR 528 #undef MPN_REDUCE 529 #define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n) 530 #define MPN_SQR(r,a,n) mpn_mul_basecase (r,a,n,a,n) 531 #define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_1 (rp, tp, mp, n, mip[0]) 532 INNERLOOP; 533 } 534 else 535 { 536 #undef MPN_MUL_N 537 #undef MPN_SQR 538 #undef MPN_REDUCE 539 #define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n) 540 #define MPN_SQR(r,a,n) mpn_sqr_basecase (r,a,n) 541 #define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_1 (rp, tp, mp, n, mip[0]) 542 INNERLOOP; 543 } 544 } 545 else if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_N_THRESHOLD)) 546 { 547 #undef MPN_MUL_N 548 #undef MPN_SQR 549 #undef MPN_REDUCE 550 #define MPN_MUL_N(r,a,b,n) mpn_mul_n (r,a,b,n) 551 #define MPN_SQR(r,a,n) mpn_sqr (r,a,n) 552 #define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_1 (rp, tp, mp, n, mip[0]) 553 INNERLOOP; 554 } 555 else 556 { 557 #undef MPN_MUL_N 558 #undef MPN_SQR 559 #undef MPN_REDUCE 560 #define MPN_MUL_N(r,a,b,n) mpn_mul_n (r,a,b,n) 561 #define MPN_SQR(r,a,n) mpn_sqr (r,a,n) 562 #define MPN_REDUCE(rp,tp,mp,n,mip) mpn_redc_n (rp, tp, mp, n, mip) 563 INNERLOOP; 564 } 565 } 566 #endif /* WANT_REDC_2 */ 567 568 done: 569 570 MPN_COPY (tp, rp, n); 571 MPN_ZERO (tp + n, n); 572 573 #if WANT_REDC_2 574 if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_2_THRESHOLD)) 575 MPN_REDC_1 (rp, tp, mp, n, mip[0]); 576 else if (BELOW_THRESHOLD (n, REDC_2_TO_REDC_N_THRESHOLD)) 577 MPN_REDC_2 (rp, tp, mp, n, mip); 578 #else 579 if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_N_THRESHOLD)) 580 MPN_REDC_1 (rp, tp, mp, n, mip[0]); 581 #endif 582 else 583 mpn_redc_n (rp, tp, mp, n, mip); 584 585 if (mpn_cmp (rp, mp, n) >= 0) 586 mpn_sub_n (rp, rp, mp, n); 587 588 TMP_FREE; 589 }