Path: blob/master/crypto/int-util.h
1295 views
// Copyright (c) 2012-2013 The Cryptonote developers1// Distributed under the MIT/X11 software license, see the accompanying2// file COPYING or http://www.opensource.org/licenses/mit-license.php.34#pragma once5#ifndef INT_UTILS_H_6#define INT_UTILS_H_78#include <assert.h>9#include <stdbool.h>10#include <stdint.h>11#include <string.h>12#ifndef _MSC_VER13#include <sys/param.h>14#else15#define inline __inline16#endif1718#ifndef LITTLE_ENDIAN19#define LITTLE_ENDIAN 0x123420#define BIG_ENDIAN 0x432121#endif2223#if !defined(BYTE_ORDER) && (defined(__LITTLE_ENDIAN__) || defined(__arm__) || defined(WIN32))24#define BYTE_ORDER LITTLE_ENDIAN25#endif2627#if defined(WIN32)28#include <stdlib.h>2930static inline uint32_t rol32(uint32_t x, int r) {31return _rotl(x, r);32}3334static inline uint64_t rol64(uint64_t x, int r) {35return _rotl64(x, r);36}3738#else3940static inline uint32_t rol32(uint32_t x, int r) {41return (x << (r & 31)) | (x >> (-r & 31));42}4344static inline uint64_t rol64(uint64_t x, int r) {45return (x << (r & 63)) | (x >> (-r & 63));46}4748#endif4950static inline uint64_t hi_dword(uint64_t val) {51return val >> 32;52}5354static inline uint64_t lo_dword(uint64_t val) {55return val & 0xFFFFFFFF;56}5758static inline uint64_t div_with_reminder(uint64_t dividend, uint32_t divisor, uint32_t* remainder) {59dividend |= ((uint64_t)*remainder) << 32;60*remainder = dividend % divisor;61return dividend / divisor;62}6364// Long division with 2^32 base65static inline uint32_t div128_32(uint64_t dividend_hi, uint64_t dividend_lo, uint32_t divisor, uint64_t* quotient_hi, uint64_t* quotient_lo) {66uint64_t dividend_dwords[4];67uint32_t remainder = 0;6869dividend_dwords[3] = hi_dword(dividend_hi);70dividend_dwords[2] = lo_dword(dividend_hi);71dividend_dwords[1] = hi_dword(dividend_lo);72dividend_dwords[0] = lo_dword(dividend_lo);7374*quotient_hi = div_with_reminder(dividend_dwords[3], divisor, &remainder) << 32;75*quotient_hi |= div_with_reminder(dividend_dwords[2], divisor, &remainder);76*quotient_lo = div_with_reminder(dividend_dwords[1], divisor, &remainder) << 32;77*quotient_lo |= div_with_reminder(dividend_dwords[0], divisor, &remainder);7879return remainder;80}8182#define IDENT32(x) ((uint32_t) (x))83#define IDENT64(x) ((uint64_t) (x))8485#define SWAP32(x) ((((uint32_t) (x) & 0x000000ff) << 24) | \86(((uint32_t) (x) & 0x0000ff00) << 8) | \87(((uint32_t) (x) & 0x00ff0000) >> 8) | \88(((uint32_t) (x) & 0xff000000) >> 24))89#define SWAP64(x) ((((uint64_t) (x) & 0x00000000000000ff) << 56) | \90(((uint64_t) (x) & 0x000000000000ff00) << 40) | \91(((uint64_t) (x) & 0x0000000000ff0000) << 24) | \92(((uint64_t) (x) & 0x00000000ff000000) << 8) | \93(((uint64_t) (x) & 0x000000ff00000000) >> 8) | \94(((uint64_t) (x) & 0x0000ff0000000000) >> 24) | \95(((uint64_t) (x) & 0x00ff000000000000) >> 40) | \96(((uint64_t) (x) & 0xff00000000000000) >> 56))9798static inline uint32_t ident32(uint32_t x) { return x; }99static inline uint64_t ident64(uint64_t x) { return x; }100101static inline uint32_t swap32(uint32_t x) {102x = ((x & 0x00ff00ff) << 8) | ((x & 0xff00ff00) >> 8);103return (x << 16) | (x >> 16);104}105static inline uint64_t swap64(uint64_t x) {106x = ((x & 0x00ff00ff00ff00ff) << 8) | ((x & 0xff00ff00ff00ff00) >> 8);107x = ((x & 0x0000ffff0000ffff) << 16) | ((x & 0xffff0000ffff0000) >> 16);108return (x << 32) | (x >> 32);109}110111#if defined(__GNUC__)112#define UNUSED __attribute__((unused))113#else114#define UNUSED115#endif116static inline void mem_inplace_ident(void *mem UNUSED, size_t n UNUSED) { }117#undef UNUSED118119static inline void mem_inplace_swap32(void *mem, size_t n) {120size_t i;121for (i = 0; i < n; i++) {122((uint32_t *) mem)[i] = swap32(((const uint32_t *) mem)[i]);123}124}125static inline void mem_inplace_swap64(void *mem, size_t n) {126size_t i;127for (i = 0; i < n; i++) {128((uint64_t *) mem)[i] = swap64(((const uint64_t *) mem)[i]);129}130}131132static inline void memcpy_ident32(void *dst, const void *src, size_t n) {133memcpy(dst, src, 4 * n);134}135static inline void memcpy_ident64(void *dst, const void *src, size_t n) {136memcpy(dst, src, 8 * n);137}138139static inline void memcpy_swap32(void *dst, const void *src, size_t n) {140size_t i;141for (i = 0; i < n; i++) {142((uint32_t *) dst)[i] = swap32(((const uint32_t *) src)[i]);143}144}145static inline void memcpy_swap64(void *dst, const void *src, size_t n) {146size_t i;147for (i = 0; i < n; i++) {148((uint64_t *) dst)[i] = swap64(((const uint64_t *) src)[i]);149}150}151152#if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN) || !defined(BIG_ENDIAN)153static_assert(false, "BYTE_ORDER is undefined. Perhaps, GNU extensions are not enabled");154#endif155156#if BYTE_ORDER == LITTLE_ENDIAN157#define SWAP32LE IDENT32158#define SWAP32BE SWAP32159#define swap32le ident32160#define swap32be swap32161#define mem_inplace_swap32le mem_inplace_ident162#define mem_inplace_swap32be mem_inplace_swap32163#define memcpy_swap32le memcpy_ident32164#define memcpy_swap32be memcpy_swap32165#define SWAP64LE IDENT64166#define SWAP64BE SWAP64167#define swap64le ident64168#define swap64be swap64169#define mem_inplace_swap64le mem_inplace_ident170#define mem_inplace_swap64be mem_inplace_swap64171#define memcpy_swap64le memcpy_ident64172#define memcpy_swap64be memcpy_swap64173#endif174175#if BYTE_ORDER == BIG_ENDIAN176#define SWAP32BE IDENT32177#define SWAP32LE SWAP32178#define swap32be ident32179#define swap32le swap32180#define mem_inplace_swap32be mem_inplace_ident181#define mem_inplace_swap32le mem_inplace_swap32182#define memcpy_swap32be memcpy_ident32183#define memcpy_swap32le memcpy_swap32184#define SWAP64BE IDENT64185#define SWAP64LE SWAP64186#define swap64be ident64187#define swap64le swap64188#define mem_inplace_swap64be mem_inplace_ident189#define mem_inplace_swap64le mem_inplace_swap64190#define memcpy_swap64be memcpy_ident64191#define memcpy_swap64le memcpy_swap64192#endif193194#endif /* INT_UTILS_H_ */195196197