diff options
Diffstat (limited to 'libtommath')
278 files changed, 10465 insertions, 44293 deletions
diff --git a/libtommath/LICENSE b/libtommath/LICENSE index 04d6d1d..b23b3c8 100644 --- a/libtommath/LICENSE +++ b/libtommath/LICENSE @@ -1,29 +1,26 @@ -LibTomMath is licensed under DUAL licensing terms. - -Choose and use the license of your needs. - -[LICENSE #1] - -LibTomMath is public domain. As should all quality software be. - -Tom St Denis - -[/LICENSE #1] - -[LICENSE #2] - - DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE - Version 2, December 2004 - - Copyright (C) 2004 Sam Hocevar <sam@hocevar.net> - - Everyone is permitted to copy and distribute verbatim or modified - copies of this license document, and changing it is allowed as long - as the name is changed. - - DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. You just DO WHAT THE FUCK YOU WANT TO. - -[/LICENSE #2] + The LibTom license + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to <http://unlicense.org/> diff --git a/libtommath/Makefile.in b/libtommath/Makefile.in index 828e243..556adfc 100644 --- a/libtommath/Makefile.in +++ b/libtommath/Makefile.in @@ -7,6 +7,9 @@ srcdir=@srcdir@ # So that libtommath can include Dropbear headers for options and m_burn() CFLAGS += -I$(srcdir) -I../libtomcrypt/src/headers/ -I$(srcdir)/../libtomcrypt/src/headers/ -I../ -I$(srcdir)/../ +CFLAGS += -Wno-deprecated + +V = 1 ifeq ($V,1) silent= @@ -23,44 +26,46 @@ coverage: LIBNAME:=-Wl,--whole-archive $(LIBNAME) -Wl,--no-whole-archive include $(srcdir)/makefile_include.mk -%.o: %.c +%.o: %.c $(HEADERS) ifneq ($V,1) @echo " * ${CC} $@" endif - ${silent} ${CC} -c ${CFLAGS} $< -o $@ + ${silent} ${CC} -c ${LTM_CFLAGS} $< -o $@ LCOV_ARGS=--directory . #START_INS -OBJECTS=bncore.o bn_error.o bn_fast_mp_invmod.o bn_fast_mp_montgomery_reduce.o bn_fast_s_mp_mul_digs.o \ -bn_fast_s_mp_mul_high_digs.o bn_fast_s_mp_sqr.o bn_mp_2expt.o bn_mp_abs.o bn_mp_add.o bn_mp_add_d.o \ -bn_mp_addmod.o bn_mp_and.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp_cmp.o bn_mp_cmp_d.o \ -bn_mp_cmp_mag.o bn_mp_cnt_lsb.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_div_2.o bn_mp_div_2d.o bn_mp_div_3.o \ -bn_mp_div.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o bn_mp_dr_setup.o bn_mp_exch.o \ -bn_mp_export.o bn_mp_expt_d.o bn_mp_expt_d_ex.o bn_mp_exptmod.o bn_mp_exptmod_fast.o bn_mp_exteuclid.o \ -bn_mp_fread.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_int.o bn_mp_get_long.o bn_mp_get_long_long.o \ -bn_mp_grow.o bn_mp_import.o bn_mp_init.o bn_mp_init_copy.o bn_mp_init_multi.o bn_mp_init_set.o \ -bn_mp_init_set_int.o bn_mp_init_size.o bn_mp_invmod.o bn_mp_invmod_slow.o bn_mp_is_square.o \ -bn_mp_jacobi.o bn_mp_karatsuba_mul.o bn_mp_karatsuba_sqr.o bn_mp_lcm.o bn_mp_lshd.o bn_mp_mod_2d.o \ -bn_mp_mod.o bn_mp_mod_d.o bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o \ -bn_mp_montgomery_setup.o bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul.o bn_mp_mul_d.o bn_mp_mulmod.o bn_mp_neg.o \ -bn_mp_n_root.o bn_mp_n_root_ex.o bn_mp_or.o bn_mp_prime_fermat.o bn_mp_prime_is_divisible.o \ +OBJECTS=bn_cutoffs.o bn_deprecated.o bn_mp_2expt.o bn_mp_abs.o bn_mp_add.o bn_mp_add_d.o bn_mp_addmod.o \ +bn_mp_and.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp_cmp.o bn_mp_cmp_d.o bn_mp_cmp_mag.o \ +bn_mp_cnt_lsb.o bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_decr.o bn_mp_div.o bn_mp_div_2.o \ +bn_mp_div_2d.o bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o bn_mp_dr_setup.o \ +bn_mp_error_to_string.o bn_mp_exch.o bn_mp_expt_u32.o bn_mp_exptmod.o bn_mp_exteuclid.o bn_mp_fread.o \ +bn_mp_from_sbin.o bn_mp_from_ubin.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_i32.o bn_mp_get_i64.o \ +bn_mp_get_l.o bn_mp_get_ll.o bn_mp_get_mag_u32.o bn_mp_get_mag_u64.o bn_mp_get_mag_ul.o \ +bn_mp_get_mag_ull.o bn_mp_grow.o bn_mp_incr.o bn_mp_init.o bn_mp_init_copy.o bn_mp_init_i32.o \ +bn_mp_init_i64.o bn_mp_init_l.o bn_mp_init_ll.o bn_mp_init_multi.o bn_mp_init_set.o bn_mp_init_size.o \ +bn_mp_init_u32.o bn_mp_init_u64.o bn_mp_init_ul.o bn_mp_init_ull.o bn_mp_invmod.o bn_mp_is_square.o \ +bn_mp_iseven.o bn_mp_isodd.o bn_mp_kronecker.o bn_mp_lcm.o bn_mp_log_u32.o bn_mp_lshd.o bn_mp_mod.o \ +bn_mp_mod_2d.o bn_mp_mod_d.o bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o \ +bn_mp_montgomery_setup.o bn_mp_mul.o bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_mulmod.o bn_mp_neg.o \ +bn_mp_or.o bn_mp_pack.o bn_mp_pack_count.o bn_mp_prime_fermat.o bn_mp_prime_frobenius_underwood.o \ bn_mp_prime_is_prime.o bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o \ -bn_mp_prime_rabin_miller_trials.o bn_mp_prime_random_ex.o bn_mp_radix_size.o bn_mp_radix_smap.o \ -bn_mp_rand.o bn_mp_read_radix.o bn_mp_read_signed_bin.o bn_mp_read_unsigned_bin.o bn_mp_reduce_2k.o \ -bn_mp_reduce_2k_l.o bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o bn_mp_reduce.o \ -bn_mp_reduce_is_2k.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_setup.o bn_mp_rshd.o bn_mp_set.o bn_mp_set_int.o \ -bn_mp_set_long.o bn_mp_set_long_long.o bn_mp_shrink.o bn_mp_signed_bin_size.o bn_mp_sqr.o bn_mp_sqrmod.o \ -bn_mp_sqrt.o bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o bn_mp_submod.o bn_mp_toom_mul.o \ -bn_mp_toom_sqr.o bn_mp_toradix.o bn_mp_toradix_n.o bn_mp_to_signed_bin.o bn_mp_to_signed_bin_n.o \ -bn_mp_to_unsigned_bin.o bn_mp_to_unsigned_bin_n.o bn_mp_unsigned_bin_size.o bn_mp_xor.o bn_mp_zero.o \ -bn_prime_tab.o bn_reverse.o bn_s_mp_add.o bn_s_mp_exptmod.o bn_s_mp_mul_digs.o bn_s_mp_mul_high_digs.o \ -bn_s_mp_sqr.o bn_s_mp_sub.o +bn_mp_prime_rabin_miller_trials.o bn_mp_prime_rand.o bn_mp_prime_strong_lucas_selfridge.o \ +bn_mp_radix_size.o bn_mp_radix_smap.o bn_mp_rand.o bn_mp_read_radix.o bn_mp_reduce.o bn_mp_reduce_2k.o \ +bn_mp_reduce_2k_l.o bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o bn_mp_reduce_is_2k.o \ +bn_mp_reduce_is_2k_l.o bn_mp_reduce_setup.o bn_mp_root_u32.o bn_mp_rshd.o bn_mp_sbin_size.o bn_mp_set.o \ +bn_mp_set_i32.o bn_mp_set_i64.o bn_mp_set_l.o bn_mp_set_ll.o bn_mp_set_u32.o bn_mp_set_u64.o \ +bn_mp_set_ul.o bn_mp_set_ull.o bn_mp_shrink.o bn_mp_signed_rsh.o bn_mp_sqr.o bn_mp_sqrmod.o bn_mp_sqrt.o \ +bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o bn_mp_submod.o bn_mp_to_radix.o bn_mp_to_sbin.o \ +bn_mp_to_ubin.o bn_mp_ubin_size.o bn_mp_unpack.o bn_mp_xor.o bn_mp_zero.o bn_prime_tab.o bn_s_mp_add.o \ +bn_s_mp_balance_mul.o bn_s_mp_exptmod.o bn_s_mp_exptmod_fast.o bn_s_mp_get_bit.o bn_s_mp_invmod_fast.o \ +bn_s_mp_invmod_slow.o bn_s_mp_karatsuba_mul.o bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o \ +bn_s_mp_mul_digs.o bn_s_mp_mul_digs_fast.o bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o \ +bn_s_mp_prime_is_divisible.o bn_s_mp_rand_jenkins.o bn_s_mp_rand_platform.o bn_s_mp_reverse.o \ +bn_s_mp_sqr.o bn_s_mp_sqr_fast.o bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o #END_INS -$(OBJECTS): $(HEADERS) - $(LIBNAME): $(OBJECTS) $(AR) $(ARFLAGS) $@ $(OBJECTS) $(RANLIB) $@ @@ -73,20 +78,20 @@ $(LIBNAME): $(OBJECTS) # So far I've seen improvements in the MP math profiled: make CFLAGS="$(CFLAGS) -fprofile-arcs -DTESTING" timing - ./ltmtest - rm -f *.a *.o ltmtest + ./timing + rm -f *.a *.o timing make CFLAGS="$(CFLAGS) -fbranch-probabilities" #make a single object profiled library profiled_single: perl gen.pl - $(CC) $(CFLAGS) -fprofile-arcs -DTESTING -c mpi.c -o mpi.o - $(CC) $(CFLAGS) -DTESTING -DTIMER demo/timing.c mpi.o -lgcov -o ltmtest - ./ltmtest - rm -f *.o ltmtest - $(CC) $(CFLAGS) -fbranch-probabilities -DTESTING -c mpi.c -o mpi.o + $(CC) $(LTM_CFLAGS) -fprofile-arcs -DTESTING -c mpi.c -o mpi.o + $(CC) $(LTM_CFLAGS) -DTESTING -DTIMER demo/timing.c mpi.o -lgcov -o timing + ./timing + rm -f *.o timing + $(CC) $(LTM_CFLAGS) -fbranch-probabilities -DTESTING -c mpi.c -o mpi.o $(AR) $(ARFLAGS) $(LIBNAME) mpi.o - $(RANLIB) $(LIBNAME) + ranlib $(LIBNAME) install: $(LIBNAME) install -d $(DESTDIR)$(LIBPATH) @@ -98,41 +103,45 @@ uninstall: rm $(DESTDIR)$(LIBPATH)/$(LIBNAME) rm $(HEADERS_PUB:%=$(DESTDIR)$(INCPATH)/%) -test: $(LIBNAME) demo/demo.o - $(CC) $(CFLAGS) demo/demo.o $(LIBNAME) $(LFLAGS) -o test +test_standalone: test + @echo "test_standalone is deprecated, please use make-target 'test'" + +DEMOS=test mtest_opponent -test_standalone: $(LIBNAME) demo/demo.o - $(CC) $(CFLAGS) demo/demo.o $(LIBNAME) $(LFLAGS) -o test +define DEMO_template +$(1): demo/$(1).o demo/shared.o $$(LIBNAME) + $$(CC) $$(LTM_CFLAGS) $$(LTM_LFLAGS) $$^ -o $$@ +endef + +$(foreach demo, $(strip $(DEMOS)), $(eval $(call DEMO_template,$(demo)))) .PHONY: mtest mtest: - cd mtest ; $(CC) $(CFLAGS) -O0 mtest.c $(LFLAGS) -o mtest + cd mtest ; $(CC) $(LTM_CFLAGS) -O0 mtest.c $(LTM_LFLAGS) -o mtest -travis_mtest: test mtest - @ for i in `seq 1 10` ; do sleep 500 && echo alive; done & - ./mtest/mtest 666666 | ./test > test.log +timing: $(LIBNAME) demo/timing.c + $(CC) $(LTM_CFLAGS) -DTIMER demo/timing.c $(LIBNAME) $(LTM_LFLAGS) -o timing -timing: $(LIBNAME) - $(CC) $(CFLAGS) -DTIMER demo/timing.c $(LIBNAME) $(LFLAGS) -o ltmtest +tune: $(LIBNAME) + $(MAKE) -C etc tune CFLAGS="$(LTM_CFLAGS)" + $(MAKE) # You have to create a file .coveralls.yml with the content "repo_token: <the token>" # in the base folder to be able to submit to coveralls coveralls: lcov coveralls-lcov -docdvi poster docs mandvi manual: +docs manual: $(MAKE) -C doc/ $@ V=$(V) -pretty: - perl pretty.build - .PHONY: pre_gen pre_gen: + mkdir -p pre_gen perl gen.pl sed -e 's/[[:blank:]]*$$//' mpi.c > pre_gen/mpi.c rm mpi.c -zipup: clean pre_gen new_file manual poster docs +zipup: clean astyle new_file docs @# Update the index, so diff-index won't fail in case the pdf has been created. @# As the pdf creation modifies the tex files, git sometimes detects the @# modified files, but misses that it's put back to its original version. @@ -141,17 +150,24 @@ zipup: clean pre_gen new_file manual poster docs rm -rf libtommath-$(VERSION) ltm-$(VERSION).* @# files/dirs excluded from "git archive" are defined in .gitattributes git archive --format=tar --prefix=libtommath-$(VERSION)/ HEAD | tar x + @echo 'fixme check' + -@(find libtommath-$(VERSION)/ -type f | xargs grep 'FIXM[E]') && echo '############## BEWARE: the "fixme" marker was found !!! ##############' || true mkdir -p libtommath-$(VERSION)/doc - cp doc/bn.pdf doc/tommath.pdf doc/poster.pdf libtommath-$(VERSION)/doc/ + cp doc/bn.pdf libtommath-$(VERSION)/doc/ + $(MAKE) -C libtommath-$(VERSION)/ pre_gen tar -c libtommath-$(VERSION)/ | xz -6e -c - > ltm-$(VERSION).tar.xz zip -9rq ltm-$(VERSION).zip libtommath-$(VERSION) + cp doc/bn.pdf bn-$(VERSION).pdf rm -rf libtommath-$(VERSION) gpg -b -a ltm-$(VERSION).tar.xz gpg -b -a ltm-$(VERSION).zip new_file: - bash updatemakes.sh - perl dep.pl + perl helper.pl --update-files perlcritic: - perlcritic *.pl + perlcritic *.pl doc/*.pl + +astyle: + @echo " * run astyle on all sources" + @astyle --options=astylerc --formatted $(OBJECTS:.o=.c) tommath*.h demo/*.c etc/*.c mtest/mtest.c diff --git a/libtommath/README.md b/libtommath/README.md index 4c5da71..be5b207 100644 --- a/libtommath/README.md +++ b/libtommath/README.md @@ -1,15 +1,44 @@ -[](https://travis-ci.org/libtom/libtommath) +# libtommath -[](https://travis-ci.org/libtom/libtommath) +This is the git repository for [LibTomMath](http://www.libtom.net/LibTomMath/), a free open source portable number theoretic multiple-precision integer (MPI) library written entirely in C. -This is the git repository for [LibTomMath](http://www.libtom.org/), a free open source portable number theoretic multiple-precision integer (MPI) library written entirely in C. +## Build Status + +### Travis CI + +master: [](https://travis-ci.org/libtom/libtommath) + +develop: [](https://travis-ci.org/libtom/libtommath) + +### AppVeyor + +master: [](https://ci.appveyor.com/project/libtom/libtommath/branch/master) + +develop: [](https://ci.appveyor.com/project/libtom/libtommath/branch/develop) + +### ABI Laboratory + +API/ABI changes: [check here](https://abi-laboratory.pro/tracker/timeline/libtommath/) + +## Summary The `develop` branch contains the in-development version. Stable releases are tagged. -Documentation is built from the LaTeX file `bn.tex`. There is also limited documentation in `tommath.h`. There is also a document, `tommath.pdf`, which describes the goals of the project and many of the algorithms used. +Documentation is built from the LaTeX file `bn.tex`. There is also limited documentation in `tommath.h`. +There is also a document, `tommath.pdf`, which describes the goals of the project and many of the algorithms used. -The project can be build by using `make`. Along with the usual `make`, `make clean` and `make install`, there are several other build targets, see the makefile for details. There are also makefiles for certain specific platforms. +The project can be build by using `make`. Along with the usual `make`, `make clean` and `make install`, +there are several other build targets, see the makefile for details. +There are also makefiles for certain specific platforms. + +## Testing Tests are located in `demo/` and can be built in two flavors. -* `make test` creates a test binary that is intended to be run against `mtest`. `mtest` can be built with `make mtest` and test execution is done like `./mtest/mtest | ./test`. `mtest` is creating test vectors using an alternative MPI library and `test` is consuming these vectors to verify correct behavior of ltm -* `make test_standalone` creates a stand-alone test binary that executes several test routines. +* `make test` creates a stand-alone test binary that executes several test routines. +* `make mtest_opponent` creates a test binary that is intended to be run against `mtest`. + `mtest` can be built with `make mtest` and test execution is done like `./mtest/mtest | ./mtest_opponent`. + `mtest` is creating test vectors using an alternative MPI library and `test` is consuming these vectors to verify correct behavior of ltm + +## Building and Installing + +Building is straightforward for GNU Linux only, the section "Building LibTomMath" in the documentation in `doc/bn.pdf` has the details. diff --git a/libtommath/astylerc b/libtommath/astylerc new file mode 100644 index 0000000..c5ff779 --- /dev/null +++ b/libtommath/astylerc @@ -0,0 +1,30 @@ +# Artistic Style, see http://astyle.sourceforge.net/ +# full documentation, see: http://astyle.sourceforge.net/astyle.html +# +# usage: +# astyle --options=astylerc *.[ch] + +# Do not create backup, annonying in the times of git +suffix=none + +## Bracket Style Options +style=kr + +## Tab Options +indent=spaces=3 + +## Bracket Modify Options + +## Indentation Options +min-conditional-indent=0 + +## Padding Options +pad-header +unpad-paren +align-pointer=name + +## Formatting Options +break-after-logical +max-code-length=120 +convert-tabs +mode=c diff --git a/libtommath/bn.tex b/libtommath/bn.tex deleted file mode 100644 index 5804318..0000000 --- a/libtommath/bn.tex +++ /dev/null @@ -1,1913 +0,0 @@ -\documentclass[synpaper]{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{LibTomMath User Manual \\ v1.0} -\author{Tom St Denis \\ tstdenis82@gmail.com} -\maketitle -This text, the library and the accompanying textbook are all hereby placed in the public domain. This book has been -formatted for B5 [176x250] paper using the \LaTeX{} {\em book} macro package. - -\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 LibTomMath?} -LibTomMath is a library of source code which provides a series of efficient and carefully written functions for manipulating -large integer numbers. It was written in portable ISO C source code so that it will build on any platform with a conforming -C compiler. - -In a nutshell the library was written from scratch with verbose comments to help instruct computer science students how -to implement ``bignum'' math. However, the resulting code has proven to be very useful. It has been used by numerous -universities, commercial and open source software developers. It has been used on a variety of platforms ranging from -Linux and Windows based x86 to ARM based Gameboys and PPC based MacOS machines. - -\section{License} -As of the v0.25 the library source code has been placed in the public domain with every new release. As of the v0.28 -release the textbook ``Implementing Multiple Precision Arithmetic'' has been placed in the public domain with every new -release as well. This textbook is meant to compliment the project by providing a more solid walkthrough of the development -algorithms used in the library. - -Since both\footnote{Note that the MPI files under mtest/ are copyrighted by Michael Fromberger. They are not required to use LibTomMath.} are in the -public domain everyone is entitled to do with them as they see fit. - -\section{Building LibTomMath} - -LibTomMath is meant to be very ``GCC friendly'' as it comes with a makefile well suited for GCC. However, the library will -also build in MSVC, Borland C out of the box. For any other ISO C compiler a makefile will have to be made by the end -developer. - -\subsection{Static Libraries} -To build as a static library for GCC issue the following -\begin{alltt} -make -\end{alltt} - -command. This will build the library and archive the object files in ``libtommath.a''. Now you link against -that and include ``tommath.h'' within your programs. Alternatively to build with MSVC issue the following -\begin{alltt} -nmake -f makefile.msvc -\end{alltt} - -This will build the library and archive the object files in ``tommath.lib''. This has been tested with MSVC -version 6.00 with service pack 5. - -\subsection{Shared Libraries} -To build as a shared library for GCC issue the following -\begin{alltt} -make -f makefile.shared -\end{alltt} -This requires the ``libtool'' package (common on most Linux/BSD systems). It will build LibTomMath as both shared -and static then install (by default) into /usr/lib as well as install the header files in /usr/include. The shared -library (resource) will be called ``libtommath.la'' while the static library called ``libtommath.a''. Generally -you use libtool to link your application against the shared object. - -There is limited support for making a ``DLL'' in windows via the ``makefile.cygwin\_dll'' makefile. It requires -Cygwin to work with since it requires the auto-export/import functionality. The resulting DLL and import library -``libtommath.dll.a'' can be used to link LibTomMath dynamically to any Windows program using Cygwin. - -\subsection{Testing} -To build the library and the test harness type - -\begin{alltt} -make test -\end{alltt} - -This will build the library, ``test'' and ``mtest/mtest''. The ``test'' program will accept test vectors and verify the -results. ``mtest/mtest'' will generate test vectors using the MPI library by Michael Fromberger\footnote{A copy of MPI -is included in the package}. Simply pipe mtest into test using - -\begin{alltt} -mtest/mtest | test -\end{alltt} - -If you do not have a ``/dev/urandom'' style RNG source you will have to write your own PRNG and simply pipe that into -mtest. For example, if your PRNG program is called ``myprng'' simply invoke - -\begin{alltt} -myprng | mtest/mtest | test -\end{alltt} - -This will output a row of numbers that are increasing. Each column is a different test (such as addition, multiplication, etc) -that is being performed. The numbers represent how many times the test was invoked. If an error is detected the program -will exit with a dump of the relevent numbers it was working with. - -\section{Build Configuration} -LibTomMath can configured at build time in three phases we shall call ``depends'', ``tweaks'' and ``trims''. -Each phase changes how the library is built and they are applied one after another respectively. - -To make the system more powerful you can tweak the build process. Classes are defined in the file -``tommath\_superclass.h''. By default, the symbol ``LTM\_ALL'' shall be defined which simply -instructs the system to build all of the functions. This is how LibTomMath used to be packaged. This will give you -access to every function LibTomMath offers. - -However, there are cases where such a build is not optional. For instance, you want to perform RSA operations. You -don't need the vast majority of the library to perform these operations. Aside from LTM\_ALL there is -another pre--defined class ``SC\_RSA\_1'' which works in conjunction with the RSA from LibTomCrypt. Additional -classes can be defined base on the need of the user. - -\subsection{Build Depends} -In the file tommath\_class.h you will see a large list of C ``defines'' followed by a series of ``ifdefs'' -which further define symbols. All of the symbols (technically they're macros $\ldots$) represent a given C source -file. For instance, BN\_MP\_ADD\_C represents the file ``bn\_mp\_add.c''. When a define has been enabled the -function in the respective file will be compiled and linked into the library. Accordingly when the define -is absent the file will not be compiled and not contribute any size to the library. - -You will also note that the header tommath\_class.h is actually recursively included (it includes itself twice). -This is to help resolve as many dependencies as possible. In the last pass the symbol LTM\_LAST will be defined. -This is useful for ``trims''. - -\subsection{Build Tweaks} -A tweak is an algorithm ``alternative''. For example, to provide tradeoffs (usually between size and space). -They can be enabled at any pass of the configuration phase. - -\begin{small} -\begin{center} -\begin{tabular}{|l|l|} -\hline \textbf{Define} & \textbf{Purpose} \\ -\hline BN\_MP\_DIV\_SMALL & Enables a slower, smaller and equally \\ - & functional mp\_div() function \\ -\hline -\end{tabular} -\end{center} -\end{small} - -\subsection{Build Trims} -A trim is a manner of removing functionality from a function that is not required. For instance, to perform -RSA cryptography you only require exponentiation with odd moduli so even moduli support can be safely removed. -Build trims are meant to be defined on the last pass of the configuration which means they are to be defined -only if LTM\_LAST has been defined. - -\subsubsection{Moduli Related} -\begin{small} -\begin{center} -\begin{tabular}{|l|l|} -\hline \textbf{Restriction} & \textbf{Undefine} \\ -\hline Exponentiation with odd moduli only & BN\_S\_MP\_EXPTMOD\_C \\ - & BN\_MP\_REDUCE\_C \\ - & BN\_MP\_REDUCE\_SETUP\_C \\ - & BN\_S\_MP\_MUL\_HIGH\_DIGS\_C \\ - & BN\_FAST\_S\_MP\_MUL\_HIGH\_DIGS\_C \\ -\hline Exponentiation with random odd moduli & (The above plus the following) \\ - & BN\_MP\_REDUCE\_2K\_C \\ - & BN\_MP\_REDUCE\_2K\_SETUP\_C \\ - & BN\_MP\_REDUCE\_IS\_2K\_C \\ - & BN\_MP\_DR\_IS\_MODULUS\_C \\ - & BN\_MP\_DR\_REDUCE\_C \\ - & BN\_MP\_DR\_SETUP\_C \\ -\hline Modular inverse odd moduli only & BN\_MP\_INVMOD\_SLOW\_C \\ -\hline Modular inverse (both, smaller/slower) & BN\_FAST\_MP\_INVMOD\_C \\ -\hline -\end{tabular} -\end{center} -\end{small} - -\subsubsection{Operand Size Related} -\begin{small} -\begin{center} -\begin{tabular}{|l|l|} -\hline \textbf{Restriction} & \textbf{Undefine} \\ -\hline Moduli $\le 2560$ bits & BN\_MP\_MONTGOMERY\_REDUCE\_C \\ - & BN\_S\_MP\_MUL\_DIGS\_C \\ - & BN\_S\_MP\_MUL\_HIGH\_DIGS\_C \\ - & BN\_S\_MP\_SQR\_C \\ -\hline Polynomial Schmolynomial & BN\_MP\_KARATSUBA\_MUL\_C \\ - & BN\_MP\_KARATSUBA\_SQR\_C \\ - & BN\_MP\_TOOM\_MUL\_C \\ - & BN\_MP\_TOOM\_SQR\_C \\ - -\hline -\end{tabular} -\end{center} -\end{small} - - -\section{Purpose of LibTomMath} -Unlike GNU MP (GMP) Library, LIP, OpenSSL or various other commercial kits (Miracl), LibTomMath was not written with -bleeding edge performance in mind. First and foremost LibTomMath was written to be entirely open. Not only is the -source code public domain (unlike various other GPL/etc licensed code), not only is the code freely downloadable but the -source code is also accessible for computer science students attempting to learn ``BigNum'' or multiple precision -arithmetic techniques. - -LibTomMath was written to be an instructive collection of source code. This is why there are many comments, only one -function per source file and often I use a ``middle-road'' approach where I don't cut corners for an extra 2\% speed -increase. - -Source code alone cannot really teach how the algorithms work which is why I also wrote a textbook that accompanies -the library (beat that!). - -So you may be thinking ``should I use LibTomMath?'' and the answer is a definite maybe. Let me tabulate what I think -are the pros and cons of LibTomMath by comparing it to the math routines from GnuPG\footnote{GnuPG v1.2.3 versus LibTomMath v0.28}. - -\newpage\begin{figure}[here] -\begin{small} -\begin{center} -\begin{tabular}{|l|c|c|l|} -\hline \textbf{Criteria} & \textbf{Pro} & \textbf{Con} & \textbf{Notes} \\ -\hline Few lines of code per file & X & & GnuPG $ = 300.9$, LibTomMath $ = 71.97$ \\ -\hline Commented function prototypes & X && GnuPG function names are cryptic. \\ -\hline Speed && X & LibTomMath is slower. \\ -\hline Totally free & X & & GPL has unfavourable restrictions.\\ -\hline Large function base & X & & GnuPG is barebones. \\ -\hline Five modular reduction algorithms & X & & Faster modular exponentiation for a variety of moduli. \\ -\hline Portable & X & & GnuPG requires configuration to build. \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{LibTomMath Valuation} -\end{figure} - -It may seem odd to compare LibTomMath to GnuPG since the math in GnuPG is only a small portion of the entire application. -However, LibTomMath was written with cryptography in mind. It provides essentially all of the functions a cryptosystem -would require when working with large integers. - -So it may feel tempting to just rip the math code out of GnuPG (or GnuMP where it was taken from originally) in your -own application but I think there are reasons not to. While LibTomMath is slower than libraries such as GnuMP it is -not normally significantly slower. On x86 machines the difference is normally a factor of two when performing modular -exponentiations. It depends largely on the processor, compiler and the moduli being used. - -Essentially the only time you wouldn't use LibTomMath is when blazing speed is the primary concern. However, -on the other side of the coin LibTomMath offers you a totally free (public domain) well structured math library -that is very flexible, complete and performs well in resource contrained environments. Fast RSA for example can -be performed with as little as 8KB of ram for data (again depending on build options). - -\chapter{Getting Started with LibTomMath} -\section{Building Programs} -In order to use LibTomMath you must include ``tommath.h'' and link against the appropriate library file (typically -libtommath.a). There is no library initialization required and the entire library is thread safe. - -\section{Return Codes} -There are three possible return codes a function may return. - -\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} - -The last two codes listed are not actually ``return'ed'' by a function. They are placed in an integer (the caller must -provide the address of an integer it can store to) which the caller can access. To convert one of the three return codes -to a string use the following function. - -\index{mp\_error\_to\_string} -\begin{alltt} -char *mp_error_to_string(int code); -\end{alltt} - -This will return a pointer to a string which describes the given error code. It will not work for the return codes -MP\_YES and MP\_NO. - -\section{Data Types} -The basic ``multiple precision integer'' type is known as the ``mp\_int'' within LibTomMath. This data type is used to -organize all of the data required to manipulate the integer it represents. Within LibTomMath it has been prototyped -as the following. - -\index{mp\_int} -\begin{alltt} -typedef struct \{ - int used, alloc, sign; - mp_digit *dp; -\} mp_int; -\end{alltt} - -Where ``mp\_digit'' is a data type that represents individual digits of the integer. By default, an mp\_digit is the -ISO C ``unsigned long'' data type and each digit is $28-$bits long. The mp\_digit type can be configured to suit other -platforms by defining the appropriate macros. - -All LTM functions that use the mp\_int type will expect a pointer to mp\_int structure. You must allocate memory to -hold the structure itself by yourself (whether off stack or heap it doesn't matter). The very first thing that must be -done to use an mp\_int is that it must be initialized. - -\section{Function Organization} - -The arithmetic functions of the library are all organized to have the same style prototype. That is source operands -are passed on the left and the destination is on the right. For instance, - -\begin{alltt} -mp_add(&a, &b, &c); /* c = a + b */ -mp_mul(&a, &a, &c); /* c = a * a */ -mp_div(&a, &b, &c, &d); /* c = [a/b], d = a mod b */ -\end{alltt} - -Another feature of the way the functions have been implemented is that source operands can be destination operands as well. -For instance, - -\begin{alltt} -mp_add(&a, &b, &b); /* b = a + b */ -mp_div(&a, &b, &a, &c); /* a = [a/b], c = a mod b */ -\end{alltt} - -This allows operands to be re-used which can make programming simpler. - -\section{Initialization} -\subsection{Single Initialization} -A single mp\_int can be initialized with the ``mp\_init'' function. - -\index{mp\_init} -\begin{alltt} -int mp_init (mp_int * a); -\end{alltt} - -This function expects a pointer to an mp\_int structure and will initialize the members of the structure so the mp\_int -represents the default integer which is zero. If the functions returns MP\_OKAY then the mp\_int is ready to be used -by the other LibTomMath functions. - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int number; - int result; - - if ((result = mp_init(&number)) != MP_OKAY) \{ - printf("Error initializing the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* use the number */ - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -\subsection{Single Free} -When you are finished with an mp\_int it is ideal to return the heap it used back to the system. The following function -provides this functionality. - -\index{mp\_clear} -\begin{alltt} -void mp_clear (mp_int * a); -\end{alltt} - -The function expects a pointer to a previously initialized mp\_int structure and frees the heap it uses. It sets the -pointer\footnote{The ``dp'' member.} within the mp\_int to \textbf{NULL} which is used to prevent double free situations. -Is is legal to call mp\_clear() twice on the same mp\_int in a row. - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int number; - int result; - - if ((result = mp_init(&number)) != MP_OKAY) \{ - printf("Error initializing the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* use the number */ - - /* We're done with it. */ - mp_clear(&number); - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -\subsection{Multiple Initializations} -Certain algorithms require more than one large integer. In these instances it is ideal to initialize all of the mp\_int -variables in an ``all or nothing'' fashion. That is, they are either all initialized successfully or they are all -not initialized. - -The mp\_init\_multi() function provides this functionality. - -\index{mp\_init\_multi} \index{mp\_clear\_multi} -\begin{alltt} -int mp_init_multi(mp_int *mp, ...); -\end{alltt} - -It accepts a \textbf{NULL} terminated list of pointers to mp\_int structures. It will attempt to initialize them all -at once. If the function returns MP\_OKAY then all of the mp\_int variables are ready to use, otherwise none of them -are available for use. A complementary mp\_clear\_multi() function allows multiple mp\_int variables to be free'd -from the heap at the same time. - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int num1, num2, num3; - int result; - - if ((result = mp_init_multi(&num1, - &num2, - &num3, NULL)) != MP\_OKAY) \{ - printf("Error initializing the numbers. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* use the numbers */ - - /* We're done with them. */ - mp_clear_multi(&num1, &num2, &num3, NULL); - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -\subsection{Other Initializers} -To initialized and make a copy of an mp\_int the mp\_init\_copy() function has been provided. - -\index{mp\_init\_copy} -\begin{alltt} -int mp_init_copy (mp_int * a, mp_int * b); -\end{alltt} - -This function will initialize $a$ and make it a copy of $b$ if all goes well. - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int num1, num2; - int result; - - /* initialize and do work on num1 ... */ - - /* We want a copy of num1 in num2 now */ - if ((result = mp_init_copy(&num2, &num1)) != MP_OKAY) \{ - printf("Error initializing the copy. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* now num2 is ready and contains a copy of num1 */ - - /* We're done with them. */ - mp_clear_multi(&num1, &num2, NULL); - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -Another less common initializer is mp\_init\_size() which allows the user to initialize an mp\_int with a given -default number of digits. By default, all initializers allocate \textbf{MP\_PREC} digits. This function lets -you override this behaviour. - -\index{mp\_init\_size} -\begin{alltt} -int mp_init_size (mp_int * a, int size); -\end{alltt} - -The $size$ parameter must be greater than zero. If the function succeeds the mp\_int $a$ will be initialized -to have $size$ digits (which are all initially zero). - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int number; - int result; - - /* we need a 60-digit number */ - if ((result = mp_init_size(&number, 60)) != MP_OKAY) \{ - printf("Error initializing the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* use the number */ - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -\section{Maintenance Functions} - -\subsection{Reducing Memory Usage} -When an mp\_int is in a state where it won't be changed again\footnote{A Diffie-Hellman modulus for instance.} excess -digits can be removed to return memory to the heap with the mp\_shrink() function. - -\index{mp\_shrink} -\begin{alltt} -int mp_shrink (mp_int * a); -\end{alltt} - -This will remove excess digits of the mp\_int $a$. If the operation fails the mp\_int should be intact without the -excess digits being removed. Note that you can use a shrunk mp\_int in further computations, however, such operations -will require heap operations which can be slow. It is not ideal to shrink mp\_int variables that you will further -modify in the system (unless you are seriously low on memory). - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int number; - int result; - - if ((result = mp_init(&number)) != MP_OKAY) \{ - printf("Error initializing the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* use the number [e.g. pre-computation] */ - - /* We're done with it for now. */ - if ((result = mp_shrink(&number)) != MP_OKAY) \{ - printf("Error shrinking the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* use it .... */ - - - /* we're done with it. */ - mp_clear(&number); - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -\subsection{Adding additional digits} - -Within the mp\_int structure are two parameters which control the limitations of the array of digits that represent -the integer the mp\_int is meant to equal. The \textit{used} parameter dictates how many digits are significant, that is, -contribute to the value of the mp\_int. The \textit{alloc} parameter dictates how many digits are currently available in -the array. If you need to perform an operation that requires more digits you will have to mp\_grow() the mp\_int to -your desired size. - -\index{mp\_grow} -\begin{alltt} -int mp_grow (mp_int * a, int size); -\end{alltt} - -This will grow the array of digits of $a$ to $size$. If the \textit{alloc} parameter is already bigger than -$size$ the function will not do anything. - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int number; - int result; - - if ((result = mp_init(&number)) != MP_OKAY) \{ - printf("Error initializing the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* use the number */ - - /* We need to add 20 digits to the number */ - if ((result = mp_grow(&number, number.alloc + 20)) != MP_OKAY) \{ - printf("Error growing the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - - /* use the number */ - - /* we're done with it. */ - mp_clear(&number); - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -\chapter{Basic Operations} -\section{Small Constants} -Setting mp\_ints to small constants is a relatively common operation. To accomodate these instances there are two -small constant assignment functions. The first function is used to set a single digit constant while the second sets -an ISO C style ``unsigned long'' constant. The reason for both functions is efficiency. Setting a single digit is quick but the -domain of a digit can change (it's always at least $0 \ldots 127$). - -\subsection{Single Digit} - -Setting a single digit can be accomplished with the following function. - -\index{mp\_set} -\begin{alltt} -void mp_set (mp_int * a, mp_digit b); -\end{alltt} - -This will zero the contents of $a$ and make it represent an integer equal to the value of $b$. Note that this -function has a return type of \textbf{void}. It cannot cause an error so it is safe to assume the function -succeeded. - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int number; - int result; - - if ((result = mp_init(&number)) != MP_OKAY) \{ - printf("Error initializing the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* set the number to 5 */ - mp_set(&number, 5); - - /* we're done with it. */ - mp_clear(&number); - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -\subsection{Long Constants} - -To set a constant that is the size of an ISO C ``unsigned long'' and larger than a single digit the following function -can be used. - -\index{mp\_set\_int} -\begin{alltt} -int mp_set_int (mp_int * a, unsigned long b); -\end{alltt} - -This will assign the value of the 32-bit variable $b$ to the mp\_int $a$. Unlike mp\_set() this function will always -accept a 32-bit input regardless of the size of a single digit. However, since the value may span several digits -this function can fail if it runs out of heap memory. - -To get the ``unsigned long'' copy of an mp\_int the following function can be used. - -\index{mp\_get\_int} -\begin{alltt} -unsigned long mp_get_int (mp_int * a); -\end{alltt} - -This will return the 32 least significant bits of the mp\_int $a$. - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int number; - int result; - - if ((result = mp_init(&number)) != MP_OKAY) \{ - printf("Error initializing the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* set the number to 654321 (note this is bigger than 127) */ - if ((result = mp_set_int(&number, 654321)) != MP_OKAY) \{ - printf("Error setting the value of the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - printf("number == \%lu", mp_get_int(&number)); - - /* we're done with it. */ - mp_clear(&number); - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -This should output the following if the program succeeds. - -\begin{alltt} -number == 654321 -\end{alltt} - -\subsection{Long Constants - platform dependant} - -\index{mp\_set\_long} -\begin{alltt} -int mp_set_long (mp_int * a, unsigned long b); -\end{alltt} - -This will assign the value of the platform-dependant sized variable $b$ to the mp\_int $a$. - -To get the ``unsigned long'' copy of an mp\_int the following function can be used. - -\index{mp\_get\_long} -\begin{alltt} -unsigned long mp_get_long (mp_int * a); -\end{alltt} - -This will return the least significant bits of the mp\_int $a$ that fit into an ``unsigned long''. - -\subsection{Long Long Constants} - -\index{mp\_set\_long\_long} -\begin{alltt} -int mp_set_long_long (mp_int * a, unsigned long long b); -\end{alltt} - -This will assign the value of the 64-bit variable $b$ to the mp\_int $a$. - -To get the ``unsigned long long'' copy of an mp\_int the following function can be used. - -\index{mp\_get\_long\_long} -\begin{alltt} -unsigned long long mp_get_long_long (mp_int * a); -\end{alltt} - -This will return the 64 least significant bits of the mp\_int $a$. - -\subsection{Initialize and Setting Constants} -To both initialize and set small constants the following two functions are available. -\index{mp\_init\_set} \index{mp\_init\_set\_int} -\begin{alltt} -int mp_init_set (mp_int * a, mp_digit b); -int mp_init_set_int (mp_int * a, unsigned long b); -\end{alltt} - -Both functions work like the previous counterparts except they first mp\_init $a$ before setting the values. - -\begin{alltt} -int main(void) -\{ - mp_int number1, number2; - int result; - - /* initialize and set a single digit */ - if ((result = mp_init_set(&number1, 100)) != MP_OKAY) \{ - printf("Error setting number1: \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* initialize and set a long */ - if ((result = mp_init_set_int(&number2, 1023)) != MP_OKAY) \{ - printf("Error setting number2: \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* display */ - printf("Number1, Number2 == \%lu, \%lu", - mp_get_int(&number1), mp_get_int(&number2)); - - /* clear */ - mp_clear_multi(&number1, &number2, NULL); - - return EXIT_SUCCESS; -\} -\end{alltt} - -If this program succeeds it shall output. -\begin{alltt} -Number1, Number2 == 100, 1023 -\end{alltt} - -\section{Comparisons} - -Comparisons in LibTomMath are always performed in a ``left to right'' fashion. There are three possible return codes -for any comparison. - -\index{MP\_GT} \index{MP\_EQ} \index{MP\_LT} -\begin{figure}[here] -\begin{center} -\begin{tabular}{|c|c|} -\hline \textbf{Result Code} & \textbf{Meaning} \\ -\hline MP\_GT & $a > b$ \\ -\hline MP\_EQ & $a = b$ \\ -\hline MP\_LT & $a < b$ \\ -\hline -\end{tabular} -\end{center} -\caption{Comparison Codes for $a, b$} -\label{fig:CMP} -\end{figure} - -In figure \ref{fig:CMP} two integers $a$ and $b$ are being compared. In this case $a$ is said to be ``to the left'' of -$b$. - -\subsection{Unsigned comparison} - -An unsigned comparison considers only the digits themselves and not the associated \textit{sign} flag of the -mp\_int structures. This is analogous to an absolute comparison. The function mp\_cmp\_mag() will compare two -mp\_int variables based on their digits only. - -\index{mp\_cmp\_mag} -\begin{alltt} -int mp_cmp_mag(mp_int * a, mp_int * b); -\end{alltt} -This will compare $a$ to $b$ placing $a$ to the left of $b$. This function cannot fail and will return one of the -three compare codes listed in figure \ref{fig:CMP}. - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int number1, number2; - int result; - - if ((result = mp_init_multi(&number1, &number2, NULL)) != MP_OKAY) \{ - printf("Error initializing the numbers. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* set the number1 to 5 */ - mp_set(&number1, 5); - - /* set the number2 to -6 */ - mp_set(&number2, 6); - if ((result = mp_neg(&number2, &number2)) != MP_OKAY) \{ - printf("Error negating number2. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - switch(mp_cmp_mag(&number1, &number2)) \{ - case MP_GT: printf("|number1| > |number2|"); break; - case MP_EQ: printf("|number1| = |number2|"); break; - case MP_LT: printf("|number1| < |number2|"); break; - \} - - /* we're done with it. */ - mp_clear_multi(&number1, &number2, NULL); - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -If this program\footnote{This function uses the mp\_neg() function which is discussed in section \ref{sec:NEG}.} completes -successfully it should print the following. - -\begin{alltt} -|number1| < |number2| -\end{alltt} - -This is because $\vert -6 \vert = 6$ and obviously $5 < 6$. - -\subsection{Signed comparison} - -To compare two mp\_int variables based on their signed value the mp\_cmp() function is provided. - -\index{mp\_cmp} -\begin{alltt} -int mp_cmp(mp_int * a, mp_int * b); -\end{alltt} - -This will compare $a$ to the left of $b$. It will first compare the signs of the two mp\_int variables. If they -differ it will return immediately based on their signs. If the signs are equal then it will compare the digits -individually. This function will return one of the compare conditions codes listed in figure \ref{fig:CMP}. - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int number1, number2; - int result; - - if ((result = mp_init_multi(&number1, &number2, NULL)) != MP_OKAY) \{ - printf("Error initializing the numbers. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* set the number1 to 5 */ - mp_set(&number1, 5); - - /* set the number2 to -6 */ - mp_set(&number2, 6); - if ((result = mp_neg(&number2, &number2)) != MP_OKAY) \{ - printf("Error negating number2. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - switch(mp_cmp(&number1, &number2)) \{ - case MP_GT: printf("number1 > number2"); break; - case MP_EQ: printf("number1 = number2"); break; - case MP_LT: printf("number1 < number2"); break; - \} - - /* we're done with it. */ - mp_clear_multi(&number1, &number2, NULL); - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -If this program\footnote{This function uses the mp\_neg() function which is discussed in section \ref{sec:NEG}.} completes -successfully it should print the following. - -\begin{alltt} -number1 > number2 -\end{alltt} - -\subsection{Single Digit} - -To compare a single digit against an mp\_int the following function has been provided. - -\index{mp\_cmp\_d} -\begin{alltt} -int mp_cmp_d(mp_int * a, mp_digit b); -\end{alltt} - -This will compare $a$ to the left of $b$ using a signed comparison. Note that it will always treat $b$ as -positive. This function is rather handy when you have to compare against small values such as $1$ (which often -comes up in cryptography). The function cannot fail and will return one of the tree compare condition codes -listed in figure \ref{fig:CMP}. - - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int number; - int result; - - if ((result = mp_init(&number)) != MP_OKAY) \{ - printf("Error initializing the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* set the number to 5 */ - mp_set(&number, 5); - - switch(mp_cmp_d(&number, 7)) \{ - case MP_GT: printf("number > 7"); break; - case MP_EQ: printf("number = 7"); break; - case MP_LT: printf("number < 7"); break; - \} - - /* we're done with it. */ - mp_clear(&number); - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -If this program functions properly it will print out the following. - -\begin{alltt} -number < 7 -\end{alltt} - -\section{Logical Operations} - -Logical operations are operations that can be performed either with simple shifts or boolean operators such as -AND, XOR and OR directly. These operations are very quick. - -\subsection{Multiplication by two} - -Multiplications and divisions by any power of two can be performed with quick logical shifts either left or -right depending on the operation. - -When multiplying or dividing by two a special case routine can be used which are as follows. -\index{mp\_mul\_2} \index{mp\_div\_2} -\begin{alltt} -int mp_mul_2(mp_int * a, mp_int * b); -int mp_div_2(mp_int * a, mp_int * b); -\end{alltt} - -The former will assign twice $a$ to $b$ while the latter will assign half $a$ to $b$. These functions are fast -since the shift counts and maskes are hardcoded into the routines. - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int number; - int result; - - if ((result = mp_init(&number)) != MP_OKAY) \{ - printf("Error initializing the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* set the number to 5 */ - mp_set(&number, 5); - - /* multiply by two */ - if ((result = mp\_mul\_2(&number, &number)) != MP_OKAY) \{ - printf("Error multiplying the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - switch(mp_cmp_d(&number, 7)) \{ - case MP_GT: printf("2*number > 7"); break; - case MP_EQ: printf("2*number = 7"); break; - case MP_LT: printf("2*number < 7"); break; - \} - - /* now divide by two */ - if ((result = mp\_div\_2(&number, &number)) != MP_OKAY) \{ - printf("Error dividing the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - switch(mp_cmp_d(&number, 7)) \{ - case MP_GT: printf("2*number/2 > 7"); break; - case MP_EQ: printf("2*number/2 = 7"); break; - case MP_LT: printf("2*number/2 < 7"); break; - \} - - /* we're done with it. */ - mp_clear(&number); - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -If this program is successful it will print out the following text. - -\begin{alltt} -2*number > 7 -2*number/2 < 7 -\end{alltt} - -Since $10 > 7$ and $5 < 7$. - -To multiply by a power of two the following function can be used. - -\index{mp\_mul\_2d} -\begin{alltt} -int mp_mul_2d(mp_int * a, int b, mp_int * c); -\end{alltt} - -This will multiply $a$ by $2^b$ and store the result in ``c''. If the value of $b$ is less than or equal to -zero the function will copy $a$ to ``c'' without performing any further actions. The multiplication itself -is implemented as a right-shift operation of $a$ by $b$ bits. - -To divide by a power of two use the following. - -\index{mp\_div\_2d} -\begin{alltt} -int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d); -\end{alltt} -Which will divide $a$ by $2^b$, store the quotient in ``c'' and the remainder in ``d'. If $b \le 0$ then the -function simply copies $a$ over to ``c'' and zeroes $d$. The variable $d$ may be passed as a \textbf{NULL} -value to signal that the remainder is not desired. The division itself is implemented as a left-shift -operation of $a$ by $b$ bits. - -\subsection{Polynomial Basis Operations} - -Strictly speaking the organization of the integers within the mp\_int structures is what is known as a -``polynomial basis''. This simply means a field element is stored by divisions of a radix. For example, if -$f(x) = \sum_{i=0}^{k} y_ix^k$ for any vector $\vec y$ then the array of digits in $\vec y$ are said to be -the polynomial basis representation of $z$ if $f(\beta) = z$ for a given radix $\beta$. - -To multiply by the polynomial $g(x) = x$ all you have todo is shift the digits of the basis left one place. The -following function provides this operation. - -\index{mp\_lshd} -\begin{alltt} -int mp_lshd (mp_int * a, int b); -\end{alltt} - -This will multiply $a$ in place by $x^b$ which is equivalent to shifting the digits left $b$ places and inserting zeroes -in the least significant digits. Similarly to divide by a power of $x$ the following function is provided. - -\index{mp\_rshd} -\begin{alltt} -void mp_rshd (mp_int * a, int b) -\end{alltt} -This will divide $a$ in place by $x^b$ and discard the remainder. This function cannot fail as it performs the operations -in place and no new digits are required to complete it. - -\subsection{AND, OR and XOR Operations} - -While AND, OR and XOR operations are not typical ``bignum functions'' they can be useful in several instances. The -three functions are prototyped as follows. - -\index{mp\_or} \index{mp\_and} \index{mp\_xor} -\begin{alltt} -int mp_or (mp_int * a, mp_int * b, mp_int * c); -int mp_and (mp_int * a, mp_int * b, mp_int * c); -int mp_xor (mp_int * a, mp_int * b, mp_int * c); -\end{alltt} - -Which compute $c = a \odot b$ where $\odot$ is one of OR, AND or XOR. - -\section{Addition and Subtraction} - -To compute an addition or subtraction the following two functions can be used. - -\index{mp\_add} \index{mp\_sub} -\begin{alltt} -int mp_add (mp_int * a, mp_int * b, mp_int * c); -int mp_sub (mp_int * a, mp_int * b, mp_int * c) -\end{alltt} - -Which perform $c = a \odot b$ where $\odot$ is one of signed addition or subtraction. The operations are fully sign -aware. - -\section{Sign Manipulation} -\subsection{Negation} -\label{sec:NEG} -Simple integer negation can be performed with the following. - -\index{mp\_neg} -\begin{alltt} -int mp_neg (mp_int * a, mp_int * b); -\end{alltt} - -Which assigns $-a$ to $b$. - -\subsection{Absolute} -Simple integer absolutes can be performed with the following. - -\index{mp\_neg} -\begin{alltt} -int mp_abs (mp_int * a, mp_int * b); -\end{alltt} - -Which assigns $\vert a \vert$ to $b$. - -\section{Integer Division and Remainder} -To perform a complete and general integer division with remainder use the following function. - -\index{mp\_div} -\begin{alltt} -int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d); -\end{alltt} - -This divides $a$ by $b$ and stores the quotient in $c$ and $d$. The signed quotient is computed such that -$bc + d = a$. Note that either of $c$ or $d$ can be set to \textbf{NULL} if their value is not required. If -$b$ is zero the function returns \textbf{MP\_VAL}. - - -\chapter{Multiplication and Squaring} -\section{Multiplication} -A full signed integer multiplication can be performed with the following. -\index{mp\_mul} -\begin{alltt} -int mp_mul (mp_int * a, mp_int * b, mp_int * c); -\end{alltt} -Which assigns the full signed product $ab$ to $c$. This function actually breaks into one of four cases which are -specific multiplication routines optimized for given parameters. First there are the Toom-Cook multiplications which -should only be used with very large inputs. This is followed by the Karatsuba multiplications which are for moderate -sized inputs. Then followed by the Comba and baseline multipliers. - -Fortunately for the developer you don't really need to know this unless you really want to fine tune the system. mp\_mul() -will determine on its own\footnote{Some tweaking may be required.} what routine to use automatically when it is called. - -\begin{alltt} -int main(void) -\{ - mp_int number1, number2; - int result; - - /* Initialize the numbers */ - if ((result = mp_init_multi(&number1, - &number2, NULL)) != MP_OKAY) \{ - printf("Error initializing the numbers. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* set the terms */ - if ((result = mp_set_int(&number, 257)) != MP_OKAY) \{ - printf("Error setting number1. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - if ((result = mp_set_int(&number2, 1023)) != MP_OKAY) \{ - printf("Error setting number2. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* multiply them */ - if ((result = mp_mul(&number1, &number2, - &number1)) != MP_OKAY) \{ - printf("Error multiplying terms. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* display */ - printf("number1 * number2 == \%lu", mp_get_int(&number1)); - - /* free terms and return */ - mp_clear_multi(&number1, &number2, NULL); - - return EXIT_SUCCESS; -\} -\end{alltt} - -If this program succeeds it shall output the following. - -\begin{alltt} -number1 * number2 == 262911 -\end{alltt} - -\section{Squaring} -Since squaring can be performed faster than multiplication it is performed it's own function instead of just using -mp\_mul(). - -\index{mp\_sqr} -\begin{alltt} -int mp_sqr (mp_int * a, mp_int * b); -\end{alltt} - -Will square $a$ and store it in $b$. Like the case of multiplication there are four different squaring -algorithms all which can be called from mp\_sqr(). It is ideal to use mp\_sqr over mp\_mul when squaring terms because -of the speed difference. - -\section{Tuning Polynomial Basis Routines} - -Both of the Toom-Cook and Karatsuba multiplication algorithms are faster than the traditional $O(n^2)$ approach that -the Comba and baseline algorithms use. At $O(n^{1.464973})$ and $O(n^{1.584962})$ running times respectively they require -considerably less work. For example, a 10000-digit multiplication would take roughly 724,000 single precision -multiplications with Toom-Cook or 100,000,000 single precision multiplications with the standard Comba (a factor -of 138). - -So why not always use Karatsuba or Toom-Cook? The simple answer is that they have so much overhead that they're not -actually faster than Comba until you hit distinct ``cutoff'' points. For Karatsuba with the default configuration, -GCC 3.3.1 and an Athlon XP processor the cutoff point is roughly 110 digits (about 70 for the Intel P4). That is, at -110 digits Karatsuba and Comba multiplications just about break even and for 110+ digits Karatsuba is faster. - -Toom-Cook has incredible overhead and is probably only useful for very large inputs. So far no known cutoff points -exist and for the most part I just set the cutoff points very high to make sure they're not called. - -A demo program in the ``etc/'' directory of the project called ``tune.c'' can be used to find the cutoff points. This -can be built with GCC as follows - -\begin{alltt} -make XXX -\end{alltt} -Where ``XXX'' is one of the following entries from the table \ref{fig:tuning}. - -\begin{figure}[here] -\begin{center} -\begin{small} -\begin{tabular}{|l|l|} -\hline \textbf{Value of XXX} & \textbf{Meaning} \\ -\hline tune & Builds portable tuning application \\ -\hline tune86 & Builds x86 (pentium and up) program for COFF \\ -\hline tune86c & Builds x86 program for Cygwin \\ -\hline tune86l & Builds x86 program for Linux (ELF format) \\ -\hline -\end{tabular} -\end{small} -\end{center} -\caption{Build Names for Tuning Programs} -\label{fig:tuning} -\end{figure} - -When the program is running it will output a series of measurements for different cutoff points. It will first find -good Karatsuba squaring and multiplication points. Then it proceeds to find Toom-Cook points. Note that the Toom-Cook -tuning takes a very long time as the cutoff points are likely to be very high. - -\chapter{Modular Reduction} - -Modular reduction is process of taking the remainder of one quantity divided by another. Expressed -as (\ref{eqn:mod}) the modular reduction is equivalent to the remainder of $b$ divided by $c$. - -\begin{equation} -a \equiv b \mbox{ (mod }c\mbox{)} -\label{eqn:mod} -\end{equation} - -Of particular interest to cryptography are reductions where $b$ is limited to the range $0 \le b < c^2$ since particularly -fast reduction algorithms can be written for the limited range. - -Note that one of the four optimized reduction algorithms are automatically chosen in the modular exponentiation -algorithm mp\_exptmod when an appropriate modulus is detected. - -\section{Straight Division} -In order to effect an arbitrary modular reduction the following algorithm is provided. - -\index{mp\_mod} -\begin{alltt} -int mp_mod(mp_int *a, mp_int *b, mp_int *c); -\end{alltt} - -This reduces $a$ modulo $b$ and stores the result in $c$. The sign of $c$ shall agree with the sign -of $b$. This algorithm accepts an input $a$ of any range and is not limited by $0 \le a < b^2$. - -\section{Barrett Reduction} - -Barrett reduction is a generic optimized reduction algorithm that requires pre--computation to achieve -a decent speedup over straight division. First a $\mu$ value must be precomputed with the following function. - -\index{mp\_reduce\_setup} -\begin{alltt} -int mp_reduce_setup(mp_int *a, mp_int *b); -\end{alltt} - -Given a modulus in $b$ this produces the required $\mu$ value in $a$. For any given modulus this only has to -be computed once. Modular reduction can now be performed with the following. - -\index{mp\_reduce} -\begin{alltt} -int mp_reduce(mp_int *a, mp_int *b, mp_int *c); -\end{alltt} - -This will reduce $a$ in place modulo $b$ with the precomputed $\mu$ value in $c$. $a$ must be in the range -$0 \le a < b^2$. - -\begin{alltt} -int main(void) -\{ - mp_int a, b, c, mu; - int result; - - /* initialize a,b to desired values, mp_init mu, - * c and set c to 1...we want to compute a^3 mod b - */ - - /* get mu value */ - if ((result = mp_reduce_setup(&mu, b)) != MP_OKAY) \{ - printf("Error getting mu. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* square a to get c = a^2 */ - if ((result = mp_sqr(&a, &c)) != MP_OKAY) \{ - printf("Error squaring. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* now reduce `c' modulo b */ - if ((result = mp_reduce(&c, &b, &mu)) != MP_OKAY) \{ - printf("Error reducing. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* multiply a to get c = a^3 */ - if ((result = mp_mul(&a, &c, &c)) != MP_OKAY) \{ - printf("Error reducing. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* now reduce `c' modulo b */ - if ((result = mp_reduce(&c, &b, &mu)) != MP_OKAY) \{ - printf("Error reducing. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* c now equals a^3 mod b */ - - return EXIT_SUCCESS; -\} -\end{alltt} - -This program will calculate $a^3 \mbox{ mod }b$ if all the functions succeed. - -\section{Montgomery Reduction} - -Montgomery is a specialized reduction algorithm for any odd moduli. Like Barrett reduction a pre--computation -step is required. This is accomplished with the following. - -\index{mp\_montgomery\_setup} -\begin{alltt} -int mp_montgomery_setup(mp_int *a, mp_digit *mp); -\end{alltt} - -For the given odd moduli $a$ the precomputation value is placed in $mp$. The reduction is computed with the -following. - -\index{mp\_montgomery\_reduce} -\begin{alltt} -int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp); -\end{alltt} -This reduces $a$ in place modulo $m$ with the pre--computed value $mp$. $a$ must be in the range -$0 \le a < b^2$. - -Montgomery reduction is faster than Barrett reduction for moduli smaller than the ``comba'' limit. With the default -setup for instance, the limit is $127$ digits ($3556$--bits). Note that this function is not limited to -$127$ digits just that it falls back to a baseline algorithm after that point. - -An important observation is that this reduction does not return $a \mbox{ mod }m$ but $aR^{-1} \mbox{ mod }m$ -where $R = \beta^n$, $n$ is the n number of digits in $m$ and $\beta$ is radix used (default is $2^{28}$). - -To quickly calculate $R$ the following function was provided. - -\index{mp\_montgomery\_calc\_normalization} -\begin{alltt} -int mp_montgomery_calc_normalization(mp_int *a, mp_int *b); -\end{alltt} -Which calculates $a = R$ for the odd moduli $b$ without using multiplication or division. - -The normal modus operandi for Montgomery reductions is to normalize the integers before entering the system. For -example, to calculate $a^3 \mbox { mod }b$ using Montgomery reduction the value of $a$ can be normalized by -multiplying it by $R$. Consider the following code snippet. - -\begin{alltt} -int main(void) -\{ - mp_int a, b, c, R; - mp_digit mp; - int result; - - /* initialize a,b to desired values, - * mp_init R, c and set c to 1.... - */ - - /* get normalization */ - if ((result = mp_montgomery_calc_normalization(&R, b)) != MP_OKAY) \{ - printf("Error getting norm. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* get mp value */ - if ((result = mp_montgomery_setup(&c, &mp)) != MP_OKAY) \{ - printf("Error setting up montgomery. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* normalize `a' so now a is equal to aR */ - if ((result = mp_mulmod(&a, &R, &b, &a)) != MP_OKAY) \{ - printf("Error computing aR. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* square a to get c = a^2R^2 */ - if ((result = mp_sqr(&a, &c)) != MP_OKAY) \{ - printf("Error squaring. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* now reduce `c' back down to c = a^2R^2 * R^-1 == a^2R */ - if ((result = mp_montgomery_reduce(&c, &b, mp)) != MP_OKAY) \{ - printf("Error reducing. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* multiply a to get c = a^3R^2 */ - if ((result = mp_mul(&a, &c, &c)) != MP_OKAY) \{ - printf("Error reducing. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* now reduce `c' back down to c = a^3R^2 * R^-1 == a^3R */ - if ((result = mp_montgomery_reduce(&c, &b, mp)) != MP_OKAY) \{ - printf("Error reducing. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* now reduce (again) `c' back down to c = a^3R * R^-1 == a^3 */ - if ((result = mp_montgomery_reduce(&c, &b, mp)) != MP_OKAY) \{ - printf("Error reducing. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* c now equals a^3 mod b */ - - return EXIT_SUCCESS; -\} -\end{alltt} - -This particular example does not look too efficient but it demonstrates the point of the algorithm. By -normalizing the inputs the reduced results are always of the form $aR$ for some variable $a$. This allows -a single final reduction to correct for the normalization and the fast reduction used within the algorithm. - -For more details consider examining the file \textit{bn\_mp\_exptmod\_fast.c}. - -\section{Restricted Dimminished Radix} - -``Dimminished Radix'' reduction refers to reduction with respect to moduli that are ameniable to simple -digit shifting and small multiplications. In this case the ``restricted'' variant refers to moduli of the -form $\beta^k - p$ for some $k \ge 0$ and $0 < p < \beta$ where $\beta$ is the radix (default to $2^{28}$). - -As in the case of Montgomery reduction there is a pre--computation phase required for a given modulus. - -\index{mp\_dr\_setup} -\begin{alltt} -void mp_dr_setup(mp_int *a, mp_digit *d); -\end{alltt} - -This computes the value required for the modulus $a$ and stores it in $d$. This function cannot fail -and does not return any error codes. After the pre--computation a reduction can be performed with the -following. - -\index{mp\_dr\_reduce} -\begin{alltt} -int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp); -\end{alltt} - -This reduces $a$ in place modulo $b$ with the pre--computed value $mp$. $b$ must be of a restricted -dimminished radix form and $a$ must be in the range $0 \le a < b^2$. Dimminished radix reductions are -much faster than both Barrett and Montgomery reductions as they have a much lower asymtotic running time. - -Since the moduli are restricted this algorithm is not particularly useful for something like Rabin, RSA or -BBS cryptographic purposes. This reduction algorithm is useful for Diffie-Hellman and ECC where fixed -primes are acceptable. - -Note that unlike Montgomery reduction there is no normalization process. The result of this function is -equal to the correct residue. - -\section{Unrestricted Dimminshed Radix} - -Unrestricted reductions work much like the restricted counterparts except in this case the moduli is of the -form $2^k - p$ for $0 < p < \beta$. In this sense the unrestricted reductions are more flexible as they -can be applied to a wider range of numbers. - -\index{mp\_reduce\_2k\_setup} -\begin{alltt} -int mp_reduce_2k_setup(mp_int *a, mp_digit *d); -\end{alltt} - -This will compute the required $d$ value for the given moduli $a$. - -\index{mp\_reduce\_2k} -\begin{alltt} -int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d); -\end{alltt} - -This will reduce $a$ in place modulo $n$ with the pre--computed value $d$. From my experience this routine is -slower than mp\_dr\_reduce but faster for most moduli sizes than the Montgomery reduction. - -\chapter{Exponentiation} -\section{Single Digit Exponentiation} -\index{mp\_expt\_d\_ex} -\begin{alltt} -int mp_expt_d_ex (mp_int * a, mp_digit b, mp_int * c, int fast) -\end{alltt} -This function computes $c = a^b$. - -With parameter \textit{fast} set to $0$ the old version of the algorithm is used, -when \textit{fast} is $1$, a faster but not statically timed version of the algorithm is used. - -The old version uses a simple binary left-to-right algorithm. -It is faster than repeated multiplications by $a$ for all values of $b$ greater than three. - -The new version uses a binary right-to-left algorithm. - -The difference between the old and the new version is that the old version always -executes $DIGIT\_BIT$ iterations. The new algorithm executes only $n$ iterations -where $n$ is equal to the position of the highest bit that is set in $b$. - -\index{mp\_expt\_d} -\begin{alltt} -int mp_expt_d (mp_int * a, mp_digit b, mp_int * c) -\end{alltt} -mp\_expt\_d(a, b, c) is a wrapper function to mp\_expt\_d\_ex(a, b, c, 0). - -\section{Modular Exponentiation} -\index{mp\_exptmod} -\begin{alltt} -int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) -\end{alltt} -This computes $Y \equiv G^X \mbox{ (mod }P\mbox{)}$ using a variable width sliding window algorithm. This function -will automatically detect the fastest modular reduction technique to use during the operation. For negative values of -$X$ the operation is performed as $Y \equiv (G^{-1} \mbox{ mod }P)^{\vert X \vert} \mbox{ (mod }P\mbox{)}$ provided that -$gcd(G, P) = 1$. - -This function is actually a shell around the two internal exponentiation functions. This routine will automatically -detect when Barrett, Montgomery, Restricted and Unrestricted Dimminished Radix based exponentiation can be used. Generally -moduli of the a ``restricted dimminished radix'' form lead to the fastest modular exponentiations. Followed by Montgomery -and the other two algorithms. - -\section{Root Finding} -\index{mp\_n\_root} -\begin{alltt} -int mp_n_root (mp_int * a, mp_digit b, mp_int * c) -\end{alltt} -This computes $c = a^{1/b}$ such that $c^b \le a$ and $(c+1)^b > a$. The implementation of this function is not -ideal for values of $b$ greater than three. It will work but become very slow. So unless you are working with very small -numbers (less than 1000 bits) I'd avoid $b > 3$ situations. Will return a positive root only for even roots and return -a root with the sign of the input for odd roots. For example, performing $4^{1/2}$ will return $2$ whereas $(-8)^{1/3}$ -will return $-2$. - -This algorithm uses the ``Newton Approximation'' method and will converge on the correct root fairly quickly. Since -the algorithm requires raising $a$ to the power of $b$ it is not ideal to attempt to find roots for large -values of $b$. If particularly large roots are required then a factor method could be used instead. For example, -$a^{1/16}$ is equivalent to $\left (a^{1/4} \right)^{1/4}$ or simply -$\left ( \left ( \left ( a^{1/2} \right )^{1/2} \right )^{1/2} \right )^{1/2}$ - -\chapter{Prime Numbers} -\section{Trial Division} -\index{mp\_prime\_is\_divisible} -\begin{alltt} -int mp_prime_is_divisible (mp_int * a, int *result) -\end{alltt} -This will attempt to evenly divide $a$ by a list of primes\footnote{Default is the first 256 primes.} and store the -outcome in ``result''. That is if $result = 0$ then $a$ is not divisible by the primes, otherwise it is. Note that -if the function does not return \textbf{MP\_OKAY} the value in ``result'' should be considered undefined\footnote{Currently -the default is to set it to zero first.}. - -\section{Fermat Test} -\index{mp\_prime\_fermat} -\begin{alltt} -int mp_prime_fermat (mp_int * a, mp_int * b, int *result) -\end{alltt} -Performs a Fermat primality test to the base $b$. That is it computes $b^a \mbox{ mod }a$ and tests whether the value is -equal to $b$ or not. If the values are equal then $a$ is probably prime and $result$ is set to one. Otherwise $result$ -is set to zero. - -\section{Miller-Rabin Test} -\index{mp\_prime\_miller\_rabin} -\begin{alltt} -int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result) -\end{alltt} -Performs a Miller-Rabin test to the base $b$ of $a$. This test is much stronger than the Fermat test and is very hard to -fool (besides with Carmichael numbers). If $a$ passes the test (therefore is probably prime) $result$ is set to one. -Otherwise $result$ is set to zero. - -Note that is suggested that you use the Miller-Rabin test instead of the Fermat test since all of the failures of -Miller-Rabin are a subset of the failures of the Fermat test. - -\subsection{Required Number of Tests} -Generally to ensure a number is very likely to be prime you have to perform the Miller-Rabin with at least a half-dozen -or so unique bases. However, it has been proven that the probability of failure goes down as the size of the input goes up. -This is why a simple function has been provided to help out. - -\index{mp\_prime\_rabin\_miller\_trials} -\begin{alltt} -int mp_prime_rabin_miller_trials(int size) -\end{alltt} -This returns the number of trials required for a $2^{-96}$ (or lower) probability of failure for a given ``size'' expressed -in bits. This comes in handy specially since larger numbers are slower to test. For example, a 512-bit number would -require ten tests whereas a 1024-bit number would only require four tests. - -You should always still perform a trial division before a Miller-Rabin test though. - -\section{Primality Testing} -\index{mp\_prime\_is\_prime} -\begin{alltt} -int mp_prime_is_prime (mp_int * a, int t, int *result) -\end{alltt} -This will perform a trial division followed by $t$ rounds of Miller-Rabin tests on $a$ and store the result in $result$. -If $a$ passes all of the tests $result$ is set to one, otherwise it is set to zero. Note that $t$ is bounded by -$1 \le t < PRIME\_SIZE$ where $PRIME\_SIZE$ is the number of primes in the prime number table (by default this is $256$). - -\section{Next Prime} -\index{mp\_prime\_next\_prime} -\begin{alltt} -int mp_prime_next_prime(mp_int *a, int t, int bbs_style) -\end{alltt} -This finds the next prime after $a$ that passes mp\_prime\_is\_prime() with $t$ tests. Set $bbs\_style$ to one if you -want only the next prime congruent to $3 \mbox{ mod } 4$, otherwise set it to zero to find any next prime. - -\section{Random Primes} -\index{mp\_prime\_random} -\begin{alltt} -int mp_prime_random(mp_int *a, int t, int size, int bbs, - ltm_prime_callback cb, void *dat) -\end{alltt} -This will find a prime greater than $256^{size}$ which can be ``bbs\_style'' or not depending on $bbs$ and must pass -$t$ rounds of tests. The ``ltm\_prime\_callback'' is a typedef for - -\begin{alltt} -typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat); -\end{alltt} - -Which is a function that must read $len$ bytes (and return the amount stored) into $dst$. The $dat$ variable is simply -copied from the original input. It can be used to pass RNG context data to the callback. The function -mp\_prime\_random() is more suitable for generating primes which must be secret (as in the case of RSA) since there -is no skew on the least significant bits. - -\textit{Note:} As of v0.30 of the LibTomMath library this function has been deprecated. It is still available -but users are encouraged to use the new mp\_prime\_random\_ex() function instead. - -\subsection{Extended Generation} -\index{mp\_prime\_random\_ex} -\begin{alltt} -int mp_prime_random_ex(mp_int *a, int t, - int size, int flags, - ltm_prime_callback cb, void *dat); -\end{alltt} -This will generate a prime in $a$ using $t$ tests of the primality testing algorithms. The variable $size$ -specifies the bit length of the prime desired. The variable $flags$ specifies one of several options available -(see fig. \ref{fig:primeopts}) which can be OR'ed together. The callback parameters are used as in -mp\_prime\_random(). - -\begin{figure}[here] -\begin{center} -\begin{small} -\begin{tabular}{|r|l|} -\hline \textbf{Flag} & \textbf{Meaning} \\ -\hline LTM\_PRIME\_BBS & Make the prime congruent to $3$ modulo $4$ \\ -\hline LTM\_PRIME\_SAFE & Make a prime $p$ such that $(p - 1)/2$ is also prime. \\ - & This option implies LTM\_PRIME\_BBS as well. \\ -\hline LTM\_PRIME\_2MSB\_OFF & Makes sure that the bit adjacent to the most significant bit \\ - & Is forced to zero. \\ -\hline LTM\_PRIME\_2MSB\_ON & Makes sure that the bit adjacent to the most significant bit \\ - & Is forced to one. \\ -\hline -\end{tabular} -\end{small} -\end{center} -\caption{Primality Generation Options} -\label{fig:primeopts} -\end{figure} - -\chapter{Input and Output} -\section{ASCII Conversions} -\subsection{To ASCII} -\index{mp\_toradix} -\begin{alltt} -int mp_toradix (mp_int * a, char *str, int radix); -\end{alltt} -This still store $a$ in ``str'' as a base-``radix'' string of ASCII chars. This function appends a NUL character -to terminate the string. Valid values of ``radix'' line in the range $[2, 64]$. To determine the size (exact) required -by the conversion before storing any data use the following function. - -\index{mp\_radix\_size} -\begin{alltt} -int mp_radix_size (mp_int * a, int radix, int *size) -\end{alltt} -This stores in ``size'' the number of characters (including space for the NUL terminator) required. Upon error this -function returns an error code and ``size'' will be zero. - -\subsection{From ASCII} -\index{mp\_read\_radix} -\begin{alltt} -int mp_read_radix (mp_int * a, char *str, int radix); -\end{alltt} -This will read the base-``radix'' NUL terminated string from ``str'' into $a$. It will stop reading when it reads a -character it does not recognize (which happens to include th NUL char... imagine that...). A single leading $-$ sign -can be used to denote a negative number. - -\section{Binary Conversions} - -Converting an mp\_int to and from binary is another keen idea. - -\index{mp\_unsigned\_bin\_size} -\begin{alltt} -int mp_unsigned_bin_size(mp_int *a); -\end{alltt} - -This will return the number of bytes (octets) required to store the unsigned copy of the integer $a$. - -\index{mp\_to\_unsigned\_bin} -\begin{alltt} -int mp_to_unsigned_bin(mp_int *a, unsigned char *b); -\end{alltt} -This will store $a$ into the buffer $b$ in big--endian format. Fortunately this is exactly what DER (or is it ASN?) -requires. It does not store the sign of the integer. - -\index{mp\_read\_unsigned\_bin} -\begin{alltt} -int mp_read_unsigned_bin(mp_int *a, unsigned char *b, int c); -\end{alltt} -This will read in an unsigned big--endian array of bytes (octets) from $b$ of length $c$ into $a$. The resulting -integer $a$ will always be positive. - -For those who acknowledge the existence of negative numbers (heretic!) there are ``signed'' versions of the -previous functions. - -\begin{alltt} -int mp_signed_bin_size(mp_int *a); -int mp_read_signed_bin(mp_int *a, unsigned char *b, int c); -int mp_to_signed_bin(mp_int *a, unsigned char *b); -\end{alltt} -They operate essentially the same as the unsigned copies except they prefix the data with zero or non--zero -byte depending on the sign. If the sign is zpos (e.g. not negative) the prefix is zero, otherwise the prefix -is non--zero. - -\chapter{Algebraic Functions} -\section{Extended Euclidean Algorithm} -\index{mp\_exteuclid} -\begin{alltt} -int mp_exteuclid(mp_int *a, mp_int *b, - mp_int *U1, mp_int *U2, mp_int *U3); -\end{alltt} - -This finds the triple U1/U2/U3 using the Extended Euclidean algorithm such that the following equation holds. - -\begin{equation} -a \cdot U1 + b \cdot U2 = U3 -\end{equation} - -Any of the U1/U2/U3 paramters can be set to \textbf{NULL} if they are not desired. - -\section{Greatest Common Divisor} -\index{mp\_gcd} -\begin{alltt} -int mp_gcd (mp_int * a, mp_int * b, mp_int * c) -\end{alltt} -This will compute the greatest common divisor of $a$ and $b$ and store it in $c$. - -\section{Least Common Multiple} -\index{mp\_lcm} -\begin{alltt} -int mp_lcm (mp_int * a, mp_int * b, mp_int * c) -\end{alltt} -This will compute the least common multiple of $a$ and $b$ and store it in $c$. - -\section{Jacobi Symbol} -\index{mp\_jacobi} -\begin{alltt} -int mp_jacobi (mp_int * a, mp_int * p, int *c) -\end{alltt} -This will compute the Jacobi symbol for $a$ with respect to $p$. If $p$ is prime this essentially computes the Legendre -symbol. The result is stored in $c$ and can take on one of three values $\lbrace -1, 0, 1 \rbrace$. If $p$ is prime -then the result will be $-1$ when $a$ is not a quadratic residue modulo $p$. The result will be $0$ if $a$ divides $p$ -and the result will be $1$ if $a$ is a quadratic residue modulo $p$. - -\section{Modular square root} -\index{mp\_sqrtmod\_prime} -\begin{alltt} -int mp_sqrtmod_prime(mp_int *n, mp_int *p, mp_int *r) -\end{alltt} - -This will solve the modular equatioon $r^2 = n \mod p$ where $p$ is a prime number greater than 2 (odd prime). -The result is returned in the third argument $r$, the function returns \textbf{MP\_OKAY} on success, -other return values indicate failure. - -The implementation is split for two different cases: - -1. if $p \mod 4 == 3$ we apply \href{http://cacr.uwaterloo.ca/hac/}{Handbook of Applied Cryptography algorithm 3.36} and compute $r$ directly as -$r = n^{(p+1)/4} \mod p$ - -2. otherwise we use \href{https://en.wikipedia.org/wiki/Tonelli-Shanks_algorithm}{Tonelli-Shanks algorithm} - -The function does not check the primality of parameter $p$ thus it is up to the caller to assure that this parameter -is a prime number. When $p$ is a composite the function behaviour is undefined, it may even return a false-positive -\textbf{MP\_OKAY}. - -\section{Modular Inverse} -\index{mp\_invmod} -\begin{alltt} -int mp_invmod (mp_int * a, mp_int * b, mp_int * c) -\end{alltt} -Computes the multiplicative inverse of $a$ modulo $b$ and stores the result in $c$ such that $ac \equiv 1 \mbox{ (mod }b\mbox{)}$. - -\section{Single Digit Functions} - -For those using small numbers (\textit{snicker snicker}) there are several ``helper'' functions - -\index{mp\_add\_d} \index{mp\_sub\_d} \index{mp\_mul\_d} \index{mp\_div\_d} \index{mp\_mod\_d} -\begin{alltt} -int mp_add_d(mp_int *a, mp_digit b, mp_int *c); -int mp_sub_d(mp_int *a, mp_digit b, mp_int *c); -int mp_mul_d(mp_int *a, mp_digit b, mp_int *c); -int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d); -int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c); -\end{alltt} - -These work like the full mp\_int capable variants except the second parameter $b$ is a mp\_digit. These -functions fairly handy if you have to work with relatively small numbers since you will not have to allocate -an entire mp\_int to store a number like $1$ or $2$. - -\input{bn.ind} - -\end{document} diff --git a/libtommath/bn_cutoffs.c b/libtommath/bn_cutoffs.c new file mode 100644 index 0000000..b02ab71 --- /dev/null +++ b/libtommath/bn_cutoffs.c @@ -0,0 +1,14 @@ +#include "tommath_private.h" +#ifdef BN_CUTOFFS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +#ifndef MP_FIXED_CUTOFFS +#include "tommath_cutoffs.h" +int KARATSUBA_MUL_CUTOFF = MP_DEFAULT_KARATSUBA_MUL_CUTOFF, + KARATSUBA_SQR_CUTOFF = MP_DEFAULT_KARATSUBA_SQR_CUTOFF, + TOOM_MUL_CUTOFF = MP_DEFAULT_TOOM_MUL_CUTOFF, + TOOM_SQR_CUTOFF = MP_DEFAULT_TOOM_SQR_CUTOFF; +#endif + +#endif diff --git a/libtommath/bn_deprecated.c b/libtommath/bn_deprecated.c new file mode 100644 index 0000000..2056b20 --- /dev/null +++ b/libtommath/bn_deprecated.c @@ -0,0 +1,321 @@ +#include "tommath_private.h" +#ifdef BN_DEPRECATED_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +#ifdef BN_MP_GET_BIT_C +int mp_get_bit(const mp_int *a, int b) +{ + if (b < 0) { + return MP_VAL; + } + return (s_mp_get_bit(a, (unsigned int)b) == MP_YES) ? MP_YES : MP_NO; +} +#endif +#ifdef BN_MP_JACOBI_C +mp_err mp_jacobi(const mp_int *a, const mp_int *n, int *c) +{ + if (a->sign == MP_NEG) { + return MP_VAL; + } + if (mp_cmp_d(n, 0uL) != MP_GT) { + return MP_VAL; + } + return mp_kronecker(a, n, c); +} +#endif +#ifdef BN_MP_PRIME_RANDOM_EX_C +mp_err mp_prime_random_ex(mp_int *a, int t, int size, int flags, private_mp_prime_callback cb, void *dat) +{ + return s_mp_prime_random_ex(a, t, size, flags, cb, dat); +} +#endif +#ifdef BN_MP_RAND_DIGIT_C +mp_err mp_rand_digit(mp_digit *r) +{ + mp_err err = s_mp_rand_source(r, sizeof(mp_digit)); + *r &= MP_MASK; + return err; +} +#endif +#ifdef BN_FAST_MP_INVMOD_C +mp_err fast_mp_invmod(const mp_int *a, const mp_int *b, mp_int *c) +{ + return s_mp_invmod_fast(a, b, c); +} +#endif +#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C +mp_err fast_mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho) +{ + return s_mp_montgomery_reduce_fast(x, n, rho); +} +#endif +#ifdef BN_FAST_S_MP_MUL_DIGS_C +mp_err fast_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) +{ + return s_mp_mul_digs_fast(a, b, c, digs); +} +#endif +#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C +mp_err fast_s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) +{ + return s_mp_mul_high_digs_fast(a, b, c, digs); +} +#endif +#ifdef BN_FAST_S_MP_SQR_C +mp_err fast_s_mp_sqr(const mp_int *a, mp_int *b) +{ + return s_mp_sqr_fast(a, b); +} +#endif +#ifdef BN_MP_BALANCE_MUL_C +mp_err mp_balance_mul(const mp_int *a, const mp_int *b, mp_int *c) +{ + return s_mp_balance_mul(a, b, c); +} +#endif +#ifdef BN_MP_EXPTMOD_FAST_C +mp_err mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode) +{ + return s_mp_exptmod_fast(G, X, P, Y, redmode); +} +#endif +#ifdef BN_MP_INVMOD_SLOW_C +mp_err mp_invmod_slow(const mp_int *a, const mp_int *b, mp_int *c) +{ + return s_mp_invmod_slow(a, b, c); +} +#endif +#ifdef BN_MP_KARATSUBA_MUL_C +mp_err mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c) +{ + return s_mp_karatsuba_mul(a, b, c); +} +#endif +#ifdef BN_MP_KARATSUBA_SQR_C +mp_err mp_karatsuba_sqr(const mp_int *a, mp_int *b) +{ + return s_mp_karatsuba_sqr(a, b); +} +#endif +#ifdef BN_MP_TOOM_MUL_C +mp_err mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c) +{ + return s_mp_toom_mul(a, b, c); +} +#endif +#ifdef BN_MP_TOOM_SQR_C +mp_err mp_toom_sqr(const mp_int *a, mp_int *b) +{ + return s_mp_toom_sqr(a, b); +} +#endif +#ifdef S_MP_REVERSE_C +void bn_reverse(unsigned char *s, int len) +{ + if (len > 0) { + s_mp_reverse(s, (size_t)len); + } +} +#endif +#ifdef BN_MP_TC_AND_C +mp_err mp_tc_and(const mp_int *a, const mp_int *b, mp_int *c) +{ + return mp_and(a, b, c); +} +#endif +#ifdef BN_MP_TC_OR_C +mp_err mp_tc_or(const mp_int *a, const mp_int *b, mp_int *c) +{ + return mp_or(a, b, c); +} +#endif +#ifdef BN_MP_TC_XOR_C +mp_err mp_tc_xor(const mp_int *a, const mp_int *b, mp_int *c) +{ + return mp_xor(a, b, c); +} +#endif +#ifdef BN_MP_TC_DIV_2D_C +mp_err mp_tc_div_2d(const mp_int *a, int b, mp_int *c) +{ + return mp_signed_rsh(a, b, c); +} +#endif +#ifdef BN_MP_INIT_SET_INT_C +mp_err mp_init_set_int(mp_int *a, unsigned long b) +{ + return mp_init_u32(a, (uint32_t)b); +} +#endif +#ifdef BN_MP_SET_INT_C +mp_err mp_set_int(mp_int *a, unsigned long b) +{ + mp_set_u32(a, (uint32_t)b); + return MP_OKAY; +} +#endif +#ifdef BN_MP_SET_LONG_C +mp_err mp_set_long(mp_int *a, unsigned long b) +{ + mp_set_u64(a, b); + return MP_OKAY; +} +#endif +#ifdef BN_MP_SET_LONG_LONG_C +mp_err mp_set_long_long(mp_int *a, unsigned long long b) +{ + mp_set_u64(a, b); + return MP_OKAY; +} +#endif +#ifdef BN_MP_GET_INT_C +unsigned long mp_get_int(const mp_int *a) +{ + return (unsigned long)mp_get_mag_u32(a); +} +#endif +#ifdef BN_MP_GET_LONG_C +unsigned long mp_get_long(const mp_int *a) +{ + return (unsigned long)mp_get_mag_ul(a); +} +#endif +#ifdef BN_MP_GET_LONG_LONG_C +unsigned long long mp_get_long_long(const mp_int *a) +{ + return mp_get_mag_ull(a); +} +#endif +#ifdef BN_MP_PRIME_IS_DIVISIBLE_C +mp_err mp_prime_is_divisible(const mp_int *a, mp_bool *result) +{ + return s_mp_prime_is_divisible(a, result); +} +#endif +#ifdef BN_MP_EXPT_D_EX_C +mp_err mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast) +{ + (void)fast; + if (b > MP_MIN(MP_DIGIT_MAX, UINT32_MAX)) { + return MP_VAL; + } + return mp_expt_u32(a, (uint32_t)b, c); +} +#endif +#ifdef BN_MP_EXPT_D_C +mp_err mp_expt_d(const mp_int *a, mp_digit b, mp_int *c) +{ + if (b > MP_MIN(MP_DIGIT_MAX, UINT32_MAX)) { + return MP_VAL; + } + return mp_expt_u32(a, (uint32_t)b, c); +} +#endif +#ifdef BN_MP_N_ROOT_EX_C +mp_err mp_n_root_ex(const mp_int *a, mp_digit b, mp_int *c, int fast) +{ + (void)fast; + if (b > MP_MIN(MP_DIGIT_MAX, UINT32_MAX)) { + return MP_VAL; + } + return mp_root_u32(a, (uint32_t)b, c); +} +#endif +#ifdef BN_MP_N_ROOT_C +mp_err mp_n_root(const mp_int *a, mp_digit b, mp_int *c) +{ + if (b > MP_MIN(MP_DIGIT_MAX, UINT32_MAX)) { + return MP_VAL; + } + return mp_root_u32(a, (uint32_t)b, c); +} +#endif +#ifdef BN_MP_UNSIGNED_BIN_SIZE_C +int mp_unsigned_bin_size(const mp_int *a) +{ + return (int)mp_ubin_size(a); +} +#endif +#ifdef BN_MP_READ_UNSIGNED_BIN_C +mp_err mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c) +{ + return mp_from_ubin(a, b, (size_t) c); +} +#endif +#ifdef BN_MP_TO_UNSIGNED_BIN_C +mp_err mp_to_unsigned_bin(const mp_int *a, unsigned char *b) +{ + return mp_to_ubin(a, b, SIZE_MAX, NULL); +} +#endif +#ifdef BN_MP_TO_UNSIGNED_BIN_N_C +mp_err mp_to_unsigned_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen) +{ + size_t n = mp_ubin_size(a); + if (*outlen < (unsigned long)n) { + return MP_VAL; + } + *outlen = (unsigned long)n; + return mp_to_ubin(a, b, n, NULL); +} +#endif +#ifdef BN_MP_SIGNED_BIN_SIZE_C +int mp_signed_bin_size(const mp_int *a) +{ + return (int)mp_sbin_size(a); +} +#endif +#ifdef BN_MP_READ_SIGNED_BIN_C +mp_err mp_read_signed_bin(mp_int *a, const unsigned char *b, int c) +{ + return mp_from_sbin(a, b, (size_t) c); +} +#endif +#ifdef BN_MP_TO_SIGNED_BIN_C +mp_err mp_to_signed_bin(const mp_int *a, unsigned char *b) +{ + return mp_to_sbin(a, b, SIZE_MAX, NULL); +} +#endif +#ifdef BN_MP_TO_SIGNED_BIN_N_C +mp_err mp_to_signed_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen) +{ + size_t n = mp_sbin_size(a); + if (*outlen < (unsigned long)n) { + return MP_VAL; + } + *outlen = (unsigned long)n; + return mp_to_sbin(a, b, n, NULL); +} +#endif +#ifdef BN_MP_TORADIX_N_C +mp_err mp_toradix_n(const mp_int *a, char *str, int radix, int maxlen) +{ + if (maxlen < 0) { + return MP_VAL; + } + return mp_to_radix(a, str, (size_t)maxlen, NULL, radix); +} +#endif +#ifdef BN_MP_TORADIX_C +mp_err mp_toradix(const mp_int *a, char *str, int radix) +{ + return mp_to_radix(a, str, SIZE_MAX, NULL, radix); +} +#endif +#ifdef BN_MP_IMPORT_C +mp_err mp_import(mp_int *rop, size_t count, int order, size_t size, int endian, size_t nails, + const void *op) +{ + return mp_unpack(rop, count, order, size, endian, nails, op); +} +#endif +#ifdef BN_MP_EXPORT_C +mp_err mp_export(void *rop, size_t *countp, int order, size_t size, + int endian, size_t nails, const mp_int *op) +{ + return mp_pack(rop, SIZE_MAX, countp, order, size, endian, nails, op); +} +#endif +#endif diff --git a/libtommath/bn_error.c b/libtommath/bn_error.c deleted file mode 100644 index 0d77411..0000000 --- a/libtommath/bn_error.c +++ /dev/null @@ -1,47 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_ERROR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -static const struct { - int code; - const char *msg; -} msgs[] = { - { MP_OKAY, "Successful" }, - { MP_MEM, "Out of heap" }, - { MP_VAL, "Value out of range" } -}; - -/* return a char * string for a given code */ -const char *mp_error_to_string(int code) -{ - int x; - - /* scan the lookup table for the given message */ - for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) { - if (msgs[x].code == code) { - return msgs[x].msg; - } - } - - /* generic reply for invalid code */ - return "Invalid error code"; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_fast_mp_invmod.c b/libtommath/bn_fast_mp_invmod.c deleted file mode 100644 index 12f42de..0000000 --- a/libtommath/bn_fast_mp_invmod.c +++ /dev/null @@ -1,148 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_FAST_MP_INVMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* computes the modular inverse via binary extended euclidean algorithm, - * that is c = 1/a mod b - * - * Based on slow invmod except this is optimized for the case where b is - * odd as per HAC Note 14.64 on pp. 610 - */ -int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int x, y, u, v, B, D; - int res, neg; - - /* 2. [modified] b must be odd */ - if (mp_iseven (b) == MP_YES) { - return MP_VAL; - } - - /* init all our temps */ - if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) { - return res; - } - - /* x == modulus, y == value to invert */ - if ((res = mp_copy (b, &x)) != MP_OKAY) { - goto LBL_ERR; - } - - /* we need y = |a| */ - if ((res = mp_mod (a, b, &y)) != MP_OKAY) { - goto LBL_ERR; - } - - /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ - if ((res = mp_copy (&x, &u)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_copy (&y, &v)) != MP_OKAY) { - goto LBL_ERR; - } - mp_set (&D, 1); - -top: - /* 4. while u is even do */ - while (mp_iseven (&u) == MP_YES) { - /* 4.1 u = u/2 */ - if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { - goto LBL_ERR; - } - /* 4.2 if B is odd then */ - if (mp_isodd (&B) == MP_YES) { - if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* B = B/2 */ - if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 5. while v is even do */ - while (mp_iseven (&v) == MP_YES) { - /* 5.1 v = v/2 */ - if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { - goto LBL_ERR; - } - /* 5.2 if D is odd then */ - if (mp_isodd (&D) == MP_YES) { - /* D = (D-x)/2 */ - if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* D = D/2 */ - if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 6. if u >= v then */ - if (mp_cmp (&u, &v) != MP_LT) { - /* u = u - v, B = B - D */ - if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } else { - /* v - v - u, D = D - B */ - if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* if not zero goto step 4 */ - if (mp_iszero (&u) == MP_NO) { - goto top; - } - - /* now a = C, b = D, gcd == g*v */ - - /* if v != 1 then there is no inverse */ - if (mp_cmp_d (&v, 1) != MP_EQ) { - res = MP_VAL; - goto LBL_ERR; - } - - /* b is now the inverse */ - neg = a->sign; - while (D.sign == MP_NEG) { - if ((res = mp_add (&D, b, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - mp_exch (&D, c); - c->sign = neg; - res = MP_OKAY; - -LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL); - return res; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_fast_mp_montgomery_reduce.c b/libtommath/bn_fast_mp_montgomery_reduce.c deleted file mode 100644 index 16d5ff7..0000000 --- a/libtommath/bn_fast_mp_montgomery_reduce.c +++ /dev/null @@ -1,172 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* computes xR**-1 == x (mod N) via Montgomery Reduction - * - * This is an optimized implementation of montgomery_reduce - * which uses the comba method to quickly calculate the columns of the - * reduction. - * - * Based on Algorithm 14.32 on pp.601 of HAC. -*/ -int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) -{ - int ix, res, olduse; - mp_word W[MP_WARRAY]; - - /* get old used count */ - olduse = x->used; - - /* grow a as required */ - if (x->alloc < (n->used + 1)) { - if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) { - return res; - } - } - - /* first we have to get the digits of the input into - * an array of double precision words W[...] - */ - { - mp_word *_W; - mp_digit *tmpx; - - /* alias for the W[] array */ - _W = W; - - /* alias for the digits of x*/ - tmpx = x->dp; - - /* copy the digits of a into W[0..a->used-1] */ - for (ix = 0; ix < x->used; ix++) { - *_W++ = *tmpx++; - } - - /* zero the high words of W[a->used..m->used*2] */ - for (; ix < ((n->used * 2) + 1); ix++) { - *_W++ = 0; - } - } - - /* now we proceed to zero successive digits - * from the least significant upwards - */ - for (ix = 0; ix < n->used; ix++) { - /* mu = ai * m' mod b - * - * We avoid a double precision multiplication (which isn't required) - * by casting the value down to a mp_digit. Note this requires - * that W[ix-1] have the carry cleared (see after the inner loop) - */ - mp_digit mu; - mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK); - - /* a = a + mu * m * b**i - * - * This is computed in place and on the fly. The multiplication - * by b**i is handled by offseting which columns the results - * are added to. - * - * Note the comba method normally doesn't handle carries in the - * inner loop In this case we fix the carry from the previous - * column since the Montgomery reduction requires digits of the - * result (so far) [see above] to work. This is - * handled by fixing up one carry after the inner loop. The - * carry fixups are done in order so after these loops the - * first m->used words of W[] have the carries fixed - */ - { - int iy; - mp_digit *tmpn; - mp_word *_W; - - /* alias for the digits of the modulus */ - tmpn = n->dp; - - /* Alias for the columns set by an offset of ix */ - _W = W + ix; - - /* inner loop */ - for (iy = 0; iy < n->used; iy++) { - *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++); - } - } - - /* now fix carry for next digit, W[ix+1] */ - W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT); - } - - /* now we have to propagate the carries and - * shift the words downward [all those least - * significant digits we zeroed]. - */ - { - mp_digit *tmpx; - mp_word *_W, *_W1; - - /* nox fix rest of carries */ - - /* alias for current word */ - _W1 = W + ix; - - /* alias for next word, where the carry goes */ - _W = W + ++ix; - - for (; ix <= ((n->used * 2) + 1); ix++) { - *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT); - } - - /* copy out, A = A/b**n - * - * The result is A/b**n but instead of converting from an - * array of mp_word to mp_digit than calling mp_rshd - * we just copy them in the right order - */ - - /* alias for destination word */ - tmpx = x->dp; - - /* alias for shifted double precision result */ - _W = W + n->used; - - for (ix = 0; ix < (n->used + 1); ix++) { - *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK)); - } - - /* zero oldused digits, if the input a was larger than - * m->used+1 we'll have to clear the digits - */ - for (; ix < olduse; ix++) { - *tmpx++ = 0; - } - } - - /* set the max used and clamp */ - x->used = n->used + 1; - mp_clamp (x); - - /* if A >= m then A = A - m */ - if (mp_cmp_mag (x, n) != MP_LT) { - return s_mp_sub (x, n, x); - } - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_fast_s_mp_mul_digs.c b/libtommath/bn_fast_s_mp_mul_digs.c deleted file mode 100644 index a1015af..0000000 --- a/libtommath/bn_fast_s_mp_mul_digs.c +++ /dev/null @@ -1,107 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_FAST_S_MP_MUL_DIGS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* Fast (comba) multiplier - * - * This is the fast column-array [comba] multiplier. It is - * designed to compute the columns of the product first - * then handle the carries afterwards. This has the effect - * of making the nested loops that compute the columns very - * simple and schedulable on super-scalar processors. - * - * This has been modified to produce a variable number of - * digits of output so if say only a half-product is required - * you don't have to compute the upper half (a feature - * required for fast Barrett reduction). - * - * Based on Algorithm 14.12 on pp.595 of HAC. - * - */ -int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - int olduse, res, pa, ix, iz; - mp_digit W[MP_WARRAY]; - mp_word _W; - - /* grow the destination as required */ - if (c->alloc < digs) { - if ((res = mp_grow (c, digs)) != MP_OKAY) { - return res; - } - } - - /* number of output digits to produce */ - pa = MIN(digs, a->used + b->used); - - /* clear the carry */ - _W = 0; - for (ix = 0; ix < pa; ix++) { - int tx, ty; - int iy; - mp_digit *tmpx, *tmpy; - - /* get offsets into the two bignums */ - ty = MIN(b->used-1, ix); - tx = ix - ty; - - /* setup temp aliases */ - tmpx = a->dp + tx; - tmpy = b->dp + ty; - - /* this is the number of times the loop will iterrate, essentially - while (tx++ < a->used && ty-- >= 0) { ... } - */ - iy = MIN(a->used-tx, ty+1); - - /* execute loop */ - for (iz = 0; iz < iy; ++iz) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); - - } - - /* store term */ - W[ix] = ((mp_digit)_W) & MP_MASK; - - /* make next carry */ - _W = _W >> ((mp_word)DIGIT_BIT); - } - - /* setup dest */ - olduse = c->used; - c->used = pa; - - { - mp_digit *tmpc; - tmpc = c->dp; - for (ix = 0; ix < (pa + 1); ix++) { - /* now extract the previous digit [below the carry] */ - *tmpc++ = W[ix]; - } - - /* clear unused digits [that existed in the old copy of c] */ - for (; ix < olduse; ix++) { - *tmpc++ = 0; - } - } - mp_clamp (c); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_fast_s_mp_mul_high_digs.c b/libtommath/bn_fast_s_mp_mul_high_digs.c deleted file mode 100644 index 08f0355..0000000 --- a/libtommath/bn_fast_s_mp_mul_high_digs.c +++ /dev/null @@ -1,98 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* this is a modified version of fast_s_mul_digs that only produces - * output digits *above* digs. See the comments for fast_s_mul_digs - * to see how it works. - * - * This is used in the Barrett reduction since for one of the multiplications - * only the higher digits were needed. This essentially halves the work. - * - * Based on Algorithm 14.12 on pp.595 of HAC. - */ -int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - int olduse, res, pa, ix, iz; - mp_digit W[MP_WARRAY]; - mp_word _W; - - /* grow the destination as required */ - pa = a->used + b->used; - if (c->alloc < pa) { - if ((res = mp_grow (c, pa)) != MP_OKAY) { - return res; - } - } - - /* number of output digits to produce */ - pa = a->used + b->used; - _W = 0; - for (ix = digs; ix < pa; ix++) { - int tx, ty, iy; - mp_digit *tmpx, *tmpy; - - /* get offsets into the two bignums */ - ty = MIN(b->used-1, ix); - tx = ix - ty; - - /* setup temp aliases */ - tmpx = a->dp + tx; - tmpy = b->dp + ty; - - /* this is the number of times the loop will iterrate, essentially its - while (tx++ < a->used && ty-- >= 0) { ... } - */ - iy = MIN(a->used-tx, ty+1); - - /* execute loop */ - for (iz = 0; iz < iy; iz++) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); - } - - /* store term */ - W[ix] = ((mp_digit)_W) & MP_MASK; - - /* make next carry */ - _W = _W >> ((mp_word)DIGIT_BIT); - } - - /* setup dest */ - olduse = c->used; - c->used = pa; - - { - mp_digit *tmpc; - - tmpc = c->dp + digs; - for (ix = digs; ix < pa; ix++) { - /* now extract the previous digit [below the carry] */ - *tmpc++ = W[ix]; - } - - /* clear unused digits [that existed in the old copy of c] */ - for (; ix < olduse; ix++) { - *tmpc++ = 0; - } - } - mp_clamp (c); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_fast_s_mp_sqr.c b/libtommath/bn_fast_s_mp_sqr.c deleted file mode 100644 index f435af9..0000000 --- a/libtommath/bn_fast_s_mp_sqr.c +++ /dev/null @@ -1,114 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_FAST_S_MP_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* the jist of squaring... - * you do like mult except the offset of the tmpx [one that - * starts closer to zero] can't equal the offset of tmpy. - * So basically you set up iy like before then you min it with - * (ty-tx) so that it never happens. You double all those - * you add in the inner loop - -After that loop you do the squares and add them in. -*/ - -int fast_s_mp_sqr (mp_int * a, mp_int * b) -{ - int olduse, res, pa, ix, iz; - mp_digit W[MP_WARRAY], *tmpx; - mp_word W1; - - /* grow the destination as required */ - pa = a->used + a->used; - if (b->alloc < pa) { - if ((res = mp_grow (b, pa)) != MP_OKAY) { - return res; - } - } - - /* number of output digits to produce */ - W1 = 0; - for (ix = 0; ix < pa; ix++) { - int tx, ty, iy; - mp_word _W; - mp_digit *tmpy; - - /* clear counter */ - _W = 0; - - /* get offsets into the two bignums */ - ty = MIN(a->used-1, ix); - tx = ix - ty; - - /* setup temp aliases */ - tmpx = a->dp + tx; - tmpy = a->dp + ty; - - /* this is the number of times the loop will iterrate, essentially - while (tx++ < a->used && ty-- >= 0) { ... } - */ - iy = MIN(a->used-tx, ty+1); - - /* now for squaring tx can never equal ty - * we halve the distance since they approach at a rate of 2x - * and we have to round because odd cases need to be executed - */ - iy = MIN(iy, ((ty-tx)+1)>>1); - - /* execute loop */ - for (iz = 0; iz < iy; iz++) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); - } - - /* double the inner product and add carry */ - _W = _W + _W + W1; - - /* even columns have the square term in them */ - if ((ix&1) == 0) { - _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]); - } - - /* store it */ - W[ix] = (mp_digit)(_W & MP_MASK); - - /* make next carry */ - W1 = _W >> ((mp_word)DIGIT_BIT); - } - - /* setup dest */ - olduse = b->used; - b->used = a->used+a->used; - - { - mp_digit *tmpb; - tmpb = b->dp; - for (ix = 0; ix < pa; ix++) { - *tmpb++ = W[ix] & MP_MASK; - } - - /* clear unused digits [that existed in the old copy of c] */ - for (; ix < olduse; ix++) { - *tmpb++ = 0; - } - } - mp_clamp (b); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_2expt.c b/libtommath/bn_mp_2expt.c index 989bb9f..0ae3df1 100644 --- a/libtommath/bn_mp_2expt.c +++ b/libtommath/bn_mp_2expt.c @@ -1,48 +1,31 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_2EXPT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ -/* computes a = 2**b +/* computes a = 2**b * * Simple algorithm which zeroes the int, grows it then just sets one bit * as required. */ -int -mp_2expt (mp_int * a, int b) +mp_err mp_2expt(mp_int *a, int b) { - int res; + mp_err err; - /* zero a as per default */ - mp_zero (a); + /* zero a as per default */ + mp_zero(a); - /* grow a to accomodate the single bit */ - if ((res = mp_grow (a, (b / DIGIT_BIT) + 1)) != MP_OKAY) { - return res; - } + /* grow a to accomodate the single bit */ + if ((err = mp_grow(a, (b / MP_DIGIT_BIT) + 1)) != MP_OKAY) { + return err; + } - /* set the used count of where the bit will go */ - a->used = (b / DIGIT_BIT) + 1; + /* set the used count of where the bit will go */ + a->used = (b / MP_DIGIT_BIT) + 1; - /* put the single bit in its place */ - a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT); + /* put the single bit in its place */ + a->dp[b / MP_DIGIT_BIT] = (mp_digit)1 << (mp_digit)(b % MP_DIGIT_BIT); - return MP_OKAY; + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_abs.c b/libtommath/bn_mp_abs.c index e7c5e25..00900bb 100644 --- a/libtommath/bn_mp_abs.c +++ b/libtommath/bn_mp_abs.c @@ -1,43 +1,26 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_ABS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ -/* b = |a| +/* b = |a| * * Simple function copies the input and fixes the sign to positive */ -int -mp_abs (mp_int * a, mp_int * b) +mp_err mp_abs(const mp_int *a, mp_int *b) { - int res; + mp_err err; - /* copy a to b */ - if (a != b) { - if ((res = mp_copy (a, b)) != MP_OKAY) { - return res; - } - } + /* copy a to b */ + if (a != b) { + if ((err = mp_copy(a, b)) != MP_OKAY) { + return err; + } + } - /* force the sign of b to positive */ - b->sign = MP_ZPOS; + /* force the sign of b to positive */ + b->sign = MP_ZPOS; - return MP_OKAY; + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_add.c b/libtommath/bn_mp_add.c index bdb166f..dfa78de 100644 --- a/libtommath/bn_mp_add.c +++ b/libtommath/bn_mp_add.c @@ -1,53 +1,38 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_ADD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* high level addition (handles signs) */ -int mp_add (mp_int * a, mp_int * b, mp_int * c) +mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c) { - int sa, sb, res; + mp_sign sa, sb; + mp_err err; - /* get sign of both inputs */ - sa = a->sign; - sb = b->sign; + /* get sign of both inputs */ + sa = a->sign; + sb = b->sign; - /* handle two cases, not four */ - if (sa == sb) { - /* both positive or both negative */ - /* add their magnitudes, copy the sign */ - c->sign = sa; - res = s_mp_add (a, b, c); - } else { - /* one positive, the other negative */ - /* subtract the one with the greater magnitude from */ - /* the one of the lesser magnitude. The result gets */ - /* the sign of the one with the greater magnitude. */ - if (mp_cmp_mag (a, b) == MP_LT) { - c->sign = sb; - res = s_mp_sub (b, a, c); - } else { + /* handle two cases, not four */ + if (sa == sb) { + /* both positive or both negative */ + /* add their magnitudes, copy the sign */ c->sign = sa; - res = s_mp_sub (a, b, c); - } - } - return res; + err = s_mp_add(a, b, c); + } else { + /* one positive, the other negative */ + /* subtract the one with the greater magnitude from */ + /* the one of the lesser magnitude. The result gets */ + /* the sign of the one with the greater magnitude. */ + if (mp_cmp_mag(a, b) == MP_LT) { + c->sign = sb; + err = s_mp_sub(b, a, c); + } else { + c->sign = sa; + err = s_mp_sub(a, b, c); + } + } + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_add_d.c b/libtommath/bn_mp_add_d.c index fd1a186..f301575 100644 --- a/libtommath/bn_mp_add_d.c +++ b/libtommath/bn_mp_add_d.c @@ -1,112 +1,89 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_ADD_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* single digit addition */ -int -mp_add_d (mp_int * a, mp_digit b, mp_int * c) +mp_err mp_add_d(const mp_int *a, mp_digit b, mp_int *c) { - int res, ix, oldused; - mp_digit *tmpa, *tmpc, mu; - - /* grow c as required */ - if (c->alloc < (a->used + 1)) { - if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { - return res; - } - } - - /* if a is negative and |a| >= b, call c = |a| - b */ - if ((a->sign == MP_NEG) && ((a->used > 1) || (a->dp[0] >= b))) { - /* temporarily fix sign of a */ - a->sign = MP_ZPOS; - - /* c = |a| - b */ - res = mp_sub_d(a, b, c); - - /* fix sign */ - a->sign = c->sign = MP_NEG; - - /* clamp */ - mp_clamp(c); - - return res; - } - - /* old number of used digits in c */ - oldused = c->used; - - /* source alias */ - tmpa = a->dp; - - /* destination alias */ - tmpc = c->dp; - - /* if a is positive */ - if (a->sign == MP_ZPOS) { - /* add digit, after this we're propagating - * the carry. - */ - *tmpc = *tmpa++ + b; - mu = *tmpc >> DIGIT_BIT; - *tmpc++ &= MP_MASK; - - /* now handle rest of the digits */ - for (ix = 1; ix < a->used; ix++) { - *tmpc = *tmpa++ + mu; - mu = *tmpc >> DIGIT_BIT; - *tmpc++ &= MP_MASK; - } - /* set final carry */ - ix++; - *tmpc++ = mu; - - /* setup size */ - c->used = a->used + 1; - } else { - /* a was negative and |a| < b */ - c->used = 1; - - /* the result is a single digit */ - if (a->used == 1) { - *tmpc++ = b - a->dp[0]; - } else { - *tmpc++ = b; - } - - /* setup count so the clearing of oldused - * can fall through correctly - */ - ix = 1; - } - - /* sign always positive */ - c->sign = MP_ZPOS; - - /* now zero to oldused */ - while (ix++ < oldused) { - *tmpc++ = 0; - } - mp_clamp(c); - - return MP_OKAY; + mp_err err; + int ix, oldused; + mp_digit *tmpa, *tmpc; + + /* grow c as required */ + if (c->alloc < (a->used + 1)) { + if ((err = mp_grow(c, a->used + 1)) != MP_OKAY) { + return err; + } + } + + /* if a is negative and |a| >= b, call c = |a| - b */ + if ((a->sign == MP_NEG) && ((a->used > 1) || (a->dp[0] >= b))) { + mp_int a_ = *a; + /* temporarily fix sign of a */ + a_.sign = MP_ZPOS; + + /* c = |a| - b */ + err = mp_sub_d(&a_, b, c); + + /* fix sign */ + c->sign = MP_NEG; + + /* clamp */ + mp_clamp(c); + + return err; + } + + /* old number of used digits in c */ + oldused = c->used; + + /* source alias */ + tmpa = a->dp; + + /* destination alias */ + tmpc = c->dp; + + /* if a is positive */ + if (a->sign == MP_ZPOS) { + /* add digits, mu is carry */ + mp_digit mu = b; + for (ix = 0; ix < a->used; ix++) { + *tmpc = *tmpa++ + mu; + mu = *tmpc >> MP_DIGIT_BIT; + *tmpc++ &= MP_MASK; + } + /* set final carry */ + ix++; + *tmpc++ = mu; + + /* setup size */ + c->used = a->used + 1; + } else { + /* a was negative and |a| < b */ + c->used = 1; + + /* the result is a single digit */ + if (a->used == 1) { + *tmpc++ = b - a->dp[0]; + } else { + *tmpc++ = b; + } + + /* setup count so the clearing of oldused + * can fall through correctly + */ + ix = 1; + } + + /* sign always positive */ + c->sign = MP_ZPOS; + + /* now zero to oldused */ + MP_ZERO_DIGITS(tmpc, oldused - ix); + mp_clamp(c); + + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_addmod.c b/libtommath/bn_mp_addmod.c index dc06788..1dcfb67 100644 --- a/libtommath/bn_mp_addmod.c +++ b/libtommath/bn_mp_addmod.c @@ -1,41 +1,25 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_ADDMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* d = a + b (mod c) */ -int -mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d) { - int res; - mp_int t; + mp_err err; + mp_int t; - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } + if ((err = mp_init(&t)) != MP_OKAY) { + return err; + } - if ((res = mp_add (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, c, d); - mp_clear (&t); - return res; + if ((err = mp_add(a, b, &t)) != MP_OKAY) { + goto LBL_ERR; + } + err = mp_mod(&t, c, d); + +LBL_ERR: + mp_clear(&t); + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_and.c b/libtommath/bn_mp_and.c index 53008a5..c259f8d 100644 --- a/libtommath/bn_mp_and.c +++ b/libtommath/bn_mp_and.c @@ -1,57 +1,56 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_AND_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* AND two ints together */ -int -mp_and (mp_int * a, mp_int * b, mp_int * c) +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* two complement and */ +mp_err mp_and(const mp_int *a, const mp_int *b, mp_int *c) { - int res, ix, px; - mp_int t, *x; - - if (a->used > b->used) { - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - px = b->used; - x = b; - } else { - if ((res = mp_init_copy (&t, b)) != MP_OKAY) { - return res; - } - px = a->used; - x = a; - } - - for (ix = 0; ix < px; ix++) { - t.dp[ix] &= x->dp[ix]; - } - - /* zero digits above the last from the smallest mp_int */ - for (; ix < t.used; ix++) { - t.dp[ix] = 0; - } - - mp_clamp (&t); - mp_exch (c, &t); - mp_clear (&t); - return MP_OKAY; + int used = MP_MAX(a->used, b->used) + 1, i; + mp_err err; + mp_digit ac = 1, bc = 1, cc = 1; + mp_sign csign = ((a->sign == MP_NEG) && (b->sign == MP_NEG)) ? MP_NEG : MP_ZPOS; + + if (c->alloc < used) { + if ((err = mp_grow(c, used)) != MP_OKAY) { + return err; + } + } + + for (i = 0; i < used; i++) { + mp_digit x, y; + + /* convert to two complement if negative */ + if (a->sign == MP_NEG) { + ac += (i >= a->used) ? MP_MASK : (~a->dp[i] & MP_MASK); + x = ac & MP_MASK; + ac >>= MP_DIGIT_BIT; + } else { + x = (i >= a->used) ? 0uL : a->dp[i]; + } + + /* convert to two complement if negative */ + if (b->sign == MP_NEG) { + bc += (i >= b->used) ? MP_MASK : (~b->dp[i] & MP_MASK); + y = bc & MP_MASK; + bc >>= MP_DIGIT_BIT; + } else { + y = (i >= b->used) ? 0uL : b->dp[i]; + } + + c->dp[i] = x & y; + + /* convert to to sign-magnitude if negative */ + if (csign == MP_NEG) { + cc += ~c->dp[i] & MP_MASK; + c->dp[i] = cc & MP_MASK; + cc >>= MP_DIGIT_BIT; + } + } + + c->used = used; + c->sign = csign; + mp_clamp(c); + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_clamp.c b/libtommath/bn_mp_clamp.c index 2c0a1a6..ac23bfd 100644 --- a/libtommath/bn_mp_clamp.c +++ b/libtommath/bn_mp_clamp.c @@ -1,44 +1,27 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_CLAMP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ -/* trim unused digits +/* trim unused digits * * This is used to ensure that leading zero digits are * trimed and the leading "used" digit will be non-zero * Typically very fast. Also fixes the sign if there * are no more leading digits */ -void -mp_clamp (mp_int * a) +void mp_clamp(mp_int *a) { - /* decrease used while the most significant digit is - * zero. - */ - while ((a->used > 0) && (a->dp[a->used - 1] == 0)) { - --(a->used); - } + /* decrease used while the most significant digit is + * zero. + */ + while ((a->used > 0) && (a->dp[a->used - 1] == 0u)) { + --(a->used); + } - /* reset the sign flag if used == 0 */ - if (a->used == 0) { - a->sign = MP_ZPOS; - } + /* reset the sign flag if used == 0 */ + if (a->used == 0) { + a->sign = MP_ZPOS; + } } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_clear.c b/libtommath/bn_mp_clear.c index d08f456..ff78324 100644 --- a/libtommath/bn_mp_clear.c +++ b/libtommath/bn_mp_clear.c @@ -1,41 +1,20 @@ -#include <tommath_private.h> -#include "dbhelpers.h" +#include "tommath_private.h" #ifdef BN_MP_CLEAR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* clear one (frees) */ -void -mp_clear (mp_int * a) +void mp_clear(mp_int *a) { - /* only do anything if a hasn't been freed previously */ - if (a->dp != NULL) { - /* first zero the digits */ - m_burn(a->dp, a->alloc * sizeof(*a->dp)); + /* only do anything if a hasn't been freed previously */ + if (a->dp != NULL) { + /* free ram */ + MP_FREE_DIGITS(a->dp, a->alloc); - /* free ram */ - XFREE(a->dp); - - /* reset members to make debugging easier */ - a->dp = NULL; - a->alloc = a->used = 0; - a->sign = MP_ZPOS; - } + /* reset members to make debugging easier */ + a->dp = NULL; + a->alloc = a->used = 0; + a->sign = MP_ZPOS; + } } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_clear_multi.c b/libtommath/bn_mp_clear_multi.c index bd4b232..794e45f 100644 --- a/libtommath/bn_mp_clear_multi.c +++ b/libtommath/bn_mp_clear_multi.c @@ -1,34 +1,19 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_CLEAR_MULTI_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + #include <stdarg.h> -void mp_clear_multi(mp_int *mp, ...) +void mp_clear_multi(mp_int *mp, ...) { - mp_int* next_mp = mp; - va_list args; - va_start(args, mp); - while (next_mp != NULL) { - mp_clear(next_mp); - next_mp = va_arg(args, mp_int*); - } - va_end(args); + mp_int *next_mp = mp; + va_list args; + va_start(args, mp); + while (next_mp != NULL) { + mp_clear(next_mp); + next_mp = va_arg(args, mp_int *); + } + va_end(args); } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_cmp.c b/libtommath/bn_mp_cmp.c index e757ddf..ced4840 100644 --- a/libtommath/bn_mp_cmp.c +++ b/libtommath/bn_mp_cmp.c @@ -1,43 +1,26 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_CMP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* compare two ints (signed)*/ -int -mp_cmp (mp_int * a, mp_int * b) +mp_ord mp_cmp(const mp_int *a, const mp_int *b) { - /* compare based on sign */ - if (a->sign != b->sign) { - if (a->sign == MP_NEG) { - return MP_LT; - } else { - return MP_GT; - } - } - - /* compare digits */ - if (a->sign == MP_NEG) { - /* if negative compare opposite direction */ - return mp_cmp_mag(b, a); - } else { - return mp_cmp_mag(a, b); - } + /* compare based on sign */ + if (a->sign != b->sign) { + if (a->sign == MP_NEG) { + return MP_LT; + } else { + return MP_GT; + } + } + + /* compare digits */ + if (a->sign == MP_NEG) { + /* if negative compare opposite direction */ + return mp_cmp_mag(b, a); + } else { + return mp_cmp_mag(a, b); + } } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_cmp_d.c b/libtommath/bn_mp_cmp_d.c index 3f5ebae..5a8337b 100644 --- a/libtommath/bn_mp_cmp_d.c +++ b/libtommath/bn_mp_cmp_d.c @@ -1,44 +1,28 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_CMP_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* compare a digit */ -int mp_cmp_d(mp_int * a, mp_digit b) +mp_ord mp_cmp_d(const mp_int *a, mp_digit b) { - /* compare based on sign */ - if (a->sign == MP_NEG) { - return MP_LT; - } + /* compare based on sign */ + if (a->sign == MP_NEG) { + return MP_LT; + } - /* compare based on magnitude */ - if (a->used > 1) { - return MP_GT; - } + /* compare based on magnitude */ + if (a->used > 1) { + return MP_GT; + } - /* compare the only digit of a to b */ - if (a->dp[0] > b) { - return MP_GT; - } else if (a->dp[0] < b) { - return MP_LT; - } else { - return MP_EQ; - } + /* compare the only digit of a to b */ + if (a->dp[0] > b) { + return MP_GT; + } else if (a->dp[0] < b) { + return MP_LT; + } else { + return MP_EQ; + } } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_cmp_mag.c b/libtommath/bn_mp_cmp_mag.c index 7ceda97..f144ea9 100644 --- a/libtommath/bn_mp_cmp_mag.c +++ b/libtommath/bn_mp_cmp_mag.c @@ -1,55 +1,39 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_CMP_MAG_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* compare maginitude of two ints (unsigned) */ -int mp_cmp_mag (mp_int * a, mp_int * b) +mp_ord mp_cmp_mag(const mp_int *a, const mp_int *b) { - int n; - mp_digit *tmpa, *tmpb; + int n; + const mp_digit *tmpa, *tmpb; - /* compare based on # of non-zero digits */ - if (a->used > b->used) { - return MP_GT; - } - - if (a->used < b->used) { - return MP_LT; - } + /* compare based on # of non-zero digits */ + if (a->used > b->used) { + return MP_GT; + } - /* alias for a */ - tmpa = a->dp + (a->used - 1); + if (a->used < b->used) { + return MP_LT; + } - /* alias for b */ - tmpb = b->dp + (a->used - 1); + /* alias for a */ + tmpa = a->dp + (a->used - 1); - /* compare based on digits */ - for (n = 0; n < a->used; ++n, --tmpa, --tmpb) { - if (*tmpa > *tmpb) { - return MP_GT; - } + /* alias for b */ + tmpb = b->dp + (a->used - 1); - if (*tmpa < *tmpb) { - return MP_LT; - } - } - return MP_EQ; + /* compare based on digits */ + for (n = 0; n < a->used; ++n, --tmpa, --tmpb) { + if (*tmpa > *tmpb) { + return MP_GT; + } + + if (*tmpa < *tmpb) { + return MP_LT; + } + } + return MP_EQ; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_cnt_lsb.c b/libtommath/bn_mp_cnt_lsb.c index bf201b5..4b2d206 100644 --- a/libtommath/bn_mp_cnt_lsb.c +++ b/libtommath/bn_mp_cnt_lsb.c @@ -1,53 +1,37 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_CNT_LSB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ -static const int lnz[16] = { +static const int lnz[16] = { 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 }; /* Counts the number of lsbs which are zero before the first zero bit */ -int mp_cnt_lsb(mp_int *a) +int mp_cnt_lsb(const mp_int *a) { int x; mp_digit q, qq; /* easy out */ - if (mp_iszero(a) == MP_YES) { + if (MP_IS_ZERO(a)) { return 0; } /* scan lower digits until non-zero */ - for (x = 0; (x < a->used) && (a->dp[x] == 0); x++) {} + for (x = 0; (x < a->used) && (a->dp[x] == 0u); x++) {} q = a->dp[x]; - x *= DIGIT_BIT; + x *= MP_DIGIT_BIT; /* now scan this digit until a 1 is found */ - if ((q & 1) == 0) { + if ((q & 1u) == 0u) { do { - qq = q & 15; + qq = q & 15u; x += lnz[qq]; q >>= 4; - } while (qq == 0); + } while (qq == 0u); } return x; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_complement.c b/libtommath/bn_mp_complement.c new file mode 100644 index 0000000..fef1423 --- /dev/null +++ b/libtommath/bn_mp_complement.c @@ -0,0 +1,12 @@ +#include "tommath_private.h" +#ifdef BN_MP_COMPLEMENT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* b = ~a */ +mp_err mp_complement(const mp_int *a, mp_int *b) +{ + mp_err err = mp_neg(a, b); + return (err == MP_OKAY) ? mp_sub_d(b, 1uL, b) : err; +} +#endif diff --git a/libtommath/bn_mp_copy.c b/libtommath/bn_mp_copy.c index 84e839e..e72fcf6 100644 --- a/libtommath/bn_mp_copy.c +++ b/libtommath/bn_mp_copy.c @@ -1,68 +1,47 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_COPY_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* copy, b = a */ -int -mp_copy (mp_int * a, mp_int * b) +mp_err mp_copy(const mp_int *a, mp_int *b) { - int res, n; + int n; + mp_digit *tmpa, *tmpb; + mp_err err; - /* if dst == src do nothing */ - if (a == b) { - return MP_OKAY; - } + /* if dst == src do nothing */ + if (a == b) { + return MP_OKAY; + } - /* grow dest */ - if (b->alloc < a->used) { - if ((res = mp_grow (b, a->used)) != MP_OKAY) { - return res; - } - } + /* grow dest */ + if (b->alloc < a->used) { + if ((err = mp_grow(b, a->used)) != MP_OKAY) { + return err; + } + } - /* zero b and copy the parameters over */ - { - mp_digit *tmpa, *tmpb; + /* zero b and copy the parameters over */ + /* pointer aliases */ - /* pointer aliases */ + /* source */ + tmpa = a->dp; - /* source */ - tmpa = a->dp; + /* destination */ + tmpb = b->dp; - /* destination */ - tmpb = b->dp; - - /* copy all the digits */ - for (n = 0; n < a->used; n++) { + /* copy all the digits */ + for (n = 0; n < a->used; n++) { *tmpb++ = *tmpa++; - } + } - /* clear high digits */ - for (; n < b->used; n++) { - *tmpb++ = 0; - } - } + /* clear high digits */ + MP_ZERO_DIGITS(tmpb, b->used - n); - /* copy used count and sign */ - b->used = a->used; - b->sign = a->sign; - return MP_OKAY; + /* copy used count and sign */ + b->used = a->used; + b->sign = a->sign; + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_count_bits.c b/libtommath/bn_mp_count_bits.c index ff558eb..b7c2cad 100644 --- a/libtommath/bn_mp_count_bits.c +++ b/libtommath/bn_mp_count_bits.c @@ -1,45 +1,28 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_COUNT_BITS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* returns the number of bits in an int */ -int -mp_count_bits (mp_int * a) +int mp_count_bits(const mp_int *a) { - int r; - mp_digit q; + int r; + mp_digit q; - /* shortcut */ - if (a->used == 0) { - return 0; - } + /* shortcut */ + if (MP_IS_ZERO(a)) { + return 0; + } - /* get number of digits and add that */ - r = (a->used - 1) * DIGIT_BIT; - - /* take the last digit and count the bits in it */ - q = a->dp[a->used - 1]; - while (q > ((mp_digit) 0)) { - ++r; - q >>= ((mp_digit) 1); - } - return r; + /* get number of digits and add that */ + r = (a->used - 1) * MP_DIGIT_BIT; + + /* take the last digit and count the bits in it */ + q = a->dp[a->used - 1]; + while (q > 0u) { + ++r; + q >>= 1u; + } + return r; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_decr.c b/libtommath/bn_mp_decr.c new file mode 100644 index 0000000..c6a1572 --- /dev/null +++ b/libtommath/bn_mp_decr.c @@ -0,0 +1,34 @@ +#include "tommath_private.h" +#ifdef BN_MP_DECR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* Decrement "a" by one like "a--". Changes input! */ +mp_err mp_decr(mp_int *a) +{ + if (MP_IS_ZERO(a)) { + mp_set(a,1uL); + a->sign = MP_NEG; + return MP_OKAY; + } else if (a->sign == MP_NEG) { + mp_err err; + a->sign = MP_ZPOS; + if ((err = mp_incr(a)) != MP_OKAY) { + return err; + } + /* There is no -0 in LTM */ + if (!MP_IS_ZERO(a)) { + a->sign = MP_NEG; + } + return MP_OKAY; + } else if (a->dp[0] > 1uL) { + a->dp[0]--; + if (a->dp[0] == 0u) { + mp_zero(a); + } + return MP_OKAY; + } else { + return mp_sub_d(a, 1uL,a); + } +} +#endif diff --git a/libtommath/bn_mp_div.c b/libtommath/bn_mp_div.c index 0890e65..71de55b 100644 --- a/libtommath/bn_mp_div.c +++ b/libtommath/bn_mp_div.c @@ -1,88 +1,71 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_DIV_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ #ifdef BN_MP_DIV_SMALL /* slower bit-bang division... also smaller */ -int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d) +mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) { mp_int ta, tb, tq, q; - int res, n, n2; - - /* is divisor zero ? */ - if (mp_iszero (b) == MP_YES) { - return MP_VAL; - } - - /* if a < b then q=0, r = a */ - if (mp_cmp_mag (a, b) == MP_LT) { - if (d != NULL) { - res = mp_copy (a, d); - } else { - res = MP_OKAY; - } - if (c != NULL) { - mp_zero (c); - } - return res; - } - - /* init our temps */ - if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL)) != MP_OKAY) { - return res; - } - - - mp_set(&tq, 1); - n = mp_count_bits(a) - mp_count_bits(b); - if (((res = mp_abs(a, &ta)) != MP_OKAY) || - ((res = mp_abs(b, &tb)) != MP_OKAY) || - ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) || - ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) { - goto LBL_ERR; - } - - while (n-- >= 0) { - if (mp_cmp(&tb, &ta) != MP_GT) { - if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) || - ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) { - goto LBL_ERR; - } - } - if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) || - ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) { - goto LBL_ERR; - } - } - - /* now q == quotient and ta == remainder */ - n = a->sign; - n2 = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; - if (c != NULL) { - mp_exch(c, &q); - c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2; - } - if (d != NULL) { - mp_exch(d, &ta); - d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n; - } + int n, n2; + mp_err err; + + /* is divisor zero ? */ + if (MP_IS_ZERO(b)) { + return MP_VAL; + } + + /* if a < b then q=0, r = a */ + if (mp_cmp_mag(a, b) == MP_LT) { + if (d != NULL) { + err = mp_copy(a, d); + } else { + err = MP_OKAY; + } + if (c != NULL) { + mp_zero(c); + } + return err; + } + + /* init our temps */ + if ((err = mp_init_multi(&ta, &tb, &tq, &q, NULL)) != MP_OKAY) { + return err; + } + + + mp_set(&tq, 1uL); + n = mp_count_bits(a) - mp_count_bits(b); + if ((err = mp_abs(a, &ta)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_abs(b, &tb)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_mul_2d(&tq, n, &tq)) != MP_OKAY) goto LBL_ERR; + + while (n-- >= 0) { + if (mp_cmp(&tb, &ta) != MP_GT) { + if ((err = mp_sub(&ta, &tb, &ta)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_add(&q, &tq, &q)) != MP_OKAY) goto LBL_ERR; + } + if ((err = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY) goto LBL_ERR; + } + + /* now q == quotient and ta == remainder */ + n = a->sign; + n2 = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; + if (c != NULL) { + mp_exch(c, &q); + c->sign = MP_IS_ZERO(c) ? MP_ZPOS : n2; + } + if (d != NULL) { + mp_exch(d, &ta); + d->sign = MP_IS_ZERO(d) ? MP_ZPOS : n; + } LBL_ERR: mp_clear_multi(&ta, &tb, &tq, &q, NULL); - return res; + return err; } #else @@ -100,196 +83,168 @@ LBL_ERR: * The overall algorithm is as described as * 14.20 from HAC but fixed to treat these cases. */ -int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) { - mp_int q, x, y, t1, t2; - int res, n, t, i, norm, neg; - - /* is divisor zero ? */ - if (mp_iszero (b) == MP_YES) { - return MP_VAL; - } - - /* if a < b then q=0, r = a */ - if (mp_cmp_mag (a, b) == MP_LT) { - if (d != NULL) { - res = mp_copy (a, d); - } else { - res = MP_OKAY; - } - if (c != NULL) { - mp_zero (c); - } - return res; - } - - if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) { - return res; - } - q.used = a->used + 2; - - if ((res = mp_init (&t1)) != MP_OKAY) { - goto LBL_Q; - } - - if ((res = mp_init (&t2)) != MP_OKAY) { - goto LBL_T1; - } - - if ((res = mp_init_copy (&x, a)) != MP_OKAY) { - goto LBL_T2; - } - - if ((res = mp_init_copy (&y, b)) != MP_OKAY) { - goto LBL_X; - } - - /* fix the sign */ - neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; - x.sign = y.sign = MP_ZPOS; - - /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */ - norm = mp_count_bits(&y) % DIGIT_BIT; - if (norm < (int)(DIGIT_BIT-1)) { - norm = (DIGIT_BIT-1) - norm; - if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) { - goto LBL_Y; - } - if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) { - goto LBL_Y; - } - } else { - norm = 0; - } - - /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */ - n = x.used - 1; - t = y.used - 1; - - /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */ - if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */ - goto LBL_Y; - } - - while (mp_cmp (&x, &y) != MP_LT) { - ++(q.dp[n - t]); - if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) { - goto LBL_Y; - } - } - - /* reset y by shifting it back down */ - mp_rshd (&y, n - t); - - /* step 3. for i from n down to (t + 1) */ - for (i = n; i >= (t + 1); i--) { - if (i > x.used) { - continue; - } - - /* step 3.1 if xi == yt then set q{i-t-1} to b-1, - * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ - if (x.dp[i] == y.dp[t]) { - q.dp[(i - t) - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1); - } else { - mp_word tmp; - tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT); - tmp |= ((mp_word) x.dp[i - 1]); - tmp /= ((mp_word) y.dp[t]); - if (tmp > (mp_word) MP_MASK) { - tmp = MP_MASK; + mp_int q, x, y, t1, t2; + int n, t, i, norm; + mp_sign neg; + mp_err err; + + /* is divisor zero ? */ + if (MP_IS_ZERO(b)) { + return MP_VAL; + } + + /* if a < b then q=0, r = a */ + if (mp_cmp_mag(a, b) == MP_LT) { + if (d != NULL) { + err = mp_copy(a, d); + } else { + err = MP_OKAY; + } + if (c != NULL) { + mp_zero(c); } - q.dp[(i - t) - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK)); - } + return err; + } - /* while (q{i-t-1} * (yt * b + y{t-1})) > - xi * b**2 + xi-1 * b + xi-2 + if ((err = mp_init_size(&q, a->used + 2)) != MP_OKAY) { + return err; + } + q.used = a->used + 2; - do q{i-t-1} -= 1; - */ - q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] + 1) & MP_MASK; - do { - q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1) & MP_MASK; - - /* find left hand */ - mp_zero (&t1); - t1.dp[0] = ((t - 1) < 0) ? 0 : y.dp[t - 1]; - t1.dp[1] = y.dp[t]; - t1.used = 2; - if ((res = mp_mul_d (&t1, q.dp[(i - t) - 1], &t1)) != MP_OKAY) { - goto LBL_Y; - } + if ((err = mp_init(&t1)) != MP_OKAY) goto LBL_Q; + + if ((err = mp_init(&t2)) != MP_OKAY) goto LBL_T1; + + if ((err = mp_init_copy(&x, a)) != MP_OKAY) goto LBL_T2; + + if ((err = mp_init_copy(&y, b)) != MP_OKAY) goto LBL_X; + + /* fix the sign */ + neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; + x.sign = y.sign = MP_ZPOS; + + /* normalize both x and y, ensure that y >= b/2, [b == 2**MP_DIGIT_BIT] */ + norm = mp_count_bits(&y) % MP_DIGIT_BIT; + if (norm < (MP_DIGIT_BIT - 1)) { + norm = (MP_DIGIT_BIT - 1) - norm; + if ((err = mp_mul_2d(&x, norm, &x)) != MP_OKAY) goto LBL_Y; + if ((err = mp_mul_2d(&y, norm, &y)) != MP_OKAY) goto LBL_Y; + } else { + norm = 0; + } + + /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */ + n = x.used - 1; + t = y.used - 1; - /* find right hand */ - t2.dp[0] = ((i - 2) < 0) ? 0 : x.dp[i - 2]; - t2.dp[1] = ((i - 1) < 0) ? 0 : x.dp[i - 1]; - t2.dp[2] = x.dp[i]; - t2.used = 3; - } while (mp_cmp_mag(&t1, &t2) == MP_GT); - - /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */ - if ((res = mp_mul_d (&y, q.dp[(i - t) - 1], &t1)) != MP_OKAY) { - goto LBL_Y; - } - - if ((res = mp_lshd (&t1, (i - t) - 1)) != MP_OKAY) { - goto LBL_Y; - } - - if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) { - goto LBL_Y; - } - - /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */ - if (x.sign == MP_NEG) { - if ((res = mp_copy (&y, &t1)) != MP_OKAY) { - goto LBL_Y; + /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */ + /* y = y*b**{n-t} */ + if ((err = mp_lshd(&y, n - t)) != MP_OKAY) goto LBL_Y; + + while (mp_cmp(&x, &y) != MP_LT) { + ++(q.dp[n - t]); + if ((err = mp_sub(&x, &y, &x)) != MP_OKAY) goto LBL_Y; + } + + /* reset y by shifting it back down */ + mp_rshd(&y, n - t); + + /* step 3. for i from n down to (t + 1) */ + for (i = n; i >= (t + 1); i--) { + if (i > x.used) { + continue; } - if ((res = mp_lshd (&t1, (i - t) - 1)) != MP_OKAY) { - goto LBL_Y; + + /* step 3.1 if xi == yt then set q{i-t-1} to b-1, + * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ + if (x.dp[i] == y.dp[t]) { + q.dp[(i - t) - 1] = ((mp_digit)1 << (mp_digit)MP_DIGIT_BIT) - (mp_digit)1; + } else { + mp_word tmp; + tmp = (mp_word)x.dp[i] << (mp_word)MP_DIGIT_BIT; + tmp |= (mp_word)x.dp[i - 1]; + tmp /= (mp_word)y.dp[t]; + if (tmp > (mp_word)MP_MASK) { + tmp = MP_MASK; + } + q.dp[(i - t) - 1] = (mp_digit)(tmp & (mp_word)MP_MASK); } - if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) { - goto LBL_Y; + + /* while (q{i-t-1} * (yt * b + y{t-1})) > + xi * b**2 + xi-1 * b + xi-2 + + do q{i-t-1} -= 1; + */ + q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] + 1uL) & (mp_digit)MP_MASK; + do { + q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1uL) & (mp_digit)MP_MASK; + + /* find left hand */ + mp_zero(&t1); + t1.dp[0] = ((t - 1) < 0) ? 0u : y.dp[t - 1]; + t1.dp[1] = y.dp[t]; + t1.used = 2; + if ((err = mp_mul_d(&t1, q.dp[(i - t) - 1], &t1)) != MP_OKAY) goto LBL_Y; + + /* find right hand */ + t2.dp[0] = ((i - 2) < 0) ? 0u : x.dp[i - 2]; + t2.dp[1] = x.dp[i - 1]; /* i >= 1 always holds */ + t2.dp[2] = x.dp[i]; + t2.used = 3; + } while (mp_cmp_mag(&t1, &t2) == MP_GT); + + /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */ + if ((err = mp_mul_d(&y, q.dp[(i - t) - 1], &t1)) != MP_OKAY) goto LBL_Y; + + if ((err = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY) goto LBL_Y; + + if ((err = mp_sub(&x, &t1, &x)) != MP_OKAY) goto LBL_Y; + + /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */ + if (x.sign == MP_NEG) { + if ((err = mp_copy(&y, &t1)) != MP_OKAY) goto LBL_Y; + if ((err = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY) goto LBL_Y; + if ((err = mp_add(&x, &t1, &x)) != MP_OKAY) goto LBL_Y; + + q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1uL) & MP_MASK; } + } + + /* now q is the quotient and x is the remainder + * [which we have to normalize] + */ - q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1UL) & MP_MASK; - } - } - - /* now q is the quotient and x is the remainder - * [which we have to normalize] - */ - - /* get sign before writing to c */ - x.sign = (x.used == 0) ? MP_ZPOS : a->sign; - - if (c != NULL) { - mp_clamp (&q); - mp_exch (&q, c); - c->sign = neg; - } - - if (d != NULL) { - if ((res = mp_div_2d (&x, norm, &x, NULL)) != MP_OKAY) { - goto LBL_Y; - } - mp_exch (&x, d); - } - - res = MP_OKAY; - -LBL_Y:mp_clear (&y); -LBL_X:mp_clear (&x); -LBL_T2:mp_clear (&t2); -LBL_T1:mp_clear (&t1); -LBL_Q:mp_clear (&q); - return res; + /* get sign before writing to c */ + x.sign = (x.used == 0) ? MP_ZPOS : a->sign; + + if (c != NULL) { + mp_clamp(&q); + mp_exch(&q, c); + c->sign = neg; + } + + if (d != NULL) { + if ((err = mp_div_2d(&x, norm, &x, NULL)) != MP_OKAY) goto LBL_Y; + mp_exch(&x, d); + } + + err = MP_OKAY; + +LBL_Y: + mp_clear(&y); +LBL_X: + mp_clear(&x); +LBL_T2: + mp_clear(&t2); +LBL_T1: + mp_clear(&t1); +LBL_Q: + mp_clear(&q); + return err; } #endif #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_div_2.c b/libtommath/bn_mp_div_2.c index 2b5bb49..f56ea81 100644 --- a/libtommath/bn_mp_div_2.c +++ b/libtommath/bn_mp_div_2.c @@ -1,68 +1,49 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_DIV_2_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* b = a/2 */ -int mp_div_2(mp_int * a, mp_int * b) +mp_err mp_div_2(const mp_int *a, mp_int *b) { - int x, res, oldused; + int x, oldused; + mp_digit r, rr, *tmpa, *tmpb; + mp_err err; - /* copy */ - if (b->alloc < a->used) { - if ((res = mp_grow (b, a->used)) != MP_OKAY) { - return res; - } - } + /* copy */ + if (b->alloc < a->used) { + if ((err = mp_grow(b, a->used)) != MP_OKAY) { + return err; + } + } - oldused = b->used; - b->used = a->used; - { - mp_digit r, rr, *tmpa, *tmpb; + oldused = b->used; + b->used = a->used; - /* source alias */ - tmpa = a->dp + b->used - 1; + /* source alias */ + tmpa = a->dp + b->used - 1; - /* dest alias */ - tmpb = b->dp + b->used - 1; + /* dest alias */ + tmpb = b->dp + b->used - 1; - /* carry */ - r = 0; - for (x = b->used - 1; x >= 0; x--) { + /* carry */ + r = 0; + for (x = b->used - 1; x >= 0; x--) { /* get the carry for the next iteration */ - rr = *tmpa & 1; + rr = *tmpa & 1u; /* shift the current digit, add in carry and store */ - *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); + *tmpb-- = (*tmpa-- >> 1) | (r << (MP_DIGIT_BIT - 1)); /* forward carry to next iteration */ r = rr; - } + } - /* zero excess digits */ - tmpb = b->dp + b->used; - for (x = b->used; x < oldused; x++) { - *tmpb++ = 0; - } - } - b->sign = a->sign; - mp_clamp (b); - return MP_OKAY; + /* zero excess digits */ + MP_ZERO_DIGITS(b->dp + b->used, oldused - b->used); + + b->sign = a->sign; + mp_clamp(b); + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_div_2d.c b/libtommath/bn_mp_div_2d.c index 635d374..c47d5ce 100644 --- a/libtommath/bn_mp_div_2d.c +++ b/libtommath/bn_mp_div_2d.c @@ -1,86 +1,71 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_DIV_2D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* shift right by a certain bit count (store quotient in c, optional remainder in d) */ -int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) +mp_err mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d) { - mp_digit D, r, rr; - int x, res; + mp_digit D, r, rr; + int x; + mp_err err; - /* if the shift count is <= 0 then we do no work */ - if (b <= 0) { - res = mp_copy (a, c); - if (d != NULL) { - mp_zero (d); - } - return res; - } + /* if the shift count is <= 0 then we do no work */ + if (b <= 0) { + err = mp_copy(a, c); + if (d != NULL) { + mp_zero(d); + } + return err; + } - /* copy */ - if ((res = mp_copy (a, c)) != MP_OKAY) { - return res; - } - /* 'a' should not be used after here - it might be the same as d */ + /* copy */ + if ((err = mp_copy(a, c)) != MP_OKAY) { + return err; + } + /* 'a' should not be used after here - it might be the same as d */ - /* get the remainder */ - if (d != NULL) { - if ((res = mp_mod_2d (a, b, d)) != MP_OKAY) { - return res; - } - } + /* get the remainder */ + if (d != NULL) { + if ((err = mp_mod_2d(a, b, d)) != MP_OKAY) { + return err; + } + } - /* shift by as many digits in the bit count */ - if (b >= (int)DIGIT_BIT) { - mp_rshd (c, b / DIGIT_BIT); - } + /* shift by as many digits in the bit count */ + if (b >= MP_DIGIT_BIT) { + mp_rshd(c, b / MP_DIGIT_BIT); + } - /* shift any bit count < DIGIT_BIT */ - D = (mp_digit) (b % DIGIT_BIT); - if (D != 0) { - mp_digit *tmpc, mask, shift; + /* shift any bit count < MP_DIGIT_BIT */ + D = (mp_digit)(b % MP_DIGIT_BIT); + if (D != 0u) { + mp_digit *tmpc, mask, shift; - /* mask */ - mask = (((mp_digit)1) << D) - 1; + /* mask */ + mask = ((mp_digit)1 << D) - 1uL; - /* shift for lsb */ - shift = DIGIT_BIT - D; + /* shift for lsb */ + shift = (mp_digit)MP_DIGIT_BIT - D; - /* alias */ - tmpc = c->dp + (c->used - 1); + /* alias */ + tmpc = c->dp + (c->used - 1); - /* carry */ - r = 0; - for (x = c->used - 1; x >= 0; x--) { - /* get the lower bits of this word in a temp */ - rr = *tmpc & mask; + /* carry */ + r = 0; + for (x = c->used - 1; x >= 0; x--) { + /* get the lower bits of this word in a temp */ + rr = *tmpc & mask; - /* shift the current word and mix in the carry bits from the previous word */ - *tmpc = (*tmpc >> D) | (r << shift); - --tmpc; + /* shift the current word and mix in the carry bits from the previous word */ + *tmpc = (*tmpc >> D) | (r << shift); + --tmpc; - /* set the carry to the carry bits of the current word found above */ - r = rr; - } - } - mp_clamp (c); - return MP_OKAY; + /* set the carry to the carry bits of the current word found above */ + r = rr; + } + } + mp_clamp(c); + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_div_3.c b/libtommath/bn_mp_div_3.c index e8504ea..3a23fdf 100644 --- a/libtommath/bn_mp_div_3.c +++ b/libtommath/bn_mp_div_3.c @@ -1,79 +1,63 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_DIV_3_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* divide by three (based on routine from MPI and the GMP manual) */ -int -mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) +mp_err mp_div_3(const mp_int *a, mp_int *c, mp_digit *d) { - mp_int q; - mp_word w, t; - mp_digit b; - int res, ix; - - /* b = 2**DIGIT_BIT / 3 */ - b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3); - - if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { - return res; - } - - q.used = a->used; - q.sign = a->sign; - w = 0; - for (ix = a->used - 1; ix >= 0; ix--) { - w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); - - if (w >= 3) { - /* multiply w by [1/3] */ - t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT); - - /* now subtract 3 * [w/3] from w, to get the remainder */ - w -= t+t+t; - - /* fixup the remainder as required since - * the optimization is not exact. - */ - while (w >= 3) { - t += 1; - w -= 3; - } + mp_int q; + mp_word w, t; + mp_digit b; + mp_err err; + int ix; + + /* b = 2**MP_DIGIT_BIT / 3 */ + b = ((mp_word)1 << (mp_word)MP_DIGIT_BIT) / (mp_word)3; + + if ((err = mp_init_size(&q, a->used)) != MP_OKAY) { + return err; + } + + q.used = a->used; + q.sign = a->sign; + w = 0; + for (ix = a->used - 1; ix >= 0; ix--) { + w = (w << (mp_word)MP_DIGIT_BIT) | (mp_word)a->dp[ix]; + + if (w >= 3u) { + /* multiply w by [1/3] */ + t = (w * (mp_word)b) >> (mp_word)MP_DIGIT_BIT; + + /* now subtract 3 * [w/3] from w, to get the remainder */ + w -= t+t+t; + + /* fixup the remainder as required since + * the optimization is not exact. + */ + while (w >= 3u) { + t += 1u; + w -= 3u; + } } else { - t = 0; + t = 0; } q.dp[ix] = (mp_digit)t; - } + } + + /* [optional] store the remainder */ + if (d != NULL) { + *d = (mp_digit)w; + } - /* [optional] store the remainder */ - if (d != NULL) { - *d = (mp_digit)w; - } + /* [optional] store the quotient */ + if (c != NULL) { + mp_clamp(&q); + mp_exch(&q, c); + } + mp_clear(&q); - /* [optional] store the quotient */ - if (c != NULL) { - mp_clamp(&q); - mp_exch(&q, c); - } - mp_clear(&q); - - return res; + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_div_d.c b/libtommath/bn_mp_div_d.c index a5dbc59..b9d718b 100644 --- a/libtommath/bn_mp_div_d.c +++ b/libtommath/bn_mp_div_d.c @@ -1,115 +1,84 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_DIV_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ -static int s_is_power_of_two(mp_digit b, int *p) +/* single digit division (based on routine from MPI) */ +mp_err mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d) { - int x; + mp_int q; + mp_word w; + mp_digit t; + mp_err err; + int ix; - /* fast return if no power of two */ - if ((b == 0) || ((b & (b-1)) != 0)) { - return 0; + /* cannot divide by zero */ + if (b == 0u) { + return MP_VAL; } - for (x = 0; x < DIGIT_BIT; x++) { - if (b == (((mp_digit)1)<<x)) { - *p = x; - return 1; + /* quick outs */ + if ((b == 1u) || MP_IS_ZERO(a)) { + if (d != NULL) { + *d = 0; + } + if (c != NULL) { + return mp_copy(a, c); } + return MP_OKAY; } - return 0; -} - -/* single digit division (based on routine from MPI) */ -int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d) -{ - mp_int q; - mp_word w; - mp_digit t; - int res, ix; - /* cannot divide by zero */ - if (b == 0) { - return MP_VAL; - } + /* power of two ? */ + if ((b & (b - 1u)) == 0u) { + ix = 1; + while ((ix < MP_DIGIT_BIT) && (b != (((mp_digit)1)<<ix))) { + ix++; + } + if (d != NULL) { + *d = a->dp[0] & (((mp_digit)1<<(mp_digit)ix) - 1uL); + } + if (c != NULL) { + return mp_div_2d(a, ix, c, NULL); + } + return MP_OKAY; + } - /* quick outs */ - if ((b == 1) || (mp_iszero(a) == MP_YES)) { - if (d != NULL) { - *d = 0; - } - if (c != NULL) { - return mp_copy(a, c); - } - return MP_OKAY; - } + /* three? */ + if (MP_HAS(MP_DIV_3) && (b == 3u)) { + return mp_div_3(a, c, d); + } - /* power of two ? */ - if (s_is_power_of_two(b, &ix) == 1) { - if (d != NULL) { - *d = a->dp[0] & ((((mp_digit)1)<<ix) - 1); - } - if (c != NULL) { - return mp_div_2d(a, ix, c, NULL); - } - return MP_OKAY; - } + /* no easy answer [c'est la vie]. Just division */ + if ((err = mp_init_size(&q, a->used)) != MP_OKAY) { + return err; + } -#ifdef BN_MP_DIV_3_C - /* three? */ - if (b == 3) { - return mp_div_3(a, c, d); - } -#endif + q.used = a->used; + q.sign = a->sign; + w = 0; + for (ix = a->used - 1; ix >= 0; ix--) { + w = (w << (mp_word)MP_DIGIT_BIT) | (mp_word)a->dp[ix]; - /* no easy answer [c'est la vie]. Just division */ - if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { - return res; - } - - q.used = a->used; - q.sign = a->sign; - w = 0; - for (ix = a->used - 1; ix >= 0; ix--) { - w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); - - if (w >= b) { - t = (mp_digit)(w / b); - w -= ((mp_word)t) * ((mp_word)b); + if (w >= b) { + t = (mp_digit)(w / b); + w -= (mp_word)t * (mp_word)b; } else { - t = 0; + t = 0; } - q.dp[ix] = (mp_digit)t; - } - - if (d != NULL) { - *d = (mp_digit)w; - } - - if (c != NULL) { - mp_clamp(&q); - mp_exch(&q, c); - } - mp_clear(&q); - - return res; + q.dp[ix] = t; + } + + if (d != NULL) { + *d = (mp_digit)w; + } + + if (c != NULL) { + mp_clamp(&q); + mp_exch(&q, c); + } + mp_clear(&q); + + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_dr_is_modulus.c b/libtommath/bn_mp_dr_is_modulus.c index ced330c..83760ea 100644 --- a/libtommath/bn_mp_dr_is_modulus.c +++ b/libtommath/bn_mp_dr_is_modulus.c @@ -1,43 +1,27 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_DR_IS_MODULUS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* determines if a number is a valid DR modulus */ -int mp_dr_is_modulus(mp_int *a) +mp_bool mp_dr_is_modulus(const mp_int *a) { int ix; /* must be at least two digits */ if (a->used < 2) { - return 0; + return MP_NO; } /* must be of the form b**k - a [a <= b] so all * but the first digit must be equal to -1 (mod b). */ for (ix = 1; ix < a->used; ix++) { - if (a->dp[ix] != MP_MASK) { - return 0; - } + if (a->dp[ix] != MP_MASK) { + return MP_NO; + } } - return 1; + return MP_YES; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_dr_reduce.c b/libtommath/bn_mp_dr_reduce.c index c85ee77..ffc33a6 100644 --- a/libtommath/bn_mp_dr_reduce.c +++ b/libtommath/bn_mp_dr_reduce.c @@ -1,19 +1,7 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_DR_REDUCE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* reduce "x" in place modulo "n" using the Diminished Radix algorithm. * @@ -29,68 +17,62 @@ * * Input x must be in the range 0 <= x <= (n-1)**2 */ -int -mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k) +mp_err mp_dr_reduce(mp_int *x, const mp_int *n, mp_digit k) { - int err, i, m; - mp_word r; - mp_digit mu, *tmpx1, *tmpx2; + mp_err err; + int i, m; + mp_word r; + mp_digit mu, *tmpx1, *tmpx2; - /* m = digits in modulus */ - m = n->used; + /* m = digits in modulus */ + m = n->used; - /* ensure that "x" has at least 2m digits */ - if (x->alloc < (m + m)) { - if ((err = mp_grow (x, m + m)) != MP_OKAY) { - return err; - } - } + /* ensure that "x" has at least 2m digits */ + if (x->alloc < (m + m)) { + if ((err = mp_grow(x, m + m)) != MP_OKAY) { + return err; + } + } -/* top of loop, this is where the code resumes if - * another reduction pass is required. - */ + /* top of loop, this is where the code resumes if + * another reduction pass is required. + */ top: - /* aliases for digits */ - /* alias for lower half of x */ - tmpx1 = x->dp; + /* aliases for digits */ + /* alias for lower half of x */ + tmpx1 = x->dp; - /* alias for upper half of x, or x/B**m */ - tmpx2 = x->dp + m; + /* alias for upper half of x, or x/B**m */ + tmpx2 = x->dp + m; - /* set carry to zero */ - mu = 0; + /* set carry to zero */ + mu = 0; - /* compute (x mod B**m) + k * [x/B**m] inline and inplace */ - for (i = 0; i < m; i++) { - r = (((mp_word)*tmpx2++) * (mp_word)k) + *tmpx1 + mu; + /* compute (x mod B**m) + k * [x/B**m] inline and inplace */ + for (i = 0; i < m; i++) { + r = ((mp_word)*tmpx2++ * (mp_word)k) + *tmpx1 + mu; *tmpx1++ = (mp_digit)(r & MP_MASK); - mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT)); - } + mu = (mp_digit)(r >> ((mp_word)MP_DIGIT_BIT)); + } - /* set final carry */ - *tmpx1++ = mu; + /* set final carry */ + *tmpx1++ = mu; - /* zero words above m */ - for (i = m + 1; i < x->used; i++) { - *tmpx1++ = 0; - } + /* zero words above m */ + MP_ZERO_DIGITS(tmpx1, (x->used - m) - 1); - /* clamp, sub and return */ - mp_clamp (x); + /* clamp, sub and return */ + mp_clamp(x); - /* if x >= n then subtract and reduce again - * Each successive "recursion" makes the input smaller and smaller. - */ - if (mp_cmp_mag (x, n) != MP_LT) { - if ((err = s_mp_sub(x, n, x)) != MP_OKAY) { - return err; - } - goto top; - } - return MP_OKAY; + /* if x >= n then subtract and reduce again + * Each successive "recursion" makes the input smaller and smaller. + */ + if (mp_cmp_mag(x, n) != MP_LT) { + if ((err = s_mp_sub(x, n, x)) != MP_OKAY) { + return err; + } + goto top; + } + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_dr_setup.c b/libtommath/bn_mp_dr_setup.c index b0d4a14..32d5f38 100644 --- a/libtommath/bn_mp_dr_setup.c +++ b/libtommath/bn_mp_dr_setup.c @@ -1,32 +1,15 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_DR_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* determines the setup value */ -void mp_dr_setup(mp_int *a, mp_digit *d) +void mp_dr_setup(const mp_int *a, mp_digit *d) { - /* the casts are required if DIGIT_BIT is one less than - * the number of bits in a mp_digit [e.g. DIGIT_BIT==31] + /* the casts are required if MP_DIGIT_BIT is one less than + * the number of bits in a mp_digit [e.g. MP_DIGIT_BIT==31] */ - *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - - ((mp_word)a->dp[0])); + *d = (mp_digit)(((mp_word)1 << (mp_word)MP_DIGIT_BIT) - (mp_word)a->dp[0]); } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_error_to_string.c b/libtommath/bn_mp_error_to_string.c new file mode 100644 index 0000000..2e2adb0 --- /dev/null +++ b/libtommath/bn_mp_error_to_string.c @@ -0,0 +1,27 @@ +#include "tommath_private.h" +#ifdef BN_MP_ERROR_TO_STRING_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* return a char * string for a given code */ +const char *mp_error_to_string(mp_err code) +{ + switch (code) { + case MP_OKAY: + return "Successful"; + case MP_ERR: + return "Unknown error"; + case MP_MEM: + return "Out of heap"; + case MP_VAL: + return "Value out of range"; + case MP_ITER: + return "Max. iterations reached"; + case MP_BUF: + return "Buffer overflow"; + default: + return "Invalid error code"; + } +} + +#endif diff --git a/libtommath/bn_mp_exch.c b/libtommath/bn_mp_exch.c index fc26bae..552094c 100644 --- a/libtommath/bn_mp_exch.c +++ b/libtommath/bn_mp_exch.c @@ -1,34 +1,17 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_EXCH_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ -/* swap the elements of two integers, for cases where you can't simply swap the +/* swap the elements of two integers, for cases where you can't simply swap the * mp_int pointers around */ -void -mp_exch (mp_int * a, mp_int * b) +void mp_exch(mp_int *a, mp_int *b) { - mp_int t; + mp_int t; - t = *a; - *a = *b; - *b = t; + t = *a; + *a = *b; + *b = t; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_export.c b/libtommath/bn_mp_export.c deleted file mode 100644 index e8dc244..0000000 --- a/libtommath/bn_mp_export.c +++ /dev/null @@ -1,88 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_EXPORT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* based on gmp's mpz_export. - * see http://gmplib.org/manual/Integer-Import-and-Export.html - */ -int mp_export(void* rop, size_t* countp, int order, size_t size, - int endian, size_t nails, mp_int* op) { - int result; - size_t odd_nails, nail_bytes, i, j, bits, count; - unsigned char odd_nail_mask; - - mp_int t; - - if ((result = mp_init_copy(&t, op)) != MP_OKAY) { - return result; - } - - if (endian == 0) { - union {
- unsigned int i;
- char c[4];
- } lint; - lint.i = 0x01020304;
-
- endian = (lint.c[0] == 4) ? -1 : 1; - } - - odd_nails = (nails % 8); - odd_nail_mask = 0xff; - for (i = 0; i < odd_nails; ++i) { - odd_nail_mask ^= (1 << (7 - i)); - } - nail_bytes = nails / 8; - - bits = mp_count_bits(&t); - count = (bits / ((size * 8) - nails)) + (((bits % ((size * 8) - nails)) != 0) ? 1 : 0); - - for (i = 0; i < count; ++i) { - for (j = 0; j < size; ++j) { - unsigned char* byte = ( - (unsigned char*)rop + - (((order == -1) ? i : ((count - 1) - i)) * size) + - ((endian == -1) ? j : ((size - 1) - j)) - ); - - if (j >= (size - nail_bytes)) { - *byte = 0; - continue; - } - - *byte = (unsigned char)((j == ((size - nail_bytes) - 1)) ? (t.dp[0] & odd_nail_mask) : (t.dp[0] & 0xFF)); - - if ((result = mp_div_2d(&t, ((j == ((size - nail_bytes) - 1)) ? (8 - odd_nails) : 8), &t, NULL)) != MP_OKAY) { - mp_clear(&t); - return result; - } - } - } - - mp_clear(&t); - - if (countp != NULL) { - *countp = count; - } - - return MP_OKAY; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_expt_d.c b/libtommath/bn_mp_expt_d.c deleted file mode 100644 index a311926..0000000 --- a/libtommath/bn_mp_expt_d.c +++ /dev/null @@ -1,28 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_EXPT_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* wrapper function for mp_expt_d_ex() */ -int mp_expt_d (mp_int * a, mp_digit b, mp_int * c) -{ - return mp_expt_d_ex(a, b, c, 0); -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_expt_d_ex.c b/libtommath/bn_mp_expt_d_ex.c deleted file mode 100644 index c361b27..0000000 --- a/libtommath/bn_mp_expt_d_ex.c +++ /dev/null @@ -1,83 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_EXPT_D_EX_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* calculate c = a**b using a square-multiply algorithm */ -int mp_expt_d_ex (mp_int * a, mp_digit b, mp_int * c, int fast) -{ - int res; - unsigned int x; - - mp_int g; - - if ((res = mp_init_copy (&g, a)) != MP_OKAY) { - return res; - } - - /* set initial result */ - mp_set (c, 1); - - if (fast != 0) { - while (b > 0) { - /* if the bit is set multiply */ - if ((b & 1) != 0) { - if ((res = mp_mul (c, &g, c)) != MP_OKAY) { - mp_clear (&g); - return res; - } - } - - /* square */ - if (b > 1) { - if ((res = mp_sqr (&g, &g)) != MP_OKAY) { - mp_clear (&g); - return res; - } - } - - /* shift to next bit */ - b >>= 1; - } - } - else { - for (x = 0; x < DIGIT_BIT; x++) { - /* square */ - if ((res = mp_sqr (c, c)) != MP_OKAY) { - mp_clear (&g); - return res; - } - - /* if the bit is set multiply */ - if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) { - if ((res = mp_mul (c, &g, c)) != MP_OKAY) { - mp_clear (&g); - return res; - } - } - - /* shift to next bit */ - b <<= 1; - } - } /* if ... else */ - - mp_clear (&g); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_expt_u32.c b/libtommath/bn_mp_expt_u32.c new file mode 100644 index 0000000..2ab67ba --- /dev/null +++ b/libtommath/bn_mp_expt_u32.c @@ -0,0 +1,46 @@ +#include "tommath_private.h" +#ifdef BN_MP_EXPT_U32_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* calculate c = a**b using a square-multiply algorithm */ +mp_err mp_expt_u32(const mp_int *a, uint32_t b, mp_int *c) +{ + mp_err err; + + mp_int g; + + if ((err = mp_init_copy(&g, a)) != MP_OKAY) { + return err; + } + + /* set initial result */ + mp_set(c, 1uL); + + while (b > 0u) { + /* if the bit is set multiply */ + if ((b & 1u) != 0u) { + if ((err = mp_mul(c, &g, c)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* square */ + if (b > 1u) { + if ((err = mp_sqr(&g, &g)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* shift to next bit */ + b >>= 1; + } + + err = MP_OKAY; + +LBL_ERR: + mp_clear(&g); + return err; +} + +#endif diff --git a/libtommath/bn_mp_exptmod.c b/libtommath/bn_mp_exptmod.c index 25c389d..5f811eb 100644 --- a/libtommath/bn_mp_exptmod.c +++ b/libtommath/bn_mp_exptmod.c @@ -1,112 +1,76 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_EXPTMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* this is a shell function that calls either the normal or Montgomery * exptmod functions. Originally the call to the montgomery code was * embedded in the normal function but that wasted alot of stack space * for nothing (since 99% of the time the Montgomery code would be called) */ -int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) +mp_err mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y) { - int dr; + int dr; - /* modulus P must be positive */ - if (P->sign == MP_NEG) { - return MP_VAL; - } + /* modulus P must be positive */ + if (P->sign == MP_NEG) { + return MP_VAL; + } - /* if exponent X is negative we have to recurse */ - if (X->sign == MP_NEG) { -#ifdef BN_MP_INVMOD_C - mp_int tmpG, tmpX; - int err; + /* if exponent X is negative we have to recurse */ + if (X->sign == MP_NEG) { + mp_int tmpG, tmpX; + mp_err err; - /* first compute 1/G mod P */ - if ((err = mp_init(&tmpG)) != MP_OKAY) { - return err; - } - if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) { - mp_clear(&tmpG); - return err; - } + if (!MP_HAS(MP_INVMOD)) { + return MP_VAL; + } - /* now get |X| */ - if ((err = mp_init(&tmpX)) != MP_OKAY) { - mp_clear(&tmpG); - return err; - } - if ((err = mp_abs(X, &tmpX)) != MP_OKAY) { - mp_clear_multi(&tmpG, &tmpX, NULL); - return err; - } + if ((err = mp_init_multi(&tmpG, &tmpX, NULL)) != MP_OKAY) { + return err; + } - /* and now compute (1/G)**|X| instead of G**X [X < 0] */ - err = mp_exptmod(&tmpG, &tmpX, P, Y); - mp_clear_multi(&tmpG, &tmpX, NULL); - return err; -#else - /* no invmod */ - return MP_VAL; -#endif - } + /* first compute 1/G mod P */ + if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) { + goto LBL_ERR; + } -/* modified diminished radix reduction */ -#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_C) - if (mp_reduce_is_2k_l(P) == MP_YES) { - return s_mp_exptmod(G, X, P, Y, 1); - } -#endif + /* now get |X| */ + if ((err = mp_abs(X, &tmpX)) != MP_OKAY) { + goto LBL_ERR; + } -#ifdef BN_MP_DR_IS_MODULUS_C - /* is it a DR modulus? */ - dr = mp_dr_is_modulus(P); -#else - /* default to no */ - dr = 0; -#endif + /* and now compute (1/G)**|X| instead of G**X [X < 0] */ + err = mp_exptmod(&tmpG, &tmpX, P, Y); +LBL_ERR: + mp_clear_multi(&tmpG, &tmpX, NULL); + return err; + } -#ifdef BN_MP_REDUCE_IS_2K_C - /* if not, is it a unrestricted DR modulus? */ - if (dr == 0) { - dr = mp_reduce_is_2k(P) << 1; - } -#endif - - /* if the modulus is odd or dr != 0 use the montgomery method */ -#ifdef BN_MP_EXPTMOD_FAST_C - if ((mp_isodd (P) == MP_YES) || (dr != 0)) { - return mp_exptmod_fast (G, X, P, Y, dr); - } else { -#endif -#ifdef BN_S_MP_EXPTMOD_C - /* otherwise use the generic Barrett reduction technique */ - return s_mp_exptmod (G, X, P, Y, 0); -#else - /* no exptmod for evens */ - return MP_VAL; -#endif -#ifdef BN_MP_EXPTMOD_FAST_C - } -#endif + /* modified diminished radix reduction */ + if (MP_HAS(MP_REDUCE_IS_2K_L) && MP_HAS(MP_REDUCE_2K_L) && MP_HAS(S_MP_EXPTMOD) && + (mp_reduce_is_2k_l(P) == MP_YES)) { + return s_mp_exptmod(G, X, P, Y, 1); + } + + /* is it a DR modulus? default to no */ + dr = (MP_HAS(MP_DR_IS_MODULUS) && (mp_dr_is_modulus(P) == MP_YES)) ? 1 : 0; + + /* if not, is it a unrestricted DR modulus? */ + if (MP_HAS(MP_REDUCE_IS_2K) && (dr == 0)) { + dr = (mp_reduce_is_2k(P) == MP_YES) ? 2 : 0; + } + + /* if the modulus is odd or dr != 0 use the montgomery method */ + if (MP_HAS(S_MP_EXPTMOD_FAST) && (MP_IS_ODD(P) || (dr != 0))) { + return s_mp_exptmod_fast(G, X, P, Y, dr); + } else if (MP_HAS(S_MP_EXPTMOD)) { + /* otherwise use the generic Barrett reduction technique */ + return s_mp_exptmod(G, X, P, Y, 0); + } else { + /* no exptmod for evens */ + return MP_VAL; + } } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_exptmod_fast.c b/libtommath/bn_mp_exptmod_fast.c deleted file mode 100644 index 5e5c7f2..0000000 --- a/libtommath/bn_mp_exptmod_fast.c +++ /dev/null @@ -1,321 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_EXPTMOD_FAST_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85 - * - * Uses a left-to-right k-ary sliding window to compute the modular exponentiation. - * The value of k changes based on the size of the exponent. - * - * Uses Montgomery or Diminished Radix reduction [whichever appropriate] - */ - -#ifdef MP_LOW_MEM - #define TAB_SIZE 32 -#else - #define TAB_SIZE 256 -#endif - -int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) -{ - mp_int M[TAB_SIZE], res; - mp_digit buf, mp; - int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; - - /* use a pointer to the reduction algorithm. This allows us to use - * one of many reduction algorithms without modding the guts of - * the code with if statements everywhere. - */ - int (*redux)(mp_int*,mp_int*,mp_digit); - - /* 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 = mp_init_size(&M[1], P->alloc)) != MP_OKAY) { - return err; - } - - /* now init the second half of the array */ - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - if ((err = mp_init_size(&M[x], P->alloc)) != MP_OKAY) { - for (y = 1<<(winsize-1); y < x; y++) { - mp_clear (&M[y]); - } - mp_clear(&M[1]); - return err; - } - } - - /* determine and setup reduction code */ - if (redmode == 0) { -#ifdef BN_MP_MONTGOMERY_SETUP_C - /* now setup montgomery */ - if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) { - goto LBL_M; - } -#else - err = MP_VAL; - goto LBL_M; -#endif - - /* automatically pick the comba one if available (saves quite a few calls/ifs) */ -#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C - if ((((P->used * 2) + 1) < MP_WARRAY) && - (P->used < (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) { - redux = fast_mp_montgomery_reduce; - } else -#endif - { -#ifdef BN_MP_MONTGOMERY_REDUCE_C - /* use slower baseline Montgomery method */ - redux = mp_montgomery_reduce; -#else - err = MP_VAL; - goto LBL_M; -#endif - } - } else if (redmode == 1) { -#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C) - /* setup DR reduction for moduli of the form B**k - b */ - mp_dr_setup(P, &mp); - redux = mp_dr_reduce; -#else - err = MP_VAL; - goto LBL_M; -#endif - } else { -#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C) - /* setup DR reduction for moduli of the form 2**k - b */ - if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) { - goto LBL_M; - } - redux = mp_reduce_2k; -#else - err = MP_VAL; - goto LBL_M; -#endif - } - - /* setup result */ - if ((err = mp_init_size (&res, P->alloc)) != MP_OKAY) { - goto LBL_M; - } - - /* create M table - * - - * - * The first half of the table is not computed though accept for M[0] and M[1] - */ - - if (redmode == 0) { -#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C - /* now we need R mod m */ - if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) { - goto LBL_RES; - } - - /* now set M[1] to G * R mod m */ - if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) { - goto LBL_RES; - } -#else - err = MP_VAL; - goto LBL_RES; -#endif - } else { - mp_set(&res, 1); - if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) { - goto LBL_RES; - } - } - - /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */ - if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_RES; - } - - for (x = 0; x < (winsize - 1); x++) { - if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* create upper table */ - for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { - if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&M[x], P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* 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 so break */ - if (digidx == -1) { - break; - } - /* read next digit and reset bitcnt */ - buf = X->dp[digidx--]; - bitcnt = (int)DIGIT_BIT; - } - - /* grab the next msb from the exponent */ - y = (mp_digit)(buf >> (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 = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_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 = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* then multiply */ - if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_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 = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - - /* get next bit of the window */ - bitbuf <<= 1; - if ((bitbuf & (1 << winsize)) != 0) { - /* then multiply */ - if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - } - } - - if (redmode == 0) { - /* fixup result if Montgomery reduction is used - * recall that any value in a Montgomery system is - * actually multiplied by R mod n. So we have - * to reduce one more time to cancel out the factor - * of R. - */ - if ((err = redux(&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* swap res with Y */ - mp_exch (&res, Y); - err = MP_OKAY; -LBL_RES:mp_clear (&res); -LBL_M: - mp_clear(&M[1]); - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - mp_clear (&M[x]); - } - return err; -} -#endif - - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_exteuclid.c b/libtommath/bn_mp_exteuclid.c index 3c9612e..faf47ba 100644 --- a/libtommath/bn_mp_exteuclid.c +++ b/libtommath/bn_mp_exteuclid.c @@ -1,75 +1,69 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_EXTEUCLID_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* Extended euclidean algorithm of (a, b) produces a*u1 + b*u2 = u3 */ -int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3) +mp_err mp_exteuclid(const mp_int *a, const mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3) { - mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp; - int err; + mp_int u1, u2, u3, v1, v2, v3, t1, t2, t3, q, tmp; + mp_err err; if ((err = mp_init_multi(&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, 1); - if ((err = mp_copy(a, &u3)) != MP_OKAY) { goto LBL_ERR; } + mp_set(&u1, 1uL); + if ((err = mp_copy(a, &u3)) != MP_OKAY) goto LBL_ERR; /* initialize, (v1,v2,v3) = (0,1,b) */ - mp_set(&v2, 1); - if ((err = mp_copy(b, &v3)) != MP_OKAY) { goto LBL_ERR; } + mp_set(&v2, 1uL); + if ((err = mp_copy(b, &v3)) != MP_OKAY) goto LBL_ERR; /* loop while v3 != 0 */ - while (mp_iszero(&v3) == MP_NO) { - /* q = u3/v3 */ - if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto LBL_ERR; } + while (!MP_IS_ZERO(&v3)) { + /* q = u3/v3 */ + if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) goto LBL_ERR; - /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */ - if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto LBL_ERR; } + /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */ + if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) goto LBL_ERR; - /* (u1,u2,u3) = (v1,v2,v3) */ - if ((err = mp_copy(&v1, &u1)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_copy(&v2, &u2)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_copy(&v3, &u3)) != MP_OKAY) { goto LBL_ERR; } + /* (u1,u2,u3) = (v1,v2,v3) */ + if ((err = mp_copy(&v1, &u1)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_copy(&v2, &u2)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_copy(&v3, &u3)) != MP_OKAY) goto LBL_ERR; - /* (v1,v2,v3) = (t1,t2,t3) */ - if ((err = mp_copy(&t1, &v1)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_copy(&t2, &v2)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { goto LBL_ERR; } + /* (v1,v2,v3) = (t1,t2,t3) */ + if ((err = mp_copy(&t1, &v1)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_copy(&t2, &v2)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_copy(&t3, &v3)) != MP_OKAY) goto LBL_ERR; } /* make sure U3 >= 0 */ if (u3.sign == MP_NEG) { - if ((err = mp_neg(&u1, &u1)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_neg(&u2, &u2)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_neg(&u3, &u3)) != MP_OKAY) { goto LBL_ERR; } + if ((err = mp_neg(&u1, &u1)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_neg(&u2, &u2)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_neg(&u3, &u3)) != MP_OKAY) goto LBL_ERR; } /* copy result out */ - if (U1 != NULL) { mp_exch(U1, &u1); } - if (U2 != NULL) { mp_exch(U2, &u2); } - if (U3 != NULL) { mp_exch(U3, &u3); } + if (U1 != NULL) { + mp_exch(U1, &u1); + } + if (U2 != NULL) { + mp_exch(U2, &u2); + } + if (U3 != NULL) { + mp_exch(U3, &u3); + } err = MP_OKAY; LBL_ERR: @@ -77,7 +71,3 @@ LBL_ERR: return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_fread.c b/libtommath/bn_mp_fread.c index 140721b..52ea773 100644 --- a/libtommath/bn_mp_fread.c +++ b/libtommath/bn_mp_fread.c @@ -1,69 +1,60 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_FREAD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ -#ifndef LTM_NO_FILE +#ifndef MP_NO_FILE /* read a bigint from a file stream in ASCII */ -int mp_fread(mp_int *a, int radix, FILE *stream) +mp_err mp_fread(mp_int *a, int radix, FILE *stream) { - int err, ch, neg, y; - - /* clear a */ - mp_zero(a); - + mp_err err; + mp_sign neg; + /* if first digit is - then set negative */ - ch = fgetc(stream); - if (ch == '-') { + int ch = fgetc(stream); + if (ch == (int)'-') { neg = MP_NEG; ch = fgetc(stream); } else { neg = MP_ZPOS; } - - for (;;) { - /* find y in the radix map */ - for (y = 0; y < radix; y++) { - if (mp_s_rmap[y] == ch) { - break; - } + + /* no digits, return error */ + if (ch == EOF) { + return MP_ERR; + } + + /* clear a */ + mp_zero(a); + + do { + int y; + unsigned pos = (unsigned)(ch - (int)'('); + if (mp_s_rmap_reverse_sz < pos) { + break; } - if (y == radix) { + + y = (int)mp_s_rmap_reverse[pos]; + + if ((y == 0xff) || (y >= radix)) { break; } - + /* shift up and add */ - if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) { + if ((err = mp_mul_d(a, (mp_digit)radix, a)) != MP_OKAY) { return err; } - if ((err = mp_add_d(a, y, a)) != MP_OKAY) { + if ((err = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) { return err; } - - ch = fgetc(stream); - } - if (mp_cmp_d(a, 0) != MP_EQ) { + } while ((ch = fgetc(stream)) != EOF); + + if (a->used != 0) { a->sign = neg; } - + return MP_OKAY; } #endif #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_from_sbin.c b/libtommath/bn_mp_from_sbin.c new file mode 100644 index 0000000..20e4597 --- /dev/null +++ b/libtommath/bn_mp_from_sbin.c @@ -0,0 +1,25 @@ +#include "tommath_private.h" +#ifdef BN_MP_FROM_SBIN_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* read signed bin, big endian, first byte is 0==positive or 1==negative */ +mp_err mp_from_sbin(mp_int *a, const unsigned char *buf, size_t size) +{ + mp_err err; + + /* read magnitude */ + if ((err = mp_from_ubin(a, buf + 1, size - 1u)) != MP_OKAY) { + return err; + } + + /* first byte is 0 for positive, non-zero for negative */ + if (buf[0] == (unsigned char)0) { + a->sign = MP_ZPOS; + } else { + a->sign = MP_NEG; + } + + return MP_OKAY; +} +#endif diff --git a/libtommath/bn_mp_from_ubin.c b/libtommath/bn_mp_from_ubin.c new file mode 100644 index 0000000..7f73cbc --- /dev/null +++ b/libtommath/bn_mp_from_ubin.c @@ -0,0 +1,39 @@ +#include "tommath_private.h" +#ifdef BN_MP_FROM_UBIN_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* reads a unsigned char array, assumes the msb is stored first [big endian] */ +mp_err mp_from_ubin(mp_int *a, const unsigned char *buf, size_t size) +{ + mp_err err; + + /* make sure there are at least two digits */ + if (a->alloc < 2) { + if ((err = mp_grow(a, 2)) != MP_OKAY) { + return err; + } + } + + /* zero the int */ + mp_zero(a); + + /* read the bytes in */ + while (size-- > 0u) { + if ((err = mp_mul_2d(a, 8, a)) != MP_OKAY) { + return err; + } + +#ifndef MP_8BIT + a->dp[0] |= *buf++; + a->used += 1; +#else + a->dp[0] = (*buf & MP_MASK); + a->dp[1] |= ((*buf++ >> 7) & 1u); + a->used += 2; +#endif + } + mp_clamp(a); + return MP_OKAY; +} +#endif diff --git a/libtommath/bn_mp_fwrite.c b/libtommath/bn_mp_fwrite.c index 23b5f64..abe2e67 100644 --- a/libtommath/bn_mp_fwrite.c +++ b/libtommath/bn_mp_fwrite.c @@ -1,54 +1,45 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_FWRITE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -#ifndef LTM_NO_FILE -int mp_fwrite(mp_int *a, int radix, FILE *stream) +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +#ifndef MP_NO_FILE +mp_err mp_fwrite(const mp_int *a, int radix, FILE *stream) { char *buf; - int err, len, x; - - if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) { - return err; + mp_err err; + int len; + size_t written; + + /* TODO: this function is not in this PR */ + if (MP_HAS(MP_RADIX_SIZE_OVERESTIMATE)) { + /* if ((err = mp_radix_size_overestimate(&t, base, &len)) != MP_OKAY) goto LBL_ERR; */ + } else { + if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) { + return err; + } } - buf = OPT_CAST(char) XMALLOC (len); + buf = (char *) MP_MALLOC((size_t)len); if (buf == NULL) { return MP_MEM; } - - if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) { - XFREE (buf); - return err; + + if ((err = mp_to_radix(a, buf, (size_t)len, &written, radix)) != MP_OKAY) { + goto LBL_ERR; } - - for (x = 0; x < len; x++) { - if (fputc(buf[x], stream) == EOF) { - XFREE (buf); - return MP_VAL; - } + + if (fwrite(buf, written, 1uL, stream) != 1uL) { + err = MP_ERR; + goto LBL_ERR; } - - XFREE (buf); - return MP_OKAY; + err = MP_OKAY; + + +LBL_ERR: + MP_FREE_BUFFER(buf, (size_t)len); + return err; } #endif #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_gcd.c b/libtommath/bn_mp_gcd.c index b0be8fb..53029ba 100644 --- a/libtommath/bn_mp_gcd.c +++ b/libtommath/bn_mp_gcd.c @@ -1,105 +1,92 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_GCD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* Greatest Common Divisor using the binary method */ -int mp_gcd (mp_int * a, mp_int * b, mp_int * c) +mp_err mp_gcd(const mp_int *a, const mp_int *b, mp_int *c) { - mp_int u, v; - int k, u_lsb, v_lsb, res; + mp_int u, v; + int k, u_lsb, v_lsb; + mp_err err; - /* either zero than gcd is the largest */ - if (mp_iszero (a) == MP_YES) { - return mp_abs (b, c); - } - if (mp_iszero (b) == MP_YES) { - return mp_abs (a, c); - } + /* either zero than gcd is the largest */ + if (MP_IS_ZERO(a)) { + return mp_abs(b, c); + } + if (MP_IS_ZERO(b)) { + return mp_abs(a, c); + } - /* get copies of a and b we can modify */ - if ((res = mp_init_copy (&u, a)) != MP_OKAY) { - return res; - } + /* get copies of a and b we can modify */ + if ((err = mp_init_copy(&u, a)) != MP_OKAY) { + return err; + } - if ((res = mp_init_copy (&v, b)) != MP_OKAY) { - goto LBL_U; - } + if ((err = mp_init_copy(&v, b)) != MP_OKAY) { + goto LBL_U; + } - /* must be positive for the remainder of the algorithm */ - u.sign = v.sign = MP_ZPOS; + /* must be positive for the remainder of the algorithm */ + u.sign = v.sign = MP_ZPOS; - /* B1. Find the common power of two for u and v */ - u_lsb = mp_cnt_lsb(&u); - v_lsb = mp_cnt_lsb(&v); - k = MIN(u_lsb, v_lsb); + /* B1. Find the common power of two for u and v */ + u_lsb = mp_cnt_lsb(&u); + v_lsb = mp_cnt_lsb(&v); + k = MP_MIN(u_lsb, v_lsb); - if (k > 0) { - /* divide the power of two out */ - if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) { - goto LBL_V; - } + if (k > 0) { + /* divide the power of two out */ + if ((err = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) { + goto LBL_V; + } - if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) { - goto LBL_V; - } - } + if ((err = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) { + goto LBL_V; + } + } - /* divide any remaining factors of two out */ - if (u_lsb != k) { - if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) { - goto LBL_V; - } - } + /* divide any remaining factors of two out */ + if (u_lsb != k) { + if ((err = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) { + goto LBL_V; + } + } - if (v_lsb != k) { - if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) { - goto LBL_V; - } - } + if (v_lsb != k) { + if ((err = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) { + goto LBL_V; + } + } - while (mp_iszero(&v) == MP_NO) { - /* make sure v is the largest */ - if (mp_cmp_mag(&u, &v) == MP_GT) { - /* swap u and v to make sure v is >= u */ - mp_exch(&u, &v); - } - - /* subtract smallest from largest */ - if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) { - goto LBL_V; - } - - /* Divide out all factors of two */ - if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) { - goto LBL_V; - } - } + while (!MP_IS_ZERO(&v)) { + /* make sure v is the largest */ + if (mp_cmp_mag(&u, &v) == MP_GT) { + /* swap u and v to make sure v is >= u */ + mp_exch(&u, &v); + } - /* multiply by 2**k which we divided out at the beginning */ - if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) { - goto LBL_V; - } - c->sign = MP_ZPOS; - res = MP_OKAY; -LBL_V:mp_clear (&u); -LBL_U:mp_clear (&v); - return res; + /* subtract smallest from largest */ + if ((err = s_mp_sub(&v, &u, &v)) != MP_OKAY) { + goto LBL_V; + } + + /* Divide out all factors of two */ + if ((err = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) { + goto LBL_V; + } + } + + /* multiply by 2**k which we divided out at the beginning */ + if ((err = mp_mul_2d(&u, k, c)) != MP_OKAY) { + goto LBL_V; + } + c->sign = MP_ZPOS; + err = MP_OKAY; +LBL_V: + mp_clear(&u); +LBL_U: + mp_clear(&v); + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_get_i32.c b/libtommath/bn_mp_get_i32.c new file mode 100644 index 0000000..030b657 --- /dev/null +++ b/libtommath/bn_mp_get_i32.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_GET_I32_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_GET_SIGNED(mp_get_i32, mp_get_mag_u32, int32_t, uint32_t) +#endif diff --git a/libtommath/bn_mp_get_i64.c b/libtommath/bn_mp_get_i64.c new file mode 100644 index 0000000..969c8d2 --- /dev/null +++ b/libtommath/bn_mp_get_i64.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_GET_I64_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_GET_SIGNED(mp_get_i64, mp_get_mag_u64, int64_t, uint64_t) +#endif diff --git a/libtommath/bn_mp_get_int.c b/libtommath/bn_mp_get_int.c deleted file mode 100644 index 5c820f8..0000000 --- a/libtommath/bn_mp_get_int.c +++ /dev/null @@ -1,45 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_GET_INT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* get the lower 32-bits of an mp_int */ -unsigned long mp_get_int(mp_int * a) -{ - int i; - mp_min_u32 res; - - if (a->used == 0) { - return 0; - } - - /* get number of digits of the lsb we have to read */ - i = MIN(a->used,(int)(((sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; - - /* get most significant digit of result */ - res = DIGIT(a,i); - - while (--i >= 0) { - res = (res << DIGIT_BIT) | DIGIT(a,i); - } - - /* force result to 32-bits always so it is consistent on non 32-bit platforms */ - return res & 0xFFFFFFFFUL; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_get_l.c b/libtommath/bn_mp_get_l.c new file mode 100644 index 0000000..55d78ec --- /dev/null +++ b/libtommath/bn_mp_get_l.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_GET_L_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_GET_SIGNED(mp_get_l, mp_get_mag_ul, long, unsigned long) +#endif diff --git a/libtommath/bn_mp_get_ll.c b/libtommath/bn_mp_get_ll.c new file mode 100644 index 0000000..2687534 --- /dev/null +++ b/libtommath/bn_mp_get_ll.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_GET_LL_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_GET_SIGNED(mp_get_ll, mp_get_mag_ull, long long, unsigned long long) +#endif diff --git a/libtommath/bn_mp_get_long.c b/libtommath/bn_mp_get_long.c deleted file mode 100644 index 7c3d0fe..0000000 --- a/libtommath/bn_mp_get_long.c +++ /dev/null @@ -1,41 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_GET_LONG_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* get the lower unsigned long of an mp_int, platform dependent */ -unsigned long mp_get_long(mp_int * a) -{ - int i; - unsigned long res; - - if (a->used == 0) { - return 0; - } - - /* get number of digits of the lsb we have to read */ - i = MIN(a->used,(int)(((sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; - - /* get most significant digit of result */ - res = DIGIT(a,i); - -#if (ULONG_MAX != 0xffffffffuL) || (DIGIT_BIT < 32) - while (--i >= 0) { - res = (res << DIGIT_BIT) | DIGIT(a,i); - } -#endif - return res; -} -#endif diff --git a/libtommath/bn_mp_get_long_long.c b/libtommath/bn_mp_get_long_long.c deleted file mode 100644 index 4b959e6..0000000 --- a/libtommath/bn_mp_get_long_long.c +++ /dev/null @@ -1,41 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_GET_LONG_LONG_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* get the lower unsigned long long of an mp_int, platform dependent */ -unsigned long long mp_get_long_long (mp_int * a) -{ - int i; - unsigned long long res; - - if (a->used == 0) { - return 0; - } - - /* get number of digits of the lsb we have to read */ - i = MIN(a->used,(int)(((sizeof(unsigned long long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; - - /* get most significant digit of result */ - res = DIGIT(a,i); - -#if DIGIT_BIT < 64 - while (--i >= 0) { - res = (res << DIGIT_BIT) | DIGIT(a,i); - } -#endif - return res; -} -#endif diff --git a/libtommath/bn_mp_get_mag_u32.c b/libtommath/bn_mp_get_mag_u32.c new file mode 100644 index 0000000..d77189b --- /dev/null +++ b/libtommath/bn_mp_get_mag_u32.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_GET_MAG_U32_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_GET_MAG(mp_get_mag_u32, uint32_t) +#endif diff --git a/libtommath/bn_mp_get_mag_u64.c b/libtommath/bn_mp_get_mag_u64.c new file mode 100644 index 0000000..36dd73f --- /dev/null +++ b/libtommath/bn_mp_get_mag_u64.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_GET_MAG_U64_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_GET_MAG(mp_get_mag_u64, uint64_t) +#endif diff --git a/libtommath/bn_mp_get_mag_ul.c b/libtommath/bn_mp_get_mag_ul.c new file mode 100644 index 0000000..e8819ae --- /dev/null +++ b/libtommath/bn_mp_get_mag_ul.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_GET_MAG_UL_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_GET_MAG(mp_get_mag_ul, unsigned long) +#endif diff --git a/libtommath/bn_mp_get_mag_ull.c b/libtommath/bn_mp_get_mag_ull.c new file mode 100644 index 0000000..63a2741 --- /dev/null +++ b/libtommath/bn_mp_get_mag_ull.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_GET_MAG_ULL_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_GET_MAG(mp_get_mag_ull, unsigned long long) +#endif diff --git a/libtommath/bn_mp_grow.c b/libtommath/bn_mp_grow.c index 74e07b1..9e904c5 100644 --- a/libtommath/bn_mp_grow.c +++ b/libtommath/bn_mp_grow.c @@ -1,57 +1,38 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_GROW_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* grow as required */ -int mp_grow (mp_int * a, int size) +mp_err mp_grow(mp_int *a, int size) { - int i; - mp_digit *tmp; + int i; + mp_digit *tmp; - /* if the alloc size is smaller alloc more ram */ - if (a->alloc < size) { - /* ensure there are always at least MP_PREC digits extra on top */ - size += (MP_PREC * 2) - (size % MP_PREC); + /* if the alloc size is smaller alloc more ram */ + if (a->alloc < size) { + /* reallocate the array a->dp + * + * We store the return in a temporary variable + * in case the operation failed we don't want + * to overwrite the dp member of a. + */ + tmp = (mp_digit *) MP_REALLOC(a->dp, + (size_t)a->alloc * sizeof(mp_digit), + (size_t)size * sizeof(mp_digit)); + if (tmp == NULL) { + /* reallocation failed but "a" is still valid [can be freed] */ + return MP_MEM; + } - /* reallocate the array a->dp - * - * We store the return in a temporary variable - * in case the operation failed we don't want - * to overwrite the dp member of a. - */ - tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size); - if (tmp == NULL) { - /* reallocation failed but "a" is still valid [can be freed] */ - return MP_MEM; - } + /* reallocation succeeded so set a->dp */ + a->dp = tmp; - /* reallocation succeeded so set a->dp */ - a->dp = tmp; - - /* zero excess digits */ - i = a->alloc; - a->alloc = size; - for (; i < a->alloc; i++) { - a->dp[i] = 0; - } - } - return MP_OKAY; + /* zero excess digits */ + i = a->alloc; + a->alloc = size; + MP_ZERO_DIGITS(a->dp + i, a->alloc - i); + } + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_import.c b/libtommath/bn_mp_import.c deleted file mode 100644 index 2e26261..0000000 --- a/libtommath/bn_mp_import.c +++ /dev/null @@ -1,73 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_IMPORT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* based on gmp's mpz_import. - * see http://gmplib.org/manual/Integer-Import-and-Export.html - */ -int mp_import(mp_int* rop, size_t count, int order, size_t size, - int endian, size_t nails, const void* op) { - int result; - size_t odd_nails, nail_bytes, i, j; - unsigned char odd_nail_mask; - - mp_zero(rop); - - if (endian == 0) { - union {
- unsigned int i;
- char c[4];
- } lint; - lint.i = 0x01020304;
-
- endian = (lint.c[0] == 4) ? -1 : 1; - } - - odd_nails = (nails % 8); - odd_nail_mask = 0xff; - for (i = 0; i < odd_nails; ++i) { - odd_nail_mask ^= (1 << (7 - i)); - } - nail_bytes = nails / 8; - - for (i = 0; i < count; ++i) { - for (j = 0; j < (size - nail_bytes); ++j) { - unsigned char byte = *( - (unsigned char*)op + - (((order == 1) ? i : ((count - 1) - i)) * size) + - ((endian == 1) ? (j + nail_bytes) : (((size - 1) - j) - nail_bytes)) - ); - - if ( - (result = mp_mul_2d(rop, ((j == 0) ? (8 - odd_nails) : 8), rop)) != MP_OKAY) { - return result; - } - - rop->dp[0] |= (j == 0) ? (byte & odd_nail_mask) : byte; - rop->used += 1; - } - } - - mp_clamp(rop); - - return MP_OKAY; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_incr.c b/libtommath/bn_mp_incr.c new file mode 100644 index 0000000..7695ac7 --- /dev/null +++ b/libtommath/bn_mp_incr.c @@ -0,0 +1,30 @@ +#include "tommath_private.h" +#ifdef BN_MP_INCR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* Increment "a" by one like "a++". Changes input! */ +mp_err mp_incr(mp_int *a) +{ + if (MP_IS_ZERO(a)) { + mp_set(a,1uL); + return MP_OKAY; + } else if (a->sign == MP_NEG) { + mp_err err; + a->sign = MP_ZPOS; + if ((err = mp_decr(a)) != MP_OKAY) { + return err; + } + /* There is no -0 in LTM */ + if (!MP_IS_ZERO(a)) { + a->sign = MP_NEG; + } + return MP_OKAY; + } else if (a->dp[0] < MP_DIGIT_MAX) { + a->dp[0]++; + return MP_OKAY; + } else { + return mp_add_d(a, 1uL,a); + } +} +#endif diff --git a/libtommath/bn_mp_init.c b/libtommath/bn_mp_init.c index ee374ae..2eb7924 100644 --- a/libtommath/bn_mp_init.c +++ b/libtommath/bn_mp_init.c @@ -1,46 +1,23 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_INIT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* init a new mp_int */ -int mp_init (mp_int * a) +mp_err mp_init(mp_int *a) { - int i; + /* allocate memory required and clear it */ + a->dp = (mp_digit *) MP_CALLOC((size_t)MP_PREC, sizeof(mp_digit)); + if (a->dp == NULL) { + return MP_MEM; + } - /* allocate memory required and clear it */ - a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC); - if (a->dp == NULL) { - return MP_MEM; - } + /* set the used to zero, allocated digits to the default precision + * and sign to positive */ + a->used = 0; + a->alloc = MP_PREC; + a->sign = MP_ZPOS; - /* set the digits to zero */ - for (i = 0; i < MP_PREC; i++) { - a->dp[i] = 0; - } - - /* set the used to zero, allocated digits to the default precision - * and sign to positive */ - a->used = 0; - a->alloc = MP_PREC; - a->sign = MP_ZPOS; - - return MP_OKAY; + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_init_copy.c b/libtommath/bn_mp_init_copy.c index 37a57ec..1888203 100644 --- a/libtommath/bn_mp_init_copy.c +++ b/libtommath/bn_mp_init_copy.c @@ -1,37 +1,21 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_INIT_COPY_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* creates "a" then copies b into it */ -int mp_init_copy (mp_int * a, mp_int * b) +mp_err mp_init_copy(mp_int *a, const mp_int *b) { - int res; + mp_err err; - if ((res = mp_init_size (a, b->used)) != MP_OKAY) { - return res; - } + if ((err = mp_init_size(a, b->used)) != MP_OKAY) { + return err; + } - if((res = mp_copy (b, a)) != MP_OKAY) { - mp_clear(a); - } + if ((err = mp_copy(b, a)) != MP_OKAY) { + mp_clear(a); + } - return res; + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_init_i32.c b/libtommath/bn_mp_init_i32.c new file mode 100644 index 0000000..bc4de8d --- /dev/null +++ b/libtommath/bn_mp_init_i32.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_INIT_I32_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_INIT_INT(mp_init_i32, mp_set_i32, int32_t) +#endif diff --git a/libtommath/bn_mp_init_i64.c b/libtommath/bn_mp_init_i64.c new file mode 100644 index 0000000..2fa1516 --- /dev/null +++ b/libtommath/bn_mp_init_i64.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_INIT_I64_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_INIT_INT(mp_init_i64, mp_set_i64, int64_t) +#endif diff --git a/libtommath/bn_mp_init_l.c b/libtommath/bn_mp_init_l.c new file mode 100644 index 0000000..bc380b5 --- /dev/null +++ b/libtommath/bn_mp_init_l.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_INIT_L_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_INIT_INT(mp_init_l, mp_set_l, long) +#endif diff --git a/libtommath/bn_mp_init_ll.c b/libtommath/bn_mp_init_ll.c new file mode 100644 index 0000000..dc7c4a4 --- /dev/null +++ b/libtommath/bn_mp_init_ll.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_INIT_LL_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_INIT_INT(mp_init_ll, mp_set_ll, long long) +#endif diff --git a/libtommath/bn_mp_init_multi.c b/libtommath/bn_mp_init_multi.c index 73d6a0f..d8390b5 100644 --- a/libtommath/bn_mp_init_multi.c +++ b/libtommath/bn_mp_init_multi.c @@ -1,56 +1,41 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_INIT_MULTI_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + #include <stdarg.h> -int mp_init_multi(mp_int *mp, ...) +mp_err mp_init_multi(mp_int *mp, ...) { - mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ - int n = 0; /* Number of ok inits */ - mp_int* cur_arg = mp; - va_list args; + mp_err err = MP_OKAY; /* Assume ok until proven otherwise */ + int n = 0; /* Number of ok inits */ + mp_int *cur_arg = mp; + va_list args; + + va_start(args, mp); /* init args to next argument from caller */ + while (cur_arg != NULL) { + if (mp_init(cur_arg) != MP_OKAY) { + /* Oops - error! Back-track and mp_clear what we already + succeeded in init-ing, then return error. + */ + va_list clean_args; - va_start(args, mp); /* init args to next argument from caller */ - while (cur_arg != NULL) { - if (mp_init(cur_arg) != MP_OKAY) { - /* Oops - error! Back-track and mp_clear what we already - succeeded in init-ing, then return error. - */ - va_list clean_args; - - /* now start cleaning up */ - cur_arg = mp; - va_start(clean_args, mp); - while (n-- != 0) { - mp_clear(cur_arg); - cur_arg = va_arg(clean_args, mp_int*); - } - va_end(clean_args); - res = MP_MEM; - break; - } - n++; - cur_arg = va_arg(args, mp_int*); - } - va_end(args); - return res; /* Assumed ok, if error flagged above. */ + /* now start cleaning up */ + cur_arg = mp; + va_start(clean_args, mp); + while (n-- != 0) { + mp_clear(cur_arg); + cur_arg = va_arg(clean_args, mp_int *); + } + va_end(clean_args); + err = MP_MEM; + break; + } + n++; + cur_arg = va_arg(args, mp_int *); + } + va_end(args); + return err; /* Assumed ok, if error flagged above. */ } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_init_set.c b/libtommath/bn_mp_init_set.c index ed4955c..5068f2b 100644 --- a/libtommath/bn_mp_init_set.c +++ b/libtommath/bn_mp_init_set.c @@ -1,32 +1,16 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_INIT_SET_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* initialize and set a digit */ -int mp_init_set (mp_int * a, mp_digit b) +mp_err mp_init_set(mp_int *a, mp_digit b) { - int err; - if ((err = mp_init(a)) != MP_OKAY) { - return err; - } - mp_set(a, b); - return err; + mp_err err; + if ((err = mp_init(a)) != MP_OKAY) { + return err; + } + mp_set(a, b); + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_init_set_int.c b/libtommath/bn_mp_init_set_int.c deleted file mode 100644 index 1bc1942..0000000 --- a/libtommath/bn_mp_init_set_int.c +++ /dev/null @@ -1,31 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_INIT_SET_INT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* initialize and set a digit */ -int mp_init_set_int (mp_int * a, unsigned long b) -{ - int err; - if ((err = mp_init(a)) != MP_OKAY) { - return err; - } - return mp_set_int(a, b); -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_init_size.c b/libtommath/bn_mp_init_size.c index 4446773..d622687 100644 --- a/libtommath/bn_mp_init_size.c +++ b/libtommath/bn_mp_init_size.c @@ -1,48 +1,24 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_INIT_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* init an mp_init for a given size */ -int mp_init_size (mp_int * a, int size) +mp_err mp_init_size(mp_int *a, int size) { - int x; + size = MP_MAX(MP_MIN_PREC, size); - /* pad size so there are always extra digits */ - size += (MP_PREC * 2) - (size % MP_PREC); - - /* alloc mem */ - a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size); - if (a->dp == NULL) { - return MP_MEM; - } + /* alloc mem */ + a->dp = (mp_digit *) MP_CALLOC((size_t)size, sizeof(mp_digit)); + if (a->dp == NULL) { + return MP_MEM; + } - /* set the members */ - a->used = 0; - a->alloc = size; - a->sign = MP_ZPOS; + /* set the members */ + a->used = 0; + a->alloc = size; + a->sign = MP_ZPOS; - /* zero the digits */ - for (x = 0; x < size; x++) { - a->dp[x] = 0; - } - - return MP_OKAY; + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_init_u32.c b/libtommath/bn_mp_init_u32.c new file mode 100644 index 0000000..015d89b --- /dev/null +++ b/libtommath/bn_mp_init_u32.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_INIT_U32_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_INIT_INT(mp_init_u32, mp_set_u32, uint32_t) +#endif diff --git a/libtommath/bn_mp_init_u64.c b/libtommath/bn_mp_init_u64.c new file mode 100644 index 0000000..2b35f7e --- /dev/null +++ b/libtommath/bn_mp_init_u64.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_INIT_U64_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_INIT_INT(mp_init_u64, mp_set_u64, uint64_t) +#endif diff --git a/libtommath/bn_mp_init_ul.c b/libtommath/bn_mp_init_ul.c new file mode 100644 index 0000000..5164f72 --- /dev/null +++ b/libtommath/bn_mp_init_ul.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_INIT_UL_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_INIT_INT(mp_init_ul, mp_set_ul, unsigned long) +#endif diff --git a/libtommath/bn_mp_init_ull.c b/libtommath/bn_mp_init_ull.c new file mode 100644 index 0000000..84110c0 --- /dev/null +++ b/libtommath/bn_mp_init_ull.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_INIT_ULL_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_INIT_INT(mp_init_ull, mp_set_ull, unsigned long long) +#endif diff --git a/libtommath/bn_mp_invmod.c b/libtommath/bn_mp_invmod.c index 36011d0..7b35a24 100644 --- a/libtommath/bn_mp_invmod.c +++ b/libtommath/bn_mp_invmod.c @@ -1,43 +1,23 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_INVMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* hac 14.61, pp608 */ -int mp_invmod (mp_int * a, mp_int * b, mp_int * c) +mp_err mp_invmod(const mp_int *a, const mp_int *b, mp_int *c) { - /* b cannot be negative */ - if ((b->sign == MP_NEG) || (mp_iszero(b) == MP_YES)) { - return MP_VAL; - } + /* b cannot be negative and has to be >1 */ + if ((b->sign == MP_NEG) || (mp_cmp_d(b, 1uL) != MP_GT)) { + return MP_VAL; + } -#ifdef BN_FAST_MP_INVMOD_C - /* if the modulus is odd we can use a faster routine instead */ - if ((mp_isodd(b) == MP_YES) && (mp_cmp_d(b, 1) != MP_EQ)) { - return fast_mp_invmod (a, b, c); - } -#endif + /* if the modulus is odd we can use a faster routine instead */ + if (MP_HAS(S_MP_INVMOD_FAST) && MP_IS_ODD(b)) { + return s_mp_invmod_fast(a, b, c); + } -#ifdef BN_MP_INVMOD_SLOW_C - return mp_invmod_slow(a, b, c); -#else - return MP_VAL; -#endif + return MP_HAS(S_MP_INVMOD_SLOW) + ? s_mp_invmod_slow(a, b, c) + : MP_VAL; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_invmod_slow.c b/libtommath/bn_mp_invmod_slow.c deleted file mode 100644 index ff0d5ae..0000000 --- a/libtommath/bn_mp_invmod_slow.c +++ /dev/null @@ -1,175 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_INVMOD_SLOW_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* hac 14.61, pp608 */ -int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int x, y, u, v, A, B, C, D; - int res; - - /* b cannot be negative */ - if ((b->sign == MP_NEG) || (mp_iszero(b) == MP_YES)) { - return MP_VAL; - } - - /* init temps */ - if ((res = mp_init_multi(&x, &y, &u, &v, - &A, &B, &C, &D, NULL)) != MP_OKAY) { - return res; - } - - /* x = a, y = b */ - if ((res = mp_mod(a, b, &x)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_copy (b, &y)) != MP_OKAY) { - goto LBL_ERR; - } - - /* 2. [modified] if x,y are both even then return an error! */ - if ((mp_iseven (&x) == MP_YES) && (mp_iseven (&y) == MP_YES)) { - res = MP_VAL; - goto LBL_ERR; - } - - /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ - if ((res = mp_copy (&x, &u)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_copy (&y, &v)) != MP_OKAY) { - goto LBL_ERR; - } - mp_set (&A, 1); - mp_set (&D, 1); - -top: - /* 4. while u is even do */ - while (mp_iseven (&u) == MP_YES) { - /* 4.1 u = u/2 */ - if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { - goto LBL_ERR; - } - /* 4.2 if A or B is odd then */ - if ((mp_isodd (&A) == MP_YES) || (mp_isodd (&B) == MP_YES)) { - /* A = (A+y)/2, B = (B-x)/2 */ - if ((res = mp_add (&A, &y, &A)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* A = A/2, B = B/2 */ - if ((res = mp_div_2 (&A, &A)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 5. while v is even do */ - while (mp_iseven (&v) == MP_YES) { - /* 5.1 v = v/2 */ - if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { - goto LBL_ERR; - } - /* 5.2 if C or D is odd then */ - if ((mp_isodd (&C) == MP_YES) || (mp_isodd (&D) == MP_YES)) { - /* C = (C+y)/2, D = (D-x)/2 */ - if ((res = mp_add (&C, &y, &C)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* C = C/2, D = D/2 */ - if ((res = mp_div_2 (&C, &C)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 6. if u >= v then */ - if (mp_cmp (&u, &v) != MP_LT) { - /* u = u - v, A = A - C, B = B - D */ - if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } else { - /* v - v - u, C = C - A, D = D - B */ - if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* if not zero goto step 4 */ - if (mp_iszero (&u) == MP_NO) - goto top; - - /* now a = C, b = D, gcd == g*v */ - - /* if v != 1 then there is no inverse */ - if (mp_cmp_d (&v, 1) != MP_EQ) { - res = MP_VAL; - goto LBL_ERR; - } - - /* if its too low */ - while (mp_cmp_d(&C, 0) == MP_LT) { - if ((res = mp_add(&C, b, &C)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* too big */ - while (mp_cmp_mag(&C, b) != MP_LT) { - if ((res = mp_sub(&C, b, &C)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* C is now the inverse */ - mp_exch (&C, c); - res = MP_OKAY; -LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL); - return res; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_is_square.c b/libtommath/bn_mp_is_square.c index dd08d58..69e77a2 100644 --- a/libtommath/bn_mp_is_square.c +++ b/libtommath/bn_mp_is_square.c @@ -1,109 +1,93 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_IS_SQUARE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* Check if remainders are possible squares - fast exclude non-squares */ static const char rem_128[128] = { - 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 + 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 }; static const char rem_105[105] = { - 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 + 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 }; /* Store non-zero to ret if arg is square, and zero if not */ -int mp_is_square(mp_int *arg,int *ret) +mp_err mp_is_square(const mp_int *arg, mp_bool *ret) { - int res; - mp_digit c; - mp_int t; - unsigned long r; + mp_err err; + mp_digit c; + mp_int t; + unsigned long r; - /* Default to Non-square :) */ - *ret = MP_NO; + /* Default to Non-square :) */ + *ret = MP_NO; - if (arg->sign == MP_NEG) { - return MP_VAL; - } + if (arg->sign == MP_NEG) { + return MP_VAL; + } - /* digits used? (TSD) */ - if (arg->used == 0) { - return MP_OKAY; - } + if (MP_IS_ZERO(arg)) { + return MP_OKAY; + } - /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */ - if (rem_128[127 & DIGIT(arg,0)] == 1) { - return MP_OKAY; - } + /* First check mod 128 (suppose that MP_DIGIT_BIT is at least 7) */ + if (rem_128[127u & arg->dp[0]] == (char)1) { + return MP_OKAY; + } - /* Next check mod 105 (3*5*7) */ - if ((res = mp_mod_d(arg,105,&c)) != MP_OKAY) { - return res; - } - if (rem_105[c] == 1) { - return MP_OKAY; - } + /* Next check mod 105 (3*5*7) */ + if ((err = mp_mod_d(arg, 105uL, &c)) != MP_OKAY) { + return err; + } + if (rem_105[c] == (char)1) { + return MP_OKAY; + } - if ((res = mp_init_set_int(&t,11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) { - return res; - } - if ((res = mp_mod(arg,&t,&t)) != MP_OKAY) { - goto ERR; - } - r = mp_get_int(&t); - /* Check for other prime modules, note it's not an ERROR but we must - * free "t" so the easiest way is to goto ERR. We know that res - * is already equal to MP_OKAY from the mp_mod call - */ - if (((1L<<(r%11)) & 0x5C4L) != 0L) goto ERR; - if (((1L<<(r%13)) & 0x9E4L) != 0L) goto ERR; - if (((1L<<(r%17)) & 0x5CE8L) != 0L) goto ERR; - if (((1L<<(r%19)) & 0x4F50CL) != 0L) goto ERR; - if (((1L<<(r%23)) & 0x7ACCA0L) != 0L) goto ERR; - if (((1L<<(r%29)) & 0xC2EDD0CL) != 0L) goto ERR; - if (((1L<<(r%31)) & 0x6DE2B848L) != 0L) goto ERR; + if ((err = mp_init_u32(&t, 11u*13u*17u*19u*23u*29u*31u)) != MP_OKAY) { + return err; + } + if ((err = mp_mod(arg, &t, &t)) != MP_OKAY) { + goto LBL_ERR; + } + r = mp_get_u32(&t); + /* Check for other prime modules, note it's not an ERROR but we must + * free "t" so the easiest way is to goto LBL_ERR. We know that err + * is already equal to MP_OKAY from the mp_mod call + */ + if (((1uL<<(r%11uL)) & 0x5C4uL) != 0uL) goto LBL_ERR; + if (((1uL<<(r%13uL)) & 0x9E4uL) != 0uL) goto LBL_ERR; + if (((1uL<<(r%17uL)) & 0x5CE8uL) != 0uL) goto LBL_ERR; + if (((1uL<<(r%19uL)) & 0x4F50CuL) != 0uL) goto LBL_ERR; + if (((1uL<<(r%23uL)) & 0x7ACCA0uL) != 0uL) goto LBL_ERR; + if (((1uL<<(r%29uL)) & 0xC2EDD0CuL) != 0uL) goto LBL_ERR; + if (((1uL<<(r%31uL)) & 0x6DE2B848uL) != 0uL) goto LBL_ERR; - /* Final check - is sqr(sqrt(arg)) == arg ? */ - if ((res = mp_sqrt(arg,&t)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sqr(&t,&t)) != MP_OKAY) { - goto ERR; - } + /* Final check - is sqr(sqrt(arg)) == arg ? */ + if ((err = mp_sqrt(arg, &t)) != MP_OKAY) { + goto LBL_ERR; + } + if ((err = mp_sqr(&t, &t)) != MP_OKAY) { + goto LBL_ERR; + } - *ret = (mp_cmp_mag(&t,arg) == MP_EQ) ? MP_YES : MP_NO; -ERR:mp_clear(&t); - return res; + *ret = (mp_cmp_mag(&t, arg) == MP_EQ) ? MP_YES : MP_NO; +LBL_ERR: + mp_clear(&t); + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_iseven.c b/libtommath/bn_mp_iseven.c new file mode 100644 index 0000000..5cb9622 --- /dev/null +++ b/libtommath/bn_mp_iseven.c @@ -0,0 +1,10 @@ +#include "tommath_private.h" +#ifdef BN_MP_ISEVEN_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +mp_bool mp_iseven(const mp_int *a) +{ + return MP_IS_EVEN(a) ? MP_YES : MP_NO; +} +#endif diff --git a/libtommath/bn_mp_isodd.c b/libtommath/bn_mp_isodd.c new file mode 100644 index 0000000..bf17646 --- /dev/null +++ b/libtommath/bn_mp_isodd.c @@ -0,0 +1,10 @@ +#include "tommath_private.h" +#ifdef BN_MP_ISODD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +mp_bool mp_isodd(const mp_int *a) +{ + return MP_IS_ODD(a) ? MP_YES : MP_NO; +} +#endif diff --git a/libtommath/bn_mp_jacobi.c b/libtommath/bn_mp_jacobi.c deleted file mode 100644 index 5fc8593..0000000 --- a/libtommath/bn_mp_jacobi.c +++ /dev/null @@ -1,117 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_JACOBI_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* computes the jacobi c = (a | n) (or Legendre if n is prime) - * HAC pp. 73 Algorithm 2.149 - * HAC is wrong here, as the special case of (0 | 1) is not - * handled correctly. - */ -int mp_jacobi (mp_int * a, mp_int * n, int *c) -{ - mp_int a1, p1; - int k, s, r, res; - mp_digit residue; - - /* if a < 0 return MP_VAL */ - if (mp_isneg(a) == MP_YES) { - return MP_VAL; - } - - /* if n <= 0 return MP_VAL */ - if (mp_cmp_d(n, 0) != MP_GT) { - return MP_VAL; - } - - /* step 1. handle case of a == 0 */ - if (mp_iszero (a) == MP_YES) { - /* special case of a == 0 and n == 1 */ - if (mp_cmp_d (n, 1) == MP_EQ) { - *c = 1; - } else { - *c = 0; - } - return MP_OKAY; - } - - /* step 2. if a == 1, return 1 */ - if (mp_cmp_d (a, 1) == MP_EQ) { - *c = 1; - return MP_OKAY; - } - - /* default */ - s = 0; - - /* step 3. write a = a1 * 2**k */ - if ((res = mp_init_copy (&a1, a)) != MP_OKAY) { - return res; - } - - if ((res = mp_init (&p1)) != MP_OKAY) { - goto LBL_A1; - } - - /* divide out larger power of two */ - k = mp_cnt_lsb(&a1); - if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) { - goto LBL_P1; - } - - /* step 4. if e is even set s=1 */ - if ((k & 1) == 0) { - s = 1; - } else { - /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */ - residue = n->dp[0] & 7; - - if ((residue == 1) || (residue == 7)) { - s = 1; - } else if ((residue == 3) || (residue == 5)) { - s = -1; - } - } - - /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */ - if ( ((n->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) { - s = -s; - } - - /* if a1 == 1 we're done */ - if (mp_cmp_d (&a1, 1) == MP_EQ) { - *c = s; - } else { - /* n1 = n mod a1 */ - if ((res = mp_mod (n, &a1, &p1)) != MP_OKAY) { - goto LBL_P1; - } - if ((res = mp_jacobi (&p1, &a1, &r)) != MP_OKAY) { - goto LBL_P1; - } - *c = s * r; - } - - /* done */ - res = MP_OKAY; -LBL_P1:mp_clear (&p1); -LBL_A1:mp_clear (&a1); - return res; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_karatsuba_mul.c b/libtommath/bn_mp_karatsuba_mul.c deleted file mode 100644 index 4d982c7..0000000 --- a/libtommath/bn_mp_karatsuba_mul.c +++ /dev/null @@ -1,167 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_KARATSUBA_MUL_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* c = |a| * |b| using Karatsuba Multiplication using - * three half size multiplications - * - * Let B represent the radix [e.g. 2**DIGIT_BIT] and - * let n represent half of the number of digits in - * the min(a,b) - * - * a = a1 * B**n + a0 - * b = b1 * B**n + b0 - * - * Then, a * b => - a1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0 - * - * Note that a1b1 and a0b0 are used twice and only need to be - * computed once. So in total three half size (half # of - * digit) multiplications are performed, a0b0, a1b1 and - * (a1+b1)(a0+b0) - * - * Note that a multiplication of half the digits requires - * 1/4th the number of single precision multiplications so in - * total after one call 25% of the single precision multiplications - * are saved. Note also that the call to mp_mul can end up back - * in this function if the a0, a1, b0, or b1 are above the threshold. - * This is known as divide-and-conquer and leads to the famous - * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than - * the standard O(N**2) that the baseline/comba methods use. - * Generally though the overhead of this method doesn't pay off - * until a certain size (N ~ 80) is reached. - */ -int mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int x0, x1, y0, y1, t1, x0y0, x1y1; - int B, err; - - /* default the return code to an error */ - err = MP_MEM; - - /* min # of digits */ - B = MIN (a->used, b->used); - - /* now divide in two */ - B = B >> 1; - - /* init copy all the temps */ - if (mp_init_size (&x0, B) != MP_OKAY) - goto ERR; - if (mp_init_size (&x1, a->used - B) != MP_OKAY) - goto X0; - if (mp_init_size (&y0, B) != MP_OKAY) - goto X1; - if (mp_init_size (&y1, b->used - B) != MP_OKAY) - goto Y0; - - /* init temps */ - if (mp_init_size (&t1, B * 2) != MP_OKAY) - goto Y1; - if (mp_init_size (&x0y0, B * 2) != MP_OKAY) - goto T1; - if (mp_init_size (&x1y1, B * 2) != MP_OKAY) - goto X0Y0; - - /* now shift the digits */ - x0.used = y0.used = B; - x1.used = a->used - B; - y1.used = b->used - B; - - { - int x; - mp_digit *tmpa, *tmpb, *tmpx, *tmpy; - - /* we copy the digits directly instead of using higher level functions - * since we also need to shift the digits - */ - tmpa = a->dp; - tmpb = b->dp; - - tmpx = x0.dp; - tmpy = y0.dp; - for (x = 0; x < B; x++) { - *tmpx++ = *tmpa++; - *tmpy++ = *tmpb++; - } - - tmpx = x1.dp; - for (x = B; x < a->used; x++) { - *tmpx++ = *tmpa++; - } - - tmpy = y1.dp; - for (x = B; x < b->used; x++) { - *tmpy++ = *tmpb++; - } - } - - /* only need to clamp the lower words since by definition the - * upper words x1/y1 must have a known number of digits - */ - mp_clamp (&x0); - mp_clamp (&y0); - - /* now calc the products x0y0 and x1y1 */ - /* after this x0 is no longer required, free temp [x0==t2]! */ - if (mp_mul (&x0, &y0, &x0y0) != MP_OKAY) - goto X1Y1; /* x0y0 = x0*y0 */ - if (mp_mul (&x1, &y1, &x1y1) != MP_OKAY) - goto X1Y1; /* x1y1 = x1*y1 */ - - /* now calc x1+x0 and y1+y0 */ - if (s_mp_add (&x1, &x0, &t1) != MP_OKAY) - goto X1Y1; /* t1 = x1 - x0 */ - if (s_mp_add (&y1, &y0, &x0) != MP_OKAY) - goto X1Y1; /* t2 = y1 - y0 */ - if (mp_mul (&t1, &x0, &t1) != MP_OKAY) - goto X1Y1; /* t1 = (x1 + x0) * (y1 + y0) */ - - /* add x0y0 */ - if (mp_add (&x0y0, &x1y1, &x0) != MP_OKAY) - goto X1Y1; /* t2 = x0y0 + x1y1 */ - if (s_mp_sub (&t1, &x0, &t1) != MP_OKAY) - goto X1Y1; /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */ - - /* shift by B */ - if (mp_lshd (&t1, B) != MP_OKAY) - goto X1Y1; /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))<<B */ - if (mp_lshd (&x1y1, B * 2) != MP_OKAY) - goto X1Y1; /* x1y1 = x1y1 << 2*B */ - - if (mp_add (&x0y0, &t1, &t1) != MP_OKAY) - goto X1Y1; /* t1 = x0y0 + t1 */ - if (mp_add (&t1, &x1y1, c) != MP_OKAY) - goto X1Y1; /* t1 = x0y0 + t1 + x1y1 */ - - /* Algorithm succeeded set the return code to MP_OKAY */ - err = MP_OKAY; - -X1Y1:mp_clear (&x1y1); -X0Y0:mp_clear (&x0y0); -T1:mp_clear (&t1); -Y1:mp_clear (&y1); -Y0:mp_clear (&y0); -X1:mp_clear (&x1); -X0:mp_clear (&x0); -ERR: - return err; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_karatsuba_sqr.c b/libtommath/bn_mp_karatsuba_sqr.c deleted file mode 100644 index 764e85a..0000000 --- a/libtommath/bn_mp_karatsuba_sqr.c +++ /dev/null @@ -1,121 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_KARATSUBA_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* Karatsuba squaring, computes b = a*a using three - * half size squarings - * - * See comments of karatsuba_mul for details. It - * is essentially the same algorithm but merely - * tuned to perform recursive squarings. - */ -int mp_karatsuba_sqr (mp_int * a, mp_int * b) -{ - mp_int x0, x1, t1, t2, x0x0, x1x1; - int B, err; - - err = MP_MEM; - - /* min # of digits */ - B = a->used; - - /* now divide in two */ - B = B >> 1; - - /* init copy all the temps */ - if (mp_init_size (&x0, B) != MP_OKAY) - goto ERR; - if (mp_init_size (&x1, a->used - B) != MP_OKAY) - goto X0; - - /* init temps */ - if (mp_init_size (&t1, a->used * 2) != MP_OKAY) - goto X1; - if (mp_init_size (&t2, a->used * 2) != MP_OKAY) - goto T1; - if (mp_init_size (&x0x0, B * 2) != MP_OKAY) - goto T2; - if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY) - goto X0X0; - - { - int x; - mp_digit *dst, *src; - - src = a->dp; - - /* now shift the digits */ - dst = x0.dp; - for (x = 0; x < B; x++) { - *dst++ = *src++; - } - - dst = x1.dp; - for (x = B; x < a->used; x++) { - *dst++ = *src++; - } - } - - x0.used = B; - x1.used = a->used - B; - - mp_clamp (&x0); - - /* now calc the products x0*x0 and x1*x1 */ - if (mp_sqr (&x0, &x0x0) != MP_OKAY) - goto X1X1; /* x0x0 = x0*x0 */ - if (mp_sqr (&x1, &x1x1) != MP_OKAY) - goto X1X1; /* x1x1 = x1*x1 */ - - /* now calc (x1+x0)**2 */ - if (s_mp_add (&x1, &x0, &t1) != MP_OKAY) - goto X1X1; /* t1 = x1 - x0 */ - if (mp_sqr (&t1, &t1) != MP_OKAY) - goto X1X1; /* t1 = (x1 - x0) * (x1 - x0) */ - - /* add x0y0 */ - if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY) - goto X1X1; /* t2 = x0x0 + x1x1 */ - if (s_mp_sub (&t1, &t2, &t1) != MP_OKAY) - goto X1X1; /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */ - - /* shift by B */ - if (mp_lshd (&t1, B) != MP_OKAY) - goto X1X1; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))<<B */ - if (mp_lshd (&x1x1, B * 2) != MP_OKAY) - goto X1X1; /* x1x1 = x1x1 << 2*B */ - - if (mp_add (&x0x0, &t1, &t1) != MP_OKAY) - goto X1X1; /* t1 = x0x0 + t1 */ - if (mp_add (&t1, &x1x1, b) != MP_OKAY) - goto X1X1; /* t1 = x0x0 + t1 + x1x1 */ - - err = MP_OKAY; - -X1X1:mp_clear (&x1x1); -X0X0:mp_clear (&x0x0); -T2:mp_clear (&t2); -T1:mp_clear (&t1); -X1:mp_clear (&x1); -X0:mp_clear (&x0); -ERR: - return err; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_kronecker.c b/libtommath/bn_mp_kronecker.c new file mode 100644 index 0000000..525a820 --- /dev/null +++ b/libtommath/bn_mp_kronecker.c @@ -0,0 +1,129 @@ +#include "tommath_private.h" +#ifdef BN_MP_KRONECKER_C + +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* + Kronecker symbol (a|p) + Straightforward implementation of algorithm 1.4.10 in + Henri Cohen: "A Course in Computational Algebraic Number Theory" + + @book{cohen2013course, + title={A course in computational algebraic number theory}, + author={Cohen, Henri}, + volume={138}, + year={2013}, + publisher={Springer Science \& Business Media} + } + */ +mp_err mp_kronecker(const mp_int *a, const mp_int *p, int *c) +{ + mp_int a1, p1, r; + mp_err err; + int v, k; + + static const int table[8] = {0, 1, 0, -1, 0, -1, 0, 1}; + + if (MP_IS_ZERO(p)) { + if ((a->used == 1) && (a->dp[0] == 1u)) { + *c = 1; + } else { + *c = 0; + } + return MP_OKAY; + } + + if (MP_IS_EVEN(a) && MP_IS_EVEN(p)) { + *c = 0; + return MP_OKAY; + } + + if ((err = mp_init_copy(&a1, a)) != MP_OKAY) { + return err; + } + if ((err = mp_init_copy(&p1, p)) != MP_OKAY) { + goto LBL_KRON_0; + } + + v = mp_cnt_lsb(&p1); + if ((err = mp_div_2d(&p1, v, &p1, NULL)) != MP_OKAY) { + goto LBL_KRON_1; + } + + if ((v & 1) == 0) { + k = 1; + } else { + k = table[a->dp[0] & 7u]; + } + + if (p1.sign == MP_NEG) { + p1.sign = MP_ZPOS; + if (a1.sign == MP_NEG) { + k = -k; + } + } + + if ((err = mp_init(&r)) != MP_OKAY) { + goto LBL_KRON_1; + } + + for (;;) { + if (MP_IS_ZERO(&a1)) { + if (mp_cmp_d(&p1, 1uL) == MP_EQ) { + *c = k; + goto LBL_KRON; + } else { + *c = 0; + goto LBL_KRON; + } + } + + v = mp_cnt_lsb(&a1); + if ((err = mp_div_2d(&a1, v, &a1, NULL)) != MP_OKAY) { + goto LBL_KRON; + } + + if ((v & 1) == 1) { + k = k * table[p1.dp[0] & 7u]; + } + + if (a1.sign == MP_NEG) { + /* + * Compute k = (-1)^((a1)*(p1-1)/4) * k + * a1.dp[0] + 1 cannot overflow because the MSB + * of the type mp_digit is not set by definition + */ + if (((a1.dp[0] + 1u) & p1.dp[0] & 2u) != 0u) { + k = -k; + } + } else { + /* compute k = (-1)^((a1-1)*(p1-1)/4) * k */ + if ((a1.dp[0] & p1.dp[0] & 2u) != 0u) { + k = -k; + } + } + + if ((err = mp_copy(&a1, &r)) != MP_OKAY) { + goto LBL_KRON; + } + r.sign = MP_ZPOS; + if ((err = mp_mod(&p1, &r, &a1)) != MP_OKAY) { + goto LBL_KRON; + } + if ((err = mp_copy(&r, &p1)) != MP_OKAY) { + goto LBL_KRON; + } + } + +LBL_KRON: + mp_clear(&r); +LBL_KRON_1: + mp_clear(&p1); +LBL_KRON_0: + mp_clear(&a1); + + return err; +} + +#endif diff --git a/libtommath/bn_mp_lcm.c b/libtommath/bn_mp_lcm.c index 512e8ec..c32b269 100644 --- a/libtommath/bn_mp_lcm.c +++ b/libtommath/bn_mp_lcm.c @@ -1,60 +1,44 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_LCM_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* computes least common multiple as |a*b|/(a, b) */ -int mp_lcm (mp_int * a, mp_int * b, mp_int * c) +mp_err mp_lcm(const mp_int *a, const mp_int *b, mp_int *c) { - int res; - mp_int t1, t2; - - - if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) { - return res; - } - - /* t1 = get the GCD of the two inputs */ - if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) { - goto LBL_T; - } - - /* divide the smallest by the GCD */ - if (mp_cmp_mag(a, b) == MP_LT) { - /* store quotient in t2 such that t2 * b is the LCM */ - if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) { - goto LBL_T; - } - res = mp_mul(b, &t2, c); - } else { - /* store quotient in t2 such that t2 * a is the LCM */ - if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) { - goto LBL_T; - } - res = mp_mul(a, &t2, c); - } - - /* fix the sign to positive */ - c->sign = MP_ZPOS; + mp_err err; + mp_int t1, t2; + + + if ((err = mp_init_multi(&t1, &t2, NULL)) != MP_OKAY) { + return err; + } + + /* t1 = get the GCD of the two inputs */ + if ((err = mp_gcd(a, b, &t1)) != MP_OKAY) { + goto LBL_T; + } + + /* divide the smallest by the GCD */ + if (mp_cmp_mag(a, b) == MP_LT) { + /* store quotient in t2 such that t2 * b is the LCM */ + if ((err = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) { + goto LBL_T; + } + err = mp_mul(b, &t2, c); + } else { + /* store quotient in t2 such that t2 * a is the LCM */ + if ((err = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) { + goto LBL_T; + } + err = mp_mul(a, &t2, c); + } + + /* fix the sign to positive */ + c->sign = MP_ZPOS; LBL_T: - mp_clear_multi (&t1, &t2, NULL); - return res; + mp_clear_multi(&t1, &t2, NULL); + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_log_u32.c b/libtommath/bn_mp_log_u32.c new file mode 100644 index 0000000..f7bca01 --- /dev/null +++ b/libtommath/bn_mp_log_u32.c @@ -0,0 +1,180 @@ +#include "tommath_private.h" +#ifdef BN_MP_LOG_U32_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* Compute log_{base}(a) */ +static mp_word s_pow(mp_word base, mp_word exponent) +{ + mp_word result = 1uLL; + while (exponent != 0u) { + if ((exponent & 1u) == 1u) { + result *= base; + } + exponent >>= 1; + base *= base; + } + + return result; +} + +static mp_digit s_digit_ilogb(mp_digit base, mp_digit n) +{ + mp_word bracket_low = 1uLL, bracket_mid, bracket_high, N; + mp_digit ret, high = 1uL, low = 0uL, mid; + + if (n < base) { + return 0uL; + } + if (n == base) { + return 1uL; + } + + bracket_high = (mp_word) base ; + N = (mp_word) n; + + while (bracket_high < N) { + low = high; + bracket_low = bracket_high; + high <<= 1; + bracket_high *= bracket_high; + } + + while (((mp_digit)(high - low)) > 1uL) { + mid = (low + high) >> 1; + bracket_mid = bracket_low * s_pow(base, (mp_word)(mid - low)); + + if (N < bracket_mid) { + high = mid ; + bracket_high = bracket_mid ; + } + if (N > bracket_mid) { + low = mid ; + bracket_low = bracket_mid ; + } + if (N == bracket_mid) { + return (mp_digit) mid; + } + } + + if (bracket_high == N) { + ret = high; + } else { + ret = low; + } + + return ret; +} + +/* TODO: output could be "int" because the output of mp_radix_size is int, too, + as is the output of mp_bitcount. + With the same problem: max size is INT_MAX * MP_DIGIT not INT_MAX only! +*/ +mp_err mp_log_u32(const mp_int *a, uint32_t base, uint32_t *c) +{ + mp_err err; + mp_ord cmp; + uint32_t high, low, mid; + mp_int bracket_low, bracket_high, bracket_mid, t, bi_base; + + err = MP_OKAY; + + if (a->sign == MP_NEG) { + return MP_VAL; + } + + if (MP_IS_ZERO(a)) { + return MP_VAL; + } + + if (base < 2u) { + return MP_VAL; + } + + /* A small shortcut for bases that are powers of two. */ + if ((base & (base - 1u)) == 0u) { + int y, bit_count; + for (y=0; (y < 7) && ((base & 1u) == 0u); y++) { + base >>= 1; + } + bit_count = mp_count_bits(a) - 1; + *c = (uint32_t)(bit_count/y); + return MP_OKAY; + } + + if (a->used == 1) { + *c = (uint32_t)s_digit_ilogb(base, a->dp[0]); + return err; + } + + cmp = mp_cmp_d(a, base); + if ((cmp == MP_LT) || (cmp == MP_EQ)) { + *c = cmp == MP_EQ; + return err; + } + + if ((err = + mp_init_multi(&bracket_low, &bracket_high, + &bracket_mid, &t, &bi_base, NULL)) != MP_OKAY) { + return err; + } + + low = 0u; + mp_set(&bracket_low, 1uL); + high = 1u; + + mp_set(&bracket_high, base); + + /* + A kind of Giant-step/baby-step algorithm. + Idea shamelessly stolen from https://programmingpraxis.com/2010/05/07/integer-logarithms/2/ + The effect is asymptotic, hence needs benchmarks to test if the Giant-step should be skipped + for small n. + */ + while (mp_cmp(&bracket_high, a) == MP_LT) { + low = high; + if ((err = mp_copy(&bracket_high, &bracket_low)) != MP_OKAY) { + goto LBL_ERR; + } + high <<= 1; + if ((err = mp_sqr(&bracket_high, &bracket_high)) != MP_OKAY) { + goto LBL_ERR; + } + } + mp_set(&bi_base, base); + + while ((high - low) > 1u) { + mid = (high + low) >> 1; + + if ((err = mp_expt_u32(&bi_base, (uint32_t)(mid - low), &t)) != MP_OKAY) { + goto LBL_ERR; + } + if ((err = mp_mul(&bracket_low, &t, &bracket_mid)) != MP_OKAY) { + goto LBL_ERR; + } + cmp = mp_cmp(a, &bracket_mid); + if (cmp == MP_LT) { + high = mid; + mp_exch(&bracket_mid, &bracket_high); + } + if (cmp == MP_GT) { + low = mid; + mp_exch(&bracket_mid, &bracket_low); + } + if (cmp == MP_EQ) { + *c = mid; + goto LBL_END; + } + } + + *c = (mp_cmp(&bracket_high, a) == MP_EQ) ? high : low; + +LBL_END: +LBL_ERR: + mp_clear_multi(&bracket_low, &bracket_high, &bracket_mid, + &t, &bi_base, NULL); + return err; +} + + +#endif diff --git a/libtommath/bn_mp_lshd.c b/libtommath/bn_mp_lshd.c index 0143e94..8234580 100644 --- a/libtommath/bn_mp_lshd.c +++ b/libtommath/bn_mp_lshd.c @@ -1,67 +1,51 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_LSHD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* shift left a certain amount of digits */ -int mp_lshd (mp_int * a, int b) +mp_err mp_lshd(mp_int *a, int b) { - int x, res; - - /* if its less than zero return */ - if (b <= 0) { - return MP_OKAY; - } - - /* grow to fit the new digits */ - if (a->alloc < (a->used + b)) { - if ((res = mp_grow (a, a->used + b)) != MP_OKAY) { - return res; - } - } - - { - mp_digit *top, *bottom; - - /* increment the used by the shift amount then copy upwards */ - a->used += b; - - /* top */ - top = a->dp + a->used - 1; - - /* base */ - bottom = (a->dp + a->used - 1) - b; - - /* much like mp_rshd this is implemented using a sliding window - * except the window goes the otherway around. Copying from - * the bottom to the top. see bn_mp_rshd.c for more info. - */ - for (x = a->used - 1; x >= b; x--) { + int x; + mp_err err; + mp_digit *top, *bottom; + + /* if its less than zero return */ + if (b <= 0) { + return MP_OKAY; + } + /* no need to shift 0 around */ + if (MP_IS_ZERO(a)) { + return MP_OKAY; + } + + /* grow to fit the new digits */ + if (a->alloc < (a->used + b)) { + if ((err = mp_grow(a, a->used + b)) != MP_OKAY) { + return err; + } + } + + /* increment the used by the shift amount then copy upwards */ + a->used += b; + + /* top */ + top = a->dp + a->used - 1; + + /* base */ + bottom = (a->dp + a->used - 1) - b; + + /* much like mp_rshd this is implemented using a sliding window + * except the window goes the otherway around. Copying from + * the bottom to the top. see bn_mp_rshd.c for more info. + */ + for (x = a->used - 1; x >= b; x--) { *top-- = *bottom--; - } + } - /* zero the lower digits */ - top = a->dp; - for (x = 0; x < b; x++) { - *top++ = 0; - } - } - return MP_OKAY; + /* zero the lower digits */ + MP_ZERO_DIGITS(a->dp, b); + + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_mod.c b/libtommath/bn_mp_mod.c index 06240a0..8fbfe08 100644 --- a/libtommath/bn_mp_mod.c +++ b/libtommath/bn_mp_mod.c @@ -1,48 +1,31 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_MOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* c = a mod b, 0 <= c < b if b > 0, b < c <= 0 if b < 0 */ -int -mp_mod (mp_int * a, mp_int * b, mp_int * c) +mp_err mp_mod(const mp_int *a, const mp_int *b, mp_int *c) { - mp_int t; - int res; + mp_int t; + mp_err err; - if ((res = mp_init_size (&t, b->used)) != MP_OKAY) { - return res; - } + if ((err = mp_init_size(&t, b->used)) != MP_OKAY) { + return err; + } - if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } + if ((err = mp_div(a, b, NULL, &t)) != MP_OKAY) { + goto LBL_ERR; + } - if ((mp_iszero(&t) != MP_NO) || (t.sign == b->sign)) { - res = MP_OKAY; - mp_exch (&t, c); - } else { - res = mp_add (b, &t, c); - } + if (MP_IS_ZERO(&t) || (t.sign == b->sign)) { + err = MP_OKAY; + mp_exch(&t, c); + } else { + err = mp_add(b, &t, c); + } - mp_clear (&t); - return res; +LBL_ERR: + mp_clear(&t); + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_mod_2d.c b/libtommath/bn_mp_mod_2d.c index 2bb86da..5bf57a1 100644 --- a/libtommath/bn_mp_mod_2d.c +++ b/libtommath/bn_mp_mod_2d.c @@ -1,55 +1,38 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_MOD_2D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* calc a value mod 2**b */ -int -mp_mod_2d (mp_int * a, int b, mp_int * c) +mp_err mp_mod_2d(const mp_int *a, int b, mp_int *c) { - int x, res; + int x; + mp_err err; - /* if b is <= 0 then zero the int */ - if (b <= 0) { - mp_zero (c); - return MP_OKAY; - } + /* if b is <= 0 then zero the int */ + if (b <= 0) { + mp_zero(c); + return MP_OKAY; + } - /* if the modulus is larger than the value than return */ - if (b >= (int) (a->used * DIGIT_BIT)) { - res = mp_copy (a, c); - return res; - } + /* if the modulus is larger than the value than return */ + if (b >= (a->used * MP_DIGIT_BIT)) { + return mp_copy(a, c); + } - /* copy */ - if ((res = mp_copy (a, c)) != MP_OKAY) { - return res; - } + /* copy */ + if ((err = mp_copy(a, c)) != MP_OKAY) { + return err; + } - /* zero digits above the last digit of the modulus */ - for (x = (b / DIGIT_BIT) + (((b % DIGIT_BIT) == 0) ? 0 : 1); x < c->used; x++) { - c->dp[x] = 0; - } - /* clear the digit that is not completely outside/inside the modulus */ - c->dp[b / DIGIT_BIT] &= - (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1)); - mp_clamp (c); - return MP_OKAY; + /* zero digits above the last digit of the modulus */ + x = (b / MP_DIGIT_BIT) + (((b % MP_DIGIT_BIT) == 0) ? 0 : 1); + MP_ZERO_DIGITS(c->dp + x, c->used - x); + + /* clear the digit that is not completely outside/inside the modulus */ + c->dp[b / MP_DIGIT_BIT] &= + ((mp_digit)1 << (mp_digit)(b % MP_DIGIT_BIT)) - (mp_digit)1; + mp_clamp(c); + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_mod_d.c b/libtommath/bn_mp_mod_d.c index bf2ccaa..0b6c12a 100644 --- a/libtommath/bn_mp_mod_d.c +++ b/libtommath/bn_mp_mod_d.c @@ -1,27 +1,10 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_MOD_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ -int -mp_mod_d (mp_int * a, mp_digit b, mp_digit * c) +mp_err mp_mod_d(const mp_int *a, mp_digit b, mp_digit *c) { - return mp_div_d(a, b, NULL, c); + return mp_div_d(a, b, NULL, c); } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_montgomery_calc_normalization.c b/libtommath/bn_mp_montgomery_calc_normalization.c index 679a871..8379789 100644 --- a/libtommath/bn_mp_montgomery_calc_normalization.c +++ b/libtommath/bn_mp_montgomery_calc_normalization.c @@ -1,19 +1,7 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* * shifts with subtractions when the result is greater than b. @@ -21,39 +9,36 @@ * The method is slightly modified to shift B unconditionally upto just under * the leading bit of b. This saves alot of multiple precision shifting. */ -int mp_montgomery_calc_normalization (mp_int * a, mp_int * b) +mp_err mp_montgomery_calc_normalization(mp_int *a, const mp_int *b) { - int x, bits, res; + int x, bits; + mp_err err; - /* how many bits of last digit does b use */ - bits = mp_count_bits (b) % DIGIT_BIT; + /* how many bits of last digit does b use */ + bits = mp_count_bits(b) % MP_DIGIT_BIT; - if (b->used > 1) { - if ((res = mp_2expt (a, ((b->used - 1) * DIGIT_BIT) + bits - 1)) != MP_OKAY) { - return res; - } - } else { - mp_set(a, 1); - bits = 1; - } + if (b->used > 1) { + if ((err = mp_2expt(a, ((b->used - 1) * MP_DIGIT_BIT) + bits - 1)) != MP_OKAY) { + return err; + } + } else { + mp_set(a, 1uL); + bits = 1; + } - /* now compute C = A * B mod b */ - for (x = bits - 1; x < (int)DIGIT_BIT; x++) { - if ((res = mp_mul_2 (a, a)) != MP_OKAY) { - return res; - } - if (mp_cmp_mag (a, b) != MP_LT) { - if ((res = s_mp_sub (a, b, a)) != MP_OKAY) { - return res; + /* now compute C = A * B mod b */ + for (x = bits - 1; x < (int)MP_DIGIT_BIT; x++) { + if ((err = mp_mul_2(a, a)) != MP_OKAY) { + return err; } - } - } + if (mp_cmp_mag(a, b) != MP_LT) { + if ((err = s_mp_sub(a, b, a)) != MP_OKAY) { + return err; + } + } + } - return MP_OKAY; + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_montgomery_reduce.c b/libtommath/bn_mp_montgomery_reduce.c index 05e8bfa..ffe8341 100644 --- a/libtommath/bn_mp_montgomery_reduce.c +++ b/libtommath/bn_mp_montgomery_reduce.c @@ -1,118 +1,102 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_MONTGOMERY_REDUCE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* computes xR**-1 == x (mod N) via Montgomery Reduction */ -int -mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) +mp_err mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho) { - int ix, res, digs; - mp_digit mu; - - /* can the fast reduction [comba] method be used? - * - * Note that unlike in mul you're safely allowed *less* - * than the available columns [255 per default] since carries - * are fixed up in the inner loop. - */ - digs = (n->used * 2) + 1; - if ((digs < MP_WARRAY) && - (n->used < - (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) { - return fast_mp_montgomery_reduce (x, n, rho); - } - - /* grow the input as required */ - if (x->alloc < digs) { - if ((res = mp_grow (x, digs)) != MP_OKAY) { - return res; - } - } - x->used = digs; - - for (ix = 0; ix < n->used; ix++) { - /* mu = ai * rho mod b - * - * The value of rho must be precalculated via - * montgomery_setup() such that - * it equals -1/n0 mod b this allows the - * following inner loop to reduce the - * input one digit at a time - */ - mu = (mp_digit) (((mp_word)x->dp[ix] * (mp_word)rho) & MP_MASK); - - /* a = a + mu * m * b**i */ - { - int iy; - mp_digit *tmpn, *tmpx, u; - mp_word r; - - /* alias for digits of the modulus */ - tmpn = n->dp; - - /* alias for the digits of x [the input] */ - tmpx = x->dp + ix; - - /* set the carry to zero */ - u = 0; - - /* Multiply and add in place */ - for (iy = 0; iy < n->used; iy++) { - /* compute product and sum */ - r = ((mp_word)mu * (mp_word)*tmpn++) + - (mp_word) u + (mp_word) *tmpx; - - /* get carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - - /* fix digit */ - *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK)); + int ix, digs; + mp_err err; + mp_digit mu; + + /* can the fast reduction [comba] method be used? + * + * Note that unlike in mul you're safely allowed *less* + * than the available columns [255 per default] since carries + * are fixed up in the inner loop. + */ + digs = (n->used * 2) + 1; + if ((digs < MP_WARRAY) && + (x->used <= MP_WARRAY) && + (n->used < MP_MAXFAST)) { + return s_mp_montgomery_reduce_fast(x, n, rho); + } + + /* grow the input as required */ + if (x->alloc < digs) { + if ((err = mp_grow(x, digs)) != MP_OKAY) { + return err; } - /* At this point the ix'th digit of x should be zero */ + } + x->used = digs; + + for (ix = 0; ix < n->used; ix++) { + /* mu = ai * rho mod b + * + * The value of rho must be precalculated via + * montgomery_setup() such that + * it equals -1/n0 mod b this allows the + * following inner loop to reduce the + * input one digit at a time + */ + mu = (mp_digit)(((mp_word)x->dp[ix] * (mp_word)rho) & MP_MASK); + + /* a = a + mu * m * b**i */ + { + int iy; + mp_digit *tmpn, *tmpx, u; + mp_word r; + + /* alias for digits of the modulus */ + tmpn = n->dp; + + /* alias for the digits of x [the input] */ + tmpx = x->dp + ix; + + /* set the carry to zero */ + u = 0; + + /* Multiply and add in place */ + for (iy = 0; iy < n->used; iy++) { + /* compute product and sum */ + r = ((mp_word)mu * (mp_word)*tmpn++) + + (mp_word)u + (mp_word)*tmpx; + + /* get carry */ + u = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT); + + /* fix digit */ + *tmpx++ = (mp_digit)(r & (mp_word)MP_MASK); + } + /* At this point the ix'th digit of x should be zero */ + + + /* propagate carries upwards as required*/ + while (u != 0u) { + *tmpx += u; + u = *tmpx >> MP_DIGIT_BIT; + *tmpx++ &= MP_MASK; + } + } + } + /* at this point the n.used'th least + * significant digits of x are all zero + * which means we can shift x to the + * right by n.used digits and the + * residue is unchanged. + */ - /* propagate carries upwards as required*/ - while (u != 0) { - *tmpx += u; - u = *tmpx >> DIGIT_BIT; - *tmpx++ &= MP_MASK; - } - } - } - - /* at this point the n.used'th least - * significant digits of x are all zero - * which means we can shift x to the - * right by n.used digits and the - * residue is unchanged. - */ - - /* x = x/b**n.used */ - mp_clamp(x); - mp_rshd (x, n->used); - - /* if x >= n then x = x - n */ - if (mp_cmp_mag (x, n) != MP_LT) { - return s_mp_sub (x, n, x); - } - - return MP_OKAY; + /* x = x/b**n.used */ + mp_clamp(x); + mp_rshd(x, n->used); + + /* if x >= n then x = x - n */ + if (mp_cmp_mag(x, n) != MP_LT) { + return s_mp_sub(x, n, x); + } + + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_montgomery_setup.c b/libtommath/bn_mp_montgomery_setup.c index 1c17445..39f6e9d 100644 --- a/libtommath/bn_mp_montgomery_setup.c +++ b/libtommath/bn_mp_montgomery_setup.c @@ -1,59 +1,42 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_MONTGOMERY_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* setups the montgomery reduction stuff */ -int -mp_montgomery_setup (mp_int * n, mp_digit * rho) +mp_err mp_montgomery_setup(const mp_int *n, mp_digit *rho) { - mp_digit x, b; + mp_digit x, b; -/* fast inversion mod 2**k - * - * Based on the fact that - * - * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n) - * => 2*X*A - X*X*A*A = 1 - * => 2*(1) - (1) = 1 - */ - b = n->dp[0]; + /* fast inversion mod 2**k + * + * Based on the fact that + * + * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n) + * => 2*X*A - X*X*A*A = 1 + * => 2*(1) - (1) = 1 + */ + b = n->dp[0]; - if ((b & 1) == 0) { - return MP_VAL; - } + if ((b & 1u) == 0u) { + return MP_VAL; + } - x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ - x *= 2 - (b * x); /* here x*a==1 mod 2**8 */ + x = (((b + 2u) & 4u) << 1) + b; /* here x*a==1 mod 2**4 */ + x *= 2u - (b * x); /* here x*a==1 mod 2**8 */ #if !defined(MP_8BIT) - x *= 2 - (b * x); /* here x*a==1 mod 2**16 */ + x *= 2u - (b * x); /* here x*a==1 mod 2**16 */ #endif #if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT)) - x *= 2 - (b * x); /* here x*a==1 mod 2**32 */ + x *= 2u - (b * x); /* here x*a==1 mod 2**32 */ #endif #ifdef MP_64BIT - x *= 2 - (b * x); /* here x*a==1 mod 2**64 */ + x *= 2u - (b * x); /* here x*a==1 mod 2**64 */ #endif - /* rho = -1/m mod b */ - *rho = (mp_digit)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK; + /* rho = -1/m mod b */ + *rho = (mp_digit)(((mp_word)1 << (mp_word)MP_DIGIT_BIT) - x) & MP_MASK; - return MP_OKAY; + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_mul.c b/libtommath/bn_mp_mul.c index cc3b9c8..561913a 100644 --- a/libtommath/bn_mp_mul.c +++ b/libtommath/bn_mp_mul.c @@ -1,67 +1,52 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_MUL_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* high level multiplication (handles sign) */ -int mp_mul (mp_int * a, mp_int * b, mp_int * c) +mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int *c) { - int res, neg; - neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; + mp_err err; + int min_len = MP_MIN(a->used, b->used), + max_len = MP_MAX(a->used, b->used), + digs = a->used + b->used + 1; + mp_sign neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; - /* use Toom-Cook? */ -#ifdef BN_MP_TOOM_MUL_C - if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) { - res = mp_toom_mul(a, b, c); - } else -#endif -#ifdef BN_MP_KARATSUBA_MUL_C - /* use Karatsuba? */ - if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) { - res = mp_karatsuba_mul (a, b, c); - } else -#endif - { - /* can we use the fast multiplier? - * - * The fast multiplier can be used if the output will - * have less than MP_WARRAY digits and the number of - * digits won't affect carry propagation - */ - int digs = a->used + b->used + 1; - -#ifdef BN_FAST_S_MP_MUL_DIGS_C - if ((digs < MP_WARRAY) && - (MIN(a->used, b->used) <= - (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) { - res = fast_s_mp_mul_digs (a, b, c, digs); - } else -#endif - { -#ifdef BN_S_MP_MUL_DIGS_C - res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */ -#else - res = MP_VAL; -#endif - } - } - c->sign = (c->used > 0) ? neg : MP_ZPOS; - return res; + if (MP_HAS(S_MP_BALANCE_MUL) && + /* Check sizes. The smaller one needs to be larger than the Karatsuba cut-off. + * The bigger one needs to be at least about one MP_KARATSUBA_MUL_CUTOFF bigger + * to make some sense, but it depends on architecture, OS, position of the + * stars... so YMMV. + * Using it to cut the input into slices small enough for fast_s_mp_mul_digs + * was actually slower on the author's machine, but YMMV. + */ + (min_len >= MP_KARATSUBA_MUL_CUTOFF) && + ((max_len / 2) >= MP_KARATSUBA_MUL_CUTOFF) && + /* Not much effect was observed below a ratio of 1:2, but again: YMMV. */ + (max_len >= (2 * min_len))) { + err = s_mp_balance_mul(a,b,c); + } else if (MP_HAS(S_MP_TOOM_MUL) && + (min_len >= MP_TOOM_MUL_CUTOFF)) { + err = s_mp_toom_mul(a, b, c); + } else if (MP_HAS(S_MP_KARATSUBA_MUL) && + (min_len >= MP_KARATSUBA_MUL_CUTOFF)) { + err = s_mp_karatsuba_mul(a, b, c); + } else if (MP_HAS(S_MP_MUL_DIGS_FAST) && + /* can we use the fast multiplier? + * + * The fast multiplier can be used if the output will + * have less than MP_WARRAY digits and the number of + * digits won't affect carry propagation + */ + (digs < MP_WARRAY) && + (min_len <= MP_MAXFAST)) { + err = s_mp_mul_digs_fast(a, b, c, digs); + } else if (MP_HAS(S_MP_MUL_DIGS)) { + err = s_mp_mul_digs(a, b, c, digs); + } else { + err = MP_VAL; + } + c->sign = (c->used > 0) ? neg : MP_ZPOS; + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_mul_2.c b/libtommath/bn_mp_mul_2.c index d22fd89..bc0691a 100644 --- a/libtommath/bn_mp_mul_2.c +++ b/libtommath/bn_mp_mul_2.c @@ -1,82 +1,64 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_MUL_2_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* b = a*2 */ -int mp_mul_2(mp_int * a, mp_int * b) +mp_err mp_mul_2(const mp_int *a, mp_int *b) { - int x, res, oldused; + int x, oldused; + mp_err err; - /* grow to accomodate result */ - if (b->alloc < (a->used + 1)) { - if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) { - return res; - } - } + /* grow to accomodate result */ + if (b->alloc < (a->used + 1)) { + if ((err = mp_grow(b, a->used + 1)) != MP_OKAY) { + return err; + } + } - oldused = b->used; - b->used = a->used; + oldused = b->used; + b->used = a->used; - { - mp_digit r, rr, *tmpa, *tmpb; + { + mp_digit r, rr, *tmpa, *tmpb; - /* alias for source */ - tmpa = a->dp; - - /* alias for dest */ - tmpb = b->dp; + /* alias for source */ + tmpa = a->dp; - /* carry */ - r = 0; - for (x = 0; x < a->used; x++) { - - /* get what will be the *next* carry bit from the - * MSB of the current digit - */ - rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1)); - - /* now shift up this digit, add in the carry [from the previous] */ - *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK; - - /* copy the carry that would be from the source - * digit into the next iteration - */ - r = rr; - } + /* alias for dest */ + tmpb = b->dp; + + /* carry */ + r = 0; + for (x = 0; x < a->used; x++) { + + /* get what will be the *next* carry bit from the + * MSB of the current digit + */ + rr = *tmpa >> (mp_digit)(MP_DIGIT_BIT - 1); - /* new leading digit? */ - if (r != 0) { - /* add a MSB which is always 1 at this point */ - *tmpb = 1; - ++(b->used); - } + /* now shift up this digit, add in the carry [from the previous] */ + *tmpb++ = ((*tmpa++ << 1uL) | r) & MP_MASK; - /* now zero any excess digits on the destination - * that we didn't write to - */ - tmpb = b->dp + b->used; - for (x = b->used; x < oldused; x++) { - *tmpb++ = 0; - } - } - b->sign = a->sign; - return MP_OKAY; + /* copy the carry that would be from the source + * digit into the next iteration + */ + r = rr; + } + + /* new leading digit? */ + if (r != 0u) { + /* add a MSB which is always 1 at this point */ + *tmpb = 1; + ++(b->used); + } + + /* now zero any excess digits on the destination + * that we didn't write to + */ + MP_ZERO_DIGITS(b->dp + b->used, oldused - b->used); + } + b->sign = a->sign; + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_mul_2d.c b/libtommath/bn_mp_mul_2d.c index c00fd7e..87354de 100644 --- a/libtommath/bn_mp_mul_2d.c +++ b/libtommath/bn_mp_mul_2d.c @@ -1,85 +1,69 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_MUL_2D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* shift left by a certain bit count */ -int mp_mul_2d (mp_int * a, int b, mp_int * c) +mp_err mp_mul_2d(const mp_int *a, int b, mp_int *c) { - mp_digit d; - int res; + mp_digit d; + mp_err err; - /* copy */ - if (a != c) { - if ((res = mp_copy (a, c)) != MP_OKAY) { - return res; - } - } + /* copy */ + if (a != c) { + if ((err = mp_copy(a, c)) != MP_OKAY) { + return err; + } + } - if (c->alloc < (int)(c->used + (b / DIGIT_BIT) + 1)) { - if ((res = mp_grow (c, c->used + (b / DIGIT_BIT) + 1)) != MP_OKAY) { - return res; - } - } + if (c->alloc < (c->used + (b / MP_DIGIT_BIT) + 1)) { + if ((err = mp_grow(c, c->used + (b / MP_DIGIT_BIT) + 1)) != MP_OKAY) { + return err; + } + } - /* shift by as many digits in the bit count */ - if (b >= (int)DIGIT_BIT) { - if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) { - return res; - } - } + /* shift by as many digits in the bit count */ + if (b >= MP_DIGIT_BIT) { + if ((err = mp_lshd(c, b / MP_DIGIT_BIT)) != MP_OKAY) { + return err; + } + } - /* shift any bit count < DIGIT_BIT */ - d = (mp_digit) (b % DIGIT_BIT); - if (d != 0) { - mp_digit *tmpc, shift, mask, r, rr; - int x; + /* shift any bit count < MP_DIGIT_BIT */ + d = (mp_digit)(b % MP_DIGIT_BIT); + if (d != 0u) { + mp_digit *tmpc, shift, mask, r, rr; + int x; - /* bitmask for carries */ - mask = (((mp_digit)1) << d) - 1; + /* bitmask for carries */ + mask = ((mp_digit)1 << d) - (mp_digit)1; - /* shift for msbs */ - shift = DIGIT_BIT - d; + /* shift for msbs */ + shift = (mp_digit)MP_DIGIT_BIT - d; - /* alias */ - tmpc = c->dp; + /* alias */ + tmpc = c->dp; - /* carry */ - r = 0; - for (x = 0; x < c->used; x++) { - /* get the higher bits of the current word */ - rr = (*tmpc >> shift) & mask; + /* carry */ + r = 0; + for (x = 0; x < c->used; x++) { + /* get the higher bits of the current word */ + rr = (*tmpc >> shift) & mask; - /* shift the current word and OR in the carry */ - *tmpc = ((*tmpc << d) | r) & MP_MASK; - ++tmpc; + /* shift the current word and OR in the carry */ + *tmpc = ((*tmpc << d) | r) & MP_MASK; + ++tmpc; - /* set the carry to the carry bits of the current word */ - r = rr; - } - - /* set final carry */ - if (r != 0) { - c->dp[(c->used)++] = r; - } - } - mp_clamp (c); - return MP_OKAY; + /* set the carry to the carry bits of the current word */ + r = rr; + } + + /* set final carry */ + if (r != 0u) { + c->dp[(c->used)++] = r; + } + } + mp_clamp(c); + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_mul_d.c b/libtommath/bn_mp_mul_d.c index 6954ed3..b56dfa3 100644 --- a/libtommath/bn_mp_mul_d.c +++ b/libtommath/bn_mp_mul_d.c @@ -1,79 +1,61 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_MUL_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* multiply by a digit */ -int -mp_mul_d (mp_int * a, mp_digit b, mp_int * c) +mp_err mp_mul_d(const mp_int *a, mp_digit b, mp_int *c) { - mp_digit u, *tmpa, *tmpc; - mp_word r; - int ix, res, olduse; + mp_digit u, *tmpa, *tmpc; + mp_word r; + mp_err err; + int ix, olduse; - /* make sure c is big enough to hold a*b */ - if (c->alloc < (a->used + 1)) { - if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) { - return res; - } - } + /* make sure c is big enough to hold a*b */ + if (c->alloc < (a->used + 1)) { + if ((err = mp_grow(c, a->used + 1)) != MP_OKAY) { + return err; + } + } - /* get the original destinations used count */ - olduse = c->used; + /* get the original destinations used count */ + olduse = c->used; - /* set the sign */ - c->sign = a->sign; + /* set the sign */ + c->sign = a->sign; - /* alias for a->dp [source] */ - tmpa = a->dp; + /* alias for a->dp [source] */ + tmpa = a->dp; - /* alias for c->dp [dest] */ - tmpc = c->dp; + /* alias for c->dp [dest] */ + tmpc = c->dp; - /* zero carry */ - u = 0; + /* zero carry */ + u = 0; - /* compute columns */ - for (ix = 0; ix < a->used; ix++) { - /* compute product and carry sum for this term */ - r = (mp_word)u + ((mp_word)*tmpa++ * (mp_word)b); + /* compute columns */ + for (ix = 0; ix < a->used; ix++) { + /* compute product and carry sum for this term */ + r = (mp_word)u + ((mp_word)*tmpa++ * (mp_word)b); - /* mask off higher bits to get a single digit */ - *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK)); + /* mask off higher bits to get a single digit */ + *tmpc++ = (mp_digit)(r & (mp_word)MP_MASK); - /* send carry into next iteration */ - u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); - } + /* send carry into next iteration */ + u = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT); + } - /* store final carry [if any] and increment ix offset */ - *tmpc++ = u; - ++ix; + /* store final carry [if any] and increment ix offset */ + *tmpc++ = u; + ++ix; - /* now zero digits above the top */ - while (ix++ < olduse) { - *tmpc++ = 0; - } + /* now zero digits above the top */ + MP_ZERO_DIGITS(tmpc, olduse - ix); - /* set used count */ - c->used = a->used + 1; - mp_clamp(c); + /* set used count */ + c->used = a->used + 1; + mp_clamp(c); - return MP_OKAY; + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_mulmod.c b/libtommath/bn_mp_mulmod.c index d7a4d3c..160d162 100644 --- a/libtommath/bn_mp_mulmod.c +++ b/libtommath/bn_mp_mulmod.c @@ -1,40 +1,25 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_MULMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* d = a * b (mod c) */ -int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d) { - int res; - mp_int t; + mp_err err; + mp_int t; - if ((res = mp_init_size (&t, c->used)) != MP_OKAY) { - return res; - } + if ((err = mp_init_size(&t, c->used)) != MP_OKAY) { + return err; + } - if ((res = mp_mul (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, c, d); - mp_clear (&t); - return res; + if ((err = mp_mul(a, b, &t)) != MP_OKAY) { + goto LBL_ERR; + } + err = mp_mod(&t, c, d); + +LBL_ERR: + mp_clear(&t); + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_n_root.c b/libtommath/bn_mp_n_root.c deleted file mode 100644 index f717f17..0000000 --- a/libtommath/bn_mp_n_root.c +++ /dev/null @@ -1,30 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_N_ROOT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* wrapper function for mp_n_root_ex() - * computes c = (a)**(1/b) such that (c)**b <= a and (c+1)**b > a - */ -int mp_n_root (mp_int * a, mp_digit b, mp_int * c) -{ - return mp_n_root_ex(a, b, c, 0); -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_n_root_ex.c b/libtommath/bn_mp_n_root_ex.c deleted file mode 100644 index 079b4f3..0000000 --- a/libtommath/bn_mp_n_root_ex.c +++ /dev/null @@ -1,132 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_N_ROOT_EX_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* find the n'th root of an integer - * - * Result found such that (c)**b <= a and (c+1)**b > a - * - * This algorithm uses Newton's approximation - * x[i+1] = x[i] - f(x[i])/f'(x[i]) - * which will find the root in log(N) time where - * each step involves a fair bit. This is not meant to - * find huge roots [square and cube, etc]. - */ -int mp_n_root_ex (mp_int * a, mp_digit b, mp_int * c, int fast) -{ - mp_int t1, t2, t3; - int res, neg; - - /* input must be positive if b is even */ - if (((b & 1) == 0) && (a->sign == MP_NEG)) { - return MP_VAL; - } - - if ((res = mp_init (&t1)) != MP_OKAY) { - return res; - } - - if ((res = mp_init (&t2)) != MP_OKAY) { - goto LBL_T1; - } - - if ((res = mp_init (&t3)) != MP_OKAY) { - goto LBL_T2; - } - - /* if a is negative fudge the sign but keep track */ - neg = a->sign; - a->sign = MP_ZPOS; - - /* t2 = 2 */ - mp_set (&t2, 2); - - do { - /* t1 = t2 */ - if ((res = mp_copy (&t2, &t1)) != MP_OKAY) { - goto LBL_T3; - } - - /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */ - - /* t3 = t1**(b-1) */ - if ((res = mp_expt_d_ex (&t1, b - 1, &t3, fast)) != MP_OKAY) { - goto LBL_T3; - } - - /* numerator */ - /* t2 = t1**b */ - if ((res = mp_mul (&t3, &t1, &t2)) != MP_OKAY) { - goto LBL_T3; - } - - /* t2 = t1**b - a */ - if ((res = mp_sub (&t2, a, &t2)) != MP_OKAY) { - goto LBL_T3; - } - - /* denominator */ - /* t3 = t1**(b-1) * b */ - if ((res = mp_mul_d (&t3, b, &t3)) != MP_OKAY) { - goto LBL_T3; - } - - /* t3 = (t1**b - a)/(b * t1**(b-1)) */ - if ((res = mp_div (&t2, &t3, &t3, NULL)) != MP_OKAY) { - goto LBL_T3; - } - - if ((res = mp_sub (&t1, &t3, &t2)) != MP_OKAY) { - goto LBL_T3; - } - } while (mp_cmp (&t1, &t2) != MP_EQ); - - /* result can be off by a few so check */ - for (;;) { - if ((res = mp_expt_d_ex (&t1, b, &t2, fast)) != MP_OKAY) { - goto LBL_T3; - } - - if (mp_cmp (&t2, a) == MP_GT) { - if ((res = mp_sub_d (&t1, 1, &t1)) != MP_OKAY) { - goto LBL_T3; - } - } else { - break; - } - } - - /* reset the sign of a first */ - a->sign = neg; - - /* set the result */ - mp_exch (&t1, c); - - /* set the sign of the result */ - c->sign = neg; - - res = MP_OKAY; - -LBL_T3:mp_clear (&t3); -LBL_T2:mp_clear (&t2); -LBL_T1:mp_clear (&t1); - return res; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_neg.c b/libtommath/bn_mp_neg.c index d03e92e..264d900 100644 --- a/libtommath/bn_mp_neg.c +++ b/libtommath/bn_mp_neg.c @@ -1,40 +1,24 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_NEG_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* b = -a */ -int mp_neg (mp_int * a, mp_int * b) +mp_err mp_neg(const mp_int *a, mp_int *b) { - int res; - if (a != b) { - if ((res = mp_copy (a, b)) != MP_OKAY) { - return res; - } - } + mp_err err; + if (a != b) { + if ((err = mp_copy(a, b)) != MP_OKAY) { + return err; + } + } - if (mp_iszero(b) != MP_YES) { - b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS; - } else { - b->sign = MP_ZPOS; - } + if (!MP_IS_ZERO(b)) { + b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS; + } else { + b->sign = MP_ZPOS; + } - return MP_OKAY; + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_or.c b/libtommath/bn_mp_or.c index b9775ce..cdacbfb 100644 --- a/libtommath/bn_mp_or.c +++ b/libtommath/bn_mp_or.c @@ -1,50 +1,56 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_OR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* OR two ints together */ -int mp_or (mp_int * a, mp_int * b, mp_int * c) +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* two complement or */ +mp_err mp_or(const mp_int *a, const mp_int *b, mp_int *c) { - int res, ix, px; - mp_int t, *x; - - if (a->used > b->used) { - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - px = b->used; - x = b; - } else { - if ((res = mp_init_copy (&t, b)) != MP_OKAY) { - return res; - } - px = a->used; - x = a; - } - - for (ix = 0; ix < px; ix++) { - t.dp[ix] |= x->dp[ix]; - } - mp_clamp (&t); - mp_exch (c, &t); - mp_clear (&t); - return MP_OKAY; + int used = MP_MAX(a->used, b->used) + 1, i; + mp_err err; + mp_digit ac = 1, bc = 1, cc = 1; + mp_sign csign = ((a->sign == MP_NEG) || (b->sign == MP_NEG)) ? MP_NEG : MP_ZPOS; + + if (c->alloc < used) { + if ((err = mp_grow(c, used)) != MP_OKAY) { + return err; + } + } + + for (i = 0; i < used; i++) { + mp_digit x, y; + + /* convert to two complement if negative */ + if (a->sign == MP_NEG) { + ac += (i >= a->used) ? MP_MASK : (~a->dp[i] & MP_MASK); + x = ac & MP_MASK; + ac >>= MP_DIGIT_BIT; + } else { + x = (i >= a->used) ? 0uL : a->dp[i]; + } + + /* convert to two complement if negative */ + if (b->sign == MP_NEG) { + bc += (i >= b->used) ? MP_MASK : (~b->dp[i] & MP_MASK); + y = bc & MP_MASK; + bc >>= MP_DIGIT_BIT; + } else { + y = (i >= b->used) ? 0uL : b->dp[i]; + } + + c->dp[i] = x | y; + + /* convert to to sign-magnitude if negative */ + if (csign == MP_NEG) { + cc += ~c->dp[i] & MP_MASK; + c->dp[i] = cc & MP_MASK; + cc >>= MP_DIGIT_BIT; + } + } + + c->used = used; + c->sign = csign; + mp_clamp(c); + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_pack.c b/libtommath/bn_mp_pack.c new file mode 100644 index 0000000..6e00b6f --- /dev/null +++ b/libtommath/bn_mp_pack.c @@ -0,0 +1,69 @@ +#include "tommath_private.h" +#ifdef BN_MP_PACK_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* based on gmp's mpz_export. + * see http://gmplib.org/manual/Integer-Import-and-Export.html + */ +mp_err mp_pack(void *rop, size_t maxcount, size_t *written, mp_order order, size_t size, + mp_endian endian, size_t nails, const mp_int *op) +{ + mp_err err; + size_t odd_nails, nail_bytes, i, j, count; + unsigned char odd_nail_mask; + + mp_int t; + + count = mp_pack_count(op, nails, size); + + if (count > maxcount) { + return MP_BUF; + } + + if ((err = mp_init_copy(&t, op)) != MP_OKAY) { + return err; + } + + if (endian == MP_NATIVE_ENDIAN) { + MP_GET_ENDIANNESS(endian); + } + + odd_nails = (nails % 8u); + odd_nail_mask = 0xff; + for (i = 0u; i < odd_nails; ++i) { + odd_nail_mask ^= (unsigned char)(1u << (7u - i)); + } + nail_bytes = nails / 8u; + + for (i = 0u; i < count; ++i) { + for (j = 0u; j < size; ++j) { + unsigned char *byte = (unsigned char *)rop + + (((order == MP_LSB_FIRST) ? i : ((count - 1u) - i)) * size) + + ((endian == MP_LITTLE_ENDIAN) ? j : ((size - 1u) - j)); + + if (j >= (size - nail_bytes)) { + *byte = 0; + continue; + } + + *byte = (unsigned char)((j == ((size - nail_bytes) - 1u)) ? (t.dp[0] & odd_nail_mask) : (t.dp[0] & 0xFFuL)); + + if ((err = mp_div_2d(&t, (j == ((size - nail_bytes) - 1u)) ? (int)(8u - odd_nails) : 8, &t, NULL)) != MP_OKAY) { + goto LBL_ERR; + } + + } + } + + if (written != NULL) { + *written = count; + } + err = MP_OKAY; + +LBL_ERR: + mp_clear(&t); + return err; +} + +#endif diff --git a/libtommath/bn_mp_pack_count.c b/libtommath/bn_mp_pack_count.c new file mode 100644 index 0000000..dfecdf9 --- /dev/null +++ b/libtommath/bn_mp_pack_count.c @@ -0,0 +1,12 @@ +#include "tommath_private.h" +#ifdef BN_MP_PACK_COUNT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +size_t mp_pack_count(const mp_int *a, size_t nails, size_t size) +{ + size_t bits = (size_t)mp_count_bits(a); + return ((bits / ((size * 8u) - nails)) + (((bits % ((size * 8u) - nails)) != 0u) ? 1u : 0u)); +} + +#endif diff --git a/libtommath/bn_mp_prime_fermat.c b/libtommath/bn_mp_prime_fermat.c index d99feeb..af3e884 100644 --- a/libtommath/bn_mp_prime_fermat.c +++ b/libtommath/bn_mp_prime_fermat.c @@ -1,62 +1,47 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_PRIME_FERMAT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* performs one Fermat test. - * + * * If "a" were prime then b**a == b (mod a) since the order of * the multiplicative sub-group would be phi(a) = a-1. That means * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a). * * Sets result to 1 if the congruence holds, or zero otherwise. */ -int mp_prime_fermat (mp_int * a, mp_int * b, int *result) +mp_err mp_prime_fermat(const mp_int *a, const mp_int *b, mp_bool *result) { - mp_int t; - int err; - - /* default to composite */ - *result = MP_NO; - - /* ensure b > 1 */ - if (mp_cmp_d(b, 1) != MP_GT) { - return MP_VAL; - } - - /* init t */ - if ((err = mp_init (&t)) != MP_OKAY) { - return err; - } - - /* compute t = b**a mod a */ - if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) { - goto LBL_T; - } - - /* is it equal to b? */ - if (mp_cmp (&t, b) == MP_EQ) { - *result = MP_YES; - } - - err = MP_OKAY; -LBL_T:mp_clear (&t); - return err; + mp_int t; + mp_err err; + + /* default to composite */ + *result = MP_NO; + + /* ensure b > 1 */ + if (mp_cmp_d(b, 1uL) != MP_GT) { + return MP_VAL; + } + + /* init t */ + if ((err = mp_init(&t)) != MP_OKAY) { + return err; + } + + /* compute t = b**a mod a */ + if ((err = mp_exptmod(b, a, a, &t)) != MP_OKAY) { + goto LBL_T; + } + + /* is it equal to b? */ + if (mp_cmp(&t, b) == MP_EQ) { + *result = MP_YES; + } + + err = MP_OKAY; +LBL_T: + mp_clear(&t); + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_prime_frobenius_underwood.c b/libtommath/bn_mp_prime_frobenius_underwood.c new file mode 100644 index 0000000..253e8d5 --- /dev/null +++ b/libtommath/bn_mp_prime_frobenius_underwood.c @@ -0,0 +1,132 @@ +#include "tommath_private.h" +#ifdef BN_MP_PRIME_FROBENIUS_UNDERWOOD_C + +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* + * See file bn_mp_prime_is_prime.c or the documentation in doc/bn.tex for the details + */ +#ifndef LTM_USE_ONLY_MR + +#ifdef MP_8BIT +/* + * floor of positive solution of + * (2^16)-1 = (a+4)*(2*a+5) + * TODO: Both values are smaller than N^(1/4), would have to use a bigint + * for a instead but any a biger than about 120 are already so rare that + * it is possible to ignore them and still get enough pseudoprimes. + * But it is still a restriction of the set of available pseudoprimes + * which makes this implementation less secure if used stand-alone. + */ +#define LTM_FROBENIUS_UNDERWOOD_A 177 +#else +#define LTM_FROBENIUS_UNDERWOOD_A 32764 +#endif +mp_err mp_prime_frobenius_underwood(const mp_int *N, mp_bool *result) +{ + mp_int T1z, T2z, Np1z, sz, tz; + + int a, ap2, length, i, j; + mp_err err; + + *result = MP_NO; + + if ((err = mp_init_multi(&T1z, &T2z, &Np1z, &sz, &tz, NULL)) != MP_OKAY) { + return err; + } + + for (a = 0; a < LTM_FROBENIUS_UNDERWOOD_A; a++) { + /* TODO: That's ugly! No, really, it is! */ + if ((a==2) || (a==4) || (a==7) || (a==8) || (a==10) || + (a==14) || (a==18) || (a==23) || (a==26) || (a==28)) { + continue; + } + /* (32764^2 - 4) < 2^31, no bigint for >MP_8BIT needed) */ + mp_set_u32(&T1z, (uint32_t)a); + + if ((err = mp_sqr(&T1z, &T1z)) != MP_OKAY) goto LBL_FU_ERR; + + if ((err = mp_sub_d(&T1z, 4uL, &T1z)) != MP_OKAY) goto LBL_FU_ERR; + + if ((err = mp_kronecker(&T1z, N, &j)) != MP_OKAY) goto LBL_FU_ERR; + + if (j == -1) { + break; + } + + if (j == 0) { + /* composite */ + goto LBL_FU_ERR; + } + } + /* Tell it a composite and set return value accordingly */ + if (a >= LTM_FROBENIUS_UNDERWOOD_A) { + err = MP_ITER; + goto LBL_FU_ERR; + } + /* Composite if N and (a+4)*(2*a+5) are not coprime */ + mp_set_u32(&T1z, (uint32_t)((a+4)*((2*a)+5))); + + if ((err = mp_gcd(N, &T1z, &T1z)) != MP_OKAY) goto LBL_FU_ERR; + + if (!((T1z.used == 1) && (T1z.dp[0] == 1u))) goto LBL_FU_ERR; + + ap2 = a + 2; + if ((err = mp_add_d(N, 1uL, &Np1z)) != MP_OKAY) goto LBL_FU_ERR; + + mp_set(&sz, 1uL); + mp_set(&tz, 2uL); + length = mp_count_bits(&Np1z); + + for (i = length - 2; i >= 0; i--) { + /* + * temp = (sz*(a*sz+2*tz))%N; + * tz = ((tz-sz)*(tz+sz))%N; + * sz = temp; + */ + if ((err = mp_mul_2(&tz, &T2z)) != MP_OKAY) goto LBL_FU_ERR; + + /* a = 0 at about 50% of the cases (non-square and odd input) */ + if (a != 0) { + if ((err = mp_mul_d(&sz, (mp_digit)a, &T1z)) != MP_OKAY) goto LBL_FU_ERR; + if ((err = mp_add(&T1z, &T2z, &T2z)) != MP_OKAY) goto LBL_FU_ERR; + } + + if ((err = mp_mul(&T2z, &sz, &T1z)) != MP_OKAY) goto LBL_FU_ERR; + if ((err = mp_sub(&tz, &sz, &T2z)) != MP_OKAY) goto LBL_FU_ERR; + if ((err = mp_add(&sz, &tz, &sz)) != MP_OKAY) goto LBL_FU_ERR; + if ((err = mp_mul(&sz, &T2z, &tz)) != MP_OKAY) goto LBL_FU_ERR; + if ((err = mp_mod(&tz, N, &tz)) != MP_OKAY) goto LBL_FU_ERR; + if ((err = mp_mod(&T1z, N, &sz)) != MP_OKAY) goto LBL_FU_ERR; + if (s_mp_get_bit(&Np1z, (unsigned int)i) == MP_YES) { + /* + * temp = (a+2) * sz + tz + * tz = 2 * tz - sz + * sz = temp + */ + if (a == 0) { + if ((err = mp_mul_2(&sz, &T1z)) != MP_OKAY) goto LBL_FU_ERR; + } else { + if ((err = mp_mul_d(&sz, (mp_digit)ap2, &T1z)) != MP_OKAY) goto LBL_FU_ERR; + } + if ((err = mp_add(&T1z, &tz, &T1z)) != MP_OKAY) goto LBL_FU_ERR; + if ((err = mp_mul_2(&tz, &T2z)) != MP_OKAY) goto LBL_FU_ERR; + if ((err = mp_sub(&T2z, &sz, &tz)) != MP_OKAY) goto LBL_FU_ERR; + mp_exch(&sz, &T1z); + } + } + + mp_set_u32(&T1z, (uint32_t)((2 * a) + 5)); + if ((err = mp_mod(&T1z, N, &T1z)) != MP_OKAY) goto LBL_FU_ERR; + if (MP_IS_ZERO(&sz) && (mp_cmp(&tz, &T1z) == MP_EQ)) { + *result = MP_YES; + } + +LBL_FU_ERR: + mp_clear_multi(&tz, &sz, &Np1z, &T2z, &T1z, NULL); + return err; +} + +#endif +#endif diff --git a/libtommath/bn_mp_prime_is_divisible.c b/libtommath/bn_mp_prime_is_divisible.c deleted file mode 100644 index eea4a27..0000000 --- a/libtommath/bn_mp_prime_is_divisible.c +++ /dev/null @@ -1,50 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_PRIME_IS_DIVISIBLE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* determines if an integers is divisible by one - * of the first PRIME_SIZE primes or not - * - * sets result to 0 if not, 1 if yes - */ -int mp_prime_is_divisible (mp_int * a, int *result) -{ - int err, ix; - mp_digit res; - - /* default to not */ - *result = MP_NO; - - for (ix = 0; ix < PRIME_SIZE; ix++) { - /* what is a mod LBL_prime_tab[ix] */ - if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) { - return err; - } - - /* is the residue zero? */ - if (res == 0) { - *result = MP_YES; - return MP_OKAY; - } - } - - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_prime_is_prime.c b/libtommath/bn_mp_prime_is_prime.c index 3eda4fd..7f9fc0b 100644 --- a/libtommath/bn_mp_prime_is_prime.c +++ b/libtommath/bn_mp_prime_is_prime.c @@ -1,83 +1,314 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_PRIME_IS_PRIME_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* performs a variable number of rounds of Miller-Rabin - * - * Probability of error after t rounds is no more than - - * - * Sets result to 1 if probably prime, 0 otherwise - */ -int mp_prime_is_prime (mp_int * a, int t, int *result) +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* portable integer log of two with small footprint */ +static unsigned int s_floor_ilog2(int value) { - mp_int b; - int ix, err, res; + unsigned int r = 0; + while ((value >>= 1) != 0) { + r++; + } + return r; +} + - /* default to no */ - *result = MP_NO; +mp_err mp_prime_is_prime(const mp_int *a, int t, mp_bool *result) +{ + mp_int b; + int ix, p_max = 0, size_a, len; + mp_bool res; + mp_err err; + unsigned int fips_rand, mask; - /* valid value of t? */ - if ((t <= 0) || (t > PRIME_SIZE)) { - return MP_VAL; - } + /* default to no */ + *result = MP_NO; - /* is the input equal to one of the primes in the table? */ - for (ix = 0; ix < PRIME_SIZE; ix++) { - if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) { - *result = 1; + /* Some shortcuts */ + /* N > 3 */ + if (a->used == 1) { + if ((a->dp[0] == 0u) || (a->dp[0] == 1u)) { + *result = MP_NO; + return MP_OKAY; + } + if (a->dp[0] == 2u) { + *result = MP_YES; return MP_OKAY; } - } + } - /* first perform trial division */ - if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) { - return err; - } + /* N must be odd */ + if (MP_IS_EVEN(a)) { + return MP_OKAY; + } + /* N is not a perfect square: floor(sqrt(N))^2 != N */ + if ((err = mp_is_square(a, &res)) != MP_OKAY) { + return err; + } + if (res != MP_NO) { + return MP_OKAY; + } - /* return if it was trivially divisible */ - if (res == MP_YES) { - return MP_OKAY; - } + /* is the input equal to one of the primes in the table? */ + for (ix = 0; ix < PRIVATE_MP_PRIME_TAB_SIZE; ix++) { + if (mp_cmp_d(a, s_mp_prime_tab[ix]) == MP_EQ) { + *result = MP_YES; + return MP_OKAY; + } + } +#ifdef MP_8BIT + /* The search in the loop above was exhaustive in this case */ + if ((a->used == 1) && (PRIVATE_MP_PRIME_TAB_SIZE >= 31)) { + return MP_OKAY; + } +#endif - /* now perform the miller-rabin rounds */ - if ((err = mp_init (&b)) != MP_OKAY) { - return err; - } + /* first perform trial division */ + if ((err = s_mp_prime_is_divisible(a, &res)) != MP_OKAY) { + return err; + } - for (ix = 0; ix < t; ix++) { - /* set the prime */ - mp_set (&b, ltm_prime_tab[ix]); + /* return if it was trivially divisible */ + if (res == MP_YES) { + return MP_OKAY; + } - if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) { - goto LBL_B; - } + /* + Run the Miller-Rabin test with base 2 for the BPSW test. + */ + if ((err = mp_init_set(&b, 2uL)) != MP_OKAY) { + return err; + } - if (res == MP_NO) { + if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) { + goto LBL_B; + } + if (res == MP_NO) { goto LBL_B; - } - } + } + /* + Rumours have it that Mathematica does a second M-R test with base 3. + Other rumours have it that their strong L-S test is slightly different. + It does not hurt, though, beside a bit of extra runtime. + */ + b.dp[0]++; + if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) { + goto LBL_B; + } + if (res == MP_NO) { + goto LBL_B; + } - /* passed the test */ - *result = MP_YES; -LBL_B:mp_clear (&b); - return err; -} + /* + * Both, the Frobenius-Underwood test and the the Lucas-Selfridge test are quite + * slow so if speed is an issue, define LTM_USE_ONLY_MR to use M-R tests with + * bases 2, 3 and t random bases. + */ +#ifndef LTM_USE_ONLY_MR + if (t >= 0) { + /* + * Use a Frobenius-Underwood test instead of the Lucas-Selfridge test for + * MP_8BIT (It is unknown if the Lucas-Selfridge test works with 16-bit + * integers but the necesssary analysis is on the todo-list). + */ +#if defined (MP_8BIT) || defined (LTM_USE_FROBENIUS_TEST) + err = mp_prime_frobenius_underwood(a, &res); + if ((err != MP_OKAY) && (err != MP_ITER)) { + goto LBL_B; + } + if (res == MP_NO) { + goto LBL_B; + } +#else + if ((err = mp_prime_strong_lucas_selfridge(a, &res)) != MP_OKAY) { + goto LBL_B; + } + if (res == MP_NO) { + goto LBL_B; + } +#endif + } #endif -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ + /* run at least one Miller-Rabin test with a random base */ + if (t == 0) { + t = 1; + } + + /* + Only recommended if the input range is known to be < 3317044064679887385961981 + + It uses the bases necessary for a deterministic M-R test if the input is + smaller than 3317044064679887385961981 + The caller has to check the size. + TODO: can be made a bit finer grained but comparing is not free. + */ + if (t < 0) { + /* + Sorenson, Jonathan; Webster, Jonathan (2015). + "Strong Pseudoprimes to Twelve Prime Bases". + */ + /* 0x437ae92817f9fc85b7e5 = 318665857834031151167461 */ + if ((err = mp_read_radix(&b, "437ae92817f9fc85b7e5", 16)) != MP_OKAY) { + goto LBL_B; + } + + if (mp_cmp(a, &b) == MP_LT) { + p_max = 12; + } else { + /* 0x2be6951adc5b22410a5fd = 3317044064679887385961981 */ + if ((err = mp_read_radix(&b, "2be6951adc5b22410a5fd", 16)) != MP_OKAY) { + goto LBL_B; + } + + if (mp_cmp(a, &b) == MP_LT) { + p_max = 13; + } else { + err = MP_VAL; + goto LBL_B; + } + } + + /* we did bases 2 and 3 already, skip them */ + for (ix = 2; ix < p_max; ix++) { + mp_set(&b, s_mp_prime_tab[ix]); + if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) { + goto LBL_B; + } + if (res == MP_NO) { + goto LBL_B; + } + } + } + /* + Do "t" M-R tests with random bases between 3 and "a". + See Fips 186.4 p. 126ff + */ + else if (t > 0) { + /* + * The mp_digit's have a defined bit-size but the size of the + * array a.dp is a simple 'int' and this library can not assume full + * compliance to the current C-standard (ISO/IEC 9899:2011) because + * it gets used for small embeded processors, too. Some of those MCUs + * have compilers that one cannot call standard compliant by any means. + * Hence the ugly type-fiddling in the following code. + */ + size_a = mp_count_bits(a); + mask = (1u << s_floor_ilog2(size_a)) - 1u; + /* + Assuming the General Rieman hypothesis (never thought to write that in a + comment) the upper bound can be lowered to 2*(log a)^2. + E. Bach, "Explicit bounds for primality testing and related problems," + Math. Comp. 55 (1990), 355-380. + + size_a = (size_a/10) * 7; + len = 2 * (size_a * size_a); + + E.g.: a number of size 2^2048 would be reduced to the upper limit + + floor(2048/10)*7 = 1428 + 2 * 1428^2 = 4078368 + + (would have been ~4030331.9962 with floats and natural log instead) + That number is smaller than 2^28, the default bit-size of mp_digit. + */ + + /* + How many tests, you might ask? Dana Jacobsen of Math::Prime::Util fame + does exactly 1. In words: one. Look at the end of _GMP_is_prime() in + Math-Prime-Util-GMP-0.50/primality.c if you do not believe it. + + The function mp_rand() goes to some length to use a cryptographically + good PRNG. That also means that the chance to always get the same base + in the loop is non-zero, although very low. + If the BPSW test and/or the addtional Frobenious test have been + performed instead of just the Miller-Rabin test with the bases 2 and 3, + a single extra test should suffice, so such a very unlikely event + will not do much harm. + + To preemptivly answer the dangling question: no, a witness does not + need to be prime. + */ + for (ix = 0; ix < t; ix++) { + /* mp_rand() guarantees the first digit to be non-zero */ + if ((err = mp_rand(&b, 1)) != MP_OKAY) { + goto LBL_B; + } + /* + * Reduce digit before casting because mp_digit might be bigger than + * an unsigned int and "mask" on the other side is most probably not. + */ + fips_rand = (unsigned int)(b.dp[0] & (mp_digit) mask); +#ifdef MP_8BIT + /* + * One 8-bit digit is too small, so concatenate two if the size of + * unsigned int allows for it. + */ + if ((MP_SIZEOF_BITS(unsigned int)/2) >= MP_SIZEOF_BITS(mp_digit)) { + if ((err = mp_rand(&b, 1)) != MP_OKAY) { + goto LBL_B; + } + fips_rand <<= MP_SIZEOF_BITS(mp_digit); + fips_rand |= (unsigned int) b.dp[0]; + fips_rand &= mask; + } +#endif + if (fips_rand > (unsigned int)(INT_MAX - MP_DIGIT_BIT)) { + len = INT_MAX / MP_DIGIT_BIT; + } else { + len = (((int)fips_rand + MP_DIGIT_BIT) / MP_DIGIT_BIT); + } + /* Unlikely. */ + if (len < 0) { + ix--; + continue; + } + /* + * As mentioned above, one 8-bit digit is too small and + * although it can only happen in the unlikely case that + * an "unsigned int" is smaller than 16 bit a simple test + * is cheap and the correction even cheaper. + */ +#ifdef MP_8BIT + /* All "a" < 2^8 have been caught before */ + if (len == 1) { + len++; + } +#endif + if ((err = mp_rand(&b, len)) != MP_OKAY) { + goto LBL_B; + } + /* + * That number might got too big and the witness has to be + * smaller than "a" + */ + len = mp_count_bits(&b); + if (len >= size_a) { + len = (len - size_a) + 1; + if ((err = mp_div_2d(&b, len, &b, NULL)) != MP_OKAY) { + goto LBL_B; + } + } + /* Although the chance for b <= 3 is miniscule, try again. */ + if (mp_cmp_d(&b, 3uL) != MP_GT) { + ix--; + continue; + } + if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) { + goto LBL_B; + } + if (res == MP_NO) { + goto LBL_B; + } + } + } + + /* passed the test */ + *result = MP_YES; +LBL_B: + mp_clear(&b); + return err; +} + +#endif diff --git a/libtommath/bn_mp_prime_miller_rabin.c b/libtommath/bn_mp_prime_miller_rabin.c index 7de0634..96470db 100644 --- a/libtommath/bn_mp_prime_miller_rabin.c +++ b/libtommath/bn_mp_prime_miller_rabin.c @@ -1,103 +1,91 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_PRIME_MILLER_RABIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ -/* Miller-Rabin test of "a" to the base of "b" as described in +/* Miller-Rabin test of "a" to the base of "b" as described in * HAC pp. 139 Algorithm 4.24 * * Sets result to 0 if definitely composite or 1 if probably prime. - * Randomly the chance of error is no more than 1/4 and often + * Randomly the chance of error is no more than 1/4 and often * very much lower. */ -int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result) +mp_err mp_prime_miller_rabin(const mp_int *a, const mp_int *b, mp_bool *result) { - mp_int n1, y, r; - int s, j, err; + mp_int n1, y, r; + mp_err err; + int s, j; - /* default */ - *result = MP_NO; + /* default */ + *result = MP_NO; - /* ensure b > 1 */ - if (mp_cmp_d(b, 1) != MP_GT) { - return MP_VAL; - } + /* ensure b > 1 */ + if (mp_cmp_d(b, 1uL) != MP_GT) { + return MP_VAL; + } - /* get n1 = a - 1 */ - if ((err = mp_init_copy (&n1, a)) != MP_OKAY) { - return err; - } - if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) { - goto LBL_N1; - } + /* get n1 = a - 1 */ + if ((err = mp_init_copy(&n1, a)) != MP_OKAY) { + return err; + } + if ((err = mp_sub_d(&n1, 1uL, &n1)) != MP_OKAY) { + goto LBL_N1; + } - /* set 2**s * r = n1 */ - if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) { - goto LBL_N1; - } + /* set 2**s * r = n1 */ + if ((err = mp_init_copy(&r, &n1)) != MP_OKAY) { + goto LBL_N1; + } - /* count the number of least significant bits - * which are zero - */ - s = mp_cnt_lsb(&r); + /* count the number of least significant bits + * which are zero + */ + s = mp_cnt_lsb(&r); - /* now divide n - 1 by 2**s */ - if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) { - goto LBL_R; - } + /* now divide n - 1 by 2**s */ + if ((err = mp_div_2d(&r, s, &r, NULL)) != MP_OKAY) { + goto LBL_R; + } - /* compute y = b**r mod a */ - if ((err = mp_init (&y)) != MP_OKAY) { - goto LBL_R; - } - if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) { - goto LBL_Y; - } + /* compute y = b**r mod a */ + if ((err = mp_init(&y)) != MP_OKAY) { + goto LBL_R; + } + if ((err = mp_exptmod(b, &r, a, &y)) != MP_OKAY) { + goto LBL_Y; + } - /* if y != 1 and y != n1 do */ - if ((mp_cmp_d (&y, 1) != MP_EQ) && (mp_cmp (&y, &n1) != MP_EQ)) { - j = 1; - /* while j <= s-1 and y != n1 */ - while ((j <= (s - 1)) && (mp_cmp (&y, &n1) != MP_EQ)) { - if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) { - goto LBL_Y; + /* if y != 1 and y != n1 do */ + if ((mp_cmp_d(&y, 1uL) != MP_EQ) && (mp_cmp(&y, &n1) != MP_EQ)) { + j = 1; + /* while j <= s-1 and y != n1 */ + while ((j <= (s - 1)) && (mp_cmp(&y, &n1) != MP_EQ)) { + if ((err = mp_sqrmod(&y, a, &y)) != MP_OKAY) { + goto LBL_Y; + } + + /* if y == 1 then composite */ + if (mp_cmp_d(&y, 1uL) == MP_EQ) { + goto LBL_Y; + } + + ++j; } - /* if y == 1 then composite */ - if (mp_cmp_d (&y, 1) == MP_EQ) { + /* if y != n1 then composite */ + if (mp_cmp(&y, &n1) != MP_EQ) { goto LBL_Y; } + } - ++j; - } - - /* if y != n1 then composite */ - if (mp_cmp (&y, &n1) != MP_EQ) { - goto LBL_Y; - } - } - - /* probably prime now */ - *result = MP_YES; -LBL_Y:mp_clear (&y); -LBL_R:mp_clear (&r); -LBL_N1:mp_clear (&n1); - return err; + /* probably prime now */ + *result = MP_YES; +LBL_Y: + mp_clear(&y); +LBL_R: + mp_clear(&r); +LBL_N1: + mp_clear(&n1); + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_prime_next_prime.c b/libtommath/bn_mp_prime_next_prime.c index 7a32d9b..d656565 100644 --- a/libtommath/bn_mp_prime_next_prime.c +++ b/libtommath/bn_mp_prime_next_prime.c @@ -1,70 +1,42 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_PRIME_NEXT_PRIME_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* finds the next prime after the number "a" using "t" trials * of Miller-Rabin. * * bbs_style = 1 means the prime must be congruent to 3 mod 4 */ -int mp_prime_next_prime(mp_int *a, int t, int bbs_style) +mp_err mp_prime_next_prime(mp_int *a, int t, int bbs_style) { - int err, res = MP_NO, x, y; - mp_digit res_tab[PRIME_SIZE], step, kstep; + int x, y; + mp_ord cmp; + mp_err err; + mp_bool res = MP_NO; + mp_digit res_tab[PRIVATE_MP_PRIME_TAB_SIZE], step, kstep; mp_int b; - /* ensure t is valid */ - if ((t <= 0) || (t > PRIME_SIZE)) { - return MP_VAL; - } - /* force positive */ a->sign = MP_ZPOS; /* simple algo if a is less than the largest prime in the table */ - if (mp_cmp_d(a, ltm_prime_tab[PRIME_SIZE-1]) == MP_LT) { - /* find which prime it is bigger than */ - for (x = PRIME_SIZE - 2; x >= 0; x--) { - if (mp_cmp_d(a, ltm_prime_tab[x]) != MP_LT) { - if (bbs_style == 1) { - /* ok we found a prime smaller or - * equal [so the next is larger] - * - * however, the prime must be - * congruent to 3 mod 4 - */ - if ((ltm_prime_tab[x + 1] & 3) != 3) { - /* scan upwards for a prime congruent to 3 mod 4 */ - for (y = x + 1; y < PRIME_SIZE; y++) { - if ((ltm_prime_tab[y] & 3) == 3) { - mp_set(a, ltm_prime_tab[y]); - return MP_OKAY; - } - } - } - } else { - mp_set(a, ltm_prime_tab[x + 1]); - return MP_OKAY; - } - } - } - /* at this point a maybe 1 */ - if (mp_cmp_d(a, 1) == MP_EQ) { - mp_set(a, 2); - return MP_OKAY; + if (mp_cmp_d(a, s_mp_prime_tab[PRIVATE_MP_PRIME_TAB_SIZE-1]) == MP_LT) { + /* find which prime it is bigger than "a" */ + for (x = 0; x < PRIVATE_MP_PRIME_TAB_SIZE; x++) { + cmp = mp_cmp_d(a, s_mp_prime_tab[x]); + if (cmp == MP_EQ) { + continue; + } + if (cmp != MP_GT) { + if ((bbs_style == 1) && ((s_mp_prime_tab[x] & 3u) != 3u)) { + /* try again until we get a prime congruent to 3 mod 4 */ + continue; + } else { + mp_set(a, s_mp_prime_tab[x]); + return MP_OKAY; + } + } } /* fall through to the sieve */ } @@ -80,21 +52,23 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style) if (bbs_style == 1) { /* if a mod 4 != 3 subtract the correct value to make it so */ - if ((a->dp[0] & 3) != 3) { - if ((err = mp_sub_d(a, (a->dp[0] & 3) + 1, a)) != MP_OKAY) { return err; }; + if ((a->dp[0] & 3u) != 3u) { + if ((err = mp_sub_d(a, (a->dp[0] & 3u) + 1u, a)) != MP_OKAY) { + return err; + } } } else { - if (mp_iseven(a) == MP_YES) { + if (MP_IS_EVEN(a)) { /* force odd */ - if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { + if ((err = mp_sub_d(a, 1uL, a)) != MP_OKAY) { return err; } } } /* generate the restable */ - for (x = 1; x < PRIME_SIZE; x++) { - if ((err = mp_mod_d(a, ltm_prime_tab[x], res_tab + x)) != MP_OKAY) { + for (x = 1; x < PRIVATE_MP_PRIME_TAB_SIZE; x++) { + if ((err = mp_mod_d(a, s_mp_prime_tab[x], res_tab + x)) != MP_OKAY) { return err; } } @@ -115,43 +89,35 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style) step += kstep; /* compute the new residue without using division */ - for (x = 1; x < PRIME_SIZE; x++) { - /* add the step to each residue */ - res_tab[x] += kstep; - - /* subtract the modulus [instead of using division] */ - if (res_tab[x] >= ltm_prime_tab[x]) { - res_tab[x] -= ltm_prime_tab[x]; - } - - /* set flag if zero */ - if (res_tab[x] == 0) { - y = 1; - } + for (x = 1; x < PRIVATE_MP_PRIME_TAB_SIZE; x++) { + /* add the step to each residue */ + res_tab[x] += kstep; + + /* subtract the modulus [instead of using division] */ + if (res_tab[x] >= s_mp_prime_tab[x]) { + res_tab[x] -= s_mp_prime_tab[x]; + } + + /* set flag if zero */ + if (res_tab[x] == 0u) { + y = 1; + } } - } while ((y == 1) && (step < ((((mp_digit)1) << DIGIT_BIT) - kstep))); + } while ((y == 1) && (step < (((mp_digit)1 << MP_DIGIT_BIT) - kstep))); /* add the step */ if ((err = mp_add_d(a, step, a)) != MP_OKAY) { goto LBL_ERR; } - /* if didn't pass sieve and step == MAX then skip test */ - if ((y == 1) && (step >= ((((mp_digit)1) << DIGIT_BIT) - kstep))) { + /* if didn't pass sieve and step == MP_MAX then skip test */ + if ((y == 1) && (step >= (((mp_digit)1 << MP_DIGIT_BIT) - kstep))) { continue; } - /* is this prime? */ - for (x = 0; x < t; x++) { - mp_set(&b, ltm_prime_tab[x]); - if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) { - goto LBL_ERR; - } - if (res == MP_NO) { - break; - } + if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { + goto LBL_ERR; } - if (res == MP_YES) { break; } @@ -164,7 +130,3 @@ LBL_ERR: } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_prime_rabin_miller_trials.c b/libtommath/bn_mp_prime_rabin_miller_trials.c index 378ceb2..8bbaf6c 100644 --- a/libtommath/bn_mp_prime_rabin_miller_trials.c +++ b/libtommath/bn_mp_prime_rabin_miller_trials.c @@ -1,32 +1,31 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_PRIME_RABIN_MILLER_TRIALS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ static const struct { int k, t; } sizes[] = { -{ 128, 28 }, -{ 256, 16 }, -{ 384, 10 }, -{ 512, 7 }, -{ 640, 6 }, -{ 768, 5 }, -{ 896, 4 }, -{ 1024, 4 } + { 80, -1 }, /* Use deterministic algorithm for size <= 80 bits */ + { 81, 37 }, /* max. error = 2^(-96)*/ + { 96, 32 }, /* max. error = 2^(-96)*/ + { 128, 40 }, /* max. error = 2^(-112)*/ + { 160, 35 }, /* max. error = 2^(-112)*/ + { 256, 27 }, /* max. error = 2^(-128)*/ + { 384, 16 }, /* max. error = 2^(-128)*/ + { 512, 18 }, /* max. error = 2^(-160)*/ + { 768, 11 }, /* max. error = 2^(-160)*/ + { 896, 10 }, /* max. error = 2^(-160)*/ + { 1024, 12 }, /* max. error = 2^(-192)*/ + { 1536, 8 }, /* max. error = 2^(-192)*/ + { 2048, 6 }, /* max. error = 2^(-192)*/ + { 3072, 4 }, /* max. error = 2^(-192)*/ + { 4096, 5 }, /* max. error = 2^(-256)*/ + { 5120, 4 }, /* max. error = 2^(-256)*/ + { 6144, 4 }, /* max. error = 2^(-256)*/ + { 8192, 3 }, /* max. error = 2^(-256)*/ + { 9216, 3 }, /* max. error = 2^(-256)*/ + { 10240, 2 } /* For bigger keysizes use always at least 2 Rounds */ }; /* returns # of RM trials required for a given bit size */ @@ -35,18 +34,14 @@ int mp_prime_rabin_miller_trials(int size) int x; for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) { - if (sizes[x].k == size) { - return sizes[x].t; - } else if (sizes[x].k > size) { - return (x == 0) ? sizes[0].t : sizes[x - 1].t; - } + if (sizes[x].k == size) { + return sizes[x].t; + } else if (sizes[x].k > size) { + return (x == 0) ? sizes[0].t : sizes[x - 1].t; + } } - return sizes[x-1].t + 1; + return sizes[x-1].t; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_prime_rand.c b/libtommath/bn_mp_prime_rand.c new file mode 100644 index 0000000..4530e9a --- /dev/null +++ b/libtommath/bn_mp_prime_rand.c @@ -0,0 +1,141 @@ +#include "tommath_private.h" +#ifdef BN_MP_PRIME_RAND_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* makes a truly random prime of a given size (bits), + * + * Flags are as follows: + * + * MP_PRIME_BBS - make prime congruent to 3 mod 4 + * MP_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies MP_PRIME_BBS) + * MP_PRIME_2MSB_ON - make the 2nd highest bit one + * + * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can + * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself + * so it can be NULL + * + */ + +/* This is possibly the mother of all prime generation functions, muahahahahaha! */ +mp_err s_mp_prime_random_ex(mp_int *a, int t, int size, int flags, private_mp_prime_callback cb, void *dat) +{ + unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb; + int bsize, maskOR_msb_offset; + mp_bool res; + mp_err err; + + /* sanity check the input */ + if ((size <= 1) || (t <= 0)) { + return MP_VAL; + } + + /* MP_PRIME_SAFE implies MP_PRIME_BBS */ + if ((flags & MP_PRIME_SAFE) != 0) { + flags |= MP_PRIME_BBS; + } + + /* calc the byte size */ + bsize = (size>>3) + ((size&7)?1:0); + + /* we need a buffer of bsize bytes */ + tmp = (unsigned char *) MP_MALLOC((size_t)bsize); + if (tmp == NULL) { + return MP_MEM; + } + + /* calc the maskAND value for the MSbyte*/ + maskAND = ((size&7) == 0) ? 0xFFu : (unsigned char)(0xFFu >> (8 - (size & 7))); + + /* calc the maskOR_msb */ + maskOR_msb = 0; + maskOR_msb_offset = ((size & 7) == 1) ? 1 : 0; + if ((flags & MP_PRIME_2MSB_ON) != 0) { + maskOR_msb |= (unsigned char)(0x80 >> ((9 - size) & 7)); + } + + /* get the maskOR_lsb */ + maskOR_lsb = 1u; + if ((flags & MP_PRIME_BBS) != 0) { + maskOR_lsb |= 3u; + } + + do { + /* read the bytes */ + if (cb(tmp, bsize, dat) != bsize) { + err = MP_VAL; + goto error; + } + + /* work over the MSbyte */ + tmp[0] &= maskAND; + tmp[0] |= (unsigned char)(1 << ((size - 1) & 7)); + + /* mix in the maskORs */ + tmp[maskOR_msb_offset] |= maskOR_msb; + tmp[bsize-1] |= maskOR_lsb; + + /* read it in */ + /* TODO: casting only for now until all lengths have been changed to the type "size_t"*/ + if ((err = mp_from_ubin(a, tmp, (size_t)bsize)) != MP_OKAY) { + goto error; + } + + /* is it prime? */ + if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { + goto error; + } + if (res == MP_NO) { + continue; + } + + if ((flags & MP_PRIME_SAFE) != 0) { + /* see if (a-1)/2 is prime */ + if ((err = mp_sub_d(a, 1uL, a)) != MP_OKAY) { + goto error; + } + if ((err = mp_div_2(a, a)) != MP_OKAY) { + goto error; + } + + /* is it prime? */ + if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { + goto error; + } + } + } while (res == MP_NO); + + if ((flags & MP_PRIME_SAFE) != 0) { + /* restore a to the original value */ + if ((err = mp_mul_2(a, a)) != MP_OKAY) { + goto error; + } + if ((err = mp_add_d(a, 1uL, a)) != MP_OKAY) { + goto error; + } + } + + err = MP_OKAY; +error: + MP_FREE_BUFFER(tmp, (size_t)bsize); + return err; +} + +static int s_mp_rand_cb(unsigned char *dst, int len, void *dat) +{ + (void)dat; + if (len <= 0) { + return len; + } + if (s_mp_rand_source(dst, (size_t)len) != MP_OKAY) { + return 0; + } + return len; +} + +mp_err mp_prime_rand(mp_int *a, int t, int size, int flags) +{ + return s_mp_prime_random_ex(a, t, size, flags, s_mp_rand_cb, NULL); +} + +#endif diff --git a/libtommath/bn_mp_prime_random_ex.c b/libtommath/bn_mp_prime_random_ex.c deleted file mode 100644 index cf5272e..0000000 --- a/libtommath/bn_mp_prime_random_ex.c +++ /dev/null @@ -1,124 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_PRIME_RANDOM_EX_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* makes a truly random prime of a given size (bits), - * - * Flags are as follows: - * - * LTM_PRIME_BBS - make prime congruent to 3 mod 4 - * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS) - * LTM_PRIME_2MSB_ON - make the 2nd highest bit one - * - * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can - * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself - * so it can be NULL - * - */ - -/* This is possibly the mother of all prime generation functions, muahahahahaha! */ -int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat) -{ - unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb; - int res, err, bsize, maskOR_msb_offset; - - /* sanity check the input */ - if ((size <= 1) || (t <= 0)) { - return MP_VAL; - } - - /* LTM_PRIME_SAFE implies LTM_PRIME_BBS */ - if ((flags & LTM_PRIME_SAFE) != 0) { - flags |= LTM_PRIME_BBS; - } - - /* calc the byte size */ - bsize = (size>>3) + ((size&7)?1:0); - - /* we need a buffer of bsize bytes */ - tmp = OPT_CAST(unsigned char) XMALLOC(bsize); - if (tmp == NULL) { - return MP_MEM; - } - - /* calc the maskAND value for the MSbyte*/ - maskAND = ((size&7) == 0) ? 0xFF : (0xFF >> (8 - (size & 7))); - - /* calc the maskOR_msb */ - maskOR_msb = 0; - maskOR_msb_offset = ((size & 7) == 1) ? 1 : 0; - if ((flags & LTM_PRIME_2MSB_ON) != 0) { - maskOR_msb |= 0x80 >> ((9 - size) & 7); - } - - /* get the maskOR_lsb */ - maskOR_lsb = 1; - if ((flags & LTM_PRIME_BBS) != 0) { - maskOR_lsb |= 3; - } - - do { - /* read the bytes */ - if (cb(tmp, bsize, dat) != bsize) { - err = MP_VAL; - goto error; - } - - /* work over the MSbyte */ - tmp[0] &= maskAND; - tmp[0] |= 1 << ((size - 1) & 7); - - /* mix in the maskORs */ - tmp[maskOR_msb_offset] |= maskOR_msb; - tmp[bsize-1] |= maskOR_lsb; - - /* read it in */ - if ((err = mp_read_unsigned_bin(a, tmp, bsize)) != MP_OKAY) { goto error; } - - /* is it prime? */ - if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; } - if (res == MP_NO) { - continue; - } - - if ((flags & LTM_PRIME_SAFE) != 0) { - /* see if (a-1)/2 is prime */ - if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { goto error; } - if ((err = mp_div_2(a, a)) != MP_OKAY) { goto error; } - - /* is it prime? */ - if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; } - } - } while (res == MP_NO); - - if ((flags & LTM_PRIME_SAFE) != 0) { - /* restore a to the original value */ - if ((err = mp_mul_2(a, a)) != MP_OKAY) { goto error; } - if ((err = mp_add_d(a, 1, a)) != MP_OKAY) { goto error; } - } - - err = MP_OKAY; -error: - XFREE(tmp); - return err; -} - - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_prime_strong_lucas_selfridge.c b/libtommath/bn_mp_prime_strong_lucas_selfridge.c new file mode 100644 index 0000000..b50bbcd --- /dev/null +++ b/libtommath/bn_mp_prime_strong_lucas_selfridge.c @@ -0,0 +1,289 @@ +#include "tommath_private.h" +#ifdef BN_MP_PRIME_STRONG_LUCAS_SELFRIDGE_C + +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* + * See file bn_mp_prime_is_prime.c or the documentation in doc/bn.tex for the details + */ +#ifndef LTM_USE_ONLY_MR + +/* + * 8-bit is just too small. You can try the Frobenius test + * but that frobenius test can fail, too, for the same reason. + */ +#ifndef MP_8BIT + +/* + * multiply bigint a with int d and put the result in c + * Like mp_mul_d() but with a signed long as the small input + */ +static mp_err s_mp_mul_si(const mp_int *a, int32_t d, mp_int *c) +{ + mp_int t; + mp_err err; + + if ((err = mp_init(&t)) != MP_OKAY) { + return err; + } + + /* + * mp_digit might be smaller than a long, which excludes + * the use of mp_mul_d() here. + */ + mp_set_i32(&t, d); + err = mp_mul(a, &t, c); + mp_clear(&t); + return err; +} +/* + Strong Lucas-Selfridge test. + returns MP_YES if it is a strong L-S prime, MP_NO if it is composite + + Code ported from Thomas Ray Nicely's implementation of the BPSW test + at http://www.trnicely.net/misc/bpsw.html + + Freeware copyright (C) 2016 Thomas R. Nicely <http://www.trnicely.net>. + Released into the public domain by the author, who disclaims any legal + liability arising from its use + + The multi-line comments are made by Thomas R. Nicely and are copied verbatim. + Additional comments marked "CZ" (without the quotes) are by the code-portist. + + (If that name sounds familiar, he is the guy who found the fdiv bug in the + Pentium (P5x, I think) Intel processor) +*/ +mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result) +{ + /* CZ TODO: choose better variable names! */ + mp_int Dz, gcd, Np1, Uz, Vz, U2mz, V2mz, Qmz, Q2mz, Qkdz, T1z, T2z, T3z, T4z, Q2kdz; + /* CZ TODO: Some of them need the full 32 bit, hence the (temporary) exclusion of MP_8BIT */ + int32_t D, Ds, J, sign, P, Q, r, s, u, Nbits; + mp_err err; + mp_bool oddness; + + *result = MP_NO; + /* + Find the first element D in the sequence {5, -7, 9, -11, 13, ...} + such that Jacobi(D,N) = -1 (Selfridge's algorithm). Theory + indicates that, if N is not a perfect square, D will "nearly + always" be "small." Just in case, an overflow trap for D is + included. + */ + + if ((err = mp_init_multi(&Dz, &gcd, &Np1, &Uz, &Vz, &U2mz, &V2mz, &Qmz, &Q2mz, &Qkdz, &T1z, &T2z, &T3z, &T4z, &Q2kdz, + NULL)) != MP_OKAY) { + return err; + } + + D = 5; + sign = 1; + + for (;;) { + Ds = sign * D; + sign = -sign; + mp_set_u32(&Dz, (uint32_t)D); + if ((err = mp_gcd(a, &Dz, &gcd)) != MP_OKAY) goto LBL_LS_ERR; + + /* if 1 < GCD < N then N is composite with factor "D", and + Jacobi(D,N) is technically undefined (but often returned + as zero). */ + if ((mp_cmp_d(&gcd, 1uL) == MP_GT) && (mp_cmp(&gcd, a) == MP_LT)) { + goto LBL_LS_ERR; + } + if (Ds < 0) { + Dz.sign = MP_NEG; + } + if ((err = mp_kronecker(&Dz, a, &J)) != MP_OKAY) goto LBL_LS_ERR; + + if (J == -1) { + break; + } + D += 2; + + if (D > (INT_MAX - 2)) { + err = MP_VAL; + goto LBL_LS_ERR; + } + } + + + + P = 1; /* Selfridge's choice */ + Q = (1 - Ds) / 4; /* Required so D = P*P - 4*Q */ + + /* NOTE: The conditions (a) N does not divide Q, and + (b) D is square-free or not a perfect square, are included by + some authors; e.g., "Prime numbers and computer methods for + factorization," Hans Riesel (2nd ed., 1994, Birkhauser, Boston), + p. 130. For this particular application of Lucas sequences, + these conditions were found to be immaterial. */ + + /* Now calculate N - Jacobi(D,N) = N + 1 (even), and calculate the + odd positive integer d and positive integer s for which + N + 1 = 2^s*d (similar to the step for N - 1 in Miller's test). + The strong Lucas-Selfridge test then returns N as a strong + Lucas probable prime (slprp) if any of the following + conditions is met: U_d=0, V_d=0, V_2d=0, V_4d=0, V_8d=0, + V_16d=0, ..., etc., ending with V_{2^(s-1)*d}=V_{(N+1)/2}=0 + (all equalities mod N). Thus d is the highest index of U that + must be computed (since V_2m is independent of U), compared + to U_{N+1} for the standard Lucas-Selfridge test; and no + index of V beyond (N+1)/2 is required, just as in the + standard Lucas-Selfridge test. However, the quantity Q^d must + be computed for use (if necessary) in the latter stages of + the test. The result is that the strong Lucas-Selfridge test + has a running time only slightly greater (order of 10 %) than + that of the standard Lucas-Selfridge test, while producing + only (roughly) 30 % as many pseudoprimes (and every strong + Lucas pseudoprime is also a standard Lucas pseudoprime). Thus + the evidence indicates that the strong Lucas-Selfridge test is + more effective than the standard Lucas-Selfridge test, and a + Baillie-PSW test based on the strong Lucas-Selfridge test + should be more reliable. */ + + if ((err = mp_add_d(a, 1uL, &Np1)) != MP_OKAY) goto LBL_LS_ERR; + s = mp_cnt_lsb(&Np1); + + /* CZ + * This should round towards zero because + * Thomas R. Nicely used GMP's mpz_tdiv_q_2exp() + * and mp_div_2d() is equivalent. Additionally: + * dividing an even number by two does not produce + * any leftovers. + */ + if ((err = mp_div_2d(&Np1, s, &Dz, NULL)) != MP_OKAY) goto LBL_LS_ERR; + /* We must now compute U_d and V_d. Since d is odd, the accumulated + values U and V are initialized to U_1 and V_1 (if the target + index were even, U and V would be initialized instead to U_0=0 + and V_0=2). The values of U_2m and V_2m are also initialized to + U_1 and V_1; the FOR loop calculates in succession U_2 and V_2, + U_4 and V_4, U_8 and V_8, etc. If the corresponding bits + (1, 2, 3, ...) of t are on (the zero bit having been accounted + for in the initialization of U and V), these values are then + combined with the previous totals for U and V, using the + composition formulas for addition of indices. */ + + mp_set(&Uz, 1uL); /* U=U_1 */ + mp_set(&Vz, (mp_digit)P); /* V=V_1 */ + mp_set(&U2mz, 1uL); /* U_1 */ + mp_set(&V2mz, (mp_digit)P); /* V_1 */ + + mp_set_i32(&Qmz, Q); + if ((err = mp_mul_2(&Qmz, &Q2mz)) != MP_OKAY) goto LBL_LS_ERR; + /* Initializes calculation of Q^d */ + mp_set_i32(&Qkdz, Q); + + Nbits = mp_count_bits(&Dz); + + for (u = 1; u < Nbits; u++) { /* zero bit off, already accounted for */ + /* Formulas for doubling of indices (carried out mod N). Note that + * the indices denoted as "2m" are actually powers of 2, specifically + * 2^(ul-1) beginning each loop and 2^ul ending each loop. + * + * U_2m = U_m*V_m + * V_2m = V_m*V_m - 2*Q^m + */ + + if ((err = mp_mul(&U2mz, &V2mz, &U2mz)) != MP_OKAY) goto LBL_LS_ERR; + if ((err = mp_mod(&U2mz, a, &U2mz)) != MP_OKAY) goto LBL_LS_ERR; + if ((err = mp_sqr(&V2mz, &V2mz)) != MP_OKAY) goto LBL_LS_ERR; + if ((err = mp_sub(&V2mz, &Q2mz, &V2mz)) != MP_OKAY) goto LBL_LS_ERR; + if ((err = mp_mod(&V2mz, a, &V2mz)) != MP_OKAY) goto LBL_LS_ERR; + + /* Must calculate powers of Q for use in V_2m, also for Q^d later */ + if ((err = mp_sqr(&Qmz, &Qmz)) != MP_OKAY) goto LBL_LS_ERR; + + /* prevents overflow */ /* CZ still necessary without a fixed prealloc'd mem.? */ + if ((err = mp_mod(&Qmz, a, &Qmz)) != MP_OKAY) goto LBL_LS_ERR; + if ((err = mp_mul_2(&Qmz, &Q2mz)) != MP_OKAY) goto LBL_LS_ERR; + + if (s_mp_get_bit(&Dz, (unsigned int)u) == MP_YES) { + /* Formulas for addition of indices (carried out mod N); + * + * U_(m+n) = (U_m*V_n + U_n*V_m)/2 + * V_(m+n) = (V_m*V_n + D*U_m*U_n)/2 + * + * Be careful with division by 2 (mod N)! + */ + if ((err = mp_mul(&U2mz, &Vz, &T1z)) != MP_OKAY) goto LBL_LS_ERR; + if ((err = mp_mul(&Uz, &V2mz, &T2z)) != MP_OKAY) goto LBL_LS_ERR; + if ((err = mp_mul(&V2mz, &Vz, &T3z)) != MP_OKAY) goto LBL_LS_ERR; + if ((err = mp_mul(&U2mz, &Uz, &T4z)) != MP_OKAY) goto LBL_LS_ERR; + if ((err = s_mp_mul_si(&T4z, Ds, &T4z)) != MP_OKAY) goto LBL_LS_ERR; + if ((err = mp_add(&T1z, &T2z, &Uz)) != MP_OKAY) goto LBL_LS_ERR; + if (MP_IS_ODD(&Uz)) { + if ((err = mp_add(&Uz, a, &Uz)) != MP_OKAY) goto LBL_LS_ERR; + } + /* CZ + * This should round towards negative infinity because + * Thomas R. Nicely used GMP's mpz_fdiv_q_2exp(). + * But mp_div_2() does not do so, it is truncating instead. + */ + oddness = MP_IS_ODD(&Uz) ? MP_YES : MP_NO; + if ((err = mp_div_2(&Uz, &Uz)) != MP_OKAY) goto LBL_LS_ERR; + if ((Uz.sign == MP_NEG) && (oddness != MP_NO)) { + if ((err = mp_sub_d(&Uz, 1uL, &Uz)) != MP_OKAY) goto LBL_LS_ERR; + } + if ((err = mp_add(&T3z, &T4z, &Vz)) != MP_OKAY) goto LBL_LS_ERR; + if (MP_IS_ODD(&Vz)) { + if ((err = mp_add(&Vz, a, &Vz)) != MP_OKAY) goto LBL_LS_ERR; + } + oddness = MP_IS_ODD(&Vz) ? MP_YES : MP_NO; + if ((err = mp_div_2(&Vz, &Vz)) != MP_OKAY) goto LBL_LS_ERR; + if ((Vz.sign == MP_NEG) && (oddness != MP_NO)) { + if ((err = mp_sub_d(&Vz, 1uL, &Vz)) != MP_OKAY) goto LBL_LS_ERR; + } + if ((err = mp_mod(&Uz, a, &Uz)) != MP_OKAY) goto LBL_LS_ERR; + if ((err = mp_mod(&Vz, a, &Vz)) != MP_OKAY) goto LBL_LS_ERR; + + /* Calculating Q^d for later use */ + if ((err = mp_mul(&Qkdz, &Qmz, &Qkdz)) != MP_OKAY) goto LBL_LS_ERR; + if ((err = mp_mod(&Qkdz, a, &Qkdz)) != MP_OKAY) goto LBL_LS_ERR; + } + } + + /* If U_d or V_d is congruent to 0 mod N, then N is a prime or a + strong Lucas pseudoprime. */ + if (MP_IS_ZERO(&Uz) || MP_IS_ZERO(&Vz)) { + *result = MP_YES; + goto LBL_LS_ERR; + } + + /* NOTE: Ribenboim ("The new book of prime number records," 3rd ed., + 1995/6) omits the condition V0 on p.142, but includes it on + p. 130. The condition is NECESSARY; otherwise the test will + return false negatives---e.g., the primes 29 and 2000029 will be + returned as composite. */ + + /* Otherwise, we must compute V_2d, V_4d, V_8d, ..., V_{2^(s-1)*d} + by repeated use of the formula V_2m = V_m*V_m - 2*Q^m. If any of + these are congruent to 0 mod N, then N is a prime or a strong + Lucas pseudoprime. */ + + /* Initialize 2*Q^(d*2^r) for V_2m */ + if ((err = mp_mul_2(&Qkdz, &Q2kdz)) != MP_OKAY) goto LBL_LS_ERR; + + for (r = 1; r < s; r++) { + if ((err = mp_sqr(&Vz, &Vz)) != MP_OKAY) goto LBL_LS_ERR; + if ((err = mp_sub(&Vz, &Q2kdz, &Vz)) != MP_OKAY) goto LBL_LS_ERR; + if ((err = mp_mod(&Vz, a, &Vz)) != MP_OKAY) goto LBL_LS_ERR; + if (MP_IS_ZERO(&Vz)) { + *result = MP_YES; + goto LBL_LS_ERR; + } + /* Calculate Q^{d*2^r} for next r (final iteration irrelevant). */ + if (r < (s - 1)) { + if ((err = mp_sqr(&Qkdz, &Qkdz)) != MP_OKAY) goto LBL_LS_ERR; + if ((err = mp_mod(&Qkdz, a, &Qkdz)) != MP_OKAY) goto LBL_LS_ERR; + if ((err = mp_mul_2(&Qkdz, &Q2kdz)) != MP_OKAY) goto LBL_LS_ERR; + } + } +LBL_LS_ERR: + mp_clear_multi(&Q2kdz, &T4z, &T3z, &T2z, &T1z, &Qkdz, &Q2mz, &Qmz, &V2mz, &U2mz, &Vz, &Uz, &Np1, &gcd, &Dz, NULL); + return err; +} +#endif +#endif +#endif diff --git a/libtommath/bn_mp_radix_size.c b/libtommath/bn_mp_radix_size.c index cb0c134..b96f487 100644 --- a/libtommath/bn_mp_radix_size.c +++ b/libtommath/bn_mp_radix_size.c @@ -1,78 +1,65 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_RADIX_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ -/* returns size of ASCII reprensentation */ -int mp_radix_size (mp_int * a, int radix, int *size) +/* returns size of ASCII representation */ +mp_err mp_radix_size(const mp_int *a, int radix, int *size) { - int res, digs; - mp_int t; - mp_digit d; + mp_err err; + int digs; + mp_int t; + mp_digit d; - *size = 0; + *size = 0; - /* make sure the radix is in range */ - if ((radix < 2) || (radix > 64)) { - return MP_VAL; - } + /* make sure the radix is in range */ + if ((radix < 2) || (radix > 64)) { + return MP_VAL; + } - if (mp_iszero(a) == MP_YES) { - *size = 2; - return MP_OKAY; - } + if (MP_IS_ZERO(a)) { + *size = 2; + return MP_OKAY; + } - /* special case for binary */ - if (radix == 2) { - *size = mp_count_bits (a) + ((a->sign == MP_NEG) ? 1 : 0) + 1; - return MP_OKAY; - } + /* special case for binary */ + if (radix == 2) { + *size = (mp_count_bits(a) + ((a->sign == MP_NEG) ? 1 : 0) + 1); + return MP_OKAY; + } - /* digs is the digit count */ - digs = 0; + /* digs is the digit count */ + digs = 0; - /* if it's negative add one for the sign */ - if (a->sign == MP_NEG) { - ++digs; - } + /* if it's negative add one for the sign */ + if (a->sign == MP_NEG) { + ++digs; + } - /* init a copy of the input */ - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } + /* init a copy of the input */ + if ((err = mp_init_copy(&t, a)) != MP_OKAY) { + return err; + } - /* force temp to positive */ - t.sign = MP_ZPOS; + /* force temp to positive */ + t.sign = MP_ZPOS; - /* fetch out all of the digits */ - while (mp_iszero (&t) == MP_NO) { - if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { - mp_clear (&t); - return res; - } - ++digs; - } - mp_clear (&t); + /* fetch out all of the digits */ + while (!MP_IS_ZERO(&t)) { + if ((err = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) { + goto LBL_ERR; + } + ++digs; + } - /* return digs + 1, the 1 is for the NULL byte that would be required. */ - *size = digs + 1; - return MP_OKAY; + /* return digs + 1, the 1 is for the NULL byte that would be required. */ + *size = digs + 1; + err = MP_OKAY; + +LBL_ERR: + mp_clear(&t); + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_radix_smap.c b/libtommath/bn_mp_radix_smap.c index 4c6e57c..a16128d 100644 --- a/libtommath/bn_mp_radix_smap.c +++ b/libtommath/bn_mp_radix_smap.c @@ -1,24 +1,22 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_RADIX_SMAP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* chars used in radix conversions */ -const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; +const char *const mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; +const uint8_t mp_s_rmap_reverse[] = { + 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, /* ()*+,-./ */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 01234567 */ + 0x08, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 89:;<=>? */ + 0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, /* @ABCDEFG */ + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, /* HIJKLMNO */ + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, /* PQRSTUVW */ + 0x21, 0x22, 0x23, 0xff, 0xff, 0xff, 0xff, 0xff, /* XYZ[\]^_ */ + 0xff, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, /* `abcdefg */ + 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, /* hijklmno */ + 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, /* pqrstuvw */ + 0x3b, 0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, /* xyz{|}~. */ +}; +const size_t mp_s_rmap_reverse_sz = sizeof(mp_s_rmap_reverse); #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_rand.c b/libtommath/bn_mp_rand.c index 93e255a..7e9052c 100644 --- a/libtommath/bn_mp_rand.c +++ b/libtommath/bn_mp_rand.c @@ -1,80 +1,46 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_RAND_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ -#if MP_GEN_RANDOM_MAX == 0xffffffff - #define MP_GEN_RANDOM_SHIFT 32 -#elif MP_GEN_RANDOM_MAX == 32767 - /* SHRT_MAX */ - #define MP_GEN_RANDOM_SHIFT 15 -#elif MP_GEN_RANDOM_MAX == 2147483647 - /* INT_MAX */ - #define MP_GEN_RANDOM_SHIFT 31 -#elif !defined(MP_GEN_RANDOM_SHIFT) -#error Thou shalt define their own valid MP_GEN_RANDOM_SHIFT -#endif +mp_err(*s_mp_rand_source)(void *out, size_t size) = s_mp_rand_platform; -/* makes a pseudo-random int of a given size */ -static mp_digit s_gen_random(void) +void mp_rand_source(mp_err(*source)(void *out, size_t size)) { - mp_digit d = 0, msk = 0; - do { - d <<= MP_GEN_RANDOM_SHIFT; - d |= ((mp_digit) MP_GEN_RANDOM()); - msk <<= MP_GEN_RANDOM_SHIFT; - msk |= (MP_MASK & MP_GEN_RANDOM_MAX); - } while ((MP_MASK & msk) != MP_MASK); - d &= MP_MASK; - return d; + s_mp_rand_source = (source == NULL) ? s_mp_rand_platform : source; } -int -mp_rand (mp_int * a, int digits) +mp_err mp_rand(mp_int *a, int digits) { - int res; - mp_digit d; + int i; + mp_err err; + + mp_zero(a); - mp_zero (a); - if (digits <= 0) { - return MP_OKAY; - } + if (digits <= 0) { + return MP_OKAY; + } - /* first place a random non-zero digit */ - do { - d = s_gen_random(); - } while (d == 0); + if ((err = mp_grow(a, digits)) != MP_OKAY) { + return err; + } - if ((res = mp_add_d (a, d, a)) != MP_OKAY) { - return res; - } + if ((err = s_mp_rand_source(a->dp, (size_t)digits * sizeof(mp_digit))) != MP_OKAY) { + return err; + } - while (--digits > 0) { - if ((res = mp_lshd (a, 1)) != MP_OKAY) { - return res; - } + /* TODO: We ensure that the highest digit is nonzero. Should this be removed? */ + while ((a->dp[digits - 1] & MP_MASK) == 0u) { + if ((err = s_mp_rand_source(a->dp + digits - 1, sizeof(mp_digit))) != MP_OKAY) { + return err; + } + } - if ((res = mp_add_d (a, s_gen_random(), a)) != MP_OKAY) { - return res; - } - } + a->used = digits; + for (i = 0; i < digits; ++i) { + a->dp[i] &= MP_MASK; + } - return MP_OKAY; + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_read_radix.c b/libtommath/bn_mp_read_radix.c index 5decdeb..de18e06 100644 --- a/libtommath/bn_mp_read_radix.c +++ b/libtommath/bn_mp_read_radix.c @@ -1,85 +1,79 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_READ_RADIX_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +#define MP_TOUPPER(c) ((((c) >= 'a') && ((c) <= 'z')) ? (((c) + 'A') - 'a') : (c)) /* read a string [ASCII] in a given radix */ -int mp_read_radix (mp_int * a, const char *str, int radix) +mp_err mp_read_radix(mp_int *a, const char *str, int radix) { - int y, res, neg; - char ch; + mp_err err; + int y; + mp_sign neg; + unsigned pos; + char ch; + + /* zero the digit bignum */ + mp_zero(a); - /* zero the digit bignum */ - mp_zero(a); + /* make sure the radix is ok */ + if ((radix < 2) || (radix > 64)) { + return MP_VAL; + } - /* make sure the radix is ok */ - if ((radix < 2) || (radix > 64)) { - return MP_VAL; - } + /* if the leading digit is a + * minus set the sign to negative. + */ + if (*str == '-') { + ++str; + neg = MP_NEG; + } else { + neg = MP_ZPOS; + } - /* if the leading digit is a - * minus set the sign to negative. - */ - if (*str == '-') { - ++str; - neg = MP_NEG; - } else { - neg = MP_ZPOS; - } + /* set the integer to the default of zero */ + mp_zero(a); - /* set the integer to the default of zero */ - mp_zero (a); - - /* process each digit of the string */ - while (*str != '\0') { - /* if the radix <= 36 the conversion is case insensitive - * this allows numbers like 1AB and 1ab to represent the same value - * [e.g. in hex] - */ - ch = (radix <= 36) ? (char)toupper((int)*str) : *str; - for (y = 0; y < 64; y++) { - if (ch == mp_s_rmap[y]) { + /* process each digit of the string */ + while (*str != '\0') { + /* if the radix <= 36 the conversion is case insensitive + * this allows numbers like 1AB and 1ab to represent the same value + * [e.g. in hex] + */ + ch = (radix <= 36) ? (char)MP_TOUPPER((int)*str) : *str; + pos = (unsigned)(ch - '('); + if (mp_s_rmap_reverse_sz < pos) { break; } - } + y = (int)mp_s_rmap_reverse[pos]; - /* if the char was found in the map - * and is less than the given radix add it - * to the number, otherwise exit the loop. - */ - if (y < radix) { - if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) { - return res; + /* if the char was found in the map + * and is less than the given radix add it + * to the number, otherwise exit the loop. + */ + if ((y == 0xff) || (y >= radix)) { + break; + } + if ((err = mp_mul_d(a, (mp_digit)radix, a)) != MP_OKAY) { + return err; } - if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) { - return res; + if ((err = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) { + return err; } - } else { - break; - } - ++str; - } - - /* set the sign only if a != 0 */ - if (mp_iszero(a) != MP_YES) { - a->sign = neg; - } - return MP_OKAY; + ++str; + } + + /* if an illegal character was found, fail. */ + if (!((*str == '\0') || (*str == '\r') || (*str == '\n'))) { + mp_zero(a); + return MP_VAL; + } + + /* set the sign only if a != 0 */ + if (!MP_IS_ZERO(a)) { + a->sign = neg; + } + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_read_signed_bin.c b/libtommath/bn_mp_read_signed_bin.c deleted file mode 100644 index 363e11f..0000000 --- a/libtommath/bn_mp_read_signed_bin.c +++ /dev/null @@ -1,41 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_READ_SIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* read signed bin, big endian, first byte is 0==positive or 1==negative */ -int mp_read_signed_bin (mp_int * a, const unsigned char *b, int c) -{ - int res; - - /* read magnitude */ - if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) { - return res; - } - - /* first byte is 0 for positive, non-zero for negative */ - if (b[0] == 0) { - a->sign = MP_ZPOS; - } else { - a->sign = MP_NEG; - } - - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_read_unsigned_bin.c b/libtommath/bn_mp_read_unsigned_bin.c deleted file mode 100644 index 1a50b58..0000000 --- a/libtommath/bn_mp_read_unsigned_bin.c +++ /dev/null @@ -1,55 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_READ_UNSIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* reads a unsigned char array, assumes the msb is stored first [big endian] */ -int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c) -{ - int res; - - /* make sure there are at least two digits */ - if (a->alloc < 2) { - if ((res = mp_grow(a, 2)) != MP_OKAY) { - return res; - } - } - - /* zero the int */ - mp_zero (a); - - /* read the bytes in */ - while (c-- > 0) { - if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) { - return res; - } - -#ifndef MP_8BIT - a->dp[0] |= *b++; - a->used += 1; -#else - a->dp[0] = (*b & MP_MASK); - a->dp[1] |= ((*b++ >> 7U) & 1); - a->used += 2; -#endif - } - mp_clamp (a); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_reduce.c b/libtommath/bn_mp_reduce.c index 367383f..3c669d4 100644 --- a/libtommath/bn_mp_reduce.c +++ b/libtommath/bn_mp_reduce.c @@ -1,100 +1,83 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_REDUCE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* reduces x mod m, assumes 0 < x < m**2, mu is * precomputed via mp_reduce_setup. * From HAC pp.604 Algorithm 14.42 */ -int mp_reduce (mp_int * x, mp_int * m, mp_int * mu) +mp_err mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu) { - mp_int q; - int res, um = m->used; + mp_int q; + mp_err err; + int um = m->used; - /* q = x */ - if ((res = mp_init_copy (&q, x)) != MP_OKAY) { - return res; - } + /* q = x */ + if ((err = mp_init_copy(&q, x)) != MP_OKAY) { + return err; + } - /* q1 = x / b**(k-1) */ - mp_rshd (&q, um - 1); + /* q1 = x / b**(k-1) */ + mp_rshd(&q, um - 1); - /* according to HAC this optimization is ok */ - if (((mp_digit) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) { - if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) { - goto CLEANUP; - } - } else { -#ifdef BN_S_MP_MUL_HIGH_DIGS_C - if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { - goto CLEANUP; - } -#elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) - if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { + /* according to HAC this optimization is ok */ + if ((mp_digit)um > ((mp_digit)1 << (MP_DIGIT_BIT - 1))) { + if ((err = mp_mul(&q, mu, &q)) != MP_OKAY) { + goto CLEANUP; + } + } else if (MP_HAS(S_MP_MUL_HIGH_DIGS)) { + if ((err = s_mp_mul_high_digs(&q, mu, &q, um)) != MP_OKAY) { + goto CLEANUP; + } + } else if (MP_HAS(S_MP_MUL_HIGH_DIGS_FAST)) { + if ((err = s_mp_mul_high_digs_fast(&q, mu, &q, um)) != MP_OKAY) { + goto CLEANUP; + } + } else { + err = MP_VAL; goto CLEANUP; - } -#else - { - res = MP_VAL; - goto CLEANUP; - } -#endif - } - - /* q3 = q2 / b**(k+1) */ - mp_rshd (&q, um + 1); + } - /* x = x mod b**(k+1), quick (no division) */ - if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) { - goto CLEANUP; - } + /* q3 = q2 / b**(k+1) */ + mp_rshd(&q, um + 1); - /* q = q * m mod b**(k+1), quick (no division) */ - if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) { - goto CLEANUP; - } - - /* x = x - q */ - if ((res = mp_sub (x, &q, x)) != MP_OKAY) { - goto CLEANUP; - } - - /* If x < 0, add b**(k+1) to it */ - if (mp_cmp_d (x, 0) == MP_LT) { - mp_set (&q, 1); - if ((res = mp_lshd (&q, um + 1)) != MP_OKAY) + /* x = x mod b**(k+1), quick (no division) */ + if ((err = mp_mod_2d(x, MP_DIGIT_BIT * (um + 1), x)) != MP_OKAY) { goto CLEANUP; - if ((res = mp_add (x, &q, x)) != MP_OKAY) + } + + /* q = q * m mod b**(k+1), quick (no division) */ + if ((err = s_mp_mul_digs(&q, m, &q, um + 1)) != MP_OKAY) { goto CLEANUP; - } + } - /* Back off if it's too big */ - while (mp_cmp (x, m) != MP_LT) { - if ((res = s_mp_sub (x, m, x)) != MP_OKAY) { + /* x = x - q */ + if ((err = mp_sub(x, &q, x)) != MP_OKAY) { goto CLEANUP; - } - } + } + + /* If x < 0, add b**(k+1) to it */ + if (mp_cmp_d(x, 0uL) == MP_LT) { + mp_set(&q, 1uL); + if ((err = mp_lshd(&q, um + 1)) != MP_OKAY) { + goto CLEANUP; + } + if ((err = mp_add(x, &q, x)) != MP_OKAY) { + goto CLEANUP; + } + } + + /* Back off if it's too big */ + while (mp_cmp(x, m) != MP_LT) { + if ((err = s_mp_sub(x, m, x)) != MP_OKAY) { + goto CLEANUP; + } + } CLEANUP: - mp_clear (&q); + mp_clear(&q); - return res; + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_reduce_2k.c b/libtommath/bn_mp_reduce_2k.c index 6bc96d1..1cea6cb 100644 --- a/libtommath/bn_mp_reduce_2k.c +++ b/libtommath/bn_mp_reduce_2k.c @@ -1,63 +1,48 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_REDUCE_2K_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* reduces a modulo n where n is of the form 2**p - d */ -int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d) +mp_err mp_reduce_2k(mp_int *a, const mp_int *n, mp_digit d) { mp_int q; - int p, res; + mp_err err; + int p; - if ((res = mp_init(&q)) != MP_OKAY) { - return res; + if ((err = mp_init(&q)) != MP_OKAY) { + return err; } p = mp_count_bits(n); top: /* q = a/2**p, a = a mod 2**p */ - if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { - goto ERR; + if ((err = mp_div_2d(a, p, &q, a)) != MP_OKAY) { + goto LBL_ERR; } - if (d != 1) { + if (d != 1u) { /* q = q * d */ - if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) { - goto ERR; + if ((err = mp_mul_d(&q, d, &q)) != MP_OKAY) { + goto LBL_ERR; } } /* a = a + q */ - if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { - goto ERR; + if ((err = s_mp_add(a, &q, a)) != MP_OKAY) { + goto LBL_ERR; } if (mp_cmp_mag(a, n) != MP_LT) { - if ((res = s_mp_sub(a, n, a)) != MP_OKAY) { - goto ERR; + if ((err = s_mp_sub(a, n, a)) != MP_OKAY) { + goto LBL_ERR; } goto top; } -ERR: +LBL_ERR: mp_clear(&q); - return res; + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_reduce_2k_l.c b/libtommath/bn_mp_reduce_2k_l.c index 8e6eeb0..6a9f3d3 100644 --- a/libtommath/bn_mp_reduce_2k_l.c +++ b/libtommath/bn_mp_reduce_2k_l.c @@ -1,64 +1,49 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_REDUCE_2K_L_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* reduces a modulo n where n is of the form 2**p - d This differs from reduce_2k since "d" can be larger than a single digit. */ -int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d) +mp_err mp_reduce_2k_l(mp_int *a, const mp_int *n, const mp_int *d) { mp_int q; - int p, res; + mp_err err; + int p; - if ((res = mp_init(&q)) != MP_OKAY) { - return res; + if ((err = mp_init(&q)) != MP_OKAY) { + return err; } p = mp_count_bits(n); top: /* q = a/2**p, a = a mod 2**p */ - if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { - goto ERR; + if ((err = mp_div_2d(a, p, &q, a)) != MP_OKAY) { + goto LBL_ERR; } /* q = q * d */ - if ((res = mp_mul(&q, d, &q)) != MP_OKAY) { - goto ERR; + if ((err = mp_mul(&q, d, &q)) != MP_OKAY) { + goto LBL_ERR; } /* a = a + q */ - if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { - goto ERR; + if ((err = s_mp_add(a, &q, a)) != MP_OKAY) { + goto LBL_ERR; } if (mp_cmp_mag(a, n) != MP_LT) { - if ((res = s_mp_sub(a, n, a)) != MP_OKAY) { - goto ERR; + if ((err = s_mp_sub(a, n, a)) != MP_OKAY) { + goto LBL_ERR; } goto top; } -ERR: +LBL_ERR: mp_clear(&q); - return res; + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_reduce_2k_setup.c b/libtommath/bn_mp_reduce_2k_setup.c index bf810c0..2eaf7ad 100644 --- a/libtommath/bn_mp_reduce_2k_setup.c +++ b/libtommath/bn_mp_reduce_2k_setup.c @@ -1,47 +1,32 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_REDUCE_2K_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* determines the setup value */ -int mp_reduce_2k_setup(mp_int *a, mp_digit *d) +mp_err mp_reduce_2k_setup(const mp_int *a, mp_digit *d) { - int res, p; + mp_err err; mp_int tmp; - - if ((res = mp_init(&tmp)) != MP_OKAY) { - return res; + int p; + + if ((err = mp_init(&tmp)) != MP_OKAY) { + return err; } - + p = mp_count_bits(a); - if ((res = mp_2expt(&tmp, p)) != MP_OKAY) { + if ((err = mp_2expt(&tmp, p)) != MP_OKAY) { mp_clear(&tmp); - return res; + return err; } - - if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) { + + if ((err = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) { mp_clear(&tmp); - return res; + return err; } - + *d = tmp.dp[0]; mp_clear(&tmp); return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_reduce_2k_setup_l.c b/libtommath/bn_mp_reduce_2k_setup_l.c index 56d1ba8..4f9aa14 100644 --- a/libtommath/bn_mp_reduce_2k_setup_l.c +++ b/libtommath/bn_mp_reduce_2k_setup_l.c @@ -1,44 +1,28 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_REDUCE_2K_SETUP_L_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* determines the setup value */ -int mp_reduce_2k_setup_l(mp_int *a, mp_int *d) +mp_err mp_reduce_2k_setup_l(const mp_int *a, mp_int *d) { - int res; + mp_err err; mp_int tmp; - - if ((res = mp_init(&tmp)) != MP_OKAY) { - return res; + + if ((err = mp_init(&tmp)) != MP_OKAY) { + return err; } - - if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) { - goto ERR; + + if ((err = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) { + goto LBL_ERR; } - - if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) { - goto ERR; + + if ((err = s_mp_sub(&tmp, a, d)) != MP_OKAY) { + goto LBL_ERR; } - -ERR: + +LBL_ERR: mp_clear(&tmp); - return res; + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_reduce_is_2k.c b/libtommath/bn_mp_reduce_is_2k.c index 0499e83..a9f4f9f 100644 --- a/libtommath/bn_mp_reduce_is_2k.c +++ b/libtommath/bn_mp_reduce_is_2k.c @@ -1,26 +1,14 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_REDUCE_IS_2K_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* determines if mp_reduce_2k can be used */ -int mp_reduce_is_2k(mp_int *a) +mp_bool mp_reduce_is_2k(const mp_int *a) { int ix, iy, iw; mp_digit iz; - + if (a->used == 0) { return MP_NO; } else if (a->used == 1) { @@ -29,24 +17,22 @@ int mp_reduce_is_2k(mp_int *a) iy = mp_count_bits(a); iz = 1; iw = 1; - + /* Test every bit from the second digit up, must be 1 */ - for (ix = DIGIT_BIT; ix < iy; ix++) { - if ((a->dp[iw] & iz) == 0) { - return MP_NO; - } - iz <<= 1; - if (iz > (mp_digit)MP_MASK) { - ++iw; - iz = 1; - } + for (ix = MP_DIGIT_BIT; ix < iy; ix++) { + if ((a->dp[iw] & iz) == 0u) { + return MP_NO; + } + iz <<= 1; + if (iz > MP_DIGIT_MAX) { + ++iw; + iz = 1; + } } + return MP_YES; + } else { + return MP_YES; } - return MP_YES; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_reduce_is_2k_l.c b/libtommath/bn_mp_reduce_is_2k_l.c index 48b3498..4bc69be 100644 --- a/libtommath/bn_mp_reduce_is_2k_l.c +++ b/libtommath/bn_mp_reduce_is_2k_l.c @@ -1,25 +1,13 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_REDUCE_IS_2K_L_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* determines if reduce_2k_l can be used */ -int mp_reduce_is_2k_l(mp_int *a) +mp_bool mp_reduce_is_2k_l(const mp_int *a) { int ix, iy; - + if (a->used == 0) { return MP_NO; } else if (a->used == 1) { @@ -27,18 +15,14 @@ int mp_reduce_is_2k_l(mp_int *a) } else if (a->used > 1) { /* if more than half of the digits are -1 we're sold */ for (iy = ix = 0; ix < a->used; ix++) { - if (a->dp[ix] == MP_MASK) { - ++iy; - } + if (a->dp[ix] == MP_DIGIT_MAX) { + ++iy; + } } return (iy >= (a->used/2)) ? MP_YES : MP_NO; - + } else { + return MP_NO; } - return MP_NO; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_reduce_setup.c b/libtommath/bn_mp_reduce_setup.c index 8875698..f02160f 100644 --- a/libtommath/bn_mp_reduce_setup.c +++ b/libtommath/bn_mp_reduce_setup.c @@ -1,34 +1,17 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_REDUCE_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* pre-calculate the value required for Barrett reduction * For a given modulus "b" it calulates the value required in "a" */ -int mp_reduce_setup (mp_int * a, mp_int * b) +mp_err mp_reduce_setup(mp_int *a, const mp_int *b) { - int res; - - if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) { - return res; - } - return mp_div (a, b, a, NULL); + mp_err err; + if ((err = mp_2expt(a, b->used * 2 * MP_DIGIT_BIT)) != MP_OKAY) { + return err; + } + return mp_div(a, b, a, NULL); } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_root_u32.c b/libtommath/bn_mp_root_u32.c new file mode 100644 index 0000000..ba65549 --- /dev/null +++ b/libtommath/bn_mp_root_u32.c @@ -0,0 +1,139 @@ +#include "tommath_private.h" +#ifdef BN_MP_ROOT_U32_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* find the n'th root of an integer + * + * Result found such that (c)**b <= a and (c+1)**b > a + * + * This algorithm uses Newton's approximation + * x[i+1] = x[i] - f(x[i])/f'(x[i]) + * which will find the root in log(N) time where + * each step involves a fair bit. + */ +mp_err mp_root_u32(const mp_int *a, uint32_t b, mp_int *c) +{ + mp_int t1, t2, t3, a_; + mp_ord cmp; + int ilog2; + mp_err err; + + /* input must be positive if b is even */ + if (((b & 1u) == 0u) && (a->sign == MP_NEG)) { + return MP_VAL; + } + + if ((err = mp_init_multi(&t1, &t2, &t3, NULL)) != MP_OKAY) { + return err; + } + + /* if a is negative fudge the sign but keep track */ + a_ = *a; + a_.sign = MP_ZPOS; + + /* Compute seed: 2^(log_2(n)/b + 2)*/ + ilog2 = mp_count_bits(a); + + /* + If "b" is larger than INT_MAX it is also larger than + log_2(n) because the bit-length of the "n" is measured + with an int and hence the root is always < 2 (two). + */ + if (b > (uint32_t)(INT_MAX/2)) { + mp_set(c, 1uL); + c->sign = a->sign; + err = MP_OKAY; + goto LBL_ERR; + } + + /* "b" is smaller than INT_MAX, we can cast safely */ + if (ilog2 < (int)b) { + mp_set(c, 1uL); + c->sign = a->sign; + err = MP_OKAY; + goto LBL_ERR; + } + ilog2 = ilog2 / ((int)b); + if (ilog2 == 0) { + mp_set(c, 1uL); + c->sign = a->sign; + err = MP_OKAY; + goto LBL_ERR; + } + /* Start value must be larger than root */ + ilog2 += 2; + if ((err = mp_2expt(&t2,ilog2)) != MP_OKAY) goto LBL_ERR; + do { + /* t1 = t2 */ + if ((err = mp_copy(&t2, &t1)) != MP_OKAY) goto LBL_ERR; + + /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */ + + /* t3 = t1**(b-1) */ + if ((err = mp_expt_u32(&t1, b - 1u, &t3)) != MP_OKAY) goto LBL_ERR; + + /* numerator */ + /* t2 = t1**b */ + if ((err = mp_mul(&t3, &t1, &t2)) != MP_OKAY) goto LBL_ERR; + + /* t2 = t1**b - a */ + if ((err = mp_sub(&t2, &a_, &t2)) != MP_OKAY) goto LBL_ERR; + + /* denominator */ + /* t3 = t1**(b-1) * b */ + if ((err = mp_mul_d(&t3, b, &t3)) != MP_OKAY) goto LBL_ERR; + + /* t3 = (t1**b - a)/(b * t1**(b-1)) */ + if ((err = mp_div(&t2, &t3, &t3, NULL)) != MP_OKAY) goto LBL_ERR; + + if ((err = mp_sub(&t1, &t3, &t2)) != MP_OKAY) goto LBL_ERR; + + /* + Number of rounds is at most log_2(root). If it is more it + got stuck, so break out of the loop and do the rest manually. + */ + if (ilog2-- == 0) { + break; + } + } while (mp_cmp(&t1, &t2) != MP_EQ); + + /* result can be off by a few so check */ + /* Loop beneath can overshoot by one if found root is smaller than actual root */ + for (;;) { + if ((err = mp_expt_u32(&t1, b, &t2)) != MP_OKAY) goto LBL_ERR; + cmp = mp_cmp(&t2, &a_); + if (cmp == MP_EQ) { + err = MP_OKAY; + goto LBL_ERR; + } + if (cmp == MP_LT) { + if ((err = mp_add_d(&t1, 1uL, &t1)) != MP_OKAY) goto LBL_ERR; + } else { + break; + } + } + /* correct overshoot from above or from recurrence */ + for (;;) { + if ((err = mp_expt_u32(&t1, b, &t2)) != MP_OKAY) goto LBL_ERR; + if (mp_cmp(&t2, &a_) == MP_GT) { + if ((err = mp_sub_d(&t1, 1uL, &t1)) != MP_OKAY) goto LBL_ERR; + } else { + break; + } + } + + /* set the result */ + mp_exch(&t1, c); + + /* set the sign of the result */ + c->sign = a->sign; + + err = MP_OKAY; + +LBL_ERR: + mp_clear_multi(&t1, &t2, &t3, NULL); + return err; +} + +#endif diff --git a/libtommath/bn_mp_rshd.c b/libtommath/bn_mp_rshd.c index 4b598de..bb8743e 100644 --- a/libtommath/bn_mp_rshd.c +++ b/libtommath/bn_mp_rshd.c @@ -1,72 +1,51 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_RSHD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* shift right a certain amount of digits */ -void mp_rshd (mp_int * a, int b) +void mp_rshd(mp_int *a, int b) { - int x; - - /* if b <= 0 then ignore it */ - if (b <= 0) { - return; - } - - /* if b > used then simply zero it and return */ - if (a->used <= b) { - mp_zero (a); - return; - } - - { - mp_digit *bottom, *top; - - /* shift the digits down */ - - /* bottom */ - bottom = a->dp; - - /* top [offset into digits] */ - top = a->dp + b; - - /* this is implemented as a sliding window where - * the window is b-digits long and digits from - * the top of the window are copied to the bottom - * - * e.g. - - b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> - /\ | ----> - \-------------------/ ----> - */ - for (x = 0; x < (a->used - b); x++) { + int x; + mp_digit *bottom, *top; + + /* if b <= 0 then ignore it */ + if (b <= 0) { + return; + } + + /* if b > used then simply zero it and return */ + if (a->used <= b) { + mp_zero(a); + return; + } + + /* shift the digits down */ + + /* bottom */ + bottom = a->dp; + + /* top [offset into digits] */ + top = a->dp + b; + + /* this is implemented as a sliding window where + * the window is b-digits long and digits from + * the top of the window are copied to the bottom + * + * e.g. + + b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> + /\ | ----> + \-------------------/ ----> + */ + for (x = 0; x < (a->used - b); x++) { *bottom++ = *top++; - } + } - /* zero the top digits */ - for (; x < a->used; x++) { - *bottom++ = 0; - } - } - - /* remove excess digits */ - a->used -= b; + /* zero the top digits */ + MP_ZERO_DIGITS(bottom, a->used - x); + + /* remove excess digits */ + a->used -= b; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_sbin_size.c b/libtommath/bn_mp_sbin_size.c new file mode 100644 index 0000000..e0993d6 --- /dev/null +++ b/libtommath/bn_mp_sbin_size.c @@ -0,0 +1,11 @@ +#include "tommath_private.h" +#ifdef BN_MP_SBIN_SIZE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* get the size for an signed equivalent */ +size_t mp_sbin_size(const mp_int *a) +{ + return 1u + mp_ubin_size(a); +} +#endif diff --git a/libtommath/bn_mp_set.c b/libtommath/bn_mp_set.c index dd4de3c..44ac6df 100644 --- a/libtommath/bn_mp_set.c +++ b/libtommath/bn_mp_set.c @@ -1,29 +1,14 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_SET_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* set to a digit */ -void mp_set (mp_int * a, mp_digit b) +void mp_set(mp_int *a, mp_digit b) { - mp_zero (a); - a->dp[0] = b & MP_MASK; - a->used = (a->dp[0] != 0) ? 1 : 0; + a->dp[0] = b & MP_MASK; + a->sign = MP_ZPOS; + a->used = (a->dp[0] != 0u) ? 1 : 0; + MP_ZERO_DIGITS(a->dp + a->used, a->alloc - a->used); } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_set_i32.c b/libtommath/bn_mp_set_i32.c new file mode 100644 index 0000000..df4513d --- /dev/null +++ b/libtommath/bn_mp_set_i32.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_SET_I32_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_SET_SIGNED(mp_set_i32, mp_set_u32, int32_t, uint32_t) +#endif diff --git a/libtommath/bn_mp_set_i64.c b/libtommath/bn_mp_set_i64.c new file mode 100644 index 0000000..395103b --- /dev/null +++ b/libtommath/bn_mp_set_i64.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_SET_I64_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_SET_SIGNED(mp_set_i64, mp_set_u64, int64_t, uint64_t) +#endif diff --git a/libtommath/bn_mp_set_int.c b/libtommath/bn_mp_set_int.c deleted file mode 100644 index 3aafec9..0000000 --- a/libtommath/bn_mp_set_int.c +++ /dev/null @@ -1,48 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_SET_INT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* set a 32-bit const */ -int mp_set_int (mp_int * a, unsigned long b) -{ - int x, res; - - mp_zero (a); - - /* set four bits at a time */ - for (x = 0; x < 8; x++) { - /* shift the number up four bits */ - if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) { - return res; - } - - /* OR in the top four bits of the source */ - a->dp[0] |= (b >> 28) & 15; - - /* shift the source up to the next four bits */ - b <<= 4; - - /* ensure that digits are not clamped off */ - a->used += 1; - } - mp_clamp (a); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_set_l.c b/libtommath/bn_mp_set_l.c new file mode 100644 index 0000000..1e445fb --- /dev/null +++ b/libtommath/bn_mp_set_l.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_SET_L_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_SET_SIGNED(mp_set_l, mp_set_ul, long, unsigned long) +#endif diff --git a/libtommath/bn_mp_set_ll.c b/libtommath/bn_mp_set_ll.c new file mode 100644 index 0000000..3e2324f --- /dev/null +++ b/libtommath/bn_mp_set_ll.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_SET_LL_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_SET_SIGNED(mp_set_ll, mp_set_ull, long long, unsigned long long) +#endif diff --git a/libtommath/bn_mp_set_long.c b/libtommath/bn_mp_set_long.c deleted file mode 100644 index 8cbb811..0000000 --- a/libtommath/bn_mp_set_long.c +++ /dev/null @@ -1,24 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_SET_LONG_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* set a platform dependent unsigned long int */ -MP_SET_XLONG(mp_set_long, unsigned long) -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_set_long_long.c b/libtommath/bn_mp_set_long_long.c deleted file mode 100644 index 3566b45..0000000 --- a/libtommath/bn_mp_set_long_long.c +++ /dev/null @@ -1,24 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_SET_LONG_LONG_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* set a platform dependent unsigned long long int */ -MP_SET_XLONG(mp_set_long_long, unsigned long long) -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_set_u32.c b/libtommath/bn_mp_set_u32.c new file mode 100644 index 0000000..18ba5e1 --- /dev/null +++ b/libtommath/bn_mp_set_u32.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_SET_U32_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_SET_UNSIGNED(mp_set_u32, uint32_t) +#endif diff --git a/libtommath/bn_mp_set_u64.c b/libtommath/bn_mp_set_u64.c new file mode 100644 index 0000000..88fab6c --- /dev/null +++ b/libtommath/bn_mp_set_u64.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_SET_U64_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_SET_UNSIGNED(mp_set_u64, uint64_t) +#endif diff --git a/libtommath/bn_mp_set_ul.c b/libtommath/bn_mp_set_ul.c new file mode 100644 index 0000000..adfd85c --- /dev/null +++ b/libtommath/bn_mp_set_ul.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_SET_UL_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_SET_UNSIGNED(mp_set_ul, unsigned long) +#endif diff --git a/libtommath/bn_mp_set_ull.c b/libtommath/bn_mp_set_ull.c new file mode 100644 index 0000000..8fbc1bd --- /dev/null +++ b/libtommath/bn_mp_set_ull.c @@ -0,0 +1,7 @@ +#include "tommath_private.h" +#ifdef BN_MP_SET_ULL_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +MP_SET_UNSIGNED(mp_set_ull, unsigned long long) +#endif diff --git a/libtommath/bn_mp_shrink.c b/libtommath/bn_mp_shrink.c index 0712c2b..cf27ed9 100644 --- a/libtommath/bn_mp_shrink.c +++ b/libtommath/bn_mp_shrink.c @@ -1,41 +1,22 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_SHRINK_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* shrink a bignum */ -int mp_shrink (mp_int * a) +mp_err mp_shrink(mp_int *a) { - mp_digit *tmp; - int used = 1; - - if(a->used > 0) { - used = a->used; - } - - if (a->alloc != used) { - if ((tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * used)) == NULL) { - return MP_MEM; - } - a->dp = tmp; - a->alloc = used; - } - return MP_OKAY; + mp_digit *tmp; + int alloc = MP_MAX(MP_MIN_PREC, a->used); + if (a->alloc != alloc) { + if ((tmp = (mp_digit *) MP_REALLOC(a->dp, + (size_t)a->alloc * sizeof(mp_digit), + (size_t)alloc * sizeof(mp_digit))) == NULL) { + return MP_MEM; + } + a->dp = tmp; + a->alloc = alloc; + } + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_signed_bin_size.c b/libtommath/bn_mp_signed_bin_size.c deleted file mode 100644 index 0910333..0000000 --- a/libtommath/bn_mp_signed_bin_size.c +++ /dev/null @@ -1,27 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_SIGNED_BIN_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* get the size for an signed equivalent */ -int mp_signed_bin_size (mp_int * a) -{ - return 1 + mp_unsigned_bin_size (a); -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_signed_rsh.c b/libtommath/bn_mp_signed_rsh.c new file mode 100644 index 0000000..8d8d841 --- /dev/null +++ b/libtommath/bn_mp_signed_rsh.c @@ -0,0 +1,22 @@ +#include "tommath_private.h" +#ifdef BN_MP_SIGNED_RSH_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* shift right by a certain bit count with sign extension */ +mp_err mp_signed_rsh(const mp_int *a, int b, mp_int *c) +{ + mp_err res; + if (a->sign == MP_ZPOS) { + return mp_div_2d(a, b, c, NULL); + } + + res = mp_add_d(a, 1uL, c); + if (res != MP_OKAY) { + return res; + } + + res = mp_div_2d(c, b, c, NULL); + return (res == MP_OKAY) ? mp_sub_d(c, 1uL, c) : res; +} +#endif diff --git a/libtommath/bn_mp_sqr.c b/libtommath/bn_mp_sqr.c index ffe94e2..e0d0a73 100644 --- a/libtommath/bn_mp_sqr.c +++ b/libtommath/bn_mp_sqr.c @@ -1,60 +1,28 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* computes b = a*a */ -int -mp_sqr (mp_int * a, mp_int * b) +mp_err mp_sqr(const mp_int *a, mp_int *b) { - int res; - -#ifdef BN_MP_TOOM_SQR_C - /* use Toom-Cook? */ - if (a->used >= TOOM_SQR_CUTOFF) { - res = mp_toom_sqr(a, b); - /* Karatsuba? */ - } else -#endif -#ifdef BN_MP_KARATSUBA_SQR_C - if (a->used >= KARATSUBA_SQR_CUTOFF) { - res = mp_karatsuba_sqr (a, b); - } else -#endif - { -#ifdef BN_FAST_S_MP_SQR_C - /* can we use the fast comba multiplier? */ - if ((((a->used * 2) + 1) < MP_WARRAY) && - (a->used < - (1 << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) - 1)))) { - res = fast_s_mp_sqr (a, b); - } else -#endif - { -#ifdef BN_S_MP_SQR_C - res = s_mp_sqr (a, b); -#else - res = MP_VAL; -#endif - } - } - b->sign = MP_ZPOS; - return res; + mp_err err; + if (MP_HAS(S_MP_TOOM_SQR) && /* use Toom-Cook? */ + (a->used >= MP_TOOM_SQR_CUTOFF)) { + err = s_mp_toom_sqr(a, b); + } else if (MP_HAS(S_MP_KARATSUBA_SQR) && /* Karatsuba? */ + (a->used >= MP_KARATSUBA_SQR_CUTOFF)) { + err = s_mp_karatsuba_sqr(a, b); + } else if (MP_HAS(S_MP_SQR_FAST) && /* can we use the fast comba multiplier? */ + (((a->used * 2) + 1) < MP_WARRAY) && + (a->used < (MP_MAXFAST / 2))) { + err = s_mp_sqr_fast(a, b); + } else if (MP_HAS(S_MP_SQR)) { + err = s_mp_sqr(a, b); + } else { + err = MP_VAL; + } + b->sign = MP_ZPOS; + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_sqrmod.c b/libtommath/bn_mp_sqrmod.c index 3b29fbc..626ea2c 100644 --- a/libtommath/bn_mp_sqrmod.c +++ b/libtommath/bn_mp_sqrmod.c @@ -1,41 +1,25 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_SQRMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* c = a * a (mod b) */ -int -mp_sqrmod (mp_int * a, mp_int * b, mp_int * c) +mp_err mp_sqrmod(const mp_int *a, const mp_int *b, mp_int *c) { - int res; - mp_int t; + mp_err err; + mp_int t; - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } + if ((err = mp_init(&t)) != MP_OKAY) { + return err; + } - if ((res = mp_sqr (a, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, b, c); - mp_clear (&t); - return res; + if ((err = mp_sqr(a, &t)) != MP_OKAY) { + goto LBL_ERR; + } + err = mp_mod(&t, b, c); + +LBL_ERR: + mp_clear(&t); + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_sqrt.c b/libtommath/bn_mp_sqrt.c index d3b5d62..82d6824 100644 --- a/libtommath/bn_mp_sqrt.c +++ b/libtommath/bn_mp_sqrt.c @@ -1,81 +1,67 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_SQRT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* this function is less generic than mp_n_root, simpler and faster */ -int mp_sqrt(mp_int *arg, mp_int *ret) +mp_err mp_sqrt(const mp_int *arg, mp_int *ret) { - int res; - mp_int t1,t2; + mp_err err; + mp_int t1, t2; - /* must be positive */ - if (arg->sign == MP_NEG) { - return MP_VAL; - } + /* must be positive */ + if (arg->sign == MP_NEG) { + return MP_VAL; + } - /* easy out */ - if (mp_iszero(arg) == MP_YES) { - mp_zero(ret); - return MP_OKAY; - } + /* easy out */ + if (MP_IS_ZERO(arg)) { + mp_zero(ret); + return MP_OKAY; + } - if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) { - return res; - } + if ((err = mp_init_copy(&t1, arg)) != MP_OKAY) { + return err; + } - if ((res = mp_init(&t2)) != MP_OKAY) { - goto E2; - } + if ((err = mp_init(&t2)) != MP_OKAY) { + goto E2; + } - /* First approx. (not very bad for large arg) */ - mp_rshd (&t1,t1.used/2); + /* First approx. (not very bad for large arg) */ + mp_rshd(&t1, t1.used/2); - /* t1 > 0 */ - if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { - goto E1; - } - if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { - goto E1; - } - if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { - goto E1; - } - /* And now t1 > sqrt(arg) */ - do { - if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { + /* t1 > 0 */ + if ((err = mp_div(arg, &t1, &t2, NULL)) != MP_OKAY) { goto E1; - } - if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { + } + if ((err = mp_add(&t1, &t2, &t1)) != MP_OKAY) { goto E1; - } - if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { + } + if ((err = mp_div_2(&t1, &t1)) != MP_OKAY) { goto E1; - } - /* t1 >= sqrt(arg) >= t2 at this point */ - } while (mp_cmp_mag(&t1,&t2) == MP_GT); + } + /* And now t1 > sqrt(arg) */ + do { + if ((err = mp_div(arg, &t1, &t2, NULL)) != MP_OKAY) { + goto E1; + } + if ((err = mp_add(&t1, &t2, &t1)) != MP_OKAY) { + goto E1; + } + if ((err = mp_div_2(&t1, &t1)) != MP_OKAY) { + goto E1; + } + /* t1 >= sqrt(arg) >= t2 at this point */ + } while (mp_cmp_mag(&t1, &t2) == MP_GT); - mp_exch(&t1,ret); + mp_exch(&t1, ret); -E1: mp_clear(&t2); -E2: mp_clear(&t1); - return res; +E1: + mp_clear(&t2); +E2: + mp_clear(&t1); + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_sqrtmod_prime.c b/libtommath/bn_mp_sqrtmod_prime.c index 968729e..a833ed7 100644 --- a/libtommath/bn_mp_sqrtmod_prime.c +++ b/libtommath/bn_mp_sqrtmod_prime.c @@ -1,13 +1,7 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_SQRTMOD_PRIME_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is free for all purposes without any express - * guarantee it works. - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* Tonelli-Shanks algorithm * https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm @@ -15,110 +9,110 @@ * */ -int mp_sqrtmod_prime(mp_int *n, mp_int *prime, mp_int *ret) +mp_err mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret) { - int res, legendre; - mp_int t1, C, Q, S, Z, M, T, R, two; - mp_digit i; + mp_err err; + int legendre; + mp_int t1, C, Q, S, Z, M, T, R, two; + mp_digit i; - /* first handle the simple cases */ - if (mp_cmp_d(n, 0) == MP_EQ) { - mp_zero(ret); - return MP_OKAY; - } - if (mp_cmp_d(prime, 2) == MP_EQ) return MP_VAL; /* prime must be odd */ - if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) return res; - if (legendre == -1) return MP_VAL; /* quadratic non-residue mod prime */ + /* first handle the simple cases */ + if (mp_cmp_d(n, 0uL) == MP_EQ) { + mp_zero(ret); + return MP_OKAY; + } + if (mp_cmp_d(prime, 2uL) == MP_EQ) return MP_VAL; /* prime must be odd */ + if ((err = mp_kronecker(n, prime, &legendre)) != MP_OKAY) return err; + if (legendre == -1) return MP_VAL; /* quadratic non-residue mod prime */ - if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M, &T, &R, &two, NULL)) != MP_OKAY) { - return res; - } + if ((err = mp_init_multi(&t1, &C, &Q, &S, &Z, &M, &T, &R, &two, NULL)) != MP_OKAY) { + return err; + } - /* SPECIAL CASE: if prime mod 4 == 3 - * compute directly: res = n^(prime+1)/4 mod prime - * Handbook of Applied Cryptography algorithm 3.36 - */ - if ((res = mp_mod_d(prime, 4, &i)) != MP_OKAY) goto cleanup; - if (i == 3) { - if ((res = mp_add_d(prime, 1, &t1)) != MP_OKAY) goto cleanup; - if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup; - if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup; - if ((res = mp_exptmod(n, &t1, prime, ret)) != MP_OKAY) goto cleanup; - res = MP_OKAY; - goto cleanup; - } + /* SPECIAL CASE: if prime mod 4 == 3 + * compute directly: err = n^(prime+1)/4 mod prime + * Handbook of Applied Cryptography algorithm 3.36 + */ + if ((err = mp_mod_d(prime, 4uL, &i)) != MP_OKAY) goto cleanup; + if (i == 3u) { + if ((err = mp_add_d(prime, 1uL, &t1)) != MP_OKAY) goto cleanup; + if ((err = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup; + if ((err = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup; + if ((err = mp_exptmod(n, &t1, prime, ret)) != MP_OKAY) goto cleanup; + err = MP_OKAY; + goto cleanup; + } - /* NOW: Tonelli-Shanks algorithm */ + /* NOW: Tonelli-Shanks algorithm */ - /* factor out powers of 2 from prime-1, defining Q and S as: prime-1 = Q*2^S */ - if ((res = mp_copy(prime, &Q)) != MP_OKAY) goto cleanup; - if ((res = mp_sub_d(&Q, 1, &Q)) != MP_OKAY) goto cleanup; - /* Q = prime - 1 */ - mp_zero(&S); - /* S = 0 */ - while (mp_iseven(&Q) != MP_NO) { - if ((res = mp_div_2(&Q, &Q)) != MP_OKAY) goto cleanup; - /* Q = Q / 2 */ - if ((res = mp_add_d(&S, 1, &S)) != MP_OKAY) goto cleanup; - /* S = S + 1 */ - } + /* factor out powers of 2 from prime-1, defining Q and S as: prime-1 = Q*2^S */ + if ((err = mp_copy(prime, &Q)) != MP_OKAY) goto cleanup; + if ((err = mp_sub_d(&Q, 1uL, &Q)) != MP_OKAY) goto cleanup; + /* Q = prime - 1 */ + mp_zero(&S); + /* S = 0 */ + while (MP_IS_EVEN(&Q)) { + if ((err = mp_div_2(&Q, &Q)) != MP_OKAY) goto cleanup; + /* Q = Q / 2 */ + if ((err = mp_add_d(&S, 1uL, &S)) != MP_OKAY) goto cleanup; + /* S = S + 1 */ + } - /* find a Z such that the Legendre symbol (Z|prime) == -1 */ - if ((res = mp_set_int(&Z, 2)) != MP_OKAY) goto cleanup; - /* Z = 2 */ - while(1) { - if ((res = mp_jacobi(&Z, prime, &legendre)) != MP_OKAY) goto cleanup; - if (legendre == -1) break; - if ((res = mp_add_d(&Z, 1, &Z)) != MP_OKAY) goto cleanup; - /* Z = Z + 1 */ - } + /* find a Z such that the Legendre symbol (Z|prime) == -1 */ + mp_set_u32(&Z, 2u); + /* Z = 2 */ + for (;;) { + if ((err = mp_kronecker(&Z, prime, &legendre)) != MP_OKAY) goto cleanup; + if (legendre == -1) break; + if ((err = mp_add_d(&Z, 1uL, &Z)) != MP_OKAY) goto cleanup; + /* Z = Z + 1 */ + } - if ((res = mp_exptmod(&Z, &Q, prime, &C)) != MP_OKAY) goto cleanup; - /* C = Z ^ Q mod prime */ - if ((res = mp_add_d(&Q, 1, &t1)) != MP_OKAY) goto cleanup; - if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup; - /* t1 = (Q + 1) / 2 */ - if ((res = mp_exptmod(n, &t1, prime, &R)) != MP_OKAY) goto cleanup; - /* R = n ^ ((Q + 1) / 2) mod prime */ - if ((res = mp_exptmod(n, &Q, prime, &T)) != MP_OKAY) goto cleanup; - /* T = n ^ Q mod prime */ - if ((res = mp_copy(&S, &M)) != MP_OKAY) goto cleanup; - /* M = S */ - if ((res = mp_set_int(&two, 2)) != MP_OKAY) goto cleanup; + if ((err = mp_exptmod(&Z, &Q, prime, &C)) != MP_OKAY) goto cleanup; + /* C = Z ^ Q mod prime */ + if ((err = mp_add_d(&Q, 1uL, &t1)) != MP_OKAY) goto cleanup; + if ((err = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup; + /* t1 = (Q + 1) / 2 */ + if ((err = mp_exptmod(n, &t1, prime, &R)) != MP_OKAY) goto cleanup; + /* R = n ^ ((Q + 1) / 2) mod prime */ + if ((err = mp_exptmod(n, &Q, prime, &T)) != MP_OKAY) goto cleanup; + /* T = n ^ Q mod prime */ + if ((err = mp_copy(&S, &M)) != MP_OKAY) goto cleanup; + /* M = S */ + mp_set_u32(&two, 2u); - res = MP_VAL; - while (1) { - if ((res = mp_copy(&T, &t1)) != MP_OKAY) goto cleanup; - i = 0; - while (1) { - if (mp_cmp_d(&t1, 1) == MP_EQ) break; - if ((res = mp_exptmod(&t1, &two, prime, &t1)) != MP_OKAY) goto cleanup; - i++; - } - if (i == 0) { - if ((res = mp_copy(&R, ret)) != MP_OKAY) goto cleanup; - res = MP_OKAY; - goto cleanup; - } - if ((res = mp_sub_d(&M, i, &t1)) != MP_OKAY) goto cleanup; - if ((res = mp_sub_d(&t1, 1, &t1)) != MP_OKAY) goto cleanup; - if ((res = mp_exptmod(&two, &t1, prime, &t1)) != MP_OKAY) goto cleanup; - /* t1 = 2 ^ (M - i - 1) */ - if ((res = mp_exptmod(&C, &t1, prime, &t1)) != MP_OKAY) goto cleanup; - /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */ - if ((res = mp_sqrmod(&t1, prime, &C)) != MP_OKAY) goto cleanup; - /* C = (t1 * t1) mod prime */ - if ((res = mp_mulmod(&R, &t1, prime, &R)) != MP_OKAY) goto cleanup; - /* R = (R * t1) mod prime */ - if ((res = mp_mulmod(&T, &C, prime, &T)) != MP_OKAY) goto cleanup; - /* T = (T * C) mod prime */ - mp_set(&M, i); - /* M = i */ - } + for (;;) { + if ((err = mp_copy(&T, &t1)) != MP_OKAY) goto cleanup; + i = 0; + for (;;) { + if (mp_cmp_d(&t1, 1uL) == MP_EQ) break; + if ((err = mp_exptmod(&t1, &two, prime, &t1)) != MP_OKAY) goto cleanup; + i++; + } + if (i == 0u) { + if ((err = mp_copy(&R, ret)) != MP_OKAY) goto cleanup; + err = MP_OKAY; + goto cleanup; + } + if ((err = mp_sub_d(&M, i, &t1)) != MP_OKAY) goto cleanup; + if ((err = mp_sub_d(&t1, 1uL, &t1)) != MP_OKAY) goto cleanup; + if ((err = mp_exptmod(&two, &t1, prime, &t1)) != MP_OKAY) goto cleanup; + /* t1 = 2 ^ (M - i - 1) */ + if ((err = mp_exptmod(&C, &t1, prime, &t1)) != MP_OKAY) goto cleanup; + /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */ + if ((err = mp_sqrmod(&t1, prime, &C)) != MP_OKAY) goto cleanup; + /* C = (t1 * t1) mod prime */ + if ((err = mp_mulmod(&R, &t1, prime, &R)) != MP_OKAY) goto cleanup; + /* R = (R * t1) mod prime */ + if ((err = mp_mulmod(&T, &C, prime, &T)) != MP_OKAY) goto cleanup; + /* T = (T * C) mod prime */ + mp_set(&M, i); + /* M = i */ + } cleanup: - mp_clear_multi(&t1, &C, &Q, &S, &Z, &M, &T, &R, &two, NULL); - return res; + mp_clear_multi(&t1, &C, &Q, &S, &Z, &M, &T, &R, &two, NULL); + return err; } #endif diff --git a/libtommath/bn_mp_sub.c b/libtommath/bn_mp_sub.c index 2f73faa..c1ea39e 100644 --- a/libtommath/bn_mp_sub.c +++ b/libtommath/bn_mp_sub.c @@ -1,59 +1,40 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_SUB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* high level subtraction (handles signs) */ -int -mp_sub (mp_int * a, mp_int * b, mp_int * c) +mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c) { - int sa, sb, res; + mp_sign sa = a->sign, sb = b->sign; + mp_err err; - sa = a->sign; - sb = b->sign; - - if (sa != sb) { - /* subtract a negative from a positive, OR */ - /* subtract a positive from a negative. */ - /* In either case, ADD their magnitudes, */ - /* and use the sign of the first number. */ - c->sign = sa; - res = s_mp_add (a, b, c); - } else { - /* subtract a positive from a positive, OR */ - /* subtract a negative from a negative. */ - /* First, take the difference between their */ - /* magnitudes, then... */ - if (mp_cmp_mag (a, b) != MP_LT) { - /* Copy the sign from the first */ + if (sa != sb) { + /* subtract a negative from a positive, OR */ + /* subtract a positive from a negative. */ + /* In either case, ADD their magnitudes, */ + /* and use the sign of the first number. */ c->sign = sa; - /* The first has a larger or equal magnitude */ - res = s_mp_sub (a, b, c); - } else { - /* The result has the *opposite* sign from */ - /* the first number. */ - c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS; - /* The second has a larger magnitude */ - res = s_mp_sub (b, a, c); - } - } - return res; + err = s_mp_add(a, b, c); + } else { + /* subtract a positive from a positive, OR */ + /* subtract a negative from a negative. */ + /* First, take the difference between their */ + /* magnitudes, then... */ + if (mp_cmp_mag(a, b) != MP_LT) { + /* Copy the sign from the first */ + c->sign = sa; + /* The first has a larger or equal magnitude */ + err = s_mp_sub(a, b, c); + } else { + /* The result has the *opposite* sign from */ + /* the first number. */ + c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS; + /* The second has a larger magnitude */ + err = s_mp_sub(b, a, c); + } + } + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_sub_d.c b/libtommath/bn_mp_sub_d.c index 5e96030..3ebf9b4 100644 --- a/libtommath/bn_mp_sub_d.c +++ b/libtommath/bn_mp_sub_d.c @@ -1,93 +1,74 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_SUB_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* single digit subtraction */ -int -mp_sub_d (mp_int * a, mp_digit b, mp_int * c) +mp_err mp_sub_d(const mp_int *a, mp_digit b, mp_int *c) { - mp_digit *tmpa, *tmpc, mu; - int res, ix, oldused; + mp_digit *tmpa, *tmpc; + mp_err err; + int ix, oldused; - /* grow c as required */ - if (c->alloc < (a->used + 1)) { - if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { - return res; - } - } + /* grow c as required */ + if (c->alloc < (a->used + 1)) { + if ((err = mp_grow(c, a->used + 1)) != MP_OKAY) { + return err; + } + } - /* if a is negative just do an unsigned - * addition [with fudged signs] - */ - if (a->sign == MP_NEG) { - a->sign = MP_ZPOS; - res = mp_add_d(a, b, c); - a->sign = c->sign = MP_NEG; + /* if a is negative just do an unsigned + * addition [with fudged signs] + */ + if (a->sign == MP_NEG) { + mp_int a_ = *a; + a_.sign = MP_ZPOS; + err = mp_add_d(&a_, b, c); + c->sign = MP_NEG; - /* clamp */ - mp_clamp(c); + /* clamp */ + mp_clamp(c); - return res; - } + return err; + } - /* setup regs */ - oldused = c->used; - tmpa = a->dp; - tmpc = c->dp; + /* setup regs */ + oldused = c->used; + tmpa = a->dp; + tmpc = c->dp; - /* if a <= b simply fix the single digit */ - if (((a->used == 1) && (a->dp[0] <= b)) || (a->used == 0)) { - if (a->used == 1) { - *tmpc++ = b - *tmpa; - } else { - *tmpc++ = b; - } - ix = 1; + /* if a <= b simply fix the single digit */ + if (((a->used == 1) && (a->dp[0] <= b)) || (a->used == 0)) { + if (a->used == 1) { + *tmpc++ = b - *tmpa; + } else { + *tmpc++ = b; + } + ix = 1; - /* negative/1digit */ - c->sign = MP_NEG; - c->used = 1; - } else { - /* positive/size */ - c->sign = MP_ZPOS; - c->used = a->used; + /* negative/1digit */ + c->sign = MP_NEG; + c->used = 1; + } else { + mp_digit mu = b; - /* subtract first digit */ - *tmpc = *tmpa++ - b; - mu = *tmpc >> ((sizeof(mp_digit) * CHAR_BIT) - 1); - *tmpc++ &= MP_MASK; + /* positive/size */ + c->sign = MP_ZPOS; + c->used = a->used; - /* handle rest of the digits */ - for (ix = 1; ix < a->used; ix++) { - *tmpc = *tmpa++ - mu; - mu = *tmpc >> ((sizeof(mp_digit) * CHAR_BIT) - 1); - *tmpc++ &= MP_MASK; - } - } + /* subtract digits, mu is carry */ + for (ix = 0; ix < a->used; ix++) { + *tmpc = *tmpa++ - mu; + mu = *tmpc >> (MP_SIZEOF_BITS(mp_digit) - 1u); + *tmpc++ &= MP_MASK; + } + } - /* zero excess digits */ - while (ix++ < oldused) { - *tmpc++ = 0; - } - mp_clamp(c); - return MP_OKAY; + /* zero excess digits */ + MP_ZERO_DIGITS(tmpc, oldused - ix); + + mp_clamp(c); + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_submod.c b/libtommath/bn_mp_submod.c index 138863c..5ebd374 100644 --- a/libtommath/bn_mp_submod.c +++ b/libtommath/bn_mp_submod.c @@ -1,42 +1,25 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_SUBMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* d = a - b (mod c) */ -int -mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +mp_err mp_submod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d) { - int res; - mp_int t; + mp_err err; + mp_int t; + if ((err = mp_init(&t)) != MP_OKAY) { + return err; + } - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } + if ((err = mp_sub(a, b, &t)) != MP_OKAY) { + goto LBL_ERR; + } + err = mp_mod(&t, c, d); - if ((res = mp_sub (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, c, d); - mp_clear (&t); - return res; +LBL_ERR: + mp_clear(&t); + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_to_radix.c b/libtommath/bn_mp_to_radix.c new file mode 100644 index 0000000..7fa86ca --- /dev/null +++ b/libtommath/bn_mp_to_radix.c @@ -0,0 +1,84 @@ +#include "tommath_private.h" +#ifdef BN_MP_TO_RADIX_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* stores a bignum as a ASCII string in a given radix (2..64) + * + * Stores upto "size - 1" chars and always a NULL byte, puts the number of characters + * written, including the '\0', in "written". + */ +mp_err mp_to_radix(const mp_int *a, char *str, size_t maxlen, size_t *written, int radix) +{ + size_t digs; + mp_err err; + mp_int t; + mp_digit d; + char *_s = str; + + /* check range of radix and size*/ + if (maxlen < 2u) { + return MP_BUF; + } + if ((radix < 2) || (radix > 64)) { + return MP_VAL; + } + + /* quick out if its zero */ + if (MP_IS_ZERO(a)) { + *str++ = '0'; + *str = '\0'; + if (written != NULL) { + *written = 2u; + } + return MP_OKAY; + } + + if ((err = mp_init_copy(&t, a)) != MP_OKAY) { + return err; + } + + /* if it is negative output a - */ + if (t.sign == MP_NEG) { + /* we have to reverse our digits later... but not the - sign!! */ + ++_s; + + /* store the flag and mark the number as positive */ + *str++ = '-'; + t.sign = MP_ZPOS; + + /* subtract a char */ + --maxlen; + } + digs = 0u; + while (!MP_IS_ZERO(&t)) { + if (--maxlen < 1u) { + /* no more room */ + err = MP_BUF; + goto LBL_ERR; + } + if ((err = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) { + goto LBL_ERR; + } + *str++ = mp_s_rmap[d]; + ++digs; + } + /* reverse the digits of the string. In this case _s points + * to the first digit [exluding the sign] of the number + */ + s_mp_reverse((unsigned char *)_s, digs); + + /* append a NULL so the string is properly terminated */ + *str = '\0'; + digs++; + + if (written != NULL) { + *written = (a->sign == MP_NEG) ? (digs + 1u): digs; + } + +LBL_ERR: + mp_clear(&t); + return err; +} + +#endif diff --git a/libtommath/bn_mp_to_sbin.c b/libtommath/bn_mp_to_sbin.c new file mode 100644 index 0000000..dbaf53e --- /dev/null +++ b/libtommath/bn_mp_to_sbin.c @@ -0,0 +1,22 @@ +#include "tommath_private.h" +#ifdef BN_MP_TO_SBIN_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* store in signed [big endian] format */ +mp_err mp_to_sbin(const mp_int *a, unsigned char *buf, size_t maxlen, size_t *written) +{ + mp_err err; + if (maxlen == 0u) { + return MP_BUF; + } + if ((err = mp_to_ubin(a, buf + 1, maxlen - 1u, written)) != MP_OKAY) { + return err; + } + if (written != NULL) { + (*written)++; + } + buf[0] = (a->sign == MP_ZPOS) ? (unsigned char)0 : (unsigned char)1; + return MP_OKAY; +} +#endif diff --git a/libtommath/bn_mp_to_signed_bin.c b/libtommath/bn_mp_to_signed_bin.c deleted file mode 100644 index c49c87d..0000000 --- a/libtommath/bn_mp_to_signed_bin.c +++ /dev/null @@ -1,33 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_TO_SIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* store in signed [big endian] format */ -int mp_to_signed_bin (mp_int * a, unsigned char *b) -{ - int res; - - if ((res = mp_to_unsigned_bin (a, b + 1)) != MP_OKAY) { - return res; - } - b[0] = (a->sign == MP_ZPOS) ? (unsigned char)0 : (unsigned char)1; - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_to_signed_bin_n.c b/libtommath/bn_mp_to_signed_bin_n.c deleted file mode 100644 index dc5ec26..0000000 --- a/libtommath/bn_mp_to_signed_bin_n.c +++ /dev/null @@ -1,31 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_TO_SIGNED_BIN_N_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* store in signed [big endian] format */ -int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen) -{ - if (*outlen < (unsigned long)mp_signed_bin_size(a)) { - return MP_VAL; - } - *outlen = mp_signed_bin_size(a); - return mp_to_signed_bin(a, b); -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_to_ubin.c b/libtommath/bn_mp_to_ubin.c new file mode 100644 index 0000000..1681ca7 --- /dev/null +++ b/libtommath/bn_mp_to_ubin.c @@ -0,0 +1,41 @@ +#include "tommath_private.h" +#ifdef BN_MP_TO_UBIN_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* store in unsigned [big endian] format */ +mp_err mp_to_ubin(const mp_int *a, unsigned char *buf, size_t maxlen, size_t *written) +{ + size_t x, count; + mp_err err; + mp_int t; + + count = mp_ubin_size(a); + if (count > maxlen) { + return MP_BUF; + } + + if ((err = mp_init_copy(&t, a)) != MP_OKAY) { + return err; + } + + for (x = count; x --> 0u;) { +#ifndef MP_8BIT + buf[x] = (unsigned char)(t.dp[0] & 255u); +#else + buf[x] = (unsigned char)(t.dp[0] | ((t.dp[1] & 1u) << 7)); +#endif + if ((err = mp_div_2d(&t, 8, &t, NULL)) != MP_OKAY) { + goto LBL_ERR; + } + } + + if (written != NULL) { + *written = count; + } + +LBL_ERR: + mp_clear(&t); + return err; +} +#endif diff --git a/libtommath/bn_mp_to_unsigned_bin.c b/libtommath/bn_mp_to_unsigned_bin.c deleted file mode 100644 index d249359..0000000 --- a/libtommath/bn_mp_to_unsigned_bin.c +++ /dev/null @@ -1,48 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_TO_UNSIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* store in unsigned [big endian] format */ -int mp_to_unsigned_bin (mp_int * a, unsigned char *b) -{ - int x, res; - mp_int t; - - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - x = 0; - while (mp_iszero (&t) == MP_NO) { -#ifndef MP_8BIT - b[x++] = (unsigned char) (t.dp[0] & 255); -#else - b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7)); -#endif - if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) { - mp_clear (&t); - return res; - } - } - bn_reverse (b, x); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_to_unsigned_bin_n.c b/libtommath/bn_mp_to_unsigned_bin_n.c deleted file mode 100644 index f671621..0000000 --- a/libtommath/bn_mp_to_unsigned_bin_n.c +++ /dev/null @@ -1,31 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_TO_UNSIGNED_BIN_N_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* store in unsigned [big endian] format */ -int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen) -{ - if (*outlen < (unsigned long)mp_unsigned_bin_size(a)) { - return MP_VAL; - } - *outlen = mp_unsigned_bin_size(a); - return mp_to_unsigned_bin(a, b); -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_toom_mul.c b/libtommath/bn_mp_toom_mul.c deleted file mode 100644 index 4a574fc..0000000 --- a/libtommath/bn_mp_toom_mul.c +++ /dev/null @@ -1,286 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_TOOM_MUL_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* multiplication using the Toom-Cook 3-way algorithm - * - * Much more complicated than Karatsuba but has a lower - * asymptotic running time of O(N**1.464). This algorithm is - * only particularly useful on VERY large inputs - * (we're talking 1000s of digits here...). -*/ -int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c) -{ - mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2; - int res, B; - - /* init temps */ - if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, - &a0, &a1, &a2, &b0, &b1, - &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) { - return res; - } - - /* B */ - B = MIN(a->used, b->used) / 3; - - /* a = a2 * B**2 + a1 * B + a0 */ - if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(a, &a1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a1, B); - if ((res = mp_mod_2d(&a1, DIGIT_BIT * B, &a1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(a, &a2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a2, B*2); - - /* b = b2 * B**2 + b1 * B + b0 */ - if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(b, &b1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&b1, B); - (void)mp_mod_2d(&b1, DIGIT_BIT * B, &b1); - - if ((res = mp_copy(b, &b2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&b2, B*2); - - /* w0 = a0*b0 */ - if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) { - goto ERR; - } - - /* w4 = a2 * b2 */ - if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) { - goto ERR; - } - - /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */ - if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) { - goto ERR; - } - - /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */ - if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) { - goto ERR; - } - - - /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */ - if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) { - goto ERR; - } - - /* now solve the matrix - - 0 0 0 0 1 - 1 2 4 8 16 - 1 1 1 1 1 - 16 8 4 2 1 - 1 0 0 0 0 - - using 12 subtractions, 4 shifts, - 2 small divisions and 1 small multiplication - */ - - /* r1 - r4 */ - if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r0 */ - if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/2 */ - if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3/2 */ - if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { - goto ERR; - } - /* r2 - r0 - r4 */ - if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1 - 8r0 */ - if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - 8r4 */ - if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - /* 3r2 - r1 - r3 */ - if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/3 */ - if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { - goto ERR; - } - /* r3/3 */ - if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { - goto ERR; - } - - /* at this point shift W[n] by B*n */ - if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) { - goto ERR; - } - -ERR: - mp_clear_multi(&w0, &w1, &w2, &w3, &w4, - &a0, &a1, &a2, &b0, &b1, - &b2, &tmp1, &tmp2, NULL); - return res; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_toom_sqr.c b/libtommath/bn_mp_toom_sqr.c deleted file mode 100644 index 0a38192..0000000 --- a/libtommath/bn_mp_toom_sqr.c +++ /dev/null @@ -1,228 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_TOOM_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* squaring using Toom-Cook 3-way algorithm */ -int -mp_toom_sqr(mp_int *a, mp_int *b) -{ - mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2; - int res, B; - - /* init temps */ - if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) { - return res; - } - - /* B */ - B = a->used / 3; - - /* a = a2 * B**2 + a1 * B + a0 */ - if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(a, &a1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a1, B); - if ((res = mp_mod_2d(&a1, DIGIT_BIT * B, &a1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(a, &a2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a2, B*2); - - /* w0 = a0*a0 */ - if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) { - goto ERR; - } - - /* w4 = a2 * a2 */ - if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) { - goto ERR; - } - - /* w1 = (a2 + 2(a1 + 2a0))**2 */ - if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - - /* w3 = (a0 + 2(a1 + 2a2))**2 */ - if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - - - /* w2 = (a2 + a1 + a0)**2 */ - if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) { - goto ERR; - } - - /* now solve the matrix - - 0 0 0 0 1 - 1 2 4 8 16 - 1 1 1 1 1 - 16 8 4 2 1 - 1 0 0 0 0 - - using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication. - */ - - /* r1 - r4 */ - if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r0 */ - if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/2 */ - if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3/2 */ - if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { - goto ERR; - } - /* r2 - r0 - r4 */ - if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1 - 8r0 */ - if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - 8r4 */ - if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - /* 3r2 - r1 - r3 */ - if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/3 */ - if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { - goto ERR; - } - /* r3/3 */ - if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { - goto ERR; - } - - /* at this point shift W[n] by B*n */ - if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) { - goto ERR; - } - -ERR: - mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL); - return res; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_toradix.c b/libtommath/bn_mp_toradix.c deleted file mode 100644 index 3337765..0000000 --- a/libtommath/bn_mp_toradix.c +++ /dev/null @@ -1,75 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_TORADIX_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* stores a bignum as a ASCII string in a given radix (2..64) */ -int mp_toradix (mp_int * a, char *str, int radix) -{ - int res, digs; - mp_int t; - mp_digit d; - char *_s = str; - - /* check range of the radix */ - if ((radix < 2) || (radix > 64)) { - return MP_VAL; - } - - /* quick out if its zero */ - if (mp_iszero(a) == MP_YES) { - *str++ = '0'; - *str = '\0'; - return MP_OKAY; - } - - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - /* if it is negative output a - */ - if (t.sign == MP_NEG) { - ++_s; - *str++ = '-'; - t.sign = MP_ZPOS; - } - - digs = 0; - while (mp_iszero (&t) == MP_NO) { - if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { - mp_clear (&t); - return res; - } - *str++ = mp_s_rmap[d]; - ++digs; - } - - /* reverse the digits of the string. In this case _s points - * to the first digit [exluding the sign] of the number] - */ - bn_reverse ((unsigned char *)_s, digs); - - /* append a NULL so the string is properly terminated */ - *str = '\0'; - - mp_clear (&t); - return MP_OKAY; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_toradix_n.c b/libtommath/bn_mp_toradix_n.c deleted file mode 100644 index ae24ada..0000000 --- a/libtommath/bn_mp_toradix_n.c +++ /dev/null @@ -1,88 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_TORADIX_N_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* stores a bignum as a ASCII string in a given radix (2..64) - * - * Stores upto maxlen-1 chars and always a NULL byte - */ -int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen) -{ - int res, digs; - mp_int t; - mp_digit d; - char *_s = str; - - /* check range of the maxlen, radix */ - if ((maxlen < 2) || (radix < 2) || (radix > 64)) { - return MP_VAL; - } - - /* quick out if its zero */ - if (mp_iszero(a) == MP_YES) { - *str++ = '0'; - *str = '\0'; - return MP_OKAY; - } - - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - /* if it is negative output a - */ - if (t.sign == MP_NEG) { - /* we have to reverse our digits later... but not the - sign!! */ - ++_s; - - /* store the flag and mark the number as positive */ - *str++ = '-'; - t.sign = MP_ZPOS; - - /* subtract a char */ - --maxlen; - } - - digs = 0; - while (mp_iszero (&t) == MP_NO) { - if (--maxlen < 1) { - /* no more room */ - break; - } - if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { - mp_clear (&t); - return res; - } - *str++ = mp_s_rmap[d]; - ++digs; - } - - /* reverse the digits of the string. In this case _s points - * to the first digit [exluding the sign] of the number - */ - bn_reverse ((unsigned char *)_s, digs); - - /* append a NULL so the string is properly terminated */ - *str = '\0'; - - mp_clear (&t); - return MP_OKAY; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_ubin_size.c b/libtommath/bn_mp_ubin_size.c new file mode 100644 index 0000000..21230b4 --- /dev/null +++ b/libtommath/bn_mp_ubin_size.c @@ -0,0 +1,12 @@ +#include "tommath_private.h" +#ifdef BN_MP_UBIN_SIZE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* get the size for an unsigned equivalent */ +size_t mp_ubin_size(const mp_int *a) +{ + size_t size = (size_t)mp_count_bits(a); + return (size / 8u) + (((size & 7u) != 0u) ? 1u : 0u); +} +#endif diff --git a/libtommath/bn_mp_unpack.c b/libtommath/bn_mp_unpack.c new file mode 100644 index 0000000..d4eb90e --- /dev/null +++ b/libtommath/bn_mp_unpack.c @@ -0,0 +1,49 @@ +#include "tommath_private.h" +#ifdef BN_MP_UNPACK_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* based on gmp's mpz_import. + * see http://gmplib.org/manual/Integer-Import-and-Export.html + */ +mp_err mp_unpack(mp_int *rop, size_t count, mp_order order, size_t size, + mp_endian endian, size_t nails, const void *op) +{ + mp_err err; + size_t odd_nails, nail_bytes, i, j; + unsigned char odd_nail_mask; + + mp_zero(rop); + + if (endian == MP_NATIVE_ENDIAN) { + MP_GET_ENDIANNESS(endian); + } + + odd_nails = (nails % 8u); + odd_nail_mask = 0xff; + for (i = 0; i < odd_nails; ++i) { + odd_nail_mask ^= (unsigned char)(1u << (7u - i)); + } + nail_bytes = nails / 8u; + + for (i = 0; i < count; ++i) { + for (j = 0; j < (size - nail_bytes); ++j) { + unsigned char byte = *((const unsigned char *)op + + (((order == MP_MSB_FIRST) ? i : ((count - 1u) - i)) * size) + + ((endian == MP_BIG_ENDIAN) ? (j + nail_bytes) : (((size - 1u) - j) - nail_bytes))); + + if ((err = mp_mul_2d(rop, (j == 0u) ? (int)(8u - odd_nails) : 8, rop)) != MP_OKAY) { + return err; + } + + rop->dp[0] |= (j == 0u) ? (mp_digit)(byte & odd_nail_mask) : (mp_digit)byte; + rop->used += 1; + } + } + + mp_clamp(rop); + + return MP_OKAY; +} + +#endif diff --git a/libtommath/bn_mp_unsigned_bin_size.c b/libtommath/bn_mp_unsigned_bin_size.c deleted file mode 100644 index f46d0ba..0000000 --- a/libtommath/bn_mp_unsigned_bin_size.c +++ /dev/null @@ -1,28 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_MP_UNSIGNED_BIN_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* get the size for an unsigned equivalent */ -int mp_unsigned_bin_size (mp_int * a) -{ - int size = mp_count_bits (a); - return (size / 8) + (((size & 7) != 0) ? 1 : 0); -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_xor.c b/libtommath/bn_mp_xor.c index f51fc8e..71e7ca1 100644 --- a/libtommath/bn_mp_xor.c +++ b/libtommath/bn_mp_xor.c @@ -1,51 +1,56 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_XOR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* XOR two ints together */ -int -mp_xor (mp_int * a, mp_int * b, mp_int * c) +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* two complement xor */ +mp_err mp_xor(const mp_int *a, const mp_int *b, mp_int *c) { - int res, ix, px; - mp_int t, *x; - - if (a->used > b->used) { - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - px = b->used; - x = b; - } else { - if ((res = mp_init_copy (&t, b)) != MP_OKAY) { - return res; - } - px = a->used; - x = a; - } - - for (ix = 0; ix < px; ix++) { - t.dp[ix] ^= x->dp[ix]; - } - mp_clamp (&t); - mp_exch (c, &t); - mp_clear (&t); - return MP_OKAY; + int used = MP_MAX(a->used, b->used) + 1, i; + mp_err err; + mp_digit ac = 1, bc = 1, cc = 1; + mp_sign csign = (a->sign != b->sign) ? MP_NEG : MP_ZPOS; + + if (c->alloc < used) { + if ((err = mp_grow(c, used)) != MP_OKAY) { + return err; + } + } + + for (i = 0; i < used; i++) { + mp_digit x, y; + + /* convert to two complement if negative */ + if (a->sign == MP_NEG) { + ac += (i >= a->used) ? MP_MASK : (~a->dp[i] & MP_MASK); + x = ac & MP_MASK; + ac >>= MP_DIGIT_BIT; + } else { + x = (i >= a->used) ? 0uL : a->dp[i]; + } + + /* convert to two complement if negative */ + if (b->sign == MP_NEG) { + bc += (i >= b->used) ? MP_MASK : (~b->dp[i] & MP_MASK); + y = bc & MP_MASK; + bc >>= MP_DIGIT_BIT; + } else { + y = (i >= b->used) ? 0uL : b->dp[i]; + } + + c->dp[i] = x ^ y; + + /* convert to to sign-magnitude if negative */ + if (csign == MP_NEG) { + cc += ~c->dp[i] & MP_MASK; + c->dp[i] = cc & MP_MASK; + cc >>= MP_DIGIT_BIT; + } + } + + c->used = used; + c->sign = csign; + mp_clamp(c); + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_mp_zero.c b/libtommath/bn_mp_zero.c index a7d59e4..72a255e 100644 --- a/libtommath/bn_mp_zero.c +++ b/libtommath/bn_mp_zero.c @@ -1,36 +1,13 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_ZERO_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* set to zero */ -void mp_zero (mp_int * a) +void mp_zero(mp_int *a) { - int n; - mp_digit *tmp; - - a->sign = MP_ZPOS; - a->used = 0; - - tmp = a->dp; - for (n = 0; n < a->alloc; n++) { - *tmp++ = 0; - } + a->sign = MP_ZPOS; + a->used = 0; + MP_ZERO_DIGITS(a->dp, a->alloc); } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_prime_tab.c b/libtommath/bn_prime_tab.c index 5252130..a6c07f8 100644 --- a/libtommath/bn_prime_tab.c +++ b/libtommath/bn_prime_tab.c @@ -1,61 +1,61 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_PRIME_TAB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + const mp_digit ltm_prime_tab[] = { - 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, - 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, - 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, - 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, + 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, + 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, + 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, + 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, #ifndef MP_8BIT - 0x0083, - 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD, - 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF, - 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107, - 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137, + 0x0083, + 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD, + 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF, + 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107, + 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137, - 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167, - 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199, - 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9, - 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7, - 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239, - 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265, - 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293, - 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF, + 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167, + 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199, + 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9, + 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7, + 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239, + 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265, + 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293, + 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF, - 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301, - 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B, - 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371, - 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD, - 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5, - 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419, - 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449, - 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B, + 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301, + 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B, + 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371, + 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD, + 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5, + 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419, + 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449, + 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B, - 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7, - 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503, - 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529, - 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F, - 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3, - 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7, - 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623, - 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 + 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7, + 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503, + 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529, + 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F, + 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3, + 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7, + 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623, + 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 #endif }; + +#if defined(__GNUC__) && __GNUC__ >= 4 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +const mp_digit *s_mp_prime_tab = ltm_prime_tab; +#pragma GCC diagnostic pop +#elif defined(_MSC_VER) && _MSC_VER >= 1500 +#pragma warning(push) +#pragma warning(disable: 4996) +const mp_digit *s_mp_prime_tab = ltm_prime_tab; +#pragma warning(pop) +#else +const mp_digit *s_mp_prime_tab = ltm_prime_tab; #endif -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ +#endif diff --git a/libtommath/bn_reverse.c b/libtommath/bn_reverse.c deleted file mode 100644 index dc87a4e..0000000 --- a/libtommath/bn_reverse.c +++ /dev/null @@ -1,39 +0,0 @@ -#include <tommath_private.h> -#ifdef BN_REVERSE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* reverse an array, used for radix code */ -void -bn_reverse (unsigned char *s, int len) -{ - int ix, iy; - unsigned char t; - - ix = 0; - iy = len - 1; - while (ix < iy) { - t = s[ix]; - s[ix] = s[iy]; - s[iy] = t; - ++ix; - --iy; - } -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_s_mp_add.c b/libtommath/bn_s_mp_add.c index 7a100e8..c946aa8 100644 --- a/libtommath/bn_s_mp_add.c +++ b/libtommath/bn_s_mp_add.c @@ -1,109 +1,91 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_S_MP_ADD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* low level addition, based on HAC pp.594, Algorithm 14.7 */ -int -s_mp_add (mp_int * a, mp_int * b, mp_int * c) +mp_err s_mp_add(const mp_int *a, const mp_int *b, mp_int *c) { - mp_int *x; - int olduse, res, min, max; - - /* find sizes, we let |a| <= |b| which means we have to sort - * them. "x" will point to the input with the most digits - */ - if (a->used > b->used) { - min = b->used; - max = a->used; - x = a; - } else { - min = a->used; - max = b->used; - x = b; - } - - /* init result */ - if (c->alloc < (max + 1)) { - if ((res = mp_grow (c, max + 1)) != MP_OKAY) { - return res; - } - } - - /* get old used digit count and set new one */ - olduse = c->used; - c->used = max + 1; - - { - mp_digit u, *tmpa, *tmpb, *tmpc; - int i; - - /* alias for digit pointers */ - - /* first input */ - tmpa = a->dp; - - /* second input */ - tmpb = b->dp; - - /* destination */ - tmpc = c->dp; - - /* zero the carry */ - u = 0; - for (i = 0; i < min; i++) { - /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */ - *tmpc = *tmpa++ + *tmpb++ + u; - - /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)DIGIT_BIT); - - /* take away carry bit from T[i] */ - *tmpc++ &= MP_MASK; - } - - /* now copy higher words if any, that is in A+B - * if A or B has more digits add those in - */ - if (min != max) { - for (; i < max; i++) { - /* T[i] = X[i] + U */ - *tmpc = x->dp[i] + u; - - /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)DIGIT_BIT); - - /* take away carry bit from T[i] */ - *tmpc++ &= MP_MASK; + const mp_int *x; + mp_err err; + int olduse, min, max; + + /* find sizes, we let |a| <= |b| which means we have to sort + * them. "x" will point to the input with the most digits + */ + if (a->used > b->used) { + min = b->used; + max = a->used; + x = a; + } else { + min = a->used; + max = b->used; + x = b; + } + + /* init result */ + if (c->alloc < (max + 1)) { + if ((err = mp_grow(c, max + 1)) != MP_OKAY) { + return err; } - } + } - /* add carry */ - *tmpc++ = u; + /* get old used digit count and set new one */ + olduse = c->used; + c->used = max + 1; - /* clear digits above oldused */ - for (i = c->used; i < olduse; i++) { - *tmpc++ = 0; - } - } + { + mp_digit u, *tmpa, *tmpb, *tmpc; + int i; - mp_clamp (c); - return MP_OKAY; + /* alias for digit pointers */ + + /* first input */ + tmpa = a->dp; + + /* second input */ + tmpb = b->dp; + + /* destination */ + tmpc = c->dp; + + /* zero the carry */ + u = 0; + for (i = 0; i < min; i++) { + /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */ + *tmpc = *tmpa++ + *tmpb++ + u; + + /* U = carry bit of T[i] */ + u = *tmpc >> (mp_digit)MP_DIGIT_BIT; + + /* take away carry bit from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* now copy higher words if any, that is in A+B + * if A or B has more digits add those in + */ + if (min != max) { + for (; i < max; i++) { + /* T[i] = X[i] + U */ + *tmpc = x->dp[i] + u; + + /* U = carry bit of T[i] */ + u = *tmpc >> (mp_digit)MP_DIGIT_BIT; + + /* take away carry bit from T[i] */ + *tmpc++ &= MP_MASK; + } + } + + /* add carry */ + *tmpc++ = u; + + /* clear digits above oldused */ + MP_ZERO_DIGITS(tmpc, olduse - c->used); + } + + mp_clamp(c); + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_s_mp_balance_mul.c b/libtommath/bn_s_mp_balance_mul.c new file mode 100644 index 0000000..7ece5d7 --- /dev/null +++ b/libtommath/bn_s_mp_balance_mul.c @@ -0,0 +1,81 @@ +#include "tommath_private.h" +#ifdef BN_S_MP_BALANCE_MUL_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* single-digit multiplication with the smaller number as the single-digit */ +mp_err s_mp_balance_mul(const mp_int *a, const mp_int *b, mp_int *c) +{ + int count, len_a, len_b, nblocks, i, j, bsize; + mp_int a0, tmp, A, B, r; + mp_err err; + + len_a = a->used; + len_b = b->used; + + nblocks = MP_MAX(a->used, b->used) / MP_MIN(a->used, b->used); + bsize = MP_MIN(a->used, b->used) ; + + if ((err = mp_init_size(&a0, bsize + 2)) != MP_OKAY) { + return err; + } + if ((err = mp_init_multi(&tmp, &r, NULL)) != MP_OKAY) { + mp_clear(&a0); + return err; + } + + /* Make sure that A is the larger one*/ + if (len_a < len_b) { + B = *a; + A = *b; + } else { + A = *a; + B = *b; + } + + for (i = 0, j=0; i < nblocks; i++) { + /* Cut a slice off of a */ + a0.used = 0; + for (count = 0; count < bsize; count++) { + a0.dp[count] = A.dp[ j++ ]; + a0.used++; + } + mp_clamp(&a0); + /* Multiply with b */ + if ((err = mp_mul(&a0, &B, &tmp)) != MP_OKAY) { + goto LBL_ERR; + } + /* Shift tmp to the correct position */ + if ((err = mp_lshd(&tmp, bsize * i)) != MP_OKAY) { + goto LBL_ERR; + } + /* Add to output. No carry needed */ + if ((err = mp_add(&r, &tmp, &r)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* The left-overs; there are always left-overs */ + if (j < A.used) { + a0.used = 0; + for (count = 0; j < A.used; count++) { + a0.dp[count] = A.dp[ j++ ]; + a0.used++; + } + mp_clamp(&a0); + if ((err = mp_mul(&a0, &B, &tmp)) != MP_OKAY) { + goto LBL_ERR; + } + if ((err = mp_lshd(&tmp, bsize * i)) != MP_OKAY) { + goto LBL_ERR; + } + if ((err = mp_add(&r, &tmp, &r)) != MP_OKAY) { + goto LBL_ERR; + } + } + + mp_exch(&r,c); +LBL_ERR: + mp_clear_multi(&a0, &tmp, &r,NULL); + return err; +} +#endif diff --git a/libtommath/bn_s_mp_exptmod.c b/libtommath/bn_s_mp_exptmod.c index ab820d4..c3bfa95 100644 --- a/libtommath/bn_s_mp_exptmod.c +++ b/libtommath/bn_s_mp_exptmod.c @@ -1,252 +1,198 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_S_MP_EXPTMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + #ifdef MP_LOW_MEM - #define TAB_SIZE 32 +# define TAB_SIZE 32 +# define MAX_WINSIZE 5 #else - #define TAB_SIZE 256 +# define TAB_SIZE 256 +# define MAX_WINSIZE 0 #endif -int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) +mp_err s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode) { - mp_int M[TAB_SIZE], res, mu; - mp_digit buf; - int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; - int (*redux)(mp_int*,mp_int*,mp_int*); - - /* 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 = mp_init(&M[1])) != MP_OKAY) { - return err; - } - - /* now init the second half of the array */ - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - if ((err = mp_init(&M[x])) != MP_OKAY) { - for (y = 1<<(winsize-1); y < x; y++) { - mp_clear (&M[y]); - } - mp_clear(&M[1]); + mp_int M[TAB_SIZE], res, mu; + mp_digit buf; + mp_err err; + int bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; + mp_err(*redux)(mp_int *x, const mp_int *m, const mp_int *mu); + + /* 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; + } + + winsize = MAX_WINSIZE ? MP_MIN(MAX_WINSIZE, winsize) : winsize; + + /* init M array */ + /* init first cell */ + if ((err = mp_init(&M[1])) != MP_OKAY) { return err; - } - } - - /* create mu, used for Barrett reduction */ - if ((err = mp_init (&mu)) != MP_OKAY) { - goto LBL_M; - } - - if (redmode == 0) { - if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) { - goto LBL_MU; - } - redux = mp_reduce; - } else { - if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) { - goto LBL_MU; - } - redux = mp_reduce_2k_l; - } - - /* 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 ((err = mp_mod (G, P, &M[1])) != MP_OKAY) { - goto LBL_MU; - } - - /* compute the value at M[1<<(winsize-1)] by squaring - * M[1] (winsize-1) times - */ - if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_MU; - } - - for (x = 0; x < (winsize - 1); x++) { - /* square it */ - if ((err = mp_sqr (&M[1 << (winsize - 1)], - &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_MU; - } - - /* reduce modulo P */ - if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) { - goto LBL_MU; - } - } - - /* 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 = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { - goto LBL_MU; - } - if ((err = redux (&M[x], P, &mu)) != MP_OKAY) { - goto LBL_MU; - } - } - - /* setup result */ - if ((err = mp_init (&res)) != MP_OKAY) { - goto LBL_MU; - } - mp_set (&res, 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 = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; + } + + /* now init the second half of the array */ + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + if ((err = mp_init(&M[x])) != MP_OKAY) { + for (y = 1<<(winsize-1); y < x; y++) { + mp_clear(&M[y]); + } + mp_clear(&M[1]); + return err; } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_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 = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } + } + + /* create mu, used for Barrett reduction */ + if ((err = mp_init(&mu)) != MP_OKAY) goto LBL_M; + + if (redmode == 0) { + if ((err = mp_reduce_setup(&mu, P)) != MP_OKAY) goto LBL_MU; + redux = mp_reduce; + } else { + if ((err = mp_reduce_2k_setup_l(P, &mu)) != MP_OKAY) goto LBL_MU; + redux = mp_reduce_2k_l; + } + + /* 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 ((err = mp_mod(G, P, &M[1])) != MP_OKAY) goto LBL_MU; + + /* compute the value at M[1<<(winsize-1)] by squaring + * M[1] (winsize-1) times + */ + if ((err = mp_copy(&M[1], &M[(size_t)1 << (winsize - 1)])) != MP_OKAY) goto LBL_MU; + + for (x = 0; x < (winsize - 1); x++) { + /* square it */ + if ((err = mp_sqr(&M[(size_t)1 << (winsize - 1)], + &M[(size_t)1 << (winsize - 1)])) != MP_OKAY) goto LBL_MU; + + /* reduce modulo P */ + if ((err = redux(&M[(size_t)1 << (winsize - 1)], P, &mu)) != MP_OKAY) goto LBL_MU; + } + + /* 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 = mp_mul(&M[x - 1], &M[1], &M[x])) != MP_OKAY) goto LBL_MU; + if ((err = redux(&M[x], P, &mu)) != MP_OKAY) goto LBL_MU; + } + + /* setup result */ + if ((err = mp_init(&res)) != MP_OKAY) goto LBL_MU; + mp_set(&res, 1uL); + + /* 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)MP_DIGIT_BIT; } - /* then multiply */ - if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; + /* grab the next msb from the exponent */ + y = (buf >> (mp_digit)(MP_DIGIT_BIT - 1)) & 1uL; + 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; } - /* 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 = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; + /* if the bit is zero and mode == 1 then we square */ + if ((mode == 1) && (y == 0)) { + if ((err = mp_sqr(&res, &res)) != MP_OKAY) goto LBL_RES; + if ((err = redux(&res, P, &mu)) != MP_OKAY) goto LBL_RES; + continue; } - bitbuf <<= 1; - if ((bitbuf & (1 << winsize)) != 0) { - /* then multiply */ - if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } + /* 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 = mp_sqr(&res, &res)) != MP_OKAY) goto LBL_RES; + if ((err = redux(&res, P, &mu)) != MP_OKAY) goto LBL_RES; + } + + /* then multiply */ + if ((err = mp_mul(&res, &M[bitbuf], &res)) != MP_OKAY) goto LBL_RES; + if ((err = redux(&res, P, &mu)) != MP_OKAY) goto LBL_RES; + + /* empty window and reset */ + bitcpy = 0; + bitbuf = 0; + mode = 1; } - } - } - - mp_exch (&res, Y); - err = MP_OKAY; -LBL_RES:mp_clear (&res); -LBL_MU:mp_clear (&mu); + } + + /* 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 = mp_sqr(&res, &res)) != MP_OKAY) goto LBL_RES; + if ((err = redux(&res, P, &mu)) != MP_OKAY) goto LBL_RES; + + bitbuf <<= 1; + if ((bitbuf & (1 << winsize)) != 0) { + /* then multiply */ + if ((err = mp_mul(&res, &M[1], &res)) != MP_OKAY) goto LBL_RES; + if ((err = redux(&res, P, &mu)) != MP_OKAY) goto LBL_RES; + } + } + } + + mp_exch(&res, Y); + err = MP_OKAY; +LBL_RES: + mp_clear(&res); +LBL_MU: + mp_clear(&mu); LBL_M: - mp_clear(&M[1]); - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - mp_clear (&M[x]); - } - return err; + mp_clear(&M[1]); + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + mp_clear(&M[x]); + } + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_s_mp_exptmod_fast.c b/libtommath/bn_s_mp_exptmod_fast.c new file mode 100644 index 0000000..682ded8 --- /dev/null +++ b/libtommath/bn_s_mp_exptmod_fast.c @@ -0,0 +1,254 @@ +#include "tommath_private.h" +#ifdef BN_S_MP_EXPTMOD_FAST_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85 + * + * Uses a left-to-right k-ary sliding window to compute the modular exponentiation. + * The value of k changes based on the size of the exponent. + * + * Uses Montgomery or Diminished Radix reduction [whichever appropriate] + */ + +#ifdef MP_LOW_MEM +# define TAB_SIZE 32 +# define MAX_WINSIZE 5 +#else +# define TAB_SIZE 256 +# define MAX_WINSIZE 0 +#endif + +mp_err s_mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode) +{ + mp_int M[TAB_SIZE], res; + mp_digit buf, mp; + int bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; + mp_err err; + + /* use a pointer to the reduction algorithm. This allows us to use + * one of many reduction algorithms without modding the guts of + * the code with if statements everywhere. + */ + mp_err(*redux)(mp_int *x, const mp_int *n, mp_digit rho); + + /* 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; + } + + winsize = MAX_WINSIZE ? MP_MIN(MAX_WINSIZE, winsize) : winsize; + + /* init M array */ + /* init first cell */ + if ((err = mp_init_size(&M[1], P->alloc)) != MP_OKAY) { + return err; + } + + /* now init the second half of the array */ + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + if ((err = mp_init_size(&M[x], P->alloc)) != MP_OKAY) { + for (y = 1<<(winsize-1); y < x; y++) { + mp_clear(&M[y]); + } + mp_clear(&M[1]); + return err; + } + } + + /* determine and setup reduction code */ + if (redmode == 0) { + if (MP_HAS(MP_MONTGOMERY_SETUP)) { + /* now setup montgomery */ + if ((err = mp_montgomery_setup(P, &mp)) != MP_OKAY) goto LBL_M; + } else { + err = MP_VAL; + goto LBL_M; + } + + /* automatically pick the comba one if available (saves quite a few calls/ifs) */ + if (MP_HAS(S_MP_MONTGOMERY_REDUCE_FAST) && + (((P->used * 2) + 1) < MP_WARRAY) && + (P->used < MP_MAXFAST)) { + redux = s_mp_montgomery_reduce_fast; + } else if (MP_HAS(MP_MONTGOMERY_REDUCE)) { + /* use slower baseline Montgomery method */ + redux = mp_montgomery_reduce; + } else { + err = MP_VAL; + goto LBL_M; + } + } else if (redmode == 1) { + if (MP_HAS(MP_DR_SETUP) && MP_HAS(MP_DR_REDUCE)) { + /* setup DR reduction for moduli of the form B**k - b */ + mp_dr_setup(P, &mp); + redux = mp_dr_reduce; + } else { + err = MP_VAL; + goto LBL_M; + } + } else if (MP_HAS(MP_REDUCE_2K_SETUP) && MP_HAS(MP_REDUCE_2K)) { + /* setup DR reduction for moduli of the form 2**k - b */ + if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) goto LBL_M; + redux = mp_reduce_2k; + } else { + err = MP_VAL; + goto LBL_M; + } + + /* setup result */ + if ((err = mp_init_size(&res, P->alloc)) != MP_OKAY) goto LBL_M; + + /* create M table + * + + * + * The first half of the table is not computed though accept for M[0] and M[1] + */ + + if (redmode == 0) { + if (MP_HAS(MP_MONTGOMERY_CALC_NORMALIZATION)) { + /* now we need R mod m */ + if ((err = mp_montgomery_calc_normalization(&res, P)) != MP_OKAY) goto LBL_RES; + + /* now set M[1] to G * R mod m */ + if ((err = mp_mulmod(G, &res, P, &M[1])) != MP_OKAY) goto LBL_RES; + } else { + err = MP_VAL; + goto LBL_RES; + } + } else { + mp_set(&res, 1uL); + if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) goto LBL_RES; + } + + /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */ + if ((err = mp_copy(&M[1], &M[(size_t)1 << (winsize - 1)])) != MP_OKAY) goto LBL_RES; + + for (x = 0; x < (winsize - 1); x++) { + if ((err = mp_sqr(&M[(size_t)1 << (winsize - 1)], &M[(size_t)1 << (winsize - 1)])) != MP_OKAY) goto LBL_RES; + if ((err = redux(&M[(size_t)1 << (winsize - 1)], P, mp)) != MP_OKAY) goto LBL_RES; + } + + /* create upper table */ + for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { + if ((err = mp_mul(&M[x - 1], &M[1], &M[x])) != MP_OKAY) goto LBL_RES; + if ((err = redux(&M[x], P, mp)) != MP_OKAY) goto LBL_RES; + } + + /* 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 so break */ + if (digidx == -1) { + break; + } + /* read next digit and reset bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int)MP_DIGIT_BIT; + } + + /* grab the next msb from the exponent */ + y = (mp_digit)(buf >> (MP_DIGIT_BIT - 1)) & 1uL; + 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 = mp_sqr(&res, &res)) != MP_OKAY) goto LBL_RES; + if ((err = redux(&res, P, mp)) != MP_OKAY) goto LBL_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 = mp_sqr(&res, &res)) != MP_OKAY) goto LBL_RES; + if ((err = redux(&res, P, mp)) != MP_OKAY) goto LBL_RES; + } + + /* then multiply */ + if ((err = mp_mul(&res, &M[bitbuf], &res)) != MP_OKAY) goto LBL_RES; + if ((err = redux(&res, P, mp)) != MP_OKAY) goto LBL_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 = mp_sqr(&res, &res)) != MP_OKAY) goto LBL_RES; + if ((err = redux(&res, P, mp)) != MP_OKAY) goto LBL_RES; + + /* get next bit of the window */ + bitbuf <<= 1; + if ((bitbuf & (1 << winsize)) != 0) { + /* then multiply */ + if ((err = mp_mul(&res, &M[1], &res)) != MP_OKAY) goto LBL_RES; + if ((err = redux(&res, P, mp)) != MP_OKAY) goto LBL_RES; + } + } + } + + if (redmode == 0) { + /* fixup result if Montgomery reduction is used + * recall that any value in a Montgomery system is + * actually multiplied by R mod n. So we have + * to reduce one more time to cancel out the factor + * of R. + */ + if ((err = redux(&res, P, mp)) != MP_OKAY) goto LBL_RES; + } + + /* swap res with Y */ + mp_exch(&res, Y); + err = MP_OKAY; +LBL_RES: + mp_clear(&res); +LBL_M: + mp_clear(&M[1]); + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + mp_clear(&M[x]); + } + return err; +} +#endif diff --git a/libtommath/bn_s_mp_get_bit.c b/libtommath/bn_s_mp_get_bit.c new file mode 100644 index 0000000..28598df --- /dev/null +++ b/libtommath/bn_s_mp_get_bit.c @@ -0,0 +1,21 @@ +#include "tommath_private.h" +#ifdef BN_S_MP_GET_BIT_C + +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* Get bit at position b and return MP_YES if the bit is 1, MP_NO if it is 0 */ +mp_bool s_mp_get_bit(const mp_int *a, unsigned int b) +{ + mp_digit bit; + int limb = (int)(b / MP_DIGIT_BIT); + + if (limb >= a->used) { + return MP_NO; + } + + bit = (mp_digit)1 << (b % MP_DIGIT_BIT); + return ((a->dp[limb] & bit) != 0u) ? MP_YES : MP_NO; +} + +#endif diff --git a/libtommath/bn_s_mp_invmod_fast.c b/libtommath/bn_s_mp_invmod_fast.c new file mode 100644 index 0000000..677d7ab --- /dev/null +++ b/libtommath/bn_s_mp_invmod_fast.c @@ -0,0 +1,118 @@ +#include "tommath_private.h" +#ifdef BN_S_MP_INVMOD_FAST_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* computes the modular inverse via binary extended euclidean algorithm, + * that is c = 1/a mod b + * + * Based on slow invmod except this is optimized for the case where b is + * odd as per HAC Note 14.64 on pp. 610 + */ +mp_err s_mp_invmod_fast(const mp_int *a, const mp_int *b, mp_int *c) +{ + mp_int x, y, u, v, B, D; + mp_sign neg; + mp_err err; + + /* 2. [modified] b must be odd */ + if (MP_IS_EVEN(b)) { + return MP_VAL; + } + + /* init all our temps */ + if ((err = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) { + return err; + } + + /* x == modulus, y == value to invert */ + if ((err = mp_copy(b, &x)) != MP_OKAY) goto LBL_ERR; + + /* we need y = |a| */ + if ((err = mp_mod(a, b, &y)) != MP_OKAY) goto LBL_ERR; + + /* if one of x,y is zero return an error! */ + if (MP_IS_ZERO(&x) || MP_IS_ZERO(&y)) { + err = MP_VAL; + goto LBL_ERR; + } + + /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ + if ((err = mp_copy(&x, &u)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_copy(&y, &v)) != MP_OKAY) goto LBL_ERR; + mp_set(&D, 1uL); + +top: + /* 4. while u is even do */ + while (MP_IS_EVEN(&u)) { + /* 4.1 u = u/2 */ + if ((err = mp_div_2(&u, &u)) != MP_OKAY) goto LBL_ERR; + + /* 4.2 if B is odd then */ + if (MP_IS_ODD(&B)) { + if ((err = mp_sub(&B, &x, &B)) != MP_OKAY) goto LBL_ERR; + } + /* B = B/2 */ + if ((err = mp_div_2(&B, &B)) != MP_OKAY) goto LBL_ERR; + } + + /* 5. while v is even do */ + while (MP_IS_EVEN(&v)) { + /* 5.1 v = v/2 */ + if ((err = mp_div_2(&v, &v)) != MP_OKAY) goto LBL_ERR; + + /* 5.2 if D is odd then */ + if (MP_IS_ODD(&D)) { + /* D = (D-x)/2 */ + if ((err = mp_sub(&D, &x, &D)) != MP_OKAY) goto LBL_ERR; + } + /* D = D/2 */ + if ((err = mp_div_2(&D, &D)) != MP_OKAY) goto LBL_ERR; + } + + /* 6. if u >= v then */ + if (mp_cmp(&u, &v) != MP_LT) { + /* u = u - v, B = B - D */ + if ((err = mp_sub(&u, &v, &u)) != MP_OKAY) goto LBL_ERR; + + if ((err = mp_sub(&B, &D, &B)) != MP_OKAY) goto LBL_ERR; + } else { + /* v - v - u, D = D - B */ + if ((err = mp_sub(&v, &u, &v)) != MP_OKAY) goto LBL_ERR; + + if ((err = mp_sub(&D, &B, &D)) != MP_OKAY) goto LBL_ERR; + } + + /* if not zero goto step 4 */ + if (!MP_IS_ZERO(&u)) { + goto top; + } + + /* now a = C, b = D, gcd == g*v */ + + /* if v != 1 then there is no inverse */ + if (mp_cmp_d(&v, 1uL) != MP_EQ) { + err = MP_VAL; + goto LBL_ERR; + } + + /* b is now the inverse */ + neg = a->sign; + while (D.sign == MP_NEG) { + if ((err = mp_add(&D, b, &D)) != MP_OKAY) goto LBL_ERR; + } + + /* too big */ + while (mp_cmp_mag(&D, b) != MP_LT) { + if ((err = mp_sub(&D, b, &D)) != MP_OKAY) goto LBL_ERR; + } + + mp_exch(&D, c); + c->sign = neg; + err = MP_OKAY; + +LBL_ERR: + mp_clear_multi(&x, &y, &u, &v, &B, &D, NULL); + return err; +} +#endif diff --git a/libtommath/bn_s_mp_invmod_slow.c b/libtommath/bn_s_mp_invmod_slow.c new file mode 100644 index 0000000..4c5db33 --- /dev/null +++ b/libtommath/bn_s_mp_invmod_slow.c @@ -0,0 +1,119 @@ +#include "tommath_private.h" +#ifdef BN_S_MP_INVMOD_SLOW_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* hac 14.61, pp608 */ +mp_err s_mp_invmod_slow(const mp_int *a, const mp_int *b, mp_int *c) +{ + mp_int x, y, u, v, A, B, C, D; + mp_err err; + + /* b cannot be negative */ + if ((b->sign == MP_NEG) || MP_IS_ZERO(b)) { + return MP_VAL; + } + + /* init temps */ + if ((err = mp_init_multi(&x, &y, &u, &v, + &A, &B, &C, &D, NULL)) != MP_OKAY) { + return err; + } + + /* x = a, y = b */ + if ((err = mp_mod(a, b, &x)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_copy(b, &y)) != MP_OKAY) goto LBL_ERR; + + /* 2. [modified] if x,y are both even then return an error! */ + if (MP_IS_EVEN(&x) && MP_IS_EVEN(&y)) { + err = MP_VAL; + goto LBL_ERR; + } + + /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ + if ((err = mp_copy(&x, &u)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_copy(&y, &v)) != MP_OKAY) goto LBL_ERR; + mp_set(&A, 1uL); + mp_set(&D, 1uL); + +top: + /* 4. while u is even do */ + while (MP_IS_EVEN(&u)) { + /* 4.1 u = u/2 */ + if ((err = mp_div_2(&u, &u)) != MP_OKAY) goto LBL_ERR; + + /* 4.2 if A or B is odd then */ + if (MP_IS_ODD(&A) || MP_IS_ODD(&B)) { + /* A = (A+y)/2, B = (B-x)/2 */ + if ((err = mp_add(&A, &y, &A)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_sub(&B, &x, &B)) != MP_OKAY) goto LBL_ERR; + } + /* A = A/2, B = B/2 */ + if ((err = mp_div_2(&A, &A)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_div_2(&B, &B)) != MP_OKAY) goto LBL_ERR; + } + + /* 5. while v is even do */ + while (MP_IS_EVEN(&v)) { + /* 5.1 v = v/2 */ + if ((err = mp_div_2(&v, &v)) != MP_OKAY) goto LBL_ERR; + + /* 5.2 if C or D is odd then */ + if (MP_IS_ODD(&C) || MP_IS_ODD(&D)) { + /* C = (C+y)/2, D = (D-x)/2 */ + if ((err = mp_add(&C, &y, &C)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_sub(&D, &x, &D)) != MP_OKAY) goto LBL_ERR; + } + /* C = C/2, D = D/2 */ + if ((err = mp_div_2(&C, &C)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_div_2(&D, &D)) != MP_OKAY) goto LBL_ERR; + } + + /* 6. if u >= v then */ + if (mp_cmp(&u, &v) != MP_LT) { + /* u = u - v, A = A - C, B = B - D */ + if ((err = mp_sub(&u, &v, &u)) != MP_OKAY) goto LBL_ERR; + + if ((err = mp_sub(&A, &C, &A)) != MP_OKAY) goto LBL_ERR; + + if ((err = mp_sub(&B, &D, &B)) != MP_OKAY) goto LBL_ERR; + } else { + /* v - v - u, C = C - A, D = D - B */ + if ((err = mp_sub(&v, &u, &v)) != MP_OKAY) goto LBL_ERR; + + if ((err = mp_sub(&C, &A, &C)) != MP_OKAY) goto LBL_ERR; + + if ((err = mp_sub(&D, &B, &D)) != MP_OKAY) goto LBL_ERR; + } + + /* if not zero goto step 4 */ + if (!MP_IS_ZERO(&u)) { + goto top; + } + + /* now a = C, b = D, gcd == g*v */ + + /* if v != 1 then there is no inverse */ + if (mp_cmp_d(&v, 1uL) != MP_EQ) { + err = MP_VAL; + goto LBL_ERR; + } + + /* if its too low */ + while (mp_cmp_d(&C, 0uL) == MP_LT) { + if ((err = mp_add(&C, b, &C)) != MP_OKAY) goto LBL_ERR; + } + + /* too big */ + while (mp_cmp_mag(&C, b) != MP_LT) { + if ((err = mp_sub(&C, b, &C)) != MP_OKAY) goto LBL_ERR; + } + + /* C is now the inverse */ + mp_exch(&C, c); + err = MP_OKAY; +LBL_ERR: + mp_clear_multi(&x, &y, &u, &v, &A, &B, &C, &D, NULL); + return err; +} +#endif diff --git a/libtommath/bn_s_mp_karatsuba_mul.c b/libtommath/bn_s_mp_karatsuba_mul.c new file mode 100644 index 0000000..85899fb --- /dev/null +++ b/libtommath/bn_s_mp_karatsuba_mul.c @@ -0,0 +1,174 @@ +#include "tommath_private.h" +#ifdef BN_S_MP_KARATSUBA_MUL_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* c = |a| * |b| using Karatsuba Multiplication using + * three half size multiplications + * + * Let B represent the radix [e.g. 2**MP_DIGIT_BIT] and + * let n represent half of the number of digits in + * the min(a,b) + * + * a = a1 * B**n + a0 + * b = b1 * B**n + b0 + * + * Then, a * b => + a1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0 + * + * Note that a1b1 and a0b0 are used twice and only need to be + * computed once. So in total three half size (half # of + * digit) multiplications are performed, a0b0, a1b1 and + * (a1+b1)(a0+b0) + * + * Note that a multiplication of half the digits requires + * 1/4th the number of single precision multiplications so in + * total after one call 25% of the single precision multiplications + * are saved. Note also that the call to mp_mul can end up back + * in this function if the a0, a1, b0, or b1 are above the threshold. + * This is known as divide-and-conquer and leads to the famous + * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than + * the standard O(N**2) that the baseline/comba methods use. + * Generally though the overhead of this method doesn't pay off + * until a certain size (N ~ 80) is reached. + */ +mp_err s_mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c) +{ + mp_int x0, x1, y0, y1, t1, x0y0, x1y1; + int B; + mp_err err = MP_MEM; /* default the return code to an error */ + + /* min # of digits */ + B = MP_MIN(a->used, b->used); + + /* now divide in two */ + B = B >> 1; + + /* init copy all the temps */ + if (mp_init_size(&x0, B) != MP_OKAY) { + goto LBL_ERR; + } + if (mp_init_size(&x1, a->used - B) != MP_OKAY) { + goto X0; + } + if (mp_init_size(&y0, B) != MP_OKAY) { + goto X1; + } + if (mp_init_size(&y1, b->used - B) != MP_OKAY) { + goto Y0; + } + + /* init temps */ + if (mp_init_size(&t1, B * 2) != MP_OKAY) { + goto Y1; + } + if (mp_init_size(&x0y0, B * 2) != MP_OKAY) { + goto T1; + } + if (mp_init_size(&x1y1, B * 2) != MP_OKAY) { + goto X0Y0; + } + + /* now shift the digits */ + x0.used = y0.used = B; + x1.used = a->used - B; + y1.used = b->used - B; + + { + int x; + mp_digit *tmpa, *tmpb, *tmpx, *tmpy; + + /* we copy the digits directly instead of using higher level functions + * since we also need to shift the digits + */ + tmpa = a->dp; + tmpb = b->dp; + + tmpx = x0.dp; + tmpy = y0.dp; + for (x = 0; x < B; x++) { + *tmpx++ = *tmpa++; + *tmpy++ = *tmpb++; + } + + tmpx = x1.dp; + for (x = B; x < a->used; x++) { + *tmpx++ = *tmpa++; + } + + tmpy = y1.dp; + for (x = B; x < b->used; x++) { + *tmpy++ = *tmpb++; + } + } + + /* only need to clamp the lower words since by definition the + * upper words x1/y1 must have a known number of digits + */ + mp_clamp(&x0); + mp_clamp(&y0); + + /* now calc the products x0y0 and x1y1 */ + /* after this x0 is no longer required, free temp [x0==t2]! */ + if (mp_mul(&x0, &y0, &x0y0) != MP_OKAY) { + goto X1Y1; /* x0y0 = x0*y0 */ + } + if (mp_mul(&x1, &y1, &x1y1) != MP_OKAY) { + goto X1Y1; /* x1y1 = x1*y1 */ + } + + /* now calc x1+x0 and y1+y0 */ + if (s_mp_add(&x1, &x0, &t1) != MP_OKAY) { + goto X1Y1; /* t1 = x1 - x0 */ + } + if (s_mp_add(&y1, &y0, &x0) != MP_OKAY) { + goto X1Y1; /* t2 = y1 - y0 */ + } + if (mp_mul(&t1, &x0, &t1) != MP_OKAY) { + goto X1Y1; /* t1 = (x1 + x0) * (y1 + y0) */ + } + + /* add x0y0 */ + if (mp_add(&x0y0, &x1y1, &x0) != MP_OKAY) { + goto X1Y1; /* t2 = x0y0 + x1y1 */ + } + if (s_mp_sub(&t1, &x0, &t1) != MP_OKAY) { + goto X1Y1; /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */ + } + + /* shift by B */ + if (mp_lshd(&t1, B) != MP_OKAY) { + goto X1Y1; /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))<<B */ + } + if (mp_lshd(&x1y1, B * 2) != MP_OKAY) { + goto X1Y1; /* x1y1 = x1y1 << 2*B */ + } + + if (mp_add(&x0y0, &t1, &t1) != MP_OKAY) { + goto X1Y1; /* t1 = x0y0 + t1 */ + } + if (mp_add(&t1, &x1y1, c) != MP_OKAY) { + goto X1Y1; /* t1 = x0y0 + t1 + x1y1 */ + } + + /* Algorithm succeeded set the return code to MP_OKAY */ + err = MP_OKAY; + +X1Y1: + mp_clear(&x1y1); +X0Y0: + mp_clear(&x0y0); +T1: + mp_clear(&t1); +Y1: + mp_clear(&y1); +Y0: + mp_clear(&y0); +X1: + mp_clear(&x1); +X0: + mp_clear(&x0); +LBL_ERR: + return err; +} +#endif diff --git a/libtommath/bn_s_mp_karatsuba_sqr.c b/libtommath/bn_s_mp_karatsuba_sqr.c new file mode 100644 index 0000000..f132d07 --- /dev/null +++ b/libtommath/bn_s_mp_karatsuba_sqr.c @@ -0,0 +1,110 @@ +#include "tommath_private.h" +#ifdef BN_S_MP_KARATSUBA_SQR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* Karatsuba squaring, computes b = a*a using three + * half size squarings + * + * See comments of karatsuba_mul for details. It + * is essentially the same algorithm but merely + * tuned to perform recursive squarings. + */ +mp_err s_mp_karatsuba_sqr(const mp_int *a, mp_int *b) +{ + mp_int x0, x1, t1, t2, x0x0, x1x1; + int B; + mp_err err = MP_MEM; + + /* min # of digits */ + B = a->used; + + /* now divide in two */ + B = B >> 1; + + /* init copy all the temps */ + if (mp_init_size(&x0, B) != MP_OKAY) + goto LBL_ERR; + if (mp_init_size(&x1, a->used - B) != MP_OKAY) + goto X0; + + /* init temps */ + if (mp_init_size(&t1, a->used * 2) != MP_OKAY) + goto X1; + if (mp_init_size(&t2, a->used * 2) != MP_OKAY) + goto T1; + if (mp_init_size(&x0x0, B * 2) != MP_OKAY) + goto T2; + if (mp_init_size(&x1x1, (a->used - B) * 2) != MP_OKAY) + goto X0X0; + + { + int x; + mp_digit *dst, *src; + + src = a->dp; + + /* now shift the digits */ + dst = x0.dp; + for (x = 0; x < B; x++) { + *dst++ = *src++; + } + + dst = x1.dp; + for (x = B; x < a->used; x++) { + *dst++ = *src++; + } + } + + x0.used = B; + x1.used = a->used - B; + + mp_clamp(&x0); + + /* now calc the products x0*x0 and x1*x1 */ + if (mp_sqr(&x0, &x0x0) != MP_OKAY) + goto X1X1; /* x0x0 = x0*x0 */ + if (mp_sqr(&x1, &x1x1) != MP_OKAY) + goto X1X1; /* x1x1 = x1*x1 */ + + /* now calc (x1+x0)**2 */ + if (s_mp_add(&x1, &x0, &t1) != MP_OKAY) + goto X1X1; /* t1 = x1 - x0 */ + if (mp_sqr(&t1, &t1) != MP_OKAY) + goto X1X1; /* t1 = (x1 - x0) * (x1 - x0) */ + + /* add x0y0 */ + if (s_mp_add(&x0x0, &x1x1, &t2) != MP_OKAY) + goto X1X1; /* t2 = x0x0 + x1x1 */ + if (s_mp_sub(&t1, &t2, &t1) != MP_OKAY) + goto X1X1; /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */ + + /* shift by B */ + if (mp_lshd(&t1, B) != MP_OKAY) + goto X1X1; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))<<B */ + if (mp_lshd(&x1x1, B * 2) != MP_OKAY) + goto X1X1; /* x1x1 = x1x1 << 2*B */ + + if (mp_add(&x0x0, &t1, &t1) != MP_OKAY) + goto X1X1; /* t1 = x0x0 + t1 */ + if (mp_add(&t1, &x1x1, b) != MP_OKAY) + goto X1X1; /* t1 = x0x0 + t1 + x1x1 */ + + err = MP_OKAY; + +X1X1: + mp_clear(&x1x1); +X0X0: + mp_clear(&x0x0); +T2: + mp_clear(&t2); +T1: + mp_clear(&t1); +X1: + mp_clear(&x1); +X0: + mp_clear(&x0); +LBL_ERR: + return err; +} +#endif diff --git a/libtommath/bn_s_mp_montgomery_reduce_fast.c b/libtommath/bn_s_mp_montgomery_reduce_fast.c new file mode 100644 index 0000000..3f0c672 --- /dev/null +++ b/libtommath/bn_s_mp_montgomery_reduce_fast.c @@ -0,0 +1,159 @@ +#include "tommath_private.h" +#ifdef BN_S_MP_MONTGOMERY_REDUCE_FAST_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* computes xR**-1 == x (mod N) via Montgomery Reduction + * + * This is an optimized implementation of montgomery_reduce + * which uses the comba method to quickly calculate the columns of the + * reduction. + * + * Based on Algorithm 14.32 on pp.601 of HAC. +*/ +mp_err s_mp_montgomery_reduce_fast(mp_int *x, const mp_int *n, mp_digit rho) +{ + int ix, olduse; + mp_err err; + mp_word W[MP_WARRAY]; + + if (x->used > MP_WARRAY) { + return MP_VAL; + } + + /* get old used count */ + olduse = x->used; + + /* grow a as required */ + if (x->alloc < (n->used + 1)) { + if ((err = mp_grow(x, n->used + 1)) != MP_OKAY) { + return err; + } + } + + /* first we have to get the digits of the input into + * an array of double precision words W[...] + */ + { + mp_word *_W; + mp_digit *tmpx; + + /* alias for the W[] array */ + _W = W; + + /* alias for the digits of x*/ + tmpx = x->dp; + + /* copy the digits of a into W[0..a->used-1] */ + for (ix = 0; ix < x->used; ix++) { + *_W++ = *tmpx++; + } + + /* zero the high words of W[a->used..m->used*2] */ + if (ix < ((n->used * 2) + 1)) { + MP_ZERO_BUFFER(_W, sizeof(mp_word) * (size_t)(((n->used * 2) + 1) - ix)); + } + } + + /* now we proceed to zero successive digits + * from the least significant upwards + */ + for (ix = 0; ix < n->used; ix++) { + /* mu = ai * m' mod b + * + * We avoid a double precision multiplication (which isn't required) + * by casting the value down to a mp_digit. Note this requires + * that W[ix-1] have the carry cleared (see after the inner loop) + */ + mp_digit mu; + mu = ((W[ix] & MP_MASK) * rho) & MP_MASK; + + /* a = a + mu * m * b**i + * + * This is computed in place and on the fly. The multiplication + * by b**i is handled by offseting which columns the results + * are added to. + * + * Note the comba method normally doesn't handle carries in the + * inner loop In this case we fix the carry from the previous + * column since the Montgomery reduction requires digits of the + * result (so far) [see above] to work. This is + * handled by fixing up one carry after the inner loop. The + * carry fixups are done in order so after these loops the + * first m->used words of W[] have the carries fixed + */ + { + int iy; + mp_digit *tmpn; + mp_word *_W; + + /* alias for the digits of the modulus */ + tmpn = n->dp; + + /* Alias for the columns set by an offset of ix */ + _W = W + ix; + + /* inner loop */ + for (iy = 0; iy < n->used; iy++) { + *_W++ += (mp_word)mu * (mp_word)*tmpn++; + } + } + + /* now fix carry for next digit, W[ix+1] */ + W[ix + 1] += W[ix] >> (mp_word)MP_DIGIT_BIT; + } + + /* now we have to propagate the carries and + * shift the words downward [all those least + * significant digits we zeroed]. + */ + { + mp_digit *tmpx; + mp_word *_W, *_W1; + + /* nox fix rest of carries */ + + /* alias for current word */ + _W1 = W + ix; + + /* alias for next word, where the carry goes */ + _W = W + ++ix; + + for (; ix < ((n->used * 2) + 1); ix++) { + *_W++ += *_W1++ >> (mp_word)MP_DIGIT_BIT; + } + + /* copy out, A = A/b**n + * + * The result is A/b**n but instead of converting from an + * array of mp_word to mp_digit than calling mp_rshd + * we just copy them in the right order + */ + + /* alias for destination word */ + tmpx = x->dp; + + /* alias for shifted double precision result */ + _W = W + n->used; + + for (ix = 0; ix < (n->used + 1); ix++) { + *tmpx++ = *_W++ & (mp_word)MP_MASK; + } + + /* zero oldused digits, if the input a was larger than + * m->used+1 we'll have to clear the digits + */ + MP_ZERO_DIGITS(tmpx, olduse - ix); + } + + /* set the max used and clamp */ + x->used = n->used + 1; + mp_clamp(x); + + /* if A >= m then A = A - m */ + if (mp_cmp_mag(x, n) != MP_LT) { + return s_mp_sub(x, n, x); + } + return MP_OKAY; +} +#endif diff --git a/libtommath/bn_s_mp_mul_digs.c b/libtommath/bn_s_mp_mul_digs.c index 8f1bf97..64509d4 100644 --- a/libtommath/bn_s_mp_mul_digs.c +++ b/libtommath/bn_s_mp_mul_digs.c @@ -1,90 +1,74 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_S_MP_MUL_DIGS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* multiplies |a| * |b| and only computes upto digs digits of result - * HAC pp. 595, Algorithm 14.12 Modified so you can control how + * HAC pp. 595, Algorithm 14.12 Modified so you can control how * many digits of output are created. */ -int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +mp_err s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) { - mp_int t; - int res, pa, pb, ix, iy; - mp_digit u; - mp_word r; - mp_digit tmpx, *tmpt, *tmpy; + mp_int t; + mp_err err; + int pa, pb, ix, iy; + mp_digit u; + mp_word r; + mp_digit tmpx, *tmpt, *tmpy; + + /* can we use the fast multiplier? */ + if ((digs < MP_WARRAY) && + (MP_MIN(a->used, b->used) < MP_MAXFAST)) { + return s_mp_mul_digs_fast(a, b, c, digs); + } - /* can we use the fast multiplier? */ - if (((digs) < MP_WARRAY) && - (MIN (a->used, b->used) < - (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) { - return fast_s_mp_mul_digs (a, b, c, digs); - } + if ((err = mp_init_size(&t, digs)) != MP_OKAY) { + return err; + } + t.used = digs; - if ((res = mp_init_size (&t, digs)) != MP_OKAY) { - return res; - } - t.used = digs; + /* compute the digits of the product directly */ + pa = a->used; + for (ix = 0; ix < pa; ix++) { + /* set the carry to zero */ + u = 0; - /* compute the digits of the product directly */ - pa = a->used; - for (ix = 0; ix < pa; ix++) { - /* set the carry to zero */ - u = 0; + /* limit ourselves to making digs digits of output */ + pb = MP_MIN(b->used, digs - ix); - /* limit ourselves to making digs digits of output */ - pb = MIN (b->used, digs - ix); + /* setup some aliases */ + /* copy of the digit from a used within the nested loop */ + tmpx = a->dp[ix]; - /* setup some aliases */ - /* copy of the digit from a used within the nested loop */ - tmpx = a->dp[ix]; - - /* an alias for the destination shifted ix places */ - tmpt = t.dp + ix; - - /* an alias for the digits of b */ - tmpy = b->dp; + /* an alias for the destination shifted ix places */ + tmpt = t.dp + ix; - /* compute the columns of the output and propagate the carry */ - for (iy = 0; iy < pb; iy++) { - /* compute the column as a mp_word */ - r = (mp_word)*tmpt + - ((mp_word)tmpx * (mp_word)*tmpy++) + - (mp_word)u; + /* an alias for the digits of b */ + tmpy = b->dp; - /* the new column is the lower part of the result */ - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + /* compute the columns of the output and propagate the carry */ + for (iy = 0; iy < pb; iy++) { + /* compute the column as a mp_word */ + r = (mp_word)*tmpt + + ((mp_word)tmpx * (mp_word)*tmpy++) + + (mp_word)u; - /* get the carry word from the result */ - u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); - } - /* set carry if it is placed below digs */ - if ((ix + iy) < digs) { - *tmpt = u; - } - } + /* the new column is the lower part of the result */ + *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK); - mp_clamp (&t); - mp_exch (&t, c); + /* get the carry word from the result */ + u = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT); + } + /* set carry if it is placed below digs */ + if ((ix + iy) < digs) { + *tmpt = u; + } + } - mp_clear (&t); - return MP_OKAY; + mp_clamp(&t); + mp_exch(&t, c); + + mp_clear(&t); + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_s_mp_mul_digs_fast.c b/libtommath/bn_s_mp_mul_digs_fast.c new file mode 100644 index 0000000..b2a287b --- /dev/null +++ b/libtommath/bn_s_mp_mul_digs_fast.c @@ -0,0 +1,90 @@ +#include "tommath_private.h" +#ifdef BN_S_MP_MUL_DIGS_FAST_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* Fast (comba) multiplier + * + * This is the fast column-array [comba] multiplier. It is + * designed to compute the columns of the product first + * then handle the carries afterwards. This has the effect + * of making the nested loops that compute the columns very + * simple and schedulable on super-scalar processors. + * + * This has been modified to produce a variable number of + * digits of output so if say only a half-product is required + * you don't have to compute the upper half (a feature + * required for fast Barrett reduction). + * + * Based on Algorithm 14.12 on pp.595 of HAC. + * + */ +mp_err s_mp_mul_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int digs) +{ + int olduse, pa, ix, iz; + mp_err err; + mp_digit W[MP_WARRAY]; + mp_word _W; + + /* grow the destination as required */ + if (c->alloc < digs) { + if ((err = mp_grow(c, digs)) != MP_OKAY) { + return err; + } + } + + /* number of output digits to produce */ + pa = MP_MIN(digs, a->used + b->used); + + /* clear the carry */ + _W = 0; + for (ix = 0; ix < pa; ix++) { + int tx, ty; + int iy; + mp_digit *tmpx, *tmpy; + + /* get offsets into the two bignums */ + ty = MP_MIN(b->used-1, ix); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = b->dp + ty; + + /* this is the number of times the loop will iterrate, essentially + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MP_MIN(a->used-tx, ty+1); + + /* execute loop */ + for (iz = 0; iz < iy; ++iz) { + _W += (mp_word)*tmpx++ * (mp_word)*tmpy--; + + } + + /* store term */ + W[ix] = (mp_digit)_W & MP_MASK; + + /* make next carry */ + _W = _W >> (mp_word)MP_DIGIT_BIT; + } + + /* setup dest */ + olduse = c->used; + c->used = pa; + + { + mp_digit *tmpc; + tmpc = c->dp; + for (ix = 0; ix < pa; ix++) { + /* now extract the previous digit [below the carry] */ + *tmpc++ = W[ix]; + } + + /* clear unused digits [that existed in the old copy of c] */ + MP_ZERO_DIGITS(tmpc, olduse - ix); + } + mp_clamp(c); + return MP_OKAY; +} +#endif diff --git a/libtommath/bn_s_mp_mul_high_digs.c b/libtommath/bn_s_mp_mul_high_digs.c index 031f17b..2bb2a50 100644 --- a/libtommath/bn_s_mp_mul_high_digs.c +++ b/libtommath/bn_s_mp_mul_high_digs.c @@ -1,81 +1,64 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_S_MP_MUL_HIGH_DIGS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* multiplies |a| * |b| and does not compute the lower digs digits * [meant to get the higher part of the product] */ -int -s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +mp_err s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) { - mp_int t; - int res, pa, pb, ix, iy; - mp_digit u; - mp_word r; - mp_digit tmpx, *tmpt, *tmpy; + mp_int t; + int pa, pb, ix, iy; + mp_err err; + mp_digit u; + mp_word r; + mp_digit tmpx, *tmpt, *tmpy; - /* can we use the fast multiplier? */ -#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C - if (((a->used + b->used + 1) < MP_WARRAY) - && (MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) { - return fast_s_mp_mul_high_digs (a, b, c, digs); - } -#endif + /* can we use the fast multiplier? */ + if (MP_HAS(S_MP_MUL_HIGH_DIGS_FAST) + && ((a->used + b->used + 1) < MP_WARRAY) + && (MP_MIN(a->used, b->used) < MP_MAXFAST)) { + return s_mp_mul_high_digs_fast(a, b, c, digs); + } - if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) { - return res; - } - t.used = a->used + b->used + 1; + if ((err = mp_init_size(&t, a->used + b->used + 1)) != MP_OKAY) { + return err; + } + t.used = a->used + b->used + 1; - pa = a->used; - pb = b->used; - for (ix = 0; ix < pa; ix++) { - /* clear the carry */ - u = 0; + pa = a->used; + pb = b->used; + for (ix = 0; ix < pa; ix++) { + /* clear the carry */ + u = 0; - /* left hand side of A[ix] * B[iy] */ - tmpx = a->dp[ix]; + /* left hand side of A[ix] * B[iy] */ + tmpx = a->dp[ix]; - /* alias to the address of where the digits will be stored */ - tmpt = &(t.dp[digs]); + /* alias to the address of where the digits will be stored */ + tmpt = &(t.dp[digs]); - /* alias for where to read the right hand side from */ - tmpy = b->dp + (digs - ix); + /* alias for where to read the right hand side from */ + tmpy = b->dp + (digs - ix); - for (iy = digs - ix; iy < pb; iy++) { - /* calculate the double precision result */ - r = (mp_word)*tmpt + - ((mp_word)tmpx * (mp_word)*tmpy++) + - (mp_word)u; + for (iy = digs - ix; iy < pb; iy++) { + /* calculate the double precision result */ + r = (mp_word)*tmpt + + ((mp_word)tmpx * (mp_word)*tmpy++) + + (mp_word)u; - /* get the lower part */ - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + /* get the lower part */ + *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK); - /* carry the carry */ - u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); - } - *tmpt = u; - } - mp_clamp (&t); - mp_exch (&t, c); - mp_clear (&t); - return MP_OKAY; + /* carry the carry */ + u = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT); + } + *tmpt = u; + } + mp_clamp(&t); + mp_exch(&t, c); + mp_clear(&t); + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_s_mp_mul_high_digs_fast.c b/libtommath/bn_s_mp_mul_high_digs_fast.c new file mode 100644 index 0000000..a2c4fb6 --- /dev/null +++ b/libtommath/bn_s_mp_mul_high_digs_fast.c @@ -0,0 +1,81 @@ +#include "tommath_private.h" +#ifdef BN_S_MP_MUL_HIGH_DIGS_FAST_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* this is a modified version of fast_s_mul_digs that only produces + * output digits *above* digs. See the comments for fast_s_mul_digs + * to see how it works. + * + * This is used in the Barrett reduction since for one of the multiplications + * only the higher digits were needed. This essentially halves the work. + * + * Based on Algorithm 14.12 on pp.595 of HAC. + */ +mp_err s_mp_mul_high_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int digs) +{ + int olduse, pa, ix, iz; + mp_err err; + mp_digit W[MP_WARRAY]; + mp_word _W; + + /* grow the destination as required */ + pa = a->used + b->used; + if (c->alloc < pa) { + if ((err = mp_grow(c, pa)) != MP_OKAY) { + return err; + } + } + + /* number of output digits to produce */ + pa = a->used + b->used; + _W = 0; + for (ix = digs; ix < pa; ix++) { + int tx, ty, iy; + mp_digit *tmpx, *tmpy; + + /* get offsets into the two bignums */ + ty = MP_MIN(b->used-1, ix); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = b->dp + ty; + + /* this is the number of times the loop will iterrate, essentially its + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MP_MIN(a->used-tx, ty+1); + + /* execute loop */ + for (iz = 0; iz < iy; iz++) { + _W += (mp_word)*tmpx++ * (mp_word)*tmpy--; + } + + /* store term */ + W[ix] = (mp_digit)_W & MP_MASK; + + /* make next carry */ + _W = _W >> (mp_word)MP_DIGIT_BIT; + } + + /* setup dest */ + olduse = c->used; + c->used = pa; + + { + mp_digit *tmpc; + + tmpc = c->dp + digs; + for (ix = digs; ix < pa; ix++) { + /* now extract the previous digit [below the carry] */ + *tmpc++ = W[ix]; + } + + /* clear unused digits [that existed in the old copy of c] */ + MP_ZERO_DIGITS(tmpc, olduse - ix); + } + mp_clamp(c); + return MP_OKAY; +} +#endif diff --git a/libtommath/bn_s_mp_prime_is_divisible.c b/libtommath/bn_s_mp_prime_is_divisible.c new file mode 100644 index 0000000..ffd5093 --- /dev/null +++ b/libtommath/bn_s_mp_prime_is_divisible.c @@ -0,0 +1,35 @@ +#include "tommath_private.h" +#ifdef BN_S_MP_PRIME_IS_DIVISIBLE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* determines if an integers is divisible by one + * of the first PRIME_SIZE primes or not + * + * sets result to 0 if not, 1 if yes + */ +mp_err s_mp_prime_is_divisible(const mp_int *a, mp_bool *result) +{ + int ix; + mp_err err; + mp_digit res; + + /* default to not */ + *result = MP_NO; + + for (ix = 0; ix < PRIVATE_MP_PRIME_TAB_SIZE; ix++) { + /* what is a mod LBL_prime_tab[ix] */ + if ((err = mp_mod_d(a, s_mp_prime_tab[ix], &res)) != MP_OKAY) { + return err; + } + + /* is the residue zero? */ + if (res == 0u) { + *result = MP_YES; + return MP_OKAY; + } + } + + return MP_OKAY; +} +#endif diff --git a/libtommath/bn_s_mp_rand_jenkins.c b/libtommath/bn_s_mp_rand_jenkins.c new file mode 100644 index 0000000..da0771c --- /dev/null +++ b/libtommath/bn_s_mp_rand_jenkins.c @@ -0,0 +1,52 @@ +#include "tommath_private.h" +#ifdef BN_S_MP_RAND_JENKINS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* Bob Jenkins' http://burtleburtle.net/bob/rand/smallprng.html */ +/* Chosen for speed and a good "mix" */ +typedef struct { + uint64_t a; + uint64_t b; + uint64_t c; + uint64_t d; +} ranctx; + +static ranctx jenkins_x; + +#define rot(x,k) (((x)<<(k))|((x)>>(64-(k)))) +static uint64_t s_rand_jenkins_val(void) +{ + uint64_t e = jenkins_x.a - rot(jenkins_x.b, 7); + jenkins_x.a = jenkins_x.b ^ rot(jenkins_x.c, 13); + jenkins_x.b = jenkins_x.c + rot(jenkins_x.d, 37); + jenkins_x.c = jenkins_x.d + e; + jenkins_x.d = e + jenkins_x.a; + return jenkins_x.d; +} + +void s_mp_rand_jenkins_init(uint64_t seed) +{ + uint64_t i; + jenkins_x.a = 0xf1ea5eedULL; + jenkins_x.b = jenkins_x.c = jenkins_x.d = seed; + for (i = 0uLL; i < 20uLL; ++i) { + (void)s_rand_jenkins_val(); + } +} + +mp_err s_mp_rand_jenkins(void *p, size_t n) +{ + char *q = (char *)p; + while (n > 0u) { + int i; + uint64_t x = s_rand_jenkins_val(); + for (i = 0; (i < 8) && (n > 0u); ++i, --n) { + *q++ = (char)(x & 0xFFuLL); + x >>= 8; + } + } + return MP_OKAY; +} + +#endif diff --git a/libtommath/bn_s_mp_rand_platform.c b/libtommath/bn_s_mp_rand_platform.c new file mode 100644 index 0000000..27339bf --- /dev/null +++ b/libtommath/bn_s_mp_rand_platform.c @@ -0,0 +1,148 @@ +#include "tommath_private.h" +#ifdef BN_S_MP_RAND_PLATFORM_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* First the OS-specific special cases + * - *BSD + * - Windows + */ +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) +#define BN_S_READ_ARC4RANDOM_C +static mp_err s_read_arc4random(void *p, size_t n) +{ + arc4random_buf(p, n); + return MP_OKAY; +} +#endif + +#if defined(_WIN32) || defined(_WIN32_WCE) +#define BN_S_READ_WINCSP_C + +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0400 +#endif +#ifdef _WIN32_WCE +#define UNDER_CE +#define ARM +#endif + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <wincrypt.h> + +static mp_err s_read_wincsp(void *p, size_t n) +{ + static HCRYPTPROV hProv = 0; + if (hProv == 0) { + HCRYPTPROV h = 0; + if (!CryptAcquireContext(&h, NULL, MS_DEF_PROV, PROV_RSA_FULL, + (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) && + !CryptAcquireContext(&h, NULL, MS_DEF_PROV, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET)) { + return MP_ERR; + } + hProv = h; + } + return CryptGenRandom(hProv, (DWORD)n, (BYTE *)p) == TRUE ? MP_OKAY : MP_ERR; +} +#endif /* WIN32 */ + +#if !defined(BN_S_READ_WINCSP_C) && defined(__linux__) && defined(__GLIBC_PREREQ) +#if __GLIBC_PREREQ(2, 25) +#define BN_S_READ_GETRANDOM_C +#include <sys/random.h> +#include <errno.h> + +static mp_err s_read_getrandom(void *p, size_t n) +{ + char *q = (char *)p; + while (n > 0u) { + ssize_t ret = getrandom(q, n, 0); + if (ret < 0) { + if (errno == EINTR) { + continue; + } + return MP_ERR; + } + q += ret; + n -= (size_t)ret; + } + return MP_OKAY; +} +#endif +#endif + +/* We assume all platforms besides windows provide "/dev/urandom". + * In case yours doesn't, define MP_NO_DEV_URANDOM at compile-time. + */ +#if !defined(BN_S_READ_WINCSP_C) && !defined(MP_NO_DEV_URANDOM) +#define BN_S_READ_URANDOM_C +#ifndef MP_DEV_URANDOM +#define MP_DEV_URANDOM "/dev/urandom" +#endif +#include <fcntl.h> +#include <errno.h> +#include <unistd.h> + +static mp_err s_read_urandom(void *p, size_t n) +{ + int fd; + char *q = (char *)p; + + do { + fd = open(MP_DEV_URANDOM, O_RDONLY); + } while ((fd == -1) && (errno == EINTR)); + if (fd == -1) return MP_ERR; + + while (n > 0u) { + ssize_t ret = read(fd, p, n); + if (ret < 0) { + if (errno == EINTR) { + continue; + } + close(fd); + return MP_ERR; + } + q += ret; + n -= (size_t)ret; + } + + close(fd); + return MP_OKAY; +} +#endif + +#if defined(MP_PRNG_ENABLE_LTM_RNG) +#define BN_S_READ_LTM_RNG +unsigned long (*ltm_rng)(unsigned char *out, unsigned long outlen, void (*callback)(void)); +void (*ltm_rng_callback)(void); + +static mp_err s_read_ltm_rng(void *p, size_t n) +{ + unsigned long res; + if (ltm_rng == NULL) return MP_ERR; + res = ltm_rng(p, n, ltm_rng_callback); + if (res != n) return MP_ERR; + return MP_OKAY; +} +#endif + +mp_err s_read_arc4random(void *p, size_t n); +mp_err s_read_wincsp(void *p, size_t n); +mp_err s_read_getrandom(void *p, size_t n); +mp_err s_read_urandom(void *p, size_t n); +mp_err s_read_ltm_rng(void *p, size_t n); + +mp_err s_mp_rand_platform(void *p, size_t n) +{ + mp_err err = MP_ERR; + if ((err != MP_OKAY) && MP_HAS(S_READ_ARC4RANDOM)) err = s_read_arc4random(p, n); + if ((err != MP_OKAY) && MP_HAS(S_READ_WINCSP)) err = s_read_wincsp(p, n); + if ((err != MP_OKAY) && MP_HAS(S_READ_GETRANDOM)) err = s_read_getrandom(p, n); + if ((err != MP_OKAY) && MP_HAS(S_READ_URANDOM)) err = s_read_urandom(p, n); + if ((err != MP_OKAY) && MP_HAS(S_READ_LTM_RNG)) err = s_read_ltm_rng(p, n); + return err; +} + +#endif diff --git a/libtommath/bn_s_mp_reverse.c b/libtommath/bn_s_mp_reverse.c new file mode 100644 index 0000000..c549e60 --- /dev/null +++ b/libtommath/bn_s_mp_reverse.c @@ -0,0 +1,22 @@ +#include "tommath_private.h" +#ifdef BN_S_MP_REVERSE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* reverse an array, used for radix code */ +void s_mp_reverse(unsigned char *s, size_t len) +{ + size_t ix, iy; + unsigned char t; + + ix = 0u; + iy = len - 1u; + while (ix < iy) { + t = s[ix]; + s[ix] = s[iy]; + s[iy] = t; + ++ix; + --iy; + } +} +#endif diff --git a/libtommath/bn_s_mp_sqr.c b/libtommath/bn_s_mp_sqr.c index ac0e157..505c9f0 100644 --- a/libtommath/bn_s_mp_sqr.c +++ b/libtommath/bn_s_mp_sqr.c @@ -1,84 +1,69 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_S_MP_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */ -int s_mp_sqr (mp_int * a, mp_int * b) +mp_err s_mp_sqr(const mp_int *a, mp_int *b) { - mp_int t; - int res, ix, iy, pa; - mp_word r; - mp_digit u, tmpx, *tmpt; + mp_int t; + int ix, iy, pa; + mp_err err; + mp_word r; + mp_digit u, tmpx, *tmpt; - pa = a->used; - if ((res = mp_init_size (&t, (2 * pa) + 1)) != MP_OKAY) { - return res; - } + pa = a->used; + if ((err = mp_init_size(&t, (2 * pa) + 1)) != MP_OKAY) { + return err; + } - /* default used is maximum possible size */ - t.used = (2 * pa) + 1; + /* default used is maximum possible size */ + t.used = (2 * pa) + 1; - for (ix = 0; ix < pa; ix++) { - /* first calculate the digit at 2*ix */ - /* calculate double precision result */ - r = (mp_word)t.dp[2*ix] + - ((mp_word)a->dp[ix] * (mp_word)a->dp[ix]); + for (ix = 0; ix < pa; ix++) { + /* first calculate the digit at 2*ix */ + /* calculate double precision result */ + r = (mp_word)t.dp[2*ix] + + ((mp_word)a->dp[ix] * (mp_word)a->dp[ix]); - /* store lower part in result */ - t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK)); + /* store lower part in result */ + t.dp[ix+ix] = (mp_digit)(r & (mp_word)MP_MASK); - /* get the carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + /* get the carry */ + u = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT); - /* left hand side of A[ix] * A[iy] */ - tmpx = a->dp[ix]; + /* left hand side of A[ix] * A[iy] */ + tmpx = a->dp[ix]; - /* alias for where to store the results */ - tmpt = t.dp + ((2 * ix) + 1); - - for (iy = ix + 1; iy < pa; iy++) { - /* first calculate the product */ - r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]); + /* alias for where to store the results */ + tmpt = t.dp + ((2 * ix) + 1); - /* now calculate the double precision result, note we use - * addition instead of *2 since it's easier to optimize - */ - r = ((mp_word) *tmpt) + r + r + ((mp_word) u); + for (iy = ix + 1; iy < pa; iy++) { + /* first calculate the product */ + r = (mp_word)tmpx * (mp_word)a->dp[iy]; - /* store lower part */ - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + /* now calculate the double precision result, note we use + * addition instead of *2 since it's easier to optimize + */ + r = (mp_word)*tmpt + r + r + (mp_word)u; - /* get carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - } - /* propagate upwards */ - while (u != ((mp_digit) 0)) { - r = ((mp_word) *tmpt) + ((mp_word) u); - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - } - } + /* store lower part */ + *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK); - mp_clamp (&t); - mp_exch (&t, b); - mp_clear (&t); - return MP_OKAY; + /* get carry */ + u = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT); + } + /* propagate upwards */ + while (u != 0uL) { + r = (mp_word)*tmpt + (mp_word)u; + *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK); + u = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT); + } + } + + mp_clamp(&t); + mp_exch(&t, b); + mp_clear(&t); + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_s_mp_sqr_fast.c b/libtommath/bn_s_mp_sqr_fast.c new file mode 100644 index 0000000..4a8a891 --- /dev/null +++ b/libtommath/bn_s_mp_sqr_fast.c @@ -0,0 +1,97 @@ +#include "tommath_private.h" +#ifdef BN_S_MP_SQR_FAST_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* the jist of squaring... + * you do like mult except the offset of the tmpx [one that + * starts closer to zero] can't equal the offset of tmpy. + * So basically you set up iy like before then you min it with + * (ty-tx) so that it never happens. You double all those + * you add in the inner loop + +After that loop you do the squares and add them in. +*/ + +mp_err s_mp_sqr_fast(const mp_int *a, mp_int *b) +{ + int olduse, pa, ix, iz; + mp_digit W[MP_WARRAY], *tmpx; + mp_word W1; + mp_err err; + + /* grow the destination as required */ + pa = a->used + a->used; + if (b->alloc < pa) { + if ((err = mp_grow(b, pa)) != MP_OKAY) { + return err; + } + } + + /* number of output digits to produce */ + W1 = 0; + for (ix = 0; ix < pa; ix++) { + int tx, ty, iy; + mp_word _W; + mp_digit *tmpy; + + /* clear counter */ + _W = 0; + + /* get offsets into the two bignums */ + ty = MP_MIN(a->used-1, ix); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = a->dp + ty; + + /* this is the number of times the loop will iterrate, essentially + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MP_MIN(a->used-tx, ty+1); + + /* now for squaring tx can never equal ty + * we halve the distance since they approach at a rate of 2x + * and we have to round because odd cases need to be executed + */ + iy = MP_MIN(iy, ((ty-tx)+1)>>1); + + /* execute loop */ + for (iz = 0; iz < iy; iz++) { + _W += (mp_word)*tmpx++ * (mp_word)*tmpy--; + } + + /* double the inner product and add carry */ + _W = _W + _W + W1; + + /* even columns have the square term in them */ + if (((unsigned)ix & 1u) == 0u) { + _W += (mp_word)a->dp[ix>>1] * (mp_word)a->dp[ix>>1]; + } + + /* store it */ + W[ix] = (mp_digit)_W & MP_MASK; + + /* make next carry */ + W1 = _W >> (mp_word)MP_DIGIT_BIT; + } + + /* setup dest */ + olduse = b->used; + b->used = a->used+a->used; + + { + mp_digit *tmpb; + tmpb = b->dp; + for (ix = 0; ix < pa; ix++) { + *tmpb++ = W[ix] & MP_MASK; + } + + /* clear unused digits [that existed in the old copy of c] */ + MP_ZERO_DIGITS(tmpb, olduse - ix); + } + mp_clamp(b); + return MP_OKAY; +} +#endif diff --git a/libtommath/bn_s_mp_sub.c b/libtommath/bn_s_mp_sub.c index 8091f4a..5672dab 100644 --- a/libtommath/bn_s_mp_sub.c +++ b/libtommath/bn_s_mp_sub.c @@ -1,89 +1,71 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_S_MP_SUB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */ -int -s_mp_sub (mp_int * a, mp_int * b, mp_int * c) +mp_err s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c) { - int olduse, res, min, max; + int olduse, min, max; + mp_err err; - /* find sizes */ - min = b->used; - max = a->used; + /* find sizes */ + min = b->used; + max = a->used; - /* init result */ - if (c->alloc < max) { - if ((res = mp_grow (c, max)) != MP_OKAY) { - return res; - } - } - olduse = c->used; - c->used = max; + /* init result */ + if (c->alloc < max) { + if ((err = mp_grow(c, max)) != MP_OKAY) { + return err; + } + } + olduse = c->used; + c->used = max; - { - mp_digit u, *tmpa, *tmpb, *tmpc; - int i; + { + mp_digit u, *tmpa, *tmpb, *tmpc; + int i; - /* alias for digit pointers */ - tmpa = a->dp; - tmpb = b->dp; - tmpc = c->dp; + /* alias for digit pointers */ + tmpa = a->dp; + tmpb = b->dp; + tmpc = c->dp; - /* set carry to zero */ - u = 0; - for (i = 0; i < min; i++) { - /* T[i] = A[i] - B[i] - U */ - *tmpc = (*tmpa++ - *tmpb++) - u; + /* set carry to zero */ + u = 0; + for (i = 0; i < min; i++) { + /* T[i] = A[i] - B[i] - U */ + *tmpc = (*tmpa++ - *tmpb++) - u; - /* U = carry bit of T[i] - * Note this saves performing an AND operation since - * if a carry does occur it will propagate all the way to the - * MSB. As a result a single shift is enough to get the carry - */ - u = *tmpc >> ((mp_digit)((CHAR_BIT * sizeof(mp_digit)) - 1)); + /* U = carry bit of T[i] + * Note this saves performing an AND operation since + * if a carry does occur it will propagate all the way to the + * MSB. As a result a single shift is enough to get the carry + */ + u = *tmpc >> (MP_SIZEOF_BITS(mp_digit) - 1u); - /* Clear carry from T[i] */ - *tmpc++ &= MP_MASK; - } + /* Clear carry from T[i] */ + *tmpc++ &= MP_MASK; + } - /* now copy higher words if any, e.g. if A has more digits than B */ - for (; i < max; i++) { - /* T[i] = A[i] - U */ - *tmpc = *tmpa++ - u; + /* now copy higher words if any, e.g. if A has more digits than B */ + for (; i < max; i++) { + /* T[i] = A[i] - U */ + *tmpc = *tmpa++ - u; - /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)((CHAR_BIT * sizeof(mp_digit)) - 1)); + /* U = carry bit of T[i] */ + u = *tmpc >> (MP_SIZEOF_BITS(mp_digit) - 1u); - /* Clear carry from T[i] */ - *tmpc++ &= MP_MASK; - } + /* Clear carry from T[i] */ + *tmpc++ &= MP_MASK; + } - /* clear digits above used (since we may not have grown result above) */ - for (i = c->used; i < olduse; i++) { - *tmpc++ = 0; - } - } + /* clear digits above used (since we may not have grown result above) */ + MP_ZERO_DIGITS(tmpc, olduse - c->used); + } - mp_clamp (c); - return MP_OKAY; + mp_clamp(c); + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/bn_s_mp_toom_mul.c b/libtommath/bn_s_mp_toom_mul.c new file mode 100644 index 0000000..86901b0 --- /dev/null +++ b/libtommath/bn_s_mp_toom_mul.c @@ -0,0 +1,215 @@ +#include "tommath_private.h" +#ifdef BN_S_MP_TOOM_MUL_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* multiplication using the Toom-Cook 3-way algorithm + * + * Much more complicated than Karatsuba but has a lower + * asymptotic running time of O(N**1.464). This algorithm is + * only particularly useful on VERY large inputs + * (we're talking 1000s of digits here...). +*/ + +/* + This file contains code from J. Arndt's book "Matters Computational" + and the accompanying FXT-library with permission of the author. +*/ + +/* + Setup from + + Chung, Jaewook, and M. Anwar Hasan. "Asymmetric squaring formulae." + 18th IEEE Symposium on Computer Arithmetic (ARITH'07). IEEE, 2007. + + The interpolation from above needed one temporary variable more + than the interpolation here: + + Bodrato, Marco, and Alberto Zanoni. "What about Toom-Cook matrices optimality." + Centro Vito Volterra Universita di Roma Tor Vergata (2006) +*/ + +mp_err s_mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c) +{ + mp_int S1, S2, T1, a0, a1, a2, b0, b1, b2; + int B, count; + mp_err err; + + /* init temps */ + if ((err = mp_init_multi(&S1, &S2, &T1, NULL)) != MP_OKAY) { + return err; + } + + /* B */ + B = MP_MIN(a->used, b->used) / 3; + + /** a = a2 * x^2 + a1 * x + a0; */ + if ((err = mp_init_size(&a0, B)) != MP_OKAY) goto LBL_ERRa0; + + for (count = 0; count < B; count++) { + a0.dp[count] = a->dp[count]; + a0.used++; + } + mp_clamp(&a0); + if ((err = mp_init_size(&a1, B)) != MP_OKAY) goto LBL_ERRa1; + for (; count < (2 * B); count++) { + a1.dp[count - B] = a->dp[count]; + a1.used++; + } + mp_clamp(&a1); + if ((err = mp_init_size(&a2, B + (a->used - (3 * B)))) != MP_OKAY) goto LBL_ERRa2; + for (; count < a->used; count++) { + a2.dp[count - (2 * B)] = a->dp[count]; + a2.used++; + } + mp_clamp(&a2); + + /** b = b2 * x^2 + b1 * x + b0; */ + if ((err = mp_init_size(&b0, B)) != MP_OKAY) goto LBL_ERRb0; + for (count = 0; count < B; count++) { + b0.dp[count] = b->dp[count]; + b0.used++; + } + mp_clamp(&b0); + if ((err = mp_init_size(&b1, B)) != MP_OKAY) goto LBL_ERRb1; + for (; count < (2 * B); count++) { + b1.dp[count - B] = b->dp[count]; + b1.used++; + } + mp_clamp(&b1); + if ((err = mp_init_size(&b2, B + (b->used - (3 * B)))) != MP_OKAY) goto LBL_ERRb2; + for (; count < b->used; count++) { + b2.dp[count - (2 * B)] = b->dp[count]; + b2.used++; + } + mp_clamp(&b2); + + /** \\ S1 = (a2+a1+a0) * (b2+b1+b0); */ + /** T1 = a2 + a1; */ + if ((err = mp_add(&a2, &a1, &T1)) != MP_OKAY) goto LBL_ERR; + + /** S2 = T1 + a0; */ + if ((err = mp_add(&T1, &a0, &S2)) != MP_OKAY) goto LBL_ERR; + + /** c = b2 + b1; */ + if ((err = mp_add(&b2, &b1, c)) != MP_OKAY) goto LBL_ERR; + + /** S1 = c + b0; */ + if ((err = mp_add(c, &b0, &S1)) != MP_OKAY) goto LBL_ERR; + + /** S1 = S1 * S2; */ + if ((err = mp_mul(&S1, &S2, &S1)) != MP_OKAY) goto LBL_ERR; + + /** \\S2 = (4*a2+2*a1+a0) * (4*b2+2*b1+b0); */ + /** T1 = T1 + a2; */ + if ((err = mp_add(&T1, &a2, &T1)) != MP_OKAY) goto LBL_ERR; + + /** T1 = T1 << 1; */ + if ((err = mp_mul_2(&T1, &T1)) != MP_OKAY) goto LBL_ERR; + + /** T1 = T1 + a0; */ + if ((err = mp_add(&T1, &a0, &T1)) != MP_OKAY) goto LBL_ERR; + + /** c = c + b2; */ + if ((err = mp_add(c, &b2, c)) != MP_OKAY) goto LBL_ERR; + + /** c = c << 1; */ + if ((err = mp_mul_2(c, c)) != MP_OKAY) goto LBL_ERR; + + /** c = c + b0; */ + if ((err = mp_add(c, &b0, c)) != MP_OKAY) goto LBL_ERR; + + /** S2 = T1 * c; */ + if ((err = mp_mul(&T1, c, &S2)) != MP_OKAY) goto LBL_ERR; + + /** \\S3 = (a2-a1+a0) * (b2-b1+b0); */ + /** a1 = a2 - a1; */ + if ((err = mp_sub(&a2, &a1, &a1)) != MP_OKAY) goto LBL_ERR; + + /** a1 = a1 + a0; */ + if ((err = mp_add(&a1, &a0, &a1)) != MP_OKAY) goto LBL_ERR; + + /** b1 = b2 - b1; */ + if ((err = mp_sub(&b2, &b1, &b1)) != MP_OKAY) goto LBL_ERR; + + /** b1 = b1 + b0; */ + if ((err = mp_add(&b1, &b0, &b1)) != MP_OKAY) goto LBL_ERR; + + /** a1 = a1 * b1; */ + if ((err = mp_mul(&a1, &b1, &a1)) != MP_OKAY) goto LBL_ERR; + + /** b1 = a2 * b2; */ + if ((err = mp_mul(&a2, &b2, &b1)) != MP_OKAY) goto LBL_ERR; + + /** \\S2 = (S2 - S3)/3; */ + /** S2 = S2 - a1; */ + if ((err = mp_sub(&S2, &a1, &S2)) != MP_OKAY) goto LBL_ERR; + + /** S2 = S2 / 3; \\ this is an exact division */ + if ((err = mp_div_3(&S2, &S2, NULL)) != MP_OKAY) goto LBL_ERR; + + /** a1 = S1 - a1; */ + if ((err = mp_sub(&S1, &a1, &a1)) != MP_OKAY) goto LBL_ERR; + + /** a1 = a1 >> 1; */ + if ((err = mp_div_2(&a1, &a1)) != MP_OKAY) goto LBL_ERR; + + /** a0 = a0 * b0; */ + if ((err = mp_mul(&a0, &b0, &a0)) != MP_OKAY) goto LBL_ERR; + + /** S1 = S1 - a0; */ + if ((err = mp_sub(&S1, &a0, &S1)) != MP_OKAY) goto LBL_ERR; + + /** S2 = S2 - S1; */ + if ((err = mp_sub(&S2, &S1, &S2)) != MP_OKAY) goto LBL_ERR; + + /** S2 = S2 >> 1; */ + if ((err = mp_div_2(&S2, &S2)) != MP_OKAY) goto LBL_ERR; + + /** S1 = S1 - a1; */ + if ((err = mp_sub(&S1, &a1, &S1)) != MP_OKAY) goto LBL_ERR; + + /** S1 = S1 - b1; */ + if ((err = mp_sub(&S1, &b1, &S1)) != MP_OKAY) goto LBL_ERR; + + /** T1 = b1 << 1; */ + if ((err = mp_mul_2(&b1, &T1)) != MP_OKAY) goto LBL_ERR; + + /** S2 = S2 - T1; */ + if ((err = mp_sub(&S2, &T1, &S2)) != MP_OKAY) goto LBL_ERR; + + /** a1 = a1 - S2; */ + if ((err = mp_sub(&a1, &S2, &a1)) != MP_OKAY) goto LBL_ERR; + + + /** P = b1*x^4+ S2*x^3+ S1*x^2+ a1*x + a0; */ + if ((err = mp_lshd(&b1, 4 * B)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_lshd(&S2, 3 * B)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_add(&b1, &S2, &b1)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_lshd(&S1, 2 * B)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_add(&b1, &S1, &b1)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_lshd(&a1, 1 * B)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_add(&b1, &a1, &b1)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_add(&b1, &a0, c)) != MP_OKAY) goto LBL_ERR; + + /** a * b - P */ + + +LBL_ERR: + mp_clear(&b2); +LBL_ERRb2: + mp_clear(&b1); +LBL_ERRb1: + mp_clear(&b0); +LBL_ERRb0: + mp_clear(&a2); +LBL_ERRa2: + mp_clear(&a1); +LBL_ERRa1: + mp_clear(&a0); +LBL_ERRa0: + mp_clear_multi(&S1, &S2, &T1, NULL); + return err; +} + +#endif diff --git a/libtommath/bn_s_mp_toom_sqr.c b/libtommath/bn_s_mp_toom_sqr.c new file mode 100644 index 0000000..f2ffb30 --- /dev/null +++ b/libtommath/bn_s_mp_toom_sqr.c @@ -0,0 +1,147 @@ +#include "tommath_private.h" +#ifdef BN_S_MP_TOOM_SQR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* squaring using Toom-Cook 3-way algorithm */ + +/* + This file contains code from J. Arndt's book "Matters Computational" + and the accompanying FXT-library with permission of the author. +*/ + +/* squaring using Toom-Cook 3-way algorithm */ +/* + Setup and interpolation from algorithm SQR_3 in + + Chung, Jaewook, and M. Anwar Hasan. "Asymmetric squaring formulae." + 18th IEEE Symposium on Computer Arithmetic (ARITH'07). IEEE, 2007. + +*/ +mp_err s_mp_toom_sqr(const mp_int *a, mp_int *b) +{ + mp_int S0, a0, a1, a2; + mp_digit *tmpa, *tmpc; + int B, count; + mp_err err; + + + /* init temps */ + if ((err = mp_init(&S0)) != MP_OKAY) { + return err; + } + + /* B */ + B = a->used / 3; + + /** a = a2 * x^2 + a1 * x + a0; */ + if ((err = mp_init_size(&a0, B)) != MP_OKAY) goto LBL_ERRa0; + + a0.used = B; + if ((err = mp_init_size(&a1, B)) != MP_OKAY) goto LBL_ERRa1; + a1.used = B; + if ((err = mp_init_size(&a2, B + (a->used - (3 * B)))) != MP_OKAY) goto LBL_ERRa2; + + tmpa = a->dp; + tmpc = a0.dp; + for (count = 0; count < B; count++) { + *tmpc++ = *tmpa++; + } + tmpc = a1.dp; + for (; count < (2 * B); count++) { + *tmpc++ = *tmpa++; + } + tmpc = a2.dp; + for (; count < a->used; count++) { + *tmpc++ = *tmpa++; + a2.used++; + } + mp_clamp(&a0); + mp_clamp(&a1); + mp_clamp(&a2); + + /** S0 = a0^2; */ + if ((err = mp_sqr(&a0, &S0)) != MP_OKAY) goto LBL_ERR; + + /** \\S1 = (a2 + a1 + a0)^2 */ + /** \\S2 = (a2 - a1 + a0)^2 */ + /** \\S1 = a0 + a2; */ + /** a0 = a0 + a2; */ + if ((err = mp_add(&a0, &a2, &a0)) != MP_OKAY) goto LBL_ERR; + /** \\S2 = S1 - a1; */ + /** b = a0 - a1; */ + if ((err = mp_sub(&a0, &a1, b)) != MP_OKAY) goto LBL_ERR; + /** \\S1 = S1 + a1; */ + /** a0 = a0 + a1; */ + if ((err = mp_add(&a0, &a1, &a0)) != MP_OKAY) goto LBL_ERR; + /** \\S1 = S1^2; */ + /** a0 = a0^2; */ + if ((err = mp_sqr(&a0, &a0)) != MP_OKAY) goto LBL_ERR; + /** \\S2 = S2^2; */ + /** b = b^2; */ + if ((err = mp_sqr(b, b)) != MP_OKAY) goto LBL_ERR; + + /** \\ S3 = 2 * a1 * a2 */ + /** \\S3 = a1 * a2; */ + /** a1 = a1 * a2; */ + if ((err = mp_mul(&a1, &a2, &a1)) != MP_OKAY) goto LBL_ERR; + /** \\S3 = S3 << 1; */ + /** a1 = a1 << 1; */ + if ((err = mp_mul_2(&a1, &a1)) != MP_OKAY) goto LBL_ERR; + + /** \\S4 = a2^2; */ + /** a2 = a2^2; */ + if ((err = mp_sqr(&a2, &a2)) != MP_OKAY) goto LBL_ERR; + + /** \\ tmp = (S1 + S2)/2 */ + /** \\tmp = S1 + S2; */ + /** b = a0 + b; */ + if ((err = mp_add(&a0, b, b)) != MP_OKAY) goto LBL_ERR; + /** \\tmp = tmp >> 1; */ + /** b = b >> 1; */ + if ((err = mp_div_2(b, b)) != MP_OKAY) goto LBL_ERR; + + /** \\ S1 = S1 - tmp - S3 */ + /** \\S1 = S1 - tmp; */ + /** a0 = a0 - b; */ + if ((err = mp_sub(&a0, b, &a0)) != MP_OKAY) goto LBL_ERR; + /** \\S1 = S1 - S3; */ + /** a0 = a0 - a1; */ + if ((err = mp_sub(&a0, &a1, &a0)) != MP_OKAY) goto LBL_ERR; + + /** \\S2 = tmp - S4 -S0 */ + /** \\S2 = tmp - S4; */ + /** b = b - a2; */ + if ((err = mp_sub(b, &a2, b)) != MP_OKAY) goto LBL_ERR; + /** \\S2 = S2 - S0; */ + /** b = b - S0; */ + if ((err = mp_sub(b, &S0, b)) != MP_OKAY) goto LBL_ERR; + + + /** \\P = S4*x^4 + S3*x^3 + S2*x^2 + S1*x + S0; */ + /** P = a2*x^4 + a1*x^3 + b*x^2 + a0*x + S0; */ + + if ((err = mp_lshd(&a2, 4 * B)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_lshd(&a1, 3 * B)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_lshd(b, 2 * B)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_lshd(&a0, 1 * B)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_add(&a2, &a1, &a2)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_add(&a2, b, b)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_add(b, &a0, b)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_add(b, &S0, b)) != MP_OKAY) goto LBL_ERR; + /** a^2 - P */ + + +LBL_ERR: + mp_clear(&a2); +LBL_ERRa2: + mp_clear(&a1); +LBL_ERRa1: + mp_clear(&a0); +LBL_ERRa0: + mp_clear(&S0); + + return err; +} + +#endif diff --git a/libtommath/bncore.c b/libtommath/bncore.c deleted file mode 100644 index e80ec99..0000000 --- a/libtommath/bncore.c +++ /dev/null @@ -1,36 +0,0 @@ -#include <tommath_private.h> -#ifdef BNCORE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* Known optimal configurations - - CPU /Compiler /MUL CUTOFF/SQR CUTOFF -------------------------------------------------------------- - Intel P4 Northwood /GCC v3.4.1 / 88/ 128/LTM 0.32 ;-) - AMD Athlon64 /GCC v3.4.4 / 80/ 120/LTM 0.35 - -*/ - -int KARATSUBA_MUL_CUTOFF = 80, /* Min. number of digits before Karatsuba multiplication is used. */ - KARATSUBA_SQR_CUTOFF = 120, /* Min. number of digits before Karatsuba squaring is used. */ - - TOOM_MUL_CUTOFF = 350, /* no optimal values of these are known yet so set em high */ - TOOM_SQR_CUTOFF = 400; -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/booker.pl b/libtommath/booker.pl deleted file mode 100644 index c2abae6..0000000 --- a/libtommath/booker.pl +++ /dev/null @@ -1,267 +0,0 @@ -#!/bin/perl -# -#Used to prepare the book "tommath.src" for LaTeX by pre-processing it into a .tex file -# -#Essentially you write the "tommath.src" as normal LaTex except where you want code snippets you put -# -#EXAM,file -# -#This preprocessor will then open "file" and insert it as a verbatim copy. -# -#Tom St Denis - -#get graphics type -if (shift =~ /PDF/) { - $graph = ""; -} else { - $graph = ".ps"; -} - -open(IN,"<tommath.src") or die "Can't open source file"; -open(OUT,">tommath.tex") or die "Can't open destination file"; - -print "Scanning for sections\n"; -$chapter = $section = $subsection = 0; -$x = 0; -while (<IN>) { - print "."; - if (!(++$x % 80)) { print "\n"; } - #update the headings - if (~($_ =~ /\*/)) { - if ($_ =~ /\\chapter\{.+}/) { - ++$chapter; - $section = $subsection = 0; - } elsif ($_ =~ /\\section\{.+}/) { - ++$section; - $subsection = 0; - } elsif ($_ =~ /\\subsection\{.+}/) { - ++$subsection; - } - } - - if ($_ =~ m/MARK/) { - @m = split(",",$_); - chomp(@m[1]); - $index1{@m[1]} = $chapter; - $index2{@m[1]} = $section; - $index3{@m[1]} = $subsection; - } -} -close(IN); - -open(IN,"<tommath.src") or die "Can't open source file"; -$readline = $wroteline = 0; -$srcline = 0; - -while (<IN>) { - ++$readline; - ++$srcline; - - if ($_ =~ m/MARK/) { - } elsif ($_ =~ m/EXAM/ || $_ =~ m/LIST/) { - if ($_ =~ m/EXAM/) { - $skipheader = 1; - } else { - $skipheader = 0; - } - - # EXAM,file - chomp($_); - @m = split(",",$_); - open(SRC,"<$m[1]") or die "Error:$srcline:Can't open source file $m[1]"; - - print "$srcline:Inserting $m[1]:"; - - $line = 0; - $tmp = $m[1]; - $tmp =~ s/_/"\\_"/ge; - print OUT "\\vspace{+3mm}\\begin{small}\n\\hspace{-5.1mm}{\\bf File}: $tmp\n\\vspace{-3mm}\n\\begin{alltt}\n"; - $wroteline += 5; - - if ($skipheader == 1) { - # scan till next end of comment, e.g. skip license - while (<SRC>) { - $text[$line++] = $_; - last if ($_ =~ /libtom\.org/); - } - <SRC>; - } - - $inline = 0; - while (<SRC>) { - next if ($_ =~ /\$Source/); - next if ($_ =~ /\$Revision/); - next if ($_ =~ /\$Date/); - $text[$line++] = $_; - ++$inline; - chomp($_); - $_ =~ s/\t/" "/ge; - $_ =~ s/{/"^{"/ge; - $_ =~ s/}/"^}"/ge; - $_ =~ s/\\/'\symbol{92}'/ge; - $_ =~ s/\^/"\\"/ge; - - printf OUT ("%03d ", $line); - for ($x = 0; $x < length($_); $x++) { - print OUT chr(vec($_, $x, 8)); - if ($x == 75) { - print OUT "\n "; - ++$wroteline; - } - } - print OUT "\n"; - ++$wroteline; - } - $totlines = $line; - print OUT "\\end{alltt}\n\\end{small}\n"; - close(SRC); - print "$inline lines\n"; - $wroteline += 2; - } elsif ($_ =~ m/@\d+,.+@/) { - # line contains [number,text] - # e.g. @14,for (ix = 0)@ - $txt = $_; - while ($txt =~ m/@\d+,.+@/) { - @m = split("@",$txt); # splits into text, one, two - @parms = split(",",$m[1]); # splits one,two into two elements - - # now search from $parms[0] down for $parms[1] - $found1 = 0; - $found2 = 0; - for ($i = $parms[0]; $i < $totlines && $found1 == 0; $i++) { - if ($text[$i] =~ m/\Q$parms[1]\E/) { - $foundline1 = $i + 1; - $found1 = 1; - } - } - - # now search backwards - for ($i = $parms[0] - 1; $i >= 0 && $found2 == 0; $i--) { - if ($text[$i] =~ m/\Q$parms[1]\E/) { - $foundline2 = $i + 1; - $found2 = 1; - } - } - - # now use the closest match or the first if tied - if ($found1 == 1 && $found2 == 0) { - $found = 1; - $foundline = $foundline1; - } elsif ($found1 == 0 && $found2 == 1) { - $found = 1; - $foundline = $foundline2; - } elsif ($found1 == 1 && $found2 == 1) { - $found = 1; - if (($foundline1 - $parms[0]) <= ($parms[0] - $foundline2)) { - $foundline = $foundline1; - } else { - $foundline = $foundline2; - } - } else { - $found = 0; - } - - # if found replace - if ($found == 1) { - $delta = $parms[0] - $foundline; - print "Found replacement tag for \"$parms[1]\" on line $srcline which refers to line $foundline (delta $delta)\n"; - $_ =~ s/@\Q$m[1]\E@/$foundline/; - } else { - print "ERROR: The tag \"$parms[1]\" on line $srcline was not found in the most recently parsed source!\n"; - } - - # remake the rest of the line - $cnt = @m; - $txt = ""; - for ($i = 2; $i < $cnt; $i++) { - $txt = $txt . $m[$i] . "@"; - } - } - print OUT $_; - ++$wroteline; - } elsif ($_ =~ /~.+~/) { - # line contains a ~text~ pair used to refer to indexing :-) - $txt = $_; - while ($txt =~ /~.+~/) { - @m = split("~", $txt); - - # word is the second position - $word = @m[1]; - $a = $index1{$word}; - $b = $index2{$word}; - $c = $index3{$word}; - - # if chapter (a) is zero it wasn't found - if ($a == 0) { - print "ERROR: the tag \"$word\" on line $srcline was not found previously marked.\n"; - } else { - # format the tag as x, x.y or x.y.z depending on the values - $str = $a; - $str = $str . ".$b" if ($b != 0); - $str = $str . ".$c" if ($c != 0); - - if ($b == 0 && $c == 0) { - # its a chapter - if ($a <= 10) { - if ($a == 1) { - $str = "chapter one"; - } elsif ($a == 2) { - $str = "chapter two"; - } elsif ($a == 3) { - $str = "chapter three"; - } elsif ($a == 4) { - $str = "chapter four"; - } elsif ($a == 5) { - $str = "chapter five"; - } elsif ($a == 6) { - $str = "chapter six"; - } elsif ($a == 7) { - $str = "chapter seven"; - } elsif ($a == 8) { - $str = "chapter eight"; - } elsif ($a == 9) { - $str = "chapter nine"; - } elsif ($a == 10) { - $str = "chapter ten"; - } - } else { - $str = "chapter " . $str; - } - } else { - $str = "section " . $str if ($b != 0 && $c == 0); - $str = "sub-section " . $str if ($b != 0 && $c != 0); - } - - #substitute - $_ =~ s/~\Q$word\E~/$str/; - - print "Found replacement tag for marker \"$word\" on line $srcline which refers to $str\n"; - } - - # remake rest of the line - $cnt = @m; - $txt = ""; - for ($i = 2; $i < $cnt; $i++) { - $txt = $txt . $m[$i] . "~"; - } - } - print OUT $_; - ++$wroteline; - } elsif ($_ =~ m/FIGU/) { - # FIGU,file,caption - chomp($_); - @m = split(",", $_); - print OUT "\\begin{center}\n\\begin{figure}[here]\n\\includegraphics{pics/$m[1]$graph}\n"; - print OUT "\\caption{$m[2]}\n\\label{pic:$m[1]}\n\\end{figure}\n\\end{center}\n"; - $wroteline += 4; - } else { - print OUT $_; - ++$wroteline; - } -} -print "Read $readline lines, wrote $wroteline lines\n"; - -close (OUT); -close (IN); - -system('perl -pli -e "s/\s*$//" tommath.tex'); diff --git a/libtommath/callgraph.txt b/libtommath/callgraph.txt deleted file mode 100644 index 52007c0..0000000 --- a/libtommath/callgraph.txt +++ /dev/null @@ -1,13188 +0,0 @@ -BNCORE_C - - -BN_ERROR_C - - -BN_FAST_MP_INVMOD_C -+--->BN_MP_INIT_MULTI_C -| +--->BN_MP_INIT_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_MOD_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C -+--->BN_MP_DIV_2_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_SUB_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_CMP_C -| +--->BN_MP_CMP_MAG_C -+--->BN_MP_CMP_D_C -+--->BN_MP_ADD_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_CLEAR_C - - -BN_FAST_MP_MONTGOMERY_REDUCE_C -+--->BN_MP_GROW_C -+--->BN_MP_RSHD_C -| +--->BN_MP_ZERO_C -+--->BN_MP_CLAMP_C -+--->BN_MP_CMP_MAG_C -+--->BN_S_MP_SUB_C - - -BN_FAST_S_MP_MUL_DIGS_C -+--->BN_MP_GROW_C -+--->BN_MP_CLAMP_C - - -BN_FAST_S_MP_MUL_HIGH_DIGS_C -+--->BN_MP_GROW_C -+--->BN_MP_CLAMP_C - - -BN_FAST_S_MP_SQR_C -+--->BN_MP_GROW_C -+--->BN_MP_CLAMP_C - - -BN_MP_2EXPT_C -+--->BN_MP_ZERO_C -+--->BN_MP_GROW_C - - -BN_MP_ABS_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C - - -BN_MP_ADDMOD_C -+--->BN_MP_INIT_C -+--->BN_MP_ADD_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_CLEAR_C -+--->BN_MP_MOD_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C - - -BN_MP_ADD_C -+--->BN_S_MP_ADD_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CMP_MAG_C -+--->BN_S_MP_SUB_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C - - -BN_MP_ADD_D_C -+--->BN_MP_GROW_C -+--->BN_MP_SUB_D_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLAMP_C - - -BN_MP_AND_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_CLAMP_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_C - - -BN_MP_CLAMP_C - - -BN_MP_CLEAR_C - - -BN_MP_CLEAR_MULTI_C -+--->BN_MP_CLEAR_C - - -BN_MP_CMP_C -+--->BN_MP_CMP_MAG_C - - -BN_MP_CMP_D_C - - -BN_MP_CMP_MAG_C - - -BN_MP_CNT_LSB_C - - -BN_MP_COPY_C -+--->BN_MP_GROW_C - - -BN_MP_COUNT_BITS_C - - -BN_MP_DIV_2D_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_ZERO_C -+--->BN_MP_MOD_2D_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_RSHD_C -+--->BN_MP_CLAMP_C - - -BN_MP_DIV_2_C -+--->BN_MP_GROW_C -+--->BN_MP_CLAMP_C - - -BN_MP_DIV_3_C -+--->BN_MP_INIT_SIZE_C -| +--->BN_MP_INIT_C -+--->BN_MP_CLAMP_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_C - - -BN_MP_DIV_C -+--->BN_MP_CMP_MAG_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_ZERO_C -+--->BN_MP_INIT_MULTI_C -| +--->BN_MP_INIT_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_SET_C -+--->BN_MP_COUNT_BITS_C -+--->BN_MP_ABS_C -+--->BN_MP_MUL_2D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CMP_C -+--->BN_MP_SUB_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_ADD_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_DIV_2D_C -| +--->BN_MP_MOD_2D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_INIT_SIZE_C -| +--->BN_MP_INIT_C -+--->BN_MP_INIT_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_LSHD_C -| +--->BN_MP_GROW_C -| +--->BN_MP_RSHD_C -+--->BN_MP_RSHD_C -+--->BN_MP_MUL_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLAMP_C -+--->BN_MP_CLEAR_C - - -BN_MP_DIV_D_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_DIV_2D_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_MOD_2D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_DIV_3_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_INIT_SIZE_C -| +--->BN_MP_INIT_C -+--->BN_MP_CLAMP_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_C - - -BN_MP_DR_IS_MODULUS_C - - -BN_MP_DR_REDUCE_C -+--->BN_MP_GROW_C -+--->BN_MP_CLAMP_C -+--->BN_MP_CMP_MAG_C -+--->BN_S_MP_SUB_C - - -BN_MP_DR_SETUP_C - - -BN_MP_EXCH_C - - -BN_MP_EXPORT_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_COUNT_BITS_C -+--->BN_MP_DIV_2D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_MOD_2D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLEAR_C - - -BN_MP_EXPTMOD_C -+--->BN_MP_INIT_C -+--->BN_MP_INVMOD_C -| +--->BN_MP_CMP_D_C -| +--->BN_FAST_MP_INVMOD_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_MOD_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_SET_C -| | | | +--->BN_MP_COUNT_BITS_C -| | | | +--->BN_MP_ABS_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2D_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_INIT_COPY_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SET_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_INVMOD_SLOW_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_SET_C -| | | | +--->BN_MP_COUNT_BITS_C -| | | | +--->BN_MP_ABS_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2D_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_INIT_COPY_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_SET_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -+--->BN_MP_CLEAR_C -+--->BN_MP_ABS_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -+--->BN_MP_CLEAR_MULTI_C -+--->BN_MP_REDUCE_IS_2K_L_C -+--->BN_S_MP_EXPTMOD_C -| +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_REDUCE_SETUP_C -| | +--->BN_MP_2EXPT_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_DIV_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_SET_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_REDUCE_C -| | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_C -| | | +--->BN_MP_TOOM_MUL_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_MUL_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_S_MP_MUL_HIGH_DIGS_C -| | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_MUL_DIGS_C -| | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_D_C -| | +--->BN_MP_SET_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_REDUCE_2K_SETUP_L_C -| | +--->BN_MP_2EXPT_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_REDUCE_2K_L_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_C -| | | +--->BN_MP_TOOM_MUL_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_MUL_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_MOD_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_DIV_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_SET_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_SQR_C -| | +--->BN_MP_TOOM_SQR_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_KARATSUBA_SQR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_MP_CMP_MAG_C -| | +--->BN_FAST_S_MP_SQR_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SQR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| +--->BN_MP_MUL_C -| | +--->BN_MP_TOOM_MUL_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_KARATSUBA_MUL_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_MUL_DIGS_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| +--->BN_MP_SET_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_EXCH_C -+--->BN_MP_DR_IS_MODULUS_C -+--->BN_MP_REDUCE_IS_2K_C -| +--->BN_MP_REDUCE_2K_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_COUNT_BITS_C -+--->BN_MP_EXPTMOD_FAST_C -| +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_MONTGOMERY_SETUP_C -| +--->BN_FAST_MP_MONTGOMERY_REDUCE_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| +--->BN_MP_MONTGOMERY_REDUCE_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| +--->BN_MP_DR_SETUP_C -| +--->BN_MP_DR_REDUCE_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| +--->BN_MP_REDUCE_2K_SETUP_C -| | +--->BN_MP_2EXPT_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_REDUCE_2K_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -| | +--->BN_MP_2EXPT_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_SET_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_MULMOD_C -| | +--->BN_MP_MUL_C -| | | +--->BN_MP_TOOM_MUL_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_MUL_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_MOD_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_SET_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2D_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_INIT_COPY_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| +--->BN_MP_SET_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_MOD_C -| | +--->BN_MP_DIV_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_SQR_C -| | +--->BN_MP_TOOM_SQR_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_KARATSUBA_SQR_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_MP_CMP_MAG_C -| | +--->BN_FAST_S_MP_SQR_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SQR_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| +--->BN_MP_MUL_C -| | +--->BN_MP_TOOM_MUL_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_KARATSUBA_MUL_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_MUL_DIGS_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| +--->BN_MP_EXCH_C - - -BN_MP_EXPTMOD_FAST_C -+--->BN_MP_COUNT_BITS_C -+--->BN_MP_INIT_SIZE_C -| +--->BN_MP_INIT_C -+--->BN_MP_CLEAR_C -+--->BN_MP_MONTGOMERY_SETUP_C -+--->BN_FAST_MP_MONTGOMERY_REDUCE_C -| +--->BN_MP_GROW_C -| +--->BN_MP_RSHD_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -+--->BN_MP_MONTGOMERY_REDUCE_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_RSHD_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -+--->BN_MP_DR_SETUP_C -+--->BN_MP_DR_REDUCE_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -+--->BN_MP_REDUCE_2K_SETUP_C -| +--->BN_MP_INIT_C -| +--->BN_MP_2EXPT_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_GROW_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_REDUCE_2K_C -| +--->BN_MP_INIT_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_MUL_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -| +--->BN_MP_2EXPT_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_SET_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_MUL_2_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_MULMOD_C -| +--->BN_MP_MUL_C -| | +--->BN_MP_TOOM_MUL_C -| | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_INIT_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_KARATSUBA_MUL_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_MUL_DIGS_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| +--->BN_MP_MOD_C -| | +--->BN_MP_DIV_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_INIT_C -| | | +--->BN_MP_SET_C -| | | +--->BN_MP_ABS_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_INIT_C -| | | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C -+--->BN_MP_MOD_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_SQR_C -| +--->BN_MP_TOOM_SQR_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_KARATSUBA_SQR_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | +--->BN_MP_ADD_C -| | | +--->BN_MP_CMP_MAG_C -| +--->BN_FAST_S_MP_SQR_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_SQR_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -+--->BN_MP_MUL_C -| +--->BN_MP_TOOM_MUL_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_KARATSUBA_MUL_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -+--->BN_MP_EXCH_C - - -BN_MP_EXPT_D_C -+--->BN_MP_EXPT_D_EX_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_SET_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_MUL_C -| | +--->BN_MP_TOOM_MUL_C -| | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_KARATSUBA_MUL_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_MUL_DIGS_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_SQR_C -| | +--->BN_MP_TOOM_SQR_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_KARATSUBA_SQR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_MP_CMP_MAG_C -| | +--->BN_FAST_S_MP_SQR_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SQR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C - - -BN_MP_EXPT_D_EX_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C -+--->BN_MP_MUL_C -| +--->BN_MP_TOOM_MUL_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_KARATSUBA_MUL_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_CLEAR_C -+--->BN_MP_SQR_C -| +--->BN_MP_TOOM_SQR_C -| | +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_KARATSUBA_SQR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | +--->BN_MP_ADD_C -| | | +--->BN_MP_CMP_MAG_C -| +--->BN_FAST_S_MP_SQR_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_SQR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C - - -BN_MP_EXTEUCLID_C -+--->BN_MP_INIT_MULTI_C -| +--->BN_MP_INIT_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_DIV_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_ABS_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_INIT_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_MUL_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_MUL_C -| +--->BN_MP_TOOM_MUL_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_KARATSUBA_MUL_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_SUB_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_NEG_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_CLEAR_C - - -BN_MP_FREAD_C -+--->BN_MP_ZERO_C -+--->BN_MP_MUL_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_ADD_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_SUB_D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CMP_D_C - - -BN_MP_FWRITE_C -+--->BN_MP_RADIX_SIZE_C -| +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_DIV_D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_TORADIX_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_DIV_D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C - - -BN_MP_GCD_C -+--->BN_MP_ABS_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_CNT_LSB_C -+--->BN_MP_DIV_2D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_MOD_2D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CMP_MAG_C -+--->BN_MP_EXCH_C -+--->BN_S_MP_SUB_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_MUL_2D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_GROW_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLEAR_C - - -BN_MP_GET_INT_C - - -BN_MP_GET_LONG_C - - -BN_MP_GET_LONG_LONG_C - - -BN_MP_GROW_C - - -BN_MP_IMPORT_C -+--->BN_MP_ZERO_C -+--->BN_MP_MUL_2D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_GROW_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLAMP_C - - -BN_MP_INIT_C - - -BN_MP_INIT_COPY_C -+--->BN_MP_INIT_SIZE_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_CLEAR_C - - -BN_MP_INIT_MULTI_C -+--->BN_MP_INIT_C -+--->BN_MP_CLEAR_C - - -BN_MP_INIT_SET_C -+--->BN_MP_INIT_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C - - -BN_MP_INIT_SET_INT_C -+--->BN_MP_INIT_C -+--->BN_MP_SET_INT_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C - - -BN_MP_INIT_SIZE_C -+--->BN_MP_INIT_C - - -BN_MP_INVMOD_C -+--->BN_MP_CMP_D_C -+--->BN_FAST_MP_INVMOD_C -| +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_MOD_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_DIV_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_SET_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_ABS_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_INIT_C -| | | +--->BN_MP_INIT_COPY_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| +--->BN_MP_SET_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_DIV_2_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_C -| | +--->BN_MP_CMP_MAG_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_INVMOD_SLOW_C -| +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_MOD_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_DIV_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_SET_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_ABS_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_INIT_C -| | | +--->BN_MP_INIT_COPY_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_SET_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_DIV_2_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_C -| | +--->BN_MP_CMP_MAG_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_CLEAR_C - - -BN_MP_INVMOD_SLOW_C -+--->BN_MP_INIT_MULTI_C -| +--->BN_MP_INIT_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_MOD_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C -+--->BN_MP_DIV_2_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_ADD_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_SUB_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_CMP_C -| +--->BN_MP_CMP_MAG_C -+--->BN_MP_CMP_D_C -+--->BN_MP_CMP_MAG_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_CLEAR_C - - -BN_MP_IS_SQUARE_C -+--->BN_MP_MOD_D_C -| +--->BN_MP_DIV_D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_INIT_SET_INT_C -| +--->BN_MP_INIT_C -| +--->BN_MP_SET_INT_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_MOD_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -+--->BN_MP_GET_INT_C -+--->BN_MP_SQRT_C -| +--->BN_MP_N_ROOT_C -| | +--->BN_MP_N_ROOT_EX_C -| | | +--->BN_MP_INIT_C -| | | +--->BN_MP_SET_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_EXPT_D_EX_C -| | | | +--->BN_MP_INIT_COPY_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_MUL_C -| | | | | +--->BN_MP_TOOM_MUL_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | | +--->BN_MP_CLEAR_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_MUL_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_3_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | | +--->BN_MP_CLEAR_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_SQR_C -| | | | | +--->BN_MP_TOOM_SQR_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_MUL_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_3_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_KARATSUBA_SQR_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_FAST_S_MP_SQR_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SQR_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_COUNT_BITS_C -| | | | +--->BN_MP_ABS_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2D_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_COPY_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_SUB_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_2_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_SQR_C -| +--->BN_MP_TOOM_SQR_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_KARATSUBA_SQR_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | +--->BN_MP_ADD_C -| | | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_SQR_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_SQR_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_CMP_MAG_C -+--->BN_MP_CLEAR_C - - -BN_MP_JACOBI_C -+--->BN_MP_CMP_D_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_CNT_LSB_C -+--->BN_MP_DIV_2D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_MOD_2D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_MOD_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -+--->BN_MP_CLEAR_C - - -BN_MP_KARATSUBA_MUL_C -+--->BN_MP_MUL_C -| +--->BN_MP_TOOM_MUL_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_INIT_SIZE_C -| +--->BN_MP_INIT_C -+--->BN_MP_CLAMP_C -+--->BN_S_MP_ADD_C -| +--->BN_MP_GROW_C -+--->BN_MP_ADD_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -+--->BN_S_MP_SUB_C -| +--->BN_MP_GROW_C -+--->BN_MP_LSHD_C -| +--->BN_MP_GROW_C -| +--->BN_MP_RSHD_C -| | +--->BN_MP_ZERO_C -+--->BN_MP_CLEAR_C - - -BN_MP_KARATSUBA_SQR_C -+--->BN_MP_INIT_SIZE_C -| +--->BN_MP_INIT_C -+--->BN_MP_CLAMP_C -+--->BN_MP_SQR_C -| +--->BN_MP_TOOM_SQR_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_SQR_C -| | +--->BN_MP_GROW_C -| +--->BN_S_MP_SQR_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_S_MP_ADD_C -| +--->BN_MP_GROW_C -+--->BN_S_MP_SUB_C -| +--->BN_MP_GROW_C -+--->BN_MP_LSHD_C -| +--->BN_MP_GROW_C -| +--->BN_MP_RSHD_C -| | +--->BN_MP_ZERO_C -+--->BN_MP_ADD_C -| +--->BN_MP_CMP_MAG_C -+--->BN_MP_CLEAR_C - - -BN_MP_LCM_C -+--->BN_MP_INIT_MULTI_C -| +--->BN_MP_INIT_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_GCD_C -| +--->BN_MP_ABS_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_CNT_LSB_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_MP_EXCH_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_CMP_MAG_C -+--->BN_MP_DIV_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_SET_C -| +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_ABS_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_INIT_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_MUL_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_MUL_C -| +--->BN_MP_TOOM_MUL_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_KARATSUBA_MUL_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_CLEAR_C - - -BN_MP_LSHD_C -+--->BN_MP_GROW_C -+--->BN_MP_RSHD_C -| +--->BN_MP_ZERO_C - - -BN_MP_MOD_2D_C -+--->BN_MP_ZERO_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_CLAMP_C - - -BN_MP_MOD_C -+--->BN_MP_INIT_SIZE_C -| +--->BN_MP_INIT_C -+--->BN_MP_DIV_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_SET_C -| +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_ABS_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_INIT_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_MUL_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_CLEAR_C -+--->BN_MP_EXCH_C -+--->BN_MP_ADD_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C - - -BN_MP_MOD_D_C -+--->BN_MP_DIV_D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_3_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C - - -BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -+--->BN_MP_COUNT_BITS_C -+--->BN_MP_2EXPT_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_GROW_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C -+--->BN_MP_MUL_2_C -| +--->BN_MP_GROW_C -+--->BN_MP_CMP_MAG_C -+--->BN_S_MP_SUB_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C - - -BN_MP_MONTGOMERY_REDUCE_C -+--->BN_FAST_MP_MONTGOMERY_REDUCE_C -| +--->BN_MP_GROW_C -| +--->BN_MP_RSHD_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -+--->BN_MP_GROW_C -+--->BN_MP_CLAMP_C -+--->BN_MP_RSHD_C -| +--->BN_MP_ZERO_C -+--->BN_MP_CMP_MAG_C -+--->BN_S_MP_SUB_C - - -BN_MP_MONTGOMERY_SETUP_C - - -BN_MP_MULMOD_C -+--->BN_MP_INIT_SIZE_C -| +--->BN_MP_INIT_C -+--->BN_MP_MUL_C -| +--->BN_MP_TOOM_MUL_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_KARATSUBA_MUL_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_CLEAR_C -+--->BN_MP_MOD_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C - - -BN_MP_MUL_2D_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_GROW_C -+--->BN_MP_LSHD_C -| +--->BN_MP_RSHD_C -| | +--->BN_MP_ZERO_C -+--->BN_MP_CLAMP_C - - -BN_MP_MUL_2_C -+--->BN_MP_GROW_C - - -BN_MP_MUL_C -+--->BN_MP_TOOM_MUL_C -| +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_MOD_2D_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_RSHD_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_MUL_2_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_2_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_MUL_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_3_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_KARATSUBA_MUL_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_CLAMP_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ADD_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| +--->BN_MP_CLEAR_C -+--->BN_FAST_S_MP_MUL_DIGS_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_S_MP_MUL_DIGS_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C - - -BN_MP_MUL_D_C -+--->BN_MP_GROW_C -+--->BN_MP_CLAMP_C - - -BN_MP_NEG_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C - - -BN_MP_N_ROOT_C -+--->BN_MP_N_ROOT_EX_C -| +--->BN_MP_INIT_C -| +--->BN_MP_SET_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_EXPT_D_EX_C -| | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MUL_C -| | | +--->BN_MP_TOOM_MUL_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_KARATSUBA_MUL_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_SQR_C -| | | +--->BN_MP_TOOM_SQR_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_KARATSUBA_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_FAST_S_MP_SQR_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| +--->BN_MP_MUL_C -| | +--->BN_MP_TOOM_MUL_C -| | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_KARATSUBA_MUL_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_MUL_DIGS_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_MUL_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_CMP_C -| | +--->BN_MP_CMP_MAG_C -| +--->BN_MP_SUB_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C - - -BN_MP_N_ROOT_EX_C -+--->BN_MP_INIT_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_EXPT_D_EX_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_MUL_C -| | +--->BN_MP_TOOM_MUL_C -| | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_KARATSUBA_MUL_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_MUL_DIGS_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_SQR_C -| | +--->BN_MP_TOOM_SQR_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_KARATSUBA_SQR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_MP_CMP_MAG_C -| | +--->BN_FAST_S_MP_SQR_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SQR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -+--->BN_MP_MUL_C -| +--->BN_MP_TOOM_MUL_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_KARATSUBA_MUL_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_SUB_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_MUL_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_DIV_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_ABS_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_CMP_C -| +--->BN_MP_CMP_MAG_C -+--->BN_MP_SUB_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_ADD_D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_C - - -BN_MP_OR_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_CLAMP_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_C - - -BN_MP_PRIME_FERMAT_C -+--->BN_MP_CMP_D_C -+--->BN_MP_INIT_C -+--->BN_MP_EXPTMOD_C -| +--->BN_MP_INVMOD_C -| | +--->BN_FAST_MP_INVMOD_C -| | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_SET_C -| | | | | +--->BN_MP_COUNT_BITS_C -| | | | | +--->BN_MP_ABS_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2D_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_INIT_COPY_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SET_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INVMOD_SLOW_C -| | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_SET_C -| | | | | +--->BN_MP_COUNT_BITS_C -| | | | | +--->BN_MP_ABS_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2D_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_INIT_COPY_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_SET_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_ABS_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_REDUCE_IS_2K_L_C -| +--->BN_S_MP_EXPTMOD_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_REDUCE_SETUP_C -| | | +--->BN_MP_2EXPT_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_SET_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2D_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_COPY_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_REDUCE_C -| | | +--->BN_MP_INIT_COPY_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_S_MP_MUL_HIGH_DIGS_C -| | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SET_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_REDUCE_2K_SETUP_L_C -| | | +--->BN_MP_2EXPT_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_REDUCE_2K_L_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MOD_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_SET_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2D_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_INIT_COPY_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_SQR_C -| | | +--->BN_MP_TOOM_SQR_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_FAST_S_MP_SQR_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_MUL_C -| | | +--->BN_MP_TOOM_MUL_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_MUL_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_SET_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_DR_IS_MODULUS_C -| +--->BN_MP_REDUCE_IS_2K_C -| | +--->BN_MP_REDUCE_2K_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_EXPTMOD_FAST_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_MONTGOMERY_SETUP_C -| | +--->BN_FAST_MP_MONTGOMERY_REDUCE_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | +--->BN_MP_MONTGOMERY_REDUCE_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | +--->BN_MP_DR_SETUP_C -| | +--->BN_MP_DR_REDUCE_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | +--->BN_MP_REDUCE_2K_SETUP_C -| | | +--->BN_MP_2EXPT_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_REDUCE_2K_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -| | | +--->BN_MP_2EXPT_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_SET_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MULMOD_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_SET_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2D_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_INIT_COPY_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SET_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2D_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_INIT_COPY_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_SQR_C -| | | +--->BN_MP_TOOM_SQR_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_SQR_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_FAST_S_MP_SQR_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SQR_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_MUL_C -| | | +--->BN_MP_TOOM_MUL_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_MUL_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_EXCH_C -+--->BN_MP_CMP_C -| +--->BN_MP_CMP_MAG_C -+--->BN_MP_CLEAR_C - - -BN_MP_PRIME_IS_DIVISIBLE_C -+--->BN_MP_MOD_D_C -| +--->BN_MP_DIV_D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C - - -BN_MP_PRIME_IS_PRIME_C -+--->BN_MP_CMP_D_C -+--->BN_MP_PRIME_IS_DIVISIBLE_C -| +--->BN_MP_MOD_D_C -| | +--->BN_MP_DIV_D_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_INIT_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -+--->BN_MP_INIT_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C -+--->BN_MP_PRIME_MILLER_RABIN_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_SUB_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CNT_LSB_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXPTMOD_C -| | +--->BN_MP_INVMOD_C -| | | +--->BN_FAST_MP_INVMOD_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_MOD_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_DIV_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COUNT_BITS_C -| | | | | | +--->BN_MP_ABS_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | | +--->BN_MP_CLEAR_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_INVMOD_SLOW_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_MOD_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_DIV_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COUNT_BITS_C -| | | | | | +--->BN_MP_ABS_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | | +--->BN_MP_CLEAR_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_ABS_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_REDUCE_IS_2K_L_C -| | +--->BN_S_MP_EXPTMOD_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_REDUCE_SETUP_C -| | | | +--->BN_MP_2EXPT_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_REDUCE_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_C -| | | | | +--->BN_MP_TOOM_MUL_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_COPY_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_MUL_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_3_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_S_MP_MUL_HIGH_DIGS_C -| | | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_REDUCE_2K_SETUP_L_C -| | | | +--->BN_MP_2EXPT_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_REDUCE_2K_L_C -| | | | +--->BN_MP_MUL_C -| | | | | +--->BN_MP_TOOM_MUL_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_COPY_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_MUL_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_3_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_SQR_C -| | | | +--->BN_MP_TOOM_SQR_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_SQR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_FAST_S_MP_SQR_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SQR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_DR_IS_MODULUS_C -| | +--->BN_MP_REDUCE_IS_2K_C -| | | +--->BN_MP_REDUCE_2K_C -| | | | +--->BN_MP_COUNT_BITS_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_EXPTMOD_FAST_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_MONTGOMERY_SETUP_C -| | | +--->BN_FAST_MP_MONTGOMERY_REDUCE_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_MONTGOMERY_REDUCE_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_DR_SETUP_C -| | | +--->BN_MP_DR_REDUCE_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_REDUCE_2K_SETUP_C -| | | | +--->BN_MP_2EXPT_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_REDUCE_2K_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -| | | | +--->BN_MP_2EXPT_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MULMOD_C -| | | | +--->BN_MP_MUL_C -| | | | | +--->BN_MP_TOOM_MUL_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_COPY_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_MUL_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_3_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_MOD_C -| | | | | +--->BN_MP_DIV_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_SQR_C -| | | | +--->BN_MP_TOOM_SQR_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_SQR_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_FAST_S_MP_SQR_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SQR_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_EXCH_C -| +--->BN_MP_CMP_C -| | +--->BN_MP_CMP_MAG_C -| +--->BN_MP_SQRMOD_C -| | +--->BN_MP_SQR_C -| | | +--->BN_MP_TOOM_SQR_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_KARATSUBA_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_FAST_S_MP_SQR_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_COUNT_BITS_C -| | | | +--->BN_MP_ABS_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_CLEAR_C - - -BN_MP_PRIME_MILLER_RABIN_C -+--->BN_MP_CMP_D_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_SUB_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_ADD_D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CNT_LSB_C -+--->BN_MP_DIV_2D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_MOD_2D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_EXPTMOD_C -| +--->BN_MP_INVMOD_C -| | +--->BN_FAST_MP_INVMOD_C -| | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_SET_C -| | | | | +--->BN_MP_COUNT_BITS_C -| | | | | +--->BN_MP_ABS_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SET_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INVMOD_SLOW_C -| | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_SET_C -| | | | | +--->BN_MP_COUNT_BITS_C -| | | | | +--->BN_MP_ABS_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_SET_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_ABS_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_REDUCE_IS_2K_L_C -| +--->BN_S_MP_EXPTMOD_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_REDUCE_SETUP_C -| | | +--->BN_MP_2EXPT_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_SET_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_REDUCE_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_S_MP_MUL_HIGH_DIGS_C -| | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SET_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_REDUCE_2K_SETUP_L_C -| | | +--->BN_MP_2EXPT_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_REDUCE_2K_L_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MOD_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_SET_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_SQR_C -| | | +--->BN_MP_TOOM_SQR_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_FAST_S_MP_SQR_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_MUL_C -| | | +--->BN_MP_TOOM_MUL_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_MUL_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_SET_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_DR_IS_MODULUS_C -| +--->BN_MP_REDUCE_IS_2K_C -| | +--->BN_MP_REDUCE_2K_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_EXPTMOD_FAST_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_MONTGOMERY_SETUP_C -| | +--->BN_FAST_MP_MONTGOMERY_REDUCE_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | +--->BN_MP_MONTGOMERY_REDUCE_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | +--->BN_MP_DR_SETUP_C -| | +--->BN_MP_DR_REDUCE_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | +--->BN_MP_REDUCE_2K_SETUP_C -| | | +--->BN_MP_2EXPT_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_REDUCE_2K_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -| | | +--->BN_MP_2EXPT_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_SET_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MULMOD_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_SET_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SET_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_SQR_C -| | | +--->BN_MP_TOOM_SQR_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_SQR_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_FAST_S_MP_SQR_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SQR_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_MUL_C -| | | +--->BN_MP_TOOM_MUL_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_MUL_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_EXCH_C -+--->BN_MP_CMP_C -| +--->BN_MP_CMP_MAG_C -+--->BN_MP_SQRMOD_C -| +--->BN_MP_SQR_C -| | +--->BN_MP_TOOM_SQR_C -| | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_KARATSUBA_SQR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_FAST_S_MP_SQR_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SQR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_MOD_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_DIV_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_SET_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_ABS_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -+--->BN_MP_CLEAR_C - - -BN_MP_PRIME_NEXT_PRIME_C -+--->BN_MP_CMP_D_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C -+--->BN_MP_SUB_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_ADD_D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_MOD_D_C -| +--->BN_MP_DIV_D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_INIT_C -+--->BN_MP_ADD_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_PRIME_MILLER_RABIN_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_CNT_LSB_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXPTMOD_C -| | +--->BN_MP_INVMOD_C -| | | +--->BN_FAST_MP_INVMOD_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_MOD_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_DIV_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COUNT_BITS_C -| | | | | | +--->BN_MP_ABS_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | | +--->BN_MP_CLEAR_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_INVMOD_SLOW_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_MOD_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_DIV_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COUNT_BITS_C -| | | | | | +--->BN_MP_ABS_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | | +--->BN_MP_CLEAR_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_ABS_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_REDUCE_IS_2K_L_C -| | +--->BN_S_MP_EXPTMOD_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_REDUCE_SETUP_C -| | | | +--->BN_MP_2EXPT_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_REDUCE_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_C -| | | | | +--->BN_MP_TOOM_MUL_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_COPY_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_MUL_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_3_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_S_MP_MUL_HIGH_DIGS_C -| | | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_REDUCE_2K_SETUP_L_C -| | | | +--->BN_MP_2EXPT_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_REDUCE_2K_L_C -| | | | +--->BN_MP_MUL_C -| | | | | +--->BN_MP_TOOM_MUL_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_COPY_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_MUL_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_3_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_SQR_C -| | | | +--->BN_MP_TOOM_SQR_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_SQR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_FAST_S_MP_SQR_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SQR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_DR_IS_MODULUS_C -| | +--->BN_MP_REDUCE_IS_2K_C -| | | +--->BN_MP_REDUCE_2K_C -| | | | +--->BN_MP_COUNT_BITS_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_EXPTMOD_FAST_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_MONTGOMERY_SETUP_C -| | | +--->BN_FAST_MP_MONTGOMERY_REDUCE_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_MONTGOMERY_REDUCE_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_DR_SETUP_C -| | | +--->BN_MP_DR_REDUCE_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_REDUCE_2K_SETUP_C -| | | | +--->BN_MP_2EXPT_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_REDUCE_2K_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -| | | | +--->BN_MP_2EXPT_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MULMOD_C -| | | | +--->BN_MP_MUL_C -| | | | | +--->BN_MP_TOOM_MUL_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_COPY_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_MUL_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_3_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_MOD_C -| | | | | +--->BN_MP_DIV_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_SQR_C -| | | | +--->BN_MP_TOOM_SQR_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_SQR_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_FAST_S_MP_SQR_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SQR_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_EXCH_C -| +--->BN_MP_CMP_C -| | +--->BN_MP_CMP_MAG_C -| +--->BN_MP_SQRMOD_C -| | +--->BN_MP_SQR_C -| | | +--->BN_MP_TOOM_SQR_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_KARATSUBA_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_FAST_S_MP_SQR_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_COUNT_BITS_C -| | | | +--->BN_MP_ABS_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_CLEAR_C - - -BN_MP_PRIME_RABIN_MILLER_TRIALS_C - - -BN_MP_PRIME_RANDOM_EX_C -+--->BN_MP_READ_UNSIGNED_BIN_C -| +--->BN_MP_GROW_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_COPY_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_PRIME_IS_PRIME_C -| +--->BN_MP_CMP_D_C -| +--->BN_MP_PRIME_IS_DIVISIBLE_C -| | +--->BN_MP_MOD_D_C -| | | +--->BN_MP_DIV_D_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_DIV_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_INIT_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_INIT_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_C -| +--->BN_MP_INIT_C -| +--->BN_MP_SET_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_PRIME_MILLER_RABIN_C -| | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_SUB_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CNT_LSB_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXPTMOD_C -| | | +--->BN_MP_INVMOD_C -| | | | +--->BN_FAST_MP_INVMOD_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_MOD_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_DIV_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_COUNT_BITS_C -| | | | | | | +--->BN_MP_ABS_C -| | | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_C -| | | | | | | +--->BN_MP_SUB_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_ADD_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | | | +--->BN_MP_CLEAR_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_MUL_D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CLEAR_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_INVMOD_SLOW_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_MOD_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_DIV_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_MP_COPY_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_COUNT_BITS_C -| | | | | | | +--->BN_MP_ABS_C -| | | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_C -| | | | | | | +--->BN_MP_SUB_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_ADD_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | | | +--->BN_MP_CLEAR_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_MUL_D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CLEAR_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_ABS_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_REDUCE_IS_2K_L_C -| | | +--->BN_S_MP_EXPTMOD_C -| | | | +--->BN_MP_COUNT_BITS_C -| | | | +--->BN_MP_REDUCE_SETUP_C -| | | | | +--->BN_MP_2EXPT_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_DIV_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_REDUCE_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_C -| | | | | | +--->BN_MP_TOOM_MUL_C -| | | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | | | | +--->BN_MP_COPY_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_COPY_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_MUL_2_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_ADD_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_SUB_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_DIV_2_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_MUL_D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_DIV_3_C -| | | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_MP_EXCH_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_ADD_C -| | | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_S_MP_MUL_HIGH_DIGS_C -| | | | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_REDUCE_2K_SETUP_L_C -| | | | | +--->BN_MP_2EXPT_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_REDUCE_2K_L_C -| | | | | +--->BN_MP_MUL_C -| | | | | | +--->BN_MP_TOOM_MUL_C -| | | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | | | | +--->BN_MP_COPY_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_COPY_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_MUL_2_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_ADD_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_SUB_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_DIV_2_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_MUL_D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_DIV_3_C -| | | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_MP_EXCH_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_ADD_C -| | | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MOD_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_DIV_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_SQR_C -| | | | | +--->BN_MP_TOOM_SQR_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_MUL_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_3_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_KARATSUBA_SQR_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_FAST_S_MP_SQR_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SQR_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_MUL_C -| | | | | +--->BN_MP_TOOM_MUL_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_MUL_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_3_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_DR_IS_MODULUS_C -| | | +--->BN_MP_REDUCE_IS_2K_C -| | | | +--->BN_MP_REDUCE_2K_C -| | | | | +--->BN_MP_COUNT_BITS_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_EXPTMOD_FAST_C -| | | | +--->BN_MP_COUNT_BITS_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_MONTGOMERY_SETUP_C -| | | | +--->BN_FAST_MP_MONTGOMERY_REDUCE_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_MONTGOMERY_REDUCE_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_DR_SETUP_C -| | | | +--->BN_MP_DR_REDUCE_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_REDUCE_2K_SETUP_C -| | | | | +--->BN_MP_2EXPT_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_REDUCE_2K_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -| | | | | +--->BN_MP_2EXPT_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MULMOD_C -| | | | | +--->BN_MP_MUL_C -| | | | | | +--->BN_MP_TOOM_MUL_C -| | | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | | | | +--->BN_MP_COPY_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_COPY_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_MUL_2_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_ADD_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_SUB_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_DIV_2_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_MUL_D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_DIV_3_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_MP_EXCH_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_ADD_C -| | | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_MOD_C -| | | | | | +--->BN_MP_DIV_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_MP_COPY_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_C -| | | | | | | +--->BN_MP_SUB_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_ADD_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_MUL_D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MOD_C -| | | | | +--->BN_MP_DIV_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_SQR_C -| | | | | +--->BN_MP_TOOM_SQR_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_MUL_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_3_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_KARATSUBA_SQR_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_FAST_S_MP_SQR_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SQR_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_MUL_C -| | | | | +--->BN_MP_TOOM_MUL_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_MUL_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_3_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_CMP_C -| | | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_SQRMOD_C -| | | +--->BN_MP_SQR_C -| | | | +--->BN_MP_TOOM_SQR_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_KARATSUBA_SQR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_FAST_S_MP_SQR_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SQR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_COUNT_BITS_C -| | | | | +--->BN_MP_ABS_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_SUB_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_ADD_D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_DIV_2_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_MUL_2_C -| +--->BN_MP_GROW_C -+--->BN_MP_ADD_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C - - -BN_MP_RADIX_SIZE_C -+--->BN_MP_COUNT_BITS_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_DIV_D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_3_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_CLEAR_C - - -BN_MP_RADIX_SMAP_C - - -BN_MP_RAND_C -+--->BN_MP_ZERO_C -+--->BN_MP_ADD_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_SUB_D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_LSHD_C -| +--->BN_MP_GROW_C -| +--->BN_MP_RSHD_C - - -BN_MP_READ_RADIX_C -+--->BN_MP_ZERO_C -+--->BN_MP_MUL_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_ADD_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_SUB_D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C - - -BN_MP_READ_SIGNED_BIN_C -+--->BN_MP_READ_UNSIGNED_BIN_C -| +--->BN_MP_GROW_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_COPY_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C - - -BN_MP_READ_UNSIGNED_BIN_C -+--->BN_MP_GROW_C -+--->BN_MP_ZERO_C -+--->BN_MP_MUL_2D_C -| +--->BN_MP_COPY_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLAMP_C - - -BN_MP_REDUCE_2K_C -+--->BN_MP_INIT_C -+--->BN_MP_COUNT_BITS_C -+--->BN_MP_DIV_2D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_MOD_2D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_MUL_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_S_MP_ADD_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CMP_MAG_C -+--->BN_S_MP_SUB_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLEAR_C - - -BN_MP_REDUCE_2K_L_C -+--->BN_MP_INIT_C -+--->BN_MP_COUNT_BITS_C -+--->BN_MP_DIV_2D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_MOD_2D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_MUL_C -| +--->BN_MP_TOOM_MUL_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_KARATSUBA_MUL_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_S_MP_ADD_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CMP_MAG_C -+--->BN_S_MP_SUB_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLEAR_C - - -BN_MP_REDUCE_2K_SETUP_C -+--->BN_MP_INIT_C -+--->BN_MP_COUNT_BITS_C -+--->BN_MP_2EXPT_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_GROW_C -+--->BN_MP_CLEAR_C -+--->BN_S_MP_SUB_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C - - -BN_MP_REDUCE_2K_SETUP_L_C -+--->BN_MP_INIT_C -+--->BN_MP_2EXPT_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_GROW_C -+--->BN_MP_COUNT_BITS_C -+--->BN_S_MP_SUB_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLEAR_C - - -BN_MP_REDUCE_C -+--->BN_MP_REDUCE_SETUP_C -| +--->BN_MP_2EXPT_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_RSHD_C -| +--->BN_MP_ZERO_C -+--->BN_MP_MUL_C -| +--->BN_MP_TOOM_MUL_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_KARATSUBA_MUL_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_S_MP_MUL_HIGH_DIGS_C -| +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C -+--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_MOD_2D_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_S_MP_MUL_DIGS_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_SUB_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_CMP_D_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C -+--->BN_MP_LSHD_C -| +--->BN_MP_GROW_C -+--->BN_MP_ADD_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_CMP_C -| +--->BN_MP_CMP_MAG_C -+--->BN_S_MP_SUB_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLEAR_C - - -BN_MP_REDUCE_IS_2K_C -+--->BN_MP_REDUCE_2K_C -| +--->BN_MP_INIT_C -| +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_MUL_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_COUNT_BITS_C - - -BN_MP_REDUCE_IS_2K_L_C - - -BN_MP_REDUCE_SETUP_C -+--->BN_MP_2EXPT_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_GROW_C -+--->BN_MP_DIV_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_SET_C -| +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_ABS_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_INIT_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_MUL_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C - - -BN_MP_RSHD_C -+--->BN_MP_ZERO_C - - -BN_MP_SET_C -+--->BN_MP_ZERO_C - - -BN_MP_SET_INT_C -+--->BN_MP_ZERO_C -+--->BN_MP_MUL_2D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_GROW_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLAMP_C - - -BN_MP_SET_LONG_C - - -BN_MP_SET_LONG_LONG_C - - -BN_MP_SHRINK_C - - -BN_MP_SIGNED_BIN_SIZE_C -+--->BN_MP_UNSIGNED_BIN_SIZE_C -| +--->BN_MP_COUNT_BITS_C - - -BN_MP_SQRMOD_C -+--->BN_MP_INIT_C -+--->BN_MP_SQR_C -| +--->BN_MP_TOOM_SQR_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_KARATSUBA_SQR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | +--->BN_MP_ADD_C -| | | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_SQR_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_SQR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_CLEAR_C -+--->BN_MP_MOD_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C - - -BN_MP_SQRTMOD_PRIME_C -+--->BN_MP_CMP_D_C -+--->BN_MP_ZERO_C -+--->BN_MP_JACOBI_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_CNT_LSB_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_MOD_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_DIV_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_SET_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_ABS_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_INIT_MULTI_C -| +--->BN_MP_INIT_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_MOD_D_C -| +--->BN_MP_DIV_D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_ADD_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_SUB_D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_DIV_2_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_EXPTMOD_C -| +--->BN_MP_INIT_C -| +--->BN_MP_INVMOD_C -| | +--->BN_FAST_MP_INVMOD_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_SET_C -| | | | | +--->BN_MP_COUNT_BITS_C -| | | | | +--->BN_MP_ABS_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2D_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_INIT_COPY_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SET_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INVMOD_SLOW_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_SET_C -| | | | | +--->BN_MP_COUNT_BITS_C -| | | | | +--->BN_MP_ABS_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2D_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_INIT_COPY_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_SET_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_ABS_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_REDUCE_IS_2K_L_C -| +--->BN_S_MP_EXPTMOD_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_REDUCE_SETUP_C -| | | +--->BN_MP_2EXPT_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_SET_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2D_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_COPY_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_REDUCE_C -| | | +--->BN_MP_INIT_COPY_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_S_MP_MUL_HIGH_DIGS_C -| | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SET_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_REDUCE_2K_SETUP_L_C -| | | +--->BN_MP_2EXPT_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_REDUCE_2K_L_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MOD_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_SET_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2D_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_INIT_COPY_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_SQR_C -| | | +--->BN_MP_TOOM_SQR_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_FAST_S_MP_SQR_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_MUL_C -| | | +--->BN_MP_TOOM_MUL_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_MUL_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_DR_IS_MODULUS_C -| +--->BN_MP_REDUCE_IS_2K_C -| | +--->BN_MP_REDUCE_2K_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_EXPTMOD_FAST_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_MONTGOMERY_SETUP_C -| | +--->BN_FAST_MP_MONTGOMERY_REDUCE_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | +--->BN_MP_MONTGOMERY_REDUCE_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | +--->BN_MP_DR_SETUP_C -| | +--->BN_MP_DR_REDUCE_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | +--->BN_MP_REDUCE_2K_SETUP_C -| | | +--->BN_MP_2EXPT_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_REDUCE_2K_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -| | | +--->BN_MP_2EXPT_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_SET_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MULMOD_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_SET_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2D_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_INIT_COPY_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_MOD_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2D_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_INIT_COPY_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_SQR_C -| | | +--->BN_MP_TOOM_SQR_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_SQR_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_FAST_S_MP_SQR_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SQR_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_MUL_C -| | | +--->BN_MP_TOOM_MUL_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_MUL_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_EXCH_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_SUB_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_SET_INT_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_SQRMOD_C -| +--->BN_MP_INIT_C -| +--->BN_MP_SQR_C -| | +--->BN_MP_TOOM_SQR_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_KARATSUBA_SQR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_FAST_S_MP_SQR_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SQR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_MOD_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_DIV_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_SET_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_ABS_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -+--->BN_MP_MULMOD_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_MUL_C -| | +--->BN_MP_TOOM_MUL_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_KARATSUBA_MUL_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_MUL_DIGS_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_MOD_C -| | +--->BN_MP_DIV_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_SET_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_ABS_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_INIT_C -| | | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -+--->BN_MP_SET_C -+--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_CLEAR_C - - -BN_MP_SQRT_C -+--->BN_MP_N_ROOT_C -| +--->BN_MP_N_ROOT_EX_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_SET_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_EXPT_D_EX_C -| | | +--->BN_MP_INIT_COPY_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_SQR_C -| | | | +--->BN_MP_TOOM_SQR_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_KARATSUBA_SQR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_FAST_S_MP_SQR_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SQR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_MUL_C -| | | +--->BN_MP_TOOM_MUL_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_KARATSUBA_MUL_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_ABS_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_COPY_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_CMP_C -| | | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_SUB_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_ZERO_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_RSHD_C -+--->BN_MP_DIV_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_SET_C -| +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_ABS_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_MUL_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_ADD_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_DIV_2_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CMP_MAG_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_C - - -BN_MP_SQR_C -+--->BN_MP_TOOM_SQR_C -| +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_MOD_2D_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_RSHD_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_MUL_2_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_2_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_MUL_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_3_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_KARATSUBA_SQR_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_CLAMP_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| +--->BN_MP_ADD_C -| | +--->BN_MP_CMP_MAG_C -| +--->BN_MP_CLEAR_C -+--->BN_FAST_S_MP_SQR_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_S_MP_SQR_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C - - -BN_MP_SUBMOD_C -+--->BN_MP_INIT_C -+--->BN_MP_SUB_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_CLEAR_C -+--->BN_MP_MOD_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C - - -BN_MP_SUB_C -+--->BN_S_MP_ADD_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CMP_MAG_C -+--->BN_S_MP_SUB_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C - - -BN_MP_SUB_D_C -+--->BN_MP_GROW_C -+--->BN_MP_ADD_D_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLAMP_C - - -BN_MP_TOOM_MUL_C -+--->BN_MP_INIT_MULTI_C -| +--->BN_MP_INIT_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_MOD_2D_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_RSHD_C -| +--->BN_MP_ZERO_C -+--->BN_MP_MUL_C -| +--->BN_MP_KARATSUBA_MUL_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_MUL_2_C -| +--->BN_MP_GROW_C -+--->BN_MP_ADD_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_SUB_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_DIV_2_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_MUL_2D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_LSHD_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_MUL_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_DIV_3_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_LSHD_C -| +--->BN_MP_GROW_C -+--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_CLEAR_C - - -BN_MP_TOOM_SQR_C -+--->BN_MP_INIT_MULTI_C -| +--->BN_MP_INIT_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_MOD_2D_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_RSHD_C -| +--->BN_MP_ZERO_C -+--->BN_MP_SQR_C -| +--->BN_MP_KARATSUBA_SQR_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_SQR_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_SQR_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_MUL_2_C -| +--->BN_MP_GROW_C -+--->BN_MP_ADD_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_SUB_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_DIV_2_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_MUL_2D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_LSHD_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_MUL_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_DIV_3_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_LSHD_C -| +--->BN_MP_GROW_C -+--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_CLEAR_C - - -BN_MP_TORADIX_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_DIV_D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_3_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_CLEAR_C - - -BN_MP_TORADIX_N_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_DIV_D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_3_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_CLEAR_C - - -BN_MP_TO_SIGNED_BIN_C -+--->BN_MP_TO_UNSIGNED_BIN_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C - - -BN_MP_TO_SIGNED_BIN_N_C -+--->BN_MP_SIGNED_BIN_SIZE_C -| +--->BN_MP_UNSIGNED_BIN_SIZE_C -| | +--->BN_MP_COUNT_BITS_C -+--->BN_MP_TO_SIGNED_BIN_C -| +--->BN_MP_TO_UNSIGNED_BIN_C -| | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C - - -BN_MP_TO_UNSIGNED_BIN_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_DIV_2D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_MOD_2D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLEAR_C - - -BN_MP_TO_UNSIGNED_BIN_N_C -+--->BN_MP_UNSIGNED_BIN_SIZE_C -| +--->BN_MP_COUNT_BITS_C -+--->BN_MP_TO_UNSIGNED_BIN_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C - - -BN_MP_UNSIGNED_BIN_SIZE_C -+--->BN_MP_COUNT_BITS_C - - -BN_MP_XOR_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_CLAMP_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_C - - -BN_MP_ZERO_C - - -BN_PRIME_TAB_C - - -BN_REVERSE_C - - -BN_S_MP_ADD_C -+--->BN_MP_GROW_C -+--->BN_MP_CLAMP_C - - -BN_S_MP_EXPTMOD_C -+--->BN_MP_COUNT_BITS_C -+--->BN_MP_INIT_C -+--->BN_MP_CLEAR_C -+--->BN_MP_REDUCE_SETUP_C -| +--->BN_MP_2EXPT_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_REDUCE_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| +--->BN_MP_RSHD_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_MUL_C -| | +--->BN_MP_TOOM_MUL_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_KARATSUBA_MUL_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_MUL_DIGS_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| +--->BN_S_MP_MUL_HIGH_DIGS_C -| | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_MOD_2D_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_D_C -| +--->BN_MP_SET_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_C -| | +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_REDUCE_2K_SETUP_L_C -| +--->BN_MP_2EXPT_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_GROW_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_REDUCE_2K_L_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_MUL_C -| | +--->BN_MP_TOOM_MUL_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_KARATSUBA_MUL_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_MUL_DIGS_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_MOD_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_SQR_C -| +--->BN_MP_TOOM_SQR_C -| | +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_KARATSUBA_SQR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | +--->BN_MP_ADD_C -| | | +--->BN_MP_CMP_MAG_C -| +--->BN_FAST_S_MP_SQR_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_SQR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -+--->BN_MP_MUL_C -| +--->BN_MP_TOOM_MUL_C -| | +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_KARATSUBA_MUL_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C -+--->BN_MP_EXCH_C - - -BN_S_MP_MUL_DIGS_C -+--->BN_FAST_S_MP_MUL_DIGS_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_INIT_SIZE_C -| +--->BN_MP_INIT_C -+--->BN_MP_CLAMP_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_C - - -BN_S_MP_MUL_HIGH_DIGS_C -+--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_INIT_SIZE_C -| +--->BN_MP_INIT_C -+--->BN_MP_CLAMP_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_C - - -BN_S_MP_SQR_C -+--->BN_MP_INIT_SIZE_C -| +--->BN_MP_INIT_C -+--->BN_MP_CLAMP_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_C - - -BN_S_MP_SUB_C -+--->BN_MP_GROW_C -+--->BN_MP_CLAMP_C - - diff --git a/libtommath/changes.txt b/libtommath/changes.txt index 3379f71..ebf7382 100644 --- a/libtommath/changes.txt +++ b/libtommath/changes.txt @@ -1,4 +1,63 @@ -XXX, 2017 +XXX XXth, 2019 +v1.2.0 + -- A huge refactoring of the library happened - renaming, + deprecating and replacing existing functions by improved API's. + + All deprecated functions, macros and symbols are only marked as such + so this version is still API and ABI compatible to v1.x. + + -- Daniel Mendler was pushing for those changes and contributing a load of patches, + refactorings, code reviews and whatnotelse. + -- Christoph Zurnieden re-worked internals of the library, improved the performance, + did code reviews and wrote documentation. + -- Francois Perrad did some refactoring and took again care of linting the sources and + provided all fixes. + -- Jan Nijtmans, Karel Miko and Joachim Breitner contributed various patches. + + -- Private symbols can now be hidden for the shared library builds, disabled by default. + -- All API's follow a single code style, are prefixed the same etc. + -- Unified, safer and improved API's + -- Less magic numbers - return values (where appropriate) and most flags are now enums, + this was implemented in a backwards compatible way where return values were int. + -- API's with return values are now by default marked as "warn on unsused result", this + can be disabled if required (which will most likely hide bugs), c.f. MP_WUR in tommath.h + -- Provide a whole set of setters&getters for different primitive types (long, uint32_t, etc.) + -- All those primitive setters are now optimized. + -- It's possible to automatically tune the cutoff values for Karatsuba&Toom-Cook + -- The custom allocators which were formerly known as XMALLOC(), XFREE() etc. are now available + as MP_MALLOC(), MP_REALLOC(), MP_CALLOC() and MP_FREE(). MP_REALLOC() and MP_FREE() now also + provide the allocated size to ease the usage of simple allocators without tracking. + -- Building is now also possible with MSVC 2015, 2017 and 2019 (use makefile.msvc) + -- Added mp_decr() and mp_incr() + -- Added mp_log_u32() + -- Improved prime-checking + -- Improved Toom-Cook multiplication + -- Removed the LTM book (`make docs` now builds the user manual) + + +Jan 28th, 2019 +v1.1.0 + -- Christoph Zurnieden contributed FIPS 186.4 compliant + prime-checking (PR #113), several other fixes and a load of documentation + -- Daniel Mendler provided two's-complement functions (PR #124) + and mp_{set,get}_double() (PR #123) + -- Francois Perrad took care of linting the sources, provided all fixes and + a astylerc to auto-format the sources. + -- A bunch of patches by Kevin B Kenny have been back-ported from TCL + -- Jan Nijtmans provided the patches to `const`ify all API + function arguments (also from TCL) + -- mp_rand() has now several native random provider implementations + and doesn't rely on `rand()` anymore + -- Karel Miko provided fixes when building for MS Windows + and re-worked the makefile generating process + -- The entire environment and build logic has been extended and improved + regarding auto-detection of platforms, libtool and a lot more + -- Prevent some potential BOF cases + -- Improved/fixed mp_lshd() and mp_invmod() + -- A load more bugs were fixed by various contributors + + +Aug 29th, 2017 v1.0.1 -- Dmitry Kovalenko provided fixes to mp_add_d() and mp_init_copy() -- Matt Johnston contributed some improvements to mp_div_2d(), diff --git a/libtommath/demo/demo.c b/libtommath/demo/demo.c deleted file mode 100644 index 7136a4c..0000000 --- a/libtommath/demo/demo.c +++ /dev/null @@ -1,1012 +0,0 @@ -#include <string.h> -#include <time.h> - -#ifdef IOWNANATHLON -#include <unistd.h> -#define SLEEP sleep(4) -#else -#define SLEEP -#endif - -/* - * Configuration - */ -#ifndef LTM_DEMO_TEST_VS_MTEST -#define LTM_DEMO_TEST_VS_MTEST 1 -#endif - -#ifndef LTM_DEMO_TEST_REDUCE_2K_L -/* This test takes a moment so we disable it by default, but it can be: - * 0 to disable testing - * 1 to make the test with P = 2^1024 - 0x2A434 B9FDEC95 D8F9D550 FFFFFFFF FFFFFFFF - * 2 to make the test with P = 2^2048 - 0x1 00000000 00000000 00000000 00000000 4945DDBF 8EA2A91D 5776399B B83E188F - */ -#define LTM_DEMO_TEST_REDUCE_2K_L 0 -#endif - -#ifdef LTM_DEMO_REAL_RAND -#define LTM_DEMO_RAND_SEED time(NULL) -#else -#define LTM_DEMO_RAND_SEED 23 -#endif - -#include "tommath.h" - -void ndraw(mp_int * a, char *name) -{ - char buf[16000]; - - printf("%s: ", name); - mp_toradix(a, buf, 10); - printf("%s\n", buf); - mp_toradix(a, buf, 16); - printf("0x%s\n", buf); -} - -#if LTM_DEMO_TEST_VS_MTEST -static void draw(mp_int * a) -{ - ndraw(a, ""); -} -#endif - - -unsigned long lfsr = 0xAAAAAAAAUL; - -int lbit(void) -{ - if (lfsr & 0x80000000UL) { - lfsr = ((lfsr << 1) ^ 0x8000001BUL) & 0xFFFFFFFFUL; - return 1; - } else { - lfsr <<= 1; - return 0; - } -} - -#if defined(LTM_DEMO_REAL_RAND) && !defined(_WIN32) -static FILE* fd_urandom; -#endif -int myrng(unsigned char *dst, int len, void *dat) -{ - int x; - (void)dat; -#if defined(LTM_DEMO_REAL_RAND) - if (!fd_urandom) { -#if !defined(_WIN32) - fprintf(stderr, "\nno /dev/urandom\n"); -#endif - } - else { - return fread(dst, 1, len, fd_urandom); - } -#endif - for (x = 0; x < len; ) { - unsigned int r = (unsigned int)rand(); - do { - dst[x++] = r & 0xFF; - r >>= 8; - } while((r != 0) && (x < len)); - } - return len; -} - -#if LTM_DEMO_TEST_VS_MTEST != 0 -static void _panic(int l) -{ - fprintf(stderr, "\n%d: fgets failed\n", l); - exit(EXIT_FAILURE); -} -#endif - -mp_int a, b, c, d, e, f; - -static void _cleanup(void) -{ - mp_clear_multi(&a, &b, &c, &d, &e, &f, NULL); - printf("\n"); - -#ifdef LTM_DEMO_REAL_RAND - if(fd_urandom) - fclose(fd_urandom); -#endif -} -struct mp_sqrtmod_prime_st { - unsigned long p; - unsigned long n; - mp_digit r; -}; -struct mp_sqrtmod_prime_st sqrtmod_prime[] = { - { 5, 14, 3 }, - { 7, 9, 4 }, - { 113, 2, 62 } -}; -struct mp_jacobi_st { - unsigned long n; - int c[16]; -}; -struct mp_jacobi_st jacobi[] = { - { 3, { 1, -1, 0, 1, -1, 0, 1, -1, 0, 1, -1, 0, 1, -1, 0, 1 } }, - { 5, { 0, 1, -1, -1, 1, 0, 1, -1, -1, 1, 0, 1, -1, -1, 1, 0 } }, - { 7, { 1, -1, 1, -1, -1, 0, 1, 1, -1, 1, -1, -1, 0, 1, 1, -1 } }, - { 9, { -1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 } }, -}; - -char cmd[4096], buf[4096]; -int main(void) -{ - unsigned rr; - int cnt, ix; -#if LTM_DEMO_TEST_VS_MTEST - unsigned long expt_n, add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n, - gcd_n, lcm_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n; - char* ret; -#else - unsigned long s, t; - unsigned long long q, r; - mp_digit mp; - int i, n, err, should; -#endif - - if (mp_init_multi(&a, &b, &c, &d, &e, &f, NULL)!= MP_OKAY) - return EXIT_FAILURE; - - atexit(_cleanup); - -#if defined(LTM_DEMO_REAL_RAND) - if (!fd_urandom) { - fd_urandom = fopen("/dev/urandom", "r"); - if (!fd_urandom) { -#if !defined(_WIN32) - fprintf(stderr, "\ncould not open /dev/urandom\n"); -#endif - } - } -#endif - srand(LTM_DEMO_RAND_SEED); - -#ifdef MP_8BIT - printf("Digit size 8 Bit \n"); -#endif -#ifdef MP_16BIT - printf("Digit size 16 Bit \n"); -#endif -#ifdef MP_32BIT - printf("Digit size 32 Bit \n"); -#endif -#ifdef MP_64BIT - printf("Digit size 64 Bit \n"); -#endif - printf("Size of mp_digit: %u\n", (unsigned int)sizeof(mp_digit)); - printf("Size of mp_word: %u\n", (unsigned int)sizeof(mp_word)); - printf("DIGIT_BIT: %d\n", DIGIT_BIT); - printf("MP_PREC: %d\n", MP_PREC); - -#if LTM_DEMO_TEST_VS_MTEST == 0 - // trivial stuff - // a: 0->5 - mp_set_int(&a, 5); - // a: 5-> b: -5 - mp_neg(&a, &b); - if (mp_cmp(&a, &b) != MP_GT) { - return EXIT_FAILURE; - } - if (mp_cmp(&b, &a) != MP_LT) { - return EXIT_FAILURE; - } - // a: 5-> a: -5 - mp_neg(&a, &a); - if (mp_cmp(&b, &a) != MP_EQ) { - return EXIT_FAILURE; - } - // a: -5-> b: 5 - mp_abs(&a, &b); - if (mp_isneg(&b) != MP_NO) { - return EXIT_FAILURE; - } - // a: -5-> b: -4 - mp_add_d(&a, 1, &b); - if (mp_isneg(&b) != MP_YES) { - return EXIT_FAILURE; - } - if (mp_get_int(&b) != 4) { - return EXIT_FAILURE; - } - // a: -5-> b: 1 - mp_add_d(&a, 6, &b); - if (mp_get_int(&b) != 1) { - return EXIT_FAILURE; - } - // a: -5-> a: 1 - mp_add_d(&a, 6, &a); - if (mp_get_int(&a) != 1) { - return EXIT_FAILURE; - } - mp_zero(&a); - // a: 0-> a: 6 - mp_add_d(&a, 6, &a); - if (mp_get_int(&a) != 6) { - return EXIT_FAILURE; - } - - - mp_set_int(&a, 0); - mp_set_int(&b, 1); - if ((err = mp_jacobi(&a, &b, &i)) != MP_OKAY) { - printf("Failed executing mp_jacobi(0 | 1) %s.\n", mp_error_to_string(err)); - return EXIT_FAILURE; - } - if (i != 1) { - printf("Failed trivial mp_jacobi(0 | 1) %d != 1\n", i); - return EXIT_FAILURE; - } - for (cnt = 0; cnt < (int)(sizeof(jacobi)/sizeof(jacobi[0])); ++cnt) { - mp_set_int(&b, jacobi[cnt].n); - /* only test positive values of a */ - for (n = -5; n <= 10; ++n) { - mp_set_int(&a, abs(n)); - should = MP_OKAY; - if (n < 0) { - mp_neg(&a, &a); - /* Until #44 is fixed the negative a's must fail */ - should = MP_VAL; - } - if ((err = mp_jacobi(&a, &b, &i)) != should) { - printf("Failed executing mp_jacobi(%d | %lu) %s.\n", n, jacobi[cnt].n, mp_error_to_string(err)); - return EXIT_FAILURE; - } - if (err == MP_OKAY && i != jacobi[cnt].c[n + 5]) { - printf("Failed trivial mp_jacobi(%d | %lu) %d != %d\n", n, jacobi[cnt].n, i, jacobi[cnt].c[n + 5]); - return EXIT_FAILURE; - } - } - } - - // test mp_get_int - printf("\n\nTesting: mp_get_int"); - for (i = 0; i < 1000; ++i) { - t = ((unsigned long) rand () * rand () + 1) & 0xFFFFFFFF; - mp_set_int (&a, t); - if (t != mp_get_int (&a)) { - printf ("\nmp_get_int() bad result!"); - return EXIT_FAILURE; - } - } - mp_set_int(&a, 0); - if (mp_get_int(&a) != 0) { - printf("\nmp_get_int() bad result!"); - return EXIT_FAILURE; - } - mp_set_int(&a, 0xffffffff); - if (mp_get_int(&a) != 0xffffffff) { - printf("\nmp_get_int() bad result!"); - return EXIT_FAILURE; - } - - printf("\n\nTesting: mp_get_long\n"); - for (i = 0; i < (int)(sizeof(unsigned long)*CHAR_BIT) - 1; ++i) { - t = (1ULL << (i+1)) - 1; - if (!t) - t = -1; - printf(" t = 0x%lx i = %d\r", t, i); - do { - if (mp_set_long(&a, t) != MP_OKAY) { - printf("\nmp_set_long() error!"); - return EXIT_FAILURE; - } - s = mp_get_long(&a); - if (s != t) { - printf("\nmp_get_long() bad result! 0x%lx != 0x%lx", s, t); - return EXIT_FAILURE; - } - t <<= 1; - } while(t); - } - - printf("\n\nTesting: mp_get_long_long\n"); - for (i = 0; i < (int)(sizeof(unsigned long long)*CHAR_BIT) - 1; ++i) { - r = (1ULL << (i+1)) - 1; - if (!r) - r = -1; - printf(" r = 0x%llx i = %d\r", r, i); - do { - if (mp_set_long_long(&a, r) != MP_OKAY) { - printf("\nmp_set_long_long() error!"); - return EXIT_FAILURE; - } - q = mp_get_long_long(&a); - if (q != r) { - printf("\nmp_get_long_long() bad result! 0x%llx != 0x%llx", q, r); - return EXIT_FAILURE; - } - r <<= 1; - } while(r); - } - - // test mp_sqrt - printf("\n\nTesting: mp_sqrt\n"); - for (i = 0; i < 1000; ++i) { - printf ("%6d\r", i); - fflush (stdout); - n = (rand () & 15) + 1; - mp_rand (&a, n); - if (mp_sqrt (&a, &b) != MP_OKAY) { - printf ("\nmp_sqrt() error!"); - return EXIT_FAILURE; - } - mp_n_root_ex (&a, 2, &c, 0); - mp_n_root_ex (&a, 2, &d, 1); - if (mp_cmp_mag (&c, &d) != MP_EQ) { - printf ("\nmp_n_root_ex() bad result!"); - return EXIT_FAILURE; - } - if (mp_cmp_mag (&b, &c) != MP_EQ) { - printf ("mp_sqrt() bad result!\n"); - return EXIT_FAILURE; - } - } - - printf("\n\nTesting: mp_is_square\n"); - for (i = 0; i < 1000; ++i) { - printf ("%6d\r", i); - fflush (stdout); - - /* test mp_is_square false negatives */ - n = (rand () & 7) + 1; - mp_rand (&a, n); - mp_sqr (&a, &a); - if (mp_is_square (&a, &n) != MP_OKAY) { - printf ("\nfn:mp_is_square() error!"); - return EXIT_FAILURE; - } - if (n == 0) { - printf ("\nfn:mp_is_square() bad result!"); - return EXIT_FAILURE; - } - - /* test for false positives */ - mp_add_d (&a, 1, &a); - if (mp_is_square (&a, &n) != MP_OKAY) { - printf ("\nfp:mp_is_square() error!"); - return EXIT_FAILURE; - } - if (n == 1) { - printf ("\nfp:mp_is_square() bad result!"); - return EXIT_FAILURE; - } - - } - printf("\n\n"); - - // r^2 = n (mod p) - for (i = 0; i < (int)(sizeof(sqrtmod_prime)/sizeof(sqrtmod_prime[0])); ++i) { - mp_set_int(&a, sqrtmod_prime[i].p); - mp_set_int(&b, sqrtmod_prime[i].n); - if (mp_sqrtmod_prime(&b, &a, &c) != MP_OKAY) { - printf("Failed executing %d. mp_sqrtmod_prime\n", (i+1)); - return EXIT_FAILURE; - } - if (mp_cmp_d(&c, sqrtmod_prime[i].r) != MP_EQ) { - printf("Failed %d. trivial mp_sqrtmod_prime\n", (i+1)); - ndraw(&c, "r"); - return EXIT_FAILURE; - } - } - - /* test for size */ - for (ix = 10; ix < 128; ix++) { - printf ("Testing (not safe-prime): %9d bits \r", ix); - fflush (stdout); - err = mp_prime_random_ex (&a, 8, ix, - (rand () & 1) ? 0 : LTM_PRIME_2MSB_ON, myrng, - NULL); - if (err != MP_OKAY) { - printf ("failed with err code %d\n", err); - return EXIT_FAILURE; - } - if (mp_count_bits (&a) != ix) { - printf ("Prime is %d not %d bits!!!\n", mp_count_bits (&a), ix); - return EXIT_FAILURE; - } - } - printf("\n"); - - for (ix = 16; ix < 128; ix++) { - printf ("Testing ( safe-prime): %9d bits \r", ix); - fflush (stdout); - err = mp_prime_random_ex ( - &a, 8, ix, ((rand () & 1) ? 0 : LTM_PRIME_2MSB_ON) | LTM_PRIME_SAFE, - myrng, NULL); - if (err != MP_OKAY) { - printf ("failed with err code %d\n", err); - return EXIT_FAILURE; - } - if (mp_count_bits (&a) != ix) { - printf ("Prime is %d not %d bits!!!\n", mp_count_bits (&a), ix); - return EXIT_FAILURE; - } - /* let's see if it's really a safe prime */ - mp_sub_d (&a, 1, &a); - mp_div_2 (&a, &a); - mp_prime_is_prime (&a, 8, &cnt); - if (cnt != MP_YES) { - printf ("sub is not prime!\n"); - return EXIT_FAILURE; - } - } - - printf("\n\n"); - - // test montgomery - printf("Testing: montgomery...\n"); - for (i = 1; i <= 10; i++) { - if (i == 10) - i = 1000; - printf(" digit size: %2d\r", i); - fflush(stdout); - for (n = 0; n < 1000; n++) { - mp_rand(&a, i); - a.dp[0] |= 1; - - // let's see if R is right - mp_montgomery_calc_normalization(&b, &a); - mp_montgomery_setup(&a, &mp); - - // now test a random reduction - for (ix = 0; ix < 100; ix++) { - mp_rand(&c, 1 + abs(rand()) % (2*i)); - mp_copy(&c, &d); - mp_copy(&c, &e); - - mp_mod(&d, &a, &d); - mp_montgomery_reduce(&c, &a, mp); - mp_mulmod(&c, &b, &a, &c); - - if (mp_cmp(&c, &d) != MP_EQ) { -printf("d = e mod a, c = e MOD a\n"); -mp_todecimal(&a, buf); printf("a = %s\n", buf); -mp_todecimal(&e, buf); printf("e = %s\n", buf); -mp_todecimal(&d, buf); printf("d = %s\n", buf); -mp_todecimal(&c, buf); printf("c = %s\n", buf); -printf("compare no compare!\n"); return EXIT_FAILURE; } - /* only one big montgomery reduction */ - if (i > 10) - { - n = 1000; - ix = 100; - } - } - } - } - - printf("\n\n"); - - mp_read_radix(&a, "123456", 10); - mp_toradix_n(&a, buf, 10, 3); - printf("a == %s\n", buf); - mp_toradix_n(&a, buf, 10, 4); - printf("a == %s\n", buf); - mp_toradix_n(&a, buf, 10, 30); - printf("a == %s\n", buf); - - -#if 0 - for (;;) { - fgets(buf, sizeof(buf), stdin); - mp_read_radix(&a, buf, 10); - mp_prime_next_prime(&a, 5, 1); - mp_toradix(&a, buf, 10); - printf("%s, %lu\n", buf, a.dp[0] & 3); - } -#endif - - /* test mp_cnt_lsb */ - printf("\n\nTesting: mp_cnt_lsb"); - mp_set(&a, 1); - for (ix = 0; ix < 1024; ix++) { - if (mp_cnt_lsb (&a) != ix) { - printf ("Failed at %d, %d\n", ix, mp_cnt_lsb (&a)); - return EXIT_FAILURE; - } - mp_mul_2 (&a, &a); - } - -/* test mp_reduce_2k */ - printf("\n\nTesting: mp_reduce_2k\n"); - for (cnt = 3; cnt <= 128; ++cnt) { - mp_digit tmp; - - mp_2expt (&a, cnt); - mp_sub_d (&a, 2, &a); /* a = 2**cnt - 2 */ - - printf ("\r %4d bits", cnt); - printf ("(%d)", mp_reduce_is_2k (&a)); - mp_reduce_2k_setup (&a, &tmp); - printf ("(%lu)", (unsigned long) tmp); - for (ix = 0; ix < 1000; ix++) { - if (!(ix & 127)) { - printf ("."); - fflush (stdout); - } - mp_rand (&b, (cnt / DIGIT_BIT + 1) * 2); - mp_copy (&c, &b); - mp_mod (&c, &a, &c); - mp_reduce_2k (&b, &a, 2); - if (mp_cmp (&c, &b)) { - printf ("FAILED\n"); - return EXIT_FAILURE; - } - } - } - -/* test mp_div_3 */ - printf("\n\nTesting: mp_div_3...\n"); - mp_set(&d, 3); - for (cnt = 0; cnt < 10000;) { - mp_digit r2; - - if (!(++cnt & 127)) - { - printf("%9d\r", cnt); - fflush(stdout); - } - mp_rand(&a, abs(rand()) % 128 + 1); - mp_div(&a, &d, &b, &e); - mp_div_3(&a, &c, &r2); - - if (mp_cmp(&b, &c) || mp_cmp_d(&e, r2)) { - printf("\nmp_div_3 => Failure\n"); - } - } - printf("\nPassed div_3 testing"); - -/* test the DR reduction */ - printf("\n\nTesting: mp_dr_reduce...\n"); - for (cnt = 2; cnt < 32; cnt++) { - printf ("\r%d digit modulus", cnt); - mp_grow (&a, cnt); - mp_zero (&a); - for (ix = 1; ix < cnt; ix++) { - a.dp[ix] = MP_MASK; - } - a.used = cnt; - a.dp[0] = 3; - - mp_rand (&b, cnt - 1); - mp_copy (&b, &c); - - rr = 0; - do { - if (!(rr & 127)) { - printf ("."); - fflush (stdout); - } - mp_sqr (&b, &b); - mp_add_d (&b, 1, &b); - mp_copy (&b, &c); - - mp_mod (&b, &a, &b); - mp_dr_setup(&a, &mp), - mp_dr_reduce (&c, &a, mp); - - if (mp_cmp (&b, &c) != MP_EQ) { - printf ("Failed on trial %u\n", rr); - return EXIT_FAILURE; - } - } while (++rr < 500); - printf (" passed"); - fflush (stdout); - } - -#if LTM_DEMO_TEST_REDUCE_2K_L -/* test the mp_reduce_2k_l code */ -#if LTM_DEMO_TEST_REDUCE_2K_L == 1 -/* first load P with 2^1024 - 0x2A434 B9FDEC95 D8F9D550 FFFFFFFF FFFFFFFF */ - mp_2expt(&a, 1024); - mp_read_radix(&b, "2A434B9FDEC95D8F9D550FFFFFFFFFFFFFFFF", 16); - mp_sub(&a, &b, &a); -#elif LTM_DEMO_TEST_REDUCE_2K_L == 2 -/* p = 2^2048 - 0x1 00000000 00000000 00000000 00000000 4945DDBF 8EA2A91D 5776399B B83E188F */ - mp_2expt(&a, 2048); - mp_read_radix(&b, - "1000000000000000000000000000000004945DDBF8EA2A91D5776399BB83E188F", - 16); - mp_sub(&a, &b, &a); -#else -#error oops -#endif - - mp_todecimal(&a, buf); - printf("\n\np==%s\n", buf); -/* now mp_reduce_is_2k_l() should return */ - if (mp_reduce_is_2k_l(&a) != 1) { - printf("mp_reduce_is_2k_l() return 0, should be 1\n"); - return EXIT_FAILURE; - } - mp_reduce_2k_setup_l(&a, &d); - /* now do a million square+1 to see if it varies */ - mp_rand(&b, 64); - mp_mod(&b, &a, &b); - mp_copy(&b, &c); - printf("Testing: mp_reduce_2k_l..."); - fflush(stdout); - for (cnt = 0; cnt < (int)(1UL << 20); cnt++) { - mp_sqr(&b, &b); - mp_add_d(&b, 1, &b); - mp_reduce_2k_l(&b, &a, &d); - mp_sqr(&c, &c); - mp_add_d(&c, 1, &c); - mp_mod(&c, &a, &c); - if (mp_cmp(&b, &c) != MP_EQ) { - printf("mp_reduce_2k_l() failed at step %d\n", cnt); - mp_tohex(&b, buf); - printf("b == %s\n", buf); - mp_tohex(&c, buf); - printf("c == %s\n", buf); - return EXIT_FAILURE; - } - } - printf("...Passed\n"); -#endif /* LTM_DEMO_TEST_REDUCE_2K_L */ - -#else - - div2_n = mul2_n = inv_n = expt_n = lcm_n = gcd_n = add_n = - sub_n = mul_n = div_n = sqr_n = mul2d_n = div2d_n = cnt = add_d_n = - sub_d_n = 0; - - /* force KARA and TOOM to enable despite cutoffs */ - KARATSUBA_SQR_CUTOFF = KARATSUBA_MUL_CUTOFF = 8; - TOOM_SQR_CUTOFF = TOOM_MUL_CUTOFF = 16; - - for (;;) { - /* randomly clear and re-init one variable, this has the affect of triming the alloc space */ - switch (abs(rand()) % 7) { - case 0: - mp_clear(&a); - mp_init(&a); - break; - case 1: - mp_clear(&b); - mp_init(&b); - break; - case 2: - mp_clear(&c); - mp_init(&c); - break; - case 3: - mp_clear(&d); - mp_init(&d); - break; - case 4: - mp_clear(&e); - mp_init(&e); - break; - case 5: - mp_clear(&f); - mp_init(&f); - break; - case 6: - break; /* don't clear any */ - } - - - printf - ("%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu ", - add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n, gcd_n, lcm_n, - expt_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n); - ret=fgets(cmd, 4095, stdin); if(!ret){_panic(__LINE__);} - cmd[strlen(cmd) - 1] = 0; - printf("%-6s ]\r", cmd); - fflush(stdout); - if (!strcmp(cmd, "mul2d")) { - ++mul2d_n; - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&a, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - sscanf(buf, "%d", &rr); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&b, buf, 64); - - mp_mul_2d(&a, rr, &a); - a.sign = b.sign; - if (mp_cmp(&a, &b) != MP_EQ) { - printf("mul2d failed, rr == %d\n", rr); - draw(&a); - draw(&b); - return EXIT_FAILURE; - } - } else if (!strcmp(cmd, "div2d")) { - ++div2d_n; - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&a, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - sscanf(buf, "%d", &rr); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&b, buf, 64); - - mp_div_2d(&a, rr, &a, &e); - a.sign = b.sign; - if (a.used == b.used && a.used == 0) { - a.sign = b.sign = MP_ZPOS; - } - if (mp_cmp(&a, &b) != MP_EQ) { - printf("div2d failed, rr == %d\n", rr); - draw(&a); - draw(&b); - return EXIT_FAILURE; - } - } else if (!strcmp(cmd, "add")) { - ++add_n; - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&a, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&b, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&c, buf, 64); - mp_copy(&a, &d); - mp_add(&d, &b, &d); - if (mp_cmp(&c, &d) != MP_EQ) { - printf("add %lu failure!\n", add_n); - draw(&a); - draw(&b); - draw(&c); - draw(&d); - return EXIT_FAILURE; - } - - /* test the sign/unsigned storage functions */ - - rr = mp_signed_bin_size(&c); - mp_to_signed_bin(&c, (unsigned char *) cmd); - memset(cmd + rr, rand() & 255, sizeof(cmd) - rr); - mp_read_signed_bin(&d, (unsigned char *) cmd, rr); - if (mp_cmp(&c, &d) != MP_EQ) { - printf("mp_signed_bin failure!\n"); - draw(&c); - draw(&d); - return EXIT_FAILURE; - } - - - rr = mp_unsigned_bin_size(&c); - mp_to_unsigned_bin(&c, (unsigned char *) cmd); - memset(cmd + rr, rand() & 255, sizeof(cmd) - rr); - mp_read_unsigned_bin(&d, (unsigned char *) cmd, rr); - if (mp_cmp_mag(&c, &d) != MP_EQ) { - printf("mp_unsigned_bin failure!\n"); - draw(&c); - draw(&d); - return EXIT_FAILURE; - } - - } else if (!strcmp(cmd, "sub")) { - ++sub_n; - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&a, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&b, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&c, buf, 64); - mp_copy(&a, &d); - mp_sub(&d, &b, &d); - if (mp_cmp(&c, &d) != MP_EQ) { - printf("sub %lu failure!\n", sub_n); - draw(&a); - draw(&b); - draw(&c); - draw(&d); - return EXIT_FAILURE; - } - } else if (!strcmp(cmd, "mul")) { - ++mul_n; - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&a, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&b, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&c, buf, 64); - mp_copy(&a, &d); - mp_mul(&d, &b, &d); - if (mp_cmp(&c, &d) != MP_EQ) { - printf("mul %lu failure!\n", mul_n); - draw(&a); - draw(&b); - draw(&c); - draw(&d); - return EXIT_FAILURE; - } - } else if (!strcmp(cmd, "div")) { - ++div_n; - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&a, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&b, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&c, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&d, buf, 64); - - mp_div(&a, &b, &e, &f); - if (mp_cmp(&c, &e) != MP_EQ || mp_cmp(&d, &f) != MP_EQ) { - printf("div %lu %d, %d, failure!\n", div_n, mp_cmp(&c, &e), - mp_cmp(&d, &f)); - draw(&a); - draw(&b); - draw(&c); - draw(&d); - draw(&e); - draw(&f); - return EXIT_FAILURE; - } - - } else if (!strcmp(cmd, "sqr")) { - ++sqr_n; - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&a, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&b, buf, 64); - mp_copy(&a, &c); - mp_sqr(&c, &c); - if (mp_cmp(&b, &c) != MP_EQ) { - printf("sqr %lu failure!\n", sqr_n); - draw(&a); - draw(&b); - draw(&c); - return EXIT_FAILURE; - } - } else if (!strcmp(cmd, "gcd")) { - ++gcd_n; - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&a, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&b, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&c, buf, 64); - mp_copy(&a, &d); - mp_gcd(&d, &b, &d); - d.sign = c.sign; - if (mp_cmp(&c, &d) != MP_EQ) { - printf("gcd %lu failure!\n", gcd_n); - draw(&a); - draw(&b); - draw(&c); - draw(&d); - return EXIT_FAILURE; - } - } else if (!strcmp(cmd, "lcm")) { - ++lcm_n; - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&a, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&b, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&c, buf, 64); - mp_copy(&a, &d); - mp_lcm(&d, &b, &d); - d.sign = c.sign; - if (mp_cmp(&c, &d) != MP_EQ) { - printf("lcm %lu failure!\n", lcm_n); - draw(&a); - draw(&b); - draw(&c); - draw(&d); - return EXIT_FAILURE; - } - } else if (!strcmp(cmd, "expt")) { - ++expt_n; - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&a, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&b, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&c, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&d, buf, 64); - mp_copy(&a, &e); - mp_exptmod(&e, &b, &c, &e); - if (mp_cmp(&d, &e) != MP_EQ) { - printf("expt %lu failure!\n", expt_n); - draw(&a); - draw(&b); - draw(&c); - draw(&d); - draw(&e); - return EXIT_FAILURE; - } - } else if (!strcmp(cmd, "invmod")) { - ++inv_n; - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&a, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&b, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&c, buf, 64); - mp_invmod(&a, &b, &d); - mp_mulmod(&d, &a, &b, &e); - if (mp_cmp_d(&e, 1) != MP_EQ) { - printf("inv [wrong value from MPI?!] failure\n"); - draw(&a); - draw(&b); - draw(&c); - draw(&d); - draw(&e); - mp_gcd(&a, &b, &e); - draw(&e); - return EXIT_FAILURE; - } - - } else if (!strcmp(cmd, "div2")) { - ++div2_n; - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&a, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&b, buf, 64); - mp_div_2(&a, &c); - if (mp_cmp(&c, &b) != MP_EQ) { - printf("div_2 %lu failure\n", div2_n); - draw(&a); - draw(&b); - draw(&c); - return EXIT_FAILURE; - } - } else if (!strcmp(cmd, "mul2")) { - ++mul2_n; - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&a, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&b, buf, 64); - mp_mul_2(&a, &c); - if (mp_cmp(&c, &b) != MP_EQ) { - printf("mul_2 %lu failure\n", mul2_n); - draw(&a); - draw(&b); - draw(&c); - return EXIT_FAILURE; - } - } else if (!strcmp(cmd, "add_d")) { - ++add_d_n; - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&a, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - sscanf(buf, "%d", &ix); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&b, buf, 64); - mp_add_d(&a, ix, &c); - if (mp_cmp(&b, &c) != MP_EQ) { - printf("add_d %lu failure\n", add_d_n); - draw(&a); - draw(&b); - draw(&c); - printf("d == %d\n", ix); - return EXIT_FAILURE; - } - } else if (!strcmp(cmd, "sub_d")) { - ++sub_d_n; - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&a, buf, 64); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - sscanf(buf, "%d", &ix); - ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);} - mp_read_radix(&b, buf, 64); - mp_sub_d(&a, ix, &c); - if (mp_cmp(&b, &c) != MP_EQ) { - printf("sub_d %lu failure\n", sub_d_n); - draw(&a); - draw(&b); - draw(&c); - printf("d == %d\n", ix); - return EXIT_FAILURE; - } - } else if (!strcmp(cmd, "exit")) { - printf("\nokay, exiting now\n"); - break; - } - } -#endif - return 0; -} - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/demo/timing.c b/libtommath/demo/timing.c deleted file mode 100644 index 2488eb4..0000000 --- a/libtommath/demo/timing.c +++ /dev/null @@ -1,340 +0,0 @@ -#include <tommath.h> -#include <time.h> -#include <unistd.h> -#include <stdint.h> - -uint64_t _tt; - -#ifdef IOWNANATHLON -#include <unistd.h> -#define SLEEP sleep(4) -#else -#define SLEEP -#endif - -#ifdef LTM_TIMING_REAL_RAND -#define LTM_TIMING_RAND_SEED time(NULL) -#else -#define LTM_TIMING_RAND_SEED 23 -#endif - - -void ndraw(mp_int * a, char *name) -{ - char buf[4096]; - - printf("%s: ", name); - mp_toradix(a, buf, 64); - printf("%s\n", buf); -} - -static void draw(mp_int * a) -{ - ndraw(a, ""); -} - - -unsigned long lfsr = 0xAAAAAAAAUL; - -int lbit(void) -{ - if (lfsr & 0x80000000UL) { - lfsr = ((lfsr << 1) ^ 0x8000001BUL) & 0xFFFFFFFFUL; - return 1; - } else { - lfsr <<= 1; - return 0; - } -} - -/* RDTSC from Scott Duplichan */ -static uint64_t TIMFUNC(void) -{ -#if defined __GNUC__ -#if defined(__i386__) || defined(__x86_64__) - /* version from http://www.mcs.anl.gov/~kazutomo/rdtsc.html - * the old code always got a warning issued by gcc, clang did not complain... - */ - unsigned hi, lo; - __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); - return ((uint64_t)lo)|( ((uint64_t)hi)<<32); -#else /* gcc-IA64 version */ - unsigned long result; - __asm__ __volatile__("mov %0=ar.itc":"=r"(result)::"memory"); - - while (__builtin_expect((int) result == -1, 0)) - __asm__ __volatile__("mov %0=ar.itc":"=r"(result)::"memory"); - - return result; -#endif - - // Microsoft and Intel Windows compilers -#elif defined _M_IX86 - __asm rdtsc -#elif defined _M_AMD64 - return __rdtsc(); -#elif defined _M_IA64 -#if defined __INTEL_COMPILER -#include <ia64intrin.h> -#endif - return __getReg(3116); -#else -#error need rdtsc function for this build -#endif -} - -#define DO(x) x; x; -//#define DO4(x) DO2(x); DO2(x); -//#define DO8(x) DO4(x); DO4(x); -//#define DO(x) DO8(x); DO8(x); - -#ifdef TIMING_NO_LOGS -#define FOPEN(a, b) NULL -#define FPRINTF(a,b,c,d) -#define FFLUSH(a) -#define FCLOSE(a) (void)(a) -#else -#define FOPEN(a,b) fopen(a,b) -#define FPRINTF(a,b,c,d) fprintf(a,b,c,d) -#define FFLUSH(a) fflush(a) -#define FCLOSE(a) fclose(a) -#endif - -int main(void) -{ - uint64_t tt, gg, CLK_PER_SEC; - FILE *log, *logb, *logc, *logd; - mp_int a, b, c, d, e, f; - int n, cnt, ix, old_kara_m, old_kara_s, old_toom_m, old_toom_s; - unsigned rr; - - mp_init(&a); - mp_init(&b); - mp_init(&c); - mp_init(&d); - mp_init(&e); - mp_init(&f); - - srand(LTM_TIMING_RAND_SEED); - - - CLK_PER_SEC = TIMFUNC(); - sleep(1); - CLK_PER_SEC = TIMFUNC() - CLK_PER_SEC; - - printf("CLK_PER_SEC == %llu\n", CLK_PER_SEC); - log = FOPEN("logs/add.log", "w"); - for (cnt = 8; cnt <= 128; cnt += 8) { - SLEEP; - mp_rand(&a, cnt); - mp_rand(&b, cnt); - rr = 0; - tt = -1; - do { - gg = TIMFUNC(); - DO(mp_add(&a, &b, &c)); - gg = (TIMFUNC() - gg) >> 1; - if (tt > gg) - tt = gg; - } while (++rr < 100000); - printf("Adding\t\t%4d-bit => %9llu/sec, %9llu cycles\n", - mp_count_bits(&a), CLK_PER_SEC / tt, tt); - FPRINTF(log, "%d %9llu\n", cnt * DIGIT_BIT, tt); - FFLUSH(log); - } - FCLOSE(log); - - log = FOPEN("logs/sub.log", "w"); - for (cnt = 8; cnt <= 128; cnt += 8) { - SLEEP; - mp_rand(&a, cnt); - mp_rand(&b, cnt); - rr = 0; - tt = -1; - do { - gg = TIMFUNC(); - DO(mp_sub(&a, &b, &c)); - gg = (TIMFUNC() - gg) >> 1; - if (tt > gg) - tt = gg; - } while (++rr < 100000); - - printf("Subtracting\t\t%4d-bit => %9llu/sec, %9llu cycles\n", - mp_count_bits(&a), CLK_PER_SEC / tt, tt); - FPRINTF(log, "%d %9llu\n", cnt * DIGIT_BIT, tt); - FFLUSH(log); - } - FCLOSE(log); - - /* do mult/square twice, first without karatsuba and second with */ - old_kara_m = KARATSUBA_MUL_CUTOFF; - old_kara_s = KARATSUBA_SQR_CUTOFF; - /* currently toom-cook cut-off is too high to kick in, so we just use the karatsuba values */ - old_toom_m = old_kara_m; - old_toom_s = old_kara_m; - for (ix = 0; ix < 3; ix++) { - printf("With%s Karatsuba, With%s Toom\n", (ix == 0) ? "out" : "", (ix == 1) ? "out" : ""); - - KARATSUBA_MUL_CUTOFF = (ix == 1) ? old_kara_m : 9999; - KARATSUBA_SQR_CUTOFF = (ix == 1) ? old_kara_s : 9999; - TOOM_MUL_CUTOFF = (ix == 2) ? old_toom_m : 9999; - TOOM_SQR_CUTOFF = (ix == 2) ? old_toom_s : 9999; - - log = FOPEN((ix == 0) ? "logs/mult.log" : (ix == 1) ? "logs/mult_kara.log" : "logs/mult_toom.log", "w"); - for (cnt = 4; cnt <= 10240 / DIGIT_BIT; cnt += 2) { - SLEEP; - mp_rand(&a, cnt); - mp_rand(&b, cnt); - rr = 0; - tt = -1; - do { - gg = TIMFUNC(); - DO(mp_mul(&a, &b, &c)); - gg = (TIMFUNC() - gg) >> 1; - if (tt > gg) - tt = gg; - } while (++rr < 100); - printf("Multiplying\t%4d-bit => %9llu/sec, %9llu cycles\n", - mp_count_bits(&a), CLK_PER_SEC / tt, tt); - FPRINTF(log, "%d %9llu\n", mp_count_bits(&a), tt); - FFLUSH(log); - } - FCLOSE(log); - - log = FOPEN((ix == 0) ? "logs/sqr.log" : (ix == 1) ? "logs/sqr_kara.log" : "logs/sqr_toom.log", "w"); - for (cnt = 4; cnt <= 10240 / DIGIT_BIT; cnt += 2) { - SLEEP; - mp_rand(&a, cnt); - rr = 0; - tt = -1; - do { - gg = TIMFUNC(); - DO(mp_sqr(&a, &b)); - gg = (TIMFUNC() - gg) >> 1; - if (tt > gg) - tt = gg; - } while (++rr < 100); - printf("Squaring\t%4d-bit => %9llu/sec, %9llu cycles\n", - mp_count_bits(&a), CLK_PER_SEC / tt, tt); - FPRINTF(log, "%d %9llu\n", mp_count_bits(&a), tt); - FFLUSH(log); - } - FCLOSE(log); - - } - - { - char *primes[] = { - /* 2K large moduli */ - "179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586239334100047359817950870678242457666208137217", - "32317006071311007300714876688669951960444102669715484032130345427524655138867890893197201411522913463688717960921898019494119559150490921095088152386448283120630877367300996091750197750389652106796057638384067568276792218642619756161838094338476170470581645852036305042887575891541065808607552399123930385521914333389668342420684974786564569494856176035326322058077805659331026192708460314150258592864177116725943603718461857357598351152301645904403697613233287231227125684710820209725157101726931323469678542580656697935045997268352998638099733077152121140120031150424541696791951097529546801429027668869927491725169", - "1044388881413152506691752710716624382579964249047383780384233483283953907971557456848826811934997558340890106714439262837987573438185793607263236087851365277945956976543709998340361590134383718314428070011855946226376318839397712745672334684344586617496807908705803704071284048740118609114467977783598029006686938976881787785946905630190260940599579453432823469303026696443059025015972399867714215541693835559885291486318237914434496734087811872639496475100189041349008417061675093668333850551032972088269550769983616369411933015213796825837188091833656751221318492846368125550225998300412344784862595674492194617023806505913245610825731835380087608622102834270197698202313169017678006675195485079921636419370285375124784014907159135459982790513399611551794271106831134090584272884279791554849782954323534517065223269061394905987693002122963395687782878948440616007412945674919823050571642377154816321380631045902916136926708342856440730447899971901781465763473223850267253059899795996090799469201774624817718449867455659250178329070473119433165550807568221846571746373296884912819520317457002440926616910874148385078411929804522981857338977648103126085902995208257421855249796721729039744118165938433694823325696642096892124547425283", - /* 2K moduli mersenne primes */ - "6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151", - "531137992816767098689588206552468627329593117727031923199444138200403559860852242739162502265229285668889329486246501015346579337652707239409519978766587351943831270835393219031728127", - "10407932194664399081925240327364085538615262247266704805319112350403608059673360298012239441732324184842421613954281007791383566248323464908139906605677320762924129509389220345773183349661583550472959420547689811211693677147548478866962501384438260291732348885311160828538416585028255604666224831890918801847068222203140521026698435488732958028878050869736186900714720710555703168729087", - "1475979915214180235084898622737381736312066145333169775147771216478570297878078949377407337049389289382748507531496480477281264838760259191814463365330269540496961201113430156902396093989090226259326935025281409614983499388222831448598601834318536230923772641390209490231836446899608210795482963763094236630945410832793769905399982457186322944729636418890623372171723742105636440368218459649632948538696905872650486914434637457507280441823676813517852099348660847172579408422316678097670224011990280170474894487426924742108823536808485072502240519452587542875349976558572670229633962575212637477897785501552646522609988869914013540483809865681250419497686697771007", - "259117086013202627776246767922441530941818887553125427303974923161874019266586362086201209516800483406550695241733194177441689509238807017410377709597512042313066624082916353517952311186154862265604547691127595848775610568757931191017711408826252153849035830401185072116424747461823031471398340229288074545677907941037288235820705892351068433882986888616658650280927692080339605869308790500409503709875902119018371991620994002568935113136548829739112656797303241986517250116412703509705427773477972349821676443446668383119322540099648994051790241624056519054483690809616061625743042361721863339415852426431208737266591962061753535748892894599629195183082621860853400937932839420261866586142503251450773096274235376822938649407127700846077124211823080804139298087057504713825264571448379371125032081826126566649084251699453951887789613650248405739378594599444335231188280123660406262468609212150349937584782292237144339628858485938215738821232393687046160677362909315071", - "190797007524439073807468042969529173669356994749940177394741882673528979787005053706368049835514900244303495954950709725762186311224148828811920216904542206960744666169364221195289538436845390250168663932838805192055137154390912666527533007309292687539092257043362517857366624699975402375462954490293259233303137330643531556539739921926201438606439020075174723029056838272505051571967594608350063404495977660656269020823960825567012344189908927956646011998057988548630107637380993519826582389781888135705408653045219655801758081251164080554609057468028203308718724654081055323215860189611391296030471108443146745671967766308925858547271507311563765171008318248647110097614890313562856541784154881743146033909602737947385055355960331855614540900081456378659068370317267696980001187750995491090350108417050917991562167972281070161305972518044872048331306383715094854938415738549894606070722584737978176686422134354526989443028353644037187375385397838259511833166416134323695660367676897722287918773420968982326089026150031515424165462111337527431154890666327374921446276833564519776797633875503548665093914556482031482248883127023777039667707976559857333357013727342079099064400455741830654320379350833236245819348824064783585692924881021978332974949906122664421376034687815350484991", - - /* DR moduli */ - "14059105607947488696282932836518693308967803494693489478439861164411992439598399594747002144074658928593502845729752797260025831423419686528151609940203368612079", - "101745825697019260773923519755878567461315282017759829107608914364075275235254395622580447400994175578963163918967182013639660669771108475957692810857098847138903161308502419410142185759152435680068435915159402496058513611411688900243039", - "736335108039604595805923406147184530889923370574768772191969612422073040099331944991573923112581267542507986451953227192970402893063850485730703075899286013451337291468249027691733891486704001513279827771740183629161065194874727962517148100775228363421083691764065477590823919364012917984605619526140821797602431", - "38564998830736521417281865696453025806593491967131023221754800625044118265468851210705360385717536794615180260494208076605798671660719333199513807806252394423283413430106003596332513246682903994829528690198205120921557533726473585751382193953592127439965050261476810842071573684505878854588706623484573925925903505747545471088867712185004135201289273405614415899438276535626346098904241020877974002916168099951885406379295536200413493190419727789712076165162175783", - "542189391331696172661670440619180536749994166415993334151601745392193484590296600979602378676624808129613777993466242203025054573692562689251250471628358318743978285860720148446448885701001277560572526947619392551574490839286458454994488665744991822837769918095117129546414124448777033941223565831420390846864429504774477949153794689948747680362212954278693335653935890352619041936727463717926744868338358149568368643403037768649616778526013610493696186055899318268339432671541328195724261329606699831016666359440874843103020666106568222401047720269951530296879490444224546654729111504346660859907296364097126834834235287147", - "1487259134814709264092032648525971038895865645148901180585340454985524155135260217788758027400478312256339496385275012465661575576202252063145698732079880294664220579764848767704076761853197216563262660046602703973050798218246170835962005598561669706844469447435461092542265792444947706769615695252256130901271870341005768912974433684521436211263358097522726462083917939091760026658925757076733484173202927141441492573799914240222628795405623953109131594523623353044898339481494120112723445689647986475279242446083151413667587008191682564376412347964146113898565886683139407005941383669325997475076910488086663256335689181157957571445067490187939553165903773554290260531009121879044170766615232300936675369451260747671432073394867530820527479172464106442450727640226503746586340279816318821395210726268291535648506190714616083163403189943334431056876038286530365757187367147446004855912033137386225053275419626102417236133948503", - "1095121115716677802856811290392395128588168592409109494900178008967955253005183831872715423151551999734857184538199864469605657805519106717529655044054833197687459782636297255219742994736751541815269727940751860670268774903340296040006114013971309257028332849679096824800250742691718610670812374272414086863715763724622797509437062518082383056050144624962776302147890521249477060215148275163688301275847155316042279405557632639366066847442861422164832655874655824221577849928863023018366835675399949740429332468186340518172487073360822220449055340582568461568645259954873303616953776393853174845132081121976327462740354930744487429617202585015510744298530101547706821590188733515880733527449780963163909830077616357506845523215289297624086914545378511082534229620116563260168494523906566709418166011112754529766183554579321224940951177394088465596712620076240067370589036924024728375076210477267488679008016579588696191194060127319035195370137160936882402244399699172017835144537488486396906144217720028992863941288217185353914991583400421682751000603596655790990815525126154394344641336397793791497068253936771017031980867706707490224041075826337383538651825493679503771934836094655802776331664261631740148281763487765852746577808019633679", - - /* generic unrestricted moduli */ - "17933601194860113372237070562165128350027320072176844226673287945873370751245439587792371960615073855669274087805055507977323024886880985062002853331424203", - "2893527720709661239493896562339544088620375736490408468011883030469939904368086092336458298221245707898933583190713188177399401852627749210994595974791782790253946539043962213027074922559572312141181787434278708783207966459019479487", - "347743159439876626079252796797422223177535447388206607607181663903045907591201940478223621722118173270898487582987137708656414344685816179420855160986340457973820182883508387588163122354089264395604796675278966117567294812714812796820596564876450716066283126720010859041484786529056457896367683122960411136319", - "47266428956356393164697365098120418976400602706072312735924071745438532218237979333351774907308168340693326687317443721193266215155735814510792148768576498491199122744351399489453533553203833318691678263241941706256996197460424029012419012634671862283532342656309677173602509498417976091509154360039893165037637034737020327399910409885798185771003505320583967737293415979917317338985837385734747478364242020380416892056650841470869294527543597349250299539682430605173321029026555546832473048600327036845781970289288898317888427517364945316709081173840186150794397479045034008257793436817683392375274635794835245695887", - "436463808505957768574894870394349739623346440601945961161254440072143298152040105676491048248110146278752857839930515766167441407021501229924721335644557342265864606569000117714935185566842453630868849121480179691838399545644365571106757731317371758557990781880691336695584799313313687287468894148823761785582982549586183756806449017542622267874275103877481475534991201849912222670102069951687572917937634467778042874315463238062009202992087620963771759666448266532858079402669920025224220613419441069718482837399612644978839925207109870840278194042158748845445131729137117098529028886770063736487420613144045836803985635654192482395882603511950547826439092832800532152534003936926017612446606135655146445620623395788978726744728503058670046885876251527122350275750995227", - "11424167473351836398078306042624362277956429440521137061889702611766348760692206243140413411077394583180726863277012016602279290144126785129569474909173584789822341986742719230331946072730319555984484911716797058875905400999504305877245849119687509023232790273637466821052576859232452982061831009770786031785669030271542286603956118755585683996118896215213488875253101894663403069677745948305893849505434201763745232895780711972432011344857521691017896316861403206449421332243658855453435784006517202894181640562433575390821384210960117518650374602256601091379644034244332285065935413233557998331562749140202965844219336298970011513882564935538704289446968322281451907487362046511461221329799897350993370560697505809686438782036235372137015731304779072430260986460269894522159103008260495503005267165927542949439526272736586626709581721032189532726389643625590680105784844246152702670169304203783072275089194754889511973916207", - "1214855636816562637502584060163403830270705000634713483015101384881871978446801224798536155406895823305035467591632531067547890948695117172076954220727075688048751022421198712032848890056357845974246560748347918630050853933697792254955890439720297560693579400297062396904306270145886830719309296352765295712183040773146419022875165382778007040109957609739589875590885701126197906063620133954893216612678838507540777138437797705602453719559017633986486649523611975865005712371194067612263330335590526176087004421363598470302731349138773205901447704682181517904064735636518462452242791676541725292378925568296858010151852326316777511935037531017413910506921922450666933202278489024521263798482237150056835746454842662048692127173834433089016107854491097456725016327709663199738238442164843147132789153725513257167915555162094970853584447993125488607696008169807374736711297007473812256272245489405898470297178738029484459690836250560495461579533254473316340608217876781986188705928270735695752830825527963838355419762516246028680280988020401914551825487349990306976304093109384451438813251211051597392127491464898797406789175453067960072008590614886532333015881171367104445044718144312416815712216611576221546455968770801413440778423979", - NULL - }; - log = FOPEN("logs/expt.log", "w"); - logb = FOPEN("logs/expt_dr.log", "w"); - logc = FOPEN("logs/expt_2k.log", "w"); - logd = FOPEN("logs/expt_2kl.log", "w"); - for (n = 0; primes[n]; n++) { - SLEEP; - mp_read_radix(&a, primes[n], 10); - mp_zero(&b); - for (rr = 0; rr < (unsigned) mp_count_bits(&a); rr++) { - mp_mul_2(&b, &b); - b.dp[0] |= lbit(); - b.used += 1; - } - mp_sub_d(&a, 1, &c); - mp_mod(&b, &c, &b); - mp_set(&c, 3); - rr = 0; - tt = -1; - do { - gg = TIMFUNC(); - DO(mp_exptmod(&c, &b, &a, &d)); - gg = (TIMFUNC() - gg) >> 1; - if (tt > gg) - tt = gg; - } while (++rr < 10); - mp_sub_d(&a, 1, &e); - mp_sub(&e, &b, &b); - mp_exptmod(&c, &b, &a, &e); /* c^(p-1-b) mod a */ - mp_mulmod(&e, &d, &a, &d); /* c^b * c^(p-1-b) == c^p-1 == 1 */ - if (mp_cmp_d(&d, 1)) { - printf("Different (%d)!!!\n", mp_count_bits(&a)); - draw(&d); - exit(0); - } - printf("Exponentiating\t%4d-bit => %9llu/sec, %9llu cycles\n", - mp_count_bits(&a), CLK_PER_SEC / tt, tt); - FPRINTF(n < 4 ? logd : (n < 9) ? logc : (n < 16) ? logb : log, - "%d %9llu\n", mp_count_bits(&a), tt); - } - } - FCLOSE(log); - FCLOSE(logb); - FCLOSE(logc); - FCLOSE(logd); - - log = FOPEN("logs/invmod.log", "w"); - for (cnt = 4; cnt <= 32; cnt += 4) { - SLEEP; - mp_rand(&a, cnt); - mp_rand(&b, cnt); - - do { - mp_add_d(&b, 1, &b); - mp_gcd(&a, &b, &c); - } while (mp_cmp_d(&c, 1) != MP_EQ); - - rr = 0; - tt = -1; - do { - gg = TIMFUNC(); - DO(mp_invmod(&b, &a, &c)); - gg = (TIMFUNC() - gg) >> 1; - if (tt > gg) - tt = gg; - } while (++rr < 1000); - mp_mulmod(&b, &c, &a, &d); - if (mp_cmp_d(&d, 1) != MP_EQ) { - printf("Failed to invert\n"); - return 0; - } - printf("Inverting mod\t%4d-bit => %9llu/sec, %9llu cycles\n", - mp_count_bits(&a), CLK_PER_SEC / tt, tt); - FPRINTF(log, "%d %9llu\n", cnt * DIGIT_BIT, tt); - } - FCLOSE(log); - - return 0; -} - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/dep.pl b/libtommath/dep.pl deleted file mode 100644 index fe9ab59..0000000 --- a/libtommath/dep.pl +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/perl -# -# Walk through source, add labels and make classes -# -use strict; -use warnings; - -my %deplist; - -#open class file and write preamble -open(my $class, '>', 'tommath_class.h') or die "Couldn't open tommath_class.h for writing\n"; -print {$class} "#if !(defined(LTM1) && defined(LTM2) && defined(LTM3))\n#if defined(LTM2)\n#define LTM3\n#endif\n#if defined(LTM1)\n#define LTM2\n#endif\n#define LTM1\n\n#if defined(LTM_ALL)\n"; - -foreach my $filename (glob 'bn*.c') { - my $define = $filename; - - print "Processing $filename\n"; - - # convert filename to upper case so we can use it as a define - $define =~ tr/[a-z]/[A-Z]/; - $define =~ tr/\./_/; - print {$class} "#define $define\n"; - - # now copy text and apply #ifdef as required - my $apply = 0; - open(my $src, '<', $filename); - open(my $out, '>', 'tmp'); - - # first line will be the #ifdef - my $line = <$src>; - if ($line =~ /include/) { - print {$out} $line; - } else { - print {$out} "#include <tommath.h>\n#ifdef $define\n$line"; - $apply = 1; - } - while (<$src>) { - if (!($_ =~ /tommath\.h/)) { - print {$out} $_; - } - } - if ($apply == 1) { - print {$out} "#endif\n"; - } - close $src; - close $out; - - unlink $filename; - rename 'tmp', $filename; -} -print {$class} "#endif\n\n"; - -# now do classes - -foreach my $filename (glob 'bn*.c') { - open(my $src, '<', $filename) or die "Can't open source file!\n"; - - # convert filename to upper case so we can use it as a define - $filename =~ tr/[a-z]/[A-Z]/; - $filename =~ tr/\./_/; - - print {$class} "#if defined($filename)\n"; - my $list = $filename; - - # scan for mp_* and make classes - while (<$src>) { - my $line = $_; - while ($line =~ m/(fast_)*(s_)*mp\_[a-z_0-9]*/) { - $line = $'; - # now $& is the match, we want to skip over LTM keywords like - # mp_int, mp_word, mp_digit - if (!($& eq 'mp_digit') && !($& eq 'mp_word') && !($& eq 'mp_int') && !($& eq 'mp_min_u32')) { - my $a = $&; - $a =~ tr/[a-z]/[A-Z]/; - $a = 'BN_' . $a . '_C'; - if (!($list =~ /$a/)) { - print {$class} " #define $a\n"; - } - $list = $list . ',' . $a; - } - } - } - $deplist{$filename} = $list; - - print {$class} "#endif\n\n"; - close $src; -} - -print {$class} "#ifdef LTM3\n#define LTM_LAST\n#endif\n#include <tommath_superclass.h>\n#include <tommath_class.h>\n#else\n#define LTM_LAST\n#endif\n"; -close $class; - -#now let's make a cool call graph... - -open(my $out, '>', 'callgraph.txt'); -my $indent = 0; -my $list; -foreach (sort keys %deplist) { - $list = ''; - draw_func($deplist{$_}); - print {$out} "\n\n"; -} -close $out; - -sub draw_func -{ - my @funcs = split ',', $_[0]; - if ($list =~ /$funcs[0]/) { - return; - } else { - $list = $list . $funcs[0]; - } - if ($indent == 0) { - } elsif ($indent >= 1) { - print {$out} '| ' x ($indent - 1) . '+--->'; - } - print {$out} $funcs[0] . "\n"; - shift @funcs; - my $temp = $list; - foreach my $i (@funcs) { - ++$indent; - draw_func($deplist{$i}) if exists $deplist{$i}; - --$indent; - } - $list = $temp; - return; -} - diff --git a/libtommath/etc/2kprime.1 b/libtommath/etc/2kprime.1 deleted file mode 100644 index c41ded1..0000000 --- a/libtommath/etc/2kprime.1 +++ /dev/null @@ -1,2 +0,0 @@ -256-bits (k = 36113) = 115792089237316195423570985008687907853269984665640564039457584007913129603823 -512-bits (k = 38117) = 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006045979 diff --git a/libtommath/etc/2kprime.c b/libtommath/etc/2kprime.c deleted file mode 100644 index 14da57e..0000000 --- a/libtommath/etc/2kprime.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Makes safe primes of a 2k nature */ -#include <tommath.h> -#include <time.h> - -int sizes[] = {256, 512, 768, 1024, 1536, 2048, 3072, 4096}; - -int main(void) -{ - char buf[2000]; - int x, y; - mp_int q, p; - FILE *out; - clock_t t1; - mp_digit z; - - mp_init_multi(&q, &p, NULL); - - out = fopen("2kprime.1", "w"); - for (x = 0; x < (int)(sizeof(sizes) / sizeof(sizes[0])); x++) { - top: - mp_2expt(&q, sizes[x]); - mp_add_d(&q, 3, &q); - z = -3; - - t1 = clock(); - for(;;) { - mp_sub_d(&q, 4, &q); - z += 4; - - if (z > MP_MASK) { - printf("No primes of size %d found\n", sizes[x]); - break; - } - - if (clock() - t1 > CLOCKS_PER_SEC) { - printf("."); fflush(stdout); -// sleep((clock() - t1 + CLOCKS_PER_SEC/2)/CLOCKS_PER_SEC); - t1 = clock(); - } - - /* quick test on q */ - mp_prime_is_prime(&q, 1, &y); - if (y == 0) { - continue; - } - - /* find (q-1)/2 */ - mp_sub_d(&q, 1, &p); - mp_div_2(&p, &p); - mp_prime_is_prime(&p, 3, &y); - if (y == 0) { - continue; - } - - /* test on q */ - mp_prime_is_prime(&q, 3, &y); - if (y == 0) { - continue; - } - - break; - } - - if (y == 0) { - ++sizes[x]; - goto top; - } - - mp_toradix(&q, buf, 10); - printf("\n\n%d-bits (k = %lu) = %s\n", sizes[x], z, buf); - fprintf(out, "%d-bits (k = %lu) = %s\n", sizes[x], z, buf); fflush(out); - } - - return 0; -} - - - - - - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/etc/drprime.c b/libtommath/etc/drprime.c deleted file mode 100644 index 29d89db..0000000 --- a/libtommath/etc/drprime.c +++ /dev/null @@ -1,64 +0,0 @@ -/* Makes safe primes of a DR nature */ -#include <tommath.h> - -int sizes[] = { 1+256/DIGIT_BIT, 1+512/DIGIT_BIT, 1+768/DIGIT_BIT, 1+1024/DIGIT_BIT, 1+2048/DIGIT_BIT, 1+4096/DIGIT_BIT }; -int main(void) -{ - int res, x, y; - char buf[4096]; - FILE *out; - mp_int a, b; - - mp_init(&a); - mp_init(&b); - - out = fopen("drprimes.txt", "w"); - for (x = 0; x < (int)(sizeof(sizes)/sizeof(sizes[0])); x++) { - top: - printf("Seeking a %d-bit safe prime\n", sizes[x] * DIGIT_BIT); - mp_grow(&a, sizes[x]); - mp_zero(&a); - for (y = 1; y < sizes[x]; y++) { - a.dp[y] = MP_MASK; - } - - /* make a DR modulus */ - a.dp[0] = -1; - a.used = sizes[x]; - - /* now loop */ - res = 0; - for (;;) { - a.dp[0] += 4; - if (a.dp[0] >= MP_MASK) break; - mp_prime_is_prime(&a, 1, &res); - if (res == 0) continue; - printf("."); fflush(stdout); - mp_sub_d(&a, 1, &b); - mp_div_2(&b, &b); - mp_prime_is_prime(&b, 3, &res); - if (res == 0) continue; - mp_prime_is_prime(&a, 3, &res); - if (res == 1) break; - } - - if (res != 1) { - printf("Error not DR modulus\n"); sizes[x] += 1; goto top; - } else { - mp_toradix(&a, buf, 10); - printf("\n\np == %s\n\n", buf); - fprintf(out, "%d-bit prime:\np == %s\n\n", mp_count_bits(&a), buf); fflush(out); - } - } - fclose(out); - - mp_clear(&a); - mp_clear(&b); - - return 0; -} - - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/etc/drprimes.28 b/libtommath/etc/drprimes.28 deleted file mode 100644 index 9d438ad..0000000 --- a/libtommath/etc/drprimes.28 +++ /dev/null @@ -1,25 +0,0 @@ -DR safe primes for 28-bit digits. - -224-bit prime: -p == 26959946667150639794667015087019630673637144422540572481103341844143 - -532-bit prime: -p == 14059105607947488696282932836518693308967803494693489478439861164411992439598399594747002144074658928593502845729752797260025831423419686528151609940203368691747 - -784-bit prime: -p == 101745825697019260773923519755878567461315282017759829107608914364075275235254395622580447400994175578963163918967182013639660669771108475957692810857098847138903161308502419410142185759152435680068435915159402496058513611411688900243039 - -1036-bit prime: -p == 736335108039604595805923406147184530889923370574768772191969612422073040099331944991573923112581267542507986451953227192970402893063850485730703075899286013451337291468249027691733891486704001513279827771740183629161065194874727962517148100775228363421083691764065477590823919364012917984605619526140821798437127 - -1540-bit prime: -p == 38564998830736521417281865696453025806593491967131023221754800625044118265468851210705360385717536794615180260494208076605798671660719333199513807806252394423283413430106003596332513246682903994829528690198205120921557533726473585751382193953592127439965050261476810842071573684505878854588706623484573925925903505747545471088867712185004135201289273405614415899438276535626346098904241020877974002916168099951885406379295536200413493190419727789712076165162175783 - -2072-bit prime: -p == 542189391331696172661670440619180536749994166415993334151601745392193484590296600979602378676624808129613777993466242203025054573692562689251250471628358318743978285860720148446448885701001277560572526947619392551574490839286458454994488665744991822837769918095117129546414124448777033941223565831420390846864429504774477949153794689948747680362212954278693335653935890352619041936727463717926744868338358149568368643403037768649616778526013610493696186055899318268339432671541328195724261329606699831016666359440874843103020666106568222401047720269951530296879490444224546654729111504346660859907296364097126834834235287147 - -3080-bit prime: -p == 1487259134814709264092032648525971038895865645148901180585340454985524155135260217788758027400478312256339496385275012465661575576202252063145698732079880294664220579764848767704076761853197216563262660046602703973050798218246170835962005598561669706844469447435461092542265792444947706769615695252256130901271870341005768912974433684521436211263358097522726462083917939091760026658925757076733484173202927141441492573799914240222628795405623953109131594523623353044898339481494120112723445689647986475279242446083151413667587008191682564376412347964146113898565886683139407005941383669325997475076910488086663256335689181157957571445067490187939553165903773554290260531009121879044170766615232300936675369451260747671432073394867530820527479172464106442450727640226503746586340279816318821395210726268291535648506190714616083163403189943334431056876038286530365757187367147446004855912033137386225053275419626102417236133948503 - -4116-bit prime: -p == 1095121115716677802856811290392395128588168592409109494900178008967955253005183831872715423151551999734857184538199864469605657805519106717529655044054833197687459782636297255219742994736751541815269727940751860670268774903340296040006114013971309257028332849679096824800250742691718610670812374272414086863715763724622797509437062518082383056050144624962776302147890521249477060215148275163688301275847155316042279405557632639366066847442861422164832655874655824221577849928863023018366835675399949740429332468186340518172487073360822220449055340582568461568645259954873303616953776393853174845132081121976327462740354930744487429617202585015510744298530101547706821590188733515880733527449780963163909830077616357506845523215289297624086914545378511082534229620116563260168494523906566709418166011112754529766183554579321224940951177394088465596712620076240067370589036924024728375076210477267488679008016579588696191194060127319035195370137160936882402244399699172017835144537488486396906144217720028992863941288217185353914991583400421682751000603596655790990815525126154394344641336397793791497068253936771017031980867706707490224041075826337383538651825493679503771934836094655802776331664261631740148281763487765852746577808019633679 diff --git a/libtommath/etc/drprimes.txt b/libtommath/etc/drprimes.txt deleted file mode 100644 index 7c97f67..0000000 --- a/libtommath/etc/drprimes.txt +++ /dev/null @@ -1,9 +0,0 @@ -300-bit prime: -p == 2037035976334486086268445688409378161051468393665936250636140449354381298610415201576637819 - -540-bit prime: -p == 3599131035634557106248430806148785487095757694641533306480604458089470064537190296255232548883112685719936728506816716098566612844395439751206810991770626477344739 - -780-bit prime: -p == 6359114106063703798370219984742410466332205126109989319225557147754704702203399726411277962562135973685197744935448875852478791860694279747355800678568677946181447581781401213133886609947027230004277244697462656003655947791725966271167 - diff --git a/libtommath/etc/makefile b/libtommath/etc/makefile deleted file mode 100644 index 99154d8..0000000 --- a/libtommath/etc/makefile +++ /dev/null @@ -1,50 +0,0 @@ -CFLAGS += -Wall -W -Wshadow -O3 -fomit-frame-pointer -funroll-loops -I../ - -# default lib name (requires install with root) -# LIBNAME=-ltommath - -# libname when you can't install the lib with install -LIBNAME=../libtommath.a - -#provable primes -pprime: pprime.o - $(CC) pprime.o $(LIBNAME) -o pprime - -# portable [well requires clock()] tuning app -tune: tune.o - $(CC) tune.o $(LIBNAME) -o tune - -# same app but using RDTSC for higher precision [requires 80586+], coff based gcc installs [e.g. ming, cygwin, djgpp] -tune86: tune.c - nasm -f coff timer.asm - $(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o $(LIBNAME) -o tune86 - -# for cygwin -tune86c: tune.c - nasm -f gnuwin32 timer.asm - $(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o $(LIBNAME) -o tune86 - -#make tune86 for linux or any ELF format -tune86l: tune.c - nasm -f elf -DUSE_ELF timer.asm - $(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o $(LIBNAME) -o tune86l - -# spits out mersenne primes -mersenne: mersenne.o - $(CC) mersenne.o $(LIBNAME) -o mersenne - -# fines DR safe primes for the given config -drprime: drprime.o - $(CC) drprime.o $(LIBNAME) -o drprime - -# fines 2k safe primes for the given config -2kprime: 2kprime.o - $(CC) 2kprime.o $(LIBNAME) -o 2kprime - -mont: mont.o - $(CC) mont.o $(LIBNAME) -o mont - - -clean: - rm -f *.log *.o *.obj *.exe pprime tune mersenne drprime tune86 tune86l mont 2kprime pprime.dat \ - *.da *.dyn *.dpi *~ diff --git a/libtommath/etc/makefile.icc b/libtommath/etc/makefile.icc deleted file mode 100644 index 8a1ffff..0000000 --- a/libtommath/etc/makefile.icc +++ /dev/null @@ -1,67 +0,0 @@ -CC = icc - -CFLAGS += -I../ - -# optimize for SPEED -# -# -mcpu= can be pentium, pentiumpro (covers PII through PIII) or pentium4 -# -ax? specifies make code specifically for ? but compatible with IA-32 -# -x? specifies compile solely for ? [not specifically IA-32 compatible] -# -# where ? is -# K - PIII -# W - first P4 [Williamette] -# N - P4 Northwood -# P - P4 Prescott -# B - Blend of P4 and PM [mobile] -# -# Default to just generic max opts -CFLAGS += -O3 -xP -ip - -# default lib name (requires install with root) -# LIBNAME=-ltommath - -# libname when you can't install the lib with install -LIBNAME=../libtommath.a - -#provable primes -pprime: pprime.o - $(CC) pprime.o $(LIBNAME) -o pprime - -# portable [well requires clock()] tuning app -tune: tune.o - $(CC) tune.o $(LIBNAME) -o tune - -# same app but using RDTSC for higher precision [requires 80586+], coff based gcc installs [e.g. ming, cygwin, djgpp] -tune86: tune.c - nasm -f coff timer.asm - $(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o $(LIBNAME) -o tune86 - -# for cygwin -tune86c: tune.c - nasm -f gnuwin32 timer.asm - $(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o $(LIBNAME) -o tune86 - -#make tune86 for linux or any ELF format -tune86l: tune.c - nasm -f elf -DUSE_ELF timer.asm - $(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o $(LIBNAME) -o tune86l - -# spits out mersenne primes -mersenne: mersenne.o - $(CC) mersenne.o $(LIBNAME) -o mersenne - -# fines DR safe primes for the given config -drprime: drprime.o - $(CC) drprime.o $(LIBNAME) -o drprime - -# fines 2k safe primes for the given config -2kprime: 2kprime.o - $(CC) 2kprime.o $(LIBNAME) -o 2kprime - -mont: mont.o - $(CC) mont.o $(LIBNAME) -o mont - - -clean: - rm -f *.log *.o *.obj *.exe pprime tune mersenne drprime tune86 tune86l mont 2kprime pprime.dat *.il diff --git a/libtommath/etc/makefile.msvc b/libtommath/etc/makefile.msvc deleted file mode 100644 index 2833372..0000000 --- a/libtommath/etc/makefile.msvc +++ /dev/null @@ -1,23 +0,0 @@ -#MSVC Makefile -# -#Tom St Denis - -CFLAGS = /I../ /Ox /DWIN32 /W3 - -pprime: pprime.obj - cl pprime.obj ../tommath.lib - -mersenne: mersenne.obj - cl mersenne.obj ../tommath.lib - -tune: tune.obj - cl tune.obj ../tommath.lib - -mont: mont.obj - cl mont.obj ../tommath.lib - -drprime: drprime.obj - cl drprime.obj ../tommath.lib - -2kprime: 2kprime.obj - cl 2kprime.obj ../tommath.lib diff --git a/libtommath/etc/mersenne.c b/libtommath/etc/mersenne.c deleted file mode 100644 index 432cec1..0000000 --- a/libtommath/etc/mersenne.c +++ /dev/null @@ -1,144 +0,0 @@ -/* Finds Mersenne primes using the Lucas-Lehmer test - * - * Tom St Denis, tomstdenis@gmail.com - */ -#include <time.h> -#include <tommath.h> - -int -is_mersenne (long s, int *pp) -{ - mp_int n, u; - int res, k; - - *pp = 0; - - if ((res = mp_init (&n)) != MP_OKAY) { - return res; - } - - if ((res = mp_init (&u)) != MP_OKAY) { - goto LBL_N; - } - - /* n = 2^s - 1 */ - if ((res = mp_2expt(&n, s)) != MP_OKAY) { - goto LBL_MU; - } - if ((res = mp_sub_d (&n, 1, &n)) != MP_OKAY) { - goto LBL_MU; - } - - /* set u=4 */ - mp_set (&u, 4); - - /* for k=1 to s-2 do */ - for (k = 1; k <= s - 2; k++) { - /* u = u^2 - 2 mod n */ - if ((res = mp_sqr (&u, &u)) != MP_OKAY) { - goto LBL_MU; - } - if ((res = mp_sub_d (&u, 2, &u)) != MP_OKAY) { - goto LBL_MU; - } - - /* make sure u is positive */ - while (u.sign == MP_NEG) { - if ((res = mp_add (&u, &n, &u)) != MP_OKAY) { - goto LBL_MU; - } - } - - /* reduce */ - if ((res = mp_reduce_2k (&u, &n, 1)) != MP_OKAY) { - goto LBL_MU; - } - } - - /* if u == 0 then its prime */ - if (mp_iszero (&u) == 1) { - mp_prime_is_prime(&n, 8, pp); - if (*pp != 1) printf("FAILURE\n"); - } - - res = MP_OKAY; -LBL_MU:mp_clear (&u); -LBL_N:mp_clear (&n); - return res; -} - -/* square root of a long < 65536 */ -long -i_sqrt (long x) -{ - long x1, x2; - - x2 = 16; - do { - x1 = x2; - x2 = x1 - ((x1 * x1) - x) / (2 * x1); - } while (x1 != x2); - - if (x1 * x1 > x) { - --x1; - } - - return x1; -} - -/* is the long prime by brute force */ -int -isprime (long k) -{ - long y, z; - - y = i_sqrt (k); - for (z = 2; z <= y; z++) { - if ((k % z) == 0) - return 0; - } - return 1; -} - - -int -main (void) -{ - int pp; - long k; - clock_t tt; - - k = 3; - - for (;;) { - /* start time */ - tt = clock (); - - /* test if 2^k - 1 is prime */ - if (is_mersenne (k, &pp) != MP_OKAY) { - printf ("Whoa error\n"); - return -1; - } - - if (pp == 1) { - /* count time */ - tt = clock () - tt; - - /* display if prime */ - printf ("2^%-5ld - 1 is prime, test took %ld ticks\n", k, tt); - } - - /* goto next odd exponent */ - k += 2; - - /* but make sure its prime */ - while (isprime (k) == 0) { - k += 2; - } - } - return 0; -} - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/etc/mont.c b/libtommath/etc/mont.c deleted file mode 100644 index ac14e06..0000000 --- a/libtommath/etc/mont.c +++ /dev/null @@ -1,50 +0,0 @@ -/* tests the montgomery routines */ -#include <tommath.h> - -int main(void) -{ - mp_int modulus, R, p, pp; - mp_digit mp; - long x, y; - - srand(time(NULL)); - mp_init_multi(&modulus, &R, &p, &pp, NULL); - - /* loop through various sizes */ - for (x = 4; x < 256; x++) { - printf("DIGITS == %3ld...", x); fflush(stdout); - - /* make up the odd modulus */ - mp_rand(&modulus, x); - modulus.dp[0] |= 1; - - /* now find the R value */ - mp_montgomery_calc_normalization(&R, &modulus); - mp_montgomery_setup(&modulus, &mp); - - /* now run through a bunch tests */ - for (y = 0; y < 1000; y++) { - mp_rand(&p, x/2); /* p = random */ - mp_mul(&p, &R, &pp); /* pp = R * p */ - mp_montgomery_reduce(&pp, &modulus, mp); - - /* should be equal to p */ - if (mp_cmp(&pp, &p) != MP_EQ) { - printf("FAILURE!\n"); - exit(-1); - } - } - printf("PASSED\n"); - } - - return 0; -} - - - - - - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/etc/pprime.c b/libtommath/etc/pprime.c deleted file mode 100644 index 0313948..0000000 --- a/libtommath/etc/pprime.c +++ /dev/null @@ -1,400 +0,0 @@ -/* Generates provable primes - * - * See http://gmail.com:8080/papers/pp.pdf for more info. - * - * Tom St Denis, tomstdenis@gmail.com, http://tom.gmail.com - */ -#include <time.h> -#include "tommath.h" - -int n_prime; -FILE *primes; - -/* fast square root */ -static mp_digit -i_sqrt (mp_word x) -{ - mp_word x1, x2; - - x2 = x; - do { - x1 = x2; - x2 = x1 - ((x1 * x1) - x) / (2 * x1); - } while (x1 != x2); - - if (x1 * x1 > x) { - --x1; - } - - return x1; -} - - -/* generates a prime digit */ -static void gen_prime (void) -{ - mp_digit r, x, y, next; - FILE *out; - - out = fopen("pprime.dat", "wb"); - - /* write first set of primes */ - r = 3; fwrite(&r, 1, sizeof(mp_digit), out); - r = 5; fwrite(&r, 1, sizeof(mp_digit), out); - r = 7; fwrite(&r, 1, sizeof(mp_digit), out); - r = 11; fwrite(&r, 1, sizeof(mp_digit), out); - r = 13; fwrite(&r, 1, sizeof(mp_digit), out); - r = 17; fwrite(&r, 1, sizeof(mp_digit), out); - r = 19; fwrite(&r, 1, sizeof(mp_digit), out); - r = 23; fwrite(&r, 1, sizeof(mp_digit), out); - r = 29; fwrite(&r, 1, sizeof(mp_digit), out); - r = 31; fwrite(&r, 1, sizeof(mp_digit), out); - - /* get square root, since if 'r' is composite its factors must be < than this */ - y = i_sqrt (r); - next = (y + 1) * (y + 1); - - for (;;) { - do { - r += 2; /* next candidate */ - r &= MP_MASK; - if (r < 31) break; - - /* update sqrt ? */ - if (next <= r) { - ++y; - next = (y + 1) * (y + 1); - } - - /* loop if divisible by 3,5,7,11,13,17,19,23,29 */ - if ((r % 3) == 0) { - x = 0; - continue; - } - if ((r % 5) == 0) { - x = 0; - continue; - } - if ((r % 7) == 0) { - x = 0; - continue; - } - if ((r % 11) == 0) { - x = 0; - continue; - } - if ((r % 13) == 0) { - x = 0; - continue; - } - if ((r % 17) == 0) { - x = 0; - continue; - } - if ((r % 19) == 0) { - x = 0; - continue; - } - if ((r % 23) == 0) { - x = 0; - continue; - } - if ((r % 29) == 0) { - x = 0; - continue; - } - - /* now check if r is divisible by x + k={1,7,11,13,17,19,23,29} */ - for (x = 30; x <= y; x += 30) { - if ((r % (x + 1)) == 0) { - x = 0; - break; - } - if ((r % (x + 7)) == 0) { - x = 0; - break; - } - if ((r % (x + 11)) == 0) { - x = 0; - break; - } - if ((r % (x + 13)) == 0) { - x = 0; - break; - } - if ((r % (x + 17)) == 0) { - x = 0; - break; - } - if ((r % (x + 19)) == 0) { - x = 0; - break; - } - if ((r % (x + 23)) == 0) { - x = 0; - break; - } - if ((r % (x + 29)) == 0) { - x = 0; - break; - } - } - } while (x == 0); - if (r > 31) { fwrite(&r, 1, sizeof(mp_digit), out); printf("%9d\r", r); fflush(stdout); } - if (r < 31) break; - } - - fclose(out); -} - -void load_tab(void) -{ - primes = fopen("pprime.dat", "rb"); - if (primes == NULL) { - gen_prime(); - primes = fopen("pprime.dat", "rb"); - } - fseek(primes, 0, SEEK_END); - n_prime = ftell(primes) / sizeof(mp_digit); -} - -mp_digit prime_digit(void) -{ - int n; - mp_digit d; - - n = abs(rand()) % n_prime; - fseek(primes, n * sizeof(mp_digit), SEEK_SET); - fread(&d, 1, sizeof(mp_digit), primes); - return d; -} - - -/* makes a prime of at least k bits */ -int -pprime (int k, int li, mp_int * p, mp_int * q) -{ - mp_int a, b, c, n, x, y, z, v; - int res, ii; - static const mp_digit bases[] = { 2, 3, 5, 7, 11, 13, 17, 19 }; - - /* single digit ? */ - if (k <= (int) DIGIT_BIT) { - mp_set (p, prime_digit ()); - return MP_OKAY; - } - - if ((res = mp_init (&c)) != MP_OKAY) { - return res; - } - - if ((res = mp_init (&v)) != MP_OKAY) { - goto LBL_C; - } - - /* product of first 50 primes */ - if ((res = - mp_read_radix (&v, - "19078266889580195013601891820992757757219839668357012055907516904309700014933909014729740190", - 10)) != MP_OKAY) { - goto LBL_V; - } - - if ((res = mp_init (&a)) != MP_OKAY) { - goto LBL_V; - } - - /* set the prime */ - mp_set (&a, prime_digit ()); - - if ((res = mp_init (&b)) != MP_OKAY) { - goto LBL_A; - } - - if ((res = mp_init (&n)) != MP_OKAY) { - goto LBL_B; - } - - if ((res = mp_init (&x)) != MP_OKAY) { - goto LBL_N; - } - - if ((res = mp_init (&y)) != MP_OKAY) { - goto LBL_X; - } - - if ((res = mp_init (&z)) != MP_OKAY) { - goto LBL_Y; - } - - /* now loop making the single digit */ - while (mp_count_bits (&a) < k) { - fprintf (stderr, "prime has %4d bits left\r", k - mp_count_bits (&a)); - fflush (stderr); - top: - mp_set (&b, prime_digit ()); - - /* now compute z = a * b * 2 */ - if ((res = mp_mul (&a, &b, &z)) != MP_OKAY) { /* z = a * b */ - goto LBL_Z; - } - - if ((res = mp_copy (&z, &c)) != MP_OKAY) { /* c = a * b */ - goto LBL_Z; - } - - if ((res = mp_mul_2 (&z, &z)) != MP_OKAY) { /* z = 2 * a * b */ - goto LBL_Z; - } - - /* n = z + 1 */ - if ((res = mp_add_d (&z, 1, &n)) != MP_OKAY) { /* n = z + 1 */ - goto LBL_Z; - } - - /* check (n, v) == 1 */ - if ((res = mp_gcd (&n, &v, &y)) != MP_OKAY) { /* y = (n, v) */ - goto LBL_Z; - } - - if (mp_cmp_d (&y, 1) != MP_EQ) - goto top; - - /* now try base x=bases[ii] */ - for (ii = 0; ii < li; ii++) { - mp_set (&x, bases[ii]); - - /* compute x^a mod n */ - if ((res = mp_exptmod (&x, &a, &n, &y)) != MP_OKAY) { /* y = x^a mod n */ - goto LBL_Z; - } - - /* if y == 1 loop */ - if (mp_cmp_d (&y, 1) == MP_EQ) - continue; - - /* now x^2a mod n */ - if ((res = mp_sqrmod (&y, &n, &y)) != MP_OKAY) { /* y = x^2a mod n */ - goto LBL_Z; - } - - if (mp_cmp_d (&y, 1) == MP_EQ) - continue; - - /* compute x^b mod n */ - if ((res = mp_exptmod (&x, &b, &n, &y)) != MP_OKAY) { /* y = x^b mod n */ - goto LBL_Z; - } - - /* if y == 1 loop */ - if (mp_cmp_d (&y, 1) == MP_EQ) - continue; - - /* now x^2b mod n */ - if ((res = mp_sqrmod (&y, &n, &y)) != MP_OKAY) { /* y = x^2b mod n */ - goto LBL_Z; - } - - if (mp_cmp_d (&y, 1) == MP_EQ) - continue; - - /* compute x^c mod n == x^ab mod n */ - if ((res = mp_exptmod (&x, &c, &n, &y)) != MP_OKAY) { /* y = x^ab mod n */ - goto LBL_Z; - } - - /* if y == 1 loop */ - if (mp_cmp_d (&y, 1) == MP_EQ) - continue; - - /* now compute (x^c mod n)^2 */ - if ((res = mp_sqrmod (&y, &n, &y)) != MP_OKAY) { /* y = x^2ab mod n */ - goto LBL_Z; - } - - /* y should be 1 */ - if (mp_cmp_d (&y, 1) != MP_EQ) - continue; - break; - } - - /* no bases worked? */ - if (ii == li) - goto top; - -{ - char buf[4096]; - - mp_toradix(&n, buf, 10); - printf("Certificate of primality for:\n%s\n\n", buf); - mp_toradix(&a, buf, 10); - printf("A == \n%s\n\n", buf); - mp_toradix(&b, buf, 10); - printf("B == \n%s\n\nG == %d\n", buf, bases[ii]); - printf("----------------------------------------------------------------\n"); -} - - /* a = n */ - mp_copy (&n, &a); - } - - /* get q to be the order of the large prime subgroup */ - mp_sub_d (&n, 1, q); - mp_div_2 (q, q); - mp_div (q, &b, q, NULL); - - mp_exch (&n, p); - - res = MP_OKAY; -LBL_Z:mp_clear (&z); -LBL_Y:mp_clear (&y); -LBL_X:mp_clear (&x); -LBL_N:mp_clear (&n); -LBL_B:mp_clear (&b); -LBL_A:mp_clear (&a); -LBL_V:mp_clear (&v); -LBL_C:mp_clear (&c); - return res; -} - - -int -main (void) -{ - mp_int p, q; - char buf[4096]; - int k, li; - clock_t t1; - - srand (time (NULL)); - load_tab(); - - printf ("Enter # of bits: \n"); - fgets (buf, sizeof (buf), stdin); - sscanf (buf, "%d", &k); - - printf ("Enter number of bases to try (1 to 8):\n"); - fgets (buf, sizeof (buf), stdin); - sscanf (buf, "%d", &li); - - - mp_init (&p); - mp_init (&q); - - t1 = clock (); - pprime (k, li, &p, &q); - t1 = clock () - t1; - - printf ("\n\nTook %ld ticks, %d bits\n", t1, mp_count_bits (&p)); - - mp_toradix (&p, buf, 10); - printf ("P == %s\n", buf); - mp_toradix (&q, buf, 10); - printf ("Q == %s\n", buf); - - return 0; -} - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/etc/prime.1024 b/libtommath/etc/prime.1024 deleted file mode 100644 index 5636e2d..0000000 --- a/libtommath/etc/prime.1024 +++ /dev/null @@ -1,414 +0,0 @@ -Enter # of bits: -Enter number of bases to try (1 to 8): -Certificate of primality for: -36360080703173363 - -A == -89963569 - -B == -202082249 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -4851595597739856136987139 - -A == -36360080703173363 - -B == -66715963 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -19550639734462621430325731591027 - -A == -4851595597739856136987139 - -B == -2014867 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -10409036141344317165691858509923818734539 - -A == -19550639734462621430325731591027 - -B == -266207047 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -1049829549988285012736475602118094726647504414203 - -A == -10409036141344317165691858509923818734539 - -B == -50428759 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -77194737385528288387712399596835459931920358844586615003 - -A == -1049829549988285012736475602118094726647504414203 - -B == -36765367 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -35663756695365208574443215955488689578374232732893628896541201763 - -A == -77194737385528288387712399596835459931920358844586615003 - -B == -230998627 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -16711831463502165169495622246023119698415848120292671294127567620396469803 - -A == -35663756695365208574443215955488689578374232732893628896541201763 - -B == -234297127 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -6163534781560285962890718925972249753147470953579266394395432475622345597103528739 - -A == -16711831463502165169495622246023119698415848120292671294127567620396469803 - -B == -184406323 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -814258256205243497704094951432575867360065658372158511036259934640748088306764553488803787 - -A == -6163534781560285962890718925972249753147470953579266394395432475622345597103528739 - -B == -66054487 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -176469695533271657902814176811660357049007467856432383037590673407330246967781451723764079581998187 - -A == -814258256205243497704094951432575867360065658372158511036259934640748088306764553488803787 - -B == -108362239 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -44924492859445516541759485198544012102424796403707253610035148063863073596051272171194806669756971406400419 - -A == -176469695533271657902814176811660357049007467856432383037590673407330246967781451723764079581998187 - -B == -127286707 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -20600996927219343383225424320134474929609459588323857796871086845924186191561749519858600696159932468024710985371059 - -A == -44924492859445516541759485198544012102424796403707253610035148063863073596051272171194806669756971406400419 - -B == -229284691 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -6295696427695493110141186605837397185848992307978456138112526915330347715236378041486547994708748840844217371233735072572979 - -A == -20600996927219343383225424320134474929609459588323857796871086845924186191561749519858600696159932468024710985371059 - -B == -152800771 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -3104984078042317488749073016454213579257792635142218294052134804187631661145261015102617582090263808696699966840735333252107678792123 - -A == -6295696427695493110141186605837397185848992307978456138112526915330347715236378041486547994708748840844217371233735072572979 - -B == -246595759 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -26405175827665701256325699315126705508919255051121452292124404943796947287968603975320562847910946802396632302209435206627913466015741799499 - -A == -3104984078042317488749073016454213579257792635142218294052134804187631661145261015102617582090263808696699966840735333252107678792123 - -B == -4252063 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -11122146237908413610034600609460545703591095894418599759742741406628055069007082998134905595800236452010905900391505454890446585211975124558601770163 - -A == -26405175827665701256325699315126705508919255051121452292124404943796947287968603975320562847910946802396632302209435206627913466015741799499 - -B == -210605419 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -1649861642047798890580354082088712649911849362201343649289384923147797960364736011515757482030049342943790127685185806092659832129486307035500638595572396187 - -A == -11122146237908413610034600609460545703591095894418599759742741406628055069007082998134905595800236452010905900391505454890446585211975124558601770163 - -B == -74170111 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -857983367126266717607389719637086684134462613006415859877666235955788392464081914127715967940968197765042399904117392707518175220864852816390004264107201177394565363 - -A == -1649861642047798890580354082088712649911849362201343649289384923147797960364736011515757482030049342943790127685185806092659832129486307035500638595572396187 - -B == -260016763 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -175995909353623703257072120479340610010337144085688850745292031336724691277374210929188442230237711063783727092685448718515661641054886101716698390145283196296702450566161283 - -A == -857983367126266717607389719637086684134462613006415859877666235955788392464081914127715967940968197765042399904117392707518175220864852816390004264107201177394565363 - -B == -102563707 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -48486002551155667224487059713350447239190772068092630563272168418880661006593537218144160068395218642353495339720640699721703003648144463556291315694787862009052641640656933232794283 - -A == -175995909353623703257072120479340610010337144085688850745292031336724691277374210929188442230237711063783727092685448718515661641054886101716698390145283196296702450566161283 - -B == -137747527 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -13156468011529105025061495011938518171328604045212410096476697450506055664012861932372156505805788068791146986282263016790631108386790291275939575123375304599622623328517354163964228279867403 - -A == -48486002551155667224487059713350447239190772068092630563272168418880661006593537218144160068395218642353495339720640699721703003648144463556291315694787862009052641640656933232794283 - -B == -135672847 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -6355194692790533601105154341731997464407930009404822926832136060319955058388106456084549316415200519472481147942263916585428906582726749131479465958107142228236909665306781538860053107680830113869123 - -A == -13156468011529105025061495011938518171328604045212410096476697450506055664012861932372156505805788068791146986282263016790631108386790291275939575123375304599622623328517354163964228279867403 - -B == -241523587 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -3157116676535430302794438027544146642863331358530722860333745617571010460905857862561870488000265751138954271040017454405707755458702044884023184574412221802502351503929935224995314581932097706874819348858083 - -A == -6355194692790533601105154341731997464407930009404822926832136060319955058388106456084549316415200519472481147942263916585428906582726749131479465958107142228236909665306781538860053107680830113869123 - -B == -248388667 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -390533129219992506725320633489467713907837370444962163378727819939092929448752905310115311180032249230394348337568973177802874166228132778126338883671958897238722734394783244237133367055422297736215754829839364158067 - -A == -3157116676535430302794438027544146642863331358530722860333745617571010460905857862561870488000265751138954271040017454405707755458702044884023184574412221802502351503929935224995314581932097706874819348858083 - -B == -61849651 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -48583654555070224891047847050732516652910250240135992225139515777200432486685999462997073444468380434359929499498804723793106565291183220444221080449740542884172281158126259373095216435009661050109711341419005972852770440739 - -A == -390533129219992506725320633489467713907837370444962163378727819939092929448752905310115311180032249230394348337568973177802874166228132778126338883671958897238722734394783244237133367055422297736215754829839364158067 - -B == -62201707 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -25733035251905120039135866524384525138869748427727001128764704499071378939227862068500633813538831598776578372709963673670934388213622433800015759585470542686333039614931682098922935087822950084908715298627996115185849260703525317419 - -A == -48583654555070224891047847050732516652910250240135992225139515777200432486685999462997073444468380434359929499498804723793106565291183220444221080449740542884172281158126259373095216435009661050109711341419005972852770440739 - -B == -264832231 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -2804594464939948901906623499531073917980499195397462605359913717827014360538186518540781517129548650937632008683280555602633122170458773895504894807182664540529077836857897972175530148107545939211339044386106111633510166695386323426241809387 - -A == -25733035251905120039135866524384525138869748427727001128764704499071378939227862068500633813538831598776578372709963673670934388213622433800015759585470542686333039614931682098922935087822950084908715298627996115185849260703525317419 - -B == -54494047 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -738136612083433720096707308165797114449914259256979340471077690416567237592465306112484843530074782721390528773594351482384711900456440808251196845265132086486672447136822046628407467459921823150600138073268385534588238548865012638209515923513516547 - -A == -2804594464939948901906623499531073917980499195397462605359913717827014360538186518540781517129548650937632008683280555602633122170458773895504894807182664540529077836857897972175530148107545939211339044386106111633510166695386323426241809387 - -B == -131594179 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -392847529056126766528615419937165193421166694172790666626558750047057558168124866940509180171236517681470100877687445134633784815352076138790217228749332398026714192707447855731679485746120589851992221508292976900578299504461333767437280988393026452846013683 - -A == -738136612083433720096707308165797114449914259256979340471077690416567237592465306112484843530074782721390528773594351482384711900456440808251196845265132086486672447136822046628407467459921823150600138073268385534588238548865012638209515923513516547 - -B == -266107603 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -168459393231883505975876919268398655632763956627405508859662408056221544310200546265681845397346956580604208064328814319465940958080244889692368602591598503944015835190587740756859842792554282496742843600573336023639256008687581291233481455395123454655488735304365627 - -A == -392847529056126766528615419937165193421166694172790666626558750047057558168124866940509180171236517681470100877687445134633784815352076138790217228749332398026714192707447855731679485746120589851992221508292976900578299504461333767437280988393026452846013683 - -B == -214408111 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -14865774288636941404884923981945833072113667565310054952177860608355263252462409554658728941191929400198053290113492910272458441655458514080123870132092365833472436407455910185221474386718838138135065780840839893113912689594815485706154461164071775481134379794909690501684643 - -A == -168459393231883505975876919268398655632763956627405508859662408056221544310200546265681845397346956580604208064328814319465940958080244889692368602591598503944015835190587740756859842792554282496742843600573336023639256008687581291233481455395123454655488735304365627 - -B == -44122723 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -1213301773203241614897109856134894783021668292000023984098824423682568173639394290886185366993108292039068940333907505157813934962357206131450244004178619265868614859794316361031904412926604138893775068853175215502104744339658944443630407632290152772487455298652998368296998719996019 - -A == -14865774288636941404884923981945833072113667565310054952177860608355263252462409554658728941191929400198053290113492910272458441655458514080123870132092365833472436407455910185221474386718838138135065780840839893113912689594815485706154461164071775481134379794909690501684643 - -B == -40808563 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -186935245989515158127969129347464851990429060640910951266513740972248428651109062997368144722015290092846666943896556191257222521203647606911446635194198213436423080005867489516421559330500722264446765608763224572386410155413161172707802334865729654109050873820610813855041667633843601286843 - -A == -1213301773203241614897109856134894783021668292000023984098824423682568173639394290886185366993108292039068940333907505157813934962357206131450244004178619265868614859794316361031904412926604138893775068853175215502104744339658944443630407632290152772487455298652998368296998719996019 - -B == -77035759 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -83142661079751490510739960019112406284111408348732592580459037404394946037094409915127399165633756159385609671956087845517678367844901424617866988187132480585966721962585586730693443536100138246516868613250009028187662080828012497191775172228832247706080044971423654632146928165751885302331924491683 - -A == -186935245989515158127969129347464851990429060640910951266513740972248428651109062997368144722015290092846666943896556191257222521203647606911446635194198213436423080005867489516421559330500722264446765608763224572386410155413161172707802334865729654109050873820610813855041667633843601286843 - -B == -222383587 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -3892354773803809855317742245039794448230625839512638747643814927766738642436392673485997449586432241626440927010641564064764336402368634186618250134234189066179771240232458249806850838490410473462391401438160528157981942499581634732706904411807195259620779379274017704050790865030808501633772117217899534443 - -A == -83142661079751490510739960019112406284111408348732592580459037404394946037094409915127399165633756159385609671956087845517678367844901424617866988187132480585966721962585586730693443536100138246516868613250009028187662080828012497191775172228832247706080044971423654632146928165751885302331924491683 - -B == -23407687 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -1663606652988091811284014366560171522582683318514519379924950390627250155440313691226744227787921928894551755219495501365555370027257568506349958010457682898612082048959464465369892842603765280317696116552850664773291371490339084156052244256635115997453399761029567033971998617303988376172539172702246575225837054723 - -A == -3892354773803809855317742245039794448230625839512638747643814927766738642436392673485997449586432241626440927010641564064764336402368634186618250134234189066179771240232458249806850838490410473462391401438160528157981942499581634732706904411807195259620779379274017704050790865030808501633772117217899534443 - -B == -213701827 - -G == 2 ----------------------------------------------------------------- - - -Took 33057 ticks, 1048 bits -P == 1663606652988091811284014366560171522582683318514519379924950390627250155440313691226744227787921928894551755219495501365555370027257568506349958010457682898612082048959464465369892842603765280317696116552850664773291371490339084156052244256635115997453399761029567033971998617303988376172539172702246575225837054723 -Q == 3892354773803809855317742245039794448230625839512638747643814927766738642436392673485997449586432241626440927010641564064764336402368634186618250134234189066179771240232458249806850838490410473462391401438160528157981942499581634732706904411807195259620779379274017704050790865030808501633772117217899534443 diff --git a/libtommath/etc/prime.512 b/libtommath/etc/prime.512 deleted file mode 100644 index cb6ec30..0000000 --- a/libtommath/etc/prime.512 +++ /dev/null @@ -1,205 +0,0 @@ -Enter # of bits: -Enter number of bases to try (1 to 8): -Certificate of primality for: -85933926807634727 - -A == -253758023 - -B == -169322581 - -G == 5 ----------------------------------------------------------------- -Certificate of primality for: -23930198825086241462113799 - -A == -85933926807634727 - -B == -139236037 - -G == 11 ----------------------------------------------------------------- -Certificate of primality for: -6401844647261612602378676572510019 - -A == -23930198825086241462113799 - -B == -133760791 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -269731366027728777712034888684015329354259 - -A == -6401844647261612602378676572510019 - -B == -21066691 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -37942338209025571690075025099189467992329684223707 - -A == -269731366027728777712034888684015329354259 - -B == -70333567 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -15306904714258982484473490774101705363308327436988160248323 - -A == -37942338209025571690075025099189467992329684223707 - -B == -201712723 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -1616744757018513392810355191503853040357155275733333124624513530099 - -A == -15306904714258982484473490774101705363308327436988160248323 - -B == -52810963 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -464222094814208047161771036072622485188658077940154689939306386289983787983 - -A == -1616744757018513392810355191503853040357155275733333124624513530099 - -B == -143566909 - -G == 5 ----------------------------------------------------------------- -Certificate of primality for: -187429931674053784626487560729643601208757374994177258429930699354770049369025096447 - -A == -464222094814208047161771036072622485188658077940154689939306386289983787983 - -B == -201875281 - -G == 5 ----------------------------------------------------------------- -Certificate of primality for: -100579220846502621074093727119851331775052664444339632682598589456666938521976625305832917563 - -A == -187429931674053784626487560729643601208757374994177258429930699354770049369025096447 - -B == -268311523 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -1173616081309758475197022137833792133815753368965945885089720153370737965497134878651384030219765163 - -A == -100579220846502621074093727119851331775052664444339632682598589456666938521976625305832917563 - -B == -5834287 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -191456913489905913185935197655672585713573070349044195411728114905691721186574907738081340754373032735283623 - -A == -1173616081309758475197022137833792133815753368965945885089720153370737965497134878651384030219765163 - -B == -81567097 - -G == 5 ----------------------------------------------------------------- -Certificate of primality for: -57856530489201750164178576399448868489243874083056587683743345599898489554401618943240901541005080049321706789987519 - -A == -191456913489905913185935197655672585713573070349044195411728114905691721186574907738081340754373032735283623 - -B == -151095433 - -G == 7 ----------------------------------------------------------------- -Certificate of primality for: -13790529750452576698109671710773784949185621244122040804792403407272729038377767162233653248852099545134831722512085881814803 - -A == -57856530489201750164178576399448868489243874083056587683743345599898489554401618943240901541005080049321706789987519 - -B == -119178679 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -7075985989000817742677547821106534174334812111605018857703825637170140040509067704269696198231266351631132464035671858077052876058979 - -A == -13790529750452576698109671710773784949185621244122040804792403407272729038377767162233653248852099545134831722512085881814803 - -B == -256552363 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -1227273006232588072907488910282307435921226646895131225407452056677899411162892829564455154080310937471747140942360789623819327234258162420463 - -A == -7075985989000817742677547821106534174334812111605018857703825637170140040509067704269696198231266351631132464035671858077052876058979 - -B == -86720989 - -G == 5 ----------------------------------------------------------------- -Certificate of primality for: -446764896913554613686067036908702877942872355053329937790398156069936255759889884246832779737114032666318220500106499161852193765380831330106375235763 - -A == -1227273006232588072907488910282307435921226646895131225407452056677899411162892829564455154080310937471747140942360789623819327234258162420463 - -B == -182015287 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -5290203010849586596974953717018896543907195901082056939587768479377028575911127944611236020459652034082251335583308070846379514569838984811187823420951275243 - -A == -446764896913554613686067036908702877942872355053329937790398156069936255759889884246832779737114032666318220500106499161852193765380831330106375235763 - -B == -5920567 - -G == 2 ----------------------------------------------------------------- - - -Took 3454 ticks, 521 bits -P == 5290203010849586596974953717018896543907195901082056939587768479377028575911127944611236020459652034082251335583308070846379514569838984811187823420951275243 -Q == 446764896913554613686067036908702877942872355053329937790398156069936255759889884246832779737114032666318220500106499161852193765380831330106375235763 diff --git a/libtommath/etc/timer.asm b/libtommath/etc/timer.asm deleted file mode 100644 index 35890d9..0000000 --- a/libtommath/etc/timer.asm +++ /dev/null @@ -1,37 +0,0 @@ -; x86 timer in NASM
-;
-; Tom St Denis, tomstdenis@iahu.ca
-[bits 32]
-[section .data]
-time dd 0, 0
-
-[section .text]
-
-%ifdef USE_ELF
-[global t_start]
-t_start:
-%else
-[global _t_start]
-_t_start:
-%endif
- push edx
- push eax
- rdtsc
- mov [time+0],edx
- mov [time+4],eax
- pop eax
- pop edx
- ret
-
-%ifdef USE_ELF
-[global t_read]
-t_read:
-%else
-[global _t_read]
-_t_read:
-%endif
- rdtsc
- sub eax,[time+4]
- sbb edx,[time+0]
- ret
-
\ No newline at end of file diff --git a/libtommath/etc/tune.c b/libtommath/etc/tune.c deleted file mode 100644 index a3f1c47..0000000 --- a/libtommath/etc/tune.c +++ /dev/null @@ -1,146 +0,0 @@ -/* Tune the Karatsuba parameters - * - * Tom St Denis, tstdenis82@gmail.com - */ -#include <tommath.h> -#include <time.h> -#include <stdint.h> - -/* how many times todo each size mult. Depends on your computer. For slow computers - * this can be low like 5 or 10. For fast [re: Athlon] should be 25 - 50 or so - */ -#define TIMES (1UL<<14UL) - -#ifndef X86_TIMER - -/* RDTSC from Scott Duplichan */ -static uint64_t TIMFUNC (void) - { - #if defined __GNUC__ - #if defined(__i386__) || defined(__x86_64__) - /* version from http://www.mcs.anl.gov/~kazutomo/rdtsc.html - * the old code always got a warning issued by gcc, clang did not complain... - */ - unsigned hi, lo; - __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); - return ((uint64_t)lo)|( ((uint64_t)hi)<<32); - #else /* gcc-IA64 version */ - unsigned long result; - __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory"); - while (__builtin_expect ((int) result == -1, 0)) - __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory"); - return result; - #endif - - // Microsoft and Intel Windows compilers - #elif defined _M_IX86 - __asm rdtsc - #elif defined _M_AMD64 - return __rdtsc (); - #elif defined _M_IA64 - #if defined __INTEL_COMPILER - #include <ia64intrin.h> - #endif - return __getReg (3116); - #else - #error need rdtsc function for this build - #endif - } - - -/* generic ISO C timer */ -uint64_t LBL_T; -void t_start(void) { LBL_T = TIMFUNC(); } -uint64_t t_read(void) { return TIMFUNC() - LBL_T; } - -#else -extern void t_start(void); -extern uint64_t t_read(void); -#endif - -uint64_t time_mult(int size, int s) -{ - unsigned long x; - mp_int a, b, c; - uint64_t t1; - - mp_init (&a); - mp_init (&b); - mp_init (&c); - - mp_rand (&a, size); - mp_rand (&b, size); - - if (s == 1) { - KARATSUBA_MUL_CUTOFF = size; - } else { - KARATSUBA_MUL_CUTOFF = 100000; - } - - t_start(); - for (x = 0; x < TIMES; x++) { - mp_mul(&a,&b,&c); - } - t1 = t_read(); - mp_clear (&a); - mp_clear (&b); - mp_clear (&c); - return t1; -} - -uint64_t time_sqr(int size, int s) -{ - unsigned long x; - mp_int a, b; - uint64_t t1; - - mp_init (&a); - mp_init (&b); - - mp_rand (&a, size); - - if (s == 1) { - KARATSUBA_SQR_CUTOFF = size; - } else { - KARATSUBA_SQR_CUTOFF = 100000; - } - - t_start(); - for (x = 0; x < TIMES; x++) { - mp_sqr(&a,&b); - } - t1 = t_read(); - mp_clear (&a); - mp_clear (&b); - return t1; -} - -int -main (void) -{ - uint64_t t1, t2; - int x, y; - - for (x = 8; ; x += 2) { - t1 = time_mult(x, 0); - t2 = time_mult(x, 1); - printf("%d: %9llu %9llu, %9llu\n", x, t1, t2, t2 - t1); - if (t2 < t1) break; - } - y = x; - - for (x = 8; ; x += 2) { - t1 = time_sqr(x, 0); - t2 = time_sqr(x, 1); - printf("%d: %9llu %9llu, %9llu\n", x, t1, t2, t2 - t1); - if (t2 < t1) break; - } - printf("KARATSUBA_MUL_CUTOFF = %d\n", y); - printf("KARATSUBA_SQR_CUTOFF = %d\n", x); - - return 0; -} - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/filter.pl b/libtommath/filter.pl deleted file mode 100755 index ad980e5..0000000 --- a/libtommath/filter.pl +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/perl - -# we want to filter every between START_INS and END_INS out and then insert crap from another file (this is fun) - -use strict; -use warnings; - -open(my $src, '<', shift); -open(my $ins, '<', shift); -open(my $tmp, '>', 'tmp.delme'); - -my $l = 0; -while (<$src>) { - if ($_ =~ /START_INS/) { - print {$tmp} $_; - $l = 1; - while (<$ins>) { - print {$tmp} $_; - } - close $ins; - } elsif ($_ =~ /END_INS/) { - print {$tmp} $_; - $l = 0; - } elsif ($l == 0) { - print {$tmp} $_; - } -} - -close $tmp; -close $src; - -# ref: $Format:%D$ -# git commit: $Format:%H$ -# commit time: $Format:%ai$ diff --git a/libtommath/genlist.sh b/libtommath/genlist.sh deleted file mode 100755 index 22048cc..0000000 --- a/libtommath/genlist.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -export a=`find . -maxdepth 1 -type f -name '*.c' | sort | sed -e 'sE\./EE' | sed -e 's/\.c/\.o/' | xargs` -perl ./parsenames.pl OBJECTS "$a" - -# ref: $Format:%D$ -# git commit: $Format:%H$ -# commit time: $Format:%ai$ diff --git a/libtommath/helper.pl b/libtommath/helper.pl new file mode 100755 index 0000000..2f06165 --- /dev/null +++ b/libtommath/helper.pl @@ -0,0 +1,469 @@ +#!/usr/bin/env perl + +use strict; +use warnings; + +use Getopt::Long; +use File::Find 'find'; +use File::Basename 'basename'; +use File::Glob 'bsd_glob'; + +sub read_file { + my $f = shift; + open my $fh, "<", $f or die "FATAL: read_rawfile() cannot open file '$f': $!"; + binmode $fh; + return do { local $/; <$fh> }; +} + +sub write_file { + my ($f, $data) = @_; + die "FATAL: write_file() no data" unless defined $data; + open my $fh, ">", $f or die "FATAL: write_file() cannot open file '$f': $!"; + binmode $fh; + print $fh $data or die "FATAL: write_file() cannot write to '$f': $!"; + close $fh or die "FATAL: write_file() cannot close '$f': $!"; + return; +} + +sub sanitize_comments { + my($content) = @_; + $content =~ s{/\*(.*?)\*/}{my $x=$1; $x =~ s/\w/x/g; "/*$x*/";}egs; + return $content; +} + +sub check_source { + my @all_files = ( + bsd_glob("Makefile*"), + bsd_glob("*.{h,c,sh,pl}"), + bsd_glob("*/*.{h,c,sh,pl}"), + ); + + my $fails = 0; + for my $file (sort @all_files) { + my $troubles = {}; + my $lineno = 1; + my $content = read_file($file); + $content = sanitize_comments $content; + push @{$troubles->{crlf_line_end}}, '?' if $content =~ /\r/; + for my $l (split /\n/, $content) { + push @{$troubles->{merge_conflict}}, $lineno if $l =~ /^(<<<<<<<|=======|>>>>>>>)([^<=>]|$)/; + push @{$troubles->{trailing_space}}, $lineno if $l =~ / $/; + push @{$troubles->{tab}}, $lineno if $l =~ /\t/ && basename($file) !~ /^makefile/i; + push @{$troubles->{non_ascii_char}}, $lineno if $l =~ /[^[:ascii:]]/; + push @{$troubles->{cpp_comment}}, $lineno if $file =~ /\.(c|h)$/ && ($l =~ /\s\/\// || $l =~ /\/\/\s/); + # we prefer using XMALLOC, XFREE, XREALLOC, XCALLOC ... + push @{$troubles->{unwanted_malloc}}, $lineno if $file =~ /^[^\/]+\.c$/ && $l =~ /\bmalloc\s*\(/; + push @{$troubles->{unwanted_realloc}}, $lineno if $file =~ /^[^\/]+\.c$/ && $l =~ /\brealloc\s*\(/; + push @{$troubles->{unwanted_calloc}}, $lineno if $file =~ /^[^\/]+\.c$/ && $l =~ /\bcalloc\s*\(/; + push @{$troubles->{unwanted_free}}, $lineno if $file =~ /^[^\/]+\.c$/ && $l =~ /\bfree\s*\(/; + # and we probably want to also avoid the following + push @{$troubles->{unwanted_memcpy}}, $lineno if $file =~ /^[^\/]+\.c$/ && $l =~ /\bmemcpy\s*\(/; + push @{$troubles->{unwanted_memset}}, $lineno if $file =~ /^[^\/]+\.c$/ && $l =~ /\bmemset\s*\(/; + push @{$troubles->{unwanted_memcpy}}, $lineno if $file =~ /^[^\/]+\.c$/ && $l =~ /\bmemcpy\s*\(/; + push @{$troubles->{unwanted_memmove}}, $lineno if $file =~ /^[^\/]+\.c$/ && $l =~ /\bmemmove\s*\(/; + push @{$troubles->{unwanted_memcmp}}, $lineno if $file =~ /^[^\/]+\.c$/ && $l =~ /\bmemcmp\s*\(/; + push @{$troubles->{unwanted_strcmp}}, $lineno if $file =~ /^[^\/]+\.c$/ && $l =~ /\bstrcmp\s*\(/; + push @{$troubles->{unwanted_strcpy}}, $lineno if $file =~ /^[^\/]+\.c$/ && $l =~ /\bstrcpy\s*\(/; + push @{$troubles->{unwanted_strncpy}}, $lineno if $file =~ /^[^\/]+\.c$/ && $l =~ /\bstrncpy\s*\(/; + push @{$troubles->{unwanted_clock}}, $lineno if $file =~ /^[^\/]+\.c$/ && $l =~ /\bclock\s*\(/; + push @{$troubles->{unwanted_qsort}}, $lineno if $file =~ /^[^\/]+\.c$/ && $l =~ /\bqsort\s*\(/; + push @{$troubles->{sizeof_no_brackets}}, $lineno if $file =~ /^[^\/]+\.c$/ && $l =~ /\bsizeof\s*[^\(]/; + if ($file =~ m|^[^\/]+\.c$| && $l =~ /^static(\s+[a-zA-Z0-9_]+)+\s+([a-zA-Z0-9_]+)\s*\(/) { + my $funcname = $2; + # static functions should start with s_ + push @{$troubles->{staticfunc_name}}, "$lineno($funcname)" if $funcname !~ /^s_/; + } + $lineno++; + } + for my $k (sort keys %$troubles) { + warn "[$k] $file line:" . join(",", @{$troubles->{$k}}) . "\n"; + $fails++; + } + } + + warn( $fails > 0 ? "check-source: FAIL $fails\n" : "check-source: PASS\n" ); + return $fails; +} + +sub check_comments { + my $fails = 0; + my $first_comment = <<'MARKER'; +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +MARKER + #my @all_files = (bsd_glob("*.{h,c}"), bsd_glob("*/*.{h,c}")); + my @all_files = (bsd_glob("*.{h,c}")); + for my $f (@all_files) { + my $txt = read_file($f); + if ($txt !~ /\Q$first_comment\E/s) { + warn "[first_comment] $f\n"; + $fails++; + } + } + warn( $fails > 0 ? "check-comments: FAIL $fails\n" : "check-comments: PASS\n" ); + return $fails; +} + +sub check_doc { + my $fails = 0; + my $tex = read_file('doc/bn.tex'); + my $tmh = read_file('tommath.h'); + my @functions = $tmh =~ /\n\s*[a-zA-Z0-9_* ]+?(mp_[a-z0-9_]+)\s*\([^\)]+\)\s*;/sg; + my @macros = $tmh =~ /\n\s*#define\s+([a-z0-9_]+)\s*\([^\)]+\)/sg; + for my $n (sort @functions) { + (my $nn = $n) =~ s/_/\\_/g; # mp_sub_d >> mp\_sub\_d + if ($tex !~ /index\Q{$nn}\E/) { + warn "[missing_doc_for_function] $n\n"; + $fails++ + } + } + for my $n (sort @macros) { + (my $nn = $n) =~ s/_/\\_/g; # mp_iszero >> mp\_iszero + if ($tex !~ /index\Q{$nn}\E/) { + warn "[missing_doc_for_macro] $n\n"; + $fails++ + } + } + warn( $fails > 0 ? "check_doc: FAIL $fails\n" : "check-doc: PASS\n" ); + return $fails; +} + +sub prepare_variable { + my ($varname, @list) = @_; + my $output = "$varname="; + my $len = length($output); + foreach my $obj (sort @list) { + $len = $len + length $obj; + $obj =~ s/\*/\$/; + if ($len > 100) { + $output .= "\\\n"; + $len = length $obj; + } + $output .= $obj . ' '; + } + $output =~ s/ $//; + return $output; +} + +sub prepare_msvc_files_xml { + my ($all, $exclude_re, $targets) = @_; + my $last = []; + my $depth = 2; + + # sort files in the same order as visual studio (ugly, I know) + my @parts = (); + for my $orig (@$all) { + my $p = $orig; + $p =~ s|/|/~|g; + $p =~ s|/~([^/]+)$|/$1|g; + my @l = map { sprintf "% -99s", $_ } split /\//, $p; + push @parts, [ $orig, join(':', @l) ]; + } + my @sorted = map { $_->[0] } sort { $a->[1] cmp $b->[1] } @parts; + + my $files = "<Files>\r\n"; + for my $full (@sorted) { + my @items = split /\//, $full; # split by '/' + $full =~ s|/|\\|g; # replace '/' bt '\' + shift @items; # drop first one (src) + pop @items; # drop last one (filename.ext) + my $current = \@items; + if (join(':', @$current) ne join(':', @$last)) { + my $common = 0; + $common++ while ($last->[$common] && $current->[$common] && $last->[$common] eq $current->[$common]); + my $back = @$last - $common; + if ($back > 0) { + $files .= ("\t" x --$depth) . "</Filter>\r\n" for (1..$back); + } + my $fwd = [ @$current ]; splice(@$fwd, 0, $common); + for my $i (0..scalar(@$fwd) - 1) { + $files .= ("\t" x $depth) . "<Filter\r\n"; + $files .= ("\t" x $depth) . "\tName=\"$fwd->[$i]\"\r\n"; + $files .= ("\t" x $depth) . "\t>\r\n"; + $depth++; + } + $last = $current; + } + $files .= ("\t" x $depth) . "<File\r\n"; + $files .= ("\t" x $depth) . "\tRelativePath=\"$full\"\r\n"; + $files .= ("\t" x $depth) . "\t>\r\n"; + if ($full =~ $exclude_re) { + for (@$targets) { + $files .= ("\t" x $depth) . "\t<FileConfiguration\r\n"; + $files .= ("\t" x $depth) . "\t\tName=\"$_\"\r\n"; + $files .= ("\t" x $depth) . "\t\tExcludedFromBuild=\"true\"\r\n"; + $files .= ("\t" x $depth) . "\t\t>\r\n"; + $files .= ("\t" x $depth) . "\t\t<Tool\r\n"; + $files .= ("\t" x $depth) . "\t\t\tName=\"VCCLCompilerTool\"\r\n"; + $files .= ("\t" x $depth) . "\t\t\tAdditionalIncludeDirectories=\"\"\r\n"; + $files .= ("\t" x $depth) . "\t\t\tPreprocessorDefinitions=\"\"\r\n"; + $files .= ("\t" x $depth) . "\t\t/>\r\n"; + $files .= ("\t" x $depth) . "\t</FileConfiguration>\r\n"; + } + } + $files .= ("\t" x $depth) . "</File>\r\n"; + } + $files .= ("\t" x --$depth) . "</Filter>\r\n" for (@$last); + $files .= "\t</Files>"; + return $files; +} + +sub patch_file { + my ($content, @variables) = @_; + for my $v (@variables) { + if ($v =~ /^([A-Z0-9_]+)\s*=.*$/si) { + my $name = $1; + $content =~ s/\n\Q$name\E\b.*?[^\\]\n/\n$v\n/s; + } + else { + die "patch_file failed: " . substr($v, 0, 30) . ".."; + } + } + return $content; +} + +sub process_makefiles { + my $write = shift; + my $changed_count = 0; + my @o = map { my $x = $_; $x =~ s/\.c$/.o/; $x } bsd_glob("*.c"); + my @all = bsd_glob("*.{c,h}"); + + my $var_o = prepare_variable("OBJECTS", @o); + (my $var_obj = $var_o) =~ s/\.o\b/.obj/sg; + + # update OBJECTS + HEADERS in makefile* + for my $m (qw/ Makefile.in /) { + my $old = read_file($m); + my $new = $m eq 'makefile.msvc' ? patch_file($old, $var_obj) + : patch_file($old, $var_o); + if ($old ne $new) { + write_file($m, $new) if $write; + warn "changed: $m\n"; + $changed_count++; + } + } + + if ($write) { + return 0; # no failures + } + else { + warn( $changed_count > 0 ? "check-makefiles: FAIL $changed_count\n" : "check-makefiles: PASS\n" ); + return $changed_count; + } +} + +sub draw_func +{ + my ($deplist, $depmap, $out, $indent, $funcslist) = @_; + my @funcs = split ',', $funcslist; + # try this if you want to have a look at a minimized version of the callgraph without all the trivial functions + #if ($deplist =~ /$funcs[0]/ || $funcs[0] =~ /BN_MP_(ADD|SUB|CLEAR|CLEAR_\S+|DIV|MUL|COPY|ZERO|GROW|CLAMP|INIT|INIT_\S+|SET|ABS|CMP|CMP_D|EXCH)_C/) { + if ($deplist =~ /$funcs[0]/) { + return $deplist; + } else { + $deplist = $deplist . $funcs[0]; + } + if ($indent == 0) { + } elsif ($indent >= 1) { + print {$out} '| ' x ($indent - 1) . '+--->'; + } + print {$out} $funcs[0] . "\n"; + shift @funcs; + my $olddeplist = $deplist; + foreach my $i (@funcs) { + $deplist = draw_func($deplist, $depmap, $out, $indent + 1, ${$depmap}{$i}) if exists ${$depmap}{$i}; + } + return $olddeplist; +} + +sub update_dep +{ + #open class file and write preamble + open(my $class, '>', 'tommath_class.h') or die "Couldn't open tommath_class.h for writing\n"; + print {$class} << 'EOS'; +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +#if !(defined(LTM1) && defined(LTM2) && defined(LTM3)) +#define LTM_INSIDE +#if defined(LTM2) +# define LTM3 +#endif +#if defined(LTM1) +# define LTM2 +#endif +#define LTM1 +#if defined(LTM_ALL) +EOS + + foreach my $filename (glob 'bn*.c') { + my $define = $filename; + + print "Processing $filename\n"; + + # convert filename to upper case so we can use it as a define + $define =~ tr/[a-z]/[A-Z]/; + $define =~ tr/\./_/; + print {$class} "# define $define\n"; + + # now copy text and apply #ifdef as required + my $apply = 0; + open(my $src, '<', $filename); + open(my $out, '>', 'tmp'); + + # first line will be the #ifdef + my $line = <$src>; + if ($line =~ /include/) { + print {$out} $line; + } else { + print {$out} << "EOS"; +#include "tommath_private.h" +#ifdef $define +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +$line +EOS + $apply = 1; + } + while (<$src>) { + if ($_ !~ /tommath\.h/) { + print {$out} $_; + } + } + if ($apply == 1) { + print {$out} "#endif\n"; + } + close $src; + close $out; + + unlink $filename; + rename 'tmp', $filename; + } + print {$class} "#endif\n#endif\n"; + + # now do classes + my %depmap; + foreach my $filename (glob 'bn*.c') { + my $content; + if ($filename =~ "bn_deprecated.c") { + open(my $src, '<', $filename) or die "Can't open source file!\n"; + read $src, $content, -s $src; + close $src; + } else { + my $cc = $ENV{'CC'} || 'gcc'; + $content = `$cc -E -x c -DLTM_ALL $filename`; + $content =~ s/^# 1 "$filename".*?^# 2 "$filename"//ms; + } + + # convert filename to upper case so we can use it as a define + $filename =~ tr/[a-z]/[A-Z]/; + $filename =~ tr/\./_/; + + print {$class} "#if defined($filename)\n"; + my $list = $filename; + + # strip comments + $content =~ s{/\*.*?\*/}{}gs; + + # scan for mp_* and make classes + my @deps = (); + foreach my $line (split /\n/, $content) { + while ($line =~ /(fast_)?(s_)?mp\_[a-z_0-9]*((?=\;)|(?=\())|(?<=\()mp\_[a-z_0-9]*(?=\()/g) { + my $a = $&; + next if $a eq "mp_err"; + $a =~ tr/[a-z]/[A-Z]/; + $a = 'BN_' . $a . '_C'; + push @deps, $a; + } + } + @deps = sort(@deps); + foreach my $a (@deps) { + if ($list !~ /$a/) { + print {$class} "# define $a\n"; + } + $list = $list . ',' . $a; + } + $depmap{$filename} = $list; + + print {$class} "#endif\n\n"; + } + + print {$class} << 'EOS'; +#ifdef LTM_INSIDE +#undef LTM_INSIDE +#ifdef LTM3 +# define LTM_LAST +#endif + +#include "tommath_superclass.h" +#include "tommath_class.h" +#else +# define LTM_LAST +#endif +EOS + close $class; + + #now let's make a cool call graph... + + open(my $out, '>', 'callgraph.txt'); + foreach (sort keys %depmap) { + draw_func("", \%depmap, $out, 0, $depmap{$_}); + print {$out} "\n\n"; + } + close $out; + + return 0; +} + +sub generate_def { + my @files = split /\n/, `git ls-files`; + @files = grep(/\.c/, @files); + @files = map { my $x = $_; $x =~ s/^bn_|\.c$//g; $x; } @files; + @files = grep(!/mp_radix_smap/, @files); + + push(@files, qw(mp_set_int mp_set_long mp_set_long_long mp_get_int mp_get_long mp_get_long_long mp_init_set_int)); + + my $files = join("\n ", sort(grep(/^mp_/, @files))); + write_file "tommath.def", "; libtommath +; +; Use this command to produce a 32-bit .lib file, for use in any MSVC version +; lib -machine:X86 -name:libtommath.dll -def:tommath.def -out:tommath.lib +; Use this command to produce a 64-bit .lib file, for use in any MSVC version +; lib -machine:X64 -name:libtommath.dll -def:tommath.def -out:tommath.lib +; +EXPORTS + $files +"; + return 0; +} + +sub die_usage { + die <<"MARKER"; +usage: $0 -s OR $0 --check-source + $0 -o OR $0 --check-comments + $0 -m OR $0 --check-makefiles + $0 -a OR $0 --check-all + $0 -u OR $0 --update-files +MARKER +} + +GetOptions( "s|check-source" => \my $check_source, + "o|check-comments" => \my $check_comments, + "m|check-makefiles" => \my $check_makefiles, + "d|check-doc" => \my $check_doc, + "a|check-all" => \my $check_all, + "u|update-files" => \my $update_files, + "h|help" => \my $help + ) or die_usage; + +my $failure; +$failure ||= check_source() if $check_all || $check_source; +$failure ||= check_comments() if $check_all || $check_comments; +$failure ||= check_doc() if $check_doc; # temporarily excluded from --check-all +$failure ||= process_makefiles(0) if $check_all || $check_makefiles; +$failure ||= process_makefiles(1) if $update_files; +$failure ||= update_dep() if $update_files; +$failure ||= generate_def() if $update_files; + +die_usage unless defined $failure; +exit $failure ? 1 : 0; diff --git a/libtommath/logs/README b/libtommath/logs/README deleted file mode 100644 index ea20c81..0000000 --- a/libtommath/logs/README +++ /dev/null @@ -1,13 +0,0 @@ -To use the pretty graphs you have to first build/run the ltmtest from the root directory of the package.
-Todo this type
-
-make timing ; ltmtest
-
-in the root. It will run for a while [about ten minutes on most PCs] and produce a series of .log files in logs/.
-
-After doing that run "gnuplot graphs.dem" to make the PNGs. If you managed todo that all so far just open index.html to view
-them all :-)
-
-Have fun
-
-Tom
\ No newline at end of file diff --git a/libtommath/logs/add.log b/libtommath/logs/add.log deleted file mode 100644 index 43503ac..0000000 --- a/libtommath/logs/add.log +++ /dev/null @@ -1,16 +0,0 @@ -480 87 -960 111 -1440 135 -1920 159 -2400 200 -2880 224 -3360 248 -3840 272 -4320 296 -4800 320 -5280 344 -5760 368 -6240 392 -6720 416 -7200 440 -7680 464 diff --git a/libtommath/logs/addsub.png b/libtommath/logs/addsub.png Binary files differdeleted file mode 100644 index a5679ac..0000000 --- a/libtommath/logs/addsub.png +++ /dev/null diff --git a/libtommath/logs/expt.log b/libtommath/logs/expt.log deleted file mode 100644 index 70932ab..0000000 --- a/libtommath/logs/expt.log +++ /dev/null @@ -1,7 +0,0 @@ -513 1435869 -769 3544970 -1025 7791638 -2049 46902238 -2561 85334899 -3073 141451412 -4097 308770310 diff --git a/libtommath/logs/expt.png b/libtommath/logs/expt.png Binary files differdeleted file mode 100644 index 9ee8bb7..0000000 --- a/libtommath/logs/expt.png +++ /dev/null diff --git a/libtommath/logs/expt_2k.log b/libtommath/logs/expt_2k.log deleted file mode 100644 index 97d325f..0000000 --- a/libtommath/logs/expt_2k.log +++ /dev/null @@ -1,5 +0,0 @@ -607 2109225 -1279 10148314 -2203 34126877 -3217 82716424 -4253 161569606 diff --git a/libtommath/logs/expt_2kl.log b/libtommath/logs/expt_2kl.log deleted file mode 100644 index d9ad4be..0000000 --- a/libtommath/logs/expt_2kl.log +++ /dev/null @@ -1,4 +0,0 @@ -1024 7705271 -2048 34286851 -4096 165207491 -521 1618631 diff --git a/libtommath/logs/expt_dr.log b/libtommath/logs/expt_dr.log deleted file mode 100644 index c6bbe07..0000000 --- a/libtommath/logs/expt_dr.log +++ /dev/null @@ -1,7 +0,0 @@ -532 1928550 -784 3763908 -1036 7564221 -1540 16566059 -2072 32283784 -3080 79851565 -4116 157843530 diff --git a/libtommath/logs/graphs.dem b/libtommath/logs/graphs.dem deleted file mode 100644 index dfaf613..0000000 --- a/libtommath/logs/graphs.dem +++ /dev/null @@ -1,17 +0,0 @@ -set terminal png -set size 1.75 -set ylabel "Cycles per Operation" -set xlabel "Operand size (bits)" - -set output "addsub.png" -plot 'add.log' smooth bezier title "Addition", 'sub.log' smooth bezier title "Subtraction" - -set output "mult.png" -plot 'sqr.log' smooth bezier title "Squaring (without Karatsuba)", 'sqr_kara.log' smooth bezier title "Squaring (Karatsuba)", 'mult.log' smooth bezier title "Multiplication (without Karatsuba)", 'mult_kara.log' smooth bezier title "Multiplication (Karatsuba)" - -set output "expt.png" -plot 'expt.log' smooth bezier title "Exptmod (Montgomery)", 'expt_dr.log' smooth bezier title "Exptmod (Dimminished Radix)", 'expt_2k.log' smooth bezier title "Exptmod (2k Reduction)" - -set output "invmod.png" -plot 'invmod.log' smooth bezier title "Modular Inverse" - diff --git a/libtommath/logs/index.html b/libtommath/logs/index.html deleted file mode 100644 index 4b68c25..0000000 --- a/libtommath/logs/index.html +++ /dev/null @@ -1,27 +0,0 @@ -<html> -<head> -<title>LibTomMath Log Plots</title> -</head> -<body> - -<h1>Addition and Subtraction</h1> -<center><img src=addsub.png></center> -<hr> - -<h1>Multipliers</h1> -<center><img src=mult.png></center> -<hr> - -<h1>Exptmod</h1> -<center><img src=expt.png></center> -<hr> - -<h1>Modular Inverse</h1> -<center><img src=invmod.png></center> -<hr> - -</body> -</html> -/* $Source: /cvs/libtom/libtommath/logs/index.html,v $ */ -/* $Revision: 1.2 $ */ -/* $Date: 2005/05/05 14:38:47 $ */ diff --git a/libtommath/logs/invmod.log b/libtommath/logs/invmod.log deleted file mode 100644 index e69de29..0000000 --- a/libtommath/logs/invmod.log +++ /dev/null diff --git a/libtommath/logs/invmod.png b/libtommath/logs/invmod.png Binary files differdeleted file mode 100644 index 0a8a4ad..0000000 --- a/libtommath/logs/invmod.png +++ /dev/null diff --git a/libtommath/logs/mult.log b/libtommath/logs/mult.log deleted file mode 100644 index 33563fc..0000000 --- a/libtommath/logs/mult.log +++ /dev/null @@ -1,84 +0,0 @@ -271 555 -390 855 -508 1161 -631 1605 -749 2117 -871 2687 -991 3329 -1108 4084 -1231 4786 -1351 5624 -1470 6392 -1586 7364 -1710 8218 -1830 9255 -1951 10217 -2067 11461 -2191 12463 -2308 13677 -2430 14800 -2551 16232 -2671 17460 -2791 18899 -2902 20247 -3028 21902 -3151 23240 -3267 24927 -3391 26441 -3511 28277 -3631 29838 -3749 31751 -3869 33673 -3989 35431 -4111 37518 -4231 39426 -4349 41504 -4471 43567 -4591 45786 -4711 47876 -4831 50299 -4951 52427 -5071 54785 -5189 57241 -5307 59730 -5431 62194 -5551 64761 -5670 67322 -5789 70073 -5907 72663 -6030 75437 -6151 78242 -6268 81202 -6389 83948 -6509 86985 -6631 89903 -6747 93184 -6869 96044 -6991 99286 -7109 102395 -7229 105917 -7351 108940 -7470 112490 -7589 115702 -7711 119508 -7831 122632 -7951 126410 -8071 129808 -8190 133895 -8311 137146 -8431 141218 -8549 144732 -8667 149131 -8790 152462 -8911 156754 -9030 160479 -9149 165138 -9271 168601 -9391 173185 -9511 176988 -9627 181976 -9751 185539 -9870 190388 -9991 194335 -10110 199605 -10228 203298 diff --git a/libtommath/logs/mult.png b/libtommath/logs/mult.png Binary files differdeleted file mode 100644 index 4f7a4ee..0000000 --- a/libtommath/logs/mult.png +++ /dev/null diff --git a/libtommath/logs/mult_kara.log b/libtommath/logs/mult_kara.log deleted file mode 100644 index 7136c79..0000000 --- a/libtommath/logs/mult_kara.log +++ /dev/null @@ -1,84 +0,0 @@ -271 560 -391 870 -511 1159 -631 1605 -750 2111 -871 2737 -991 3361 -1111 4054 -1231 4778 -1351 5600 -1471 6404 -1591 7323 -1710 8255 -1831 9239 -1948 10257 -2070 11397 -2190 12531 -2308 13665 -2429 14870 -2550 16175 -2671 17539 -2787 18879 -2911 20350 -3031 21807 -3150 23415 -3270 24897 -3388 26567 -3511 28205 -3627 30076 -3751 31744 -3869 33657 -3991 35425 -4111 37522 -4229 39363 -4351 41503 -4470 43491 -4590 45827 -4711 47795 -4828 50166 -4951 52318 -5070 54911 -5191 57036 -5308 58237 -5431 60248 -5551 62678 -5671 64786 -5791 67294 -5908 69343 -6031 71607 -6151 74166 -6271 76590 -6391 78734 -6511 81175 -6631 83742 -6750 86403 -6868 88873 -6990 91150 -7110 94211 -7228 96922 -7351 99445 -7469 102216 -7589 104968 -7711 108113 -7827 110758 -7950 113714 -8071 116511 -8186 119643 -8310 122679 -8425 125581 -8551 128715 -8669 131778 -8788 135116 -8910 138138 -9031 141628 -9148 144754 -9268 148367 -9391 151551 -9511 155033 -9631 158652 -9751 162125 -9871 165248 -9988 168627 -10111 172427 -10231 176412 diff --git a/libtommath/logs/sqr.log b/libtommath/logs/sqr.log deleted file mode 100644 index cd29fc5..0000000 --- a/libtommath/logs/sqr.log +++ /dev/null @@ -1,84 +0,0 @@ -265 562 -389 882 -509 1207 -631 1572 -750 1990 -859 2433 -991 2894 -1109 3555 -1230 4228 -1350 5018 -1471 5805 -1591 6579 -1709 7415 -1829 8329 -1949 9225 -2071 10139 -2188 11239 -2309 12178 -2431 13212 -2551 14294 -2671 15551 -2791 16512 -2911 17718 -3030 18876 -3150 20259 -3270 21374 -3391 22650 -3511 23948 -3631 25493 -3750 26756 -3870 28225 -3989 29705 -4110 31409 -4230 32834 -4351 34327 -4471 35818 -4591 37636 -4711 39228 -4830 40868 -4949 42393 -5070 44541 -5191 46269 -5310 48162 -5429 49728 -5548 51985 -5671 53948 -5791 55885 -5910 57584 -6031 60082 -6150 62239 -6270 64309 -6390 66014 -6511 68766 -6631 71012 -6750 73172 -6871 74952 -6991 77909 -7111 80371 -7231 82666 -7351 84531 -7469 87698 -7589 90318 -7711 225384 -7830 232428 -7950 240009 -8070 246522 -8190 253662 -8310 260961 -8431 269253 -8549 275743 -8671 283769 -8789 290811 -8911 300034 -9030 306873 -9149 315085 -9270 323944 -9390 332390 -9508 337519 -9631 348986 -9749 356904 -9871 367013 -9989 373831 -10108 381033 -10230 393475 diff --git a/libtommath/logs/sqr_kara.log b/libtommath/logs/sqr_kara.log deleted file mode 100644 index 06355a7..0000000 --- a/libtommath/logs/sqr_kara.log +++ /dev/null @@ -1,84 +0,0 @@ -271 560 -388 878 -511 1179 -629 1625 -751 1988 -871 2423 -989 2896 -1111 3561 -1231 4209 -1350 5015 -1470 5804 -1591 6556 -1709 7420 -1831 8263 -1951 9173 -2070 10153 -2191 11229 -2310 12167 -2431 13211 -2550 14309 -2671 15524 -2788 16525 -2910 17712 -3028 18822 -3148 20220 -3271 21343 -3391 22652 -3511 23944 -3630 25485 -3750 26778 -3868 28201 -3990 29653 -4111 31393 -4225 32841 -4350 34328 -4471 35786 -4590 37652 -4711 39245 -4830 40876 -4951 42433 -5068 44547 -5191 46321 -5311 48140 -5430 49727 -5550 52034 -5671 53954 -5791 55921 -5908 57597 -6031 60084 -6148 62226 -6270 64295 -6390 66045 -6511 68779 -6629 71003 -6751 73169 -6871 74992 -6991 77895 -7110 80376 -7231 82628 -7351 84468 -7470 87664 -7591 90284 -7711 91352 -7828 93995 -7950 96276 -8071 98691 -8190 101256 -8308 103631 -8431 105222 -8550 108343 -8671 110281 -8787 112764 -8911 115397 -9031 117690 -9151 120266 -9271 122715 -9391 124624 -9510 127937 -9630 130313 -9750 132914 -9871 136129 -9991 138517 -10108 141525 -10231 144225 diff --git a/libtommath/logs/sub.log b/libtommath/logs/sub.log deleted file mode 100644 index 9f84fa2..0000000 --- a/libtommath/logs/sub.log +++ /dev/null @@ -1,16 +0,0 @@ -480 94 -960 116 -1440 140 -1920 164 -2400 205 -2880 229 -3360 253 -3840 277 -4320 299 -4800 321 -5280 345 -5760 371 -6240 395 -6720 419 -7200 441 -7680 465 diff --git a/libtommath/makefile.bcc b/libtommath/makefile.bcc deleted file mode 100644 index a0cfd74..0000000 --- a/libtommath/makefile.bcc +++ /dev/null @@ -1,46 +0,0 @@ -# -# Borland C++Builder Makefile (makefile.bcc) -# - - -LIB = tlib -CC = bcc32 -CFLAGS = -c -O2 -I. - -#START_INS -OBJECTS=bncore.obj bn_error.obj bn_fast_mp_invmod.obj bn_fast_mp_montgomery_reduce.obj bn_fast_s_mp_mul_digs.obj \ -bn_fast_s_mp_mul_high_digs.obj bn_fast_s_mp_sqr.obj bn_mp_2expt.obj bn_mp_abs.obj bn_mp_add.obj bn_mp_add_d.obj \ -bn_mp_addmod.obj bn_mp_and.obj bn_mp_clamp.obj bn_mp_clear.obj bn_mp_clear_multi.obj bn_mp_cmp.obj bn_mp_cmp_d.obj \ -bn_mp_cmp_mag.obj bn_mp_cnt_lsb.obj bn_mp_copy.obj bn_mp_count_bits.obj bn_mp_div_2.obj bn_mp_div_2d.obj bn_mp_div_3.obj \ -bn_mp_div.obj bn_mp_div_d.obj bn_mp_dr_is_modulus.obj bn_mp_dr_reduce.obj bn_mp_dr_setup.obj bn_mp_exch.obj \ -bn_mp_export.obj bn_mp_expt_d.obj bn_mp_expt_d_ex.obj bn_mp_exptmod.obj bn_mp_exptmod_fast.obj bn_mp_exteuclid.obj \ -bn_mp_fread.obj bn_mp_fwrite.obj bn_mp_gcd.obj bn_mp_get_int.obj bn_mp_get_long.obj bn_mp_get_long_long.obj \ -bn_mp_grow.obj bn_mp_import.obj bn_mp_init.obj bn_mp_init_copy.obj bn_mp_init_multi.obj bn_mp_init_set.obj \ -bn_mp_init_set_int.obj bn_mp_init_size.obj bn_mp_invmod.obj bn_mp_invmod_slow.obj bn_mp_is_square.obj \ -bn_mp_jacobi.obj bn_mp_karatsuba_mul.obj bn_mp_karatsuba_sqr.obj bn_mp_lcm.obj bn_mp_lshd.obj bn_mp_mod_2d.obj \ -bn_mp_mod.obj bn_mp_mod_d.obj bn_mp_montgomery_calc_normalization.obj bn_mp_montgomery_reduce.obj \ -bn_mp_montgomery_setup.obj bn_mp_mul_2.obj bn_mp_mul_2d.obj bn_mp_mul.obj bn_mp_mul_d.obj bn_mp_mulmod.obj bn_mp_neg.obj \ -bn_mp_n_root.obj bn_mp_n_root_ex.obj bn_mp_or.obj bn_mp_prime_fermat.obj bn_mp_prime_is_divisible.obj \ -bn_mp_prime_is_prime.obj bn_mp_prime_miller_rabin.obj bn_mp_prime_next_prime.obj \ -bn_mp_prime_rabin_miller_trials.obj bn_mp_prime_random_ex.obj bn_mp_radix_size.obj bn_mp_radix_smap.obj \ -bn_mp_rand.obj bn_mp_read_radix.obj bn_mp_read_signed_bin.obj bn_mp_read_unsigned_bin.obj bn_mp_reduce_2k.obj \ -bn_mp_reduce_2k_l.obj bn_mp_reduce_2k_setup.obj bn_mp_reduce_2k_setup_l.obj bn_mp_reduce.obj \ -bn_mp_reduce_is_2k.obj bn_mp_reduce_is_2k_l.obj bn_mp_reduce_setup.obj bn_mp_rshd.obj bn_mp_set.obj bn_mp_set_int.obj \ -bn_mp_set_long.obj bn_mp_set_long_long.obj bn_mp_shrink.obj bn_mp_signed_bin_size.obj bn_mp_sqr.obj bn_mp_sqrmod.obj \ -bn_mp_sqrt.obj bn_mp_sqrtmod_prime.obj bn_mp_sub.obj bn_mp_sub_d.obj bn_mp_submod.obj bn_mp_toom_mul.obj \ -bn_mp_toom_sqr.obj bn_mp_toradix.obj bn_mp_toradix_n.obj bn_mp_to_signed_bin.obj bn_mp_to_signed_bin_n.obj \ -bn_mp_to_unsigned_bin.obj bn_mp_to_unsigned_bin_n.obj bn_mp_unsigned_bin_size.obj bn_mp_xor.obj bn_mp_zero.obj \ -bn_prime_tab.obj bn_reverse.obj bn_s_mp_add.obj bn_s_mp_exptmod.obj bn_s_mp_mul_digs.obj bn_s_mp_mul_high_digs.obj \ -bn_s_mp_sqr.obj bn_s_mp_sub.obj - -#END_INS - -HEADERS=tommath.h tommath_class.h tommath_superclass.h - -TARGET = libtommath.lib - -$(TARGET): $(OBJECTS) - -.c.obj: - $(CC) $(CFLAGS) $< - $(LIB) $(TARGET) -+$@ diff --git a/libtommath/makefile.cygwin_dll b/libtommath/makefile.cygwin_dll deleted file mode 100644 index 6feb5b4..0000000 --- a/libtommath/makefile.cygwin_dll +++ /dev/null @@ -1,57 +0,0 @@ -#Makefile for Cygwin-GCC -# -#This makefile will build a Windows DLL [doesn't require cygwin to run] in the file -#libtommath.dll. The import library is in libtommath.dll.a. Remember to add -#"-Wl,--enable-auto-import" to your client build to avoid the auto-import warnings -# -#Tom St Denis -CFLAGS += -I./ -Wall -W -Wshadow -O3 -funroll-loops -mno-cygwin - -#x86 optimizations [should be valid for any GCC install though] -CFLAGS += -fomit-frame-pointer - -default: windll - -#START_INS -OBJECTS=bncore.o bn_error.o bn_fast_mp_invmod.o bn_fast_mp_montgomery_reduce.o bn_fast_s_mp_mul_digs.o \ -bn_fast_s_mp_mul_high_digs.o bn_fast_s_mp_sqr.o bn_mp_2expt.o bn_mp_abs.o bn_mp_add.o bn_mp_add_d.o \ -bn_mp_addmod.o bn_mp_and.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp_cmp.o bn_mp_cmp_d.o \ -bn_mp_cmp_mag.o bn_mp_cnt_lsb.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_div_2.o bn_mp_div_2d.o bn_mp_div_3.o \ -bn_mp_div.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o bn_mp_dr_setup.o bn_mp_exch.o \ -bn_mp_export.o bn_mp_expt_d.o bn_mp_expt_d_ex.o bn_mp_exptmod.o bn_mp_exptmod_fast.o bn_mp_exteuclid.o \ -bn_mp_fread.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_int.o bn_mp_get_long.o bn_mp_get_long_long.o \ -bn_mp_grow.o bn_mp_import.o bn_mp_init.o bn_mp_init_copy.o bn_mp_init_multi.o bn_mp_init_set.o \ -bn_mp_init_set_int.o bn_mp_init_size.o bn_mp_invmod.o bn_mp_invmod_slow.o bn_mp_is_square.o \ -bn_mp_jacobi.o bn_mp_karatsuba_mul.o bn_mp_karatsuba_sqr.o bn_mp_lcm.o bn_mp_lshd.o bn_mp_mod_2d.o \ -bn_mp_mod.o bn_mp_mod_d.o bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o \ -bn_mp_montgomery_setup.o bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul.o bn_mp_mul_d.o bn_mp_mulmod.o bn_mp_neg.o \ -bn_mp_n_root.o bn_mp_n_root_ex.o bn_mp_or.o bn_mp_prime_fermat.o bn_mp_prime_is_divisible.o \ -bn_mp_prime_is_prime.o bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o \ -bn_mp_prime_rabin_miller_trials.o bn_mp_prime_random_ex.o bn_mp_radix_size.o bn_mp_radix_smap.o \ -bn_mp_rand.o bn_mp_read_radix.o bn_mp_read_signed_bin.o bn_mp_read_unsigned_bin.o bn_mp_reduce_2k.o \ -bn_mp_reduce_2k_l.o bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o bn_mp_reduce.o \ -bn_mp_reduce_is_2k.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_setup.o bn_mp_rshd.o bn_mp_set.o bn_mp_set_int.o \ -bn_mp_set_long.o bn_mp_set_long_long.o bn_mp_shrink.o bn_mp_signed_bin_size.o bn_mp_sqr.o bn_mp_sqrmod.o \ -bn_mp_sqrt.o bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o bn_mp_submod.o bn_mp_toom_mul.o \ -bn_mp_toom_sqr.o bn_mp_toradix.o bn_mp_toradix_n.o bn_mp_to_signed_bin.o bn_mp_to_signed_bin_n.o \ -bn_mp_to_unsigned_bin.o bn_mp_to_unsigned_bin_n.o bn_mp_unsigned_bin_size.o bn_mp_xor.o bn_mp_zero.o \ -bn_prime_tab.o bn_reverse.o bn_s_mp_add.o bn_s_mp_exptmod.o bn_s_mp_mul_digs.o bn_s_mp_mul_high_digs.o \ -bn_s_mp_sqr.o bn_s_mp_sub.o - -#END_INS - -HEADERS=tommath.h tommath_class.h tommath_superclass.h - -# make a Windows DLL via Cygwin -windll: $(OBJECTS) - gcc -mno-cygwin -mdll -o libtommath.dll -Wl,--out-implib=libtommath.dll.a -Wl,--export-all-symbols *.o - ranlib libtommath.dll.a - -# build the test program using the windows DLL -test: $(OBJECTS) windll - gcc $(CFLAGS) demo/demo.c libtommath.dll.a -Wl,--enable-auto-import -o test -s - cd mtest ; $(CC) -O3 -fomit-frame-pointer -funroll-loops mtest.c -o mtest -s - -/* $Source: /cvs/libtom/libtommath/makefile.cygwin_dll,v $ */ -/* $Revision: 1.2 $ */ -/* $Date: 2005/05/05 14:38:45 $ */ diff --git a/libtommath/makefile.icc b/libtommath/makefile.icc deleted file mode 100644 index 1563802..0000000 --- a/libtommath/makefile.icc +++ /dev/null @@ -1,117 +0,0 @@ -#Makefile for ICC -# -#Tom St Denis -CC=icc - -CFLAGS += -I./ - -# optimize for SPEED -# -# -mcpu= can be pentium, pentiumpro (covers PII through PIII) or pentium4 -# -ax? specifies make code specifically for ? but compatible with IA-32 -# -x? specifies compile solely for ? [not specifically IA-32 compatible] -# -# where ? is -# K - PIII -# W - first P4 [Williamette] -# N - P4 Northwood -# P - P4 Prescott -# B - Blend of P4 and PM [mobile] -# -# Default to just generic max opts -CFLAGS += -O3 -xP -ip - -#install as this user -USER=root -GROUP=root - -default: libtommath.a - -#default files to install -LIBNAME=libtommath.a - -#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/libtommath/pdf - -#START_INS -OBJECTS=bncore.o bn_error.o bn_fast_mp_invmod.o bn_fast_mp_montgomery_reduce.o bn_fast_s_mp_mul_digs.o \ -bn_fast_s_mp_mul_high_digs.o bn_fast_s_mp_sqr.o bn_mp_2expt.o bn_mp_abs.o bn_mp_add.o bn_mp_add_d.o \ -bn_mp_addmod.o bn_mp_and.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp_cmp.o bn_mp_cmp_d.o \ -bn_mp_cmp_mag.o bn_mp_cnt_lsb.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_div_2.o bn_mp_div_2d.o bn_mp_div_3.o \ -bn_mp_div.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o bn_mp_dr_setup.o bn_mp_exch.o \ -bn_mp_export.o bn_mp_expt_d.o bn_mp_expt_d_ex.o bn_mp_exptmod.o bn_mp_exptmod_fast.o bn_mp_exteuclid.o \ -bn_mp_fread.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_int.o bn_mp_get_long.o bn_mp_get_long_long.o \ -bn_mp_grow.o bn_mp_import.o bn_mp_init.o bn_mp_init_copy.o bn_mp_init_multi.o bn_mp_init_set.o \ -bn_mp_init_set_int.o bn_mp_init_size.o bn_mp_invmod.o bn_mp_invmod_slow.o bn_mp_is_square.o \ -bn_mp_jacobi.o bn_mp_karatsuba_mul.o bn_mp_karatsuba_sqr.o bn_mp_lcm.o bn_mp_lshd.o bn_mp_mod_2d.o \ -bn_mp_mod.o bn_mp_mod_d.o bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o \ -bn_mp_montgomery_setup.o bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul.o bn_mp_mul_d.o bn_mp_mulmod.o bn_mp_neg.o \ -bn_mp_n_root.o bn_mp_n_root_ex.o bn_mp_or.o bn_mp_prime_fermat.o bn_mp_prime_is_divisible.o \ -bn_mp_prime_is_prime.o bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o \ -bn_mp_prime_rabin_miller_trials.o bn_mp_prime_random_ex.o bn_mp_radix_size.o bn_mp_radix_smap.o \ -bn_mp_rand.o bn_mp_read_radix.o bn_mp_read_signed_bin.o bn_mp_read_unsigned_bin.o bn_mp_reduce_2k.o \ -bn_mp_reduce_2k_l.o bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o bn_mp_reduce.o \ -bn_mp_reduce_is_2k.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_setup.o bn_mp_rshd.o bn_mp_set.o bn_mp_set_int.o \ -bn_mp_set_long.o bn_mp_set_long_long.o bn_mp_shrink.o bn_mp_signed_bin_size.o bn_mp_sqr.o bn_mp_sqrmod.o \ -bn_mp_sqrt.o bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o bn_mp_submod.o bn_mp_toom_mul.o \ -bn_mp_toom_sqr.o bn_mp_toradix.o bn_mp_toradix_n.o bn_mp_to_signed_bin.o bn_mp_to_signed_bin_n.o \ -bn_mp_to_unsigned_bin.o bn_mp_to_unsigned_bin_n.o bn_mp_unsigned_bin_size.o bn_mp_xor.o bn_mp_zero.o \ -bn_prime_tab.o bn_reverse.o bn_s_mp_add.o bn_s_mp_exptmod.o bn_s_mp_mul_digs.o bn_s_mp_mul_high_digs.o \ -bn_s_mp_sqr.o bn_s_mp_sub.o - -#END_INS - -HEADERS=tommath.h tommath_class.h tommath_superclass.h - -libtommath.a: $(OBJECTS) - $(AR) $(ARFLAGS) libtommath.a $(OBJECTS) - ranlib libtommath.a - -#make a profiled library (takes a while!!!) -# -# This will build the library with profile generation -# then run the test demo and rebuild the library. -# -# So far I've seen improvements in the MP math -profiled: - make -f makefile.icc CFLAGS="$(CFLAGS) -prof_gen -DTESTING" timing - ./ltmtest - rm -f *.a *.o ltmtest - make -f makefile.icc CFLAGS="$(CFLAGS) -prof_use" - -#make a single object profiled library -profiled_single: - perl gen.pl - $(CC) $(CFLAGS) -prof_gen -DTESTING -c mpi.c -o mpi.o - $(CC) $(CFLAGS) -DTESTING -DTIMER demo/demo.c mpi.o -o ltmtest - ./ltmtest - rm -f *.o ltmtest - $(CC) $(CFLAGS) -prof_use -ip -DTESTING -c mpi.c -o mpi.o - $(AR) $(ARFLAGS) libtommath.a mpi.o - ranlib libtommath.a - -install: libtommath.a - install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) - install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) - install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH) - install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) - -test: libtommath.a demo/demo.o - $(CC) demo/demo.o libtommath.a -o test - -mtest: test - cd mtest ; $(CC) $(CFLAGS) mtest.c -o mtest - -timing: libtommath.a - $(CC) $(CFLAGS) -DTIMER demo/timing.c libtommath.a -o ltmtest - -clean: - rm -f *.bat *.pdf *.o *.a *.obj *.lib *.exe *.dll etclib/*.o demo/demo.o test ltmtest mpitest mtest/mtest mtest/mtest.exe \ - *.idx *.toc *.log *.aux *.dvi *.lof *.ind *.ilg *.ps *.log *.s mpi.c *.il etc/*.il *.dyn - cd etc ; make clean - cd pics ; make clean diff --git a/libtommath/makefile.msvc b/libtommath/makefile.msvc deleted file mode 100644 index a47aadd..0000000 --- a/libtommath/makefile.msvc +++ /dev/null @@ -1,40 +0,0 @@ -#MSVC Makefile -# -#Tom St Denis - -CFLAGS = /I. /Ox /DWIN32 /W3 /Fo$@ - -default: library - -#START_INS -OBJECTS=bncore.obj bn_error.obj bn_fast_mp_invmod.obj bn_fast_mp_montgomery_reduce.obj bn_fast_s_mp_mul_digs.obj \ -bn_fast_s_mp_mul_high_digs.obj bn_fast_s_mp_sqr.obj bn_mp_2expt.obj bn_mp_abs.obj bn_mp_add.obj bn_mp_add_d.obj \ -bn_mp_addmod.obj bn_mp_and.obj bn_mp_clamp.obj bn_mp_clear.obj bn_mp_clear_multi.obj bn_mp_cmp.obj bn_mp_cmp_d.obj \ -bn_mp_cmp_mag.obj bn_mp_cnt_lsb.obj bn_mp_copy.obj bn_mp_count_bits.obj bn_mp_div_2.obj bn_mp_div_2d.obj bn_mp_div_3.obj \ -bn_mp_div.obj bn_mp_div_d.obj bn_mp_dr_is_modulus.obj bn_mp_dr_reduce.obj bn_mp_dr_setup.obj bn_mp_exch.obj \ -bn_mp_export.obj bn_mp_expt_d.obj bn_mp_expt_d_ex.obj bn_mp_exptmod.obj bn_mp_exptmod_fast.obj bn_mp_exteuclid.obj \ -bn_mp_fread.obj bn_mp_fwrite.obj bn_mp_gcd.obj bn_mp_get_int.obj bn_mp_get_long.obj bn_mp_get_long_long.obj \ -bn_mp_grow.obj bn_mp_import.obj bn_mp_init.obj bn_mp_init_copy.obj bn_mp_init_multi.obj bn_mp_init_set.obj \ -bn_mp_init_set_int.obj bn_mp_init_size.obj bn_mp_invmod.obj bn_mp_invmod_slow.obj bn_mp_is_square.obj \ -bn_mp_jacobi.obj bn_mp_karatsuba_mul.obj bn_mp_karatsuba_sqr.obj bn_mp_lcm.obj bn_mp_lshd.obj bn_mp_mod_2d.obj \ -bn_mp_mod.obj bn_mp_mod_d.obj bn_mp_montgomery_calc_normalization.obj bn_mp_montgomery_reduce.obj \ -bn_mp_montgomery_setup.obj bn_mp_mul_2.obj bn_mp_mul_2d.obj bn_mp_mul.obj bn_mp_mul_d.obj bn_mp_mulmod.obj bn_mp_neg.obj \ -bn_mp_n_root.obj bn_mp_n_root_ex.obj bn_mp_or.obj bn_mp_prime_fermat.obj bn_mp_prime_is_divisible.obj \ -bn_mp_prime_is_prime.obj bn_mp_prime_miller_rabin.obj bn_mp_prime_next_prime.obj \ -bn_mp_prime_rabin_miller_trials.obj bn_mp_prime_random_ex.obj bn_mp_radix_size.obj bn_mp_radix_smap.obj \ -bn_mp_rand.obj bn_mp_read_radix.obj bn_mp_read_signed_bin.obj bn_mp_read_unsigned_bin.obj bn_mp_reduce_2k.obj \ -bn_mp_reduce_2k_l.obj bn_mp_reduce_2k_setup.obj bn_mp_reduce_2k_setup_l.obj bn_mp_reduce.obj \ -bn_mp_reduce_is_2k.obj bn_mp_reduce_is_2k_l.obj bn_mp_reduce_setup.obj bn_mp_rshd.obj bn_mp_set.obj bn_mp_set_int.obj \ -bn_mp_set_long.obj bn_mp_set_long_long.obj bn_mp_shrink.obj bn_mp_signed_bin_size.obj bn_mp_sqr.obj bn_mp_sqrmod.obj \ -bn_mp_sqrt.obj bn_mp_sqrtmod_prime.obj bn_mp_sub.obj bn_mp_sub_d.obj bn_mp_submod.obj bn_mp_toom_mul.obj \ -bn_mp_toom_sqr.obj bn_mp_toradix.obj bn_mp_toradix_n.obj bn_mp_to_signed_bin.obj bn_mp_to_signed_bin_n.obj \ -bn_mp_to_unsigned_bin.obj bn_mp_to_unsigned_bin_n.obj bn_mp_unsigned_bin_size.obj bn_mp_xor.obj bn_mp_zero.obj \ -bn_prime_tab.obj bn_reverse.obj bn_s_mp_add.obj bn_s_mp_exptmod.obj bn_s_mp_mul_digs.obj bn_s_mp_mul_high_digs.obj \ -bn_s_mp_sqr.obj bn_s_mp_sub.obj - -#END_INS - -HEADERS=tommath.h tommath_class.h tommath_superclass.h - -library: $(OBJECTS) - lib /out:tommath.lib $(OBJECTS) diff --git a/libtommath/makefile.shared b/libtommath/makefile.shared deleted file mode 100644 index 67213a2..0000000 --- a/libtommath/makefile.shared +++ /dev/null @@ -1,88 +0,0 @@ -#Makefile for GCC -# -#Tom St Denis - -#default files to install -ifndef LIBNAME - LIBNAME=libtommath.la -endif - -include makefile_include.mk - - -ifndef LT - ifeq ($(PLATFORM), Darwin) - LT:=glibtool - else - LT:=libtool - endif -endif -LTCOMPILE = $(LT) --mode=compile --tag=CC $(CC) - -LCOV_ARGS=--directory .libs --directory . - -#START_INS -OBJECTS=bncore.o bn_error.o bn_fast_mp_invmod.o bn_fast_mp_montgomery_reduce.o bn_fast_s_mp_mul_digs.o \ -bn_fast_s_mp_mul_high_digs.o bn_fast_s_mp_sqr.o bn_mp_2expt.o bn_mp_abs.o bn_mp_add.o bn_mp_add_d.o \ -bn_mp_addmod.o bn_mp_and.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp_cmp.o bn_mp_cmp_d.o \ -bn_mp_cmp_mag.o bn_mp_cnt_lsb.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_div_2.o bn_mp_div_2d.o bn_mp_div_3.o \ -bn_mp_div.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o bn_mp_dr_setup.o bn_mp_exch.o \ -bn_mp_export.o bn_mp_expt_d.o bn_mp_expt_d_ex.o bn_mp_exptmod.o bn_mp_exptmod_fast.o bn_mp_exteuclid.o \ -bn_mp_fread.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_int.o bn_mp_get_long.o bn_mp_get_long_long.o \ -bn_mp_grow.o bn_mp_import.o bn_mp_init.o bn_mp_init_copy.o bn_mp_init_multi.o bn_mp_init_set.o \ -bn_mp_init_set_int.o bn_mp_init_size.o bn_mp_invmod.o bn_mp_invmod_slow.o bn_mp_is_square.o \ -bn_mp_jacobi.o bn_mp_karatsuba_mul.o bn_mp_karatsuba_sqr.o bn_mp_lcm.o bn_mp_lshd.o bn_mp_mod_2d.o \ -bn_mp_mod.o bn_mp_mod_d.o bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o \ -bn_mp_montgomery_setup.o bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul.o bn_mp_mul_d.o bn_mp_mulmod.o bn_mp_neg.o \ -bn_mp_n_root.o bn_mp_n_root_ex.o bn_mp_or.o bn_mp_prime_fermat.o bn_mp_prime_is_divisible.o \ -bn_mp_prime_is_prime.o bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o \ -bn_mp_prime_rabin_miller_trials.o bn_mp_prime_random_ex.o bn_mp_radix_size.o bn_mp_radix_smap.o \ -bn_mp_rand.o bn_mp_read_radix.o bn_mp_read_signed_bin.o bn_mp_read_unsigned_bin.o bn_mp_reduce_2k.o \ -bn_mp_reduce_2k_l.o bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o bn_mp_reduce.o \ -bn_mp_reduce_is_2k.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_setup.o bn_mp_rshd.o bn_mp_set.o bn_mp_set_int.o \ -bn_mp_set_long.o bn_mp_set_long_long.o bn_mp_shrink.o bn_mp_signed_bin_size.o bn_mp_sqr.o bn_mp_sqrmod.o \ -bn_mp_sqrt.o bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o bn_mp_submod.o bn_mp_toom_mul.o \ -bn_mp_toom_sqr.o bn_mp_toradix.o bn_mp_toradix_n.o bn_mp_to_signed_bin.o bn_mp_to_signed_bin_n.o \ -bn_mp_to_unsigned_bin.o bn_mp_to_unsigned_bin_n.o bn_mp_unsigned_bin_size.o bn_mp_xor.o bn_mp_zero.o \ -bn_prime_tab.o bn_reverse.o bn_s_mp_add.o bn_s_mp_exptmod.o bn_s_mp_mul_digs.o bn_s_mp_mul_high_digs.o \ -bn_s_mp_sqr.o bn_s_mp_sub.o - -#END_INS - -objs: $(OBJECTS) - -.c.o: - $(LTCOMPILE) $(CFLAGS) $(LDFLAGS) -o $@ -c $< - -LOBJECTS = $(OBJECTS:.o=.lo) - -$(LIBNAME): $(OBJECTS) - $(LT) --mode=link --tag=CC $(CC) $(LDFLAGS) $(LOBJECTS) -o $(LIBNAME) -rpath $(LIBPATH) -version-info $(VERSION_SO) - -install: $(LIBNAME) - install -d $(DESTDIR)$(LIBPATH) - install -d $(DESTDIR)$(INCPATH) - $(LT) --mode=install install -m 644 $(LIBNAME) $(DESTDIR)$(LIBPATH)/$(LIBNAME) - install -m 644 $(HEADERS_PUB) $(DESTDIR)$(INCPATH) - sed -e 's,^prefix=.*,prefix=$(PREFIX),' -e 's,^Version:.*,Version: $(VERSION_PC),' libtommath.pc.in > libtommath.pc - install -d $(DESTDIR)$(LIBPATH)/pkgconfig - install -m 644 libtommath.pc $(DESTDIR)$(LIBPATH)/pkgconfig/ - -uninstall: - $(LT) --mode=uninstall rm $(DESTDIR)$(LIBPATH)/$(LIBNAME) - rm $(HEADERS_PUB:%=$(DESTDIR)$(INCPATH)/%) - rm $(DESTDIR)$(LIBPATH)/pkgconfig/libtommath.pc - -test: $(LIBNAME) demo/demo.o - $(CC) $(CFLAGS) -c demo/demo.c -o demo/demo.o - $(LT) --mode=link $(CC) $(LDFLAGS) -o test demo/demo.o $(LIBNAME) - -test_standalone: $(LIBNAME) demo/demo.o - $(CC) $(CFLAGS) -c demo/demo.c -o demo/demo.o - $(LT) --mode=link $(CC) $(LDFLAGS) -o test demo/demo.o $(LIBNAME) - -mtest: - cd mtest ; $(CC) $(CFLAGS) $(LDFLAGS) mtest.c -o mtest - -timing: $(LIBNAME) - $(LT) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) -DTIMER demo/timing.c $(LIBNAME) -o ltmtest diff --git a/libtommath/makefile_include.mk b/libtommath/makefile_include.mk index 580a478..711b630 100644 --- a/libtommath/makefile_include.mk +++ b/libtommath/makefile_include.mk @@ -3,9 +3,9 @@ # #version of library -VERSION=1.0.1 -VERSION_PC=1.0.1 -VERSION_SO=1:1 +VERSION=1.2.0 +VERSION_PC=1.2.0 +VERSION_SO=3:0:2 PLATFORM := $(shell uname | sed -e 's/_.*//') @@ -17,67 +17,116 @@ ifndef CROSS_COMPILE CROSS_COMPILE= endif +# We only need to go through this dance of determining the right compiler if we're using +# cross compilation, otherwise $(CC) is fine as-is. +ifneq (,$(CROSS_COMPILE)) +ifeq ($(origin CC),default) +CSTR := "\#ifdef __clang__\nCLANG\n\#endif\n" +ifeq ($(PLATFORM),FreeBSD) + # XXX: FreeBSD needs extra escaping for some reason + CSTR := $$$(CSTR) +endif +ifneq (,$(shell echo $(CSTR) | $(CC) -E - | grep CLANG)) + CC := $(CROSS_COMPILE)clang +else + CC := $(CROSS_COMPILE)gcc +endif # Clang +endif # cc is Make's default +endif # CROSS_COMPILE non-empty + # Dropbear passes these down -#ifeq ($(CC),cc) -# CC = $(CROSS_COMPILE)gcc -#endif #LD=$(CROSS_COMPILE)ld #AR=$(CROSS_COMPILE)ar #RANLIB=$(CROSS_COMPILE)ranlib ifndef MAKE - MAKE=make +# BSDs refer to GNU Make as gmake +ifneq (,$(findstring $(PLATFORM),FreeBSD OpenBSD DragonFly NetBSD)) + MAKE=gmake +else + MAKE=make +endif endif -CFLAGS += -I./ -Wall -Wsign-compare -Wextra -Wshadow +LTM_CFLAGS += -I./ -Wall -Wsign-compare -Wextra -Wshadow + +# renamed for Dropbear to avoid clash with oss-fuzz $SANITIZER var +ifdef LTM_SANITIZER +LTM_CFLAGS += -fsanitize=undefined -fno-sanitize-recover=all -fno-sanitize=float-divide-by-zero +endif ifndef NO_ADDTL_WARNINGS # additional warnings -CFLAGS += -Wsystem-headers -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -CFLAGS += -Wstrict-prototypes -Wpointer-arith +LTM_CFLAGS += -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align +LTM_CFLAGS += -Wstrict-prototypes -Wpointer-arith +endif + +ifdef CONV_WARNINGS +LTM_CFLAGS += -std=c89 -Wconversion -Wsign-conversion +ifeq ($(CONV_WARNINGS), strict) +LTM_CFLAGS += -DMP_USE_ENUMS -Wc++-compat +endif +else +LTM_CFLAGS += -Wsystem-headers endif ifdef COMPILE_DEBUG #debug -CFLAGS += -g3 -else +LTM_CFLAGS += -g3 +endif ifdef COMPILE_SIZE #for size -CFLAGS += -Os +LTM_CFLAGS += -Os else ifndef IGNORE_SPEED #for speed -CFLAGS += -O3 -funroll-loops +LTM_CFLAGS += -O3 -funroll-loops #x86 optimizations [should be valid for any GCC install though] -CFLAGS += -fomit-frame-pointer +LTM_CFLAGS += -fomit-frame-pointer endif endif # COMPILE_SIZE -endif # COMPILE_DEBUG ifneq ($(findstring clang,$(CC)),) -CFLAGS += -Wno-typedef-redefinition -Wno-tautological-compare -Wno-builtin-requires-header +LTM_CFLAGS += -Wno-typedef-redefinition -Wno-tautological-compare -Wno-builtin-requires-header +endif +ifneq ($(findstring mingw,$(CC)),) +LTM_CFLAGS += -Wno-shadow endif ifeq ($(PLATFORM), Darwin) -CFLAGS += -Wno-nullability-completeness +LTM_CFLAGS += -Wno-nullability-completeness +endif +ifeq ($(PLATFORM), CYGWIN) +LIBTOOLFLAGS += -no-undefined +endif + +# add in the standard FLAGS +LTM_CFLAGS += $(CFLAGS) +LTM_LFLAGS += $(LFLAGS) +LTM_LDFLAGS += $(LDFLAGS) +LTM_LIBTOOLFLAGS += $(LIBTOOLFLAGS) + + +ifeq ($(PLATFORM),FreeBSD) + _ARCH := $(shell sysctl -b hw.machine_arch) +else + _ARCH := $(shell uname -m) endif # adjust coverage set -ifneq ($(filter $(shell arch), i386 i686 x86_64 amd64 ia64),) +ifneq ($(filter $(_ARCH), i386 i686 x86_64 amd64 ia64),) COVERAGE = test_standalone timing - COVERAGE_APP = ./test && ./ltmtest + COVERAGE_APP = ./test && ./timing else COVERAGE = test_standalone COVERAGE_APP = ./test endif -HEADERS_PUB=tommath.h tommath_class.h tommath_superclass.h -HEADERS=tommath_private.h $(HEADERS_PUB) - -test_standalone: CFLAGS+=-DLTM_DEMO_TEST_VS_MTEST=0 +HEADERS_PUB=tommath.h +HEADERS=tommath_private.h tommath_class.h tommath_superclass.h tommath_cutoffs.h $(HEADERS_PUB) #LIBPATH The directory for libtommath to be installed to. #INCPATH The directory to install the header files for libtommath. @@ -90,9 +139,9 @@ DATAPATH ?= $(PREFIX)/share/doc/libtommath/pdf #make the code coverage of the library # -coverage: CFLAGS += -fprofile-arcs -ftest-coverage -DTIMING_NO_LOGS -coverage: LFLAGS += -lgcov -coverage: LDFLAGS += -lgcov +coverage: LTM_CFLAGS += -fprofile-arcs -ftest-coverage -DTIMING_NO_LOGS +coverage: LTM_LFLAGS += -lgcov +coverage: LTM_LDFLAGS += -lgcov coverage: $(COVERAGE) $(COVERAGE_APP) @@ -111,8 +160,7 @@ cleancov-clean: cleancov: cleancov-clean clean clean: - rm -f *.gcda *.gcno *.gcov *.bat *.o *.a *.obj *.lib *.exe *.dll etclib/*.o demo/demo.o test ltmtest mpitest mtest/mtest mtest/mtest.exe \ - *.idx *.toc *.log *.aux *.dvi *.lof *.ind *.ilg *.ps *.log *.s mpi.c *.da *.dyn *.dpi tommath.tex `find . -type f | grep [~] | xargs` *.lo *.la - rm -rf .libs/ - #${MAKE} -C etc/ clean MAKE=${MAKE} - #${MAKE} -C doc/ clean MAKE=${MAKE} + rm -f *.gcda *.gcno *.gcov *.bat *.o *.a *.obj *.lib *.exe *.dll etclib/*.o \ + demo/*.o test timing mtest_opponent mtest/mtest mtest/mtest.exe tuning_list \ + *.s mpi.c *.da *.dyn *.dpi tommath.tex `find . -type f | grep [~] | xargs` *.lo *.la + rm -rf .libs/ demo/.libs diff --git a/libtommath/mess.sh b/libtommath/mess.sh deleted file mode 100644 index bf639ce..0000000 --- a/libtommath/mess.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -if cvs log $1 >/dev/null 2>/dev/null; then exit 0; else echo "$1 shouldn't be here" ; exit 1; fi - - diff --git a/libtommath/mtest/logtab.h b/libtommath/mtest/logtab.h deleted file mode 100644 index 751111e..0000000 --- a/libtommath/mtest/logtab.h +++ /dev/null @@ -1,24 +0,0 @@ -const float s_logv_2[] = { - 0.000000000, 0.000000000, 1.000000000, 0.630929754, /* 0 1 2 3 */ - 0.500000000, 0.430676558, 0.386852807, 0.356207187, /* 4 5 6 7 */ - 0.333333333, 0.315464877, 0.301029996, 0.289064826, /* 8 9 10 11 */ - 0.278942946, 0.270238154, 0.262649535, 0.255958025, /* 12 13 14 15 */ - 0.250000000, 0.244650542, 0.239812467, 0.235408913, /* 16 17 18 19 */ - 0.231378213, 0.227670249, 0.224243824, 0.221064729, /* 20 21 22 23 */ - 0.218104292, 0.215338279, 0.212746054, 0.210309918, /* 24 25 26 27 */ - 0.208014598, 0.205846832, 0.203795047, 0.201849087, /* 28 29 30 31 */ - 0.200000000, 0.198239863, 0.196561632, 0.194959022, /* 32 33 34 35 */ - 0.193426404, 0.191958720, 0.190551412, 0.189200360, /* 36 37 38 39 */ - 0.187901825, 0.186652411, 0.185449023, 0.184288833, /* 40 41 42 43 */ - 0.183169251, 0.182087900, 0.181042597, 0.180031327, /* 44 45 46 47 */ - 0.179052232, 0.178103594, 0.177183820, 0.176291434, /* 48 49 50 51 */ - 0.175425064, 0.174583430, 0.173765343, 0.172969690, /* 52 53 54 55 */ - 0.172195434, 0.171441601, 0.170707280, 0.169991616, /* 56 57 58 59 */ - 0.169293808, 0.168613099, 0.167948779, 0.167300179, /* 60 61 62 63 */ - 0.166666667 -}; - - -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ diff --git a/libtommath/mtest/mpi-config.h b/libtommath/mtest/mpi-config.h deleted file mode 100644 index fc2a885..0000000 --- a/libtommath/mtest/mpi-config.h +++ /dev/null @@ -1,90 +0,0 @@ -/* Default configuration for MPI library */ -/* $Id$ */ - -#ifndef MPI_CONFIG_H_ -#define MPI_CONFIG_H_ - -/* - For boolean options, - 0 = no - 1 = yes - - Other options are documented individually. - - */ - -#ifndef MP_IOFUNC -#define MP_IOFUNC 0 /* include mp_print() ? */ -#endif - -#ifndef MP_MODARITH -#define MP_MODARITH 1 /* include modular arithmetic ? */ -#endif - -#ifndef MP_NUMTH -#define MP_NUMTH 1 /* include number theoretic functions? */ -#endif - -#ifndef MP_LOGTAB -#define MP_LOGTAB 1 /* use table of logs instead of log()? */ -#endif - -#ifndef MP_MEMSET -#define MP_MEMSET 1 /* use memset() to zero buffers? */ -#endif - -#ifndef MP_MEMCPY -#define MP_MEMCPY 1 /* use memcpy() to copy buffers? */ -#endif - -#ifndef MP_CRYPTO -#define MP_CRYPTO 1 /* erase memory on free? */ -#endif - -#ifndef MP_ARGCHK -/* - 0 = no parameter checks - 1 = runtime checks, continue execution and return an error to caller - 2 = assertions; dump core on parameter errors - */ -#define MP_ARGCHK 2 /* how to check input arguments */ -#endif - -#ifndef MP_DEBUG -#define MP_DEBUG 0 /* print diagnostic output? */ -#endif - -#ifndef MP_DEFPREC -#define MP_DEFPREC 64 /* default precision, in digits */ -#endif - -#ifndef MP_MACRO -#define MP_MACRO 1 /* use macros for frequent calls? */ -#endif - -#ifndef MP_SQUARE -#define MP_SQUARE 1 /* use separate squaring code? */ -#endif - -#ifndef MP_PTAB_SIZE -/* - When building mpprime.c, we build in a table of small prime - values to use for primality testing. The more you include, - the more space they take up. See primes.c for the possible - values (currently 16, 32, 64, 128, 256, and 6542) - */ -#define MP_PTAB_SIZE 128 /* how many built-in primes? */ -#endif - -#ifndef MP_COMPAT_MACROS -#define MP_COMPAT_MACROS 1 /* define compatibility macros? */ -#endif - -#endif /* ifndef MPI_CONFIG_H_ */ - - -/* crc==3287762869, version==2, Sat Feb 02 06:43:53 2002 */ - -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ diff --git a/libtommath/mtest/mpi-types.h b/libtommath/mtest/mpi-types.h deleted file mode 100644 index f99d7ee..0000000 --- a/libtommath/mtest/mpi-types.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Type definitions generated by 'types.pl' */ -typedef char mp_sign; -typedef unsigned short mp_digit; /* 2 byte type */ -typedef unsigned int mp_word; /* 4 byte type */ -typedef unsigned int mp_size; -typedef int mp_err; - -#define MP_DIGIT_BIT (CHAR_BIT*sizeof(mp_digit)) -#define MP_DIGIT_MAX USHRT_MAX -#define MP_WORD_BIT (CHAR_BIT*sizeof(mp_word)) -#define MP_WORD_MAX UINT_MAX - -#define MP_DIGIT_SIZE 2 -#define DIGIT_FMT "%04X" -#define RADIX (MP_DIGIT_MAX+1) - - -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ diff --git a/libtommath/mtest/mpi.c b/libtommath/mtest/mpi.c deleted file mode 100644 index 48dbe27..0000000 --- a/libtommath/mtest/mpi.c +++ /dev/null @@ -1,3985 +0,0 @@ -/* - mpi.c - - by Michael J. Fromberger <sting@linguist.dartmouth.edu> - Copyright (C) 1998 Michael J. Fromberger, All Rights Reserved - - Arbitrary precision integer arithmetic library - - $Id$ - */ - -#include "mpi.h" -#include <stdlib.h> -#include <string.h> -#include <ctype.h> - -#if MP_DEBUG -#include <stdio.h> - -#define DIAG(T,V) {fprintf(stderr,T);mp_print(V,stderr);fputc('\n',stderr);} -#else -#define DIAG(T,V) -#endif - -/* - If MP_LOGTAB is not defined, use the math library to compute the - logarithms on the fly. Otherwise, use the static table below. - Pick which works best for your system. - */ -#if MP_LOGTAB - -/* {{{ s_logv_2[] - log table for 2 in various bases */ - -/* - A table of the logs of 2 for various bases (the 0 and 1 entries of - this table are meaningless and should not be referenced). - - This table is used to compute output lengths for the mp_toradix() - function. Since a number n in radix r takes up about log_r(n) - digits, we estimate the output size by taking the least integer - greater than log_r(n), where: - - log_r(n) = log_2(n) * log_r(2) - - This table, therefore, is a table of log_r(2) for 2 <= r <= 36, - which are the output bases supported. - */ - -#include "logtab.h" - -/* }}} */ -#define LOG_V_2(R) s_logv_2[(R)] - -#else - -#include <math.h> -#define LOG_V_2(R) (log(2.0)/log(R)) - -#endif - -/* Default precision for newly created mp_int's */ -static unsigned int s_mp_defprec = MP_DEFPREC; - -/* {{{ Digit arithmetic macros */ - -/* - When adding and multiplying digits, the results can be larger than - can be contained in an mp_digit. Thus, an mp_word is used. These - macros mask off the upper and lower digits of the mp_word (the - mp_word may be more than 2 mp_digits wide, but we only concern - ourselves with the low-order 2 mp_digits) - - If your mp_word DOES have more than 2 mp_digits, you need to - uncomment the first line, and comment out the second. - */ - -/* #define CARRYOUT(W) (((W)>>DIGIT_BIT)&MP_DIGIT_MAX) */ -#define CARRYOUT(W) ((W)>>DIGIT_BIT) -#define ACCUM(W) ((W)&MP_DIGIT_MAX) - -/* }}} */ - -/* {{{ Comparison constants */ - -#define MP_LT -1 -#define MP_EQ 0 -#define MP_GT 1 - -/* }}} */ - -/* {{{ Constant strings */ - -/* Constant strings returned by mp_strerror() */ -static const char *mp_err_string[] = { - "unknown result code", /* say what? */ - "boolean true", /* MP_OKAY, MP_YES */ - "boolean false", /* MP_NO */ - "out of memory", /* MP_MEM */ - "argument out of range", /* MP_RANGE */ - "invalid input parameter", /* MP_BADARG */ - "result is undefined" /* MP_UNDEF */ -}; - -/* Value to digit maps for radix conversion */ - -/* s_dmap_1 - standard digits and letters */ -static const char *s_dmap_1 = - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; - -#if 0 -/* s_dmap_2 - base64 ordering for digits */ -static const char *s_dmap_2 = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -#endif - -/* }}} */ - -/* {{{ Static function declarations */ - -/* - If MP_MACRO is false, these will be defined as actual functions; - otherwise, suitable macro definitions will be used. This works - around the fact that ANSI C89 doesn't support an 'inline' keyword - (although I hear C9x will ... about bloody time). At present, the - macro definitions are identical to the function bodies, but they'll - expand in place, instead of generating a function call. - - I chose these particular functions to be made into macros because - some profiling showed they are called a lot on a typical workload, - and yet they are primarily housekeeping. - */ -#if MP_MACRO == 0 - void s_mp_setz(mp_digit *dp, mp_size count); /* zero digits */ - void s_mp_copy(mp_digit *sp, mp_digit *dp, mp_size count); /* copy */ - void *s_mp_alloc(size_t nb, size_t ni); /* general allocator */ - void s_mp_free(void *ptr); /* general free function */ -#else - - /* Even if these are defined as macros, we need to respect the settings - of the MP_MEMSET and MP_MEMCPY configuration options... - */ - #if MP_MEMSET == 0 - #define s_mp_setz(dp, count) \ - {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=0;} - #else - #define s_mp_setz(dp, count) memset(dp, 0, (count) * sizeof(mp_digit)) - #endif /* MP_MEMSET */ - - #if MP_MEMCPY == 0 - #define s_mp_copy(sp, dp, count) \ - {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=(sp)[ix];} - #else - #define s_mp_copy(sp, dp, count) memcpy(dp, sp, (count) * sizeof(mp_digit)) - #endif /* MP_MEMCPY */ - - #define s_mp_alloc(nb, ni) calloc(nb, ni) - #define s_mp_free(ptr) {if(ptr) free(ptr);} -#endif /* MP_MACRO */ - -mp_err s_mp_grow(mp_int *mp, mp_size min); /* increase allocated size */ -mp_err s_mp_pad(mp_int *mp, mp_size min); /* left pad with zeroes */ - -void s_mp_clamp(mp_int *mp); /* clip leading zeroes */ - -void s_mp_exch(mp_int *a, mp_int *b); /* swap a and b in place */ - -mp_err s_mp_lshd(mp_int *mp, mp_size p); /* left-shift by p digits */ -void s_mp_rshd(mp_int *mp, mp_size p); /* right-shift by p digits */ -void s_mp_div_2d(mp_int *mp, mp_digit d); /* divide by 2^d in place */ -void s_mp_mod_2d(mp_int *mp, mp_digit d); /* modulo 2^d in place */ -mp_err s_mp_mul_2d(mp_int *mp, mp_digit d); /* multiply by 2^d in place*/ -void s_mp_div_2(mp_int *mp); /* divide by 2 in place */ -mp_err s_mp_mul_2(mp_int *mp); /* multiply by 2 in place */ -mp_digit s_mp_norm(mp_int *a, mp_int *b); /* normalize for division */ -mp_err s_mp_add_d(mp_int *mp, mp_digit d); /* unsigned digit addition */ -mp_err s_mp_sub_d(mp_int *mp, mp_digit d); /* unsigned digit subtract */ -mp_err s_mp_mul_d(mp_int *mp, mp_digit d); /* unsigned digit multiply */ -mp_err s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r); - /* unsigned digit divide */ -mp_err s_mp_reduce(mp_int *x, mp_int *m, mp_int *mu); - /* Barrett reduction */ -mp_err s_mp_add(mp_int *a, mp_int *b); /* magnitude addition */ -mp_err s_mp_sub(mp_int *a, mp_int *b); /* magnitude subtract */ -mp_err s_mp_mul(mp_int *a, mp_int *b); /* magnitude multiply */ -#if 0 -void s_mp_kmul(mp_digit *a, mp_digit *b, mp_digit *out, mp_size len); - /* multiply buffers in place */ -#endif -#if MP_SQUARE -mp_err s_mp_sqr(mp_int *a); /* magnitude square */ -#else -#define s_mp_sqr(a) s_mp_mul(a, a) -#endif -mp_err s_mp_div(mp_int *a, mp_int *b); /* magnitude divide */ -mp_err s_mp_2expt(mp_int *a, mp_digit k); /* a = 2^k */ -int s_mp_cmp(mp_int *a, mp_int *b); /* magnitude comparison */ -int s_mp_cmp_d(mp_int *a, mp_digit d); /* magnitude digit compare */ -int s_mp_ispow2(mp_int *v); /* is v a power of 2? */ -int s_mp_ispow2d(mp_digit d); /* is d a power of 2? */ - -int s_mp_tovalue(char ch, int r); /* convert ch to value */ -char s_mp_todigit(int val, int r, int low); /* convert val to digit */ -int s_mp_outlen(int bits, int r); /* output length in bytes */ - -/* }}} */ - -/* {{{ Default precision manipulation */ - -unsigned int mp_get_prec(void) -{ - return s_mp_defprec; - -} /* end mp_get_prec() */ - -void mp_set_prec(unsigned int prec) -{ - if(prec == 0) - s_mp_defprec = MP_DEFPREC; - else - s_mp_defprec = prec; - -} /* end mp_set_prec() */ - -/* }}} */ - -/*------------------------------------------------------------------------*/ -/* {{{ mp_init(mp) */ - -/* - mp_init(mp) - - Initialize a new zero-valued mp_int. Returns MP_OKAY if successful, - MP_MEM if memory could not be allocated for the structure. - */ - -mp_err mp_init(mp_int *mp) -{ - return mp_init_size(mp, s_mp_defprec); - -} /* end mp_init() */ - -/* }}} */ - -/* {{{ mp_init_array(mp[], count) */ - -mp_err mp_init_array(mp_int mp[], int count) -{ - mp_err res; - int pos; - - ARGCHK(mp !=NULL && count > 0, MP_BADARG); - - for(pos = 0; pos < count; ++pos) { - if((res = mp_init(&mp[pos])) != MP_OKAY) - goto CLEANUP; - } - - return MP_OKAY; - - CLEANUP: - while(--pos >= 0) - mp_clear(&mp[pos]); - - return res; - -} /* end mp_init_array() */ - -/* }}} */ - -/* {{{ mp_init_size(mp, prec) */ - -/* - mp_init_size(mp, prec) - - Initialize a new zero-valued mp_int with at least the given - precision; returns MP_OKAY if successful, or MP_MEM if memory could - not be allocated for the structure. - */ - -mp_err mp_init_size(mp_int *mp, mp_size prec) -{ - ARGCHK(mp != NULL && prec > 0, MP_BADARG); - - if((DIGITS(mp) = s_mp_alloc(prec, sizeof(mp_digit))) == NULL) - return MP_MEM; - - SIGN(mp) = MP_ZPOS; - USED(mp) = 1; - ALLOC(mp) = prec; - - return MP_OKAY; - -} /* end mp_init_size() */ - -/* }}} */ - -/* {{{ mp_init_copy(mp, from) */ - -/* - mp_init_copy(mp, from) - - Initialize mp as an exact copy of from. Returns MP_OKAY if - successful, MP_MEM if memory could not be allocated for the new - structure. - */ - -mp_err mp_init_copy(mp_int *mp, mp_int *from) -{ - ARGCHK(mp != NULL && from != NULL, MP_BADARG); - - if(mp == from) - return MP_OKAY; - - if((DIGITS(mp) = s_mp_alloc(USED(from), sizeof(mp_digit))) == NULL) - return MP_MEM; - - s_mp_copy(DIGITS(from), DIGITS(mp), USED(from)); - USED(mp) = USED(from); - ALLOC(mp) = USED(from); - SIGN(mp) = SIGN(from); - - return MP_OKAY; - -} /* end mp_init_copy() */ - -/* }}} */ - -/* {{{ mp_copy(from, to) */ - -/* - mp_copy(from, to) - - Copies the mp_int 'from' to the mp_int 'to'. It is presumed that - 'to' has already been initialized (if not, use mp_init_copy() - instead). If 'from' and 'to' are identical, nothing happens. - */ - -mp_err mp_copy(mp_int *from, mp_int *to) -{ - ARGCHK(from != NULL && to != NULL, MP_BADARG); - - if(from == to) - return MP_OKAY; - - { /* copy */ - mp_digit *tmp; - - /* - If the allocated buffer in 'to' already has enough space to hold - all the used digits of 'from', we'll re-use it to avoid hitting - the memory allocater more than necessary; otherwise, we'd have - to grow anyway, so we just allocate a hunk and make the copy as - usual - */ - if(ALLOC(to) >= USED(from)) { - s_mp_setz(DIGITS(to) + USED(from), ALLOC(to) - USED(from)); - s_mp_copy(DIGITS(from), DIGITS(to), USED(from)); - - } else { - if((tmp = s_mp_alloc(USED(from), sizeof(mp_digit))) == NULL) - return MP_MEM; - - s_mp_copy(DIGITS(from), tmp, USED(from)); - - if(DIGITS(to) != NULL) { -#if MP_CRYPTO - s_mp_setz(DIGITS(to), ALLOC(to)); -#endif - s_mp_free(DIGITS(to)); - } - - DIGITS(to) = tmp; - ALLOC(to) = USED(from); - } - - /* Copy the precision and sign from the original */ - USED(to) = USED(from); - SIGN(to) = SIGN(from); - } /* end copy */ - - return MP_OKAY; - -} /* end mp_copy() */ - -/* }}} */ - -/* {{{ mp_exch(mp1, mp2) */ - -/* - mp_exch(mp1, mp2) - - Exchange mp1 and mp2 without allocating any intermediate memory - (well, unless you count the stack space needed for this call and the - locals it creates...). This cannot fail. - */ - -void mp_exch(mp_int *mp1, mp_int *mp2) -{ -#if MP_ARGCHK == 2 - assert(mp1 != NULL && mp2 != NULL); -#else - if(mp1 == NULL || mp2 == NULL) - return; -#endif - - s_mp_exch(mp1, mp2); - -} /* end mp_exch() */ - -/* }}} */ - -/* {{{ mp_clear(mp) */ - -/* - mp_clear(mp) - - Release the storage used by an mp_int, and void its fields so that - if someone calls mp_clear() again for the same int later, we won't - get tollchocked. - */ - -void mp_clear(mp_int *mp) -{ - if(mp == NULL) - return; - - if(DIGITS(mp) != NULL) { -#if MP_CRYPTO - s_mp_setz(DIGITS(mp), ALLOC(mp)); -#endif - s_mp_free(DIGITS(mp)); - DIGITS(mp) = NULL; - } - - USED(mp) = 0; - ALLOC(mp) = 0; - -} /* end mp_clear() */ - -/* }}} */ - -/* {{{ mp_clear_array(mp[], count) */ - -void mp_clear_array(mp_int mp[], int count) -{ - ARGCHK(mp != NULL && count > 0, MP_BADARG); - - while(--count >= 0) - mp_clear(&mp[count]); - -} /* end mp_clear_array() */ - -/* }}} */ - -/* {{{ mp_zero(mp) */ - -/* - mp_zero(mp) - - Set mp to zero. Does not change the allocated size of the structure, - and therefore cannot fail (except on a bad argument, which we ignore) - */ -void mp_zero(mp_int *mp) -{ - if(mp == NULL) - return; - - s_mp_setz(DIGITS(mp), ALLOC(mp)); - USED(mp) = 1; - SIGN(mp) = MP_ZPOS; - -} /* end mp_zero() */ - -/* }}} */ - -/* {{{ mp_set(mp, d) */ - -void mp_set(mp_int *mp, mp_digit d) -{ - if(mp == NULL) - return; - - mp_zero(mp); - DIGIT(mp, 0) = d; - -} /* end mp_set() */ - -/* }}} */ - -/* {{{ mp_set_int(mp, z) */ - -mp_err mp_set_int(mp_int *mp, long z) -{ - int ix; - unsigned long v = abs(z); - mp_err res; - - ARGCHK(mp != NULL, MP_BADARG); - - mp_zero(mp); - if(z == 0) - return MP_OKAY; /* shortcut for zero */ - - for(ix = sizeof(long) - 1; ix >= 0; ix--) { - - if((res = s_mp_mul_2d(mp, CHAR_BIT)) != MP_OKAY) - return res; - - res = s_mp_add_d(mp, - (mp_digit)((v >> (ix * CHAR_BIT)) & UCHAR_MAX)); - if(res != MP_OKAY) - return res; - - } - - if(z < 0) - SIGN(mp) = MP_NEG; - - return MP_OKAY; - -} /* end mp_set_int() */ - -/* }}} */ - -/*------------------------------------------------------------------------*/ -/* {{{ Digit arithmetic */ - -/* {{{ mp_add_d(a, d, b) */ - -/* - mp_add_d(a, d, b) - - Compute the sum b = a + d, for a single digit d. Respects the sign of - its primary addend (single digits are unsigned anyway). - */ - -mp_err mp_add_d(mp_int *a, mp_digit d, mp_int *b) -{ - mp_err res = MP_OKAY; - - ARGCHK(a != NULL && b != NULL, MP_BADARG); - - if((res = mp_copy(a, b)) != MP_OKAY) - return res; - - if(SIGN(b) == MP_ZPOS) { - res = s_mp_add_d(b, d); - } else if(s_mp_cmp_d(b, d) >= 0) { - res = s_mp_sub_d(b, d); - } else { - SIGN(b) = MP_ZPOS; - - DIGIT(b, 0) = d - DIGIT(b, 0); - } - - return res; - -} /* end mp_add_d() */ - -/* }}} */ - -/* {{{ mp_sub_d(a, d, b) */ - -/* - mp_sub_d(a, d, b) - - Compute the difference b = a - d, for a single digit d. Respects the - sign of its subtrahend (single digits are unsigned anyway). - */ - -mp_err mp_sub_d(mp_int *a, mp_digit d, mp_int *b) -{ - mp_err res; - - ARGCHK(a != NULL && b != NULL, MP_BADARG); - - if((res = mp_copy(a, b)) != MP_OKAY) - return res; - - if(SIGN(b) == MP_NEG) { - if((res = s_mp_add_d(b, d)) != MP_OKAY) - return res; - - } else if(s_mp_cmp_d(b, d) >= 0) { - if((res = s_mp_sub_d(b, d)) != MP_OKAY) - return res; - - } else { - mp_neg(b, b); - - DIGIT(b, 0) = d - DIGIT(b, 0); - SIGN(b) = MP_NEG; - } - - if(s_mp_cmp_d(b, 0) == 0) - SIGN(b) = MP_ZPOS; - - return MP_OKAY; - -} /* end mp_sub_d() */ - -/* }}} */ - -/* {{{ mp_mul_d(a, d, b) */ - -/* - mp_mul_d(a, d, b) - - Compute the product b = a * d, for a single digit d. Respects the sign - of its multiplicand (single digits are unsigned anyway) - */ - -mp_err mp_mul_d(mp_int *a, mp_digit d, mp_int *b) -{ - mp_err res; - - ARGCHK(a != NULL && b != NULL, MP_BADARG); - - if(d == 0) { - mp_zero(b); - return MP_OKAY; - } - - if((res = mp_copy(a, b)) != MP_OKAY) - return res; - - res = s_mp_mul_d(b, d); - - return res; - -} /* end mp_mul_d() */ - -/* }}} */ - -/* {{{ mp_mul_2(a, c) */ - -mp_err mp_mul_2(mp_int *a, mp_int *c) -{ - mp_err res; - - ARGCHK(a != NULL && c != NULL, MP_BADARG); - - if((res = mp_copy(a, c)) != MP_OKAY) - return res; - - return s_mp_mul_2(c); - -} /* end mp_mul_2() */ - -/* }}} */ - -/* {{{ mp_div_d(a, d, q, r) */ - -/* - mp_div_d(a, d, q, r) - - Compute the quotient q = a / d and remainder r = a mod d, for a - single digit d. Respects the sign of its divisor (single digits are - unsigned anyway). - */ - -mp_err mp_div_d(mp_int *a, mp_digit d, mp_int *q, mp_digit *r) -{ - mp_err res; - mp_digit rem; - int pow; - - ARGCHK(a != NULL, MP_BADARG); - - if(d == 0) - return MP_RANGE; - - /* Shortcut for powers of two ... */ - if((pow = s_mp_ispow2d(d)) >= 0) { - mp_digit mask; - - mask = (1 << pow) - 1; - rem = DIGIT(a, 0) & mask; - - if(q) { - mp_copy(a, q); - s_mp_div_2d(q, pow); - } - - if(r) - *r = rem; - - return MP_OKAY; - } - - /* - If the quotient is actually going to be returned, we'll try to - avoid hitting the memory allocator by copying the dividend into it - and doing the division there. This can't be any _worse_ than - always copying, and will sometimes be better (since it won't make - another copy) - - If it's not going to be returned, we need to allocate a temporary - to hold the quotient, which will just be discarded. - */ - if(q) { - if((res = mp_copy(a, q)) != MP_OKAY) - return res; - - res = s_mp_div_d(q, d, &rem); - if(s_mp_cmp_d(q, 0) == MP_EQ) - SIGN(q) = MP_ZPOS; - - } else { - mp_int qp; - - if((res = mp_init_copy(&qp, a)) != MP_OKAY) - return res; - - res = s_mp_div_d(&qp, d, &rem); - if(s_mp_cmp_d(&qp, 0) == 0) - SIGN(&qp) = MP_ZPOS; - - mp_clear(&qp); - } - - if(r) - *r = rem; - - return res; - -} /* end mp_div_d() */ - -/* }}} */ - -/* {{{ mp_div_2(a, c) */ - -/* - mp_div_2(a, c) - - Compute c = a / 2, disregarding the remainder. - */ - -mp_err mp_div_2(mp_int *a, mp_int *c) -{ - mp_err res; - - ARGCHK(a != NULL && c != NULL, MP_BADARG); - - if((res = mp_copy(a, c)) != MP_OKAY) - return res; - - s_mp_div_2(c); - - return MP_OKAY; - -} /* end mp_div_2() */ - -/* }}} */ - -/* {{{ mp_expt_d(a, d, b) */ - -mp_err mp_expt_d(mp_int *a, mp_digit d, mp_int *c) -{ - mp_int s, x; - mp_err res; - - ARGCHK(a != NULL && c != NULL, MP_BADARG); - - if((res = mp_init(&s)) != MP_OKAY) - return res; - if((res = mp_init_copy(&x, a)) != MP_OKAY) - goto X; - - DIGIT(&s, 0) = 1; - - while(d != 0) { - if(d & 1) { - if((res = s_mp_mul(&s, &x)) != MP_OKAY) - goto CLEANUP; - } - - d >>= 1; - - if((res = s_mp_sqr(&x)) != MP_OKAY) - goto CLEANUP; - } - - s_mp_exch(&s, c); - -CLEANUP: - mp_clear(&x); -X: - mp_clear(&s); - - return res; - -} /* end mp_expt_d() */ - -/* }}} */ - -/* }}} */ - -/*------------------------------------------------------------------------*/ -/* {{{ Full arithmetic */ - -/* {{{ mp_abs(a, b) */ - -/* - mp_abs(a, b) - - Compute b = |a|. 'a' and 'b' may be identical. - */ - -mp_err mp_abs(mp_int *a, mp_int *b) -{ - mp_err res; - - ARGCHK(a != NULL && b != NULL, MP_BADARG); - - if((res = mp_copy(a, b)) != MP_OKAY) - return res; - - SIGN(b) = MP_ZPOS; - - return MP_OKAY; - -} /* end mp_abs() */ - -/* }}} */ - -/* {{{ mp_neg(a, b) */ - -/* - mp_neg(a, b) - - Compute b = -a. 'a' and 'b' may be identical. - */ - -mp_err mp_neg(mp_int *a, mp_int *b) -{ - mp_err res; - - ARGCHK(a != NULL && b != NULL, MP_BADARG); - - if((res = mp_copy(a, b)) != MP_OKAY) - return res; - - if(s_mp_cmp_d(b, 0) == MP_EQ) - SIGN(b) = MP_ZPOS; - else - SIGN(b) = (SIGN(b) == MP_NEG) ? MP_ZPOS : MP_NEG; - - return MP_OKAY; - -} /* end mp_neg() */ - -/* }}} */ - -/* {{{ mp_add(a, b, c) */ - -/* - mp_add(a, b, c) - - Compute c = a + b. All parameters may be identical. - */ - -mp_err mp_add(mp_int *a, mp_int *b, mp_int *c) -{ - mp_err res; - int cmp; - - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - - if(SIGN(a) == SIGN(b)) { /* same sign: add values, keep sign */ - - /* Commutativity of addition lets us do this in either order, - so we avoid having to use a temporary even if the result - is supposed to replace the output - */ - if(c == b) { - if((res = s_mp_add(c, a)) != MP_OKAY) - return res; - } else { - if(c != a && (res = mp_copy(a, c)) != MP_OKAY) - return res; - - if((res = s_mp_add(c, b)) != MP_OKAY) - return res; - } - - } else if((cmp = s_mp_cmp(a, b)) > 0) { /* different sign: a > b */ - - /* If the output is going to be clobbered, we will use a temporary - variable; otherwise, we'll do it without touching the memory - allocator at all, if possible - */ - if(c == b) { - mp_int tmp; - - if((res = mp_init_copy(&tmp, a)) != MP_OKAY) - return res; - if((res = s_mp_sub(&tmp, b)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - - s_mp_exch(&tmp, c); - mp_clear(&tmp); - - } else { - - if(c != a && (res = mp_copy(a, c)) != MP_OKAY) - return res; - if((res = s_mp_sub(c, b)) != MP_OKAY) - return res; - - } - - } else if(cmp == 0) { /* different sign, a == b */ - - mp_zero(c); - return MP_OKAY; - - } else { /* different sign: a < b */ - - /* See above... */ - if(c == a) { - mp_int tmp; - - if((res = mp_init_copy(&tmp, b)) != MP_OKAY) - return res; - if((res = s_mp_sub(&tmp, a)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - - s_mp_exch(&tmp, c); - mp_clear(&tmp); - - } else { - - if(c != b && (res = mp_copy(b, c)) != MP_OKAY) - return res; - if((res = s_mp_sub(c, a)) != MP_OKAY) - return res; - - } - } - - if(USED(c) == 1 && DIGIT(c, 0) == 0) - SIGN(c) = MP_ZPOS; - - return MP_OKAY; - -} /* end mp_add() */ - -/* }}} */ - -/* {{{ mp_sub(a, b, c) */ - -/* - mp_sub(a, b, c) - - Compute c = a - b. All parameters may be identical. - */ - -mp_err mp_sub(mp_int *a, mp_int *b, mp_int *c) -{ - mp_err res; - int cmp; - - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - - if(SIGN(a) != SIGN(b)) { - if(c == a) { - if((res = s_mp_add(c, b)) != MP_OKAY) - return res; - } else { - if(c != b && ((res = mp_copy(b, c)) != MP_OKAY)) - return res; - if((res = s_mp_add(c, a)) != MP_OKAY) - return res; - SIGN(c) = SIGN(a); - } - - } else if((cmp = s_mp_cmp(a, b)) > 0) { /* Same sign, a > b */ - if(c == b) { - mp_int tmp; - - if((res = mp_init_copy(&tmp, a)) != MP_OKAY) - return res; - if((res = s_mp_sub(&tmp, b)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - s_mp_exch(&tmp, c); - mp_clear(&tmp); - - } else { - if(c != a && ((res = mp_copy(a, c)) != MP_OKAY)) - return res; - - if((res = s_mp_sub(c, b)) != MP_OKAY) - return res; - } - - } else if(cmp == 0) { /* Same sign, equal magnitude */ - mp_zero(c); - return MP_OKAY; - - } else { /* Same sign, b > a */ - if(c == a) { - mp_int tmp; - - if((res = mp_init_copy(&tmp, b)) != MP_OKAY) - return res; - - if((res = s_mp_sub(&tmp, a)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - s_mp_exch(&tmp, c); - mp_clear(&tmp); - - } else { - if(c != b && ((res = mp_copy(b, c)) != MP_OKAY)) - return res; - - if((res = s_mp_sub(c, a)) != MP_OKAY) - return res; - } - - SIGN(c) = !SIGN(b); - } - - if(USED(c) == 1 && DIGIT(c, 0) == 0) - SIGN(c) = MP_ZPOS; - - return MP_OKAY; - -} /* end mp_sub() */ - -/* }}} */ - -/* {{{ mp_mul(a, b, c) */ - -/* - mp_mul(a, b, c) - - Compute c = a * b. All parameters may be identical. - */ - -mp_err mp_mul(mp_int *a, mp_int *b, mp_int *c) -{ - mp_err res; - mp_sign sgn; - - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - - sgn = (SIGN(a) == SIGN(b)) ? MP_ZPOS : MP_NEG; - - if(c == b) { - if((res = s_mp_mul(c, a)) != MP_OKAY) - return res; - - } else { - if((res = mp_copy(a, c)) != MP_OKAY) - return res; - - if((res = s_mp_mul(c, b)) != MP_OKAY) - return res; - } - - if(sgn == MP_ZPOS || s_mp_cmp_d(c, 0) == MP_EQ) - SIGN(c) = MP_ZPOS; - else - SIGN(c) = sgn; - - return MP_OKAY; - -} /* end mp_mul() */ - -/* }}} */ - -/* {{{ mp_mul_2d(a, d, c) */ - -/* - mp_mul_2d(a, d, c) - - Compute c = a * 2^d. a may be the same as c. - */ - -mp_err mp_mul_2d(mp_int *a, mp_digit d, mp_int *c) -{ - mp_err res; - - ARGCHK(a != NULL && c != NULL, MP_BADARG); - - if((res = mp_copy(a, c)) != MP_OKAY) - return res; - - if(d == 0) - return MP_OKAY; - - return s_mp_mul_2d(c, d); - -} /* end mp_mul() */ - -/* }}} */ - -/* {{{ mp_sqr(a, b) */ - -#if MP_SQUARE -mp_err mp_sqr(mp_int *a, mp_int *b) -{ - mp_err res; - - ARGCHK(a != NULL && b != NULL, MP_BADARG); - - if((res = mp_copy(a, b)) != MP_OKAY) - return res; - - if((res = s_mp_sqr(b)) != MP_OKAY) - return res; - - SIGN(b) = MP_ZPOS; - - return MP_OKAY; - -} /* end mp_sqr() */ -#endif - -/* }}} */ - -/* {{{ mp_div(a, b, q, r) */ - -/* - mp_div(a, b, q, r) - - Compute q = a / b and r = a mod b. Input parameters may be re-used - as output parameters. If q or r is NULL, that portion of the - computation will be discarded (although it will still be computed) - - Pay no attention to the hacker behind the curtain. - */ - -mp_err mp_div(mp_int *a, mp_int *b, mp_int *q, mp_int *r) -{ - mp_err res; - mp_int qtmp, rtmp; - int cmp; - - ARGCHK(a != NULL && b != NULL, MP_BADARG); - - if(mp_cmp_z(b) == MP_EQ) - return MP_RANGE; - - /* If a <= b, we can compute the solution without division, and - avoid any memory allocation - */ - if((cmp = s_mp_cmp(a, b)) < 0) { - if(r) { - if((res = mp_copy(a, r)) != MP_OKAY) - return res; - } - - if(q) - mp_zero(q); - - return MP_OKAY; - - } else if(cmp == 0) { - - /* Set quotient to 1, with appropriate sign */ - if(q) { - int qneg = (SIGN(a) != SIGN(b)); - - mp_set(q, 1); - if(qneg) - SIGN(q) = MP_NEG; - } - - if(r) - mp_zero(r); - - return MP_OKAY; - } - - /* If we get here, it means we actually have to do some division */ - - /* Set up some temporaries... */ - if((res = mp_init_copy(&qtmp, a)) != MP_OKAY) - return res; - if((res = mp_init_copy(&rtmp, b)) != MP_OKAY) - goto CLEANUP; - - if((res = s_mp_div(&qtmp, &rtmp)) != MP_OKAY) - goto CLEANUP; - - /* Compute the signs for the output */ - SIGN(&rtmp) = SIGN(a); /* Sr = Sa */ - if(SIGN(a) == SIGN(b)) - SIGN(&qtmp) = MP_ZPOS; /* Sq = MP_ZPOS if Sa = Sb */ - else - SIGN(&qtmp) = MP_NEG; /* Sq = MP_NEG if Sa != Sb */ - - if(s_mp_cmp_d(&qtmp, 0) == MP_EQ) - SIGN(&qtmp) = MP_ZPOS; - if(s_mp_cmp_d(&rtmp, 0) == MP_EQ) - SIGN(&rtmp) = MP_ZPOS; - - /* Copy output, if it is needed */ - if(q) - s_mp_exch(&qtmp, q); - - if(r) - s_mp_exch(&rtmp, r); - -CLEANUP: - mp_clear(&rtmp); - mp_clear(&qtmp); - - return res; - -} /* end mp_div() */ - -/* }}} */ - -/* {{{ mp_div_2d(a, d, q, r) */ - -mp_err mp_div_2d(mp_int *a, mp_digit d, mp_int *q, mp_int *r) -{ - mp_err res; - - ARGCHK(a != NULL, MP_BADARG); - - if(q) { - if((res = mp_copy(a, q)) != MP_OKAY) - return res; - - s_mp_div_2d(q, d); - } - - if(r) { - if((res = mp_copy(a, r)) != MP_OKAY) - return res; - - s_mp_mod_2d(r, d); - } - - return MP_OKAY; - -} /* end mp_div_2d() */ - -/* }}} */ - -/* {{{ mp_expt(a, b, c) */ - -/* - mp_expt(a, b, c) - - Compute c = a ** b, that is, raise a to the b power. Uses a - standard iterative square-and-multiply technique. - */ - -mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c) -{ - mp_int s, x; - mp_err res; - mp_digit d; - unsigned int bit, dig; - - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - - if(mp_cmp_z(b) < 0) - return MP_RANGE; - - if((res = mp_init(&s)) != MP_OKAY) - return res; - - mp_set(&s, 1); - - if((res = mp_init_copy(&x, a)) != MP_OKAY) - goto X; - - /* Loop over low-order digits in ascending order */ - for(dig = 0; dig < (USED(b) - 1); dig++) { - d = DIGIT(b, dig); - - /* Loop over bits of each non-maximal digit */ - for(bit = 0; bit < DIGIT_BIT; bit++) { - if(d & 1) { - if((res = s_mp_mul(&s, &x)) != MP_OKAY) - goto CLEANUP; - } - - d >>= 1; - - if((res = s_mp_sqr(&x)) != MP_OKAY) - goto CLEANUP; - } - } - - /* Consider now the last digit... */ - d = DIGIT(b, dig); - - while(d) { - if(d & 1) { - if((res = s_mp_mul(&s, &x)) != MP_OKAY) - goto CLEANUP; - } - - d >>= 1; - - if((res = s_mp_sqr(&x)) != MP_OKAY) - goto CLEANUP; - } - - if(mp_iseven(b)) - SIGN(&s) = SIGN(a); - - res = mp_copy(&s, c); - -CLEANUP: - mp_clear(&x); -X: - mp_clear(&s); - - return res; - -} /* end mp_expt() */ - -/* }}} */ - -/* {{{ mp_2expt(a, k) */ - -/* Compute a = 2^k */ - -mp_err mp_2expt(mp_int *a, mp_digit k) -{ - ARGCHK(a != NULL, MP_BADARG); - - return s_mp_2expt(a, k); - -} /* end mp_2expt() */ - -/* }}} */ - -/* {{{ mp_mod(a, m, c) */ - -/* - mp_mod(a, m, c) - - Compute c = a (mod m). Result will always be 0 <= c < m. - */ - -mp_err mp_mod(mp_int *a, mp_int *m, mp_int *c) -{ - mp_err res; - int mag; - - ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG); - - if(SIGN(m) == MP_NEG) - return MP_RANGE; - - /* - If |a| > m, we need to divide to get the remainder and take the - absolute value. - - If |a| < m, we don't need to do any division, just copy and adjust - the sign (if a is negative). - - If |a| == m, we can simply set the result to zero. - - This order is intended to minimize the average path length of the - comparison chain on common workloads -- the most frequent cases are - that |a| != m, so we do those first. - */ - if((mag = s_mp_cmp(a, m)) > 0) { - if((res = mp_div(a, m, NULL, c)) != MP_OKAY) - return res; - - if(SIGN(c) == MP_NEG) { - if((res = mp_add(c, m, c)) != MP_OKAY) - return res; - } - - } else if(mag < 0) { - if((res = mp_copy(a, c)) != MP_OKAY) - return res; - - if(mp_cmp_z(a) < 0) { - if((res = mp_add(c, m, c)) != MP_OKAY) - return res; - - } - - } else { - mp_zero(c); - - } - - return MP_OKAY; - -} /* end mp_mod() */ - -/* }}} */ - -/* {{{ mp_mod_d(a, d, c) */ - -/* - mp_mod_d(a, d, c) - - Compute c = a (mod d). Result will always be 0 <= c < d - */ -mp_err mp_mod_d(mp_int *a, mp_digit d, mp_digit *c) -{ - mp_err res; - mp_digit rem; - - ARGCHK(a != NULL && c != NULL, MP_BADARG); - - if(s_mp_cmp_d(a, d) > 0) { - if((res = mp_div_d(a, d, NULL, &rem)) != MP_OKAY) - return res; - - } else { - if(SIGN(a) == MP_NEG) - rem = d - DIGIT(a, 0); - else - rem = DIGIT(a, 0); - } - - if(c) - *c = rem; - - return MP_OKAY; - -} /* end mp_mod_d() */ - -/* }}} */ - -/* {{{ mp_sqrt(a, b) */ - -/* - mp_sqrt(a, b) - - Compute the integer square root of a, and store the result in b. - Uses an integer-arithmetic version of Newton's iterative linear - approximation technique to determine this value; the result has the - following two properties: - - b^2 <= a - (b+1)^2 >= a - - It is a range error to pass a negative value. - */ -mp_err mp_sqrt(mp_int *a, mp_int *b) -{ - mp_int x, t; - mp_err res; - - ARGCHK(a != NULL && b != NULL, MP_BADARG); - - /* Cannot take square root of a negative value */ - if(SIGN(a) == MP_NEG) - return MP_RANGE; - - /* Special cases for zero and one, trivial */ - if(mp_cmp_d(a, 0) == MP_EQ || mp_cmp_d(a, 1) == MP_EQ) - return mp_copy(a, b); - - /* Initialize the temporaries we'll use below */ - if((res = mp_init_size(&t, USED(a))) != MP_OKAY) - return res; - - /* Compute an initial guess for the iteration as a itself */ - if((res = mp_init_copy(&x, a)) != MP_OKAY) - goto X; - -s_mp_rshd(&x, (USED(&x)/2)+1); -mp_add_d(&x, 1, &x); - - for(;;) { - /* t = (x * x) - a */ - mp_copy(&x, &t); /* can't fail, t is big enough for original x */ - if((res = mp_sqr(&t, &t)) != MP_OKAY || - (res = mp_sub(&t, a, &t)) != MP_OKAY) - goto CLEANUP; - - /* t = t / 2x */ - s_mp_mul_2(&x); - if((res = mp_div(&t, &x, &t, NULL)) != MP_OKAY) - goto CLEANUP; - s_mp_div_2(&x); - - /* Terminate the loop, if the quotient is zero */ - if(mp_cmp_z(&t) == MP_EQ) - break; - - /* x = x - t */ - if((res = mp_sub(&x, &t, &x)) != MP_OKAY) - goto CLEANUP; - - } - - /* Copy result to output parameter */ - mp_sub_d(&x, 1, &x); - s_mp_exch(&x, b); - - CLEANUP: - mp_clear(&x); - X: - mp_clear(&t); - - return res; - -} /* end mp_sqrt() */ - -/* }}} */ - -/* }}} */ - -/*------------------------------------------------------------------------*/ -/* {{{ Modular arithmetic */ - -#if MP_MODARITH -/* {{{ mp_addmod(a, b, m, c) */ - -/* - mp_addmod(a, b, m, c) - - Compute c = (a + b) mod m - */ - -mp_err mp_addmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c) -{ - mp_err res; - - ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG); - - if((res = mp_add(a, b, c)) != MP_OKAY) - return res; - if((res = mp_mod(c, m, c)) != MP_OKAY) - return res; - - return MP_OKAY; - -} - -/* }}} */ - -/* {{{ mp_submod(a, b, m, c) */ - -/* - mp_submod(a, b, m, c) - - Compute c = (a - b) mod m - */ - -mp_err mp_submod(mp_int *a, mp_int *b, mp_int *m, mp_int *c) -{ - mp_err res; - - ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG); - - if((res = mp_sub(a, b, c)) != MP_OKAY) - return res; - if((res = mp_mod(c, m, c)) != MP_OKAY) - return res; - - return MP_OKAY; - -} - -/* }}} */ - -/* {{{ mp_mulmod(a, b, m, c) */ - -/* - mp_mulmod(a, b, m, c) - - Compute c = (a * b) mod m - */ - -mp_err mp_mulmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c) -{ - mp_err res; - - ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG); - - if((res = mp_mul(a, b, c)) != MP_OKAY) - return res; - if((res = mp_mod(c, m, c)) != MP_OKAY) - return res; - - return MP_OKAY; - -} - -/* }}} */ - -/* {{{ mp_sqrmod(a, m, c) */ - -#if MP_SQUARE -mp_err mp_sqrmod(mp_int *a, mp_int *m, mp_int *c) -{ - mp_err res; - - ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG); - - if((res = mp_sqr(a, c)) != MP_OKAY) - return res; - if((res = mp_mod(c, m, c)) != MP_OKAY) - return res; - - return MP_OKAY; - -} /* end mp_sqrmod() */ -#endif - -/* }}} */ - -/* {{{ mp_exptmod(a, b, m, c) */ - -/* - mp_exptmod(a, b, m, c) - - Compute c = (a ** b) mod m. Uses a standard square-and-multiply - method with modular reductions at each step. (This is basically the - same code as mp_expt(), except for the addition of the reductions) - - The modular reductions are done using Barrett's algorithm (see - s_mp_reduce() below for details) - */ - -mp_err mp_exptmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c) -{ - mp_int s, x, mu; - mp_err res; - mp_digit d, *db = DIGITS(b); - mp_size ub = USED(b); - unsigned int bit, dig; - - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - - if(mp_cmp_z(b) < 0 || mp_cmp_z(m) <= 0) - return MP_RANGE; - - if((res = mp_init(&s)) != MP_OKAY) - return res; - if((res = mp_init_copy(&x, a)) != MP_OKAY) - goto X; - if((res = mp_mod(&x, m, &x)) != MP_OKAY || - (res = mp_init(&mu)) != MP_OKAY) - goto MU; - - mp_set(&s, 1); - - /* mu = b^2k / m */ - s_mp_add_d(&mu, 1); - s_mp_lshd(&mu, 2 * USED(m)); - if((res = mp_div(&mu, m, &mu, NULL)) != MP_OKAY) - goto CLEANUP; - - /* Loop over digits of b in ascending order, except highest order */ - for(dig = 0; dig < (ub - 1); dig++) { - d = *db++; - - /* Loop over the bits of the lower-order digits */ - for(bit = 0; bit < DIGIT_BIT; bit++) { - if(d & 1) { - if((res = s_mp_mul(&s, &x)) != MP_OKAY) - goto CLEANUP; - if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY) - goto CLEANUP; - } - - d >>= 1; - - if((res = s_mp_sqr(&x)) != MP_OKAY) - goto CLEANUP; - if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY) - goto CLEANUP; - } - } - - /* Now do the last digit... */ - d = *db; - - while(d) { - if(d & 1) { - if((res = s_mp_mul(&s, &x)) != MP_OKAY) - goto CLEANUP; - if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY) - goto CLEANUP; - } - - d >>= 1; - - if((res = s_mp_sqr(&x)) != MP_OKAY) - goto CLEANUP; - if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY) - goto CLEANUP; - } - - s_mp_exch(&s, c); - - CLEANUP: - mp_clear(&mu); - MU: - mp_clear(&x); - X: - mp_clear(&s); - - return res; - -} /* end mp_exptmod() */ - -/* }}} */ - -/* {{{ mp_exptmod_d(a, d, m, c) */ - -mp_err mp_exptmod_d(mp_int *a, mp_digit d, mp_int *m, mp_int *c) -{ - mp_int s, x; - mp_err res; - - ARGCHK(a != NULL && c != NULL, MP_BADARG); - - if((res = mp_init(&s)) != MP_OKAY) - return res; - if((res = mp_init_copy(&x, a)) != MP_OKAY) - goto X; - - mp_set(&s, 1); - - while(d != 0) { - if(d & 1) { - if((res = s_mp_mul(&s, &x)) != MP_OKAY || - (res = mp_mod(&s, m, &s)) != MP_OKAY) - goto CLEANUP; - } - - d /= 2; - - if((res = s_mp_sqr(&x)) != MP_OKAY || - (res = mp_mod(&x, m, &x)) != MP_OKAY) - goto CLEANUP; - } - - s_mp_exch(&s, c); - -CLEANUP: - mp_clear(&x); -X: - mp_clear(&s); - - return res; - -} /* end mp_exptmod_d() */ - -/* }}} */ -#endif /* if MP_MODARITH */ - -/* }}} */ - -/*------------------------------------------------------------------------*/ -/* {{{ Comparison functions */ - -/* {{{ mp_cmp_z(a) */ - -/* - mp_cmp_z(a) - - Compare a <=> 0. Returns <0 if a<0, 0 if a=0, >0 if a>0. - */ - -int mp_cmp_z(mp_int *a) -{ - if(SIGN(a) == MP_NEG) - return MP_LT; - else if(USED(a) == 1 && DIGIT(a, 0) == 0) - return MP_EQ; - else - return MP_GT; - -} /* end mp_cmp_z() */ - -/* }}} */ - -/* {{{ mp_cmp_d(a, d) */ - -/* - mp_cmp_d(a, d) - - Compare a <=> d. Returns <0 if a<d, 0 if a=d, >0 if a>d - */ - -int mp_cmp_d(mp_int *a, mp_digit d) -{ - ARGCHK(a != NULL, MP_EQ); - - if(SIGN(a) == MP_NEG) - return MP_LT; - - return s_mp_cmp_d(a, d); - -} /* end mp_cmp_d() */ - -/* }}} */ - -/* {{{ mp_cmp(a, b) */ - -int mp_cmp(mp_int *a, mp_int *b) -{ - ARGCHK(a != NULL && b != NULL, MP_EQ); - - if(SIGN(a) == SIGN(b)) { - int mag; - - if((mag = s_mp_cmp(a, b)) == MP_EQ) - return MP_EQ; - - if(SIGN(a) == MP_ZPOS) - return mag; - else - return -mag; - - } else if(SIGN(a) == MP_ZPOS) { - return MP_GT; - } else { - return MP_LT; - } - -} /* end mp_cmp() */ - -/* }}} */ - -/* {{{ mp_cmp_mag(a, b) */ - -/* - mp_cmp_mag(a, b) - - Compares |a| <=> |b|, and returns an appropriate comparison result - */ - -int mp_cmp_mag(mp_int *a, mp_int *b) -{ - ARGCHK(a != NULL && b != NULL, MP_EQ); - - return s_mp_cmp(a, b); - -} /* end mp_cmp_mag() */ - -/* }}} */ - -/* {{{ mp_cmp_int(a, z) */ - -/* - This just converts z to an mp_int, and uses the existing comparison - routines. This is sort of inefficient, but it's not clear to me how - frequently this wil get used anyway. For small positive constants, - you can always use mp_cmp_d(), and for zero, there is mp_cmp_z(). - */ -int mp_cmp_int(mp_int *a, long z) -{ - mp_int tmp; - int out; - - ARGCHK(a != NULL, MP_EQ); - - mp_init(&tmp); mp_set_int(&tmp, z); - out = mp_cmp(a, &tmp); - mp_clear(&tmp); - - return out; - -} /* end mp_cmp_int() */ - -/* }}} */ - -/* {{{ mp_isodd(a) */ - -/* - mp_isodd(a) - - Returns a true (non-zero) value if a is odd, false (zero) otherwise. - */ -int mp_isodd(mp_int *a) -{ - ARGCHK(a != NULL, 0); - - return (DIGIT(a, 0) & 1); - -} /* end mp_isodd() */ - -/* }}} */ - -/* {{{ mp_iseven(a) */ - -int mp_iseven(mp_int *a) -{ - return !mp_isodd(a); - -} /* end mp_iseven() */ - -/* }}} */ - -/* }}} */ - -/*------------------------------------------------------------------------*/ -/* {{{ Number theoretic functions */ - -#if MP_NUMTH -/* {{{ mp_gcd(a, b, c) */ - -/* - Like the old mp_gcd() function, except computes the GCD using the - binary algorithm due to Josef Stein in 1961 (via Knuth). - */ -mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c) -{ - mp_err res; - mp_int u, v, t; - mp_size k = 0; - - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - - if(mp_cmp_z(a) == MP_EQ && mp_cmp_z(b) == MP_EQ) - return MP_RANGE; - if(mp_cmp_z(a) == MP_EQ) { - return mp_copy(b, c); - } else if(mp_cmp_z(b) == MP_EQ) { - return mp_copy(a, c); - } - - if((res = mp_init(&t)) != MP_OKAY) - return res; - if((res = mp_init_copy(&u, a)) != MP_OKAY) - goto U; - if((res = mp_init_copy(&v, b)) != MP_OKAY) - goto V; - - SIGN(&u) = MP_ZPOS; - SIGN(&v) = MP_ZPOS; - - /* Divide out common factors of 2 until at least 1 of a, b is even */ - while(mp_iseven(&u) && mp_iseven(&v)) { - s_mp_div_2(&u); - s_mp_div_2(&v); - ++k; - } - - /* Initialize t */ - if(mp_isodd(&u)) { - if((res = mp_copy(&v, &t)) != MP_OKAY) - goto CLEANUP; - - /* t = -v */ - if(SIGN(&v) == MP_ZPOS) - SIGN(&t) = MP_NEG; - else - SIGN(&t) = MP_ZPOS; - - } else { - if((res = mp_copy(&u, &t)) != MP_OKAY) - goto CLEANUP; - - } - - for(;;) { - while(mp_iseven(&t)) { - s_mp_div_2(&t); - } - - if(mp_cmp_z(&t) == MP_GT) { - if((res = mp_copy(&t, &u)) != MP_OKAY) - goto CLEANUP; - - } else { - if((res = mp_copy(&t, &v)) != MP_OKAY) - goto CLEANUP; - - /* v = -t */ - if(SIGN(&t) == MP_ZPOS) - SIGN(&v) = MP_NEG; - else - SIGN(&v) = MP_ZPOS; - } - - if((res = mp_sub(&u, &v, &t)) != MP_OKAY) - goto CLEANUP; - - if(s_mp_cmp_d(&t, 0) == MP_EQ) - break; - } - - s_mp_2expt(&v, k); /* v = 2^k */ - res = mp_mul(&u, &v, c); /* c = u * v */ - - CLEANUP: - mp_clear(&v); - V: - mp_clear(&u); - U: - mp_clear(&t); - - return res; - -} /* end mp_bgcd() */ - -/* }}} */ - -/* {{{ mp_lcm(a, b, c) */ - -/* We compute the least common multiple using the rule: - - ab = [a, b](a, b) - - ... by computing the product, and dividing out the gcd. - */ - -mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c) -{ - mp_int gcd, prod; - mp_err res; - - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - - /* Set up temporaries */ - if((res = mp_init(&gcd)) != MP_OKAY) - return res; - if((res = mp_init(&prod)) != MP_OKAY) - goto GCD; - - if((res = mp_mul(a, b, &prod)) != MP_OKAY) - goto CLEANUP; - if((res = mp_gcd(a, b, &gcd)) != MP_OKAY) - goto CLEANUP; - - res = mp_div(&prod, &gcd, c, NULL); - - CLEANUP: - mp_clear(&prod); - GCD: - mp_clear(&gcd); - - return res; - -} /* end mp_lcm() */ - -/* }}} */ - -/* {{{ mp_xgcd(a, b, g, x, y) */ - -/* - mp_xgcd(a, b, g, x, y) - - Compute g = (a, b) and values x and y satisfying Bezout's identity - (that is, ax + by = g). This uses the extended binary GCD algorithm - based on the Stein algorithm used for mp_gcd() - */ - -mp_err mp_xgcd(mp_int *a, mp_int *b, mp_int *g, mp_int *x, mp_int *y) -{ - mp_int gx, xc, yc, u, v, A, B, C, D; - mp_int *clean[9]; - mp_err res; - int last = -1; - - if(mp_cmp_z(b) == 0) - return MP_RANGE; - - /* Initialize all these variables we need */ - if((res = mp_init(&u)) != MP_OKAY) goto CLEANUP; - clean[++last] = &u; - if((res = mp_init(&v)) != MP_OKAY) goto CLEANUP; - clean[++last] = &v; - if((res = mp_init(&gx)) != MP_OKAY) goto CLEANUP; - clean[++last] = &gx; - if((res = mp_init(&A)) != MP_OKAY) goto CLEANUP; - clean[++last] = &A; - if((res = mp_init(&B)) != MP_OKAY) goto CLEANUP; - clean[++last] = &B; - if((res = mp_init(&C)) != MP_OKAY) goto CLEANUP; - clean[++last] = &C; - if((res = mp_init(&D)) != MP_OKAY) goto CLEANUP; - clean[++last] = &D; - if((res = mp_init_copy(&xc, a)) != MP_OKAY) goto CLEANUP; - clean[++last] = &xc; - mp_abs(&xc, &xc); - if((res = mp_init_copy(&yc, b)) != MP_OKAY) goto CLEANUP; - clean[++last] = &yc; - mp_abs(&yc, &yc); - - mp_set(&gx, 1); - - /* Divide by two until at least one of them is even */ - while(mp_iseven(&xc) && mp_iseven(&yc)) { - s_mp_div_2(&xc); - s_mp_div_2(&yc); - if((res = s_mp_mul_2(&gx)) != MP_OKAY) - goto CLEANUP; - } - - mp_copy(&xc, &u); - mp_copy(&yc, &v); - mp_set(&A, 1); mp_set(&D, 1); - - /* Loop through binary GCD algorithm */ - for(;;) { - while(mp_iseven(&u)) { - s_mp_div_2(&u); - - if(mp_iseven(&A) && mp_iseven(&B)) { - s_mp_div_2(&A); s_mp_div_2(&B); - } else { - if((res = mp_add(&A, &yc, &A)) != MP_OKAY) goto CLEANUP; - s_mp_div_2(&A); - if((res = mp_sub(&B, &xc, &B)) != MP_OKAY) goto CLEANUP; - s_mp_div_2(&B); - } - } - - while(mp_iseven(&v)) { - s_mp_div_2(&v); - - if(mp_iseven(&C) && mp_iseven(&D)) { - s_mp_div_2(&C); s_mp_div_2(&D); - } else { - if((res = mp_add(&C, &yc, &C)) != MP_OKAY) goto CLEANUP; - s_mp_div_2(&C); - if((res = mp_sub(&D, &xc, &D)) != MP_OKAY) goto CLEANUP; - s_mp_div_2(&D); - } - } - - if(mp_cmp(&u, &v) >= 0) { - if((res = mp_sub(&u, &v, &u)) != MP_OKAY) goto CLEANUP; - if((res = mp_sub(&A, &C, &A)) != MP_OKAY) goto CLEANUP; - if((res = mp_sub(&B, &D, &B)) != MP_OKAY) goto CLEANUP; - - } else { - if((res = mp_sub(&v, &u, &v)) != MP_OKAY) goto CLEANUP; - if((res = mp_sub(&C, &A, &C)) != MP_OKAY) goto CLEANUP; - if((res = mp_sub(&D, &B, &D)) != MP_OKAY) goto CLEANUP; - - } - - /* If we're done, copy results to output */ - if(mp_cmp_z(&u) == 0) { - if(x) - if((res = mp_copy(&C, x)) != MP_OKAY) goto CLEANUP; - - if(y) - if((res = mp_copy(&D, y)) != MP_OKAY) goto CLEANUP; - - if(g) - if((res = mp_mul(&gx, &v, g)) != MP_OKAY) goto CLEANUP; - - break; - } - } - - CLEANUP: - while(last >= 0) - mp_clear(clean[last--]); - - return res; - -} /* end mp_xgcd() */ - -/* }}} */ - -/* {{{ mp_invmod(a, m, c) */ - -/* - mp_invmod(a, m, c) - - Compute c = a^-1 (mod m), if there is an inverse for a (mod m). - This is equivalent to the question of whether (a, m) = 1. If not, - MP_UNDEF is returned, and there is no inverse. - */ - -mp_err mp_invmod(mp_int *a, mp_int *m, mp_int *c) -{ - mp_int g, x; - mp_err res; - - ARGCHK(a && m && c, MP_BADARG); - - if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0) - return MP_RANGE; - - if((res = mp_init(&g)) != MP_OKAY) - return res; - if((res = mp_init(&x)) != MP_OKAY) - goto X; - - if((res = mp_xgcd(a, m, &g, &x, NULL)) != MP_OKAY) - goto CLEANUP; - - if(mp_cmp_d(&g, 1) != MP_EQ) { - res = MP_UNDEF; - goto CLEANUP; - } - - res = mp_mod(&x, m, c); - SIGN(c) = SIGN(a); - -CLEANUP: - mp_clear(&x); -X: - mp_clear(&g); - - return res; - -} /* end mp_invmod() */ - -/* }}} */ -#endif /* if MP_NUMTH */ - -/* }}} */ - -/*------------------------------------------------------------------------*/ -/* {{{ mp_print(mp, ofp) */ - -#if MP_IOFUNC -/* - mp_print(mp, ofp) - - Print a textual representation of the given mp_int on the output - stream 'ofp'. Output is generated using the internal radix. - */ - -void mp_print(mp_int *mp, FILE *ofp) -{ - int ix; - - if(mp == NULL || ofp == NULL) - return; - - fputc((SIGN(mp) == MP_NEG) ? '-' : '+', ofp); - - for(ix = USED(mp) - 1; ix >= 0; ix--) { - fprintf(ofp, DIGIT_FMT, DIGIT(mp, ix)); - } - -} /* end mp_print() */ - -#endif /* if MP_IOFUNC */ - -/* }}} */ - -/*------------------------------------------------------------------------*/ -/* {{{ More I/O Functions */ - -/* {{{ mp_read_signed_bin(mp, str, len) */ - -/* - mp_read_signed_bin(mp, str, len) - - Read in a raw value (base 256) into the given mp_int - */ - -mp_err mp_read_signed_bin(mp_int *mp, unsigned char *str, int len) -{ - mp_err res; - - ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG); - - if((res = mp_read_unsigned_bin(mp, str + 1, len - 1)) == MP_OKAY) { - /* Get sign from first byte */ - if(str[0]) - SIGN(mp) = MP_NEG; - else - SIGN(mp) = MP_ZPOS; - } - - return res; - -} /* end mp_read_signed_bin() */ - -/* }}} */ - -/* {{{ mp_signed_bin_size(mp) */ - -int mp_signed_bin_size(mp_int *mp) -{ - ARGCHK(mp != NULL, 0); - - return mp_unsigned_bin_size(mp) + 1; - -} /* end mp_signed_bin_size() */ - -/* }}} */ - -/* {{{ mp_to_signed_bin(mp, str) */ - -mp_err mp_to_signed_bin(mp_int *mp, unsigned char *str) -{ - ARGCHK(mp != NULL && str != NULL, MP_BADARG); - - /* Caller responsible for allocating enough memory (use mp_raw_size(mp)) */ - str[0] = (char)SIGN(mp); - - return mp_to_unsigned_bin(mp, str + 1); - -} /* end mp_to_signed_bin() */ - -/* }}} */ - -/* {{{ mp_read_unsigned_bin(mp, str, len) */ - -/* - mp_read_unsigned_bin(mp, str, len) - - Read in an unsigned value (base 256) into the given mp_int - */ - -mp_err mp_read_unsigned_bin(mp_int *mp, unsigned char *str, int len) -{ - int ix; - mp_err res; - - ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG); - - mp_zero(mp); - - for(ix = 0; ix < len; ix++) { - if((res = s_mp_mul_2d(mp, CHAR_BIT)) != MP_OKAY) - return res; - - if((res = mp_add_d(mp, str[ix], mp)) != MP_OKAY) - return res; - } - - return MP_OKAY; - -} /* end mp_read_unsigned_bin() */ - -/* }}} */ - -/* {{{ mp_unsigned_bin_size(mp) */ - -int mp_unsigned_bin_size(mp_int *mp) -{ - mp_digit topdig; - int count; - - ARGCHK(mp != NULL, 0); - - /* Special case for the value zero */ - if(USED(mp) == 1 && DIGIT(mp, 0) == 0) - return 1; - - count = (USED(mp) - 1) * sizeof(mp_digit); - topdig = DIGIT(mp, USED(mp) - 1); - - while(topdig != 0) { - ++count; - topdig >>= CHAR_BIT; - } - - return count; - -} /* end mp_unsigned_bin_size() */ - -/* }}} */ - -/* {{{ mp_to_unsigned_bin(mp, str) */ - -mp_err mp_to_unsigned_bin(mp_int *mp, unsigned char *str) -{ - mp_digit *dp, *end, d; - unsigned char *spos; - - ARGCHK(mp != NULL && str != NULL, MP_BADARG); - - dp = DIGITS(mp); - end = dp + USED(mp) - 1; - spos = str; - - /* Special case for zero, quick test */ - if(dp == end && *dp == 0) { - *str = '\0'; - return MP_OKAY; - } - - /* Generate digits in reverse order */ - while(dp < end) { - unsigned int ix; - - d = *dp; - for(ix = 0; ix < sizeof(mp_digit); ++ix) { - *spos = d & UCHAR_MAX; - d >>= CHAR_BIT; - ++spos; - } - - ++dp; - } - - /* Now handle last digit specially, high order zeroes are not written */ - d = *end; - while(d != 0) { - *spos = d & UCHAR_MAX; - d >>= CHAR_BIT; - ++spos; - } - - /* Reverse everything to get digits in the correct order */ - while(--spos > str) { - unsigned char t = *str; - *str = *spos; - *spos = t; - - ++str; - } - - return MP_OKAY; - -} /* end mp_to_unsigned_bin() */ - -/* }}} */ - -/* {{{ mp_count_bits(mp) */ - -int mp_count_bits(mp_int *mp) -{ - int len; - mp_digit d; - - ARGCHK(mp != NULL, MP_BADARG); - - len = DIGIT_BIT * (USED(mp) - 1); - d = DIGIT(mp, USED(mp) - 1); - - while(d != 0) { - ++len; - d >>= 1; - } - - return len; - -} /* end mp_count_bits() */ - -/* }}} */ - -/* {{{ mp_read_radix(mp, str, radix) */ - -/* - mp_read_radix(mp, str, radix) - - Read an integer from the given string, and set mp to the resulting - value. The input is presumed to be in base 10. Leading non-digit - characters are ignored, and the function reads until a non-digit - character or the end of the string. - */ - -mp_err mp_read_radix(mp_int *mp, unsigned char *str, int radix) -{ - int ix = 0, val = 0; - mp_err res; - mp_sign sig = MP_ZPOS; - - ARGCHK(mp != NULL && str != NULL && radix >= 2 && radix <= MAX_RADIX, - MP_BADARG); - - mp_zero(mp); - - /* Skip leading non-digit characters until a digit or '-' or '+' */ - while(str[ix] && - (s_mp_tovalue(str[ix], radix) < 0) && - str[ix] != '-' && - str[ix] != '+') { - ++ix; - } - - if(str[ix] == '-') { - sig = MP_NEG; - ++ix; - } else if(str[ix] == '+') { - sig = MP_ZPOS; /* this is the default anyway... */ - ++ix; - } - - while((val = s_mp_tovalue(str[ix], radix)) >= 0) { - if((res = s_mp_mul_d(mp, radix)) != MP_OKAY) - return res; - if((res = s_mp_add_d(mp, val)) != MP_OKAY) - return res; - ++ix; - } - - if(s_mp_cmp_d(mp, 0) == MP_EQ) - SIGN(mp) = MP_ZPOS; - else - SIGN(mp) = sig; - - return MP_OKAY; - -} /* end mp_read_radix() */ - -/* }}} */ - -/* {{{ mp_radix_size(mp, radix) */ - -int mp_radix_size(mp_int *mp, int radix) -{ - int len; - ARGCHK(mp != NULL, 0); - - len = s_mp_outlen(mp_count_bits(mp), radix) + 1; /* for NUL terminator */ - - if(mp_cmp_z(mp) < 0) - ++len; /* for sign */ - - return len; - -} /* end mp_radix_size() */ - -/* }}} */ - -/* {{{ mp_value_radix_size(num, qty, radix) */ - -/* num = number of digits - qty = number of bits per digit - radix = target base - - Return the number of digits in the specified radix that would be - needed to express 'num' digits of 'qty' bits each. - */ -int mp_value_radix_size(int num, int qty, int radix) -{ - ARGCHK(num >= 0 && qty > 0 && radix >= 2 && radix <= MAX_RADIX, 0); - - return s_mp_outlen(num * qty, radix); - -} /* end mp_value_radix_size() */ - -/* }}} */ - -/* {{{ mp_toradix(mp, str, radix) */ - -mp_err mp_toradix(mp_int *mp, char *str, int radix) -{ - int ix, pos = 0; - - ARGCHK(mp != NULL && str != NULL, MP_BADARG); - ARGCHK(radix > 1 && radix <= MAX_RADIX, MP_RANGE); - - if(mp_cmp_z(mp) == MP_EQ) { - str[0] = '0'; - str[1] = '\0'; - } else { - mp_err res; - mp_int tmp; - mp_sign sgn; - mp_digit rem, rdx = (mp_digit)radix; - char ch; - - if((res = mp_init_copy(&tmp, mp)) != MP_OKAY) - return res; - - /* Save sign for later, and take absolute value */ - sgn = SIGN(&tmp); SIGN(&tmp) = MP_ZPOS; - - /* Generate output digits in reverse order */ - while(mp_cmp_z(&tmp) != 0) { - if((res = s_mp_div_d(&tmp, rdx, &rem)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - - /* Generate digits, use capital letters */ - ch = s_mp_todigit(rem, radix, 0); - - str[pos++] = ch; - } - - /* Add - sign if original value was negative */ - if(sgn == MP_NEG) - str[pos++] = '-'; - - /* Add trailing NUL to end the string */ - str[pos--] = '\0'; - - /* Reverse the digits and sign indicator */ - ix = 0; - while(ix < pos) { - char _tmp = str[ix]; - - str[ix] = str[pos]; - str[pos] = _tmp; - ++ix; - --pos; - } - - mp_clear(&tmp); - } - - return MP_OKAY; - -} /* end mp_toradix() */ - -/* }}} */ - -/* {{{ mp_char2value(ch, r) */ - -int mp_char2value(char ch, int r) -{ - return s_mp_tovalue(ch, r); - -} /* end mp_tovalue() */ - -/* }}} */ - -/* }}} */ - -/* {{{ mp_strerror(ec) */ - -/* - mp_strerror(ec) - - Return a string describing the meaning of error code 'ec'. The - string returned is allocated in static memory, so the caller should - not attempt to modify or free the memory associated with this - string. - */ -const char *mp_strerror(mp_err ec) -{ - int aec = (ec < 0) ? -ec : ec; - - /* Code values are negative, so the senses of these comparisons - are accurate */ - if(ec < MP_LAST_CODE || ec > MP_OKAY) { - return mp_err_string[0]; /* unknown error code */ - } else { - return mp_err_string[aec + 1]; - } - -} /* end mp_strerror() */ - -/* }}} */ - -/*========================================================================*/ -/*------------------------------------------------------------------------*/ -/* Static function definitions (internal use only) */ - -/* {{{ Memory management */ - -/* {{{ s_mp_grow(mp, min) */ - -/* Make sure there are at least 'min' digits allocated to mp */ -mp_err s_mp_grow(mp_int *mp, mp_size min) -{ - if(min > ALLOC(mp)) { - mp_digit *tmp; - - /* Set min to next nearest default precision block size */ - min = ((min + (s_mp_defprec - 1)) / s_mp_defprec) * s_mp_defprec; - - if((tmp = s_mp_alloc(min, sizeof(mp_digit))) == NULL) - return MP_MEM; - - s_mp_copy(DIGITS(mp), tmp, USED(mp)); - -#if MP_CRYPTO - s_mp_setz(DIGITS(mp), ALLOC(mp)); -#endif - s_mp_free(DIGITS(mp)); - DIGITS(mp) = tmp; - ALLOC(mp) = min; - } - - return MP_OKAY; - -} /* end s_mp_grow() */ - -/* }}} */ - -/* {{{ s_mp_pad(mp, min) */ - -/* Make sure the used size of mp is at least 'min', growing if needed */ -mp_err s_mp_pad(mp_int *mp, mp_size min) -{ - if(min > USED(mp)) { - mp_err res; - - /* Make sure there is room to increase precision */ - if(min > ALLOC(mp) && (res = s_mp_grow(mp, min)) != MP_OKAY) - return res; - - /* Increase precision; should already be 0-filled */ - USED(mp) = min; - } - - return MP_OKAY; - -} /* end s_mp_pad() */ - -/* }}} */ - -/* {{{ s_mp_setz(dp, count) */ - -#if MP_MACRO == 0 -/* Set 'count' digits pointed to by dp to be zeroes */ -void s_mp_setz(mp_digit *dp, mp_size count) -{ -#if MP_MEMSET == 0 - int ix; - - for(ix = 0; ix < count; ix++) - dp[ix] = 0; -#else - memset(dp, 0, count * sizeof(mp_digit)); -#endif - -} /* end s_mp_setz() */ -#endif - -/* }}} */ - -/* {{{ s_mp_copy(sp, dp, count) */ - -#if MP_MACRO == 0 -/* Copy 'count' digits from sp to dp */ -void s_mp_copy(mp_digit *sp, mp_digit *dp, mp_size count) -{ -#if MP_MEMCPY == 0 - int ix; - - for(ix = 0; ix < count; ix++) - dp[ix] = sp[ix]; -#else - memcpy(dp, sp, count * sizeof(mp_digit)); -#endif - -} /* end s_mp_copy() */ -#endif - -/* }}} */ - -/* {{{ s_mp_alloc(nb, ni) */ - -#if MP_MACRO == 0 -/* Allocate ni records of nb bytes each, and return a pointer to that */ -void *s_mp_alloc(size_t nb, size_t ni) -{ - return calloc(nb, ni); - -} /* end s_mp_alloc() */ -#endif - -/* }}} */ - -/* {{{ s_mp_free(ptr) */ - -#if MP_MACRO == 0 -/* Free the memory pointed to by ptr */ -void s_mp_free(void *ptr) -{ - if(ptr) - free(ptr); - -} /* end s_mp_free() */ -#endif - -/* }}} */ - -/* {{{ s_mp_clamp(mp) */ - -/* Remove leading zeroes from the given value */ -void s_mp_clamp(mp_int *mp) -{ - mp_size du = USED(mp); - mp_digit *zp = DIGITS(mp) + du - 1; - - while(du > 1 && !*zp--) - --du; - - USED(mp) = du; - -} /* end s_mp_clamp() */ - - -/* }}} */ - -/* {{{ s_mp_exch(a, b) */ - -/* Exchange the data for a and b; (b, a) = (a, b) */ -void s_mp_exch(mp_int *a, mp_int *b) -{ - mp_int tmp; - - tmp = *a; - *a = *b; - *b = tmp; - -} /* end s_mp_exch() */ - -/* }}} */ - -/* }}} */ - -/* {{{ Arithmetic helpers */ - -/* {{{ s_mp_lshd(mp, p) */ - -/* - Shift mp leftward by p digits, growing if needed, and zero-filling - the in-shifted digits at the right end. This is a convenient - alternative to multiplication by powers of the radix - */ - -mp_err s_mp_lshd(mp_int *mp, mp_size p) -{ - mp_err res; - mp_size pos; - mp_digit *dp; - int ix; - - if(p == 0) - return MP_OKAY; - - if((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY) - return res; - - pos = USED(mp) - 1; - dp = DIGITS(mp); - - /* Shift all the significant figures over as needed */ - for(ix = pos - p; ix >= 0; ix--) - dp[ix + p] = dp[ix]; - - /* Fill the bottom digits with zeroes */ - for(ix = 0; (unsigned)ix < p; ix++) - dp[ix] = 0; - - return MP_OKAY; - -} /* end s_mp_lshd() */ - -/* }}} */ - -/* {{{ s_mp_rshd(mp, p) */ - -/* - Shift mp rightward by p digits. Maintains the invariant that - digits above the precision are all zero. Digits shifted off the - end are lost. Cannot fail. - */ - -void s_mp_rshd(mp_int *mp, mp_size p) -{ - mp_size ix; - mp_digit *dp; - - if(p == 0) - return; - - /* Shortcut when all digits are to be shifted off */ - if(p >= USED(mp)) { - s_mp_setz(DIGITS(mp), ALLOC(mp)); - USED(mp) = 1; - SIGN(mp) = MP_ZPOS; - return; - } - - /* Shift all the significant figures over as needed */ - dp = DIGITS(mp); - for(ix = p; ix < USED(mp); ix++) - dp[ix - p] = dp[ix]; - - /* Fill the top digits with zeroes */ - ix -= p; - while(ix < USED(mp)) - dp[ix++] = 0; - - /* Strip off any leading zeroes */ - s_mp_clamp(mp); - -} /* end s_mp_rshd() */ - -/* }}} */ - -/* {{{ s_mp_div_2(mp) */ - -/* Divide by two -- take advantage of radix properties to do it fast */ -void s_mp_div_2(mp_int *mp) -{ - s_mp_div_2d(mp, 1); - -} /* end s_mp_div_2() */ - -/* }}} */ - -/* {{{ s_mp_mul_2(mp) */ - -mp_err s_mp_mul_2(mp_int *mp) -{ - unsigned int ix; - mp_digit kin = 0, kout, *dp = DIGITS(mp); - mp_err res; - - /* Shift digits leftward by 1 bit */ - for(ix = 0; ix < USED(mp); ix++) { - kout = (dp[ix] >> (DIGIT_BIT - 1)) & 1; - dp[ix] = (dp[ix] << 1) | kin; - - kin = kout; - } - - /* Deal with rollover from last digit */ - if(kin) { - if(ix >= ALLOC(mp)) { - if((res = s_mp_grow(mp, ALLOC(mp) + 1)) != MP_OKAY) - return res; - dp = DIGITS(mp); - } - - dp[ix] = kin; - USED(mp) += 1; - } - - return MP_OKAY; - -} /* end s_mp_mul_2() */ - -/* }}} */ - -/* {{{ s_mp_mod_2d(mp, d) */ - -/* - Remainder the integer by 2^d, where d is a number of bits. This - amounts to a bitwise AND of the value, and does not require the full - division code - */ -void s_mp_mod_2d(mp_int *mp, mp_digit d) -{ - unsigned int ndig = (d / DIGIT_BIT), nbit = (d % DIGIT_BIT); - unsigned int ix; - mp_digit dmask, *dp = DIGITS(mp); - - if(ndig >= USED(mp)) - return; - - /* Flush all the bits above 2^d in its digit */ - dmask = (1 << nbit) - 1; - dp[ndig] &= dmask; - - /* Flush all digits above the one with 2^d in it */ - for(ix = ndig + 1; ix < USED(mp); ix++) - dp[ix] = 0; - - s_mp_clamp(mp); - -} /* end s_mp_mod_2d() */ - -/* }}} */ - -/* {{{ s_mp_mul_2d(mp, d) */ - -/* - Multiply by the integer 2^d, where d is a number of bits. This - amounts to a bitwise shift of the value, and does not require the - full multiplication code. - */ -mp_err s_mp_mul_2d(mp_int *mp, mp_digit d) -{ - mp_err res; - mp_digit save, next, mask, *dp; - mp_size used; - unsigned int ix; - - if((res = s_mp_lshd(mp, d / DIGIT_BIT)) != MP_OKAY) - return res; - - dp = DIGITS(mp); used = USED(mp); - d %= DIGIT_BIT; - - mask = (1 << d) - 1; - - /* If the shift requires another digit, make sure we've got one to - work with */ - if((dp[used - 1] >> (DIGIT_BIT - d)) & mask) { - if((res = s_mp_grow(mp, used + 1)) != MP_OKAY) - return res; - dp = DIGITS(mp); - } - - /* Do the shifting... */ - save = 0; - for(ix = 0; ix < used; ix++) { - next = (dp[ix] >> (DIGIT_BIT - d)) & mask; - dp[ix] = (dp[ix] << d) | save; - save = next; - } - - /* If, at this point, we have a nonzero carryout into the next - digit, we'll increase the size by one digit, and store it... - */ - if(save) { - dp[used] = save; - USED(mp) += 1; - } - - s_mp_clamp(mp); - return MP_OKAY; - -} /* end s_mp_mul_2d() */ - -/* }}} */ - -/* {{{ s_mp_div_2d(mp, d) */ - -/* - Divide the integer by 2^d, where d is a number of bits. This - amounts to a bitwise shift of the value, and does not require the - full division code (used in Barrett reduction, see below) - */ -void s_mp_div_2d(mp_int *mp, mp_digit d) -{ - int ix; - mp_digit save, next, mask, *dp = DIGITS(mp); - - s_mp_rshd(mp, d / DIGIT_BIT); - d %= DIGIT_BIT; - - mask = (1 << d) - 1; - - save = 0; - for(ix = USED(mp) - 1; ix >= 0; ix--) { - next = dp[ix] & mask; - dp[ix] = (dp[ix] >> d) | (save << (DIGIT_BIT - d)); - save = next; - } - - s_mp_clamp(mp); - -} /* end s_mp_div_2d() */ - -/* }}} */ - -/* {{{ s_mp_norm(a, b) */ - -/* - s_mp_norm(a, b) - - Normalize a and b for division, where b is the divisor. In order - that we might make good guesses for quotient digits, we want the - leading digit of b to be at least half the radix, which we - accomplish by multiplying a and b by a constant. This constant is - returned (so that it can be divided back out of the remainder at the - end of the division process). - - We multiply by the smallest power of 2 that gives us a leading digit - at least half the radix. By choosing a power of 2, we simplify the - multiplication and division steps to simple shifts. - */ -mp_digit s_mp_norm(mp_int *a, mp_int *b) -{ - mp_digit t, d = 0; - - t = DIGIT(b, USED(b) - 1); - while(t < (RADIX / 2)) { - t <<= 1; - ++d; - } - - if(d != 0) { - s_mp_mul_2d(a, d); - s_mp_mul_2d(b, d); - } - - return d; - -} /* end s_mp_norm() */ - -/* }}} */ - -/* }}} */ - -/* {{{ Primitive digit arithmetic */ - -/* {{{ s_mp_add_d(mp, d) */ - -/* Add d to |mp| in place */ -mp_err s_mp_add_d(mp_int *mp, mp_digit d) /* unsigned digit addition */ -{ - mp_word w, k = 0; - mp_size ix = 1, used = USED(mp); - mp_digit *dp = DIGITS(mp); - - w = dp[0] + d; - dp[0] = ACCUM(w); - k = CARRYOUT(w); - - while(ix < used && k) { - w = dp[ix] + k; - dp[ix] = ACCUM(w); - k = CARRYOUT(w); - ++ix; - } - - if(k != 0) { - mp_err res; - - if((res = s_mp_pad(mp, USED(mp) + 1)) != MP_OKAY) - return res; - - DIGIT(mp, ix) = k; - } - - return MP_OKAY; - -} /* end s_mp_add_d() */ - -/* }}} */ - -/* {{{ s_mp_sub_d(mp, d) */ - -/* Subtract d from |mp| in place, assumes |mp| > d */ -mp_err s_mp_sub_d(mp_int *mp, mp_digit d) /* unsigned digit subtract */ -{ - mp_word w, b = 0; - mp_size ix = 1, used = USED(mp); - mp_digit *dp = DIGITS(mp); - - /* Compute initial subtraction */ - w = (RADIX + dp[0]) - d; - b = CARRYOUT(w) ? 0 : 1; - dp[0] = ACCUM(w); - - /* Propagate borrows leftward */ - while(b && ix < used) { - w = (RADIX + dp[ix]) - b; - b = CARRYOUT(w) ? 0 : 1; - dp[ix] = ACCUM(w); - ++ix; - } - - /* Remove leading zeroes */ - s_mp_clamp(mp); - - /* If we have a borrow out, it's a violation of the input invariant */ - if(b) - return MP_RANGE; - else - return MP_OKAY; - -} /* end s_mp_sub_d() */ - -/* }}} */ - -/* {{{ s_mp_mul_d(a, d) */ - -/* Compute a = a * d, single digit multiplication */ -mp_err s_mp_mul_d(mp_int *a, mp_digit d) -{ - mp_word w, k = 0; - mp_size ix, max; - mp_err res; - mp_digit *dp = DIGITS(a); - - /* - Single-digit multiplication will increase the precision of the - output by at most one digit. However, we can detect when this - will happen -- if the high-order digit of a, times d, gives a - two-digit result, then the precision of the result will increase; - otherwise it won't. We use this fact to avoid calling s_mp_pad() - unless absolutely necessary. - */ - max = USED(a); - w = dp[max - 1] * d; - if(CARRYOUT(w) != 0) { - if((res = s_mp_pad(a, max + 1)) != MP_OKAY) - return res; - dp = DIGITS(a); - } - - for(ix = 0; ix < max; ix++) { - w = (dp[ix] * d) + k; - dp[ix] = ACCUM(w); - k = CARRYOUT(w); - } - - /* If there is a precision increase, take care of it here; the above - test guarantees we have enough storage to do this safely. - */ - if(k) { - dp[max] = k; - USED(a) = max + 1; - } - - s_mp_clamp(a); - - return MP_OKAY; - -} /* end s_mp_mul_d() */ - -/* }}} */ - -/* {{{ s_mp_div_d(mp, d, r) */ - -/* - s_mp_div_d(mp, d, r) - - Compute the quotient mp = mp / d and remainder r = mp mod d, for a - single digit d. If r is null, the remainder will be discarded. - */ - -mp_err s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r) -{ - mp_word w = 0, t; - mp_int quot; - mp_err res; - mp_digit *dp = DIGITS(mp), *qp; - int ix; - - if(d == 0) - return MP_RANGE; - - /* Make room for the quotient */ - if((res = mp_init_size(", USED(mp))) != MP_OKAY) - return res; - - USED(") = USED(mp); /* so clamping will work below */ - qp = DIGITS("); - - /* Divide without subtraction */ - for(ix = USED(mp) - 1; ix >= 0; ix--) { - w = (w << DIGIT_BIT) | dp[ix]; - - if(w >= d) { - t = w / d; - w = w % d; - } else { - t = 0; - } - - qp[ix] = t; - } - - /* Deliver the remainder, if desired */ - if(r) - *r = w; - - s_mp_clamp("); - mp_exch(", mp); - mp_clear("); - - return MP_OKAY; - -} /* end s_mp_div_d() */ - -/* }}} */ - -/* }}} */ - -/* {{{ Primitive full arithmetic */ - -/* {{{ s_mp_add(a, b) */ - -/* Compute a = |a| + |b| */ -mp_err s_mp_add(mp_int *a, mp_int *b) /* magnitude addition */ -{ - mp_word w = 0; - mp_digit *pa, *pb; - mp_size ix, used = USED(b); - mp_err res; - - /* Make sure a has enough precision for the output value */ - if((used > USED(a)) && (res = s_mp_pad(a, used)) != MP_OKAY) - return res; - - /* - Add up all digits up to the precision of b. If b had initially - the same precision as a, or greater, we took care of it by the - padding step above, so there is no problem. If b had initially - less precision, we'll have to make sure the carry out is duly - propagated upward among the higher-order digits of the sum. - */ - pa = DIGITS(a); - pb = DIGITS(b); - for(ix = 0; ix < used; ++ix) { - w += *pa + *pb++; - *pa++ = ACCUM(w); - w = CARRYOUT(w); - } - - /* If we run out of 'b' digits before we're actually done, make - sure the carries get propagated upward... - */ - used = USED(a); - while(w && ix < used) { - w += *pa; - *pa++ = ACCUM(w); - w = CARRYOUT(w); - ++ix; - } - - /* If there's an overall carry out, increase precision and include - it. We could have done this initially, but why touch the memory - allocator unless we're sure we have to? - */ - if(w) { - if((res = s_mp_pad(a, used + 1)) != MP_OKAY) - return res; - - DIGIT(a, ix) = w; /* pa may not be valid after s_mp_pad() call */ - } - - return MP_OKAY; - -} /* end s_mp_add() */ - -/* }}} */ - -/* {{{ s_mp_sub(a, b) */ - -/* Compute a = |a| - |b|, assumes |a| >= |b| */ -mp_err s_mp_sub(mp_int *a, mp_int *b) /* magnitude subtract */ -{ - mp_word w = 0; - mp_digit *pa, *pb; - mp_size ix, used = USED(b); - - /* - Subtract and propagate borrow. Up to the precision of b, this - accounts for the digits of b; after that, we just make sure the - carries get to the right place. This saves having to pad b out to - the precision of a just to make the loops work right... - */ - pa = DIGITS(a); - pb = DIGITS(b); - - for(ix = 0; ix < used; ++ix) { - w = (RADIX + *pa) - w - *pb++; - *pa++ = ACCUM(w); - w = CARRYOUT(w) ? 0 : 1; - } - - used = USED(a); - while(ix < used) { - w = RADIX + *pa - w; - *pa++ = ACCUM(w); - w = CARRYOUT(w) ? 0 : 1; - ++ix; - } - - /* Clobber any leading zeroes we created */ - s_mp_clamp(a); - - /* - If there was a borrow out, then |b| > |a| in violation - of our input invariant. We've already done the work, - but we'll at least complain about it... - */ - if(w) - return MP_RANGE; - else - return MP_OKAY; - -} /* end s_mp_sub() */ - -/* }}} */ - -mp_err s_mp_reduce(mp_int *x, mp_int *m, mp_int *mu) -{ - mp_int q; - mp_err res; - mp_size um = USED(m); - - if((res = mp_init_copy(&q, x)) != MP_OKAY) - return res; - - s_mp_rshd(&q, um - 1); /* q1 = x / b^(k-1) */ - s_mp_mul(&q, mu); /* q2 = q1 * mu */ - s_mp_rshd(&q, um + 1); /* q3 = q2 / b^(k+1) */ - - /* x = x mod b^(k+1), quick (no division) */ - s_mp_mod_2d(x, (mp_digit)(DIGIT_BIT * (um + 1))); - - /* q = q * m mod b^(k+1), quick (no division), uses the short multiplier */ -#ifndef SHRT_MUL - s_mp_mul(&q, m); - s_mp_mod_2d(&q, (mp_digit)(DIGIT_BIT * (um + 1))); -#else - s_mp_mul_dig(&q, m, um + 1); -#endif - - /* x = x - q */ - if((res = mp_sub(x, &q, x)) != MP_OKAY) - goto CLEANUP; - - /* If x < 0, add b^(k+1) to it */ - if(mp_cmp_z(x) < 0) { - mp_set(&q, 1); - if((res = s_mp_lshd(&q, um + 1)) != MP_OKAY) - goto CLEANUP; - if((res = mp_add(x, &q, x)) != MP_OKAY) - goto CLEANUP; - } - - /* Back off if it's too big */ - while(mp_cmp(x, m) >= 0) { - if((res = s_mp_sub(x, m)) != MP_OKAY) - break; - } - - CLEANUP: - mp_clear(&q); - - return res; - -} /* end s_mp_reduce() */ - - - -/* {{{ s_mp_mul(a, b) */ - -/* Compute a = |a| * |b| */ -mp_err s_mp_mul(mp_int *a, mp_int *b) -{ - mp_word w, k = 0; - mp_int tmp; - mp_err res; - mp_size ix, jx, ua = USED(a), ub = USED(b); - mp_digit *pa, *pb, *pt, *pbt; - - if((res = mp_init_size(&tmp, ua + ub)) != MP_OKAY) - return res; - - /* This has the effect of left-padding with zeroes... */ - USED(&tmp) = ua + ub; - - /* We're going to need the base value each iteration */ - pbt = DIGITS(&tmp); - - /* Outer loop: Digits of b */ - - pb = DIGITS(b); - for(ix = 0; ix < ub; ++ix, ++pb) { - if(*pb == 0) - continue; - - /* Inner product: Digits of a */ - pa = DIGITS(a); - for(jx = 0; jx < ua; ++jx, ++pa) { - pt = pbt + ix + jx; - w = *pb * *pa + k + *pt; - *pt = ACCUM(w); - k = CARRYOUT(w); - } - - pbt[ix + jx] = k; - k = 0; - } - - s_mp_clamp(&tmp); - s_mp_exch(&tmp, a); - - mp_clear(&tmp); - - return MP_OKAY; - -} /* end s_mp_mul() */ - -/* }}} */ - -/* {{{ s_mp_kmul(a, b, out, len) */ - -#if 0 -void s_mp_kmul(mp_digit *a, mp_digit *b, mp_digit *out, mp_size len) -{ - mp_word w, k = 0; - mp_size ix, jx; - mp_digit *pa, *pt; - - for(ix = 0; ix < len; ++ix, ++b) { - if(*b == 0) - continue; - - pa = a; - for(jx = 0; jx < len; ++jx, ++pa) { - pt = out + ix + jx; - w = *b * *pa + k + *pt; - *pt = ACCUM(w); - k = CARRYOUT(w); - } - - out[ix + jx] = k; - k = 0; - } - -} /* end s_mp_kmul() */ -#endif - -/* }}} */ - -/* {{{ s_mp_sqr(a) */ - -/* - Computes the square of a, in place. This can be done more - efficiently than a general multiplication, because many of the - computation steps are redundant when squaring. The inner product - step is a bit more complicated, but we save a fair number of - iterations of the multiplication loop. - */ -#if MP_SQUARE -mp_err s_mp_sqr(mp_int *a) -{ - mp_word w, k = 0; - mp_int tmp; - mp_err res; - mp_size ix, jx, kx, used = USED(a); - mp_digit *pa1, *pa2, *pt, *pbt; - - if((res = mp_init_size(&tmp, 2 * used)) != MP_OKAY) - return res; - - /* Left-pad with zeroes */ - USED(&tmp) = 2 * used; - - /* We need the base value each time through the loop */ - pbt = DIGITS(&tmp); - - pa1 = DIGITS(a); - for(ix = 0; ix < used; ++ix, ++pa1) { - if(*pa1 == 0) - continue; - - w = DIGIT(&tmp, ix + ix) + (*pa1 * *pa1); - - pbt[ix + ix] = ACCUM(w); - k = CARRYOUT(w); - - /* - The inner product is computed as: - - (C, S) = t[i,j] + 2 a[i] a[j] + C - - This can overflow what can be represented in an mp_word, and - since C arithmetic does not provide any way to check for - overflow, we have to check explicitly for overflow conditions - before they happen. - */ - for(jx = ix + 1, pa2 = DIGITS(a) + jx; jx < used; ++jx, ++pa2) { - mp_word u = 0, v; - - /* Store this in a temporary to avoid indirections later */ - pt = pbt + ix + jx; - - /* Compute the multiplicative step */ - w = *pa1 * *pa2; - - /* If w is more than half MP_WORD_MAX, the doubling will - overflow, and we need to record a carry out into the next - word */ - u = (w >> (MP_WORD_BIT - 1)) & 1; - - /* Double what we've got, overflow will be ignored as defined - for C arithmetic (we've already noted if it is to occur) - */ - w *= 2; - - /* Compute the additive step */ - v = *pt + k; - - /* If we do not already have an overflow carry, check to see - if the addition will cause one, and set the carry out if so - */ - u |= ((MP_WORD_MAX - v) < w); - - /* Add in the rest, again ignoring overflow */ - w += v; - - /* Set the i,j digit of the output */ - *pt = ACCUM(w); - - /* Save carry information for the next iteration of the loop. - This is why k must be an mp_word, instead of an mp_digit */ - k = CARRYOUT(w) | (u << DIGIT_BIT); - - } /* for(jx ...) */ - - /* Set the last digit in the cycle and reset the carry */ - k = DIGIT(&tmp, ix + jx) + k; - pbt[ix + jx] = ACCUM(k); - k = CARRYOUT(k); - - /* If we are carrying out, propagate the carry to the next digit - in the output. This may cascade, so we have to be somewhat - circumspect -- but we will have enough precision in the output - that we won't overflow - */ - kx = 1; - while(k) { - k = pbt[ix + jx + kx] + 1; - pbt[ix + jx + kx] = ACCUM(k); - k = CARRYOUT(k); - ++kx; - } - } /* for(ix ...) */ - - s_mp_clamp(&tmp); - s_mp_exch(&tmp, a); - - mp_clear(&tmp); - - return MP_OKAY; - -} /* end s_mp_sqr() */ -#endif - -/* }}} */ - -/* {{{ s_mp_div(a, b) */ - -/* - s_mp_div(a, b) - - Compute a = a / b and b = a mod b. Assumes b > a. - */ - -mp_err s_mp_div(mp_int *a, mp_int *b) -{ - mp_int quot, rem, t; - mp_word q; - mp_err res; - mp_digit d; - int ix; - - if(mp_cmp_z(b) == 0) - return MP_RANGE; - - /* Shortcut if b is power of two */ - if((ix = s_mp_ispow2(b)) >= 0) { - mp_copy(a, b); /* need this for remainder */ - s_mp_div_2d(a, (mp_digit)ix); - s_mp_mod_2d(b, (mp_digit)ix); - - return MP_OKAY; - } - - /* Allocate space to store the quotient */ - if((res = mp_init_size(", USED(a))) != MP_OKAY) - return res; - - /* A working temporary for division */ - if((res = mp_init_size(&t, USED(a))) != MP_OKAY) - goto T; - - /* Allocate space for the remainder */ - if((res = mp_init_size(&rem, USED(a))) != MP_OKAY) - goto REM; - - /* Normalize to optimize guessing */ - d = s_mp_norm(a, b); - - /* Perform the division itself...woo! */ - ix = USED(a) - 1; - - while(ix >= 0) { - /* Find a partial substring of a which is at least b */ - while(s_mp_cmp(&rem, b) < 0 && ix >= 0) { - if((res = s_mp_lshd(&rem, 1)) != MP_OKAY) - goto CLEANUP; - - if((res = s_mp_lshd(", 1)) != MP_OKAY) - goto CLEANUP; - - DIGIT(&rem, 0) = DIGIT(a, ix); - s_mp_clamp(&rem); - --ix; - } - - /* If we didn't find one, we're finished dividing */ - if(s_mp_cmp(&rem, b) < 0) - break; - - /* Compute a guess for the next quotient digit */ - q = DIGIT(&rem, USED(&rem) - 1); - if(q <= DIGIT(b, USED(b) - 1) && USED(&rem) > 1) - q = (q << DIGIT_BIT) | DIGIT(&rem, USED(&rem) - 2); - - q /= DIGIT(b, USED(b) - 1); - - /* The guess can be as much as RADIX + 1 */ - if(q >= RADIX) - q = RADIX - 1; - - /* See what that multiplies out to */ - mp_copy(b, &t); - if((res = s_mp_mul_d(&t, q)) != MP_OKAY) - goto CLEANUP; - - /* - If it's too big, back it off. We should not have to do this - more than once, or, in rare cases, twice. Knuth describes a - method by which this could be reduced to a maximum of once, but - I didn't implement that here. - */ - while(s_mp_cmp(&t, &rem) > 0) { - --q; - s_mp_sub(&t, b); - } - - /* At this point, q should be the right next digit */ - if((res = s_mp_sub(&rem, &t)) != MP_OKAY) - goto CLEANUP; - - /* - Include the digit in the quotient. We allocated enough memory - for any quotient we could ever possibly get, so we should not - have to check for failures here - */ - DIGIT(", 0) = q; - } - - /* Denormalize remainder */ - if(d != 0) - s_mp_div_2d(&rem, d); - - s_mp_clamp("); - s_mp_clamp(&rem); - - /* Copy quotient back to output */ - s_mp_exch(", a); - - /* Copy remainder back to output */ - s_mp_exch(&rem, b); - -CLEANUP: - mp_clear(&rem); -REM: - mp_clear(&t); -T: - mp_clear("); - - return res; - -} /* end s_mp_div() */ - -/* }}} */ - -/* {{{ s_mp_2expt(a, k) */ - -mp_err s_mp_2expt(mp_int *a, mp_digit k) -{ - mp_err res; - mp_size dig, bit; - - dig = k / DIGIT_BIT; - bit = k % DIGIT_BIT; - - mp_zero(a); - if((res = s_mp_pad(a, dig + 1)) != MP_OKAY) - return res; - - DIGIT(a, dig) |= (1 << bit); - - return MP_OKAY; - -} /* end s_mp_2expt() */ - -/* }}} */ - - -/* }}} */ - -/* }}} */ - -/* {{{ Primitive comparisons */ - -/* {{{ s_mp_cmp(a, b) */ - -/* Compare |a| <=> |b|, return 0 if equal, <0 if a<b, >0 if a>b */ -int s_mp_cmp(mp_int *a, mp_int *b) -{ - mp_size ua = USED(a), ub = USED(b); - - if(ua > ub) - return MP_GT; - else if(ua < ub) - return MP_LT; - else { - int ix = ua - 1; - mp_digit *ap = DIGITS(a) + ix, *bp = DIGITS(b) + ix; - - while(ix >= 0) { - if(*ap > *bp) - return MP_GT; - else if(*ap < *bp) - return MP_LT; - - --ap; --bp; --ix; - } - - return MP_EQ; - } - -} /* end s_mp_cmp() */ - -/* }}} */ - -/* {{{ s_mp_cmp_d(a, d) */ - -/* Compare |a| <=> d, return 0 if equal, <0 if a<d, >0 if a>d */ -int s_mp_cmp_d(mp_int *a, mp_digit d) -{ - mp_size ua = USED(a); - mp_digit *ap = DIGITS(a); - - if(ua > 1) - return MP_GT; - - if(*ap < d) - return MP_LT; - else if(*ap > d) - return MP_GT; - else - return MP_EQ; - -} /* end s_mp_cmp_d() */ - -/* }}} */ - -/* {{{ s_mp_ispow2(v) */ - -/* - Returns -1 if the value is not a power of two; otherwise, it returns - k such that v = 2^k, i.e. lg(v). - */ -int s_mp_ispow2(mp_int *v) -{ - mp_digit d, *dp; - mp_size uv = USED(v); - int extra = 0, ix; - - d = DIGIT(v, uv - 1); /* most significant digit of v */ - - while(d && ((d & 1) == 0)) { - d >>= 1; - ++extra; - } - - if(d == 1) { - ix = uv - 2; - dp = DIGITS(v) + ix; - - while(ix >= 0) { - if(*dp) - return -1; /* not a power of two */ - - --dp; --ix; - } - - return ((uv - 1) * DIGIT_BIT) + extra; - } - - return -1; - -} /* end s_mp_ispow2() */ - -/* }}} */ - -/* {{{ s_mp_ispow2d(d) */ - -int s_mp_ispow2d(mp_digit d) -{ - int pow = 0; - - while((d & 1) == 0) { - ++pow; d >>= 1; - } - - if(d == 1) - return pow; - - return -1; - -} /* end s_mp_ispow2d() */ - -/* }}} */ - -/* }}} */ - -/* {{{ Primitive I/O helpers */ - -/* {{{ s_mp_tovalue(ch, r) */ - -/* - Convert the given character to its digit value, in the given radix. - If the given character is not understood in the given radix, -1 is - returned. Otherwise the digit's numeric value is returned. - - The results will be odd if you use a radix < 2 or > 62, you are - expected to know what you're up to. - */ -int s_mp_tovalue(char ch, int r) -{ - int val, xch; - - if(r > 36) - xch = ch; - else - xch = toupper(ch); - - if(isdigit(xch)) - val = xch - '0'; - else if(isupper(xch)) - val = xch - 'A' + 10; - else if(islower(xch)) - val = xch - 'a' + 36; - else if(xch == '+') - val = 62; - else if(xch == '/') - val = 63; - else - return -1; - - if(val < 0 || val >= r) - return -1; - - return val; - -} /* end s_mp_tovalue() */ - -/* }}} */ - -/* {{{ s_mp_todigit(val, r, low) */ - -/* - Convert val to a radix-r digit, if possible. If val is out of range - for r, returns zero. Otherwise, returns an ASCII character denoting - the value in the given radix. - - The results may be odd if you use a radix < 2 or > 64, you are - expected to know what you're doing. - */ - -char s_mp_todigit(int val, int r, int low) -{ - char ch; - - if(val < 0 || val >= r) - return 0; - - ch = s_dmap_1[val]; - - if(r <= 36 && low) - ch = tolower(ch); - - return ch; - -} /* end s_mp_todigit() */ - -/* }}} */ - -/* {{{ s_mp_outlen(bits, radix) */ - -/* - Return an estimate for how long a string is needed to hold a radix - r representation of a number with 'bits' significant bits. - - Does not include space for a sign or a NUL terminator. - */ -int s_mp_outlen(int bits, int r) -{ - return (int)((double)bits * LOG_V_2(r)); - -} /* end s_mp_outlen() */ - -/* }}} */ - -/* }}} */ - -/*------------------------------------------------------------------------*/ -/* HERE THERE BE DRAGONS */ -/* crc==4242132123, version==2, Sat Feb 02 06:43:52 2002 */ - -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ diff --git a/libtommath/mtest/mpi.h b/libtommath/mtest/mpi.h deleted file mode 100644 index 5accb52..0000000 --- a/libtommath/mtest/mpi.h +++ /dev/null @@ -1,231 +0,0 @@ -/* - mpi.h - - by Michael J. Fromberger <sting@linguist.dartmouth.edu> - Copyright (C) 1998 Michael J. Fromberger, All Rights Reserved - - Arbitrary precision integer arithmetic library - - $Id$ - */ - -#ifndef _H_MPI_ -#define _H_MPI_ - -#include "mpi-config.h" - -#define MP_LT -1 -#define MP_EQ 0 -#define MP_GT 1 - -#if MP_DEBUG -#undef MP_IOFUNC -#define MP_IOFUNC 1 -#endif - -#if MP_IOFUNC -#include <stdio.h> -#include <ctype.h> -#endif - -#include <limits.h> - -#define MP_NEG 1 -#define MP_ZPOS 0 - -/* Included for compatibility... */ -#define NEG MP_NEG -#define ZPOS MP_ZPOS - -#define MP_OKAY 0 /* no error, all is well */ -#define MP_YES 0 /* yes (boolean result) */ -#define MP_NO -1 /* no (boolean result) */ -#define MP_MEM -2 /* out of memory */ -#define MP_RANGE -3 /* argument out of range */ -#define MP_BADARG -4 /* invalid parameter */ -#define MP_UNDEF -5 /* answer is undefined */ -#define MP_LAST_CODE MP_UNDEF - -#include "mpi-types.h" - -/* Included for compatibility... */ -#define DIGIT_BIT MP_DIGIT_BIT -#define DIGIT_MAX MP_DIGIT_MAX - -/* Macros for accessing the mp_int internals */ -#define SIGN(MP) ((MP)->sign) -#define USED(MP) ((MP)->used) -#define ALLOC(MP) ((MP)->alloc) -#define DIGITS(MP) ((MP)->dp) -#define DIGIT(MP,N) (MP)->dp[(N)] - -#if MP_ARGCHK == 1 -#define ARGCHK(X,Y) {if(!(X)){return (Y);}} -#elif MP_ARGCHK == 2 -#include <assert.h> -#define ARGCHK(X,Y) assert(X) -#else -#define ARGCHK(X,Y) /* */ -#endif - -/* This defines the maximum I/O base (minimum is 2) */ -#define MAX_RADIX 64 - -typedef struct { - mp_sign sign; /* sign of this quantity */ - mp_size alloc; /* how many digits allocated */ - mp_size used; /* how many digits used */ - mp_digit *dp; /* the digits themselves */ -} mp_int; - -/*------------------------------------------------------------------------*/ -/* Default precision */ - -unsigned int mp_get_prec(void); -void mp_set_prec(unsigned int prec); - -/*------------------------------------------------------------------------*/ -/* Memory management */ - -mp_err mp_init(mp_int *mp); -mp_err mp_init_array(mp_int mp[], int count); -mp_err mp_init_size(mp_int *mp, mp_size prec); -mp_err mp_init_copy(mp_int *mp, mp_int *from); -mp_err mp_copy(mp_int *from, mp_int *to); -void mp_exch(mp_int *mp1, mp_int *mp2); -void mp_clear(mp_int *mp); -void mp_clear_array(mp_int mp[], int count); -void mp_zero(mp_int *mp); -void mp_set(mp_int *mp, mp_digit d); -mp_err mp_set_int(mp_int *mp, long z); -mp_err mp_shrink(mp_int *a); - - -/*------------------------------------------------------------------------*/ -/* Single digit arithmetic */ - -mp_err mp_add_d(mp_int *a, mp_digit d, mp_int *b); -mp_err mp_sub_d(mp_int *a, mp_digit d, mp_int *b); -mp_err mp_mul_d(mp_int *a, mp_digit d, mp_int *b); -mp_err mp_mul_2(mp_int *a, mp_int *c); -mp_err mp_div_d(mp_int *a, mp_digit d, mp_int *q, mp_digit *r); -mp_err mp_div_2(mp_int *a, mp_int *c); -mp_err mp_expt_d(mp_int *a, mp_digit d, mp_int *c); - -/*------------------------------------------------------------------------*/ -/* Sign manipulations */ - -mp_err mp_abs(mp_int *a, mp_int *b); -mp_err mp_neg(mp_int *a, mp_int *b); - -/*------------------------------------------------------------------------*/ -/* Full arithmetic */ - -mp_err mp_add(mp_int *a, mp_int *b, mp_int *c); -mp_err mp_sub(mp_int *a, mp_int *b, mp_int *c); -mp_err mp_mul(mp_int *a, mp_int *b, mp_int *c); -mp_err mp_mul_2d(mp_int *a, mp_digit d, mp_int *c); -#if MP_SQUARE -mp_err mp_sqr(mp_int *a, mp_int *b); -#else -#define mp_sqr(a, b) mp_mul(a, a, b) -#endif -mp_err mp_div(mp_int *a, mp_int *b, mp_int *q, mp_int *r); -mp_err mp_div_2d(mp_int *a, mp_digit d, mp_int *q, mp_int *r); -mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c); -mp_err mp_2expt(mp_int *a, mp_digit k); -mp_err mp_sqrt(mp_int *a, mp_int *b); - -/*------------------------------------------------------------------------*/ -/* Modular arithmetic */ - -#if MP_MODARITH -mp_err mp_mod(mp_int *a, mp_int *m, mp_int *c); -mp_err mp_mod_d(mp_int *a, mp_digit d, mp_digit *c); -mp_err mp_addmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c); -mp_err mp_submod(mp_int *a, mp_int *b, mp_int *m, mp_int *c); -mp_err mp_mulmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c); -#if MP_SQUARE -mp_err mp_sqrmod(mp_int *a, mp_int *m, mp_int *c); -#else -#define mp_sqrmod(a, m, c) mp_mulmod(a, a, m, c) -#endif -mp_err mp_exptmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c); -mp_err mp_exptmod_d(mp_int *a, mp_digit d, mp_int *m, mp_int *c); -#endif /* MP_MODARITH */ - -/*------------------------------------------------------------------------*/ -/* Comparisons */ - -int mp_cmp_z(mp_int *a); -int mp_cmp_d(mp_int *a, mp_digit d); -int mp_cmp(mp_int *a, mp_int *b); -int mp_cmp_mag(mp_int *a, mp_int *b); -int mp_cmp_int(mp_int *a, long z); -int mp_isodd(mp_int *a); -int mp_iseven(mp_int *a); - -/*------------------------------------------------------------------------*/ -/* Number theoretic */ - -#if MP_NUMTH -mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c); -mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c); -mp_err mp_xgcd(mp_int *a, mp_int *b, mp_int *g, mp_int *x, mp_int *y); -mp_err mp_invmod(mp_int *a, mp_int *m, mp_int *c); -#endif /* end MP_NUMTH */ - -/*------------------------------------------------------------------------*/ -/* Input and output */ - -#if MP_IOFUNC -void mp_print(mp_int *mp, FILE *ofp); -#endif /* end MP_IOFUNC */ - -/*------------------------------------------------------------------------*/ -/* Base conversion */ - -#define BITS 1 -#define BYTES CHAR_BIT - -mp_err mp_read_signed_bin(mp_int *mp, unsigned char *str, int len); -int mp_signed_bin_size(mp_int *mp); -mp_err mp_to_signed_bin(mp_int *mp, unsigned char *str); - -mp_err mp_read_unsigned_bin(mp_int *mp, unsigned char *str, int len); -int mp_unsigned_bin_size(mp_int *mp); -mp_err mp_to_unsigned_bin(mp_int *mp, unsigned char *str); - -int mp_count_bits(mp_int *mp); - -#if MP_COMPAT_MACROS -#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len)) -#define mp_raw_size(mp) mp_signed_bin_size(mp) -#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str)) -#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len)) -#define mp_mag_size(mp) mp_unsigned_bin_size(mp) -#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str)) -#endif - -mp_err mp_read_radix(mp_int *mp, unsigned char *str, int radix); -int mp_radix_size(mp_int *mp, int radix); -int mp_value_radix_size(int num, int qty, int radix); -mp_err mp_toradix(mp_int *mp, char *str, int radix); - -int mp_char2value(char ch, int r); - -#define mp_tobinary(M, S) mp_toradix((M), (S), 2) -#define mp_tooctal(M, S) mp_toradix((M), (S), 8) -#define mp_todecimal(M, S) mp_toradix((M), (S), 10) -#define mp_tohex(M, S) mp_toradix((M), (S), 16) - -/*------------------------------------------------------------------------*/ -/* Error strings */ - -const char *mp_strerror(mp_err ec); - -#endif /* end _H_MPI_ */ - -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ diff --git a/libtommath/mtest/mtest.c b/libtommath/mtest/mtest.c deleted file mode 100644 index af86920..0000000 --- a/libtommath/mtest/mtest.c +++ /dev/null @@ -1,374 +0,0 @@ -/* makes a bignum test harness with NUM tests per operation - * - * the output is made in the following format [one parameter per line] - -operation -operand1 -operand2 -[... operandN] -result1 -result2 -[... resultN] - -So for example "a * b mod n" would be - -mulmod -a -b -n -a*b mod n - -e.g. if a=3, b=4 n=11 then - -mulmod -3 -4 -11 -1 - - */ - -#ifdef MP_8BIT -#define THE_MASK 127 -#else -#define THE_MASK 32767 -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <time.h> -#include "mpi.c" - -#ifdef LTM_MTEST_REAL_RAND -#define getRandChar() fgetc(rng) -FILE *rng; -#else -#define getRandChar() (rand()&0xFF) -#endif - -void rand_num(mp_int *a) -{ - int size; - unsigned char buf[2048]; - size_t sz; - - size = 1 + ((getRandChar()<<8) + getRandChar()) % 101; - buf[0] = (getRandChar()&1)?1:0; -#ifdef LTM_MTEST_REAL_RAND - sz = fread(buf+1, 1, size, rng); -#else - sz = 1; - while (sz < (unsigned)size) { - buf[sz] = getRandChar(); - ++sz; - } -#endif - if (sz != (unsigned)size) { - fprintf(stderr, "\nWarning: fread failed\n\n"); - } - while (buf[1] == 0) buf[1] = getRandChar(); - mp_read_raw(a, buf, 1+size); -} - -void rand_num2(mp_int *a) -{ - int size; - unsigned char buf[2048]; - size_t sz; - - size = 10 + ((getRandChar()<<8) + getRandChar()) % 101; - buf[0] = (getRandChar()&1)?1:0; -#ifdef LTM_MTEST_REAL_RAND - sz = fread(buf+1, 1, size, rng); -#else - sz = 1; - while (sz < (unsigned)size) { - buf[sz] = getRandChar(); - ++sz; - } -#endif - if (sz != (unsigned)size) { - fprintf(stderr, "\nWarning: fread failed\n\n"); - } - while (buf[1] == 0) buf[1] = getRandChar(); - mp_read_raw(a, buf, 1+size); -} - -#define mp_to64(a, b) mp_toradix(a, b, 64) - -int main(int argc, char *argv[]) -{ - int n, tmp; - long long max; - mp_int a, b, c, d, e; -#ifdef MTEST_NO_FULLSPEED - clock_t t1; -#endif - char buf[4096]; - - mp_init(&a); - mp_init(&b); - mp_init(&c); - mp_init(&d); - mp_init(&e); - - if (argc > 1) { - max = strtol(argv[1], NULL, 0); - if (max < 0) { - if (max > -64) { - max = (1 << -(max)) + 1; - } else { - max = 1; - } - } else if (max == 0) { - max = 1; - } - } - else { - max = 0; - } - - - /* initial (2^n - 1)^2 testing, makes sure the comba multiplier works [it has the new carry code] */ -/* - mp_set(&a, 1); - for (n = 1; n < 8192; n++) { - mp_mul(&a, &a, &c); - printf("mul\n"); - mp_to64(&a, buf); - printf("%s\n%s\n", buf, buf); - mp_to64(&c, buf); - printf("%s\n", buf); - - mp_add_d(&a, 1, &a); - mp_mul_2(&a, &a); - mp_sub_d(&a, 1, &a); - } -*/ - -#ifdef LTM_MTEST_REAL_RAND - rng = fopen("/dev/urandom", "rb"); - if (rng == NULL) { - rng = fopen("/dev/random", "rb"); - if (rng == NULL) { - fprintf(stderr, "\nWarning: stdin used as random source\n\n"); - rng = stdin; - } - } -#else - srand(23); -#endif - -#ifdef MTEST_NO_FULLSPEED - t1 = clock(); -#endif - for (;;) { -#ifdef MTEST_NO_FULLSPEED - if (clock() - t1 > CLOCKS_PER_SEC) { - sleep(2); - t1 = clock(); - } -#endif - n = getRandChar() % 15; - - if (max != 0) { - --max; - if (max == 0) - n = 255; - } - - if (n == 0) { - /* add tests */ - rand_num(&a); - rand_num(&b); - mp_add(&a, &b, &c); - printf("add\n"); - mp_to64(&a, buf); - printf("%s\n", buf); - mp_to64(&b, buf); - printf("%s\n", buf); - mp_to64(&c, buf); - printf("%s\n", buf); - } else if (n == 1) { - /* sub tests */ - rand_num(&a); - rand_num(&b); - mp_sub(&a, &b, &c); - printf("sub\n"); - mp_to64(&a, buf); - printf("%s\n", buf); - mp_to64(&b, buf); - printf("%s\n", buf); - mp_to64(&c, buf); - printf("%s\n", buf); - } else if (n == 2) { - /* mul tests */ - rand_num(&a); - rand_num(&b); - mp_mul(&a, &b, &c); - printf("mul\n"); - mp_to64(&a, buf); - printf("%s\n", buf); - mp_to64(&b, buf); - printf("%s\n", buf); - mp_to64(&c, buf); - printf("%s\n", buf); - } else if (n == 3) { - /* div tests */ - rand_num(&a); - rand_num(&b); - mp_div(&a, &b, &c, &d); - printf("div\n"); - mp_to64(&a, buf); - printf("%s\n", buf); - mp_to64(&b, buf); - printf("%s\n", buf); - mp_to64(&c, buf); - printf("%s\n", buf); - mp_to64(&d, buf); - printf("%s\n", buf); - } else if (n == 4) { - /* sqr tests */ - rand_num(&a); - mp_sqr(&a, &b); - printf("sqr\n"); - mp_to64(&a, buf); - printf("%s\n", buf); - mp_to64(&b, buf); - printf("%s\n", buf); - } else if (n == 5) { - /* mul_2d test */ - rand_num(&a); - mp_copy(&a, &b); - n = getRandChar() & 63; - mp_mul_2d(&b, n, &b); - mp_to64(&a, buf); - printf("mul2d\n"); - printf("%s\n", buf); - printf("%d\n", n); - mp_to64(&b, buf); - printf("%s\n", buf); - } else if (n == 6) { - /* div_2d test */ - rand_num(&a); - mp_copy(&a, &b); - n = getRandChar() & 63; - mp_div_2d(&b, n, &b, NULL); - mp_to64(&a, buf); - printf("div2d\n"); - printf("%s\n", buf); - printf("%d\n", n); - mp_to64(&b, buf); - printf("%s\n", buf); - } else if (n == 7) { - /* gcd test */ - rand_num(&a); - rand_num(&b); - a.sign = MP_ZPOS; - b.sign = MP_ZPOS; - mp_gcd(&a, &b, &c); - printf("gcd\n"); - mp_to64(&a, buf); - printf("%s\n", buf); - mp_to64(&b, buf); - printf("%s\n", buf); - mp_to64(&c, buf); - printf("%s\n", buf); - } else if (n == 8) { - /* lcm test */ - rand_num(&a); - rand_num(&b); - a.sign = MP_ZPOS; - b.sign = MP_ZPOS; - mp_lcm(&a, &b, &c); - printf("lcm\n"); - mp_to64(&a, buf); - printf("%s\n", buf); - mp_to64(&b, buf); - printf("%s\n", buf); - mp_to64(&c, buf); - printf("%s\n", buf); - } else if (n == 9) { - /* exptmod test */ - rand_num2(&a); - rand_num2(&b); - rand_num2(&c); -// if (c.dp[0]&1) mp_add_d(&c, 1, &c); - a.sign = b.sign = c.sign = 0; - mp_exptmod(&a, &b, &c, &d); - printf("expt\n"); - mp_to64(&a, buf); - printf("%s\n", buf); - mp_to64(&b, buf); - printf("%s\n", buf); - mp_to64(&c, buf); - printf("%s\n", buf); - mp_to64(&d, buf); - printf("%s\n", buf); - } else if (n == 10) { - /* invmod test */ - do { - rand_num2(&a); - rand_num2(&b); - b.sign = MP_ZPOS; - a.sign = MP_ZPOS; - mp_gcd(&a, &b, &c); - } while (mp_cmp_d(&c, 1) != 0 || mp_cmp_d(&b, 1) == 0); - mp_invmod(&a, &b, &c); - printf("invmod\n"); - mp_to64(&a, buf); - printf("%s\n", buf); - mp_to64(&b, buf); - printf("%s\n", buf); - mp_to64(&c, buf); - printf("%s\n", buf); - } else if (n == 11) { - rand_num(&a); - mp_mul_2(&a, &a); - mp_div_2(&a, &b); - printf("div2\n"); - mp_to64(&a, buf); - printf("%s\n", buf); - mp_to64(&b, buf); - printf("%s\n", buf); - } else if (n == 12) { - rand_num2(&a); - mp_mul_2(&a, &b); - printf("mul2\n"); - mp_to64(&a, buf); - printf("%s\n", buf); - mp_to64(&b, buf); - printf("%s\n", buf); - } else if (n == 13) { - rand_num2(&a); - tmp = abs(rand()) & THE_MASK; - mp_add_d(&a, tmp, &b); - printf("add_d\n"); - mp_to64(&a, buf); - printf("%s\n%d\n", buf, tmp); - mp_to64(&b, buf); - printf("%s\n", buf); - } else if (n == 14) { - rand_num2(&a); - tmp = abs(rand()) & THE_MASK; - mp_sub_d(&a, tmp, &b); - printf("sub_d\n"); - mp_to64(&a, buf); - printf("%s\n%d\n", buf, tmp); - mp_to64(&b, buf); - printf("%s\n", buf); - } else if (n == 255) { - printf("exit\n"); - break; - } - - } -#ifdef LTM_MTEST_REAL_RAND - fclose(rng); -#endif - return 0; -} - -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ diff --git a/libtommath/parsenames.pl b/libtommath/parsenames.pl deleted file mode 100755 index 6703971..0000000 --- a/libtommath/parsenames.pl +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/perl -# -# Splits the list of files and outputs for makefile type files -# wrapped at 80 chars -# -# Tom St Denis -use strict; -use warnings; - -my @a = split ' ', $ARGV[1]; -my $b = $ARGV[0] . '='; -my $len = length $b; -print $b; -foreach my $obj (@a) { - $len = $len + length $obj; - $obj =~ s/\*/\$/; - if ($len > 100) { - printf "\\\n"; - $len = length $obj; - } - print $obj . ' '; -} - -print "\n\n"; - -# ref: $Format:%D$ -# git commit: $Format:%H$ -# commit time: $Format:%ai$ diff --git a/libtommath/pics/design_process.sxd b/libtommath/pics/design_process.sxd Binary files differdeleted file mode 100644 index 7414dbb..0000000 --- a/libtommath/pics/design_process.sxd +++ /dev/null diff --git a/libtommath/pics/design_process.tif b/libtommath/pics/design_process.tif Binary files differdeleted file mode 100644 index 4a0c012..0000000 --- a/libtommath/pics/design_process.tif +++ /dev/null diff --git a/libtommath/pics/expt_state.sxd b/libtommath/pics/expt_state.sxd Binary files differdeleted file mode 100644 index 6518404..0000000 --- a/libtommath/pics/expt_state.sxd +++ /dev/null diff --git a/libtommath/pics/expt_state.tif b/libtommath/pics/expt_state.tif Binary files differdeleted file mode 100644 index cb06e8e..0000000 --- a/libtommath/pics/expt_state.tif +++ /dev/null diff --git a/libtommath/pics/makefile b/libtommath/pics/makefile deleted file mode 100644 index 3ecb02f..0000000 --- a/libtommath/pics/makefile +++ /dev/null @@ -1,35 +0,0 @@ -# makes the images... yeah - -default: pses - -design_process.ps: design_process.tif - tiff2ps -s -e design_process.tif > design_process.ps - -sliding_window.ps: sliding_window.tif - tiff2ps -s -e sliding_window.tif > sliding_window.ps - -expt_state.ps: expt_state.tif - tiff2ps -s -e expt_state.tif > expt_state.ps - -primality.ps: primality.tif - tiff2ps -s -e primality.tif > primality.ps - -design_process.pdf: design_process.ps - epstopdf design_process.ps - -sliding_window.pdf: sliding_window.ps - epstopdf sliding_window.ps - -expt_state.pdf: expt_state.ps - epstopdf expt_state.ps - -primality.pdf: primality.ps - epstopdf primality.ps - - -pses: sliding_window.ps expt_state.ps primality.ps design_process.ps -pdfes: sliding_window.pdf expt_state.pdf primality.pdf design_process.pdf - -clean: - rm -rf *.ps *.pdf .xvpics -
\ No newline at end of file diff --git a/libtommath/pics/primality.tif b/libtommath/pics/primality.tif Binary files differdeleted file mode 100644 index 76d6be3..0000000 --- a/libtommath/pics/primality.tif +++ /dev/null diff --git a/libtommath/pics/radix.sxd b/libtommath/pics/radix.sxd Binary files differdeleted file mode 100644 index b9eb9a0..0000000 --- a/libtommath/pics/radix.sxd +++ /dev/null diff --git a/libtommath/pics/sliding_window.sxd b/libtommath/pics/sliding_window.sxd Binary files differdeleted file mode 100644 index 91e7c0d..0000000 --- a/libtommath/pics/sliding_window.sxd +++ /dev/null diff --git a/libtommath/pics/sliding_window.tif b/libtommath/pics/sliding_window.tif Binary files differdeleted file mode 100644 index bb4cb96..0000000 --- a/libtommath/pics/sliding_window.tif +++ /dev/null diff --git a/libtommath/poster.out b/libtommath/poster.out deleted file mode 100644 index e69de29..0000000 --- a/libtommath/poster.out +++ /dev/null diff --git a/libtommath/poster.tex b/libtommath/poster.tex deleted file mode 100644 index e7388f4..0000000 --- a/libtommath/poster.tex +++ /dev/null @@ -1,35 +0,0 @@ -\documentclass[landscape,11pt]{article} -\usepackage{amsmath, amssymb} -\usepackage{hyperref} -\begin{document} -\hspace*{-3in} -\begin{tabular}{llllll} -$c = a + b$ & {\tt mp\_add(\&a, \&b, \&c)} & $b = 2a$ & {\tt mp\_mul\_2(\&a, \&b)} & \\ -$c = a - b$ & {\tt mp\_sub(\&a, \&b, \&c)} & $b = a/2$ & {\tt mp\_div\_2(\&a, \&b)} & \\ -$c = ab $ & {\tt mp\_mul(\&a, \&b, \&c)} & $c = 2^ba$ & {\tt mp\_mul\_2d(\&a, b, \&c)} \\ -$b = a^2 $ & {\tt mp\_sqr(\&a, \&b)} & $c = a/2^b, d = a \mod 2^b$ & {\tt mp\_div\_2d(\&a, b, \&c, \&d)} \\ -$c = \lfloor a/b \rfloor, d = a \mod b$ & {\tt mp\_div(\&a, \&b, \&c, \&d)} & $c = a \mod 2^b $ & {\tt mp\_mod\_2d(\&a, b, \&c)} \\ - && \\ -$a = b $ & {\tt mp\_set\_int(\&a, b)} & $c = a \vee b$ & {\tt mp\_or(\&a, \&b, \&c)} \\ -$b = a $ & {\tt mp\_copy(\&a, \&b)} & $c = a \wedge b$ & {\tt mp\_and(\&a, \&b, \&c)} \\ - && $c = a \oplus b$ & {\tt mp\_xor(\&a, \&b, \&c)} \\ - & \\ -$b = -a $ & {\tt mp\_neg(\&a, \&b)} & $d = a + b \mod c$ & {\tt mp\_addmod(\&a, \&b, \&c, \&d)} \\ -$b = |a| $ & {\tt mp\_abs(\&a, \&b)} & $d = a - b \mod c$ & {\tt mp\_submod(\&a, \&b, \&c, \&d)} \\ - && $d = ab \mod c$ & {\tt mp\_mulmod(\&a, \&b, \&c, \&d)} \\ -Compare $a$ and $b$ & {\tt mp\_cmp(\&a, \&b)} & $c = a^2 \mod b$ & {\tt mp\_sqrmod(\&a, \&b, \&c)} \\ -Is Zero? & {\tt mp\_iszero(\&a)} & $c = a^{-1} \mod b$ & {\tt mp\_invmod(\&a, \&b, \&c)} \\ -Is Even? & {\tt mp\_iseven(\&a)} & $d = a^b \mod c$ & {\tt mp\_exptmod(\&a, \&b, \&c, \&d)} \\ -Is Odd ? & {\tt mp\_isodd(\&a)} \\ -&\\ -$\vert \vert a \vert \vert$ & {\tt mp\_unsigned\_bin\_size(\&a)} & $res$ = 1 if $a$ prime to $t$ rounds? & {\tt mp\_prime\_is\_prime(\&a, t, \&res)} \\ -$buf \leftarrow a$ & {\tt mp\_to\_unsigned\_bin(\&a, buf)} & Next prime after $a$ to $t$ rounds. & {\tt mp\_prime\_next\_prime(\&a, t, bbs\_style)} \\ -$a \leftarrow buf[0..len-1]$ & {\tt mp\_read\_unsigned\_bin(\&a, buf, len)} \\ -&\\ -$b = \sqrt{a}$ & {\tt mp\_sqrt(\&a, \&b)} & $c = \mbox{gcd}(a, b)$ & {\tt mp\_gcd(\&a, \&b, \&c)} \\ -$c = a^{1/b}$ & {\tt mp\_n\_root(\&a, b, \&c)} & $c = \mbox{lcm}(a, b)$ & {\tt mp\_lcm(\&a, \&b, \&c)} \\ -&\\ -Greater Than & MP\_GT & Equal To & MP\_EQ \\ -Less Than & MP\_LT & Bits per digit & DIGIT\_BIT \\ -\end{tabular} -\end{document} diff --git a/libtommath/pre_gen/mpi.c b/libtommath/pre_gen/mpi.c deleted file mode 100644 index 180bc57..0000000 --- a/libtommath/pre_gen/mpi.c +++ /dev/null @@ -1,10108 +0,0 @@ -/* Start: bn_error.c */ -#include <tommath_private.h> -#ifdef BN_ERROR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -static const struct { - int code; - const char *msg; -} msgs[] = { - { MP_OKAY, "Successful" }, - { MP_MEM, "Out of heap" }, - { MP_VAL, "Value out of range" } -}; - -/* return a char * string for a given code */ -const char *mp_error_to_string(int code) -{ - int x; - - /* scan the lookup table for the given message */ - for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) { - if (msgs[x].code == code) { - return msgs[x].msg; - } - } - - /* generic reply for invalid code */ - return "Invalid error code"; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_error.c */ - -/* Start: bn_fast_mp_invmod.c */ -#include <tommath_private.h> -#ifdef BN_FAST_MP_INVMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* computes the modular inverse via binary extended euclidean algorithm, - * that is c = 1/a mod b - * - * Based on slow invmod except this is optimized for the case where b is - * odd as per HAC Note 14.64 on pp. 610 - */ -int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int x, y, u, v, B, D; - int res, neg; - - /* 2. [modified] b must be odd */ - if (mp_iseven (b) == MP_YES) { - return MP_VAL; - } - - /* init all our temps */ - if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) { - return res; - } - - /* x == modulus, y == value to invert */ - if ((res = mp_copy (b, &x)) != MP_OKAY) { - goto LBL_ERR; - } - - /* we need y = |a| */ - if ((res = mp_mod (a, b, &y)) != MP_OKAY) { - goto LBL_ERR; - } - - /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ - if ((res = mp_copy (&x, &u)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_copy (&y, &v)) != MP_OKAY) { - goto LBL_ERR; - } - mp_set (&D, 1); - -top: - /* 4. while u is even do */ - while (mp_iseven (&u) == MP_YES) { - /* 4.1 u = u/2 */ - if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { - goto LBL_ERR; - } - /* 4.2 if B is odd then */ - if (mp_isodd (&B) == MP_YES) { - if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* B = B/2 */ - if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 5. while v is even do */ - while (mp_iseven (&v) == MP_YES) { - /* 5.1 v = v/2 */ - if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { - goto LBL_ERR; - } - /* 5.2 if D is odd then */ - if (mp_isodd (&D) == MP_YES) { - /* D = (D-x)/2 */ - if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* D = D/2 */ - if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 6. if u >= v then */ - if (mp_cmp (&u, &v) != MP_LT) { - /* u = u - v, B = B - D */ - if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } else { - /* v - v - u, D = D - B */ - if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* if not zero goto step 4 */ - if (mp_iszero (&u) == MP_NO) { - goto top; - } - - /* now a = C, b = D, gcd == g*v */ - - /* if v != 1 then there is no inverse */ - if (mp_cmp_d (&v, 1) != MP_EQ) { - res = MP_VAL; - goto LBL_ERR; - } - - /* b is now the inverse */ - neg = a->sign; - while (D.sign == MP_NEG) { - if ((res = mp_add (&D, b, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - mp_exch (&D, c); - c->sign = neg; - res = MP_OKAY; - -LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL); - return res; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_fast_mp_invmod.c */ - -/* Start: bn_fast_mp_montgomery_reduce.c */ -#include <tommath_private.h> -#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* computes xR**-1 == x (mod N) via Montgomery Reduction - * - * This is an optimized implementation of montgomery_reduce - * which uses the comba method to quickly calculate the columns of the - * reduction. - * - * Based on Algorithm 14.32 on pp.601 of HAC. -*/ -int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) -{ - int ix, res, olduse; - mp_word W[MP_WARRAY]; - - /* get old used count */ - olduse = x->used; - - /* grow a as required */ - if (x->alloc < (n->used + 1)) { - if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) { - return res; - } - } - - /* first we have to get the digits of the input into - * an array of double precision words W[...] - */ - { - mp_word *_W; - mp_digit *tmpx; - - /* alias for the W[] array */ - _W = W; - - /* alias for the digits of x*/ - tmpx = x->dp; - - /* copy the digits of a into W[0..a->used-1] */ - for (ix = 0; ix < x->used; ix++) { - *_W++ = *tmpx++; - } - - /* zero the high words of W[a->used..m->used*2] */ - for (; ix < ((n->used * 2) + 1); ix++) { - *_W++ = 0; - } - } - - /* now we proceed to zero successive digits - * from the least significant upwards - */ - for (ix = 0; ix < n->used; ix++) { - /* mu = ai * m' mod b - * - * We avoid a double precision multiplication (which isn't required) - * by casting the value down to a mp_digit. Note this requires - * that W[ix-1] have the carry cleared (see after the inner loop) - */ - mp_digit mu; - mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK); - - /* a = a + mu * m * b**i - * - * This is computed in place and on the fly. The multiplication - * by b**i is handled by offseting which columns the results - * are added to. - * - * Note the comba method normally doesn't handle carries in the - * inner loop In this case we fix the carry from the previous - * column since the Montgomery reduction requires digits of the - * result (so far) [see above] to work. This is - * handled by fixing up one carry after the inner loop. The - * carry fixups are done in order so after these loops the - * first m->used words of W[] have the carries fixed - */ - { - int iy; - mp_digit *tmpn; - mp_word *_W; - - /* alias for the digits of the modulus */ - tmpn = n->dp; - - /* Alias for the columns set by an offset of ix */ - _W = W + ix; - - /* inner loop */ - for (iy = 0; iy < n->used; iy++) { - *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++); - } - } - - /* now fix carry for next digit, W[ix+1] */ - W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT); - } - - /* now we have to propagate the carries and - * shift the words downward [all those least - * significant digits we zeroed]. - */ - { - mp_digit *tmpx; - mp_word *_W, *_W1; - - /* nox fix rest of carries */ - - /* alias for current word */ - _W1 = W + ix; - - /* alias for next word, where the carry goes */ - _W = W + ++ix; - - for (; ix <= ((n->used * 2) + 1); ix++) { - *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT); - } - - /* copy out, A = A/b**n - * - * The result is A/b**n but instead of converting from an - * array of mp_word to mp_digit than calling mp_rshd - * we just copy them in the right order - */ - - /* alias for destination word */ - tmpx = x->dp; - - /* alias for shifted double precision result */ - _W = W + n->used; - - for (ix = 0; ix < (n->used + 1); ix++) { - *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK)); - } - - /* zero oldused digits, if the input a was larger than - * m->used+1 we'll have to clear the digits - */ - for (; ix < olduse; ix++) { - *tmpx++ = 0; - } - } - - /* set the max used and clamp */ - x->used = n->used + 1; - mp_clamp (x); - - /* if A >= m then A = A - m */ - if (mp_cmp_mag (x, n) != MP_LT) { - return s_mp_sub (x, n, x); - } - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_fast_mp_montgomery_reduce.c */ - -/* Start: bn_fast_s_mp_mul_digs.c */ -#include <tommath_private.h> -#ifdef BN_FAST_S_MP_MUL_DIGS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* Fast (comba) multiplier - * - * This is the fast column-array [comba] multiplier. It is - * designed to compute the columns of the product first - * then handle the carries afterwards. This has the effect - * of making the nested loops that compute the columns very - * simple and schedulable on super-scalar processors. - * - * This has been modified to produce a variable number of - * digits of output so if say only a half-product is required - * you don't have to compute the upper half (a feature - * required for fast Barrett reduction). - * - * Based on Algorithm 14.12 on pp.595 of HAC. - * - */ -int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - int olduse, res, pa, ix, iz; - mp_digit W[MP_WARRAY]; - mp_word _W; - - /* grow the destination as required */ - if (c->alloc < digs) { - if ((res = mp_grow (c, digs)) != MP_OKAY) { - return res; - } - } - - /* number of output digits to produce */ - pa = MIN(digs, a->used + b->used); - - /* clear the carry */ - _W = 0; - for (ix = 0; ix < pa; ix++) { - int tx, ty; - int iy; - mp_digit *tmpx, *tmpy; - - /* get offsets into the two bignums */ - ty = MIN(b->used-1, ix); - tx = ix - ty; - - /* setup temp aliases */ - tmpx = a->dp + tx; - tmpy = b->dp + ty; - - /* this is the number of times the loop will iterrate, essentially - while (tx++ < a->used && ty-- >= 0) { ... } - */ - iy = MIN(a->used-tx, ty+1); - - /* execute loop */ - for (iz = 0; iz < iy; ++iz) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); - - } - - /* store term */ - W[ix] = ((mp_digit)_W) & MP_MASK; - - /* make next carry */ - _W = _W >> ((mp_word)DIGIT_BIT); - } - - /* setup dest */ - olduse = c->used; - c->used = pa; - - { - mp_digit *tmpc; - tmpc = c->dp; - for (ix = 0; ix < (pa + 1); ix++) { - /* now extract the previous digit [below the carry] */ - *tmpc++ = W[ix]; - } - - /* clear unused digits [that existed in the old copy of c] */ - for (; ix < olduse; ix++) { - *tmpc++ = 0; - } - } - mp_clamp (c); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_fast_s_mp_mul_digs.c */ - -/* Start: bn_fast_s_mp_mul_high_digs.c */ -#include <tommath_private.h> -#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* this is a modified version of fast_s_mul_digs that only produces - * output digits *above* digs. See the comments for fast_s_mul_digs - * to see how it works. - * - * This is used in the Barrett reduction since for one of the multiplications - * only the higher digits were needed. This essentially halves the work. - * - * Based on Algorithm 14.12 on pp.595 of HAC. - */ -int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - int olduse, res, pa, ix, iz; - mp_digit W[MP_WARRAY]; - mp_word _W; - - /* grow the destination as required */ - pa = a->used + b->used; - if (c->alloc < pa) { - if ((res = mp_grow (c, pa)) != MP_OKAY) { - return res; - } - } - - /* number of output digits to produce */ - pa = a->used + b->used; - _W = 0; - for (ix = digs; ix < pa; ix++) { - int tx, ty, iy; - mp_digit *tmpx, *tmpy; - - /* get offsets into the two bignums */ - ty = MIN(b->used-1, ix); - tx = ix - ty; - - /* setup temp aliases */ - tmpx = a->dp + tx; - tmpy = b->dp + ty; - - /* this is the number of times the loop will iterrate, essentially its - while (tx++ < a->used && ty-- >= 0) { ... } - */ - iy = MIN(a->used-tx, ty+1); - - /* execute loop */ - for (iz = 0; iz < iy; iz++) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); - } - - /* store term */ - W[ix] = ((mp_digit)_W) & MP_MASK; - - /* make next carry */ - _W = _W >> ((mp_word)DIGIT_BIT); - } - - /* setup dest */ - olduse = c->used; - c->used = pa; - - { - mp_digit *tmpc; - - tmpc = c->dp + digs; - for (ix = digs; ix < pa; ix++) { - /* now extract the previous digit [below the carry] */ - *tmpc++ = W[ix]; - } - - /* clear unused digits [that existed in the old copy of c] */ - for (; ix < olduse; ix++) { - *tmpc++ = 0; - } - } - mp_clamp (c); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_fast_s_mp_mul_high_digs.c */ - -/* Start: bn_fast_s_mp_sqr.c */ -#include <tommath_private.h> -#ifdef BN_FAST_S_MP_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* the jist of squaring... - * you do like mult except the offset of the tmpx [one that - * starts closer to zero] can't equal the offset of tmpy. - * So basically you set up iy like before then you min it with - * (ty-tx) so that it never happens. You double all those - * you add in the inner loop - -After that loop you do the squares and add them in. -*/ - -int fast_s_mp_sqr (mp_int * a, mp_int * b) -{ - int olduse, res, pa, ix, iz; - mp_digit W[MP_WARRAY], *tmpx; - mp_word W1; - - /* grow the destination as required */ - pa = a->used + a->used; - if (b->alloc < pa) { - if ((res = mp_grow (b, pa)) != MP_OKAY) { - return res; - } - } - - /* number of output digits to produce */ - W1 = 0; - for (ix = 0; ix < pa; ix++) { - int tx, ty, iy; - mp_word _W; - mp_digit *tmpy; - - /* clear counter */ - _W = 0; - - /* get offsets into the two bignums */ - ty = MIN(a->used-1, ix); - tx = ix - ty; - - /* setup temp aliases */ - tmpx = a->dp + tx; - tmpy = a->dp + ty; - - /* this is the number of times the loop will iterrate, essentially - while (tx++ < a->used && ty-- >= 0) { ... } - */ - iy = MIN(a->used-tx, ty+1); - - /* now for squaring tx can never equal ty - * we halve the distance since they approach at a rate of 2x - * and we have to round because odd cases need to be executed - */ - iy = MIN(iy, ((ty-tx)+1)>>1); - - /* execute loop */ - for (iz = 0; iz < iy; iz++) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); - } - - /* double the inner product and add carry */ - _W = _W + _W + W1; - - /* even columns have the square term in them */ - if ((ix&1) == 0) { - _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]); - } - - /* store it */ - W[ix] = (mp_digit)(_W & MP_MASK); - - /* make next carry */ - W1 = _W >> ((mp_word)DIGIT_BIT); - } - - /* setup dest */ - olduse = b->used; - b->used = a->used+a->used; - - { - mp_digit *tmpb; - tmpb = b->dp; - for (ix = 0; ix < pa; ix++) { - *tmpb++ = W[ix] & MP_MASK; - } - - /* clear unused digits [that existed in the old copy of c] */ - for (; ix < olduse; ix++) { - *tmpb++ = 0; - } - } - mp_clamp (b); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_fast_s_mp_sqr.c */ - -/* Start: bn_mp_2expt.c */ -#include <tommath_private.h> -#ifdef BN_MP_2EXPT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* computes a = 2**b - * - * Simple algorithm which zeroes the int, grows it then just sets one bit - * as required. - */ -int -mp_2expt (mp_int * a, int b) -{ - int res; - - /* zero a as per default */ - mp_zero (a); - - /* grow a to accomodate the single bit */ - if ((res = mp_grow (a, (b / DIGIT_BIT) + 1)) != MP_OKAY) { - return res; - } - - /* set the used count of where the bit will go */ - a->used = (b / DIGIT_BIT) + 1; - - /* put the single bit in its place */ - a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT); - - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_2expt.c */ - -/* Start: bn_mp_abs.c */ -#include <tommath_private.h> -#ifdef BN_MP_ABS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* b = |a| - * - * Simple function copies the input and fixes the sign to positive - */ -int -mp_abs (mp_int * a, mp_int * b) -{ - int res; - - /* copy a to b */ - if (a != b) { - if ((res = mp_copy (a, b)) != MP_OKAY) { - return res; - } - } - - /* force the sign of b to positive */ - b->sign = MP_ZPOS; - - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_abs.c */ - -/* Start: bn_mp_add.c */ -#include <tommath_private.h> -#ifdef BN_MP_ADD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* high level addition (handles signs) */ -int mp_add (mp_int * a, mp_int * b, mp_int * c) -{ - int sa, sb, res; - - /* get sign of both inputs */ - sa = a->sign; - sb = b->sign; - - /* handle two cases, not four */ - if (sa == sb) { - /* both positive or both negative */ - /* add their magnitudes, copy the sign */ - c->sign = sa; - res = s_mp_add (a, b, c); - } else { - /* one positive, the other negative */ - /* subtract the one with the greater magnitude from */ - /* the one of the lesser magnitude. The result gets */ - /* the sign of the one with the greater magnitude. */ - if (mp_cmp_mag (a, b) == MP_LT) { - c->sign = sb; - res = s_mp_sub (b, a, c); - } else { - c->sign = sa; - res = s_mp_sub (a, b, c); - } - } - return res; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_add.c */ - -/* Start: bn_mp_add_d.c */ -#include <tommath_private.h> -#ifdef BN_MP_ADD_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* single digit addition */ -int -mp_add_d (mp_int * a, mp_digit b, mp_int * c) -{ - int res, ix, oldused; - mp_digit *tmpa, *tmpc, mu; - - /* grow c as required */ - if (c->alloc < (a->used + 1)) { - if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { - return res; - } - } - - /* if a is negative and |a| >= b, call c = |a| - b */ - if ((a->sign == MP_NEG) && ((a->used > 1) || (a->dp[0] >= b))) { - /* temporarily fix sign of a */ - a->sign = MP_ZPOS; - - /* c = |a| - b */ - res = mp_sub_d(a, b, c); - - /* fix sign */ - a->sign = c->sign = MP_NEG; - - /* clamp */ - mp_clamp(c); - - return res; - } - - /* old number of used digits in c */ - oldused = c->used; - - /* source alias */ - tmpa = a->dp; - - /* destination alias */ - tmpc = c->dp; - - /* if a is positive */ - if (a->sign == MP_ZPOS) { - /* add digit, after this we're propagating - * the carry. - */ - *tmpc = *tmpa++ + b; - mu = *tmpc >> DIGIT_BIT; - *tmpc++ &= MP_MASK; - - /* now handle rest of the digits */ - for (ix = 1; ix < a->used; ix++) { - *tmpc = *tmpa++ + mu; - mu = *tmpc >> DIGIT_BIT; - *tmpc++ &= MP_MASK; - } - /* set final carry */ - ix++; - *tmpc++ = mu; - - /* setup size */ - c->used = a->used + 1; - } else { - /* a was negative and |a| < b */ - c->used = 1; - - /* the result is a single digit */ - if (a->used == 1) { - *tmpc++ = b - a->dp[0]; - } else { - *tmpc++ = b; - } - - /* setup count so the clearing of oldused - * can fall through correctly - */ - ix = 1; - } - - /* sign always positive */ - c->sign = MP_ZPOS; - - /* now zero to oldused */ - while (ix++ < oldused) { - *tmpc++ = 0; - } - mp_clamp(c); - - return MP_OKAY; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_add_d.c */ - -/* Start: bn_mp_addmod.c */ -#include <tommath_private.h> -#ifdef BN_MP_ADDMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* d = a + b (mod c) */ -int -mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) -{ - int res; - mp_int t; - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_add (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, c, d); - mp_clear (&t); - return res; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_addmod.c */ - -/* Start: bn_mp_and.c */ -#include <tommath_private.h> -#ifdef BN_MP_AND_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* AND two ints together */ -int -mp_and (mp_int * a, mp_int * b, mp_int * c) -{ - int res, ix, px; - mp_int t, *x; - - if (a->used > b->used) { - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - px = b->used; - x = b; - } else { - if ((res = mp_init_copy (&t, b)) != MP_OKAY) { - return res; - } - px = a->used; - x = a; - } - - for (ix = 0; ix < px; ix++) { - t.dp[ix] &= x->dp[ix]; - } - - /* zero digits above the last from the smallest mp_int */ - for (; ix < t.used; ix++) { - t.dp[ix] = 0; - } - - mp_clamp (&t); - mp_exch (c, &t); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_and.c */ - -/* Start: bn_mp_clamp.c */ -#include <tommath_private.h> -#ifdef BN_MP_CLAMP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* trim unused digits - * - * This is used to ensure that leading zero digits are - * trimed and the leading "used" digit will be non-zero - * Typically very fast. Also fixes the sign if there - * are no more leading digits - */ -void -mp_clamp (mp_int * a) -{ - /* decrease used while the most significant digit is - * zero. - */ - while ((a->used > 0) && (a->dp[a->used - 1] == 0)) { - --(a->used); - } - - /* reset the sign flag if used == 0 */ - if (a->used == 0) { - a->sign = MP_ZPOS; - } -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_clamp.c */ - -/* Start: bn_mp_clear.c */ -#include <tommath_private.h> -#ifdef BN_MP_CLEAR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* clear one (frees) */ -void -mp_clear (mp_int * a) -{ - int i; - - /* only do anything if a hasn't been freed previously */ - if (a->dp != NULL) { - /* first zero the digits */ - for (i = 0; i < a->used; i++) { - a->dp[i] = 0; - } - - /* free ram */ - XFREE(a->dp); - - /* reset members to make debugging easier */ - a->dp = NULL; - a->alloc = a->used = 0; - a->sign = MP_ZPOS; - } -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_clear.c */ - -/* Start: bn_mp_clear_multi.c */ -#include <tommath_private.h> -#ifdef BN_MP_CLEAR_MULTI_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ -#include <stdarg.h> - -void mp_clear_multi(mp_int *mp, ...) -{ - mp_int* next_mp = mp; - va_list args; - va_start(args, mp); - while (next_mp != NULL) { - mp_clear(next_mp); - next_mp = va_arg(args, mp_int*); - } - va_end(args); -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_clear_multi.c */ - -/* Start: bn_mp_cmp.c */ -#include <tommath_private.h> -#ifdef BN_MP_CMP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* compare two ints (signed)*/ -int -mp_cmp (mp_int * a, mp_int * b) -{ - /* compare based on sign */ - if (a->sign != b->sign) { - if (a->sign == MP_NEG) { - return MP_LT; - } else { - return MP_GT; - } - } - - /* compare digits */ - if (a->sign == MP_NEG) { - /* if negative compare opposite direction */ - return mp_cmp_mag(b, a); - } else { - return mp_cmp_mag(a, b); - } -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_cmp.c */ - -/* Start: bn_mp_cmp_d.c */ -#include <tommath_private.h> -#ifdef BN_MP_CMP_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* compare a digit */ -int mp_cmp_d(mp_int * a, mp_digit b) -{ - /* compare based on sign */ - if (a->sign == MP_NEG) { - return MP_LT; - } - - /* compare based on magnitude */ - if (a->used > 1) { - return MP_GT; - } - - /* compare the only digit of a to b */ - if (a->dp[0] > b) { - return MP_GT; - } else if (a->dp[0] < b) { - return MP_LT; - } else { - return MP_EQ; - } -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_cmp_d.c */ - -/* Start: bn_mp_cmp_mag.c */ -#include <tommath_private.h> -#ifdef BN_MP_CMP_MAG_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* compare maginitude of two ints (unsigned) */ -int mp_cmp_mag (mp_int * a, mp_int * b) -{ - int n; - mp_digit *tmpa, *tmpb; - - /* compare based on # of non-zero digits */ - if (a->used > b->used) { - return MP_GT; - } - - if (a->used < b->used) { - return MP_LT; - } - - /* alias for a */ - tmpa = a->dp + (a->used - 1); - - /* alias for b */ - tmpb = b->dp + (a->used - 1); - - /* compare based on digits */ - for (n = 0; n < a->used; ++n, --tmpa, --tmpb) { - if (*tmpa > *tmpb) { - return MP_GT; - } - - if (*tmpa < *tmpb) { - return MP_LT; - } - } - return MP_EQ; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_cmp_mag.c */ - -/* Start: bn_mp_cnt_lsb.c */ -#include <tommath_private.h> -#ifdef BN_MP_CNT_LSB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -static const int lnz[16] = { - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 -}; - -/* Counts the number of lsbs which are zero before the first zero bit */ -int mp_cnt_lsb(mp_int *a) -{ - int x; - mp_digit q, qq; - - /* easy out */ - if (mp_iszero(a) == MP_YES) { - return 0; - } - - /* scan lower digits until non-zero */ - for (x = 0; (x < a->used) && (a->dp[x] == 0); x++) {} - q = a->dp[x]; - x *= DIGIT_BIT; - - /* now scan this digit until a 1 is found */ - if ((q & 1) == 0) { - do { - qq = q & 15; - x += lnz[qq]; - q >>= 4; - } while (qq == 0); - } - return x; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_cnt_lsb.c */ - -/* Start: bn_mp_copy.c */ -#include <tommath_private.h> -#ifdef BN_MP_COPY_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* copy, b = a */ -int -mp_copy (mp_int * a, mp_int * b) -{ - int res, n; - - /* if dst == src do nothing */ - if (a == b) { - return MP_OKAY; - } - - /* grow dest */ - if (b->alloc < a->used) { - if ((res = mp_grow (b, a->used)) != MP_OKAY) { - return res; - } - } - - /* zero b and copy the parameters over */ - { - mp_digit *tmpa, *tmpb; - - /* pointer aliases */ - - /* source */ - tmpa = a->dp; - - /* destination */ - tmpb = b->dp; - - /* copy all the digits */ - for (n = 0; n < a->used; n++) { - *tmpb++ = *tmpa++; - } - - /* clear high digits */ - for (; n < b->used; n++) { - *tmpb++ = 0; - } - } - - /* copy used count and sign */ - b->used = a->used; - b->sign = a->sign; - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_copy.c */ - -/* Start: bn_mp_count_bits.c */ -#include <tommath_private.h> -#ifdef BN_MP_COUNT_BITS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* returns the number of bits in an int */ -int -mp_count_bits (mp_int * a) -{ - int r; - mp_digit q; - - /* shortcut */ - if (a->used == 0) { - return 0; - } - - /* get number of digits and add that */ - r = (a->used - 1) * DIGIT_BIT; - - /* take the last digit and count the bits in it */ - q = a->dp[a->used - 1]; - while (q > ((mp_digit) 0)) { - ++r; - q >>= ((mp_digit) 1); - } - return r; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_count_bits.c */ - -/* Start: bn_mp_div.c */ -#include <tommath_private.h> -#ifdef BN_MP_DIV_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -#ifdef BN_MP_DIV_SMALL - -/* slower bit-bang division... also smaller */ -int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d) -{ - mp_int ta, tb, tq, q; - int res, n, n2; - - /* is divisor zero ? */ - if (mp_iszero (b) == MP_YES) { - return MP_VAL; - } - - /* if a < b then q=0, r = a */ - if (mp_cmp_mag (a, b) == MP_LT) { - if (d != NULL) { - res = mp_copy (a, d); - } else { - res = MP_OKAY; - } - if (c != NULL) { - mp_zero (c); - } - return res; - } - - /* init our temps */ - if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL)) != MP_OKAY) { - return res; - } - - - mp_set(&tq, 1); - n = mp_count_bits(a) - mp_count_bits(b); - if (((res = mp_abs(a, &ta)) != MP_OKAY) || - ((res = mp_abs(b, &tb)) != MP_OKAY) || - ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) || - ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) { - goto LBL_ERR; - } - - while (n-- >= 0) { - if (mp_cmp(&tb, &ta) != MP_GT) { - if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) || - ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) { - goto LBL_ERR; - } - } - if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) || - ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) { - goto LBL_ERR; - } - } - - /* now q == quotient and ta == remainder */ - n = a->sign; - n2 = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; - if (c != NULL) { - mp_exch(c, &q); - c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2; - } - if (d != NULL) { - mp_exch(d, &ta); - d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n; - } -LBL_ERR: - mp_clear_multi(&ta, &tb, &tq, &q, NULL); - return res; -} - -#else - -/* integer signed division. - * c*b + d == a [e.g. a/b, c=quotient, d=remainder] - * HAC pp.598 Algorithm 14.20 - * - * Note that the description in HAC is horribly - * incomplete. For example, it doesn't consider - * the case where digits are removed from 'x' in - * the inner loop. It also doesn't consider the - * case that y has fewer than three digits, etc.. - * - * The overall algorithm is as described as - * 14.20 from HAC but fixed to treat these cases. -*/ -int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d) -{ - mp_int q, x, y, t1, t2; - int res, n, t, i, norm, neg; - - /* is divisor zero ? */ - if (mp_iszero (b) == MP_YES) { - return MP_VAL; - } - - /* if a < b then q=0, r = a */ - if (mp_cmp_mag (a, b) == MP_LT) { - if (d != NULL) { - res = mp_copy (a, d); - } else { - res = MP_OKAY; - } - if (c != NULL) { - mp_zero (c); - } - return res; - } - - if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) { - return res; - } - q.used = a->used + 2; - - if ((res = mp_init (&t1)) != MP_OKAY) { - goto LBL_Q; - } - - if ((res = mp_init (&t2)) != MP_OKAY) { - goto LBL_T1; - } - - if ((res = mp_init_copy (&x, a)) != MP_OKAY) { - goto LBL_T2; - } - - if ((res = mp_init_copy (&y, b)) != MP_OKAY) { - goto LBL_X; - } - - /* fix the sign */ - neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; - x.sign = y.sign = MP_ZPOS; - - /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */ - norm = mp_count_bits(&y) % DIGIT_BIT; - if (norm < (int)(DIGIT_BIT-1)) { - norm = (DIGIT_BIT-1) - norm; - if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) { - goto LBL_Y; - } - if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) { - goto LBL_Y; - } - } else { - norm = 0; - } - - /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */ - n = x.used - 1; - t = y.used - 1; - - /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */ - if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */ - goto LBL_Y; - } - - while (mp_cmp (&x, &y) != MP_LT) { - ++(q.dp[n - t]); - if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) { - goto LBL_Y; - } - } - - /* reset y by shifting it back down */ - mp_rshd (&y, n - t); - - /* step 3. for i from n down to (t + 1) */ - for (i = n; i >= (t + 1); i--) { - if (i > x.used) { - continue; - } - - /* step 3.1 if xi == yt then set q{i-t-1} to b-1, - * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ - if (x.dp[i] == y.dp[t]) { - q.dp[(i - t) - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1); - } else { - mp_word tmp; - tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT); - tmp |= ((mp_word) x.dp[i - 1]); - tmp /= ((mp_word) y.dp[t]); - if (tmp > (mp_word) MP_MASK) { - tmp = MP_MASK; - } - q.dp[(i - t) - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK)); - } - - /* while (q{i-t-1} * (yt * b + y{t-1})) > - xi * b**2 + xi-1 * b + xi-2 - - do q{i-t-1} -= 1; - */ - q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] + 1) & MP_MASK; - do { - q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1) & MP_MASK; - - /* find left hand */ - mp_zero (&t1); - t1.dp[0] = ((t - 1) < 0) ? 0 : y.dp[t - 1]; - t1.dp[1] = y.dp[t]; - t1.used = 2; - if ((res = mp_mul_d (&t1, q.dp[(i - t) - 1], &t1)) != MP_OKAY) { - goto LBL_Y; - } - - /* find right hand */ - t2.dp[0] = ((i - 2) < 0) ? 0 : x.dp[i - 2]; - t2.dp[1] = ((i - 1) < 0) ? 0 : x.dp[i - 1]; - t2.dp[2] = x.dp[i]; - t2.used = 3; - } while (mp_cmp_mag(&t1, &t2) == MP_GT); - - /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */ - if ((res = mp_mul_d (&y, q.dp[(i - t) - 1], &t1)) != MP_OKAY) { - goto LBL_Y; - } - - if ((res = mp_lshd (&t1, (i - t) - 1)) != MP_OKAY) { - goto LBL_Y; - } - - if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) { - goto LBL_Y; - } - - /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */ - if (x.sign == MP_NEG) { - if ((res = mp_copy (&y, &t1)) != MP_OKAY) { - goto LBL_Y; - } - if ((res = mp_lshd (&t1, (i - t) - 1)) != MP_OKAY) { - goto LBL_Y; - } - if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) { - goto LBL_Y; - } - - q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1UL) & MP_MASK; - } - } - - /* now q is the quotient and x is the remainder - * [which we have to normalize] - */ - - /* get sign before writing to c */ - x.sign = (x.used == 0) ? MP_ZPOS : a->sign; - - if (c != NULL) { - mp_clamp (&q); - mp_exch (&q, c); - c->sign = neg; - } - - if (d != NULL) { - if ((res = mp_div_2d (&x, norm, &x, NULL)) != MP_OKAY) { - goto LBL_Y; - } - mp_exch (&x, d); - } - - res = MP_OKAY; - -LBL_Y:mp_clear (&y); -LBL_X:mp_clear (&x); -LBL_T2:mp_clear (&t2); -LBL_T1:mp_clear (&t1); -LBL_Q:mp_clear (&q); - return res; -} - -#endif - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_div.c */ - -/* Start: bn_mp_div_2.c */ -#include <tommath_private.h> -#ifdef BN_MP_DIV_2_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* b = a/2 */ -int mp_div_2(mp_int * a, mp_int * b) -{ - int x, res, oldused; - - /* copy */ - if (b->alloc < a->used) { - if ((res = mp_grow (b, a->used)) != MP_OKAY) { - return res; - } - } - - oldused = b->used; - b->used = a->used; - { - mp_digit r, rr, *tmpa, *tmpb; - - /* source alias */ - tmpa = a->dp + b->used - 1; - - /* dest alias */ - tmpb = b->dp + b->used - 1; - - /* carry */ - r = 0; - for (x = b->used - 1; x >= 0; x--) { - /* get the carry for the next iteration */ - rr = *tmpa & 1; - - /* shift the current digit, add in carry and store */ - *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); - - /* forward carry to next iteration */ - r = rr; - } - - /* zero excess digits */ - tmpb = b->dp + b->used; - for (x = b->used; x < oldused; x++) { - *tmpb++ = 0; - } - } - b->sign = a->sign; - mp_clamp (b); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_div_2.c */ - -/* Start: bn_mp_div_2d.c */ -#include <tommath_private.h> -#ifdef BN_MP_DIV_2D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* shift right by a certain bit count (store quotient in c, optional remainder in d) */ -int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) -{ - mp_digit D, r, rr; - int x, res; - - /* if the shift count is <= 0 then we do no work */ - if (b <= 0) { - res = mp_copy (a, c); - if (d != NULL) { - mp_zero (d); - } - return res; - } - - /* copy */ - if ((res = mp_copy (a, c)) != MP_OKAY) { - return res; - } - /* 'a' should not be used after here - it might be the same as d */ - - /* get the remainder */ - if (d != NULL) { - if ((res = mp_mod_2d (a, b, d)) != MP_OKAY) { - return res; - } - } - - /* shift by as many digits in the bit count */ - if (b >= (int)DIGIT_BIT) { - mp_rshd (c, b / DIGIT_BIT); - } - - /* shift any bit count < DIGIT_BIT */ - D = (mp_digit) (b % DIGIT_BIT); - if (D != 0) { - mp_digit *tmpc, mask, shift; - - /* mask */ - mask = (((mp_digit)1) << D) - 1; - - /* shift for lsb */ - shift = DIGIT_BIT - D; - - /* alias */ - tmpc = c->dp + (c->used - 1); - - /* carry */ - r = 0; - for (x = c->used - 1; x >= 0; x--) { - /* get the lower bits of this word in a temp */ - rr = *tmpc & mask; - - /* shift the current word and mix in the carry bits from the previous word */ - *tmpc = (*tmpc >> D) | (r << shift); - --tmpc; - - /* set the carry to the carry bits of the current word found above */ - r = rr; - } - } - mp_clamp (c); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_div_2d.c */ - -/* Start: bn_mp_div_3.c */ -#include <tommath_private.h> -#ifdef BN_MP_DIV_3_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* divide by three (based on routine from MPI and the GMP manual) */ -int -mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) -{ - mp_int q; - mp_word w, t; - mp_digit b; - int res, ix; - - /* b = 2**DIGIT_BIT / 3 */ - b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3); - - if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { - return res; - } - - q.used = a->used; - q.sign = a->sign; - w = 0; - for (ix = a->used - 1; ix >= 0; ix--) { - w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); - - if (w >= 3) { - /* multiply w by [1/3] */ - t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT); - - /* now subtract 3 * [w/3] from w, to get the remainder */ - w -= t+t+t; - - /* fixup the remainder as required since - * the optimization is not exact. - */ - while (w >= 3) { - t += 1; - w -= 3; - } - } else { - t = 0; - } - q.dp[ix] = (mp_digit)t; - } - - /* [optional] store the remainder */ - if (d != NULL) { - *d = (mp_digit)w; - } - - /* [optional] store the quotient */ - if (c != NULL) { - mp_clamp(&q); - mp_exch(&q, c); - } - mp_clear(&q); - - return res; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_div_3.c */ - -/* Start: bn_mp_div_d.c */ -#include <tommath_private.h> -#ifdef BN_MP_DIV_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -static int s_is_power_of_two(mp_digit b, int *p) -{ - int x; - - /* fast return if no power of two */ - if ((b == 0) || ((b & (b-1)) != 0)) { - return 0; - } - - for (x = 0; x < DIGIT_BIT; x++) { - if (b == (((mp_digit)1)<<x)) { - *p = x; - return 1; - } - } - return 0; -} - -/* single digit division (based on routine from MPI) */ -int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d) -{ - mp_int q; - mp_word w; - mp_digit t; - int res, ix; - - /* cannot divide by zero */ - if (b == 0) { - return MP_VAL; - } - - /* quick outs */ - if ((b == 1) || (mp_iszero(a) == MP_YES)) { - if (d != NULL) { - *d = 0; - } - if (c != NULL) { - return mp_copy(a, c); - } - return MP_OKAY; - } - - /* power of two ? */ - if (s_is_power_of_two(b, &ix) == 1) { - if (d != NULL) { - *d = a->dp[0] & ((((mp_digit)1)<<ix) - 1); - } - if (c != NULL) { - return mp_div_2d(a, ix, c, NULL); - } - return MP_OKAY; - } - -#ifdef BN_MP_DIV_3_C - /* three? */ - if (b == 3) { - return mp_div_3(a, c, d); - } -#endif - - /* no easy answer [c'est la vie]. Just division */ - if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { - return res; - } - - q.used = a->used; - q.sign = a->sign; - w = 0; - for (ix = a->used - 1; ix >= 0; ix--) { - w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); - - if (w >= b) { - t = (mp_digit)(w / b); - w -= ((mp_word)t) * ((mp_word)b); - } else { - t = 0; - } - q.dp[ix] = (mp_digit)t; - } - - if (d != NULL) { - *d = (mp_digit)w; - } - - if (c != NULL) { - mp_clamp(&q); - mp_exch(&q, c); - } - mp_clear(&q); - - return res; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_div_d.c */ - -/* Start: bn_mp_dr_is_modulus.c */ -#include <tommath_private.h> -#ifdef BN_MP_DR_IS_MODULUS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* determines if a number is a valid DR modulus */ -int mp_dr_is_modulus(mp_int *a) -{ - int ix; - - /* must be at least two digits */ - if (a->used < 2) { - return 0; - } - - /* must be of the form b**k - a [a <= b] so all - * but the first digit must be equal to -1 (mod b). - */ - for (ix = 1; ix < a->used; ix++) { - if (a->dp[ix] != MP_MASK) { - return 0; - } - } - return 1; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_dr_is_modulus.c */ - -/* Start: bn_mp_dr_reduce.c */ -#include <tommath_private.h> -#ifdef BN_MP_DR_REDUCE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* reduce "x" in place modulo "n" using the Diminished Radix algorithm. - * - * Based on algorithm from the paper - * - * "Generating Efficient Primes for Discrete Log Cryptosystems" - * Chae Hoon Lim, Pil Joong Lee, - * POSTECH Information Research Laboratories - * - * The modulus must be of a special format [see manual] - * - * Has been modified to use algorithm 7.10 from the LTM book instead - * - * Input x must be in the range 0 <= x <= (n-1)**2 - */ -int -mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k) -{ - int err, i, m; - mp_word r; - mp_digit mu, *tmpx1, *tmpx2; - - /* m = digits in modulus */ - m = n->used; - - /* ensure that "x" has at least 2m digits */ - if (x->alloc < (m + m)) { - if ((err = mp_grow (x, m + m)) != MP_OKAY) { - return err; - } - } - -/* top of loop, this is where the code resumes if - * another reduction pass is required. - */ -top: - /* aliases for digits */ - /* alias for lower half of x */ - tmpx1 = x->dp; - - /* alias for upper half of x, or x/B**m */ - tmpx2 = x->dp + m; - - /* set carry to zero */ - mu = 0; - - /* compute (x mod B**m) + k * [x/B**m] inline and inplace */ - for (i = 0; i < m; i++) { - r = (((mp_word)*tmpx2++) * (mp_word)k) + *tmpx1 + mu; - *tmpx1++ = (mp_digit)(r & MP_MASK); - mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT)); - } - - /* set final carry */ - *tmpx1++ = mu; - - /* zero words above m */ - for (i = m + 1; i < x->used; i++) { - *tmpx1++ = 0; - } - - /* clamp, sub and return */ - mp_clamp (x); - - /* if x >= n then subtract and reduce again - * Each successive "recursion" makes the input smaller and smaller. - */ - if (mp_cmp_mag (x, n) != MP_LT) { - if ((err = s_mp_sub(x, n, x)) != MP_OKAY) { - return err; - } - goto top; - } - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_dr_reduce.c */ - -/* Start: bn_mp_dr_setup.c */ -#include <tommath_private.h> -#ifdef BN_MP_DR_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* determines the setup value */ -void mp_dr_setup(mp_int *a, mp_digit *d) -{ - /* the casts are required if DIGIT_BIT is one less than - * the number of bits in a mp_digit [e.g. DIGIT_BIT==31] - */ - *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - - ((mp_word)a->dp[0])); -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_dr_setup.c */ - -/* Start: bn_mp_exch.c */ -#include <tommath_private.h> -#ifdef BN_MP_EXCH_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* swap the elements of two integers, for cases where you can't simply swap the - * mp_int pointers around - */ -void -mp_exch (mp_int * a, mp_int * b) -{ - mp_int t; - - t = *a; - *a = *b; - *b = t; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_exch.c */ - -/* Start: bn_mp_export.c */ -#include <tommath_private.h> -#ifdef BN_MP_EXPORT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* based on gmp's mpz_export. - * see http://gmplib.org/manual/Integer-Import-and-Export.html - */ -int mp_export(void* rop, size_t* countp, int order, size_t size, - int endian, size_t nails, mp_int* op) { - int result; - size_t odd_nails, nail_bytes, i, j, bits, count; - unsigned char odd_nail_mask; - - mp_int t; - - if ((result = mp_init_copy(&t, op)) != MP_OKAY) { - return result; - } - - if (endian == 0) { - union { - unsigned int i; - char c[4]; - } lint; - lint.i = 0x01020304; - - endian = (lint.c[0] == 4) ? -1 : 1; - } - - odd_nails = (nails % 8); - odd_nail_mask = 0xff; - for (i = 0; i < odd_nails; ++i) { - odd_nail_mask ^= (1 << (7 - i)); - } - nail_bytes = nails / 8; - - bits = mp_count_bits(&t); - count = (bits / ((size * 8) - nails)) + (((bits % ((size * 8) - nails)) != 0) ? 1 : 0); - - for (i = 0; i < count; ++i) { - for (j = 0; j < size; ++j) { - unsigned char* byte = ( - (unsigned char*)rop + - (((order == -1) ? i : ((count - 1) - i)) * size) + - ((endian == -1) ? j : ((size - 1) - j)) - ); - - if (j >= (size - nail_bytes)) { - *byte = 0; - continue; - } - - *byte = (unsigned char)((j == ((size - nail_bytes) - 1)) ? (t.dp[0] & odd_nail_mask) : (t.dp[0] & 0xFF)); - - if ((result = mp_div_2d(&t, ((j == ((size - nail_bytes) - 1)) ? (8 - odd_nails) : 8), &t, NULL)) != MP_OKAY) { - mp_clear(&t); - return result; - } - } - } - - mp_clear(&t); - - if (countp != NULL) { - *countp = count; - } - - return MP_OKAY; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_export.c */ - -/* Start: bn_mp_expt_d.c */ -#include <tommath_private.h> -#ifdef BN_MP_EXPT_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* wrapper function for mp_expt_d_ex() */ -int mp_expt_d (mp_int * a, mp_digit b, mp_int * c) -{ - return mp_expt_d_ex(a, b, c, 0); -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_expt_d.c */ - -/* Start: bn_mp_expt_d_ex.c */ -#include <tommath_private.h> -#ifdef BN_MP_EXPT_D_EX_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* calculate c = a**b using a square-multiply algorithm */ -int mp_expt_d_ex (mp_int * a, mp_digit b, mp_int * c, int fast) -{ - int res; - unsigned int x; - - mp_int g; - - if ((res = mp_init_copy (&g, a)) != MP_OKAY) { - return res; - } - - /* set initial result */ - mp_set (c, 1); - - if (fast != 0) { - while (b > 0) { - /* if the bit is set multiply */ - if ((b & 1) != 0) { - if ((res = mp_mul (c, &g, c)) != MP_OKAY) { - mp_clear (&g); - return res; - } - } - - /* square */ - if (b > 1) { - if ((res = mp_sqr (&g, &g)) != MP_OKAY) { - mp_clear (&g); - return res; - } - } - - /* shift to next bit */ - b >>= 1; - } - } - else { - for (x = 0; x < DIGIT_BIT; x++) { - /* square */ - if ((res = mp_sqr (c, c)) != MP_OKAY) { - mp_clear (&g); - return res; - } - - /* if the bit is set multiply */ - if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) { - if ((res = mp_mul (c, &g, c)) != MP_OKAY) { - mp_clear (&g); - return res; - } - } - - /* shift to next bit */ - b <<= 1; - } - } /* if ... else */ - - mp_clear (&g); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_expt_d_ex.c */ - -/* Start: bn_mp_exptmod.c */ -#include <tommath_private.h> -#ifdef BN_MP_EXPTMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - - -/* this is a shell function that calls either the normal or Montgomery - * exptmod functions. Originally the call to the montgomery code was - * embedded in the normal function but that wasted alot of stack space - * for nothing (since 99% of the time the Montgomery code would be called) - */ -int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) -{ - int dr; - - /* modulus P must be positive */ - if (P->sign == MP_NEG) { - return MP_VAL; - } - - /* if exponent X is negative we have to recurse */ - if (X->sign == MP_NEG) { -#ifdef BN_MP_INVMOD_C - mp_int tmpG, tmpX; - int err; - - /* first compute 1/G mod P */ - if ((err = mp_init(&tmpG)) != MP_OKAY) { - return err; - } - if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) { - mp_clear(&tmpG); - return err; - } - - /* now get |X| */ - if ((err = mp_init(&tmpX)) != MP_OKAY) { - mp_clear(&tmpG); - return err; - } - if ((err = mp_abs(X, &tmpX)) != MP_OKAY) { - mp_clear_multi(&tmpG, &tmpX, NULL); - return err; - } - - /* and now compute (1/G)**|X| instead of G**X [X < 0] */ - err = mp_exptmod(&tmpG, &tmpX, P, Y); - mp_clear_multi(&tmpG, &tmpX, NULL); - return err; -#else - /* no invmod */ - return MP_VAL; -#endif - } - -/* modified diminished radix reduction */ -#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_C) - if (mp_reduce_is_2k_l(P) == MP_YES) { - return s_mp_exptmod(G, X, P, Y, 1); - } -#endif - -#ifdef BN_MP_DR_IS_MODULUS_C - /* is it a DR modulus? */ - dr = mp_dr_is_modulus(P); -#else - /* default to no */ - dr = 0; -#endif - -#ifdef BN_MP_REDUCE_IS_2K_C - /* if not, is it a unrestricted DR modulus? */ - if (dr == 0) { - dr = mp_reduce_is_2k(P) << 1; - } -#endif - - /* if the modulus is odd or dr != 0 use the montgomery method */ -#ifdef BN_MP_EXPTMOD_FAST_C - if ((mp_isodd (P) == MP_YES) || (dr != 0)) { - return mp_exptmod_fast (G, X, P, Y, dr); - } else { -#endif -#ifdef BN_S_MP_EXPTMOD_C - /* otherwise use the generic Barrett reduction technique */ - return s_mp_exptmod (G, X, P, Y, 0); -#else - /* no exptmod for evens */ - return MP_VAL; -#endif -#ifdef BN_MP_EXPTMOD_FAST_C - } -#endif -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_exptmod.c */ - -/* Start: bn_mp_exptmod_fast.c */ -#include <tommath_private.h> -#ifdef BN_MP_EXPTMOD_FAST_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85 - * - * Uses a left-to-right k-ary sliding window to compute the modular exponentiation. - * The value of k changes based on the size of the exponent. - * - * Uses Montgomery or Diminished Radix reduction [whichever appropriate] - */ - -#ifdef MP_LOW_MEM - #define TAB_SIZE 32 -#else - #define TAB_SIZE 256 -#endif - -int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) -{ - mp_int M[TAB_SIZE], res; - mp_digit buf, mp; - int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; - - /* use a pointer to the reduction algorithm. This allows us to use - * one of many reduction algorithms without modding the guts of - * the code with if statements everywhere. - */ - int (*redux)(mp_int*,mp_int*,mp_digit); - - /* 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 = mp_init_size(&M[1], P->alloc)) != MP_OKAY) { - return err; - } - - /* now init the second half of the array */ - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - if ((err = mp_init_size(&M[x], P->alloc)) != MP_OKAY) { - for (y = 1<<(winsize-1); y < x; y++) { - mp_clear (&M[y]); - } - mp_clear(&M[1]); - return err; - } - } - - /* determine and setup reduction code */ - if (redmode == 0) { -#ifdef BN_MP_MONTGOMERY_SETUP_C - /* now setup montgomery */ - if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) { - goto LBL_M; - } -#else - err = MP_VAL; - goto LBL_M; -#endif - - /* automatically pick the comba one if available (saves quite a few calls/ifs) */ -#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C - if ((((P->used * 2) + 1) < MP_WARRAY) && - (P->used < (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) { - redux = fast_mp_montgomery_reduce; - } else -#endif - { -#ifdef BN_MP_MONTGOMERY_REDUCE_C - /* use slower baseline Montgomery method */ - redux = mp_montgomery_reduce; -#else - err = MP_VAL; - goto LBL_M; -#endif - } - } else if (redmode == 1) { -#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C) - /* setup DR reduction for moduli of the form B**k - b */ - mp_dr_setup(P, &mp); - redux = mp_dr_reduce; -#else - err = MP_VAL; - goto LBL_M; -#endif - } else { -#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C) - /* setup DR reduction for moduli of the form 2**k - b */ - if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) { - goto LBL_M; - } - redux = mp_reduce_2k; -#else - err = MP_VAL; - goto LBL_M; -#endif - } - - /* setup result */ - if ((err = mp_init_size (&res, P->alloc)) != MP_OKAY) { - goto LBL_M; - } - - /* create M table - * - - * - * The first half of the table is not computed though accept for M[0] and M[1] - */ - - if (redmode == 0) { -#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C - /* now we need R mod m */ - if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) { - goto LBL_RES; - } - - /* now set M[1] to G * R mod m */ - if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) { - goto LBL_RES; - } -#else - err = MP_VAL; - goto LBL_RES; -#endif - } else { - mp_set(&res, 1); - if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) { - goto LBL_RES; - } - } - - /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */ - if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_RES; - } - - for (x = 0; x < (winsize - 1); x++) { - if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* create upper table */ - for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { - if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&M[x], P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* 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 so break */ - if (digidx == -1) { - break; - } - /* read next digit and reset bitcnt */ - buf = X->dp[digidx--]; - bitcnt = (int)DIGIT_BIT; - } - - /* grab the next msb from the exponent */ - y = (mp_digit)(buf >> (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 = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_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 = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* then multiply */ - if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_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 = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - - /* get next bit of the window */ - bitbuf <<= 1; - if ((bitbuf & (1 << winsize)) != 0) { - /* then multiply */ - if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - } - } - - if (redmode == 0) { - /* fixup result if Montgomery reduction is used - * recall that any value in a Montgomery system is - * actually multiplied by R mod n. So we have - * to reduce one more time to cancel out the factor - * of R. - */ - if ((err = redux(&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* swap res with Y */ - mp_exch (&res, Y); - err = MP_OKAY; -LBL_RES:mp_clear (&res); -LBL_M: - mp_clear(&M[1]); - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - mp_clear (&M[x]); - } - return err; -} -#endif - - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_exptmod_fast.c */ - -/* Start: bn_mp_exteuclid.c */ -#include <tommath_private.h> -#ifdef BN_MP_EXTEUCLID_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* Extended euclidean algorithm of (a, b) produces - a*u1 + b*u2 = u3 - */ -int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3) -{ - mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp; - int err; - - if ((err = mp_init_multi(&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, 1); - if ((err = mp_copy(a, &u3)) != MP_OKAY) { goto LBL_ERR; } - - /* initialize, (v1,v2,v3) = (0,1,b) */ - mp_set(&v2, 1); - if ((err = mp_copy(b, &v3)) != MP_OKAY) { goto LBL_ERR; } - - /* loop while v3 != 0 */ - while (mp_iszero(&v3) == MP_NO) { - /* q = u3/v3 */ - if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto LBL_ERR; } - - /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */ - if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto LBL_ERR; } - - /* (u1,u2,u3) = (v1,v2,v3) */ - if ((err = mp_copy(&v1, &u1)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_copy(&v2, &u2)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_copy(&v3, &u3)) != MP_OKAY) { goto LBL_ERR; } - - /* (v1,v2,v3) = (t1,t2,t3) */ - if ((err = mp_copy(&t1, &v1)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_copy(&t2, &v2)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { goto LBL_ERR; } - } - - /* make sure U3 >= 0 */ - if (u3.sign == MP_NEG) { - if ((err = mp_neg(&u1, &u1)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_neg(&u2, &u2)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_neg(&u3, &u3)) != MP_OKAY) { goto LBL_ERR; } - } - - /* copy result out */ - if (U1 != NULL) { mp_exch(U1, &u1); } - if (U2 != NULL) { mp_exch(U2, &u2); } - if (U3 != NULL) { mp_exch(U3, &u3); } - - err = MP_OKAY; -LBL_ERR: - mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL); - return err; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_exteuclid.c */ - -/* Start: bn_mp_fread.c */ -#include <tommath_private.h> -#ifdef BN_MP_FREAD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -#ifndef LTM_NO_FILE -/* read a bigint from a file stream in ASCII */ -int mp_fread(mp_int *a, int radix, FILE *stream) -{ - int err, ch, neg, y; - - /* clear a */ - mp_zero(a); - - /* if first digit is - then set negative */ - ch = fgetc(stream); - if (ch == '-') { - neg = MP_NEG; - ch = fgetc(stream); - } else { - neg = MP_ZPOS; - } - - for (;;) { - /* find y in the radix map */ - for (y = 0; y < radix; y++) { - if (mp_s_rmap[y] == ch) { - break; - } - } - if (y == radix) { - break; - } - - /* shift up and add */ - if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) { - return err; - } - if ((err = mp_add_d(a, y, a)) != MP_OKAY) { - return err; - } - - ch = fgetc(stream); - } - if (mp_cmp_d(a, 0) != MP_EQ) { - a->sign = neg; - } - - return MP_OKAY; -} -#endif - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_fread.c */ - -/* Start: bn_mp_fwrite.c */ -#include <tommath_private.h> -#ifdef BN_MP_FWRITE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -#ifndef LTM_NO_FILE -int mp_fwrite(mp_int *a, int radix, FILE *stream) -{ - char *buf; - int err, len, x; - - if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) { - return err; - } - - buf = OPT_CAST(char) XMALLOC (len); - if (buf == NULL) { - return MP_MEM; - } - - if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) { - XFREE (buf); - return err; - } - - for (x = 0; x < len; x++) { - if (fputc(buf[x], stream) == EOF) { - XFREE (buf); - return MP_VAL; - } - } - - XFREE (buf); - return MP_OKAY; -} -#endif - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_fwrite.c */ - -/* Start: bn_mp_gcd.c */ -#include <tommath_private.h> -#ifdef BN_MP_GCD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* Greatest Common Divisor using the binary method */ -int mp_gcd (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int u, v; - int k, u_lsb, v_lsb, res; - - /* either zero than gcd is the largest */ - if (mp_iszero (a) == MP_YES) { - return mp_abs (b, c); - } - if (mp_iszero (b) == MP_YES) { - return mp_abs (a, c); - } - - /* get copies of a and b we can modify */ - if ((res = mp_init_copy (&u, a)) != MP_OKAY) { - return res; - } - - if ((res = mp_init_copy (&v, b)) != MP_OKAY) { - goto LBL_U; - } - - /* must be positive for the remainder of the algorithm */ - u.sign = v.sign = MP_ZPOS; - - /* B1. Find the common power of two for u and v */ - u_lsb = mp_cnt_lsb(&u); - v_lsb = mp_cnt_lsb(&v); - k = MIN(u_lsb, v_lsb); - - if (k > 0) { - /* divide the power of two out */ - if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) { - goto LBL_V; - } - - if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) { - goto LBL_V; - } - } - - /* divide any remaining factors of two out */ - if (u_lsb != k) { - if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) { - goto LBL_V; - } - } - - if (v_lsb != k) { - if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) { - goto LBL_V; - } - } - - while (mp_iszero(&v) == MP_NO) { - /* make sure v is the largest */ - if (mp_cmp_mag(&u, &v) == MP_GT) { - /* swap u and v to make sure v is >= u */ - mp_exch(&u, &v); - } - - /* subtract smallest from largest */ - if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) { - goto LBL_V; - } - - /* Divide out all factors of two */ - if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) { - goto LBL_V; - } - } - - /* multiply by 2**k which we divided out at the beginning */ - if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) { - goto LBL_V; - } - c->sign = MP_ZPOS; - res = MP_OKAY; -LBL_V:mp_clear (&u); -LBL_U:mp_clear (&v); - return res; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_gcd.c */ - -/* Start: bn_mp_get_int.c */ -#include <tommath_private.h> -#ifdef BN_MP_GET_INT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* get the lower 32-bits of an mp_int */ -unsigned long mp_get_int(mp_int * a) -{ - int i; - mp_min_u32 res; - - if (a->used == 0) { - return 0; - } - - /* get number of digits of the lsb we have to read */ - i = MIN(a->used,(int)(((sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; - - /* get most significant digit of result */ - res = DIGIT(a,i); - - while (--i >= 0) { - res = (res << DIGIT_BIT) | DIGIT(a,i); - } - - /* force result to 32-bits always so it is consistent on non 32-bit platforms */ - return res & 0xFFFFFFFFUL; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_get_int.c */ - -/* Start: bn_mp_get_long.c */ -#include <tommath_private.h> -#ifdef BN_MP_GET_LONG_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* get the lower unsigned long of an mp_int, platform dependent */ -unsigned long mp_get_long(mp_int * a) -{ - int i; - unsigned long res; - - if (a->used == 0) { - return 0; - } - - /* get number of digits of the lsb we have to read */ - i = MIN(a->used,(int)(((sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; - - /* get most significant digit of result */ - res = DIGIT(a,i); - -#if (ULONG_MAX != 0xffffffffuL) || (DIGIT_BIT < 32) - while (--i >= 0) { - res = (res << DIGIT_BIT) | DIGIT(a,i); - } -#endif - return res; -} -#endif - -/* End: bn_mp_get_long.c */ - -/* Start: bn_mp_get_long_long.c */ -#include <tommath_private.h> -#ifdef BN_MP_GET_LONG_LONG_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* get the lower unsigned long long of an mp_int, platform dependent */ -unsigned long long mp_get_long_long (mp_int * a) -{ - int i; - unsigned long long res; - - if (a->used == 0) { - return 0; - } - - /* get number of digits of the lsb we have to read */ - i = MIN(a->used,(int)(((sizeof(unsigned long long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; - - /* get most significant digit of result */ - res = DIGIT(a,i); - -#if DIGIT_BIT < 64 - while (--i >= 0) { - res = (res << DIGIT_BIT) | DIGIT(a,i); - } -#endif - return res; -} -#endif - -/* End: bn_mp_get_long_long.c */ - -/* Start: bn_mp_grow.c */ -#include <tommath_private.h> -#ifdef BN_MP_GROW_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* grow as required */ -int mp_grow (mp_int * a, int size) -{ - int i; - mp_digit *tmp; - - /* if the alloc size is smaller alloc more ram */ - if (a->alloc < size) { - /* ensure there are always at least MP_PREC digits extra on top */ - size += (MP_PREC * 2) - (size % MP_PREC); - - /* reallocate the array a->dp - * - * We store the return in a temporary variable - * in case the operation failed we don't want - * to overwrite the dp member of a. - */ - tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size); - if (tmp == NULL) { - /* reallocation failed but "a" is still valid [can be freed] */ - return MP_MEM; - } - - /* reallocation succeeded so set a->dp */ - a->dp = tmp; - - /* zero excess digits */ - i = a->alloc; - a->alloc = size; - for (; i < a->alloc; i++) { - a->dp[i] = 0; - } - } - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_grow.c */ - -/* Start: bn_mp_import.c */ -#include <tommath_private.h> -#ifdef BN_MP_IMPORT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* based on gmp's mpz_import. - * see http://gmplib.org/manual/Integer-Import-and-Export.html - */ -int mp_import(mp_int* rop, size_t count, int order, size_t size, - int endian, size_t nails, const void* op) { - int result; - size_t odd_nails, nail_bytes, i, j; - unsigned char odd_nail_mask; - - mp_zero(rop); - - if (endian == 0) { - union { - unsigned int i; - char c[4]; - } lint; - lint.i = 0x01020304; - - endian = (lint.c[0] == 4) ? -1 : 1; - } - - odd_nails = (nails % 8); - odd_nail_mask = 0xff; - for (i = 0; i < odd_nails; ++i) { - odd_nail_mask ^= (1 << (7 - i)); - } - nail_bytes = nails / 8; - - for (i = 0; i < count; ++i) { - for (j = 0; j < (size - nail_bytes); ++j) { - unsigned char byte = *( - (unsigned char*)op + - (((order == 1) ? i : ((count - 1) - i)) * size) + - ((endian == 1) ? (j + nail_bytes) : (((size - 1) - j) - nail_bytes)) - ); - - if ( - (result = mp_mul_2d(rop, ((j == 0) ? (8 - odd_nails) : 8), rop)) != MP_OKAY) { - return result; - } - - rop->dp[0] |= (j == 0) ? (byte & odd_nail_mask) : byte; - rop->used += 1; - } - } - - mp_clamp(rop); - - return MP_OKAY; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_import.c */ - -/* Start: bn_mp_init.c */ -#include <tommath_private.h> -#ifdef BN_MP_INIT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* init a new mp_int */ -int mp_init (mp_int * a) -{ - int i; - - /* allocate memory required and clear it */ - a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC); - if (a->dp == NULL) { - return MP_MEM; - } - - /* set the digits to zero */ - for (i = 0; i < MP_PREC; i++) { - a->dp[i] = 0; - } - - /* set the used to zero, allocated digits to the default precision - * and sign to positive */ - a->used = 0; - a->alloc = MP_PREC; - a->sign = MP_ZPOS; - - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_init.c */ - -/* Start: bn_mp_init_copy.c */ -#include <tommath_private.h> -#ifdef BN_MP_INIT_COPY_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* creates "a" then copies b into it */ -int mp_init_copy (mp_int * a, mp_int * b) -{ - int res; - - if ((res = mp_init_size (a, b->used)) != MP_OKAY) { - return res; - } - - if((res = mp_copy (b, a)) != MP_OKAY) { - mp_clear(a); - } - - return res; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_init_copy.c */ - -/* Start: bn_mp_init_multi.c */ -#include <tommath_private.h> -#ifdef BN_MP_INIT_MULTI_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ -#include <stdarg.h> - -int mp_init_multi(mp_int *mp, ...) -{ - mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ - int n = 0; /* Number of ok inits */ - mp_int* cur_arg = mp; - va_list args; - - va_start(args, mp); /* init args to next argument from caller */ - while (cur_arg != NULL) { - if (mp_init(cur_arg) != MP_OKAY) { - /* Oops - error! Back-track and mp_clear what we already - succeeded in init-ing, then return error. - */ - va_list clean_args; - - /* now start cleaning up */ - cur_arg = mp; - va_start(clean_args, mp); - while (n-- != 0) { - mp_clear(cur_arg); - cur_arg = va_arg(clean_args, mp_int*); - } - va_end(clean_args); - res = MP_MEM; - break; - } - n++; - cur_arg = va_arg(args, mp_int*); - } - va_end(args); - return res; /* Assumed ok, if error flagged above. */ -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_init_multi.c */ - -/* Start: bn_mp_init_set.c */ -#include <tommath_private.h> -#ifdef BN_MP_INIT_SET_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* initialize and set a digit */ -int mp_init_set (mp_int * a, mp_digit b) -{ - int err; - if ((err = mp_init(a)) != MP_OKAY) { - return err; - } - mp_set(a, b); - return err; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_init_set.c */ - -/* Start: bn_mp_init_set_int.c */ -#include <tommath_private.h> -#ifdef BN_MP_INIT_SET_INT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* initialize and set a digit */ -int mp_init_set_int (mp_int * a, unsigned long b) -{ - int err; - if ((err = mp_init(a)) != MP_OKAY) { - return err; - } - return mp_set_int(a, b); -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_init_set_int.c */ - -/* Start: bn_mp_init_size.c */ -#include <tommath_private.h> -#ifdef BN_MP_INIT_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* init an mp_init for a given size */ -int mp_init_size (mp_int * a, int size) -{ - int x; - - /* pad size so there are always extra digits */ - size += (MP_PREC * 2) - (size % MP_PREC); - - /* alloc mem */ - a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size); - if (a->dp == NULL) { - return MP_MEM; - } - - /* set the members */ - a->used = 0; - a->alloc = size; - a->sign = MP_ZPOS; - - /* zero the digits */ - for (x = 0; x < size; x++) { - a->dp[x] = 0; - } - - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_init_size.c */ - -/* Start: bn_mp_invmod.c */ -#include <tommath_private.h> -#ifdef BN_MP_INVMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* hac 14.61, pp608 */ -int mp_invmod (mp_int * a, mp_int * b, mp_int * c) -{ - /* b cannot be negative */ - if ((b->sign == MP_NEG) || (mp_iszero(b) == MP_YES)) { - return MP_VAL; - } - -#ifdef BN_FAST_MP_INVMOD_C - /* if the modulus is odd we can use a faster routine instead */ - if ((mp_isodd(b) == MP_YES) && (mp_cmp_d(b, 1) != MP_EQ)) { - return fast_mp_invmod (a, b, c); - } -#endif - -#ifdef BN_MP_INVMOD_SLOW_C - return mp_invmod_slow(a, b, c); -#else - return MP_VAL; -#endif -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_invmod.c */ - -/* Start: bn_mp_invmod_slow.c */ -#include <tommath_private.h> -#ifdef BN_MP_INVMOD_SLOW_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* hac 14.61, pp608 */ -int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int x, y, u, v, A, B, C, D; - int res; - - /* b cannot be negative */ - if ((b->sign == MP_NEG) || (mp_iszero(b) == MP_YES)) { - return MP_VAL; - } - - /* init temps */ - if ((res = mp_init_multi(&x, &y, &u, &v, - &A, &B, &C, &D, NULL)) != MP_OKAY) { - return res; - } - - /* x = a, y = b */ - if ((res = mp_mod(a, b, &x)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_copy (b, &y)) != MP_OKAY) { - goto LBL_ERR; - } - - /* 2. [modified] if x,y are both even then return an error! */ - if ((mp_iseven (&x) == MP_YES) && (mp_iseven (&y) == MP_YES)) { - res = MP_VAL; - goto LBL_ERR; - } - - /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ - if ((res = mp_copy (&x, &u)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_copy (&y, &v)) != MP_OKAY) { - goto LBL_ERR; - } - mp_set (&A, 1); - mp_set (&D, 1); - -top: - /* 4. while u is even do */ - while (mp_iseven (&u) == MP_YES) { - /* 4.1 u = u/2 */ - if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { - goto LBL_ERR; - } - /* 4.2 if A or B is odd then */ - if ((mp_isodd (&A) == MP_YES) || (mp_isodd (&B) == MP_YES)) { - /* A = (A+y)/2, B = (B-x)/2 */ - if ((res = mp_add (&A, &y, &A)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* A = A/2, B = B/2 */ - if ((res = mp_div_2 (&A, &A)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 5. while v is even do */ - while (mp_iseven (&v) == MP_YES) { - /* 5.1 v = v/2 */ - if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { - goto LBL_ERR; - } - /* 5.2 if C or D is odd then */ - if ((mp_isodd (&C) == MP_YES) || (mp_isodd (&D) == MP_YES)) { - /* C = (C+y)/2, D = (D-x)/2 */ - if ((res = mp_add (&C, &y, &C)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* C = C/2, D = D/2 */ - if ((res = mp_div_2 (&C, &C)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 6. if u >= v then */ - if (mp_cmp (&u, &v) != MP_LT) { - /* u = u - v, A = A - C, B = B - D */ - if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } else { - /* v - v - u, C = C - A, D = D - B */ - if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* if not zero goto step 4 */ - if (mp_iszero (&u) == MP_NO) - goto top; - - /* now a = C, b = D, gcd == g*v */ - - /* if v != 1 then there is no inverse */ - if (mp_cmp_d (&v, 1) != MP_EQ) { - res = MP_VAL; - goto LBL_ERR; - } - - /* if its too low */ - while (mp_cmp_d(&C, 0) == MP_LT) { - if ((res = mp_add(&C, b, &C)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* too big */ - while (mp_cmp_mag(&C, b) != MP_LT) { - if ((res = mp_sub(&C, b, &C)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* C is now the inverse */ - mp_exch (&C, c); - res = MP_OKAY; -LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL); - return res; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_invmod_slow.c */ - -/* Start: bn_mp_is_square.c */ -#include <tommath_private.h> -#ifdef BN_MP_IS_SQUARE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* Check if remainders are possible squares - fast exclude non-squares */ -static const char rem_128[128] = { - 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 -}; - -static const char rem_105[105] = { - 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 -}; - -/* Store non-zero to ret if arg is square, and zero if not */ -int mp_is_square(mp_int *arg,int *ret) -{ - int res; - mp_digit c; - mp_int t; - unsigned long r; - - /* Default to Non-square :) */ - *ret = MP_NO; - - if (arg->sign == MP_NEG) { - return MP_VAL; - } - - /* digits used? (TSD) */ - if (arg->used == 0) { - return MP_OKAY; - } - - /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */ - if (rem_128[127 & DIGIT(arg,0)] == 1) { - return MP_OKAY; - } - - /* Next check mod 105 (3*5*7) */ - if ((res = mp_mod_d(arg,105,&c)) != MP_OKAY) { - return res; - } - if (rem_105[c] == 1) { - return MP_OKAY; - } - - - if ((res = mp_init_set_int(&t,11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) { - return res; - } - if ((res = mp_mod(arg,&t,&t)) != MP_OKAY) { - goto ERR; - } - r = mp_get_int(&t); - /* Check for other prime modules, note it's not an ERROR but we must - * free "t" so the easiest way is to goto ERR. We know that res - * is already equal to MP_OKAY from the mp_mod call - */ - if (((1L<<(r%11)) & 0x5C4L) != 0L) goto ERR; - if (((1L<<(r%13)) & 0x9E4L) != 0L) goto ERR; - if (((1L<<(r%17)) & 0x5CE8L) != 0L) goto ERR; - if (((1L<<(r%19)) & 0x4F50CL) != 0L) goto ERR; - if (((1L<<(r%23)) & 0x7ACCA0L) != 0L) goto ERR; - if (((1L<<(r%29)) & 0xC2EDD0CL) != 0L) goto ERR; - if (((1L<<(r%31)) & 0x6DE2B848L) != 0L) goto ERR; - - /* Final check - is sqr(sqrt(arg)) == arg ? */ - if ((res = mp_sqrt(arg,&t)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sqr(&t,&t)) != MP_OKAY) { - goto ERR; - } - - *ret = (mp_cmp_mag(&t,arg) == MP_EQ) ? MP_YES : MP_NO; -ERR:mp_clear(&t); - return res; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_is_square.c */ - -/* Start: bn_mp_jacobi.c */ -#include <tommath_private.h> -#ifdef BN_MP_JACOBI_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* computes the jacobi c = (a | n) (or Legendre if n is prime) - * HAC pp. 73 Algorithm 2.149 - * HAC is wrong here, as the special case of (0 | 1) is not - * handled correctly. - */ -int mp_jacobi (mp_int * a, mp_int * n, int *c) -{ - mp_int a1, p1; - int k, s, r, res; - mp_digit residue; - - /* if a < 0 return MP_VAL */ - if (mp_isneg(a) == MP_YES) { - return MP_VAL; - } - - /* if n <= 0 return MP_VAL */ - if (mp_cmp_d(n, 0) != MP_GT) { - return MP_VAL; - } - - /* step 1. handle case of a == 0 */ - if (mp_iszero (a) == MP_YES) { - /* special case of a == 0 and n == 1 */ - if (mp_cmp_d (n, 1) == MP_EQ) { - *c = 1; - } else { - *c = 0; - } - return MP_OKAY; - } - - /* step 2. if a == 1, return 1 */ - if (mp_cmp_d (a, 1) == MP_EQ) { - *c = 1; - return MP_OKAY; - } - - /* default */ - s = 0; - - /* step 3. write a = a1 * 2**k */ - if ((res = mp_init_copy (&a1, a)) != MP_OKAY) { - return res; - } - - if ((res = mp_init (&p1)) != MP_OKAY) { - goto LBL_A1; - } - - /* divide out larger power of two */ - k = mp_cnt_lsb(&a1); - if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) { - goto LBL_P1; - } - - /* step 4. if e is even set s=1 */ - if ((k & 1) == 0) { - s = 1; - } else { - /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */ - residue = n->dp[0] & 7; - - if ((residue == 1) || (residue == 7)) { - s = 1; - } else if ((residue == 3) || (residue == 5)) { - s = -1; - } - } - - /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */ - if ( ((n->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) { - s = -s; - } - - /* if a1 == 1 we're done */ - if (mp_cmp_d (&a1, 1) == MP_EQ) { - *c = s; - } else { - /* n1 = n mod a1 */ - if ((res = mp_mod (n, &a1, &p1)) != MP_OKAY) { - goto LBL_P1; - } - if ((res = mp_jacobi (&p1, &a1, &r)) != MP_OKAY) { - goto LBL_P1; - } - *c = s * r; - } - - /* done */ - res = MP_OKAY; -LBL_P1:mp_clear (&p1); -LBL_A1:mp_clear (&a1); - return res; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_jacobi.c */ - -/* Start: bn_mp_karatsuba_mul.c */ -#include <tommath_private.h> -#ifdef BN_MP_KARATSUBA_MUL_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* c = |a| * |b| using Karatsuba Multiplication using - * three half size multiplications - * - * Let B represent the radix [e.g. 2**DIGIT_BIT] and - * let n represent half of the number of digits in - * the min(a,b) - * - * a = a1 * B**n + a0 - * b = b1 * B**n + b0 - * - * Then, a * b => - a1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0 - * - * Note that a1b1 and a0b0 are used twice and only need to be - * computed once. So in total three half size (half # of - * digit) multiplications are performed, a0b0, a1b1 and - * (a1+b1)(a0+b0) - * - * Note that a multiplication of half the digits requires - * 1/4th the number of single precision multiplications so in - * total after one call 25% of the single precision multiplications - * are saved. Note also that the call to mp_mul can end up back - * in this function if the a0, a1, b0, or b1 are above the threshold. - * This is known as divide-and-conquer and leads to the famous - * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than - * the standard O(N**2) that the baseline/comba methods use. - * Generally though the overhead of this method doesn't pay off - * until a certain size (N ~ 80) is reached. - */ -int mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int x0, x1, y0, y1, t1, x0y0, x1y1; - int B, err; - - /* default the return code to an error */ - err = MP_MEM; - - /* min # of digits */ - B = MIN (a->used, b->used); - - /* now divide in two */ - B = B >> 1; - - /* init copy all the temps */ - if (mp_init_size (&x0, B) != MP_OKAY) - goto ERR; - if (mp_init_size (&x1, a->used - B) != MP_OKAY) - goto X0; - if (mp_init_size (&y0, B) != MP_OKAY) - goto X1; - if (mp_init_size (&y1, b->used - B) != MP_OKAY) - goto Y0; - - /* init temps */ - if (mp_init_size (&t1, B * 2) != MP_OKAY) - goto Y1; - if (mp_init_size (&x0y0, B * 2) != MP_OKAY) - goto T1; - if (mp_init_size (&x1y1, B * 2) != MP_OKAY) - goto X0Y0; - - /* now shift the digits */ - x0.used = y0.used = B; - x1.used = a->used - B; - y1.used = b->used - B; - - { - int x; - mp_digit *tmpa, *tmpb, *tmpx, *tmpy; - - /* we copy the digits directly instead of using higher level functions - * since we also need to shift the digits - */ - tmpa = a->dp; - tmpb = b->dp; - - tmpx = x0.dp; - tmpy = y0.dp; - for (x = 0; x < B; x++) { - *tmpx++ = *tmpa++; - *tmpy++ = *tmpb++; - } - - tmpx = x1.dp; - for (x = B; x < a->used; x++) { - *tmpx++ = *tmpa++; - } - - tmpy = y1.dp; - for (x = B; x < b->used; x++) { - *tmpy++ = *tmpb++; - } - } - - /* only need to clamp the lower words since by definition the - * upper words x1/y1 must have a known number of digits - */ - mp_clamp (&x0); - mp_clamp (&y0); - - /* now calc the products x0y0 and x1y1 */ - /* after this x0 is no longer required, free temp [x0==t2]! */ - if (mp_mul (&x0, &y0, &x0y0) != MP_OKAY) - goto X1Y1; /* x0y0 = x0*y0 */ - if (mp_mul (&x1, &y1, &x1y1) != MP_OKAY) - goto X1Y1; /* x1y1 = x1*y1 */ - - /* now calc x1+x0 and y1+y0 */ - if (s_mp_add (&x1, &x0, &t1) != MP_OKAY) - goto X1Y1; /* t1 = x1 - x0 */ - if (s_mp_add (&y1, &y0, &x0) != MP_OKAY) - goto X1Y1; /* t2 = y1 - y0 */ - if (mp_mul (&t1, &x0, &t1) != MP_OKAY) - goto X1Y1; /* t1 = (x1 + x0) * (y1 + y0) */ - - /* add x0y0 */ - if (mp_add (&x0y0, &x1y1, &x0) != MP_OKAY) - goto X1Y1; /* t2 = x0y0 + x1y1 */ - if (s_mp_sub (&t1, &x0, &t1) != MP_OKAY) - goto X1Y1; /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */ - - /* shift by B */ - if (mp_lshd (&t1, B) != MP_OKAY) - goto X1Y1; /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))<<B */ - if (mp_lshd (&x1y1, B * 2) != MP_OKAY) - goto X1Y1; /* x1y1 = x1y1 << 2*B */ - - if (mp_add (&x0y0, &t1, &t1) != MP_OKAY) - goto X1Y1; /* t1 = x0y0 + t1 */ - if (mp_add (&t1, &x1y1, c) != MP_OKAY) - goto X1Y1; /* t1 = x0y0 + t1 + x1y1 */ - - /* Algorithm succeeded set the return code to MP_OKAY */ - err = MP_OKAY; - -X1Y1:mp_clear (&x1y1); -X0Y0:mp_clear (&x0y0); -T1:mp_clear (&t1); -Y1:mp_clear (&y1); -Y0:mp_clear (&y0); -X1:mp_clear (&x1); -X0:mp_clear (&x0); -ERR: - return err; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_karatsuba_mul.c */ - -/* Start: bn_mp_karatsuba_sqr.c */ -#include <tommath_private.h> -#ifdef BN_MP_KARATSUBA_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* Karatsuba squaring, computes b = a*a using three - * half size squarings - * - * See comments of karatsuba_mul for details. It - * is essentially the same algorithm but merely - * tuned to perform recursive squarings. - */ -int mp_karatsuba_sqr (mp_int * a, mp_int * b) -{ - mp_int x0, x1, t1, t2, x0x0, x1x1; - int B, err; - - err = MP_MEM; - - /* min # of digits */ - B = a->used; - - /* now divide in two */ - B = B >> 1; - - /* init copy all the temps */ - if (mp_init_size (&x0, B) != MP_OKAY) - goto ERR; - if (mp_init_size (&x1, a->used - B) != MP_OKAY) - goto X0; - - /* init temps */ - if (mp_init_size (&t1, a->used * 2) != MP_OKAY) - goto X1; - if (mp_init_size (&t2, a->used * 2) != MP_OKAY) - goto T1; - if (mp_init_size (&x0x0, B * 2) != MP_OKAY) - goto T2; - if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY) - goto X0X0; - - { - int x; - mp_digit *dst, *src; - - src = a->dp; - - /* now shift the digits */ - dst = x0.dp; - for (x = 0; x < B; x++) { - *dst++ = *src++; - } - - dst = x1.dp; - for (x = B; x < a->used; x++) { - *dst++ = *src++; - } - } - - x0.used = B; - x1.used = a->used - B; - - mp_clamp (&x0); - - /* now calc the products x0*x0 and x1*x1 */ - if (mp_sqr (&x0, &x0x0) != MP_OKAY) - goto X1X1; /* x0x0 = x0*x0 */ - if (mp_sqr (&x1, &x1x1) != MP_OKAY) - goto X1X1; /* x1x1 = x1*x1 */ - - /* now calc (x1+x0)**2 */ - if (s_mp_add (&x1, &x0, &t1) != MP_OKAY) - goto X1X1; /* t1 = x1 - x0 */ - if (mp_sqr (&t1, &t1) != MP_OKAY) - goto X1X1; /* t1 = (x1 - x0) * (x1 - x0) */ - - /* add x0y0 */ - if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY) - goto X1X1; /* t2 = x0x0 + x1x1 */ - if (s_mp_sub (&t1, &t2, &t1) != MP_OKAY) - goto X1X1; /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */ - - /* shift by B */ - if (mp_lshd (&t1, B) != MP_OKAY) - goto X1X1; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))<<B */ - if (mp_lshd (&x1x1, B * 2) != MP_OKAY) - goto X1X1; /* x1x1 = x1x1 << 2*B */ - - if (mp_add (&x0x0, &t1, &t1) != MP_OKAY) - goto X1X1; /* t1 = x0x0 + t1 */ - if (mp_add (&t1, &x1x1, b) != MP_OKAY) - goto X1X1; /* t1 = x0x0 + t1 + x1x1 */ - - err = MP_OKAY; - -X1X1:mp_clear (&x1x1); -X0X0:mp_clear (&x0x0); -T2:mp_clear (&t2); -T1:mp_clear (&t1); -X1:mp_clear (&x1); -X0:mp_clear (&x0); -ERR: - return err; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_karatsuba_sqr.c */ - -/* Start: bn_mp_lcm.c */ -#include <tommath_private.h> -#ifdef BN_MP_LCM_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* computes least common multiple as |a*b|/(a, b) */ -int mp_lcm (mp_int * a, mp_int * b, mp_int * c) -{ - int res; - mp_int t1, t2; - - - if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) { - return res; - } - - /* t1 = get the GCD of the two inputs */ - if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) { - goto LBL_T; - } - - /* divide the smallest by the GCD */ - if (mp_cmp_mag(a, b) == MP_LT) { - /* store quotient in t2 such that t2 * b is the LCM */ - if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) { - goto LBL_T; - } - res = mp_mul(b, &t2, c); - } else { - /* store quotient in t2 such that t2 * a is the LCM */ - if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) { - goto LBL_T; - } - res = mp_mul(a, &t2, c); - } - - /* fix the sign to positive */ - c->sign = MP_ZPOS; - -LBL_T: - mp_clear_multi (&t1, &t2, NULL); - return res; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_lcm.c */ - -/* Start: bn_mp_lshd.c */ -#include <tommath_private.h> -#ifdef BN_MP_LSHD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* shift left a certain amount of digits */ -int mp_lshd (mp_int * a, int b) -{ - int x, res; - - /* if its less than zero return */ - if (b <= 0) { - return MP_OKAY; - } - - /* grow to fit the new digits */ - if (a->alloc < (a->used + b)) { - if ((res = mp_grow (a, a->used + b)) != MP_OKAY) { - return res; - } - } - - { - mp_digit *top, *bottom; - - /* increment the used by the shift amount then copy upwards */ - a->used += b; - - /* top */ - top = a->dp + a->used - 1; - - /* base */ - bottom = (a->dp + a->used - 1) - b; - - /* much like mp_rshd this is implemented using a sliding window - * except the window goes the otherway around. Copying from - * the bottom to the top. see bn_mp_rshd.c for more info. - */ - for (x = a->used - 1; x >= b; x--) { - *top-- = *bottom--; - } - - /* zero the lower digits */ - top = a->dp; - for (x = 0; x < b; x++) { - *top++ = 0; - } - } - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_lshd.c */ - -/* Start: bn_mp_mod.c */ -#include <tommath_private.h> -#ifdef BN_MP_MOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* c = a mod b, 0 <= c < b if b > 0, b < c <= 0 if b < 0 */ -int -mp_mod (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int t; - int res; - - if ((res = mp_init_size (&t, b->used)) != MP_OKAY) { - return res; - } - - if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - - if ((mp_iszero(&t) != MP_NO) || (t.sign == b->sign)) { - res = MP_OKAY; - mp_exch (&t, c); - } else { - res = mp_add (b, &t, c); - } - - mp_clear (&t); - return res; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_mod.c */ - -/* Start: bn_mp_mod_2d.c */ -#include <tommath_private.h> -#ifdef BN_MP_MOD_2D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* calc a value mod 2**b */ -int -mp_mod_2d (mp_int * a, int b, mp_int * c) -{ - int x, res; - - /* if b is <= 0 then zero the int */ - if (b <= 0) { - mp_zero (c); - return MP_OKAY; - } - - /* if the modulus is larger than the value than return */ - if (b >= (int) (a->used * DIGIT_BIT)) { - res = mp_copy (a, c); - return res; - } - - /* copy */ - if ((res = mp_copy (a, c)) != MP_OKAY) { - return res; - } - - /* zero digits above the last digit of the modulus */ - for (x = (b / DIGIT_BIT) + (((b % DIGIT_BIT) == 0) ? 0 : 1); x < c->used; x++) { - c->dp[x] = 0; - } - /* clear the digit that is not completely outside/inside the modulus */ - c->dp[b / DIGIT_BIT] &= - (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1)); - mp_clamp (c); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_mod_2d.c */ - -/* Start: bn_mp_mod_d.c */ -#include <tommath_private.h> -#ifdef BN_MP_MOD_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -int -mp_mod_d (mp_int * a, mp_digit b, mp_digit * c) -{ - return mp_div_d(a, b, NULL, c); -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_mod_d.c */ - -/* Start: bn_mp_montgomery_calc_normalization.c */ -#include <tommath_private.h> -#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* - * shifts with subtractions when the result is greater than b. - * - * The method is slightly modified to shift B unconditionally upto just under - * the leading bit of b. This saves alot of multiple precision shifting. - */ -int mp_montgomery_calc_normalization (mp_int * a, mp_int * b) -{ - int x, bits, res; - - /* how many bits of last digit does b use */ - bits = mp_count_bits (b) % DIGIT_BIT; - - if (b->used > 1) { - if ((res = mp_2expt (a, ((b->used - 1) * DIGIT_BIT) + bits - 1)) != MP_OKAY) { - return res; - } - } else { - mp_set(a, 1); - bits = 1; - } - - - /* now compute C = A * B mod b */ - for (x = bits - 1; x < (int)DIGIT_BIT; x++) { - if ((res = mp_mul_2 (a, a)) != MP_OKAY) { - return res; - } - if (mp_cmp_mag (a, b) != MP_LT) { - if ((res = s_mp_sub (a, b, a)) != MP_OKAY) { - return res; - } - } - } - - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_montgomery_calc_normalization.c */ - -/* Start: bn_mp_montgomery_reduce.c */ -#include <tommath_private.h> -#ifdef BN_MP_MONTGOMERY_REDUCE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* computes xR**-1 == x (mod N) via Montgomery Reduction */ -int -mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) -{ - int ix, res, digs; - mp_digit mu; - - /* can the fast reduction [comba] method be used? - * - * Note that unlike in mul you're safely allowed *less* - * than the available columns [255 per default] since carries - * are fixed up in the inner loop. - */ - digs = (n->used * 2) + 1; - if ((digs < MP_WARRAY) && - (n->used < - (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) { - return fast_mp_montgomery_reduce (x, n, rho); - } - - /* grow the input as required */ - if (x->alloc < digs) { - if ((res = mp_grow (x, digs)) != MP_OKAY) { - return res; - } - } - x->used = digs; - - for (ix = 0; ix < n->used; ix++) { - /* mu = ai * rho mod b - * - * The value of rho must be precalculated via - * montgomery_setup() such that - * it equals -1/n0 mod b this allows the - * following inner loop to reduce the - * input one digit at a time - */ - mu = (mp_digit) (((mp_word)x->dp[ix] * (mp_word)rho) & MP_MASK); - - /* a = a + mu * m * b**i */ - { - int iy; - mp_digit *tmpn, *tmpx, u; - mp_word r; - - /* alias for digits of the modulus */ - tmpn = n->dp; - - /* alias for the digits of x [the input] */ - tmpx = x->dp + ix; - - /* set the carry to zero */ - u = 0; - - /* Multiply and add in place */ - for (iy = 0; iy < n->used; iy++) { - /* compute product and sum */ - r = ((mp_word)mu * (mp_word)*tmpn++) + - (mp_word) u + (mp_word) *tmpx; - - /* get carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - - /* fix digit */ - *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK)); - } - /* At this point the ix'th digit of x should be zero */ - - - /* propagate carries upwards as required*/ - while (u != 0) { - *tmpx += u; - u = *tmpx >> DIGIT_BIT; - *tmpx++ &= MP_MASK; - } - } - } - - /* at this point the n.used'th least - * significant digits of x are all zero - * which means we can shift x to the - * right by n.used digits and the - * residue is unchanged. - */ - - /* x = x/b**n.used */ - mp_clamp(x); - mp_rshd (x, n->used); - - /* if x >= n then x = x - n */ - if (mp_cmp_mag (x, n) != MP_LT) { - return s_mp_sub (x, n, x); - } - - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_montgomery_reduce.c */ - -/* Start: bn_mp_montgomery_setup.c */ -#include <tommath_private.h> -#ifdef BN_MP_MONTGOMERY_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* setups the montgomery reduction stuff */ -int -mp_montgomery_setup (mp_int * n, mp_digit * rho) -{ - mp_digit x, b; - -/* fast inversion mod 2**k - * - * Based on the fact that - * - * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n) - * => 2*X*A - X*X*A*A = 1 - * => 2*(1) - (1) = 1 - */ - b = n->dp[0]; - - if ((b & 1) == 0) { - return MP_VAL; - } - - x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ - x *= 2 - (b * x); /* here x*a==1 mod 2**8 */ -#if !defined(MP_8BIT) - x *= 2 - (b * x); /* here x*a==1 mod 2**16 */ -#endif -#if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT)) - x *= 2 - (b * x); /* here x*a==1 mod 2**32 */ -#endif -#ifdef MP_64BIT - x *= 2 - (b * x); /* here x*a==1 mod 2**64 */ -#endif - - /* rho = -1/m mod b */ - *rho = (mp_digit)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK; - - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_montgomery_setup.c */ - -/* Start: bn_mp_mul.c */ -#include <tommath_private.h> -#ifdef BN_MP_MUL_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* high level multiplication (handles sign) */ -int mp_mul (mp_int * a, mp_int * b, mp_int * c) -{ - int res, neg; - neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; - - /* use Toom-Cook? */ -#ifdef BN_MP_TOOM_MUL_C - if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) { - res = mp_toom_mul(a, b, c); - } else -#endif -#ifdef BN_MP_KARATSUBA_MUL_C - /* use Karatsuba? */ - if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) { - res = mp_karatsuba_mul (a, b, c); - } else -#endif - { - /* can we use the fast multiplier? - * - * The fast multiplier can be used if the output will - * have less than MP_WARRAY digits and the number of - * digits won't affect carry propagation - */ - int digs = a->used + b->used + 1; - -#ifdef BN_FAST_S_MP_MUL_DIGS_C - if ((digs < MP_WARRAY) && - (MIN(a->used, b->used) <= - (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) { - res = fast_s_mp_mul_digs (a, b, c, digs); - } else -#endif - { -#ifdef BN_S_MP_MUL_DIGS_C - res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */ -#else - res = MP_VAL; -#endif - } - } - c->sign = (c->used > 0) ? neg : MP_ZPOS; - return res; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_mul.c */ - -/* Start: bn_mp_mul_2.c */ -#include <tommath_private.h> -#ifdef BN_MP_MUL_2_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* b = a*2 */ -int mp_mul_2(mp_int * a, mp_int * b) -{ - int x, res, oldused; - - /* grow to accomodate result */ - if (b->alloc < (a->used + 1)) { - if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) { - return res; - } - } - - oldused = b->used; - b->used = a->used; - - { - mp_digit r, rr, *tmpa, *tmpb; - - /* alias for source */ - tmpa = a->dp; - - /* alias for dest */ - tmpb = b->dp; - - /* carry */ - r = 0; - for (x = 0; x < a->used; x++) { - - /* get what will be the *next* carry bit from the - * MSB of the current digit - */ - rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1)); - - /* now shift up this digit, add in the carry [from the previous] */ - *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK; - - /* copy the carry that would be from the source - * digit into the next iteration - */ - r = rr; - } - - /* new leading digit? */ - if (r != 0) { - /* add a MSB which is always 1 at this point */ - *tmpb = 1; - ++(b->used); - } - - /* now zero any excess digits on the destination - * that we didn't write to - */ - tmpb = b->dp + b->used; - for (x = b->used; x < oldused; x++) { - *tmpb++ = 0; - } - } - b->sign = a->sign; - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_mul_2.c */ - -/* Start: bn_mp_mul_2d.c */ -#include <tommath_private.h> -#ifdef BN_MP_MUL_2D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* shift left by a certain bit count */ -int mp_mul_2d (mp_int * a, int b, mp_int * c) -{ - mp_digit d; - int res; - - /* copy */ - if (a != c) { - if ((res = mp_copy (a, c)) != MP_OKAY) { - return res; - } - } - - if (c->alloc < (int)(c->used + (b / DIGIT_BIT) + 1)) { - if ((res = mp_grow (c, c->used + (b / DIGIT_BIT) + 1)) != MP_OKAY) { - return res; - } - } - - /* shift by as many digits in the bit count */ - if (b >= (int)DIGIT_BIT) { - if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) { - return res; - } - } - - /* shift any bit count < DIGIT_BIT */ - d = (mp_digit) (b % DIGIT_BIT); - if (d != 0) { - mp_digit *tmpc, shift, mask, r, rr; - int x; - - /* bitmask for carries */ - mask = (((mp_digit)1) << d) - 1; - - /* shift for msbs */ - shift = DIGIT_BIT - d; - - /* alias */ - tmpc = c->dp; - - /* carry */ - r = 0; - for (x = 0; x < c->used; x++) { - /* get the higher bits of the current word */ - rr = (*tmpc >> shift) & mask; - - /* shift the current word and OR in the carry */ - *tmpc = ((*tmpc << d) | r) & MP_MASK; - ++tmpc; - - /* set the carry to the carry bits of the current word */ - r = rr; - } - - /* set final carry */ - if (r != 0) { - c->dp[(c->used)++] = r; - } - } - mp_clamp (c); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_mul_2d.c */ - -/* Start: bn_mp_mul_d.c */ -#include <tommath_private.h> -#ifdef BN_MP_MUL_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* multiply by a digit */ -int -mp_mul_d (mp_int * a, mp_digit b, mp_int * c) -{ - mp_digit u, *tmpa, *tmpc; - mp_word r; - int ix, res, olduse; - - /* make sure c is big enough to hold a*b */ - if (c->alloc < (a->used + 1)) { - if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) { - return res; - } - } - - /* get the original destinations used count */ - olduse = c->used; - - /* set the sign */ - c->sign = a->sign; - - /* alias for a->dp [source] */ - tmpa = a->dp; - - /* alias for c->dp [dest] */ - tmpc = c->dp; - - /* zero carry */ - u = 0; - - /* compute columns */ - for (ix = 0; ix < a->used; ix++) { - /* compute product and carry sum for this term */ - r = (mp_word)u + ((mp_word)*tmpa++ * (mp_word)b); - - /* mask off higher bits to get a single digit */ - *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* send carry into next iteration */ - u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); - } - - /* store final carry [if any] and increment ix offset */ - *tmpc++ = u; - ++ix; - - /* now zero digits above the top */ - while (ix++ < olduse) { - *tmpc++ = 0; - } - - /* set used count */ - c->used = a->used + 1; - mp_clamp(c); - - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_mul_d.c */ - -/* Start: bn_mp_mulmod.c */ -#include <tommath_private.h> -#ifdef BN_MP_MULMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* d = a * b (mod c) */ -int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) -{ - int res; - mp_int t; - - if ((res = mp_init_size (&t, c->used)) != MP_OKAY) { - return res; - } - - if ((res = mp_mul (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, c, d); - mp_clear (&t); - return res; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_mulmod.c */ - -/* Start: bn_mp_n_root.c */ -#include <tommath_private.h> -#ifdef BN_MP_N_ROOT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* wrapper function for mp_n_root_ex() - * computes c = (a)**(1/b) such that (c)**b <= a and (c+1)**b > a - */ -int mp_n_root (mp_int * a, mp_digit b, mp_int * c) -{ - return mp_n_root_ex(a, b, c, 0); -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_n_root.c */ - -/* Start: bn_mp_n_root_ex.c */ -#include <tommath_private.h> -#ifdef BN_MP_N_ROOT_EX_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* find the n'th root of an integer - * - * Result found such that (c)**b <= a and (c+1)**b > a - * - * This algorithm uses Newton's approximation - * x[i+1] = x[i] - f(x[i])/f'(x[i]) - * which will find the root in log(N) time where - * each step involves a fair bit. This is not meant to - * find huge roots [square and cube, etc]. - */ -int mp_n_root_ex (mp_int * a, mp_digit b, mp_int * c, int fast) -{ - mp_int t1, t2, t3; - int res, neg; - - /* input must be positive if b is even */ - if (((b & 1) == 0) && (a->sign == MP_NEG)) { - return MP_VAL; - } - - if ((res = mp_init (&t1)) != MP_OKAY) { - return res; - } - - if ((res = mp_init (&t2)) != MP_OKAY) { - goto LBL_T1; - } - - if ((res = mp_init (&t3)) != MP_OKAY) { - goto LBL_T2; - } - - /* if a is negative fudge the sign but keep track */ - neg = a->sign; - a->sign = MP_ZPOS; - - /* t2 = 2 */ - mp_set (&t2, 2); - - do { - /* t1 = t2 */ - if ((res = mp_copy (&t2, &t1)) != MP_OKAY) { - goto LBL_T3; - } - - /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */ - - /* t3 = t1**(b-1) */ - if ((res = mp_expt_d_ex (&t1, b - 1, &t3, fast)) != MP_OKAY) { - goto LBL_T3; - } - - /* numerator */ - /* t2 = t1**b */ - if ((res = mp_mul (&t3, &t1, &t2)) != MP_OKAY) { - goto LBL_T3; - } - - /* t2 = t1**b - a */ - if ((res = mp_sub (&t2, a, &t2)) != MP_OKAY) { - goto LBL_T3; - } - - /* denominator */ - /* t3 = t1**(b-1) * b */ - if ((res = mp_mul_d (&t3, b, &t3)) != MP_OKAY) { - goto LBL_T3; - } - - /* t3 = (t1**b - a)/(b * t1**(b-1)) */ - if ((res = mp_div (&t2, &t3, &t3, NULL)) != MP_OKAY) { - goto LBL_T3; - } - - if ((res = mp_sub (&t1, &t3, &t2)) != MP_OKAY) { - goto LBL_T3; - } - } while (mp_cmp (&t1, &t2) != MP_EQ); - - /* result can be off by a few so check */ - for (;;) { - if ((res = mp_expt_d_ex (&t1, b, &t2, fast)) != MP_OKAY) { - goto LBL_T3; - } - - if (mp_cmp (&t2, a) == MP_GT) { - if ((res = mp_sub_d (&t1, 1, &t1)) != MP_OKAY) { - goto LBL_T3; - } - } else { - break; - } - } - - /* reset the sign of a first */ - a->sign = neg; - - /* set the result */ - mp_exch (&t1, c); - - /* set the sign of the result */ - c->sign = neg; - - res = MP_OKAY; - -LBL_T3:mp_clear (&t3); -LBL_T2:mp_clear (&t2); -LBL_T1:mp_clear (&t1); - return res; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_n_root_ex.c */ - -/* Start: bn_mp_neg.c */ -#include <tommath_private.h> -#ifdef BN_MP_NEG_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* b = -a */ -int mp_neg (mp_int * a, mp_int * b) -{ - int res; - if (a != b) { - if ((res = mp_copy (a, b)) != MP_OKAY) { - return res; - } - } - - if (mp_iszero(b) != MP_YES) { - b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS; - } else { - b->sign = MP_ZPOS; - } - - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_neg.c */ - -/* Start: bn_mp_or.c */ -#include <tommath_private.h> -#ifdef BN_MP_OR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* OR two ints together */ -int mp_or (mp_int * a, mp_int * b, mp_int * c) -{ - int res, ix, px; - mp_int t, *x; - - if (a->used > b->used) { - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - px = b->used; - x = b; - } else { - if ((res = mp_init_copy (&t, b)) != MP_OKAY) { - return res; - } - px = a->used; - x = a; - } - - for (ix = 0; ix < px; ix++) { - t.dp[ix] |= x->dp[ix]; - } - mp_clamp (&t); - mp_exch (c, &t); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_or.c */ - -/* Start: bn_mp_prime_fermat.c */ -#include <tommath_private.h> -#ifdef BN_MP_PRIME_FERMAT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* performs one Fermat test. - * - * If "a" were prime then b**a == b (mod a) since the order of - * the multiplicative sub-group would be phi(a) = a-1. That means - * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a). - * - * Sets result to 1 if the congruence holds, or zero otherwise. - */ -int mp_prime_fermat (mp_int * a, mp_int * b, int *result) -{ - mp_int t; - int err; - - /* default to composite */ - *result = MP_NO; - - /* ensure b > 1 */ - if (mp_cmp_d(b, 1) != MP_GT) { - return MP_VAL; - } - - /* init t */ - if ((err = mp_init (&t)) != MP_OKAY) { - return err; - } - - /* compute t = b**a mod a */ - if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) { - goto LBL_T; - } - - /* is it equal to b? */ - if (mp_cmp (&t, b) == MP_EQ) { - *result = MP_YES; - } - - err = MP_OKAY; -LBL_T:mp_clear (&t); - return err; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_prime_fermat.c */ - -/* Start: bn_mp_prime_is_divisible.c */ -#include <tommath_private.h> -#ifdef BN_MP_PRIME_IS_DIVISIBLE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* determines if an integers is divisible by one - * of the first PRIME_SIZE primes or not - * - * sets result to 0 if not, 1 if yes - */ -int mp_prime_is_divisible (mp_int * a, int *result) -{ - int err, ix; - mp_digit res; - - /* default to not */ - *result = MP_NO; - - for (ix = 0; ix < PRIME_SIZE; ix++) { - /* what is a mod LBL_prime_tab[ix] */ - if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) { - return err; - } - - /* is the residue zero? */ - if (res == 0) { - *result = MP_YES; - return MP_OKAY; - } - } - - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_prime_is_divisible.c */ - -/* Start: bn_mp_prime_is_prime.c */ -#include <tommath_private.h> -#ifdef BN_MP_PRIME_IS_PRIME_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* performs a variable number of rounds of Miller-Rabin - * - * Probability of error after t rounds is no more than - - * - * Sets result to 1 if probably prime, 0 otherwise - */ -int mp_prime_is_prime (mp_int * a, int t, int *result) -{ - mp_int b; - int ix, err, res; - - /* default to no */ - *result = MP_NO; - - /* valid value of t? */ - if ((t <= 0) || (t > PRIME_SIZE)) { - return MP_VAL; - } - - /* is the input equal to one of the primes in the table? */ - for (ix = 0; ix < PRIME_SIZE; ix++) { - if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) { - *result = 1; - return MP_OKAY; - } - } - - /* first perform trial division */ - if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) { - return err; - } - - /* return if it was trivially divisible */ - if (res == MP_YES) { - return MP_OKAY; - } - - /* now perform the miller-rabin rounds */ - if ((err = mp_init (&b)) != MP_OKAY) { - return err; - } - - for (ix = 0; ix < t; ix++) { - /* set the prime */ - mp_set (&b, ltm_prime_tab[ix]); - - if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) { - goto LBL_B; - } - - if (res == MP_NO) { - goto LBL_B; - } - } - - /* passed the test */ - *result = MP_YES; -LBL_B:mp_clear (&b); - return err; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_prime_is_prime.c */ - -/* Start: bn_mp_prime_miller_rabin.c */ -#include <tommath_private.h> -#ifdef BN_MP_PRIME_MILLER_RABIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* Miller-Rabin test of "a" to the base of "b" as described in - * HAC pp. 139 Algorithm 4.24 - * - * Sets result to 0 if definitely composite or 1 if probably prime. - * Randomly the chance of error is no more than 1/4 and often - * very much lower. - */ -int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result) -{ - mp_int n1, y, r; - int s, j, err; - - /* default */ - *result = MP_NO; - - /* ensure b > 1 */ - if (mp_cmp_d(b, 1) != MP_GT) { - return MP_VAL; - } - - /* get n1 = a - 1 */ - if ((err = mp_init_copy (&n1, a)) != MP_OKAY) { - return err; - } - if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) { - goto LBL_N1; - } - - /* set 2**s * r = n1 */ - if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) { - goto LBL_N1; - } - - /* count the number of least significant bits - * which are zero - */ - s = mp_cnt_lsb(&r); - - /* now divide n - 1 by 2**s */ - if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) { - goto LBL_R; - } - - /* compute y = b**r mod a */ - if ((err = mp_init (&y)) != MP_OKAY) { - goto LBL_R; - } - if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) { - goto LBL_Y; - } - - /* if y != 1 and y != n1 do */ - if ((mp_cmp_d (&y, 1) != MP_EQ) && (mp_cmp (&y, &n1) != MP_EQ)) { - j = 1; - /* while j <= s-1 and y != n1 */ - while ((j <= (s - 1)) && (mp_cmp (&y, &n1) != MP_EQ)) { - if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) { - goto LBL_Y; - } - - /* if y == 1 then composite */ - if (mp_cmp_d (&y, 1) == MP_EQ) { - goto LBL_Y; - } - - ++j; - } - - /* if y != n1 then composite */ - if (mp_cmp (&y, &n1) != MP_EQ) { - goto LBL_Y; - } - } - - /* probably prime now */ - *result = MP_YES; -LBL_Y:mp_clear (&y); -LBL_R:mp_clear (&r); -LBL_N1:mp_clear (&n1); - return err; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_prime_miller_rabin.c */ - -/* Start: bn_mp_prime_next_prime.c */ -#include <tommath_private.h> -#ifdef BN_MP_PRIME_NEXT_PRIME_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* finds the next prime after the number "a" using "t" trials - * of Miller-Rabin. - * - * bbs_style = 1 means the prime must be congruent to 3 mod 4 - */ -int mp_prime_next_prime(mp_int *a, int t, int bbs_style) -{ - int err, res = MP_NO, x, y; - mp_digit res_tab[PRIME_SIZE], step, kstep; - mp_int b; - - /* ensure t is valid */ - if ((t <= 0) || (t > PRIME_SIZE)) { - return MP_VAL; - } - - /* force positive */ - a->sign = MP_ZPOS; - - /* simple algo if a is less than the largest prime in the table */ - if (mp_cmp_d(a, ltm_prime_tab[PRIME_SIZE-1]) == MP_LT) { - /* find which prime it is bigger than */ - for (x = PRIME_SIZE - 2; x >= 0; x--) { - if (mp_cmp_d(a, ltm_prime_tab[x]) != MP_LT) { - if (bbs_style == 1) { - /* ok we found a prime smaller or - * equal [so the next is larger] - * - * however, the prime must be - * congruent to 3 mod 4 - */ - if ((ltm_prime_tab[x + 1] & 3) != 3) { - /* scan upwards for a prime congruent to 3 mod 4 */ - for (y = x + 1; y < PRIME_SIZE; y++) { - if ((ltm_prime_tab[y] & 3) == 3) { - mp_set(a, ltm_prime_tab[y]); - return MP_OKAY; - } - } - } - } else { - mp_set(a, ltm_prime_tab[x + 1]); - return MP_OKAY; - } - } - } - /* at this point a maybe 1 */ - if (mp_cmp_d(a, 1) == MP_EQ) { - mp_set(a, 2); - return MP_OKAY; - } - /* fall through to the sieve */ - } - - /* generate a prime congruent to 3 mod 4 or 1/3 mod 4? */ - if (bbs_style == 1) { - kstep = 4; - } else { - kstep = 2; - } - - /* at this point we will use a combination of a sieve and Miller-Rabin */ - - if (bbs_style == 1) { - /* if a mod 4 != 3 subtract the correct value to make it so */ - if ((a->dp[0] & 3) != 3) { - if ((err = mp_sub_d(a, (a->dp[0] & 3) + 1, a)) != MP_OKAY) { return err; }; - } - } else { - if (mp_iseven(a) == MP_YES) { - /* force odd */ - if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { - return err; - } - } - } - - /* generate the restable */ - for (x = 1; x < PRIME_SIZE; x++) { - if ((err = mp_mod_d(a, ltm_prime_tab[x], res_tab + x)) != MP_OKAY) { - return err; - } - } - - /* init temp used for Miller-Rabin Testing */ - if ((err = mp_init(&b)) != MP_OKAY) { - return err; - } - - for (;;) { - /* skip to the next non-trivially divisible candidate */ - step = 0; - do { - /* y == 1 if any residue was zero [e.g. cannot be prime] */ - y = 0; - - /* increase step to next candidate */ - step += kstep; - - /* compute the new residue without using division */ - for (x = 1; x < PRIME_SIZE; x++) { - /* add the step to each residue */ - res_tab[x] += kstep; - - /* subtract the modulus [instead of using division] */ - if (res_tab[x] >= ltm_prime_tab[x]) { - res_tab[x] -= ltm_prime_tab[x]; - } - - /* set flag if zero */ - if (res_tab[x] == 0) { - y = 1; - } - } - } while ((y == 1) && (step < ((((mp_digit)1) << DIGIT_BIT) - kstep))); - - /* add the step */ - if ((err = mp_add_d(a, step, a)) != MP_OKAY) { - goto LBL_ERR; - } - - /* if didn't pass sieve and step == MAX then skip test */ - if ((y == 1) && (step >= ((((mp_digit)1) << DIGIT_BIT) - kstep))) { - continue; - } - - /* is this prime? */ - for (x = 0; x < t; x++) { - mp_set(&b, ltm_prime_tab[x]); - if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) { - goto LBL_ERR; - } - if (res == MP_NO) { - break; - } - } - - if (res == MP_YES) { - break; - } - } - - err = MP_OKAY; -LBL_ERR: - mp_clear(&b); - return err; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_prime_next_prime.c */ - -/* Start: bn_mp_prime_rabin_miller_trials.c */ -#include <tommath_private.h> -#ifdef BN_MP_PRIME_RABIN_MILLER_TRIALS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - - -static const struct { - int k, t; -} sizes[] = { -{ 128, 28 }, -{ 256, 16 }, -{ 384, 10 }, -{ 512, 7 }, -{ 640, 6 }, -{ 768, 5 }, -{ 896, 4 }, -{ 1024, 4 } -}; - -/* returns # of RM trials required for a given bit size */ -int mp_prime_rabin_miller_trials(int size) -{ - int x; - - for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) { - if (sizes[x].k == size) { - return sizes[x].t; - } else if (sizes[x].k > size) { - return (x == 0) ? sizes[0].t : sizes[x - 1].t; - } - } - return sizes[x-1].t + 1; -} - - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_prime_rabin_miller_trials.c */ - -/* Start: bn_mp_prime_random_ex.c */ -#include <tommath_private.h> -#ifdef BN_MP_PRIME_RANDOM_EX_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* makes a truly random prime of a given size (bits), - * - * Flags are as follows: - * - * LTM_PRIME_BBS - make prime congruent to 3 mod 4 - * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS) - * LTM_PRIME_2MSB_ON - make the 2nd highest bit one - * - * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can - * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself - * so it can be NULL - * - */ - -/* This is possibly the mother of all prime generation functions, muahahahahaha! */ -int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat) -{ - unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb; - int res, err, bsize, maskOR_msb_offset; - - /* sanity check the input */ - if ((size <= 1) || (t <= 0)) { - return MP_VAL; - } - - /* LTM_PRIME_SAFE implies LTM_PRIME_BBS */ - if ((flags & LTM_PRIME_SAFE) != 0) { - flags |= LTM_PRIME_BBS; - } - - /* calc the byte size */ - bsize = (size>>3) + ((size&7)?1:0); - - /* we need a buffer of bsize bytes */ - tmp = OPT_CAST(unsigned char) XMALLOC(bsize); - if (tmp == NULL) { - return MP_MEM; - } - - /* calc the maskAND value for the MSbyte*/ - maskAND = ((size&7) == 0) ? 0xFF : (0xFF >> (8 - (size & 7))); - - /* calc the maskOR_msb */ - maskOR_msb = 0; - maskOR_msb_offset = ((size & 7) == 1) ? 1 : 0; - if ((flags & LTM_PRIME_2MSB_ON) != 0) { - maskOR_msb |= 0x80 >> ((9 - size) & 7); - } - - /* get the maskOR_lsb */ - maskOR_lsb = 1; - if ((flags & LTM_PRIME_BBS) != 0) { - maskOR_lsb |= 3; - } - - do { - /* read the bytes */ - if (cb(tmp, bsize, dat) != bsize) { - err = MP_VAL; - goto error; - } - - /* work over the MSbyte */ - tmp[0] &= maskAND; - tmp[0] |= 1 << ((size - 1) & 7); - - /* mix in the maskORs */ - tmp[maskOR_msb_offset] |= maskOR_msb; - tmp[bsize-1] |= maskOR_lsb; - - /* read it in */ - if ((err = mp_read_unsigned_bin(a, tmp, bsize)) != MP_OKAY) { goto error; } - - /* is it prime? */ - if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; } - if (res == MP_NO) { - continue; - } - - if ((flags & LTM_PRIME_SAFE) != 0) { - /* see if (a-1)/2 is prime */ - if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { goto error; } - if ((err = mp_div_2(a, a)) != MP_OKAY) { goto error; } - - /* is it prime? */ - if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; } - } - } while (res == MP_NO); - - if ((flags & LTM_PRIME_SAFE) != 0) { - /* restore a to the original value */ - if ((err = mp_mul_2(a, a)) != MP_OKAY) { goto error; } - if ((err = mp_add_d(a, 1, a)) != MP_OKAY) { goto error; } - } - - err = MP_OKAY; -error: - XFREE(tmp); - return err; -} - - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_prime_random_ex.c */ - -/* Start: bn_mp_radix_size.c */ -#include <tommath_private.h> -#ifdef BN_MP_RADIX_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* returns size of ASCII reprensentation */ -int mp_radix_size (mp_int * a, int radix, int *size) -{ - int res, digs; - mp_int t; - mp_digit d; - - *size = 0; - - /* make sure the radix is in range */ - if ((radix < 2) || (radix > 64)) { - return MP_VAL; - } - - if (mp_iszero(a) == MP_YES) { - *size = 2; - return MP_OKAY; - } - - /* special case for binary */ - if (radix == 2) { - *size = mp_count_bits (a) + ((a->sign == MP_NEG) ? 1 : 0) + 1; - return MP_OKAY; - } - - /* digs is the digit count */ - digs = 0; - - /* if it's negative add one for the sign */ - if (a->sign == MP_NEG) { - ++digs; - } - - /* init a copy of the input */ - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - /* force temp to positive */ - t.sign = MP_ZPOS; - - /* fetch out all of the digits */ - while (mp_iszero (&t) == MP_NO) { - if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { - mp_clear (&t); - return res; - } - ++digs; - } - mp_clear (&t); - - /* return digs + 1, the 1 is for the NULL byte that would be required. */ - *size = digs + 1; - return MP_OKAY; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_radix_size.c */ - -/* Start: bn_mp_radix_smap.c */ -#include <tommath_private.h> -#ifdef BN_MP_RADIX_SMAP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* chars used in radix conversions */ -const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_radix_smap.c */ - -/* Start: bn_mp_rand.c */ -#include <tommath_private.h> -#ifdef BN_MP_RAND_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -#if MP_GEN_RANDOM_MAX == 0xffffffff - #define MP_GEN_RANDOM_SHIFT 32 -#elif MP_GEN_RANDOM_MAX == 32767 - /* SHRT_MAX */ - #define MP_GEN_RANDOM_SHIFT 15 -#elif MP_GEN_RANDOM_MAX == 2147483647 - /* INT_MAX */ - #define MP_GEN_RANDOM_SHIFT 31 -#elif !defined(MP_GEN_RANDOM_SHIFT) -#error Thou shalt define their own valid MP_GEN_RANDOM_SHIFT -#endif - -/* makes a pseudo-random int of a given size */ -static mp_digit s_gen_random(void) -{ - mp_digit d = 0, msk = 0; - do { - d <<= MP_GEN_RANDOM_SHIFT; - d |= ((mp_digit) MP_GEN_RANDOM()); - msk <<= MP_GEN_RANDOM_SHIFT; - msk |= (MP_MASK & MP_GEN_RANDOM_MAX); - } while ((MP_MASK & msk) != MP_MASK); - d &= MP_MASK; - return d; -} - -int -mp_rand (mp_int * a, int digits) -{ - int res; - mp_digit d; - - mp_zero (a); - if (digits <= 0) { - return MP_OKAY; - } - - /* first place a random non-zero digit */ - do { - d = s_gen_random(); - } while (d == 0); - - if ((res = mp_add_d (a, d, a)) != MP_OKAY) { - return res; - } - - while (--digits > 0) { - if ((res = mp_lshd (a, 1)) != MP_OKAY) { - return res; - } - - if ((res = mp_add_d (a, s_gen_random(), a)) != MP_OKAY) { - return res; - } - } - - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_rand.c */ - -/* Start: bn_mp_read_radix.c */ -#include <tommath_private.h> -#ifdef BN_MP_READ_RADIX_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* read a string [ASCII] in a given radix */ -int mp_read_radix (mp_int * a, const char *str, int radix) -{ - int y, res, neg; - char ch; - - /* zero the digit bignum */ - mp_zero(a); - - /* make sure the radix is ok */ - if ((radix < 2) || (radix > 64)) { - return MP_VAL; - } - - /* if the leading digit is a - * minus set the sign to negative. - */ - if (*str == '-') { - ++str; - neg = MP_NEG; - } else { - neg = MP_ZPOS; - } - - /* set the integer to the default of zero */ - mp_zero (a); - - /* process each digit of the string */ - while (*str != '\0') { - /* if the radix <= 36 the conversion is case insensitive - * this allows numbers like 1AB and 1ab to represent the same value - * [e.g. in hex] - */ - ch = (radix <= 36) ? (char)toupper((int)*str) : *str; - for (y = 0; y < 64; y++) { - if (ch == mp_s_rmap[y]) { - break; - } - } - - /* if the char was found in the map - * and is less than the given radix add it - * to the number, otherwise exit the loop. - */ - if (y < radix) { - if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) { - return res; - } - if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) { - return res; - } - } else { - break; - } - ++str; - } - - /* set the sign only if a != 0 */ - if (mp_iszero(a) != MP_YES) { - a->sign = neg; - } - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_read_radix.c */ - -/* Start: bn_mp_read_signed_bin.c */ -#include <tommath_private.h> -#ifdef BN_MP_READ_SIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* read signed bin, big endian, first byte is 0==positive or 1==negative */ -int mp_read_signed_bin (mp_int * a, const unsigned char *b, int c) -{ - int res; - - /* read magnitude */ - if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) { - return res; - } - - /* first byte is 0 for positive, non-zero for negative */ - if (b[0] == 0) { - a->sign = MP_ZPOS; - } else { - a->sign = MP_NEG; - } - - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_read_signed_bin.c */ - -/* Start: bn_mp_read_unsigned_bin.c */ -#include <tommath_private.h> -#ifdef BN_MP_READ_UNSIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* reads a unsigned char array, assumes the msb is stored first [big endian] */ -int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c) -{ - int res; - - /* make sure there are at least two digits */ - if (a->alloc < 2) { - if ((res = mp_grow(a, 2)) != MP_OKAY) { - return res; - } - } - - /* zero the int */ - mp_zero (a); - - /* read the bytes in */ - while (c-- > 0) { - if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) { - return res; - } - -#ifndef MP_8BIT - a->dp[0] |= *b++; - a->used += 1; -#else - a->dp[0] = (*b & MP_MASK); - a->dp[1] |= ((*b++ >> 7U) & 1); - a->used += 2; -#endif - } - mp_clamp (a); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_read_unsigned_bin.c */ - -/* Start: bn_mp_reduce.c */ -#include <tommath_private.h> -#ifdef BN_MP_REDUCE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* reduces x mod m, assumes 0 < x < m**2, mu is - * precomputed via mp_reduce_setup. - * From HAC pp.604 Algorithm 14.42 - */ -int mp_reduce (mp_int * x, mp_int * m, mp_int * mu) -{ - mp_int q; - int res, um = m->used; - - /* q = x */ - if ((res = mp_init_copy (&q, x)) != MP_OKAY) { - return res; - } - - /* q1 = x / b**(k-1) */ - mp_rshd (&q, um - 1); - - /* according to HAC this optimization is ok */ - if (((mp_digit) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) { - if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) { - goto CLEANUP; - } - } else { -#ifdef BN_S_MP_MUL_HIGH_DIGS_C - if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { - goto CLEANUP; - } -#elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) - if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { - goto CLEANUP; - } -#else - { - res = MP_VAL; - goto CLEANUP; - } -#endif - } - - /* q3 = q2 / b**(k+1) */ - mp_rshd (&q, um + 1); - - /* x = x mod b**(k+1), quick (no division) */ - if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) { - goto CLEANUP; - } - - /* q = q * m mod b**(k+1), quick (no division) */ - if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) { - goto CLEANUP; - } - - /* x = x - q */ - if ((res = mp_sub (x, &q, x)) != MP_OKAY) { - goto CLEANUP; - } - - /* If x < 0, add b**(k+1) to it */ - if (mp_cmp_d (x, 0) == MP_LT) { - mp_set (&q, 1); - if ((res = mp_lshd (&q, um + 1)) != MP_OKAY) - goto CLEANUP; - if ((res = mp_add (x, &q, x)) != MP_OKAY) - goto CLEANUP; - } - - /* Back off if it's too big */ - while (mp_cmp (x, m) != MP_LT) { - if ((res = s_mp_sub (x, m, x)) != MP_OKAY) { - goto CLEANUP; - } - } - -CLEANUP: - mp_clear (&q); - - return res; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_reduce.c */ - -/* Start: bn_mp_reduce_2k.c */ -#include <tommath_private.h> -#ifdef BN_MP_REDUCE_2K_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* reduces a modulo n where n is of the form 2**p - d */ -int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d) -{ - mp_int q; - int p, res; - - if ((res = mp_init(&q)) != MP_OKAY) { - return res; - } - - p = mp_count_bits(n); -top: - /* q = a/2**p, a = a mod 2**p */ - if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { - goto ERR; - } - - if (d != 1) { - /* q = q * d */ - if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) { - goto ERR; - } - } - - /* a = a + q */ - if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { - goto ERR; - } - - if (mp_cmp_mag(a, n) != MP_LT) { - if ((res = s_mp_sub(a, n, a)) != MP_OKAY) { - goto ERR; - } - goto top; - } - -ERR: - mp_clear(&q); - return res; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_reduce_2k.c */ - -/* Start: bn_mp_reduce_2k_l.c */ -#include <tommath_private.h> -#ifdef BN_MP_REDUCE_2K_L_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* reduces a modulo n where n is of the form 2**p - d - This differs from reduce_2k since "d" can be larger - than a single digit. -*/ -int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d) -{ - mp_int q; - int p, res; - - if ((res = mp_init(&q)) != MP_OKAY) { - return res; - } - - p = mp_count_bits(n); -top: - /* q = a/2**p, a = a mod 2**p */ - if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { - goto ERR; - } - - /* q = q * d */ - if ((res = mp_mul(&q, d, &q)) != MP_OKAY) { - goto ERR; - } - - /* a = a + q */ - if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { - goto ERR; - } - - if (mp_cmp_mag(a, n) != MP_LT) { - if ((res = s_mp_sub(a, n, a)) != MP_OKAY) { - goto ERR; - } - goto top; - } - -ERR: - mp_clear(&q); - return res; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_reduce_2k_l.c */ - -/* Start: bn_mp_reduce_2k_setup.c */ -#include <tommath_private.h> -#ifdef BN_MP_REDUCE_2K_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* determines the setup value */ -int mp_reduce_2k_setup(mp_int *a, mp_digit *d) -{ - int res, p; - mp_int tmp; - - if ((res = mp_init(&tmp)) != MP_OKAY) { - return res; - } - - p = mp_count_bits(a); - if ((res = mp_2expt(&tmp, p)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - - if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - - *d = tmp.dp[0]; - mp_clear(&tmp); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_reduce_2k_setup.c */ - -/* Start: bn_mp_reduce_2k_setup_l.c */ -#include <tommath_private.h> -#ifdef BN_MP_REDUCE_2K_SETUP_L_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* determines the setup value */ -int mp_reduce_2k_setup_l(mp_int *a, mp_int *d) -{ - int res; - mp_int tmp; - - if ((res = mp_init(&tmp)) != MP_OKAY) { - return res; - } - - if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) { - goto ERR; - } - - if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) { - goto ERR; - } - -ERR: - mp_clear(&tmp); - return res; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_reduce_2k_setup_l.c */ - -/* Start: bn_mp_reduce_is_2k.c */ -#include <tommath_private.h> -#ifdef BN_MP_REDUCE_IS_2K_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* determines if mp_reduce_2k can be used */ -int mp_reduce_is_2k(mp_int *a) -{ - int ix, iy, iw; - mp_digit iz; - - if (a->used == 0) { - return MP_NO; - } else if (a->used == 1) { - return MP_YES; - } else if (a->used > 1) { - iy = mp_count_bits(a); - iz = 1; - iw = 1; - - /* Test every bit from the second digit up, must be 1 */ - for (ix = DIGIT_BIT; ix < iy; ix++) { - if ((a->dp[iw] & iz) == 0) { - return MP_NO; - } - iz <<= 1; - if (iz > (mp_digit)MP_MASK) { - ++iw; - iz = 1; - } - } - } - return MP_YES; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_reduce_is_2k.c */ - -/* Start: bn_mp_reduce_is_2k_l.c */ -#include <tommath_private.h> -#ifdef BN_MP_REDUCE_IS_2K_L_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* determines if reduce_2k_l can be used */ -int mp_reduce_is_2k_l(mp_int *a) -{ - int ix, iy; - - if (a->used == 0) { - return MP_NO; - } else if (a->used == 1) { - return MP_YES; - } else if (a->used > 1) { - /* if more than half of the digits are -1 we're sold */ - for (iy = ix = 0; ix < a->used; ix++) { - if (a->dp[ix] == MP_MASK) { - ++iy; - } - } - return (iy >= (a->used/2)) ? MP_YES : MP_NO; - - } - return MP_NO; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_reduce_is_2k_l.c */ - -/* Start: bn_mp_reduce_setup.c */ -#include <tommath_private.h> -#ifdef BN_MP_REDUCE_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* pre-calculate the value required for Barrett reduction - * For a given modulus "b" it calulates the value required in "a" - */ -int mp_reduce_setup (mp_int * a, mp_int * b) -{ - int res; - - if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) { - return res; - } - return mp_div (a, b, a, NULL); -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_reduce_setup.c */ - -/* Start: bn_mp_rshd.c */ -#include <tommath_private.h> -#ifdef BN_MP_RSHD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* shift right a certain amount of digits */ -void mp_rshd (mp_int * a, int b) -{ - int x; - - /* if b <= 0 then ignore it */ - if (b <= 0) { - return; - } - - /* if b > used then simply zero it and return */ - if (a->used <= b) { - mp_zero (a); - return; - } - - { - mp_digit *bottom, *top; - - /* shift the digits down */ - - /* bottom */ - bottom = a->dp; - - /* top [offset into digits] */ - top = a->dp + b; - - /* this is implemented as a sliding window where - * the window is b-digits long and digits from - * the top of the window are copied to the bottom - * - * e.g. - - b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> - /\ | ----> - \-------------------/ ----> - */ - for (x = 0; x < (a->used - b); x++) { - *bottom++ = *top++; - } - - /* zero the top digits */ - for (; x < a->used; x++) { - *bottom++ = 0; - } - } - - /* remove excess digits */ - a->used -= b; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_rshd.c */ - -/* Start: bn_mp_set.c */ -#include <tommath_private.h> -#ifdef BN_MP_SET_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* set to a digit */ -void mp_set (mp_int * a, mp_digit b) -{ - mp_zero (a); - a->dp[0] = b & MP_MASK; - a->used = (a->dp[0] != 0) ? 1 : 0; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_set.c */ - -/* Start: bn_mp_set_int.c */ -#include <tommath_private.h> -#ifdef BN_MP_SET_INT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* set a 32-bit const */ -int mp_set_int (mp_int * a, unsigned long b) -{ - int x, res; - - mp_zero (a); - - /* set four bits at a time */ - for (x = 0; x < 8; x++) { - /* shift the number up four bits */ - if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) { - return res; - } - - /* OR in the top four bits of the source */ - a->dp[0] |= (b >> 28) & 15; - - /* shift the source up to the next four bits */ - b <<= 4; - - /* ensure that digits are not clamped off */ - a->used += 1; - } - mp_clamp (a); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_set_int.c */ - -/* Start: bn_mp_set_long.c */ -#include <tommath_private.h> -#ifdef BN_MP_SET_LONG_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* set a platform dependent unsigned long int */ -MP_SET_XLONG(mp_set_long, unsigned long) -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_set_long.c */ - -/* Start: bn_mp_set_long_long.c */ -#include <tommath_private.h> -#ifdef BN_MP_SET_LONG_LONG_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* set a platform dependent unsigned long long int */ -MP_SET_XLONG(mp_set_long_long, unsigned long long) -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_set_long_long.c */ - -/* Start: bn_mp_shrink.c */ -#include <tommath_private.h> -#ifdef BN_MP_SHRINK_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* shrink a bignum */ -int mp_shrink (mp_int * a) -{ - mp_digit *tmp; - int used = 1; - - if(a->used > 0) { - used = a->used; - } - - if (a->alloc != used) { - if ((tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * used)) == NULL) { - return MP_MEM; - } - a->dp = tmp; - a->alloc = used; - } - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_shrink.c */ - -/* Start: bn_mp_signed_bin_size.c */ -#include <tommath_private.h> -#ifdef BN_MP_SIGNED_BIN_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* get the size for an signed equivalent */ -int mp_signed_bin_size (mp_int * a) -{ - return 1 + mp_unsigned_bin_size (a); -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_signed_bin_size.c */ - -/* Start: bn_mp_sqr.c */ -#include <tommath_private.h> -#ifdef BN_MP_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* computes b = a*a */ -int -mp_sqr (mp_int * a, mp_int * b) -{ - int res; - -#ifdef BN_MP_TOOM_SQR_C - /* use Toom-Cook? */ - if (a->used >= TOOM_SQR_CUTOFF) { - res = mp_toom_sqr(a, b); - /* Karatsuba? */ - } else -#endif -#ifdef BN_MP_KARATSUBA_SQR_C - if (a->used >= KARATSUBA_SQR_CUTOFF) { - res = mp_karatsuba_sqr (a, b); - } else -#endif - { -#ifdef BN_FAST_S_MP_SQR_C - /* can we use the fast comba multiplier? */ - if ((((a->used * 2) + 1) < MP_WARRAY) && - (a->used < - (1 << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) - 1)))) { - res = fast_s_mp_sqr (a, b); - } else -#endif - { -#ifdef BN_S_MP_SQR_C - res = s_mp_sqr (a, b); -#else - res = MP_VAL; -#endif - } - } - b->sign = MP_ZPOS; - return res; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_sqr.c */ - -/* Start: bn_mp_sqrmod.c */ -#include <tommath_private.h> -#ifdef BN_MP_SQRMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* c = a * a (mod b) */ -int -mp_sqrmod (mp_int * a, mp_int * b, mp_int * c) -{ - int res; - mp_int t; - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_sqr (a, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, b, c); - mp_clear (&t); - return res; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_sqrmod.c */ - -/* Start: bn_mp_sqrt.c */ -#include <tommath_private.h> -#ifdef BN_MP_SQRT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* this function is less generic than mp_n_root, simpler and faster */ -int mp_sqrt(mp_int *arg, mp_int *ret) -{ - int res; - mp_int t1,t2; - - /* must be positive */ - if (arg->sign == MP_NEG) { - return MP_VAL; - } - - /* easy out */ - if (mp_iszero(arg) == MP_YES) { - mp_zero(ret); - return MP_OKAY; - } - - if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) { - return res; - } - - if ((res = mp_init(&t2)) != MP_OKAY) { - goto E2; - } - - /* First approx. (not very bad for large arg) */ - mp_rshd (&t1,t1.used/2); - - /* t1 > 0 */ - if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { - goto E1; - } - if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { - goto E1; - } - if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { - goto E1; - } - /* And now t1 > sqrt(arg) */ - do { - if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { - goto E1; - } - if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { - goto E1; - } - if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { - goto E1; - } - /* t1 >= sqrt(arg) >= t2 at this point */ - } while (mp_cmp_mag(&t1,&t2) == MP_GT); - - mp_exch(&t1,ret); - -E1: mp_clear(&t2); -E2: mp_clear(&t1); - return res; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_sqrt.c */ - -/* Start: bn_mp_sqrtmod_prime.c */ -#include <tommath_private.h> -#ifdef BN_MP_SQRTMOD_PRIME_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is free for all purposes without any express - * guarantee it works. - */ - -/* Tonelli-Shanks algorithm - * https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm - * https://gmplib.org/list-archives/gmp-discuss/2013-April/005300.html - * - */ - -int mp_sqrtmod_prime(mp_int *n, mp_int *prime, mp_int *ret) -{ - int res, legendre; - mp_int t1, C, Q, S, Z, M, T, R, two; - mp_digit i; - - /* first handle the simple cases */ - if (mp_cmp_d(n, 0) == MP_EQ) { - mp_zero(ret); - return MP_OKAY; - } - if (mp_cmp_d(prime, 2) == MP_EQ) return MP_VAL; /* prime must be odd */ - if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) return res; - if (legendre == -1) return MP_VAL; /* quadratic non-residue mod prime */ - - if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M, &T, &R, &two, NULL)) != MP_OKAY) { - return res; - } - - /* SPECIAL CASE: if prime mod 4 == 3 - * compute directly: res = n^(prime+1)/4 mod prime - * Handbook of Applied Cryptography algorithm 3.36 - */ - if ((res = mp_mod_d(prime, 4, &i)) != MP_OKAY) goto cleanup; - if (i == 3) { - if ((res = mp_add_d(prime, 1, &t1)) != MP_OKAY) goto cleanup; - if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup; - if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup; - if ((res = mp_exptmod(n, &t1, prime, ret)) != MP_OKAY) goto cleanup; - res = MP_OKAY; - goto cleanup; - } - - /* NOW: Tonelli-Shanks algorithm */ - - /* factor out powers of 2 from prime-1, defining Q and S as: prime-1 = Q*2^S */ - if ((res = mp_copy(prime, &Q)) != MP_OKAY) goto cleanup; - if ((res = mp_sub_d(&Q, 1, &Q)) != MP_OKAY) goto cleanup; - /* Q = prime - 1 */ - mp_zero(&S); - /* S = 0 */ - while (mp_iseven(&Q) != MP_NO) { - if ((res = mp_div_2(&Q, &Q)) != MP_OKAY) goto cleanup; - /* Q = Q / 2 */ - if ((res = mp_add_d(&S, 1, &S)) != MP_OKAY) goto cleanup; - /* S = S + 1 */ - } - - /* find a Z such that the Legendre symbol (Z|prime) == -1 */ - if ((res = mp_set_int(&Z, 2)) != MP_OKAY) goto cleanup; - /* Z = 2 */ - while(1) { - if ((res = mp_jacobi(&Z, prime, &legendre)) != MP_OKAY) goto cleanup; - if (legendre == -1) break; - if ((res = mp_add_d(&Z, 1, &Z)) != MP_OKAY) goto cleanup; - /* Z = Z + 1 */ - } - - if ((res = mp_exptmod(&Z, &Q, prime, &C)) != MP_OKAY) goto cleanup; - /* C = Z ^ Q mod prime */ - if ((res = mp_add_d(&Q, 1, &t1)) != MP_OKAY) goto cleanup; - if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup; - /* t1 = (Q + 1) / 2 */ - if ((res = mp_exptmod(n, &t1, prime, &R)) != MP_OKAY) goto cleanup; - /* R = n ^ ((Q + 1) / 2) mod prime */ - if ((res = mp_exptmod(n, &Q, prime, &T)) != MP_OKAY) goto cleanup; - /* T = n ^ Q mod prime */ - if ((res = mp_copy(&S, &M)) != MP_OKAY) goto cleanup; - /* M = S */ - if ((res = mp_set_int(&two, 2)) != MP_OKAY) goto cleanup; - - res = MP_VAL; - while (1) { - if ((res = mp_copy(&T, &t1)) != MP_OKAY) goto cleanup; - i = 0; - while (1) { - if (mp_cmp_d(&t1, 1) == MP_EQ) break; - if ((res = mp_exptmod(&t1, &two, prime, &t1)) != MP_OKAY) goto cleanup; - i++; - } - if (i == 0) { - if ((res = mp_copy(&R, ret)) != MP_OKAY) goto cleanup; - res = MP_OKAY; - goto cleanup; - } - if ((res = mp_sub_d(&M, i, &t1)) != MP_OKAY) goto cleanup; - if ((res = mp_sub_d(&t1, 1, &t1)) != MP_OKAY) goto cleanup; - if ((res = mp_exptmod(&two, &t1, prime, &t1)) != MP_OKAY) goto cleanup; - /* t1 = 2 ^ (M - i - 1) */ - if ((res = mp_exptmod(&C, &t1, prime, &t1)) != MP_OKAY) goto cleanup; - /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */ - if ((res = mp_sqrmod(&t1, prime, &C)) != MP_OKAY) goto cleanup; - /* C = (t1 * t1) mod prime */ - if ((res = mp_mulmod(&R, &t1, prime, &R)) != MP_OKAY) goto cleanup; - /* R = (R * t1) mod prime */ - if ((res = mp_mulmod(&T, &C, prime, &T)) != MP_OKAY) goto cleanup; - /* T = (T * C) mod prime */ - mp_set(&M, i); - /* M = i */ - } - -cleanup: - mp_clear_multi(&t1, &C, &Q, &S, &Z, &M, &T, &R, &two, NULL); - return res; -} - -#endif - -/* End: bn_mp_sqrtmod_prime.c */ - -/* Start: bn_mp_sub.c */ -#include <tommath_private.h> -#ifdef BN_MP_SUB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* high level subtraction (handles signs) */ -int -mp_sub (mp_int * a, mp_int * b, mp_int * c) -{ - int sa, sb, res; - - sa = a->sign; - sb = b->sign; - - if (sa != sb) { - /* subtract a negative from a positive, OR */ - /* subtract a positive from a negative. */ - /* In either case, ADD their magnitudes, */ - /* and use the sign of the first number. */ - c->sign = sa; - res = s_mp_add (a, b, c); - } else { - /* subtract a positive from a positive, OR */ - /* subtract a negative from a negative. */ - /* First, take the difference between their */ - /* magnitudes, then... */ - if (mp_cmp_mag (a, b) != MP_LT) { - /* Copy the sign from the first */ - c->sign = sa; - /* The first has a larger or equal magnitude */ - res = s_mp_sub (a, b, c); - } else { - /* The result has the *opposite* sign from */ - /* the first number. */ - c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS; - /* The second has a larger magnitude */ - res = s_mp_sub (b, a, c); - } - } - return res; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_sub.c */ - -/* Start: bn_mp_sub_d.c */ -#include <tommath_private.h> -#ifdef BN_MP_SUB_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* single digit subtraction */ -int -mp_sub_d (mp_int * a, mp_digit b, mp_int * c) -{ - mp_digit *tmpa, *tmpc, mu; - int res, ix, oldused; - - /* grow c as required */ - if (c->alloc < (a->used + 1)) { - if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { - return res; - } - } - - /* if a is negative just do an unsigned - * addition [with fudged signs] - */ - if (a->sign == MP_NEG) { - a->sign = MP_ZPOS; - res = mp_add_d(a, b, c); - a->sign = c->sign = MP_NEG; - - /* clamp */ - mp_clamp(c); - - return res; - } - - /* setup regs */ - oldused = c->used; - tmpa = a->dp; - tmpc = c->dp; - - /* if a <= b simply fix the single digit */ - if (((a->used == 1) && (a->dp[0] <= b)) || (a->used == 0)) { - if (a->used == 1) { - *tmpc++ = b - *tmpa; - } else { - *tmpc++ = b; - } - ix = 1; - - /* negative/1digit */ - c->sign = MP_NEG; - c->used = 1; - } else { - /* positive/size */ - c->sign = MP_ZPOS; - c->used = a->used; - - /* subtract first digit */ - *tmpc = *tmpa++ - b; - mu = *tmpc >> ((sizeof(mp_digit) * CHAR_BIT) - 1); - *tmpc++ &= MP_MASK; - - /* handle rest of the digits */ - for (ix = 1; ix < a->used; ix++) { - *tmpc = *tmpa++ - mu; - mu = *tmpc >> ((sizeof(mp_digit) * CHAR_BIT) - 1); - *tmpc++ &= MP_MASK; - } - } - - /* zero excess digits */ - while (ix++ < oldused) { - *tmpc++ = 0; - } - mp_clamp(c); - return MP_OKAY; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_sub_d.c */ - -/* Start: bn_mp_submod.c */ -#include <tommath_private.h> -#ifdef BN_MP_SUBMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* d = a - b (mod c) */ -int -mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) -{ - int res; - mp_int t; - - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_sub (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, c, d); - mp_clear (&t); - return res; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_submod.c */ - -/* Start: bn_mp_to_signed_bin.c */ -#include <tommath_private.h> -#ifdef BN_MP_TO_SIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* store in signed [big endian] format */ -int mp_to_signed_bin (mp_int * a, unsigned char *b) -{ - int res; - - if ((res = mp_to_unsigned_bin (a, b + 1)) != MP_OKAY) { - return res; - } - b[0] = (a->sign == MP_ZPOS) ? (unsigned char)0 : (unsigned char)1; - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_to_signed_bin.c */ - -/* Start: bn_mp_to_signed_bin_n.c */ -#include <tommath_private.h> -#ifdef BN_MP_TO_SIGNED_BIN_N_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* store in signed [big endian] format */ -int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen) -{ - if (*outlen < (unsigned long)mp_signed_bin_size(a)) { - return MP_VAL; - } - *outlen = mp_signed_bin_size(a); - return mp_to_signed_bin(a, b); -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_to_signed_bin_n.c */ - -/* Start: bn_mp_to_unsigned_bin.c */ -#include <tommath_private.h> -#ifdef BN_MP_TO_UNSIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* store in unsigned [big endian] format */ -int mp_to_unsigned_bin (mp_int * a, unsigned char *b) -{ - int x, res; - mp_int t; - - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - x = 0; - while (mp_iszero (&t) == MP_NO) { -#ifndef MP_8BIT - b[x++] = (unsigned char) (t.dp[0] & 255); -#else - b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7)); -#endif - if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) { - mp_clear (&t); - return res; - } - } - bn_reverse (b, x); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_to_unsigned_bin.c */ - -/* Start: bn_mp_to_unsigned_bin_n.c */ -#include <tommath_private.h> -#ifdef BN_MP_TO_UNSIGNED_BIN_N_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* store in unsigned [big endian] format */ -int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen) -{ - if (*outlen < (unsigned long)mp_unsigned_bin_size(a)) { - return MP_VAL; - } - *outlen = mp_unsigned_bin_size(a); - return mp_to_unsigned_bin(a, b); -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_to_unsigned_bin_n.c */ - -/* Start: bn_mp_toom_mul.c */ -#include <tommath_private.h> -#ifdef BN_MP_TOOM_MUL_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* multiplication using the Toom-Cook 3-way algorithm - * - * Much more complicated than Karatsuba but has a lower - * asymptotic running time of O(N**1.464). This algorithm is - * only particularly useful on VERY large inputs - * (we're talking 1000s of digits here...). -*/ -int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c) -{ - mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2; - int res, B; - - /* init temps */ - if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, - &a0, &a1, &a2, &b0, &b1, - &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) { - return res; - } - - /* B */ - B = MIN(a->used, b->used) / 3; - - /* a = a2 * B**2 + a1 * B + a0 */ - if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(a, &a1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a1, B); - if ((res = mp_mod_2d(&a1, DIGIT_BIT * B, &a1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(a, &a2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a2, B*2); - - /* b = b2 * B**2 + b1 * B + b0 */ - if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(b, &b1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&b1, B); - (void)mp_mod_2d(&b1, DIGIT_BIT * B, &b1); - - if ((res = mp_copy(b, &b2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&b2, B*2); - - /* w0 = a0*b0 */ - if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) { - goto ERR; - } - - /* w4 = a2 * b2 */ - if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) { - goto ERR; - } - - /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */ - if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) { - goto ERR; - } - - /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */ - if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) { - goto ERR; - } - - - /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */ - if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) { - goto ERR; - } - - /* now solve the matrix - - 0 0 0 0 1 - 1 2 4 8 16 - 1 1 1 1 1 - 16 8 4 2 1 - 1 0 0 0 0 - - using 12 subtractions, 4 shifts, - 2 small divisions and 1 small multiplication - */ - - /* r1 - r4 */ - if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r0 */ - if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/2 */ - if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3/2 */ - if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { - goto ERR; - } - /* r2 - r0 - r4 */ - if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1 - 8r0 */ - if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - 8r4 */ - if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - /* 3r2 - r1 - r3 */ - if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/3 */ - if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { - goto ERR; - } - /* r3/3 */ - if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { - goto ERR; - } - - /* at this point shift W[n] by B*n */ - if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) { - goto ERR; - } - -ERR: - mp_clear_multi(&w0, &w1, &w2, &w3, &w4, - &a0, &a1, &a2, &b0, &b1, - &b2, &tmp1, &tmp2, NULL); - return res; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_toom_mul.c */ - -/* Start: bn_mp_toom_sqr.c */ -#include <tommath_private.h> -#ifdef BN_MP_TOOM_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* squaring using Toom-Cook 3-way algorithm */ -int -mp_toom_sqr(mp_int *a, mp_int *b) -{ - mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2; - int res, B; - - /* init temps */ - if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) { - return res; - } - - /* B */ - B = a->used / 3; - - /* a = a2 * B**2 + a1 * B + a0 */ - if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(a, &a1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a1, B); - if ((res = mp_mod_2d(&a1, DIGIT_BIT * B, &a1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(a, &a2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a2, B*2); - - /* w0 = a0*a0 */ - if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) { - goto ERR; - } - - /* w4 = a2 * a2 */ - if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) { - goto ERR; - } - - /* w1 = (a2 + 2(a1 + 2a0))**2 */ - if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - - /* w3 = (a0 + 2(a1 + 2a2))**2 */ - if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - - - /* w2 = (a2 + a1 + a0)**2 */ - if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) { - goto ERR; - } - - /* now solve the matrix - - 0 0 0 0 1 - 1 2 4 8 16 - 1 1 1 1 1 - 16 8 4 2 1 - 1 0 0 0 0 - - using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication. - */ - - /* r1 - r4 */ - if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r0 */ - if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/2 */ - if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3/2 */ - if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { - goto ERR; - } - /* r2 - r0 - r4 */ - if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1 - 8r0 */ - if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - 8r4 */ - if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - /* 3r2 - r1 - r3 */ - if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/3 */ - if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { - goto ERR; - } - /* r3/3 */ - if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { - goto ERR; - } - - /* at this point shift W[n] by B*n */ - if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) { - goto ERR; - } - -ERR: - mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL); - return res; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_toom_sqr.c */ - -/* Start: bn_mp_toradix.c */ -#include <tommath_private.h> -#ifdef BN_MP_TORADIX_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* stores a bignum as a ASCII string in a given radix (2..64) */ -int mp_toradix (mp_int * a, char *str, int radix) -{ - int res, digs; - mp_int t; - mp_digit d; - char *_s = str; - - /* check range of the radix */ - if ((radix < 2) || (radix > 64)) { - return MP_VAL; - } - - /* quick out if its zero */ - if (mp_iszero(a) == MP_YES) { - *str++ = '0'; - *str = '\0'; - return MP_OKAY; - } - - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - /* if it is negative output a - */ - if (t.sign == MP_NEG) { - ++_s; - *str++ = '-'; - t.sign = MP_ZPOS; - } - - digs = 0; - while (mp_iszero (&t) == MP_NO) { - if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { - mp_clear (&t); - return res; - } - *str++ = mp_s_rmap[d]; - ++digs; - } - - /* reverse the digits of the string. In this case _s points - * to the first digit [exluding the sign] of the number] - */ - bn_reverse ((unsigned char *)_s, digs); - - /* append a NULL so the string is properly terminated */ - *str = '\0'; - - mp_clear (&t); - return MP_OKAY; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_toradix.c */ - -/* Start: bn_mp_toradix_n.c */ -#include <tommath_private.h> -#ifdef BN_MP_TORADIX_N_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* stores a bignum as a ASCII string in a given radix (2..64) - * - * Stores upto maxlen-1 chars and always a NULL byte - */ -int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen) -{ - int res, digs; - mp_int t; - mp_digit d; - char *_s = str; - - /* check range of the maxlen, radix */ - if ((maxlen < 2) || (radix < 2) || (radix > 64)) { - return MP_VAL; - } - - /* quick out if its zero */ - if (mp_iszero(a) == MP_YES) { - *str++ = '0'; - *str = '\0'; - return MP_OKAY; - } - - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - /* if it is negative output a - */ - if (t.sign == MP_NEG) { - /* we have to reverse our digits later... but not the - sign!! */ - ++_s; - - /* store the flag and mark the number as positive */ - *str++ = '-'; - t.sign = MP_ZPOS; - - /* subtract a char */ - --maxlen; - } - - digs = 0; - while (mp_iszero (&t) == MP_NO) { - if (--maxlen < 1) { - /* no more room */ - break; - } - if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { - mp_clear (&t); - return res; - } - *str++ = mp_s_rmap[d]; - ++digs; - } - - /* reverse the digits of the string. In this case _s points - * to the first digit [exluding the sign] of the number - */ - bn_reverse ((unsigned char *)_s, digs); - - /* append a NULL so the string is properly terminated */ - *str = '\0'; - - mp_clear (&t); - return MP_OKAY; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_toradix_n.c */ - -/* Start: bn_mp_unsigned_bin_size.c */ -#include <tommath_private.h> -#ifdef BN_MP_UNSIGNED_BIN_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* get the size for an unsigned equivalent */ -int mp_unsigned_bin_size (mp_int * a) -{ - int size = mp_count_bits (a); - return (size / 8) + (((size & 7) != 0) ? 1 : 0); -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_unsigned_bin_size.c */ - -/* Start: bn_mp_xor.c */ -#include <tommath_private.h> -#ifdef BN_MP_XOR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* XOR two ints together */ -int -mp_xor (mp_int * a, mp_int * b, mp_int * c) -{ - int res, ix, px; - mp_int t, *x; - - if (a->used > b->used) { - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - px = b->used; - x = b; - } else { - if ((res = mp_init_copy (&t, b)) != MP_OKAY) { - return res; - } - px = a->used; - x = a; - } - - for (ix = 0; ix < px; ix++) { - t.dp[ix] ^= x->dp[ix]; - } - mp_clamp (&t); - mp_exch (c, &t); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_xor.c */ - -/* Start: bn_mp_zero.c */ -#include <tommath_private.h> -#ifdef BN_MP_ZERO_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* set to zero */ -void mp_zero (mp_int * a) -{ - int n; - mp_digit *tmp; - - a->sign = MP_ZPOS; - a->used = 0; - - tmp = a->dp; - for (n = 0; n < a->alloc; n++) { - *tmp++ = 0; - } -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_mp_zero.c */ - -/* Start: bn_prime_tab.c */ -#include <tommath_private.h> -#ifdef BN_PRIME_TAB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ -const mp_digit ltm_prime_tab[] = { - 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, - 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, - 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, - 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, -#ifndef MP_8BIT - 0x0083, - 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD, - 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF, - 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107, - 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137, - - 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167, - 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199, - 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9, - 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7, - 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239, - 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265, - 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293, - 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF, - - 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301, - 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B, - 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371, - 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD, - 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5, - 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419, - 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449, - 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B, - - 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7, - 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503, - 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529, - 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F, - 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3, - 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7, - 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623, - 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 -#endif -}; -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_prime_tab.c */ - -/* Start: bn_reverse.c */ -#include <tommath_private.h> -#ifdef BN_REVERSE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* reverse an array, used for radix code */ -void -bn_reverse (unsigned char *s, int len) -{ - int ix, iy; - unsigned char t; - - ix = 0; - iy = len - 1; - while (ix < iy) { - t = s[ix]; - s[ix] = s[iy]; - s[iy] = t; - ++ix; - --iy; - } -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_reverse.c */ - -/* Start: bn_s_mp_add.c */ -#include <tommath_private.h> -#ifdef BN_S_MP_ADD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* low level addition, based on HAC pp.594, Algorithm 14.7 */ -int -s_mp_add (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int *x; - int olduse, res, min, max; - - /* find sizes, we let |a| <= |b| which means we have to sort - * them. "x" will point to the input with the most digits - */ - if (a->used > b->used) { - min = b->used; - max = a->used; - x = a; - } else { - min = a->used; - max = b->used; - x = b; - } - - /* init result */ - if (c->alloc < (max + 1)) { - if ((res = mp_grow (c, max + 1)) != MP_OKAY) { - return res; - } - } - - /* get old used digit count and set new one */ - olduse = c->used; - c->used = max + 1; - - { - mp_digit u, *tmpa, *tmpb, *tmpc; - int i; - - /* alias for digit pointers */ - - /* first input */ - tmpa = a->dp; - - /* second input */ - tmpb = b->dp; - - /* destination */ - tmpc = c->dp; - - /* zero the carry */ - u = 0; - for (i = 0; i < min; i++) { - /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */ - *tmpc = *tmpa++ + *tmpb++ + u; - - /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)DIGIT_BIT); - - /* take away carry bit from T[i] */ - *tmpc++ &= MP_MASK; - } - - /* now copy higher words if any, that is in A+B - * if A or B has more digits add those in - */ - if (min != max) { - for (; i < max; i++) { - /* T[i] = X[i] + U */ - *tmpc = x->dp[i] + u; - - /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)DIGIT_BIT); - - /* take away carry bit from T[i] */ - *tmpc++ &= MP_MASK; - } - } - - /* add carry */ - *tmpc++ = u; - - /* clear digits above oldused */ - for (i = c->used; i < olduse; i++) { - *tmpc++ = 0; - } - } - - mp_clamp (c); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_s_mp_add.c */ - -/* Start: bn_s_mp_exptmod.c */ -#include <tommath_private.h> -#ifdef BN_S_MP_EXPTMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ -#ifdef MP_LOW_MEM - #define TAB_SIZE 32 -#else - #define TAB_SIZE 256 -#endif - -int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) -{ - mp_int M[TAB_SIZE], res, mu; - mp_digit buf; - int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; - int (*redux)(mp_int*,mp_int*,mp_int*); - - /* 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 = mp_init(&M[1])) != MP_OKAY) { - return err; - } - - /* now init the second half of the array */ - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - if ((err = mp_init(&M[x])) != MP_OKAY) { - for (y = 1<<(winsize-1); y < x; y++) { - mp_clear (&M[y]); - } - mp_clear(&M[1]); - return err; - } - } - - /* create mu, used for Barrett reduction */ - if ((err = mp_init (&mu)) != MP_OKAY) { - goto LBL_M; - } - - if (redmode == 0) { - if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) { - goto LBL_MU; - } - redux = mp_reduce; - } else { - if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) { - goto LBL_MU; - } - redux = mp_reduce_2k_l; - } - - /* 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 ((err = mp_mod (G, P, &M[1])) != MP_OKAY) { - goto LBL_MU; - } - - /* compute the value at M[1<<(winsize-1)] by squaring - * M[1] (winsize-1) times - */ - if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_MU; - } - - for (x = 0; x < (winsize - 1); x++) { - /* square it */ - if ((err = mp_sqr (&M[1 << (winsize - 1)], - &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_MU; - } - - /* reduce modulo P */ - if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) { - goto LBL_MU; - } - } - - /* 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 = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { - goto LBL_MU; - } - if ((err = redux (&M[x], P, &mu)) != MP_OKAY) { - goto LBL_MU; - } - } - - /* setup result */ - if ((err = mp_init (&res)) != MP_OKAY) { - goto LBL_MU; - } - mp_set (&res, 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 = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_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 = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* then multiply */ - if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_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 = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - - bitbuf <<= 1; - if ((bitbuf & (1 << winsize)) != 0) { - /* then multiply */ - if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - } - } - } - - mp_exch (&res, Y); - err = MP_OKAY; -LBL_RES:mp_clear (&res); -LBL_MU:mp_clear (&mu); -LBL_M: - mp_clear(&M[1]); - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - mp_clear (&M[x]); - } - return err; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_s_mp_exptmod.c */ - -/* Start: bn_s_mp_mul_digs.c */ -#include <tommath_private.h> -#ifdef BN_S_MP_MUL_DIGS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* multiplies |a| * |b| and only computes upto digs digits of result - * HAC pp. 595, Algorithm 14.12 Modified so you can control how - * many digits of output are created. - */ -int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - mp_int t; - int res, pa, pb, ix, iy; - mp_digit u; - mp_word r; - mp_digit tmpx, *tmpt, *tmpy; - - /* can we use the fast multiplier? */ - if (((digs) < MP_WARRAY) && - (MIN (a->used, b->used) < - (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) { - return fast_s_mp_mul_digs (a, b, c, digs); - } - - if ((res = mp_init_size (&t, digs)) != MP_OKAY) { - return res; - } - t.used = digs; - - /* compute the digits of the product directly */ - pa = a->used; - for (ix = 0; ix < pa; ix++) { - /* set the carry to zero */ - u = 0; - - /* limit ourselves to making digs digits of output */ - pb = MIN (b->used, digs - ix); - - /* setup some aliases */ - /* copy of the digit from a used within the nested loop */ - tmpx = a->dp[ix]; - - /* an alias for the destination shifted ix places */ - tmpt = t.dp + ix; - - /* an alias for the digits of b */ - tmpy = b->dp; - - /* compute the columns of the output and propagate the carry */ - for (iy = 0; iy < pb; iy++) { - /* compute the column as a mp_word */ - r = (mp_word)*tmpt + - ((mp_word)tmpx * (mp_word)*tmpy++) + - (mp_word)u; - - /* the new column is the lower part of the result */ - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* get the carry word from the result */ - u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); - } - /* set carry if it is placed below digs */ - if ((ix + iy) < digs) { - *tmpt = u; - } - } - - mp_clamp (&t); - mp_exch (&t, c); - - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_s_mp_mul_digs.c */ - -/* Start: bn_s_mp_mul_high_digs.c */ -#include <tommath_private.h> -#ifdef BN_S_MP_MUL_HIGH_DIGS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* multiplies |a| * |b| and does not compute the lower digs digits - * [meant to get the higher part of the product] - */ -int -s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - mp_int t; - int res, pa, pb, ix, iy; - mp_digit u; - mp_word r; - mp_digit tmpx, *tmpt, *tmpy; - - /* can we use the fast multiplier? */ -#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C - if (((a->used + b->used + 1) < MP_WARRAY) - && (MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) { - return fast_s_mp_mul_high_digs (a, b, c, digs); - } -#endif - - if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) { - return res; - } - t.used = a->used + b->used + 1; - - pa = a->used; - pb = b->used; - for (ix = 0; ix < pa; ix++) { - /* clear the carry */ - u = 0; - - /* left hand side of A[ix] * B[iy] */ - tmpx = a->dp[ix]; - - /* alias to the address of where the digits will be stored */ - tmpt = &(t.dp[digs]); - - /* alias for where to read the right hand side from */ - tmpy = b->dp + (digs - ix); - - for (iy = digs - ix; iy < pb; iy++) { - /* calculate the double precision result */ - r = (mp_word)*tmpt + - ((mp_word)tmpx * (mp_word)*tmpy++) + - (mp_word)u; - - /* get the lower part */ - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* carry the carry */ - u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); - } - *tmpt = u; - } - mp_clamp (&t); - mp_exch (&t, c); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_s_mp_mul_high_digs.c */ - -/* Start: bn_s_mp_sqr.c */ -#include <tommath_private.h> -#ifdef BN_S_MP_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */ -int s_mp_sqr (mp_int * a, mp_int * b) -{ - mp_int t; - int res, ix, iy, pa; - mp_word r; - mp_digit u, tmpx, *tmpt; - - pa = a->used; - if ((res = mp_init_size (&t, (2 * pa) + 1)) != MP_OKAY) { - return res; - } - - /* default used is maximum possible size */ - t.used = (2 * pa) + 1; - - for (ix = 0; ix < pa; ix++) { - /* first calculate the digit at 2*ix */ - /* calculate double precision result */ - r = (mp_word)t.dp[2*ix] + - ((mp_word)a->dp[ix] * (mp_word)a->dp[ix]); - - /* store lower part in result */ - t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* get the carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - - /* left hand side of A[ix] * A[iy] */ - tmpx = a->dp[ix]; - - /* alias for where to store the results */ - tmpt = t.dp + ((2 * ix) + 1); - - for (iy = ix + 1; iy < pa; iy++) { - /* first calculate the product */ - r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]); - - /* now calculate the double precision result, note we use - * addition instead of *2 since it's easier to optimize - */ - r = ((mp_word) *tmpt) + r + r + ((mp_word) u); - - /* store lower part */ - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* get carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - } - /* propagate upwards */ - while (u != ((mp_digit) 0)) { - r = ((mp_word) *tmpt) + ((mp_word) u); - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - } - } - - mp_clamp (&t); - mp_exch (&t, b); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_s_mp_sqr.c */ - -/* Start: bn_s_mp_sub.c */ -#include <tommath_private.h> -#ifdef BN_S_MP_SUB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */ -int -s_mp_sub (mp_int * a, mp_int * b, mp_int * c) -{ - int olduse, res, min, max; - - /* find sizes */ - min = b->used; - max = a->used; - - /* init result */ - if (c->alloc < max) { - if ((res = mp_grow (c, max)) != MP_OKAY) { - return res; - } - } - olduse = c->used; - c->used = max; - - { - mp_digit u, *tmpa, *tmpb, *tmpc; - int i; - - /* alias for digit pointers */ - tmpa = a->dp; - tmpb = b->dp; - tmpc = c->dp; - - /* set carry to zero */ - u = 0; - for (i = 0; i < min; i++) { - /* T[i] = A[i] - B[i] - U */ - *tmpc = (*tmpa++ - *tmpb++) - u; - - /* U = carry bit of T[i] - * Note this saves performing an AND operation since - * if a carry does occur it will propagate all the way to the - * MSB. As a result a single shift is enough to get the carry - */ - u = *tmpc >> ((mp_digit)((CHAR_BIT * sizeof(mp_digit)) - 1)); - - /* Clear carry from T[i] */ - *tmpc++ &= MP_MASK; - } - - /* now copy higher words if any, e.g. if A has more digits than B */ - for (; i < max; i++) { - /* T[i] = A[i] - U */ - *tmpc = *tmpa++ - u; - - /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)((CHAR_BIT * sizeof(mp_digit)) - 1)); - - /* Clear carry from T[i] */ - *tmpc++ &= MP_MASK; - } - - /* clear digits above used (since we may not have grown result above) */ - for (i = c->used; i < olduse; i++) { - *tmpc++ = 0; - } - } - - mp_clamp (c); - return MP_OKAY; -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bn_s_mp_sub.c */ - -/* Start: bncore.c */ -#include <tommath_private.h> -#ifdef BNCORE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ - -/* Known optimal configurations - - CPU /Compiler /MUL CUTOFF/SQR CUTOFF -------------------------------------------------------------- - Intel P4 Northwood /GCC v3.4.1 / 88/ 128/LTM 0.32 ;-) - AMD Athlon64 /GCC v3.4.4 / 80/ 120/LTM 0.35 - -*/ - -int KARATSUBA_MUL_CUTOFF = 80, /* Min. number of digits before Karatsuba multiplication is used. */ - KARATSUBA_SQR_CUTOFF = 120, /* Min. number of digits before Karatsuba squaring is used. */ - - TOOM_MUL_CUTOFF = 350, /* no optimal values of these are known yet so set em high */ - TOOM_SQR_CUTOFF = 400; -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ - -/* End: bncore.c */ - - -/* EOF */ diff --git a/libtommath/pretty.build b/libtommath/pretty.build deleted file mode 100644 index a708b8a..0000000 --- a/libtommath/pretty.build +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/perl -w -# -# Cute little builder for perl -# Total waste of development time... -# -# This will build all the object files and then the archive .a file -# requires GCC, GNU make and a sense of humour. -# -# Tom St Denis -use strict; - -my $count = 0; -my $starttime = time; -my $rate = 0; -print "Scanning for source files...\n"; -foreach my $filename (glob "*.c") { - ++$count; -} -print "Source files to build: $count\nBuilding...\n"; -my $i = 0; -my $lines = 0; -my $filesbuilt = 0; -foreach my $filename (glob "*.c") { - printf("Building %3.2f%%, ", (++$i/$count)*100.0); - if ($i % 4 == 0) { print "/, "; } - if ($i % 4 == 1) { print "-, "; } - if ($i % 4 == 2) { print "\\, "; } - if ($i % 4 == 3) { print "|, "; } - if ($rate > 0) { - my $tleft = ($count - $i) / $rate; - my $tsec = $tleft%60; - my $tmin = ($tleft/60)%60; - my $thour = ($tleft/3600)%60; - printf("%2d:%02d:%02d left, ", $thour, $tmin, $tsec); - } - my $cnt = ($i/$count)*30.0; - my $x = 0; - print "["; - for (; $x < $cnt; $x++) { print "#"; } - for (; $x < 30; $x++) { print " "; } - print "]\r"; - my $tmp = $filename; - $tmp =~ s/\.c/".o"/ge; - if (open(SRC, "<$tmp")) { - close SRC; - } else { - !system("make $tmp > /dev/null 2>/dev/null") or die "\nERROR: Failed to make $tmp!!!\n"; - open( SRC, "<$filename" ) or die "Couldn't open $filename for reading: $!"; - ++$lines while (<SRC>); - close SRC or die "Error closing $filename after reading: $!"; - ++$filesbuilt; - } - - # update timer - if (time != $starttime) { - my $delay = time - $starttime; - $rate = $i/$delay; - } -} - -# finish building the library -printf("\nFinished building source (%d seconds, %3.2f files per second).\n", time - $starttime, $rate); -print "Compiled approximately $filesbuilt files and $lines lines of code.\n"; -print "Doing final make (building archive...)\n"; -!system("make > /dev/null 2>/dev/null") or die "\nERROR: Failed to perform last make command!!!\n"; -print "done.\n";
\ No newline at end of file diff --git a/libtommath/testme.sh b/libtommath/testme.sh index ee2e87c..40fa32d 100755 --- a/libtommath/testme.sh +++ b/libtommath/testme.sh @@ -4,6 +4,7 @@ # 0 success # 128 a test failed # >0 the number of timed-out tests +# 255 parsing of parameters failed set -e @@ -21,35 +22,69 @@ _help() { echo "Usage options for $(basename $0) [--with-cc=arg [other options]]" echo - echo "Executing this script without any parameter will only run the default configuration" - echo "that has automatically been determined for the architecture you're running." + echo "Executing this script without any parameter will only run the default" + echo "configuration that has automatically been determined for the" + echo "architecture you're running." echo echo " --with-cc=* The compiler(s) to use for the tests" - echo " This is an option that will be iterated." + echo " This is an option that will be iterated." echo - echo "To be able to specify options a compiler has to be given." - echo "All options will be tested with all MP_xBIT configurations." + echo " --test-vs-mtest=* Run test vs. mtest for '*' operations." + echo " Only the first of each options will be" + echo " taken into account." echo - echo " --with-{m64,m32,mx32} The architecture(s) to build and test for," - echo " e.g. --with-mx32." - echo " This is an option that will be iterated, multiple selections are possible." - echo " The mx32 architecture is not supported by clang and will not be executed." + echo "To be able to specify options a compiler has to be given with" + echo "the option --with-cc=compilername" + echo "All other options will be tested with all MP_xBIT configurations." + echo + echo " --with-{m64,m32,mx32} The architecture(s) to build and test" + echo " for, e.g. --with-mx32." + echo " This is an option that will be iterated," + echo " multiple selections are possible." + echo " The mx32 architecture is not supported" + echo " by clang and will not be executed." echo echo " --cflags=* Give an option to the compiler," echo " e.g. --cflags=-g" - echo " This is an option that will always be passed as parameter to CC." + echo " This is an option that will always be" + echo " passed as parameter to CC." echo echo " --make-option=* Give an option to make," echo " e.g. --make-option=\"-f makefile.shared\"" - echo " This is an option that will always be passed as parameter to make." + echo " This is an option that will always be" + echo " passed as parameter to make." echo echo " --with-low-mp Also build&run tests with -DMP_{8,16,32}BIT." echo + echo " --mtest-real-rand Use real random data when running mtest." + echo + echo " --with-valgrind" + echo " --with-valgrind=* Run in valgrind (slow!)." + echo + echo " --with-travis-valgrind Run with valgrind on Travis on specific branches." + echo + echo " --valgrind-options Additional Valgrind options" + echo " Some of the options like e.g.:" + echo " --track-origins=yes add a lot of extra" + echo " runtime and may trigger the 30 minutes" + echo " timeout." + echo echo "Godmode:" echo - echo " --all Choose all architectures and gcc and clang as compilers" + echo " --all Choose all architectures and gcc and clang" + echo " as compilers but does not run valgrind." + echo + echo " --format Runs the various source-code formatters" + echo " and generators and checks if the sources" + echo " are clean." echo + echo " -h" echo " --help This message" + echo + echo " -v" + echo " --version Prints the version. It is just the number" + echo " of git commits to this file, no deeper" + echo " meaning attached" exit 0 } @@ -61,28 +96,73 @@ _die() exit 128 else echo "assuming timeout while running test - continue" + local _tail="" + which tail >/dev/null && _tail="tail -n 1 test_${suffix}.log" && \ + echo "last line of test_"${suffix}".log was:" && $_tail && echo "" ret=$(( $ret + 1 )) fi } -_runtest() +_make() { echo -ne " Compile $1 $2" - make clean > /dev/null suffix=$(echo ${1}${2} | tr ' ' '_') - CC="$1" CFLAGS="$2 $TEST_CFLAGS" make -j$MAKE_JOBS test_standalone $MAKE_OPTIONS > /dev/null 2>gcc_errors_${suffix}.txt - errcnt=$(wc -l < gcc_errors_${suffix}.txt) + CC="$1" CFLAGS="$2 $TEST_CFLAGS" make -j$MAKE_JOBS $3 $MAKE_OPTIONS > /dev/null 2>gcc_errors_${suffix}.log + errcnt=$(wc -l < gcc_errors_${suffix}.log) if [[ ${errcnt} -gt 1 ]]; then echo " failed" - cat gcc_errors_${suffix}.txt + cat gcc_errors_${suffix}.log exit 128 fi - echo -e "\rRun test $1 $2" +} + + +_runtest() +{ + make clean > /dev/null local _timeout="" which timeout >/dev/null && _timeout="timeout --foreground 90" - $_timeout ./test > test_${suffix}.txt || _die "running tests" $? + if [[ "$MAKE_OPTIONS" =~ "tune" ]] + then + # "make tune" will run "tune_it.sh" automatically, hence "autotune", but it cannot + # get switched off without some effort, so we just let it run twice for testing purposes + echo -e "\rRun autotune $1 $2" + _make "$1" "$2" "" + $_timeout $TUNE_CMD > test_${suffix}.log || _die "running autotune" $? + else + _make "$1" "$2" "test" + echo -e "\rRun test $1 $2" + $_timeout ./test > test_${suffix}.log || _die "running tests" $? + fi +} + +# This is not much more of a C&P of _runtest with a different timeout +# and the additional valgrind call. +# TODO: merge +_runvalgrind() +{ + make clean > /dev/null + local _timeout="" + # 30 minutes? Yes. Had it at 20 minutes and the Valgrind run needed over 25 minutes. + # A bit too close for comfort. + which timeout >/dev/null && _timeout="timeout --foreground 1800" +echo "MAKE_OPTIONS = \"$MAKE_OPTIONS\"" + if [[ "$MAKE_OPTIONS" =~ "tune" ]] + then +echo "autotune branch" + _make "$1" "$2" "" + # The shell used for /bin/sh is DASH 0.5.7-4ubuntu1 on the author's machine which fails valgrind, so + # we just run on instance of etc/tune with the same options as in etc/tune_it.sh + echo -e "\rRun etc/tune $1 $2 once inside valgrind" + $_timeout $VALGRIND_BIN $VALGRIND_OPTS $TUNE_CMD > test_${suffix}.log || _die "running etc/tune" $? + else + _make "$1" "$2" "test" + echo -e "\rRun test $1 $2 inside valgrind" + $_timeout $VALGRIND_BIN $VALGRIND_OPTS ./test > test_${suffix}.log || _die "running tests" $? + fi } + _banner() { echo "uname="$(uname -a) @@ -105,6 +185,31 @@ ARCHFLAGS="" COMPILERS="" CFLAGS="" WITH_LOW_MP="" +TEST_VS_MTEST="" +MTEST_RAND="" +# timed with an AMD A8-6600K +# 25 minutes +#VALGRIND_OPTS=" --track-origins=yes --leak-check=full --show-leak-kinds=all --error-exitcode=1 " +# 9 minutes (14 minutes with --test-vs-mtest=333333 --mtest-real-rand) +VALGRIND_OPTS=" --leak-check=full --show-leak-kinds=all --error-exitcode=1 " +#VALGRIND_OPTS="" +VALGRIND_BIN="" +CHECK_FORMAT="" +TUNE_CMD="./etc/tune -t -r 10 -L 3" + +alive_pid=0 + +function kill_alive() { + disown $alive_pid || true + kill $alive_pid 2>/dev/null +} + +function start_alive_printing() { + [ "$alive_pid" == "0" ] || return 0; + for i in `seq 1 10` ; do sleep 300 && echo "Tests still in Progress..."; done & + alive_pid=$! + trap kill_alive EXIT +} while [ $# -gt 0 ]; do @@ -118,12 +223,51 @@ do --cflags=*) CFLAGS="$CFLAGS ${1#*=}" ;; + --valgrind-options=*) + VALGRIND_OPTS="$VALGRIND_OPTS ${1#*=}" + ;; + --with-valgrind*) + if [[ ${1#*d} != "" ]] + then + VALGRIND_BIN="${1#*=}" + else + VALGRIND_BIN="valgrind" + fi + start_alive_printing + ;; + --with-travis-valgrind*) + if [[ ("$TRAVIS_BRANCH" == "develop" && "$TRAVIS_PULL_REQUEST" == "false") || "$TRAVIS_BRANCH" == *"valgrind"* || "$TRAVIS_COMMIT_MESSAGE" == *"valgrind"* ]] + then + if [[ ${1#*d} != "" ]] + then + VALGRIND_BIN="${1#*=}" + else + VALGRIND_BIN="valgrind" + fi + start_alive_printing + fi + ;; --make-option=*) MAKE_OPTIONS="$MAKE_OPTIONS ${1#*=}" ;; --with-low-mp) WITH_LOW_MP="1" ;; + --test-vs-mtest=*) + TEST_VS_MTEST="${1#*=}" + if ! [ "$TEST_VS_MTEST" -eq "$TEST_VS_MTEST" ] 2> /dev/null + then + echo "--test-vs-mtest Parameter has to be int" + exit 255 + fi + start_alive_printing + ;; + --mtest-real-rand) + MTEST_RAND="-DLTM_MTEST_REAL_RAND" + ;; + --format) + CHECK_FORMAT="1" + ;; --all) COMPILERS="gcc clang" ARCHFLAGS="-m64 -m32 -mx32" @@ -131,6 +275,10 @@ do --help | -h) _help ;; + --version | -v) + echo $(git rev-list HEAD --count -- testme.sh) || echo "Unknown. Please run in original libtommath git repository." + exit 0 + ;; *) echo "Ignoring option ${1}" ;; @@ -138,18 +286,42 @@ do shift done -# default to gcc if no compiler is defined but some other options +function _check_git() { + git update-index --refresh >/dev/null || true + git diff-index --quiet HEAD -- . || ( echo "FAILURE: $*" && exit 1 ) +} + +if [[ "$CHECK_FORMAT" == "1" ]] +then + make astyle + _check_git "make astyle" + perl helper.pl --update-files + _check_git "helper.pl --update-files" + perl helper.pl --check-all + _check_git "helper.pl --check-all" + exit $? +fi + +[[ "$VALGRIND_BIN" == "" ]] && VALGRIND_OPTS="" + +# default to CC environment variable if no compiler is defined but some other options if [[ "$COMPILERS" == "" ]] && [[ "$ARCHFLAGS$MAKE_OPTIONS$CFLAGS" != "" ]] then - COMPILERS="gcc" -# default to gcc and run only default config if no option is given + COMPILERS="$CC" +# default to CC environment variable and run only default config if no option is given elif [[ "$COMPILERS" == "" ]] then - _banner gcc - _runtest "gcc" "" + _banner "$CC" + if [[ "$VALGRIND_BIN" != "" ]] + then + _runvalgrind "$CC" "" + else + _runtest "$CC" "" + fi _exit fi + archflags=( $ARCHFLAGS ) compilers=( $COMPILERS ) @@ -161,6 +333,23 @@ fi _banner +if [[ "$TEST_VS_MTEST" != "" ]] +then + make clean > /dev/null + _make "${compilers[0]} ${archflags[0]}" "$CFLAGS" "mtest_opponent" + echo + _make "gcc" "$MTEST_RAND" "mtest" + echo + echo "Run test vs. mtest for $TEST_VS_MTEST iterations" + _timeout="" + which timeout >/dev/null && _timeout="timeout --foreground 1800" + $_timeout ./mtest/mtest $TEST_VS_MTEST | $VALGRIND_BIN $VALGRIND_OPTS ./mtest_opponent > valgrind_test.log 2> test_vs_mtest_err.log + retval=$? + head -n 5 valgrind_test.log + tail -n 2 valgrind_test.log + exit $retval +fi + for i in "${compilers[@]}" do if [ -z "$(which $i)" ] @@ -185,12 +374,20 @@ do echo "clang -mx32 tests skipped" continue fi - - _runtest "$i $a" "$CFLAGS" - [ "$WITH_LOW_MP" != "1" ] && continue - _runtest "$i $a" "-DMP_8BIT $CFLAGS" - _runtest "$i $a" "-DMP_16BIT $CFLAGS" - _runtest "$i $a" "-DMP_32BIT $CFLAGS" + if [[ "$VALGRIND_BIN" != "" ]] + then + _runvalgrind "$i $a" "$CFLAGS" + [ "$WITH_LOW_MP" != "1" ] && continue + _runvalgrind "$i $a" "-DMP_8BIT $CFLAGS" + _runvalgrind "$i $a" "-DMP_16BIT $CFLAGS" + _runvalgrind "$i $a" "-DMP_32BIT $CFLAGS" + else + _runtest "$i $a" "$CFLAGS" + [ "$WITH_LOW_MP" != "1" ] && continue + _runtest "$i $a" "-DMP_8BIT $CFLAGS" + _runtest "$i $a" "-DMP_16BIT $CFLAGS" + _runtest "$i $a" "-DMP_32BIT $CFLAGS" + fi done done diff --git a/libtommath/tombc/grammar.txt b/libtommath/tombc/grammar.txt deleted file mode 100644 index a780e75..0000000 --- a/libtommath/tombc/grammar.txt +++ /dev/null @@ -1,35 +0,0 @@ -program := program statement | statement | empty -statement := { statement } | - identifier = numexpression; | - identifier[numexpression] = numexpression; | - function(expressionlist); | - for (identifer = numexpression; numexpression; identifier = numexpression) { statement } | - while (numexpression) { statement } | - if (numexpresion) { statement } elif | - break; | - continue; - -elif := else statement | empty -function := abs | countbits | exptmod | jacobi | print | isprime | nextprime | issquare | readinteger | exit -expressionlist := expressionlist, expression | expression - -// LR(1) !!!? -expression := string | numexpression -numexpression := cmpexpr && cmpexpr | cmpexpr \|\| cmpexpr | cmpexpr -cmpexpr := boolexpr < boolexpr | boolexpr > boolexpr | boolexpr == boolexpr | - boolexpr <= boolexpr | boolexpr >= boolexpr | boolexpr -boolexpr := shiftexpr & shiftexpr | shiftexpr ^ shiftexpr | shiftexpr \| shiftexpr | shiftexpr -shiftexpr := addsubexpr << addsubexpr | addsubexpr >> addsubexpr | addsubexpr -addsubexpr := mulexpr + mulexpr | mulexpr - mulexpr | mulexpr -mulexpr := expr * expr | expr / expr | expr % expr | expr -expr := -nexpr | nexpr -nexpr := integer | identifier | ( numexpression ) | identifier[numexpression] - -identifier := identifer digits | identifier alpha | alpha -alpha := a ... z | A ... Z -integer := hexnumber | digits -hexnumber := 0xhexdigits -hexdigits := hexdigits hexdigit | hexdigit -hexdigit := 0 ... 9 | a ... f | A ... F -digits := digits digit | digit -digit := 0 ... 9 diff --git a/libtommath/tommath.h b/libtommath/tommath.h index 88ad122..e87bb08 100644 --- a/libtommath/tommath.h +++ b/libtommath/tommath.h @@ -1,31 +1,39 @@ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://math.libtomcrypt.com - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + #ifndef BN_H_ #define BN_H_ -#include <stdio.h> -#include <stdlib.h> #include <stdint.h> +#include <stddef.h> #include <limits.h> -#include "tommath_class.h" +#ifdef LTM_NO_FILE +# warning LTM_NO_FILE has been deprecated, use MP_NO_FILE. +# define MP_NO_FILE +#endif + +#ifndef MP_NO_FILE +# include <stdio.h> +#endif + +#ifdef MP_8BIT +# ifdef _MSC_VER +# pragma message("8-bit (MP_8BIT) support is deprecated and will be dropped completely in the next version.") +# else +# warning "8-bit (MP_8BIT) support is deprecated and will be dropped completely in the next version." +# endif +#endif #ifdef __cplusplus extern "C" { #endif +/* MS Visual C++ doesn't have a 128bit type for words, so fall back to 32bit MPI's (where words are 64bit) */ +#if (defined(_MSC_VER) || defined(__LLP64__) || defined(__e2k__) || defined(__LCC__)) && !defined(MP_64BIT) +# define MP_32BIT +#endif + /* detect 64-bit mode if possible */ #if defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) || \ defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) || \ @@ -33,224 +41,352 @@ extern "C" { defined(__sparcv9) || defined(__sparc_v9__) || defined(__sparc64__) || \ defined(__ia64) || defined(__ia64__) || defined(__itanium__) || defined(_M_IA64) || \ defined(__LP64__) || defined(_LP64) || defined(__64BIT__) - #if !(defined(MP_32BIT) || defined(MP_16BIT) || defined(MP_8BIT)) - #define MP_64BIT - #endif +# if !(defined(MP_64BIT) || defined(MP_32BIT) || defined(MP_16BIT) || defined(MP_8BIT)) +# if defined(__GNUC__) && !defined(__hppa) +/* we support 128bit integers only via: __attribute__((mode(TI))) */ +# define MP_64BIT +# else +/* otherwise we fall back to MP_32BIT even on 64bit platforms */ +# define MP_32BIT +# endif +# endif +#endif + +#ifdef MP_DIGIT_BIT +# error Defining MP_DIGIT_BIT is disallowed, use MP_8/16/31/32/64BIT #endif /* some default configurations. * - * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits - * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits + * A "mp_digit" must be able to hold MP_DIGIT_BIT + 1 bits + * A "mp_word" must be able to hold 2*MP_DIGIT_BIT + 1 bits * * At the very least a mp_digit must be able to hold 7 bits * [any size beyond that is ok provided it doesn't overflow the data type] */ + #ifdef MP_8BIT - typedef uint8_t mp_digit; - typedef uint16_t mp_word; -#define MP_SIZEOF_MP_DIGIT 1 -#ifdef DIGIT_BIT -#error You must not define DIGIT_BIT when using MP_8BIT -#endif +typedef uint8_t mp_digit; +typedef uint16_t private_mp_word; +# define MP_DIGIT_BIT 7 #elif defined(MP_16BIT) - typedef uint16_t mp_digit; - typedef uint32_t mp_word; -#define MP_SIZEOF_MP_DIGIT 2 -#ifdef DIGIT_BIT -#error You must not define DIGIT_BIT when using MP_16BIT -#endif +typedef uint16_t mp_digit; +typedef uint32_t private_mp_word; +# define MP_DIGIT_BIT 15 #elif defined(MP_64BIT) - /* for GCC only on supported platforms */ - typedef uint64_t mp_digit; -#if defined(_WIN32) - typedef unsigned __int128 mp_word; -#elif defined(__GNUC__) - typedef unsigned long mp_word __attribute__ ((mode(TI))); -#else - /* it seems you have a problem - * but we assume you can somewhere define your own uint128_t */ - typedef uint128_t mp_word; +/* for GCC only on supported platforms */ +typedef uint64_t mp_digit; +#if defined(__GNUC__) +typedef unsigned long private_mp_word __attribute__((mode(TI))); #endif - - #define DIGIT_BIT 60 +# define MP_DIGIT_BIT 60 #else - /* this is the default case, 28-bit digits */ - - /* this is to make porting into LibTomCrypt easier :-) */ - typedef uint32_t mp_digit; - typedef uint64_t mp_word; - -#ifdef MP_31BIT - /* this is an extension that uses 31-bit digits */ - #define DIGIT_BIT 31 -#else - /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */ - #define DIGIT_BIT 28 - #define MP_28BIT -#endif -#endif - -/* otherwise the bits per digit is calculated automatically from the size of a mp_digit */ -#ifndef DIGIT_BIT - #define DIGIT_BIT (((CHAR_BIT * MP_SIZEOF_MP_DIGIT) - 1)) /* bits per digit */ - typedef uint_least32_t mp_min_u32; -#else - typedef mp_digit mp_min_u32; +typedef uint32_t mp_digit; +typedef uint64_t private_mp_word; +# ifdef MP_31BIT +/* + * This is an extension that uses 31-bit digits. + * Please be aware that not all functions support this size, especially s_mp_mul_digs_fast + * will be reduced to work on small numbers only: + * Up to 8 limbs, 248 bits instead of up to 512 limbs, 15872 bits with MP_28BIT. + */ +# define MP_DIGIT_BIT 31 +# else +/* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */ +# define MP_DIGIT_BIT 28 +# define MP_28BIT +# endif #endif -/* use arc4random on platforms that support it */ -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) - #define MP_GEN_RANDOM() arc4random() - #define MP_GEN_RANDOM_MAX 0xffffffff -#endif +/* mp_word is a private type */ +#define mp_word MP_DEPRECATED_PRAGMA("mp_word has been made private") private_mp_word -/* use rand() as fall-back if there's no better rand function */ -#ifndef MP_GEN_RANDOM - #define MP_GEN_RANDOM() rand() - #define MP_GEN_RANDOM_MAX RAND_MAX -#endif +#define MP_SIZEOF_MP_DIGIT (MP_DEPRECATED_PRAGMA("MP_SIZEOF_MP_DIGIT has been deprecated, use sizeof (mp_digit)") sizeof (mp_digit)) -#define MP_DIGIT_BIT DIGIT_BIT -#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1)) +#define MP_MASK ((((mp_digit)1)<<((mp_digit)MP_DIGIT_BIT))-((mp_digit)1)) #define MP_DIGIT_MAX MP_MASK -/* equalities */ +/* Primality generation flags */ +#define MP_PRIME_BBS 0x0001 /* BBS style prime */ +#define MP_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */ +#define MP_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */ + +#define LTM_PRIME_BBS (MP_DEPRECATED_PRAGMA("LTM_PRIME_BBS has been deprecated, use MP_PRIME_BBS") MP_PRIME_BBS) +#define LTM_PRIME_SAFE (MP_DEPRECATED_PRAGMA("LTM_PRIME_SAFE has been deprecated, use MP_PRIME_SAFE") MP_PRIME_SAFE) +#define LTM_PRIME_2MSB_ON (MP_DEPRECATED_PRAGMA("LTM_PRIME_2MSB_ON has been deprecated, use MP_PRIME_2MSB_ON") MP_PRIME_2MSB_ON) + +#ifdef MP_USE_ENUMS +typedef enum { + MP_ZPOS = 0, /* positive */ + MP_NEG = 1 /* negative */ +} mp_sign; +typedef enum { + MP_LT = -1, /* less than */ + MP_EQ = 0, /* equal */ + MP_GT = 1 /* greater than */ +} mp_ord; +typedef enum { + MP_NO = 0, + MP_YES = 1 +} mp_bool; +typedef enum { + MP_OKAY = 0, /* no error */ + MP_ERR = -1, /* unknown error */ + MP_MEM = -2, /* out of mem */ + MP_VAL = -3, /* invalid input */ + MP_ITER = -4, /* maximum iterations reached */ + MP_BUF = -5 /* buffer overflow, supplied buffer too small */ +} mp_err; +typedef enum { + MP_LSB_FIRST = -1, + MP_MSB_FIRST = 1 +} mp_order; +typedef enum { + MP_LITTLE_ENDIAN = -1, + MP_NATIVE_ENDIAN = 0, + MP_BIG_ENDIAN = 1 +} mp_endian; +#else +typedef int mp_sign; +#define MP_ZPOS 0 /* positive integer */ +#define MP_NEG 1 /* negative */ +typedef int mp_ord; #define MP_LT -1 /* less than */ #define MP_EQ 0 /* equal to */ #define MP_GT 1 /* greater than */ - -#define MP_ZPOS 0 /* positive integer */ -#define MP_NEG 1 /* negative */ - -#define MP_OKAY 0 /* ok result */ +typedef int mp_bool; +#define MP_YES 1 +#define MP_NO 0 +typedef int mp_err; +#define MP_OKAY 0 /* no error */ +#define MP_ERR -1 /* unknown error */ #define MP_MEM -2 /* out of mem */ #define MP_VAL -3 /* invalid input */ -#define MP_RANGE MP_VAL - -#define MP_YES 1 /* yes response */ -#define MP_NO 0 /* no response */ - -/* Primality generation flags */ -#define LTM_PRIME_BBS 0x0001 /* BBS style prime */ -#define LTM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */ -#define LTM_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */ +#define MP_RANGE (MP_DEPRECATED_PRAGMA("MP_RANGE has been deprecated in favor of MP_VAL") MP_VAL) +#define MP_ITER -4 /* maximum iterations reached */ +#define MP_BUF -5 /* buffer overflow, supplied buffer too small */ +typedef int mp_order; +#define MP_LSB_FIRST -1 +#define MP_MSB_FIRST 1 +typedef int mp_endian; +#define MP_LITTLE_ENDIAN -1 +#define MP_NATIVE_ENDIAN 0 +#define MP_BIG_ENDIAN 1 +#endif -typedef int mp_err; +/* tunable cutoffs */ -/* you'll have to tune these... */ -extern int KARATSUBA_MUL_CUTOFF, - KARATSUBA_SQR_CUTOFF, - TOOM_MUL_CUTOFF, - TOOM_SQR_CUTOFF; +#ifndef MP_FIXED_CUTOFFS +extern int +KARATSUBA_MUL_CUTOFF, +KARATSUBA_SQR_CUTOFF, +TOOM_MUL_CUTOFF, +TOOM_SQR_CUTOFF; +#endif /* define this to use lower memory usage routines (exptmods mostly) */ /* #define MP_LOW_MEM */ /* default precision */ #ifndef MP_PREC - #ifndef MP_LOW_MEM - #define MP_PREC 32 /* default digits of precision */ - #else - #define MP_PREC 8 /* default digits of precision */ - #endif +# ifndef MP_LOW_MEM +# define PRIVATE_MP_PREC 32 /* default digits of precision */ +# elif defined(MP_8BIT) +# define PRIVATE_MP_PREC 16 /* default digits of precision */ +# else +# define PRIVATE_MP_PREC 8 /* default digits of precision */ +# endif +# define MP_PREC (MP_DEPRECATED_PRAGMA("MP_PREC is an internal macro") PRIVATE_MP_PREC) #endif /* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */ -#define MP_WARRAY (1 << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) + 1)) +#define PRIVATE_MP_WARRAY (int)(1uLL << (((CHAR_BIT * sizeof(private_mp_word)) - (2 * MP_DIGIT_BIT)) + 1)) +#define MP_WARRAY (MP_DEPRECATED_PRAGMA("MP_WARRAY is an internal macro") PRIVATE_MP_WARRAY) + +#if defined(__GNUC__) && __GNUC__ >= 4 +# define MP_NULL_TERMINATED __attribute__((sentinel)) +#else +# define MP_NULL_TERMINATED +#endif + +/* + * MP_WUR - warn unused result + * --------------------------- + * + * The result of functions annotated with MP_WUR must be + * checked and cannot be ignored. + * + * Most functions in libtommath return an error code. + * This error code must be checked in order to prevent crashes or invalid + * results. + * + * If you still want to avoid the error checks for quick and dirty programs + * without robustness guarantees, you can `#define MP_WUR` before including + * tommath.h, disabling the warnings. + */ +#ifndef MP_WUR +# if defined(__GNUC__) && __GNUC__ >= 4 +# define MP_WUR __attribute__((warn_unused_result)) +# else +# define MP_WUR +# endif +#endif + +#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 405) +# define MP_DEPRECATED(x) __attribute__((deprecated("replaced by " #x))) +# define PRIVATE_MP_DEPRECATED_PRAGMA(s) _Pragma(#s) +# define MP_DEPRECATED_PRAGMA(s) PRIVATE_MP_DEPRECATED_PRAGMA(GCC warning s) +#elif defined(_MSC_VER) && _MSC_VER >= 1500 +# define MP_DEPRECATED(x) __declspec(deprecated("replaced by " #x)) +# define MP_DEPRECATED_PRAGMA(s) __pragma(message(s)) +#else +# define MP_DEPRECATED(s) +# define MP_DEPRECATED_PRAGMA(s) +#endif + +#define DIGIT_BIT (MP_DEPRECATED_PRAGMA("DIGIT_BIT macro is deprecated, MP_DIGIT_BIT instead") MP_DIGIT_BIT) +#define USED(m) (MP_DEPRECATED_PRAGMA("USED macro is deprecated, use z->used instead") (m)->used) +#define DIGIT(m, k) (MP_DEPRECATED_PRAGMA("DIGIT macro is deprecated, use z->dp instead") (m)->dp[(k)]) +#define SIGN(m) (MP_DEPRECATED_PRAGMA("SIGN macro is deprecated, use z->sign instead") (m)->sign) /* the infamous mp_int structure */ typedef struct { - int used, alloc, sign; - mp_digit *dp; + int used, alloc; + mp_sign sign; + mp_digit *dp; } mp_int; /* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */ -typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat); - - -#define USED(m) ((m)->used) -#define DIGIT(m,k) ((m)->dp[(k)]) -#define SIGN(m) ((m)->sign) +typedef int private_mp_prime_callback(unsigned char *dst, int len, void *dat); +typedef private_mp_prime_callback MP_DEPRECATED(mp_rand_source) ltm_prime_callback; /* error code to char* string */ -const char *mp_error_to_string(int code); +const char *mp_error_to_string(mp_err code) MP_WUR; /* ---> init and deinit bignum functions <--- */ /* init a bignum */ -int mp_init(mp_int *a); +mp_err mp_init(mp_int *a) MP_WUR; /* free a bignum */ void mp_clear(mp_int *a); /* init a null terminated series of arguments */ -int mp_init_multi(mp_int *mp, ...); +mp_err mp_init_multi(mp_int *mp, ...) MP_NULL_TERMINATED MP_WUR; /* clear a null terminated series of arguments */ -void mp_clear_multi(mp_int *mp, ...); +void mp_clear_multi(mp_int *mp, ...) MP_NULL_TERMINATED; /* exchange two ints */ void mp_exch(mp_int *a, mp_int *b); /* shrink ram required for a bignum */ -int mp_shrink(mp_int *a); +mp_err mp_shrink(mp_int *a) MP_WUR; /* grow an int to a given size */ -int mp_grow(mp_int *a, int size); +mp_err mp_grow(mp_int *a, int size) MP_WUR; /* init to a given number of digits */ -int mp_init_size(mp_int *a, int size); +mp_err mp_init_size(mp_int *a, int size) MP_WUR; /* ---> Basic Manipulations <--- */ #define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO) -#define mp_iseven(a) ((((a)->used > 0) && (((a)->dp[0] & 1u) == 0u)) ? MP_YES : MP_NO) -#define mp_isodd(a) ((((a)->used > 0) && (((a)->dp[0] & 1u) == 1u)) ? MP_YES : MP_NO) +mp_bool mp_iseven(const mp_int *a) MP_WUR; +mp_bool mp_isodd(const mp_int *a) MP_WUR; #define mp_isneg(a) (((a)->sign != MP_ZPOS) ? MP_YES : MP_NO) /* set to zero */ void mp_zero(mp_int *a); -/* set to a digit */ +/* get and set doubles */ +double mp_get_double(const mp_int *a) MP_WUR; +mp_err mp_set_double(mp_int *a, double b) MP_WUR; + +/* get integer, set integer and init with integer (int32_t) */ +int32_t mp_get_i32(const mp_int *a) MP_WUR; +void mp_set_i32(mp_int *a, int32_t b); +mp_err mp_init_i32(mp_int *a, int32_t b) MP_WUR; + +/* get integer, set integer and init with integer, behaves like two complement for negative numbers (uint32_t) */ +#define mp_get_u32(a) ((uint32_t)mp_get_i32(a)) +void mp_set_u32(mp_int *a, uint32_t b); +mp_err mp_init_u32(mp_int *a, uint32_t b) MP_WUR; + +/* get integer, set integer and init with integer (int64_t) */ +int64_t mp_get_i64(const mp_int *a) MP_WUR; +void mp_set_i64(mp_int *a, int64_t b); +mp_err mp_init_i64(mp_int *a, int64_t b) MP_WUR; + +/* get integer, set integer and init with integer, behaves like two complement for negative numbers (uint64_t) */ +#define mp_get_u64(a) ((uint64_t)mp_get_i64(a)) +void mp_set_u64(mp_int *a, uint64_t b); +mp_err mp_init_u64(mp_int *a, uint64_t b) MP_WUR; + +/* get magnitude */ +uint32_t mp_get_mag_u32(const mp_int *a) MP_WUR; +uint64_t mp_get_mag_u64(const mp_int *a) MP_WUR; +unsigned long mp_get_mag_ul(const mp_int *a) MP_WUR; +unsigned long long mp_get_mag_ull(const mp_int *a) MP_WUR; + +/* get integer, set integer (long) */ +long mp_get_l(const mp_int *a) MP_WUR; +void mp_set_l(mp_int *a, long b); +mp_err mp_init_l(mp_int *a, long b) MP_WUR; + +/* get integer, set integer (unsigned long) */ +#define mp_get_ul(a) ((unsigned long)mp_get_l(a)) +void mp_set_ul(mp_int *a, unsigned long b); +mp_err mp_init_ul(mp_int *a, unsigned long b) MP_WUR; + +/* get integer, set integer (long long) */ +long long mp_get_ll(const mp_int *a) MP_WUR; +void mp_set_ll(mp_int *a, long long b); +mp_err mp_init_ll(mp_int *a, long long b) MP_WUR; + +/* get integer, set integer (unsigned long long) */ +#define mp_get_ull(a) ((unsigned long long)mp_get_ll(a)) +void mp_set_ull(mp_int *a, unsigned long long b); +mp_err mp_init_ull(mp_int *a, unsigned long long b) MP_WUR; + +/* set to single unsigned digit, up to MP_DIGIT_MAX */ void mp_set(mp_int *a, mp_digit b); +mp_err mp_init_set(mp_int *a, mp_digit b) MP_WUR; -/* set a 32-bit const */ -int mp_set_int(mp_int *a, unsigned long b); - -/* set a platform dependent unsigned long value */ -int mp_set_long(mp_int *a, unsigned long b); - -/* set a platform dependent unsigned long long value */ -int mp_set_long_long(mp_int *a, unsigned long long b); - -/* get a 32-bit value */ -unsigned long mp_get_int(mp_int * a); - -/* get a platform dependent unsigned long value */ -unsigned long mp_get_long(mp_int * a); - -/* get a platform dependent unsigned long long value */ -unsigned long long mp_get_long_long(mp_int * a); - -/* initialize and set a digit */ -int mp_init_set (mp_int * a, mp_digit b); - -/* initialize and set 32-bit value */ -int mp_init_set_int (mp_int * a, unsigned long b); +/* get integer, set integer and init with integer (deprecated) */ +MP_DEPRECATED(mp_get_mag_u32/mp_get_u32) unsigned long mp_get_int(const mp_int *a) MP_WUR; +MP_DEPRECATED(mp_get_mag_ul/mp_get_ul) unsigned long mp_get_long(const mp_int *a) MP_WUR; +MP_DEPRECATED(mp_get_mag_ull/mp_get_ull) unsigned long long mp_get_long_long(const mp_int *a) MP_WUR; +MP_DEPRECATED(mp_set_ul) mp_err mp_set_int(mp_int *a, unsigned long b); +MP_DEPRECATED(mp_set_ul) mp_err mp_set_long(mp_int *a, unsigned long b); +MP_DEPRECATED(mp_set_ull) mp_err mp_set_long_long(mp_int *a, unsigned long long b); +MP_DEPRECATED(mp_init_ul) mp_err mp_init_set_int(mp_int *a, unsigned long b) MP_WUR; /* copy, b = a */ -int mp_copy(mp_int *a, mp_int *b); +mp_err mp_copy(const mp_int *a, mp_int *b) MP_WUR; /* inits and copies, a = b */ -int mp_init_copy(mp_int *a, mp_int *b); +mp_err mp_init_copy(mp_int *a, const mp_int *b) MP_WUR; /* trim unused digits */ void mp_clamp(mp_int *a); -/* import binary data */ -int mp_import(mp_int* rop, size_t count, int order, size_t size, int endian, size_t nails, const void* op); /* export binary data */ -int mp_export(void* rop, size_t* countp, int order, size_t size, int endian, size_t nails, mp_int* op); +MP_DEPRECATED(mp_pack) mp_err mp_export(void *rop, size_t *countp, int order, size_t size, + int endian, size_t nails, const mp_int *op) MP_WUR; + +/* import binary data */ +MP_DEPRECATED(mp_unpack) mp_err mp_import(mp_int *rop, size_t count, int order, + size_t size, int endian, size_t nails, + const void *op) MP_WUR; + +/* unpack binary data */ +mp_err mp_unpack(mp_int *rop, size_t count, mp_order order, size_t size, mp_endian endian, + size_t nails, const void *op) MP_WUR; + +/* pack binary data */ +size_t mp_pack_count(const mp_int *a, size_t nails, size_t size) MP_WUR; +mp_err mp_pack(void *rop, size_t maxcount, size_t *written, mp_order order, size_t size, + mp_endian endian, size_t nails, const mp_int *op) MP_WUR; /* ---> digit manipulation <--- */ @@ -258,244 +394,299 @@ int mp_export(void* rop, size_t* countp, int order, size_t size, int endian, siz void mp_rshd(mp_int *a, int b); /* left shift by "b" digits */ -int mp_lshd(mp_int *a, int b); +mp_err mp_lshd(mp_int *a, int b) MP_WUR; /* c = a / 2**b, implemented as c = a >> b */ -int mp_div_2d(mp_int *a, int b, mp_int *c, mp_int *d); +mp_err mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d) MP_WUR; /* b = a/2 */ -int mp_div_2(mp_int *a, mp_int *b); +mp_err mp_div_2(const mp_int *a, mp_int *b) MP_WUR; + +/* a/3 => 3c + d == a */ +mp_err mp_div_3(const mp_int *a, mp_int *c, mp_digit *d) MP_WUR; /* c = a * 2**b, implemented as c = a << b */ -int mp_mul_2d(mp_int *a, int b, mp_int *c); +mp_err mp_mul_2d(const mp_int *a, int b, mp_int *c) MP_WUR; /* b = a*2 */ -int mp_mul_2(mp_int *a, mp_int *b); +mp_err mp_mul_2(const mp_int *a, mp_int *b) MP_WUR; /* c = a mod 2**b */ -int mp_mod_2d(mp_int *a, int b, mp_int *c); +mp_err mp_mod_2d(const mp_int *a, int b, mp_int *c) MP_WUR; /* computes a = 2**b */ -int mp_2expt(mp_int *a, int b); +mp_err mp_2expt(mp_int *a, int b) MP_WUR; /* Counts the number of lsbs which are zero before the first zero bit */ -int mp_cnt_lsb(mp_int *a); +int mp_cnt_lsb(const mp_int *a) MP_WUR; /* I Love Earth! */ -/* makes a pseudo-random int of a given size */ -int mp_rand(mp_int *a, int digits); +/* makes a pseudo-random mp_int of a given size */ +mp_err mp_rand(mp_int *a, int digits) MP_WUR; +/* makes a pseudo-random small int of a given size */ +MP_DEPRECATED(mp_rand) mp_err mp_rand_digit(mp_digit *r) MP_WUR; +/* use custom random data source instead of source provided the platform */ +void mp_rand_source(mp_err(*source)(void *out, size_t size)); + +#ifdef MP_PRNG_ENABLE_LTM_RNG +# warning MP_PRNG_ENABLE_LTM_RNG has been deprecated, use mp_rand_source instead. +/* A last resort to provide random data on systems without any of the other + * implemented ways to gather entropy. + * It is compatible with `rng_get_bytes()` from libtomcrypt so you could + * provide that one and then set `ltm_rng = rng_get_bytes;` */ +extern unsigned long (*ltm_rng)(unsigned char *out, unsigned long outlen, void (*callback)(void)); +extern void (*ltm_rng_callback)(void); +#endif /* ---> binary operations <--- */ -/* c = a XOR b */ -int mp_xor(mp_int *a, mp_int *b, mp_int *c); -/* c = a OR b */ -int mp_or(mp_int *a, mp_int *b, mp_int *c); +/* Checks the bit at position b and returns MP_YES + * if the bit is 1, MP_NO if it is 0 and MP_VAL + * in case of error + */ +MP_DEPRECATED(s_mp_get_bit) int mp_get_bit(const mp_int *a, int b) MP_WUR; + +/* c = a XOR b (two complement) */ +MP_DEPRECATED(mp_xor) mp_err mp_tc_xor(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; +mp_err mp_xor(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; + +/* c = a OR b (two complement) */ +MP_DEPRECATED(mp_or) mp_err mp_tc_or(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; +mp_err mp_or(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; + +/* c = a AND b (two complement) */ +MP_DEPRECATED(mp_and) mp_err mp_tc_and(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; +mp_err mp_and(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; + +/* b = ~a (bitwise not, two complement) */ +mp_err mp_complement(const mp_int *a, mp_int *b) MP_WUR; -/* c = a AND b */ -int mp_and(mp_int *a, mp_int *b, mp_int *c); +/* right shift with sign extension */ +MP_DEPRECATED(mp_signed_rsh) mp_err mp_tc_div_2d(const mp_int *a, int b, mp_int *c) MP_WUR; +mp_err mp_signed_rsh(const mp_int *a, int b, mp_int *c) MP_WUR; /* ---> Basic arithmetic <--- */ /* b = -a */ -int mp_neg(mp_int *a, mp_int *b); +mp_err mp_neg(const mp_int *a, mp_int *b) MP_WUR; /* b = |a| */ -int mp_abs(mp_int *a, mp_int *b); +mp_err mp_abs(const mp_int *a, mp_int *b) MP_WUR; /* compare a to b */ -int mp_cmp(mp_int *a, mp_int *b); +mp_ord mp_cmp(const mp_int *a, const mp_int *b) MP_WUR; /* compare |a| to |b| */ -int mp_cmp_mag(mp_int *a, mp_int *b); +mp_ord mp_cmp_mag(const mp_int *a, const mp_int *b) MP_WUR; /* c = a + b */ -int mp_add(mp_int *a, mp_int *b, mp_int *c); +mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; /* c = a - b */ -int mp_sub(mp_int *a, mp_int *b, mp_int *c); +mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; /* c = a * b */ -int mp_mul(mp_int *a, mp_int *b, mp_int *c); +mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; /* b = a*a */ -int mp_sqr(mp_int *a, mp_int *b); +mp_err mp_sqr(const mp_int *a, mp_int *b) MP_WUR; /* a/b => cb + d == a */ -int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d); +mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) MP_WUR; /* c = a mod b, 0 <= c < b */ -int mp_mod(mp_int *a, mp_int *b, mp_int *c); +mp_err mp_mod(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; + +/* Increment "a" by one like "a++". Changes input! */ +mp_err mp_incr(mp_int *a) MP_WUR; + +/* Decrement "a" by one like "a--". Changes input! */ +mp_err mp_decr(mp_int *a) MP_WUR; /* ---> single digit functions <--- */ /* compare against a single digit */ -int mp_cmp_d(mp_int *a, mp_digit b); +mp_ord mp_cmp_d(const mp_int *a, mp_digit b) MP_WUR; /* c = a + b */ -int mp_add_d(mp_int *a, mp_digit b, mp_int *c); +mp_err mp_add_d(const mp_int *a, mp_digit b, mp_int *c) MP_WUR; /* c = a - b */ -int mp_sub_d(mp_int *a, mp_digit b, mp_int *c); +mp_err mp_sub_d(const mp_int *a, mp_digit b, mp_int *c) MP_WUR; /* c = a * b */ -int mp_mul_d(mp_int *a, mp_digit b, mp_int *c); +mp_err mp_mul_d(const mp_int *a, mp_digit b, mp_int *c) MP_WUR; /* a/b => cb + d == a */ -int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d); - -/* a/3 => 3c + d == a */ -int mp_div_3(mp_int *a, mp_int *c, mp_digit *d); - -/* c = a**b */ -int mp_expt_d(mp_int *a, mp_digit b, mp_int *c); -int mp_expt_d_ex (mp_int * a, mp_digit b, mp_int * c, int fast); +mp_err mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d) MP_WUR; /* c = a mod b, 0 <= c < b */ -int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c); +mp_err mp_mod_d(const mp_int *a, mp_digit b, mp_digit *c) MP_WUR; /* ---> number theory <--- */ /* d = a + b (mod c) */ -int mp_addmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); +mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d) MP_WUR; /* d = a - b (mod c) */ -int mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); +mp_err mp_submod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d) MP_WUR; /* d = a * b (mod c) */ -int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); +mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d) MP_WUR; /* c = a * a (mod b) */ -int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c); +mp_err mp_sqrmod(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; /* c = 1/a (mod b) */ -int mp_invmod(mp_int *a, mp_int *b, mp_int *c); +mp_err mp_invmod(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; /* c = (a, b) */ -int mp_gcd(mp_int *a, mp_int *b, mp_int *c); +mp_err mp_gcd(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; /* produces value such that U1*a + U2*b = U3 */ -int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3); +mp_err mp_exteuclid(const mp_int *a, const mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3) MP_WUR; /* c = [a, b] or (a*b)/(a, b) */ -int mp_lcm(mp_int *a, mp_int *b, mp_int *c); +mp_err mp_lcm(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; /* finds one of the b'th root of a, such that |c|**b <= |a| * * returns error if a < 0 and b is even */ -int mp_n_root(mp_int *a, mp_digit b, mp_int *c); -int mp_n_root_ex (mp_int * a, mp_digit b, mp_int * c, int fast); +mp_err mp_root_u32(const mp_int *a, uint32_t b, mp_int *c) MP_WUR; +MP_DEPRECATED(mp_root_u32) mp_err mp_n_root(const mp_int *a, mp_digit b, mp_int *c) MP_WUR; +MP_DEPRECATED(mp_root_u32) mp_err mp_n_root_ex(const mp_int *a, mp_digit b, mp_int *c, int fast) MP_WUR; /* special sqrt algo */ -int mp_sqrt(mp_int *arg, mp_int *ret); +mp_err mp_sqrt(const mp_int *arg, mp_int *ret) MP_WUR; /* special sqrt (mod prime) */ -int mp_sqrtmod_prime(mp_int *arg, mp_int *prime, mp_int *ret); +mp_err mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret) MP_WUR; /* is number a square? */ -int mp_is_square(mp_int *arg, int *ret); +mp_err mp_is_square(const mp_int *arg, mp_bool *ret) MP_WUR; /* computes the jacobi c = (a | n) (or Legendre if b is prime) */ -int mp_jacobi(mp_int *a, mp_int *n, int *c); +MP_DEPRECATED(mp_kronecker) mp_err mp_jacobi(const mp_int *a, const mp_int *n, int *c) MP_WUR; + +/* computes the Kronecker symbol c = (a | p) (like jacobi() but with {a,p} in Z */ +mp_err mp_kronecker(const mp_int *a, const mp_int *p, int *c) MP_WUR; /* used to setup the Barrett reduction for a given modulus b */ -int mp_reduce_setup(mp_int *a, mp_int *b); +mp_err mp_reduce_setup(mp_int *a, const mp_int *b) MP_WUR; /* Barrett Reduction, computes a (mod b) with a precomputed value c * - * Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely - * compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code]. + * Assumes that 0 < x <= m*m, note if 0 > x > -(m*m) then you can merely + * compute the reduction as -1 * mp_reduce(mp_abs(x)) [pseudo code]. */ -int mp_reduce(mp_int *a, mp_int *b, mp_int *c); +mp_err mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu) MP_WUR; /* setups the montgomery reduction */ -int mp_montgomery_setup(mp_int *a, mp_digit *mp); +mp_err mp_montgomery_setup(const mp_int *n, mp_digit *rho) MP_WUR; /* computes a = B**n mod b without division or multiplication useful for * normalizing numbers in a Montgomery system. */ -int mp_montgomery_calc_normalization(mp_int *a, mp_int *b); +mp_err mp_montgomery_calc_normalization(mp_int *a, const mp_int *b) MP_WUR; /* computes x/R == x (mod N) via Montgomery Reduction */ -int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp); +mp_err mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho) MP_WUR; /* returns 1 if a is a valid DR modulus */ -int mp_dr_is_modulus(mp_int *a); +mp_bool mp_dr_is_modulus(const mp_int *a) MP_WUR; /* sets the value of "d" required for mp_dr_reduce */ -void mp_dr_setup(mp_int *a, mp_digit *d); +void mp_dr_setup(const mp_int *a, mp_digit *d); -/* reduces a modulo b using the Diminished Radix method */ -int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp); +/* reduces a modulo n using the Diminished Radix method */ +mp_err mp_dr_reduce(mp_int *x, const mp_int *n, mp_digit k) MP_WUR; /* returns true if a can be reduced with mp_reduce_2k */ -int mp_reduce_is_2k(mp_int *a); +mp_bool mp_reduce_is_2k(const mp_int *a) MP_WUR; /* determines k value for 2k reduction */ -int mp_reduce_2k_setup(mp_int *a, mp_digit *d); +mp_err mp_reduce_2k_setup(const mp_int *a, mp_digit *d) MP_WUR; /* reduces a modulo b where b is of the form 2**p - k [0 <= a] */ -int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d); +mp_err mp_reduce_2k(mp_int *a, const mp_int *n, mp_digit d) MP_WUR; /* returns true if a can be reduced with mp_reduce_2k_l */ -int mp_reduce_is_2k_l(mp_int *a); +mp_bool mp_reduce_is_2k_l(const mp_int *a) MP_WUR; /* determines k value for 2k reduction */ -int mp_reduce_2k_setup_l(mp_int *a, mp_int *d); +mp_err mp_reduce_2k_setup_l(const mp_int *a, mp_int *d) MP_WUR; /* reduces a modulo b where b is of the form 2**p - k [0 <= a] */ -int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d); +mp_err mp_reduce_2k_l(mp_int *a, const mp_int *n, const mp_int *d) MP_WUR; -/* d = a**b (mod c) */ -int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); +/* Y = G**X (mod P) */ +mp_err mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y) MP_WUR; /* ---> Primes <--- */ /* number of primes */ #ifdef MP_8BIT - #define PRIME_SIZE 31 +# define PRIVATE_MP_PRIME_TAB_SIZE 31 #else - #define PRIME_SIZE 256 +# define PRIVATE_MP_PRIME_TAB_SIZE 256 #endif +#define PRIME_SIZE (MP_DEPRECATED_PRAGMA("PRIME_SIZE has been made internal") PRIVATE_MP_PRIME_TAB_SIZE) /* table of first PRIME_SIZE primes */ -extern const mp_digit ltm_prime_tab[PRIME_SIZE]; +MP_DEPRECATED(internal) extern const mp_digit ltm_prime_tab[PRIVATE_MP_PRIME_TAB_SIZE]; /* result=1 if a is divisible by one of the first PRIME_SIZE primes */ -int mp_prime_is_divisible(mp_int *a, int *result); +MP_DEPRECATED(mp_prime_is_prime) mp_err mp_prime_is_divisible(const mp_int *a, mp_bool *result) MP_WUR; /* performs one Fermat test of "a" using base "b". * Sets result to 0 if composite or 1 if probable prime */ -int mp_prime_fermat(mp_int *a, mp_int *b, int *result); +mp_err mp_prime_fermat(const mp_int *a, const mp_int *b, mp_bool *result) MP_WUR; /* performs one Miller-Rabin test of "a" using base "b". * Sets result to 0 if composite or 1 if probable prime */ -int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result); +mp_err mp_prime_miller_rabin(const mp_int *a, const mp_int *b, mp_bool *result) MP_WUR; /* This gives [for a given bit size] the number of trials required * such that Miller-Rabin gives a prob of failure lower than 2^-96 */ -int mp_prime_rabin_miller_trials(int size); +int mp_prime_rabin_miller_trials(int size) MP_WUR; + +/* performs one strong Lucas-Selfridge test of "a". + * Sets result to 0 if composite or 1 if probable prime + */ +mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result) MP_WUR; + +/* performs one Frobenius test of "a" as described by Paul Underwood. + * Sets result to 0 if composite or 1 if probable prime + */ +mp_err mp_prime_frobenius_underwood(const mp_int *N, mp_bool *result) MP_WUR; -/* performs t rounds of Miller-Rabin on "a" using the first - * t prime bases. Also performs an initial sieve of trial +/* performs t random rounds of Miller-Rabin on "a" additional to + * bases 2 and 3. Also performs an initial sieve of trial * division. Determines if "a" is prime with probability * of error no more than (1/4)**t. + * Both a strong Lucas-Selfridge to complete the BPSW test + * and a separate Frobenius test are available at compile time. + * With t<0 a deterministic test is run for primes up to + * 318665857834031151167461. With t<13 (abs(t)-13) additional + * tests with sequential small primes are run starting at 43. + * Is Fips 186.4 compliant if called with t as computed by + * mp_prime_rabin_miller_trials(); * * Sets result to 1 if probably prime, 0 otherwise */ -int mp_prime_is_prime(mp_int *a, int t, int *result); +mp_err mp_prime_is_prime(const mp_int *a, int t, mp_bool *result) MP_WUR; /* finds the next prime after the number "a" using "t" trials * of Miller-Rabin. * * bbs_style = 1 means the prime must be congruent to 3 mod 4 */ -int mp_prime_next_prime(mp_int *a, int t, int bbs_style); +mp_err mp_prime_next_prime(mp_int *a, int t, int bbs_style) MP_WUR; /* makes a truly random prime of a given size (bytes), * call with bbs = 1 if you want it to be congruent to 3 mod 4 @@ -506,65 +697,85 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style); * * The prime generated will be larger than 2^(8*size). */ -#define mp_prime_random(a, t, size, bbs, cb, dat) mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat) +#define mp_prime_random(a, t, size, bbs, cb, dat) (MP_DEPRECATED_PRAGMA("mp_prime_random has been deprecated, use mp_prime_rand instead") mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?MP_PRIME_BBS:0, cb, dat)) /* makes a truly random prime of a given size (bits), * * Flags are as follows: * - * LTM_PRIME_BBS - make prime congruent to 3 mod 4 - * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS) - * LTM_PRIME_2MSB_ON - make the 2nd highest bit one + * MP_PRIME_BBS - make prime congruent to 3 mod 4 + * MP_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies MP_PRIME_BBS) + * MP_PRIME_2MSB_ON - make the 2nd highest bit one * * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself * so it can be NULL * */ -int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat); +MP_DEPRECATED(mp_prime_rand) mp_err mp_prime_random_ex(mp_int *a, int t, int size, int flags, + private_mp_prime_callback cb, void *dat) MP_WUR; +mp_err mp_prime_rand(mp_int *a, int t, int size, int flags) MP_WUR; + +/* Integer logarithm to integer base */ +mp_err mp_log_u32(const mp_int *a, uint32_t base, uint32_t *c) MP_WUR; + +/* c = a**b */ +mp_err mp_expt_u32(const mp_int *a, uint32_t b, mp_int *c) MP_WUR; +MP_DEPRECATED(mp_expt_u32) mp_err mp_expt_d(const mp_int *a, mp_digit b, mp_int *c) MP_WUR; +MP_DEPRECATED(mp_expt_u32) mp_err mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast) MP_WUR; /* ---> radix conversion <--- */ -int mp_count_bits(mp_int *a); - -int mp_unsigned_bin_size(mp_int *a); -int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c); -int mp_to_unsigned_bin(mp_int *a, unsigned char *b); -int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen); - -int mp_signed_bin_size(mp_int *a); -int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c); -int mp_to_signed_bin(mp_int *a, unsigned char *b); -int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen); - -int mp_read_radix(mp_int *a, const char *str, int radix); -int mp_toradix(mp_int *a, char *str, int radix); -int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen); -int mp_radix_size(mp_int *a, int radix, int *size); - -#ifndef LTM_NO_FILE -int mp_fread(mp_int *a, int radix, FILE *stream); -int mp_fwrite(mp_int *a, int radix, FILE *stream); +int mp_count_bits(const mp_int *a) MP_WUR; + + +MP_DEPRECATED(mp_ubin_size) int mp_unsigned_bin_size(const mp_int *a) MP_WUR; +MP_DEPRECATED(mp_from_ubin) mp_err mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c) MP_WUR; +MP_DEPRECATED(mp_to_ubin) mp_err mp_to_unsigned_bin(const mp_int *a, unsigned char *b) MP_WUR; +MP_DEPRECATED(mp_to_ubin) mp_err mp_to_unsigned_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen) MP_WUR; + +MP_DEPRECATED(mp_sbin_size) int mp_signed_bin_size(const mp_int *a) MP_WUR; +MP_DEPRECATED(mp_from_sbin) mp_err mp_read_signed_bin(mp_int *a, const unsigned char *b, int c) MP_WUR; +MP_DEPRECATED(mp_to_sbin) mp_err mp_to_signed_bin(const mp_int *a, unsigned char *b) MP_WUR; +MP_DEPRECATED(mp_to_sbin) mp_err mp_to_signed_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen) MP_WUR; + +size_t mp_ubin_size(const mp_int *a) MP_WUR; +mp_err mp_from_ubin(mp_int *a, const unsigned char *buf, size_t size) MP_WUR; +mp_err mp_to_ubin(const mp_int *a, unsigned char *buf, size_t maxlen, size_t *written) MP_WUR; + +size_t mp_sbin_size(const mp_int *a) MP_WUR; +mp_err mp_from_sbin(mp_int *a, const unsigned char *buf, size_t size) MP_WUR; +mp_err mp_to_sbin(const mp_int *a, unsigned char *buf, size_t maxlen, size_t *written) MP_WUR; + +mp_err mp_read_radix(mp_int *a, const char *str, int radix) MP_WUR; +MP_DEPRECATED(mp_to_radix) mp_err mp_toradix(const mp_int *a, char *str, int radix) MP_WUR; +MP_DEPRECATED(mp_to_radix) mp_err mp_toradix_n(const mp_int *a, char *str, int radix, int maxlen) MP_WUR; +mp_err mp_to_radix(const mp_int *a, char *str, size_t maxlen, size_t *written, int radix) MP_WUR; +mp_err mp_radix_size(const mp_int *a, int radix, int *size) MP_WUR; + +#ifndef MP_NO_FILE +mp_err mp_fread(mp_int *a, int radix, FILE *stream) MP_WUR; +mp_err mp_fwrite(const mp_int *a, int radix, FILE *stream) MP_WUR; #endif -#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len)) -#define mp_raw_size(mp) mp_signed_bin_size(mp) -#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str)) -#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len)) -#define mp_mag_size(mp) mp_unsigned_bin_size(mp) -#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str)) +#define mp_read_raw(mp, str, len) (MP_DEPRECATED_PRAGMA("replaced by mp_read_signed_bin") mp_read_signed_bin((mp), (str), (len))) +#define mp_raw_size(mp) (MP_DEPRECATED_PRAGMA("replaced by mp_signed_bin_size") mp_signed_bin_size(mp)) +#define mp_toraw(mp, str) (MP_DEPRECATED_PRAGMA("replaced by mp_to_signed_bin") mp_to_signed_bin((mp), (str))) +#define mp_read_mag(mp, str, len) (MP_DEPRECATED_PRAGMA("replaced by mp_read_unsigned_bin") mp_read_unsigned_bin((mp), (str), (len)) +#define mp_mag_size(mp) (MP_DEPRECATED_PRAGMA("replaced by mp_unsigned_bin_size") mp_unsigned_bin_size(mp)) +#define mp_tomag(mp, str) (MP_DEPRECATED_PRAGMA("replaced by mp_to_unsigned_bin") mp_to_unsigned_bin((mp), (str))) -#define mp_tobinary(M, S) mp_toradix((M), (S), 2) -#define mp_tooctal(M, S) mp_toradix((M), (S), 8) -#define mp_todecimal(M, S) mp_toradix((M), (S), 10) -#define mp_tohex(M, S) mp_toradix((M), (S), 16) +#define mp_tobinary(M, S) (MP_DEPRECATED_PRAGMA("replaced by mp_to_binary") mp_toradix((M), (S), 2)) +#define mp_tooctal(M, S) (MP_DEPRECATED_PRAGMA("replaced by mp_to_octal") mp_toradix((M), (S), 8)) +#define mp_todecimal(M, S) (MP_DEPRECATED_PRAGMA("replaced by mp_to_decimal") mp_toradix((M), (S), 10)) +#define mp_tohex(M, S) (MP_DEPRECATED_PRAGMA("replaced by mp_to_hex") mp_toradix((M), (S), 16)) + +#define mp_to_binary(M, S, N) mp_to_radix((M), (S), (N), NULL, 2) +#define mp_to_octal(M, S, N) mp_to_radix((M), (S), (N), NULL, 8) +#define mp_to_decimal(M, S, N) mp_to_radix((M), (S), (N), NULL, 10) +#define mp_to_hex(M, S, N) mp_to_radix((M), (S), (N), NULL, 16) #ifdef __cplusplus - } +} #endif #endif - - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/libtommath/tommath.out b/libtommath/tommath.out deleted file mode 100644 index 9f62617..0000000 --- a/libtommath/tommath.out +++ /dev/null @@ -1,139 +0,0 @@ -\BOOKMARK [0][-]{chapter.1}{Introduction}{} -\BOOKMARK [1][-]{section.1.1}{Multiple Precision Arithmetic}{chapter.1} -\BOOKMARK [2][-]{subsection.1.1.1}{What is Multiple Precision Arithmetic?}{section.1.1} -\BOOKMARK [2][-]{subsection.1.1.2}{The Need for Multiple Precision Arithmetic}{section.1.1} -\BOOKMARK [2][-]{subsection.1.1.3}{Benefits of Multiple Precision Arithmetic}{section.1.1} -\BOOKMARK [1][-]{section.1.2}{Purpose of This Text}{chapter.1} -\BOOKMARK [1][-]{section.1.3}{Discussion and Notation}{chapter.1} -\BOOKMARK [2][-]{subsection.1.3.1}{Notation}{section.1.3} -\BOOKMARK [2][-]{subsection.1.3.2}{Precision Notation}{section.1.3} -\BOOKMARK [2][-]{subsection.1.3.3}{Algorithm Inputs and Outputs}{section.1.3} -\BOOKMARK [2][-]{subsection.1.3.4}{Mathematical Expressions}{section.1.3} -\BOOKMARK [2][-]{subsection.1.3.5}{Work Effort}{section.1.3} -\BOOKMARK [1][-]{section.1.4}{Exercises}{chapter.1} -\BOOKMARK [1][-]{section.1.5}{Introduction to LibTomMath}{chapter.1} -\BOOKMARK [2][-]{subsection.1.5.1}{What is LibTomMath?}{section.1.5} -\BOOKMARK [2][-]{subsection.1.5.2}{Goals of LibTomMath}{section.1.5} -\BOOKMARK [1][-]{section.1.6}{Choice of LibTomMath}{chapter.1} -\BOOKMARK [2][-]{subsection.1.6.1}{Code Base}{section.1.6} -\BOOKMARK [2][-]{subsection.1.6.2}{API Simplicity}{section.1.6} -\BOOKMARK [2][-]{subsection.1.6.3}{Optimizations}{section.1.6} -\BOOKMARK [2][-]{subsection.1.6.4}{Portability and Stability}{section.1.6} -\BOOKMARK [2][-]{subsection.1.6.5}{Choice}{section.1.6} -\BOOKMARK [0][-]{chapter.2}{Getting Started}{} -\BOOKMARK [1][-]{section.2.1}{Library Basics}{chapter.2} -\BOOKMARK [1][-]{section.2.2}{What is a Multiple Precision Integer?}{chapter.2} -\BOOKMARK [2][-]{subsection.2.2.1}{The mp\137int Structure}{section.2.2} -\BOOKMARK [1][-]{section.2.3}{Argument Passing}{chapter.2} -\BOOKMARK [1][-]{section.2.4}{Return Values}{chapter.2} -\BOOKMARK [1][-]{section.2.5}{Initialization and Clearing}{chapter.2} -\BOOKMARK [2][-]{subsection.2.5.1}{Initializing an mp\137int}{section.2.5} -\BOOKMARK [2][-]{subsection.2.5.2}{Clearing an mp\137int}{section.2.5} -\BOOKMARK [1][-]{section.2.6}{Maintenance Algorithms}{chapter.2} -\BOOKMARK [2][-]{subsection.2.6.1}{Augmenting an mp\137int's Precision}{section.2.6} -\BOOKMARK [2][-]{subsection.2.6.2}{Initializing Variable Precision mp\137ints}{section.2.6} -\BOOKMARK [2][-]{subsection.2.6.3}{Multiple Integer Initializations and Clearings}{section.2.6} -\BOOKMARK [2][-]{subsection.2.6.4}{Clamping Excess Digits}{section.2.6} -\BOOKMARK [0][-]{chapter.3}{Basic Operations}{} -\BOOKMARK [1][-]{section.3.1}{Introduction}{chapter.3} -\BOOKMARK [1][-]{section.3.2}{Assigning Values to mp\137int Structures}{chapter.3} -\BOOKMARK [2][-]{subsection.3.2.1}{Copying an mp\137int}{section.3.2} -\BOOKMARK [2][-]{subsection.3.2.2}{Creating a Clone}{section.3.2} -\BOOKMARK [1][-]{section.3.3}{Zeroing an Integer}{chapter.3} -\BOOKMARK [1][-]{section.3.4}{Sign Manipulation}{chapter.3} -\BOOKMARK [2][-]{subsection.3.4.1}{Absolute Value}{section.3.4} -\BOOKMARK [2][-]{subsection.3.4.2}{Integer Negation}{section.3.4} -\BOOKMARK [1][-]{section.3.5}{Small Constants}{chapter.3} -\BOOKMARK [2][-]{subsection.3.5.1}{Setting Small Constants}{section.3.5} -\BOOKMARK [2][-]{subsection.3.5.2}{Setting Large Constants}{section.3.5} -\BOOKMARK [1][-]{section.3.6}{Comparisons}{chapter.3} -\BOOKMARK [2][-]{subsection.3.6.1}{Unsigned Comparisions}{section.3.6} -\BOOKMARK [2][-]{subsection.3.6.2}{Signed Comparisons}{section.3.6} -\BOOKMARK [0][-]{chapter.4}{Basic Arithmetic}{} -\BOOKMARK [1][-]{section.4.1}{Introduction}{chapter.4} -\BOOKMARK [1][-]{section.4.2}{Addition and Subtraction}{chapter.4} -\BOOKMARK [2][-]{subsection.4.2.1}{Low Level Addition}{section.4.2} -\BOOKMARK [2][-]{subsection.4.2.2}{Low Level Subtraction}{section.4.2} -\BOOKMARK [2][-]{subsection.4.2.3}{High Level Addition}{section.4.2} -\BOOKMARK [2][-]{subsection.4.2.4}{High Level Subtraction}{section.4.2} -\BOOKMARK [1][-]{section.4.3}{Bit and Digit Shifting}{chapter.4} -\BOOKMARK [2][-]{subsection.4.3.1}{Multiplication by Two}{section.4.3} -\BOOKMARK [2][-]{subsection.4.3.2}{Division by Two}{section.4.3} -\BOOKMARK [1][-]{section.4.4}{Polynomial Basis Operations}{chapter.4} -\BOOKMARK [2][-]{subsection.4.4.1}{Multiplication by x}{section.4.4} -\BOOKMARK [2][-]{subsection.4.4.2}{Division by x}{section.4.4} -\BOOKMARK [1][-]{section.4.5}{Powers of Two}{chapter.4} -\BOOKMARK [2][-]{subsection.4.5.1}{Multiplication by Power of Two}{section.4.5} -\BOOKMARK [2][-]{subsection.4.5.2}{Division by Power of Two}{section.4.5} -\BOOKMARK [2][-]{subsection.4.5.3}{Remainder of Division by Power of Two}{section.4.5} -\BOOKMARK [0][-]{chapter.5}{Multiplication and Squaring}{} -\BOOKMARK [1][-]{section.5.1}{The Multipliers}{chapter.5} -\BOOKMARK [1][-]{section.5.2}{Multiplication}{chapter.5} -\BOOKMARK [2][-]{subsection.5.2.1}{The Baseline Multiplication}{section.5.2} -\BOOKMARK [2][-]{subsection.5.2.2}{Faster Multiplication by the ``Comba'' Method}{section.5.2} -\BOOKMARK [2][-]{subsection.5.2.3}{Polynomial Basis Multiplication}{section.5.2} -\BOOKMARK [2][-]{subsection.5.2.4}{Karatsuba Multiplication}{section.5.2} -\BOOKMARK [2][-]{subsection.5.2.5}{Toom-Cook 3-Way Multiplication}{section.5.2} -\BOOKMARK [2][-]{subsection.5.2.6}{Signed Multiplication}{section.5.2} -\BOOKMARK [1][-]{section.5.3}{Squaring}{chapter.5} -\BOOKMARK [2][-]{subsection.5.3.1}{The Baseline Squaring Algorithm}{section.5.3} -\BOOKMARK [2][-]{subsection.5.3.2}{Faster Squaring by the ``Comba'' Method}{section.5.3} -\BOOKMARK [2][-]{subsection.5.3.3}{Polynomial Basis Squaring}{section.5.3} -\BOOKMARK [2][-]{subsection.5.3.4}{Karatsuba Squaring}{section.5.3} -\BOOKMARK [2][-]{subsection.5.3.5}{Toom-Cook Squaring}{section.5.3} -\BOOKMARK [2][-]{subsection.5.3.6}{High Level Squaring}{section.5.3} -\BOOKMARK [0][-]{chapter.6}{Modular Reduction}{} -\BOOKMARK [1][-]{section.6.1}{Basics of Modular Reduction}{chapter.6} -\BOOKMARK [1][-]{section.6.2}{The Barrett Reduction}{chapter.6} -\BOOKMARK [2][-]{subsection.6.2.1}{Fixed Point Arithmetic}{section.6.2} -\BOOKMARK [2][-]{subsection.6.2.2}{Choosing a Radix Point}{section.6.2} -\BOOKMARK [2][-]{subsection.6.2.3}{Trimming the Quotient}{section.6.2} -\BOOKMARK [2][-]{subsection.6.2.4}{Trimming the Residue}{section.6.2} -\BOOKMARK [2][-]{subsection.6.2.5}{The Barrett Algorithm}{section.6.2} -\BOOKMARK [2][-]{subsection.6.2.6}{The Barrett Setup Algorithm}{section.6.2} -\BOOKMARK [1][-]{section.6.3}{The Montgomery Reduction}{chapter.6} -\BOOKMARK [2][-]{subsection.6.3.1}{Digit Based Montgomery Reduction}{section.6.3} -\BOOKMARK [2][-]{subsection.6.3.2}{Baseline Montgomery Reduction}{section.6.3} -\BOOKMARK [2][-]{subsection.6.3.3}{Faster ``Comba'' Montgomery Reduction}{section.6.3} -\BOOKMARK [2][-]{subsection.6.3.4}{Montgomery Setup}{section.6.3} -\BOOKMARK [1][-]{section.6.4}{The Diminished Radix Algorithm}{chapter.6} -\BOOKMARK [2][-]{subsection.6.4.1}{Choice of Moduli}{section.6.4} -\BOOKMARK [2][-]{subsection.6.4.2}{Choice of k}{section.6.4} -\BOOKMARK [2][-]{subsection.6.4.3}{Restricted Diminished Radix Reduction}{section.6.4} -\BOOKMARK [2][-]{subsection.6.4.4}{Unrestricted Diminished Radix Reduction}{section.6.4} -\BOOKMARK [1][-]{section.6.5}{Algorithm Comparison}{chapter.6} -\BOOKMARK [0][-]{chapter.7}{Exponentiation}{} -\BOOKMARK [1][-]{section.7.1}{Exponentiation Basics}{chapter.7} -\BOOKMARK [2][-]{subsection.7.1.1}{Single Digit Exponentiation}{section.7.1} -\BOOKMARK [1][-]{section.7.2}{k-ary Exponentiation}{chapter.7} -\BOOKMARK [2][-]{subsection.7.2.1}{Optimal Values of k}{section.7.2} -\BOOKMARK [2][-]{subsection.7.2.2}{Sliding-Window Exponentiation}{section.7.2} -\BOOKMARK [1][-]{section.7.3}{Modular Exponentiation}{chapter.7} -\BOOKMARK [2][-]{subsection.7.3.1}{Barrett Modular Exponentiation}{section.7.3} -\BOOKMARK [1][-]{section.7.4}{Quick Power of Two}{chapter.7} -\BOOKMARK [0][-]{chapter.8}{Higher Level Algorithms}{} -\BOOKMARK [1][-]{section.8.1}{Integer Division with Remainder}{chapter.8} -\BOOKMARK [2][-]{subsection.8.1.1}{Quotient Estimation}{section.8.1} -\BOOKMARK [2][-]{subsection.8.1.2}{Normalized Integers}{section.8.1} -\BOOKMARK [2][-]{subsection.8.1.3}{Radix- Division with Remainder}{section.8.1} -\BOOKMARK [1][-]{section.8.2}{Single Digit Helpers}{chapter.8} -\BOOKMARK [2][-]{subsection.8.2.1}{Single Digit Addition and Subtraction}{section.8.2} -\BOOKMARK [2][-]{subsection.8.2.2}{Single Digit Multiplication}{section.8.2} -\BOOKMARK [2][-]{subsection.8.2.3}{Single Digit Division}{section.8.2} -\BOOKMARK [2][-]{subsection.8.2.4}{Single Digit Root Extraction}{section.8.2} -\BOOKMARK [1][-]{section.8.3}{Random Number Generation}{chapter.8} -\BOOKMARK [1][-]{section.8.4}{Formatted Representations}{chapter.8} -\BOOKMARK [2][-]{subsection.8.4.1}{Reading Radix-n Input}{section.8.4} -\BOOKMARK [2][-]{subsection.8.4.2}{Generating Radix-n Output}{section.8.4} -\BOOKMARK [0][-]{chapter.9}{Number Theoretic Algorithms}{} -\BOOKMARK [1][-]{section.9.1}{Greatest Common Divisor}{chapter.9} -\BOOKMARK [2][-]{subsection.9.1.1}{Complete Greatest Common Divisor}{section.9.1} -\BOOKMARK [1][-]{section.9.2}{Least Common Multiple}{chapter.9} -\BOOKMARK [1][-]{section.9.3}{Jacobi Symbol Computation}{chapter.9} -\BOOKMARK [2][-]{subsection.9.3.1}{Jacobi Symbol}{section.9.3} -\BOOKMARK [1][-]{section.9.4}{Modular Inverse}{chapter.9} -\BOOKMARK [2][-]{subsection.9.4.1}{General Case}{section.9.4} -\BOOKMARK [1][-]{section.9.5}{Primality Tests}{chapter.9} -\BOOKMARK [2][-]{subsection.9.5.1}{Trial Division}{section.9.5} -\BOOKMARK [2][-]{subsection.9.5.2}{The Fermat Test}{section.9.5} -\BOOKMARK [2][-]{subsection.9.5.3}{The Miller-Rabin Test}{section.9.5} diff --git a/libtommath/tommath_class.h b/libtommath/tommath_class.h index bd7c39a..19bef02 100644 --- a/libtommath/tommath_class.h +++ b/libtommath/tommath_class.h @@ -1,220 +1,294 @@ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + #if !(defined(LTM1) && defined(LTM2) && defined(LTM3)) +#define LTM_INSIDE #if defined(LTM2) -#define LTM3 +# define LTM3 #endif #if defined(LTM1) -#define LTM2 +# define LTM2 #endif #define LTM1 - #if defined(LTM_ALL) -#define BN_ERROR_C -#define BN_FAST_MP_INVMOD_C -#define BN_FAST_MP_MONTGOMERY_REDUCE_C -#define BN_FAST_S_MP_MUL_DIGS_C -#define BN_FAST_S_MP_MUL_HIGH_DIGS_C -#define BN_FAST_S_MP_SQR_C -#define BN_MP_2EXPT_C -#define BN_MP_ABS_C -#define BN_MP_ADD_C -#define BN_MP_ADD_D_C -#define BN_MP_ADDMOD_C -#define BN_MP_AND_C -#define BN_MP_CLAMP_C -#define BN_MP_CLEAR_C -#define BN_MP_CLEAR_MULTI_C -#define BN_MP_CMP_C -#define BN_MP_CMP_D_C -#define BN_MP_CMP_MAG_C -#define BN_MP_CNT_LSB_C -#define BN_MP_COPY_C -#define BN_MP_COUNT_BITS_C -#define BN_MP_DIV_C -#define BN_MP_DIV_2_C -#define BN_MP_DIV_2D_C -#define BN_MP_DIV_3_C -#define BN_MP_DIV_D_C -#define BN_MP_DR_IS_MODULUS_C -#define BN_MP_DR_REDUCE_C -#define BN_MP_DR_SETUP_C -#define BN_MP_EXCH_C -#define BN_MP_EXPORT_C -#define BN_MP_EXPT_D_C -#define BN_MP_EXPT_D_EX_C -#define BN_MP_EXPTMOD_C -#define BN_MP_EXPTMOD_FAST_C -#define BN_MP_EXTEUCLID_C -#define BN_MP_FREAD_C -#define BN_MP_FWRITE_C -#define BN_MP_GCD_C -#define BN_MP_GET_INT_C -#define BN_MP_GET_LONG_C -#define BN_MP_GET_LONG_LONG_C -#define BN_MP_GROW_C -#define BN_MP_IMPORT_C -#define BN_MP_INIT_C -#define BN_MP_INIT_COPY_C -#define BN_MP_INIT_MULTI_C -#define BN_MP_INIT_SET_C -#define BN_MP_INIT_SET_INT_C -#define BN_MP_INIT_SIZE_C -#define BN_MP_INVMOD_C -#define BN_MP_INVMOD_SLOW_C -#define BN_MP_IS_SQUARE_C -#define BN_MP_JACOBI_C -#define BN_MP_KARATSUBA_MUL_C -#define BN_MP_KARATSUBA_SQR_C -#define BN_MP_LCM_C -#define BN_MP_LSHD_C -#define BN_MP_MOD_C -#define BN_MP_MOD_2D_C -#define BN_MP_MOD_D_C -#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -#define BN_MP_MONTGOMERY_REDUCE_C -#define BN_MP_MONTGOMERY_SETUP_C -#define BN_MP_MUL_C -#define BN_MP_MUL_2_C -#define BN_MP_MUL_2D_C -#define BN_MP_MUL_D_C -#define BN_MP_MULMOD_C -#define BN_MP_N_ROOT_C -#define BN_MP_N_ROOT_EX_C -#define BN_MP_NEG_C -#define BN_MP_OR_C -#define BN_MP_PRIME_FERMAT_C -#define BN_MP_PRIME_IS_DIVISIBLE_C -#define BN_MP_PRIME_IS_PRIME_C -#define BN_MP_PRIME_MILLER_RABIN_C -#define BN_MP_PRIME_NEXT_PRIME_C -#define BN_MP_PRIME_RABIN_MILLER_TRIALS_C -#define BN_MP_PRIME_RANDOM_EX_C -#define BN_MP_RADIX_SIZE_C -#define BN_MP_RADIX_SMAP_C -#define BN_MP_RAND_C -#define BN_MP_READ_RADIX_C -#define BN_MP_READ_SIGNED_BIN_C -#define BN_MP_READ_UNSIGNED_BIN_C -#define BN_MP_REDUCE_C -#define BN_MP_REDUCE_2K_C -#define BN_MP_REDUCE_2K_L_C -#define BN_MP_REDUCE_2K_SETUP_C -#define BN_MP_REDUCE_2K_SETUP_L_C -#define BN_MP_REDUCE_IS_2K_C -#define BN_MP_REDUCE_IS_2K_L_C -#define BN_MP_REDUCE_SETUP_C -#define BN_MP_RSHD_C -#define BN_MP_SET_C -#define BN_MP_SET_INT_C -#define BN_MP_SET_LONG_C -#define BN_MP_SET_LONG_LONG_C -#define BN_MP_SHRINK_C -#define BN_MP_SIGNED_BIN_SIZE_C -#define BN_MP_SQR_C -#define BN_MP_SQRMOD_C -#define BN_MP_SQRT_C -#define BN_MP_SQRTMOD_PRIME_C -#define BN_MP_SUB_C -#define BN_MP_SUB_D_C -#define BN_MP_SUBMOD_C -#define BN_MP_TO_SIGNED_BIN_C -#define BN_MP_TO_SIGNED_BIN_N_C -#define BN_MP_TO_UNSIGNED_BIN_C -#define BN_MP_TO_UNSIGNED_BIN_N_C -#define BN_MP_TOOM_MUL_C -#define BN_MP_TOOM_SQR_C -#define BN_MP_TORADIX_C -#define BN_MP_TORADIX_N_C -#define BN_MP_UNSIGNED_BIN_SIZE_C -#define BN_MP_XOR_C -#define BN_MP_ZERO_C -#define BN_PRIME_TAB_C -#define BN_REVERSE_C -#define BN_S_MP_ADD_C -#define BN_S_MP_EXPTMOD_C -#define BN_S_MP_MUL_DIGS_C -#define BN_S_MP_MUL_HIGH_DIGS_C -#define BN_S_MP_SQR_C -#define BN_S_MP_SUB_C -#define BNCORE_C -#endif - -#if defined(BN_ERROR_C) - #define BN_MP_ERROR_TO_STRING_C -#endif - -#if defined(BN_FAST_MP_INVMOD_C) - #define BN_MP_ISEVEN_C - #define BN_MP_INIT_MULTI_C - #define BN_MP_COPY_C - #define BN_MP_MOD_C - #define BN_MP_SET_C - #define BN_MP_DIV_2_C - #define BN_MP_ISODD_C - #define BN_MP_SUB_C - #define BN_MP_CMP_C - #define BN_MP_ISZERO_C - #define BN_MP_CMP_D_C - #define BN_MP_ADD_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_MULTI_C -#endif - -#if defined(BN_FAST_MP_MONTGOMERY_REDUCE_C) - #define BN_MP_GROW_C - #define BN_MP_RSHD_C - #define BN_MP_CLAMP_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C -#endif - -#if defined(BN_FAST_S_MP_MUL_DIGS_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_FAST_S_MP_SQR_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C +# define BN_CUTOFFS_C +# define BN_DEPRECATED_C +# define BN_MP_2EXPT_C +# define BN_MP_ABS_C +# define BN_MP_ADD_C +# define BN_MP_ADD_D_C +# define BN_MP_ADDMOD_C +# define BN_MP_AND_C +# define BN_MP_CLAMP_C +# define BN_MP_CLEAR_C +# define BN_MP_CLEAR_MULTI_C +# define BN_MP_CMP_C +# define BN_MP_CMP_D_C +# define BN_MP_CMP_MAG_C +# define BN_MP_CNT_LSB_C +# define BN_MP_COMPLEMENT_C +# define BN_MP_COPY_C +# define BN_MP_COUNT_BITS_C +# define BN_MP_DECR_C +# define BN_MP_DIV_C +# define BN_MP_DIV_2_C +# define BN_MP_DIV_2D_C +# define BN_MP_DIV_3_C +# define BN_MP_DIV_D_C +# define BN_MP_DR_IS_MODULUS_C +# define BN_MP_DR_REDUCE_C +# define BN_MP_DR_SETUP_C +# define BN_MP_ERROR_TO_STRING_C +# define BN_MP_EXCH_C +# define BN_MP_EXPT_U32_C +# define BN_MP_EXPTMOD_C +# define BN_MP_EXTEUCLID_C +# define BN_MP_FREAD_C +# define BN_MP_FROM_SBIN_C +# define BN_MP_FROM_UBIN_C +# define BN_MP_FWRITE_C +# define BN_MP_GCD_C +# define BN_MP_GET_I32_C +# define BN_MP_GET_I64_C +# define BN_MP_GET_L_C +# define BN_MP_GET_LL_C +# define BN_MP_GET_MAG_U32_C +# define BN_MP_GET_MAG_U64_C +# define BN_MP_GET_MAG_UL_C +# define BN_MP_GET_MAG_ULL_C +# define BN_MP_GROW_C +# define BN_MP_INCR_C +# define BN_MP_INIT_C +# define BN_MP_INIT_COPY_C +# define BN_MP_INIT_I32_C +# define BN_MP_INIT_I64_C +# define BN_MP_INIT_L_C +# define BN_MP_INIT_LL_C +# define BN_MP_INIT_MULTI_C +# define BN_MP_INIT_SET_C +# define BN_MP_INIT_SIZE_C +# define BN_MP_INIT_U32_C +# define BN_MP_INIT_U64_C +# define BN_MP_INIT_UL_C +# define BN_MP_INIT_ULL_C +# define BN_MP_INVMOD_C +# define BN_MP_IS_SQUARE_C +# define BN_MP_ISEVEN_C +# define BN_MP_ISODD_C +# define BN_MP_KRONECKER_C +# define BN_MP_LCM_C +# define BN_MP_LOG_U32_C +# define BN_MP_LSHD_C +# define BN_MP_MOD_C +# define BN_MP_MOD_2D_C +# define BN_MP_MOD_D_C +# define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C +# define BN_MP_MONTGOMERY_REDUCE_C +# define BN_MP_MONTGOMERY_SETUP_C +# define BN_MP_MUL_C +# define BN_MP_MUL_2_C +# define BN_MP_MUL_2D_C +# define BN_MP_MUL_D_C +# define BN_MP_MULMOD_C +# define BN_MP_NEG_C +# define BN_MP_OR_C +# define BN_MP_PACK_C +# define BN_MP_PACK_COUNT_C +# define BN_MP_PRIME_FERMAT_C +# define BN_MP_PRIME_FROBENIUS_UNDERWOOD_C +# define BN_MP_PRIME_IS_PRIME_C +# define BN_MP_PRIME_MILLER_RABIN_C +# define BN_MP_PRIME_NEXT_PRIME_C +# define BN_MP_PRIME_RABIN_MILLER_TRIALS_C +# define BN_MP_PRIME_RAND_C +# define BN_MP_PRIME_STRONG_LUCAS_SELFRIDGE_C +# define BN_MP_RADIX_SIZE_C +# define BN_MP_RADIX_SMAP_C +# define BN_MP_RAND_C +# define BN_MP_READ_RADIX_C +# define BN_MP_REDUCE_C +# define BN_MP_REDUCE_2K_C +# define BN_MP_REDUCE_2K_L_C +# define BN_MP_REDUCE_2K_SETUP_C +# define BN_MP_REDUCE_2K_SETUP_L_C +# define BN_MP_REDUCE_IS_2K_C +# define BN_MP_REDUCE_IS_2K_L_C +# define BN_MP_REDUCE_SETUP_C +# define BN_MP_ROOT_U32_C +# define BN_MP_RSHD_C +# define BN_MP_SBIN_SIZE_C +# define BN_MP_SET_C +# define BN_MP_SET_I32_C +# define BN_MP_SET_I64_C +# define BN_MP_SET_L_C +# define BN_MP_SET_LL_C +# define BN_MP_SET_U32_C +# define BN_MP_SET_U64_C +# define BN_MP_SET_UL_C +# define BN_MP_SET_ULL_C +# define BN_MP_SHRINK_C +# define BN_MP_SIGNED_RSH_C +# define BN_MP_SQR_C +# define BN_MP_SQRMOD_C +# define BN_MP_SQRT_C +# define BN_MP_SQRTMOD_PRIME_C +# define BN_MP_SUB_C +# define BN_MP_SUB_D_C +# define BN_MP_SUBMOD_C +# define BN_MP_TO_RADIX_C +# define BN_MP_TO_SBIN_C +# define BN_MP_TO_UBIN_C +# define BN_MP_UBIN_SIZE_C +# define BN_MP_UNPACK_C +# define BN_MP_XOR_C +# define BN_MP_ZERO_C +# define BN_PRIME_TAB_C +# define BN_S_MP_ADD_C +# define BN_S_MP_BALANCE_MUL_C +# define BN_S_MP_EXPTMOD_C +# define BN_S_MP_EXPTMOD_FAST_C +# define BN_S_MP_GET_BIT_C +# define BN_S_MP_INVMOD_FAST_C +# define BN_S_MP_INVMOD_SLOW_C +# define BN_S_MP_KARATSUBA_MUL_C +# define BN_S_MP_KARATSUBA_SQR_C +# define BN_S_MP_MONTGOMERY_REDUCE_FAST_C +# define BN_S_MP_MUL_DIGS_C +# define BN_S_MP_MUL_DIGS_FAST_C +# define BN_S_MP_MUL_HIGH_DIGS_C +# define BN_S_MP_MUL_HIGH_DIGS_FAST_C +# define BN_S_MP_PRIME_IS_DIVISIBLE_C +# define BN_S_MP_RAND_JENKINS_C +# define BN_S_MP_RAND_PLATFORM_C +# define BN_S_MP_REVERSE_C +# define BN_S_MP_SQR_C +# define BN_S_MP_SQR_FAST_C +# define BN_S_MP_SUB_C +# define BN_S_MP_TOOM_MUL_C +# define BN_S_MP_TOOM_SQR_C +#endif +#endif +#if defined(BN_CUTOFFS_C) +#endif + +#if defined(BN_DEPRECATED_C) +# define BN_FAST_MP_INVMOD_C +# define BN_FAST_MP_MONTGOMERY_REDUCE_C +# define BN_FAST_S_MP_MUL_DIGS_C +# define BN_FAST_S_MP_MUL_HIGH_DIGS_C +# define BN_FAST_S_MP_SQR_C +# define BN_MP_AND_C +# define BN_MP_BALANCE_MUL_C +# define BN_MP_CMP_D_C +# define BN_MP_EXPORT_C +# define BN_MP_EXPTMOD_FAST_C +# define BN_MP_EXPT_D_C +# define BN_MP_EXPT_D_EX_C +# define BN_MP_EXPT_U32_C +# define BN_MP_FROM_SBIN_C +# define BN_MP_FROM_UBIN_C +# define BN_MP_GET_BIT_C +# define BN_MP_GET_INT_C +# define BN_MP_GET_LONG_C +# define BN_MP_GET_LONG_LONG_C +# define BN_MP_GET_MAG_U32_C +# define BN_MP_GET_MAG_ULL_C +# define BN_MP_GET_MAG_UL_C +# define BN_MP_IMPORT_C +# define BN_MP_INIT_SET_INT_C +# define BN_MP_INIT_U32_C +# define BN_MP_INVMOD_SLOW_C +# define BN_MP_JACOBI_C +# define BN_MP_KARATSUBA_MUL_C +# define BN_MP_KARATSUBA_SQR_C +# define BN_MP_KRONECKER_C +# define BN_MP_N_ROOT_C +# define BN_MP_N_ROOT_EX_C +# define BN_MP_OR_C +# define BN_MP_PACK_C +# define BN_MP_PRIME_IS_DIVISIBLE_C +# define BN_MP_PRIME_RANDOM_EX_C +# define BN_MP_RAND_DIGIT_C +# define BN_MP_READ_SIGNED_BIN_C +# define BN_MP_READ_UNSIGNED_BIN_C +# define BN_MP_ROOT_U32_C +# define BN_MP_SBIN_SIZE_C +# define BN_MP_SET_INT_C +# define BN_MP_SET_LONG_C +# define BN_MP_SET_LONG_LONG_C +# define BN_MP_SET_U32_C +# define BN_MP_SET_U64_C +# define BN_MP_SIGNED_BIN_SIZE_C +# define BN_MP_SIGNED_RSH_C +# define BN_MP_TC_AND_C +# define BN_MP_TC_DIV_2D_C +# define BN_MP_TC_OR_C +# define BN_MP_TC_XOR_C +# define BN_MP_TOOM_MUL_C +# define BN_MP_TOOM_SQR_C +# define BN_MP_TORADIX_C +# define BN_MP_TORADIX_N_C +# define BN_MP_TO_RADIX_C +# define BN_MP_TO_SBIN_C +# define BN_MP_TO_SIGNED_BIN_C +# define BN_MP_TO_SIGNED_BIN_N_C +# define BN_MP_TO_UBIN_C +# define BN_MP_TO_UNSIGNED_BIN_C +# define BN_MP_TO_UNSIGNED_BIN_N_C +# define BN_MP_UBIN_SIZE_C +# define BN_MP_UNPACK_C +# define BN_MP_UNSIGNED_BIN_SIZE_C +# define BN_MP_XOR_C +# define BN_S_MP_BALANCE_MUL_C +# define BN_S_MP_EXPTMOD_FAST_C +# define BN_S_MP_GET_BIT_C +# define BN_S_MP_INVMOD_FAST_C +# define BN_S_MP_INVMOD_SLOW_C +# define BN_S_MP_KARATSUBA_MUL_C +# define BN_S_MP_KARATSUBA_SQR_C +# define BN_S_MP_MONTGOMERY_REDUCE_FAST_C +# define BN_S_MP_MUL_DIGS_FAST_C +# define BN_S_MP_MUL_HIGH_DIGS_FAST_C +# define BN_S_MP_PRIME_IS_DIVISIBLE_C +# define BN_S_MP_PRIME_RANDOM_EX_C +# define BN_S_MP_RAND_SOURCE_C +# define BN_S_MP_REVERSE_C +# define BN_S_MP_SQR_FAST_C +# define BN_S_MP_TOOM_MUL_C +# define BN_S_MP_TOOM_SQR_C #endif #if defined(BN_MP_2EXPT_C) - #define BN_MP_ZERO_C - #define BN_MP_GROW_C +# define BN_MP_GROW_C +# define BN_MP_ZERO_C #endif #if defined(BN_MP_ABS_C) - #define BN_MP_COPY_C +# define BN_MP_COPY_C #endif #if defined(BN_MP_ADD_C) - #define BN_S_MP_ADD_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C +# define BN_MP_CMP_MAG_C +# define BN_S_MP_ADD_C +# define BN_S_MP_SUB_C #endif #if defined(BN_MP_ADD_D_C) - #define BN_MP_GROW_C - #define BN_MP_SUB_D_C - #define BN_MP_CLAMP_C +# define BN_MP_CLAMP_C +# define BN_MP_GROW_C +# define BN_MP_SUB_D_C #endif #if defined(BN_MP_ADDMOD_C) - #define BN_MP_INIT_C - #define BN_MP_ADD_C - #define BN_MP_CLEAR_C - #define BN_MP_MOD_C +# define BN_MP_ADD_C +# define BN_MP_CLEAR_C +# define BN_MP_INIT_C +# define BN_MP_MOD_C #endif #if defined(BN_MP_AND_C) - #define BN_MP_INIT_COPY_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C +# define BN_MP_CLAMP_C +# define BN_MP_GROW_C #endif #if defined(BN_MP_CLAMP_C) @@ -224,11 +298,11 @@ #endif #if defined(BN_MP_CLEAR_MULTI_C) - #define BN_MP_CLEAR_C +# define BN_MP_CLEAR_C #endif #if defined(BN_MP_CMP_C) - #define BN_MP_CMP_MAG_C +# define BN_MP_CMP_MAG_C #endif #if defined(BN_MP_CMP_D_C) @@ -238,822 +312,999 @@ #endif #if defined(BN_MP_CNT_LSB_C) - #define BN_MP_ISZERO_C +#endif + +#if defined(BN_MP_COMPLEMENT_C) +# define BN_MP_NEG_C +# define BN_MP_SUB_D_C #endif #if defined(BN_MP_COPY_C) - #define BN_MP_GROW_C +# define BN_MP_GROW_C #endif #if defined(BN_MP_COUNT_BITS_C) #endif +#if defined(BN_MP_DECR_C) +# define BN_MP_INCR_C +# define BN_MP_SET_C +# define BN_MP_SUB_D_C +# define BN_MP_ZERO_C +#endif + #if defined(BN_MP_DIV_C) - #define BN_MP_ISZERO_C - #define BN_MP_CMP_MAG_C - #define BN_MP_COPY_C - #define BN_MP_ZERO_C - #define BN_MP_INIT_MULTI_C - #define BN_MP_SET_C - #define BN_MP_COUNT_BITS_C - #define BN_MP_ABS_C - #define BN_MP_MUL_2D_C - #define BN_MP_CMP_C - #define BN_MP_SUB_C - #define BN_MP_ADD_C - #define BN_MP_DIV_2D_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_MULTI_C - #define BN_MP_INIT_SIZE_C - #define BN_MP_INIT_C - #define BN_MP_INIT_COPY_C - #define BN_MP_LSHD_C - #define BN_MP_RSHD_C - #define BN_MP_MUL_D_C - #define BN_MP_CLAMP_C - #define BN_MP_CLEAR_C +# define BN_MP_ADD_C +# define BN_MP_CLAMP_C +# define BN_MP_CLEAR_C +# define BN_MP_CMP_C +# define BN_MP_CMP_MAG_C +# define BN_MP_COPY_C +# define BN_MP_COUNT_BITS_C +# define BN_MP_DIV_2D_C +# define BN_MP_EXCH_C +# define BN_MP_INIT_C +# define BN_MP_INIT_COPY_C +# define BN_MP_INIT_SIZE_C +# define BN_MP_LSHD_C +# define BN_MP_MUL_2D_C +# define BN_MP_MUL_D_C +# define BN_MP_RSHD_C +# define BN_MP_SUB_C +# define BN_MP_ZERO_C #endif #if defined(BN_MP_DIV_2_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C +# define BN_MP_CLAMP_C +# define BN_MP_GROW_C #endif #if defined(BN_MP_DIV_2D_C) - #define BN_MP_COPY_C - #define BN_MP_ZERO_C - #define BN_MP_MOD_2D_C - #define BN_MP_RSHD_C - #define BN_MP_CLAMP_C +# define BN_MP_CLAMP_C +# define BN_MP_COPY_C +# define BN_MP_MOD_2D_C +# define BN_MP_RSHD_C +# define BN_MP_ZERO_C #endif #if defined(BN_MP_DIV_3_C) - #define BN_MP_INIT_SIZE_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C +# define BN_MP_CLAMP_C +# define BN_MP_CLEAR_C +# define BN_MP_EXCH_C +# define BN_MP_INIT_SIZE_C #endif #if defined(BN_MP_DIV_D_C) - #define BN_MP_ISZERO_C - #define BN_MP_COPY_C - #define BN_MP_DIV_2D_C - #define BN_MP_DIV_3_C - #define BN_MP_INIT_SIZE_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C +# define BN_MP_CLAMP_C +# define BN_MP_CLEAR_C +# define BN_MP_COPY_C +# define BN_MP_DIV_2D_C +# define BN_MP_DIV_3_C +# define BN_MP_EXCH_C +# define BN_MP_INIT_SIZE_C #endif #if defined(BN_MP_DR_IS_MODULUS_C) #endif #if defined(BN_MP_DR_REDUCE_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C +# define BN_MP_CLAMP_C +# define BN_MP_CMP_MAG_C +# define BN_MP_GROW_C +# define BN_S_MP_SUB_C #endif #if defined(BN_MP_DR_SETUP_C) #endif -#if defined(BN_MP_EXCH_C) -#endif - -#if defined(BN_MP_EXPORT_C) - #define BN_MP_INIT_COPY_C - #define BN_MP_COUNT_BITS_C - #define BN_MP_DIV_2D_C - #define BN_MP_CLEAR_C +#if defined(BN_MP_ERROR_TO_STRING_C) #endif -#if defined(BN_MP_EXPT_D_C) - #define BN_MP_EXPT_D_EX_C +#if defined(BN_MP_EXCH_C) #endif -#if defined(BN_MP_EXPT_D_EX_C) - #define BN_MP_INIT_COPY_C - #define BN_MP_SET_C - #define BN_MP_MUL_C - #define BN_MP_CLEAR_C - #define BN_MP_SQR_C +#if defined(BN_MP_EXPT_U32_C) +# define BN_MP_CLEAR_C +# define BN_MP_INIT_COPY_C +# define BN_MP_MUL_C +# define BN_MP_SET_C +# define BN_MP_SQR_C #endif #if defined(BN_MP_EXPTMOD_C) - #define BN_MP_INIT_C - #define BN_MP_INVMOD_C - #define BN_MP_CLEAR_C - #define BN_MP_ABS_C - #define BN_MP_CLEAR_MULTI_C - #define BN_MP_REDUCE_IS_2K_L_C - #define BN_S_MP_EXPTMOD_C - #define BN_MP_DR_IS_MODULUS_C - #define BN_MP_REDUCE_IS_2K_C - #define BN_MP_ISODD_C - #define BN_MP_EXPTMOD_FAST_C -#endif - -#if defined(BN_MP_EXPTMOD_FAST_C) - #define BN_MP_COUNT_BITS_C - #define BN_MP_INIT_SIZE_C - #define BN_MP_CLEAR_C - #define BN_MP_MONTGOMERY_SETUP_C - #define BN_FAST_MP_MONTGOMERY_REDUCE_C - #define BN_MP_MONTGOMERY_REDUCE_C - #define BN_MP_DR_SETUP_C - #define BN_MP_DR_REDUCE_C - #define BN_MP_REDUCE_2K_SETUP_C - #define BN_MP_REDUCE_2K_C - #define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C - #define BN_MP_MULMOD_C - #define BN_MP_SET_C - #define BN_MP_MOD_C - #define BN_MP_COPY_C - #define BN_MP_SQR_C - #define BN_MP_MUL_C - #define BN_MP_EXCH_C +# define BN_MP_ABS_C +# define BN_MP_CLEAR_MULTI_C +# define BN_MP_DR_IS_MODULUS_C +# define BN_MP_INIT_MULTI_C +# define BN_MP_INVMOD_C +# define BN_MP_REDUCE_IS_2K_C +# define BN_MP_REDUCE_IS_2K_L_C +# define BN_S_MP_EXPTMOD_C +# define BN_S_MP_EXPTMOD_FAST_C #endif #if defined(BN_MP_EXTEUCLID_C) - #define BN_MP_INIT_MULTI_C - #define BN_MP_SET_C - #define BN_MP_COPY_C - #define BN_MP_ISZERO_C - #define BN_MP_DIV_C - #define BN_MP_MUL_C - #define BN_MP_SUB_C - #define BN_MP_NEG_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_MULTI_C +# define BN_MP_CLEAR_MULTI_C +# define BN_MP_COPY_C +# define BN_MP_DIV_C +# define BN_MP_EXCH_C +# define BN_MP_INIT_MULTI_C +# define BN_MP_MUL_C +# define BN_MP_NEG_C +# define BN_MP_SET_C +# define BN_MP_SUB_C #endif #if defined(BN_MP_FREAD_C) - #define BN_MP_ZERO_C - #define BN_MP_S_RMAP_C - #define BN_MP_MUL_D_C - #define BN_MP_ADD_D_C - #define BN_MP_CMP_D_C +# define BN_MP_ADD_D_C +# define BN_MP_MUL_D_C +# define BN_MP_ZERO_C +#endif + +#if defined(BN_MP_FROM_SBIN_C) +# define BN_MP_FROM_UBIN_C +#endif + +#if defined(BN_MP_FROM_UBIN_C) +# define BN_MP_CLAMP_C +# define BN_MP_GROW_C +# define BN_MP_MUL_2D_C +# define BN_MP_ZERO_C #endif #if defined(BN_MP_FWRITE_C) - #define BN_MP_RADIX_SIZE_C - #define BN_MP_TORADIX_C +# define BN_MP_RADIX_SIZE_C +# define BN_MP_TO_RADIX_C #endif #if defined(BN_MP_GCD_C) - #define BN_MP_ISZERO_C - #define BN_MP_ABS_C - #define BN_MP_INIT_COPY_C - #define BN_MP_CNT_LSB_C - #define BN_MP_DIV_2D_C - #define BN_MP_CMP_MAG_C - #define BN_MP_EXCH_C - #define BN_S_MP_SUB_C - #define BN_MP_MUL_2D_C - #define BN_MP_CLEAR_C +# define BN_MP_ABS_C +# define BN_MP_CLEAR_C +# define BN_MP_CMP_MAG_C +# define BN_MP_CNT_LSB_C +# define BN_MP_DIV_2D_C +# define BN_MP_EXCH_C +# define BN_MP_INIT_COPY_C +# define BN_MP_MUL_2D_C +# define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_GET_I32_C) +# define BN_MP_GET_MAG_U32_C +#endif + +#if defined(BN_MP_GET_I64_C) +# define BN_MP_GET_MAG_U64_C +#endif + +#if defined(BN_MP_GET_L_C) +# define BN_MP_GET_MAG_UL_C +#endif + +#if defined(BN_MP_GET_LL_C) +# define BN_MP_GET_MAG_ULL_C +#endif + +#if defined(BN_MP_GET_MAG_U32_C) #endif -#if defined(BN_MP_GET_INT_C) +#if defined(BN_MP_GET_MAG_U64_C) #endif -#if defined(BN_MP_GET_LONG_C) +#if defined(BN_MP_GET_MAG_UL_C) #endif -#if defined(BN_MP_GET_LONG_LONG_C) +#if defined(BN_MP_GET_MAG_ULL_C) #endif #if defined(BN_MP_GROW_C) #endif -#if defined(BN_MP_IMPORT_C) - #define BN_MP_ZERO_C - #define BN_MP_MUL_2D_C - #define BN_MP_CLAMP_C +#if defined(BN_MP_INCR_C) +# define BN_MP_ADD_D_C +# define BN_MP_DECR_C +# define BN_MP_SET_C #endif #if defined(BN_MP_INIT_C) #endif #if defined(BN_MP_INIT_COPY_C) - #define BN_MP_INIT_SIZE_C - #define BN_MP_COPY_C - #define BN_MP_CLEAR_C +# define BN_MP_CLEAR_C +# define BN_MP_COPY_C +# define BN_MP_INIT_SIZE_C +#endif + +#if defined(BN_MP_INIT_I32_C) +# define BN_MP_INIT_C +# define BN_MP_SET_I32_C +#endif + +#if defined(BN_MP_INIT_I64_C) +# define BN_MP_INIT_C +# define BN_MP_SET_I64_C +#endif + +#if defined(BN_MP_INIT_L_C) +# define BN_MP_INIT_C +# define BN_MP_SET_L_C +#endif + +#if defined(BN_MP_INIT_LL_C) +# define BN_MP_INIT_C +# define BN_MP_SET_LL_C #endif #if defined(BN_MP_INIT_MULTI_C) - #define BN_MP_ERR_C - #define BN_MP_INIT_C - #define BN_MP_CLEAR_C +# define BN_MP_CLEAR_C +# define BN_MP_INIT_C #endif #if defined(BN_MP_INIT_SET_C) - #define BN_MP_INIT_C - #define BN_MP_SET_C +# define BN_MP_INIT_C +# define BN_MP_SET_C #endif -#if defined(BN_MP_INIT_SET_INT_C) - #define BN_MP_INIT_C - #define BN_MP_SET_INT_C +#if defined(BN_MP_INIT_SIZE_C) #endif -#if defined(BN_MP_INIT_SIZE_C) - #define BN_MP_INIT_C +#if defined(BN_MP_INIT_U32_C) +# define BN_MP_INIT_C +# define BN_MP_SET_U32_C +#endif + +#if defined(BN_MP_INIT_U64_C) +# define BN_MP_INIT_C +# define BN_MP_SET_U64_C +#endif + +#if defined(BN_MP_INIT_UL_C) +# define BN_MP_INIT_C +# define BN_MP_SET_UL_C +#endif + +#if defined(BN_MP_INIT_ULL_C) +# define BN_MP_INIT_C +# define BN_MP_SET_ULL_C #endif #if defined(BN_MP_INVMOD_C) - #define BN_MP_ISZERO_C - #define BN_MP_ISODD_C - #define BN_MP_CMP_D_C - #define BN_FAST_MP_INVMOD_C - #define BN_MP_INVMOD_SLOW_C -#endif - -#if defined(BN_MP_INVMOD_SLOW_C) - #define BN_MP_ISZERO_C - #define BN_MP_INIT_MULTI_C - #define BN_MP_MOD_C - #define BN_MP_COPY_C - #define BN_MP_ISEVEN_C - #define BN_MP_SET_C - #define BN_MP_DIV_2_C - #define BN_MP_ISODD_C - #define BN_MP_ADD_C - #define BN_MP_SUB_C - #define BN_MP_CMP_C - #define BN_MP_CMP_D_C - #define BN_MP_CMP_MAG_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_MULTI_C +# define BN_MP_CMP_D_C +# define BN_S_MP_INVMOD_FAST_C +# define BN_S_MP_INVMOD_SLOW_C #endif #if defined(BN_MP_IS_SQUARE_C) - #define BN_MP_MOD_D_C - #define BN_MP_INIT_SET_INT_C - #define BN_MP_MOD_C - #define BN_MP_GET_INT_C - #define BN_MP_SQRT_C - #define BN_MP_SQR_C - #define BN_MP_CMP_MAG_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_JACOBI_C) - #define BN_MP_ISNEG_C - #define BN_MP_CMP_D_C - #define BN_MP_ISZERO_C - #define BN_MP_INIT_COPY_C - #define BN_MP_CNT_LSB_C - #define BN_MP_DIV_2D_C - #define BN_MP_MOD_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_KARATSUBA_MUL_C) - #define BN_MP_MUL_C - #define BN_MP_INIT_SIZE_C - #define BN_MP_CLAMP_C - #define BN_S_MP_ADD_C - #define BN_MP_ADD_C - #define BN_S_MP_SUB_C - #define BN_MP_LSHD_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_KARATSUBA_SQR_C) - #define BN_MP_INIT_SIZE_C - #define BN_MP_CLAMP_C - #define BN_MP_SQR_C - #define BN_S_MP_ADD_C - #define BN_S_MP_SUB_C - #define BN_MP_LSHD_C - #define BN_MP_ADD_C - #define BN_MP_CLEAR_C +# define BN_MP_CLEAR_C +# define BN_MP_CMP_MAG_C +# define BN_MP_GET_I32_C +# define BN_MP_INIT_U32_C +# define BN_MP_MOD_C +# define BN_MP_MOD_D_C +# define BN_MP_SQRT_C +# define BN_MP_SQR_C +#endif + +#if defined(BN_MP_ISEVEN_C) +#endif + +#if defined(BN_MP_ISODD_C) +#endif + +#if defined(BN_MP_KRONECKER_C) +# define BN_MP_CLEAR_C +# define BN_MP_CMP_D_C +# define BN_MP_CNT_LSB_C +# define BN_MP_COPY_C +# define BN_MP_DIV_2D_C +# define BN_MP_INIT_C +# define BN_MP_INIT_COPY_C +# define BN_MP_MOD_C #endif #if defined(BN_MP_LCM_C) - #define BN_MP_INIT_MULTI_C - #define BN_MP_GCD_C - #define BN_MP_CMP_MAG_C - #define BN_MP_DIV_C - #define BN_MP_MUL_C - #define BN_MP_CLEAR_MULTI_C +# define BN_MP_CLEAR_MULTI_C +# define BN_MP_CMP_MAG_C +# define BN_MP_DIV_C +# define BN_MP_GCD_C +# define BN_MP_INIT_MULTI_C +# define BN_MP_MUL_C +#endif + +#if defined(BN_MP_LOG_U32_C) +# define BN_MP_CLEAR_MULTI_C +# define BN_MP_CMP_C +# define BN_MP_CMP_D_C +# define BN_MP_COPY_C +# define BN_MP_COUNT_BITS_C +# define BN_MP_EXCH_C +# define BN_MP_EXPT_U32_C +# define BN_MP_INIT_MULTI_C +# define BN_MP_MUL_C +# define BN_MP_SET_C +# define BN_MP_SQR_C #endif #if defined(BN_MP_LSHD_C) - #define BN_MP_GROW_C - #define BN_MP_RSHD_C +# define BN_MP_GROW_C #endif #if defined(BN_MP_MOD_C) - #define BN_MP_INIT_SIZE_C - #define BN_MP_DIV_C - #define BN_MP_CLEAR_C - #define BN_MP_ISZERO_C - #define BN_MP_EXCH_C - #define BN_MP_ADD_C +# define BN_MP_ADD_C +# define BN_MP_CLEAR_C +# define BN_MP_DIV_C +# define BN_MP_EXCH_C +# define BN_MP_INIT_SIZE_C #endif #if defined(BN_MP_MOD_2D_C) - #define BN_MP_ZERO_C - #define BN_MP_COPY_C - #define BN_MP_CLAMP_C +# define BN_MP_CLAMP_C +# define BN_MP_COPY_C +# define BN_MP_ZERO_C #endif #if defined(BN_MP_MOD_D_C) - #define BN_MP_DIV_D_C +# define BN_MP_DIV_D_C #endif #if defined(BN_MP_MONTGOMERY_CALC_NORMALIZATION_C) - #define BN_MP_COUNT_BITS_C - #define BN_MP_2EXPT_C - #define BN_MP_SET_C - #define BN_MP_MUL_2_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C +# define BN_MP_2EXPT_C +# define BN_MP_CMP_MAG_C +# define BN_MP_COUNT_BITS_C +# define BN_MP_MUL_2_C +# define BN_MP_SET_C +# define BN_S_MP_SUB_C #endif #if defined(BN_MP_MONTGOMERY_REDUCE_C) - #define BN_FAST_MP_MONTGOMERY_REDUCE_C - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C - #define BN_MP_RSHD_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C +# define BN_MP_CLAMP_C +# define BN_MP_CMP_MAG_C +# define BN_MP_GROW_C +# define BN_MP_RSHD_C +# define BN_S_MP_MONTGOMERY_REDUCE_FAST_C +# define BN_S_MP_SUB_C #endif #if defined(BN_MP_MONTGOMERY_SETUP_C) #endif #if defined(BN_MP_MUL_C) - #define BN_MP_TOOM_MUL_C - #define BN_MP_KARATSUBA_MUL_C - #define BN_FAST_S_MP_MUL_DIGS_C - #define BN_S_MP_MUL_C - #define BN_S_MP_MUL_DIGS_C +# define BN_S_MP_BALANCE_MUL_C +# define BN_S_MP_KARATSUBA_MUL_C +# define BN_S_MP_MUL_DIGS_C +# define BN_S_MP_MUL_DIGS_FAST_C +# define BN_S_MP_TOOM_MUL_C #endif #if defined(BN_MP_MUL_2_C) - #define BN_MP_GROW_C +# define BN_MP_GROW_C #endif #if defined(BN_MP_MUL_2D_C) - #define BN_MP_COPY_C - #define BN_MP_GROW_C - #define BN_MP_LSHD_C - #define BN_MP_CLAMP_C +# define BN_MP_CLAMP_C +# define BN_MP_COPY_C +# define BN_MP_GROW_C +# define BN_MP_LSHD_C #endif #if defined(BN_MP_MUL_D_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C +# define BN_MP_CLAMP_C +# define BN_MP_GROW_C #endif #if defined(BN_MP_MULMOD_C) - #define BN_MP_INIT_SIZE_C - #define BN_MP_MUL_C - #define BN_MP_CLEAR_C - #define BN_MP_MOD_C +# define BN_MP_CLEAR_C +# define BN_MP_INIT_SIZE_C +# define BN_MP_MOD_C +# define BN_MP_MUL_C #endif -#if defined(BN_MP_N_ROOT_C) - #define BN_MP_N_ROOT_EX_C +#if defined(BN_MP_NEG_C) +# define BN_MP_COPY_C #endif -#if defined(BN_MP_N_ROOT_EX_C) - #define BN_MP_INIT_C - #define BN_MP_SET_C - #define BN_MP_COPY_C - #define BN_MP_EXPT_D_EX_C - #define BN_MP_MUL_C - #define BN_MP_SUB_C - #define BN_MP_MUL_D_C - #define BN_MP_DIV_C - #define BN_MP_CMP_C - #define BN_MP_SUB_D_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C +#if defined(BN_MP_OR_C) +# define BN_MP_CLAMP_C +# define BN_MP_GROW_C #endif -#if defined(BN_MP_NEG_C) - #define BN_MP_COPY_C - #define BN_MP_ISZERO_C +#if defined(BN_MP_PACK_C) +# define BN_MP_CLEAR_C +# define BN_MP_DIV_2D_C +# define BN_MP_INIT_COPY_C +# define BN_MP_PACK_COUNT_C #endif -#if defined(BN_MP_OR_C) - #define BN_MP_INIT_COPY_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C +#if defined(BN_MP_PACK_COUNT_C) +# define BN_MP_COUNT_BITS_C #endif #if defined(BN_MP_PRIME_FERMAT_C) - #define BN_MP_CMP_D_C - #define BN_MP_INIT_C - #define BN_MP_EXPTMOD_C - #define BN_MP_CMP_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_PRIME_IS_DIVISIBLE_C) - #define BN_MP_MOD_D_C +# define BN_MP_CLEAR_C +# define BN_MP_CMP_C +# define BN_MP_CMP_D_C +# define BN_MP_EXPTMOD_C +# define BN_MP_INIT_C +#endif + +#if defined(BN_MP_PRIME_FROBENIUS_UNDERWOOD_C) +# define BN_MP_ADD_C +# define BN_MP_ADD_D_C +# define BN_MP_CLEAR_MULTI_C +# define BN_MP_CMP_C +# define BN_MP_COUNT_BITS_C +# define BN_MP_EXCH_C +# define BN_MP_GCD_C +# define BN_MP_INIT_MULTI_C +# define BN_MP_KRONECKER_C +# define BN_MP_MOD_C +# define BN_MP_MUL_2_C +# define BN_MP_MUL_C +# define BN_MP_MUL_D_C +# define BN_MP_SET_C +# define BN_MP_SET_U32_C +# define BN_MP_SQR_C +# define BN_MP_SUB_C +# define BN_MP_SUB_D_C +# define BN_S_MP_GET_BIT_C #endif #if defined(BN_MP_PRIME_IS_PRIME_C) - #define BN_MP_CMP_D_C - #define BN_MP_PRIME_IS_DIVISIBLE_C - #define BN_MP_INIT_C - #define BN_MP_SET_C - #define BN_MP_PRIME_MILLER_RABIN_C - #define BN_MP_CLEAR_C +# define BN_MP_CLEAR_C +# define BN_MP_CMP_C +# define BN_MP_CMP_D_C +# define BN_MP_COUNT_BITS_C +# define BN_MP_DIV_2D_C +# define BN_MP_INIT_SET_C +# define BN_MP_IS_SQUARE_C +# define BN_MP_PRIME_MILLER_RABIN_C +# define BN_MP_PRIME_STRONG_LUCAS_SELFRIDGE_C +# define BN_MP_RAND_C +# define BN_MP_READ_RADIX_C +# define BN_MP_SET_C +# define BN_S_MP_PRIME_IS_DIVISIBLE_C #endif #if defined(BN_MP_PRIME_MILLER_RABIN_C) - #define BN_MP_CMP_D_C - #define BN_MP_INIT_COPY_C - #define BN_MP_SUB_D_C - #define BN_MP_CNT_LSB_C - #define BN_MP_DIV_2D_C - #define BN_MP_EXPTMOD_C - #define BN_MP_CMP_C - #define BN_MP_SQRMOD_C - #define BN_MP_CLEAR_C +# define BN_MP_CLEAR_C +# define BN_MP_CMP_C +# define BN_MP_CMP_D_C +# define BN_MP_CNT_LSB_C +# define BN_MP_DIV_2D_C +# define BN_MP_EXPTMOD_C +# define BN_MP_INIT_C +# define BN_MP_INIT_COPY_C +# define BN_MP_SQRMOD_C +# define BN_MP_SUB_D_C #endif #if defined(BN_MP_PRIME_NEXT_PRIME_C) - #define BN_MP_CMP_D_C - #define BN_MP_SET_C - #define BN_MP_SUB_D_C - #define BN_MP_ISEVEN_C - #define BN_MP_MOD_D_C - #define BN_MP_INIT_C - #define BN_MP_ADD_D_C - #define BN_MP_PRIME_MILLER_RABIN_C - #define BN_MP_CLEAR_C +# define BN_MP_ADD_D_C +# define BN_MP_CLEAR_C +# define BN_MP_CMP_D_C +# define BN_MP_INIT_C +# define BN_MP_MOD_D_C +# define BN_MP_PRIME_IS_PRIME_C +# define BN_MP_SET_C +# define BN_MP_SUB_D_C #endif #if defined(BN_MP_PRIME_RABIN_MILLER_TRIALS_C) #endif -#if defined(BN_MP_PRIME_RANDOM_EX_C) - #define BN_MP_READ_UNSIGNED_BIN_C - #define BN_MP_PRIME_IS_PRIME_C - #define BN_MP_SUB_D_C - #define BN_MP_DIV_2_C - #define BN_MP_MUL_2_C - #define BN_MP_ADD_D_C +#if defined(BN_MP_PRIME_RAND_C) +# define BN_MP_ADD_D_C +# define BN_MP_DIV_2_C +# define BN_MP_FROM_UBIN_C +# define BN_MP_MUL_2_C +# define BN_MP_PRIME_IS_PRIME_C +# define BN_MP_SUB_D_C +# define BN_S_MP_PRIME_RANDOM_EX_C +# define BN_S_MP_RAND_CB_C +# define BN_S_MP_RAND_SOURCE_C +#endif + +#if defined(BN_MP_PRIME_STRONG_LUCAS_SELFRIDGE_C) +# define BN_MP_ADD_C +# define BN_MP_ADD_D_C +# define BN_MP_CLEAR_C +# define BN_MP_CLEAR_MULTI_C +# define BN_MP_CMP_C +# define BN_MP_CMP_D_C +# define BN_MP_CNT_LSB_C +# define BN_MP_COUNT_BITS_C +# define BN_MP_DIV_2D_C +# define BN_MP_DIV_2_C +# define BN_MP_GCD_C +# define BN_MP_INIT_C +# define BN_MP_INIT_MULTI_C +# define BN_MP_KRONECKER_C +# define BN_MP_MOD_C +# define BN_MP_MUL_2_C +# define BN_MP_MUL_C +# define BN_MP_SET_C +# define BN_MP_SET_I32_C +# define BN_MP_SET_U32_C +# define BN_MP_SQR_C +# define BN_MP_SUB_C +# define BN_MP_SUB_D_C +# define BN_S_MP_GET_BIT_C +# define BN_S_MP_MUL_SI_C #endif #if defined(BN_MP_RADIX_SIZE_C) - #define BN_MP_ISZERO_C - #define BN_MP_COUNT_BITS_C - #define BN_MP_INIT_COPY_C - #define BN_MP_DIV_D_C - #define BN_MP_CLEAR_C +# define BN_MP_CLEAR_C +# define BN_MP_COUNT_BITS_C +# define BN_MP_DIV_D_C +# define BN_MP_INIT_COPY_C #endif #if defined(BN_MP_RADIX_SMAP_C) - #define BN_MP_S_RMAP_C #endif #if defined(BN_MP_RAND_C) - #define BN_MP_ZERO_C - #define BN_MP_ADD_D_C - #define BN_MP_LSHD_C +# define BN_MP_GROW_C +# define BN_MP_RAND_SOURCE_C +# define BN_MP_ZERO_C +# define BN_S_MP_RAND_PLATFORM_C +# define BN_S_MP_RAND_SOURCE_C #endif #if defined(BN_MP_READ_RADIX_C) - #define BN_MP_ZERO_C - #define BN_MP_S_RMAP_C - #define BN_MP_MUL_D_C - #define BN_MP_ADD_D_C - #define BN_MP_ISZERO_C -#endif - -#if defined(BN_MP_READ_SIGNED_BIN_C) - #define BN_MP_READ_UNSIGNED_BIN_C -#endif - -#if defined(BN_MP_READ_UNSIGNED_BIN_C) - #define BN_MP_GROW_C - #define BN_MP_ZERO_C - #define BN_MP_MUL_2D_C - #define BN_MP_CLAMP_C +# define BN_MP_ADD_D_C +# define BN_MP_MUL_D_C +# define BN_MP_ZERO_C #endif #if defined(BN_MP_REDUCE_C) - #define BN_MP_REDUCE_SETUP_C - #define BN_MP_INIT_COPY_C - #define BN_MP_RSHD_C - #define BN_MP_MUL_C - #define BN_S_MP_MUL_HIGH_DIGS_C - #define BN_FAST_S_MP_MUL_HIGH_DIGS_C - #define BN_MP_MOD_2D_C - #define BN_S_MP_MUL_DIGS_C - #define BN_MP_SUB_C - #define BN_MP_CMP_D_C - #define BN_MP_SET_C - #define BN_MP_LSHD_C - #define BN_MP_ADD_C - #define BN_MP_CMP_C - #define BN_S_MP_SUB_C - #define BN_MP_CLEAR_C +# define BN_MP_ADD_C +# define BN_MP_CLEAR_C +# define BN_MP_CMP_C +# define BN_MP_CMP_D_C +# define BN_MP_INIT_COPY_C +# define BN_MP_LSHD_C +# define BN_MP_MOD_2D_C +# define BN_MP_MUL_C +# define BN_MP_RSHD_C +# define BN_MP_SET_C +# define BN_MP_SUB_C +# define BN_S_MP_MUL_DIGS_C +# define BN_S_MP_MUL_HIGH_DIGS_C +# define BN_S_MP_MUL_HIGH_DIGS_FAST_C +# define BN_S_MP_SUB_C #endif #if defined(BN_MP_REDUCE_2K_C) - #define BN_MP_INIT_C - #define BN_MP_COUNT_BITS_C - #define BN_MP_DIV_2D_C - #define BN_MP_MUL_D_C - #define BN_S_MP_ADD_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C - #define BN_MP_CLEAR_C +# define BN_MP_CLEAR_C +# define BN_MP_CMP_MAG_C +# define BN_MP_COUNT_BITS_C +# define BN_MP_DIV_2D_C +# define BN_MP_INIT_C +# define BN_MP_MUL_D_C +# define BN_S_MP_ADD_C +# define BN_S_MP_SUB_C #endif #if defined(BN_MP_REDUCE_2K_L_C) - #define BN_MP_INIT_C - #define BN_MP_COUNT_BITS_C - #define BN_MP_DIV_2D_C - #define BN_MP_MUL_C - #define BN_S_MP_ADD_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C - #define BN_MP_CLEAR_C +# define BN_MP_CLEAR_C +# define BN_MP_CMP_MAG_C +# define BN_MP_COUNT_BITS_C +# define BN_MP_DIV_2D_C +# define BN_MP_INIT_C +# define BN_MP_MUL_C +# define BN_S_MP_ADD_C +# define BN_S_MP_SUB_C #endif #if defined(BN_MP_REDUCE_2K_SETUP_C) - #define BN_MP_INIT_C - #define BN_MP_COUNT_BITS_C - #define BN_MP_2EXPT_C - #define BN_MP_CLEAR_C - #define BN_S_MP_SUB_C +# define BN_MP_2EXPT_C +# define BN_MP_CLEAR_C +# define BN_MP_COUNT_BITS_C +# define BN_MP_INIT_C +# define BN_S_MP_SUB_C #endif #if defined(BN_MP_REDUCE_2K_SETUP_L_C) - #define BN_MP_INIT_C - #define BN_MP_2EXPT_C - #define BN_MP_COUNT_BITS_C - #define BN_S_MP_SUB_C - #define BN_MP_CLEAR_C +# define BN_MP_2EXPT_C +# define BN_MP_CLEAR_C +# define BN_MP_COUNT_BITS_C +# define BN_MP_INIT_C +# define BN_S_MP_SUB_C #endif #if defined(BN_MP_REDUCE_IS_2K_C) - #define BN_MP_REDUCE_2K_C - #define BN_MP_COUNT_BITS_C +# define BN_MP_COUNT_BITS_C #endif #if defined(BN_MP_REDUCE_IS_2K_L_C) #endif #if defined(BN_MP_REDUCE_SETUP_C) - #define BN_MP_2EXPT_C - #define BN_MP_DIV_C +# define BN_MP_2EXPT_C +# define BN_MP_DIV_C +#endif + +#if defined(BN_MP_ROOT_U32_C) +# define BN_MP_2EXPT_C +# define BN_MP_ADD_D_C +# define BN_MP_CLEAR_MULTI_C +# define BN_MP_CMP_C +# define BN_MP_COPY_C +# define BN_MP_COUNT_BITS_C +# define BN_MP_DIV_C +# define BN_MP_EXCH_C +# define BN_MP_EXPT_U32_C +# define BN_MP_INIT_MULTI_C +# define BN_MP_MUL_C +# define BN_MP_MUL_D_C +# define BN_MP_SET_C +# define BN_MP_SUB_C +# define BN_MP_SUB_D_C #endif #if defined(BN_MP_RSHD_C) - #define BN_MP_ZERO_C +# define BN_MP_ZERO_C +#endif + +#if defined(BN_MP_SBIN_SIZE_C) +# define BN_MP_UBIN_SIZE_C #endif #if defined(BN_MP_SET_C) - #define BN_MP_ZERO_C #endif -#if defined(BN_MP_SET_INT_C) - #define BN_MP_ZERO_C - #define BN_MP_MUL_2D_C - #define BN_MP_CLAMP_C +#if defined(BN_MP_SET_I32_C) +# define BN_MP_SET_U32_C #endif -#if defined(BN_MP_SET_LONG_C) +#if defined(BN_MP_SET_I64_C) +# define BN_MP_SET_U64_C #endif -#if defined(BN_MP_SET_LONG_LONG_C) +#if defined(BN_MP_SET_L_C) +# define BN_MP_SET_UL_C +#endif + +#if defined(BN_MP_SET_LL_C) +# define BN_MP_SET_ULL_C +#endif + +#if defined(BN_MP_SET_U32_C) +#endif + +#if defined(BN_MP_SET_U64_C) +#endif + +#if defined(BN_MP_SET_UL_C) +#endif + +#if defined(BN_MP_SET_ULL_C) #endif #if defined(BN_MP_SHRINK_C) #endif -#if defined(BN_MP_SIGNED_BIN_SIZE_C) - #define BN_MP_UNSIGNED_BIN_SIZE_C +#if defined(BN_MP_SIGNED_RSH_C) +# define BN_MP_ADD_D_C +# define BN_MP_DIV_2D_C +# define BN_MP_SUB_D_C #endif #if defined(BN_MP_SQR_C) - #define BN_MP_TOOM_SQR_C - #define BN_MP_KARATSUBA_SQR_C - #define BN_FAST_S_MP_SQR_C - #define BN_S_MP_SQR_C +# define BN_S_MP_KARATSUBA_SQR_C +# define BN_S_MP_SQR_C +# define BN_S_MP_SQR_FAST_C +# define BN_S_MP_TOOM_SQR_C #endif #if defined(BN_MP_SQRMOD_C) - #define BN_MP_INIT_C - #define BN_MP_SQR_C - #define BN_MP_CLEAR_C - #define BN_MP_MOD_C +# define BN_MP_CLEAR_C +# define BN_MP_INIT_C +# define BN_MP_MOD_C +# define BN_MP_SQR_C #endif #if defined(BN_MP_SQRT_C) - #define BN_MP_N_ROOT_C - #define BN_MP_ISZERO_C - #define BN_MP_ZERO_C - #define BN_MP_INIT_COPY_C - #define BN_MP_RSHD_C - #define BN_MP_DIV_C - #define BN_MP_ADD_C - #define BN_MP_DIV_2_C - #define BN_MP_CMP_MAG_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C +# define BN_MP_ADD_C +# define BN_MP_CLEAR_C +# define BN_MP_CMP_MAG_C +# define BN_MP_DIV_2_C +# define BN_MP_DIV_C +# define BN_MP_EXCH_C +# define BN_MP_INIT_C +# define BN_MP_INIT_COPY_C +# define BN_MP_RSHD_C +# define BN_MP_ZERO_C #endif #if defined(BN_MP_SQRTMOD_PRIME_C) - #define BN_MP_CMP_D_C - #define BN_MP_ZERO_C - #define BN_MP_JACOBI_C - #define BN_MP_INIT_MULTI_C - #define BN_MP_MOD_D_C - #define BN_MP_ADD_D_C - #define BN_MP_DIV_2_C - #define BN_MP_EXPTMOD_C - #define BN_MP_COPY_C - #define BN_MP_SUB_D_C - #define BN_MP_ISEVEN_C - #define BN_MP_SET_INT_C - #define BN_MP_SQRMOD_C - #define BN_MP_MULMOD_C - #define BN_MP_SET_C - #define BN_MP_CLEAR_MULTI_C +# define BN_MP_ADD_D_C +# define BN_MP_CLEAR_MULTI_C +# define BN_MP_CMP_D_C +# define BN_MP_COPY_C +# define BN_MP_DIV_2_C +# define BN_MP_EXPTMOD_C +# define BN_MP_INIT_MULTI_C +# define BN_MP_KRONECKER_C +# define BN_MP_MOD_D_C +# define BN_MP_MULMOD_C +# define BN_MP_SET_C +# define BN_MP_SET_U32_C +# define BN_MP_SQRMOD_C +# define BN_MP_SUB_D_C +# define BN_MP_ZERO_C #endif #if defined(BN_MP_SUB_C) - #define BN_S_MP_ADD_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C +# define BN_MP_CMP_MAG_C +# define BN_S_MP_ADD_C +# define BN_S_MP_SUB_C #endif #if defined(BN_MP_SUB_D_C) - #define BN_MP_GROW_C - #define BN_MP_ADD_D_C - #define BN_MP_CLAMP_C +# define BN_MP_ADD_D_C +# define BN_MP_CLAMP_C +# define BN_MP_GROW_C #endif #if defined(BN_MP_SUBMOD_C) - #define BN_MP_INIT_C - #define BN_MP_SUB_C - #define BN_MP_CLEAR_C - #define BN_MP_MOD_C +# define BN_MP_CLEAR_C +# define BN_MP_INIT_C +# define BN_MP_MOD_C +# define BN_MP_SUB_C +#endif + +#if defined(BN_MP_TO_RADIX_C) +# define BN_MP_CLEAR_C +# define BN_MP_DIV_D_C +# define BN_MP_INIT_COPY_C +# define BN_S_MP_REVERSE_C #endif -#if defined(BN_MP_TO_SIGNED_BIN_C) - #define BN_MP_TO_UNSIGNED_BIN_C +#if defined(BN_MP_TO_SBIN_C) +# define BN_MP_TO_UBIN_C #endif -#if defined(BN_MP_TO_SIGNED_BIN_N_C) - #define BN_MP_SIGNED_BIN_SIZE_C - #define BN_MP_TO_SIGNED_BIN_C +#if defined(BN_MP_TO_UBIN_C) +# define BN_MP_CLEAR_C +# define BN_MP_DIV_2D_C +# define BN_MP_INIT_COPY_C +# define BN_MP_UBIN_SIZE_C #endif -#if defined(BN_MP_TO_UNSIGNED_BIN_C) - #define BN_MP_INIT_COPY_C - #define BN_MP_ISZERO_C - #define BN_MP_DIV_2D_C - #define BN_MP_CLEAR_C +#if defined(BN_MP_UBIN_SIZE_C) +# define BN_MP_COUNT_BITS_C #endif -#if defined(BN_MP_TO_UNSIGNED_BIN_N_C) - #define BN_MP_UNSIGNED_BIN_SIZE_C - #define BN_MP_TO_UNSIGNED_BIN_C +#if defined(BN_MP_UNPACK_C) +# define BN_MP_CLAMP_C +# define BN_MP_MUL_2D_C +# define BN_MP_ZERO_C #endif -#if defined(BN_MP_TOOM_MUL_C) - #define BN_MP_INIT_MULTI_C - #define BN_MP_MOD_2D_C - #define BN_MP_COPY_C - #define BN_MP_RSHD_C - #define BN_MP_MUL_C - #define BN_MP_MUL_2_C - #define BN_MP_ADD_C - #define BN_MP_SUB_C - #define BN_MP_DIV_2_C - #define BN_MP_MUL_2D_C - #define BN_MP_MUL_D_C - #define BN_MP_DIV_3_C - #define BN_MP_LSHD_C - #define BN_MP_CLEAR_MULTI_C +#if defined(BN_MP_XOR_C) +# define BN_MP_CLAMP_C +# define BN_MP_GROW_C #endif -#if defined(BN_MP_TOOM_SQR_C) - #define BN_MP_INIT_MULTI_C - #define BN_MP_MOD_2D_C - #define BN_MP_COPY_C - #define BN_MP_RSHD_C - #define BN_MP_SQR_C - #define BN_MP_MUL_2_C - #define BN_MP_ADD_C - #define BN_MP_SUB_C - #define BN_MP_DIV_2_C - #define BN_MP_MUL_2D_C - #define BN_MP_MUL_D_C - #define BN_MP_DIV_3_C - #define BN_MP_LSHD_C - #define BN_MP_CLEAR_MULTI_C +#if defined(BN_MP_ZERO_C) #endif -#if defined(BN_MP_TORADIX_C) - #define BN_MP_ISZERO_C - #define BN_MP_INIT_COPY_C - #define BN_MP_DIV_D_C - #define BN_MP_CLEAR_C - #define BN_MP_S_RMAP_C +#if defined(BN_PRIME_TAB_C) #endif -#if defined(BN_MP_TORADIX_N_C) - #define BN_MP_ISZERO_C - #define BN_MP_INIT_COPY_C - #define BN_MP_DIV_D_C - #define BN_MP_CLEAR_C - #define BN_MP_S_RMAP_C +#if defined(BN_S_MP_ADD_C) +# define BN_MP_CLAMP_C +# define BN_MP_GROW_C #endif -#if defined(BN_MP_UNSIGNED_BIN_SIZE_C) - #define BN_MP_COUNT_BITS_C +#if defined(BN_S_MP_BALANCE_MUL_C) +# define BN_MP_ADD_C +# define BN_MP_CLAMP_C +# define BN_MP_CLEAR_C +# define BN_MP_CLEAR_MULTI_C +# define BN_MP_EXCH_C +# define BN_MP_INIT_MULTI_C +# define BN_MP_INIT_SIZE_C +# define BN_MP_LSHD_C +# define BN_MP_MUL_C #endif -#if defined(BN_MP_XOR_C) - #define BN_MP_INIT_COPY_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C +#if defined(BN_S_MP_EXPTMOD_C) +# define BN_MP_CLEAR_C +# define BN_MP_COPY_C +# define BN_MP_COUNT_BITS_C +# define BN_MP_EXCH_C +# define BN_MP_INIT_C +# define BN_MP_MOD_C +# define BN_MP_MUL_C +# define BN_MP_REDUCE_2K_L_C +# define BN_MP_REDUCE_2K_SETUP_L_C +# define BN_MP_REDUCE_C +# define BN_MP_REDUCE_SETUP_C +# define BN_MP_SET_C +# define BN_MP_SQR_C +#endif + +#if defined(BN_S_MP_EXPTMOD_FAST_C) +# define BN_MP_CLEAR_C +# define BN_MP_COPY_C +# define BN_MP_COUNT_BITS_C +# define BN_MP_DR_REDUCE_C +# define BN_MP_DR_SETUP_C +# define BN_MP_EXCH_C +# define BN_MP_INIT_SIZE_C +# define BN_MP_MOD_C +# define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C +# define BN_MP_MONTGOMERY_REDUCE_C +# define BN_MP_MONTGOMERY_SETUP_C +# define BN_MP_MULMOD_C +# define BN_MP_MUL_C +# define BN_MP_REDUCE_2K_C +# define BN_MP_REDUCE_2K_SETUP_C +# define BN_MP_SET_C +# define BN_MP_SQR_C +# define BN_S_MP_MONTGOMERY_REDUCE_FAST_C +#endif + +#if defined(BN_S_MP_GET_BIT_C) +#endif + +#if defined(BN_S_MP_INVMOD_FAST_C) +# define BN_MP_ADD_C +# define BN_MP_CLEAR_MULTI_C +# define BN_MP_CMP_C +# define BN_MP_CMP_D_C +# define BN_MP_CMP_MAG_C +# define BN_MP_COPY_C +# define BN_MP_DIV_2_C +# define BN_MP_EXCH_C +# define BN_MP_INIT_MULTI_C +# define BN_MP_MOD_C +# define BN_MP_SET_C +# define BN_MP_SUB_C +#endif + +#if defined(BN_S_MP_INVMOD_SLOW_C) +# define BN_MP_ADD_C +# define BN_MP_CLEAR_MULTI_C +# define BN_MP_CMP_C +# define BN_MP_CMP_D_C +# define BN_MP_CMP_MAG_C +# define BN_MP_COPY_C +# define BN_MP_DIV_2_C +# define BN_MP_EXCH_C +# define BN_MP_INIT_MULTI_C +# define BN_MP_MOD_C +# define BN_MP_SET_C +# define BN_MP_SUB_C +#endif + +#if defined(BN_S_MP_KARATSUBA_MUL_C) +# define BN_MP_ADD_C +# define BN_MP_CLAMP_C +# define BN_MP_CLEAR_C +# define BN_MP_INIT_SIZE_C +# define BN_MP_LSHD_C +# define BN_MP_MUL_C +# define BN_S_MP_ADD_C +# define BN_S_MP_SUB_C +#endif + +#if defined(BN_S_MP_KARATSUBA_SQR_C) +# define BN_MP_ADD_C +# define BN_MP_CLAMP_C +# define BN_MP_CLEAR_C +# define BN_MP_INIT_SIZE_C +# define BN_MP_LSHD_C +# define BN_MP_SQR_C +# define BN_S_MP_ADD_C +# define BN_S_MP_SUB_C +#endif + +#if defined(BN_S_MP_MONTGOMERY_REDUCE_FAST_C) +# define BN_MP_CLAMP_C +# define BN_MP_CMP_MAG_C +# define BN_MP_GROW_C +# define BN_S_MP_SUB_C #endif -#if defined(BN_MP_ZERO_C) +#if defined(BN_S_MP_MUL_DIGS_C) +# define BN_MP_CLAMP_C +# define BN_MP_CLEAR_C +# define BN_MP_EXCH_C +# define BN_MP_INIT_SIZE_C +# define BN_S_MP_MUL_DIGS_FAST_C #endif -#if defined(BN_PRIME_TAB_C) +#if defined(BN_S_MP_MUL_DIGS_FAST_C) +# define BN_MP_CLAMP_C +# define BN_MP_GROW_C #endif -#if defined(BN_REVERSE_C) +#if defined(BN_S_MP_MUL_HIGH_DIGS_C) +# define BN_MP_CLAMP_C +# define BN_MP_CLEAR_C +# define BN_MP_EXCH_C +# define BN_MP_INIT_SIZE_C +# define BN_S_MP_MUL_HIGH_DIGS_FAST_C #endif -#if defined(BN_S_MP_ADD_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C +#if defined(BN_S_MP_MUL_HIGH_DIGS_FAST_C) +# define BN_MP_CLAMP_C +# define BN_MP_GROW_C #endif -#if defined(BN_S_MP_EXPTMOD_C) - #define BN_MP_COUNT_BITS_C - #define BN_MP_INIT_C - #define BN_MP_CLEAR_C - #define BN_MP_REDUCE_SETUP_C - #define BN_MP_REDUCE_C - #define BN_MP_REDUCE_2K_SETUP_L_C - #define BN_MP_REDUCE_2K_L_C - #define BN_MP_MOD_C - #define BN_MP_COPY_C - #define BN_MP_SQR_C - #define BN_MP_MUL_C - #define BN_MP_SET_C - #define BN_MP_EXCH_C +#if defined(BN_S_MP_PRIME_IS_DIVISIBLE_C) +# define BN_MP_MOD_D_C #endif -#if defined(BN_S_MP_MUL_DIGS_C) - #define BN_FAST_S_MP_MUL_DIGS_C - #define BN_MP_INIT_SIZE_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C +#if defined(BN_S_MP_RAND_JENKINS_C) +# define BN_S_MP_RAND_JENKINS_INIT_C #endif -#if defined(BN_S_MP_MUL_HIGH_DIGS_C) - #define BN_FAST_S_MP_MUL_HIGH_DIGS_C - #define BN_MP_INIT_SIZE_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C +#if defined(BN_S_MP_RAND_PLATFORM_C) #endif -#if defined(BN_S_MP_SQR_C) - #define BN_MP_INIT_SIZE_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C +#if defined(BN_S_MP_REVERSE_C) #endif -#if defined(BN_S_MP_SUB_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C +#if defined(BN_S_MP_SQR_C) +# define BN_MP_CLAMP_C +# define BN_MP_CLEAR_C +# define BN_MP_EXCH_C +# define BN_MP_INIT_SIZE_C #endif -#if defined(BNCORE_C) +#if defined(BN_S_MP_SQR_FAST_C) +# define BN_MP_CLAMP_C +# define BN_MP_GROW_C #endif +#if defined(BN_S_MP_SUB_C) +# define BN_MP_CLAMP_C +# define BN_MP_GROW_C +#endif + +#if defined(BN_S_MP_TOOM_MUL_C) +# define BN_MP_ADD_C +# define BN_MP_CLAMP_C +# define BN_MP_CLEAR_C +# define BN_MP_CLEAR_MULTI_C +# define BN_MP_DIV_2_C +# define BN_MP_DIV_3_C +# define BN_MP_INIT_MULTI_C +# define BN_MP_INIT_SIZE_C +# define BN_MP_LSHD_C +# define BN_MP_MUL_2_C +# define BN_MP_MUL_C +# define BN_MP_SUB_C +#endif + +#if defined(BN_S_MP_TOOM_SQR_C) +# define BN_MP_ADD_C +# define BN_MP_CLAMP_C +# define BN_MP_CLEAR_C +# define BN_MP_DIV_2_C +# define BN_MP_INIT_C +# define BN_MP_INIT_SIZE_C +# define BN_MP_LSHD_C +# define BN_MP_MUL_2_C +# define BN_MP_MUL_C +# define BN_MP_SQR_C +# define BN_MP_SUB_C +#endif + +#ifdef LTM_INSIDE +#undef LTM_INSIDE #ifdef LTM3 -#define LTM_LAST +# define LTM_LAST #endif + #include "tommath_superclass.h" #include "tommath_class.h" #else -#define LTM_LAST +# define LTM_LAST #endif /* Dropbear doesn't need these. */ @@ -1061,18 +1312,13 @@ #undef BN_MP_KARATSUBA_SQR_C #undef BN_MP_TOOM_MUL_C #undef BN_MP_TOOM_SQR_C - -void * m_malloc(size_t size); -/* m_calloc is limited in size, enough for libtomcrypt */ -void * m_calloc(size_t nmemb, size_t size); -void * m_realloc(void* ptr, size_t size); -void m_free_direct(void* ptr); - -#define XMALLOC m_malloc -#define XFREE m_free_direct -#define XREALLOC m_realloc -#define XCALLOC m_calloc - -/* $Source$ */ -/* $Revision$ */ -/* $Date$ */ +#undef BN_S_MP_KARATSUBA_MUL_C +#undef BN_S_MP_KARATSUBA_SQR_C +#undef BN_S_MP_TOOM_MUL_C +#undef BN_S_MP_TOOM_SQR_C + +#include "dbmalloc.h" +#define MP_MALLOC m_malloc +#define MP_FREE m_free_ltm +#define MP_REALLOC m_realloc_ltm +#define MP_CALLOC m_calloc diff --git a/libtommath/tommath_cutoffs.h b/libtommath/tommath_cutoffs.h new file mode 100644 index 0000000..a65a9b3 --- /dev/null +++ b/libtommath/tommath_cutoffs.h @@ -0,0 +1,13 @@ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +/* + Current values evaluated on an AMD A8-6600K (64-bit). + Type "make tune" to optimize them for your machine but + be aware that it may take a long time. It took 2:30 minutes + on the aforementioned machine for example. + */ + +#define MP_DEFAULT_KARATSUBA_MUL_CUTOFF 80 +#define MP_DEFAULT_KARATSUBA_SQR_CUTOFF 120 +#define MP_DEFAULT_TOOM_MUL_CUTOFF 350 +#define MP_DEFAULT_TOOM_SQR_CUTOFF 400 diff --git a/libtommath/tommath_private.h b/libtommath/tommath_private.h index aeda684..1a0096f 100644 --- a/libtommath/tommath_private.h +++ b/libtommath/tommath_private.h @@ -1,123 +1,303 @@ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://math.libtomcrypt.com - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + #ifndef TOMMATH_PRIV_H_ #define TOMMATH_PRIV_H_ -#include <tommath.h> -#include <ctype.h> +#include "tommath.h" +#include "tommath_class.h" -#ifndef MIN - #define MIN(x,y) (((x) < (y)) ? (x) : (y)) +/* + * Private symbols + * --------------- + * + * On Unix symbols can be marked as hidden if libtommath is compiled + * as a shared object. By default, symbols are visible. + * As of now, this feature is opt-in via the MP_PRIVATE_SYMBOLS define. + * + * On Win32 a .def file must be used to specify the exported symbols. + */ +#if defined (MP_PRIVATE_SYMBOLS) && defined(__GNUC__) && __GNUC__ >= 4 +# define MP_PRIVATE __attribute__ ((visibility ("hidden"))) +#else +# define MP_PRIVATE #endif -#ifndef MAX - #define MAX(x,y) (((x) > (y)) ? (x) : (y)) +/* Hardening libtommath + * -------------------- + * + * By default memory is zeroed before calling + * MP_FREE to avoid leaking data. This is good + * practice in cryptographical applications. + * + * Note however that memory allocators used + * in cryptographical applications can often + * be configured by itself to clear memory, + * rendering the clearing in tommath unnecessary. + * See for example https://github.com/GrapheneOS/hardened_malloc + * and the option CONFIG_ZERO_ON_FREE. + * + * Furthermore there are applications which + * value performance more and want this + * feature to be disabled. For such applications + * define MP_NO_ZERO_ON_FREE during compilation. + */ +#ifdef MP_NO_ZERO_ON_FREE +# define MP_FREE_BUFFER(mem, size) MP_FREE((mem), (size)) +# define MP_FREE_DIGITS(mem, digits) MP_FREE((mem), sizeof (mp_digit) * (size_t)(digits)) +#else +# define MP_FREE_BUFFER(mem, size) \ +do { \ + size_t fs_ = (size); \ + void* fm_ = (mem); \ + if (fm_ != NULL) { \ + MP_ZERO_BUFFER(fm_, fs_); \ + MP_FREE(fm_, fs_); \ + } \ +} while (0) +# define MP_FREE_DIGITS(mem, digits) \ +do { \ + int fd_ = (digits); \ + void* fm_ = (mem); \ + if (fm_ != NULL) { \ + size_t fs_ = sizeof (mp_digit) * (size_t)fd_; \ + MP_ZERO_BUFFER(fm_, fs_); \ + MP_FREE(fm_, fs_); \ + } \ +} while (0) #endif -#ifdef __cplusplus -extern "C" { - -/* C++ compilers don't like assigning void * to mp_digit * */ -#define OPT_CAST(x) (x *) - +#ifdef MP_USE_MEMSET +# include <string.h> +# define MP_ZERO_BUFFER(mem, size) memset((mem), 0, (size)) +# define MP_ZERO_DIGITS(mem, digits) \ +do { \ + int zd_ = (digits); \ + if (zd_ > 0) { \ + memset((mem), 0, sizeof(mp_digit) * (size_t)zd_); \ + } \ +} while (0) #else +# define MP_ZERO_BUFFER(mem, size) \ +do { \ + size_t zs_ = (size); \ + char* zm_ = (char*)(mem); \ + while (zs_-- > 0u) { \ + *zm_++ = '\0'; \ + } \ +} while (0) +# define MP_ZERO_DIGITS(mem, digits) \ +do { \ + int zd_ = (digits); \ + mp_digit* zm_ = (mem); \ + while (zd_-- > 0) { \ + *zm_++ = 0; \ + } \ +} while (0) +#endif -/* C on the other hand doesn't care */ -#define OPT_CAST(x) +/* Tunable cutoffs + * --------------- + * + * - In the default settings, a cutoff X can be modified at runtime + * by adjusting the corresponding X_CUTOFF variable. + * + * - Tunability of the library can be disabled at compile time + * by defining the MP_FIXED_CUTOFFS macro. + * + * - There is an additional file tommath_cutoffs.h, which defines + * the default cutoffs. These can be adjusted manually or by the + * autotuner. + * + */ +#ifdef MP_FIXED_CUTOFFS +# include "tommath_cutoffs.h" +# define MP_KARATSUBA_MUL_CUTOFF MP_DEFAULT_KARATSUBA_MUL_CUTOFF +# define MP_KARATSUBA_SQR_CUTOFF MP_DEFAULT_KARATSUBA_SQR_CUTOFF +# define MP_TOOM_MUL_CUTOFF MP_DEFAULT_TOOM_MUL_CUTOFF +# define MP_TOOM_SQR_CUTOFF MP_DEFAULT_TOOM_SQR_CUTOFF +#else +# define MP_KARATSUBA_MUL_CUTOFF KARATSUBA_MUL_CUTOFF +# define MP_KARATSUBA_SQR_CUTOFF KARATSUBA_SQR_CUTOFF +# define MP_TOOM_MUL_CUTOFF TOOM_MUL_CUTOFF +# define MP_TOOM_SQR_CUTOFF TOOM_SQR_CUTOFF #endif /* define heap macros */ -#ifndef XMALLOC - /* default to libc stuff */ - #define XMALLOC malloc - #define XFREE free - #define XREALLOC realloc - #define XCALLOC calloc +#ifndef MP_MALLOC +/* default to libc stuff */ +# include <stdlib.h> +# define MP_MALLOC(size) malloc(size) +# define MP_REALLOC(mem, oldsize, newsize) realloc((mem), (newsize)) +# define MP_CALLOC(nmemb, size) calloc((nmemb), (size)) +# define MP_FREE(mem, size) free(mem) #else - /* prototypes for our heap functions */ - extern void *XMALLOC(size_t n); - extern void *XREALLOC(void *p, size_t n); - extern void *XCALLOC(size_t n, size_t s); - extern void XFREE(void *p); +/* prototypes for our heap functions */ +extern void *MP_MALLOC(size_t size); +extern void *MP_REALLOC(void *mem, size_t oldsize, size_t newsize); +extern void *MP_CALLOC(size_t nmemb, size_t size); +extern void MP_FREE(void *mem, size_t size); #endif -/* lowlevel functions, do not call! */ -int s_mp_add(mp_int *a, mp_int *b, mp_int *c); -int s_mp_sub(mp_int *a, mp_int *b, mp_int *c); -#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1) -int fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs); -int s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs); -int fast_s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs); -int s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs); -int fast_s_mp_sqr(mp_int *a, mp_int *b); -int s_mp_sqr(mp_int *a, mp_int *b); -int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c); -int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c); -int mp_karatsuba_sqr(mp_int *a, mp_int *b); -int mp_toom_sqr(mp_int *a, mp_int *b); -int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c); -int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c); -int fast_mp_montgomery_reduce(mp_int *x, mp_int *n, mp_digit rho); -int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int redmode); -int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode); -void bn_reverse(unsigned char *s, int len); - -extern const char *mp_s_rmap; - -/* Fancy macro to set an MPI from another type. - * There are several things assumed: - * x is the counter and unsigned - * a is the pointer to the MPI - * b is the original value that should be set in the MPI. - */ -#define MP_SET_XLONG(func_name, type) \ -int func_name (mp_int * a, type b) \ -{ \ - unsigned int x; \ - int res; \ - \ - mp_zero (a); \ - \ - /* set four bits at a time */ \ - for (x = 0; x < (sizeof(type) * 2u); x++) { \ - /* shift the number up four bits */ \ - if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) { \ - return res; \ - } \ - \ - /* OR in the top four bits of the source */ \ - a->dp[0] |= (b >> ((sizeof(type) * 8u) - 4u)) & 15u; \ - \ - /* shift the source up to the next four bits */ \ - b <<= 4; \ - \ - /* ensure that digits are not clamped off */ \ - a->used += 1; \ - } \ - mp_clamp (a); \ - return MP_OKAY; \ -} - -#ifdef __cplusplus - } +/* feature detection macro */ +#ifdef _MSC_VER +/* Prevent false positive: not enough arguments for function-like macro invocation */ +#pragma warning(disable: 4003) #endif +#define MP_STRINGIZE(x) MP__STRINGIZE(x) +#define MP__STRINGIZE(x) ""#x"" +#define MP_HAS(x) (sizeof(MP_STRINGIZE(BN_##x##_C)) == 1u) + +/* TODO: Remove private_mp_word as soon as deprecated mp_word is removed from tommath. */ +#undef mp_word +typedef private_mp_word mp_word; + +#define MP_MIN(x, y) (((x) < (y)) ? (x) : (y)) +#define MP_MAX(x, y) (((x) > (y)) ? (x) : (y)) + +/* Static assertion */ +#define MP_STATIC_ASSERT(msg, cond) typedef char mp_static_assert_##msg[(cond) ? 1 : -1]; +/* ---> Basic Manipulations <--- */ +#define MP_IS_ZERO(a) ((a)->used == 0) +#define MP_IS_EVEN(a) (((a)->used == 0) || (((a)->dp[0] & 1u) == 0u)) +#define MP_IS_ODD(a) (((a)->used > 0) && (((a)->dp[0] & 1u) == 1u)) + +#define MP_SIZEOF_BITS(type) ((size_t)CHAR_BIT * sizeof(type)) +#define MP_MAXFAST (int)(1uL << (MP_SIZEOF_BITS(mp_word) - (2u * (size_t)MP_DIGIT_BIT))) + +/* TODO: Remove PRIVATE_MP_WARRAY as soon as deprecated MP_WARRAY is removed from tommath.h */ +#undef MP_WARRAY +#define MP_WARRAY PRIVATE_MP_WARRAY + +/* TODO: Remove PRIVATE_MP_PREC as soon as deprecated MP_PREC is removed from tommath.h */ +#ifdef PRIVATE_MP_PREC +# undef MP_PREC +# define MP_PREC PRIVATE_MP_PREC #endif +/* Minimum number of available digits in mp_int, MP_PREC >= MP_MIN_PREC */ +#define MP_MIN_PREC ((((int)MP_SIZEOF_BITS(long long) + MP_DIGIT_BIT) - 1) / MP_DIGIT_BIT) -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ +MP_STATIC_ASSERT(prec_geq_min_prec, MP_PREC >= MP_MIN_PREC) + +/* random number source */ +extern MP_PRIVATE mp_err(*s_mp_rand_source)(void *out, size_t size); + +/* lowlevel functions, do not call! */ +MP_PRIVATE mp_bool s_mp_get_bit(const mp_int *a, unsigned int b); +MP_PRIVATE mp_err s_mp_add(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; +MP_PRIVATE mp_err s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; +MP_PRIVATE mp_err s_mp_mul_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int digs) MP_WUR; +MP_PRIVATE mp_err s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) MP_WUR; +MP_PRIVATE mp_err s_mp_mul_high_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int digs) MP_WUR; +MP_PRIVATE mp_err s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) MP_WUR; +MP_PRIVATE mp_err s_mp_sqr_fast(const mp_int *a, mp_int *b) MP_WUR; +MP_PRIVATE mp_err s_mp_sqr(const mp_int *a, mp_int *b) MP_WUR; +MP_PRIVATE mp_err s_mp_balance_mul(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; +MP_PRIVATE mp_err s_mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; +MP_PRIVATE mp_err s_mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; +MP_PRIVATE mp_err s_mp_karatsuba_sqr(const mp_int *a, mp_int *b) MP_WUR; +MP_PRIVATE mp_err s_mp_toom_sqr(const mp_int *a, mp_int *b) MP_WUR; +MP_PRIVATE mp_err s_mp_invmod_fast(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; +MP_PRIVATE mp_err s_mp_invmod_slow(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; +MP_PRIVATE mp_err s_mp_montgomery_reduce_fast(mp_int *x, const mp_int *n, mp_digit rho) MP_WUR; +MP_PRIVATE mp_err s_mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode) MP_WUR; +MP_PRIVATE mp_err s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode) MP_WUR; +MP_PRIVATE mp_err s_mp_rand_platform(void *p, size_t n) MP_WUR; +MP_PRIVATE mp_err s_mp_prime_random_ex(mp_int *a, int t, int size, int flags, private_mp_prime_callback cb, void *dat); +MP_PRIVATE void s_mp_reverse(unsigned char *s, size_t len); +MP_PRIVATE mp_err s_mp_prime_is_divisible(const mp_int *a, mp_bool *result); + +/* TODO: jenkins prng is not thread safe as of now */ +MP_PRIVATE mp_err s_mp_rand_jenkins(void *p, size_t n) MP_WUR; +MP_PRIVATE void s_mp_rand_jenkins_init(uint64_t seed); + +extern MP_PRIVATE const char *const mp_s_rmap; +extern MP_PRIVATE const uint8_t mp_s_rmap_reverse[]; +extern MP_PRIVATE const size_t mp_s_rmap_reverse_sz; +extern MP_PRIVATE const mp_digit *s_mp_prime_tab; + +/* deprecated functions */ +MP_DEPRECATED(s_mp_invmod_fast) mp_err fast_mp_invmod(const mp_int *a, const mp_int *b, mp_int *c); +MP_DEPRECATED(s_mp_montgomery_reduce_fast) mp_err fast_mp_montgomery_reduce(mp_int *x, const mp_int *n, + mp_digit rho); +MP_DEPRECATED(s_mp_mul_digs_fast) mp_err fast_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, + int digs); +MP_DEPRECATED(s_mp_mul_high_digs_fast) mp_err fast_s_mp_mul_high_digs(const mp_int *a, const mp_int *b, + mp_int *c, + int digs); +MP_DEPRECATED(s_mp_sqr_fast) mp_err fast_s_mp_sqr(const mp_int *a, mp_int *b); +MP_DEPRECATED(s_mp_balance_mul) mp_err mp_balance_mul(const mp_int *a, const mp_int *b, mp_int *c); +MP_DEPRECATED(s_mp_exptmod_fast) mp_err mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, + mp_int *Y, + int redmode); +MP_DEPRECATED(s_mp_invmod_slow) mp_err mp_invmod_slow(const mp_int *a, const mp_int *b, mp_int *c); +MP_DEPRECATED(s_mp_karatsuba_mul) mp_err mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c); +MP_DEPRECATED(s_mp_karatsuba_sqr) mp_err mp_karatsuba_sqr(const mp_int *a, mp_int *b); +MP_DEPRECATED(s_mp_toom_mul) mp_err mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c); +MP_DEPRECATED(s_mp_toom_sqr) mp_err mp_toom_sqr(const mp_int *a, mp_int *b); +MP_DEPRECATED(s_mp_reverse) void bn_reverse(unsigned char *s, int len); + +#define MP_GET_ENDIANNESS(x) \ + do{\ + int16_t n = 0x1; \ + char *p = (char *)&n; \ + x = (p[0] == '\x01') ? MP_LITTLE_ENDIAN : MP_BIG_ENDIAN; \ + } while (0) + +/* code-generating macros */ +#define MP_SET_UNSIGNED(name, type) \ + void name(mp_int * a, type b) \ + { \ + int i = 0; \ + while (b != 0u) { \ + a->dp[i++] = ((mp_digit)b & MP_MASK); \ + if (MP_SIZEOF_BITS(type) <= MP_DIGIT_BIT) { break; } \ + b >>= ((MP_SIZEOF_BITS(type) <= MP_DIGIT_BIT) ? 0 : MP_DIGIT_BIT); \ + } \ + a->used = i; \ + a->sign = MP_ZPOS; \ + MP_ZERO_DIGITS(a->dp + a->used, a->alloc - a->used); \ + } + +#define MP_SET_SIGNED(name, uname, type, utype) \ + void name(mp_int * a, type b) \ + { \ + uname(a, (b < 0) ? -(utype)b : (utype)b); \ + if (b < 0) { a->sign = MP_NEG; } \ + } + +#define MP_INIT_INT(name , set, type) \ + mp_err name(mp_int * a, type b) \ + { \ + mp_err err; \ + if ((err = mp_init(a)) != MP_OKAY) { \ + return err; \ + } \ + set(a, b); \ + return MP_OKAY; \ + } + +#define MP_GET_MAG(name, type) \ + type name(const mp_int* a) \ + { \ + unsigned i = MP_MIN((unsigned)a->used, (unsigned)((MP_SIZEOF_BITS(type) + MP_DIGIT_BIT - 1) / MP_DIGIT_BIT)); \ + type res = 0u; \ + while (i --> 0u) { \ + res <<= ((MP_SIZEOF_BITS(type) <= MP_DIGIT_BIT) ? 0 : MP_DIGIT_BIT); \ + res |= (type)a->dp[i]; \ + if (MP_SIZEOF_BITS(type) <= MP_DIGIT_BIT) { break; } \ + } \ + return res; \ + } + +#define MP_GET_SIGNED(name, mag, type, utype) \ + type name(const mp_int* a) \ + { \ + utype res = mag(a); \ + return (a->sign == MP_NEG) ? (type)-res : (type)res; \ + } + +#endif diff --git a/libtommath/tommath_superclass.h b/libtommath/tommath_superclass.h index a2f4d93..d88bce9 100644 --- a/libtommath/tommath_superclass.h +++ b/libtommath/tommath_superclass.h @@ -1,10 +1,16 @@ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + /* super class file for PK algos */ /* default ... include all MPI */ +#ifndef LTM_NOTHING #define LTM_ALL +#endif /* RSA only (does not support DH/DSA/ECC) */ /* #define SC_RSA_1 */ +/* #define SC_RSA_1_WITH_TESTS */ /* For reference.... On an Athlon64 optimizing for speed... @@ -12,65 +18,93 @@ */ +#ifdef SC_RSA_1_WITH_TESTS +# define BN_MP_ERROR_TO_STRING_C +# define BN_MP_FREAD_C +# define BN_MP_FWRITE_C +# define BN_MP_INCR_C +# define BN_MP_ISEVEN_C +# define BN_MP_ISODD_C +# define BN_MP_NEG_C +# define BN_MP_PRIME_FROBENIUS_UNDERWOOD_C +# define BN_MP_RADIX_SIZE_C +# define BN_MP_RAND_C +# define BN_MP_REDUCE_C +# define BN_MP_REDUCE_2K_L_C +# define BN_MP_FROM_SBIN_C +# define BN_MP_ROOT_U32_C +# define BN_MP_SET_L_C +# define BN_MP_SET_UL_C +# define BN_MP_SBIN_SIZE_C +# define BN_MP_TO_RADIX_C +# define BN_MP_TO_SBIN_C +# define BN_S_MP_RAND_JENKINS_C +# define BN_S_MP_RAND_PLATFORM_C +#endif + /* Works for RSA only, mpi.o is 68KiB */ -#ifdef SC_RSA_1 - #define BN_MP_SHRINK_C - #define BN_MP_LCM_C - #define BN_MP_PRIME_RANDOM_EX_C - #define BN_MP_INVMOD_C - #define BN_MP_GCD_C - #define BN_MP_MOD_C - #define BN_MP_MULMOD_C - #define BN_MP_ADDMOD_C - #define BN_MP_EXPTMOD_C - #define BN_MP_SET_INT_C - #define BN_MP_INIT_MULTI_C - #define BN_MP_CLEAR_MULTI_C - #define BN_MP_UNSIGNED_BIN_SIZE_C - #define BN_MP_TO_UNSIGNED_BIN_C - #define BN_MP_MOD_D_C - #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C - #define BN_REVERSE_C - #define BN_PRIME_TAB_C +#if defined(SC_RSA_1) || defined (SC_RSA_1_WITH_TESTS) +# define BN_CUTOFFS_C +# define BN_MP_ADDMOD_C +# define BN_MP_CLEAR_MULTI_C +# define BN_MP_EXPTMOD_C +# define BN_MP_GCD_C +# define BN_MP_INIT_MULTI_C +# define BN_MP_INVMOD_C +# define BN_MP_LCM_C +# define BN_MP_MOD_C +# define BN_MP_MOD_D_C +# define BN_MP_MULMOD_C +# define BN_MP_PRIME_IS_PRIME_C +# define BN_MP_PRIME_RABIN_MILLER_TRIALS_C +# define BN_MP_PRIME_RAND_C +# define BN_MP_RADIX_SMAP_C +# define BN_MP_SET_INT_C +# define BN_MP_SHRINK_C +# define BN_MP_TO_UNSIGNED_BIN_C +# define BN_MP_UNSIGNED_BIN_SIZE_C +# define BN_PRIME_TAB_C +# define BN_S_MP_REVERSE_C - /* other modifiers */ - #define BN_MP_DIV_SMALL /* Slower division, not critical */ +/* other modifiers */ +# define BN_MP_DIV_SMALL /* Slower division, not critical */ - /* here we are on the last pass so we turn things off. The functions classes are still there - * but we remove them specifically from the build. This also invokes tweaks in functions - * like removing support for even moduli, etc... - */ -#ifdef LTM_LAST - #undef BN_MP_TOOM_MUL_C - #undef BN_MP_TOOM_SQR_C - #undef BN_MP_KARATSUBA_MUL_C - #undef BN_MP_KARATSUBA_SQR_C - #undef BN_MP_REDUCE_C - #undef BN_MP_REDUCE_SETUP_C - #undef BN_MP_DR_IS_MODULUS_C - #undef BN_MP_DR_SETUP_C - #undef BN_MP_DR_REDUCE_C - #undef BN_MP_REDUCE_IS_2K_C - #undef BN_MP_REDUCE_2K_SETUP_C - #undef BN_MP_REDUCE_2K_C - #undef BN_S_MP_EXPTMOD_C - #undef BN_MP_DIV_3_C - #undef BN_S_MP_MUL_HIGH_DIGS_C - #undef BN_FAST_S_MP_MUL_HIGH_DIGS_C - #undef BN_FAST_MP_INVMOD_C - /* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold - * which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines] - * which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without - * trouble. - */ - #undef BN_S_MP_MUL_DIGS_C - #undef BN_S_MP_SQR_C - #undef BN_MP_MONTGOMERY_REDUCE_C -#endif +/* here we are on the last pass so we turn things off. The functions classes are still there + * but we remove them specifically from the build. This also invokes tweaks in functions + * like removing support for even moduli, etc... + */ +# ifdef LTM_LAST +# undef BN_MP_DR_IS_MODULUS_C +# undef BN_MP_DR_SETUP_C +# undef BN_MP_DR_REDUCE_C +# undef BN_MP_DIV_3_C +# undef BN_MP_REDUCE_2K_SETUP_C +# undef BN_MP_REDUCE_2K_C +# undef BN_MP_REDUCE_IS_2K_C +# undef BN_MP_REDUCE_SETUP_C +# undef BN_S_MP_BALANCE_MUL_C +# undef BN_S_MP_EXPTMOD_C +# undef BN_S_MP_INVMOD_FAST_C +# undef BN_S_MP_KARATSUBA_MUL_C +# undef BN_S_MP_KARATSUBA_SQR_C +# undef BN_S_MP_MUL_HIGH_DIGS_C +# undef BN_S_MP_MUL_HIGH_DIGS_FAST_C +# undef BN_S_MP_TOOM_MUL_C +# undef BN_S_MP_TOOM_SQR_C -#endif +# ifndef SC_RSA_1_WITH_TESTS +# undef BN_MP_REDUCE_C +# endif -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ +/* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold + * which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines] + * which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without + * trouble. + */ +# undef BN_MP_MONTGOMERY_REDUCE_C +# undef BN_S_MP_MUL_DIGS_C +# undef BN_S_MP_SQR_C +# endif + +#endif diff --git a/libtommath/updatemakes.sh b/libtommath/updatemakes.sh deleted file mode 100755 index 0f9520e..0000000 --- a/libtommath/updatemakes.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -bash genlist.sh > tmplist - -perl filter.pl makefile tmplist -sed -e 's/ *$//' < tmp.delme > makefile -rm -f tmp.delme - -perl filter.pl makefile.icc tmplist -sed -e 's/ *$//' < tmp.delme > makefile.icc -rm -f tmp.delme - -perl filter.pl makefile.shared tmplist -sed -e 's/ *$//' < tmp.delme > makefile.shared -rm -f tmp.delme - -perl filter.pl makefile.cygwin_dll tmplist -sed -e 's/ *$//' < tmp.delme > makefile.cygwin_dll -rm -f tmp.delme - -perl filter.pl makefile.bcc tmplist -sed -e 's/\.o /.obj /g' -e 's/ *$//' < tmp.delme > makefile.bcc -rm -f tmp.delme - -perl filter.pl makefile.msvc tmplist -sed -e 's/\.o /.obj /g' -e 's/ *$//' < tmp.delme > makefile.msvc -rm -f tmp.delme - -rm -f tmplist - -# ref: $Format:%D$ -# git commit: $Format:%H$ -# commit time: $Format:%ai$ |