| 249 | // ------------------------------------------------ |
| 250 | |
| 251 | void Int::ModInv() { |
| 252 | |
| 253 | // Compute modular inverse of this mop _P |
| 254 | // 0 < this < P , P must be odd |
| 255 | // Return 0 if no inverse |
| 256 | |
| 257 | // 256bit |
| 258 | //#define XCD 1 // ~80 kOps/s |
| 259 | //#define MONTGOMERY 1 // ~246 kOps/s |
| 260 | //#define PENK 1 // ~215 kOps/s |
| 261 | #define DRS62 1 // ~640 kOps/s |
| 262 | |
| 263 | Int u(&_P); |
| 264 | Int v(this); |
| 265 | |
| 266 | #ifdef XCD |
| 267 | |
| 268 | Int r((int64_t)0); |
| 269 | Int s((int64_t)1); |
| 270 | Int q, t1, t2, w; |
| 271 | |
| 272 | // Classic XCD |
| 273 | |
| 274 | bool bIterations = true; // Remember odd/even iterations |
| 275 | while (!u.IsZero()) { |
| 276 | // Step X3. Divide and "Subtract" |
| 277 | q.Set(&v); |
| 278 | q.Div(&u, &t2); // q = u / v, t2 = u % v |
| 279 | w.Mult(&q, &r); // w = q * r |
| 280 | t1.Add(&s, &w); // t1 = s + w |
| 281 | |
| 282 | // Swap u,v & r,s |
| 283 | s.Set(&r); |
| 284 | r.Set(&t1); |
| 285 | v.Set(&u); |
| 286 | u.Set(&t2); |
| 287 | |
| 288 | bIterations = !bIterations; |
| 289 | } |
| 290 | |
| 291 | if (!v.IsOne()) { |
| 292 | CLEAR(); |
| 293 | return; |
| 294 | } |
| 295 | |
| 296 | if (!bIterations) { |
| 297 | Set(&_P); |
| 298 | Sub(&s); /* inv = n - u1 */ |
| 299 | } else { |
| 300 | Set(&s); /* inv = u1 */ |
| 301 | } |
| 302 | |
| 303 | #endif |
| 304 | |
| 305 | #ifdef PENK |
| 306 | |
| 307 | Int r((int64_t)0); |
| 308 | Int s((int64_t)1); |
no test coverage detected