| 572 | } |
| 573 | |
| 574 | Integer ModularSquareRoot(const Integer &a, const Integer &p) |
| 575 | { |
| 576 | if (p%4 == 3) |
| 577 | return a_exp_b_mod_c(a, (p+1)/4, p); |
| 578 | |
| 579 | Integer q=p-1; |
| 580 | unsigned int r=0; |
| 581 | while (q.IsEven()) |
| 582 | { |
| 583 | r++; |
| 584 | q >>= 1; |
| 585 | } |
| 586 | |
| 587 | Integer n=2; |
| 588 | while (Jacobi(n, p) != -1) |
| 589 | ++n; |
| 590 | |
| 591 | Integer y = a_exp_b_mod_c(n, q, p); |
| 592 | Integer x = a_exp_b_mod_c(a, (q-1)/2, p); |
| 593 | Integer b = (x.Squared()%p)*a%p; |
| 594 | x = a*x%p; |
| 595 | Integer tempb, t; |
| 596 | |
| 597 | while (b != 1) |
| 598 | { |
| 599 | unsigned m=0; |
| 600 | tempb = b; |
| 601 | do |
| 602 | { |
| 603 | m++; |
| 604 | b = b.Squared()%p; |
| 605 | if (m==r) |
| 606 | return Integer::Zero(); |
| 607 | } |
| 608 | while (b != 1); |
| 609 | |
| 610 | t = y; |
| 611 | for (unsigned i=0; i<r-m-1; i++) |
| 612 | t = t.Squared()%p; |
| 613 | y = t.Squared()%p; |
| 614 | r = m; |
| 615 | x = x*t%p; |
| 616 | b = tempb*y%p; |
| 617 | } |
| 618 | |
| 619 | CRYPTOPP_ASSERT(x.Squared()%p == a); |
| 620 | return x; |
| 621 | } |
| 622 | |
| 623 | bool SolveModularQuadraticEquation(Integer &r1, Integer &r2, const Integer &a, const Integer &b, const Integer &c, const Integer &p) |
| 624 | { |
no test coverage detected