2 Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; see the file COPYING. If not, write to the
15 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
19 /* based on Wei Dai's integer.h from CryptoPP */
22 #ifndef TAO_CRYPT_INTEGER_HPP
23 #define TAO_CRYPT_INTEGER_HPP
28 // 4660: explicitly instantiating a class already implicitly instantiated
29 // 4661: no suitable definition provided for explicit template request
30 // 4786: identifer was truncated in debug information
31 // 4355: 'this' : used in base member initializer list
32 # pragma warning(disable: 4250 4660 4661 4786 4355)
44 #include "algorithm.hpp"
48 #ifdef TAOCRYPT_X86ASM_AVAILABLE
51 #if (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 500)) || \
52 (defined(__ICL) && (__ICL >= 500))
53 #define SSE2_INTRINSICS_AVAILABLE
54 #define TAOCRYPT_MM_MALLOC_AVAILABLE
55 #elif defined(_MSC_VER)
56 // _mm_free seems to be the only way to tell if the Processor Pack is
60 #define SSE2_INTRINSICS_AVAILABLE
61 #define TAOCRYPT_MM_MALLOC_AVAILABLE
66 // SSE2 intrinsics work in GCC 3.3 or later
67 #if defined(__SSE2__) && (__GNUC__ == 4 || __GNUC_MAJOR__ > 3 || \
69 #define SSE2_INTRINSICS_AVAILABLE
79 #if defined(SSE2_INTRINSICS_AVAILABLE)
81 // Allocator handling proper alignment
83 class AlignedAllocator
: public AllocatorBase
<T
>
86 typedef typename AllocatorBase
<T
>::pointer pointer
;
87 typedef typename AllocatorBase
<T
>::size_type size_type
;
89 pointer
allocate(size_type n
, const void* = 0);
90 void deallocate(void* p
, size_type n
);
91 pointer
reallocate(T
* p
, size_type oldSize
, size_type newSize
,
94 return StdReallocate(*this, p
, oldSize
, newSize
, preserve
);
97 #if !(defined(TAOCRYPT_MALLOC_ALIGNMENT_IS_16) || \
98 defined(TAOCRYPT_MEMALIGN_AVAILABLE) || \
99 defined(TAOCRYPT_MM_MALLOC_AVAILABLE))
100 #define TAOCRYPT_NO_ALIGNED_ALLOC
101 AlignedAllocator() : m_pBlock(0) {}
107 typedef Block
<word
, AlignedAllocator
<word
> > AlignedWordBlock
;
109 typedef WordBlock AlignedWordBlock
;
115 template<typename T
> inline
116 const T
& max(const T
& a
, const T
& b
)
118 return a
> b
? a
: b
;
122 // Large Integer class
125 enum Sign
{POSITIVE
= 0, NEGATIVE
= 1 };
126 enum Signedness
{ UNSIGNED
, SIGNED
};
127 enum RandomNumberType
{ ANY
, PRIME
};
129 class DivideByZero
{};
132 Integer(const Integer
& t
);
133 Integer(signed long value
);
134 Integer(Sign s
, word highWord
, word lowWord
);
137 explicit Integer(Source
&);
139 Integer(const byte
* encodedInteger
, unsigned int byteCount
,
140 Signedness s
= UNSIGNED
);
144 static const Integer
& Zero();
145 static const Integer
& One();
147 Integer
& Ref() { return *this; }
149 Integer(RandomNumberGenerator
& rng
, const Integer
& min
,
152 static Integer
Power2(unsigned int e
);
154 unsigned int MinEncodedSize(Signedness
= UNSIGNED
) const;
155 unsigned int Encode(byte
* output
, unsigned int outputLen
,
156 Signedness
= UNSIGNED
) const;
158 void Decode(const byte
* input
, unsigned int inputLen
,
159 Signedness
= UNSIGNED
);
160 void Decode(Source
&);
162 bool IsConvertableToLong() const;
163 signed long ConvertToLong() const;
165 unsigned int BitCount() const;
166 unsigned int ByteCount() const;
167 unsigned int WordCount() const;
169 bool GetBit(unsigned int i
) const;
170 byte
GetByte(unsigned int i
) const;
171 unsigned long GetBits(unsigned int i
, unsigned int n
) const;
173 bool IsZero() const { return !*this; }
174 bool NotZero() const { return !IsZero(); }
175 bool IsNegative() const { return sign_
== NEGATIVE
; }
176 bool NotNegative() const { return !IsNegative(); }
177 bool IsPositive() const { return NotNegative() && NotZero(); }
178 bool NotPositive() const { return !IsPositive(); }
179 bool IsEven() const { return GetBit(0) == 0; }
180 bool IsOdd() const { return GetBit(0) == 1; }
182 Integer
& operator=(const Integer
& t
);
183 Integer
& operator+=(const Integer
& t
);
184 Integer
& operator-=(const Integer
& t
);
185 Integer
& operator*=(const Integer
& t
) { return *this = Times(t
); }
186 Integer
& operator/=(const Integer
& t
)
187 { return *this = DividedBy(t
);}
188 Integer
& operator%=(const Integer
& t
) { return *this = Modulo(t
); }
189 Integer
& operator/=(word t
) { return *this = DividedBy(t
); }
190 Integer
& operator%=(word t
) { return *this = Modulo(t
); }
191 Integer
& operator<<=(unsigned int);
192 Integer
& operator>>=(unsigned int);
195 void Randomize(RandomNumberGenerator
&rng
, unsigned int bitcount
);
196 void Randomize(RandomNumberGenerator
&rng
, const Integer
&min
,
199 void SetBit(unsigned int n
, bool value
= 1);
200 void SetByte(unsigned int n
, byte value
);
203 void SetPositive() { sign_
= POSITIVE
; }
204 void SetNegative() { if (!!(*this)) sign_
= NEGATIVE
; }
205 void Swap(Integer
& a
);
207 bool operator!() const;
208 Integer
operator+() const {return *this;}
209 Integer
operator-() const;
210 Integer
& operator++();
211 Integer
& operator--();
212 Integer
operator++(int)
213 { Integer temp
= *this; ++*this; return temp
; }
214 Integer
operator--(int)
215 { Integer temp
= *this; --*this; return temp
; }
217 int Compare(const Integer
& a
) const;
219 Integer
Plus(const Integer
&b
) const;
220 Integer
Minus(const Integer
&b
) const;
221 Integer
Times(const Integer
&b
) const;
222 Integer
DividedBy(const Integer
&b
) const;
223 Integer
Modulo(const Integer
&b
) const;
224 Integer
DividedBy(word b
) const;
225 word
Modulo(word b
) const;
227 Integer
operator>>(unsigned int n
) const { return Integer(*this)>>=n
; }
228 Integer
operator<<(unsigned int n
) const { return Integer(*this)<<=n
; }
230 Integer
AbsoluteValue() const;
231 Integer
Doubled() const { return Plus(*this); }
232 Integer
Squared() const { return Times(*this); }
233 Integer
SquareRoot() const;
235 bool IsSquare() const;
238 Integer
MultiplicativeInverse() const;
240 friend Integer
a_times_b_mod_c(const Integer
& x
, const Integer
& y
,
242 friend Integer
a_exp_b_mod_c(const Integer
& x
, const Integer
& e
,
245 static void Divide(Integer
& r
, Integer
& q
, const Integer
& a
,
247 static void Divide(word
& r
, Integer
& q
, const Integer
& a
, word d
);
248 static void DivideByPowerOf2(Integer
& r
, Integer
& q
, const Integer
& a
,
250 static Integer
Gcd(const Integer
& a
, const Integer
& n
);
252 Integer
InverseMod(const Integer
& n
) const;
253 word
InverseMod(word n
) const;
256 friend class ModularArithmetic
;
257 friend class MontgomeryRepresentation
;
259 Integer(word value
, unsigned int length
);
260 int PositiveCompare(const Integer
& t
) const;
262 friend void PositiveAdd(Integer
& sum
, const Integer
& a
, const Integer
& b
);
263 friend void PositiveSubtract(Integer
& diff
, const Integer
& a
,
265 friend void PositiveMultiply(Integer
& product
, const Integer
& a
,
267 friend void PositiveDivide(Integer
& remainder
, Integer
& quotient
, const
268 Integer
& dividend
, const Integer
& divisor
);
269 AlignedWordBlock reg_
;
273 inline bool operator==(const Integer
& a
, const Integer
& b
)
274 {return a
.Compare(b
)==0;}
275 inline bool operator!=(const Integer
& a
, const Integer
& b
)
276 {return a
.Compare(b
)!=0;}
277 inline bool operator> (const Integer
& a
, const Integer
& b
)
278 {return a
.Compare(b
)> 0;}
279 inline bool operator>=(const Integer
& a
, const Integer
& b
)
280 {return a
.Compare(b
)>=0;}
281 inline bool operator< (const Integer
& a
, const Integer
& b
)
282 {return a
.Compare(b
)< 0;}
283 inline bool operator<=(const Integer
& a
, const Integer
& b
)
284 {return a
.Compare(b
)<=0;}
286 inline Integer
operator+(const Integer
&a
, const Integer
&b
)
288 inline Integer
operator-(const Integer
&a
, const Integer
&b
)
290 inline Integer
operator*(const Integer
&a
, const Integer
&b
)
292 inline Integer
operator/(const Integer
&a
, const Integer
&b
)
293 {return a
.DividedBy(b
);}
294 inline Integer
operator%(const Integer
&a
, const Integer
&b
)
295 {return a
.Modulo(b
);}
296 inline Integer
operator/(const Integer
&a
, word b
) {return a
.DividedBy(b
);}
297 inline word
operator%(const Integer
&a
, word b
) {return a
.Modulo(b
);}
299 inline void swap(Integer
&a
, Integer
&b
)
305 Integer
CRT(const Integer
& xp
, const Integer
& p
, const Integer
& xq
,
306 const Integer
& q
, const Integer
& u
);
308 inline Integer
ModularExponentiation(const Integer
& a
, const Integer
& e
,
311 return a_exp_b_mod_c(a
, e
, m
);
314 Integer
ModularRoot(const Integer
& a
, const Integer
& dp
, const Integer
& dq
,
315 const Integer
& p
, const Integer
& q
, const Integer
& u
);
321 #endif // TAO_CRYPT_INTEGER_HPP