Sophie

Sophie

distrib > Mandriva > 10.2 > i586 > media > contrib > by-pkgid > 7457b841ac8136d3a1a9d3d960c5252e > files > 1291

libcryptopp-doc-5.2.1-2mdk.i586.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>Crypto++: integer.cpp Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.3.7 -->
<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="namespaces.html">Namespace List</a> | <a class="qindex" href="hierarchy.html">Class&nbsp;Hierarchy</a> | <a class="qindex" href="classes.html">Alphabetical&nbsp;List</a> | <a class="qindex" href="annotated.html">Class&nbsp;List</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="namespacemembers.html">Namespace&nbsp;Members</a> | <a class="qindex" href="functions.html">Class&nbsp;Members</a> | <a class="qindex" href="globals.html">File&nbsp;Members</a></div>
<h1>integer.cpp</h1><pre class="fragment"><div>00001 <span class="comment">// integer.cpp - written and placed in the public domain by Wei Dai</span>
00002 <span class="comment">// contains public domain code contributed by Alister Lee and Leonard Janke</span>
00003 
00004 <span class="preprocessor">#include "pch.h"</span>
00005 
00006 <span class="preprocessor">#ifndef CRYPTOPP_IMPORTS</span>
00007 <span class="preprocessor"></span>
00008 <span class="preprocessor">#include "<a class="code" href="integer_8h.html">integer.h</a>"</span>
00009 <span class="preprocessor">#include "modarith.h"</span>
00010 <span class="preprocessor">#include "nbtheory.h"</span>
00011 <span class="preprocessor">#include "asn.h"</span>
00012 <span class="preprocessor">#include "oids.h"</span>
00013 <span class="preprocessor">#include "words.h"</span>
00014 <span class="preprocessor">#include "algparam.h"</span>
00015 <span class="preprocessor">#include "<a class="code" href="pubkey_8h.html">pubkey.h</a>"</span>             <span class="comment">// for P1363_KDF2</span>
00016 <span class="preprocessor">#include "sha.h"</span>
00017 
00018 <span class="preprocessor">#include &lt;iostream&gt;</span>
00019 
00020 <span class="preprocessor">#ifdef SSE2_INTRINSICS_AVAILABLE</span>
00021 <span class="preprocessor"></span><span class="preprocessor">        #ifdef __GNUC__</span>
00022 <span class="preprocessor"></span><span class="preprocessor">                #include &lt;xmmintrin.h&gt;</span>
00023 <span class="preprocessor">                #include &lt;signal.h&gt;</span>
00024 <span class="preprocessor">                #include &lt;setjmp.h&gt;</span>
00025 <span class="preprocessor">                #ifdef CRYPTOPP_MEMALIGN_AVAILABLE</span>
00026 <span class="preprocessor"></span><span class="preprocessor">                        #include &lt;malloc.h&gt;</span>
00027 <span class="preprocessor">                #else</span>
00028 <span class="preprocessor"></span><span class="preprocessor">                        #include &lt;stdlib.h&gt;</span>
00029 <span class="preprocessor">                #endif</span>
00030 <span class="preprocessor"></span><span class="preprocessor">        #else</span>
00031 <span class="preprocessor"></span><span class="preprocessor">                #include &lt;emmintrin.h&gt;</span>
00032 <span class="preprocessor">        #endif</span>
00033 <span class="preprocessor"></span><span class="preprocessor">#elif defined(_MSC_VER) &amp;&amp; defined(_M_IX86)</span>
00034 <span class="preprocessor"></span><span class="preprocessor">        #pragma message("You do not seem to have the Visual C++ Processor Pack installed, so use of SSE2 intrinsics will be disabled.")</span>
00035 <span class="preprocessor"></span><span class="preprocessor">#elif defined(__GNUC__) &amp;&amp; defined(__i386__)</span>
00036 <span class="preprocessor"></span><span class="preprocessor">        #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."</span>
00037 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
00038 <span class="preprocessor"></span>
00039 NAMESPACE_BEGIN(CryptoPP)
00040 
00041 bool FunctionAssignIntToInteger(const std::type_info &amp;valueType, <span class="keywordtype">void</span> *pInteger, const <span class="keywordtype">void</span> *pInt)
00042 {
00043         <span class="keywordflow">if</span> (valueType != <span class="keyword">typeid</span>(<a class="code" href="class_integer.html">Integer</a>))
00044                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
00045         *reinterpret_cast&lt;Integer *&gt;(pInteger) = *reinterpret_cast&lt;const int *&gt;(pInt);
00046         <span class="keywordflow">return</span> <span class="keyword">true</span>;
00047 }
00048 
00049 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span> s_RunAtStartup = (AssignIntToInteger = FunctionAssignIntToInteger, 0);
00050 
00051 <span class="preprocessor">#ifdef SSE2_INTRINSICS_AVAILABLE</span>
00052 <span class="preprocessor"></span><span class="keyword">template</span> &lt;<span class="keyword">class</span> T&gt;
00053 CPP_TYPENAME AllocatorBase&lt;T&gt;::pointer AlignedAllocator&lt;T&gt;::allocate(size_type n, <span class="keyword">const</span> <span class="keywordtype">void</span> *)
00054 {
00055         CheckSize(n);
00056         <span class="keywordflow">if</span> (n == 0)
00057                 <span class="keywordflow">return</span> NULL;
00058         <span class="keywordflow">if</span> (n &gt;= 4)
00059         {
00060                 <span class="keywordtype">void</span> *p;
00061 <span class="preprocessor">        #ifdef CRYPTOPP_MM_MALLOC_AVAILABLE</span>
00062 <span class="preprocessor"></span>                <span class="keywordflow">while</span> (!(p = _mm_malloc(<span class="keyword">sizeof</span>(T)*n, 16)))
00063 <span class="preprocessor">        #elif defined(CRYPTOPP_MEMALIGN_AVAILABLE)</span>
00064 <span class="preprocessor"></span>                <span class="keywordflow">while</span> (!(p = memalign(16, <span class="keyword">sizeof</span>(T)*n)))
00065 <span class="preprocessor">        #elif defined(CRYPTOPP_MALLOC_ALIGNMENT_IS_16)</span>
00066 <span class="preprocessor"></span>                <span class="keywordflow">while</span> (!(p = malloc(<span class="keyword">sizeof</span>(T)*n)))
00067 <span class="preprocessor">        #else</span>
00068 <span class="preprocessor"></span>                <span class="keywordflow">while</span> (!(p = (byte *)malloc(<span class="keyword">sizeof</span>(T)*n + 8)))  <span class="comment">// assume malloc alignment is at least 8</span>
00069 <span class="preprocessor">        #endif</span>
00070 <span class="preprocessor"></span>                        CallNewHandler();
00071 
00072 <span class="preprocessor">        #ifdef CRYPTOPP_NO_ALIGNED_ALLOC</span>
00073 <span class="preprocessor"></span>                assert(m_pBlock == NULL);
00074                 m_pBlock = p;
00075                 <span class="keywordflow">if</span> (!IsAlignedOn(p, 16))
00076                 {
00077                         assert(IsAlignedOn(p, 8));
00078                         p = (byte *)p + 8;
00079                 }
00080 <span class="preprocessor">        #endif</span>
00081 <span class="preprocessor"></span>
00082                 assert(IsAlignedOn(p, 16));
00083                 <span class="keywordflow">return</span> (T*)p;
00084         }
00085         <span class="keywordflow">return</span> <span class="keyword">new</span> T[n];
00086 }
00087 
00088 <span class="keyword">template</span> &lt;<span class="keyword">class</span> T&gt;
00089 <span class="keywordtype">void</span> AlignedAllocator&lt;T&gt;::deallocate(<span class="keywordtype">void</span> *p, size_type n)
00090 {
00091         memset(p, 0, n*<span class="keyword">sizeof</span>(T));
00092         <span class="keywordflow">if</span> (n &gt;= 4)
00093         {
00094 <span class="preprocessor">                #ifdef CRYPTOPP_MM_MALLOC_AVAILABLE</span>
00095 <span class="preprocessor"></span>                        _mm_free(p);
00096 <span class="preprocessor">                #elif defined(CRYPTOPP_NO_ALIGNED_ALLOC)</span>
00097 <span class="preprocessor"></span>                        assert(m_pBlock == p || (byte *)m_pBlock+8 == p);
00098                         free(m_pBlock);
00099                         m_pBlock = NULL;
00100 <span class="preprocessor">                #else</span>
00101 <span class="preprocessor"></span>                        free(p);
00102 <span class="preprocessor">                #endif</span>
00103 <span class="preprocessor"></span>        }
00104         <span class="keywordflow">else</span>
00105                 <span class="keyword">delete</span> [] (T *)p;
00106 }
00107 <span class="preprocessor">#endif</span>
00108 <span class="preprocessor"></span>
00109 <span class="keyword">static</span> <span class="keywordtype">int</span> Compare(<span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
00110 {
00111         <span class="keywordflow">while</span> (N--)
00112                 <span class="keywordflow">if</span> (A[N] &gt; B[N])
00113                         <span class="keywordflow">return</span> 1;
00114                 <span class="keywordflow">else</span> <span class="keywordflow">if</span> (A[N] &lt; B[N])
00115                         <span class="keywordflow">return</span> -1;
00116 
00117         <span class="keywordflow">return</span> 0;
00118 }
00119 
00120 <span class="keyword">static</span> word Increment(word *A, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N, word B=1)
00121 {
00122         assert(N);
00123         word t = A[0];
00124         A[0] = t+B;
00125         <span class="keywordflow">if</span> (A[0] &gt;= t)
00126                 <span class="keywordflow">return</span> 0;
00127         <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i=1; i&lt;N; i++)
00128                 <span class="keywordflow">if</span> (++A[i])
00129                         <span class="keywordflow">return</span> 0;
00130         <span class="keywordflow">return</span> 1;
00131 }
00132 
00133 <span class="keyword">static</span> word Decrement(word *A, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N, word B=1)
00134 {
00135         assert(N);
00136         word t = A[0];
00137         A[0] = t-B;
00138         <span class="keywordflow">if</span> (A[0] &lt;= t)
00139                 <span class="keywordflow">return</span> 0;
00140         <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i=1; i&lt;N; i++)
00141                 <span class="keywordflow">if</span> (A[i]--)
00142                         <span class="keywordflow">return</span> 0;
00143         <span class="keywordflow">return</span> 1;
00144 }
00145 
00146 <span class="keyword">static</span> <span class="keywordtype">void</span> TwosComplement(word *A, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
00147 {
00148         Decrement(A, N);
00149         <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i=0; i&lt;N; i++)
00150                 A[i] = ~A[i];
00151 }
00152 
00153 <span class="keyword">static</span> word AtomicInverseModPower2(word A)
00154 {
00155         assert(A%2==1);
00156 
00157         word R=A%8;
00158 
00159         <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i=3; i&lt;WORD_BITS; i*=2)
00160                 R = R*(2-R*A);
00161 
00162         assert(R*A==1);
00163         <span class="keywordflow">return</span> R;
00164 }
00165 
00166 <span class="comment">// ********************************************************</span>
00167 
00168 <span class="keyword">class </span>DWord
00169 {
00170 <span class="keyword">public</span>:
00171         DWord() {}
00172 
00173 <span class="preprocessor">#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE</span>
00174 <span class="preprocessor"></span>        <span class="keyword">explicit</span> DWord(word low)
00175         {
00176                 m_whole = low;
00177         }
00178 <span class="preprocessor">#else</span>
00179 <span class="preprocessor"></span>        <span class="keyword">explicit</span> DWord(word low)
00180         {
00181                 m_halfs.low = low;
00182                 m_halfs.high = 0;
00183         }
00184 <span class="preprocessor">#endif</span>
00185 <span class="preprocessor"></span>
00186         DWord(word low, word high)
00187         {
00188                 m_halfs.low = low;
00189                 m_halfs.high = high;
00190         }
00191 
00192         <span class="keyword">static</span> DWord Multiply(word a, word b)
00193         {
00194                 DWord r;
00195 <span class="preprocessor">                #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE</span>
00196 <span class="preprocessor"></span>                        r.m_whole = (dword)a * b;
00197 <span class="preprocessor">                #elif defined(__alpha__)</span>
00198 <span class="preprocessor"></span>                        r.m_halfs.low = a*b; __asm__(<span class="stringliteral">"umulh %1,%2,%0"</span> : <span class="stringliteral">"=r"</span> (r.m_halfs.high) : <span class="stringliteral">"r"</span> (a), <span class="stringliteral">"r"</span> (b));
00199 <span class="preprocessor">                #elif defined(__ia64__)</span>
00200 <span class="preprocessor"></span>                        r.m_halfs.low = a*b; __asm__(<span class="stringliteral">"xmpy.hu %0=%1,%2"</span> : <span class="stringliteral">"=f"</span> (r.m_halfs.high) : <span class="stringliteral">"f"</span> (a), <span class="stringliteral">"f"</span> (b));
00201 <span class="preprocessor">                #elif defined(_ARCH_PPC64)</span>
00202 <span class="preprocessor"></span>                        r.m_halfs.low = a*b; __asm__(<span class="stringliteral">"mulhdu %0,%1,%2"</span> : <span class="stringliteral">"=r"</span> (r.m_halfs.high) : <span class="stringliteral">"r"</span> (a), <span class="stringliteral">"r"</span> (b) : <span class="stringliteral">"cc"</span>);
00203 <span class="preprocessor">                #elif defined(__x86_64__)</span>
00204 <span class="preprocessor"></span>                        __asm__(<span class="stringliteral">"mulq %3"</span> : <span class="stringliteral">"=d"</span> (r.m_halfs.high), <span class="stringliteral">"=a"</span> (r.m_halfs.low) : <span class="stringliteral">"a"</span> (a), <span class="stringliteral">"rm"</span> (b) : <span class="stringliteral">"cc"</span>);
00205 <span class="preprocessor">                #elif defined(__mips64)</span>
00206 <span class="preprocessor"></span>                        __asm__(<span class="stringliteral">"dmultu %2,%3"</span> : <span class="stringliteral">"=h"</span> (r.m_halfs.high), <span class="stringliteral">"=l"</span> (r.m_halfs.low) : <span class="stringliteral">"r"</span> (a), <span class="stringliteral">"r"</span> (b));
00207 <span class="preprocessor">                #elif defined(_M_IX86)</span>
00208 <span class="preprocessor"></span>                        <span class="comment">// for testing</span>
00209                         word64 t = (word64)a * b;
00210                         r.m_halfs.high = ((word32 *)(&amp;t))[1];
00211                         r.m_halfs.low = (word32)t;
00212 <span class="preprocessor">                #else</span>
00213 <span class="preprocessor"></span><span class="preprocessor">                        #error can not implement DWord</span>
00214 <span class="preprocessor"></span><span class="preprocessor">                #endif</span>
00215 <span class="preprocessor"></span>                <span class="keywordflow">return</span> r;
00216         }
00217 
00218         <span class="keyword">static</span> DWord MultiplyAndAdd(word a, word b, word c)
00219         {
00220                 DWord r = Multiply(a, b);
00221                 <span class="keywordflow">return</span> r += c;
00222         }
00223 
00224         DWord &amp; operator+=(word a)
00225         {
00226 <span class="preprocessor">                #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE</span>
00227 <span class="preprocessor"></span>                        m_whole = m_whole + a;
00228 <span class="preprocessor">                #else</span>
00229 <span class="preprocessor"></span>                        m_halfs.low += a;
00230                         m_halfs.high += (m_halfs.low &lt; a);
00231 <span class="preprocessor">                #endif</span>
00232 <span class="preprocessor"></span>                <span class="keywordflow">return</span> *<span class="keyword">this</span>;
00233         }
00234 
00235         DWord operator+(word a)
00236         {
00237                 DWord r;
00238 <span class="preprocessor">                #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE</span>
00239 <span class="preprocessor"></span>                        r.m_whole = m_whole + a;
00240 <span class="preprocessor">                #else</span>
00241 <span class="preprocessor"></span>                        r.m_halfs.low = m_halfs.low + a;
00242                         r.m_halfs.high = m_halfs.high + (r.m_halfs.low &lt; a);
00243 <span class="preprocessor">                #endif</span>
00244 <span class="preprocessor"></span>                <span class="keywordflow">return</span> r;
00245         }
00246 
00247         DWord operator-(DWord a)
00248         {
00249                 DWord r;
00250 <span class="preprocessor">                #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE</span>
00251 <span class="preprocessor"></span>                        r.m_whole = m_whole - a.m_whole;
00252 <span class="preprocessor">                #else</span>
00253 <span class="preprocessor"></span>                        r.m_halfs.low = m_halfs.low - a.m_halfs.low;
00254                         r.m_halfs.high = m_halfs.high - a.m_halfs.high - (r.m_halfs.low &gt; m_halfs.low);
00255 <span class="preprocessor">                #endif</span>
00256 <span class="preprocessor"></span>                <span class="keywordflow">return</span> r;
00257         }
00258 
00259         DWord operator-(word a)
00260         {
00261                 DWord r;
00262 <span class="preprocessor">                #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE</span>
00263 <span class="preprocessor"></span>                        r.m_whole = m_whole - a;
00264 <span class="preprocessor">                #else</span>
00265 <span class="preprocessor"></span>                        r.m_halfs.low = m_halfs.low - a;
00266                         r.m_halfs.high = m_halfs.high - (r.m_halfs.low &gt; m_halfs.low);
00267 <span class="preprocessor">                #endif</span>
00268 <span class="preprocessor"></span>                <span class="keywordflow">return</span> r;
00269         }
00270 
00271         <span class="comment">// returns quotient, which must fit in a word</span>
00272         word operator/(word divisor);
00273 
00274         word operator%(word a);
00275 
00276         <span class="keywordtype">bool</span> operator!()<span class="keyword"> const</span>
00277 <span class="keyword">        </span>{
00278 <span class="preprocessor">        #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE</span>
00279 <span class="preprocessor"></span>                <span class="keywordflow">return</span> !m_whole;
00280 <span class="preprocessor">        #else</span>
00281 <span class="preprocessor"></span>                <span class="keywordflow">return</span> !m_halfs.high &amp;&amp; !m_halfs.low;
00282 <span class="preprocessor">        #endif</span>
00283 <span class="preprocessor"></span>        }
00284 
00285         word GetLowHalf()<span class="keyword"> const </span>{<span class="keywordflow">return</span> m_halfs.low;}
00286         word GetHighHalf()<span class="keyword"> const </span>{<span class="keywordflow">return</span> m_halfs.high;}
00287         word GetHighHalfAsBorrow()<span class="keyword"> const </span>{<span class="keywordflow">return</span> 0-m_halfs.high;}
00288 
00289 <span class="keyword">private</span>:
00290         <span class="keyword">union</span>
00291 <span class="keyword">        </span>{
00292 <span class="preprocessor">        #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE</span>
00293 <span class="preprocessor"></span>                dword m_whole;
00294 <span class="preprocessor">        #endif</span>
00295 <span class="preprocessor"></span>                <span class="keyword">struct</span>
00296 <span class="keyword">                </span>{
00297 <span class="preprocessor">                #ifdef IS_LITTLE_ENDIAN</span>
00298 <span class="preprocessor"></span>                        word low;
00299                         word high;
00300 <span class="preprocessor">                #else</span>
00301 <span class="preprocessor"></span>                        word high;
00302                         word low;
00303 <span class="preprocessor">                #endif</span>
00304 <span class="preprocessor"></span>                } m_halfs;
00305         };
00306 };
00307 
00308 <span class="keyword">class </span>Word
00309 {
00310 <span class="keyword">public</span>:
00311         Word() {}
00312 
00313         Word(word value)
00314         {
00315                 m_whole = value;
00316         }
00317 
00318         Word(hword low, hword high)
00319         {
00320                 m_whole = low | (word(high) &lt;&lt; (WORD_BITS/2));
00321         }
00322 
00323         <span class="keyword">static</span> Word Multiply(hword a, hword b)
00324         {
00325                 Word r;
00326                 r.m_whole = (word)a * b;
00327                 <span class="keywordflow">return</span> r;
00328         }
00329 
00330         Word operator-(Word a)
00331         {
00332                 Word r;
00333                 r.m_whole = m_whole - a.m_whole;
00334                 <span class="keywordflow">return</span> r;
00335         }
00336 
00337         Word operator-(hword a)
00338         {
00339                 Word r;
00340                 r.m_whole = m_whole - a;
00341                 <span class="keywordflow">return</span> r;
00342         }
00343 
00344         <span class="comment">// returns quotient, which must fit in a word</span>
00345         hword operator/(hword divisor)
00346         {
00347                 <span class="keywordflow">return</span> hword(m_whole / divisor);
00348         }
00349 
00350         <span class="keywordtype">bool</span> operator!()<span class="keyword"> const</span>
00351 <span class="keyword">        </span>{
00352                 <span class="keywordflow">return</span> !m_whole;
00353         }
00354 
00355         word GetWhole()<span class="keyword"> const </span>{<span class="keywordflow">return</span> m_whole;}
00356         hword GetLowHalf()<span class="keyword"> const </span>{<span class="keywordflow">return</span> hword(m_whole);}
00357         hword GetHighHalf()<span class="keyword"> const </span>{<span class="keywordflow">return</span> hword(m_whole&gt;&gt;(WORD_BITS/2));}
00358         hword GetHighHalfAsBorrow()<span class="keyword"> const </span>{<span class="keywordflow">return</span> 0-hword(m_whole&gt;&gt;(WORD_BITS/2));}
00359         
00360 <span class="keyword">private</span>:
00361         word m_whole;
00362 };
00363 
00364 <span class="comment">// do a 3 word by 2 word divide, returns quotient and leaves remainder in A</span>
00365 <span class="keyword">template</span> &lt;<span class="keyword">class</span> S, <span class="keyword">class</span> D&gt;
00366 S DivideThreeWordsByTwo(S *A, S B0, S B1, D *dummy=NULL)
00367 {
00368         <span class="comment">// assert {A[2],A[1]} &lt; {B1,B0}, so quotient can fit in a S</span>
00369         assert(A[2] &lt; B1 || (A[2]==B1 &amp;&amp; A[1] &lt; B0));
00370 
00371         <span class="comment">// estimate the quotient: do a 2 S by 1 S divide</span>
00372         S Q;
00373         <span class="keywordflow">if</span> (S(B1+1) == 0)
00374                 Q = A[2];
00375         <span class="keywordflow">else</span>
00376                 Q = D(A[1], A[2]) / S(B1+1);
00377 
00378         <span class="comment">// now subtract Q*B from A</span>
00379         D p = D::Multiply(B0, Q);
00380         D u = (D) A[0] - p.GetLowHalf();
00381         A[0] = u.GetLowHalf();
00382         u = (D) A[1] - p.GetHighHalf() - u.GetHighHalfAsBorrow() - D::Multiply(B1, Q);
00383         A[1] = u.GetLowHalf();
00384         A[2] += u.GetHighHalf();
00385 
00386         <span class="comment">// Q &lt;= actual quotient, so fix it</span>
00387         <span class="keywordflow">while</span> (A[2] || A[1] &gt; B1 || (A[1]==B1 &amp;&amp; A[0]&gt;=B0))
00388         {
00389                 u = (D) A[0] - B0;
00390                 A[0] = u.GetLowHalf();
00391                 u = (D) A[1] - B1 - u.GetHighHalfAsBorrow();
00392                 A[1] = u.GetLowHalf();
00393                 A[2] += u.GetHighHalf();
00394                 Q++;
00395                 assert(Q);      <span class="comment">// shouldn't overflow</span>
00396         }
00397 
00398         <span class="keywordflow">return</span> Q;
00399 }
00400 
00401 <span class="comment">// do a 4 word by 2 word divide, returns 2 word quotient in Q0 and Q1</span>
00402 <span class="keyword">template</span> &lt;<span class="keyword">class</span> S, <span class="keyword">class</span> D&gt;
00403 <span class="keyword">inline</span> D DivideFourWordsByTwo(S *T, <span class="keyword">const</span> D &amp;Al, <span class="keyword">const</span> D &amp;Ah, <span class="keyword">const</span> D &amp;B)
00404 {
00405         <span class="keywordflow">if</span> (!B) <span class="comment">// if divisor is 0, we assume divisor==2**(2*WORD_BITS)</span>
00406                 <span class="keywordflow">return</span> D(Ah.GetLowHalf(), Ah.GetHighHalf());
00407         <span class="keywordflow">else</span>
00408         {
00409                 S Q[2];
00410                 T[0] = Al.GetLowHalf();
00411                 T[1] = Al.GetHighHalf(); 
00412                 T[2] = Ah.GetLowHalf();
00413                 T[3] = Ah.GetHighHalf();
00414                 Q[1] = DivideThreeWordsByTwo&lt;S, D&gt;(T+1, B.GetLowHalf(), B.GetHighHalf());
00415                 Q[0] = DivideThreeWordsByTwo&lt;S, D&gt;(T, B.GetLowHalf(), B.GetHighHalf());
00416                 <span class="keywordflow">return</span> D(Q[0], Q[1]);
00417         }
00418 }
00419 
00420 <span class="comment">// returns quotient, which must fit in a word</span>
00421 <span class="keyword">inline</span> word DWord::operator/(word a)
00422 {
00423 <span class="preprocessor">        #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE</span>
00424 <span class="preprocessor"></span>                <span class="keywordflow">return</span> word(m_whole / a);
00425 <span class="preprocessor">        #else</span>
00426 <span class="preprocessor"></span>                hword r[4];
00427                 <span class="keywordflow">return</span> DivideFourWordsByTwo&lt;hword, Word&gt;(r, m_halfs.low, m_halfs.high, a).GetWhole();
00428 <span class="preprocessor">        #endif</span>
00429 <span class="preprocessor"></span>}
00430 
00431 <span class="keyword">inline</span> word DWord::operator%(word a)
00432 {
00433 <span class="preprocessor">        #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE</span>
00434 <span class="preprocessor"></span>                <span class="keywordflow">return</span> word(m_whole % a);
00435 <span class="preprocessor">        #else</span>
00436 <span class="preprocessor"></span>                <span class="keywordflow">if</span> (a &lt; (word(1) &lt;&lt; (WORD_BITS/2)))
00437                 {
00438                         hword h = hword(a);
00439                         word r = m_halfs.high % h;
00440                         r = ((m_halfs.low &gt;&gt; (WORD_BITS/2)) + (r &lt;&lt; (WORD_BITS/2))) % h;
00441                         <span class="keywordflow">return</span> hword((hword(m_halfs.low) + (r &lt;&lt; (WORD_BITS/2))) % h);
00442                 }
00443                 <span class="keywordflow">else</span>
00444                 {
00445                         hword r[4];
00446                         DivideFourWordsByTwo&lt;hword, Word&gt;(r, m_halfs.low, m_halfs.high, a);
00447                         <span class="keywordflow">return</span> Word(r[0], r[1]).GetWhole();
00448                 }
00449 <span class="preprocessor">        #endif</span>
00450 <span class="preprocessor"></span>}
00451 
00452 <span class="comment">// ********************************************************</span>
00453 
00454 <span class="keyword">class </span>Portable
00455 {
00456 <span class="keyword">public</span>:
00457         <span class="keyword">static</span> word Add(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N);
00458         <span class="keyword">static</span> word Subtract(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N);
00459 
00460         <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">void</span> Multiply2(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B);
00461         <span class="keyword">static</span> <span class="keyword">inline</span> word Multiply2Add(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B);
00462         <span class="keyword">static</span> <span class="keywordtype">void</span> Multiply4(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B);
00463         <span class="keyword">static</span> <span class="keywordtype">void</span> Multiply8(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B);
00464         <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> MultiplyRecursionLimit() {<span class="keywordflow">return</span> 8;}
00465 
00466         <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">void</span> Multiply2Bottom(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B);
00467         <span class="keyword">static</span> <span class="keywordtype">void</span> Multiply4Bottom(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B);
00468         <span class="keyword">static</span> <span class="keywordtype">void</span> Multiply8Bottom(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B);
00469         <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> MultiplyBottomRecursionLimit() {<span class="keywordflow">return</span> 8;}
00470 
00471         <span class="keyword">static</span> <span class="keywordtype">void</span> Square2(word *R, <span class="keyword">const</span> word *A);
00472         <span class="keyword">static</span> <span class="keywordtype">void</span> Square4(word *R, <span class="keyword">const</span> word *A);
00473         <span class="keyword">static</span> <span class="keywordtype">void</span> Square8(word *R, <span class="keyword">const</span> word *A) {assert(<span class="keyword">false</span>);}
00474         <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SquareRecursionLimit() {<span class="keywordflow">return</span> 4;}
00475 };
00476 
00477 word Portable::Add(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
00478 {
00479         assert (N%2 == 0);
00480 
00481         DWord u(0, 0);
00482         <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i = 0; i &lt; N; i+=2)
00483         {
00484                 u = DWord(A[i]) + B[i] + u.GetHighHalf();
00485                 C[i] = u.GetLowHalf();
00486                 u = DWord(A[i+1]) + B[i+1] + u.GetHighHalf();
00487                 C[i+1] = u.GetLowHalf();
00488         }
00489         <span class="keywordflow">return</span> u.GetHighHalf();
00490 }
00491 
00492 word Portable::Subtract(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
00493 {
00494         assert (N%2 == 0);
00495 
00496         DWord u(0, 0);
00497         <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i = 0; i &lt; N; i+=2)
00498         {
00499                 u = (DWord) A[i] - B[i] - u.GetHighHalfAsBorrow();
00500                 C[i] = u.GetLowHalf();
00501                 u = (DWord) A[i+1] - B[i+1] - u.GetHighHalfAsBorrow();
00502                 C[i+1] = u.GetLowHalf();
00503         }
00504         <span class="keywordflow">return</span> 0-u.GetHighHalf();
00505 }
00506 
00507 <span class="keywordtype">void</span> Portable::Multiply2(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B)
00508 {
00509 <span class="comment">/*</span>
00510 <span class="comment">        word s;</span>
00511 <span class="comment">        dword d;</span>
00512 <span class="comment"></span>
00513 <span class="comment">        if (A1 &gt;= A0)</span>
00514 <span class="comment">                if (B0 &gt;= B1)</span>
00515 <span class="comment">                {</span>
00516 <span class="comment">                        s = 0;</span>
00517 <span class="comment">                        d = (dword)(A1-A0)*(B0-B1);</span>
00518 <span class="comment">                }</span>
00519 <span class="comment">                else</span>
00520 <span class="comment">                {</span>
00521 <span class="comment">                        s = (A1-A0);</span>
00522 <span class="comment">                        d = (dword)s*(word)(B0-B1);</span>
00523 <span class="comment">                }</span>
00524 <span class="comment">        else</span>
00525 <span class="comment">                if (B0 &gt; B1)</span>
00526 <span class="comment">                {</span>
00527 <span class="comment">                        s = (B0-B1);</span>
00528 <span class="comment">                        d = (word)(A1-A0)*(dword)s;</span>
00529 <span class="comment">                }</span>
00530 <span class="comment">                else</span>
00531 <span class="comment">                {</span>
00532 <span class="comment">                        s = 0;</span>
00533 <span class="comment">                        d = (dword)(A0-A1)*(B1-B0);</span>
00534 <span class="comment">                }</span>
00535 <span class="comment">*/</span>
00536         <span class="comment">// this segment is the branchless equivalent of above</span>
00537         word D[4] = {A[1]-A[0], A[0]-A[1], B[0]-B[1], B[1]-B[0]};
00538         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ai = A[1] &lt; A[0];
00539         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> bi = B[0] &lt; B[1];
00540         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> di = ai &amp; bi;
00541         DWord d = DWord::Multiply(D[di], D[di+2]);
00542         D[1] = D[3] = 0;
00543         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> si = ai + !bi;
00544         word s = D[si];
00545 
00546         DWord A0B0 = DWord::Multiply(A[0], B[0]);
00547         C[0] = A0B0.GetLowHalf();
00548 
00549         DWord A1B1 = DWord::Multiply(A[1], B[1]);
00550         DWord t = (DWord) A0B0.GetHighHalf() + A0B0.GetLowHalf() + d.GetLowHalf() + A1B1.GetLowHalf();
00551         C[1] = t.GetLowHalf();
00552 
00553         t = A1B1 + t.GetHighHalf() + A0B0.GetHighHalf() + d.GetHighHalf() + A1B1.GetHighHalf() - s;
00554         C[2] = t.GetLowHalf();
00555         C[3] = t.GetHighHalf();
00556 }
00557 
00558 <span class="keyword">inline</span> <span class="keywordtype">void</span> Portable::Multiply2Bottom(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B)
00559 {
00560         DWord t = DWord::Multiply(A[0], B[0]);
00561         C[0] = t.GetLowHalf();
00562         C[1] = t.GetHighHalf() + A[0]*B[1] + A[1]*B[0];
00563 }
00564 
00565 word Portable::Multiply2Add(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B)
00566 {
00567         word D[4] = {A[1]-A[0], A[0]-A[1], B[0]-B[1], B[1]-B[0]};
00568         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ai = A[1] &lt; A[0];
00569         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> bi = B[0] &lt; B[1];
00570         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> di = ai &amp; bi;
00571         DWord d = DWord::Multiply(D[di], D[di+2]);
00572         D[1] = D[3] = 0;
00573         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> si = ai + !bi;
00574         word s = D[si];
00575 
00576         DWord A0B0 = DWord::Multiply(A[0], B[0]);
00577         DWord t = A0B0 + C[0];
00578         C[0] = t.GetLowHalf();
00579 
00580         DWord A1B1 = DWord::Multiply(A[1], B[1]);
00581         t = (DWord) t.GetHighHalf() + A0B0.GetLowHalf() + d.GetLowHalf() + A1B1.GetLowHalf() + C[1];
00582         C[1] = t.GetLowHalf();
00583 
00584         t = (DWord) t.GetHighHalf() + A1B1.GetLowHalf() + A0B0.GetHighHalf() + d.GetHighHalf() + A1B1.GetHighHalf() - s + C[2];
00585         C[2] = t.GetLowHalf();
00586 
00587         t = (DWord) t.GetHighHalf() + A1B1.GetHighHalf() + C[3];
00588         C[3] = t.GetLowHalf();
00589         <span class="keywordflow">return</span> t.GetHighHalf();
00590 }
00591 
00592 <span class="preprocessor">#define MulAcc(x, y)                                                            \</span>
00593 <span class="preprocessor">        p = DWord::MultiplyAndAdd(A[x], B[y], c);               \</span>
00594 <span class="preprocessor">        c = p.GetLowHalf();                                                             \</span>
00595 <span class="preprocessor">        p = (DWord) d + p.GetHighHalf();                                        \</span>
00596 <span class="preprocessor">        d = p.GetLowHalf();                                                             \</span>
00597 <span class="preprocessor">        e += p.GetHighHalf();</span>
00598 <span class="preprocessor"></span>
00599 <span class="preprocessor">#define SaveMulAcc(s, x, y)                                             \</span>
00600 <span class="preprocessor">        R[s] = c;                                                                               \</span>
00601 <span class="preprocessor">        p = DWord::MultiplyAndAdd(A[x], B[y], d);                               \</span>
00602 <span class="preprocessor">        c = p.GetLowHalf();                                                             \</span>
00603 <span class="preprocessor">        p = (DWord) e + p.GetHighHalf();                                        \</span>
00604 <span class="preprocessor">        d = p.GetLowHalf();                                                             \</span>
00605 <span class="preprocessor">        e = p.GetHighHalf();</span>
00606 <span class="preprocessor"></span>
00607 <span class="preprocessor">#define SquAcc(x, y)                                                            \</span>
00608 <span class="preprocessor">        q = DWord::Multiply(A[x], A[y]);        \</span>
00609 <span class="preprocessor">        p = q + c;                                      \</span>
00610 <span class="preprocessor">        c = p.GetLowHalf();                                                             \</span>
00611 <span class="preprocessor">        p = (DWord) d + p.GetHighHalf();                                        \</span>
00612 <span class="preprocessor">        d = p.GetLowHalf();                                                             \</span>
00613 <span class="preprocessor">        e += p.GetHighHalf();                   \</span>
00614 <span class="preprocessor">        p = q + c;                                      \</span>
00615 <span class="preprocessor">        c = p.GetLowHalf();                                                             \</span>
00616 <span class="preprocessor">        p = (DWord) d + p.GetHighHalf();                                        \</span>
00617 <span class="preprocessor">        d = p.GetLowHalf();                                                             \</span>
00618 <span class="preprocessor">        e += p.GetHighHalf();</span>
00619 <span class="preprocessor"></span>
00620 <span class="preprocessor">#define SaveSquAcc(s, x, y)                                             \</span>
00621 <span class="preprocessor">        R[s] = c;                                                                               \</span>
00622 <span class="preprocessor">        q = DWord::Multiply(A[x], A[y]);        \</span>
00623 <span class="preprocessor">        p = q + d;                                      \</span>
00624 <span class="preprocessor">        c = p.GetLowHalf();                                                             \</span>
00625 <span class="preprocessor">        p = (DWord) e + p.GetHighHalf();                                        \</span>
00626 <span class="preprocessor">        d = p.GetLowHalf();                                                             \</span>
00627 <span class="preprocessor">        e = p.GetHighHalf();                    \</span>
00628 <span class="preprocessor">        p = q + c;                                      \</span>
00629 <span class="preprocessor">        c = p.GetLowHalf();                                                             \</span>
00630 <span class="preprocessor">        p = (DWord) d + p.GetHighHalf();                                        \</span>
00631 <span class="preprocessor">        d = p.GetLowHalf();                                                             \</span>
00632 <span class="preprocessor">        e += p.GetHighHalf();</span>
00633 <span class="preprocessor"></span>
00634 <span class="keywordtype">void</span> Portable::Multiply4(word *R, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B)
00635 {
00636         DWord p;
00637         word c, d, e;
00638 
00639         p = DWord::Multiply(A[0], B[0]);
00640         R[0] = p.GetLowHalf();
00641         c = p.GetHighHalf();
00642         d = e = 0;
00643 
00644         MulAcc(0, 1);
00645         MulAcc(1, 0);
00646 
00647         SaveMulAcc(1, 2, 0);
00648         MulAcc(1, 1);
00649         MulAcc(0, 2);
00650 
00651         SaveMulAcc(2, 0, 3);
00652         MulAcc(1, 2);
00653         MulAcc(2, 1);
00654         MulAcc(3, 0);
00655 
00656         SaveMulAcc(3, 3, 1);
00657         MulAcc(2, 2);
00658         MulAcc(1, 3);
00659 
00660         SaveMulAcc(4, 2, 3);
00661         MulAcc(3, 2);
00662 
00663         R[5] = c;
00664         p = DWord::MultiplyAndAdd(A[3], B[3], d);
00665         R[6] = p.GetLowHalf();
00666         R[7] = e + p.GetHighHalf();
00667 }
00668 
00669 <span class="keywordtype">void</span> Portable::Square2(word *R, <span class="keyword">const</span> word *A)
00670 {
00671         DWord p, q;
00672         word c, d, e;
00673 
00674         p = DWord::Multiply(A[0], A[0]);
00675         R[0] = p.GetLowHalf();
00676         c = p.GetHighHalf();
00677         d = e = 0;
00678 
00679         SquAcc(0, 1);
00680 
00681         R[1] = c;
00682         p = DWord::MultiplyAndAdd(A[1], A[1], d);
00683         R[2] = p.GetLowHalf();
00684         R[3] = e + p.GetHighHalf();
00685 }
00686 
00687 <span class="keywordtype">void</span> Portable::Square4(word *R, <span class="keyword">const</span> word *A)
00688 {
00689 <span class="preprocessor">#ifdef _MSC_VER</span>
00690 <span class="preprocessor"></span>        <span class="comment">// VC60 workaround: MSVC 6.0 has an optimization bug that makes</span>
00691         <span class="comment">// (dword)A*B where either A or B has been cast to a dword before</span>
00692         <span class="comment">// very expensive. Revisit this function when this</span>
00693         <span class="comment">// bug is fixed.</span>
00694         Multiply4(R, A, A);
00695 <span class="preprocessor">#else</span>
00696 <span class="preprocessor"></span>        <span class="keyword">const</span> word *B = A;
00697         DWord p, q;
00698         word c, d, e;
00699 
00700         p = DWord::Multiply(A[0], A[0]);
00701         R[0] = p.GetLowHalf();
00702         c = p.GetHighHalf();
00703         d = e = 0;
00704 
00705         SquAcc(0, 1);
00706 
00707         SaveSquAcc(1, 2, 0);
00708         MulAcc(1, 1);
00709 
00710         SaveSquAcc(2, 0, 3);
00711         SquAcc(1, 2);
00712 
00713         SaveSquAcc(3, 3, 1);
00714         MulAcc(2, 2);
00715 
00716         SaveSquAcc(4, 2, 3);
00717 
00718         R[5] = c;
00719         p = DWord::MultiplyAndAdd(A[3], A[3], d);
00720         R[6] = p.GetLowHalf();
00721         R[7] = e + p.GetHighHalf();
00722 <span class="preprocessor">#endif</span>
00723 <span class="preprocessor"></span>}
00724 
00725 <span class="keywordtype">void</span> Portable::Multiply8(word *R, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B)
00726 {
00727         DWord p;
00728         word c, d, e;
00729 
00730         p = DWord::Multiply(A[0], B[0]);
00731         R[0] = p.GetLowHalf();
00732         c = p.GetHighHalf();
00733         d = e = 0;
00734 
00735         MulAcc(0, 1);
00736         MulAcc(1, 0);
00737 
00738         SaveMulAcc(1, 2, 0);
00739         MulAcc(1, 1);
00740         MulAcc(0, 2);
00741 
00742         SaveMulAcc(2, 0, 3);
00743         MulAcc(1, 2);
00744         MulAcc(2, 1);
00745         MulAcc(3, 0);
00746 
00747         SaveMulAcc(3, 0, 4);
00748         MulAcc(1, 3);
00749         MulAcc(2, 2);
00750         MulAcc(3, 1);
00751         MulAcc(4, 0);
00752 
00753         SaveMulAcc(4, 0, 5);
00754         MulAcc(1, 4);
00755         MulAcc(2, 3);
00756         MulAcc(3, 2);
00757         MulAcc(4, 1);
00758         MulAcc(5, 0);
00759 
00760         SaveMulAcc(5, 0, 6);
00761         MulAcc(1, 5);
00762         MulAcc(2, 4);
00763         MulAcc(3, 3);
00764         MulAcc(4, 2);
00765         MulAcc(5, 1);
00766         MulAcc(6, 0);
00767 
00768         SaveMulAcc(6, 0, 7);
00769         MulAcc(1, 6);
00770         MulAcc(2, 5);
00771         MulAcc(3, 4);
00772         MulAcc(4, 3);
00773         MulAcc(5, 2);
00774         MulAcc(6, 1);
00775         MulAcc(7, 0);
00776 
00777         SaveMulAcc(7, 1, 7);
00778         MulAcc(2, 6);
00779         MulAcc(3, 5);
00780         MulAcc(4, 4);
00781         MulAcc(5, 3);
00782         MulAcc(6, 2);
00783         MulAcc(7, 1);
00784 
00785         SaveMulAcc(8, 2, 7);
00786         MulAcc(3, 6);
00787         MulAcc(4, 5);
00788         MulAcc(5, 4);
00789         MulAcc(6, 3);
00790         MulAcc(7, 2);
00791 
00792         SaveMulAcc(9, 3, 7);
00793         MulAcc(4, 6);
00794         MulAcc(5, 5);
00795         MulAcc(6, 4);
00796         MulAcc(7, 3);
00797 
00798         SaveMulAcc(10, 4, 7);
00799         MulAcc(5, 6);
00800         MulAcc(6, 5);
00801         MulAcc(7, 4);
00802 
00803         SaveMulAcc(11, 5, 7);
00804         MulAcc(6, 6);
00805         MulAcc(7, 5);
00806 
00807         SaveMulAcc(12, 6, 7);
00808         MulAcc(7, 6);
00809 
00810         R[13] = c;
00811         p = DWord::MultiplyAndAdd(A[7], B[7], d);
00812         R[14] = p.GetLowHalf();
00813         R[15] = e + p.GetHighHalf();
00814 }
00815 
00816 <span class="keywordtype">void</span> Portable::Multiply4Bottom(word *R, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B)
00817 {
00818         DWord p;
00819         word c, d, e;
00820 
00821         p = DWord::Multiply(A[0], B[0]);
00822         R[0] = p.GetLowHalf();
00823         c = p.GetHighHalf();
00824         d = e = 0;
00825 
00826         MulAcc(0, 1);
00827         MulAcc(1, 0);
00828 
00829         SaveMulAcc(1, 2, 0);
00830         MulAcc(1, 1);
00831         MulAcc(0, 2);
00832 
00833         R[2] = c;
00834         R[3] = d + A[0] * B[3] + A[1] * B[2] + A[2] * B[1] + A[3] * B[0];
00835 }
00836 
00837 <span class="keywordtype">void</span> Portable::Multiply8Bottom(word *R, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B)
00838 {
00839         DWord p;
00840         word c, d, e;
00841 
00842         p = DWord::Multiply(A[0], B[0]);
00843         R[0] = p.GetLowHalf();
00844         c = p.GetHighHalf();
00845         d = e = 0;
00846 
00847         MulAcc(0, 1);
00848         MulAcc(1, 0);
00849 
00850         SaveMulAcc(1, 2, 0);
00851         MulAcc(1, 1);
00852         MulAcc(0, 2);
00853 
00854         SaveMulAcc(2, 0, 3);
00855         MulAcc(1, 2);
00856         MulAcc(2, 1);
00857         MulAcc(3, 0);
00858 
00859         SaveMulAcc(3, 0, 4);
00860         MulAcc(1, 3);
00861         MulAcc(2, 2);
00862         MulAcc(3, 1);
00863         MulAcc(4, 0);
00864 
00865         SaveMulAcc(4, 0, 5);
00866         MulAcc(1, 4);
00867         MulAcc(2, 3);
00868         MulAcc(3, 2);
00869         MulAcc(4, 1);
00870         MulAcc(5, 0);
00871 
00872         SaveMulAcc(5, 0, 6);
00873         MulAcc(1, 5);
00874         MulAcc(2, 4);
00875         MulAcc(3, 3);
00876         MulAcc(4, 2);
00877         MulAcc(5, 1);
00878         MulAcc(6, 0);
00879 
00880         R[6] = c;
00881         R[7] = d + A[0] * B[7] + A[1] * B[6] + A[2] * B[5] + A[3] * B[4] +
00882                                 A[4] * B[3] + A[5] * B[2] + A[6] * B[1] + A[7] * B[0];
00883 }
00884 
00885 <span class="preprocessor">#undef MulAcc</span>
00886 <span class="preprocessor"></span><span class="preprocessor">#undef SaveMulAcc</span>
00887 <span class="preprocessor"></span><span class="preprocessor">#undef SquAcc</span>
00888 <span class="preprocessor"></span><span class="preprocessor">#undef SaveSquAcc</span>
00889 <span class="preprocessor"></span>
00890 <span class="preprocessor">#ifdef CRYPTOPP_X86ASM_AVAILABLE</span>
00891 <span class="preprocessor"></span>
00892 <span class="comment">// ************** x86 feature detection ***************</span>
00893 
00894 <span class="keyword">static</span> <span class="keywordtype">bool</span> s_sse2Enabled = <span class="keyword">true</span>;
00895 
00896 <span class="keyword">static</span> <span class="keywordtype">void</span> CpuId(word32 input, word32 *output)
00897 {
00898 <span class="preprocessor">#ifdef __GNUC__</span>
00899 <span class="preprocessor"></span>        __asm__
00900         (
00901                 <span class="comment">// save ebx in case -fPIC is being used</span>
00902                 <span class="stringliteral">"push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx"</span>
00903                 : <span class="stringliteral">"=a"</span> (output[0]), <span class="stringliteral">"=D"</span> (output[1]), <span class="stringliteral">"=c"</span> (output[2]), <span class="stringliteral">"=d"</span> (output[3])
00904                 : <span class="stringliteral">"a"</span> (input)
00905         );
00906 <span class="preprocessor">#else</span>
00907 <span class="preprocessor"></span>        __asm
00908         {
00909                 mov eax, input
00910                 cpuid
00911                 mov edi, output
00912                 mov [edi], eax
00913                 mov [edi+4], ebx
00914                 mov [edi+8], ecx
00915                 mov [edi+12], edx
00916         }
00917 <span class="preprocessor">#endif</span>
00918 <span class="preprocessor"></span>}
00919 
00920 <span class="preprocessor">#ifdef SSE2_INTRINSICS_AVAILABLE</span>
00921 <span class="preprocessor"></span><span class="preprocessor">#ifndef _MSC_VER</span>
00922 <span class="preprocessor"></span><span class="keyword">static</span> jmp_buf s_env;
00923 <span class="keyword">static</span> <span class="keywordtype">void</span> SigIllHandler(<span class="keywordtype">int</span>)
00924 {
00925         longjmp(s_env, 1);
00926 }
00927 <span class="preprocessor">#endif</span>
00928 <span class="preprocessor"></span>
00929 <span class="keyword">static</span> <span class="keywordtype">bool</span> HasSSE2()
00930 {
00931         <span class="keywordflow">if</span> (!s_sse2Enabled)
00932                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
00933 
00934         word32 cpuid[4];
00935         CpuId(1, cpuid);
00936         <span class="keywordflow">if</span> ((cpuid[3] &amp; (1 &lt;&lt; 26)) == 0)
00937                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
00938 
00939 <span class="preprocessor">#ifdef _MSC_VER</span>
00940 <span class="preprocessor"></span>    __try
00941         {
00942         __asm xorpd xmm0, xmm0        <span class="comment">// executing SSE2 instruction</span>
00943         }
00944     __except (1)
00945         {
00946                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
00947     }
00948         <span class="keywordflow">return</span> <span class="keyword">true</span>;
00949 <span class="preprocessor">#else</span>
00950 <span class="preprocessor"></span>        <span class="keyword">typedef</span> void (*SigHandler)(<span class="keywordtype">int</span>);
00951 
00952         SigHandler oldHandler = signal(SIGILL, SigIllHandler);
00953         <span class="keywordflow">if</span> (oldHandler == SIG_ERR)
00954                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
00955 
00956         <span class="keywordtype">bool</span> result = <span class="keyword">true</span>;
00957         <span class="keywordflow">if</span> (setjmp(s_env))
00958                 result = <span class="keyword">false</span>;
00959         <span class="keywordflow">else</span>
00960                 __asm __volatile (<span class="stringliteral">"xorps %xmm0, %xmm0"</span>);
00961 
00962         signal(SIGILL, oldHandler);
00963         <span class="keywordflow">return</span> result;
00964 <span class="preprocessor">#endif</span>
00965 <span class="preprocessor"></span>}
00966 <span class="preprocessor">#endif</span>
00967 <span class="preprocessor"></span>
00968 <span class="keyword">static</span> <span class="keywordtype">bool</span> IsP4()
00969 {
00970         word32 cpuid[4];
00971 
00972         CpuId(0, cpuid);
00973         std::swap(cpuid[2], cpuid[3]);
00974         <span class="keywordflow">if</span> (memcmp(cpuid+1, <span class="stringliteral">"GenuineIntel"</span>, 12) != 0)
00975                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
00976 
00977         CpuId(1, cpuid);
00978         <span class="keywordflow">return</span> ((cpuid[0] &gt;&gt; 8) &amp; 0xf) == 0xf;
00979 }
00980 
00981 <span class="comment">// ************** Pentium/P4 optimizations ***************</span>
00982 
00983 <span class="keyword">class </span>PentiumOptimized : <span class="keyword">public</span> Portable
00984 {
00985 <span class="keyword">public</span>:
00986         <span class="keyword">static</span> word CRYPTOPP_CDECL Add(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N);
00987         <span class="keyword">static</span> word CRYPTOPP_CDECL Subtract(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N);
00988         <span class="keyword">static</span> <span class="keywordtype">void</span> CRYPTOPP_CDECL Multiply4(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B);
00989         <span class="keyword">static</span> <span class="keywordtype">void</span> CRYPTOPP_CDECL Multiply8(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B);
00990         <span class="keyword">static</span> <span class="keywordtype">void</span> CRYPTOPP_CDECL Multiply8Bottom(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B);
00991 };
00992 
00993 <span class="keyword">class </span>P4Optimized
00994 {
00995 <span class="keyword">public</span>:
00996         <span class="keyword">static</span> word CRYPTOPP_CDECL Add(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N);
00997         <span class="keyword">static</span> word CRYPTOPP_CDECL Subtract(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N);
00998 <span class="preprocessor">#ifdef SSE2_INTRINSICS_AVAILABLE</span>
00999 <span class="preprocessor"></span>        <span class="keyword">static</span> <span class="keywordtype">void</span> CRYPTOPP_CDECL Multiply4(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B);
01000         <span class="keyword">static</span> <span class="keywordtype">void</span> CRYPTOPP_CDECL Multiply8(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B);
01001         <span class="keyword">static</span> <span class="keywordtype">void</span> CRYPTOPP_CDECL Multiply8Bottom(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B);
01002 <span class="preprocessor">#endif</span>
01003 <span class="preprocessor"></span>};
01004 
01005 <span class="keyword">typedef</span> word (CRYPTOPP_CDECL * PAddSub)(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N);
01006 <span class="keyword">typedef</span> void (CRYPTOPP_CDECL * PMul)(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B);
01007 
01008 <span class="keyword">static</span> PAddSub s_pAdd, s_pSub;
01009 <span class="preprocessor">#ifdef SSE2_INTRINSICS_AVAILABLE</span>
01010 <span class="preprocessor"></span><span class="keyword">static</span> PMul s_pMul4, s_pMul8, s_pMul8B;
01011 <span class="preprocessor">#endif</span>
01012 <span class="preprocessor"></span>
01013 <span class="keyword">static</span> <span class="keywordtype">void</span> SetPentiumFunctionPointers()
01014 {
01015         <span class="keywordflow">if</span> (IsP4())
01016         {
01017                 s_pAdd = &amp;P4Optimized::Add;
01018                 s_pSub = &amp;P4Optimized::Subtract;
01019         }
01020         <span class="keywordflow">else</span>
01021         {
01022                 s_pAdd = &amp;PentiumOptimized::Add;
01023                 s_pSub = &amp;PentiumOptimized::Subtract;
01024         }
01025 
01026 <span class="preprocessor">#ifdef SSE2_INTRINSICS_AVAILABLE</span>
01027 <span class="preprocessor"></span>        <span class="keywordflow">if</span> (HasSSE2())
01028         {
01029                 s_pMul4 = &amp;P4Optimized::Multiply4;
01030                 s_pMul8 = &amp;P4Optimized::Multiply8;
01031                 s_pMul8B = &amp;P4Optimized::Multiply8Bottom;
01032         }
01033         <span class="keywordflow">else</span>
01034         {
01035                 s_pMul4 = &amp;PentiumOptimized::Multiply4;
01036                 s_pMul8 = &amp;PentiumOptimized::Multiply8;
01037                 s_pMul8B = &amp;PentiumOptimized::Multiply8Bottom;
01038         }
01039 <span class="preprocessor">#endif</span>
01040 <span class="preprocessor"></span>}
01041 
01042 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span> s_RunAtStartupSetPentiumFunctionPointers = (SetPentiumFunctionPointers(), 0);
01043 
01044 <span class="keywordtype">void</span> DisableSSE2()
01045 {
01046         s_sse2Enabled = <span class="keyword">false</span>;
01047         SetPentiumFunctionPointers();
01048 }
01049 
01050 <span class="keyword">class </span>LowLevel : <span class="keyword">public</span> PentiumOptimized
01051 {
01052 <span class="keyword">public</span>:
01053         <span class="keyword">inline</span> <span class="keyword">static</span> word Add(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
01054                 {<span class="keywordflow">return</span> s_pAdd(C, A, B, N);}
01055         <span class="keyword">inline</span> <span class="keyword">static</span> word Subtract(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
01056                 {<span class="keywordflow">return</span> s_pSub(C, A, B, N);}
01057         <span class="keyword">inline</span> <span class="keyword">static</span> <span class="keywordtype">void</span> Square4(word *R, <span class="keyword">const</span> word *A)
01058                 {Multiply4(R, A, A);}
01059 <span class="preprocessor">#ifdef SSE2_INTRINSICS_AVAILABLE</span>
01060 <span class="preprocessor"></span>        <span class="keyword">inline</span> <span class="keyword">static</span> <span class="keywordtype">void</span> Multiply4(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B)
01061                 {s_pMul4(C, A, B);}
01062         <span class="keyword">inline</span> <span class="keyword">static</span> <span class="keywordtype">void</span> Multiply8(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B)
01063                 {s_pMul8(C, A, B);}
01064         <span class="keyword">inline</span> <span class="keyword">static</span> <span class="keywordtype">void</span> Multiply8Bottom(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B)
01065                 {s_pMul8B(C, A, B);}
01066 <span class="preprocessor">#endif</span>
01067 <span class="preprocessor"></span>};
01068 
01069 <span class="comment">// use some tricks to share assembly code between MSVC and GCC</span>
01070 <span class="preprocessor">#ifdef _MSC_VER</span>
01071 <span class="preprocessor"></span><span class="preprocessor">        #define CRYPTOPP_NAKED __declspec(naked)</span>
01072 <span class="preprocessor"></span><span class="preprocessor">        #define AS1(x) __asm x</span>
01073 <span class="preprocessor"></span><span class="preprocessor">        #define AS2(x, y) __asm x, y</span>
01074 <span class="preprocessor"></span><span class="preprocessor">        #define AddPrologue \</span>
01075 <span class="preprocessor">                __asm   push ebp \</span>
01076 <span class="preprocessor">                __asm   push ebx \</span>
01077 <span class="preprocessor">                __asm   push esi \</span>
01078 <span class="preprocessor">                __asm   push edi \</span>
01079 <span class="preprocessor">                __asm   mov             ecx, [esp+20] \</span>
01080 <span class="preprocessor">                __asm   mov             edx, [esp+24] \</span>
01081 <span class="preprocessor">                __asm   mov             ebx, [esp+28] \</span>
01082 <span class="preprocessor">                __asm   mov             esi, [esp+32]</span>
01083 <span class="preprocessor"></span><span class="preprocessor">        #define AddEpilogue \</span>
01084 <span class="preprocessor">                __asm   pop edi \</span>
01085 <span class="preprocessor">                __asm   pop esi \</span>
01086 <span class="preprocessor">                __asm   pop ebx \</span>
01087 <span class="preprocessor">                __asm   pop ebp \</span>
01088 <span class="preprocessor">                __asm   ret</span>
01089 <span class="preprocessor"></span><span class="preprocessor">        #define MulPrologue \</span>
01090 <span class="preprocessor">                __asm   push ebp \</span>
01091 <span class="preprocessor">                __asm   push ebx \</span>
01092 <span class="preprocessor">                __asm   push esi \</span>
01093 <span class="preprocessor">                __asm   push edi \</span>
01094 <span class="preprocessor">                __asm   mov ecx, [esp+28] \</span>
01095 <span class="preprocessor">                __asm   mov esi, [esp+24] \</span>
01096 <span class="preprocessor">                __asm   push [esp+20]</span>
01097 <span class="preprocessor"></span><span class="preprocessor">        #define MulEpilogue \</span>
01098 <span class="preprocessor">                __asm   add esp, 4 \</span>
01099 <span class="preprocessor">                __asm   pop edi \</span>
01100 <span class="preprocessor">                __asm   pop esi \</span>
01101 <span class="preprocessor">                __asm   pop ebx \</span>
01102 <span class="preprocessor">                __asm   pop ebp \</span>
01103 <span class="preprocessor">                __asm   ret</span>
01104 <span class="preprocessor"></span><span class="preprocessor">#else</span>
01105 <span class="preprocessor"></span><span class="preprocessor">        #define CRYPTOPP_NAKED</span>
01106 <span class="preprocessor"></span><span class="preprocessor">        #define AS1(x) #x ";"</span>
01107 <span class="preprocessor"></span><span class="preprocessor">        #define AS2(x, y) #x ", " #y ";"</span>
01108 <span class="preprocessor"></span><span class="preprocessor">        #define AddPrologue \</span>
01109 <span class="preprocessor">                __asm__ __volatile__ \</span>
01110 <span class="preprocessor">                ( \</span>
01111 <span class="preprocessor">                        "push %%ebx;"   </span><span class="comment">/* save this manually, in case of -fPIC */</span> \
01112                         "mov %2, %%ebx;" \
01113                         ".intel_syntax noprefix;" \
01114                         "push ebp;"
01115 <span class="preprocessor">        #define AddEpilogue \</span>
01116 <span class="preprocessor">                        "pop ebp;" \</span>
01117 <span class="preprocessor">                        ".att_syntax prefix;" \</span>
01118 <span class="preprocessor">                        "pop %%ebx;" \</span>
01119 <span class="preprocessor">                                        : \</span>
01120 <span class="preprocessor">                                        : "c" (C), "d" (A), "m" (B), "S" (N) \</span>
01121 <span class="preprocessor">                                        : "%edi", "memory", "cc" \</span>
01122 <span class="preprocessor">                );</span>
01123 <span class="preprocessor"></span><span class="preprocessor">        #define MulPrologue \</span>
01124 <span class="preprocessor">                __asm__ __volatile__ \</span>
01125 <span class="preprocessor">                ( \</span>
01126 <span class="preprocessor">                        "push %%ebx;"   </span><span class="comment">/* save this manually, in case of -fPIC */</span> \
01127                         "push %%ebp;" \
01128                         "push %0;" \
01129                         ".intel_syntax noprefix;"
01130 <span class="preprocessor">        #define MulEpilogue \</span>
01131 <span class="preprocessor">                        "add esp, 4;" \</span>
01132 <span class="preprocessor">                        "pop ebp;" \</span>
01133 <span class="preprocessor">                        "pop ebx;" \</span>
01134 <span class="preprocessor">                        ".att_syntax prefix;" \</span>
01135 <span class="preprocessor">                        : \</span>
01136 <span class="preprocessor">                        : "rm" (Z), "S" (X), "c" (Y) \</span>
01137 <span class="preprocessor">                        : "%eax", "%edx", "%edi", "memory", "cc" \</span>
01138 <span class="preprocessor">                );</span>
01139 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
01140 <span class="preprocessor"></span>
01141 CRYPTOPP_NAKED word PentiumOptimized::Add(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
01142 {
01143         AddPrologue
01144 
01145         <span class="comment">// now: ebx = B, ecx = C, edx = A, esi = N</span>
01146         AS2(    sub ecx, edx)   <span class="comment">// hold the distance between C &amp; A so we can add this to A to get C</span>
01147         AS2(    xor eax, eax)   <span class="comment">// clear eax</span>
01148 
01149         AS2(    sub eax, esi)   <span class="comment">// eax is a negative index from end of B</span>
01150         AS2(    lea ebx, [ebx+4*esi])   <span class="comment">// ebx is end of B</span>
01151 
01152         AS2(    sar eax, 1)             <span class="comment">// unit of eax is now dwords; this also clears the carry flag</span>
01153         AS1(    jz      loopendAdd)             <span class="comment">// if no dwords then nothing to do</span>
01154 
01155         AS1(loopstartAdd:)
01156         AS2(    mov    esi,[edx])                       <span class="comment">// load lower word of A</span>
01157         AS2(    mov    ebp,[edx+4])                     <span class="comment">// load higher word of A</span>
01158 
01159         AS2(    mov    edi,[ebx+8*eax])         <span class="comment">// load lower word of B</span>
01160         AS2(    lea    edx,[edx+8])                     <span class="comment">// advance A and C</span>
01161 
01162         AS2(    adc    esi,edi)                         <span class="comment">// add lower words</span>
01163         AS2(    mov    edi,[ebx+8*eax+4])       <span class="comment">// load higher word of B</span>
01164 
01165         AS2(    adc    ebp,edi)                         <span class="comment">// add higher words</span>
01166         AS1(    inc    eax)                                     <span class="comment">// advance B</span>
01167 
01168         AS2(    mov    [edx+ecx-8],esi)         <span class="comment">// store lower word result</span>
01169         AS2(    mov    [edx+ecx-4],ebp)         <span class="comment">// store higher word result</span>
01170 
01171         AS1(    jnz    loopstartAdd)                    <span class="comment">// loop until eax overflows and becomes zero</span>
01172 
01173         AS1(loopendAdd:)
01174         AS2(    adc eax, 0)             <span class="comment">// store carry into eax (return result register)</span>
01175 
01176         AddEpilogue
01177 }
01178 
01179 CRYPTOPP_NAKED word PentiumOptimized::Subtract(word *C, const word *A, const word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
01180 {
01181         AddPrologue
01182 
01183         <span class="comment">// now: ebx = B, ecx = C, edx = A, esi = N</span>
01184         AS2(    sub ecx, edx)   <span class="comment">// hold the distance between C &amp; A so we can add this to A to get C</span>
01185         AS2(    xor eax, eax)   <span class="comment">// clear eax</span>
01186 
01187         AS2(    sub eax, esi)   <span class="comment">// eax is a negative index from end of B</span>
01188         AS2(    lea ebx, [ebx+4*esi])   <span class="comment">// ebx is end of B</span>
01189 
01190         AS2(    sar eax, 1)             <span class="comment">// unit of eax is now dwords; this also clears the carry flag</span>
01191         AS1(    jz      loopendSub)             <span class="comment">// if no dwords then nothing to do</span>
01192 
01193         AS1(loopstartSub:)
01194         AS2(    mov    esi,[edx])                       <span class="comment">// load lower word of A</span>
01195         AS2(    mov    ebp,[edx+4])                     <span class="comment">// load higher word of A</span>
01196 
01197         AS2(    mov    edi,[ebx+8*eax])         <span class="comment">// load lower word of B</span>
01198         AS2(    lea    edx,[edx+8])                     <span class="comment">// advance A and C</span>
01199 
01200         AS2(    sbb    esi,edi)                         <span class="comment">// subtract lower words</span>
01201         AS2(    mov    edi,[ebx+8*eax+4])       <span class="comment">// load higher word of B</span>
01202 
01203         AS2(    sbb    ebp,edi)                         <span class="comment">// subtract higher words</span>
01204         AS1(    inc    eax)                                     <span class="comment">// advance B</span>
01205 
01206         AS2(    mov    [edx+ecx-8],esi)         <span class="comment">// store lower word result</span>
01207         AS2(    mov    [edx+ecx-4],ebp)         <span class="comment">// store higher word result</span>
01208 
01209         AS1(    jnz    loopstartSub)                    <span class="comment">// loop until eax overflows and becomes zero</span>
01210 
01211         AS1(loopendSub:)
01212         AS2(    adc eax, 0)             <span class="comment">// store carry into eax (return result register)</span>
01213 
01214         AddEpilogue
01215 }
01216 
01217 <span class="comment">// On Pentium 4, the adc and sbb instructions are very expensive, so avoid them.</span>
01218 
01219 CRYPTOPP_NAKED word P4Optimized::Add(word *C, const word *A, const word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
01220 {
01221         AddPrologue
01222 
01223         <span class="comment">// now: ebx = B, ecx = C, edx = A, esi = N</span>
01224         AS2(    xor             eax, eax)
01225         AS1(    neg             esi)
01226         AS1(    jz              loopendAddP4)           <span class="comment">// if no dwords then nothing to do</span>
01227 
01228         AS2(    mov             edi, [edx])
01229         AS2(    mov             ebp, [ebx])
01230         AS1(    jmp             carry1AddP4)
01231 
01232         AS1(loopstartAddP4:)
01233         AS2(    mov             edi, [edx+8])
01234         AS2(    add             ecx, 8)
01235         AS2(    add             edx, 8)
01236         AS2(    mov             ebp, [ebx])
01237         AS2(    add             edi, eax)
01238         AS1(    jc              carry1AddP4)
01239         AS2(    xor             eax, eax)
01240 
01241         AS1(carry1AddP4:)
01242         AS2(    add             edi, ebp)
01243         AS2(    mov             ebp, 1)
01244         AS2(    mov             [ecx], edi)
01245         AS2(    mov             edi, [edx+4])
01246         AS2(    cmovc   eax, ebp)
01247         AS2(    mov             ebp, [ebx+4])
01248         AS2(    add             ebx, 8)
01249         AS2(    add             edi, eax)
01250         AS1(    jc              carry2AddP4)
01251         AS2(    xor             eax, eax)
01252 
01253         AS1(carry2AddP4:)
01254         AS2(    add             edi, ebp)
01255         AS2(    mov             ebp, 1)
01256         AS2(    cmovc   eax, ebp)
01257         AS2(    mov             [ecx+4], edi)
01258         AS2(    add             esi, 2)
01259         AS1(    jnz             loopstartAddP4)
01260 
01261         AS1(loopendAddP4:)
01262 
01263         AddEpilogue
01264 }
01265 
01266 CRYPTOPP_NAKED word P4Optimized::Subtract(word *C, const word *A, const word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
01267 {
01268         AddPrologue
01269 
01270         <span class="comment">// now: ebx = B, ecx = C, edx = A, esi = N</span>
01271         AS2(    xor             eax, eax)
01272         AS1(    neg             esi)
01273         AS1(    jz              loopendSubP4)           <span class="comment">// if no dwords then nothing to do</span>
01274 
01275         AS2(    mov             edi, [edx])
01276         AS2(    mov             ebp, [ebx])
01277         AS1(    jmp             carry1SubP4)
01278 
01279         AS1(loopstartSubP4:)
01280         AS2(    mov             edi, [edx+8])
01281         AS2(    add             edx, 8)
01282         AS2(    add             ecx, 8)
01283         AS2(    mov             ebp, [ebx])
01284         AS2(    sub             edi, eax)
01285         AS1(    jc              carry1SubP4)
01286         AS2(    xor             eax, eax)
01287 
01288         AS1(carry1SubP4:)
01289         AS2(    sub             edi, ebp)
01290         AS2(    mov             ebp, 1)
01291         AS2(    mov             [ecx], edi)
01292         AS2(    mov             edi, [edx+4])
01293         AS2(    cmovc   eax, ebp)
01294         AS2(    mov             ebp, [ebx+4])
01295         AS2(    add             ebx, 8)
01296         AS2(    sub             edi, eax)
01297         AS1(    jc              carry2SubP4)
01298         AS2(    xor             eax, eax)
01299 
01300         AS1(carry2SubP4:)
01301         AS2(    sub             edi, ebp)
01302         AS2(    mov             ebp, 1)
01303         AS2(    cmovc   eax, ebp)
01304         AS2(    mov             [ecx+4], edi)
01305         AS2(    add             esi, 2)
01306         AS1(    jnz             loopstartSubP4)
01307 
01308         AS1(loopendSubP4:)
01309 
01310         AddEpilogue
01311 }
01312 
01313 <span class="comment">// multiply assembly code originally contributed by Leonard Janke</span>
01314 
01315 #define MulStartup \
01316         AS2(xor ebp, ebp) \
01317         AS2(xor edi, edi) \
01318         AS2(xor ebx, ebx) 
01319 
01320 #define MulShiftCarry \
01321         AS2(mov ebp, edx) \
01322         AS2(mov edi, ebx) \
01323         AS2(xor ebx, ebx)
01324 
01325 #define MulAccumulateBottom(i,j) \
01326         AS2(mov eax, [ecx+4*j]) \
01327         AS2(imul eax, dword ptr [esi+4*i]) \
01328         AS2(add ebp, eax)
01329 
01330 #define MulAccumulate(i,j) \
01331         AS2(mov eax, [ecx+4*j]) \
01332         AS1(mul dword ptr [esi+4*i]) \
01333         AS2(add ebp, eax) \
01334         AS2(adc edi, edx) \
01335         AS2(adc bl, bh)
01336 
01337 #define MulStoreDigit(i)  \
01338         AS2(mov edx, edi) \
01339         AS2(mov edi, [esp]) \
01340         AS2(mov [edi+4*i], ebp)
01341 
01342 #define MulLastDiagonal(digits) \
01343         AS2(mov eax, [ecx+4*(digits-1)]) \
01344         AS1(mul dword ptr [esi+4*(digits-1)]) \
01345         AS2(add ebp, eax) \
01346         AS2(adc edx, edi) \
01347         AS2(mov edi, [esp]) \
01348         AS2(mov [edi+4*(2*digits-2)], ebp) \
01349         AS2(mov [edi+4*(2*digits-1)], edx)
01350 
01351 CRYPTOPP_NAKED <span class="keywordtype">void</span> PentiumOptimized::Multiply4(word* Z, const word* X, const word* Y)
01352 {
01353         MulPrologue
01354         <span class="comment">// now: [esp] = Z, esi = X, ecx = Y</span>
01355         MulStartup
01356         MulAccumulate(0,0)
01357         MulStoreDigit(0)
01358         MulShiftCarry
01359 
01360         MulAccumulate(1,0)
01361         MulAccumulate(0,1)
01362         MulStoreDigit(1)
01363         MulShiftCarry
01364 
01365         MulAccumulate(2,0)
01366         MulAccumulate(1,1)
01367         MulAccumulate(0,2)
01368         MulStoreDigit(2)
01369         MulShiftCarry
01370 
01371         MulAccumulate(3,0)
01372         MulAccumulate(2,1)
01373         MulAccumulate(1,2)
01374         MulAccumulate(0,3)
01375         MulStoreDigit(3)
01376         MulShiftCarry
01377 
01378         MulAccumulate(3,1)
01379         MulAccumulate(2,2)
01380         MulAccumulate(1,3)
01381         MulStoreDigit(4)
01382         MulShiftCarry
01383 
01384         MulAccumulate(3,2)
01385         MulAccumulate(2,3)
01386         MulStoreDigit(5)
01387         MulShiftCarry
01388 
01389         MulLastDiagonal(4)
01390         MulEpilogue
01391 }
01392 
01393 CRYPTOPP_NAKED <span class="keywordtype">void</span> PentiumOptimized::Multiply8(word* Z, const word* X, const word* Y)
01394 {
01395         MulPrologue
01396         <span class="comment">// now: [esp] = Z, esi = X, ecx = Y</span>
01397         MulStartup
01398         MulAccumulate(0,0)
01399         MulStoreDigit(0)
01400         MulShiftCarry
01401 
01402         MulAccumulate(1,0)
01403         MulAccumulate(0,1)
01404         MulStoreDigit(1)
01405         MulShiftCarry
01406 
01407         MulAccumulate(2,0)
01408         MulAccumulate(1,1)
01409         MulAccumulate(0,2)
01410         MulStoreDigit(2)
01411         MulShiftCarry
01412 
01413         MulAccumulate(3,0)
01414         MulAccumulate(2,1)
01415         MulAccumulate(1,2)
01416         MulAccumulate(0,3)
01417         MulStoreDigit(3)
01418         MulShiftCarry
01419 
01420         MulAccumulate(4,0)
01421         MulAccumulate(3,1)
01422         MulAccumulate(2,2)
01423         MulAccumulate(1,3)
01424         MulAccumulate(0,4)
01425         MulStoreDigit(4)
01426         MulShiftCarry
01427 
01428         MulAccumulate(5,0)
01429         MulAccumulate(4,1)
01430         MulAccumulate(3,2)
01431         MulAccumulate(2,3)
01432         MulAccumulate(1,4)
01433         MulAccumulate(0,5)
01434         MulStoreDigit(5)
01435         MulShiftCarry
01436 
01437         MulAccumulate(6,0)
01438         MulAccumulate(5,1)
01439         MulAccumulate(4,2)
01440         MulAccumulate(3,3)
01441         MulAccumulate(2,4)
01442         MulAccumulate(1,5)
01443         MulAccumulate(0,6)
01444         MulStoreDigit(6)
01445         MulShiftCarry
01446 
01447         MulAccumulate(7,0)
01448         MulAccumulate(6,1)
01449         MulAccumulate(5,2)
01450         MulAccumulate(4,3)
01451         MulAccumulate(3,4)
01452         MulAccumulate(2,5)
01453         MulAccumulate(1,6)
01454         MulAccumulate(0,7)
01455         MulStoreDigit(7)
01456         MulShiftCarry
01457 
01458         MulAccumulate(7,1)
01459         MulAccumulate(6,2)
01460         MulAccumulate(5,3)
01461         MulAccumulate(4,4)
01462         MulAccumulate(3,5)
01463         MulAccumulate(2,6)
01464         MulAccumulate(1,7)
01465         MulStoreDigit(8)
01466         MulShiftCarry
01467 
01468         MulAccumulate(7,2)
01469         MulAccumulate(6,3)
01470         MulAccumulate(5,4)
01471         MulAccumulate(4,5)
01472         MulAccumulate(3,6)
01473         MulAccumulate(2,7)
01474         MulStoreDigit(9)
01475         MulShiftCarry
01476 
01477         MulAccumulate(7,3)
01478         MulAccumulate(6,4)
01479         MulAccumulate(5,5)
01480         MulAccumulate(4,6)
01481         MulAccumulate(3,7)
01482         MulStoreDigit(10)
01483         MulShiftCarry
01484 
01485         MulAccumulate(7,4)
01486         MulAccumulate(6,5)
01487         MulAccumulate(5,6)
01488         MulAccumulate(4,7)
01489         MulStoreDigit(11)
01490         MulShiftCarry
01491 
01492         MulAccumulate(7,5)
01493         MulAccumulate(6,6)
01494         MulAccumulate(5,7)
01495         MulStoreDigit(12)
01496         MulShiftCarry
01497 
01498         MulAccumulate(7,6)
01499         MulAccumulate(6,7)
01500         MulStoreDigit(13)
01501         MulShiftCarry
01502 
01503         MulLastDiagonal(8)
01504         MulEpilogue
01505 }
01506 
01507 CRYPTOPP_NAKED <span class="keywordtype">void</span> PentiumOptimized::Multiply8Bottom(word* Z, const word* X, const word* Y)
01508 {
01509         MulPrologue
01510         <span class="comment">// now: [esp] = Z, esi = X, ecx = Y</span>
01511         MulStartup
01512         MulAccumulate(0,0)
01513         MulStoreDigit(0)
01514         MulShiftCarry
01515 
01516         MulAccumulate(1,0)
01517         MulAccumulate(0,1)
01518         MulStoreDigit(1)
01519         MulShiftCarry
01520 
01521         MulAccumulate(2,0)
01522         MulAccumulate(1,1)
01523         MulAccumulate(0,2)
01524         MulStoreDigit(2)
01525         MulShiftCarry
01526 
01527         MulAccumulate(3,0)
01528         MulAccumulate(2,1)
01529         MulAccumulate(1,2)
01530         MulAccumulate(0,3)
01531         MulStoreDigit(3)
01532         MulShiftCarry
01533 
01534         MulAccumulate(4,0)
01535         MulAccumulate(3,1)
01536         MulAccumulate(2,2)
01537         MulAccumulate(1,3)
01538         MulAccumulate(0,4)
01539         MulStoreDigit(4)
01540         MulShiftCarry
01541 
01542         MulAccumulate(5,0)
01543         MulAccumulate(4,1)
01544         MulAccumulate(3,2)
01545         MulAccumulate(2,3)
01546         MulAccumulate(1,4)
01547         MulAccumulate(0,5)
01548         MulStoreDigit(5)
01549         MulShiftCarry
01550 
01551         MulAccumulate(6,0)
01552         MulAccumulate(5,1)
01553         MulAccumulate(4,2)
01554         MulAccumulate(3,3)
01555         MulAccumulate(2,4)
01556         MulAccumulate(1,5)
01557         MulAccumulate(0,6)
01558         MulStoreDigit(6)
01559         MulShiftCarry
01560 
01561         MulAccumulateBottom(7,0)
01562         MulAccumulateBottom(6,1)
01563         MulAccumulateBottom(5,2)
01564         MulAccumulateBottom(4,3)
01565         MulAccumulateBottom(3,4)
01566         MulAccumulateBottom(2,5)
01567         MulAccumulateBottom(1,6)
01568         MulAccumulateBottom(0,7)
01569         MulStoreDigit(7)
01570         MulEpilogue
01571 }
01572 
01573 #undef AS1
01574 #undef AS2
01575 
01576 #else   <span class="comment">// not x86 - no processor specific code at this layer</span>
01577 
01578 typedef Portable LowLevel;
01579 
01580 #endif
01581 
01582 #ifdef SSE2_INTRINSICS_AVAILABLE
01583 
01584 #ifdef __GNUC__
01585 #define CRYPTOPP_FASTCALL
01586 #else
01587 #define CRYPTOPP_FASTCALL __fastcall
01588 #endif
01589 
01590 static <span class="keywordtype">void</span> CRYPTOPP_FASTCALL P4_Mul(__m128i *C, const __m128i *A, const __m128i *B)
01591 {
01592         __m128i a3210 = _mm_load_si128(A);
01593         __m128i b3210 = _mm_load_si128(B);
01594 
01595         __m128i sum;
01596 
01597         __m128i z = _mm_setzero_si128();
01598         __m128i a2b2_a0b0 = _mm_mul_epu32(a3210, b3210);
01599         C[0] = a2b2_a0b0;
01600 
01601         __m128i a3120 = _mm_shuffle_epi32(a3210, _MM_SHUFFLE(3, 1, 2, 0));
01602         __m128i b3021 = _mm_shuffle_epi32(b3210, _MM_SHUFFLE(3, 0, 2, 1));
01603         __m128i a1b0_a0b1 = _mm_mul_epu32(a3120, b3021);
01604         __m128i a1b0 = _mm_unpackhi_epi32(a1b0_a0b1, z);
01605         __m128i a0b1 = _mm_unpacklo_epi32(a1b0_a0b1, z);
01606         C[1] = _mm_add_epi64(a1b0, a0b1);
01607 
01608         __m128i a31 = _mm_srli_epi64(a3210, 32);
01609         __m128i b31 = _mm_srli_epi64(b3210, 32);
01610         __m128i a3b3_a1b1 = _mm_mul_epu32(a31, b31);
01611         C[6] = a3b3_a1b1;
01612 
01613         __m128i a1b1 = _mm_unpacklo_epi32(a3b3_a1b1, z);
01614         __m128i b3012 = _mm_shuffle_epi32(b3210, _MM_SHUFFLE(3, 0, 1, 2));
01615         __m128i a2b0_a0b2 = _mm_mul_epu32(a3210, b3012);
01616         __m128i a0b2 = _mm_unpacklo_epi32(a2b0_a0b2, z);
01617         __m128i a2b0 = _mm_unpackhi_epi32(a2b0_a0b2, z);
01618         sum = _mm_add_epi64(a1b1, a0b2);
01619         C[2] = _mm_add_epi64(sum, a2b0);
01620 
01621         __m128i a2301 = _mm_shuffle_epi32(a3210, _MM_SHUFFLE(2, 3, 0, 1));
01622         __m128i b2103 = _mm_shuffle_epi32(b3210, _MM_SHUFFLE(2, 1, 0, 3));
01623         __m128i a3b0_a1b2 = _mm_mul_epu32(a2301, b3012);
01624         __m128i a2b1_a0b3 = _mm_mul_epu32(a3210, b2103);
01625         __m128i a3b0 = _mm_unpackhi_epi32(a3b0_a1b2, z);
01626         __m128i a1b2 = _mm_unpacklo_epi32(a3b0_a1b2, z);
01627         __m128i a2b1 = _mm_unpackhi_epi32(a2b1_a0b3, z);
01628         __m128i a0b3 = _mm_unpacklo_epi32(a2b1_a0b3, z);
01629         __m128i sum1 = _mm_add_epi64(a3b0, a1b2);
01630         sum = _mm_add_epi64(a2b1, a0b3);
01631         C[3] = _mm_add_epi64(sum, sum1);
01632 
01633         __m128i a3b1_a1b3 = _mm_mul_epu32(a2301, b2103);
01634         __m128i a2b2 = _mm_unpackhi_epi32(a2b2_a0b0, z);
01635         __m128i a3b1 = _mm_unpackhi_epi32(a3b1_a1b3, z);
01636         __m128i a1b3 = _mm_unpacklo_epi32(a3b1_a1b3, z);
01637         sum = _mm_add_epi64(a2b2, a3b1);
01638         C[4] = _mm_add_epi64(sum, a1b3);
01639 
01640         __m128i a1302 = _mm_shuffle_epi32(a3210, _MM_SHUFFLE(1, 3, 0, 2));
01641         __m128i b1203 = _mm_shuffle_epi32(b3210, _MM_SHUFFLE(1, 2, 0, 3));
01642         __m128i a3b2_a2b3 = _mm_mul_epu32(a1302, b1203);
01643         __m128i a3b2 = _mm_unpackhi_epi32(a3b2_a2b3, z);
01644         __m128i a2b3 = _mm_unpacklo_epi32(a3b2_a2b3, z);
01645         C[5] = _mm_add_epi64(a3b2, a2b3);
01646 }
01647 
01648 <span class="keywordtype">void</span> P4Optimized::Multiply4(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B)
01649 {
01650         __m128i temp[7];
01651         <span class="keyword">const</span> word *w = (word *)temp;
01652         <span class="keyword">const</span> __m64 *mw = (__m64 *)w;
01653 
01654         P4_Mul(temp, (__m128i *)A, (__m128i *)B);
01655 
01656         C[0] = w[0];
01657 
01658         __m64 s1, s2;
01659 
01660         __m64 w1 = _mm_cvtsi32_si64(w[1]);
01661         __m64 w4 = mw[2];
01662         __m64 w6 = mw[3];
01663         __m64 w8 = mw[4];
01664         __m64 w10 = mw[5];
01665         __m64 w12 = mw[6];
01666         __m64 w14 = mw[7];
01667         __m64 w16 = mw[8];
01668         __m64 w18 = mw[9];
01669         __m64 w20 = mw[10];
01670         __m64 w22 = mw[11];
01671         __m64 w26 = _mm_cvtsi32_si64(w[26]);
01672 
01673         s1 = _mm_add_si64(w1, w4);
01674         C[1] = _mm_cvtsi64_si32(s1);
01675         s1 = _mm_srli_si64(s1, 32);
01676 
01677         s2 = _mm_add_si64(w6, w8);
01678         s1 = _mm_add_si64(s1, s2);
01679         C[2] = _mm_cvtsi64_si32(s1);
01680         s1 = _mm_srli_si64(s1, 32);
01681 
01682         s2 = _mm_add_si64(w10, w12);
01683         s1 = _mm_add_si64(s1, s2);
01684         C[3] = _mm_cvtsi64_si32(s1);
01685         s1 = _mm_srli_si64(s1, 32);
01686 
01687         s2 = _mm_add_si64(w14, w16);
01688         s1 = _mm_add_si64(s1, s2);
01689         C[4] = _mm_cvtsi64_si32(s1);
01690         s1 = _mm_srli_si64(s1, 32);
01691 
01692         s2 = _mm_add_si64(w18, w20);
01693         s1 = _mm_add_si64(s1, s2);
01694         C[5] = _mm_cvtsi64_si32(s1);
01695         s1 = _mm_srli_si64(s1, 32);
01696 
01697         s2 = _mm_add_si64(w22, w26);
01698         s1 = _mm_add_si64(s1, s2);
01699         C[6] = _mm_cvtsi64_si32(s1);
01700         s1 = _mm_srli_si64(s1, 32);
01701 
01702         C[7] = _mm_cvtsi64_si32(s1) + w[27];
01703         _mm_empty();
01704 }
01705 
01706 <span class="keywordtype">void</span> P4Optimized::Multiply8(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B)
01707 {
01708         __m128i temp[28];
01709         <span class="keyword">const</span> word *w = (word *)temp;
01710         <span class="keyword">const</span> __m64 *mw = (__m64 *)w;
01711         <span class="keyword">const</span> word *x = (word *)temp+7*4;
01712         <span class="keyword">const</span> __m64 *mx = (__m64 *)x;
01713         <span class="keyword">const</span> word *y = (word *)temp+7*4*2;
01714         <span class="keyword">const</span> __m64 *my = (__m64 *)y;
01715         <span class="keyword">const</span> word *z = (word *)temp+7*4*3;
01716         <span class="keyword">const</span> __m64 *mz = (__m64 *)z;
01717 
01718         P4_Mul(temp, (__m128i *)A, (__m128i *)B);
01719 
01720         P4_Mul(temp+7, (__m128i *)A+1, (__m128i *)B);
01721 
01722         P4_Mul(temp+14, (__m128i *)A, (__m128i *)B+1);
01723 
01724         P4_Mul(temp+21, (__m128i *)A+1, (__m128i *)B+1);
01725 
01726         C[0] = w[0];
01727 
01728         __m64 s1, s2, s3, s4;
01729 
01730         __m64 w1 = _mm_cvtsi32_si64(w[1]);
01731         __m64 w4 = mw[2];
01732         __m64 w6 = mw[3];
01733         __m64 w8 = mw[4];
01734         __m64 w10 = mw[5];
01735         __m64 w12 = mw[6];
01736         __m64 w14 = mw[7];
01737         __m64 w16 = mw[8];
01738         __m64 w18 = mw[9];
01739         __m64 w20 = mw[10];
01740         __m64 w22 = mw[11];
01741         __m64 w26 = _mm_cvtsi32_si64(w[26]);
01742         __m64 w27 = _mm_cvtsi32_si64(w[27]);
01743 
01744         __m64 x0 = _mm_cvtsi32_si64(x[0]);
01745         __m64 x1 = _mm_cvtsi32_si64(x[1]);
01746         __m64 x4 = mx[2];
01747         __m64 x6 = mx[3];
01748         __m64 x8 = mx[4];
01749         __m64 x10 = mx[5];
01750         __m64 x12 = mx[6];
01751         __m64 x14 = mx[7];
01752         __m64 x16 = mx[8];
01753         __m64 x18 = mx[9];
01754         __m64 x20 = mx[10];
01755         __m64 x22 = mx[11];
01756         __m64 x26 = _mm_cvtsi32_si64(x[26]);
01757         __m64 x27 = _mm_cvtsi32_si64(x[27]);
01758 
01759         __m64 y0 = _mm_cvtsi32_si64(y[0]);
01760         __m64 y1 = _mm_cvtsi32_si64(y[1]);
01761         __m64 y4 = my[2];
01762         __m64 y6 = my[3];
01763         __m64 y8 = my[4];
01764         __m64 y10 = my[5];
01765         __m64 y12 = my[6];
01766         __m64 y14 = my[7];
01767         __m64 y16 = my[8];
01768         __m64 y18 = my[9];
01769         __m64 y20 = my[10];
01770         __m64 y22 = my[11];
01771         __m64 y26 = _mm_cvtsi32_si64(y[26]);
01772         __m64 y27 = _mm_cvtsi32_si64(y[27]);
01773 
01774         __m64 z0 = _mm_cvtsi32_si64(z[0]);
01775         __m64 z1 = _mm_cvtsi32_si64(z[1]);
01776         __m64 z4 = mz[2];
01777         __m64 z6 = mz[3];
01778         __m64 z8 = mz[4];
01779         __m64 z10 = mz[5];
01780         __m64 z12 = mz[6];
01781         __m64 z14 = mz[7];
01782         __m64 z16 = mz[8];
01783         __m64 z18 = mz[9];
01784         __m64 z20 = mz[10];
01785         __m64 z22 = mz[11];
01786         __m64 z26 = _mm_cvtsi32_si64(z[26]);
01787 
01788         s1 = _mm_add_si64(w1, w4);
01789         C[1] = _mm_cvtsi64_si32(s1);
01790         s1 = _mm_srli_si64(s1, 32);
01791 
01792         s2 = _mm_add_si64(w6, w8);
01793         s1 = _mm_add_si64(s1, s2);
01794         C[2] = _mm_cvtsi64_si32(s1);
01795         s1 = _mm_srli_si64(s1, 32);
01796 
01797         s2 = _mm_add_si64(w10, w12);
01798         s1 = _mm_add_si64(s1, s2);
01799         C[3] = _mm_cvtsi64_si32(s1);
01800         s1 = _mm_srli_si64(s1, 32);
01801 
01802         s3 = _mm_add_si64(x0, y0);
01803         s2 = _mm_add_si64(w14, w16);
01804         s1 = _mm_add_si64(s1, s3);
01805         s1 = _mm_add_si64(s1, s2);
01806         C[4] = _mm_cvtsi64_si32(s1);
01807         s1 = _mm_srli_si64(s1, 32);
01808 
01809         s3 = _mm_add_si64(x1, y1);
01810         s4 = _mm_add_si64(x4, y4);
01811         s1 = _mm_add_si64(s1, w18);
01812         s3 = _mm_add_si64(s3, s4);
01813         s1 = _mm_add_si64(s1, w20);
01814         s1 = _mm_add_si64(s1, s3);
01815         C[5] = _mm_cvtsi64_si32(s1);
01816         s1 = _mm_srli_si64(s1, 32);
01817 
01818         s3 = _mm_add_si64(x6, y6);
01819         s4 = _mm_add_si64(x8, y8);
01820         s1 = _mm_add_si64(s1, w22);
01821         s3 = _mm_add_si64(s3, s4);
01822         s1 = _mm_add_si64(s1, w26);
01823         s1 = _mm_add_si64(s1, s3);
01824         C[6] = _mm_cvtsi64_si32(s1);
01825         s1 = _mm_srli_si64(s1, 32);
01826 
01827         s3 = _mm_add_si64(x10, y10);
01828         s4 = _mm_add_si64(x12, y12);
01829         s1 = _mm_add_si64(s1, w27);
01830         s3 = _mm_add_si64(s3, s4);
01831         s1 = _mm_add_si64(s1, s3);
01832         C[7] = _mm_cvtsi64_si32(s1);
01833         s1 = _mm_srli_si64(s1, 32);
01834 
01835         s3 = _mm_add_si64(x14, y14);
01836         s4 = _mm_add_si64(x16, y16);
01837         s1 = _mm_add_si64(s1, z0);
01838         s3 = _mm_add_si64(s3, s4);
01839         s1 = _mm_add_si64(s1, s3);
01840         C[8] = _mm_cvtsi64_si32(s1);
01841         s1 = _mm_srli_si64(s1, 32);
01842 
01843         s3 = _mm_add_si64(x18, y18);
01844         s4 = _mm_add_si64(x20, y20);
01845         s1 = _mm_add_si64(s1, z1);
01846         s3 = _mm_add_si64(s3, s4);
01847         s1 = _mm_add_si64(s1, z4);
01848         s1 = _mm_add_si64(s1, s3);
01849         C[9] = _mm_cvtsi64_si32(s1);
01850         s1 = _mm_srli_si64(s1, 32);
01851 
01852         s3 = _mm_add_si64(x22, y22);
01853         s4 = _mm_add_si64(x26, y26);
01854         s1 = _mm_add_si64(s1, z6);
01855         s3 = _mm_add_si64(s3, s4);
01856         s1 = _mm_add_si64(s1, z8);
01857         s1 = _mm_add_si64(s1, s3);
01858         C[10] = _mm_cvtsi64_si32(s1);
01859         s1 = _mm_srli_si64(s1, 32);
01860 
01861         s3 = _mm_add_si64(x27, y27);
01862         s1 = _mm_add_si64(s1, z10);
01863         s1 = _mm_add_si64(s1, z12);
01864         s1 = _mm_add_si64(s1, s3);
01865         C[11] = _mm_cvtsi64_si32(s1);
01866         s1 = _mm_srli_si64(s1, 32);
01867 
01868         s3 = _mm_add_si64(z14, z16);
01869         s1 = _mm_add_si64(s1, s3);
01870         C[12] = _mm_cvtsi64_si32(s1);
01871         s1 = _mm_srli_si64(s1, 32);
01872 
01873         s3 = _mm_add_si64(z18, z20);
01874         s1 = _mm_add_si64(s1, s3);
01875         C[13] = _mm_cvtsi64_si32(s1);
01876         s1 = _mm_srli_si64(s1, 32);
01877 
01878         s3 = _mm_add_si64(z22, z26);
01879         s1 = _mm_add_si64(s1, s3);
01880         C[14] = _mm_cvtsi64_si32(s1);
01881         s1 = _mm_srli_si64(s1, 32);
01882 
01883         C[15] = z[27] + _mm_cvtsi64_si32(s1);
01884         _mm_empty();
01885 }
01886 
01887 <span class="keywordtype">void</span> P4Optimized::Multiply8Bottom(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B)
01888 {
01889         __m128i temp[21];
01890         <span class="keyword">const</span> word *w = (word *)temp;
01891         <span class="keyword">const</span> __m64 *mw = (__m64 *)w;
01892         <span class="keyword">const</span> word *x = (word *)temp+7*4;
01893         <span class="keyword">const</span> __m64 *mx = (__m64 *)x;
01894         <span class="keyword">const</span> word *y = (word *)temp+7*4*2;
01895         <span class="keyword">const</span> __m64 *my = (__m64 *)y;
01896 
01897         P4_Mul(temp, (__m128i *)A, (__m128i *)B);
01898 
01899         P4_Mul(temp+7, (__m128i *)A+1, (__m128i *)B);
01900 
01901         P4_Mul(temp+14, (__m128i *)A, (__m128i *)B+1);
01902 
01903         C[0] = w[0];
01904 
01905         __m64 s1, s2, s3, s4;
01906 
01907         __m64 w1 = _mm_cvtsi32_si64(w[1]);
01908         __m64 w4 = mw[2];
01909         __m64 w6 = mw[3];
01910         __m64 w8 = mw[4];
01911         __m64 w10 = mw[5];
01912         __m64 w12 = mw[6];
01913         __m64 w14 = mw[7];
01914         __m64 w16 = mw[8];
01915         __m64 w18 = mw[9];
01916         __m64 w20 = mw[10];
01917         __m64 w22 = mw[11];
01918         __m64 w26 = _mm_cvtsi32_si64(w[26]);
01919 
01920         __m64 x0 = _mm_cvtsi32_si64(x[0]);
01921         __m64 x1 = _mm_cvtsi32_si64(x[1]);
01922         __m64 x4 = mx[2];
01923         __m64 x6 = mx[3];
01924         __m64 x8 = mx[4];
01925 
01926         __m64 y0 = _mm_cvtsi32_si64(y[0]);
01927         __m64 y1 = _mm_cvtsi32_si64(y[1]);
01928         __m64 y4 = my[2];
01929         __m64 y6 = my[3];
01930         __m64 y8 = my[4];
01931 
01932         s1 = _mm_add_si64(w1, w4);
01933         C[1] = _mm_cvtsi64_si32(s1);
01934         s1 = _mm_srli_si64(s1, 32);
01935 
01936         s2 = _mm_add_si64(w6, w8);
01937         s1 = _mm_add_si64(s1, s2);
01938         C[2] = _mm_cvtsi64_si32(s1);
01939         s1 = _mm_srli_si64(s1, 32);
01940 
01941         s2 = _mm_add_si64(w10, w12);
01942         s1 = _mm_add_si64(s1, s2);
01943         C[3] = _mm_cvtsi64_si32(s1);
01944         s1 = _mm_srli_si64(s1, 32);
01945 
01946         s3 = _mm_add_si64(x0, y0);
01947         s2 = _mm_add_si64(w14, w16);
01948         s1 = _mm_add_si64(s1, s3);
01949         s1 = _mm_add_si64(s1, s2);
01950         C[4] = _mm_cvtsi64_si32(s1);
01951         s1 = _mm_srli_si64(s1, 32);
01952 
01953         s3 = _mm_add_si64(x1, y1);
01954         s4 = _mm_add_si64(x4, y4);
01955         s1 = _mm_add_si64(s1, w18);
01956         s3 = _mm_add_si64(s3, s4);
01957         s1 = _mm_add_si64(s1, w20);
01958         s1 = _mm_add_si64(s1, s3);
01959         C[5] = _mm_cvtsi64_si32(s1);
01960         s1 = _mm_srli_si64(s1, 32);
01961 
01962         s3 = _mm_add_si64(x6, y6);
01963         s4 = _mm_add_si64(x8, y8);
01964         s1 = _mm_add_si64(s1, w22);
01965         s3 = _mm_add_si64(s3, s4);
01966         s1 = _mm_add_si64(s1, w26);
01967         s1 = _mm_add_si64(s1, s3);
01968         C[6] = _mm_cvtsi64_si32(s1);
01969         s1 = _mm_srli_si64(s1, 32);
01970 
01971         C[7] = _mm_cvtsi64_si32(s1) + w[27] + x[10] + y[10] + x[12] + y[12];
01972         _mm_empty();
01973 }
01974 
01975 <span class="preprocessor">#endif  // #ifdef SSE2_INTRINSICS_AVAILABLE</span>
01976 <span class="preprocessor"></span>
01977 <span class="comment">// ********************************************************</span>
01978 
01979 <span class="preprocessor">#define A0              A</span>
01980 <span class="preprocessor"></span><span class="preprocessor">#define A1              (A+N2)</span>
01981 <span class="preprocessor"></span><span class="preprocessor">#define B0              B</span>
01982 <span class="preprocessor"></span><span class="preprocessor">#define B1              (B+N2)</span>
01983 <span class="preprocessor"></span>
01984 <span class="preprocessor">#define T0              T</span>
01985 <span class="preprocessor"></span><span class="preprocessor">#define T1              (T+N2)</span>
01986 <span class="preprocessor"></span><span class="preprocessor">#define T2              (T+N)</span>
01987 <span class="preprocessor"></span><span class="preprocessor">#define T3              (T+N+N2)</span>
01988 <span class="preprocessor"></span>
01989 <span class="preprocessor">#define R0              R</span>
01990 <span class="preprocessor"></span><span class="preprocessor">#define R1              (R+N2)</span>
01991 <span class="preprocessor"></span><span class="preprocessor">#define R2              (R+N)</span>
01992 <span class="preprocessor"></span><span class="preprocessor">#define R3              (R+N+N2)</span>
01993 <span class="preprocessor"></span>
01994 <span class="comment">// R[2*N] - result = A*B</span>
01995 <span class="comment">// T[2*N] - temporary work space</span>
01996 <span class="comment">// A[N] --- multiplier</span>
01997 <span class="comment">// B[N] --- multiplicant</span>
01998 
01999 <span class="keywordtype">void</span> RecursiveMultiply(word *R, word *T, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
02000 {
02001         assert(N&gt;=2 &amp;&amp; N%2==0);
02002 
02003         <span class="keywordflow">if</span> (LowLevel::MultiplyRecursionLimit() &gt;= 8 &amp;&amp; N==8)
02004                 LowLevel::Multiply8(R, A, B);
02005         <span class="keywordflow">else</span> <span class="keywordflow">if</span> (LowLevel::MultiplyRecursionLimit() &gt;= 4 &amp;&amp; N==4)
02006                 LowLevel::Multiply4(R, A, B);
02007         <span class="keywordflow">else</span> <span class="keywordflow">if</span> (N==2)
02008                 LowLevel::Multiply2(R, A, B);
02009         <span class="keywordflow">else</span>
02010         {
02011                 <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N2 = N/2;
02012                 <span class="keywordtype">int</span> carry;
02013 
02014                 <span class="keywordtype">int</span> aComp = Compare(A0, A1, N2);
02015                 <span class="keywordtype">int</span> bComp = Compare(B0, B1, N2);
02016 
02017                 <span class="keywordflow">switch</span> (2*aComp + aComp + bComp)
02018                 {
02019                 <span class="keywordflow">case</span> -4:
02020                         LowLevel::Subtract(R0, A1, A0, N2);
02021                         LowLevel::Subtract(R1, B0, B1, N2);
02022                         RecursiveMultiply(T0, T2, R0, R1, N2);
02023                         LowLevel::Subtract(T1, T1, R0, N2);
02024                         carry = -1;
02025                         <span class="keywordflow">break</span>;
02026                 <span class="keywordflow">case</span> -2:
02027                         LowLevel::Subtract(R0, A1, A0, N2);
02028                         LowLevel::Subtract(R1, B0, B1, N2);
02029                         RecursiveMultiply(T0, T2, R0, R1, N2);
02030                         carry = 0;
02031                         <span class="keywordflow">break</span>;
02032                 <span class="keywordflow">case</span> 2:
02033                         LowLevel::Subtract(R0, A0, A1, N2);
02034                         LowLevel::Subtract(R1, B1, B0, N2);
02035                         RecursiveMultiply(T0, T2, R0, R1, N2);
02036                         carry = 0;
02037                         <span class="keywordflow">break</span>;
02038                 <span class="keywordflow">case</span> 4:
02039                         LowLevel::Subtract(R0, A1, A0, N2);
02040                         LowLevel::Subtract(R1, B0, B1, N2);
02041                         RecursiveMultiply(T0, T2, R0, R1, N2);
02042                         LowLevel::Subtract(T1, T1, R1, N2);
02043                         carry = -1;
02044                         <span class="keywordflow">break</span>;
02045                 <span class="keywordflow">default</span>:
02046                         SetWords(T0, 0, N);
02047                         carry = 0;
02048                 }
02049 
02050                 RecursiveMultiply(R0, T2, A0, B0, N2);
02051                 RecursiveMultiply(R2, T2, A1, B1, N2);
02052 
02053                 <span class="comment">// now T[01] holds (A1-A0)*(B0-B1), R[01] holds A0*B0, R[23] holds A1*B1</span>
02054 
02055                 carry += LowLevel::Add(T0, T0, R0, N);
02056                 carry += LowLevel::Add(T0, T0, R2, N);
02057                 carry += LowLevel::Add(R1, R1, T0, N);
02058 
02059                 assert (carry &gt;= 0 &amp;&amp; carry &lt;= 2);
02060                 Increment(R3, N2, carry);
02061         }
02062 }
02063 
02064 <span class="comment">// R[2*N] - result = A*A</span>
02065 <span class="comment">// T[2*N] - temporary work space</span>
02066 <span class="comment">// A[N] --- number to be squared</span>
02067 
02068 <span class="keywordtype">void</span> RecursiveSquare(word *R, word *T, <span class="keyword">const</span> word *A, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
02069 {
02070         assert(N &amp;&amp; N%2==0);
02071         <span class="keywordflow">if</span> (LowLevel::SquareRecursionLimit() &gt;= 8 &amp;&amp; N==8)
02072                 LowLevel::Square8(R, A);
02073         <span class="keywordflow">if</span> (LowLevel::SquareRecursionLimit() &gt;= 4 &amp;&amp; N==4)
02074                 LowLevel::Square4(R, A);
02075         <span class="keywordflow">else</span> <span class="keywordflow">if</span> (N==2)
02076                 LowLevel::Square2(R, A);
02077         <span class="keywordflow">else</span>
02078         {
02079                 <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N2 = N/2;
02080 
02081                 RecursiveSquare(R0, T2, A0, N2);
02082                 RecursiveSquare(R2, T2, A1, N2);
02083                 RecursiveMultiply(T0, T2, A0, A1, N2);
02084 
02085                 word carry = LowLevel::Add(R1, R1, T0, N);
02086                 carry += LowLevel::Add(R1, R1, T0, N);
02087                 Increment(R3, N2, carry);
02088         }
02089 }
02090 
02091 <span class="comment">// R[N] - bottom half of A*B</span>
02092 <span class="comment">// T[N] - temporary work space</span>
02093 <span class="comment">// A[N] - multiplier</span>
02094 <span class="comment">// B[N] - multiplicant</span>
02095 
02096 <span class="keywordtype">void</span> RecursiveMultiplyBottom(word *R, word *T, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
02097 {
02098         assert(N&gt;=2 &amp;&amp; N%2==0);
02099         <span class="keywordflow">if</span> (LowLevel::MultiplyBottomRecursionLimit() &gt;= 8 &amp;&amp; N==8)
02100                 LowLevel::Multiply8Bottom(R, A, B);
02101         <span class="keywordflow">else</span> <span class="keywordflow">if</span> (LowLevel::MultiplyBottomRecursionLimit() &gt;= 4 &amp;&amp; N==4)
02102                 LowLevel::Multiply4Bottom(R, A, B);
02103         <span class="keywordflow">else</span> <span class="keywordflow">if</span> (N==2)
02104                 LowLevel::Multiply2Bottom(R, A, B);
02105         <span class="keywordflow">else</span>
02106         {
02107                 <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N2 = N/2;
02108 
02109                 RecursiveMultiply(R, T, A0, B0, N2);
02110                 RecursiveMultiplyBottom(T0, T1, A1, B0, N2);
02111                 LowLevel::Add(R1, R1, T0, N2);
02112                 RecursiveMultiplyBottom(T0, T1, A0, B1, N2);
02113                 LowLevel::Add(R1, R1, T0, N2);
02114         }
02115 }
02116 
02117 <span class="comment">// R[N] --- upper half of A*B</span>
02118 <span class="comment">// T[2*N] - temporary work space</span>
02119 <span class="comment">// L[N] --- lower half of A*B</span>
02120 <span class="comment">// A[N] --- multiplier</span>
02121 <span class="comment">// B[N] --- multiplicant</span>
02122 
02123 <span class="keywordtype">void</span> RecursiveMultiplyTop(word *R, word *T, <span class="keyword">const</span> word *L, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
02124 {
02125         assert(N&gt;=2 &amp;&amp; N%2==0);
02126 
02127         <span class="keywordflow">if</span> (N==4)
02128         {
02129                 LowLevel::Multiply4(T, A, B);
02130                 memcpy(R, T+4, 4*WORD_SIZE);
02131         }
02132         <span class="keywordflow">else</span> <span class="keywordflow">if</span> (N==2)
02133         {
02134                 LowLevel::Multiply2(T, A, B);
02135                 memcpy(R, T+2, 2*WORD_SIZE);
02136         }
02137         <span class="keywordflow">else</span>
02138         {
02139                 <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N2 = N/2;
02140                 <span class="keywordtype">int</span> carry;
02141 
02142                 <span class="keywordtype">int</span> aComp = Compare(A0, A1, N2);
02143                 <span class="keywordtype">int</span> bComp = Compare(B0, B1, N2);
02144 
02145                 <span class="keywordflow">switch</span> (2*aComp + aComp + bComp)
02146                 {
02147                 <span class="keywordflow">case</span> -4:
02148                         LowLevel::Subtract(R0, A1, A0, N2);
02149                         LowLevel::Subtract(R1, B0, B1, N2);
02150                         RecursiveMultiply(T0, T2, R0, R1, N2);
02151                         LowLevel::Subtract(T1, T1, R0, N2);
02152                         carry = -1;
02153                         <span class="keywordflow">break</span>;
02154                 <span class="keywordflow">case</span> -2:
02155                         LowLevel::Subtract(R0, A1, A0, N2);
02156                         LowLevel::Subtract(R1, B0, B1, N2);
02157                         RecursiveMultiply(T0, T2, R0, R1, N2);
02158                         carry = 0;
02159                         <span class="keywordflow">break</span>;
02160                 <span class="keywordflow">case</span> 2:
02161                         LowLevel::Subtract(R0, A0, A1, N2);
02162                         LowLevel::Subtract(R1, B1, B0, N2);
02163                         RecursiveMultiply(T0, T2, R0, R1, N2);
02164                         carry = 0;
02165                         <span class="keywordflow">break</span>;
02166                 <span class="keywordflow">case</span> 4:
02167                         LowLevel::Subtract(R0, A1, A0, N2);
02168                         LowLevel::Subtract(R1, B0, B1, N2);
02169                         RecursiveMultiply(T0, T2, R0, R1, N2);
02170                         LowLevel::Subtract(T1, T1, R1, N2);
02171                         carry = -1;
02172                         <span class="keywordflow">break</span>;
02173                 <span class="keywordflow">default</span>:
02174                         SetWords(T0, 0, N);
02175                         carry = 0;
02176                 }
02177 
02178                 RecursiveMultiply(T2, R0, A1, B1, N2);
02179 
02180                 <span class="comment">// now T[01] holds (A1-A0)*(B0-B1), T[23] holds A1*B1</span>
02181 
02182                 word c2 = LowLevel::Subtract(R0, L+N2, L, N2);
02183                 c2 += LowLevel::Subtract(R0, R0, T0, N2);
02184                 word t = (Compare(R0, T2, N2) == -1);
02185 
02186                 carry += t;
02187                 carry += Increment(R0, N2, c2+t);
02188                 carry += LowLevel::Add(R0, R0, T1, N2);
02189                 carry += LowLevel::Add(R0, R0, T3, N2);
02190                 assert (carry &gt;= 0 &amp;&amp; carry &lt;= 2);
02191 
02192                 CopyWords(R1, T3, N2);
02193                 Increment(R1, N2, carry);
02194         }
02195 }
02196 
02197 <span class="keyword">inline</span> word Add(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
02198 {
02199         <span class="keywordflow">return</span> LowLevel::Add(C, A, B, N);
02200 }
02201 
02202 <span class="keyword">inline</span> word Subtract(word *C, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
02203 {
02204         <span class="keywordflow">return</span> LowLevel::Subtract(C, A, B, N);
02205 }
02206 
02207 <span class="keyword">inline</span> <span class="keywordtype">void</span> Multiply(word *R, word *T, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
02208 {
02209         RecursiveMultiply(R, T, A, B, N);
02210 }
02211 
02212 <span class="keyword">inline</span> <span class="keywordtype">void</span> <a class="code" href="class_square.html">Square</a>(word *R, word *T, <span class="keyword">const</span> word *A, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
02213 {
02214         RecursiveSquare(R, T, A, N);
02215 }
02216 
02217 <span class="keyword">inline</span> <span class="keywordtype">void</span> MultiplyBottom(word *R, word *T, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
02218 {
02219         RecursiveMultiplyBottom(R, T, A, B, N);
02220 }
02221 
02222 <span class="keyword">inline</span> <span class="keywordtype">void</span> MultiplyTop(word *R, word *T, <span class="keyword">const</span> word *L, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
02223 {
02224         RecursiveMultiplyTop(R, T, L, A, B, N);
02225 }
02226 
02227 <span class="keyword">static</span> word LinearMultiply(word *C, <span class="keyword">const</span> word *A, word B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
02228 {
02229         word carry=0;
02230         <span class="keywordflow">for</span>(<span class="keywordtype">unsigned</span> i=0; i&lt;N; i++)
02231         {
02232                 DWord p = DWord::MultiplyAndAdd(A[i], B, carry);
02233                 C[i] = p.GetLowHalf();
02234                 carry = p.GetHighHalf();
02235         }
02236         <span class="keywordflow">return</span> carry;
02237 }
02238 
02239 <span class="comment">// R[NA+NB] - result = A*B</span>
02240 <span class="comment">// T[NA+NB] - temporary work space</span>
02241 <span class="comment">// A[NA] ---- multiplier</span>
02242 <span class="comment">// B[NB] ---- multiplicant</span>
02243 
02244 <span class="keywordtype">void</span> AsymmetricMultiply(word *R, word *T, <span class="keyword">const</span> word *A, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> NA, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> NB)
02245 {
02246         <span class="keywordflow">if</span> (NA == NB)
02247         {
02248                 <span class="keywordflow">if</span> (A == B)
02249                         Square(R, T, A, NA);
02250                 <span class="keywordflow">else</span>
02251                         Multiply(R, T, A, B, NA);
02252 
02253                 <span class="keywordflow">return</span>;
02254         }
02255 
02256         <span class="keywordflow">if</span> (NA &gt; NB)
02257         {
02258                 std::swap(A, B);
02259                 std::swap(NA, NB);
02260         }
02261 
02262         assert(NB % NA == 0);
02263         assert((NB/NA)%2 == 0);         <span class="comment">// NB is an even multiple of NA</span>
02264 
02265         <span class="keywordflow">if</span> (NA==2 &amp;&amp; !A[1])
02266         {
02267                 <span class="keywordflow">switch</span> (A[0])
02268                 {
02269                 <span class="keywordflow">case</span> 0:
02270                         SetWords(R, 0, NB+2);
02271                         <span class="keywordflow">return</span>;
02272                 <span class="keywordflow">case</span> 1:
02273                         CopyWords(R, B, NB);
02274                         R[NB] = R[NB+1] = 0;
02275                         <span class="keywordflow">return</span>;
02276                 <span class="keywordflow">default</span>:
02277                         R[NB] = LinearMultiply(R, B, A[0], NB);
02278                         R[NB+1] = 0;
02279                         <span class="keywordflow">return</span>;
02280                 }
02281         }
02282 
02283         Multiply(R, T, A, B, NA);
02284         CopyWords(T+2*NA, R+NA, NA);
02285 
02286         <span class="keywordtype">unsigned</span> i;
02287 
02288         <span class="keywordflow">for</span> (i=2*NA; i&lt;NB; i+=2*NA)
02289                 Multiply(T+NA+i, T, A, B+i, NA);
02290         <span class="keywordflow">for</span> (i=NA; i&lt;NB; i+=2*NA)
02291                 Multiply(R+i, T, A, B+i, NA);
02292 
02293         <span class="keywordflow">if</span> (Add(R+NA, R+NA, T+2*NA, NB-NA))
02294                 Increment(R+NB, NA);
02295 }
02296 
02297 <span class="comment">// R[N] ----- result = A inverse mod 2**(WORD_BITS*N)</span>
02298 <span class="comment">// T[3*N/2] - temporary work space</span>
02299 <span class="comment">// A[N] ----- an odd number as input</span>
02300 
02301 <span class="keywordtype">void</span> RecursiveInverseModPower2(word *R, word *T, <span class="keyword">const</span> word *A, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
02302 {
02303         <span class="keywordflow">if</span> (N==2)
02304         {
02305                 T[0] = AtomicInverseModPower2(A[0]);
02306                 T[1] = 0;
02307                 LowLevel::Multiply2Bottom(T+2, T, A);
02308                 TwosComplement(T+2, 2);
02309                 Increment(T+2, 2, 2);
02310                 LowLevel::Multiply2Bottom(R, T, T+2);
02311         }
02312         <span class="keywordflow">else</span>
02313         {
02314                 <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N2 = N/2;
02315                 RecursiveInverseModPower2(R0, T0, A0, N2);
02316                 T0[0] = 1;
02317                 SetWords(T0+1, 0, N2-1);
02318                 MultiplyTop(R1, T1, T0, R0, A0, N2);
02319                 MultiplyBottom(T0, T1, R0, A1, N2);
02320                 Add(T0, R1, T0, N2);
02321                 TwosComplement(T0, N2);
02322                 MultiplyBottom(R1, T1, R0, T0, N2);
02323         }
02324 }
02325 
02326 <span class="comment">// R[N] --- result = X/(2**(WORD_BITS*N)) mod M</span>
02327 <span class="comment">// T[3*N] - temporary work space</span>
02328 <span class="comment">// X[2*N] - number to be reduced</span>
02329 <span class="comment">// M[N] --- modulus</span>
02330 <span class="comment">// U[N] --- multiplicative inverse of M mod 2**(WORD_BITS*N)</span>
02331 
02332 <span class="keywordtype">void</span> MontgomeryReduce(word *R, word *T, <span class="keyword">const</span> word *X, <span class="keyword">const</span> word *M, <span class="keyword">const</span> word *U, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
02333 {
02334         MultiplyBottom(R, T, X, U, N);
02335         MultiplyTop(T, T+N, X, R, M, N);
02336         word borrow = Subtract(T, X+N, T, N);
02337         <span class="comment">// defend against timing attack by doing this Add even when not needed</span>
02338         word carry = Add(T+N, T, M, N);
02339         assert(carry || !borrow);
02340         CopyWords(R, T + (borrow ? N : 0), N);
02341 }
02342 
02343 <span class="comment">// R[N] --- result = X/(2**(WORD_BITS*N/2)) mod M</span>
02344 <span class="comment">// T[2*N] - temporary work space</span>
02345 <span class="comment">// X[2*N] - number to be reduced</span>
02346 <span class="comment">// M[N] --- modulus</span>
02347 <span class="comment">// U[N/2] - multiplicative inverse of M mod 2**(WORD_BITS*N/2)</span>
02348 <span class="comment">// V[N] --- 2**(WORD_BITS*3*N/2) mod M</span>
02349 
02350 <span class="keywordtype">void</span> HalfMontgomeryReduce(word *R, word *T, <span class="keyword">const</span> word *X, <span class="keyword">const</span> word *M, <span class="keyword">const</span> word *U, <span class="keyword">const</span> word *V, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
02351 {
02352         assert(N%2==0 &amp;&amp; N&gt;=4);
02353 
02354 <span class="preprocessor">#define M0              M</span>
02355 <span class="preprocessor"></span><span class="preprocessor">#define M1              (M+N2)</span>
02356 <span class="preprocessor"></span><span class="preprocessor">#define V0              V</span>
02357 <span class="preprocessor"></span><span class="preprocessor">#define V1              (V+N2)</span>
02358 <span class="preprocessor"></span>
02359 <span class="preprocessor">#define X0              X</span>
02360 <span class="preprocessor"></span><span class="preprocessor">#define X1              (X+N2)</span>
02361 <span class="preprocessor"></span><span class="preprocessor">#define X2              (X+N)</span>
02362 <span class="preprocessor"></span><span class="preprocessor">#define X3              (X+N+N2)</span>
02363 <span class="preprocessor"></span>
02364         <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N2 = N/2;
02365         Multiply(T0, T2, V0, X3, N2);
02366         <span class="keywordtype">int</span> c2 = Add(T0, T0, X0, N);
02367         MultiplyBottom(T3, T2, T0, U, N2);
02368         MultiplyTop(T2, R, T0, T3, M0, N2);
02369         c2 -= Subtract(T2, T1, T2, N2);
02370         Multiply(T0, R, T3, M1, N2);
02371         c2 -= Subtract(T0, T2, T0, N2);
02372         <span class="keywordtype">int</span> c3 = -(<span class="keywordtype">int</span>)Subtract(T1, X2, T1, N2);
02373         Multiply(R0, T2, V1, X3, N2);
02374         c3 += Add(R, R, T, N);
02375 
02376         <span class="keywordflow">if</span> (c2&gt;0)
02377                 c3 += Increment(R1, N2);
02378         <span class="keywordflow">else</span> <span class="keywordflow">if</span> (c2&lt;0)
02379                 c3 -= Decrement(R1, N2, -c2);
02380 
02381         assert(c3&gt;=-1 &amp;&amp; c3&lt;=1);
02382         <span class="keywordflow">if</span> (c3&gt;0)
02383                 Subtract(R, R, M, N);
02384         <span class="keywordflow">else</span> <span class="keywordflow">if</span> (c3&lt;0)
02385                 Add(R, R, M, N);
02386 
02387 <span class="preprocessor">#undef M0</span>
02388 <span class="preprocessor"></span><span class="preprocessor">#undef M1</span>
02389 <span class="preprocessor"></span><span class="preprocessor">#undef V0</span>
02390 <span class="preprocessor"></span><span class="preprocessor">#undef V1</span>
02391 <span class="preprocessor"></span>
02392 <span class="preprocessor">#undef X0</span>
02393 <span class="preprocessor"></span><span class="preprocessor">#undef X1</span>
02394 <span class="preprocessor"></span><span class="preprocessor">#undef X2</span>
02395 <span class="preprocessor"></span><span class="preprocessor">#undef X3</span>
02396 <span class="preprocessor"></span>}
02397 
02398 <span class="preprocessor">#undef A0</span>
02399 <span class="preprocessor"></span><span class="preprocessor">#undef A1</span>
02400 <span class="preprocessor"></span><span class="preprocessor">#undef B0</span>
02401 <span class="preprocessor"></span><span class="preprocessor">#undef B1</span>
02402 <span class="preprocessor"></span>
02403 <span class="preprocessor">#undef T0</span>
02404 <span class="preprocessor"></span><span class="preprocessor">#undef T1</span>
02405 <span class="preprocessor"></span><span class="preprocessor">#undef T2</span>
02406 <span class="preprocessor"></span><span class="preprocessor">#undef T3</span>
02407 <span class="preprocessor"></span>
02408 <span class="preprocessor">#undef R0</span>
02409 <span class="preprocessor"></span><span class="preprocessor">#undef R1</span>
02410 <span class="preprocessor"></span><span class="preprocessor">#undef R2</span>
02411 <span class="preprocessor"></span><span class="preprocessor">#undef R3</span>
02412 <span class="preprocessor"></span>
02413 <span class="comment">/*</span>
02414 <span class="comment">// do a 3 word by 2 word divide, returns quotient and leaves remainder in A</span>
02415 <span class="comment">static word SubatomicDivide(word *A, word B0, word B1)</span>
02416 <span class="comment">{</span>
02417 <span class="comment">        // assert {A[2],A[1]} &lt; {B1,B0}, so quotient can fit in a word</span>
02418 <span class="comment">        assert(A[2] &lt; B1 || (A[2]==B1 &amp;&amp; A[1] &lt; B0));</span>
02419 <span class="comment"></span>
02420 <span class="comment">        // estimate the quotient: do a 2 word by 1 word divide</span>
02421 <span class="comment">        word Q;</span>
02422 <span class="comment">        if (B1+1 == 0)</span>
02423 <span class="comment">                Q = A[2];</span>
02424 <span class="comment">        else</span>
02425 <span class="comment">                Q = DWord(A[1], A[2]).DividedBy(B1+1);</span>
02426 <span class="comment"></span>
02427 <span class="comment">        // now subtract Q*B from A</span>
02428 <span class="comment">        DWord p = DWord::Multiply(B0, Q);</span>
02429 <span class="comment">        DWord u = (DWord) A[0] - p.GetLowHalf();</span>
02430 <span class="comment">        A[0] = u.GetLowHalf();</span>
02431 <span class="comment">        u = (DWord) A[1] - p.GetHighHalf() - u.GetHighHalfAsBorrow() - DWord::Multiply(B1, Q);</span>
02432 <span class="comment">        A[1] = u.GetLowHalf();</span>
02433 <span class="comment">        A[2] += u.GetHighHalf();</span>
02434 <span class="comment"></span>
02435 <span class="comment">        // Q &lt;= actual quotient, so fix it</span>
02436 <span class="comment">        while (A[2] || A[1] &gt; B1 || (A[1]==B1 &amp;&amp; A[0]&gt;=B0))</span>
02437 <span class="comment">        {</span>
02438 <span class="comment">                u = (DWord) A[0] - B0;</span>
02439 <span class="comment">                A[0] = u.GetLowHalf();</span>
02440 <span class="comment">                u = (DWord) A[1] - B1 - u.GetHighHalfAsBorrow();</span>
02441 <span class="comment">                A[1] = u.GetLowHalf();</span>
02442 <span class="comment">                A[2] += u.GetHighHalf();</span>
02443 <span class="comment">                Q++;</span>
02444 <span class="comment">                assert(Q);      // shouldn't overflow</span>
02445 <span class="comment">        }</span>
02446 <span class="comment"></span>
02447 <span class="comment">        return Q;</span>
02448 <span class="comment">}</span>
02449 <span class="comment"></span>
02450 <span class="comment">// do a 4 word by 2 word divide, returns 2 word quotient in Q0 and Q1</span>
02451 <span class="comment">static inline void AtomicDivide(word *Q, const word *A, const word *B)</span>
02452 <span class="comment">{</span>
02453 <span class="comment">        if (!B[0] &amp;&amp; !B[1]) // if divisor is 0, we assume divisor==2**(2*WORD_BITS)</span>
02454 <span class="comment">        {</span>
02455 <span class="comment">                Q[0] = A[2];</span>
02456 <span class="comment">                Q[1] = A[3];</span>
02457 <span class="comment">        }</span>
02458 <span class="comment">        else</span>
02459 <span class="comment">        {</span>
02460 <span class="comment">                word T[4];</span>
02461 <span class="comment">                T[0] = A[0]; T[1] = A[1]; T[2] = A[2]; T[3] = A[3];</span>
02462 <span class="comment">                Q[1] = SubatomicDivide(T+1, B[0], B[1]);</span>
02463 <span class="comment">                Q[0] = SubatomicDivide(T, B[0], B[1]);</span>
02464 <span class="comment"></span>
02465 <span class="comment">#ifndef NDEBUG</span>
02466 <span class="comment">                // multiply quotient and divisor and add remainder, make sure it equals dividend</span>
02467 <span class="comment">                assert(!T[2] &amp;&amp; !T[3] &amp;&amp; (T[1] &lt; B[1] || (T[1]==B[1] &amp;&amp; T[0]&lt;B[0])));</span>
02468 <span class="comment">                word P[4];</span>
02469 <span class="comment">                LowLevel::Multiply2(P, Q, B);</span>
02470 <span class="comment">                Add(P, P, T, 4);</span>
02471 <span class="comment">                assert(memcmp(P, A, 4*WORD_SIZE)==0);</span>
02472 <span class="comment">#endif</span>
02473 <span class="comment">        }</span>
02474 <span class="comment">}</span>
02475 <span class="comment">*/</span>
02476 
02477 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">void</span> AtomicDivide(word *Q, <span class="keyword">const</span> word *A, <span class="keyword">const</span> word *B)
02478 {
02479         word T[4];
02480         DWord q = DivideFourWordsByTwo&lt;word, DWord&gt;(T, DWord(A[0], A[1]), DWord(A[2], A[3]), DWord(B[0], B[1]));
02481         Q[0] = q.GetLowHalf();
02482         Q[1] = q.GetHighHalf();
02483 
02484 <span class="preprocessor">#ifndef NDEBUG</span>
02485 <span class="preprocessor"></span>        <span class="keywordflow">if</span> (B[0] || B[1])
02486         {
02487                 <span class="comment">// multiply quotient and divisor and add remainder, make sure it equals dividend</span>
02488                 assert(!T[2] &amp;&amp; !T[3] &amp;&amp; (T[1] &lt; B[1] || (T[1]==B[1] &amp;&amp; T[0]&lt;B[0])));
02489                 word P[4];
02490                 Portable::Multiply2(P, Q, B);
02491                 Add(P, P, T, 4);
02492                 assert(memcmp(P, A, 4*WORD_SIZE)==0);
02493         }
02494 <span class="preprocessor">#endif</span>
02495 <span class="preprocessor"></span>}
02496 
02497 <span class="comment">// for use by Divide(), corrects the underestimated quotient {Q1,Q0}</span>
02498 <span class="keyword">static</span> <span class="keywordtype">void</span> CorrectQuotientEstimate(word *R, word *T, word *Q, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
02499 {
02500         assert(N &amp;&amp; N%2==0);
02501 
02502         <span class="keywordflow">if</span> (Q[1])
02503         {
02504                 T[N] = T[N+1] = 0;
02505                 <span class="keywordtype">unsigned</span> i;
02506                 <span class="keywordflow">for</span> (i=0; i&lt;N; i+=4)
02507                         LowLevel::Multiply2(T+i, Q, B+i);
02508                 <span class="keywordflow">for</span> (i=2; i&lt;N; i+=4)
02509                         <span class="keywordflow">if</span> (LowLevel::Multiply2Add(T+i, Q, B+i))
02510                                 T[i+5] += (++T[i+4]==0);
02511         }
02512         <span class="keywordflow">else</span>
02513         {
02514                 T[N] = LinearMultiply(T, B, Q[0], N);
02515                 T[N+1] = 0;
02516         }
02517 
02518         word borrow = Subtract(R, R, T, N+2);
02519         assert(!borrow &amp;&amp; !R[N+1]);
02520 
02521         <span class="keywordflow">while</span> (R[N] || Compare(R, B, N) &gt;= 0)
02522         {
02523                 R[N] -= Subtract(R, R, B, N);
02524                 Q[1] += (++Q[0]==0);
02525                 assert(Q[0] || Q[1]); <span class="comment">// no overflow</span>
02526         }
02527 }
02528 
02529 <span class="comment">// R[NB] -------- remainder = A%B</span>
02530 <span class="comment">// Q[NA-NB+2] --- quotient      = A/B</span>
02531 <span class="comment">// T[NA+2*NB+4] - temp work space</span>
02532 <span class="comment">// A[NA] -------- dividend</span>
02533 <span class="comment">// B[NB] -------- divisor</span>
02534 
02535 <span class="keywordtype">void</span> Divide(word *R, word *Q, word *T, <span class="keyword">const</span> word *A, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> NA, <span class="keyword">const</span> word *B, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> NB)
02536 {
02537         assert(NA &amp;&amp; NB &amp;&amp; NA%2==0 &amp;&amp; NB%2==0);
02538         assert(B[NB-1] || B[NB-2]);
02539         assert(NB &lt;= NA);
02540 
02541         <span class="comment">// set up temporary work space</span>
02542         word *<span class="keyword">const</span> TA=T;
02543         word *<span class="keyword">const</span> TB=T+NA+2;
02544         word *<span class="keyword">const</span> TP=T+NA+2+NB;
02545 
02546         <span class="comment">// copy B into TB and normalize it so that TB has highest bit set to 1</span>
02547         <span class="keywordtype">unsigned</span> shiftWords = (B[NB-1]==0);
02548         TB[0] = TB[NB-1] = 0;
02549         CopyWords(TB+shiftWords, B, NB-shiftWords);
02550         <span class="keywordtype">unsigned</span> shiftBits = WORD_BITS - BitPrecision(TB[NB-1]);
02551         assert(shiftBits &lt; WORD_BITS);
02552         ShiftWordsLeftByBits(TB, NB, shiftBits);
02553 
02554         <span class="comment">// copy A into TA and normalize it</span>
02555         TA[0] = TA[NA] = TA[NA+1] = 0;
02556         CopyWords(TA+shiftWords, A, NA);
02557         ShiftWordsLeftByBits(TA, NA+2, shiftBits);
02558 
02559         <span class="keywordflow">if</span> (TA[NA+1]==0 &amp;&amp; TA[NA] &lt;= 1)
02560         {
02561                 Q[NA-NB+1] = Q[NA-NB] = 0;
02562                 <span class="keywordflow">while</span> (TA[NA] || Compare(TA+NA-NB, TB, NB) &gt;= 0)
02563                 {
02564                         TA[NA] -= Subtract(TA+NA-NB, TA+NA-NB, TB, NB);
02565                         ++Q[NA-NB];
02566                 }
02567         }
02568         <span class="keywordflow">else</span>
02569         {
02570                 NA+=2;
02571                 assert(Compare(TA+NA-NB, TB, NB) &lt; 0);
02572         }
02573 
02574         word BT[2];
02575         BT[0] = TB[NB-2] + 1;
02576         BT[1] = TB[NB-1] + (BT[0]==0);
02577 
02578         <span class="comment">// start reducing TA mod TB, 2 words at a time</span>
02579         <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i=NA-2; i&gt;=NB; i-=2)
02580         {
02581                 AtomicDivide(Q+i-NB, TA+i-2, BT);
02582                 CorrectQuotientEstimate(TA+i-NB, TP, Q+i-NB, TB, NB);
02583         }
02584 
02585         <span class="comment">// copy TA into R, and denormalize it</span>
02586         CopyWords(R, TA+shiftWords, NB);
02587         ShiftWordsRightByBits(R, NB, shiftBits);
02588 }
02589 
02590 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> EvenWordCount(<span class="keyword">const</span> word *X, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
02591 {
02592         <span class="keywordflow">while</span> (N &amp;&amp; X[N-2]==0 &amp;&amp; X[N-1]==0)
02593                 N-=2;
02594         <span class="keywordflow">return</span> N;
02595 }
02596 
02597 <span class="comment">// return k</span>
02598 <span class="comment">// R[N] --- result = A^(-1) * 2^k mod M</span>
02599 <span class="comment">// T[4*N] - temporary work space</span>
02600 <span class="comment">// A[NA] -- number to take inverse of</span>
02601 <span class="comment">// M[N] --- modulus</span>
02602 
02603 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> AlmostInverse(word *R, word *T, <span class="keyword">const</span> word *A, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> NA, <span class="keyword">const</span> word *M, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
02604 {
02605         assert(NA&lt;=N &amp;&amp; N &amp;&amp; N%2==0);
02606 
02607         word *b = T;
02608         word *c = T+N;
02609         word *f = T+2*N;
02610         word *g = T+3*N;
02611         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> bcLen=2, fgLen=EvenWordCount(M, N);
02612         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> k=0, s=0;
02613 
02614         SetWords(T, 0, 3*N);
02615         b[0]=1;
02616         CopyWords(f, A, NA);
02617         CopyWords(g, M, N);
02618 
02619         <span class="keywordflow">while</span> (1)
02620         {
02621                 word t=f[0];
02622                 <span class="keywordflow">while</span> (!t)
02623                 {
02624                         <span class="keywordflow">if</span> (EvenWordCount(f, fgLen)==0)
02625                         {
02626                                 SetWords(R, 0, N);
02627                                 <span class="keywordflow">return</span> 0;
02628                         }
02629 
02630                         ShiftWordsRightByWords(f, fgLen, 1);
02631                         <span class="keywordflow">if</span> (c[bcLen-1]) bcLen+=2;
02632                         assert(bcLen &lt;= N);
02633                         ShiftWordsLeftByWords(c, bcLen, 1);
02634                         k+=WORD_BITS;
02635                         t=f[0];
02636                 }
02637 
02638                 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=0;
02639                 <span class="keywordflow">while</span> (t%2 == 0)
02640                 {
02641                         t&gt;&gt;=1;
02642                         i++;
02643                 }
02644                 k+=i;
02645 
02646                 <span class="keywordflow">if</span> (t==1 &amp;&amp; f[1]==0 &amp;&amp; EvenWordCount(f, fgLen)==2)
02647                 {
02648                         <span class="keywordflow">if</span> (s%2==0)
02649                                 CopyWords(R, b, N);
02650                         <span class="keywordflow">else</span>
02651                                 Subtract(R, M, b, N);
02652                         <span class="keywordflow">return</span> k;
02653                 }
02654 
02655                 ShiftWordsRightByBits(f, fgLen, i);
02656                 t=ShiftWordsLeftByBits(c, bcLen, i);
02657                 <span class="keywordflow">if</span> (t)
02658                 {
02659                         c[bcLen] = t;
02660                         bcLen+=2;
02661                         assert(bcLen &lt;= N);
02662                 }
02663 
02664                 <span class="keywordflow">if</span> (f[fgLen-2]==0 &amp;&amp; g[fgLen-2]==0 &amp;&amp; f[fgLen-1]==0 &amp;&amp; g[fgLen-1]==0)
02665                         fgLen-=2;
02666 
02667                 <span class="keywordflow">if</span> (Compare(f, g, fgLen)==-1)
02668                 {
02669                         std::swap(f, g);
02670                         std::swap(b, c);
02671                         s++;
02672                 }
02673 
02674                 Subtract(f, f, g, fgLen);
02675 
02676                 <span class="keywordflow">if</span> (Add(b, b, c, bcLen))
02677                 {
02678                         b[bcLen] = 1;
02679                         bcLen+=2;
02680                         assert(bcLen &lt;= N);
02681                 }
02682         }
02683 }
02684 
02685 <span class="comment">// R[N] - result = A/(2^k) mod M</span>
02686 <span class="comment">// A[N] - input</span>
02687 <span class="comment">// M[N] - modulus</span>
02688 
02689 <span class="keywordtype">void</span> DivideByPower2Mod(word *R, <span class="keyword">const</span> word *A, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> k, <span class="keyword">const</span> word *M, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
02690 {
02691         CopyWords(R, A, N);
02692 
02693         <span class="keywordflow">while</span> (k--)
02694         {
02695                 <span class="keywordflow">if</span> (R[0]%2==0)
02696                         ShiftWordsRightByBits(R, N, 1);
02697                 <span class="keywordflow">else</span>
02698                 {
02699                         word carry = Add(R, R, M, N);
02700                         ShiftWordsRightByBits(R, N, 1);
02701                         R[N-1] += carry&lt;&lt;(WORD_BITS-1);
02702                 }
02703         }
02704 }
02705 
02706 <span class="comment">// R[N] - result = A*(2^k) mod M</span>
02707 <span class="comment">// A[N] - input</span>
02708 <span class="comment">// M[N] - modulus</span>
02709 
02710 <span class="keywordtype">void</span> MultiplyByPower2Mod(word *R, <span class="keyword">const</span> word *A, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> k, <span class="keyword">const</span> word *M, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N)
02711 {
02712         CopyWords(R, A, N);
02713 
02714         <span class="keywordflow">while</span> (k--)
02715                 <span class="keywordflow">if</span> (ShiftWordsLeftByBits(R, N, 1) || Compare(R, M, N)&gt;=0)
02716                         Subtract(R, R, M, N);
02717 }
02718 
02719 <span class="comment">// ******************************************************************</span>
02720 
02721 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> RoundupSizeTable[] = {2, 2, 2, 4, 4, 8, 8, 8, 8};
02722 
02723 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> RoundupSize(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> n)
02724 {
02725         <span class="keywordflow">if</span> (n&lt;=8)
02726                 <span class="keywordflow">return</span> RoundupSizeTable[n];
02727         <span class="keywordflow">else</span> <span class="keywordflow">if</span> (n&lt;=16)
02728                 <span class="keywordflow">return</span> 16;
02729         <span class="keywordflow">else</span> <span class="keywordflow">if</span> (n&lt;=32)
02730                 <span class="keywordflow">return</span> 32;
02731         <span class="keywordflow">else</span> <span class="keywordflow">if</span> (n&lt;=64)
02732                 <span class="keywordflow">return</span> 64;
02733         <span class="keywordflow">else</span> <span class="keywordflow">return</span> 1U &lt;&lt; BitPrecision(n-1);
02734 }
02735 
<a name="l02736"></a><a class="code" href="class_integer.html#_integerz37_0">02736</a> <a class="code" href="class_integer.html#_integerz37_0">Integer::Integer</a>()
02737         : reg(2), sign(POSITIVE)
02738 {
02739         reg[0] = reg[1] = 0;
02740 }
02741 
<a name="l02742"></a><a class="code" href="class_integer.html#_integerz37_1">02742</a> <a class="code" href="class_integer.html#_integerz37_0">Integer::Integer</a>(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a>&amp; t)
02743         : reg(RoundupSize(t.WordCount())), sign(t.sign)
02744 {
02745         CopyWords(reg, t.reg, reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>());
02746 }
02747 
<a name="l02748"></a><a class="code" href="class_integer.html#_integerz37_3">02748</a> <a class="code" href="class_integer.html#_integerz37_0">Integer::Integer</a>(Sign s, lword value)
02749         : reg(2), sign(s)
02750 {
02751         reg[0] = word(value);
02752         reg[1] = word(SafeRightShift&lt;WORD_BITS&gt;(value));
02753 }
02754 
<a name="l02755"></a><a class="code" href="class_integer.html#_integerz37_2">02755</a> <a class="code" href="class_integer.html#_integerz37_0">Integer::Integer</a>(<span class="keywordtype">signed</span> <span class="keywordtype">long</span> value)
02756         : reg(2)
02757 {
02758         <span class="keywordflow">if</span> (value &gt;= 0)
02759                 sign = POSITIVE;
02760         <span class="keywordflow">else</span>
02761         {
02762                 sign = NEGATIVE;
02763                 value = -value;
02764         }
02765         reg[0] = word(value);
02766         reg[1] = word(SafeRightShift&lt;WORD_BITS&gt;((<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>)value));
02767 }
02768 
<a name="l02769"></a><a class="code" href="class_integer.html#_integerz37_4">02769</a> <a class="code" href="class_integer.html#_integerz37_0">Integer::Integer</a>(Sign s, word high, word low)
02770         : reg(2), sign(s)
02771 {
02772         reg[0] = low;
02773         reg[1] = high;
02774 }
02775 
<a name="l02776"></a><a class="code" href="class_integer.html#_integerz41_0">02776</a> <span class="keywordtype">bool</span> <a class="code" href="class_integer.html#_integerz41_0">Integer::IsConvertableToLong</a>()<span class="keyword"> const</span>
02777 <span class="keyword"></span>{
02778         <span class="keywordflow">if</span> (<a class="code" href="class_integer.html#_integerz41_3">ByteCount</a>() &gt; <span class="keyword">sizeof</span>(<span class="keywordtype">long</span>))
02779                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
02780 
02781         <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> value = reg[0];
02782         value += SafeLeftShift&lt;WORD_BITS, unsigned long&gt;(reg[1]);
02783 
02784         <span class="keywordflow">if</span> (sign==POSITIVE)
02785                 <span class="keywordflow">return</span> (<span class="keywordtype">signed</span> <span class="keywordtype">long</span>)value &gt;= 0;
02786         <span class="keywordflow">else</span>
02787                 <span class="keywordflow">return</span> -(<span class="keywordtype">signed</span> <span class="keywordtype">long</span>)value &lt; 0;
02788 }
02789 
<a name="l02790"></a><a class="code" href="class_integer.html#_integerz41_1">02790</a> <span class="keywordtype">signed</span> <span class="keywordtype">long</span> <a class="code" href="class_integer.html#_integerz41_1">Integer::ConvertToLong</a>()<span class="keyword"> const</span>
02791 <span class="keyword"></span>{
02792         assert(<a class="code" href="class_integer.html#_integerz41_0">IsConvertableToLong</a>());
02793 
02794         <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> value = reg[0];
02795         value += SafeLeftShift&lt;WORD_BITS, unsigned long&gt;(reg[1]);
02796         <span class="keywordflow">return</span> sign==POSITIVE ? value : -(<span class="keywordtype">signed</span> <span class="keywordtype">long</span>)value;
02797 }
02798 
<a name="l02799"></a><a class="code" href="class_integer.html#_integerz37_8">02799</a> <a class="code" href="class_integer.html#_integerz37_0">Integer::Integer</a>(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &amp;encodedInteger, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> byteCount, Signedness s)
02800 {
02801         Decode(encodedInteger, byteCount, s);
02802 }
02803 
<a name="l02804"></a><a class="code" href="class_integer.html#_integerz37_7">02804</a> <a class="code" href="class_integer.html#_integerz37_0">Integer::Integer</a>(<span class="keyword">const</span> byte *encodedInteger, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> byteCount, Signedness s)
02805 {
02806         Decode(encodedInteger, byteCount, s);
02807 }
02808 
<a name="l02809"></a><a class="code" href="class_integer.html#_integerz37_9">02809</a> <a class="code" href="class_integer.html#_integerz37_0">Integer::Integer</a>(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &amp;bt)
02810 {
02811         BERDecode(bt);
02812 }
02813 
<a name="l02814"></a><a class="code" href="class_integer.html#_integerz37_10">02814</a> <a class="code" href="class_integer.html#_integerz37_0">Integer::Integer</a>(<a class="code" href="class_random_number_generator.html">RandomNumberGenerator</a> &amp;rng, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> bitcount)
02815 {
02816         Randomize(rng, bitcount);
02817 }
02818 
<a name="l02819"></a><a class="code" href="class_integer.html#_integerz37_11">02819</a> <a class="code" href="class_integer.html#_integerz37_0">Integer::Integer</a>(<a class="code" href="class_random_number_generator.html">RandomNumberGenerator</a> &amp;rng, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;min, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;max, RandomNumberType rnType, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;equiv, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;mod)
02820 {
02821         <span class="keywordflow">if</span> (!Randomize(rng, min, max, rnType, equiv, mod))
02822                 <span class="keywordflow">throw</span> Integer::RandomNumberNotFound();
02823 }
02824 
<a name="l02825"></a><a class="code" href="class_integer.html#_integerz37_15">02825</a> <a class="code" href="class_integer.html">Integer</a> <a class="code" href="class_integer.html#_integerz37_15">Integer::Power2</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> e)
02826 {
02827         <a class="code" href="class_integer.html">Integer</a> r((word)0, BitsToWords(e+1));
02828         r.<a class="code" href="class_integer.html#_integerz43_15">SetBit</a>(e);
02829         <span class="keywordflow">return</span> r;
02830 }
02831 
02832 <span class="keyword">template</span> &lt;<span class="keywordtype">long</span> i&gt;
02833 <span class="keyword">struct </span>NewInteger
02834 {
02835         <a class="code" href="class_integer.html">Integer</a> * operator()()<span class="keyword"> const</span>
02836 <span class="keyword">        </span>{
02837                 <span class="keywordflow">return</span> <span class="keyword">new</span> <a class="code" href="class_integer.html">Integer</a>(i);
02838         }
02839 };
02840 
<a name="l02841"></a><a class="code" href="class_integer.html#_integerz37_12">02841</a> <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;<a class="code" href="class_integer.html#_integerz37_12">Integer::Zero</a>()
02842 {
02843         <span class="keywordflow">return</span> <a class="code" href="class_singleton.html">Singleton&lt;Integer&gt;</a>().Ref();
02844 }
02845 
<a name="l02846"></a><a class="code" href="class_integer.html#_integerz37_13">02846</a> <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;<a class="code" href="class_integer.html#_integerz37_13">Integer::One</a>()
02847 {
02848         <span class="keywordflow">return</span> <a class="code" href="class_singleton.html">Singleton&lt;Integer, NewInteger&lt;1&gt;</a> &gt;().Ref();
02849 }
02850 
<a name="l02851"></a><a class="code" href="class_integer.html#_integerz37_14">02851</a> <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;<a class="code" href="class_integer.html#_integerz37_14">Integer::Two</a>()
02852 {
02853         <span class="keywordflow">return</span> <a class="code" href="class_singleton.html">Singleton&lt;Integer, NewInteger&lt;2&gt;</a> &gt;().Ref();
02854 }
02855 
02856 <span class="keywordtype">bool</span> Integer::operator!()<span class="keyword"> const</span>
02857 <span class="keyword"></span>{
02858         <span class="keywordflow">return</span> IsNegative() ? <span class="keyword">false</span> : (reg[0]==0 &amp;&amp; <a class="code" href="class_integer.html#_integerz41_4">WordCount</a>()==0);
02859 }
02860 
02861 <a class="code" href="class_integer.html">Integer</a>&amp; Integer::operator=(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a>&amp; t)
02862 {
02863         <span class="keywordflow">if</span> (<span class="keyword">this</span> != &amp;t)
02864         {
02865                 reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta21">New</a>(RoundupSize(t.WordCount()));
02866                 CopyWords(reg, t.reg, reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>());
02867                 sign = t.sign;
02868         }
02869         <span class="keywordflow">return</span> *<span class="keyword">this</span>;
02870 }
02871 
<a name="l02872"></a><a class="code" href="class_integer.html#_integerz41_5">02872</a> <span class="keywordtype">bool</span> <a class="code" href="class_integer.html#_integerz41_5">Integer::GetBit</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> n)<span class="keyword"> const</span>
02873 <span class="keyword"></span>{
02874         <span class="keywordflow">if</span> (n/WORD_BITS &gt;= reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>())
02875                 <span class="keywordflow">return</span> 0;
02876         <span class="keywordflow">else</span>
02877                 <span class="keywordflow">return</span> bool((reg[n/WORD_BITS] &gt;&gt; (n % WORD_BITS)) &amp; 1);
02878 }
02879 
<a name="l02880"></a><a class="code" href="class_integer.html#_integerz43_15">02880</a> <span class="keywordtype">void</span> <a class="code" href="class_integer.html#_integerz43_15">Integer::SetBit</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> n, <span class="keywordtype">bool</span> value)
02881 {
02882         <span class="keywordflow">if</span> (value)
02883         {
02884                 reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta24">CleanGrow</a>(RoundupSize(BitsToWords(n+1)));
02885                 reg[n/WORD_BITS] |= (word(1) &lt;&lt; (n%WORD_BITS));
02886         }
02887         <span class="keywordflow">else</span>
02888         {
02889                 <span class="keywordflow">if</span> (n/WORD_BITS &lt; reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>())
02890                         reg[n/WORD_BITS] &amp;= ~(word(1) &lt;&lt; (n%WORD_BITS));
02891         }
02892 }
02893 
<a name="l02894"></a><a class="code" href="class_integer.html#_integerz41_6">02894</a> byte <a class="code" href="class_integer.html#_integerz41_6">Integer::GetByte</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> n)<span class="keyword"> const</span>
02895 <span class="keyword"></span>{
02896         <span class="keywordflow">if</span> (n/WORD_SIZE &gt;= reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>())
02897                 <span class="keywordflow">return</span> 0;
02898         <span class="keywordflow">else</span>
02899                 <span class="keywordflow">return</span> byte(reg[n/WORD_SIZE] &gt;&gt; ((n%WORD_SIZE)*8));
02900 }
02901 
<a name="l02902"></a><a class="code" href="class_integer.html#_integerz43_16">02902</a> <span class="keywordtype">void</span> <a class="code" href="class_integer.html#_integerz43_16">Integer::SetByte</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> n, byte value)
02903 {
02904         reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta24">CleanGrow</a>(RoundupSize(BytesToWords(n+1)));
02905         reg[n/WORD_SIZE] &amp;= ~(word(0xff) &lt;&lt; 8*(n%WORD_SIZE));
02906         reg[n/WORD_SIZE] |= (word(value) &lt;&lt; 8*(n%WORD_SIZE));
02907 }
02908 
<a name="l02909"></a><a class="code" href="class_integer.html#_integerz41_7">02909</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> <a class="code" href="class_integer.html#_integerz41_7">Integer::GetBits</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> n)<span class="keyword"> const</span>
02910 <span class="keyword"></span>{
02911         assert(n &lt;= <span class="keyword">sizeof</span>(<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>)*8);
02912         <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> v = 0;
02913         <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> j=0; j&lt;n; j++)
02914                 v |= <a class="code" href="class_integer.html#_integerz41_5">GetBit</a>(i+j) &lt;&lt; j;
02915         <span class="keywordflow">return</span> v;
02916 }
02917 
02918 <a class="code" href="class_integer.html">Integer</a> Integer::operator-()<span class="keyword"> const</span>
02919 <span class="keyword"></span>{
02920         <a class="code" href="class_integer.html">Integer</a> result(*<span class="keyword">this</span>);
02921         result.<a class="code" href="class_integer.html#_integerz43_17">Negate</a>();
02922         <span class="keywordflow">return</span> result;
02923 }
02924 
02925 <a class="code" href="class_integer.html">Integer</a> Integer::AbsoluteValue()<span class="keyword"> const</span>
02926 <span class="keyword"></span>{
02927         <a class="code" href="class_integer.html">Integer</a> result(*<span class="keyword">this</span>);
02928         result.<a class="code" href="class_integer.html#_integerr1">sign</a> = POSITIVE;
02929         <span class="keywordflow">return</span> result;
02930 }
02931 
02932 <span class="keywordtype">void</span> Integer::swap(<a class="code" href="class_integer.html">Integer</a> &amp;a)
02933 {
02934         reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta26">swap</a>(a.reg);
02935         std::swap(sign, a.sign);
02936 }
02937 
02938 <a class="code" href="class_integer.html#_integerz37_0">Integer::Integer</a>(word value, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length)
02939         : reg(RoundupSize(length)), sign(POSITIVE)
02940 {
02941         reg[0] = value;
02942         SetWords(reg+1, 0, reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>()-1);
02943 }
02944 
02945 <span class="keyword">template</span> &lt;<span class="keyword">class</span> T&gt;
02946 <span class="keyword">static</span> <a class="code" href="class_integer.html">Integer</a> StringToInteger(<span class="keyword">const</span> T *str)
02947 {
02948         word radix;
02949         <span class="comment">// GCC workaround</span>
02950         <span class="comment">// std::char_traits doesn't exist in GCC 2.x</span>
02951         <span class="comment">// std::char_traits&lt;wchar_t&gt;::length() not defined in GCC 3.2 and STLport 4.5.3</span>
02952         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length;
02953         <span class="keywordflow">for</span> (length = 0; str[length] != 0; length++) {}
02954 
02955         <a class="code" href="class_integer.html">Integer</a> v;
02956 
02957         <span class="keywordflow">if</span> (length == 0)
02958                 <span class="keywordflow">return</span> v;
02959 
02960         <span class="keywordflow">switch</span> (str[length-1])
02961         {
02962         <span class="keywordflow">case</span> <span class="charliteral">'h'</span>:
02963         <span class="keywordflow">case</span> <span class="charliteral">'H'</span>:
02964                 radix=16;
02965                 <span class="keywordflow">break</span>;
02966         <span class="keywordflow">case</span> <span class="charliteral">'o'</span>:
02967         <span class="keywordflow">case</span> <span class="charliteral">'O'</span>:
02968                 radix=8;
02969                 <span class="keywordflow">break</span>;
02970         <span class="keywordflow">case</span> <span class="charliteral">'b'</span>:
02971         <span class="keywordflow">case</span> <span class="charliteral">'B'</span>:
02972                 radix=2;
02973                 <span class="keywordflow">break</span>;
02974         <span class="keywordflow">default</span>:
02975                 radix=10;
02976         }
02977 
02978         <span class="keywordflow">if</span> (length &gt; 2 &amp;&amp; str[0] == <span class="charliteral">'0'</span> &amp;&amp; str[1] == <span class="charliteral">'x'</span>)
02979                 radix = 16;
02980 
02981         <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i=0; i&lt;length; i++)
02982         {
02983                 word digit;
02984 
02985                 <span class="keywordflow">if</span> (str[i] &gt;= <span class="charliteral">'0'</span> &amp;&amp; str[i] &lt;= <span class="charliteral">'9'</span>)
02986                         digit = str[i] - <span class="charliteral">'0'</span>;
02987                 <span class="keywordflow">else</span> <span class="keywordflow">if</span> (str[i] &gt;= <span class="charliteral">'A'</span> &amp;&amp; str[i] &lt;= <span class="charliteral">'F'</span>)
02988                         digit = str[i] - <span class="charliteral">'A'</span> + 10;
02989                 <span class="keywordflow">else</span> <span class="keywordflow">if</span> (str[i] &gt;= <span class="charliteral">'a'</span> &amp;&amp; str[i] &lt;= <span class="charliteral">'f'</span>)
02990                         digit = str[i] - <span class="charliteral">'a'</span> + 10;
02991                 <span class="keywordflow">else</span>
02992                         digit = radix;
02993 
02994                 <span class="keywordflow">if</span> (digit &lt; radix)
02995                 {
02996                         v *= radix;
02997                         v += digit;
02998                 }
02999         }
03000 
03001         <span class="keywordflow">if</span> (str[0] == <span class="charliteral">'-'</span>)
03002                 v.<a class="code" href="class_integer.html#_integerz43_17">Negate</a>();
03003 
03004         <span class="keywordflow">return</span> v;
03005 }
03006 
<a name="l03007"></a><a class="code" href="class_integer.html#_integerz37_5">03007</a> <a class="code" href="class_integer.html#_integerz37_0">Integer::Integer</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> *str)
03008         : reg(2), sign(POSITIVE)
03009 {
03010         *<span class="keyword">this</span> = StringToInteger(str);
03011 }
03012 
03013 <a class="code" href="class_integer.html#_integerz37_0">Integer::Integer</a>(<span class="keyword">const</span> <span class="keywordtype">wchar_t</span> *str)
03014         : reg(2), sign(POSITIVE)
03015 {
03016         *<span class="keyword">this</span> = StringToInteger(str);
03017 }
03018 
<a name="l03019"></a><a class="code" href="class_integer.html#_integerz41_4">03019</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="class_integer.html#_integerz41_4">Integer::WordCount</a>()<span class="keyword"> const</span>
03020 <span class="keyword"></span>{
03021         <span class="keywordflow">return</span> CountWords(reg, reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>());
03022 }
03023 
<a name="l03024"></a><a class="code" href="class_integer.html#_integerz41_3">03024</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="class_integer.html#_integerz41_3">Integer::ByteCount</a>()<span class="keyword"> const</span>
03025 <span class="keyword"></span>{
03026         <span class="keywordtype">unsigned</span> wordCount = <a class="code" href="class_integer.html#_integerz41_4">WordCount</a>();
03027         <span class="keywordflow">if</span> (wordCount)
03028                 <span class="keywordflow">return</span> (wordCount-1)*WORD_SIZE + BytePrecision(reg[wordCount-1]);
03029         <span class="keywordflow">else</span>
03030                 <span class="keywordflow">return</span> 0;
03031 }
03032 
<a name="l03033"></a><a class="code" href="class_integer.html#_integerz41_2">03033</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="class_integer.html#_integerz41_2">Integer::BitCount</a>()<span class="keyword"> const</span>
03034 <span class="keyword"></span>{
03035         <span class="keywordtype">unsigned</span> wordCount = <a class="code" href="class_integer.html#_integerz41_4">WordCount</a>();
03036         <span class="keywordflow">if</span> (wordCount)
03037                 <span class="keywordflow">return</span> (wordCount-1)*WORD_BITS + BitPrecision(reg[wordCount-1]);
03038         <span class="keywordflow">else</span>
03039                 <span class="keywordflow">return</span> 0;
03040 }
03041 
03042 <span class="keywordtype">void</span> Integer::Decode(<span class="keyword">const</span> byte *input, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> inputLen, Signedness s)
03043 {
03044         <a class="code" href="class_string_store.html">StringStore</a> store(input, inputLen);
03045         Decode(store, inputLen, s);
03046 }
03047 
03048 <span class="keywordtype">void</span> Integer::Decode(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &amp;bt, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> inputLen, Signedness s)
03049 {
03050         assert(bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_0">MaxRetrievable</a>() &gt;= inputLen);
03051 
03052         byte b;
03053         bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_4">Peek</a>(b);
03054         sign = ((s==SIGNED) &amp;&amp; (b &amp; 0x80)) ? NEGATIVE : POSITIVE;
03055 
03056         <span class="keywordflow">while</span> (inputLen&gt;0 &amp;&amp; (sign==POSITIVE ? b==0 : b==0xff))
03057         {
03058                 bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_11">Skip</a>(1);
03059                 inputLen--;
03060                 bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_4">Peek</a>(b);
03061         }
03062 
03063         reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta22">CleanNew</a>(RoundupSize(BytesToWords(inputLen)));
03064 
03065         <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=inputLen; i &gt; 0; i--)
03066         {
03067                 bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_2">Get</a>(b);
03068                 reg[(i-1)/WORD_SIZE] |= word(b) &lt;&lt; ((i-1)%WORD_SIZE)*8;
03069         }
03070 
03071         <span class="keywordflow">if</span> (sign == NEGATIVE)
03072         {
03073                 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i=inputLen; i&lt;reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>()*WORD_SIZE; i++)
03074                         reg[i/WORD_SIZE] |= word(0xff) &lt;&lt; (i%WORD_SIZE)*8;
03075                 TwosComplement(reg, reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>());
03076         }
03077 }
03078 
<a name="l03079"></a><a class="code" href="class_integer.html#_integerz39_0">03079</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="class_integer.html#_integerz39_0">Integer::MinEncodedSize</a>(Signedness signedness)<span class="keyword"> const</span>
03080 <span class="keyword"></span>{
03081         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> outputLen = STDMAX(1U, <a class="code" href="class_integer.html#_integerz41_3">ByteCount</a>());
03082         <span class="keywordflow">if</span> (signedness == UNSIGNED)
03083                 <span class="keywordflow">return</span> outputLen;
03084         <span class="keywordflow">if</span> (NotNegative() &amp;&amp; (<a class="code" href="class_integer.html#_integerz41_6">GetByte</a>(outputLen-1) &amp; 0x80))
03085                 outputLen++;
03086         <span class="keywordflow">if</span> (IsNegative() &amp;&amp; *<span class="keyword">this</span> &lt; -<a class="code" href="class_integer.html#_integerz37_15">Power2</a>(outputLen*8-1))
03087                 outputLen++;
03088         <span class="keywordflow">return</span> outputLen;
03089 }
03090 
<a name="l03091"></a><a class="code" href="class_integer.html#_integerz39_1">03091</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="class_integer.html#_integerz39_1">Integer::Encode</a>(byte *output, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> outputLen, Signedness signedness)<span class="keyword"> const</span>
03092 <span class="keyword"></span>{
03093         <a class="code" href="class_array_sink.html">ArraySink</a> sink(output, outputLen);
03094         <span class="keywordflow">return</span> <a class="code" href="class_integer.html#_integerz39_1">Encode</a>(sink, outputLen, signedness);
03095 }
03096 
03097 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> Integer::Encode(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &amp;bt, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> outputLen, Signedness signedness)<span class="keyword"> const</span>
03098 <span class="keyword"></span>{
03099         <span class="keywordflow">if</span> (signedness == UNSIGNED || NotNegative())
03100         {
03101                 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=outputLen; i &gt; 0; i--)
03102                         bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_0">Put</a>(GetByte(i-1));
03103         }
03104         <span class="keywordflow">else</span>
03105         {
03106                 <span class="comment">// take two's complement of *this</span>
03107                 <a class="code" href="class_integer.html">Integer</a> temp = <a class="code" href="class_integer.html#_integerz37_15">Integer::Power2</a>(8*STDMAX(<a class="code" href="class_integer.html#_integerz41_3">ByteCount</a>(), outputLen)) + *<span class="keyword">this</span>;
03108                 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i=0; i&lt;outputLen; i++)
03109                         bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_0">Put</a>(temp.<a class="code" href="class_integer.html#_integerz41_6">GetByte</a>(outputLen-i-1));
03110         }
03111         <span class="keywordflow">return</span> outputLen;
03112 }
03113 
<a name="l03114"></a><a class="code" href="class_integer.html#_integerz39_3">03114</a> <span class="keywordtype">void</span> <a class="code" href="class_integer.html#_integerz39_3">Integer::DEREncode</a>(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &amp;bt)<span class="keyword"> const</span>
03115 <span class="keyword"></span>{
03116         <a class="code" href="class_d_e_r_general_encoder.html">DERGeneralEncoder</a> enc(bt, INTEGER);
03117         <a class="code" href="class_integer.html#_integerz39_1">Encode</a>(enc, <a class="code" href="class_integer.html#_integerz39_0">MinEncodedSize</a>(SIGNED), SIGNED);
03118         enc.<a class="code" href="class_d_e_r_general_encoder.html#_d_e_r_set_encodera2">MessageEnd</a>();
03119 }
03120 
03121 <span class="keywordtype">void</span> Integer::BERDecode(<span class="keyword">const</span> byte *input, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> len)
03122 {
03123         <a class="code" href="class_string_store.html">StringStore</a> store(input, len);
03124         BERDecode(store);
03125 }
03126 
<a name="l03127"></a><a class="code" href="class_integer.html#_integerz39_10">03127</a> <span class="keywordtype">void</span> Integer::BERDecode(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &amp;bt)
03128 {
03129         <a class="code" href="class_b_e_r_general_decoder.html">BERGeneralDecoder</a> dec(bt, INTEGER);
03130         <span class="keywordflow">if</span> (!dec.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera2">IsDefiniteLength</a>() || dec.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_0">MaxRetrievable</a>() &lt; dec.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera3">RemainingLength</a>())
03131                 BERDecodeError();
03132         Decode(dec, dec.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera3">RemainingLength</a>(), SIGNED);
03133         dec.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera9">MessageEnd</a>();
03134 }
03135 
<a name="l03136"></a><a class="code" href="class_integer.html#_integerz39_4">03136</a> <span class="keywordtype">void</span> <a class="code" href="class_integer.html#_integerz39_4">Integer::DEREncodeAsOctetString</a>(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &amp;bt, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length)<span class="keyword"> const</span>
03137 <span class="keyword"></span>{
03138         <a class="code" href="class_d_e_r_general_encoder.html">DERGeneralEncoder</a> enc(bt, OCTET_STRING);
03139         <a class="code" href="class_integer.html#_integerz39_1">Encode</a>(enc, length);
03140         enc.<a class="code" href="class_d_e_r_general_encoder.html#_d_e_r_set_encodera2">MessageEnd</a>();
03141 }
03142 
<a name="l03143"></a><a class="code" href="class_integer.html#_integerz39_11">03143</a> <span class="keywordtype">void</span> <a class="code" href="class_integer.html#_integerz39_11">Integer::BERDecodeAsOctetString</a>(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &amp;bt, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length)
03144 {
03145         <a class="code" href="class_b_e_r_general_decoder.html">BERGeneralDecoder</a> dec(bt, OCTET_STRING);
03146         <span class="keywordflow">if</span> (!dec.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera2">IsDefiniteLength</a>() || dec.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera3">RemainingLength</a>() != length)
03147                 BERDecodeError();
03148         Decode(dec, length);
03149         dec.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera9">MessageEnd</a>();
03150 }
03151 
<a name="l03152"></a><a class="code" href="class_integer.html#_integerz39_5">03152</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="class_integer.html#_integerz39_5">Integer::OpenPGPEncode</a>(byte *output, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> len)<span class="keyword"> const</span>
03153 <span class="keyword"></span>{
03154         <a class="code" href="class_array_sink.html">ArraySink</a> sink(output, len);
03155         <span class="keywordflow">return</span> <a class="code" href="class_integer.html#_integerz39_5">OpenPGPEncode</a>(sink);
03156 }
03157 
<a name="l03158"></a><a class="code" href="class_integer.html#_integerz39_6">03158</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="class_integer.html#_integerz39_5">Integer::OpenPGPEncode</a>(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &amp;bt)<span class="keyword"> const</span>
03159 <span class="keyword"></span>{
03160         word16 bitCount = <a class="code" href="class_integer.html#_integerz41_2">BitCount</a>();
03161         bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_2">PutWord16</a>(bitCount);
03162         <span class="keywordflow">return</span> 2 + <a class="code" href="class_integer.html#_integerz39_1">Encode</a>(bt, BitsToBytes(bitCount));
03163 }
03164 
03165 <span class="keywordtype">void</span> Integer::OpenPGPDecode(<span class="keyword">const</span> byte *input, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> len)
03166 {
03167         <a class="code" href="class_string_store.html">StringStore</a> store(input, len);
03168         OpenPGPDecode(store);
03169 }
03170 
03171 <span class="keywordtype">void</span> Integer::OpenPGPDecode(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &amp;bt)
03172 {
03173         word16 bitCount;
03174         <span class="keywordflow">if</span> (bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_6">GetWord16</a>(bitCount) != 2 || bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_0">MaxRetrievable</a>() &lt; BitsToBytes(bitCount))
03175                 <span class="keywordflow">throw</span> OpenPGPDecodeErr();
03176         Decode(bt, BitsToBytes(bitCount));
03177 }
03178 
03179 <span class="keywordtype">void</span> Integer::Randomize(<a class="code" href="class_random_number_generator.html">RandomNumberGenerator</a> &amp;rng, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nbits)
03180 {
03181         <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nbytes = nbits/8 + 1;
03182         <a class="code" href="class_sec_block.html">SecByteBlock</a> buf(nbytes);
03183         rng.<a class="code" href="class_random_number_generator.html#_x917_r_n_ga4">GenerateBlock</a>(buf, nbytes);
03184         <span class="keywordflow">if</span> (nbytes)
03185                 buf[0] = (byte)Crop(buf[0], nbits % 8);
03186         Decode(buf, nbytes, UNSIGNED);
03187 }
03188 
03189 <span class="keywordtype">void</span> Integer::Randomize(<a class="code" href="class_random_number_generator.html">RandomNumberGenerator</a> &amp;rng, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;min, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;max)
03190 {
03191         <span class="keywordflow">if</span> (min &gt; max)
03192                 <span class="keywordflow">throw</span> <a class="code" href="class_invalid_argument.html">InvalidArgument</a>(<span class="stringliteral">"Integer: Min must be no greater than Max"</span>);
03193 
03194         <a class="code" href="class_integer.html">Integer</a> range = max - min;
03195         <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nbits = range.<a class="code" href="class_integer.html#_integerz41_2">BitCount</a>();
03196 
03197         <span class="keywordflow">do</span>
03198         {
03199                 Randomize(rng, nbits);
03200         }
03201         <span class="keywordflow">while</span> (*<span class="keyword">this</span> &gt; range);
03202 
03203         *<span class="keyword">this</span> += min;
03204 }
03205 
<a name="l03206"></a><a class="code" href="class_integer.html#_integerz43_12">03206</a> <span class="keywordtype">bool</span> Integer::Randomize(<a class="code" href="class_random_number_generator.html">RandomNumberGenerator</a> &amp;rng, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;min, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;max, RandomNumberType rnType, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;equiv, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;mod)
03207 {
03208         <span class="keywordflow">return</span> GenerateRandomNoThrow(rng, MakeParameters(<span class="stringliteral">"Min"</span>, min)(<span class="stringliteral">"Max"</span>, max)(<span class="stringliteral">"RandomNumberType"</span>, rnType)(<span class="stringliteral">"EquivalentTo"</span>, equiv)(<span class="stringliteral">"Mod"</span>, mod));
03209 }
03210 
03211 <span class="keyword">class </span>KDF2_RNG : <span class="keyword">public</span> <a class="code" href="class_random_number_generator.html">RandomNumberGenerator</a>
03212 {
03213 <span class="keyword">public</span>:
03214         KDF2_RNG(<span class="keyword">const</span> byte *seed, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> seedSize)
03215                 : m_counter(0), m_counterAndSeed(seedSize + 4)
03216         {
03217                 memcpy(m_counterAndSeed + 4, seed, seedSize);
03218         }
03219 
03220         byte <a class="code" href="class_random_number_generator.html#_random_number_generatora0">GenerateByte</a>()
03221         {
03222                 byte b;
03223                 GenerateBlock(&amp;b, 1);
03224                 <span class="keywordflow">return</span> b;
03225         }
03226 
03227         <span class="keywordtype">void</span> GenerateBlock(byte *output, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> size)
03228         {
03229                 UnalignedPutWord(BIG_ENDIAN_ORDER, m_counterAndSeed, m_counter);
03230                 ++m_counter;
03231                 <a class="code" href="class_p1363___k_d_f2.html">P1363_KDF2&lt;SHA1&gt;::DeriveKey</a>(output, size, m_counterAndSeed, m_counterAndSeed.size(), NULL, 0);
03232         }
03233 
03234 <span class="keyword">private</span>:
03235         word32 m_counter;
03236         <a class="code" href="class_sec_block.html">SecByteBlock</a> m_counterAndSeed;
03237 };
03238 
03239 <span class="keywordtype">bool</span> Integer::GenerateRandomNoThrow(<a class="code" href="class_random_number_generator.html">RandomNumberGenerator</a> &amp;i_rng, <span class="keyword">const</span> <a class="code" href="class_name_value_pairs.html">NameValuePairs</a> &amp;params)
03240 {
03241         <a class="code" href="class_integer.html">Integer</a> min = params.<a class="code" href="class_name_value_pairs.html#_x_t_r___d_ha40">GetValueWithDefault</a>(<span class="stringliteral">"Min"</span>, Integer::Zero());
03242         <a class="code" href="class_integer.html">Integer</a> max;
03243         <span class="keywordflow">if</span> (!params.<a class="code" href="class_name_value_pairs.html#_x_t_r___d_ha39">GetValue</a>(<span class="stringliteral">"Max"</span>, max))
03244         {
03245                 <span class="keywordtype">int</span> bitLength;
03246                 <span class="keywordflow">if</span> (params.<a class="code" href="class_name_value_pairs.html#_x_t_r___d_ha42">GetIntValue</a>(<span class="stringliteral">"BitLength"</span>, bitLength))
03247                         max = <a class="code" href="class_integer.html#_integerz37_15">Integer::Power2</a>(bitLength);
03248                 <span class="keywordflow">else</span>
03249                         <span class="keywordflow">throw</span> <a class="code" href="class_invalid_argument.html">InvalidArgument</a>(<span class="stringliteral">"Integer: missing Max argument"</span>);
03250         }
03251         <span class="keywordflow">if</span> (min &gt; max)
03252                 <span class="keywordflow">throw</span> <a class="code" href="class_invalid_argument.html">InvalidArgument</a>(<span class="stringliteral">"Integer: Min must be no greater than Max"</span>);
03253 
03254         <a class="code" href="class_integer.html">Integer</a> equiv = params.<a class="code" href="class_name_value_pairs.html#_x_t_r___d_ha40">GetValueWithDefault</a>(<span class="stringliteral">"EquivalentTo"</span>, Integer::Zero());
03255         <a class="code" href="class_integer.html">Integer</a> mod = params.<a class="code" href="class_name_value_pairs.html#_x_t_r___d_ha40">GetValueWithDefault</a>(<span class="stringliteral">"Mod"</span>, Integer::One());
03256 
03257         <span class="keywordflow">if</span> (equiv.<a class="code" href="class_integer.html#_integerz41_10">IsNegative</a>() || equiv &gt;= mod)
03258                 <span class="keywordflow">throw</span> <a class="code" href="class_invalid_argument.html">InvalidArgument</a>(<span class="stringliteral">"Integer: invalid EquivalentTo and/or Mod argument"</span>);
03259 
03260         Integer::RandomNumberType rnType = params.<a class="code" href="class_name_value_pairs.html#_x_t_r___d_ha40">GetValueWithDefault</a>(<span class="stringliteral">"RandomNumberType"</span>, Integer::ANY);
03261 
03262         member_ptr&lt;KDF2_RNG&gt; kdf2Rng;
03263         <a class="code" href="class_const_byte_array_parameter.html">ConstByteArrayParameter</a> seed;
03264         <span class="keywordflow">if</span> (params.<a class="code" href="class_name_value_pairs.html#_x_t_r___d_ha39">GetValue</a>(<span class="stringliteral">"Seed"</span>, seed))
03265         {
03266                 <a class="code" href="class_byte_queue.html">ByteQueue</a> bq;
03267                 <a class="code" href="class_d_e_r_sequence_encoder.html">DERSequenceEncoder</a> seq(bq);
03268                 min.<a class="code" href="class_integer.html#_integerz39_3">DEREncode</a>(seq);
03269                 max.<a class="code" href="class_integer.html#_integerz39_3">DEREncode</a>(seq);
03270                 equiv.<a class="code" href="class_integer.html#_integerz39_3">DEREncode</a>(seq);
03271                 mod.<a class="code" href="class_integer.html#_integerz39_3">DEREncode</a>(seq);
03272                 DEREncodeUnsigned(seq, rnType);
03273                 DEREncodeOctetString(seq, seed.<a class="code" href="class_const_byte_array_parameter.html#_const_byte_array_parametera4">begin</a>(), seed.<a class="code" href="class_const_byte_array_parameter.html#_const_byte_array_parametera6">size</a>());
03274                 seq.<a class="code" href="class_d_e_r_general_encoder.html#_d_e_r_set_encodera2">MessageEnd</a>();
03275 
03276                 <a class="code" href="class_sec_block.html">SecByteBlock</a> finalSeed(bq.<a class="code" href="class_byte_queue.html#_d_e_r_set_encodera3">MaxRetrievable</a>());
03277                 bq.<a class="code" href="class_byte_queue.html#_d_e_r_set_encodera8">Get</a>(finalSeed, finalSeed.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>());
03278                 kdf2Rng.reset(<span class="keyword">new</span> KDF2_RNG(finalSeed.<a class="code" href="class_sec_block.html#_sec_block_with_hinta9">begin</a>(), finalSeed.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>()));
03279         }
03280         <a class="code" href="class_random_number_generator.html">RandomNumberGenerator</a> &amp;rng = kdf2Rng.get() ? (<a class="code" href="class_random_number_generator.html">RandomNumberGenerator</a> &amp;)*kdf2Rng : i_rng;
03281 
03282         <span class="keywordflow">switch</span> (rnType)
03283         {
03284                 <span class="keywordflow">case</span> ANY:
03285                         <span class="keywordflow">if</span> (mod == <a class="code" href="class_integer.html#_integerz37_13">One</a>())
03286                                 Randomize(rng, min, max);
03287                         <span class="keywordflow">else</span>
03288                         {
03289                                 <a class="code" href="class_integer.html">Integer</a> min1 = min + (equiv-min)%mod;
03290                                 <span class="keywordflow">if</span> (max &lt; min1)
03291                                         <span class="keywordflow">return</span> <span class="keyword">false</span>;
03292                                 Randomize(rng, <a class="code" href="class_integer.html#_integerz37_12">Zero</a>(), (max - min1) / mod);
03293                                 *<span class="keyword">this</span> *= mod;
03294                                 *<span class="keyword">this</span> += min1;
03295                         }
03296                         <span class="keywordflow">return</span> <span class="keyword">true</span>;
03297 
03298                 <span class="keywordflow">case</span> PRIME:
03299                 {
03300                         <span class="keyword">const</span> PrimeSelector *pSelector = params.<a class="code" href="class_name_value_pairs.html#_x_t_r___d_ha40">GetValueWithDefault</a>(Name::PointerToPrimeSelector(), (<span class="keyword">const</span> PrimeSelector *)NULL);
03301 
03302                         <span class="keywordtype">int</span> i;
03303                         i = 0;
03304                         <span class="keywordflow">while</span> (1)
03305                         {
03306                                 <span class="keywordflow">if</span> (++i==16)
03307                                 {
03308                                         <span class="comment">// check if there are any suitable primes in [min, max]</span>
03309                                         <a class="code" href="class_integer.html">Integer</a> first = min;
03310                                         <span class="keywordflow">if</span> (FirstPrime(first, max, equiv, mod, pSelector))
03311                                         {
03312                                                 <span class="comment">// if there is only one suitable prime, we're done</span>
03313                                                 *<span class="keyword">this</span> = first;
03314                                                 <span class="keywordflow">if</span> (!FirstPrime(first, max, equiv, mod, pSelector))
03315                                                         <span class="keywordflow">return</span> <span class="keyword">true</span>;
03316                                         }
03317                                         <span class="keywordflow">else</span>
03318                                                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
03319                                 }
03320 
03321                                 Randomize(rng, min, max);
03322                                 <span class="keywordflow">if</span> (FirstPrime(*<span class="keyword">this</span>, STDMIN(*<span class="keyword">this</span>+mod*PrimeSearchInterval(max), max), equiv, mod, pSelector))
03323                                         <span class="keywordflow">return</span> <span class="keyword">true</span>;
03324                         }
03325                 }
03326 
03327                 <span class="keywordflow">default</span>:
03328                         <span class="keywordflow">throw</span> <a class="code" href="class_invalid_argument.html">InvalidArgument</a>(<span class="stringliteral">"Integer: invalid RandomNumberType argument"</span>);
03329         }
03330 }
03331 
03332 std::istream&amp; operator&gt;&gt;(std::istream&amp; in, <a class="code" href="class_integer.html">Integer</a> &amp;a)
03333 {
03334         <span class="keywordtype">char</span> c;
03335         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length = 0;
03336         <a class="code" href="class_sec_block.html">SecBlock&lt;char&gt;</a> str(length + 16);
03337 
03338         std::ws(in);
03339 
03340         <span class="keywordflow">do</span>
03341         {
03342                 in.read(&amp;c, 1);
03343                 str[length++] = c;
03344                 <span class="keywordflow">if</span> (length &gt;= str.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>())
03345                         str.<a class="code" href="class_sec_block.html#_sec_block_with_hinta23">Grow</a>(length + 16);
03346         }
03347         <span class="keywordflow">while</span> (in &amp;&amp; (c==<span class="charliteral">'-'</span> || c==<span class="charliteral">'x'</span> || (c&gt;=<span class="charliteral">'0'</span> &amp;&amp; c&lt;='9') || (c&gt;=<span class="charliteral">'a'</span> &amp;&amp; c&lt;='f') || (c&gt;=<span class="charliteral">'A'</span> &amp;&amp; c&lt;=<span class="charliteral">'F'</span>) || c==<span class="charliteral">'h'</span> || c==<span class="charliteral">'H'</span> || c==<span class="charliteral">'o'</span> || c==<span class="charliteral">'O'</span> || c==<span class="charliteral">','</span> || c==<span class="charliteral">'.'</span>));
03348 
03349         <span class="keywordflow">if</span> (in.gcount())
03350                 in.putback(c);
03351         str[length-1] = <span class="charliteral">'\0'</span>;
03352         a = <a class="code" href="class_integer.html">Integer</a>(str);
03353 
03354         <span class="keywordflow">return</span> in;
03355 }
03356 
03357 std::ostream&amp; operator&lt;&lt;(std::ostream&amp; out, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;a)
03358 {
03359         <span class="comment">// Get relevant conversion specifications from ostream.</span>
03360         <span class="keywordtype">long</span> f = out.flags() &amp; std::ios::basefield; <span class="comment">// Get base digits.</span>
03361         <span class="keywordtype">int</span> base, block;
03362         <span class="keywordtype">char</span> suffix;
03363         <span class="keywordflow">switch</span>(f)
03364         {
03365         <span class="keywordflow">case</span> std::ios::oct :
03366                 base = 8;
03367                 block = 8;
03368                 suffix = <span class="charliteral">'o'</span>;
03369                 <span class="keywordflow">break</span>;
03370         <span class="keywordflow">case</span> std::ios::hex :
03371                 base = 16;
03372                 block = 4;
03373                 suffix = <span class="charliteral">'h'</span>;
03374                 <span class="keywordflow">break</span>;
03375         <span class="keywordflow">default</span> :
03376                 base = 10;
03377                 block = 3;
03378                 suffix = <span class="charliteral">'.'</span>;
03379         }
03380 
03381         <a class="code" href="class_sec_block.html">SecBlock&lt;char&gt;</a> s(a.BitCount() / (BitPrecision(base)-1) + 1);
03382         <a class="code" href="class_integer.html">Integer</a> temp1=a, temp2;
03383         <span class="keywordtype">unsigned</span> i=0;
03384         <span class="keyword">const</span> <span class="keywordtype">char</span> vec[]=<span class="stringliteral">"0123456789ABCDEF"</span>;
03385 
03386         <span class="keywordflow">if</span> (a.IsNegative())
03387         {
03388                 out &lt;&lt; <span class="charliteral">'-'</span>;
03389                 temp1.<a class="code" href="class_integer.html#_integerz43_17">Negate</a>();
03390         }
03391 
03392         <span class="keywordflow">if</span> (!a)
03393                 out &lt;&lt; <span class="charliteral">'0'</span>;
03394 
03395         <span class="keywordflow">while</span> (!!temp1)
03396         {
03397                 word digit;
03398                 <a class="code" href="class_integer.html#_integerz49_9">Integer::Divide</a>(digit, temp2, temp1, base);
03399                 s[i++]=vec[digit];
03400                 temp1=temp2;
03401         }
03402 
03403         <span class="keywordflow">while</span> (i--)
03404         {
03405                 out &lt;&lt; s[i];
03406 <span class="comment">//              if (i &amp;&amp; !(i%block))</span>
03407 <span class="comment">//                      out &lt;&lt; ",";</span>
03408         }
03409         <span class="keywordflow">return</span> out &lt;&lt; suffix;
03410 }
03411 
03412 <a class="code" href="class_integer.html">Integer</a>&amp; Integer::operator++()
03413 {
03414         <span class="keywordflow">if</span> (NotNegative())
03415         {
03416                 <span class="keywordflow">if</span> (Increment(reg, reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>()))
03417                 {
03418                         reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta24">CleanGrow</a>(2*reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>());
03419                         reg[reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>()/2]=1;
03420                 }
03421         }
03422         <span class="keywordflow">else</span>
03423         {
03424                 word borrow = Decrement(reg, reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>());
03425                 assert(!borrow);
03426                 <span class="keywordflow">if</span> (<a class="code" href="class_integer.html#_integerz41_4">WordCount</a>()==0)
03427                         *<span class="keyword">this</span> = <a class="code" href="class_integer.html#_integerz37_12">Zero</a>();
03428         }
03429         <span class="keywordflow">return</span> *<span class="keyword">this</span>;
03430 }
03431 
03432 <a class="code" href="class_integer.html">Integer</a>&amp; Integer::operator--()
03433 {
03434         <span class="keywordflow">if</span> (IsNegative())
03435         {
03436                 <span class="keywordflow">if</span> (Increment(reg, reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>()))
03437                 {
03438                         reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta24">CleanGrow</a>(2*reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>());
03439                         reg[reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>()/2]=1;
03440                 }
03441         }
03442         <span class="keywordflow">else</span>
03443         {
03444                 <span class="keywordflow">if</span> (Decrement(reg, reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>()))
03445                         *<span class="keyword">this</span> = -<a class="code" href="class_integer.html#_integerz37_13">One</a>();
03446         }
03447         <span class="keywordflow">return</span> *<span class="keyword">this</span>;
03448 }
03449 
03450 <span class="keywordtype">void</span> PositiveAdd(<a class="code" href="class_integer.html">Integer</a> &amp;sum, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;a, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a>&amp; b)
03451 {
03452         word carry;
03453         <span class="keywordflow">if</span> (a.reg.size() == b.reg.size())
03454                 carry = Add(sum.<a class="code" href="class_integer.html#_integerr0">reg</a>, a.reg, b.reg, a.reg.size());
03455         <span class="keywordflow">else</span> <span class="keywordflow">if</span> (a.reg.size() &gt; b.reg.size())
03456         {
03457                 carry = Add(sum.<a class="code" href="class_integer.html#_integerr0">reg</a>, a.reg, b.reg, b.reg.size());
03458                 CopyWords(sum.<a class="code" href="class_integer.html#_integerr0">reg</a>+b.reg.size(), a.reg+b.reg.size(), a.reg.size()-b.reg.size());
03459                 carry = Increment(sum.<a class="code" href="class_integer.html#_integerr0">reg</a>+b.reg.size(), a.reg.size()-b.reg.size(), carry);
03460         }
03461         <span class="keywordflow">else</span>
03462         {
03463                 carry = Add(sum.<a class="code" href="class_integer.html#_integerr0">reg</a>, a.reg, b.reg, a.reg.size());
03464                 CopyWords(sum.<a class="code" href="class_integer.html#_integerr0">reg</a>+a.reg.size(), b.reg+a.reg.size(), b.reg.size()-a.reg.size());
03465                 carry = Increment(sum.<a class="code" href="class_integer.html#_integerr0">reg</a>+a.reg.size(), b.reg.size()-a.reg.size(), carry);
03466         }
03467 
03468         <span class="keywordflow">if</span> (carry)
03469         {
03470                 sum.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta24">CleanGrow</a>(2*sum.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>());
03471                 sum.<a class="code" href="class_integer.html#_integerr0">reg</a>[sum.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>()/2] = 1;
03472         }
03473         sum.<a class="code" href="class_integer.html#_integerr1">sign</a> = Integer::POSITIVE;
03474 }
03475 
03476 <span class="keywordtype">void</span> PositiveSubtract(<a class="code" href="class_integer.html">Integer</a> &amp;diff, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;a, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a>&amp; b)
03477 {
03478         <span class="keywordtype">unsigned</span> aSize = a.WordCount();
03479         aSize += aSize%2;
03480         <span class="keywordtype">unsigned</span> bSize = b.WordCount();
03481         bSize += bSize%2;
03482 
03483         <span class="keywordflow">if</span> (aSize == bSize)
03484         {
03485                 <span class="keywordflow">if</span> (Compare(a.reg, b.reg, aSize) &gt;= 0)
03486                 {
03487                         Subtract(diff.<a class="code" href="class_integer.html#_integerr0">reg</a>, a.reg, b.reg, aSize);
03488                         diff.<a class="code" href="class_integer.html#_integerr1">sign</a> = Integer::POSITIVE;
03489                 }
03490                 <span class="keywordflow">else</span>
03491                 {
03492                         Subtract(diff.<a class="code" href="class_integer.html#_integerr0">reg</a>, b.reg, a.reg, aSize);
03493                         diff.<a class="code" href="class_integer.html#_integerr1">sign</a> = Integer::NEGATIVE;
03494                 }
03495         }
03496         <span class="keywordflow">else</span> <span class="keywordflow">if</span> (aSize &gt; bSize)
03497         {
03498                 word borrow = Subtract(diff.<a class="code" href="class_integer.html#_integerr0">reg</a>, a.reg, b.reg, bSize);
03499                 CopyWords(diff.<a class="code" href="class_integer.html#_integerr0">reg</a>+bSize, a.reg+bSize, aSize-bSize);
03500                 borrow = Decrement(diff.<a class="code" href="class_integer.html#_integerr0">reg</a>+bSize, aSize-bSize, borrow);
03501                 assert(!borrow);
03502                 diff.<a class="code" href="class_integer.html#_integerr1">sign</a> = Integer::POSITIVE;
03503         }
03504         <span class="keywordflow">else</span>
03505         {
03506                 word borrow = Subtract(diff.<a class="code" href="class_integer.html#_integerr0">reg</a>, b.reg, a.reg, aSize);
03507                 CopyWords(diff.<a class="code" href="class_integer.html#_integerr0">reg</a>+aSize, b.reg+aSize, bSize-aSize);
03508                 borrow = Decrement(diff.<a class="code" href="class_integer.html#_integerr0">reg</a>+aSize, bSize-aSize, borrow);
03509                 assert(!borrow);
03510                 diff.<a class="code" href="class_integer.html#_integerr1">sign</a> = Integer::NEGATIVE;
03511         }
03512 }
03513 
03514 <a class="code" href="class_integer.html">Integer</a> Integer::Plus(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a>&amp; b)<span class="keyword"> const</span>
03515 <span class="keyword"></span>{
03516         <a class="code" href="class_integer.html">Integer</a> sum((word)0, STDMAX(reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>(), b.reg.size()));
03517         <span class="keywordflow">if</span> (NotNegative())
03518         {
03519                 <span class="keywordflow">if</span> (b.NotNegative())
03520                         PositiveAdd(sum, *<span class="keyword">this</span>, b);
03521                 <span class="keywordflow">else</span>
03522                         PositiveSubtract(sum, *<span class="keyword">this</span>, b);
03523         }
03524         <span class="keywordflow">else</span>
03525         {
03526                 <span class="keywordflow">if</span> (b.NotNegative())
03527                         PositiveSubtract(sum, b, *<span class="keyword">this</span>);
03528                 <span class="keywordflow">else</span>
03529                 {
03530                         PositiveAdd(sum, *<span class="keyword">this</span>, b);
03531                         sum.<a class="code" href="class_integer.html#_integerr1">sign</a> = Integer::NEGATIVE;
03532                 }
03533         }
03534         <span class="keywordflow">return</span> sum;
03535 }
03536 
03537 <a class="code" href="class_integer.html">Integer</a>&amp; Integer::operator+=(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a>&amp; t)
03538 {
03539         reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta24">CleanGrow</a>(t.reg.size());
03540         <span class="keywordflow">if</span> (NotNegative())
03541         {
03542                 <span class="keywordflow">if</span> (t.NotNegative())
03543                         PositiveAdd(*<span class="keyword">this</span>, *<span class="keyword">this</span>, t);
03544                 <span class="keywordflow">else</span>
03545                         PositiveSubtract(*<span class="keyword">this</span>, *<span class="keyword">this</span>, t);
03546         }
03547         <span class="keywordflow">else</span>
03548         {
03549                 <span class="keywordflow">if</span> (t.NotNegative())
03550                         PositiveSubtract(*<span class="keyword">this</span>, t, *<span class="keyword">this</span>);
03551                 <span class="keywordflow">else</span>
03552                 {
03553                         PositiveAdd(*<span class="keyword">this</span>, *<span class="keyword">this</span>, t);
03554                         sign = Integer::NEGATIVE;
03555                 }
03556         }
03557         <span class="keywordflow">return</span> *<span class="keyword">this</span>;
03558 }
03559 
03560 <a class="code" href="class_integer.html">Integer</a> Integer::Minus(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a>&amp; b)<span class="keyword"> const</span>
03561 <span class="keyword"></span>{
03562         <a class="code" href="class_integer.html">Integer</a> diff((word)0, STDMAX(reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>(), b.reg.size()));
03563         <span class="keywordflow">if</span> (NotNegative())
03564         {
03565                 <span class="keywordflow">if</span> (b.NotNegative())
03566                         PositiveSubtract(diff, *<span class="keyword">this</span>, b);
03567                 <span class="keywordflow">else</span>
03568                         PositiveAdd(diff, *<span class="keyword">this</span>, b);
03569         }
03570         <span class="keywordflow">else</span>
03571         {
03572                 <span class="keywordflow">if</span> (b.NotNegative())
03573                 {
03574                         PositiveAdd(diff, *<span class="keyword">this</span>, b);
03575                         diff.<a class="code" href="class_integer.html#_integerr1">sign</a> = Integer::NEGATIVE;
03576                 }
03577                 <span class="keywordflow">else</span>
03578                         PositiveSubtract(diff, b, *<span class="keyword">this</span>);
03579         }
03580         <span class="keywordflow">return</span> diff;
03581 }
03582 
03583 <a class="code" href="class_integer.html">Integer</a>&amp; Integer::operator-=(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a>&amp; t)
03584 {
03585         reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta24">CleanGrow</a>(t.reg.size());
03586         <span class="keywordflow">if</span> (NotNegative())
03587         {
03588                 <span class="keywordflow">if</span> (t.NotNegative())
03589                         PositiveSubtract(*<span class="keyword">this</span>, *<span class="keyword">this</span>, t);
03590                 <span class="keywordflow">else</span>
03591                         PositiveAdd(*<span class="keyword">this</span>, *<span class="keyword">this</span>, t);
03592         }
03593         <span class="keywordflow">else</span>
03594         {
03595                 <span class="keywordflow">if</span> (t.NotNegative())
03596                 {
03597                         PositiveAdd(*<span class="keyword">this</span>, *<span class="keyword">this</span>, t);
03598                         sign = Integer::NEGATIVE;
03599                 }
03600                 <span class="keywordflow">else</span>
03601                         PositiveSubtract(*<span class="keyword">this</span>, t, *<span class="keyword">this</span>);
03602         }
03603         <span class="keywordflow">return</span> *<span class="keyword">this</span>;
03604 }
03605 
03606 <a class="code" href="class_integer.html">Integer</a>&amp; Integer::operator&lt;&lt;=(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> n)
03607 {
03608         <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> wordCount = <a class="code" href="class_integer.html#_integerz41_4">WordCount</a>();
03609         <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> shiftWords = n / WORD_BITS;
03610         <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> shiftBits = n % WORD_BITS;
03611 
03612         reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta24">CleanGrow</a>(RoundupSize(wordCount+BitsToWords(n)));
03613         ShiftWordsLeftByWords(reg, wordCount + shiftWords, shiftWords);
03614         ShiftWordsLeftByBits(reg+shiftWords, wordCount+BitsToWords(shiftBits), shiftBits);
03615         <span class="keywordflow">return</span> *<span class="keyword">this</span>;
03616 }
03617 
03618 <a class="code" href="class_integer.html">Integer</a>&amp; Integer::operator&gt;&gt;=(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> n)
03619 {
03620         <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> wordCount = <a class="code" href="class_integer.html#_integerz41_4">WordCount</a>();
03621         <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> shiftWords = n / WORD_BITS;
03622         <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> shiftBits = n % WORD_BITS;
03623 
03624         ShiftWordsRightByWords(reg, wordCount, shiftWords);
03625         <span class="keywordflow">if</span> (wordCount &gt; shiftWords)
03626                 ShiftWordsRightByBits(reg, wordCount-shiftWords, shiftBits);
03627         <span class="keywordflow">if</span> (IsNegative() &amp;&amp; <a class="code" href="class_integer.html#_integerz41_4">WordCount</a>()==0)   <span class="comment">// avoid -0</span>
03628                 *<span class="keyword">this</span> = <a class="code" href="class_integer.html#_integerz37_12">Zero</a>();
03629         <span class="keywordflow">return</span> *<span class="keyword">this</span>;
03630 }
03631 
03632 <span class="keywordtype">void</span> PositiveMultiply(<a class="code" href="class_integer.html">Integer</a> &amp;product, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;a, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;b)
03633 {
03634         <span class="keywordtype">unsigned</span> aSize = RoundupSize(a.WordCount());
03635         <span class="keywordtype">unsigned</span> bSize = RoundupSize(b.WordCount());
03636 
03637         product.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta22">CleanNew</a>(RoundupSize(aSize+bSize));
03638         product.<a class="code" href="class_integer.html#_integerr1">sign</a> = Integer::POSITIVE;
03639 
03640         <a class="code" href="class_sec_block.html">SecAlignedWordBlock</a> workspace(aSize + bSize);
03641         AsymmetricMultiply(product.<a class="code" href="class_integer.html#_integerr0">reg</a>, workspace, a.reg, aSize, b.reg, bSize);
03642 }
03643 
03644 <span class="keywordtype">void</span> Multiply(<a class="code" href="class_integer.html">Integer</a> &amp;product, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;a, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;b)
03645 {
03646         PositiveMultiply(product, a, b);
03647 
03648         <span class="keywordflow">if</span> (a.NotNegative() != b.NotNegative())
03649                 product.<a class="code" href="class_integer.html#_integerz43_17">Negate</a>();
03650 }
03651 
03652 <a class="code" href="class_integer.html">Integer</a> Integer::Times(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;b)<span class="keyword"> const</span>
03653 <span class="keyword"></span>{
03654         <a class="code" href="class_integer.html">Integer</a> product;
03655         Multiply(product, *<span class="keyword">this</span>, b);
03656         <span class="keywordflow">return</span> product;
03657 }
03658 
03659 <span class="comment">/*</span>
03660 <span class="comment">void PositiveDivide(Integer &amp;remainder, Integer &amp;quotient,</span>
03661 <span class="comment">                                   const Integer &amp;dividend, const Integer &amp;divisor)</span>
03662 <span class="comment">{</span>
03663 <span class="comment">        remainder.reg.CleanNew(divisor.reg.size());</span>
03664 <span class="comment">        remainder.sign = Integer::POSITIVE;</span>
03665 <span class="comment">        quotient.reg.New(0);</span>
03666 <span class="comment">        quotient.sign = Integer::POSITIVE;</span>
03667 <span class="comment">        unsigned i=dividend.BitCount();</span>
03668 <span class="comment">        while (i--)</span>
03669 <span class="comment">        {</span>
03670 <span class="comment">                word overflow = ShiftWordsLeftByBits(remainder.reg, remainder.reg.size(), 1);</span>
03671 <span class="comment">                remainder.reg[0] |= dividend[i];</span>
03672 <span class="comment">                if (overflow || remainder &gt;= divisor)</span>
03673 <span class="comment">                {</span>
03674 <span class="comment">                        Subtract(remainder.reg, remainder.reg, divisor.reg, remainder.reg.size());</span>
03675 <span class="comment">                        quotient.SetBit(i);</span>
03676 <span class="comment">                }</span>
03677 <span class="comment">        }</span>
03678 <span class="comment">}</span>
03679 <span class="comment">*/</span>
03680 
03681 <span class="keywordtype">void</span> PositiveDivide(<a class="code" href="class_integer.html">Integer</a> &amp;remainder, <a class="code" href="class_integer.html">Integer</a> &amp;quotient,
03682                                    <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;a, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;b)
03683 {
03684         <span class="keywordtype">unsigned</span> aSize = a.WordCount();
03685         <span class="keywordtype">unsigned</span> bSize = b.WordCount();
03686 
03687         <span class="keywordflow">if</span> (!bSize)
03688                 <span class="keywordflow">throw</span> <a class="code" href="class_integer_1_1_divide_by_zero.html">Integer::DivideByZero</a>();
03689 
03690         <span class="keywordflow">if</span> (a.PositiveCompare(b) == -1)
03691         {
03692                 remainder = a;
03693                 remainder.<a class="code" href="class_integer.html#_integerr1">sign</a> = Integer::POSITIVE;
03694                 quotient = <a class="code" href="class_integer.html#_integerz37_12">Integer::Zero</a>();
03695                 <span class="keywordflow">return</span>;
03696         }
03697 
03698         aSize += aSize%2;       <span class="comment">// round up to next even number</span>
03699         bSize += bSize%2;
03700 
03701         remainder.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta22">CleanNew</a>(RoundupSize(bSize));
03702         remainder.<a class="code" href="class_integer.html#_integerr1">sign</a> = Integer::POSITIVE;
03703         quotient.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta22">CleanNew</a>(RoundupSize(aSize-bSize+2));
03704         quotient.<a class="code" href="class_integer.html#_integerr1">sign</a> = Integer::POSITIVE;
03705 
03706         <a class="code" href="class_sec_block.html">SecAlignedWordBlock</a> T(aSize+2*bSize+4);
03707         Divide(remainder.<a class="code" href="class_integer.html#_integerr0">reg</a>, quotient.<a class="code" href="class_integer.html#_integerr0">reg</a>, T, a.reg, aSize, b.reg, bSize);
03708 }
03709 
03710 <span class="keywordtype">void</span> <a class="code" href="class_integer.html#_integerz49_9">Integer::Divide</a>(<a class="code" href="class_integer.html">Integer</a> &amp;remainder, <a class="code" href="class_integer.html">Integer</a> &amp;quotient, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;dividend, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;divisor)
<a name="l03711"></a><a class="code" href="class_integer.html#_integerz49_9">03711</a> {
03712         PositiveDivide(remainder, quotient, dividend, divisor);
03713 
03714         <span class="keywordflow">if</span> (dividend.<a class="code" href="class_integer.html#_integerz41_10">IsNegative</a>())
03715         {
03716                 quotient.<a class="code" href="class_integer.html#_integerz43_17">Negate</a>();
03717                 <span class="keywordflow">if</span> (remainder.<a class="code" href="class_integer.html#_integerz41_9">NotZero</a>())
03718                 {
03719                         --quotient;
03720                         remainder = divisor.<a class="code" href="class_integer.html#_integerz49_0">AbsoluteValue</a>() - remainder;
03721                 }
03722         }
03723 
03724         <span class="keywordflow">if</span> (divisor.<a class="code" href="class_integer.html#_integerz41_10">IsNegative</a>())
03725                 quotient.<a class="code" href="class_integer.html#_integerz43_17">Negate</a>();
03726 }
03727 
03728 <span class="keywordtype">void</span> Integer::DivideByPowerOf2(<a class="code" href="class_integer.html">Integer</a> &amp;r, <a class="code" href="class_integer.html">Integer</a> &amp;q, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;a, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> n)
<a name="l03729"></a><a class="code" href="class_integer.html#_integerz49_11">03729</a> {
03730         q = a;
03731         q &gt;&gt;= n;
03732 
03733         <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> wordCount = BitsToWords(n);
03734         <span class="keywordflow">if</span> (wordCount &lt;= a.WordCount())
03735         {
03736                 r.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta25">resize</a>(RoundupSize(wordCount));
03737                 CopyWords(r.<a class="code" href="class_integer.html#_integerr0">reg</a>, a.reg, wordCount);
03738                 SetWords(r.<a class="code" href="class_integer.html#_integerr0">reg</a>+wordCount, 0, r.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>()-wordCount);
03739                 <span class="keywordflow">if</span> (n % WORD_BITS != 0)
03740                         r.<a class="code" href="class_integer.html#_integerr0">reg</a>[wordCount-1] %= (1 &lt;&lt; (n % WORD_BITS));
03741         }
03742         <span class="keywordflow">else</span>
03743         {
03744                 r.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta25">resize</a>(RoundupSize(a.WordCount()));
03745                 CopyWords(r.<a class="code" href="class_integer.html#_integerr0">reg</a>, a.reg, r.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>());
03746         }
03747         r.<a class="code" href="class_integer.html#_integerr1">sign</a> = POSITIVE;
03748 
03749         <span class="keywordflow">if</span> (a.IsNegative() &amp;&amp; r.<a class="code" href="class_integer.html#_integerz41_9">NotZero</a>())
03750         {
03751                 --q;
03752                 r = <a class="code" href="class_integer.html#_integerz37_15">Power2</a>(n) - r;
03753         }
03754 }
03755 
03756 <a class="code" href="class_integer.html">Integer</a> Integer::DividedBy(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;b)<span class="keyword"> const</span>
03757 <span class="keyword"></span>{
03758         <a class="code" href="class_integer.html">Integer</a> remainder, quotient;
03759         Integer::Divide(remainder, quotient, *<span class="keyword">this</span>, b);
03760         <span class="keywordflow">return</span> quotient;
03761 }
03762 
03763 <a class="code" href="class_integer.html">Integer</a> Integer::Modulo(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;b)<span class="keyword"> const</span>
03764 <span class="keyword"></span>{
03765         <a class="code" href="class_integer.html">Integer</a> remainder, quotient;
03766         <a class="code" href="class_integer.html#_integerz49_9">Integer::Divide</a>(remainder, quotient, *<span class="keyword">this</span>, b);
03767         <span class="keywordflow">return</span> remainder;
03768 }
03769 
03770 <span class="keywordtype">void</span> <a class="code" href="class_integer.html#_integerz49_9">Integer::Divide</a>(word &amp;remainder, <a class="code" href="class_integer.html">Integer</a> &amp;quotient, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;dividend, word divisor)
<a name="l03771"></a><a class="code" href="class_integer.html#_integerz49_10">03771</a> {
03772         <span class="keywordflow">if</span> (!divisor)
03773                 <span class="keywordflow">throw</span> <a class="code" href="class_integer_1_1_divide_by_zero.html">Integer::DivideByZero</a>();
03774 
03775         assert(divisor);
03776 
03777         <span class="keywordflow">if</span> ((divisor &amp; (divisor-1)) == 0)       <span class="comment">// divisor is a power of 2</span>
03778         {
03779                 quotient = dividend &gt;&gt; (BitPrecision(divisor)-1);
03780                 remainder = dividend.<a class="code" href="class_integer.html#_integerr0">reg</a>[0] &amp; (divisor-1);
03781                 <span class="keywordflow">return</span>;
03782         }
03783 
03784         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i = dividend.<a class="code" href="class_integer.html#_integerz41_4">WordCount</a>();
03785         quotient.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta22">CleanNew</a>(RoundupSize(i));
03786         remainder = 0;
03787         <span class="keywordflow">while</span> (i--)
03788         {
03789                 quotient.<a class="code" href="class_integer.html#_integerr0">reg</a>[i] = DWord(dividend.<a class="code" href="class_integer.html#_integerr0">reg</a>[i], remainder) / divisor;
03790                 remainder = DWord(dividend.<a class="code" href="class_integer.html#_integerr0">reg</a>[i], remainder) % divisor;
03791         }
03792 
03793         <span class="keywordflow">if</span> (dividend.<a class="code" href="class_integer.html#_integerz41_11">NotNegative</a>())
03794                 quotient.<a class="code" href="class_integer.html#_integerr1">sign</a> = POSITIVE;
03795         <span class="keywordflow">else</span>
03796         {
03797                 quotient.<a class="code" href="class_integer.html#_integerr1">sign</a> = NEGATIVE;
03798                 <span class="keywordflow">if</span> (remainder)
03799                 {
03800                         --quotient;
03801                         remainder = divisor - remainder;
03802                 }
03803         }
03804 }
03805 
03806 <a class="code" href="class_integer.html">Integer</a> Integer::DividedBy(word b)<span class="keyword"> const</span>
03807 <span class="keyword"></span>{
03808         word remainder;
03809         <a class="code" href="class_integer.html">Integer</a> quotient;
03810         Integer::Divide(remainder, quotient, *<span class="keyword">this</span>, b);
03811         <span class="keywordflow">return</span> quotient;
03812 }
03813 
03814 word Integer::Modulo(word divisor)<span class="keyword"> const</span>
03815 <span class="keyword"></span>{
03816         <span class="keywordflow">if</span> (!divisor)
03817                 <span class="keywordflow">throw</span> <a class="code" href="class_integer_1_1_divide_by_zero.html">Integer::DivideByZero</a>();
03818 
03819         assert(divisor);
03820 
03821         word remainder;
03822 
03823         <span class="keywordflow">if</span> ((divisor &amp; (divisor-1)) == 0)       <span class="comment">// divisor is a power of 2</span>
03824                 remainder = reg[0] &amp; (divisor-1);
03825         <span class="keywordflow">else</span>
03826         {
03827                 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i = <a class="code" href="class_integer.html#_integerz41_4">WordCount</a>();
03828 
03829                 <span class="keywordflow">if</span> (divisor &lt;= 5)
03830                 {
03831                         DWord sum(0, 0);
03832                         <span class="keywordflow">while</span> (i--)
03833                                 sum += reg[i];
03834                         remainder = sum % divisor;
03835                 }
03836                 <span class="keywordflow">else</span>
03837                 {
03838                         remainder = 0;
03839                         <span class="keywordflow">while</span> (i--)
03840                                 remainder = DWord(reg[i], remainder) % divisor;
03841                 }
03842         }
03843 
03844         <span class="keywordflow">if</span> (IsNegative() &amp;&amp; remainder)
03845                 remainder = divisor - remainder;
03846 
03847         <span class="keywordflow">return</span> remainder;
03848 }
03849 
03850 <span class="keywordtype">void</span> Integer::Negate()
03851 {
03852         <span class="keywordflow">if</span> (!!(*this))  <span class="comment">// don't flip sign if *this==0</span>
03853                 sign = Sign(1-sign);
03854 }
03855 
03856 <span class="keywordtype">int</span> Integer::PositiveCompare(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a>&amp; t)<span class="keyword"> const</span>
03857 <span class="keyword"></span>{
03858         <span class="keywordtype">unsigned</span> size = <a class="code" href="class_integer.html#_integerz41_4">WordCount</a>(), tSize = t.WordCount();
03859 
03860         <span class="keywordflow">if</span> (size == tSize)
03861                 <span class="keywordflow">return</span> CryptoPP::Compare(reg, t.reg, size);
03862         <span class="keywordflow">else</span>
03863                 <span class="keywordflow">return</span> size &gt; tSize ? 1 : -1;
03864 }
03865 
03866 <span class="keywordtype">int</span> <a class="code" href="class_integer.html#_integerz47_0">Integer::Compare</a>(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a>&amp; t)<span class="keyword"> const</span>
<a name="l03867"></a><a class="code" href="class_integer.html#_integerz47_0">03867</a> <span class="keyword"></span>{
03868         <span class="keywordflow">if</span> (NotNegative())
03869         {
03870                 <span class="keywordflow">if</span> (t.NotNegative())
03871                         <span class="keywordflow">return</span> PositiveCompare(t);
03872                 <span class="keywordflow">else</span>
03873                         <span class="keywordflow">return</span> 1;
03874         }
03875         <span class="keywordflow">else</span>
03876         {
03877                 <span class="keywordflow">if</span> (t.NotNegative())
03878                         <span class="keywordflow">return</span> -1;
03879                 <span class="keywordflow">else</span>
03880                         <span class="keywordflow">return</span> -PositiveCompare(t);
03881         }
03882 }
03883 
03884 <a class="code" href="class_integer.html">Integer</a> <a class="code" href="class_integer.html#_integerz49_3">Integer::SquareRoot</a>()<span class="keyword"> const</span>
<a name="l03885"></a><a class="code" href="class_integer.html#_integerz49_3">03885</a> <span class="keyword"></span>{
03886         <span class="keywordflow">if</span> (!IsPositive())
03887                 <span class="keywordflow">return</span> <a class="code" href="class_integer.html#_integerz37_12">Zero</a>();
03888 
03889         <span class="comment">// overestimate square root</span>
03890         <a class="code" href="class_integer.html">Integer</a> x, y = <a class="code" href="class_integer.html#_integerz37_15">Power2</a>((<a class="code" href="class_integer.html#_integerz41_2">BitCount</a>()+1)/2);
03891         assert(y*y &gt;= *<span class="keyword">this</span>);
03892 
03893         <span class="keywordflow">do</span>
03894         {
03895                 x = y;
03896                 y = (x + *<span class="keyword">this</span>/x) &gt;&gt; 1;
03897         } <span class="keywordflow">while</span> (y&lt;x);
03898 
03899         <span class="keywordflow">return</span> x;
03900 }
03901 
03902 <span class="keywordtype">bool</span> <a class="code" href="class_integer.html#_integerz49_4">Integer::IsSquare</a>()<span class="keyword"> const</span>
<a name="l03903"></a><a class="code" href="class_integer.html#_integerz49_4">03903</a> <span class="keyword"></span>{
03904         <a class="code" href="class_integer.html">Integer</a> r = <a class="code" href="class_integer.html#_integerz49_3">SquareRoot</a>();
03905         <span class="keywordflow">return</span> *<span class="keyword">this</span> == r.<a class="code" href="class_integer.html#_integerz49_2">Squared</a>();
03906 }
03907 
03908 <span class="keywordtype">bool</span> <a class="code" href="class_integer.html#_integerz49_5">Integer::IsUnit</a>()<span class="keyword"> const</span>
<a name="l03909"></a><a class="code" href="class_integer.html#_integerz49_5">03909</a> <span class="keyword"></span>{
03910         <span class="keywordflow">return</span> (<a class="code" href="class_integer.html#_integerz41_4">WordCount</a>() == 1) &amp;&amp; (reg[0] == 1);
03911 }
03912 
03913 <a class="code" href="class_integer.html">Integer</a> <a class="code" href="class_integer.html#_integerz49_6">Integer::MultiplicativeInverse</a>()<span class="keyword"> const</span>
<a name="l03914"></a><a class="code" href="class_integer.html#_integerz49_6">03914</a> <span class="keyword"></span>{
03915         <span class="keywordflow">return</span> <a class="code" href="class_integer.html#_integerz49_5">IsUnit</a>() ? *<span class="keyword">this</span> : <a class="code" href="class_integer.html#_integerz37_12">Zero</a>();
03916 }
03917 
03918 <a class="code" href="class_integer.html">Integer</a> a_times_b_mod_c(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;x, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a>&amp; y, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a>&amp; m)
<a name="l03919"></a><a class="code" href="class_integer.html#_integerz49_13">03919</a> {
03920         <span class="keywordflow">return</span> x*y%m;
03921 }
03922 
03923 <a class="code" href="class_integer.html">Integer</a> a_exp_b_mod_c(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;x, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a>&amp; e, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a>&amp; m)
<a name="l03924"></a><a class="code" href="class_integer.html#_integerz49_14">03924</a> {
03925         <a class="code" href="class_modular_arithmetic.html">ModularArithmetic</a> mr(m);
03926         <span class="keywordflow">return</span> mr.<a class="code" href="class_abstract_ring.html#_euclidean_domain_ofa19">Exponentiate</a>(x, e);
03927 }
03928 
03929 <a class="code" href="class_integer.html">Integer</a> Integer::Gcd(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;a, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;b)
<a name="l03930"></a><a class="code" href="class_integer.html#_integerz49_12">03930</a> {
03931         <span class="keywordflow">return</span> <a class="code" href="class_euclidean_domain_of.html">EuclideanDomainOf&lt;Integer&gt;</a>().<a class="code" href="class_integer.html#_integerz49_12">Gcd</a>(a, b);
03932 }
03933 
03934 <a class="code" href="class_integer.html">Integer</a> Integer::InverseMod(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;m)<span class="keyword"> const</span>
<a name="l03935"></a><a class="code" href="class_integer.html#_integerz49_7">03935</a> <span class="keyword"></span>{
03936         assert(m.<a class="code" href="class_integer.html#_integerz41_11">NotNegative</a>());
03937 
03938         <span class="keywordflow">if</span> (IsNegative() || *<span class="keyword">this</span>&gt;=m)
03939                 <span class="keywordflow">return</span> (*<span class="keyword">this</span>%m).<a class="code" href="class_integer.html#_integerz49_7">InverseMod</a>(m);
03940 
03941         <span class="keywordflow">if</span> (m.<a class="code" href="class_integer.html#_integerz41_14">IsEven</a>())
03942         {
03943                 <span class="keywordflow">if</span> (!m || IsEven())
03944                         <span class="keywordflow">return</span> <a class="code" href="class_integer.html#_integerz37_12">Zero</a>();  <span class="comment">// no inverse</span>
03945                 <span class="keywordflow">if</span> (*<span class="keyword">this</span> == <a class="code" href="class_integer.html#_integerz37_13">One</a>())
03946                         <span class="keywordflow">return</span> <a class="code" href="class_integer.html#_integerz37_13">One</a>();
03947 
03948                 <a class="code" href="class_integer.html">Integer</a> u = m.<a class="code" href="class_integer.html#_integerz49_7">InverseMod</a>(*<span class="keyword">this</span>);
03949                 <span class="keywordflow">return</span> !u ? <a class="code" href="class_integer.html#_integerz37_12">Zero</a>() : (m*(*<span class="keyword">this</span>-u)+1)/(*this);
03950         }
03951 
03952         <a class="code" href="class_sec_block.html">SecBlock&lt;word&gt;</a> T(m.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>() * 4);
03953         <a class="code" href="class_integer.html">Integer</a> r((word)0, m.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>());
03954         <span class="keywordtype">unsigned</span> k = AlmostInverse(r.<a class="code" href="class_integer.html#_integerr0">reg</a>, T, reg, reg.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>(), m.<a class="code" href="class_integer.html#_integerr0">reg</a>, m.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>());
03955         DivideByPower2Mod(r.<a class="code" href="class_integer.html#_integerr0">reg</a>, r.<a class="code" href="class_integer.html#_integerr0">reg</a>, k, m.<a class="code" href="class_integer.html#_integerr0">reg</a>, m.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>());
03956         <span class="keywordflow">return</span> r;
03957 }
03958 
03959 word Integer::InverseMod(<span class="keyword">const</span> word mod)<span class="keyword"> const</span>
03960 <span class="keyword"></span>{
03961         word g0 = mod, g1 = *<span class="keyword">this</span> % mod;
03962         word v0 = 0, v1 = 1;
03963         word y;
03964 
03965         <span class="keywordflow">while</span> (g1)
03966         {
03967                 <span class="keywordflow">if</span> (g1 == 1)
03968                         <span class="keywordflow">return</span> v1;
03969                 y = g0 / g1;
03970                 g0 = g0 % g1;
03971                 v0 += y * v1;
03972 
03973                 <span class="keywordflow">if</span> (!g0)
03974                         <span class="keywordflow">break</span>;
03975                 <span class="keywordflow">if</span> (g0 == 1)
03976                         <span class="keywordflow">return</span> mod-v0;
03977                 y = g1 / g0;
03978                 g1 = g1 % g0;
03979                 v1 += y * v0;
03980         }
03981         <span class="keywordflow">return</span> 0;
03982 }
03983 
03984 <span class="comment">// ********************************************************</span>
03985 
03986 ModularArithmetic::ModularArithmetic(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &amp;bt)
03987 {
03988         <a class="code" href="class_b_e_r_sequence_decoder.html">BERSequenceDecoder</a> seq(bt);
03989         <a class="code" href="class_o_i_d.html">OID</a> oid(seq);
03990         <span class="keywordflow">if</span> (oid != ASN1::prime_field())
03991                 BERDecodeError();
03992         modulus.<a class="code" href="class_integer.html#_integerz39_9">BERDecode</a>(seq);
03993         seq.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera9">MessageEnd</a>();
03994         result.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta25">resize</a>(modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>());
03995 }
03996 
03997 <span class="keywordtype">void</span> ModularArithmetic::DEREncode(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &amp;bt)<span class="keyword"> const</span>
03998 <span class="keyword"></span>{
03999         <a class="code" href="class_d_e_r_sequence_encoder.html">DERSequenceEncoder</a> seq(bt);
04000         ASN1::prime_field().DEREncode(seq);
04001         modulus.<a class="code" href="class_integer.html#_integerz39_3">DEREncode</a>(seq);
04002         seq.<a class="code" href="class_d_e_r_general_encoder.html#_d_e_r_set_encodera2">MessageEnd</a>();
04003 }
04004 
04005 <span class="keywordtype">void</span> ModularArithmetic::DEREncodeElement(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &amp;out, <span class="keyword">const</span> Element &amp;a)<span class="keyword"> const</span>
04006 <span class="keyword"></span>{
04007         a.DEREncodeAsOctetString(out, MaxElementByteLength());
04008 }
04009 
04010 <span class="keywordtype">void</span> ModularArithmetic::BERDecodeElement(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &amp;in, Element &amp;a)<span class="keyword"> const</span>
04011 <span class="keyword"></span>{
04012         a.BERDecodeAsOctetString(in, MaxElementByteLength());
04013 }
04014 
04015 <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a>&amp; ModularArithmetic::Half(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;a)<span class="keyword"> const</span>
04016 <span class="keyword"></span>{
04017         <span class="keywordflow">if</span> (a.reg.size()==modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>())
04018         {
04019                 CryptoPP::DivideByPower2Mod(result.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta9">begin</a>(), a.reg, 1, modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>, a.reg.size());
04020                 <span class="keywordflow">return</span> result;
04021         }
04022         <span class="keywordflow">else</span>
04023                 <span class="keywordflow">return</span> result1 = (a.IsEven() ? (a &gt;&gt; 1) : ((a+modulus) &gt;&gt; 1));
04024 }
04025 
04026 <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a>&amp; ModularArithmetic::Add(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;a, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;b)<span class="keyword"> const</span>
04027 <span class="keyword"></span>{
04028         <span class="keywordflow">if</span> (a.reg.size()==modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>() &amp;&amp; b.reg.size()==modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>())
04029         {
04030                 <span class="keywordflow">if</span> (CryptoPP::Add(result.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta9">begin</a>(), a.reg, b.reg, a.reg.size())
04031                         || Compare(result.<a class="code" href="class_integer.html#_integerr0">reg</a>, modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>, a.reg.size()) &gt;= 0)
04032                 {
04033                         CryptoPP::Subtract(result.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta9">begin</a>(), result.<a class="code" href="class_integer.html#_integerr0">reg</a>, modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>, a.reg.size());
04034                 }
04035                 <span class="keywordflow">return</span> result;
04036         }
04037         <span class="keywordflow">else</span>
04038         {
04039                 result1 = a+b;
04040                 <span class="keywordflow">if</span> (result1 &gt;= modulus)
04041                         result1 -= modulus;
04042                 <span class="keywordflow">return</span> result1;
04043         }
04044 }
04045 
04046 <a class="code" href="class_integer.html">Integer</a>&amp; ModularArithmetic::Accumulate(<a class="code" href="class_integer.html">Integer</a> &amp;a, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;b)<span class="keyword"> const</span>
04047 <span class="keyword"></span>{
04048         <span class="keywordflow">if</span> (a.reg.size()==modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>() &amp;&amp; b.reg.size()==modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>())
04049         {
04050                 <span class="keywordflow">if</span> (CryptoPP::Add(a.reg, a.reg, b.reg, a.reg.size())
04051                         || Compare(a.reg, modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>, a.reg.size()) &gt;= 0)
04052                 {
04053                         CryptoPP::Subtract(a.reg, a.reg, modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>, a.reg.size());
04054                 }
04055         }
04056         <span class="keywordflow">else</span>
04057         {
04058                 a+=b;
04059                 <span class="keywordflow">if</span> (a&gt;=modulus)
04060                         a-=modulus;
04061         }
04062 
04063         <span class="keywordflow">return</span> a;
04064 }
04065 
04066 <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a>&amp; ModularArithmetic::Subtract(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;a, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;b)<span class="keyword"> const</span>
04067 <span class="keyword"></span>{
04068         <span class="keywordflow">if</span> (a.reg.size()==modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>() &amp;&amp; b.reg.size()==modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>())
04069         {
04070                 <span class="keywordflow">if</span> (CryptoPP::Subtract(result.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta9">begin</a>(), a.reg, b.reg, a.reg.size()))
04071                         CryptoPP::Add(result.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta9">begin</a>(), result.<a class="code" href="class_integer.html#_integerr0">reg</a>, modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>, a.reg.size());
04072                 <span class="keywordflow">return</span> result;
04073         }
04074         <span class="keywordflow">else</span>
04075         {
04076                 result1 = a-b;
04077                 <span class="keywordflow">if</span> (result1.<a class="code" href="class_integer.html#_integerz41_10">IsNegative</a>())
04078                         result1 += modulus;
04079                 <span class="keywordflow">return</span> result1;
04080         }
04081 }
04082 
04083 <a class="code" href="class_integer.html">Integer</a>&amp; ModularArithmetic::Reduce(<a class="code" href="class_integer.html">Integer</a> &amp;a, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;b)<span class="keyword"> const</span>
04084 <span class="keyword"></span>{
04085         <span class="keywordflow">if</span> (a.reg.size()==modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>() &amp;&amp; b.reg.size()==modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>())
04086         {
04087                 <span class="keywordflow">if</span> (CryptoPP::Subtract(a.reg, a.reg, b.reg, a.reg.size()))
04088                         CryptoPP::Add(a.reg, a.reg, modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>, a.reg.size());
04089         }
04090         <span class="keywordflow">else</span>
04091         {
04092                 a-=b;
04093                 <span class="keywordflow">if</span> (a.IsNegative())
04094                         a+=modulus;
04095         }
04096 
04097         <span class="keywordflow">return</span> a;
04098 }
04099 
04100 <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a>&amp; ModularArithmetic::Inverse(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;a)<span class="keyword"> const</span>
04101 <span class="keyword"></span>{
04102         <span class="keywordflow">if</span> (!a)
04103                 <span class="keywordflow">return</span> a;
04104 
04105         CopyWords(result.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta9">begin</a>(), modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>, modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>());
04106         <span class="keywordflow">if</span> (CryptoPP::Subtract(result.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta9">begin</a>(), result.<a class="code" href="class_integer.html#_integerr0">reg</a>, a.reg, a.reg.size()))
04107                 Decrement(result.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta9">begin</a>()+a.reg.size(), 1, modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>()-a.reg.size());
04108 
04109         <span class="keywordflow">return</span> result;
04110 }
04111 
04112 <a class="code" href="class_integer.html">Integer</a> ModularArithmetic::CascadeExponentiate(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;x, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;e1, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;y, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;e2)<span class="keyword"> const</span>
04113 <span class="keyword"></span>{
04114         <span class="keywordflow">if</span> (modulus.<a class="code" href="class_integer.html#_integerz41_15">IsOdd</a>())
04115         {
04116                 <a class="code" href="class_montgomery_representation.html">MontgomeryRepresentation</a> dr(modulus);
04117                 <span class="keywordflow">return</span> dr.<a class="code" href="class_montgomery_representation.html#_montgomery_representationa4">ConvertOut</a>(dr.<a class="code" href="class_montgomery_representation.html#_montgomery_representationa9">CascadeExponentiate</a>(dr.<a class="code" href="class_montgomery_representation.html#_montgomery_representationa3">ConvertIn</a>(x), e1, dr.<a class="code" href="class_montgomery_representation.html#_montgomery_representationa3">ConvertIn</a>(y), e2));
04118         }
04119         <span class="keywordflow">else</span>
04120                 <span class="keywordflow">return</span> <a class="code" href="class_abstract_ring.html">AbstractRing&lt;Integer&gt;::CascadeExponentiate</a>(x, e1, y, e2);
04121 }
04122 
04123 <span class="keywordtype">void</span> ModularArithmetic::SimultaneousExponentiate(<a class="code" href="class_integer.html">Integer</a> *results, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;base, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> *exponents, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> exponentsCount)<span class="keyword"> const</span>
04124 <span class="keyword"></span>{
04125         <span class="keywordflow">if</span> (modulus.<a class="code" href="class_integer.html#_integerz41_15">IsOdd</a>())
04126         {
04127                 <a class="code" href="class_montgomery_representation.html">MontgomeryRepresentation</a> dr(modulus);
04128                 dr.<a class="code" href="class_montgomery_representation.html#_montgomery_representationa10">SimultaneousExponentiate</a>(results, dr.<a class="code" href="class_montgomery_representation.html#_montgomery_representationa3">ConvertIn</a>(base), exponents, exponentsCount);
04129                 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=0; i&lt;exponentsCount; i++)
04130                         results[i] = dr.<a class="code" href="class_montgomery_representation.html#_montgomery_representationa4">ConvertOut</a>(results[i]);
04131         }
04132         <span class="keywordflow">else</span>
04133                 <a class="code" href="class_abstract_ring.html">AbstractRing&lt;Integer&gt;::SimultaneousExponentiate</a>(results, base, exponents, exponentsCount);
04134 }
04135 
04136 MontgomeryRepresentation::MontgomeryRepresentation(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;m)    <span class="comment">// modulus must be odd</span>
04137         : <a class="code" href="class_modular_arithmetic.html">ModularArithmetic</a>(m),
04138           u((word)0, modulus.reg.size()),
04139           workspace(5*modulus.reg.size())
04140 {
04141         <span class="keywordflow">if</span> (!modulus.IsOdd())
04142                 <span class="keywordflow">throw</span> <a class="code" href="class_invalid_argument.html">InvalidArgument</a>(<span class="stringliteral">"MontgomeryRepresentation: Montgomery representation requires an odd modulus"</span>);
04143 
04144         RecursiveInverseModPower2(u.reg, workspace, modulus.reg, modulus.reg.size());
04145 }
04146 
04147 <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a>&amp; MontgomeryRepresentation::Multiply(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;a, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;b)<span class="keyword"> const</span>
04148 <span class="keyword"></span>{
04149         word *<span class="keyword">const</span> T = workspace.<a class="code" href="class_sec_block.html#_sec_block_with_hinta9">begin</a>();
04150         word *<span class="keyword">const</span> R = result.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta9">begin</a>();
04151         <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N = modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>();
04152         assert(a.reg.size()&lt;=N &amp;&amp; b.reg.size()&lt;=N);
04153 
04154         AsymmetricMultiply(T, T+2*N, a.reg, a.reg.size(), b.reg, b.reg.size());
04155         SetWords(T+a.reg.size()+b.reg.size(), 0, 2*N-a.reg.size()-b.reg.size());
04156         MontgomeryReduce(R, T+2*N, T, modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>, u.<a class="code" href="class_integer.html#_integerr0">reg</a>, N);
04157         <span class="keywordflow">return</span> result;
04158 }
04159 
04160 <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a>&amp; MontgomeryRepresentation::Square(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;a)<span class="keyword"> const</span>
04161 <span class="keyword"></span>{
04162         word *<span class="keyword">const</span> T = workspace.<a class="code" href="class_sec_block.html#_sec_block_with_hinta9">begin</a>();
04163         word *<span class="keyword">const</span> R = result.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta9">begin</a>();
04164         <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N = modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>();
04165         assert(a.reg.size()&lt;=N);
04166 
04167         CryptoPP::Square(T, T+2*N, a.reg, a.reg.size());
04168         SetWords(T+2*a.reg.size(), 0, 2*N-2*a.reg.size());
04169         MontgomeryReduce(R, T+2*N, T, modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>, u.<a class="code" href="class_integer.html#_integerr0">reg</a>, N);
04170         <span class="keywordflow">return</span> result;
04171 }
04172 
04173 <a class="code" href="class_integer.html">Integer</a> MontgomeryRepresentation::ConvertOut(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;a)<span class="keyword"> const</span>
04174 <span class="keyword"></span>{
04175         word *<span class="keyword">const</span> T = workspace.<a class="code" href="class_sec_block.html#_sec_block_with_hinta9">begin</a>();
04176         word *<span class="keyword">const</span> R = result.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta9">begin</a>();
04177         <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N = modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>();
04178         assert(a.reg.size()&lt;=N);
04179 
04180         CopyWords(T, a.reg, a.reg.size());
04181         SetWords(T+a.reg.size(), 0, 2*N-a.reg.size());
04182         MontgomeryReduce(R, T+2*N, T, modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>, u.<a class="code" href="class_integer.html#_integerr0">reg</a>, N);
04183         <span class="keywordflow">return</span> result;
04184 }
04185 
04186 <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a>&amp; MontgomeryRepresentation::MultiplicativeInverse(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &amp;a)<span class="keyword"> const</span>
04187 <span class="keyword"></span>{
04188 <span class="comment">//        return (EuclideanMultiplicativeInverse(a, modulus)&lt;&lt;(2*WORD_BITS*modulus.reg.size()))%modulus;</span>
04189         word *<span class="keyword">const</span> T = workspace.<a class="code" href="class_sec_block.html#_sec_block_with_hinta9">begin</a>();
04190         word *<span class="keyword">const</span> R = result.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta9">begin</a>();
04191         <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> N = modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>();
04192         assert(a.reg.size()&lt;=N);
04193 
04194         CopyWords(T, a.reg, a.reg.size());
04195         SetWords(T+a.reg.size(), 0, 2*N-a.reg.size());
04196         MontgomeryReduce(R, T+2*N, T, modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>, u.<a class="code" href="class_integer.html#_integerr0">reg</a>, N);
04197         <span class="keywordtype">unsigned</span> k = AlmostInverse(R, T, R, N, modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>, N);
04198 
04199 <span class="comment">//      cout &lt;&lt; "k=" &lt;&lt; k &lt;&lt; " N*32=" &lt;&lt; 32*N &lt;&lt; endl;</span>
04200 
04201         <span class="keywordflow">if</span> (k&gt;N*WORD_BITS)
04202                 DivideByPower2Mod(R, R, k-N*WORD_BITS, modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>, N);
04203         <span class="keywordflow">else</span>
04204                 MultiplyByPower2Mod(R, R, N*WORD_BITS-k, modulus.<a class="code" href="class_integer.html#_integerr0">reg</a>, N);
04205 
04206         <span class="keywordflow">return</span> result;
04207 }
04208 
04209 NAMESPACE_END
04210 
04211 <span class="preprocessor">#endif</span>
</div></pre><hr size="1"><address style="align: right;"><small>Generated on Sun Nov 7 08:23:58 2004 for Crypto++ by
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border=0 ></a> 1.3.7 </small></address>
</body>
</html>