|
|
1.1 ! root 1: #include "mp.h" ! 2: mint mulmod(); ! 3: ! 4: /* ! 5: returns 0 if pseudoprime ! 6: 1 if composite ! 7: 2 if composite pseudoprime ! 8: */ ! 9: int ! 10: pseudo(nn, arg2) ! 11: mint nn; ! 12: mint arg2; ! 13: { ! 14: mint nm1, y, z; ! 15: mint zero, one, two; ! 16: mint rem; ! 17: mint mtemp; ! 18: mint lasty; ! 19: int i; ! 20: ! 21: zero.low = zero.high = 0.0; ! 22: one = itom(1); ! 23: two = itom(2); ! 24: ! 25: if(mcmp(nn,zero) <= 0) abort(0); ! 26: if(mcmp(nn,two) <=0) abort(0); ! 27: mdiv(nn, two, &rem); ! 28: if(mcmp(rem, zero) == 0.0) abort(0); ! 29: ! 30: nm1 = msub(nn, one); ! 31: y = one; ! 32: z = arg2; ! 33: ! 34: i = 0; ! 35: while(1){ ! 36: mtemp = mdiv(nm1, two, &rem); ! 37: if(mcmp(rem,zero) == 0){ ! 38: nm1 = mtemp; ! 39: i = i + 1; ! 40: }else break; ! 41: } ! 42: ! 43: while(mcmp(nm1,zero) != 0){ ! 44: nm1 = mdiv(nm1, two, &rem); ! 45: if(mcmp(rem, one) == 0){ ! 46: y = mulmod(y, z, nn); ! 47: } ! 48: z = mulmod(z, z, nn); ! 49: } ! 50: if(mcmp(y, one) == 0){ ! 51: return(0); ! 52: } ! 53: while(i--){ ! 54: lasty = y; ! 55: y = mulmod(y,y,nn); ! 56: if(mcmp(y, one) == 0) break; ! 57: } ! 58: if(mcmp(y, one) != 0){ ! 59: return(1); ! 60: } ! 61: if(mcmp(lasty, one) == 0){ ! 62: printf("pseudo: error.\n"); ! 63: } ! 64: if(mcmp(lasty,msub(nn,one)) != 0){ ! 65: return(2); ! 66: } ! 67: return(0); ! 68: } ! 69: mint ! 70: mulmod(a,b,c) ! 71: mint a, b, c; ! 72: { ! 73: ! 74: mint mjunk; ! 75: mint mtemp1, mtemp2; ! 76: mint xy0, xy1, xy2, xy3; ! 77: mint x1, x2, y1, y2; ! 78: int i; ! 79: double z0, z1, z2, z3; ! 80: double s0, s1, s2; ! 81: double tquot, dtemp1, dtemp2; ! 82: mint zero; ! 83: ! 84: ! 85: zero.low = 0.0; ! 86: zero.high = 0.0; ! 87: if(mcmp(c,zero) == 0){ ! 88: printf("mulmod: divide check\n"); ! 89: abort(0); ! 90: } ! 91: ! 92: if((mcmp(a,zero)<0) || (mcmp(b,zero)<0)){ ! 93: printf("mulmod: negative argument.\n"); ! 94: abort(0); ! 95: } ! 96: if(mcmp(c,zero) < 0){ ! 97: printf("mulmod: negative modulus.\n"); ! 98: abort(0); ! 99: } ! 100: x1.low = a.low; ! 101: x1.high = 0; ! 102: x2.low = a.high; ! 103: x2.high = 0; ! 104: ! 105: y1.low = b.low; ! 106: y1.high = 0; ! 107: y2.low = b.high; ! 108: y2.high = 0; ! 109: ! 110: xy0 = mult(x1,y1); ! 111: xy1 = mult(x1,y2); ! 112: xy2 = mult(x2,y1); ! 113: xy3 = mult(x2,y2); ! 114: ! 115: z0 = xy0.low; ! 116: ! 117: mtemp1.low = xy0.high; ! 118: mtemp1.high = 0; ! 119: mtemp2.low = xy1.low; ! 120: mtemp2.high = 0; ! 121: mtemp1 = madd(mtemp1, mtemp2); ! 122: mtemp2.low = xy2.low; ! 123: mtemp1 = madd(mtemp1, mtemp2); ! 124: z1 = mtemp1.low; ! 125: ! 126: mtemp1.low = mtemp1.high; ! 127: mtemp1.high = 0; ! 128: mtemp2.low = xy1.high; ! 129: mtemp2.high = 0; ! 130: mtemp1 = madd(mtemp1, mtemp2); ! 131: mtemp2.low = xy2.high; ! 132: mtemp1 = madd(mtemp1, mtemp2); ! 133: mtemp2.low = xy3.low; ! 134: mtemp1 = madd(mtemp1, mtemp2); ! 135: z2 = mtemp1.low; ! 136: ! 137: mtemp1.low = mtemp1.high; ! 138: mtemp1.high = 0; ! 139: mtemp2.low = xy3.high; ! 140: mtemp2.high = 0; ! 141: mtemp1 = madd(mtemp1, mtemp2); ! 142: z3 = mtemp1.low; ! 143: ! 144: ! 145: if(mtemp1.high != 0.0){ ! 146: printf("mulmod: error\n"); ! 147: } ! 148: ! 149: if(c.high == 0.0){ ! 150: mtemp1.high = 0.0; ! 151: mtemp1.low = z3; ! 152: mjunk = mdiv(mtemp1, c, &mtemp2); ! 153: z3 = mtemp2.low; ! 154: if(mtemp2.high != 0.0) trouble(12); ! 155: mtemp1.high = z3; ! 156: mtemp1.low = z2; ! 157: mjunk = mdiv(mtemp1, c, &mtemp2); ! 158: mtemp1.high = mtemp2.low; ! 159: mtemp1.low = z1; ! 160: mjunk = mdiv(mtemp1, c, &mtemp2); ! 161: mtemp1.high = mtemp2.low; ! 162: mtemp1.low = z0; ! 163: mjunk = mdiv(mtemp1, c, &mtemp2); ! 164: if(mcmp(mtemp2, c) >= 0) trouble(10); ! 165: if(mcmp(mtemp2, zero) < 0) trouble(11); ! 166: return(mtemp2); ! 167: } ! 168: ! 169: mtemp1.high = z3; ! 170: mtemp1.low = z2; ! 171: if(mcmp(mtemp1, c) >= 0){ ! 172: mjunk = mdiv(mtemp1, c, &mtemp2); ! 173: z3 = mtemp2.high; ! 174: z2 = mtemp2.low; ! 175: } ! 176: dtemp1 = (z3*e16 + z2) + z1/e16; ! 177: tquot = dtemp1/(c.high+c.low/e16); ! 178: modf(tquot, &tquot); ! 179: y1.low = tquot; ! 180: y1.high = 0.0; ! 181: x1.low = c.low; ! 182: x1.high = 0.0; ! 183: x2.low = c.high; ! 184: x2.high = 0; ! 185: xy0 = mult(x1, y1); ! 186: xy1 = mult(x2, y1); ! 187: ! 188: s0 = xy0.low; ! 189: ! 190: mtemp1.low = xy0.high; ! 191: mtemp1.high = 0.0; ! 192: mtemp1 = madd(mtemp1, xy1); ! 193: s1 = mtemp1.low; ! 194: s2 = mtemp1.high; ! 195: s0 = z1 - s0; ! 196: s1 = z2 - s1; ! 197: s2 = z3 - s2; ! 198: ! 199: if(s2 > 0.0) {s2 = s2 - 1; s1 = s1 + e16;} ! 200: if(s2 < 0.0) {s2 = s2 + 1; s1 = s1 - e16;} ! 201: if((s1<0.0) && (s0>0.0)){ ! 202: s1 = s1 + 1; ! 203: s0 = s0 - e16; ! 204: }else ! 205: if((s1>0.0) && (s0<0.0)){ ! 206: s1 = s1 - 1; ! 207: s0 = s0 + e16; ! 208: } ! 209: if((s1*e16+s0) < 0.0){ ! 210: mtemp1.low = s0; ! 211: mtemp1.high = s1; ! 212: mtemp1 = madd(mtemp1, c); ! 213: s1 = mtemp1.high; ! 214: s0 = mtemp1.low; ! 215: } ! 216: if(s2 != 0.0) trouble(1); ! 217: mtemp1.low = s0; ! 218: mtemp1.high = s1; ! 219: if(mcmp(mtemp1,zero) < 0) trouble(2); ! 220: if(mcmp(mtemp1,c) >= 0){ ! 221: mtemp1.high = s1; ! 222: mtemp1.low = s0; ! 223: mtemp1 = msub(mtemp1, c); ! 224: s1 = mtemp1.high; ! 225: s0 = mtemp1.low; ! 226: } ! 227: if(mcmp(mtemp1,c) >0) trouble(3); ! 228: ! 229: z3 = s2; ! 230: z2 = s1; ! 231: z1 = s0; ! 232: ! 233: dtemp1 = (z2*e16 + z1) + z0/e16; ! 234: tquot = dtemp1/(c.high + c.low/e16); ! 235: modf(tquot, &tquot); ! 236: y1.low = tquot; ! 237: y1.high = 0.0; ! 238: x1.low = c.low; ! 239: x1.high = 0.0; ! 240: x2.low = c.high; ! 241: x2.high = 0.0; ! 242: xy0 = mult(x1, y1); ! 243: xy1 = mult(x2, y1); ! 244: ! 245: s0 = xy0.low; ! 246: ! 247: mtemp1.low = xy0.high; ! 248: mtemp1.high = 0.0; ! 249: mtemp1 = madd(mtemp1, xy1); ! 250: s1 = mtemp1.low; ! 251: s2 = mtemp1.high; ! 252: ! 253: s0 = z0 - s0; ! 254: s1 = z1 - s1; ! 255: s2 = z2 - s2; ! 256: if(s2 > 0.0) {s2 = s2 - 1; s1 = s1 + e16;} ! 257: if(s2 < 0.0) {s2 = s2 + 1; s1 = s1 - e16;} ! 258: if((s1<0.0) && (s0>0.0)){ ! 259: s1 = s1 + 1; ! 260: s0 = s0 - e16; ! 261: }else ! 262: if((s1>0.0) && (s0<0.0)){ ! 263: s1 = s1 - 1; ! 264: s0 = s0 + e16; ! 265: } ! 266: if((s1*e16+s0) < 0.0){ ! 267: mtemp1.low = s0; ! 268: mtemp1.high = s1; ! 269: mtemp1 = madd(mtemp1, c); ! 270: s1 = mtemp1.high; ! 271: s0 = mtemp1.low; ! 272: } ! 273: if(s2 != 0.0) trouble(4); ! 274: mtemp1.low = s0; ! 275: mtemp1.high = s1; ! 276: if(mcmp(mtemp1,zero) < 0) trouble(5); ! 277: if(mcmp(mtemp1,c) >= 0){ ! 278: mtemp1.high = s1; ! 279: mtemp1.low = s0; ! 280: mtemp1 = msub(mtemp1, c); ! 281: s1 = mtemp1.high; ! 282: s0 = mtemp1.low; ! 283: } ! 284: if(mcmp(mtemp1,c) > 0) trouble(6); ! 285: ! 286: z2 = s2; ! 287: z1 = s1; ! 288: z0 = s0; ! 289: mtemp1.high = s1; ! 290: mtemp1.low = s0; ! 291: return(mtemp1); ! 292: } ! 293: ! 294: trouble(i) ! 295: int i; ! 296: { ! 297: printf("mulmod: error %d\n", i); ! 298: abort(0); ! 299: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.