Botan  1.10.9
big_code.cpp
Go to the documentation of this file.
1 /*
2 * BigInt Encoding/Decoding
3 * (C) 1999-2010 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
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(byte output[], const BigInt& n, Base base)
19  {
20  if(base == Binary)
21  n.binary_encode(output);
22  else if(base == Hexadecimal)
23  {
25  n.binary_encode(&binary[0]);
26 
27  hex_encode(reinterpret_cast<char*>(output),
28  &binary[0], binary.size());
29  }
30  else if(base == Octal)
31  {
32  BigInt copy = n;
33  const size_t output_size = n.encoded_size(Octal);
34  for(size_t j = 0; j != output_size; ++j)
35  {
36  output[output_size - 1 - j] =
37  Charset::digit2char(static_cast<byte>(copy % 8));
38 
39  copy /= 8;
40  }
41  }
42  else if(base == Decimal)
43  {
44  BigInt copy = n;
45  BigInt remainder;
46  copy.set_sign(Positive);
47  const size_t output_size = n.encoded_size(Decimal);
48  for(size_t j = 0; j != output_size; ++j)
49  {
50  divide(copy, 10, copy, remainder);
51  output[output_size - 1 - j] =
52  Charset::digit2char(static_cast<byte>(remainder.word_at(0)));
53  if(copy.is_zero())
54  break;
55  }
56  }
57  else
58  throw Invalid_Argument("Unknown BigInt encoding method");
59  }
60 
61 /*
62 * Encode a BigInt
63 */
65  {
66  SecureVector<byte> output(n.encoded_size(base));
67  encode(&output[0], n, base);
68  if(base != Binary)
69  for(size_t j = 0; j != output.size(); ++j)
70  if(output[j] == 0)
71  output[j] = '0';
72  return output;
73  }
74 
75 /*
76 * Encode a BigInt, with leading 0s if needed
77 */
79  {
80  const size_t n_bytes = n.bytes();
81  if(n_bytes > bytes)
82  throw Encoding_Error("encode_1363: n is too large to encode properly");
83 
84  const size_t leading_0s = bytes - n_bytes;
85 
86  SecureVector<byte> output(bytes);
87  encode(&output[leading_0s], n, Binary);
88  return output;
89  }
90 
91 /*
92 * Decode a BigInt
93 */
95  {
96  return BigInt::decode(&buf[0], buf.size(), base);
97  }
98 
99 /*
100 * Decode a BigInt
101 */
102 BigInt BigInt::decode(const byte buf[], size_t length, Base base)
103  {
104  BigInt r;
105  if(base == Binary)
106  r.binary_decode(buf, length);
107  else if(base == Hexadecimal)
108  {
109  SecureVector<byte> binary;
110 
111  if(length % 2)
112  {
113  // Handle lack of leading 0
114  const char buf0_with_leading_0[2] = { '0', static_cast<char>(buf[0]) };
115  binary = hex_decode(buf0_with_leading_0, 2);
116 
117  binary += hex_decode(reinterpret_cast<const char*>(&buf[1]),
118  length - 1,
119  false);
120  }
121  else
122  binary = hex_decode(reinterpret_cast<const char*>(buf),
123  length, false);
124 
125  r.binary_decode(&binary[0], binary.size());
126  }
127  else if(base == Decimal || base == Octal)
128  {
129  const size_t RADIX = ((base == Decimal) ? 10 : 8);
130  for(size_t j = 0; j != length; ++j)
131  {
132  if(Charset::is_space(buf[j]))
133  continue;
134 
135  if(!Charset::is_digit(buf[j]))
136  throw Invalid_Argument("BigInt::decode: "
137  "Invalid character in decimal input");
138 
139  byte x = Charset::char2digit(buf[j]);
140  if(x >= RADIX)
141  {
142  if(RADIX == 10)
143  throw Invalid_Argument("BigInt: Invalid decimal string");
144  else
145  throw Invalid_Argument("BigInt: Invalid octal string");
146  }
147 
148  r *= RADIX;
149  r += x;
150  }
151  }
152  else
153  throw Invalid_Argument("Unknown BigInt decoding method");
154  return r;
155  }
156 
157 }
size_t encoded_size(Base base=Binary) const
Definition: bigint.cpp:272
word word_at(size_t n) const
Definition: bigint.h:238
void binary_encode(byte buf[]) const
Definition: bigint.cpp:340
void divide(const BigInt &x, const BigInt &y_arg, BigInt &q, BigInt &r)
Definition: divide.cpp:34
BigInt n
Definition: numthry.cpp:26
size_t hex_decode(byte output[], const char input[], size_t input_length, size_t &input_consumed, bool ignore_ws)
Definition: hex.cpp:55
void binary_decode(const byte buf[], size_t length)
Definition: bigint.cpp:350
std::invalid_argument Invalid_Argument
Definition: exceptn.h:20
static SecureVector< byte > encode(const BigInt &n, Base base=Binary)
Definition: big_code.cpp:64
unsigned char byte
Definition: types.h:22
byte char2digit(char c)
Definition: charset.cpp:149
size_t size() const
Definition: secmem.h:29
bool is_digit(char c)
Definition: charset.cpp:128
bool is_space(char c)
Definition: charset.cpp:139
static BigInt decode(const byte buf[], size_t length, Base base=Binary)
Definition: big_code.cpp:102
BigInt r
Definition: numthry.cpp:26
bool is_zero() const
Definition: bigint.h:176
char digit2char(byte b)
Definition: charset.cpp:171
void set_sign(Sign sign)
Definition: bigint.cpp:291
static SecureVector< byte > encode_1363(const BigInt &n, size_t bytes)
Definition: big_code.cpp:78
GMP_MPZ base
Definition: gmp_powm.cpp:29
void hex_encode(char output[], const byte input[], size_t input_length, bool uppercase)
Definition: hex.cpp:14
size_t bytes() const
Definition: bigint.cpp:245