diff --git a/external/libtompoly-0.04/LICENSE b/external/libtompoly-0.04/LICENSE new file mode 100644 index 0000000..87c21ca --- /dev/null +++ b/external/libtompoly-0.04/LICENSE @@ -0,0 +1,4 @@ +LibTomPoly is hereby placed in the Public Domain. + +-- Tom St Denis + diff --git a/external/libtompoly-0.04/changes.txt b/external/libtompoly-0.04/changes.txt new file mode 100644 index 0000000..d7ed38a --- /dev/null +++ b/external/libtompoly-0.04/changes.txt @@ -0,0 +1,24 @@ +May 5th, 2004 +v0.04 - Fixed a bug in pb_monic() which for zero valued inputs could cause a segfault + - Daniel Richards (kyhwana@kyhwana.org) found several typos in the manual. + - Fixed bug in pb_shrink() that would leak memory + +Jan 25th, 2004 +v0.03 - Added pb_rawsize(), pb_readraw(), pb_toraw() + - Fixed bug in pb_monic() where it would only check the first [not leading] coefficient for one + +Jan 3rd, 2004 +v0.02 - Update pb_div() to shift r(x) after multplying it wit b(x) to save a bit of time + - improved pb_gcd() to handle inputs which are zero + - Added pb_shrink() + - fixed pb_invmod() + - added pb_exteuclid() [back ported that code into LTM... hehehe] + - added pb_exptmod() [this led me to find a bug in LTM!!!] + - added pb_monic() + - added pb_isirreduc() + - Some minor additions to test/documentation + +Dec 31st, 2003 +v0.01 ++ thanks goes to Martin Marcel, Greg Rose and Colin Percival for providing some missing knowledge and + helping me get this release going + - Initial release. diff --git a/external/libtompoly-0.04/demo/demo.c b/external/libtompoly-0.04/demo/demo.c new file mode 100644 index 0000000..a6fe41c --- /dev/null +++ b/external/libtompoly-0.04/demo/demo.c @@ -0,0 +1,216 @@ +#include + +void draw_poly(pb_poly *a) +{ + int x; + char buf[8192]; + + if (a->used == 0) { + printf("0"); + } else { + for (x = a->used - 1; x >= 0; x--) { + if (mp_iszero(&(a->terms[x])) == MP_YES) continue; + mp_toradix(&(a->terms[x]), buf, 10); + if ((x != a->used - 1) && a->terms[x].sign == MP_ZPOS) { + printf("+"); + } + printf(" %sx^%d ", buf, x); + } + } + if (mp_iszero(&(a->characteristic)) == MP_NO) { + mp_toradix(&(a->characteristic), buf, 10); + printf(" (mod %s)", buf); + } + printf("\n"); +} + +int main(void) +{ + mp_int chara; + pb_poly a,b,c,d,e; + mp_int aa,bb,cc,dd,ee; + int res; + + mp_init(&chara); + mp_init_multi(&aa,&bb,&cc,&dd,&ee,NULL); + pb_init_size(&a, &chara, 32); + pb_init_size(&b, &chara, 32); + pb_init_size(&c, &chara, 32); + pb_init_size(&d, &chara, 32); + pb_init_size(&e, &chara, 32); + + /* a = 3x + 4 */ + mp_set(&(a.terms[1]), 3); + mp_set(&(a.terms[0]), 4); + a.used = 2; + pb_clamp(&a); + printf("a == \n"); + draw_poly(&a); + + /* b = 7x^2 + 5x + 7 */ + mp_set(&(b.terms[2]), 7); + mp_set(&(b.terms[1]), 5); + mp_set(&(b.terms[0]), 7); + b.used = 3; + pb_clamp(&b); + printf("b == \n"); + draw_poly(&b); + + /* c = a + b */ + printf("a + b\n"); + pb_add(&a, &b, &c); + draw_poly(&c); + + /* c = b + a */ + printf("b + a\n"); + pb_add(&b, &a, &c); + draw_poly(&c); + + /* now test clearing */ + printf("Shifting previous up one\n"); + pb_lshd(&c, 1); + draw_poly(&c); + pb_rshd(&c, 1); + draw_poly(&c); + pb_lshd(&c, 1); + pb_add(&a, &b, &c); + printf("previous add (test if excess cleared)\n"); + draw_poly(&c); + + /* multiply */ + printf("Multiply:\n"); + draw_poly(&a); + draw_poly(&b); + pb_mul(&a, &b, &c); + draw_poly(&c); + + /* subtract */ + printf("a - b\n"); + pb_sub(&a, &b, &c); + draw_poly(&c); + printf("b - a\n"); + pb_sub(&b, &a, &c); + draw_poly(&c); + + + /* now hijack the char */ + mp_set(&(a.characteristic), 17); + mp_set(&(b.characteristic), 17); + mp_set(&(c.characteristic), 17); + mp_set(&(d.characteristic), 17); + mp_set(&(e.characteristic), 17); + + /* perform modular addition */ + printf("a + b (in GF(17))\n"); + pb_add(&a, &b, &c); + draw_poly(&c); + pb_add(&b, &a, &c); + draw_poly(&c); + + /* perform modular subtaction */ + printf("a - b (in GF(17))\n"); + pb_sub(&a, &b, &c); + draw_poly(&c); + printf("b - a (in GF(17))\n"); + pb_sub(&b, &a, &c); + draw_poly(&c); + + /* perform division */ + printf("Division (b/a)\n"); + pb_div(&b, &a, &c, &d); + draw_poly(&a); + draw_poly(&b); + printf("Q == \n"); draw_poly(&c); + printf("R == \n"); draw_poly(&d); + + /* now test it */ + pb_mul(&a, &c, &c); + pb_add(&c, &d, &c); + printf("aQ + R =\n"); draw_poly(&c); + + /* test mod */ + pb_mod(&b, &a, &c); + printf("b mod a == "); draw_poly(&c); + + /* test GCD of (x^2 - 1) and 5*x^4+5*x^3+7*x^2+8*x+1 [should be x+1] */ + printf("GCD Test\n"); + pb_zero(&a); + mp_set(&(a.terms[2]), 1); + mp_set(&(a.terms[0]), 16); + a.used = 3; + pb_clamp(&a); + printf("a == \n"); + draw_poly(&a); + + pb_zero(&b); + mp_set(&(b.terms[4]), 5); + mp_set(&(b.terms[3]), 5); + mp_set(&(b.terms[2]), 7); + mp_set(&(b.terms[1]), 8); + mp_set(&(b.terms[0]), 1); + b.used = 6; + pb_clamp(&b); + printf("b == \n"); + draw_poly(&b); + + pb_gcd(&a, &b, &c); + printf("GCD: "); draw_poly(&c); + + /* test GCD */ + pb_div(&a, &c, &d, &e); + printf("a/c == "); draw_poly(&d); printf("a mod c == "); draw_poly(&e); pb_mul(&d, &c, &e); printf("should be a: "); draw_poly(&e); + pb_div(&b, &c, &d, &e); + printf("b/c == "); draw_poly(&d); printf("b mod c == "); draw_poly(&e); pb_mul(&d, &c, &e); printf("should be b: "); draw_poly(&e); + + /* test modular inverse... x^2 + 3 or so should work nice */ + printf("Modular Inverse\n"); + pb_zero(&a); + mp_set(&(a.terms[2]), 1); + mp_set(&(a.terms[1]), 0); + mp_set(&(a.terms[0]), 3); + a.used = 3; + pb_clamp(&a); + printf("a == \n"); + draw_poly(&a); + + /* take inverse of 2x + 9 */ + pb_zero(&b); + mp_set(&(b.terms[1]), 2); + mp_set(&(b.terms[0]), 9); + b.used = 2; + pb_clamp(&b); + printf("b == \n"); + draw_poly(&b); + + /* invert */ + pb_invmod(&b, &a, &c); + printf("Inverse\n"); + draw_poly(&c); + + /* test */ + pb_mulmod(&b, &c, &a, &d); + pb_mul(&b, &c, &e); + printf("This should be 1 : "); draw_poly(&d); + printf("This should be equal to k*a + 1: "); draw_poly(&e); + + /* now b has order [dividing] 17^2 - 1 == 288 so b^287 should equal c */ + printf("exptmod test\n"); + mp_set(&aa, 287); + pb_exptmod(&b, &aa, &a, &d); + printf("This should be invmod : "); draw_poly(&d); + + /* test irreduc */ + printf("Irreducibility testing\n"); + pb_isirreduc(&a, &res); + printf("This should be 1 : %d\n", res); + + pb_isirreduc(&b, &res); + printf("This should be 0 : %d\n", res); + + + + return EXIT_SUCCESS; +} + + + diff --git a/external/libtompoly-0.04/makefile b/external/libtompoly-0.04/makefile new file mode 100644 index 0000000..af2503e --- /dev/null +++ b/external/libtompoly-0.04/makefile @@ -0,0 +1,56 @@ +#Makefile for GCC by Tom St Denis +CFLAGS += -fPIC -I. -Os -Wall -W + +VERSION=0.04 + +#default files to install +LIBNAME=libtompoly.a +HEADERS=tompoly.h + +#LIBPATH-The directory for libtomcrypt to be installed to. +#INCPATH-The directory to install the header files for libtommath. +#DATAPATH-The directory to install the pdf docs. +DESTDIR= +LIBPATH=/usr/lib +INCPATH=/usr/include +DATAPATH=/usr/share/doc/libtompoly/pdf + +default: libtompoly.a + +OBJECTS = pb_init.o pb_clear.o pb_init_size.o pb_grow.o pb_copy.o pb_clamp.o pb_init_copy.o \ +pb_add.o pb_sub.o pb_mul.o pb_div.o pb_zero.o pb_lshd.o pb_rshd.o pb_exch.o pb_mod.o \ +pb_addmod.o pb_submod.o pb_mulmod.o pb_gcd.o pb_init_multi.o pb_clear_multi.o pb_invmod.o \ +pb_cmp.o pb_shrink.o pb_exteuclid.o pb_monic.o pb_exptmod.o pb_isirreduc.o pb_rawsize.o \ +pb_toraw.o pb_readraw.o + +libtompoly.a: $(OBJECTS) + ar $(ARFLAGS) libtompoly.a $(OBJECTS) + +install: libtompoly.a + install -d -g root -o root $(DESTDIR)$(LIBPATH) + install -d -g root -o root $(DESTDIR)$(INCPATH) + install -g root -o root $(LIBNAME) $(DESTDIR)$(LIBPATH) + install -g root -o root $(HEADERS) $(DESTDIR)$(INCPATH) + +demo: demo/demo.o libtompoly.a + gcc demo/demo.o libtompoly.a -ltommath -o pbdemo + +mandvi: pb.tex + echo "hello" > pb.ind + latex pb > /dev/null + latex pb > /dev/null + makeindex pb + latex pb > /dev/null + +manual: mandvi + pdflatex pb >/dev/null + +clean: + rm -f *.o *.a *.obj *.lib *.exe pbdemo demo/*.o demo/*.obj demo/*.exe + rm -f *.idx *.ilg *.ind *.lof *.out *.toc *.dvi *.log *.aux + +zipup: manual clean + cd .. ; rm -rf ltp* libtompoly-$(VERSION) ; mkdir libtompoly-$(VERSION) ; \ + cp -R ./libtompoly/* ./libtompoly-$(VERSION)/ ; \ + tar -c libtompoly-$(VERSION)/* | bzip2 -9vvc > ltp-$(VERSION).tar.bz2 ; \ + zip -9 -r ltp-$(VERSION).zip libtompoly-$(VERSION)/* diff --git a/external/libtompoly-0.04/makefile.msvc b/external/libtompoly-0.04/makefile.msvc new file mode 100644 index 0000000..8fddcd4 --- /dev/null +++ b/external/libtompoly-0.04/makefile.msvc @@ -0,0 +1,17 @@ +#Makefile for MSVC by Tom St Denis +CFLAGS = /W3 /Ox /I. + +default: tompoly.lib + +OBJECTS = pb_init.obj pb_clear.obj pb_init_size.obj pb_grow.obj pb_copy.obj pb_clamp.obj pb_init_copy.obj \ +pb_add.obj pb_sub.obj pb_mul.obj pb_div.obj pb_zero.obj pb_lshd.obj pb_rshd.obj pb_exch.obj pb_mod.obj \ +pb_addmod.obj pb_submod.obj pb_mulmod.obj pb_gcd.obj pb_init_multi.obj pb_clear_multi.obj pb_invmod.obj \ +pb_cmp.obj pb_shrink.obj pb_exteuclid.obj pb_monic.obj pb_exptmod.obj pb_isirreduc.obj pb_rawsize.obj \ +pb_toraw.obj pb_readraw.obj + +tompoly.lib: $(OBJECTS) + lib /out:tompoly.lib $(OBJECTS) + +demo: demo/demo.obj tompoly.lib + cl demo.obj tompoly.lib tommath.lib + diff --git a/external/libtompoly-0.04/pb.pdf b/external/libtompoly-0.04/pb.pdf new file mode 100644 index 0000000..c15f7dc Binary files /dev/null and b/external/libtompoly-0.04/pb.pdf differ diff --git a/external/libtompoly-0.04/pb.tex b/external/libtompoly-0.04/pb.tex new file mode 100644 index 0000000..b4c7927 --- /dev/null +++ b/external/libtompoly-0.04/pb.tex @@ -0,0 +1,433 @@ +\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 +\begin{document} +\frontmatter +\pagestyle{empty} +\title{LibTomPoly User Manual \\ v0.04} +\author{Tom St Denis \\ tomstdenis@iahu.ca} +\maketitle +This text and library are hereby placed in the public domain. This book has been +formatted for B5 [176x250] paper using the \LaTeX{} {\em book} macro package. + +\vspace{10cm} + +\begin{flushright}Open Source. Open Academia. Open Minds. + +\mbox{ } + +Tom St Denis, + +Ontario, Canada +\end{flushright} + +\tableofcontents +\listoffigures +\mainmatter +\pagestyle{headings} +\chapter{Introduction} +\section{What is LibTomPoly?} +LibTomPoly is a public domain open source library to provide polynomial basis arithmetic. It uses the public domain +library LibTomMath (not included) for the integer arithmetic and extends the functonality to provide polynomial arithmetic. + +Technically speaking the library allows the user to perform arithmetic on elements from the group $GF(p)[x]$ and to +a lesser extent (this will change in the future) over $\Z[x]$. Essentially the math you can do with integers (including +forming rings and fields) you can do with with polynomials and now you can do with LibTomPoly. + +\section{License} +LibTomPoly is public domain. Enjoy. + +\section{Terminology} +Throughout this manual and within the library there will be some terminology that not everyone is familiar with. It is afterall +weird math. + +\begin{figure}[here] +\begin{center} +\begin{small} +\begin{tabular}{|l|l|} +\hline \textbf{Term} & \textbf{Definition} \\ +\hline monic polynomial & A polynomial where the leading coefficient is a one. \\ +\hline irreducible polynomial & A polynomial that has no factors in a given group. \\ + & For instance, $x^2 + 4$ is irreducible in $\Z[x]$ but not \\ + & in $GF(17)[x]$ since $x^2 + 4 = (x+8)(x+9) \mbox{ (mod }17\mbox{)}$. \\ +\hline primitive polynomial & An irreducible polynomial which generates all of \\ + & elements of a given field (e.g. $GF(p)[x]/v(x)$) \\ +\hline characteristic & An integer $k$ such that $k \cdot p(x) \equiv 0$ \\ +\hline deg() & Functon returns degree of polynomial, e.g. deg($x^6 + x^3 + 1$) = 6 \\ +\hline +\end{tabular} +\end{small} +\end{center} +\caption{Terminology} +\end{figure} + +\section{Building the Library} +The library is not ready for production yet but you can test out the library manually if you want. To build the library +simply type + +\begin{alltt} +make +\end{alltt} + +Which will build ``libtompoly.a''. To build a Win32 library with MSVC type + +\begin{alltt} +nmake -f makefile.msvc +\end{alltt} + +To build against this library include ``tompoly.h'' and link against ``libtompoly.a'' (or tommath.lib as appropriate). +To build the included demo type + +\begin{alltt} +make demo +\end{alltt} + +Which will build ``demo'' in the current directory. The demo is not interactive and produces results which must be manually +inspected. + +\chapter{Getting Started} + +\section{The LibTomMath Connection} +LibTomPoly is really just an extension of LibTomMath\footnote{\url{http://math.libtomcrypt.org}}. As such the library has +been designed in much the same way as far as argument passing and error handling events are concerned. The reader is +encouraged to become familiar with LibTomMath before diving into LibTomPoly. + +\section{The pb\_poly structure} +A polynomial can characterized by a few variables. Given the C structure as follows + +\begin{alltt} +typedef struct \{ + int used, /* number of terms */ + alloc; /* number of terms available (total) */ + mp_int characteristic, /* characteristic, zero if not finite */ + *terms; /* terms of polynomial */ +\} pb_poly; +\end{alltt} + +\begin{enumerate} + \item The \textbf{used} member indicates how many terms of the \textbf{terms} array are used to represent the polynomial. + \item The \textbf{alloc} member indicates the size of the \textbf{terms} array. Also note that even if \textbf{used} + is less than \textbf{alloc} the mp\_ints above \textbf{used} in the array must be set to a valid representation + of zero. + \item The \textbf{characteristic} member is an mp\_int representing the characteristic of the polynomial. If the desire is to + have a null characteristic (e.g. $\Z[x]$) this element must still be initialized to a valid representation + of zero. + \item The \textbf{terms} member is a dynamically sized array of mp\_int values which represent the coefficients for + the terms of the polynomial. They start from least to most significant degree. E.g. $p(x) = \sum_{i=0}^{used-1} terms_i \cdot x^i$. +\end{enumerate} + +\section{Return Codes} +The library uses the return codes from LibTomMath. They are + +\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} + +\section{Function Argument Passing} +Just like LibTomMath the arguments are meant to be read left to right where the destination is on the right. Consider +the following. + +\begin{alltt} +pb_add(a, b, c); /* c = a + b */ +pb_mul(a, b, c); /* c = a * b */ +\end{alltt} + +Also like LibTomMath input arguments can be specified as output arguments. Consider. + +\begin{alltt} +pb_mul(a, b, a); /* a = a * b */ +pb_gcd(a, b, b); /* b = (a, b) */ +\end{alltt} + +However, polynomial math raises another consideration. The characteristic of the result is taken from the right most +argument passed to the function. Not all functions will return an error code if the characteristics of the inputs +do not match so it's important to keep this in mind. In general the results are undefined if not all of the polynomials +have identical characteristics. + +\section{Initializing Polynomials} +In order to use a pb\_poly structure with one of the functions in this library the structure must be initialized. +There are three functions provided to initialize pb\_poly structures. + +\subsection{Default Initialization} +\index{pb\_init} +\begin{alltt} +int pb_init(pb_poly *a, mp_int *characteristic); +\end{alltt} +This will initialize ``a'' with the given ``characteristic'' such that the polynomial represented is a constant zero. +The mp\_int characteristic must be a valid initialized mp\_int even if a characteristic of zero is desired. By default, +the polynomial will be initialized so there are ``PB\_TERMS'' terms available. This will grow automatically as required +by the other functions. + +\subsection{Initilization of Given Size} +\index{pb\_init\_size} +\begin{alltt} +int pb_init_size(pb_poly *a, mp_int *characteristic, int size); +\end{alltt} +This behaves similar to pb\_init() except it will allocate ``size'' terms to initialize instead of ``PB\_TERMS''. This +is useful if you happen to know in advance how many terms you want. + +\subsection{Initilization of a Copy} +\index{pb\_init\_copy} +\begin{alltt} +int pb_init_copy(pb_poly *a, pb_poly *b); +\end{alltt} + +This will initialize ``a'' so it is a verbatim copy of ``b''. It will copy the characteristic and all of the terms +from ``b'' into ``a''. + +\subsection{Freeing a Polynomial} +\index{pb\_clear} +\begin{alltt} +int pb_clear(pb_poly *a); +\end{alltt} + +This will free all the memory required by ``a'' and mark it as been freed. You can repeatedly pb\_clear() the same +pb\_poly safely. + +\chapter{Basic Operations} +\section{Comparison} +Comparisions with polynomials is a bit less intuitive then with integers. Is $x^2 + 3$ greater than $x^2 + x + 4$? To +create a rational form of comparison the following comparison codes were designed. + +\begin{figure}[here] +\begin{small} +\begin{center} +\begin{tabular}{|l|l|} +\hline \textbf{Code} & \textbf{Meaning} \\ +\hline PB\_EQ & The polynomials are exactly equal \\ +\hline PB\_DEG\_LT & The left polynomial has a lower degree than the right. \\ +\hline PB\_DEG\_EQ & Both have the same degree. \\ +\hline PB\_DEG\_GT & The left polynomial has a higher degree than the right. \\ +\hline +\end{tabular} +\end{center} +\end{small} +\caption{Compare Codes} +\end{figure} + +\index{pb\_cmp} +\begin{alltt} +int pb_cmp(pb_poly *a, pb_poly *b); +\end{alltt} + +This will compare the polynomial ``a'' to the left of the polynomial ``b''. It will return one of the four +codes listed above. Note that the function does not compare the characteristics. So if $a \in GF(17)[x]$ and +$b \in GF(11)[x]$ were both equal to $x^2 + 3$ they would compare to PB\_EQ. Whereas $x^3 + 4$ +would compare to PB\_DEG\_LT, $x^1 + 7$ would compare to $PB\_DEG\_GT$ and $x^2 + 7$ would compare to $PB\_DEG\_EQ$\footnote{If the polynomial $a$ were on the left for all three cases.}. + +\section{Copying and Swapping} +\index{pb\_copy} +\begin{alltt} +int pb_copy(pb_poly *src, pb_poly *dest); +\end{alltt} +This will copy the polynomial from ``src'' to ``dest'' verbatim. + +\index{pb\_exch} +\begin{alltt} +int pb_exch(pb_poly *a, pb_poly *b); +\end{alltt} +This will exchange the contents of ``a'' with ``b''. + +\section{Multiplying and Dividing by $x$} +\index{pb\_lshd} \index{pb\_rshd} +\begin{alltt} +int pb_lshd(pb_poly *a, int i); +int pb_rshd(pb_poly *a, int i); +\end{alltt} +These will multiply (or divide, respectfully) the polynomial ``a'' by $x^i$. If $i \le 0$ the functions return without +performing any operation. For example, + +\begin{alltt} +pb_lshd(a, 2); /* a(x) = a(x) * x^2 */ +pb_rshd(a, 7); /* a(x) = a(x) / x^7 */ +\end{alltt} + +\chapter{Basic Arithmetic} +\section{Addition, Subtraction and Multiplication} +\index{pb\_add} \index{pb\_sub} +\begin{alltt} +int pb_add(pb_poly *a, pb_poly *b, pb_poly *c); +int pb_sub(pb_poly *a, pb_poly *b, pb_poly *c); +int pb_mul(pb_poly *a, pb_poly *b, pb_poly *c); +\end{alltt} + +These will add (subtract or multiply, respectfully) the polynomial ``a'' and polynomial ``b'' and store the result in +polynomial ``c''. The characteristic from ``c'' is used to calculate the result. Note that the coefficients of ``c'' +will always be positive provided the characteristic of ``c'' is greater than zero. + +Quick examples of usage. + +\begin{alltt} +pb_add(a, b, c); /* c = a + b */ +pb_sub(b, a, c); /* c = b - a */ +pb_mul(c, a, a); /* a = c * a */ +\end{alltt} + +\section{Division} +\index{pb\_div} +\begin{alltt} +int pb_div(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); +\end{alltt} +This will divide the polynomial ``a'' by ``b'' and store the quotient in ``c'' and remainder in ``d''. That is + +\begin{equation} +b(x) \cdot c(x) + d(x) = a(x) +\end{equation} + +The value of $deg(d(x))$ is always less than $deg(b(x))$. Either of ``c'' and ``d'' can be set to \textbf{NULL} to +signify their value is not desired. This is useful if you only want the quotient or remainder but not both. + +Since one of the destinations can be \textbf{NULL} the characteristic of the result is taken from ``b''. The function +will return an error if the characteristic of ``a'' differs from that of ``b''. + +This function is defined for polynomials in $GF(p)[x]$ only. A routine pb\_zdiv()\footnote{To be written!} allows the +division of polynomials in $\Z[x]$. + +\section{Modular Functions} +\index{pb\_addmod} \index{pb\_submod} \index{pb\_mulmod} +\begin{alltt} +int pb_addmod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); +int pb_submod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); +int pb_mulmod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); +\end{alltt} + +These add (subtract or multiply respectfully) the polynomial ``a'' and the polynomial ``b'' modulo the polynomial ``c'' +and store the result in the polynomial ``d''. + +\chapter{Algebraic Functions} + +\section{Monic Reductions} +\index{pb\_monic} +\begin{alltt} +int pb_monic(pb_poly *a, pb_poly *b) +\end{alltt} +Makes ``b'' the monic representation of ``a'' by ensuring the most significant coefficient is one. Only defined +over $GF(p)[x]$. Note that this is not a straight copy to ``b'' so you must ensure the characteristic of the two +are equal before you call the function\footnote{Note that $a == b$ is acceptable as well.}. Monic polynomials +are related to their original polynomial through an integer $k$ as follows + +\begin{equation} +a(x) \cdot k^{-1} \equiv b(x) +\end{equation} + +\section{Extended Euclidean Algorithm} +\index{pb\_exteuclid} +\begin{alltt} +int pb_exteuclid(pb_poly *a, pb_poly *b, + pb_poly *U1, pb_poly *U2, pb_poly *U3); +\end{alltt} + +This will compute the Euclidean algorithm and find values ``U1'', ``U2'', ``U3'' such that + +\begin{equation} +a(x) \cdot U1(x) + b(x) \cdot U2(x) = U3(x) +\end{equation} + +The value of ``U3'' is reduced to a monic polynomial. The three destination variables are all optional and can +be specified as \textbf{NULL} if they are not desired. + +\section{Greatest Common Divisor} +\index{pb\_gcd} +\begin{alltt} +int pb_gcd(pb_poly *a, pb_poly *b, pb_poly *c); +\end{alltt} +This finds the monic greatest common divisor of the two polynomials ``a'' and ``b'' and store the result in ``c''. The +operation is only defined over $GF(p)[x]$. + +\section{Modular Inverse} +\index{pb\_invmod} +\begin{alltt} +int pb_invmod(pb_poly *a, pb_poly *b, pb_poly *c); +\end{alltt} +This finds the modular inverse of ``a'' modulo ``b'' and stores the result in ``c''. The operation is only defined over +$GF(p)[x]$. If the operation succeed then the following congruency should hold true. + +\begin{equation} +a(x)c(x) \equiv 1 \mbox{ (mod }b(x)\mbox{)} +\end{equation} + +\section{Modular Exponentiation} +\index{pb\_exptmod} +\begin{alltt} +int pb_exptmod (pb_poly * G, mp_int * X, pb_poly * P, pb_poly * Y); +\end{alltt} + +This raise ``G'' to the power of ``X'' modulo ``P'' and stores the result in ``Y''. Or as a congruence + +\begin{equation} +Y(x) \equiv G(x)^X \mbox{ (mod }P(x)\mbox{)} +\end{equation} + +Where ``X'' can be negative\footnote{But in that case $G^{-1}(x)$ must exist modulo $P(x)$.} or positive. This function +is only defined over $GF(p)[x]$. + +\section{Irreducibility Testing} +\index{pb\_isirreduc} +\begin{alltt} +int pb_isirreduc(pb_poly *a, int *res); +\end{alltt} +Sets ``res'' to MP\_YES if ``a'' is irreducible (only for $GF(p)[x]$) otherwise sets ``res'' to MP\_NO. + +\input{pb.ind} + +\end{document} diff --git a/external/libtompoly-0.04/pb_add.c b/external/libtompoly-0.04/pb_add.c new file mode 100644 index 0000000..eb3c8f7 --- /dev/null +++ b/external/libtompoly-0.04/pb_add.c @@ -0,0 +1,73 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +int pb_add(pb_poly *a, pb_poly *b, pb_poly *c) +{ + int err, x, y, z, characteristic; + pb_poly *tmp; + + /* grow c to be the max size */ + y = MAX(a->used, b->used); + if (c->alloc < y) { + if ((err = pb_grow(c, y)) != MP_OKAY) { + return err; + } + } + + /* do we need to concern char */ + characteristic = mp_iszero(&(c->characteristic)); + + /* add the terms */ + z = MIN(a->used, b->used); + for (x = 0; x < z; x++) { + if ((err = mp_add(&(a->terms[x]), &(b->terms[x]), &(c->terms[x]))) != MP_OKAY) { + return err; + } + if (characteristic == MP_NO) { + if ((err = mp_mod(&(c->terms[x]), &(c->characteristic), &(c->terms[x]))) != MP_OKAY) { + return err; + } + } + } + + /* excess digits? */ + if (y != z) { + if (a->used == y) { + tmp = a; + } else { + tmp = b; + } + for (x = z; x < y; x++) { + if (characteristic == MP_NO) { + if ((err = mp_mod(&(tmp->terms[x]), &(c->characteristic), &(c->terms[x]))) != MP_OKAY) { + return err; + } + } else { + if ((err = mp_copy(&(tmp->terms[x]), &(c->terms[x]))) != MP_OKAY) { + return err; + } + } + } + } + + /* zero excess */ + for (x = y; x < c->used; x++) { + mp_zero(&(c->terms[x])); + } + c->used = y; + pb_clamp(c); + + return MP_OKAY; +} + + diff --git a/external/libtompoly-0.04/pb_addmod.c b/external/libtompoly-0.04/pb_addmod.c new file mode 100644 index 0000000..7587e1e --- /dev/null +++ b/external/libtompoly-0.04/pb_addmod.c @@ -0,0 +1,35 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +int pb_addmod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d) +{ + int err; + pb_poly tmp; + + if ((err = pb_init(&tmp, &(d->characteristic))) != MP_OKAY) { + return err; + } + if ((err = pb_add(a, b, &tmp)) != MP_OKAY) { + goto __TMP; + } + if ((err = pb_mod(&tmp, c, d)) != MP_OKAY) { + goto __TMP; + } + + err = MP_OKAY; +__TMP: pb_clear(&tmp); + return err; +} + + + diff --git a/external/libtompoly-0.04/pb_clamp.c b/external/libtompoly-0.04/pb_clamp.c new file mode 100644 index 0000000..c99e7b4 --- /dev/null +++ b/external/libtompoly-0.04/pb_clamp.c @@ -0,0 +1,21 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +void pb_clamp(pb_poly *a) +{ + while (a->used > 0 && (mp_iszero(&(a->terms[a->used-1])) == MP_YES)) { + --(a->used); + } +} + + diff --git a/external/libtompoly-0.04/pb_clear.c b/external/libtompoly-0.04/pb_clear.c new file mode 100644 index 0000000..ecfb5c0 --- /dev/null +++ b/external/libtompoly-0.04/pb_clear.c @@ -0,0 +1,32 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +void pb_clear(pb_poly *a) +{ + int x; + + if (a->terms != NULL) { + /* free stuff */ + for (x = 0; x < a->alloc; x++) { + mp_clear(&(a->terms[x])); + } + free(a->terms); + mp_clear(&(a->characteristic)); + + /* prevent double frees */ + a->terms = NULL; + a->alloc = a->used = 0; + } +} + + diff --git a/external/libtompoly-0.04/pb_clear_multi.c b/external/libtompoly-0.04/pb_clear_multi.c new file mode 100644 index 0000000..a1dff4a --- /dev/null +++ b/external/libtompoly-0.04/pb_clear_multi.c @@ -0,0 +1,25 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include +#include + +void pb_clear_multi(pb_poly *mp, ...) +{ + pb_poly* next_mp = mp; + va_list args; + va_start(args, mp); + while (next_mp != NULL) { + pb_clear(next_mp); + next_mp = va_arg(args, pb_poly*); + } + va_end(args); +} diff --git a/external/libtompoly-0.04/pb_cmp.c b/external/libtompoly-0.04/pb_cmp.c new file mode 100644 index 0000000..0812d61 --- /dev/null +++ b/external/libtompoly-0.04/pb_cmp.c @@ -0,0 +1,32 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +int pb_cmp(pb_poly *a, pb_poly *b) +{ + int x; + + if (a->used > b->used) { + return PB_DEG_GT; + } else if (a->used < b->used) { + return PB_DEG_LT; + } + + for (x = 0; x < a->used; x++) { + if (mp_cmp(&(a->terms[x]), &(b->terms[x])) != MP_EQ) { + return PB_DEG_EQ; + } + } + return PB_EQ; +} + + diff --git a/external/libtompoly-0.04/pb_copy.c b/external/libtompoly-0.04/pb_copy.c new file mode 100644 index 0000000..d9ae366 --- /dev/null +++ b/external/libtompoly-0.04/pb_copy.c @@ -0,0 +1,51 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +/* dest = src */ +int pb_copy(pb_poly *src, pb_poly *dest) +{ + int err, x; + + /* avoid trivial copies */ + if (src == dest) { + return MP_OKAY; + } + + /* grow dest as required */ + if (dest->alloc < src->used) { + if ((err = pb_grow(dest, src->used)) != MP_OKAY) { + return err; + } + } + + /* set the characteristic */ + if ((err = mp_copy(&(src->characteristic), &(dest->characteristic))) != MP_OKAY) { + return err; + } + + /* copy digits */ + for (x = 0; x < src->used; x++) { + if ((err = mp_copy(&(src->terms[x]), &(dest->terms[x]))) != MP_OKAY) { + return err; + } + } + + /* zero excess digits */ + for (x = src->used; x < dest->used; x++) { + mp_zero(&(dest->terms[x])); + } + dest->used = src->used; + return MP_OKAY; +} + + diff --git a/external/libtompoly-0.04/pb_div.c b/external/libtompoly-0.04/pb_div.c new file mode 100644 index 0000000..84d5665 --- /dev/null +++ b/external/libtompoly-0.04/pb_div.c @@ -0,0 +1,135 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + + +/* Divides a by b (uses the char of b as the char of the result) only for + * polynomials over GF(p^k)[x] + */ +int pb_div(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d) +{ + int err, x; + pb_poly p, q, r; + mp_int tmp, tmp2; + + /* if ||b|| > ||a|| it's a simple copy over */ + if (b->used > a->used) { + if (d != NULL) { + pb_copy(a, d); + } + if (c != NULL) { + pb_zero(c); + } + } + + /* zero divisor */ + if (b->used == 0) { + return MP_VAL; + } + + /* compare chars */ + if (mp_cmp(&(a->characteristic), &(b->characteristic)) != MP_EQ) { + return MP_VAL; + } + + /* we don't support char zero! */ + if (mp_iszero(&(b->characteristic)) == MP_YES) { + return MP_VAL; + } + + /* get a copy of "a" to work with */ + if ((err = pb_init_copy(&p, a)) != MP_OKAY) { + return err; + } + + /* init a temp quotient */ + if ((err = pb_init_size(&q, &(b->characteristic), a->used - b->used + 1)) != MP_OKAY) { + goto __P; + } + + /* init a temp polynomial we can work with */ + if ((err = pb_init_size(&r, &(b->characteristic), a->used)) != MP_OKAY) { + goto __Q; + } + + /* now init an mp_int we can work with */ + if ((err = mp_init(&tmp)) != MP_OKAY) { + goto __R; + } + + /* and the inverse of the leading digit of b(x) */ + if ((err = mp_init(&tmp2)) != MP_OKAY) { + goto __TMP; + } + if ((err = mp_invmod(&(b->terms[b->used - 1]), &(b->characteristic), &tmp2)) != MP_OKAY) { + goto __TMP2; + } + + /* now let's reduce us some digits */ + for (x = a->used - 1; x >= b->used-1; x--) { + /* skip zero digits */ + if (mp_iszero(&(p.terms[x])) == MP_YES) { + continue; + } + + /* now we have a leading digit of p(x), call it A + and a leading digit of b(x), call it B + + Now we want to reduce it so we need A + CB = 0 which turns into + A + CB = 0 + CB = -A + C = -A/B + + So we multiply b(x) by C * x^k [where k = ||p(x)|| - ||b(x)||], add that to p(x) and + we must reduced one digit + */ + + /* multiply 1/B [tmp2] by A */ + if ((err = mp_mulmod(&tmp2, &(p.terms[x]), &(b->characteristic), &tmp)) != MP_OKAY) { goto __TMP2; } + + /* tmp is now a term of the quotient */ + if ((err = mp_copy(&tmp, &(q.terms[x - b->used + 1]))) != MP_OKAY) { goto __TMP2; } + + /* create r(x) = C */ + pb_zero(&r); + if ((err = mp_copy(&tmp, &(r.terms[0]))) != MP_OKAY) { goto __TMP2; } + r.used = 1; + + /* now multiply r(x) by b(x)*x^k and subtract from p(x) */ + if ((err = pb_mul(b, &r, &r)) != MP_OKAY) { goto __TMP2; } + if ((err = pb_lshd(&r, x - b->used + 1)) != MP_OKAY) { goto __TMP2; } + if ((err = pb_sub(&p, &r, &p)) != MP_OKAY) { goto __TMP2; } + } + + /* setup q properly (so q.used is valid) */ + q.used = a->used; + pb_clamp(&q); + + /* ok so now p(x) is the remainder and q(x) is the quotient */ + if (c != NULL) { + pb_exch(&q, c); + } + if (d != NULL) { + pb_exch(&p, d); + } + + err = MP_OKAY; + +__TMP2: mp_clear(&tmp2); +__TMP : mp_clear(&tmp); +__R : pb_clear(&r); +__Q : pb_clear(&q); +__P : pb_clear(&p); + return err; +} + + diff --git a/external/libtompoly-0.04/pb_exch.c b/external/libtompoly-0.04/pb_exch.c new file mode 100644 index 0000000..b2925b9 --- /dev/null +++ b/external/libtompoly-0.04/pb_exch.c @@ -0,0 +1,20 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +void pb_exch(pb_poly *a, pb_poly *b) +{ + pb_poly tmp; + tmp = *a; *a = *b; *b = tmp; +} + + diff --git a/external/libtompoly-0.04/pb_exptmod.c b/external/libtompoly-0.04/pb_exptmod.c new file mode 100644 index 0000000..e203b72 --- /dev/null +++ b/external/libtompoly-0.04/pb_exptmod.c @@ -0,0 +1,186 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +#ifdef MP_LOW_MEM + #define TAB_SIZE 32 +#else + #define TAB_SIZE 256 +#endif + +int pb_exptmod (pb_poly * G, mp_int * X, pb_poly * P, pb_poly * Y) +{ + pb_poly M[TAB_SIZE], res; + mp_digit buf; + int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; + + /* find window size */ + x = mp_count_bits (X); + if (x <= 7) { + winsize = 2; + } else if (x <= 36) { + winsize = 3; + } else if (x <= 140) { + winsize = 4; + } else if (x <= 450) { + winsize = 5; + } else if (x <= 1303) { + winsize = 6; + } else if (x <= 3529) { + winsize = 7; + } else { + winsize = 8; + } + +#ifdef MP_LOW_MEM + if (winsize > 5) { + winsize = 5; + } +#endif + + /* init M array */ + /* init first cell */ + if ((err = pb_init(&M[1], &(Y->characteristic))) != MP_OKAY) { + return err; + } + + /* now init the second half of the array */ + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + if ((err = pb_init(&M[x], &(Y->characteristic))) != MP_OKAY) { + for (y = 1<<(winsize-1); y < x; y++) { + pb_clear (&M[y]); + } + pb_clear(&M[1]); + return err; + } + } + + /* create M table + * + * The M table contains powers of the base, + * e.g. M[x] = G**x mod P + * + * The first half of the table is not + * computed though accept for M[0] and M[1] + */ + + if (X->sign == MP_ZPOS) { + if ((err = pb_mod (G, P, &M[1])) != MP_OKAY) { goto __M; } + } else { + if ((err = pb_invmod(G, P, &M[1])) != MP_OKAY) { goto __M; } + } + + /* compute the value at M[1<<(winsize-1)] by squaring + * M[1] (winsize-1) times + */ + if ((err = pb_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { goto __M; } + + for (x = 0; x < (winsize - 1); x++) { + if ((err = pb_mulmod (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)], + P, &M[1 << (winsize - 1)])) != MP_OKAY) { goto __M; } + } + + /* create upper table, that is M[x] = M[x-1] * M[1] (mod P) + * for x = (2**(winsize - 1) + 1) to (2**winsize - 1) + */ + for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { + if ((err = pb_mulmod (&M[x - 1], &M[1], P, &M[x])) != MP_OKAY) { goto __M; } + } + + /* setup result */ + if ((err = pb_init (&res, &(Y->characteristic))) != MP_OKAY) { goto __M; } + mp_set (&(res.terms[0]), 1); res.used = 1; + + /* set initial mode and bit cnt */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = X->used - 1; + bitcpy = 0; + bitbuf = 0; + + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits */ + if (digidx == -1) { + break; + } + /* read next digit and reset the bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int) DIGIT_BIT; + } + + /* grab the next msb from the exponent */ + y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1; + buf <<= (mp_digit)1; + + /* if the bit is zero and mode == 0 then we ignore it + * These represent the leading zero bits before the first 1 bit + * in the exponent. Technically this opt is not required but it + * does lower the # of trivial squaring/reductions used + */ + if (mode == 0 && y == 0) { + continue; + } + + /* if the bit is zero and mode == 1 then we square */ + if (mode == 1 && y == 0) { + if ((err = pb_mulmod (&res, &res, P, &res)) != MP_OKAY) { goto __RES; } + continue; + } + + /* else we add it to the window */ + bitbuf |= (y << (winsize - ++bitcpy)); + mode = 2; + + if (bitcpy == winsize) { + /* ok window is filled so square as required and multiply */ + /* square first */ + for (x = 0; x < winsize; x++) { + if ((err = pb_mulmod (&res, &res, P, &res)) != MP_OKAY) { goto __RES; } + } + + /* then multiply */ + if ((err = pb_mulmod (&res, &M[bitbuf], P, &res)) != MP_OKAY) { goto __RES; } + + /* empty window and reset */ + bitcpy = 0; + bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then square/multiply */ + if (mode == 2 && bitcpy > 0) { + /* square then multiply if the bit is set */ + for (x = 0; x < bitcpy; x++) { + if ((err = pb_mulmod (&res, &res, P, &res)) != MP_OKAY) { goto __RES; } + + bitbuf <<= 1; + if ((bitbuf & (1 << winsize)) != 0) { + /* then multiply */ + if ((err = pb_mulmod (&res, &M[1], P, &res)) != MP_OKAY) { goto __RES; } + } + } + } + + pb_exch (&res, Y); + err = MP_OKAY; +__RES:pb_clear (&res); +__M: + pb_clear(&M[1]); + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + pb_clear (&M[x]); + } + return err; +} diff --git a/external/libtompoly-0.04/pb_exteuclid.c b/external/libtompoly-0.04/pb_exteuclid.c new file mode 100644 index 0000000..2fb6911 --- /dev/null +++ b/external/libtompoly-0.04/pb_exteuclid.c @@ -0,0 +1,74 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +/* Extended euclidean algorithm of (a, b) produces + a*u1 + b*u2 = u3 + */ +int pb_exteuclid(pb_poly *a, pb_poly *b, pb_poly *U1, pb_poly *U2, pb_poly *U3) +{ + pb_poly u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp; + int err; + + if ((err = pb_init_multi(&(b->characteristic), + &u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) { + return err; + } + + /* initialize, (u1,u2,u3) = (1,0,a) */ + mp_set(&(u1.terms[0]), 1); u1.used = 1; + if ((err = pb_copy(a, &u3)) != MP_OKAY) { goto _ERR; } + + /* initialize, (v1,v2,v3) = (0,1,b) */ + mp_set(&(v2.terms[0]), 1); v2.used = 1; + if ((err = pb_copy(b, &v3)) != MP_OKAY) { goto _ERR; } + + /* loop while v3 != 0 */ + while (v3.used > 0) { + /* q = u3/v3 */ + if ((err = pb_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto _ERR; } + + /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */ + if ((err = pb_mul(&v1, &q, &tmp)) != MP_OKAY) { goto _ERR; } + if ((err = pb_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto _ERR; } + if ((err = pb_mul(&v2, &q, &tmp)) != MP_OKAY) { goto _ERR; } + if ((err = pb_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto _ERR; } + if ((err = pb_mul(&v3, &q, &tmp)) != MP_OKAY) { goto _ERR; } + if ((err = pb_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto _ERR; } + + /* (u1,u2,u3) = (v1,v2,v3) */ + if ((err = pb_copy(&v1, &u1)) != MP_OKAY) { goto _ERR; } + if ((err = pb_copy(&v2, &u2)) != MP_OKAY) { goto _ERR; } + if ((err = pb_copy(&v3, &u3)) != MP_OKAY) { goto _ERR; } + + /* (v1,v2,v3) = (t1,t2,t3) */ + if ((err = pb_copy(&t1, &v1)) != MP_OKAY) { goto _ERR; } + if ((err = pb_copy(&t2, &v2)) != MP_OKAY) { goto _ERR; } + if ((err = pb_copy(&t3, &v3)) != MP_OKAY) { goto _ERR; } + } + + /* reduce U3 to monic but we have to mangle all three to remain consistent */ + pb_zero(&v1); + if ((err = mp_copy(&(u3.terms[u3.used-1]), &(v1.terms[0]))) != MP_OKAY) { goto _ERR; } + v1.used = 1; + + /* copy result out */ + if (U1 != NULL) { if ((err = pb_div(&u1, &v1, U1, NULL)) != MP_OKAY) { goto _ERR; }} + if (U2 != NULL) { if ((err = pb_div(&u2, &v1, U2, NULL)) != MP_OKAY) { goto _ERR; }} + if (U3 != NULL) { if ((err = pb_div(&u3, &v1, U3, NULL)) != MP_OKAY) { goto _ERR; }} + + err = MP_OKAY; +_ERR: pb_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL); + return err; +} + + diff --git a/external/libtompoly-0.04/pb_gcd.c b/external/libtompoly-0.04/pb_gcd.c new file mode 100644 index 0000000..12749b6 --- /dev/null +++ b/external/libtompoly-0.04/pb_gcd.c @@ -0,0 +1,69 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +/* returns the monic GCD only for GF(p^k)[x] */ +int pb_gcd(pb_poly *a, pb_poly *b, pb_poly *c) +{ + pb_poly A, B, tmp; + int err; + + if (mp_iszero(&(c->characteristic)) == MP_YES) { + return MP_VAL; + } + + /* special cases (one or both are zero) */ + if (a->used == 0 && b->used == 0) { + /* both zero, set to 1 */ + pb_zero(c); + c->used = 1; + mp_set(&(c->terms[0]), 1); + return MP_OKAY; + } else if (a->used == 0) { + return pb_copy(b, c); + } else if (b->used == 0) { + return pb_copy(a, c); + } + + if ((err = pb_init(&tmp, &(c->characteristic))) != MP_OKAY) { + return err; + } + if ((err = pb_init_copy(&A, a)) != MP_OKAY) { + goto __TMP; + } + if ((err = pb_init_copy(&B, b)) != MP_OKAY) { + goto __A; + } + + while (B.used > 0) { + if ((err = pb_mod(&A, &B, &tmp)) != MP_OKAY) { + goto __B; + } + /* A = B, B = tmp */ + if ((err = pb_copy(&B, &A)) != MP_OKAY) { + goto __B; + } + if ((err = pb_copy(&tmp, &B)) != MP_OKAY) { + goto __B; + } + } + + /* ensure it's monic */ + err = pb_monic(&A, c); + +__B : pb_clear(&B); +__A : pb_clear(&A); +__TMP: pb_clear(&tmp); + return err; +} + + diff --git a/external/libtompoly-0.04/pb_grow.c b/external/libtompoly-0.04/pb_grow.c new file mode 100644 index 0000000..b9e34e5 --- /dev/null +++ b/external/libtompoly-0.04/pb_grow.c @@ -0,0 +1,46 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +int pb_grow(pb_poly *a, int size) +{ + mp_int *tmp; + int x, err; + + if (a->alloc < size) { + /* pad size upwards */ + size += (PB_TERMS - (size % PB_TERMS)); + + /* regrow terms */ + tmp = realloc(a->terms, sizeof(mp_int) * size); + if (tmp == NULL) { + return MP_MEM; + } + a->terms = tmp; + + /* zero the new stuff (prevents mp_clear from double freeing) */ + memset(a->terms + a->alloc, 0, (size - a->alloc) * sizeof(mp_int)); + + /* now init the terms */ + for (x = a->alloc; x < size; x++) { + if ((err = mp_init(&(a->terms[x]))) != MP_OKAY) { + return err; + } + } + + /* update info */ + a->alloc = size; + } + return MP_OKAY; +} + + diff --git a/external/libtompoly-0.04/pb_init.c b/external/libtompoly-0.04/pb_init.c new file mode 100644 index 0000000..c312534 --- /dev/null +++ b/external/libtompoly-0.04/pb_init.c @@ -0,0 +1,49 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +/* initialize a */ +int pb_init(pb_poly *a, mp_int *characteristic) +{ + int x, y, err; + + /* init characteristic */ + if ((err = mp_init_copy(&(a->characteristic), characteristic)) != MP_OKAY) { + return err; + } + + /* now allocate an array of mp_ints */ + if ((a->terms = calloc(PB_TERMS, sizeof(mp_int))) == NULL) { + mp_clear(&(a->characteristic)); + return MP_MEM; + } + + /* now initialize them all */ + for (x = 0; x < PB_TERMS; x++) { + if ((err = mp_init(&(a->terms[x]))) != MP_OKAY) { + /* free stuff */ + for (y = 0; y < x; y++) { + mp_clear(&(a->terms[y])); + } + free(a->terms); + mp_clear(&(a->characteristic)); + return err; + } + } + + /* set our parameters */ + a->used = 0; + a->alloc = PB_TERMS; + return MP_OKAY; +} + + diff --git a/external/libtompoly-0.04/pb_init_copy.c b/external/libtompoly-0.04/pb_init_copy.c new file mode 100644 index 0000000..dc93f2f --- /dev/null +++ b/external/libtompoly-0.04/pb_init_copy.c @@ -0,0 +1,21 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +int pb_init_copy(pb_poly *a, pb_poly *b) +{ + int err; + if ((err = pb_init(a, &(b->characteristic))) != MP_OKAY) { + return err; + } + return pb_copy(b, a); +} diff --git a/external/libtompoly-0.04/pb_init_multi.c b/external/libtompoly-0.04/pb_init_multi.c new file mode 100644 index 0000000..f704b86 --- /dev/null +++ b/external/libtompoly-0.04/pb_init_multi.c @@ -0,0 +1,50 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include +#include + +int pb_init_multi(mp_int *characteristic, pb_poly *pb, ...) +{ + mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ + int n = 0; /* Number of ok inits */ + pb_poly* cur_arg = pb; + va_list args; + + va_start(args, pb); /* init args to next argument from caller */ + while (cur_arg != NULL) { + if (pb_init(cur_arg, characteristic) != MP_OKAY) { + /* Oops - error! Back-track and mp_clear what we already + succeeded in init-ing, then return error. + */ + va_list clean_args; + + /* end the current list */ + va_end(args); + + /* now start cleaning up */ + cur_arg = pb; + va_start(clean_args, pb); + while (n--) { + pb_clear(cur_arg); + cur_arg = va_arg(clean_args, pb_poly*); + } + va_end(clean_args); + res = MP_MEM; + break; + } + n++; + cur_arg = va_arg(args, pb_poly*); + } + va_end(args); + return res; /* Assumed ok, if error flagged above. */ +} + diff --git a/external/libtompoly-0.04/pb_init_size.c b/external/libtompoly-0.04/pb_init_size.c new file mode 100644 index 0000000..bf44027 --- /dev/null +++ b/external/libtompoly-0.04/pb_init_size.c @@ -0,0 +1,58 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +/* initialize a */ +int pb_init_size(pb_poly *a, mp_int *characteristic, int size) +{ + int x, y, err; + + /* enforce a minimum size */ + if (size < 1) { + size = 1; + } + + /* pad size upwards */ + size += (PB_TERMS - (size % PB_TERMS)); + + + /* init characteristic */ + if ((err = mp_init_copy(&(a->characteristic), characteristic)) != MP_OKAY) { + return err; + } + + /* now allocate an array of mp_ints */ + if ((a->terms = calloc(size, sizeof(mp_int))) == NULL) { + mp_clear(&(a->characteristic)); + return MP_MEM; + } + + /* now initialize them all */ + for (x = 0; x < size; x++) { + if ((err = mp_init(&(a->terms[x]))) != MP_OKAY) { + /* free stuff */ + for (y = 0; y < x; y++) { + mp_clear(&(a->terms[y])); + } + free(a->terms); + mp_clear(&(a->characteristic)); + return err; + } + } + + /* set our parameters */ + a->used = 0; + a->alloc = size; + return MP_OKAY; +} + + diff --git a/external/libtompoly-0.04/pb_invmod.c b/external/libtompoly-0.04/pb_invmod.c new file mode 100644 index 0000000..5607dec --- /dev/null +++ b/external/libtompoly-0.04/pb_invmod.c @@ -0,0 +1,33 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +int pb_invmod(pb_poly *a, pb_poly *b, pb_poly *c) +{ + int err; + pb_poly tmp; + + if ((err = pb_init(&tmp, &(c->characteristic))) != MP_OKAY) { + return err; + } + + if ((err = pb_exteuclid(a, b, c, NULL, &tmp)) != MP_OKAY) { goto _ERR; } + + /* if deg(tmp(x)) > 0 then there is no invmod */ + if (tmp.used > 1) { err = MP_VAL; goto _ERR; } + + err = MP_OKAY; +_ERR: pb_clear(&tmp); + return err; +} + + diff --git a/external/libtompoly-0.04/pb_isirreduc.c b/external/libtompoly-0.04/pb_isirreduc.c new file mode 100644 index 0000000..7600386 --- /dev/null +++ b/external/libtompoly-0.04/pb_isirreduc.c @@ -0,0 +1,59 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +/* is a(x) irreducible? */ +int pb_isirreduc(pb_poly *a, int *res) +{ + pb_poly u, tmp, fm, d; + int err, i; + + /* default to no */ + *res = MP_NO; + + /* init temps */ + if ((err = pb_init_multi(&(a->characteristic), + &u, &tmp, &fm, &d, NULL)) != MP_OKAY) { + return err; + } + + /* fm = monic(a(x)) */ + if ((err = pb_monic(a, &fm)) != MP_OKAY) { goto _ERR; } + + /* u = x */ + mp_set(&(u.terms[1]), 1); u.used = 2; + + /* loop */ + for (i = 1; i <= (a->used / 2); i++) { + /* u = u^p mod fm */ + if ((err = pb_exptmod(&u, &(a->characteristic), &fm, &u)) != MP_OKAY) { goto _ERR; } + + /* tmp = u - x */ + pb_zero(&tmp); + mp_set(&(tmp.terms[1]), 1); tmp.used = 2; + if ((err = pb_sub(&u, &tmp, &tmp)) != MP_OKAY) { goto _ERR; } + + /* d = gcd(fm, tmp) */ + if ((err = pb_gcd(&fm, &tmp, &d)) != MP_OKAY) { goto _ERR; } + + /* if d != 1 then reducible */ + if (d.used > 1) { err = MP_OKAY; goto _ERR; } + } + + /* irreducible */ + *res = MP_YES; + err = MP_OKAY; +_ERR: pb_clear_multi(&u, &tmp, &fm, &d, NULL); + return err; +} + + diff --git a/external/libtompoly-0.04/pb_lshd.c b/external/libtompoly-0.04/pb_lshd.c new file mode 100644 index 0000000..155b391 --- /dev/null +++ b/external/libtompoly-0.04/pb_lshd.c @@ -0,0 +1,42 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +int pb_lshd(pb_poly *a, int x) +{ + int err, y; + + if (x <= 0) { + return MP_OKAY; + } + + /* grow as required */ + if (a->alloc < (a->used + x)) { + if ((err = pb_grow(a, a->used + x)) != MP_OKAY) { + return err; + } + } + + /* shift */ + for (y = a->used + x; y >= x; y--) { + mp_exch(&(a->terms[y-x]), &(a->terms[y])); + } + + /* zero lower digits */ + for (y = 0; y < x; y++) { + mp_zero(&(a->terms[y])); + } + a->used += x; + + return MP_OKAY; +} + diff --git a/external/libtompoly-0.04/pb_mod.c b/external/libtompoly-0.04/pb_mod.c new file mode 100644 index 0000000..4be21e9 --- /dev/null +++ b/external/libtompoly-0.04/pb_mod.c @@ -0,0 +1,19 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +int pb_mod(pb_poly *a, pb_poly *b, pb_poly *c) +{ + return pb_div(a, b, NULL, c); +} + + diff --git a/external/libtompoly-0.04/pb_monic.c b/external/libtompoly-0.04/pb_monic.c new file mode 100644 index 0000000..19107bb --- /dev/null +++ b/external/libtompoly-0.04/pb_monic.c @@ -0,0 +1,60 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +/* makes b equal to the monic polynomial form of a */ +int pb_monic(pb_poly *a, pb_poly *b) +{ + mp_int tmp; + int err, x; + + /* must be in GF(p)[x] */ + if (mp_iszero(&(b->characteristic)) == MP_YES) { + return MP_VAL; + } + + /* if it's already monic just copy */ + if (a->used == 0 || mp_cmp_d(&(a->terms[a->used - 1]), 1) == MP_EQ) { + return pb_copy(a, b); + } + + /* grow b to hold result */ + if (b->alloc < a->used) { + if ((err = pb_grow(b, a->used)) != MP_OKAY) { + return err; + } + } + + /* now init tmp and find the inverse of the leading digit */ + if ((err = mp_init(&tmp)) != MP_OKAY) { + return err; + } + + if ((err = mp_invmod(&(a->terms[a->used-1]), &(b->characteristic), &tmp)) != MP_OKAY) { goto _ERR; } + + /* now reduce each coefficient */ + for (x = 0; x < a->used; x++) { + if ((err = mp_mulmod(&(a->terms[x]), &tmp, &(b->characteristic), &(b->terms[x]))) != MP_OKAY) { goto _ERR; } + } + + /* zero excess digits */ + for (x = a->used; x < b->used; x++) { + mp_zero(&(b->terms[x])); + } + b->used = a->used; + + err = MP_OKAY; +_ERR: mp_clear(&tmp); + return err; +} + + diff --git a/external/libtompoly-0.04/pb_mul.c b/external/libtompoly-0.04/pb_mul.c new file mode 100644 index 0000000..b215f54 --- /dev/null +++ b/external/libtompoly-0.04/pb_mul.c @@ -0,0 +1,62 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +int pb_mul(pb_poly *a, pb_poly *b, pb_poly *c) +{ + int err, x, y; + pb_poly tmp; + mp_int tmp2; + + /* make temp */ + if ((err = pb_init_size(&tmp, &(c->characteristic), a->used + b->used)) != MP_OKAY) { + return err; + } + + if ((err = mp_init(&tmp2)) != MP_OKAY) { + goto __TMP; + } + + /* multiply the terms */ + for (x = 0; x < a->used; x++) { + for (y = 0; y < b->used; y++) { + if ((err = mp_mul(&(a->terms[x]), &(b->terms[y]), &tmp2)) != MP_OKAY) { + goto __TMP2; + } + if ((err = mp_add(&tmp2, &(tmp.terms[x+y]), &(tmp.terms[x+y]))) != MP_OKAY) { + goto __TMP2; + } + } + } + + /* now reduce the terms as required */ + if (mp_iszero(&(c->characteristic)) == MP_NO) { + for (x = 0; x < (a->used + b->used); x++) { + if ((err = mp_mod(&(tmp.terms[x]), &(c->characteristic), &(tmp.terms[x]))) != MP_OKAY) { + goto __TMP2; + } + } + } + + /* set digit count */ + tmp.used = a->used + b->used; + pb_clamp(&tmp); + + /* exchange tmp and c */ + pb_exch(&tmp, c); + + err = MP_OKAY; + +__TMP2: mp_clear(&tmp2); +__TMP : pb_clear(&tmp); + return err; +} diff --git a/external/libtompoly-0.04/pb_mulmod.c b/external/libtompoly-0.04/pb_mulmod.c new file mode 100644 index 0000000..b960043 --- /dev/null +++ b/external/libtompoly-0.04/pb_mulmod.c @@ -0,0 +1,35 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +int pb_mulmod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d) +{ + int err; + pb_poly tmp; + + if ((err = pb_init(&tmp, &(d->characteristic))) != MP_OKAY) { + return err; + } + if ((err = pb_mul(a, b, &tmp)) != MP_OKAY) { + goto __TMP; + } + if ((err = pb_mod(&tmp, c, d)) != MP_OKAY) { + goto __TMP; + } + + err = MP_OKAY; +__TMP: pb_clear(&tmp); + return err; +} + + + diff --git a/external/libtompoly-0.04/pb_rawsize.c b/external/libtompoly-0.04/pb_rawsize.c new file mode 100644 index 0000000..43ccc76 --- /dev/null +++ b/external/libtompoly-0.04/pb_rawsize.c @@ -0,0 +1,32 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +int pb_rawsize(pb_poly *a) +{ + int x, y; + + /* 2 bytes for # of coefficients */ + y = 2; + + /* characteristic */ + y += 2 + mp_signed_bin_size(&(a->characteristic)); + + /* all of the terms */ + for (x = 0; x < a->used; x++) { + y += 2 + mp_signed_bin_size(&(a->terms[x])); + } + + return y; +} + + diff --git a/external/libtompoly-0.04/pb_readraw.c b/external/libtompoly-0.04/pb_readraw.c new file mode 100644 index 0000000..8e4b70a --- /dev/null +++ b/external/libtompoly-0.04/pb_readraw.c @@ -0,0 +1,55 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +int pb_readraw(pb_poly *a, unsigned char *buf, int len) +{ + int terms, x, y, z, err; + + /* zero poly */ + pb_zero(a); + + /* must be at least four bytes */ + if (len < 4) { + return MP_VAL; + } + + /* number of terms */ + terms = ((unsigned)buf[0]) | ((unsigned)buf[1]<<8); + y = 2; + + /* grow to the right size */ + if (a->alloc < terms) { + if ((err = pb_grow(a, terms)) != MP_OKAY) { + return err; + } + } + + /* read characteristic */ + z = ((unsigned)buf[y]) | ((unsigned)buf[y+1]<<8); y += 2; + if (z + y > len) { return MP_VAL; } + if ((err = mp_read_signed_bin(&(a->characteristic), buf+y, z)) != MP_OKAY) { return err; } + y += z; + + + /* read terms */ + for (x = 0; x < terms; x++) { + z = ((unsigned)buf[y]) | ((unsigned)buf[y+1]<<8); y += 2; + if (z + y > len) { return MP_VAL; } + if ((err = mp_read_signed_bin(&(a->characteristic), buf+y, z)) != MP_OKAY) { return err; } + y += z; + } + + return MP_OKAY; +} + + diff --git a/external/libtompoly-0.04/pb_rshd.c b/external/libtompoly-0.04/pb_rshd.c new file mode 100644 index 0000000..2662ab1 --- /dev/null +++ b/external/libtompoly-0.04/pb_rshd.c @@ -0,0 +1,38 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +int pb_rshd(pb_poly *a, int x) +{ + int y; + + if (x >= a->used) { + pb_zero(a); + return MP_OKAY; + } + + if (x <= 0) { + return MP_OKAY; + } + + for (y = x; y < a->used; y++) { + mp_exch(&(a->terms[y]), &(a->terms[y-x])); + } + + for (y = a->used - x; y < a->used; y++) { + mp_zero(&(a->terms[y])); + } + a->used -= x; + + return MP_OKAY; +} + diff --git a/external/libtompoly-0.04/pb_shrink.c b/external/libtompoly-0.04/pb_shrink.c new file mode 100644 index 0000000..68a3a58 --- /dev/null +++ b/external/libtompoly-0.04/pb_shrink.c @@ -0,0 +1,44 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +int pb_shrink(pb_poly *a) +{ + int err, x; + mp_int *tmp; + + /* first resize the array of terms */ + if (a->used != a->alloc && a->used > 0) { + /* free the mp_ints */ + for (x = a->used; x < a->alloc; x++) { + mp_clear(&(a->terms[x])); + } + + /* resize the array of pointers */ + tmp = realloc(a->terms, sizeof(mp_int) * a->used); + if (tmp == NULL) { + return MP_MEM; + } + a->terms = tmp; + a->alloc = a->used; + } + + /* now shrink each mp_int */ + for (x = 0; x < a->used; x++) { + if ((err = mp_shrink(&(a->terms[x]))) != MP_OKAY) { + return err; + } + } + return MP_OKAY; +} + + diff --git a/external/libtompoly-0.04/pb_sub.c b/external/libtompoly-0.04/pb_sub.c new file mode 100644 index 0000000..b82a2e8 --- /dev/null +++ b/external/libtompoly-0.04/pb_sub.c @@ -0,0 +1,86 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +int pb_sub(pb_poly *a, pb_poly *b, pb_poly *c) +{ + int neg, err, x, y, z, characteristic; + pb_poly *tmp; + + /* grow c to be the max size */ + y = MAX(a->used, b->used); + if (c->alloc < y) { + if ((err = pb_grow(c, y)) != MP_OKAY) { + return err; + } + } + + /* do we need to concern char */ + characteristic = mp_iszero(&(c->characteristic)); + + /* sub the terms */ + z = MIN(a->used, b->used); + for (x = 0; x < z; x++) { + if ((err = mp_sub(&(a->terms[x]), &(b->terms[x]), &(c->terms[x]))) != MP_OKAY) { + return err; + } + if (characteristic == MP_NO) { + if ((err = mp_mod(&(c->terms[x]), &(c->characteristic), &(c->terms[x]))) != MP_OKAY) { + return err; + } + } + } + + /* excess digits? */ + if (y != z) { + if (a->used == y) { + tmp = a; + neg = 0; + } else { + tmp = b; + neg = 1; + } + for (x = z; x < y; x++) { + if (characteristic == MP_NO) { + if ((err = mp_mod(&(tmp->terms[x]), &(c->characteristic), &(c->terms[x]))) != MP_OKAY) { + return err; + } + if (neg) { + if ((err = mp_sub(&(c->characteristic), &(c->terms[x]), &(c->terms[x]))) != MP_OKAY) { + return err; + } + } + } else { + if (neg) { + if ((err = mp_neg(&(tmp->terms[x]), &(c->terms[x]))) != MP_OKAY) { + return err; + } + } else { + if ((err = mp_copy(&(tmp->terms[x]), &(c->terms[x]))) != MP_OKAY) { + return err; + } + } + } + } + } + + /* zero excess */ + for (x = y; x < c->used; x++) { + mp_zero(&(c->terms[x])); + } + c->used = y; + pb_clamp(c); + + return MP_OKAY; +} + + diff --git a/external/libtompoly-0.04/pb_submod.c b/external/libtompoly-0.04/pb_submod.c new file mode 100644 index 0000000..bfa2f8e --- /dev/null +++ b/external/libtompoly-0.04/pb_submod.c @@ -0,0 +1,35 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +int pb_submod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d) +{ + int err; + pb_poly tmp; + + if ((err = pb_init(&tmp, &(d->characteristic))) != MP_OKAY) { + return err; + } + if ((err = pb_sub(a, b, &tmp)) != MP_OKAY) { + goto __TMP; + } + if ((err = pb_mod(&tmp, c, d)) != MP_OKAY) { + goto __TMP; + } + + err = MP_OKAY; +__TMP: pb_clear(&tmp); + return err; +} + + + diff --git a/external/libtompoly-0.04/pb_toraw.c b/external/libtompoly-0.04/pb_toraw.c new file mode 100644 index 0000000..8c0c63f --- /dev/null +++ b/external/libtompoly-0.04/pb_toraw.c @@ -0,0 +1,42 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +int pb_toraw(pb_poly *a, unsigned char *dst) +{ + int err, x, y, z; + + /* store the # of terms */ + dst[0] = a->used & 255; + dst[1] = (a->used >> 8) & 255; + y = 2; + + /* store the characteristic */ + z = mp_signed_bin_size(&(a->characteristic)); + dst[y++] = z&255; + dst[y++] = (z>>8)&255; + if ((err = mp_to_signed_bin(&(a->characteristic), dst+y)) != MP_OKAY) { return err; } + y += z; + + for (x = 0; x < a->used; x++) { + z = mp_signed_bin_size(&(a->terms[x])); + dst[y++] = z&255; + dst[y++] = (z>>8)&255; + if ((err = mp_to_signed_bin(&(a->terms[x]), dst+y)) != MP_OKAY) { return err; } + y += z; + } + + return MP_OKAY; +} + + + diff --git a/external/libtompoly-0.04/pb_zero.c b/external/libtompoly-0.04/pb_zero.c new file mode 100644 index 0000000..ca51a91 --- /dev/null +++ b/external/libtompoly-0.04/pb_zero.c @@ -0,0 +1,23 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#include + +void pb_zero(pb_poly *a) +{ + int x; + for (x = 0; x < a->used; x++) { + mp_zero(&(a->terms[x])); + } + a->used = 0; +} + + diff --git a/external/libtompoly-0.04/tompoly.h b/external/libtompoly-0.04/tompoly.h new file mode 100644 index 0000000..646a903 --- /dev/null +++ b/external/libtompoly-0.04/tompoly.h @@ -0,0 +1,115 @@ +/* LibTomPoly, Polynomial Basis Math -- Tom St Denis + * + * LibTomPoly is a public domain library that provides + * polynomial basis arithmetic support. It relies on + * LibTomMath for large integer support. + * + * This library is free for all purposes without any + * express guarantee that it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org + */ +#ifndef TOMPOLY_H_ +#define TOMPOLY_H_ + +#include + +/* this structure holds a polynomial */ +typedef struct { + int used, /* number of terms */ + alloc; /* number of terms available (total) */ + mp_int characteristic, /* characteristic, zero if not finite */ + *terms; /* terms of polynomial */ +} pb_poly; + + +/* default number of terms */ +#define PB_TERMS 4 + +/* Compare codes */ +#define PB_EQ 0 /* They're exactly equal */ +#define PB_DEG_LT 1 /* The left has a lower degree */ +#define PB_DEG_EQ 2 /* same degree */ +#define PB_DEG_GT 3 /* The left has a higher degree */ + +int pb_init(pb_poly *a, mp_int *characteristic); +int pb_init_size(pb_poly *a, mp_int *characteristic, int size); +int pb_init_copy(pb_poly *a, pb_poly *b); +int pb_init_multi(mp_int *characteristic, pb_poly *pb, ...); +void pb_clear_multi(pb_poly *mp, ...); +void pb_clear(pb_poly *a); + +int pb_shrink(pb_poly *a); +int pb_grow(pb_poly *a, int size); +void pb_clamp(pb_poly *a); + +/* dest(x) := src(x) */ +int pb_copy(pb_poly *src, pb_poly *dest); + +/* compare these */ +int pb_cmp(pb_poly *a, pb_poly *b); + +/* swap contents of a(x) and b(x) */ +void pb_exch(pb_poly *a, pb_poly *b); + +/* a(x) = 0 */ +void pb_zero(pb_poly *a); + +/* a(x) = a(x) / I(x)^x */ +int pb_rshd(pb_poly *a, int x); + +/* a(x) = a(x) * I(x)^x */ +int pb_lshd(pb_poly *a, int x); + +/* c(x) = a(x) + b(x) */ +int pb_add(pb_poly *a, pb_poly *b, pb_poly *c); + +/* c(x) = a(x) - b(x) */ +int pb_sub(pb_poly *a, pb_poly *b, pb_poly *c); + +/* c(x) = a(x) * b(x) */ +int pb_mul(pb_poly *a, pb_poly *b, pb_poly *c); + +/* c(x) * b(x) + d(x) = a(x) */ +int pb_div(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); + +/* c(x) = a(x) mod b(x) */ +int pb_mod(pb_poly *a, pb_poly *b, pb_poly *c); + +/* d(x) = (a(x) + b(x)) mod c(x) */ +int pb_addmod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); + +/* d(x) = (a(x) - b(x)) mod c(x) */ +int pb_submod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); + +/* d(x) = (a(x) * b(x)) mod c(x) */ +int pb_mulmod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); + + +/* mathy stuff */ + +/* makes b equal to the monic polynomial form of a */ +int pb_monic(pb_poly *a, pb_poly *b); + +/* returns the monic GCD of a,b in GF(p^k)[x] */ +int pb_gcd(pb_poly *a, pb_poly *b, pb_poly *c); + +/* Extended euclidean algorithm of (a, b) produces a*u1 + b*u2 = u3 */ +int pb_exteuclid(pb_poly *a, pb_poly *b, pb_poly *U1, pb_poly *U2, pb_poly *U3); + +/* finds the inverse of a modulo b and stores it in c such that a*c == 1 mod b */ +int pb_invmod(pb_poly *a, pb_poly *b, pb_poly *c); + +/* computes Y == G^X mod P [accepts negative values for X] */ +int pb_exptmod (pb_poly * G, mp_int * X, pb_poly * P, pb_poly * Y); + +/* is a(x) irreducible (GF(p)[x] only) */ +int pb_isirreduc(pb_poly *a, int *res); + + +/* I/O */ +int pb_rawsize(pb_poly *a); +int pb_toraw(pb_poly *a, unsigned char *dst); +int pb_readraw(pb_poly *a, unsigned char *buf, int len); + +#endif