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