/* 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 0; /* subroutine to manufacture a wheel */ setup(list, n) register int list[]; register int n; { register 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; register int b; b = (key[j]>>i)&1; if(i++ > 5) { j++; i = 0; } return b; } main(argc, argv) int argc; char *argv[]; { register char *ip, *jp; register int i; int temp, random, j, precious, crypt; int cage[27]; /* zap arguments for benefit of 'ps' */ argv[argc] = 0; /* copy input key and pad with clever junk */ jp = key; *jp++ = 004; *jp++ = 034; if(argc > 1) { while(*jp++ = *argv[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 0; } char ibuf[512]; char obuf[512]; char *ibufp; int icnt; int ocnt; getchar() { if(icnt == 0) { icnt = read(0, ibuf, 512); if(icnt < 0) { perror("read"); exit(1); } if(icnt == 0) return -1; ibufp = ibuf; } icnt--; return *ibufp++ & 0377 ; } putchar(c) { obuf[ocnt++] = c; if(ocnt >= 512) flush(); } flush() { if(ocnt > 0) if( write(1, obuf, ocnt) != ocnt ) { perror("write"); exit(1); } ocnt = 0; }