cryptopp.cpp

Go to the documentation of this file.
00001 /**
00002  * \file cryptopp.cpp Subset of Crypto++ library, implementation
00003  *
00004  * This file contains a subset of the Crypto++ library (version 5.2.1), with
00005  * kind permission from Wei Dai. Please note that this file should not reflect
00006  * on the real Crypto++ library in any way, as this file been greatly mangled to
00007  * reduce the code-size, since HydraNode only makes use of RSA classes (for
00008  * Secure Identification)
00009  *
00010  * For the full Crypto++ library, please refer to the official Crypto++ website,
00011  * which can be found at http://www.cryptopp.com
00012  */
00013 
00014 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00015 
00016 //
00017 // Compilation Copyright (c) 1995-2004 by Wei Dai.  All rights reserved.
00018 // This copyright applies only to this software distribution package
00019 // as a compilation, and does not imply a copyright on any particular
00020 // file in the package.
00021 //
00022 // The following files are copyrighted by their respective original authors,
00023 // and their use is subject to additional licenses included in these files.
00024 //
00025 // mars.cpp - Copyright 1998 Brian Gladman.
00026 
00027 // All other files in this compilation are placed in the public domain by
00028 // Wei Dai and other contributors.
00029 //
00030 // I would like to thank the following authors for placing their works into
00031 // the public domain:
00032 //
00033 // Joan Daemen - 3way.cpp
00034 // Leonard Janke - cast.cpp, seal.cpp
00035 // Steve Reid - cast.cpp
00036 // Phil Karn - des.cpp
00037 // Michael Paul Johnson - diamond.cpp
00038 // Andrew M. Kuchling - md2.cpp, md4.cpp
00039 // Colin Plumb - md5.cpp, md5mac.cpp
00040 // Seal Woods - rc6.cpp
00041 // Chris Morgan - rijndael.cpp
00042 // Paulo Baretto - rijndael.cpp, skipjack.cpp, square.cpp
00043 // Richard De Moliner - safer.cpp
00044 // Matthew Skala - twofish.cpp
00045 // Kevin Springle - camellia.cpp, shacal2.cpp, ttmac.cpp, whrlpool.cpp, ripemd.cpp
00046 //
00047 // Permission to use, copy, modify, and distribute this compilation for
00048 // any purpose, including commercial applications, is hereby granted
00049 // without fee, subject to the following restrictions:
00050 //
00051 // 1. Any copy or modification of this compilation in any form, except
00052 // in object code form as part of an application software, must include
00053 // the above copyright notice and this license.
00054 //
00055 // 2. Users of this software agree that any modification or extension
00056 // they provide to Wei Dai will be considered public domain and not
00057 // copyrighted unless it includes an explicit copyright notice.
00058 //
00059 // 3. Wei Dai makes no warranty or representation that the operation of the
00060 // software in this compilation will be error-free, and Wei Dai is under no
00061 // obligation to provide any services, by way of maintenance, update, or
00062 // otherwise.  THE SOFTWARE AND ANY DOCUMENTATION ARE PROVIDED "AS IS"
00063 // WITHOUT EXPRESS OR IMPLIED WARRANTY INCLUDING, BUT NOT LIMITED TO,
00064 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00065 // PURPOSE. IN NO EVENT WILL WEI DAI OR ANY OTHER CONTRIBUTOR BE LIABLE FOR
00066 // DIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES, EVEN IF
00067 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
00068 //
00069 // 4. Users will not use Wei Dai or any other contributor's name in any
00070 // publicity or advertising, without prior written consent in each case.
00071 //
00072 // 5. Export of this software from the United States may require a
00073 // specific license from the United States Government.  It is the
00074 // responsibility of any person or organization contemplating export
00075 // to obtain such a license before exporting.
00076 //
00077 // 6. Certain parts of this software may be protected by patents.  It
00078 // is the users' responsibility to obtain the appropriate
00079 // licenses before using those parts.
00080 //
00081 // If this compilation is used in object code form in an application
00082 // software, acknowledgement of the author is not required but would be
00083 // appreciated. The contribution of any useful modifications or extensions
00084 // to Wei Dai is not required but would also be appreciated.
00085 //
00086 ////////////////////////////////////////////////////////////////////////////////
00087 
00088 #include "cryptopp.h"
00089 
00090 ////////////////////////////////////////////////////////////////////////////////
00091 #ifndef CRYPTOPP_FLTRIMPL_H
00092 #define CRYPTOPP_FLTRIMPL_H
00093 
00094 #define FILTER_BEGIN    \
00095         switch (m_continueAt)   \
00096         {       \
00097         case 0: \
00098                 m_inputPosition = 0;
00099 
00100 #define FILTER_END_NO_MESSAGE_END_NO_RETURN     \
00101                 break;  \
00102         default:        \
00103                 assert(false);  \
00104         }
00105 
00106 #define FILTER_END_NO_MESSAGE_END       \
00107         FILTER_END_NO_MESSAGE_END_NO_RETURN     \
00108         return 0;
00109 
00110 /*
00111 #define FILTER_END      \
00112         case -1:        \
00113                 if (messageEnd && Output(-1, NULL, 0, messageEnd, blocking))    \
00114                         return 1;       \
00115         FILTER_END_NO_MESSAGE_END
00116 */
00117 
00118 #define FILTER_OUTPUT2(site, statement, output, length, messageEnd)     \
00119         {\
00120         case site:      \
00121         statement;      \
00122         if (Output(site, output, length, messageEnd, blocking)) \
00123                 return STDMAX(1U, (unsigned int)length-m_inputPosition);\
00124         }
00125 
00126 #define FILTER_OUTPUT(site, output, length, messageEnd) \
00127         {\
00128         case site:      \
00129         if (Output(site, output, length, messageEnd, blocking)) \
00130                 return STDMAX(1U, (unsigned int)length-m_inputPosition);\
00131         }
00132 
00133 #endif
00134 ////////////////////////////////////////////////////////////////////////////////
00135 
00136 
00137 
00138 ////////////////////////////////////////////////////////////////////////////////
00139 // cryptlib.cpp - written and placed in the public domain by Wei Dai
00140 
00141 //- #include "pch.h"
00142 
00143 #ifndef CRYPTOPP_IMPORTS
00144 
00145 //- #include "cryptlib.h"
00146 //- #include "misc.h"
00147 //- #include "filters.h"
00148 //- #include "algparam.h"
00149 //- #include "fips140.h"
00150 //- #include "argnames.h"
00151 //- #include "fltrimpl.h"
00152 
00153 #include <memory>
00154 
00155 namespace CryptoPP {
00156 
00157 CRYPTOPP_COMPILE_ASSERT_GLOBAL(sizeof(byte) == 1);
00158 CRYPTOPP_COMPILE_ASSERT_GLOBAL(sizeof(word16) == 2);
00159 CRYPTOPP_COMPILE_ASSERT_GLOBAL(sizeof(word32) == 4);
00160 #ifdef WORD64_AVAILABLE
00161 CRYPTOPP_COMPILE_ASSERT_GLOBAL(sizeof(word64) == 8);
00162 #endif
00163 #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
00164 CRYPTOPP_COMPILE_ASSERT_GLOBAL(sizeof(dword) == 2*sizeof(word));
00165 #endif
00166 
00167 const std::string BufferedTransformation::NULL_CHANNEL;
00168 const NullNameValuePairs g_nullNameValuePairs;
00169 
00170 BufferedTransformation & TheBitBucket()
00171 {
00172         static BitBucket bitBucket;
00173         return bitBucket;
00174 }
00175 
00176 Algorithm::Algorithm(bool /* checkSelfTestStatus */)
00177 {
00178 }
00179 
00180 void SimpleKeyingInterface::SetKeyWithRounds(const byte *key, unsigned int length, int rounds)
00181 {
00182         SetKey(key, length, MakeParameters(Name::Rounds(), rounds));
00183 }
00184 
00185 void SimpleKeyingInterface::SetKeyWithIV(const byte *key, unsigned int length, const byte *iv)
00186 {
00187         SetKey(key, length, MakeParameters(Name::IV(), iv));
00188 }
00189 
00190 void SimpleKeyingInterface::ThrowIfInvalidKeyLength(const Algorithm &algorithm, unsigned int length)
00191 {
00192         if (!IsValidKeyLength(length))
00193                 throw InvalidKeyLength(algorithm.AlgorithmName(), length);
00194 }
00195 
00196 void SimpleKeyingInterface::ThrowIfResynchronizable()
00197 {
00198         if (IsResynchronizable())
00199                 throw InvalidArgument("SimpleKeyingInterface: this object requires an IV");
00200 }
00201 
00202 void SimpleKeyingInterface::ThrowIfInvalidIV(const byte *iv)
00203 {
00204         if (!iv && !(IVRequirement() == INTERNALLY_GENERATED_IV || IVRequirement() == STRUCTURED_IV || !IsResynchronizable()))
00205                 throw InvalidArgument("SimpleKeyingInterface: this object cannot use a null IV");
00206 }
00207 
00208 const byte * SimpleKeyingInterface::GetIVAndThrowIfInvalid(const NameValuePairs &params)
00209 {
00210         const byte *iv;
00211         if (params.GetValue(Name::IV(), iv))
00212                 ThrowIfInvalidIV(iv);
00213         else
00214                 ThrowIfResynchronizable();
00215         return iv;
00216 }
00217 
00218 void BlockTransformation::ProcessAndXorMultipleBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, unsigned int numberOfBlocks) const
00219 {
00220         unsigned int blockSize = BlockSize();
00221         while (numberOfBlocks--)
00222         {
00223                 ProcessAndXorBlock(inBlocks, xorBlocks, outBlocks);
00224                 inBlocks += blockSize;
00225                 outBlocks += blockSize;
00226                 if (xorBlocks)
00227                         xorBlocks += blockSize;
00228         }
00229 }
00230 
00231 void StreamTransformation::ProcessLastBlock(byte *outString, const byte *inString, unsigned int length)
00232 {
00233         assert(MinLastBlockSize() == 0);        // this function should be overriden otherwise
00234 
00235         if (length == MandatoryBlockSize())
00236                 ProcessData(outString, inString, length);
00237         else if (length != 0)
00238                 throw NotImplemented("StreamTransformation: this object does't support a special last block");
00239 }
00240 
00241 unsigned int RandomNumberGenerator::GenerateBit()
00242 {
00243         return Parity(GenerateByte());
00244 }
00245 
00246 void RandomNumberGenerator::GenerateBlock(byte *output, unsigned int size)
00247 {
00248         while (size--)
00249                 *output++ = GenerateByte();
00250 }
00251 
00252 word32 RandomNumberGenerator::GenerateWord32(word32 min, word32 max)
00253 {
00254         word32 range = max-min;
00255         const int maxBytes = BytePrecision(range);
00256         const int maxBits = BitPrecision(range);
00257 
00258         word32 value;
00259 
00260         do
00261         {
00262                 value = 0;
00263                 for (int i=0; i<maxBytes; i++)
00264                         value = (value << 8) | GenerateByte();
00265 
00266                 value = Crop(value, maxBits);
00267         } while (value > range);
00268 
00269         return value+min;
00270 }
00271 
00272 void RandomNumberGenerator::DiscardBytes(unsigned int n)
00273 {
00274         while (n--)
00275                 GenerateByte();
00276 }
00277 
00278 //! see NullRNG()
00279 class ClassNullRNG : public RandomNumberGenerator
00280 {
00281 public:
00282         std::string AlgorithmName() const {return "NullRNG";}
00283         byte GenerateByte() {throw NotImplemented("NullRNG: NullRNG should only be passed to functions that don't need to generate random bytes");}
00284 };
00285 
00286 RandomNumberGenerator & NullRNG()
00287 {
00288         static ClassNullRNG s_nullRNG;
00289         return s_nullRNG;
00290 }
00291 
00292 bool HashTransformation::TruncatedVerify(const byte *digestIn, unsigned int digestLength)
00293 {
00294         ThrowIfInvalidTruncatedSize(digestLength);
00295         SecByteBlock digest(digestLength);
00296         TruncatedFinal(digest, digestLength);
00297         return memcmp(digest, digestIn, digestLength) == 0;
00298 }
00299 
00300 void HashTransformation::ThrowIfInvalidTruncatedSize(unsigned int size) const
00301 {
00302         if (size > DigestSize())
00303                 throw InvalidArgument("HashTransformation: can't truncate a " + IntToString(DigestSize()) + " byte digest to " + IntToString(size) + " bytes");
00304 }
00305 
00306 unsigned int BufferedTransformation::GetMaxWaitObjectCount() const
00307 {
00308         const BufferedTransformation *t = AttachedTransformation();
00309         return t ? t->GetMaxWaitObjectCount() : 0;
00310 }
00311 
00312 void BufferedTransformation::GetWaitObjects(WaitObjectContainer &container)
00313 {
00314         BufferedTransformation *t = AttachedTransformation();
00315         if (t)
00316                 t->GetWaitObjects(container);
00317 }
00318 
00319 void BufferedTransformation::Initialize(const NameValuePairs &parameters, int /* propagation */)
00320 {
00321         assert(!AttachedTransformation());
00322         IsolatedInitialize(parameters);
00323 }
00324 
00325 bool BufferedTransformation::Flush(bool hardFlush, int /* propagation */, bool blocking)
00326 {
00327         assert(!AttachedTransformation());
00328         return IsolatedFlush(hardFlush, blocking);
00329 }
00330 
00331 bool BufferedTransformation::MessageSeriesEnd(int /* propagation */, bool blocking)
00332 {
00333         assert(!AttachedTransformation());
00334         return IsolatedMessageSeriesEnd(blocking);
00335 }
00336 
00337 byte * BufferedTransformation::ChannelCreatePutSpace(const std::string &channel, unsigned int &size)
00338 {
00339         if (channel.empty())
00340                 return CreatePutSpace(size);
00341         else
00342                 throw NoChannelSupport();
00343 }
00344 
00345 unsigned int BufferedTransformation::ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking)
00346 {
00347         if (channel.empty())
00348                 return Put2(begin, length, messageEnd, blocking);
00349         else
00350                 throw NoChannelSupport();
00351 }
00352 
00353 unsigned int BufferedTransformation::ChannelPutModifiable2(const std::string &channel, byte *begin, unsigned int length, int messageEnd, bool blocking)
00354 {
00355         if (channel.empty())
00356                 return PutModifiable2(begin, length, messageEnd, blocking);
00357         else
00358                 return ChannelPut2(channel, begin, length, messageEnd, blocking);
00359 }
00360 
00361 bool BufferedTransformation::ChannelFlush(const std::string &channel, bool completeFlush, int propagation, bool blocking)
00362 {
00363         if (channel.empty())
00364                 return Flush(completeFlush, propagation, blocking);
00365         else
00366                 throw NoChannelSupport();
00367 }
00368 
00369 bool BufferedTransformation::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking)
00370 {
00371         if (channel.empty())
00372                 return MessageSeriesEnd(propagation, blocking);
00373         else
00374                 throw NoChannelSupport();
00375 }
00376 
00377 unsigned long BufferedTransformation::MaxRetrievable() const
00378 {
00379         if (AttachedTransformation())
00380                 return AttachedTransformation()->MaxRetrievable();
00381         else
00382                 return CopyTo(TheBitBucket());
00383 }
00384 
00385 bool BufferedTransformation::AnyRetrievable() const
00386 {
00387         if (AttachedTransformation())
00388                 return AttachedTransformation()->AnyRetrievable();
00389         else
00390         {
00391                 byte b;
00392                 return Peek(b) != 0;
00393         }
00394 }
00395 
00396 unsigned int BufferedTransformation::Get(byte &outByte)
00397 {
00398         if (AttachedTransformation())
00399                 return AttachedTransformation()->Get(outByte);
00400         else
00401                 return Get(&outByte, 1);
00402 }
00403 
00404 unsigned int BufferedTransformation::Get(byte *outString, unsigned int getMax)
00405 {
00406         if (AttachedTransformation())
00407                 return AttachedTransformation()->Get(outString, getMax);
00408         else
00409         {
00410                 ArraySink arraySink(outString, getMax);
00411                 return TransferTo(arraySink, getMax);
00412         }
00413 }
00414 
00415 unsigned int BufferedTransformation::Peek(byte &outByte) const
00416 {
00417         if (AttachedTransformation())
00418                 return AttachedTransformation()->Peek(outByte);
00419         else
00420                 return Peek(&outByte, 1);
00421 }
00422 
00423 unsigned int BufferedTransformation::Peek(byte *outString, unsigned int peekMax) const
00424 {
00425         if (AttachedTransformation())
00426                 return AttachedTransformation()->Peek(outString, peekMax);
00427         else
00428         {
00429                 ArraySink arraySink(outString, peekMax);
00430                 return CopyTo(arraySink, peekMax);
00431         }
00432 }
00433 
00434 unsigned long BufferedTransformation::Skip(unsigned long skipMax)
00435 {
00436         if (AttachedTransformation())
00437                 return AttachedTransformation()->Skip(skipMax);
00438         else
00439                 return TransferTo(TheBitBucket(), skipMax);
00440 }
00441 
00442 unsigned long BufferedTransformation::TotalBytesRetrievable() const
00443 {
00444         if (AttachedTransformation())
00445                 return AttachedTransformation()->TotalBytesRetrievable();
00446         else
00447                 return MaxRetrievable();
00448 }
00449 
00450 unsigned int BufferedTransformation::NumberOfMessages() const
00451 {
00452         if (AttachedTransformation())
00453                 return AttachedTransformation()->NumberOfMessages();
00454         else
00455                 return CopyMessagesTo(TheBitBucket());
00456 }
00457 
00458 bool BufferedTransformation::AnyMessages() const
00459 {
00460         if (AttachedTransformation())
00461                 return AttachedTransformation()->AnyMessages();
00462         else
00463                 return NumberOfMessages() != 0;
00464 }
00465 
00466 bool BufferedTransformation::GetNextMessage()
00467 {
00468         if (AttachedTransformation())
00469                 return AttachedTransformation()->GetNextMessage();
00470         else
00471         {
00472                 assert(!AnyMessages());
00473                 return false;
00474         }
00475 }
00476 
00477 unsigned int BufferedTransformation::SkipMessages(unsigned int count)
00478 {
00479         if (AttachedTransformation())
00480                 return AttachedTransformation()->SkipMessages(count);
00481         else
00482                 return TransferMessagesTo(TheBitBucket(), count);
00483 }
00484 
00485 unsigned int BufferedTransformation::TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel, bool blocking)
00486 {
00487         if (AttachedTransformation())
00488                 return AttachedTransformation()->TransferMessagesTo2(target, messageCount, channel, blocking);
00489         else
00490         {
00491                 unsigned int maxMessages = messageCount;
00492                 for (messageCount=0; messageCount < maxMessages && AnyMessages(); messageCount++)
00493                 {
00494                         unsigned int blockedBytes;
00495                         unsigned long transferredBytes;
00496 
00497                         while (AnyRetrievable())
00498                         {
00499                                 transferredBytes = ULONG_MAX;
00500                                 blockedBytes = TransferTo2(target, transferredBytes, channel, blocking);
00501                                 if (blockedBytes > 0)
00502                                         return blockedBytes;
00503                         }
00504 
00505                         if (target.ChannelMessageEnd(channel, GetAutoSignalPropagation(), blocking))
00506                                 return 1;
00507 
00508                         bool result = GetNextMessage();
00509                         assert(result);
00510                 }
00511                 return 0;
00512         }
00513 }
00514 
00515 unsigned int BufferedTransformation::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const
00516 {
00517         if (AttachedTransformation())
00518                 return AttachedTransformation()->CopyMessagesTo(target, count, channel);
00519         else
00520                 return 0;
00521 }
00522 
00523 void BufferedTransformation::SkipAll()
00524 {
00525         if (AttachedTransformation())
00526                 AttachedTransformation()->SkipAll();
00527         else
00528         {
00529                 while (SkipMessages()) {}
00530                 while (Skip()) {}
00531         }
00532 }
00533 
00534 unsigned int BufferedTransformation::TransferAllTo2(BufferedTransformation &target, const std::string &channel, bool blocking)
00535 {
00536         if (AttachedTransformation())
00537                 return AttachedTransformation()->TransferAllTo2(target, channel, blocking);
00538         else
00539         {
00540                 assert(!NumberOfMessageSeries());
00541 
00542                 unsigned int messageCount;
00543                 do
00544                 {
00545                         messageCount = UINT_MAX;
00546                         unsigned int blockedBytes = TransferMessagesTo2(target, messageCount, channel, blocking);
00547                         if (blockedBytes)
00548                                 return blockedBytes;
00549                 }
00550                 while (messageCount != 0);
00551 
00552                 unsigned long byteCount;
00553                 do
00554                 {
00555                         byteCount = ULONG_MAX;
00556                         unsigned int blockedBytes = TransferTo2(target, byteCount, channel, blocking);
00557                         if (blockedBytes)
00558                                 return blockedBytes;
00559                 }
00560                 while (byteCount != 0);
00561 
00562                 return 0;
00563         }
00564 }
00565 
00566 void BufferedTransformation::CopyAllTo(BufferedTransformation &target, const std::string &channel) const
00567 {
00568         if (AttachedTransformation())
00569                 AttachedTransformation()->CopyAllTo(target, channel);
00570         else
00571         {
00572                 assert(!NumberOfMessageSeries());
00573                 while (CopyMessagesTo(target, UINT_MAX, channel)) {}
00574         }
00575 }
00576 
00577 void BufferedTransformation::SetRetrievalChannel(const std::string &channel)
00578 {
00579         if (AttachedTransformation())
00580                 AttachedTransformation()->SetRetrievalChannel(channel);
00581 }
00582 
00583 unsigned int BufferedTransformation::ChannelPutWord16(const std::string &channel, word16 value, ByteOrder order, bool blocking)
00584 {
00585         FixedSizeSecBlock<byte, 2> buf;
00586         PutWord(false, order, buf, value);
00587         return ChannelPut(channel, buf, 2, blocking);
00588 }
00589 
00590 unsigned int BufferedTransformation::ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order, bool blocking)
00591 {
00592         FixedSizeSecBlock<byte, 4> buf;
00593         PutWord(false, order, buf, value);
00594         return ChannelPut(channel, buf, 4, blocking);
00595 }
00596 
00597 unsigned int BufferedTransformation::PutWord16(word16 value, ByteOrder order, bool blocking)
00598 {
00599         return ChannelPutWord16(NULL_CHANNEL, value, order, blocking);
00600 }
00601 
00602 unsigned int BufferedTransformation::PutWord32(word32 value, ByteOrder order, bool blocking)
00603 {
00604         return ChannelPutWord32(NULL_CHANNEL, value, order, blocking);
00605 }
00606 
00607 unsigned int BufferedTransformation::PeekWord16(word16 &value, ByteOrder order)
00608 {
00609         byte buf[2] = {0, 0};
00610         unsigned int len = Peek(buf, 2);
00611 
00612         if (order)
00613                 value = (buf[0] << 8) | buf[1];
00614         else
00615                 value = (buf[1] << 8) | buf[0];
00616 
00617         return len;
00618 }
00619 
00620 unsigned int BufferedTransformation::PeekWord32(word32 &value, ByteOrder order)
00621 {
00622         byte buf[4] = {0, 0, 0, 0};
00623         unsigned int len = Peek(buf, 4);
00624 
00625         if (order)
00626                 value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf [3];
00627         else
00628                 value = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf [0];
00629 
00630         return len;
00631 }
00632 
00633 unsigned int BufferedTransformation::GetWord16(word16 &value, ByteOrder order)
00634 {
00635         return Skip(PeekWord16(value, order));
00636 }
00637 
00638 unsigned int BufferedTransformation::GetWord32(word32 &value, ByteOrder order)
00639 {
00640         return Skip(PeekWord32(value, order));
00641 }
00642 
00643 void BufferedTransformation::Attach(BufferedTransformation *newOut)
00644 {
00645         if (AttachedTransformation() && AttachedTransformation()->Attachable())
00646                 AttachedTransformation()->Attach(newOut);
00647         else
00648                 Detach(newOut);
00649 }
00650 
00651 void GeneratableCryptoMaterial::GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize)
00652 {
00653         GenerateRandom(rng, MakeParameters("KeySize", (int)keySize));
00654 }
00655 
00656 class PK_DefaultEncryptionFilter : public Unflushable<Filter>
00657 {
00658 public:
00659         PK_DefaultEncryptionFilter(RandomNumberGenerator &rng, const PK_Encryptor &encryptor, BufferedTransformation *attachment, const NameValuePairs &parameters)
00660                 : m_rng(rng), m_encryptor(encryptor), m_parameters(parameters)
00661         {
00662                 Detach(attachment);
00663         }
00664 
00665         unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
00666         {
00667                 FILTER_BEGIN;
00668                 m_plaintextQueue.Put(inString, length);
00669 
00670                 if (messageEnd)
00671                 {
00672                         {
00673                         unsigned int plaintextLength = m_plaintextQueue.CurrentSize();
00674                         unsigned int ciphertextLength = m_encryptor.CiphertextLength(plaintextLength);
00675 
00676                         SecByteBlock plaintext(plaintextLength);
00677                         m_plaintextQueue.Get(plaintext, plaintextLength);
00678                         m_ciphertext.resize(ciphertextLength);
00679                         m_encryptor.Encrypt(m_rng, plaintext, plaintextLength, m_ciphertext, m_parameters);
00680                         }
00681 
00682                         FILTER_OUTPUT(1, m_ciphertext, m_ciphertext.size(), messageEnd);
00683                 }
00684                 FILTER_END_NO_MESSAGE_END;
00685         }
00686 
00687         RandomNumberGenerator &m_rng;
00688         const PK_Encryptor &m_encryptor;
00689         const NameValuePairs &m_parameters;
00690         ByteQueue m_plaintextQueue;
00691         SecByteBlock m_ciphertext;
00692 };
00693 
00694 BufferedTransformation * PK_Encryptor::CreateEncryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment, const NameValuePairs &parameters) const
00695 {
00696         return new PK_DefaultEncryptionFilter(rng, *this, attachment, parameters);
00697 }
00698 
00699 unsigned int PK_Signer::Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const
00700 {
00701         std::auto_ptr<PK_MessageAccumulator> m(messageAccumulator);
00702         return SignAndRestart(rng, *m, signature, false);
00703 }
00704 
00705 unsigned int PK_Signer::SignMessage(RandomNumberGenerator &rng, const byte *message, unsigned int messageLen, byte *signature) const
00706 {
00707         std::auto_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));
00708         m->Update(message, messageLen);
00709         return SignAndRestart(rng, *m, signature, false);
00710 }
00711 
00712 unsigned int PK_Signer::SignMessageWithRecovery(RandomNumberGenerator &rng, const byte *recoverableMessage, unsigned int recoverableMessageLength,
00713         const byte *nonrecoverableMessage, unsigned int nonrecoverableMessageLength, byte *signature) const
00714 {
00715         std::auto_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));
00716         InputRecoverableMessage(*m, recoverableMessage, recoverableMessageLength);
00717         m->Update(nonrecoverableMessage, nonrecoverableMessageLength);
00718         return SignAndRestart(rng, *m, signature, false);
00719 }
00720 
00721 bool PK_Verifier::Verify(PK_MessageAccumulator *messageAccumulator) const
00722 {
00723         std::auto_ptr<PK_MessageAccumulator> m(messageAccumulator);
00724         return VerifyAndRestart(*m);
00725 }
00726 
00727 bool PK_Verifier::VerifyMessage(const byte *message, unsigned int messageLen, const byte *signature, unsigned int signatureLength) const
00728 {
00729         std::auto_ptr<PK_MessageAccumulator> m(NewVerificationAccumulator());
00730         InputSignature(*m, signature, signatureLength);
00731         m->Update(message, messageLen);
00732         return VerifyAndRestart(*m);
00733 }
00734 
00735 DecodingResult PK_Verifier::Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const
00736 {
00737         std::auto_ptr<PK_MessageAccumulator> m(messageAccumulator);
00738         return RecoverAndRestart(recoveredMessage, *m);
00739 }
00740 
00741 DecodingResult PK_Verifier::RecoverMessage(byte *recoveredMessage,
00742         const byte *nonrecoverableMessage, unsigned int nonrecoverableMessageLength,
00743         const byte *signature, unsigned int signatureLength) const
00744 {
00745         std::auto_ptr<PK_MessageAccumulator> m(NewVerificationAccumulator());
00746         InputSignature(*m, signature, signatureLength);
00747         m->Update(nonrecoverableMessage, nonrecoverableMessageLength);
00748         return RecoverAndRestart(recoveredMessage, *m);
00749 }
00750 
00751 NAMESPACE_END
00752 
00753 #endif
00754 ////////////////////////////////////////////////////////////////////////////////
00755 
00756 
00757 
00758 ////////////////////////////////////////////////////////////////////////////////
00759 #ifndef CRYPTOPP_WORDS_H
00760 #define CRYPTOPP_WORDS_H
00761 
00762 //- #include "misc.h"
00763 
00764 namespace CryptoPP {
00765 
00766 inline unsigned int CountWords(const word *X, unsigned int N)
00767 {
00768         while (N && X[N-1]==0)
00769                 N--;
00770         return N;
00771 }
00772 
00773 inline void SetWords(word *r, word a, unsigned int n)
00774 {
00775         for (unsigned int i=0; i<n; i++)
00776                 r[i] = a;
00777 }
00778 
00779 inline void CopyWords(word *r, const word *a, unsigned int n)
00780 {
00781         for (unsigned int i=0; i<n; i++)
00782                 r[i] = a[i];
00783 }
00784 
00785 inline void XorWords(word *r, const word *a, const word *b, unsigned int n)
00786 {
00787         for (unsigned int i=0; i<n; i++)
00788                 r[i] = a[i] ^ b[i];
00789 }
00790 
00791 inline void XorWords(word *r, const word *a, unsigned int n)
00792 {
00793         for (unsigned int i=0; i<n; i++)
00794                 r[i] ^= a[i];
00795 }
00796 
00797 inline word ShiftWordsLeftByBits(word *r, unsigned int n, unsigned int shiftBits)
00798 {
00799         assert (shiftBits<WORD_BITS);
00800         word u, carry=0;
00801         if (shiftBits)
00802                 for (unsigned int i=0; i<n; i++)
00803                 {
00804                         u = r[i];
00805                         r[i] = (u << shiftBits) | carry;
00806                         carry = u >> (WORD_BITS-shiftBits);
00807                 }
00808         return carry;
00809 }
00810 
00811 inline word ShiftWordsRightByBits(word *r, unsigned int n, unsigned int shiftBits)
00812 {
00813         assert (shiftBits<WORD_BITS);
00814         word u, carry=0;
00815         if (shiftBits)
00816                 for (int i=n-1; i>=0; i--)
00817                 {
00818                         u = r[i];
00819                         r[i] = (u >> shiftBits) | carry;
00820                         carry = u << (WORD_BITS-shiftBits);
00821                 }
00822         return carry;
00823 }
00824 
00825 inline void ShiftWordsLeftByWords(word *r, unsigned int n, unsigned int shiftWords)
00826 {
00827         shiftWords = STDMIN(shiftWords, n);
00828         if (shiftWords)
00829         {
00830                 for (unsigned int i=n-1; i>=shiftWords; i--)
00831                         r[i] = r[i-shiftWords];
00832                 SetWords(r, 0, shiftWords);
00833         }
00834 }
00835 
00836 inline void ShiftWordsRightByWords(word *r, unsigned int n, unsigned int shiftWords)
00837 {
00838         shiftWords = STDMIN(shiftWords, n);
00839         if (shiftWords)
00840         {
00841                 for (unsigned int i=0; i+shiftWords<n; i++)
00842                         r[i] = r[i+shiftWords];
00843                 SetWords(r+n-shiftWords, 0, shiftWords);
00844         }
00845 }
00846 
00847 NAMESPACE_END
00848 
00849 #endif
00850 ////////////////////////////////////////////////////////////////////////////////
00851 
00852 
00853 
00854 ////////////////////////////////////////////////////////////////////////////////
00855 // misc.cpp - written and placed in the public domain by Wei Dai
00856 
00857 //- #include "pch.h"
00858 
00859 #ifndef CRYPTOPP_IMPORTS
00860 
00861 //- #include "misc.h"
00862 //- #include "words.h"
00863 #include <new>
00864 
00865 namespace CryptoPP {
00866 
00867 void xorbuf(byte *buf, const byte *mask, unsigned int count)
00868 {
00869         if (((size_t)buf | (size_t)mask | count) % WORD_SIZE == 0)
00870                 XorWords((word *)buf, (const word *)mask, count/WORD_SIZE);
00871         else
00872         {
00873                 for (unsigned int i=0; i<count; i++)
00874                         buf[i] ^= mask[i];
00875         }
00876 }
00877 
00878 void xorbuf(byte *output, const byte *input, const byte *mask, unsigned int count)
00879 {
00880         if (((size_t)output | (size_t)input | (size_t)mask | count) % WORD_SIZE == 0)
00881                 XorWords((word *)output, (const word *)input, (const word *)mask, count/WORD_SIZE);
00882         else
00883         {
00884                 for (unsigned int i=0; i<count; i++)
00885                         output[i] = input[i] ^ mask[i];
00886         }
00887 }
00888 
00889 unsigned int Parity(unsigned long value)
00890 {
00891         for (unsigned int i=8*sizeof(value)/2; i>0; i/=2)
00892                 value ^= value >> i;
00893         return (unsigned int)value&1;
00894 }
00895 
00896 unsigned int BytePrecision(unsigned long value)
00897 {
00898         unsigned int i;
00899         for (i=sizeof(value); i; --i)
00900                 if (value >> (i-1)*8)
00901                         break;
00902 
00903         return i;
00904 }
00905 
00906 unsigned int BitPrecision(unsigned long value)
00907 {
00908         if (!value)
00909                 return 0;
00910 
00911         unsigned int l=0, h=8*sizeof(value);
00912 
00913         while (h-l > 1)
00914         {
00915                 unsigned int t = (l+h)/2;
00916                 if (value >> t)
00917                         l = t;
00918                 else
00919                         h = t;
00920         }
00921 
00922         return h;
00923 }
00924 
00925 unsigned long Crop(unsigned long value, unsigned int size)
00926 {
00927         if (size < 8*sizeof(value))
00928         return (value & ((1L << size) - 1));
00929         else
00930                 return value;
00931 }
00932 
00933 #if !(defined(_MSC_VER) && (_MSC_VER < 1300))
00934 using std::new_handler;
00935 using std::set_new_handler;
00936 #endif
00937 
00938 void CallNewHandler()
00939 {
00940         new_handler newHandler = set_new_handler(NULL);
00941         if (newHandler)
00942                 set_new_handler(newHandler);
00943 
00944         if (newHandler)
00945                 newHandler();
00946         else
00947                 throw std::bad_alloc();
00948 }
00949 
00950 NAMESPACE_END
00951 
00952 #endif
00953 ////////////////////////////////////////////////////////////////////////////////
00954 
00955 
00956 
00957 ////////////////////////////////////////////////////////////////////////////////
00958 // nbtheory.h - written and placed in the public domain by Wei Dai
00959 
00960 #ifndef CRYPTOPP_NBTHEORY_H
00961 #define CRYPTOPP_NBTHEORY_H
00962 
00963 //- #include "integer.h"
00964 //- #include "algparam.h"
00965 
00966 namespace CryptoPP {
00967 
00968 // obtain pointer to small prime table and get its size
00969 CRYPTOPP_DLL const word16 * GetPrimeTable(unsigned int &size);
00970 
00971 // ************ primality testing ****************
00972 
00973 CRYPTOPP_DLL bool IsSmallPrime(const Integer &p);
00974 
00975 // returns true if p is divisible by some prime less than bound
00976 // bound not be greater than the largest entry in the prime table
00977 CRYPTOPP_DLL bool TrialDivision(const Integer &p, unsigned bound);
00978 
00979 // returns true if p is NOT divisible by small primes
00980 CRYPTOPP_DLL bool SmallDivisorsTest(const Integer &p);
00981 
00982 CRYPTOPP_DLL bool IsStrongProbablePrime(const Integer &n, const Integer &b);
00983 CRYPTOPP_DLL bool IsStrongLucasProbablePrime(const Integer &n);
00984 
00985 // Rabin-Miller primality test, i.e. repeating the strong probable prime test
00986 // for several rounds with random bases
00987 CRYPTOPP_DLL bool RabinMillerTest(RandomNumberGenerator &rng, const Integer &w, unsigned int rounds);
00988 
00989 // primality test, used to generate primes
00990 CRYPTOPP_DLL bool IsPrime(const Integer &p);
00991 
00992 // more reliable than IsPrime(), used to verify primes generated by others
00993 CRYPTOPP_DLL bool VerifyPrime(RandomNumberGenerator &rng, const Integer &p, unsigned int level = 1);
00994 
00995 class PrimeSelector
00996 {
00997 public:
00998         virtual ~PrimeSelector() {}
00999 
01000         const PrimeSelector *GetSelectorPointer() const {return this;}
01001         virtual bool IsAcceptable(const Integer &candidate) const =0;
01002 };
01003 
01004 // use a fast sieve to find the first probable prime in {x | p<=x<=max and x%mod==equiv}
01005 // returns true iff successful, value of p is undefined if no such prime exists
01006 CRYPTOPP_DLL bool FirstPrime(Integer &p, const Integer &max, const Integer &equiv, const Integer &mod, const PrimeSelector *pSelector);
01007 
01008 CRYPTOPP_DLL unsigned int PrimeSearchInterval(const Integer &max);
01009 
01010 CRYPTOPP_DLL AlgorithmParameters<AlgorithmParameters<AlgorithmParameters<NullNameValuePairs, Integer::RandomNumberType>, Integer>, Integer>
01011         MakeParametersForTwoPrimesOfEqualSize(unsigned int productBitLength);
01012 
01013 // ********** other number theoretic functions ************
01014 
01015 inline Integer GCD(const Integer &a, const Integer &b)
01016         {return Integer::Gcd(a,b);}
01017 inline bool RelativelyPrime(const Integer &a, const Integer &b)
01018         {return Integer::Gcd(a,b) == Integer::One();}
01019 inline Integer LCM(const Integer &a, const Integer &b)
01020         {return a/Integer::Gcd(a,b)*b;}
01021 inline Integer EuclideanMultiplicativeInverse(const Integer &a, const Integer &b)
01022         {return a.InverseMod(b);}
01023 
01024 // use Chinese Remainder Theorem to calculate x given x mod p and x mod q
01025 CRYPTOPP_DLL Integer CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q);
01026 // use this one if u = inverse of p mod q has been precalculated
01027 CRYPTOPP_DLL Integer CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q, const Integer &u);
01028 
01029 // if b is prime, then Jacobi(a, b) returns 0 if a%b==0, 1 if a is quadratic residue mod b, -1 otherwise
01030 // check a number theory book for what Jacobi symbol means when b is not prime
01031 CRYPTOPP_DLL int Jacobi(const Integer &a, const Integer &b);
01032 
01033 // calculates the Lucas function V_e(p, 1) mod n
01034 CRYPTOPP_DLL Integer Lucas(const Integer &e, const Integer &p, const Integer &n);
01035 // calculates x such that m==Lucas(e, x, p*q), p q primes
01036 CRYPTOPP_DLL Integer InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q);
01037 // use this one if u=inverse of p mod q has been precalculated
01038 CRYPTOPP_DLL Integer InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q, const Integer &u);
01039 
01040 inline Integer ModularExponentiation(const Integer &a, const Integer &e, const Integer &m)
01041         {return a_exp_b_mod_c(a, e, m);}
01042 // returns x such that a==ModularExponentiation(x, e, p*q), p q primes,
01043 // and e relatively prime to (p-1)*(q-1)
01044 CRYPTOPP_DLL Integer ModularRoot(const Integer &a, const Integer &e, const Integer &p, const Integer &q);
01045 // use this one if dp=d%(p-1), dq=d%(q-1), (d is inverse of e mod (p-1)*(q-1))
01046 // and u=inverse of p mod q have been precalculated
01047 CRYPTOPP_DLL Integer ModularRoot(const Integer &a, const Integer &dp, const Integer &dq, const Integer &p, const Integer &q, const Integer &u);
01048 
01049 NAMESPACE_END
01050 
01051 #endif
01052 ////////////////////////////////////////////////////////////////////////////////
01053 
01054 
01055 
01056 ////////////////////////////////////////////////////////////////////////////////
01057 // nbtheory.cpp - written and placed in the public domain by Wei Dai
01058 
01059 //- #include "pch.h"
01060 
01061 #ifndef CRYPTOPP_IMPORTS
01062 
01063 //- #include "nbtheory.h"
01064 //- #include "modarith.h"
01065 //- #include "algparam.h"
01066 
01067 #include <math.h>
01068 #include <vector>
01069 
01070 namespace CryptoPP {
01071 
01072 const word s_lastSmallPrime = 32719;
01073 
01074 struct NewPrimeTable
01075 {
01076         std::vector<word16> * operator()() const
01077         {
01078                 const unsigned int maxPrimeTableSize = 3511;
01079 
01080                 std::auto_ptr<std::vector<word16> > pPrimeTable(new std::vector<word16>);
01081                 std::vector<word16> &primeTable = *pPrimeTable;
01082                 primeTable.reserve(maxPrimeTableSize);
01083 
01084                 primeTable.push_back(2);
01085                 unsigned int testEntriesEnd = 1;
01086 
01087                 for (unsigned int p=3; p<=s_lastSmallPrime; p+=2)
01088                 {
01089                         unsigned int j;
01090                         for (j=1; j<testEntriesEnd; j++)
01091                                 if (p%primeTable[j] == 0)
01092                                         break;
01093                         if (j == testEntriesEnd)
01094                         {
01095                                 primeTable.push_back(p);
01096                                 testEntriesEnd = STDMIN((size_t)54U, primeTable.size());
01097                         }
01098                 }
01099 
01100                 return pPrimeTable.release();
01101         }
01102 };
01103 
01104 const word16 * GetPrimeTable(unsigned int &size)
01105 {
01106         const std::vector<word16> &primeTable = Singleton<std::vector<word16>, NewPrimeTable>().Ref();
01107         size = primeTable.size();
01108         return &primeTable[0];
01109 }
01110 
01111 bool IsSmallPrime(const Integer &p)
01112 {
01113         unsigned int primeTableSize;
01114         const word16 * primeTable = GetPrimeTable(primeTableSize);
01115 
01116         if (p.IsPositive() && p <= primeTable[primeTableSize-1])
01117                 return std::binary_search(primeTable, primeTable+primeTableSize, (word16)p.ConvertToLong());
01118         else
01119                 return false;
01120 }
01121 
01122 bool TrialDivision(const Integer &p, unsigned bound)
01123 {
01124         unsigned int primeTableSize;
01125         const word16 * primeTable = GetPrimeTable(primeTableSize);
01126 
01127         assert(primeTable[primeTableSize-1] >= bound);
01128 
01129         unsigned int i;
01130         for (i = 0; primeTable[i]<bound; i++)
01131                 if ((p % primeTable[i]) == 0)
01132                         return true;
01133 
01134         if (bound == primeTable[i])
01135                 return (p % bound == 0);
01136         else
01137                 return false;
01138 }
01139 
01140 bool SmallDivisorsTest(const Integer &p)
01141 {
01142         unsigned int primeTableSize;
01143         const word16 * primeTable = GetPrimeTable(primeTableSize);
01144         return !TrialDivision(p, primeTable[primeTableSize-1]);
01145 }
01146 
01147 bool IsStrongProbablePrime(const Integer &n, const Integer &b)
01148 {
01149         if (n <= 3)
01150                 return n==2 || n==3;
01151 
01152         assert(n>3 && b>1 && b<n-1);
01153 
01154         if ((n.IsEven() && n!=2) || GCD(b, n) != 1)
01155                 return false;
01156 
01157         Integer nminus1 = (n-1);
01158         unsigned int a;
01159 
01160         // calculate a = largest power of 2 that divides (n-1)
01161         for (a=0; ; a++)
01162                 if (nminus1.GetBit(a))
01163                         break;
01164         Integer m = nminus1>>a;
01165 
01166         Integer z = a_exp_b_mod_c(b, m, n);
01167         if (z==1 || z==nminus1)
01168                 return true;
01169         for (unsigned j=1; j<a; j++)
01170         {
01171                 z = z.Squared()%n;
01172                 if (z==nminus1)
01173                         return true;
01174                 if (z==1)
01175                         return false;
01176         }
01177         return false;
01178 }
01179 
01180 bool RabinMillerTest(RandomNumberGenerator &rng, const Integer &n, unsigned int rounds)
01181 {
01182         if (n <= 3)
01183                 return n==2 || n==3;
01184 
01185         assert(n>3);
01186 
01187         Integer b;
01188         for (unsigned int i=0; i<rounds; i++)
01189         {
01190                 b.Randomize(rng, 2, n-2);
01191                 if (!IsStrongProbablePrime(n, b))
01192                         return false;
01193         }
01194         return true;
01195 }
01196 
01197 bool IsStrongLucasProbablePrime(const Integer &n)
01198 {
01199         if (n <= 1)
01200                 return false;
01201 
01202         if (n.IsEven())
01203                 return n==2;
01204 
01205         assert(n>2);
01206 
01207         Integer b=3;
01208         unsigned int i=0;
01209         int j;
01210 
01211         while ((j=Jacobi(b.Squared()-4, n)) == 1)
01212         {
01213                 if (++i==64 && n.IsSquare())    // avoid infinite loop if n is a square
01214                         return false;
01215                 ++b; ++b;
01216         }
01217 
01218         if (j==0)
01219                 return false;
01220 
01221         Integer n1 = n+1;
01222         unsigned int a;
01223 
01224         // calculate a = largest power of 2 that divides n1
01225         for (a=0; ; a++)
01226                 if (n1.GetBit(a))
01227                         break;
01228         Integer m = n1>>a;
01229 
01230         Integer z = Lucas(m, b, n);
01231         if (z==2 || z==n-2)
01232                 return true;
01233         for (i=1; i<a; i++)
01234         {
01235                 z = (z.Squared()-2)%n;
01236                 if (z==n-2)
01237                         return true;
01238                 if (z==2)
01239                         return false;
01240         }
01241         return false;
01242 }
01243 
01244 struct NewLastSmallPrimeSquared
01245 {
01246         Integer * operator()() const
01247         {
01248                 return new Integer(Integer(s_lastSmallPrime).Squared());
01249         }
01250 };
01251 
01252 bool IsPrime(const Integer &p)
01253 {
01254         if (p <= s_lastSmallPrime)
01255                 return IsSmallPrime(p);
01256         else if (p <= Singleton<Integer, NewLastSmallPrimeSquared>().Ref())
01257                 return SmallDivisorsTest(p);
01258         else
01259                 return SmallDivisorsTest(p) && IsStrongProbablePrime(p, 3) && IsStrongLucasProbablePrime(p);
01260 }
01261 
01262 bool VerifyPrime(RandomNumberGenerator &rng, const Integer &p, unsigned int level)
01263 {
01264         bool pass = IsPrime(p) && RabinMillerTest(rng, p, 1);
01265         if (level >= 1)
01266                 pass = pass && RabinMillerTest(rng, p, 10);
01267         return pass;
01268 }
01269 
01270 unsigned int PrimeSearchInterval(const Integer &max)
01271 {
01272         return max.BitCount();
01273 }
01274 
01275 static inline bool FastProbablePrimeTest(const Integer &n)
01276 {
01277         return IsStrongProbablePrime(n,2);
01278 }
01279 
01280 AlgorithmParameters<AlgorithmParameters<AlgorithmParameters<NullNameValuePairs, Integer::RandomNumberType>, Integer>, Integer>
01281         MakeParametersForTwoPrimesOfEqualSize(unsigned int productBitLength)
01282 {
01283         if (productBitLength < 16)
01284                 throw InvalidArgument("invalid bit length");
01285 
01286         Integer minP, maxP;
01287 
01288         if (productBitLength%2==0)
01289         {
01290                 minP = Integer(182) << (productBitLength/2-8);
01291                 maxP = Integer::Power2(productBitLength/2)-1;
01292         }
01293         else
01294         {
01295                 minP = Integer::Power2((productBitLength-1)/2);
01296                 maxP = Integer(181) << ((productBitLength+1)/2-8);
01297         }
01298 
01299         return MakeParameters("RandomNumberType", Integer::PRIME)("Min", minP)("Max", maxP);
01300 }
01301 
01302 class PrimeSieve
01303 {
01304 public:
01305         // delta == 1 or -1 means double sieve with p = 2*q + delta
01306         PrimeSieve(const Integer &first, const Integer &last, const Integer &step, signed int delta=0);
01307         bool NextCandidate(Integer &c);
01308 
01309         void DoSieve();
01310         static void SieveSingle(std::vector<bool> &sieve, word16 p, const Integer &first, const Integer &step, word16 stepInv);
01311 
01312         Integer m_first, m_last, m_step;
01313         signed int m_delta;
01314         word m_next;
01315         std::vector<bool> m_sieve;
01316 };
01317 
01318 PrimeSieve::PrimeSieve(const Integer &first, const Integer &last, const Integer &step, signed int delta)
01319         : m_first(first), m_last(last), m_step(step), m_delta(delta), m_next(0)
01320 {
01321         DoSieve();
01322 }
01323 
01324 bool PrimeSieve::NextCandidate(Integer &c)
01325 {
01326         m_next = std::find(m_sieve.begin()+m_next, m_sieve.end(), false) - m_sieve.begin();
01327         if (m_next == m_sieve.size())
01328         {
01329                 m_first += m_sieve.size()*m_step;
01330                 if (m_first > m_last)
01331                         return false;
01332                 else
01333                 {
01334                         m_next = 0;
01335                         DoSieve();
01336                         return NextCandidate(c);
01337                 }
01338         }
01339         else
01340         {
01341                 c = m_first + m_next*m_step;
01342                 ++m_next;
01343                 return true;
01344         }
01345 }
01346 
01347 void PrimeSieve::SieveSingle(std::vector<bool> &sieve, word16 p, const Integer &first, const Integer &step, word16 stepInv)
01348 {
01349         if (stepInv)
01350         {
01351                 unsigned int sieveSize = sieve.size();
01352                 word j = word((word32(p-(first%p))*stepInv) % p);
01353                 // if the first multiple of p is p, skip it
01354                 if (first.WordCount() <= 1 && first + step*j == p)
01355                         j += p;
01356                 for (; j < sieveSize; j += p)
01357                         sieve[j] = true;
01358         }
01359 }
01360 
01361 void PrimeSieve::DoSieve()
01362 {
01363         unsigned int primeTableSize;
01364         const word16 * primeTable = GetPrimeTable(primeTableSize);
01365 
01366         const unsigned int maxSieveSize = 32768;
01367         unsigned int sieveSize = STDMIN(Integer(maxSieveSize), (m_last-m_first)/m_step+1).ConvertToLong();
01368 
01369         m_sieve.clear();
01370         m_sieve.resize(sieveSize, false);
01371 
01372         if (m_delta == 0)
01373         {
01374                 for (unsigned int i = 0; i < primeTableSize; ++i)
01375                         SieveSingle(m_sieve, primeTable[i], m_first, m_step, m_step.InverseMod(primeTable[i]));
01376         }
01377         else
01378         {
01379                 assert(m_step%2==0);
01380                 Integer qFirst = (m_first-m_delta) >> 1;
01381                 Integer halfStep = m_step >> 1;
01382                 for (unsigned int i = 0; i < primeTableSize; ++i)
01383                 {
01384                         word16 p = primeTable[i];
01385                         word16 stepInv = m_step.InverseMod(p);
01386                         SieveSingle(m_sieve, p, m_first, m_step, stepInv);
01387 
01388                         word16 halfStepInv = 2*stepInv < p ? 2*stepInv : 2*stepInv-p;
01389                         SieveSingle(m_sieve, p, qFirst, halfStep, halfStepInv);
01390                 }
01391         }
01392 }
01393 
01394 bool FirstPrime(Integer &p, const Integer &max, const Integer &equiv, const Integer &mod, const PrimeSelector *pSelector)
01395 {
01396         assert(!equiv.IsNegative() && equiv < mod);
01397 
01398         Integer gcd = GCD(equiv, mod);
01399         if (gcd != Integer::One())
01400         {
01401                 // the only possible prime p such that p%mod==equiv where GCD(mod,equiv)!=1 is GCD(mod,equiv)
01402                 if (p <= gcd && gcd <= max && IsPrime(gcd) && (!pSelector || pSelector->IsAcceptable(gcd)))
01403                 {
01404                         p = gcd;
01405                         return true;
01406                 }
01407                 else
01408                         return false;
01409         }
01410 
01411         unsigned int primeTableSize;
01412         const word16 * primeTable = GetPrimeTable(primeTableSize);
01413 
01414         if (p <= primeTable[primeTableSize-1])
01415         {
01416                 const word16 *pItr;
01417 
01418                 --p;
01419                 if (p.IsPositive())
01420                         pItr = std::upper_bound(primeTable, primeTable+primeTableSize, (word)p.ConvertToLong());
01421                 else
01422                         pItr = primeTable;
01423 
01424                 while (pItr < primeTable+primeTableSize && !(*pItr%mod == equiv && (!pSelector || pSelector->IsAcceptable(*pItr))))
01425                         ++pItr;
01426 
01427                 if (pItr < primeTable+primeTableSize)
01428                 {
01429                         p = *pItr;
01430                         return p <= max;
01431                 }
01432 
01433                 p = primeTable[primeTableSize-1]+1;
01434         }
01435 
01436         assert(p > primeTable[primeTableSize-1]);
01437 
01438         if (mod.IsOdd())
01439                 return FirstPrime(p, max, CRT(equiv, mod, 1, 2, 1), mod<<1, pSelector);
01440 
01441         p += (equiv-p)%mod;
01442 
01443         if (p>max)
01444                 return false;
01445 
01446         PrimeSieve sieve(p, max, mod);
01447 
01448         while (sieve.NextCandidate(p))
01449         {
01450                 if ((!pSelector || pSelector->IsAcceptable(p)) && FastProbablePrimeTest(p) && IsPrime(p))
01451                         return true;
01452         }
01453 
01454         return false;
01455 }
01456 
01457 Integer CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q, const Integer &u)
01458 {
01459         // isn't operator overloading great?
01460         return p * (u * (xq-xp) % q) + xp;
01461 }
01462 
01463 Integer CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q)
01464 {
01465         return CRT(xp, p, xq, q, EuclideanMultiplicativeInverse(p, q));
01466 }
01467 
01468 Integer ModularRoot(const Integer &a, const Integer &dp, const Integer &dq,
01469                                         const Integer &p, const Integer &q, const Integer &u)
01470 {
01471         Integer p2 = ModularExponentiation((a % p), dp, p);
01472         Integer q2 = ModularExponentiation((a % q), dq, q);
01473         return CRT(p2, p, q2, q, u);
01474 }
01475 
01476 Integer ModularRoot(const Integer &a, const Integer &e,
01477                                         const Integer &p, const Integer &q)
01478 {
01479         Integer dp = EuclideanMultiplicativeInverse(e, p-1);
01480         Integer dq = EuclideanMultiplicativeInverse(e, q-1);
01481         Integer u = EuclideanMultiplicativeInverse(p, q);
01482         assert(!!dp && !!dq && !!u);
01483         return ModularRoot(a, dp, dq, p, q, u);
01484 }
01485 
01486 int Jacobi(const Integer &aIn, const Integer &bIn)
01487 {
01488         assert(bIn.IsOdd());
01489 
01490         Integer b = bIn, a = aIn%bIn;
01491         int result = 1;
01492 
01493         while (!!a)
01494         {
01495                 unsigned i=0;
01496                 while (a.GetBit(i)==0)
01497                         i++;
01498                 a>>=i;
01499 
01500                 if (i%2==1 && (b%8==3 || b%8==5))
01501                         result = -result;
01502 
01503                 if (a%4==3 && b%4==3)
01504                         result = -result;
01505 
01506                 std::swap(a, b);
01507                 a %= b;
01508         }
01509 
01510         return (b==1) ? result : 0;
01511 }
01512 
01513 Integer Lucas(const Integer &e, const Integer &pIn, const Integer &n)
01514 {
01515         unsigned i = e.BitCount();
01516         if (i==0)
01517                 return Integer::Two();
01518 
01519         MontgomeryRepresentation m(n);
01520         Integer p=m.ConvertIn(pIn%n), two=m.ConvertIn(Integer::Two());
01521         Integer v=p, v1=m.Subtract(m.Square(p), two);
01522 
01523         i--;
01524         while (i--)
01525         {
01526                 if (e.GetBit(i))
01527                 {
01528                         // v = (v*v1 - p) % m;
01529                         v = m.Subtract(m.Multiply(v,v1), p);
01530                         // v1 = (v1*v1 - 2) % m;
01531                         v1 = m.Subtract(m.Square(v1), two);
01532                 }
01533                 else
01534                 {
01535                         // v1 = (v*v1 - p) % m;
01536                         v1 = m.Subtract(m.Multiply(v,v1), p);
01537                         // v = (v*v - 2) % m;
01538                         v = m.Subtract(m.Square(v), two);
01539                 }
01540         }
01541         return m.ConvertOut(v);
01542 }
01543 
01544 Integer InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q, const Integer &u)
01545 {
01546         Integer d = (m*m-4);
01547         Integer p2 = p-Jacobi(d,p);
01548         Integer q2 = q-Jacobi(d,q);
01549         return CRT(Lucas(EuclideanMultiplicativeInverse(e,p2), m, p), p, Lucas(EuclideanMultiplicativeInverse(e,q2), m, q), q, u);
01550 }
01551 
01552 Integer InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q)
01553 {
01554         return InverseLucas(e, m, p, q, EuclideanMultiplicativeInverse(p, q));
01555 }
01556 
01557 NAMESPACE_END
01558 
01559 #endif
01560 ////////////////////////////////////////////////////////////////////////////////
01561 
01562 
01563 
01564 ////////////////////////////////////////////////////////////////////////////////
01565 #ifndef CRYPTOPP_OIDS_H
01566 #define CRYPTOPP_OIDS_H
01567 
01568 // crypto-related ASN.1 object identifiers
01569 
01570 //- #include "asn.h"
01571 
01572 namespace CryptoPP {
01573 
01574 namespace ASN1 {
01575 
01576 #define DEFINE_OID(value, name) inline OID name() {return value;}
01577 
01578 DEFINE_OID(1, iso)
01579         DEFINE_OID(iso()+2, member_body)
01580                 DEFINE_OID(member_body()+840, iso_us)
01581                         DEFINE_OID(iso_us()+10040, ansi_x9_57)
01582                                 DEFINE_OID(ansi_x9_57()+4+1, id_dsa)
01583                         DEFINE_OID(iso_us()+10045, ansi_x9_62)
01584                                 DEFINE_OID(ansi_x9_62()+1, id_fieldType)
01585                                         DEFINE_OID(id_fieldType()+1, prime_field)
01586                                         DEFINE_OID(id_fieldType()+2, characteristic_two_field)
01587                                                 DEFINE_OID(characteristic_two_field()+3, id_characteristic_two_basis)
01588                                                         DEFINE_OID(id_characteristic_two_basis()+1, gnBasis)
01589                                                         DEFINE_OID(id_characteristic_two_basis()+2, tpBasis)
01590                                                         DEFINE_OID(id_characteristic_two_basis()+3, ppBasis)
01591                                 DEFINE_OID(ansi_x9_62()+2, id_publicKeyType)
01592                                         DEFINE_OID(id_publicKeyType()+1, id_ecPublicKey)
01593                                 DEFINE_OID(ansi_x9_62()+3, ansi_x9_62_curves)
01594                                         DEFINE_OID(ansi_x9_62_curves()+1, ansi_x9_62_curves_prime)
01595                                                 DEFINE_OID(ansi_x9_62_curves_prime()+1, secp192r1)
01596                                                 DEFINE_OID(ansi_x9_62_curves_prime()+7, secp256r1)
01597                         DEFINE_OID(iso_us()+113549, rsadsi)
01598                                 DEFINE_OID(rsadsi()+1, pkcs)
01599                                         DEFINE_OID(pkcs()+1, pkcs_1)
01600                                                 DEFINE_OID(pkcs_1()+1, rsaEncryption)
01601                                 DEFINE_OID(rsadsi()+2, rsadsi_digestAlgorithm)
01602                                         DEFINE_OID(rsadsi_digestAlgorithm()+2, id_md2)
01603                                         DEFINE_OID(rsadsi_digestAlgorithm()+5, id_md5)
01604         DEFINE_OID(iso()+3, identified_organization)
01605                 DEFINE_OID(identified_organization()+14, oiw)
01606                         DEFINE_OID(oiw()+14, oiw_secsig)
01607                                 DEFINE_OID(oiw_secsig()+2, oiw_secsig_algorithms)
01608                                         DEFINE_OID(oiw_secsig_algorithms()+26, id_sha1)
01609                 DEFINE_OID(identified_organization()+36, teletrust)
01610                         DEFINE_OID(teletrust()+3+2+1, id_ripemd160)
01611                 DEFINE_OID(identified_organization()+132, certicom)
01612                         DEFINE_OID(certicom()+0, certicom_ellipticCurve)
01613                                 // these are sorted by curve type and then by OID
01614                                 // first curves based on GF(p)
01615                                 DEFINE_OID(certicom_ellipticCurve()+6, secp112r1)
01616                                 DEFINE_OID(certicom_ellipticCurve()+7, secp112r2)
01617                                 DEFINE_OID(certicom_ellipticCurve()+8, secp160r1)
01618                                 DEFINE_OID(certicom_ellipticCurve()+9, secp160k1)
01619                                 DEFINE_OID(certicom_ellipticCurve()+10, secp256k1)
01620                                 DEFINE_OID(certicom_ellipticCurve()+28, secp128r1)
01621                                 DEFINE_OID(certicom_ellipticCurve()+29, secp128r2)
01622                                 DEFINE_OID(certicom_ellipticCurve()+30, secp160r2)
01623                                 DEFINE_OID(certicom_ellipticCurve()+31, secp192k1)
01624                                 DEFINE_OID(certicom_ellipticCurve()+32, secp224k1)
01625                                 DEFINE_OID(certicom_ellipticCurve()+33, secp224r1)
01626                                 DEFINE_OID(certicom_ellipticCurve()+34, secp384r1)
01627                                 DEFINE_OID(certicom_ellipticCurve()+35, secp521r1)
01628                                 // then curves based on GF(2^n)
01629                                 DEFINE_OID(certicom_ellipticCurve()+1, sect163k1)
01630                                 DEFINE_OID(certicom_ellipticCurve()+2, sect163r1)
01631                                 DEFINE_OID(certicom_ellipticCurve()+3, sect239k1)
01632                                 DEFINE_OID(certicom_ellipticCurve()+4, sect113r1)
01633                                 DEFINE_OID(certicom_ellipticCurve()+5, sect113r2)
01634                                 DEFINE_OID(certicom_ellipticCurve()+15, sect163r2)
01635                                 DEFINE_OID(certicom_ellipticCurve()+16, sect283k1)
01636                                 DEFINE_OID(certicom_ellipticCurve()+17, sect283r1)
01637                                 DEFINE_OID(certicom_ellipticCurve()+22, sect131r1)
01638                                 DEFINE_OID(certicom_ellipticCurve()+23, sect131r2)
01639                                 DEFINE_OID(certicom_ellipticCurve()+24, sect193r1)
01640                                 DEFINE_OID(certicom_ellipticCurve()+25, sect193r2)
01641                                 DEFINE_OID(certicom_ellipticCurve()+26, sect233k1)
01642                                 DEFINE_OID(certicom_ellipticCurve()+27, sect233r1)
01643                                 DEFINE_OID(certicom_ellipticCurve()+36, sect409k1)
01644                                 DEFINE_OID(certicom_ellipticCurve()+37, sect409r1)
01645                                 DEFINE_OID(certicom_ellipticCurve()+38, sect571k1)
01646                                 DEFINE_OID(certicom_ellipticCurve()+39, sect571r1)
01647 DEFINE_OID(2, joint_iso_ccitt)
01648         DEFINE_OID(joint_iso_ccitt()+16, country)
01649                 DEFINE_OID(country()+840, joint_iso_ccitt_us)
01650                         DEFINE_OID(joint_iso_ccitt_us()+1, us_organization)
01651                                 DEFINE_OID(us_organization()+101, us_gov)
01652                                         DEFINE_OID(us_gov()+3, csor)
01653                                                 DEFINE_OID(csor()+4, nistalgorithms)
01654                                                         DEFINE_OID(nistalgorithms()+1, aes)
01655                                                                 DEFINE_OID(aes()+1, id_aes128_ECB)
01656                                                                 DEFINE_OID(aes()+2, id_aes128_cbc)
01657                                                                 DEFINE_OID(aes()+3, id_aes128_ofb)
01658                                                                 DEFINE_OID(aes()+4, id_aes128_cfb)
01659                                                                 DEFINE_OID(aes()+21, id_aes192_ECB)
01660                                                                 DEFINE_OID(aes()+22, id_aes192_cbc)
01661                                                                 DEFINE_OID(aes()+23, id_aes192_ofb)
01662                                                                 DEFINE_OID(aes()+24, id_aes192_cfb)
01663                                                                 DEFINE_OID(aes()+41, id_aes256_ECB)
01664                                                                 DEFINE_OID(aes()+42, id_aes256_cbc)
01665                                                                 DEFINE_OID(aes()+43, id_aes256_ofb)
01666                                                                 DEFINE_OID(aes()+44, id_aes256_cfb)
01667                                                         DEFINE_OID(nistalgorithms()+2, nist_hashalgs)
01668                                                                 DEFINE_OID(nist_hashalgs()+1, id_sha256)
01669                                                                 DEFINE_OID(nist_hashalgs()+2, id_sha384)
01670                                                                 DEFINE_OID(nist_hashalgs()+3, id_sha512)
01671 
01672 NAMESPACE_END
01673 
01674 NAMESPACE_END
01675 
01676 #endif
01677 ////////////////////////////////////////////////////////////////////////////////
01678 
01679 
01680 
01681 ////////////////////////////////////////////////////////////////////////////////
01682 // integer.cpp - written and placed in the public domain by Wei Dai
01683 // contains public domain code contributed by Alister Lee and Leonard Janke
01684 
01685 //- #include "pch.h"
01686 
01687 #ifndef CRYPTOPP_IMPORTS
01688 
01689 //- #include "integer.h"
01690 //- #include "modarith.h"
01691 //- #include "nbtheory.h"
01692 //- #include "asn.h"
01693 //- #include "oids.h"
01694 //- #include "words.h"
01695 //- #include "algparam.h"
01696 //- #include "pubkey.h"         // for P1363_KDF2
01697 //- #include "sha.h"
01698 
01699 #include <iostream>
01700 
01701 #ifdef SSE2_INTRINSICS_AVAILABLE
01702         #ifdef __GNUC__
01703                 #include <xmmintrin.h>
01704                 #include <signal.h>
01705                 #include <setjmp.h>
01706                 #ifdef CRYPTOPP_MEMALIGN_AVAILABLE
01707                         #include <malloc.h>
01708                 #else
01709                         #include <stdlib.h>
01710                 #endif
01711         #else
01712                 #include <emmintrin.h>
01713         #endif
01714 #elif defined(_MSC_VER) && defined(_M_IX86)
01715         #pragma message("You do not seem to have the Visual C++ Processor Pack installed, so use of SSE2 intrinsics will be disabled.")
01716 //#elif defined(__GNUC__) && defined(__i386__)
01717 //      #warning "You do not have GCC 3.3 or later, or did not specify -msse2 compiler option, so use of SSE2 intrinsics will be disabled."
01718 #endif
01719 
01720 namespace CryptoPP {
01721 
01722 bool FunctionAssignIntToInteger(const std::type_info &valueType, void *pInteger, const void *pInt)
01723 {
01724         if (valueType != typeid(Integer))
01725                 return false;
01726         *reinterpret_cast<Integer *>(pInteger) = *reinterpret_cast<const int *>(pInt);
01727         return true;
01728 }
01729 
01730 static const char s_RunAtStartup = (AssignIntToInteger = FunctionAssignIntToInteger, 0);
01731 
01732 #ifdef SSE2_INTRINSICS_AVAILABLE
01733 template <class T>
01734 CPP_TYPENAME AllocatorBase<T>::pointer AlignedAllocator<T>::allocate(size_type n, const void *)
01735 {
01736         CheckSize(n);
01737         if (n == 0)
01738                 return NULL;
01739         if (n >= 4)
01740         {
01741                 void *p;
01742         #ifdef CRYPTOPP_MM_MALLOC_AVAILABLE
01743                 while (!(p = _mm_malloc(sizeof(T)*n, 16)))
01744         #elif defined(CRYPTOPP_MEMALIGN_AVAILABLE)
01745                 while (!(p = memalign(16, sizeof(T)*n)))
01746         #elif defined(CRYPTOPP_MALLOC_ALIGNMENT_IS_16)
01747                 while (!(p = malloc(sizeof(T)*n)))
01748         #else
01749                 while (!(p = (byte *)malloc(sizeof(T)*n + 8)))  // assume malloc alignment is at least 8
01750         #endif
01751                         CallNewHandler();
01752 
01753         #ifdef CRYPTOPP_NO_ALIGNED_ALLOC
01754                 assert(m_pBlock == NULL);
01755                 m_pBlock = p;
01756                 if (!IsAlignedOn(p, 16))
01757                 {
01758                         assert(IsAlignedOn(p, 8));
01759                         p = (byte *)p + 8;
01760                 }
01761         #endif
01762 
01763                 assert(IsAlignedOn(p, 16));
01764                 return (T*)p;
01765         }
01766         return new T[n];
01767 }
01768 
01769 template <class T>
01770 void AlignedAllocator<T>::deallocate(void *p, size_type n)
01771 {
01772         memset(p, 0, n*sizeof(T));
01773         if (n >= 4)
01774         {
01775                 #ifdef CRYPTOPP_MM_MALLOC_AVAILABLE
01776                         _mm_free(p);
01777                 #elif defined(CRYPTOPP_NO_ALIGNED_ALLOC)
01778                         assert(m_pBlock == p || (byte *)m_pBlock+8 == p);
01779                         free(m_pBlock);
01780                         m_pBlock = NULL;
01781                 #else
01782                         free(p);
01783                 #endif
01784         }
01785         else
01786                 delete [] (T *)p;
01787 }
01788 #endif
01789 
01790 static int Compare(const word *A, const word *B, unsigned int N)
01791 {
01792         while (N--)
01793                 if (A[N] > B[N])
01794                         return 1;
01795                 else if (A[N] < B[N])
01796                         return -1;
01797 
01798         return 0;
01799 }
01800 
01801 static word Increment(word *A, unsigned int N, word B=1)
01802 {
01803         assert(N);
01804         word t = A[0];
01805         A[0] = t+B;
01806         if (A[0] >= t)
01807                 return 0;
01808         for (unsigned i=1; i<N; i++)
01809                 if (++A[i])
01810                         return 0;
01811         return 1;
01812 }
01813 
01814 static word Decrement(word *A, unsigned int N, word B=1)
01815 {
01816         assert(N);
01817         word t = A[0];
01818         A[0] = t-B;
01819         if (A[0] <= t)
01820                 return 0;
01821         for (unsigned i=1; i<N; i++)
01822                 if (A[i]--)
01823                         return 0;
01824         return 1;
01825 }
01826 
01827 static void TwosComplement(word *A, unsigned int N)
01828 {
01829         Decrement(A, N);
01830         for (unsigned i=0; i<N; i++)
01831                 A[i] = ~A[i];
01832 }
01833 
01834 static word AtomicInverseModPower2(word A)
01835 {
01836         assert(A%2==1);
01837 
01838         word R=A%8;
01839 
01840         for (unsigned i=3; i<WORD_BITS; i*=2)
01841                 R = R*(2-R*A);
01842 
01843         assert(R*A==1);
01844         return R;
01845 }
01846 
01847 // ********************************************************
01848 
01849 class DWord
01850 {
01851 public:
01852         DWord() {}
01853 
01854 #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
01855         explicit DWord(word low)
01856         {
01857                 m_whole = low;
01858         }
01859 #else
01860         explicit DWord(word low)
01861         {
01862                 m_halfs.low = low;
01863                 m_halfs.high = 0;
01864         }
01865 #endif
01866 
01867         DWord(word low, word high)
01868         {
01869                 m_halfs.low = low;
01870                 m_halfs.high = high;
01871         }
01872 
01873         static DWord Multiply(word a, word b)
01874         {
01875                 DWord r;
01876                 #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
01877                         r.m_whole = (dword)a * b;
01878                 #elif defined(__alpha__)
01879                         r.m_halfs.low = a*b; __asm__("umulh %1,%2,%0" : "=r" (r.m_halfs.high) : "r" (a), "r" (b));
01880                 #elif defined(__ia64__)
01881                         r.m_halfs.low = a*b; __asm__("xmpy.hu %0=%1,%2" : "=f" (r.m_halfs.high) : "f" (a), "f" (b));
01882                 #elif defined(_ARCH_PPC64)
01883                         r.m_halfs.low = a*b; __asm__("mulhdu %0,%1,%2" : "=r" (r.m_halfs.high) : "r" (a), "r" (b) : "cc");
01884                 #elif defined(__x86_64__)
01885                         __asm__("mulq %3" : "=d" (r.m_halfs.high), "=a" (r.m_halfs.low) : "a" (a), "rm" (b) : "cc");
01886                 #elif defined(__mips64)
01887                         __asm__("dmultu %2,%3" : "=h" (r.m_halfs.high), "=l" (r.m_halfs.low) : "r" (a), "r" (b));
01888                 #elif defined(_M_IX86)
01889                         // for testing
01890                         word64 t = (word64)a * b;
01891                         r.m_halfs.high = ((word32 *)(&t))[1];
01892                         r.m_halfs.low = (word32)t;
01893                 #else
01894                         #error can not implement DWord
01895                 #endif
01896                 return r;
01897         }
01898 
01899         static DWord MultiplyAndAdd(word a, word b, word c)
01900         {
01901                 DWord r = Multiply(a, b);
01902                 return r += c;
01903         }
01904 
01905         DWord & operator+=(word a)
01906         {
01907                 #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
01908                         m_whole = m_whole + a;
01909                 #else
01910                         m_halfs.low += a;
01911                         m_halfs.high += (m_halfs.low < a);
01912                 #endif
01913                 return *this;
01914         }
01915 
01916         DWord operator+(word a)
01917         {
01918                 DWord r;
01919                 #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
01920                         r.m_whole = m_whole + a;
01921                 #else
01922                         r.m_halfs.low = m_halfs.low + a;
01923                         r.m_halfs.high = m_halfs.high + (r.m_halfs.low < a);
01924                 #endif
01925                 return r;
01926         }
01927 
01928         DWord operator-(DWord a)
01929         {
01930                 DWord r;
01931                 #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
01932                         r.m_whole = m_whole - a.m_whole;
01933                 #else
01934                         r.m_halfs.low = m_halfs.low - a.m_halfs.low;
01935                         r.m_halfs.high = m_halfs.high - a.m_halfs.high - (r.m_halfs.low > m_halfs.low);
01936                 #endif
01937                 return r;
01938         }
01939 
01940         DWord operator-(word a)
01941         {
01942                 DWord r;
01943                 #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
01944                         r.m_whole = m_whole - a;
01945                 #else
01946                         r.m_halfs.low = m_halfs.low - a;
01947                         r.m_halfs.high = m_halfs.high - (r.m_halfs.low > m_halfs.low);
01948                 #endif
01949                 return r;
01950         }
01951 
01952         // returns quotient, which must fit in a word
01953         word operator/(word divisor);
01954 
01955         word operator%(word a);
01956 
01957         bool operator!() const
01958         {
01959         #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
01960                 return !m_whole;
01961         #else
01962                 return !m_halfs.high && !m_halfs.low;
01963         #endif
01964         }
01965 
01966         word GetLowHalf() const {return m_halfs.low;}
01967         word GetHighHalf() const {return m_halfs.high;}
01968         word GetHighHalfAsBorrow() const {return 0-m_halfs.high;}
01969 
01970 private:
01971         union
01972         {
01973         #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
01974                 dword m_whole;
01975         #endif
01976                 struct
01977                 {
01978                 #ifdef IS_LITTLE_ENDIAN
01979                         word low;
01980                         word high;
01981                 #else
01982                         word high;
01983                         word low;
01984                 #endif
01985                 } m_halfs;
01986         };
01987 };
01988 
01989 class Word
01990 {
01991 public:
01992         Word() {}
01993 
01994         Word(word value)
01995         {
01996                 m_whole = value;
01997         }
01998 
01999         Word(hword low, hword high)
02000         {
02001                 m_whole = low | (word(high) << (WORD_BITS/2));
02002         }
02003 
02004         static Word Multiply(hword a, hword b)
02005         {
02006                 Word r;
02007                 r.m_whole = (word)a * b;
02008                 return r;
02009         }
02010 
02011         Word operator-(Word a)
02012         {
02013                 Word r;
02014                 r.m_whole = m_whole - a.m_whole;
02015                 return r;
02016         }
02017 
02018         Word operator-(hword a)
02019         {
02020                 Word r;
02021                 r.m_whole = m_whole - a;
02022                 return r;
02023         }
02024 
02025         // returns quotient, which must fit in a word
02026         hword operator/(hword divisor)
02027         {
02028                 return hword(m_whole / divisor);
02029         }
02030 
02031         bool operator!() const
02032         {
02033                 return !m_whole;
02034         }
02035 
02036         word GetWhole() const {return m_whole;}
02037         hword GetLowHalf() const {return hword(m_whole);}
02038         hword GetHighHalf() const {return hword(m_whole>>(WORD_BITS/2));}
02039         hword GetHighHalfAsBorrow() const {return 0-hword(m_whole>>(WORD_BITS/2));}
02040 
02041 private:
02042         word m_whole;
02043 };
02044 
02045 // do a 3 word by 2 word divide, returns quotient and leaves remainder in A
02046 template <class S, class D>
02047 S DivideThreeWordsByTwo(S *A, S B0, S B1, D* /* dummy */ = NULL)
02048 {
02049         // assert {A[2],A[1]} < {B1,B0}, so quotient can fit in a S
02050         assert(A[2] < B1 || (A[2]==B1 && A[1] < B0));
02051 
02052         // estimate the quotient: do a 2 S by 1 S divide
02053         S Q;
02054         if (S(B1+1) == 0)
02055                 Q = A[2];
02056         else
02057                 Q = D(A[1], A[2]) / S(B1+1);
02058 
02059         // now subtract Q*B from A
02060         D p = D::Multiply(B0, Q);
02061         D u = (D) A[0] - p.GetLowHalf();
02062         A[0] = u.GetLowHalf();
02063         u = (D) A[1] - p.GetHighHalf() - u.GetHighHalfAsBorrow() - D::Multiply(B1, Q);
02064         A[1] = u.GetLowHalf();
02065         A[2] += u.GetHighHalf();
02066 
02067         // Q <= actual quotient, so fix it
02068         while (A[2] || A[1] > B1 || (A[1]==B1 && A[0]>=B0))
02069         {
02070                 u = (D) A[0] - B0;
02071                 A[0] = u.GetLowHalf();
02072                 u = (D) A[1] - B1 - u.GetHighHalfAsBorrow();
02073                 A[1] = u.GetLowHalf();
02074                 A[2] += u.GetHighHalf();
02075                 Q++;
02076                 assert(Q);      // shouldn't overflow
02077         }
02078 
02079         return Q;
02080 }
02081 
02082 // do a 4 word by 2 word divide, returns 2 word quotient in Q0 and Q1
02083 template <class S, class D>
02084 inline D DivideFourWordsByTwo(S *T, const D &Al, const D &Ah, const D &B)
02085 {
02086         if (!B) // if divisor is 0, we assume divisor==2**(2*WORD_BITS)
02087                 return D(Ah.GetLowHalf(), Ah.GetHighHalf());
02088         else
02089         {
02090                 S Q[2];
02091                 T[0] = Al.GetLowHalf();
02092                 T[1] = Al.GetHighHalf();
02093                 T[2] = Ah.GetLowHalf();
02094                 T[3] = Ah.GetHighHalf();
02095                 Q[1] = DivideThreeWordsByTwo<S, D>(T+1, B.GetLowHalf(), B.GetHighHalf());
02096                 Q[0] = DivideThreeWordsByTwo<S, D>(T, B.GetLowHalf(), B.GetHighHalf());
02097                 return D(Q[0], Q[1]);
02098         }
02099 }
02100 
02101 // returns quotient, which must fit in a word
02102 inline word DWord::operator/(word a)
02103 {
02104         #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
02105                 return word(m_whole / a);
02106         #else
02107                 hword r[4];
02108                 return DivideFourWordsByTwo<hword, Word>(r, m_halfs.low, m_halfs.high, a).GetWhole();
02109         #endif
02110 }
02111 
02112 inline word DWord::operator%(word a)
02113 {
02114         #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
02115                 return word(m_whole % a);
02116         #else
02117                 if (a < (word(1) << (WORD_BITS/2)))
02118                 {
02119                         hword h = hword(a);
02120                         word r = m_halfs.high % h;
02121                         r = ((m_halfs.low >> (WORD_BITS/2)) + (r << (WORD_BITS/2))) % h;
02122                         return hword((hword(m_halfs.low) + (r << (WORD_BITS/2))) % h);
02123                 }
02124                 else
02125                 {
02126                         hword r[4];
02127                         DivideFourWordsByTwo<hword, Word>(r, m_halfs.low, m_halfs.high, a);
02128                         return Word(r[0], r[1]).GetWhole();
02129                 }
02130         #endif
02131 }
02132 
02133 // ********************************************************
02134 
02135 class Portable
02136 {
02137 public:
02138         static word Add(word *C, const word *A, const word *B, unsigned int N);
02139         static word Subtract(word *C, const word *A, const word *B, unsigned int N);
02140 
02141         static inline void Multiply2(word *C, const word *A, const word *B);
02142         static inline word Multiply2Add(word *C, const word *A, const word *B);
02143         static void Multiply4(word *C, const word *A, const word *B);
02144         static void Multiply8(word *C, const word *A, const word *B);
02145         static inline unsigned int MultiplyRecursionLimit() {return 8;}
02146 
02147         static inline void Multiply2Bottom(word *C, const word *A, const word *B);
02148         static void Multiply4Bottom(word *C, const word *A, const word *B);
02149         static void Multiply8Bottom(word *C, const word *A, const word *B);
02150         static inline unsigned int MultiplyBottomRecursionLimit() {return 8;}
02151 
02152         static void Square2(word *R, const word *A);
02153         static void Square4(word *R, const word *A);
02154         static void Square8(word* /* R */, const word* /* A */) {assert(false);}
02155         static inline unsigned int SquareRecursionLimit() {return 4;}
02156 };
02157 
02158 word Portable::Add(word *C, const word *A, const word *B, unsigned int N)
02159 {
02160         assert (N%2 == 0);
02161 
02162         DWord u(0, 0);
02163         for (unsigned int i = 0; i < N; i+=2)
02164         {
02165                 u = DWord(A[i]) + B[i] + u.GetHighHalf();
02166                 C[i] = u.GetLowHalf();
02167                 u = DWord(A[i+1]) + B[i+1] + u.GetHighHalf();
02168                 C[i+1] = u.GetLowHalf();
02169         }
02170         return u.GetHighHalf();
02171 }
02172 
02173 word Portable::Subtract(word *C, const word *A, const word *B, unsigned int N)
02174 {
02175         assert (N%2 == 0);
02176 
02177         DWord u(0, 0);
02178         for (unsigned int i = 0; i < N; i+=2)
02179         {
02180                 u = (DWord) A[i] - B[i] - u.GetHighHalfAsBorrow();
02181                 C[i] = u.GetLowHalf();
02182                 u = (DWord) A[i+1] - B[i+1] - u.GetHighHalfAsBorrow();
02183                 C[i+1] = u.GetLowHalf();
02184         }
02185         return 0-u.GetHighHalf();
02186 }
02187 
02188 void Portable::Multiply2(word *C, const word *A, const word *B)
02189 {
02190         // this segment is the branchless equivalent of above
02191         word D[4] = {A[1]-A[0], A[0]-A[1], B[0]-B[1], B[1]-B[0]};
02192         unsigned int ai = A[1] < A[0];
02193         unsigned int bi = B[0] < B[1];
02194         unsigned int di = ai & bi;
02195         DWord d = DWord::Multiply(D[di], D[di+2]);
02196         D[1] = D[3] = 0;
02197         unsigned int si = ai + !bi;
02198         word s = D[si];
02199 
02200         DWord A0B0 = DWord::Multiply(A[0], B[0]);
02201         C[0] = A0B0.GetLowHalf();
02202 
02203         DWord A1B1 = DWord::Multiply(A[1], B[1]);
02204         DWord t = (DWord) A0B0.GetHighHalf() + A0B0.GetLowHalf() + d.GetLowHalf() + A1B1.GetLowHalf();
02205         C[1] = t.GetLowHalf();
02206 
02207         t = A1B1 + t.GetHighHalf() + A0B0.GetHighHalf() + d.GetHighHalf() + A1B1.GetHighHalf() - s;
02208         C[2] = t.GetLowHalf();
02209         C[3] = t.GetHighHalf();
02210 }
02211 
02212 inline void Portable::Multiply2Bottom(word *C, const word *A, const word *B)
02213 {
02214         DWord t = DWord::Multiply(A[0], B[0]);
02215         C[0] = t.GetLowHalf();
02216         C[1] = t.GetHighHalf() + A[0]*B[1] + A[1]*B[0];
02217 }
02218 
02219 word Portable::Multiply2Add(word *C, const word *A, const word *B)
02220 {
02221         word D[4] = {A[1]-A[0], A[0]-A[1], B[0]-B[1], B[1]-B[0]};
02222         unsigned int ai = A[1] < A[0];
02223         unsigned int bi = B[0] < B[1];
02224         unsigned int di = ai & bi;
02225         DWord d = DWord::Multiply(D[di], D[di+2]);
02226         D[1] = D[3] = 0;
02227         unsigned int si = ai + !bi;
02228         word s = D[si];
02229 
02230         DWord A0B0 = DWord::Multiply(A[0], B[0]);
02231         DWord t = A0B0 + C[0];
02232         C[0] = t.GetLowHalf();
02233 
02234         DWord A1B1 = DWord::Multiply(A[1], B[1]);
02235         t = (DWord) t.GetHighHalf() + A0B0.GetLowHalf() + d.GetLowHalf() + A1B1.GetLowHalf() + C[1];
02236         C[1] = t.GetLowHalf();
02237 
02238         t = (DWord) t.GetHighHalf() + A1B1.GetLowHalf() + A0B0.GetHighHalf() + d.GetHighHalf() + A1B1.GetHighHalf() - s + C[2];
02239         C[2] = t.GetLowHalf();
02240 
02241         t = (DWord) t.GetHighHalf() + A1B1.GetHighHalf() + C[3];
02242         C[3] = t.GetLowHalf();
02243         return t.GetHighHalf();
02244 }
02245 
02246 #define MulAcc(x, y)                                                            \
02247         p = DWord::MultiplyAndAdd(A[x], B[y], c);               \
02248         c = p.GetLowHalf();                                                             \
02249         p = (DWord) d + p.GetHighHalf();                                        \
02250         d = p.GetLowHalf();                                                             \
02251         e += p.GetHighHalf();
02252 
02253 #define SaveMulAcc(s, x, y)                                             \
02254         R[s] = c;                                                                               \
02255         p = DWord::MultiplyAndAdd(A[x], B[y], d);                               \
02256         c = p.GetLowHalf();                                                             \
02257         p = (DWord) e + p.GetHighHalf();                                        \
02258         d = p.GetLowHalf();                                                             \
02259         e = p.GetHighHalf();
02260 
02261 #define SquAcc(x, y)                                                            \
02262         q = DWord::Multiply(A[x], A[y]);        \
02263         p = q + c;                                      \
02264         c = p.GetLowHalf();                                                             \
02265         p = (DWord) d + p.GetHighHalf();                                        \
02266         d = p.GetLowHalf();                                                             \
02267         e += p.GetHighHalf();                   \
02268         p = q + c;                                      \
02269         c = p.GetLowHalf();                                                             \
02270         p = (DWord) d + p.GetHighHalf();                                        \
02271         d = p.GetLowHalf();                                                             \
02272         e += p.GetHighHalf();
02273 
02274 #define SaveSquAcc(s, x, y)                                             \
02275         R[s] = c;                                                                               \
02276         q = DWord::Multiply(A[x], A[y]);        \
02277         p = q + d;                                      \
02278         c = p.GetLowHalf();                                                             \
02279         p = (DWord) e + p.GetHighHalf();                                        \
02280         d = p.GetLowHalf();                                                             \
02281         e = p.GetHighHalf();                    \
02282         p = q + c;                                      \
02283         c = p.GetLowHalf();                                                             \
02284         p = (DWord) d + p.GetHighHalf();                                        \
02285         d = p.GetLowHalf();                                                             \
02286         e += p.GetHighHalf();
02287 
02288 void Portable::Multiply4(word *R, const word *A, const word *B)
02289 {
02290         DWord p;
02291         word c, d, e;
02292 
02293         p = DWord::Multiply(A[0], B[0]);
02294         R[0] = p.GetLowHalf();
02295         c = p.GetHighHalf();
02296         d = e = 0;
02297 
02298         MulAcc(0, 1);
02299         MulAcc(1, 0);
02300 
02301         SaveMulAcc(1, 2, 0);
02302         MulAcc(1, 1);
02303         MulAcc(0, 2);
02304 
02305         SaveMulAcc(2, 0, 3);
02306         MulAcc(1, 2);
02307         MulAcc(2, 1);
02308         MulAcc(3, 0);
02309 
02310         SaveMulAcc(3, 3, 1);
02311         MulAcc(2, 2);
02312         MulAcc(1, 3);
02313 
02314         SaveMulAcc(4, 2, 3);
02315         MulAcc(3, 2);
02316 
02317         R[5] = c;
02318         p = DWord::MultiplyAndAdd(A[3], B[3], d);
02319         R[6] = p.GetLowHalf();
02320         R[7] = e + p.GetHighHalf();
02321 }
02322 
02323 void Portable::Square2(word *R, const word *A)
02324 {
02325         DWord p, q;
02326         word c, d, e;
02327 
02328         p = DWord::Multiply(A[0], A[0]);
02329         R[0] = p.GetLowHalf();
02330         c = p.GetHighHalf();
02331         d = e = 0;
02332 
02333         SquAcc(0, 1);
02334 
02335         R[1] = c;
02336         p = DWord::MultiplyAndAdd(A[1], A[1], d);
02337         R[2] = p.GetLowHalf();
02338         R[3] = e + p.GetHighHalf();
02339 }
02340 
02341 void Portable::Square4(word *R, const word *A)
02342 {
02343 #ifdef _MSC_VER
02344         // VC60 workaround: MSVC 6.0 has an optimization bug that makes
02345         // (dword)A*B where either A or B has been cast to a dword before
02346         // very expensive. Revisit this function when this
02347         // bug is fixed.
02348         Multiply4(R, A, A);
02349 #else
02350         const word *B = A;
02351         DWord p, q;
02352         word c, d, e;
02353 
02354         p = DWord::Multiply(A[0], A[0]);
02355         R[0] = p.GetLowHalf();
02356         c = p.GetHighHalf();
02357         d = e = 0;
02358 
02359         SquAcc(0, 1);
02360 
02361         SaveSquAcc(1, 2, 0);
02362         MulAcc(1, 1);
02363 
02364         SaveSquAcc(2, 0, 3);
02365         SquAcc(1, 2);
02366 
02367         SaveSquAcc(3, 3, 1);
02368         MulAcc(2, 2);
02369 
02370         SaveSquAcc(4, 2, 3);
02371 
02372         R[5] = c;
02373         p = DWord::MultiplyAndAdd(A[3], A[3], d);
02374         R[6] = p.GetLowHalf();
02375         R[7] = e + p.GetHighHalf();
02376 #endif
02377 }
02378 
02379 void Portable::Multiply8(word *R, const word *A, const word *B)
02380 {
02381         DWord p;
02382         word c, d, e;
02383 
02384         p = DWord::Multiply(A[0], B[0]);
02385         R[0] = p.GetLowHalf();
02386         c = p.GetHighHalf();
02387         d = e = 0;
02388 
02389         MulAcc(0, 1);
02390         MulAcc(1, 0);
02391 
02392         SaveMulAcc(1, 2, 0);
02393         MulAcc(1, 1);
02394         MulAcc(0, 2);
02395 
02396         SaveMulAcc(2, 0, 3);
02397         MulAcc(1, 2);
02398         MulAcc(2, 1);
02399         MulAcc(3, 0);
02400 
02401         SaveMulAcc(3, 0, 4);
02402         MulAcc(1, 3);
02403         MulAcc(2, 2);
02404         MulAcc(3, 1);
02405         MulAcc(4, 0);
02406 
02407         SaveMulAcc(4, 0, 5);
02408         MulAcc(1, 4);
02409         MulAcc(2, 3);
02410         MulAcc(3, 2);
02411         MulAcc(4, 1);
02412         MulAcc(5, 0);
02413 
02414         SaveMulAcc(5, 0, 6);
02415         MulAcc(1, 5);
02416         MulAcc(2, 4);
02417         MulAcc(3, 3);
02418         MulAcc(4, 2);
02419         MulAcc(5, 1);
02420         MulAcc(6, 0);
02421 
02422         SaveMulAcc(6, 0, 7);
02423         MulAcc(1, 6);
02424         MulAcc(2, 5);
02425         MulAcc(3, 4);
02426         MulAcc(4, 3);
02427         MulAcc(5, 2);
02428         MulAcc(6, 1);
02429         MulAcc(7, 0);
02430 
02431         SaveMulAcc(7, 1, 7);
02432         MulAcc(2, 6);
02433         MulAcc(3, 5);
02434         MulAcc(4, 4);
02435         MulAcc(5, 3);
02436         MulAcc(6, 2);
02437         MulAcc(7, 1);
02438 
02439         SaveMulAcc(8, 2, 7);
02440         MulAcc(3, 6);
02441         MulAcc(4, 5);
02442         MulAcc(5, 4);
02443         MulAcc(6, 3);
02444         MulAcc(7, 2);
02445 
02446         SaveMulAcc(9, 3, 7);
02447         MulAcc(4, 6);
02448         MulAcc(5, 5);
02449         MulAcc(6, 4);
02450         MulAcc(7, 3);
02451 
02452         SaveMulAcc(10, 4, 7);
02453         MulAcc(5, 6);
02454         MulAcc(6, 5);
02455         MulAcc(7, 4);
02456 
02457         SaveMulAcc(11, 5, 7);
02458         MulAcc(6, 6);
02459         MulAcc(7, 5);
02460 
02461         SaveMulAcc(12, 6, 7);
02462         MulAcc(7, 6);
02463 
02464         R[13] = c;
02465         p = DWord::MultiplyAndAdd(A[7], B[7], d);
02466         R[14] = p.GetLowHalf();
02467         R[15] = e + p.GetHighHalf();
02468 }
02469 
02470 void Portable::Multiply4Bottom(word *R, const word *A, const word *B)
02471 {
02472         DWord p;
02473         word c, d, e;
02474 
02475         p = DWord::Multiply(A[0], B[0]);
02476         R[0] = p.GetLowHalf();
02477         c = p.GetHighHalf();
02478         d = e = 0;
02479 
02480         MulAcc(0, 1);
02481         MulAcc(1, 0);
02482 
02483         SaveMulAcc(1, 2, 0);
02484         MulAcc(1, 1);
02485         MulAcc(0, 2);
02486 
02487         R[2] = c;
02488         R[3] = d + A[0] * B[3] + A[1] * B[2] + A[2] * B[1] + A[3] * B[0];
02489 }
02490 
02491 void Portable::Multiply8Bottom(word *R, const word *A, const word *B)
02492 {
02493         DWord p;
02494         word c, d, e;
02495 
02496         p = DWord::Multiply(A[0], B[0]);
02497         R[0] = p.GetLowHalf();
02498         c = p.GetHighHalf();
02499         d = e = 0;
02500 
02501         MulAcc(0, 1);
02502         MulAcc(1, 0);
02503 
02504         SaveMulAcc(1, 2, 0);
02505         MulAcc(1, 1);
02506         MulAcc(0, 2);
02507 
02508         SaveMulAcc(2, 0, 3);
02509         MulAcc(1, 2);
02510         MulAcc(2, 1);
02511         MulAcc(3, 0);
02512 
02513         SaveMulAcc(3, 0, 4);
02514         MulAcc(1, 3);
02515         MulAcc(2, 2);
02516         MulAcc(3, 1);
02517         MulAcc(4, 0);
02518 
02519         SaveMulAcc(4, 0, 5);
02520         MulAcc(1, 4);
02521         MulAcc(2, 3);
02522         MulAcc(3, 2);
02523         MulAcc(4, 1);
02524         MulAcc(5, 0);
02525 
02526         SaveMulAcc(5, 0, 6);
02527         MulAcc(1, 5);
02528         MulAcc(2, 4);
02529         MulAcc(3, 3);
02530         MulAcc(4, 2);
02531         MulAcc(5, 1);
02532         MulAcc(6, 0);
02533 
02534         R[6] = c;
02535         R[7] = d + A[0] * B[7] + A[1] * B[6] + A[2] * B[5] + A[3] * B[4] +
02536                                 A[4] * B[3] + A[5] * B[2] + A[6] * B[1] + A[7] * B[0];
02537 }
02538 
02539 #undef MulAcc
02540 #undef SaveMulAcc
02541 #undef SquAcc
02542 #undef SaveSquAcc
02543 
02544 #ifdef CRYPTOPP_X86ASM_AVAILABLE
02545 
02546 // ************** x86 feature detection ***************
02547 
02548 static void CpuId(word32 input, word32 *output)
02549 {
02550 #ifdef __GNUC__
02551         __asm__
02552         (
02553                 // save ebx in case -fPIC is being used
02554                 "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx"
02555                 : "=a" (output[0]), "=D" (output[1]), "=c" (output[2]), "=d" (output[3])
02556                 : "a" (input)
02557         );
02558 #else
02559         __asm
02560         {
02561                 mov eax, input
02562                 cpuid
02563                 mov edi, output
02564                 mov [edi], eax
02565                 mov [edi+4], ebx
02566                 mov [edi+8], ecx
02567                 mov [edi+12], edx
02568         }
02569 #endif
02570 }
02571 
02572 static bool IsP4()
02573 {
02574         word32 cpuid[4];
02575 
02576         CpuId(0, cpuid);
02577         std::swap(cpuid[2], cpuid[3]);
02578         if (memcmp(cpuid+1, "GenuineIntel", 12) != 0)
02579                 return false;
02580 
02581         CpuId(1, cpuid);
02582         return ((cpuid[0] >> 8) & 0xf) == 0xf;
02583 
02584 }
02585 
02586 
02587 // ************** Pentium/P4 optimizations ***************
02588 
02589 class PentiumOptimized : public Portable
02590 {
02591 public:
02592         static word CRYPTOPP_CDECL Add(word *C, const word *A, const word *B, unsigned int N);
02593         static word CRYPTOPP_CDECL Subtract(word *C, const word *A, const word *B, unsigned int N);
02594         static void CRYPTOPP_CDECL Multiply4(word *C, const word *A, const word *B);
02595         static void CRYPTOPP_CDECL Multiply8(word *C, const word *A, const word *B);
02596         static void CRYPTOPP_CDECL Multiply8Bottom(word *C, const word *A, const word *B);
02597 };
02598 
02599 class P4Optimized
02600 {
02601 public:
02602         static word CRYPTOPP_CDECL Add(word *C, const word *A, const word *B, unsigned int N);
02603         static word CRYPTOPP_CDECL Subtract(word *C, const word *A, const word *B, unsigned int N);
02604 };
02605 
02606 typedef word (CRYPTOPP_CDECL * PAddSub)(word *C, const word *A, const word *B, unsigned int N);
02607 typedef void (CRYPTOPP_CDECL * PMul)(word *C, const word *A, const word *B);
02608 
02609 static PAddSub s_pAdd, s_pSub;
02610 #ifdef SSE2_INTRINSICS_AVAILABLE
02611 static PMul s_pMul4, s_pMul8, s_pMul8B;
02612 #endif
02613 
02614 static void SetPentiumFunctionPointers()
02615 {
02616         if (IsP4())
02617         {
02618                 s_pAdd = &P4Optimized::Add;
02619                 s_pSub = &P4Optimized::Subtract;
02620         }
02621         else
02622         {
02623                 s_pAdd = &PentiumOptimized::Add;
02624                 s_pSub = &PentiumOptimized::Subtract;
02625         }
02626 
02627 #ifdef SSE2_INTRINSICS_AVAILABLE
02628         s_pMul4 = &PentiumOptimized::Multiply4;
02629         s_pMul8 = &PentiumOptimized::Multiply8;
02630         s_pMul8B = &PentiumOptimized::Multiply8Bottom;
02631 #endif
02632 }
02633 
02634 static const char s_RunAtStartupSetPentiumFunctionPointers = (SetPentiumFunctionPointers(), 0);
02635 
02636 class LowLevel : public PentiumOptimized
02637 {
02638 public:
02639         inline static word Add(word *C, const word *A, const word *B, unsigned int N)
02640                 {return s_pAdd(C, A, B, N);}
02641         inline static word Subtract(word *C, const word *A, const word *B, unsigned int N)
02642                 {return s_pSub(C, A, B, N);}
02643         inline static void Square4(word *R, const word *A)
02644                 {Multiply4(R, A, A);}
02645 #ifdef SSE2_INTRINSICS_AVAILABLE
02646         inline static void Multiply4(word *C, const word *A, const word *B)
02647                 {s_pMul4(C, A, B);}
02648         inline static void Multiply8(word *C, const word *A, const word *B)
02649                 {s_pMul8(C, A, B);}
02650         inline static void Multiply8Bottom(word *C, const word *A, const word *B)
02651                 {s_pMul8B(C, A, B);}
02652 #endif
02653 };
02654 
02655 // use some tricks to share assembly code between MSVC and GCC
02656 #ifdef _MSC_VER
02657         #define CRYPTOPP_NAKED __declspec(naked)
02658         #define AS1(x) __asm x
02659         #define AS2(x, y) __asm x, y
02660         #define AddPrologue \
02661                 __asm   push ebp \
02662                 __asm   push ebx \
02663                 __asm   push esi \
02664                 __asm   push edi \
02665                 __asm   mov             ecx, [esp+20] \
02666                 __asm   mov             edx, [esp+24] \
02667                 __asm   mov             ebx, [esp+28] \
02668                 __asm   mov             esi, [esp+32]
02669         #define AddEpilogue \
02670                 __asm   pop edi \
02671                 __asm   pop esi \
02672                 __asm   pop ebx \
02673                 __asm   pop ebp \
02674                 __asm   ret
02675         #define MulPrologue \
02676                 __asm   push ebp \
02677                 __asm   push ebx \
02678                 __asm   push esi \
02679                 __asm   push edi \
02680                 __asm   mov ecx, [esp+28] \
02681                 __asm   mov esi, [esp+24] \
02682                 __asm   push [esp+20]
02683         #define MulEpilogue \
02684                 __asm   add esp, 4 \
02685                 __asm   pop edi \
02686                 __asm   pop esi \
02687                 __asm   pop ebx \
02688                 __asm   pop ebp \
02689                 __asm   ret
02690 #else
02691         #define CRYPTOPP_NAKED
02692         #define AS1(x) #x ";"
02693         #define AS2(x, y) #x ", " #y ";"
02694         #define AddPrologue \
02695                 __asm__ __volatile__ \
02696                 ( \
02697                         "push %%ebx;"   /* save this manually, in case of -fPIC */ \
02698                         "mov %2, %%ebx;" \
02699                         ".intel_syntax noprefix;" \
02700                         "push ebp;"
02701         #define AddEpilogue \
02702                         "pop ebp;" \
02703                         ".att_syntax prefix;" \
02704                         "pop %%ebx;" \
02705                                         : \
02706                                         : "c" (C), "d" (A), "m" (B), "S" (N) \
02707                                         : "%edi", "memory", "cc" \
02708                 );
02709         #define MulPrologue \
02710                 __asm__ __volatile__ \
02711                 ( \
02712                         "push %%ebx;"   /* save this manually, in case of -fPIC */ \
02713                         "push %%ebp;" \
02714                         "push %0;" \
02715                         ".intel_syntax noprefix;"
02716         #define MulEpilogue \
02717                         "add esp, 4;" \
02718                         "pop ebp;" \
02719                         "pop ebx;" \
02720                         ".att_syntax prefix;" \
02721                         : \
02722                         : "rm" (Z), "S" (X), "c" (Y) \
02723                         : "%eax", "%edx", "%edi", "memory", "cc" \
02724                 );
02725 #endif
02726 
02727 CRYPTOPP_NAKED word PentiumOptimized::Add(word *C, const word *A, const word *B, unsigned int N)
02728 {
02729         AddPrologue
02730 
02731         // now: ebx = B, ecx = C, edx = A, esi = N
02732         AS2(    sub ecx, edx)   // hold the distance between C & A so we can add this to A to get C
02733         AS2(    xor eax, eax)   // clear eax
02734 
02735         AS2(    sub eax, esi)   // eax is a negative index from end of B
02736         AS2(    lea ebx, [ebx+4*esi])   // ebx is end of B
02737 
02738         AS2(    sar eax, 1)             // unit of eax is now dwords; this also clears the carry flag
02739         AS1(    jz      loopendAdd)             // if no dwords then nothing to do
02740 
02741         AS1(loopstartAdd:)
02742         AS2(    mov    esi,[edx])                       // load lower word of A
02743         AS2(    mov    ebp,[edx+4])                     // load higher word of A
02744 
02745         AS2(    mov    edi,[ebx+8*eax])         // load lower word of B
02746         AS2(    lea    edx,[edx+8])                     // advance A and C
02747 
02748         AS2(    adc    esi,edi)                         // add lower words
02749         AS2(    mov    edi,[ebx+8*eax+4])       // load higher word of B
02750 
02751         AS2(    adc    ebp,edi)                         // add higher words
02752         AS1(    inc    eax)                                     // advance B
02753 
02754         AS2(    mov    [edx+ecx-8],esi)         // store lower word result
02755         AS2(    mov    [edx+ecx-4],ebp)         // store higher word result
02756 
02757         AS1(    jnz    loopstartAdd)                    // loop until eax overflows and becomes zero
02758 
02759         AS1(loopendAdd:)
02760         AS2(    adc eax, 0)             // store carry into eax (return result register)
02761 
02762         AddEpilogue
02763 
02764         // Just to get rid of warnings
02765         // return 0;
02766 }
02767 
02768 CRYPTOPP_NAKED word PentiumOptimized::Subtract(word *C, const word *A, const word *B, unsigned int N)
02769 {
02770         AddPrologue
02771 
02772         // now: ebx = B, ecx = C, edx = A, esi = N
02773         AS2(    sub ecx, edx)   // hold the distance between C & A so we can add this to A to get C
02774         AS2(    xor eax, eax)   // clear eax
02775 
02776         AS2(    sub eax, esi)   // eax is a negative index from end of B
02777         AS2(    lea ebx, [ebx+4*esi])   // ebx is end of B
02778 
02779         AS2(    sar eax, 1)             // unit of eax is now dwords; this also clears the carry flag
02780         AS1(    jz      loopendSub)             // if no dwords then nothing to do
02781 
02782         AS1(loopstartSub:)
02783         AS2(    mov    esi,[edx])                       // load lower word of A
02784         AS2(    mov    ebp,[edx+4])                     // load higher word of A
02785 
02786         AS2(    mov    edi,[ebx+8*eax])         // load lower word of B
02787         AS2(    lea    edx,[edx+8])                     // advance A and C
02788 
02789         AS2(    sbb    esi,edi)                         // subtract lower words
02790         AS2(    mov    edi,[ebx+8*eax+4])       // load higher word of B
02791 
02792         AS2(    sbb    ebp,edi)                         // subtract higher words
02793         AS1(    inc    eax)                                     // advance B
02794 
02795         AS2(    mov    [edx+ecx-8],esi)         // store lower word result
02796         AS2(    mov    [edx+ecx-4],ebp)         // store higher word result
02797 
02798         AS1(    jnz    loopstartSub)                    // loop until eax overflows and becomes zero
02799 
02800         AS1(loopendSub:)
02801         AS2(    adc eax, 0)             // store carry into eax (return result register)
02802 
02803         AddEpilogue
02804 
02805         // Just to get rid of warnings
02806         // return 0;
02807 }
02808 
02809 // On Pentium 4, the adc and sbb instructions are very expensive, so avoid them.
02810 
02811 CRYPTOPP_NAKED word P4Optimized::Add(word *C, const word *A, const word *B, unsigned int N)
02812 {
02813         AddPrologue
02814 
02815         // now: ebx = B, ecx = C, edx = A, esi = N
02816         AS2(    xor             eax, eax)
02817         AS1(    neg             esi)
02818         AS1(    jz              loopendAddP4)           // if no dwords then nothing to do
02819 
02820         AS2(    mov             edi, [edx])
02821         AS2(    mov             ebp, [ebx])
02822         AS1(    jmp             carry1AddP4)
02823 
02824         AS1(loopstartAddP4:)
02825         AS2(    mov             edi, [edx+8])
02826         AS2(    add             ecx, 8)
02827         AS2(    add             edx, 8)
02828         AS2(    mov             ebp, [ebx])
02829         AS2(    add             edi, eax)
02830         AS1(    jc              carry1AddP4)
02831         AS2(    xor             eax, eax)
02832 
02833         AS1(carry1AddP4:)
02834         AS2(    add             edi, ebp)
02835         AS2(    mov             ebp, 1)
02836         AS2(    mov             [ecx], edi)
02837         AS2(    mov             edi, [edx+4])
02838         AS2(    cmovc   eax, ebp)
02839         AS2(    mov             ebp, [ebx+4])
02840         AS2(    add             ebx, 8)
02841         AS2(    add             edi, eax)
02842         AS1(    jc              carry2AddP4)
02843         AS2(    xor             eax, eax)
02844 
02845         AS1(carry2AddP4:)
02846         AS2(    add             edi, ebp)
02847         AS2(    mov             ebp, 1)
02848         AS2(    cmovc   eax, ebp)
02849         AS2(    mov             [ecx+4], edi)
02850         AS2(    add             esi, 2)
02851         AS1(    jnz             loopstartAddP4)
02852 
02853         AS1(loopendAddP4:)
02854 
02855         AddEpilogue
02856 
02857         // Just to get rid of warnings
02858         // return 0;
02859 }
02860 
02861 CRYPTOPP_NAKED word P4Optimized::Subtract(word *C, const word *A, const word *B, unsigned int N)
02862 {
02863         AddPrologue
02864 
02865         // now: ebx = B, ecx = C, edx = A, esi = N
02866         AS2(    xor             eax, eax)
02867         AS1(    neg             esi)
02868         AS1(    jz              loopendSubP4)           // if no dwords then nothing to do
02869 
02870         AS2(    mov             edi, [edx])
02871         AS2(    mov             ebp, [ebx])
02872         AS1(    jmp             carry1SubP4)
02873 
02874         AS1(loopstartSubP4:)
02875         AS2(    mov             edi, [edx+8])
02876         AS2(    add             edx, 8)
02877         AS2(    add             ecx, 8)
02878         AS2(    mov             ebp, [ebx])
02879         AS2(    sub             edi, eax)
02880         AS1(    jc              carry1SubP4)
02881         AS2(    xor             eax, eax)
02882 
02883         AS1(carry1SubP4:)
02884         AS2(    sub             edi, ebp)
02885         AS2(    mov             ebp, 1)
02886         AS2(    mov             [ecx], edi)
02887         AS2(    mov             edi, [edx+4])
02888         AS2(    cmovc   eax, ebp)
02889         AS2(    mov             ebp, [ebx+4])
02890         AS2(    add             ebx, 8)
02891         AS2(    sub             edi, eax)
02892         AS1(    jc              carry2SubP4)
02893         AS2(    xor             eax, eax)
02894 
02895         AS1(carry2SubP4:)
02896         AS2(    sub             edi, ebp)
02897         AS2(    mov             ebp, 1)
02898         AS2(    cmovc   eax, ebp)
02899         AS2(    mov             [ecx+4], edi)
02900         AS2(    add             esi, 2)
02901         AS1(    jnz             loopstartSubP4)
02902 
02903         AS1(loopendSubP4:)
02904 
02905         AddEpilogue
02906 
02907         // Just to get rid of warnings
02908         // return 0;
02909 }
02910 
02911 // multiply assembly code originally contributed by Leonard Janke
02912 
02913 #define MulStartup \
02914         AS2(xor ebp, ebp) \
02915         AS2(xor edi, edi) \
02916         AS2(xor ebx, ebx)
02917 
02918 #define MulShiftCarry \
02919         AS2(mov ebp, edx) \
02920         AS2(mov edi, ebx) \
02921         AS2(xor ebx, ebx)
02922 
02923 #define MulAccumulateBottom(i,j) \
02924         AS2(mov eax, [ecx+4*j]) \
02925         AS2(imul eax, dword ptr [esi+4*i]) \
02926         AS2(add ebp, eax)
02927 
02928 #define MulAccumulate(i,j) \
02929         AS2(mov eax, [ecx+4*j]) \
02930         AS1(mul dword ptr [esi+4*i]) \
02931         AS2(add ebp, eax) \
02932         AS2(adc edi, edx) \
02933         AS2(adc bl, bh)
02934 
02935 #define MulStoreDigit(i)  \
02936         AS2(mov edx, edi) \
02937         AS2(mov edi, [esp]) \
02938         AS2(mov [edi+4*i], ebp)
02939 
02940 #define MulLastDiagonal(digits) \
02941         AS2(mov eax, [ecx+4*(digits-1)]) \
02942         AS1(mul dword ptr [esi+4*(digits-1)]) \
02943         AS2(add ebp, eax) \
02944         AS2(adc edx, edi) \
02945         AS2(mov edi, [esp]) \
02946         AS2(mov [edi+4*(2*digits-2)], ebp) \
02947         AS2(mov [edi+4*(2*digits-1)], edx)
02948 
02949 CRYPTOPP_NAKED void PentiumOptimized::Multiply4(word* Z, const word* X, const word* Y)
02950 {
02951         MulPrologue
02952         // now: [esp] = Z, esi = X, ecx = Y
02953         MulStartup
02954         MulAccumulate(0,0)
02955         MulStoreDigit(0)
02956         MulShiftCarry
02957 
02958         MulAccumulate(1,0)
02959         MulAccumulate(0,1)
02960         MulStoreDigit(1)
02961         MulShiftCarry
02962 
02963         MulAccumulate(2,0)
02964         MulAccumulate(1,1)
02965         MulAccumulate(0,2)
02966         MulStoreDigit(2)
02967         MulShiftCarry
02968 
02969         MulAccumulate(3,0)
02970         MulAccumulate(2,1)
02971         MulAccumulate(1,2)
02972         MulAccumulate(0,3)
02973         MulStoreDigit(3)
02974         MulShiftCarry
02975 
02976         MulAccumulate(3,1)
02977         MulAccumulate(2,2)
02978         MulAccumulate(1,3)
02979         MulStoreDigit(4)
02980         MulShiftCarry
02981 
02982         MulAccumulate(3,2)
02983         MulAccumulate(2,3)
02984         MulStoreDigit(5)
02985         MulShiftCarry
02986 
02987         MulLastDiagonal(4)
02988         MulEpilogue
02989 }
02990 
02991 CRYPTOPP_NAKED void PentiumOptimized::Multiply8(word* Z, const word* X, const word* Y)
02992 {
02993         MulPrologue
02994         // now: [esp] = Z, esi = X, ecx = Y
02995         MulStartup
02996         MulAccumulate(0,0)
02997         MulStoreDigit(0)
02998         MulShiftCarry
02999 
03000         MulAccumulate(1,0)
03001         MulAccumulate(0,1)
03002         MulStoreDigit(1)
03003         MulShiftCarry
03004 
03005         MulAccumulate(2,0)
03006         MulAccumulate(1,1)
03007         MulAccumulate(0,2)
03008         MulStoreDigit(2)
03009         MulShiftCarry
03010 
03011         MulAccumulate(3,0)
03012         MulAccumulate(2,1)
03013         MulAccumulate(1,2)
03014         MulAccumulate(0,3)
03015         MulStoreDigit(3)
03016         MulShiftCarry
03017 
03018         MulAccumulate(4,0)
03019         MulAccumulate(3,1)
03020         MulAccumulate(2,2)
03021         MulAccumulate(1,3)
03022         MulAccumulate(0,4)
03023         MulStoreDigit(4)
03024         MulShiftCarry
03025 
03026         MulAccumulate(5,0)
03027         MulAccumulate(4,1)
03028         MulAccumulate(3,2)
03029         MulAccumulate(2,3)
03030         MulAccumulate(1,4)
03031         MulAccumulate(0,5)
03032         MulStoreDigit(5)
03033         MulShiftCarry
03034 
03035         MulAccumulate(6,0)
03036         MulAccumulate(5,1)
03037         MulAccumulate(4,2)
03038         MulAccumulate(3,3)
03039         MulAccumulate(2,4)
03040         MulAccumulate(1,5)
03041         MulAccumulate(0,6)
03042         MulStoreDigit(6)
03043         MulShiftCarry
03044 
03045         MulAccumulate(7,0)
03046         MulAccumulate(6,1)
03047         MulAccumulate(5,2)
03048         MulAccumulate(4,3)
03049         MulAccumulate(3,4)
03050         MulAccumulate(2,5)
03051         MulAccumulate(1,6)
03052         MulAccumulate(0,7)
03053         MulStoreDigit(7)
03054         MulShiftCarry
03055 
03056         MulAccumulate(7,1)
03057         MulAccumulate(6,2)
03058         MulAccumulate(5,3)
03059         MulAccumulate(4,4)
03060         MulAccumulate(3,5)
03061         MulAccumulate(2,6)
03062         MulAccumulate(1,7)
03063         MulStoreDigit(8)
03064         MulShiftCarry
03065 
03066         MulAccumulate(7,2)
03067         MulAccumulate(6,3)
03068         MulAccumulate(5,4)
03069         MulAccumulate(4,5)
03070         MulAccumulate(3,6)
03071         MulAccumulate(2,7)
03072         MulStoreDigit(9)
03073         MulShiftCarry
03074 
03075         MulAccumulate(7,3)
03076         MulAccumulate(6,4)
03077         MulAccumulate(5,5)
03078         MulAccumulate(4,6)
03079         MulAccumulate(3,7)
03080         MulStoreDigit(10)
03081         MulShiftCarry
03082 
03083         MulAccumulate(7,4)
03084         MulAccumulate(6,5)
03085         MulAccumulate(5,6)
03086         MulAccumulate(4,7)
03087         MulStoreDigit(11)
03088         MulShiftCarry
03089 
03090         MulAccumulate(7,5)
03091         MulAccumulate(6,6)
03092         MulAccumulate(5,7)
03093         MulStoreDigit(12)
03094         MulShiftCarry
03095 
03096         MulAccumulate(7,6)
03097         MulAccumulate(6,7)
03098         MulStoreDigit(13)
03099         MulShiftCarry
03100 
03101         MulLastDiagonal(8)
03102         MulEpilogue
03103 }
03104 
03105 CRYPTOPP_NAKED void PentiumOptimized::Multiply8Bottom(word* Z, const word* X, const word* Y)
03106 {
03107         MulPrologue
03108         // now: [esp] = Z, esi = X, ecx = Y
03109         MulStartup
03110         MulAccumulate(0,0)
03111         MulStoreDigit(0)
03112         MulShiftCarry
03113 
03114         MulAccumulate(1,0)
03115         MulAccumulate(0,1)
03116         MulStoreDigit(1)
03117         MulShiftCarry
03118 
03119         MulAccumulate(2,0)
03120         MulAccumulate(1,1)
03121         MulAccumulate(0,2)
03122         MulStoreDigit(2)
03123         MulShiftCarry
03124 
03125         MulAccumulate(3,0)
03126         MulAccumulate(2,1)
03127         MulAccumulate(1,2)
03128         MulAccumulate(0,3)
03129         MulStoreDigit(3)
03130         MulShiftCarry
03131 
03132         MulAccumulate(4,0)
03133         MulAccumulate(3,1)
03134         MulAccumulate(2,2)
03135         MulAccumulate(1,3)
03136         MulAccumulate(0,4)
03137         MulStoreDigit(4)
03138         MulShiftCarry
03139 
03140         MulAccumulate(5,0)
03141         MulAccumulate(4,1)
03142         MulAccumulate(3,2)
03143         MulAccumulate(2,3)
03144         MulAccumulate(1,4)
03145         MulAccumulate(0,5)
03146         MulStoreDigit(5)
03147         MulShiftCarry
03148 
03149         MulAccumulate(6,0)
03150         MulAccumulate(5,1)
03151         MulAccumulate(4,2)
03152         MulAccumulate(3,3)
03153         MulAccumulate(2,4)
03154         MulAccumulate(1,5)
03155         MulAccumulate(0,6)
03156         MulStoreDigit(6)
03157         MulShiftCarry
03158 
03159         MulAccumulateBottom(7,0)
03160         MulAccumulateBottom(6,1)
03161         MulAccumulateBottom(5,2)
03162         MulAccumulateBottom(4,3)
03163         MulAccumulateBottom(3,4)
03164         MulAccumulateBottom(2,5)
03165         MulAccumulateBottom(1,6)
03166         MulAccumulateBottom(0,7)
03167         MulStoreDigit(7)
03168         MulEpilogue
03169 }
03170 
03171 #undef AS1
03172 #undef AS2
03173 
03174 #else   // not x86 - no processor specific code at this layer
03175 
03176 typedef Portable LowLevel;
03177 
03178 #endif
03179 
03180 #ifdef SSE2_INTRINSICS_AVAILABLE
03181 
03182 #ifdef __GNUC__
03183 #define CRYPTOPP_FASTCALL
03184 #else
03185 #define CRYPTOPP_FASTCALL __fastcall
03186 #endif
03187 
03188 static void CRYPTOPP_FASTCALL P4_Mul(__m128i *C, const __m128i *A, const __m128i *B)
03189 {
03190         __m128i a3210 = _mm_load_si128(A);
03191         __m128i b3210 = _mm_load_si128(B);
03192 
03193         __m128i sum;
03194 
03195         __m128i z = _mm_setzero_si128();
03196         __m128i a2b2_a0b0 = _mm_mul_epu32(a3210, b3210);
03197         C[0] = a2b2_a0b0;
03198 
03199         __m128i a3120 = _mm_shuffle_epi32(a3210, _MM_SHUFFLE(3, 1, 2, 0));
03200         __m128i b3021 = _mm_shuffle_epi32(b3210, _MM_SHUFFLE(3, 0, 2, 1));
03201         __m128i a1b0_a0b1 = _mm_mul_epu32(a3120, b3021);
03202         __m128i a1b0 = _mm_unpackhi_epi32(a1b0_a0b1, z);
03203         __m128i a0b1 = _mm_unpacklo_epi32(a1b0_a0b1, z);
03204         C[1] = _mm_add_epi64(a1b0, a0b1);
03205 
03206         __m128i a31 = _mm_srli_epi64(a3210, 32);
03207         __m128i b31 = _mm_srli_epi64(b3210, 32);
03208         __m128i a3b3_a1b1 = _mm_mul_epu32(a31, b31);
03209         C[6] = a3b3_a1b1;
03210 
03211         __m128i a1b1 = _mm_unpacklo_epi32(a3b3_a1b1, z);
03212         __m128i b3012 = _mm_shuffle_epi32(b3210, _MM_SHUFFLE(3, 0, 1, 2));
03213         __m128i a2b0_a0b2 = _mm_mul_epu32(a3210, b3012);
03214         __m128i a0b2 = _mm_unpacklo_epi32(a2b0_a0b2, z);
03215         __m128i a2b0 = _mm_unpackhi_epi32(a2b0_a0b2, z);
03216         sum = _mm_add_epi64(a1b1, a0b2);
03217         C[2] = _mm_add_epi64(sum, a2b0);
03218 
03219         __m128i a2301 = _mm_shuffle_epi32(a3210, _MM_SHUFFLE(2, 3, 0, 1));
03220         __m128i b2103 = _mm_shuffle_epi32(b3210, _MM_SHUFFLE(2, 1, 0, 3));
03221         __m128i a3b0_a1b2 = _mm_mul_epu32(a2301, b3012);
03222         __m128i a2b1_a0b3 = _mm_mul_epu32(a3210, b2103);
03223         __m128i a3b0 = _mm_unpackhi_epi32(a3b0_a1b2, z);
03224         __m128i a1b2 = _mm_unpacklo_epi32(a3b0_a1b2, z);
03225         __m128i a2b1 = _mm_unpackhi_epi32(a2b1_a0b3, z);
03226         __m128i a0b3 = _mm_unpacklo_epi32(a2b1_a0b3, z);
03227         __m128i sum1 = _mm_add_epi64(a3b0, a1b2);
03228         sum = _mm_add_epi64(a2b1, a0b3);
03229         C[3] = _mm_add_epi64(sum, sum1);
03230 
03231         __m128i a3b1_a1b3 = _mm_mul_epu32(a2301, b2103);
03232         __m128i a2b2 = _mm_unpackhi_epi32(a2b2_a0b0, z);
03233         __m128i a3b1 = _mm_unpackhi_epi32(a3b1_a1b3, z);
03234         __m128i a1b3 = _mm_unpacklo_epi32(a3b1_a1b3, z);
03235         sum = _mm_add_epi64(a2b2, a3b1);
03236         C[4] = _mm_add_epi64(sum, a1b3);
03237 
03238         __m128i a1302 = _mm_shuffle_epi32(a3210, _MM_SHUFFLE(1, 3, 0, 2));
03239         __m128i b1203 = _mm_shuffle_epi32(b3210, _MM_SHUFFLE(1, 2, 0, 3));
03240         __m128i a3b2_a2b3 = _mm_mul_epu32(a1302, b1203);
03241         __m128i a3b2 = _mm_unpackhi_epi32(a3b2_a2b3, z);
03242         __m128i a2b3 = _mm_unpacklo_epi32(a3b2_a2b3, z);
03243         C[5] = _mm_add_epi64(a3b2, a2b3);
03244 }
03245 
03246 #endif  // #ifdef SSE2_INTRINSICS_AVAILABLE
03247 
03248 // ********************************************************
03249 
03250 #define A0              A
03251 #define A1              (A+N2)
03252 #define B0              B
03253 #define B1              (B+N2)
03254 
03255 #define T0              T
03256 #define T1              (T+N2)
03257 #define T2              (T+N)
03258 #define T3              (T+N+N2)
03259 
03260 #define R0              R
03261 #define R1              (R+N2)
03262 #define R2              (R+N)
03263 #define R3              (R+N+N2)
03264 
03265 // R[2*N] - result = A*B
03266 // T[2*N] - temporary work space
03267 // A[N] --- multiplier
03268 // B[N] --- multiplicant
03269 
03270 void RecursiveMultiply(word *R, word *T, const word *A, const word *B, unsigned int N)
03271 {
03272         assert(N>=2 && N%2==0);
03273 
03274         if (LowLevel::MultiplyRecursionLimit() >= 8 && N==8)
03275                 LowLevel::Multiply8(R, A, B);
03276         else if (LowLevel::MultiplyRecursionLimit() >= 4 && N==4)
03277                 LowLevel::Multiply4(R, A, B);
03278         else if (N==2)
03279                 LowLevel::Multiply2(R, A, B);
03280         else
03281         {
03282                 const unsigned int N2 = N/2;
03283                 int carry;
03284 
03285                 int aComp = Compare(A0, A1, N2);
03286                 int bComp = Compare(B0, B1, N2);
03287 
03288                 switch (2*aComp + aComp + bComp)
03289                 {
03290                 case -4:
03291                         LowLevel::Subtract(R0, A1, A0, N2);
03292                         LowLevel::Subtract(R1, B0, B1, N2);
03293                         RecursiveMultiply(T0, T2, R0, R1, N2);
03294                         LowLevel::Subtract(T1, T1, R0, N2);
03295                         carry = -1;
03296                         break;
03297                 case -2:
03298                         LowLevel::Subtract(R0, A1, A0, N2);
03299                         LowLevel::Subtract(R1, B0, B1, N2);
03300                         RecursiveMultiply(T0, T2, R0, R1, N2);
03301                         carry = 0;
03302                         break;
03303                 case 2:
03304                         LowLevel::Subtract(R0, A0, A1, N2);
03305                         LowLevel::Subtract(R1, B1, B0, N2);
03306                         RecursiveMultiply(T0, T2, R0, R1, N2);
03307                         carry = 0;
03308                         break;
03309                 case 4:
03310                         LowLevel::Subtract(R0, A1, A0, N2);
03311                         LowLevel::Subtract(R1, B0, B1, N2);
03312                         RecursiveMultiply(T0, T2, R0, R1, N2);
03313                         LowLevel::Subtract(T1, T1, R1, N2);
03314                         carry = -1;
03315                         break;
03316                 default:
03317                         SetWords(T0, 0, N);
03318                         carry = 0;
03319                 }
03320 
03321                 RecursiveMultiply(R0, T2, A0, B0, N2);
03322                 RecursiveMultiply(R2, T2, A1, B1, N2);
03323 
03324                 // now T[01] holds (A1-A0)*(B0-B1), R[01] holds A0*B0, R[23] holds A1*B1
03325 
03326                 carry += LowLevel::Add(T0, T0, R0, N);
03327                 carry += LowLevel::Add(T0, T0, R2, N);
03328                 carry += LowLevel::Add(R1, R1, T0, N);
03329 
03330                 assert (carry >= 0 && carry <= 2);
03331                 Increment(R3, N2, carry);
03332         }
03333 }
03334 
03335 // R[2*N] - result = A*A
03336 // T[2*N] - temporary work space
03337 // A[N] --- number to be squared
03338 
03339 void RecursiveSquare(word *R, word *T, const word *A, unsigned int N)
03340 {
03341         assert(N && N%2==0);
03342         if (LowLevel::SquareRecursionLimit() >= 8 && N==8)
03343                 LowLevel::Square8(R, A);
03344         if (LowLevel::SquareRecursionLimit() >= 4 && N==4)
03345                 LowLevel::Square4(R, A);
03346         else if (N==2)
03347                 LowLevel::Square2(R, A);
03348         else
03349         {
03350                 const unsigned int N2 = N/2;
03351 
03352                 RecursiveSquare(R0, T2, A0, N2);
03353                 RecursiveSquare(R2, T2, A1, N2);
03354                 RecursiveMultiply(T0, T2, A0, A1, N2);
03355 
03356                 word carry = LowLevel::Add(R1, R1, T0, N);
03357                 carry += LowLevel::Add(R1, R1, T0, N);
03358                 Increment(R3, N2, carry);
03359         }
03360 }
03361 
03362 // R[N] - bottom half of A*B
03363 // T[N] - temporary work space
03364 // A[N] - multiplier
03365 // B[N] - multiplicant
03366 
03367 void RecursiveMultiplyBottom(word *R, word *T, const word *A, const word *B, unsigned int N)
03368 {
03369         assert(N>=2 && N%2==0);
03370         if (LowLevel::MultiplyBottomRecursionLimit() >= 8 && N==8)
03371                 LowLevel::Multiply8Bottom(R, A, B);
03372         else if (LowLevel::MultiplyBottomRecursionLimit() >= 4 && N==4)
03373                 LowLevel::Multiply4Bottom(R, A, B);
03374         else if (N==2)
03375                 LowLevel::Multiply2Bottom(R, A, B);
03376         else
03377         {
03378                 const unsigned int N2 = N/2;
03379 
03380                 RecursiveMultiply(R, T, A0, B0, N2);
03381                 RecursiveMultiplyBottom(T0, T1, A1, B0, N2);
03382                 LowLevel::Add(R1, R1, T0, N2);
03383                 RecursiveMultiplyBottom(T0, T1, A0, B1, N2);
03384                 LowLevel::Add(R1, R1, T0, N2);
03385         }
03386 }
03387 
03388 // R[N] --- upper half of A*B
03389 // T[2*N] - temporary work space
03390 // L[N] --- lower half of A*B
03391 // A[N] --- multiplier
03392 // B[N] --- multiplicant
03393 
03394 void RecursiveMultiplyTop(word *R, word *T, const word *L, const word *A, const word *B, unsigned int N)
03395 {
03396         assert(N>=2 && N%2==0);
03397 
03398         if (N==4)
03399         {
03400                 LowLevel::Multiply4(T, A, B);
03401                 memcpy(R, T+4, 4*WORD_SIZE);
03402         }
03403         else if (N==2)
03404         {
03405                 LowLevel::Multiply2(T, A, B);
03406                 memcpy(R, T+2, 2*WORD_SIZE);
03407         }
03408         else
03409         {
03410                 const unsigned int N2 = N/2;
03411                 int carry;
03412 
03413                 int aComp = Compare(A0, A1, N2);
03414                 int bComp = Compare(B0, B1, N2);
03415 
03416                 switch (2*aComp + aComp + bComp)
03417                 {
03418                 case -4:
03419                         LowLevel::Subtract(R0, A1, A0, N2);
03420                         LowLevel::Subtract(R1, B0, B1, N2);
03421                         RecursiveMultiply(T0, T2, R0, R1, N2);
03422                         LowLevel::Subtract(T1, T1, R0, N2);
03423                         carry = -1;
03424                         break;
03425                 case -2:
03426                         LowLevel::Subtract(R0, A1, A0, N2);
03427                         LowLevel::Subtract(R1, B0, B1, N2);
03428                         RecursiveMultiply(T0, T2, R0, R1, N2);
03429                         carry = 0;
03430                         break;
03431                 case 2:
03432                         LowLevel::Subtract(R0, A0, A1, N2);
03433                         LowLevel::Subtract(R1, B1, B0, N2);
03434                         RecursiveMultiply(T0, T2, R0, R1, N2);
03435                         carry = 0;
03436                         break;
03437                 case 4:
03438                         LowLevel::Subtract(R0, A1, A0, N2);
03439                         LowLevel::Subtract(R1, B0, B1, N2);
03440                         RecursiveMultiply(T0, T2, R0, R1, N2);
03441                         LowLevel::Subtract(T1, T1, R1, N2);
03442                         carry = -1;
03443                         break;
03444                 default:
03445                         SetWords(T0, 0, N);
03446                         carry = 0;
03447                 }
03448 
03449                 RecursiveMultiply(T2, R0, A1, B1, N2);
03450 
03451                 // now T[01] holds (A1-A0)*(B0-B1), T[23] holds A1*B1
03452 
03453                 word c2 = LowLevel::Subtract(R0, L+N2, L, N2);
03454                 c2 += LowLevel::Subtract(R0, R0, T0, N2);
03455                 word t = (Compare(R0, T2, N2) == -1);
03456 
03457                 carry += t;
03458                 carry += Increment(R0, N2, c2+t);
03459                 carry += LowLevel::Add(R0, R0, T1, N2);
03460                 carry += LowLevel::Add(R0, R0, T3, N2);
03461                 assert (carry >= 0 && carry <= 2);
03462 
03463                 CopyWords(R1, T3, N2);
03464                 Increment(R1, N2, carry);
03465         }
03466 }
03467 
03468 inline word Add(word *C, const word *A, const word *B, unsigned int N)
03469 {
03470         return LowLevel::Add(C, A, B, N);
03471 }
03472 
03473 inline word Subtract(word *C, const word *A, const word *B, unsigned int N)
03474 {
03475         return LowLevel::Subtract(C, A, B, N);
03476 }
03477 
03478 inline void Multiply(word *R, word *T, const word *A, const word *B, unsigned int N)
03479 {
03480         RecursiveMultiply(R, T, A, B, N);
03481 }
03482 
03483 inline void Square(word *R, word *T, const word *A, unsigned int N)
03484 {
03485         RecursiveSquare(R, T, A, N);
03486 }
03487 
03488 inline void MultiplyBottom(word *R, word *T, const word *A, const word *B, unsigned int N)
03489 {
03490         RecursiveMultiplyBottom(R, T, A, B, N);
03491 }
03492 
03493 inline void MultiplyTop(word *R, word *T, const word *L, const word *A, const word *B, unsigned int N)
03494 {
03495         RecursiveMultiplyTop(R, T, L, A, B, N);
03496 }
03497 
03498 static word LinearMultiply(word *C, const word *A, word B, unsigned int N)
03499 {
03500         word carry=0;
03501         for(unsigned i=0; i<N; i++)
03502         {
03503                 DWord p = DWord::MultiplyAndAdd(A[i], B, carry);
03504                 C[i] = p.GetLowHalf();
03505                 carry = p.GetHighHalf();
03506         }
03507         return carry;
03508 }
03509 
03510 // R[NA+NB] - result = A*B
03511 // T[NA+NB] - temporary work space
03512 // A[NA] ---- multiplier
03513 // B[NB] ---- multiplicant
03514 
03515 void AsymmetricMultiply(word *R, word *T, const word *A, unsigned int NA, const word *B, unsigned int NB)
03516 {
03517         if (NA == NB)
03518         {
03519                 if (A == B)
03520                         Square(R, T, A, NA);
03521                 else
03522                         Multiply(R, T, A, B, NA);
03523 
03524                 return;
03525         }
03526 
03527         if (NA > NB)
03528         {
03529                 std::swap(A, B);
03530                 std::swap(NA, NB);
03531         }
03532 
03533         assert(NB % NA == 0);
03534         assert((NB/NA)%2 == 0);         // NB is an even multiple of NA
03535 
03536         if (NA==2 && !A[1])
03537         {
03538                 switch (A[0])
03539                 {
03540                 case 0:
03541                         SetWords(R, 0, NB+2);
03542                         return;
03543                 case 1:
03544                         CopyWords(R, B, NB);
03545                         R[NB] = R[NB+1] = 0;
03546                         return;
03547                 default:
03548                         R[NB] = LinearMultiply(R, B, A[0], NB);
03549                         R[NB+1] = 0;
03550                         return;
03551                 }
03552         }
03553 
03554         Multiply(R, T, A, B, NA);
03555         CopyWords(T+2*NA, R+NA, NA);
03556 
03557         unsigned i;
03558 
03559         for (i=2*NA; i<NB; i+=2*NA)
03560                 Multiply(T+NA+i, T, A, B+i, NA);
03561         for (i=NA; i<NB; i+=2*NA)
03562                 Multiply(R+i, T, A, B+i, NA);
03563 
03564         if (Add(R+NA, R+NA, T+2*NA, NB-NA))
03565                 Increment(R+NB, NA);
03566 }
03567 
03568 // R[N] ----- result = A inverse mod 2**(WORD_BITS*N)
03569 // T[3*N/2] - temporary work space
03570 // A[N] ----- an odd number as input
03571 
03572 void RecursiveInverseModPower2(word *R, word *T, const word *A, unsigned int N)
03573 {
03574         if (N==2)
03575         {
03576                 T[0] = AtomicInverseModPower2(A[0]);
03577                 T[1] = 0;
03578                 LowLevel::Multiply2Bottom(T+2, T, A);
03579                 TwosComplement(T+2, 2);
03580                 Increment(T+2, 2, 2);
03581                 LowLevel::Multiply2Bottom(R, T, T+2);
03582         }
03583         else
03584         {
03585                 const unsigned int N2 = N/2;
03586                 RecursiveInverseModPower2(R0, T0, A0, N2);
03587                 T0[0] = 1;
03588                 SetWords(T0+1, 0, N2-1);
03589                 MultiplyTop(R1, T1, T0, R0, A0, N2);
03590                 MultiplyBottom(T0, T1, R0, A1, N2);
03591                 Add(T0, R1, T0, N2);
03592                 TwosComplement(T0, N2);
03593                 MultiplyBottom(R1, T1, R0, T0, N2);
03594         }
03595 }
03596 
03597 // R[N] --- result = X/(2**(WORD_BITS*N)) mod M
03598 // T[3*N] - temporary work space
03599 // X[2*N] - number to be reduced
03600 // M[N] --- modulus
03601 // U[N] --- multiplicative inverse of M mod 2**(WORD_BITS*N)
03602 
03603 void MontgomeryReduce(word *R, word *T, const word *X, const word *M, const word *U, unsigned int N)
03604 {
03605         MultiplyBottom(R, T, X, U, N);
03606         MultiplyTop(T, T+N, X, R, M, N);
03607         word borrow = Subtract(T, X+N, T, N);
03608         // defend against timing attack by doing this Add even when not needed
03609         word carry = Add(T+N, T, M, N);
03610         assert(carry || !borrow);
03611         CopyWords(R, T + (borrow ? N : 0), N);
03612 }
03613 
03614 // R[N] --- result = X/(2**(WORD_BITS*N/2)) mod M
03615 // T[2*N] - temporary work space
03616 // X[2*N] - number to be reduced
03617 // M[N] --- modulus
03618 // U[N/2] - multiplicative inverse of M mod 2**(WORD_BITS*N/2)
03619 // V[N] --- 2**(WORD_BITS*3*N/2) mod M
03620 
03621 void HalfMontgomeryReduce(word *R, word *T, const word *X, const word *M, const word *U, const word *V, unsigned int N)
03622 {
03623         assert(N%2==0 && N>=4);
03624 
03625 #define M0              M
03626 #define M1              (M+N2)
03627 #define V0              V
03628 #define V1              (V+N2)
03629 
03630 #define X0              X
03631 #define X1              (X+N2)
03632 #define X2              (X+N)
03633 #define X3              (X+N+N2)
03634 
03635         const unsigned int N2 = N/2;
03636         Multiply(T0, T2, V0, X3, N2);
03637         int c2 = Add(T0, T0, X0, N);
03638         MultiplyBottom(T3, T2, T0, U, N2);
03639         MultiplyTop(T2, R, T0, T3, M0, N2);
03640         c2 -= Subtract(T2, T1, T2, N2);
03641         Multiply(T0, R, T3, M1, N2);
03642         c2 -= Subtract(T0, T2, T0, N2);
03643         int c3 = -(int)Subtract(T1, X2, T1, N2);
03644         Multiply(R0, T2, V1, X3, N2);
03645         c3 += Add(R, R, T, N);
03646 
03647         if (c2>0)
03648                 c3 += Increment(R1, N2);
03649         else if (c2<0)
03650                 c3 -= Decrement(R1, N2, -c2);
03651 
03652         assert(c3>=-1 && c3<=1);
03653         if (c3>0)
03654                 Subtract(R, R, M, N);
03655         else if (c3<0)
03656                 Add(R, R, M, N);
03657 
03658 #undef M0
03659 #undef M1
03660 #undef V0
03661 #undef V1
03662 
03663 #undef X0
03664 #undef X1
03665 #undef X2
03666 #undef X3
03667 }
03668 
03669 #undef A0
03670 #undef A1
03671 #undef B0
03672 #undef B1
03673 
03674 #undef T0
03675 #undef T1
03676 #undef T2
03677 #undef T3
03678 
03679 #undef R0
03680 #undef R1
03681 #undef R2
03682 #undef R3
03683 
03684 static inline void AtomicDivide(word *Q, const word *A, const word *B)
03685 {
03686         word T[4];
03687         DWord q = DivideFourWordsByTwo<word, DWord>(T, DWord(A[0], A[1]), DWord(A[2], A[3]), DWord(B[0], B[1]));
03688         Q[0] = q.GetLowHalf();
03689         Q[1] = q.GetHighHalf();
03690 }
03691 
03692 // for use by Divide(), corrects the underestimated quotient {Q1,Q0}
03693 static void CorrectQuotientEstimate(word *R, word *T, word *Q, const word *B, unsigned int N)
03694 {
03695         assert(N && N%2==0);
03696 
03697         if (Q[1])
03698         {
03699                 T[N] = T[N+1] = 0;
03700                 unsigned i;
03701                 for (i=0; i<N; i+=4)
03702                         LowLevel::Multiply2(T+i, Q, B+i);
03703                 for (i=2; i<N; i+=4)
03704                         if (LowLevel::Multiply2Add(T+i, Q, B+i))
03705                                 T[i+5] += (++T[i+4]==0);
03706         }
03707         else
03708         {
03709                 T[N] = LinearMultiply(T, B, Q[0], N);
03710                 T[N+1] = 0;
03711         }
03712 
03713         word borrow = Subtract(R, R, T, N+2);
03714         assert(!borrow && !R[N+1]);
03715 
03716         while (R[N] || Compare(R, B, N) >= 0)
03717         {
03718                 R[N] -= Subtract(R, R, B, N);
03719                 Q[1] += (++Q[0]==0);
03720                 assert(Q[0] || Q[1]); // no overflow
03721         }
03722 }
03723 
03724 // R[NB] -------- remainder = A%B
03725 // Q[NA-NB+2] --- quotient      = A/B
03726 // T[NA+2*NB+4] - temp work space
03727 // A[NA] -------- dividend
03728 // B[NB] -------- divisor
03729 
03730 void Divide(word *R, word *Q, word *T, const word *A, unsigned int NA, const word *B, unsigned int NB)
03731 {
03732         assert(NA && NB && NA%2==0 && NB%2==0);
03733         assert(B[NB-1] || B[NB-2]);
03734         assert(NB <= NA);
03735 
03736         // set up temporary work space
03737         word *const TA=T;
03738         word *const TB=T+NA+2;
03739         word *const TP=T+NA+2+NB;
03740 
03741         // copy B into TB and normalize it so that TB has highest bit set to 1
03742         unsigned shiftWords = (B[NB-1]==0);
03743         TB[0] = TB[NB-1] = 0;
03744         CopyWords(TB+shiftWords, B, NB-shiftWords);
03745         unsigned shiftBits = WORD_BITS - BitPrecision(TB[NB-1]);
03746         assert(shiftBits < WORD_BITS);
03747         ShiftWordsLeftByBits(TB, NB, shiftBits);
03748 
03749         // copy A into TA and normalize it
03750         TA[0] = TA[NA] = TA[NA+1] = 0;
03751         CopyWords(TA+shiftWords, A, NA);
03752         ShiftWordsLeftByBits(TA, NA+2, shiftBits);
03753 
03754         if (TA[NA+1]==0 && TA[NA] <= 1)
03755         {
03756                 Q[NA-NB+1] = Q[NA-NB] = 0;
03757                 while (TA[NA] || Compare(TA+NA-NB, TB, NB) >= 0)
03758                 {
03759                         TA[NA] -= Subtract(TA+NA-NB, TA+NA-NB, TB, NB);
03760                         ++Q[NA-NB];
03761                 }
03762         }
03763         else
03764         {
03765                 NA+=2;
03766                 assert(Compare(TA+NA-NB, TB, NB) < 0);
03767         }
03768 
03769         word BT[2];
03770         BT[0] = TB[NB-2] + 1;
03771         BT[1] = TB[NB-1] + (BT[0]==0);
03772 
03773         // start reducing TA mod TB, 2 words at a time
03774         for (unsigned i=NA-2; i>=NB; i-=2)
03775         {
03776                 AtomicDivide(Q+i-NB, TA+i-2, BT);
03777                 CorrectQuotientEstimate(TA+i-NB, TP, Q+i-NB, TB, NB);
03778         }
03779 
03780         // copy TA into R, and denormalize it
03781         CopyWords(R, TA+shiftWords, NB);
03782         ShiftWordsRightByBits(R, NB, shiftBits);
03783 }
03784 
03785 static inline unsigned int EvenWordCount(const word *X, unsigned int N)
03786 {
03787         while (N && X[N-2]==0 && X[N-1]==0)
03788                 N-=2;
03789         return N;
03790 }
03791 
03792 // return k
03793 // R[N] --- result = A^(-1) * 2^k mod M
03794 // T[4*N] - temporary work space
03795 // A[NA] -- number to take inverse of
03796 // M[N] --- modulus
03797 
03798 unsigned int AlmostInverse(word *R, word *T, const word *A, unsigned int NA, const word *M, unsigned int N)
03799 {
03800         assert(NA<=N && N && N%2==0);
03801 
03802         word *b = T;
03803         word *c = T+N;
03804         word *f = T+2*N;
03805         word *g = T+3*N;
03806         unsigned int bcLen=2, fgLen=EvenWordCount(M, N);
03807         unsigned int k=0, s=0;
03808 
03809         SetWords(T, 0, 3*N);
03810         b[0]=1;
03811         CopyWords(f, A, NA);
03812         CopyWords(g, M, N);
03813 
03814         while (1)
03815         {
03816                 word t=f[0];
03817                 while (!t)
03818                 {
03819                         if (EvenWordCount(f, fgLen)==0)
03820                         {
03821                                 SetWords(R, 0, N);
03822                                 return 0;
03823                         }
03824 
03825                         ShiftWordsRightByWords(f, fgLen, 1);
03826                         if (c[bcLen-1]) bcLen+=2;
03827                         assert(bcLen <= N);
03828                         ShiftWordsLeftByWords(c, bcLen, 1);
03829                         k+=WORD_BITS;
03830                         t=f[0];
03831                 }
03832 
03833                 unsigned int i=0;
03834                 while (t%2 == 0)
03835                 {
03836                         t>>=1;
03837                         i++;
03838                 }
03839                 k+=i;
03840 
03841                 if (t==1 && f[1]==0 && EvenWordCount(f, fgLen)==2)
03842                 {
03843                         if (s%2==0)
03844                                 CopyWords(R, b, N);
03845                         else
03846                                 Subtract(R, M, b, N);
03847                         return k;
03848                 }
03849 
03850                 ShiftWordsRightByBits(f, fgLen, i);
03851                 t=ShiftWordsLeftByBits(c, bcLen, i);
03852                 if (t)
03853                 {
03854                         c[bcLen] = t;
03855                         bcLen+=2;
03856                         assert(bcLen <= N);
03857                 }
03858 
03859                 if (f[fgLen-2]==0 && g[fgLen-2]==0 && f[fgLen-1]==0 && g[fgLen-1]==0)
03860                         fgLen-=2;
03861 
03862                 if (Compare(f, g, fgLen)==-1)
03863                 {
03864                         std::swap(f, g);
03865                         std::swap(b, c);
03866                         s++;
03867                 }
03868 
03869                 Subtract(f, f, g, fgLen);
03870 
03871                 if (Add(b, b, c, bcLen))
03872                 {
03873                         b[bcLen] = 1;
03874                         bcLen+=2;
03875                         assert(bcLen <= N);
03876                 }
03877         }
03878 }
03879 
03880 // R[N] - result = A/(2^k) mod M
03881 // A[N] - input
03882 // M[N] - modulus
03883 
03884 void DivideByPower2Mod(word *R, const word *A, unsigned int k, const word *M, unsigned int N)
03885 {
03886         CopyWords(R, A, N);
03887 
03888         while (k--)
03889         {
03890                 if (R[0]%2==0)
03891                         ShiftWordsRightByBits(R, N, 1);
03892                 else
03893                 {
03894                         word carry = Add(R, R, M, N);
03895                         ShiftWordsRightByBits(R, N, 1);
03896                         R[N-1] += carry<<(WORD_BITS-1);
03897                 }
03898         }
03899 }
03900 
03901 // R[N] - result = A*(2^k) mod M
03902 // A[N] - input
03903 // M[N] - modulus
03904 
03905 void MultiplyByPower2Mod(word *R, const word *A, unsigned int k, const word *M, unsigned int N)
03906 {
03907         CopyWords(R, A, N);
03908 
03909         while (k--)
03910                 if (ShiftWordsLeftByBits(R, N, 1) || Compare(R, M, N)>=0)
03911                         Subtract(R, R, M, N);
03912 }
03913 
03914 // ******************************************************************
03915 
03916 static const unsigned int RoundupSizeTable[] = {2, 2, 2, 4, 4, 8, 8, 8, 8};
03917 
03918 static inline unsigned int RoundupSize(unsigned int n)
03919 {
03920         if (n<=8)
03921                 return RoundupSizeTable[n];
03922         else if (n<=16)
03923                 return 16;
03924         else if (n<=32)
03925                 return 32;
03926         else if (n<=64)
03927                 return 64;
03928         else return 1U << BitPrecision(n-1);
03929 }
03930 
03931 Integer::Integer()
03932         : reg(2), sign(POSITIVE)
03933 {
03934         reg[0] = reg[1] = 0;
03935 }
03936 
03937 Integer::Integer(const Integer& t)
03938         : ASN1Object(), reg(RoundupSize(t.WordCount())), sign(t.sign)
03939 {
03940         CopyWords(reg, t.reg, reg.size());
03941 }
03942 
03943 Integer::Integer(Sign s, lword value)
03944         : reg(2), sign(s)
03945 {
03946         reg[0] = word(value);
03947         reg[1] = word(SafeRightShift<WORD_BITS>(value));
03948 }
03949 
03950 Integer::Integer(signed long value)
03951         : reg(2)
03952 {
03953         if (value >= 0)
03954                 sign = POSITIVE;
03955         else
03956         {
03957                 sign = NEGATIVE;
03958                 value = -value;
03959         }
03960         reg[0] = word(value);
03961         reg[1] = word(SafeRightShift<WORD_BITS>((unsigned long)value));
03962 }
03963 
03964 Integer::Integer(Sign s, word high, word low)
03965         : reg(2), sign(s)
03966 {
03967         reg[0] = low;
03968         reg[1] = high;
03969 }
03970 
03971 bool Integer::IsConvertableToLong() const
03972 {
03973         if (ByteCount() > sizeof(long))
03974                 return false;
03975 
03976         unsigned long value = reg[0];
03977         value += SafeLeftShift<WORD_BITS, unsigned long>(reg[1]);
03978 
03979         if (sign==POSITIVE)
03980                 return (signed long)value >= 0;
03981         else
03982                 return -(signed long)value < 0;
03983 }
03984 
03985 signed long Integer::ConvertToLong() const
03986 {
03987         assert(IsConvertableToLong());
03988 
03989         unsigned long value = reg[0];
03990         value += SafeLeftShift<WORD_BITS, unsigned long>(reg[1]);
03991         return sign==POSITIVE ? value : -(signed long)value;
03992 }
03993 
03994 Integer::Integer(BufferedTransformation &encodedInteger, unsigned int byteCount, Signedness s)
03995 {
03996         Decode(encodedInteger, byteCount, s);
03997 }
03998 
03999 Integer::Integer(const byte *encodedInteger, unsigned int byteCount, Signedness s)
04000 {
04001         Decode(encodedInteger, byteCount, s);
04002 }
04003 
04004 Integer::Integer(BufferedTransformation &bt)
04005 {
04006         BERDecode(bt);
04007 }
04008 
04009 Integer::Integer(RandomNumberGenerator &rng, unsigned int bitcount)
04010 {
04011         Randomize(rng, bitcount);
04012 }
04013 
04014 Integer::Integer(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType, const Integer &equiv, const Integer &mod)
04015 {
04016         if (!Randomize(rng, min, max, rnType, equiv, mod))
04017                 throw Integer::RandomNumberNotFound();
04018 }
04019 
04020 Integer Integer::Power2(unsigned int e)
04021 {
04022         Integer r((word)0, BitsToWords(e+1));
04023         r.SetBit(e);
04024         return r;
04025 }
04026 
04027 template <long i>
04028 struct NewInteger
04029 {
04030         Integer * operator()() const
04031         {
04032                 return new Integer(i);
04033         }
04034 };
04035 
04036 const Integer &Integer::Zero()
04037 {
04038         return Singleton<Integer>().Ref();
04039 }
04040 
04041 const Integer &Integer::One()
04042 {
04043         return Singleton<Integer, NewInteger<1> >().Ref();
04044 }
04045 
04046 const Integer &Integer::Two()
04047 {
04048         return Singleton<Integer, NewInteger<2> >().Ref();
04049 }
04050 
04051 bool Integer::operator!() const
04052 {
04053         return IsNegative() ? false : (reg[0]==0 && WordCount()==0);
04054 }
04055 
04056 Integer& Integer::operator=(const Integer& t)
04057 {
04058         if (this != &t)
04059         {
04060                 reg.New(RoundupSize(t.WordCount()));
04061                 CopyWords(reg, t.reg, reg.size());
04062                 sign = t.sign;
04063         }
04064         return *this;
04065 }
04066 
04067 bool Integer::GetBit(unsigned int n) const
04068 {
04069         if (n/WORD_BITS >= reg.size())
04070                 return 0;
04071         else
04072                 return bool((reg[n/WORD_BITS] >> (n % WORD_BITS)) & 1);
04073 }
04074 
04075 void Integer::SetBit(unsigned int n, bool value)
04076 {
04077         if (value)
04078         {
04079                 reg.CleanGrow(RoundupSize(BitsToWords(n+1)));
04080                 reg[n/WORD_BITS] |= (word(1) << (n%WORD_BITS));
04081         }
04082         else
04083         {
04084                 if (n/WORD_BITS < reg.size())
04085                         reg[n/WORD_BITS] &= ~(word(1) << (n%WORD_BITS));
04086         }
04087 }
04088 
04089 byte Integer::GetByte(unsigned int n) const
04090 {
04091         if (n/WORD_SIZE >= reg.size())
04092                 return 0;
04093         else
04094                 return byte(reg[n/WORD_SIZE] >> ((n%WORD_SIZE)*8));
04095 }
04096 
04097 void Integer::SetByte(unsigned int n, byte value)
04098 {
04099         reg.CleanGrow(RoundupSize(BytesToWords(n+1)));
04100         reg[n/WORD_SIZE] &= ~(word(0xff) << 8*(n%WORD_SIZE));
04101         reg[n/WORD_SIZE] |= (word(value) << 8*(n%WORD_SIZE));
04102 }
04103 
04104 unsigned long Integer::GetBits(unsigned int i, unsigned int n) const
04105 {
04106         assert(n <= sizeof(unsigned long)*8);
04107         unsigned long v = 0;
04108         for (unsigned int j=0; j<n; j++)
04109                 v |= GetBit(i+j) << j;
04110         return v;
04111 }
04112 
04113 Integer Integer::operator-() const
04114 {
04115         Integer result(*this);
04116         result.Negate();
04117         return result;
04118 }
04119 
04120 Integer Integer::AbsoluteValue() const
04121 {
04122         Integer result(*this);
04123         result.sign = POSITIVE;
04124         return result;
04125 }
04126 
04127 void Integer::swap(Integer &a)
04128 {
04129         reg.swap(a.reg);
04130         std::swap(sign, a.sign);
04131 }
04132 
04133 Integer::Integer(word value, unsigned int length)
04134         : reg(RoundupSize(length)), sign(POSITIVE)
04135 {
04136         reg[0] = value;
04137         SetWords(reg+1, 0, reg.size()-1);
04138 }
04139 
04140 template <class T>
04141 static Integer StringToInteger(const T *str)
04142 {
04143         word radix;
04144         // GCC workaround
04145         // std::char_traits doesn't exist in GCC 2.x
04146         // std::char_traits<wchar_t>::length() not defined in GCC 3.2 and STLport 4.5.3
04147         unsigned int length;
04148         for (length = 0; str[length] != 0; length++) {}
04149 
04150         Integer v;
04151 
04152         if (length == 0)
04153                 return v;
04154 
04155         switch (str[length-1])
04156         {
04157         case 'h':
04158         case 'H':
04159                 radix=16;
04160                 break;
04161         case 'o':
04162         case 'O':
04163                 radix=8;
04164                 break;
04165         case 'b':
04166         case 'B':
04167                 radix=2;
04168                 break;
04169         default:
04170                 radix=10;
04171         }
04172 
04173         if (length > 2 && str[0] == '0' && str[1] == 'x')
04174                 radix = 16;
04175 
04176         for (unsigned i=0; i<length; i++)
04177         {
04178                 word digit;
04179 
04180                 if (str[i] >= '0' && str[i] <= '9')
04181                         digit = str[i] - '0';
04182                 else if (str[i] >= 'A' && str[i] <= 'F')
04183                         digit = str[i] - 'A' + 10;
04184                 else if (str[i] >= 'a' && str[i] <= 'f')
04185                         digit = str[i] - 'a' + 10;
04186                 else
04187                         digit = radix;
04188 
04189                 if (digit < radix)
04190                 {
04191                         v *= radix;
04192                         v += digit;
04193                 }
04194         }
04195 
04196         if (str[0] == '-')
04197                 v.Negate();
04198 
04199         return v;
04200 }
04201 
04202 Integer::Integer(const char *str)
04203         : reg(2), sign(POSITIVE)
04204 {
04205         *this = StringToInteger(str);
04206 }
04207 
04208 Integer::Integer(const wchar_t *str)
04209         : reg(2), sign(POSITIVE)
04210 {
04211         *this = StringToInteger(str);
04212 }
04213 
04214 unsigned int Integer::WordCount() const
04215 {
04216         return CountWords(reg, reg.size());
04217 }
04218 
04219 unsigned int Integer::ByteCount() const
04220 {
04221         unsigned wordCount = WordCount();
04222         if (wordCount)
04223                 return (wordCount-1)*WORD_SIZE + BytePrecision(reg[wordCount-1]);
04224         else
04225                 return 0;
04226 }
04227 
04228 unsigned int Integer::BitCount() const
04229 {
04230         unsigned wordCount = WordCount();
04231         if (wordCount)
04232                 return (wordCount-1)*WORD_BITS + BitPrecision(reg[wordCount-1]);
04233         else
04234                 return 0;
04235 }
04236 
04237 void Integer::Decode(const byte *input, unsigned int inputLen, Signedness s)
04238 {
04239         StringStore store(input, inputLen);
04240         Decode(store, inputLen, s);
04241 }
04242 
04243 void Integer::Decode(BufferedTransformation &bt, unsigned int inputLen, Signedness s)
04244 {
04245         assert(bt.MaxRetrievable() >= inputLen);
04246 
04247         byte b;
04248         bt.Peek(b);
04249         sign = ((s==SIGNED) && (b & 0x80)) ? NEGATIVE : POSITIVE;
04250 
04251         while (inputLen>0 && (sign==POSITIVE ? b==0 : b==0xff))
04252         {
04253                 bt.Skip(1);
04254                 inputLen--;
04255                 bt.Peek(b);
04256         }
04257 
04258         reg.CleanNew(RoundupSize(BytesToWords(inputLen)));
04259 
04260         for (unsigned int i=inputLen; i > 0; i--)
04261         {
04262                 bt.Get(b);
04263                 reg[(i-1)/WORD_SIZE] |= word(b) << ((i-1)%WORD_SIZE)*8;
04264         }
04265 
04266         if (sign == NEGATIVE)
04267         {
04268                 for (unsigned i=inputLen; i<reg.size()*WORD_SIZE; i++)
04269                         reg[i/WORD_SIZE] |= word(0xff) << (i%WORD_SIZE)*8;
04270                 TwosComplement(reg, reg.size());
04271         }
04272 }
04273 
04274 unsigned int Integer::MinEncodedSize(Signedness signedness) const
04275 {
04276         unsigned int outputLen = STDMAX(1U, ByteCount());
04277         if (signedness == UNSIGNED)
04278                 return outputLen;
04279         if (NotNegative() && (GetByte(outputLen-1) & 0x80))
04280                 outputLen++;
04281         if (IsNegative() && *this < -Power2(outputLen*8-1))
04282                 outputLen++;
04283         return outputLen;
04284 }
04285 
04286 unsigned int Integer::Encode(byte *output, unsigned int outputLen, Signedness signedness) const
04287 {
04288         ArraySink sink(output, outputLen);
04289         return Encode(sink, outputLen, signedness);
04290 }
04291 
04292 unsigned int Integer::Encode(BufferedTransformation &bt, unsigned int outputLen, Signedness signedness) const
04293 {
04294         if (signedness == UNSIGNED || NotNegative())
04295         {
04296                 for (unsigned int i=outputLen; i > 0; i--)
04297                         bt.Put(GetByte(i-1));
04298         }
04299         else
04300         {
04301                 // take two's complement of *this
04302                 Integer temp = Integer::Power2(8*STDMAX(ByteCount(), outputLen)) + *this;
04303                 for (unsigned i=0; i<outputLen; i++)
04304                         bt.Put(temp.GetByte(outputLen-i-1));
04305         }
04306         return outputLen;
04307 }
04308 
04309 void Integer::DEREncode(BufferedTransformation &bt) const
04310 {
04311         DERGeneralEncoder enc(bt, INTEGER);
04312         Encode(enc, MinEncodedSize(SIGNED), SIGNED);
04313         enc.MessageEnd();
04314 }
04315 
04316 void Integer::BERDecode(const byte *input, unsigned int len)
04317 {
04318         StringStore store(input, len);
04319         BERDecode(store);
04320 }
04321 
04322 void Integer::BERDecode(BufferedTransformation &bt)
04323 {
04324         BERGeneralDecoder dec(bt, INTEGER);
04325         if (!dec.IsDefiniteLength() || dec.MaxRetrievable() < dec.RemainingLength())
04326                 BERDecodeError();
04327         Decode(dec, dec.RemainingLength(), SIGNED);
04328         dec.MessageEnd();
04329 }
04330 
04331 void Integer::DEREncodeAsOctetString(BufferedTransformation &bt, unsigned int length) const
04332 {
04333         DERGeneralEncoder enc(bt, OCTET_STRING);
04334         Encode(enc, length);
04335         enc.MessageEnd();
04336 }
04337 
04338 void Integer::BERDecodeAsOctetString(BufferedTransformation &bt, unsigned int length)
04339 {
04340         BERGeneralDecoder dec(bt, OCTET_STRING);
04341         if (!dec.IsDefiniteLength() || dec.RemainingLength() != length)
04342                 BERDecodeError();
04343         Decode(dec, length);
04344         dec.MessageEnd();
04345 }
04346 
04347 unsigned int Integer::OpenPGPEncode(byte *output, unsigned int len) const
04348 {
04349         ArraySink sink(output, len);
04350         return OpenPGPEncode(sink);
04351 }
04352 
04353 unsigned int Integer::OpenPGPEncode(BufferedTransformation &bt) const
04354 {
04355         word16 bitCount = BitCount();
04356         bt.PutWord16(bitCount);
04357         return 2 + Encode(bt, BitsToBytes(bitCount));
04358 }
04359 
04360 void Integer::OpenPGPDecode(const byte *input, unsigned int len)
04361 {
04362         StringStore store(input, len);
04363         OpenPGPDecode(store);
04364 }
04365 
04366 void Integer::OpenPGPDecode(BufferedTransformation &bt)
04367 {
04368         word16 bitCount;
04369         if (bt.GetWord16(bitCount) != 2 || bt.MaxRetrievable() < BitsToBytes(bitCount))
04370                 throw OpenPGPDecodeErr();
04371         Decode(bt, BitsToBytes(bitCount));
04372 }
04373 
04374 void Integer::Randomize(RandomNumberGenerator &rng, unsigned int nbits)
04375 {
04376         const unsigned int nbytes = nbits/8 + 1;
04377         SecByteBlock buf(nbytes);
04378         rng.GenerateBlock(buf, nbytes);
04379         if (nbytes)
04380                 buf[0] = (byte)Crop(buf[0], nbits % 8);
04381         Decode(buf, nbytes, UNSIGNED);
04382 }
04383 
04384 void Integer::Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max)
04385 {
04386         if (min > max)
04387                 throw InvalidArgument("Integer: Min must be no greater than Max");
04388 
04389         Integer range = max - min;
04390         const unsigned int nbits = range.BitCount();
04391 
04392         do
04393         {
04394                 Randomize(rng, nbits);
04395         }
04396         while (*this > range);
04397 
04398         *this += min;
04399 }
04400 
04401 bool Integer::Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType, const Integer &equiv, const Integer &mod)
04402 {
04403         return GenerateRandomNoThrow(rng, MakeParameters("Min", min)("Max", max)("RandomNumberType", rnType)("EquivalentTo", equiv)("Mod", mod));
04404 }
04405 
04406 class KDF2_RNG : public RandomNumberGenerator
04407 {
04408 public:
04409         KDF2_RNG(const byte *seed, unsigned int seedSize)
04410                 : m_counter(0), m_counterAndSeed(seedSize + 4)
04411         {
04412                 memcpy(m_counterAndSeed + 4, seed, seedSize);
04413         }
04414 
04415         byte GenerateByte()
04416         {
04417                 byte b;
04418                 GenerateBlock(&b, 1);
04419                 return b;
04420         }
04421 
04422         void GenerateBlock(byte *output, unsigned int size)
04423         {
04424                 UnalignedPutWord(BIG_ENDIAN_ORDER, m_counterAndSeed, m_counter);
04425                 ++m_counter;
04426                 P1363_KDF2<SHA1>::DeriveKey(output, size, m_counterAndSeed, m_counterAndSeed.size(), NULL, 0);
04427         }
04428 
04429 private:
04430         word32 m_counter;
04431         SecByteBlock m_counterAndSeed;
04432 };
04433 
04434 bool Integer::GenerateRandomNoThrow(RandomNumberGenerator &i_rng, const NameValuePairs &params)
04435 {
04436         Integer min = params.GetValueWithDefault("Min", Integer::Zero());
04437         Integer max;
04438         if (!params.GetValue("Max", max))
04439         {
04440                 int bitLength;
04441                 if (params.GetIntValue("BitLength", bitLength))
04442                         max = Integer::Power2(bitLength);
04443                 else
04444                         throw InvalidArgument("Integer: missing Max argument");
04445         }
04446         if (min > max)
04447                 throw InvalidArgument("Integer: Min must be no greater than Max");
04448 
04449         Integer equiv = params.GetValueWithDefault("EquivalentTo", Integer::Zero());
04450         Integer mod = params.GetValueWithDefault("Mod", Integer::One());
04451 
04452         if (equiv.IsNegative() || equiv >= mod)
04453                 throw InvalidArgument("Integer: invalid EquivalentTo and/or Mod argument");
04454 
04455         Integer::RandomNumberType rnType = params.GetValueWithDefault("RandomNumberType", Integer::ANY);
04456 
04457         member_ptr<KDF2_RNG> kdf2Rng;
04458         ConstByteArrayParameter seed;
04459         if (params.GetValue("Seed", seed))
04460         {
04461                 ByteQueue bq;
04462                 DERSequenceEncoder seq(bq);
04463                 min.DEREncode(seq);
04464                 max.DEREncode(seq);
04465                 equiv.DEREncode(seq);
04466                 mod.DEREncode(seq);
04467                 DEREncodeUnsigned(seq, rnType);
04468                 DEREncodeOctetString(seq, seed.begin(), seed.size());
04469                 seq.MessageEnd();
04470 
04471                 SecByteBlock finalSeed(bq.MaxRetrievable());
04472                 bq.Get(finalSeed, finalSeed.size());
04473                 kdf2Rng.reset(new KDF2_RNG(finalSeed.begin(), finalSeed.size()));
04474         }
04475         RandomNumberGenerator &rng = kdf2Rng.get() ? (RandomNumberGenerator &)*kdf2Rng : i_rng;
04476 
04477         switch (rnType)
04478         {
04479                 case ANY:
04480                         if (mod == One())
04481                                 Randomize(rng, min, max);
04482                         else
04483                         {
04484                                 Integer min1 = min + (equiv-min)%mod;
04485                                 if (max < min1)
04486                                         return false;
04487                                 Randomize(rng, Zero(), (max - min1) / mod);
04488                                 *this *= mod;
04489                                 *this += min1;
04490                         }
04491                         return true;
04492 
04493                 case PRIME:
04494                 {
04495                         const PrimeSelector *pSelector = params.GetValueWithDefault(Name::PointerToPrimeSelector(), (const PrimeSelector *)NULL);
04496 
04497                         int i;
04498                         i = 0;
04499                         while (1)
04500                         {
04501                                 if (++i==16)
04502                                 {
04503                                         // check if there are any suitable primes in [min, max]
04504                                         Integer first = min;
04505                                         if (FirstPrime(first, max, equiv, mod, pSelector))
04506                                         {
04507                                                 // if there is only one suitable prime, we're done
04508                                                 *this = first;
04509                                                 if (!FirstPrime(first, max, equiv, mod, pSelector))
04510                                                         return true;
04511                                         }
04512                                         else
04513                                                 return false;
04514                                 }
04515 
04516                                 Randomize(rng, min, max);
04517                                 if (FirstPrime(*this, STDMIN(*this+mod*PrimeSearchInterval(max), max), equiv, mod, pSelector))
04518                                         return true;
04519                         }
04520                 }
04521 
04522                 default:
04523                         throw InvalidArgument("Integer: invalid RandomNumberType argument");
04524         }
04525 }
04526 
04527 std::istream& operator>>(std::istream& in, Integer &a)
04528 {
04529         char c;
04530         unsigned int length = 0;
04531         SecBlock<char> str(length + 16);
04532 
04533         std::ws(in);
04534 
04535         do
04536         {
04537                 in.read(&c, 1);
04538                 str[length++] = c;
04539                 if (length >= str.size())
04540                         str.Grow(length + 16);
04541         }
04542         while (in && (c=='-' || c=='x' || (c>='0' && c<='9') || (c>='a' && c<='f') || (c>='A' && c<='F') || c=='h' || c=='H' || c=='o' || c=='O' || c==',' || c=='.'));
04543 
04544         if (in.gcount())
04545                 in.putback(c);
04546         str[length-1] = '\0';
04547         a = Integer(str);
04548 
04549         return in;
04550 }
04551 
04552 std::ostream& operator<<(std::ostream& out, const Integer &a)
04553 {
04554         // Get relevant conversion specifications from ostream.
04555         long f = out.flags() & std::ios::basefield; // Get base digits.
04556         int base, block;
04557         char suffix;
04558         switch(f)
04559         {
04560         case std::ios::oct :
04561                 base = 8;
04562                 block = 8;
04563                 suffix = 'o';
04564                 break;
04565         case std::ios::hex :
04566                 base = 16;
04567                 block = 4;
04568                 suffix = 'h';
04569                 break;
04570         default :
04571                 base = 10;
04572                 block = 3;
04573                 suffix = '.';
04574         }
04575 
04576         SecBlock<char> s(a.BitCount() / (BitPrecision(base)-1) + 1);
04577         Integer temp1=a, temp2;
04578         unsigned i=0;
04579         const char vec[]="0123456789ABCDEF";
04580 
04581         if (a.IsNegative())
04582         {
04583                 out << '-';
04584                 temp1.Negate();
04585         }
04586 
04587         if (!a)
04588                 out << '0';
04589 
04590         while (!!temp1)
04591         {
04592                 word digit;
04593                 Integer::Divide(digit, temp2, temp1, base);
04594                 s[i++]=vec[digit];
04595                 temp1=temp2;
04596         }
04597 
04598         while (i--)
04599         {
04600                 out << s[i];
04601 //              if (i && !(i%block))
04602 //                      out << ",";
04603         }
04604         return out << suffix;
04605 }
04606 
04607 Integer& Integer::operator++()
04608 {
04609         if (NotNegative())
04610         {
04611                 if (Increment(reg, reg.size()))
04612                 {
04613                         reg.CleanGrow(2*reg.size());
04614                         reg[reg.size()/2]=1;
04615                 }
04616         }
04617         else
04618         {
04619                 word borrow = Decrement(reg, reg.size());
04620                 assert(!borrow);
04621                 if (WordCount()==0)
04622                         *this = Zero();
04623         }
04624         return *this;
04625 }
04626 
04627 Integer& Integer::operator--()
04628 {
04629         if (IsNegative())
04630         {
04631                 if (Increment(reg, reg.size()))
04632                 {
04633                         reg.CleanGrow(2*reg.size());
04634                         reg[reg.size()/2]=1;
04635                 }
04636         }
04637         else
04638         {
04639                 if (Decrement(reg, reg.size()))
04640                         *this = -One();
04641         }
04642         return *this;
04643 }
04644 
04645 void PositiveAdd(Integer &sum, const Integer &a, const Integer& b)
04646 {
04647         word carry;
04648         if (a.reg.size() == b.reg.size())
04649                 carry = Add(sum.reg, a.reg, b.reg, a.reg.size());
04650         else if (a.reg.size() > b.reg.size())
04651         {
04652                 carry = Add(sum.reg, a.reg, b.reg, b.reg.size());
04653                 CopyWords(sum.reg+b.reg.size(), a.reg+b.reg.size(), a.reg.size()-b.reg.size());
04654                 carry = Increment(sum.reg+b.reg.size(), a.reg.size()-b.reg.size(), carry);
04655         }
04656         else
04657         {
04658                 carry = Add(sum.reg, a.reg, b.reg, a.reg.size());
04659                 CopyWords(sum.reg+a.reg.size(), b.reg+a.reg.size(), b.reg.size()-a.reg.size());
04660                 carry = Increment(sum.reg+a.reg.size(), b.reg.size()-a.reg.size(), carry);
04661         }
04662 
04663         if (carry)
04664         {
04665                 sum.reg.CleanGrow(2*sum.reg.size());
04666                 sum.reg[sum.reg.size()/2] = 1;
04667         }
04668         sum.sign = Integer::POSITIVE;
04669 }
04670 
04671 void PositiveSubtract(Integer &diff, const Integer &a, const Integer& b)
04672 {
04673         unsigned aSize = a.WordCount();
04674         aSize += aSize%2;
04675         unsigned bSize = b.WordCount();
04676         bSize += bSize%2;
04677 
04678         if (aSize == bSize)
04679         {
04680                 if (Compare(a.reg, b.reg, aSize) >= 0)
04681                 {
04682                         Subtract(diff.reg, a.reg, b.reg, aSize);
04683                         diff.sign = Integer::POSITIVE;
04684                 }
04685                 else
04686                 {
04687                         Subtract(diff.reg, b.reg, a.reg, aSize);
04688                         diff.sign = Integer::NEGATIVE;
04689                 }
04690         }
04691         else if (aSize > bSize)
04692         {
04693                 word borrow = Subtract(diff.reg, a.reg, b.reg, bSize);
04694                 CopyWords(diff.reg+bSize, a.reg+bSize, aSize-bSize);
04695                 borrow = Decrement(diff.reg+bSize, aSize-bSize, borrow);
04696                 assert(!borrow);
04697                 diff.sign = Integer::POSITIVE;
04698         }
04699         else
04700         {
04701                 word borrow = Subtract(diff.reg, b.reg, a.reg, aSize);
04702                 CopyWords(diff.reg+aSize, b.reg+aSize, bSize-aSize);
04703                 borrow = Decrement(diff.reg+aSize, bSize-aSize, borrow);
04704                 assert(!borrow);
04705                 diff.sign = Integer::NEGATIVE;
04706         }
04707 }
04708 
04709 Integer Integer::Plus(const Integer& b) const
04710 {
04711         Integer sum((word)0, STDMAX(reg.size(), b.reg.size()));
04712         if (NotNegative())
04713         {
04714                 if (b.NotNegative())
04715                         PositiveAdd(sum, *this, b);
04716                 else
04717                         PositiveSubtract(sum, *this, b);
04718         }
04719         else
04720         {
04721                 if (b.NotNegative())
04722                         PositiveSubtract(sum, b, *this);
04723                 else
04724                 {
04725                         PositiveAdd(sum, *this, b);
04726                         sum.sign = Integer::NEGATIVE;
04727                 }
04728         }
04729         return sum;
04730 }
04731 
04732 Integer& Integer::operator+=(const Integer& t)
04733 {
04734         reg.CleanGrow(t.reg.size());
04735         if (NotNegative())
04736         {
04737                 if (t.NotNegative())
04738                         PositiveAdd(*this, *this, t);
04739                 else
04740                         PositiveSubtract(*this, *this, t);
04741         }
04742         else
04743         {
04744                 if (t.NotNegative())
04745                         PositiveSubtract(*this, t, *this);
04746                 else
04747                 {
04748                         PositiveAdd(*this, *this, t);
04749                         sign = Integer::NEGATIVE;
04750                 }
04751         }
04752         return *this;
04753 }
04754 
04755 Integer Integer::Minus(const Integer& b) const
04756 {
04757         Integer diff((word)0, STDMAX(reg.size(), b.reg.size()));
04758         if (NotNegative())
04759         {
04760                 if (b.NotNegative())
04761                         PositiveSubtract(diff, *this, b);
04762                 else
04763                         PositiveAdd(diff, *this, b);
04764         }
04765         else
04766         {
04767                 if (b.NotNegative())
04768                 {
04769                         PositiveAdd(diff, *this, b);
04770                         diff.sign = Integer::NEGATIVE;
04771                 }
04772                 else
04773                         PositiveSubtract(diff, b, *this);
04774         }
04775         return diff;
04776 }
04777 
04778 Integer& Integer::operator-=(const Integer& t)
04779 {
04780         reg.CleanGrow(t.reg.size());
04781         if (NotNegative())
04782         {
04783                 if (t.NotNegative())
04784                         PositiveSubtract(*this, *this, t);
04785                 else
04786                         PositiveAdd(*this, *this, t);
04787         }
04788         else
04789         {
04790                 if (t.NotNegative())
04791                 {
04792                         PositiveAdd(*this, *this, t);
04793                         sign = Integer::NEGATIVE;
04794                 }
04795                 else
04796                         PositiveSubtract(*this, t, *this);
04797         }
04798         return *this;
04799 }
04800 
04801 Integer& Integer::operator<<=(unsigned int n)
04802 {
04803         const unsigned int wordCount = WordCount();
04804         const unsigned int shiftWords = n / WORD_BITS;
04805         const unsigned int shiftBits = n % WORD_BITS;
04806 
04807         reg.CleanGrow(RoundupSize(wordCount+BitsToWords(n)));
04808         ShiftWordsLeftByWords(reg, wordCount + shiftWords, shiftWords);
04809         ShiftWordsLeftByBits(reg+shiftWords, wordCount+BitsToWords(shiftBits), shiftBits);
04810         return *this;
04811 }
04812 
04813 Integer& Integer::operator>>=(unsigned int n)
04814 {
04815         const unsigned int wordCount = WordCount();
04816         const unsigned int shiftWords = n / WORD_BITS;
04817         const unsigned int shiftBits = n % WORD_BITS;
04818 
04819         ShiftWordsRightByWords(reg, wordCount, shiftWords);
04820         if (wordCount > shiftWords)
04821                 ShiftWordsRightByBits(reg, wordCount-shiftWords, shiftBits);
04822         if (IsNegative() && WordCount()==0)   // avoid -0
04823                 *this = Zero();
04824         return *this;
04825 }
04826 
04827 void PositiveMultiply(Integer &product, const Integer &a, const Integer &b)
04828 {
04829         unsigned aSize = RoundupSize(a.WordCount());
04830         unsigned bSize = RoundupSize(b.WordCount());
04831 
04832         product.reg.CleanNew(RoundupSize(aSize+bSize));
04833         product.sign = Integer::POSITIVE;
04834 
04835         SecAlignedWordBlock workspace(aSize + bSize);
04836         AsymmetricMultiply(product.reg, workspace, a.reg, aSize, b.reg, bSize);
04837 }
04838 
04839 void Multiply(Integer &product, const Integer &a, const Integer &b)
04840 {
04841         PositiveMultiply(product, a, b);
04842 
04843         if (a.NotNegative() != b.NotNegative())
04844                 product.Negate();
04845 }
04846 
04847 Integer Integer::Times(const Integer &b) const
04848 {
04849         Integer product;
04850         Multiply(product, *this, b);
04851         return product;
04852 }
04853 
04854 void PositiveDivide(Integer &remainder, Integer &quotient,
04855                                    const Integer &a, const Integer &b)
04856 {
04857         unsigned aSize = a.WordCount();
04858         unsigned bSize = b.WordCount();
04859 
04860         if (!bSize)
04861                 throw Integer::DivideByZero();
04862 
04863         if (a.PositiveCompare(b) == -1)
04864         {
04865                 remainder = a;
04866                 remainder.sign = Integer::POSITIVE;
04867                 quotient = Integer::Zero();
04868                 return;
04869         }
04870 
04871         aSize += aSize%2;       // round up to next even number
04872         bSize += bSize%2;
04873 
04874         remainder.reg.CleanNew(RoundupSize(bSize));
04875         remainder.sign = Integer::POSITIVE;
04876         quotient.reg.CleanNew(RoundupSize(aSize-bSize+2));
04877         quotient.sign = Integer::POSITIVE;
04878 
04879         SecAlignedWordBlock T(aSize+2*bSize+4);
04880         Divide(remainder.reg, quotient.reg, T, a.reg, aSize, b.reg, bSize);
04881 }
04882 
04883 void Integer::Divide(Integer &remainder, Integer &quotient, const Integer &dividend, const Integer &divisor)
04884 {
04885         PositiveDivide(remainder, quotient, dividend, divisor);
04886 
04887         if (dividend.IsNegative())
04888         {
04889                 quotient.Negate();
04890                 if (remainder.NotZero())
04891                 {
04892                         --quotient;
04893                         remainder = divisor.AbsoluteValue() - remainder;
04894                 }
04895         }
04896 
04897         if (divisor.IsNegative())
04898                 quotient.Negate();
04899 }
04900 
04901 void Integer::DivideByPowerOf2(Integer &r, Integer &q, const Integer &a, unsigned int n)
04902 {
04903         q = a;
04904         q >>= n;
04905 
04906         const unsigned int wordCount = BitsToWords(n);
04907         if (wordCount <= a.WordCount())
04908         {
04909                 r.reg.resize(RoundupSize(wordCount));
04910                 CopyWords(r.reg, a.reg, wordCount);
04911                 SetWords(r.reg+wordCount, 0, r.reg.size()-wordCount);
04912                 if (n % WORD_BITS != 0)
04913                         r.reg[wordCount-1] %= (1 << (n % WORD_BITS));
04914         }
04915         else
04916         {
04917                 r.reg.resize(RoundupSize(a.WordCount()));
04918                 CopyWords(r.reg, a.reg, r.reg.size());
04919         }
04920         r.sign = POSITIVE;
04921 
04922         if (a.IsNegative() && r.NotZero())
04923         {
04924                 --q;
04925                 r = Power2(n) - r;
04926         }
04927 }
04928 
04929 Integer Integer::DividedBy(const Integer &b) const
04930 {
04931         Integer remainder, quotient;
04932         Integer::Divide(remainder, quotient, *this, b);
04933         return quotient;
04934 }
04935 
04936 Integer Integer::Modulo(const Integer &b) const
04937 {
04938         Integer remainder, quotient;
04939         Integer::Divide(remainder, quotient, *this, b);
04940         return remainder;
04941 }
04942 
04943 void Integer::Divide(word &remainder, Integer &quotient, const Integer &dividend, word divisor)
04944 {
04945         if (!divisor)
04946                 throw Integer::DivideByZero();
04947 
04948         assert(divisor);
04949 
04950         if ((divisor & (divisor-1)) == 0)       // divisor is a power of 2
04951         {
04952                 quotient = dividend >> (BitPrecision(divisor)-1);
04953                 remainder = dividend.reg[0] & (divisor-1);
04954                 return;
04955         }
04956 
04957         unsigned int i = dividend.WordCount();
04958         quotient.reg.CleanNew(RoundupSize(i));
04959         remainder = 0;
04960         while (i--)
04961         {
04962                 quotient.reg[i] = DWord(dividend.reg[i], remainder) / divisor;
04963                 remainder = DWord(dividend.reg[i], remainder) % divisor;
04964         }
04965 
04966         if (dividend.NotNegative())
04967                 quotient.sign = POSITIVE;
04968         else
04969         {
04970                 quotient.sign = NEGATIVE;
04971                 if (remainder)
04972                 {
04973                         --quotient;
04974                         remainder = divisor - remainder;
04975                 }
04976         }
04977 }
04978 
04979 Integer Integer::DividedBy(word b) const
04980 {
04981         word remainder;
04982         Integer quotient;
04983         Integer::Divide(remainder, quotient, *this, b);
04984         return quotient;
04985 }
04986 
04987 word Integer::Modulo(word divisor) const
04988 {
04989         if (!divisor)
04990                 throw Integer::DivideByZero();
04991 
04992         assert(divisor);
04993 
04994         word remainder;
04995 
04996         if ((divisor & (divisor-1)) == 0)       // divisor is a power of 2
04997                 remainder = reg[0] & (divisor-1);
04998         else
04999         {
05000                 unsigned int i = WordCount();
05001 
05002                 if (divisor <= 5)
05003                 {
05004                         DWord sum(0, 0);
05005                         while (i--)
05006                                 sum += reg[i];
05007                         remainder = sum % divisor;
05008                 }
05009                 else
05010                 {
05011                         remainder = 0;
05012                         while (i--)
05013                                 remainder = DWord(reg[i], remainder) % divisor;
05014                 }
05015         }
05016 
05017         if (IsNegative() && remainder)
05018                 remainder = divisor - remainder;
05019 
05020         return remainder;
05021 }
05022 
05023 void Integer::Negate()
05024 {
05025         if (!!(*this))  // don't flip sign if *this==0
05026                 sign = Sign(1-sign);
05027 }
05028 
05029 int Integer::PositiveCompare(const Integer& t) const
05030 {
05031         unsigned size = WordCount(), tSize = t.WordCount();
05032 
05033         if (size == tSize)
05034                 return CryptoPP::Compare(reg, t.reg, size);
05035         else
05036                 return size > tSize ? 1 : -1;
05037 }
05038 
05039 int Integer::Compare(const Integer& t) const
05040 {
05041         if (NotNegative())
05042         {
05043                 if (t.NotNegative())
05044                         return PositiveCompare(t);
05045                 else
05046                         return 1;
05047         }
05048         else
05049         {
05050                 if (t.NotNegative())
05051                         return -1;
05052                 else
05053                         return -PositiveCompare(t);
05054         }
05055 }
05056 
05057 Integer Integer::SquareRoot() const
05058 {
05059         if (!IsPositive())
05060                 return Zero();
05061 
05062         // overestimate square root
05063         Integer x, y = Power2((BitCount()+1)/2);
05064         assert(y*y >= *this);
05065 
05066         do
05067         {
05068                 x = y;
05069                 y = (x + *this/x) >> 1;
05070         } while (y<x);
05071 
05072         return x;
05073 }
05074 
05075 bool Integer::IsSquare() const
05076 {
05077         Integer r = SquareRoot();
05078         return *this == r.Squared();
05079 }
05080 
05081 bool Integer::IsUnit() const
05082 {
05083         return (WordCount() == 1) && (reg[0] == 1);
05084 }
05085 
05086 Integer Integer::MultiplicativeInverse() const
05087 {
05088         return IsUnit() ? *this : Zero();
05089 }
05090 
05091 Integer a_times_b_mod_c(const Integer &x, const Integer& y, const Integer& m)
05092 {
05093         return x*y%m;
05094 }
05095 
05096 Integer a_exp_b_mod_c(const Integer &x, const Integer& e, const Integer& m)
05097 {
05098         ModularArithmetic mr(m);
05099         return mr.Exponentiate(x, e);
05100 }
05101 
05102 Integer Integer::Gcd(const Integer &a, const Integer &b)
05103 {
05104         return EuclideanDomainOf<Integer>().Gcd(a, b);
05105 }
05106 
05107 Integer Integer::InverseMod(const Integer &m) const
05108 {
05109         assert(m.NotNegative());
05110 
05111         if (IsNegative() || *this>=m)
05112                 return (*this%m).InverseMod(m);
05113 
05114         if (m.IsEven())
05115         {
05116                 if (!m || IsEven())
05117                         return Zero();  // no inverse
05118                 if (*this == One())
05119                         return One();
05120 
05121                 Integer u = m.InverseMod(*this);
05122                 return !u ? Zero() : (m*(*this-u)+1)/(*this);
05123         }
05124 
05125         SecBlock<word> T(m.reg.size() * 4);
05126         Integer r((word)0, m.reg.size());
05127         unsigned k = AlmostInverse(r.reg, T, reg, reg.size(), m.reg, m.reg.size());
05128         DivideByPower2Mod(r.reg, r.reg, k, m.reg, m.reg.size());
05129         return r;
05130 }
05131 
05132 word Integer::InverseMod(const word mod) const
05133 {
05134         word g0 = mod, g1 = *this % mod;
05135         word v0 = 0, v1 = 1;
05136         word y;
05137 
05138         while (g1)
05139         {
05140                 if (g1 == 1)
05141                         return v1;
05142                 y = g0 / g1;
05143                 g0 = g0 % g1;
05144                 v0 += y * v1;
05145 
05146                 if (!g0)
05147                         break;
05148                 if (g0 == 1)
05149                         return mod-v0;
05150                 y = g1 / g0;
05151                 g1 = g1 % g0;
05152                 v1 += y * v0;
05153         }
05154         return 0;
05155 }
05156 
05157 // ********************************************************
05158 
05159 ModularArithmetic::ModularArithmetic(BufferedTransformation &bt)
05160 {
05161         BERSequenceDecoder seq(bt);
05162         OID oid(seq);
05163         if (oid != ASN1::prime_field())
05164                 BERDecodeError();
05165         modulus.BERDecode(seq);
05166         seq.MessageEnd();
05167         result.reg.resize(modulus.reg.size());
05168 }
05169 
05170 void ModularArithmetic::DEREncode(BufferedTransformation &bt) const
05171 {
05172         DERSequenceEncoder seq(bt);
05173         ASN1::prime_field().DEREncode(seq);
05174         modulus.DEREncode(seq);
05175         seq.MessageEnd();
05176 }
05177 
05178 void ModularArithmetic::DEREncodeElement(BufferedTransformation &out, const Element &a) const
05179 {
05180         a.DEREncodeAsOctetString(out, MaxElementByteLength());
05181 }
05182 
05183 void ModularArithmetic::BERDecodeElement(BufferedTransformation &in, Element &a) const
05184 {
05185         a.BERDecodeAsOctetString(in, MaxElementByteLength());
05186 }
05187 
05188 const Integer& ModularArithmetic::Half(const Integer &a) const
05189 {
05190         if (a.reg.size()==modulus.reg.size())
05191         {
05192                 CryptoPP::DivideByPower2Mod(result.reg.begin(), a.reg, 1, modulus.reg, a.reg.size());
05193                 return result;
05194         }
05195         else
05196                 return result1 = (a.IsEven() ? (a >> 1) : ((a+modulus) >> 1));
05197 }
05198 
05199 const Integer& ModularArithmetic::Add(const Integer &a, const Integer &b) const
05200 {
05201         if (a.reg.size()==modulus.reg.size() && b.reg.size()==modulus.reg.size())
05202         {
05203                 if (CryptoPP::Add(result.reg.begin(), a.reg, b.reg, a.reg.size())
05204                         || Compare(result.reg, modulus.reg, a.reg.size()) >= 0)
05205                 {
05206                         CryptoPP::Subtract(result.reg.begin(), result.reg, modulus.reg, a.reg.size());
05207                 }
05208                 return result;
05209         }
05210         else
05211         {
05212                 result1 = a+b;
05213                 if (result1 >= modulus)
05214                         result1 -= modulus;
05215                 return result1;
05216         }
05217 }
05218 
05219 Integer& ModularArithmetic::Accumulate(Integer &a, const Integer &b) const
05220 {
05221         if (a.reg.size()==modulus.reg.size() && b.reg.size()==modulus.reg.size())
05222         {
05223                 if (CryptoPP::Add(a.reg, a.reg, b.reg, a.reg.size())
05224                         || Compare(a.reg, modulus.reg, a.reg.size()) >= 0)
05225                 {
05226                         CryptoPP::Subtract(a.reg, a.reg, modulus.reg, a.reg.size());
05227                 }
05228         }
05229         else
05230         {
05231                 a+=b;
05232                 if (a>=modulus)
05233                         a-=modulus;
05234         }
05235 
05236         return a;
05237 }
05238 
05239 const Integer& ModularArithmetic::Subtract(const Integer &a, const Integer &b) const
05240 {
05241         if (a.reg.size()==modulus.reg.size() && b.reg.size()==modulus.reg.size())
05242         {
05243                 if (CryptoPP::Subtract(result.reg.begin(), a.reg, b.reg, a.reg.size()))
05244                         CryptoPP::Add(result.reg.begin(), result.reg, modulus.reg, a.reg.size());
05245                 return result;
05246         }
05247         else
05248         {
05249                 result1 = a-b;
05250                 if (result1.IsNegative())
05251                         result1 += modulus;
05252                 return result1;
05253         }
05254 }
05255 
05256 Integer& ModularArithmetic::Reduce(Integer &a, const Integer &b) const
05257 {
05258         if (a.reg.size()==modulus.reg.size() && b.reg.size()==modulus.reg.size())
05259         {
05260                 if (CryptoPP::Subtract(a.reg, a.reg, b.reg, a.reg.size()))
05261                         CryptoPP::Add(a.reg, a.reg, modulus.reg, a.reg.size());
05262         }
05263         else
05264         {
05265                 a-=b;
05266                 if (a.IsNegative())
05267                         a+=modulus;
05268         }
05269 
05270         return a;
05271 }
05272 
05273 const Integer& ModularArithmetic::Inverse(const Integer &a) const
05274 {
05275         if (!a)
05276                 return a;
05277 
05278         CopyWords(result.reg.begin(), modulus.reg, modulus.reg.size());
05279         if (CryptoPP::Subtract(result.reg.begin(), result.reg, a.reg, a.reg.size()))
05280                 Decrement(result.reg.begin()+a.reg.size(), 1, modulus.reg.size()-a.reg.size());
05281 
05282         return result;
05283 }
05284 
05285 Integer ModularArithmetic::CascadeExponentiate(const Integer &x, const Integer &e1, const Integer &y, const Integer &e2) const
05286 {
05287         if (modulus.IsOdd())
05288         {
05289                 MontgomeryRepresentation dr(modulus);
05290                 return dr.ConvertOut(dr.CascadeExponentiate(dr.ConvertIn(x), e1, dr.ConvertIn(y), e2));
05291         }
05292         else
05293                 return AbstractRing<Integer>::CascadeExponentiate(x, e1, y, e2);
05294 }
05295 
05296 void ModularArithmetic::SimultaneousExponentiate(Integer *results, const Integer &base, const Integer *exponents, unsigned int exponentsCount) const
05297 {
05298         if (modulus.IsOdd())
05299         {
05300                 MontgomeryRepresentation dr(modulus);
05301                 dr.SimultaneousExponentiate(results, dr.ConvertIn(base), exponents, exponentsCount);
05302                 for (unsigned int i=0; i<exponentsCount; i++)
05303                         results[i] = dr.ConvertOut(results[i]);
05304         }
05305         else
05306                 AbstractRing<Integer>::SimultaneousExponentiate(results, base, exponents, exponentsCount);
05307 }
05308 
05309 MontgomeryRepresentation::MontgomeryRepresentation(const Integer &m)    // modulus must be odd
05310         : ModularArithmetic(m),
05311           u((word)0, modulus.reg.size()),
05312           workspace(5*modulus.reg.size())
05313 {
05314         if (!modulus.IsOdd())
05315                 throw InvalidArgument("MontgomeryRepresentation: Montgomery representation requires an odd modulus");
05316 
05317         RecursiveInverseModPower2(u.reg, workspace, modulus.reg, modulus.reg.size());
05318 }
05319 
05320 const Integer& MontgomeryRepresentation::Multiply(const Integer &a, const Integer &b) const
05321 {
05322         word *const T = workspace.begin();
05323         word *const R = result.reg.begin();
05324         const unsigned int N = modulus.reg.size();
05325         assert(a.reg.size()<=N && b.reg.size()<=N);
05326 
05327         AsymmetricMultiply(T, T+2*N, a.reg, a.reg.size(), b.reg, b.reg.size());
05328         SetWords(T+a.reg.size()+b.reg.size(), 0, 2*N-a.reg.size()-b.reg.size());
05329         MontgomeryReduce(R, T+2*N, T, modulus.reg, u.reg, N);
05330         return result;
05331 }
05332 
05333 const Integer& MontgomeryRepresentation::Square(const Integer &a) const
05334 {
05335         word *const T = workspace.begin();
05336         word *const R = result.reg.begin();
05337         const unsigned int N = modulus.reg.size();
05338         assert(a.reg.size()<=N);
05339 
05340         CryptoPP::Square(T, T+2*N, a.reg, a.reg.size());
05341         SetWords(T+2*a.reg.size(), 0, 2*N-2*a.reg.size());
05342         MontgomeryReduce(R, T+2*N, T, modulus.reg, u.reg, N);
05343         return result;
05344 }
05345 
05346 Integer MontgomeryRepresentation::ConvertOut(const Integer &a) const
05347 {
05348         word *const T = workspace.begin();
05349         word *const R = result.reg.begin();
05350         const unsigned int N = modulus.reg.size();
05351         assert(a.reg.size()<=N);
05352 
05353         CopyWords(T, a.reg, a.reg.size());
05354         SetWords(T+a.reg.size(), 0, 2*N-a.reg.size());
05355         MontgomeryReduce(R, T+2*N, T, modulus.reg, u.reg, N);
05356         return result;
05357 }
05358 
05359 const Integer& MontgomeryRepresentation::MultiplicativeInverse(const Integer &a) const
05360 {
05361 //        return (EuclideanMultiplicativeInverse(a, modulus)<<(2*WORD_BITS*modulus.reg.size()))%modulus;
05362         word *const T = workspace.begin();
05363         word *const R = result.reg.begin();
05364         const unsigned int N = modulus.reg.size();
05365         assert(a.reg.size()<=N);
05366 
05367         CopyWords(T, a.reg, a.reg.size());
05368         SetWords(T+a.reg.size(), 0, 2*N-a.reg.size());
05369         MontgomeryReduce(R, T+2*N, T, modulus.reg, u.reg, N);
05370         unsigned k = AlmostInverse(R, T, R, N, modulus.reg, N);
05371 
05372 //      cout << "k=" << k << " N*32=" << 32*N << endl;
05373 
05374         if (k>N*WORD_BITS)
05375                 DivideByPower2Mod(R, R, k-N*WORD_BITS, modulus.reg, N);
05376         else
05377                 MultiplyByPower2Mod(R, R, N*WORD_BITS-k, modulus.reg, N);
05378 
05379         return result;
05380 }
05381 
05382 NAMESPACE_END
05383 
05384 #endif
05385 ////////////////////////////////////////////////////////////////////////////////
05386 
05387 
05388 
05389 ////////////////////////////////////////////////////////////////////////////////
05390 // algebra.cpp - written and placed in the public domain by Wei Dai
05391 
05392 //- #include "pch.h"
05393 //- #include "algebra.h"
05394 //- #include "integer.h"
05395 
05396 #include <vector>
05397 
05398 namespace CryptoPP {
05399 
05400 template <class T> const T& AbstractGroup<T>::Double(const Element &a) const
05401 {
05402         return Add(a, a);
05403 }
05404 
05405 template <class T> const T& AbstractGroup<T>::Subtract(const Element &a, const Element &b) const
05406 {
05407         // make copy of a in case Inverse() overwrites it
05408         Element a1(a);
05409         return Add(a1, Inverse(b));
05410 }
05411 
05412 template <class T> T& AbstractGroup<T>::Accumulate(Element &a, const Element &b) const
05413 {
05414         return a = Add(a, b);
05415 }
05416 
05417 template <class T> T& AbstractGroup<T>::Reduce(Element &a, const Element &b) const
05418 {
05419         return a = Subtract(a, b);
05420 }
05421 
05422 template <class T> const T& AbstractRing<T>::Square(const Element &a) const
05423 {
05424         return Multiply(a, a);
05425 }
05426 
05427 template <class T> const T& AbstractRing<T>::Divide(const Element &a, const Element &b) const
05428 {
05429         // make copy of a in case MultiplicativeInverse() overwrites it
05430         Element a1(a);
05431         return Multiply(a1, MultiplicativeInverse(b));
05432 }
05433 
05434 template <class T> const T& AbstractEuclideanDomain<T>::Mod(const Element &a, const Element &b) const
05435 {
05436         Element q;
05437         DivisionAlgorithm(result, q, a, b);
05438         return result;
05439 }
05440 
05441 template <class T> const T& AbstractEuclideanDomain<T>::Gcd(const Element &a, const Element &b) const
05442 {
05443         Element g[3]={b, a};
05444         unsigned int i0=0, i1=1, i2=2;
05445 
05446         while (!Equal(g[i1], this->Identity()))
05447         {
05448                 g[i2] = Mod(g[i0], g[i1]);
05449                 unsigned int t = i0; i0 = i1; i1 = i2; i2 = t;
05450         }
05451 
05452         return result = g[i0];
05453 }
05454 
05455 template <class T> T AbstractGroup<T>::ScalarMultiply(const Element &base, const Integer &exponent) const
05456 {
05457         Element result;
05458         SimultaneousMultiply(&result, base, &exponent, 1);
05459         return result;
05460 }
05461 
05462 template <class T> T AbstractGroup<T>::CascadeScalarMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const
05463 {
05464         const unsigned expLen = STDMAX(e1.BitCount(), e2.BitCount());
05465         if (expLen==0)
05466                 return Identity();
05467 
05468         const unsigned w = (expLen <= 46 ? 1 : (expLen <= 260 ? 2 : 3));
05469         const unsigned tableSize = 1<<w;
05470         std::vector<Element> powerTable(tableSize << w);
05471 
05472         powerTable[1] = x;
05473         powerTable[tableSize] = y;
05474         if (w==1)
05475                 powerTable[3] = Add(x,y);
05476         else
05477         {
05478                 powerTable[2] = Double(x);
05479                 powerTable[2*tableSize] = Double(y);
05480 
05481                 unsigned i, j;
05482 
05483                 for (i=3; i<tableSize; i+=2)
05484                         powerTable[i] = Add(powerTable[i-2], powerTable[2]);
05485                 for (i=1; i<tableSize; i+=2)
05486                         for (j=i+tableSize; j<(tableSize<<w); j+=tableSize)
05487                                 powerTable[j] = Add(powerTable[j-tableSize], y);
05488 
05489                 for (i=3*tableSize; i<(tableSize<<w); i+=2*tableSize)
05490                         powerTable[i] = Add(powerTable[i-2*tableSize], powerTable[2*tableSize]);
05491                 for (i=tableSize; i<(tableSize<<w); i+=2*tableSize)
05492                         for (j=i+2; j<i+tableSize; j+=2)
05493                                 powerTable[j] = Add(powerTable[j-1], x);
05494         }
05495 
05496         Element result;
05497         unsigned power1 = 0, power2 = 0, prevPosition = expLen-1;
05498         bool firstTime = true;
05499 
05500         for (int i = expLen-1; i>=0; i--)
05501         {
05502                 power1 = 2*power1 + e1.GetBit(i);
05503                 power2 = 2*power2 + e2.GetBit(i);
05504 
05505                 if (i==0 || 2*power1 >= tableSize || 2*power2 >= tableSize)
05506                 {
05507                         unsigned squaresBefore = prevPosition-i;
05508                         unsigned squaresAfter = 0;
05509                         prevPosition = i;
05510                         while ((power1 || power2) && power1%2 == 0 && power2%2==0)
05511                         {
05512                                 power1 /= 2;
05513                                 power2 /= 2;
05514                                 squaresBefore--;
05515                                 squaresAfter++;
05516                         }
05517                         if (firstTime)
05518                         {
05519                                 result = powerTable[(power2<<w) + power1];
05520                                 firstTime = false;
05521                         }
05522                         else
05523                         {
05524                                 while (squaresBefore--)
05525                                         result = Double(result);
05526                                 if (power1 || power2)
05527                                         Accumulate(result, powerTable[(power2<<w) + power1]);
05528                         }
05529                         while (squaresAfter--)
05530                                 result = Double(result);
05531                         power1 = power2 = 0;
05532                 }
05533         }
05534         return result;
05535 }
05536 
05537 struct WindowSlider
05538 {
05539         WindowSlider(const Integer &exp, bool fastNegate, unsigned int windowSizeIn=0)
05540                 : exp(exp), windowModulus(Integer::One()), windowSize(windowSizeIn), windowBegin(0), fastNegate(fastNegate), firstTime(true), finished(false)
05541         {
05542                 if (windowSize == 0)
05543                 {
05544                         unsigned int expLen = exp.BitCount();
05545                         windowSize = expLen <= 17 ? 1 : (expLen <= 24 ? 2 : (expLen <= 70 ? 3 : (expLen <= 197 ? 4 : (expLen <= 539 ? 5 : (expLen <= 1434 ? 6 : 7)))));
05546                 }
05547                 windowModulus <<= windowSize;
05548         }
05549 
05550         void FindNextWindow()
05551         {
05552                 unsigned int expLen = exp.WordCount() * WORD_BITS;
05553                 unsigned int skipCount = firstTime ? 0 : windowSize;
05554                 firstTime = false;
05555                 while (!exp.GetBit(skipCount))
05556                 {
05557                         if (skipCount >= expLen)
05558                         {
05559                                 finished = true;
05560                                 return;
05561                         }
05562                         skipCount++;
05563                 }
05564 
05565                 exp >>= skipCount;
05566                 windowBegin += skipCount;
05567                 expWindow = exp % (1 << windowSize);
05568 
05569                 if (fastNegate && exp.GetBit(windowSize))
05570                 {
05571                         negateNext = true;
05572                         expWindow = (1 << windowSize) - expWindow;
05573                         exp += windowModulus;
05574                 }
05575                 else
05576                         negateNext = false;
05577         }
05578 
05579         Integer exp, windowModulus;
05580         unsigned int windowSize, windowBegin, expWindow;
05581         bool fastNegate, negateNext, firstTime, finished;
05582 };
05583 
05584 template <class T>
05585 void AbstractGroup<T>::SimultaneousMultiply(T *results, const T &base, const Integer *expBegin, unsigned int expCount) const
05586 {
05587         std::vector<std::vector<Element> > buckets(expCount);
05588         std::vector<WindowSlider> exponents;
05589         exponents.reserve(expCount);
05590         unsigned int i;
05591 
05592         for (i=0; i<expCount; i++)
05593         {
05594                 assert(expBegin->NotNegative());
05595                 exponents.push_back(WindowSlider(*expBegin++, InversionIsFast(), 0));
05596                 exponents[i].FindNextWindow();
05597                 buckets[i].resize(1<<(exponents[i].windowSize-1), Identity());
05598         }
05599 
05600         unsigned int expBitPosition = 0;
05601         Element g = base;
05602         bool notDone = true;
05603 
05604         while (notDone)
05605         {
05606                 notDone = false;
05607                 for (i=0; i<expCount; i++)
05608                 {
05609                         if (!exponents[i].finished && expBitPosition == exponents[i].windowBegin)
05610                         {
05611                                 Element &bucket = buckets[i][exponents[i].expWindow/2];
05612                                 if (exponents[i].negateNext)
05613                                         Accumulate(bucket, Inverse(g));
05614                                 else
05615                                         Accumulate(bucket, g);
05616                                 exponents[i].FindNextWindow();
05617                         }
05618                         notDone = notDone || !exponents[i].finished;
05619                 }
05620 
05621                 if (notDone)
05622                 {
05623                         g = Double(g);
05624                         expBitPosition++;
05625                 }
05626         }
05627 
05628         for (i=0; i<expCount; i++)
05629         {
05630                 Element &r = *results++;
05631                 r = buckets[i][buckets[i].size()-1];
05632                 if (buckets[i].size() > 1)
05633                 {
05634                         for (int j = buckets[i].size()-2; j >= 1; j--)
05635                         {
05636                                 Accumulate(buckets[i][j], buckets[i][j+1]);
05637                                 Accumulate(r, buckets[i][j]);
05638                         }
05639                         Accumulate(buckets[i][0], buckets[i][1]);
05640                         r = Add(Double(r), buckets[i][0]);
05641                 }
05642         }
05643 }
05644 
05645 template <class T> T AbstractRing<T>::Exponentiate(const Element &base, const Integer &exponent) const
05646 {
05647         Element result;
05648         SimultaneousExponentiate(&result, base, &exponent, 1);
05649         return result;
05650 }
05651 
05652 template <class T> T AbstractRing<T>::CascadeExponentiate(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const
05653 {
05654         return MultiplicativeGroup().AbstractGroup<T>::CascadeScalarMultiply(x, e1, y, e2);
05655 }
05656 
05657 template <class T>
05658 void AbstractRing<T>::SimultaneousExponentiate(T *results, const T &base, const Integer *exponents, unsigned int expCount) const
05659 {
05660         MultiplicativeGroup().AbstractGroup<T>::SimultaneousMultiply(results, base, exponents, expCount);
05661 }
05662 
05663 NAMESPACE_END
05664 ////////////////////////////////////////////////////////////////////////////////
05665 
05666 
05667 
05668 ////////////////////////////////////////////////////////////////////////////////
05669 // queue.cpp - written and placed in the public domain by Wei Dai
05670 
05671 //- #include "pch.h"
05672 
05673 #ifndef CRYPTOPP_IMPORTS
05674 
05675 //- #include "queue.h"
05676 //- #include "filters.h"
05677 
05678 namespace CryptoPP {
05679 
05680 static const unsigned int s_maxAutoNodeSize = 16*1024;
05681 
05682 // this class for use by ByteQueue only
05683 class ByteQueueNode
05684 {
05685 public:
05686         ByteQueueNode(unsigned int maxSize)
05687                 : buf(maxSize)
05688         {
05689                 m_head = m_tail = 0;
05690                 next = 0;
05691         }
05692 
05693         inline unsigned int MaxSize() const {return buf.size();}
05694 
05695         inline unsigned int CurrentSize() const
05696         {
05697                 return m_tail-m_head;
05698         }
05699 
05700         inline bool UsedUp() const
05701         {
05702                 return (m_head==MaxSize());
05703         }
05704 
05705         inline void Clear()
05706         {
05707                 m_head = m_tail = 0;
05708         }
05709 
05710         inline unsigned int Put(const byte *begin, unsigned int length)
05711         {
05712                 unsigned int l = STDMIN(length, MaxSize()-m_tail);
05713                 if (buf+m_tail != begin)
05714                         memcpy(buf+m_tail, begin, l);
05715                 m_tail += l;
05716                 return l;
05717         }
05718 
05719         inline unsigned int Peek(byte &outByte) const
05720         {
05721                 if (m_tail==m_head)
05722                         return 0;
05723 
05724                 outByte=buf[m_head];
05725                 return 1;
05726         }
05727 
05728         inline unsigned int Peek(byte *target, unsigned int copyMax) const
05729         {
05730                 unsigned int len = STDMIN(copyMax, m_tail-m_head);
05731                 memcpy(target, buf+m_head, len);
05732                 return len;
05733         }
05734 
05735         inline unsigned int CopyTo(BufferedTransformation &target, const std::string &channel=BufferedTransformation::NULL_CHANNEL) const
05736         {
05737                 unsigned int len = m_tail-m_head;
05738                 target.ChannelPut(channel, buf+m_head, len);
05739                 return len;
05740         }
05741 
05742         inline unsigned int CopyTo(BufferedTransformation &target, unsigned int copyMax, const std::string &channel=BufferedTransformation::NULL_CHANNEL) const
05743         {
05744                 unsigned int len = STDMIN(copyMax, m_tail-m_head);
05745                 target.ChannelPut(channel, buf+m_head, len);
05746                 return len;
05747         }
05748 
05749         inline unsigned int Get(byte &outByte)
05750         {
05751                 unsigned int len = Peek(outByte);
05752                 m_head += len;
05753                 return len;
05754         }
05755 
05756         inline unsigned int Get(byte *outString, unsigned int getMax)
05757         {
05758                 unsigned int len = Peek(outString, getMax);
05759                 m_head += len;
05760                 return len;
05761         }
05762 
05763         inline unsigned int TransferTo(BufferedTransformation &target, const std::string &channel=BufferedTransformation::NULL_CHANNEL)
05764         {
05765                 unsigned int len = m_tail-m_head;
05766                 target.ChannelPutModifiable(channel, buf+m_head, len);
05767                 m_head = m_tail;
05768                 return len;
05769         }
05770 
05771         inline unsigned int TransferTo(BufferedTransformation &target, unsigned int transferMax, const std::string &channel=BufferedTransformation::NULL_CHANNEL)
05772         {
05773                 unsigned int len = STDMIN(transferMax, m_tail-m_head);
05774                 target.ChannelPutModifiable(channel, buf+m_head, len);
05775                 m_head += len;
05776                 return len;
05777         }
05778 
05779         inline unsigned int Skip(unsigned int skipMax)
05780         {
05781                 unsigned int len = STDMIN(skipMax, m_tail-m_head);
05782                 m_head += len;
05783                 return len;
05784         }
05785 
05786         inline byte operator[](unsigned int i) const
05787         {
05788                 return buf[m_head+i];
05789         }
05790 
05791         ByteQueueNode *next;
05792 
05793         SecByteBlock buf;
05794         unsigned int m_head, m_tail;
05795 };
05796 
05797 // ********************************************************
05798 
05799 ByteQueue::ByteQueue(unsigned int nodeSize)
05800         : m_lazyLength(0)
05801 {
05802         SetNodeSize(nodeSize);
05803         m_head = m_tail = new ByteQueueNode(m_nodeSize);
05804 }
05805 
05806 void ByteQueue::SetNodeSize(unsigned int nodeSize)
05807 {
05808         m_autoNodeSize = !nodeSize;
05809         m_nodeSize = m_autoNodeSize ? 256 : nodeSize;
05810 }
05811 
05812 ByteQueue::ByteQueue(const ByteQueue &copy)
05813         : Bufferless<BufferedTransformation>()
05814 {
05815         CopyFrom(copy);
05816 }
05817 
05818 void ByteQueue::CopyFrom(const ByteQueue &copy)
05819 {
05820         m_lazyLength = 0;
05821         m_autoNodeSize = copy.m_autoNodeSize;
05822         m_nodeSize = copy.m_nodeSize;
05823         m_head = m_tail = new ByteQueueNode(*copy.m_head);
05824 
05825         for (ByteQueueNode *current=copy.m_head->next; current; current=current->next)
05826         {
05827                 m_tail->next = new ByteQueueNode(*current);
05828                 m_tail = m_tail->next;
05829         }
05830 
05831         m_tail->next = NULL;
05832 
05833         Put(copy.m_lazyString, copy.m_lazyLength);
05834 }
05835 
05836 ByteQueue::~ByteQueue()
05837 {
05838         Destroy();
05839 }
05840 
05841 void ByteQueue::Destroy()
05842 {
05843         for (ByteQueueNode *next, *current=m_head; current; current=next)
05844         {
05845                 next=current->next;
05846                 delete current;
05847         }
05848 }
05849 
05850 void ByteQueue::IsolatedInitialize(const NameValuePairs &parameters)
05851 {
05852         m_nodeSize = parameters.GetIntValueWithDefault("NodeSize", 256);
05853         Clear();
05854 }
05855 
05856 unsigned long ByteQueue::CurrentSize() const
05857 {
05858         unsigned long size=0;
05859 
05860         for (ByteQueueNode *current=m_head; current; current=current->next)
05861                 size += current->CurrentSize();
05862 
05863         return size + m_lazyLength;
05864 }
05865 
05866 bool ByteQueue::IsEmpty() const
05867 {
05868         return m_head==m_tail && m_head->CurrentSize()==0 && m_lazyLength==0;
05869 }
05870 
05871 void ByteQueue::Clear()
05872 {
05873         for (ByteQueueNode *next, *current=m_head->next; current; current=next)
05874         {
05875                 next=current->next;
05876                 delete current;
05877         }
05878 
05879         m_tail = m_head;
05880         m_head->Clear();
05881         m_head->next = NULL;
05882         m_lazyLength = 0;
05883 }
05884 
05885 unsigned int ByteQueue::Put2(const byte *inString, unsigned int length, int /* messageEnd */, bool /* blocking */)
05886 {
05887         if (m_lazyLength > 0)
05888                 FinalizeLazyPut();
05889 
05890         unsigned int len;
05891         while ((len=m_tail->Put(inString, length)) < length)
05892         {
05893                 inString += len;
05894                 length -= len;
05895                 if (m_autoNodeSize && m_nodeSize < s_maxAutoNodeSize)
05896                         do
05897                         {
05898                                 m_nodeSize *= 2;
05899                         }
05900                         while (m_nodeSize < length && m_nodeSize < s_maxAutoNodeSize);
05901                 m_tail->next = new ByteQueueNode(STDMAX(m_nodeSize, length));
05902                 m_tail = m_tail->next;
05903         }
05904 
05905         return 0;
05906 }
05907 
05908 void ByteQueue::CleanupUsedNodes()
05909 {
05910         while (m_head != m_tail && m_head->UsedUp())
05911         {
05912                 ByteQueueNode *temp=m_head;
05913                 m_head=m_head->next;
05914                 delete temp;
05915         }
05916 
05917         if (m_head->CurrentSize() == 0)
05918                 m_head->Clear();
05919 }
05920 
05921 void ByteQueue::LazyPut(const byte *inString, unsigned int size)
05922 {
05923         if (m_lazyLength > 0)
05924                 FinalizeLazyPut();
05925 
05926         if (inString == m_tail->buf+m_tail->m_tail)
05927                 Put(inString, size);
05928         else
05929         {
05930                 m_lazyString = const_cast<byte *>(inString);
05931                 m_lazyLength = size;
05932                 m_lazyStringModifiable = false;
05933         }
05934 }
05935 
05936 void ByteQueue::LazyPutModifiable(byte *inString, unsigned int size)
05937 {
05938         if (m_lazyLength > 0)
05939                 FinalizeLazyPut();
05940         m_lazyString = inString;
05941         m_lazyLength = size;
05942         m_lazyStringModifiable = true;
05943 }
05944 
05945 void ByteQueue::UndoLazyPut(unsigned int size)
05946 {
05947         if (m_lazyLength < size)
05948                 throw InvalidArgument("ByteQueue: size specified for UndoLazyPut is too large");
05949 
05950         m_lazyLength -= size;
05951 }
05952 
05953 void ByteQueue::FinalizeLazyPut()
05954 {
05955         unsigned int len = m_lazyLength;
05956         m_lazyLength = 0;
05957         if (len)
05958                 Put(m_lazyString, len);
05959 }
05960 
05961 unsigned int ByteQueue::Get(byte &outByte)
05962 {
05963         if (m_head->Get(outByte))
05964         {
05965                 if (m_head->UsedUp())
05966                         CleanupUsedNodes();
05967                 return 1;
05968         }
05969         else if (m_lazyLength > 0)
05970         {
05971                 outByte = *m_lazyString++;
05972                 m_lazyLength--;
05973                 return 1;
05974         }
05975         else
05976                 return 0;
05977 }
05978 
05979 unsigned int ByteQueue::Get(byte *outString, unsigned int getMax)
05980 {
05981         ArraySink sink(outString, getMax);
05982         return TransferTo(sink, getMax);
05983 }
05984 
05985 unsigned int ByteQueue::Peek(byte &outByte) const
05986 {
05987         if (m_head->Peek(outByte))
05988                 return 1;
05989         else if (m_lazyLength > 0)
05990         {
05991                 outByte = *m_lazyString;
05992                 return 1;
05993         }
05994         else
05995                 return 0;
05996 }
05997 
05998 unsigned int ByteQueue::Peek(byte *outString, unsigned int peekMax) const
05999 {
06000         ArraySink sink(outString, peekMax);
06001         return CopyTo(sink, peekMax);
06002 }
06003 
06004 unsigned int ByteQueue::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
06005 {
06006         if (blocking)
06007         {
06008                 unsigned long bytesLeft = transferBytes;
06009                 for (ByteQueueNode *current=m_head; bytesLeft && current; current=current->next)
06010                         bytesLeft -= current->TransferTo(target, bytesLeft, channel);
06011                 CleanupUsedNodes();
06012 
06013                 unsigned int len = (unsigned int)STDMIN(bytesLeft, (unsigned long)m_lazyLength);
06014                 if (len)
06015                 {
06016                         if (m_lazyStringModifiable)
06017                                 target.ChannelPutModifiable(channel, m_lazyString, len);
06018                         else
06019                                 target.ChannelPut(channel, m_lazyString, len);
06020                         m_lazyString += len;
06021                         m_lazyLength -= len;
06022                         bytesLeft -= len;
06023                 }
06024                 transferBytes -= bytesLeft;
06025                 return 0;
06026         }
06027         else
06028         {
06029                 Walker walker(*this);
06030                 unsigned int blockedBytes = walker.TransferTo2(target, transferBytes, channel, blocking);
06031                 Skip(transferBytes);
06032                 return blockedBytes;
06033         }
06034 }
06035 
06036 unsigned int ByteQueue::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
06037 {
06038         Walker walker(*this);
06039         walker.Skip(begin);
06040         unsigned long transferBytes = end-begin;
06041         unsigned int blockedBytes = walker.TransferTo2(target, transferBytes, channel, blocking);
06042         begin += transferBytes;
06043         return blockedBytes;
06044 }
06045 
06046 void ByteQueue::Unget(byte inByte)
06047 {
06048         Unget(&inByte, 1);
06049 }
06050 
06051 void ByteQueue::Unget(const byte *inString, unsigned int length)
06052 {
06053         unsigned int len = STDMIN(length, m_head->m_head);
06054         length -= len;
06055         m_head->m_head -= len;
06056         memcpy(m_head->buf + m_head->m_head, inString + length, len);
06057 
06058         if (length > 0)
06059         {
06060                 ByteQueueNode *newHead = new ByteQueueNode(length);
06061                 newHead->next = m_head;
06062                 m_head = newHead;
06063                 m_head->Put(inString, length);
06064         }
06065 }
06066 
06067 const byte * ByteQueue::Spy(unsigned int &contiguousSize) const
06068 {
06069         contiguousSize = m_head->m_tail - m_head->m_head;
06070         if (contiguousSize == 0 && m_lazyLength > 0)
06071         {
06072                 contiguousSize = m_lazyLength;
06073                 return m_lazyString;
06074         }
06075         else
06076                 return m_head->buf + m_head->m_head;
06077 }
06078 
06079 byte * ByteQueue::CreatePutSpace(unsigned int &size)
06080 {
06081         if (m_lazyLength > 0)
06082                 FinalizeLazyPut();
06083 
06084         if (m_tail->m_tail == m_tail->MaxSize())
06085         {
06086                 m_tail->next = new ByteQueueNode(STDMAX(m_nodeSize, size));
06087                 m_tail = m_tail->next;
06088         }
06089 
06090         size = m_tail->MaxSize() - m_tail->m_tail;
06091         return m_tail->buf + m_tail->m_tail;
06092 }
06093 
06094 ByteQueue & ByteQueue::operator=(const ByteQueue &rhs)
06095 {
06096         Destroy();
06097         CopyFrom(rhs);
06098         return *this;
06099 }
06100 
06101 bool ByteQueue::operator==(const ByteQueue &rhs) const
06102 {
06103         const unsigned long currentSize = CurrentSize();
06104 
06105         if (currentSize != rhs.CurrentSize())
06106                 return false;
06107 
06108         Walker walker1(*this), walker2(rhs);
06109         byte b1, b2;
06110 
06111         while (walker1.Get(b1) && walker2.Get(b2))
06112                 if (b1 != b2)
06113                         return false;
06114 
06115         return true;
06116 }
06117 
06118 byte ByteQueue::operator[](unsigned long i) const
06119 {
06120         for (ByteQueueNode *current=m_head; current; current=current->next)
06121         {
06122                 if (i < current->CurrentSize())
06123                         return (*current)[i];
06124 
06125                 i -= current->CurrentSize();
06126         }
06127 
06128         assert(i < m_lazyLength);
06129         return m_lazyString[i];
06130 }
06131 
06132 void ByteQueue::swap(ByteQueue &rhs)
06133 {
06134         std::swap(m_autoNodeSize, rhs.m_autoNodeSize);
06135         std::swap(m_nodeSize, rhs.m_nodeSize);
06136         std::swap(m_head, rhs.m_head);
06137         std::swap(m_tail, rhs.m_tail);
06138         std::swap(m_lazyString, rhs.m_lazyString);
06139         std::swap(m_lazyLength, rhs.m_lazyLength);
06140         std::swap(m_lazyStringModifiable, rhs.m_lazyStringModifiable);
06141 }
06142 
06143 // ********************************************************
06144 
06145 void ByteQueue::Walker::IsolatedInitialize(const NameValuePairs& /* parameters */)
06146 {
06147         m_node = m_queue.m_head;
06148         m_position = 0;
06149         m_offset = 0;
06150         m_lazyString = m_queue.m_lazyString;
06151         m_lazyLength = m_queue.m_lazyLength;
06152 }
06153 
06154 unsigned int ByteQueue::Walker::Get(byte &outByte)
06155 {
06156         ArraySink sink(&outByte, 1);
06157         return TransferTo(sink, 1);
06158 }
06159 
06160 unsigned int ByteQueue::Walker::Get(byte *outString, unsigned int getMax)
06161 {
06162         ArraySink sink(outString, getMax);
06163         return TransferTo(sink, getMax);
06164 }
06165 
06166 unsigned int ByteQueue::Walker::Peek(byte &outByte) const
06167 {
06168         ArraySink sink(&outByte, 1);
06169         return CopyTo(sink, 1);
06170 }
06171 
06172 unsigned int ByteQueue::Walker::Peek(byte *outString, unsigned int peekMax) const
06173 {
06174         ArraySink sink(outString, peekMax);
06175         return CopyTo(sink, peekMax);
06176 }
06177 
06178 unsigned int ByteQueue::Walker::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
06179 {
06180         unsigned long bytesLeft = transferBytes;
06181         unsigned int blockedBytes = 0;
06182 
06183         while (m_node)
06184         {
06185                 unsigned int len = STDMIN(bytesLeft, (unsigned long)m_node->CurrentSize()-m_offset);
06186                 blockedBytes = target.ChannelPut2(channel, m_node->buf+m_node->m_head+m_offset, len, 0, blocking);
06187 
06188                 if (blockedBytes)
06189                         goto done;
06190 
06191                 m_position += len;
06192                 bytesLeft -= len;
06193 
06194                 if (!bytesLeft)
06195                 {
06196                         m_offset += len;
06197                         goto done;
06198                 }
06199 
06200                 m_node = m_node->next;
06201                 m_offset = 0;
06202         }
06203 
06204         if (bytesLeft && m_lazyLength)
06205         {
06206                 unsigned int len = (unsigned int)STDMIN(bytesLeft, (unsigned long)m_lazyLength);
06207                 unsigned int blockedBytes = target.ChannelPut2(channel, m_lazyString, len, 0, blocking);
06208                 if (blockedBytes)
06209                         goto done;
06210 
06211                 m_lazyString += len;
06212                 m_lazyLength -= len;
06213                 bytesLeft -= len;
06214         }
06215 
06216 done:
06217         transferBytes -= bytesLeft;
06218         return blockedBytes;
06219 }
06220 
06221 unsigned int ByteQueue::Walker::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
06222 {
06223         Walker walker(*this);
06224         walker.Skip(begin);
06225         unsigned long transferBytes = end-begin;
06226         unsigned int blockedBytes = walker.TransferTo2(target, transferBytes, channel, blocking);
06227         begin += transferBytes;
06228         return blockedBytes;
06229 }
06230 
06231 NAMESPACE_END
06232 
06233 #endif
06234 ////////////////////////////////////////////////////////////////////////////////
06235 
06236 
06237 
06238 ////////////////////////////////////////////////////////////////////////////////
06239 // algparam.cpp - written and placed in the public domain by Wei Dai
06240 
06241 //- #include "pch.h"
06242 
06243 #ifndef CRYPTOPP_IMPORTS
06244 
06245 //- #include "algparam.h"
06246 
06247 namespace CryptoPP {
06248 
06249 bool (*AssignIntToInteger)(const std::type_info &valueType, void *pInteger, const void *pInt) = NULL;
06250 
06251 bool CombinedNameValuePairs::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
06252 {
06253         if (strcmp(name, "ValueNames") == 0)
06254                 return m_pairs1.GetVoidValue(name, valueType, pValue) && m_pairs2.GetVoidValue(name, valueType, pValue);
06255         else
06256                 return m_pairs1.GetVoidValue(name, valueType, pValue) || m_pairs2.GetVoidValue(name, valueType, pValue);
06257 }
06258 
06259 bool AlgorithmParametersBase::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
06260 {
06261         if (strcmp(name, "ValueNames") == 0)
06262         {
06263                 ThrowIfTypeMismatch(name, typeid(std::string), valueType);
06264                 GetParent().GetVoidValue(name, valueType, pValue);
06265                 (*reinterpret_cast<std::string *>(pValue) += m_name) += ";";
06266                 return true;
06267         }
06268         else if (strcmp(name, m_name) == 0)
06269         {
06270                 AssignValue(name, valueType, pValue);
06271                 m_used = true;
06272                 return true;
06273         }
06274         else
06275                 return GetParent().GetVoidValue(name, valueType, pValue);
06276 }
06277 
06278 NAMESPACE_END
06279 
06280 #endif
06281 ////////////////////////////////////////////////////////////////////////////////
06282 
06283 
06284 
06285 ////////////////////////////////////////////////////////////////////////////////
06286 #ifndef CRYPTOPP_MQUEUE_H
06287 #define CRYPTOPP_MQUEUE_H
06288 
06289 //- #include "queue.h"
06290 //- #include "filters.h"
06291 #include <deque>
06292 
06293 namespace CryptoPP {
06294 
06295 //! Message Queue
06296 class CRYPTOPP_DLL MessageQueue : public AutoSignaling<BufferedTransformation>
06297 {
06298 public:
06299         MessageQueue(unsigned int nodeSize=256);
06300 
06301         void IsolatedInitialize(const NameValuePairs &parameters)
06302                 {m_queue.IsolatedInitialize(parameters); m_lengths.assign(1, 0U); m_messageCounts.assign(1, 0U);}
06303         unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool /* blocking */)
06304         {
06305                 m_queue.Put(begin, length);
06306                 m_lengths.back() += length;
06307                 if (messageEnd)
06308                 {
06309                         m_lengths.push_back(0);
06310                         m_messageCounts.back()++;
06311                 }
06312                 return 0;
06313         }
06314         bool IsolatedFlush(bool /* hardFlush */, bool /* blocking */) {return false;}
06315         bool IsolatedMessageSeriesEnd(bool /* blocking */)
06316                 {m_messageCounts.push_back(0); return false;}
06317 
06318         unsigned long MaxRetrievable() const
06319                 {return m_lengths.front();}
06320         bool AnyRetrievable() const
06321                 {return m_lengths.front() > 0;}
06322 
06323         unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
06324         unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const;
06325 
06326         unsigned long TotalBytesRetrievable() const
06327                 {return m_queue.MaxRetrievable();}
06328         unsigned int NumberOfMessages() const
06329                 {return m_lengths.size()-1;}
06330         bool GetNextMessage();
06331 
06332         unsigned int NumberOfMessagesInThisSeries() const
06333                 {return m_messageCounts[0];}
06334         unsigned int NumberOfMessageSeries() const
06335                 {return m_messageCounts.size()-1;}
06336 
06337         unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=NULL_CHANNEL) const;
06338 
06339         const byte * Spy(unsigned int &contiguousSize) const;
06340 
06341         void swap(MessageQueue &rhs);
06342 
06343 private:
06344         ByteQueue m_queue;
06345         std::deque<unsigned long> m_lengths, m_messageCounts;
06346 };
06347 
06348 
06349 NAMESPACE_END
06350 
06351 NAMESPACE_BEGIN(std)
06352 template<> inline void swap(CryptoPP::MessageQueue &a, CryptoPP::MessageQueue &b)
06353 {
06354         a.swap(b);
06355 }
06356 NAMESPACE_END
06357 
06358 #endif
06359 ////////////////////////////////////////////////////////////////////////////////
06360 
06361 
06362 
06363 ////////////////////////////////////////////////////////////////////////////////
06364 // mqueue.cpp - written and placed in the public domain by Wei Dai
06365 
06366 //- #include "pch.h"
06367 
06368 #ifndef CRYPTOPP_IMPORTS
06369 
06370 //- #include "mqueue.h"
06371 
06372 namespace CryptoPP {
06373 
06374 MessageQueue::MessageQueue(unsigned int nodeSize)
06375         : m_queue(nodeSize), m_lengths(1, 0U), m_messageCounts(1, 0U)
06376 {
06377 }
06378 
06379 unsigned int MessageQueue::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
06380 {
06381         if (begin >= MaxRetrievable())
06382                 return 0;
06383 
06384         return m_queue.CopyRangeTo2(target, begin, STDMIN(MaxRetrievable(), end), channel, blocking);
06385 }
06386 
06387 unsigned int MessageQueue::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
06388 {
06389         transferBytes = STDMIN(MaxRetrievable(), transferBytes);
06390         unsigned int blockedBytes = m_queue.TransferTo2(target, transferBytes, channel, blocking);
06391         m_lengths.front() -= transferBytes;
06392         return blockedBytes;
06393 }
06394 
06395 bool MessageQueue::GetNextMessage()
06396 {
06397         if (NumberOfMessages() > 0 && !AnyRetrievable())
06398         {
06399                 m_lengths.pop_front();
06400                 if (m_messageCounts[0] == 0 && m_messageCounts.size() > 1)
06401                         m_messageCounts.pop_front();
06402                 return true;
06403         }
06404         else
06405                 return false;
06406 }
06407 
06408 unsigned int MessageQueue::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const
06409 {
06410         ByteQueue::Walker walker(m_queue);
06411         std::deque<unsigned long>::const_iterator it = m_lengths.begin();
06412         unsigned int i;
06413         for (i=0; i<count && it != --m_lengths.end(); ++i, ++it)
06414         {
06415                 walker.TransferTo(target, *it, channel);
06416                 if (GetAutoSignalPropagation())
06417                         target.ChannelMessageEnd(channel, GetAutoSignalPropagation()-1);
06418         }
06419         return i;
06420 }
06421 
06422 void MessageQueue::swap(MessageQueue &rhs)
06423 {
06424         m_queue.swap(rhs.m_queue);
06425         m_lengths.swap(rhs.m_lengths);
06426 }
06427 
06428 const byte * MessageQueue::Spy(unsigned int &contiguousSize) const
06429 {
06430         const byte *result = m_queue.Spy(contiguousSize);
06431         contiguousSize = (unsigned int)STDMIN((unsigned long)contiguousSize, MaxRetrievable());
06432         return result;
06433 }
06434 
06435 NAMESPACE_END
06436 
06437 #endif
06438 ////////////////////////////////////////////////////////////////////////////////
06439 
06440 
06441 
06442 ////////////////////////////////////////////////////////////////////////////////
06443 // filters.cpp - written and placed in the public domain by Wei Dai
06444 
06445 //- #include "pch.h"
06446 
06447 #ifndef CRYPTOPP_IMPORTS
06448 
06449 //- #include "filters.h"
06450 //- #include "mqueue.h"
06451 //- #include "fltrimpl.h"
06452 //- #include "argnames.h"
06453 #include <memory>
06454 #include <functional>
06455 
06456 namespace CryptoPP {
06457 
06458 Filter::Filter(BufferedTransformation *attachment)
06459         : m_attachment(attachment), m_continueAt(0)
06460 {
06461 }
06462 
06463 BufferedTransformation * Filter::NewDefaultAttachment() const
06464 {
06465         return new MessageQueue;
06466 }
06467 
06468 BufferedTransformation * Filter::AttachedTransformation()
06469 {
06470         if (m_attachment.get() == NULL)
06471                 m_attachment.reset(NewDefaultAttachment());
06472         return m_attachment.get();
06473 }
06474 
06475 const BufferedTransformation *Filter::AttachedTransformation() const
06476 {
06477         if (m_attachment.get() == NULL)
06478                 const_cast<Filter *>(this)->m_attachment.reset(NewDefaultAttachment());
06479         return m_attachment.get();
06480 }
06481 
06482 void Filter::Detach(BufferedTransformation *newOut)
06483 {
06484         m_attachment.reset(newOut);
06485 }
06486 
06487 void Filter::Insert(Filter *filter)
06488 {
06489         filter->m_attachment.reset(m_attachment.release());
06490         m_attachment.reset(filter);
06491 }
06492 
06493 unsigned int Filter::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
06494 {
06495         return AttachedTransformation()->CopyRangeTo2(target, begin, end, channel, blocking);
06496 }
06497 
06498 unsigned int Filter::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
06499 {
06500         return AttachedTransformation()->TransferTo2(target, transferBytes, channel, blocking);
06501 }
06502 
06503 void Filter::Initialize(const NameValuePairs &parameters, int propagation)
06504 {
06505         m_continueAt = 0;
06506         IsolatedInitialize(parameters);
06507         PropagateInitialize(parameters, propagation);
06508 }
06509 
06510 bool Filter::Flush(bool hardFlush, int propagation, bool blocking)
06511 {
06512         switch (m_continueAt)
06513         {
06514         case 0:
06515                 if (IsolatedFlush(hardFlush, blocking))
06516                         return true;
06517         case 1:
06518                 if (OutputFlush(1, hardFlush, propagation, blocking))
06519                         return true;
06520         }
06521         return false;
06522 }
06523 
06524 bool Filter::MessageSeriesEnd(int propagation, bool blocking)
06525 {
06526         switch (m_continueAt)
06527         {
06528         case 0:
06529                 if (IsolatedMessageSeriesEnd(blocking))
06530                         return true;
06531         case 1:
06532                 if (ShouldPropagateMessageSeriesEnd() && OutputMessageSeriesEnd(1, propagation, blocking))
06533                         return true;
06534         }
06535         return false;
06536 }
06537 
06538 void Filter::PropagateInitialize(const NameValuePairs &parameters, int propagation)
06539 {
06540         if (propagation)
06541                 AttachedTransformation()->Initialize(parameters, propagation-1);
06542 }
06543 
06544 unsigned int Filter::OutputModifiable(int outputSite, byte *inString, unsigned int length, int messageEnd, bool blocking, const std::string& /* channel */)
06545 {
06546         if (messageEnd)
06547                 messageEnd--;
06548         unsigned int result = AttachedTransformation()->PutModifiable2(inString, length, messageEnd, blocking);
06549         m_continueAt = result ? outputSite : 0;
06550         return result;
06551 }
06552 
06553 unsigned int Filter::Output(int outputSite, const byte *inString, unsigned int length, int messageEnd, bool blocking, const std::string& /* channel */)
06554 {
06555         if (messageEnd)
06556                 messageEnd--;
06557         unsigned int result = AttachedTransformation()->Put2(inString, length, messageEnd, blocking);
06558         m_continueAt = result ? outputSite : 0;
06559         return result;
06560 }
06561 
06562 bool Filter::OutputFlush(int outputSite, bool hardFlush, int propagation, bool blocking, const std::string &channel)
06563 {
06564         if (propagation && AttachedTransformation()->ChannelFlush(channel, hardFlush, propagation-1, blocking))
06565         {
06566                 m_continueAt = outputSite;
06567                 return true;
06568         }
06569         m_continueAt = 0;
06570         return false;
06571 }
06572 
06573 bool Filter::OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel)
06574 {
06575         if (propagation && AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation-1, blocking))
06576         {
06577                 m_continueAt = outputSite;
06578                 return true;
06579         }
06580         m_continueAt = 0;
06581         return false;
06582 }
06583 
06584 // *************************************************************
06585 
06586 void FilterWithBufferedInput::BlockQueue::ResetQueue(unsigned int blockSize, unsigned int maxBlocks)
06587 {
06588         m_buffer.New(blockSize * maxBlocks);
06589         m_blockSize = blockSize;
06590         m_maxBlocks = maxBlocks;
06591         m_size = 0;
06592         m_begin = m_buffer;
06593 }
06594 
06595 byte *FilterWithBufferedInput::BlockQueue::GetBlock()
06596 {
06597         if (m_size >= m_blockSize)
06598         {
06599                 byte *ptr = m_begin;
06600                 if ((m_begin+=m_blockSize) == m_buffer.end())
06601                         m_begin = m_buffer;
06602                 m_size -= m_blockSize;
06603                 return ptr;
06604         }
06605         else
06606                 return NULL;
06607 }
06608 
06609 byte *FilterWithBufferedInput::BlockQueue::GetContigousBlocks(unsigned int &numberOfBytes)
06610 {
06611         numberOfBytes = STDMIN(numberOfBytes, STDMIN((unsigned int)(m_buffer.end()-m_begin), m_size));
06612         byte *ptr = m_begin;
06613         m_begin += numberOfBytes;
06614         m_size -= numberOfBytes;
06615         if (m_size == 0 || m_begin == m_buffer.end())
06616                 m_begin = m_buffer;
06617         return ptr;
06618 }
06619 
06620 unsigned int FilterWithBufferedInput::BlockQueue::GetAll(byte *outString)
06621 {
06622         unsigned int size = m_size;
06623         unsigned int numberOfBytes = m_maxBlocks*m_blockSize;
06624         const byte *ptr = GetContigousBlocks(numberOfBytes);
06625         memcpy(outString, ptr, numberOfBytes);
06626         memcpy(outString+numberOfBytes, m_begin, m_size);
06627         m_size = 0;
06628         return size;
06629 }
06630 
06631 void FilterWithBufferedInput::BlockQueue::Put(const byte *inString, unsigned int length)
06632 {
06633         assert(m_size + length <= m_buffer.size());
06634         byte *end = (m_size < (unsigned int)(m_buffer.end()-m_begin)) ? m_begin + m_size : m_begin + m_size - m_buffer.size();
06635         unsigned int len = STDMIN(length, (unsigned int)(m_buffer.end()-end));
06636         memcpy(end, inString, len);
06637         if (len < length)
06638                 memcpy(m_buffer, inString+len, length-len);
06639         m_size += length;
06640 }
06641 
06642 FilterWithBufferedInput::FilterWithBufferedInput(BufferedTransformation *attachment)
06643         : Filter(attachment)
06644 {
06645 }
06646 
06647 FilterWithBufferedInput::FilterWithBufferedInput(unsigned int firstSize, unsigned int blockSize, unsigned int lastSize, BufferedTransformation *attachment)
06648         : Filter(attachment), m_firstSize(firstSize), m_blockSize(blockSize), m_lastSize(lastSize)
06649         , m_firstInputDone(false)
06650 {
06651         if (m_blockSize < 1)
06652                 throw InvalidArgument("FilterWithBufferedInput: invalid buffer size");
06653 
06654         m_queue.ResetQueue(1, m_firstSize);
06655 }
06656 
06657 void FilterWithBufferedInput::IsolatedInitialize(const NameValuePairs &parameters)
06658 {
06659         InitializeDerivedAndReturnNewSizes(parameters, m_firstSize, m_blockSize, m_lastSize);
06660         if (m_blockSize < 1)
06661                 throw InvalidArgument("FilterWithBufferedInput: invalid buffer size");
06662         m_queue.ResetQueue(1, m_firstSize);
06663         m_firstInputDone = false;
06664 }
06665 
06666 bool FilterWithBufferedInput::IsolatedFlush(bool hardFlush, bool blocking)
06667 {
06668         if (!blocking)
06669                 throw BlockingInputOnly("FilterWithBufferedInput");
06670 
06671         if (hardFlush)
06672                 ForceNextPut();
06673         FlushDerived();
06674 
06675         return false;
06676 }
06677 
06678 unsigned int FilterWithBufferedInput::PutMaybeModifiable(byte *inString, unsigned int length, int messageEnd, bool blocking, bool modifiable)
06679 {
06680         if (!blocking)
06681                 throw BlockingInputOnly("FilterWithBufferedInput");
06682 
06683         if (length != 0)
06684         {
06685                 unsigned int newLength = m_queue.CurrentSize() + length;
06686 
06687                 if (!m_firstInputDone && newLength >= m_firstSize)
06688                 {
06689                         unsigned int len = m_firstSize - m_queue.CurrentSize();
06690                         m_queue.Put(inString, len);
06691                         FirstPut(m_queue.GetContigousBlocks(m_firstSize));
06692                         assert(m_queue.CurrentSize() == 0);
06693                         m_queue.ResetQueue(m_blockSize, (2*m_blockSize+m_lastSize-2)/m_blockSize);
06694 
06695                         inString += len;
06696                         newLength -= m_firstSize;
06697                         m_firstInputDone = true;
06698                 }
06699 
06700                 if (m_firstInputDone)
06701                 {
06702                         if (m_blockSize == 1)
06703                         {
06704                                 while (newLength > m_lastSize && m_queue.CurrentSize() > 0)
06705                                 {
06706                                         unsigned int len = newLength - m_lastSize;
06707                                         byte *ptr = m_queue.GetContigousBlocks(len);
06708                                         NextPutModifiable(ptr, len);
06709                                         newLength -= len;
06710                                 }
06711 
06712                                 if (newLength > m_lastSize)
06713                                 {
06714                                         unsigned int len = newLength - m_lastSize;
06715                                         NextPutMaybeModifiable(inString, len, modifiable);
06716                                         inString += len;
06717                                         newLength -= len;
06718                                 }
06719                         }
06720                         else
06721                         {
06722                                 while (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() >= m_blockSize)
06723                                 {
06724                                         NextPutModifiable(m_queue.GetBlock(), m_blockSize);
06725                                         newLength -= m_blockSize;
06726                                 }
06727 
06728                                 if (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() > 0)
06729                                 {
06730                                         assert(m_queue.CurrentSize() < m_blockSize);
06731                                         unsigned int len = m_blockSize - m_queue.CurrentSize();
06732                                         m_queue.Put(inString, len);
06733                                         inString += len;
06734                                         NextPutModifiable(m_queue.GetBlock(), m_blockSize);
06735                                         newLength -= m_blockSize;
06736                                 }
06737 
06738                                 if (newLength >= m_blockSize + m_lastSize)
06739                                 {
06740                                         unsigned int len = RoundDownToMultipleOf(newLength - m_lastSize, m_blockSize);
06741                                         NextPutMaybeModifiable(inString, len, modifiable);
06742                                         inString += len;
06743                                         newLength -= len;
06744                                 }
06745                         }
06746                 }
06747 
06748                 m_queue.Put(inString, newLength - m_queue.CurrentSize());
06749         }
06750 
06751         if (messageEnd)
06752         {
06753                 if (!m_firstInputDone && m_firstSize==0)
06754                         FirstPut(NULL);
06755 
06756                 SecByteBlock temp(m_queue.CurrentSize());
06757                 m_queue.GetAll(temp);
06758                 LastPut(temp, temp.size());
06759 
06760                 m_firstInputDone = false;
06761                 m_queue.ResetQueue(1, m_firstSize);
06762 
06763                 Output(1, NULL, 0, messageEnd, blocking);
06764         }
06765         return 0;
06766 }
06767 
06768 void FilterWithBufferedInput::ForceNextPut()
06769 {
06770         if (!m_firstInputDone)
06771                 return;
06772 
06773         if (m_blockSize > 1)
06774         {
06775                 while (m_queue.CurrentSize() >= m_blockSize)
06776                         NextPutModifiable(m_queue.GetBlock(), m_blockSize);
06777         }
06778         else
06779         {
06780                 unsigned int len;
06781                 while ((len = m_queue.CurrentSize()) > 0)
06782                         NextPutModifiable(m_queue.GetContigousBlocks(len), len);
06783         }
06784 }
06785 
06786 void FilterWithBufferedInput::NextPutMultiple(const byte *inString, unsigned int length)
06787 {
06788         assert(m_blockSize > 1);        // m_blockSize = 1 should always override this function
06789         while (length > 0)
06790         {
06791                 assert(length >= m_blockSize);
06792                 NextPutSingle(inString);
06793                 inString += m_blockSize;
06794                 length -= m_blockSize;
06795         }
06796 }
06797 
06798 // *************************************************************
06799 
06800 ProxyFilter::ProxyFilter(BufferedTransformation *filter, unsigned int firstSize, unsigned int lastSize, BufferedTransformation *attachment)
06801         : FilterWithBufferedInput(firstSize, 1, lastSize, attachment), m_filter(filter)
06802 {
06803         if (m_filter.get())
06804                 m_filter->Attach(new OutputProxy(*this, false));
06805 }
06806 
06807 bool ProxyFilter::IsolatedFlush(bool hardFlush, bool blocking)
06808 {
06809         return m_filter.get() ? m_filter->Flush(hardFlush, -1, blocking) : false;
06810 }
06811 
06812 void ProxyFilter::SetFilter(Filter *filter)
06813 {
06814         m_filter.reset(filter);
06815         if (filter)
06816         {
06817                 OutputProxy *proxy;
06818                 std::auto_ptr<OutputProxy> temp(proxy = new OutputProxy(*this, false));
06819                 m_filter->TransferAllTo(*proxy);
06820                 m_filter->Attach(temp.release());
06821         }
06822 }
06823 
06824 void ProxyFilter::NextPutMultiple(const byte *s, unsigned int len)
06825 {
06826         if (m_filter.get())
06827                 m_filter->Put(s, len);
06828 }
06829 
06830 void ProxyFilter::NextPutModifiable(byte *s, unsigned int len)
06831 {
06832         if (m_filter.get())
06833                 m_filter->PutModifiable(s, len);
06834 }
06835 
06836 // *************************************************************
06837 
06838 unsigned int ArraySink::Put2(const byte *begin, unsigned int length, int /* messageEnd */, bool /* blocking */)
06839 {
06840         memcpy(m_buf+m_total, begin, STDMIN(length, SaturatingSubtract(m_size, m_total)));
06841         m_total += length;
06842         return 0;
06843 }
06844 
06845 byte * ArraySink::CreatePutSpace(unsigned int &size)
06846 {
06847         size = m_size - m_total;
06848         return m_buf + m_total;
06849 }
06850 
06851 void ArraySink::IsolatedInitialize(const NameValuePairs &parameters)
06852 {
06853         ByteArrayParameter array;
06854         if (!parameters.GetValue(Name::OutputBuffer(), array))
06855                 throw InvalidArgument("ArraySink: missing OutputBuffer argument");
06856         m_buf = array.begin();
06857         m_size = array.size();
06858         m_total = 0;
06859 }
06860 
06861 unsigned int ArrayXorSink::Put2(const byte *begin, unsigned int length, int /* messageEnd */, bool /* blocking */)
06862 {
06863         xorbuf(m_buf+m_total, begin, STDMIN(length, SaturatingSubtract(m_size, m_total)));
06864         m_total += length;
06865         return 0;
06866 }
06867 
06868 // *************************************************************
06869 
06870 void HashFilter::IsolatedInitialize(const NameValuePairs &parameters)
06871 {
06872         m_putMessage = parameters.GetValueWithDefault(Name::PutMessage(), false);
06873         m_hashModule.Restart();
06874 }
06875 
06876 unsigned int HashFilter::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
06877 {
06878         FILTER_BEGIN;
06879         m_hashModule.Update(inString, length);
06880         if (m_putMessage)
06881                 FILTER_OUTPUT(1, inString, length, 0);
06882         if (messageEnd)
06883         {
06884                 {
06885                         unsigned int size, digestSize = m_hashModule.DigestSize();
06886                         m_space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, digestSize, digestSize, size = digestSize);
06887                         m_hashModule.Final(m_space);
06888                 }
06889                 FILTER_OUTPUT(2, m_space, m_hashModule.DigestSize(), messageEnd);
06890         }
06891         FILTER_END_NO_MESSAGE_END;
06892 }
06893 
06894 // *************************************************************
06895 
06896 unsigned int Source::PumpAll2(bool blocking)
06897 {
06898         // TODO: switch length type
06899         unsigned long i = UINT_MAX;
06900         RETURN_IF_NONZERO(Pump2(i, blocking));
06901         unsigned int j = UINT_MAX;
06902         return PumpMessages2(j, blocking);
06903 }
06904 
06905 bool Store::GetNextMessage()
06906 {
06907         if (!m_messageEnd && !AnyRetrievable())
06908         {
06909                 m_messageEnd=true;
06910                 return true;
06911         }
06912         else
06913                 return false;
06914 }
06915 
06916 unsigned int Store::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const
06917 {
06918         if (m_messageEnd || count == 0)
06919                 return 0;
06920         else
06921         {
06922                 CopyTo(target, ULONG_MAX, channel);
06923                 if (GetAutoSignalPropagation())
06924                         target.ChannelMessageEnd(channel, GetAutoSignalPropagation()-1);
06925                 return 1;
06926         }
06927 }
06928 
06929 void StringStore::StoreInitialize(const NameValuePairs &parameters)
06930 {
06931         ConstByteArrayParameter array;
06932         if (!parameters.GetValue(Name::InputBuffer(), array))
06933                 throw InvalidArgument("StringStore: missing InputBuffer argument");
06934         m_store = array.begin();
06935         m_length = array.size();
06936         m_count = 0;
06937 }
06938 
06939 unsigned int StringStore::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
06940 {
06941         unsigned long position = 0;
06942         unsigned int blockedBytes = CopyRangeTo2(target, position, transferBytes, channel, blocking);
06943         m_count += position;
06944         transferBytes = position;
06945         return blockedBytes;
06946 }
06947 
06948 unsigned int StringStore::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
06949 {
06950         unsigned int i = (unsigned int)STDMIN((unsigned long)m_count+begin, (unsigned long)m_length);
06951         unsigned int len = (unsigned int)STDMIN((unsigned long)m_length-i, end-begin);
06952         unsigned int blockedBytes = target.ChannelPut2(channel, m_store+i, len, 0, blocking);
06953         if (!blockedBytes)
06954                 begin += len;
06955         return blockedBytes;
06956 }
06957 
06958 
06959 NAMESPACE_END
06960 
06961 #endif
06962 ////////////////////////////////////////////////////////////////////////////////
06963 
06964 
06965 
06966 ////////////////////////////////////////////////////////////////////////////////
06967 // pubkey.cpp - written and placed in the public domain by Wei Dai
06968 
06969 //- #include "pch.h"
06970 
06971 #ifndef CRYPTOPP_IMPORTS
06972 
06973 //- #include "pubkey.h"
06974 
06975 namespace CryptoPP {
06976 
06977 void P1363_MGF1KDF2_Common(HashTransformation &hash, byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength, const byte *derivationParams, unsigned int derivationParamsLength, bool mask, unsigned int counterStart)
06978 {
06979         ArraySink *sink;
06980         HashFilter filter(hash, sink = mask ? new ArrayXorSink(output, outputLength) : new ArraySink(output, outputLength));
06981         word32 counter = counterStart;
06982         while (sink->AvailableSize() > 0)
06983         {
06984                 filter.Put(input, inputLength);
06985                 filter.PutWord32(counter++);
06986                 filter.Put(derivationParams, derivationParamsLength);
06987                 filter.MessageEnd();
06988         }
06989 }
06990 
06991 bool PK_DeterministicSignatureMessageEncodingMethod::VerifyMessageRepresentative(
06992         HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
06993         byte *representative, unsigned int representativeBitLength) const
06994 {
06995         SecByteBlock computedRepresentative(BitsToBytes(representativeBitLength));
06996         ComputeMessageRepresentative(NullRNG(), NULL, 0, hash, hashIdentifier, messageEmpty, computedRepresentative, representativeBitLength);
06997         return memcmp(representative, computedRepresentative, computedRepresentative.size()) == 0;
06998 }
06999 
07000 void TF_SignerBase::InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, unsigned int recoverableMessageLength) const
07001 {
07002         PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
07003         const MessageEncodingInterface &mei = GetMessageEncodingInterface();
07004         unsigned int maxRecoverableLength = mei.MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, ma.AccessHash().DigestSize());
07005 
07006         if (maxRecoverableLength == 0)
07007                 {throw NotImplemented("TF_SignerBase: this algorithm does not support messsage recovery or the key is too short");}
07008         if (recoverableMessageLength > maxRecoverableLength)
07009                 throw InvalidArgument("TF_SignerBase: the recoverable message part is too long for the given key and algorithm");
07010 
07011         ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength);
07012         mei.ProcessRecoverableMessage(
07013                 ma.AccessHash(),
07014                 recoverableMessage, recoverableMessageLength,
07015                 NULL, 0, ma.m_semisignature);
07016 }
07017 
07018 unsigned int TF_SignerBase::SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool /* restart */) const
07019 {
07020         PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
07021         SecByteBlock representative(MessageRepresentativeLength());
07022         GetMessageEncodingInterface().ComputeMessageRepresentative(rng,
07023                 ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
07024                 ma.AccessHash(), GetHashIdentifier(), ma.m_empty,
07025                 representative, MessageRepresentativeBitLength());
07026         ma.m_empty = true;
07027 
07028         Integer r(representative, representative.size());
07029         unsigned int signatureLength = SignatureLength();
07030         GetTrapdoorFunctionInterface().CalculateRandomizedInverse(rng, r).Encode(signature, signatureLength);
07031         return signatureLength;
07032 }
07033 
07034 void TF_VerifierBase::InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, unsigned int signatureLength) const
07035 {
07036         PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
07037         ma.m_representative.New(MessageRepresentativeLength());
07038         Integer x = GetTrapdoorFunctionInterface().ApplyFunction(Integer(signature, signatureLength));
07039         if (x.BitCount() > MessageRepresentativeBitLength())
07040                 x = Integer::Zero();    // don't return false here to prevent timing attack
07041         x.Encode(ma.m_representative, ma.m_representative.size());
07042 }
07043 
07044 bool TF_VerifierBase::VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
07045 {
07046         PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
07047         bool result = GetMessageEncodingInterface().VerifyMessageRepresentative(
07048                 ma.AccessHash(), GetHashIdentifier(), ma.m_empty, ma.m_representative, MessageRepresentativeBitLength());
07049         ma.m_empty = true;
07050         return result;
07051 }
07052 
07053 DecodingResult TF_VerifierBase::RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
07054 {
07055         PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
07056         DecodingResult result = GetMessageEncodingInterface().RecoverMessageFromRepresentative(
07057                 ma.AccessHash(), GetHashIdentifier(), ma.m_empty, ma.m_representative, MessageRepresentativeBitLength(), recoveredMessage);
07058         ma.m_empty = true;
07059         return result;
07060 }
07061 
07062 NAMESPACE_END
07063 
07064 #endif
07065 ////////////////////////////////////////////////////////////////////////////////
07066 
07067 
07068 
07069 ////////////////////////////////////////////////////////////////////////////////
07070 // iterhash.cpp - written and placed in the public domain by Wei Dai
07071 
07072 //- #include "pch.h"
07073 //- #include "iterhash.h"
07074 //- #include "misc.h"
07075 
07076 namespace CryptoPP {
07077 
07078 template <class T, class BASE> void IteratedHashBase<T, BASE>::Update(const byte *input, unsigned int len)
07079 {
07080         HashWordType tmp = m_countLo;
07081         if ((m_countLo = tmp + len) < tmp)
07082                 m_countHi++;             // carry from low to high
07083         m_countHi += SafeRightShift<8*sizeof(HashWordType)>(len);
07084 
07085         unsigned int blockSize = BlockSize();
07086         unsigned int num = ModPowerOf2(tmp, blockSize);
07087 
07088         if (num != 0)   // process left over data
07089         {
07090                 if ((num+len) >= blockSize)
07091                 {
07092                         memcpy((byte *)m_data.begin()+num, input, blockSize-num);
07093                         HashBlock(m_data);
07094                         input += (blockSize-num);
07095                         len-=(blockSize - num);
07096                         num=0;
07097                         // drop through and do the rest
07098                 }
07099                 else
07100                 {
07101                         memcpy((byte *)m_data.begin()+num, input, len);
07102                         return;
07103                 }
07104         }
07105 
07106         // now process the input data in blocks of blockSize bytes and save the leftovers to m_data
07107         if (len >= blockSize)
07108         {
07109                 if (input == (byte *)m_data.begin())
07110                 {
07111                         assert(len == blockSize);
07112                         HashBlock(m_data);
07113                         return;
07114                 }
07115                 else if (IsAligned<T>(input))
07116                 {
07117                         unsigned int leftOver = HashMultipleBlocks((T *)input, len);
07118                         input += (len - leftOver);
07119                         len = leftOver;
07120                 }
07121                 else
07122                         do
07123                         {   // copy input first if it's not aligned correctly
07124                                 memcpy(m_data, input, blockSize);
07125                                 HashBlock(m_data);
07126                                 input+=blockSize;
07127                                 len-=blockSize;
07128                         } while (len >= blockSize);
07129         }
07130 
07131         memcpy(m_data, input, len);
07132 }
07133 
07134 template <class T, class BASE> byte * IteratedHashBase<T, BASE>::CreateUpdateSpace(unsigned int &size)
07135 {
07136         unsigned int blockSize = BlockSize();
07137         unsigned int num = ModPowerOf2(m_countLo, blockSize);
07138         size = blockSize - num;
07139         return (byte *)m_data.begin() + num;
07140 }
07141 
07142 template <class T, class BASE> unsigned int IteratedHashBase<T, BASE>::HashMultipleBlocks(const T *input, unsigned int length)
07143 {
07144         unsigned int blockSize = BlockSize();
07145         do
07146         {
07147                 HashBlock(input);
07148                 input += blockSize/sizeof(T);
07149                 length -= blockSize;
07150         }
07151         while (length >= blockSize);
07152         return length;
07153 }
07154 
07155 template <class T, class BASE> void IteratedHashBase<T, BASE>::PadLastBlock(unsigned int lastBlockSize, byte padFirst)
07156 {
07157         unsigned int blockSize = BlockSize();
07158         unsigned int num = ModPowerOf2(m_countLo, blockSize);
07159         ((byte *)m_data.begin())[num++]=padFirst;
07160         if (num <= lastBlockSize)
07161                 memset((byte *)m_data.begin()+num, 0, lastBlockSize-num);
07162         else
07163         {
07164                 memset((byte *)m_data.begin()+num, 0, blockSize-num);
07165                 HashBlock(m_data);
07166                 memset(m_data, 0, lastBlockSize);
07167         }
07168 }
07169 
07170 template <class T, class BASE> void IteratedHashBase<T, BASE>::Restart()
07171 {
07172         m_countLo = m_countHi = 0;
07173         Init();
07174 }
07175 
07176 NAMESPACE_END
07177 ////////////////////////////////////////////////////////////////////////////////
07178 
07179 
07180 
07181 ////////////////////////////////////////////////////////////////////////////////
07182 // sha.cpp - modified by Wei Dai from Steve Reid's public domain sha1.c
07183 
07184 // Steve Reid implemented SHA-1. Wei Dai implemented SHA-2.
07185 // Both are in the public domain.
07186 
07187 //- #include "pch.h"
07188 //- #include "sha.h"
07189 //- #include "misc.h"
07190 
07191 namespace CryptoPP {
07192 
07193 // start of Steve Reid's code
07194 
07195 #define blk0(i) (W[i] = data[i])
07196 #define blk1(i) (W[i&15] = rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1))
07197 
07198 #ifndef CRYPTOPP_IMPORTS
07199 
07200 void SHA::InitState(HashWordType *state)
07201 {
07202         state[0] = 0x67452301L;
07203         state[1] = 0xEFCDAB89L;
07204         state[2] = 0x98BADCFEL;
07205         state[3] = 0x10325476L;
07206         state[4] = 0xC3D2E1F0L;
07207 }
07208 
07209 #define f1(x,y,z) (z^(x&(y^z)))
07210 #define f2(x,y,z) (x^y^z)
07211 #define f3(x,y,z) ((x&y)|(z&(x|y)))
07212 #define f4(x,y,z) (x^y^z)
07213 
07214 /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
07215 #define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30);
07216 #define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30);
07217 #define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rotlFixed(v,5);w=rotlFixed(w,30);
07218 #define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rotlFixed(v,5);w=rotlFixed(w,30);
07219 #define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rotlFixed(v,5);w=rotlFixed(w,30);
07220 
07221 void SHA::Transform(word32 *state, const word32 *data)
07222 {
07223         word32 W[16];
07224     /* Copy context->state[] to working vars */
07225     word32 a = state[0];
07226     word32 b = state[1];
07227     word32 c = state[2];
07228     word32 d = state[3];
07229     word32 e = state[4];
07230     /* 4 rounds of 20 operations each. Loop unrolled. */
07231     R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
07232     R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
07233     R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
07234     R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
07235     R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
07236     R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
07237     R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
07238     R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
07239     R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
07240     R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
07241     R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
07242     R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
07243     R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
07244     R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
07245     R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
07246     R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
07247     R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
07248     R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
07249     R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
07250     R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
07251     /* Add the working vars back into context.state[] */
07252     state[0] += a;
07253     state[1] += b;
07254     state[2] += c;
07255     state[3] += d;
07256     state[4] += e;
07257     /* Wipe variables */
07258     a = b = c = d = e = 0;
07259         memset(W, 0, sizeof(W));
07260 }
07261 
07262 #endif  // #ifndef CRYPTOPP_IMPORTS
07263 
07264 // end of Steve Reid's code
07265 
07266 // *************************************************************
07267 
07268 NAMESPACE_END
07269 ////////////////////////////////////////////////////////////////////////////////
07270 
07271 
07272 
07273 ////////////////////////////////////////////////////////////////////////////////
07274 // pkcspad.cpp - written and placed in the public domain by Wei Dai
07275 
07276 //- #include "pch.h"
07277 
07278 //- #include "pkcspad.h"
07279 #include <assert.h>
07280 
07281 namespace CryptoPP {
07282 
07283 template<> const byte PKCS_DigestDecoration<SHA>::decoration[] = {0x30,0x21,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x05,0x00,0x04,0x14};
07284 template<> const unsigned int PKCS_DigestDecoration<SHA>::length = sizeof(PKCS_DigestDecoration<SHA>::decoration);
07285 
07286 unsigned int PKCS_EncryptionPaddingScheme::MaxUnpaddedLength(unsigned int paddedLength) const
07287 {
07288         return SaturatingSubtract(paddedLength/8, 10U);
07289 }
07290 
07291 void PKCS_EncryptionPaddingScheme::Pad(RandomNumberGenerator &rng, const byte *input, unsigned int inputLen, byte *pkcsBlock, unsigned int pkcsBlockLen, const NameValuePairs& /* parameters */) const
07292 {
07293         assert (inputLen <= MaxUnpaddedLength(pkcsBlockLen));   // this should be checked by caller
07294 
07295         // convert from bit length to byte length
07296         if (pkcsBlockLen % 8 != 0)
07297         {
07298                 pkcsBlock[0] = 0;
07299                 pkcsBlock++;
07300         }
07301         pkcsBlockLen /= 8;
07302 
07303         pkcsBlock[0] = 2;  // block type 2
07304 
07305         // pad with non-zero random bytes
07306         for (unsigned i = 1; i < pkcsBlockLen-inputLen-1; i++)
07307                 pkcsBlock[i] = (byte)rng.GenerateWord32(1, 0xff);
07308 
07309         pkcsBlock[pkcsBlockLen-inputLen-1] = 0;     // separator
07310         memcpy(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen);
07311 }
07312 
07313 DecodingResult PKCS_EncryptionPaddingScheme::Unpad(const byte *pkcsBlock, unsigned int pkcsBlockLen, byte *output, const NameValuePairs& /* parameters */) const
07314 {
07315         bool invalid = false;
07316         unsigned int maxOutputLen = MaxUnpaddedLength(pkcsBlockLen);
07317 
07318         // convert from bit length to byte length
07319         if (pkcsBlockLen % 8 != 0)
07320         {
07321                 invalid = (pkcsBlock[0] != 0) || invalid;
07322                 pkcsBlock++;
07323         }
07324         pkcsBlockLen /= 8;
07325 
07326         // Require block type 2.
07327         invalid = (pkcsBlock[0] != 2) || invalid;
07328 
07329         // skip past the padding until we find the separator
07330         unsigned i=1;
07331         while (i<pkcsBlockLen && pkcsBlock[i++]) { // null body
07332                 }
07333         assert(i==pkcsBlockLen || pkcsBlock[i-1]==0);
07334 
07335         unsigned int outputLen = pkcsBlockLen - i;
07336         invalid = (outputLen > maxOutputLen) || invalid;
07337 
07338         if (invalid)
07339                 return DecodingResult();
07340 
07341         memcpy (output, pkcsBlock+i, outputLen);
07342         return DecodingResult(outputLen);
07343 }
07344 
07345 // ********************************************************
07346 
07347 #ifndef CRYPTOPP_IMPORTS
07348 
07349 void PKCS1v15_SignatureMessageEncodingMethod::ComputeMessageRepresentative(RandomNumberGenerator& /* rng */,
07350         const byte* /* recoverableMessage */, unsigned int /* recoverableMessageLength */,
07351         HashTransformation &hash, HashIdentifier hashIdentifier, bool /* messageEmpty */,
07352         byte *representative, unsigned int representativeBitLength) const
07353 {
07354         unsigned int digestSize = hash.DigestSize();
07355         if (digestSize + hashIdentifier.second + 10 > representativeBitLength/8)
07356                 throw PK_Signer::KeyTooShort();
07357 
07358         unsigned int pkcsBlockLen = representativeBitLength;
07359         // convert from bit length to byte length
07360         if (pkcsBlockLen % 8 != 0)
07361         {
07362                 representative[0] = 0;
07363                 representative++;
07364         }
07365         pkcsBlockLen /= 8;
07366 
07367         representative[0] = 1;   // block type 1
07368 
07369         byte *pPadding = representative + 1;
07370         byte *pDigest = representative + pkcsBlockLen - digestSize;
07371         byte *pHashId = pDigest - hashIdentifier.second;
07372         byte *pSeparator = pHashId - 1;
07373 
07374         // pad with 0xff
07375         memset(pPadding, 0xff, pSeparator-pPadding);
07376         *pSeparator = 0;
07377         memcpy(pHashId, hashIdentifier.first, hashIdentifier.second);
07378         hash.Final(pDigest);
07379 }
07380 
07381 #endif
07382 
07383 NAMESPACE_END
07384 ////////////////////////////////////////////////////////////////////////////////
07385 
07386 
07387 
07388 ////////////////////////////////////////////////////////////////////////////////
07389 // asn.cpp - written and placed in the public domain by Wei Dai
07390 
07391 //- #include "pch.h"
07392 
07393 #ifndef CRYPTOPP_IMPORTS
07394 
07395 //- #include "asn.h"
07396 
07397 #include <iomanip>
07398 #include <time.h>
07399 
07400 namespace CryptoPP {
07401 USING_NAMESPACE(std)
07402 
07403 /// DER Length
07404 unsigned int DERLengthEncode(BufferedTransformation &bt, unsigned int length)
07405 {
07406         unsigned int i=0;
07407         if (length <= 0x7f)
07408         {
07409                 bt.Put(byte(length));
07410                 i++;
07411         }
07412         else
07413         {
07414                 bt.Put(byte(BytePrecision(length) | 0x80));
07415                 i++;
07416                 for (int j=BytePrecision(length); j; --j)
07417                 {
07418                         bt.Put(byte(length >> (j-1)*8));
07419                         i++;
07420                 }
07421         }
07422         return i;
07423 }
07424 
07425 bool BERLengthDecode(BufferedTransformation &bt, unsigned int &length, bool &definiteLength)
07426 {
07427         byte b;
07428 
07429         if (!bt.Get(b))
07430                 return false;
07431 
07432         if (!(b & 0x80))
07433         {
07434                 definiteLength = true;
07435                 length = b;
07436         }
07437         else
07438         {
07439                 unsigned int lengthBytes = b & 0x7f;
07440 
07441                 if (lengthBytes == 0)
07442                 {
07443                         definiteLength = false;
07444                         return true;
07445                 }
07446 
07447                 definiteLength = true;
07448                 length = 0;
07449                 while (lengthBytes--)
07450                 {
07451                         if (length >> (8*(sizeof(length)-1)))
07452                                 BERDecodeError();       // length about to overflow
07453 
07454                         if (!bt.Get(b))
07455                                 return false;
07456 
07457                         length = (length << 8) | b;
07458                 }
07459         }
07460         return true;
07461 }
07462 
07463 bool BERLengthDecode(BufferedTransformation &bt, unsigned int &length)
07464 {
07465         bool definiteLength = false;
07466         if (!BERLengthDecode(bt, length, definiteLength))
07467                 BERDecodeError();
07468         return definiteLength;
07469 }
07470 
07471 void DEREncodeNull(BufferedTransformation &out)
07472 {
07473         out.Put(TAG_NULL);
07474         out.Put(0);
07475 }
07476 
07477 void BERDecodeNull(BufferedTransformation &in)
07478 {
07479         byte b;
07480         if (!in.Get(b) || b != TAG_NULL)
07481                 BERDecodeError();
07482         unsigned int length;
07483         if (!BERLengthDecode(in, length) || length != 0)
07484                 BERDecodeError();
07485 }
07486 
07487 /// ASN Strings
07488 unsigned int DEREncodeOctetString(BufferedTransformation &bt, const byte *str, unsigned int strLen)
07489 {
07490         bt.Put(OCTET_STRING);
07491         unsigned int lengthBytes = DERLengthEncode(bt, strLen);
07492         bt.Put(str, strLen);
07493         return 1+lengthBytes+strLen;
07494 }
07495 
07496 unsigned int DEREncodeOctetString(BufferedTransformation &bt, const SecByteBlock &str)
07497 {
07498         return DEREncodeOctetString(bt, str.begin(), str.size());
07499 }
07500 
07501 void DERReencode(BufferedTransformation &source, BufferedTransformation &dest)
07502 {
07503         byte tag;
07504         source.Peek(tag);
07505         BERGeneralDecoder decoder(source, tag);
07506         DERGeneralEncoder encoder(dest, tag);
07507         if (decoder.IsDefiniteLength())
07508                 decoder.TransferTo(encoder, decoder.RemainingLength());
07509         else
07510         {
07511                 while (!decoder.EndReached())
07512                         DERReencode(decoder, encoder);
07513         }
07514         decoder.MessageEnd();
07515         encoder.MessageEnd();
07516 }
07517 
07518 void OID::EncodeValue(BufferedTransformation &bt, unsigned long v)
07519 {
07520         for (unsigned int i=RoundUpToMultipleOf(STDMAX(7U,BitPrecision(v)), 7U)-7; i != 0; i-=7)
07521                 bt.Put((byte)(0x80 | ((v >> i) & 0x7f)));
07522         bt.Put((byte)(v & 0x7f));
07523 }
07524 
07525 unsigned int OID::DecodeValue(BufferedTransformation &bt, unsigned long &v)
07526 {
07527         byte b;
07528         unsigned int i=0;
07529         v = 0;
07530         while (true)
07531         {
07532                 if (!bt.Get(b))
07533                         BERDecodeError();
07534                 i++;
07535                 v <<= 7;
07536                 v += b & 0x7f;
07537                 if (!(b & 0x80))
07538                         return i;
07539         }
07540 }
07541 
07542 void OID::DEREncode(BufferedTransformation &bt) const
07543 {
07544         assert(m_values.size() >= 2);
07545         ByteQueue temp;
07546         temp.Put(byte(m_values[0] * 40 + m_values[1]));
07547         for (unsigned int i=2; i<m_values.size(); i++)
07548                 EncodeValue(temp, m_values[i]);
07549         bt.Put(OBJECT_IDENTIFIER);
07550         DERLengthEncode(bt, temp.CurrentSize());
07551         temp.TransferTo(bt);
07552 }
07553 
07554 void OID::BERDecode(BufferedTransformation &bt)
07555 {
07556         byte b;
07557         if (!bt.Get(b) || b != OBJECT_IDENTIFIER)
07558                 BERDecodeError();
07559 
07560         unsigned int length;
07561         if (!BERLengthDecode(bt, length) || length < 1)
07562                 BERDecodeError();
07563 
07564         if (!bt.Get(b))
07565                 BERDecodeError();
07566 
07567         length--;
07568         m_values.resize(2);
07569         m_values[0] = b / 40;
07570         m_values[1] = b % 40;
07571 
07572         while (length > 0)
07573         {
07574                 unsigned long v;
07575                 unsigned int valueLen = DecodeValue(bt, v);
07576                 if (valueLen > length)
07577                         BERDecodeError();
07578                 m_values.push_back(v);
07579                 length -= valueLen;
07580         }
07581 }
07582 
07583 void OID::BERDecodeAndCheck(BufferedTransformation &bt) const
07584 {
07585         OID oid(bt);
07586         if (*this != oid)
07587                 BERDecodeError();
07588 }
07589 
07590 BERGeneralDecoder::BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag)
07591         : m_inQueue(inQueue), m_finished(false)
07592 {
07593         Init(asnTag);
07594 }
07595 
07596 BERGeneralDecoder::BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag)
07597         : m_inQueue(inQueue), m_finished(false)
07598 {
07599         Init(asnTag);
07600 }
07601 
07602 void BERGeneralDecoder::Init(byte asnTag)
07603 {
07604         byte b;
07605         if (!m_inQueue.Get(b) || b != asnTag)
07606                 BERDecodeError();
07607 
07608         m_definiteLength = BERLengthDecode(m_inQueue, m_length);
07609         if (!m_definiteLength && !(asnTag & CONSTRUCTED))
07610                 BERDecodeError();       // cannot be primitive and have indefinite length
07611 }
07612 
07613 BERGeneralDecoder::~BERGeneralDecoder()
07614 {
07615         try     // avoid throwing in constructor
07616         {
07617                 if (!m_finished)
07618                         MessageEnd();
07619         }
07620         catch (...)
07621         {
07622         }
07623 }
07624 
07625 bool BERGeneralDecoder::EndReached() const
07626 {
07627         if (m_definiteLength)
07628                 return m_length == 0;
07629         else
07630         {       // check end-of-content octets
07631                 word16 i;
07632                 return (m_inQueue.PeekWord16(i)==2 && i==0);
07633         }
07634 }
07635 
07636 byte BERGeneralDecoder::PeekByte() const
07637 {
07638         byte b;
07639         if (!Peek(b))
07640                 BERDecodeError();
07641         return b;
07642 }
07643 
07644 void BERGeneralDecoder::CheckByte(byte check)
07645 {
07646         byte b;
07647         if (!Get(b) || b != check)
07648                 BERDecodeError();
07649 }
07650 
07651 void BERGeneralDecoder::MessageEnd()
07652 {
07653         m_finished = true;
07654         if (m_definiteLength)
07655         {
07656                 if (m_length != 0)
07657                         BERDecodeError();
07658         }
07659         else
07660         {       // remove end-of-content octets
07661                 word16 i;
07662                 if (m_inQueue.GetWord16(i) != 2 || i != 0)
07663                         BERDecodeError();
07664         }
07665 }
07666 
07667 unsigned int BERGeneralDecoder::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
07668 {
07669         if (m_definiteLength && transferBytes > m_length)
07670                 transferBytes = m_length;
07671         unsigned int blockedBytes = m_inQueue.TransferTo2(target, transferBytes, channel, blocking);
07672         ReduceLength(transferBytes);
07673         return blockedBytes;
07674 }
07675 
07676 unsigned int BERGeneralDecoder::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
07677 {
07678         if (m_definiteLength)
07679                 end = STDMIN((unsigned long)m_length, end);
07680         return m_inQueue.CopyRangeTo2(target, begin, end, channel, blocking);
07681 }
07682 
07683 unsigned int BERGeneralDecoder::ReduceLength(unsigned int delta)
07684 {
07685         if (m_definiteLength)
07686         {
07687                 if (m_length < delta)
07688                         BERDecodeError();
07689                 m_length -= delta;
07690         }
07691         return delta;
07692 }
07693 
07694 DERGeneralEncoder::DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag)
07695         : m_outQueue(outQueue), m_finished(false), m_asnTag(asnTag)
07696 {
07697 }
07698 
07699 DERGeneralEncoder::DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag)
07700         : ByteQueue(), m_outQueue(outQueue), m_finished(false), m_asnTag(asnTag)
07701 {
07702 }
07703 
07704 DERGeneralEncoder::~DERGeneralEncoder()
07705 {
07706         try     // avoid throwing in constructor
07707         {
07708                 if (!m_finished)
07709                         MessageEnd();
07710         }
07711         catch (...)
07712         {
07713         }
07714 }
07715 
07716 void DERGeneralEncoder::MessageEnd()
07717 {
07718         m_finished = true;
07719         unsigned int length = (unsigned int)CurrentSize();
07720         m_outQueue.Put(m_asnTag);
07721         DERLengthEncode(m_outQueue, length);
07722         TransferTo(m_outQueue);
07723 }
07724 
07725 // *************************************************************
07726 
07727 void X509PublicKey::BERDecode(BufferedTransformation &bt)
07728 {
07729         BERSequenceDecoder subjectPublicKeyInfo(bt);
07730                 BERSequenceDecoder algorithm(subjectPublicKeyInfo);
07731                         GetAlgorithmID().BERDecodeAndCheck(algorithm);
07732                         bool parametersPresent = algorithm.EndReached() ? false : BERDecodeAlgorithmParameters(algorithm);
07733                 algorithm.MessageEnd();
07734 
07735                 BERGeneralDecoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING);
07736                         subjectPublicKey.CheckByte(0);  // unused bits
07737                         BERDecodeKey2(subjectPublicKey, parametersPresent, subjectPublicKey.RemainingLength());
07738                 subjectPublicKey.MessageEnd();
07739         subjectPublicKeyInfo.MessageEnd();
07740 }
07741 
07742 void X509PublicKey::DEREncode(BufferedTransformation &bt) const
07743 {
07744         DERSequenceEncoder subjectPublicKeyInfo(bt);
07745 
07746                 DERSequenceEncoder algorithm(subjectPublicKeyInfo);
07747                         GetAlgorithmID().DEREncode(algorithm);
07748                         DEREncodeAlgorithmParameters(algorithm);
07749                 algorithm.MessageEnd();
07750 
07751                 DERGeneralEncoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING);
07752                         subjectPublicKey.Put(0);        // unused bits
07753                         DEREncodeKey(subjectPublicKey);
07754                 subjectPublicKey.MessageEnd();
07755 
07756         subjectPublicKeyInfo.MessageEnd();
07757 }
07758 
07759 void PKCS8PrivateKey::BERDecode(BufferedTransformation &bt)
07760 {
07761         BERSequenceDecoder privateKeyInfo(bt);
07762                 word32 version;
07763                 BERDecodeUnsigned<word32>(privateKeyInfo, version, INTEGER, 0, 0);      // check version
07764 
07765                 BERSequenceDecoder algorithm(privateKeyInfo);
07766                         GetAlgorithmID().BERDecodeAndCheck(algorithm);
07767                         bool parametersPresent = BERDecodeAlgorithmParameters(algorithm);
07768                 algorithm.MessageEnd();
07769 
07770                 BERGeneralDecoder octetString(privateKeyInfo, OCTET_STRING);
07771                         BERDecodeKey2(octetString, parametersPresent, privateKeyInfo.RemainingLength());
07772                 octetString.MessageEnd();
07773 
07774                 if (!privateKeyInfo.EndReached())
07775                         BERDecodeOptionalAttributes(privateKeyInfo);
07776         privateKeyInfo.MessageEnd();
07777 }
07778 
07779 void PKCS8PrivateKey::DEREncode(BufferedTransformation &bt) const
07780 {
07781         DERSequenceEncoder privateKeyInfo(bt);
07782                 DEREncodeUnsigned<word32>(privateKeyInfo, 0);   // version
07783 
07784                 DERSequenceEncoder algorithm(privateKeyInfo);
07785                         GetAlgorithmID().DEREncode(algorithm);
07786                         DEREncodeAlgorithmParameters(algorithm);
07787                 algorithm.MessageEnd();
07788 
07789                 DERGeneralEncoder octetString(privateKeyInfo, OCTET_STRING);
07790                         DEREncodeKey(octetString);
07791                 octetString.MessageEnd();
07792 
07793                 DEREncodeOptionalAttributes(privateKeyInfo);
07794         privateKeyInfo.MessageEnd();
07795 }
07796 
07797 void PKCS8PrivateKey::BERDecodeOptionalAttributes(BufferedTransformation &bt)
07798 {
07799         DERReencode(bt, m_optionalAttributes);
07800 }
07801 
07802 void PKCS8PrivateKey::DEREncodeOptionalAttributes(BufferedTransformation &bt) const
07803 {
07804         m_optionalAttributes.CopyTo(bt);
07805 }
07806 
07807 NAMESPACE_END
07808 
07809 #endif
07810 ////////////////////////////////////////////////////////////////////////////////
07811 
07812 
07813 
07814 ////////////////////////////////////////////////////////////////////////////////
07815 // rsa.cpp - written and placed in the public domain by Wei Dai
07816 
07817 //- #include "pch.h"
07818 //- #include "rsa.h"
07819 //- #include "asn.h"
07820 //- #include "oids.h"
07821 //- #include "modarith.h"
07822 //- #include "nbtheory.h"
07823 //- #include "sha.h"
07824 //- #include "algparam.h"
07825 //- #include "fips140.h"
07826 
07827 #ifndef CRYPTOPP_IMPORTS
07828 
07829 namespace CryptoPP {
07830 
07831 OID RSAFunction::GetAlgorithmID() const
07832 {
07833         return ASN1::rsaEncryption();
07834 }
07835 
07836 void RSAFunction::BERDecodeKey(BufferedTransformation &bt)
07837 {
07838         BERSequenceDecoder seq(bt);
07839                 m_n.BERDecode(seq);
07840                 m_e.BERDecode(seq);
07841         seq.MessageEnd();
07842 }
07843 
07844 void RSAFunction::DEREncodeKey(BufferedTransformation &bt) const
07845 {
07846         DERSequenceEncoder seq(bt);
07847                 m_n.DEREncode(seq);
07848                 m_e.DEREncode(seq);
07849         seq.MessageEnd();
07850 }
07851 
07852 Integer RSAFunction::ApplyFunction(const Integer &x) const
07853 {
07854         DoQuickSanityCheck();
07855         return a_exp_b_mod_c(x, m_e, m_n);
07856 }
07857 
07858 bool RSAFunction::Validate(RandomNumberGenerator& /* rng */, unsigned int /* level */) const
07859 {
07860         bool pass = true;
07861         pass = pass && m_n > Integer::One() && m_n.IsOdd();
07862         pass = pass && m_e > Integer::One() && m_e.IsOdd() && m_e < m_n;
07863         return pass;
07864 }
07865 
07866 bool RSAFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
07867 {
07868         return GetValueHelper(this, name, valueType, pValue).Assignable()
07869                 CRYPTOPP_GET_FUNCTION_ENTRY(Modulus)
07870                 CRYPTOPP_GET_FUNCTION_ENTRY(PublicExponent)
07871                 ;
07872 }
07873 
07874 void RSAFunction::AssignFrom(const NameValuePairs &source)
07875 {
07876         AssignFromHelper(this, source)
07877                 CRYPTOPP_SET_FUNCTION_ENTRY(Modulus)
07878                 CRYPTOPP_SET_FUNCTION_ENTRY(PublicExponent)
07879                 ;
07880 }
07881 
07882 // *****************************************************************************
07883 
07884 class RSAPrimeSelector : public PrimeSelector
07885 {
07886 public:
07887         RSAPrimeSelector(const Integer &e) : m_e(e) {}
07888         virtual ~RSAPrimeSelector() {};
07889 
07890         bool IsAcceptable(const Integer &candidate) const {return RelativelyPrime(m_e, candidate-Integer::One());}
07891         Integer m_e;
07892 };
07893 
07894 void InvertibleRSAFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
07895 {
07896         int modulusSize = 2048;
07897         alg.GetIntValue(Name::ModulusSize(), modulusSize) || alg.GetIntValue(Name::KeySize(), modulusSize);
07898 
07899         if (modulusSize < 16)
07900                 throw InvalidArgument("InvertibleRSAFunction: specified modulus size is too small");
07901 
07902         m_e = alg.GetValueWithDefault(Name::PublicExponent(), Integer(17));
07903 
07904         if (m_e < 3 || m_e.IsEven())
07905                 throw InvalidArgument("InvertibleRSAFunction: invalid public exponent");
07906 
07907         RSAPrimeSelector selector(m_e);
07908         const NameValuePairs &primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize)
07909                 (Name::PointerToPrimeSelector(), selector.GetSelectorPointer());
07910         m_p.GenerateRandom(rng, primeParam);
07911         m_q.GenerateRandom(rng, primeParam);
07912 
07913         m_d = EuclideanMultiplicativeInverse(m_e, LCM(m_p-1, m_q-1));
07914         assert(m_d.IsPositive());
07915 
07916         m_dp = m_d % (m_p-1);
07917         m_dq = m_d % (m_q-1);
07918         m_n = m_p * m_q;
07919         m_u = m_q.InverseMod(m_p);
07920 
07921 }
07922 
07923 void InvertibleRSAFunction::Initialize(RandomNumberGenerator &rng, unsigned int keybits, const Integer &e)
07924 {
07925         GenerateRandom(rng, MakeParameters(Name::ModulusSize(), (int)keybits)(Name::PublicExponent(), e+e.IsEven()));
07926 }
07927 
07928 void InvertibleRSAFunction::Initialize(const Integer &n, const Integer &e, const Integer &d)
07929 {
07930         if (n.IsEven() || e.IsEven() | d.IsEven())
07931                 throw InvalidArgument("InvertibleRSAFunction: input is not a valid RSA private key");
07932 
07933         m_n = n;
07934         m_e = e;
07935         m_d = d;
07936 
07937         Integer r = --(d*e);
07938         unsigned int s = 0;
07939         while (r.IsEven())
07940         {
07941                 r >>= 1;
07942                 s++;
07943         }
07944 
07945         ModularArithmetic modn(n);
07946         for (Integer i = 2; ; ++i)
07947         {
07948                 Integer a = modn.Exponentiate(i, r);
07949                 if (a == 1)
07950                         continue;
07951                 Integer b;
07952                 unsigned int j = 0;
07953                 while (a != n-1)
07954                 {
07955                         b = modn.Square(a);
07956                         if (b == 1)
07957                         {
07958                                 m_p = GCD(a-1, n);
07959                                 m_q = n/m_p;
07960                                 m_dp = m_d % (m_p-1);
07961                                 m_dq = m_d % (m_q-1);
07962                                 m_u = m_q.InverseMod(m_p);
07963                                 return;
07964                         }
07965                         if (++j == s)
07966                                 throw InvalidArgument("InvertibleRSAFunction: input is not a valid RSA private key");
07967                         a = b;
07968                 }
07969         }
07970 }
07971 
07972 void InvertibleRSAFunction::BERDecodeKey(BufferedTransformation &bt)
07973 {
07974         BERSequenceDecoder privateKey(bt);
07975                 word32 version;
07976                 BERDecodeUnsigned<word32>(privateKey, version, INTEGER, 0, 0);  // check version
07977                 m_n.BERDecode(privateKey);
07978                 m_e.BERDecode(privateKey);
07979                 m_d.BERDecode(privateKey);
07980                 m_p.BERDecode(privateKey);
07981                 m_q.BERDecode(privateKey);
07982                 m_dp.BERDecode(privateKey);
07983                 m_dq.BERDecode(privateKey);
07984                 m_u.BERDecode(privateKey);
07985         privateKey.MessageEnd();
07986 }
07987 
07988 void InvertibleRSAFunction::DEREncodeKey(BufferedTransformation &bt) const
07989 {
07990         DERSequenceEncoder privateKey(bt);
07991                 DEREncodeUnsigned<word32>(privateKey, 0);       // version
07992                 m_n.DEREncode(privateKey);
07993                 m_e.DEREncode(privateKey);
07994                 m_d.DEREncode(privateKey);
07995                 m_p.DEREncode(privateKey);
07996                 m_q.DEREncode(privateKey);
07997                 m_dp.DEREncode(privateKey);
07998                 m_dq.DEREncode(privateKey);
07999                 m_u.DEREncode(privateKey);
08000         privateKey.MessageEnd();
08001 }
08002 
08003 Integer InvertibleRSAFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const
08004 {
08005         DoQuickSanityCheck();
08006         ModularArithmetic modn(m_n);
08007         Integer r, rInv;
08008         do {    // do this loop for people using small numbers for testing
08009                 r.Randomize(rng, Integer::One(), m_n - Integer::One());
08010                 rInv = modn.MultiplicativeInverse(r);
08011         } while (rInv.IsZero());
08012         Integer re = modn.Exponentiate(r, m_e);
08013         re = modn.Multiply(re, x);                      // blind
08014         // here we follow the notation of PKCS #1 and let u=q inverse mod p
08015         // but in ModRoot, u=p inverse mod q, so we reverse the order of p and q
08016         Integer y = ModularRoot(re, m_dq, m_dp, m_q, m_p, m_u);
08017         y = modn.Multiply(y, rInv);                             // unblind
08018         if (modn.Exponentiate(y, m_e) != x)             // check
08019                 throw Exception(Exception::OTHER_ERROR, "InvertibleRSAFunction: computational error during private key operation");
08020         return y;
08021 }
08022 
08023 bool InvertibleRSAFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const
08024 {
08025         bool pass = RSAFunction::Validate(rng, level);
08026         pass = pass && m_p > Integer::One() && m_p.IsOdd() && m_p < m_n;
08027         pass = pass && m_q > Integer::One() && m_q.IsOdd() && m_q < m_n;
08028         pass = pass && m_d > Integer::One() && m_d.IsOdd() && m_d < m_n;
08029         pass = pass && m_dp > Integer::One() && m_dp.IsOdd() && m_dp < m_p;
08030         pass = pass && m_dq > Integer::One() && m_dq.IsOdd() && m_dq < m_q;
08031         pass = pass && m_u.IsPositive() && m_u < m_p;
08032         if (level >= 1)
08033         {
08034                 pass = pass && m_p * m_q == m_n;
08035                 pass = pass && m_e*m_d % LCM(m_p-1, m_q-1) == 1;
08036                 pass = pass && m_dp == m_d%(m_p-1) && m_dq == m_d%(m_q-1);
08037                 pass = pass && m_u * m_q % m_p == 1;
08038         }
08039         if (level >= 2)
08040                 pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2);
08041         return pass;
08042 }
08043 
08044 bool InvertibleRSAFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
08045 {
08046         return GetValueHelper<RSAFunction>(this, name, valueType, pValue).Assignable()
08047                 CRYPTOPP_GET_FUNCTION_ENTRY(Prime1)
08048                 CRYPTOPP_GET_FUNCTION_ENTRY(Prime2)
08049                 CRYPTOPP_GET_FUNCTION_ENTRY(PrivateExponent)
08050                 CRYPTOPP_GET_FUNCTION_ENTRY(ModPrime1PrivateExponent)
08051                 CRYPTOPP_GET_FUNCTION_ENTRY(ModPrime2PrivateExponent)
08052                 CRYPTOPP_GET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1)
08053                 ;
08054 }
08055 
08056 void InvertibleRSAFunction::AssignFrom(const NameValuePairs &source)
08057 {
08058         AssignFromHelper<RSAFunction>(this, source)
08059                 CRYPTOPP_SET_FUNCTION_ENTRY(Prime1)
08060                 CRYPTOPP_SET_FUNCTION_ENTRY(Prime2)
08061                 CRYPTOPP_SET_FUNCTION_ENTRY(PrivateExponent)
08062                 CRYPTOPP_SET_FUNCTION_ENTRY(ModPrime1PrivateExponent)
08063                 CRYPTOPP_SET_FUNCTION_ENTRY(ModPrime2PrivateExponent)
08064                 CRYPTOPP_SET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1)
08065                 ;
08066 }
08067 
08068 NAMESPACE_END
08069 
08070 #endif
08071 ////////////////////////////////////////////////////////////////////////////////
08072 
08073 
08074 
08075 ////////////////////////////////////////////////////////////////////////////////
08076 // basecode.cpp - written and placed in the public domain by Wei Dai
08077 
08078 //- #include "pch.h"
08079 
08080 #ifndef CRYPTOPP_IMPORTS
08081 
08082 //- #include "basecode.h"
08083 //- #include "fltrimpl.h"
08084 #include <ctype.h>
08085 
08086 namespace CryptoPP {
08087 
08088 void BaseN_Encoder::IsolatedInitialize(const NameValuePairs &parameters)
08089 {
08090         parameters.GetRequiredParameter("BaseN_Encoder", Name::EncodingLookupArray(), m_alphabet);
08091 
08092         parameters.GetRequiredIntParameter("BaseN_Encoder", Name::Log2Base(), m_bitsPerChar);
08093         if (m_bitsPerChar <= 0 || m_bitsPerChar >= 8)
08094                 throw InvalidArgument("BaseN_Encoder: Log2Base must be between 1 and 7 inclusive");
08095 
08096         byte padding;
08097         bool pad;
08098         if (parameters.GetValue(Name::PaddingByte(), padding))
08099                 pad = parameters.GetValueWithDefault(Name::Pad(), true);
08100         else
08101                 pad = false;
08102         m_padding = pad ? padding : -1;
08103 
08104         m_bytePos = m_bitPos = 0;
08105 
08106         int i = 8;
08107         while (i%m_bitsPerChar != 0)
08108                 i += 8;
08109         m_outputBlockSize = i/m_bitsPerChar;
08110 
08111         m_outBuf.New(m_outputBlockSize);
08112 }
08113 
08114 unsigned int BaseN_Encoder::Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
08115 {
08116         FILTER_BEGIN;
08117         while (m_inputPosition < length)
08118         {
08119                 if (m_bytePos == 0)
08120                         memset(m_outBuf, 0, m_outputBlockSize);
08121 
08122                 {
08123                 unsigned int b = begin[m_inputPosition++], bitsLeftInSource = 8;
08124                 while (true)
08125                 {
08126                         assert(m_bitPos < m_bitsPerChar);
08127                         unsigned int bitsLeftInTarget = m_bitsPerChar-m_bitPos;
08128                         m_outBuf[m_bytePos] |= b >> (8-bitsLeftInTarget);
08129                         if (bitsLeftInSource >= bitsLeftInTarget)
08130                         {
08131                                 m_bitPos = 0;
08132                                 ++m_bytePos;
08133                                 bitsLeftInSource -= bitsLeftInTarget;
08134                                 if (bitsLeftInSource == 0)
08135                                         break;
08136                                 b <<= bitsLeftInTarget;
08137                                 b &= 0xff;
08138                         }
08139                         else
08140                         {
08141                                 m_bitPos += bitsLeftInSource;
08142                                 break;
08143                         }
08144                 }
08145                 }
08146 
08147                 assert(m_bytePos <= m_outputBlockSize);
08148                 if (m_bytePos == m_outputBlockSize)
08149                 {
08150                         int i;
08151                         for (i=0; i<m_bytePos; i++)
08152                         {
08153                                 assert(m_outBuf[i] < (1 << m_bitsPerChar));
08154                                 m_outBuf[i] = m_alphabet[m_outBuf[i]];
08155                         }
08156                         FILTER_OUTPUT(1, m_outBuf, m_outputBlockSize, 0);
08157 
08158                         m_bytePos = m_bitPos = 0;
08159                 }
08160         }
08161         if (messageEnd)
08162         {
08163                 if (m_bitPos > 0)
08164                         ++m_bytePos;
08165 
08166                 int i;
08167                 for (i=0; i<m_bytePos; i++)
08168                         m_outBuf[i] = m_alphabet[m_outBuf[i]];
08169 
08170                 if (m_padding != -1 && m_bytePos > 0)
08171                 {
08172                         memset(m_outBuf+m_bytePos, m_padding, m_outputBlockSize-m_bytePos);
08173                         m_bytePos = m_outputBlockSize;
08174                 }
08175                 FILTER_OUTPUT(2, m_outBuf, m_bytePos, messageEnd);
08176                 m_bytePos = m_bitPos = 0;
08177         }
08178         FILTER_END_NO_MESSAGE_END;
08179 }
08180 
08181 void BaseN_Decoder::IsolatedInitialize(const NameValuePairs &parameters)
08182 {
08183         parameters.GetRequiredParameter("BaseN_Decoder", Name::DecodingLookupArray(), m_lookup);
08184 
08185         parameters.GetRequiredIntParameter("BaseN_Decoder", Name::Log2Base(), m_bitsPerChar);
08186         if (m_bitsPerChar <= 0 || m_bitsPerChar >= 8)
08187                 throw InvalidArgument("BaseN_Decoder: Log2Base must be between 1 and 7 inclusive");
08188 
08189         m_bytePos = m_bitPos = 0;
08190 
08191         int i = m_bitsPerChar;
08192         while (i%8 != 0)
08193                 i += m_bitsPerChar;
08194         m_outputBlockSize = i/8;
08195 
08196         m_outBuf.New(m_outputBlockSize);
08197 }
08198 
08199 unsigned int BaseN_Decoder::Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
08200 {
08201         FILTER_BEGIN;
08202         while (m_inputPosition < length)
08203         {
08204                 unsigned int value;
08205                 value = m_lookup[begin[m_inputPosition++]];
08206                 if (value >= 256)
08207                         continue;
08208 
08209                 if (m_bytePos == 0 && m_bitPos == 0)
08210                         memset(m_outBuf, 0, m_outputBlockSize);
08211 
08212                 {
08213                         int newBitPos = m_bitPos + m_bitsPerChar;
08214                         if (newBitPos <= 8)
08215                                 m_outBuf[m_bytePos] |= value << (8-newBitPos);
08216                         else
08217                         {
08218                                 m_outBuf[m_bytePos] |= value >> (newBitPos-8);
08219                                 m_outBuf[m_bytePos+1] |= value << (16-newBitPos);
08220                         }
08221 
08222                         m_bitPos = newBitPos;
08223                         while (m_bitPos >= 8)
08224                         {
08225                                 m_bitPos -= 8;
08226                                 ++m_bytePos;
08227                         }
08228                 }
08229 
08230                 if (m_bytePos == m_outputBlockSize)
08231                 {
08232                         FILTER_OUTPUT(1, m_outBuf, m_outputBlockSize, 0);
08233                         m_bytePos = m_bitPos = 0;
08234                 }
08235         }
08236         if (messageEnd)
08237         {
08238                 FILTER_OUTPUT(2, m_outBuf, m_bytePos, messageEnd);
08239                 m_bytePos = m_bitPos = 0;
08240         }
08241         FILTER_END_NO_MESSAGE_END;
08242 }
08243 
08244 void BaseN_Decoder::InitializeDecodingLookupArray(int *lookup, const byte *alphabet, unsigned int base, bool caseInsensitive)
08245 {
08246         std::fill(lookup, lookup+256, -1);
08247 
08248         for (unsigned int i=0; i<base; i++)
08249         {
08250                 if (caseInsensitive && isalpha(alphabet[i]))
08251                 {
08252                         assert(lookup[toupper(alphabet[i])] == -1);
08253                         lookup[toupper(alphabet[i])] = i;
08254                         assert(lookup[tolower(alphabet[i])] == -1);
08255                         lookup[tolower(alphabet[i])] = i;
08256                 }
08257                 else
08258                 {
08259                         assert(lookup[alphabet[i]] == -1);
08260                         lookup[alphabet[i]] = i;
08261                 }
08262         }
08263 }
08264 
08265 void Grouper::IsolatedInitialize(const NameValuePairs &parameters)
08266 {
08267         m_groupSize = parameters.GetIntValueWithDefault(Name::GroupSize(), 0);
08268         ConstByteArrayParameter separator, terminator;
08269         if (m_groupSize)
08270                 parameters.GetRequiredParameter("Grouper", Name::Separator(), separator);
08271         else
08272                 parameters.GetValue(Name::Separator(), separator);
08273         parameters.GetValue(Name::Terminator(), terminator);
08274 
08275         m_separator.Assign(separator.begin(), separator.size());
08276         m_terminator.Assign(terminator.begin(), terminator.size());
08277         m_counter = 0;
08278 }
08279 
08280 unsigned int Grouper::Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
08281 {
08282         FILTER_BEGIN;
08283         if (m_groupSize)
08284         {
08285                 while (m_inputPosition < length)
08286                 {
08287                         if (m_counter == m_groupSize)
08288                         {
08289                                 FILTER_OUTPUT(1, m_separator, m_separator.size(), 0);
08290                                 m_counter = 0;
08291                         }
08292 
08293                         unsigned int len;
08294                         FILTER_OUTPUT2(2, len = STDMIN(length-m_inputPosition, m_groupSize-m_counter),
08295                                 begin+m_inputPosition, len, 0);
08296                         m_inputPosition += len;
08297                         m_counter += len;
08298                 }
08299         }
08300         else
08301                 FILTER_OUTPUT(3, begin, length, 0);
08302 
08303         if (messageEnd)
08304         {
08305                 FILTER_OUTPUT(4, m_terminator, m_terminator.size(), messageEnd);
08306                 m_counter = 0;
08307         }
08308         FILTER_END_NO_MESSAGE_END
08309 }
08310 
08311 NAMESPACE_END
08312 
08313 #endif
08314 ////////////////////////////////////////////////////////////////////////////////
08315 
08316 
08317 
08318 ////////////////////////////////////////////////////////////////////////////////
08319 // base64.cpp - written and placed in the public domain by Wei Dai
08320 
08321 //- #include "pch.h"
08322 //- #include "base64.h"
08323 
08324 namespace CryptoPP {
08325 
08326 static const byte s_vec[] =
08327                 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
08328 static const byte s_padding = '=';
08329 
08330 void Base64Encoder::IsolatedInitialize(const NameValuePairs &parameters)
08331 {
08332         bool insertLineBreaks = parameters.GetValueWithDefault(Name::InsertLineBreaks(), true);
08333         int maxLineLength = parameters.GetIntValueWithDefault(Name::MaxLineLength(), 72);
08334 
08335         const char *lineBreak = insertLineBreaks ? "\n" : "";
08336 
08337         m_filter->Initialize(CombinedNameValuePairs(
08338                 parameters,
08339                 MakeParameters(Name::EncodingLookupArray(), &s_vec[0], false)
08340                         (Name::PaddingByte(), s_padding)
08341                         (Name::GroupSize(), insertLineBreaks ? maxLineLength : 0)
08342                         (Name::Separator(), ConstByteArrayParameter(lineBreak))
08343                         (Name::Terminator(), ConstByteArrayParameter(lineBreak))
08344                         (Name::Log2Base(), 6, true)));
08345 }
08346 
08347 const int *Base64Decoder::GetDecodingLookupArray()
08348 {
08349         static bool s_initialized = false;
08350         static int s_array[256];
08351 
08352         if (!s_initialized)
08353         {
08354                 InitializeDecodingLookupArray(s_array, s_vec, 64, false);
08355                 s_initialized = true;
08356         }
08357         return s_array;
08358 }
08359 
08360 NAMESPACE_END
08361 ////////////////////////////////////////////////////////////////////////////////
08362 
08363 
08364 
08365 ////////////////////////////////////////////////////////////////////////////////
08366 // files.cpp - written and placed in the public domain by Wei Dai
08367 
08368 //- #include "pch.h"
08369 
08370 #ifndef CRYPTOPP_IMPORTS
08371 
08372 //- #include "files.h"
08373 
08374 namespace CryptoPP {
08375 
08376 using namespace std;
08377 
08378 void FileStore::StoreInitialize(const NameValuePairs &parameters)
08379 {
08380         m_file.reset(new std::ifstream);
08381         const char *fileName;
08382         if (parameters.GetValue(Name::InputFileName(), fileName))
08383         {
08384                 ios::openmode binary = parameters.GetValueWithDefault(Name::InputBinaryMode(), true) ? ios::binary : ios::openmode(0);
08385                 m_file->open(fileName, ios::in | binary);
08386                 if (!*m_file)
08387                         throw OpenErr(fileName);
08388                 m_stream = m_file.get();
08389         }
08390         else
08391         {
08392                 m_stream = NULL;
08393                 parameters.GetValue(Name::InputStreamPointer(), m_stream);
08394         }
08395         m_waiting = false;
08396 }
08397 
08398 unsigned long FileStore::MaxRetrievable() const
08399 {
08400         if (!m_stream)
08401                 return 0;
08402 
08403         streampos current = m_stream->tellg();
08404         streampos end = m_stream->seekg(0, ios::end).tellg();
08405         m_stream->seekg(current);
08406         return end-current;
08407 }
08408 
08409 unsigned int FileStore::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
08410 {
08411         if (!m_stream)
08412         {
08413                 transferBytes = 0;
08414                 return 0;
08415         }
08416 
08417         unsigned long size=transferBytes;
08418         transferBytes = 0;
08419 
08420         if (m_waiting)
08421                 goto output;
08422 
08423         while (size && m_stream->good())
08424         {
08425                 {
08426                 unsigned int spaceSize = 1024;
08427                 m_space = HelpCreatePutSpace(target, channel, 1, (unsigned int)STDMIN(size, (unsigned long)UINT_MAX), spaceSize);
08428 
08429                 m_stream->read((char *)m_space, STDMIN(size, (unsigned long)spaceSize));
08430                 }
08431                 m_len = m_stream->gcount();
08432                 unsigned int blockedBytes;
08433 output:
08434                 blockedBytes = target.ChannelPutModifiable2(channel, m_space, m_len, 0, blocking);
08435                 m_waiting = blockedBytes > 0;
08436                 if (m_waiting)
08437                         return blockedBytes;
08438                 size -= m_len;
08439                 transferBytes += m_len;
08440         }
08441 
08442         if (!m_stream->good() && !m_stream->eof())
08443                 throw ReadErr();
08444 
08445         return 0;
08446 }
08447 
08448 unsigned int FileStore::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
08449 {
08450         if (!m_stream)
08451                 return 0;
08452 
08453         if (begin == 0 && end == 1)
08454         {
08455                 int result = m_stream->peek();
08456                 if (result == EOF)      // GCC workaround: 2.95.2 doesn't have char_traits<char>::eof()
08457                         return 0;
08458                 else
08459                 {
08460                         unsigned int blockedBytes = target.ChannelPut(channel, byte(result), blocking);
08461                         begin += 1-blockedBytes;
08462                         return blockedBytes;
08463                 }
08464         }
08465 
08466         // TODO: figure out what happens on cin
08467         streampos current = m_stream->tellg();
08468         streampos endPosition = m_stream->seekg(0, ios::end).tellg();
08469         streampos newPosition = current + (streamoff)begin;
08470 
08471         if (newPosition >= endPosition)
08472         {
08473                 m_stream->seekg(current);
08474                 return 0;       // don't try to seek beyond the end of file
08475         }
08476         m_stream->seekg(newPosition);
08477         try
08478         {
08479                 assert(!m_waiting);
08480                 unsigned long copyMax = end-begin;
08481                 unsigned int blockedBytes = const_cast<FileStore *>(this)->TransferTo2(target, copyMax, channel, blocking);
08482                 begin += copyMax;
08483                 if (blockedBytes)
08484                 {
08485                         const_cast<FileStore *>(this)->m_waiting = false;
08486                         return blockedBytes;
08487                 }
08488         }
08489         catch(...)
08490         {
08491                 m_stream->clear();
08492                 m_stream->seekg(current);
08493                 throw;
08494         }
08495         m_stream->clear();
08496         m_stream->seekg(current);
08497 
08498         return 0;
08499 }
08500 
08501 unsigned long FileStore::Skip(unsigned long skipMax)
08502 {
08503         unsigned long oldPos = m_stream->tellg();
08504         m_stream->seekg(skipMax, ios::cur);
08505         return (unsigned long)m_stream->tellg() - oldPos;
08506 }
08507 
08508 void FileSink::IsolatedInitialize(const NameValuePairs &parameters)
08509 {
08510         m_file.reset(new std::ofstream);
08511         const char *fileName;
08512         if (parameters.GetValue(Name::OutputFileName(), fileName))
08513         {
08514                 ios::openmode binary = parameters.GetValueWithDefault(Name::OutputBinaryMode(), true) ? ios::binary : ios::openmode(0);
08515                 m_file->open(fileName, ios::out | ios::trunc | binary);
08516                 if (!*m_file)
08517                         throw OpenErr(fileName);
08518                 m_stream = m_file.get();
08519         }
08520         else
08521         {
08522                 m_stream = NULL;
08523                 parameters.GetValue(Name::OutputStreamPointer(), m_stream);
08524         }
08525 }
08526 
08527 bool FileSink::IsolatedFlush(bool /* hardFlush */, bool /* blocking */)
08528 {
08529         if (!m_stream)
08530                 throw Err("FileSink: output stream not opened");
08531 
08532         m_stream->flush();
08533         if (!m_stream->good())
08534                 throw WriteErr();
08535 
08536         return false;
08537 }
08538 
08539 unsigned int FileSink::Put2(const byte *inString, unsigned int length, int messageEnd, bool /* blocking */)
08540 {
08541         if (!m_stream)
08542                 throw Err("FileSink: output stream not opened");
08543 
08544         m_stream->write((const char *)inString, length);
08545 
08546         if (messageEnd)
08547                 m_stream->flush();
08548 
08549         if (!m_stream->good())
08550                 throw WriteErr();
08551 
08552         return 0;
08553 }
08554 
08555 NAMESPACE_END
08556 
08557 #endif
08558 ////////////////////////////////////////////////////////////////////////////////
08559 
08560 
08561 
08562 ////////////////////////////////////////////////////////////////////////////////
08563  // mdc.h - written and placed in the public domain by Wei Dai
08564 
08565 #ifndef CRYPTOPP_MDC_H
08566 #define CRYPTOPP_MDC_H
08567 
08568 /** \file
08569 */
08570 
08571 //- #include "seckey.h"
08572 //- #include "misc.h"
08573 
08574 namespace CryptoPP {
08575 
08576 //! _
08577 template <class T>
08578 struct MDC_Info : public FixedBlockSize<T::DIGESTSIZE>, public FixedKeyLength<T::BLOCKSIZE>
08579 {
08580         static std::string StaticAlgorithmName() {return std::string("MDC/")+T::StaticAlgorithmName();}
08581 };
08582 
08583 //! <a href="http://www.weidai.com/scan-mirror/cs.html#MDC">MDC</a>
08584 /*! a construction by Peter Gutmann to turn an iterated hash function into a PRF */
08585 template <class T>
08586 class MDC : public MDC_Info<T>
08587 {
08588         class CRYPTOPP_NO_VTABLE Enc : public BlockCipherImpl<MDC_Info<T> >
08589         {
08590                 typedef typename T::HashWordType HashWordType;
08591 
08592         public:
08593                 void UncheckedSetKey(CipherDir direction, const byte *userKey, unsigned int length)
08594                 {
08595                         assert(direction == ENCRYPTION);
08596                         this->AssertValidKeyLength(length);
08597                         memcpy(Key(), userKey, this->KEYLENGTH);
08598                         T::CorrectEndianess(Key(), Key(), this->KEYLENGTH);
08599                 }
08600 
08601                 void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
08602                 {
08603                         T::CorrectEndianess(Buffer(), (HashWordType *)inBlock, this->BLOCKSIZE);
08604                         T::Transform(Buffer(), Key());
08605                         if (xorBlock)
08606                         {
08607                                 T::CorrectEndianess(Buffer(), Buffer(), this->BLOCKSIZE);
08608                                 xorbuf(outBlock, xorBlock, m_buffer, this->BLOCKSIZE);
08609                         }
08610                         else
08611                                 T::CorrectEndianess((HashWordType *)outBlock, Buffer(), this->BLOCKSIZE);
08612                 }
08613 
08614                 bool IsPermutation() const {return false;}
08615 
08616                 unsigned int GetAlignment() const {return sizeof(HashWordType);}
08617 
08618         private:
08619                 HashWordType *Key() {return (HashWordType *)m_key.data();}
08620                 const HashWordType *Key() const {return (const HashWordType *)m_key.data();}
08621                 HashWordType *Buffer() const {return (HashWordType *)m_buffer.data();}
08622 
08623                 // VC60 workaround: bug triggered if using FixedSizeAllocatorWithCleanup
08624                 FixedSizeSecBlock<byte, MDC_Info<T>::KEYLENGTH, AllocatorWithCleanup<byte> > m_key;
08625                 mutable FixedSizeSecBlock<byte, MDC_Info<T>::BLOCKSIZE, AllocatorWithCleanup<byte> > m_buffer;
08626         };
08627 
08628 public:
08629         //! use BlockCipher interface
08630         typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption;
08631 };
08632 
08633 NAMESPACE_END
08634 
08635 #endif
08636 ////////////////////////////////////////////////////////////////////////////////
08637 
08638 
08639 
08640 ////////////////////////////////////////////////////////////////////////////////
08641 /*! \file
08642         This file contains helper classes for implementing stream ciphers.
08643 
08644         All this infrastructure may look very complex compared to what's in Crypto++ 4.x,
08645         but stream ciphers implementations now support a lot of new functionality,
08646         including better performance (minimizing copying), resetting of keys and IVs, and methods to
08647         query which features are supported by a cipher.
08648 
08649         Here's an explanation of these classes. The word "policy" is used here to mean a class with a
08650         set of methods that must be implemented by individual stream cipher implementations.
08651         This is usually much simpler than the full stream cipher API, which is implemented by
08652         either AdditiveCipherTemplate or CFB_CipherTemplate using the policy. So for example, an
08653         implementation of SEAL only needs to implement the AdditiveCipherAbstractPolicy interface
08654         (since it's an additive cipher, i.e., it xors a keystream into the plaintext).
08655         See this line in seal.h:
08656 
08657         typedef SymmetricCipherFinal<ConcretePolicyHolder<SEAL_Policy<B>, AdditiveCipherTemplate<> > > Encryption;
08658 
08659         AdditiveCipherTemplate and CFB_CipherTemplate are designed so that they don't need
08660         to take a policy class as a template parameter (although this is allowed), so that
08661         their code is not duplicated for each new cipher. Instead they each
08662         get a reference to an abstract policy interface by calling AccessPolicy() on itself, so
08663         AccessPolicy() must be overriden to return the actual policy reference. This is done
08664         by the ConceretePolicyHolder class. Finally, SymmetricCipherFinal implements the constructors and
08665         other functions that must be implemented by the most derived class.
08666 */
08667 
08668 #ifndef CRYPTOPP_STRCIPHR_H
08669 #define CRYPTOPP_STRCIPHR_H
08670 
08671 //- #include "seckey.h"
08672 //- #include "secblock.h"
08673 //- #include "argnames.h"
08674 
08675 namespace CryptoPP {
08676 
08677 template <class POLICY_INTERFACE, class BASE = Empty>
08678 class CRYPTOPP_NO_VTABLE AbstractPolicyHolder : public BASE
08679 {
08680 public:
08681         typedef POLICY_INTERFACE PolicyInterface;
08682 
08683 protected:
08684         virtual const POLICY_INTERFACE & GetPolicy() const =0;
08685         virtual POLICY_INTERFACE & AccessPolicy() =0;
08686 };
08687 
08688 template <class POLICY, class BASE, class POLICY_INTERFACE = CPP_TYPENAME BASE::PolicyInterface>
08689 class ConcretePolicyHolder : public BASE, protected POLICY
08690 {
08691 protected:
08692         const POLICY_INTERFACE & GetPolicy() const {return *this;}
08693         POLICY_INTERFACE & AccessPolicy() {return *this;}
08694 };
08695 
08696 enum KeystreamOperation {WRITE_KEYSTREAM, XOR_KEYSTREAM, XOR_KEYSTREAM_INPLACE};
08697 
08698 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CFB_CipherAbstractPolicy
08699 {
08700 public:
08701         virtual ~CFB_CipherAbstractPolicy() {}
08702 
08703         virtual unsigned int GetAlignment() const =0;
08704         virtual unsigned int GetBytesPerIteration() const =0;
08705         virtual byte * GetRegisterBegin() =0;
08706         virtual void TransformRegister() =0;
08707         virtual bool CanIterate() const {return false;}
08708         virtual void Iterate(byte* /* output */, const byte* /* input */, CipherDir /* dir */, unsigned int /* iterationCount */) {assert(false);}
08709         virtual void CipherSetKey(const NameValuePairs &params, const byte *key, unsigned int length) =0;
08710         virtual void CipherResynchronize(const byte* /* iv */) {throw NotImplemented("StreamTransformation: this object doesn't support resynchronization");}
08711 };
08712 
08713 template <class BASE>
08714 class CRYPTOPP_NO_VTABLE CFB_CipherTemplate : public BASE
08715 {
08716 public:
08717         void ProcessData(byte *outString, const byte *inString, unsigned int length);
08718         void Resynchronize(const byte *iv);
08719         unsigned int OptimalBlockSize() const {return this->GetPolicy().GetBytesPerIteration();}
08720         unsigned int GetOptimalNextBlockSize() const {return m_leftOver;}
08721         unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();}
08722         bool IsRandomAccess() const {return false;}
08723         bool IsSelfInverting() const {return false;}
08724 
08725         typedef typename BASE::PolicyInterface PolicyInterface;
08726 
08727 protected:
08728         virtual void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length) =0;
08729 
08730         void UncheckedSetKey(const NameValuePairs &params, const byte *key, unsigned int length, const byte *iv);
08731 
08732         unsigned int m_leftOver;
08733 };
08734 
08735 template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
08736 class CRYPTOPP_NO_VTABLE CFB_EncryptionTemplate : public CFB_CipherTemplate<BASE>
08737 {
08738         bool IsForwardTransformation() const {return true;}
08739         void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length);
08740 };
08741 
08742 template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
08743 class CRYPTOPP_NO_VTABLE CFB_DecryptionTemplate : public CFB_CipherTemplate<BASE>
08744 {
08745         bool IsForwardTransformation() const {return false;}
08746         void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length);
08747 };
08748 
08749 template <class BASE>
08750 void CFB_CipherTemplate<BASE>::UncheckedSetKey(const NameValuePairs &params, const byte *key, unsigned int length, const byte *iv)
08751 {
08752         PolicyInterface &policy = this->AccessPolicy();
08753         policy.CipherSetKey(params, key, length);
08754 
08755         if (this->IsResynchronizable())
08756                 policy.CipherResynchronize(iv);
08757 
08758         m_leftOver = policy.GetBytesPerIteration();
08759 }
08760 
08761 NAMESPACE_END
08762 
08763 #endif
08764 ////////////////////////////////////////////////////////////////////////////////
08765 
08766 
08767 
08768 ////////////////////////////////////////////////////////////////////////////////
08769 // strciphr.cpp - written and placed in the public domain by Wei Dai
08770 
08771 //- #include "pch.h"
08772 
08773 #ifndef CRYPTOPP_IMPORTS
08774 
08775 //- #include "strciphr.h"
08776 
08777 namespace CryptoPP {
08778 
08779 template <class BASE>
08780 void CFB_CipherTemplate<BASE>::Resynchronize(const byte *iv)
08781 {
08782         PolicyInterface &policy = this->AccessPolicy();
08783         policy.CipherResynchronize(iv);
08784         m_leftOver = policy.GetBytesPerIteration();
08785 }
08786 
08787 template <class BASE>
08788 void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString, unsigned int length)
08789 {
08790         assert(length % this->MandatoryBlockSize() == 0);
08791 
08792         PolicyInterface &policy = this->AccessPolicy();
08793         unsigned int bytesPerIteration = policy.GetBytesPerIteration();
08794         unsigned int alignment = policy.GetAlignment();
08795         byte *reg = policy.GetRegisterBegin();
08796 
08797         if (m_leftOver)
08798         {
08799                 unsigned int len = STDMIN(m_leftOver, length);
08800                 CombineMessageAndShiftRegister(outString, reg + bytesPerIteration - m_leftOver, inString, len);
08801                 m_leftOver -= len;
08802                 length -= len;
08803                 inString += len;
08804                 outString += len;
08805         }
08806 
08807         if (!length)
08808                 return;
08809 
08810         assert(m_leftOver == 0);
08811 
08812         if (policy.CanIterate() && length >= bytesPerIteration && IsAlignedOn(outString, alignment))
08813         {
08814                 if (IsAlignedOn(inString, alignment))
08815                         policy.Iterate(outString, inString, GetCipherDir(*this), length / bytesPerIteration);
08816                 else
08817                 {
08818                         memcpy(outString, inString, length);
08819                         policy.Iterate(outString, outString, GetCipherDir(*this), length / bytesPerIteration);
08820                 }
08821                 inString += length - length % bytesPerIteration;
08822                 outString += length - length % bytesPerIteration;
08823                 length %= bytesPerIteration;
08824         }
08825 
08826         while (length >= bytesPerIteration)
08827         {
08828                 policy.TransformRegister();
08829                 CombineMessageAndShiftRegister(outString, reg, inString, bytesPerIteration);
08830                 length -= bytesPerIteration;
08831                 inString += bytesPerIteration;
08832                 outString += bytesPerIteration;
08833         }
08834 
08835         if (length > 0)
08836         {
08837                 policy.TransformRegister();
08838                 CombineMessageAndShiftRegister(outString, reg, inString, length);
08839                 m_leftOver = bytesPerIteration - length;
08840         }
08841 }
08842 
08843 template <class BASE>
08844 void CFB_EncryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length)
08845 {
08846         xorbuf(reg, message, length);
08847         memcpy(output, reg, length);
08848 }
08849 
08850 template <class BASE>
08851 void CFB_DecryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length)
08852 {
08853         for (unsigned int i=0; i<length; i++)
08854         {
08855                 byte b = message[i];
08856                 output[i] = reg[i] ^ b;
08857                 reg[i] = b;
08858         }
08859 }
08860 
08861 NAMESPACE_END
08862 
08863 #endif
08864 ////////////////////////////////////////////////////////////////////////////////
08865 
08866 
08867 
08868 ////////////////////////////////////////////////////////////////////////////////
08869 #ifndef CRYPTOPP_MODES_H
08870 #define CRYPTOPP_MODES_H
08871 
08872 /*! \file
08873 */
08874 
08875 //- #include "cryptlib.h"
08876 //- #include "secblock.h"
08877 //- #include "misc.h"
08878 //- #include "strciphr.h"
08879 //- #include "argnames.h"
08880 //- #include "algparam.h"
08881 
08882 namespace CryptoPP {
08883 
08884 //! Cipher mode documentation. See NIST SP 800-38A for definitions of these modes.
08885 
08886 /*! Each class derived from this one defines two types, Encryption and Decryption,
08887         both of which implement the SymmetricCipher interface.
08888         For each mode there are two classes, one of which is a template class,
08889         and the other one has a name that ends in "_ExternalCipher".
08890         The "external cipher" mode objects hold a reference to the underlying block cipher,
08891         instead of holding an instance of it. The reference must be passed in to the constructor.
08892         For the "cipher holder" classes, the CIPHER template parameter should be a class
08893         derived from BlockCipherDocumentation, for example DES or AES.
08894 */
08895 struct CipherModeDocumentation : public SymmetricCipherDocumentation
08896 {
08897 };
08898 
08899 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CipherModeBase : public SymmetricCipher
08900 {
08901 public:
08902         unsigned int MinKeyLength() const {return m_cipher->MinKeyLength();}
08903         unsigned int MaxKeyLength() const {return m_cipher->MaxKeyLength();}
08904         unsigned int DefaultKeyLength() const {return m_cipher->DefaultKeyLength();}
08905         unsigned int GetValidKeyLength(unsigned int n) const {return m_cipher->GetValidKeyLength(n);}
08906         bool IsValidKeyLength(unsigned int n) const {return m_cipher->IsValidKeyLength(n);}
08907 
08908         void SetKey(const byte *key, unsigned int length, const NameValuePairs &params = g_nullNameValuePairs);
08909 
08910         unsigned int OptimalDataAlignment() const {return BlockSize();}
08911 
08912         unsigned int IVSize() const {return BlockSize();}
08913         void GetNextIV(byte *IV);
08914         virtual IV_Requirement IVRequirement() const =0;
08915 
08916 protected:
08917         inline unsigned int BlockSize() const {assert(m_register.size() > 0); return m_register.size();}
08918         virtual void SetFeedbackSize(unsigned int feedbackSize)
08919         {
08920                 if (!(feedbackSize == 0 || feedbackSize == BlockSize()))
08921                         throw InvalidArgument("CipherModeBase: feedback size cannot be specified for this cipher mode");
08922         }
08923         virtual void ResizeBuffers()
08924         {
08925                 m_register.New(m_cipher->BlockSize());
08926         }
08927         virtual void UncheckedSetKey(const NameValuePairs &params, const byte *key, unsigned int length, const byte *iv) =0;
08928 
08929         BlockCipher *m_cipher;
08930         SecByteBlock m_register;
08931 };
08932 
08933 template <class POLICY_INTERFACE>
08934 class CRYPTOPP_NO_VTABLE ModePolicyCommonTemplate : public CipherModeBase, public POLICY_INTERFACE
08935 {
08936         unsigned int GetAlignment() const {return m_cipher->BlockAlignment();}
08937         void CipherSetKey(const NameValuePairs &params, const byte *key, unsigned int length);
08938 };
08939 
08940 template <class POLICY_INTERFACE>
08941 void ModePolicyCommonTemplate<POLICY_INTERFACE>::CipherSetKey(const NameValuePairs &params, const byte *key, unsigned int length)
08942 {
08943         m_cipher->SetKey(key, length, params);
08944         ResizeBuffers();
08945         int feedbackSize = params.GetIntValueWithDefault(Name::FeedbackSize(), 0);
08946         SetFeedbackSize(feedbackSize);
08947 }
08948 
08949 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CFB_ModePolicy : public ModePolicyCommonTemplate<CFB_CipherAbstractPolicy>
08950 {
08951 public:
08952         IV_Requirement IVRequirement() const {return RANDOM_IV;}
08953         static const char *StaticAlgorithmName() {return "CFB";}
08954 
08955 protected:
08956         unsigned int GetBytesPerIteration() const {return m_feedbackSize;}
08957         byte * GetRegisterBegin() {return m_register + BlockSize() - m_feedbackSize;}
08958         void TransformRegister()
08959         {
08960                 m_cipher->ProcessBlock(m_register, m_temp);
08961                 memmove(m_register, m_register+m_feedbackSize, BlockSize()-m_feedbackSize);
08962                 memcpy(m_register+BlockSize()-m_feedbackSize, m_temp, m_feedbackSize);
08963         }
08964         void CipherResynchronize(const byte *iv)
08965         {
08966                 memcpy(m_register, iv, BlockSize());
08967                 TransformRegister();
08968         }
08969         void SetFeedbackSize(unsigned int feedbackSize)
08970         {
08971                 if (feedbackSize > BlockSize())
08972                         throw InvalidArgument("CFB_Mode: invalid feedback size");
08973                 m_feedbackSize = feedbackSize ? feedbackSize : BlockSize();
08974         }
08975         void ResizeBuffers()
08976         {
08977                 CipherModeBase::ResizeBuffers();
08978                 m_temp.New(BlockSize());
08979         }
08980 
08981         SecByteBlock m_temp;
08982         unsigned int m_feedbackSize;
08983 };
08984 
08985 //! _
08986 template <class CIPHER, class BASE>
08987 class CipherModeFinalTemplate_CipherHolder : protected ObjectHolder<CIPHER>, public AlgorithmImpl<BASE, CipherModeFinalTemplate_CipherHolder<CIPHER, BASE> >
08988 {
08989 public:
08990         CipherModeFinalTemplate_CipherHolder()
08991         {
08992                 this->m_cipher = &this->m_object;
08993                 this->ResizeBuffers();
08994         }
08995         CipherModeFinalTemplate_CipherHolder(const byte *key, unsigned int length)
08996         {
08997                 this->m_cipher = &this->m_object;
08998                 this->SetKey(key, length);
08999         }
09000         CipherModeFinalTemplate_CipherHolder(const byte *key, unsigned int length, const byte *iv)
09001         {
09002                 this->m_cipher = &this->m_object;
09003                 this->SetKey(key, length, MakeParameters(Name::IV(), iv));
09004         }
09005         CipherModeFinalTemplate_CipherHolder(const byte *key, unsigned int length, const byte *iv, int feedbackSize)
09006         {
09007                 this->m_cipher = &this->m_object;
09008                 this->SetKey(key, length, MakeParameters(Name::IV(), iv)(Name::FeedbackSize(), feedbackSize));
09009         }
09010 
09011         static std::string StaticAlgorithmName()
09012                 {return CIPHER::StaticAlgorithmName() + "/" + BASE::StaticAlgorithmName();}
09013 };
09014 
09015 //! CFB mode
09016 template <class CIPHER>
09017 struct CFB_Mode : public CipherModeDocumentation
09018 {
09019         typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Encryption;
09020         typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Decryption;
09021 };
09022 
09023 NAMESPACE_END
09024 
09025 #endif
09026 ////////////////////////////////////////////////////////////////////////////////
09027 
09028 
09029 
09030 ////////////////////////////////////////////////////////////////////////////////
09031 // modes.cpp - written and placed in the public domain by Wei Dai
09032 
09033 //- #include "pch.h"
09034 
09035 #ifndef CRYPTOPP_IMPORTS
09036 
09037 //- #include "modes.h"
09038 
09039 namespace CryptoPP {
09040 
09041 void CipherModeBase::SetKey(const byte *key, unsigned int length, const NameValuePairs &params)
09042 {
09043         UncheckedSetKey(params, key, length, GetIVAndThrowIfInvalid(params));   // the underlying cipher will check the key length
09044 }
09045 
09046 void CipherModeBase::GetNextIV(byte *IV)
09047 {
09048         if (!IsForwardTransformation())
09049                 throw NotImplemented("CipherModeBase: GetNextIV() must be called on an encryption object");
09050 
09051         m_cipher->ProcessBlock(m_register);
09052         memcpy(IV, m_register, BlockSize());
09053 }
09054 
09055 NAMESPACE_END
09056 
09057 #endif
09058 ////////////////////////////////////////////////////////////////////////////////
09059 
09060 
09061 
09062 ////////////////////////////////////////////////////////////////////////////////
09063 // randpool.cpp - written and placed in the public domain by Wei Dai
09064 // The algorithm in this module comes from PGP's randpool.c
09065 
09066 //- #include "pch.h"
09067 
09068 #ifndef CRYPTOPP_IMPORTS
09069 
09070 //- #include "randpool.h"
09071 //- #include "mdc.h"
09072 //- #include "sha.h"
09073 //- #include "modes.h"
09074 
09075 namespace CryptoPP {
09076 
09077 typedef MDC<SHA> RandomPoolCipher;
09078 
09079 RandomPool::RandomPool(unsigned int poolSize)
09080         : pool(poolSize), key(RandomPoolCipher::DEFAULT_KEYLENGTH)
09081 {
09082         assert(poolSize > key.size());
09083 
09084         addPos=0;
09085         getPos=poolSize;
09086         memset(pool, 0, poolSize);
09087         memset(key, 0, key.size());
09088 }
09089 
09090 void RandomPool::Stir()
09091 {
09092         CFB_Mode<RandomPoolCipher>::Encryption cipher;
09093 
09094         for (int i=0; i<2; i++)
09095         {
09096                 cipher.SetKeyWithIV(key, key.size(), pool.end()-cipher.IVSize());
09097                 cipher.ProcessString(pool, pool.size());
09098                 memcpy(key, pool, key.size());
09099         }
09100 
09101         addPos = 0;
09102         getPos = key.size();
09103 }
09104 
09105 unsigned int RandomPool::Put2(const byte *inString, unsigned int length, int /* messageEnd */, bool /* blocking */)
09106 {
09107         unsigned t;
09108 
09109         while (length > (t = pool.size() - addPos))
09110         {
09111                 xorbuf(pool+addPos, inString, t);
09112                 inString += t;
09113                 length -= t;
09114                 Stir();
09115         }
09116 
09117         if (length)
09118         {
09119                 xorbuf(pool+addPos, inString, length);
09120                 addPos += length;
09121                 getPos = pool.size(); // Force stir on get
09122         }
09123 
09124         return 0;
09125 }
09126 
09127 unsigned int RandomPool::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
09128 {
09129         if (!blocking)
09130                 throw NotImplemented("RandomPool: nonblocking transfer is not implemented by this object");
09131 
09132         unsigned int t;
09133         unsigned long size = transferBytes;
09134 
09135         while (size > (t = pool.size() - getPos))
09136         {
09137                 target.ChannelPut(channel, pool+getPos, t);
09138                 size -= t;
09139                 Stir();
09140         }
09141 
09142         if (size)
09143         {
09144                 target.ChannelPut(channel, pool+getPos, size);
09145                 getPos += size;
09146         }
09147 
09148         return 0;
09149 }
09150 
09151 byte RandomPool::GenerateByte()
09152 {
09153         if (getPos == pool.size())
09154                 Stir();
09155 
09156         return pool[getPos++];
09157 }
09158 
09159 void RandomPool::GenerateBlock(byte *outString, unsigned int size)
09160 {
09161         ArraySink sink(outString, size);
09162         TransferTo(sink, size);
09163 }
09164 
09165 NAMESPACE_END
09166 
09167 #endif
09168 ////////////////////////////////////////////////////////////////////////////////
09169 
09170 
09171 
09172 ////////////////////////////////////////////////////////////////////////////////
09173 // osrng.cpp - written and placed in the public domain by Wei Dai
09174 
09175 // Thanks to Leonard Janke for the suggestion for AutoSeededRandomPool.
09176 
09177 //- #include "pch.h"
09178 
09179 #ifndef CRYPTOPP_IMPORTS
09180 
09181 //- #include "osrng.h"
09182 
09183 #ifdef OS_RNG_AVAILABLE
09184 
09185 //- #include "rng.h"
09186 
09187 #ifdef CRYPTOPP_WIN32_AVAILABLE
09188 #ifndef _WIN32_WINNT
09189 #define _WIN32_WINNT 0x0400
09190 #endif
09191 #include <windows.h>
09192 #include <wincrypt.h>
09193 #endif
09194 
09195 #ifdef CRYPTOPP_UNIX_AVAILABLE
09196 #include <errno.h>
09197 #include <fcntl.h>
09198 #include <unistd.h>
09199 #endif
09200 
09201 namespace CryptoPP {
09202 
09203 #if defined(NONBLOCKING_RNG_AVAILABLE) || defined(BLOCKING_RNG_AVAILABLE)
09204 OS_RNG_Err::OS_RNG_Err(const std::string &operation)
09205         : Exception(OTHER_ERROR, "OS_Rng: " + operation + " operation failed with error " +
09206 #ifdef CRYPTOPP_WIN32_AVAILABLE
09207                 "0x" + IntToString(GetLastError(), 16)
09208 #else
09209                 IntToString(errno)
09210 #endif
09211                 )
09212 {
09213 }
09214 #endif
09215 
09216 #ifdef NONBLOCKING_RNG_AVAILABLE
09217 
09218 #ifdef CRYPTOPP_WIN32_AVAILABLE
09219 
09220 MicrosoftCryptoProvider::MicrosoftCryptoProvider()
09221 {
09222         if(!CryptAcquireContext(&m_hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
09223                 throw OS_RNG_Err("CryptAcquireContext");
09224 }
09225 
09226 MicrosoftCryptoProvider::~MicrosoftCryptoProvider()
09227 {
09228         CryptReleaseContext(m_hProvider, 0);
09229 }
09230 
09231 #endif
09232 
09233 NonblockingRng::NonblockingRng()
09234 {
09235 #ifndef CRYPTOPP_WIN32_AVAILABLE
09236         m_fd = open("/dev/urandom",O_RDONLY);
09237         if (m_fd == -1)
09238                 throw OS_RNG_Err("open /dev/urandom");
09239 #endif
09240 }
09241 
09242 NonblockingRng::~NonblockingRng()
09243 {
09244 #ifndef CRYPTOPP_WIN32_AVAILABLE
09245         close(m_fd);
09246 #endif
09247 }
09248 
09249 byte NonblockingRng::GenerateByte()
09250 {
09251         byte b;
09252         GenerateBlock(&b, 1);
09253         return b;
09254 }
09255 
09256 void NonblockingRng::GenerateBlock(byte *output, unsigned int size)
09257 {
09258 #ifdef CRYPTOPP_WIN32_AVAILABLE
09259 #       ifdef WORKAROUND_MS_BUG_Q258000
09260                 static MicrosoftCryptoProvider m_Provider;
09261 #       endif
09262         if (!CryptGenRandom(m_Provider.GetProviderHandle(), size, output))
09263                 throw OS_RNG_Err("CryptGenRandom");
09264 #else
09265         if ((unsigned int)read(m_fd, output, size) != size) {
09266                 // Kernel 2.6.10 has non-concurrent access to /dev/urandom, retry at least once
09267                 printf("Shamelessly retrying a random generation attempt\n");
09268                 if ((unsigned int)read(m_fd, output, size) != size) {
09269                         printf("Error reading /dev/urandom! (kernel 2.6.10?)\n");
09270                         throw OS_RNG_Err("read /dev/urandom");
09271                 }
09272         }
09273 #endif
09274 }
09275 
09276 #endif
09277 
09278 // *************************************************************
09279 
09280 #ifdef BLOCKING_RNG_AVAILABLE
09281 
09282 BlockingRng::BlockingRng()
09283 {
09284         m_fd = open("/dev/random",O_RDONLY);
09285         if (m_fd == -1)
09286                 throw OS_RNG_Err("open /dev/random");
09287 }
09288 
09289 BlockingRng::~BlockingRng()
09290 {
09291         close(m_fd);
09292 }
09293 
09294 byte BlockingRng::GenerateByte()
09295 {
09296         byte b;
09297         GenerateBlock(&b, 1);
09298         return b;
09299 }
09300 
09301 void BlockingRng::GenerateBlock(byte *output, unsigned int size)
09302 {
09303         while (size)
09304         {
09305                 // on some systems /dev/random will block until all bytes
09306                 // are available, on others it will returns immediately
09307                 int len = read(m_fd, output, STDMIN(size, (unsigned int)INT_MAX));
09308                 if (len == -1)
09309                         throw OS_RNG_Err("read /dev/random");
09310                 size -= len;
09311                 output += len;
09312                 if (size)
09313                         sleep(1);
09314         }
09315 }
09316 
09317 #endif
09318 
09319 // *************************************************************
09320 
09321 void OS_GenerateRandomBlock(bool blocking, byte *output, unsigned int size)
09322 {
09323 #ifdef NONBLOCKING_RNG_AVAILABLE
09324         if (blocking)
09325 #endif
09326         {
09327 #ifdef BLOCKING_RNG_AVAILABLE
09328                 BlockingRng rng;
09329                 rng.GenerateBlock(output, size);
09330 #endif
09331         }
09332 
09333 #ifdef BLOCKING_RNG_AVAILABLE
09334         if (!blocking)
09335 #endif
09336         {
09337 #ifdef NONBLOCKING_RNG_AVAILABLE
09338                 NonblockingRng rng;
09339                 rng.GenerateBlock(output, size);
09340 #endif
09341         }
09342 }
09343 
09344 void AutoSeededRandomPool::Reseed(bool blocking, unsigned int seedSize)
09345 {
09346         SecByteBlock seed(seedSize);
09347         OS_GenerateRandomBlock(blocking, seed, seedSize);
09348         Put(seed, seedSize);
09349 }
09350 
09351 NAMESPACE_END
09352 
09353 #endif
09354 
09355 #endif
09356 ////////////////////////////////////////////////////////////////////////////////
09357 #endif
09358