added libtommath-0.15
This commit is contained in:
		
							parent
							
								
									82f4858291
								
							
						
					
					
						commit
						b1756f2f98
					
				
							
								
								
									
										372
									
								
								bn.tex
									
									
									
									
									
								
							
							
						
						
									
										372
									
								
								bn.tex
									
									
									
									
									
								
							| @ -1,7 +1,7 @@ | ||||
| \documentclass{article} | ||||
| \begin{document} | ||||
| 
 | ||||
| \title{LibTomMath v0.14 \\ A Free Multiple Precision Integer Library \\ http://math.libtomcrypt.org } | ||||
| \title{LibTomMath v0.15 \\ A Free Multiple Precision Integer Library \\ http://math.libtomcrypt.org } | ||||
| \author{Tom St Denis \\ tomstdenis@iahu.ca} | ||||
| \maketitle | ||||
| \newpage | ||||
| @ -100,6 +100,22 @@ in the order $x, y, z$.  For example: | ||||
|    mp_div_2(&x, &y);             /* y = x / 2 */ | ||||
| \end{verbatim} | ||||
| 
 | ||||
| \subsection{Various Optimizations} | ||||
| Various routines come in several ``flavours'' which are optimized for particular cases of inputs.  For instance | ||||
| the multiplicative inverse function ``mp\_invmod()'' has a routine for odd and even moduli.  Similarly the | ||||
| ``mp\_exptmod()'' function has several variants depending on the modulus as well.  Several lower level | ||||
| functions such as multiplication, squaring and reductions come in ``comba'' and ``baseline'' variants. | ||||
| 
 | ||||
| The design of LibTomMath is such that the end user does not have to concern themselves too much with these | ||||
| details.  This is why the functions provided will determine \textit{automatically} when an appropriate | ||||
| optimal function can be used.  For example, when you call ``mp\_mul()'' the routines will first determine | ||||
| if the Karatsuba multiplier should be used.  If not it will determine if the ``comba'' method can be used | ||||
| and finally call the standard catch-all ``baseline'' method. | ||||
| 
 | ||||
| Throughout the rest of this manual several variants for various functions will be referenced to as | ||||
| the ``comba'', ``baseline'', etc... method.  Keep in mind you call one function to use any of the optimal | ||||
| variants. | ||||
| 
 | ||||
| \subsection{Return Values} | ||||
| All functions that return errors will return \textbf{MP\_OKAY} if the function was succesful.  It will return  | ||||
| \textbf{MP\_MEM} if it ran out of heap memory or \textbf{MP\_VAL} if one of the arguements is out of range.   | ||||
| @ -326,10 +342,53 @@ int mp_montgomery_setup(mp_int *a, mp_digit *mp); | ||||
| /* computes xR^-1 == x (mod N) via Montgomery Reduction */ | ||||
| int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp); | ||||
| 
 | ||||
| /* returns 1 if a is a valid DR modulus */ | ||||
| int mp_dr_is_modulus(mp_int *a); | ||||
| 
 | ||||
| /* sets the value of "d" required for mp_dr_reduce */ | ||||
| void mp_dr_setup(mp_int *a, mp_digit *d); | ||||
| 
 | ||||
| /* reduces a modulo b using the Diminished Radix method */ | ||||
| int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp); | ||||
| 
 | ||||
| /* d = a^b (mod c) */ | ||||
| int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); | ||||
| \end{verbatim} | ||||
| 
 | ||||
| \subsection{Primality Routines} | ||||
| \begin{verbatim} | ||||
| /* ---> Primes <--- */ | ||||
| /* table of first 256 primes */ | ||||
| extern const mp_digit __prime_tab[]; | ||||
| 
 | ||||
| /* result=1 if a is divisible by one of the first 256 primes */ | ||||
| int mp_prime_is_divisible(mp_int *a, int *result); | ||||
| 
 | ||||
| /* performs one Fermat test of "a" using base "b".   | ||||
|  * Sets result to 0 if composite or 1 if probable prime  | ||||
|  */ | ||||
| int mp_prime_fermat(mp_int *a, mp_int *b, int *result); | ||||
| 
 | ||||
| /* performs one Miller-Rabin test of "a" using base "b". | ||||
|  * Sets result to 0 if composite or 1 if probable prime  | ||||
|  */ | ||||
| int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result); | ||||
| 
 | ||||
| /* performs t rounds of Miller-Rabin on "a" using the first | ||||
|  * t prime bases.  Also performs an initial sieve of trial | ||||
|  * division.  Determines if "a" is prime with probability | ||||
|  * of error no more than (1/4)^t. | ||||
|  * | ||||
|  * Sets result to 1 if probably prime, 0 otherwise | ||||
|  */ | ||||
| int mp_prime_is_prime(mp_int *a, int t, int *result); | ||||
| 
 | ||||
| /* finds the next prime after the number "a" using "t" trials | ||||
|  * of Miller-Rabin. | ||||
|  */ | ||||
| int mp_prime_next_prime(mp_int *a, int t); | ||||
| \end{verbatim} | ||||
| 
 | ||||
| \subsection{Radix Conversions} | ||||
| To read or store integers in other formats there are the following functions. | ||||
| 
 | ||||
| @ -533,23 +592,131 @@ $n$ is prime then $\left ( {a \over n} \right )$ is equal to $1$ if $a$ is a qua | ||||
| it is not. | ||||
| 
 | ||||
| \subsubsection{mp\_exptmod(mp\_int *a, mp\_int *b, mp\_int *c, mp\_int *d)} | ||||
| Computes $d = a^b \mbox{ (mod }c\mbox{)}$ using a sliding window $k$-ary exponentiation algorithm.  For an $\alpha$-bit | ||||
| Computes $d \equiv a^b \mbox{ (mod }c\mbox{)}$ using a sliding window $k$-ary exponentiation algorithm.  For an $\alpha$-bit | ||||
| exponent it performs $\alpha$ squarings and at most $\lfloor \alpha/k \rfloor + 2^{k-1}$ multiplications.  The value of $k$ is | ||||
| chosen to minimize the number of multiplications required for a given value of $\alpha$.  Barrett or Montgomery  | ||||
| reductions are used to reduce the squared or multiplied temporary results modulo $c$. | ||||
| chosen to minimize the number of multiplications required for a given value of $\alpha$.  Barrett, Montgomery or | ||||
| Dimminished-Radix reductions are used to reduce the squared or multiplied temporary results modulo $c$. | ||||
| 
 | ||||
| \subsection{Fast Modular Reductions} | ||||
| 
 | ||||
| A modular reduction of $a \mbox{ (mod }b\mbox{)}$ means to divide $a$ by $b$ and obtain the remainder.   | ||||
| Typically modular reductions are popular in public key cryptography algorithms such as RSA,  | ||||
| Diffie-Hellman and Elliptic Curve.  Modular reductions are also a large portion of modular exponentiation  | ||||
| (e.g. $a^b \mbox{ (mod }c\mbox{)}$).   | ||||
| 
 | ||||
| In a simplistic sense a normal integer division could be used to compute reduction.  Division is by far | ||||
| the most complicated of routines in terms of the work required.  As a result it is desirable to avoid | ||||
| division as much as possible.  This is evident in quite a few fields in computing.  For example, often in | ||||
| signal analysis uses multiplication by the reciprocal to approximate divisions.  Number theory is no | ||||
| different. | ||||
| 
 | ||||
| In most cases for the reduction of $a$ modulo $b$ the integer $a$ will be limited to the range  | ||||
| $0 \le a \le b^2$ which led to the invention of specialized algorithms to do the work. | ||||
| 
 | ||||
| The first algorithm is the most generic and is called the Barrett reduction.  When the input is of the  | ||||
| limited form (e.g. $0 \le a \le b^2$) Barrett reduction is numerically equivalent to a full integer | ||||
| division with remainder.  For a $n$-digit value $b$ the Barrett reduction requires approximately $2n^2$ | ||||
| multiplications. | ||||
| 
 | ||||
| The second algorithm is the Montgomery reduction.  It is slightly different since the result is not | ||||
| numerically equivalent to a standard integer division with remainder.  Also this algorithm only works for | ||||
| odd moduli.  The final result can be converted easily back to the desired for which makes the reduction  | ||||
| technique useful for algorithms where only the final output is desired.  For a $n$-digit value $b$ the  | ||||
| Montgomery reduction requires approximately $n^2 + n$ multiplications, about half as many as the  | ||||
| Barrett algorithm.   | ||||
| 
 | ||||
| The third algorithm is the Diminished Radix ``DR'' reduction.  It is a highly optimized reduction algorithm | ||||
| suitable only for a limited set of moduli.  For the specific moduli it is numerically equivalent to | ||||
| integer division with remainder.  For a $n$-digit value $b$ the DR reduction rquires exactly $n$ | ||||
| multiplications which is considerably faster than either of the two previous algorithms. | ||||
| 
 | ||||
| All three algorithms are automatically used in the modular exponentiation function mp\_exptmod() when  | ||||
| appropriate moduli are detected. | ||||
| 
 | ||||
| \begin{figure}[here] | ||||
| \begin{small} | ||||
| \begin{center} | ||||
| \begin{tabular}{|c|c|l|} | ||||
| \hline \textbf{Algorithm} & \textbf{Multiplications} & \textbf{Limitations} \\ | ||||
|  Barrett Reduction  & $2n^2$ & Any modulus. \\ | ||||
|  Montgomery Reduction & $n^2 + n$ & Any odd modulus. \\ | ||||
|  DR Reduction & $n$ & Moduli of the form  $p = \beta^k - p'$.\\ | ||||
| \hline | ||||
| \end{tabular} | ||||
| \caption{Summary of reduction techniques.} | ||||
| \end{center} | ||||
| \end{small} | ||||
| \end{figure} | ||||
| 
 | ||||
| \subsubsection{mp\_reduce(mp\_int *a, mp\_int *b, mp\_int *c)} | ||||
| Computes a Barrett reduction in-place of $a$ modulo $b$ with respect to $c$.  In essence it computes  | ||||
| $a \equiv a \mbox{ (mod }b\mbox{)}$ provided $0 \le a \le b^2$.  The value of $c$ is precomputed with the  | ||||
| $a \mbox{ (mod }b\mbox{)}$ provided $0 \le a \le b^2$.  The value of $c$ is precomputed with the  | ||||
| function mp\_reduce\_setup().  The modulus $b$ must be larger than zero. | ||||
| 
 | ||||
| This reduction function is much faster than simply calling mp\_mod() (\textit{Which simply uses mp\_div() anyways}) and is | ||||
| desirable where ever an appropriate reduction is desired.   | ||||
| 
 | ||||
| The Barrett reduction function has been optimized to use partial multipliers which means compared to MPI it performs | ||||
| have the number of single precision multipliers (\textit{provided they have the same size digits}).  The partial | ||||
| multipliers (\textit{one of which is shared with mp\_mul}) both have baseline and comba variants.  Barrett reduction  | ||||
| can reduce a number modulo a $n-$digit modulus with approximately $2n^2$ single precision multiplications.   | ||||
| 
 | ||||
| Consider the following snippet (from a BBS generator) using the more traditional approach: | ||||
| 
 | ||||
| \begin{small} | ||||
| \begin{verbatim} | ||||
|    mp_int modulus, n; | ||||
|    unsigned char buf[128]; | ||||
|    int ix, err; | ||||
|     | ||||
|    /* ... init code ..., e.g. init modulus and n */ | ||||
|    /* now output 128 bytes */ | ||||
|    for (ix = 0; ix < 128; ix++) {  | ||||
|        if ((err = mp_sqrmod(&n, &modulus, &n)) != MP_OKAY) { | ||||
|           printf("Err: %d\n", err); | ||||
|           exit(EXIT_FAILURE); | ||||
|        } | ||||
|        buf[ix] = n->dp[0] & 255; | ||||
|    } | ||||
| \end{verbatim} | ||||
| \end{small} | ||||
| 
 | ||||
| And now consider the same function using Barrett reductions: | ||||
| 
 | ||||
| \begin{small} | ||||
| \begin{verbatim} | ||||
|    mp_int modulus, n, mp; | ||||
|    unsigned char buf[128]; | ||||
|    int ix, err; | ||||
|     | ||||
|    /* ... init code ... e.g. modulus and n */ | ||||
|     | ||||
|    /* now setup mp which is the Barrett param */ | ||||
|    if ((err = mp_reduce_setup(&mp, &modulus)) != MP_OKAY) { | ||||
|       printf("Err: %d\n", err); | ||||
|       exit(EXIT_FAILURE); | ||||
|    } | ||||
|    /* now output 128 bytes */ | ||||
|    for (ix = 0; ix < 128; ix++) { | ||||
|       /* square n */ | ||||
|       if ((err = mp_sqr(&n, &n)) != MP_OKAY) { | ||||
|          printf("Err: %d\n", err); | ||||
|          exit(EXIT_FAILURE); | ||||
|       } | ||||
|       /* now reduce the square modulo modulus */ | ||||
|       if ((err = mp_reduce(&n, &modulus, &mp)) != MP_OKAY) { | ||||
|          printf("Err: %d\n", err); | ||||
|          exit(EXIT_FAILURE); | ||||
|       } | ||||
|       buf[ix] = n->dp[0] & 255; | ||||
|    } | ||||
| \end{verbatim}	 | ||||
| \end{small} | ||||
| 
 | ||||
| Both routines will produce the same output provided the same initial values of $modulus$ and $n$.  The Barrett | ||||
| method seems like more work but the optimization stems from the use of the Barrett reduction instead of the normal | ||||
| integer division. | ||||
| 
 | ||||
| \subsubsection{mp\_montgomery\_reduce(mp\_int *a, mp\_int *m, mp\_digit mp)} | ||||
| Computes a Montgomery reduction in-place of $a$ modulo $b$ with respect to $mp$.  If $b$ is some $n-$digit modulus then | ||||
| $R = \beta^{n+1}$.  The result of this function is $aR^{-1} \mbox{ (mod }b\mbox{)}$ provided that $0 \le a \le b^2$. | ||||
| @ -578,6 +745,94 @@ two long divisions would be required to setup $\hat x$ and a multiplication foll | ||||
| A very useful observation is that multiplying by $R = \beta^n$ amounts to performing a left shift by $n$ positions which | ||||
| requires no single precision multiplications. | ||||
| 
 | ||||
| \subsubsection{mp\_dr\_reduce(mp\_int *a, mp\_int *b, mp\_digit mp)} | ||||
| Computes the Diminished-Radix reduction of $a$ in place modulo $b$ with respect to $mp$.  $a$ must be in the range  | ||||
| $0 \le a \le b^2$ and $mp$ must be precomputed with the function mp\_dr\_setup(). | ||||
| 
 | ||||
| This reduction technique performs the reduction with $n$ multiplications and is much faster than either of the previous | ||||
| reduction methods.  Essentially it is very much like the Montgomery reduction except it is particularly optimized for | ||||
| specific types of moduli.  The moduli must be of the form $p = \beta^k - p'$ where $0 \le p' < \beta$ for $k \ge 2$.   | ||||
| This algorithm is suitable for several applications such as Diffie-Hellman public key cryptsystems where the prime $p$ is  | ||||
| of this form. | ||||
| 
 | ||||
| In appendix A several ``safe'' primes of various sizes are provided.  These primes are DR moduli and of the form  | ||||
| $p = 2q + 1$ where both $p$ and $q$ are prime.  A trivial observation is that $g = 4$ will be a generator for all of them | ||||
| since the order of the multiplicative sub-group is at most $2q$.  Since $2^2 \ne 1$ that means $4^q \equiv 2^{2q} \equiv 1$  | ||||
| and that $g = 4$ is a generator of order $q$. | ||||
| 
 | ||||
| These moduli can be used to construct a Diffie-Hellman public key cryptosystem.  Since the moduli are of the | ||||
| DR form the modular exponentiation steps will be efficient. | ||||
| 
 | ||||
| \subsection{Primality Testing and Generation} | ||||
| 
 | ||||
| \subsubsection{mp\_prime\_is\_divisible(mp\_int *a, int *result)} | ||||
| Determines if $a$ is divisible by any of the first 256 primes.  Sets $result$ to $1$ if true or $0$  | ||||
| otherwise.  Also will set $result$ to $1$ if $a$ is equal to one of the first 256 primes.   | ||||
| 
 | ||||
| \subsubsection{mp\_prime\_fermat(mp\_int *a, mp\_int *b, int *result)} | ||||
| Determines if $b$ is a witness to the compositeness of $a$ using the Fermat test.  Essentially this | ||||
| computes $b^a \mbox{ (mod }a\mbox{)}$ and compares it to $b$.  If they match $result$ is set | ||||
| to $1$ otherwise it is set to $0$.  If $a$ is prime and $1 < b < a$ then this function will set  | ||||
| $result$ to $1$ with a probability of one.  If $a$ is composite then this function will set  | ||||
| $result$ to $1$ with a probability of no more than $1 \over 2$.   | ||||
| 
 | ||||
| If this function is repeated $t$ times with different bases $b$ then the probability of a false positive | ||||
| is no more than $2^{-t}$. | ||||
| 
 | ||||
| \subsubsection{mp\_prime\_miller\_rabin(mp\_int *a, mp\_int *b, int *result)} | ||||
| Determines if $b$ is a witness to the compositeness of $a$ using the Miller-Rabin test.  This test | ||||
| works much (\textit{on an abstract level}) the same as the Fermat test except is more robust.  The | ||||
| set of pseudo-primes to any given base for the Miller-Rabin test is a proper subset of the pseudo-primes | ||||
| for the Fermat test.   | ||||
| 
 | ||||
| If $a$ is prime and $1 < b < a$ then this function will always set $result$ to $1$.  If $a$ is composite | ||||
| the trivial bound of error is $1 \over 4$.  However, according to HAC\footnote{Handbook of Applied | ||||
| Cryptography, Chapter 4, Section 4, pp. 147, Fact 4.48.} the following bounds are  | ||||
| known.  For a test of $t$ trials on a $k$-bit number the probability $P_{k,t}$ of error is given as | ||||
| follows. | ||||
| 
 | ||||
| \begin{enumerate} | ||||
| \item $P_{k,1} < k^24^{2 - \sqrt{k}}$ for $k \ge 2$ | ||||
| \item $P_{k,t} < k^{3/2}2^tt^{-1/2}4^{2-\sqrt{tk}}$ for $(t = 2, k \ge 88)$ or $(3 \le t \le k/9, k \ge 21)$. | ||||
| \item $P_{k,t} < {7 \over 20}k2^{-5t} + {1 \over 7}k^{15/4}2^{-k/2-2t} + 12k2^{-k/4-3t}$ for $k/9 \le t \le k/4, k \ge 21$. | ||||
| \item $P_{k,t} < {1 \over 7}k^{15/4}2^{-k/2 - 2t}$  for $t \ge k/4, k \ge 21$. | ||||
| \end{enumerate} | ||||
| 
 | ||||
| For instance, $P_{1024,1}$ which indicates the probability of failure of one test with a 1024-bit candidate  | ||||
| is no more than $2^{-40}$.  However, ideally at least a couple of trials should be used.  In LibTomCrypt | ||||
| for instance eight tests are used.  In this case $P_{1024,8}$ falls under the second rule which leads | ||||
| to a probability of failure of no more than $2^{-155.52}$. | ||||
| 
 | ||||
| \begin{figure}[here] | ||||
| \begin{small} | ||||
| \begin{center} | ||||
| \begin{tabular}{|c|c|c|c|c|c|c|} | ||||
| \hline \textbf{Size (k)} & \textbf{$t = 3$} & \textbf{$t = 4$} & \textbf{$t = 5$} & \textbf{$t = 6$} & \textbf{$t = 7$} & \textbf{$t = 8$}\\ | ||||
| \hline 512  & -58 & -70 & -79 & -88 & -96 & -104 \\ | ||||
| \hline 768  & -75 & -89 & -101 & -112 & -122 & -131\\ | ||||
| \hline 1024 & -89 & -106 & -120 & -133 & -144 & -155 \\ | ||||
| \hline 1280 & -102 & -120 & -136 & -151 & -164 & -176 \\ | ||||
| \hline 1536 & -113 & -133 & -151 & -167 & -181 & -195 \\ | ||||
| \hline 1792 & -124 & -146 & -165 & -182 & -198 & -212 \\ | ||||
| \hline 2048 & -134 & -157 & -178 & -196 & -213 & -228\\ | ||||
| \hline | ||||
| \end{tabular} | ||||
| \end{center} | ||||
| \end{small} | ||||
| \caption{Probability of error for a given random candidate of $k$ bits with $t$ trials.  Denoted as  | ||||
| log$_2(P_{k,t})$. } | ||||
| \end{figure} | ||||
| 
 | ||||
| \subsubsection{mp\_prime\_is\_prime(mp\_int *a, int t, int *result)} | ||||
| This function determines if $a$ is probably prime by first performing trial division by the first 256  | ||||
| primes and then $t$ rounds of Miller-Rabin using the first $t$ primes as bases.  If $a$ is prime this | ||||
| function will always set $result$ to $1$.  If $a$ is composite then it will almost always set $result$ | ||||
| to $0$.  The probability of error is given in figure two. | ||||
| 
 | ||||
| \subsubsection{mp\_prime\_next\_prime(mp\_int *a, int t)} | ||||
| This function will find the next prime \textbf{after} $a$ by using trial division and $t$ trials of  | ||||
| Miller-Rabin.   | ||||
| 
 | ||||
| \section{Timing Analysis} | ||||
| 
 | ||||
| \subsection{Digit Size} | ||||
| @ -662,8 +917,12 @@ MPI uses a binary square-multiply method for exponentiation.  For the same expon | ||||
| perform 8 squarings and 5 multiplications.  There is a precomputation phase for the method LibTomMath uses but it  | ||||
| generally cuts down considerably on the number of multiplications.  Consider a 512-bit exponent.  The worst case for the  | ||||
| LibTomMath method results in 512 squarings and 124 multiplications.  The MPI method would have 512 squarings  | ||||
| and 512 multiplications.  Randomly every $2k$ bits another multiplication is saved via the sliding-window  | ||||
| technique on top of the savings the $k$-ary method provides. | ||||
| and 512 multiplications.   | ||||
| 
 | ||||
| Randomly the most probable event is that every $2k^2$ bits another multiplication is saved via the  | ||||
| sliding-window technique on top of the savings the $k$-ary method provides.  This stems from the fact that each window | ||||
| has a probability of $2^{-1}$ of being delayed by one bit.  In reality the savings can be much more when the exponent | ||||
| has an abundance of zero bits.   | ||||
| 
 | ||||
| Both LibTomMath and MPI use Barrett reduction instead of division to reduce the numbers modulo the modulus given. | ||||
| However, LibTomMath can take advantage of the fact that the multiplications required within the Barrett reduction | ||||
| @ -671,12 +930,103 @@ do not have to give full precision.  As a result the reduction step is much fast | ||||
| code will automatically determine at run-time (e.g. when its called) whether the faster multiplier can be used.  The | ||||
| faster multipliers have also been optimized into the two variants (baseline and comba baseline). | ||||
| 
 | ||||
| LibTomMath also has a variant of the exptmod function that uses Montgomery reductions instead of Barrett reductions | ||||
| which is faster.  The code will automatically detect when the Montgomery version can be used (\textit{Requires the | ||||
| modulus to be odd and below the MONTGOMERY\_EXPT\_CUTOFF size}).  The Montgomery routine is essentially a copy of the  | ||||
| Barrett exponentiation routine except it uses Montgomery reduction. | ||||
| LibTomMath also has a variant of the exptmod function that uses Montgomery or Diminished-Radix reductions instead of  | ||||
| Barrett reductions which are faster.  The code will automatically detect when the Montgomery version can be used  | ||||
| (\textit{Requires the modulus to be odd and below the MONTGOMERY\_EXPT\_CUTOFF size}).  The Montgomery routine is  | ||||
| essentially a copy of the Barrett exponentiation routine except it uses Montgomery reduction. | ||||
| 
 | ||||
| As a result of all these changes exponentiation in LibTomMath is much faster than compared to MPI.  On most ALU-strong | ||||
| processors (AMD Athlon for instance) exponentiation in LibTomMath is often more then ten times faster than MPI. | ||||
| 
 | ||||
| \newpage | ||||
| \section*{Appendix A -- DR Safe Prime Moduli} | ||||
| These are safe primes suitable for the DR reduction techniques. | ||||
| 
 | ||||
| \begin{small} | ||||
| \begin{verbatim} | ||||
| 224-bit prime: | ||||
| p == 26959946667150639794667015087019630673637144422540572481103341844143 | ||||
| 
 | ||||
| 532-bit prime: | ||||
| p == 14059105607947488696282932836518693308967803494693489478439861164411 | ||||
|      99243959839959474700214407465892859350284572975279726002583142341968 | ||||
|      6528151609940203368691747 | ||||
| 
 | ||||
| 784-bit prime: | ||||
| p == 10174582569701926077392351975587856746131528201775982910760891436407 | ||||
|      52752352543956225804474009941755789631639189671820136396606697711084 | ||||
|      75957692810857098847138903161308502419410142185759152435680068435915 | ||||
|      159402496058513611411688900243039 | ||||
|       | ||||
| 1036-bit prime: | ||||
| p == 73633510803960459580592340614718453088992337057476877219196961242207 | ||||
|      30400993319449915739231125812675425079864519532271929704028930638504 | ||||
|      85730703075899286013451337291468249027691733891486704001513279827771 | ||||
|      74018362916106519487472796251714810077522836342108369176406547759082 | ||||
|      3919364012917984605619526140821798437127 | ||||
| 
 | ||||
| 1540-bit prime: | ||||
| p == 38564998830736521417281865696453025806593491967131023221754800625044 | ||||
|      11826546885121070536038571753679461518026049420807660579867166071933 | ||||
|      31995138078062523944232834134301060035963325132466829039948295286901 | ||||
|      98205120921557533726473585751382193953592127439965050261476810842071 | ||||
|      57368450587885458870662348457392592590350574754547108886771218500413 | ||||
|      52012892734056144158994382765356263460989042410208779740029161680999 | ||||
|      51885406379295536200413493190419727789712076165162175783 | ||||
|       | ||||
| 2072-bit prime: | ||||
| p == 54218939133169617266167044061918053674999416641599333415160174539219 | ||||
|      34845902966009796023786766248081296137779934662422030250545736925626 | ||||
|      89251250471628358318743978285860720148446448885701001277560572526947 | ||||
|      61939255157449083928645845499448866574499182283776991809511712954641 | ||||
|      41244487770339412235658314203908468644295047744779491537946899487476 | ||||
|      80362212954278693335653935890352619041936727463717926744868338358149 | ||||
|      56836864340303776864961677852601361049369618605589931826833943267154 | ||||
|      13281957242613296066998310166663594408748431030206661065682224010477 | ||||
|      20269951530296879490444224546654729111504346660859907296364097126834 | ||||
|      834235287147 | ||||
| \end{verbatim} | ||||
| \newpage | ||||
| \begin{verbatim} | ||||
| 3080-bit prime: | ||||
| p == 14872591348147092640920326485259710388958656451489011805853404549855 | ||||
|      24155135260217788758027400478312256339496385275012465661575576202252 | ||||
|      06314569873207988029466422057976484876770407676185319721656326266004 | ||||
|      66027039730507982182461708359620055985616697068444694474354610925422 | ||||
|      65792444947706769615695252256130901271870341005768912974433684521436 | ||||
|      21126335809752272646208391793909176002665892575707673348417320292714 | ||||
|      14414925737999142402226287954056239531091315945236233530448983394814 | ||||
|      94120112723445689647986475279242446083151413667587008191682564376412 | ||||
|      34796414611389856588668313940700594138366932599747507691048808666325 | ||||
|      63356891811579575714450674901879395531659037735542902605310091218790 | ||||
|      44170766615232300936675369451260747671432073394867530820527479172464 | ||||
|      10644245072764022650374658634027981631882139521072626829153564850619 | ||||
|      07146160831634031899433344310568760382865303657571873671474460048559 | ||||
|      12033137386225053275419626102417236133948503 | ||||
| 
 | ||||
| 4116-bit prime: | ||||
| p == 10951211157166778028568112903923951285881685924091094949001780089679 | ||||
|      55253005183831872715423151551999734857184538199864469605657805519106 | ||||
|      71752965504405483319768745978263629725521974299473675154181526972794 | ||||
|      07518606702687749033402960400061140139713092570283328496790968248002 | ||||
|      50742691718610670812374272414086863715763724622797509437062518082383 | ||||
|      05605014462496277630214789052124947706021514827516368830127584715531 | ||||
|      60422794055576326393660668474428614221648326558746558242215778499288 | ||||
|      63023018366835675399949740429332468186340518172487073360822220449055 | ||||
|      34058256846156864525995487330361695377639385317484513208112197632746 | ||||
|      27403549307444874296172025850155107442985301015477068215901887335158 | ||||
|      80733527449780963163909830077616357506845523215289297624086914545378 | ||||
|      51108253422962011656326016849452390656670941816601111275452976618355 | ||||
|      45793212249409511773940884655967126200762400673705890369240247283750 | ||||
|      76210477267488679008016579588696191194060127319035195370137160936882 | ||||
|      40224439969917201783514453748848639690614421772002899286394128821718 | ||||
|      53539149915834004216827510006035966557909908155251261543943446413363 | ||||
|      97793791497068253936771017031980867706707490224041075826337383538651 | ||||
|      82549367950377193483609465580277633166426163174014828176348776585274 | ||||
|      6577808019633679 | ||||
| \end{verbatim} | ||||
| \end{small} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| \end{document} | ||||
|  | ||||
| @ -80,7 +80,6 @@ fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c) | ||||
|   } | ||||
|   mp_set (&D, 1); | ||||
| 
 | ||||
| 
 | ||||
| top: | ||||
|   /* 4.  while u is even do */ | ||||
|   while (mp_iseven (&u) == 1) { | ||||
|  | ||||
| @ -106,7 +106,7 @@ mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d) | ||||
| 
 | ||||
|   /* step 3. for i from n down to (t + 1) */ | ||||
|   for (i = n; i >= (t + 1); i--) { | ||||
|     if (i > x.alloc) | ||||
|     if (i > x.used) | ||||
|       continue; | ||||
| 
 | ||||
|     /* step 3.1 if xi == yt then set q{i-t-1} to b-1, otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ | ||||
| @ -175,6 +175,7 @@ mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d) | ||||
|   /* now q is the quotient and x is the remainder [which we have to normalize] */ | ||||
|   /* get sign before writing to c */ | ||||
|   x.sign = a->sign; | ||||
| 
 | ||||
|   if (c != NULL) { | ||||
|     mp_clamp (&q); | ||||
|     mp_exch (&q, c); | ||||
| @ -183,7 +184,6 @@ mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d) | ||||
| 
 | ||||
|   if (d != NULL) { | ||||
|     mp_div_2d (&x, norm, &x, NULL); | ||||
|     mp_clamp (&x); | ||||
|     mp_exch (&x, d); | ||||
|   } | ||||
| 
 | ||||
|  | ||||
| @ -52,7 +52,7 @@ mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) | ||||
| 
 | ||||
|   /* shift by as many digits in the bit count */ | ||||
|   if (b >= DIGIT_BIT) { | ||||
|      mp_rshd (c, b / DIGIT_BIT); | ||||
|     mp_rshd (c, b / DIGIT_BIT); | ||||
|   } | ||||
| 
 | ||||
|   /* shift any bit count < DIGIT_BIT */ | ||||
|  | ||||
| @ -21,7 +21,6 @@ mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d) | ||||
|   mp_int  t, t2; | ||||
|   int     res; | ||||
| 
 | ||||
| 
 | ||||
|   if ((res = mp_init (&t)) != MP_OKAY) { | ||||
|     return res; | ||||
|   } | ||||
|  | ||||
							
								
								
									
										150
									
								
								bn_mp_dr_reduce.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								bn_mp_dr_reduce.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,150 @@ | ||||
| /* LibTomMath, multiple-precision integer library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomMath is library that provides for multiple-precision | ||||
|  * integer arithmetic as well as number theoretic functionality. | ||||
|  * | ||||
|  * The library is designed directly after the MPI library by | ||||
|  * Michael Fromberger but has been written from scratch with | ||||
|  * additional optimizations in place. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
 | ||||
|  */ | ||||
| #include <tommath.h> | ||||
| 
 | ||||
| /* reduce "a" in place modulo "b" using the Diminished Radix algorithm.
 | ||||
|  * | ||||
|  * Based on algorithm from the paper  | ||||
|  * | ||||
|  * "Generating Efficient Primes for Discrete Log Cryptosystems" | ||||
|  *                 Chae Hoon Lim, Pil Loong Lee, | ||||
|  *          POSTECH Information Research Laboratories | ||||
|  * | ||||
|  * The modulus must be of a special format [see manual] | ||||
|  */ | ||||
| int | ||||
| mp_dr_reduce (mp_int * a, mp_int * b, mp_digit mp) | ||||
| { | ||||
|   int     err, i, j, k; | ||||
|   mp_word r; | ||||
|   mp_digit mu, *tmpj, *tmpi; | ||||
| 
 | ||||
|   /* k = digits in modulus */ | ||||
|   k = b->used; | ||||
| 
 | ||||
|   /* ensure that "a" has at least 2k digits */ | ||||
|   if (a->alloc < k + k) { | ||||
|     if ((err = mp_grow (a, k + k)) != MP_OKAY) { | ||||
|       return err; | ||||
|     } | ||||
|   } | ||||
|   | ||||
|   /* alias for a->dp[i] */ | ||||
|   tmpi = a->dp + k + k - 1; | ||||
| 
 | ||||
|   /* for (i = 2k - 1; i >= k; i = i - 1) 
 | ||||
|    * | ||||
|    * This is the main loop of the reduction.  Note that at the end | ||||
|    * the words above position k are not zeroed as expected.  The end | ||||
|    * result is that the digits from 0 to k-1 are the residue.  So  | ||||
|    * we have to clear those afterwards. | ||||
|    */ | ||||
|   for (i = k + k - 1; i >= k; i = i - 1) { | ||||
|     /* x[i - 1 : i - k] += x[i]*mp */ | ||||
| 
 | ||||
|     /* x[i] * mp */ | ||||
|     r = ((mp_word) *tmpi--) * ((mp_word) mp); | ||||
| 
 | ||||
|     /* now add r to x[i-1:i-k] 
 | ||||
|      * | ||||
|      * First add it to the first digit x[i-k] then form the carry | ||||
|      * then enter the main loop  | ||||
|      */ | ||||
|     j = i - k; | ||||
| 
 | ||||
|     /* alias for a->dp[j] */ | ||||
|     tmpj = a->dp + j; | ||||
| 
 | ||||
|     /* add digit */ | ||||
|     *tmpj += (mp_digit)(r & MP_MASK); | ||||
| 
 | ||||
|     /* this is the carry */ | ||||
|     mu = (r >> ((mp_word) DIGIT_BIT)) + (*tmpj >> DIGIT_BIT); | ||||
| 
 | ||||
|     /* clear carry from a->dp[j]  */ | ||||
|     *tmpj++ &= MP_MASK;  | ||||
| 
 | ||||
|     /* now add rest of the digits 
 | ||||
|      *  | ||||
|      * Note this is basically a simple single digit addition to | ||||
|      * a larger multiple digit number.  This is optimized somewhat | ||||
|      * because the propagation of carries is not likely to move | ||||
|      * more than a few digits.  | ||||
|      * | ||||
|      */ | ||||
|     for (++j; mu != 0 && j <= (i - 1); ++j) { | ||||
|       *tmpj   += mu; | ||||
|       mu       = *tmpj >> DIGIT_BIT; | ||||
|       *tmpj++ &= MP_MASK; | ||||
|     } | ||||
| 
 | ||||
|     /* if final carry */ | ||||
|     if (mu != 0) { | ||||
|       /* add mp to this to correct */ | ||||
|       j = i - k; | ||||
|       tmpj = a->dp + j; | ||||
| 
 | ||||
|       *tmpj += mp; | ||||
|       mu = *tmpj >> DIGIT_BIT; | ||||
|       *tmpj++ &= MP_MASK; | ||||
|        | ||||
|       /* now handle carries */ | ||||
|       for (++j; mu != 0 && j <= (i - 1); j++) { | ||||
| 	*tmpj   += mu; | ||||
| 	mu       = *tmpj >> DIGIT_BIT; | ||||
| 	*tmpj++ &= MP_MASK; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   /* zero words above k */ | ||||
|   tmpi = a->dp + k; | ||||
|   for (i = k; i < a->used; i++) { | ||||
|       *tmpi++ = 0; | ||||
|   } | ||||
| 
 | ||||
|   /* clamp, sub and return */ | ||||
|   mp_clamp (a); | ||||
|    | ||||
|   if (mp_cmp_mag (a, b) != MP_LT) { | ||||
|     return s_mp_sub (a, b, a); | ||||
|   } | ||||
|   return MP_OKAY; | ||||
| } | ||||
| 
 | ||||
| /* determines if a number is a valid DR modulus */ | ||||
| int mp_dr_is_modulus(mp_int *a) | ||||
| { | ||||
|    int ix; | ||||
|     | ||||
|    /* must be at least two digits */ | ||||
|    if (a->used < 2) { | ||||
|       return 0; | ||||
|    }       | ||||
|     | ||||
|    for (ix = 1; ix < a->used; ix++) { | ||||
|        if (a->dp[ix] != MP_MASK) { | ||||
|           return 0; | ||||
|        } | ||||
|    } | ||||
|    return 1; | ||||
| } | ||||
| 
 | ||||
| /* determines the setup value */ | ||||
| void mp_dr_setup(mp_int *a, mp_digit *d) | ||||
| { | ||||
|    *d = (1 << DIGIT_BIT) - a->dp[0]; | ||||
| } | ||||
| 
 | ||||
| @ -24,9 +24,12 @@ static int f_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y); | ||||
| int | ||||
| mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) | ||||
| { | ||||
|   int dr; | ||||
|    | ||||
|   dr = mp_dr_is_modulus(P); | ||||
|   /* if the modulus is odd use the fast method */ | ||||
|   if (mp_isodd (P) == 1 && P->used > 4 && P->used < MONTGOMERY_EXPT_CUTOFF) { | ||||
|     return mp_exptmod_fast (G, X, P, Y); | ||||
|   if (((mp_isodd (P) == 1 && P->used < MONTGOMERY_EXPT_CUTOFF) || dr == 1) && P->used > 4) { | ||||
|     return mp_exptmod_fast (G, X, P, Y, dr); | ||||
|   } else { | ||||
|     return f_mp_exptmod (G, X, P, Y); | ||||
|   } | ||||
|  | ||||
| @ -22,11 +22,13 @@ | ||||
|  * Uses Montgomery reduction  | ||||
|  */ | ||||
| int | ||||
| mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) | ||||
| mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) | ||||
| { | ||||
|   mp_int  M[256], res; | ||||
|   mp_digit buf, mp; | ||||
|   int     err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; | ||||
|   int     (*redux)(mp_int*,mp_int*,mp_digit); | ||||
|    | ||||
| 
 | ||||
|   /* find window size */ | ||||
|   x = mp_count_bits (X); | ||||
| @ -56,9 +58,16 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   /* now setup montgomery  */ | ||||
|   if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) { | ||||
|     goto __M; | ||||
|   if (redmode == 0) { | ||||
|      /* now setup montgomery  */ | ||||
|      if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) { | ||||
|         goto __M; | ||||
|      } | ||||
|      redux = mp_montgomery_reduce; | ||||
|   } else { | ||||
|      /* setup DR reduction */ | ||||
|      mp_dr_setup(P, &mp); | ||||
|      redux = mp_dr_reduce; | ||||
|   } | ||||
| 
 | ||||
|   /* setup result */ | ||||
| @ -73,15 +82,23 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) | ||||
|    * The first half of the table is not computed though accept for M[0] and M[1] | ||||
|    */ | ||||
| 
 | ||||
|   /* now we need R mod m */ | ||||
|   if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) { | ||||
|     goto __RES; | ||||
|   if (redmode == 0) { | ||||
|      /* now we need R mod m */ | ||||
|      if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) { | ||||
|        goto __RES; | ||||
|      } | ||||
| 
 | ||||
|      /* now set M[1] to G * R mod m */ | ||||
|      if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) { | ||||
|        goto __RES; | ||||
|      } | ||||
|   } else { | ||||
|      mp_set(&res, 1); | ||||
|      if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) { | ||||
|         goto __RES; | ||||
|      } | ||||
|   } | ||||
|    | ||||
|   /* now set M[1] to G * R mod m */ | ||||
|   if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) { | ||||
|     goto __RES; | ||||
|   } | ||||
|   /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */ | ||||
|   if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { | ||||
|     goto __RES; | ||||
| @ -91,7 +108,7 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) | ||||
|     if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) { | ||||
|       goto __RES; | ||||
|     } | ||||
|     if ((err = mp_montgomery_reduce (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) { | ||||
|     if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) { | ||||
|       goto __RES; | ||||
|     } | ||||
|   } | ||||
| @ -101,7 +118,7 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) | ||||
|     if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { | ||||
|       goto __RES; | ||||
|     } | ||||
|     if ((err = mp_montgomery_reduce (&M[x], P, mp)) != MP_OKAY) { | ||||
|     if ((err = redux (&M[x], P, mp)) != MP_OKAY) { | ||||
|       goto __RES; | ||||
|     } | ||||
|   } | ||||
| @ -141,7 +158,7 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) | ||||
|       if ((err = mp_sqr (&res, &res)) != MP_OKAY) { | ||||
| 	goto __RES; | ||||
|       } | ||||
|       if ((err = mp_montgomery_reduce (&res, P, mp)) != MP_OKAY) { | ||||
|       if ((err = redux (&res, P, mp)) != MP_OKAY) { | ||||
| 	goto __RES; | ||||
|       } | ||||
|       continue; | ||||
| @ -158,7 +175,7 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) | ||||
| 	if ((err = mp_sqr (&res, &res)) != MP_OKAY) { | ||||
| 	  goto __RES; | ||||
| 	} | ||||
| 	if ((err = mp_montgomery_reduce (&res, P, mp)) != MP_OKAY) { | ||||
| 	if ((err = redux (&res, P, mp)) != MP_OKAY) { | ||||
| 	  goto __RES; | ||||
| 	} | ||||
|       } | ||||
| @ -167,7 +184,7 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) | ||||
|       if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { | ||||
| 	goto __RES; | ||||
|       } | ||||
|       if ((err = mp_montgomery_reduce (&res, P, mp)) != MP_OKAY) { | ||||
|       if ((err = redux (&res, P, mp)) != MP_OKAY) { | ||||
| 	goto __RES; | ||||
|       } | ||||
| 
 | ||||
| @ -184,7 +201,7 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) | ||||
|       if ((err = mp_sqr (&res, &res)) != MP_OKAY) { | ||||
| 	goto __RES; | ||||
|       } | ||||
|       if ((err = mp_montgomery_reduce (&res, P, mp)) != MP_OKAY) { | ||||
|       if ((err = redux (&res, P, mp)) != MP_OKAY) { | ||||
| 	goto __RES; | ||||
|       } | ||||
| 
 | ||||
| @ -194,16 +211,18 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) | ||||
| 	if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { | ||||
| 	  goto __RES; | ||||
| 	} | ||||
| 	if ((err = mp_montgomery_reduce (&res, P, mp)) != MP_OKAY) { | ||||
| 	if ((err = redux (&res, P, mp)) != MP_OKAY) { | ||||
| 	  goto __RES; | ||||
| 	} | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /* fixup result */ | ||||
|   if ((err = mp_montgomery_reduce (&res, P, mp)) != MP_OKAY) { | ||||
|     goto __RES; | ||||
|   if (redmode == 0) { | ||||
|      /* fixup result */ | ||||
|      if ((err = mp_montgomery_reduce (&res, P, mp)) != MP_OKAY) { | ||||
|        goto __RES; | ||||
|      } | ||||
|   }      | ||||
| 
 | ||||
|   mp_exch (&res, Y); | ||||
|  | ||||
| @ -24,7 +24,7 @@ mp_grow (mp_int * a, int size) | ||||
|   if (a->alloc < size) { | ||||
|     size += (MP_PREC * 2) - (size & (MP_PREC - 1));	/* ensure there are always at least MP_PREC digits extra on top */ | ||||
| 
 | ||||
|     a->dp = realloc (a->dp, sizeof (mp_digit) * size); | ||||
|     a->dp = OPT_CAST realloc (a->dp, sizeof (mp_digit) * size); | ||||
|     if (a->dp == NULL) { | ||||
|       return MP_MEM; | ||||
|     } | ||||
|  | ||||
| @ -20,7 +20,7 @@ mp_init (mp_int * a) | ||||
| { | ||||
| 
 | ||||
|   /* allocate ram required and clear it */ | ||||
|   a->dp = calloc (sizeof (mp_digit), MP_PREC); | ||||
|   a->dp = OPT_CAST calloc (sizeof (mp_digit), MP_PREC); | ||||
|   if (a->dp == NULL) { | ||||
|     return MP_MEM; | ||||
|   } | ||||
|  | ||||
| @ -21,7 +21,7 @@ mp_init_size (mp_int * a, int size) | ||||
| 
 | ||||
|   /* pad up so there are at least 16 zero digits */ | ||||
|   size += (MP_PREC * 2) - (size & (MP_PREC - 1));	/* ensure there are always at least 16 digits extra on top */ | ||||
|   a->dp = calloc (sizeof (mp_digit), size); | ||||
|   a->dp = OPT_CAST calloc (sizeof (mp_digit), size); | ||||
|   if (a->dp == NULL) { | ||||
|     return MP_MEM; | ||||
|   } | ||||
|  | ||||
| @ -33,9 +33,9 @@ mp_mul_2d (mp_int * a, int b, mp_int * c) | ||||
| 
 | ||||
|   /* shift by as many digits in the bit count */ | ||||
|   if (b >= DIGIT_BIT) { | ||||
|      if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) { | ||||
|        return res; | ||||
|      } | ||||
|     if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) { | ||||
|       return res; | ||||
|     } | ||||
|   } | ||||
|   c->used = c->alloc; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										52
									
								
								bn_mp_prime_fermat.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								bn_mp_prime_fermat.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | ||||
| /* LibTomMath, multiple-precision integer library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomMath is library that provides for multiple-precision | ||||
|  * integer arithmetic as well as number theoretic functionality. | ||||
|  * | ||||
|  * The library is designed directly after the MPI library by | ||||
|  * Michael Fromberger but has been written from scratch with | ||||
|  * additional optimizations in place. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
 | ||||
|  */ | ||||
| #include <tommath.h> | ||||
| 
 | ||||
| /* performs one Fermat test.
 | ||||
|  *  | ||||
|  * If "a" were prime then b^a == b (mod a) since the order of | ||||
|  * the multiplicative sub-group would be phi(a) = a-1.  That means | ||||
|  * it would be the same as b^(a mod (a-1)) == b^1 == b (mod a). | ||||
|  * | ||||
|  * Sets result to 1 if the congruence holds, or zero otherwise. | ||||
|  */ | ||||
| int | ||||
| mp_prime_fermat (mp_int * a, mp_int * b, int *result) | ||||
| { | ||||
|   mp_int  t; | ||||
|   int     err; | ||||
| 
 | ||||
|   /* default to fail */ | ||||
|   *result = 0; | ||||
| 
 | ||||
|   /* init t */ | ||||
|   if ((err = mp_init (&t)) != MP_OKAY) { | ||||
|     return err; | ||||
|   } | ||||
| 
 | ||||
|   /* compute t = b^a mod a */ | ||||
|   if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) { | ||||
|     goto __T; | ||||
|   } | ||||
| 
 | ||||
|   /* is it equal to b? */ | ||||
|   if (mp_cmp (&t, b) == MP_EQ) { | ||||
|     *result = 1; | ||||
|   } | ||||
| 
 | ||||
|   err = MP_OKAY; | ||||
| __T:mp_clear (&t); | ||||
|   return err; | ||||
| } | ||||
							
								
								
									
										50
									
								
								bn_mp_prime_is_divisible.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								bn_mp_prime_is_divisible.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,50 @@ | ||||
| /* LibTomMath, multiple-precision integer library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomMath is library that provides for multiple-precision | ||||
|  * integer arithmetic as well as number theoretic functionality. | ||||
|  * | ||||
|  * The library is designed directly after the MPI library by | ||||
|  * Michael Fromberger but has been written from scratch with | ||||
|  * additional optimizations in place. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
 | ||||
|  */ | ||||
| #include <tommath.h> | ||||
| 
 | ||||
| /* determines if an integers is divisible by one of the first 256 primes or not 
 | ||||
|  * | ||||
|  * sets result to 0 if not, 1 if yes | ||||
|  */ | ||||
| int | ||||
| mp_prime_is_divisible (mp_int * a, int *result) | ||||
| { | ||||
|   int     err, ix; | ||||
|   mp_digit res; | ||||
| 
 | ||||
|   /* default to not */ | ||||
|   *result = 0; | ||||
| 
 | ||||
|   for (ix = 0; ix < 256; ix++) { | ||||
|     /* is it equal to the prime? */ | ||||
|     if (mp_cmp_d (a, __prime_tab[ix]) == MP_EQ) { | ||||
|       *result = 1; | ||||
|       return MP_OKAY; | ||||
|     } | ||||
| 
 | ||||
|     /* what is a mod __prime_tab[ix] */ | ||||
|     if ((err = mp_mod_d (a, __prime_tab[ix], &res)) != MP_OKAY) { | ||||
|       return err; | ||||
|     } | ||||
| 
 | ||||
|     /* is the residue zero? */ | ||||
|     if (res == 0) { | ||||
|       *result = 1; | ||||
|       return MP_OKAY; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   return MP_OKAY; | ||||
| } | ||||
							
								
								
									
										68
									
								
								bn_mp_prime_is_prime.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								bn_mp_prime_is_prime.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,68 @@ | ||||
| /* LibTomMath, multiple-precision integer library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomMath is library that provides for multiple-precision | ||||
|  * integer arithmetic as well as number theoretic functionality. | ||||
|  * | ||||
|  * The library is designed directly after the MPI library by | ||||
|  * Michael Fromberger but has been written from scratch with | ||||
|  * additional optimizations in place. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
 | ||||
|  */ | ||||
| #include <tommath.h> | ||||
| 
 | ||||
| /* performs a variable number of rounds of Miller-Rabin
 | ||||
|  * | ||||
|  * Probability of error after t rounds is no more than | ||||
|  * (1/4)^t when 1 <= t <= 256 | ||||
|  * | ||||
|  * Sets result to 1 if probably prime, 0 otherwise | ||||
|  */ | ||||
| int | ||||
| mp_prime_is_prime (mp_int * a, int t, int *result) | ||||
| { | ||||
|   mp_int  b; | ||||
|   int     ix, err, res; | ||||
| 
 | ||||
|   /* default to no */ | ||||
|   *result = 0; | ||||
| 
 | ||||
|   /* valid value of t? */ | ||||
|   if (t < 1 || t > 256) { | ||||
|     return MP_VAL; | ||||
|   } | ||||
| 
 | ||||
|   /* first perform trial division */ | ||||
|   if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) { | ||||
|     return err; | ||||
|   } | ||||
|   if (res == 1) { | ||||
|     return MP_OKAY; | ||||
|   } | ||||
| 
 | ||||
|   /* now perform the miller-rabin rounds */ | ||||
|   if ((err = mp_init (&b)) != MP_OKAY) { | ||||
|     return err; | ||||
|   } | ||||
| 
 | ||||
|   for (ix = 0; ix < t; ix++) { | ||||
|     /* set the prime */ | ||||
|     mp_set (&b, __prime_tab[ix]); | ||||
| 
 | ||||
|     if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) { | ||||
|       goto __B; | ||||
|     } | ||||
| 
 | ||||
|     if (res == 0) { | ||||
|       goto __B; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /* passed the test */ | ||||
|   *result = 1; | ||||
| __B:mp_clear (&b); | ||||
|   return err; | ||||
| } | ||||
							
								
								
									
										90
									
								
								bn_mp_prime_miller_rabin.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								bn_mp_prime_miller_rabin.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,90 @@ | ||||
| /* LibTomMath, multiple-precision integer library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomMath is library that provides for multiple-precision | ||||
|  * integer arithmetic as well as number theoretic functionality. | ||||
|  * | ||||
|  * The library is designed directly after the MPI library by | ||||
|  * Michael Fromberger but has been written from scratch with | ||||
|  * additional optimizations in place. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
 | ||||
|  */ | ||||
| #include <tommath.h> | ||||
| 
 | ||||
| /* Miller-Rabin test of "a" to the base of "b" as described in 
 | ||||
|  * HAC pp. 139 Algorithm 4.24 | ||||
|  * | ||||
|  * Sets result to 0 if definitely composite or 1 if probably prime. | ||||
|  * Randomly the chance of error is no more than 1/4 and often  | ||||
|  * very much lower. | ||||
|  */ | ||||
| int | ||||
| mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result) | ||||
| { | ||||
|   mp_int  n1, y, r; | ||||
|   int     s, j, err; | ||||
| 
 | ||||
|   /* default */ | ||||
|   *result = 0; | ||||
| 
 | ||||
|   /* get n1 = a - 1 */ | ||||
|   if ((err = mp_init_copy (&n1, a)) != MP_OKAY) { | ||||
|     return err; | ||||
|   } | ||||
|   if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) { | ||||
|     goto __N1; | ||||
|   } | ||||
| 
 | ||||
|   /* set 2^s * r = n1 */ | ||||
|   if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) { | ||||
|     goto __N1; | ||||
|   } | ||||
|   s = 0; | ||||
|   while (mp_iseven (&r) == 1) { | ||||
|     ++s; | ||||
|     if ((err = mp_div_2 (&r, &r)) != MP_OKAY) { | ||||
|       goto __R; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /* compute y = b^r mod a */ | ||||
|   if ((err = mp_init (&y)) != MP_OKAY) { | ||||
|     goto __R; | ||||
|   } | ||||
|   if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) { | ||||
|     goto __Y; | ||||
|   } | ||||
| 
 | ||||
|   /* if y != 1 and y != n1 do */ | ||||
|   if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) { | ||||
|     j = 1; | ||||
|     /* while j <= s-1 and y != n1 */ | ||||
|     while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) { | ||||
|       if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) { | ||||
| 	goto __Y; | ||||
|       } | ||||
| 
 | ||||
|       /* if y == 1 then composite */ | ||||
|       if (mp_cmp_d (&y, 1) == MP_EQ) { | ||||
| 	goto __Y; | ||||
|       } | ||||
| 
 | ||||
|       ++j; | ||||
|     } | ||||
| 
 | ||||
|     /* if y != n1 then composite */ | ||||
|     if (mp_cmp (&y, &n1) != MP_EQ) { | ||||
|       goto __Y; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /* probably prime now */ | ||||
|   *result = 1; | ||||
| __Y:mp_clear (&y); | ||||
| __R:mp_clear (&r); | ||||
| __N1:mp_clear (&n1); | ||||
|   return err; | ||||
| } | ||||
							
								
								
									
										54
									
								
								bn_mp_prime_next_prime.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								bn_mp_prime_next_prime.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,54 @@ | ||||
| /* LibTomMath, multiple-precision integer library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomMath is library that provides for multiple-precision | ||||
|  * integer arithmetic as well as number theoretic functionality. | ||||
|  * | ||||
|  * The library is designed directly after the MPI library by | ||||
|  * Michael Fromberger but has been written from scratch with | ||||
|  * additional optimizations in place. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
 | ||||
|  */ | ||||
| #include <tommath.h> | ||||
| 
 | ||||
| /* finds the next prime after the number "a" using "t" trials
 | ||||
|  * of Miller-Rabin. | ||||
|  */ | ||||
| int mp_prime_next_prime(mp_int *a, int t) | ||||
| { | ||||
|    int err, res; | ||||
|     | ||||
|    if (mp_iseven(a) == 1) { | ||||
|       /* force odd */ | ||||
|       if ((err = mp_add_d(a, 1, a)) != MP_OKAY) { | ||||
|          return err; | ||||
|       } | ||||
|    } else { | ||||
|       /* force to next number */ | ||||
|       if ((err = mp_add_d(a, 2, a)) != MP_OKAY) { | ||||
|          return err; | ||||
|       } | ||||
|    }      | ||||
|     | ||||
|    for (;;) { | ||||
|       /* is this prime? */ | ||||
|       if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { | ||||
|          return err; | ||||
|       } | ||||
|        | ||||
|       if (res == 1) { | ||||
|          break; | ||||
|       } | ||||
|        | ||||
|       /* add two, next candidate */ | ||||
|       if ((err = mp_add_d(a, 2, a)) != MP_OKAY) { | ||||
|          return err; | ||||
|       } | ||||
|    } | ||||
|     | ||||
|    return MP_OKAY; | ||||
| } | ||||
| 
 | ||||
| @ -50,7 +50,7 @@ mp_rshd (mp_int * a, int b) | ||||
|      b-2 | b-1 | b0 | b1 | b2 | ... | bb |   ----> | ||||
|                  /\                   |      ----> | ||||
|                   \-------------------/      ----> | ||||
|     */          | ||||
|      */ | ||||
|     for (x = 0; x < (a->used - b); x++) { | ||||
|       *tmpa++ = *tmpaa++; | ||||
|     } | ||||
|  | ||||
| @ -19,7 +19,7 @@ int | ||||
| mp_shrink (mp_int * a) | ||||
| { | ||||
|   if (a->alloc != a->used) { | ||||
|     if ((a->dp = realloc (a->dp, sizeof (mp_digit) * a->used)) == NULL) { | ||||
|     if ((a->dp = OPT_CAST realloc (a->dp, sizeof (mp_digit) * a->used)) == NULL) { | ||||
|       return MP_MEM; | ||||
|     } | ||||
|     a->alloc = a->used; | ||||
|  | ||||
							
								
								
									
										52
									
								
								bn_prime_tab.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								bn_prime_tab.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | ||||
| /* LibTomMath, multiple-precision integer library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomMath is library that provides for multiple-precision | ||||
|  * integer arithmetic as well as number theoretic functionality. | ||||
|  * | ||||
|  * The library is designed directly after the MPI library by | ||||
|  * Michael Fromberger but has been written from scratch with | ||||
|  * additional optimizations in place. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
 | ||||
|  */ | ||||
| #include <tommath.h> | ||||
| const mp_digit __prime_tab[] = { | ||||
|   0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, | ||||
|   0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, | ||||
|   0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, | ||||
|   0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, 0x0083, | ||||
|   0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD, | ||||
|   0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF, | ||||
|   0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107, | ||||
|   0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137, | ||||
| 
 | ||||
|   0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167, | ||||
|   0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199, | ||||
|   0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9, | ||||
|   0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7, | ||||
|   0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239, | ||||
|   0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265, | ||||
|   0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293, | ||||
|   0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF, | ||||
| 
 | ||||
|   0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301, | ||||
|   0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B, | ||||
|   0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371, | ||||
|   0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD, | ||||
|   0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5, | ||||
|   0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419, | ||||
|   0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449, | ||||
|   0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B, | ||||
| 
 | ||||
|   0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7, | ||||
|   0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503, | ||||
|   0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529, | ||||
|   0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F, | ||||
|   0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3, | ||||
|   0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7, | ||||
|   0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623, | ||||
|   0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 | ||||
| }; | ||||
| @ -93,7 +93,7 @@ mp_toradix (mp_int * a, char *str, int radix) | ||||
|     *str++ = s_rmap[d]; | ||||
|     ++digs; | ||||
|   } | ||||
|   bn_reverse ((unsigned char *) _s, digs); | ||||
|   bn_reverse ((unsigned char *)_s, digs); | ||||
|   *str++ = '\0'; | ||||
|   mp_clear (&t); | ||||
|   return MP_OKAY; | ||||
|  | ||||
							
								
								
									
										2
									
								
								bncore.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								bncore.c
									
									
									
									
									
								
							| @ -18,5 +18,3 @@ | ||||
| int     KARATSUBA_MUL_CUTOFF = 73,	/* Min. number of digits before Karatsuba multiplication is used. */ | ||||
|         KARATSUBA_SQR_CUTOFF = 121,	/* Min. number of digits before Karatsuba squaring is used. */ | ||||
|         MONTGOMERY_EXPT_CUTOFF = 128;	/* max. number of digits that montgomery reductions will help for */ | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										11
									
								
								changes.txt
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								changes.txt
									
									
									
									
									
								
							| @ -1,3 +1,14 @@ | ||||
| Mar 22nd, 2003 | ||||
| v0.15  -- Added series of prime testing routines to lib | ||||
|        -- Fixed up etc/tune.c | ||||
|        -- Added DR reduction algorithm | ||||
|        -- Beefed up the manual more. | ||||
|        -- Fixed up demo/demo.c so it doesn't have so many warnings and it does the full series of | ||||
|           tests | ||||
|        -- Added "pre-gen" directory which will hold a "gen.pl"'ed copy of the entire lib [done at | ||||
|           zipup time so its always the latest] | ||||
|        -- Added conditional casts for C++ users [boo!] | ||||
| 
 | ||||
| Mar 15th, 2003 | ||||
| v0.14  -- Tons of manual updates | ||||
|        -- cleaned up the directory | ||||
|  | ||||
							
								
								
									
										52
									
								
								demo/demo.c
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								demo/demo.c
									
									
									
									
									
								
							| @ -89,7 +89,7 @@ int main(void) | ||||
|    unsigned long expt_n, add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n, gcd_n, lcm_n, inv_n, | ||||
|                  div2_n, mul2_n; | ||||
|    unsigned rr; | ||||
|    int cnt; | ||||
|    int cnt, ix; | ||||
| 
 | ||||
| #ifdef TIMER | ||||
|    int n; | ||||
| @ -104,9 +104,42 @@ int main(void) | ||||
|    mp_init(&e); | ||||
|    mp_init(&f); | ||||
|     | ||||
| /* test the DR reduction */ | ||||
| #if 0 | ||||
|     | ||||
|    srand(time(NULL)); | ||||
|    for (cnt = 2; cnt < 32; cnt++) { | ||||
|        printf("%d digit modulus\n", cnt); | ||||
|        mp_grow(&a, cnt); | ||||
|        mp_zero(&a); | ||||
|        for (ix = 1; ix < cnt; ix++) { | ||||
|            a.dp[ix] = MP_MASK; | ||||
|        } | ||||
|        a.used = cnt; | ||||
|        mp_prime_next_prime(&a, 3); | ||||
|         | ||||
|        mp_rand(&b, cnt - 1); | ||||
|        mp_copy(&b, &c); | ||||
|     | ||||
|       rr = 0; | ||||
|       do { | ||||
|          if (!(rr & 127)) { printf("%9lu\r", rr); fflush(stdout); } | ||||
|          mp_sqr(&b, &b); mp_add_d(&b, 1, &b); | ||||
|          mp_copy(&b, &c); | ||||
|        | ||||
|          mp_mod(&b, &a, &b); | ||||
|          mp_dr_reduce(&c, &a, (1<<DIGIT_BIT)-a.dp[0]); | ||||
|        | ||||
|          if (mp_cmp(&b, &c) != MP_EQ) { | ||||
|             printf("Failed on trial %lu\n", rr); exit(-1); | ||||
|          } | ||||
|       } while (++rr < 1000000);  | ||||
|       printf("Passed DR test for %d digits\n", cnt); | ||||
|    } | ||||
| #endif    | ||||
| 
 | ||||
| #ifdef TIMER | ||||
|       printf("CLOCKS_PER_SEC == %lu\n", CLOCKS_PER_SEC); | ||||
| goto expttime;       | ||||
| 
 | ||||
|       log = fopen("add.log", "w"); | ||||
|       for (cnt = 4; cnt <= 128; cnt += 4) { | ||||
| @ -136,7 +169,6 @@ goto expttime; | ||||
|       } | ||||
|       fclose(log); | ||||
|        | ||||
| multtime:       | ||||
| 
 | ||||
|    log = fopen("sqr.log", "w"); | ||||
|    for (cnt = 4; cnt <= 128; cnt += 4) { | ||||
| @ -165,9 +197,18 @@ multtime: | ||||
|    } | ||||
|    fclose(log); | ||||
| 
 | ||||
| expttime:   | ||||
|    { | ||||
|       char *primes[] = { | ||||
|          /* DR moduli */ | ||||
|          "14059105607947488696282932836518693308967803494693489478439861164411992439598399594747002144074658928593502845729752797260025831423419686528151609940203368612079", | ||||
|          "101745825697019260773923519755878567461315282017759829107608914364075275235254395622580447400994175578963163918967182013639660669771108475957692810857098847138903161308502419410142185759152435680068435915159402496058513611411688900243039", | ||||
|          "736335108039604595805923406147184530889923370574768772191969612422073040099331944991573923112581267542507986451953227192970402893063850485730703075899286013451337291468249027691733891486704001513279827771740183629161065194874727962517148100775228363421083691764065477590823919364012917984605619526140821797602431", | ||||
|          "38564998830736521417281865696453025806593491967131023221754800625044118265468851210705360385717536794615180260494208076605798671660719333199513807806252394423283413430106003596332513246682903994829528690198205120921557533726473585751382193953592127439965050261476810842071573684505878854588706623484573925925903505747545471088867712185004135201289273405614415899438276535626346098904241020877974002916168099951885406379295536200413493190419727789712076165162175783", | ||||
|          "542189391331696172661670440619180536749994166415993334151601745392193484590296600979602378676624808129613777993466242203025054573692562689251250471628358318743978285860720148446448885701001277560572526947619392551574490839286458454994488665744991822837769918095117129546414124448777033941223565831420390846864429504774477949153794689948747680362212954278693335653935890352619041936727463717926744868338358149568368643403037768649616778526013610493696186055899318268339432671541328195724261329606699831016666359440874843103020666106568222401047720269951530296879490444224546654729111504346660859907296364097126834834235287147", | ||||
|          "1487259134814709264092032648525971038895865645148901180585340454985524155135260217788758027400478312256339496385275012465661575576202252063145698732079880294664220579764848767704076761853197216563262660046602703973050798218246170835962005598561669706844469447435461092542265792444947706769615695252256130901271870341005768912974433684521436211263358097522726462083917939091760026658925757076733484173202927141441492573799914240222628795405623953109131594523623353044898339481494120112723445689647986475279242446083151413667587008191682564376412347964146113898565886683139407005941383669325997475076910488086663256335689181157957571445067490187939553165903773554290260531009121879044170766615232300936675369451260747671432073394867530820527479172464106442450727640226503746586340279816318821395210726268291535648506190714616083163403189943334431056876038286530365757187367147446004855912033137386225053275419626102417236133948503", | ||||
|          "1095121115716677802856811290392395128588168592409109494900178008967955253005183831872715423151551999734857184538199864469605657805519106717529655044054833197687459782636297255219742994736751541815269727940751860670268774903340296040006114013971309257028332849679096824800250742691718610670812374272414086863715763724622797509437062518082383056050144624962776302147890521249477060215148275163688301275847155316042279405557632639366066847442861422164832655874655824221577849928863023018366835675399949740429332468186340518172487073360822220449055340582568461568645259954873303616953776393853174845132081121976327462740354930744487429617202585015510744298530101547706821590188733515880733527449780963163909830077616357506845523215289297624086914545378511082534229620116563260168494523906566709418166011112754529766183554579321224940951177394088465596712620076240067370589036924024728375076210477267488679008016579588696191194060127319035195370137160936882402244399699172017835144537488486396906144217720028992863941288217185353914991583400421682751000603596655790990815525126154394344641336397793791497068253936771017031980867706707490224041075826337383538651825493679503771934836094655802776331664261631740148281763487765852746577808019633679", | ||||
|           | ||||
|          /* generic unrestricted moduli */ | ||||
|          "17933601194860113372237070562165128350027320072176844226673287945873370751245439587792371960615073855669274087805055507977323024886880985062002853331424203", | ||||
|          "2893527720709661239493896562339544088620375736490408468011883030469939904368086092336458298221245707898933583190713188177399401852627749210994595974791782790253946539043962213027074922559572312141181787434278708783207966459019479487", | ||||
|          "347743159439876626079252796797422223177535447388206607607181663903045907591201940478223621722118173270898487582987137708656414344685816179420855160986340457973820182883508387588163122354089264395604796675278966117567294812714812796820596564876450716066283126720010859041484786529056457896367683122960411136319", | ||||
| @ -208,7 +249,7 @@ expttime: | ||||
|    } | ||||
|    }    | ||||
|    fclose(log); | ||||
| invtime: | ||||
| 
 | ||||
|    log = fopen("invmod.log", "w"); | ||||
|    for (cnt = 4; cnt <= 128; cnt += 4) { | ||||
|       mp_rand(&a, cnt); | ||||
| @ -241,7 +282,6 @@ invtime: | ||||
|    div2_n = mul2_n = inv_n = expt_n = lcm_n = gcd_n = add_n =  | ||||
|    sub_n = mul_n = div_n = sqr_n = mul2d_n = div2d_n = cnt = 0; | ||||
|    for (;;) { | ||||
|        if (!(++cnt & 15)) sleep(3); | ||||
|   | ||||
|        /* randomly clear and re-init one variable, this has the affect of triming the alloc space */ | ||||
|        switch (abs(rand()) % 7) { | ||||
|  | ||||
							
								
								
									
										53
									
								
								etc/drprime.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								etc/drprime.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | ||||
| /* Makes safe primes of a DR nature */ | ||||
| #include <tommath.h> | ||||
| 
 | ||||
| const int sizes[] = { 8, 19, 28, 37, 55, 74,  110, 147 }; | ||||
| int main(void) | ||||
| { | ||||
|    int res, x, y; | ||||
|    char buf[4096]; | ||||
|    FILE *out; | ||||
|    mp_int a, b; | ||||
|     | ||||
|    mp_init(&a); | ||||
|    mp_init(&b); | ||||
|     | ||||
|    out = fopen("drprimes.txt", "w"); | ||||
|    for (x = 0; x < (int)(sizeof(sizes)/sizeof(sizes[0])); x++) { | ||||
|        printf("Seeking a %d-bit safe prime\n", sizes[x] * DIGIT_BIT); | ||||
|        mp_grow(&a, sizes[x]); | ||||
|        mp_zero(&a); | ||||
|        for (y = 1; y < sizes[x]; y++) { | ||||
|            a.dp[y] = MP_MASK; | ||||
|        } | ||||
|         | ||||
|        /* make a DR modulus */ | ||||
|        a.dp[0] = 1; | ||||
|        a.used = sizes[x]; | ||||
|         | ||||
|        /* now loop */ | ||||
|        do {  | ||||
|           fflush(stdout); | ||||
|           mp_prime_next_prime(&a, 3); | ||||
|           printf("."); | ||||
|           mp_sub_d(&a, 1, &b); | ||||
|           mp_div_2(&b, &b); | ||||
|           mp_prime_is_prime(&b, 3, &res);   | ||||
| 	} while (res == 0);           | ||||
|          | ||||
|         if (mp_dr_is_modulus(&a) != 1) { | ||||
|            printf("Error not DR modulus\n"); | ||||
|         } else { | ||||
|            mp_toradix(&a, buf, 10); | ||||
|            printf("\n\np == %s\n\n", buf); | ||||
|            fprintf(out, "%d-bit prime:\np == %s\n\n", mp_count_bits(&a), buf); fflush(out); | ||||
|         }            | ||||
|    } | ||||
|    fclose(out); | ||||
|     | ||||
|    mp_clear(&a); | ||||
|    mp_clear(&b); | ||||
|     | ||||
|    return 0; | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										23
									
								
								etc/drprimes.1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								etc/drprimes.1
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| 224-bit prime: | ||||
| p == 26959946667150639794667015087019630673637144422540572481103341844143 | ||||
| 
 | ||||
| 532-bit prime: | ||||
| p == 14059105607947488696282932836518693308967803494693489478439861164411992439598399594747002144074658928593502845729752797260025831423419686528151609940203368691747 | ||||
| 
 | ||||
| 784-bit prime: | ||||
| p == 101745825697019260773923519755878567461315282017759829107608914364075275235254395622580447400994175578963163918967182013639660669771108475957692810857098847138903161308502419410142185759152435680068435915159402496058513611411688900243039 | ||||
| 
 | ||||
| 1036-bit prime: | ||||
| p == 736335108039604595805923406147184530889923370574768772191969612422073040099331944991573923112581267542507986451953227192970402893063850485730703075899286013451337291468249027691733891486704001513279827771740183629161065194874727962517148100775228363421083691764065477590823919364012917984605619526140821798437127 | ||||
| 
 | ||||
| 1540-bit prime: | ||||
| p == 38564998830736521417281865696453025806593491967131023221754800625044118265468851210705360385717536794615180260494208076605798671660719333199513807806252394423283413430106003596332513246682903994829528690198205120921557533726473585751382193953592127439965050261476810842071573684505878854588706623484573925925903505747545471088867712185004135201289273405614415899438276535626346098904241020877974002916168099951885406379295536200413493190419727789712076165162175783 | ||||
| 
 | ||||
| 2072-bit prime: | ||||
| p == 542189391331696172661670440619180536749994166415993334151601745392193484590296600979602378676624808129613777993466242203025054573692562689251250471628358318743978285860720148446448885701001277560572526947619392551574490839286458454994488665744991822837769918095117129546414124448777033941223565831420390846864429504774477949153794689948747680362212954278693335653935890352619041936727463717926744868338358149568368643403037768649616778526013610493696186055899318268339432671541328195724261329606699831016666359440874843103020666106568222401047720269951530296879490444224546654729111504346660859907296364097126834834235287147 | ||||
| 
 | ||||
| 3080-bit prime: | ||||
| p == 1487259134814709264092032648525971038895865645148901180585340454985524155135260217788758027400478312256339496385275012465661575576202252063145698732079880294664220579764848767704076761853197216563262660046602703973050798218246170835962005598561669706844469447435461092542265792444947706769615695252256130901271870341005768912974433684521436211263358097522726462083917939091760026658925757076733484173202927141441492573799914240222628795405623953109131594523623353044898339481494120112723445689647986475279242446083151413667587008191682564376412347964146113898565886683139407005941383669325997475076910488086663256335689181157957571445067490187939553165903773554290260531009121879044170766615232300936675369451260747671432073394867530820527479172464106442450727640226503746586340279816318821395210726268291535648506190714616083163403189943334431056876038286530365757187367147446004855912033137386225053275419626102417236133948503 | ||||
| 
 | ||||
| 4116-bit prime: | ||||
| p == 1095121115716677802856811290392395128588168592409109494900178008967955253005183831872715423151551999734857184538199864469605657805519106717529655044054833197687459782636297255219742994736751541815269727940751860670268774903340296040006114013971309257028332849679096824800250742691718610670812374272414086863715763724622797509437062518082383056050144624962776302147890521249477060215148275163688301275847155316042279405557632639366066847442861422164832655874655824221577849928863023018366835675399949740429332468186340518172487073360822220449055340582568461568645259954873303616953776393853174845132081121976327462740354930744487429617202585015510744298530101547706821590188733515880733527449780963163909830077616357506845523215289297624086914545378511082534229620116563260168494523906566709418166011112754529766183554579321224940951177394088465596712620076240067370589036924024728375076210477267488679008016579588696191194060127319035195370137160936882402244399699172017835144537488486396906144217720028992863941288217185353914991583400421682751000603596655790990815525126154394344641336397793791497068253936771017031980867706707490224041075826337383538651825493679503771934836094655802776331664261631740148281763487765852746577808019633679 | ||||
| @ -16,5 +16,8 @@ tune: tune.o | ||||
| mersenne: mersenne.o | ||||
| 	$(CC) mersenne.o $(LIBNAME) -o mersenne | ||||
| 
 | ||||
| drprime: drprime.o | ||||
| 	$(CC) drprime.o $(LIBNAME) -o drprime | ||||
|          | ||||
| clean: | ||||
| 	rm -f *.log *.o *.obj *.exe pprime tune mersenne  | ||||
| 	rm -f *.log *.o *.obj *.exe pprime tune mersenne drprime | ||||
| @ -12,3 +12,6 @@ mersenne: mersenne.obj | ||||
| 	 | ||||
| tune: tune.obj | ||||
| 	cl tune.obj ../tommath.lib | ||||
| 	 | ||||
| drprime: drprime.obj | ||||
| 	cl drprime.obj ../tommath.lib | ||||
							
								
								
									
										12
									
								
								etc/tune.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								etc/tune.c
									
									
									
									
									
								
							| @ -17,7 +17,7 @@ time_mult (void) | ||||
|   mp_init (&c); | ||||
| 
 | ||||
|   t1 = clock (); | ||||
|   for (x = 4; x <= 128; x += 4) { | ||||
|   for (x = 4; x <= 144; x += 4) { | ||||
|     mp_rand (&a, x); | ||||
|     mp_rand (&b, x); | ||||
|     for (y = 0; y < 10000; y++) { | ||||
| @ -41,7 +41,7 @@ time_sqr (void) | ||||
|   mp_init (&b); | ||||
| 
 | ||||
|   t1 = clock (); | ||||
|   for (x = 4; x <= 128; x += 4) { | ||||
|   for (x = 4; x <= 144; x += 4) { | ||||
|     mp_rand (&a, x); | ||||
|     for (y = 0; y < 10000; y++) { | ||||
|       mp_sqr (&a, &b); | ||||
| @ -65,7 +65,7 @@ time_expt (void) | ||||
|   mp_init (&d); | ||||
| 
 | ||||
|   t1 = clock (); | ||||
|   for (x = 4; x <= 128; x += 4) { | ||||
|   for (x = 4; x <= 144; x += 4) { | ||||
|     mp_rand (&a, x); | ||||
|     mp_rand (&b, x); | ||||
|     mp_rand (&c, x); | ||||
| @ -96,7 +96,7 @@ main (void) | ||||
|   /* tune multiplication first */ | ||||
|   log = fopen ("mult.log", "w"); | ||||
|   best = CLOCKS_PER_SEC * 1000; | ||||
|   for (KARATSUBA_MUL_CUTOFF = 8; KARATSUBA_MUL_CUTOFF <= 128; KARATSUBA_MUL_CUTOFF++) { | ||||
|   for (KARATSUBA_MUL_CUTOFF = 8; KARATSUBA_MUL_CUTOFF <= 144; KARATSUBA_MUL_CUTOFF++) { | ||||
|     ti = time_mult (); | ||||
|     printf ("%4d : %9lu\r", KARATSUBA_MUL_CUTOFF, ti); | ||||
|     fprintf (log, "%d, %lu\n", KARATSUBA_MUL_CUTOFF, ti); | ||||
| @ -112,7 +112,7 @@ main (void) | ||||
|   /* tune squaring */ | ||||
|   log = fopen ("sqr.log", "w"); | ||||
|   best = CLOCKS_PER_SEC * 1000; | ||||
|   for (KARATSUBA_SQR_CUTOFF = 8; KARATSUBA_SQR_CUTOFF <= 128; KARATSUBA_SQR_CUTOFF++) { | ||||
|   for (KARATSUBA_SQR_CUTOFF = 8; KARATSUBA_SQR_CUTOFF <= 144; KARATSUBA_SQR_CUTOFF++) { | ||||
|     ti = time_sqr (); | ||||
|     printf ("%4d : %9lu\r", KARATSUBA_SQR_CUTOFF, ti); | ||||
|     fprintf (log, "%d, %lu\n", KARATSUBA_SQR_CUTOFF, ti); | ||||
| @ -131,7 +131,7 @@ main (void) | ||||
| 
 | ||||
|   log = fopen ("expt.log", "w"); | ||||
|   best = CLOCKS_PER_SEC * 1000; | ||||
|   for (MONTGOMERY_EXPT_CUTOFF = 8; MONTGOMERY_EXPT_CUTOFF <= 192; MONTGOMERY_EXPT_CUTOFF++) { | ||||
|   for (MONTGOMERY_EXPT_CUTOFF = 8; MONTGOMERY_EXPT_CUTOFF <= 144; MONTGOMERY_EXPT_CUTOFF++) { | ||||
|     ti = time_expt (); | ||||
|     printf ("%4d : %9lu\r", MONTGOMERY_EXPT_CUTOFF, ti); | ||||
|     fflush (stdout); | ||||
|  | ||||
							
								
								
									
										7
									
								
								makefile
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								makefile
									
									
									
									
									
								
							| @ -1,6 +1,6 @@ | ||||
| CFLAGS  +=  -I./ -Wall -W -Wshadow -O3 -fomit-frame-pointer -funroll-loops | ||||
| 
 | ||||
| VERSION=0.14 | ||||
| VERSION=0.15 | ||||
| 
 | ||||
| default: libtommath.a | ||||
| 
 | ||||
| @ -30,7 +30,9 @@ bn_mp_reduce.o bn_mp_montgomery_setup.o bn_fast_mp_montgomery_reduce.o bn_mp_mon | ||||
| bn_mp_exptmod_fast.o bn_mp_exptmod.o bn_mp_2expt.o bn_mp_n_root.o bn_mp_jacobi.o bn_reverse.o \ | ||||
| bn_mp_count_bits.o bn_mp_read_unsigned_bin.o bn_mp_read_signed_bin.o bn_mp_to_unsigned_bin.o \ | ||||
| bn_mp_to_signed_bin.o bn_mp_unsigned_bin_size.o bn_mp_signed_bin_size.o bn_radix.o \ | ||||
| bn_mp_xor.o bn_mp_and.o bn_mp_or.o bn_mp_rand.o bn_mp_montgomery_calc_normalization.o | ||||
| bn_mp_xor.o bn_mp_and.o bn_mp_or.o bn_mp_rand.o bn_mp_montgomery_calc_normalization.o \ | ||||
| bn_mp_prime_is_divisible.o bn_prime_tab.o bn_mp_prime_fermat.o bn_mp_prime_miller_rabin.o \ | ||||
| bn_mp_prime_is_prime.o bn_mp_prime_next_prime.o bn_mp_dr_reduce.o  | ||||
| 
 | ||||
| libtommath.a:  $(OBJECTS) | ||||
| 	$(AR) $(ARFLAGS) libtommath.a $(OBJECTS) | ||||
| @ -65,6 +67,7 @@ clean: | ||||
| 	cd etc ; make clean | ||||
| 
 | ||||
| zipup: clean docs | ||||
| 	perl gen.pl ; mv mpi.c pre_gen/ ; \
 | ||||
| 	cd .. ; rm -rf ltm* libtommath-$(VERSION) ; mkdir libtommath-$(VERSION) ; \
 | ||||
| 	cp -R ./libtommath/* ./libtommath-$(VERSION)/ ; tar -c libtommath-$(VERSION)/* > ltm-$(VERSION).tar ; \
 | ||||
| 	bzip2 -9vv ltm-$(VERSION).tar ; zip -9 -r ltm-$(VERSION).zip libtommath-$(VERSION)/* | ||||
|  | ||||
| @ -20,7 +20,10 @@ bn_mp_reduce.obj bn_mp_montgomery_setup.obj bn_fast_mp_montgomery_reduce.obj bn_ | ||||
| bn_mp_exptmod_fast.obj bn_mp_exptmod.obj bn_mp_2expt.obj bn_mp_n_root.obj bn_mp_jacobi.obj bn_reverse.obj \ | ||||
| bn_mp_count_bits.obj bn_mp_read_unsigned_bin.obj bn_mp_read_signed_bin.obj bn_mp_to_unsigned_bin.obj \ | ||||
| bn_mp_to_signed_bin.obj bn_mp_unsigned_bin_size.obj bn_mp_signed_bin_size.obj bn_radix.obj \ | ||||
| bn_mp_xor.obj bn_mp_and.obj bn_mp_or.obj bn_mp_rand.obj bn_mp_montgomery_calc_normalization.obj | ||||
| bn_mp_xor.obj bn_mp_and.obj bn_mp_or.obj bn_mp_rand.obj bn_mp_montgomery_calc_normalization.obj \ | ||||
| bn_mp_prime_is_divisible.obj bn_prime_tab.obj bn_mp_prime_fermat.obj bn_mp_prime_miller_rabin.obj \ | ||||
| bn_mp_prime_is_prime.obj bn_mp_prime_next_prime.obj bn_mp_dr_reduce.obj | ||||
| 
 | ||||
| 
 | ||||
| library: $(OBJECTS) | ||||
| 	lib /out:tommath.lib $(OBJECTS) | ||||
|  | ||||
| @ -41,7 +41,7 @@ void rand_num(mp_int *a) | ||||
|    unsigned char buf[512]; | ||||
| 
 | ||||
| top: | ||||
|    size = 1 + ((fgetc(rng)*fgetc(rng)) % 512); | ||||
|    size = 1 + ((fgetc(rng)*fgetc(rng)) % 96); | ||||
|    buf[0] = (fgetc(rng)&1)?1:0; | ||||
|    fread(buf+1, 1, size, rng); | ||||
|    for (n = 0; n < size; n++) { | ||||
| @ -57,7 +57,7 @@ void rand_num2(mp_int *a) | ||||
|    unsigned char buf[512]; | ||||
| 
 | ||||
| top: | ||||
|    size = 1 + ((fgetc(rng)*fgetc(rng)) % 512); | ||||
|    size = 1 + ((fgetc(rng)*fgetc(rng)) % 96); | ||||
|    buf[0] = (fgetc(rng)&1)?1:0; | ||||
|    fread(buf+1, 1, size, rng); | ||||
|    for (n = 0; n < size; n++) { | ||||
| @ -73,8 +73,6 @@ int main(void) | ||||
|    mp_int a, b, c, d, e; | ||||
|    char buf[4096]; | ||||
|     | ||||
|    static int tests[] = { 11, 12 }; | ||||
| 
 | ||||
|    mp_init(&a); | ||||
|    mp_init(&b); | ||||
|    mp_init(&c); | ||||
|  | ||||
							
								
								
									
										5993
									
								
								pre_gen/mpi.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5993
									
								
								pre_gen/mpi.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										56
									
								
								tommath.h
									
									
									
									
									
								
							
							
						
						
									
										56
									
								
								tommath.h
									
									
									
									
									
								
							| @ -28,8 +28,16 @@ | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| /* C++ compilers don't like assigning void * to mp_digit * */ | ||||
| #define  OPT_CAST  (mp_digit *) | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
| /* C on the other hand dosen't care */ | ||||
| #define  OPT_CAST   | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| /* some default configurations.  
 | ||||
|  * | ||||
| @ -202,7 +210,6 @@ int mp_cmp_mag(mp_int *a, mp_int *b); | ||||
| /* c = a + b */ | ||||
| int mp_add(mp_int *a, mp_int *b, mp_int *c); | ||||
| 
 | ||||
| 
 | ||||
| /* c = a - b */ | ||||
| int mp_sub(mp_int *a, mp_int *b, mp_int *c); | ||||
| 
 | ||||
| @ -297,9 +304,52 @@ int mp_montgomery_calc_normalization(mp_int *a, mp_int *b); | ||||
| /* computes xR^-1 == x (mod N) via Montgomery Reduction */ | ||||
| int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp); | ||||
| 
 | ||||
| /* returns 1 if a is a valid DR modulus */ | ||||
| int mp_dr_is_modulus(mp_int *a); | ||||
| 
 | ||||
| /* sets the value of "d" required for mp_dr_reduce */ | ||||
| void mp_dr_setup(mp_int *a, mp_digit *d); | ||||
| 
 | ||||
| /* reduces a modulo b using the Diminished Radix method */ | ||||
| int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp); | ||||
| 
 | ||||
| /* d = a^b (mod c) */ | ||||
| int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); | ||||
| 
 | ||||
| /* ---> Primes <--- */ | ||||
| #define PRIME_SIZE	256	/* number of primes */ | ||||
| 
 | ||||
| /* table of first 256 primes */ | ||||
| extern const mp_digit __prime_tab[]; | ||||
| 
 | ||||
| /* result=1 if a is divisible by one of the first 256 primes */ | ||||
| int mp_prime_is_divisible(mp_int *a, int *result); | ||||
| 
 | ||||
| /* performs one Fermat test of "a" using base "b".  
 | ||||
|  * Sets result to 0 if composite or 1 if probable prime  | ||||
|  */ | ||||
| int mp_prime_fermat(mp_int *a, mp_int *b, int *result); | ||||
| 
 | ||||
| /* performs one Miller-Rabin test of "a" using base "b".
 | ||||
|  * Sets result to 0 if composite or 1 if probable prime  | ||||
|  */ | ||||
| int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result); | ||||
| 
 | ||||
| /* performs t rounds of Miller-Rabin on "a" using the first
 | ||||
|  * t prime bases.  Also performs an initial sieve of trial | ||||
|  * division.  Determines if "a" is prime with probability | ||||
|  * of error no more than (1/4)^t. | ||||
|  * | ||||
|  * Sets result to 1 if probably prime, 0 otherwise | ||||
|  */ | ||||
| int mp_prime_is_prime(mp_int *a, int t, int *result); | ||||
| 
 | ||||
| /* finds the next prime after the number "a" using "t" trials
 | ||||
|  * of Miller-Rabin. | ||||
|  */ | ||||
| int mp_prime_next_prime(mp_int *a, int t); | ||||
| 
 | ||||
| 
 | ||||
| /* ---> radix conversion <--- */ | ||||
| int mp_count_bits(mp_int *a); | ||||
| 
 | ||||
| @ -341,7 +391,7 @@ int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c); | ||||
| int mp_karatsuba_sqr(mp_int *a, mp_int *b); | ||||
| int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c); | ||||
| int fast_mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp); | ||||
| int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y); | ||||
| int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int mode); | ||||
| void bn_reverse(unsigned char *s, int len); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user