208 lines
2.9 KiB
C
208 lines
2.9 KiB
C
/*
|
|
This routine is an exact implementation of Boris Hagelin's
|
|
cryptographic machine. See U. S. Patent #2,089,603.
|
|
*/
|
|
|
|
int cagetable[] { 0, 1, 1, 2, 2, 3, 4, 4, 5, 6, 8, 8, 9, 10, 12, 16,
|
|
16, 17, 18, 20, 24, 32, 32, 33, 34, 36, 40, 48};
|
|
int warr1[52];
|
|
int warr2[50];
|
|
int warr3[46];
|
|
int warr4[42];
|
|
int warr5[38];
|
|
int warr6[34];
|
|
int *wheel1 warr1;
|
|
int *wheel2 warr2;
|
|
int *wheel3 warr3;
|
|
int *wheel4 warr4;
|
|
int *wheel5 warr5;
|
|
int *wheel6 warr6;
|
|
char key[130];
|
|
int xxx;
|
|
|
|
|
|
/*
|
|
subroutine to manufacture a wheel
|
|
*/
|
|
|
|
setup(list,n) int list[];
|
|
{int *lp;
|
|
lp = list;
|
|
while(--n){
|
|
*lp = lp+2;
|
|
lp[1] = getbit();
|
|
if(xxx) putchar(lp[1]+'0');
|
|
lp = lp + 2;
|
|
}
|
|
*lp = list;
|
|
lp[1] = getbit();
|
|
if(xxx){
|
|
putchar(lp[1]+'0');
|
|
putchar('\n');
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
subroutine to return the next bit from the main routines
|
|
argument
|
|
*/
|
|
|
|
getbit(){
|
|
static i,j;
|
|
int b;
|
|
b = (key[j] >> i) & 1;
|
|
if (i++ > 5) {
|
|
j++;
|
|
i = 0;
|
|
}
|
|
return (b);
|
|
}
|
|
|
|
|
|
|
|
|
|
main(ncooky,cookyp)
|
|
int ncooky;
|
|
char *cookyp[];
|
|
{
|
|
char *ip, *jp;
|
|
int temp;
|
|
int random;
|
|
int i,j;
|
|
int precious;
|
|
int crypt;
|
|
int cage[27];
|
|
xxx = 0;
|
|
|
|
|
|
|
|
/*
|
|
copy input key and pad with clever junk
|
|
*/
|
|
|
|
jp = key;
|
|
*jp++ = 004;
|
|
*jp++ = 034;
|
|
if(ncooky > 1){
|
|
while (*jp++ = *cookyp[1]++);
|
|
jp--;
|
|
}
|
|
ip = key;
|
|
while (jp < key+128) {
|
|
*jp = jp[-1] ^ *ip++;
|
|
jp++;
|
|
}
|
|
|
|
|
|
/*
|
|
manufacture six wheels of various length
|
|
*/
|
|
|
|
setup(wheel1,26);
|
|
setup(wheel2,25);
|
|
setup(wheel3,23);
|
|
setup(wheel4,21);
|
|
setup(wheel5,19);
|
|
setup(wheel6,17);
|
|
|
|
/*
|
|
set up the cage bars from the key area
|
|
*/
|
|
|
|
jp = key;
|
|
i = 27;
|
|
while (i--){
|
|
cage[i] = cagetable[*jp++ % 28];
|
|
if(xxx && (cage[i] != 0)){
|
|
putchar( cage[i]/8 + '0');
|
|
putchar( cage[i]%8 + '0');
|
|
putchar(' ');
|
|
}
|
|
}
|
|
if(xxx) putchar('\n');
|
|
|
|
|
|
/*
|
|
the internal settings are now complete
|
|
it's time to turn the crank, running the cage
|
|
bars against the wheel lugs.
|
|
*/
|
|
|
|
|
|
while ((precious = getchar()) >=0){
|
|
temp = 040*wheel1[1] + 020*wheel2[1] + 010*wheel3[1]
|
|
+ 004*wheel4[1] + 002*wheel5[1] + 001*wheel6[1];
|
|
wheel1 = *wheel1;
|
|
wheel2 = *wheel2;
|
|
wheel3 = *wheel3;
|
|
wheel4 = *wheel4;
|
|
wheel5 = *wheel5;
|
|
wheel6 = *wheel6;
|
|
|
|
random = 0;
|
|
i = 27;
|
|
while (i--){
|
|
random = random + ((temp & cage[i]) != 0);
|
|
}
|
|
random =% 26;
|
|
|
|
/*
|
|
now we have a random number to use to encrypt the input
|
|
it is done in such a way that the process is its own
|
|
inverse.
|
|
*/
|
|
|
|
|
|
if ( precious=='\n' || precious==' ')
|
|
crypt = precious;
|
|
else{
|
|
crypt = ('a' + 'z' - precious + random)%0400;
|
|
if (crypt >= 'a' && crypt <= 'z' && precious > 'z')
|
|
crypt =+ 26;
|
|
if (crypt > 'z' && precious >= 'a' & precious <= 'z')
|
|
crypt =- 26;
|
|
if (crypt == '\n' || crypt == ' ')
|
|
crypt = precious;
|
|
}
|
|
putchar(crypt);
|
|
}
|
|
flush();
|
|
return;
|
|
}
|
|
|
|
char ibuf[512];
|
|
char obuf[512];
|
|
char *ibufp;
|
|
int icnt;
|
|
int ocnt;
|
|
getchar()
|
|
{
|
|
|
|
if(icnt == 0) {
|
|
icnt = read(0, ibuf, 512);
|
|
if(icnt <= 0)
|
|
return(-1);
|
|
ibufp = ibuf;
|
|
}
|
|
icnt --;
|
|
return(*ibufp++ & 0377);
|
|
}
|
|
|
|
putchar(c)
|
|
{
|
|
|
|
obuf[ocnt++] = c;
|
|
if(ocnt >= 512)
|
|
flush();
|
|
}
|
|
|
|
flush()
|
|
{
|
|
|
|
if(ocnt > 0)
|
|
write(1, obuf, ocnt);
|
|
ocnt = 0;
|
|
}
|