chiark / gitweb /
kalyna-python.c, setup.py: Actually implement the bindings.
[kalyna-python] / ref / transformations.h
CommitLineData
22eafbca
RO
1/*
2
3Constant and basic transformations for the reference implementation of the Kalyna block cipher (DSTU 7624:2014)
4
5Authors: 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 */
75void 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 */
83void 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 */
91void 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 */
99void 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 */
108uint8_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 */
119void 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 */
127void 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 */
135void 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 */
143void 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 */
151void 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 */
162void 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 */
172void 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 */
184void 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 */
194void 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 */
207void 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 */
220void 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 */
231void 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 */
243void 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 */
254void 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 */
265void 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 */
273void 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 */
285uint8_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 */
297uint64_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 */
306uint64_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 */
0a501374 313int IsBigEndian(void);
22eafbca
RO
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 */
321void PrintState(size_t length, uint64_t* state);
322
323#endif /* KALYNA_DEFS_H */
324