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