diff --git a/deps/libtommath/.github/workflows/main.yml b/deps/libtommath/.github/workflows/main.yml index 2f0ef4e7..18a832bb 100644 --- a/deps/libtommath/.github/workflows/main.yml +++ b/deps/libtommath/.github/workflows/main.yml @@ -29,7 +29,7 @@ jobs: runs-on: ubuntu-20.04 container: texlive/texlive:latest-full steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: generate PDF run: | make docs V=1 @@ -70,6 +70,12 @@ jobs: # RSA superclass with tests (no sanitizer, but debug info) - { BUILDOPTIONS: '--with-cc=gcc --with-m64 --cflags=-DLTM_NOTHING --cflags=-DSC_RSA_1_WITH_TESTS --limit-valgrind', SANITIZER: '', COMPILE_DEBUG: '1', COMPILE_LTO: '0', CONV_WARNINGS: '', OTHERDEPS: '' } + # Build with small stack-size + - { BUILDOPTIONS: '--with-cc=gcc --with-m32 --with-m64 --cflags=-DMP_SMALL_STACK_SIZE', SANITIZER: '', COMPILE_DEBUG: '0', COMPILE_LTO: '0', CONV_WARNINGS: '', OTHERDEPS: 'gcc-multilib' } + - { BUILDOPTIONS: '--with-cc=clang-10 --with-m32 --with-m64 --cflags=-DMP_SMALL_STACK_SIZE --limit-valgrind', SANITIZER: '1', COMPILE_DEBUG: '0', COMPILE_LTO: '0', CONV_WARNINGS: '', OTHERDEPS: 'clang-10 llvm-10 libc6-dev-i386 gcc-multilib' } + - { BUILDOPTIONS: '--with-cc=gcc --with-m32 --with-m64 --cflags=-DMP_SMALL_STACK_SIZE --multithread --limit-valgrind', SANITIZER: '', COMPILE_DEBUG: '0', COMPILE_LTO: '0', CONV_WARNINGS: '', OTHERDEPS: 'libc6-dev-i386 gcc-multilib' } + - { BUILDOPTIONS: '--with-cc=clang-10 --with-m32 --with-m64 --cflags=-DMP_SMALL_STACK_SIZE --multithread', SANITIZER: '1', COMPILE_DEBUG: '0', COMPILE_LTO: '0', CONV_WARNINGS: '', OTHERDEPS: 'clang-10 llvm-10 gcc-multilib' } + # Test "autotuning", the automatic evaluation and setting of the Toom-Cook cut-offs. #- env: SANITIZER=1 BUILDOPTIONS='--with-cc=gcc-5 --cflags=-DMP_16BIT --limit-valgrind --make-option=tune' #- env: SANITIZER=1 BUILDOPTIONS='--with-cc=gcc-5 --cflags=-DMP_32BIT --limit-valgrind --make-option=tune' @@ -129,7 +135,7 @@ jobs: - { BUILDOPTIONS: '--with-cc=clang --cflags=-DMP_16BIT --limit-valgrind', SANITIZER: '1', COMPILE_DEBUG: '0', COMPILE_LTO: '0', CONV_WARNINGS: '', OTHERDEPS: 'clang llvm' } - { BUILDOPTIONS: '--with-cc=clang --cflags=-DMP_32BIT --limit-valgrind', SANITIZER: '1', COMPILE_DEBUG: '0', COMPILE_LTO: '0', CONV_WARNINGS: '', OTHERDEPS: 'clang llvm' } steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: install dependencies run: | sudo apt-get update -qq @@ -172,7 +178,7 @@ jobs: amalgam: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: install dependencies run: | make amalgamated_timing @@ -190,7 +196,7 @@ jobs: # Shared library build - { CMAKEOPTIONS: '-DBUILD_SHARED_LIBS=On' } steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: install dependencies run: | sudo apt-get update -qq diff --git a/deps/libtommath/.gitignore b/deps/libtommath/.gitignore index d2f01329..51f3eee2 100644 --- a/deps/libtommath/.gitignore +++ b/deps/libtommath/.gitignore @@ -29,6 +29,17 @@ mtest.exe mtest_opponent mtest_opponent.exe +2kprime +2kprime.exe +drprime +drprime.exe +mersenne +mersenne.exe +mont +mont.exe +pprime +pprime.exe + # ignore eclipse project files .cproject .project @@ -66,9 +77,11 @@ perf.data.old # ignore tommath_amalgam.c generated by make tommath_amalgam.c -# ignore file generated by make tune +# ignore file generated by make 'tune and friends' tuning_list etc/tune +2kprime.1 +drprimes.txt # ignore stuff generated by "make manual" and "make poster" *.aux diff --git a/deps/libtommath/CMakeLists.txt b/deps/libtommath/CMakeLists.txt index dfbcb0f2..014fb188 100644 --- a/deps/libtommath/CMakeLists.txt +++ b/deps/libtommath/CMakeLists.txt @@ -7,7 +7,7 @@ cmake_minimum_required(VERSION 3.10) project(libtommath - VERSION 1.2.0 + VERSION 1.3.0 DESCRIPTION "A free open source portable number theoretic multiple-precision integer (MPI) library written entirely in C." HOMEPAGE_URL "https://www.libtom.net/LibTomMath" LANGUAGES C) @@ -28,7 +28,9 @@ option(BUILD_TESTING "" OFF) include(CTest) include(sources.cmake) -# The only direct cmake argument for now +#----------------------------------------------------------------------------- +# Options +#----------------------------------------------------------------------------- option(BUILD_SHARED_LIBS "Build shared library and only the shared library if \"ON\", default is static" OFF) #----------------------------------------------------------------------------- @@ -122,7 +124,7 @@ if(COMPILE_LTO) if(COMPILER_SUPPORTS_LTO) set_property(TARGET ${PROJECT_NAME} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) else() - message(SEND_ERROR "This compiler does not support LTO. Reconfigure ${PROJECT_NAME} with -DCOMPILE_LTO=OFF.") + message(FATAL_ERROR "This compiler does not support LTO. Reconfigure ${PROJECT_NAME} with -DCOMPILE_LTO=OFF.") endif() endif() diff --git a/deps/libtommath/README.md b/deps/libtommath/README.md index 29e077f2..8ebdab70 100644 --- a/deps/libtommath/README.md +++ b/deps/libtommath/README.md @@ -30,8 +30,14 @@ Use those packages with caution and at your own discretion. 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 `doc/bn.tex` and available as PDF for each release. +This PDF is also created as build artifact on each CI run. + +There is also limited documentation in `tommath.h`. + +Originally the library contained a document, `tommath.pdf`, which describes the goals of the project and many of the algorithms used at the time. +This document has been removed since it can't be built anymore and nobody spent the time to fix and update it. +The latest valid update to that document was done in version [`0.39`](https://github.com/libtom/libtommath/releases/tag/0.39) of the library and it is contained within that tarball. 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. diff --git a/deps/libtommath/appveyor.yml b/deps/libtommath/appveyor.yml index 5accc261..d483d0e9 100644 --- a/deps/libtommath/appveyor.yml +++ b/deps/libtommath/appveyor.yml @@ -1,4 +1,4 @@ -version: 1.2.1-{build} +version: 1.3.0-{build} branches: only: - master @@ -11,6 +11,10 @@ image: - Visual Studio 2019 - Visual Studio 2017 - Visual Studio 2015 +environment: + matrix: + - CFLAGS_VAR: "" + CFLAGS_VAR_DLL: "CFLAGS=\"/Ox /MD /DLTM_TEST_DYNAMIC\"" build_script: - cmd: >- if "Visual Studio 2022"=="%APPVEYOR_BUILD_WORKER_IMAGE%" call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat" @@ -18,9 +22,9 @@ build_script: if "Visual Studio 2017"=="%APPVEYOR_BUILD_WORKER_IMAGE%" call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" if "Visual Studio 2015"=="%APPVEYOR_BUILD_WORKER_IMAGE%" call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64 if "Visual Studio 2015"=="%APPVEYOR_BUILD_WORKER_IMAGE%" call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86_amd64 - nmake -f makefile.msvc test.exe + nmake -f makefile.msvc test.exe %CFLAGS_VAR% nmake -f makefile.msvc clean-obj - nmake -f makefile.msvc test_dll.exe CFLAGS="/Ox /MD /DLTM_TEST_DYNAMIC" + nmake -f makefile.msvc test_dll.exe %CFLAGS_VAR_DLL% test_script: - cmd: test.exe - cmd: test_dll.exe diff --git a/deps/libtommath/changes.txt b/deps/libtommath/changes.txt index 2d8ff9f8..df2735da 100644 --- a/deps/libtommath/changes.txt +++ b/deps/libtommath/changes.txt @@ -1,3 +1,9 @@ +Mar 27th, 2024 +v1.3.0 + -- Deprecate more APIs which are replaced in develop (PR #572) + -- Add support for CMake (PR #573) + -- Add support for GitHub Actions (PR #573) + Sep 04th, 2023 v1.2.1 -- Bugfix release because of potential integer overflow diff --git a/deps/libtommath/demo/test.c b/deps/libtommath/demo/test.c index c5141ef7..2fa6e08d 100644 --- a/deps/libtommath/demo/test.c +++ b/deps/libtommath/demo/test.c @@ -1229,11 +1229,20 @@ LBL_ERR: static int test_mp_reduce_2k(void) { int ix, cnt; + bool is2k; mp_int a, b, c, d; DOR(mp_init_multi(&a, &b, &c, &d, NULL)); /* test mp_reduce_2k */ + + /* Algorithm as implemented does not work if the least significant digit is zero */ + DO(mp_2expt(&a, 100)); + DO(mp_sub_d(&a, 1, &a)); + DO(mp_sub_d(&a, MP_MASK, &a)); + is2k = mp_reduce_is_2k(&a); + EXPECT(!is2k); + for (cnt = 3; cnt <= 128; ++cnt) { mp_digit tmp; @@ -2446,12 +2455,101 @@ LBL_ERR: #define ONLY_PUBLIC_API_C #endif +#if !defined(LTM_TEST_MULTITHREAD) +#define SINGLE_THREADED_C +typedef uintptr_t thread_id_t; +#else +#define MULTI_THREADED_C +#if !defined(_WIN32) +#define MULTI_THREADED_PTHREAD_C +#include +typedef pthread_t thread_id_t; +#else +#define MULTI_THREADED_MSVC_C + +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0501 +#endif +#ifndef WINVER +#define WINVER 0x0501 +#endif + +#define WIN32_LEAN_AND_MEAN +#include +typedef HANDLE thread_id_t; +#endif +#endif + +#if !defined(MULTI_THREADED_PTHREAD_C) +extern int pthread_create(thread_id_t *, const void *, void *(*)(void *), void *); +extern int pthread_join(thread_id_t, void **); +#endif + +#if !defined(MULTI_THREADED_MSVC_C) +extern thread_id_t CreateThread(void *, size_t, unsigned long (*)(void *), void *, unsigned long, void *); +extern unsigned long WaitForSingleObject(thread_id_t hHandle, unsigned long dwMilliseconds); +#define INFINITE ((unsigned long)-1) +#endif + +struct test_fn { + const char *name; + int (*fn)(void); +}; + +struct thread_info { + thread_id_t thread_id; + const struct test_fn *t; + int ret; +}; + +static void run(struct thread_info *tinfo) +{ + tinfo->ret = tinfo->t->fn(); + + if (mp_warray_free() == -2) + tinfo->ret = EXIT_FAILURE; +} + +static void *run_pthread(void *arg) +{ + run(arg); + + return arg; +} + +static unsigned long run_msvc(void *arg) +{ + run(arg); + + return 0; +} + +static int thread_start(struct thread_info *info) +{ + if (MP_HAS(MULTI_THREADED_PTHREAD)) + return pthread_create(&info->thread_id, NULL, run_pthread, info); + if (MP_HAS(MULTI_THREADED_MSVC)) { + info->thread_id = CreateThread(NULL, 0, run_msvc, info, 0, NULL); + return info->thread_id == (thread_id_t)NULL ? -1 : 0; + } + return -1; +} + +static int thread_join(struct thread_info *info, struct thread_info **res) +{ + if (MP_HAS(MULTI_THREADED_PTHREAD)) + return pthread_join(info->thread_id, (void **)res); + if (MP_HAS(MULTI_THREADED_MSVC)) { + WaitForSingleObject(info->thread_id, INFINITE); + *res = info; + return 0; + } + return -1; +} + static int unit_tests(int argc, char **argv) { - static const struct { - const char *name; - int (*fn)(void); - } test[] = { + static const struct test_fn test[] = { #define T0(n) { #n, test_##n } #define T1(n, o) { #n, MP_HAS(o) ? test_##n : NULL } #define T2(n, o1, o2) { #n, (MP_HAS(o1) && MP_HAS(o2)) ? test_##n : NULL } @@ -2513,10 +2611,10 @@ static int unit_tests(int argc, char **argv) #undef T2 #undef T1 }; + struct thread_info test_threads[sizeof(test)/sizeof(test[0])], *res; unsigned long i, ok, fail, nop; uint64_t t; int j; - ok = fail = nop = 0; t = (uint64_t)time(NULL); @@ -2524,20 +2622,43 @@ static int unit_tests(int argc, char **argv) s_mp_rand_jenkins_init(t); mp_rand_source(s_mp_rand_jenkins); + if (MP_HAS(MP_SMALL_STACK_SIZE)) { + printf("Small-stack enabled\n\n"); + } + + if (MP_HAS(MULTI_THREADED)) { + printf("Multi-threading enabled\n\n"); + /* we ignore the fact that jenkins is not thread safe */ + for (i = 0; i < (sizeof(test) / sizeof(test[0])); ++i) { + test_threads[i].t = &test[i]; + EXPECT(thread_start(&test_threads[i]) == 0); + } + } + for (i = 0; i < (sizeof(test) / sizeof(test[0])); ++i) { - if (argc > 1) { - for (j = 1; j < argc; ++j) { - if (strstr(test[i].name, argv[j]) != NULL) { - break; + j = -1; + if (MP_HAS(SINGLE_THREADED)) { + if (argc > 1) { + for (j = 1; j < argc; ++j) { + if (strstr(test[i].name, argv[j]) != NULL) { + break; + } } + if (j == argc) continue; } - if (j == argc) continue; + + if (test[i].fn) + j = test[i].fn(); + } else if (MP_HAS(MULTI_THREADED)) { + EXPECT(thread_join(&test_threads[i], &res) == 0); + j = res->ret; } printf("TEST %s\n", test[i].name); + if (test[i].fn == NULL) { nop++; printf("NOP %s\n\n", test[i].name); - } else if (test[i].fn() == EXIT_SUCCESS) { + } else if (j == EXIT_SUCCESS) { ok++; printf("\n"); } else { @@ -2547,8 +2668,12 @@ static int unit_tests(int argc, char **argv) } fprintf(fail?stderr:stdout, "Tests OK/NOP/FAIL: %lu/%lu/%lu\n", ok, nop, fail); - if (fail != 0) return EXIT_FAILURE; - else return EXIT_SUCCESS; + EXPECT(mp_warray_free() != -2); + + if (fail == 0) + return EXIT_SUCCESS; +LBL_ERR: + return EXIT_FAILURE; } int main(int argc, char **argv) diff --git a/deps/libtommath/doc/bn.tex b/deps/libtommath/doc/bn.tex index 118a4700..63e71633 100644 --- a/deps/libtommath/doc/bn.tex +++ b/deps/libtommath/doc/bn.tex @@ -51,7 +51,7 @@ \begin{document} \frontmatter \pagestyle{empty} -\title{LibTomMath User Manual \\ v1.2.1} +\title{LibTomMath User Manual \\ v1.3.0} \author{LibTom Projects \\ www.libtom.net} \maketitle This text, the library and the accompanying textbook are all hereby placed in the public domain. @@ -352,6 +352,16 @@ which means they are to be defined only if \texttt{LTM\_LAST} has been defined. \end{center} \end{small} +\subsection{Small-Stack option} +\label{ch:SMALL_STACK_INTRO} +The library can be compiled with the symbol \texttt{MP\_SMALL\_STACK\_SIZE} defined, which results in +the temporary \texttt{MP\_WARRAY}-sized stack buffers being put on the heap. +This comes with one problem, namely: formerly promised thread-safety isn't given anymore. +Therefore if the Small-Stack option is enabled while doing multi threading, one shall always initialize +the library by calling \texttt{mp\_warray\_init()} once with the correct number of threads. + +C.f. \ref{ch:SMALL_STACK_API} for the API description and further details. + \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 @@ -428,7 +438,11 @@ environments. Fast RSA for example can be performed with as little as 8 Kibibyt \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. +libtommath.a). There is no library initialization required and the entire library is thread safe +if it is used in its default configuration. The small-stack option makes use of atomic operations +to maintain its internal state and therefore does not require locking, but it MUST be initialized +if used from multiple threads. For further information see \ref{ch:SMALL_STACK_INTRO} resp. +\ref{ch:SMALL_STACK_API}. \section{Return Codes} There are five possible return codes a function may return. @@ -813,6 +827,37 @@ int main(void) \end{alltt} \end{small} +\section{Small-Stack option} +\label{ch:SMALL_STACK_API} + +In case the \texttt{MP\_SMALL\_STACK\_SIZE} symbol is defined the following functions +can be useful. + +To initialize the internal structure the following function shall be called. + +\index{mp\_warray\_init} +\begin{alltt} +mp_err mp_warray_init(size_t n_alloc, bool preallocate); +\end{alltt} + +The flag \texttt{preallocate} controls whether the internal buffers -- +\texttt{n\_alloc} buffers of size \texttt{MP\_WARRAY} -- will be allocated when +\texttt{mp\_warray\_init()} is called, or whether they will be allocated when required. + +To free the internally allocated memory the following function shall be called. + +\index{mp\_warray\_free} +\begin{alltt} +int mp_warray_free(void); +\end{alltt} + + +Those two API functions are always available, even if the \texttt{MP\_SMALL\_STACK\_SIZE} option +has been disabled at compile time. +In that case \texttt{mp\_warray\_init()} will return \texttt{MP\_ERR} and \texttt{mp\_warray\_free()} +will return $-1$. + + \chapter{Basic Operations} \section{Copying} diff --git a/deps/libtommath/etc/2kprime.1 b/deps/libtommath/etc/2kprime.1 deleted file mode 100644 index c41ded1f..00000000 --- a/deps/libtommath/etc/2kprime.1 +++ /dev/null @@ -1,2 +0,0 @@ -256-bits (k = 36113) = 115792089237316195423570985008687907853269984665640564039457584007913129603823 -512-bits (k = 38117) = 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006045979 diff --git a/deps/libtommath/etc/2kprime.c b/deps/libtommath/etc/2kprime.c index 3a3e2830..5aa83abd 100644 --- a/deps/libtommath/etc/2kprime.c +++ b/deps/libtommath/etc/2kprime.c @@ -10,23 +10,24 @@ int main(void) size_t x; bool y; mp_int q, p; + mp_err err; FILE *out; clock_t t1; mp_digit z; - mp_init_multi(&q, &p, NULL); + if ((err = mp_init_multi(&q, &p, NULL)) != MP_OKAY) goto LTM_ERR; out = fopen("2kprime.1", "w"); if (out != NULL) { for (x = 0; x < (sizeof(sizes) / sizeof(sizes[0])); x++) { top: - mp_2expt(&q, sizes[x]); - mp_add_d(&q, 3uL, &q); + if ((err = mp_2expt(&q, sizes[x])) != MP_OKAY) goto LTM_ERR; + if ((err = mp_add_d(&q, 3uL, &q)) != MP_OKAY) goto LTM_ERR; z = -3; t1 = clock(); for (;;) { - mp_sub_d(&q, 4uL, &q); + if ((err = mp_sub_d(&q, 4uL, &q)) != MP_OKAY) goto LTM_ERR; z += 4uL; if (z > MP_MASK) { @@ -42,21 +43,21 @@ top: } /* quick test on q */ - mp_prime_is_prime(&q, 1, &y); + if ((err = mp_prime_is_prime(&q, 1, &y)) != MP_OKAY) goto LTM_ERR; if (!y) { continue; } /* find (q-1)/2 */ - mp_sub_d(&q, 1uL, &p); - mp_div_2(&p, &p); - mp_prime_is_prime(&p, 3, &y); + if ((err = mp_sub_d(&q, 1uL, &p)) != MP_OKAY) goto LTM_ERR; + if ((err = mp_div_2(&p, &p)) != MP_OKAY) goto LTM_ERR; + if ((err = mp_prime_is_prime(&p, 3, &y)) != MP_OKAY) goto LTM_ERR; if (!y) { continue; } /* test on q */ - mp_prime_is_prime(&q, 3, &y); + if ((err = mp_prime_is_prime(&q, 3, &y)) != MP_OKAY) goto LTM_ERR; if (!y) { continue; } @@ -69,13 +70,13 @@ top: goto top; } - mp_to_decimal(&q, buf, sizeof(buf)); + if ((err = mp_to_decimal(&q, buf, sizeof(buf))) != MP_OKAY) goto LTM_ERR; 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); } fclose(out); } - +LTM_ERR: return 0; } diff --git a/deps/libtommath/etc/drprime.c b/deps/libtommath/etc/drprime.c index 31dff4e9..e2e709b9 100644 --- a/deps/libtommath/etc/drprime.c +++ b/deps/libtommath/etc/drprime.c @@ -10,16 +10,17 @@ int main(void) char buf[4096]; FILE *out; mp_int a, b; + mp_err err; - mp_init(&a); - mp_init(&b); + if ((err = mp_init(&a)) != MP_OKAY) goto LTM_ERR; + if ((err = mp_init(&b)) != MP_OKAY) goto LTM_ERR; out = fopen("drprimes.txt", "w"); if (out != NULL) { for (x = 0; x < (int)(sizeof(sizes)/sizeof(sizes[0])); x++) { top: printf("Seeking a %d-bit safe prime\n", sizes[x] * MP_DIGIT_BIT); - mp_grow(&a, sizes[x]); + if ((err = mp_grow(&a, sizes[x])) != MP_OKAY) goto LTM_ERR; mp_zero(&a); for (y = 1; y < sizes[x]; y++) { a.dp[y] = MP_MASK; @@ -34,15 +35,15 @@ top: for (;;) { a.dp[0] += 4uL; if (a.dp[0] >= MP_MASK) break; - mp_prime_is_prime(&a, 1, &res); + if ((err = mp_prime_is_prime(&a, 1, &res)) != MP_OKAY) goto LTM_ERR; if (!res) continue; printf("."); fflush(stdout); - mp_sub_d(&a, 1uL, &b); - mp_div_2(&b, &b); - mp_prime_is_prime(&b, 3, &res); + if ((err = mp_sub_d(&a, 1uL, &b)) != MP_OKAY) goto LTM_ERR; + if ((err = mp_div_2(&b, &b)) != MP_OKAY) goto LTM_ERR; + if ((err = mp_prime_is_prime(&b, 3, &res)) != MP_OKAY) goto LTM_ERR; if (!res) continue; - mp_prime_is_prime(&a, 3, &res); + if ((err = mp_prime_is_prime(&a, 3, &res)) != MP_OKAY) goto LTM_ERR; if (res) break; } @@ -51,7 +52,7 @@ top: sizes[x] += 1; goto top; } else { - mp_to_decimal(&a, buf, sizeof(buf)); + if ((err = mp_to_decimal(&a, buf, sizeof(buf))) != MP_OKAY) goto LTM_ERR; printf("\n\np == %s\n\n", buf); fprintf(out, "%d-bit prime:\np == %s\n\n", mp_count_bits(&a), buf); fflush(out); @@ -60,6 +61,7 @@ top: fclose(out); } +LTM_ERR: mp_clear(&a); mp_clear(&b); diff --git a/deps/libtommath/etc/drprimes.txt b/deps/libtommath/etc/drprimes.txt deleted file mode 100644 index 7c97f67b..00000000 --- a/deps/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/deps/libtommath/etc/makefile b/deps/libtommath/etc/makefile index 52ad4753..0e178396 100644 --- a/deps/libtommath/etc/makefile +++ b/deps/libtommath/etc/makefile @@ -6,6 +6,8 @@ LTM_TUNE_CFLAGS = $(CFLAGS) $(LTM_CFLAGS) -Wall -W -Wextra -Wshadow -O3 -I../ # libname when you can't install the lib with install LIBNAME=../libtommath.a +all: pprime tune test_standalone mersenne drprime 2kprime mont + #provable primes pprime: pprime.o $(CC) $(LTM_TUNE_CFLAGS) pprime.o $(LIBNAME) -o pprime diff --git a/deps/libtommath/etc/mersenne.c b/deps/libtommath/etc/mersenne.c index 4d3939e3..f7487ecd 100644 --- a/deps/libtommath/etc/mersenne.c +++ b/deps/libtommath/etc/mersenne.c @@ -57,7 +57,9 @@ static mp_err is_mersenne(long s, bool *pp) /* if u == 0 then its prime */ if (mp_iszero(&u)) { - mp_prime_is_prime(&n, 8, pp); + if ((res = mp_prime_is_prime(&n, 8, pp)) != MP_OKAY) { + goto LBL_MU; + } if (!*pp) printf("FAILURE\n"); } diff --git a/deps/libtommath/etc/mont.c b/deps/libtommath/etc/mont.c index 4652410d..3d844496 100644 --- a/deps/libtommath/etc/mont.c +++ b/deps/libtommath/etc/mont.c @@ -7,10 +7,11 @@ int main(void) { mp_int modulus, R, p, pp; mp_digit mp; + mp_err err; int x, y; srand(time(NULL)); - mp_init_multi(&modulus, &R, &p, &pp, NULL); + if ((err = mp_init_multi(&modulus, &R, &p, &pp, NULL)) != MP_OKAY) goto LTM_ERR; /* loop through various sizes */ for (x = 4; x < 256; x++) { @@ -18,18 +19,20 @@ int main(void) fflush(stdout); /* make up the odd modulus */ - mp_rand(&modulus, x); + if ((err = mp_rand(&modulus, x)) != MP_OKAY) goto LTM_ERR; modulus.dp[0] |= 1uL; /* now find the R value */ - mp_montgomery_calc_normalization(&R, &modulus); - mp_montgomery_setup(&modulus, &mp); + if ((err = mp_montgomery_calc_normalization(&R, &modulus)) != MP_OKAY) goto LTM_ERR; + if ((err = mp_montgomery_setup(&modulus, &mp)) != MP_OKAY) goto LTM_ERR; /* 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); + /* p = random */ + if ((err = mp_rand(&p, x/2)) != MP_OKAY) goto LTM_ERR; + /* pp = R * p */ + if ((err = mp_mul(&p, &R, &pp)) != MP_OKAY) goto LTM_ERR; + if ((err = mp_montgomery_reduce(&pp, &modulus, mp)) != MP_OKAY) goto LTM_ERR; /* should be equal to p */ if (mp_cmp(&pp, &p) != MP_EQ) { @@ -40,5 +43,6 @@ int main(void) printf("PASSED\n"); } +LTM_ERR: return 0; } diff --git a/deps/libtommath/etc/pprime.c b/deps/libtommath/etc/pprime.c index 1d59cab7..7533a609 100644 --- a/deps/libtommath/etc/pprime.c +++ b/deps/libtommath/etc/pprime.c @@ -1,179 +1,40 @@ -/* Generates provable primes - * - * See http://gmail.com:8080/papers/pp.pdf for more info. +/* + * Generates provable primes * * Tom St Denis, tomstdenis@gmail.com, http://tom.gmail.com + * */ #include #include -#include "tommath_private.h" +#include "../tommath_private.h" -static int n_prime; -static FILE *primes; - -/* fast square root */ -static mp_digit i_sqrt(mp_word x) +static void mp_print(const char *s, const mp_int *a, int radix, FILE *stream) { - mp_word x1, x2; - - x2 = x; - do { - x1 = x2; - x2 = x1 - ((x1 * x1) - x) / (2u * x1); - } while (x1 != x2); - - if ((x1 * x1) > x) { - --x1; + mp_err err; + fputs(s, stream); + err = mp_fwrite(a, radix, stream); + if (err != MP_OKAY) { + fprintf(stderr,"mp_fwrite in mp_print failed. error = %s\n", mp_error_to_string(err)); + exit(EXIT_FAILURE); } - - return x1; + fputc('\n',stream); } - -/* generates a prime digit */ -static void gen_prime(void) +static mp_digit prime_digit(int bits) { - mp_digit r, x, y, next; - FILE *out; + mp_digit d = 0; + mp_int a; + mp_err err; - out = fopen("pprime.dat", "wb"); - if (out != NULL) { - - /* write first set of primes */ - /* *INDENT-OFF* */ - r = 3uL; fwrite(&r, 1uL, sizeof(mp_digit), out); - r = 5uL; fwrite(&r, 1uL, sizeof(mp_digit), out); - r = 7uL; fwrite(&r, 1uL, sizeof(mp_digit), out); - r = 11uL; fwrite(&r, 1uL, sizeof(mp_digit), out); - r = 13uL; fwrite(&r, 1uL, sizeof(mp_digit), out); - r = 17uL; fwrite(&r, 1uL, sizeof(mp_digit), out); - r = 19uL; fwrite(&r, 1uL, sizeof(mp_digit), out); - r = 23uL; fwrite(&r, 1uL, sizeof(mp_digit), out); - r = 29uL; fwrite(&r, 1uL, sizeof(mp_digit), out); - r = 31uL; fwrite(&r, 1uL, sizeof(mp_digit), out); - /* *INDENT-ON* */ - - /* get square root, since if 'r' is composite its factors must be < than this */ - y = i_sqrt(r); - next = (y + 1uL) * (y + 1uL); - - for (;;) { - do { - r += 2uL; /* next candidate */ - r &= MP_MASK; - if (r < 31uL) break; - - /* update sqrt ? */ - if (next <= r) { - ++y; - next = (y + 1uL) * (y + 1uL); - } - - /* loop if divisible by 3,5,7,11,13,17,19,23,29 */ - if ((r % 3uL) == 0uL) { - x = 0uL; - continue; - } - if ((r % 5uL) == 0uL) { - x = 0uL; - continue; - } - if ((r % 7uL) == 0uL) { - x = 0uL; - continue; - } - if ((r % 11uL) == 0uL) { - x = 0uL; - continue; - } - if ((r % 13uL) == 0uL) { - x = 0uL; - continue; - } - if ((r % 17uL) == 0uL) { - x = 0uL; - continue; - } - if ((r % 19uL) == 0uL) { - x = 0uL; - continue; - } - if ((r % 23uL) == 0uL) { - x = 0uL; - continue; - } - if ((r % 29uL) == 0uL) { - x = 0uL; - continue; - } - - /* now check if r is divisible by x + k={1,7,11,13,17,19,23,29} */ - for (x = 30uL; x <= y; x += 30uL) { - if ((r % (x + 1uL)) == 0uL) { - x = 0uL; - break; - } - if ((r % (x + 7uL)) == 0uL) { - x = 0uL; - break; - } - if ((r % (x + 11uL)) == 0uL) { - x = 0uL; - break; - } - if ((r % (x + 13uL)) == 0uL) { - x = 0uL; - break; - } - if ((r % (x + 17uL)) == 0uL) { - x = 0uL; - break; - } - if ((r % (x + 19uL)) == 0uL) { - x = 0uL; - break; - } - if ((r % (x + 23uL)) == 0uL) { - x = 0uL; - break; - } - if ((r % (x + 29uL)) == 0uL) { - x = 0uL; - break; - } - } - } while (x == 0uL); - if (r > 31uL) { - fwrite(&r, 1uL, sizeof(mp_digit), out); - printf("%9lu\r", r); - fflush(stdout); - } - if (r < 31uL) break; - } - - fclose(out); + if ((err = mp_init(&a)) != MP_OKAY) { + return 0; } -} -static void load_tab(void) -{ - primes = fopen("pprime.dat", "rb"); - if (primes == NULL) { - gen_prime(); - primes = fopen("pprime.dat", "rb"); - } - fseek(primes, 0L, SEEK_END); - n_prime = ftell(primes) / sizeof(mp_digit); -} + if ((err = mp_prime_rand(&a, 1, bits, false)) != MP_OKAY) goto LTM_ERR; + d = a.dp[0]; -static 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, 1uL, sizeof(mp_digit), primes); +LTM_ERR: + mp_clear(&a); return d; } @@ -182,230 +43,177 @@ static mp_digit prime_digit(void) static mp_err pprime(int k, int li, mp_int *p, mp_int *q) { mp_int a, b, c, n, x, y, z, v; - mp_err res; - int ii; - static const mp_digit bases[] = { 2, 3, 5, 7, 11, 13, 17, 19 }; + mp_err err = MP_OKAY; + int ii, bits; /* single digit ? */ - if (k <= (int) MP_DIGIT_BIT) { - mp_set(p, prime_digit()); + if (k < (int) MP_DIGIT_BIT) { + mp_set(p, prime_digit(k)); + if (mp_iszero(p)) { + return MP_VAL; + } return MP_OKAY; } - if ((res = mp_init(&c)) != MP_OKAY) { - return res; - } - - if ((res = mp_init(&v)) != MP_OKAY) { - goto LBL_C; + if ((err = mp_init_multi(&a, &b, &c, &n, &x, &y, &z, &v, NULL)) != MP_OKAY) { + return err; } /* 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; + if ((err = mp_read_radix(&v, "9NPvy2By/eZ0N6s68ky5K/8UTD0Q7fInhDK9BHnueH92HfzU4+U", 64)) != MP_OKAY) { + goto LTM_ERR; } /* 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; + mp_set(&a, prime_digit(MP_DIGIT_BIT)); + if (mp_iszero(&a)) { + err = MP_VAL; + goto LTM_ERR; } /* 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)); + bits = k - mp_count_bits(&a); + fprintf(stderr, "prime has %4d bits left\r", bits); fflush(stderr); top: - mp_set(&b, prime_digit()); + if (bits < MP_DIGIT_BIT) { + mp_set(&b, prime_digit(bits)); + } else { + mp_set(&b, prime_digit(MP_DIGIT_BIT)); + } + if (mp_iszero(&b)) { + err = MP_VAL; + goto LTM_ERR; + } /* 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; - } - + /* z = a * b */ + if ((err = mp_mul(&a, &b, &z)) != MP_OKAY) goto LTM_ERR; + /* c = a * b */ + if ((err = mp_copy(&z, &c)) != MP_OKAY) goto LTM_ERR; + /* z = 2 * a * b */ + if ((err = mp_mul_2(&z, &z)) != MP_OKAY) goto LTM_ERR; /* n = z + 1 */ - if ((res = mp_add_d(&z, 1uL, &n)) != MP_OKAY) { /* n = z + 1 */ - goto LBL_Z; - } + if ((err = mp_add_d(&z, 1uL, &n)) != MP_OKAY) goto LTM_ERR; + /* check (n, v) == 1; y = (n, v) */ + if ((err = mp_gcd(&n, &v, &y)) != MP_OKAY) goto LTM_ERR; - /* check (n, v) == 1 */ - if ((res = mp_gcd(&n, &v, &y)) != MP_OKAY) { /* y = (n, v) */ - goto LBL_Z; - } - - if (mp_cmp_d(&y, 1uL) != MP_EQ) + if (mp_cmp_d(&y, 1uL) != MP_EQ) { goto top; - + } + mp_set(&x, 2u); /* now try base x=bases[ii] */ for (ii = 0; ii < li; ii++) { - mp_set(&x, bases[ii]); + if ((err = mp_prime_next_prime(&x, -1, false)) != MP_OKAY) goto LTM_ERR; - /* compute x^a mod n */ - if ((res = mp_exptmod(&x, &a, &n, &y)) != MP_OKAY) { /* y = x^a mod n */ - goto LBL_Z; + /* compute x^a mod n; y = x^a mod n */ + if ((err = mp_exptmod(&x, &a, &n, &y)) != MP_OKAY) goto LTM_ERR; + /* if y == 1 loop */ + if (mp_cmp_d(&y, 1uL) == MP_EQ) { + continue; } + /* now x^2a mod n ; y = x^2a mod n*/ + if ((err = mp_sqrmod(&y, &n, &y)) != MP_OKAY) goto LTM_ERR; + + if (mp_cmp_d(&y, 1uL) == MP_EQ) { + continue; + } + + /* compute x^b mod n ; y = x^b mod n*/ + if ((err = mp_exptmod(&x, &b, &n, &y)) != MP_OKAY) goto LTM_ERR; /* if y == 1 loop */ - if (mp_cmp_d(&y, 1uL) == MP_EQ) + if (mp_cmp_d(&y, 1uL) == 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, 1uL) == MP_EQ) - continue; + /* now x^2b mod n; y = x^2b mod n */ + if ((err = mp_sqrmod(&y, &n, &y)) != MP_OKAY) goto LTM_ERR; - /* compute x^b mod n */ - if ((res = mp_exptmod(&x, &b, &n, &y)) != MP_OKAY) { /* y = x^b mod n */ - goto LBL_Z; + if (mp_cmp_d(&y, 1uL) == MP_EQ) { + continue; } + /* compute x^c mod n == x^ab mod n ; y = x^ab mod n */ + if ((err = mp_exptmod(&x, &c, &n, &y)) != MP_OKAY) goto LTM_ERR; /* if y == 1 loop */ - if (mp_cmp_d(&y, 1uL) == MP_EQ) + if (mp_cmp_d(&y, 1uL) == 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, 1uL) == 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, 1uL) == 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; } + /* now compute (x^c mod n)^2 ; y = x^2ab mod n */ + if ((err = mp_sqrmod(&y, &n, &y)) != MP_OKAY) goto LTM_ERR; /* y should be 1 */ - if (mp_cmp_d(&y, 1uL) != MP_EQ) + if (mp_cmp_d(&y, 1uL) != MP_EQ) { continue; + } break; } /* no bases worked? */ - if (ii == li) + if (ii == li) { goto top; - - { - char buf[4096]; - - mp_to_decimal(&n, buf, sizeof(buf)); - printf("Certificate of primality for:\n%s\n\n", buf); - mp_to_decimal(&a, buf, sizeof(buf)); - printf("A == \n%s\n\n", buf); - mp_to_decimal(&b, buf, sizeof(buf)); - printf("B == \n%s\n\nG == %lu\n", buf, bases[ii]); - printf("----------------------------------------------------------------\n"); } + mp_print("Certificate of primality for:\n ", &n, 10, stdout); + mp_print("A == ", &a, 10, stdout); + mp_print("B == ", &b, 10, stdout); + mp_print("G == ", &x, 10, stdout); + printf("----------------------------------------------------------------\n"); + /* a = n */ - mp_copy(&n, &a); + if ((err = mp_copy(&n, &a)) != MP_OKAY) goto LTM_ERR; } /* get q to be the order of the large prime subgroup */ - mp_sub_d(&n, 1uL, q); - mp_div_2(q, q); - mp_div(q, &b, q, NULL); + if ((err = mp_sub_d(&n, 1uL, q)) != MP_OKAY) goto LTM_ERR; + if ((err = mp_div_2(q, q)) != MP_OKAY) goto LTM_ERR; + if ((err = mp_div(q, &b, q, NULL)) != MP_OKAY) goto LTM_ERR; 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; + err = MP_OKAY; +LTM_ERR: + mp_clear_multi(&a, &b, &c, &n, &x, &y, &z, &v, NULL); + return err; } int main(void) { mp_int p, q; + mp_err err; 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"); + printf("Enter number of bases to try\n"); fgets(buf, sizeof(buf), stdin); sscanf(buf, "%d", &li); - mp_init(&p); - mp_init(&q); + if ((err = mp_init_multi(&p, &q, NULL)) != MP_OKAY) goto LTM_ERR; t1 = clock(); - pprime(k, li, &p, &q); + if ((err = pprime(k, li, &p, &q)) != MP_OKAY) { + fprintf(stderr, "Something went wrong in function pprime: %s\n", mp_error_to_string(err)); + goto LTM_ERR; + } t1 = clock() - t1; printf("\n\nTook %lu ticks, %d bits\n", t1, mp_count_bits(&p)); - mp_to_decimal(&p, buf, sizeof(buf)); - printf("P == %s\n", buf); - mp_to_decimal(&q, buf, sizeof(buf)); - printf("Q == %s\n", buf); + mp_print("P == ", &p, 10, stdout); + mp_print("Q == ", &q, 10, stdout); - return 0; + mp_clear_multi(&p, &q, NULL); + exit(EXIT_SUCCESS); +LTM_ERR: + mp_clear_multi(&p, &q, NULL); + exit(EXIT_FAILURE); } diff --git a/deps/libtommath/helper.pl b/deps/libtommath/helper.pl index 53658614..ffc592a7 100644 --- a/deps/libtommath/helper.pl +++ b/deps/libtommath/helper.pl @@ -394,7 +394,7 @@ EOS foreach my $filename (glob '*mp_*.c') { my $content; my $cc = $ENV{'CC'} || 'gcc'; - $content = `$cc -E -x c -DLTM_ALL $filename`; + $content = `$cc -E -x c -DLTM_ALL -DMP_SMALL_STACK_SIZE $filename`; $content =~ s/^# 1 "$filename".*?^# 2 "$filename"//ms; # convert filename to upper case so we can use it as a define diff --git a/deps/libtommath/libtommath_VS2008.vcproj b/deps/libtommath/libtommath_VS2008.vcproj index 50a2dd68..b819477e 100644 --- a/deps/libtommath/libtommath_VS2008.vcproj +++ b/deps/libtommath/libtommath_VS2008.vcproj @@ -792,6 +792,10 @@ RelativePath="mp_unpack.c" > + + @@ -928,6 +932,18 @@ RelativePath="s_mp_sub.c" > + + + + + + diff --git a/deps/libtommath/makefile b/deps/libtommath/makefile index f8feff7c..8f211f5f 100644 --- a/deps/libtommath/makefile +++ b/deps/libtommath/makefile @@ -43,13 +43,14 @@ mp_reduce_2k_l.o mp_reduce_2k_setup.o mp_reduce_2k_setup_l.o mp_reduce_is_2k.o m mp_reduce_setup.o mp_root_n.o mp_rshd.o mp_sbin_size.o mp_set.o mp_set_double.o mp_set_i32.o mp_set_i64.o \ mp_set_l.o mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_shrink.o mp_signed_rsh.o mp_sqrmod.o mp_sqrt.o \ mp_sqrtmod_prime.o mp_sub.o mp_sub_d.o mp_submod.o mp_to_radix.o mp_to_sbin.o mp_to_ubin.o mp_ubin_size.o \ -mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_copy_digs.o s_mp_div_3.o s_mp_div_recursive.o \ -s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_fp_log.o s_mp_fp_log_d.o \ -s_mp_get_bit.o s_mp_invmod.o s_mp_invmod_odd.o s_mp_log_2expt.o s_mp_montgomery_reduce_comba.o s_mp_mul.o \ -s_mp_mul_balance.o s_mp_mul_comba.o s_mp_mul_high.o s_mp_mul_high_comba.o s_mp_mul_karatsuba.o \ -s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o s_mp_radix_map.o \ -s_mp_radix_size_overestimate.o s_mp_rand_platform.o s_mp_sqr.o s_mp_sqr_comba.o s_mp_sqr_karatsuba.o \ -s_mp_sqr_toom.o s_mp_sub.o s_mp_zero_buf.o s_mp_zero_digs.o +mp_unpack.o mp_warray_free.o mp_xor.o mp_zero.o s_mp_add.o s_mp_copy_digs.o s_mp_div_3.o \ +s_mp_div_recursive.o s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_fp_log.o \ +s_mp_fp_log_d.o s_mp_get_bit.o s_mp_invmod.o s_mp_invmod_odd.o s_mp_log_2expt.o \ +s_mp_montgomery_reduce_comba.o s_mp_mul.o s_mp_mul_balance.o s_mp_mul_comba.o s_mp_mul_high.o \ +s_mp_mul_high_comba.o s_mp_mul_karatsuba.o s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o \ +s_mp_radix_map.o s_mp_radix_size_overestimate.o s_mp_rand_platform.o s_mp_sqr.o s_mp_sqr_comba.o \ +s_mp_sqr_karatsuba.o s_mp_sqr_toom.o s_mp_sub.o s_mp_warray.o s_mp_warray_get.o s_mp_warray_put.o \ +s_mp_zero_buf.o s_mp_zero_digs.o #END_INS @@ -107,6 +108,10 @@ tune: $(LIBNAME) $(MAKE) -C etc tune CFLAGS="$(LTM_CFLAGS) -I../" $(MAKE) +etc-all: $(LIBNAME) + $(MAKE) -C etc all CFLAGS="$(LTM_CFLAGS) -I../" + $(MAKE) + # You have to create a file .coveralls.yml with the content "repo_token: " # in the base folder to be able to submit to coveralls coveralls: lcov @@ -122,8 +127,12 @@ cmp: profiled_single ./timing $(MAKE) -C logs/ cmp +zipup: + $(MAKE) clean + $(MAKE) .zipup + TODAY=$(shell date -I) -zipup: clean astyle new_file docs +.zipup: 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. @@ -164,9 +173,10 @@ c89: -e 's/UINT32_MAX/0xFFFFFFFFu/g' \ -e 's/UINT64_MAX/(mp_u64)-1/g' \ -e 's/INT32_MAX/0x7FFFFFFF/g' \ - -e 's/INT32_MIN/(-2147483647-1)/g' \ + -e 's/INT32_MIN/(-2147483647-1)/g' \ -e 's/INT64_MAX/(mp_i64)(((mp_u64)1<<63)-1)/g' \ -e 's/INT64_MIN/(mp_i64)((mp_u64)1<<63)/g' \ + -e 's/uintptr_t/mp_uintptr/g' \ -e 's/SIZE_MAX/((size_t)-1)/g' \ -e 's/\(PRI[ioux]64\)/MP_\1/g' \ -e 's/uint\([0-9][0-9]*\)_t/mp_u\1/g' \ @@ -187,10 +197,11 @@ c99: -e 's/false_/MP_NO_/g' \ -e 's/0xFFFFFFFFu/UINT32_MAX/g' \ -e 's/(mp_u64)-1/UINT64_MAX/g' \ - -e 's/(-2147483647-1)/INT32_MIN/g' \ + -e 's/(-2147483647-1)/INT32_MIN/g' \ -e 's/0x7FFFFFFF/INT32_MAX/g' \ -e 's/(mp_i64)((mp_u64)1<<63)/INT64_MIN/g' \ -e 's/(mp_i64)(((mp_u64)1<<63)-1)/INT64_MAX/g' \ + -e 's/mp_uintptr/uintptr_t/g' \ -e 's/((size_t)-1)/SIZE_MAX/g' \ -e 's/MP_\(PRI[ioux]64\)/\1/g' \ -e 's/mp_u\([0-9][0-9]*\)/uint\1_t/g' \ diff --git a/deps/libtommath/makefile.mingw b/deps/libtommath/makefile.mingw index 532747be..e2445e8a 100644 --- a/deps/libtommath/makefile.mingw +++ b/deps/libtommath/makefile.mingw @@ -45,13 +45,14 @@ mp_reduce_2k_l.o mp_reduce_2k_setup.o mp_reduce_2k_setup_l.o mp_reduce_is_2k.o m mp_reduce_setup.o mp_root_n.o mp_rshd.o mp_sbin_size.o mp_set.o mp_set_double.o mp_set_i32.o mp_set_i64.o \ mp_set_l.o mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_shrink.o mp_signed_rsh.o mp_sqrmod.o mp_sqrt.o \ mp_sqrtmod_prime.o mp_sub.o mp_sub_d.o mp_submod.o mp_to_radix.o mp_to_sbin.o mp_to_ubin.o mp_ubin_size.o \ -mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_copy_digs.o s_mp_div_3.o s_mp_div_recursive.o \ -s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_fp_log.o s_mp_fp_log_d.o \ -s_mp_get_bit.o s_mp_invmod.o s_mp_invmod_odd.o s_mp_log_2expt.o s_mp_montgomery_reduce_comba.o s_mp_mul.o \ -s_mp_mul_balance.o s_mp_mul_comba.o s_mp_mul_high.o s_mp_mul_high_comba.o s_mp_mul_karatsuba.o \ -s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o s_mp_radix_map.o \ -s_mp_radix_size_overestimate.o s_mp_rand_platform.o s_mp_sqr.o s_mp_sqr_comba.o s_mp_sqr_karatsuba.o \ -s_mp_sqr_toom.o s_mp_sub.o s_mp_zero_buf.o s_mp_zero_digs.o +mp_unpack.o mp_warray_free.o mp_xor.o mp_zero.o s_mp_add.o s_mp_copy_digs.o s_mp_div_3.o \ +s_mp_div_recursive.o s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_fp_log.o \ +s_mp_fp_log_d.o s_mp_get_bit.o s_mp_invmod.o s_mp_invmod_odd.o s_mp_log_2expt.o \ +s_mp_montgomery_reduce_comba.o s_mp_mul.o s_mp_mul_balance.o s_mp_mul_comba.o s_mp_mul_high.o \ +s_mp_mul_high_comba.o s_mp_mul_karatsuba.o s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o \ +s_mp_radix_map.o s_mp_radix_size_overestimate.o s_mp_rand_platform.o s_mp_sqr.o s_mp_sqr_comba.o \ +s_mp_sqr_karatsuba.o s_mp_sqr_toom.o s_mp_sub.o s_mp_warray.o s_mp_warray_get.o s_mp_warray_put.o \ +s_mp_zero_buf.o s_mp_zero_digs.o HEADERS_PUB=tommath.h HEADERS=tommath_private.h tommath_class.h tommath_superclass.h tommath_cutoffs.h $(HEADERS_PUB) diff --git a/deps/libtommath/makefile.msvc b/deps/libtommath/makefile.msvc index 5d128549..8feb425c 100644 --- a/deps/libtommath/makefile.msvc +++ b/deps/libtommath/makefile.msvc @@ -41,13 +41,14 @@ mp_reduce_2k_l.obj mp_reduce_2k_setup.obj mp_reduce_2k_setup_l.obj mp_reduce_is_ mp_reduce_setup.obj mp_root_n.obj mp_rshd.obj mp_sbin_size.obj mp_set.obj mp_set_double.obj mp_set_i32.obj mp_set_i64.obj \ mp_set_l.obj mp_set_u32.obj mp_set_u64.obj mp_set_ul.obj mp_shrink.obj mp_signed_rsh.obj mp_sqrmod.obj mp_sqrt.obj \ mp_sqrtmod_prime.obj mp_sub.obj mp_sub_d.obj mp_submod.obj mp_to_radix.obj mp_to_sbin.obj mp_to_ubin.obj mp_ubin_size.obj \ -mp_unpack.obj mp_xor.obj mp_zero.obj s_mp_add.obj s_mp_copy_digs.obj s_mp_div_3.obj s_mp_div_recursive.obj \ -s_mp_div_school.obj s_mp_div_small.obj s_mp_exptmod.obj s_mp_exptmod_fast.obj s_mp_fp_log.obj s_mp_fp_log_d.obj \ -s_mp_get_bit.obj s_mp_invmod.obj s_mp_invmod_odd.obj s_mp_log_2expt.obj s_mp_montgomery_reduce_comba.obj s_mp_mul.obj \ -s_mp_mul_balance.obj s_mp_mul_comba.obj s_mp_mul_high.obj s_mp_mul_high_comba.obj s_mp_mul_karatsuba.obj \ -s_mp_mul_toom.obj s_mp_prime_is_divisible.obj s_mp_prime_tab.obj s_mp_radix_map.obj \ -s_mp_radix_size_overestimate.obj s_mp_rand_platform.obj s_mp_sqr.obj s_mp_sqr_comba.obj s_mp_sqr_karatsuba.obj \ -s_mp_sqr_toom.obj s_mp_sub.obj s_mp_zero_buf.obj s_mp_zero_digs.obj +mp_unpack.obj mp_warray_free.obj mp_xor.obj mp_zero.obj s_mp_add.obj s_mp_copy_digs.obj s_mp_div_3.obj \ +s_mp_div_recursive.obj s_mp_div_school.obj s_mp_div_small.obj s_mp_exptmod.obj s_mp_exptmod_fast.obj s_mp_fp_log.obj \ +s_mp_fp_log_d.obj s_mp_get_bit.obj s_mp_invmod.obj s_mp_invmod_odd.obj s_mp_log_2expt.obj \ +s_mp_montgomery_reduce_comba.obj s_mp_mul.obj s_mp_mul_balance.obj s_mp_mul_comba.obj s_mp_mul_high.obj \ +s_mp_mul_high_comba.obj s_mp_mul_karatsuba.obj s_mp_mul_toom.obj s_mp_prime_is_divisible.obj s_mp_prime_tab.obj \ +s_mp_radix_map.obj s_mp_radix_size_overestimate.obj s_mp_rand_platform.obj s_mp_sqr.obj s_mp_sqr_comba.obj \ +s_mp_sqr_karatsuba.obj s_mp_sqr_toom.obj s_mp_sub.obj s_mp_warray.obj s_mp_warray_get.obj s_mp_warray_put.obj \ +s_mp_zero_buf.obj s_mp_zero_digs.obj HEADERS_PUB=tommath.h HEADERS=tommath_private.h tommath_class.h tommath_superclass.h tommath_cutoffs.h $(HEADERS_PUB) diff --git a/deps/libtommath/makefile.shared b/deps/libtommath/makefile.shared index c9b93351..50c33526 100644 --- a/deps/libtommath/makefile.shared +++ b/deps/libtommath/makefile.shared @@ -40,13 +40,14 @@ mp_reduce_2k_l.o mp_reduce_2k_setup.o mp_reduce_2k_setup_l.o mp_reduce_is_2k.o m mp_reduce_setup.o mp_root_n.o mp_rshd.o mp_sbin_size.o mp_set.o mp_set_double.o mp_set_i32.o mp_set_i64.o \ mp_set_l.o mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_shrink.o mp_signed_rsh.o mp_sqrmod.o mp_sqrt.o \ mp_sqrtmod_prime.o mp_sub.o mp_sub_d.o mp_submod.o mp_to_radix.o mp_to_sbin.o mp_to_ubin.o mp_ubin_size.o \ -mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_copy_digs.o s_mp_div_3.o s_mp_div_recursive.o \ -s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_fp_log.o s_mp_fp_log_d.o \ -s_mp_get_bit.o s_mp_invmod.o s_mp_invmod_odd.o s_mp_log_2expt.o s_mp_montgomery_reduce_comba.o s_mp_mul.o \ -s_mp_mul_balance.o s_mp_mul_comba.o s_mp_mul_high.o s_mp_mul_high_comba.o s_mp_mul_karatsuba.o \ -s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o s_mp_radix_map.o \ -s_mp_radix_size_overestimate.o s_mp_rand_platform.o s_mp_sqr.o s_mp_sqr_comba.o s_mp_sqr_karatsuba.o \ -s_mp_sqr_toom.o s_mp_sub.o s_mp_zero_buf.o s_mp_zero_digs.o +mp_unpack.o mp_warray_free.o mp_xor.o mp_zero.o s_mp_add.o s_mp_copy_digs.o s_mp_div_3.o \ +s_mp_div_recursive.o s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_fp_log.o \ +s_mp_fp_log_d.o s_mp_get_bit.o s_mp_invmod.o s_mp_invmod_odd.o s_mp_log_2expt.o \ +s_mp_montgomery_reduce_comba.o s_mp_mul.o s_mp_mul_balance.o s_mp_mul_comba.o s_mp_mul_high.o \ +s_mp_mul_high_comba.o s_mp_mul_karatsuba.o s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o \ +s_mp_radix_map.o s_mp_radix_size_overestimate.o s_mp_rand_platform.o s_mp_sqr.o s_mp_sqr_comba.o \ +s_mp_sqr_karatsuba.o s_mp_sqr_toom.o s_mp_sub.o s_mp_warray.o s_mp_warray_get.o s_mp_warray_put.o \ +s_mp_zero_buf.o s_mp_zero_digs.o #END_INS diff --git a/deps/libtommath/makefile.unix b/deps/libtommath/makefile.unix index ccf8f021..58642098 100644 --- a/deps/libtommath/makefile.unix +++ b/deps/libtommath/makefile.unix @@ -20,7 +20,7 @@ ARFLAGS = rcs CFLAGS = -O2 LDFLAGS = -VERSION = 1.2.1 +VERSION = 1.3.0 #Compilation flags LTM_CFLAGS = -I. $(CFLAGS) @@ -46,13 +46,14 @@ mp_reduce_2k_l.o mp_reduce_2k_setup.o mp_reduce_2k_setup_l.o mp_reduce_is_2k.o m mp_reduce_setup.o mp_root_n.o mp_rshd.o mp_sbin_size.o mp_set.o mp_set_double.o mp_set_i32.o mp_set_i64.o \ mp_set_l.o mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_shrink.o mp_signed_rsh.o mp_sqrmod.o mp_sqrt.o \ mp_sqrtmod_prime.o mp_sub.o mp_sub_d.o mp_submod.o mp_to_radix.o mp_to_sbin.o mp_to_ubin.o mp_ubin_size.o \ -mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_copy_digs.o s_mp_div_3.o s_mp_div_recursive.o \ -s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_fp_log.o s_mp_fp_log_d.o \ -s_mp_get_bit.o s_mp_invmod.o s_mp_invmod_odd.o s_mp_log_2expt.o s_mp_montgomery_reduce_comba.o s_mp_mul.o \ -s_mp_mul_balance.o s_mp_mul_comba.o s_mp_mul_high.o s_mp_mul_high_comba.o s_mp_mul_karatsuba.o \ -s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o s_mp_radix_map.o \ -s_mp_radix_size_overestimate.o s_mp_rand_platform.o s_mp_sqr.o s_mp_sqr_comba.o s_mp_sqr_karatsuba.o \ -s_mp_sqr_toom.o s_mp_sub.o s_mp_zero_buf.o s_mp_zero_digs.o +mp_unpack.o mp_warray_free.o mp_xor.o mp_zero.o s_mp_add.o s_mp_copy_digs.o s_mp_div_3.o \ +s_mp_div_recursive.o s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_fp_log.o \ +s_mp_fp_log_d.o s_mp_get_bit.o s_mp_invmod.o s_mp_invmod_odd.o s_mp_log_2expt.o \ +s_mp_montgomery_reduce_comba.o s_mp_mul.o s_mp_mul_balance.o s_mp_mul_comba.o s_mp_mul_high.o \ +s_mp_mul_high_comba.o s_mp_mul_karatsuba.o s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o \ +s_mp_radix_map.o s_mp_radix_size_overestimate.o s_mp_rand_platform.o s_mp_sqr.o s_mp_sqr_comba.o \ +s_mp_sqr_karatsuba.o s_mp_sqr_toom.o s_mp_sub.o s_mp_warray.o s_mp_warray_get.o s_mp_warray_put.o \ +s_mp_zero_buf.o s_mp_zero_digs.o HEADERS_PUB=tommath.h diff --git a/deps/libtommath/makefile_include.mk b/deps/libtommath/makefile_include.mk index 77708305..d47ea2ba 100644 --- a/deps/libtommath/makefile_include.mk +++ b/deps/libtommath/makefile_include.mk @@ -3,9 +3,9 @@ # #version of library -VERSION=1.2.1-develop -VERSION_PC=1.2.1 -VERSION_SO=3:1:2 +VERSION=1.3.0-develop +VERSION_PC=1.3.0 +VERSION_SO=4:0:3 PLATFORM := $(shell uname | sed -e 's/_.*//') @@ -97,7 +97,7 @@ endif endif # COMPILE_SIZE ifneq ($(findstring clang,$(CC)),) -LTM_CFLAGS += -Wno-typedef-redefinition -Wno-tautological-compare -Wno-builtin-requires-header +LTM_CFLAGS += -Wno-unknown-warning-option -Wno-typedef-redefinition -Wno-tautological-compare -Wno-builtin-requires-header -Wno-incomplete-setjmp-declaration ifdef IGNORE_SPEED #for dead code eliminiation LTM_CFLAGS += -O1 diff --git a/deps/libtommath/mp_prime_rand.c b/deps/libtommath/mp_prime_rand.c index c5cebbda..5351aefe 100644 --- a/deps/libtommath/mp_prime_rand.c +++ b/deps/libtommath/mp_prime_rand.c @@ -26,7 +26,7 @@ mp_err mp_prime_rand(mp_int *a, int t, int size, int flags) mp_err err; /* sanity check the input */ - if ((size <= 1) || (t <= 0)) { + if (size <= 1) { return MP_VAL; } diff --git a/deps/libtommath/mp_prime_strong_lucas_selfridge.c b/deps/libtommath/mp_prime_strong_lucas_selfridge.c index ffbd9d34..23486e3a 100644 --- a/deps/libtommath/mp_prime_strong_lucas_selfridge.c +++ b/deps/libtommath/mp_prime_strong_lucas_selfridge.c @@ -52,7 +52,8 @@ mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, 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; - int32_t D, Ds, J, sign, P, Q, r, s, u, Nbits; + int J; + int32_t D, Ds, sign, P, Q, r, s, u, Nbits; mp_err err; bool oddness; diff --git a/deps/libtommath/mp_reduce_is_2k.c b/deps/libtommath/mp_reduce_is_2k.c index 9774f96e..d5496338 100644 --- a/deps/libtommath/mp_reduce_is_2k.c +++ b/deps/libtommath/mp_reduce_is_2k.c @@ -11,9 +11,16 @@ bool mp_reduce_is_2k(const mp_int *a) } else if (a->used == 1) { return true; } else if (a->used > 1) { - int ix, iy = mp_count_bits(a), iw = 1; - mp_digit iz = 1; + int ix, iy, iw = 1; + mp_digit iz; + /* Algorithm as implemented does not work if the least significant digit is zero */ + iz = a->dp[0] & MP_MASK; + if (iz == 0u) { + return false; + } + iy = mp_count_bits(a); + iz = 1; /* Test every bit from the second digit up, must be 1 */ for (ix = MP_DIGIT_BIT; ix < iy; ix++) { if ((a->dp[iw] & iz) == 0u) { diff --git a/deps/libtommath/mp_warray_free.c b/deps/libtommath/mp_warray_free.c new file mode 100644 index 00000000..f7470f81 --- /dev/null +++ b/deps/libtommath/mp_warray_free.c @@ -0,0 +1,28 @@ +#include "tommath_private.h" +#ifdef MP_WARRAY_FREE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* static check that the multiplication won't overflow */ +MP_STATIC_ASSERT(warray_free_sz_does_not_overflow, (sizeof(mp_word) * MP_WARRAY) >= MP_WARRAY) + +static int s_warray_free(void) +{ + int ret = 0; + if (s_mp_warray.w_used) + return -2; + if (s_mp_warray.w_free) { + s_mp_zero_buf(s_mp_warray.w_free, sizeof(mp_word) * MP_WARRAY); + MP_FREE(s_mp_warray.w_free, sizeof(mp_word) * MP_WARRAY); + s_mp_warray.w_free = NULL; + } + return ret; +} + +int mp_warray_free(void) +{ + if (MP_HAS(MP_SMALL_STACK_SIZE)) return s_warray_free(); + return -1; +} + +#endif diff --git a/deps/libtommath/s_mp_montgomery_reduce_comba.c b/deps/libtommath/s_mp_montgomery_reduce_comba.c index 7472caf3..3858f75a 100644 --- a/deps/libtommath/s_mp_montgomery_reduce_comba.c +++ b/deps/libtommath/s_mp_montgomery_reduce_comba.c @@ -15,9 +15,12 @@ mp_err s_mp_montgomery_reduce_comba(mp_int *x, const mp_int *n, mp_digit rho) { int ix, oldused; mp_err err; - mp_word W[MP_WARRAY]; + mp_word MP_ALLOC_WARRAY(W); + + MP_CHECK_WARRAY(W); if (x->used > MP_WARRAY) { + MP_FREE_WARRAY(W); return MP_VAL; } @@ -26,6 +29,7 @@ mp_err s_mp_montgomery_reduce_comba(mp_int *x, const mp_int *n, mp_digit rho) /* grow a as required */ if ((err = mp_grow(x, n->used + 1)) != MP_OKAY) { + MP_FREE_WARRAY(W); return err; } @@ -110,6 +114,7 @@ mp_err s_mp_montgomery_reduce_comba(mp_int *x, const mp_int *n, mp_digit rho) mp_clamp(x); + MP_FREE_WARRAY(W); /* if A >= m then A = A - m */ if (mp_cmp_mag(x, n) != MP_LT) { return s_mp_sub(x, n, x); diff --git a/deps/libtommath/s_mp_mul_comba.c b/deps/libtommath/s_mp_mul_comba.c index ca89ff9d..5b37035e 100644 --- a/deps/libtommath/s_mp_mul_comba.c +++ b/deps/libtommath/s_mp_mul_comba.c @@ -23,15 +23,19 @@ mp_err s_mp_mul_comba(const mp_int *a, const mp_int *b, mp_int *c, int digs) { int oldused, pa, ix; mp_err err; - mp_digit W[MP_WARRAY]; + mp_digit MP_ALLOC_WARRAY(W); mp_word _W; + MP_CHECK_WARRAY(W); + if (digs < 0) { + MP_FREE_WARRAY(W); return MP_VAL; } /* grow the destination as required */ if ((err = mp_grow(c, digs)) != MP_OKAY) { + MP_FREE_WARRAY(W); return err; } @@ -77,6 +81,7 @@ mp_err s_mp_mul_comba(const mp_int *a, const mp_int *b, mp_int *c, int digs) s_mp_zero_digs(c->dp + c->used, oldused - c->used); mp_clamp(c); + MP_FREE_WARRAY(W); return MP_OKAY; } #endif diff --git a/deps/libtommath/s_mp_mul_high_comba.c b/deps/libtommath/s_mp_mul_high_comba.c index b5ac06d7..b0096d4e 100644 --- a/deps/libtommath/s_mp_mul_high_comba.c +++ b/deps/libtommath/s_mp_mul_high_comba.c @@ -16,16 +16,20 @@ mp_err s_mp_mul_high_comba(const mp_int *a, const mp_int *b, mp_int *c, int digs { int oldused, pa, ix; mp_err err; - mp_digit W[MP_WARRAY]; + mp_digit MP_ALLOC_WARRAY(W); mp_word _W; + MP_CHECK_WARRAY(W); + if (digs < 0) { + MP_FREE_WARRAY(W); return MP_VAL; } /* grow the destination as required */ pa = a->used + b->used; if ((err = mp_grow(c, pa)) != MP_OKAY) { + MP_FREE_WARRAY(W); return err; } @@ -69,6 +73,7 @@ mp_err s_mp_mul_high_comba(const mp_int *a, const mp_int *b, mp_int *c, int digs s_mp_zero_digs(c->dp + c->used, oldused - c->used); mp_clamp(c); + MP_FREE_WARRAY(W); return MP_OKAY; } #endif diff --git a/deps/libtommath/s_mp_sqr_comba.c b/deps/libtommath/s_mp_sqr_comba.c index 1bcc1f93..336a0a08 100644 --- a/deps/libtommath/s_mp_sqr_comba.c +++ b/deps/libtommath/s_mp_sqr_comba.c @@ -16,13 +16,16 @@ After that loop you do the squares and add them in. mp_err s_mp_sqr_comba(const mp_int *a, mp_int *b) { int oldused, pa, ix; - mp_digit W[MP_WARRAY]; + mp_digit MP_ALLOC_WARRAY(W); mp_word W1; mp_err err; + MP_CHECK_WARRAY(W); + /* grow the destination as required */ pa = a->used + a->used; if ((err = mp_grow(b, pa)) != MP_OKAY) { + MP_FREE_WARRAY(W); return err; } @@ -82,6 +85,7 @@ mp_err s_mp_sqr_comba(const mp_int *a, mp_int *b) s_mp_zero_digs(b->dp + b->used, oldused - b->used); mp_clamp(b); + MP_FREE_WARRAY(W); return MP_OKAY; } #endif diff --git a/deps/libtommath/s_mp_warray.c b/deps/libtommath/s_mp_warray.c new file mode 100644 index 00000000..1b8b068b --- /dev/null +++ b/deps/libtommath/s_mp_warray.c @@ -0,0 +1,8 @@ +#include "tommath_private.h" +#ifdef S_MP_WARRAY_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +mp_thread st_warray s_mp_warray = { 0 }; + +#endif diff --git a/deps/libtommath/s_mp_warray_get.c b/deps/libtommath/s_mp_warray_get.c new file mode 100644 index 00000000..26b0d7c1 --- /dev/null +++ b/deps/libtommath/s_mp_warray_get.c @@ -0,0 +1,18 @@ +#include "tommath_private.h" +#ifdef S_MP_WARRAY_GET_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +void *s_mp_warray_get(void) +{ + if (s_mp_warray.w_used) + return NULL; + if (s_mp_warray.w_free == NULL) { + s_mp_warray.w_free = MP_CALLOC(MP_WARRAY, sizeof(mp_word)); + } + s_mp_warray.w_used = s_mp_warray.w_free; + s_mp_warray.w_free = NULL; + return s_mp_warray.w_used; +} + +#endif diff --git a/deps/libtommath/s_mp_warray_put.c b/deps/libtommath/s_mp_warray_put.c new file mode 100644 index 00000000..79e014ac --- /dev/null +++ b/deps/libtommath/s_mp_warray_put.c @@ -0,0 +1,14 @@ +#include "tommath_private.h" +#ifdef S_MP_WARRAY_PUT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +void s_mp_warray_put(void *w) +{ + if (s_mp_warray.w_free || s_mp_warray.w_used != w) + return; + s_mp_warray.w_free = w; + s_mp_warray.w_used = NULL; +} + +#endif diff --git a/deps/libtommath/sources.cmake b/deps/libtommath/sources.cmake index bbb2aeab..103e9c09 100644 --- a/deps/libtommath/sources.cmake +++ b/deps/libtommath/sources.cmake @@ -122,6 +122,7 @@ mp_to_sbin.c mp_to_ubin.c mp_ubin_size.c mp_unpack.c +mp_warray_free.c mp_xor.c mp_zero.c s_mp_add.c @@ -156,6 +157,9 @@ s_mp_sqr_comba.c s_mp_sqr_karatsuba.c s_mp_sqr_toom.c s_mp_sub.c +s_mp_warray.c +s_mp_warray_get.c +s_mp_warray_put.c s_mp_zero_buf.c s_mp_zero_digs.c ) diff --git a/deps/libtommath/testme.sh b/deps/libtommath/testme.sh index 089e42a7..92997a04 100644 --- a/deps/libtommath/testme.sh +++ b/deps/libtommath/testme.sh @@ -70,6 +70,8 @@ All other options will be tested with all MP_xBIT configurations. runtime and may trigger the 30 minutes timeout. + --multithread Run tests in multi-threaded mode (via pthread). + Godmode: --all Choose all architectures and gcc and clang @@ -128,7 +130,7 @@ _make() echo -ne " Compile $1 $2" suffix=$(echo ${1}${2} | tr ' ' '_') _fixup_cflags "$1" - CC="$1" CFLAGS="$2 $TEST_CFLAGS" make -j$MAKE_JOBS $3 $MAKE_OPTIONS 2>gcc_errors_${suffix}.log + CC="$1" CFLAGS="$2 $TEST_CFLAGS" LFLAGS="$4" LDFLAGS="$5" make -j$MAKE_JOBS $3 $MAKE_OPTIONS 2>gcc_errors_${suffix}.log errcnt=$(wc -l < gcc_errors_${suffix}.log) if [[ ${errcnt} -gt 1 ]]; then echo " failed" @@ -148,10 +150,10 @@ _runtest() # "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" "" + _make "$1" "$2" "" "$3" "$4" $_timeout $TUNE_CMD > test_${suffix}.log || _die "running autotune" $? else - _make "$1" "$2" "test" + _make "$1" "$2" "test" "$3" "$4" echo -e "\rRun test $1 $2" $_timeout ./test > test_${suffix}.log || _die "running tests" $? fi @@ -171,13 +173,13 @@ echo "MAKE_OPTIONS = \"$MAKE_OPTIONS\"" if [[ "$MAKE_OPTIONS" =~ "tune" ]] then echo "autotune branch" - _make "$1" "$2" "" + _make "$1" "$2" "" "$3" "$4" # 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" + _make "$1" "$2" "test" "$3" "$4" echo -e "\rRun test $1 $2 inside valgrind" $_timeout $VALGRIND_BIN $VALGRIND_OPTS ./test > test_${suffix}.log || _die "running tests" $? fi @@ -301,6 +303,11 @@ do --symbols) CHECK_SYMBOLS="1" ;; + --multithread) + CFLAGS="$CFLAGS -DLTM_TEST_MULTITHREAD" + LFLAGS="$LFLAGS -pthread" + LDFLAGS="$LDFLAGS -pthread" + ;; --all) COMPILERS="gcc clang" ARCHFLAGS="-m64 -m32 -mx32" @@ -376,9 +383,9 @@ then _banner "$CC" if [[ "$VALGRIND_BIN" != "" ]] then - _runvalgrind "$CC" "" + _runvalgrind "$CC" "" "$LFLAGS" "$LDFLAGS" else - _runtest "$CC" "" + _runtest "$CC" "" "$LFLAGS" "$LDFLAGS" fi _exit fi @@ -398,9 +405,9 @@ _banner if [[ "$TEST_VS_MTEST" != "" ]] then make clean > /dev/null - _make "${compilers[0]}" "${archflags[0]} $CFLAGS" "mtest_opponent" + _make "${compilers[0]}" "${archflags[0]} $CFLAGS" "mtest_opponent" "$LFLAGS" "$LDFLAGS" echo - _make "gcc" "$MTEST_RAND" "mtest" + _make "gcc" "$MTEST_RAND" "mtest" "$LFLAGS" "$LDFLAGS" echo echo "Run test vs. mtest for $TEST_VS_MTEST iterations" _timeout="" @@ -429,15 +436,15 @@ do fi if [[ "$VALGRIND_BIN" != "" ]] then - _runvalgrind "$i" "$a $CFLAGS" + _runvalgrind "$i" "$a $CFLAGS" "$LFLAGS" "$LDFLAGS" [ "$WITH_LOW_MP" != "1" ] && continue - _runvalgrind "$i" "$a -DMP_16BIT $CFLAGS" - _runvalgrind "$i" "$a -DMP_32BIT $CFLAGS" + _runvalgrind "$i" "$a -DMP_16BIT $CFLAGS" "$LFLAGS" "$LDFLAGS" + _runvalgrind "$i" "$a -DMP_32BIT $CFLAGS" "$LFLAGS" "$LDFLAGS" else - _runtest "$i" "$a $CFLAGS" + _runtest "$i" "$a $CFLAGS" "$LFLAGS" "$LDFLAGS" [ "$WITH_LOW_MP" != "1" ] && continue - _runtest "$i" "$a -DMP_16BIT $CFLAGS" - _runtest "$i" "$a -DMP_32BIT $CFLAGS" + _runtest "$i" "$a -DMP_16BIT $CFLAGS" "$LFLAGS" "$LDFLAGS" + _runtest "$i" "$a -DMP_32BIT $CFLAGS" "$LFLAGS" "$LDFLAGS" fi done done diff --git a/deps/libtommath/tommath.def b/deps/libtommath/tommath.def index 86f34872..ed5aa8b0 100644 --- a/deps/libtommath/tommath.def +++ b/deps/libtommath/tommath.def @@ -125,6 +125,7 @@ EXPORTS mp_to_ubin mp_ubin_size mp_unpack + mp_warray_free mp_xor mp_zero MP_MUL_KARATSUBA_CUTOFF diff --git a/deps/libtommath/tommath.h b/deps/libtommath/tommath.h index 84bb0909..1820d243 100644 --- a/deps/libtommath/tommath.h +++ b/deps/libtommath/tommath.h @@ -588,6 +588,8 @@ 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 +int mp_warray_free(void); + #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) diff --git a/deps/libtommath/tommath_c89.h b/deps/libtommath/tommath_c89.h index 49400a13..22436366 100644 --- a/deps/libtommath/tommath_c89.h +++ b/deps/libtommath/tommath_c89.h @@ -26,6 +26,11 @@ typedef __UINT8_TYPE__ mp_u8; typedef __UINT16_TYPE__ mp_u16; typedef __UINT32_TYPE__ mp_u32; typedef __UINT64_TYPE__ mp_u64; +# if __WORDSIZE == 64 +typedef __UINT64_TYPE__ mp_uintptr; +# else +typedef __UINT32_TYPE__ mp_uintptr; +# endif /* inttypes.h replacement, printf format specifier */ # if __WORDSIZE == 64 diff --git a/deps/libtommath/tommath_class.h b/deps/libtommath/tommath_class.h index e08bc5f3..09bb3ea6 100644 --- a/deps/libtommath/tommath_class.h +++ b/deps/libtommath/tommath_class.h @@ -131,6 +131,7 @@ # define MP_TO_UBIN_C # define MP_UBIN_SIZE_C # define MP_UNPACK_C +# define MP_WARRAY_FREE_C # define MP_XOR_C # define MP_ZERO_C # define S_MP_ADD_C @@ -165,6 +166,9 @@ # define S_MP_SQR_KARATSUBA_C # define S_MP_SQR_TOOM_C # define S_MP_SUB_C +# define S_MP_WARRAY_C +# define S_MP_WARRAY_GET_C +# define S_MP_WARRAY_PUT_C # define S_MP_ZERO_BUF_C # define S_MP_ZERO_DIGS_C #endif @@ -957,6 +961,10 @@ # define MP_ZERO_C #endif +#if defined(MP_WARRAY_FREE_C) +# define S_MP_ZERO_BUF_C +#endif + #if defined(MP_XOR_C) # define MP_CLAMP_C # define MP_GROW_C @@ -1137,6 +1145,8 @@ # define MP_CMP_MAG_C # define MP_GROW_C # define S_MP_SUB_C +# define S_MP_WARRAY_GET_C +# define S_MP_WARRAY_PUT_C # define S_MP_ZERO_BUF_C # define S_MP_ZERO_DIGS_C #endif @@ -1165,6 +1175,8 @@ #if defined(S_MP_MUL_COMBA_C) # define MP_CLAMP_C # define MP_GROW_C +# define S_MP_WARRAY_GET_C +# define S_MP_WARRAY_PUT_C # define S_MP_ZERO_DIGS_C #endif @@ -1179,6 +1191,8 @@ #if defined(S_MP_MUL_HIGH_COMBA_C) # define MP_CLAMP_C # define MP_GROW_C +# define S_MP_WARRAY_GET_C +# define S_MP_WARRAY_PUT_C # define S_MP_ZERO_DIGS_C #endif @@ -1244,6 +1258,8 @@ #if defined(S_MP_SQR_COMBA_C) # define MP_CLAMP_C # define MP_GROW_C +# define S_MP_WARRAY_GET_C +# define S_MP_WARRAY_PUT_C # define S_MP_ZERO_DIGS_C #endif @@ -1279,6 +1295,15 @@ # define S_MP_ZERO_DIGS_C #endif +#if defined(S_MP_WARRAY_C) +#endif + +#if defined(S_MP_WARRAY_GET_C) +#endif + +#if defined(S_MP_WARRAY_PUT_C) +#endif + #if defined(S_MP_ZERO_BUF_C) #endif diff --git a/deps/libtommath/tommath_private.h b/deps/libtommath/tommath_private.h index d319a1db..be620dbc 100644 --- a/deps/libtommath/tommath_private.h +++ b/deps/libtommath/tommath_private.h @@ -160,8 +160,13 @@ MP_STATIC_ASSERT(correct_word_size, sizeof(mp_word) == (2u * sizeof(mp_digit))) * - Must be large enough such that the mp_set_u64 setter can * store uint64_t in the mp_int without growing */ -#define MP_MIN_DIGIT_COUNT MP_MAX(3, (((int)MP_SIZEOF_BITS(uint64_t) + MP_DIGIT_BIT) - 1) / MP_DIGIT_BIT) +#ifndef MP_MIN_DIGIT_COUNT +# define MP_MIN_DIGIT_COUNT MP_MAX(3, (((int)MP_SIZEOF_BITS(uint64_t) + MP_DIGIT_BIT) - 1) / MP_DIGIT_BIT) +#endif MP_STATIC_ASSERT(prec_geq_min_prec, MP_DEFAULT_DIGIT_COUNT >= MP_MIN_DIGIT_COUNT) +MP_STATIC_ASSERT(min_prec_geq_3, MP_MIN_DIGIT_COUNT >= 3) +MP_STATIC_ASSERT(min_prec_geq_uint64size, + MP_MIN_DIGIT_COUNT >= ((((int)MP_SIZEOF_BITS(uint64_t) + MP_DIGIT_BIT) - 1) / MP_DIGIT_BIT)) /* Maximum number of digits. * - Must be small enough such that mp_bit_count does not overflow. @@ -229,6 +234,47 @@ MP_PRIVATE mp_err s_mp_radix_size_overestimate(const mp_int *a, const int radix, MP_PRIVATE mp_err s_mp_fp_log(const mp_int *a, mp_int *c) MP_WUR; MP_PRIVATE mp_err s_mp_fp_log_d(const mp_int *a, mp_word *c) MP_WUR; +#ifdef MP_SMALL_STACK_SIZE + +#if defined(__GNUC__) +/* We use TLS (Thread Local Storage) to manage the instance of the WARRAY + * per thread. + * The compilers we're usually looking at are GCC, Clang and MSVC. + * Both GCC and Clang are straight-forward with TLS, so it's enabled there. + * Using MSVC the tests were OK with the static library, but failed when + * the library was built as a DLL. As a result we completely disable + * support for MSVC. + * If your compiler can handle TLS properly without too much hocus pocus, + * feel free to open a PR to add support for it. + */ +#define mp_thread __thread +#else +#error "MP_SMALL_STACK_SIZE not supported with your compiler" +#endif + +#define MP_SMALL_STACK_SIZE_C +#define MP_ALLOC_WARRAY(name) *name = s_mp_warray_get() +#define MP_FREE_WARRAY(name) s_mp_warray_put(name) +#define MP_CHECK_WARRAY(name) do { if ((name) == NULL) { return MP_MEM; } } while(0) +#else +#define MP_ALLOC_WARRAY(name) name[MP_WARRAY] +#define MP_FREE_WARRAY(name) +#define MP_CHECK_WARRAY(name) +#endif + +#ifndef mp_thread +#define mp_thread +#endif + +typedef struct { + void *w_free, *w_used; +} st_warray; + +extern MP_PRIVATE mp_thread st_warray s_mp_warray; + +MP_PRIVATE void *s_mp_warray_get(void); +MP_PRIVATE void s_mp_warray_put(void *w); + #define MP_RADIX_MAP_REVERSE_SIZE 80u extern MP_PRIVATE const char s_mp_radix_map[]; extern MP_PRIVATE const uint8_t s_mp_radix_map_reverse[]; diff --git a/deps/libtommath/tommath_superclass.h b/deps/libtommath/tommath_superclass.h index 9245e002..10c7f12a 100644 --- a/deps/libtommath/tommath_superclass.h +++ b/deps/libtommath/tommath_superclass.h @@ -42,6 +42,8 @@ # define MP_SBIN_SIZE_C # define MP_TO_RADIX_C # define MP_TO_SBIN_C +# define MP_WARRAY_FREE_C +# define MP_WARRAY_INIT_C # define S_MP_RAND_JENKINS_C # define S_MP_RAND_PLATFORM_C #endif diff --git a/deps/rapidjson/include/rapidjson/schema.h b/deps/rapidjson/include/rapidjson/schema.h index 06f50efa..973e935f 100644 --- a/deps/rapidjson/include/rapidjson/schema.h +++ b/deps/rapidjson/include/rapidjson/schema.h @@ -367,7 +367,9 @@ public: uint64_t h = Hash(0, kObjectType); uint64_t* kv = stack_.template Pop(memberCount * 2); for (SizeType i = 0; i < memberCount; i++) - h ^= Hash(kv[i * 2], kv[i * 2 + 1]); // Use xor to achieve member order insensitive + // Issue #2205 + // Hasing the key to avoid key=value cases with bug-prone zero-value hash + h ^= Hash(Hash(0, kv[i * 2]), kv[i * 2 + 1]); // Use xor to achieve member order insensitive *stack_.template Push() = h; return true; } @@ -405,7 +407,7 @@ private: bool WriteBuffer(Type type, const void* data, size_t len) { // FNV-1a from http://isthe.com/chongo/tech/comp/fnv/ - uint64_t h = Hash(RAPIDJSON_UINT64_C2(0x84222325, 0xcbf29ce4), type); + uint64_t h = Hash(RAPIDJSON_UINT64_C2(0xcbf29ce4, 0x84222325), type); const unsigned char* d = static_cast(data); for (size_t i = 0; i < len; i++) h = Hash(h, d[i]); diff --git a/deps/rapidjson/include/rapidjson/writer.h b/deps/rapidjson/include/rapidjson/writer.h index 142230d9..632e02ce 100644 --- a/deps/rapidjson/include/rapidjson/writer.h +++ b/deps/rapidjson/include/rapidjson/writer.h @@ -349,7 +349,7 @@ protected: bool WriteDouble(double d) { if (internal::Double(d).IsNanOrInf()) { - if (!(writeFlags & kWriteNanAndInfFlag)) + if (!(writeFlags & kWriteNanAndInfFlag) && !(writeFlags & kWriteNanAndInfNullFlag)) return false; if (writeFlags & kWriteNanAndInfNullFlag) { PutReserve(*os_, 4); diff --git a/deps/rapidjson/test/unittest/schematest.cpp b/deps/rapidjson/test/unittest/schematest.cpp index 7387c089..9d95cd40 100644 --- a/deps/rapidjson/test/unittest/schematest.cpp +++ b/deps/rapidjson/test/unittest/schematest.cpp @@ -99,6 +99,9 @@ TEST(SchemaValidator, Hasher) { TEST_HASHER("{\"a\":1}", "{\"a\":1}", true); TEST_HASHER("{\"a\":1}", "{\"b\":1}", false); TEST_HASHER("{\"a\":1}", "{\"a\":2}", false); + TEST_HASHER("{\"a\":\"a\"}", "{\"b\":\"b\"}", false); // Key equals value hashing + TEST_HASHER("{\"a\":\"a\", \"b\":\"b\"}", "{\"c\":\"c\", \"d\":\"d\"}", false); + TEST_HASHER("{\"a\":\"a\"}", "{\"b\":\"b\", \"c\":\"c\"}", false); TEST_HASHER("{\"a\":1, \"b\":2}", "{\"b\":2, \"a\":1}", true); // Member order insensitive TEST_HASHER("{}", "null", false); TEST_HASHER("{}", "false", false); @@ -2282,7 +2285,7 @@ TEST(SchemaValidator, TestSuite) { MemoryPoolAllocator<>::Free(json); jsonAllocator.Clear(); } - printf("%d / %d passed (%2d%%)\n", passCount, testCount, passCount * 100 / testCount); + printf("%u / %u passed (%2u%%)\n", passCount, testCount, passCount * 100 / testCount); if (passCount != testCount) ADD_FAILURE(); } diff --git a/deps/rapidjson/test/unittest/writertest.cpp b/deps/rapidjson/test/unittest/writertest.cpp index ac9ad899..4c241210 100644 --- a/deps/rapidjson/test/unittest/writertest.cpp +++ b/deps/rapidjson/test/unittest/writertest.cpp @@ -500,6 +500,18 @@ TEST(Writer, NaN) { EXPECT_FALSE(writer2.Double(nan)); } +TEST(Writer, NaNToNull) { + double nan = std::numeric_limits::quiet_NaN(); + + EXPECT_TRUE(internal::Double(nan).IsNan()); + { + StringBuffer buffer; + Writer, UTF8<>, CrtAllocator, kWriteNanAndInfNullFlag> writer(buffer); + EXPECT_TRUE(writer.Double(nan)); + EXPECT_STREQ("null", buffer.GetString()); + } +} + TEST(Writer, Inf) { double inf = std::numeric_limits::infinity(); @@ -524,6 +536,24 @@ TEST(Writer, Inf) { EXPECT_STREQ("Infinity-Infinity", buffer.GetString()); } +TEST(Writer, InfToNull) { + double inf = std::numeric_limits::infinity(); + + EXPECT_TRUE(internal::Double(inf).IsInf()); + { + StringBuffer buffer; + Writer, UTF8<>, CrtAllocator, kWriteNanAndInfNullFlag> writer(buffer); + EXPECT_TRUE(writer.Double(inf)); + EXPECT_STREQ("null", buffer.GetString()); + } + { + StringBuffer buffer; + Writer, UTF8<>, CrtAllocator, kWriteNanAndInfNullFlag> writer(buffer); + EXPECT_TRUE(writer.Double(-inf)); + EXPECT_STREQ("null", buffer.GetString()); + } +} + TEST(Writer, RawValue) { StringBuffer buffer; Writer writer(buffer); diff --git a/deps/zlib/contrib/infback9/inftree9.h b/deps/zlib/contrib/infback9/inftree9.h index 2c1252f5..ab2ea28b 100644 --- a/deps/zlib/contrib/infback9/inftree9.h +++ b/deps/zlib/contrib/infback9/inftree9.h @@ -41,8 +41,8 @@ typedef struct { examples/enough.c found in the zlib distribution. The arguments to that program are the number of symbols, the initial root table size, and the maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns returns 852, and "enough 32 6 15" for distance codes returns 594. - The initial root table size (9 or 6) is found in the fifth argument of the + returns 852, and "enough 32 6 15" for distance codes returns 594. The + initial root table size (9 or 6) is found in the fifth argument of the inflate_table() calls in infback9.c. If the root table size is changed, then these maximum sizes would be need to be recalculated and updated. */ #define ENOUGH_LENS 852 diff --git a/deps/zlib/contrib/minizip/ioapi.h b/deps/zlib/contrib/minizip/ioapi.h index c588a18d..a2d2e6e6 100644 --- a/deps/zlib/contrib/minizip/ioapi.h +++ b/deps/zlib/contrib/minizip/ioapi.h @@ -144,7 +144,7 @@ typedef long (ZCALLBACK *tell_file_func) (voidpf opaque, voidpf stream) typedef long (ZCALLBACK *seek_file_func) (voidpf opaque, voidpf stream, uLong offset, int origin); -/* here is the "old" 32 bits structure structure */ +/* here is the "old" 32 bits structure */ typedef struct zlib_filefunc_def_s { open_file_func zopen_file; diff --git a/deps/zlib/contrib/minizip/miniunz.c b/deps/zlib/contrib/minizip/miniunz.c index a12aec8b..8ada038d 100644 --- a/deps/zlib/contrib/minizip/miniunz.c +++ b/deps/zlib/contrib/minizip/miniunz.c @@ -186,7 +186,7 @@ static int makedir(const char *newdir) { } static void do_banner(void) { - printf("MiniUnz 1.01b, demo of zLib + Unz package written by Gilles Vollant\n"); + printf("MiniUnz 1.1, demo of zLib + Unz package written by Gilles Vollant\n"); printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n"); } diff --git a/deps/zlib/contrib/minizip/zip.c b/deps/zlib/contrib/minizip/zip.c index 0446109b..e2e9da07 100644 --- a/deps/zlib/contrib/minizip/zip.c +++ b/deps/zlib/contrib/minizip/zip.c @@ -614,9 +614,9 @@ local int LoadCentralDirectoryRecord(zip64_internal* pziinit) { ZPOS64_T central_pos; uLong uL; - uLong number_disk; /* number of the current dist, used for + uLong number_disk; /* number of the current disk, used for spanning ZIP, unsupported, always 0*/ - uLong number_disk_with_CD; /* number the the disk with central dir, used + uLong number_disk_with_CD; /* number of the disk with central dir, used for spanning ZIP, unsupported, always 0*/ ZPOS64_T number_entry; ZPOS64_T number_entry_CD; /* total number of entries in @@ -1872,7 +1872,7 @@ extern int ZEXPORT zipClose(zipFile file, const char* global_comment) { free_linkedlist(&(zi->central_dir)); pos = centraldir_pos_inzip - zi->add_position_when_writing_offset; - if(pos >= 0xffffffff || zi->number_entry > 0xFFFF) + if(pos >= 0xffffffff || zi->number_entry >= 0xFFFF) { ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); diff --git a/deps/zlib/contrib/minizip/zip.h b/deps/zlib/contrib/minizip/zip.h index 5fc08413..3e230d34 100644 --- a/deps/zlib/contrib/minizip/zip.h +++ b/deps/zlib/contrib/minizip/zip.h @@ -177,9 +177,9 @@ extern int ZEXPORT zipOpenNewFileInZip64(zipFile file, filename : the filename in zip (if NULL, '-' without quote will be used *zipfi contain supplemental information if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local - contains the extrafield data the the local header + contains the extrafield data for the local header if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global - contains the extrafield data the the local header + contains the extrafield data for the global header if comment != NULL, comment contain the comment string method contain the compression method (0 for store, Z_DEFLATED for deflate) level contain the level of compression (can be Z_DEFAULT_COMPRESSION) diff --git a/deps/zlib/deflate.c b/deps/zlib/deflate.c index 5e72cd92..263bbc8d 100644 --- a/deps/zlib/deflate.c +++ b/deps/zlib/deflate.c @@ -493,7 +493,11 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, * symbols from which it is being constructed. */ +#ifdef LIT_MEM + s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 5); +#else s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4); +#endif s->pending_buf_size = (ulg)s->lit_bufsize * 4; if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || @@ -503,8 +507,14 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, deflateEnd (strm); return Z_MEM_ERROR; } +#ifdef LIT_MEM + s->d_buf = (ushf *)(s->pending_buf + (s->lit_bufsize << 1)); + s->l_buf = s->pending_buf + (s->lit_bufsize << 2); + s->sym_end = s->lit_bufsize - 1; +#else s->sym_buf = s->pending_buf + s->lit_bufsize; s->sym_end = (s->lit_bufsize - 1) * 3; +#endif /* We avoid equality with lit_bufsize*3 because of wraparound at 64K * on 16 bit machines and because stored blocks are restricted to * 64K-1 bytes. @@ -720,9 +730,15 @@ int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) { if (deflateStateCheck(strm)) return Z_STREAM_ERROR; s = strm->state; +#ifdef LIT_MEM + if (bits < 0 || bits > 16 || + (uchf *)s->d_buf < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; +#else if (bits < 0 || bits > 16 || s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3)) return Z_BUF_ERROR; +#endif do { put = Buf_size - s->bi_valid; if (put > bits) @@ -1308,7 +1324,12 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); +#ifdef LIT_MEM + ds->d_buf = (ushf *)(ds->pending_buf + (ds->lit_bufsize << 1)); + ds->l_buf = ds->pending_buf + (ds->lit_bufsize << 2); +#else ds->sym_buf = ds->pending_buf + ds->lit_bufsize; +#endif ds->l_desc.dyn_tree = ds->dyn_ltree; ds->d_desc.dyn_tree = ds->dyn_dtree; diff --git a/deps/zlib/deflate.h b/deps/zlib/deflate.h index 86967914..69fe3a93 100644 --- a/deps/zlib/deflate.h +++ b/deps/zlib/deflate.h @@ -23,6 +23,10 @@ # define GZIP #endif +/* define LIT_MEM to slightly increase the speed of deflate (order 1% to 2%) at + the cost of a larger memory footprint */ +/* #define LIT_MEM */ + /* =========================================================================== * Internal compression state. */ @@ -217,7 +221,12 @@ typedef struct internal_state { /* Depth of each subtree used as tie breaker for trees of equal frequency */ +#ifdef LIT_MEM + ushf *d_buf; /* buffer for distances */ + uchf *l_buf; /* buffer for literals/lengths */ +#else uchf *sym_buf; /* buffer for distances and literals/lengths */ +#endif uInt lit_bufsize; /* Size of match buffer for literals/lengths. There are 4 reasons for @@ -239,7 +248,7 @@ typedef struct internal_state { * - I can't count above 4 */ - uInt sym_next; /* running index in sym_buf */ + uInt sym_next; /* running index in symbol buffer */ uInt sym_end; /* symbol table full when sym_next reaches this */ ulg opt_len; /* bit length of current block with optimal trees */ @@ -318,6 +327,25 @@ void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, extern const uch ZLIB_INTERNAL _dist_code[]; #endif +#ifdef LIT_MEM +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->sym_next] = 0; \ + s->l_buf[s->sym_next++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (uch)(length); \ + ush dist = (ush)(distance); \ + s->d_buf[s->sym_next] = dist; \ + s->l_buf[s->sym_next++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +#else # define _tr_tally_lit(s, c, flush) \ { uch cc = (c); \ s->sym_buf[s->sym_next++] = 0; \ @@ -337,6 +365,7 @@ void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, s->dyn_dtree[d_code(dist)].Freq++; \ flush = (s->sym_next == s->sym_end); \ } +#endif #else # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) # define _tr_tally_dist(s, distance, length, flush) \ diff --git a/deps/zlib/inflate.c b/deps/zlib/inflate.c index b0757a9b..94ecff01 100644 --- a/deps/zlib/inflate.c +++ b/deps/zlib/inflate.c @@ -1387,7 +1387,7 @@ int ZEXPORT inflateSync(z_streamp strm) { /* if first time, start search in bit buffer */ if (state->mode != SYNC) { state->mode = SYNC; - state->hold <<= state->bits & 7; + state->hold >>= state->bits & 7; state->bits -= state->bits & 7; len = 0; while (state->bits >= 8) { diff --git a/deps/zlib/inftrees.h b/deps/zlib/inftrees.h index a10712d8..396f74b5 100644 --- a/deps/zlib/inftrees.h +++ b/deps/zlib/inftrees.h @@ -41,8 +41,8 @@ typedef struct { examples/enough.c found in the zlib distribution. The arguments to that program are the number of symbols, the initial root table size, and the maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns returns 852, and "enough 30 6 15" for distance codes returns 592. - The initial root table size (9 or 6) is found in the fifth argument of the + returns 852, and "enough 30 6 15" for distance codes returns 592. The + initial root table size (9 or 6) is found in the fifth argument of the inflate_table() calls in inflate.c and infback.c. If the root table size is changed, then these maximum sizes would be need to be recalculated and updated. */ diff --git a/deps/zlib/test/example.c b/deps/zlib/test/example.c index 582a17a3..c3521dd5 100644 --- a/deps/zlib/test/example.c +++ b/deps/zlib/test/example.c @@ -36,12 +36,12 @@ static uLong dictId; /* Adler32 value of the dictionary */ #ifdef Z_SOLO -void *myalloc(void *q, unsigned n, unsigned m) { +static void *myalloc(void *q, unsigned n, unsigned m) { (void)q; return calloc(n, m); } -void myfree(void *q, void *p) { +static void myfree(void *q, void *p) { (void)q; free(p); } @@ -57,7 +57,7 @@ static free_func zfree = (free_func)0; /* =========================================================================== * Test compress() and uncompress() */ -void test_compress(Byte *compr, uLong comprLen, Byte *uncompr, +static void test_compress(Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen) { int err; uLong len = (uLong)strlen(hello)+1; @@ -81,7 +81,7 @@ void test_compress(Byte *compr, uLong comprLen, Byte *uncompr, /* =========================================================================== * Test read/write of .gz files */ -void test_gzio(const char *fname, Byte *uncompr, uLong uncomprLen) { +static void test_gzio(const char *fname, Byte *uncompr, uLong uncomprLen) { #ifdef NO_GZCOMPRESS fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n"); #else @@ -163,7 +163,7 @@ void test_gzio(const char *fname, Byte *uncompr, uLong uncomprLen) { /* =========================================================================== * Test deflate() with small buffers */ -void test_deflate(Byte *compr, uLong comprLen) { +static void test_deflate(Byte *compr, uLong comprLen) { z_stream c_stream; /* compression stream */ int err; uLong len = (uLong)strlen(hello)+1; @@ -198,7 +198,7 @@ void test_deflate(Byte *compr, uLong comprLen) { /* =========================================================================== * Test inflate() with small buffers */ -void test_inflate(Byte *compr, uLong comprLen, Byte *uncompr, +static void test_inflate(Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen) { int err; z_stream d_stream; /* decompression stream */ @@ -237,7 +237,7 @@ void test_inflate(Byte *compr, uLong comprLen, Byte *uncompr, /* =========================================================================== * Test deflate() with large buffers and dynamic change of compression level */ -void test_large_deflate(Byte *compr, uLong comprLen, Byte *uncompr, +static void test_large_deflate(Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen) { z_stream c_stream; /* compression stream */ int err; @@ -290,7 +290,7 @@ void test_large_deflate(Byte *compr, uLong comprLen, Byte *uncompr, /* =========================================================================== * Test inflate() with large buffers */ -void test_large_inflate(Byte *compr, uLong comprLen, Byte *uncompr, +static void test_large_inflate(Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen) { int err; z_stream d_stream; /* decompression stream */ @@ -329,7 +329,7 @@ void test_large_inflate(Byte *compr, uLong comprLen, Byte *uncompr, /* =========================================================================== * Test deflate() with full flush */ -void test_flush(Byte *compr, uLong *comprLen) { +static void test_flush(Byte *compr, uLong *comprLen) { z_stream c_stream; /* compression stream */ int err; uInt len = (uInt)strlen(hello)+1; @@ -364,7 +364,8 @@ void test_flush(Byte *compr, uLong *comprLen) { /* =========================================================================== * Test inflateSync() */ -void test_sync(Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen) { +static void test_sync(Byte *compr, uLong comprLen, Byte *uncompr, + uLong uncomprLen) { int err; z_stream d_stream; /* decompression stream */ @@ -404,7 +405,7 @@ void test_sync(Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen) { /* =========================================================================== * Test deflate() with preset dictionary */ -void test_dict_deflate(Byte *compr, uLong comprLen) { +static void test_dict_deflate(Byte *compr, uLong comprLen) { z_stream c_stream; /* compression stream */ int err; @@ -438,7 +439,7 @@ void test_dict_deflate(Byte *compr, uLong comprLen) { /* =========================================================================== * Test inflate() with a preset dictionary */ -void test_dict_inflate(Byte *compr, uLong comprLen, Byte *uncompr, +static void test_dict_inflate(Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen) { int err; z_stream d_stream; /* decompression stream */ diff --git a/deps/zlib/test/minigzip.c b/deps/zlib/test/minigzip.c index 8a21ddfb..c72356db 100644 --- a/deps/zlib/test/minigzip.c +++ b/deps/zlib/test/minigzip.c @@ -149,12 +149,12 @@ static void pwinerror (s) # include /* for unlink() */ #endif -void *myalloc(void *q, unsigned n, unsigned m) { +static void *myalloc(void *q, unsigned n, unsigned m) { (void)q; return calloc(n, m); } -void myfree(void *q, void *p) { +static void myfree(void *q, void *p) { (void)q; free(p); } @@ -167,7 +167,7 @@ typedef struct gzFile_s { z_stream strm; } *gzFile; -gzFile gz_open(const char *path, int fd, const char *mode) { +static gzFile gz_open(const char *path, int fd, const char *mode) { gzFile gz; int ret; @@ -201,15 +201,15 @@ gzFile gz_open(const char *path, int fd, const char *mode) { return gz; } -gzFile gzopen(const char *path, const char *mode) { +static gzFile gzopen(const char *path, const char *mode) { return gz_open(path, -1, mode); } -gzFile gzdopen(int fd, const char *mode) { +static gzFile gzdopen(int fd, const char *mode) { return gz_open(NULL, fd, mode); } -int gzwrite(gzFile gz, const void *buf, unsigned len) { +static int gzwrite(gzFile gz, const void *buf, unsigned len) { z_stream *strm; unsigned char out[BUFLEN]; @@ -227,7 +227,7 @@ int gzwrite(gzFile gz, const void *buf, unsigned len) { return len; } -int gzread(gzFile gz, void *buf, unsigned len) { +static int gzread(gzFile gz, void *buf, unsigned len) { int ret; unsigned got; unsigned char in[1]; @@ -258,7 +258,7 @@ int gzread(gzFile gz, void *buf, unsigned len) { return len - strm->avail_out; } -int gzclose(gzFile gz) { +static int gzclose(gzFile gz) { z_stream *strm; unsigned char out[BUFLEN]; @@ -283,7 +283,7 @@ int gzclose(gzFile gz) { return Z_OK; } -const char *gzerror(gzFile gz, int *err) { +static const char *gzerror(gzFile gz, int *err) { *err = gz->err; return gz->msg; } @@ -295,7 +295,7 @@ static char *prog; /* =========================================================================== * Display error message and exit */ -void error(const char *msg) { +static void error(const char *msg) { fprintf(stderr, "%s: %s\n", prog, msg); exit(1); } @@ -305,7 +305,7 @@ void error(const char *msg) { /* Try compressing the input file at once using mmap. Return Z_OK if * if success, Z_ERRNO otherwise. */ -int gz_compress_mmap(FILE *in, gzFile out) { +static int gz_compress_mmap(FILE *in, gzFile out) { int len; int err; int ifd = fileno(in); @@ -338,7 +338,7 @@ int gz_compress_mmap(FILE *in, gzFile out) { * Compress input to output then close both files. */ -void gz_compress(FILE *in, gzFile out) { +static void gz_compress(FILE *in, gzFile out) { local char buf[BUFLEN]; int len; int err; @@ -366,7 +366,7 @@ void gz_compress(FILE *in, gzFile out) { /* =========================================================================== * Uncompress input to output then close both files. */ -void gz_uncompress(gzFile in, FILE *out) { +static void gz_uncompress(gzFile in, FILE *out) { local char buf[BUFLEN]; int len; int err; @@ -390,7 +390,7 @@ void gz_uncompress(gzFile in, FILE *out) { * Compress the given file: create a corresponding .gz file and remove the * original. */ -void file_compress(char *file, char *mode) { +static void file_compress(char *file, char *mode) { local char outfile[MAX_NAME_LEN]; FILE *in; gzFile out; @@ -426,7 +426,7 @@ void file_compress(char *file, char *mode) { /* =========================================================================== * Uncompress the given file and remove the original. */ -void file_uncompress(char *file) { +static void file_uncompress(char *file) { local char buf[MAX_NAME_LEN]; char *infile, *outfile; FILE *out; diff --git a/deps/zlib/trees.c b/deps/zlib/trees.c index 8dbdc40b..5ca23e93 100644 --- a/deps/zlib/trees.c +++ b/deps/zlib/trees.c @@ -899,14 +899,19 @@ local void compress_block(deflate_state *s, const ct_data *ltree, const ct_data *dtree) { unsigned dist; /* distance of matched string */ int lc; /* match length or unmatched char (if dist == 0) */ - unsigned sx = 0; /* running index in sym_buf */ + unsigned sx = 0; /* running index in symbol buffers */ unsigned code; /* the code to send */ int extra; /* number of extra bits to send */ if (s->sym_next != 0) do { +#ifdef LIT_MEM + dist = s->d_buf[sx]; + lc = s->l_buf[sx++]; +#else dist = s->sym_buf[sx++] & 0xff; dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; lc = s->sym_buf[sx++]; +#endif if (dist == 0) { send_code(s, lc, ltree); /* send a literal byte */ Tracecv(isgraph(lc), (stderr," '%c' ", lc)); @@ -931,8 +936,12 @@ local void compress_block(deflate_state *s, const ct_data *ltree, } } /* literal or match pair ? */ - /* Check that the overlay between pending_buf and sym_buf is ok: */ + /* Check for no overlay of pending_buf on needed symbols */ +#ifdef LIT_MEM + Assert(s->pending < (s->lit_bufsize << 1) + sx, "pendingBuf overflow"); +#else Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); +#endif } while (sx < s->sym_next); @@ -1082,9 +1091,14 @@ void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, * the current block must be flushed. */ int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) { +#ifdef LIT_MEM + s->d_buf[s->sym_next] = (ush)dist; + s->l_buf[s->sym_next++] = (uch)lc; +#else s->sym_buf[s->sym_next++] = (uch)dist; s->sym_buf[s->sym_next++] = (uch)(dist >> 8); s->sym_buf[s->sym_next++] = (uch)lc; +#endif if (dist == 0) { /* lc is the unmatched char */ s->dyn_ltree[lc].Freq++; diff --git a/deps/zlib/win32/README-WIN32.txt b/deps/zlib/win32/README-WIN32.txt index 2790e838..600fa3f5 100644 --- a/deps/zlib/win32/README-WIN32.txt +++ b/deps/zlib/win32/README-WIN32.txt @@ -16,8 +16,8 @@ is http://zlib.net/ . Before reporting a problem, please check this site to verify that you have the latest version of zlib; otherwise get the latest version and check whether the problem still exists or not. -PLEASE read DLL_FAQ.txt, and the the zlib FAQ http://zlib.net/zlib_faq.html -before asking for help. +PLEASE read DLL_FAQ.txt, and the zlib FAQ http://zlib.net/zlib_faq.html before +asking for help. Manifest: diff --git a/deps/zlib/zlib.h b/deps/zlib/zlib.h index ff0fd7e8..b3e19fce 100644 --- a/deps/zlib/zlib.h +++ b/deps/zlib/zlib.h @@ -936,10 +936,10 @@ ZEXTERN int ZEXPORT inflateSync(z_streamp strm); inflateSync returns Z_OK if a possible full flush point has been found, Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. - In the success case, the application may save the current current value of - total_in which indicates where valid compressed data was found. In the - error case, the application may repeatedly call inflateSync, providing more - input each time, until success or end of the input data. + In the success case, the application may save the current value of total_in + which indicates where valid compressed data was found. In the error case, + the application may repeatedly call inflateSync, providing more input each + time, until success or end of the input data. */ ZEXTERN int ZEXPORT inflateCopy(z_streamp dest,