summaryrefslogtreecommitdiff
path: root/integer.h
diff options
context:
space:
mode:
authorJeffrey Walton <noloader@gmail.com>2016-11-23 21:55:30 -0500
committerJeffrey Walton <noloader@gmail.com>2016-11-23 21:55:30 -0500
commit16ffe513a42110193254dac663ebfc732959ac85 (patch)
tree1fca886b57e6710de92b8e87b2ae00fe321410c9 /integer.h
parent6d898321e405f1abb40e35919171601f5f4b656f (diff)
downloadcryptopp-git-16ffe513a42110193254dac663ebfc732959ac85.tar.gz
Add Integer bitwise AND, OR and XOR (Issue 336)
Diffstat (limited to 'integer.h')
-rw-r--r--integer.h244
1 files changed, 180 insertions, 64 deletions
diff --git a/integer.h b/integer.h
index e59b0a56..5dd80101 100644
--- a/integer.h
+++ b/integer.h
@@ -6,8 +6,9 @@
//! with absolute value less than (256**sizeof(word))<sup>(256**sizeof(int))</sup>.
//! \details Internally, the library uses a sign magnitude representation, and the class
//! has two data members. The first is a IntegerSecBlock (a SecBlock<word>) and it is
-//! used to hold the representation. The second is a Sign, and its is used to track
-//! the sign of the Integer.
+//! used to hold the representation. The second is a Sign (an enumeration), and it is
+//! used to track the sign of the Integer.
+//! \since Crypto++ 1.0
#ifndef CRYPTOPP_INTEGER_H
#define CRYPTOPP_INTEGER_H
@@ -21,26 +22,23 @@
NAMESPACE_BEGIN(CryptoPP)
//! \struct InitializeInteger
-//! Performs static intialization of the Integer class
+//! \brief Performs static intialization of the Integer class
struct InitializeInteger
{
InitializeInteger();
};
-// http://github.com/weidai11/cryptopp/issues/256
-#if defined(CRYPTOPP_WORD128_AVAILABLE)
+// Always align, http://github.com/weidai11/cryptopp/issues/256
typedef SecBlock<word, AllocatorWithCleanup<word, true> > IntegerSecBlock;
-#else
-typedef SecBlock<word, AllocatorWithCleanup<word, CRYPTOPP_BOOL_X86> > IntegerSecBlock;
-#endif
//! \brief Multiple precision integer with arithmetic operations
//! \details The Integer class can represent positive and negative integers
//! with absolute value less than (256**sizeof(word))<sup>(256**sizeof(int))</sup>.
//! \details Internally, the library uses a sign magnitude representation, and the class
//! has two data members. The first is a IntegerSecBlock (a SecBlock<word>) and it is
-//! used to hold the representation. The second is a Sign, and its is used to track
-//! the sign of the Integer.
+//! used to hold the representation. The second is a Sign (an enumeration), and it is
+//! used to track the sign of the Integer.
+//! \since Crypto++ 1.0
//! \nosubgrouping
class CRYPTOPP_DLL Integer : private InitializeInteger, public ASN1Object
{
@@ -65,7 +63,7 @@ public:
//! \enum Sign
//! \brief Used internally to represent the integer
//! \details Sign is used internally to represent the integer. It is also used in a few API functions.
- //! \sa Signedness
+ //! \sa SetPositive(), SetNegative(), Signedness
enum Sign {
//! \brief the value is positive or 0
POSITIVE=0,
@@ -198,7 +196,7 @@ public:
//! \name ENCODE/DECODE
//@{
- //! \brief The minimum number of bytes to encode this integer
+ //! \brief Minimum number of bytes to encode this integer
//! \param sign enumeration indicating Signedness
//! \note The MinEncodedSize() of 0 is 1.
size_t MinEncodedSize(Signedness sign=UNSIGNED) const;
@@ -227,7 +225,7 @@ public:
//! The result is placed into a BufferedTransformation object
void DEREncode(BufferedTransformation &bt) const;
- //! encode absolute value as big-endian octet string
+ //! \brief Encode absolute value as big-endian octet string
//! \param bt BufferedTransformation object
//! \param length the number of mytes to decode
void DEREncodeAsOctetString(BufferedTransformation &bt, size_t length) const;
@@ -349,31 +347,68 @@ public:
//! \name MANIPULATORS
//@{
- //!
+ //! \brief Assignment
Integer& operator=(const Integer& t);
- //!
+ //! \brief Addition Assignment
Integer& operator+=(const Integer& t);
- //!
+ //! \brief Subtraction Assignment
Integer& operator-=(const Integer& t);
- //!
+ //! \brief Multiplication Assignment
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer& operator*=(const Integer& t) {return *this = Times(t);}
- //!
+ //! \brief Division Assignment
Integer& operator/=(const Integer& t) {return *this = DividedBy(t);}
- //!
+ //! \brief Remainder Assignment
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer& operator%=(const Integer& t) {return *this = Modulo(t);}
- //!
+ //! \brief Division Assignment
Integer& operator/=(word t) {return *this = DividedBy(t);}
- //!
+ //! \brief Remainder Assignment
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer& operator%=(word t) {return *this = Integer(POSITIVE, 0, Modulo(t));}
- //!
- Integer& operator<<=(size_t);
- //!
- Integer& operator>>=(size_t);
+ //! \brief Left-shift Assignment
+ Integer& operator<<=(size_t n);
+ //! \brief Right-shift Assignment
+ Integer& operator>>=(size_t n);
+
+ //! \brief Bitwise AND Assignment
+ //! \param t the other Integer
+ //! \returns the result of *this & t
+ //! \details operator&=() performs a bitwise AND on *this. Missing bits are truncated
+ //! at the most significant bit positions, so the result is as small as the
+ //! smaller of the operands.
+ //! \details Internally, Crypto++ uses a sign-magnitude representation. The library
+ //! does not attempt to interpret bits, and the result is always POSITIVE. If needed,
+ //! the integer should be converted to a 2's compliment representation before performing
+ //! the operation.
+ //! \since Crypto++ 5.7
+ Integer& operator&=(const Integer& t);
+ //! \brief Bitwise OR Assignment
+ //! \param t the second Integer
+ //! \returns the result of *this | t
+ //! \details operator|=() performs a bitwise OR on *this. Missing bits are shifted in
+ //! at the most significant bit positions, so the result is as large as the
+ //! larger of the operands.
+ //! \details Internally, Crypto++ uses a sign-magnitude representation. The library
+ //! does not attempt to interpret bits, and the result is always POSITIVE. If needed,
+ //! the integer should be converted to a 2's compliment representation before performing
+ //! the operation.
+ //! \since Crypto++ 5.7
+ Integer& operator|=(const Integer& t);
+ //! \brief Bitwise XOR Assignment
+ //! \param t the other Integer
+ //! \returns the result of *this ^ t
+ //! \details operator^=() performs a bitwise XOR on *this. Missing bits are shifted
+ //! in at the most significant bit positions, so the result is as large as the
+ //! larger of the operands.
+ //! \details Internally, Crypto++ uses a sign-magnitude representation. The library
+ //! does not attempt to interpret bits, and the result is always POSITIVE. If needed,
+ //! the integer should be converted to a 2's compliment representation before performing
+ //! the operation.
+ //! \since Crypto++ 5.7
+ Integer& operator^=(const Integer& t);
//! \brief Set this Integer to random integer
//! \param rng RandomNumberGenerator used to generate material
@@ -436,19 +471,19 @@ public:
//! \name UNARY OPERATORS
//@{
- //!
+ //! \brief Negation
bool operator!() const;
- //!
+ //! \brief Addition
Integer operator+() const {return *this;}
- //!
+ //! \brief Subtraction
Integer operator-() const;
- //!
+ //! \brief Pre-increment
Integer& operator++();
- //!
+ //! \brief Pre-decrement
Integer& operator--();
- //!
+ //! \brief Post-increment
Integer operator++(int) {Integer temp = *this; ++*this; return temp;}
- //!
+ //! \brief Post-decrement
Integer operator--(int) {Integer temp = *this; --*this; return temp;}
//@}
@@ -461,42 +496,82 @@ public:
//! \retval 1 if <tt>*this > a</tt>
int Compare(const Integer& a) const;
- //!
+ //! \brief Addition
Integer Plus(const Integer &b) const;
- //!
+ //! \brief Subtraction
Integer Minus(const Integer &b) const;
- //!
+ //! \brief Multiplication
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer Times(const Integer &b) const;
- //!
+ //! \brief Division
Integer DividedBy(const Integer &b) const;
- //!
+ //! \brief Remainder
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer Modulo(const Integer &b) const;
- //!
+ //! \brief Division
Integer DividedBy(word b) const;
- //!
+ //! \brief Remainder
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
word Modulo(word b) const;
- //!
+ //! \brief Bitwise AND
+ //! \param t the other Integer
+ //! \returns the result of <tt>*this & t</tt>
+ //! \details And() performs a bitwise AND on the operands. Missing bits are truncated
+ //! at the most significant bit positions, so the result is as small as the
+ //! smaller of the operands.
+ //! \details Internally, Crypto++ uses a sign-magnitude representation. The library
+ //! does not attempt to interpret bits, and the result is always POSITIVE. If needed,
+ //! the integer should be converted to a 2's compliment representation before performing
+ //! the operation.
+ //! \since Crypto++ 5.7
+ Integer And(const Integer&) const;
+
+ //! \brief Bitwise OR
+ //! \param t the other Integer
+ //! \returns the result of <tt>*this | t</tt>
+ //! \details Or() performs a bitwise OR on the operands. Missing bits are shifted in
+ //! at the most significant bit positions, so the result is as large as the
+ //! larger of the operands.
+ //! \details Internally, Crypto++ uses a sign-magnitude representation. The library
+ //! does not attempt to interpret bits, and the result is always POSITIVE. If needed,
+ //! the integer should be converted to a 2's compliment representation before performing
+ //! the operation.
+ //! \since Crypto++ 5.7
+ Integer Or(const Integer&) const;
+
+ //! \brief Bitwise XOR
+ //! \param t the other Integer
+ //! \returns the result of <tt>*this ^ t</tt>
+ //! \details Xor() performs a bitwise XOR on the operands. Missing bits are shifted in
+ //! at the most significant bit positions, so the result is as large as the
+ //! larger of the operands.
+ //! \details Internally, Crypto++ uses a sign-magnitude representation. The library
+ //! does not attempt to interpret bits, and the result is always POSITIVE. If needed,
+ //! the integer should be converted to a 2's compliment representation before performing
+ //! the operation.
+ //! \since Crypto++ 5.7
+ Integer Xor(const Integer&) const;
+
+ //! \brief Right-shift
Integer operator>>(size_t n) const {return Integer(*this)>>=n;}
- //!
+ //! \brief Left-shift
Integer operator<<(size_t n) const {return Integer(*this)<<=n;}
//@}
//! \name OTHER ARITHMETIC FUNCTIONS
//@{
- //!
+ //! \brief Retrieve the absolute value of this integer
Integer AbsoluteValue() const;
- //!
+ //! \brief Add this integer to itself
Integer Doubled() const {return Plus(*this);}
- //!
+ //! \brief Multiply this integer by itself
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer Squared() const {return Times(*this);}
- //! extract square root, if negative return 0, else return floor of square root
+ //! \brief Extract square root
+ //! \details if negative return 0, else return floor of square root
Integer SquareRoot() const;
- //! return whether this integer is a perfect square
+ //! \brief Determine whether this integer is a perfect square
bool IsSquare() const;
//! is 1 or -1
@@ -504,18 +579,17 @@ public:
//! return inverse if 1 or -1, otherwise return 0
Integer MultiplicativeInverse() const;
- //! calculate r and q such that (a == d*q + r) && (0 <= r < abs(d))
+ //! \brief calculate r and q such that (a == d*q + r) && (0 <= r < abs(d))
static void CRYPTOPP_API Divide(Integer &r, Integer &q, const Integer &a, const Integer &d);
- //! use a faster division algorithm when divisor is short
+ //! \brief use a faster division algorithm when divisor is short
static void CRYPTOPP_API Divide(word &r, Integer &q, const Integer &a, word d);
- //! returns same result as Divide(r, q, a, Power2(n)), but faster
+ //! \brief returns same result as Divide(r, q, a, Power2(n)), but faster
static void CRYPTOPP_API DivideByPowerOf2(Integer &r, Integer &q, const Integer &a, unsigned int n);
//! greatest common divisor
static Integer CRYPTOPP_API Gcd(const Integer &a, const Integer &n);
- //! calculate multiplicative inverse of *this mod n
- //! \sa a_times_b_mod_c() and a_exp_b_mod_c()
+ //! \brief calculate multiplicative inverse of *this mod n
Integer InverseMod(const Integer &n) const;
//!
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
@@ -570,36 +644,78 @@ private:
#endif
};
-//!
+//! \brief Comparison
inline bool operator==(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)==0;}
-//!
+//! \brief Comparison
inline bool operator!=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)!=0;}
-//!
+//! \brief Comparison
inline bool operator> (const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)> 0;}
-//!
+//! \brief Comparison
inline bool operator>=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)>=0;}
-//!
+//! \brief Comparison
inline bool operator< (const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)< 0;}
-//!
+//! \brief Comparison
inline bool operator<=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)<=0;}
-//!
+//! \brief Addition
inline CryptoPP::Integer operator+(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Plus(b);}
-//!
+//! \brief Subtraction
inline CryptoPP::Integer operator-(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Minus(b);}
-//!
+//! \brief Multiplication
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
inline CryptoPP::Integer operator*(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Times(b);}
-//!
+//! \brief Division
inline CryptoPP::Integer operator/(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.DividedBy(b);}
-//!
+//! \brief Remainder
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
inline CryptoPP::Integer operator%(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Modulo(b);}
-//!
+//! \brief Division
inline CryptoPP::Integer operator/(const CryptoPP::Integer &a, CryptoPP::word b) {return a.DividedBy(b);}
-//!
+//! \brief Remainder
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
inline CryptoPP::word operator%(const CryptoPP::Integer &a, CryptoPP::word b) {return a.Modulo(b);}
+//! \brief Bitwise AND
+//! \param a the first Integer
+//! \param b the second Integer
+//! \returns the result of a & b
+//! \details operator&() performs a bitwise AND on the operands. Missing bits are truncated
+//! at the most significant bit positions, so the result is as small as the
+//! smaller of the operands.
+//! \details Internally, Crypto++ uses a sign-magnitude representation. The library
+//! does not attempt to interpret bits, and the result is always POSITIVE. If needed,
+//! the integer should be converted to a 2's compliment representation before performing
+//! the operation.
+//! \since Crypto++ 5.7
+inline CryptoPP::Integer operator&(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.And(b);}
+
+//! \brief Bitwise OR
+//! \param a the first Integer
+//! \param b the second Integer
+//! \returns the result of a | b
+//! \details operator|() performs a bitwise OR on the operands. Missing bits are shifted in
+//! at the most significant bit positions, so the result is as large as the
+//! larger of the operands.
+//! \details Internally, Crypto++ uses a sign-magnitude representation. The library
+//! does not attempt to interpret bits, and the result is always POSITIVE. If needed,
+//! the integer should be converted to a 2's compliment representation before performing
+//! the operation.
+//! \since Crypto++ 5.7
+inline CryptoPP::Integer operator|(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Or(b);}
+
+//! \brief Bitwise XOR
+//! \param a the first Integer
+//! \param b the second Integer
+//! \returns the result of a ^ b
+//! \details operator^() performs a bitwise XOR on the operands. Missing bits are shifted
+//! in at the most significant bit positions, so the result is as large as the
+//! larger of the operands.
+//! \details Internally, Crypto++ uses a sign-magnitude representation. The library
+//! does not attempt to interpret bits, and the result is always POSITIVE. If needed,
+//! the integer should be converted to a 2's compliment representation before performing
+//! the operation.
+//! \since Crypto++ 5.7
+inline CryptoPP::Integer operator^(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Xor(b);}
+
NAMESPACE_END
#ifndef __BORLANDC__