gf128.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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. #include "cf_config.h"
  15. #include "gf128.h"
  16. #include "bitops.h"
  17. #include <string.h>
  18. void cf_gf128_tobytes_be(const cf_gf128 in, uint8_t out[16])
  19. {
  20. write32_be(in[0], out + 0);
  21. write32_be(in[1], out + 4);
  22. write32_be(in[2], out + 8);
  23. write32_be(in[3], out + 12);
  24. }
  25. void cf_gf128_frombytes_be(const uint8_t in[16], cf_gf128 out)
  26. {
  27. out[0] = read32_be(in + 0);
  28. out[1] = read32_be(in + 4);
  29. out[2] = read32_be(in + 8);
  30. out[3] = read32_be(in + 12);
  31. }
  32. /* out = 2 * in. Arguments may alias. */
  33. void cf_gf128_double(const cf_gf128 in, cf_gf128 out)
  34. {
  35. uint8_t table[2] = { 0x00, 0x87 };
  36. uint32_t borrow = 0;
  37. uint32_t inword;
  38. inword = in[3]; out[3] = (inword << 1) | borrow; borrow = inword >> 31;
  39. inword = in[2]; out[2] = (inword << 1) | borrow; borrow = inword >> 31;
  40. inword = in[1]; out[1] = (inword << 1) | borrow; borrow = inword >> 31;
  41. inword = in[0]; out[0] = (inword << 1) | borrow; borrow = inword >> 31;
  42. #if CF_CACHE_SIDE_CHANNEL_PROTECTION
  43. out[3] ^= select_u8(borrow, table, 2);
  44. #else
  45. out[3] ^= table[borrow];
  46. #endif
  47. }
  48. /* out = 2 * in. Arguments may alias. */
  49. void cf_gf128_double_le(const cf_gf128 in, cf_gf128 out)
  50. {
  51. uint8_t table[2] = { 0x00, 0xe1 };
  52. uint32_t borrow = 0;
  53. uint32_t inword;
  54. inword = in[0]; out[0] = (inword >> 1) | (borrow << 31); borrow = inword & 1;
  55. inword = in[1]; out[1] = (inword >> 1) | (borrow << 31); borrow = inword & 1;
  56. inword = in[2]; out[2] = (inword >> 1) | (borrow << 31); borrow = inword & 1;
  57. inword = in[3]; out[3] = (inword >> 1) | (borrow << 31); borrow = inword & 1;
  58. #if CF_CACHE_SIDE_CHANNEL_PROTECTION
  59. out[0] ^= select_u8(borrow, table, 2) << 24;
  60. #else
  61. out[0] ^= table[borrow] << 24;
  62. #endif
  63. }
  64. /* out = x + y. Arguments may alias. */
  65. void cf_gf128_add(const cf_gf128 x, const cf_gf128 y, cf_gf128 out)
  66. {
  67. out[0] = x[0] ^ y[0];
  68. out[1] = x[1] ^ y[1];
  69. out[2] = x[2] ^ y[2];
  70. out[3] = x[3] ^ y[3];
  71. }
  72. /* out = xy. Arguments may alias. */
  73. void cf_gf128_mul(const cf_gf128 x, const cf_gf128 y, cf_gf128 out)
  74. {
  75. #if CF_TIME_SIDE_CHANNEL_PROTECTION
  76. cf_gf128 zero = { 0 };
  77. #endif
  78. /* Z_0 = 0^128
  79. * V_0 = Y */
  80. cf_gf128 Z, V;
  81. memset(Z, 0, sizeof Z);
  82. memcpy(V, y, sizeof V);
  83. for (int i = 0; i < 128; i++)
  84. {
  85. uint32_t word = x[i >> 5];
  86. uint8_t bit = (word >> (31 - (i & 31))) & 1;
  87. #if CF_TIME_SIDE_CHANNEL_PROTECTION
  88. select_xor128(Z, zero, V, bit);
  89. #else
  90. if (bit)
  91. xor_words(Z, V, 4);
  92. #endif
  93. cf_gf128_double_le(V, V);
  94. }
  95. memcpy(out, Z, sizeof Z);
  96. }