long long binpow(long long a, long long n) { if (n == 0) return 1; long long res = binpow(a, n / 2); res = mulmod(res, res); if (n % 2 == 1) return res = mulmod(res, a); return res; }
main(int ac, char **av) { uint64_t k,b,n,p; int64_t c; uint64_t r; int i; if (ac < 5) { printf("usage: %s k b n c p iterations\n",av[0]); exit(1); } // convert arguments k = atoi(av[1]); b = atoi(av[2]); n = atoi(av[3]); p = atoi(av[4]); for (i=0; i< atoi(av[5]); i++); r = powmulmod(k,b,n,p); printf("%d^%d | %d = %d\n", b,n,p,r); printf("2^2-1 %3 = %d\n", mulmod(1,(2*2-1),3)); printf("2^3-1 %3 = %d\n", mulmod(1,(4*2-1),3)); printf("2^4-1 %3 = %d\n", mulmod(1,(8*2-1),3)); printf("2^4-2 %3 = %d\n", mulmod(1,(8*2-2),3)); printf("2^4-3 %3 = %d\n", mulmod(1,(8*2-3),3)); }
ll expmod(ll b, ll e, ll m) { //O(log b) if (!e) return 1; ll q = expmod(b, e / 2, m); q = mulmod(q, q, m); return e % 2 ? mulmod(b, q, m) : q; }
//(a^b)%m in log(b) long long power(long long b, long long n, long long mod) { long long x=1, p=b; while(n) { if(n&1) x = mulmod(x, p, mod); p = mulmod(p, p, mod); n >>= 1; } return x; }
uint64 powmod(uint64 x, uint64 n, uint64 m) { uint64 a = 1, b = x; for (; n > 0; n >>= 1) { if (n & 1) { a = mulmod(a, b, m); } b = mulmod(b, b, m); } return a % m; }
ll modulo(ll a, ll b, ll c) { ll x = 1, y = a%c; while(b>0) { if(b&1) x = mulmod(x,y,c); y = mulmod(y,y,c); b = b>>1; } return x; }
unsigned long long powmod(long long a, long long b, long long c){ unsigned long long result = 1; unsigned long long base = a; while (b){ if (b & 1){ result = mulmod(result, base , c); } b >>= 1; base = mulmod(base, base , c); } return result; }
unsigned long long modulo(unsigned long long a, unsigned long long b, unsigned long long P) { unsigned long long ans = 1; while( b ) { if( b & 1 ) ans = mulmod(ans, a, P); a = mulmod(a, a, P); b >>= 1; } return ans; }
type mod_exp (type a, type n, type q) { type var = 1; type mult = a; while ( n != 0 ) { if (n%2 == 1) { var = mulmod(var, mult, q); } mult = mulmod(mult, mult, q); n = n>>1; } return var; }
/* Return a^r % n, where 0 < n. */ static uint64_t powmod(uint64_t a, uint64_t r, uint64_t n) { uint64_t x = 1; while (r != 0) { if (r & 1) x = mulmod(a, x, n); a = mulmod(a, a, n); r >>= 1; } return (x); }
uint64_t modexp (uint64_t m, uint64_t e, uint64_t n) { uint64_t result = 1; while (e > 0) { if (e & 1) { result = mulmod (result, m, n); } e >>= 1; m = mulmod (m, m, n); } return result; }
unsigned long long RSA::powmod(const unsigned long long base,unsigned long long pow,const unsigned long long n) { unsigned long long a=base,b=pow,c=1; while(b) { while(!(b&1)) { b>>=1; a=mulmod(a,a,n); } b--; c=mulmod(a,c,n); } return c; }
ull power(ull n ,ull k,ull mod) { ull temp = 1,ans=1; while(k>0) { if(k&temp) { ans = mulmod(ans,n,mod); k-=temp; } temp <<=1; n = mulmod(n,n,mod); } return ans%mod; }
bool passesMiLLerRabin(unsigned long long N) { if(N < 2) return false; if( N % 2 == 0) return N == 2; if( N % 3 == 0) return N == 3; if( N % 5 == 0) return N == 5; if( N % 7 == 0) return N == 7; int d = 0; long long odd = N - 1; while( (odd & 1) == 0) { d++; odd>>= 1; } for(int i = 0; i < maxIter; i++) { long long a = rand() % ( N - 1) + 1; // a is random number from 1 to N -1 long long mod = modulo( a, odd, N); bool passes = ( mod == 1 || mod == N -1 ); for(int r = 1; r < d && !passes; r ++) { mod = mulmod( mod, mod, N); passes = passes || mod == N - 1; } if(!passes) return false; } return true; }
ll rho(ll n) { if ((n & 1) == 0) return 2; ll x = 2, y = 2, d = 1; ll c = rand() % n + 1; while (d == 1) { x = (mulmod(x, x, n) + c) % n; y = (mulmod(y, y, n) + c) % n; y = (mulmod(y, y, n) + c) % n; if (x - y >= 0) d = gcd(x - y, n); else d = gcd(y - x, n); } return d == n ? rho(n) : d; }
/* * Miller-Rabin primality test, iteration signifies the accuracy */ bool EulerUtility::isPrime(ll p, int iteration) { if ((p < 2) || (p != 2 && p % 2 == 0)) return false; ll s = p - 1; while (s % 2 == 0) s /= 2; for (int i = 0; i < iteration; i++) { ll a = rand() % (p - 1) + 1, temp = s; ll mod = modulo(a, temp, p); while (temp != p - 1 && mod != 1 && mod != p - 1) { mod = mulmod(mod, mod, p); temp *= 2; } if (mod != p - 1 && temp % 2 == 0) return false; } return true; }
bool is_prime_fast(long long n) { static const int np = 9, p[] = {2, 3, 5, 7, 11, 13, 17, 19, 23}; for (int i = 0; i < np; i++) { if (n % p[i] == 0) { return n == p[i]; } } if (n < p[np - 1]) { return false; } uint64 t; int s = 0; for (t = n - 1; !(t & 1); t >>= 1) { s++; } for (int i = 0; i < np; i++) { uint64 r = powmod(p[i], t, n); if (r == 1) { continue; } bool ok = false; for (int j = 0; j < s && !ok; j++) { ok |= (r == (uint64)n - 1); r = mulmod(r, r, n); } if (!ok) { return false; } } return true; }
static int sqrmod(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); return mulmod(a, a, b, c); }
int isPrime (long p,int iteration){ // Miller-Rabin Primality Test long mulmod(long a, long b, long c); int modulo(int a,int b,int c); if(p<2){ return 0; } if(p!=2 && p%2==0){ return 0; } long long s=p-1; while(s%2==0){ s/=2; } for(int i = 0; i < iteration;i++){ long a = rand()%(p-1)+1,temp=s; long mod = modulo (a,temp,p); while (temp !=p-1 && mod != 1 && mod != p-1){ mod=mulmod(mod,mod,p); temp *= 2; } if(mod != p-1 && temp %2 ==0){ return 0; } } return 1; }
long long modulo(long long a,long long b,long long c){ long long x=1,y=a; while(b>0){ if(b%2==1){ x=mulmod(x,y,c); } y=mulmod(y,y,c); b/=2; } return x%c; }
T chineseremainder(const std::vector<T>& remainders, const std::vector<T>& moduli) { T N = 1; for (auto& v : moduli) N *= v; T x = 0; for (auto ai = remainders.begin(), ni = moduli.begin(); ai != remainders.end() && ni != moduli.end(); ai++, ni++) { if (*ai > 0) { T Nni = N / (*ni); T term = mulmod(*ai, Nni, N); term = mulmod(term, inverse(Nni, *ni), N); x += term; } } return x % N; }
__int64 powmod(__int64 b, __int64 p, __int64 n) { __int64 val; if(!n) return -1; p = p % n; if(p==0) return 1; if(p<0) p += n-1; val = 1; while(p) { if(p&1) val = mulmod(val,b,n); p = p>>1; b = mulmod(b,b,n); } return val; }
/* Naive znorder. Works well if limit is small. Note arguments. */ static UV order(UV r, UV n, UV limit) { UV j; UV t = 1; for (j = 1; j <= limit; j++) { t = mulmod(t, n, r); if (t == 1) break; } return j; }
/** * Generate a keypair for the U-LP cryptosystem. * @param size_t n - security parameter * @param size_t l - message length * @param uint64_t sk - error bound for key generation * @param uint64_t se - error bound for encryption * @param uint64_t q - modulus, must be less than 2^63 due to possible overflow problems * @param ulp_public_key** pub_key_p - pointer to a public key pointer (will be generated) * @param ulp_private_key** priv_key_p - pointer to a private key pointer (will be generated) * @return int - 0 on success, a negative value otherwise */ int ulp_generate_key_pair(size_t n, size_t l, uint64_t sk, uint64_t se, uint64_t q, ulp_public_key** pub_key_p, ulp_private_key** priv_key_p) { if(n == 0 || l == 0 || sk == 0 || se == 0 || q == 0 || pub_key_p == NULL || priv_key_p == NULL || q >= 0x8000000000000000) return -2; // allocate memory for keys ulp_public_key* pub_key = ulp_alloc_public_key(n, l); ulp_private_key* priv_key = ulp_alloc_private_key(n, l); uint64_t* SA = calloc(l*n, sizeof(q)); if(pub_key == NULL || priv_key == NULL || SA == NULL) goto fail; // store parameters in key structs pub_key->se = se; pub_key->q = q; priv_key->q = q; // sample random data int err = 0; err += get_random_numbers(pub_key->A, n*n, q); err += get_random_numbers(pub_key->P, l*n, sk); err += get_random_numbers(priv_key->S, l*n, sk); if(err != 0) goto fail; // S*A for(size_t i = 0; i < l; i++) { for(size_t j = 0; j < n; j++) { for(size_t k = 0; k < n; k++) { SA[i*n+j] = (SA[i*n+j] + mulmod(priv_key->S[i*n+k], pub_key->A[k*n+j], q)) % q; } } } // P = E - S*A for(size_t i = 0; i < l*n; i++) { pub_key->P[i] = (pub_key->P[i] + q - SA[i]) % q; } // exit properly free(SA); *pub_key_p = pub_key; *priv_key_p = priv_key; return 0; // on failure, do cleanup fail: ulp_free_public_key(pub_key); ulp_free_private_key(priv_key); free(SA); return -1; }
ll pollard_rho(ll n) { int i = 0, k = 2; ll x = 3, y = 3; // random seed = 3, other values possible while (1) { i++; x = (mulmod(x, x, n) + n - 1) % n; // generating function ll d = gcd(abs_val(y - x), n); // the key insight if (d != 1 && d != n) return d; // found one non-trivial factor if (i == k) y = x, k *= 2; } }
T AP_pow(T x, T y, T p) { T z; assert(x); assert(y); assert(y->sign == 1); assert( (!p) || (p->sign==1 && !iszero(p) && !isone(p))); if (iszero(x)) return AP_new(0); if (iszero(y)) return AP_new(1); if (isone(x)) return AP_new((((y)->digits[0]&1) == 0) ? 1 : x->sign); if (p) if (isone(y)) z = AP_mod(x, p); else { T y2 = AP_rshift(y, 1), t = AP_pow(x, y2, p); z = mulmod(t, t, p); AP_free(&y2); AP_free(&t); if (!(((y)->digits[0]&1) == 0)) { z = mulmod(y2 = AP_mod(x, p), t = z, p); AP_free(&y2); AP_free(&t); } } else if (isone(y)) z = AP_addi(x, 0); else { T y2 = AP_rshift(y, 1), t = AP_pow(x, y2, NULL); z = AP_mul(t, t); AP_free(&y2); AP_free(&t); if (!(((y)->digits[0]&1) == 0)) { z = AP_mul(x, t = z); AP_free(&t); } } return z; }
//Ps: 这里选取伪随机数方程为 F(x)= x*x+c 并默认 c = 12323。注意最大只能分解 2^62-1。 //分解失败(返回 n)就尝试变换 c,c 不得取 0 或-2。若还失败,尝试变换 X0 //PB 函数调用前先 MR 判素数,每次可以分解出一个因数(不一定是素数),需配合 MR 算法。 ll PB(ll n,int c=12323,int x0=2){ if(~n&1) return 2; ll x,y,d=1,k=0,i=1; x=y=x0; while(1){ x=(mulmod(x,x,n)+c)%n; //f(x)=x*x+c,c 可换 24251 或其他素数 d=gcd(n+x-y,n); if(d!=1 && d<n) return d; //如莫名其妙一直 TLE 可尝试 d<n 改成 d<=n,目前没碰到过 if(y==x) return n; if(++k == i) y=x,i<<=1; } }
bool rabin_miller(long long p) { if (p < 2) return false; if (p != 2 && p % 2 == 0) return false; if (p < 8) return true; long long s = p-1, val = p-1, a, m, temp; while (s % 2 == 0) s >>= 1; for (int i = 0; i < 3; ++i) { a = 1ll*rand()%val + 1ll; temp = s; m = power(a, temp, p); while (temp != (p-1) && m != 1 && m != (p-1)) { m = mulmod(m, m, p); temp <<= 1; } if (m != (p-1) && temp % 2 == 0) return false; } return true; }
int Miller(long long p,int iteration){ if(p<2)return 0; if(p!=2 && p%2==0)return 0; long long s=p-1,i; while(s%2==0)s/=2; for(i=0;i<iteration;i++){ long long a=rand()%(p-1)+1,temp=s; long long mod=powmod(a,temp,p); while(temp!=p-1 && mod!=1 && mod!=p-1){ mod=mulmod(mod,mod,p); temp *= 2; } if(mod!=p-1 && temp%2==0){ return 0; } } return 1; }
bool es_primo_prob(ll n, int a) { if (n == a) return true; ll s = 0, d = n - 1; while (d % 2 == 0) s++, d /= 2; ll x = expmod(a, d, n); if ((x == 1) || (x + 1 == n)) return true; for (int i = 0; i < s-1; ++i) { x = mulmod(x, x, n); if (x == 1) return false; if (x + 1 == n) return true; } return false; }