words.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. // words.h - originally written and placed in the public domain by Wei Dai
  2. /// \file words.h
  3. /// \brief Support functions for word operations
  4. #ifndef CRYPTOPP_WORDS_H
  5. #define CRYPTOPP_WORDS_H
  6. #include "config.h"
  7. #include "misc.h"
  8. NAMESPACE_BEGIN(CryptoPP)
  9. /// \brief Count the number of words
  10. /// \param x word array
  11. /// \param n size of the word array, in elements
  12. /// \return number of words used in the array.
  13. /// \details CountWords counts the number of words in a word array.
  14. /// Leading 0-words are not included in the count.
  15. /// \since Crypto++ 1.0
  16. inline size_t CountWords(const word *x, size_t n)
  17. {
  18. while (n && x[n-1]==0)
  19. n--;
  20. return n;
  21. }
  22. /// \brief Set the value of words
  23. /// \param r word array
  24. /// \param a value
  25. /// \param n size of the word array, in elements
  26. /// \details SetWords sets all elements in the word array to the
  27. /// specified value.
  28. /// \since Crypto++ 1.0
  29. inline void SetWords(word *r, word a, size_t n)
  30. {
  31. for (size_t i=0; i<n; i++)
  32. r[i] = a;
  33. }
  34. /// \brief Copy word array
  35. /// \param r destination word array
  36. /// \param a source word array
  37. /// \param n size of the word array, in elements
  38. /// \details CopyWords copies the source word array to the destination
  39. /// word array.
  40. /// \since Crypto++ 1.0
  41. inline void CopyWords(word *r, const word *a, size_t n)
  42. {
  43. if (r != a)
  44. #if CRYPTOPP_MSC_VERSION
  45. memcpy_s(r, n*WORD_SIZE, a, n*WORD_SIZE);
  46. #else
  47. std::memcpy(r, a, n*WORD_SIZE);
  48. #endif
  49. }
  50. /// \brief XOR word arrays
  51. /// \param r destination word array
  52. /// \param a first source word array
  53. /// \param b second source word array
  54. /// \param n size of the word array, in elements
  55. /// \details XorWords XORs the two source word arrays and copies the
  56. /// result to the destination word array.
  57. /// \since Crypto++ 1.0
  58. inline void XorWords(word *r, const word *a, const word *b, size_t n)
  59. {
  60. for (size_t i=0; i<n; i++)
  61. r[i] = a[i] ^ b[i];
  62. }
  63. /// \brief XOR word arrays
  64. /// \param r destination word array
  65. /// \param a source word array
  66. /// \param n size of the word array, in elements
  67. /// \details XorWords XORs the source word array with the
  68. /// destination word array.
  69. /// \since Crypto++ 1.0
  70. inline void XorWords(word *r, const word *a, size_t n)
  71. {
  72. for (size_t i=0; i<n; i++)
  73. r[i] ^= a[i];
  74. }
  75. /// \brief AND word arrays
  76. /// \param r destination word array
  77. /// \param a first source word array
  78. /// \param b second source word array
  79. /// \param n size of the word array, in elements
  80. /// \details AndWords ANDs the two source word arrays and copies the
  81. /// result to the destination word array.
  82. /// \since Crypto++ 1.0
  83. inline void AndWords(word *r, const word *a, const word *b, size_t n)
  84. {
  85. for (size_t i=0; i<n; i++)
  86. r[i] = a[i] & b[i];
  87. }
  88. /// \brief AND word arrays
  89. /// \param r destination word array
  90. /// \param a source word array
  91. /// \param n size of the word array, in elements
  92. /// \details AndWords ANDs the source word array with the
  93. /// destination word array.
  94. /// \since Crypto++ 1.0
  95. inline void AndWords(word *r, const word *a, size_t n)
  96. {
  97. for (size_t i=0; i<n; i++)
  98. r[i] &= a[i];
  99. }
  100. /// \brief OR word arrays
  101. /// \param r destination word array
  102. /// \param a first source word array
  103. /// \param b second source word array
  104. /// \param n size of the word array, in elements
  105. /// \details OrWords ORs the two source word arrays and copies the
  106. /// result to the destination word array.
  107. /// \since Crypto++ 1.0
  108. inline void OrWords(word *r, const word *a, const word *b, size_t n)
  109. {
  110. for (size_t i=0; i<n; i++)
  111. r[i] = a[i] | b[i];
  112. }
  113. /// \brief OR word arrays
  114. /// \param r destination word array
  115. /// \param a source word array
  116. /// \param n size of the word array, in elements
  117. /// \details OrWords ORs the source word array with the
  118. /// destination word array.
  119. /// \since Crypto++ 1.0
  120. inline void OrWords(word *r, const word *a, size_t n)
  121. {
  122. for (size_t i=0; i<n; i++)
  123. r[i] |= a[i];
  124. }
  125. /// \brief Left shift word array
  126. /// \param r word array
  127. /// \param n size of the word array, in elements
  128. /// \param shiftBits number of bits to shift
  129. /// \return word shifted out
  130. /// \details ShiftWordsLeftByBits shifts the word array left by
  131. /// shiftBits. ShiftWordsLeftByBits shifts bits out on the left;
  132. /// it does not extend the array.
  133. /// \note shiftBits must be less than WORD_BITS.
  134. /// \since Crypto++ 1.0
  135. inline word ShiftWordsLeftByBits(word *r, size_t n, unsigned int shiftBits)
  136. {
  137. CRYPTOPP_ASSERT (shiftBits<WORD_BITS);
  138. word u, carry=0;
  139. if (shiftBits)
  140. for (size_t i=0; i<n; i++)
  141. {
  142. u = r[i];
  143. r[i] = (u << shiftBits) | carry;
  144. carry = u >> (WORD_BITS-shiftBits);
  145. }
  146. return carry;
  147. }
  148. /// \brief Right shift word array
  149. /// \param r word array
  150. /// \param n size of the word array, in elements
  151. /// \param shiftBits number of bits to shift
  152. /// \return word shifted out
  153. /// \details ShiftWordsRightByBits shifts the word array shight by
  154. /// shiftBits. ShiftWordsRightByBits shifts bits out on the right.
  155. /// \note shiftBits must be less than WORD_BITS.
  156. /// \since Crypto++ 1.0
  157. inline word ShiftWordsRightByBits(word *r, size_t n, unsigned int shiftBits)
  158. {
  159. CRYPTOPP_ASSERT (shiftBits<WORD_BITS);
  160. word u, carry=0;
  161. if (shiftBits)
  162. for (size_t i=n; i>0; i--)
  163. {
  164. u = r[i-1];
  165. r[i-1] = (u >> shiftBits) | carry;
  166. carry = u << (WORD_BITS-shiftBits);
  167. }
  168. return carry;
  169. }
  170. /// \brief Left shift word array
  171. /// \param r word array
  172. /// \param n size of the word array, in elements
  173. /// \param shiftWords number of words to shift
  174. /// \details ShiftWordsLeftByWords shifts the word array left by
  175. /// shiftWords. ShiftWordsLeftByWords shifts bits out on the left;
  176. /// it does not extend the array.
  177. /// \since Crypto++ 1.0
  178. inline void ShiftWordsLeftByWords(word *r, size_t n, size_t shiftWords)
  179. {
  180. shiftWords = STDMIN(shiftWords, n);
  181. if (shiftWords)
  182. {
  183. for (size_t i=n-1; i>=shiftWords; i--)
  184. r[i] = r[i-shiftWords];
  185. SetWords(r, 0, shiftWords);
  186. }
  187. }
  188. /// \brief Right shift word array
  189. /// \param r word array
  190. /// \param n size of the word array, in elements
  191. /// \param shiftWords number of words to shift
  192. /// \details ShiftWordsRightByWords shifts the word array right by
  193. /// shiftWords. ShiftWordsRightByWords shifts bits out on the right.
  194. /// \since Crypto++ 1.0
  195. inline void ShiftWordsRightByWords(word *r, size_t n, size_t shiftWords)
  196. {
  197. shiftWords = STDMIN(shiftWords, n);
  198. if (shiftWords)
  199. {
  200. for (size_t i=0; i+shiftWords<n; i++)
  201. r[i] = r[i+shiftWords];
  202. SetWords(r+n-shiftWords, 0, shiftWords);
  203. }
  204. }
  205. NAMESPACE_END
  206. #endif