Coverage Report

Created: 2021-02-21 07:20

/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/hex.h>
11
12
namespace Botan {
13
14
std::string BigInt::to_dec_string() const
15
0
   {
16
0
   BigInt copy = *this;
17
0
   copy.set_sign(Positive);
18
19
0
   uint8_t remainder;
20
0
   std::vector<uint8_t> digits;
21
22
0
   while(copy > 0)
23
0
      {
24
0
      ct_divide_u8(copy, 100, copy, remainder);
25
26
0
      const uint8_t ld = remainder % 10;
27
0
      const uint8_t td = (remainder - ld) / 10;
28
0
      digits.push_back(ld);
29
30
0
      if(copy > 0 || td > 0)
31
0
         digits.push_back(td);
32
0
      }
33
34
0
   std::string s;
35
36
0
   for(auto i = digits.rbegin(); i != digits.rend(); ++i)
37
0
      {
38
0
      s.push_back(*i + '0');
39
0
      }
40
41
0
   if(s.empty())
42
0
      s += "0";
43
44
0
   return s;
45
0
   }
46
47
std::string BigInt::to_hex_string() const
48
0
   {
49
0
   const std::vector<uint8_t> bits = BigInt::encode(*this);
50
0
   if(bits.empty())
51
0
      return "00";
52
0
   else
53
0
      return hex_encode(bits);
54
0
   }
55
56
/*
57
* Encode a BigInt, with leading 0s if needed
58
*/
59
secure_vector<uint8_t> BigInt::encode_1363(const BigInt& n, size_t bytes)
60
9.27k
   {
61
9.27k
   if(n.bytes() > bytes)
62
42
      throw Encoding_Error("encode_1363: n is too large to encode properly");
63
64
9.23k
   secure_vector<uint8_t> output(bytes);
65
9.23k
   n.binary_encode(output.data(), output.size());
66
9.23k
   return output;
67
9.23k
   }
68
69
//static
70
void BigInt::encode_1363(uint8_t output[], size_t bytes, const BigInt& n)
71
40.7k
   {
72
40.7k
   if(n.bytes() > bytes)
73
0
      throw Encoding_Error("encode_1363: n is too large to encode properly");
74
75
40.7k
   n.binary_encode(output, bytes);
76
40.7k
   }
77
78
/*
79
* Encode two BigInt, with leading 0s if needed, and concatenate
80
*/
81
secure_vector<uint8_t> BigInt::encode_fixed_length_int_pair(const BigInt& n1, const BigInt& n2, size_t bytes)
82
0
   {
83
0
   if(n1.bytes() > bytes || n2.bytes() > bytes)
84
0
      throw Encoding_Error("encode_fixed_length_int_pair: values too large to encode properly");
85
0
   secure_vector<uint8_t> output(2 * bytes);
86
0
   n1.binary_encode(output.data()        , bytes);
87
0
   n2.binary_encode(output.data() + bytes, bytes);
88
0
   return output;
89
0
   }
90
91
/*
92
* Decode a BigInt
93
*/
94
BigInt BigInt::decode(const uint8_t buf[], size_t length, Base base)
95
6.95k
   {
96
6.95k
   BigInt r;
97
6.95k
   if(base == Binary)
98
0
      {
99
0
      r.binary_decode(buf, length);
100
0
      }
101
6.95k
   else if(base == Hexadecimal)
102
6.95k
      {
103
6.95k
      secure_vector<uint8_t> binary;
104
105
6.95k
      if(length % 2)
106
2.18k
         {
107
         // Handle lack of leading 0
108
2.18k
         const char buf0_with_leading_0[2] =
109
2.18k
            { '0', static_cast<char>(buf[0]) };
110
111
2.18k
         binary = hex_decode_locked(buf0_with_leading_0, 2);
112
113
2.18k
         binary += hex_decode_locked(cast_uint8_ptr_to_char(&buf[1]),
114
2.18k
                                     length - 1,
115
2.18k
                                     false);
116
2.18k
         }
117
4.77k
      else
118
4.77k
         binary = hex_decode_locked(cast_uint8_ptr_to_char(buf),
119
4.77k
                                    length, false);
120
121
6.95k
      r.binary_decode(binary.data(), binary.size());
122
6.95k
      }
123
0
   else if(base == Decimal)
124
0
      {
125
0
      for(size_t i = 0; i != length; ++i)
126
0
         {
127
0
         const char c = buf[i];
128
129
0
         if(c < '0' || c > '9')
130
0
            throw Invalid_Argument("BigInt::decode: invalid decimal char");
131
132
0
         const uint8_t x = c - '0';
133
0
         BOTAN_ASSERT_NOMSG(x < 10);
134
135
0
         r *= 10;
136
0
         r += x;
137
0
         }
138
0
      }
139
0
   else
140
0
      throw Invalid_Argument("Unknown BigInt decoding method");
141
6.95k
   return r;
142
6.95k
   }
143
144
}