📄 integer.h
字号:
#ifndef CRYPTOPP_INTEGER_H
#define CRYPTOPP_INTEGER_H
/** \file */
#include "cryptlib.h"
#include "secblock.h"
#include <iosfwd>
#include <algorithm>
#ifdef CRYPTOPP_X86ASM_AVAILABLE
#ifdef _M_IX86
#if (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 500)) || (defined(__ICL) && (__ICL >= 500))
#define SSE2_INTRINSICS_AVAILABLE
#define CRYPTOPP_MM_MALLOC_AVAILABLE
#elif defined(_MSC_VER)
// _mm_free seems to be the only way to tell if the Processor Pack is installed or not
#include <malloc.h>
#if defined(_mm_free)
#define SSE2_INTRINSICS_AVAILABLE
#define CRYPTOPP_MM_MALLOC_AVAILABLE
#endif
#endif
#endif
// SSE2 intrinsics work in GCC 3.3 or later
#if defined(__SSE2__) && (__GNUC__ > 3 || __GNUC_MINOR__ > 2)
#define SSE2_INTRINSICS_AVAILABLE
#endif
#endif
NAMESPACE_BEGIN(CryptoPP)
#if defined(SSE2_INTRINSICS_AVAILABLE)
template <class T>
class AlignedAllocator : public AllocatorBase<T>
{
public:
CRYPTOPP_INHERIT_ALLOCATOR_TYPES
pointer allocate(size_type n, const void *);
void deallocate(void *p, size_type n);
pointer reallocate(T *p, size_type oldSize, size_type newSize, bool preserve)
{
return StandardReallocate(*this, p, oldSize, newSize, preserve);
}
#if !(defined(CRYPTOPP_MALLOC_ALIGNMENT_IS_16) || defined(CRYPTOPP_MEMALIGN_AVAILABLE) || defined(CRYPTOPP_MM_MALLOC_AVAILABLE))
#define CRYPTOPP_NO_ALIGNED_ALLOC
AlignedAllocator() : m_pBlock(NULL) {}
protected:
void *m_pBlock;
#endif
};
#ifdef CRYPTOPP_IMPORTS
CRYPTOPP_DLL_TEMPLATE_CLASS AlignedAllocator<word>;
#endif
typedef SecBlock<word, AlignedAllocator<word> > SecAlignedWordBlock;
#else
typedef SecWordBlock SecAlignedWordBlock;
#endif
void CRYPTOPP_DLL CRYPTOPP_API DisableSSE2();
struct InitializeInteger // used to initialize static variables
{
InitializeInteger();
};
//! multiple precision integer and basic arithmetics
/*! This class can represent positive and negative integers
with absolute value less than (256**sizeof(word)) ** (256**sizeof(int)).
\nosubgrouping
*/
class CRYPTOPP_DLL Integer : private InitializeInteger, public ASN1Object
{
public:
//! \name ENUMS, EXCEPTIONS, and TYPEDEFS
//@{
//! division by zero exception
class DivideByZero : public Exception
{
public:
DivideByZero() : Exception(OTHER_ERROR, "Integer: division by zero") {}
};
//!
class RandomNumberNotFound : public Exception
{
public:
RandomNumberNotFound() : Exception(OTHER_ERROR, "Integer: no integer satisfies the given parameters") {}
};
//!
enum Sign {POSITIVE=0, NEGATIVE=1};
//!
enum Signedness {
//!
UNSIGNED,
//!
SIGNED};
//!
enum RandomNumberType {
//!
ANY,
//!
PRIME};
//@}
//! \name CREATORS
//@{
//! creates the zero integer
Integer();
//! copy constructor
Integer(const Integer& t);
//! convert from signed long
Integer(signed long value);
//! convert from lword
Integer(Sign s, lword value);
//! convert from two words
Integer(Sign s, word highWord, word lowWord);
//! convert from string
/*! str can be in base 2, 8, 10, or 16. Base is determined by a
case insensitive suffix of 'h', 'o', or 'b'. No suffix means base 10.
*/
explicit Integer(const char *str);
explicit Integer(const wchar_t *str);
//! convert from big-endian byte array
Integer(const byte *encodedInteger, size_t byteCount, Signedness s=UNSIGNED);
//! convert from big-endian form stored in a BufferedTransformation
Integer(BufferedTransformation &bt, size_t byteCount, Signedness s=UNSIGNED);
//! convert from BER encoded byte array stored in a BufferedTransformation object
explicit Integer(BufferedTransformation &bt);
//! create a random integer
/*! The random integer created is uniformly distributed over [0, 2**bitcount). */
Integer(RandomNumberGenerator &rng, size_t bitcount);
//! avoid calling constructors for these frequently used integers
static const Integer & CRYPTOPP_API Zero();
//! avoid calling constructors for these frequently used integers
static const Integer & CRYPTOPP_API One();
//! avoid calling constructors for these frequently used integers
static const Integer & CRYPTOPP_API Two();
//! create a random integer of special type
/*! Ideally, the random integer created should be uniformly distributed
over {x | min <= x <= max and x is of rnType and x % mod == equiv}.
However the actual distribution may not be uniform because sequential
search is used to find an appropriate number from a random starting
point.
May return (with very small probability) a pseudoprime when a prime
is requested and max > lastSmallPrime*lastSmallPrime (lastSmallPrime
is declared in nbtheory.h).
\throw RandomNumberNotFound if the set is empty.
*/
Integer(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType=ANY, const Integer &equiv=Zero(), const Integer &mod=One());
//! return the integer 2**e
static Integer CRYPTOPP_API Power2(size_t e);
//@}
//! \name ENCODE/DECODE
//@{
//! minimum number of bytes to encode this integer
/*! MinEncodedSize of 0 is 1 */
size_t MinEncodedSize(Signedness=UNSIGNED) const;
//! encode in big-endian format
/*! unsigned means encode absolute value, signed means encode two's complement if negative.
if outputLen < MinEncodedSize, the most significant bytes will be dropped
if outputLen > MinEncodedSize, the most significant bytes will be padded
*/
void Encode(byte *output, size_t outputLen, Signedness=UNSIGNED) const;
//!
void Encode(BufferedTransformation &bt, size_t outputLen, Signedness=UNSIGNED) const;
//! encode using Distinguished Encoding Rules, put result into a BufferedTransformation object
void DEREncode(BufferedTransformation &bt) const;
//! encode absolute value as big-endian octet string
void DEREncodeAsOctetString(BufferedTransformation &bt, size_t length) const;
//! encode absolute value in OpenPGP format, return length of output
size_t OpenPGPEncode(byte *output, size_t bufferSize) const;
//! encode absolute value in OpenPGP format, put result into a BufferedTransformation object
size_t OpenPGPEncode(BufferedTransformation &bt) const;
//!
void Decode(const byte *input, size_t inputLen, Signedness=UNSIGNED);
//!
//* Precondition: bt.MaxRetrievable() >= inputLen
void Decode(BufferedTransformation &bt, size_t inputLen, Signedness=UNSIGNED);
//!
void BERDecode(const byte *input, size_t inputLen);
//!
void BERDecode(BufferedTransformation &bt);
//! decode nonnegative value as big-endian octet string
void BERDecodeAsOctetString(BufferedTransformation &bt, size_t length);
class OpenPGPDecodeErr : public Exception
{
public:
OpenPGPDecodeErr() : Exception(INVALID_DATA_FORMAT, "OpenPGP decode error") {}
};
//!
void OpenPGPDecode(const byte *input, size_t inputLen);
//!
void OpenPGPDecode(BufferedTransformation &bt);
//@}
//! \name ACCESSORS
//@{
//! return true if *this can be represented as a signed long
bool IsConvertableToLong() const;
//! return equivalent signed long if possible, otherwise undefined
signed long ConvertToLong() const;
//! number of significant bits = floor(log2(abs(*this))) + 1
unsigned int BitCount() const;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -