Исходные тексты на языке C алгоритмов шифрования DES и ГОСТ из книги Б.Шнайера (1014278), страница 2
Текст из файла (страница 2)
Caller is responsible forshort blocks. */void des_enc(des_ctx *dc, unsigned char *data, int blocks){unsigned long work[2];int i;unsigned char *cp;}cp = data;for(i=0;i<blocks;i++){scrunch(cp,work);desfunc(work,dc->ek);unscrun(work,cp);cp+=8;}void des_dec(des_ctx *dc, unsigned char *data, int blocks){unsigned long work[2];int i;unsigned char *cp;}cp = data;for(i=0;i<blocks;i++){scrunch(cp,work);desfunc(work,dc->dk);unscrun(work,cp);cp+=8;}void main(void){des_ctx dc;int i;unsigned long data[10];char *cp,key[8] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};char x[8] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xe7};cp = x;des_key(&dc,key);9des_enc(&dc,cp,1);printf("Enc(0..7,0..7) = ");for(i=0;i<8;i++) printf("%02x ", ((unsigned int) cp[i])&0x00ff);printf("\n");des_dec(&dc,cp,1);printf("Dec(above,0..7) = ");for(i=0;i<8;i++) printf("%02x ",((unsigned int)cp[i])&0x00ff);printf("\n");cp = (char *) data;for(i=0;i<10;i++)data[i]=i;des_enc(&dc,cp,5); /* Enc 5 blocks.
*/for(i=0;i<10;i+=2) printf("Block %01d = %08lx %08lx.\n",i/2,data[i],data[i+1]);des_dec(&dc,cp,1);des_dec(&dc,cp+8,4);for(i=0;i<10;i+=2) printf("Block %01d = %08lx %08lx.\n",i/2,data[i],data[i+1]);}LOKI91#include <stdio.h>#define LOKIBLK*/#define ROUNDS*/8/* No of bytes in a LOKI data-block16/* No of LOKI roundstypedef unsigned longLOKI blocks */Long;extern Longextern charcopyright/* 64-bit key used by LOKI routines/* String with version no. &lokikey[2];*loki_lib_ver;*//* type specification for aligned*/#ifdef __STDC__/* declare prototypes for libraryfunctions */extern void enloki(char *b);extern void deloki(char *b);extern void setlokikey(char key[LOKIBLK]);#else/* else just declare library functions extern*/extern void enloki(), deloki(), setlokikey();#endif __STDC__char P[32] = {31, 23,29, 21,27, 19,25, 17,};15, 7, 30, 22, 14, 6,13, 5, 28, 20, 12, 4,11, 3, 26, 18, 10, 2,9, 1, 24, 16, 8, 010for(i=0;i<10;i++) long_block[i] = i;idea_enc(&c,lbp,5);for(i=0;i<10;i+=2) printf("Block %01d = %08lx %08lx.\n",i/2,long_block[i],long_block[i+1]);idea_dec(&c,lbp,3);idea_dec(&c,lbp+24,2);for(i=0;i<10;i+=2) printf("Block %01d = %08lx %08lx.\n",i/2,long_block[i],long_block[i+1]);return 0;} /* main *//* normal exit */GOSTtypedef unsigned long u4;typedef unsigned char byte;typedef struct {u4 k[8];/* Constant s-boxes -- set up in gost_init().
*/char k87[256],k65[256],k43[256],k21[256];} gost_ctx;/* Note:voidvoidvoidvoidvoidencrypt and decrypt expect full blocks--padding blocks iscaller's responsibility. All bulk encryption is done inECB mode by these calls. Other modes may be added easilyenough.gost_enc(gost_ctx *, u4 *, int);gost_dec(gost_ctx *, u4 *, int);gost_key(gost_ctx *, u4 *);gost_init(gost_ctx *);gost_destroy(gost_ctx *);#ifdef __alpha /* Any other 64-bit machines? */typedef unsigned int word32;#elsetypedef unsigned long word32;#endifkboxinit(gost_ctx *c){int i;byte k8[16] = {14,12,byte k7[16] = {15,13,byte k6[16] = {10,7,byte k5[16] = { 7,5,byte k4[16] = { 2,15,byte k3[16] = {12,4,4,5,1,12,0,11,13,11,12,13,1,14,13,9,8,0,9,4,14,12,4,0,10,7,1, 2, 15, 11, 8,0, 7 };14, 6, 11, 3, 4,5, 10 };14, 6, 3, 15, 5,2, 8 };3, 0, 6, 9, 10,4, 15 };1, 7, 10, 11, 6,14, 9 };15, 9, 2, 6, 8,5, 11 };3, 10,6,9,2,7,1, 13, 12,1,2,8,8,5,3,0, 13,3,*/11byte k2[16] = { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12,7, 5, 10, 6, 1 };byte k1[16] = {13, 2, 8, 4, 6, 15, 11, 1, 10, 9,14, 5, 0, 12, 7 };}for (i = 0; i < 256;c->k87[i]c->k65[i]c->k43[i]c->k21[i]}i++) {= k8[i= k6[i= k4[i= k2[i>>>>>>>>4]4]4]4]<<<<<<<<4444||||k7[ik5[ik3[ik1[i&&&&9,3,15];15];15];15];static word32f(gost_ctx *c,word32 x){x = c->k87[x>>24 & 255] << 24 | c->k65[x>>16 & 255] << 16 |c->k43[x>> 8 & 255] << 8 | c->k21[x & 255];}/* Rotate left 11 bits */return x<<11 | x>>(32-11);void gostcrypt(gost_ctx *c, word32 *d){register word32 n1, n2; /* As named in the GOST */n1 = d[0];n2 = d[1];/* Instead of swapping halves, swap names each round */n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);}n2n2n2n2^=^=^=^=f(c,n1+c->k[0]);f(c,n1+c->k[2]);f(c,n1+c->k[4]);f(c,n1+c->k[6]);n1n1n1n1^=^=^=^=f(c,n2+c->k[1]);f(c,n2+c->k[3]);f(c,n2+c->k[5]);f(c,n2+c->k[7]);n2n2n2n2^=^=^=^=f(c,n1+c->k[0]);f(c,n1+c->k[2]);f(c,n1+c->k[4]);f(c,n1+c->k[6]);n1n1n1n1^=^=^=^=f(c,n2+c->k[1]);f(c,n2+c->k[3]);f(c,n2+c->k[5]);f(c,n2+c->k[7]);n2n2n2n2^=^=^=^=f(c,n1+c->k[7]);f(c,n1+c->k[5]);f(c,n1+c->k[3]);f(c,n1+c->k[1]);n1n1n1n1^=^=^=^=f(c,n2+c->k[6]);f(c,n2+c->k[4]);f(c,n2+c->k[2]);f(c,n2+c->k[0]);d[0] = n2; d[1] = n1;voidgostdecrypt(gost_ctx *c, u4 *d){register word32 n1, n2; /* As named in the GOST */n1 = d[0]; n2 = d[1];n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);12n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);}n2n2n2n2^=^=^=^=f(c,n1+c->k[7]);f(c,n1+c->k[5]);f(c,n1+c->k[3]);f(c,n1+c->k[1]);n1n1n1n1^=^=^=^=f(c,n2+c->k[6]);f(c,n2+c->k[4]);f(c,n2+c->k[2]);f(c,n2+c->k[0]);n2n2n2n2^=^=^=^=f(c,n1+c->k[7]);f(c,n1+c->k[5]);f(c,n1+c->k[3]);f(c,n1+c->k[1]);n1n1n1n1^=^=^=^=f(c,n2+c->k[6]);f(c,n2+c->k[4]);f(c,n2+c->k[2]);f(c,n2+c->k[0]);n2n2n2n2^=^=^=^=f(c,n1+c->k[7]);f(c,n1+c->k[5]);f(c,n1+c->k[3]);f(c,n1+c->k[1]);n1n1n1n1^=^=^=^=f(c,n2+c->k[6]);f(c,n2+c->k[4]);f(c,n2+c->k[2]);f(c,n2+c->k[0]);d[0] = n2; d[1] = n1;void gost_enc(gost_ctx *c, u4 *d, int blocks){int i;}for(i=0;i<blocks;i++){gostcrypt(c,d);d+=2;}void gost_dec(gost_ctx *c, u4 *d, int blocks){int i;}for(i=0;i<blocks;i++){gostdecrypt(c,d);d+=2;}void gost_key(gost_ctx *c, u4 *k){int i;for(i=0;i<8;i++) c->k[i]=k[i];}void gost_init(gost_ctx *c){kboxinit(c);}void gost_destroy(gost_ctx *c){int i;for(i=0;i<8;i++) c->k[i]=0;}void main(void){gost_ctx gc;u4 k[8],data[10];int i;/* Initialize GOST context.
*/gost_init(&gc);/* Prepare key--a simple key should be OK, with this many rounds! */for(i=0;i<8;i++) k[i] = i;13gost_key(&gc,k);/* Try some test vectors. */data[0] = 0; data[1] = 0;gostcrypt(&gc,data);printf("Enc of zero vector: %08lx %08lx\n",data[0],data[1]);gostcrypt(&gc,data);printf("Enc of above:%08lx %08lx\n",data[0],data[1]);data[0] = 0xffffffff; data[1] = 0xffffffff;gostcrypt(&gc,data);printf("Enc of ones vector: %08lx %08lx\n",data[0],data[1]);gostcrypt(&gc,data);printf("Enc of above:%08lx %08lx\n",data[0],data[1]);/* Does gost_dec() properly reverse gost_enc()? Dowe deal OK with single-block lengths passed in gost_dec()?Do we deal OK with different lengths passed in? *//* Init data */for(i=0;i<10;i++) data[i]=i;/* Encrypt data as 5 blocks. */gost_enc(&gc,data,5);/* Display encrypted data.
*/for(i=0;i<10;i+=2) printf("Block %02d = %08lx %08lx\n",i/2,data[i],data[i+1]);/* Decrypt in different sized chunks. */gost_dec(&gc,data,1);gost_dec(&gc,data+2,4);printf("\n");/* Display decrypted data. */for(i=0;i<10;i+=2) printf("Block %02d = %08lx %08lx\n",i/2,data[i],data[i+1]);}gost_destroy(&gc);BLOWFISH#include#include#include#include<math.h><stdio.h><stdlib.h><time.h>#ifdef little_endian#include <alloc.h>#endif/* Eg: Intel */#include <ctype.h>#ifdef little_endian#include <dir.h>#include <bios.h>#endif/* Eg: Intel */.