Botan 1.10.17

skipjack.cpp
Go to the documentation of this file.
1 /*
2 * Skipjack
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7
8 #include <botan/skipjack.h>
9 #include <botan/loadstor.h>
10
11 namespace Botan {
12
13 namespace {
14
15 /*
16 * Skipjack Stepping Rule 'A'
17 */
18 void step_A(u16bit& W1, u16bit& W4, size_t round, const byte FTAB[])
19 {
20 byte G1 = get_byte(0, W1), G2 = get_byte(1, W1), G3;
21
22 G3 = FTAB[((4*round-4)%10)*256 + G2] ^ G1;
23 G1 = FTAB[((4*round-3)%10)*256 + G3] ^ G2;
24 G2 = FTAB[((4*round-2)%10)*256 + G1] ^ G3;
25 G3 = FTAB[((4*round-1)%10)*256 + G2] ^ G1;
26
27 W1 = make_u16bit(G2, G3);
28 W4 ^= W1 ^ round;
29 }
30
31 /*
32 * Skipjack Stepping Rule 'B'
33 */
34 void step_B(u16bit& W1, u16bit& W2, size_t round, const byte FTAB[])
35 {
36 W2 ^= W1 ^ round;
37 byte G1 = get_byte(0, W1), G2 = get_byte(1, W1), G3;
38 G3 = FTAB[((4*round-4)%10)*256 + G2] ^ G1;
39 G1 = FTAB[((4*round-3)%10)*256 + G3] ^ G2;
40 G2 = FTAB[((4*round-2)%10)*256 + G1] ^ G3;
41 G3 = FTAB[((4*round-1)%10)*256 + G2] ^ G1;
42 W1 = make_u16bit(G2, G3);
43 }
44
45 /*
46 * Skipjack Invserse Stepping Rule 'A'
47 */
48 void step_Ai(u16bit& W1, u16bit& W2, size_t round, const byte FTAB[])
49 {
50 W1 ^= W2 ^ round;
51 byte G1 = get_byte(1, W2), G2 = get_byte(0, W2), G3;
52 G3 = FTAB[((4 * round - 1) % 10)*256 + G2] ^ G1;
53 G1 = FTAB[((4 * round - 2) % 10)*256 + G3] ^ G2;
54 G2 = FTAB[((4 * round - 3) % 10)*256 + G1] ^ G3;
55 G3 = FTAB[((4 * round - 4) % 10)*256 + G2] ^ G1;
56 W2 = make_u16bit(G3, G2);
57 }
58
59 /*
60 * Skipjack Invserse Stepping Rule 'B'
61 */
62 void step_Bi(u16bit& W2, u16bit& W3, size_t round, const byte FTAB[])
63 {
64 byte G1 = get_byte(1, W2), G2 = get_byte(0, W2), G3;
65 G3 = FTAB[((4 * round - 1) % 10)*256 + G2] ^ G1;
66 G1 = FTAB[((4 * round - 2) % 10)*256 + G3] ^ G2;
67 G2 = FTAB[((4 * round - 3) % 10)*256 + G1] ^ G3;
68 G3 = FTAB[((4 * round - 4) % 10)*256 + G2] ^ G1;
69 W2 = make_u16bit(G3, G2);
70 W3 ^= W2 ^ round;
71 }
72
73 }
74
75 /*
76 * Skipjack Encryption
77 */
78 void Skipjack::encrypt_n(const byte in[], byte out[], size_t blocks) const
79 {
80 const byte* ftab = &FTAB[0];
81
82 for(size_t i = 0; i != blocks; ++i)
83 {
84 u16bit W1 = load_le<u16bit>(in, 3);
85 u16bit W2 = load_le<u16bit>(in, 2);
86 u16bit W3 = load_le<u16bit>(in, 1);
87 u16bit W4 = load_le<u16bit>(in, 0);
88
89 step_A(W1, W4, 1, ftab); step_A(W4, W3, 2, ftab);
90 step_A(W3, W2, 3, ftab); step_A(W2, W1, 4, ftab);
91 step_A(W1, W4, 5, ftab); step_A(W4, W3, 6, ftab);
92 step_A(W3, W2, 7, ftab); step_A(W2, W1, 8, ftab);
93
94 step_B(W1, W2, 9, ftab); step_B(W4, W1, 10, ftab);
95 step_B(W3, W4, 11, ftab); step_B(W2, W3, 12, ftab);
96 step_B(W1, W2, 13, ftab); step_B(W4, W1, 14, ftab);
97 step_B(W3, W4, 15, ftab); step_B(W2, W3, 16, ftab);
98
99 step_A(W1, W4, 17, ftab); step_A(W4, W3, 18, ftab);
100 step_A(W3, W2, 19, ftab); step_A(W2, W1, 20, ftab);
101 step_A(W1, W4, 21, ftab); step_A(W4, W3, 22, ftab);
102 step_A(W3, W2, 23, ftab); step_A(W2, W1, 24, ftab);
103
104 step_B(W1, W2, 25, ftab); step_B(W4, W1, 26, ftab);
105 step_B(W3, W4, 27, ftab); step_B(W2, W3, 28, ftab);
106 step_B(W1, W2, 29, ftab); step_B(W4, W1, 30, ftab);
107 step_B(W3, W4, 31, ftab); step_B(W2, W3, 32, ftab);
108
109 store_le(out, W4, W3, W2, W1);
110
111 in += BLOCK_SIZE;
112 out += BLOCK_SIZE;
113 }
114 }
115
116 /*
117 * Skipjack Decryption
118 */
119 void Skipjack::decrypt_n(const byte in[], byte out[], size_t blocks) const
120 {
121 const byte* ftab = &FTAB[0];
122
123 for(size_t i = 0; i != blocks; ++i)
124 {
125 u16bit W1 = load_le<u16bit>(in, 3);
126 u16bit W2 = load_le<u16bit>(in, 2);
127 u16bit W3 = load_le<u16bit>(in, 1);
128 u16bit W4 = load_le<u16bit>(in, 0);
129
130 step_Bi(W2, W3, 32, ftab); step_Bi(W3, W4, 31, ftab);
131 step_Bi(W4, W1, 30, ftab); step_Bi(W1, W2, 29, ftab);
132 step_Bi(W2, W3, 28, ftab); step_Bi(W3, W4, 27, ftab);
133 step_Bi(W4, W1, 26, ftab); step_Bi(W1, W2, 25, ftab);
134
135 step_Ai(W1, W2, 24, ftab); step_Ai(W2, W3, 23, ftab);
136 step_Ai(W3, W4, 22, ftab); step_Ai(W4, W1, 21, ftab);
137 step_Ai(W1, W2, 20, ftab); step_Ai(W2, W3, 19, ftab);
138 step_Ai(W3, W4, 18, ftab); step_Ai(W4, W1, 17, ftab);
139
140 step_Bi(W2, W3, 16, ftab); step_Bi(W3, W4, 15, ftab);
141 step_Bi(W4, W1, 14, ftab); step_Bi(W1, W2, 13, ftab);
142 step_Bi(W2, W3, 12, ftab); step_Bi(W3, W4, 11, ftab);
143 step_Bi(W4, W1, 10, ftab); step_Bi(W1, W2, 9, ftab);
144
145 step_Ai(W1, W2, 8, ftab); step_Ai(W2, W3, 7, ftab);
146 step_Ai(W3, W4, 6, ftab); step_Ai(W4, W1, 5, ftab);
147 step_Ai(W1, W2, 4, ftab); step_Ai(W2, W3, 3, ftab);
148 step_Ai(W3, W4, 2, ftab); step_Ai(W4, W1, 1, ftab);
149
150 store_le(out, W4, W3, W2, W1);
151
152 in += BLOCK_SIZE;
153 out += BLOCK_SIZE;
154 }
155 }
156
157 /*
158 * Skipjack Key Schedule
159 */
160 void Skipjack::key_schedule(const byte key[], size_t)
161 {
162 static const byte F[256] = {
163 0xA3, 0xD7, 0x09, 0x83, 0xF8, 0x48, 0xF6, 0xF4, 0xB3, 0x21, 0x15, 0x78,
164 0x99, 0xB1, 0xAF, 0xF9, 0xE7, 0x2D, 0x4D, 0x8A, 0xCE, 0x4C, 0xCA, 0x2E,
165 0x52, 0x95, 0xD9, 0x1E, 0x4E, 0x38, 0x44, 0x28, 0x0A, 0xDF, 0x02, 0xA0,
166 0x17, 0xF1, 0x60, 0x68, 0x12, 0xB7, 0x7A, 0xC3, 0xE9, 0xFA, 0x3D, 0x53,
167 0x96, 0x84, 0x6B, 0xBA, 0xF2, 0x63, 0x9A, 0x19, 0x7C, 0xAE, 0xE5, 0xF5,
168 0xF7, 0x16, 0x6A, 0xA2, 0x39, 0xB6, 0x7B, 0x0F, 0xC1, 0x93, 0x81, 0x1B,
169 0xEE, 0xB4, 0x1A, 0xEA, 0xD0, 0x91, 0x2F, 0xB8, 0x55, 0xB9, 0xDA, 0x85,
170 0x3F, 0x41, 0xBF, 0xE0, 0x5A, 0x58, 0x80, 0x5F, 0x66, 0x0B, 0xD8, 0x90,
171 0x35, 0xD5, 0xC0, 0xA7, 0x33, 0x06, 0x65, 0x69, 0x45, 0x00, 0x94, 0x56,
172 0x6D, 0x98, 0x9B, 0x76, 0x97, 0xFC, 0xB2, 0xC2, 0xB0, 0xFE, 0xDB, 0x20,
173 0xE1, 0xEB, 0xD6, 0xE4, 0xDD, 0x47, 0x4A, 0x1D, 0x42, 0xED, 0x9E, 0x6E,
174 0x49, 0x3C, 0xCD, 0x43, 0x27, 0xD2, 0x07, 0xD4, 0xDE, 0xC7, 0x67, 0x18,
175 0x89, 0xCB, 0x30, 0x1F, 0x8D, 0xC6, 0x8F, 0xAA, 0xC8, 0x74, 0xDC, 0xC9,
176 0x5D, 0x5C, 0x31, 0xA4, 0x70, 0x88, 0x61, 0x2C, 0x9F, 0x0D, 0x2B, 0x87,
177 0x50, 0x82, 0x54, 0x64, 0x26, 0x7D, 0x03, 0x40, 0x34, 0x4B, 0x1C, 0x73,
178 0xD1, 0xC4, 0xFD, 0x3B, 0xCC, 0xFB, 0x7F, 0xAB, 0xE6, 0x3E, 0x5B, 0xA5,
179 0xAD, 0x04, 0x23, 0x9C, 0x14, 0x51, 0x22, 0xF0, 0x29, 0x79, 0x71, 0x7E,
180 0xFF, 0x8C, 0x0E, 0xE2, 0x0C, 0xEF, 0xBC, 0x72, 0x75, 0x6F, 0x37, 0xA1,
181 0xEC, 0xD3, 0x8E, 0x62, 0x8B, 0x86, 0x10, 0xE8, 0x08, 0x77, 0x11, 0xBE,
182 0x92, 0x4F, 0x24, 0xC5, 0x32, 0x36, 0x9D, 0xCF, 0xF3, 0xA6, 0xBB, 0xAC,
183 0x5E, 0x6C, 0xA9, 0x13, 0x57, 0x25, 0xB5, 0xE3, 0xBD, 0xA8, 0x3A, 0x01,
184 0x05, 0x59, 0x2A, 0x46 };
185
186 for(size_t i = 0; i != 10; ++i)
187 for(size_t j = 0; j != 256; ++j)
188 FTAB[256*i+j] = F[j ^ key[9-i]];
189 }
190
191 /*
192 * Clear memory of sensitive data
193 */
194 void Skipjack::clear()
195 {
196 zeroise(FTAB);
197 }
198
199 }
Botan::Block_Cipher_Fixed_Params< 8, 10 >::BLOCK_SIZE
Definition: block_cipher.h:107
Botan::Skipjack::encrypt_n
void encrypt_n(const byte in[], byte out[], size_t blocks) const
Definition: skipjack.cpp:78
Botan::store_le
void store_le(u16bit in, byte out[2])
Definition: loadstor.h:427
Botan::get_byte
byte get_byte(size_t byte_num, T input)
Definition: get_byte.h:21
Botan::byte
unsigned char byte
Definition: types.h:22
Botan::u16bit
unsigned short u16bit
Definition: types.h:27
Botan
Definition: algo_base.h:14
Botan::load_le< u16bit >
u16bit load_le< u16bit >(const byte in[], size_t off)
Definition: loadstor.h:149
Botan::make_u16bit
u16bit make_u16bit(byte i0, byte i1)
Definition: loadstor.h:47
Botan::Skipjack::decrypt_n
void decrypt_n(const byte in[], byte out[], size_t blocks) const
Definition: skipjack.cpp:119
Botan::zeroise
void zeroise(MemoryRegion< T > &vec)
Definition: secmem.h:428
Botan::Skipjack::clear
void clear()
Definition: skipjack.cpp:194