2003-12-24 18:59:22 +00:00
|
|
|
\documentclass[b5paper]{book}
|
|
|
|
\usepackage{hyperref}
|
|
|
|
\usepackage{makeidx}
|
|
|
|
\usepackage{amssymb}
|
|
|
|
\usepackage{color}
|
|
|
|
\usepackage{alltt}
|
|
|
|
\usepackage{graphicx}
|
|
|
|
\usepackage{layout}
|
|
|
|
\def\union{\cup}
|
|
|
|
\def\intersect{\cap}
|
|
|
|
\def\getsrandom{\stackrel{\rm R}{\gets}}
|
|
|
|
\def\cross{\times}
|
|
|
|
\def\cat{\hspace{0.5em} \| \hspace{0.5em}}
|
|
|
|
\def\catn{$\|$}
|
|
|
|
\def\divides{\hspace{0.3em} | \hspace{0.3em}}
|
|
|
|
\def\nequiv{\not\equiv}
|
|
|
|
\def\approx{\raisebox{0.2ex}{\mbox{\small $\sim$}}}
|
|
|
|
\def\lcm{{\rm lcm}}
|
|
|
|
\def\gcd{{\rm gcd}}
|
|
|
|
\def\log{{\rm log}}
|
|
|
|
\def\ord{{\rm ord}}
|
|
|
|
\def\abs{{\mathit abs}}
|
|
|
|
\def\rep{{\mathit rep}}
|
|
|
|
\def\mod{{\mathit\ mod\ }}
|
|
|
|
\renewcommand{\pmod}[1]{\ ({\rm mod\ }{#1})}
|
|
|
|
\newcommand{\floor}[1]{\left\lfloor{#1}\right\rfloor}
|
|
|
|
\newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil}
|
|
|
|
\def\Or{{\rm\ or\ }}
|
|
|
|
\def\And{{\rm\ and\ }}
|
|
|
|
\def\iff{\hspace{1em}\Longleftrightarrow\hspace{1em}}
|
|
|
|
\def\implies{\Rightarrow}
|
|
|
|
\def\undefined{{\rm ``undefined"}}
|
|
|
|
\def\Proof{\vspace{1ex}\noindent {\bf Proof:}\hspace{1em}}
|
|
|
|
\let\oldphi\phi
|
|
|
|
\def\phi{\varphi}
|
|
|
|
\def\Pr{{\rm Pr}}
|
|
|
|
\newcommand{\str}[1]{{\mathbf{#1}}}
|
|
|
|
\def\F{{\mathbb F}}
|
|
|
|
\def\N{{\mathbb N}}
|
|
|
|
\def\Z{{\mathbb Z}}
|
|
|
|
\def\R{{\mathbb R}}
|
|
|
|
\def\C{{\mathbb C}}
|
|
|
|
\def\Q{{\mathbb Q}}
|
|
|
|
\definecolor{DGray}{gray}{0.5}
|
|
|
|
\newcommand{\emailaddr}[1]{\mbox{$<${#1}$>$}}
|
|
|
|
\def\twiddle{\raisebox{0.3ex}{\mbox{\tiny $\sim$}}}
|
|
|
|
\def\gap{\vspace{0.5ex}}
|
|
|
|
\makeindex
|
2003-02-28 16:07:58 +00:00
|
|
|
\begin{document}
|
2003-12-24 18:59:22 +00:00
|
|
|
\frontmatter
|
|
|
|
\pagestyle{empty}
|
|
|
|
\title{LibTomMath User Manual \\ v0.28}
|
2003-02-28 16:07:58 +00:00
|
|
|
\author{Tom St Denis \\ tomstdenis@iahu.ca}
|
|
|
|
\maketitle
|
2003-12-24 18:59:22 +00:00
|
|
|
This text, the library and the accompanying textbook are all hereby placed in the public domain. This book has been
|
|
|
|
formatted for B5 [176x250] paper using the \LaTeX{} {\em book} macro package.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\vspace{10cm}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\begin{flushright}Open Source. Open Academia. Open Minds.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\mbox{ }
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
Tom St Denis,
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
Ontario, Canada
|
|
|
|
\end{flushright}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\tableofcontents
|
|
|
|
\listoffigures
|
|
|
|
\mainmatter
|
|
|
|
\pagestyle{headings}
|
|
|
|
\chapter{Introduction}
|
|
|
|
\section{What is LibTomMath?}
|
|
|
|
LibTomMath is a library of source code which provides a series of efficient and carefully written functions for manipulating
|
|
|
|
large integer numbers. It was written in portable ISO C source code so that it will build on any platform with a conforming
|
|
|
|
C compiler.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
In a nutshell the library was written from scratch with verbose comments to help instruct computer science students how
|
|
|
|
to implement ``bignum'' math. However, the resulting code has proven to be very useful. It has been used by numerous
|
|
|
|
universities, commercial and open source software developers. It has been used on a variety of platforms ranging from
|
|
|
|
Linux and Windows based x86 to ARM based Gameboys and PPC based MacOS machines.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\section{License}
|
|
|
|
As of the v0.25 the library source code has been placed in the public domain with every new release. As of the v0.28
|
|
|
|
release the textbook ``Implementing Multiple Precision Arithmetic'' has been placed in the public domain with every new
|
|
|
|
release as well. This textbook is meant to compliment the project by providing a more solid walkthrough of the development
|
|
|
|
algorithms used in the library.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
Since both\footnote{Note that the MPI files under mtest/ are copyrighted by Michael Fromberger.} are in the
|
|
|
|
public domain everyone is entitled to do with them as they see fit.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\section{Building LibTomMath}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
LibTomMath is meant to be very ``GCC friendly'' as it comes with a makefile well suited for GCC. However, the library will
|
|
|
|
also build in MSVC, Borland C out of the box. For any other ISO C compiler a makefile will have to be made by the end
|
|
|
|
developer.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
To build the library for GCC simply issue the
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\begin{alltt}
|
|
|
|
make
|
|
|
|
\end{alltt}
|
2003-02-28 16:08:34 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
command. This will build the library and archive the object files in ``libtommath.a''. Now you simply link against that
|
|
|
|
and include ``tommath.h'' within your programs.
|
2003-02-28 16:08:34 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
Alternatively to build with MSVC type
|
2003-02-28 16:08:34 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\begin{alltt}
|
|
|
|
nmake -f makefile.msvc
|
|
|
|
\end{alltt}
|
2003-02-28 16:08:34 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
This will build the library and archive the object files in ``tommath.lib''. This has been tested with MSVC version 6.00
|
|
|
|
with service pack 5.
|
2003-02-28 16:08:34 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
Tbere is limited support for making a ``DLL'' in windows via the ``makefile.cygwin\_dll'' makefile. It requires Cygwin
|
|
|
|
to work with since it requires the auto-export/import functionality. The resulting DLL and imprt library ``libtomcrypt.dll.a''
|
|
|
|
can be used to link LibTomMath dynamically to any Windows program using Cygwin.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\subsection{Testing}
|
|
|
|
To build the library and the test harness type
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\begin{alltt}
|
|
|
|
make test
|
|
|
|
\end{alltt}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
This will build the library, ``test'' and ``mtest/mtest''. The ``test'' program will accept test vectors and verify the
|
|
|
|
results. ``mtest/mtest'' will generate test vectors using the MPI library by Michael Fromberger\footnote{A copy of MPI
|
|
|
|
is included in the package}. Simply pipe mtest into test using
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\begin{alltt}
|
|
|
|
mtest/mtest | test
|
|
|
|
\end{alltt}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
If you do not have a ``/dev/urandom'' style RNG source you will have to write your own PRNG and simply pipe that into
|
|
|
|
mtest. For example, if your PRNG program is called ``myprng'' simply invoke
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\begin{alltt}
|
|
|
|
myprng | mtest/mtest | test
|
|
|
|
\end{alltt}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
This will output a row of numbers that are increasing. Each column is a different test (such as addition, multiplication, etc)
|
|
|
|
that is being performed. The numbers represent how many times the test was invoked. If an error is detected the program
|
|
|
|
will exit with a dump of the relevent numbers it was working with.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\section{Purpose of LibTomMath}
|
|
|
|
Unlike GNU MP (GMP) Library, LIP, OpenSSL or various other commercial kits (Miracl), LibTomMath was not written with
|
|
|
|
bleeding edge performance in mind. First and foremost LibTomMath was written to be entirely open. Not only is the
|
|
|
|
source code public domain (unlike various other GPL/etc licensed code), not only is the code freely downloadable but the
|
|
|
|
source code is also accessible for computer science students attempting to learn ``BigNum'' or multiple precision
|
|
|
|
arithmetic techniques.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
LibTomMath was written to be an instructive collection of source code. This is why there are many comments, only one
|
|
|
|
function per source file and often I use a ``middle-road'' approach where I don't cut corners for an extra 2\% speed
|
|
|
|
increase.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
Source code alone cannot really teach how the algorithms work which is why I also wrote a textbook that accompanies
|
|
|
|
the library (beat that!).
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
So you may be thinking ``should I use LibTomMath?'' and the answer is a definite maybe. Let me tabulate what I think
|
|
|
|
are the pros and cons of LibTomMath by comparing it to the math routines from GnuPG\footnote{GnuPG v1.2.3 versus LibTomMath v0.28}.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\newpage\begin{figure}[here]
|
|
|
|
\begin{small}
|
|
|
|
\begin{center}
|
|
|
|
\begin{tabular}{|l|c|c|l|}
|
|
|
|
\hline \textbf{Criteria} & \textbf{Pro} & \textbf{Con} & \textbf{Notes} \\
|
|
|
|
\hline Few lines of code per file & X & & GnuPG $ = 300.9$, LibTomMath $ = 76.04$ \\
|
|
|
|
\hline Commented function prototypes & X && GnuPG function names are cryptic. \\
|
|
|
|
\hline Speed && X & LibTomMath is slower. \\
|
|
|
|
\hline Totally free & X & & GPL has unfavourable restrictions.\\
|
|
|
|
\hline Large function base & X & & GnuPG is barebones. \\
|
|
|
|
\hline Four modular reduction algorithms & X & & Faster modular exponentiation. \\
|
|
|
|
\hline Portable & X & & GnuPG requires configuration to build. \\
|
|
|
|
\hline
|
|
|
|
\end{tabular}
|
|
|
|
\end{center}
|
|
|
|
\end{small}
|
|
|
|
\caption{LibTomMath Valuation}
|
|
|
|
\end{figure}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
It may seem odd to compare LibTomMath to GnuPG since the math in GnuPG is only a small portion of the entire application.
|
|
|
|
However, LibTomMath was written with cryptography in mind. It provides essentially all of the functions a cryptosystem
|
|
|
|
would require when working with large integers.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
So it may feel tempting to just rip the math code out of GnuPG (or GnuMP where it was taken from originally) in your
|
|
|
|
own application but I think there are reasons not to. While LibTomMath is slower than libraries such as GnuMP it is
|
|
|
|
not normally significantly slower. On x86 machines the difference is normally a factor of two when performing modular
|
|
|
|
exponentiations.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
Essentially the only time you wouldn't use LibTomMath is when blazing speed is the primary concern.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\chapter{Getting Started with LibTomMath}
|
|
|
|
\section{Building Programs}
|
|
|
|
In order to use LibTomMath you must include ``tommath.h'' and link against the appropriate library file (typically
|
|
|
|
libtommath.a). There is no library initialization required and the entire library is thread safe.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\section{Return Codes}
|
|
|
|
There are three possible return codes a function may return.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\index{MP\_OKAY}\index{MP\_YES}\index{MP\_NO}\index{MP\_VAL}\index{MP\_MEM}
|
|
|
|
\begin{figure}[here!]
|
|
|
|
\begin{center}
|
|
|
|
\begin{small}
|
|
|
|
\begin{tabular}{|l|l|}
|
|
|
|
\hline \textbf{Code} & \textbf{Meaning} \\
|
|
|
|
\hline MP\_OKAY & The function succeeded. \\
|
|
|
|
\hline MP\_VAL & The function input was invalid. \\
|
|
|
|
\hline MP\_MEM & Heap memory exhausted. \\
|
|
|
|
\hline &\\
|
|
|
|
\hline MP\_YES & Response is yes. \\
|
|
|
|
\hline MP\_NO & Response is no. \\
|
|
|
|
\hline
|
|
|
|
\end{tabular}
|
|
|
|
\end{small}
|
|
|
|
\end{center}
|
|
|
|
\caption{Return Codes}
|
|
|
|
\end{figure}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
The last two codes listed are not actually ``return'ed'' by a function. They are placed in an integer (the caller must
|
|
|
|
provide the address of an integer it can store to) which the caller can access. To convert one of the three return codes
|
|
|
|
to a string use the following function.
|
2003-03-29 18:16:01 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\index{mp\_error\_to\_string}
|
|
|
|
\begin{alltt}
|
|
|
|
char *mp_error_to_string(int code);
|
|
|
|
\end{alltt}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
This will return a pointer to a string which describes the given error code. It will not work for the return codes
|
|
|
|
MP\_YES and MP\_NO.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\section{Data Types}
|
|
|
|
The basic ``multiple precision integer'' type is known as the ``mp\_int'' within LibTomMath. This data type is used to
|
|
|
|
organize all of the data required to manipulate the integer it represents. Within LibTomMath it has been prototyped
|
|
|
|
as the following.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\index{mp\_int}
|
|
|
|
\begin{alltt}
|
|
|
|
typedef struct \{
|
|
|
|
int used, alloc, sign;
|
|
|
|
mp_digit *dp;
|
|
|
|
\} mp_int;
|
|
|
|
\end{alltt}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
Where ``mp\_digit'' is a data type that represents individual digits of the integer. By default, an mp\_digit is the
|
|
|
|
ISO C ``unsigned long'' data type and each digit is $28-$bits long. The mp\_digit type can be configured to suit other
|
|
|
|
platforms by defining the appropriate macros.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
All LTM functions that use the mp\_int type will expect a pointer to mp\_int structure. You must allocate memory to
|
|
|
|
hold the structure itself by yourself (whether off stack or heap it doesn't matter). The very first thing that must be
|
|
|
|
done to use an mp\_int is that it must be initialized.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\section{Function Organization}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
The arithmetic functions of the library are all organized to have the same style prototype. That is source operands
|
|
|
|
are passed on the left and the destination is on the right. For instance,
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\begin{alltt}
|
|
|
|
mp_add(&a, &b, &c); /* c = a + b */
|
|
|
|
mp_mul(&a, &a, &c); /* c = a * a */
|
|
|
|
mp_div(&a, &b, &c, &d); /* c = [a/b], d = a mod b */
|
|
|
|
\end{alltt}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
Another feature of the way the functions have been implemented is that source operands can be destination operands as well.
|
|
|
|
For instance,
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\begin{alltt}
|
|
|
|
mp_add(&a, &b, &b); /* b = a + b */
|
|
|
|
mp_div(&a, &b, &a, &c); /* a = [a/b], c = a mod b */
|
|
|
|
\end{alltt}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
This allows operands to be re-used which can make programming simpler.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\section{Initialization}
|
|
|
|
\subsection{Single Initialization}
|
|
|
|
A single mp\_int can be initialized with the ``mp\_init'' function.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\index{mp\_init}
|
|
|
|
\begin{alltt}
|
|
|
|
int mp_init (mp_int * a);
|
|
|
|
\end{alltt}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
This function expects a pointer to an mp\_int structure and will initialize the members of the structure so the mp\_int
|
|
|
|
represents the default integer which is zero. If the functions returns MP\_OKAY then the mp\_int is ready to be used
|
|
|
|
by the other LibTomMath functions.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\begin{small} \begin{alltt}
|
|
|
|
int main(void)
|
|
|
|
\{
|
|
|
|
mp_int number;
|
|
|
|
int result;
|
|
|
|
|
|
|
|
if ((result = mp_init(&number)) != MP_OKAY) \{
|
|
|
|
printf("Error initializing the number. \%s",
|
|
|
|
mp_error_to_string(result));
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
\}
|
|
|
|
|
|
|
|
/* use the number */
|
|
|
|
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
\}
|
|
|
|
\end{alltt} \end{small}
|
|
|
|
|
|
|
|
\subsection{Single Free}
|
|
|
|
When you are finished with an mp\_int it is ideal to return the heap it used back to the system. The following function
|
|
|
|
provides this functionality.
|
|
|
|
|
|
|
|
\index{mp\_clear}
|
|
|
|
\begin{alltt}
|
|
|
|
void mp_clear (mp_int * a);
|
|
|
|
\end{alltt}
|
|
|
|
|
|
|
|
The function expects a pointer to a previously initialized mp\_int structure and frees the heap it uses. It sets the
|
|
|
|
pointer\footnote{The ``dp'' member.} within the mp\_int to \textbf{NULL} which is used to prevent double free situations.
|
|
|
|
Is is legal to call mp\_clear() twice on the same mp\_int in a row.
|
|
|
|
|
|
|
|
\begin{small} \begin{alltt}
|
|
|
|
int main(void)
|
|
|
|
\{
|
|
|
|
mp_int number;
|
|
|
|
int result;
|
|
|
|
|
|
|
|
if ((result = mp_init(&number)) != MP_OKAY) \{
|
|
|
|
printf("Error initializing the number. \%s",
|
|
|
|
mp_error_to_string(result));
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
\}
|
|
|
|
|
|
|
|
/* use the number */
|
|
|
|
|
|
|
|
/* We're done with it. */
|
|
|
|
mp_clear(&number);
|
|
|
|
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
\}
|
|
|
|
\end{alltt} \end{small}
|
|
|
|
|
|
|
|
\subsection{Multiple Initializations}
|
|
|
|
Certain algorithms require more than one large integer. In these instances it is ideal to initialize all of the mp\_int
|
|
|
|
variables in an ``all or nothing'' fashion. That is, they are either all initialized successfully or they are all
|
|
|
|
not initialized.
|
|
|
|
|
|
|
|
The mp\_init\_multi() function provides this functionality.
|
|
|
|
|
|
|
|
\index{mp\_init\_multi} \index{mp\_clear\_multi}
|
|
|
|
\begin{alltt}
|
|
|
|
int mp_init_multi(mp_int *mp, ...);
|
|
|
|
\end{alltt}
|
|
|
|
|
|
|
|
It accepts a \textbf{NULL} terminated list of pointers to mp\_int structures. It will attempt to initialize them all
|
|
|
|
at once. If the function returns MP\_OKAY then all of the mp\_int variables are ready to use, otherwise none of them
|
|
|
|
are available for use. A complementary mp\_clear\_multi() function allows multiple mp\_int variables to be free'd
|
|
|
|
from the heap at the same time.
|
|
|
|
|
|
|
|
\begin{small} \begin{alltt}
|
|
|
|
int main(void)
|
|
|
|
\{
|
|
|
|
mp_int num1, num2, num3;
|
|
|
|
int result;
|
|
|
|
|
|
|
|
if ((result = mp_init_multi(&num1,
|
|
|
|
&num2,
|
|
|
|
&num3, NULL)) != MP\_OKAY) \{
|
|
|
|
printf("Error initializing the numbers. \%s",
|
|
|
|
mp_error_to_string(result));
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
\}
|
|
|
|
|
|
|
|
/* use the numbers */
|
|
|
|
|
|
|
|
/* We're done with them. */
|
|
|
|
mp_clear_multi(&num1, &num2, &num3, NULL);
|
|
|
|
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
\}
|
|
|
|
\end{alltt} \end{small}
|
|
|
|
|
|
|
|
\subsection{Other Initializers}
|
|
|
|
To initialized and make a copy of an mp\_int the mp\_init\_copy() function has been provided.
|
|
|
|
|
|
|
|
\index{mp\_init\_copy}
|
|
|
|
\begin{alltt}
|
|
|
|
int mp_init_copy (mp_int * a, mp_int * b);
|
|
|
|
\end{alltt}
|
|
|
|
|
|
|
|
This function will initialize ``a'' and make it a copy of ``b'' if all goes well.
|
|
|
|
|
|
|
|
\begin{small} \begin{alltt}
|
|
|
|
int main(void)
|
|
|
|
\{
|
|
|
|
mp_int num1, num2;
|
|
|
|
int result;
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
/* initialize and do work on num1 ... */
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
/* We want a copy of num1 in num2 now */
|
|
|
|
if ((result = mp_init_copy(&num2, &num1)) != MP_OKAY) \{
|
|
|
|
printf("Error initializing the copy. \%s",
|
|
|
|
mp_error_to_string(result));
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
\}
|
|
|
|
|
|
|
|
/* now num2 is ready and contains a copy of num1 */
|
2003-03-22 15:10:20 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
/* We're done with them. */
|
|
|
|
mp_clear_multi(&num1, &num2, NULL);
|
2003-03-22 15:10:20 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
return EXIT_SUCCESS;
|
|
|
|
\}
|
|
|
|
\end{alltt} \end{small}
|
2003-03-22 15:10:20 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
Another less common initializer is mp\_init\_size() which allows the user to initialize an mp\_int with a given
|
|
|
|
default number of digits. By default, all initializers allocate \textbf{MP\_PREC} digits. This function lets
|
|
|
|
you override this behaviour.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\index{mp\_init\_size}
|
|
|
|
\begin{alltt}
|
|
|
|
int mp_init_size (mp_int * a, int size);
|
|
|
|
\end{alltt}
|
2003-03-22 15:10:20 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
The ``size'' parameter must be greater than zero. If the function succeeds the mp\_int ``a'' will be initialized
|
|
|
|
to have ``size'' digits (which are all initially zero).
|
2003-03-22 15:10:20 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\begin{small} \begin{alltt}
|
|
|
|
int main(void)
|
|
|
|
\{
|
|
|
|
mp_int number;
|
|
|
|
int result;
|
|
|
|
|
|
|
|
/* we need a 60-digit number */
|
|
|
|
if ((result = mp_init_size(&number, 60)) != MP_OKAY) \{
|
|
|
|
printf("Error initializing the number. \%s",
|
|
|
|
mp_error_to_string(result));
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
\}
|
|
|
|
|
|
|
|
/* use the number */
|
|
|
|
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
\}
|
|
|
|
\end{alltt} \end{small}
|
|
|
|
|
|
|
|
\section{Maintenance Functions}
|
|
|
|
|
|
|
|
\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
|
|
|
|
digits can be removed to return memory to the heap with the mp\_shrink() function.
|
|
|
|
|
|
|
|
\index{mp\_shrink}
|
|
|
|
\begin{alltt}
|
|
|
|
int mp_shrink (mp_int * a);
|
|
|
|
\end{alltt}
|
|
|
|
|
|
|
|
This will remove excess digits of the mp\_int ``a''. If the operation fails the mp\_int should be intact without the
|
|
|
|
excess digits being removed. Note that you can use a shrunk mp\_int in further computations, however, such operations
|
|
|
|
will require heap operations which can be slow. It is not ideal to shrink mp\_int variables that you will further
|
|
|
|
modify in the system (unless you are seriously low on memory).
|
|
|
|
|
|
|
|
\begin{small} \begin{alltt}
|
|
|
|
int main(void)
|
|
|
|
\{
|
|
|
|
mp_int number;
|
|
|
|
int result;
|
2003-03-22 15:10:20 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
if ((result = mp_init(&number)) != MP_OKAY) \{
|
|
|
|
printf("Error initializing the number. \%s",
|
|
|
|
mp_error_to_string(result));
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
\}
|
|
|
|
|
|
|
|
/* use the number [e.g. pre-computation] */
|
2003-03-22 15:10:20 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
/* We're done with it for now. */
|
|
|
|
if ((result = mp_shrink(&number)) != MP_OKAY) \{
|
|
|
|
printf("Error shrinking the number. \%s",
|
|
|
|
mp_error_to_string(result));
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
\}
|
2003-03-22 15:10:20 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
/* use it .... */
|
2003-03-22 15:10:20 +00:00
|
|
|
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
/* we're done with it. */
|
|
|
|
mp_clear(&number);
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
return EXIT_SUCCESS;
|
|
|
|
\}
|
|
|
|
\end{alltt} \end{small}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\subsection{Adding additional digits}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
Within the mp\_int structure are two parameters which control the limitations of the array of digits that represent
|
|
|
|
the integer the mp\_int is meant to equal. The \textit{used} parameter dictates how many digits are significant, that is,
|
|
|
|
contribute to the value of the mp\_int. The \textit{alloc} parameter dictates how many digits are currently available in
|
|
|
|
the array. If you need to perform an operation that requires more digits you will have to mp\_grow() the mp\_int to
|
|
|
|
your desired size.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\index{mp\_grow}
|
|
|
|
\begin{alltt}
|
|
|
|
int mp_grow (mp_int * a, int size);
|
|
|
|
\end{alltt}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
This will grow the array of digits of ``a'' to ``size''. If the \textit{alloc} parameter is already bigger than
|
|
|
|
``size'' the function will not do anything.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\begin{small} \begin{alltt}
|
|
|
|
int main(void)
|
|
|
|
\{
|
|
|
|
mp_int number;
|
|
|
|
int result;
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
if ((result = mp_init(&number)) != MP_OKAY) \{
|
|
|
|
printf("Error initializing the number. \%s",
|
|
|
|
mp_error_to_string(result));
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
\}
|
|
|
|
|
|
|
|
/* use the number */
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
/* We need to add 20 digits to the number */
|
|
|
|
if ((result = mp_grow(&number, number.alloc + 20)) != MP_OKAY) \{
|
|
|
|
printf("Error growing the number. \%s",
|
|
|
|
mp_error_to_string(result));
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
\}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
/* use the number */
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
/* we're done with it. */
|
|
|
|
mp_clear(&number);
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
return EXIT_SUCCESS;
|
|
|
|
\}
|
|
|
|
\end{alltt} \end{small}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\chapter{Basic Operations}
|
|
|
|
\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
|
|
|
|
an ISO C style ``unsigned long'' constant. The reason for both functions is efficiency. Setting a single digit is quick but the
|
|
|
|
domain of a digit can change (it's always at least $0 \ldots 127$).
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\subsection{Single Digit}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
Setting a single digit can be accomplished with the following function.
|
2003-03-13 02:11:11 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\index{mp\_set}
|
|
|
|
\begin{alltt}
|
|
|
|
void mp_set (mp_int * a, mp_digit b);
|
|
|
|
\end{alltt}
|
2003-03-13 02:11:11 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
This will zero the contents of ``a'' and make it represent an integer equal to the value of ``b''. Note that this
|
|
|
|
function has a return type of \textbf{void}. It cannot cause an error so it is safe to assume the function
|
|
|
|
succeeded.
|
2003-03-13 02:11:11 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\begin{small} \begin{alltt}
|
|
|
|
int main(void)
|
|
|
|
\{
|
|
|
|
mp_int number;
|
|
|
|
int result;
|
2003-03-13 02:11:11 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
if ((result = mp_init(&number)) != MP_OKAY) \{
|
|
|
|
printf("Error initializing the number. \%s",
|
|
|
|
mp_error_to_string(result));
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
\}
|
|
|
|
|
|
|
|
/* set the number to 5 */
|
|
|
|
mp_set(&number, 5);
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
/* we're done with it. */
|
|
|
|
mp_clear(&number);
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
return EXIT_SUCCESS;
|
|
|
|
\}
|
|
|
|
\end{alltt} \end{small}
|
2003-02-28 16:08:34 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\subsection{Long Constant}
|
2003-02-28 16:08:34 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
When you want to set a constant that is the size of an ISO C ``unsigned long'' and larger than a single
|
|
|
|
digit the following function is provided.
|
2003-02-28 16:08:34 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\index{mp\_set\_int}
|
|
|
|
\begin{alltt}
|
|
|
|
int mp_set_int (mp_int * a, unsigned long b);
|
|
|
|
\end{alltt}
|
2003-02-28 16:08:34 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
This will assign the value of the 32-bit variable ``b'' to the mp\_int ``a''. Unlike mp\_set() this function will always
|
|
|
|
accept a 32-bit input regardless of the size of a single digit. However, since the value may span several digits
|
|
|
|
this function can fail if it runs out of heap memory.
|
2003-02-28 16:08:34 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\begin{small} \begin{alltt}
|
|
|
|
int main(void)
|
|
|
|
\{
|
|
|
|
mp_int number;
|
|
|
|
int result;
|
|
|
|
|
|
|
|
if ((result = mp_init(&number)) != MP_OKAY) \{
|
|
|
|
printf("Error initializing the number. \%s",
|
|
|
|
mp_error_to_string(result));
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
\}
|
|
|
|
|
|
|
|
/* set the number to 654321 (note this is bigger than 127) */
|
|
|
|
if ((result = mp_set_int(&number, 654321)) != MP_OKAY) \{
|
|
|
|
printf("Error setting the value of the number. \%s",
|
|
|
|
mp_error_to_string(result));
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
\}
|
|
|
|
/* we're done with it. */
|
|
|
|
mp_clear(&number);
|
|
|
|
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
\}
|
|
|
|
\end{alltt} \end{small}
|
|
|
|
|
|
|
|
\section{Comparisons}
|
|
|
|
|
|
|
|
Comparisons in LibTomMath are always performed in a ``left to right'' fashion. There are three possible return codes
|
|
|
|
for any comparison.
|
|
|
|
|
|
|
|
\index{MP\_GT} \index{MP\_EQ} \index{MP\_LT}
|
|
|
|
\begin{figure}[here]
|
|
|
|
\begin{center}
|
|
|
|
\begin{tabular}{|c|c|}
|
|
|
|
\hline \textbf{Result Code} & \textbf{Meaning} \\
|
|
|
|
\hline MP\_GT & $a > b$ \\
|
|
|
|
\hline MP\_EQ & $a = b$ \\
|
|
|
|
\hline MP\_LT & $a < b$ \\
|
|
|
|
\hline
|
|
|
|
\end{tabular}
|
|
|
|
\end{center}
|
|
|
|
\caption{Comparison Codes for $a, b$}
|
|
|
|
\label{fig:CMP}
|
|
|
|
\end{figure}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
In figure \ref{fig:CMP} two integers $a$ and $b$ are being compared. In this case $a$ is said to be ``to the left'' of
|
|
|
|
$b$.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\subsection{Unsigned comparison}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
An unsigned comparison considers only the digits themselves and not the associated \textit{sign} flag of the
|
|
|
|
mp\_int structures. This is analogous to an absolute comparison. The function mp\_cmp\_mag() will compare two
|
|
|
|
mp\_int variables based on their digits only.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\index{mp\_cmp\_mag}
|
|
|
|
\begin{alltt}
|
|
|
|
int mp_cmp(mp_int * a, mp_int * b);
|
|
|
|
\end{alltt}
|
|
|
|
This will compare ``a'' to ``b'' placing ``a'' to the left of ``b''. This function cannot fail and will return one of the
|
|
|
|
three compare codes listed in figure \ref{fig:CMP}.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\begin{small} \begin{alltt}
|
|
|
|
int main(void)
|
|
|
|
\{
|
|
|
|
mp_int number1, number2;
|
|
|
|
int result;
|
|
|
|
|
|
|
|
if ((result = mp_init_multi(&number1, &number2, NULL)) != MP_OKAY) \{
|
|
|
|
printf("Error initializing the numbers. \%s",
|
|
|
|
mp_error_to_string(result));
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
\}
|
|
|
|
|
|
|
|
/* set the number1 to 5 */
|
|
|
|
mp_set(&number1, 5);
|
|
|
|
|
|
|
|
/* set the number2 to -6 */
|
|
|
|
mp_set(&number2, 6);
|
|
|
|
if ((result = mp_neg(&number2, &number2)) != MP_OKAY) \{
|
|
|
|
printf("Error negating number2. \%s",
|
|
|
|
mp_error_to_string(result));
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
\}
|
|
|
|
|
|
|
|
switch(mp_cmp_mag(&number1, &number2)) \{
|
|
|
|
case MP_GT: printf("|number1| > |number2|"); break;
|
|
|
|
case MP_EQ: printf("|number1| = |number2|"); break;
|
|
|
|
case MP_LT: printf("|number1| < |number2|"); break;
|
|
|
|
\}
|
|
|
|
|
|
|
|
/* we're done with it. */
|
|
|
|
mp_clear_multi(&number1, &number2, NULL);
|
|
|
|
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
\}
|
|
|
|
\end{alltt} \end{small}
|
|
|
|
|
|
|
|
If this program\footnote{This function uses the mp\_neg() function which is discussed in section \ref{sec:NEG}.} completes
|
|
|
|
successfully it should print the following.
|
|
|
|
|
|
|
|
\begin{alltt}
|
|
|
|
|number1| < |number2|
|
|
|
|
\end{alltt}
|
|
|
|
|
|
|
|
This is because $\vert -6 \vert = 6$ and obviously $5 < 6$.
|
|
|
|
|
|
|
|
\subsection{Signed comparison}
|
|
|
|
|
|
|
|
To compare two mp\_int variables based on their signed value the mp\_cmp() function is provided.
|
|
|
|
|
|
|
|
\index{mp\_cmp}
|
|
|
|
\begin{alltt}
|
|
|
|
int mp_cmp(mp_int * a, mp_int * b);
|
|
|
|
\end{alltt}
|
|
|
|
|
|
|
|
This will compare ``a'' to the left of ``b''. It will first compare the signs of the two mp\_int variables. If they
|
|
|
|
differ it will return immediately based on their signs. If the signs are equal then it will compare the digits
|
|
|
|
individually. This function will return one of the compare conditions codes listed in figure \ref{fig:CMP}.
|
|
|
|
|
|
|
|
\begin{small} \begin{alltt}
|
|
|
|
int main(void)
|
|
|
|
\{
|
|
|
|
mp_int number1, number2;
|
|
|
|
int result;
|
|
|
|
|
|
|
|
if ((result = mp_init_multi(&number1, &number2, NULL)) != MP_OKAY) \{
|
|
|
|
printf("Error initializing the numbers. \%s",
|
|
|
|
mp_error_to_string(result));
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
\}
|
|
|
|
|
|
|
|
/* set the number1 to 5 */
|
|
|
|
mp_set(&number1, 5);
|
|
|
|
|
|
|
|
/* set the number2 to -6 */
|
|
|
|
mp_set(&number2, 6);
|
|
|
|
if ((result = mp_neg(&number2, &number2)) != MP_OKAY) \{
|
|
|
|
printf("Error negating number2. \%s",
|
|
|
|
mp_error_to_string(result));
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
\}
|
|
|
|
|
|
|
|
switch(mp_cmp(&number1, &number2)) \{
|
|
|
|
case MP_GT: printf("number1 > number2"); break;
|
|
|
|
case MP_EQ: printf("number1 = number2"); break;
|
|
|
|
case MP_LT: printf("number1 < number2"); break;
|
|
|
|
\}
|
|
|
|
|
|
|
|
/* we're done with it. */
|
|
|
|
mp_clear_multi(&number1, &number2, NULL);
|
|
|
|
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
\}
|
|
|
|
\end{alltt} \end{small}
|
|
|
|
|
|
|
|
If this program\footnote{This function uses the mp\_neg() function which is discussed in section \ref{sec:NEG}.} completes
|
|
|
|
successfully it should print the following.
|
|
|
|
|
|
|
|
\begin{alltt}
|
|
|
|
number1 > number2
|
|
|
|
\end{alltt}
|
|
|
|
|
|
|
|
\subsection{Single Digit}
|
|
|
|
|
|
|
|
To compare a single digit against an mp\_int the following function has been provided.
|
|
|
|
|
|
|
|
\index{mp\_cmp\_d}
|
|
|
|
\begin{alltt}
|
|
|
|
int mp_cmp_d(mp_int * a, mp_digit b);
|
|
|
|
\end{alltt}
|
|
|
|
|
|
|
|
This will compare ``a'' to the left of ``b'' using a signed comparison. Note that it will always treat ``b'' as
|
|
|
|
positive. This function is rather handy when you have to compare against small values such as $1$ (which often
|
|
|
|
comes up in cryptography). The function cannot fail and will return one of the tree compare condition codes
|
|
|
|
listed in figure \ref{fig:CMP}.
|
|
|
|
|
|
|
|
|
|
|
|
\begin{small} \begin{alltt}
|
|
|
|
int main(void)
|
|
|
|
\{
|
|
|
|
mp_int number;
|
|
|
|
int result;
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
if ((result = mp_init(&number)) != MP_OKAY) \{
|
|
|
|
printf("Error initializing the number. \%s",
|
|
|
|
mp_error_to_string(result));
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
\}
|
|
|
|
|
|
|
|
/* set the number to 5 */
|
|
|
|
mp_set(&number, 5);
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
switch(mp_cmp_d(&number, 7)) \{
|
|
|
|
case MP_GT: printf("number > 7"); break;
|
|
|
|
case MP_EQ: printf("number = 7"); break;
|
|
|
|
case MP_LT: printf("number < 7"); break;
|
|
|
|
\}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
/* we're done with it. */
|
|
|
|
mp_clear(&number);
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
return EXIT_SUCCESS;
|
|
|
|
\}
|
|
|
|
\end{alltt} \end{small}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
If this program functions properly it will print out the following.
|
2003-02-28 16:09:08 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\begin{alltt}
|
|
|
|
number < 7
|
|
|
|
\end{alltt}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\section{Logical Operations}
|
2003-02-28 16:09:08 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
Logical operations are operations that can be performed either with simple shifts or boolean operators such as
|
|
|
|
AND, XOR and OR directly. These operations are very quick.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\subsection{Multiplication by two}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
Multiplications and divisions by any power of two can be performed with quick logical shifts either left or
|
|
|
|
right depending on the operation.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
When multiplying or dividing by two a special case routine can be used which are as follows.
|
|
|
|
\index{mp\_mul\_2} \index{mp\_div\_2}
|
|
|
|
\begin{alltt}
|
|
|
|
int mp_mul_2(mp_int * a, mp_int * b);
|
|
|
|
int mp_div_2(mp_int * a, mp_int * b);
|
|
|
|
\end{alltt}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
The former will assign twice ``a'' to ``b'' while the latter will assign half ``a'' to ``b''. These functions are fast
|
|
|
|
since the shift counts and maskes are hardcoded into the routines.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\begin{small} \begin{alltt}
|
|
|
|
int main(void)
|
|
|
|
\{
|
|
|
|
mp_int number;
|
|
|
|
int result;
|
|
|
|
|
|
|
|
if ((result = mp_init(&number)) != MP_OKAY) \{
|
|
|
|
printf("Error initializing the number. \%s",
|
|
|
|
mp_error_to_string(result));
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
\}
|
|
|
|
|
|
|
|
/* set the number to 5 */
|
|
|
|
mp_set(&number, 5);
|
|
|
|
|
|
|
|
/* multiply by two */
|
|
|
|
if ((result = mp\_mul\_2(&number, &number)) != MP_OKAY) \{
|
|
|
|
printf("Error multiplying the number. \%s",
|
|
|
|
mp_error_to_string(result));
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
\}
|
|
|
|
switch(mp_cmp_d(&number, 7)) \{
|
|
|
|
case MP_GT: printf("2*number > 7"); break;
|
|
|
|
case MP_EQ: printf("2*number = 7"); break;
|
|
|
|
case MP_LT: printf("2*number < 7"); break;
|
|
|
|
\}
|
|
|
|
|
|
|
|
/* now divide by two */
|
|
|
|
if ((result = mp\_div\_2(&number, &number)) != MP_OKAY) \{
|
|
|
|
printf("Error dividing the number. \%s",
|
|
|
|
mp_error_to_string(result));
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
\}
|
|
|
|
switch(mp_cmp_d(&number, 7)) \{
|
|
|
|
case MP_GT: printf("2*number/2 > 7"); break;
|
|
|
|
case MP_EQ: printf("2*number/2 = 7"); break;
|
|
|
|
case MP_LT: printf("2*number/2 < 7"); break;
|
|
|
|
\}
|
|
|
|
|
|
|
|
/* we're done with it. */
|
|
|
|
mp_clear(&number);
|
|
|
|
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
\}
|
|
|
|
\end{alltt} \end{small}
|
|
|
|
|
|
|
|
If this program is successful it will print out the following text.
|
|
|
|
|
|
|
|
\begin{alltt}
|
|
|
|
2*number > 7
|
|
|
|
2*number/2 < 7
|
|
|
|
\end{alltt}
|
|
|
|
|
|
|
|
Since $10 > 7$ and $5 < 7$. To multiply by a power of two the following function can be used.
|
|
|
|
|
|
|
|
\index{mp\_mul\_2d}
|
|
|
|
\begin{alltt}
|
|
|
|
int mp_mul_2d(mp_int * a, int b, mp_int * c);
|
|
|
|
\end{alltt}
|
|
|
|
|
|
|
|
This will multiply ``a'' by $2^b$ and store the result in ``c''. If the value of $b$ is less than or equal to
|
|
|
|
zero the function will copy ``a'' to ``c'' without performing any further actions.
|
|
|
|
|
|
|
|
To divide by a power of two use the following.
|
|
|
|
|
|
|
|
\index{mp\_div\_2d}
|
|
|
|
\begin{alltt}
|
|
|
|
int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d);
|
|
|
|
\end{alltt}
|
|
|
|
Which will divide ``a'' by $2^b$, store the quotient in ``c'' and the remainder in ``d'. If $b \le 0$ then the
|
|
|
|
function simply copies ``a'' over to ``c'' and zeroes ``d''. The variable ``d'' may be passed as a \textbf{NULL}
|
|
|
|
value to signal that the remainder is not desired.
|
|
|
|
|
|
|
|
\subsection{Polynomial Basis Operations}
|
|
|
|
|
|
|
|
Strictly speaking the organization of the integers within the mp\_int structures is what is known as a
|
|
|
|
``polynomial basis''. This simply means a field element is stored by divisions of a radix. For example, if
|
|
|
|
$f(x) = \sum_{i=0}^{k} y_ix^k$ for any vector $\vec y$ then the array of digits in $\vec y$ are said to be
|
|
|
|
the polynomial basis representation of $z$ if $f(\beta) = z$ for a given radix $\beta$.
|
|
|
|
|
|
|
|
To multiply by the polynomial $g(x) = x$ all you have todo is shift the digits of the basis left one place. The
|
|
|
|
following function provides this operation.
|
|
|
|
|
|
|
|
\index{mp\_lshd}
|
|
|
|
\begin{alltt}
|
|
|
|
int mp_lshd (mp_int * a, int b);
|
|
|
|
\end{alltt}
|
|
|
|
|
|
|
|
This will multiply ``a'' in place by $x^b$ which is equivalent to shifting the digits left $b$ places and inserting zeroes
|
|
|
|
in the least significant digits. Similarly to divide by a power of $x$ the following function is provided.
|
|
|
|
|
|
|
|
\index{mp\_rshd}
|
|
|
|
\begin{alltt}
|
|
|
|
void mp_rshd (mp_int * a, int b)
|
|
|
|
\end{alltt}
|
|
|
|
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}
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
\index{mp\_or} \index{mp\_and} \index{mp\_xor}
|
|
|
|
\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);
|
|
|
|
\end{alltt}
|
|
|
|
|
|
|
|
Which compute $c = a \odot b$ where $\odot$ is one of OR, AND or XOR.
|
|
|
|
|
|
|
|
\section{Addition and Subtraction}
|
|
|
|
|
|
|
|
To compute an addition or subtraction the following two functions can be used.
|
|
|
|
|
|
|
|
\index{mp\_add} \index{mp\_sub}
|
|
|
|
\begin{alltt}
|
|
|
|
int mp_add (mp_int * a, mp_int * b, mp_int * c);
|
|
|
|
int mp_sub (mp_int * a, mp_int * b, mp_int * c)
|
|
|
|
\end{alltt}
|
|
|
|
|
|
|
|
Which perform $c = a \odot b$ where $\odot$ is one of signed addition or subtraction. The operations are fully sign
|
|
|
|
aware.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\section{Sign Manipulation}
|
|
|
|
\subsection{Negation}
|
|
|
|
\label{sec:NEG}
|
|
|
|
Simple integer negation can be performed with the following.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\index{mp\_neg}
|
|
|
|
\begin{alltt}
|
|
|
|
int mp_neg (mp_int * a, mp_int * b);
|
|
|
|
\end{alltt}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
Which assigns $-b$ to $a$.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\subsection{Absolute}
|
|
|
|
Simple integer absolutes can be performed with the following.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\index{mp\_neg}
|
|
|
|
\begin{alltt}
|
|
|
|
int mp_abs (mp_int * a, mp_int * b);
|
|
|
|
\end{alltt}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
Which assigns $\vert b \vert$ to $a$.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\chapter{Multiplication and Squaring}
|
|
|
|
\section{Multiplication}
|
|
|
|
A full signed integer multiplication can be performed with the following.
|
|
|
|
\index{mp\_mul}
|
|
|
|
\begin{alltt}
|
|
|
|
int mp_mul (mp_int * a, mp_int * b, mp_int * c);
|
|
|
|
\end{alltt}
|
|
|
|
Which assigns the full signed product $ab$ to $c$. This function actually breaks into one of four cases which are
|
|
|
|
specific multiplication routines optimized for given parameters. First there are the Toom-Cook multiplications which
|
|
|
|
should only be used with very large inputs. This is followed by the Karatsuba multiplications which are for moderate
|
|
|
|
sized inputs. Then followed by the Comba and baseline multipliers.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
Fortunately for the developer you don't really need to know this unless you really want to fine tune the system. mp\_mul()
|
|
|
|
will determine on its own\footnote{Some tweaking may be required.} what routine to use automatically when it is called.
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\section{Squaring}
|
|
|
|
Since squaring can be performed faster than multiplication it is performed it's own function instead of just using
|
|
|
|
mp\_mul().
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\index{mp\_sqr}
|
|
|
|
\begin{alltt}
|
|
|
|
int mp_sqr (mp_int * a, mp_int * b);
|
|
|
|
\end{alltt}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
Will square ``a'' and store it in ``b''. Like the case of multiplication there are four different squaring
|
|
|
|
algorithms all which can be called from mp\_sqr().
|
2003-02-28 16:07:58 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\section{Tuning Polynomial Basis Routines}
|
2003-03-22 15:10:20 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
Both Toom-Cook and Karatsuba multiplication algorithms are faster than the traditional $O(n^2)$ approach that
|
|
|
|
the Comba and baseline algorithms use. At $O(n^{1.46})$ and $O(n^{1.58})$ running times respectfully they require
|
|
|
|
considerably less work. For example, a 10000-digit multiplication would take roughly 692,000 single precision
|
|
|
|
multiplications with Toom-Cook or 100,000,000 single precision multiplications with the standard Comba (a factor
|
|
|
|
of 144).
|
2003-03-22 15:10:20 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
So why not always use Karatsuba or Toom-Cook? The simple answer is that they have so much overhead that they're not
|
|
|
|
actually faster than Comba until you hit distinct ``cutoff'' points. For Karatsuba with the default configuration,
|
|
|
|
GCC 3.3.1 and an Athlon XP processor the cutoff point is roughly 110 digits (about 70 for the Intel P4). That is, at
|
|
|
|
110 digits Karatsuba and Comba multiplications just about break even and for 110+ digits Karatsuba is faster.
|
2003-03-22 15:10:20 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
Toom-Cook has incredible overhead and is probably only useful for very large inputs. So far no known cutoff points
|
|
|
|
exist and for the most part I just set the cutoff points very high to make sure they're not called.
|
2003-03-22 15:10:20 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
A demo program in the ``etc/'' directory of the project called ``tune.c'' can be used to find the cutoff points. This
|
|
|
|
can be built with GCC as follows
|
2003-03-22 15:10:20 +00:00
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
\begin{alltt}
|
|
|
|
make XXX
|
|
|
|
\end{alltt}
|
|
|
|
Where ``XXX'' is one of the following entries from the table \ref{fig:tuning}.
|
2003-03-22 15:10:20 +00:00
|
|
|
|
|
|
|
\begin{figure}[here]
|
|
|
|
\begin{center}
|
|
|
|
\begin{small}
|
2003-12-24 18:59:22 +00:00
|
|
|
\begin{tabular}{|l|l|}
|
|
|
|
\hline \textbf{Value of XXX} & \textbf{Meaning} \\
|
|
|
|
\hline tune & Builds portable tuning application \\
|
|
|
|
\hline tune86 & Builds x86 (pentium and up) program for COFF \\
|
|
|
|
\hline tune86c & Builds x86 program for Cygwin \\
|
|
|
|
\hline tune86l & Builds x86 program for Linux (ELF format) \\
|
2003-03-22 15:10:20 +00:00
|
|
|
\hline
|
|
|
|
\end{tabular}
|
|
|
|
\end{small}
|
2003-12-24 18:59:22 +00:00
|
|
|
\end{center}
|
|
|
|
\caption{Build Names for Tuning Programs}
|
|
|
|
\label{fig:tuning}
|
2003-03-22 15:10:20 +00:00
|
|
|
\end{figure}
|
|
|
|
|
2003-12-24 18:59:22 +00:00
|
|
|
When the program is running it will output a series of measurements for different cutoff points. It will first find
|
|
|
|
good Karatsuba squaring and multiplication points. Then it proceeds to find Toom-Cook points. Note that the Toom-Cook
|
|
|
|
tuning takes a very long time as the cutoff points are likely to be very high.
|
|
|
|
|
|
|
|
\chapter{Modular Reduction}
|
|
|
|
\section{Integer Division and Remainder}
|
|
|
|
To perform a complete and general integer division with remainder use the following function.
|
|
|
|
|
|
|
|
\index{mp\_div}
|
|
|
|
\begin{alltt}
|
|
|
|
int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d);
|
|
|
|
\end{alltt}
|
|
|
|
|
|
|
|
This divides ``a'' by ``b'' and stores the quotient in ``c'' and ``d''. The signed quotient is computed such that
|
|
|
|
$bc + d = a$. Note that either of ``c'' or ``d'' can be set to \textbf{NULL} if their value is not required.
|
|
|
|
|
|
|
|
\section{Barrett Reduction}
|
|
|
|
\section{Montgomery Reduction}
|
|
|
|
\section{Restricted Dimminished Radix}
|
|
|
|
\section{Unrestricted Dimminshed Radix}
|
|
|
|
|
|
|
|
\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-write algorithm. It is faster than repeated multiplications 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 function
|
|
|
|
will 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$.
|
|
|
|
|
|
|
|
\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 small
|
|
|
|
numbers (less than 1000 bits) I'd avoid $b > 3$ situations. Will return a positive root only for even roots and return
|
|
|
|
a 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$.
|
|
|
|
|
|
|
|
\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{Currently
|
|
|
|
the 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 is
|
|
|
|
equal 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 to
|
|
|
|
fool (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-dozen
|
|
|
|
or 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'' expressed
|
|
|
|
in bits. This comes in handy specially since larger numbers are slower to test. For example, a 512-bit number would
|
|
|
|
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}
|
|
|
|
\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 simply
|
|
|
|
copied 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.
|
|
|
|
|
|
|
|
\chapter{Input and Output}
|
|
|
|
\section{ASCII Conversions}
|
|
|
|
\section{Binary Conversions}
|
|
|
|
\section{Stream Functions}
|
|
|
|
|
|
|
|
\chapter{Algebraic Functions}
|
|
|
|
\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$.
|
|
|
|
|
|
|
|
\section{Least Common Multiple}
|
|
|
|
\index{mp\_lcm}
|
|
|
|
\begin{alltt}
|
|
|
|
int mp_lcm (mp_int * a, mp_int * b, mp_int * c)
|
|
|
|
\end{alltt}
|
|
|
|
This will compute the least common multiple of $a$ and $b$ and store it in $c$.
|
|
|
|
|
|
|
|
\section{Jacobi Symbol}
|
|
|
|
\index{mp\_jacobi}
|
|
|
|
\begin{alltt}
|
|
|
|
int mp_jacobi (mp_int * a, mp_int * p, int *c)
|
|
|
|
\end{alltt}
|
|
|
|
This will compute the Jacobi symbol for $a$ with respect to $p$. If $p$ is prime this essentially computes the Legendre
|
|
|
|
symbol. The result is stored in $c$ and can take on one of three values $\lbrace -1, 0, 1 \rbrace$. If $p$ is prime
|
|
|
|
then the result will be $-1$ when $a$ is not a quadratic residue modulo $p$. The result will be $0$ if $a$ divides $p$
|
|
|
|
and the result will be $1$ if $a$ is a quadratic residue modulo $p$.
|
|
|
|
|
|
|
|
\section{Modular Inverse}
|
|
|
|
\index{mp\_invmod}
|
|
|
|
\begin{alltt}
|
|
|
|
int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
|
|
|
|
\end{alltt}
|
|
|
|
Computes the multiplicative inverse of $a$ modulo $b$ and stores the result in $c$ such that $ac \equiv 1 \mbox{ (mod }b\mbox{)}$.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\section{Single Digit Functions}
|
|
|
|
|
|
|
|
\input{bn.ind}
|
2003-02-28 16:07:58 +00:00
|
|
|
|
|
|
|
\end{document}
|