bitops.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*
  2. * cifra - embedded cryptography library
  3. * Written in 2014 by Joseph Birr-Pixton <jpixton@gmail.com>
  4. *
  5. * To the extent possible under law, the author(s) have dedicated all
  6. * copyright and related and neighboring rights to this software to the
  7. * public domain worldwide. This software is distributed without any
  8. * warranty.
  9. *
  10. * You should have received a copy of the CC0 Public Domain Dedication
  11. * along with this software. If not, see
  12. * <http://creativecommons.org/publicdomain/zero/1.0/>.
  13. */
  14. #ifndef BITOPS_H
  15. #define BITOPS_H
  16. #include <stdint.h>
  17. #include <stddef.h>
  18. #ifdef _WINDOWS
  19. #include <intrin.h>
  20. #endif
  21. /* Assorted bitwise and common operations used in ciphers. */
  22. /** Circularly rotate right x by n bits.
  23. * 0 > n > 32. */
  24. static inline uint32_t rotr32(uint32_t x, unsigned n)
  25. {
  26. return (x >> n) | (x << (32 - n));
  27. }
  28. /** Circularly rotate left x by n bits.
  29. * 0 > n > 32. */
  30. static inline uint32_t rotl32(uint32_t x, unsigned n)
  31. {
  32. return (x << n) | (x >> (32 - n));
  33. }
  34. /** Circularly rotate right x by n bits.
  35. * 0 > n > 64. */
  36. static inline uint64_t rotr64(uint64_t x, unsigned n)
  37. {
  38. return (x >> n) | (x << (64 - n));
  39. }
  40. /** Circularly rotate left x by n bits.
  41. * 0 > n > 64. */
  42. static inline uint64_t rotl64(uint64_t x, unsigned n)
  43. {
  44. return (x << n) | (x >> (64 - n));
  45. }
  46. /** Read 4 bytes from buf, as a 32-bit big endian quantity. */
  47. static inline uint32_t read32_be(const uint8_t buf[4])
  48. {
  49. return ((uint32_t)buf[0] << 24) |
  50. ((uint32_t)buf[1] << 16) |
  51. ((uint32_t)buf[2] << 8) |
  52. ((uint32_t)buf[3]);
  53. }
  54. /** Read 4 bytes from buf, as a 32-bit little endian quantity. */
  55. static inline uint32_t read32_le(const uint8_t buf[4])
  56. {
  57. return ((uint32_t)buf[3] << 24) |
  58. ((uint32_t)buf[2] << 16) |
  59. ((uint32_t)buf[1] << 8) |
  60. ((uint32_t)buf[0]);
  61. }
  62. /** Read 8 bytes from buf, as a 64-bit big endian quantity. */
  63. static inline uint64_t read64_be(const uint8_t buf[8])
  64. {
  65. uint32_t hi = read32_be(buf),
  66. lo = read32_be(buf + 4);
  67. return ((uint64_t)hi) << 32 |
  68. lo;
  69. }
  70. /** Read 8 bytes from buf, as a 64-bit little endian quantity. */
  71. static inline uint64_t read64_le(const uint8_t buf[8])
  72. {
  73. uint32_t hi = read32_le(buf + 4),
  74. lo = read32_le(buf);
  75. return ((uint64_t)hi) << 32 |
  76. lo;
  77. }
  78. /** Encode v as a 32-bit big endian quantity into buf. */
  79. static inline void write32_be(uint32_t v, uint8_t buf[4])
  80. {
  81. *buf++ = (v >> 24) & 0xff;
  82. *buf++ = (v >> 16) & 0xff;
  83. *buf++ = (v >> 8) & 0xff;
  84. *buf = v & 0xff;
  85. }
  86. /** Encode v as a 32-bit little endian quantity into buf. */
  87. static inline void write32_le(uint32_t v, uint8_t buf[4])
  88. {
  89. *buf++ = v & 0xff;
  90. *buf++ = (v >> 8) & 0xff;
  91. *buf++ = (v >> 16) & 0xff;
  92. *buf = (v >> 24) & 0xff;
  93. }
  94. /** Encode v as a 64-bit big endian quantity into buf. */
  95. static inline void write64_be(uint64_t v, uint8_t buf[8])
  96. {
  97. *buf++ = (v >> 56) & 0xff;
  98. *buf++ = (v >> 48) & 0xff;
  99. *buf++ = (v >> 40) & 0xff;
  100. *buf++ = (v >> 32) & 0xff;
  101. *buf++ = (v >> 24) & 0xff;
  102. *buf++ = (v >> 16) & 0xff;
  103. *buf++ = (v >> 8) & 0xff;
  104. *buf = v & 0xff;
  105. }
  106. /** Encode v as a 64-bit little endian quantity into buf. */
  107. static inline void write64_le(uint64_t v, uint8_t buf[8])
  108. {
  109. *buf++ = v & 0xff;
  110. *buf++ = (v >> 8) & 0xff;
  111. *buf++ = (v >> 16) & 0xff;
  112. *buf++ = (v >> 24) & 0xff;
  113. *buf++ = (v >> 32) & 0xff;
  114. *buf++ = (v >> 40) & 0xff;
  115. *buf++ = (v >> 48) & 0xff;
  116. *buf = (v >> 56) & 0xff;
  117. }
  118. /** out = in ^ b8.
  119. * out and in may alias. */
  120. static inline void xor_b8(uint8_t *out, const uint8_t *in, uint8_t b8, size_t len)
  121. {
  122. size_t i;
  123. for (i = 0; i < len; i++)
  124. out[i] = in[i] ^ b8;
  125. }
  126. /** out = x ^ y.
  127. * out, x and y may alias. */
  128. static inline void xor_bb(uint8_t *out, const uint8_t *x, const uint8_t *y, size_t len)
  129. {
  130. size_t i;
  131. for (i = 0; i < len; i++)
  132. out[i] = x[i] ^ y[i];
  133. }
  134. /* out ^= x
  135. * out and x may alias. */
  136. static inline void xor_words(uint32_t *out, const uint32_t *x, size_t nwords)
  137. {
  138. size_t i;
  139. for (i = 0; i < nwords; i++)
  140. out[i] ^= x[i];
  141. }
  142. /** Produce 0xffffffff if x == y, zero otherwise, without branching. */
  143. static inline uint32_t mask_u32(uint32_t x, uint32_t y)
  144. {
  145. uint32_t diff = x ^ y;
  146. uint32_t diff_is_zero = ~diff & (diff - 1);
  147. return (uint32_t)(-(int32_t)(diff_is_zero >> 31));
  148. }
  149. /** Product 0xff if x == y, zero otherwise, without branching. */
  150. static inline uint8_t mask_u8(uint32_t x, uint32_t y)
  151. {
  152. uint32_t diff = x ^ y;
  153. uint8_t diff_is_zero = ~diff & (diff - 1);
  154. return - (diff_is_zero >> 7);
  155. }
  156. /** Select the ith entry from the given table of n values, in a side channel-silent
  157. * way. */
  158. static inline uint32_t select_u32(uint32_t i, volatile const uint32_t *tab, uint32_t n)
  159. {
  160. uint32_t r = 0, ii;
  161. for (ii = 0; ii < n; ii++)
  162. {
  163. uint32_t mask = mask_u32(i, ii);
  164. r = (r & ~mask) | (tab[ii] & mask);
  165. }
  166. return r;
  167. }
  168. /** Select the ith entry from the given table of n values, in a side channel-silent
  169. * way. */
  170. static inline uint8_t select_u8(uint32_t i, volatile const uint8_t *tab, uint32_t n)
  171. {
  172. uint8_t r = 0;
  173. uint32_t ii;
  174. for (ii = 0; ii < n; ii++)
  175. {
  176. uint8_t mask = mask_u8(i, ii);
  177. r = (r & ~mask) | (tab[ii] & mask);
  178. }
  179. return r;
  180. }
  181. /** Select the ath, bth, cth and dth entries from the given table of n values,
  182. * placing the results into a, b, c and d. */
  183. static inline void select_u8x4(uint8_t *a, uint8_t *b, uint8_t *c, uint8_t *d,
  184. volatile const uint8_t *tab, uint32_t n)
  185. {
  186. uint8_t ra = 0,
  187. rb = 0,
  188. rc = 0,
  189. rd = 0;
  190. uint8_t mask;
  191. uint32_t i;
  192. for (i = 0; i < n; i++)
  193. {
  194. uint8_t item = tab[i];
  195. mask = mask_u8(*a, i); ra = (ra & ~mask) | (item & mask);
  196. mask = mask_u8(*b, i); rb = (rb & ~mask) | (item & mask);
  197. mask = mask_u8(*c, i); rc = (rc & ~mask) | (item & mask);
  198. mask = mask_u8(*d, i); rd = (rd & ~mask) | (item & mask);
  199. }
  200. *a = ra;
  201. *b = rb;
  202. *c = rc;
  203. *d = rd;
  204. }
  205. /** out ^= if0 or if1, depending on the value of bit. */
  206. static inline void select_xor128(uint32_t out[4],
  207. const uint32_t if0[4],
  208. const uint32_t if1[4],
  209. uint8_t bit)
  210. {
  211. uint32_t mask1 = mask_u32(bit, 1);
  212. uint32_t mask0 = ~mask1;
  213. out[0] ^= (if0[0] & mask0) | (if1[0] & mask1);
  214. out[1] ^= (if0[1] & mask0) | (if1[1] & mask1);
  215. out[2] ^= (if0[2] & mask0) | (if1[2] & mask1);
  216. out[3] ^= (if0[3] & mask0) | (if1[3] & mask1);
  217. }
  218. /** Increments the integer stored at v (of non-zero length len)
  219. * with the least significant byte first. */
  220. static inline void incr_le(uint8_t *v, size_t len)
  221. {
  222. size_t i = 0;
  223. while (1)
  224. {
  225. if (++v[i] != 0)
  226. return;
  227. i++;
  228. if (i == len)
  229. return;
  230. }
  231. }
  232. /** Increments the integer stored at v (of non-zero length len)
  233. * with the most significant byte last. */
  234. static inline void incr_be(uint8_t *v, size_t len)
  235. {
  236. len--;
  237. while (1)
  238. {
  239. if (++v[len] != 0)
  240. return;
  241. if (len == 0)
  242. return;
  243. len--;
  244. }
  245. }
  246. /** Copies len bytes from in to out, with in shifted left by offset bits
  247. * to the right. */
  248. static inline void copy_bytes_unaligned(uint8_t *out, const uint8_t *in, size_t len, uint8_t offset)
  249. {
  250. uint8_t byte_off = offset / 8;
  251. uint8_t bit_off = offset & 7;
  252. uint8_t rmask = (1 << bit_off) - 1;
  253. uint8_t lmask = ~rmask;
  254. size_t i;
  255. for (i = 0; i < len; i++)
  256. {
  257. out[i] = (in[i + byte_off] << bit_off) & lmask;
  258. out[i] |= (in[i + byte_off + 1] >> (8 - bit_off)) & rmask;
  259. }
  260. }
  261. static inline uint32_t count_trailing_zeroes(uint32_t x)
  262. {
  263. #ifdef _WINDOWS
  264. uint32_t r = 0;
  265. _BitScanReverse(&r, x);
  266. return (31 - r);
  267. #else
  268. return (uint32_t) __builtin_ctzl(x);
  269. #endif
  270. }
  271. #endif