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

#include <stdint.h>
Martin Schläffer committed
5
#include <string.h>
Martin Schläffer committed
6 7

#include "endian.h"
Enrico Pozzobon committed
8
#include "forceinline.h"
Martin Schläffer committed
9 10

typedef union {
Martin Schläffer committed
11 12
  uint64_t x;
  uint32_t w[2];
Martin Schläffer committed
13 14 15
  uint8_t b[8];
} word_t;

Martin Schläffer committed
16 17
#define U64TOWORD(x) U64BIG(x)
#define WORDTOU64(x) U64BIG(x)
Martin Schläffer committed
18 19 20 21 22 23 24 25

#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)

Martin Schläffer committed
26 27
forceinline uint64_t ROR(uint64_t x, int n) {
  word_t a = {.x = x}, b = {.x = 0ull};
Martin Schläffer committed
28 29 30 31 32 33 34 35 36 37 38
  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);
Martin Schläffer committed
39
  return b.x;
Martin Schläffer committed
40 41
}

Martin Schläffer committed
42
forceinline uint8_t NOT8(uint8_t a) { return ~a; }
Martin Schläffer committed
43

Martin Schläffer committed
44
forceinline uint8_t XOR8(uint8_t a, uint8_t b) { return a ^ b; }
Martin Schläffer committed
45

Martin Schläffer committed
46
forceinline uint8_t AND8(uint8_t a, uint8_t b) { return a & b; }
Martin Schläffer committed
47

Martin Schläffer committed
48
forceinline uint8_t OR8(uint8_t a, uint8_t b) { return a | b; }
Martin Schläffer committed
49

Martin Schläffer committed
50 51
forceinline uint64_t KEYROT(uint64_t lo2hi, uint64_t hi2lo) {
  return lo2hi << 32 | hi2lo >> 32;
Martin Schläffer committed
52 53
}

Martin Schläffer committed
54 55
forceinline int NOTZERO(uint64_t a, uint64_t b) {
  uint64_t result = a | b;
Martin Schläffer committed
56 57 58
  result |= result >> 32;
  result |= result >> 16;
  result |= result >> 8;
Enrico Pozzobon committed
59
  return ((((int)(result & 0xff) - 1) >> 8) & 1) - 1;
Martin Schläffer committed
60 61
}

Martin Schläffer committed
62
forceinline uint64_t PAD(int i) { return 0x80ull << (56 - 8 * i); }
Martin Schläffer committed
63

Martin Schläffer committed
64 65 66
forceinline uint64_t PRFS_MLEN(uint64_t len) { return len << 51; }

forceinline uint64_t CLEAR(uint64_t w, int n) {
Martin Schläffer committed
67
  /* undefined for n == 0 */
Martin Schläffer committed
68 69
  uint64_t mask = ~0ull >> (8 * n);
  return w & mask;
Martin Schläffer committed
70 71
}

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

Martin Schläffer committed
77
forceinline uint64_t LOAD(const uint8_t* bytes, int n) {
Martin Schläffer committed
78
  uint64_t x = *(uint64_t*)bytes & MASK(n);
Martin Schläffer committed
79
  return U64TOWORD(x);
Martin Schläffer committed
80 81
}

Martin Schläffer committed
82
forceinline void STORE(uint8_t* bytes, uint64_t w, int n) {
Martin Schläffer committed
83
  *(uint64_t*)bytes &= ~MASK(n);
Martin Schläffer committed
84
  *(uint64_t*)bytes |= WORDTOU64(w);
Martin Schläffer committed
85 86
}

Martin Schläffer committed
87
forceinline uint64_t LOADBYTES(const uint8_t* bytes, int n) {
Martin Schläffer committed
88
  uint64_t x = 0;
Martin Schläffer committed
89
  memcpy(&x, bytes, n);
Martin Schläffer committed
90 91 92
  return U64TOWORD(x);
}

Martin Schläffer committed
93
forceinline void STOREBYTES(uint8_t* bytes, uint64_t w, int n) {
Martin Schläffer committed
94
  uint64_t x = WORDTOU64(w);
Martin Schläffer committed
95
  memcpy(bytes, &x, n);
Martin Schläffer committed
96 97 98
}

#endif /* WORD_H_ */