Algoritam A5 ostvaren programskim jezikom C

 

#include<stdio.h>

#include<stdlib.h>

 

typedef struct

            {

            unsigned long r1, r2, r3;            /* 32- bitne vrijednosti, predstavljaju 3 posmačna registra */

            } a5_ctx;

 

static int threshold(unsigned int r1, unsigned int r2, unsigned int r3)

            {

            int total;

            total = (((r1>>9) & 0x1) ==1) + (((r2>>11) & 0x1) ==1) + (((r3>>11) & 0x1) == 1);

            if(total>1) return(0);      /* ispitivanje kontrolnih bitova */           

            else return(1);

 

unsigned long clock_r1(ctl, r1)  /* mijenjanje registra R1 u ovisnosti o njegovom stanju */

            {

            unsigned long feeback;

            ctl ^= ((r1>>9) & 0x1);

            if(ctl)

                        {

                        feedback=(r1>>18) ^ (r1>>17) ^ (r1>>16) ^ (r1>>13);

                        r1=(r1<<1) & 0x7ffff;

                        if(feedback & 0x01)

                        r1 ^= 0x01;

                        }

            return(r1);

            }

 

unsigned long clock_r2(ctl, r2)  /* promjene u registru R2 */

            {

            unsigned long feeback;

            ctl ^= ((r2>>11) & 0x1);

            if(ctl)

                        {

                        feedback=(r2>>21) ^ (r2>>20) ^ (r2>>16) ^ (r1>>12);

                        r2=(r2<<1) & 0x3fffff;

                        if(feedback & 0x01)

                        r2 ^= 0x01;

                        }

            return(r2);

            }

 

unsigned long clock_r3(ctl, r3)  /* promjene u registru R3 */

            {

            unsigned long feeback;

            ctl ^= ((r3>>11) & 0x1);

            if(ctl)

                        {

                        feedback=(r3>>22) ^ (r3>>21) ^ (r3>>18) ^ (r3>>17);

                        r1=(r3<<1) & 0x7fffff;

                        if(feedback & 0x01)

                        r3 ^= 0x01;

                        }

            return(r3);

            }

 

void a5_key(a5_ctx *c, char *k)         /* zapisivanje ključa u posmačne registre */

            {

            c->r1 = k[0]<<11 | k[1]<<3 | k[2]>>5;

            c->r2 = k[2]<<17 | k[3]<<9 | k[4]<<1 | k[5]>>7;

            c->r3 = k[5]<<15 | k[6]<<8 | k[7];

            }

 

int a5_step(a5_ctx *c)  /* funkcija koja vraća bit koji će biti upisan u spomenuti pomoćni bajt za kriptiranje */

            {

            int control;

            control=threshold(c->r1, c->r2, c->r3);

            c->r1=clock_r1(control, c->r1);

            c->r2=clock_r2(control, c->r2);

            c->r3=clock_r3(control, c->r3);

            return((c->r1 ^ c->r2 ^ c->r3) & 1);

            }

 

void a5_encrypt(a5_ctx *c, char *data, int len)          /* funkcija kriptiranja podataka */

            {

            int i,j;

            char t;

            for(i=0; i<len; i++)

                        {

                        for(j=0; j<8; j++)

                                    t = t<<1 | a5_step(c);   /* t predstavlja pomoćni bajt */

                        data[i] ^= t;

                        }

            }

 

void a5_decrypt(a5_ctx *c, char *data, int len)          /* funkcija dekriptiranja podataka, identièna je funkciji kriptiranja */

            {

            a5_encrypt(c, data, len);

            }

 

void main()

            {

            a5_ctx c;

            char data[100]; /* kriptiramo niz od 100 bajtova */

            char key[] = {rand(), rand(),rand(),rand(),rand(), rand(), rand(), rand()}; /* ključ je duljine 64 bita, tj. 8 bajta */

            int i;

            for(i=0; i<100; i++)

                        data[i] = rand();

            a5_key(&c, key);         /* upisivanje ključa u posmačne registre */

            a5_encrypt(&c, data,100);       /* kriptiranje podataka */

            a5_key(&c, key);         /* ponovni upis ključa u posmačne registre */

            a5_decrypt(&c, data, 100);      /* dekriptiranje podataka */

            }