00001
00007 void my_mpz_powm_ui(mpz_t a, unsigned int n, const mpz_t m)
00008 {
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 if (n<127) { mpz_powm_ui(a,a,n,m); return; }
00020
00021 register unsigned int h = n;
00022 register int b = 0;
00023 while (h) { b+=(h&1) ? 3 : -4; h>>=1; }
00024
00025
00026 if (b<0)
00027 {
00028
00029 mpz_powm_ui(a,a,n,m);
00030 return;
00031 }
00032
00033
00034 mpz_t r;
00035 mpz_init_set(r,a);
00036 n--;
00037
00038 h=0; while ((n&1)==0) { n>>=1; h++; }
00039 if (h) mpz_powm_ui(r,r,1<<h,m);
00040 while (n%129==0) { n/=129; mpz_powm_ui(r,r,129,m); }
00041 while (n%65==0) { n/=65; mpz_powm_ui(r,r,65,m); }
00042 while (n%33==0) { n/=33; mpz_powm_ui(r,r,33,m); }
00043 while (n%17==0) { n/=17; mpz_powm_ui(r,r,17,m); }
00044 while (n%9==0) { n/=9; mpz_powm_ui(r,r,9,m); }
00045 while (n%5==0) { n/=5; mpz_powm_ui(r,r,5,m); }
00046 while (n%3==0) { n/=3; mpz_powm_ui(r,r,3,m); }
00047
00048 while (n%11==0) { n/=11; mpz_powm_ui(r,r,11,m); }
00049 while (n%13==0) { n/=13; mpz_powm_ui(r,r,13,m); }
00050 while (n%19==0) { n/=19; mpz_powm_ui(r,r,19,m); }
00051
00052
00053 if (n>1) mpz_powm_ui(r,r,n,m);
00054 mpz_mul(a,a,r); mpz_mod(a,a,m);
00055 mpz_clear(r);
00056 }