aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/asn1/asn1_print.cpp14
-rw-r--r--src/lib/asn1/asn1_print.h10
-rw-r--r--src/lib/math/bigint/big_code.cpp22
-rw-r--r--src/lib/math/bigint/big_io.cpp17
4 files changed, 42 insertions, 21 deletions
diff --git a/src/lib/asn1/asn1_print.cpp b/src/lib/asn1/asn1_print.cpp
index 34c671483..1a1654fef 100644
--- a/src/lib/asn1/asn1_print.cpp
+++ b/src/lib/asn1/asn1_print.cpp
@@ -172,11 +172,7 @@ void ASN1_Formatter::decode(std::ostream& output,
data.decode(number, ASN1_Type::Enumerated, class_tag);
}
- std::vector<uint8_t> rep = BigInt::encode(number);
- if(rep.empty()) // if zero
- rep.resize(1);
-
- output << format(type_tag, class_tag, level, length, hex_encode(rep));
+ output << format(type_tag, class_tag, level, length, format_bn(number));
}
else if(type_tag == ASN1_Type::Boolean)
{
@@ -324,4 +320,12 @@ std::string ASN1_Pretty_Printer::format_bin(ASN1_Type /*type_tag*/,
return hex_encode(vec);
}
+std::string ASN1_Pretty_Printer::format_bn(const BigInt& bn) const
+ {
+ if(bn.bits() < 16)
+ return bn.to_dec_string();
+ else
+ return bn.to_hex_string();
+ }
+
}
diff --git a/src/lib/asn1/asn1_print.h b/src/lib/asn1/asn1_print.h
index 53ed42de6..94dc48d6a 100644
--- a/src/lib/asn1/asn1_print.h
+++ b/src/lib/asn1/asn1_print.h
@@ -14,6 +14,7 @@
namespace Botan {
+class BigInt;
class BER_Decoder;
/**
@@ -58,13 +59,18 @@ class BOTAN_PUBLIC_API(2,4) ASN1_Formatter
/**
* This is called to format binary elements that we don't know how to
- * convert to a string The result will be passed as value to format; the
+ * convert to a string. The result will be passed as value to format; the
* tags are included as a hint to aid decoding.
*/
virtual std::string format_bin(ASN1_Type type_tag,
ASN1_Class class_tag,
const std::vector<uint8_t>& vec) const = 0;
+ /**
+ * This is called to format integers
+ */
+ virtual std::string format_bn(const BigInt& bn) const = 0;
+
private:
void decode(std::ostream& output,
BER_Decoder& decoder,
@@ -114,6 +120,8 @@ class BOTAN_PUBLIC_API(2,4) ASN1_Pretty_Printer final : public ASN1_Formatter
ASN1_Class class_tag,
const std::vector<uint8_t>& vec) const override;
+ std::string format_bn(const BigInt& bn) const override;
+
const size_t m_print_limit;
const size_t m_print_binary_limit;
const size_t m_initial_level;
diff --git a/src/lib/math/bigint/big_code.cpp b/src/lib/math/bigint/big_code.cpp
index 3ff31b639..c31221333 100644
--- a/src/lib/math/bigint/big_code.cpp
+++ b/src/lib/math/bigint/big_code.cpp
@@ -17,7 +17,10 @@ std::string BigInt::to_dec_string() const
copy.set_sign(Positive);
uint8_t remainder;
- std::vector<uint8_t> digits;
+ secure_vector<uint8_t> digits;
+
+ // (over-)estimate of the number of digits, log2(10) ~= 3.32
+ digits.reserve(3.4 * this->bits());
while(copy > 0)
{
@@ -33,6 +36,9 @@ std::string BigInt::to_dec_string() const
std::string s;
+ if(is_negative())
+ s += "-";
+
for(auto i = digits.rbegin(); i != digits.rend(); ++i)
{
s.push_back(*i + '0');
@@ -46,11 +52,17 @@ std::string BigInt::to_dec_string() const
std::string BigInt::to_hex_string() const
{
- const std::vector<uint8_t> bits = BigInt::encode(*this);
+ std::vector<uint8_t> bits = BigInt::encode(*this);
+
if(bits.empty())
- return "00";
- else
- return hex_encode(bits);
+ bits.push_back(0);
+
+ std::string hrep;
+ if(is_negative())
+ hrep += "-";
+ hrep += "0x";
+ hrep += hex_encode(bits);
+ return hrep;
}
/*
diff --git a/src/lib/math/bigint/big_io.cpp b/src/lib/math/bigint/big_io.cpp
index b31315eac..ae2855fcc 100644
--- a/src/lib/math/bigint/big_io.cpp
+++ b/src/lib/math/bigint/big_io.cpp
@@ -16,17 +16,17 @@ namespace Botan {
*/
std::ostream& operator<<(std::ostream& stream, const BigInt& n)
{
- size_t base = 10;
- if(stream.flags() & std::ios::hex)
- base = 16;
- if(stream.flags() & std::ios::oct)
+ const auto stream_flags = stream.flags();
+ if(stream_flags & std::ios::oct)
throw Invalid_Argument("Octal output of BigInt not supported");
- if(n == 0)
+ const size_t base = (stream_flags & std::ios::hex) ? 16 : 10;
+
+ if(n.is_zero())
stream.write("0", 1);
else
{
- if(n < 0)
+ if(n.is_negative())
stream.write("-", 1);
std::string enc;
@@ -36,10 +36,7 @@ std::ostream& operator<<(std::ostream& stream, const BigInt& n)
else
enc = n.to_hex_string();
- size_t skip = 0;
- while(skip < enc.size() && enc[skip] == '0')
- ++skip;
- stream.write(&enc[skip], enc.size() - skip);
+ stream.write(enc.data(), enc.size());
}
if(!stream.good())
throw Stream_IO_Error("BigInt output operator has failed");