• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • KDE Support
  • Sitemap
  • Contact Us
 

qca

big_base.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright (C) 1999-2007 The Botan Project. All rights reserved.
00003 
00004 Redistribution and use in source and binary forms, for any use, with or without
00005 modification, is permitted provided that the following conditions are met:
00006 
00007 1. Redistributions of source code must retain the above copyright notice, this
00008 list of conditions, and the following disclaimer.
00009 
00010 2. Redistributions in binary form must reproduce the above copyright notice,
00011 this list of conditions, and the following disclaimer in the documentation
00012 and/or other materials provided with the distribution.
00013 
00014 THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
00015 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00016 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
00017 
00018 IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
00019 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00020 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00021 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00022 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
00023 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00024 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00025 */
00026 // LICENSEHEADER_END
00027 namespace QCA { // WRAPNS_LINE
00028 /*************************************************
00029 * BigInt Base Source File                        *
00030 * (C) 1999-2007 The Botan Project                *
00031 *************************************************/
00032 
00033 } // WRAPNS_LINE
00034 #include <botan/bigint.h>
00035 namespace QCA { // WRAPNS_LINE
00036 } // WRAPNS_LINE
00037 #include <botan/mp_core.h>
00038 namespace QCA { // WRAPNS_LINE
00039 } // WRAPNS_LINE
00040 #include <botan/bit_ops.h>
00041 namespace QCA { // WRAPNS_LINE
00042 } // WRAPNS_LINE
00043 #include <botan/parsing.h>
00044 namespace QCA { // WRAPNS_LINE
00045 } // WRAPNS_LINE
00046 #include <botan/util.h>
00047 namespace QCA { // WRAPNS_LINE
00048 
00049 namespace Botan {
00050 
00051 /*************************************************
00052 * Construct a BigInt from a regular number       *
00053 *************************************************/
00054 BigInt::BigInt(u64bit n)
00055    {
00056    set_sign(Positive);
00057 
00058    if(n == 0)
00059       return;
00060 
00061    const u32bit limbs_needed = sizeof(u64bit) / sizeof(word);
00062 
00063    reg.create(4*limbs_needed);
00064    for(u32bit j = 0; j != limbs_needed; ++j)
00065       reg[j] = (word)((n >> (j*MP_WORD_BITS)) & MP_WORD_MASK);
00066    }
00067 
00068 /*************************************************
00069 * Construct a BigInt of the specified size       *
00070 *************************************************/
00071 BigInt::BigInt(Sign s, u32bit size)
00072    {
00073    reg.create(round_up(size, 8));
00074    signedness = s;
00075    }
00076 
00077 /*************************************************
00078 * Construct a BigInt from a "raw" BigInt         *
00079 *************************************************/
00080 BigInt::BigInt(const BigInt& b)
00081    {
00082    const u32bit b_words = b.sig_words();
00083 
00084    if(b_words)
00085       {
00086       reg.create(round_up(b_words, 8));
00087       reg.copy(b.data(), b_words);
00088       set_sign(b.sign());
00089       }
00090    else
00091       {
00092       reg.create(2);
00093       set_sign(Positive);
00094       }
00095    }
00096 
00097 /*************************************************
00098 * Construct a BigInt from a string               *
00099 *************************************************/
00100 BigInt::BigInt(const std::string& str)
00101    {
00102    Base base = Decimal;
00103    u32bit markers = 0;
00104    bool negative = false;
00105    if(str.length() > 0 && str[0] == '-') { markers += 1; negative = true; }
00106 
00107    if(str.length() > markers + 2 && str[markers    ] == '0' &&
00108                                     str[markers + 1] == 'x')
00109       { markers += 2; base = Hexadecimal; }
00110    else if(str.length() > markers + 1 && str[markers] == '0')
00111       { markers += 1; base = Octal; }
00112 
00113    *this = decode((const byte*)str.data() + markers,
00114                   str.length() - markers, base);
00115 
00116    if(negative) set_sign(Negative);
00117    else         set_sign(Positive);
00118    }
00119 
00120 /*************************************************
00121 * Construct a BigInt from an encoded BigInt      *
00122 *************************************************/
00123 BigInt::BigInt(const byte input[], u32bit length, Base base)
00124    {
00125    set_sign(Positive);
00126    *this = decode(input, length, base);
00127    }
00128 
00129 /*************************************************
00130 * Swap this BigInt with another                  *
00131 *************************************************/
00132 void BigInt::swap(BigInt& other)
00133    {
00134    std::swap(reg, other.reg);
00135    std::swap(signedness, other.signedness);
00136    }
00137 
00138 /*************************************************
00139 * Grow the internal storage                      *
00140 *************************************************/
00141 void BigInt::grow_reg(u32bit n) const
00142    {
00143    reg.grow_to(round_up(size() + n, 8));
00144    }
00145 
00146 /*************************************************
00147 * Grow the internal storage                      *
00148 *************************************************/
00149 void BigInt::grow_to(u32bit n) const
00150    {
00151    if(n > size())
00152       reg.grow_to(round_up(n, 8));
00153    }
00154 
00155 /*************************************************
00156 * Comparison Function                            *
00157 *************************************************/
00158 s32bit BigInt::cmp(const BigInt& n, bool check_signs) const
00159    {
00160    if(check_signs)
00161       {
00162       if(n.is_positive() && this->is_negative()) return -1;
00163       if(n.is_negative() && this->is_positive()) return 1;
00164       if(n.is_negative() && this->is_negative())
00165          return (-bigint_cmp(data(), sig_words(), n.data(), n.sig_words()));
00166       }
00167    return bigint_cmp(data(), sig_words(), n.data(), n.sig_words());
00168    }
00169 
00170 /*************************************************
00171 * Convert this number to a u32bit, if possible   *
00172 *************************************************/
00173 u32bit BigInt::to_u32bit() const
00174    {
00175    if(is_negative())
00176       throw Encoding_Error("BigInt::to_u32bit: Number is negative");
00177    if(bits() >= 32)
00178       throw Encoding_Error("BigInt::to_u32bit: Number is too big to convert");
00179 
00180    u32bit out = 0;
00181    for(u32bit j = 0; j != 4; ++j)
00182       out = (out << 8) | byte_at(3-j);
00183    return out;
00184    }
00185 
00186 /*************************************************
00187 * Return byte n of this number                   *
00188 *************************************************/
00189 byte BigInt::byte_at(u32bit n) const
00190    {
00191    const u32bit WORD_BYTES = sizeof(word);
00192    u32bit word_num = n / WORD_BYTES, byte_num = n % WORD_BYTES;
00193    if(word_num >= size())
00194       return 0;
00195    else
00196       return get_byte(WORD_BYTES - byte_num - 1, reg[word_num]);
00197    }
00198 
00199 /*************************************************
00200 * Return bit n of this number                    *
00201 *************************************************/
00202 bool BigInt::get_bit(u32bit n) const
00203    {
00204    return ((word_at(n / MP_WORD_BITS) >> (n % MP_WORD_BITS)) & 1);
00205    }
00206 
00207 /*************************************************
00208 * Return bits {offset...offset+length}           *
00209 *************************************************/
00210 u32bit BigInt::get_substring(u32bit offset, u32bit length) const
00211    {
00212    if(length > 32)
00213       throw Invalid_Argument("BigInt::get_substring: Substring size too big");
00214 
00215    u64bit piece = 0;
00216    for(u32bit j = 0; j != 8; ++j)
00217       piece = (piece << 8) | byte_at((offset / 8) + (7-j));
00218 
00219    u64bit mask = (1 << length) - 1;
00220    u32bit shift = (offset % 8);
00221 
00222    return static_cast<u32bit>((piece >> shift) & mask);
00223    }
00224 
00225 /*************************************************
00226 * Set bit number n                               *
00227 *************************************************/
00228 void BigInt::set_bit(u32bit n)
00229    {
00230    const u32bit which = n / MP_WORD_BITS;
00231    const word mask = (word)1 << (n % MP_WORD_BITS);
00232    if(which >= size()) grow_to(which + 1);
00233    reg[which] |= mask;
00234    }
00235 
00236 /*************************************************
00237 * Clear bit number n                             *
00238 *************************************************/
00239 void BigInt::clear_bit(u32bit n)
00240    {
00241    const u32bit which = n / MP_WORD_BITS;
00242    const word mask = (word)1 << (n % MP_WORD_BITS);
00243    if(which < size())
00244       reg[which] &= ~mask;
00245    }
00246 
00247 /*************************************************
00248 * Clear all but the lowest n bits                *
00249 *************************************************/
00250 void BigInt::mask_bits(u32bit n)
00251    {
00252    if(n == 0) { clear(); return; }
00253    if(n >= bits()) return;
00254 
00255    const u32bit top_word = n / MP_WORD_BITS;
00256    const word mask = ((word)1 << (n % MP_WORD_BITS)) - 1;
00257 
00258    if(top_word < size())
00259       for(u32bit j = top_word + 1; j != size(); ++j)
00260          reg[j] = 0;
00261 
00262    reg[top_word] &= mask;
00263    }
00264 
00265 /*************************************************
00266 * Count the significant words                    *
00267 *************************************************/
00268 u32bit BigInt::sig_words() const
00269    {
00270    const word* x = data();
00271    u32bit top_set = size();
00272 
00273    while(top_set >= 4)
00274       {
00275       word sum = x[top_set-1] | x[top_set-2] | x[top_set-3] | x[top_set-4];
00276       if(sum) break;
00277       else    top_set -= 4;
00278       }
00279    while(top_set && (x[top_set-1] == 0))
00280       top_set--;
00281    return top_set;
00282    }
00283 
00284 /*************************************************
00285 * Count how many bytes are being used            *
00286 *************************************************/
00287 u32bit BigInt::bytes() const
00288    {
00289    return (bits() + 7) / 8;
00290    }
00291 
00292 /*************************************************
00293 * Count how many bits are being used             *
00294 *************************************************/
00295 u32bit BigInt::bits() const
00296    {
00297    if(sig_words() == 0)
00298       return 0;
00299 
00300    u32bit full_words = sig_words() - 1, top_bits = MP_WORD_BITS;
00301    word top_word = word_at(full_words), mask = MP_WORD_TOP_BIT;
00302 
00303    while(top_bits && ((top_word & mask) == 0))
00304       { mask >>= 1; top_bits--; }
00305 
00306    return (full_words * MP_WORD_BITS + top_bits);
00307    }
00308 
00309 /*************************************************
00310 * Calcluate the size in a certain base           *
00311 *************************************************/
00312 u32bit BigInt::encoded_size(Base base) const
00313    {
00314    static const double LOG_2_BASE_10 = 0.30102999566;
00315 
00316    if(base == Binary)
00317       return bytes();
00318    else if(base == Hexadecimal)
00319       return 2*bytes();
00320    else if(base == Octal)
00321       return ((bits() + 2) / 3);
00322    else if(base == Decimal)
00323       return (u32bit)((bits() * LOG_2_BASE_10) + 1);
00324    else
00325       throw Invalid_Argument("Unknown base for BigInt encoding");
00326    }
00327 
00328 /*************************************************
00329 * Return true if this number is zero             *
00330 *************************************************/
00331 bool BigInt::is_zero() const
00332    {
00333    for(u32bit j = 0; j != size(); ++j)
00334       if(reg[j]) return false;
00335    return true;
00336    }
00337 
00338 /*************************************************
00339 * Set the sign                                   *
00340 *************************************************/
00341 void BigInt::set_sign(Sign s)
00342    {
00343    if(is_zero())
00344       signedness = Positive;
00345    else
00346       signedness = s;
00347    }
00348 
00349 /*************************************************
00350 * Reverse the value of the sign flag             *
00351 *************************************************/
00352 void BigInt::flip_sign()
00353    {
00354    set_sign(reverse_sign());
00355    }
00356 
00357 /*************************************************
00358 * Return the opposite value of the current sign  *
00359 *************************************************/
00360 BigInt::Sign BigInt::reverse_sign() const
00361    {
00362    if(sign() == Positive)
00363       return Negative;
00364    return Positive;
00365    }
00366 
00367 /*************************************************
00368 * Return the negation of this number             *
00369 *************************************************/
00370 BigInt BigInt::operator-() const
00371    {
00372    BigInt x = (*this);
00373    x.flip_sign();
00374    return x;
00375    }
00376 
00377 /*************************************************
00378 * Return the absolute value of this number       *
00379 *************************************************/
00380 BigInt BigInt::abs() const
00381    {
00382    BigInt x = (*this);
00383    x.set_sign(Positive);
00384    return x;
00385    }
00386 
00387 /*************************************************
00388 * Encode this number into bytes                  *
00389 *************************************************/
00390 void BigInt::binary_encode(byte output[]) const
00391    {
00392    const u32bit sig_bytes = bytes();
00393    for(u32bit j = 0; j != sig_bytes; ++j)
00394       output[sig_bytes-j-1] = byte_at(j);
00395    }
00396 
00397 /*************************************************
00398 * Set this number to the value in buf            *
00399 *************************************************/
00400 void BigInt::binary_decode(const byte buf[], u32bit length)
00401    {
00402    const u32bit WORD_BYTES = sizeof(word);
00403    reg.create(round_up((length / WORD_BYTES) + 1, 8));
00404 
00405    for(u32bit j = 0; j != length / WORD_BYTES; ++j)
00406       {
00407       u32bit top = length - WORD_BYTES*j;
00408       for(u32bit k = WORD_BYTES; k > 0; --k)
00409          reg[j] = (reg[j] << 8) | buf[top - k];
00410       }
00411    for(u32bit j = 0; j != length % WORD_BYTES; ++j)
00412       reg[length / WORD_BYTES] = (reg[length / WORD_BYTES] << 8) | buf[j];
00413    }
00414 
00415 }
00416 } // WRAPNS_LINE

qca

Skip menu "qca"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

KDE Support

Skip menu "KDE Support"
  • akonadi
  • Decibel
  • grantlee
  • kdewin
  • phonon
  •     Backend
  • polkit-qt
  • qca
  • qimageblitz
  • soprano
  • strigi
  •     searchclient
  •     streamanalyzer
  •     streams
Generated for KDE Support by doxygen 1.5.9-20090814
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal