chiark / gitweb /
bfb2fd3b5e949693a6359d3e628b0d884bd512ac
[kalyna-python] / ref / transformations.h
1 /*
2
3 Constant and basic transformations for the reference implementation of the Kalyna block cipher (DSTU 7624:2014)
4
5 Authors: Ruslan Kiianchuk, Ruslan Mordvinov, Roman Oliynykov
6
7 */
8
9 #ifndef KALYNA_DEFS_H
10 #define KALYNA_DEFS_H
11
12
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <memory.h>
16 #include <limits.h>
17
18 #include "kalyna.h"
19
20
21 #if (ULLONG_MAX != 0xFFFFFFFFFFFFFFFFULL)
22 #error "Architecture not supported. Required type to fit 64 bits."
23 #endif
24
25 #define kBITS_IN_WORD 64
26
27 #if (CHAR_BIT != 8)
28 #error "Architecture not supported. Required type to fit 8 bits."
29 #endif
30
31 #define kBITS_IN_BYTE 8
32
33 #define TRUE 1
34 #define FALSE 0
35
36 /* Block words size. */
37 #define kNB_128 2
38 #define kNB_256 4
39 #define kNB_512 8
40
41 /* Key words size. */
42 #define kNK_128 2
43 #define kNK_256 4
44 #define kNK_512 8
45
46 /* Block bits size. */
47 #define kBLOCK_128 kNB_128 * kBITS_IN_WORD
48 #define kBLOCK_256 kNB_256 * kBITS_IN_WORD
49 #define kBLOCK_512 kNB_512 * kBITS_IN_WORD
50
51 /* Block bits size. */
52 #define kKEY_128 kNK_128 * kBITS_IN_WORD
53 #define kKEY_256 kNK_256 * kBITS_IN_WORD
54 #define kKEY_512 kNK_512 * kBITS_IN_WORD
55
56 /* Number of enciphering rounds size depending on key length. */
57 #define kNR_128 10
58 #define kNR_256 14
59 #define kNR_512 18
60
61 #define kREDUCTION_POLYNOMIAL 0x011d  /* x^8 + x^4 + x^3 + x^2 + 1 */
62
63 /*!
64  * Index a byte array as cipher state matrix.
65  */
66 #define INDEX(table, row, col) table[(row) + (col) * sizeof(uint64_t)]
67
68
69 /*!
70  * Substitute each byte of the cipher state using corresponding S-Boxes.
71  *
72  * @param ctx Initialized cipher context with current state and round keys 
73  * precomputed.
74  */
75 void SubBytes(kalyna_t* ctx);
76
77 /*!
78  * Inverse SubBytes transformation.
79  *
80  * @param ctx Initialized cipher context with current state and round keys 
81  * precomputed.
82  */
83 void InvSubBytes(kalyna_t* ctx);
84
85 /*!
86  * Shift cipher state rows according to specification.
87  *
88  * @param ctx Initialized cipher context with current state and round keys 
89  * precomputed.
90  */
91 void ShiftRows(kalyna_t* ctx);
92
93 /*!
94  * Inverse ShiftRows transformation.
95  *
96  * @param ctx Initialized cipher context with current state and round keys 
97  * precomputed.
98  */
99 void InvShiftRows(kalyna_t* ctx);
100
101 /*!
102  * Multiply bytes in Finite Field GF(2^8).
103  *
104  * @param x Multiplicand element of GF(2^8).
105  * @param y Multiplier element of GF(2^8) from MDS matrix.
106  * @return Product of multiplication in GF(2^8).
107  */                                                         
108 uint8_t MultiplyGF(uint8_t x, uint8_t y);
109
110
111 /*!
112  * Multiply cipher state by specified MDS matrix. 
113  * Used to avoid code repetition for MixColumn and Inverse MixColumn.
114  *
115  * @param ctx Initialized cipher context with current state and round keys 
116  * precomputed.
117  * @param matrix MDS 8x8 byte matrix.
118  */
119 void MatrixMultiply(kalyna_t* ctx, uint8_t matrix[8][8]);
120
121 /*!
122  * Perform MixColumn transformation to the cipher state.
123  *
124  * @param ctx Initialized cipher context with current state and round keys 
125  * precomputed.
126  */
127 void MixColumns(kalyna_t* ctx);
128
129 /*!
130  * Inverse MixColumn transformation.
131  *
132  * @param ctx Initialized cipher context with current state and round keys 
133  * precomputed.
134  */
135 void InvMixColumns(kalyna_t* ctx);
136
137 /*!
138  * Perform single round enciphering routine.
139  *
140  * @param ctx Initialized cipher context with current state and round keys 
141  * precomputed.
142  */
143 void EncipherRound(kalyna_t* ctx);
144
145 /*!
146  * Perform single round deciphering routine.
147  *
148  * @param ctx Initialized cipher context with current state and round keys 
149  * precomputed.
150  */
151 void DecipherRound(kalyna_t* ctx);
152
153
154 /*!
155  * Inject round key into the state using addition modulo 2^{64}.
156  *
157  * @param round Number of the round on which the key addition is performed in
158  * order to use the correct round key.
159  * @param ctx Initialized cipher context with current state and round keys 
160  * precomputed.
161  */
162 void AddRoundKey(int round, kalyna_t* ctx);
163
164 /*!
165  * Extract round key from the state using subtraction modulo 2^{64}.
166  *
167  * @param round Number of the round on which the key subtraction is performed 
168  * in order to use the correct round key.
169  * @param ctx Initialized cipher context with current state and round keys 
170  * precomputed.
171  */
172 void SubRoundKey(int round, kalyna_t* ctx);
173
174 /*!
175  * Perform addition of two arbitrary states modulo 2^{64}.
176  * The operation is identical to simple round key addition but on arbitrary 
177  * state array and addition value (instead of the actual round key). Used in
178  * key expansion procedure. The result is stored in `state`.
179  * 
180  * @param ctx Initialized cipher context with current state and round keys 
181  * precomputed.
182  * @param value Is to be added to the state array modulo 2^{64}.
183  */
184 void AddRoundKeyExpand(uint64_t* value, kalyna_t* ctx);
185
186 /*!
187  * Inject round key into the state using XOR operation.
188  *
189  * @param round Number of the round on which the key addition is performed in
190  * order to use the correct round key.
191  * @param ctx Initialized cipher context with current state and round keys 
192  * precomputed.
193  */
194 void XorRoundKey(int round, kalyna_t* ctx);
195
196 /*!
197  * Perform XOR of two arbitrary states.
198  * The operation is identical to simple round key XORing but on arbitrary 
199  * state array and addition value (instead of the actual round key). Used in
200  * key expansion procedure. The result is stored in `state`.
201  * XOR operation is involutive so no inverse transformation is required.
202  * 
203  * @param ctx Initialized cipher context with current state and round keys 
204  * precomputed.
205  * @param value Is to be added to the state array modulo 2^{64}.
206  */
207 void XorRoundKeyExpand(uint64_t* value, kalyna_t* ctx);
208
209 /*!
210  * Rotate words of a state.
211  * The state is processed as 64-bit words array {w_{0}, w_{1}, ..., w_{nk-1}}
212  * and rotation is performed so the resulting state is 
213  * {w_{1}, ..., w_{nk-1}, w_{0}}.
214  *
215  * @param ctx Initialized cipher context with current state and round keys 
216  * precomputed.
217  * @param state_value A state represented by 64-bit words array of length Nk.
218  * It is not the cipher state that is used during enciphering.
219  */
220 void Rotate(size_t state_size, uint64_t* state_value);
221
222 /*!
223  * Shift each word one bit to the left.
224  * The shift of each word is independent of other array words.
225  *
226  * @param state_size Size of the state to be shifted. 
227  * @param state_value State represented as 64-bit words array.  Note that this 
228  * state Nk words long and differs from the cipher state used during 
229  * enciphering.
230  */
231 void ShiftLeft(size_t state_size, uint64_t* state_value);
232
233 /*!
234  * Rotate the state (2 * Nb + 3) bytes to the left.
235  * The state is interpreted as bytes string in little endian. Big endian
236  * architectures are also correctly processed by this function.
237  *
238  * @param ctx Initialized cipher context with current state and round keys 
239  * precomputed.
240  * @param state_value A state represented by 64-bit words array of length Nk.
241  * It is not the cipher state that is used during enciphering.
242  */
243 void RotateLeft(size_t state_size, uint64_t* state_value);
244
245 /*!
246  * Generate the Kt value (auxiliary key used in key expansion).
247  *
248  * @param ctx Initialized cipher context with current state and round keys 
249  * precomputed.
250  * @param key Enciphering key of size corresponding to the one stored in cipher
251  * context `ctx` (specified via KalynaInit() function).
252  * @param kt Array for storing generated Kt value.
253  */
254 void KeyExpandKt(uint64_t* key, kalyna_t* ctx, uint64_t* kt);
255
256
257 /*!
258  * Compute even round keys and store them in cipher context `ctx`.
259  *
260  * @param key Kalyna enciphering key of length Nk 64-bit words.
261  * @param kt Kalyna auxiliary key. The size is equal to enciphering state
262  * size and equals Nb 64-bit words.
263  * @param ctx Initialized cipher context.
264  */
265 void KeyExpandEven(uint64_t* key, uint64_t* kt, kalyna_t* ctx);
266
267 /*!
268  * Compute odd round keys by rotating already generated even ones and
269  * fill in the rest of the round keys in cipher context `ctx`.
270  *
271  * @param ctx Initialized cipher context.
272  */
273 void KeyExpandOdd(kalyna_t* ctx);
274
275 /*!
276  * Convert array of 64-bit words to array of bytes.
277  * Each word is interpreted as byte sequence following little endian
278  * convention. However a check for big endian and corresponding word reversion
279  * is performed if needed.
280  *
281  * @param length Length of 64-bit words array.
282  * @param words Pointer to 64-bit words array.
283  * @return Pointer to bytes array.
284  */
285 uint8_t* WordsToBytes(size_t length, uint64_t* words);
286
287 /*!
288  * Convert array of bytes to array of 64-bit words.
289  * Each word is interpreted as byte sequence following little endian
290  * convention. However a check for big endian and corresponding word reversion
291  * is performed if needed.
292  *
293  * @param length Length of bytes array.
294  * @param words Pointer to bytes array.
295  * @return Pointer to 64-bit words array.
296  */
297 uint64_t* BytesToWords(size_t length, uint8_t* bytes);
298
299 /*!
300  * Reverse bytes ordering that form the word.
301  *
302  * @param word 64-bit word that needs its bytes to be reversed (perhaps for
303  * converting between little and big endian).
304  * @return 64-bit word with reversed bytes.
305  */
306 uint64_t ReverseWord(uint64_t word);
307
308 /*!
309  * Check if architecture follows big endian convention.
310  *
311  * @return 1 if architecture is big endian, 0 if it is little endian.
312  */
313 int IsBigEndian();
314
315 /*!
316  * Print specified cipher state (or any similar array) to stdout.
317  *
318  * @param length Length of the words array.
319  * @param state State represented as words array.
320  */
321 void PrintState(size_t length, uint64_t* state);
322
323 #endif  /* KALYNA_DEFS_H */
324