Botan 1.10.17
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
12namespace Botan {
13
14namespace {
15
16/*
17* CAST-128 Round Type 1
18*/
19inline 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*/
29inline 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*/
39inline 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*/
51void 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*/
85void 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*/
119void 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*/
136void 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}
#define R3
Definition asm_x86_64.h:55
#define R2
Definition asm_x86_64.h:53
#define R1
Definition asm_x86_64.h:52
void encrypt_n(const byte in[], byte out[], size_t blocks) const
Definition cast128.cpp:51
void decrypt_n(const byte in[], byte out[], size_t blocks) const
Definition cast128.cpp:85
void clear()
Definition cast128.h:24
const u32bit CAST_SBOX1[256]
Definition cast256.h:39
byte get_byte(size_t byte_num, T input)
Definition get_byte.h:21
T load_be(const byte in[], size_t off)
Definition loadstor.h:100
T rotate_left(T input, size_t rot)
Definition rotate.h:21
const u32bit CAST_SBOX2[256]
Definition cast256.h:40
unsigned int u32bit
Definition types.h:32
const u32bit CAST_SBOX3[256]
Definition cast256.h:41
void store_be(u16bit in, byte out[2])
Definition loadstor.h:412
const u32bit CAST_SBOX4[256]
Definition cast256.h:42