added most of the missing doumentation to doc/bn.tex
This commit is contained in:
		
							parent
							
								
									9ff526fa22
								
							
						
					
					
						commit
						9505280693
					
				
							
								
								
									
										303
									
								
								doc/bn.tex
									
									
									
									
									
								
							
							
						
						
									
										303
									
								
								doc/bn.tex
									
									
									
									
									
								
							| @ -1,3 +1,13 @@ | ||||
| \def\fixedpdfdate{D:20181209230255+01'00'} | ||||
| \pdfinfo{ | ||||
|   /CreationDate (\fixedpdfdate) | ||||
|   /ModDate (\fixedpdfdate) | ||||
| } | ||||
| \def\fixedpdfdate{D:20181209230255+01'00'} | ||||
| \pdfinfo{ | ||||
|   /CreationDate (\fixedpdfdate) | ||||
|   /ModDate (\fixedpdfdate) | ||||
| } | ||||
| \documentclass[synpaper]{book} | ||||
| \usepackage{hyperref} | ||||
| \usepackage{makeidx} | ||||
| @ -546,6 +556,25 @@ int main(void) | ||||
| \end{alltt} \end{small} | ||||
| 
 | ||||
| \section{Maintenance Functions} | ||||
| \subsection{Clear Leading Zeros} | ||||
| 
 | ||||
| This is used to ensure that leading zero digits are trimed and the leading "used" digit will be non-zero. | ||||
| It also fixes the sign if there are no more leading digits. | ||||
| 
 | ||||
| \index{mp\_clamp} | ||||
| \begin{alltt} | ||||
| void mp_clamp(mp_int *a); | ||||
| \end{alltt} | ||||
| 
 | ||||
| \subsection{Zero Out} | ||||
| 
 | ||||
| This function will set the ``bigint'' to zeros without changing the amount of allocated memory. | ||||
| 
 | ||||
| \index{mp\_zero} | ||||
| \begin{alltt} | ||||
| void mp_zero(mp_int *a); | ||||
| \end{alltt} | ||||
| 
 | ||||
| 
 | ||||
| \subsection{Reducing Memory Usage} | ||||
| When an mp\_int is in a state where it won't be changed again\footnote{A Diffie-Hellman modulus for instance.} excess | ||||
| @ -640,6 +669,39 @@ int main(void) | ||||
| \end{alltt} \end{small} | ||||
| 
 | ||||
| \chapter{Basic Operations} | ||||
| \section{Copying} | ||||
| 
 | ||||
| A so called ``deep copy'', where new memory is allocated and all contents of $a$ are copied verbatim into $b$ such that $b = a$ at the end. | ||||
| 
 | ||||
| \index{mp\_copy} | ||||
| \begin{alltt} | ||||
| int mp_copy (mp_int * a, mp_int *b); | ||||
| \end{alltt} | ||||
| 
 | ||||
| You can also just swap $a$ and $b$. It does the normal pointer changing with a temporary pointer variable, just that you do not have to. | ||||
| 
 | ||||
| \index{mp\_exch} | ||||
| \begin{alltt} | ||||
| void mp_exch (mp_int * a, mp_int *b); | ||||
| \end{alltt} | ||||
| 
 | ||||
| \section{Bit Counting} | ||||
| 
 | ||||
| To get the position of the lowest bit set (LSB, the Lowest Significant Bit; the number of bits which are zero before the first zero bit ) | ||||
| 
 | ||||
| \index{mp\_cnt\_lsb} | ||||
| \begin{alltt} | ||||
| int mp_cnt_lsb(const mp_int *a); | ||||
| \end{alltt} | ||||
| 
 | ||||
| To get the position of the highest bit set (MSB, the Most Significant Bit; the number of bits in teh ``bignum'') | ||||
| 
 | ||||
| \index{mp\_count\_bits} | ||||
| \begin{alltt} | ||||
| int mp_count_bits(const mp_int *a); | ||||
| \end{alltt} | ||||
| 
 | ||||
| 
 | ||||
| \section{Small Constants} | ||||
| Setting mp\_ints to small constants is a relatively common operation.  To accomodate these instances there are two | ||||
| small constant assignment functions.  The first function is used to set a single digit constant while the second sets | ||||
| @ -1103,6 +1165,21 @@ function simply copies $a$ over to ``c'' and zeroes $d$.  The variable $d$ may b | ||||
| value to signal that the remainder is not desired.  The division itself is implemented as a left-shift | ||||
| operation of $a$ by $b$ bits. | ||||
| 
 | ||||
| \index{mp\_tc\_div\_2d}\label{arithrightshift} | ||||
| \begin{alltt} | ||||
| int mp_tc_div_2d (mp_int * a, int b, mp_int * c, mp_int * d); | ||||
| \end{alltt} | ||||
| The two-co,mplement version of the function above. This can be used to implement arbitrary-precision two-complement integers together with the two-complement bit-wise operations at page \ref{tcbitwiseops}. | ||||
| 
 | ||||
| 
 | ||||
| It is also not very uncommon to need just the power of two $2^b$;  for example the startvalue for the Newton method. | ||||
| 
 | ||||
| \index{mp\_2expt} | ||||
| \begin{alltt} | ||||
| int mp_2expt(mp_int *a, int b); | ||||
| \end{alltt} | ||||
| It is faster than doing it by shifting $1$ with \texttt{mp_mul_2d}. | ||||
| 
 | ||||
| \subsection{Polynomial Basis Operations} | ||||
| 
 | ||||
| Strictly speaking the organization of the integers within the mp\_int structures is what is known as a | ||||
| @ -1128,19 +1205,32 @@ void mp_rshd (mp_int * a, int b) | ||||
| This will divide $a$ in place by $x^b$ and discard the remainder.  This function cannot fail as it performs the operations | ||||
| in place and no new digits are required to complete it. | ||||
| 
 | ||||
| \subsection{AND, OR and XOR Operations} | ||||
| \subsection{AND, OR, XOR and COMPLEMENT Operations} | ||||
| 
 | ||||
| While AND, OR and XOR operations are not typical ``bignum functions'' they can be useful in several instances.  The | ||||
| three functions are prototyped as follows. | ||||
| four functions are prototyped as follows. | ||||
| 
 | ||||
| \index{mp\_or} \index{mp\_and} \index{mp\_xor} | ||||
| \index{mp\_or} \index{mp\_and} \index{mp\_xor} \index {mp\_complement} | ||||
| \begin{alltt} | ||||
| int mp_or  (mp_int * a, mp_int * b, mp_int * c); | ||||
| int mp_and (mp_int * a, mp_int * b, mp_int * c); | ||||
| int mp_xor (mp_int * a, mp_int * b, mp_int * c); | ||||
| int mp_complement(const mp_int *a, mp_int *b); | ||||
| \end{alltt} | ||||
| 
 | ||||
| Which compute $c = a \odot b$ where $\odot$ is one of OR, AND or XOR. | ||||
| Which compute $c = a \odot b$ where $\odot$ is one of OR, AND or XOR and $ b = \sim a $. | ||||
| 
 | ||||
| There are also three functions that act as if the ``bignum'' would be a two-complement number. | ||||
| 
 | ||||
| \index{mp\_tc\_or} \index{mp\_tc\_and} \index{mp\_tc\_xor}\label{tcbitwiseops} | ||||
| \begin{alltt} | ||||
| int mp_tc_or  (mp_int * a, mp_int * b, mp_int * c); | ||||
| int mp_tc_and (mp_int * a, mp_int * b, mp_int * c); | ||||
| int mp_tc_xor (mp_int * a, mp_int * b, mp_int * c); | ||||
| \end{alltt} | ||||
| 
 | ||||
| The compute $c = a \odot b$ as above if both $a$ and $b$ are positive, negative values are converted into their two-complement representation first. This can be used to implement arbitrary-precision two-complement integers together with the arithmetic right-shift at page \ref{arithrightshift}. | ||||
| 
 | ||||
| 
 | ||||
| \section{Addition and Subtraction} | ||||
| 
 | ||||
| @ -1170,7 +1260,7 @@ Which assigns $-a$ to $b$. | ||||
| \subsection{Absolute} | ||||
| Simple integer absolutes can be performed with the following. | ||||
| 
 | ||||
| \index{mp\_neg} | ||||
| \index{mp\_abs} | ||||
| \begin{alltt} | ||||
| int mp_abs (mp_int * a, mp_int * b); | ||||
| \end{alltt} | ||||
| @ -1587,6 +1677,33 @@ int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d); | ||||
| 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. | ||||
| 
 | ||||
| \section{Combined Modular Reduction} | ||||
| 
 | ||||
| Some of the combinations of an arithmetic operations followed by a modular reduction can be done in a faster way. The ones implemented are: | ||||
| 
 | ||||
| Addition $d = (a + b) \mod c$  | ||||
| \index{mp\_addmod} | ||||
| \begin{alltt} | ||||
| int mp_addmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d); | ||||
| \end{alltt} | ||||
| 
 | ||||
| Subtraction  $d = (a - b) \mod c$  | ||||
| \begin{alltt} | ||||
| int mp_submod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d); | ||||
| \end{alltt} | ||||
| 
 | ||||
| Multiplication $d = (ab) \mod c$  | ||||
| \begin{alltt} | ||||
| int mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d); | ||||
| \end{alltt} | ||||
| 
 | ||||
| Squaring  $d = (a^2) \mod c$  | ||||
| \begin{alltt} | ||||
| int mp_sqrmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d); | ||||
| \end{alltt} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| \chapter{Exponentiation} | ||||
| \section{Single Digit Exponentiation} | ||||
| \index{mp\_expt\_d\_ex} | ||||
| @ -1628,6 +1745,13 @@ detect when Barrett, Montgomery, Restricted and Unrestricted Dimminished Radix b | ||||
| moduli of the a ``restricted dimminished radix'' form lead to the fastest modular exponentiations.  Followed by Montgomery | ||||
| and the other two algorithms. | ||||
| 
 | ||||
| \section{Modulus a Power of Two} | ||||
| \index{mp\_mod_2d} | ||||
| \begin{alltt} | ||||
| int mp_mod_2d(const mp_int *a, int b, mp_int *c) | ||||
| \end{alltt} | ||||
| It calculates $c = a \mod 2^b$. | ||||
| 
 | ||||
| \section{Root Finding} | ||||
| \index{mp\_n\_root} | ||||
| \begin{alltt} | ||||
| @ -1645,6 +1769,15 @@ values of $b$.  If particularly large roots are required then a factor method co | ||||
| $a^{1/16}$ is equivalent to $\left (a^{1/4} \right)^{1/4}$ or simply | ||||
| $\left ( \left ( \left ( a^{1/2} \right )^{1/2} \right )^{1/2} \right )^{1/2}$ | ||||
| 
 | ||||
| 
 | ||||
| The square root  $c = a^{1/2}$ (with the same conditions $c^2 \le a$ and $(c+1)^2 > a$) is implemented with a faster algorithm. | ||||
| 
 | ||||
| \index{mp\_sqrt} | ||||
| \begin{alltt} | ||||
| int mp_sqrt (mp_int * a, mp_digit b, mp_int * c) | ||||
| \end{alltt} | ||||
| 
 | ||||
| 
 | ||||
| \chapter{Prime Numbers} | ||||
| \section{Trial Division} | ||||
| \index{mp\_prime\_is\_divisible} | ||||
| @ -1693,6 +1826,13 @@ require 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} | ||||
| Testing if a number is a square can be done a bit faster than just by calculating the square root. It is used by the primality testing function described below. | ||||
| \index{mp\_is\_square} | ||||
| \begin{alltt} | ||||
| int mp_is_square(const mp_int *arg, int *ret); | ||||
| \end{alltt} | ||||
| 
 | ||||
| 
 | ||||
| \index{mp\_prime\_is\_prime} | ||||
| \begin{alltt} | ||||
| int mp_prime_is_prime (mp_int * a, int t, int *result) | ||||
| @ -1762,6 +1902,17 @@ mp\_prime\_random(). | ||||
| \label{fig:primeopts} | ||||
| \end{figure} | ||||
| 
 | ||||
| \chapter{Random Number Generation} | ||||
| \section{PRNG} | ||||
| \index{mp\_rand} | ||||
| \begin{alltt} | ||||
| int mp_rand(mp_int *a, int digits) | ||||
| \end{alltt} | ||||
| The function generates a random number of \texttt{digits} bits. | ||||
| 
 | ||||
| This random number is cryptographically secure if the source of random numbers the operating systems offers is cryptographically secure. It will use \texttt{arc4random()} if the OS is a BSD flavor, Wincrypt on Windows, and \texttt{\dev\urandom} on all operating systems that have it. | ||||
| 
 | ||||
| 
 | ||||
| \chapter{Input and Output} | ||||
| \section{ASCII Conversions} | ||||
| \subsection{To ASCII} | ||||
| @ -1773,6 +1924,13 @@ This still store $a$ in ``str'' as a base-``radix'' string of ASCII chars.  This | ||||
| to terminate the string.  Valid values of ``radix'' line in the range $[2, 64]$.  To determine the size (exact) required | ||||
| by the conversion before storing any data use the following function. | ||||
| 
 | ||||
| \index{mp\_toradix\_n} | ||||
| \begin{alltt} | ||||
| int mp_toradix_n (mp_int * a, char *str, int radix, int maxlen); | ||||
| \end{alltt} | ||||
| 
 | ||||
| Like \texttt{mp\_toradix} but stores upto maxlen-1 chars and always a NULL byte. | ||||
| 
 | ||||
| \index{mp\_radix\_size} | ||||
| \begin{alltt} | ||||
| int mp_radix_size (mp_int * a, int radix, int *size) | ||||
| @ -1780,6 +1938,13 @@ int mp_radix_size (mp_int * a, int radix, int *size) | ||||
| 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. | ||||
| 
 | ||||
| If \texttt{LTM\_NO\_FILE} is not defined a function to write to a file is also available. | ||||
| \index{mp\_fwrite} | ||||
| \begin{alltt} | ||||
| int mp_fwrite(const mp_int *a, int radix, FILE *stream); | ||||
| \end{alltt} | ||||
| 
 | ||||
| 
 | ||||
| \subsection{From ASCII} | ||||
| \index{mp\_read\_radix} | ||||
| \begin{alltt} | ||||
| @ -1789,6 +1954,13 @@ This will read the base-``radix'' NUL terminated string from ``str'' into $a$. | ||||
| character it does not recognize (which happens to include th NUL char... imagine that...).  A single leading $-$ sign | ||||
| can be used to denote a negative number. | ||||
| 
 | ||||
| If \texttt{LTM\_NO\_FILE} is not defined a function to read from a file is also available. | ||||
| \index{mp\_fread} | ||||
| \begin{alltt} | ||||
| int mp_fread(mp_int *a, int radix, FILE *stream); | ||||
| \end{alltt} | ||||
| 
 | ||||
| 
 | ||||
| \section{Binary Conversions} | ||||
| 
 | ||||
| Converting an mp\_int to and from binary is another keen idea. | ||||
| @ -1807,6 +1979,13 @@ int mp_to_unsigned_bin(mp_int *a, unsigned char *b); | ||||
| 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\_to\_unsigned\_bin\_n} | ||||
| \begin{alltt} | ||||
| int mp_to_unsigned_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen) | ||||
| \end{alltt} | ||||
| Like \texttt{mp\_to\_unsigned\_bin} but checks if the value at \texttt{*outlen} is larger than or equal to the output of \texttt{mp\_unsigned\_bin\_size(a)} and sets \texttt{*outlen} to the output of \texttt{mp\_unsigned\_bin\_size(a)} or returns \texttt{MP\_VAL} if the test failed. | ||||
| 
 | ||||
| 
 | ||||
| \index{mp\_read\_unsigned\_bin} | ||||
| \begin{alltt} | ||||
| int mp_read_unsigned_bin(mp_int *a, unsigned char *b, int c); | ||||
| @ -1816,7 +1995,7 @@ integer $a$ will always be positive. | ||||
| 
 | ||||
| For those who acknowledge the existence of negative numbers (heretic!) there are ``signed'' versions of the | ||||
| previous functions. | ||||
| 
 | ||||
| \index{mp\_signed\_bin\_size} \index{mp\_to\_signed\_bin} \index{mp\_read\_signed\_bin} | ||||
| \begin{alltt} | ||||
| int mp_signed_bin_size(mp_int *a); | ||||
| int mp_read_signed_bin(mp_int *a, unsigned char *b, int c); | ||||
| @ -1826,6 +2005,13 @@ They operate essentially the same as the unsigned copies except they prefix the | ||||
| byte depending on the sign.  If the sign is zpos (e.g. not negative) the prefix is zero, otherwise the prefix | ||||
| is non--zero. | ||||
| 
 | ||||
| The two functions \texttt{mp\_import} and \texttt{mp\_export} implement the corresponding GMP functions as described at \url{http://gmplib.org/manual/Integer-Import-and-Export.html}. | ||||
| \index{mp\_import} \index{mp\_export} | ||||
| \begin{alltt} | ||||
| int mp_import(mp_int *rop, size_t count, int order, size_t size, int endian, size_t nails, const void *op); | ||||
| int mp_export(void *rop, size_t *countp, int order, size_t size, int endian, size_t nails, const mp_int *op); | ||||
| \end{alltt} | ||||
| 
 | ||||
| \chapter{Algebraic Functions} | ||||
| \section{Extended Euclidean Algorithm} | ||||
| \index{mp\_exteuclid} | ||||
| @ -1911,6 +2097,111 @@ These work like the full mp\_int capable variants except the second parameter $b | ||||
| functions fairly handy if you have to work with relatively small numbers since you will not have to allocate | ||||
| an entire mp\_int to store a number like $1$ or $2$. | ||||
| 
 | ||||
| The division by three can be made faster by replacing the division with a multiplication by the multiplicative inverse of three. | ||||
| 
 | ||||
| \index{mp\_div\_3} | ||||
| \begin{alltt} | ||||
| int mp_div_3(const mp_int *a, mp_int *c, mp_digit *d); | ||||
| \end{alltt} | ||||
| 
 | ||||
| \chapter{Little Helpers} | ||||
| It is never wrong to have some useful little shortcuts at hand. | ||||
| \section{Function Macros} | ||||
| To make this overview simpler the macros are given as function prototypes. The return of logic macros is \texttt{MP\_NO} or \texttt{MP\_YES} respectively. | ||||
| 
 | ||||
| \index{mp\_iseven} | ||||
| \begin{alltt} | ||||
| int mp_iseven(mp_int *a) | ||||
| \end{alltt} | ||||
| Checks if $a = 0 mod 2$ | ||||
| 
 | ||||
| \index{mp\_isodd} | ||||
| \begin{alltt} | ||||
| int mp_isodd(mp_int *a) | ||||
| \end{alltt} | ||||
| Checks if $a = 1 mod 2$ | ||||
| 
 | ||||
| \index{mp\_isneg} | ||||
| \begin{alltt} | ||||
| int mp_isneg(mp_int *a) | ||||
| \end{alltt} | ||||
| Checks if $a < 0$ | ||||
| 
 | ||||
| 
 | ||||
| \index{mp\_iszero} | ||||
| \begin{alltt} | ||||
| int mp_iszero(mp_int *a) | ||||
| \end{alltt} | ||||
| Checks if $a = 0$. It does not check if the amount of memory allocated for $a$ is also minimal. | ||||
| 
 | ||||
| 
 | ||||
| Other macros which are either shortcuts to normal functions or just other names for them do have their place in a programmer's life, too! | ||||
| 
 | ||||
| \subsection{Renamings} | ||||
| \index{mp\_mag\_size} | ||||
| \begin{alltt} | ||||
| #define mp_mag_size(mp) mp_unsigned_bin_size(mp) | ||||
| \end{alltt} | ||||
| 
 | ||||
| 
 | ||||
| \index{mp\_raw\_size} | ||||
| \begin{alltt} | ||||
| #define mp_raw_size(mp) mp_signed_bin_size(mp) | ||||
| \end{alltt} | ||||
| 
 | ||||
| 
 | ||||
| \index{mp\_read\_mag} | ||||
| \begin{alltt} | ||||
| #define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len)) | ||||
| \end{alltt} | ||||
| 
 | ||||
| 
 | ||||
| \index{mp\_read\_raw} | ||||
| \begin{alltt} | ||||
|  #define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len)) | ||||
| \end{alltt} | ||||
| 
 | ||||
| 
 | ||||
| \index{mp\_tomag} | ||||
| \begin{alltt} | ||||
| #define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str)) | ||||
| \end{alltt} | ||||
| 
 | ||||
| 
 | ||||
| \index{mp\_toraw} | ||||
| \begin{alltt} | ||||
| #define mp_toraw(mp, str)         mp_to_signed_bin((mp), (str)) | ||||
| \end{alltt} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| \subsection{Shortcuts} | ||||
| 
 | ||||
| \index{mp\_tobinary} | ||||
| \begin{alltt} | ||||
| #define mp_tobinary(M, S) mp_toradix((M), (S), 2) | ||||
| \end{alltt} | ||||
| 
 | ||||
| 
 | ||||
| \index{mp\_tooctal} | ||||
| \begin{alltt} | ||||
| #define mp_tooctal(M, S) mp_toradix((M), (S), 8) | ||||
| \end{alltt} | ||||
| 
 | ||||
| 
 | ||||
| \index{mp\_todecimal} | ||||
| \begin{alltt} | ||||
| #define mp_todecimal(M, S) mp_toradix((M), (S), 10) | ||||
| \end{alltt} | ||||
| 
 | ||||
| 
 | ||||
| \index{mp\_tohex} | ||||
| \begin{alltt} | ||||
| #define mp_tohex(M, S)     mp_toradix((M), (S), 16) | ||||
| \end{alltt} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| \input{bn.ind} | ||||
| 
 | ||||
| \end{document} | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user