From f48072a395225f624c6337ea33a3f7231ae80c1e Mon Sep 17 00:00:00 2001 From: siv2r Date: Sat, 20 Aug 2022 10:58:44 +0530 Subject: [PATCH] batch: Generate graphs for batch verification speed up This commit generates two semi-log graphs that visualize the batch verification speed up over single verification (y-axis) wrt the number of signatures (or tweak checks) in the batch (x-axis). The input data points are taken from the batch verify benchmark. GNU plot was used to generate these graphs (plot.gp file). The instructions to reproduce these graphs (on your local machine) are given in doc/speedup-batch.md file. The value of `STRAUSS_MAX_TERMS_PER_BATCH` was calculated (approx) from the generated graphs. Relevant discussion: https://github.com/siv2r/secp256k1/pull/2#issuecomment-1211585236 --- doc/speedup-batch.md | 15 ++ doc/speedup-batch/.gitignore | 1 + doc/speedup-batch/Makefile | 23 +++ doc/speedup-batch/bench.sh | 13 ++ doc/speedup-batch/bench_output.txt | 137 ++++++++++++++++++ doc/speedup-batch/bench_output.txt.log | 127 ++++++++++++++++ doc/speedup-batch/plot.gp | 41 ++++++ .../schnorrsig-speedup-batch.png | Bin 0 -> 8192 bytes .../tweakcheck-speedup-batch.png | Bin 0 -> 8639 bytes src/modules/batch/main_impl.h | 8 + 10 files changed, 365 insertions(+) create mode 100644 doc/speedup-batch.md create mode 100644 doc/speedup-batch/.gitignore create mode 100644 doc/speedup-batch/Makefile create mode 100755 doc/speedup-batch/bench.sh create mode 100644 doc/speedup-batch/bench_output.txt create mode 100644 doc/speedup-batch/bench_output.txt.log create mode 100644 doc/speedup-batch/plot.gp create mode 100644 doc/speedup-batch/schnorrsig-speedup-batch.png create mode 100644 doc/speedup-batch/tweakcheck-speedup-batch.png diff --git a/doc/speedup-batch.md b/doc/speedup-batch.md new file mode 100644 index 0000000000..c695639892 --- /dev/null +++ b/doc/speedup-batch.md @@ -0,0 +1,15 @@ +# Schnorrsig Batch Verification Speedup + +![Speedup over single verification](speedup-batch/schnorrsig-speedup-batch.png) + +# Tweak Pubkey Check Batch Verification Speedup + +![Speedup over single verification](speedup-batch/tweakcheck-speedup-batch.png) + +Build steps +----------- +To generate the above graphs on your local machine: + + $ cd doc/speedup-batch + $ make + $ make speedup-batch.png diff --git a/doc/speedup-batch/.gitignore b/doc/speedup-batch/.gitignore new file mode 100644 index 0000000000..773a6df9ba --- /dev/null +++ b/doc/speedup-batch/.gitignore @@ -0,0 +1 @@ +*.dat diff --git a/doc/speedup-batch/Makefile b/doc/speedup-batch/Makefile new file mode 100644 index 0000000000..a6a270d348 --- /dev/null +++ b/doc/speedup-batch/Makefile @@ -0,0 +1,23 @@ +schnorrsig_data = schnorrsig_batch.dat schnorrsig_single.dat +tweak_data = tweak_batch.dat tweak_single.dat + +bench_output.txt: bench.sh + SECP256K1_BENCH_ITERS=500000 ./bench.sh bench_output.txt + +schnorrsig_batch.dat: bench_output.txt + cat bench_output.txt | grep -v "schnorrsig_batch_verify_1 " | awk '{ gsub(/ /,""); print }' | awk -F, 'match($$0, /schnorrsig_batch_verify_([0-9]+)/, arr) {print arr[1] " " $$3}' > schnorrsig_batch.dat + +schnorrsig_single.dat: bench_output.txt + cat bench_output.txt | awk '{ gsub(/ /,""); print }' | awk -F, 'match($$0, /schnorrsig_verify/) {print $$3}' > schnorrsig_single.dat + +tweak_batch.dat: bench_output.txt + cat bench_output.txt | grep -v "tweak_check_batch_verify_1 " | awk '{ gsub(/ /,""); print }' | awk -F, 'match($$0, /tweak_check_batch_verify_([0-9]+)/, arr) {print arr[1] " " $$3}' > tweak_batch.dat + +tweak_single.dat: bench_output.txt + cat bench_output.txt | awk '{ gsub(/ /,""); print }' | awk -F, 'match($$0, /tweak_add_check/) {print $$3}' > tweak_single.dat + +speedup-batch.png: $(schnorrsig_data) $(tweak_data) plot.gp + gnuplot plot.gp + +clean: + rm *.log *.txt *.dat *.png diff --git a/doc/speedup-batch/bench.sh b/doc/speedup-batch/bench.sh new file mode 100755 index 0000000000..d38d45dceb --- /dev/null +++ b/doc/speedup-batch/bench.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +output_file=$1 +cur_dir=$(pwd) + +cd ../../ +echo "HEAD: $(git rev-parse --short HEAD)" > "$cur_dir/$output_file.log" +make clean +./autogen.sh +./configure --enable-experimental --enable-module-batch --enable-module-schnorrsig >> "$cur_dir/$output_file.log" +make -j +./bench schnorrsig > "$cur_dir/$output_file" +./bench extrakeys >> "$cur_dir/$output_file" \ No newline at end of file diff --git a/doc/speedup-batch/bench_output.txt b/doc/speedup-batch/bench_output.txt new file mode 100644 index 0000000000..9d257341c1 --- /dev/null +++ b/doc/speedup-batch/bench_output.txt @@ -0,0 +1,137 @@ +Benchmark , Min(us) , Avg(us) , Max(us) + +schnorrsig_sign , 50.4 , 50.5 , 50.7 +schnorrsig_verify , 89.1 , 89.2 , 89.3 +schnorrsig_batch_verify_1 , 104.0 , 104.0 , 104.0 +schnorrsig_batch_verify_2 , 89.0 , 89.1 , 89.1 +schnorrsig_batch_verify_3 , 84.1 , 84.1 , 84.1 +schnorrsig_batch_verify_4 , 81.5 , 81.5 , 81.5 +schnorrsig_batch_verify_5 , 79.9 , 79.9 , 79.9 +schnorrsig_batch_verify_7 , 78.0 , 78.1 , 78.3 +schnorrsig_batch_verify_9 , 77.0 , 77.0 , 77.1 +schnorrsig_batch_verify_11 , 76.2 , 76.3 , 76.3 +schnorrsig_batch_verify_14 , 75.6 , 75.6 , 75.6 +schnorrsig_batch_verify_17 , 75.2 , 75.2 , 75.2 +schnorrsig_batch_verify_21 , 74.8 , 74.8 , 74.8 +schnorrsig_batch_verify_26 , 74.5 , 74.6 , 74.9 +schnorrsig_batch_verify_32 , 74.3 , 74.5 , 74.7 +schnorrsig_batch_verify_39 , 74.1 , 74.1 , 74.1 +schnorrsig_batch_verify_47 , 73.9 , 73.9 , 73.9 +schnorrsig_batch_verify_57 , 74.5 , 74.5 , 74.5 +schnorrsig_batch_verify_69 , 74.3 , 74.3 , 74.5 +schnorrsig_batch_verify_83 , 74.1 , 74.1 , 74.2 +schnorrsig_batch_verify_100 , 73.9 , 74.0 , 74.1 +schnorrsig_batch_verify_121 , 74.1 , 74.1 , 74.2 +schnorrsig_batch_verify_146 , 73.9 , 73.9 , 74.0 +schnorrsig_batch_verify_176 , 74.0 , 74.2 , 74.5 +schnorrsig_batch_verify_212 , 73.9 , 74.1 , 74.1 +schnorrsig_batch_verify_255 , 74.0 , 74.0 , 74.1 +schnorrsig_batch_verify_307 , 73.9 , 74.0 , 74.1 +schnorrsig_batch_verify_369 , 73.9 , 73.9 , 73.9 +schnorrsig_batch_verify_443 , 73.9 , 74.1 , 74.3 +schnorrsig_batch_verify_532 , 74.0 , 74.0 , 74.1 +schnorrsig_batch_verify_639 , 73.9 , 74.0 , 74.0 +schnorrsig_batch_verify_767 , 73.9 , 73.9 , 73.9 +schnorrsig_batch_verify_921 , 74.0 , 74.0 , 74.1 +schnorrsig_batch_verify_1106 , 73.9 , 73.9 , 73.9 +schnorrsig_batch_verify_1328 , 73.9 , 74.1 , 74.2 +schnorrsig_batch_verify_1594 , 74.0 , 74.1 , 74.1 +schnorrsig_batch_verify_1913 , 74.0 , 74.0 , 74.0 +schnorrsig_batch_verify_2296 , 74.0 , 74.0 , 74.0 +schnorrsig_batch_verify_2756 , 73.9 , 74.0 , 74.1 +schnorrsig_batch_verify_3308 , 74.1 , 74.1 , 74.2 +schnorrsig_batch_verify_3970 , 74.1 , 74.2 , 74.4 +schnorrsig_batch_verify_4765 , 74.0 , 74.1 , 74.2 +schnorrsig_batch_verify_5719 , 74.0 , 74.1 , 74.1 +schnorrsig_batch_verify_6863 , 74.0 , 74.1 , 74.1 +schnorrsig_batch_verify_8236 , 74.0 , 74.1 , 74.1 +schnorrsig_batch_verify_9884 , 74.0 , 74.1 , 74.3 +schnorrsig_batch_verify_11861 , 74.0 , 74.0 , 74.1 +schnorrsig_batch_verify_14234 , 73.9 , 74.0 , 74.1 +schnorrsig_batch_verify_17081 , 73.9 , 73.9 , 73.9 +schnorrsig_batch_verify_20498 , 73.9 , 74.0 , 74.0 +schnorrsig_batch_verify_24598 , 73.9 , 74.0 , 74.1 +schnorrsig_batch_verify_29518 , 73.9 , 74.0 , 74.1 +schnorrsig_batch_verify_35422 , 73.9 , 73.9 , 73.9 +schnorrsig_batch_verify_42507 , 73.9 , 74.0 , 74.0 +schnorrsig_batch_verify_51009 , 73.9 , 74.1 , 74.3 +schnorrsig_batch_verify_61211 , 73.9 , 73.9 , 74.0 +schnorrsig_batch_verify_73454 , 73.9 , 74.0 , 74.3 +schnorrsig_batch_verify_88145 , 73.9 , 74.0 , 74.1 +schnorrsig_batch_verify_105775 , 74.0 , 74.1 , 74.1 +schnorrsig_batch_verify_126931 , 73.9 , 74.0 , 74.1 +schnorrsig_batch_verify_152318 , 73.9 , 73.9 , 74.0 +schnorrsig_batch_verify_182782 , 73.9 , 73.9 , 74.0 +schnorrsig_batch_verify_219339 , 73.9 , 73.9 , 74.0 +schnorrsig_batch_verify_263207 , 74.0 , 74.1 , 74.3 +schnorrsig_batch_verify_315849 , 73.9 , 74.0 , 74.0 +schnorrsig_batch_verify_379019 , 73.9 , 73.9 , 73.9 +schnorrsig_batch_verify_454823 , 74.0 , 74.0 , 74.0 +Benchmark , Min(us) , Avg(us) , Max(us) + +tweak_add_check , 64.7 , 64.7 , 65.0 +tweak_check_batch_verify_1 , 69.7 , 69.8 , 69.8 +tweak_check_batch_verify_2 , 57.2 , 57.2 , 57.3 +tweak_check_batch_verify_3 , 52.0 , 52.1 , 52.2 +tweak_check_batch_verify_4 , 49.4 , 49.5 , 49.5 +tweak_check_batch_verify_5 , 47.9 , 47.9 , 47.9 +tweak_check_batch_verify_7 , 46.1 , 46.1 , 46.2 +tweak_check_batch_verify_9 , 45.2 , 45.2 , 45.4 +tweak_check_batch_verify_11 , 44.5 , 44.6 , 44.6 +tweak_check_batch_verify_14 , 43.9 , 43.9 , 43.9 +tweak_check_batch_verify_17 , 43.5 , 43.5 , 43.5 +tweak_check_batch_verify_21 , 43.1 , 43.1 , 43.1 +tweak_check_batch_verify_26 , 42.8 , 42.8 , 42.8 +tweak_check_batch_verify_32 , 42.5 , 42.6 , 42.6 +tweak_check_batch_verify_39 , 42.3 , 42.4 , 42.4 +tweak_check_batch_verify_47 , 42.2 , 42.2 , 42.2 +tweak_check_batch_verify_57 , 42.1 , 42.2 , 42.3 +tweak_check_batch_verify_69 , 42.0 , 42.1 , 42.1 +tweak_check_batch_verify_83 , 41.9 , 41.9 , 41.9 +tweak_check_batch_verify_100 , 41.8 , 41.9 , 41.9 +tweak_check_batch_verify_121 , 42.1 , 42.1 , 42.1 +tweak_check_batch_verify_146 , 42.0 , 42.0 , 42.0 +tweak_check_batch_verify_176 , 41.9 , 41.9 , 42.0 +tweak_check_batch_verify_212 , 41.8 , 41.9 , 41.9 +tweak_check_batch_verify_255 , 41.9 , 41.9 , 41.9 +tweak_check_batch_verify_307 , 41.8 , 41.9 , 41.9 +tweak_check_batch_verify_369 , 41.9 , 42.0 , 42.1 +tweak_check_batch_verify_443 , 41.9 , 41.9 , 41.9 +tweak_check_batch_verify_532 , 41.9 , 41.9 , 41.9 +tweak_check_batch_verify_639 , 41.9 , 41.9 , 42.0 +tweak_check_batch_verify_767 , 41.9 , 41.9 , 41.9 +tweak_check_batch_verify_921 , 41.9 , 41.9 , 41.9 +tweak_check_batch_verify_1106 , 41.9 , 41.9 , 41.9 +tweak_check_batch_verify_1328 , 41.9 , 41.9 , 42.0 +tweak_check_batch_verify_1594 , 41.9 , 41.9 , 42.0 +tweak_check_batch_verify_1913 , 41.9 , 41.9 , 41.9 +tweak_check_batch_verify_2296 , 41.9 , 41.9 , 41.9 +tweak_check_batch_verify_2756 , 41.8 , 41.9 , 41.9 +tweak_check_batch_verify_3308 , 41.9 , 41.9 , 42.0 +tweak_check_batch_verify_3970 , 41.9 , 41.9 , 41.9 +tweak_check_batch_verify_4765 , 41.8 , 41.9 , 41.9 +tweak_check_batch_verify_5719 , 41.9 , 42.0 , 42.1 +tweak_check_batch_verify_6863 , 42.0 , 42.0 , 42.0 +tweak_check_batch_verify_8236 , 42.0 , 42.0 , 42.0 +tweak_check_batch_verify_9884 , 41.9 , 41.9 , 42.0 +tweak_check_batch_verify_11861 , 41.9 , 42.0 , 42.1 +tweak_check_batch_verify_14234 , 41.9 , 42.0 , 42.0 +tweak_check_batch_verify_17081 , 41.8 , 41.9 , 41.9 +tweak_check_batch_verify_20498 , 41.8 , 41.9 , 41.9 +tweak_check_batch_verify_24598 , 41.8 , 41.9 , 41.9 +tweak_check_batch_verify_29518 , 41.9 , 41.9 , 41.9 +tweak_check_batch_verify_35422 , 41.9 , 41.9 , 41.9 +tweak_check_batch_verify_42507 , 41.8 , 41.8 , 41.9 +tweak_check_batch_verify_51009 , 41.9 , 41.9 , 41.9 +tweak_check_batch_verify_61211 , 41.8 , 41.8 , 41.8 +tweak_check_batch_verify_73454 , 41.8 , 42.0 , 42.2 +tweak_check_batch_verify_88145 , 41.9 , 41.9 , 41.9 +tweak_check_batch_verify_105775 , 41.8 , 41.8 , 41.8 +tweak_check_batch_verify_126931 , 41.8 , 41.9 , 41.9 +tweak_check_batch_verify_152318 , 41.8 , 41.9 , 42.0 +tweak_check_batch_verify_182782 , 41.9 , 41.9 , 41.9 +tweak_check_batch_verify_219339 , 41.9 , 42.0 , 42.0 +tweak_check_batch_verify_263207 , 41.9 , 42.0 , 42.1 +tweak_check_batch_verify_315849 , 41.9 , 41.9 , 41.9 +tweak_check_batch_verify_379019 , 41.9 , 41.9 , 42.0 +tweak_check_batch_verify_454823 , 41.9 , 41.9 , 41.9 diff --git a/doc/speedup-batch/bench_output.txt.log b/doc/speedup-batch/bench_output.txt.log new file mode 100644 index 0000000000..c289c4aab2 --- /dev/null +++ b/doc/speedup-batch/bench_output.txt.log @@ -0,0 +1,127 @@ +HEAD: 6ddb0d0c +checking build system type... x86_64-pc-linux-gnu +checking host system type... x86_64-pc-linux-gnu +checking for a BSD-compatible install... /usr/bin/install -c +checking whether build environment is sane... yes +checking for a thread-safe mkdir -p... /usr/bin/mkdir -p +checking for gawk... gawk +checking whether make sets $(MAKE)... yes +checking whether make supports nested variables... yes +checking whether make supports nested variables... (cached) yes +checking for gcc... gcc +checking whether the C compiler works... yes +checking for C compiler default output file name... a.out +checking for suffix of executables... +checking whether we are cross compiling... no +checking for suffix of object files... o +checking whether we are using the GNU C compiler... yes +checking whether gcc accepts -g... yes +checking for gcc option to accept ISO C89... none needed +checking whether gcc understands -c and -o together... yes +checking whether make supports the include directive... yes (GNU style) +checking dependency style of gcc... gcc3 +checking dependency style of gcc... gcc3 +checking for ar... ar +checking the archiver (ar) interface... ar +checking how to print strings... printf +checking for a sed that does not truncate output... /usr/bin/sed +checking for grep that handles long lines and -e... /usr/bin/grep +checking for egrep... /usr/bin/grep -E +checking for fgrep... /usr/bin/grep -F +checking for ld used by gcc... /usr/bin/ld +checking if the linker (/usr/bin/ld) is GNU ld... yes +checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B +checking the name lister (/usr/bin/nm -B) interface... BSD nm +checking whether ln -s works... yes +checking the maximum length of command line arguments... 1572864 +checking how to convert x86_64-pc-linux-gnu file names to x86_64-pc-linux-gnu format... func_convert_file_noop +checking how to convert x86_64-pc-linux-gnu file names to toolchain format... func_convert_file_noop +checking for /usr/bin/ld option to reload object files... -r +checking for objdump... objdump +checking how to recognize dependent libraries... pass_all +checking for dlltool... no +checking how to associate runtime and link libraries... printf %s\n +checking for archiver @FILE support... @ +checking for strip... strip +checking for ranlib... ranlib +checking command to parse /usr/bin/nm -B output from gcc object... ok +checking for sysroot... no +checking for a working dd... /usr/bin/dd +checking how to truncate binary pipes... /usr/bin/dd bs=4096 count=1 +checking for mt... mt +checking if mt is a manifest tool... no +checking how to run the C preprocessor... gcc -E +checking for ANSI C header files... yes +checking for sys/types.h... yes +checking for sys/stat.h... yes +checking for stdlib.h... yes +checking for string.h... yes +checking for memory.h... yes +checking for strings.h... yes +checking for inttypes.h... yes +checking for stdint.h... yes +checking for unistd.h... yes +checking for dlfcn.h... yes +checking for objdir... .libs +checking if gcc supports -fno-rtti -fno-exceptions... no +checking for gcc option to produce PIC... -fPIC -DPIC +checking if gcc PIC flag -fPIC -DPIC works... yes +checking if gcc static flag -static works... yes +checking if gcc supports -c -o file.o... yes +checking if gcc supports -c -o file.o... (cached) yes +checking whether the gcc linker (/usr/bin/ld -m elf_x86_64) supports shared libraries... yes +checking whether -lc should be explicitly linked in... no +checking dynamic linker characteristics... GNU/Linux ld.so +checking how to hardcode library paths into programs... immediate +checking whether stripping libraries is possible... yes +checking if libtool supports shared libraries... yes +checking whether to build shared libraries... yes +checking whether to build static libraries... yes +checking if gcc supports -Werror=unknown-warning-option... no +checking if gcc supports -std=c89 -pedantic -Wno-long-long -Wnested-externs -Wshadow -Wstrict-prototypes -Wundef... yes +checking if gcc supports -Wno-overlength-strings... yes +checking if gcc supports -Wall... yes +checking if gcc supports -Wno-unused-function... yes +checking if gcc supports -Wextra... yes +checking if gcc supports -Wcast-align... yes +checking if gcc supports -Wcast-align=strict... yes +checking if gcc supports -Wconditional-uninitialized... no +checking if gcc supports -fvisibility=hidden... yes +checking for valgrind support... yes +checking for x86_64 assembly availability... yes +configure: ****** +configure: WARNING: experimental build +configure: Experimental features do not have stable APIs or properties, and may not be safe for production use. +configure: Building batch verification module: yes +configure: ****** +checking that generated files are newer than configure... done +configure: creating ./config.status +config.status: creating Makefile +config.status: creating libsecp256k1.pc +config.status: creating src/libsecp256k1-config.h +config.status: src/libsecp256k1-config.h is unchanged +config.status: executing depfiles commands +config.status: executing libtool commands + +Build Options: + with external callbacks = no + with benchmarks = yes + with tests = yes + with coverage = no + with examples = no + module ecdh = no + module recovery = no + module extrakeys = yes + module schnorrsig = yes + module batch = yes + + asm = x86_64 + ecmult window size = 15 + ecmult gen prec. bits = 4 + + valgrind = yes + CC = gcc + CPPFLAGS = + SECP_CFLAGS = -O2 -std=c89 -pedantic -Wno-long-long -Wnested-externs -Wshadow -Wstrict-prototypes -Wundef -Wno-overlength-strings -Wall -Wno-unused-function -Wextra -Wcast-align -Wcast-align=strict -fvisibility=hidden + CFLAGS = -g -O2 + LDFLAGS = diff --git a/doc/speedup-batch/plot.gp b/doc/speedup-batch/plot.gp new file mode 100644 index 0000000000..7960ca0fd0 --- /dev/null +++ b/doc/speedup-batch/plot.gp @@ -0,0 +1,41 @@ +set style line 80 lt rgb "#808080" +set style line 81 lt 0 +set style line 81 lt rgb "#808080" +set grid back linestyle 81 +set border 3 back linestyle 80 +set xtics nomirror +set ytics nomirror +set style line 1 lt rgb "#A00000" lw 2 pt 1 +set style line 2 lt rgb "#00A000" lw 2 pt 6 +set style line 3 lt rgb "#5060D0" lw 2 pt 2 +set style line 4 lt rgb "#F25900" lw 2 pt 9 +set key bottom right +set autoscale +unset log +unset label +set xtic auto +set ytic auto +set title "Batch signature verification in libsecp256k1" +set xlabel "Number of signatures (logarithmic)" +set ylabel "Verification time per signature in us" +set grid +set logscale x +set mxtics 10 + +# Generate graph of Schnorr signature benchmark +schnorrsig_single_val=system("cat schnorrsig_single.dat") +set xrange [1.1:] +set xtics add ("2" 2) +set yrange [0.9:] +set ytics -1,0.1,3 +set ylabel "Speedup over single verification" +set term png size 800,600 +set output 'schnorrsig-speedup-batch.png' +plot "schnorrsig_batch.dat" using 1:(schnorrsig_single_val/$2) with points title "" ls 1 + +# Generate graph of tweaked x-only pubkey check benchmark +set title "Batch tweaked x-only pubkey check in libsecp256k1" +set xlabel "Number of tweak checks (logarithmic)" +tweak_single_val=system("cat tweak_single.dat") +set output 'tweakcheck-speedup-batch.png' +plot "tweak_batch.dat" using 1:(tweak_single_val/$2) with points title "" ls 1 diff --git a/doc/speedup-batch/schnorrsig-speedup-batch.png b/doc/speedup-batch/schnorrsig-speedup-batch.png new file mode 100644 index 0000000000000000000000000000000000000000..536b831503ce3ef518dd8fb771952831a169d979 GIT binary patch literal 8192 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 Q%Px# literal 0 HcmV?d00001 diff --git a/doc/speedup-batch/tweakcheck-speedup-batch.png b/doc/speedup-batch/tweakcheck-speedup-batch.png new file mode 100644 index 0000000000000000000000000000000000000000..f12e6e273f1915e985c46ff175b0f5c162f0a26d GIT binary patch literal 8639 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 OsHLv=SGn5Fuzv#^D0X%L literal 0 HcmV?d00001 diff --git a/src/modules/batch/main_impl.h b/src/modules/batch/main_impl.h index 2e8f5b0aa0..81badd5b3b 100644 --- a/src/modules/batch/main_impl.h +++ b/src/modules/batch/main_impl.h @@ -3,6 +3,10 @@ #include "include/secp256k1_batch.h" +/* Maximum number of scalar-point pairs on the batch + * for which `secp256k1_batch_verify` remains efficient */ +#define STRAUSS_MAX_TERMS_PER_BATCH 106 + /* Assume two batch objects (batch1 and batch2) and we call * `batch_add_tweak_check` on batch1 and `batch_add_schnorrsig` on batch2. * In this case, the same randomizer will be generated if the input bytes to @@ -102,6 +106,10 @@ secp256k1_batch* secp256k1_batch_create(const secp256k1_context* ctx, size_t max secp256k1_batch* batch; size_t batch_scratch_size; unsigned char zeros[16] = {0}; + /* max number of scalar-point pairs on scratch up to which Strauss multi multiplication is efficient */ + if (max_terms > STRAUSS_MAX_TERMS_PER_BATCH) { + max_terms = STRAUSS_MAX_TERMS_PER_BATCH; + } VERIFY_CHECK(ctx != NULL); ARG_CHECK(max_terms != 0);