Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an experimental batch module #1134

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ env:
ECDH: no
RECOVERY: no
SCHNORRSIG: no
BATCH: no
### test options
SECP256K1_TEST_ITERS:
BENCH: yes
Expand Down Expand Up @@ -67,12 +68,12 @@ task:
<< : *LINUX_CONTAINER
matrix: &ENV_MATRIX
- env: {WIDEMUL: int64, RECOVERY: yes}
- env: {WIDEMUL: int64, ECDH: yes, SCHNORRSIG: yes}
- env: {WIDEMUL: int64, ECDH: yes, SCHNORRSIG: yes, EXPERIMENTAL: yes, BATCH: yes}
- env: {WIDEMUL: int128}
- env: {WIDEMUL: int128, RECOVERY: yes, SCHNORRSIG: yes}
- env: {WIDEMUL: int128, ECDH: yes, SCHNORRSIG: yes}
- env: {WIDEMUL: int128, RECOVERY: yes, SCHNORRSIG: yes, EXPERIMENTAL: yes, BATCH: yes}
- env: {WIDEMUL: int128, ECDH: yes, SCHNORRSIG: yes, EXPERIMENTAL: yes, BATCH: yes}
- env: {WIDEMUL: int128, ASM: x86_64}
- env: { RECOVERY: yes, SCHNORRSIG: yes}
- env: { RECOVERY: yes, SCHNORRSIG: yes, EXPERIMENTAL: yes, BATCH: yes}
- env: {BUILD: distcheck, WITH_VALGRIND: no, CTIMETEST: no, BENCH: no}
- env: {CPPFLAGS: -DDETERMINISTIC}
- env: {CFLAGS: -O0, CTIMETEST: no}
Expand All @@ -96,6 +97,8 @@ task:
ECDH: yes
RECOVERY: yes
SCHNORRSIG: yes
EXPERIMENTAL: yes
BATCH: yes
matrix:
- env:
CC: i686-linux-gnu-gcc
Expand Down Expand Up @@ -178,6 +181,8 @@ task:
ECDH: yes
RECOVERY: yes
SCHNORRSIG: yes
EXPERIMENTAL: yes
BATCH: yes
CTIMETEST: no
<< : *MERGE_BASE
test_script:
Expand All @@ -197,6 +202,8 @@ task:
ECDH: yes
RECOVERY: yes
SCHNORRSIG: yes
EXPERIMENTAL: yes
BATCH: yes
CTIMETEST: no
matrix:
- env: {}
Expand All @@ -217,6 +224,8 @@ task:
ECDH: yes
RECOVERY: yes
SCHNORRSIG: yes
EXPERIMENTAL: yes
BATCH: yes
CTIMETEST: no
<< : *MERGE_BASE
test_script:
Expand All @@ -234,6 +243,8 @@ task:
ECDH: yes
RECOVERY: yes
SCHNORRSIG: yes
EXPERIMENTAL: yes
BATCH: yes
CTIMETEST: no
<< : *MERGE_BASE
test_script:
Expand Down Expand Up @@ -271,6 +282,8 @@ task:
RECOVERY: yes
EXPERIMENTAL: yes
SCHNORRSIG: yes
EXPERIMENTAL: yes
BATCH: yes
CTIMETEST: no
# Set non-essential options that affect the CLI messages here.
# (They depend on the user's taste, so we don't want to set them automatically in configure.ac.)
Expand Down Expand Up @@ -304,6 +317,8 @@ task:
ECDH: yes
RECOVERY: yes
SCHNORRSIG: yes
EXPERIMENTAL: yes
BATCH: yes
CTIMETEST: no
matrix:
- name: "Valgrind (memcheck)"
Expand Down Expand Up @@ -352,6 +367,8 @@ task:
ECDH: yes
RECOVERY: yes
SCHNORRSIG: yes
EXPERIMENTAL: yes
BATCH: yes
<< : *MERGE_BASE
test_script:
- ./ci/cirrus.sh
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ valgrind_ctime_test
ecdh_example
ecdsa_example
schnorr_example
batch_example
*.exe
*.so
*.a
Expand Down
15 changes: 15 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,17 @@ if BUILD_WINDOWS
schnorr_example_LDFLAGS += -lbcrypt
endif
TESTS += schnorr_example
if ENABLE_MODULE_BATCH
noinst_PROGRAMS += batch_example
batch_example_SOURCES = examples/batch.c
batch_example_CPPFLAGS = -I$(top_srcdir)/include
batch_example_LDADD = libsecp256k1.la
batch_example_LDFLAGS = -static
if BUILD_WINDOWS
batch_example_LDFLAGS += -lbcrypt
endif
TESTS += batch_example
endif
endif
endif

Expand Down Expand Up @@ -227,3 +238,7 @@ endif
if ENABLE_MODULE_SCHNORRSIG
include src/modules/schnorrsig/Makefile.am.include
endif

if ENABLE_MODULE_BATCH
include src/modules/batch/Makefile.am.include
endif
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Features:
* Optional module for public key recovery.
* Optional module for ECDH key exchange.
* Optional module for Schnorr signatures according to [BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki).
* Optional module for Batch Verification (experimental).

Implementation details
----------------------
Expand Down
1 change: 1 addition & 0 deletions ci/cirrus.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ $WRAPPER_CMD --version || true
--with-ecmult-gen-precision="$ECMULTGENPRECISION" \
--enable-module-ecdh="$ECDH" --enable-module-recovery="$RECOVERY" \
--enable-module-schnorrsig="$SCHNORRSIG" \
--enable-module-batch="$BATCH" \
--enable-examples="$EXAMPLES" \
--with-valgrind="$WITH_VALGRIND" \
--host="$HOST" $EXTRAFLAGS
Expand Down
14 changes: 14 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ AC_ARG_ENABLE(module_schnorrsig,
AS_HELP_STRING([--enable-module-schnorrsig],[enable schnorrsig module [default=no]]), [],
[SECP_SET_DEFAULT([enable_module_schnorrsig], [no], [yes])])

AC_ARG_ENABLE(module_batch,
AS_HELP_STRING([--enable-module-batch],[enable batch verification module (experimental) [default=no]]), [],
[SECP_SET_DEFAULT([enable_module_batch], [no], [yes])])

AC_ARG_ENABLE(external_default_callbacks,
AS_HELP_STRING([--enable-external-default-callbacks],[enable external default callback functions [default=no]]), [],
[SECP_SET_DEFAULT([enable_external_default_callbacks], [no], [no])])
Expand Down Expand Up @@ -368,6 +372,10 @@ if test x"$enable_module_extrakeys" = x"yes"; then
AC_DEFINE(ENABLE_MODULE_EXTRAKEYS, 1, [Define this symbol to enable the extrakeys module])
fi

if test x"$enable_module_batch" = x"yes"; then
AC_DEFINE(ENABLE_MODULE_BATCH, 1, [Define this symbol to enable the batch verification module])
fi

if test x"$enable_external_default_callbacks" = x"yes"; then
AC_DEFINE(USE_EXTERNAL_DEFAULT_CALLBACKS, 1, [Define this symbol if an external implementation of the default callbacks is used])
fi
Expand All @@ -380,11 +388,15 @@ if test x"$enable_experimental" = x"yes"; then
AC_MSG_NOTICE([******])
AC_MSG_NOTICE([WARNING: experimental build])
AC_MSG_NOTICE([Experimental features do not have stable APIs or properties, and may not be safe for production use.])
AC_MSG_NOTICE([Building batch verification module: $enable_module_batch])
AC_MSG_NOTICE([******])
else
if test x"$set_asm" = x"arm"; then
AC_MSG_ERROR([ARM assembly optimization is experimental. Use --enable-experimental to allow.])
fi
if test x"$enable_module_batch" = x"yes"; then
AC_MSG_ERROR([batch verification module is experimental. Use --enable-experimental to allow.])
fi
fi

###
Expand All @@ -407,6 +419,7 @@ AM_CONDITIONAL([ENABLE_MODULE_ECDH], [test x"$enable_module_ecdh" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_RECOVERY], [test x"$enable_module_recovery" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_EXTRAKEYS], [test x"$enable_module_extrakeys" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_SCHNORRSIG], [test x"$enable_module_schnorrsig" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_BATCH], [test x"$enable_module_batch" = x"yes"])
AM_CONDITIONAL([USE_EXTERNAL_ASM], [test x"$enable_external_asm" = x"yes"])
AM_CONDITIONAL([USE_ASM_ARM], [test x"$set_asm" = x"arm"])
AM_CONDITIONAL([BUILD_WINDOWS], [test "$build_windows" = "yes"])
Expand All @@ -427,6 +440,7 @@ echo " module ecdh = $enable_module_ecdh"
echo " module recovery = $enable_module_recovery"
echo " module extrakeys = $enable_module_extrakeys"
echo " module schnorrsig = $enable_module_schnorrsig"
echo " module batch = $enable_module_batch"
echo
echo " asm = $set_asm"
echo " ecmult window size = $set_ecmult_window"
Expand Down
15 changes: 15 additions & 0 deletions doc/speedup-batch.md
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions doc/speedup-batch/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.dat
23 changes: 23 additions & 0 deletions doc/speedup-batch/Makefile
Original file line number Diff line number Diff line change
@@ -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
13 changes: 13 additions & 0 deletions doc/speedup-batch/bench.sh
Original file line number Diff line number Diff line change
@@ -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"
137 changes: 137 additions & 0 deletions doc/speedup-batch/bench_output.txt
Original file line number Diff line number Diff line change
@@ -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
Copy link
Contributor

@sipa sipa Aug 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

batch_verify_1 shouldn't be slower than non-batch verify. Is it possible to revert to using non-batch validation logic for this case?

Copy link
Contributor Author

@siv2r siv2r Aug 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not possible with the current design.

The non-batch validation (secp256k1_schnorrsig_verify) logic looks something like this:

  • calc rj using secp256k1_ecmult: Rj = sG - eP
  • convert rj (gej) to r (ge)
  • check if the r.x = sig[0:32] and r.y = even

one schnorrsig occupies two points in the batch, and one tweak check occupies one point in the batch. If a batch contains two points, there is no guarantee that they are from a schnorrsig (R, P). It could be from two tweak checks. So, we can't use the r.y = even check.

Hence, I tried implementing a slightly modified schnorrsig_verify logic (not implement in this PR):

  • calc neg_rj using secp256k1_ecmult: neg_Rj = -s*G + batch.scalars[1]*batch.points[1]
  • check if neg_rj + batch.points[0] == inf using _gej_add_var
    • batch.scalars[0] = 1 always. So, we don't need to use ecmult again

This gives somewhat better benchmarks than before:

Benchmark                          ,    Min(us)    ,    Avg(us)    ,    Max(us)    

schnorrsig_sign                    ,    49.1       ,    50.1       ,    53.4    
schnorrsig_verify                  ,    86.6       ,    87.2       ,    88.4    
schnorrsig_batch_verify_1          ,    94.7       ,    95.0       ,    95.2 

But schnorrsig_batch_verify_1 is still slower than schnorrsig_verify.

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
Loading