1 1.1 mrg /* jacobi_2.c 2 1.1 mrg 3 1.1 mrg THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY 4 1.1 mrg SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST 5 1.1 mrg GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE. 6 1.1 mrg 7 1.1.1.2 mrg Copyright 1996, 1998, 2000-2004, 2008, 2010 Free Software Foundation, Inc. 8 1.1 mrg 9 1.1 mrg This file is part of the GNU MP Library. 10 1.1 mrg 11 1.1 mrg The GNU MP Library is free software; you can redistribute it and/or modify 12 1.1.1.2 mrg it under the terms of either: 13 1.1.1.2 mrg 14 1.1.1.2 mrg * the GNU Lesser General Public License as published by the Free 15 1.1.1.2 mrg Software Foundation; either version 3 of the License, or (at your 16 1.1.1.2 mrg option) any later version. 17 1.1.1.2 mrg 18 1.1.1.2 mrg or 19 1.1.1.2 mrg 20 1.1.1.2 mrg * the GNU General Public License as published by the Free Software 21 1.1.1.2 mrg Foundation; either version 2 of the License, or (at your option) any 22 1.1.1.2 mrg later version. 23 1.1.1.2 mrg 24 1.1.1.2 mrg or both in parallel, as here. 25 1.1 mrg 26 1.1 mrg The GNU MP Library is distributed in the hope that it will be useful, but 27 1.1 mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 28 1.1.1.2 mrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 29 1.1.1.2 mrg for more details. 30 1.1 mrg 31 1.1.1.2 mrg You should have received copies of the GNU General Public License and the 32 1.1.1.2 mrg GNU Lesser General Public License along with the GNU MP Library. If not, 33 1.1.1.2 mrg see https://www.gnu.org/licenses/. */ 34 1.1 mrg 35 1.1 mrg #include "gmp-impl.h" 36 1.1 mrg #include "longlong.h" 37 1.1 mrg 38 1.1 mrg #ifndef JACOBI_2_METHOD 39 1.1 mrg #define JACOBI_2_METHOD 2 40 1.1 mrg #endif 41 1.1 mrg 42 1.1 mrg /* Computes (a / b) where b is odd, and a and b are otherwise arbitrary 43 1.1 mrg two-limb numbers. */ 44 1.1 mrg #if JACOBI_2_METHOD == 1 45 1.1 mrg int 46 1.1 mrg mpn_jacobi_2 (mp_srcptr ap, mp_srcptr bp, unsigned bit) 47 1.1 mrg { 48 1.1 mrg mp_limb_t ah, al, bh, bl; 49 1.1 mrg int c; 50 1.1 mrg 51 1.1 mrg al = ap[0]; 52 1.1 mrg ah = ap[1]; 53 1.1 mrg bl = bp[0]; 54 1.1 mrg bh = bp[1]; 55 1.1 mrg 56 1.1 mrg ASSERT (bl & 1); 57 1.1 mrg 58 1.1 mrg bl = ((bh << (GMP_NUMB_BITS - 1)) & GMP_NUMB_MASK) | (bl >> 1); 59 1.1 mrg bh >>= 1; 60 1.1 mrg 61 1.1 mrg if ( (bh | bl) == 0) 62 1.1 mrg return 1 - 2*(bit & 1); 63 1.1 mrg 64 1.1 mrg if ( (ah | al) == 0) 65 1.1 mrg return 0; 66 1.1 mrg 67 1.1 mrg if (al == 0) 68 1.1 mrg { 69 1.1 mrg al = ah; 70 1.1 mrg ah = 0; 71 1.1 mrg bit ^= GMP_NUMB_BITS & (bl ^ (bl >> 1)); 72 1.1 mrg } 73 1.1 mrg count_trailing_zeros (c, al); 74 1.1 mrg bit ^= c & (bl ^ (bl >> 1)); 75 1.1 mrg 76 1.1 mrg c++; 77 1.1 mrg if (UNLIKELY (c == GMP_NUMB_BITS)) 78 1.1 mrg { 79 1.1 mrg al = ah; 80 1.1 mrg ah = 0; 81 1.1 mrg } 82 1.1 mrg else 83 1.1 mrg { 84 1.1 mrg al = ((ah << (GMP_NUMB_BITS - c)) & GMP_NUMB_MASK) | (al >> c); 85 1.1 mrg ah >>= c; 86 1.1 mrg } 87 1.1 mrg while ( (ah | bh) > 0) 88 1.1 mrg { 89 1.1 mrg mp_limb_t th, tl; 90 1.1 mrg mp_limb_t bgta; 91 1.1 mrg 92 1.1 mrg sub_ddmmss (th, tl, ah, al, bh, bl); 93 1.1 mrg if ( (tl | th) == 0) 94 1.1 mrg return 0; 95 1.1 mrg 96 1.1 mrg bgta = LIMB_HIGHBIT_TO_MASK (th); 97 1.1 mrg 98 1.1 mrg /* If b > a, invoke reciprocity */ 99 1.1 mrg bit ^= (bgta & al & bl); 100 1.1 mrg 101 1.1 mrg /* b <-- min (a, b) */ 102 1.1 mrg add_ssaaaa (bh, bl, bh, bl, th & bgta, tl & bgta); 103 1.1 mrg 104 1.1 mrg if ( (bh | bl) == 0) 105 1.1 mrg return 1 - 2*(bit & 1); 106 1.1 mrg 107 1.1 mrg /* a <-- |a - b| */ 108 1.1 mrg al = (bgta ^ tl) - bgta; 109 1.1 mrg ah = (bgta ^ th); 110 1.1 mrg 111 1.1 mrg if (UNLIKELY (al == 0)) 112 1.1 mrg { 113 1.1 mrg /* If b > a, al == 0 implies that we have a carry to 114 1.1 mrg propagate. */ 115 1.1 mrg al = ah - bgta; 116 1.1 mrg ah = 0; 117 1.1 mrg bit ^= GMP_NUMB_BITS & (bl ^ (bl >> 1)); 118 1.1 mrg } 119 1.1 mrg count_trailing_zeros (c, al); 120 1.1 mrg c++; 121 1.1 mrg bit ^= c & (bl ^ (bl >> 1)); 122 1.1 mrg 123 1.1 mrg if (UNLIKELY (c == GMP_NUMB_BITS)) 124 1.1 mrg { 125 1.1 mrg al = ah; 126 1.1 mrg ah = 0; 127 1.1 mrg } 128 1.1 mrg else 129 1.1 mrg { 130 1.1 mrg al = ((ah << (GMP_NUMB_BITS - c)) & GMP_NUMB_MASK) | (al >> c); 131 1.1 mrg ah >>= c; 132 1.1 mrg } 133 1.1 mrg } 134 1.1 mrg 135 1.1 mrg ASSERT (bl > 0); 136 1.1 mrg 137 1.1 mrg while ( (al | bl) & GMP_LIMB_HIGHBIT) 138 1.1 mrg { 139 1.1 mrg /* Need an extra comparison to get the mask. */ 140 1.1 mrg mp_limb_t t = al - bl; 141 1.1 mrg mp_limb_t bgta = - (bl > al); 142 1.1 mrg 143 1.1 mrg if (t == 0) 144 1.1 mrg return 0; 145 1.1 mrg 146 1.1 mrg /* If b > a, invoke reciprocity */ 147 1.1 mrg bit ^= (bgta & al & bl); 148 1.1 mrg 149 1.1 mrg /* b <-- min (a, b) */ 150 1.1 mrg bl += (bgta & t); 151 1.1 mrg 152 1.1 mrg /* a <-- |a - b| */ 153 1.1 mrg al = (t ^ bgta) - bgta; 154 1.1 mrg 155 1.1 mrg /* Number of trailing zeros is the same no matter if we look at 156 1.1 mrg * t or a, but using t gives more parallelism. */ 157 1.1 mrg count_trailing_zeros (c, t); 158 1.1 mrg c ++; 159 1.1 mrg /* (2/b) = -1 if b = 3 or 5 mod 8 */ 160 1.1 mrg bit ^= c & (bl ^ (bl >> 1)); 161 1.1 mrg 162 1.1 mrg if (UNLIKELY (c == GMP_NUMB_BITS)) 163 1.1 mrg return 1 - 2*(bit & 1); 164 1.1 mrg 165 1.1 mrg al >>= c; 166 1.1 mrg } 167 1.1 mrg 168 1.1 mrg /* Here we have a little impedance mismatch. Better to inline it? */ 169 1.1 mrg return mpn_jacobi_base (2*al+1, 2*bl+1, bit << 1); 170 1.1 mrg } 171 1.1 mrg #elif JACOBI_2_METHOD == 2 172 1.1 mrg int 173 1.1 mrg mpn_jacobi_2 (mp_srcptr ap, mp_srcptr bp, unsigned bit) 174 1.1 mrg { 175 1.1 mrg mp_limb_t ah, al, bh, bl; 176 1.1 mrg int c; 177 1.1 mrg 178 1.1 mrg al = ap[0]; 179 1.1 mrg ah = ap[1]; 180 1.1 mrg bl = bp[0]; 181 1.1 mrg bh = bp[1]; 182 1.1 mrg 183 1.1 mrg ASSERT (bl & 1); 184 1.1 mrg 185 1.1 mrg /* Use bit 1. */ 186 1.1 mrg bit <<= 1; 187 1.1 mrg 188 1.1 mrg if (bh == 0 && bl == 1) 189 1.1 mrg /* (a|1) = 1 */ 190 1.1 mrg return 1 - (bit & 2); 191 1.1 mrg 192 1.1 mrg if (al == 0) 193 1.1 mrg { 194 1.1 mrg if (ah == 0) 195 1.1 mrg /* (0|b) = 0, b > 1 */ 196 1.1 mrg return 0; 197 1.1 mrg 198 1.1 mrg count_trailing_zeros (c, ah); 199 1.1 mrg bit ^= ((GMP_NUMB_BITS + c) << 1) & (bl ^ (bl >> 1)); 200 1.1 mrg 201 1.1 mrg al = bl; 202 1.1 mrg bl = ah >> c; 203 1.1 mrg 204 1.1 mrg if (bl == 1) 205 1.1 mrg /* (1|b) = 1 */ 206 1.1 mrg return 1 - (bit & 2); 207 1.1 mrg 208 1.1 mrg ah = bh; 209 1.1 mrg 210 1.1 mrg bit ^= al & bl; 211 1.1 mrg 212 1.1 mrg goto b_reduced; 213 1.1 mrg } 214 1.1 mrg if ( (al & 1) == 0) 215 1.1 mrg { 216 1.1 mrg count_trailing_zeros (c, al); 217 1.1 mrg 218 1.1 mrg al = ((ah << (GMP_NUMB_BITS - c)) & GMP_NUMB_MASK) | (al >> c); 219 1.1 mrg ah >>= c; 220 1.1 mrg bit ^= (c << 1) & (bl ^ (bl >> 1)); 221 1.1 mrg } 222 1.1 mrg if (ah == 0) 223 1.1 mrg { 224 1.1 mrg if (bh > 0) 225 1.1 mrg { 226 1.1 mrg bit ^= al & bl; 227 1.1 mrg MP_LIMB_T_SWAP (al, bl); 228 1.1 mrg ah = bh; 229 1.1 mrg goto b_reduced; 230 1.1 mrg } 231 1.1 mrg goto ab_reduced; 232 1.1 mrg } 233 1.1 mrg 234 1.1 mrg while (bh > 0) 235 1.1 mrg { 236 1.1 mrg /* Compute (a|b) */ 237 1.1 mrg while (ah > bh) 238 1.1 mrg { 239 1.1 mrg sub_ddmmss (ah, al, ah, al, bh, bl); 240 1.1 mrg if (al == 0) 241 1.1 mrg { 242 1.1 mrg count_trailing_zeros (c, ah); 243 1.1 mrg bit ^= ((GMP_NUMB_BITS + c) << 1) & (bl ^ (bl >> 1)); 244 1.1 mrg 245 1.1 mrg al = bl; 246 1.1 mrg bl = ah >> c; 247 1.1 mrg ah = bh; 248 1.1 mrg 249 1.1 mrg bit ^= al & bl; 250 1.1 mrg goto b_reduced; 251 1.1 mrg } 252 1.1 mrg count_trailing_zeros (c, al); 253 1.1 mrg bit ^= (c << 1) & (bl ^ (bl >> 1)); 254 1.1 mrg al = ((ah << (GMP_NUMB_BITS - c)) & GMP_NUMB_MASK) | (al >> c); 255 1.1 mrg ah >>= c; 256 1.1 mrg } 257 1.1 mrg if (ah == bh) 258 1.1 mrg goto cancel_hi; 259 1.1 mrg 260 1.1 mrg if (ah == 0) 261 1.1 mrg { 262 1.1 mrg bit ^= al & bl; 263 1.1 mrg MP_LIMB_T_SWAP (al, bl); 264 1.1 mrg ah = bh; 265 1.1 mrg break; 266 1.1 mrg } 267 1.1 mrg 268 1.1 mrg bit ^= al & bl; 269 1.1 mrg 270 1.1 mrg /* Compute (b|a) */ 271 1.1 mrg while (bh > ah) 272 1.1 mrg { 273 1.1 mrg sub_ddmmss (bh, bl, bh, bl, ah, al); 274 1.1 mrg if (bl == 0) 275 1.1 mrg { 276 1.1 mrg count_trailing_zeros (c, bh); 277 1.1 mrg bit ^= ((GMP_NUMB_BITS + c) << 1) & (al ^ (al >> 1)); 278 1.1 mrg 279 1.1 mrg bl = bh >> c; 280 1.1 mrg bit ^= al & bl; 281 1.1 mrg goto b_reduced; 282 1.1 mrg } 283 1.1 mrg count_trailing_zeros (c, bl); 284 1.1 mrg bit ^= (c << 1) & (al ^ (al >> 1)); 285 1.1 mrg bl = ((bh << (GMP_NUMB_BITS - c)) & GMP_NUMB_MASK) | (bl >> c); 286 1.1 mrg bh >>= c; 287 1.1 mrg } 288 1.1 mrg bit ^= al & bl; 289 1.1 mrg 290 1.1 mrg /* Compute (a|b) */ 291 1.1 mrg if (ah == bh) 292 1.1 mrg { 293 1.1 mrg cancel_hi: 294 1.1 mrg if (al < bl) 295 1.1 mrg { 296 1.1 mrg MP_LIMB_T_SWAP (al, bl); 297 1.1 mrg bit ^= al & bl; 298 1.1 mrg } 299 1.1 mrg al -= bl; 300 1.1 mrg if (al == 0) 301 1.1 mrg return 0; 302 1.1 mrg 303 1.1 mrg count_trailing_zeros (c, al); 304 1.1 mrg bit ^= (c << 1) & (bl ^ (bl >> 1)); 305 1.1 mrg al >>= c; 306 1.1 mrg 307 1.1 mrg if (al == 1) 308 1.1 mrg return 1 - (bit & 2); 309 1.1 mrg 310 1.1 mrg MP_LIMB_T_SWAP (al, bl); 311 1.1 mrg bit ^= al & bl; 312 1.1 mrg break; 313 1.1 mrg } 314 1.1 mrg } 315 1.1 mrg 316 1.1 mrg b_reduced: 317 1.1 mrg /* Compute (a|b), with b a single limb. */ 318 1.1 mrg ASSERT (bl & 1); 319 1.1 mrg 320 1.1 mrg if (bl == 1) 321 1.1 mrg /* (a|1) = 1 */ 322 1.1 mrg return 1 - (bit & 2); 323 1.1 mrg 324 1.1 mrg while (ah > 0) 325 1.1 mrg { 326 1.1 mrg ah -= (al < bl); 327 1.1 mrg al -= bl; 328 1.1 mrg if (al == 0) 329 1.1 mrg { 330 1.1 mrg if (ah == 0) 331 1.1 mrg return 0; 332 1.1 mrg count_trailing_zeros (c, ah); 333 1.1 mrg bit ^= ((GMP_NUMB_BITS + c) << 1) & (bl ^ (bl >> 1)); 334 1.1 mrg al = ah >> c; 335 1.1 mrg goto ab_reduced; 336 1.1 mrg } 337 1.1 mrg count_trailing_zeros (c, al); 338 1.1 mrg 339 1.1 mrg al = ((ah << (GMP_NUMB_BITS - c)) & GMP_NUMB_MASK) | (al >> c); 340 1.1 mrg ah >>= c; 341 1.1 mrg bit ^= (c << 1) & (bl ^ (bl >> 1)); 342 1.1 mrg } 343 1.1 mrg ab_reduced: 344 1.1 mrg ASSERT (bl & 1); 345 1.1 mrg ASSERT (bl > 1); 346 1.1 mrg 347 1.1 mrg return mpn_jacobi_base (al, bl, bit); 348 1.1 mrg } 349 1.1 mrg #else 350 1.1 mrg #error Unsupported value for JACOBI_2_METHOD 351 1.1 mrg #endif 352