Botan  2.6.0
Crypto and TLS for C++11
big_code.cpp
Go to the documentation of this file.
1 /*
2 * BigInt Encoding/Decoding
3 * (C) 1999-2010,2012 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 
15 /*
16 * Encode a BigInt
17 */
18 void BigInt::encode(uint8_t output[], const BigInt& n, Base base)
19  {
20  if(base == Binary)
21  {
22  n.binary_encode(output);
23  }
24  else if(base == Hexadecimal)
25  {
27  n.binary_encode(binary.data());
28 
30  binary.data(), binary.size());
31  }
32  else if(base == Decimal)
33  {
34  BigInt copy = n;
35  BigInt remainder;
36  copy.set_sign(Positive);
37  const size_t output_size = n.encoded_size(Decimal);
38  for(size_t j = 0; j != output_size; ++j)
39  {
40  divide(copy, 10, copy, remainder);
41  output[output_size - 1 - j] =
42  Charset::digit2char(static_cast<uint8_t>(remainder.word_at(0)));
43  if(copy.is_zero())
44  break;
45  }
46  }
47  else
48  throw Invalid_Argument("Unknown BigInt encoding method");
49  }
50 
51 /*
52 * Encode a BigInt
53 */
54 std::vector<uint8_t> BigInt::encode(const BigInt& n, Base base)
55  {
56  std::vector<uint8_t> output(n.encoded_size(base));
57  encode(output.data(), n, base);
58  if(base != Binary)
59  for(size_t j = 0; j != output.size(); ++j)
60  if(output[j] == 0)
61  output[j] = '0';
62  return output;
63  }
64 
65 /*
66 * Encode a BigInt
67 */
69  {
70  secure_vector<uint8_t> output(n.encoded_size(base));
71  encode(output.data(), n, base);
72  if(base != Binary)
73  for(size_t j = 0; j != output.size(); ++j)
74  if(output[j] == 0)
75  output[j] = '0';
76  return output;
77  }
78 
79 /*
80 * Encode a BigInt, with leading 0s if needed
81 */
83  {
85  BigInt::encode_1363(output.data(), output.size(), n);
86  return output;
87  }
88 
89 //static
90 void BigInt::encode_1363(uint8_t output[], size_t bytes, const BigInt& n)
91  {
92  const size_t n_bytes = n.bytes();
93  if(n_bytes > bytes)
94  throw Encoding_Error("encode_1363: n is too large to encode properly");
95 
96  const size_t leading_0s = bytes - n_bytes;
97  encode(&output[leading_0s], n, Binary);
98  }
99 
100 /*
101 * Encode two BigInt, with leading 0s if needed, and concatenate
102 */
104  {
105  secure_vector<uint8_t> output(2 * bytes);
106  BigInt::encode_1363(output.data(), bytes, n1);
107  BigInt::encode_1363(output.data() + bytes, bytes, n2);
108  return output;
109  }
110 
111 /*
112 * Decode a BigInt
113 */
114 BigInt BigInt::decode(const uint8_t buf[], size_t length, Base base)
115  {
116  BigInt r;
117  if(base == Binary)
118  r.binary_decode(buf, length);
119  else if(base == Hexadecimal)
120  {
121  secure_vector<uint8_t> binary;
122 
123  if(length % 2)
124  {
125  // Handle lack of leading 0
126  const char buf0_with_leading_0[2] =
127  { '0', static_cast<char>(buf[0]) };
128 
129  binary = hex_decode_locked(buf0_with_leading_0, 2);
130 
131  binary += hex_decode_locked(cast_uint8_ptr_to_char(&buf[1]),
132  length - 1,
133  false);
134  }
135  else
137  length, false);
138 
139  r.binary_decode(binary.data(), binary.size());
140  }
141  else if(base == Decimal)
142  {
143  for(size_t i = 0; i != length; ++i)
144  {
145  if(Charset::is_space(buf[i]))
146  continue;
147 
148  if(!Charset::is_digit(buf[i]))
149  throw Invalid_Argument("BigInt::decode: "
150  "Invalid character in decimal input");
151 
152  const uint8_t x = Charset::char2digit(buf[i]);
153 
154  if(x >= 10)
155  throw Invalid_Argument("BigInt: Invalid decimal string");
156 
157  r *= 10;
158  r += x;
159  }
160  }
161  else
162  throw Invalid_Argument("Unknown BigInt decoding method");
163  return r;
164  }
165 
166 }
void hex_encode(char output[], const uint8_t input[], size_t input_length, bool uppercase)
Definition: hex.cpp:14
secure_vector< uint8_t > hex_decode_locked(const char input[], size_t input_length, bool ignore_ws)
Definition: hex.cpp:165
uint8_t char2digit(char c)
Definition: charset.cpp:231
bool is_zero() const
Definition: bigint.h:314
void binary_encode(uint8_t buf[]) const
Definition: bigint.cpp:304
word word_at(size_t n) const
Definition: bigint.h:399
void divide(const BigInt &x, const BigInt &y_arg, BigInt &q, BigInt &r)
Definition: divide.cpp:58
static secure_vector< uint8_t > encode_locked(const BigInt &n, Base base=Binary)
Definition: big_code.cpp:68
bool is_space(char c)
Definition: charset.cpp:221
Definition: alg_id.cpp:13
size_t bytes() const
Definition: bigint.cpp:208
size_t encoded_size(Base base=Binary) const
Definition: bigint.cpp:230
const char * cast_uint8_ptr_to_char(const uint8_t *b)
Definition: mem_ops.h:136
char digit2char(uint8_t b)
Definition: charset.cpp:253
bool is_digit(char c)
Definition: charset.cpp:210
void binary_decode(const uint8_t buf[], size_t length)
Definition: bigint.cpp:314
static secure_vector< uint8_t > encode_1363(const BigInt &n, size_t bytes)
Definition: big_code.cpp:82
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88
static secure_vector< uint8_t > encode_fixed_length_int_pair(const BigInt &n1, const BigInt &n2, size_t bytes)
Definition: big_code.cpp:103
static std::vector< uint8_t > encode(const BigInt &n, Base base=Binary)
Definition: big_code.cpp:54
void set_sign(Sign sign)
Definition: bigint.h:449
static BigInt decode(const uint8_t buf[], size_t length, Base base=Binary)
Definition: big_code.cpp:114