Botan 1.10.17

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 {
24 SecureVector<byte> binary(n.encoded_size(Binary));
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 */
64 SecureVector<byte> BigInt::encode(const BigInt& n, Base base)
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 */
78 SecureVector<byte> BigInt::encode_1363(const BigInt& n, size_t bytes)
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 */
94 BigInt BigInt::decode(const MemoryRegion<byte>& buf, Base base)
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 }
Botan::BigInt::Hexadecimal
Definition: bigint.h:28
Botan::divide
void divide(const BigInt &x, const BigInt &y_arg, BigInt &q, BigInt &r)
Definition: divide.cpp:34
Botan::BigInt
Definition: bigint.h:22
Botan::BigInt::Positive
Definition: bigint.h:33
Botan::BigInt::Decimal
Definition: bigint.h:28
Botan::hex_decode
size_t hex_decode(byte output[], const char input[], size_t input_length, size_t &input_consumed, bool ignore_ws)
Definition: hex.cpp:55
Botan::BigInt::is_zero
bool is_zero() const
Definition: bigint.h:176
Botan::Invalid_Argument
std::invalid_argument Invalid_Argument
Definition: exceptn.h:20
Botan::BigInt::encode
static SecureVector< byte > encode(const BigInt &n, Base base=Binary)
Definition: big_code.cpp:64
Botan::BigInt::word_at
word word_at(size_t n) const
Definition: bigint.h:238
Botan::byte
unsigned char byte
Definition: types.h:22
Botan::Charset::char2digit
byte char2digit(char c)
Definition: charset.cpp:149
Botan::BigInt::Octal
Definition: bigint.h:28
Botan::MemoryRegion< byte >
Botan
Definition: algo_base.h:14
Botan::BigInt::bytes
size_t bytes() const
Definition: bigint.cpp:246
Botan::BigInt::Binary
Definition: bigint.h:28
Botan::Charset::is_digit
bool is_digit(char c)
Definition: charset.cpp:128
Botan::BigInt::Base
Base
Definition: bigint.h:28
Botan::MemoryRegion::size
size_t size() const
Definition: secmem.h:29
Botan::Charset::is_space
bool is_space(char c)
Definition: charset.cpp:139
Botan::BigInt::decode
static BigInt decode(const byte buf[], size_t length, Base base=Binary)
Definition: big_code.cpp:102
Botan::SecureVector< byte >
Botan::Charset::digit2char
char digit2char(byte b)
Definition: charset.cpp:171
Botan::BigInt::set_sign
void set_sign(Sign sign)
Definition: bigint.cpp:292
Botan::BigInt::encode_1363
static SecureVector< byte > encode_1363(const BigInt &n, size_t bytes)
Definition: big_code.cpp:78
Botan::Encoding_Error
Definition: exceptn.h:129
Botan::hex_encode
void hex_encode(char output[], const byte input[], size_t input_length, bool uppercase)
Definition: hex.cpp:14