1 | /* rc6 (TM)
|
---|
2 | * Unoptimized sample implementation of Ron Rivest's submission to the
|
---|
3 | * AES bakeoff.
|
---|
4 | *
|
---|
5 | * Salvo Salasio, 19 June 1998
|
---|
6 | *
|
---|
7 | * Intellectual property notes: The name of the algorithm (RC6) is
|
---|
8 | * trademarked; any property rights to the algorithm or the trademark
|
---|
9 | * should be discussed with discussed with the authors of the defining
|
---|
10 | * paper "The RC6(TM) Block Cipher": Ronald L. Rivest (MIT),
|
---|
11 | * M.J.B. Robshaw (RSA Labs), R. Sidney (RSA Labs), and Y.L. Yin (RSA Labs),
|
---|
12 | * distributed 18 June 1998 and available from the lead author's web site.
|
---|
13 | *
|
---|
14 | * This sample implementation is placed in the public domain by the author,
|
---|
15 | * Salvo Salasio. The ROTL and ROTR definitions were cribbed from RSA Labs'
|
---|
16 | * RC5 reference implementation.
|
---|
17 | */
|
---|
18 |
|
---|
19 | #include <stdio.h>
|
---|
20 | #include "rc6.h"
|
---|
21 |
|
---|
22 | #define w 32 /* word size in bits */
|
---|
23 | #define r 20 /* based on security estimates */
|
---|
24 |
|
---|
25 | #define P32 0xB7E15163 /* Magic constants for key setup */
|
---|
26 | #define Q32 0x9E3779B9
|
---|
27 |
|
---|
28 | /* derived constants */
|
---|
29 | #define bytes (w / 8) /* bytes per word */
|
---|
30 | #define c ((b + bytes - 1) / bytes) /* key in words, rounded up */
|
---|
31 | #define R24 (2 * r + 4)
|
---|
32 | #define lgw 5 /* log2(w) -- wussed out */
|
---|
33 |
|
---|
34 | /* Rotations */
|
---|
35 | #define ROTL(x,y) (((x)<<((y)&(w-1))) | ((x)>>(w-((y)&(w-1)))))
|
---|
36 | #define ROTR(x,y) (((x)>>((y)&(w-1))) | ((x)<<(w-((y)&(w-1)))))
|
---|
37 |
|
---|
38 | void rc6_key_setup(unsigned char *K, int b, unsigned int *S)
|
---|
39 | {
|
---|
40 | int i, j, s, v;
|
---|
41 | unsigned int L[(32 + bytes - 1) / bytes]; /* Big enough for max b */
|
---|
42 | unsigned int A, B;
|
---|
43 |
|
---|
44 | L[c - 1] = 0;
|
---|
45 | for (i = b - 1; i >= 0; i--)
|
---|
46 | L[i / bytes] = (L[i / bytes] << 8) + K[i];
|
---|
47 |
|
---|
48 | S[0] = P32;
|
---|
49 | for (i = 1; i <= 2 * r + 3; i++)
|
---|
50 | S[i] = S[i - 1] + Q32;
|
---|
51 |
|
---|
52 | A = B = i = j = 0;
|
---|
53 | v = R24;
|
---|
54 | if (c > v) v = c;
|
---|
55 | v *= 3;
|
---|
56 |
|
---|
57 | for (s = 1; s <= v; s++)
|
---|
58 | {
|
---|
59 | A = S[i] = ROTL(S[i] + A + B, 3);
|
---|
60 | B = L[j] = ROTL(L[j] + A + B, A + B);
|
---|
61 | i = (i + 1) % R24;
|
---|
62 | j = (j + 1) % c;
|
---|
63 | }
|
---|
64 | }
|
---|
65 |
|
---|
66 | void rc6_block_encrypt(unsigned int *pt, unsigned int *ct, unsigned int *S)
|
---|
67 | {
|
---|
68 | unsigned int A, B, C, D, t, u, x;
|
---|
69 | int i;
|
---|
70 |
|
---|
71 | A = pt[0];
|
---|
72 | B = pt[1];
|
---|
73 | C = pt[2];
|
---|
74 | D = pt[3];
|
---|
75 | B += S[0];
|
---|
76 | D += S[1];
|
---|
77 | for (i = 2; i <= 2 * r; i += 2)
|
---|
78 | {
|
---|
79 | t = ROTL(B * (2 * B + 1), lgw);
|
---|
80 | u = ROTL(D * (2 * D + 1), lgw);
|
---|
81 | A = ROTL(A ^ t, u) + S[i];
|
---|
82 | C = ROTL(C ^ u, t) + S[i + 1];
|
---|
83 | x = A;
|
---|
84 | A = B;
|
---|
85 | B = C;
|
---|
86 | C = D;
|
---|
87 | D = x;
|
---|
88 | }
|
---|
89 | A += S[2 * r + 2];
|
---|
90 | C += S[2 * r + 3];
|
---|
91 | ct[0] = A;
|
---|
92 | ct[1] = B;
|
---|
93 | ct[2] = C;
|
---|
94 | ct[3] = D;
|
---|
95 | }
|
---|
96 |
|
---|
97 | void rc6_block_decrypt(unsigned int *ct, unsigned int *pt, unsigned int *S)
|
---|
98 | {
|
---|
99 | unsigned int A, B, C, D, t, u, x;
|
---|
100 | int i;
|
---|
101 |
|
---|
102 | A = ct[0];
|
---|
103 | B = ct[1];
|
---|
104 | C = ct[2];
|
---|
105 | D = ct[3];
|
---|
106 | C -= S[2 * r + 3];
|
---|
107 | A -= S[2 * r + 2];
|
---|
108 | for (i = 2 * r; i >= 2; i -= 2)
|
---|
109 | {
|
---|
110 | x = D;
|
---|
111 | D = C;
|
---|
112 | C = B;
|
---|
113 | B = A;
|
---|
114 | A = x;
|
---|
115 | u = ROTL(D * (2 * D + 1), lgw);
|
---|
116 | t = ROTL(B * (2 * B + 1), lgw);
|
---|
117 | C = ROTR(C - S[i + 1], t) ^ u;
|
---|
118 | A = ROTR(A - S[i], u) ^ t;
|
---|
119 | }
|
---|
120 | D -= S[1];
|
---|
121 | B -= S[0];
|
---|
122 | pt[0] = A;
|
---|
123 | pt[1] = B;
|
---|
124 | pt[2] = C;
|
---|
125 | pt[3] = D;
|
---|
126 | }
|
---|
127 |
|
---|
128 | /*
|
---|
129 | struct test_struct
|
---|
130 | {
|
---|
131 | int keylen;
|
---|
132 | unsigned char key[32];
|
---|
133 | unsigned int pt[4];
|
---|
134 | unsigned int ct[4];
|
---|
135 | } tests[] =
|
---|
136 | {
|
---|
137 | { 16, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
---|
138 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
---|
139 | {0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
---|
140 | {0x36a5c38f, 0x78f7b156, 0x4edf29c1, 0x1ea44898},
|
---|
141 | },
|
---|
142 |
|
---|
143 | { 16, {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
|
---|
144 | 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78},
|
---|
145 | {0x35241302, 0x79685746, 0xbdac9b8a, 0xf1e0dfce},
|
---|
146 | {0x2f194e52, 0x23c61547, 0x36f6511f, 0x183fa47e},
|
---|
147 | },
|
---|
148 |
|
---|
149 | { 24, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
---|
150 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
---|
151 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
---|
152 | {0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
---|
153 | {0xcb1bd66c, 0x38300b19, 0x163f8a4e, 0x82ae9086},
|
---|
154 | },
|
---|
155 |
|
---|
156 | { 24, {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
|
---|
157 | 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
|
---|
158 | 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0},
|
---|
159 | {0x35241302, 0x79685746, 0xbdac9b8a, 0xf1e0dfce},
|
---|
160 | {0xd0298368, 0x0405e519, 0x2ae9521e, 0xd49152f9},
|
---|
161 | },
|
---|
162 |
|
---|
163 | { 32, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
---|
164 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
---|
165 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
---|
166 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
---|
167 | {0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
---|
168 | {0x05bd5f8f, 0xa85fd110, 0xda3ffa93, 0xc27e856e},
|
---|
169 | },
|
---|
170 |
|
---|
171 | { 32, {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
|
---|
172 | 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
|
---|
173 | 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0,
|
---|
174 | 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe},
|
---|
175 | {0x35241302, 0x79685746, 0xbdac9b8a, 0xf1e0dfce},
|
---|
176 | {0x161824c8, 0x89e4d7f0, 0xa116ad20, 0x485d4e67},
|
---|
177 | },
|
---|
178 |
|
---|
179 | { 0,
|
---|
180 | }
|
---|
181 | };
|
---|
182 |
|
---|
183 | int
|
---|
184 | main()
|
---|
185 | {
|
---|
186 | unsigned int ct[4], pt[4];
|
---|
187 | int i;
|
---|
188 | struct test_struct *p;
|
---|
189 | RC6KEY S;
|
---|
190 |
|
---|
191 | for (p = tests, i = 1; p->keylen; p++, i++)
|
---|
192 | {
|
---|
193 |
|
---|
194 | rc6_key_setup(p->key, p->keylen, &S);
|
---|
195 | rc6_block_encrypt(p->pt, ct, &S);
|
---|
196 | printf("Test %d: %08x %08x %08x %08x\n",
|
---|
197 | i, ct[0], ct[1], ct[2], ct[3]);
|
---|
198 | printf("Should be: %08x %08x %08x %08x\n",
|
---|
199 | p->ct[0], p->ct[1], p->ct[2], p->ct[3]);
|
---|
200 | rc6_block_decrypt(ct, pt, &S);
|
---|
201 | printf("Plain: %08x %08x %08x %08x\n",
|
---|
202 | pt[0], pt[1], pt[2], pt[3]);
|
---|
203 | printf("Should be: %08x %08x %08x %08x\n\n",
|
---|
204 | p->pt[0], p->pt[1], p->pt[2], p->pt[3]);
|
---|
205 | }
|
---|
206 |
|
---|
207 | return 0;
|
---|
208 | }
|
---|
209 | */
|
---|
210 |
|
---|