Botan  1.10.9
cast128.cpp
Go to the documentation of this file.
1 /*
2 * CAST-128
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7 
8 #include <botan/cast128.h>
9 #include <botan/loadstor.h>
10 #include <botan/rotate.h>
11 
12 namespace Botan {
13 
14 namespace {
15 
16 /*
17 * CAST-128 Round Type 1
18 */
19 inline void R1(u32bit& L, u32bit R, u32bit MK, u32bit RK)
20  {
21  u32bit T = rotate_left(MK + R, RK);
22  L ^= (CAST_SBOX1[get_byte(0, T)] ^ CAST_SBOX2[get_byte(1, T)]) -
23  CAST_SBOX3[get_byte(2, T)] + CAST_SBOX4[get_byte(3, T)];
24  }
25 
26 /*
27 * CAST-128 Round Type 2
28 */
29 inline void R2(u32bit& L, u32bit R, u32bit MK, u32bit RK)
30  {
31  u32bit T = rotate_left(MK ^ R, RK);
32  L ^= (CAST_SBOX1[get_byte(0, T)] - CAST_SBOX2[get_byte(1, T)] +
33  CAST_SBOX3[get_byte(2, T)]) ^ CAST_SBOX4[get_byte(3, T)];
34  }
35 
36 /*
37 * CAST-128 Round Type 3
38 */
39 inline void R3(u32bit& L, u32bit R, u32bit MK, u32bit RK)
40  {
41  u32bit T = rotate_left(MK - R, RK);
42  L ^= ((CAST_SBOX1[get_byte(0, T)] + CAST_SBOX2[get_byte(1, T)]) ^
43  CAST_SBOX3[get_byte(2, T)]) - CAST_SBOX4[get_byte(3, T)];
44  }
45 
46 }
47 
48 /*
49 * CAST-128 Encryption
50 */
51 void CAST_128::encrypt_n(const byte in[], byte out[], size_t blocks) const
52  {
53  for(size_t i = 0; i != blocks; ++i)
54  {
55  u32bit L = load_be<u32bit>(in, 0);
56  u32bit R = load_be<u32bit>(in, 1);
57 
58  R1(L, R, MK[ 0], RK[ 0]);
59  R2(R, L, MK[ 1], RK[ 1]);
60  R3(L, R, MK[ 2], RK[ 2]);
61  R1(R, L, MK[ 3], RK[ 3]);
62  R2(L, R, MK[ 4], RK[ 4]);
63  R3(R, L, MK[ 5], RK[ 5]);
64  R1(L, R, MK[ 6], RK[ 6]);
65  R2(R, L, MK[ 7], RK[ 7]);
66  R3(L, R, MK[ 8], RK[ 8]);
67  R1(R, L, MK[ 9], RK[ 9]);
68  R2(L, R, MK[10], RK[10]);
69  R3(R, L, MK[11], RK[11]);
70  R1(L, R, MK[12], RK[12]);
71  R2(R, L, MK[13], RK[13]);
72  R3(L, R, MK[14], RK[14]);
73  R1(R, L, MK[15], RK[15]);
74 
75  store_be(out, R, L);
76 
77  in += BLOCK_SIZE;
78  out += BLOCK_SIZE;
79  }
80  }
81 
82 /*
83 * CAST-128 Decryption
84 */
85 void CAST_128::decrypt_n(const byte in[], byte out[], size_t blocks) const
86  {
87  for(size_t i = 0; i != blocks; ++i)
88  {
89  u32bit L = load_be<u32bit>(in, 0);
90  u32bit R = load_be<u32bit>(in, 1);
91 
92  R1(L, R, MK[15], RK[15]);
93  R3(R, L, MK[14], RK[14]);
94  R2(L, R, MK[13], RK[13]);
95  R1(R, L, MK[12], RK[12]);
96  R3(L, R, MK[11], RK[11]);
97  R2(R, L, MK[10], RK[10]);
98  R1(L, R, MK[ 9], RK[ 9]);
99  R3(R, L, MK[ 8], RK[ 8]);
100  R2(L, R, MK[ 7], RK[ 7]);
101  R1(R, L, MK[ 6], RK[ 6]);
102  R3(L, R, MK[ 5], RK[ 5]);
103  R2(R, L, MK[ 4], RK[ 4]);
104  R1(L, R, MK[ 3], RK[ 3]);
105  R3(R, L, MK[ 2], RK[ 2]);
106  R2(L, R, MK[ 1], RK[ 1]);
107  R1(R, L, MK[ 0], RK[ 0]);
108 
109  store_be(out, R, L);
110 
111  in += BLOCK_SIZE;
112  out += BLOCK_SIZE;
113  }
114  }
115 
116 /*
117 * CAST-128 Key Schedule
118 */
119 void CAST_128::key_schedule(const byte key[], size_t length)
120  {
121  clear();
123  for(size_t j = 0; j != length; ++j)
124  X[j/4] = (X[j/4] << 8) + key[j];
125 
126  cast_ks(MK, X);
127  cast_ks(RK, X);
128 
129  for(size_t j = 0; j != 16; ++j)
130  RK[j] %= 32;
131  }
132 
133 /*
134 * S-Box Based Key Expansion
135 */
136 void CAST_128::cast_ks(MemoryRegion<u32bit>& K,
137  MemoryRegion<u32bit>& X)
138  {
139  class ByteReader
140  {
141  public:
142  byte operator()(size_t i) { return (X[i/4] >> (8*(3 - (i%4)))); }
143  ByteReader(const u32bit* x) : X(x) {}
144  private:
145  const u32bit* X;
146  };
147 
148  SecureVector<u32bit> Z(4);
149  ByteReader x(&X[0]), z(&Z[0]);
150 
151  Z[0] = X[0] ^ S5[x(13)] ^ S6[x(15)] ^ S7[x(12)] ^ S8[x(14)] ^ S7[x( 8)];
152  Z[1] = X[2] ^ S5[z( 0)] ^ S6[z( 2)] ^ S7[z( 1)] ^ S8[z( 3)] ^ S8[x(10)];
153  Z[2] = X[3] ^ S5[z( 7)] ^ S6[z( 6)] ^ S7[z( 5)] ^ S8[z( 4)] ^ S5[x( 9)];
154  Z[3] = X[1] ^ S5[z(10)] ^ S6[z( 9)] ^ S7[z(11)] ^ S8[z( 8)] ^ S6[x(11)];
155  K[ 0] = S5[z( 8)] ^ S6[z( 9)] ^ S7[z( 7)] ^ S8[z( 6)] ^ S5[z( 2)];
156  K[ 1] = S5[z(10)] ^ S6[z(11)] ^ S7[z( 5)] ^ S8[z( 4)] ^ S6[z( 6)];
157  K[ 2] = S5[z(12)] ^ S6[z(13)] ^ S7[z( 3)] ^ S8[z( 2)] ^ S7[z( 9)];
158  K[ 3] = S5[z(14)] ^ S6[z(15)] ^ S7[z( 1)] ^ S8[z( 0)] ^ S8[z(12)];
159  X[0] = Z[2] ^ S5[z( 5)] ^ S6[z( 7)] ^ S7[z( 4)] ^ S8[z( 6)] ^ S7[z( 0)];
160  X[1] = Z[0] ^ S5[x( 0)] ^ S6[x( 2)] ^ S7[x( 1)] ^ S8[x( 3)] ^ S8[z( 2)];
161  X[2] = Z[1] ^ S5[x( 7)] ^ S6[x( 6)] ^ S7[x( 5)] ^ S8[x( 4)] ^ S5[z( 1)];
162  X[3] = Z[3] ^ S5[x(10)] ^ S6[x( 9)] ^ S7[x(11)] ^ S8[x( 8)] ^ S6[z( 3)];
163  K[ 4] = S5[x( 3)] ^ S6[x( 2)] ^ S7[x(12)] ^ S8[x(13)] ^ S5[x( 8)];
164  K[ 5] = S5[x( 1)] ^ S6[x( 0)] ^ S7[x(14)] ^ S8[x(15)] ^ S6[x(13)];
165  K[ 6] = S5[x( 7)] ^ S6[x( 6)] ^ S7[x( 8)] ^ S8[x( 9)] ^ S7[x( 3)];
166  K[ 7] = S5[x( 5)] ^ S6[x( 4)] ^ S7[x(10)] ^ S8[x(11)] ^ S8[x( 7)];
167  Z[0] = X[0] ^ S5[x(13)] ^ S6[x(15)] ^ S7[x(12)] ^ S8[x(14)] ^ S7[x( 8)];
168  Z[1] = X[2] ^ S5[z( 0)] ^ S6[z( 2)] ^ S7[z( 1)] ^ S8[z( 3)] ^ S8[x(10)];
169  Z[2] = X[3] ^ S5[z( 7)] ^ S6[z( 6)] ^ S7[z( 5)] ^ S8[z( 4)] ^ S5[x( 9)];
170  Z[3] = X[1] ^ S5[z(10)] ^ S6[z( 9)] ^ S7[z(11)] ^ S8[z( 8)] ^ S6[x(11)];
171  K[ 8] = S5[z( 3)] ^ S6[z( 2)] ^ S7[z(12)] ^ S8[z(13)] ^ S5[z( 9)];
172  K[ 9] = S5[z( 1)] ^ S6[z( 0)] ^ S7[z(14)] ^ S8[z(15)] ^ S6[z(12)];
173  K[10] = S5[z( 7)] ^ S6[z( 6)] ^ S7[z( 8)] ^ S8[z( 9)] ^ S7[z( 2)];
174  K[11] = S5[z( 5)] ^ S6[z( 4)] ^ S7[z(10)] ^ S8[z(11)] ^ S8[z( 6)];
175  X[0] = Z[2] ^ S5[z( 5)] ^ S6[z( 7)] ^ S7[z( 4)] ^ S8[z( 6)] ^ S7[z( 0)];
176  X[1] = Z[0] ^ S5[x( 0)] ^ S6[x( 2)] ^ S7[x( 1)] ^ S8[x( 3)] ^ S8[z( 2)];
177  X[2] = Z[1] ^ S5[x( 7)] ^ S6[x( 6)] ^ S7[x( 5)] ^ S8[x( 4)] ^ S5[z( 1)];
178  X[3] = Z[3] ^ S5[x(10)] ^ S6[x( 9)] ^ S7[x(11)] ^ S8[x( 8)] ^ S6[z( 3)];
179  K[12] = S5[x( 8)] ^ S6[x( 9)] ^ S7[x( 7)] ^ S8[x( 6)] ^ S5[x( 3)];
180  K[13] = S5[x(10)] ^ S6[x(11)] ^ S7[x( 5)] ^ S8[x( 4)] ^ S6[x( 7)];
181  K[14] = S5[x(12)] ^ S6[x(13)] ^ S7[x( 3)] ^ S8[x( 2)] ^ S7[x( 8)];
182  K[15] = S5[x(14)] ^ S6[x(15)] ^ S7[x( 1)] ^ S8[x( 0)] ^ S8[x(13)];
183  }
184 
185 }
void clear()
Definition: cast128.h:24
const u32bit CAST_SBOX2[256]
Definition: cast256.h:40
const u32bit CAST_SBOX1[256]
Definition: cast256.h:39
T rotate_left(T input, size_t rot)
Definition: rotate.h:21
byte get_byte(size_t byte_num, T input)
Definition: get_byte.h:21
unsigned char byte
Definition: types.h:22
const u32bit CAST_SBOX4[256]
Definition: cast256.h:42
#define R2
Definition: asm_x86_64.h:53
void encrypt_n(const byte in[], byte out[], size_t blocks) const
Definition: cast128.cpp:51
#define R1
Definition: asm_x86_64.h:52
u32bit load_be< u32bit >(const byte in[], size_t off)
Definition: loadstor.h:166
void store_be(u16bit in, byte out[2])
Definition: loadstor.h:412
void decrypt_n(const byte in[], byte out[], size_t blocks) const
Definition: cast128.cpp:85
#define R3
Definition: asm_x86_64.h:55
unsigned int u32bit
Definition: types.h:32
const u32bit CAST_SBOX3[256]
Definition: cast256.h:41