qca
big_code.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 namespace QCA {
00028
00029
00030
00031
00032
00033 }
00034 #include <botan/bigint.h>
00035 namespace QCA {
00036 }
00037 #include <botan/numthry.h>
00038 namespace QCA {
00039 }
00040 #include <botan/charset.h>
00041 namespace QCA {
00042 #ifndef BOTAN_MINIMAL_BIGINT
00043 }
00044 #include <botan/hex.h>
00045 namespace QCA {
00046 #endif
00047
00048 namespace Botan {
00049
00050
00051
00052
00053 void BigInt::encode(byte output[], const BigInt& n, Base base)
00054 {
00055 if(base == Binary)
00056 n.binary_encode(output);
00057 #ifndef BOTAN_MINIMAL_BIGINT
00058 else if(base == Hexadecimal)
00059 {
00060 SecureVector<byte> binary(n.encoded_size(Binary));
00061 n.binary_encode(binary);
00062 for(u32bit j = 0; j != binary.size(); ++j)
00063 Hex_Encoder::encode(binary[j], output + 2*j);
00064 }
00065 #endif
00066 else if(base == Octal)
00067 {
00068 BigInt copy = n;
00069 const u32bit output_size = n.encoded_size(Octal);
00070 for(u32bit j = 0; j != output_size; ++j)
00071 {
00072 output[output_size - 1 - j] = Charset::digit2char(copy % 8);
00073 copy /= 8;
00074 }
00075 }
00076 else if(base == Decimal)
00077 {
00078 BigInt copy = n;
00079 BigInt remainder;
00080 copy.set_sign(Positive);
00081 const u32bit output_size = n.encoded_size(Decimal);
00082 for(u32bit j = 0; j != output_size; ++j)
00083 {
00084 divide(copy, 10, copy, remainder);
00085 output[output_size - 1 - j] =
00086 Charset::digit2char(remainder.word_at(0));
00087 if(copy.is_zero())
00088 {
00089 if(j < output_size - 1)
00090 {
00091 int extra = output_size - 1 - j;
00092 memmove(output, output + extra, output_size - extra);
00093 memset(output + output_size - extra, 0, extra);
00094 }
00095 break;
00096 }
00097 }
00098 }
00099 else
00100 throw Invalid_Argument("Unknown BigInt encoding method");
00101 }
00102
00103
00104
00105
00106 SecureVector<byte> BigInt::encode(const BigInt& n, Base base)
00107 {
00108 SecureVector<byte> output(n.encoded_size(base));
00109 encode(output, n, base);
00110 if(base != Binary)
00111 for(u32bit j = 0; j != output.size(); ++j)
00112 if(output[j] == 0)
00113 output[j] = '0';
00114 return output;
00115 }
00116
00117
00118
00119
00120 SecureVector<byte> BigInt::encode_1363(const BigInt& n, u32bit bytes)
00121 {
00122 const u32bit n_bytes = n.bytes();
00123 if(n_bytes > bytes)
00124 throw Encoding_Error("encode_1363: n is too large to encode properly");
00125
00126 const u32bit leading_0s = bytes - n_bytes;
00127
00128 SecureVector<byte> output(bytes);
00129 encode(output + leading_0s, n, Binary);
00130 return output;
00131 }
00132
00133
00134
00135
00136 BigInt BigInt::decode(const MemoryRegion<byte>& buf, Base base)
00137 {
00138 return BigInt::decode(buf, buf.size(), base);
00139 }
00140
00141
00142
00143
00144 BigInt BigInt::decode(const byte buf[], u32bit length, Base base)
00145 {
00146 BigInt r;
00147 if(base == Binary)
00148 r.binary_decode(buf, length);
00149 #ifndef BOTAN_MINIMAL_BIGINT
00150 else if(base == Hexadecimal)
00151 {
00152 SecureVector<byte> hex;
00153 for(u32bit j = 0; j != length; ++j)
00154 if(Hex_Decoder::is_valid(buf[j]))
00155 hex.append(buf[j]);
00156
00157 u32bit offset = (hex.size() % 2);
00158 SecureVector<byte> binary(hex.size() / 2 + offset);
00159
00160 if(offset)
00161 {
00162 byte temp[2] = { '0', hex[0] };
00163 binary[0] = Hex_Decoder::decode(temp);
00164 }
00165
00166 for(u32bit j = offset; j != binary.size(); ++j)
00167 binary[j] = Hex_Decoder::decode(hex+2*j-offset);
00168 r.binary_decode(binary, binary.size());
00169 }
00170 #endif
00171 else if(base == Decimal || base == Octal)
00172 {
00173 const u32bit RADIX = ((base == Decimal) ? 10 : 8);
00174 for(u32bit j = 0; j != length; ++j)
00175 {
00176 byte x = Charset::char2digit(buf[j]);
00177 if(x >= RADIX)
00178 {
00179 if(RADIX == 10)
00180 throw Invalid_Argument("BigInt: Invalid decimal string");
00181 else
00182 throw Invalid_Argument("BigInt: Invalid octal string");
00183 }
00184
00185 r *= RADIX;
00186 r += x;
00187 }
00188 }
00189 else
00190 throw Invalid_Argument("Unknown BigInt decoding method");
00191 return r;
00192 }
00193
00194 }
00195 }