fix potential threading problem with initialization of static objects

pull/2/head
weidai 2003-07-29 01:18:33 +00:00
parent 259ee22eba
commit 9c5c4769a9
15 changed files with 169 additions and 120 deletions

2
dh.h
View File

@ -78,7 +78,7 @@ public:
private: private:
const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const
{static KeyAgreementAlgorithm a; return a;} {return Singleton<KeyAgreementAlgorithm>().Ref();}
DL_GroupParameters<Element> & AccessAbstractGroupParameters() DL_GroupParameters<Element> & AccessAbstractGroupParameters()
{return m_groupParameters;} {return m_groupParameters;}

View File

@ -171,8 +171,7 @@ bool EC2N::Equal(const Point &P, const Point &Q) const
const EC2N::Point& EC2N::Identity() const const EC2N::Point& EC2N::Identity() const
{ {
static const Point zero; return Singleton<Point>().Ref();
return zero;
} }
const EC2N::Point& EC2N::Inverse(const Point &P) const const EC2N::Point& EC2N::Inverse(const Point &P) const

View File

@ -195,8 +195,7 @@ bool ECP::Equal(const Point &P, const Point &Q) const
const ECP::Point& ECP::Identity() const const ECP::Point& ECP::Identity() const
{ {
static const Point zero; return Singleton<Point>().Ref();
return zero;
} }
const ECP::Point& ECP::Inverse(const Point &P) const const ECP::Point& ECP::Inverse(const Point &P) const

View File

@ -111,16 +111,23 @@ PolynomialMod2 PolynomialMod2::Pentanomial(unsigned t0, unsigned t1, unsigned t2
return r; return r;
} }
template <word i>
struct NewPolynomialMod2
{
PolynomialMod2 * operator()() const
{
return new PolynomialMod2(i);
}
};
const PolynomialMod2 &PolynomialMod2::Zero() const PolynomialMod2 &PolynomialMod2::Zero()
{ {
static const PolynomialMod2 zero; return Singleton<PolynomialMod2>().Ref();
return zero;
} }
const PolynomialMod2 &PolynomialMod2::One() const PolynomialMod2 &PolynomialMod2::One()
{ {
static const PolynomialMod2 one = 1; return Singleton<PolynomialMod2, NewPolynomialMod2<1> >().Ref();
return one;
} }
void PolynomialMod2::Decode(const byte *input, unsigned int inputLen) void PolynomialMod2::Decode(const byte *input, unsigned int inputLen)

View File

@ -40,7 +40,7 @@ word64 Timer::GetCurrentTimerValue()
word64 Timer::TicksPerSecond() word64 Timer::TicksPerSecond()
{ {
#if defined(CRYPTOPP_WIN32_AVAILABLE) #if defined(CRYPTOPP_WIN32_AVAILABLE)
static LARGE_INTEGER freq; static LARGE_INTEGER freq = {0};
if (freq.QuadPart == 0) if (freq.QuadPart == 0)
{ {
if (!QueryPerformanceFrequency(&freq)) if (!QueryPerformanceFrequency(&freq))

View File

@ -2834,22 +2834,28 @@ Integer Integer::Power2(unsigned int e)
return r; return r;
} }
template <long i>
struct NewInteger
{
Integer * operator()() const
{
return new Integer(i);
}
};
const Integer &Integer::Zero() const Integer &Integer::Zero()
{ {
static const Integer zero; return Singleton<Integer>().Ref();
return zero;
} }
const Integer &Integer::One() const Integer &Integer::One()
{ {
static const Integer one(1,2); return Singleton<Integer, NewInteger<1> >().Ref();
return one;
} }
const Integer &Integer::Two() const Integer &Integer::Two()
{ {
static const Integer two(2,2); return Singleton<Integer, NewInteger<2> >().Ref();
return two;
} }
bool Integer::operator!() const bool Integer::operator!() const

42
misc.h
View File

@ -209,29 +209,57 @@ inline CipherDir GetCipherDir(const T &obj)
return obj.IsForwardTransformation() ? ENCRYPTION : DECRYPTION; return obj.IsForwardTransformation() ? ENCRYPTION : DECRYPTION;
} }
template <class T>
struct NewObject
{
T* operator()() const {return new T;}
};
// This function safely initializes a static object in a multithreaded environment without using locks. // This function safely initializes a static object in a multithreaded environment without using locks.
// It may leak memory when two threads try to initialize the static object at the same time // It may leak memory when two threads try to initialize the static object at the same time
// but this should be acceptable since each static object is only initialized once per session. // but this should be acceptable since each static object is only initialized once per session.
template <class T, class F> template <class T, class F = NewObject<T>, int instance=0>
T & StaticObject(F NewT, T *dummy=NULL) class Singleton
{ {
static member_ptr<T> s_pObject; public:
Singleton(F objectFactory = F()) : m_objectFactory(objectFactory) {}
// VC60 workaround: use "..." to prevent this function from being inlined
const T & Ref(...) const;
private:
F m_objectFactory;
};
template <class T, class F, int instance>
const T & Singleton<T, F, instance>::Ref(...) const
{
static simple_ptr<T> s_pObject;
static char s_objectState = 0; static char s_objectState = 0;
retry:
switch (s_objectState) switch (s_objectState)
{ {
case 0: case 0:
s_objectState = 1; s_objectState = 1;
s_pObject.reset(NewT()); try
{
s_pObject.m_p = m_objectFactory();
}
catch(...)
{
s_objectState = 0;
throw;
}
s_objectState = 2; s_objectState = 2;
break; break;
case 1: case 1:
while (s_objectState == 1) {} goto retry;
default: default:
break; break;
} }
return *s_pObject; return *s_pObject.m_p;
}; }
// ************** rotate functions *************** // ************** rotate functions ***************

View File

@ -15,36 +15,39 @@ NAMESPACE_BEGIN(CryptoPP)
const word s_lastSmallPrime = 32719; const word s_lastSmallPrime = 32719;
std::vector<word16> * NewPrimeTable() struct NewPrimeTable
{ {
const unsigned int maxPrimeTableSize = 3511; std::vector<word16> * operator()() const
std::auto_ptr<std::vector<word16> > pPrimeTable(new std::vector<word16>);
std::vector<word16> &primeTable = *pPrimeTable;
primeTable.reserve(maxPrimeTableSize);
primeTable.push_back(2);
unsigned int testEntriesEnd = 1;
for (unsigned int p=3; p<=s_lastSmallPrime; p+=2)
{ {
unsigned int j; const unsigned int maxPrimeTableSize = 3511;
for (j=1; j<testEntriesEnd; j++)
if (p%primeTable[j] == 0)
break;
if (j == testEntriesEnd)
{
primeTable.push_back(p);
testEntriesEnd = STDMIN((size_t)54U, primeTable.size());
}
}
return pPrimeTable.release(); std::auto_ptr<std::vector<word16> > pPrimeTable(new std::vector<word16>);
} std::vector<word16> &primeTable = *pPrimeTable;
primeTable.reserve(maxPrimeTableSize);
primeTable.push_back(2);
unsigned int testEntriesEnd = 1;
for (unsigned int p=3; p<=s_lastSmallPrime; p+=2)
{
unsigned int j;
for (j=1; j<testEntriesEnd; j++)
if (p%primeTable[j] == 0)
break;
if (j == testEntriesEnd)
{
primeTable.push_back(p);
testEntriesEnd = STDMIN((size_t)54U, primeTable.size());
}
}
return pPrimeTable.release();
}
};
const word16 * GetPrimeTable(unsigned int &size) const word16 * GetPrimeTable(unsigned int &size)
{ {
std::vector<word16> &primeTable = StaticObject<std::vector<word16> >(&NewPrimeTable); const std::vector<word16> &primeTable = Singleton<std::vector<word16>, NewPrimeTable>().Ref();
size = primeTable.size(); size = primeTable.size();
return &primeTable[0]; return &primeTable[0];
} }
@ -218,13 +221,19 @@ bool IsStrongLucasProbablePrime(const Integer &n)
return false; return false;
} }
struct NewLastSmallPrimeSquared
{
Integer * operator()() const
{
return new Integer(Integer(s_lastSmallPrime).Squared());
}
};
bool IsPrime(const Integer &p) bool IsPrime(const Integer &p)
{ {
static const Integer lastSmallPrimeSquared = Integer(s_lastSmallPrime).Squared();
if (p <= s_lastSmallPrime) if (p <= s_lastSmallPrime)
return IsSmallPrime(p); return IsSmallPrime(p);
else if (p <= lastSmallPrimeSquared) else if (p <= Singleton<Integer, NewLastSmallPrimeSquared>().Ref())
return SmallDivisorsTest(p); return SmallDivisorsTest(p);
else else
return SmallDivisorsTest(p) && IsStrongProbablePrime(p, 3) && IsStrongLucasProbablePrime(p); return SmallDivisorsTest(p) && IsStrongProbablePrime(p, 3) && IsStrongLucasProbablePrime(p);

View File

@ -565,15 +565,13 @@ Element BulkPolynomialInterpolateAt(const Ring &ring, const Element y[], const E
template <class T, int instance> template <class T, int instance>
const PolynomialOverFixedRing<T, instance> &PolynomialOverFixedRing<T, instance>::Zero() const PolynomialOverFixedRing<T, instance> &PolynomialOverFixedRing<T, instance>::Zero()
{ {
static const PolynomialOverFixedRing<T, instance> zero; return Singleton<ThisType>().Ref();
return zero;
} }
template <class T, int instance> template <class T, int instance>
const PolynomialOverFixedRing<T, instance> &PolynomialOverFixedRing<T, instance>::One() const PolynomialOverFixedRing<T, instance> &PolynomialOverFixedRing<T, instance>::One()
{ {
static const PolynomialOverFixedRing<T, instance> one = fixedRing.MultiplicativeIdentity(); return Singleton<ThisType, NewOnePolynomial>().Ref();
return one;
} }
NAMESPACE_END NAMESPACE_END

View File

@ -170,7 +170,7 @@ public:
//! \name CREATORS //! \name CREATORS
//@{ //@{
//! creates the zero polynomial //! creates the zero polynomial
PolynomialOverFixedRing(unsigned int count = 0) : B(fixedRing, count) {} PolynomialOverFixedRing(unsigned int count = 0) : B(ms_fixedRing, count) {}
//! copy constructor //! copy constructor
PolynomialOverFixedRing(const ThisType &t) : B(t) {} PolynomialOverFixedRing(const ThisType &t) : B(t) {}
@ -185,7 +185,7 @@ public:
: B(first, last) {} : B(first, last) {}
//! convert from string //! convert from string
explicit PolynomialOverFixedRing(const char *str) : B(str, fixedRing) {} explicit PolynomialOverFixedRing(const char *str) : B(str, ms_fixedRing) {}
//! convert from big-endian byte array //! convert from big-endian byte array
PolynomialOverFixedRing(const byte *encodedPoly, unsigned int byteCount) : B(encodedPoly, byteCount) {} PolynomialOverFixedRing(const byte *encodedPoly, unsigned int byteCount) : B(encodedPoly, byteCount) {}
@ -197,7 +197,7 @@ public:
explicit PolynomialOverFixedRing(BufferedTransformation &bt) : B(bt) {} explicit PolynomialOverFixedRing(BufferedTransformation &bt) : B(bt) {}
//! create a random PolynomialOverFixedRing //! create a random PolynomialOverFixedRing
PolynomialOverFixedRing(RandomNumberGenerator &rng, const RandomizationParameter &parameter) : B(rng, parameter, fixedRing) {} PolynomialOverFixedRing(RandomNumberGenerator &rng, const RandomizationParameter &parameter) : B(rng, parameter, ms_fixedRing) {}
static const ThisType &Zero(); static const ThisType &Zero();
static const ThisType &One(); static const ThisType &One();
@ -206,13 +206,13 @@ public:
//! \name ACCESSORS //! \name ACCESSORS
//@{ //@{
//! the zero polynomial will return a degree of -1 //! the zero polynomial will return a degree of -1
int Degree() const {return B::Degree(fixedRing);} int Degree() const {return B::Degree(ms_fixedRing);}
//! degree + 1 //! degree + 1
unsigned int CoefficientCount() const {return B::CoefficientCount(fixedRing);} unsigned int CoefficientCount() const {return B::CoefficientCount(ms_fixedRing);}
//! return coefficient for x^i //! return coefficient for x^i
CoefficientType GetCoefficient(unsigned int i) const {return B::GetCoefficient(i, fixedRing);} CoefficientType GetCoefficient(unsigned int i) const {return B::GetCoefficient(i, ms_fixedRing);}
//! return coefficient for x^i //! return coefficient for x^i
CoefficientType operator[](unsigned int i) const {return B::GetCoefficient(i, fixedRing);} CoefficientType operator[](unsigned int i) const {return B::GetCoefficient(i, ms_fixedRing);}
//@} //@}
//! \name MANIPULATORS //! \name MANIPULATORS
@ -220,9 +220,9 @@ public:
//! //!
ThisType& operator=(const ThisType& t) {B::operator=(t); return *this;} ThisType& operator=(const ThisType& t) {B::operator=(t); return *this;}
//! //!
ThisType& operator+=(const ThisType& t) {Accumulate(t, fixedRing); return *this;} ThisType& operator+=(const ThisType& t) {Accumulate(t, ms_fixedRing); return *this;}
//! //!
ThisType& operator-=(const ThisType& t) {Reduce(t, fixedRing); return *this;} ThisType& operator-=(const ThisType& t) {Reduce(t, ms_fixedRing); return *this;}
//! //!
ThisType& operator*=(const ThisType& t) {return *this = *this*t;} ThisType& operator*=(const ThisType& t) {return *this = *this*t;}
//! //!
@ -231,18 +231,18 @@ public:
ThisType& operator%=(const ThisType& t) {return *this = *this%t;} ThisType& operator%=(const ThisType& t) {return *this = *this%t;}
//! //!
ThisType& operator<<=(unsigned int n) {ShiftLeft(n, fixedRing); return *this;} ThisType& operator<<=(unsigned int n) {ShiftLeft(n, ms_fixedRing); return *this;}
//! //!
ThisType& operator>>=(unsigned int n) {ShiftRight(n, fixedRing); return *this;} ThisType& operator>>=(unsigned int n) {ShiftRight(n, ms_fixedRing); return *this;}
//! set the coefficient for x^i to value //! set the coefficient for x^i to value
void SetCoefficient(unsigned int i, const CoefficientType &value) {B::SetCoefficient(i, value, fixedRing);} void SetCoefficient(unsigned int i, const CoefficientType &value) {B::SetCoefficient(i, value, ms_fixedRing);}
//! //!
void Randomize(RandomNumberGenerator &rng, const RandomizationParameter &parameter) {B::Randomize(rng, parameter, fixedRing);} void Randomize(RandomNumberGenerator &rng, const RandomizationParameter &parameter) {B::Randomize(rng, parameter, ms_fixedRing);}
//! //!
void Negate() {B::Negate(fixedRing);} void Negate() {B::Negate(ms_fixedRing);}
void swap(ThisType &t) {B::swap(t);} void swap(ThisType &t) {B::swap(t);}
//@} //@}
@ -254,7 +254,7 @@ public:
//! //!
ThisType operator+() const {return *this;} ThisType operator+() const {return *this;}
//! //!
ThisType operator-() const {return ThisType(Inverse(fixedRing));} ThisType operator-() const {return ThisType(Inverse(ms_fixedRing));}
//@} //@}
//! \name BINARY OPERATORS //! \name BINARY OPERATORS
@ -268,34 +268,42 @@ public:
//! \name OTHER ARITHMETIC FUNCTIONS //! \name OTHER ARITHMETIC FUNCTIONS
//@{ //@{
//! //!
ThisType MultiplicativeInverse() const {return ThisType(B::MultiplicativeInverse(fixedRing));} ThisType MultiplicativeInverse() const {return ThisType(B::MultiplicativeInverse(ms_fixedRing));}
//! //!
bool IsUnit() const {return B::IsUnit(fixedRing);} bool IsUnit() const {return B::IsUnit(ms_fixedRing);}
//! //!
ThisType Doubled() const {return ThisType(B::Doubled(fixedRing));} ThisType Doubled() const {return ThisType(B::Doubled(ms_fixedRing));}
//! //!
ThisType Squared() const {return ThisType(B::Squared(fixedRing));} ThisType Squared() const {return ThisType(B::Squared(ms_fixedRing));}
CoefficientType EvaluateAt(const CoefficientType &x) const {return B::EvaluateAt(x, fixedRing);} CoefficientType EvaluateAt(const CoefficientType &x) const {return B::EvaluateAt(x, ms_fixedRing);}
//! calculate r and q such that (a == d*q + r) && (0 <= r < abs(d)) //! calculate r and q such that (a == d*q + r) && (0 <= r < abs(d))
static void Divide(ThisType &r, ThisType &q, const ThisType &a, const ThisType &d) static void Divide(ThisType &r, ThisType &q, const ThisType &a, const ThisType &d)
{B::Divide(r, q, a, d, fixedRing);} {B::Divide(r, q, a, d, ms_fixedRing);}
//@} //@}
//! \name INPUT/OUTPUT //! \name INPUT/OUTPUT
//@{ //@{
//! //!
friend std::istream& operator>>(std::istream& in, ThisType &a) friend std::istream& operator>>(std::istream& in, ThisType &a)
{return a.Input(in, fixedRing);} {return a.Input(in, ms_fixedRing);}
//! //!
friend std::ostream& operator<<(std::ostream& out, const ThisType &a) friend std::ostream& operator<<(std::ostream& out, const ThisType &a)
{return a.Output(out, fixedRing);} {return a.Output(out, ms_fixedRing);}
//@} //@}
private: private:
static const Ring fixedRing; struct NewOnePolynomial
{
ThisType * operator()() const
{
return new ThisType(ms_fixedRing.MultiplicativeIdentity());
}
};
static const Ring ms_fixedRing;
}; };
//! Ring of polynomials over another ring //! Ring of polynomials over another ring
@ -391,7 +399,7 @@ Element BulkPolynomialInterpolateAt(const Ring &ring, const Element y[], const E
//! //!
template <class T, int instance> template <class T, int instance>
inline bool operator==(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b) inline bool operator==(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
{return a.Equals(b, fixedRing);} {return a.Equals(b, ms_fixedRing);}
//! //!
template <class T, int instance> template <class T, int instance>
inline bool operator!=(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b) inline bool operator!=(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
@ -417,23 +425,23 @@ inline bool operator<=(const CryptoPP::PolynomialOverFixedRing<T, instance> &a,
//! //!
template <class T, int instance> template <class T, int instance>
inline CryptoPP::PolynomialOverFixedRing<T, instance> operator+(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b) inline CryptoPP::PolynomialOverFixedRing<T, instance> operator+(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
{return CryptoPP::PolynomialOverFixedRing<T, instance>(a.Plus(b, fixedRing));} {return CryptoPP::PolynomialOverFixedRing<T, instance>(a.Plus(b, ms_fixedRing));}
//! //!
template <class T, int instance> template <class T, int instance>
inline CryptoPP::PolynomialOverFixedRing<T, instance> operator-(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b) inline CryptoPP::PolynomialOverFixedRing<T, instance> operator-(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
{return CryptoPP::PolynomialOverFixedRing<T, instance>(a.Minus(b, fixedRing));} {return CryptoPP::PolynomialOverFixedRing<T, instance>(a.Minus(b, ms_fixedRing));}
//! //!
template <class T, int instance> template <class T, int instance>
inline CryptoPP::PolynomialOverFixedRing<T, instance> operator*(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b) inline CryptoPP::PolynomialOverFixedRing<T, instance> operator*(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
{return CryptoPP::PolynomialOverFixedRing<T, instance>(a.Times(b, fixedRing));} {return CryptoPP::PolynomialOverFixedRing<T, instance>(a.Times(b, ms_fixedRing));}
//! //!
template <class T, int instance> template <class T, int instance>
inline CryptoPP::PolynomialOverFixedRing<T, instance> operator/(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b) inline CryptoPP::PolynomialOverFixedRing<T, instance> operator/(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
{return CryptoPP::PolynomialOverFixedRing<T, instance>(a.DividedBy(b, fixedRing));} {return CryptoPP::PolynomialOverFixedRing<T, instance>(a.DividedBy(b, ms_fixedRing));}
//! //!
template <class T, int instance> template <class T, int instance>
inline CryptoPP::PolynomialOverFixedRing<T, instance> operator%(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b) inline CryptoPP::PolynomialOverFixedRing<T, instance> operator%(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
{return CryptoPP::PolynomialOverFixedRing<T, instance>(a.Modulo(b, fixedRing));} {return CryptoPP::PolynomialOverFixedRing<T, instance>(a.Modulo(b, ms_fixedRing));}
NAMESPACE_END NAMESPACE_END

View File

@ -414,7 +414,7 @@ public:
protected: protected:
const typename BASE::MessageEncodingInterface & GetMessageEncodingInterface() const const typename BASE::MessageEncodingInterface & GetMessageEncodingInterface() const
{static typename SCHEME_OPTIONS::MessageEncodingMethod messageEncodingMethod; return messageEncodingMethod;} {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::MessageEncodingMethod>().Ref();}
const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const
{return GetKey();} {return GetKey();}
const typename BASE::TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const const typename BASE::TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const
@ -1322,17 +1322,17 @@ public:
protected: protected:
const DL_ElgamalLikeSignatureAlgorithm<Element> & GetSignatureAlgorithm() const const DL_ElgamalLikeSignatureAlgorithm<Element> & GetSignatureAlgorithm() const
{static typename SCHEME_OPTIONS::SignatureAlgorithm a; return a;} {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::SignatureAlgorithm>().Ref();}
const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const
{static typename SCHEME_OPTIONS::KeyAgreementAlgorithm a; return a;} {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::KeyAgreementAlgorithm>().Ref();}
const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const
{static typename SCHEME_OPTIONS::KeyDerivationAlgorithm a; return a;} {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::KeyDerivationAlgorithm>().Ref();}
const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const
{static typename SCHEME_OPTIONS::SymmetricEncryptionAlgorithm a; return a;} {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::SymmetricEncryptionAlgorithm>().Ref();}
HashIdentifier GetHashIdentifier() const HashIdentifier GetHashIdentifier() const
{return HashIdentifier();} {return HashIdentifier();}
const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const
{static typename SCHEME_OPTIONS::MessageEncodingMethod a; return a;} {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::MessageEncodingMethod>().Ref();}
}; };
//! . //! .

View File

@ -8,10 +8,9 @@
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
GFP2Element & GFP2Element::Zero() const GFP2Element & GFP2Element::Zero()
{ {
static GFP2Element zero; return Singleton<GFP2Element>().Ref();
return zero;
} }
void XTR_FindPrimesAndGenerator(RandomNumberGenerator &rng, Integer &p, Integer &q, GFP2Element &g, unsigned int pbits, unsigned int qbits) void XTR_FindPrimesAndGenerator(RandomNumberGenerator &rng, Integer &p, Integer &q, GFP2Element &g, unsigned int pbits, unsigned int qbits)

2
xtr.h
View File

@ -33,7 +33,7 @@ public:
c2.swap(a.c2); c2.swap(a.c2);
} }
static GFP2Element & Zero(); static const GFP2Element & Zero();
Integer c1, c2; Integer c1, c2;
}; };

View File

@ -483,15 +483,15 @@ bool Inflator::DecodeBody()
7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
12, 12, 13, 13}; 12, 12, 13, 13};
const HuffmanDecoder* pLiteralDecoder = GetLiteralDecoder(); const HuffmanDecoder& literalDecoder = GetLiteralDecoder();
const HuffmanDecoder* pDistanceDecoder = GetDistanceDecoder(); const HuffmanDecoder& distanceDecoder = GetDistanceDecoder();
switch (m_nextDecode) switch (m_nextDecode)
{ {
case LITERAL: case LITERAL:
while (true) while (true)
{ {
if (!pLiteralDecoder->Decode(m_reader, m_literal)) if (!literalDecoder.Decode(m_reader, m_literal))
{ {
m_nextDecode = LITERAL; m_nextDecode = LITERAL;
break; break;
@ -517,7 +517,7 @@ bool Inflator::DecodeBody()
} }
m_literal = m_reader.GetBits(bits) + lengthStarts[m_literal-257]; m_literal = m_reader.GetBits(bits) + lengthStarts[m_literal-257];
case DISTANCE: case DISTANCE:
if (!pDistanceDecoder->Decode(m_reader, m_distance)) if (!distanceDecoder.Decode(m_reader, m_distance))
{ {
m_nextDecode = DISTANCE; m_nextDecode = DISTANCE;
break; break;
@ -567,45 +567,41 @@ void Inflator::FlushOutput()
} }
} }
const HuffmanDecoder *Inflator::FixedLiteralDecoder() struct NewFixedLiteralDecoder
{ {
static simple_ptr<HuffmanDecoder> s_pDecoder; HuffmanDecoder * operator()() const
if (!s_pDecoder.m_p)
{ {
unsigned int codeLengths[288]; unsigned int codeLengths[288];
std::fill(codeLengths + 0, codeLengths + 144, 8); std::fill(codeLengths + 0, codeLengths + 144, 8);
std::fill(codeLengths + 144, codeLengths + 256, 9); std::fill(codeLengths + 144, codeLengths + 256, 9);
std::fill(codeLengths + 256, codeLengths + 280, 7); std::fill(codeLengths + 256, codeLengths + 280, 7);
std::fill(codeLengths + 280, codeLengths + 288, 8); std::fill(codeLengths + 280, codeLengths + 288, 8);
HuffmanDecoder *pDecoder = new HuffmanDecoder; std::auto_ptr<HuffmanDecoder> pDecoder(new HuffmanDecoder);
pDecoder->Initialize(codeLengths, 288); pDecoder->Initialize(codeLengths, 288);
s_pDecoder.m_p = pDecoder; return pDecoder.release();
} }
return s_pDecoder.m_p; };
}
const HuffmanDecoder *Inflator::FixedDistanceDecoder() struct NewFixedDistanceDecoder
{ {
static simple_ptr<HuffmanDecoder> s_pDecoder; HuffmanDecoder * operator()() const
if (!s_pDecoder.m_p)
{ {
unsigned int codeLengths[32]; unsigned int codeLengths[32];
std::fill(codeLengths + 0, codeLengths + 32, 5); std::fill(codeLengths + 0, codeLengths + 32, 5);
HuffmanDecoder *pDecoder = new HuffmanDecoder; std::auto_ptr<HuffmanDecoder> pDecoder(new HuffmanDecoder);
pDecoder->Initialize(codeLengths, 32); pDecoder->Initialize(codeLengths, 32);
s_pDecoder.m_p = pDecoder; return pDecoder.release();
} }
return s_pDecoder.m_p; };
const HuffmanDecoder& Inflator::GetLiteralDecoder() const
{
return m_blockType == 1 ? Singleton<HuffmanDecoder, NewFixedLiteralDecoder>().Ref() : m_dynamicLiteralDecoder;
} }
const HuffmanDecoder *Inflator::GetLiteralDecoder() const const HuffmanDecoder& Inflator::GetDistanceDecoder() const
{ {
return m_blockType == 1 ? FixedLiteralDecoder() : &m_dynamicLiteralDecoder; return m_blockType == 1 ? Singleton<HuffmanDecoder, NewFixedDistanceDecoder>().Ref() : m_dynamicDistanceDecoder;
}
const HuffmanDecoder *Inflator::GetDistanceDecoder() const
{
return m_blockType == 1 ? FixedDistanceDecoder() : &m_dynamicDistanceDecoder;
} }
NAMESPACE_END NAMESPACE_END

View File

@ -127,8 +127,8 @@ private:
static const HuffmanDecoder *FixedLiteralDecoder(); static const HuffmanDecoder *FixedLiteralDecoder();
static const HuffmanDecoder *FixedDistanceDecoder(); static const HuffmanDecoder *FixedDistanceDecoder();
const HuffmanDecoder *GetLiteralDecoder() const; const HuffmanDecoder& GetLiteralDecoder() const;
const HuffmanDecoder *GetDistanceDecoder() const; const HuffmanDecoder& GetDistanceDecoder() const;
enum State {PRE_STREAM, WAIT_HEADER, DECODING_BODY, POST_STREAM, AFTER_END}; enum State {PRE_STREAM, WAIT_HEADER, DECODING_BODY, POST_STREAM, AFTER_END};
State m_state; State m_state;