Coverage Report

Created: 2024-11-21 07:03

/src/trezor-firmware/crypto/groestl_internal.h
Line
Count
Source (jump to first uncovered line)
1
/* Groestl hash from https://github.com/Groestlcoin/vanitygen
2
 * Trezor adaptation by Yura Pakhuchiy <pakhuchiy@gmail.com>. */
3
/**
4
 * Basic type definitions.
5
 *
6
 * This header file defines the generic integer types that will be used
7
 * for the implementation of hash functions; it also contains helper
8
 * functions which encode and decode multi-byte integer values, using
9
 * either little-endian or big-endian conventions.
10
 *
11
 * This file contains a compile-time test on the size of a byte
12
 * (the <code>unsigned char</code> C type). If bytes are not octets,
13
 * i.e. if they do not have a size of exactly 8 bits, then compilation
14
 * is aborted. Architectures where bytes are not octets are relatively
15
 * rare, even in the embedded devices market. We forbid non-octet bytes
16
 * because there is no clear convention on how octet streams are encoded
17
 * on such systems.
18
 *
19
 * ==========================(LICENSE BEGIN)============================
20
 *
21
 * Copyright (c) 2007-2010  Projet RNRT SAPHIR
22
 *
23
 * Permission is hereby granted, free of charge, to any person obtaining
24
 * a copy of this software and associated documentation files (the
25
 * "Software"), to deal in the Software without restriction, including
26
 * without limitation the rights to use, copy, modify, merge, publish,
27
 * distribute, sublicense, and/or sell copies of the Software, and to
28
 * permit persons to whom the Software is furnished to do so, subject to
29
 * the following conditions:
30
 *
31
 * The above copyright notice and this permission notice shall be
32
 * included in all copies or substantial portions of the Software.
33
 *
34
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
35
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
36
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
37
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
38
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
39
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
40
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
41
 *
42
 * ===========================(LICENSE END)=============================
43
 *
44
 * @file     sph_types.h
45
 * @author   Thomas Pornin <thomas.pornin@cryptolog.com>
46
 */
47
48
#ifndef GROESTL_INTERNAL_H__
49
#define GROESTL_INTERNAL_H__
50
51
#include <limits.h>
52
53
/*
54
 * All our I/O functions are defined over octet streams. We do not know
55
 * how to handle input data if bytes are not octets.
56
 */
57
#if CHAR_BIT != 8
58
#error This code requires 8-bit bytes
59
#endif
60
61
#if defined __STDC__ && __STDC_VERSION__ >= 199901L
62
63
#include <stdint.h>
64
65
typedef uint32_t sph_u32;
66
typedef int32_t sph_s32;
67
typedef uint64_t sph_u64;
68
typedef int64_t sph_s64;
69
70
46.3M
#define SPH_C32(x) ((sph_u32)(x))
71
53
#define SPH_C64(x) ((sph_u64)(x))
72
73
#else
74
#error We need at least C99 compiler
75
#endif
76
77
43.7M
#define SPH_T32(x) ((x) & SPH_C32(0xFFFFFFFF))
78
#define SPH_ROTL32(x, n) SPH_T32(((x) << (n)) | ((x) >> (32 - (n))))
79
#define SPH_ROTR32(x, n) SPH_ROTL32(x, (32 - (n)))
80
81
53
#define SPH_T64(x) ((x) & SPH_C64(0xFFFFFFFFFFFFFFFF))
82
#define SPH_ROTL64(x, n) SPH_T64(((x) << (n)) | ((x) >> (64 - (n))))
83
#define SPH_ROTR64(x, n) SPH_ROTL64(x, (64 - (n)))
84
85
/*
86
 * 32-bit x86, aka "i386 compatible".
87
 */
88
#if defined __i386__ || defined _M_IX86
89
90
#define SPH_DETECT_LITTLE_ENDIAN 1
91
#define SPH_DETECT_BIG_ENDIAN 0
92
93
/*
94
 * 64-bit x86, hereafter known as "amd64".
95
 */
96
#elif defined __x86_64 || defined _M_X64
97
98
#define SPH_DETECT_LITTLE_ENDIAN 1
99
#define SPH_DETECT_BIG_ENDIAN 0
100
101
/*
102
 * ARM, little-endian.
103
 */
104
#elif defined __arm__ && __ARMEL__
105
106
#define SPH_DETECT_LITTLE_ENDIAN 1
107
#define SPH_DETECT_BIG_ENDIAN 0
108
109
/*
110
 * ARM64, little-endian.
111
 */
112
#elif defined __aarch64__
113
114
#define SPH_DETECT_LITTLE_ENDIAN 1
115
#define SPH_DETECT_BIG_ENDIAN 0
116
117
#endif
118
119
#if defined SPH_DETECT_LITTLE_ENDIAN && !defined SPH_LITTLE_ENDIAN
120
#define SPH_LITTLE_ENDIAN SPH_DETECT_LITTLE_ENDIAN
121
#endif
122
#if defined SPH_DETECT_BIG_ENDIAN && !defined SPH_BIG_ENDIAN
123
#define SPH_BIG_ENDIAN SPH_DETECT_BIG_ENDIAN
124
#endif
125
126
0
static inline sph_u32 sph_bswap32(sph_u32 x) {
127
0
  x = SPH_T32((x << 16) | (x >> 16));
128
0
  x = ((x & SPH_C32(0xFF00FF00)) >> 8) | ((x & SPH_C32(0x00FF00FF)) << 8);
129
0
  return x;
130
0
}
131
132
/**
133
 * Byte-swap a 64-bit value.
134
 *
135
 * @param x   the input value
136
 * @return  the byte-swapped value
137
 */
138
0
static inline sph_u64 sph_bswap64(sph_u64 x) {
139
0
  x = SPH_T64((x << 32) | (x >> 32));
140
0
  x = ((x & SPH_C64(0xFFFF0000FFFF0000)) >> 16) |
141
0
      ((x & SPH_C64(0x0000FFFF0000FFFF)) << 16);
142
0
  x = ((x & SPH_C64(0xFF00FF00FF00FF00)) >> 8) |
143
0
      ((x & SPH_C64(0x00FF00FF00FF00FF)) << 8);
144
0
  return x;
145
0
}
146
147
0
static inline void sph_enc16be(void *dst, unsigned val) {
148
0
  ((unsigned char *)dst)[0] = (val >> 8);
149
0
  ((unsigned char *)dst)[1] = val;
150
0
}
151
152
0
static inline unsigned sph_dec16be(const void *src) {
153
0
  return ((unsigned)(((const unsigned char *)src)[0]) << 8) |
154
0
         (unsigned)(((const unsigned char *)src)[1]);
155
0
}
156
157
0
static inline void sph_enc16le(void *dst, unsigned val) {
158
0
  ((unsigned char *)dst)[0] = val;
159
0
  ((unsigned char *)dst)[1] = val >> 8;
160
0
}
161
162
0
static inline unsigned sph_dec16le(const void *src) {
163
0
  return (unsigned)(((const unsigned char *)src)[0]) |
164
0
         ((unsigned)(((const unsigned char *)src)[1]) << 8);
165
0
}
166
167
/**
168
 * Encode a 32-bit value into the provided buffer (big endian convention).
169
 *
170
 * @param dst   the destination buffer
171
 * @param val   the 32-bit value to encode
172
 */
173
0
static inline void sph_enc32be(void *dst, sph_u32 val) {
174
0
  ((unsigned char *)dst)[0] = (val >> 24);
175
0
  ((unsigned char *)dst)[1] = (val >> 16);
176
0
  ((unsigned char *)dst)[2] = (val >> 8);
177
0
  ((unsigned char *)dst)[3] = val;
178
0
}
179
180
/**
181
 * Encode a 32-bit value into the provided buffer (big endian convention).
182
 * The destination buffer must be properly aligned.
183
 *
184
 * @param dst   the destination buffer (32-bit aligned)
185
 * @param val   the value to encode
186
 */
187
0
static inline void sph_enc32be_aligned(void *dst, sph_u32 val) {
188
0
#if SPH_LITTLE_ENDIAN
189
0
  *(sph_u32 *)dst = sph_bswap32(val);
190
0
#elif SPH_BIG_ENDIAN
191
0
  *(sph_u32 *)dst = val;
192
0
#else
193
0
  ((unsigned char *)dst)[0] = (val >> 24);
194
0
  ((unsigned char *)dst)[1] = (val >> 16);
195
0
  ((unsigned char *)dst)[2] = (val >> 8);
196
0
  ((unsigned char *)dst)[3] = val;
197
0
#endif
198
0
}
199
200
/**
201
 * Decode a 32-bit value from the provided buffer (big endian convention).
202
 *
203
 * @param src   the source buffer
204
 * @return  the decoded value
205
 */
206
0
static inline sph_u32 sph_dec32be(const void *src) {
207
0
  return ((sph_u32)(((const unsigned char *)src)[0]) << 24) |
208
0
         ((sph_u32)(((const unsigned char *)src)[1]) << 16) |
209
0
         ((sph_u32)(((const unsigned char *)src)[2]) << 8) |
210
0
         (sph_u32)(((const unsigned char *)src)[3]);
211
0
}
212
213
/**
214
 * Decode a 32-bit value from the provided buffer (big endian convention).
215
 * The source buffer must be properly aligned.
216
 *
217
 * @param src   the source buffer (32-bit aligned)
218
 * @return  the decoded value
219
 */
220
0
static inline sph_u32 sph_dec32be_aligned(const void *src) {
221
0
#if SPH_LITTLE_ENDIAN
222
0
  return sph_bswap32(*(const sph_u32 *)src);
223
0
#elif SPH_BIG_ENDIAN
224
0
  return *(const sph_u32 *)src;
225
0
#else
226
0
  return ((sph_u32)(((const unsigned char *)src)[0]) << 24) |
227
0
         ((sph_u32)(((const unsigned char *)src)[1]) << 16) |
228
0
         ((sph_u32)(((const unsigned char *)src)[2]) << 8) |
229
0
         (sph_u32)(((const unsigned char *)src)[3]);
230
0
#endif
231
0
}
232
233
/**
234
 * Encode a 32-bit value into the provided buffer (little endian convention).
235
 *
236
 * @param dst   the destination buffer
237
 * @param val   the 32-bit value to encode
238
 */
239
848
static inline void sph_enc32le(void *dst, sph_u32 val) {
240
848
  ((unsigned char *)dst)[0] = val;
241
848
  ((unsigned char *)dst)[1] = (val >> 8);
242
848
  ((unsigned char *)dst)[2] = (val >> 16);
243
848
  ((unsigned char *)dst)[3] = (val >> 24);
244
848
}
245
246
/**
247
 * Encode a 32-bit value into the provided buffer (little endian convention).
248
 * The destination buffer must be properly aligned.
249
 *
250
 * @param dst   the destination buffer (32-bit aligned)
251
 * @param val   the value to encode
252
 */
253
0
static inline void sph_enc32le_aligned(void *dst, sph_u32 val) {
254
0
#if SPH_LITTLE_ENDIAN
255
0
  *(sph_u32 *)dst = val;
256
0
#elif SPH_BIG_ENDIAN
257
0
  *(sph_u32 *)dst = sph_bswap32(val);
258
0
#else
259
0
  ((unsigned char *)dst)[0] = val;
260
0
  ((unsigned char *)dst)[1] = (val >> 8);
261
0
  ((unsigned char *)dst)[2] = (val >> 16);
262
0
  ((unsigned char *)dst)[3] = (val >> 24);
263
0
#endif
264
0
}
265
266
/**
267
 * Decode a 32-bit value from the provided buffer (little endian convention).
268
 *
269
 * @param src   the source buffer
270
 * @return  the decoded value
271
 */
272
0
static inline sph_u32 sph_dec32le(const void *src) {
273
0
  return (sph_u32)(((const unsigned char *)src)[0]) |
274
0
         ((sph_u32)(((const unsigned char *)src)[1]) << 8) |
275
0
         ((sph_u32)(((const unsigned char *)src)[2]) << 16) |
276
0
         ((sph_u32)(((const unsigned char *)src)[3]) << 24);
277
0
}
278
279
/**
280
 * Decode a 32-bit value from the provided buffer (little endian convention).
281
 * The source buffer must be properly aligned.
282
 *
283
 * @param src   the source buffer (32-bit aligned)
284
 * @return  the decoded value
285
 */
286
367k
static inline sph_u32 sph_dec32le_aligned(const void *src) {
287
367k
#if SPH_LITTLE_ENDIAN
288
367k
  return *(const sph_u32 *)src;
289
#elif SPH_BIG_ENDIAN
290
  return sph_bswap32(*(const sph_u32 *)src);
291
#else
292
  return (sph_u32)(((const unsigned char *)src)[0]) |
293
         ((sph_u32)(((const unsigned char *)src)[1]) << 8) |
294
         ((sph_u32)(((const unsigned char *)src)[2]) << 16) |
295
         ((sph_u32)(((const unsigned char *)src)[3]) << 24);
296
#endif
297
367k
}
298
299
/**
300
 * Encode a 64-bit value into the provided buffer (big endian convention).
301
 *
302
 * @param dst   the destination buffer
303
 * @param val   the 64-bit value to encode
304
 */
305
53
static inline void sph_enc64be(void *dst, sph_u64 val) {
306
53
  ((unsigned char *)dst)[0] = (val >> 56);
307
53
  ((unsigned char *)dst)[1] = (val >> 48);
308
53
  ((unsigned char *)dst)[2] = (val >> 40);
309
53
  ((unsigned char *)dst)[3] = (val >> 32);
310
53
  ((unsigned char *)dst)[4] = (val >> 24);
311
53
  ((unsigned char *)dst)[5] = (val >> 16);
312
53
  ((unsigned char *)dst)[6] = (val >> 8);
313
53
  ((unsigned char *)dst)[7] = val;
314
53
}
315
316
/**
317
 * Encode a 64-bit value into the provided buffer (big endian convention).
318
 * The destination buffer must be properly aligned.
319
 *
320
 * @param dst   the destination buffer (64-bit aligned)
321
 * @param val   the value to encode
322
 */
323
0
static inline void sph_enc64be_aligned(void *dst, sph_u64 val) {
324
0
#if SPH_LITTLE_ENDIAN
325
0
  *(sph_u64 *)dst = sph_bswap64(val);
326
0
#elif SPH_BIG_ENDIAN
327
0
  *(sph_u64 *)dst = val;
328
0
#else
329
0
  ((unsigned char *)dst)[0] = (val >> 56);
330
0
  ((unsigned char *)dst)[1] = (val >> 48);
331
0
  ((unsigned char *)dst)[2] = (val >> 40);
332
0
  ((unsigned char *)dst)[3] = (val >> 32);
333
0
  ((unsigned char *)dst)[4] = (val >> 24);
334
0
  ((unsigned char *)dst)[5] = (val >> 16);
335
0
  ((unsigned char *)dst)[6] = (val >> 8);
336
0
  ((unsigned char *)dst)[7] = val;
337
0
#endif
338
0
}
339
340
/**
341
 * Decode a 64-bit value from the provided buffer (big endian convention).
342
 *
343
 * @param src   the source buffer
344
 * @return  the decoded value
345
 */
346
0
static inline sph_u64 sph_dec64be(const void *src) {
347
0
  return ((sph_u64)(((const unsigned char *)src)[0]) << 56) |
348
0
         ((sph_u64)(((const unsigned char *)src)[1]) << 48) |
349
0
         ((sph_u64)(((const unsigned char *)src)[2]) << 40) |
350
0
         ((sph_u64)(((const unsigned char *)src)[3]) << 32) |
351
0
         ((sph_u64)(((const unsigned char *)src)[4]) << 24) |
352
0
         ((sph_u64)(((const unsigned char *)src)[5]) << 16) |
353
0
         ((sph_u64)(((const unsigned char *)src)[6]) << 8) |
354
0
         (sph_u64)(((const unsigned char *)src)[7]);
355
0
}
356
357
/**
358
 * Decode a 64-bit value from the provided buffer (big endian convention).
359
 * The source buffer must be properly aligned.
360
 *
361
 * @param src   the source buffer (64-bit aligned)
362
 * @return  the decoded value
363
 */
364
0
static inline sph_u64 sph_dec64be_aligned(const void *src) {
365
0
#if SPH_LITTLE_ENDIAN
366
0
  return sph_bswap64(*(const sph_u64 *)src);
367
0
#elif SPH_BIG_ENDIAN
368
0
  return *(const sph_u64 *)src;
369
0
#else
370
0
  return ((sph_u64)(((const unsigned char *)src)[0]) << 56) |
371
0
         ((sph_u64)(((const unsigned char *)src)[1]) << 48) |
372
0
         ((sph_u64)(((const unsigned char *)src)[2]) << 40) |
373
0
         ((sph_u64)(((const unsigned char *)src)[3]) << 32) |
374
0
         ((sph_u64)(((const unsigned char *)src)[4]) << 24) |
375
0
         ((sph_u64)(((const unsigned char *)src)[5]) << 16) |
376
0
         ((sph_u64)(((const unsigned char *)src)[6]) << 8) |
377
0
         (sph_u64)(((const unsigned char *)src)[7]);
378
0
#endif
379
0
}
380
381
/**
382
 * Encode a 64-bit value into the provided buffer (little endian convention).
383
 *
384
 * @param dst   the destination buffer
385
 * @param val   the 64-bit value to encode
386
 */
387
0
static inline void sph_enc64le(void *dst, sph_u64 val) {
388
0
  ((unsigned char *)dst)[0] = val;
389
0
  ((unsigned char *)dst)[1] = (val >> 8);
390
0
  ((unsigned char *)dst)[2] = (val >> 16);
391
0
  ((unsigned char *)dst)[3] = (val >> 24);
392
0
  ((unsigned char *)dst)[4] = (val >> 32);
393
0
  ((unsigned char *)dst)[5] = (val >> 40);
394
0
  ((unsigned char *)dst)[6] = (val >> 48);
395
0
  ((unsigned char *)dst)[7] = (val >> 56);
396
0
}
397
398
/**
399
 * Encode a 64-bit value into the provided buffer (little endian convention).
400
 * The destination buffer must be properly aligned.
401
 *
402
 * @param dst   the destination buffer (64-bit aligned)
403
 * @param val   the value to encode
404
 */
405
0
static inline void sph_enc64le_aligned(void *dst, sph_u64 val) {
406
0
#if SPH_LITTLE_ENDIAN
407
0
  *(sph_u64 *)dst = val;
408
0
#elif SPH_BIG_ENDIAN
409
0
  *(sph_u64 *)dst = sph_bswap64(val);
410
0
#else
411
0
  ((unsigned char *)dst)[0] = val;
412
0
  ((unsigned char *)dst)[1] = (val >> 8);
413
0
  ((unsigned char *)dst)[2] = (val >> 16);
414
0
  ((unsigned char *)dst)[3] = (val >> 24);
415
0
  ((unsigned char *)dst)[4] = (val >> 32);
416
0
  ((unsigned char *)dst)[5] = (val >> 40);
417
0
  ((unsigned char *)dst)[6] = (val >> 48);
418
0
  ((unsigned char *)dst)[7] = (val >> 56);
419
0
#endif
420
0
}
421
422
/**
423
 * Decode a 64-bit value from the provided buffer (little endian convention).
424
 *
425
 * @param src   the source buffer
426
 * @return  the decoded value
427
 */
428
0
static inline sph_u64 sph_dec64le(const void *src) {
429
0
  return (sph_u64)(((const unsigned char *)src)[0]) |
430
0
         ((sph_u64)(((const unsigned char *)src)[1]) << 8) |
431
0
         ((sph_u64)(((const unsigned char *)src)[2]) << 16) |
432
0
         ((sph_u64)(((const unsigned char *)src)[3]) << 24) |
433
0
         ((sph_u64)(((const unsigned char *)src)[4]) << 32) |
434
0
         ((sph_u64)(((const unsigned char *)src)[5]) << 40) |
435
0
         ((sph_u64)(((const unsigned char *)src)[6]) << 48) |
436
0
         ((sph_u64)(((const unsigned char *)src)[7]) << 56);
437
0
}
438
439
/**
440
 * Decode a 64-bit value from the provided buffer (little endian convention).
441
 * The source buffer must be properly aligned.
442
 *
443
 * @param src   the source buffer (64-bit aligned)
444
 * @return  the decoded value
445
 */
446
0
static inline sph_u64 sph_dec64le_aligned(const void *src) {
447
0
#if SPH_LITTLE_ENDIAN
448
0
  return *(const sph_u64 *)src;
449
0
#elif SPH_BIG_ENDIAN
450
0
  return sph_bswap64(*(const sph_u64 *)src);
451
0
#else
452
0
  return (sph_u64)(((const unsigned char *)src)[0]) |
453
0
         ((sph_u64)(((const unsigned char *)src)[1]) << 8) |
454
0
         ((sph_u64)(((const unsigned char *)src)[2]) << 16) |
455
0
         ((sph_u64)(((const unsigned char *)src)[3]) << 24) |
456
0
         ((sph_u64)(((const unsigned char *)src)[4]) << 32) |
457
0
         ((sph_u64)(((const unsigned char *)src)[5]) << 40) |
458
0
         ((sph_u64)(((const unsigned char *)src)[6]) << 48) |
459
0
         ((sph_u64)(((const unsigned char *)src)[7]) << 56);
460
0
#endif
461
0
}
462
463
#endif