| 755 | // V[N] --- 2**(WORD_BITS*3*N/2) mod M |
| 756 | |
| 757 | void HalfMontgomeryReduce(word *R, word *T, const word *X, const word *M, const word *U, const word *V, unsigned int N) |
| 758 | { |
| 759 | assert(N%2==0 && N>=4); |
| 760 | |
| 761 | #define M0 M |
| 762 | #define M1 (M+N2) |
| 763 | #define V0 V |
| 764 | #define V1 (V+N2) |
| 765 | |
| 766 | #define X0 X |
| 767 | #define X1 (X+N2) |
| 768 | #define X2 (X+N) |
| 769 | #define X3 (X+N+N2) |
| 770 | |
| 771 | const unsigned int N2 = N/2; |
| 772 | RecursiveMultiply(T0, T2, V0, X3, N2); |
| 773 | int c2 = Add(T0, T0, X0, N); |
| 774 | RecursiveMultiplyBottom(T3, T2, T0, U, N2); |
| 775 | RecursiveMultiplyTop(T2, R, T0, T3, M0, N2); |
| 776 | c2 -= Subtract(T2, T1, T2, N2); |
| 777 | RecursiveMultiply(T0, R, T3, M1, N2); |
| 778 | c2 -= Subtract(T0, T2, T0, N2); |
| 779 | int c3 = -(int)Subtract(T1, X2, T1, N2); |
| 780 | RecursiveMultiply(R0, T2, V1, X3, N2); |
| 781 | c3 += Add(R, R, T, N); |
| 782 | |
| 783 | if (c2>0) |
| 784 | c3 += Increment(R1, N2); |
| 785 | else if (c2<0) |
| 786 | c3 -= Decrement(R1, N2, -c2); |
| 787 | |
| 788 | assert(c3>=-1 && c3<=1); |
| 789 | if (c3>0) |
| 790 | Subtract(R, R, M, N); |
| 791 | else if (c3<0) |
| 792 | Add(R, R, M, N); |
| 793 | |
| 794 | #undef M0 |
| 795 | #undef M1 |
| 796 | #undef V0 |
| 797 | #undef V1 |
| 798 | |
| 799 | #undef X0 |
| 800 | #undef X1 |
| 801 | #undef X2 |
| 802 | #undef X3 |
| 803 | } |
| 804 | |
| 805 | #undef A0 |
| 806 | #undef A1 |
no test coverage detected