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
13namespace Botan {
14
15/*
16* Encode a BigInt
17*/
18void 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
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*/
102BigInt 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}
static SecureVector< byte > encode_1363(const BigInt &n, size_t bytes)
Definition big_code.cpp:78
static BigInt decode(const byte buf[], size_t length, Base base=Binary)
Definition big_code.cpp:102
void binary_encode(byte buf[]) const
Definition bigint.cpp:341
static SecureVector< byte > encode(const BigInt &n, Base base=Binary)
Definition big_code.cpp:64
word word_at(size_t n) const
Definition bigint.h:238
size_t encoded_size(Base base=Binary) const
Definition bigint.cpp:273
void binary_decode(const byte buf[], size_t length)
Definition bigint.cpp:351
bool is_zero() const
Definition bigint.h:176
size_t bytes() const
Definition bigint.cpp:246
void set_sign(Sign sign)
Definition bigint.cpp:292
size_t size() const
Definition secmem.h:29
bool is_space(char c)
Definition charset.cpp:139
byte char2digit(char c)
Definition charset.cpp:149
char digit2char(byte b)
Definition charset.cpp:171
bool is_digit(char c)
Definition charset.cpp:128
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 hex_encode(char output[], const byte input[], size_t input_length, bool uppercase)
Definition hex.cpp:14
std::invalid_argument Invalid_Argument
Definition exceptn.h:20
void divide(const BigInt &x, const BigInt &y_arg, BigInt &q, BigInt &r)
Definition divide.cpp:34
Encoding_Error(const std::string &name)
Definition exceptn.h:131