Warning, file /libraries/qca/src/botantools/botan/big_code.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002 Copyright (C) 1999-2007 The Botan Project. All rights reserved.
0003 
0004 Redistribution and use in source and binary forms, for any use, with or without
0005 modification, is permitted provided that the following conditions are met:
0006 
0007 1. Redistributions of source code must retain the above copyright notice, this
0008 list of conditions, and the following disclaimer.
0009 
0010 2. Redistributions in binary form must reproduce the above copyright notice,
0011 this list of conditions, and the following disclaimer in the documentation
0012 and/or other materials provided with the distribution.
0013 
0014 THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
0015 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
0016 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
0017 
0018 IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
0019 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
0020 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0021 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
0022 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
0023 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
0024 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0025 */
0026 // LICENSEHEADER_END
0027 namespace QCA { // WRAPNS_LINE
0028 /*************************************************
0029  * BigInt Encoding/Decoding Source File           *
0030  * (C) 1999-2007 The Botan Project                *
0031  *************************************************/
0032 
0033 } // WRAPNS_LINE
0034 #include <botan/bigint.h>
0035 namespace QCA { // WRAPNS_LINE
0036 } // WRAPNS_LINE
0037 #include <botan/numthry.h>
0038 namespace QCA { // WRAPNS_LINE
0039 } // WRAPNS_LINE
0040 #include <botan/charset.h>
0041 namespace QCA { // WRAPNS_LINE
0042 #ifndef BOTAN_MINIMAL_BIGINT
0043 } // WRAPNS_LINE
0044 #include <botan/hex.h>
0045 namespace QCA { // WRAPNS_LINE
0046 #endif
0047 
0048 namespace Botan {
0049 
0050 /*************************************************
0051  * Encode a BigInt                                *
0052  *************************************************/
0053 void BigInt::encode(byte output[], const BigInt &n, Base base)
0054 {
0055     if (base == Binary)
0056         n.binary_encode(output);
0057 #ifndef BOTAN_MINIMAL_BIGINT
0058     else if (base == Hexadecimal) {
0059         SecureVector<byte> binary(n.encoded_size(Binary));
0060         n.binary_encode(binary);
0061         for (u32bit j = 0; j != binary.size(); ++j)
0062             Hex_Encoder::encode(binary[j], output + 2 * j);
0063     }
0064 #endif
0065     else if (base == Octal) {
0066         BigInt       copy        = n;
0067         const u32bit output_size = n.encoded_size(Octal);
0068         for (u32bit j = 0; j != output_size; ++j) {
0069             output[output_size - 1 - j] = Charset::digit2char(copy % 8);
0070             copy /= 8;
0071         }
0072     } else if (base == Decimal) {
0073         BigInt copy = n;
0074         BigInt remainder;
0075         copy.set_sign(Positive);
0076         const u32bit output_size = n.encoded_size(Decimal);
0077         for (u32bit j = 0; j != output_size; ++j) {
0078             divide(copy, 10, copy, remainder);
0079             output[output_size - 1 - j] = Charset::digit2char(remainder.word_at(0));
0080             if (copy.is_zero()) {
0081                 if (j < output_size - 1) {
0082                     int extra = output_size - 1 - j;
0083                     memmove(output, output + extra, output_size - extra);
0084                     memset(output + output_size - extra, 0, extra);
0085                 }
0086                 break;
0087             }
0088         }
0089     } else
0090         throw Invalid_Argument("Unknown BigInt encoding method");
0091 }
0092 
0093 /*************************************************
0094  * Encode a BigInt                                *
0095  *************************************************/
0096 SecureVector<byte> BigInt::encode(const BigInt &n, Base base)
0097 {
0098     SecureVector<byte> output(n.encoded_size(base));
0099     encode(output, n, base);
0100     if (base != Binary)
0101         for (u32bit j = 0; j != output.size(); ++j)
0102             if (output[j] == 0)
0103                 output[j] = '0';
0104     return output;
0105 }
0106 
0107 /*************************************************
0108  * Encode a BigInt, with leading 0s if needed     *
0109  *************************************************/
0110 SecureVector<byte> BigInt::encode_1363(const BigInt &n, u32bit bytes)
0111 {
0112     const u32bit n_bytes = n.bytes();
0113     if (n_bytes > bytes)
0114         throw Encoding_Error("encode_1363: n is too large to encode properly");
0115 
0116     const u32bit leading_0s = bytes - n_bytes;
0117 
0118     SecureVector<byte> output(bytes);
0119     encode(output + leading_0s, n, Binary);
0120     return output;
0121 }
0122 
0123 /*************************************************
0124  * Decode a BigInt                                *
0125  *************************************************/
0126 BigInt BigInt::decode(const MemoryRegion<byte> &buf, Base base)
0127 {
0128     return BigInt::decode(buf, buf.size(), base);
0129 }
0130 
0131 /*************************************************
0132  * Decode a BigInt                                *
0133  *************************************************/
0134 BigInt BigInt::decode(const byte buf[], u32bit length, Base base)
0135 {
0136     BigInt r;
0137     if (base == Binary)
0138         r.binary_decode(buf, length);
0139 #ifndef BOTAN_MINIMAL_BIGINT
0140     else if (base == Hexadecimal) {
0141         SecureVector<byte> hex;
0142         for (u32bit j = 0; j != length; ++j)
0143             if (Hex_Decoder::is_valid(buf[j]))
0144                 hex.append(buf[j]);
0145 
0146         u32bit             offset = (hex.size() % 2);
0147         SecureVector<byte> binary(hex.size() / 2 + offset);
0148 
0149         if (offset) {
0150             byte temp[2] = {'0', hex[0]};
0151             binary[0]    = Hex_Decoder::decode(temp);
0152         }
0153 
0154         for (u32bit j = offset; j != binary.size(); ++j)
0155             binary[j] = Hex_Decoder::decode(hex + 2 * j - offset);
0156         r.binary_decode(binary, binary.size());
0157     }
0158 #endif
0159     else if (base == Decimal || base == Octal) {
0160         const u32bit RADIX = ((base == Decimal) ? 10 : 8);
0161         for (u32bit j = 0; j != length; ++j) {
0162             byte x = Charset::char2digit(buf[j]);
0163             if (x >= RADIX) {
0164                 if (RADIX == 10)
0165                     throw Invalid_Argument("BigInt: Invalid decimal string");
0166                 else
0167                     throw Invalid_Argument("BigInt: Invalid octal string");
0168             }
0169 
0170             r *= RADIX;
0171             r += x;
0172         }
0173     } else
0174         throw Invalid_Argument("Unknown BigInt decoding method");
0175     return r;
0176 }
0177 
0178 }
0179 } // WRAPNS_LINE