void extended_gcd_Test() { std::cout << "extended gcd ... "; int gcd, x, y; bool pass = true; extended_gcd(10,2,gcd,x,y); pass &= (gcd==2)&&((10*x + 2*y) == gcd); extended_gcd(3458,4864,gcd,x,y); pass &= (gcd==38)&&((3458*x + 4864*y) == gcd); if(pass) std::cout << "PASS" << std::endl; else std::cout << "FAIL" << std::endl; }
vector <int> residue(int p,int N,int a) { int g=primitive_root(p); long long m=discrete_log(g,a,p); vector<int> ret; if (a==0) { ret.push_back(0); return ret; } if (m==-1) return ret; long long A=N,B=p-1,C=m,x,y; long long d=extended_gcd(A,B,x,y); if (c%d!=0) return ret; x=x*(C/d)%B; long long delta=B/d; for (int i=0;i<d;i++) { x=((x+delta)%B+B)%B; ret.push_back((int)pow_mod(g,x,p)); } sort(ret.begin(),ret.end()); ret.erase(unqinue(ret.begin(),ret.end()),ret.end()); return ret; }
static std::pair<T, T> extended_gcd(T a, T b) { if(b == 0) { return std::pair<T, T>(1, 0); } const auto p = extended_gcd(b, a % b); return std::pair<T, T>(p.second, p.first - a / b * p.second); }
long long extended_gcd(long long a, long long b, long long& x, long long& y){ if (!b){ y = 0, x = 1; return a; } long long g = extended_gcd(b, a % b, y, x); y -= ((a / b) * x); return g; }
INT base::invert_mod(base &p) { base u, v, g; // cout << "base::invert_mod() this=" << *this << endl; extended_gcd(p, u, v, g, 0); // cout << "base::invert_mod(): gcd = " << g << " = " << u << " * " << *this << " + " << v << " * " << p << endl; if (!g.is_one()) { return FALSE; } swap(u); // normalize(p); return TRUE; }
int main() { long long int a, b, x, y, r; while(scanf("%lld %lld", &a, &b) == 2) { x = a; y = b; while(y > 0) { r = x % y; x = y; y = r; } extended_gcd(a, b); printf("%lld %lld %lld\n", lastx, lasty, x); } return 0; }
INT unipoly::is_squarefree(INT verbose_level) { INT f_v = (verbose_level >= 1); unipoly a, u, v, g; INT d; a = *this; a.derive(); if (f_v) { cout << "unipoly::is_squarefree() derivative p' = " << a << endl; } extended_gcd(a, u, v, g, verbose_level - 2); if (f_v) { cout << "unipoly::is_squarefree() gcd(p, p') = " << g << endl; } d = g.degree(); if (d >= 1) return FALSE; else return TRUE; }
long long mod_inverse(long long a, long long m){ long long x, y; extended_gcd(a, m, x, y); return (x + m) % m; }
inline long long inverse(int k){ extended_gcd(k,P); return (x%P+P)%P; }
void extended_gcd(const int a,const int b){ if(!b){ x=1; y=0; return; } extended_gcd(b,a%b); t=x; x=y; y=t-a/b*y; }
LL modinv(LL a_,LL m_){ //ax === gcd(a,m) (mod m) return (extended_gcd(a_,m_).first % m_ + m_) % m_; }
pair<LL,LL> extended_gcd(LL a_,LL b_){ //ax+by = gcd(a,b) if(!b_) return make_pair(1,0); pair<LL,LL> retval = extended_gcd(b_,a_%b_); return make_pair(retval.second,retval.first - ((a_/b_) * retval.second)); }
/* ---------------------------------------------------------------------------- * Funktion: calculate_rsa_keys * ------------------------------------------------------------------------- */ extern void calculate_rsa_keys(void) { int p = 0; /* p und q sind zwei zufällig ausgewählte Primzahlen */ int q = 0; /* im Intervall von 2 bis LIMIT */ int phi_n; /* Wert der Eulerschen phi-Funktion: (p - 1) * (q - 1) */ int e = 0; /* Exponent des öffentlichen Schlüssels */ int d = 0; /* Exponent des privaten Schlüssels */ int n; /* RSA-Modul */ int gcd; /* ggt von e und n */ int d_and_k[2] = {0}; /* Hilfsvektor, um die beiden Werte d und k, die im * erweiterten Euklidschen Algorithmus berechnet werden, * zurückzugeben. */ BOOL found_e; /* TRUE, wenn ein teilerfremdes e zu n gefunden wurde, * FALSE sonst. */ /* Berechnung der Primzahlen von 2 bis PRIME_LIMIT */ generate_primes(PRIME_LIMIT); /* * Wähle zwei zufällige Primzahlen, so dass deren Produkt (das RSA-Modul) * größer als der ASCII-Wert des größten zu verschlüsselnden * Zeichens ist und kleiner als die Zahl (PRIME_LIMIT), die die * RSA-Schlüssel nicht überschreiten dürfen. */ n = 0; while (n <= MAX_CHAR || n >= PRIME_LIMIT) { p = get_random_prime(LIMIT); q = get_random_prime(LIMIT); n = p * q; } #ifdef DEBUG DPRINT(p); DPRINT(q); DPRINT(n); #endif /* Berechne die eulersche Phi-Funktion von p und q */ phi_n = (p - 1) * (q - 1); #ifdef DEBUG DPRINT(phi_n); #endif /* * Wähle eine zu phi_n teilerfremde Zahl e und berechne d, so dass gilt: * d > 1, e != d, e * d + k * phi_n = 1 = ggt(e, phi_n) */ gcd = -1; while (d <= 1 || d == e || gcd != 1) { /* * Wähle eine Primzahl e, so dass e kleiner ist als phi_n und * e kein Teiler von phi_n ist --> e und phi_n sind teilerfremd. */ found_e = FALSE; while (found_e == FALSE) { e = get_random_prime(phi_n); if (e < phi_n && phi_n % e != 0) { found_e = TRUE; } } #ifdef DEBUG DPRINT(e); #endif /* * Bestimme die Zahl d mit dem erweiterten euklidschen Algorithmus, * so dass gilt: e * d + k * phi_n = 1 = ggT(e, phi_n) */ gcd = extended_gcd(e, phi_n, d_and_k); d = d_and_k[0]; } #ifdef DEBUG DPRINT(phi_n); DPRINT(e); DPRINT(n); DPRINT(d); #endif /* Globale Variablen auf die generierten Schlüsselwerte setzen */ rsa_modul = n; public_exponent = e; secret_exponent = d; #ifdef DEBUG printf("Es wurde folgendes Schluesselpaar erzeugt:\n"); printf("oeffentlicher Schluessel: (%4d, %4d)\n", e, n); printf("privater Schluessel : (%4d, %4d)\n", d, n); printf("\n"); #endif }
LL inv(LL a,LL n) { LL xx,yy,d=extended_gcd(a,n,xx,yy); return (xx%n+n)%n; }