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
11namespace Botan {
12
13namespace {
14
15/*
16* Skipjack Stepping Rule 'A'
17*/
18void 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*/
34void 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*/
48void 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*/
62void 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*/
78void 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*/
119void 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*/
160void 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*/
195 {
196 zeroise(FTAB);
197 }
198
199}
void decrypt_n(const byte in[], byte out[], size_t blocks) const
Definition skipjack.cpp:119
void encrypt_n(const byte in[], byte out[], size_t blocks) const
Definition skipjack.cpp:78
void zeroise(MemoryRegion< T > &vec)
Definition secmem.h:428
byte get_byte(size_t byte_num, T input)
Definition get_byte.h:21
T load_le(const byte in[], size_t off)
Definition loadstor.h:116
u16bit make_u16bit(byte i0, byte i1)
Definition loadstor.h:47
unsigned short u16bit
Definition types.h:27
void store_le(u16bit in, byte out[2])
Definition loadstor.h:427