2 * Argon2 reference source code package - reference C implementations
5 * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
7 * You may use this work under the terms of a Creative Commons CC0 1.0
8 * License/Waiver or the Apache Public License 2.0, at your option. The terms of
9 * these licenses can be found at:
11 * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
12 * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
14 * You should have received a copy of both of these licenses along with this
15 * software. If not, they may be obtained at the above URLs.
18 #ifndef PORTABLE_BLAKE2_IMPL_H
19 #define PORTABLE_BLAKE2_IMPL_H
25 #define BLAKE2_INLINE __inline
26 #elif defined(__GNUC__) || defined(__clang__)
27 #define BLAKE2_INLINE __inline__
32 /* Argon2 Team - Begin Code */
34 Not an exhaustive list, but should cover the majority of modern platforms
35 Additionally, the code will always be correct---this is only a performance
38 #if (defined(__BYTE_ORDER__) && \
39 (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) || \
40 defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || defined(__MIPSEL__) || \
41 defined(__AARCH64EL__) || defined(__amd64__) || defined(__i386__) || \
42 defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || \
44 #define NATIVE_LITTLE_ENDIAN
46 /* Argon2 Team - End Code */
48 static BLAKE2_INLINE uint32_t load32(const void *src) {
49 #if defined(NATIVE_LITTLE_ENDIAN)
51 memcpy(&w, src, sizeof w);
54 const uint8_t *p = (const uint8_t *)src;
56 w |= (uint32_t)(*p++) << 8;
57 w |= (uint32_t)(*p++) << 16;
58 w |= (uint32_t)(*p++) << 24;
63 static BLAKE2_INLINE uint64_t load64(const void *src) {
64 #if defined(NATIVE_LITTLE_ENDIAN)
66 memcpy(&w, src, sizeof w);
69 const uint8_t *p = (const uint8_t *)src;
71 w |= (uint64_t)(*p++) << 8;
72 w |= (uint64_t)(*p++) << 16;
73 w |= (uint64_t)(*p++) << 24;
74 w |= (uint64_t)(*p++) << 32;
75 w |= (uint64_t)(*p++) << 40;
76 w |= (uint64_t)(*p++) << 48;
77 w |= (uint64_t)(*p++) << 56;
82 static BLAKE2_INLINE void store32(void *dst, uint32_t w) {
83 #if defined(NATIVE_LITTLE_ENDIAN)
84 memcpy(dst, &w, sizeof w);
86 uint8_t *p = (uint8_t *)dst;
97 static BLAKE2_INLINE void store64(void *dst, uint64_t w) {
98 #if defined(NATIVE_LITTLE_ENDIAN)
99 memcpy(dst, &w, sizeof w);
101 uint8_t *p = (uint8_t *)dst;
120 static BLAKE2_INLINE uint64_t load48(const void *src) {
121 const uint8_t *p = (const uint8_t *)src;
123 w |= (uint64_t)(*p++) << 8;
124 w |= (uint64_t)(*p++) << 16;
125 w |= (uint64_t)(*p++) << 24;
126 w |= (uint64_t)(*p++) << 32;
127 w |= (uint64_t)(*p++) << 40;
131 static BLAKE2_INLINE void store48(void *dst, uint64_t w) {
132 uint8_t *p = (uint8_t *)dst;
146 static BLAKE2_INLINE uint32_t rotr32(const uint32_t w, const unsigned c) {
147 return (w >> c) | (w << (32 - c));
150 static BLAKE2_INLINE uint64_t rotr64(const uint64_t w, const unsigned c) {
151 return (w >> c) | (w << (64 - c));