1: /* 2: This routine is an exact implementation of Boris Hagelin's 3: cryptographic machine. See U. S. Patent #2,089,603. 4: */ 5: 6: int cagetable[] { 0, 1, 1, 2, 2, 3, 4, 4, 5, 6, 8, 8, 9, 10, 12, 16, 7: 16, 17, 18, 20, 24, 32, 32, 33, 34, 36, 40, 48}; 8: int warr1[52]; 9: int warr2[50]; 10: int warr3[46]; 11: int warr4[42]; 12: int warr5[38]; 13: int warr6[34]; 14: int *wheel1 warr1; 15: int *wheel2 warr2; 16: int *wheel3 warr3; 17: int *wheel4 warr4; 18: int *wheel5 warr5; 19: int *wheel6 warr6; 20: char key[130]; 21: int xxx; 22: 23: 24: /* 25: subroutine to manufacture a wheel 26: */ 27: 28: setup(list,n) int list[]; 29: {int *lp; 30: lp = list; 31: while(--n){ 32: *lp = lp+2; 33: lp[1] = getbit(); 34: if(xxx) putchar(lp[1]+'0'); 35: lp = lp + 2; 36: } 37: *lp = list; 38: lp[1] = getbit(); 39: if(xxx){ 40: putchar(lp[1]+'0'); 41: putchar('\n'); 42: } 43: } 44: 45: 46: 47: /* 48: subroutine to return the next bit from the main routines 49: argument 50: */ 51: 52: getbit(){ 53: static i,j; 54: int b; 55: b = (key[j] >> i) & 1; 56: if (i++ > 5) { 57: j++; 58: i = 0; 59: } 60: return (b); 61: } 62: 63: 64: 65: 66: main(ncooky,cookyp) 67: int ncooky; 68: char *cookyp[]; 69: { 70: char *ip, *jp; 71: int temp; 72: int random; 73: int i,j; 74: int precious; 75: int crypt; 76: int cage[27]; 77: xxx = 0; 78: 79: 80: 81: /* 82: copy input key and pad with clever junk 83: */ 84: 85: jp = key; 86: *jp++ = 004; 87: *jp++ = 034; 88: if(ncooky > 1){ 89: while (*jp++ = *cookyp[1]++); 90: jp--; 91: } 92: ip = key; 93: while (jp < key+128) { 94: *jp = jp[-1] ^ *ip++; 95: jp++; 96: } 97: 98: 99: /* 100: manufacture six wheels of various length 101: */ 102: 103: setup(wheel1,26); 104: setup(wheel2,25); 105: setup(wheel3,23); 106: setup(wheel4,21); 107: setup(wheel5,19); 108: setup(wheel6,17); 109: 110: /* 111: set up the cage bars from the key area 112: */ 113: 114: jp = key; 115: i = 27; 116: while (i--){ 117: cage[i] = cagetable[*jp++ % 28]; 118: if(xxx && (cage[i] != 0)){ 119: putchar( cage[i]/8 + '0'); 120: putchar( cage[i]%8 + '0'); 121: putchar(' '); 122: } 123: } 124: if(xxx) putchar('\n'); 125: 126: 127: /* 128: the internal settings are now complete 129: it's time to turn the crank, running the cage 130: bars against the wheel lugs. 131: */ 132: 133: 134: while ((precious = getchar()) >=0){ 135: temp = 040*wheel1[1] + 020*wheel2[1] + 010*wheel3[1] 136: + 004*wheel4[1] + 002*wheel5[1] + 001*wheel6[1]; 137: wheel1 = *wheel1; 138: wheel2 = *wheel2; 139: wheel3 = *wheel3; 140: wheel4 = *wheel4; 141: wheel5 = *wheel5; 142: wheel6 = *wheel6; 143: 144: random = 0; 145: i = 27; 146: while (i--){ 147: random = random + ((temp & cage[i]) != 0); 148: } 149: random =% 26; 150: 151: /* 152: now we have a random number to use to encrypt the input 153: it is done in such a way that the process is its own 154: inverse. 155: */ 156: 157: 158: if ( precious=='\n' || precious==' ') 159: crypt = precious; 160: else{ 161: crypt = ('a' + 'z' - precious + random)%0400; 162: if (crypt >= 'a' && crypt <= 'z' && precious > 'z') 163: crypt =+ 26; 164: if (crypt > 'z' && precious >= 'a' & precious <= 'z') 165: crypt =- 26; 166: if (crypt == '\n' || crypt == ' ') 167: crypt = precious; 168: } 169: putchar(crypt); 170: } 171: flush(); 172: return; 173: } 174: 175: char ibuf[512]; 176: char obuf[512]; 177: char *ibufp; 178: int icnt; 179: int ocnt; 180: getchar() 181: { 182: 183: if(icnt == 0) { 184: icnt = read(0, ibuf, 512); 185: if(icnt <= 0) 186: return(-1); 187: ibufp = ibuf; 188: } 189: icnt --; 190: return(*ibufp++ & 0377); 191: } 192: 193: putchar(c) 194: { 195: 196: obuf[ocnt++] = c; 197: if(ocnt >= 512) 198: flush(); 199: } 200: 201: flush() 202: { 203: 204: if(ocnt > 0) 205: write(1, obuf, ocnt); 206: ocnt = 0; 207: }