GaloisField.hpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. #pragma once
  2. #include <stddef.h>
  3. #include <stdint.h>
  4. #include <vector>
  5. #include <type_traits>
  6. struct GaloisFieldInitByZero {};
  7. struct GaloisFieldInitByOne {};
  8. struct GaloisFieldInitByElement {};
  9. struct GaloisFieldInitByDump {};
  10. template<typename __FieldTraits>
  11. class GaloisField {
  12. public:
  13. static constexpr size_t BitSizeValue = __FieldTraits::BitSizeValue;
  14. static constexpr size_t DumpSizeValue = __FieldTraits::DumpSizeValue;
  15. private:
  16. static_assert(std::is_pod<typename __FieldTraits::ElementType>::value == true);
  17. typename __FieldTraits::ElementType _Val;
  18. #ifdef _MSC_VER
  19. #pragma warning(push)
  20. #pragma warning(disable: 26495) // disable uninitialized warning
  21. #endif
  22. struct NoInitialization {};
  23. GaloisField(NoInitialization) noexcept {};
  24. #ifdef _MSC_VER
  25. #pragma warning(pop)
  26. #endif
  27. public:
  28. GaloisField() noexcept {
  29. __FieldTraits::SetZero(_Val);
  30. }
  31. GaloisField(GaloisFieldInitByZero) noexcept {
  32. __FieldTraits::SetZero(_Val);
  33. }
  34. GaloisField(GaloisFieldInitByOne) noexcept {
  35. __FieldTraits::SetOne(_Val);
  36. }
  37. GaloisField(GaloisFieldInitByElement, const typename __FieldTraits::ElementType& Element) {
  38. __FieldTraits::Verify(Element);
  39. _Val = Element;
  40. }
  41. GaloisField(GaloisFieldInitByDump, const void* pbBuffer, size_t cbBuffer) {
  42. __FieldTraits::Load(_Val, pbBuffer, cbBuffer);
  43. }
  44. template<typename F=__FieldTraits, typename std::enable_if<F::BitSizeValue <= sizeof(uintptr_t) * 8, std::nullptr_t>::type = nullptr>
  45. GaloisField(GaloisFieldInitByDump, uintptr_t SerializedValue) {
  46. __FieldTraits::Load(_Val, SerializedValue);
  47. }
  48. GaloisField<__FieldTraits>& operator=(const typename __FieldTraits::ElementType& Element) {
  49. __FieldTraits::Verify(Element);
  50. _Val = Element;
  51. return *this;
  52. }
  53. template<typename F=__FieldTraits, typename std::enable_if<F::BitSizeValue <= sizeof(uintptr_t) * 8, std::nullptr_t>::type = nullptr>
  54. GaloisField<__FieldTraits>& operator=(uintptr_t SerializedValue) {
  55. __FieldTraits::Load(_Val, SerializedValue);
  56. return *this;
  57. }
  58. bool IsZero() const noexcept {
  59. return __FieldTraits::IsZero(_Val);
  60. }
  61. bool IsOne() const noexcept {
  62. return __FieldTraits::IsOne(_Val);
  63. }
  64. bool operator==(const GaloisField<__FieldTraits>& Other) const noexcept {
  65. return __FieldTraits::IsEqual(_Val, Other._Val);
  66. }
  67. bool operator!=(const GaloisField<__FieldTraits>& Other) const noexcept {
  68. return __FieldTraits::IsEqual(_Val, Other._Val) == false;
  69. }
  70. GaloisField<__FieldTraits> operator+(const GaloisField<__FieldTraits>& Other) const noexcept {
  71. GaloisField<__FieldTraits> Result(NoInitialization{});
  72. __FieldTraits::Add(Result._Val, _Val, Other._Val);
  73. return Result;
  74. }
  75. GaloisField<__FieldTraits>& operator+=(const GaloisField<__FieldTraits>& Other) noexcept {
  76. __FieldTraits::AddAssign(_Val, Other._Val);
  77. return *this;
  78. }
  79. GaloisField<__FieldTraits> operator-(const GaloisField<__FieldTraits>& Other) const noexcept {
  80. GaloisField<__FieldTraits> Result(NoInitialization{});
  81. __FieldTraits::Substract(Result._Val, _Val, Other._Val);
  82. return Result;
  83. }
  84. GaloisField<__FieldTraits>& operator-=(const GaloisField<__FieldTraits>& Other) noexcept {
  85. __FieldTraits::SubstractAssign(_Val, Other._Val);
  86. return *this;
  87. }
  88. GaloisField<__FieldTraits> operator*(const GaloisField<__FieldTraits>& Other) const noexcept {
  89. GaloisField<__FieldTraits> Result(NoInitialization{});
  90. __FieldTraits::Multiply(Result._Val, _Val, Other._Val);
  91. return Result;
  92. }
  93. GaloisField<__FieldTraits>& operator*=(const GaloisField<__FieldTraits>& Other) noexcept {
  94. __FieldTraits::MultiplyAssign(_Val, Other._Val);
  95. return *this;
  96. }
  97. GaloisField<__FieldTraits> operator/(const GaloisField<__FieldTraits>& Other) const {
  98. GaloisField<__FieldTraits> Result(NoInitialization{});
  99. __FieldTraits::Divide(Result._Val, _Val, Other._Val);
  100. return Result;
  101. }
  102. GaloisField<__FieldTraits>& operator/=(const GaloisField<__FieldTraits>& Other) {
  103. __FieldTraits::DivideAssign(_Val, Other._Val);
  104. return *this;
  105. }
  106. GaloisField<__FieldTraits>& operator++() noexcept { // prefix ++
  107. __FieldTraits::AddOneAssign(_Val);
  108. return *this;
  109. }
  110. GaloisField<__FieldTraits> operator++(int) noexcept { // postfix ++
  111. GaloisField<__FieldTraits> Prev(*this);
  112. __FieldTraits::AddOneAssign(_Val);
  113. return Prev;
  114. }
  115. GaloisField<__FieldTraits>& operator--() noexcept { // prefix --
  116. __FieldTraits::SubstractOneAssign(_Val);
  117. return *this;
  118. }
  119. GaloisField<__FieldTraits> operator--(int) noexcept { // postfix --
  120. GaloisField<__FieldTraits> Prev(*this);
  121. __FieldTraits::SubstractOneAssign(_Val);
  122. return Prev;
  123. }
  124. GaloisField<__FieldTraits>& Inverse() {
  125. __FieldTraits::InverseAssign(_Val);
  126. return *this;
  127. }
  128. GaloisField<__FieldTraits> InverseValue() const {
  129. GaloisField<__FieldTraits> Result(NoInitialization{});
  130. __FieldTraits::Inverse(Result, _Val);
  131. return Result;
  132. }
  133. GaloisField<__FieldTraits>& AddOne() noexcept {
  134. __FieldTraits::AddOneAssign(_Val);
  135. return *this;
  136. }
  137. GaloisField<__FieldTraits> AddOneValue() const noexcept {
  138. GaloisField<__FieldTraits> Result(NoInitialization{});
  139. __FieldTraits::AddOne(Result._Val, _Val);
  140. return Result;
  141. }
  142. GaloisField<__FieldTraits>& SubstractOne() noexcept {
  143. __FieldTraits::SubstractOneAssign(_Val);
  144. return *this;
  145. }
  146. GaloisField<__FieldTraits> SubstractOneValue() const noexcept {
  147. GaloisField<__FieldTraits> Result(NoInitialization{});
  148. __FieldTraits::SubstractOne(Result._Val, _Val);
  149. return Result;
  150. }
  151. GaloisField<__FieldTraits>& Square() noexcept {
  152. __FieldTraits::SquareAssign(_Val);
  153. return *this;
  154. }
  155. GaloisField<__FieldTraits> SquareValue() const noexcept {
  156. GaloisField<__FieldTraits> Result(NoInitialization{});
  157. __FieldTraits::Square(Result._Val, _Val);
  158. return Result;
  159. }
  160. template<typename F=__FieldTraits, typename std::enable_if<F::BitSizeValue <= sizeof(uintptr_t) * 8, std::nullptr_t>::type = nullptr>
  161. uintptr_t Dump() const noexcept {
  162. return __FieldTraits::Dump(_Val);
  163. }
  164. size_t Dump(void* lpBuffer, size_t cbBuffer) const {
  165. return __FieldTraits::Dump(_Val, lpBuffer, cbBuffer);
  166. }
  167. std::vector<uint8_t> Dump() const noexcept {
  168. return __FieldTraits::Dump(_Val);
  169. }
  170. template<typename F=__FieldTraits, typename std::enable_if<F::BitSizeValue <= sizeof(uintptr_t) * 8, std::nullptr_t>::type = nullptr>
  171. GaloisField<__FieldTraits>& Load(uintptr_t SerializedValue) {
  172. __FieldTraits::Load(_Val, SerializedValue);
  173. return *this;
  174. }
  175. GaloisField<__FieldTraits>& Load(const void* lpBuffer, size_t cbBuffer) {
  176. __FieldTraits::Load(_Val, lpBuffer, cbBuffer);
  177. return *this;
  178. }
  179. GaloisField<__FieldTraits>& Load(const std::vector<uint8_t>& Buffer) {
  180. __FieldTraits::Load(_Val, Buffer);
  181. return *this;
  182. }
  183. };