#include "supercon.h" #define SIZE 65536 /* (256*256) */ typedef struct { int p1; int p2; }ypair; typedef struct { int sign; bignum num; }_bignum; typedef struct { int x; int image; bignum mimage; }recv_msg; int image[SIZE], eimage[SIZE]; bignum rsaN, rsaE; int flgE[128], lenE; bignum hint[SIZE]; int hardness[SIZE]; int s[SIZE][16]; bignum mimage[SIZE]; int isprime[SIZE]; int hokan[SIZE], outimage[SIZE]; MPI_Datatype mpi_bignum; MPI_Datatype mpi_recv_msg; ypair yp_data[800000]; ypair *yp[65536]; int yp_len[65536]; void hokan4(int x) { int color; color = image[x] ? 1 : -1; if(x-Nx >= 0) hokan[x-Nx] += color; if(x+Nx < SIZE) hokan[x+Nx] += color; if(x-1 >= 0) hokan[x-1] += color; if(x+1 < SIZE) hokan[x+1] += color; } _bignum _bmul(_bignum x, _bignum y) { _bignum a; a.sign = x.sign ^ y.sign; a.num = bmul(x.num, y.num); return a; } _bignum _bquo(_bignum x, _bignum y) { _bignum a; a.sign = x.sign ^ y.sign; a.num = bquo(x.num, y.num); return a; } _bignum _bsub(_bignum x, _bignum y) { _bignum a; if(x.sign ^ y.sign) { if(x.sign) { a.sign = 1; a.num = badd(x.num, y.num); } else { a.sign = 0; a.num = badd(x.num, y.num); } } else { if(x.sign) { if(bge(x.num, y.num)) { a.sign = 1; a.num = bsub(x.num, y.num); } else { a.sign = 0; a.num = bsub(y.num, x.num); } } else { if(bge(y.num, x.num)) { a.sign = 1; a.num = bsub(y.num, x.num); } else { a.sign = 0; a.num = bsub(x.num, y.num); } } } return a; } _bignum _badd(_bignum x, _bignum y) { _bignum a; if(x.sign ^ y.sign) { if(x.sign) { if(bge(x.num, y.num)) { a.sign = 1; a.num = bsub(x.num, y.num); } else { a.sign = 0; a.num = bsub(y.num, x.num); } } else { if(bge(y.num, x.num)) { a.sign = 1; a.num = bsub(y.num, x.num); } else { a.sign = 0; a.num = bsub(x.num, y.num); } } } else { if(x.sign) { a.sign = 0; a.num = badd(x.num, y.num); } else { a.sign = 1; a.num = badd(x.num, y.num); } } return a; } bool _bgt(_bignum x, _bignum y) { if(x.sign == 0) { if(y.sign == 0) { return bgt(x.num, y.num); } else { return true; } } else { if(y.sign == 0) { return false; } else { return bgt(y.num, x.num); } } } bignum ltob(unsigned long x) { bignum a; a.h = 0; a.l = x; return a; } _bignum lto_b(int sign, unsigned long x) { _bignum a; a.sign = sign; a.num.h = 0; a.num.l = x; return a; } bignum _btob(_bignum x) { bignum a; a = x.num; return a; } _bignum bto_b(bignum x) { _bignum a; a.sign = 0; a.num = x; return a; } int yakusu() { int i, p1, p2, len; ypair *w; w = yp_data; for(i=1; i<65536; i++) { yp[i] = w; p1 = 2; p2 = i >> 1; /* p2 = i / 2; */ len = 0; while(p1 < p2) { if(i - p1*p2 == 0 && p2 != 1) { w->p1 = p1; w->p2 = p2; w++; w->p2 = p1; w->p1 = p2; w++; len+=2; } p1++; p2 = i / p1; } yp_len[i] = len; } return w - yp_data; } int cmp(const void *a, const void *b) { if( *(int *)a > *(int *)b ) return 1; else if( *(int *)a == *(int *)b ) return 0; else return -1; } void soinsuu(int s[], int n) { int len; int m, i, add; /* init */ len = 0; m = n; i = 2; if(n == 0) { s[0] = 0; return; } /* i = 2, 3 */ while((m & 1) == 0) /* while(m % 2 == 0) */ { m >>= 1; /* m /= 2; */ s[len++] = 2; } while(m % 3 == 0) { m /= 3; s[len++] = 3; } /* i = 5, 7, 11, 13, 17, 19...... */ i = 5; add = 2; while(m > 1) { if(m % i == 0) { m /= i; s[len++] = i; } else { i += add; if(add == 2) { add = 4; } else if(add == 4) { add = 2; } } if(i <= m/5) { s[len++] = m; break; } } s[len] = 0; } bignum exmod(bignum b) { int i; bignum a, c; a = brem(b, rsaN); c.h = 0; c.l = 1; for(i=0; isign ^= 1; y->sign ^= 1; } } void solve_div(int ab, int a) { int b; _bignum c1, alp, beta, N; bignum cb; c1.sign = 0; c1.num = mimage[a]; N.sign = 0; N.num = rsaN; b = ab / a; EuclidEx(c1, N, &alp, &beta); if(alp.sign == 1) alp.num = bsub(badd(rsaN, bmul(rsaN, bquo(alp.num, rsaN))), alp.num); cb = mmul(mimage[ab], alp.num, rsaN); mimage[b] = cb; image[b] = (cb.l & 1) ^ eimage[b]; } void solve_prod(int a, int b) { int c; c = a*b; mimage[c] = mmul(mimage[a], mimage[b], rsaN); image[c] = (mimage[c].l & 1) ^ eimage[c]; } void init_rsaE() { int i, j; j = rsaE.l; for(i=0; i<64; i++, j>>=1) { if(flgE[i] = j&1) lenE = i+1; } j = rsaE.h; for(i=64; i<128; i++, j>>=1) { if(flgE[i] = j&1) lenE = i+1; } } void is_prime() { int i, j; for(i=0; inow; i-=now, k--) { if(image[k] != -1 && image[i] == -1) { solve_prod(now, k); hokan4(i); prod_search(i); } } } void div_search(int now) { int i, end; ypair *pyp; pyp = yp[now]; end = yp_len[now]; for(i=0; i=0 ? 1 : 0; else outimage[i] = image[i]; } outresult(outimage); } int main(int argc, char **argv) { FILE *fp; int pri[SIZE]; int send, i, now; recv_msg message; MPI_Status status; int size, myrank; double oldtime; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &myrank); outstarttime(); if(argc < 2) { MPI_Finalize(); exit(1); } make_mpi_type(); if(myrank == 0) { fp=fopen(argv[1], "r"); getimage(fp, eimage); fclose(fp); fp=fopen(argv[2], "r"); gethint(fp, &rsaN, &rsaE, hardness, hint); fclose(fp); is_prime(); init_rsaE(); for(i=0; i= 2 && image[i] != -1) { prod_search(i); } if(!isprime[i] && image[i] != -1) { div_search(i); } } } while(image[pri[send]] != -1) send++; MPI_Send(&pri[send], 1, MPI_INT, status.MPI_SOURCE, 99, MPI_COMM_WORLD); send++; if(MPI_Wtime() > oldtime + 5) { /*outresult(image);*/ output(); oldtime += 5; } } } else { client_process(); } MPI_Finalize(); exit(0); }