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

#include <stdint.h>

Martin Schläffer committed
6 7
#include "endian.h"
#include "interleave.h"
Martin Schläffer committed
8 9 10 11 12 13

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

Martin Schläffer committed
14 15 16 17 18 19 20 21 22 23 24
__forceinline uint32_t ROR32(uint32_t x, int n) {
  return (n == 0) ? x : 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;
}

Martin Schläffer committed
25 26 27 28 29 30
__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; }

Martin Schläffer committed
31
__forceinline word_t U64TOWORD(uint64_t x) { return WORD_T(deinterleave32(x)); }
Martin Schläffer committed
32

Martin Schläffer committed
33
__forceinline uint64_t WORDTOU64(word_t w) { return interleave32(UINT64_T(w)); }
Martin Schläffer committed
34

Martin Schläffer committed
35 36 37 38
__forceinline word_t NOT(word_t a) {
  a.e = ~a.e;
  a.o = ~a.o;
  return a;
Martin Schläffer committed
39 40
}

Martin Schläffer committed
41 42 43 44
__forceinline word_t XOR(word_t a, word_t b) {
  a.e ^= b.e;
  a.o ^= b.o;
  return a;
Martin Schläffer committed
45 46
}

Martin Schläffer committed
47 48 49 50
__forceinline word_t AND(word_t a, word_t b) {
  a.e &= b.e;
  a.o &= b.o;
  return a;
Martin Schläffer committed
51 52 53 54 55 56 57 58 59
}

__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;
}

Martin Schläffer committed
60 61 62 63 64
__forceinline uint8_t NOTZERO(word_t a, word_t b) {
  uint32_t result = a.e | a.o | b.e | b.o;
  result |= result >> 16;
  result |= result >> 8;
  return (uint8_t)result;
Martin Schläffer committed
65 66 67 68 69 70
}

__forceinline word_t PAD(int i) {
  return WORD_T((uint64_t)(0x08 << (28 - 4 * i)) << 32);
}

Martin Schläffer committed
71 72
__forceinline word_t CLEAR(word_t w, int n) {
  /* undefined for n == 0 */
Martin Schläffer committed
73
  uint32_t mask = 0x0fffffff >> (n * 4 - 4);
Martin Schläffer committed
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
  return AND(w, WORD_T((uint64_t)mask << 32 | mask));
}

__forceinline uint64_t MASK(int n) {
  /* undefined for n == 0 */
  return ~0ull >> (64 - 8 * n);
}

__forceinline word_t LOAD64(const uint8_t* bytes) {
  uint64_t x = *(uint64_t*)bytes;
  return U64TOWORD(U64BIG(x));
}

__forceinline void STORE64(uint8_t* bytes, word_t w) {
  uint64_t x = WORDTOU64(w);
  *(uint64_t*)bytes = U64BIG(x);
}

__forceinline word_t LOAD(const uint8_t* bytes, int n) {
  uint64_t x = *(uint64_t*)bytes & MASK(n);
  return U64TOWORD(U64BIG(x));
}

__forceinline void STORE(uint8_t* bytes, word_t w, int n) {
  uint64_t x = WORDTOU64(w);
  *(uint64_t*)bytes &= ~MASK(n);
  *(uint64_t*)bytes |= U64BIG(x);
}

__forceinline word_t LOADBYTES(const uint8_t* bytes, int n) {
  uint64_t x = 0;
  for (int i = 0; i < n; ++i) ((uint8_t*)&x)[7 - i] = bytes[i];
  return U64TOWORD(x);
}

__forceinline void STOREBYTES(uint8_t* bytes, word_t w, int n) {
  uint64_t x = WORDTOU64(w);
  for (int i = 0; i < n; ++i) bytes[i] = ((uint8_t*)&x)[7 - i];
Martin Schläffer committed
112 113 114
}

#endif /* WORD_H_ */