| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- // words.h - originally written and placed in the public domain by Wei Dai
- /// \file words.h
- /// \brief Support functions for word operations
- #ifndef CRYPTOPP_WORDS_H
- #define CRYPTOPP_WORDS_H
- #include "config.h"
- #include "misc.h"
- NAMESPACE_BEGIN(CryptoPP)
- /// \brief Count the number of words
- /// \param x word array
- /// \param n size of the word array, in elements
- /// \return number of words used in the array.
- /// \details CountWords counts the number of words in a word array.
- /// Leading 0-words are not included in the count.
- /// \since Crypto++ 1.0
- inline size_t CountWords(const word *x, size_t n)
- {
- while (n && x[n-1]==0)
- n--;
- return n;
- }
- /// \brief Set the value of words
- /// \param r word array
- /// \param a value
- /// \param n size of the word array, in elements
- /// \details SetWords sets all elements in the word array to the
- /// specified value.
- /// \since Crypto++ 1.0
- inline void SetWords(word *r, word a, size_t n)
- {
- for (size_t i=0; i<n; i++)
- r[i] = a;
- }
- /// \brief Copy word array
- /// \param r destination word array
- /// \param a source word array
- /// \param n size of the word array, in elements
- /// \details CopyWords copies the source word array to the destination
- /// word array.
- /// \since Crypto++ 1.0
- inline void CopyWords(word *r, const word *a, size_t n)
- {
- if (r != a)
- #if CRYPTOPP_MSC_VERSION
- memcpy_s(r, n*WORD_SIZE, a, n*WORD_SIZE);
- #else
- std::memcpy(r, a, n*WORD_SIZE);
- #endif
- }
- /// \brief XOR word arrays
- /// \param r destination word array
- /// \param a first source word array
- /// \param b second source word array
- /// \param n size of the word array, in elements
- /// \details XorWords XORs the two source word arrays and copies the
- /// result to the destination word array.
- /// \since Crypto++ 1.0
- inline void XorWords(word *r, const word *a, const word *b, size_t n)
- {
- for (size_t i=0; i<n; i++)
- r[i] = a[i] ^ b[i];
- }
- /// \brief XOR word arrays
- /// \param r destination word array
- /// \param a source word array
- /// \param n size of the word array, in elements
- /// \details XorWords XORs the source word array with the
- /// destination word array.
- /// \since Crypto++ 1.0
- inline void XorWords(word *r, const word *a, size_t n)
- {
- for (size_t i=0; i<n; i++)
- r[i] ^= a[i];
- }
- /// \brief AND word arrays
- /// \param r destination word array
- /// \param a first source word array
- /// \param b second source word array
- /// \param n size of the word array, in elements
- /// \details AndWords ANDs the two source word arrays and copies the
- /// result to the destination word array.
- /// \since Crypto++ 1.0
- inline void AndWords(word *r, const word *a, const word *b, size_t n)
- {
- for (size_t i=0; i<n; i++)
- r[i] = a[i] & b[i];
- }
- /// \brief AND word arrays
- /// \param r destination word array
- /// \param a source word array
- /// \param n size of the word array, in elements
- /// \details AndWords ANDs the source word array with the
- /// destination word array.
- /// \since Crypto++ 1.0
- inline void AndWords(word *r, const word *a, size_t n)
- {
- for (size_t i=0; i<n; i++)
- r[i] &= a[i];
- }
- /// \brief OR word arrays
- /// \param r destination word array
- /// \param a first source word array
- /// \param b second source word array
- /// \param n size of the word array, in elements
- /// \details OrWords ORs the two source word arrays and copies the
- /// result to the destination word array.
- /// \since Crypto++ 1.0
- inline void OrWords(word *r, const word *a, const word *b, size_t n)
- {
- for (size_t i=0; i<n; i++)
- r[i] = a[i] | b[i];
- }
- /// \brief OR word arrays
- /// \param r destination word array
- /// \param a source word array
- /// \param n size of the word array, in elements
- /// \details OrWords ORs the source word array with the
- /// destination word array.
- /// \since Crypto++ 1.0
- inline void OrWords(word *r, const word *a, size_t n)
- {
- for (size_t i=0; i<n; i++)
- r[i] |= a[i];
- }
- /// \brief Left shift word array
- /// \param r word array
- /// \param n size of the word array, in elements
- /// \param shiftBits number of bits to shift
- /// \return word shifted out
- /// \details ShiftWordsLeftByBits shifts the word array left by
- /// shiftBits. ShiftWordsLeftByBits shifts bits out on the left;
- /// it does not extend the array.
- /// \note shiftBits must be less than WORD_BITS.
- /// \since Crypto++ 1.0
- inline word ShiftWordsLeftByBits(word *r, size_t n, unsigned int shiftBits)
- {
- CRYPTOPP_ASSERT (shiftBits<WORD_BITS);
- word u, carry=0;
- if (shiftBits)
- for (size_t i=0; i<n; i++)
- {
- u = r[i];
- r[i] = (u << shiftBits) | carry;
- carry = u >> (WORD_BITS-shiftBits);
- }
- return carry;
- }
- /// \brief Right shift word array
- /// \param r word array
- /// \param n size of the word array, in elements
- /// \param shiftBits number of bits to shift
- /// \return word shifted out
- /// \details ShiftWordsRightByBits shifts the word array shight by
- /// shiftBits. ShiftWordsRightByBits shifts bits out on the right.
- /// \note shiftBits must be less than WORD_BITS.
- /// \since Crypto++ 1.0
- inline word ShiftWordsRightByBits(word *r, size_t n, unsigned int shiftBits)
- {
- CRYPTOPP_ASSERT (shiftBits<WORD_BITS);
- word u, carry=0;
- if (shiftBits)
- for (size_t i=n; i>0; i--)
- {
- u = r[i-1];
- r[i-1] = (u >> shiftBits) | carry;
- carry = u << (WORD_BITS-shiftBits);
- }
- return carry;
- }
- /// \brief Left shift word array
- /// \param r word array
- /// \param n size of the word array, in elements
- /// \param shiftWords number of words to shift
- /// \details ShiftWordsLeftByWords shifts the word array left by
- /// shiftWords. ShiftWordsLeftByWords shifts bits out on the left;
- /// it does not extend the array.
- /// \since Crypto++ 1.0
- inline void ShiftWordsLeftByWords(word *r, size_t n, size_t shiftWords)
- {
- shiftWords = STDMIN(shiftWords, n);
- if (shiftWords)
- {
- for (size_t i=n-1; i>=shiftWords; i--)
- r[i] = r[i-shiftWords];
- SetWords(r, 0, shiftWords);
- }
- }
- /// \brief Right shift word array
- /// \param r word array
- /// \param n size of the word array, in elements
- /// \param shiftWords number of words to shift
- /// \details ShiftWordsRightByWords shifts the word array right by
- /// shiftWords. ShiftWordsRightByWords shifts bits out on the right.
- /// \since Crypto++ 1.0
- inline void ShiftWordsRightByWords(word *r, size_t n, size_t shiftWords)
- {
- shiftWords = STDMIN(shiftWords, n);
- if (shiftWords)
- {
- for (size_t i=0; i+shiftWords<n; i++)
- r[i] = r[i+shiftWords];
- SetWords(r+n-shiftWords, 0, shiftWords);
- }
- }
- NAMESPACE_END
- #endif
|