word.h 2.77 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 11
#include "interleave.h"

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

Martin Schläffer committed
17 18 19
#define U64TOWORD(x) interleave8(U64BIG(x))
#define WORDTOU64(x) U64BIG(interleave8(x))

Enrico Pozzobon committed
20
forceinline uint8_t ROR8(uint8_t a, int n) { return a >> n | a << (8 - n); }
Martin Schläffer committed
21

Martin Schläffer committed
22 23
forceinline uint64_t ROR(uint64_t x, int n) {
  word_t b, a = {.x = x};
Martin Schläffer committed
24 25 26 27 28 29 30 31
  b.b[0] = ROR8(a.b[(n + 0) & 0x7], (n + 0) >> 3);
  b.b[1] = ROR8(a.b[(n + 1) & 0x7], (n + 1) >> 3);
  b.b[2] = ROR8(a.b[(n + 2) & 0x7], (n + 2) >> 3);
  b.b[3] = ROR8(a.b[(n + 3) & 0x7], (n + 3) >> 3);
  b.b[4] = ROR8(a.b[(n + 4) & 0x7], (n + 4) >> 3);
  b.b[5] = ROR8(a.b[(n + 5) & 0x7], (n + 5) >> 3);
  b.b[6] = ROR8(a.b[(n + 6) & 0x7], (n + 6) >> 3);
  b.b[7] = ROR8(a.b[(n + 7) & 0x7], (n + 7) >> 3);
Martin Schläffer committed
32
  return b.x;
Martin Schläffer committed
33 34
}

Martin Schläffer committed
35 36 37 38 39 40 41 42 43 44 45
forceinline uint64_t KEYROT(uint64_t a, uint64_t b) {
  word_t w, lo2hi = {.x = a}, hi2lo = {.x = b};
  w.b[0] = lo2hi.b[0] << 4 | hi2lo.b[0] >> 4;
  w.b[1] = lo2hi.b[1] << 4 | hi2lo.b[1] >> 4;
  w.b[2] = lo2hi.b[2] << 4 | hi2lo.b[2] >> 4;
  w.b[3] = lo2hi.b[3] << 4 | hi2lo.b[3] >> 4;
  w.b[4] = lo2hi.b[4] << 4 | hi2lo.b[4] >> 4;
  w.b[5] = lo2hi.b[5] << 4 | hi2lo.b[5] >> 4;
  w.b[6] = lo2hi.b[6] << 4 | hi2lo.b[6] >> 4;
  w.b[7] = lo2hi.b[7] << 4 | hi2lo.b[7] >> 4;
  return w.x;
Martin Schläffer committed
46 47
}

Martin Schläffer committed
48 49
forceinline int NOTZERO(uint64_t a, uint64_t b) {
  uint64_t result = a | b;
Martin Schläffer committed
50 51 52
  result |= result >> 32;
  result |= result >> 16;
  result |= result >> 8;
Enrico Pozzobon committed
53
  return ((((int)(result & 0xff) - 1) >> 8) & 1) - 1;
Martin Schläffer committed
54 55
}

Martin Schläffer committed
56
forceinline uint64_t PAD(int i) { return (uint64_t)(0x80 >> i) << 56; }
Martin Schläffer committed
57

Martin Schläffer committed
58 59 60 61 62 63 64 65 66
forceinline uint64_t PRFS_MLEN(uint64_t len) {
  return ((len & 0x01) << 30) | /* 0000x */
         ((len & 0x02) << 37) | /* 000x0 */
         ((len & 0x04) << 44) | /* 00x00 */
         ((len & 0x08) << 51) | /* 0x000 */
         ((len & 0x10) << 58);  /* x0000 */
}

forceinline uint64_t CLEAR(uint64_t w, int n) {
Martin Schläffer committed
67 68 69 70 71 72 73 74 75 76 77 78
  /* undefined for n == 0 */
  uint8_t m = 0xff >> n;
  word_t mask = {
      .b[0] = m,
      .b[1] = m,
      .b[2] = m,
      .b[3] = m,
      .b[4] = m,
      .b[5] = m,
      .b[6] = m,
      .b[7] = m,
  };
Martin Schläffer committed
79
  return w & mask.x;
Martin Schläffer committed
80 81
}

Enrico Pozzobon committed
82
forceinline uint64_t MASK(int n) {
Martin Schläffer committed
83 84 85 86
  /* undefined for n == 0 */
  return ~0ull >> (64 - 8 * n);
}

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

Martin Schläffer committed
92
forceinline void STORE(uint8_t* bytes, uint64_t w, int n) {
Martin Schläffer committed
93
  *(uint64_t*)bytes &= ~MASK(n);
Martin Schläffer committed
94
  *(uint64_t*)bytes |= WORDTOU64(w);
Martin Schläffer committed
95 96
}

Martin Schläffer committed
97
forceinline uint64_t LOADBYTES(const uint8_t* bytes, int n) {
Martin Schläffer committed
98
  uint64_t x = 0;
Martin Schläffer committed
99
  memcpy(&x, bytes, n);
Martin Schläffer committed
100 101 102
  return U64TOWORD(x);
}

Martin Schläffer committed
103
forceinline void STOREBYTES(uint8_t* bytes, uint64_t w, int n) {
Martin Schläffer committed
104
  uint64_t x = WORDTOU64(w);
Martin Schläffer committed
105
  memcpy(bytes, &x, n);
Martin Schläffer committed
106 107 108
}

#endif /* WORD_H_ */