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