Skip to content

Instantly share code, notes, and snippets.

@hebasto
Last active September 18, 2023 11:50
Show Gist options
  • Save hebasto/3d83844d61e95623f6792b2648d8f5ec to your computer and use it in GitHub Desktop.
Save hebasto/3d83844d61e95623f6792b2648d8f5ec to your computer and use it in GitHub Desktop.
libsecp256k1 Constant-Time Tests Demo

libsecp256k1 Constant-Time Tests Demo

Some theory -- Constant-time code verification...:

In many cases, checking if the implementation is constant-time is not trivial and tools are needed.

Using Valgrind for constant-time tests.

The key details about fixes -- https://en.cppreference.com/w/c/language/volatile:

... within a single thread of execution, a volatile access cannot be optimized out...

System: Ubuntu 23.04 Default compilers:

  • gcc version 12.2.0
  • clang version 15.0.7

Clang Case -- Fixed in v0.3.1

A fix -- PR1257.

$ sudo apt install clang-13
$ git checkout v0.3.0
$ cmake -B ../v0.3.0-clang-13 -DCMAKE_C_COMPILER=clang-13 \
  -DSECP256K1_BUILD_CTIME_TESTS=ON \
  -DSECP256K1_VALGRIND=ON \
  -DCMAKE_BUILD_TYPE=None \
  -DCMAKE_C_FLAGS="-O1"
$ cmake --build ../v0.3.0-clang-13
$ valgrind ../v0.3.0-clang-13/src/ctime_tests
==94124== Memcheck, a memory error detector
==94124== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==94124== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==94124== Command: ../v0.3.0-clang-13/src/ctime_tests
==94124== 
==94124== 
==94124== HEAP SUMMARY:
==94124==     in use at exit: 0 bytes in 0 blocks
==94124==   total heap usage: 1 allocs, 1 frees, 208 bytes allocated
==94124== 
==94124== All heap blocks were freed -- no leaks are possible
==94124== 
==94124== For lists of detected and suppressed errors, rerun with: -s
==94124== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0
$ cmake -B ../v0.3.0-clang-15 -DCMAKE_C_COMPILER=clang-15 \
  -DSECP256K1_BUILD_CTIME_TESTS=ON \
  -DSECP256K1_VALGRIND=ON \
  -DCMAKE_BUILD_TYPE=None \
  -DCMAKE_C_FLAGS="-O1"
$ cmake --build ../v0.3.0-clang-15
$ valgrind ../v0.3.0-clang-15/src/ctime_tests
==101364== Memcheck, a memory error detector
==101364== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==101364== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==101364== Command: ../v0.3.0-clang-15/src/ctime_tests
==101364== 
==101364== Conditional jump or move depends on uninitialised value(s)
==101364==    at 0x48726E4: secp256k1_ecmult_gen (in /home/hebasto/git/secp256k1/v0.3.0-clang-15/src/libsecp256k1.so.2.0.0)
==101364==    by 0x485AF39: secp256k1_ec_pubkey_create (in /home/hebasto/git/secp256k1/v0.3.0-clang-15/src/libsecp256k1.so.2.0.0)
==101364==    by 0x1093AD: main (in /home/hebasto/git/secp256k1/v0.3.0-clang-15/src/ctime_tests)
==101364== 
...
==101364== 
==101364== HEAP SUMMARY:
==101364==     in use at exit: 0 bytes in 0 blocks
==101364==   total heap usage: 1 allocs, 1 frees, 208 bytes allocated
==101364== 
==101364== All heap blocks were freed -- no leaks are possible
==101364== 
==101364== Use --track-origins=yes to see where uninitialised values come from
==101364== For lists of detected and suppressed errors, rerun with: -s
==101364== ERROR SUMMARY: 6606 errors from 10 contexts (suppressed: 0 from 0)
$ git checkout v0.3.1
$ cmake -B ../v0.3.1-clang-15 -DCMAKE_C_COMPILER=clang-15 \
  -DSECP256K1_BUILD_CTIME_TESTS=ON \
  -DSECP256K1_VALGRIND=ON \
  -DCMAKE_BUILD_TYPE=None \
  -DCMAKE_C_FLAGS="-O1"
$ cmake --build ../v0.3.1-clang-15
$ valgrind ../v0.3.1-clang-15/src/ctime_tests
==106010== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==106010== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==106010== Command: ../v0.3.1-clang-15/src/ctime_tests
==106010== 
==106010== 
==106010== HEAP SUMMARY:
==106010==     in use at exit: 0 bytes in 0 blocks
==106010==   total heap usage: 1 allocs, 1 frees, 208 bytes allocated
==106010== 
==106010== All heap blocks were freed -- no leaks are possible
==106010== 
==106010== For lists of detected and suppressed errors, rerun with: -s
==106010== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

GCC Case -- Fixed in v0.3.2

A fix -- PR1303.

$ sudo apt install gcc-13
$ cmake -B ../v0.3.1-gcc-12 -DCMAKE_C_COMPILER=gcc-12 \
  -DSECP256K1_BUILD_CTIME_TESTS=ON \
  -DSECP256K1_VALGRIND=ON \
  -DCMAKE_BUILD_TYPE=None \
  -DCMAKE_C_FLAGS="-O1"
$ cmake --build ../v0.3.1-gcc-12
$ valgrind ../v0.3.1-gcc-12/src/ctime_tests
==132191== Memcheck, a memory error detector
==132191== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==132191== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==132191== Command: ../v0.3.1-gcc-12/src/ctime_tests
==132191== 
==132191== 
==132191== HEAP SUMMARY:
==132191==     in use at exit: 0 bytes in 0 blocks
==132191==   total heap usage: 1 allocs, 1 frees, 208 bytes allocated
==132191== 
==132191== All heap blocks were freed -- no leaks are possible
==132191== 
==132191== For lists of detected and suppressed errors, rerun with: -s
==132191== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$ cmake -B ../v0.3.1-gcc-13 -DCMAKE_C_COMPILER=gcc-13 \
  -DSECP256K1_BUILD_CTIME_TESTS=ON \
  -DSECP256K1_VALGRIND=ON \
  -DCMAKE_BUILD_TYPE=None \
  -DCMAKE_C_FLAGS="-O1"
$ cmake --build ../v0.3.1-gcc-13
$ valgrind ../v0.3.1-gcc-13/src/ctime_tests
==134495== Memcheck, a memory error detector
==134495== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==134495== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==134495== Command: ../v0.3.1-gcc-13/src/ctime_tests
==134495== 
==134495== Conditional jump or move depends on uninitialised value(s)
==134495==    at 0x48596E1: secp256k1_scalar_cond_negate (in /home/hebasto/git/secp256k1/v0.3.1-gcc-13/src/libsecp256k1.so.2.0.1)
==134495==    by 0x4863F93: secp256k1_ecdsa_sign (in /home/hebasto/git/secp256k1/v0.3.1-gcc-13/src/libsecp256k1.so.2.0.1)
==134495==    by 0x1096D0: main (in /home/hebasto/git/secp256k1/v0.3.1-gcc-13/src/ctime_tests)
==134495== 
...
==134495== 
==134495== HEAP SUMMARY:
==134495==     in use at exit: 0 bytes in 0 blocks
==134495==   total heap usage: 1 allocs, 1 frees, 208 bytes allocated
==134495== 
==134495== All heap blocks were freed -- no leaks are possible
==134495== 
==134495== Use --track-origins=yes to see where uninitialised values come from
==134495== For lists of detected and suppressed errors, rerun with: -s
==134495== ERROR SUMMARY: 9 errors from 9 contexts (suppressed: 0 from 0)
$ git checkout v0.3.2
$ cmake -B ../v0.3.2-gcc-13 -DCMAKE_C_COMPILER=gcc-13 \
  -DSECP256K1_BUILD_CTIME_TESTS=ON \
  -DSECP256K1_VALGRIND=ON \
  -DCMAKE_BUILD_TYPE=None \
  -DCMAKE_C_FLAGS="-O1"
$ cmake --build ../v0.3.2-gcc-13
$ valgrind ../v0.3.2-gcc-13/src/ctime_tests
==137308== Memcheck, a memory error detector
==137308== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==137308== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==137308== Command: ../v0.3.2-gcc-13/src/ctime_tests
==137308== 
==137308== 
==137308== HEAP SUMMARY:
==137308==     in use at exit: 0 bytes in 0 blocks
==137308==   total heap usage: 1 allocs, 1 frees, 208 bytes allocated
==137308== 
==137308== All heap blocks were freed -- no leaks are possible
==137308== 
==137308== For lists of detected and suppressed errors, rerun with: -s
==137308== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment