Advertisement
Metalhead33

Eucledian Algorithm for Linear Congruence (C version)

Apr 25th, 2017
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.04 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <stdlib.h>
  4. #include <time.h>
  5.  
  6. typedef struct t_eucledian_field {
  7.     int a;
  8.     int b;
  9.     int a_per_b;
  10.     int x;
  11.     int y;
  12.     struct t_eucledian_field* next;
  13.     struct t_eucledian_field* prev;
  14. } EucledianField;
  15.  
  16. typedef EucledianField* EucledianTableEntry;
  17. EucledianTableEntry FindFirst(EucledianTableEntry anchor);
  18. EucledianTableEntry FindLast(EucledianTableEntry anchor);
  19. void FreeField(EucledianTableEntry anchor);
  20. EucledianTableEntry CalculateGreatestCommonDenom(int xa, int yb);
  21. EucledianTableEntry EucledianAlgorithm(int xa, int yb);
  22.  
  23. typedef struct t_rsa_coder {
  24.     int p;
  25.     int q;
  26.     int n; // n = p * q
  27.     int e; // relative prime to (p-1)*(q-1)
  28.     int d; // (e*d) % (p-1)*(q-1) = 1
  29.     // n and e are public
  30.     // p, q, d are private
  31. } RsaCoder;
  32. typedef RsaCoder* Coder;
  33.  
  34. Coder GenerateCoder(int p, int q);
  35. int modpower(int x, unsigned int y, int p);
  36. int code(int signal, Coder rsa);
  37. int decode(int signal, Coder rsa);
  38. char prime(int n);
  39.  
  40. int main(void) {
  41.     // your code goes here
  42.     /*EucledianTableEntry a = EucledianAlgorithm(2070,125);
  43.     EucledianTableEntry to_delete = a;
  44.     do {
  45.         printf("A: %d \t B: %d \t A\\B: %d \t X: %d \t Y: %d \n",a->a,a->b,a->a_per_b,a->x,a->y);
  46.         //to_delete = a;
  47.         a = a->next;
  48.         //free(to_delete);
  49.     }while (a);
  50.     FreeField(to_delete);*/
  51.     Coder a;
  52.     int p;
  53.     int q;
  54.     srand(time(NULL));
  55.     p = 3 + rand() % 13;
  56.     q = rand() % (p - 3);
  57.     a = GenerateCoder(p,q);
  58.     printf("Coder:\n P=%d \n Q=%d \n N=%d \n E=%d \n D=%d\n\n",a->p, a->q, a->n, a->e, a->d);
  59.     printf("Coding and decoding: 2 -> %d -> %d\n",code(2,a),decode(code(2,a),a) );
  60.     return 0;
  61. }
  62. EucledianTableEntry FindFirst(EucledianTableEntry anchor)
  63. {
  64.     EucledianTableEntry tmp = anchor;
  65.     if(!anchor->prev) return tmp; // Already first
  66.     do
  67.     {
  68.         tmp = tmp->prev;
  69.     } while(tmp->prev);
  70.     return tmp;
  71. }
  72. EucledianTableEntry FindLast(EucledianTableEntry anchor)
  73. {
  74.     EucledianTableEntry tmp = anchor;
  75.     if(!anchor->next) return tmp; // Already last
  76.     do
  77.     {
  78.         tmp = tmp->next;
  79.     } while(tmp->next);
  80.     return tmp;
  81. }
  82. void FreeField(EucledianTableEntry anchor)
  83. {
  84.     EucledianTableEntry tmp = FindFirst(anchor);
  85.     do
  86.     {
  87.         tmp = tmp->next;
  88.         free(tmp->prev);
  89.     } while(tmp->next);
  90.     free(tmp);
  91. }
  92. EucledianTableEntry CalculateGreatestCommonDenom(int xa, int yb)
  93. {
  94.     EucledianTableEntry first=0,tmp=0,anchor=0;
  95.     first = (EucledianTableEntry)malloc(sizeof(EucledianField));
  96.     tmp = first;
  97.     if(xa > yb)
  98.     {
  99.     tmp->a = xa;
  100.     tmp->b = yb;
  101.     }
  102.     else
  103.     {
  104.         tmp->a = yb;
  105.         tmp->b = xa;
  106.     }
  107.     tmp->a_per_b = tmp->a / tmp->b;
  108.     tmp->x = 0;
  109.     tmp->y = 0;
  110.     tmp->prev = 0;
  111.     tmp->next = 0;
  112.     //printf("A: %d \t B: %d \t A\\B: %d\n",tmp->a,tmp->b,tmp->a_per_b);
  113.     do {
  114.         anchor = tmp;
  115.         tmp = (EucledianTableEntry)malloc(sizeof(EucledianField));
  116.         anchor->next = tmp;
  117.         tmp->prev = anchor;
  118.         tmp->next = 0;
  119.         tmp->a = anchor->b;
  120.         tmp->b = anchor->a % anchor->b;
  121.         if(tmp->b) tmp->a_per_b = tmp->a / tmp->b;
  122.         else tmp->a_per_b = 1;
  123.         tmp->x = 0;
  124.         tmp->y = 0;
  125.         //printf("A: %d \t B: %d \t A\\B: %d\n",tmp->a,tmp->b,tmp->a_per_b);
  126.     } while(tmp->b);
  127.     return first;
  128. }
  129. EucledianTableEntry EucledianAlgorithm(int xa, int yb)
  130. {
  131.     EucledianTableEntry first=0,anchor=0;
  132.     first = CalculateGreatestCommonDenom(xa,yb);
  133.     anchor = FindLast(first); // We start from the end.
  134.     anchor->x = anchor->a;
  135.     anchor->y = anchor->b;
  136.     anchor = anchor->prev;
  137.     do {
  138.         anchor->x = anchor->next->y;
  139.         anchor->y = anchor->next->x - (anchor->a_per_b * anchor->next->y);
  140.         anchor = anchor->prev;
  141.     } while(anchor);
  142.     return first;
  143. }
  144. /* Iterative Function to calculate (x^y)%p in O(log y) */
  145. int modpower(int x, unsigned int y, int p)
  146. {
  147.     int res = 1;      // Initialize result
  148.  
  149.     x = x % p;  // Update x if it is more than or
  150.                 // equal to p
  151.  
  152.     while (y > 0)
  153.     {
  154.         // If y is odd, multiply x with result
  155.         if (y & 1)
  156.             res = (res*x) % p;
  157.  
  158.         // y must be even now
  159.         y = y>>1; // y = y/2
  160.         x = (x*x) % p;  
  161.     }
  162.     return res;
  163. }
  164.  
  165. Coder GenerateCoder(int p, int q)
  166. {
  167.     Coder temp;
  168.     EucledianTableEntry counter;
  169.     temp = (Coder)malloc(sizeof(RsaCoder));
  170.     temp->p = primize(p);
  171.     temp->q = primize(q);
  172.     if(temp->q == temp->p)
  173.     {
  174.         temp->q = primize(temp->p+2);
  175.     }
  176.     if(temp->q < temp->p) temp->e = primize(temp->p + 2);
  177.     else temp->e = primize(temp->q + 2);
  178.     temp->n = temp->q * temp->p;
  179.     counter = EucledianAlgorithm((temp->p - 1) * (temp->q - 1),temp->e);
  180.     temp->d = counter->y;
  181.     if(temp->d < 0) temp->d += counter->a;
  182.     FreeField(counter);
  183.     return temp;
  184. }
  185. int code(int signal, Coder rsa)
  186. {
  187.     return modpower(signal,rsa->e,rsa->n);
  188. }
  189. int decode(int signal, Coder rsa)
  190. {
  191.     return modpower(signal,rsa->d,rsa->n);
  192. }
  193. char prime(int n)
  194. {
  195.     int i;
  196.     char flag = 0;
  197.     for(i=2; i<=n/2; ++i)
  198.     {
  199.         // condition for nonprime number
  200.         if(n%i==0)
  201.         {
  202.             flag=1;
  203.             break;
  204.         }
  205.     }
  206.     return !flag;
  207. }
  208. int primize(int n)
  209. {
  210.     int tmp = n;
  211.     if(prime(tmp)) return tmp;
  212.     else
  213.     {
  214.         do
  215.         {
  216.             ++tmp;
  217.         } while(!prime(tmp));
  218.     }
  219.     return tmp;
  220. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement