word.h 2.38 KB
Newer Older
Martin Schläffer committed
1 2 3 4 5 6
#ifndef WORD_H_
#define WORD_H_

#include <stdint.h>

#include "endian.h"
Enrico Pozzobon committed
7
#include "forceinline.h"
Martin Schläffer committed
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

typedef union {
  uint64_t w;
  uint8_t b[8];
} word_t;

#define U64TOWORD WORD_T
#define WORDTOU64 UINT64_T

#define XMUL(i, x)                               \
  do {                                           \
    tmp = (uint16_t)a.b[i] * (1 << (x));         \
    b.b[(byte_rol + (i)) & 0x7] ^= (uint8_t)tmp; \
    b.b[(byte_rol + (i) + 1) & 0x7] ^= tmp >> 8; \
  } while (0)

Enrico Pozzobon committed
24
forceinline word_t ROR(word_t a, int n) {
Martin Schläffer committed
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
  word_t b = {.w = 0ull};
  int bit_rol = (64 - n) & 0x7;
  int byte_rol = (64 - n) >> 3;
  uint16_t tmp;
  XMUL(0, bit_rol);
  XMUL(1, bit_rol);
  XMUL(2, bit_rol);
  XMUL(3, bit_rol);
  XMUL(4, bit_rol);
  XMUL(5, bit_rol);
  XMUL(6, bit_rol);
  XMUL(7, bit_rol);
  return b;
}

Enrico Pozzobon committed
40
forceinline word_t WORD_T(uint64_t x) { return (word_t){.w = x}; }
Martin Schläffer committed
41

Enrico Pozzobon committed
42
forceinline uint64_t UINT64_T(word_t w) { return w.w; }
Martin Schläffer committed
43

Enrico Pozzobon committed
44
forceinline word_t NOT(word_t a) {
Martin Schläffer committed
45 46 47 48
  a.w = ~a.w;
  return a;
}

Enrico Pozzobon committed
49
forceinline word_t XOR(word_t a, word_t b) {
Martin Schläffer committed
50 51 52 53
  a.w ^= b.w;
  return a;
}

Enrico Pozzobon committed
54
forceinline word_t AND(word_t a, word_t b) {
Martin Schläffer committed
55 56 57 58
  a.w &= b.w;
  return a;
}

Enrico Pozzobon committed
59
forceinline word_t KEYROT(word_t lo2hi, word_t hi2lo) {
Martin Schläffer committed
60 61 62
  return (word_t){.w = lo2hi.w << 32 | hi2lo.w >> 32};
}

Enrico Pozzobon committed
63
forceinline int NOTZERO(word_t a, word_t b) {
Martin Schläffer committed
64 65 66 67
  uint64_t result = a.w | b.w;
  result |= result >> 32;
  result |= result >> 16;
  result |= result >> 8;
Enrico Pozzobon committed
68
  return ((((int)(result & 0xff) - 1) >> 8) & 1) - 1;
Martin Schläffer committed
69 70
}

Enrico Pozzobon committed
71
forceinline word_t PAD(int i) { return WORD_T(0x80ull << (56 - 8 * i)); }
Martin Schläffer committed
72

Enrico Pozzobon committed
73
forceinline uint64_t MASK(int n) {
Martin Schläffer committed
74 75 76 77
  /* undefined for n == 0 */
  return ~0ull >> (64 - 8 * n);
}

Enrico Pozzobon committed
78
forceinline word_t CLEAR(word_t w, int n) {
Martin Schläffer committed
79 80 81 82 83
  /* undefined for n == 0 */
  uint64_t mask = 0x00ffffffffffffffull >> (n * 8 - 8);
  return AND(w, WORD_T(mask));
}

Enrico Pozzobon committed
84
forceinline word_t LOAD(const uint8_t* bytes, int n) {
Martin Schläffer committed
85 86 87 88
  uint64_t x = *(uint64_t*)bytes & MASK(n);
  return U64TOWORD(U64BIG(x));
}

Enrico Pozzobon committed
89
forceinline void STORE(uint8_t* bytes, word_t w, int n) {
Martin Schläffer committed
90 91 92 93 94
  uint64_t x = WORDTOU64(w);
  *(uint64_t*)bytes &= ~MASK(n);
  *(uint64_t*)bytes |= U64BIG(x);
}

Enrico Pozzobon committed
95
forceinline word_t LOADBYTES(const uint8_t* bytes, int n) {
Martin Schläffer committed
96 97 98 99 100
  uint64_t x = 0;
  for (int i = 0; i < n; ++i) ((uint8_t*)&x)[7 - i] = bytes[i];
  return U64TOWORD(x);
}

Enrico Pozzobon committed
101
forceinline void STOREBYTES(uint8_t* bytes, word_t w, int n) {
Martin Schläffer committed
102 103 104 105 106
  uint64_t x = WORDTOU64(w);
  for (int i = 0; i < n; ++i) bytes[i] = ((uint8_t*)&x)[7 - i];
}

#endif /* WORD_H_ */