3 * rc2.c : Source code for the RC2 block cipher
5 * Part of the Python Cryptography Toolkit
7 * Distribute and use freely; there are no restrictions on further
8 * dissemination and usage except those imposed by the laws of your
9 * country of residence.
15 #define MODULE_NAME ARC2
19 typedef unsigned int U32;
20 typedef unsigned short U16;
21 typedef unsigned char U8;
29 block_encrypt(block_state *self, U8 *in, U8 *out)
31 U16 x76, x54, x32, x10;
34 x76 = (in[7] << 8) + in[6];
35 x54 = (in[5] << 8) + in[4];
36 x32 = (in[3] << 8) + in[2];
37 x10 = (in[1] << 8) + in[0];
39 for (i = 0; i < 16; i++)
41 x10 += (x32 & ~x76) + (x54 & x76) + self->xkey[4*i+0];
42 x10 = (x10 << 1) + (x10 >> 15 & 1);
44 x32 += (x54 & ~x10) + (x76 & x10) + self->xkey[4*i+1];
45 x32 = (x32 << 2) + (x32 >> 14 & 3);
47 x54 += (x76 & ~x32) + (x10 & x32) + self->xkey[4*i+2];
48 x54 = (x54 << 3) + (x54 >> 13 & 7);
50 x76 += (x10 & ~x54) + (x32 & x54) + self->xkey[4*i+3];
51 x76 = (x76 << 5) + (x76 >> 11 & 31);
53 if (i == 4 || i == 10) {
54 x10 += self->xkey[x76 & 63];
55 x32 += self->xkey[x10 & 63];
56 x54 += self->xkey[x32 & 63];
57 x76 += self->xkey[x54 & 63];
62 out[1] = (U8)(x10 >> 8);
64 out[3] = (U8)(x32 >> 8);
66 out[5] = (U8)(x54 >> 8);
68 out[7] = (U8)(x76 >> 8);
73 block_decrypt(block_state *self, U8 *in, U8 *out)
75 U16 x76, x54, x32, x10;
78 x76 = (in[7] << 8) + in[6];
79 x54 = (in[5] << 8) + in[4];
80 x32 = (in[3] << 8) + in[2];
81 x10 = (in[1] << 8) + in[0];
86 x76 = (x76 << 11) + (x76 >> 5);
87 x76 -= (x10 & ~x54) + (x32 & x54) + self->xkey[4*i+3];
90 x54 = (x54 << 13) + (x54 >> 3);
91 x54 -= (x76 & ~x32) + (x10 & x32) + self->xkey[4*i+2];
94 x32 = (x32 << 14) + (x32 >> 2);
95 x32 -= (x54 & ~x10) + (x76 & x10) + self->xkey[4*i+1];
98 x10 = (x10 << 15) + (x10 >> 1);
99 x10 -= (x32 & ~x76) + (x54 & x76) + self->xkey[4*i+0];
101 if (i == 5 || i == 11) {
102 x76 -= self->xkey[x54 & 63];
103 x54 -= self->xkey[x32 & 63];
104 x32 -= self->xkey[x10 & 63];
105 x10 -= self->xkey[x76 & 63];
110 out[1] = (U8)(x10 >> 8);
112 out[3] = (U8)(x32 >> 8);
114 out[5] = (U8)(x54 >> 8);
116 out[7] = (U8)(x76 >> 8);
121 block_init(block_state *self, U8 *key, int keylength)
125 /* 256-entry permutation table, probably derived somehow from pi */
126 static const U8 permute[256] = {
127 217,120,249,196, 25,221,181,237, 40,233,253,121, 74,160,216,157,
128 198,126, 55,131, 43,118, 83,142, 98, 76,100,136, 68,139,251,162,
129 23,154, 89,245,135,179, 79, 19, 97, 69,109,141, 9,129,125, 50,
130 189,143, 64,235,134,183,123, 11,240,149, 33, 34, 92,107, 78,130,
131 84,214,101,147,206, 96,178, 28,115, 86,192, 20,167,140,241,220,
132 18,117,202, 31, 59,190,228,209, 66, 61,212, 48,163, 60,182, 38,
133 111,191, 14,218, 70,105, 7, 87, 39,242, 29,155,188,148, 67, 3,
134 248, 17,199,246,144,239, 62,231, 6,195,213, 47,200,102, 30,215,
135 8,232,234,222,128, 82,238,247,132,170,114,172, 53, 77,106, 42,
136 150, 26,210,113, 90, 21, 73,116, 75,159,208, 94, 4, 24,164,236,
137 194,224, 65,110, 15, 81,203,204, 36,145,175, 80,161,244,112, 57,
138 153,124, 58,133, 35,184,180,122,252, 2, 54, 91, 37, 85,151, 49,
139 45, 93,250,152,227,138,146,174, 5,223, 41, 16,103,108,186,201,
140 211, 0,230,207,225,158,168, 44, 99, 22, 1, 63, 88,226,137,169,
141 13, 56, 52, 27,171, 51,255,176,187, 72, 12, 95,185,177,205, 46,
142 197,243,219, 71,229,165,156,119, 10,166, 32,104,254,127,193,173
145 /* The "bits" value may be some sort of export control weakening.
146 We'll hardwire it to 1024. */
149 memcpy(self->xkey, key, keylength);
151 /* Phase 1: Expand input key to 128 bytes */
152 if (keylength < 128) {
154 x = ((U8 *)self->xkey)[keylength-1];
156 x = permute[(x + ((U8 *)self->xkey)[i++]) & 255];
157 ((U8 *)self->xkey)[keylength++] = x;
158 } while (keylength < 128);
161 /* Phase 2 - reduce effective key size to "bits" */
162 keylength = (bits+7) >> 3;
164 x = permute[((U8 *)self->xkey)[i] & (255 >>
166 ((bits %8 ) ? 8-(bits%8): 0))
168 ((U8 *)self->xkey)[i] = x;
171 x = permute[ x ^ ((U8 *)self->xkey)[i+keylength] ];
172 ((U8 *)self->xkey)[i] = x;
175 /* Phase 3 - copy to self->xkey in little-endian order */
178 self->xkey[i] = ((U8 *)self->xkey)[2*i] +
179 (((U8 *)self->xkey)[2*i+1] << 8);
185 #include "block_template.c"