]>
Commit | Line | Data |
---|---|---|
86e3c28a CIK |
1 | /* |
2 | * Platform-specific definitions for Skein hash function. | |
3 | * | |
4 | * Source code author: Doug Whiting, 2008. | |
5 | * | |
6 | * This algorithm and source code is released to the public domain. | |
7 | * | |
8 | * Many thanks to Brian Gladman for his portable header files. | |
9 | * | |
10 | * To port Skein to an "unsupported" platform, change the definitions | |
11 | * in this file appropriately. | |
12 | */ | |
13 | /* Copyright 2013 Doug Whiting. This code is released to the public domain. */ | |
14 | ||
15 | #ifndef _SKEIN_PORT_H_ | |
16 | #define _SKEIN_PORT_H_ | |
17 | ||
18 | #include <sys/types.h> /* get integer type definitions */ | |
19 | #include <sys/systm.h> /* for bcopy() */ | |
20 | ||
21 | #ifndef RotL_64 | |
22 | #define RotL_64(x, N) (((x) << (N)) | ((x) >> (64 - (N)))) | |
23 | #endif | |
24 | ||
25 | /* | |
26 | * Skein is "natively" little-endian (unlike SHA-xxx), for optimal | |
27 | * performance on x86 CPUs. The Skein code requires the following | |
28 | * definitions for dealing with endianness: | |
29 | * | |
30 | * SKEIN_NEED_SWAP: 0 for little-endian, 1 for big-endian | |
31 | * Skein_Put64_LSB_First | |
32 | * Skein_Get64_LSB_First | |
33 | * Skein_Swap64 | |
34 | * | |
35 | * If SKEIN_NEED_SWAP is defined at compile time, it is used here | |
36 | * along with the portable versions of Put64/Get64/Swap64, which | |
37 | * are slow in general. | |
38 | * | |
39 | * Otherwise, an "auto-detect" of endianness is attempted below. | |
40 | * If the default handling doesn't work well, the user may insert | |
41 | * platform-specific code instead (e.g., for big-endian CPUs). | |
42 | * | |
43 | */ | |
44 | #ifndef SKEIN_NEED_SWAP /* compile-time "override" for endianness? */ | |
45 | ||
46 | #include <sys/isa_defs.h> /* get endianness selection */ | |
47 | ||
48 | #define PLATFORM_MUST_ALIGN _ALIGNMENT_REQUIRED | |
49 | #if defined(_BIG_ENDIAN) | |
50 | /* here for big-endian CPUs */ | |
51 | #define SKEIN_NEED_SWAP (1) | |
52 | #else | |
53 | /* here for x86 and x86-64 CPUs (and other detected little-endian CPUs) */ | |
54 | #define SKEIN_NEED_SWAP (0) | |
55 | #if PLATFORM_MUST_ALIGN == 0 /* ok to use "fast" versions? */ | |
56 | #define Skein_Put64_LSB_First(dst08, src64, bCnt) bcopy(src64, dst08, bCnt) | |
57 | #define Skein_Get64_LSB_First(dst64, src08, wCnt) \ | |
58 | bcopy(src08, dst64, 8 * (wCnt)) | |
59 | #endif | |
60 | #endif | |
61 | ||
62 | #endif /* ifndef SKEIN_NEED_SWAP */ | |
63 | ||
64 | /* | |
65 | * Provide any definitions still needed. | |
66 | */ | |
67 | #ifndef Skein_Swap64 /* swap for big-endian, nop for little-endian */ | |
68 | #if SKEIN_NEED_SWAP | |
69 | #define Skein_Swap64(w64) \ | |
70 | (((((uint64_t)(w64)) & 0xFF) << 56) | \ | |
71 | (((((uint64_t)(w64)) >> 8) & 0xFF) << 48) | \ | |
72 | (((((uint64_t)(w64)) >> 16) & 0xFF) << 40) | \ | |
73 | (((((uint64_t)(w64)) >> 24) & 0xFF) << 32) | \ | |
74 | (((((uint64_t)(w64)) >> 32) & 0xFF) << 24) | \ | |
75 | (((((uint64_t)(w64)) >> 40) & 0xFF) << 16) | \ | |
76 | (((((uint64_t)(w64)) >> 48) & 0xFF) << 8) | \ | |
77 | (((((uint64_t)(w64)) >> 56) & 0xFF))) | |
78 | #else | |
79 | #define Skein_Swap64(w64) (w64) | |
80 | #endif | |
81 | #endif /* ifndef Skein_Swap64 */ | |
82 | ||
83 | #ifndef Skein_Put64_LSB_First | |
84 | void | |
85 | Skein_Put64_LSB_First(uint8_t *dst, const uint64_t *src, size_t bCnt) | |
86 | #ifdef SKEIN_PORT_CODE /* instantiate the function code here? */ | |
87 | { | |
88 | /* | |
89 | * this version is fully portable (big-endian or little-endian), | |
90 | * but slow | |
91 | */ | |
92 | size_t n; | |
93 | ||
94 | for (n = 0; n < bCnt; n++) | |
95 | dst[n] = (uint8_t)(src[n >> 3] >> (8 * (n & 7))); | |
96 | } | |
97 | #else | |
98 | ; /* output only the function prototype */ | |
99 | #endif | |
100 | #endif /* ifndef Skein_Put64_LSB_First */ | |
101 | ||
102 | #ifndef Skein_Get64_LSB_First | |
103 | void | |
104 | Skein_Get64_LSB_First(uint64_t *dst, const uint8_t *src, size_t wCnt) | |
105 | #ifdef SKEIN_PORT_CODE /* instantiate the function code here? */ | |
106 | { | |
107 | /* | |
108 | * this version is fully portable (big-endian or little-endian), | |
109 | * but slow | |
110 | */ | |
111 | size_t n; | |
112 | ||
113 | for (n = 0; n < 8 * wCnt; n += 8) | |
114 | dst[n / 8] = (((uint64_t)src[n])) + | |
115 | (((uint64_t)src[n + 1]) << 8) + | |
116 | (((uint64_t)src[n + 2]) << 16) + | |
117 | (((uint64_t)src[n + 3]) << 24) + | |
118 | (((uint64_t)src[n + 4]) << 32) + | |
119 | (((uint64_t)src[n + 5]) << 40) + | |
120 | (((uint64_t)src[n + 6]) << 48) + | |
121 | (((uint64_t)src[n + 7]) << 56); | |
122 | } | |
123 | #else | |
124 | ; /* output only the function prototype */ | |
125 | #endif | |
126 | #endif /* ifndef Skein_Get64_LSB_First */ | |
127 | ||
128 | #endif /* _SKEIN_PORT_H_ */ |