301{
302 mpz_t a1, a2, u1, u2, q, h, mhalf, u2sqr, a2sqr;
303 bool retVal = true;
304 mpz_init_set(a1, m);
305 mpz_init_set(a2, c);
306 mpz_init_set_si(u1, 0);
307 mpz_init_set_si(u2, 1);
308 mpz_init_set_si(q, 0);
309 mpz_init_set_si(h, 0);
310 mpz_init(u2sqr);
311 mpz_init(a2sqr);
312 mpz_init(mhalf);
313
314 mpz_tdiv_q_2exp(mhalf, m, 1);
315
316 for (;;)
317 {
318 mpz_mul(u2sqr, u2, u2);
319
320 if (mpz_cmp(u2sqr, mhalf) >= 0)
321 {
322 retVal = false;
324 break;
325 }
326
327 mpz_mul(a2sqr, a2, a2);
328
329 if (mpz_cmp(a2sqr, mhalf) < 0)
330 {
331 retVal = true;
335 break;
336 }
337
338 mpz_fdiv_q(q, a1, a2);
339 mpz_submul(a1, q, a2);
340 mpz_submul(u1, q, u2);
341 mpz_swap(a1, a2);
342 mpz_swap(u1, u2);
343 }
344
345
346 mpz_clear(a1);
347 mpz_clear(a2);
348 mpz_clear(u1);
349 mpz_clear(u2);
350 mpz_clear(q);
351 mpz_clear(h);
352 mpz_clear(mhalf);
353 mpz_clear(u2sqr);
354 mpz_clear(a2sqr);
355
356 return retVal;
357}
VALGRIND_MAKE_MEM_DEFINED & result(result)