Coverage Report

Created: 2020-11-21 08:34

/src/botan/src/lib/math/bigint/big_code.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* BigInt Encoding/Decoding
3
* (C) 1999-2010,2012,2019 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7
8
#include <botan/bigint.h>
9
#include <botan/internal/divide.h>
10
#include <botan/internal/charset.h>
11
#include <botan/hex.h>
12
13
namespace Botan {
14
15
std::string BigInt::to_dec_string() const
16
0
   {
17
0
   BigInt copy = *this;
18
0
   copy.set_sign(Positive);
19
20
0
   uint8_t remainder;
21
0
   std::vector<uint8_t> digits;
22
23
0
   while(copy > 0)
24
0
      {
25
0
      ct_divide_u8(copy, 10, copy, remainder);
26
0
      digits.push_back(remainder);
27
0
      }
28
29
0
   std::string s;
30
31
0
   for(auto i = digits.rbegin(); i != digits.rend(); ++i)
32
0
      {
33
0
      s.push_back(Charset::digit2char(*i));
34
0
      }
35
36
0
   if(s.empty())
37
0
      s += "0";
38
39
0
   return s;
40
0
   }
41
42
std::string BigInt::to_hex_string() const
43
0
   {
44
0
   const std::vector<uint8_t> bits = BigInt::encode(*this);
45
0
   if(bits.empty())
46
0
      return "00";
47
0
   else
48
0
      return hex_encode(bits);
49
0
   }
50
51
/*
52
* Encode a BigInt, with leading 0s if needed
53
*/
54
secure_vector<uint8_t> BigInt::encode_1363(const BigInt& n, size_t bytes)
55
20.7k
   {
56
20.7k
   if(n.bytes() > bytes)
57
26
      throw Encoding_Error("encode_1363: n is too large to encode properly");
58
59
20.7k
   secure_vector<uint8_t> output(bytes);
60
20.7k
   n.binary_encode(output.data(), output.size());
61
20.7k
   return output;
62
20.7k
   }
63
64
//static
65
void BigInt::encode_1363(uint8_t output[], size_t bytes, const BigInt& n)
66
41.3k
   {
67
41.3k
   if(n.bytes() > bytes)
68
0
      throw Encoding_Error("encode_1363: n is too large to encode properly");
69
70
41.3k
   n.binary_encode(output, bytes);
71
41.3k
   }
72
73
/*
74
* Encode two BigInt, with leading 0s if needed, and concatenate
75
*/
76
secure_vector<uint8_t> BigInt::encode_fixed_length_int_pair(const BigInt& n1, const BigInt& n2, size_t bytes)
77
0
   {
78
0
   if(n1.bytes() > bytes || n2.bytes() > bytes)
79
0
      throw Encoding_Error("encode_fixed_length_int_pair: values too large to encode properly");
80
0
   secure_vector<uint8_t> output(2 * bytes);
81
0
   n1.binary_encode(output.data()        , bytes);
82
0
   n2.binary_encode(output.data() + bytes, bytes);
83
0
   return output;
84
0
   }
85
86
/*
87
* Decode a BigInt
88
*/
89
BigInt BigInt::decode(const uint8_t buf[], size_t length, Base base)
90
20.1k
   {
91
20.1k
   BigInt r;
92
20.1k
   if(base == Binary)
93
0
      {
94
0
      r.binary_decode(buf, length);
95
0
      }
96
20.1k
   else if(base == Hexadecimal)
97
20.1k
      {
98
20.1k
      secure_vector<uint8_t> binary;
99
100
20.1k
      if(length % 2)
101
8.39k
         {
102
         // Handle lack of leading 0
103
8.39k
         const char buf0_with_leading_0[2] =
104
8.39k
            { '0', static_cast<char>(buf[0]) };
105
106
8.39k
         binary = hex_decode_locked(buf0_with_leading_0, 2);
107
108
8.39k
         binary += hex_decode_locked(cast_uint8_ptr_to_char(&buf[1]),
109
8.39k
                                     length - 1,
110
8.39k
                                     false);
111
8.39k
         }
112
11.7k
      else
113
11.7k
         binary = hex_decode_locked(cast_uint8_ptr_to_char(buf),
114
11.7k
                                    length, false);
115
116
20.1k
      r.binary_decode(binary.data(), binary.size());
117
20.1k
      }
118
0
   else if(base == Decimal)
119
0
      {
120
0
      for(size_t i = 0; i != length; ++i)
121
0
         {
122
0
         if(Charset::is_space(buf[i]))
123
0
            continue;
124
125
0
         if(!Charset::is_digit(buf[i]))
126
0
            throw Invalid_Argument("BigInt::decode: "
127
0
                                   "Invalid character in decimal input");
128
129
0
         const uint8_t x = Charset::char2digit(buf[i]);
130
131
0
         if(x >= 10)
132
0
            throw Invalid_Argument("BigInt: Invalid decimal string");
133
134
0
         r *= 10;
135
0
         r += x;
136
0
         }
137
0
      }
138
0
   else
139
0
      throw Invalid_Argument("Unknown BigInt decoding method");
140
20.1k
   return r;
141
20.1k
   }
142
143
}