word.h 3.31 KB
Newer Older
Martin Schläffer committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
#ifndef WORD_H_
#define WORD_H_

#include <stdint.h>

#include "config.h"

typedef struct {
  uint32_t e;
  uint32_t o;
} word_t;

__forceinline word_t WORD_T(uint64_t x) {
  return (word_t){.o = x >> 32, .e = x};
}

__forceinline uint64_t UINT64_T(word_t x) { return (uint64_t)x.o << 32 | x.e; }

__forceinline uint64_t TOBI32(uint64_t in);

__forceinline uint64_t FROMBI32(uint64_t in);

__forceinline word_t U64TOWORD(uint64_t x) {
  uint64_t w = TOBI32(x);
  return (word_t){.o = w >> 32, .e = w};
}

__forceinline uint64_t WORDTOU64(word_t w) {
  return FROMBI32((uint64_t)w.o << 32 | w.e);
}

#define XOR(a, b)  \
  do {             \
    word_t tb = b; \
    (a).e ^= tb.e; \
    (a).o ^= tb.o; \
  } while (0)

#define AND(a, b)  \
  do {             \
    word_t tb = b; \
    (a).e &= tb.e; \
    (a).o &= tb.o; \
  } while (0)

__forceinline uint32_t ROR32(uint32_t x, int n) {
  return x >> n | x << (32 - n);
}

__forceinline word_t ROR64(word_t x, int n) {
  word_t r;
  r.e = (n % 2) ? ROR32(x.o, (n - 1) / 2) : ROR32(x.e, n / 2);
  r.o = (n % 2) ? ROR32(x.e, (n + 1) / 2) : ROR32(x.o, n / 2);
  return r;
}

__forceinline word_t KEYROT(word_t lo2hi, word_t hi2lo) {
  word_t r;
  r.o = lo2hi.o << 16 | hi2lo.o >> 16;
  r.e = lo2hi.e << 16 | hi2lo.e >> 16;
  return r;
}

__forceinline int NOTZERO(word_t a, word_t b) {
  int result = 0;
  for (int i = 0; i < 8; ++i) result |= ((uint8_t*)&a)[i];
  for (int i = 0; i < 8; ++i) result |= ((uint8_t*)&b)[i];
  return result;
}

/* set padding byte in 64-bit Ascon word */
__forceinline word_t PAD(int i) {
  return WORD_T((uint64_t)(0x08 << (28 - 4 * i)) << 32);
}

/* byte mask for 64-bit Ascon word (1 <= n <= 8) */
__forceinline word_t XMASK(int n) {
  uint32_t mask = 0x0fffffff >> (n * 4 - 4);
  return WORD_T((uint64_t)mask << 32 | mask);
}

/* credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */
__forceinline uint64_t TOBI32(uint64_t in) {
  uint32_t hi = in >> 32;
  uint32_t lo = in;
  uint32_t r0, r1;
  r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1);
  r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2);
  r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4);
  r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8);
  r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1);
  r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2);
  r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4);
  r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8);
  r0 = (lo & 0x0000FFFF) | (hi << 16);
  r1 = (lo >> 16) | (hi & 0xFFFF0000);
  return (uint64_t)r1 << 32 | r0;
}

/* credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */
__forceinline uint64_t FROMBI32(uint64_t in) {
  uint32_t r0 = in;
  uint32_t r1 = in >> 32;
  uint32_t lo = (r0 & 0x0000FFFF) | (r1 << 16);
  uint32_t hi = (r0 >> 16) | (r1 & 0xFFFF0000);
  r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8);
  r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4);
  r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2);
  r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1);
  r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8);
  r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4);
  r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2);
  r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1);
  return (uint64_t)hi << 32 | lo;
}

#endif /* WORD_H_ */