6 * fast reduction for generalized mersenne numbers (GM)
7 * using a series of additions and subtractions.
14 typedef struct GMfield GMfield;
27 gmreduce(Mfield *m, mpint *a, mpint *r)
29 GMfield *g = (GMfield*)m;
30 mpdigit d0, t[MAXDIG];
33 if(mpmagcmp(a, g->m2) >= 0)
40 mpbits(r, (d+1)*Dbits*2);
41 memmove(t+d, r->p+d, d*Dbytes);
48 mpvecdigmuladd(g->p, d, g->nsub, r->p);
51 for(i=0; i<g->nadd; i++){
58 mpvecadd(r->p, d+1, t, d, r->p);
61 for(i=0; i<g->nsub; i++){
68 mpvecsub(r->p, d+1, t, d, r->p);
71 mpvecdigmulsub(g->p, d, r->p[d], r->p);
74 mpvecsub(r->p, d+1, g->p, d, r->p+d+1);
77 r->p[j] = (r->p[j] & d0) | (r->p[j+d+1] & ~d0);
87 int i,j,d, s, *C, *X, *x, *e;
92 if(d <= 2 || d > MAXDIG/2 || (mpsignif(N) % Dbits) != 0)
97 C = malloc(sizeof(int)*(d+1));
98 X = malloc(sizeof(int)*(d*d));
99 if(C == nil || X == nil)
103 if((M->p[i]>>8) != 0 && (~M->p[i]>>8) != 0)
108 mpleft(T, i*Dbits, T);
114 X[d*i] = X[d*(i-1) + d-1]*C[d];
116 X[d*i + j] = X[d*(i-1) + j-1] + X[d*(i-1) + d-1]*C[d-j];
118 g = mallocz(sizeof(GMfield) + (d+1)*sizeof(mpdigit)*2, 1);
122 g->m2->p = (mpdigit*)&g[1];
126 g->reduce = gmreduce;
131 e = x + nelem(g->indx) - d;
132 for(g->nadd=0; x <= e; x += d, g->nadd++){
136 if(X[d*i+j] > 0 && x[j] == 0){
147 for(g->nsub=0; x <= e; x += d, g->nsub++){
151 if(X[d*i+j] < 0 && x[j] == 0){