/* SAFER SK-64 By James L. Massey who did not do this conversion and is not responsible for any bugs in it. This a 'C' conversion of the reference Turbo Pascal implementation Examples of Encryption with SAFER SK-64 (i.e., with the strengthened key schedule of 64 bits.) PLAINTEXT is 1 2 3 4 5 6 7 8 The KEY is 0 0 0 0 0 0 0 1 after round 1 131 177 53 27 130 249 141 121 after round 2 68 73 32 102 134 54 206 57 after round 3 248 213 217 11 23 68 0 243 after round 4 194 62 109 79 24 18 13 84 after round 5 153 156 246 172 40 72 173 39 after round 6 154 242 34 6 61 35 216 28 CRYPTOGRAM is 21 27 255 2 173 17 191 45 PLAINTEXT is 1 2 3 4 5 6 7 8 The KEY is 1 2 3 4 5 6 7 8 after round 1 223 98 177 100 46 234 13 210 after round 2 182 246 230 93 158 14 48 89 after round 3 45 234 128 149 40 101 10 134 after round 4 30 17 249 236 158 120 69 100 after round 5 1 200 182 241 0 127 152 162 after round 6 144 85 94 214 5 38 65 150 CRYPTOGRAM is 95 206 155 162 5 132 56 199 */ #include <stdio.h> /* globals */ unsigned char a1,a2,a3,a4,a5,a6,a7,a8, b1,b2,b3,b4,b5,b6,b7,b8, r; unsigned char k[21][8],k1[9]; int logtab[256],exptab[256],i,j,n; mat1(p1,p2,q1,q2) unsigned char p1,p2,*q1,*q2; { *q2=p1+p2; *q1=*q2+p1; } invmat1(p1,p2,q1,q2) unsigned char p1,p2,*q1,*q2; { *q1=p1-p2; *q2=-*q1+p2; } init_tables() { /* This portion of the program computes the powers of the primitive element 45 of the finite field GF(257) and stores these numbers in the table "exptab". The corresponding logarithms to the base 45 are stored in the table "logtab" */ logtab[1]=0; exptab[0]=1; for(i=1;i<=255;i++) { exptab[i]=(45*exptab[i-1]) % 257; logtab[exptab[i]]=i; } exptab[128]=0; logtab[0]=128; exptab[0]=1; } set_rounds() { int rounds; do { printf("Enter number of rounds (max 10): "); scanf("%d",&rounds); } while(rounds<1 || rounds>10); r=(unsigned char)rounds; } get_plaintext() { int i1,i2,i3,i4,i5,i6,i7,i8; printf("Enter plaintext as 8 bytes (0-255 separated by spaces)\n"); scanf("%d%d%d%d%d%d%d%d",&i1,&i2,&i3,&i4,&i5,&i6,&i7,&i8); a1=(unsigned char)i1; a2=(unsigned char)i2; a3=(unsigned char)i3; a4=(unsigned char)i4; a5=(unsigned char)i5; a6=(unsigned char)i6; a7=(unsigned char)i7; a8=(unsigned char)i8; } get_key() { int i1,i2,i3,i4,i5,i6,i7,i8; printf("Enter key as 8 bytes (0-255 separated by spaces)\n"); scanf("%d%d%d%d%d%d%d%d",&i1,&i2,&i3,&i4,&i5,&i6,&i7,&i8); k[0][0]=k1[0]=(unsigned char)i1; k[0][1]=k1[1]=(unsigned char)i2; k[0][2]=k1[2]=(unsigned char)i3; k[0][3]=k1[3]=(unsigned char)i4; k[0][4]=k1[4]=(unsigned char)i5; k[0][5]=k1[5]=(unsigned char)i6; k[0][6]=k1[6]=(unsigned char)i7; k[0][7]=k1[7]=(unsigned char)i8; } key_schedule() { /* append a "parity byte" to the key k1 */ k1[8]=k1[0]^k1[1]^k1[2]^k1[3]^k1[4]^k1[5]^k1[6]^k1[7]; /* derive keys k2, k3, ... k2r+1 from input key k1 */ for(n=2;n<=(2*r)+1;n++) { /* each byte of the key k1 is left rotated by 3 */ for(j=0;j<=8;j++) k1[j]=(k1[j]<<3) + (k1[j]>>5); /* the key bias is added here to the right rotated k1 */ for(j=1;j<=8;j++) k[n-1][j-1]=k1[(j+n-2) % 9]+exptab[exptab[(9*n)+j]]; } } encrypt() { for(i=1;i<=r;i++) { /* Key 2i-1 is mixed bit and byte added to the round input */ a1=a1 ^ k[2*i-2][0]; a2=a2 + k[2*i-2][1]; a3=a3 + k[2*i-2][2]; a4=a4 ^ k[2*i-2][3]; a5=a5 ^ k[2*i-2][4]; a6=a6 + k[2*i-2][5]; a7=a7 + k[2*i-2][6]; a8=a8 ^ k[2*i-2][7]; /* The result now passes through the nonlinear layer */ b1=exptab[a1]; b2=logtab[a2]; b3=logtab[a3]; b4=exptab[a4]; b5=exptab[a5]; b6=logtab[a6]; b7=logtab[a7]; b8=exptab[a8]; /* Key 2i is now mixed byte and bit added to the result */ b1=b1 + k[2*i-1][0]; b2=b2 ^ k[2*i-1][1]; b3=b3 ^ k[2*i-1][2]; b4=b4 + k[2*i-1][3]; b5=b5 + k[2*i-1][4]; b6=b6 ^ k[2*i-1][5]; b7=b7 ^ k[2*i-1][6]; b8=b8 + k[2*i-1][7]; /* The result now enters the linear layer */ mat1(b1,b2,&a1,&a2); mat1(b3,b4,&a3,&a4); mat1(b5,b6,&a5,&a6); mat1(b7,b8,&a7,&a8); mat1(a1,a3,&b1,&b2); mat1(a5,a7,&b3,&b4); mat1(a2,a4,&b5,&b6); mat1(a6,a8,&b7,&b8); mat1(b1,b3,&a1,&a2); mat1(b5,b7,&a3,&a4); mat1(b2,b4,&a5,&a6); mat1(b6,b8,&a7,&a8); /* The round is now completed! */ printf("after round %d %3d %3d %3d %3d %3d %3d %3d %3d\n", (int)i,a1,a2,a3,a4,a5,a6,a7,a8); } /* Key 2r+1 is now mixed bit and byte added to produce the final cryptogram */ a1=a1 ^ k[2*r][0]; a2=a2 + k[2*r][1]; a3=a3 + k[2*r][2]; a4=a4 ^ k[2*r][3]; a5=a5 ^ k[2*r][4]; a6=a6 + k[2*r][5]; a7=a7 + k[2*r][6]; a8=a8 ^ k[2*r][7]; } main() { init_tables(); for(;;) { set_rounds(); get_plaintext(); get_key(); printf("PLAINTEXT is %3d %3d %3d %3d %3d %3d %3d %3d\n", a1,a2,a3,a4,a5,a6,a7,a8); printf("THE KEY IS %3d %3d %3d %3d %3d %3d %3d %3d\n", k[0][0],k[0][1],k[0][2],k[0][3],k[0][4],k[0][5],k[0][6],k[0][7]); key_schedule(); encrypt(); printf("CRYPTOGRAM IS %3d %3d %3d %3d %3d %3d %3d %3d\n\n", a1,a2,a3,a4,a5,a6,a7,a8); } }
participants (1)
-
Hroller Anonymous Remailer