Botan 2.19.5 Crypto and TLS for C&

big_code.cpp
Go to the documentation of this file.
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/divide.h>
10#include <botan/charset.h>
11#include <botan/hex.h>
12
13 namespace Botan {
14
15std::string BigInt::to_dec_string() const
16 {
17 BigInt copy = *this;
18 copy.set_sign(Positive);
19
20 uint8_t remainder;
21 std::vector<uint8_t> digits;
22
23 while(copy > 0)
24 {
25 ct_divide_u8(copy, 10, copy, remainder);
26 digits.push_back(remainder);
27 }
28
29 std::string s;
30
31 for(auto i = digits.rbegin(); i != digits.rend(); ++i)
32 {
33 s.push_back(Charset::digit2char(*i));
34 }
35
36 if(s.empty())
37 s += "0";
38
39 return s;
40 }
41
42std::string BigInt::to_hex_string() const
43 {
44 const std::vector<uint8_t> bits = BigInt::encode(*this);
45 if(bits.empty())
46 return "00";
47 else
48 return hex_encode(bits);
49 }
50
51/*
52* Encode a BigInt
53*/
54 void BigInt::encode(uint8_t output[], const BigInt& n, Base base)
55 {
56 secure_vector<uint8_t> enc = n.encode_locked(base);
57 copy_mem(output, enc.data(), enc.size());
58 }
59
60 namespace {
61
62std::vector<uint8_t> str_to_vector(const std::string& s)
63 {
64 std::vector<uint8_t> v(s.size());
65 std::memcpy(v.data(), s.data(), s.size());
66 return v;
67 }
68
69secure_vector<uint8_t> str_to_lvector(const std::string& s)
70 {
71 secure_vector<uint8_t> v(s.size());
72 std::memcpy(v.data(), s.data(), s.size());
73 return v;
74 }
75
76}
77
78/*
79* Encode a BigInt
80*/
81std::vector<uint8_t> BigInt::encode(const BigInt& n, Base base)
82 {
83 if(base == Binary)
84 return BigInt::encode(n);
85 else if(base == Hexadecimal)
86 return str_to_vector(n.to_hex_string());
87 else if(base == Decimal)
88 return str_to_vector(n.to_dec_string());
89 else
90 throw Invalid_Argument("Unknown BigInt encoding base");
91 }
92
93/*
94* Encode a BigInt
95*/
96 secure_vector<uint8_t> BigInt::encode_locked(const BigInt& n, Base base)
97 {
98 if(base == Binary)
99 return BigInt::encode_locked(n);
100 else if(base == Hexadecimal)
101 return str_to_lvector(n.to_hex_string());
102 else if(base == Decimal)
103 return str_to_lvector(n.to_dec_string());
104 else
105 throw Invalid_Argument("Unknown BigInt encoding base");
106 }
107
108/*
109* Encode a BigInt, with leading 0s if needed
110*/
111 secure_vector<uint8_t> BigInt::encode_1363(const BigInt& n, size_t bytes)
112 {
113 if(n.bytes() > bytes)
114 throw Encoding_Error("encode_1363: n is too large to encode properly");
115
116 secure_vector<uint8_t> output(bytes);
117 n.binary_encode(output.data(), output.size());
118 return output;
119 }
120
121//static
122 void BigInt::encode_1363(uint8_t output[], size_t bytes, const BigInt& n)
123 {
124 if(n.bytes() > bytes)
125 throw Encoding_Error("encode_1363: n is too large to encode properly");
126
127 n.binary_encode(output, bytes);
128 }
129
130/*
131* Encode two BigInt, with leading 0s if needed, and concatenate
132*/
133 secure_vector<uint8_t> BigInt::encode_fixed_length_int_pair(const BigInt& n1, const BigInt& n2, size_t bytes)
134 {
135 if(n1.bytes() > bytes || n2.bytes() > bytes)
136 throw Encoding_Error("encode_fixed_length_int_pair: values too large to encode properly");
137 secure_vector<uint8_t> output(2 * bytes);
138 n1.binary_encode(output.data() , bytes);
139 n2.binary_encode(output.data() + bytes, bytes);
140 return output;
141 }
142
143/*
144* Decode a BigInt
145*/
146 BigInt BigInt::decode(const uint8_t buf[], size_t length, Base base)
147 {
148 BigInt r;
149 if(base == Binary)
150 {
151 r.binary_decode(buf, length);
152 }
153 else if(base == Hexadecimal)
154 {
155 secure_vector<uint8_t> binary;
156
157 if(length % 2)
158 {
159 // Handle lack of leading 0
160 const char buf0_with_leading_0[2] =
161 { '0', static_cast<char>(buf[0]) };
162
163 binary = hex_decode_locked(buf0_with_leading_0, 2);
164
165 binary += hex_decode_locked(cast_uint8_ptr_to_char(&buf[1]),
166 length - 1,
167 false);
168 }
169 else
170 binary = hex_decode_locked(cast_uint8_ptr_to_char(buf),
171 length, false);
172
173 r.binary_decode(binary.data(), binary.size());
174 }
175 else if(base == Decimal)
176 {
177 for(size_t i = 0; i != length; ++i)
178 {
179 if(Charset::is_space(buf[i]))
180 continue;
181
182 if(!Charset::is_digit(buf[i]))
183 throw Invalid_Argument("BigInt::decode: "
184 "Invalid character in decimal input");
185
186 const uint8_t x = Charset::char2digit(buf[i]);
187
188 if(x >= 10)
189 throw Invalid_Argument("BigInt: Invalid decimal string");
190
191 r *= 10;
192 r += x;
193 }
194 }
195 else
196 throw Invalid_Argument("Unknown BigInt decoding method");
197 return r;
198 }
199
200}
Botan::BigInt
Definition: bigint.h:25
Botan::BigInt::binary_decode
void binary_decode(const uint8_t buf[], size_t length)
Definition: bigint.cpp:440
Botan::BigInt::decode
static BigInt decode(const uint8_t buf[], size_t length)
Definition: bigint.h:817
Botan::BigInt::Base
Base
Definition: bigint.h:30
Botan::BigInt::Binary
@ Binary
Definition: bigint.h:30
Botan::BigInt::Decimal
@ Decimal
Definition: bigint.h:30
Botan::BigInt::Hexadecimal
@ Hexadecimal
Definition: bigint.h:30
Botan::BigInt::to_dec_string
std::string to_dec_string() const
Definition: big_code.cpp:15
Botan::BigInt::encode_locked
static secure_vector< uint8_t > encode_locked(const BigInt &n)
Definition: bigint.h:794
Botan::BigInt::binary_encode
void binary_encode(uint8_t buf[]) const
Definition: bigint.cpp:407
Botan::BigInt::to_hex_string
std::string to_hex_string() const
Definition: big_code.cpp:42
Botan::BigInt::encode_fixed_length_int_pair
static secure_vector< uint8_t > encode_fixed_length_int_pair(const BigInt &n1, const BigInt &n2, size_t bytes)
Definition: big_code.cpp:133
Botan::BigInt::bits
size_t bits() const
Definition: bigint.cpp:304
Botan::BigInt::encode
static std::vector< uint8_t > encode(const BigInt &n)
Definition: bigint.h:782
Botan::BigInt::encode_1363
static secure_vector< uint8_t > encode_1363(const BigInt &n, size_t bytes)
Definition: big_code.cpp:111
Botan::BigInt::Positive
@ Positive
Definition: bigint.h:35
Botan::BigInt::bytes
size_t bytes() const
Definition: bigint.cpp:289
Botan::BigInt::set_sign
void set_sign(Sign sign)
Definition: bigint.h:569
Botan::Encoding_Error
Definition: exceptn.h:185
Botan::Invalid_Argument
Definition: exceptn.h:137
Botan::Charset::is_digit
bool is_digit(char c)
Definition: charset.cpp:210
Botan::Charset::is_space
bool is_space(char c)
Definition: charset.cpp:221
Botan::Charset::char2digit
uint8_t char2digit(char c)
Definition: charset.cpp:231
Botan::Charset::digit2char
char digit2char(uint8_t b)
Definition: charset.cpp:253
Botan
Definition: alg_id.cpp:13
Botan::ct_divide_u8
void ct_divide_u8(const BigInt &x, uint8_t y, BigInt &q_out, uint8_t &r_out)
Definition: divide.cpp:82
Botan::hex_decode_locked
secure_vector< uint8_t > hex_decode_locked(const char input[], size_t input_length, bool ignore_ws)
Definition: hex.cpp:168
Botan::copy_mem
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:133
Botan::hex_encode
void hex_encode(char output[], const uint8_t input[], size_t input_length, bool uppercase)
Definition: hex.cpp:31
Botan::cast_uint8_ptr_to_char
const char * cast_uint8_ptr_to_char(const uint8_t *b)
Definition: mem_ops.h:195
Botan::secure_vector
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65