cf25d38cb340b407b93b544d49a7218ae04b8d37
[openafs.git] / src / des / make_keyperm.c
1 /*
2  * Copyright 1988 by the Massachusetts Institute of Technology.
3  *
4  * For copying and distribution information, please see the file
5  * <mit-cpyright.h>.
6  *
7  * This routine calculates an effective Key schedule set of
8  * permutations for des.  Beginning with the pre-defined key schedule
9  * algorithm, it reduces it to a set of 16 permutations upon the
10  * initial key.  Only needs to execute once to produce a header file.
11  * Note that we subtract one from the values ouput to fix up for C
12  * subscripts starting at 0.
13  */
14
15 #include <mit-cpyright.h>
16 #include <stdio.h>
17 #include <errno.h>
18 #include "des_internal.h"
19
20 char *progname;
21 extern char *errmsg();
22 extern afs_int32 swap_bit_pos_1();
23 extern afs_int32 swap_bit_pos_0();
24 int sflag;
25 int vflag;
26 int dflag;
27 int pid;
28 int child_status;
29
30 int key_position[64+1];
31 int C[28+1];
32 int D[28+1];
33 int C_temp, D_temp;
34
35 /*
36  *  CONVENTIONS for numbering the bits
37  *  bit 0 ==> lsb
38  *  L starts at bit 0
39  *  R starts at bit 64
40  *
41  *  BEWARE-- some stuff starts at 0, some at 1;  perhaps some bugs still?
42  */
43
44 /*
45  * Sequence of shifts used for the key schedule.
46  */
47 int const shift[16+1] = { 0,
48     1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,
49 };
50
51 int const pc_1[64+1] = { 0,
52
53     57,49,41,33,25,17, 9,
54      1,58,50,42,34,26,18,
55     10, 2,59,51,43,35,27,
56     19,11, 3,60,52,44,36,
57
58     63,55,47,39,31,23,15,
59      7,62,54,46,38,30,22,
60     14, 6,61,53,45,37,29,
61     21,13, 5,28,20,12, 4,
62 };
63
64
65 /*
66  * Permuted-choice 2, to pick out the bits from
67  * the CD array that generate the key schedule.
68  */
69 int const pc_2[48+1] = { 0,
70
71     14,17,11,24, 1, 5,
72      3,28,15, 6,21,10,
73     23,19,12, 4,26, 8,
74     16, 7,27,20,13, 2,
75
76     41,52,31,37,47,55,
77     30,40,51,45,33,48,
78     44,49,39,56,34,53,
79     46,42,50,36,29,32,
80 };
81
82 int ks_perm[16+1][48+1];
83
84 int des_debug;
85
86 void gen(stream)
87     FILE *stream;
88 {
89     /*  Local Declarations */
90     register int i, j, iter;
91
92     /*
93      * initialize the key_position array s.t. key_position[i] = i;
94      * that is, each element is equal to its starting position.
95      *
96      * Also adjust for the bit order within bytes.
97      */
98
99     for (i=0; i<65; i++)
100         key_position[i]= swap_bit_pos_1(i);
101
102     fprintf(stream,"static int const key_perm[16][48] = {\n");
103
104     /*
105      * apply pc_1 to initial key_position to create C[0] and D[0]
106      * Start at pc_1[1], not pc_1[0]
107      */
108     for (i=1; i<=28; i++) {
109         C[i] = key_position[pc_1[i]];
110         D[i] = key_position[pc_1[i+28]];
111     }
112
113     /*
114      * major loop over the 16 iterations
115      * start at iter = 1, not zero.
116      */
117     for (iter = 1; iter <= 16; iter++) {
118         if (des_debug) {
119             /*  for debugging */
120             printf(
121                     "/* DEBUG-- start iteration = %d  shifts = %d",
122                     iter, shift[iter]);
123             printf("\nC array");
124             for (i = 1; i <=4 ; i++) {
125                 printf("\n");
126                 for (j = 1; j<=7; j++)
127                     printf("%d, ",C[(i-1)*7+j]);
128             }
129             printf("\n\nD array");
130             for (i = 1; i <=4 ; i++) {
131                 printf("\n");
132                 for (j = 1; j<=7; j++)
133                     printf("%d, ",D[(i-1)*7+j]);
134             }
135             printf("\n */");
136             fflush(stdout);
137         }
138
139         /* apply the appropriate left shifts */
140         for (i = 1; i <= shift[iter]; i++) {
141             C_temp = C[1];
142             D_temp = D[1];
143             for (j =1; j<=27; j++) {
144                 C[j] = C[j+1];
145                 D[j] = D[j+1];
146             }
147             C[j] = C_temp;
148             D[j] = D_temp;
149         }
150
151
152         if (des_debug) {
153             /* for debugging */
154             printf("/* DEBUG:\n");
155             printf(" * after shifts, iteration = %d  shifts = %d",
156                     iter, shift[iter]);
157             printf("\nC array");
158             for (i = 1; i <=4 ; i++) {
159                 printf("\n");
160                 for (j = 1; j<=7; j++)
161                     printf("%d, ",C[(i-1)*7+j]);
162             }
163             printf("\n\nD array");
164             for (i = 1; i <=4 ; i++) {
165                 printf("\n");
166                 for (j = 1; j<=7; j++)
167                     printf("%d, ",D[(i-1)*7+j]);
168             }
169             printf("\n */");
170             fflush(stdout);
171         }
172
173         /*
174          * apply pc_2
175          * Start at pc_2[1], not pc_2[0]
176          *
177          * Start stuffing ks_perm[1][1], not ks_perm[0][0]
178          *
179          * Adjust ks_perm for bit order if needed.
180          */
181         for (i = 1; i <= 48; i++) {
182             if (pc_2[i] <= 28)
183                 ks_perm[iter][(i)] = C[pc_2[i]];
184             else
185                 ks_perm[iter][(i)] = D[pc_2[i]-28];
186         }
187
188         /* now output the resulting key permutation */
189         fprintf(stream, "    /* ks permutation iteration = %2d */",
190                 iter);
191         for (i = 1; i <= 6; i++) {
192             fprintf(stream, "\n    ");
193             for (j = 1; j <= 8; j++) {
194                 /*
195                  * IMPORTANT -- subtract one from value to adjust to a
196                  * zero-based subscript for key
197                  */
198                 fprintf(stream, "%d", ks_perm[iter][(i-1)*8+j]-1);
199                 /* omit last comma */
200                 if ((j != 8) || (i != 6) || (iter != 16)) {
201                     fprintf(stream,", ");
202                 }
203             }
204         }
205     }
206     fprintf(stream,"\n};\n");
207 }