diff --git a/config.h b/config.h index db594544..41103fe6 100644 --- a/config.h +++ b/config.h @@ -86,6 +86,14 @@ // CACM paper. // #define LCRNG_ORIGINAL_NUMBERS +// Define this if you want Integer's operator<< to honor std::showbase (and +// std::noshowbase). If defined, Integer will use a suffix of 'b', 'o', 'h' +// or '.' (the last for decimal) when std::showbase is in effect. If +// std::noshowbase is set, then the suffix is not added to the Integer. If +// not defined, existing behavior is preserved and Integer will use a suffix +// of 'b', 'o', 'h' or '.' (the last for decimal). +// #define CRYPTOPP_USE_STD_SHOWBASE + // choose which style of sockets to wrap (mostly useful for MinGW which has both) #if !defined(NO_BERKELEY_STYLE_SOCKETS) && !defined(PREFER_BERKELEY_STYLE_SOCKETS) # define PREFER_BERKELEY_STYLE_SOCKETS diff --git a/config.recommend b/config.recommend index bc933a0b..8fe2e84c 100644 --- a/config.recommend +++ b/config.recommend @@ -86,6 +86,14 @@ // CACM paper. // #define LCRNG_ORIGINAL_NUMBERS +// Define this if you want Integer's operator<< to honor std::showbase (and +// std::noshowbase). If defined, Integer will use a suffix of 'b', 'o', 'h' +// or '.' (the last for decimal) when std::showbase is in effect. If +// std::noshowbase is set, then the suffix is not added to the Integer. If +// not defined, existing behavior is preserved and Integer will use a suffix +// of 'b', 'o', 'h' or '.' (the last for decimal). +// #define CRYPTOPP_USE_STD_SHOWBASE + // choose which style of sockets to wrap (mostly useful for MinGW which has both) #if !defined(NO_BERKELEY_STYLE_SOCKETS) && !defined(PREFER_BERKELEY_STYLE_SOCKETS) # define PREFER_BERKELEY_STYLE_SOCKETS diff --git a/integer.cpp b/integer.cpp index de5df007..c5321680 100644 --- a/integer.cpp +++ b/integer.cpp @@ -2871,13 +2871,36 @@ signed long Integer::ConvertToLong() const return sign==POSITIVE ? value : -(signed long)value; } -Integer::Integer(BufferedTransformation &encodedInteger, size_t byteCount, Signedness s) +Integer::Integer(BufferedTransformation &encodedInteger, size_t byteCount, Signedness s, ByteOrder o) { + assert(o == BIG_ENDIAN_ORDER || o == LITTLE_ENDIAN_ORDER); + + if(o == LITTLE_ENDIAN_ORDER) + { + SecByteBlock block(byteCount); + encodedInteger.Get(block, block.size()); + std::reverse(block.begin(), block.begin()+block.size()); + + Decode(block.begin(), block.size(), s); + return; + } + Decode(encodedInteger, byteCount, s); } -Integer::Integer(const byte *encodedInteger, size_t byteCount, Signedness s) +Integer::Integer(const byte *encodedInteger, size_t byteCount, Signedness s, ByteOrder o) { + assert(o == BIG_ENDIAN_ORDER || o == LITTLE_ENDIAN_ORDER); + + if(o == LITTLE_ENDIAN_ORDER) + { + SecByteBlock block(byteCount); + std::reverse_copy(encodedInteger, encodedInteger+byteCount, block.begin()); + + Decode(block.begin(), block.size(), s); + return; + } + Decode(encodedInteger, byteCount, s); } @@ -3019,9 +3042,11 @@ Integer::Integer(word value, size_t length) } template -static Integer StringToInteger(const T *str) +static Integer StringToInteger(const T *str, ByteOrder order) { - int radix; + assert( order == BIG_ENDIAN_ORDER || order == LITTLE_ENDIAN_ORDER ); + + int radix, sign = 1; // GCC workaround // std::char_traits::length() not defined in GCC 3.2 and STLport 4.5.3 unsigned int length; @@ -3030,7 +3055,7 @@ static Integer StringToInteger(const T *str) Integer v; if (length == 0) - return v; + return Integer::Zero(); switch (str[length-1]) { @@ -3050,45 +3075,117 @@ static Integer StringToInteger(const T *str) radix=10; } - if (length > 2 && str[0] == '0' && str[1] == 'x') - radix = 16; - - for (unsigned i=0; i= '0' && str[i] <= '9') - digit = str[i] - '0'; - else if (str[i] >= 'A' && str[i] <= 'F') - digit = str[i] - 'A' + 10; - else if (str[i] >= 'a' && str[i] <= 'f') - digit = str[i] - 'a' + 10; - else - digit = radix; - - if (digit < radix) - { - v *= radix; - v += digit; - } + sign = -1; + str += 1, length -= 1; } - if (str[0] == '-') + if (length > 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) + { + radix = 16; + str += 2, length -= 2; + } + + if(order == BIG_ENDIAN_ORDER) + { + for (unsigned int i=0; i(str[i]); + + if (ch >= '0' && ch <= '9') + digit = ch - '0'; + else if (ch >= 'A' && ch <= 'F') + digit = ch - 'A' + 10; + else if (ch >= 'a' && ch <= 'f') + digit = ch - 'a' + 10; + else + digit = radix; + + if (digit < radix) + { + v *= radix; + v += digit; + } + } + } + else if(radix == 16 && order == LITTLE_ENDIAN_ORDER) + { + // Nibble high, low and count + unsigned int nh, nl, nc = 0; + Integer position(Integer::One()); + + for (unsigned int i=0; i(str[i]); + + if (ch >= '0' && ch <= '9') + digit = ch - '0'; + else if (ch >= 'A' && ch <= 'F') + digit = ch - 'A' + 10; + else if (ch >= 'a' && ch <= 'f') + digit = ch - 'a' + 10; + else + digit = radix; + + if (digit < radix) + { + if(nc++ == 0) + nh = digit; + else + nl = digit; + + if(nc == 2) + { + v += position * (nh << 4 | nl); + nc = 0, position <<= 8; + } + } + } + + if(nc == 1) + v += nh * position; + } + else // LITTLE_ENDIAN_ORDER && radix != 16 + { + for (int i=static_cast(length)-1; i>=0; i--) + { + int digit, ch = static_cast(str[i]); + + if (ch >= '0' && ch <= '9') + digit = ch - '0'; + else if (ch >= 'A' && ch <= 'F') + digit = ch - 'A' + 10; + else if (ch >= 'a' && ch <= 'f') + digit = ch - 'a' + 10; + else + digit = radix; + + if (digit < radix) + { + v *= radix; + v += digit; + } + } + } + + if (sign == -1) v.Negate(); return v; } -Integer::Integer(const char *str) +Integer::Integer(const char *str, ByteOrder order) : reg(2), sign(POSITIVE) { - *this = StringToInteger(str); + *this = StringToInteger(str,order); } -Integer::Integer(const wchar_t *str) +Integer::Integer(const wchar_t *str, ByteOrder order) : reg(2), sign(POSITIVE) { - *this = StringToInteger(str); + *this = StringToInteger(str,order); } unsigned int Integer::WordCount() const @@ -3483,7 +3580,14 @@ std::ostream& operator<<(std::ostream& out, const Integer &a) // out << ","; } - return out << suffix; +#ifdef CRYPTOPP_USE_STD_SHOWBASE + if(out.flags() & std::ios_base::showbase) + out << suffix; + + return out; +#else + return out << suffix; +#endif } Integer& Integer::operator++() diff --git a/integer.h b/integer.h index 858b1cdb..17f651c7 100644 --- a/integer.h +++ b/integer.h @@ -101,27 +101,31 @@ public: //! \brief Convert from a C-string //! \param str C-string value + //! \param order byte order //! \details \p 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 char *str, ByteOrder order = BIG_ENDIAN_ORDER); //! \brief Convert from a wide C-string //! \param str wide C-string value + //! \param order byte order //! \details \p 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 wchar_t *str); + explicit Integer(const wchar_t *str, ByteOrder order = BIG_ENDIAN_ORDER); //! \brief Convert from a big-endian byte array //! \param encodedInteger big-endian byte array //! \param byteCount length of the byte array //! \param sign enumeration indicating Signedness - Integer(const byte *encodedInteger, size_t byteCount, Signedness sign=UNSIGNED); + //! \param order byte order + Integer(const byte *encodedInteger, size_t byteCount, Signedness sign=UNSIGNED, ByteOrder order = BIG_ENDIAN_ORDER); //! \brief Convert from a big-endian array //! \param bt BufferedTransformation object with big-endian byte array //! \param byteCount length of the byte array //! \param sign enumeration indicating Signedness - Integer(BufferedTransformation &bt, size_t byteCount, Signedness sign=UNSIGNED); + //! \param order byte order + Integer(BufferedTransformation &bt, size_t byteCount, Signedness sign=UNSIGNED, ByteOrder order = BIG_ENDIAN_ORDER); //! \brief Convert from a BER encoded byte array //! \param bt BufferedTransformation object with BER encoded byte array diff --git a/oids.h b/oids.h index 4ce6546d..9eac4f10 100644 --- a/oids.h +++ b/oids.h @@ -48,7 +48,7 @@ DEFINE_OID(1, iso) DEFINE_OID(oiw()+3, oiw_secsig); DEFINE_OID(oiw_secsig()+2, oiw_secsig_algorithms); DEFINE_OID(oiw_secsig_algorithms()+26, id_sha1); - + DEFINE_OID(identified_organization()+36, teletrust); DEFINE_OID(teletrust()+3, teletrust_algorithm) DEFINE_OID(teletrust_algorithm()+2+1, id_ripemd160)