00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00017 class CN_Residue
00018 {
00019 private:
00020 mpz_t N;
00021 mpz_t R;
00022 mpz_t h;
00023 unsigned int k;
00024 public:
00025 inline CN_Residue()
00026 {
00027 cout << "Modular arithmetic using precomputed reciprocal activated." << endl;
00028 mpz_init(N); mpz_init(R); mpz_init(h);
00029 k=0;
00030 };
00031 inline void init(const mpz_t M)
00032 {
00033 mpz_set(N,M);
00034 k=mpz_sizeinbase(N,2)+1;
00035 mpz_set_ui(h,1); mpz_mul_2exp(h,h,2*k);
00036 mpz_cdiv_q(R,h,N);
00037 };
00038 inline explicit CN_Residue(const mpz_t M)
00039 {
00040 CN_Residue();
00041 init(M);
00042 };
00043 inline ~CN_Residue()
00044 {
00045 mpz_clear(N);
00046 mpz_clear(R);
00047 mpz_clear(h);
00048 };
00049 inline void mod(mpz_t res, const mpz_t a)
00050 {
00051 mpz_fdiv_q_2exp(h,a,k-1); mpz_add_ui(h,h,1);
00052 mpz_mul(h,h,R);
00053 mpz_fdiv_q_2exp(h,h,k+1);
00054 mpz_mul(h,h,N); mpz_sub(res,a,h);
00055 if (mpz_sizeinbase(res,2)>k+1)
00056 { mpz_mod(res,res,N); cerr << endl << "moderror!" << endl; }
00057 }
00058 };