- fix Building without Nagra not possible at Nagra_Merlin https://trac.streamboard...
[oscam.git] / cscrypt / rc6.c
blob4a561c47aea5d2514e99dcbdccd132c42e1e7695
1 /* rc6 (TM)
2 * Unoptimized sample implementation of Ron Rivest's submission to the
3 * AES bakeoff.
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.
19 #include <stdio.h>
20 #include "rc6.h"
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 */
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)))))
38 void rc6_key_setup(unsigned char *K, int b, RC6KEY S)
40 int i, j, s, v;
41 unsigned int L[(32 + bytes - 1) / bytes]; /* Big enough for max b */
42 unsigned int A, B;
44 L[c - 1] = 0;
45 for(i = b - 1; i >= 0; i--)
46 { L[i / bytes] = (L[i / bytes] << 8) + K[i]; }
48 S[0] = P32;
49 for(i = 1; i <= 2 * r + 3; i++)
50 { S[i] = S[i - 1] + Q32; }
52 A = B = i = j = 0;
53 v = R24;
54 if(c > v) { v = c; }
55 v *= 3;
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);
61 i = (i + 1) % R24;
62 j = (j + 1) % c;
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;
69 int i;
71 while(block_count > 0)
73 A = pt[0];
74 B = pt[1];
75 C = pt[2];
76 D = pt[3];
77 B += S[0];
78 D += S[1];
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];
85 x = A;
86 A = B;
87 B = C;
88 C = D;
89 D = x;
91 A += S[2 * r + 2];
92 C += S[2 * r + 3];
93 ct[0] = A;
94 ct[1] = B;
95 ct[2] = C;
96 ct[3] = D;
98 block_count--;
99 pt++;
100 ct++;
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;
107 int i;
109 while(block_count > 0)
111 A = ct[0];
112 B = ct[1];
113 C = ct[2];
114 D = ct[3];
115 C -= S[2 * r + 3];
116 A -= S[2 * r + 2];
117 for(i = 2 * r; i >= 2; i -= 2)
119 x = D;
120 D = C;
121 C = B;
122 B = A;
123 A = x;
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;
129 D -= S[1];
130 B -= S[0];
131 pt[0] = A;
132 pt[1] = B;
133 pt[2] = C;
134 pt[3] = D;
136 block_count--;
137 ct++;
138 pt++;
143 struct test_struct
145 int keylen;
146 unsigned char key[32];
147 unsigned int pt[4];
148 unsigned int ct[4];
149 } tests[] =
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},
193 { 0,
198 main()
200 unsigned int ct[4], pt[4];
201 int i;
202 struct test_struct *p;
203 RC6KEY S;
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]);
221 return 0;