├── LICENSE ├── README.md ├── changes.txt ├── demo └── demo.c ├── makefile ├── makefile.msvc ├── pb.pdf ├── pb.tex ├── pb_add.c ├── pb_addmod.c ├── pb_clamp.c ├── pb_clear.c ├── pb_clear_multi.c ├── pb_cmp.c ├── pb_copy.c ├── pb_div.c ├── pb_exch.c ├── pb_exptmod.c ├── pb_exteuclid.c ├── pb_gcd.c ├── pb_grow.c ├── pb_init.c ├── pb_init_copy.c ├── pb_init_multi.c ├── pb_init_size.c ├── pb_invmod.c ├── pb_isirreduc.c ├── pb_lshd.c ├── pb_mod.c ├── pb_monic.c ├── pb_mul.c ├── pb_mulmod.c ├── pb_rawsize.c ├── pb_readraw.c ├── pb_rshd.c ├── pb_shrink.c ├── pb_sub.c ├── pb_submod.c ├── pb_toraw.c ├── pb_zero.c └── tompoly.h /LICENSE: -------------------------------------------------------------------------------- 1 | LibTomPoly is licensed under DUAL licensing terms. 2 | 3 | Choose and use the license of your needs. 4 | 5 | [LICENSE #1] 6 | 7 | LibTomPoly is public domain. As should all quality software be. 8 | 9 | Tom St Denis 10 | 11 | [/LICENSE #1] 12 | 13 | [LICENSE #2] 14 | 15 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 16 | Version 2, December 2004 17 | 18 | Copyright (C) 2004 Sam Hocevar 19 | 20 | Everyone is permitted to copy and distribute verbatim or modified 21 | copies of this license document, and changing it is allowed as long 22 | as the name is changed. 23 | 24 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 25 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 26 | 27 | 0. You just DO WHAT THE FUCK YOU WANT TO. 28 | 29 | [/LICENSE #2] 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | libtompoly 2 | ========== 3 | 4 | Chapter 1.1 taken from pb.pdf 5 | 6 | What is LibTomPoly? 7 | ------------------- 8 | 9 | LibTomPoly is a public domain open source library to provide polynomial basis 10 | arithmetic. It uses the public domain library LibTomMath (not included) 11 | for the integer arithmetic and extends the functonality to provide polynomial 12 | arithmetic. 13 | -------------------------------------------------------------------------------- /changes.txt: -------------------------------------------------------------------------------- 1 | May 5th, 2004 2 | v0.04 - Fixed a bug in pb_monic() which for zero valued inputs could cause a segfault 3 | - Daniel Richards (kyhwana@kyhwana.org) found several typos in the manual. 4 | - Fixed bug in pb_shrink() that would leak memory 5 | 6 | Jan 25th, 2004 7 | v0.03 - Added pb_rawsize(), pb_readraw(), pb_toraw() 8 | - Fixed bug in pb_monic() where it would only check the first [not leading] coefficient for one 9 | 10 | Jan 3rd, 2004 11 | v0.02 - Update pb_div() to shift r(x) after multplying it wit b(x) to save a bit of time 12 | - improved pb_gcd() to handle inputs which are zero 13 | - Added pb_shrink() 14 | - fixed pb_invmod() 15 | - added pb_exteuclid() [back ported that code into LTM... hehehe] 16 | - added pb_exptmod() [this led me to find a bug in LTM!!!] 17 | - added pb_monic() 18 | - added pb_isirreduc() 19 | - Some minor additions to test/documentation 20 | 21 | Dec 31st, 2003 22 | v0.01 ++ thanks goes to Martin Marcel, Greg Rose and Colin Percival for providing some missing knowledge and 23 | helping me get this release going 24 | - Initial release. 25 | -------------------------------------------------------------------------------- /demo/demo.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void draw_poly(pb_poly *a) 4 | { 5 | int x; 6 | char buf[8192]; 7 | 8 | if (a->used == 0) { 9 | printf("0"); 10 | } else { 11 | for (x = a->used - 1; x >= 0; x--) { 12 | if (mp_iszero(&(a->terms[x])) == MP_YES) continue; 13 | mp_toradix(&(a->terms[x]), buf, 10); 14 | if ((x != a->used - 1) && a->terms[x].sign == MP_ZPOS) { 15 | printf("+"); 16 | } 17 | printf(" %sx^%d ", buf, x); 18 | } 19 | } 20 | if (mp_iszero(&(a->characteristic)) == MP_NO) { 21 | mp_toradix(&(a->characteristic), buf, 10); 22 | printf(" (mod %s)", buf); 23 | } 24 | printf("\n"); 25 | } 26 | 27 | int main(void) 28 | { 29 | mp_int chara; 30 | pb_poly a,b,c,d,e; 31 | mp_int aa,bb,cc,dd,ee; 32 | int res; 33 | 34 | mp_init(&chara); 35 | mp_init_multi(&aa,&bb,&cc,&dd,&ee,NULL); 36 | pb_init_size(&a, &chara, 32); 37 | pb_init_size(&b, &chara, 32); 38 | pb_init_size(&c, &chara, 32); 39 | pb_init_size(&d, &chara, 32); 40 | pb_init_size(&e, &chara, 32); 41 | 42 | /* a = 3x + 4 */ 43 | mp_set(&(a.terms[1]), 3); 44 | mp_set(&(a.terms[0]), 4); 45 | a.used = 2; 46 | pb_clamp(&a); 47 | printf("a == \n"); 48 | draw_poly(&a); 49 | 50 | /* b = 7x^2 + 5x + 7 */ 51 | mp_set(&(b.terms[2]), 7); 52 | mp_set(&(b.terms[1]), 5); 53 | mp_set(&(b.terms[0]), 7); 54 | b.used = 3; 55 | pb_clamp(&b); 56 | printf("b == \n"); 57 | draw_poly(&b); 58 | 59 | /* c = a + b */ 60 | printf("a + b\n"); 61 | pb_add(&a, &b, &c); 62 | draw_poly(&c); 63 | 64 | /* c = b + a */ 65 | printf("b + a\n"); 66 | pb_add(&b, &a, &c); 67 | draw_poly(&c); 68 | 69 | /* now test clearing */ 70 | printf("Shifting previous up one\n"); 71 | pb_lshd(&c, 1); 72 | draw_poly(&c); 73 | pb_rshd(&c, 1); 74 | draw_poly(&c); 75 | pb_lshd(&c, 1); 76 | pb_add(&a, &b, &c); 77 | printf("previous add (test if excess cleared)\n"); 78 | draw_poly(&c); 79 | 80 | /* multiply */ 81 | printf("Multiply:\n"); 82 | draw_poly(&a); 83 | draw_poly(&b); 84 | pb_mul(&a, &b, &c); 85 | draw_poly(&c); 86 | 87 | /* subtract */ 88 | printf("a - b\n"); 89 | pb_sub(&a, &b, &c); 90 | draw_poly(&c); 91 | printf("b - a\n"); 92 | pb_sub(&b, &a, &c); 93 | draw_poly(&c); 94 | 95 | 96 | /* now hijack the char */ 97 | mp_set(&(a.characteristic), 17); 98 | mp_set(&(b.characteristic), 17); 99 | mp_set(&(c.characteristic), 17); 100 | mp_set(&(d.characteristic), 17); 101 | mp_set(&(e.characteristic), 17); 102 | 103 | /* perform modular addition */ 104 | printf("a + b (in GF(17))\n"); 105 | pb_add(&a, &b, &c); 106 | draw_poly(&c); 107 | pb_add(&b, &a, &c); 108 | draw_poly(&c); 109 | 110 | /* perform modular subtaction */ 111 | printf("a - b (in GF(17))\n"); 112 | pb_sub(&a, &b, &c); 113 | draw_poly(&c); 114 | printf("b - a (in GF(17))\n"); 115 | pb_sub(&b, &a, &c); 116 | draw_poly(&c); 117 | 118 | /* perform division */ 119 | printf("Division (b/a)\n"); 120 | pb_div(&b, &a, &c, &d); 121 | draw_poly(&a); 122 | draw_poly(&b); 123 | printf("Q == \n"); draw_poly(&c); 124 | printf("R == \n"); draw_poly(&d); 125 | 126 | /* now test it */ 127 | pb_mul(&a, &c, &c); 128 | pb_add(&c, &d, &c); 129 | printf("aQ + R =\n"); draw_poly(&c); 130 | 131 | /* test mod */ 132 | pb_mod(&b, &a, &c); 133 | printf("b mod a == "); draw_poly(&c); 134 | 135 | /* test GCD of (x^2 - 1) and 5*x^4+5*x^3+7*x^2+8*x+1 [should be x+1] */ 136 | printf("GCD Test\n"); 137 | pb_zero(&a); 138 | mp_set(&(a.terms[2]), 1); 139 | mp_set(&(a.terms[0]), 16); 140 | a.used = 3; 141 | pb_clamp(&a); 142 | printf("a == \n"); 143 | draw_poly(&a); 144 | 145 | pb_zero(&b); 146 | mp_set(&(b.terms[4]), 5); 147 | mp_set(&(b.terms[3]), 5); 148 | mp_set(&(b.terms[2]), 7); 149 | mp_set(&(b.terms[1]), 8); 150 | mp_set(&(b.terms[0]), 1); 151 | b.used = 6; 152 | pb_clamp(&b); 153 | printf("b == \n"); 154 | draw_poly(&b); 155 | 156 | pb_gcd(&a, &b, &c); 157 | printf("GCD: "); draw_poly(&c); 158 | 159 | /* test GCD */ 160 | pb_div(&a, &c, &d, &e); 161 | 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); 162 | pb_div(&b, &c, &d, &e); 163 | 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); 164 | 165 | /* test modular inverse... x^2 + 3 or so should work nice */ 166 | printf("Modular Inverse\n"); 167 | pb_zero(&a); 168 | mp_set(&(a.terms[2]), 1); 169 | mp_set(&(a.terms[1]), 0); 170 | mp_set(&(a.terms[0]), 3); 171 | a.used = 3; 172 | pb_clamp(&a); 173 | printf("a == \n"); 174 | draw_poly(&a); 175 | 176 | /* take inverse of 2x + 9 */ 177 | pb_zero(&b); 178 | mp_set(&(b.terms[1]), 2); 179 | mp_set(&(b.terms[0]), 9); 180 | b.used = 2; 181 | pb_clamp(&b); 182 | printf("b == \n"); 183 | draw_poly(&b); 184 | 185 | /* invert */ 186 | pb_invmod(&b, &a, &c); 187 | printf("Inverse\n"); 188 | draw_poly(&c); 189 | 190 | /* test */ 191 | pb_mulmod(&b, &c, &a, &d); 192 | pb_mul(&b, &c, &e); 193 | printf("This should be 1 : "); draw_poly(&d); 194 | printf("This should be equal to k*a + 1: "); draw_poly(&e); 195 | 196 | /* now b has order [dividing] 17^2 - 1 == 288 so b^287 should equal c */ 197 | printf("exptmod test\n"); 198 | mp_set(&aa, 287); 199 | pb_exptmod(&b, &aa, &a, &d); 200 | printf("This should be invmod : "); draw_poly(&d); 201 | 202 | /* test irreduc */ 203 | printf("Irreducibility testing\n"); 204 | pb_isirreduc(&a, &res); 205 | printf("This should be 1 : %d\n", res); 206 | 207 | pb_isirreduc(&b, &res); 208 | printf("This should be 0 : %d\n", res); 209 | 210 | 211 | 212 | return EXIT_SUCCESS; 213 | } 214 | 215 | 216 | 217 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | #Makefile for GCC by Tom St Denis 2 | CFLAGS += -I. -Os -Wall -W 3 | 4 | VERSION=0.04 5 | 6 | #default files to install 7 | LIBNAME=libtompoly.a 8 | HEADERS=tompoly.h 9 | 10 | #LIBPATH-The directory for libtomcrypt to be installed to. 11 | #INCPATH-The directory to install the header files for libtommath. 12 | #DATAPATH-The directory to install the pdf docs. 13 | DESTDIR= 14 | LIBPATH=/usr/lib 15 | INCPATH=/usr/include 16 | DATAPATH=/usr/share/doc/libtompoly/pdf 17 | 18 | default: libtompoly.a 19 | 20 | OBJECTS = pb_init.o pb_clear.o pb_init_size.o pb_grow.o pb_copy.o pb_clamp.o pb_init_copy.o \ 21 | 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 \ 22 | pb_addmod.o pb_submod.o pb_mulmod.o pb_gcd.o pb_init_multi.o pb_clear_multi.o pb_invmod.o \ 23 | pb_cmp.o pb_shrink.o pb_exteuclid.o pb_monic.o pb_exptmod.o pb_isirreduc.o pb_rawsize.o \ 24 | pb_toraw.o pb_readraw.o 25 | 26 | libtompoly.a: $(OBJECTS) 27 | ar $(ARFLAGS) libtompoly.a $(OBJECTS) 28 | 29 | install: libtompoly.a 30 | install -d -g root -o root $(DESTDIR)$(LIBPATH) 31 | install -d -g root -o root $(DESTDIR)$(INCPATH) 32 | install -g root -o root $(LIBNAME) $(DESTDIR)$(LIBPATH) 33 | install -g root -o root $(HEADERS) $(DESTDIR)$(INCPATH) 34 | 35 | demo: demo/demo.o libtompoly.a 36 | gcc demo/demo.o libtompoly.a -ltommath -o pbdemo 37 | 38 | mandvi: pb.tex 39 | echo "hello" > pb.ind 40 | latex pb > /dev/null 41 | latex pb > /dev/null 42 | makeindex pb 43 | latex pb > /dev/null 44 | 45 | manual: mandvi 46 | pdflatex pb >/dev/null 47 | 48 | clean: 49 | rm -f *.o *.a *.obj *.lib *.exe pbdemo demo/*.o demo/*.obj demo/*.exe 50 | rm -f *.idx *.ilg *.ind *.lof *.out *.toc *.dvi *.log *.aux 51 | 52 | zipup: manual clean 53 | cd .. ; rm -rf ltp* libtompoly-$(VERSION) ; mkdir libtompoly-$(VERSION) ; \ 54 | cp -R ./libtompoly/* ./libtompoly-$(VERSION)/ ; \ 55 | tar -c libtompoly-$(VERSION)/* | bzip2 -9vvc > ltp-$(VERSION).tar.bz2 ; \ 56 | zip -9 -r ltp-$(VERSION).zip libtompoly-$(VERSION)/* 57 | -------------------------------------------------------------------------------- /makefile.msvc: -------------------------------------------------------------------------------- 1 | #Makefile for MSVC by Tom St Denis 2 | CFLAGS = /W3 /Ox /I. 3 | 4 | default: tompoly.lib 5 | 6 | OBJECTS = pb_init.obj pb_clear.obj pb_init_size.obj pb_grow.obj pb_copy.obj pb_clamp.obj pb_init_copy.obj \ 7 | 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 \ 8 | pb_addmod.obj pb_submod.obj pb_mulmod.obj pb_gcd.obj pb_init_multi.obj pb_clear_multi.obj pb_invmod.obj \ 9 | pb_cmp.obj pb_shrink.obj pb_exteuclid.obj pb_monic.obj pb_exptmod.obj pb_isirreduc.obj pb_rawsize.obj \ 10 | pb_toraw.obj pb_readraw.obj 11 | 12 | tompoly.lib: $(OBJECTS) 13 | lib /out:tompoly.lib $(OBJECTS) 14 | 15 | demo: demo/demo.obj tompoly.lib 16 | cl demo.obj tompoly.lib tommath.lib 17 | 18 | -------------------------------------------------------------------------------- /pb.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libtom/libtompoly/a026b0fa080f9edf9e10e6ca09f1f7276a5a0d0c/pb.pdf -------------------------------------------------------------------------------- /pb.tex: -------------------------------------------------------------------------------- 1 | \documentclass[b5paper]{book} 2 | \usepackage{hyperref} 3 | \usepackage{makeidx} 4 | \usepackage{amssymb} 5 | \usepackage{color} 6 | \usepackage{alltt} 7 | \usepackage{graphicx} 8 | \usepackage{layout} 9 | \def\union{\cup} 10 | \def\intersect{\cap} 11 | \def\getsrandom{\stackrel{\rm R}{\gets}} 12 | \def\cross{\times} 13 | \def\cat{\hspace{0.5em} \| \hspace{0.5em}} 14 | \def\catn{$\|$} 15 | \def\divides{\hspace{0.3em} | \hspace{0.3em}} 16 | \def\nequiv{\not\equiv} 17 | \def\approx{\raisebox{0.2ex}{\mbox{\small $\sim$}}} 18 | \def\lcm{{\rm lcm}} 19 | \def\gcd{{\rm gcd}} 20 | \def\log{{\rm log}} 21 | \def\ord{{\rm ord}} 22 | \def\abs{{\mathit abs}} 23 | \def\rep{{\mathit rep}} 24 | \def\mod{{\mathit\ mod\ }} 25 | \renewcommand{\pmod}[1]{\ ({\rm mod\ }{#1})} 26 | \newcommand{\floor}[1]{\left\lfloor{#1}\right\rfloor} 27 | \newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil} 28 | \def\Or{{\rm\ or\ }} 29 | \def\And{{\rm\ and\ }} 30 | \def\iff{\hspace{1em}\Longleftrightarrow\hspace{1em}} 31 | \def\implies{\Rightarrow} 32 | \def\undefined{{\rm ``undefined"}} 33 | \def\Proof{\vspace{1ex}\noindent {\bf Proof:}\hspace{1em}} 34 | \let\oldphi\phi 35 | \def\phi{\varphi} 36 | \def\Pr{{\rm Pr}} 37 | \newcommand{\str}[1]{{\mathbf{#1}}} 38 | \def\F{{\mathbb F}} 39 | \def\N{{\mathbb N}} 40 | \def\Z{{\mathbb Z}} 41 | \def\R{{\mathbb R}} 42 | \def\C{{\mathbb C}} 43 | \def\Q{{\mathbb Q}} 44 | \definecolor{DGray}{gray}{0.5} 45 | \newcommand{\emailaddr}[1]{\mbox{$<${#1}$>$}} 46 | \def\twiddle{\raisebox{0.3ex}{\mbox{\tiny $\sim$}}} 47 | \def\gap{\vspace{0.5ex}} 48 | \makeindex 49 | \begin{document} 50 | \frontmatter 51 | \pagestyle{empty} 52 | \title{LibTomPoly User Manual \\ v0.04} 53 | \author{Tom St Denis \\ tomstdenis@iahu.ca} 54 | \maketitle 55 | This text and library are hereby placed in the public domain. This book has been 56 | formatted for B5 [176x250] paper using the \LaTeX{} {\em book} macro package. 57 | 58 | \vspace{10cm} 59 | 60 | \begin{flushright}Open Source. Open Academia. Open Minds. 61 | 62 | \mbox{ } 63 | 64 | Tom St Denis, 65 | 66 | Ontario, Canada 67 | \end{flushright} 68 | 69 | \tableofcontents 70 | \listoffigures 71 | \mainmatter 72 | \pagestyle{headings} 73 | \chapter{Introduction} 74 | \section{What is LibTomPoly?} 75 | LibTomPoly is a public domain open source library to provide polynomial basis arithmetic. It uses the public domain 76 | library LibTomMath (not included) for the integer arithmetic and extends the functonality to provide polynomial arithmetic. 77 | 78 | Technically speaking the library allows the user to perform arithmetic on elements from the group $GF(p)[x]$ and to 79 | a lesser extent (this will change in the future) over $\Z[x]$. Essentially the math you can do with integers (including 80 | forming rings and fields) you can do with with polynomials and now you can do with LibTomPoly. 81 | 82 | \section{License} 83 | LibTomPoly is public domain. Enjoy. 84 | 85 | \section{Terminology} 86 | Throughout this manual and within the library there will be some terminology that not everyone is familiar with. It is afterall 87 | weird math. 88 | 89 | \begin{figure}[here] 90 | \begin{center} 91 | \begin{small} 92 | \begin{tabular}{|l|l|} 93 | \hline \textbf{Term} & \textbf{Definition} \\ 94 | \hline monic polynomial & A polynomial where the leading coefficient is a one. \\ 95 | \hline irreducible polynomial & A polynomial that has no factors in a given group. \\ 96 | & For instance, $x^2 + 4$ is irreducible in $\Z[x]$ but not \\ 97 | & in $GF(17)[x]$ since $x^2 + 4 = (x+8)(x+9) \mbox{ (mod }17\mbox{)}$. \\ 98 | \hline primitive polynomial & An irreducible polynomial which generates all of \\ 99 | & elements of a given field (e.g. $GF(p)[x]/v(x)$) \\ 100 | \hline characteristic & An integer $k$ such that $k \cdot p(x) \equiv 0$ \\ 101 | \hline deg() & Functon returns degree of polynomial, e.g. deg($x^6 + x^3 + 1$) = 6 \\ 102 | \hline 103 | \end{tabular} 104 | \end{small} 105 | \end{center} 106 | \caption{Terminology} 107 | \end{figure} 108 | 109 | \section{Building the Library} 110 | The library is not ready for production yet but you can test out the library manually if you want. To build the library 111 | simply type 112 | 113 | \begin{alltt} 114 | make 115 | \end{alltt} 116 | 117 | Which will build ``libtompoly.a''. To build a Win32 library with MSVC type 118 | 119 | \begin{alltt} 120 | nmake -f makefile.msvc 121 | \end{alltt} 122 | 123 | To build against this library include ``tompoly.h'' and link against ``libtompoly.a'' (or tommath.lib as appropriate). 124 | To build the included demo type 125 | 126 | \begin{alltt} 127 | make demo 128 | \end{alltt} 129 | 130 | Which will build ``demo'' in the current directory. The demo is not interactive and produces results which must be manually 131 | inspected. 132 | 133 | \chapter{Getting Started} 134 | 135 | \section{The LibTomMath Connection} 136 | LibTomPoly is really just an extension of LibTomMath\footnote{\url{http://math.libtomcrypt.org}}. As such the library has 137 | been designed in much the same way as far as argument passing and error handling events are concerned. The reader is 138 | encouraged to become familiar with LibTomMath before diving into LibTomPoly. 139 | 140 | \section{The pb\_poly structure} 141 | A polynomial can characterized by a few variables. Given the C structure as follows 142 | 143 | \begin{alltt} 144 | typedef struct \{ 145 | int used, /* number of terms */ 146 | alloc; /* number of terms available (total) */ 147 | mp_int characteristic, /* characteristic, zero if not finite */ 148 | *terms; /* terms of polynomial */ 149 | \} pb_poly; 150 | \end{alltt} 151 | 152 | \begin{enumerate} 153 | \item The \textbf{used} member indicates how many terms of the \textbf{terms} array are used to represent the polynomial. 154 | \item The \textbf{alloc} member indicates the size of the \textbf{terms} array. Also note that even if \textbf{used} 155 | is less than \textbf{alloc} the mp\_ints above \textbf{used} in the array must be set to a valid representation 156 | of zero. 157 | \item The \textbf{characteristic} member is an mp\_int representing the characteristic of the polynomial. If the desire is to 158 | have a null characteristic (e.g. $\Z[x]$) this element must still be initialized to a valid representation 159 | of zero. 160 | \item The \textbf{terms} member is a dynamically sized array of mp\_int values which represent the coefficients for 161 | 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$. 162 | \end{enumerate} 163 | 164 | \section{Return Codes} 165 | The library uses the return codes from LibTomMath. They are 166 | 167 | \index{MP\_OKAY}\index{MP\_YES}\index{MP\_NO}\index{MP\_VAL}\index{MP\_MEM} 168 | \begin{figure}[here!] 169 | \begin{center} 170 | \begin{small} 171 | \begin{tabular}{|l|l|} 172 | \hline \textbf{Code} & \textbf{Meaning} \\ 173 | \hline MP\_OKAY & The function succeeded. \\ 174 | \hline MP\_VAL & The function input was invalid. \\ 175 | \hline MP\_MEM & Heap memory exhausted. \\ 176 | \hline &\\ 177 | \hline MP\_YES & Response is yes. \\ 178 | \hline MP\_NO & Response is no. \\ 179 | \hline 180 | \end{tabular} 181 | \end{small} 182 | \end{center} 183 | \caption{Return Codes} 184 | \end{figure} 185 | 186 | \section{Function Argument Passing} 187 | Just like LibTomMath the arguments are meant to be read left to right where the destination is on the right. Consider 188 | the following. 189 | 190 | \begin{alltt} 191 | pb_add(a, b, c); /* c = a + b */ 192 | pb_mul(a, b, c); /* c = a * b */ 193 | \end{alltt} 194 | 195 | Also like LibTomMath input arguments can be specified as output arguments. Consider. 196 | 197 | \begin{alltt} 198 | pb_mul(a, b, a); /* a = a * b */ 199 | pb_gcd(a, b, b); /* b = (a, b) */ 200 | \end{alltt} 201 | 202 | However, polynomial math raises another consideration. The characteristic of the result is taken from the right most 203 | argument passed to the function. Not all functions will return an error code if the characteristics of the inputs 204 | do not match so it's important to keep this in mind. In general the results are undefined if not all of the polynomials 205 | have identical characteristics. 206 | 207 | \section{Initializing Polynomials} 208 | In order to use a pb\_poly structure with one of the functions in this library the structure must be initialized. 209 | There are three functions provided to initialize pb\_poly structures. 210 | 211 | \subsection{Default Initialization} 212 | \index{pb\_init} 213 | \begin{alltt} 214 | int pb_init(pb_poly *a, mp_int *characteristic); 215 | \end{alltt} 216 | This will initialize ``a'' with the given ``characteristic'' such that the polynomial represented is a constant zero. 217 | The mp\_int characteristic must be a valid initialized mp\_int even if a characteristic of zero is desired. By default, 218 | the polynomial will be initialized so there are ``PB\_TERMS'' terms available. This will grow automatically as required 219 | by the other functions. 220 | 221 | \subsection{Initilization of Given Size} 222 | \index{pb\_init\_size} 223 | \begin{alltt} 224 | int pb_init_size(pb_poly *a, mp_int *characteristic, int size); 225 | \end{alltt} 226 | This behaves similar to pb\_init() except it will allocate ``size'' terms to initialize instead of ``PB\_TERMS''. This 227 | is useful if you happen to know in advance how many terms you want. 228 | 229 | \subsection{Initilization of a Copy} 230 | \index{pb\_init\_copy} 231 | \begin{alltt} 232 | int pb_init_copy(pb_poly *a, pb_poly *b); 233 | \end{alltt} 234 | 235 | This will initialize ``a'' so it is a verbatim copy of ``b''. It will copy the characteristic and all of the terms 236 | from ``b'' into ``a''. 237 | 238 | \subsection{Freeing a Polynomial} 239 | \index{pb\_clear} 240 | \begin{alltt} 241 | int pb_clear(pb_poly *a); 242 | \end{alltt} 243 | 244 | This will free all the memory required by ``a'' and mark it as been freed. You can repeatedly pb\_clear() the same 245 | pb\_poly safely. 246 | 247 | \chapter{Basic Operations} 248 | \section{Comparison} 249 | Comparisions with polynomials is a bit less intuitive then with integers. Is $x^2 + 3$ greater than $x^2 + x + 4$? To 250 | create a rational form of comparison the following comparison codes were designed. 251 | 252 | \begin{figure}[here] 253 | \begin{small} 254 | \begin{center} 255 | \begin{tabular}{|l|l|} 256 | \hline \textbf{Code} & \textbf{Meaning} \\ 257 | \hline PB\_EQ & The polynomials are exactly equal \\ 258 | \hline PB\_DEG\_LT & The left polynomial has a lower degree than the right. \\ 259 | \hline PB\_DEG\_EQ & Both have the same degree. \\ 260 | \hline PB\_DEG\_GT & The left polynomial has a higher degree than the right. \\ 261 | \hline 262 | \end{tabular} 263 | \end{center} 264 | \end{small} 265 | \caption{Compare Codes} 266 | \end{figure} 267 | 268 | \index{pb\_cmp} 269 | \begin{alltt} 270 | int pb_cmp(pb_poly *a, pb_poly *b); 271 | \end{alltt} 272 | 273 | This will compare the polynomial ``a'' to the left of the polynomial ``b''. It will return one of the four 274 | codes listed above. Note that the function does not compare the characteristics. So if $a \in GF(17)[x]$ and 275 | $b \in GF(11)[x]$ were both equal to $x^2 + 3$ they would compare to PB\_EQ. Whereas $x^3 + 4$ 276 | 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.}. 277 | 278 | \section{Copying and Swapping} 279 | \index{pb\_copy} 280 | \begin{alltt} 281 | int pb_copy(pb_poly *src, pb_poly *dest); 282 | \end{alltt} 283 | This will copy the polynomial from ``src'' to ``dest'' verbatim. 284 | 285 | \index{pb\_exch} 286 | \begin{alltt} 287 | int pb_exch(pb_poly *a, pb_poly *b); 288 | \end{alltt} 289 | This will exchange the contents of ``a'' with ``b''. 290 | 291 | \section{Multiplying and Dividing by $x$} 292 | \index{pb\_lshd} \index{pb\_rshd} 293 | \begin{alltt} 294 | int pb_lshd(pb_poly *a, int i); 295 | int pb_rshd(pb_poly *a, int i); 296 | \end{alltt} 297 | These will multiply (or divide, respectfully) the polynomial ``a'' by $x^i$. If $i \le 0$ the functions return without 298 | performing any operation. For example, 299 | 300 | \begin{alltt} 301 | pb_lshd(a, 2); /* a(x) = a(x) * x^2 */ 302 | pb_rshd(a, 7); /* a(x) = a(x) / x^7 */ 303 | \end{alltt} 304 | 305 | \chapter{Basic Arithmetic} 306 | \section{Addition, Subtraction and Multiplication} 307 | \index{pb\_add} \index{pb\_sub} 308 | \begin{alltt} 309 | int pb_add(pb_poly *a, pb_poly *b, pb_poly *c); 310 | int pb_sub(pb_poly *a, pb_poly *b, pb_poly *c); 311 | int pb_mul(pb_poly *a, pb_poly *b, pb_poly *c); 312 | \end{alltt} 313 | 314 | These will add (subtract or multiply, respectfully) the polynomial ``a'' and polynomial ``b'' and store the result in 315 | polynomial ``c''. The characteristic from ``c'' is used to calculate the result. Note that the coefficients of ``c'' 316 | will always be positive provided the characteristic of ``c'' is greater than zero. 317 | 318 | Quick examples of usage. 319 | 320 | \begin{alltt} 321 | pb_add(a, b, c); /* c = a + b */ 322 | pb_sub(b, a, c); /* c = b - a */ 323 | pb_mul(c, a, a); /* a = c * a */ 324 | \end{alltt} 325 | 326 | \section{Division} 327 | \index{pb\_div} 328 | \begin{alltt} 329 | int pb_div(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); 330 | \end{alltt} 331 | This will divide the polynomial ``a'' by ``b'' and store the quotient in ``c'' and remainder in ``d''. That is 332 | 333 | \begin{equation} 334 | b(x) \cdot c(x) + d(x) = a(x) 335 | \end{equation} 336 | 337 | 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 338 | signify their value is not desired. This is useful if you only want the quotient or remainder but not both. 339 | 340 | Since one of the destinations can be \textbf{NULL} the characteristic of the result is taken from ``b''. The function 341 | will return an error if the characteristic of ``a'' differs from that of ``b''. 342 | 343 | This function is defined for polynomials in $GF(p)[x]$ only. A routine pb\_zdiv()\footnote{To be written!} allows the 344 | division of polynomials in $\Z[x]$. 345 | 346 | \section{Modular Functions} 347 | \index{pb\_addmod} \index{pb\_submod} \index{pb\_mulmod} 348 | \begin{alltt} 349 | int pb_addmod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); 350 | int pb_submod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); 351 | int pb_mulmod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); 352 | \end{alltt} 353 | 354 | These add (subtract or multiply respectfully) the polynomial ``a'' and the polynomial ``b'' modulo the polynomial ``c'' 355 | and store the result in the polynomial ``d''. 356 | 357 | \chapter{Algebraic Functions} 358 | 359 | \section{Monic Reductions} 360 | \index{pb\_monic} 361 | \begin{alltt} 362 | int pb_monic(pb_poly *a, pb_poly *b) 363 | \end{alltt} 364 | Makes ``b'' the monic representation of ``a'' by ensuring the most significant coefficient is one. Only defined 365 | over $GF(p)[x]$. Note that this is not a straight copy to ``b'' so you must ensure the characteristic of the two 366 | are equal before you call the function\footnote{Note that $a == b$ is acceptable as well.}. Monic polynomials 367 | are related to their original polynomial through an integer $k$ as follows 368 | 369 | \begin{equation} 370 | a(x) \cdot k^{-1} \equiv b(x) 371 | \end{equation} 372 | 373 | \section{Extended Euclidean Algorithm} 374 | \index{pb\_exteuclid} 375 | \begin{alltt} 376 | int pb_exteuclid(pb_poly *a, pb_poly *b, 377 | pb_poly *U1, pb_poly *U2, pb_poly *U3); 378 | \end{alltt} 379 | 380 | This will compute the Euclidean algorithm and find values ``U1'', ``U2'', ``U3'' such that 381 | 382 | \begin{equation} 383 | a(x) \cdot U1(x) + b(x) \cdot U2(x) = U3(x) 384 | \end{equation} 385 | 386 | The value of ``U3'' is reduced to a monic polynomial. The three destination variables are all optional and can 387 | be specified as \textbf{NULL} if they are not desired. 388 | 389 | \section{Greatest Common Divisor} 390 | \index{pb\_gcd} 391 | \begin{alltt} 392 | int pb_gcd(pb_poly *a, pb_poly *b, pb_poly *c); 393 | \end{alltt} 394 | This finds the monic greatest common divisor of the two polynomials ``a'' and ``b'' and store the result in ``c''. The 395 | operation is only defined over $GF(p)[x]$. 396 | 397 | \section{Modular Inverse} 398 | \index{pb\_invmod} 399 | \begin{alltt} 400 | int pb_invmod(pb_poly *a, pb_poly *b, pb_poly *c); 401 | \end{alltt} 402 | This finds the modular inverse of ``a'' modulo ``b'' and stores the result in ``c''. The operation is only defined over 403 | $GF(p)[x]$. If the operation succeed then the following congruency should hold true. 404 | 405 | \begin{equation} 406 | a(x)c(x) \equiv 1 \mbox{ (mod }b(x)\mbox{)} 407 | \end{equation} 408 | 409 | \section{Modular Exponentiation} 410 | \index{pb\_exptmod} 411 | \begin{alltt} 412 | int pb_exptmod (pb_poly * G, mp_int * X, pb_poly * P, pb_poly * Y); 413 | \end{alltt} 414 | 415 | This raise ``G'' to the power of ``X'' modulo ``P'' and stores the result in ``Y''. Or as a congruence 416 | 417 | \begin{equation} 418 | Y(x) \equiv G(x)^X \mbox{ (mod }P(x)\mbox{)} 419 | \end{equation} 420 | 421 | Where ``X'' can be negative\footnote{But in that case $G^{-1}(x)$ must exist modulo $P(x)$.} or positive. This function 422 | is only defined over $GF(p)[x]$. 423 | 424 | \section{Irreducibility Testing} 425 | \index{pb\_isirreduc} 426 | \begin{alltt} 427 | int pb_isirreduc(pb_poly *a, int *res); 428 | \end{alltt} 429 | Sets ``res'' to MP\_YES if ``a'' is irreducible (only for $GF(p)[x]$) otherwise sets ``res'' to MP\_NO. 430 | 431 | \input{pb.ind} 432 | 433 | \end{document} 434 | -------------------------------------------------------------------------------- /pb_add.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | int pb_add(pb_poly *a, pb_poly *b, pb_poly *c) 15 | { 16 | int err, x, y, z, characteristic; 17 | pb_poly *tmp; 18 | 19 | /* grow c to be the max size */ 20 | y = PB_MAX(a->used, b->used); 21 | if (c->alloc < y) { 22 | if ((err = pb_grow(c, y)) != MP_OKAY) { 23 | return err; 24 | } 25 | } 26 | 27 | /* do we need to concern char */ 28 | characteristic = mp_iszero(&(c->characteristic)); 29 | 30 | /* add the terms */ 31 | z = PB_MIN(a->used, b->used); 32 | for (x = 0; x < z; x++) { 33 | if ((err = mp_add(&(a->terms[x]), &(b->terms[x]), &(c->terms[x]))) != MP_OKAY) { 34 | return err; 35 | } 36 | if (characteristic == MP_NO) { 37 | if ((err = mp_mod(&(c->terms[x]), &(c->characteristic), &(c->terms[x]))) != MP_OKAY) { 38 | return err; 39 | } 40 | } 41 | } 42 | 43 | /* excess digits? */ 44 | if (y != z) { 45 | if (a->used == y) { 46 | tmp = a; 47 | } else { 48 | tmp = b; 49 | } 50 | for (x = z; x < y; x++) { 51 | if (characteristic == MP_NO) { 52 | if ((err = mp_mod(&(tmp->terms[x]), &(c->characteristic), &(c->terms[x]))) != MP_OKAY) { 53 | return err; 54 | } 55 | } else { 56 | if ((err = mp_copy(&(tmp->terms[x]), &(c->terms[x]))) != MP_OKAY) { 57 | return err; 58 | } 59 | } 60 | } 61 | } 62 | 63 | /* zero excess */ 64 | for (x = y; x < c->used; x++) { 65 | mp_zero(&(c->terms[x])); 66 | } 67 | c->used = y; 68 | pb_clamp(c); 69 | 70 | return MP_OKAY; 71 | } 72 | 73 | 74 | -------------------------------------------------------------------------------- /pb_addmod.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | int pb_addmod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d) 15 | { 16 | int err; 17 | pb_poly tmp; 18 | 19 | if ((err = pb_init(&tmp, &(d->characteristic))) != MP_OKAY) { 20 | return err; 21 | } 22 | if ((err = pb_add(a, b, &tmp)) != MP_OKAY) { 23 | goto __TMP; 24 | } 25 | if ((err = pb_mod(&tmp, c, d)) != MP_OKAY) { 26 | goto __TMP; 27 | } 28 | 29 | err = MP_OKAY; 30 | __TMP: pb_clear(&tmp); 31 | return err; 32 | } 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /pb_clamp.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | void pb_clamp(pb_poly *a) 15 | { 16 | while (a->used > 0 && (mp_iszero(&(a->terms[a->used-1])) == MP_YES)) { 17 | --(a->used); 18 | } 19 | } 20 | 21 | 22 | -------------------------------------------------------------------------------- /pb_clear.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | #include 14 | 15 | void pb_clear(pb_poly *a) 16 | { 17 | int x; 18 | 19 | if (a->terms != NULL) { 20 | /* free stuff */ 21 | for (x = 0; x < a->alloc; x++) { 22 | mp_clear(&(a->terms[x])); 23 | } 24 | free(a->terms); 25 | mp_clear(&(a->characteristic)); 26 | 27 | /* prevent double frees */ 28 | a->terms = NULL; 29 | a->alloc = a->used = 0; 30 | } 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /pb_clear_multi.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | #include 14 | 15 | void pb_clear_multi(pb_poly *mp, ...) 16 | { 17 | pb_poly* next_mp = mp; 18 | va_list args; 19 | va_start(args, mp); 20 | while (next_mp != NULL) { 21 | pb_clear(next_mp); 22 | next_mp = va_arg(args, pb_poly*); 23 | } 24 | va_end(args); 25 | } 26 | -------------------------------------------------------------------------------- /pb_cmp.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | int pb_cmp(pb_poly *a, pb_poly *b) 15 | { 16 | int x; 17 | 18 | if (a->used > b->used) { 19 | return PB_DEG_GT; 20 | } else if (a->used < b->used) { 21 | return PB_DEG_LT; 22 | } 23 | 24 | for (x = 0; x < a->used; x++) { 25 | if (mp_cmp(&(a->terms[x]), &(b->terms[x])) != MP_EQ) { 26 | return PB_DEG_EQ; 27 | } 28 | } 29 | return PB_EQ; 30 | } 31 | 32 | 33 | -------------------------------------------------------------------------------- /pb_copy.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | /* dest = src */ 15 | int pb_copy(pb_poly *src, pb_poly *dest) 16 | { 17 | int err, x; 18 | 19 | /* avoid trivial copies */ 20 | if (src == dest) { 21 | return MP_OKAY; 22 | } 23 | 24 | /* grow dest as required */ 25 | if (dest->alloc < src->used) { 26 | if ((err = pb_grow(dest, src->used)) != MP_OKAY) { 27 | return err; 28 | } 29 | } 30 | 31 | /* set the characteristic */ 32 | if ((err = mp_copy(&(src->characteristic), &(dest->characteristic))) != MP_OKAY) { 33 | return err; 34 | } 35 | 36 | /* copy digits */ 37 | for (x = 0; x < src->used; x++) { 38 | if ((err = mp_copy(&(src->terms[x]), &(dest->terms[x]))) != MP_OKAY) { 39 | return err; 40 | } 41 | } 42 | 43 | /* zero excess digits */ 44 | for (x = src->used; x < dest->used; x++) { 45 | mp_zero(&(dest->terms[x])); 46 | } 47 | dest->used = src->used; 48 | return MP_OKAY; 49 | } 50 | 51 | 52 | -------------------------------------------------------------------------------- /pb_div.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | 15 | /* Divides a by b (uses the char of b as the char of the result) only for 16 | * polynomials over GF(p^k)[x] 17 | */ 18 | int pb_div(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d) 19 | { 20 | int err, x; 21 | pb_poly p, q, r; 22 | mp_int tmp, tmp2; 23 | 24 | /* if ||b|| > ||a|| it's a simple copy over */ 25 | if (b->used > a->used) { 26 | if (d != NULL) { 27 | pb_copy(a, d); 28 | } 29 | if (c != NULL) { 30 | pb_zero(c); 31 | } 32 | } 33 | 34 | /* zero divisor */ 35 | if (b->used == 0) { 36 | return MP_VAL; 37 | } 38 | 39 | /* compare chars */ 40 | if (mp_cmp(&(a->characteristic), &(b->characteristic)) != MP_EQ) { 41 | return MP_VAL; 42 | } 43 | 44 | /* we don't support char zero! */ 45 | if (mp_iszero(&(b->characteristic)) == MP_YES) { 46 | return MP_VAL; 47 | } 48 | 49 | /* get a copy of "a" to work with */ 50 | if ((err = pb_init_copy(&p, a)) != MP_OKAY) { 51 | return err; 52 | } 53 | 54 | /* init a temp quotient */ 55 | if ((err = pb_init_size(&q, &(b->characteristic), a->used - b->used + 1)) != MP_OKAY) { 56 | goto __P; 57 | } 58 | 59 | /* init a temp polynomial we can work with */ 60 | if ((err = pb_init_size(&r, &(b->characteristic), a->used)) != MP_OKAY) { 61 | goto __Q; 62 | } 63 | 64 | /* now init an mp_int we can work with */ 65 | if ((err = mp_init(&tmp)) != MP_OKAY) { 66 | goto __R; 67 | } 68 | 69 | /* and the inverse of the leading digit of b(x) */ 70 | if ((err = mp_init(&tmp2)) != MP_OKAY) { 71 | goto __TMP; 72 | } 73 | if ((err = mp_invmod(&(b->terms[b->used - 1]), &(b->characteristic), &tmp2)) != MP_OKAY) { 74 | goto __TMP2; 75 | } 76 | 77 | /* now let's reduce us some digits */ 78 | for (x = a->used - 1; x >= b->used-1; x--) { 79 | /* skip zero digits */ 80 | if (mp_iszero(&(p.terms[x])) == MP_YES) { 81 | continue; 82 | } 83 | 84 | /* now we have a leading digit of p(x), call it A 85 | and a leading digit of b(x), call it B 86 | 87 | Now we want to reduce it so we need A + CB = 0 which turns into 88 | A + CB = 0 89 | CB = -A 90 | C = -A/B 91 | 92 | So we multiply b(x) by C * x^k [where k = ||p(x)|| - ||b(x)||], add that to p(x) and 93 | we must reduced one digit 94 | */ 95 | 96 | /* multiply 1/B [tmp2] by A */ 97 | if ((err = mp_mulmod(&tmp2, &(p.terms[x]), &(b->characteristic), &tmp)) != MP_OKAY) { goto __TMP2; } 98 | 99 | /* tmp is now a term of the quotient */ 100 | if ((err = mp_copy(&tmp, &(q.terms[x - b->used + 1]))) != MP_OKAY) { goto __TMP2; } 101 | 102 | /* create r(x) = C */ 103 | pb_zero(&r); 104 | if ((err = mp_copy(&tmp, &(r.terms[0]))) != MP_OKAY) { goto __TMP2; } 105 | r.used = 1; 106 | 107 | /* now multiply r(x) by b(x)*x^k and subtract from p(x) */ 108 | if ((err = pb_mul(b, &r, &r)) != MP_OKAY) { goto __TMP2; } 109 | if ((err = pb_lshd(&r, x - b->used + 1)) != MP_OKAY) { goto __TMP2; } 110 | if ((err = pb_sub(&p, &r, &p)) != MP_OKAY) { goto __TMP2; } 111 | } 112 | 113 | /* setup q properly (so q.used is valid) */ 114 | q.used = a->used; 115 | pb_clamp(&q); 116 | 117 | /* ok so now p(x) is the remainder and q(x) is the quotient */ 118 | if (c != NULL) { 119 | pb_exch(&q, c); 120 | } 121 | if (d != NULL) { 122 | pb_exch(&p, d); 123 | } 124 | 125 | err = MP_OKAY; 126 | 127 | __TMP2: mp_clear(&tmp2); 128 | __TMP : mp_clear(&tmp); 129 | __R : pb_clear(&r); 130 | __Q : pb_clear(&q); 131 | __P : pb_clear(&p); 132 | return err; 133 | } 134 | 135 | 136 | -------------------------------------------------------------------------------- /pb_exch.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | void pb_exch(pb_poly *a, pb_poly *b) 15 | { 16 | pb_poly tmp; 17 | tmp = *a; *a = *b; *b = tmp; 18 | } 19 | 20 | 21 | -------------------------------------------------------------------------------- /pb_exptmod.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | #ifdef MP_LOW_MEM 15 | #define TAB_SIZE 32 16 | #else 17 | #define TAB_SIZE 256 18 | #endif 19 | 20 | int pb_exptmod (pb_poly * G, mp_int * X, pb_poly * P, pb_poly * Y) 21 | { 22 | pb_poly M[TAB_SIZE], res; 23 | mp_digit buf; 24 | int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; 25 | 26 | /* find window size */ 27 | x = mp_count_bits (X); 28 | if (x <= 7) { 29 | winsize = 2; 30 | } else if (x <= 36) { 31 | winsize = 3; 32 | } else if (x <= 140) { 33 | winsize = 4; 34 | } else if (x <= 450) { 35 | winsize = 5; 36 | } else if (x <= 1303) { 37 | winsize = 6; 38 | } else if (x <= 3529) { 39 | winsize = 7; 40 | } else { 41 | winsize = 8; 42 | } 43 | 44 | #ifdef MP_LOW_MEM 45 | if (winsize > 5) { 46 | winsize = 5; 47 | } 48 | #endif 49 | 50 | /* init M array */ 51 | /* init first cell */ 52 | if ((err = pb_init(&M[1], &(Y->characteristic))) != MP_OKAY) { 53 | return err; 54 | } 55 | 56 | /* now init the second half of the array */ 57 | for (x = 1<<(winsize-1); x < (1 << winsize); x++) { 58 | if ((err = pb_init(&M[x], &(Y->characteristic))) != MP_OKAY) { 59 | for (y = 1<<(winsize-1); y < x; y++) { 60 | pb_clear (&M[y]); 61 | } 62 | pb_clear(&M[1]); 63 | return err; 64 | } 65 | } 66 | 67 | /* create M table 68 | * 69 | * The M table contains powers of the base, 70 | * e.g. M[x] = G**x mod P 71 | * 72 | * The first half of the table is not 73 | * computed though accept for M[0] and M[1] 74 | */ 75 | 76 | if (X->sign == MP_ZPOS) { 77 | if ((err = pb_mod (G, P, &M[1])) != MP_OKAY) { goto __M; } 78 | } else { 79 | if ((err = pb_invmod(G, P, &M[1])) != MP_OKAY) { goto __M; } 80 | } 81 | 82 | /* compute the value at M[1<<(winsize-1)] by squaring 83 | * M[1] (winsize-1) times 84 | */ 85 | if ((err = pb_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { goto __M; } 86 | 87 | for (x = 0; x < (winsize - 1); x++) { 88 | if ((err = pb_mulmod (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)], 89 | P, &M[1 << (winsize - 1)])) != MP_OKAY) { goto __M; } 90 | } 91 | 92 | /* create upper table, that is M[x] = M[x-1] * M[1] (mod P) 93 | * for x = (2**(winsize - 1) + 1) to (2**winsize - 1) 94 | */ 95 | for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { 96 | if ((err = pb_mulmod (&M[x - 1], &M[1], P, &M[x])) != MP_OKAY) { goto __M; } 97 | } 98 | 99 | /* setup result */ 100 | if ((err = pb_init (&res, &(Y->characteristic))) != MP_OKAY) { goto __M; } 101 | mp_set (&(res.terms[0]), 1); res.used = 1; 102 | 103 | /* set initial mode and bit cnt */ 104 | mode = 0; 105 | bitcnt = 1; 106 | buf = 0; 107 | digidx = X->used - 1; 108 | bitcpy = 0; 109 | bitbuf = 0; 110 | 111 | for (;;) { 112 | /* grab next digit as required */ 113 | if (--bitcnt == 0) { 114 | /* if digidx == -1 we are out of digits */ 115 | if (digidx == -1) { 116 | break; 117 | } 118 | /* read next digit and reset the bitcnt */ 119 | buf = X->dp[digidx--]; 120 | bitcnt = (int) DIGIT_BIT; 121 | } 122 | 123 | /* grab the next msb from the exponent */ 124 | y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1; 125 | buf <<= (mp_digit)1; 126 | 127 | /* if the bit is zero and mode == 0 then we ignore it 128 | * These represent the leading zero bits before the first 1 bit 129 | * in the exponent. Technically this opt is not required but it 130 | * does lower the # of trivial squaring/reductions used 131 | */ 132 | if (mode == 0 && y == 0) { 133 | continue; 134 | } 135 | 136 | /* if the bit is zero and mode == 1 then we square */ 137 | if (mode == 1 && y == 0) { 138 | if ((err = pb_mulmod (&res, &res, P, &res)) != MP_OKAY) { goto __RES; } 139 | continue; 140 | } 141 | 142 | /* else we add it to the window */ 143 | bitbuf |= (y << (winsize - ++bitcpy)); 144 | mode = 2; 145 | 146 | if (bitcpy == winsize) { 147 | /* ok window is filled so square as required and multiply */ 148 | /* square first */ 149 | for (x = 0; x < winsize; x++) { 150 | if ((err = pb_mulmod (&res, &res, P, &res)) != MP_OKAY) { goto __RES; } 151 | } 152 | 153 | /* then multiply */ 154 | if ((err = pb_mulmod (&res, &M[bitbuf], P, &res)) != MP_OKAY) { goto __RES; } 155 | 156 | /* empty window and reset */ 157 | bitcpy = 0; 158 | bitbuf = 0; 159 | mode = 1; 160 | } 161 | } 162 | 163 | /* if bits remain then square/multiply */ 164 | if (mode == 2 && bitcpy > 0) { 165 | /* square then multiply if the bit is set */ 166 | for (x = 0; x < bitcpy; x++) { 167 | if ((err = pb_mulmod (&res, &res, P, &res)) != MP_OKAY) { goto __RES; } 168 | 169 | bitbuf <<= 1; 170 | if ((bitbuf & (1 << winsize)) != 0) { 171 | /* then multiply */ 172 | if ((err = pb_mulmod (&res, &M[1], P, &res)) != MP_OKAY) { goto __RES; } 173 | } 174 | } 175 | } 176 | 177 | pb_exch (&res, Y); 178 | err = MP_OKAY; 179 | __RES:pb_clear (&res); 180 | __M: 181 | pb_clear(&M[1]); 182 | for (x = 1<<(winsize-1); x < (1 << winsize); x++) { 183 | pb_clear (&M[x]); 184 | } 185 | return err; 186 | } 187 | -------------------------------------------------------------------------------- /pb_exteuclid.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | /* Extended euclidean algorithm of (a, b) produces 15 | a*u1 + b*u2 = u3 16 | */ 17 | int pb_exteuclid(pb_poly *a, pb_poly *b, pb_poly *U1, pb_poly *U2, pb_poly *U3) 18 | { 19 | pb_poly u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp; 20 | int err; 21 | 22 | if ((err = pb_init_multi(&(b->characteristic), 23 | &u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) { 24 | return err; 25 | } 26 | 27 | /* initialize, (u1,u2,u3) = (1,0,a) */ 28 | mp_set(&(u1.terms[0]), 1); u1.used = 1; 29 | if ((err = pb_copy(a, &u3)) != MP_OKAY) { goto _ERR; } 30 | 31 | /* initialize, (v1,v2,v3) = (0,1,b) */ 32 | mp_set(&(v2.terms[0]), 1); v2.used = 1; 33 | if ((err = pb_copy(b, &v3)) != MP_OKAY) { goto _ERR; } 34 | 35 | /* loop while v3 != 0 */ 36 | while (v3.used > 0) { 37 | /* q = u3/v3 */ 38 | if ((err = pb_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto _ERR; } 39 | 40 | /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */ 41 | if ((err = pb_mul(&v1, &q, &tmp)) != MP_OKAY) { goto _ERR; } 42 | if ((err = pb_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto _ERR; } 43 | if ((err = pb_mul(&v2, &q, &tmp)) != MP_OKAY) { goto _ERR; } 44 | if ((err = pb_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto _ERR; } 45 | if ((err = pb_mul(&v3, &q, &tmp)) != MP_OKAY) { goto _ERR; } 46 | if ((err = pb_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto _ERR; } 47 | 48 | /* (u1,u2,u3) = (v1,v2,v3) */ 49 | if ((err = pb_copy(&v1, &u1)) != MP_OKAY) { goto _ERR; } 50 | if ((err = pb_copy(&v2, &u2)) != MP_OKAY) { goto _ERR; } 51 | if ((err = pb_copy(&v3, &u3)) != MP_OKAY) { goto _ERR; } 52 | 53 | /* (v1,v2,v3) = (t1,t2,t3) */ 54 | if ((err = pb_copy(&t1, &v1)) != MP_OKAY) { goto _ERR; } 55 | if ((err = pb_copy(&t2, &v2)) != MP_OKAY) { goto _ERR; } 56 | if ((err = pb_copy(&t3, &v3)) != MP_OKAY) { goto _ERR; } 57 | } 58 | 59 | /* reduce U3 to monic but we have to mangle all three to remain consistent */ 60 | pb_zero(&v1); 61 | if ((err = mp_copy(&(u3.terms[u3.used-1]), &(v1.terms[0]))) != MP_OKAY) { goto _ERR; } 62 | v1.used = 1; 63 | 64 | /* copy result out */ 65 | if (U1 != NULL) { if ((err = pb_div(&u1, &v1, U1, NULL)) != MP_OKAY) { goto _ERR; }} 66 | if (U2 != NULL) { if ((err = pb_div(&u2, &v1, U2, NULL)) != MP_OKAY) { goto _ERR; }} 67 | if (U3 != NULL) { if ((err = pb_div(&u3, &v1, U3, NULL)) != MP_OKAY) { goto _ERR; }} 68 | 69 | err = MP_OKAY; 70 | _ERR: pb_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL); 71 | return err; 72 | } 73 | 74 | 75 | -------------------------------------------------------------------------------- /pb_gcd.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | /* returns the monic GCD only for GF(p^k)[x] */ 15 | int pb_gcd(pb_poly *a, pb_poly *b, pb_poly *c) 16 | { 17 | pb_poly A, B, tmp; 18 | int err; 19 | 20 | if (mp_iszero(&(c->characteristic)) == MP_YES) { 21 | return MP_VAL; 22 | } 23 | 24 | /* special cases (one or both are zero) */ 25 | if (a->used == 0 && b->used == 0) { 26 | /* both zero, set to 1 */ 27 | pb_zero(c); 28 | c->used = 1; 29 | mp_set(&(c->terms[0]), 1); 30 | return MP_OKAY; 31 | } else if (a->used == 0) { 32 | return pb_copy(b, c); 33 | } else if (b->used == 0) { 34 | return pb_copy(a, c); 35 | } 36 | 37 | if ((err = pb_init(&tmp, &(c->characteristic))) != MP_OKAY) { 38 | return err; 39 | } 40 | if ((err = pb_init_copy(&A, a)) != MP_OKAY) { 41 | goto __TMP; 42 | } 43 | if ((err = pb_init_copy(&B, b)) != MP_OKAY) { 44 | goto __A; 45 | } 46 | 47 | while (B.used > 0) { 48 | if ((err = pb_mod(&A, &B, &tmp)) != MP_OKAY) { 49 | goto __B; 50 | } 51 | /* A = B, B = tmp */ 52 | if ((err = pb_copy(&B, &A)) != MP_OKAY) { 53 | goto __B; 54 | } 55 | if ((err = pb_copy(&tmp, &B)) != MP_OKAY) { 56 | goto __B; 57 | } 58 | } 59 | 60 | /* ensure it's monic */ 61 | err = pb_monic(&A, c); 62 | 63 | __B : pb_clear(&B); 64 | __A : pb_clear(&A); 65 | __TMP: pb_clear(&tmp); 66 | return err; 67 | } 68 | 69 | 70 | -------------------------------------------------------------------------------- /pb_grow.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | #include 14 | #include 15 | 16 | int pb_grow(pb_poly *a, int size) 17 | { 18 | mp_int *tmp; 19 | int x, err; 20 | 21 | if (a->alloc < size) { 22 | /* pad size upwards */ 23 | size += (PB_TERMS - (size % PB_TERMS)); 24 | 25 | /* regrow terms */ 26 | tmp = realloc(a->terms, sizeof(mp_int) * size); 27 | if (tmp == NULL) { 28 | return MP_MEM; 29 | } 30 | a->terms = tmp; 31 | 32 | /* zero the new stuff (prevents mp_clear from double freeing) */ 33 | memset(a->terms + a->alloc, 0, (size - a->alloc) * sizeof(mp_int)); 34 | 35 | /* now init the terms */ 36 | for (x = a->alloc; x < size; x++) { 37 | if ((err = mp_init(&(a->terms[x]))) != MP_OKAY) { 38 | return err; 39 | } 40 | } 41 | 42 | /* update info */ 43 | a->alloc = size; 44 | } 45 | return MP_OKAY; 46 | } 47 | 48 | 49 | -------------------------------------------------------------------------------- /pb_init.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | #include 14 | 15 | /* initialize a */ 16 | int pb_init(pb_poly *a, mp_int *characteristic) 17 | { 18 | int x, y, err; 19 | 20 | /* init characteristic */ 21 | if ((err = mp_init_copy(&(a->characteristic), characteristic)) != MP_OKAY) { 22 | return err; 23 | } 24 | 25 | /* now allocate an array of mp_ints */ 26 | if ((a->terms = calloc(PB_TERMS, sizeof(mp_int))) == NULL) { 27 | mp_clear(&(a->characteristic)); 28 | return MP_MEM; 29 | } 30 | 31 | /* now initialize them all */ 32 | for (x = 0; x < PB_TERMS; x++) { 33 | if ((err = mp_init(&(a->terms[x]))) != MP_OKAY) { 34 | /* free stuff */ 35 | for (y = 0; y < x; y++) { 36 | mp_clear(&(a->terms[y])); 37 | } 38 | free(a->terms); 39 | mp_clear(&(a->characteristic)); 40 | return err; 41 | } 42 | } 43 | 44 | /* set our parameters */ 45 | a->used = 0; 46 | a->alloc = PB_TERMS; 47 | return MP_OKAY; 48 | } 49 | 50 | 51 | -------------------------------------------------------------------------------- /pb_init_copy.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | int pb_init_copy(pb_poly *a, pb_poly *b) 15 | { 16 | int err; 17 | if ((err = pb_init(a, &(b->characteristic))) != MP_OKAY) { 18 | return err; 19 | } 20 | return pb_copy(b, a); 21 | } 22 | -------------------------------------------------------------------------------- /pb_init_multi.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | #include 14 | 15 | int pb_init_multi(mp_int *characteristic, pb_poly *pb, ...) 16 | { 17 | mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ 18 | int n = 0; /* Number of ok inits */ 19 | pb_poly* cur_arg = pb; 20 | va_list args; 21 | 22 | va_start(args, pb); /* init args to next argument from caller */ 23 | while (cur_arg != NULL) { 24 | if (pb_init(cur_arg, characteristic) != MP_OKAY) { 25 | /* Oops - error! Back-track and mp_clear what we already 26 | succeeded in init-ing, then return error. 27 | */ 28 | va_list clean_args; 29 | 30 | /* end the current list */ 31 | va_end(args); 32 | 33 | /* now start cleaning up */ 34 | cur_arg = pb; 35 | va_start(clean_args, pb); 36 | while (n--) { 37 | pb_clear(cur_arg); 38 | cur_arg = va_arg(clean_args, pb_poly*); 39 | } 40 | va_end(clean_args); 41 | res = MP_MEM; 42 | break; 43 | } 44 | n++; 45 | cur_arg = va_arg(args, pb_poly*); 46 | } 47 | va_end(args); 48 | return res; /* Assumed ok, if error flagged above. */ 49 | } 50 | 51 | -------------------------------------------------------------------------------- /pb_init_size.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | #include 14 | 15 | /* initialize a */ 16 | int pb_init_size(pb_poly *a, mp_int *characteristic, int size) 17 | { 18 | int x, y, err; 19 | 20 | /* enforce a minimum size */ 21 | if (size < 1) { 22 | size = 1; 23 | } 24 | 25 | /* pad size upwards */ 26 | size += (PB_TERMS - (size % PB_TERMS)); 27 | 28 | 29 | /* init characteristic */ 30 | if ((err = mp_init_copy(&(a->characteristic), characteristic)) != MP_OKAY) { 31 | return err; 32 | } 33 | 34 | /* now allocate an array of mp_ints */ 35 | if ((a->terms = calloc(size, sizeof(mp_int))) == NULL) { 36 | mp_clear(&(a->characteristic)); 37 | return MP_MEM; 38 | } 39 | 40 | /* now initialize them all */ 41 | for (x = 0; x < size; x++) { 42 | if ((err = mp_init(&(a->terms[x]))) != MP_OKAY) { 43 | /* free stuff */ 44 | for (y = 0; y < x; y++) { 45 | mp_clear(&(a->terms[y])); 46 | } 47 | free(a->terms); 48 | mp_clear(&(a->characteristic)); 49 | return err; 50 | } 51 | } 52 | 53 | /* set our parameters */ 54 | a->used = 0; 55 | a->alloc = size; 56 | return MP_OKAY; 57 | } 58 | 59 | 60 | -------------------------------------------------------------------------------- /pb_invmod.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | int pb_invmod(pb_poly *a, pb_poly *b, pb_poly *c) 15 | { 16 | int err; 17 | pb_poly tmp; 18 | 19 | if ((err = pb_init(&tmp, &(c->characteristic))) != MP_OKAY) { 20 | return err; 21 | } 22 | 23 | if ((err = pb_exteuclid(a, b, c, NULL, &tmp)) != MP_OKAY) { goto _ERR; } 24 | 25 | /* if deg(tmp(x)) > 0 then there is no invmod */ 26 | if (tmp.used > 1) { err = MP_VAL; goto _ERR; } 27 | 28 | err = MP_OKAY; 29 | _ERR: pb_clear(&tmp); 30 | return err; 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /pb_isirreduc.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | /* is a(x) irreducible? */ 15 | int pb_isirreduc(pb_poly *a, int *res) 16 | { 17 | pb_poly u, tmp, fm, d; 18 | int err, i; 19 | 20 | /* default to no */ 21 | *res = MP_NO; 22 | 23 | /* init temps */ 24 | if ((err = pb_init_multi(&(a->characteristic), 25 | &u, &tmp, &fm, &d, NULL)) != MP_OKAY) { 26 | return err; 27 | } 28 | 29 | /* fm = monic(a(x)) */ 30 | if ((err = pb_monic(a, &fm)) != MP_OKAY) { goto _ERR; } 31 | 32 | /* u = x */ 33 | mp_set(&(u.terms[1]), 1); u.used = 2; 34 | 35 | /* loop */ 36 | for (i = 1; i <= (a->used / 2); i++) { 37 | /* u = u^p mod fm */ 38 | if ((err = pb_exptmod(&u, &(a->characteristic), &fm, &u)) != MP_OKAY) { goto _ERR; } 39 | 40 | /* tmp = u - x */ 41 | pb_zero(&tmp); 42 | mp_set(&(tmp.terms[1]), 1); tmp.used = 2; 43 | if ((err = pb_sub(&u, &tmp, &tmp)) != MP_OKAY) { goto _ERR; } 44 | 45 | /* d = gcd(fm, tmp) */ 46 | if ((err = pb_gcd(&fm, &tmp, &d)) != MP_OKAY) { goto _ERR; } 47 | 48 | /* if d != 1 then reducible */ 49 | if (d.used > 1) { err = MP_OKAY; goto _ERR; } 50 | } 51 | 52 | /* irreducible */ 53 | *res = MP_YES; 54 | err = MP_OKAY; 55 | _ERR: pb_clear_multi(&u, &tmp, &fm, &d, NULL); 56 | return err; 57 | } 58 | 59 | 60 | -------------------------------------------------------------------------------- /pb_lshd.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | int pb_lshd(pb_poly *a, int x) 15 | { 16 | int err, y; 17 | 18 | if (x <= 0) { 19 | return MP_OKAY; 20 | } 21 | 22 | /* grow as required */ 23 | if (a->alloc < (a->used + x)) { 24 | if ((err = pb_grow(a, a->used + x)) != MP_OKAY) { 25 | return err; 26 | } 27 | } 28 | 29 | /* shift */ 30 | for (y = a->used + x; y >= x; y--) { 31 | mp_exch(&(a->terms[y-x]), &(a->terms[y])); 32 | } 33 | 34 | /* zero lower digits */ 35 | for (y = 0; y < x; y++) { 36 | mp_zero(&(a->terms[y])); 37 | } 38 | a->used += x; 39 | 40 | return MP_OKAY; 41 | } 42 | 43 | -------------------------------------------------------------------------------- /pb_mod.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | int pb_mod(pb_poly *a, pb_poly *b, pb_poly *c) 15 | { 16 | return pb_div(a, b, NULL, c); 17 | } 18 | 19 | 20 | -------------------------------------------------------------------------------- /pb_monic.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | /* makes b equal to the monic polynomial form of a */ 15 | int pb_monic(pb_poly *a, pb_poly *b) 16 | { 17 | mp_int tmp; 18 | int err, x; 19 | 20 | /* must be in GF(p)[x] */ 21 | if (mp_iszero(&(b->characteristic)) == MP_YES) { 22 | return MP_VAL; 23 | } 24 | 25 | /* if it's already monic just copy */ 26 | if (a->used == 0 || mp_cmp_d(&(a->terms[a->used - 1]), 1) == MP_EQ) { 27 | return pb_copy(a, b); 28 | } 29 | 30 | /* grow b to hold result */ 31 | if (b->alloc < a->used) { 32 | if ((err = pb_grow(b, a->used)) != MP_OKAY) { 33 | return err; 34 | } 35 | } 36 | 37 | /* now init tmp and find the inverse of the leading digit */ 38 | if ((err = mp_init(&tmp)) != MP_OKAY) { 39 | return err; 40 | } 41 | 42 | if ((err = mp_invmod(&(a->terms[a->used-1]), &(b->characteristic), &tmp)) != MP_OKAY) { goto _ERR; } 43 | 44 | /* now reduce each coefficient */ 45 | for (x = 0; x < a->used; x++) { 46 | if ((err = mp_mulmod(&(a->terms[x]), &tmp, &(b->characteristic), &(b->terms[x]))) != MP_OKAY) { goto _ERR; } 47 | } 48 | 49 | /* zero excess digits */ 50 | for (x = a->used; x < b->used; x++) { 51 | mp_zero(&(b->terms[x])); 52 | } 53 | b->used = a->used; 54 | 55 | err = MP_OKAY; 56 | _ERR: mp_clear(&tmp); 57 | return err; 58 | } 59 | 60 | 61 | -------------------------------------------------------------------------------- /pb_mul.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | int pb_mul(pb_poly *a, pb_poly *b, pb_poly *c) 15 | { 16 | int err, x, y; 17 | pb_poly tmp; 18 | mp_int tmp2; 19 | 20 | /* make temp */ 21 | if ((err = pb_init_size(&tmp, &(c->characteristic), a->used + b->used)) != MP_OKAY) { 22 | return err; 23 | } 24 | 25 | if ((err = mp_init(&tmp2)) != MP_OKAY) { 26 | goto __TMP; 27 | } 28 | 29 | /* multiply the terms */ 30 | for (x = 0; x < a->used; x++) { 31 | for (y = 0; y < b->used; y++) { 32 | if ((err = mp_mul(&(a->terms[x]), &(b->terms[y]), &tmp2)) != MP_OKAY) { 33 | goto __TMP2; 34 | } 35 | if ((err = mp_add(&tmp2, &(tmp.terms[x+y]), &(tmp.terms[x+y]))) != MP_OKAY) { 36 | goto __TMP2; 37 | } 38 | } 39 | } 40 | 41 | /* now reduce the terms as required */ 42 | if (mp_iszero(&(c->characteristic)) == MP_NO) { 43 | for (x = 0; x < (a->used + b->used); x++) { 44 | if ((err = mp_mod(&(tmp.terms[x]), &(c->characteristic), &(tmp.terms[x]))) != MP_OKAY) { 45 | goto __TMP2; 46 | } 47 | } 48 | } 49 | 50 | /* set digit count */ 51 | tmp.used = a->used + b->used; 52 | pb_clamp(&tmp); 53 | 54 | /* exchange tmp and c */ 55 | pb_exch(&tmp, c); 56 | 57 | err = MP_OKAY; 58 | 59 | __TMP2: mp_clear(&tmp2); 60 | __TMP : pb_clear(&tmp); 61 | return err; 62 | } 63 | -------------------------------------------------------------------------------- /pb_mulmod.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | int pb_mulmod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d) 15 | { 16 | int err; 17 | pb_poly tmp; 18 | 19 | if ((err = pb_init(&tmp, &(d->characteristic))) != MP_OKAY) { 20 | return err; 21 | } 22 | if ((err = pb_mul(a, b, &tmp)) != MP_OKAY) { 23 | goto __TMP; 24 | } 25 | if ((err = pb_mod(&tmp, c, d)) != MP_OKAY) { 26 | goto __TMP; 27 | } 28 | 29 | err = MP_OKAY; 30 | __TMP: pb_clear(&tmp); 31 | return err; 32 | } 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /pb_rawsize.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | int pb_rawsize(pb_poly *a) 15 | { 16 | int x, y; 17 | 18 | /* 2 bytes for # of coefficients */ 19 | y = 2; 20 | 21 | /* characteristic */ 22 | y += 2 + mp_signed_bin_size(&(a->characteristic)); 23 | 24 | /* all of the terms */ 25 | for (x = 0; x < a->used; x++) { 26 | y += 2 + mp_signed_bin_size(&(a->terms[x])); 27 | } 28 | 29 | return y; 30 | } 31 | 32 | 33 | -------------------------------------------------------------------------------- /pb_readraw.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | int pb_readraw(pb_poly *a, unsigned char *buf, int len) 15 | { 16 | int terms, x, y, z, err; 17 | 18 | /* zero poly */ 19 | pb_zero(a); 20 | 21 | /* must be at least four bytes */ 22 | if (len < 4) { 23 | return MP_VAL; 24 | } 25 | 26 | /* number of terms */ 27 | terms = ((unsigned)buf[0]) | ((unsigned)buf[1]<<8); 28 | y = 2; 29 | 30 | /* grow to the right size */ 31 | if (a->alloc < terms) { 32 | if ((err = pb_grow(a, terms)) != MP_OKAY) { 33 | return err; 34 | } 35 | } 36 | 37 | /* read characteristic */ 38 | z = ((unsigned)buf[y]) | ((unsigned)buf[y+1]<<8); y += 2; 39 | if (z + y > len) { return MP_VAL; } 40 | if ((err = mp_read_signed_bin(&(a->characteristic), buf+y, z)) != MP_OKAY) { return err; } 41 | y += z; 42 | 43 | 44 | /* read terms */ 45 | for (x = 0; x < terms; x++) { 46 | z = ((unsigned)buf[y]) | ((unsigned)buf[y+1]<<8); y += 2; 47 | if (z + y > len) { return MP_VAL; } 48 | if ((err = mp_read_signed_bin(&(a->characteristic), buf+y, z)) != MP_OKAY) { return err; } 49 | y += z; 50 | } 51 | 52 | return MP_OKAY; 53 | } 54 | 55 | 56 | -------------------------------------------------------------------------------- /pb_rshd.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | int pb_rshd(pb_poly *a, int x) 15 | { 16 | int y; 17 | 18 | if (x >= a->used) { 19 | pb_zero(a); 20 | return MP_OKAY; 21 | } 22 | 23 | if (x <= 0) { 24 | return MP_OKAY; 25 | } 26 | 27 | for (y = x; y < a->used; y++) { 28 | mp_exch(&(a->terms[y]), &(a->terms[y-x])); 29 | } 30 | 31 | for (y = a->used - x; y < a->used; y++) { 32 | mp_zero(&(a->terms[y])); 33 | } 34 | a->used -= x; 35 | 36 | return MP_OKAY; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /pb_shrink.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | #include 14 | 15 | int pb_shrink(pb_poly *a) 16 | { 17 | int err, x; 18 | mp_int *tmp; 19 | 20 | /* first resize the array of terms */ 21 | if (a->used != a->alloc && a->used > 0) { 22 | /* free the mp_ints */ 23 | for (x = a->used; x < a->alloc; x++) { 24 | mp_clear(&(a->terms[x])); 25 | } 26 | 27 | /* resize the array of pointers */ 28 | tmp = realloc(a->terms, sizeof(mp_int) * a->used); 29 | if (tmp == NULL) { 30 | return MP_MEM; 31 | } 32 | a->terms = tmp; 33 | a->alloc = a->used; 34 | } 35 | 36 | /* now shrink each mp_int */ 37 | for (x = 0; x < a->used; x++) { 38 | if ((err = mp_shrink(&(a->terms[x]))) != MP_OKAY) { 39 | return err; 40 | } 41 | } 42 | return MP_OKAY; 43 | } 44 | 45 | 46 | -------------------------------------------------------------------------------- /pb_sub.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | int pb_sub(pb_poly *a, pb_poly *b, pb_poly *c) 15 | { 16 | int neg, err, x, y, z, characteristic; 17 | pb_poly *tmp; 18 | 19 | /* grow c to be the max size */ 20 | y = PB_MAX(a->used, b->used); 21 | if (c->alloc < y) { 22 | if ((err = pb_grow(c, y)) != MP_OKAY) { 23 | return err; 24 | } 25 | } 26 | 27 | /* do we need to concern char */ 28 | characteristic = mp_iszero(&(c->characteristic)); 29 | 30 | /* sub the terms */ 31 | z = PB_MIN(a->used, b->used); 32 | for (x = 0; x < z; x++) { 33 | if ((err = mp_sub(&(a->terms[x]), &(b->terms[x]), &(c->terms[x]))) != MP_OKAY) { 34 | return err; 35 | } 36 | if (characteristic == MP_NO) { 37 | if ((err = mp_mod(&(c->terms[x]), &(c->characteristic), &(c->terms[x]))) != MP_OKAY) { 38 | return err; 39 | } 40 | } 41 | } 42 | 43 | /* excess digits? */ 44 | if (y != z) { 45 | if (a->used == y) { 46 | tmp = a; 47 | neg = 0; 48 | } else { 49 | tmp = b; 50 | neg = 1; 51 | } 52 | for (x = z; x < y; x++) { 53 | if (characteristic == MP_NO) { 54 | if ((err = mp_mod(&(tmp->terms[x]), &(c->characteristic), &(c->terms[x]))) != MP_OKAY) { 55 | return err; 56 | } 57 | if (neg) { 58 | if ((err = mp_sub(&(c->characteristic), &(c->terms[x]), &(c->terms[x]))) != MP_OKAY) { 59 | return err; 60 | } 61 | } 62 | } else { 63 | if (neg) { 64 | if ((err = mp_neg(&(tmp->terms[x]), &(c->terms[x]))) != MP_OKAY) { 65 | return err; 66 | } 67 | } else { 68 | if ((err = mp_copy(&(tmp->terms[x]), &(c->terms[x]))) != MP_OKAY) { 69 | return err; 70 | } 71 | } 72 | } 73 | } 74 | } 75 | 76 | /* zero excess */ 77 | for (x = y; x < c->used; x++) { 78 | mp_zero(&(c->terms[x])); 79 | } 80 | c->used = y; 81 | pb_clamp(c); 82 | 83 | return MP_OKAY; 84 | } 85 | 86 | 87 | -------------------------------------------------------------------------------- /pb_submod.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | int pb_submod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d) 15 | { 16 | int err; 17 | pb_poly tmp; 18 | 19 | if ((err = pb_init(&tmp, &(d->characteristic))) != MP_OKAY) { 20 | return err; 21 | } 22 | if ((err = pb_sub(a, b, &tmp)) != MP_OKAY) { 23 | goto __TMP; 24 | } 25 | if ((err = pb_mod(&tmp, c, d)) != MP_OKAY) { 26 | goto __TMP; 27 | } 28 | 29 | err = MP_OKAY; 30 | __TMP: pb_clear(&tmp); 31 | return err; 32 | } 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /pb_toraw.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | int pb_toraw(pb_poly *a, unsigned char *dst) 15 | { 16 | int err, x, y, z; 17 | 18 | /* store the # of terms */ 19 | dst[0] = a->used & 255; 20 | dst[1] = (a->used >> 8) & 255; 21 | y = 2; 22 | 23 | /* store the characteristic */ 24 | z = mp_signed_bin_size(&(a->characteristic)); 25 | dst[y++] = z&255; 26 | dst[y++] = (z>>8)&255; 27 | if ((err = mp_to_signed_bin(&(a->characteristic), dst+y)) != MP_OKAY) { return err; } 28 | y += z; 29 | 30 | for (x = 0; x < a->used; x++) { 31 | z = mp_signed_bin_size(&(a->terms[x])); 32 | dst[y++] = z&255; 33 | dst[y++] = (z>>8)&255; 34 | if ((err = mp_to_signed_bin(&(a->terms[x]), dst+y)) != MP_OKAY) { return err; } 35 | y += z; 36 | } 37 | 38 | return MP_OKAY; 39 | } 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /pb_zero.c: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #include 13 | 14 | void pb_zero(pb_poly *a) 15 | { 16 | int x; 17 | for (x = 0; x < a->used; x++) { 18 | mp_zero(&(a->terms[x])); 19 | } 20 | a->used = 0; 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /tompoly.h: -------------------------------------------------------------------------------- 1 | /* LibTomPoly, Polynomial Basis Math -- Tom St Denis 2 | * 3 | * LibTomPoly is a public domain library that provides 4 | * polynomial basis arithmetic support. It relies on 5 | * LibTomMath for large integer support. 6 | * 7 | * This library is free for all purposes without any 8 | * express guarantee that it works. 9 | * 10 | * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org 11 | */ 12 | #ifndef TOMPOLY_H_ 13 | #define TOMPOLY_H_ 14 | 15 | #include 16 | 17 | /* this structure holds a polynomial */ 18 | typedef struct { 19 | int used, /* number of terms */ 20 | alloc; /* number of terms available (total) */ 21 | mp_int characteristic, /* characteristic, zero if not finite */ 22 | *terms; /* terms of polynomial */ 23 | } pb_poly; 24 | 25 | 26 | /* default number of terms */ 27 | #define PB_TERMS 4 28 | 29 | /* Compare codes */ 30 | #define PB_EQ 0 /* They're exactly equal */ 31 | #define PB_DEG_LT 1 /* The left has a lower degree */ 32 | #define PB_DEG_EQ 2 /* same degree */ 33 | #define PB_DEG_GT 3 /* The left has a higher degree */ 34 | 35 | int pb_init(pb_poly *a, mp_int *characteristic); 36 | int pb_init_size(pb_poly *a, mp_int *characteristic, int size); 37 | int pb_init_copy(pb_poly *a, pb_poly *b); 38 | int pb_init_multi(mp_int *characteristic, pb_poly *pb, ...); 39 | void pb_clear_multi(pb_poly *mp, ...); 40 | void pb_clear(pb_poly *a); 41 | 42 | int pb_shrink(pb_poly *a); 43 | int pb_grow(pb_poly *a, int size); 44 | void pb_clamp(pb_poly *a); 45 | 46 | /* dest(x) := src(x) */ 47 | int pb_copy(pb_poly *src, pb_poly *dest); 48 | 49 | /* compare these */ 50 | int pb_cmp(pb_poly *a, pb_poly *b); 51 | 52 | /* swap contents of a(x) and b(x) */ 53 | void pb_exch(pb_poly *a, pb_poly *b); 54 | 55 | /* a(x) = 0 */ 56 | void pb_zero(pb_poly *a); 57 | 58 | /* a(x) = a(x) / I(x)^x */ 59 | int pb_rshd(pb_poly *a, int x); 60 | 61 | /* a(x) = a(x) * I(x)^x */ 62 | int pb_lshd(pb_poly *a, int x); 63 | 64 | /* c(x) = a(x) + b(x) */ 65 | int pb_add(pb_poly *a, pb_poly *b, pb_poly *c); 66 | 67 | /* c(x) = a(x) - b(x) */ 68 | int pb_sub(pb_poly *a, pb_poly *b, pb_poly *c); 69 | 70 | /* c(x) = a(x) * b(x) */ 71 | int pb_mul(pb_poly *a, pb_poly *b, pb_poly *c); 72 | 73 | /* c(x) * b(x) + d(x) = a(x) */ 74 | int pb_div(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); 75 | 76 | /* c(x) = a(x) mod b(x) */ 77 | int pb_mod(pb_poly *a, pb_poly *b, pb_poly *c); 78 | 79 | /* d(x) = (a(x) + b(x)) mod c(x) */ 80 | int pb_addmod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); 81 | 82 | /* d(x) = (a(x) - b(x)) mod c(x) */ 83 | int pb_submod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); 84 | 85 | /* d(x) = (a(x) * b(x)) mod c(x) */ 86 | int pb_mulmod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); 87 | 88 | 89 | /* mathy stuff */ 90 | 91 | /* makes b equal to the monic polynomial form of a */ 92 | int pb_monic(pb_poly *a, pb_poly *b); 93 | 94 | /* returns the monic GCD of a,b in GF(p^k)[x] */ 95 | int pb_gcd(pb_poly *a, pb_poly *b, pb_poly *c); 96 | 97 | /* Extended euclidean algorithm of (a, b) produces a*u1 + b*u2 = u3 */ 98 | int pb_exteuclid(pb_poly *a, pb_poly *b, pb_poly *U1, pb_poly *U2, pb_poly *U3); 99 | 100 | /* finds the inverse of a modulo b and stores it in c such that a*c == 1 mod b */ 101 | int pb_invmod(pb_poly *a, pb_poly *b, pb_poly *c); 102 | 103 | /* computes Y == G^X mod P [accepts negative values for X] */ 104 | int pb_exptmod (pb_poly * G, mp_int * X, pb_poly * P, pb_poly * Y); 105 | 106 | /* is a(x) irreducible (GF(p)[x] only) */ 107 | int pb_isirreduc(pb_poly *a, int *res); 108 | 109 | 110 | /* I/O */ 111 | int pb_rawsize(pb_poly *a); 112 | int pb_toraw(pb_poly *a, unsigned char *dst); 113 | int pb_readraw(pb_poly *a, unsigned char *buf, int len); 114 | 115 | /* What follows should be in a private header, but it's fine for now like that. */ 116 | 117 | #ifndef PB_MIN 118 | #define PB_MIN(x, y) (((x) < (y)) ? (x) : (y)) 119 | #endif 120 | #ifndef PB_MAX 121 | #define PB_MAX(x, y) (((x) > (y)) ? (x) : (y)) 122 | #endif 123 | 124 | #endif 125 | --------------------------------------------------------------------------------