Commit 818d8fb7f55e64b127bd12cc45e5587c05a99784

Daniel Mendler 2019-05-03T17:39:10

Rework handling of tunable cutoffs * In the default settings, a cutoff X can be modified at runtime by adjusting the corresponding X_CUTOFF variable. * Tunability of the library can be disabled at compile time by defining the MP_FIXED_CUTOFFS macro. * There is an additional file tommath_cutoffs.h, which defines the default cutoffs. These can be adjusted manually or by the autotuner.

diff --git a/bn_cutoffs.c b/bn_cutoffs.c
new file mode 100644
index 0000000..b02ab71
--- /dev/null
+++ b/bn_cutoffs.c
@@ -0,0 +1,14 @@
+#include "tommath_private.h"
+#ifdef BN_CUTOFFS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+#ifndef MP_FIXED_CUTOFFS
+#include "tommath_cutoffs.h"
+int KARATSUBA_MUL_CUTOFF = MP_DEFAULT_KARATSUBA_MUL_CUTOFF,
+    KARATSUBA_SQR_CUTOFF = MP_DEFAULT_KARATSUBA_SQR_CUTOFF,
+    TOOM_MUL_CUTOFF = MP_DEFAULT_TOOM_MUL_CUTOFF,
+    TOOM_SQR_CUTOFF = MP_DEFAULT_TOOM_SQR_CUTOFF;
+#endif
+
+#endif
diff --git a/bn_mp_mul.c b/bn_mp_mul.c
index 5ea592b..e206152 100644
--- a/bn_mp_mul.c
+++ b/bn_mp_mul.c
@@ -26,8 +26,8 @@ int mp_mul(const mp_int *a, const mp_int *b, mp_int *c)
     * Using it to cut the input into slices small enough for fast_s_mp_mul_digs
     * was actually slower on the author's machine, but YMMV.
     */
-   if ((MP_MIN(len_a, len_b) < KARATSUBA_MUL_CUTOFF)
-       || ((MP_MAX(len_a, len_b) / 2) < KARATSUBA_MUL_CUTOFF)) {
+   if ((MP_MIN(len_a, len_b) < MP_KARATSUBA_MUL_CUTOFF)
+       || ((MP_MAX(len_a, len_b) / 2) < MP_KARATSUBA_MUL_CUTOFF)) {
       goto GO_ON;
    }
    /*
@@ -45,13 +45,13 @@ GO_ON:
 
    /* use Toom-Cook? */
 #ifdef BN_S_MP_TOOM_MUL_C
-   if (MP_MIN(a->used, b->used) >= TOOM_MUL_CUTOFF) {
+   if (MP_MIN(a->used, b->used) >= MP_TOOM_MUL_CUTOFF) {
       res = s_mp_toom_mul(a, b, c);
    } else
 #endif
 #ifdef BN_S_MP_KARATSUBA_MUL_C
       /* use Karatsuba? */
-      if (MP_MIN(a->used, b->used) >= KARATSUBA_MUL_CUTOFF) {
+      if (MP_MIN(a->used, b->used) >= MP_KARATSUBA_MUL_CUTOFF) {
          res = s_mp_karatsuba_mul(a, b, c);
       } else
 #endif
diff --git a/bn_mp_sqr.c b/bn_mp_sqr.c
index 531939f..da12929 100644
--- a/bn_mp_sqr.c
+++ b/bn_mp_sqr.c
@@ -10,13 +10,13 @@ int mp_sqr(const mp_int *a, mp_int *b)
 
 #ifdef BN_S_MP_TOOM_SQR_C
    /* use Toom-Cook? */
-   if (a->used >= TOOM_SQR_CUTOFF) {
+   if (a->used >= MP_TOOM_SQR_CUTOFF) {
       res = s_mp_toom_sqr(a, b);
       /* Karatsuba? */
    } else
 #endif
 #ifdef BN_S_MP_KARATSUBA_SQR_C
-      if (a->used >= KARATSUBA_SQR_CUTOFF) {
+      if (a->used >= MP_KARATSUBA_SQR_CUTOFF) {
          res = s_mp_karatsuba_sqr(a, b);
       } else
 #endif
diff --git a/bncore.c b/bncore.c
deleted file mode 100644
index 0be0e8d..0000000
--- a/bncore.c
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "tommath_private.h"
-#ifdef BNCORE_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis */
-/* SPDX-License-Identifier: Unlicense */
-
-/* Known optimal configurations
-
- CPU                    /Compiler     /MUL CUTOFF/SQR CUTOFF
--------------------------------------------------------------
- Intel P4 Northwood     /GCC v3.4.1   /        88/       128/LTM 0.32 ;-)
- AMD Athlon64           /GCC v3.4.4   /        80/       120/LTM 0.35
-
-*/
-
-int     KARATSUBA_MUL_CUTOFF = 80,      /* Min. number of digits before Karatsuba multiplication is used. */
-        KARATSUBA_SQR_CUTOFF = 120,     /* Min. number of digits before Karatsuba squaring is used. */
-
-        TOOM_MUL_CUTOFF      = 350,      /* no optimal values of these are known yet so set em high */
-        TOOM_SQR_CUTOFF      = 400;
-#endif
diff --git a/callgraph.txt b/callgraph.txt
index 3922bb2..505c7ea 100644
--- a/callgraph.txt
+++ b/callgraph.txt
@@ -1,4 +1,4 @@
-BNCORE_C
+BN_CUTOFFS_C
 
 
 BN_DEPRECATED_C
diff --git a/libtommath_VS2008.vcproj b/libtommath_VS2008.vcproj
index 85b5b82..db7a185 100644
--- a/libtommath_VS2008.vcproj
+++ b/libtommath_VS2008.vcproj
@@ -313,6 +313,10 @@
 	</References>
 	<Files>
 		<File
+			RelativePath="bn_cutoffs.c"
+			>
+		</File>
+		<File
 			RelativePath="bn_deprecated.c"
 			>
 		</File>
@@ -893,15 +897,15 @@
 			>
 		</File>
 		<File
-			RelativePath="bncore.c"
+			RelativePath="tommath.h"
 			>
 		</File>
 		<File
-			RelativePath="tommath.h"
+			RelativePath="tommath_class.h"
 			>
 		</File>
 		<File
-			RelativePath="tommath_class.h"
+			RelativePath="tommath_cutoffs.h"
 			>
 		</File>
 		<File
diff --git a/makefile b/makefile
index c797533..d1d2e23 100644
--- a/makefile
+++ b/makefile
@@ -26,10 +26,10 @@ endif
 LCOV_ARGS=--directory .
 
 #START_INS
-OBJECTS=bn_deprecated.o bn_mp_2expt.o bn_mp_abs.o bn_mp_add.o bn_mp_add_d.o bn_mp_addmod.o bn_mp_and.o \
-bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp_cmp.o bn_mp_cmp_d.o bn_mp_cmp_mag.o bn_mp_cnt_lsb.o \
-bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_decr.o bn_mp_div.o bn_mp_div_2.o bn_mp_div_2d.o \
-bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o bn_mp_dr_setup.o \
+OBJECTS=bn_cutoffs.o bn_deprecated.o bn_mp_2expt.o bn_mp_abs.o bn_mp_add.o bn_mp_add_d.o bn_mp_addmod.o \
+bn_mp_and.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp_cmp.o bn_mp_cmp_d.o bn_mp_cmp_mag.o \
+bn_mp_cnt_lsb.o bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_decr.o bn_mp_div.o bn_mp_div_2.o \
+bn_mp_div_2d.o bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o bn_mp_dr_setup.o \
 bn_mp_error_to_string.o bn_mp_exch.o bn_mp_export.o bn_mp_expt_d.o bn_mp_expt_d_ex.o bn_mp_exptmod.o \
 bn_mp_exteuclid.o bn_mp_fread.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_bit.o bn_mp_get_double.o \
 bn_mp_get_int.o bn_mp_get_long.o bn_mp_get_long_long.o bn_mp_grow.o bn_mp_ilogb.o bn_mp_import.o \
@@ -52,8 +52,7 @@ bn_mp_toradix.o bn_mp_toradix_n.o bn_mp_unsigned_bin_size.o bn_mp_xor.o bn_mp_ze
 bn_s_mp_add.o bn_s_mp_balance_mul.o bn_s_mp_exptmod.o bn_s_mp_exptmod_fast.o bn_s_mp_invmod_fast.o \
 bn_s_mp_invmod_slow.o bn_s_mp_karatsuba_mul.o bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o \
 bn_s_mp_mul_digs.o bn_s_mp_mul_digs_fast.o bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o \
-bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o \
-bncore.o
+bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o
 
 #END_INS
 
diff --git a/makefile.mingw b/makefile.mingw
index 6ab8a01..374733a 100644
--- a/makefile.mingw
+++ b/makefile.mingw
@@ -29,10 +29,10 @@ LIBMAIN_I =libtommath.dll.a
 LIBMAIN_D =libtommath.dll
 
 #List of objects to compile (all goes to libtommath.a)
-OBJECTS=bn_deprecated.o bn_mp_2expt.o bn_mp_abs.o bn_mp_add.o bn_mp_add_d.o bn_mp_addmod.o bn_mp_and.o \
-bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp_cmp.o bn_mp_cmp_d.o bn_mp_cmp_mag.o bn_mp_cnt_lsb.o \
-bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_decr.o bn_mp_div.o bn_mp_div_2.o bn_mp_div_2d.o \
-bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o bn_mp_dr_setup.o \
+OBJECTS=bn_cutoffs.o bn_deprecated.o bn_mp_2expt.o bn_mp_abs.o bn_mp_add.o bn_mp_add_d.o bn_mp_addmod.o \
+bn_mp_and.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp_cmp.o bn_mp_cmp_d.o bn_mp_cmp_mag.o \
+bn_mp_cnt_lsb.o bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_decr.o bn_mp_div.o bn_mp_div_2.o \
+bn_mp_div_2d.o bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o bn_mp_dr_setup.o \
 bn_mp_error_to_string.o bn_mp_exch.o bn_mp_export.o bn_mp_expt_d.o bn_mp_expt_d_ex.o bn_mp_exptmod.o \
 bn_mp_exteuclid.o bn_mp_fread.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_bit.o bn_mp_get_double.o \
 bn_mp_get_int.o bn_mp_get_long.o bn_mp_get_long_long.o bn_mp_grow.o bn_mp_ilogb.o bn_mp_import.o \
@@ -55,8 +55,7 @@ bn_mp_toradix.o bn_mp_toradix_n.o bn_mp_unsigned_bin_size.o bn_mp_xor.o bn_mp_ze
 bn_s_mp_add.o bn_s_mp_balance_mul.o bn_s_mp_exptmod.o bn_s_mp_exptmod_fast.o bn_s_mp_invmod_fast.o \
 bn_s_mp_invmod_slow.o bn_s_mp_karatsuba_mul.o bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o \
 bn_s_mp_mul_digs.o bn_s_mp_mul_digs_fast.o bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o \
-bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o \
-bncore.o
+bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o
 
 HEADERS_PUB=tommath.h tommath_class.h tommath_superclass.h
 
diff --git a/makefile.msvc b/makefile.msvc
index 3fff7c6..0b2b212 100644
--- a/makefile.msvc
+++ b/makefile.msvc
@@ -21,10 +21,10 @@ LTM_LDFLAGS = advapi32.lib
 LIBMAIN_S =tommath.lib
 
 #List of objects to compile (all goes to tommath.lib)
-OBJECTS=bn_deprecated.obj bn_mp_2expt.obj bn_mp_abs.obj bn_mp_add.obj bn_mp_add_d.obj bn_mp_addmod.obj bn_mp_and.obj \
-bn_mp_clamp.obj bn_mp_clear.obj bn_mp_clear_multi.obj bn_mp_cmp.obj bn_mp_cmp_d.obj bn_mp_cmp_mag.obj bn_mp_cnt_lsb.obj \
-bn_mp_complement.obj bn_mp_copy.obj bn_mp_count_bits.obj bn_mp_decr.obj bn_mp_div.obj bn_mp_div_2.obj bn_mp_div_2d.obj \
-bn_mp_div_3.obj bn_mp_div_d.obj bn_mp_dr_is_modulus.obj bn_mp_dr_reduce.obj bn_mp_dr_setup.obj \
+OBJECTS=bn_cutoffs.obj bn_deprecated.obj bn_mp_2expt.obj bn_mp_abs.obj bn_mp_add.obj bn_mp_add_d.obj bn_mp_addmod.obj \
+bn_mp_and.obj bn_mp_clamp.obj bn_mp_clear.obj bn_mp_clear_multi.obj bn_mp_cmp.obj bn_mp_cmp_d.obj bn_mp_cmp_mag.obj \
+bn_mp_cnt_lsb.obj bn_mp_complement.obj bn_mp_copy.obj bn_mp_count_bits.obj bn_mp_decr.obj bn_mp_div.obj bn_mp_div_2.obj \
+bn_mp_div_2d.obj bn_mp_div_3.obj bn_mp_div_d.obj bn_mp_dr_is_modulus.obj bn_mp_dr_reduce.obj bn_mp_dr_setup.obj \
 bn_mp_error_to_string.obj bn_mp_exch.obj bn_mp_export.obj bn_mp_expt_d.obj bn_mp_expt_d_ex.obj bn_mp_exptmod.obj \
 bn_mp_exteuclid.obj bn_mp_fread.obj bn_mp_fwrite.obj bn_mp_gcd.obj bn_mp_get_bit.obj bn_mp_get_double.obj \
 bn_mp_get_int.obj bn_mp_get_long.obj bn_mp_get_long_long.obj bn_mp_grow.obj bn_mp_ilogb.obj bn_mp_import.obj \
@@ -47,8 +47,7 @@ bn_mp_toradix.obj bn_mp_toradix_n.obj bn_mp_unsigned_bin_size.obj bn_mp_xor.obj 
 bn_s_mp_add.obj bn_s_mp_balance_mul.obj bn_s_mp_exptmod.obj bn_s_mp_exptmod_fast.obj bn_s_mp_invmod_fast.obj \
 bn_s_mp_invmod_slow.obj bn_s_mp_karatsuba_mul.obj bn_s_mp_karatsuba_sqr.obj bn_s_mp_montgomery_reduce_fast.obj \
 bn_s_mp_mul_digs.obj bn_s_mp_mul_digs_fast.obj bn_s_mp_mul_high_digs.obj bn_s_mp_mul_high_digs_fast.obj \
-bn_s_mp_reverse.obj bn_s_mp_sqr.obj bn_s_mp_sqr_fast.obj bn_s_mp_sub.obj bn_s_mp_toom_mul.obj bn_s_mp_toom_sqr.obj \
-bncore.obj
+bn_s_mp_reverse.obj bn_s_mp_sqr.obj bn_s_mp_sqr_fast.obj bn_s_mp_sub.obj bn_s_mp_toom_mul.obj bn_s_mp_toom_sqr.obj
 
 HEADERS_PUB=tommath.h tommath_class.h tommath_superclass.h
 
diff --git a/makefile.shared b/makefile.shared
index 6b9e18e..8c5d548 100644
--- a/makefile.shared
+++ b/makefile.shared
@@ -23,10 +23,10 @@ LTLINK = $(LIBTOOL) --mode=link --tag=CC $(CC)
 LCOV_ARGS=--directory .libs --directory .
 
 #START_INS
-OBJECTS=bn_deprecated.o bn_mp_2expt.o bn_mp_abs.o bn_mp_add.o bn_mp_add_d.o bn_mp_addmod.o bn_mp_and.o \
-bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp_cmp.o bn_mp_cmp_d.o bn_mp_cmp_mag.o bn_mp_cnt_lsb.o \
-bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_decr.o bn_mp_div.o bn_mp_div_2.o bn_mp_div_2d.o \
-bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o bn_mp_dr_setup.o \
+OBJECTS=bn_cutoffs.o bn_deprecated.o bn_mp_2expt.o bn_mp_abs.o bn_mp_add.o bn_mp_add_d.o bn_mp_addmod.o \
+bn_mp_and.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp_cmp.o bn_mp_cmp_d.o bn_mp_cmp_mag.o \
+bn_mp_cnt_lsb.o bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_decr.o bn_mp_div.o bn_mp_div_2.o \
+bn_mp_div_2d.o bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o bn_mp_dr_setup.o \
 bn_mp_error_to_string.o bn_mp_exch.o bn_mp_export.o bn_mp_expt_d.o bn_mp_expt_d_ex.o bn_mp_exptmod.o \
 bn_mp_exteuclid.o bn_mp_fread.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_bit.o bn_mp_get_double.o \
 bn_mp_get_int.o bn_mp_get_long.o bn_mp_get_long_long.o bn_mp_grow.o bn_mp_ilogb.o bn_mp_import.o \
@@ -49,8 +49,7 @@ bn_mp_toradix.o bn_mp_toradix_n.o bn_mp_unsigned_bin_size.o bn_mp_xor.o bn_mp_ze
 bn_s_mp_add.o bn_s_mp_balance_mul.o bn_s_mp_exptmod.o bn_s_mp_exptmod_fast.o bn_s_mp_invmod_fast.o \
 bn_s_mp_invmod_slow.o bn_s_mp_karatsuba_mul.o bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o \
 bn_s_mp_mul_digs.o bn_s_mp_mul_digs_fast.o bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o \
-bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o \
-bncore.o
+bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o
 
 #END_INS
 
diff --git a/makefile.unix b/makefile.unix
index c648298..beb7abd 100644
--- a/makefile.unix
+++ b/makefile.unix
@@ -30,10 +30,10 @@ LTM_LDFLAGS = $(LDFLAGS)
 #Library to be created (this makefile builds only static library)
 LIBMAIN_S = libtommath.a
 
-OBJECTS=bn_deprecated.o bn_mp_2expt.o bn_mp_abs.o bn_mp_add.o bn_mp_add_d.o bn_mp_addmod.o bn_mp_and.o \
-bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp_cmp.o bn_mp_cmp_d.o bn_mp_cmp_mag.o bn_mp_cnt_lsb.o \
-bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_decr.o bn_mp_div.o bn_mp_div_2.o bn_mp_div_2d.o \
-bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o bn_mp_dr_setup.o \
+OBJECTS=bn_cutoffs.o bn_deprecated.o bn_mp_2expt.o bn_mp_abs.o bn_mp_add.o bn_mp_add_d.o bn_mp_addmod.o \
+bn_mp_and.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp_cmp.o bn_mp_cmp_d.o bn_mp_cmp_mag.o \
+bn_mp_cnt_lsb.o bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_decr.o bn_mp_div.o bn_mp_div_2.o \
+bn_mp_div_2d.o bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o bn_mp_dr_setup.o \
 bn_mp_error_to_string.o bn_mp_exch.o bn_mp_export.o bn_mp_expt_d.o bn_mp_expt_d_ex.o bn_mp_exptmod.o \
 bn_mp_exteuclid.o bn_mp_fread.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_bit.o bn_mp_get_double.o \
 bn_mp_get_int.o bn_mp_get_long.o bn_mp_get_long_long.o bn_mp_grow.o bn_mp_ilogb.o bn_mp_import.o \
@@ -56,8 +56,7 @@ bn_mp_toradix.o bn_mp_toradix_n.o bn_mp_unsigned_bin_size.o bn_mp_xor.o bn_mp_ze
 bn_s_mp_add.o bn_s_mp_balance_mul.o bn_s_mp_exptmod.o bn_s_mp_exptmod_fast.o bn_s_mp_invmod_fast.o \
 bn_s_mp_invmod_slow.o bn_s_mp_karatsuba_mul.o bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o \
 bn_s_mp_mul_digs.o bn_s_mp_mul_digs_fast.o bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o \
-bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o \
-bncore.o
+bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o
 
 HEADERS_PUB=tommath.h tommath_class.h tommath_superclass.h
 
diff --git a/tommath.h b/tommath.h
index 44c35df..2ffcb68 100644
--- a/tommath.h
+++ b/tommath.h
@@ -117,11 +117,15 @@ typedef uint64_t             mp_word;
 
 typedef int           mp_err;
 
-/* you'll have to tune these... */
-extern int KARATSUBA_MUL_CUTOFF,
-       KARATSUBA_SQR_CUTOFF,
-       TOOM_MUL_CUTOFF,
-       TOOM_SQR_CUTOFF;
+/* tunable cutoffs */
+
+#ifndef MP_FIXED_CUTOFFS
+extern int
+KARATSUBA_MUL_CUTOFF,
+KARATSUBA_SQR_CUTOFF,
+TOOM_MUL_CUTOFF,
+TOOM_SQR_CUTOFF;
+#endif
 
 /* define this to use lower memory usage routines (exptmods mostly) */
 /* #define MP_LOW_MEM */
diff --git a/tommath_class.h b/tommath_class.h
index 2a8e438..57360a0 100644
--- a/tommath_class.h
+++ b/tommath_class.h
@@ -10,6 +10,7 @@
 #endif
 #define LTM1
 #if defined(LTM_ALL)
+#   define BN_CUTOFFS_C
 #   define BN_DEPRECATED_C
 #   define BN_MP_2EXPT_C
 #   define BN_MP_ABS_C
@@ -155,8 +156,10 @@
 #   define BN_S_MP_SUB_C
 #   define BN_S_MP_TOOM_MUL_C
 #   define BN_S_MP_TOOM_SQR_C
-#   define BNCORE_C
 #endif
+#if defined(BN_CUTOFFS_C)
+#endif
+
 #if defined(BN_DEPRECATED_C)
 #   define BN_FAST_MP_INVMOD_C
 #   define BN_S_MP_INVMOD_FAST_C
@@ -1246,9 +1249,6 @@
 #   define BN_MP_CLEAR_MULTI_C
 #endif
 
-#if defined(BNCORE_C)
-#endif
-
 #ifdef LTM3
 #   define LTM_LAST
 #endif
diff --git a/tommath_cutoffs.h b/tommath_cutoffs.h
new file mode 100644
index 0000000..65072b1
--- /dev/null
+++ b/tommath_cutoffs.h
@@ -0,0 +1,7 @@
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+#define MP_DEFAULT_KARATSUBA_MUL_CUTOFF 80
+#define MP_DEFAULT_KARATSUBA_SQR_CUTOFF 120
+#define MP_DEFAULT_TOOM_MUL_CUTOFF      350
+#define MP_DEFAULT_TOOM_SQR_CUTOFF      400
diff --git a/tommath_private.h b/tommath_private.h
index 88d5de6..1f5c40d 100644
--- a/tommath_private.h
+++ b/tommath_private.h
@@ -10,6 +10,34 @@
 extern "C" {
 #endif
 
+/* Tunable cutoffs
+ * ---------------
+ *
+ *  - In the default settings, a cutoff X can be modified at runtime
+ *    by adjusting the corresponding X_CUTOFF variable.
+ *
+ *  - Tunability of the library can be disabled at compile time
+ *    by defining the MP_FIXED_CUTOFFS macro.
+ *
+ *  - There is an additional file tommath_cutoffs.h, which defines
+ *    the default cutoffs. These can be adjusted manually or by the
+ *    autotuner.
+ *
+ */
+
+#ifdef MP_FIXED_CUTOFFS
+#  include "tommath_cutoffs.h"
+#  define MP_KARATSUBA_MUL_CUTOFF MP_DEFAULT_KARATSUBA_MUL_CUTOFF
+#  define MP_KARATSUBA_SQR_CUTOFF MP_DEFAULT_KARATSUBA_SQR_CUTOFF
+#  define MP_TOOM_MUL_CUTOFF      MP_DEFAULT_TOOM_MUL_CUTOFF
+#  define MP_TOOM_SQR_CUTOFF      MP_DEFAULT_TOOM_SQR_CUTOFF
+#else
+#  define MP_KARATSUBA_MUL_CUTOFF KARATSUBA_MUL_CUTOFF
+#  define MP_KARATSUBA_SQR_CUTOFF KARATSUBA_SQR_CUTOFF
+#  define MP_TOOM_MUL_CUTOFF      TOOM_MUL_CUTOFF
+#  define MP_TOOM_SQR_CUTOFF      TOOM_SQR_CUTOFF
+#endif
+
 /* define heap macros */
 #ifndef MP_MALLOC
 /* default to libc stuff */