2 * Unoptimized sample implementation of Ron Rivest's submission to the
5 * Salvo Salasio, 19 June 1998
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.
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.
22 #define w 32 /* word size in bits */
23 #define r 20 /* based on security estimates */
25 #define P32 0xB7E15163 /* Magic constants for key setup */
26 #define Q32 0x9E3779B9
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 */
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)))))
38 void rc6_key_setup(unsigned char *K
, int b
, RC6KEY S
)
41 unsigned int L
[(32 + bytes
- 1) / bytes
]; /* Big enough for max b */
45 for(i
= b
- 1; i
>= 0; i
--)
46 { L
[i
/ bytes
] = (L
[i
/ bytes
] << 8) + K
[i
]; }
49 for(i
= 1; i
<= 2 * r
+ 3; i
++)
50 { S
[i
] = S
[i
- 1] + Q32
; }
57 for(s
= 1; s
<= v
; s
++)
59 A
= S
[i
] = ROTL(S
[i
] + A
+ B
, 3);
60 B
= L
[j
] = ROTL(L
[j
] + A
+ B
, A
+ B
);
66 void rc6_block_encrypt(unsigned int *pt
, unsigned int *ct
, int block_count
, RC6KEY S
)
68 unsigned int A
, B
, C
, D
, t
, u
, x
;
71 while(block_count
> 0)
79 for(i
= 2; i
<= 2 * r
; i
+= 2)
81 t
= ROTL(B
* (2 * B
+ 1), lgw
);
82 u
= ROTL(D
* (2 * D
+ 1), lgw
);
83 A
= ROTL(A
^ t
, u
) + S
[i
];
84 C
= ROTL(C
^ u
, t
) + S
[i
+ 1];
104 void rc6_block_decrypt(unsigned int *ct
, unsigned int *pt
, int block_count
, RC6KEY S
)
106 unsigned int A
, B
, C
, D
, t
, u
, x
;
109 while(block_count
> 0)
117 for(i
= 2 * r
; i
>= 2; i
-= 2)
124 u
= ROTL(D
* (2 * D
+ 1), lgw
);
125 t
= ROTL(B
* (2 * B
+ 1), lgw
);
126 C
= ROTR(C
- S
[i
+ 1], t
) ^ u
;
127 A
= ROTR(A
- S
[i
], u
) ^ t
;
146 unsigned char key[32];
151 { 16, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
153 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
154 {0x36a5c38f, 0x78f7b156, 0x4edf29c1, 0x1ea44898},
157 { 16, {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
158 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78},
159 {0x35241302, 0x79685746, 0xbdac9b8a, 0xf1e0dfce},
160 {0x2f194e52, 0x23c61547, 0x36f6511f, 0x183fa47e},
163 { 24, {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 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
167 {0xcb1bd66c, 0x38300b19, 0x163f8a4e, 0x82ae9086},
170 { 24, {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
171 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
172 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0},
173 {0x35241302, 0x79685746, 0xbdac9b8a, 0xf1e0dfce},
174 {0xd0298368, 0x0405e519, 0x2ae9521e, 0xd49152f9},
177 { 32, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
181 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
182 {0x05bd5f8f, 0xa85fd110, 0xda3ffa93, 0xc27e856e},
185 { 32, {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
186 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
187 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0,
188 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe},
189 {0x35241302, 0x79685746, 0xbdac9b8a, 0xf1e0dfce},
190 {0x161824c8, 0x89e4d7f0, 0xa116ad20, 0x485d4e67},
200 unsigned int ct[4], pt[4];
202 struct test_struct *p;
205 for (p = tests, i = 1; p->keylen; p++, i++)
208 rc6_key_setup(p->key, p->keylen, &S);
209 rc6_block_encrypt(p->pt, ct, &S);
210 printf("Test %d: %08x %08x %08x %08x\n",
211 i, ct[0], ct[1], ct[2], ct[3]);
212 printf("Should be: %08x %08x %08x %08x\n",
213 p->ct[0], p->ct[1], p->ct[2], p->ct[3]);
214 rc6_block_decrypt(ct, pt, &S);
215 printf("Plain: %08x %08x %08x %08x\n",
216 pt[0], pt[1], pt[2], pt[3]);
217 printf("Should be: %08x %08x %08x %08x\n\n",
218 p->pt[0], p->pt[1], p->pt[2], p->pt[3]);