1 | // modarith.h - written and placed in the public domain by Wei Dai |
---|
2 | |
---|
3 | //! \file modarith.h |
---|
4 | //! \brief Class file for performing modular arithmetic. |
---|
5 | |
---|
6 | #ifndef CRYPTOPP_MODARITH_H |
---|
7 | #define CRYPTOPP_MODARITH_H |
---|
8 | |
---|
9 | // implementations are in integer.cpp |
---|
10 | |
---|
11 | #include "cryptlib.h" |
---|
12 | #include "integer.h" |
---|
13 | #include "algebra.h" |
---|
14 | #include "secblock.h" |
---|
15 | #include "misc.h" |
---|
16 | |
---|
17 | NAMESPACE_BEGIN(CryptoPP) |
---|
18 | |
---|
19 | CRYPTOPP_DLL_TEMPLATE_CLASS AbstractGroup<Integer>; |
---|
20 | CRYPTOPP_DLL_TEMPLATE_CLASS AbstractRing<Integer>; |
---|
21 | CRYPTOPP_DLL_TEMPLATE_CLASS AbstractEuclideanDomain<Integer>; |
---|
22 | |
---|
23 | //! \class ModularArithmetic |
---|
24 | //! \brief Ring of congruence classes modulo n |
---|
25 | //! \details This implementation represents each congruence class as the smallest |
---|
26 | //! non-negative integer in that class. |
---|
27 | //! \details <tt>const Element&</tt> returned by member functions are references |
---|
28 | //! to internal data members. Since each object may have only |
---|
29 | //! one such data member for holding results, the following code |
---|
30 | //! will produce incorrect results: |
---|
31 | //! <pre> abcd = group.Add(group.Add(a,b), group.Add(c,d));</pre> |
---|
32 | //! But this should be fine: |
---|
33 | //! <pre> abcd = group.Add(a, group.Add(b, group.Add(c,d));</pre> |
---|
34 | class CRYPTOPP_DLL ModularArithmetic : public AbstractRing<Integer> |
---|
35 | { |
---|
36 | public: |
---|
37 | |
---|
38 | typedef int RandomizationParameter; |
---|
39 | typedef Integer Element; |
---|
40 | |
---|
41 | #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 |
---|
42 | virtual ~ModularArithmetic() {} |
---|
43 | #endif |
---|
44 | |
---|
45 | //! \brief Construct a ModularArithmetic |
---|
46 | //! \param modulus congruence class modulus |
---|
47 | ModularArithmetic(const Integer &modulus = Integer::One()) |
---|
48 | : AbstractRing<Integer>(), m_modulus(modulus), m_result((word)0, modulus.reg.size()) {} |
---|
49 | |
---|
50 | //! \brief Copy construct a ModularArithmetic |
---|
51 | //! \param ma other ModularArithmetic |
---|
52 | ModularArithmetic(const ModularArithmetic &ma) |
---|
53 | : AbstractRing<Integer>(), m_modulus(ma.m_modulus), m_result((word)0, ma.m_modulus.reg.size()) {} |
---|
54 | |
---|
55 | //! \brief Construct a ModularArithmetic |
---|
56 | //! \param bt BER encoded ModularArithmetic |
---|
57 | ModularArithmetic(BufferedTransformation &bt); // construct from BER encoded parameters |
---|
58 | |
---|
59 | //! \brief Clone a ModularArithmetic |
---|
60 | //! \returns pointer to a new ModularArithmetic |
---|
61 | //! \details Clone effectively copy constructs a new ModularArithmetic. The caller is |
---|
62 | //! responsible for deleting the pointer returned from this method. |
---|
63 | virtual ModularArithmetic * Clone() const {return new ModularArithmetic(*this);} |
---|
64 | |
---|
65 | //! \brief Encodes in DER format |
---|
66 | //! \param bt BufferedTransformation object |
---|
67 | void DEREncode(BufferedTransformation &bt) const; |
---|
68 | |
---|
69 | //! \brief Encodes element in DER format |
---|
70 | //! \param out BufferedTransformation object |
---|
71 | //! \param a Element to encode |
---|
72 | void DEREncodeElement(BufferedTransformation &out, const Element &a) const; |
---|
73 | |
---|
74 | //! \brief Decodes element in DER format |
---|
75 | //! \param in BufferedTransformation object |
---|
76 | //! \param a Element to decode |
---|
77 | void BERDecodeElement(BufferedTransformation &in, Element &a) const; |
---|
78 | |
---|
79 | //! \brief Retrieves the modulus |
---|
80 | //! \returns the modulus |
---|
81 | const Integer& GetModulus() const {return m_modulus;} |
---|
82 | |
---|
83 | //! \brief Sets the modulus |
---|
84 | //! \param newModulus the new modulus |
---|
85 | void SetModulus(const Integer &newModulus) |
---|
86 | {m_modulus = newModulus; m_result.reg.resize(m_modulus.reg.size());} |
---|
87 | |
---|
88 | //! \brief Retrieves the representation |
---|
89 | //! \returns true if the representation is MontgomeryRepresentation, false otherwise |
---|
90 | virtual bool IsMontgomeryRepresentation() const {return false;} |
---|
91 | |
---|
92 | //! \brief Reduces an element in the congruence class |
---|
93 | //! \param a element to convert |
---|
94 | //! \returns the reduced element |
---|
95 | //! \details ConvertIn is useful for derived classes, like MontgomeryRepresentation, which |
---|
96 | //! must convert between representations. |
---|
97 | virtual Integer ConvertIn(const Integer &a) const |
---|
98 | {return a%m_modulus;} |
---|
99 | |
---|
100 | //! \brief Reduces an element in the congruence class |
---|
101 | //! \param a element to convert |
---|
102 | //! \returns the reduced element |
---|
103 | //! \details ConvertOut is useful for derived classes, like MontgomeryRepresentation, which |
---|
104 | //! must convert between representations. |
---|
105 | virtual Integer ConvertOut(const Integer &a) const |
---|
106 | {return a;} |
---|
107 | |
---|
108 | //! \brief TODO |
---|
109 | //! \param a element to convert |
---|
110 | const Integer& Half(const Integer &a) const; |
---|
111 | |
---|
112 | //! \brief Compare two elements for equality |
---|
113 | //! \param a first element |
---|
114 | //! \param b second element |
---|
115 | //! \returns true if the elements are equal, false otherwise |
---|
116 | //! \details Equal() tests the elements for equality using <tt>a==b</tt> |
---|
117 | bool Equal(const Integer &a, const Integer &b) const |
---|
118 | {return a==b;} |
---|
119 | |
---|
120 | //! \brief Provides the Identity element |
---|
121 | //! \returns the Identity element |
---|
122 | const Integer& Identity() const |
---|
123 | {return Integer::Zero();} |
---|
124 | |
---|
125 | //! \brief Adds elements in the ring |
---|
126 | //! \param a first element |
---|
127 | //! \param b second element |
---|
128 | //! \returns the sum of <tt>a</tt> and <tt>b</tt> |
---|
129 | const Integer& Add(const Integer &a, const Integer &b) const; |
---|
130 | |
---|
131 | //! \brief TODO |
---|
132 | //! \param a first element |
---|
133 | //! \param b second element |
---|
134 | //! \returns TODO |
---|
135 | Integer& Accumulate(Integer &a, const Integer &b) const; |
---|
136 | |
---|
137 | //! \brief Inverts the element in the ring |
---|
138 | //! \param a first element |
---|
139 | //! \returns the inverse of the element |
---|
140 | const Integer& Inverse(const Integer &a) const; |
---|
141 | |
---|
142 | //! \brief Subtracts elements in the ring |
---|
143 | //! \param a first element |
---|
144 | //! \param b second element |
---|
145 | //! \returns the difference of <tt>a</tt> and <tt>b</tt>. The element <tt>a</tt> must provide a Subtract member function. |
---|
146 | const Integer& Subtract(const Integer &a, const Integer &b) const; |
---|
147 | |
---|
148 | //! \brief TODO |
---|
149 | //! \param a first element |
---|
150 | //! \param b second element |
---|
151 | //! \returns TODO |
---|
152 | Integer& Reduce(Integer &a, const Integer &b) const; |
---|
153 | |
---|
154 | //! \brief Doubles an element in the ring |
---|
155 | //! \param a the element |
---|
156 | //! \returns the element doubled |
---|
157 | //! \details Double returns <tt>Add(a, a)</tt>. The element <tt>a</tt> must provide an Add member function. |
---|
158 | const Integer& Double(const Integer &a) const |
---|
159 | {return Add(a, a);} |
---|
160 | |
---|
161 | //! \brief Retrieves the multiplicative identity |
---|
162 | //! \returns the multiplicative identity |
---|
163 | //! \details the base class implementations returns 1. |
---|
164 | const Integer& MultiplicativeIdentity() const |
---|
165 | {return Integer::One();} |
---|
166 | |
---|
167 | //! \brief Multiplies elements in the ring |
---|
168 | //! \param a the multiplicand |
---|
169 | //! \param b the multiplier |
---|
170 | //! \returns the product of a and b |
---|
171 | //! \details Multiply returns <tt>a*b\%n</tt>. |
---|
172 | const Integer& Multiply(const Integer &a, const Integer &b) const |
---|
173 | {return m_result1 = a*b%m_modulus;} |
---|
174 | |
---|
175 | //! \brief Square an element in the ring |
---|
176 | //! \param a the element |
---|
177 | //! \returns the element squared |
---|
178 | //! \details Square returns <tt>a*a\%n</tt>. The element <tt>a</tt> must provide a Square member function. |
---|
179 | const Integer& Square(const Integer &a) const |
---|
180 | {return m_result1 = a.Squared()%m_modulus;} |
---|
181 | |
---|
182 | //! \brief Determines whether an element is a unit in the ring |
---|
183 | //! \param a the element |
---|
184 | //! \returns true if the element is a unit after reduction, false otherwise. |
---|
185 | bool IsUnit(const Integer &a) const |
---|
186 | {return Integer::Gcd(a, m_modulus).IsUnit();} |
---|
187 | |
---|
188 | //! \brief Calculate the multiplicative inverse of an element in the ring |
---|
189 | //! \param a the element |
---|
190 | //! \details MultiplicativeInverse returns <tt>a<sup>-1</sup>\%n</tt>. The element <tt>a</tt> must |
---|
191 | //! provide a InverseMod member function. |
---|
192 | const Integer& MultiplicativeInverse(const Integer &a) const |
---|
193 | {return m_result1 = a.InverseMod(m_modulus);} |
---|
194 | |
---|
195 | //! \brief Divides elements in the ring |
---|
196 | //! \param a the dividend |
---|
197 | //! \param b the divisor |
---|
198 | //! \returns the quotient |
---|
199 | //! \details Divide returns <tt>a*b<sup>-1</sup>\%n</tt>. |
---|
200 | const Integer& Divide(const Integer &a, const Integer &b) const |
---|
201 | {return Multiply(a, MultiplicativeInverse(b));} |
---|
202 | |
---|
203 | //! \brief TODO |
---|
204 | //! \param x first element |
---|
205 | //! \param e1 first exponent |
---|
206 | //! \param y second element |
---|
207 | //! \param e2 second exponent |
---|
208 | //! \returns TODO |
---|
209 | Integer CascadeExponentiate(const Integer &x, const Integer &e1, const Integer &y, const Integer &e2) const; |
---|
210 | |
---|
211 | //! \brief Exponentiates a base to multiple exponents in the ring |
---|
212 | //! \param results an array of Elements |
---|
213 | //! \param base the base to raise to the exponents |
---|
214 | //! \param exponents an array of exponents |
---|
215 | //! \param exponentsCount the number of exponents in the array |
---|
216 | //! \details SimultaneousExponentiate() raises the base to each exponent in the exponents array and stores the |
---|
217 | //! result at the respective position in the results array. |
---|
218 | //! \details SimultaneousExponentiate() must be implemented in a derived class. |
---|
219 | //! \pre <tt>COUNTOF(results) == exponentsCount</tt> |
---|
220 | //! \pre <tt>COUNTOF(exponents) == exponentsCount</tt> |
---|
221 | void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; |
---|
222 | |
---|
223 | //! \brief Provides the maximum bit size of an element in the ring |
---|
224 | //! \returns maximum bit size of an element |
---|
225 | unsigned int MaxElementBitLength() const |
---|
226 | {return (m_modulus-1).BitCount();} |
---|
227 | |
---|
228 | //! \brief Provides the maximum byte size of an element in the ring |
---|
229 | //! \returns maximum byte size of an element |
---|
230 | unsigned int MaxElementByteLength() const |
---|
231 | {return (m_modulus-1).ByteCount();} |
---|
232 | |
---|
233 | //! \brief Provides a random element in the ring |
---|
234 | //! \param rng RandomNumberGenerator used to generate material |
---|
235 | //! \param ignore_for_now unused |
---|
236 | //! \returns a random element that is uniformly distributed |
---|
237 | //! \details RandomElement constructs a new element in the range <tt>[0,n-1]</tt>, inclusive. |
---|
238 | //! The element's class must provide a constructor with the signature <tt>Element(RandomNumberGenerator rng, |
---|
239 | //! Element min, Element max)</tt>. |
---|
240 | Element RandomElement( RandomNumberGenerator &rng , const RandomizationParameter &ignore_for_now = 0) const |
---|
241 | // left RandomizationParameter arg as ref in case RandomizationParameter becomes a more complicated struct |
---|
242 | { |
---|
243 | CRYPTOPP_UNUSED(ignore_for_now); |
---|
244 | return Element(rng, Integer::Zero(), m_modulus - Integer::One()) ; |
---|
245 | } |
---|
246 | |
---|
247 | //! \brief Compares two ModularArithmetic for equality |
---|
248 | //! \param rhs other ModularArithmetic |
---|
249 | //! \returns true if this is equal to the other, false otherwise |
---|
250 | //! \details The operator tests for equality using <tt>this.m_modulus == rhs.m_modulus</tt>. |
---|
251 | bool operator==(const ModularArithmetic &rhs) const |
---|
252 | {return m_modulus == rhs.m_modulus;} |
---|
253 | |
---|
254 | static const RandomizationParameter DefaultRandomizationParameter ; |
---|
255 | |
---|
256 | protected: |
---|
257 | Integer m_modulus; |
---|
258 | mutable Integer m_result, m_result1; |
---|
259 | }; |
---|
260 | |
---|
261 | // const ModularArithmetic::RandomizationParameter ModularArithmetic::DefaultRandomizationParameter = 0 ; |
---|
262 | |
---|
263 | //! \class MontgomeryRepresentation |
---|
264 | //! \brief Performs modular arithmetic in Montgomery representation for increased speed |
---|
265 | //! \details The Montgomery representation represents each congruence class <tt>[a]</tt> as |
---|
266 | //! <tt>a*r\%n</tt>, where <tt>r</tt> is a convenient power of 2. |
---|
267 | //! \details <tt>const Element&</tt> returned by member functions are references |
---|
268 | //! to internal data members. Since each object may have only |
---|
269 | //! one such data member for holding results, the following code |
---|
270 | //! will produce incorrect results: |
---|
271 | //! <pre> abcd = group.Add(group.Add(a,b), group.Add(c,d));</pre> |
---|
272 | //! But this should be fine: |
---|
273 | //! <pre> abcd = group.Add(a, group.Add(b, group.Add(c,d));</pre> |
---|
274 | class CRYPTOPP_DLL MontgomeryRepresentation : public ModularArithmetic |
---|
275 | { |
---|
276 | public: |
---|
277 | #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 |
---|
278 | virtual ~MontgomeryRepresentation() {} |
---|
279 | #endif |
---|
280 | |
---|
281 | //! \brief Construct a IsMontgomeryRepresentation |
---|
282 | //! \param modulus congruence class modulus |
---|
283 | //! \note The modulus must be odd. |
---|
284 | MontgomeryRepresentation(const Integer &modulus); |
---|
285 | |
---|
286 | //! \brief Clone a MontgomeryRepresentation |
---|
287 | //! \returns pointer to a new MontgomeryRepresentation |
---|
288 | //! \details Clone effectively copy constructs a new MontgomeryRepresentation. The caller is |
---|
289 | //! responsible for deleting the pointer returned from this method. |
---|
290 | virtual ModularArithmetic * Clone() const {return new MontgomeryRepresentation(*this);} |
---|
291 | |
---|
292 | bool IsMontgomeryRepresentation() const {return true;} |
---|
293 | |
---|
294 | Integer ConvertIn(const Integer &a) const |
---|
295 | {return (a<<(WORD_BITS*m_modulus.reg.size()))%m_modulus;} |
---|
296 | |
---|
297 | Integer ConvertOut(const Integer &a) const; |
---|
298 | |
---|
299 | const Integer& MultiplicativeIdentity() const |
---|
300 | {return m_result1 = Integer::Power2(WORD_BITS*m_modulus.reg.size())%m_modulus;} |
---|
301 | |
---|
302 | const Integer& Multiply(const Integer &a, const Integer &b) const; |
---|
303 | |
---|
304 | const Integer& Square(const Integer &a) const; |
---|
305 | |
---|
306 | const Integer& MultiplicativeInverse(const Integer &a) const; |
---|
307 | |
---|
308 | Integer CascadeExponentiate(const Integer &x, const Integer &e1, const Integer &y, const Integer &e2) const |
---|
309 | {return AbstractRing<Integer>::CascadeExponentiate(x, e1, y, e2);} |
---|
310 | |
---|
311 | void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const |
---|
312 | {AbstractRing<Integer>::SimultaneousExponentiate(results, base, exponents, exponentsCount);} |
---|
313 | |
---|
314 | private: |
---|
315 | Integer m_u; |
---|
316 | mutable IntegerSecBlock m_workspace; |
---|
317 | }; |
---|
318 | |
---|
319 | NAMESPACE_END |
---|
320 | |
---|
321 | #endif |
---|