Electroneum
ed25519-donna-portable.h
Go to the documentation of this file.
2 
3 #define mul32x32_64(a,b) (((uint64_t)(a))*(b))
4 
5 /* platform */
6 #if defined(COMPILER_MSVC)
7  #include <intrin.h>
8  #if !defined(_DEBUG)
9  #undef mul32x32_64
10  #define mul32x32_64(a,b) __emulu(a,b)
11  #endif
12  #undef inline
13  #define inline __forceinline
14  #define DONNA_INLINE __forceinline
15  #define DONNA_NOINLINE __declspec(noinline)
16  #define ALIGN(x) __declspec(align(x))
17  #define ROTL32(a,b) _rotl(a,b)
18  #define ROTR32(a,b) _rotr(a,b)
19 #else
20  #include <sys/param.h>
21  #define DONNA_INLINE inline __attribute__((always_inline))
22  #define DONNA_NOINLINE __attribute__((noinline))
23  #define ALIGN(x) __attribute__((aligned(x)))
24  #define ROTL32(a,b) (((a) << (b)) | ((a) >> (32 - b)))
25  #define ROTR32(a,b) (((a) >> (b)) | ((a) << (32 - b)))
26 #endif
27 
28 /* uint128_t */
29 #if defined(CPU_64BITS) && !defined(ED25519_FORCE_32BIT)
30  #if defined(COMPILER_CLANG) && (COMPILER_CLANG >= 30100)
31  #define HAVE_NATIVE_UINT128
32  typedef unsigned __int128 uint128_t;
33  #elif defined(COMPILER_MSVC)
34  #define HAVE_UINT128
35  typedef struct uint128_t {
36  uint64_t lo, hi;
37  } uint128_t;
38  #define mul64x64_128(out,a,b) out.lo = _umul128(a,b,&out.hi);
39  #define shr128_pair(out,hi,lo,shift) out = __shiftright128(lo, hi, shift);
40  #define shl128_pair(out,hi,lo,shift) out = __shiftleft128(lo, hi, shift);
41  #define shr128(out,in,shift) shr128_pair(out, in.hi, in.lo, shift)
42  #define shl128(out,in,shift) shl128_pair(out, in.hi, in.lo, shift)
43  #define add128(a,b) { uint64_t p = a.lo; a.lo += b.lo; a.hi += b.hi + (a.lo < p); }
44  #define add128_64(a,b) { uint64_t p = a.lo; a.lo += b; a.hi += (a.lo < p); }
45  #define lo128(a) (a.lo)
46  #define hi128(a) (a.hi)
47  #elif defined(COMPILER_GCC) && !defined(HAVE_NATIVE_UINT128)
48  #if defined(__SIZEOF_INT128__)
49  #define HAVE_NATIVE_UINT128
50  typedef unsigned __int128 uint128_t;
51  #elif (COMPILER_GCC >= 40400)
52  #define HAVE_NATIVE_UINT128
53  typedef unsigned uint128_t __attribute__((mode(TI)));
54  #elif defined(CPU_X86_64)
55  #define HAVE_UINT128
56  typedef struct uint128_t {
57  uint64_t lo, hi;
58  } uint128_t;
59  #define mul64x64_128(out,a,b) __asm__ ("mulq %3" : "=a" (out.lo), "=d" (out.hi) : "a" (a), "rm" (b));
60  #define shr128_pair(out,hi,lo,shift) __asm__ ("shrdq %2,%1,%0" : "+r" (lo) : "r" (hi), "J" (shift)); out = lo;
61  #define shl128_pair(out,hi,lo,shift) __asm__ ("shldq %2,%1,%0" : "+r" (hi) : "r" (lo), "J" (shift)); out = hi;
62  #define shr128(out,in,shift) shr128_pair(out,in.hi, in.lo, shift)
63  #define shl128(out,in,shift) shl128_pair(out,in.hi, in.lo, shift)
64  #define add128(a,b) __asm__ ("addq %4,%2; adcq %5,%3" : "=r" (a.hi), "=r" (a.lo) : "1" (a.lo), "0" (a.hi), "rm" (b.lo), "rm" (b.hi) : "cc");
65  #define add128_64(a,b) __asm__ ("addq %4,%2; adcq $0,%3" : "=r" (a.hi), "=r" (a.lo) : "1" (a.lo), "0" (a.hi), "rm" (b) : "cc");
66  #define lo128(a) (a.lo)
67  #define hi128(a) (a.hi)
68  #endif
69  #endif
70 
71  #if defined(HAVE_NATIVE_UINT128)
72  #define HAVE_UINT128
73  #define mul64x64_128(out,a,b) out = (uint128_t)a * b;
74  #define shr128_pair(out,hi,lo,shift) out = (uint64_t)((((uint128_t)hi << 64) | lo) >> (shift));
75  #define shl128_pair(out,hi,lo,shift) out = (uint64_t)(((((uint128_t)hi << 64) | lo) << (shift)) >> 64);
76  #define shr128(out,in,shift) out = (uint64_t)(in >> (shift));
77  #define shl128(out,in,shift) out = (uint64_t)((in << shift) >> 64);
78  #define add128(a,b) a += b;
79  #define add128_64(a,b) a += (uint64_t)b;
80  #define lo128(a) ((uint64_t)a)
81  #define hi128(a) ((uint64_t)(a >> 64))
82  #endif
83 
84  #if !defined(HAVE_UINT128)
85  #error Need a uint128_t implementation!
86  #endif
87 #endif
88 
89 /* endian */
90 #if !defined(ED25519_OPENSSLRNG)
91 static inline void U32TO8_LE(unsigned char *p, const uint32_t v) {
92  p[0] = (unsigned char)(v );
93  p[1] = (unsigned char)(v >> 8);
94  p[2] = (unsigned char)(v >> 16);
95  p[3] = (unsigned char)(v >> 24);
96 }
97 #endif
98 
99 #if !defined(HAVE_UINT128)
100 static inline uint32_t U8TO32_LE(const unsigned char *p) {
101  return
102  (((uint32_t)(p[0]) ) |
103  ((uint32_t)(p[1]) << 8) |
104  ((uint32_t)(p[2]) << 16) |
105  ((uint32_t)(p[3]) << 24));
106 }
107 #else
108 static inline uint64_t U8TO64_LE(const unsigned char *p) {
109  return
110  (((uint64_t)(p[0]) ) |
111  ((uint64_t)(p[1]) << 8) |
112  ((uint64_t)(p[2]) << 16) |
113  ((uint64_t)(p[3]) << 24) |
114  ((uint64_t)(p[4]) << 32) |
115  ((uint64_t)(p[5]) << 40) |
116  ((uint64_t)(p[6]) << 48) |
117  ((uint64_t)(p[7]) << 56));
118 }
119 
120 static inline void U64TO8_LE(unsigned char *p, const uint64_t v) {
121  p[0] = (unsigned char)(v );
122  p[1] = (unsigned char)(v >> 8);
123  p[2] = (unsigned char)(v >> 16);
124  p[3] = (unsigned char)(v >> 24);
125  p[4] = (unsigned char)(v >> 32);
126  p[5] = (unsigned char)(v >> 40);
127  p[6] = (unsigned char)(v >> 48);
128  p[7] = (unsigned char)(v >> 56);
129 }
130 #endif
131 
132 #include <stdlib.h>
133 #include <string.h>
134 
135 
unsigned int uint32_t
Definition: stdint.h:126
unsigned __int64 uint64_t
Definition: stdint.h:136
__attribute__((noreturn)) void CXA_THROW(void *ex