1/*
2Copyright (C) 1999-2007 The Botan Project. All rights reserved.
3
4Redistribution and use in source and binary forms, for any use, with or without
5modification, is permitted provided that the following conditions are met:
6
71. Redistributions of source code must retain the above copyright notice, this
8list of conditions, and the following disclaimer.
9
102. Redistributions in binary form must reproduce the above copyright notice,
11this list of conditions, and the following disclaimer in the documentation
12and/or other materials provided with the distribution.
13
14THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
15WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
17
18IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
19INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
23OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*/
26// LICENSEHEADER_END
27namespace QCA { // WRAPNS_LINE
28/*************************************************
29 * BigInt Encoding/Decoding Source File *
30 * (C) 1999-2007 The Botan Project *
31 *************************************************/
32
33} // WRAPNS_LINE
34#include <botan/bigint.h>
35namespace QCA { // WRAPNS_LINE
36} // WRAPNS_LINE
37#include <botan/numthry.h>
38namespace QCA { // WRAPNS_LINE
39} // WRAPNS_LINE
40#include <botan/charset.h>
41namespace QCA { // WRAPNS_LINE
42#ifndef BOTAN_MINIMAL_BIGINT
43} // WRAPNS_LINE
44#include <botan/hex.h>
45namespace QCA { // WRAPNS_LINE
46#endif
47
48namespace Botan {
49
50/*************************************************
51 * Encode a BigInt *
52 *************************************************/
53void BigInt::encode(byte output[], const BigInt &n, Base base)
54{
55 if (base == Binary)
56 n.binary_encode(output);
57#ifndef BOTAN_MINIMAL_BIGINT
58 else if (base == Hexadecimal) {
59 SecureVector<byte> binary(n.encoded_size(Binary));
60 n.binary_encode(binary);
61 for (u32bit j = 0; j != binary.size(); ++j)
62 Hex_Encoder::encode(binary[j], output + 2 * j);
63 }
64#endif
65 else if (base == Octal) {
66 BigInt copy = n;
67 const u32bit output_size = n.encoded_size(Octal);
68 for (u32bit j = 0; j != output_size; ++j) {
69 output[output_size - 1 - j] = Charset::digit2char(copy % 8);
70 copy /= 8;
71 }
72 } else if (base == Decimal) {
73 BigInt copy = n;
74 BigInt remainder;
75 copy.set_sign(Positive);
76 const u32bit output_size = n.encoded_size(Decimal);
77 for (u32bit j = 0; j != output_size; ++j) {
78 divide(copy, 10, copy, remainder);
79 output[output_size - 1 - j] = Charset::digit2char(remainder.word_at(n: 0));
80 if (copy.is_zero()) {
81 if (j < output_size - 1) {
82 int extra = output_size - 1 - j;
83 memmove(dest: output, src: output + extra, n: output_size - extra);
84 memset(s: output + output_size - extra, c: 0, n: extra);
85 }
86 break;
87 }
88 }
89 } else
90 throw Invalid_Argument("Unknown BigInt encoding method");
91}
92
93/*************************************************
94 * Encode a BigInt *
95 *************************************************/
96SecureVector<byte> BigInt::encode(const BigInt &n, Base base)
97{
98 SecureVector<byte> output(n.encoded_size(base));
99 encode(output, n, base);
100 if (base != Binary)
101 for (u32bit j = 0; j != output.size(); ++j)
102 if (output[j] == 0)
103 output[j] = '0';
104 return output;
105}
106
107/*************************************************
108 * Encode a BigInt, with leading 0s if needed *
109 *************************************************/
110SecureVector<byte> BigInt::encode_1363(const BigInt &n, u32bit bytes)
111{
112 const u32bit n_bytes = n.bytes();
113 if (n_bytes > bytes)
114 throw Encoding_Error("encode_1363: n is too large to encode properly");
115
116 const u32bit leading_0s = bytes - n_bytes;
117
118 SecureVector<byte> output(bytes);
119 encode(output: output + leading_0s, n, base: Binary);
120 return output;
121}
122
123/*************************************************
124 * Decode a BigInt *
125 *************************************************/
126BigInt BigInt::decode(const MemoryRegion<byte> &buf, Base base)
127{
128 return BigInt::decode(buf, buf.size(), base);
129}
130
131/*************************************************
132 * Decode a BigInt *
133 *************************************************/
134BigInt BigInt::decode(const byte buf[], u32bit length, Base base)
135{
136 BigInt r;
137 if (base == Binary)
138 r.binary_decode(buf, length);
139#ifndef BOTAN_MINIMAL_BIGINT
140 else if (base == Hexadecimal) {
141 SecureVector<byte> hex;
142 for (u32bit j = 0; j != length; ++j)
143 if (Hex_Decoder::is_valid(buf[j]))
144 hex.append(buf[j]);
145
146 u32bit offset = (hex.size() % 2);
147 SecureVector<byte> binary(hex.size() / 2 + offset);
148
149 if (offset) {
150 byte temp[2] = {'0', hex[0]};
151 binary[0] = Hex_Decoder::decode(temp);
152 }
153
154 for (u32bit j = offset; j != binary.size(); ++j)
155 binary[j] = Hex_Decoder::decode(hex + 2 * j - offset);
156 r.binary_decode(binary, binary.size());
157 }
158#endif
159 else if (base == Decimal || base == Octal) {
160 const u32bit RADIX = ((base == Decimal) ? 10 : 8);
161 for (u32bit j = 0; j != length; ++j) {
162 byte x = Charset::char2digit(buf[j]);
163 if (x >= RADIX) {
164 if (RADIX == 10)
165 throw Invalid_Argument("BigInt: Invalid decimal string");
166 else
167 throw Invalid_Argument("BigInt: Invalid octal string");
168 }
169
170 r *= RADIX;
171 r += x;
172 }
173 } else
174 throw Invalid_Argument("Unknown BigInt decoding method");
175 return r;
176}
177
178}
179} // WRAPNS_LINE
180

source code of qca/src/botantools/botan/big_code.cpp