[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
No Subject
/* 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);
}
}