Esempio n. 1
0
int main()
{
    ll x, y, m, n, L, a, b, c, r, p, q, t;
    while(~scanf("%lld%lld%lld%lld%lld", &x, &y, &m, &n, &L))
    {
        b = L;
        a = n-m;
        c = x-y;
        r = gcd(a, b);
        if(c%r)
        {
            printf("Impossible\n");
            continue;
        }
        extended_euclid(a, b, p, q);
        // x = x0 + b/gcd(a,b)*t
        // y = y0 - a/gcd(a,b)*t
        // t is integer.
        
        // Calculate how many b in c*p/r at most.(c*p/r is x in ax+by=c)
        // should notice that t*b <= y
        t = c*p/r/b;  
        // Get a particular solution which x is the smallest in all solutions.
        p = c*p/r - t*b;
        if(p<0)
            p += b;
        printf("%lld\n", p);
    }
    return 0;
}
/* Euclid's Extended GCD algorithm to compute the modular inverse of an element */
void extended_euclid(long int A1, long int A2, long int A3, long int B1, long int B2,long int B3)
{
	long int Q;
	long int T1,T2,T3;

	if(B3==0){
		  gcd_value= A3;
		  mul_inverse= NOT_EXIST;
		  return;
	}

	if(B3==1){
		  gcd_value= B3;
		  mul_inverse= B2;
		  return;
	}

	Q=(int)(A3/B3);

	T1=A1-Q*B1;
	T2=A2-Q*B2;
	T3=A3-Q*B3;

	A1=B1;
	A2=B2;
	A3=B3;

	B1=T1;
	B2=T2;
	B3=T3;

	extended_euclid(A1,A2,A3,B1,B2,B3);

}
Esempio n. 3
0
int main(void)
{
  long a = 4864, b = 3458, d, x, y;

  extended_euclid(a, b, &x, &y, &d);
  printf("x = %ld y = %ld d = %ld\n", x, y, d);
  return 0;
}
Esempio n. 4
0
long inverse(long a, long n)
/* computes the inverse of a modulo n */
{
  long d, x, y;

  extended_euclid(a, n, &x, &y, &d);
  if (d == 1) return x;
  return 0;
}
Esempio n. 5
0
// finds all solutions to ax = b (mod n)
ve<int> modular_linear_equation_solver(int a, int b, int n) {
  int x, y;
  ve<int> solutions;
  int d = extended_euclid(a, n, x, y);
  if (!(b%d)) {
    x = mod (x*(b/d), n);
    for (int i = 0; i < d; i++)
      solutions.push_back(mod(x + i*(n/d), n));
  }
  return solutions;
}
Esempio n. 6
0
i64 find_inv(i64 a, i64 prime)
{

    i64 x, y, g;
    extended_euclid(a, prime, x, y, g);
    assert(g == 1);
    if(x < 0)
        x += prime;
    assert( x > 0 && x < prime);
    assert((a*x) % prime == 1);
    return x;
}
ll extended_euclid(ll a, ll b, ll &x, ll &y)
{
    if(b==0)
    {
        x=1,y=0;
        return a;
    }
    ll x1,y1;
    ll ret=extended_euclid(b,a%b,x1,y1);
    x=y1;
    y=x1-y1*(a/b);
    return ret;
}
Esempio n. 8
0
int main(int argc, char **argv){
  int i,j, r_size;
  unsigned long long tmp1, tmp2;
  unsigned long long p, q, e, d;
  unsigned long long phi, n, nn, num, encoded_num;
  unsigned long long buf;
  FILE *fid_keys;
  int fid_in, fid_out, r_count;
  fid_in = open(argv[1], O_RDONLY);
  fid_out = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 00755);
  if (strcmp(argv[3], "1") == 0){ /*1 -- encode 0 - decode*/
    fid_keys = fopen("keys", "w");
    p = prime();
    q = prime();
    n = p*q;
    while (n >= MAXN){
      p = prime();
      q = prime();
      n = p*q;
    }
    phi = (p-1)*(q-1);
    e = prime_too(phi);
    extended_euclid(e, phi, &d, &tmp1, &tmp2);
    d = d % phi;
    fprintf(fid_keys, "Secret key: %llu-%llu\nPublic key: %llu-%llu\n", d, n, e, n);
  }else{
    fid_keys = fopen("keys", "r");
    if (fscanf(fid_keys, "Secret key: %llu-%llu\nPublic key: %llu-%llu\n", &d, &n, &e, &n) < 4){puts("Make keys with param 1 first."); exit(0);};
  }
  nn = 1; r_size = 0;
  while (nn <= n) {nn <<= 8; r_size++;};
  r_size -= 1;
  if (r_size <= 0){puts("Error: Too small p, q. p*q must be bigger than 255."); exit(0);}
  printf("%d\n", r_size);
  if (strcmp(argv[3], "1") == 0){
    while (r_count = read(fid_in, num, r_size) > 0){
      encoded_num = crypt(num, d, n);
      printf("%llu\n", encoded_num);
      write(fid_out, ((char *)(&encoded_num)) + sizeof(unsigned long long) - r_count, r_count);
    }
  }else{
    while (r_count = read(fid_in, num, r_size) > 0){
      num = crypt(encoded_num, e, n);
      write(fid_out, ((char *)(&num))  + sizeof(unsigned long long) - r_count, r_count);
    }
  }
  if (close(fid_in) < 0){perror("fid_in"); exit(0);};
  if (close(fid_out) < 0){perror("fid_out"); exit(0);};
  fclose(fid_keys);
  return 0;
}
Esempio n. 9
0
void extended_euclid(ll a, ll b, ll &x, ll &y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return;
    }
    extended_euclid(b, a%b, x, y);
    ll t = x;
    x = y;
    y = t - a/b*y;
    return;
}
Esempio n. 10
0
/* Determine the value that combined with string hashes to 0 */
static char hash_zero(int *coeffs, char *string, int size, int c) {
    gcd euclid = extended_euclid(size, coeffs[c]);

    // euclid.y + size to ensure it's positive
    euclid.y = (euclid.y + size) % size;

    // Get the hash of string excluding the char at c
    int hash = universal_hash((unsigned char*)string, size);
    hash -= coeffs[c] * (unsigned char) string[c] % size;

    // size is prime so euclid.y * coeffs % size = 1
    // So hash + (size - hash) * 1 = size % size = 0
    return (size - hash) * euclid.y % size;
}
int extended_euclid(int a, int b, int& x, int& y)
{//返回a,b的最大公约数以及a,b的系数x和y
 //使得等式gcd(a, b) = d = ax + by成立
	//递归终止条件
	if(b == 0){
		int gcd = a;
		x = 1;
		y = 0;
		return(gcd);
	}
	int gcd = extended_euclid(b, a % b, x, y);
	int tmp = x;
	x = y;
	y = tmp - (a / b) * y;
	return(gcd);
}
//KEY GENERATION ALGORITHM IN RSA CRYPTOSYSTEM.
void KeyGeneration(key *pub_key, key *pvt_key)
{
long int p,q;
long int n;
long int phi_n;
long int e;
// Select p and q which are primes and p<q.
if(print_flag1)
printf("\n selecting p->\n\r");
while(1)
{
 srand((unsigned int) time(NULL));
 p = random() % LARGE;
 /* test for even number */
 if ( p & 0x01 == 0 ) continue;
 if(MillerRobinTest(p, MAX_ITERATION))
break;
}
if(print_flag1)
printf("\n selecting q->\n\r");

while(1)
{
 srand((unsigned int) time(NULL));
 q=random() % LARGE;
if( q == p)
{
 srand((unsigned int) time(NULL));
q = random() % LARGE;
continue;
}
if(MillerRobinTest(q, MAX_ITERATION))
break;

}
 // Compute n.
 if (verify_prime(p) && verify_prime(q) )
 printf("p = %ld, q = %ld are primes\n", p, q);
 else {
 //exit(0);

 return recall_key(pub_key, pvt_key);

 }
 printf("p = %ld, q = %ld\n", p, q);
 n = p * q;
 // Compute Euler's phi(totient) function
 phi_n = (p-1)*(q-1);
 // Compute e such that gcd(e,phi_n(n))=1.
 if(print_flag1)
 printf("\n selcting e->\n\r");
 while(1)
 {
 e = random()%phi_n;
 if(gcd(e, phi_n)==1)
 break;
 }
// Compute d such that ed=1(mod phi_n(n)).
 if(print_flag1)
 printf("\n selceting d->\n\r");
 extended_euclid(1, 0, phi_n, 0, 1, e);
 if(mul_inverse <0) {
 mul_inverse = - mul_inverse;
 mul_inverse = ((phi_n - 1 ) * mul_inverse) mod phi_n;
 }
 if(print_flag1)
 printf("\n phi_n= %ld\n\n",phi_n);
// Put Public Key and Private Key.
 pub_key->public_key.n = n;
 pub_key->public_key.e = e;
 pvt_key->private_key.n = n;
 pvt_key->private_key.d = mul_inverse;
} // end of KeyGeneraion()
Esempio n. 13
0
int main()
{
    //n= 100; m = 10; p = 4;
    i64 p1k = 1;
    i64 p1kinv = 0;
    for(i64 k = 2; k <= p; ++k){
        p1k *=k;
        p1k%=nmod;
    }
    i64 nr = n % nmod; //630000
    i64 mr = m % nmod; //63000 
    assert(mr < nr);
    vector<i64> v1, v2;
    v1.resize(15000, 0);
    v2.resize(15000, 0);
    vector<i64> vnum;
    vector<i64> vden;
    vnum.resize(nr-p, 1);
    vden.resize(nr-p, 0); // k= p to nr - 1, cannot have k = nr
    i64 prod = 1;
    for(i64 kk=0; kk<p; ++kk )
        prod = product_mod(prod, n-kk, nmod);

    for(i64 kk = 0; kk<(i64)vnum.size(); ++kk){
        vnum[kk] = prod;
        prod = product_mod(prod, n-p-kk, nmod);
    }
    prod = 1;
    vden[0] = 1;
    i64 x, y, gcd;
    for(i64 kk = 1; kk <= (i64)vden.size(); ++kk){
        prod = product_mod(prod, kk, nmod);
        extended_euclid(prod, nmod, x, y, gcd);
        vden[kk] = x; //actuallly it has been inversed!!!
    }
    assert(product_mod(2LL, vden[2], nmod)== 1);
    assert(product_mod(6LL, vden[3], nmod)== 1);
    
    prod = 1;
    v1[0] = 1;
    for( i64 i = 1, t = n/nmod; t > 0; --t, ++i){
        prod = product_mod(prod, t, nmod);
        v1[i] = prod;
    }
    prod = 1;
    v2[0] = 1;
    for(i64 t = 1; t <= n/nmod; ++t){
        prod = product_mod(prod, t, nmod);
        extended_euclid(prod, nmod, x, y, gcd);
        v2[t] = x;//inversed!!!!
    }
    extended_euclid(p1k,nmod, p1kinv, y, gcd);//calculate p1kinv
    
    i64 kpart =0;
    i64 kpart2 = 0;
    for(i64 kk = 0; kk < (i64)vden.size(); ++kk ){
        i64 t = product_mod(vden[kk], vnum[kk], nmod );
        kpart += kk & 1 ? -t:t;
        kpart %= nmod;
        //printf("kk=%lld, num=%lld den=%lld t=%lld kpart=%lld sum=%lld\n", kk,vnum[kk], vden[kk], t, kpart, product_mod( p1kinv, kpart, nmod));
        if(kk==mr-p-1) kpart2 = kpart;
    }
    i64 jpart = 0;
    i64 jt = 1;
    i64 t = 0;
    i64 sign = -1;
    i64 nseg = (m/nmod); //k = 0...nseg *nmod+(0, 630000)
    for(int j = 0; j < nseg; ++j){
        t = product_mod(v1[j], v2[j], nmod);    
        jt = product_mod(jt, t, nmod);
        sign = -sign;
        jpart += jt*sign;
        jpart %= nmod;
    }
    i64 sum = product_mod(jpart, kpart, nmod) + sign * product_mod(kpart2, jt, nmod);
    sum = product_mod(sum , p1kinv, nmod);
    printf("jpart=%lld kpart=%lld  kpart2=%lld jt=%lld %lld\n",jpart, kpart, kpart2, jt, sum);
}
Esempio n. 14
0
int main(int argc, char **argv){
  unsigned long long i,j;
  unsigned long long tmp1, tmp2, r_size;
  unsigned long long p, q, e, d, a;
  unsigned long long phi, n, nn, num, encoded_num;
  unsigned long long buf;
  FILE *fid_keys;
  int fid_in, fid_out, r_count;
  fid_in = open(argv[1], O_RDONLY);
  fid_out = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 00755);
  if (strcmp(argv[3], "1") == 0){ /*1 -- encode 0 - decode*/
#ifdef DEBUG
    printf("Start encode equations.\n");
#endif    
    fid_keys = fopen("keys", "w");
    p = prime();
    q = prime();
    n = p*q;
    phi = (p-1)*(q-1);
    e = prime_too(phi);
    extended_euclid(e, phi, &d, &tmp1, &tmp2);
    d = d % phi;
#ifdef DEBUG
    printf("Variables:\n p: %llu, q: %llu, n: %llu\n phi: %llu, e: %llu\n d: %llu\n=====\n", p, q, n, phi, e, d);
    printf("Secret key: %llu-%llu\nPublic key: %llu-%llu\n", d, n, e, n);
    printf("=========\nStop encode equations\n");
#endif
    fprintf(fid_keys, "Secret key: %llu-%llu\nPublic key: %llu-%llu\n", d, n, e, n);
  }else{
#ifdef DEBUG
    printf("Start decode equations.\n");
#endif

    fid_keys = fopen("keys", "r");
    if (fscanf(fid_keys, "Secret key: %llu-%llu\nPublic key: %llu-%llu\n", &d, &n, &e, &n) < 4){puts("Make keys with param 1 first."); exit(0);};
#ifdef DEBUG
    printf("Variables:\n n: %llu\n e: %llu\n d: %llu\n=====\n", n, e, d);
    printf("Secret key: %llu-%llu\nPublic key: %llu-%llu\n", d, n, e, n);
    printf("=========\nStop decode equations\n");
#endif
  }
  nn = 1; r_size = 0;
  while (nn <= n) {nn <<= 8; r_size+=1;};
  r_size -= 1;
  if (r_size <= 0){puts("Error: Too small p, q. p*q must be bigger than 255."); exit(0);}
  printf("%d\n", r_size);
  if (strcmp(argv[3], "1") == 0){
    while (r_count = read(fid_in, num, r_size) > 0){
      encoded_num = crypt(num, d, n);
      printf("%llu\n", encoded_num);
      write(fid_out, ((char *)(&encoded_num)) + sizeof(unsigned long long) - r_count, r_count);
    }
  }else{
    while (r_count = read(fid_in, num, r_size) > 0){
      num = crypt(encoded_num, e, n);
      write(fid_out, ((char *)(&num))  + sizeof(unsigned long long) - r_count, r_count);
    }
  }
  if (close(fid_in) < 0){perror("fid_in"); exit(0);};
  if (close(fid_out) < 0){perror("fid_out"); exit(0);};
  fclose(fid_keys);
  return 0;
}
/* Print n strings that are hashed to 0 by universal_hash seeded with seed */
void collide_clever(unsigned int size, unsigned int seed, int n) {

	const int MAX_SIZE = 10;
	srand(seed);
	
	fprintf(stdout, "%d\n", MAXSTRLEN);

	int r[MAXSTRLEN] = { -1 };

	//Print out all the r values
	size_t i;
	if(r[0] == -1){
		for(i = 0; i < MAXSTRLEN; i++)
		{
			r[i] = rand()%size;
			fprintf(stdout, "%d\n", r[i]);
			
		}
	}
	
	//Haven't really tested for large n values, as the requirements state full marks for n=2;
	//Currently I have n =10, which is satisfactory.
	if(n > MAX_SIZE)
		{
			fprintf(stdout, "Unknown results at n > %d, (n = %d was chosen) exiting...", MAX_SIZE, n);
			return;
		}
	
	char* keys[n]; 
	
	int j;
	 for(j = 0; j < n; j++)
	{
		long x, y, d;
		extended_euclid(r[j], size, &x, &y, &d);
		keys[j] = malloc(n* sizeof(char*));
		//We don't like these ASCII characters, so don't use them
		while(x < 33)
			x += size;
		
		//if r[j] is zero it will always hash to 0, don't 
		//need to find the zero mod
		if(r[j]!=0)
			x = x*r[j]-1;
		
		//We want x to be a char, therefore it must be less than MAXSTRLEN
		while(x > MAXSTRLEN)
			x -= size;
		
		//malloc the key everytime to ensure we get a new string
		char* key = (char*)malloc(2 * sizeof(char));

		//Copy the previous string into the new one, then concatenate the 
		//current string
		if(j>0)
		{
			//If we are on the second string, then concatenate the first string, to produce strings of significant length.
			key[0] = x;
			key[1] = '\0'; 
			strcpy(keys[j], keys[j-1]);
			strcat(keys[j],key);

		}
		else
		{	
			key[0] = x;
			key[1] = '\0'; 
			keys[j] = key;
		}
		
		
		//This loop checks to see if we can generate anymore ASCII characters without having to increase our length by 1.
		//Not really part of the requirements but is still nice to have, so we don't always end up generating the same ASCII character
		//each time we increase the string length.
		while((x - size) >= 33 && (j +1) < n)
			{
				x-= size;
				j++;
				char* key = (char*)malloc(2 * sizeof(char));
				keys[j] = malloc(10 * sizeof(char*));
				key[0] = x;
				key[1] = '\0'; 
				strcpy(keys[j], keys[j-1]);
				strcat(keys[j],key);
			}
		
	} 
	

	
	for(j = 0 ; j < n; j++)
	{
		fprintf( stdout, "%s\n", keys[j]);
	}
	

	
}
Esempio n. 16
0
// find z such that z % x = a, z % y = b.  Here, z is unique modulo M = lcm(x,y).
// Return (z,M).  On failure, M = -1.
pii chinese_remainder_theorem(int x, int a, int y, int b) {
  int s, t;
  int d = extended_euclid(x, y, s, t);
  if (a%d != b%d) return make_pair(0, -1);
  return make_pair(mod(s*b*x+t*a*y,x*y)/d, x*y/d);
}
Esempio n. 17
0
// computes b such that ab = 1 (mod n), returns -1 on failure
int mod_inverse(int a, int n) {
  int x, y;
  int d = extended_euclid(a, n, x, y);
  if (d > 1) return -1;
  return mod(x,n);
}
Esempio n. 18
0
template<typename T> T mod_inverse(T a, T n){T x,y;T d = extended_euclid(a, n, x, y);return (d>1?-1:mod_neg(x,n));}