Electroneum
int-util.h
Go to the documentation of this file.
1 // Copyrights(c) 2017-2019, The Electroneum Project
2 // Copyrights(c) 2014-2017, The Monero Project
3 //
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without modification, are
7 // permitted provided that the following conditions are met:
8 //
9 // 1. Redistributions of source code must retain the above copyright notice, this list of
10 // conditions and the following disclaimer.
11 //
12 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
13 // of conditions and the following disclaimer in the documentation and/or other
14 // materials provided with the distribution.
15 //
16 // 3. Neither the name of the copyright holder nor the names of its contributors may be
17 // used to endorse or promote products derived from this software without specific
18 // prior written permission.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
21 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
28 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
31 
32 #pragma once
33 
34 #include <assert.h>
35 #include <stdbool.h>
36 #include <stdint.h>
37 #include <string.h>
38 #include <sys/param.h>
39 
40 #if defined(__ANDROID__)
41 #include <byteswap.h>
42 #endif
43 
44 #if defined(_MSC_VER)
45 #include <stdlib.h>
46 
47 static inline uint32_t rol32(uint32_t x, int r) {
48  static_assert(sizeof(uint32_t) == sizeof(unsigned int), "this code assumes 32-bit integers");
49  return _rotl(x, r);
50 }
51 
52 static inline uint64_t rol64(uint64_t x, int r) {
53  return _rotl64(x, r);
54 }
55 
56 #else
57 
58 static inline uint32_t rol32(uint32_t x, int r) {
59  return (x << (r & 31)) | (x >> (-r & 31));
60 }
61 
62 static inline uint64_t rol64(uint64_t x, int r) {
63  return (x << (r & 63)) | (x >> (-r & 63));
64 }
65 
66 #endif
67 
68 static inline uint64_t hi_dword(uint64_t val) {
69  return val >> 32;
70 }
71 
72 static inline uint64_t lo_dword(uint64_t val) {
73  return val & 0xFFFFFFFF;
74 }
75 
76 static inline uint64_t mul128(uint64_t multiplier, uint64_t multiplicand, uint64_t* product_hi) {
77  // multiplier = ab = a * 2^32 + b
78  // multiplicand = cd = c * 2^32 + d
79  // ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d
80  uint64_t a = hi_dword(multiplier);
81  uint64_t b = lo_dword(multiplier);
82  uint64_t c = hi_dword(multiplicand);
83  uint64_t d = lo_dword(multiplicand);
84 
85  uint64_t ac = a * c;
86  uint64_t ad = a * d;
87  uint64_t bc = b * c;
88  uint64_t bd = b * d;
89 
90  uint64_t adbc = ad + bc;
91  uint64_t adbc_carry = adbc < ad ? 1 : 0;
92 
93  // multiplier * multiplicand = product_hi * 2^64 + product_lo
94  uint64_t product_lo = bd + (adbc << 32);
95  uint64_t product_lo_carry = product_lo < bd ? 1 : 0;
96  *product_hi = ac + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry;
97  assert(ac <= *product_hi);
98 
99  return product_lo;
100 }
101 
102 static inline uint64_t div_with_reminder(uint64_t dividend, uint32_t divisor, uint32_t* remainder) {
103  dividend |= ((uint64_t)*remainder) << 32;
104  *remainder = dividend % divisor;
105  return dividend / divisor;
106 }
107 
108 // Long division with 2^32 base
109 static inline uint32_t div128_32(uint64_t dividend_hi, uint64_t dividend_lo, uint32_t divisor, uint64_t* quotient_hi, uint64_t* quotient_lo) {
110  uint64_t dividend_dwords[4];
111  uint32_t remainder = 0;
112 
113  dividend_dwords[3] = hi_dword(dividend_hi);
114  dividend_dwords[2] = lo_dword(dividend_hi);
115  dividend_dwords[1] = hi_dword(dividend_lo);
116  dividend_dwords[0] = lo_dword(dividend_lo);
117 
118  *quotient_hi = div_with_reminder(dividend_dwords[3], divisor, &remainder) << 32;
119  *quotient_hi |= div_with_reminder(dividend_dwords[2], divisor, &remainder);
120  *quotient_lo = div_with_reminder(dividend_dwords[1], divisor, &remainder) << 32;
121  *quotient_lo |= div_with_reminder(dividend_dwords[0], divisor, &remainder);
122 
123  return remainder;
124 }
125 
126 #define IDENT32(x) ((uint32_t) (x))
127 #define IDENT64(x) ((uint64_t) (x))
128 
129 #define SWAP32(x) ((((uint32_t) (x) & 0x000000ff) << 24) | \
130  (((uint32_t) (x) & 0x0000ff00) << 8) | \
131  (((uint32_t) (x) & 0x00ff0000) >> 8) | \
132  (((uint32_t) (x) & 0xff000000) >> 24))
133 #define SWAP64(x) ((((uint64_t) (x) & 0x00000000000000ff) << 56) | \
134  (((uint64_t) (x) & 0x000000000000ff00) << 40) | \
135  (((uint64_t) (x) & 0x0000000000ff0000) << 24) | \
136  (((uint64_t) (x) & 0x00000000ff000000) << 8) | \
137  (((uint64_t) (x) & 0x000000ff00000000) >> 8) | \
138  (((uint64_t) (x) & 0x0000ff0000000000) >> 24) | \
139  (((uint64_t) (x) & 0x00ff000000000000) >> 40) | \
140  (((uint64_t) (x) & 0xff00000000000000) >> 56))
141 
142 static inline uint32_t ident32(uint32_t x) { return x; }
143 static inline uint64_t ident64(uint64_t x) { return x; }
144 
145 #ifndef __OpenBSD__
146 # if defined(__ANDROID__) && defined(__swap32) && !defined(swap32)
147 # define swap32 __swap32
148 # elif !defined(swap32)
149 static inline uint32_t swap32(uint32_t x) {
150  x = ((x & 0x00ff00ff) << 8) | ((x & 0xff00ff00) >> 8);
151  return (x << 16) | (x >> 16);
152 }
153 # endif
154 # if defined(__ANDROID__) && defined(__swap64) && !defined(swap64)
155 # define swap64 __swap64
156 # elif !defined(swap64)
157 static inline uint64_t swap64(uint64_t x) {
158  x = ((x & 0x00ff00ff00ff00ff) << 8) | ((x & 0xff00ff00ff00ff00) >> 8);
159  x = ((x & 0x0000ffff0000ffff) << 16) | ((x & 0xffff0000ffff0000) >> 16);
160  return (x << 32) | (x >> 32);
161 }
162 # endif
163 #endif /* __OpenBSD__ */
164 
165 #if defined(__GNUC__)
166 #define UNUSED __attribute__((unused))
167 #else
168 #define UNUSED
169 #endif
170 static inline void mem_inplace_ident(void *mem UNUSED, size_t n UNUSED) { }
171 #undef UNUSED
172 
173 static inline void mem_inplace_swap32(void *mem, size_t n) {
174  size_t i;
175  for (i = 0; i < n; i++) {
176  ((uint32_t *) mem)[i] = swap32(((const uint32_t *) mem)[i]);
177  }
178 }
179 static inline void mem_inplace_swap64(void *mem, size_t n) {
180  size_t i;
181  for (i = 0; i < n; i++) {
182  ((uint64_t *) mem)[i] = swap64(((const uint64_t *) mem)[i]);
183  }
184 }
185 
186 static inline void memcpy_ident32(void *dst, const void *src, size_t n) {
187  memcpy(dst, src, 4 * n);
188 }
189 static inline void memcpy_ident64(void *dst, const void *src, size_t n) {
190  memcpy(dst, src, 8 * n);
191 }
192 
193 static inline void memcpy_swap32(void *dst, const void *src, size_t n) {
194  size_t i;
195  for (i = 0; i < n; i++) {
196  ((uint32_t *) dst)[i] = swap32(((const uint32_t *) src)[i]);
197  }
198 }
199 static inline void memcpy_swap64(void *dst, const void *src, size_t n) {
200  size_t i;
201  for (i = 0; i < n; i++) {
202  ((uint64_t *) dst)[i] = swap64(((const uint64_t *) src)[i]);
203  }
204 }
205 
206 #if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN) || !defined(BIG_ENDIAN)
207 static_assert(false, "BYTE_ORDER is undefined. Perhaps, GNU extensions are not enabled");
208 #endif
209 
210 #if BYTE_ORDER == LITTLE_ENDIAN
211 #define SWAP32LE IDENT32
212 #define SWAP32BE SWAP32
213 #define swap32le ident32
214 #define swap32be swap32
215 #define mem_inplace_swap32le mem_inplace_ident
216 #define mem_inplace_swap32be mem_inplace_swap32
217 #define memcpy_swap32le memcpy_ident32
218 #define memcpy_swap32be memcpy_swap32
219 #define SWAP64LE IDENT64
220 #define SWAP64BE SWAP64
221 #define swap64le ident64
222 #define swap64be swap64
223 #define mem_inplace_swap64le mem_inplace_ident
224 #define mem_inplace_swap64be mem_inplace_swap64
225 #define memcpy_swap64le memcpy_ident64
226 #define memcpy_swap64be memcpy_swap64
227 #endif
228 
229 #if BYTE_ORDER == BIG_ENDIAN
230 #define SWAP32BE IDENT32
231 #define SWAP32LE SWAP32
232 #define swap32be ident32
233 #define swap32le swap32
234 #define mem_inplace_swap32be mem_inplace_ident
235 #define mem_inplace_swap32le mem_inplace_swap32
236 #define memcpy_swap32be memcpy_ident32
237 #define memcpy_swap32le memcpy_swap32
238 #define SWAP64BE IDENT64
239 #define SWAP64LE SWAP64
240 #define swap64be ident64
241 #define swap64le swap64
242 #define mem_inplace_swap64be mem_inplace_ident
243 #define mem_inplace_swap64le mem_inplace_swap64
244 #define memcpy_swap64be memcpy_ident64
245 #define memcpy_swap64le memcpy_swap64
246 #endif
int d
Definition: base.py:14
static void mem_inplace_ident(void *mem UNUSED, size_t n UNUSED)
Definition: int-util.h:170
static void memcpy_ident32(void *dst, const void *src, size_t n)
Definition: int-util.h:186
static void memcpy_swap64(void *dst, const void *src, size_t n)
Definition: int-util.h:199
static uint32_t div128_32(uint64_t dividend_hi, uint64_t dividend_lo, uint32_t divisor, uint64_t *quotient_hi, uint64_t *quotient_lo)
Definition: int-util.h:109
static void mem_inplace_swap64(void *mem, size_t n)
Definition: int-util.h:179
Definition: d.py:1
static void memcpy_ident64(void *dst, const void *src, size_t n)
Definition: int-util.h:189
static uint32_t rol32(uint32_t x, int r)
Definition: int-util.h:58
static uint64_t swap64(uint64_t x)
Definition: int-util.h:157
static uint64_t div_with_reminder(uint64_t dividend, uint32_t divisor, uint32_t *remainder)
Definition: int-util.h:102
int b
Definition: base.py:1
static void mem_inplace_swap32(void *mem, size_t n)
Definition: int-util.h:173
static uint64_t lo_dword(uint64_t val)
Definition: int-util.h:72
static uint32_t swap32(uint32_t x)
Definition: int-util.h:149
static uint64_t hi_dword(uint64_t val)
Definition: int-util.h:68
static uint64_t ident64(uint64_t x)
Definition: int-util.h:143
static uint64_t rol64(uint64_t x, int r)
Definition: int-util.h:62
string a
Definition: MakeCryptoOps.py:15
#define UNUSED
Definition: int-util.h:168
static void memcpy_swap32(void *dst, const void *src, size_t n)
Definition: int-util.h:193
static uint32_t ident32(uint32_t x)
Definition: int-util.h:142
static uint64_t mul128(uint64_t multiplier, uint64_t multiplicand, uint64_t *product_hi)
Definition: int-util.h:76