/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 | | } |