| 987 | // M[N] --- modulus |
| 988 | |
| 989 | unsigned int AlmostInverse(word *R, word *T, const word *A, unsigned int NA, const word *M, unsigned int N) |
| 990 | { |
| 991 | assert(NA<=N && N && N%2==0); |
| 992 | |
| 993 | word *b = T; |
| 994 | word *c = T+N; |
| 995 | word *f = T+2*N; |
| 996 | word *g = T+3*N; |
| 997 | unsigned int bcLen=2, fgLen=EvenWordCount(M, N); |
| 998 | unsigned int k=0, s=0; |
| 999 | |
| 1000 | SetWords(T, 0, 3*N); |
| 1001 | b[0]=1; |
| 1002 | CopyWords(f, A, NA); |
| 1003 | CopyWords(g, M, N); |
| 1004 | |
| 1005 | while (1) |
| 1006 | { |
| 1007 | word t=f[0]; |
| 1008 | while (!t) |
| 1009 | { |
| 1010 | if (EvenWordCount(f, fgLen)==0) |
| 1011 | { |
| 1012 | SetWords(R, 0, N); |
| 1013 | return 0; |
| 1014 | } |
| 1015 | |
| 1016 | ShiftWordsRightByWords(f, fgLen, 1); |
| 1017 | if (c[bcLen-1]) bcLen+=2; |
| 1018 | assert(bcLen <= N); |
| 1019 | ShiftWordsLeftByWords(c, bcLen, 1); |
| 1020 | k+=WORD_BITS; |
| 1021 | t=f[0]; |
| 1022 | } |
| 1023 | |
| 1024 | unsigned int i=0; |
| 1025 | while (t%2 == 0) |
| 1026 | { |
| 1027 | t>>=1; |
| 1028 | i++; |
| 1029 | } |
| 1030 | k+=i; |
| 1031 | |
| 1032 | if (t==1 && f[1]==0 && EvenWordCount(f, fgLen)==2) |
| 1033 | { |
| 1034 | if (s%2==0) |
| 1035 | CopyWords(R, b, N); |
| 1036 | else |
| 1037 | Subtract(R, M, b, N); |
| 1038 | return k; |
| 1039 | } |
| 1040 | |
| 1041 | ShiftWordsRightByBits(f, fgLen, i); |
| 1042 | t=ShiftWordsLeftByBits(c, bcLen, i); |
| 1043 | if (t) |
| 1044 | { |
| 1045 | c[bcLen] = t; |
| 1046 | bcLen+=2; |
no test coverage detected