Add Integer bitwise AND, OR and XOR (Issue 336)
parent
6d898321e4
commit
16ffe513a4
|
|
@ -592,7 +592,7 @@ public:
|
||||||
{SetKeyWithIV(key, length, iv, IVSize());}
|
{SetKeyWithIV(key, length, iv, IVSize());}
|
||||||
|
|
||||||
//! \brief Secure IVs requirements as enumerated values.
|
//! \brief Secure IVs requirements as enumerated values.
|
||||||
//! \details Provides secure IV requirements as a monotomically increasing enumerated values. Requirements can be
|
//! \details Provides secure IV requirements as a monotonically increasing enumerated values. Requirements can be
|
||||||
//! compared using less than (<) and greater than (>). For example, <tt>UNIQUE_IV < RANDOM_IV</tt>
|
//! compared using less than (<) and greater than (>). For example, <tt>UNIQUE_IV < RANDOM_IV</tt>
|
||||||
//! and <tt>UNPREDICTABLE_RANDOM_IV > RANDOM_IV</tt>.
|
//! and <tt>UNPREDICTABLE_RANDOM_IV > RANDOM_IV</tt>.
|
||||||
//! \sa IsResynchronizable(), CanUseRandomIVs(), CanUsePredictableIVs(), CanUseStructuredIVs()
|
//! \sa IsResynchronizable(), CanUseRandomIVs(), CanUsePredictableIVs(), CanUseStructuredIVs()
|
||||||
|
|
|
||||||
136
integer.cpp
136
integer.cpp
|
|
@ -3738,6 +3738,84 @@ Integer& Integer::operator--()
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is a bit operation. We set sign to POSITIVE, so there's no need to
|
||||||
|
// worry about negative zero. Also see http://stackoverflow.com/q/11644362.
|
||||||
|
Integer Integer::And(const Integer& t) const
|
||||||
|
{
|
||||||
|
if (this == &t)
|
||||||
|
{
|
||||||
|
return AbsoluteValue();
|
||||||
|
}
|
||||||
|
else if (WordCount() >= t.WordCount())
|
||||||
|
{
|
||||||
|
Integer result(t);
|
||||||
|
AndWords(result.reg, reg, t.WordCount());
|
||||||
|
|
||||||
|
result.sign = POSITIVE;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else // WordCount() < t.WordCount()
|
||||||
|
{
|
||||||
|
Integer result(*this);
|
||||||
|
AndWords(result.reg, t.reg, WordCount());
|
||||||
|
|
||||||
|
result.sign = POSITIVE;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a bit operation. We set sign to POSITIVE, so there's no need to
|
||||||
|
// worry about negative zero. Also see http://stackoverflow.com/q/11644362.
|
||||||
|
Integer Integer::Or(const Integer& t) const
|
||||||
|
{
|
||||||
|
if (this == &t)
|
||||||
|
{
|
||||||
|
return AbsoluteValue();
|
||||||
|
}
|
||||||
|
else if (WordCount() >= t.WordCount())
|
||||||
|
{
|
||||||
|
Integer result(*this);
|
||||||
|
OrWords(result.reg, t.reg, t.WordCount());
|
||||||
|
|
||||||
|
result.sign = POSITIVE;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else // WordCount() < t.WordCount()
|
||||||
|
{
|
||||||
|
Integer result(t);
|
||||||
|
OrWords(result.reg, reg, WordCount());
|
||||||
|
|
||||||
|
result.sign = POSITIVE;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a bit operation. We set sign to POSITIVE, so there's no need to
|
||||||
|
// worry about negative zero. Also see http://stackoverflow.com/q/11644362.
|
||||||
|
Integer Integer::Xor(const Integer& t) const
|
||||||
|
{
|
||||||
|
if (this == &t)
|
||||||
|
{
|
||||||
|
return Integer::Zero();
|
||||||
|
}
|
||||||
|
else if (WordCount() >= t.WordCount())
|
||||||
|
{
|
||||||
|
Integer result(*this);
|
||||||
|
XorWords(result.reg, t.reg, t.WordCount());
|
||||||
|
|
||||||
|
result.sign = POSITIVE;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else // WordCount() < t.WordCount()
|
||||||
|
{
|
||||||
|
Integer result(t);
|
||||||
|
XorWords(result.reg, reg, WordCount());
|
||||||
|
|
||||||
|
result.sign = POSITIVE;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PositiveAdd(Integer &sum, const Integer &a, const Integer& b)
|
void PositiveAdd(Integer &sum, const Integer &a, const Integer& b)
|
||||||
{
|
{
|
||||||
// Profiling tells us the original second Else If was dominant, so it was promoted to the first If statement.
|
// Profiling tells us the original second Else If was dominant, so it was promoted to the first If statement.
|
||||||
|
|
@ -3932,6 +4010,64 @@ Integer& Integer::operator>>=(size_t n)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Integer& Integer::operator&=(const Integer& t)
|
||||||
|
{
|
||||||
|
if (this != &t)
|
||||||
|
{
|
||||||
|
const size_t size = STDMIN(WordCount(), t.WordCount());
|
||||||
|
reg.resize(size);
|
||||||
|
AndWords(reg, t.reg, size);
|
||||||
|
}
|
||||||
|
sign = POSITIVE;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer& Integer::operator|=(const Integer& t)
|
||||||
|
{
|
||||||
|
if (this != &t)
|
||||||
|
{
|
||||||
|
if (WordCount() >= t.WordCount())
|
||||||
|
{
|
||||||
|
OrWords(reg, t.reg, t.WordCount());
|
||||||
|
}
|
||||||
|
else // WordCount() < t.WordCount()
|
||||||
|
{
|
||||||
|
const size_t head = WordCount();
|
||||||
|
const size_t tail = t.WordCount() - WordCount();
|
||||||
|
reg.resize(head+tail);
|
||||||
|
OrWords(reg, t.reg, head);
|
||||||
|
CopyWords(reg+head,t.reg+head,tail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sign = POSITIVE;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer& Integer::operator^=(const Integer& t)
|
||||||
|
{
|
||||||
|
if (this == &t)
|
||||||
|
{
|
||||||
|
*this = Zero();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (WordCount() >= t.WordCount())
|
||||||
|
{
|
||||||
|
XorWords(reg, t.reg, t.WordCount());
|
||||||
|
}
|
||||||
|
else // WordCount() < t.WordCount()
|
||||||
|
{
|
||||||
|
const size_t head = WordCount();
|
||||||
|
const size_t tail = t.WordCount() - WordCount();
|
||||||
|
reg.resize(head+tail);
|
||||||
|
XorWords(reg, t.reg, head);
|
||||||
|
CopyWords(reg+head,t.reg+head,tail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sign = POSITIVE;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
void PositiveMultiply(Integer &product, const Integer &a, const Integer &b)
|
void PositiveMultiply(Integer &product, const Integer &a, const Integer &b)
|
||||||
{
|
{
|
||||||
size_t aSize = RoundupSize(a.WordCount());
|
size_t aSize = RoundupSize(a.WordCount());
|
||||||
|
|
|
||||||
244
integer.h
244
integer.h
|
|
@ -6,8 +6,9 @@
|
||||||
//! with absolute value less than (256**sizeof(word))<sup>(256**sizeof(int))</sup>.
|
//! 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
|
//! \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
|
//! 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
|
//! used to hold the representation. The second is a Sign (an enumeration), and it is
|
||||||
//! the sign of the Integer.
|
//! used to track the sign of the Integer.
|
||||||
|
//! \since Crypto++ 1.0
|
||||||
|
|
||||||
#ifndef CRYPTOPP_INTEGER_H
|
#ifndef CRYPTOPP_INTEGER_H
|
||||||
#define CRYPTOPP_INTEGER_H
|
#define CRYPTOPP_INTEGER_H
|
||||||
|
|
@ -21,26 +22,23 @@
|
||||||
NAMESPACE_BEGIN(CryptoPP)
|
NAMESPACE_BEGIN(CryptoPP)
|
||||||
|
|
||||||
//! \struct InitializeInteger
|
//! \struct InitializeInteger
|
||||||
//! Performs static intialization of the Integer class
|
//! \brief Performs static intialization of the Integer class
|
||||||
struct InitializeInteger
|
struct InitializeInteger
|
||||||
{
|
{
|
||||||
InitializeInteger();
|
InitializeInteger();
|
||||||
};
|
};
|
||||||
|
|
||||||
// http://github.com/weidai11/cryptopp/issues/256
|
// Always align, http://github.com/weidai11/cryptopp/issues/256
|
||||||
#if defined(CRYPTOPP_WORD128_AVAILABLE)
|
|
||||||
typedef SecBlock<word, AllocatorWithCleanup<word, true> > IntegerSecBlock;
|
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
|
//! \brief Multiple precision integer with arithmetic operations
|
||||||
//! \details The Integer class can represent positive and negative integers
|
//! \details The Integer class can represent positive and negative integers
|
||||||
//! with absolute value less than (256**sizeof(word))<sup>(256**sizeof(int))</sup>.
|
//! 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
|
//! \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
|
//! 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
|
//! used to hold the representation. The second is a Sign (an enumeration), and it is
|
||||||
//! the sign of the Integer.
|
//! used to track the sign of the Integer.
|
||||||
|
//! \since Crypto++ 1.0
|
||||||
//! \nosubgrouping
|
//! \nosubgrouping
|
||||||
class CRYPTOPP_DLL Integer : private InitializeInteger, public ASN1Object
|
class CRYPTOPP_DLL Integer : private InitializeInteger, public ASN1Object
|
||||||
{
|
{
|
||||||
|
|
@ -65,7 +63,7 @@ public:
|
||||||
//! \enum Sign
|
//! \enum Sign
|
||||||
//! \brief Used internally to represent the integer
|
//! \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.
|
//! \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 {
|
enum Sign {
|
||||||
//! \brief the value is positive or 0
|
//! \brief the value is positive or 0
|
||||||
POSITIVE=0,
|
POSITIVE=0,
|
||||||
|
|
@ -198,7 +196,7 @@ public:
|
||||||
|
|
||||||
//! \name ENCODE/DECODE
|
//! \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
|
//! \param sign enumeration indicating Signedness
|
||||||
//! \note The MinEncodedSize() of 0 is 1.
|
//! \note The MinEncodedSize() of 0 is 1.
|
||||||
size_t MinEncodedSize(Signedness sign=UNSIGNED) const;
|
size_t MinEncodedSize(Signedness sign=UNSIGNED) const;
|
||||||
|
|
@ -227,7 +225,7 @@ public:
|
||||||
//! The result is placed into a BufferedTransformation object
|
//! The result is placed into a BufferedTransformation object
|
||||||
void DEREncode(BufferedTransformation &bt) const;
|
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 bt BufferedTransformation object
|
||||||
//! \param length the number of mytes to decode
|
//! \param length the number of mytes to decode
|
||||||
void DEREncodeAsOctetString(BufferedTransformation &bt, size_t length) const;
|
void DEREncodeAsOctetString(BufferedTransformation &bt, size_t length) const;
|
||||||
|
|
@ -349,31 +347,68 @@ public:
|
||||||
|
|
||||||
//! \name MANIPULATORS
|
//! \name MANIPULATORS
|
||||||
//@{
|
//@{
|
||||||
//!
|
//! \brief Assignment
|
||||||
Integer& operator=(const Integer& t);
|
Integer& operator=(const Integer& t);
|
||||||
|
|
||||||
//!
|
//! \brief Addition Assignment
|
||||||
Integer& operator+=(const Integer& t);
|
Integer& operator+=(const Integer& t);
|
||||||
//!
|
//! \brief Subtraction Assignment
|
||||||
Integer& operator-=(const Integer& t);
|
Integer& operator-=(const Integer& t);
|
||||||
//!
|
//! \brief Multiplication Assignment
|
||||||
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
|
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
|
||||||
Integer& operator*=(const Integer& t) {return *this = Times(t);}
|
Integer& operator*=(const Integer& t) {return *this = Times(t);}
|
||||||
//!
|
//! \brief Division Assignment
|
||||||
Integer& operator/=(const Integer& t) {return *this = DividedBy(t);}
|
Integer& operator/=(const Integer& t) {return *this = DividedBy(t);}
|
||||||
//!
|
//! \brief Remainder Assignment
|
||||||
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
|
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
|
||||||
Integer& operator%=(const Integer& t) {return *this = Modulo(t);}
|
Integer& operator%=(const Integer& t) {return *this = Modulo(t);}
|
||||||
//!
|
//! \brief Division Assignment
|
||||||
Integer& operator/=(word t) {return *this = DividedBy(t);}
|
Integer& operator/=(word t) {return *this = DividedBy(t);}
|
||||||
//!
|
//! \brief Remainder Assignment
|
||||||
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
|
//! \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%=(word t) {return *this = Integer(POSITIVE, 0, Modulo(t));}
|
||||||
|
|
||||||
//!
|
//! \brief Left-shift Assignment
|
||||||
Integer& operator<<=(size_t);
|
Integer& operator<<=(size_t n);
|
||||||
//!
|
//! \brief Right-shift Assignment
|
||||||
Integer& operator>>=(size_t);
|
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
|
//! \brief Set this Integer to random integer
|
||||||
//! \param rng RandomNumberGenerator used to generate material
|
//! \param rng RandomNumberGenerator used to generate material
|
||||||
|
|
@ -436,19 +471,19 @@ public:
|
||||||
|
|
||||||
//! \name UNARY OPERATORS
|
//! \name UNARY OPERATORS
|
||||||
//@{
|
//@{
|
||||||
//!
|
//! \brief Negation
|
||||||
bool operator!() const;
|
bool operator!() const;
|
||||||
//!
|
//! \brief Addition
|
||||||
Integer operator+() const {return *this;}
|
Integer operator+() const {return *this;}
|
||||||
//!
|
//! \brief Subtraction
|
||||||
Integer operator-() const;
|
Integer operator-() const;
|
||||||
//!
|
//! \brief Pre-increment
|
||||||
Integer& operator++();
|
Integer& operator++();
|
||||||
//!
|
//! \brief Pre-decrement
|
||||||
Integer& operator--();
|
Integer& operator--();
|
||||||
//!
|
//! \brief Post-increment
|
||||||
Integer operator++(int) {Integer temp = *this; ++*this; return temp;}
|
Integer operator++(int) {Integer temp = *this; ++*this; return temp;}
|
||||||
//!
|
//! \brief Post-decrement
|
||||||
Integer operator--(int) {Integer temp = *this; --*this; return temp;}
|
Integer operator--(int) {Integer temp = *this; --*this; return temp;}
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
|
|
@ -461,42 +496,82 @@ public:
|
||||||
//! \retval 1 if <tt>*this > a</tt>
|
//! \retval 1 if <tt>*this > a</tt>
|
||||||
int Compare(const Integer& a) const;
|
int Compare(const Integer& a) const;
|
||||||
|
|
||||||
//!
|
//! \brief Addition
|
||||||
Integer Plus(const Integer &b) const;
|
Integer Plus(const Integer &b) const;
|
||||||
//!
|
//! \brief Subtraction
|
||||||
Integer Minus(const Integer &b) const;
|
Integer Minus(const Integer &b) const;
|
||||||
//!
|
//! \brief Multiplication
|
||||||
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
|
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
|
||||||
Integer Times(const Integer &b) const;
|
Integer Times(const Integer &b) const;
|
||||||
//!
|
//! \brief Division
|
||||||
Integer DividedBy(const Integer &b) const;
|
Integer DividedBy(const Integer &b) const;
|
||||||
//!
|
//! \brief Remainder
|
||||||
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
|
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
|
||||||
Integer Modulo(const Integer &b) const;
|
Integer Modulo(const Integer &b) const;
|
||||||
//!
|
//! \brief Division
|
||||||
Integer DividedBy(word b) const;
|
Integer DividedBy(word b) const;
|
||||||
//!
|
//! \brief Remainder
|
||||||
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
|
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
|
||||||
word Modulo(word b) const;
|
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;}
|
Integer operator>>(size_t n) const {return Integer(*this)>>=n;}
|
||||||
//!
|
//! \brief Left-shift
|
||||||
Integer operator<<(size_t n) const {return Integer(*this)<<=n;}
|
Integer operator<<(size_t n) const {return Integer(*this)<<=n;}
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//! \name OTHER ARITHMETIC FUNCTIONS
|
//! \name OTHER ARITHMETIC FUNCTIONS
|
||||||
//@{
|
//@{
|
||||||
//!
|
//! \brief Retrieve the absolute value of this integer
|
||||||
Integer AbsoluteValue() const;
|
Integer AbsoluteValue() const;
|
||||||
//!
|
//! \brief Add this integer to itself
|
||||||
Integer Doubled() const {return Plus(*this);}
|
Integer Doubled() const {return Plus(*this);}
|
||||||
//!
|
//! \brief Multiply this integer by itself
|
||||||
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
|
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
|
||||||
Integer Squared() const {return Times(*this);}
|
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;
|
Integer SquareRoot() const;
|
||||||
//! return whether this integer is a perfect square
|
//! \brief Determine whether this integer is a perfect square
|
||||||
bool IsSquare() const;
|
bool IsSquare() const;
|
||||||
|
|
||||||
//! is 1 or -1
|
//! is 1 or -1
|
||||||
|
|
@ -504,18 +579,17 @@ public:
|
||||||
//! return inverse if 1 or -1, otherwise return 0
|
//! return inverse if 1 or -1, otherwise return 0
|
||||||
Integer MultiplicativeInverse() const;
|
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);
|
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);
|
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);
|
static void CRYPTOPP_API DivideByPowerOf2(Integer &r, Integer &q, const Integer &a, unsigned int n);
|
||||||
|
|
||||||
//! greatest common divisor
|
//! greatest common divisor
|
||||||
static Integer CRYPTOPP_API Gcd(const Integer &a, const Integer &n);
|
static Integer CRYPTOPP_API Gcd(const Integer &a, const Integer &n);
|
||||||
//! calculate multiplicative inverse of *this mod n
|
//! \brief calculate multiplicative inverse of *this mod n
|
||||||
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
|
|
||||||
Integer InverseMod(const Integer &n) const;
|
Integer InverseMod(const Integer &n) const;
|
||||||
//!
|
//!
|
||||||
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
|
//! \sa a_times_b_mod_c() and a_exp_b_mod_c()
|
||||||
|
|
@ -570,36 +644,78 @@ private:
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
//!
|
//! \brief Comparison
|
||||||
inline bool operator==(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)==0;}
|
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;}
|
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;}
|
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;}
|
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;}
|
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;}
|
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);}
|
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);}
|
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()
|
//! \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);}
|
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);}
|
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()
|
//! \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);}
|
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);}
|
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()
|
//! \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);}
|
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
|
NAMESPACE_END
|
||||||
|
|
||||||
#ifndef __BORLANDC__
|
#ifndef __BORLANDC__
|
||||||
|
|
|
||||||
12
words.h
12
words.h
|
|
@ -53,6 +53,18 @@ inline void AndWords(word *r, const word *a, size_t n)
|
||||||
r[i] &= a[i];
|
r[i] &= a[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void OrWords(word *r, const word *a, size_t n)
|
||||||
|
{
|
||||||
|
for (size_t i=0; i<n; i++)
|
||||||
|
r[i] |= a[i];
|
||||||
|
}
|
||||||
|
|
||||||
inline word ShiftWordsLeftByBits(word *r, size_t n, unsigned int shiftBits)
|
inline word ShiftWordsLeftByBits(word *r, size_t n, unsigned int shiftBits)
|
||||||
{
|
{
|
||||||
CRYPTOPP_ASSERT (shiftBits<WORD_BITS);
|
CRYPTOPP_ASSERT (shiftBits<WORD_BITS);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue