⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bn.tex

📁 tommath库
💻 TEX
📖 第 1 页 / 共 5 页
字号:
   if ((result = mp_montgomery_setup(&c, &mp)) != MP_OKAY) \{      printf("Error setting up montgomery.  \%s",              mp_error_to_string(result));      return EXIT_FAILURE;   \}   /* normalize `a' so now a is equal to aR */   if ((result = mp_mulmod(&a, &R, &b, &a)) != MP_OKAY) \{      printf("Error computing aR.  \%s",              mp_error_to_string(result));      return EXIT_FAILURE;   \}   /* square a to get c = a^2R^2 */   if ((result = mp_sqr(&a, &c)) != MP_OKAY) \{      printf("Error squaring.  \%s",              mp_error_to_string(result));      return EXIT_FAILURE;   \}   /* now reduce `c' back down to c = a^2R^2 * R^-1 == a^2R */   if ((result = mp_montgomery_reduce(&c, &b, mp)) != MP_OKAY) \{      printf("Error reducing.  \%s",              mp_error_to_string(result));      return EXIT_FAILURE;   \}      /* multiply a to get c = a^3R^2 */   if ((result = mp_mul(&a, &c, &c)) != MP_OKAY) \{      printf("Error reducing.  \%s",              mp_error_to_string(result));      return EXIT_FAILURE;   \}   /* now reduce `c' back down to c = a^3R^2 * R^-1 == a^3R */   if ((result = mp_montgomery_reduce(&c, &b, mp)) != MP_OKAY) \{      printf("Error reducing.  \%s",              mp_error_to_string(result));      return EXIT_FAILURE;   \}      /* now reduce (again) `c' back down to c = a^3R * R^-1 == a^3 */   if ((result = mp_montgomery_reduce(&c, &b, mp)) != MP_OKAY) \{      printf("Error reducing.  \%s",              mp_error_to_string(result));      return EXIT_FAILURE;   \}   /* c now equals a^3 mod b */   return EXIT_SUCCESS;\}\end{alltt} This particular example does not look too efficient but it demonstrates the point of the algorithm.  By normalizing the inputs the reduced results are always of the form $aR$ for some variable $a$.  This allowsa single final reduction to correct for the normalization and the fast reduction used within the algorithm.For more details consider examining the file \textit{bn\_mp\_exptmod\_fast.c}.\section{Restricted Dimminished Radix}``Dimminished Radix'' reduction refers to reduction with respect to moduli that are ameniable to simpledigit shifting and small multiplications.  In this case the ``restricted'' variant refers to moduli of theform $\beta^k - p$ for some $k \ge 0$ and $0 < p < \beta$ where $\beta$ is the radix (default to $2^{28}$).  As in the case of Montgomery reduction there is a pre--computation phase required for a given modulus.\index{mp\_dr\_setup}\begin{alltt}void mp_dr_setup(mp_int *a, mp_digit *d);\end{alltt}This computes the value required for the modulus $a$ and stores it in $d$.  This function cannot failand does not return any error codes.  After the pre--computation a reduction can be performed with thefollowing.\index{mp\_dr\_reduce}\begin{alltt}int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp);\end{alltt}This reduces $a$ in place modulo $b$ with the pre--computed value $mp$.  $b$ must be of a restricteddimminished radix form and $a$ must be in the range $0 \le a < b^2$.  Dimminished radix reductions are much faster than both Barrett and Montgomery reductions as they have a much lower asymtotic running time.  Since the moduli are restricted this algorithm is not particularly useful for something like Rabin, RSA orBBS cryptographic purposes.  This reduction algorithm is useful for Diffie-Hellman and ECC where fixedprimes are acceptable.  Note that unlike Montgomery reduction there is no normalization process.  The result of this function isequal to the correct residue.\section{Unrestricted Dimminshed Radix}Unrestricted reductions work much like the restricted counterparts except in this case the moduli is of the form $2^k - p$ for $0 < p < \beta$.  In this sense the unrestricted reductions are more flexible as they can be applied to a wider range of numbers.  \index{mp\_reduce\_2k\_setup}\begin{alltt}int mp_reduce_2k_setup(mp_int *a, mp_digit *d);\end{alltt}This will compute the required $d$ value for the given moduli $a$.  \index{mp\_reduce\_2k}\begin{alltt}int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d);\end{alltt}This will reduce $a$ in place modulo $n$ with the pre--computed value $d$.  From my experience this routine is slower than mp\_dr\_reduce but faster for most moduli sizes than the Montgomery reduction.  \chapter{Exponentiation}\section{Single Digit Exponentiation}\index{mp\_expt\_d}\begin{alltt}int mp_expt_d (mp_int * a, mp_digit b, mp_int * c)\end{alltt}This computes $c = a^b$ using a simple binary left-to-right algorithm.  It is faster than repeated multiplications by $a$ for all values of $b$ greater than three.  \section{Modular Exponentiation}\index{mp\_exptmod}\begin{alltt}int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)\end{alltt}This computes $Y \equiv G^X \mbox{ (mod }P\mbox{)}$ using a variable width sliding window algorithm.  This functionwill automatically detect the fastest modular reduction technique to use during the operation.  For negative values of $X$ the operation is performed as $Y \equiv (G^{-1} \mbox{ mod }P)^{\vert X \vert} \mbox{ (mod }P\mbox{)}$ provided that $gcd(G, P) = 1$.This function is actually a shell around the two internal exponentiation functions.  This routine will automaticallydetect when Barrett, Montgomery, Restricted and Unrestricted Dimminished Radix based exponentiation can be used.  Generallymoduli of the a ``restricted dimminished radix'' form lead to the fastest modular exponentiations.  Followed by Montgomeryand the other two algorithms.\section{Root Finding}\index{mp\_n\_root}\begin{alltt}int mp_n_root (mp_int * a, mp_digit b, mp_int * c)\end{alltt}This computes $c = a^{1/b}$ such that $c^b \le a$ and $(c+1)^b > a$.  The implementation of this function is not ideal for values of $b$ greater than three.  It will work but become very slow.  So unless you are working with very smallnumbers (less than 1000 bits) I'd avoid $b > 3$ situations.  Will return a positive root only for even roots and returna root with the sign of the input for odd roots.  For example, performing $4^{1/2}$ will return $2$ whereas $(-8)^{1/3}$ will return $-2$.  This algorithm uses the ``Newton Approximation'' method and will converge on the correct root fairly quickly.  Sincethe algorithm requires raising $a$ to the power of $b$ it is not ideal to attempt to find roots for largevalues of $b$.  If particularly large roots are required then a factor method could be used instead.  For example,$a^{1/16}$ is equivalent to $\left (a^{1/4} \right)^{1/4}$.\chapter{Prime Numbers}\section{Trial Division}\index{mp\_prime\_is\_divisible}\begin{alltt}int mp_prime_is_divisible (mp_int * a, int *result)\end{alltt}This will attempt to evenly divide $a$ by a list of primes\footnote{Default is the first 256 primes.} and store the outcome in ``result''.  That is if $result = 0$ then $a$ is not divisible by the primes, otherwise it is.  Note that if the function does not return \textbf{MP\_OKAY} the value in ``result'' should be considered undefined\footnote{Currentlythe default is to set it to zero first.}.\section{Fermat Test}\index{mp\_prime\_fermat}\begin{alltt}int mp_prime_fermat (mp_int * a, mp_int * b, int *result)\end{alltt}Performs a Fermat primality test to the base $b$.  That is it computes $b^a \mbox{ mod }a$ and tests whether the value isequal to $b$ or not.  If the values are equal then $a$ is probably prime and $result$ is set to one.  Otherwise $result$is set to zero.\section{Miller-Rabin Test}\index{mp\_prime\_miller\_rabin}\begin{alltt}int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)\end{alltt}Performs a Miller-Rabin test to the base $b$ of $a$.  This test is much stronger than the Fermat test and is very hard tofool (besides with Carmichael numbers).  If $a$ passes the test (therefore is probably prime) $result$ is set to one.  Otherwise $result$ is set to zero.  Note that is suggested that you use the Miller-Rabin test instead of the Fermat test since all of the failures of Miller-Rabin are a subset of the failures of the Fermat test.\subsection{Required Number of Tests}Generally to ensure a number is very likely to be prime you have to perform the Miller-Rabin with at least a half-dozenor so unique bases.  However, it has been proven that the probability of failure goes down as the size of the input goes up.This is why a simple function has been provided to help out.\index{mp\_prime\_rabin\_miller\_trials}\begin{alltt}int mp_prime_rabin_miller_trials(int size)\end{alltt}This returns the number of trials required for a $2^{-96}$ (or lower) probability of failure for a given ``size'' expressedin bits.  This comes in handy specially since larger numbers are slower to test.  For example, a 512-bit number wouldrequire ten tests whereas a 1024-bit number would only require four tests. You should always still perform a trial division before a Miller-Rabin test though.\section{Primality Testing}\index{mp\_prime\_is\_prime}\begin{alltt}int mp_prime_is_prime (mp_int * a, int t, int *result)\end{alltt}This will perform a trial division followed by $t$ rounds of Miller-Rabin tests on $a$ and store the result in $result$.  If $a$ passes all of the tests $result$ is set to one, otherwise it is set to zero.  Note that $t$ is bounded by $1 \le t < PRIME\_SIZE$ where $PRIME\_SIZE$ is the number of primes in the prime number table (by default this is $256$).\section{Next Prime}\index{mp\_prime\_next\_prime}\begin{alltt}int mp_prime_next_prime(mp_int *a, int t, int bbs_style)\end{alltt}This finds the next prime after $a$ that passes mp\_prime\_is\_prime() with $t$ tests.  Set $bbs\_style$ to one if you want only the next prime congruent to $3 \mbox{ mod } 4$, otherwise set it to zero to find any next prime.  \section{Random Primes}\index{mp\_prime\_random}\begin{alltt}int mp_prime_random(mp_int *a, int t, int size, int bbs,                     ltm_prime_callback cb, void *dat)\end{alltt}This will find a prime greater than $256^{size}$ which can be ``bbs\_style'' or not depending on $bbs$ and must pass$t$ rounds of tests.  The ``ltm\_prime\_callback'' is a typedef for \begin{alltt}typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat);\end{alltt}Which is a function that must read $len$ bytes (and return the amount stored) into $dst$.  The $dat$ variable is simplycopied from the original input.  It can be used to pass RNG context data to the callback.  The function mp\_prime\_random() is more suitable for generating primes which must be secret (as in the case of RSA) since there is no skew on the least significant bits.\textit{Note:}  As of v0.30 of the LibTomMath library this function has been deprecated.  It is still availablebut users are encouraged to use the new mp\_prime\_random\_ex() function instead.\subsection{Extended Generation}\index{mp\_prime\_random\_ex}\begin{alltt}int mp_prime_random_ex(mp_int *a,    int t,                        int     size, int flags,                        ltm_prime_callback cb, void *dat);\end{alltt}This will generate a prime in $a$ using $t$ tests of the primality testing algorithms.  The variable $size$specifies the bit length of the prime desired.  The variable $flags$ specifies one of several options available(see fig. \ref{fig:primeopts}) which can be OR'ed together.  The callback parameters are used as in mp\_prime\_random().\begin{figure}[here]\begin{center}\begin{small}\begin{tabular}{|r|l|}\hline \textbf{Flag}         & \textbf{Meaning} \\\hline LTM\_PRIME\_BBS       & Make the prime congruent to $3$ modulo $4$ \\\hline LTM\_PRIME\_SAFE      & Make a prime $p$ such that $(p - 1)/2$ is also prime. \\                             & This option implies LTM\_PRIME\_BBS as well. \\\hline LTM\_PRIME\_2MSB\_OFF & Makes sure that the bit adjacent to the most significant bit \\                             & Is forced to zero.  \\\hline LTM\_PRIME\_2MSB\_ON  & Makes sure that the bit adjacent to the most significant bit \\                             & Is forced to one. \\\hline\end{tabular}\end{small}\end{center}\caption{Primality Generation Options}\label{fig:primeopts}\end{figure}\chapter{Input and Output}\section{ASCII Conversions}\subsection{To ASCII}\index{mp\_toradix}\begin{alltt}int mp_toradix (mp_int * a, char *str, int radix);\end{alltt}This still store $a$ in ``str'' as a base-``radix'' string of ASCII chars.  This function appends a NUL characterto terminate the string.  Valid values of ``radix'' line in the range $[2, 64]$.  To determine the size (exact) requiredby the conversion before storing any data use the following function.\index{mp\_radix\_size}\begin{alltt}int mp_radix_size (mp_int * a, int radix, int *size)\end{alltt}This stores in ``size'' the number of characters (including space for the NUL terminator) required.  Upon error this function returns an error code and ``size'' will be zero.  \subsection{From ASCII}\index{mp\_read\_radix}\begin{alltt}int mp_read_radix (mp_int * a, char *str, int radix);\end{alltt}This will read the base-``radix'' NUL terminated string from ``str'' into $a$.  It will stop reading when it reads acharacter it does not recognize (which happens to include th NUL char... imagine that...).  A single leading $-$ signcan be used to denote a negative number.\section{Binary Conversions}Converting an mp\_int to and from binary is another keen idea.\index{mp\_unsigned\_bin\_size}\begin{alltt}int mp_unsigned_bin_size(mp_int *a);\end{alltt}This will return the number of bytes (octets) required to store the unsigned copy of the integer $a$.\index{mp\_to\_unsigned\_bin}\begin{alltt}int mp_to_unsigned_bin(mp_int *a, unsigned char *b);\end{alltt}This will store $a$ into the buffer $b$ in big--endian format.  Fortunately this is exactly what DER (or is it ASN?)requires.  It does not store the sign of the integer.\index{mp\_read\_unsigned\_bin}\begin{alltt}int mp_read_unsigned_bin(mp_int *a, unsigned char *b, int c);\end{alltt}This will read in an unsigned big--endian array of bytes (octets) from $b$ of length $c$ into $a$.  The resultinginteger $a$ will always be positive.For those who acknowledge the existence of negative numbers (heretic!) there are ``signed'' versions of theprevious functions.\begin{alltt}int mp_signed_bin_size(mp_int *a);int mp_read_signed_bin(mp_int *a, unsigned char *b, int c);int mp_to_signed_bin(mp_int *a, unsigned char *b);\end{alltt}They operate essentially the same as the unsigned copies except they prefix the data with zero or non--zerobyte depending on the sign.  If the sign is zpos (e.g. not negative) the prefix is zero, otherwise the prefixis non--zero.  \chapter{Algebraic Functions}\section{Extended Euclidean Algorithm}\index{mp\_exteuclid}\begin{alltt}int mp_exteuclid(mp_int *a, mp_int *b,                  mp_int *U1, mp_int *U2, mp_int *U3);\end{alltt}This finds the triple U1/U2/U3 using the Extended Euclidean algorithm such that the following equation holds.\begin{equation}a \cdot U1 + b \cdot U2 = U3\end{equation}Any of the U1/U2/U3 paramters can be set to \textbf{NULL} if they are not desired.  \section{Greatest Common Divisor}\index{mp\_gcd}\begin{alltt}int mp_gcd (mp_int * a, mp_int * b, mp_int * c)\end{alltt}This will compute the greatest common divisor of $a$ and $b$ and store it in $c$

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -