2
Copyright (C) 1999-2007 The Botan Project. All rights reserved.
4
Redistribution and use in source and binary forms, for any use, with or without
5
modification, is permitted provided that the following conditions are met:
7
1. Redistributions of source code must retain the above copyright notice, this
8
list of conditions, and the following disclaimer.
10
2. Redistributions in binary form must reproduce the above copyright notice,
11
this list of conditions, and the following disclaimer in the documentation
12
and/or other materials provided with the distribution.
14
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
15
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
18
IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
19
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
23
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
namespace QCA { // WRAPNS_LINE
28
/*************************************************
29
* BigInt Encoding/Decoding Source File *
30
* (C) 1999-2007 The Botan Project *
31
*************************************************/
34
#include <botan/bigint.h>
35
namespace QCA { // WRAPNS_LINE
37
#include <botan/numthry.h>
38
namespace QCA { // WRAPNS_LINE
40
#include <botan/charset.h>
41
namespace QCA { // WRAPNS_LINE
42
#ifndef BOTAN_MINIMAL_BIGINT
44
#include <botan/hex.h>
45
namespace QCA { // WRAPNS_LINE
50
/*************************************************
52
*************************************************/
53
void BigInt::encode(byte output[], const BigInt& n, Base base)
56
n.binary_encode(output);
57
#ifndef BOTAN_MINIMAL_BIGINT
58
else if(base == Hexadecimal)
60
SecureVector<byte> binary(n.encoded_size(Binary));
61
n.binary_encode(binary);
62
for(u32bit j = 0; j != binary.size(); ++j)
63
Hex_Encoder::encode(binary[j], output + 2*j);
66
else if(base == Octal)
69
const u32bit output_size = n.encoded_size(Octal);
70
for(u32bit j = 0; j != output_size; ++j)
72
output[output_size - 1 - j] = Charset::digit2char(copy % 8);
76
else if(base == Decimal)
80
copy.set_sign(Positive);
81
const u32bit output_size = n.encoded_size(Decimal);
82
for(u32bit j = 0; j != output_size; ++j)
84
divide(copy, 10, copy, remainder);
85
output[output_size - 1 - j] =
86
Charset::digit2char(remainder.word_at(0));
89
if(j < output_size - 1)
91
int extra = output_size - 1 - j;
92
memmove(output, output + extra, output_size - extra);
93
memset(output + output_size - extra, 0, extra);
100
throw Invalid_Argument("Unknown BigInt encoding method");
103
/*************************************************
105
*************************************************/
106
SecureVector<byte> BigInt::encode(const BigInt& n, Base base)
108
SecureVector<byte> output(n.encoded_size(base));
109
encode(output, n, base);
111
for(u32bit j = 0; j != output.size(); ++j)
117
/*************************************************
118
* Encode a BigInt, with leading 0s if needed *
119
*************************************************/
120
SecureVector<byte> BigInt::encode_1363(const BigInt& n, u32bit bytes)
122
const u32bit n_bytes = n.bytes();
124
throw Encoding_Error("encode_1363: n is too large to encode properly");
126
const u32bit leading_0s = bytes - n_bytes;
128
SecureVector<byte> output(bytes);
129
encode(output + leading_0s, n, Binary);
133
/*************************************************
135
*************************************************/
136
BigInt BigInt::decode(const MemoryRegion<byte>& buf, Base base)
138
return BigInt::decode(buf, buf.size(), base);
141
/*************************************************
143
*************************************************/
144
BigInt BigInt::decode(const byte buf[], u32bit length, Base base)
148
r.binary_decode(buf, length);
149
#ifndef BOTAN_MINIMAL_BIGINT
150
else if(base == Hexadecimal)
152
SecureVector<byte> hex;
153
for(u32bit j = 0; j != length; ++j)
154
if(Hex_Decoder::is_valid(buf[j]))
157
u32bit offset = (hex.size() % 2);
158
SecureVector<byte> binary(hex.size() / 2 + offset);
162
byte temp[2] = { '0', hex[0] };
163
binary[0] = Hex_Decoder::decode(temp);
166
for(u32bit j = offset; j != binary.size(); ++j)
167
binary[j] = Hex_Decoder::decode(hex+2*j-offset);
168
r.binary_decode(binary, binary.size());
171
else if(base == Decimal || base == Octal)
173
const u32bit RADIX = ((base == Decimal) ? 10 : 8);
174
for(u32bit j = 0; j != length; ++j)
176
byte x = Charset::char2digit(buf[j]);
180
throw Invalid_Argument("BigInt: Invalid decimal string");
182
throw Invalid_Argument("BigInt: Invalid octal string");
190
throw Invalid_Argument("Unknown BigInt decoding method");