1431 Commits

Author SHA1 Message Date
kngako
69d5e6bdc1 Update README
Some checks failed
CI / Build Docker image (push) Failing after 25m57s
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[ASM:x86_64 ELLSWIFT:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[BENCH:no BUILD:distcheck CTIMETESTS:no WITH_VALGRIND:no]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[BPPP:yes CPPFLAGS:-DVERIFY CTIMETESTS:no ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes… (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:int64]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[BPPP:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[CFLAGS:-O0 CTIMETESTS:no]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[CFLAGS:-O1 ECDH:yes ELLSWIFT:yes RECOVERY:yes SCHNORRSIG:yes]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[CPPFLAGS:-DDETERMINISTIC]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[ECMULTGENPRECISION:2 ECMULTWINDOW:2]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[ECMULTGENPRECISION:8 ECMULTWINDOW:4]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[ELLSWIFT:yes RECOVERY:yes SCHNORRSIG:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[ELLSWIFT:yes WIDEMUL:int128_struct]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[RECOVERY:yes WIDEMUL:int64]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[ASM:x86_64 ELLSWIFT:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[BENCH:no BUILD:distcheck CTIMETESTS:no WITH_VALGRIND:no]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[BPPP:yes CPPFLAGS:-DVERIFY CTIMETESTS:no ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HA… (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:… (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[BPPP:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[CFLAGS:-O0 CTIMETESTS:no]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[CFLAGS:-O1 ECDH:yes ELLSWIFT:yes RECOVERY:yes SCHNORRSIG:yes]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[CPPFLAGS:-DDETERMINISTIC]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[ECMULTGENPRECISION:2 ECMULTWINDOW:2]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[ECMULTGENPRECISION:8 ECMULTWINDOW:4]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[ELLSWIFT:yes RECOVERY:yes SCHNORRSIG:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[ELLSWIFT:yes WIDEMUL:int128_struct]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[RECOVERY:yes WIDEMUL:int64]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[ASM:x86_64 ELLSWIFT:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[BENCH:no BUILD:distcheck CTIMETESTS:no WITH_VALGRIND:no]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[BPPP:yes CPPFLAGS:-DVERIFY CTIMETESTS:no ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes W… (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:int64]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[BPPP:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[CFLAGS:-O0 CTIMETESTS:no]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[CFLAGS:-O1 ECDH:yes ELLSWIFT:yes RECOVERY:yes SCHNORRSIG:yes]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[CPPFLAGS:-DDETERMINISTIC]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[ECMULTGENPRECISION:2 ECMULTWINDOW:2]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[ECMULTGENPRECISION:8 ECMULTWINDOW:4]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[ELLSWIFT:yes RECOVERY:yes SCHNORRSIG:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[ELLSWIFT:yes WIDEMUL:int128_struct]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[RECOVERY:yes WIDEMUL:int64]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[ASM:x86_64 ELLSWIFT:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[BENCH:no BUILD:distcheck CTIMETESTS:no WITH_VALGRIND:no]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[BPPP:yes CPPFLAGS:-DVERIFY CTIMETESTS:no ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALF… (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:in… (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[BPPP:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[CFLAGS:-O0 CTIMETESTS:no]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[CFLAGS:-O1 ECDH:yes ELLSWIFT:yes RECOVERY:yes SCHNORRSIG:yes]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[CPPFLAGS:-DDETERMINISTIC]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[ECMULTGENPRECISION:2 ECMULTWINDOW:2]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[ECMULTGENPRECISION:8 ECMULTWINDOW:4]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[ELLSWIFT:yes RECOVERY:yes SCHNORRSIG:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[ELLSWIFT:yes WIDEMUL:int128_struct]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[RECOVERY:yes WIDEMUL:int64]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[WIDEMUL:int128]]) (push) Has been skipped
CI / i686: Linux (Debian stable) (clang --target=i686-pc-linux-gnu -isystem /usr/i686-linux-gnu/include) (push) Has been skipped
CI / i686: Linux (Debian stable) (i686-linux-gnu-gcc) (push) Has been skipped
CI / s390x (big-endian): Linux (Debian stable, QEMU) (push) Has been skipped
CI / ARM32: Linux (Debian stable, QEMU) (map[env_vars:map[ASM:arm32 EXPERIMENTAL:yes]]) (push) Has been skipped
CI / ARM32: Linux (Debian stable, QEMU) (map[env_vars:map[]]) (push) Has been skipped
CI / ARM64: Linux (Debian stable, QEMU) (map[env_vars:map[CC:clang --target=aarch64-linux-gnu]]) (push) Has been skipped
CI / ARM64: Linux (Debian stable, QEMU) (map[env_vars:map[CC:clang-snapshot --target=aarch64-linux-gnu]]) (push) Has been skipped
CI / ARM64: Linux (Debian stable, QEMU) (map[env_vars:map[]]) (push) Has been skipped
CI / ppc64le: Linux (Debian stable, QEMU) (push) Has been skipped
CI / Valgrind (memcheck) (map[env_vars:map[ASM:auto CC:clang]]) (push) Has been skipped
CI / Valgrind (memcheck) (map[env_vars:map[ASM:auto CC:i686-linux-gnu-gcc HOST:i686-linux-gnu]]) (push) Has been skipped
CI / Valgrind (memcheck) (map[env_vars:map[ASM:no CC:clang ECMULTGENPRECISION:2 ECMULTWINDOW:2]]) (push) Has been skipped
CI / Valgrind (memcheck) (map[env_vars:map[ASM:no CC:i686-linux-gnu-gcc ECMULTGENPRECISION:2 ECMULTWINDOW:2 HOST:i686-linux-gnu]]) (push) Has been skipped
CI / UBSan, ASan, LSan (map[env_vars:map[ASM:auto CC:clang]]) (push) Has been skipped
CI / UBSan, ASan, LSan (map[env_vars:map[ASM:auto CC:i686-linux-gnu-gcc HOST:i686-linux-gnu]]) (push) Has been skipped
CI / UBSan, ASan, LSan (map[env_vars:map[ASM:no CC:clang ECMULTGENPRECISION:2 ECMULTWINDOW:2]]) (push) Has been skipped
CI / UBSan, ASan, LSan (map[env_vars:map[ASM:no CC:i686-linux-gnu-gcc ECMULTGENPRECISION:2 ECMULTWINDOW:2 HOST:i686-linux-gnu]]) (push) Has been skipped
CI / MSan (map[env_vars:map[CFLAGS:-fsanitize=memory -fsanitize-recover=memory -g -O3 ECMULTGENPRECISION:2 ECMULTWINDOW:2]]) (push) Has been skipped
CI / MSan (map[env_vars:map[CFLAGS:-fsanitize=memory -fsanitize-recover=memory -g]]) (push) Has been skipped
CI / ${{ matrix.configuration.job_name }} (map[env_vars:map[HOST:i686-w64-mingw32] job_name:i686 (mingw32-w64): Windows (Debian stable, Wine)]) (push) Has been skipped
CI / ${{ matrix.configuration.job_name }} (map[env_vars:map[HOST:x86_64-w64-mingw32] job_name:x86_64 (mingw32-w64): Windows (Debian stable, Wine)]) (push) Has been skipped
CI / C++ -fpermissive (entire project) (push) Has been skipped
CI / C++ (public headers) (push) Has been skipped
CI / SageMath prover (push) Failing after 2m13s
CI / release (push) Failing after 8m4s
CI / x86_64: macOS Monterey (map[BPPP:yes CC:gcc ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SECP256K1_TEST_ITERS:2 WHITELIST:yes W… (push) Has been cancelled
CI / x86_64: macOS Monterey (map[BPPP:yes CC:gcc ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:int128]) (push) Has been cancelled
CI / x86_64: macOS Monterey (map[BPPP:yes CPPFLAGS:-DVERIFY CTIMETESTS:no ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes… (push) Has been cancelled
CI / x86_64: macOS Monterey (map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SECP256K1_TEST_ITERS:2 WHITELIST:yes WIDEMUL:… (push) Has been cancelled
CI / x86_64: macOS Monterey (map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:int128]) (push) Has been cancelled
CI / x86_64: macOS Monterey (map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:int64]) (push) Has been cancelled
CI / x86_64: macOS Monterey (map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:int128]) (push) Has been cancelled
CI / x86_64: macOS Monterey (map[BUILD:distcheck]) (push) Has been cancelled
CI / x86_64: macOS Monterey (map[ECMULTGENPRECISION:2 ECMULTWINDOW:4 WIDEMUL:int128_struct]) (push) Has been cancelled
CI / x86_64: macOS Monterey (map[RECOVERY:yes WIDEMUL:int128]) (push) Has been cancelled
CI / ${{ matrix.configuration.job_name }} (map[cmake_options:-A Win32 job_name:x86 (MSVC): Windows (VS 2022)]) (push) Has been cancelled
CI / ${{ matrix.configuration.job_name }} (map[cmake_options:-A x64 -DBUILD_SHARED_LIBS=OFF job_name:x64 (MSVC): Windows (VS 2022, static)]) (push) Has been cancelled
CI / ${{ matrix.configuration.job_name }} (map[cmake_options:-A x64 -DBUILD_SHARED_LIBS=ON job_name:x64 (MSVC): Windows (VS 2022, shared)]) (push) Has been cancelled
CI / ${{ matrix.configuration.job_name }} (map[cmake_options:-A x64 -DSECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY=int128_struct cpp_flags:/DSECP256K1_MSVC_MULH_TEST_OVERRIDE job_name:x64 (MSVC): Windows (VS 2022, int128_struct with __(u)mulh)]) (push) Has been cancelled
CI / ${{ matrix.configuration.job_name }} (map[cmake_options:-A x64 -DSECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY=int128_struct job_name:x64 (MSVC): Windows (VS 2022, int128_struct)]) (push) Has been cancelled
CI / x64 (MSVC): C++ (public headers) (push) Has been cancelled
2024-08-23 02:09:22 +02:00
Kgothatso
df0bdeb096 Add xconfigure to gitignore
Some checks failed
CI / Build Docker image (push) Failing after 5m22s
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[ASM:x86_64 ELLSWIFT:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[BENCH:no BUILD:distcheck CTIMETESTS:no WITH_VALGRIND:no]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[BPPP:yes CPPFLAGS:-DVERIFY CTIMETESTS:no ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes… (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:int64]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[BPPP:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[CFLAGS:-O0 CTIMETESTS:no]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[CFLAGS:-O1 ECDH:yes ELLSWIFT:yes RECOVERY:yes SCHNORRSIG:yes]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[CPPFLAGS:-DDETERMINISTIC]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[ECMULTGENPRECISION:2 ECMULTWINDOW:2]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[ECMULTGENPRECISION:8 ECMULTWINDOW:4]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[ELLSWIFT:yes RECOVERY:yes SCHNORRSIG:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[ELLSWIFT:yes WIDEMUL:int128_struct]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[RECOVERY:yes WIDEMUL:int64]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[ASM:x86_64 ELLSWIFT:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[BENCH:no BUILD:distcheck CTIMETESTS:no WITH_VALGRIND:no]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[BPPP:yes CPPFLAGS:-DVERIFY CTIMETESTS:no ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HA… (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:… (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[BPPP:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[CFLAGS:-O0 CTIMETESTS:no]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[CFLAGS:-O1 ECDH:yes ELLSWIFT:yes RECOVERY:yes SCHNORRSIG:yes]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[CPPFLAGS:-DDETERMINISTIC]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[ECMULTGENPRECISION:2 ECMULTWINDOW:2]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[ECMULTGENPRECISION:8 ECMULTWINDOW:4]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[ELLSWIFT:yes RECOVERY:yes SCHNORRSIG:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[ELLSWIFT:yes WIDEMUL:int128_struct]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[RECOVERY:yes WIDEMUL:int64]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[ASM:x86_64 ELLSWIFT:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[BENCH:no BUILD:distcheck CTIMETESTS:no WITH_VALGRIND:no]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[BPPP:yes CPPFLAGS:-DVERIFY CTIMETESTS:no ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes W… (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:int64]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[BPPP:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[CFLAGS:-O0 CTIMETESTS:no]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[CFLAGS:-O1 ECDH:yes ELLSWIFT:yes RECOVERY:yes SCHNORRSIG:yes]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[CPPFLAGS:-DDETERMINISTIC]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[ECMULTGENPRECISION:2 ECMULTWINDOW:2]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[ECMULTGENPRECISION:8 ECMULTWINDOW:4]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[ELLSWIFT:yes RECOVERY:yes SCHNORRSIG:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[ELLSWIFT:yes WIDEMUL:int128_struct]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[RECOVERY:yes WIDEMUL:int64]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[ASM:x86_64 ELLSWIFT:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[BENCH:no BUILD:distcheck CTIMETESTS:no WITH_VALGRIND:no]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[BPPP:yes CPPFLAGS:-DVERIFY CTIMETESTS:no ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALF… (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:in… (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[BPPP:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[CFLAGS:-O0 CTIMETESTS:no]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[CFLAGS:-O1 ECDH:yes ELLSWIFT:yes RECOVERY:yes SCHNORRSIG:yes]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[CPPFLAGS:-DDETERMINISTIC]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[ECMULTGENPRECISION:2 ECMULTWINDOW:2]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[ECMULTGENPRECISION:8 ECMULTWINDOW:4]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[ELLSWIFT:yes RECOVERY:yes SCHNORRSIG:yes WIDEMUL:int128]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[ELLSWIFT:yes WIDEMUL:int128_struct]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[RECOVERY:yes WIDEMUL:int64]]) (push) Has been skipped
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[WIDEMUL:int128]]) (push) Has been skipped
CI / i686: Linux (Debian stable) (clang --target=i686-pc-linux-gnu -isystem /usr/i686-linux-gnu/include) (push) Has been skipped
CI / i686: Linux (Debian stable) (i686-linux-gnu-gcc) (push) Has been skipped
CI / s390x (big-endian): Linux (Debian stable, QEMU) (push) Has been skipped
CI / ARM32: Linux (Debian stable, QEMU) (map[env_vars:map[ASM:arm32 EXPERIMENTAL:yes]]) (push) Has been skipped
CI / ARM32: Linux (Debian stable, QEMU) (map[env_vars:map[]]) (push) Has been skipped
CI / ARM64: Linux (Debian stable, QEMU) (map[env_vars:map[CC:clang --target=aarch64-linux-gnu]]) (push) Has been skipped
CI / ARM64: Linux (Debian stable, QEMU) (map[env_vars:map[CC:clang-snapshot --target=aarch64-linux-gnu]]) (push) Has been skipped
CI / ARM64: Linux (Debian stable, QEMU) (map[env_vars:map[]]) (push) Has been skipped
CI / ppc64le: Linux (Debian stable, QEMU) (push) Has been skipped
CI / Valgrind (memcheck) (map[env_vars:map[ASM:auto CC:clang]]) (push) Has been skipped
CI / Valgrind (memcheck) (map[env_vars:map[ASM:auto CC:i686-linux-gnu-gcc HOST:i686-linux-gnu]]) (push) Has been skipped
CI / Valgrind (memcheck) (map[env_vars:map[ASM:no CC:clang ECMULTGENPRECISION:2 ECMULTWINDOW:2]]) (push) Has been skipped
CI / Valgrind (memcheck) (map[env_vars:map[ASM:no CC:i686-linux-gnu-gcc ECMULTGENPRECISION:2 ECMULTWINDOW:2 HOST:i686-linux-gnu]]) (push) Has been skipped
CI / UBSan, ASan, LSan (map[env_vars:map[ASM:auto CC:clang]]) (push) Has been skipped
CI / UBSan, ASan, LSan (map[env_vars:map[ASM:auto CC:i686-linux-gnu-gcc HOST:i686-linux-gnu]]) (push) Has been skipped
CI / UBSan, ASan, LSan (map[env_vars:map[ASM:no CC:clang ECMULTGENPRECISION:2 ECMULTWINDOW:2]]) (push) Has been skipped
CI / UBSan, ASan, LSan (map[env_vars:map[ASM:no CC:i686-linux-gnu-gcc ECMULTGENPRECISION:2 ECMULTWINDOW:2 HOST:i686-linux-gnu]]) (push) Has been skipped
CI / MSan (map[env_vars:map[CFLAGS:-fsanitize=memory -fsanitize-recover=memory -g -O3 ECMULTGENPRECISION:2 ECMULTWINDOW:2]]) (push) Has been skipped
CI / MSan (map[env_vars:map[CFLAGS:-fsanitize=memory -fsanitize-recover=memory -g]]) (push) Has been skipped
CI / ${{ matrix.configuration.job_name }} (map[env_vars:map[HOST:i686-w64-mingw32] job_name:i686 (mingw32-w64): Windows (Debian stable, Wine)]) (push) Has been skipped
CI / ${{ matrix.configuration.job_name }} (map[env_vars:map[HOST:x86_64-w64-mingw32] job_name:x86_64 (mingw32-w64): Windows (Debian stable, Wine)]) (push) Has been skipped
CI / C++ -fpermissive (entire project) (push) Has been skipped
CI / C++ (public headers) (push) Has been skipped
CI / SageMath prover (push) Has started running
CI / release (push) Failing after 22m11s
CI / x86_64: macOS Monterey (map[BPPP:yes CC:gcc ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SECP256K1_TEST_ITERS:2 WHITELIST:yes W… (push) Has been cancelled
CI / x86_64: macOS Monterey (map[BPPP:yes CC:gcc ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:int128]) (push) Has been cancelled
CI / x86_64: macOS Monterey (map[BPPP:yes CPPFLAGS:-DVERIFY CTIMETESTS:no ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes… (push) Has been cancelled
CI / x86_64: macOS Monterey (map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SECP256K1_TEST_ITERS:2 WHITELIST:yes WIDEMUL:… (push) Has been cancelled
CI / x86_64: macOS Monterey (map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:int128]) (push) Has been cancelled
CI / x86_64: macOS Monterey (map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:int64]) (push) Has been cancelled
CI / x86_64: macOS Monterey (map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes WHITELIST:yes WIDEMUL:int128]) (push) Has been cancelled
CI / x86_64: macOS Monterey (map[BUILD:distcheck]) (push) Has been cancelled
CI / x86_64: macOS Monterey (map[ECMULTGENPRECISION:2 ECMULTWINDOW:4 WIDEMUL:int128_struct]) (push) Has been cancelled
CI / x86_64: macOS Monterey (map[RECOVERY:yes WIDEMUL:int128]) (push) Has been cancelled
CI / ${{ matrix.configuration.job_name }} (map[cmake_options:-A Win32 job_name:x86 (MSVC): Windows (VS 2022)]) (push) Has been cancelled
CI / ${{ matrix.configuration.job_name }} (map[cmake_options:-A x64 -DBUILD_SHARED_LIBS=OFF job_name:x64 (MSVC): Windows (VS 2022, static)]) (push) Has been cancelled
CI / ${{ matrix.configuration.job_name }} (map[cmake_options:-A x64 -DBUILD_SHARED_LIBS=ON job_name:x64 (MSVC): Windows (VS 2022, shared)]) (push) Has been cancelled
CI / ${{ matrix.configuration.job_name }} (map[cmake_options:-A x64 -DSECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY=int128_struct cpp_flags:/DSECP256K1_MSVC_MULH_TEST_OVERRIDE job_name:x64 (MSVC): Windows (VS 2022, int128_struct with __(u)mulh)]) (push) Has been cancelled
CI / ${{ matrix.configuration.job_name }} (map[cmake_options:-A x64 -DSECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY=int128_struct job_name:x64 (MSVC): Windows (VS 2022, int128_struct)]) (push) Has been cancelled
CI / x64 (MSVC): C++ (public headers) (push) Has been cancelled
2024-08-03 19:55:35 +02:00
Jesse Posner
3891388905 frost: add documentation file
This commit adds a documentation file with detailed instructions for how
to use the module properly.
2024-07-23 14:33:22 -07:00
Jesse Posner
36ff5b02da frost: add tests
Add api tests, nonce tests, tweak tests, sha256 tag tests, and constant
time tests.
2024-07-23 14:33:09 -07:00
Jesse Posner
c2d48a7039 frost: add example file
This commit adds an example file to demonstrate how to use the module.
2024-07-16 23:36:51 -07:00
Jesse Posner
ef15156ffb frost: signature generation and aggregation
This commit adds signature generation and aggregation, as well as
partial signature serialization and parsing.
2024-07-16 23:36:51 -07:00
Jesse Posner
67c21beadd frost: nonce aggregation and adaptor signatures
This commit adds nonce aggregation, as well as adaptor signatures.
2024-07-16 23:36:47 -07:00
Jesse Posner
17c47e9708 frost: key tweaking
This commits add BIP-341 ("Taproot") and BIP-32 ("ordinary") public key
tweaking.
2024-07-16 22:13:19 -07:00
Jesse Posner
f606507120 frost: nonce generation
This commits adds nonce generation, as well as serialization and
parsing.
2024-07-16 22:13:19 -07:00
Jesse Posner
197fb7efb9 frost: share aggregation
This commit adds share aggregation and verification, as well as
computation of public verification shares.
2024-07-16 22:13:15 -07:00
Jesse Posner
2336b02fad frost: share generation
This commit adds share generation, as well as share serialization and
parsing.
2024-07-16 22:01:45 -07:00
Jesse Posner
2f3fa4cace frost: initialize project
This commit adds the foundational configuration and building scripts
and an initial structure for the project.
2024-07-16 22:01:40 -07:00
Jonas Nick
168377204d Merge elementsproject/secp256k1-zkp#294: generator: massively speed up serialization
6361266013 generator: speed up parsing (Andrew Poelstra)
5e7c2c178d generator: massively speed up serialization (Andrew Poelstra)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK 6361266013
  jonasnick:
    ACK 6361266013

Tree-SHA512: 9f35467ac9d39d23b68a3f830c920f61ae39d99974d6a864df4a3c19860dc8fc447609d0480e45234c66250878d34da03bfcf0056eaa83d3c78babb254962bf4
2024-05-22 11:55:07 +00:00
Andrew Poelstra
6361266013 generator: speed up parsing
Similar to speeding up serialization; in our parsing logic we did a
bunch of expensive stuff then expensively inverted it. Drop everything
except the essential checks and then memcpy.
2024-05-21 13:32:12 +00:00
Andrew Poelstra
5e7c2c178d generator: massively speed up serialization
`secp256k1_pedersen_commit_serialize` would call `_load` (which does a
sqrt to fully decompress the key, then a conditional negation based on
the flag), then check the Jacobian symbol of the resulting y-coordinate,
then re-serialize based on this.

Instead, don't do any of this stuff. Copy the flag directly out of the
internal representation and copy the x-coordinate directly out of the
internal representation.

Checked that none of the other _serialize methods in the modules do
this.

Fixes #293
2024-05-20 12:40:02 +00:00
Tim Ruffing
d661a93cc9 Merge BlockstreamResearch/secp256k1-zkp#292: doc: fix sage code for deriving alternative generator H
7040a20247 doc: fix sage code for deriving alternative generator H (Sebastian Falbesoner)

Pull request description:

  The line calculating H (in particular, the expression `G.decode('hex')`) fails with the following error message on Sage 9.5:

  ```
  AttributeError: 'str' object has no attribute 'decode'
  ```

  Fix that by converting the hex-string to bytes using `bytes.fromhex`.

  (Noticed while reviewing https://github.com/bitcoin/bitcoin/pull/30048 which picks this code snippet comment up.)

ACKs for top commit:
  josibake:
    ACK 7040a20247
  real-or-random:
    utACK 7040a20247

Tree-SHA512: 0a44f399b103c2f5840056d163c1483a1d4f032bc0f8d3822507ac6da9d567f46e36caa79c7f5016aebcc8827b79e9aec7ebdb4f21c3c0242dc6875be140f289
2024-05-08 12:20:56 +02:00
Sebastian Falbesoner
7040a20247 doc: fix sage code for deriving alternative generator H
The expression `G.decode('hex')` fails with the following error message
on Sage 9.5:

AttributeError: 'str' object has no attribute 'decode'

Fix that by converting the hex-string to bytes using `bytes.fromhex`.
2024-05-07 19:38:51 +02:00
Tim Ruffing
a7907b1af2 Merge BlockstreamResearch/secp256k1-zkp#261: Schnorr (Incremental) Half Aggregation
3a9b1d46a3 New Experimental Module: Incremental Half-Aggregation for Schnorr Signatures (Benedikt)

Pull request description:

  Revisited PR #130 by jonasnick.
  I am happy to hear your thoughts.

  **Summary of changes compared to #130:**

  - Address comments from rustyrussell
  - Use tagged hash
  - Compute hashes with common prefix by copying midstate
  - Allow Incremental Aggregation and make code consistent with the [draft spec](https://github.com/BlockstreamResearch/cross-input-aggregation/blob/master/half-aggregation.mediawiki)

ACKs for top commit:
  real-or-random:
    ACK 3a9b1d46a3

Tree-SHA512: 27239033f8b28ecf87ea310b3dd5a19dbbe6fd07495db71ef7017f8f444ec25a12897087d1bea0a2e9c3df77d7f17c38b183d7fe768858da2180f26624add4aa
2024-03-05 12:17:22 +01:00
Benedikt
3a9b1d46a3 New Experimental Module: Incremental Half-Aggregation for Schnorr Signatures 2024-02-27 14:04:40 +01:00
Jonas Nick
900a4371d3 Merge elementsproject/secp256k1-zkp#290: configure: Clean ups
860e3bb294 configure: Fix reduced surjection proof size (Tim Ruffing)
0873358f77 configure: Reorder modules also for AC_ARG_ENABLE (Tim Ruffing)
9de973f613 configure: Document canonical order of modules (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 860e3bb294

Tree-SHA512: cfbaf9cb8a686aeab43ef6727b38d94467b862746062c1c06876bd98614ada7a00bc617481b0e0059dc294250a94a53581f3ffd685aa05c47a665950b280da51
2024-02-16 14:04:16 +00:00
Tim Ruffing
860e3bb294 configure: Fix reduced surjection proof size
The variable set automatically by AC_ARG_ENABLE is called enable_...
2024-02-16 10:59:25 +01:00
Tim Ruffing
0873358f77 configure: Reorder modules also for AC_ARG_ENABLE 2024-02-16 10:59:25 +01:00
Tim Ruffing
9de973f613 configure: Document canonical order of modules 2024-02-16 10:59:25 +01:00
Jonas Nick
1e04d32447 Merge elementsproject/secp256k1-zkp#288: cmake: Add support for -zkp modules
4228fd1124 cmake: Add support for -zkp modules (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    utACK 4228fd1124

Tree-SHA512: 72606bb3421a4d6479c5cbc94e2468d6a9a53581f571fd5340edc41595eac18fbb04dcaacce8f39020e32a69b733ba6743aac4b901e1600f5245a4a04cb0e27a
2024-02-02 19:47:59 +00:00
Tim Ruffing
4228fd1124 cmake: Add support for -zkp modules
Co-authored-by: lightyear15 <g.minist8@gmail.com>
2024-01-25 15:58:52 +01:00
Jonas Nick
03aecafe4c Merge elementsproject/secp256k1-zkp#286: shallue_van_de_woestijne rewrite
6b9d335ef6 generator: add shallue_van_de_woestijne test for t = 0 (Jonas Nick)
26522241b4 generators: shallue_van_de_woestijne improve comments (Jonas Nick)
5d87e80c69 shallue_van_de_woestijne rewrite (Russell O'Connor)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK 6b9d335ef6
  jonasnick:
    ACK 6b9d335ef6

Tree-SHA512: 4a5ca291ec760ea54a43ff0b811ca1fac024002172d4639919fb97f63cfa0e75a580674c86a5a0ac9866e00520be4dd8d1d37b6d2fd8d2057e42a804dbf9127c
2024-01-25 09:07:16 +00:00
Jonas Nick
6b9d335ef6 generator: add shallue_van_de_woestijne test for t = 0 2024-01-24 17:55:38 -05:00
Jonas Nick
26522241b4 generators: shallue_van_de_woestijne improve comments 2024-01-24 17:55:36 -05:00
Russell O'Connor
5d87e80c69 shallue_van_de_woestijne rewrite
The previous implementation returns an off-curve point for the input t=0.

This rewrite addresses that issue by implicity returning the on-curve point
(d, sqrt(1 + b)), which is the point that the paper Indifferentiable Hashing
to Barreto–Naehrig Curves suggests returning in this case.

Note: At the moment it is cryptographically impossible for the input t to be 0.
2024-01-24 17:50:48 -05:00
Jonas Nick
b5a6812bd6 Merge elementsproject/secp256k1-zkp#285: Upstream PRs 1426, 1430, 1184, 1437, 1442, 1441, 1445, 1438, 1393, 1446, 1450, 1451, 1431, 990, 1455, 1380, 1465, 1466, 1473, 1474, 1476, 1480, 1468, 1482, 1249
b673a43090 musig: new upstream def of VERIFY_CHECK (empty in non-VERIFY) (Jonas Nick)
cd173688fb musig: replace point_{save,load} with ge_{to,from}_bytes (Jonas Nick)
33db8edb27 group: add ge_to_bytes and ge_from_bytes (Jonas Nick)
de54a1eff7 musig2: clean up ctx doc in include file (Jonas Nick)
4f65698865 extrakeys: Remove redundant secp256k1_pubkey_cmp (Tim Ruffing)
c29f28e638 include: make docs more consistent (Tim Ruffing)
42f8c51402 cmake: Add `SECP256K1_LATE_CFLAGS` configure option (Hennadii Stepanov)
e6822678ea build: Error if required module explicitly off (Tim Ruffing)
89ec583ccf build: Clean up handling of module dependencies (Tim Ruffing)
b37fdb28ce check-abi: Minor UI improvements (Tim Ruffing)
ad5f589a94 check-abi: Default to HEAD for new version (Tim Ruffing)
9fb7e2f156 release process: Style and formatting nits (Tim Ruffing)
e7053d065b release process: Add email step (Tim Ruffing)
429d21dc79 release process: Run sanity checks on release PR (Tim Ruffing)
ba5d72d626 assumptions: Use new STATIC_ASSERT macro (Tim Ruffing)
e53c2d9ffc Require that sizeof(secp256k1_ge_storage) == 64 (Tim Ruffing)
d0ba2abbff util: Add STATIC_ASSERT macro (Tim Ruffing)
da7bc1b803 include: in doc, remove article in front of "pointer" (Jonas Nick)
aa3dd5280b include: make doc about ctx more consistent (Jonas Nick)
e3f690015a include: remove obvious "cannot be NULL" doc (Jonas Nick)
3dbfb48946 tests: restore scalar_mul test (Jonas Nick)
d77170a88d Fix typos (shuoer86)
4b2e06f460 release cleanup: bump version after 0.4.1 (Jonas Nick)
672053d801 release: prepare for 0.4.1 (Jonas Nick)
74a4d974d5 doc: Add ABI checking with `check-abi.sh` to the Release Process (Hennadii Stepanov)
e7f830e32c Add `tools/check-abi.sh` (Hennadii Stepanov)
3928b7c383 doc: improve secp256k1_fe_set_b32_mod doc (Coding Enthusiast)
e02f313b1f Add comment on length checks when parsing ECDSA sigs (Tim Ruffing)
0e5ea62207 CONTRIBUTING: add some coding and style conventions (Jonas Nick)
1a432cb982 README: update first sentence (Jonas Nick)
0922a047fb docs: move coverage report instructions to CONTRIBUTING (Jonas Nick)
76880e4015 Add CONTRIBUTING.md including scope and guidelines for new code (Jonas Nick)
d2e36a2b81 changelog: add entry for "field: Remove x86_64 asm" (Jonas Nick)
04af0ba162 Replace ge_equals_ge[,j] calls with group.h equality calls (Pieter Wuille)
60525f6c14 Add unit tests for group.h equality functions (Pieter Wuille)
a47cd97d51 Add group.h ge/gej equality functions (Pieter Wuille)
f07cead0ca build: Don't call assembly an optimization (Tim Ruffing)
2f0762fa8f field: Remove x86_64 asm (Tim Ruffing)
bb4672342e remove VERIFY_SETUP define (Sebastian Falbesoner)
a3a3e11acd remove unneeded VERIFY_SETUP uses in ECMULT_CONST_TABLE_GET_GE macro (Sebastian Falbesoner)
a0fb68a2e7 introduce and use SECP256K1_SCALAR_VERIFY macro (Sebastian Falbesoner)
cf25c86d05 introduce and use SECP256K1_{FE,GE,GEJ}_VERIFY macros (Sebastian Falbesoner)
5d89bc031b remove superfluous `#ifdef VERIFY`/`#endif` preprocessor conditions (Sebastian Falbesoner)
c2688f8de9 redefine VERIFY_CHECK to empty in production (non-VERIFY) mode (Sebastian Falbesoner)
dcdda31f2c Tighten secp256k1_fe_mul_inner's VERIFY_BITS checks (Russell O'Connor)
8e2a5fe908 correct assertion for secp256k1_fe_mul_inner (roconnor-blockstream)
1ddd76af0a bench: add --help option to bench_internal (Sebastian Falbesoner)
33dc7e4d3e asm: add .note.GNU-stack section for non-exec stack (fanquake)
10271356c8 Return temporaries to being unsigned in secp256k1_fe_sqr_inner (roconnor-blockstream)
8185e72d29 ci: Ignore internal errors in snapshot compilers (Hennadii Stepanov)
355bbdf38a Add changelog entry for signed-digit ecmult_const algorithm (Pieter Wuille)
21f49d9bec Remove unused secp256k1_scalar_shr_int (Pieter Wuille)
115fdc7232 Remove unused secp256k1_wnaf_const (Pieter Wuille)
aa9f3a3c00 ecmult_const: add/improve tests (Jonas Nick)
4d16e90111 Signed-digit based ecmult_const algorithm (Pieter Wuille)
ba523be067 make SECP256K1_SCALAR_CONST reduce modulo exhaustive group order (Pieter Wuille)
2140da9cd5 Add secp256k1_scalar_half for halving scalars (+ tests/benchmarks). (Pieter Wuille)
5dab0baa80 README: remove CI badge (Jonas Nick)
fa4d6c76b6 ci/cirrus: Add native ARM64 persistent workers (MarcoFalke)
2262d0eaab ci/cirrus: Bring back skeleton .cirrus.yml without jobs (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK b673a43090

Tree-SHA512: fe4f4d1db71518cad80724c21915a6235ffc21aadc06226f6dc29237e786f546189165ffdbe64b90b094ada4c36a031caa712c1f21bf280d33ba221fda2e0019
2024-01-23 19:07:05 +00:00
Jonas Nick
b673a43090 musig: new upstream def of VERIFY_CHECK (empty in non-VERIFY)
Remove explicity VERIFY_CHECKs in keyaggcoef_internal since normalization should
be checked in the fe_* functions.
2024-01-23 16:04:45 +01:00
Jonas Nick
cd173688fb musig: replace point_{save,load} with ge_{to,from}_bytes 2024-01-23 16:04:45 +01:00
Jonas Nick
33db8edb27 group: add ge_to_bytes and ge_from_bytes 2024-01-23 16:04:45 +01:00
Jonas Nick
de54a1eff7 musig2: clean up ctx doc in include file 2024-01-23 16:04:45 +01:00
Tim Ruffing
4f65698865 extrakeys: Remove redundant secp256k1_pubkey_cmp
It was a verbatim copy of secp256k1_ec_pubkey_cmp.
2024-01-23 16:04:45 +01:00
Tim Ruffing
c29f28e638 include: make docs more consistent
Like upstream https://github.com/bitcoin-core/secp256k1/pull/1476 .
2024-01-23 16:04:45 +01:00
Tim Ruffing
e626f00d1e Merge commits 'b314cf28 1f1bb78b 40f50d0f c891c5c2 ea47c82e e7210393 c1b49664 5814d848 07687e81 10e6d29b d3e29db8 e2c9888e 4197d667 5e9a4d7a 77af1da9 1a81df82 1ad5185c efe85c70 79e09451 d373bf6d 74b7c3b5 a9db9f2d 44378867 3bf4d68f e4af41c6 ' into temp-merge-1249 2024-01-23 16:04:45 +01:00
Tim Ruffing
e4af41c61b Merge bitcoin-core/secp256k1#1249: cmake: Add SECP256K1_LATE_CFLAGS configure option
42f8c51402 cmake: Add `SECP256K1_LATE_CFLAGS` configure option (Hennadii Stepanov)

Pull request description:

  This PR enables users to override compiler flags that have been set by the CMake-based build system, such as warning flags.

  The Autotools-based build system has the same feature out-of-the-box.

  See more details [here](https://github.com/bitcoin-core/secp256k1/issues/1235#issuecomment-1465330925).

  Here are some examples of the new option usage:
  ```
  cmake -S . -B build -DSECP256K1_LATE_CFLAGS="-Wno-extra -Wlong-long"
  ```

  ```
  cmake -S . -B build -DSECP256K1_BUILD_EXAMPLES=ON -DSECP256K1_LATE_CFLAGS=-O1
  cmake --build build
  ...
  In function ‘secp256k1_ecmult_strauss_wnaf’,
      inlined from ‘secp256k1_ecmult’ at /home/hebasto/git/secp256k1/src/ecmult_impl.h:353:5:
  /home/hebasto/git/secp256k1/src/ecmult_impl.h:291:5: warning: ‘aux’ may be used uninitialized [-Wmaybe-uninitialized]
    291 |     secp256k1_ge_table_set_globalz(ECMULT_TABLE_SIZE(WINDOW_A) * no, state->pre_a, state->aux);
        |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  In file included from /home/hebasto/git/secp256k1/src/secp256k1.c:29:
  /home/hebasto/git/secp256k1/src/ecmult_impl.h: In function ‘secp256k1_ecmult’:
  /home/hebasto/git/secp256k1/src/group_impl.h:174:13: note: by argument 3 of type ‘const secp256k1_fe *’ to ‘secp256k1_ge_table_set_globalz’ declared here
    174 | static void secp256k1_ge_table_set_globalz(size_t len, secp256k1_ge *a, const secp256k1_fe *zr) {
        |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  In file included from /home/hebasto/git/secp256k1/src/secp256k1.c:30:
  /home/hebasto/git/secp256k1/src/ecmult_impl.h:345:18: note: ‘aux’ declared here
    345 |     secp256k1_fe aux[ECMULT_TABLE_SIZE(WINDOW_A)];
        |                  ^~~
  ...
  ```

  Please note that in the last case providing `env CFLAGS=-O1` or `-DCMAKE_C_FLAGS=-O1` won't work.

ACKs for top commit:
  real-or-random:
    ACK 42f8c51402

Tree-SHA512: 2b152e420a4a8ffd5f67857de03ae5ba9f2223e535ac01a867c1025e0619180d8255fdd1e5fb8279b290f0a1c96bcc874043ef968fcd99b1ff4e13041a91b1e1
2024-01-17 13:20:50 +01:00
Tim Ruffing
3bf4d68fc0 Merge bitcoin-core/secp256k1#1482: build: Clean up handling of module dependencies
e6822678ea build: Error if required module explicitly off (Tim Ruffing)
89ec583ccf build: Clean up handling of module dependencies (Tim Ruffing)

Pull request description:

  This is a cleanup which makes it easier to add further modules with dependencies, e.g., in #1452. The diff looks larger than it is because I also reordered the modules and made the order consistent between CMake and autotools.

  (We noticed that the current logic could be improved in https://github.com/BlockstreamResearch/secp256k1-zkp/pull/275.)

ACKs for top commit:
  jonasnick:
    ACK e6822678ea
  hebasto:
    ACK e6822678ea.

Tree-SHA512: 040e791e5b5b9b8845a39632633a45ca759391455910bdefba2b7b77c6340e65df6eda18199ae2ad65c30ee2fc6630471437aec143c26fe09ae4c11409a37622
2024-01-17 13:20:19 +01:00
Tim Ruffing
e6822678ea build: Error if required module explicitly off 2024-01-16 22:58:15 +01:00
Tim Ruffing
89ec583ccf build: Clean up handling of module dependencies
This also makes the order in which module options are processed
consistent between CMake and autotools (the reverse order of the listing
printed to stdout).
2024-01-16 22:36:50 +01:00
Jonas Nick
44378867a0 Merge bitcoin-core/secp256k1#1468: v0.4.1 release aftermath
b37fdb28ce check-abi: Minor UI improvements (Tim Ruffing)
ad5f589a94 check-abi: Default to HEAD for new version (Tim Ruffing)
9fb7e2f156 release process: Style and formatting nits (Tim Ruffing)
e7053d065b release process: Add email step (Tim Ruffing)
429d21dc79 release process: Run sanity checks on release PR (Tim Ruffing)

Pull request description:

ACKs for top commit:
  hebasto:
    ACK b37fdb28ce.
  jonasnick:
    ACK b37fdb28ce

Tree-SHA512: 6e18a5b897d29a3dd3a73ba81623dd91c04fa6730fb56374b924dc84baaec8c55d0c689ee1a41dab9a03ccd566082fc59ffb5d68cafd536a136fc7aaac2d8ef5
2024-01-16 20:01:44 +00:00
Tim Ruffing
a9db9f2d75 Merge bitcoin-core/secp256k1#1480: Get rid of untested sizeof(secp256k1_ge_storage) == 64 code path
ba5d72d626 assumptions: Use new STATIC_ASSERT macro (Tim Ruffing)
e53c2d9ffc Require that sizeof(secp256k1_ge_storage) == 64 (Tim Ruffing)
d0ba2abbff util: Add STATIC_ASSERT macro (Tim Ruffing)

Pull request description:

  This gets rid of an untested code path. Resolves https://github.com/bitcoin-core/secp256k1/issues/1352.

  This is a bit opinionated in the sense that it adds a static assertion where it's needed in `secp256k1_pubkey_save` and `secp256k1_pubkey_load`. I think this is justified in this case. It helps the reviewer verify that these functions are correct.

  See individual commit messages.

ACKs for top commit:
  sipa:
    utACK ba5d72d626
  jonasnick:
    ACK ba5d72d626

Tree-SHA512: 2553c0610b62bcda6d4ef26eb26b5b2e07acf723bcd299691a2d02da57af22b8763f63c2d4adb17d30de8825b6157be6e4f0398147854fbabdf8b865fb0b5c88
2024-01-09 18:59:27 +01:00
Jonas Nick
74b7c3b53e Merge bitcoin-core/secp256k1#1476: include: make docs more consistent
da7bc1b803 include: in doc, remove article in front of "pointer" (Jonas Nick)
aa3dd5280b include: make doc about ctx more consistent (Jonas Nick)
e3f690015a include: remove obvious "cannot be NULL" doc (Jonas Nick)

Pull request description:

ACKs for top commit:
  sipa:
    ACK da7bc1b803
  real-or-random:
    ACK da7bc1b803

Tree-SHA512: 809f312fa0cd1e9502ac79b8a1c502b87e6dfc2db8ad6bbd96d7ddbdaadad0c3b6110fa704b770c353cd34d5bf5547541cbb5f2779425d7419b584e721c854c2
2024-01-09 16:52:00 +00:00
Tim Ruffing
b37fdb28ce check-abi: Minor UI improvements 2024-01-09 01:05:09 +01:00
Tim Ruffing
ad5f589a94 check-abi: Default to HEAD for new version 2024-01-09 01:00:02 +01:00
Tim Ruffing
9fb7e2f156 release process: Style and formatting nits 2024-01-09 00:59:24 +01:00
Tim Ruffing
ba5d72d626 assumptions: Use new STATIC_ASSERT macro
This also splits the big "&&" expression into separate expressions. If
we ever see an assertion fail, the error message will tell it precisely
which one failed.
2024-01-08 16:10:55 +01:00
Tim Ruffing
e53c2d9ffc Require that sizeof(secp256k1_ge_storage) == 64
This gets rid of an untested code path. Resolves #1352.

secp256k1_ge_storage is a struct with two secp256k1_fe_storage fields.
The C standard allows the compiler to add padding between the fields and
at the end of the struct, but no sane compiler in the end would do this:
The only reason to add padding is to ensure alignment, but such padding
is never necessary between two fields of the same type.

Similarly, secp256k1_fe_storage is a struct with a single array of
uintXX_t. No padding is allowed between array elements. Again, C allows
the compiler to insert padding at the end of the struct, but there's no
absolute reason to do so in this case.

For the uintXX_t itself, this guaranteed to have no padding bits, i.e.,
it's guaranteed to have exactly XX bits.

So I claim that for any existing compiler in the real world,
sizeof(secp256k1_ge_storage) == 64.
2024-01-08 16:08:42 +01:00
Tim Ruffing
d0ba2abbff util: Add STATIC_ASSERT macro 2024-01-08 16:08:42 +01:00
Jonas Nick
0ffca6f794 Merge elementsproject/secp256k1-zkp#281: Make *key_cache const in musig_pubkey_get
e2eb3fae40 Make *key_cache const in musig_pubkey_get (Sanket Kanjalkar)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK e2eb3fae40

Tree-SHA512: 24d1375bd48440e805e82d8a7d371eebfa98f7ef2c7a60d86c720e8512b5fa5bb70499ea821f9cef81c73145a3569c243fa0ecb1c29d7c31c4515dafeba80e23
2024-01-08 08:03:41 +00:00
Sanket Kanjalkar
e2eb3fae40 Make *key_cache const in musig_pubkey_get 2024-01-07 07:44:11 -08:00
Jonas Nick
da7bc1b803 include: in doc, remove article in front of "pointer" 2024-01-05 13:06:50 +00:00
Jonas Nick
aa3dd5280b include: make doc about ctx more consistent
Replaces "ctx: a secp256k1 context object" with "ctx: pointer to a context
object". Also removes the word "existing".
2024-01-04 17:15:03 +00:00
Jonas Nick
e3f690015a include: remove obvious "cannot be NULL" doc 2024-01-04 17:15:01 +00:00
Tim Ruffing
d373bf6d08 Merge bitcoin-core/secp256k1#1474: tests: restore scalar_mul test
3dbfb48946 tests: restore scalar_mul test (Jonas Nick)

Pull request description:

  Without this commit, the res[i][1] test vectors are unused. They were introduced to test the correctness of scalar_sqr(x) and scalar_mul(x, x). These tests were deleted as part of removing scalar_sqr in commit
  [5437e7bdfb](5437e7bdfb (diff-c2d5f1f7616875ab71cd41b053cfb428696988ff89642b931a0963d50f34f7e8L2195)).

  Discovered in https://github.com/bitcoin-core/secp256k1/discussions/1463 by Coding-Enthusiast (thanks!).

ACKs for top commit:
  real-or-random:
    utACK 3dbfb48946

Tree-SHA512: 914e08db3efaa1cef546a9730096e740478c422d41fedb2b71ec3a7ea962f81740a05dc7e7c1fb191088f6d38b5690479c7d0864ca8abf2b2e9c4334f03ca605
2024-01-04 17:48:36 +01:00
Tim Ruffing
79e094517c Merge bitcoin-core/secp256k1#1473: Fix typos
d77170a88d Fix typos (shuoer86)

Pull request description:

  Fix some typos caught by spell checker

ACKs for top commit:
  real-or-random:
    utACK d77170a88d

Tree-SHA512: 18722459b0b8d906ad93dd0f159b0a70a338d08c121ce6523bb6be70be33febdffa5241efc000acf18c70a845795b0582599a71d6dd25b663fee1358c8d38c85
2024-01-04 17:39:19 +01:00
Jonas Nick
3dbfb48946 tests: restore scalar_mul test
Without this commit, the res[i][1] test vectors are unused. They were introduced
to test the correctness of scalar_sqr(x) and scalar_mul(x, x). These tests were
deleted as part of removing scalar_sqr in commit
5437e7bdfb.
2024-01-04 15:45:11 +00:00
shuoer86
d77170a88d Fix typos 2024-01-03 20:03:07 +08:00
Tim Ruffing
e7053d065b release process: Add email step 2023-12-21 17:34:22 +01:00
Tim Ruffing
429d21dc79 release process: Run sanity checks on release PR 2023-12-21 17:34:18 +01:00
Tim Ruffing
efe85c70a2 Merge bitcoin-core/secp256k1#1466: release cleanup: bump version after 0.4.1
4b2e06f460 release cleanup: bump version after 0.4.1 (Jonas Nick)

Pull request description:

ACKs for top commit:
  hebasto:
    ACK 4b2e06f460
  real-or-random:
    ACK 4b2e06f460

Tree-SHA512: b1c764f0f13b259bcd6f2a8988dd92cefe7791dfed337c8d54bd148ea0b93dc1c931c9ff310fd5503432250a8359dd7b09dea6e8f66c0300c47a68349077d8f8
2023-12-21 17:00:13 +01:00
Jonas Nick
4b2e06f460 release cleanup: bump version after 0.4.1 2023-12-21 15:56:11 +00:00
Tim Ruffing
1ad5185cd4 Merge bitcoin-core/secp256k1#1465: release: prepare for 0.4.1
672053d801 release: prepare for 0.4.1 (Jonas Nick)

Pull request description:

ACKs for top commit:
  sipa:
    ACK 672053d801
  real-or-random:
    ACK 672053d801
  hebasto:
    ACK 672053d801

Tree-SHA512: de78fd4588061ffc9b869d86c6d639dce06ed215c0614a888827054014c073a97b106268e5d5773967f9407c70ddc0f27326ee9c858dce5d52af7f33d2d46b69
2023-12-21 16:51:32 +01:00
Jonas Nick
672053d801 release: prepare for 0.4.1 2023-12-21 15:46:34 +00:00
Jonas Nick
1a81df826e Merge bitcoin-core/secp256k1#1380: Add ABI checking tool for release process
74a4d974d5 doc: Add ABI checking with `check-abi.sh` to the Release Process (Hennadii Stepanov)
e7f830e32c Add `tools/check-abi.sh` (Hennadii Stepanov)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 74a4d974d5 it compares the right commits now
  jonasnick:
    re-Concept ACK 74a4d974d5

Tree-SHA512: bcca5246837f899d43ced3b0099a8e123f4fd2db7d15684bda22657649521db0c87f76696bfbd93b4dfdec6c4851e99c26c7e37cc5a1a78e9b1a296850a067fe
2023-12-20 22:10:45 +00:00
Hennadii Stepanov
74a4d974d5 doc: Add ABI checking with check-abi.sh to the Release Process 2023-12-20 17:38:18 +00:00
Hennadii Stepanov
e7f830e32c Add tools/check-abi.sh
Co-authored-by: Tim Ruffing <crypto@timruffing.de>
2023-12-20 17:37:39 +00:00
Tim Ruffing
77af1da9f6 Merge bitcoin-core/secp256k1#1455: doc: improve secp256k1_fe_set_b32_mod doc
3928b7c383 doc: improve secp256k1_fe_set_b32_mod doc (Coding Enthusiast)

Pull request description:

  As discussed in #1453
  This only changes the `secp256k1_fe_impl_set_b32_mod` comment since I think `secp256k1_fe_set_b32_limit` doc is clear enough.

ACKs for top commit:
  sipa:
    ACK 3928b7c383
  theStack:
    ACK 3928b7c383

Tree-SHA512: ad62c1b72d6a487473b182e6aadc7765711385add8c6576bf15c2015db82721f19e3d635f7a29316c2ee7e3c73bc55e2cd4f46ec13180be93d6fe8641f47e7d2
2023-12-11 09:20:12 +01:00
Coding Enthusiast
3928b7c383 doc: improve secp256k1_fe_set_b32_mod doc 2023-12-08 14:58:38 +03:30
Tim Ruffing
5e9a4d7aec Merge bitcoin-core/secp256k1#990: Add comment on length checks when parsing ECDSA sigs
e02f313b1f Add comment on length checks when parsing ECDSA sigs (Tim Ruffing)

Pull request description:

  I claim the check can be removed but I don't want to touch this
  stable and well-tested code.

  On the way, we fix grammar in another comment.

ACKs for top commit:
  sipa:
    ACK e02f313b1f
  RandyMcMillan:
    ACK e02f313

Tree-SHA512: f82691a8f5db82a1e9683e52ce8e952ebd56b476a2817c5a876ce4638254b7b4ac93175318fb59598ed5532f33433951d75afea03724ef4419c3e1bd12ca8c20
2023-12-07 09:26:38 +01:00
Tim Ruffing
4197d667ec Merge bitcoin-core/secp256k1#1431: Add CONTRIBUTING.md
0e5ea62207 CONTRIBUTING: add some coding and style conventions (Jonas Nick)
1a432cb982 README: update first sentence (Jonas Nick)
0922a047fb docs: move coverage report instructions to CONTRIBUTING (Jonas Nick)
76880e4015 Add CONTRIBUTING.md including scope and guidelines for new code (Jonas Nick)

Pull request description:

  Following offline discussions, this PR documents the scope of the library and the requirements for adding new modules. I think this fixes most of #997. It also updates the README very slightly.

  In addition, I added some coding conventions that I remembered explaining to new contributors in the past year. Even though it's far from exhaustive, I think this is an easy improvement to the CONTRIBUTING.md. Feel free to suggest more conventions.

ACKs for top commit:
  sipa:
    ACK 0e5ea62207
  real-or-random:
    ACK 0e5ea62207

Tree-SHA512: ffdbab22982fd632de92e81bd135f141ac86e24cc0dcfc0e1ae12b0d2a2e4f91377ab2c0cc440cb919889eaed8bfc1447b880fa1430fd771b956f2af0fe3766e
2023-12-07 09:16:50 +01:00
Jonas Nick
0e5ea62207 CONTRIBUTING: add some coding and style conventions 2023-12-06 17:20:09 +00:00
Tim Ruffing
e2c9888eee Merge bitcoin-core/secp256k1#1451: changelog: add entry for "field: Remove x86_64 asm"
d2e36a2b81 changelog: add entry for "field: Remove x86_64 asm" (Jonas Nick)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK d2e36a2b81

Tree-SHA512: c4bffb921c58185b0a43546977449f3c53c21230d6d32cf5d5ccf563b196ec3d0370a0b87de5b334e5190ff91da598dd0bbebbb5c9d7bef9ec8c0679c3b6c702
2023-12-06 18:16:41 +01:00
Jonas Nick
d2e36a2b81 changelog: add entry for "field: Remove x86_64 asm" 2023-12-05 20:51:24 +00:00
Jonas Nick
1a432cb982 README: update first sentence
libsecp256k1 has become more than a library for just ECDSA and key tweaking.
2023-12-05 20:48:12 +00:00
Jonas Nick
0922a047fb docs: move coverage report instructions to CONTRIBUTING 2023-12-04 20:08:33 +00:00
Jonas Nick
76880e4015 Add CONTRIBUTING.md including scope and guidelines for new code 2023-12-04 20:08:25 +00:00
Tim Ruffing
d3e29db8bb Merge bitcoin-core/secp256k1#1450: Add group.h ge/gej equality functions
04af0ba162 Replace ge_equals_ge[,j] calls with group.h equality calls (Pieter Wuille)
60525f6c14 Add unit tests for group.h equality functions (Pieter Wuille)
a47cd97d51 Add group.h ge/gej equality functions (Pieter Wuille)

Pull request description:

  This pull requests removes the test-only functions `ge_equals_ge` and `ge_equals_gej`, and replaces them with proper group.h functions `secp256k1_ge_eq_var` and `secp256k1_gej_eq_ge_var` (mimicking the existing `secp256k1_gej_eq_var` function).

  This drops some of the arbitrary and undocumented magnitude restristrictions these functions have, makes them properly tested on their own, and makes their semantics cleaner (I'm always left checking whether `ge_equals_ge` does a `CHECK` internally or whether it returns a value...).

ACKs for top commit:
  real-or-random:
    utACK 04af0ba162
  stratospher:
    ACK 04af0ba.

Tree-SHA512: 49bc409ffa980144d1305c9389a846af45f0a97bfec19d016929056aa918c6a9f020dbe8549f5318fa8e6a4108621cc3cce60331aa0634f84619a1104d20a62a
2023-12-02 10:18:05 +01:00
Pieter Wuille
04af0ba162 Replace ge_equals_ge[,j] calls with group.h equality calls 2023-12-01 16:10:20 -05:00
Pieter Wuille
60525f6c14 Add unit tests for group.h equality functions 2023-12-01 16:10:15 -05:00
Pieter Wuille
a47cd97d51 Add group.h ge/gej equality functions 2023-12-01 16:06:29 -05:00
Jonas Nick
10e6d29b60 Merge bitcoin-core/secp256k1#1446: field: Remove x86_64 asm
f07cead0ca build: Don't call assembly an optimization (Tim Ruffing)
2f0762fa8f field: Remove x86_64 asm (Tim Ruffing)

Pull request description:

ACKs for top commit:
  sipa:
    utACK f07cead0ca
  theStack:
    ACK f07cead0ca
  jonasnick:
    ACK f07cead0ca

Tree-SHA512: df7f895ab8ab924c5f8f01c35d0cd2f65d5c947c5ab5325787d169c5b202834ab8aa5d85dedb25839fff3f518097fe8cf8e837d3c1918e5f039ddd6ddf4187da
2023-12-01 18:49:48 +00:00
Tim Ruffing
07687e811d Merge bitcoin-core/secp256k1#1393: Implement new policy for VERIFY_CHECK and #ifdef VERIFY (issue #1381)
bb4672342e remove VERIFY_SETUP define (Sebastian Falbesoner)
a3a3e11acd remove unneeded VERIFY_SETUP uses in ECMULT_CONST_TABLE_GET_GE macro (Sebastian Falbesoner)
a0fb68a2e7 introduce and use SECP256K1_SCALAR_VERIFY macro (Sebastian Falbesoner)
cf25c86d05 introduce and use SECP256K1_{FE,GE,GEJ}_VERIFY macros (Sebastian Falbesoner)
5d89bc031b remove superfluous `#ifdef VERIFY`/`#endif` preprocessor conditions (Sebastian Falbesoner)
c2688f8de9 redefine VERIFY_CHECK to empty in production (non-VERIFY) mode (Sebastian Falbesoner)

Pull request description:

  As suggested in #1381, this PR reworks the policy for VERIFY_CHECK and when to use #ifdef VERIFY, by:
  - redefining VERIFY_CHECK to empty in production (non-VERIFY) mode
  - removing many then superflous #ifdef VERIFY blocks (if they exclusively contained VERIFY_CHECKs)
  - introducing uppercase macros around verify_ functions and using them for better readabiliy

  What is _not_ included yet is the proposed renaming from "_check" to "_assert":
  > And while we're touching this anyway, we could consider renaming "check" to "assert", which is a more precise term. (In fact, if we redefine VERIFY_CHECK to be empty in production, we have almost reimplemented assert.h...)

  This should be easy to achieve with simple search-and-replace (e.g. using sed), but I was hesitant as this would probably case annoying merge conflicts on some of the open PRs. Happy to add this if the rename if desired (#1381 didn't get any feedback about the renaming idea yet).

ACKs for top commit:
  stratospher:
    ACK bb46723.
  real-or-random:
    utACK bb4672342e

Tree-SHA512: 226ca609926dea638aa3bb537d29d4fac8b8302dcd9da35acf767ba9573e5221d2dae04ea26c15d80a50ed70af1ab0dca10642c21df7dbdda432fa237a5ef2cc
2023-12-01 12:59:41 +01:00
Sebastian Falbesoner
bb4672342e remove VERIFY_SETUP define
This define was seemingly introduced for VERIFY mode code with side
effects (for setup purposes), that should just be executed without any
checks. The same can be achieved by putting it in an `#if VERIFY` block,
so we can remove it.
2023-12-01 01:36:32 +01:00
Sebastian Falbesoner
a3a3e11acd remove unneeded VERIFY_SETUP uses in ECMULT_CONST_TABLE_GET_GE macro
As the fields r->x and r->y are set immediately after (three lines
below), there is no need to clear them.
2023-12-01 01:36:32 +01:00
Sebastian Falbesoner
a0fb68a2e7 introduce and use SECP256K1_SCALAR_VERIFY macro
By providing an uppercase variant of these verification functions,
it is better visible that it is test code.
2023-12-01 01:36:29 +01:00
Sebastian Falbesoner
cf25c86d05 introduce and use SECP256K1_{FE,GE,GEJ}_VERIFY macros
By providing an uppercase variant of these verification functions, it is
better visible that it is test code and surrounding `#ifdef VERIFY`
blocks can be removed (if there is no other code around that could
remain in production mode), as they don't serve their purpose any more.

At some places intentional blank lines are inserted for grouping and
better readadbility.
2023-12-01 00:54:58 +01:00
Sebastian Falbesoner
5d89bc031b remove superfluous #ifdef VERIFY/#endif preprocessor conditions
Now that the `VERIFY_CHECK` compiles to empty in non-VERIFY mode, blocks
that only consist of these macros don't need surrounding `#ifdef VERIFY`
conditions anymore.

At some places intentional blank lines are inserted for grouping and
better readadbility.
2023-12-01 00:54:41 +01:00
Sebastian Falbesoner
c2688f8de9 redefine VERIFY_CHECK to empty in production (non-VERIFY) mode
As suggested in issue #1381, this will make things simpler and
improve code readability, as we don't need to force omitting of
evaluations on a case-by-case basis anymore and hence can remove
lots of `#ifdef VERIFY`/`#endif` lines (see next commit). Plus,
VERIFY_CHECK behaves now identical in both non-VERIFY and coverage mode,
making the latter not special anymore and hopefully decreasing
maintenance burden. The idea of "side-effect safety" is given up.

Note that at two places in the ellswift module void-casts of return
values have to be inserted for non-VERIFY builds, in order to avoid
   "variable ... set but not used [-Wunused-but-set-variable]"
warnings.
2023-12-01 00:22:40 +01:00
Tim Ruffing
5814d8485c Merge bitcoin-core/secp256k1#1438: correct assertion for secp256k1_fe_mul_inner
dcdda31f2c Tighten secp256k1_fe_mul_inner's VERIFY_BITS checks (Russell O'Connor)
8e2a5fe908 correct assertion for secp256k1_fe_mul_inner (roconnor-blockstream)

Pull request description:

  Based on the surrounding asserts, 112 bits before this line, and 61 bits after this line, this assertion should be 113 bits.  Notably the commensurate line in secp256k1_fe_sqr_inner is correctly assert to be 113 bits.

ACKs for top commit:
  real-or-random:
    ACK dcdda31f2c tested with asm disabled

Tree-SHA512: c35170e37d9a6d1413dd625032028129ab2eccee7da86697ab9641b68ad78efd7251953d51e7acaefd14888d3fd61877f9f05349c44f6fc0133ce9b3921b0e1a
2023-11-27 09:45:09 +01:00
Tim Ruffing
c1b4966410 Merge bitcoin-core/secp256k1#1445: bench: add --help option to bench_internal
1ddd76af0a bench: add --help option to bench_internal (Sebastian Falbesoner)

Pull request description:

  While coming up with commands for running the benchmarks for issue https://github.com/bitcoin-core/secp256k1/issues/726#issuecomment-1824625653, I noticed that in contrast to `bench{_ecmult}`, `bench_internal` doesn't have a help option yet and figured it would be nice to have one. A comparable past PR is https://github.com/bitcoin-core/secp256k1/pull/1008. Benchmark categories appear in the same order as they are executed, the concrete benchmark names in parantheses per category are listed in alphabetical order.

ACKs for top commit:
  real-or-random:
    utACK 1ddd76af0a
  siv2r:
    ACK 1ddd76a, tested the `--help` option locally, and it works as expected.

Tree-SHA512: d117641a5f25a7cbf83881f3acceae99624528a0cbb2405efdbe1a3a2762b4d6b251392e954aaa32f6771069d31143743770fccafe198084c12258dedb0856fc
2023-11-24 14:50:05 +01:00
Tim Ruffing
f07cead0ca build: Don't call assembly an optimization
because we don't know whether it's an optimization.
2023-11-24 08:11:33 +01:00
Tim Ruffing
2f0762fa8f field: Remove x86_64 asm
Widely available versions of GCC and Clang beat our field asm on -O2.
In particular, GCC 10.5.0, which is Bitcoin Core's current compiler
for official x86_64 builds, produces code that is > 20% faster for
fe_mul and > 10% faster for signature verification (see #726).

These are the alternatives to this PR:

We could replace our current asm with the fastest compiler output
that we can find. This is potentially faster, but it has multiple
drawbacks:
 - It's more coding work because it needs detailed benchmarks (e.g.,
   with many compiler/options).
 - It's more review work because we need to deal with inline asm
   (including clobbers etc.) and there's a lack of experts reviewers
   in this area.
 - It's not unlikely that we'll fall behind again in a few compiler
   versions, and then we have to deal with this again, i.e., redo the
   benchmarks. Given our history here, I doubt that we'll revolve
   this timely.

We could change the default of the asm build option to off. But this
will also disable the scalar asm, which is still faster.

We could split the build option into two separate options for field
and scalar asm and only disable the field asm by default. But this
adds complexity to the build and to the test matrix.

My conclusion is that this PR gets the low-hanging fruit in terms of
performance. It simplifies our code significantly. It's clearly an
improvement, and it's very easy to review. Whether re-introducing
better asm (whether from a compiler or from CryptOpt) is worth the
hassle can be evaluated separately, and should not hold up this
improvement.

Solves #726.
2023-11-24 08:11:08 +01:00
Sebastian Falbesoner
1ddd76af0a bench: add --help option to bench_internal 2023-11-24 02:33:40 +01:00
Tim Ruffing
eb4fb6db05 Merge ElementsProject/secp256k1-zkp#276: Typo in shallue_van_de_woestijne description
c33d2241cb Typo in shallue_van_de_woestijne description (roconnor-blockstream)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK c33d2241cb

Tree-SHA512: b008b3d64856e4ccf472e97749695bec42e0bf137d7cfe2d8eeed0ba1a27f8fbdafbe20cda550c4931f80a1585c4893ae155e624f3d2ce9e3caf5e955c3dbbf4
2023-11-17 23:39:31 +01:00
roconnor-blockstream
c33d2241cb Typo in shallue_van_de_woestijne description 2023-11-17 14:58:35 -05:00
Tim Ruffing
e72103932d Merge bitcoin-core/secp256k1#1441: asm: add .note.GNU-stack section for non-exec stack
33dc7e4d3e asm: add .note.GNU-stack section for non-exec stack (fanquake)

Pull request description:

  With this in place, we no-longer see warnings like the following:
  ```bash
  /usr/lib/gcc-cross/arm-linux-gnueabihf/12/../../../../arm-linux-gnueabihf/bin/ld: warning: field_10x26_arm.o: missing .note.GNU-stack section implies executable stack
  /usr/lib/gcc-cross/arm-linux-gnueabihf/12/../../../../arm-linux-gnueabihf/bin/ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker
  ```

  Should close #1434.

ACKs for top commit:
  sipa:
    utACK 33dc7e4d3e
  real-or-random:
    utACK 33dc7e4d3e

Tree-SHA512: f75ded8d971f54d1e871bcc4d815ba367b3e154eea2f18309ecaf9053e22f986bfffcf28418367f8055b65a5a0b245fee045adfcb63a2196df5e2f3aa6c97b89
2023-11-16 09:46:16 +01:00
Tim Ruffing
ea47c82e01 Merge bitcoin-core/secp256k1#1442: Return temporaries to being unsigned in secp256k1_fe_sqr_inner
10271356c8 Return temporaries to being unsigned in secp256k1_fe_sqr_inner (roconnor-blockstream)

Pull request description:

  These temporaries seem to been inadvertently changed to signed during a refactoring.  Generally, bit shifting is frowned upon for signed values.

ACKs for top commit:
  sipa:
    utACK 10271356c8
  real-or-random:
    utACK 10271356c8

Tree-SHA512: a9fefe4b146163209662cd435422beb3c9561eb9e83110454184f70df2292992f39ec1971143428e039a80cad2f6285db74de2f059e877ad8756ff739269b67a
2023-11-16 09:45:49 +01:00
Russell O'Connor
dcdda31f2c Tighten secp256k1_fe_mul_inner's VERIFY_BITS checks
These changes bring the checks to the same values used at the corresponding positions in secp256k1_fe_sqr_inner.
2023-11-14 12:07:00 -05:00
roconnor-blockstream
10271356c8 Return temporaries to being unsigned in secp256k1_fe_sqr_inner
These temporaries seem to been inadvertently changed to signed during a refactoring.  Generally, bit shifting is frowned upon for signed values.
2023-11-14 09:29:21 -05:00
fanquake
33dc7e4d3e asm: add .note.GNU-stack section for non-exec stack
With this in place, we no-longer see warnings like the following:
```bash
/usr/lib/gcc-cross/arm-linux-gnueabihf/12/../../../../arm-linux-gnueabihf/bin/ld: warning: field_10x26_arm.o: missing .note.GNU-stack section implies executable stack
/usr/lib/gcc-cross/arm-linux-gnueabihf/12/../../../../arm-linux-gnueabihf/bin/ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker
```

Should close #1434.
2023-11-13 14:49:35 +00:00
Tim Ruffing
c891c5c2f4 Merge bitcoin-core/secp256k1#1437: ci: Ignore internal errors of snapshot compilers
8185e72d29 ci: Ignore internal errors in snapshot compilers (Hennadii Stepanov)

Pull request description:

  It was discussed on today's IRC meeting.

ACKs for top commit:
  real-or-random:
    ACK 8185e72d29

Tree-SHA512: 0f41ca8303bd3d6efefcd3a544c7bd7dfcf464c57c779c876da4a77cacd262e6c963449d493fdf5a641b0d10b655c8c67fe8a147145b6533328d7bf5344313e1
2023-11-08 20:50:55 +01:00
Hennadii Stepanov
8185e72d29 ci: Ignore internal errors in snapshot compilers 2023-11-08 17:51:52 +00:00
Tim Ruffing
40f50d0fbd Merge bitcoin-core/secp256k1#1184: Signed-digit based ecmult_const algorithm
355bbdf38a Add changelog entry for signed-digit ecmult_const algorithm (Pieter Wuille)
21f49d9bec Remove unused secp256k1_scalar_shr_int (Pieter Wuille)
115fdc7232 Remove unused secp256k1_wnaf_const (Pieter Wuille)
aa9f3a3c00 ecmult_const: add/improve tests (Jonas Nick)
4d16e90111 Signed-digit based ecmult_const algorithm (Pieter Wuille)
ba523be067 make SECP256K1_SCALAR_CONST reduce modulo exhaustive group order (Pieter Wuille)
2140da9cd5 Add secp256k1_scalar_half for halving scalars (+ tests/benchmarks). (Pieter Wuille)

Pull request description:

  Using some insights learned from #1058, this replaces the fixed-wnaf ecmult_const algorithm with a signed-digit based one. Conceptually both algorithms are very similar, in that they boil down to summing precomputed odd multiples of the input points. Practically however, the new algorithm is simpler because it's just using scalar operations, rather than relying on wnaf machinery with skew terms to guarantee odd multipliers.

  The idea is that we can compute $q \cdot A$ as follows:
  * Let $s = f(q)$, for some function $f()$.
  * Compute $(s_1, s_2)$ such that $s = s_1 + \lambda s_2$, using `secp256k1_scalar_lambda_split`.
  * Let $v_1 = s_1 + 2^{128}$ and $v_2 = s_2 + 2^{128}$ (such that the $v_i$ are positive and $n$ bits long).
  * Computing the result as $$\sum_{i=0}^{n-1} (2v_1[i]-1) 2^i A + \sum_{i=0}^{n-1} (2v_2[i]-1) 2^i \lambda A$$ where $x[i]$ stands for the *i*'th bit of $x$, so summing positive and negative powers of two times $A$, based on the bits of $v_1.$

  The comments in `ecmult_const_impl.h` show that if $f(q) = (q + (1+\lambda)(2^n - 2^{129} - 1))/2 \mod n$, the result will equal $q \cdot A$.

  This last step can be performed in groups of multiple bits at once, by looking up entries in a precomputed table of odd multiples of $A$ and $\lambda A$, and then multiplying by a power of two before proceeding to the next group.

  The result is slightly faster (I measure ~2% speedup), but significantly simpler as it only uses scalar arithmetic to determine the table lookup values. The speedup is due to the fact that no skew corrections at the end are needed, and less overhead to determine table indices. The precomputed table sizes are also made independent from the `ecmult` ones, after observing that the optimal table size is bigger here (which also gives a small speedup).

ACKs for top commit:
  jonasnick:
    ACK 355bbdf38a
  siv2r:
    ACK 355bbdf
  real-or-random:
    ACK 355bbdf38a

Tree-SHA512: 13db572cb7f9be00bf0931c65fcd8bc8b5545be86a8c8700bd6a79ad9e4d9e5e79e7f763f92ca6a91d9717a355f8162204b0ea821b6ae99d58cb400497ddc656
2023-11-07 23:18:59 +01:00
roconnor-blockstream
8e2a5fe908 correct assertion for secp256k1_fe_mul_inner
Based on the surrounding asserts, 112 bits before this line, and 61 bits after this line, this assertion should be 113 bits.  Notably the commensurate line in secp256k1_fe_sqr_inner is correctly assert to be 113 bits.
2023-11-06 17:40:17 -05:00
Pieter Wuille
355bbdf38a Add changelog entry for signed-digit ecmult_const algorithm 2023-11-04 15:55:12 -04:00
Pieter Wuille
21f49d9bec Remove unused secp256k1_scalar_shr_int 2023-11-04 15:55:12 -04:00
Pieter Wuille
115fdc7232 Remove unused secp256k1_wnaf_const 2023-11-04 15:55:12 -04:00
Jonas Nick
aa9f3a3c00 ecmult_const: add/improve tests
* add test case for a=infinity

  The corresponding ecmult_const branch was not tested before this commit.

* add test for edge cases
2023-11-04 15:55:12 -04:00
Pieter Wuille
4d16e90111 Signed-digit based ecmult_const algorithm 2023-11-04 15:55:12 -04:00
Pieter Wuille
ba523be067 make SECP256K1_SCALAR_CONST reduce modulo exhaustive group order 2023-11-04 15:54:08 -04:00
Pieter Wuille
2140da9cd5 Add secp256k1_scalar_half for halving scalars (+ tests/benchmarks).
Co-authored-by: Jonas Nick <jonasd.nick@gmail.com>
Co-authored-by: Tim Ruffing <crypto@timruffing.de>
2023-11-04 15:54:08 -04:00
Jonas Nick
2192e9d051 Merge elementsproject/secp256k1-zkp#272: surjectionproof: remove unused include
fcc0299fa5 surjectionproof: remove unused include (Jon Griffiths)

Pull request description:

ACKs for top commit:
  delta1:
    ACK fcc0299fa5
  jonasnick:
    ACK fcc0299fa5

Tree-SHA512: dbd5dd982796b99871f2fbd3ab8404c6817bd4970d8775a83bd3a3fd916a683ff9da70c334a377870063eaa5c8cfb73481edfdd0bd7279fc7dc7f8b5368bb5aa
2023-10-31 07:38:41 +00:00
Jon Griffiths
fcc0299fa5 surjectionproof: remove unused include
Following the merge of b627ba7050 from
upstream, this include should have been deleted as well.
2023-10-31 16:53:26 +13:00
Tim Ruffing
1f1bb78b7f Merge bitcoin-core/secp256k1#1430: README: remove CI badge
5dab0baa80 README: remove CI badge (Jonas Nick)

Pull request description:

ACKs for top commit:
  sipa:
    utACK 5dab0baa80
  real-or-random:
    utACK 5dab0baa80

Tree-SHA512: 56730fa8067cc48b8e5af6fc21b0cd6c47f615c5ebba9edcf29ca5eaf7b2359662a9af219612e80688d8f8939649c7c3c26136c0442ba47d56251a0d92cf984a
2023-10-23 17:49:43 +02:00
Jonas Nick
5dab0baa80 README: remove CI badge
We're not solely using cirrus anymore and github already displays the CI status
at a different location.
2023-10-22 11:50:09 +00:00
Tim Ruffing
d575ef9aca Merge ElementsProject/secp256k1-zkp#270: Upstream PRs 1391, 1290, 1389, 1397, 1399, 1400, 1348, 1402, 1274, 1394, 1404, 1062, 1401, 1373, 1403, 1398, 1405, 1396, 1406, 1410, 1409, 1411, 1412, 1414, 1413, 1415, 1417, 1390, 1416, 1422, 1424, 1395
b41caaafd2 bppp: replace memcmp in tests with secp256k1_memcmp_var (Jonas Nick)
6a3aae8f1d group_parse: use secp256k1_memcmp_var instead of memcmp (Jonas Nick)
e9d522fc64 ci: turn on -zkp modules in macos-native job (Jonas Nick)
c45b7c4fbb refactor: introduce testutil.h (deduplicate `random_fe_`, `ge_equals_` helpers) (Sebastian Falbesoner)
dc5514144f tests: simplify `random_fe_non_zero` (remove loop limit and unneeded normalize) (Sebastian Falbesoner)
d9d80fd155 ci: Bump major versions for docker actions (Hennadii Stepanov)
421d84855a ci: Align Autotools/CMake `CI_INSTALL` directory names (Hennadii Stepanov)
9f005c60d6 cmake: Install `libsecp256k1.pc` file (Hennadii Stepanov)
b0f7bfedc9 doc: Do not mention soname in CHANGELOG.md "ABI Compatibility" section (Hennadii Stepanov)
bd9d98d353 doc: Align documented scripts with CI ones (Hennadii Stepanov)
70303643cf tests: add CHECK_ERROR_VOID and use it in scratch tests (Jonas Nick)
f8d7ea68df tests: Replace counting_illegal_callbacks with CHECK_ILLEGAL_VOID (Jonas Nick)
a1d52e3e12 tests: remove unnecessary test in run_ec_pubkey_parse_test (Jonas Nick)
875b0ada25 tests: remove unnecessary set_illegal_callback (Jonas Nick)
9b118bc7fb release cleanup: bump version after 0.4.0 (Jonas Nick)
16339804c9 release: Prepare for 0.4.0 (Tim Ruffing)
d9a85065a9 changelog: Catch up in preparation of release (Tim Ruffing)
8659a01714 ci: Add `release` job (Hennadii Stepanov)
f9b38894ba ci: Update `actions/checkout` version (Hennadii Stepanov)
2635068abf ci/gha: Let MSan continue checking after errors in all jobs (Tim Ruffing)
e78c7b68eb ci/Dockerfile: Reduce size of Docker image further (Tim Ruffing)
2f0d3bbffb ci/Dockerfile: Warn if `ulimit -n` is too high when running Docker (Tim Ruffing)
4b8a647ad3 ci/gha: Add ARM64 QEMU jobs for clang and clang-snapshot (Tim Ruffing)
6ebe7d2bb3 ci/Dockerfile: Always use versioned clang packages (Tim Ruffing)
c223d7e33d ci: Switch macOS from Ventura to Monterey and add Valgrind (Hennadii Stepanov)
cce0456304 ci: Make repetitive command the default one (Hennadii Stepanov)
317a4c48f0 ci: Move `git config ...` to `run-in-docker-action` (Hennadii Stepanov)
676ed8f9cf ci: Move "C++ (public headers)" from Cirrus to GitHub Actions (Hennadii Stepanov)
61fc3a2dc8 ci: Move "C++ -fpermissive..." from Cirrus to GitHub Actions (Hennadii Stepanov)
d51fb0a533 ci: Move "MSan" from Cirrus to GitHub Actions (Hennadii Stepanov)
c22ac27529 ci: Move sanitizers task from Cirrus to GitHub Actions (Hennadii Stepanov)
ee1be62d84 ci: Use concurrency for pull requests only (Hennadii Stepanov)
fc3dea29ea ci: Move "ppc64le: Linux..." from Cirrus to GitHub Actions (Hennadii Stepanov)
7782dc8276 ci: Move "ARM64: Linux..." from Cirrus to GitHub Actions (Hennadii Stepanov)
0a16de671c ci: Move "ARM32: Linux..." from Cirrus to GitHub Actions (Hennadii Stepanov)
ea33914e00 ci: Move "s390x (big-endian): Linux..." from Cirrus to GitHub Actions (Hennadii Stepanov)
880be8af99 ci: Move "i686: Linux (Debian stable)" from Cirrus to GiHub Actions (Hennadii Stepanov)
e10878f58e ci, gha: Drop `driver-opts.network` input for `setup-buildx-action` (Hennadii Stepanov)
4ad4914bd1 ci, gha: Add `retry_builder` Docker image builder (Hennadii Stepanov)
6617a620d9 ci: Remove "x86_64: Linux (Debian stable)" task from Cirrus CI (Hennadii Stepanov)
03c9e6508c ci, gha: Add "x86_64: Linux (Debian stable)" GitHub Actions job (Hennadii Stepanov)
ad3e65d9fe ci: Remove GCC build files and sage to reduce size of Docker image (Tim Ruffing)
ef9fe959de ci: Drop no longer needed workaround (Hennadii Stepanov)
87d35f30c0 ci: Rename `cirrus.sh` to more general `ci.sh` (Hennadii Stepanov)
d6281dd008 ci: Remove Windows tasks from Cirrus CI (Hennadii Stepanov)
2b6f9cd546 ci, gha: Add Windows jobs based on Linux image (Hennadii Stepanov)
b0886fd35c ci, gha: Ensure only a single workflow processes `github.ref` at a time (Hennadii Stepanov)
d23da6d557 use secp256k1_scalar_verify checks (stratospher)
c7d0454932 add verification for scalars (stratospher)
ad152151b0 update max scalar in scalar_cmov_test and fix schnorrsig_verify exhaustive test (stratospher)
d78bec7001 ci: Remove Windows MSVC tasks from Cirrus CI (Hennadii Stepanov)
3545dc2b9b ci, gha: Run all MSVC tests on Windows natively (Hennadii Stepanov)
54058d16fe field: remove `secp256k1_fe_equal_var` (siv2r)
bb4efd6404 tests: remove unwanted `secp256k1_fe_normalize_weak` call (siv2r)
c2f6435802 ci: Add comment about switching macOS to M1 on GHA later (Tim Ruffing)
4a24fae0bc ci: Remove "arm64: macOS Ventura" task from Cirrus CI (Hennadii Stepanov)
8e54a346d2 ci, gha: Run "x86_64: macOS Ventura" job on GitHub Actions (Hennadii Stepanov)
747ada3587 test: Silent noisy clang warnings about Valgrind code on macOS x86_64 (Hennadii Stepanov)
d62db57427 ci: Use Homebrew's gcc in native macOS task (Hennadii Stepanov)
b7c685e74a Save _normalize_weak calls in group add methods (Peter Dettman)
c83afa66e0 Tighten group magnitude limits (Peter Dettman)
173e8d061a Implement current magnitude assumptions (Peter Dettman)
49afd2f5d8 Take use of _fe_verify_magnitude in field_impl.h (Sebastian Falbesoner)
4e9661fc42 Add _fe_verify_magnitude (no-op unless VERIFY is enabled) (Peter Dettman)
690b0fc05a add missing group element invariant checks (Sebastian Falbesoner)
9c91ea41b1 ci: Enable ellswift module where it's missing (Tim Ruffing)
db32a24761 ctimetests: Use new SECP256K1_CHECKMEM macros also for ellswift (Tim Ruffing)
8408dfdc4c Revert "ci: Run sage prover on CI" (Hennadii Stepanov)
c8d9914fb1 ci, gha: Run "SageMath prover" job on GitHub Actions (Hennadii Stepanov)
f1774e5ec4 ci, gha: Make MSVC job presentation more explicit (Hennadii Stepanov)
5ee039bb58 ci: Remove "Windows (VS 2022)" task from Cirrus CI (Hennadii Stepanov)
a2f7ccdecc ci: Run "Windows (VS 2022)" job on GitHub Actions (Hennadii Stepanov)
175db31149 ci: Drop no longer needed `PATH` variable update on Windows (Hennadii Stepanov)
116d2ab3df cmake: Set `ENVIRONMENT` property for examples on Windows (Hennadii Stepanov)
cef373997c cmake, refactor: Use helper function instead of interface library (Hennadii Stepanov)
a1bd4971d6 refactor: take use of `secp256k1_scalar_{zero,one}` constants (part 2) (Sebastian Falbesoner)

Pull request description:

  [bitcoin-core/secp256k1#1391]: refactor: take use of `secp256k1_scalar_{zero,one}` constants (part 2)
  [bitcoin-core/secp256k1#1290]: cmake: Set `ENVIRONMENT` property for examples on Windows
  [bitcoin-core/secp256k1#1389]: ci: Run "Windows (VS 2022)" job on GitHub Actions
  [bitcoin-core/secp256k1#1397]: ci: Remove "Windows (VS 2022)" task from Cirrus CI
  [bitcoin-core/secp256k1#1399]: ci, gha: Run "SageMath prover" job on GitHub Actions
  [bitcoin-core/secp256k1#1400]: ctimetests: Use new SECP256K1_CHECKMEM macros also for ellswift
  [bitcoin-core/secp256k1#1348]: tighten group magnitude limits, save normalize_weak calls in group add methods (revival of #1032)
  [bitcoin-core/secp256k1#1402]: ci: Use Homebrew'\''s gcc in native macOS task
  [bitcoin-core/secp256k1#1274]: test: Silent noisy clang warnings about Valgrind code on macOS x86_64
  [bitcoin-core/secp256k1#1394]: ci, gha: Run "x86_64: macOS Ventura" job on GitHub Actions
  [bitcoin-core/secp256k1#1404]: ci: Remove "arm64: macOS Ventura" task from Cirrus CI
  [bitcoin-core/secp256k1#1062]: Removes `_fe_equal_var`, and unwanted `_fe_normalize_weak` calls (in tests)
  [bitcoin-core/secp256k1#1401]: ci, gha: Run all MSVC tests on Windows natively
  [bitcoin-core/secp256k1#1373]: Add invariant checking for scalars
  [bitcoin-core/secp256k1#1403]: ci, gha: Ensure only a single workflow processes `github.ref` at a time
  [bitcoin-core/secp256k1#1398]: ci, gha: Add Windows jobs based on Linux image
  [bitcoin-core/secp256k1#1405]: ci: Drop no longer needed workaround
  [bitcoin-core/secp256k1#1396]: ci, gha: Add "x86_64: Linux (Debian stable)" GitHub Actions job
  [bitcoin-core/secp256k1#1406]: ci, gha: Move more non-x86_64 tasks from Cirrus CI to GitHub Actions
  [bitcoin-core/secp256k1#1410]: ci: Use concurrency for pull requests only
  [bitcoin-core/secp256k1#1409]: ci: Move remained task from Cirrus to GitHub Actions
  [bitcoin-core/secp256k1#1411]: ci: Make repetitive command the default one
  [bitcoin-core/secp256k1#1412]: ci: Switch macOS from Ventura to Monterey and add Valgrind
  [bitcoin-core/secp256k1#1414]: ci/gha: Add ARM64 QEMU jobs for clang and clang-snapshot
  [bitcoin-core/secp256k1#1413]: ci: Add `release` job
  [bitcoin-core/secp256k1#1415]: release: Prepare for 0.4.0
  [bitcoin-core/secp256k1#1417]: release cleanup: bump version after 0.4.0
  [bitcoin-core/secp256k1#1390]: tests: Replace counting_illegal_callbacks with CHECK_ILLEGAL_VOID
  [bitcoin-core/secp256k1#1416]: doc: Align documented scripts with CI ones
  [bitcoin-core/secp256k1#1422]: cmake: Install `libsecp256k1.pc` file
  [bitcoin-core/secp256k1#1424]: ci: Bump major versions for docker actions
  [bitcoin-core/secp256k1#1395]: tests: simplify `random_fe_non_zero` (remove loop limit and unneeded normalize)

  This PR can be recreated with `./contrib/sync-upstream.sh -b master range ee7aaf213ea3eb42fc8960c7d178b5ffb286440f`.
  Tip: Use `git show --remerge-diff` to show the changes manually added to the merge commit.' --web

  - Replace fe_equal_var with fe_equal
  - Use CHECK_ILLEGAL instead of CHECK/ecount
  - Turn on secp256k1-zkp specific modules in CI

ACKs for top commit:
  real-or-random:
    ACK b41caaafd2

Tree-SHA512: e8994fa2590d6e277d60a130d3f11b0256dc7fbe67e8a2b85463d9849d3f9fbfccf366b17b3904f1974f8b7b27a24128d2a04a3337c1b8409d000d136714bf90
2023-10-12 17:14:20 +02:00
Jonas Nick
b41caaafd2 bppp: replace memcmp in tests with secp256k1_memcmp_var 2023-10-12 13:10:05 +00:00
Jonas Nick
6a3aae8f1d group_parse: use secp256k1_memcmp_var instead of memcmp 2023-10-12 11:18:21 +00:00
Jonas Nick
e9d522fc64 ci: turn on -zkp modules in macos-native job 2023-10-12 08:10:49 +00:00
Tim Ruffing
b314cf2833 Merge bitcoin-core/secp256k1#1426: ci/cirrus: Add native ARM64 jobs
fa4d6c76b6 ci/cirrus: Add native ARM64 persistent workers (MarcoFalke)
2262d0eaab ci/cirrus: Bring back skeleton .cirrus.yml without jobs (Tim Ruffing)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK fa4d6c76b6
  hebasto:
    re-ACK fa4d6c76b6, only last two commits have been squashed since my recent [review](https://github.com/bitcoin-core/secp256k1/pull/1426#pullrequestreview-1636119941).

Tree-SHA512: d1fee99d54a41a4126f7eb72695a56137c925dc9ce7cd692a60ea1262ac0789bbd6aa4e4dfc030f0d97d06aeeae0724a5f2d794a85ff533c6cf3cd215f6a4b7a
2023-09-20 23:14:07 +00:00
MarcoFalke
fa4d6c76b6 ci/cirrus: Add native ARM64 persistent workers
Co-authored-by: Tim Ruffing <crypto@timruffing.de>
2023-09-20 17:09:54 +00:00
Jonas Nick
775f5e242b Merge commits '1b13415d 374e2b54 96294c00 8d2960c8 ce765a5b b2f6712d eedd7810 b327abfc 5d8fa825 3d05c86d bcffeb14 de657c20 060e32cb 0ba2b945 48b1d939 6b9507ad 5373693e 2e6cf9ba 6ee14550 26a98992 4d7fe609 ea26b71c 65c79fe2 727bec5b 0b4640ae 199d27ce cbf3053f 49be5be9 b10ddd2b 4fd00f4b ba9cb6f3 ee7aaf21 ' into temp-merge-1395
- Replace fe_equal_var with fe_equal
- Use CHECK_ILLEGAL instead of CHECK/ecount
- Turn on secp256k1-zkp specific modules in CI
2023-09-20 09:38:36 +00:00
Tim Ruffing
ee7aaf213e Merge bitcoin-core/secp256k1#1395: tests: simplify random_fe_non_zero (remove loop limit and unneeded normalize)
c45b7c4fbb refactor: introduce testutil.h (deduplicate `random_fe_`, `ge_equals_` helpers) (Sebastian Falbesoner)
dc5514144f tests: simplify `random_fe_non_zero` (remove loop limit and unneeded normalize) (Sebastian Falbesoner)

Pull request description:

  `random_fe_non_zero` contains a loop iteration limit that ensures that we abort if `random_fe` ever yielded zero more than ten times in a row. This construct was first introduced in PR #19 (commit 09ca4f32) for random non-square field elements and was later refactored into the non-zero helper in PR #25 (commit 6d6102fe). The copy-over to the exhaustive tests happened recently in PR #1118 (commit 0f864207).

  This case seems to be practically irrelevant and I'd argue for keeping things simple and removing it (which was already suggested in https://github.com/bitcoin-core/secp256k1/pull/1118#discussion_r1067259954); if there's really a worry that the test's random generator is heavily biased towards certain values or value ranges then there should consequently be checks at other places too (e.g. directly in `random_fe` for 256-bit values that repeatedly overflow, i.e. >= p).

  Also, the _fe_normalize call is not needed and can be removed, as the result of `random_fe` is already normalized.

ACKs for top commit:
  real-or-random:
    utACK c45b7c4fbb
  siv2r:
    ACK `c45b7c4` (reviewed the changes and tests for both the commits passed locally).

Tree-SHA512: 4ffa66dd0b8392d7d0083a71e7b0682ad18f9261fd4ce8548c3059b497d3462db97e16114fded9787661ca447a877a27f5b996bd7d47e6f91c4454079d28a8ac
2023-09-14 15:06:41 +02:00
Tim Ruffing
ba9cb6f378 Merge bitcoin-core/secp256k1#1424: ci: Bump major versions for docker actions
d9d80fd155 ci: Bump major versions for docker actions (Hennadii Stepanov)

Pull request description:

  See:
  - https://github.com/docker/build-push-action/releases/tag/v5.0.0
  - https://github.com/docker/setup-buildx-action/releases/tag/v3.0.0

ACKs for top commit:
  real-or-random:
    ACK d9d80fd155

Tree-SHA512: b1266e46cd02f8e893b4ce3b4bf51f7fb2ea7c6ae54a5c24a4bc5df4f6e97e99afaf90cf598d4321e8b83a250ba5fd7d43c34d53a8cc71f70f6c6e05cc973d6f
2023-09-13 14:49:13 +02:00
Hennadii Stepanov
d9d80fd155 ci: Bump major versions for docker actions
https://github.com/docker/build-push-action/releases/tag/v5.0.0
https://github.com/docker/setup-buildx-action/releases/tag/v3.0.0
2023-09-12 10:18:39 +01:00
Tim Ruffing
4fd00f4bfe Merge bitcoin-core/secp256k1#1422: cmake: Install libsecp256k1.pc file
421d84855a ci: Align Autotools/CMake `CI_INSTALL` directory names (Hennadii Stepanov)
9f005c60d6 cmake: Install `libsecp256k1.pc` file (Hennadii Stepanov)

Pull request description:

  This PR allows downstream projects to use pkg-config to search for the libsecp256k1 library that is built with CMake.

  Addressed https://github.com/bitcoin-core/secp256k1/discussions/1419#discussioncomment-6922896:
  > We could just ship the pkg-config file also in CMake builds.

ACKs for top commit:
  real-or-random:
    ACK 421d84855a I compared the generated pc files and they match in autotools and CMake

Tree-SHA512: 8e54eb7c76bc727ab18715258c06cc2a419c6c04892a2bd7bfe34392f9a3223f673ff84d2d21b00b3c222b357f02296ec49c872532d98ea0a2f17ef1ed6b6ac1
2023-09-12 10:14:48 +02:00
Hennadii Stepanov
421d84855a ci: Align Autotools/CMake CI_INSTALL directory names 2023-09-07 20:58:28 +01:00
Hennadii Stepanov
9f005c60d6 cmake: Install libsecp256k1.pc file
This change allows downstream projects to use pkg-config to search for
the libsecp256k1 library that is built with CMake.
2023-09-07 20:47:57 +01:00
Tim Ruffing
2262d0eaab ci/cirrus: Bring back skeleton .cirrus.yml without jobs 2023-09-05 13:45:43 +02:00
Jonas Nick
b10ddd2bd2 Merge bitcoin-core/secp256k1#1416: doc: Align documented scripts with CI ones
b0f7bfedc9 doc: Do not mention soname in CHANGELOG.md "ABI Compatibility" section (Hennadii Stepanov)
bd9d98d353 doc: Align documented scripts with CI ones (Hennadii Stepanov)

Pull request description:

ACKs for top commit:
  sipa:
    ACK b0f7bfedc9
  real-or-random:
    ACK b0f7bfedc9

Tree-SHA512: 99cbc065cf9610923a863bac34e607ce4f2b1fe71fc32cb96fed33203e42c914ef29924cd9eade89859f63fdd95ffb214c5a2a1066bfca9c202e85aec5f7c16e
2023-09-04 17:27:23 +00:00
Tim Ruffing
49be5be9e8 Merge bitcoin-core/secp256k1#1390: tests: Replace counting_illegal_callbacks with CHECK_ILLEGAL_VOID
70303643cf tests: add CHECK_ERROR_VOID and use it in scratch tests (Jonas Nick)
f8d7ea68df tests: Replace counting_illegal_callbacks with CHECK_ILLEGAL_VOID (Jonas Nick)
a1d52e3e12 tests: remove unnecessary test in run_ec_pubkey_parse_test (Jonas Nick)
875b0ada25 tests: remove unnecessary set_illegal_callback (Jonas Nick)

Pull request description:

  Fixes #1167

ACKs for top commit:
  siv2r:
    reACK 7030364 (tests pass locally)
  real-or-random:
    reACK 70303643cf

Tree-SHA512: 0ca1f1c92a1c3a93b412433e53e882be56f3c7c55d4cbf12683ab7d9b8a916231b6508270099bfed0bfaa9d0af19cb8fdf0fe3274112ab48d33a0bd2356f2fa7
2023-09-04 18:58:57 +02:00
Tim Ruffing
cbf3053ff1 Merge bitcoin-core/secp256k1#1417: release cleanup: bump version after 0.4.0
9b118bc7fb release cleanup: bump version after 0.4.0 (Jonas Nick)

Pull request description:

  based on #1415

ACKs for top commit:
  sipa:
    ACK 9b118bc7fb
  hebasto:
    ACK 9b118bc7fb
  real-or-random:
    ACK 9b118bc7fb

Tree-SHA512: 76df87c41bdc3379df4e88619645f5110010d7713ebe20bad3e7c99472bd62b90f4bd3c6b558ad5a23119acc4734e39383d96a9800e4a43dfadc086ef66fd0ab
2023-09-04 18:37:41 +02:00
Jonas Nick
9b118bc7fb release cleanup: bump version after 0.4.0 2023-09-04 16:27:38 +00:00
Jonas Nick
199d27cea3 Merge bitcoin-core/secp256k1#1415: release: Prepare for 0.4.0
16339804c9 release: Prepare for 0.4.0 (Tim Ruffing)
d9a85065a9 changelog: Catch up in preparation of release (Tim Ruffing)

Pull request description:

ACKs for top commit:
  hebasto:
    re-ACK 16339804c9.
  sipa:
    ACK 16339804c9
  jonasnick:
    ACK 16339804c9

Tree-SHA512: 9b29edc8beece44cb8456de9844bf22e13f41b43bb5567b3f37dcbdcb7cd5ca6a976a0f805973ddfa7666509aa452247a4d8297e3cfb362acaf4f0fa942daa21
2023-09-04 16:26:47 +00:00
Jonas Nick
70303643cf tests: add CHECK_ERROR_VOID and use it in scratch tests 2023-09-04 16:19:49 +00:00
Jonas Nick
f8d7ea68df tests: Replace counting_illegal_callbacks with CHECK_ILLEGAL_VOID
This commit also explicitly initializes shortpubkey. For some reason, removing
surrounding, unrelated lines results in gcc warnings when configured with
--enable-ctime-tests=no --with-valgrind=no.
2023-09-04 16:19:40 +00:00
Tim Ruffing
16339804c9 release: Prepare for 0.4.0 2023-09-04 18:18:24 +02:00
Tim Ruffing
d9a85065a9 changelog: Catch up in preparation of release 2023-09-04 18:18:19 +02:00
Hennadii Stepanov
b0f7bfedc9 doc: Do not mention soname in CHANGELOG.md "ABI Compatibility" section
Co-authored-by: Tim Ruffing <crypto@timruffing.de>
2023-09-04 17:05:53 +01:00
Hennadii Stepanov
bd9d98d353 doc: Align documented scripts with CI ones 2023-09-04 16:05:29 +01:00
Tim Ruffing
0b4640aedd Merge bitcoin-core/secp256k1#1413: ci: Add release job
8659a01714 ci: Add `release` job (Hennadii Stepanov)
f9b38894ba ci: Update `actions/checkout` version (Hennadii Stepanov)

Pull request description:

  This PR introduces a new "Release" job that conducts sanity checks as defined in [`doc/release-process.md`](https://github.com/bitcoin-core/secp256k1/blob/master/doc/release-process.md#sanity-checks).

ACKs for top commit:
  sipa:
    ACK 8659a01714
  real-or-random:
    ACK 8659a01714

Tree-SHA512: 84e03fa07f8c41aec0f6d1ccb4ac3643e85d370ef7e388b335365deadb555f2d9ef7e5d80e1255a18e790a774e04ca66f265b9441402b183d4c535a97688f20f
2023-09-04 16:27:14 +02:00
Hennadii Stepanov
8659a01714 ci: Add release job
The new job runs checks outlined in the `doc/release-process.md`.
2023-09-04 15:04:37 +01:00
Hennadii Stepanov
f9b38894ba ci: Update actions/checkout version 2023-09-04 14:58:01 +01:00
Jonas Nick
a1d52e3e12 tests: remove unnecessary test in run_ec_pubkey_parse_test
This test tested whether setting the callback works correctly which should be
tested in the context tests.
2023-09-04 12:52:19 +00:00
Jonas Nick
875b0ada25 tests: remove unnecessary set_illegal_callback 2023-09-04 12:50:32 +00:00
Tim Ruffing
727bec5bc2 Merge bitcoin-core/secp256k1#1414: ci/gha: Add ARM64 QEMU jobs for clang and clang-snapshot
2635068abf ci/gha: Let MSan continue checking after errors in all jobs (Tim Ruffing)
e78c7b68eb ci/Dockerfile: Reduce size of Docker image further (Tim Ruffing)
2f0d3bbffb ci/Dockerfile: Warn if `ulimit -n` is too high when running Docker (Tim Ruffing)
4b8a647ad3 ci/gha: Add ARM64 QEMU jobs for clang and clang-snapshot (Tim Ruffing)
6ebe7d2bb3 ci/Dockerfile: Always use versioned clang packages (Tim Ruffing)

Pull request description:

  Solves one item in https://github.com/bitcoin-core/secp256k1/issues/1392.

  This PR also has a few tweaks to the Dockerfile, see individual commits.

  ---

  I'll follow up soon with a PR for ARM64/gcc. This will rely on Cirrus CI.

ACKs for top commit:
  hebasto:
    ACK 2635068abf.

Tree-SHA512: d290bdd8e8e2a2a2b6ccb1b25ecdc9662c51dab745068a98044b9abed75232d13cb9d2ddc2c63c908dcff6a12317f0c7a35db3288c57bc3b814793f7fce059fd
2023-09-04 08:59:14 +02:00
Tim Ruffing
2635068abf ci/gha: Let MSan continue checking after errors in all jobs 2023-09-03 11:31:35 +02:00
Tim Ruffing
e78c7b68eb ci/Dockerfile: Reduce size of Docker image further
- No need to have wget installed
 - Clean up rm -rf /var/lib/apt/lists/, see
   https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#apt-get
2023-09-03 11:31:35 +02:00
Tim Ruffing
2f0d3bbffb ci/Dockerfile: Warn if ulimit -n is too high when running Docker
The underlying issue does not affect our CI hosts, but is an issue on my
development machine (Arch Linux). In particular, this affects the vanilla
configuration of Docker on systemd, which has effectively no limit:
11400a3f5a/pkg/docker-engine/common/systemd/docker.service (L31)

I hope this saves future generations some precious hours of their life.
2023-09-03 11:31:35 +02:00
Tim Ruffing
4b8a647ad3 ci/gha: Add ARM64 QEMU jobs for clang and clang-snapshot 2023-09-03 11:31:35 +02:00
Tim Ruffing
6ebe7d2bb3 ci/Dockerfile: Always use versioned clang packages
This commit switches to a new strategy to make sure we're installing the
most recent LLVM packages. Before this commit, we used the unversioned
LLVM packages (e.g., `clang` instead of `clang-18`), which are supposed
to provide the latest snapshot, but this is broken for arm64 [1],
which we want to add in a later PR.

Anyway, the new approach is cleaner because it does not require us to
fiddle with the installed `clang` package by removing a symlink.

[1] https://github.com/llvm/llvm-project/issues/64790

Co-authored-by: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
2023-09-03 11:29:44 +02:00
Tim Ruffing
65c79fe2d0 Merge bitcoin-core/secp256k1#1412: ci: Switch macOS from Ventura to Monterey and add Valgrind
c223d7e33d ci: Switch macOS from Ventura to Monterey and add Valgrind (Hennadii Stepanov)

Pull request description:

  This PR switches the macOS native job from Ventura to Monterey, which allows to support Valgrind.

  Both runners--`macos-12` and `macos-13`--have the same clang compilers installed:
  - https://github.com/actions/runner-images/blob/main/images/macos/macos-12-Readme.md
  - https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md

  But Valgrind works fine on macOS Monterey, but not on Ventura.

  See: https://github.com/bitcoin-core/secp256k1/issues/1392#issuecomment-1693685610.

  The Homebrew's Valgrind package is cached once it has been built (as it was before https://github.com/bitcoin-core/secp256k1/pull/1152). Therefore, the `actions/cache@*` action is needed to be added to the list of the allowed actions.

  https://github.com/bitcoin-core/secp256k1/pull/1412#issuecomment-1695716350:
  > By the way, this solves #1151.

ACKs for top commit:
  real-or-random:
    ACK c223d7e33d I tested that a cttest failure makes CI fail: https://github.com/real-or-random/secp256k1/actions/runs/6010365844

Tree-SHA512: 5e72d89fd4d82acbda8adeda7106db0dad85162cca03abe8eae9a40393997ba36a84ad7b12c4b32aec5e9230f275738ef12169994cd530952e2b0b963449b231
2023-08-29 14:59:47 +02:00
Hennadii Stepanov
c223d7e33d ci: Switch macOS from Ventura to Monterey and add Valgrind 2023-08-28 17:49:45 +01:00
Tim Ruffing
ea26b71c3a Merge bitcoin-core/secp256k1#1411: ci: Make repetitive command the default one
cce0456304 ci: Make repetitive command the default one (Hennadii Stepanov)
317a4c48f0 ci: Move `git config ...` to `run-in-docker-action` (Hennadii Stepanov)

Pull request description:

  This PR addresses the https://github.com/bitcoin-core/secp256k1/pull/1409#discussion_r1301767281:
  > couldn't we add this to `run-in-docker-action` to avoid duplication?

ACKs for top commit:
  real-or-random:
    ACK cce0456304

Tree-SHA512: 793cec3d99853a23e06680fe35a7cae2dc8771f22e3940c4a4f36357273164f2d92e196768118d146e956ffca9ef59d4e5f86e1cba5576ebfdc59343581c9924
2023-08-24 10:46:07 +02:00
Hennadii Stepanov
cce0456304 ci: Make repetitive command the default one 2023-08-23 21:31:57 +01:00
Hennadii Stepanov
317a4c48f0 ci: Move git config ... to run-in-docker-action 2023-08-23 21:18:53 +01:00
Tim Ruffing
4d7fe60905 Merge bitcoin-core/secp256k1#1409: ci: Move remained task from Cirrus to GitHub Actions
676ed8f9cf ci: Move "C++ (public headers)" from Cirrus to GitHub Actions (Hennadii Stepanov)
61fc3a2dc8 ci: Move "C++ -fpermissive..." from Cirrus to GitHub Actions (Hennadii Stepanov)
d51fb0a533 ci: Move "MSan" from Cirrus to GitHub Actions (Hennadii Stepanov)
c22ac27529 ci: Move sanitizers task from Cirrus to GitHub Actions (Hennadii Stepanov)

Pull request description:

  This PR concludes the migration from Cirrus CI to GitHub Actions.

ACKs for top commit:
  real-or-random:
    ACK 676ed8f9cf

Tree-SHA512: d8ea91a20297ff4c2c11a02c0a52f19413fde442c71e2e8b660737c09d62e55e4ae3f9bdbdeb0d967f6720a3dffa1566b7f94e0e32bcd490ac052819d5427c84
2023-08-23 14:57:52 +02:00
Hennadii Stepanov
676ed8f9cf ci: Move "C++ (public headers)" from Cirrus to GitHub Actions 2023-08-23 10:59:26 +01:00
Hennadii Stepanov
61fc3a2dc8 ci: Move "C++ -fpermissive..." from Cirrus to GitHub Actions 2023-08-23 10:24:24 +01:00
Hennadii Stepanov
d51fb0a533 ci: Move "MSan" from Cirrus to GitHub Actions 2023-08-23 10:24:15 +01:00
Hennadii Stepanov
c22ac27529 ci: Move sanitizers task from Cirrus to GitHub Actions 2023-08-23 10:24:05 +01:00
Tim Ruffing
26a989924b Merge bitcoin-core/secp256k1#1410: ci: Use concurrency for pull requests only
ee1be62d84 ci: Use concurrency for pull requests only (Hennadii Stepanov)

Pull request description:

  This PR is an amendment for https://github.com/bitcoin-core/secp256k1/pull/1403.

  It avoids skipping builds when some pushes were done consequentially.

  From GitHub Actions [docs](https://docs.github.com/en/actions/using-jobs/using-concurrency):

  > When a concurrent ... workflow is queued, if another ... workflow using the same concurrency group in the repository is in progress, the queued ... workflow will be pending. **Any previously pending ... workflow in the concurrency group will be canceled.**

  No behavior change for pull requests.

  Same as https://github.com/bitcoin/bitcoin/pull/28322.

ACKs for top commit:
  real-or-random:
    ACK ee1be62d84

Tree-SHA512: ce26378c3224a7647eb3b351d19e9308650ad49b933a68d37a0eca8516767a63f55580a33b02864caa539392c9aab0b4b54ecbace85bea6082bf533539a37c9c
2023-08-23 11:02:52 +02:00
Hennadii Stepanov
ee1be62d84 ci: Use concurrency for pull requests only
Otherwise, any previously pending workflow will be canceled on the
following push.
2023-08-22 15:02:30 +01:00
Tim Ruffing
6ee14550c8 Merge bitcoin-core/secp256k1#1406: ci, gha: Move more non-x86_64 tasks from Cirrus CI to GitHub Actions
fc3dea29ea ci: Move "ppc64le: Linux..." from Cirrus to GitHub Actions (Hennadii Stepanov)
7782dc8276 ci: Move "ARM64: Linux..." from Cirrus to GitHub Actions (Hennadii Stepanov)
0a16de671c ci: Move "ARM32: Linux..." from Cirrus to GitHub Actions (Hennadii Stepanov)
ea33914e00 ci: Move "s390x (big-endian): Linux..." from Cirrus to GitHub Actions (Hennadii Stepanov)
880be8af99 ci: Move "i686: Linux (Debian stable)" from Cirrus to GiHub Actions (Hennadii Stepanov)

Pull request description:

  Move more non-x86_64 tasks from Cirrus CI to GitHub Actions.

  Solves one item in https://github.com/bitcoin-core/secp256k1/issues/1392 partially.

ACKs for top commit:
  real-or-random:
    ACK fc3dea29ea but still waiting for Cirrus

Tree-SHA512: 9a910b3ee500aa34fc4db827f8b2a50bcfb637a9e59f4ad32545634772b397ce80b31a18723f4605dc42aa19a5632292943102099f7720f87de1da454da068b0
2023-08-22 11:10:43 +02:00
Hennadii Stepanov
fc3dea29ea ci: Move "ppc64le: Linux..." from Cirrus to GitHub Actions 2023-08-21 15:33:27 +01:00
Hennadii Stepanov
7782dc8276 ci: Move "ARM64: Linux..." from Cirrus to GitHub Actions 2023-08-21 15:33:19 +01:00
Hennadii Stepanov
0a16de671c ci: Move "ARM32: Linux..." from Cirrus to GitHub Actions 2023-08-21 15:33:08 +01:00
Hennadii Stepanov
ea33914e00 ci: Move "s390x (big-endian): Linux..." from Cirrus to GitHub Actions 2023-08-21 15:32:56 +01:00
Hennadii Stepanov
880be8af99 ci: Move "i686: Linux (Debian stable)" from Cirrus to GiHub Actions 2023-08-21 15:32:20 +01:00
Tim Ruffing
2e6cf9bae5 Merge bitcoin-core/secp256k1#1396: ci, gha: Add "x86_64: Linux (Debian stable)" GitHub Actions job
e10878f58e ci, gha: Drop `driver-opts.network` input for `setup-buildx-action` (Hennadii Stepanov)
4ad4914bd1 ci, gha: Add `retry_builder` Docker image builder (Hennadii Stepanov)
6617a620d9 ci: Remove "x86_64: Linux (Debian stable)" task from Cirrus CI (Hennadii Stepanov)
03c9e6508c ci, gha: Add "x86_64: Linux (Debian stable)" GitHub Actions job (Hennadii Stepanov)
ad3e65d9fe ci: Remove GCC build files and sage to reduce size of Docker image (Tim Ruffing)

Pull request description:

  Solves one item in https://github.com/bitcoin-core/secp256k1/issues/1392 partially.

ACKs for top commit:
  real-or-random:
    ACK e10878f58e

Tree-SHA512: 1e685b1a6a41b4be97b9b5bb0fe546c3f1f7daac9374146ca05ab29803d5945a038294ce3ab77489bd971ffce9789ece722e0e0f268b6a7e6483a3aa782d532d
2023-08-21 16:06:50 +02:00
Tim Ruffing
5373693e45 Merge bitcoin-core/secp256k1#1405: ci: Drop no longer needed workaround
ef9fe959de ci: Drop no longer needed workaround (Hennadii Stepanov)

Pull request description:

  The https://sourceware.org/bugzilla/show_bug.cgi?id=27008 bug has been resolved since libc 2.33.

  Debian Bookworm has [libc](https://packages.debian.org/bookworm/libc6) 2.36.

  I've separated this change from moving CI tasks to GitHub Actions intentionally.

ACKs for top commit:
  real-or-random:
    ACK ef9fe959de

Tree-SHA512: 4e8ce1232fcb581fa4700da75e5f63ff3da359416e5c5c1966f6aae079219fd697554db03d0b1729ea62cca42aae74bd36621a85d6ec7e4ee18e2c20b879cfa6
2023-08-21 16:06:04 +02:00
Hennadii Stepanov
ef9fe959de ci: Drop no longer needed workaround
The https://sourceware.org/bugzilla/show_bug.cgi?id=27008 bug has been
resolved since libc 2.33.

Debian Bookworm has libc 2.36.
2023-08-20 11:15:45 +01:00
Hennadii Stepanov
e10878f58e ci, gha: Drop driver-opts.network input for setup-buildx-action 2023-08-19 18:02:08 +01:00
Hennadii Stepanov
4ad4914bd1 ci, gha: Add retry_builder Docker image builder
This change is aimed at significantly reducing the frequency of failures
caused by intermittent network timeouts.
2023-08-18 17:05:25 +01:00
Hennadii Stepanov
6617a620d9 ci: Remove "x86_64: Linux (Debian stable)" task from Cirrus CI 2023-08-18 13:58:46 +01:00
Hennadii Stepanov
03c9e6508c ci, gha: Add "x86_64: Linux (Debian stable)" GitHub Actions job 2023-08-18 13:57:50 +01:00
Tim Ruffing
ad3e65d9fe ci: Remove GCC build files and sage to reduce size of Docker image 2023-08-18 13:52:28 +01:00
Jonas Nick
6b9507adf6 Merge bitcoin-core/secp256k1#1398: ci, gha: Add Windows jobs based on Linux image
87d35f30c0 ci: Rename `cirrus.sh` to more general `ci.sh` (Hennadii Stepanov)
d6281dd008 ci: Remove Windows tasks from Cirrus CI (Hennadii Stepanov)
2b6f9cd546 ci, gha: Add Windows jobs based on Linux image (Hennadii Stepanov)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 87d35f30c0
  jonasnick:
    ACK 87d35f30c0

Tree-SHA512: bab005041692f52ed26899d50ee9114e6dd57a21ffa36b4d0b99e8b5b394a64a956cbc99ae2767fdf64f242970ebbeb0df4f5b373e059ecb187174f471b1a95e
2023-08-18 12:47:10 +00:00
Hennadii Stepanov
87d35f30c0 ci: Rename cirrus.sh to more general ci.sh
This makes sense in the process of moving stuff to GitHub Actions.
2023-08-18 10:57:58 +01:00
Hennadii Stepanov
d6281dd008 ci: Remove Windows tasks from Cirrus CI 2023-08-18 10:57:58 +01:00
Hennadii Stepanov
2b6f9cd546 ci, gha: Add Windows jobs based on Linux image 2023-08-18 10:57:45 +01:00
Jonas Nick
48b1d939b5 Merge bitcoin-core/secp256k1#1403: ci, gha: Ensure only a single workflow processes github.ref at a time
b0886fd35c ci, gha: Ensure only a single workflow processes `github.ref` at a time (Hennadii Stepanov)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK b0886fd35c
  jonasnick:
    ACK b0886fd35c

Tree-SHA512: 8edda9259fc07bda3a35286ab97238b2f2749fbc629030da52e5a352988e5562cf62255c7d4917b7f0c8dbc9a0bd3a36b5e725d3d5a4c635ae8239faef829d1b
2023-08-18 09:56:40 +00:00
Tim Ruffing
0ba2b94551 Merge bitcoin-core/secp256k1#1373: Add invariant checking for scalars
d23da6d557 use secp256k1_scalar_verify checks (stratospher)
c7d0454932 add verification for scalars (stratospher)
ad152151b0 update max scalar in scalar_cmov_test and fix schnorrsig_verify exhaustive test (stratospher)

Pull request description:

  From #1360. This PR:
  1. adds `secp256k1_scalar_verify` to make sure scalars are reduced mod the group order in VERIFY mode
  2. uses `secp256k1_scalar_verify` in all the scalar functions except `secp256k1_scalar_clear`, `secp256k1_scalar_reduce_512`, `secp256k1_scalar_mul_512` and `secp256k1_scalar_*_var` functions in `scalar_low_impl.h`

ACKs for top commit:
  real-or-random:
    utACK d23da6d557
  theStack:
    Code-review ACK d23da6d557

Tree-SHA512: a371b319d948198c4038d35c9ea58f4b94de4dc312215e2b78a323c2acd4ae1355d97935c558b388774832d6d0058b97ff8ca50c3aab40b9ede5307760d0a505
2023-08-18 11:44:17 +02:00
Sebastian Falbesoner
c45b7c4fbb refactor: introduce testutil.h (deduplicate random_fe_, ge_equals_ helpers) 2023-08-17 19:44:00 +02:00
Sebastian Falbesoner
dc5514144f tests: simplify random_fe_non_zero (remove loop limit and unneeded normalize)
`random_fe_non_zero` contains a loop iteration limit that ensures that
we abort if `random_fe` ever yielded zero more than ten times in a row.
This construct was first introduced in PR #19 (commit 09ca4f32) for
random non-square field elements and was later refactored into the
non-zero helper in PR #25 (commit 6d6102fe). The copy-over to the
exhaustive tests happened recently in PR #1118 (commit 0f864207).

This case seems to be practically irrelevant and I'd argue for keeping
things simple and removing it; if there's really a worry that the test's
random generator is heavily biased towards certain values or value
ranges then there should consequently be checks at other places too
(e.g. directly in `random_fe` for 256-bit values that repeatedly
overflow, i.e. >= p).

Also, the _fe_normalize call is not needed and can be removed, as the
result of `random_fe` is already normalized.
2023-08-17 19:40:49 +02:00
Jonas Nick
060e32cb60 Merge bitcoin-core/secp256k1#1401: ci, gha: Run all MSVC tests on Windows natively
d78bec7001 ci: Remove Windows MSVC tasks from Cirrus CI (Hennadii Stepanov)
3545dc2b9b ci, gha: Run all MSVC tests on Windows natively (Hennadii Stepanov)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK d78bec7001
  jonasnick:
    ACK d78bec7001

Tree-SHA512: b58162a9f0827dceb1c7eb6fb7c759c0bffcf3e0d24cc7e6628ad71d1faaabaffb9d8de6fcd3d07bfcaca409632a13f711f9ad871a30718139557544cf91b4bf
2023-08-17 16:55:15 +00:00
Tim Ruffing
de657c2044 Merge bitcoin-core/secp256k1#1062: Removes _fe_equal_var, and unwanted _fe_normalize_weak calls (in tests)
54058d16fe field: remove `secp256k1_fe_equal_var` (siv2r)
bb4efd6404 tests: remove unwanted `secp256k1_fe_normalize_weak` call (siv2r)

Pull request description:

  Fixes #946 and #1061

  Changes:
  - removes unwanted `fe_normalize_weak` calls to the second argument of `fe_equal`
  - removes `fe_equal_var`

ACKs for top commit:
  real-or-random:
    utACK 54058d16fe
  jonasnick:
    ACK 54058d16fe

Tree-SHA512: 89bfd1c205f760d0736b995adebb96d15b0df0a42ece25885c57ae7f4318f6816eb009a7fe94b5987a4cbb8588f0fffbdc275234b406a2d1f80d7695b4bd89db
2023-08-17 18:25:22 +02:00
Jonas Nick
bcffeb14bc Merge bitcoin-core/secp256k1#1404: ci: Remove "arm64: macOS Ventura" task from Cirrus CI
c2f6435802 ci: Add comment about switching macOS to M1 on GHA later (Tim Ruffing)
4a24fae0bc ci: Remove "arm64: macOS Ventura" task from Cirrus CI (Hennadii Stepanov)

Pull request description:

ACKs for top commit:
  hebasto:
    ACK c2f6435802
  jonasnick:
    ACK c2f6435802

Tree-SHA512: a930f2a58fdf3624d03ffd07f6db236e804100eb9d4320c943a65b5a2afb89a5da82df8e0207b87e0e8f858974af07c876c9e56495246dfd24146dfb3b10b591
2023-08-17 15:13:04 +00:00
Tim Ruffing
c2f6435802 ci: Add comment about switching macOS to M1 on GHA later 2023-08-17 16:03:54 +02:00
Hennadii Stepanov
4a24fae0bc ci: Remove "arm64: macOS Ventura" task from Cirrus CI 2023-08-17 15:56:32 +02:00
Hennadii Stepanov
b0886fd35c ci, gha: Ensure only a single workflow processes github.ref at a time 2023-08-17 14:32:43 +01:00
Jonas Nick
3d05c86d63 Merge bitcoin-core/secp256k1#1394: ci, gha: Run "x86_64: macOS Ventura" job on GitHub Actions
8e54a346d2 ci, gha: Run "x86_64: macOS Ventura" job on GitHub Actions (Hennadii Stepanov)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 8e54a346d2
  jonasnick:
    ACK 8e54a346d2

Tree-SHA512: c10f9d8d677409b37f1d8a49e580f3160a920fed78add3437184e5dabf79083b1ba6df920a233f27485630e5bbee9ff9825e908cc6fb64b0c9959c131bc9f070
2023-08-17 11:09:59 +00:00
Hennadii Stepanov
d78bec7001 ci: Remove Windows MSVC tasks from Cirrus CI
Co-authored-by: Tim Ruffing <crypto@timruffing.de>
2023-08-17 10:13:38 +01:00
Hennadii Stepanov
3545dc2b9b ci, gha: Run all MSVC tests on Windows natively 2023-08-17 10:13:28 +01:00
Tim Ruffing
5d8fa825e2 Merge bitcoin-core/secp256k1#1274: test: Silent noisy clang warnings about Valgrind code on macOS x86_64
747ada3587 test: Silent noisy clang warnings about Valgrind code on macOS x86_64 (Hennadii Stepanov)

Pull request description:

  Since #1206, on macOS x86_64 with Valgrind installed, clang emits a massive amount of `-Wreserved-identifier` and `-Wreserved-macro-identifier` warnings from the `valgrind/valgrind.h` and `valgrind/memcheck.h` headers.

  This PR prevents warnings emitted for the Valgrind code.

ACKs for top commit:
  real-or-random:
    utACK 747ada3587

Tree-SHA512: dd1b2b9db2d471939fdc30f9d8fd106a12f21ec5008ca98d8ebe3087d7ea352d564e8bbd0cec59a004e084af3a84d4680cb81f2ef6fe13cf164b7691e33f437d
2023-08-16 19:04:31 +02:00
Hennadii Stepanov
8e54a346d2 ci, gha: Run "x86_64: macOS Ventura" job on GitHub Actions 2023-08-16 16:45:21 +01:00
Tim Ruffing
b327abfcea Merge bitcoin-core/secp256k1#1402: ci: Use Homebrew's gcc in native macOS task
d62db57427 ci: Use Homebrew's gcc in native macOS task (Hennadii Stepanov)

Pull request description:

  Fixes an issue noticed in https://github.com/bitcoin-core/secp256k1/pull/1394#issuecomment-1680233151:

  > This uses the wrong GCC, namely Clang

  When `CC=gcc`:

  - on the [master](https://api.cirrus-ci.com/v1/task/5074854529990656/logs/test.log) branch:
  ```
  + gcc -v
  Apple clang version 14.0.3 (clang-1403.0.22.14.1)
  Target: arm64-apple-darwin22.5.0
  Thread model: posix
  InstalledDir: /Library/Developer/CommandLineTools/usr/bin
  ```

  - with this [PR](https://api.cirrus-ci.com/v1/task/5460539170619392/logs/test.log):
  ```
  + gcc -v
  Using built-in specs.
  COLLECT_GCC=gcc
  COLLECT_LTO_WRAPPER=/opt/homebrew/Cellar/gcc/13.1.0/bin/../libexec/gcc/aarch64-apple-darwin22/13/lto-wrapper
  Target: aarch64-apple-darwin22
  Configured with: ../configure --prefix=/opt/homebrew/opt/gcc --libdir=/opt/homebrew/opt/gcc/lib/gcc/current --disable-nls --enable-checking=release --with-gcc-major-version-only --enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-13 --with-gmp=/opt/homebrew/opt/gmp --with-mpfr=/opt/homebrew/opt/mpfr --with-mpc=/opt/homebrew/opt/libmpc --with-isl=/opt/homebrew/opt/isl --with-zstd=/opt/homebrew/opt/zstd --with-pkgversion='Homebrew GCC 13.1.0' --with-bugurl=https://github.com/Homebrew/homebrew-core/issues --with-system-zlib --build=aarch64-apple-darwin22 --with-sysroot=/Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk
  Thread model: posix
  Supported LTO compression algorithms: zlib zstd
  gcc version 13.1.0 (Homebrew GCC 13.1.0)
  ```

ACKs for top commit:
  real-or-random:
    ACK d62db57427, it works: https://cirrus-ci.com/task/6200190252613632?logs=test#L27

Tree-SHA512: 34b3aa86584fc04b57301731ebf811cd5b457cebb13e64593b8efb776aec48c1be5d2662b1af3f482d39fdb43308dafa5f4bfc18bd2cf350f0f61f0be799346e
2023-08-16 16:32:19 +02:00
Hennadii Stepanov
d62db57427 ci: Use Homebrew's gcc in native macOS task
Co-authored-by: Tim Ruffing <crypto@timruffing.de>
2023-08-16 14:39:58 +01:00
siv2r
54058d16fe field: remove secp256k1_fe_equal_var
`fe_equal_var` hits a fast path only when the inputs are unequal, which is
uncommon among its callers (public key parsing, ECDSA verify).
2023-08-16 17:39:25 +05:30
siv2r
bb4efd6404 tests: remove unwanted secp256k1_fe_normalize_weak call
It is not neccessary for the second argument in `secp256k1_fe_equal_var`
(or `secp256k1_fe_equal`) to have magnitude = 1.
Hence, removed the `secp256k1_fe_normalize_weak` call for those argument.
2023-08-16 17:38:04 +05:30
Tim Ruffing
eedd781085 Merge bitcoin-core/secp256k1#1348: tighten group magnitude limits, save normalize_weak calls in group add methods (revival of #1032)
b7c685e74a Save _normalize_weak calls in group add methods (Peter Dettman)
c83afa66e0 Tighten group magnitude limits (Peter Dettman)
173e8d061a Implement current magnitude assumptions (Peter Dettman)
49afd2f5d8 Take use of _fe_verify_magnitude in field_impl.h (Sebastian Falbesoner)
4e9661fc42 Add _fe_verify_magnitude (no-op unless VERIFY is enabled) (Peter Dettman)
690b0fc05a add missing group element invariant checks (Sebastian Falbesoner)

Pull request description:

  This PR picks up #1032 by peterdettman. It's essentially a rebase on master; the original first commit (09dbba561fdb9d57a2cc9842ce041d9ba29a6189) which introduced group verification methods has mostly been replaced by PR #1299 (commit f20266722a) and what remains now is only adding a few missing checks at some places. The remaining commits are unchanged, though some (easy-to-solve) conflicts appeared through cherry-picking. The last commit which actually removes the `normalize_weak` calls is obviously the critical one and needs the most attention for review.

ACKs for top commit:
  sipa:
    utACK b7c685e74a
  real-or-random:
    ACK b7c685e74a
  jonasnick:
    ACK b7c685e74a

Tree-SHA512: f15167eff7ef6ed971c726a4d738de9a15be95b0c947d7e38329e7b16656202b7113497d36625304e784866349f2293f6f1d8cb97df35393af9ea465a4156da3
2023-08-16 13:51:11 +02:00
Jonas Nick
b2f6712dd3 Merge bitcoin-core/secp256k1#1400: ctimetests: Use new SECP256K1_CHECKMEM macros also for ellswift
9c91ea41b1 ci: Enable ellswift module where it's missing (Tim Ruffing)
db32a24761 ctimetests: Use new SECP256K1_CHECKMEM macros also for ellswift (Tim Ruffing)

Pull request description:

ACKs for top commit:
  hebasto:
    ACK 9c91ea41b1.
  jonasnick:
    ACK 9c91ea41b1

Tree-SHA512: e918236cb38b2bb6e69f84fcfa5f550c54f0df018103627082646a8fd731c238ce68b1b85badf042f08300208015012677143a96f9b97d94065b9a00c1da7876
2023-08-16 09:32:01 +00:00
Tim Ruffing
9c91ea41b1 ci: Enable ellswift module where it's missing 2023-08-15 19:19:36 +02:00
Tim Ruffing
db32a24761 ctimetests: Use new SECP256K1_CHECKMEM macros also for ellswift 2023-08-15 19:13:09 +02:00
Jonas Nick
ce765a5b8e Merge bitcoin-core/secp256k1#1399: ci, gha: Run "SageMath prover" job on GitHub Actions
8408dfdc4c Revert "ci: Run sage prover on CI" (Hennadii Stepanov)
c8d9914fb1 ci, gha: Run "SageMath prover" job on GitHub Actions (Hennadii Stepanov)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK 8408dfdc4c
  jonasnick:
    ACK 8408dfdc4c

Tree-SHA512: 4de628b6d5535023c5351faebfd98d2bd9effe6592f14ffe0d0f7c6eeedd7426b9891da70aa3ea7fa830f0abc054f6b015af01fb6e26f50d45eb26177a7a6310
2023-08-15 11:54:27 +00:00
Hennadii Stepanov
8408dfdc4c Revert "ci: Run sage prover on CI"
This reverts commit d8d54859ed.
2023-08-14 14:28:54 +01:00
Hennadii Stepanov
c8d9914fb1 ci, gha: Run "SageMath prover" job on GitHub Actions 2023-08-14 14:28:53 +01:00
Tim Ruffing
8d2960c8e2 Merge bitcoin-core/secp256k1#1397: ci: Remove "Windows (VS 2022)" task from Cirrus CI
f1774e5ec4 ci, gha: Make MSVC job presentation more explicit (Hennadii Stepanov)
5ee039bb58 ci: Remove "Windows (VS 2022)" task from Cirrus CI (Hennadii Stepanov)

Pull request description:

  A follow-up for https://github.com/bitcoin-core/secp256k1/pull/1389.

  https://github.com/bitcoin-core/secp256k1/pull/1389#issuecomment-1671345100:
  > Or actually... hebasto Can you remove the second commit for now, if we're unsure whether this works at all.

  ---

  Second commit effect:
  - [before (master branch)](https://github.com/bitcoin-core/secp256k1/actions/runs/5809860925):
  ![image](https://github.com/bitcoin-core/secp256k1/assets/32963518/041439a5-8d1a-4740-85c3-4223e8cd9f70)

  - [after (this PR)](https://github.com/bitcoin-core/secp256k1/actions/runs/5810140851):
  ![image](https://github.com/bitcoin-core/secp256k1/assets/32963518/9e0c8f2c-1ba6-4df9-8720-542788b24da6)

ACKs for top commit:
  real-or-random:
    utACK f1774e5ec4

Tree-SHA512: ed36c5cef3ba4cf6769d480358f753ecc4a8a150103201f586b05d8d364c580ff637fe5b915918c695c8f7067c1bd7de6384eea1a12d1b8575ba5b629779ebf4
2023-08-09 16:57:53 +02:00
Hennadii Stepanov
f1774e5ec4 ci, gha: Make MSVC job presentation more explicit 2023-08-09 15:08:24 +01:00
Hennadii Stepanov
5ee039bb58 ci: Remove "Windows (VS 2022)" task from Cirrus CI 2023-08-09 14:48:11 +01:00
Tim Ruffing
96294c00fb Merge bitcoin-core/secp256k1#1389: ci: Run "Windows (VS 2022)" job on GitHub Actions
a2f7ccdecc ci: Run "Windows (VS 2022)" job on GitHub Actions (Hennadii Stepanov)

Pull request description:

  This PR solves one item in https://github.com/bitcoin-core/secp256k1/issues/1392.

  In response to upcoming [limiting free usage of Cirrus CI](https://cirrus-ci.org/blog/2023/07/17/limiting-free-usage-of-cirrus-ci/), suggesting to move (partially?) CI tasks/jobs from Cirrus CI to [GitHub Actions](https://docs.github.com/actions) (GHA).

  Here is example from my personal repo: https://github.com/hebasto/secp256k1/actions/runs/5806269046.

  For security concerns, see:
  - https://github.com/bitcoin/bitcoin/issues/28098#issuecomment-1651432106
  - https://github.com/bitcoin/bitcoin/issues/28098#issuecomment-1651688197

  I'm suggesting the repository "Actions permissions" as follows:

  ![image](https://github.com/bitcoin-core/secp256k1/assets/32963518/bd18d489-784f-48ba-b599-ed1c4dfc34fa)

  ![image](https://github.com/bitcoin-core/secp256k1/assets/32963518/632280e0-9c26-42eb-a0ed-24f9a8142faa)

  ---

  See build logs in my personal repo: https://github.com/hebasto/secp256k1/actions/runs/5692587475.

ACKs for top commit:
  real-or-random:
    utACK a2f7ccdecc

Tree-SHA512: b6329a29391146e3cdee9a56f6151b6672aa45837dfaacb708ba4209719801ed029a6928d638d314b71c7533d927d771b3eca4b9e740cfcf580a40ba07970ae4
2023-08-09 15:43:50 +02:00
Hennadii Stepanov
a2f7ccdecc ci: Run "Windows (VS 2022)" job on GitHub Actions 2023-08-09 12:54:18 +01:00
Tim Ruffing
b911b3cbd5 Merge ElementsProject/secp256k1-zkp#265: bppp: Fix test for invalid sign byte again
5bf57590bf bppp: Fix test for invalid sign byte again (Jonas Nick)

Pull request description:

  The first byte provided to secp256k1_bppp_parse_one_of_points is allowed to be 0, 1, 2, or 3 since it encodes the Y coordinate of two points. In a previous fix we wrongly assumed it can only be 2 or 3.

ACKs for top commit:
  real-or-random:
    utACK 5bf57590bf

Tree-SHA512: 4dcc83a03691b8cb0cbe39da6e34311bde518e09fb02fb8648557eba435031eaee8acef9dc762e24c7d106b935b725981dcdaadbd1a3801026ee2b7b9bc34951
2023-08-06 02:25:32 +02:00
Jonas Nick
5bf57590bf bppp: Fix test for invalid sign byte again
The first byte provided to secp256k1_bppp_parse_one_of_points is allowed to be
0, 1, 2, or 3 since it encodes the Y coordinate of two points. In a previous fix
we wrongly assumed it can only be 2 or 3.
2023-08-05 19:12:59 +00:00
Tim Ruffing
374e2b54e2 Merge bitcoin-core/secp256k1#1290: cmake: Set ENVIRONMENT property for examples on Windows
175db31149 ci: Drop no longer needed `PATH` variable update on Windows (Hennadii Stepanov)
116d2ab3df cmake: Set `ENVIRONMENT` property for examples on Windows (Hennadii Stepanov)
cef373997c cmake, refactor: Use helper function instead of interface library (Hennadii Stepanov)

Pull request description:

  This PR simplifies running examples on Windows, because the DLL must reside either in the same folder where the executable is or somewhere in PATH.

  It is an alternative to #1233.

ACKs for top commit:
  real-or-random:
    utACK 175db31149

Tree-SHA512: 8188018589a5bcf0179647a039cdafcce661dc103a70a5bb9e6b6f680b899332ba30b1e9ef5dad2a8c22c315d7794747e49d8cf2e391eebea21e3d8505ee334b
2023-08-03 15:15:03 +02:00
Jonas Nick
1b13415df9 Merge bitcoin-core/secp256k1#1391: refactor: take use of secp256k1_scalar_{zero,one} constants (part 2)
a1bd4971d6 refactor: take use of `secp256k1_scalar_{zero,one}` constants (part 2) (Sebastian Falbesoner)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK a1bd4971d6
  jonasnick:
    ACK a1bd4971d6

Tree-SHA512: 09ef6d9be1d3f9c19f8fe4614fe629de5c45197027e0e3f9dd8d4679a510a7b57f8aa499707a6daf652041f255c87316c9883bf7cf9a08bd41a3651bff54299e
2023-08-03 09:41:58 +00:00
Jonas Nick
b2ccc8d9fd Merge elementsproject/secp256k1-zkp#260: Finish sync to upstream
394e09ee84 musig: change test vector generation code shebang from python to python3 (Jonas Nick)
aa3edea119 scalar: Remove unused secp256k1_scalar_chacha20 (Tim Ruffing)
167194bede rangeproof: Use util functions for writing big endian (Tim Ruffing)
82777bba34 bppp: Fix test for invalid sign byte (Tim Ruffing)
54b37db953 build: Fix linkage of extra binaries in -zkp modules (Tim Ruffing)
9e96a2e9d8 hsort tests: Don't call secp256k1_testrand_int(0) (Tim Ruffing)
4692478853 ci: print $ELLSWIFT in cirrus.sh (Jonas Nick)
78ca880788 build: enable ellswift module via SECP_CONFIG_DEFINES (Jonas Nick)
b097a466c1 util: remove unused checked_realloc (Cory Fields)
4f8c5bd761 refactor: Drop unused cast (Hennadii Stepanov)
6ec3731e8c Simplify test PRNG implementation (Pieter Wuille)
fb5bfa4eed Add static test vector for Xoshiro256++ (Tim Ruffing)
723e8ca8f7 Remove randomness tests (Pieter Wuille)
c424e2fb43 ellswift: fix probabilistic test failure when swapping sides (Jonas Nick)
981e5be38c ci: Fix typo in comment (Tim Ruffing)
e9e9648219 ci: Reduce number of macOS tasks from 28 to 8 (Tim Ruffing)
609093b387 ci: Add x86_64 Linux tasks for gcc and clang snapshots (Tim Ruffing)
1deecaaf3b ci: Install development snapshots of gcc and clang (Tim Ruffing)
b79ba8aa4c field: Use `restrict` consistently in fe_sqrt (Tim Ruffing)
600c5adcd5 clean up in-comment Sage code (refer to secp256k1_params.sage, update to Python3) (Sebastian Falbesoner)
c7d900ffd1 doc: minor ellswift.md updates (stratospher)
2792119278 Add exhaustive test for ellswift (create+decode roundtrip) (Sebastian Falbesoner)
07c0e8b82e group: remove unneeded normalize_weak in `secp256k1_gej_eq_x_var` (Sebastian Falbesoner)
efa76c4bf7 group: remove unneeded normalize_weak in `secp256k1_ge_is_valid_var` (Sebastian Falbesoner)
c6cd2b15a0 ci: Add task for static library on Windows + CMake (Hennadii Stepanov)
020bf69a44 build: Add extensive docs on visibility issues (Tim Ruffing)
0196e8ade1 build: Introduce `SECP256k1_DLL_EXPORT` macro (Hennadii Stepanov)
9f1b1904a3 refactor: Replace `SECP256K1_API_VAR` with `SECP256K1_API` (Hennadii Stepanov)
ae9db95cea build: Introduce `SECP256K1_STATIC` macro for Windows users (Hennadii Stepanov)
b6b9834e8d small fixes (Alejandro)
5b9f37f136 ci: Add `CFLAGS: -O1` to task matrix (Hennadii Stepanov)
a6ca76cdf2 Avoid `-Wmaybe-uninitialized` when compiling with `gcc -O1` (Hennadii Stepanov)
05873bb6b1 tweak_add: fix API doc for tweak=0 (Jonas Nick)
a7bec34231 ci: Print commit in Windows container (Hennadii Stepanov)
98579e297b ci: Drop manual checkout of merge commit (Tim Ruffing)
5a95a268b9 tests: introduce helper for non-zero `random_fe_test` results (Sebastian Falbesoner)
304421d57b tests: refactor: remove duplicate function `random_field_element_test` (Sebastian Falbesoner)
be8ff3a02a field: Static-assert that int args affecting magnitude are constant (Tim Ruffing)
7d8d5c86df tests: refactor: take use of `secp256k1_ge_x_on_curve_var` (Sebastian Falbesoner)
525b661f83 bppp/build: Fix linkage of benchmark (Tim Ruffing)
4c70cc9bf5 Suppress wrong/buggy warning in MSVC <19.33 (Tim Ruffing)
579999b425 scalar: adjust muladd2 to new int128 interface (Jonas Nick)
b160486766 ecdsa_adaptor: add missing include (Jonas Nick)
c862a9fb49 ci: Adjust Docker image to Debian 12 "bookworm" (Hennadii Stepanov)
a1782098a9 ci: Force DWARF v4 for Clang when Valgrind tests are expected (Hennadii Stepanov)
8a7273465b Help the compiler prove that a loop is entered (Tim Ruffing)
67887ae65c Fix a typo in the error message (Hennadii Stepanov)
7c7467ab7f Refer to ellswift.md in API docs (Pieter Wuille)
c32ffd8d8c Add ellswift to CHANGELOG (Pieter Wuille)
bc7c8db179 abi: Use dllexport for mingw builds (Cory Fields)
5b7bf2e9d4 Use `__shiftright128` intrinsic in `secp256k1_u128_rshift` on MSVC (Hennadii Stepanov)
5779137457 field: Document return value of fe_sqrt() (Tim Ruffing)
90e360acc2 Add doc/ellswift.md with ElligatorSwift explanation (Pieter Wuille)
4f091847c2 Add ellswift testing to CI (Pieter Wuille)
1bcea8c57f Add benchmarks for ellswift module (Pieter Wuille)
2d1d41acf8 Add ctime tests for ellswift module (Pieter Wuille)
df633cdeba Add _prefix and _bip324 ellswift_xdh hash functions (Pieter Wuille)
9695deb351 Add tests for ellswift module (Pieter Wuille)
c47917bbd6 Add ellswift module implementing ElligatorSwift (Pieter Wuille)
79e5b2a8b8 Add functions to test if X coordinate is valid (Pieter Wuille)
a597a5a9ce Add benchmark for key generation (Pieter Wuille)
e449af6872 Drop no longer needed `#include "../include/secp256k1.h"` (Hennadii Stepanov)
f1652528be Normalize ge produced from secp256k1_pubkey_load (stratospher)
7067ee54b4 tests: add tests for `secp256k1_{read,write}_be64` (Sebastian Falbesoner)
740528caad scalar: use newly introduced `secp256k1_{read,write}_be64` helpers (4x64 impl.) (Sebastian Falbesoner)
887183e7de scalar: use `secp256k1_{read,write}_be32` helpers (4x64 impl.) (Sebastian Falbesoner)
52b84238de scalar: use `secp256k1_{read,write}_be32` helpers (8x32 impl.) (Sebastian Falbesoner)
f3644287b1 docs: correct `pubkey` param descriptions for `secp256k1_keypair_{xonly_,}pub` (Sebastian Falbesoner)
db29bf220c ci: Remove quirk that runs dummy command after wineserver (Tim Ruffing)
c7db4942b3 ci: Fix error D8037 in `cl.exe` (Hennadii Stepanov)
7dae115861 Revert "ci: Move wine prefix to /tmp to avoid error D8037 in cl.exe" (Hennadii Stepanov)
605e07e365 fix input range comment for `secp256k1_fe_add_int` (Sebastian Falbesoner)
ade5b36701 tests: add checks for scalar constants `secp256k1_scalar_{zero,one}` (Sebastian Falbesoner)
654246c635 refactor: take use of `secp256k1_scalar_{zero,one}` constants (Sebastian Falbesoner)
e83801f5db test: Warn if both `VERIFY` and `COVERAGE` are defined (Hennadii Stepanov)
1549db0ca5 build: Level up MSVC warnings (Hennadii Stepanov)
ad84603297 release process: clarify change log updates (Jonas Nick)
6348bc7eee release process: fix process for maintenance release (Jonas Nick)
79fa50b082 release process: mention targeted release schedule (Jonas Nick)
165206789b release process: add sanity checks (Jonas Nick)
27504d5c94 ci: Move wine prefix to /tmp to avoid error D8037 in cl.exe (Tim Ruffing)
6433175ffe Do not invoke fe_is_zero on failed set_b32_limit (Pieter Wuille)
5768b50229 build: Enable -DVERIFY for precomputation binaries (Tim Ruffing)
31b4bbee1e Make fe_cmov take max of magnitudes (Pieter Wuille)
95448ef2f8 release cleanup: bump version after 0.3.2 (Pieter Wuille)
e593ed5685 musig: ensure point_load output is normalized (Jonas Nick)
d490ca2046 release: Prepare for 0.3.2 (Tim Ruffing)
697e1ccf4a changelog: Catch up (Tim Ruffing)
76b43f3443 changelog: Add entry for #1303 (Tim Ruffing)
3ad1027a40 Revert "Remove unused scratch space from API" (Jonas Nick)
8c9ae37a5a Add release note (Pieter Wuille)
350b4bd6e6 Mark stack variables as early clobber for technical correctness (Pieter Wuille)
0c729ba70d Bugfix: mark outputs as early clobber in scalar x86_64 asm (Pieter Wuille)
c6bb29b303 build: Rename `64bit` to `x86_64` (Hennadii Stepanov)
03246457a8 autotools: Add `SECP_ARM32_ASM_CHECK` macro (Hennadii Stepanov)
ed4ba238e2 cmake: Add `check_arm32_assembly` function (Hennadii Stepanov)
e5cf4bf3ff build: Rename `arm` to `arm32` (Hennadii Stepanov)
5b32602295 Split fe_set_b32 into reducing and normalizing variants (Pieter Wuille)
1907f0f166 build: Make tests work with external default callbacks (Tim Ruffing)
cd54ac7c1c schnorrsig: Improve docs of schnorrsig_sign_custom (Tim Ruffing)
28687b0312 schnorrsig: Add BIP340 varlen test vectors (Tim Ruffing)
97a98bed1e schnorrsig: Refactor test vector code to allow varlen messages (Tim Ruffing)
17fa21733a ct: Be cautious and use volatile trick in more "conditional" paths (Tim Ruffing)
5fb336f9ce ct: Use volatile trick in scalar_cond_negate (Tim Ruffing)
712e7f8722 Remove unused scratch space from API (Jonas Nick)
d1e48e5474 refactor: Make 64-bit shift explicit (Hennadii Stepanov)
b2e29e43d0 ci: Treat all compiler warnings as errors in "Windows (VS 2022)" task (Hennadii Stepanov)
97c63b9039 Avoid normalize conditional on VERIFY (Pieter Wuille)
7fc642fa25 Simplify secp256k1_fe_{impl_,}verify (Pieter Wuille)
4e176ad5b9 Abstract out verify logic for fe_is_square_var (Pieter Wuille)
4371f98346 Abstract out verify logic for fe_add_int (Pieter Wuille)
89e324c6b9 Abstract out verify logic for fe_half (Pieter Wuille)
283cd80ab4 Abstract out verify logic for fe_get_bounds (Pieter Wuille)
d5aa2f0358 Abstract out verify logic for fe_inv{,_var} (Pieter Wuille)
3167646072 Abstract out verify logic for fe_from_storage (Pieter Wuille)
76d31e5047 Abstract out verify logic for fe_to_storage (Pieter Wuille)
1e6894bdd7 Abstract out verify logic for fe_cmov (Pieter Wuille)
be82bd8e03 Improve comments/checks for fe_sqrt (Pieter Wuille)
6ab35082ef Abstract out verify logic for fe_sqr (Pieter Wuille)
4c25f6efbd Abstract out verify logic for fe_mul (Pieter Wuille)
e179e651cb Abstract out verify logic for fe_add (Pieter Wuille)
7e7ad7ff57 Abstract out verify logic for fe_mul_int (Pieter Wuille)
65d82a3445 Abstract out verify logic for fe_negate (Pieter Wuille)
144670893e Abstract out verify logic for fe_get_b32 (Pieter Wuille)
f7a7666aeb Abstract out verify logic for fe_set_b32 (Pieter Wuille)
ce4d2093e8 Abstract out verify logic for fe_cmp_var (Pieter Wuille)
7d7d43c6dd Improve comments/check for fe_equal{,_var} (Pieter Wuille)
c5e788d672 Abstract out verify logic for fe_is_odd (Pieter Wuille)
d3f3fe8616 Abstract out verify logic for fe_is_zero (Pieter Wuille)
c701d9a471 Abstract out verify logic for fe_clear (Pieter Wuille)
19a2bfeeea Abstract out verify logic for fe_set_int (Pieter Wuille)
864f9db491 Abstract out verify logic for fe_normalizes_to_zero{,_var} (Pieter Wuille)
6c31371120 Abstract out verify logic for fe_normalize_var (Pieter Wuille)
e28b51f522 Abstract out verify logic for fe_normalize_weak (Pieter Wuille)
b6b6f9cb97 Abstract out verify logic for fe_normalize (Pieter Wuille)
7fa5195559 Bugfix: correct SECP256K1_FE_CONST mag/norm fields (Pieter Wuille)
b29566c51b Merge magnitude/normalized fields, move/improve comments (Pieter Wuille)
bbc834467c Avoid secp256k1_ge_set_gej_zinv with uninitialized z (Pieter Wuille)
0a2e0b2ae4 Make secp256k1_{fe,ge,gej}_verify work as no-op if non-VERIFY (Pieter Wuille)
f20266722a Add invariant checking to group elements (Pieter Wuille)
a18821d5b1 Always initialize output coordinates in secp256k1_ge_set_gej (Pieter Wuille)
3086cb90ac Expose secp256k1_fe_verify to other modules (Pieter Wuille)
a0e696fd4d Make secp256k1_ecmult_const handle infinity (Gregory Maxwell)
2e65f1fdbc Avoid using bench_verify_data as bench_sign_data; merge them (Pieter Wuille)
149c41cee1 docs: complete interface description for `secp256k1_schnorrsig_sign_custom` (Sebastian Falbesoner)
bef448f9af cmake: Fix library ABI versioning (Hennadii Stepanov)
755629bc03 cmake: Use full signature of `add_test()` command (Hennadii Stepanov)
7e977b3c50 autotools: Take VPATH builds into account when generating testvectors (Tim Ruffing)
2418d3260a autotools: Create src/wycheproof dir before creating file in it (Tim Ruffing)
8764034ed5 autotools: Make all "pregenerated" targets .PHONY (Tim Ruffing)
e1b9ce8811 autotools: Use same conventions for all pregenerated files (Tim Ruffing)
08f4b1632d autotools: Move code around to tidy Makefile (Tim Ruffing)
529b54d922 autotools: Move Wycheproof header from EXTRA_DIST to noinst_HEADERS (Tim Ruffing)
71f746c057 cmake: Include `include` directory for subtree builds (Hennadii Stepanov)
5431b9decd cmake: Make `SECP256K1_INSTALL` default depend on `PROJECT_IS_TOP_LEVEL` (Hennadii Stepanov)
162608cc98 cmake: Emulate `PROJECT_IS_TOP_LEVEL` for CMake<3.21 (Hennadii Stepanov)
a8d059f76c cmake, doc: Document compiler flags (Hennadii Stepanov)
6ece1507cb cmake, refactor: Rename `try_add_compile_option` to `try_append_cflags` (Hennadii Stepanov)
19516ed3e9 cmake: Use `add_compile_options()` in `try_add_compile_option()` (Hennadii Stepanov)
a273d74b2e cmake: Improve version comparison (Hennadii Stepanov)
6a58b483ef cmake: Use `if(... IN_LIST ...)` command (Hennadii Stepanov)
2445808c02 cmake: Use dedicated `GENERATOR_IS_MULTI_CONFIG` property (Hennadii Stepanov)
9f8703ef17 cmake: Use dedicated `CMAKE_HOST_APPLE` variable (Hennadii Stepanov)
8c2017035a cmake: Use recommended `add_compile_definitions` command (Hennadii Stepanov)
04d4cc071a cmake: Add `DESCRIPTION` and `HOMEPAGE_URL` options to `project` command (Hennadii Stepanov)
8a8b6536ef cmake: Use `SameMinorVersion` compatibility mode (Hennadii Stepanov)
ce5ba9e24d gitignore: Add CMakeUserPresets.json (Tim Ruffing)
0a446a312f cmake: Add dev-mode CMake preset (Tim Ruffing)
dc0657c762 build: Fix C4005 "macro redefinition" MSVC warnings in examples (Hennadii Stepanov)
c4062d6b5d debug: move helper for printing buffers into util.h (Jonas Nick)
3858bad2c6 tests: remove extra semicolon in macro (Jonas Nick)
162da73e9a tests: Add debug helper for printing buffers (Tim Ruffing)
e9fd3dff76 field: Improve docs and tests of secp256k1_fe_set_b32 (Tim Ruffing)
ca92a35d01 field: Simplify code in secp256k1_fe_set_b32 (Tim Ruffing)
d93f62e369 field: Verify field element even after secp256k1_fe_set_b32 fails (Tim Ruffing)
69e1ec0331 Get rid of secp256k1_fe_const_b (Pieter Wuille)
68b16a1662 bench: Make sys/time.h a system include (Tim Ruffing)
8e142ca410 Move `SECP256K1_INLINE` macro definition out from `include/secp256k1.h` (Hennadii Stepanov)
77445898a5 Remove `SECP256K1_INLINE` usage from examples (Hennadii Stepanov)
47ac3d63cd cmake: Make installation optional (Anna “CyberTailor”)
1ecb94ebe9 build: Make `SECP_VALGRIND_CHECK` preserve `CPPFLAGS` (Hennadii Stepanov)
35ada3b954 tests: lint wycheproof's python script (RandomLattice)
ef49a11d29 build: allow static or shared but not both (Cory Fields)
36b0adf1b9 build: remove warning until it's reproducible (Cory Fields)
a575339c02 Remove bits argument from secp256k1_wnaf_const (always 256) (Pieter Wuille)
1b6fb5593c doc: clarify process for patch releases (Jonas Nick)
06c67dea9f autotools: Don't regenerate Wycheproof header automatically (Tim Ruffing)
656c6ea8d8 release cleanup: bump version after 0.3.1 (Jonas Nick)
6a37b2a5ea changelog: Fix link (Tim Ruffing)
898e1c676e release: Prepare for 0.3.1 (Tim Ruffing)
1d9a13fc26 changelog: Remove inconsistent newlines (Tim Ruffing)
0e091669a1 changelog: Catch up in preparation of 0.3.1 (Tim Ruffing)
e5de454609 tests: Add Wycheproof ECDSA vectors (RandomLattice)
0f8642079b Add exhaustive tests for ecmult_const_xonly (Pieter Wuille)
4485926ace Add x-only ecmult_const version for x=n/d (Pieter Wuille)
3d1f430f9f Make position of * in pointer declarations in include/ consistent (Jonas Nick)
0c07c82834 Add CMake instructions to release process (Tim Ruffing)
4a496a36fb ct: Use volatile "trick" in all fe/scalar cmov implementations (Tim Ruffing)
3addb4c1e8 build: Improve `SECP_TRY_APPEND_DEFAULT_CFLAGS` macro (Hennadii Stepanov)
5bb03c2911 Replace `SECP256K1_ECMULT_TABLE_VERIFY` macro by a function (Hennadii Stepanov)
4429a8c218 Suppress `-Wunused-parameter` when building for coverage analysis (Hennadii Stepanov)
3e43041be6 No need to subtract 1 before doing a right shift (roconnor-blockstream)
fd2a408647 Set ARM ASM symbol visibility to `hidden` (Hennadii Stepanov)
4ebd82852d Apply Checks only in VERIFY mode. (roconnor-blockstream)
d1e7ca192d Typo (roconnor-blockstream)
96dd062511 build: bump CMake minimum requirement to 3.13 (Cory Fields)
8e79c7ed11 build: Ensure no optimization when building for coverage analysis (Hennadii Stepanov)
647f0a5cb1 Update comment for secp256k1_modinv32_inv256 (roconnor-blockstream)
28e63f7ea7 release cleanup: bump version after 0.3.0 (Jonas Nick)
b40adf2360 release: prepare for 0.3.0 (Jonas Nick)
8be82d4362 cmake: Rename project to "libsecp256k1" (Hennadii Stepanov)
756b61d451 readme: Use correct build type in CMake/Windows build instructions (Tim Ruffing)
92098d84cf changelog: Add entry for CMake (Tim Ruffing)
e1eb33724c ci: Add "x86_64: Windows (VS 2022)" task (Hennadii Stepanov)
10602b0030 cmake: Export config files (Hennadii Stepanov)
5468d70964 build: Add CMake-based build system (Hennadii Stepanov)
5d8f53e312 Remove redudent checks. (Russell O'Connor)
d232112fa7 Update Changelog (Tim Ruffing)
b081f7e4cb Add secp256k1_fe_add_int function (Pieter Wuille)
2ef1c9b387 Update overflow check (Russell O'Connor)
5660c13755 prevent optimization in algorithms (Harshil Jani)
ce3cfc78a6 doc: Describe Jacobi calculation in safegcd_implementation.md (Elliott Jin)
6be01036c8 Add secp256k1_fe_is_square_var function (Pieter Wuille)
1de2a01c2b Native jacobi symbol algorithm (Pieter Wuille)
04c6c1b181 Make secp256k1_modinv64_det_check_pow2 support abs val (Pieter Wuille)
5fffb2c7af Make secp256k1_i128_check_pow2 support -(2^n) (Pieter Wuille)
e4330341bd ci: Shutdown wineserver whenever CI script exits (Tim Ruffing)
9a5a611a21 build: Suppress stupid MSVC linker warning (Tim Ruffing)
739c53b19a examples: Extend sig examples by call that uses static context (Tim Ruffing)
914276e4d2 build: Add SECP256K1_API_VAR to fix importing variables from DLLs (Tim Ruffing)
e089eecc1e group: Further simply gej_add_ge (Tim Ruffing)
ac71020ebe group: Save a normalize_to_zero in gej_add_ge (Tim Ruffing)
8c7e0fc1de build: Add -Wreserved-identifier supported by clang (Tim Ruffing)
9b60e3148d ci: Do not set git's `user.{email,name}` config options (Hennadii Stepanov)
ef39721ccc Do not link `bench` and `ctime_tests` to `COMMON_LIB` (Hennadii Stepanov)
c2415866c7 ci: Don't fetch git history (Tim Ruffing)
0ecf318851 ci: Use remote pull/merge ref instead of local git merge (Tim Ruffing)
9b7d18669d Drop no longer used Autoheader macros (Hennadii Stepanov)
eb6bebaee3 scalar: restrict split_lambda args, improve doc and VERIFY_CHECKs (Jonas Nick)
7f49aa7f2d ci: add test job with -DVERIFY (Jonas Nick)
620ba3d74b benchmarks: fix bench_scalar_split (Jonas Nick)
e39d954f11 tests: Add CHECK_ILLEGAL(_VOID) macros and use in static ctx tests (Tim Ruffing)
61841fc9ee contexts: Forbid randomizing secp256k1_context_static (Tim Ruffing)
4b6df5e33e contexts: Forbid cloning/destroying secp256k1_context_static (Tim Ruffing)
8f51229e03 ctime_tests: improve output when CHECKMEM_RUNNING is not defined (Jonas Nick)
2cd4e3c0a9 Drop no longer used `SECP_{LIBS,INCLUDE}` variables (Hennadii Stepanov)
613626f94c Drop no longer used `SECP_TEST_{LIBS,INCLUDE}` variables (Hennadii Stepanov)
d6ff738d5b Ensure safety of ctz_debruijn implementation. (Russell O'Connor)
ce60785b26 Introduce SECP256K1_B macro for curve b coefficient (Pieter Wuille)
4934aa7995 Switch to exhaustive groups with small B coefficient (Pieter Wuille)
e03ef86559 Make all non-API functions (except main) static (Pieter Wuille)
0f088ec112 Rename CTIMETEST -> CTIMETESTS (Pieter Wuille)
74b026f05d Add runtime checking for DECLASSIFY flag (Pieter Wuille)
5e2e6fcfc0 Run ctime test in Linux MSan CI job (Pieter Wuille)
18974061a3 Make ctime tests building configurable (Pieter Wuille)
5048be17e9 Rename valgrind_ctime_test -> ctime_tests (Pieter Wuille)
6eed6c18de Update error messages to suggest msan as well (Pieter Wuille)
8e11f89a68 Add support for msan integration to checkmem.h (Pieter Wuille)
8dc64079eb Add compile-time error to valgrind_ctime_test (Pieter Wuille)
0db05a770e Abstract interactions with valgrind behind new checkmem.h (Pieter Wuille)
4f1a54e41d Move valgrind CPPFLAGS into SECP_CONFIG_DEFINES (Pieter Wuille)
d4a6b58df7 Add `noverify_tests` to `.gitignore` (Hennadii Stepanov)
e862c4af0c Makefile: add -I$(top_srcdir)/src to CPPFLAGS for precomputed (Matt Whitlock)
9a93f48f50 refactor: Rename STTC to STATIC_CTX in tests (Tim Ruffing)
3385a2648d refactor: Rename global variables to uppercase in tests (Tim Ruffing)
203760023c tests: Add noverify_tests which is like tests but without VERIFY (Tim Ruffing)
39e8f0e3d7 refactor: Separate run_context_tests into static vs proper contexts (Tim Ruffing)
a4a09379b1 tests: Clean up and improve run_context_tests() further (Tim Ruffing)
fc90bb5695 refactor: Tidy up main() (Tim Ruffing)
f32a36f620 tests: Don't use global context for context tests (Tim Ruffing)
ce4f936c4f tests: Tidy run_context_tests() by extracting functions (Tim Ruffing)
18e0db30cb tests: Don't recreate global context in scratch space test (Tim Ruffing)
b19806122e tests: Use global copy of secp256k1_context_static instead of clone (Tim Ruffing)
2f9ca284e2 Drop `SECP_CONFIG_DEFINES` from examples (Hennadii Stepanov)
c0a555b2ae Bugfix: pass SECP_CONFIG_DEFINES to bench compilation (Pieter Wuille)
d216475205 test secp256k1_i128_to_i64 (Russell O'Connor)
4bc429019d Add a secp256k1_i128_to_u64 function. (Russell O'Connor)
a49e0940ad docs: Fix typo (Tim Ruffing)
2551cdac90 tests: Fix code formatting (Tim Ruffing)
c635c1bfd5 Change ARG_CHECK_NO_RETURN to ARG_CHECK_VOID which returns (void) (Tim Ruffing)
cf66f2357c refactor: Add helper function secp256k1_context_is_proper() (Tim Ruffing)
c30b889f17 Clarify that the ABI-incompatible versions are earlier (Pieter Wuille)
881fc33d0c Consistency in naming of modules (Pieter Wuille)
9ecf8149a1 Reduce font size in changelog (Pieter Wuille)
2dc133a67f Add more changelog entries (Pieter Wuille)
ac233e181a Add links to diffs to changelog (Pieter Wuille)
cee8223ef6 Mention semantic versioning in changelog (Pieter Wuille)
9c5a4d21bb Do not define unused `HAVE_VALGRIND` macro (Hennadii Stepanov)
ad8647f548 Drop no longer relevant files from `.gitignore` (Hennadii Stepanov)
b627ba7050 Remove dependency on `src/libsecp256k1-config.h` (Hennadii Stepanov)
7a74688201 ci: add missing CFLAGS & CPPFLAGS variable to print_environment (Jonas Nick)
c2e0fdadeb ci: set -u in cirrus.sh to treat unset variables as an error (Jonas Nick)
02ebc290f7 release cleanup: bump version after 0.2.0 (Jonas Nick)
b6b360efaf doc: improve message of cleanup commit (Jonas Nick)
e025ccdf74 release: prepare for initial release 0.2.0 (Jonas Nick)
6d1784a2e2 build: add missing files to EXTRA_DIST (Jonas Nick)
13bf1b6b32 changelog: make order of change types match keepachangelog.com (Jonas Nick)
b1f992a552 doc: improve release process (Jonas Nick)
ad39e2dc41 build: change package version to 0.1.0-dev (Jonas Nick)
90618e9263 doc: move CHANGELOG from doc/ to root directory (Jonas Nick)
7e5b22684f Don't use compute credits for now (Pieter Wuille)
d6dc0f4ae3 tests: Switch to NONE contexts in module tests (Jonas Nick)
0c8a5caddd tests: Switch to NONE contexts in tests.c (Jonas Nick)
86540e9e1f tests: add test for deprecated flags and rm them from run_context (Jonas Nick)
caa0ad631e group: add gej_eq_var (Jonas Nick)
37ba744f5b tests: Switch to NONE contexts in exhaustive and ctime tests (Jonas Nick)
8d7a9a8eda benchmarks: Switch to NONE contexts (Jonas Nick)
4386a2306c examples: Switch to NONE contexts (Tim Ruffing)
7289b51d31 docs: Use doxygen style if and only if comment is user-facing (Tim Ruffing)
e7d0185c90 docs: Get rid of "initialized for signing" terminology (Tim Ruffing)
06126364ad docs: Tidy and improve docs about contexts and randomization (Tim Ruffing)
e02d6862bd selftest: Expose in public API (Tim Ruffing)
e383fbfa66 selftest: Rename internal function to make name available for API (Tim Ruffing)
d2c6d48de3 tests: Use new name of static context (Tim Ruffing)
53796d2b24 contexts: Rename static context (Tim Ruffing)
72fedf8a6c docs: Improve docs for static context (Tim Ruffing)
316ac7625a contexts: Deprecate all context flags except SECP256K1_CONTEXT_NONE (Tim Ruffing)
1a553ee8be docs: Change signature "validation" to "verification" (Tim Ruffing)
ee7341fbac docs: Never require a verification context (Tim Ruffing)
092be61c5e gitignore: Add *.sage.py files autogenerated by sage (Tim Ruffing)
a8494b02bf Use compute credits for macOS jobs (Pieter Wuille)
c0ae48c995 Update macOS image for CI (Pieter Wuille)
41e8704b48 build: Enable some modules by default (Tim Ruffing)
99bd335599 Make int128 overflow test use secp256k1_[ui]128_mul (Pieter Wuille)
3afce0af7c Avoid signed overflow in MSVC AMR64 secp256k1_mul128 (Pieter Wuille)
9b5f589d30 Heuristically decide whether to use int128_struct (Pieter Wuille)
63ff064d2f int128: Add test override for testing __(u)mulh on MSVC X64 (Tim Ruffing)
f2b7e88768 Add int128 randomized tests (Pieter Wuille)
00a42b91b3 Add MSan CI job (Pieter Wuille)
a340d9500a ci: add int128_struct tests (Jonas Nick)
dceaa1f579 int128: Tidy #includes of int128.h and int128_impl.h (Tim Ruffing)
2914bccbc0 Simulated int128 type. (Russell O'Connor)
6a965b6b98 Remove usage of CHECK from non-test file (Tobin C. Harding)
4e54c03153 ci: print env to allow reproducing the job outside of CI (Jonas Nick)
49ae843592 ci: mostly prevent "-v/--version: not found" irrelevant error (Jonas Nick)
5c9f1a5c37 ci: always cat all logs_snippets (Jonas Nick)
f5039cb66c Cleanup `.gitignore` file (Hennadii Stepanov)
798727ae1e Revert "Add test logs to gitignore" (Hennadii Stepanov)
88b00897e7 readme: Fix line break (Tim Ruffing)
78f5296da4 readme: Sell "no runtime dependencies" (Tim Ruffing)
ef48f088ad readme: Add IRC channel (Tim Ruffing)
cabe085bb4 configure: Remove pkgconfig macros again (reintroduced by mismerge) (Tim Ruffing)
c27ae45144 config: Remove basic-config.h (Tim Ruffing)
da6514a04a config: Introduce DEBUG_CONFIG macro for debug output of config (Tim Ruffing)
d0cf55e13a config: Set preprocessor defaults for ECMULT_* config values (Tim Ruffing)
17065f48ae tests: Randomize the context with probability 15/16 instead of 1/4 (Tim Ruffing)
55f8bc99dc ecmult_gen: Improve comments about projective blinding (Tim Ruffing)
7a86955800 ecmult_gen: Simplify code (no observable change) (Tim Ruffing)
4cc0b1b669 ecmult_gen: Skip RNG when creating blinding if no seed is available (Tim Ruffing)
40a3473a9d build: Fix #include "..." paths to get rid of further -I arguments (Tim Ruffing)
069aba8125 Fix sepc256k1 -> secp256k1 typo in group.h (henopied)
1827c9bf2b scratch_destroy: move VERIFY_CHECK after invalid scrach space check (siv2r)
49e2acd927 configure: Improve rationale for WERROR_CFLAGS (Tim Ruffing)
8dc4b03341 ci: Add a C++ job that compiles the public headers without -fpermissive (Tim Ruffing)
51f296a46c ci: Run persistent wineserver to speed up wine (Tim Ruffing)
3fb3269c22 ci: Add 32-bit MinGW64 build (Tim Ruffing)
9efc2e5221 ci: Add MSVC builds (Tim Ruffing)
2be6ba0fed configure: Convince autotools to work with MSVC's archiver lib.exe (Tim Ruffing)
bd81f4140a schnorrsig bench: Suppress a stupid warning in MSVC (Tim Ruffing)
09f3d71c51 configure: Add a few CFLAGS for MSVC (Tim Ruffing)
3b4f3d0d46 build: Reject C++ compilers in the preprocessor (Tim Ruffing)
1cc0941414 configure: Don't abort if the compiler does not define __STDC__ (Tim Ruffing)
cca8cbbac8 configure: Output message when checking for valgrind (Tim Ruffing)
1a6be5745f bench: Make benchmarks compile on MSVC (Tim Ruffing)
6f6cab9989 abi: Don't export symbols in static Windows libraries (Cory Fields)
7efc9835a9 Fix the false positive of `SECP_64BIT_ASM_CHECK` (Sprite)
2f984ffc45 Save negations in var-time group addition (Peter Dettman)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 395e65e9f1

Tree-SHA512: 95feaf60c5fc8c8cafde8796c50b4b9dfcae87ece3be90286278243a629bcfd91fc4ffdc707a6cc5969fbaf9cd8ea490aa34ca724462b77cd542ebcd7f013eb9
2023-08-01 14:32:30 +00:00
Tim Ruffing
395e65e9f1 Merge branch 'master' into sync-upstream 2023-08-01 11:00:23 +02:00
Jonas Nick
394e09ee84 musig: change test vector generation code shebang from python to python3 2023-08-01 10:53:56 +02:00
Tim Ruffing
aa3edea119 scalar: Remove unused secp256k1_scalar_chacha20
Unused since a11250330b.
2023-08-01 10:50:10 +02:00
Tim Ruffing
167194bede rangeproof: Use util functions for writing big endian 2023-08-01 10:48:34 +02:00
Sebastian Falbesoner
a1bd4971d6 refactor: take use of secp256k1_scalar_{zero,one} constants (part 2) 2023-08-01 02:40:21 +02:00
Peter Dettman
b7c685e74a Save _normalize_weak calls in group add methods
Also update the operations count comments in each of the affected
functions accordingly and remove a redundant VERIFY_CHECK in
secp256k1_gej_add_ge (the infinity value range check [0,1] is already
covered by secp256k1_gej_verify above).

Co-authored-by: Sebastian Falbesoner <sebastian.falbesoner@gmail.com>
Co-authored-by: Tim Ruffing <crypto@timruffing.de>
Co-authored-by: Jonas Nick <jonasd.nick@gmail.com>
2023-07-29 01:10:21 +02:00
Tim Ruffing
82777bba34 bppp: Fix test for invalid sign byte
The test is supposed to create an invalid sign byte. Before this PR,
the generated sign byte could in fact be valid due to an overflow.

Co-authored-by: Jonas Nick <jonasd.nick@gmail.com>
2023-07-28 14:20:44 +02:00
Tim Ruffing
54b37db953 build: Fix linkage of extra binaries in -zkp modules 2023-07-28 14:20:42 +02:00
Peter Dettman
c83afa66e0 Tighten group magnitude limits
- adjust test methods that randomize magnitudes

Co-authored-by: Sebastian Falbesoner <sebastian.falbesoner@gmail.com>
Co-authored-by: Jonas Nick <jonasd.nick@gmail.com>
2023-07-28 13:05:04 +02:00
Tim Ruffing
9e96a2e9d8 hsort tests: Don't call secp256k1_testrand_int(0) 2023-07-28 10:52:25 +02:00
Jonas Nick
80187089ff Merge commits '4494a369 3aef6ab8 0fa84f86 249c81ea 7966aee3 fb758fe8 3fc1de5c 0aacf643 9e6d1b0e 332af315 afd7eb4a c9ebca95 cc557575 0f7657d5 907a6721 b40e2d30 c545fdc3 2bd5f3e6 0e00fc7d c734c642 26392da2 ' into temp-merge-1386 2023-07-27 18:57:30 +00:00
Jonas Nick
50e20fa7d4 Merge elementsproject/secp256k1-zkp#257: Upstream PRs 1314, 1317, 1318, 1316, 1327, 1310, 1328, 1333, 1330, 1334, 1337, 1341, 1339, 1350, 1349, 1338, 1129, 1347, 1336, 1295, 1354, 1355, 1356
525b661f83 bppp/build: Fix linkage of benchmark (Tim Ruffing)
4c70cc9bf5 Suppress wrong/buggy warning in MSVC <19.33 (Tim Ruffing)
579999b425 scalar: adjust muladd2 to new int128 interface (Jonas Nick)
b160486766 ecdsa_adaptor: add missing include (Jonas Nick)
c862a9fb49 ci: Adjust Docker image to Debian 12 "bookworm" (Hennadii Stepanov)
a1782098a9 ci: Force DWARF v4 for Clang when Valgrind tests are expected (Hennadii Stepanov)
8a7273465b Help the compiler prove that a loop is entered (Tim Ruffing)
67887ae65c Fix a typo in the error message (Hennadii Stepanov)
7c7467ab7f Refer to ellswift.md in API docs (Pieter Wuille)
c32ffd8d8c Add ellswift to CHANGELOG (Pieter Wuille)
bc7c8db179 abi: Use dllexport for mingw builds (Cory Fields)
5b7bf2e9d4 Use `__shiftright128` intrinsic in `secp256k1_u128_rshift` on MSVC (Hennadii Stepanov)
5779137457 field: Document return value of fe_sqrt() (Tim Ruffing)
90e360acc2 Add doc/ellswift.md with ElligatorSwift explanation (Pieter Wuille)
4f091847c2 Add ellswift testing to CI (Pieter Wuille)
1bcea8c57f Add benchmarks for ellswift module (Pieter Wuille)
2d1d41acf8 Add ctime tests for ellswift module (Pieter Wuille)
df633cdeba Add _prefix and _bip324 ellswift_xdh hash functions (Pieter Wuille)
9695deb351 Add tests for ellswift module (Pieter Wuille)
c47917bbd6 Add ellswift module implementing ElligatorSwift (Pieter Wuille)
79e5b2a8b8 Add functions to test if X coordinate is valid (Pieter Wuille)
a597a5a9ce Add benchmark for key generation (Pieter Wuille)
e449af6872 Drop no longer needed `#include "../include/secp256k1.h"` (Hennadii Stepanov)
f1652528be Normalize ge produced from secp256k1_pubkey_load (stratospher)
7067ee54b4 tests: add tests for `secp256k1_{read,write}_be64` (Sebastian Falbesoner)
740528caad scalar: use newly introduced `secp256k1_{read,write}_be64` helpers (4x64 impl.) (Sebastian Falbesoner)
887183e7de scalar: use `secp256k1_{read,write}_be32` helpers (4x64 impl.) (Sebastian Falbesoner)
52b84238de scalar: use `secp256k1_{read,write}_be32` helpers (8x32 impl.) (Sebastian Falbesoner)
f3644287b1 docs: correct `pubkey` param descriptions for `secp256k1_keypair_{xonly_,}pub` (Sebastian Falbesoner)
db29bf220c ci: Remove quirk that runs dummy command after wineserver (Tim Ruffing)
c7db4942b3 ci: Fix error D8037 in `cl.exe` (Hennadii Stepanov)
7dae115861 Revert "ci: Move wine prefix to /tmp to avoid error D8037 in cl.exe" (Hennadii Stepanov)
605e07e365 fix input range comment for `secp256k1_fe_add_int` (Sebastian Falbesoner)
ade5b36701 tests: add checks for scalar constants `secp256k1_scalar_{zero,one}` (Sebastian Falbesoner)
654246c635 refactor: take use of `secp256k1_scalar_{zero,one}` constants (Sebastian Falbesoner)
e83801f5db test: Warn if both `VERIFY` and `COVERAGE` are defined (Hennadii Stepanov)
1549db0ca5 build: Level up MSVC warnings (Hennadii Stepanov)
ad84603297 release process: clarify change log updates (Jonas Nick)
6348bc7eee release process: fix process for maintenance release (Jonas Nick)
79fa50b082 release process: mention targeted release schedule (Jonas Nick)
165206789b release process: add sanity checks (Jonas Nick)
27504d5c94 ci: Move wine prefix to /tmp to avoid error D8037 in cl.exe (Tim Ruffing)
6433175ffe Do not invoke fe_is_zero on failed set_b32_limit (Pieter Wuille)
5768b50229 build: Enable -DVERIFY for precomputation binaries (Tim Ruffing)
31b4bbee1e Make fe_cmov take max of magnitudes (Pieter Wuille)
95448ef2f8 release cleanup: bump version after 0.3.2 (Pieter Wuille)

Pull request description:

ACKs for top commit:
  real-or-random:
    tACK 525b661f83

Tree-SHA512: edee04b48ebcede0ad48b165b18a7542b48d6e5d9db034154682fa89bf76ec90569f8073cff8ce57f8abb016671604bcdec58a3a0c1aade911e62dcb63d4acd1
2023-07-27 18:40:29 +00:00
Tim Ruffing
525b661f83 bppp/build: Fix linkage of benchmark 2023-07-27 16:31:40 +00:00
Tim Ruffing
4c70cc9bf5 Suppress wrong/buggy warning in MSVC <19.33
For background, see:
https://developercommunity.visualstudio.com/t/c-compiler-incorrect-propagation-of-const-qualifie/390711
2023-07-27 16:31:40 +00:00
Jonas Nick
579999b425 scalar: adjust muladd2 to new int128 interface 2023-07-27 16:31:40 +00:00
Jonas Nick
b160486766 ecdsa_adaptor: add missing include 2023-07-27 16:31:40 +00:00
Jonas Nick
74d9073414 Merge commits '83186db3 e9e4526a 5f7903c7 d373a721 09df0bfb 20a5da5f 908e02d5 d75dc59b debf3e5c bf29f8d0 60556c9f cb1a5927 67214f5f 45c5ca76 30574f22 0702ecb0 705ce7ed 3c1a0fd3 10836832 926dd3e9 ac43613d fd491ea1 799f4eec ' into temp-merge-1356 2023-07-27 16:31:40 +00:00
Tim Ruffing
26392da2fb Merge bitcoin-core/secp256k1#1386: ci: print $ELLSWIFT in cirrus.sh
4692478853 ci: print $ELLSWIFT in cirrus.sh (Jonas Nick)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 4692478853

Tree-SHA512: 84c6021e2135857541def6ba058d9c9a1c180fd32a625854ff82d51d0561a4dd243623d38d335aeaf40200501581c0678878a9166f4a96ae3fb32717b8d39fbd
2023-07-27 15:05:29 +02:00
stratospher
d23da6d557 use secp256k1_scalar_verify checks 2023-07-27 17:35:50 +05:30
Jonas Nick
4692478853 ci: print $ELLSWIFT in cirrus.sh 2023-07-27 10:20:50 +00:00
stratospher
c7d0454932 add verification for scalars
secp256k1_scalar_verify checks that scalars are reduced mod the
group order
2023-07-27 14:03:59 +05:30
Tim Ruffing
c734c64278 Merge bitcoin-core/secp256k1#1384: build: enable ellswift module via SECP_CONFIG_DEFINES
78ca880788 build: enable ellswift module via SECP_CONFIG_DEFINES (Jonas Nick)

Pull request description:

  ...like the other modules.

ACKs for top commit:
  sipa:
    utACK 78ca880788
  real-or-random:
    utACK 78ca880788

Tree-SHA512: c157a1ed912b9aa1a318aa0a70859a3ac67cb22303993f08ff00ed601e6ac197380dd503d3b361cbc4e698fc6489b5283b782f570f2703809d23668f3ebe5ba6
2023-07-27 09:21:00 +02:00
stratospher
ad152151b0 update max scalar in scalar_cmov_test and fix schnorrsig_verify exhaustive test
- `secp256k1_scalar_set_int` in scalar_low uses input mod EXHAUSTIVE_TEST_ORDER
- directly store s in sig64 without reducing it mod the group order for testing
2023-07-27 11:59:33 +05:30
Jonas Nick
78ca880788 build: enable ellswift module via SECP_CONFIG_DEFINES
...like the other modules.
2023-07-26 14:44:20 +00:00
Tim Ruffing
0e00fc7d10 Merge bitcoin-core/secp256k1#1383: util: remove unused checked_realloc
b097a466c1 util: remove unused checked_realloc (Cory Fields)

Pull request description:

  Usage was removed in 6fe50439 . This should be a NOOP.

  Noticed when analyzing for zenbleed exposure: stdlib calls that aren't optimized away.

  In this case realloc isn't making it into the final binary, but as far as I can tell this is completely dead code and should be dropped.

ACKs for top commit:
  jonasnick:
    ACK b097a466c1
  real-or-random:
    ACK b097a466c1

Tree-SHA512: d4249215eddd4035be2b50a8bb48b8a681abdab4ab41ca53f6c2a2507edfbc9ffa39ba22eb48e7da52f978e224198294495ce64f9d571d98c19283b20b82a63a
2023-07-26 13:50:23 +02:00
Cory Fields
b097a466c1 util: remove unused checked_realloc
Usage was removed in 6fe50439 .
2023-07-25 20:37:46 +00:00
Jonas Nick
e593ed5685 musig: ensure point_load output is normalized
This is similar to the upstream commit "Normalize ge produced from
secp256k1_pubkey_load".
2023-07-25 07:28:33 +00:00
Jonas Nick
7a07f3d33f Merge commits '3bab71cf 4258c54f 566faa17 9ce9984f 04bf3f67 5be353d6 2e035af2 5b0444a3 a6f4bcf6 5ec1333d f6bef03c 1f33bb2b 1c895367 6b7e5b71 596b336f 4b84f4bf 024a4094 222ecaf6 4b0f711d 3c818388 f30c7486 1cf15ebd 24c768ae 341cc197 c63ec88e 54d34b6c 073d98a0 9eb6934f ab5a9171 fb3a8063 006ddc1f 3353d3c7 b54a0672 7d4f86d2 e8295d07 3e3d125b acf5c55a ' into temp-merge-1312 2023-07-24 20:15:07 +00:00
Jonas Nick
2bd5f3e618 Merge bitcoin-core/secp256k1#1382: refactor: Drop unused cast
4f8c5bd761 refactor: Drop unused cast (Hennadii Stepanov)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK 4f8c5bd761
  jonasnick:
    ACK 4f8c5bd761

Tree-SHA512: cc94b524f53e393bd843383e92bbc5b84dd7557d8121241f2d0461b960a0706236147d02b6f5bfc433272849f517c62eb6f1e0cfae892e1b8054817c27365430
2023-07-24 19:07:54 +00:00
Jonas Nick
a9a5c24de2 Merge commits '56582094 427bc3cd 0cf2fb91 9c8c4f44 70be3cad f16a709f 464a9115 1d8f3675 afd8b23b 2bca0a5c 2d51a454 4e682626 a0f4644f 145078c4 7b7503da ec98fced 346a053d ' into temp-merge-1269 2023-07-24 13:46:43 +00:00
Hennadii Stepanov
4f8c5bd761 refactor: Drop unused cast 2023-07-24 13:14:23 +01:00
Tim Ruffing
bfeae121fb Merge ElementsProject/secp256k1-zkp#255: musig: change test vector generation code shebang from python to python3
ea478beec6 musig: change test vector generation code shebang from python to python3 (Jonas Nick)

Pull request description:

  The linter included in the Bitcoin Core and Elements test framework requires python3.

ACKs for top commit:
  real-or-random:
    utACK ea478beec6

Tree-SHA512: 0174e9d72529d1aa2c7a0542bc49a21af9163715961fa042da39c9bb857259f4c7e2b9be8e30b77c7b9b420574bd15f76308d807e22bdc590a91d249cca5ae86
2023-07-23 08:30:06 +02:00
Jonas Nick
ea478beec6 musig: change test vector generation code shebang from python to python3 2023-07-22 18:10:55 +00:00
Peter Dettman
173e8d061a Implement current magnitude assumptions
Remove also the explicit magnitude restriction `a->x.magnitude <= 31`
in `secp256k1_gej_eq_x_var` (introduced in commit
07c0e8b82e), as this is implied by the
new limits.

Co-authored-by: Sebastian Falbesoner <sebastian.falbesoner@gmail.com>
2023-07-22 01:52:06 +02:00
Sebastian Falbesoner
49afd2f5d8 Take use of _fe_verify_magnitude in field_impl.h 2023-07-22 01:52:06 +02:00
Peter Dettman
4e9661fc42 Add _fe_verify_magnitude (no-op unless VERIFY is enabled)
Co-authored-by: Tim Ruffing <crypto@timruffing.de>
2023-07-22 01:52:06 +02:00
Sebastian Falbesoner
690b0fc05a add missing group element invariant checks
The group element checks `secp256k1_{ge,gej}_verify` have first been
implemented and added in commit f20266722a
(PR #1299). This commit adds additional verification calls in group
functions, to match the ones that were originally proposed in commit
09dbba561fdb9d57a2cc9842ce041d9ba29a6189 of WIP-PR #1032 (which is
obviously not rebased on #1299 yet).

Also, for easier review, all functions handling group elements are
structured in the following wasy for easier review (idea suggested by
Tim Ruffing):

- on entry, verify all input ge, gej (and fe)
- empty line
- actual function body
- empty line
- on exit, verify all output ge, gej

Co-authored-by: Peter Dettman <peter.dettman@gmail.com>
Co-authored-by: Tim Ruffing <crypto@timruffing.de>
2023-07-22 01:52:06 +02:00
Jonas Nick
d47e4d40ca Merge elementsproject/secp256k1-zkp#252: Upstream PRs 1113, 1225, 1227, 1229, 1223
b40adf2360 release: prepare for 0.3.0 (Jonas Nick)
8be82d4362 cmake: Rename project to "libsecp256k1" (Hennadii Stepanov)
756b61d451 readme: Use correct build type in CMake/Windows build instructions (Tim Ruffing)
92098d84cf changelog: Add entry for CMake (Tim Ruffing)
e1eb33724c ci: Add "x86_64: Windows (VS 2022)" task (Hennadii Stepanov)
10602b0030 cmake: Export config files (Hennadii Stepanov)
5468d70964 build: Add CMake-based build system (Hennadii Stepanov)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK dc733595b0

Tree-SHA512: ded76837ee78d3a99daf5e9dbdb3912a1f7efb8b9ea329535e5b5452f8bf6d02bc290dd2378b17a20e1d33b4811c1d88482bf46a57d6c414855b64cf55e38e99
2023-07-21 14:57:16 +00:00
Jonas Nick
dc733595b0 Merge commits 'df323b5c 3295aa14 ef4f8bd0 90b513aa bdf39000 ' into temp-merge-1223 2023-07-21 13:34:46 +00:00
Jonas Nick
3937cefce6 Merge elementsproject/secp256k1-zkp#249: Upstream PRs 1160, 1193, 1169, 1190, 1192, 1194, 1196, 1195, 1170, 1172, 1200, 1199, 1203, 1201, 1206, 1078, 1209, 979, 1212, 1218, 1217, 1221, 1222
5d8f53e312 Remove redudent checks. (Russell O'Connor)
d232112fa7 Update Changelog (Tim Ruffing)
b081f7e4cb Add secp256k1_fe_add_int function (Pieter Wuille)
2ef1c9b387 Update overflow check (Russell O'Connor)
5660c13755 prevent optimization in algorithms (Harshil Jani)
ce3cfc78a6 doc: Describe Jacobi calculation in safegcd_implementation.md (Elliott Jin)
6be01036c8 Add secp256k1_fe_is_square_var function (Pieter Wuille)
1de2a01c2b Native jacobi symbol algorithm (Pieter Wuille)
04c6c1b181 Make secp256k1_modinv64_det_check_pow2 support abs val (Pieter Wuille)
5fffb2c7af Make secp256k1_i128_check_pow2 support -(2^n) (Pieter Wuille)
e4330341bd ci: Shutdown wineserver whenever CI script exits (Tim Ruffing)
9a5a611a21 build: Suppress stupid MSVC linker warning (Tim Ruffing)
739c53b19a examples: Extend sig examples by call that uses static context (Tim Ruffing)
914276e4d2 build: Add SECP256K1_API_VAR to fix importing variables from DLLs (Tim Ruffing)
e089eecc1e group: Further simply gej_add_ge (Tim Ruffing)
ac71020ebe group: Save a normalize_to_zero in gej_add_ge (Tim Ruffing)
8c7e0fc1de build: Add -Wreserved-identifier supported by clang (Tim Ruffing)
9b60e3148d ci: Do not set git's `user.{email,name}` config options (Hennadii Stepanov)
ef39721ccc Do not link `bench` and `ctime_tests` to `COMMON_LIB` (Hennadii Stepanov)
c2415866c7 ci: Don't fetch git history (Tim Ruffing)
0ecf318851 ci: Use remote pull/merge ref instead of local git merge (Tim Ruffing)
9b7d18669d Drop no longer used Autoheader macros (Hennadii Stepanov)
eb6bebaee3 scalar: restrict split_lambda args, improve doc and VERIFY_CHECKs (Jonas Nick)
7f49aa7f2d ci: add test job with -DVERIFY (Jonas Nick)
620ba3d74b benchmarks: fix bench_scalar_split (Jonas Nick)
e39d954f11 tests: Add CHECK_ILLEGAL(_VOID) macros and use in static ctx tests (Tim Ruffing)
61841fc9ee contexts: Forbid randomizing secp256k1_context_static (Tim Ruffing)
4b6df5e33e contexts: Forbid cloning/destroying secp256k1_context_static (Tim Ruffing)
8f51229e03 ctime_tests: improve output when CHECKMEM_RUNNING is not defined (Jonas Nick)
2cd4e3c0a9 Drop no longer used `SECP_{LIBS,INCLUDE}` variables (Hennadii Stepanov)
613626f94c Drop no longer used `SECP_TEST_{LIBS,INCLUDE}` variables (Hennadii Stepanov)
d6ff738d5b Ensure safety of ctz_debruijn implementation. (Russell O'Connor)
ce60785b26 Introduce SECP256K1_B macro for curve b coefficient (Pieter Wuille)
4934aa7995 Switch to exhaustive groups with small B coefficient (Pieter Wuille)
e03ef86559 Make all non-API functions (except main) static (Pieter Wuille)
0f088ec112 Rename CTIMETEST -> CTIMETESTS (Pieter Wuille)
74b026f05d Add runtime checking for DECLASSIFY flag (Pieter Wuille)
5e2e6fcfc0 Run ctime test in Linux MSan CI job (Pieter Wuille)
18974061a3 Make ctime tests building configurable (Pieter Wuille)
5048be17e9 Rename valgrind_ctime_test -> ctime_tests (Pieter Wuille)
6eed6c18de Update error messages to suggest msan as well (Pieter Wuille)
8e11f89a68 Add support for msan integration to checkmem.h (Pieter Wuille)
8dc64079eb Add compile-time error to valgrind_ctime_test (Pieter Wuille)
0db05a770e Abstract interactions with valgrind behind new checkmem.h (Pieter Wuille)
4f1a54e41d Move valgrind CPPFLAGS into SECP_CONFIG_DEFINES (Pieter Wuille)
d4a6b58df7 Add `noverify_tests` to `.gitignore` (Hennadii Stepanov)
e862c4af0c Makefile: add -I$(top_srcdir)/src to CPPFLAGS for precomputed (Matt Whitlock)

Pull request description:

ACKs for top commit:
  real-or-random:
    tACK  0d540ec942

Tree-SHA512: bc54ccf752163ab6e1a12bb8c4e1f9339f4421d2e4f7716c408549514b3c902f2e9f727655799f1eecb085b0026761b04735b17be3c95c6cf54e07fbf7e86477
2023-07-21 13:29:02 +00:00
Jonas Nick
897c765a49 Merge elementsproject/secp256k1-zkp#251: Update sync-upstream with master
7e9193666f ci: Always define EXPERIMENTAL variable (Tim Ruffing)
0a99156871 sync-upstream.sh: Add "git show --remerge-diff" tip (Tim Ruffing)
9b6a1c384d sync-upstream.sh: Fix position of "-b" option in reproduce command (Tim Ruffing)
05b207e969 sync-upstream: allows providing the local branch via cli (Jonas Nick)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK 7e9193666f

Tree-SHA512: 4527cb6a2493d210eb7ba6d8f6e717b2acbc07aebdc1c4011cffe23490876a4e795d656a69df2cd50e4e3fe8742c123d9ea493914c148c8fbc93d7d3799e7447
2023-07-21 13:28:15 +00:00
Jonas Nick
53bc63f9f9 Merge elementsproject/secp256k1-zkp#245: scalar: Remove unused secp256k1_scalar_chacha20
860360eed4 scalar: Remove unused secp256k1_scalar_chacha20 (Tim Ruffing)
3970a7292a rangeproof: Use util functions for writing big endian (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 860360eed4

Tree-SHA512: 0e74fe6f4aa5ab12eea1dece3b43aa2f98c188096ab4bb59324f86f1c88d4f13fc81b9fe852701682a9c4c1fccdc17e3bdbc1d3df7cc341822ac022772037c29
2023-07-21 12:24:21 +00:00
Tim Ruffing
860360eed4 scalar: Remove unused secp256k1_scalar_chacha20
Unused since a11250330b.
2023-07-21 13:06:17 +02:00
Tim Ruffing
3970a7292a rangeproof: Use util functions for writing big endian 2023-07-21 13:06:17 +02:00
Jonas Nick
afe7e649ee Merge elementsproject/secp256k1-zkp#248: bppp: Fix and improve test for invalid sign byte
3372993060 bppp: Fix test for invalid sign byte (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 3372993060

Tree-SHA512: cfc317b47dc731b419cc88d0c5292cb6b3ca9e28c937d316f63940be6ad4607056ece81136ca1226f94dbf26cfe0492f5d27f4cfa473cf46898474b342a55593
2023-07-21 07:19:51 +00:00
Jonas Nick
1a6d93f8b6 Merge elementsproject/secp256k1-zkp#250: ci: Always define EXPERIMENTAL variable
7e9193666f ci: Always define EXPERIMENTAL variable (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 7e9193666f

Tree-SHA512: d684ae76456a90b6bb8d215b108a420f6bb32800fe515a201de948366ffc9a1c33c7dd35a491db44f0db8b06c41c976ffe423bfccbab88b51bacbc23453992d1
2023-07-21 07:17:41 +00:00
Tim Ruffing
3372993060 bppp: Fix test for invalid sign byte
The test is supposed to create an invalid sign byte. Before this PR,
the generated sign byte could in fact be valid due to an overflow.

Co-authored-by: Jonas Nick <jonasd.nick@gmail.com>
2023-07-20 23:34:43 +02:00
Tim Ruffing
7e9193666f ci: Always define EXPERIMENTAL variable 2023-07-20 23:02:55 +02:00
Jonas Nick
0d540ec942 Merge commits '88e80722 ff8edf89 f29a3270 a7a7bfaf a01a7d86 b1579cf5 ad7433b1 233822d8 5fbff5d3 2b77240b 1bff2005 e1817a6f 5596ec5c 8ebe5c52 1cca7c17 1b21aa51 cbd25559 09b1d466 57573187 8962fc95 9d1b458d eb8749fc 6048e6c0 ' into temp-merge-1222 2023-07-20 16:29:40 +00:00
Jonas Nick
7aa9887128 Merge pull request #246 from jonasnick/temp-merge-1187
Upstream PRs 1174, 1154, 1178, 1177, 1171, 1158, 1183, 1185, 1186, 1188, 1187
2023-07-20 15:35:18 +00:00
Jonas Nick
304fc88557 Merge commits '9a8d65f0 75d7b7f5 665ba77e 3f57b9f7 eacad90f 01b819a8 31ed5386 2a39ac16 0eb30004 cbe41ac1 cc3b8a4f ' into temp-merge-1187 2023-07-20 12:19:00 +00:00
Tim Ruffing
58e27bc2d2 Merge ElementsProject/secp256k1-zkp#244: sync-upstream.sh: Add "git show --remerge-diff" tip
0a99156871 sync-upstream.sh: Add "git show --remerge-diff" tip (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    utACK 0a99156871

Tree-SHA512: 6d3a26481f8d8f263db2379aca2670f5610b44fbf6b283550d83af9500b7e156927683d400e720fcb017cade317b176f882159a472ac8d5c99cff886b497dcfb
2023-07-19 11:15:29 +02:00
Jonas Nick
c545fdc374 Merge bitcoin-core/secp256k1#1298: Remove randomness tests
6ec3731e8c Simplify test PRNG implementation (Pieter Wuille)
fb5bfa4eed Add static test vector for Xoshiro256++ (Tim Ruffing)
723e8ca8f7 Remove randomness tests (Pieter Wuille)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK 6ec3731e8c
  jonasnick:
    ACK 6ec3731e8c

Tree-SHA512: 4cbbb9c42e31f067b17dd9169ae5d5e68bce77d1253452db9df523d3be2b5d61002d5a4203e5a153f257ec63c5ff2113555743eeb402d4b6c573069ea494d407
2023-07-18 14:05:46 +00:00
Tim Ruffing
0a99156871 sync-upstream.sh: Add "git show --remerge-diff" tip 2023-07-18 15:05:27 +02:00
Jonas Nick
6c54db1987 Merge commits '2286f809 751c4354 477f02c4 e3f84777 5c789dcd 8c949f56 21ffe4b2 ' into temp-merge-1055 2023-07-18 12:51:17 +00:00
Tim Ruffing
30fc9d6551 Merge ElementsProject/secp256k1-zkp#242: sync-upstream.sh: Fix position of "-b" option in reproduce command
9b6a1c384d sync-upstream.sh: Fix position of "-b" option in reproduce command (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    utACK 9b6a1c384d

Tree-SHA512: 27e4a41bc9c8f10715623f669c97a511520753b23d24ae91d6d2144e54588da0769f97b1de78c87b7471b39e556b682b1c2910b2bf71f124fb77cbc9e446d5f8
2023-07-18 10:11:23 +02:00
Tim Ruffing
9b6a1c384d sync-upstream.sh: Fix position of "-b" option in reproduce command 2023-07-17 18:44:33 +02:00
Tim Ruffing
b40e2d30b7 Merge bitcoin-core/secp256k1#1378: ellswift: fix probabilistic test failure when swapping sides
c424e2fb43 ellswift: fix probabilistic test failure when swapping sides (Jonas Nick)

Pull request description:

  Reported by jonatack in https://github.com/bitcoin/bitcoin/issues/28079.

  When configured with `--disable-module-ecdh --enable-module-recovery`, then `./tests  64 81af32fd7ab8c9cbc2e62a689f642106` fails with
  ```
  src/modules/ellswift/tests_impl.h:396: test condition failed: secp256k1_memcmp_var(share32_bad, share32a, 32) != 0
  ```

  This tests verifies that changing the `party` bit of the `secp256k1_ellswift_xdh` function results in a different share. However, that's not the case when the secret keys of both parties are the same and this is actually what happens in the observed test failure. The keys can be equal in this test case because they are created by the `random_scalar_order_test` function whose output is not uniformly random (it's biased towards 0).

  This commit restores the assumption that the secret keys differ.

ACKs for top commit:
  sipa:
    utACK c424e2fb43
  real-or-random:
    utACK c424e2fb43

Tree-SHA512: d1ab61473a77478f9aeffb21ad73e0bba478c90d8573c72ec89d2e0140434cc65c9d5f4d56e5f259931dc68fc1800695c6cd5d63d9cfce4c1c4d6744eeaa2028
2023-07-17 18:37:20 +02:00
Jonas Nick
e996d076da Merge commits '44916ae9 86e3b38a ddf2b291 6138d73b e40fd277 ' into temp-merge-1156 2023-07-17 14:02:13 +00:00
Tim Ruffing
533571d6cf Merge ElementsProject/secp256k1-zkp#239: sync-upstream: allows providing the local branch via cli
05b207e969 sync-upstream: allows providing the local branch via cli (Jonas Nick)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 05b207e969

Tree-SHA512: b02f3fdf6565943cea2b93a0b2b0a38c30bb3c94873d0c4ed2ad276c75f3dc610911d1c9c076c8b7fd3a5baf83aa1ab66ec86415333cf58fe8f07c64fa74656f
2023-07-17 15:47:16 +02:00
Jonas Nick
05b207e969 sync-upstream: allows providing the local branch via cli 2023-07-17 13:29:59 +00:00
Jonas Nick
64717a7b16 Merge commits '8b013fce 485f608f 44c2452f cd470333 accadc94 43756da8 af65d30c 63a3565e 6a873cc4 3efeb9da 9f8a13dc 694ce8fb a43e982b e13fae48 c2ee9175 ' into temp-merge-1146 2023-07-17 13:02:36 +00:00
Jonas Nick
9a981068ce Merge commits '8b013fce 485f608f 44c2452f cd470333 accadc94 43756da8 ' into temp-merge-1115 2023-07-17 12:01:46 +00:00
Jonas Nick
c424e2fb43 ellswift: fix probabilistic test failure when swapping sides
When configured with `--disable-module-ecdh --enable-module-recovery`, then
`./tests  64 81af32fd7ab8c9cbc2e62a689f642106` fails with
```
src/modules/ellswift/tests_impl.h:396: test condition failed: secp256k1_memcmp_var(share32_bad, share32a, 32) != 0
```

This tests verifies that changing the `party` bit of the
`secp256k1_ellswift_xdh` function results in a different share. However, that's
not the case when the secret keys of both parties are the same and this is
actually what happens in the observed test failure. The keys can be equal in
this test case because they are created by the `random_scalar_order_test`
function whose output is not uniformly random (it's biased towards 0).

This commit restores the assummption that the secret keys differ.
2023-07-17 09:50:32 +00:00
Hennadii Stepanov
175db31149 ci: Drop no longer needed PATH variable update on Windows 2023-07-14 08:43:08 +01:00
Hennadii Stepanov
116d2ab3df cmake: Set ENVIRONMENT property for examples on Windows
This change simplifies running examples on Windows, because the DLL
must reside either in the same folder where the executable is or
somewhere in PATH.
2023-07-14 08:42:48 +01:00
Hennadii Stepanov
cef373997c cmake, refactor: Use helper function instead of interface library
This change aims to simplify the following commit.
2023-07-14 08:41:26 +01:00
Jonas Nick
907a67212e Merge bitcoin-core/secp256k1#1313: ci: Test on development snapshots of GCC and Clang
981e5be38c ci: Fix typo in comment (Tim Ruffing)
e9e9648219 ci: Reduce number of macOS tasks from 28 to 8 (Tim Ruffing)
609093b387 ci: Add x86_64 Linux tasks for gcc and clang snapshots (Tim Ruffing)
1deecaaf3b ci: Install development snapshots of gcc and clang (Tim Ruffing)

Pull request description:

ACKs for top commit:
  hebasto:
    re-ACK 981e5be38c
  jonasnick:
    ACK 981e5be38c

Tree-SHA512: a36ef6f3c30a7f6e09e186e67b8eeb6e16e05de3bd97f21342866e75e33275103d463b6a12603ce235da7e26e4acdef4d811f62f369f18db9ac4e7ff06749136
2023-07-13 14:44:45 +00:00
Tim Ruffing
0f7657d59c Merge bitcoin-core/secp256k1#1366: field: Use restrict consistently in fe_sqrt
b79ba8aa4c field: Use `restrict` consistently in fe_sqrt (Tim Ruffing)

Pull request description:

  That is, use it also in the definition and not only the declaration.

  I believe this was the intention of commit
  be82bd8e03, but it was omitted there.

  edit: Changed the description. I'm not entirely sure but after looking at the standard, I tend to think this is more than a cosmetic change, and only this change actually makes the parameters `restrict`. Anyway, I believe making them `restrict` was simply forgotten in be82bd8e03.

ACKs for top commit:
  sipa:
    utACK b79ba8aa4c

Tree-SHA512: eecec7674d8cef7833d50f4041b87241ca8de4839aa8027df1c422b89f5a1bcef3916ac785057a596c459ce1aa9d41e5a21ecb6fed9c5d15a1d9f588c7ee208e
2023-07-12 01:14:22 +02:00
Tim Ruffing
cc55757552 Merge bitcoin-core/secp256k1#1340: clean up in-comment Sage code (refer to secp256k1_params.sage, update to Python3)
600c5adcd5 clean up in-comment Sage code (refer to secp256k1_params.sage, update to Python3) (Sebastian Falbesoner)

Pull request description:

  Some of the C source files contain contain in-comment Sage code calculating secp256k1 parameters that are already defined in the file secp256k1_params.sage.  Replace that by a corresponding load instruction and access the necessary variables. In ecdsa_impl.h, update the comment to use a one-line shell command calling sage to get the values.

  The remaining code (test `test_add_neg_y_diff_x` in tests.c) is updated to work with a current version based on Python3 (Sage 9.0+, see https://wiki.sagemath.org/Python3-Switch).

  The latter can be seen as a small follow-up to PR #849 (commit 13c88efed0).

ACKs for top commit:
  sipa:
    ACK 600c5adcd5
  real-or-random:
    ACK 600c5adcd5

Tree-SHA512: a9e52f6afbce65edd9ab14203612c3d423639f450fe8f0d269a3dda04bebefa95b607f7aa0faec864cb78b46d49f281632bb1277118749b7d8613e9f5dcc8f3d
2023-07-10 18:34:16 +02:00
Sebastian Falbesoner
600c5adcd5 clean up in-comment Sage code (refer to secp256k1_params.sage, update to Python3)
Some of the C source files contain contain in-comment Sage code
calculating secp256k1 parameters that are already defined in the file
secp256k1_params.sage.  Replace that by a corresponding load instruction
and access the necessary variables. In ecdsa_impl.h, update the comment
to use a one-line shell command calling sage to get the values.

The remaining code (test `test_add_neg_y_diff_x` in tests.c) is updated
to work with a current version based on Python3 (Sage 9.0+, see
https://wiki.sagemath.org/Python3-Switch).

The latter can be seen as a small follow-up to PR #849 (commit
13c88efed0).
2023-07-10 02:28:31 +02:00
Tim Ruffing
981e5be38c ci: Fix typo in comment 2023-07-06 20:19:07 +02:00
Tim Ruffing
e9e9648219 ci: Reduce number of macOS tasks from 28 to 8 2023-07-06 20:19:04 +02:00
Tim Ruffing
609093b387 ci: Add x86_64 Linux tasks for gcc and clang snapshots 2023-07-06 20:19:04 +02:00
Tim Ruffing
1deecaaf3b ci: Install development snapshots of gcc and clang
TODO: Make sure the Docker image is actually rebuild
2023-07-06 20:19:04 +02:00
Tim Ruffing
b79ba8aa4c field: Use restrict consistently in fe_sqrt
That is, use it also in the definition and not only the declaration.

I believe this was the intention of commit
be82bd8e03, but it was omitted there.
2023-07-06 16:44:52 +02:00
Tim Ruffing
c9ebca95f9 Merge bitcoin-core/secp256k1#1363: doc: minor ellswift.md updates
c7d900ffd1 doc: minor ellswift.md updates (stratospher)

Pull request description:

ACKs for top commit:
  sipa:
    ACK c7d900ffd1
  real-or-random:
    ACK c7d900ffd1

Tree-SHA512: 161c17d038eb1eed9f5811c3eb92975a821a5274e7f69aa386bfbe5376b3f06f3d0d2887ea3310efbec83424f09ea8e4082e8c02b2fcad3b915625ce5c2007d2
2023-07-06 16:03:19 +02:00
Tim Ruffing
afd7eb4a55 Merge bitcoin-core/secp256k1#1371: Add exhaustive tests for ellswift (with create+decode roundtrip)
2792119278 Add exhaustive test for ellswift (create+decode roundtrip) (Sebastian Falbesoner)

Pull request description:

  This PR adds the basic structure for ellswift exhaustive tests. Right now only a `secp256k1_ellswift_create` + `secp256k1_ellswift_decode` indirect roundtrip (exhaustive loop scalar -> ellswift pubkey -> decoded pubkey -> decoded group element, compared with exhaustive precomputed group element) is included.

  The exhaustive tests passes locally with all currently supported orders (n=13 [default] and n=199). Note that for n=7, the test is skipped, as the used curve in this case is even-ordered and ellswift only supports odd-ordered curves.

ACKs for top commit:
  sipa:
    utACK 2792119278
  real-or-random:
    utACK 2792119278

Tree-SHA512: c51d3d99e9839793b3c15d75b9a29f01080db160ab8819973abd877288f9f0af972ea4264290220ab1cd035fdebcfac7767436aa39154d924ef0bf6a5733a55d
2023-07-05 23:19:31 +02:00
Sebastian Falbesoner
2792119278 Add exhaustive test for ellswift (create+decode roundtrip)
Co-authored-by: Pieter Wuille <pieter@wuille.net>
Co-authored-by: Tim Ruffing <crypto@timruffing.de>
2023-07-05 18:24:37 +02:00
stratospher
c7d900ffd1 doc: minor ellswift.md updates 2023-07-05 20:26:18 +05:30
Tim Ruffing
332af315fc Merge bitcoin-core/secp256k1#1344: group: save normalize_weak calls in secp256k1_ge_is_valid_var/secp256k1_gej_eq_x_var
07c0e8b82e group: remove unneeded normalize_weak in `secp256k1_gej_eq_x_var` (Sebastian Falbesoner)
efa76c4bf7 group: remove unneeded normalize_weak in `secp256k1_ge_is_valid_var` (Sebastian Falbesoner)

Pull request description:

  This PR removes unneeded normalize_weak calls in two group element functions:
  * `secp256k1_ge_is_valid_var`: After calculating the right-hand side of the elliptic curve equation (x^3 + 7), the field element `x3` has a magnitude of 2 (1 as result of `secp256k1_fe_mul`, then increased by 1 due to `secp256k1_fe_add_int`). This is fine for `secp256k1_fe_equal_var`, as the second parameter only requires the magnitude to not exceed 31, and the normalize_weak call is hence not needed and can be dropped. Note that the interface description for `secp256k1_fe_equal` (which also applies to `secp256k1_fe_equal_var`) once stated that _both_ parameters need to have magnitude 1, but that was corrected in commit 7d7d43c6dd.

  * `secp256k1_gej_eq_x_var`: By requiring that the input group element's X coordinate (`a->x`) has a magnitude of <= 31, the normalize_weak call and also the field element variable `r2` are not needed anymore and hence can be dropped.

ACKs for top commit:
  sipa:
    utACK 07c0e8b82e
  jonasnick:
    ACK 07c0e8b82e

Tree-SHA512: 9037e4af881ce7bf3347414d6da06b99e3d318733ba4f70e8b24d2320c2f26d022144e17bd6b95c1a4ef1be3825a4464e56ce2d2b3ae7bbced04257048832b7f
2023-07-04 14:21:46 +02:00
Tim Ruffing
9e6d1b0e9b Merge bitcoin-core/secp256k1#1367: build: Improvements to symbol visibility logic on Windows (attempt 3)
c6cd2b15a0 ci: Add task for static library on Windows + CMake (Hennadii Stepanov)
020bf69a44 build: Add extensive docs on visibility issues (Tim Ruffing)
0196e8ade1 build: Introduce `SECP256k1_DLL_EXPORT` macro (Hennadii Stepanov)
9f1b1904a3 refactor: Replace `SECP256K1_API_VAR` with `SECP256K1_API` (Hennadii Stepanov)
ae9db95cea build: Introduce `SECP256K1_STATIC` macro for Windows users (Hennadii Stepanov)

Pull request description:

  Previous attempts:
  - https://github.com/bitcoin-core/secp256k1/pull/1346
  - https://github.com/bitcoin-core/secp256k1/pull/1362

  The result is as follows:
  1. Simple, concise and extensively documented code.
  2. Explicitly documented use cases with no ambiguities.
  3. No workarounds for linker warnings.
  4. Solves one item in https://github.com/bitcoin-core/secp256k1/issues/1235.

ACKs for top commit:
  real-or-random:
    utACK c6cd2b15a0

Tree-SHA512: d58694452d630aefbd047916033249891bc726b7475433aaaa7c3ea2a07ded8f185a598385b67c2ee3440ec5904ff9d9452c97b0961d84dcb2eb2cf46caa171e
2023-07-03 18:53:38 +02:00
Tim Ruffing
0aacf64352 Merge bitcoin-core/secp256k1#1370: Corrected some typos
b6b9834e8d small fixes (Alejandro)

Pull request description:

  Corrected some typos

ACKs for top commit:
  real-or-random:
    ACK b6b9834e8d

Tree-SHA512: c40c22c66f1067ecca351f08cca07a78b00bb98af2f6cfb08c25d0b1db6845e0e32ace1954c386db7020cf9fc7ae973ff15bd6d9c0144f3d21ea28c15741050f
2023-07-03 18:50:45 +02:00
Alejandro
b6b9834e8d small fixes
restoring wycheproof files

restoring wycheproof files2
2023-07-03 17:05:55 +02:00
Sebastian Falbesoner
07c0e8b82e group: remove unneeded normalize_weak in secp256k1_gej_eq_x_var
By requiring that the input group element's X coordinate (`a->x`) has a
magnitude of <= 31, the normalize_weak call and also the field element
variable `r2` are not needed anymore and hence can be dropped.
2023-07-03 16:54:19 +02:00
Tim Ruffing
3fc1de5c55 Merge bitcoin-core/secp256k1#1364: Avoid -Wmaybe-uninitialized when compiling with gcc -O1
5b9f37f136 ci: Add `CFLAGS: -O1` to task matrix (Hennadii Stepanov)
a6ca76cdf2 Avoid `-Wmaybe-uninitialized` when compiling with `gcc -O1` (Hennadii Stepanov)

Pull request description:

  Fixes https://github.com/bitcoin-core/secp256k1/issues/1361.

  CI tasks have been adjusted to catch similar issues in the future.

ACKs for top commit:
  real-or-random:
    utACK 5b9f37f136
  jonasnick:
    tACK 5b9f37f136

Tree-SHA512: 8aa5ec22ed88579ecd37681df68d64f8bab93cd14bdbf432a3af41cadc7ab3eba86c33c179db15bf3a3c798c33064bd845ebdedb02ee617ef634e98c596838c2
2023-07-03 15:32:17 +02:00
Jonas Nick
fb758fe8d6 Merge bitcoin-core/secp256k1#1323: tweak_add: fix API doc for tweak=0
05873bb6b1 tweak_add: fix API doc for tweak=0 (Jonas Nick)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 05873bb6b1

Tree-SHA512: ef587a680c3355c6328dd61e0f5fcac80ea995f6045b4392fe35f3ee1c04ee1bd941662c120758ad641588670c1f0f53bfb17a802821f54100f1385b8bb7375a
2023-07-03 13:11:20 +00:00
Hennadii Stepanov
c6cd2b15a0 ci: Add task for static library on Windows + CMake 2023-07-03 13:57:31 +01:00
Tim Ruffing
020bf69a44 build: Add extensive docs on visibility issues 2023-07-03 13:57:17 +01:00
Hennadii Stepanov
0196e8ade1 build: Introduce SECP256k1_DLL_EXPORT macro
This change provides a way to build a shared library that is not tired
to the Libtool-specific `DLL_EXPORT` macro.
2023-07-03 13:57:17 +01:00
Hennadii Stepanov
9f1b1904a3 refactor: Replace SECP256K1_API_VAR with SECP256K1_API 2023-07-03 13:57:16 +01:00
Hennadii Stepanov
ae9db95cea build: Introduce SECP256K1_STATIC macro for Windows users
It is a non-Libtool-specific way to explicitly specify the user's
intention to consume a static `libseck256k1`.

This change allows to get rid of MSVC linker warnings LNK4217 and
LNK4286. Also, it makes possible to merge the `SECP256K1_API` and
`SECP256K1_API_VAR` into one.
2023-07-03 13:57:11 +01:00
Tim Ruffing
7966aee31d Merge bitcoin-core/secp256k1#1369: ci: Print commit in Windows container
a7bec34231 ci: Print commit in Windows container (Hennadii Stepanov)

Pull request description:

  This PR is a follow-up to https://github.com/bitcoin-core/secp256k1/pull/1368 and adds the same functionality to Windows containers that is already available in Linux containers.

  See: https://github.com/bitcoin-core/secp256k1/pull/1368#discussion_r1250454050.

ACKs for top commit:
  real-or-random:
    ACK a7bec34231 seems to work: https://cirrus-ci.com/task/4919320090771456?logs=git_show#L2

Tree-SHA512: 0998e0f7231e3057a7e358a27b34071c73ca556973da20494db84fc67f2a72ad2fe582e59647a425ee41e7d9103a0a22fb3cdf0ace6fe0aed1d21f2f75c8ec53
2023-07-03 14:55:19 +02:00
Hennadii Stepanov
a7bec34231 ci: Print commit in Windows container
This change adds the same functionality to Windows containers that is
already available in Linux containers.
2023-07-03 09:31:49 +01:00
Jonas Nick
249c81eaa3 Merge bitcoin-core/secp256k1#1368: ci: Drop manual checkout of merge commit
98579e297b ci: Drop manual checkout of merge commit (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 98579e297b

Tree-SHA512: fe5305322e6fa616af4664db7c151acdfb8119feb0255a65190b9c185ae5383eab37debe76085dfc8137c691e0ff55cb20d9e51993f6cc871bc6c5c945ed66bf
2023-07-02 18:23:54 +00:00
Tim Ruffing
98579e297b ci: Drop manual checkout of merge commit
This is no longer necessary as of
https://github.com/cirruslabs/cirrus-ci-docs/issues/791#issuecomment-1615691585 .
2023-07-01 13:01:57 +02:00
Hennadii Stepanov
5b9f37f136 ci: Add CFLAGS: -O1 to task matrix 2023-06-28 07:46:40 +01:00
Hennadii Stepanov
a6ca76cdf2 Avoid -Wmaybe-uninitialized when compiling with gcc -O1 2023-06-28 07:45:57 +01:00
Tim Ruffing
0fa84f869d Merge bitcoin-core/secp256k1#1358: tests: introduce helper for non-zero random_fe_test() results
5a95a268b9 tests: introduce helper for non-zero `random_fe_test` results (Sebastian Falbesoner)
304421d57b tests: refactor: remove duplicate function `random_field_element_test` (Sebastian Falbesoner)

Pull request description:

  There are several instances in the tests where random non-zero field elements are generated by calling `random_fe_test` in a do/while-loop with is-zero condition. This PR deduplicates all these by introducing a `random_fe_non_zero_test` helper. Note that some instances checked the is-zero condition via `secp256k1_fe_normalizes_to_zero_var`, which is unnecessary, as the result of `random_field_element_test` is already normalized (so strictly speaking, this is not a pure refactor, and there could be tiny run-time improvements, though I doubt that's measurable).

  Additionally, the first commit removes the function `random_field_element_test` as it is logically a duplicate of `random_fe_test`.

ACKs for top commit:
  real-or-random:
    ACK 5a95a268b9

Tree-SHA512: 920404f38ebe8b84bfd52f3354dc17ae6a0fd6355f99b78c9aeb53bf21f7eca5fd4518edc8a422d84f430ae95864661b497de42a3ab7fa9c49515a1df2f1d466
2023-06-27 12:16:50 +02:00
Sebastian Falbesoner
5a95a268b9 tests: introduce helper for non-zero random_fe_test results
There are several instances in the tests where random non-zero field
elements are generated by calling `random_fe_test` in a do/while-loop.
This commit deduplicates all these by introducing a
`random_fe_non_zero_test` helper. Note that some instances checked the
is-zero condition via `secp256k1_fe_normalizes_to_zero_var`, which is
unnecessary, as the result of `random_fe_test` is already normalized (so
strictly speaking, this is not a pure refactor).
2023-06-27 10:31:24 +02:00
Sebastian Falbesoner
304421d57b tests: refactor: remove duplicate function random_field_element_test
There is a function `random_fe_test` which does exactly the
same, so use that instead. Note that it's also moved up before the
`random_group_element_test` function, in order to avoid needing a forward
declaration.
2023-06-27 10:31:22 +02:00
Tim Ruffing
3aef6ab8e1 Merge bitcoin-core/secp256k1#1345: field: Static-assert that int args affecting magnitude are constant
be8ff3a02a field: Static-assert that int args affecting magnitude are constant (Tim Ruffing)

Pull request description:

  See #1001.

  Try to revert the lines in `tests.c` to see the error message in action.

ACKs for top commit:
  sipa:
    ACK be8ff3a02a. Verified by introducing some non-constant expressions and seeing compilation fail.
  theStack:
    ACK be8ff3a02a

Tree-SHA512: 8befec6ee64959cdc7f3e29b4b622410794cfaf69e9df8df17600390a93bc787dba5cf86239de6eb2e99c038b9aca5461e4b3c82f0e0c4cf066ad7c689941b19
2023-06-27 09:39:10 +02:00
Tim Ruffing
4494a369b6 Merge bitcoin-core/secp256k1#1357: tests: refactor: take use of secp256k1_ge_x_on_curve_var
7d8d5c86df tests: refactor: take use of `secp256k1_ge_x_on_curve_var` (Sebastian Falbesoner)

Pull request description:

  The recently merged ellswift PR (#1129) introduced a helper `secp256k1_ge_x_on_curve_var` to check if a given X coordinate is on the curve (i.e. the expression x^3 + 7 is square, see commit 79e5b2a8b8). This can be used for code deduplication in the `ecmult_const_mult_xonly` test.

  (Found this instance via `$ git grep add_int.*SECP256K1_B`, I think it's the only one where the helper can be used.)

ACKs for top commit:
  sipa:
    utACK 7d8d5c86df
  real-or-random:
    utACK 7d8d5c86df

Tree-SHA512: aebff9b5ef2f6f6664ce89e4e1272cb55b6aac81cfb379652c4b7ab30dd1d7fd82a2c3b47c7b7429755ba28f011a3a9e2e6d3aa5c77d3b105d159104c24b89f3
2023-06-27 09:37:49 +02:00
Tim Ruffing
799f4eec27 Merge bitcoin-core/secp256k1#1356: ci: Adjust Docker image to Debian 12 "bookworm"
c862a9fb49 ci: Adjust Docker image to Debian 12 "bookworm" (Hennadii Stepanov)
a1782098a9 ci: Force DWARF v4 for Clang when Valgrind tests are expected (Hennadii Stepanov)
8a7273465b Help the compiler prove that a loop is entered (Tim Ruffing)

Pull request description:

  Since the [release](https://www.debian.org/News/2023/20230610.html) of Debian 12 "bookworm", it has become the "stable" one that our `ci/linux-debian.Dockerfile` relies on.

  Last time the Docker image was built basing on Debian Bullseye.

  Changes in packages are significant, for instance:
  - `gcc` 10.2. --> 12.2
  - `clang` 11.0 --> 14.0
  - `wine` 5.0 --> 8.0

  which requires certain adjustments provided in this PR.

  The first commit has been cherry-picked from https://github.com/bitcoin-core/secp256k1/pull/1313.

ACKs for top commit:
  sipa:
    utACK c862a9fb49
  real-or-random:
    ACK c862a9fb49

Tree-SHA512: 2a62a8865f904a460274f1f3ec02d2b0b72c84b25722a383c6455cfe672c1d93382941a5027e8dceb2c0f5fe0f0efd49a0ed6b72303982f9e32991f1535538eb
2023-06-27 09:33:42 +02:00
Hennadii Stepanov
c862a9fb49 ci: Adjust Docker image to Debian 12 "bookworm" 2023-06-26 10:24:15 +01:00
Hennadii Stepanov
a1782098a9 ci: Force DWARF v4 for Clang when Valgrind tests are expected 2023-06-26 10:03:19 +01:00
Sebastian Falbesoner
7d8d5c86df tests: refactor: take use of secp256k1_ge_x_on_curve_var
The recently merged ellswift PR (#1129) introduced a helper
`secp256k1_ge_x_on_curve_var` to check if a given X coordinate is
valid (i.e. the expression x^3 + 7 is square, see commit
79e5b2a8b8). This can be used for code
deduplication in the `ecmult_const_mult_xonly` test.
2023-06-25 22:26:20 +02:00
Tim Ruffing
8a7273465b Help the compiler prove that a loop is entered 2023-06-25 19:07:16 +01:00
Tim Ruffing
fd491ea1bb Merge bitcoin-core/secp256k1#1355: Fix a typo in the error message
67887ae65c Fix a typo in the error message (Hennadii Stepanov)

Pull request description:

  The code has been copy-pasted from the `precompute_ecmult_gen.c` source file.

ACKs for top commit:
  real-or-random:
    ACK 67887ae65c

Tree-SHA512: d6874949310197e5d2d6c43f5a7c2165b4ee0f6cbe3cc1491d0f97163fa5329ebeab2b2adf10246c87382016fbe738c69dfd3f2253e93c906bf404cbf439b12a
2023-06-25 09:52:04 +02:00
Tim Ruffing
ac43613d25 Merge bitcoin-core/secp256k1#1354: Add ellswift to CHANGELOG
7c7467ab7f Refer to ellswift.md in API docs (Pieter Wuille)
c32ffd8d8c Add ellswift to CHANGELOG (Pieter Wuille)

Pull request description:

  A follow-up with a CHANGELOG entry for #1129.

ACKs for top commit:
  real-or-random:
    ACK 7c7467ab7f
  theStack:
    ACK 7c7467ab7f

Tree-SHA512: 4f066e4b8d5e130f2b5bea0ed4c634e9426bc576342aad6c306e0805a8354e27a5e679b15ec869d4e7d36eb5d53174e46b3bf5e15d19a7e165afc82e46ddfcf5
2023-06-25 09:49:40 +02:00
Hennadii Stepanov
67887ae65c Fix a typo in the error message
The code has been copy-pasted from the `precompute_ecmult_gen.c` source
file.
2023-06-24 20:18:45 +01:00
Tim Ruffing
926dd3e962 Merge bitcoin-core/secp256k1#1295: abi: Use dllexport for mingw builds
bc7c8db179 abi: Use dllexport for mingw builds (Cory Fields)

Pull request description:

  Addresses the first part of #1181. See the discussion there for more context and history.

  After this, all that remains is a (platform-independent) exports checker for c-i. Or perhaps a linker script or .def file could be tricked into testing as a side-effect.

  This should fix mingw exports, specifically hiding the following:
  `secp256k1_pre_g_128`
  `secp256k1_pre_g`
  `secp256k1_ecmult_gen_prec_table`

  This changes our visibility macros to look more like [gcc's recommendation](https://gcc.gnu.org/wiki/Visibility#How_to_use_the_new_C.2B-.2B-_visibility_support).

  Edit:
  Note that we could further complicate this by supporting `__attribute__ ((dllexport))` as well, though I didn't bother as I'm not sure what compiler combo would accept that but not the bare dllexport syntax.

  Edit2:
  As the title implies, this affects this ABI and could affect downstream libs/apps in unintended ways (though it's hard to imagine any real downside). Though because it's win32 only, I'm imagining very little real-world impact at all.

ACKs for top commit:
  hebasto:
    re-ACK bc7c8db179, only a comment has been adjusted since my recent [review](https://github.com/bitcoin-core/secp256k1/pull/1295#pullrequestreview-1414928537),
  real-or-random:
    utACK bc7c8db179

Tree-SHA512: 378e15556da49494f551bdf4f7b41304db9d03a435f21fcc947c9520aa43e3c655cfe216fba57a5179a871c975c806460eef7c33b105f2726e1de0937ff2444e
2023-06-24 10:37:55 +02:00
Tim Ruffing
10836832e7 Merge bitcoin-core/secp256k1#1336: Use __shiftright128 intrinsic in secp256k1_u128_rshift on MSVC
5b7bf2e9d4 Use `__shiftright128` intrinsic in `secp256k1_u128_rshift` on MSVC (Hennadii Stepanov)

Pull request description:

  Closes https://github.com/bitcoin-core/secp256k1/issues/1324.

  As the `__shiftright128` [docs](https://learn.microsoft.com/en-us/cpp/intrinsics/shiftright128) state:
  > The `Shift` value is always modulo 64...

  it is not applicable for the `n >= 64` branch.

ACKs for top commit:
  sipa:
    utACK 5b7bf2e9d4
  real-or-random:
    ACK 5b7bf2e9d4 tested with MSVC x64

Tree-SHA512: bc4c245a9da83c783a0479e751a4bc2ec77a34b99189fcc4431033a5420c93b610f3b960d3f23c15bce2eb010beba665b3e84d468b3fdab3d5846d4f27016898
2023-06-24 10:16:02 +02:00
Pieter Wuille
7c7467ab7f Refer to ellswift.md in API docs 2023-06-23 16:05:24 -04:00
Pieter Wuille
c32ffd8d8c Add ellswift to CHANGELOG 2023-06-21 13:04:42 -04:00
Tim Ruffing
3c1a0fd37f Merge bitcoin-core/secp256k1#1347: field: Document return value of fe_sqrt()
5779137457 field: Document return value of fe_sqrt() (Tim Ruffing)

Pull request description:

ACKs for top commit:
  sipa:
    ACK 5779137457
  theStack:
    ACK 5779137457

Tree-SHA512: 706f8c6a26bf85f6c23af3bb053173b2cdee6838dd930cb2b1e2f851f47cfebafccecbd7d84b8152f2fea12f0676c1ddd700bb32beebec3f3e0f4300e878d0f5
2023-06-21 17:43:01 +02:00
Jonas Nick
705ce7ed8c Merge bitcoin-core/secp256k1#1129: ElligatorSwift + integrated x-only DH
90e360acc2 Add doc/ellswift.md with ElligatorSwift explanation (Pieter Wuille)
4f091847c2 Add ellswift testing to CI (Pieter Wuille)
1bcea8c57f Add benchmarks for ellswift module (Pieter Wuille)
2d1d41acf8 Add ctime tests for ellswift module (Pieter Wuille)
df633cdeba Add _prefix and _bip324 ellswift_xdh hash functions (Pieter Wuille)
9695deb351 Add tests for ellswift module (Pieter Wuille)
c47917bbd6 Add ellswift module implementing ElligatorSwift (Pieter Wuille)
79e5b2a8b8 Add functions to test if X coordinate is valid (Pieter Wuille)
a597a5a9ce Add benchmark for key generation (Pieter Wuille)

Pull request description:

ACKs for top commit:
  Davidson-Souza:
    tACK 90e360a. Full testing backlog:
  real-or-random:
    ACK 90e360acc2
  jonasnick:
    ACK 90e360acc2

Tree-SHA512: cf59044c1b064f9a3fd57fd1c4c6ab154305ee6ad67a604bc254ddd6b8ee78626250d325174e10d2f2b19264ab0d58013508dc763aa07f5a1e6417e03551a378
2023-06-21 14:34:39 +00:00
Tim Ruffing
0702ecb061 Merge bitcoin-core/secp256k1#1338: Drop no longer needed #include "../include/secp256k1.h"
e449af6872 Drop no longer needed `#include "../include/secp256k1.h"` (Hennadii Stepanov)

Pull request description:

  The removed header includes have not been needed since https://github.com/bitcoin-core/secp256k1/pull/1231.

  Test suggestions:
  1. Using Autottols-based build system:
  ```
  ./autogen.sh
  ./configure
  make clean-precomp
  make
  ```
  2. Using CMake-based build system:
  ```
  cmake -B build -DCMAKE_C_INCLUDE_WHAT_YOU_USE="include-what-you-use"
  cmake --build build --target secp256k1_precomputed
  ```

ACKs for top commit:
  sipa:
    utACK e449af6872
  real-or-random:
    utACK e449af6872

Tree-SHA512: 5aed7a88e1e03fcc2306c43817712c0652ecf6145679dd17f4719376818d372f619e4180bdaee548f2e82aaccbe6a2ff4c37203121d939af545128c8c48b933e
2023-06-21 09:55:02 +02:00
Tim Ruffing
5779137457 field: Document return value of fe_sqrt()
Co-authored-by: Jonas Nick <jonasd.nick@gmail.com>
2023-06-21 00:18:24 +02:00
Pieter Wuille
90e360acc2 Add doc/ellswift.md with ElligatorSwift explanation 2023-06-20 11:31:58 -04:00
Pieter Wuille
4f091847c2 Add ellswift testing to CI 2023-06-20 11:31:58 -04:00
Pieter Wuille
1bcea8c57f Add benchmarks for ellswift module 2023-06-20 11:31:58 -04:00
Pieter Wuille
2d1d41acf8 Add ctime tests for ellswift module 2023-06-20 11:31:58 -04:00
Pieter Wuille
df633cdeba Add _prefix and _bip324 ellswift_xdh hash functions 2023-06-20 11:31:58 -04:00
Pieter Wuille
9695deb351 Add tests for ellswift module
These include both test vectors taken from BIP324, as randomized unit tests.
2023-06-20 11:31:58 -04:00
Pieter Wuille
c47917bbd6 Add ellswift module implementing ElligatorSwift
The scheme implemented is described below, and largely follows the paper
"SwiftEC: Shallue–van de Woestijne Indifferentiable Function To Elliptic Curves",
by Chavez-Saab, Rodriguez-Henriquez, and Tibouchi
(https://eprint.iacr.org/2022/759).

A new 64-byte public key format is introduced, with the property that *every*
64-byte array is an encoding for a non-infinite curve point. Each curve point
has roughly 2^256 distinct encodings. This permits disguising public keys as
uniformly random bytes.

The new API functions:
* secp256k1_ellswift_encode: convert a normal public key to an ellswift 64-byte
  public key, using additional entropy to pick among the many possible
  encodings.
* secp256k1_ellswift_decode: convert an ellswift 64-byte public key to a normal
  public key.
* secp256k1_ellswift_create: a faster and safer equivalent to calling
  secp256k1_ec_pubkey_create + secp256k1_ellswift_encode.
* secp256k1_ellswift_xdh: x-only ECDH directly on ellswift 64-byte public keys,
  where the key encodings are fed to the hash function.

The scheme itself is documented in secp256k1_ellswift.h.
2023-06-20 11:31:58 -04:00
Pieter Wuille
79e5b2a8b8 Add functions to test if X coordinate is valid 2023-06-20 11:05:32 -04:00
Pieter Wuille
a597a5a9ce Add benchmark for key generation 2023-06-20 10:57:19 -04:00
Tim Ruffing
30574f22ea Merge bitcoin-core/secp256k1#1349: Normalize ge produced from secp256k1_pubkey_load
f1652528be Normalize ge produced from secp256k1_pubkey_load (stratospher)

Pull request description:

  The output `ge` in secp256k1_pubkey_load is normalized when `sizeof(secp256k1_ge_storage) = 64` but not when it's not 64. ARG_CHECK at the end of the function assumes normalization. So normalize ge in the other code path too.

  context: [#1129(comment)](https://github.com/bitcoin-core/secp256k1/pull/1129/files#r1196167066)

ACKs for top commit:
  sipa:
    utACK f1652528be
  real-or-random:
    ACK f1652528be tested by changing the two `== 64` checks to `== 65`

Tree-SHA512: 0de1caad85ccdb42053f8e09576135257c88fda88455ef25e7640049c05a1e03d1e9bae1cd132d2e6fc327fd79929257a8b21fe1cc41c82374b6cd88e6744aa3
2023-06-18 20:34:43 +02:00
Tim Ruffing
45c5ca7675 Merge bitcoin-core/secp256k1#1350: scalar: introduce and use secp256k1_{read,write}_be64 helpers
7067ee54b4 tests: add tests for `secp256k1_{read,write}_be64` (Sebastian Falbesoner)
740528caad scalar: use newly introduced `secp256k1_{read,write}_be64` helpers (4x64 impl.) (Sebastian Falbesoner)

Pull request description:

  This is a simple follow-up to #1339, as suggested in comment https://github.com/bitcoin-core/secp256k1/pull/1339#issuecomment-1587508040.

ACKs for top commit:
  stratospher:
    ACK 7067ee5.
  real-or-random:
    utACK 7067ee54b4

Tree-SHA512: f9bc2ab610099948ffac1e6bb3c822bd90b81a7110ab74cec03175e2c92ed27694a15f9cdaa7c4f1b460fe459f61c3d1d102c99592169f127fdd7539a1a0c154
2023-06-18 20:33:38 +02:00
stratospher
f1652528be Normalize ge produced from secp256k1_pubkey_load
The output ge is normalized when sizeof(secp256k1_ge_storage) = 64
but not when it's not 64. ARG_CHECK at the end of the function
assumes normalization. So normalize ge in the other code path too.
2023-06-17 10:26:19 +05:30
Sebastian Falbesoner
7067ee54b4 tests: add tests for secp256k1_{read,write}_be64
This can be reviewed with `--ignore-all-space` (or `-w`), to ignore
already existing code that was only indented.
2023-06-17 01:54:25 +02:00
Sebastian Falbesoner
740528caad scalar: use newly introduced secp256k1_{read,write}_be64 helpers (4x64 impl.) 2023-06-17 01:06:35 +02:00
Tim Ruffing
be8ff3a02a field: Static-assert that int args affecting magnitude are constant
See #1001.
2023-06-13 13:34:49 +02:00
Sebastian Falbesoner
efa76c4bf7 group: remove unneeded normalize_weak in secp256k1_ge_is_valid_var
After calculating the right-hand side of the elliptic curve equation
(x^3 + 7), the field element `x3` has a magnitude of 2 (1 as result of
`secp256k1_fe_mul`, then increased by 1 due to `secp256k1_fe_add_int`).
This is fine for `secp256k1_fe_equal_var`, as the second parameter only
requires the magnitude to not exceed 31, and the normalize_weak call can
hence be dropped.
2023-06-12 23:57:15 +02:00
Tim Ruffing
67214f5f7d Merge bitcoin-core/secp256k1#1339: scalar: refactor: use secp256k1_{read,write}_be32 helpers
887183e7de scalar: use `secp256k1_{read,write}_be32` helpers (4x64 impl.) (Sebastian Falbesoner)
52b84238de scalar: use `secp256k1_{read,write}_be32` helpers (8x32 impl.) (Sebastian Falbesoner)

Pull request description:

  This refactoring PR takes use of the `secp256k1_{read,write}_be32` helpers (introduced in PR #1093, commit 8d89b9e6e5) in the scalar <-> byte array conversion functions, for both the 8x32 and 4x64 implementations. (An alternative for the latter would be to introduce special helpers for reading/writing uint64_t in big endian `secp256k1_{read,write}_be64`).

  Verified via `objdump -D libsecp256k1.a` that `secp256k1_scalar_set_b32` for 4x64 compiles to the same code on master and the PR (`secp256k1_scalar_get_b32` is apparently always inlined) on amd64 with clang 13.0.0.

ACKs for top commit:
  sipa:
    utACK 887183e7de

Tree-SHA512: 915cb4624c6da0530dce4ec3ac48e88dd735386302cd2e15759e3c30102d81186f382ffe71493ddd0538069f1b558db543d9bb900dfdb69acb60effedc33f705
2023-06-12 18:38:35 +02:00
Jonas Nick
cb1a59275c Merge bitcoin-core/secp256k1#1341: docs: correct pubkey param descriptions for secp256k1_keypair_{xonly_,}pub
f3644287b1 docs: correct `pubkey` param descriptions for `secp256k1_keypair_{xonly_,}pub` (Sebastian Falbesoner)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK f3644287b1 because it's consistent with the other docs
  jonasnick:
    ACK f3644287b1

Tree-SHA512: cc4db4637301335ea9d23ac43bb3a78de54af79a5262dba2013945f87d80670c7ae1e106101a59c04225eb077e9a9e0ecc9d9d3bfe2d11cdc90f098ebd479f49
2023-06-12 08:43:27 +00:00
Sebastian Falbesoner
f3644287b1 docs: correct pubkey param descriptions for secp256k1_keypair_{xonly_,}pub
From an API perspective, the functions `secp256k1_keypair_pub` and
`secp256k1_keypair_xonly_pub` always succeed (i.e. return the value 1),
so the other cases in the `pubkey` parameter descriptions never happen
and can hence be removed.

Note that the "1 always" return value description was previously done in
commit b8f8b99f0f (PR #1089), which also
explains why invalid inputs for the affected functions are in practice
only possible in violation of the type system.
2023-06-11 18:44:16 +02:00
Sebastian Falbesoner
887183e7de scalar: use secp256k1_{read,write}_be32 helpers (4x64 impl.)
An alternative would be to introduce special helpers for reading/writing
uint64_t in big endian `secp256k1_{read,write}_be64`.
2023-06-10 19:50:54 +02:00
Sebastian Falbesoner
52b84238de scalar: use secp256k1_{read,write}_be32 helpers (8x32 impl.) 2023-06-10 19:21:38 +02:00
Hennadii Stepanov
e449af6872 Drop no longer needed #include "../include/secp256k1.h"
The removed header includes have not been needed since PR1231.
2023-06-06 09:07:36 +01:00
Hennadii Stepanov
747ada3587 test: Silent noisy clang warnings about Valgrind code on macOS x86_64 2023-06-04 18:25:39 +01:00
Hennadii Stepanov
5b7bf2e9d4 Use __shiftright128 intrinsic in secp256k1_u128_rshift on MSVC 2023-06-04 18:03:36 +01:00
Tim Ruffing
60556c9f49 Merge bitcoin-core/secp256k1#1337: ci: Fix error D8037 in cl.exe (attempt 2)
db29bf220c ci: Remove quirk that runs dummy command after wineserver (Tim Ruffing)
c7db4942b3 ci: Fix error D8037 in `cl.exe` (Hennadii Stepanov)
7dae115861 Revert "ci: Move wine prefix to /tmp to avoid error D8037 in cl.exe" (Hennadii Stepanov)

Pull request description:

  Since the 2146cbfaf0, the `msvc-wine` effectively initializes the WINE prefix when running the `install.sh` script. See [`install.sh`#L143](2146cbfaf0/install.sh (L143)):
  ```sh
      WINEDEBUG=-all wine64 wineboot &>/dev/null
  ```

  Our following `wine64 wineboot --init` just messes up with the prefix.

  This PR fixes this issue.

  Also https://github.com/bitcoin-core/secp256k1/pull/1327 has been reverted as apparently it does not work. And https://github.com/bitcoin-core/secp256k1/pull/1320 has been combined into this one.

ACKs for top commit:
  real-or-random:
    ACK db29bf220c

Tree-SHA512: 59e61bde0060f67501f93da8b4e193f2bfcda85d849c16bb017e38af7aa9e3b569fe2fd4aa5cdb658c3b2345cc42fad98323e329b519389b2e881ecfd403d147
2023-06-03 13:49:20 +02:00
Tim Ruffing
db29bf220c ci: Remove quirk that runs dummy command after wineserver
The underlying issue is now worked around in upstream, see
https://github.com/mstorsjo/msvc-wine/issues/47 for details.
2023-06-03 09:08:38 +01:00
Hennadii Stepanov
c7db4942b3 ci: Fix error D8037 in cl.exe 2023-06-03 09:08:31 +01:00
Hennadii Stepanov
7dae115861 Revert "ci: Move wine prefix to /tmp to avoid error D8037 in cl.exe"
This reverts commit 27504d5c94.
2023-06-02 16:13:29 +01:00
Tim Ruffing
bf29f8d0a6 Merge bitcoin-core/secp256k1#1334: fix input range comment for secp256k1_fe_add_int
605e07e365 fix input range comment for `secp256k1_fe_add_int` (Sebastian Falbesoner)

Pull request description:

  This seems to be a typo that was introduced with commit 4371f98346 (PR #1066).

ACKs for top commit:
  sipa:
    ACK 605e07e365
  real-or-random:
    ACK 605e07e365

Tree-SHA512: 7ee99cf7140c698d1146072734ba986de7328f78b2c076ee445067ef64a6a335c8669f1e733e10f5e14f98b566c799cc4c51b3eb0f036cd178b3c93476c6df2e
2023-06-01 09:38:29 +02:00
Sebastian Falbesoner
605e07e365 fix input range comment for secp256k1_fe_add_int
This seems to be a typo that was introduced with commit
4371f98346 (PR #1066).
2023-06-01 02:55:12 +02:00
Tim Ruffing
debf3e5c08 Merge bitcoin-core/secp256k1#1330: refactor: take use of secp256k1_scalar_{zero,one} constants
ade5b36701 tests: add checks for scalar constants `secp256k1_scalar_{zero,one}` (Sebastian Falbesoner)
654246c635 refactor: take use of `secp256k1_scalar_{zero,one}` constants (Sebastian Falbesoner)

Pull request description:

  Rather than allocating a (non-constant) scalar variable on the stack with the sole purpose of setting it to a constant value, the global constants `secp256k1_scalar_{zero,one}` (apparently introduced in 34a67c773b, PR #710) can be directly used instead for the values 0 or 1. There is very likely not even a difference in run-time, but it leads to simpler and less code which might be nice.

ACKs for top commit:
  sipa:
    utACK ade5b36701
  real-or-random:
    utACK ade5b36701

Tree-SHA512: 0ff05a449c153f7117a4a56efef04b2087c2330f4692f3390a0b1d95573785ac7ae3fe689ed0ec2ecc64b575d2489d6e341d32567e75a1a4b4d458c3ecd406a1
2023-05-31 19:39:05 +02:00
Tim Ruffing
d75dc59b58 Merge bitcoin-core/secp256k1#1333: test: Warn if both VERIFY and COVERAGE are defined
e83801f5db test: Warn if both `VERIFY` and `COVERAGE` are defined (Hennadii Stepanov)

Pull request description:

  Solves one item in https://github.com/bitcoin-core/secp256k1/issues/1235.

  Also see: https://github.com/bitcoin-core/secp256k1/pull/1113#discussion_r1127856040.

ACKs for top commit:
  sipa:
    utACK e83801f5db
  real-or-random:
    ACK e83801f5db

Tree-SHA512: 25e10a09ba2c3585148becd06f2a03d85306208bda333827c9ba73eb7fd94ad15536f10daf1b335703e5cb0539584f001501ce9c578f478ff1ebc1051aefde7d
2023-05-31 19:37:56 +02:00
Sebastian Falbesoner
ade5b36701 tests: add checks for scalar constants secp256k1_scalar_{zero,one} 2023-05-30 12:24:33 +02:00
Hennadii Stepanov
e83801f5db test: Warn if both VERIFY and COVERAGE are defined 2023-05-30 11:17:20 +01:00
Sebastian Falbesoner
654246c635 refactor: take use of secp256k1_scalar_{zero,one} constants 2023-05-30 12:10:41 +02:00
Tim Ruffing
908e02d596 Merge bitcoin-core/secp256k1#1328: build: Bump MSVC warning level up to W3
1549db0ca5 build: Level up MSVC warnings (Hennadii Stepanov)

Pull request description:

  Solves one item in https://github.com/bitcoin-core/secp256k1/issues/1235.

ACKs for top commit:
  sipa:
    utACK 1549db0ca5
  real-or-random:
    ACK 1549db0ca5

Tree-SHA512: 769386f734709537291ddee45c7fbee501185d3eebe9daa117d36e13e8504fabd1127857bc661a751fdf63f2eee1e7e9507121bdb020c97eb87b8758cb0879f8
2023-05-26 16:14:16 +02:00
Hennadii Stepanov
1549db0ca5 build: Level up MSVC warnings 2023-05-25 09:43:55 +01:00
Tim Ruffing
20a5da5fb1 Merge bitcoin-core/secp256k1#1310: Refine release process
ad84603297 release process: clarify change log updates (Jonas Nick)
6348bc7eee release process: fix process for maintenance release (Jonas Nick)
79fa50b082 release process: mention targeted release schedule (Jonas Nick)
165206789b release process: add sanity checks (Jonas Nick)

Pull request description:

  Fixes #1176

ACKs for top commit:
  real-or-random:
    ACK ad84603297
  hebasto:
    re-ACK ad84603297

Tree-SHA512: 215b469f4ecc6ecb2b07ba4d29b6b01fc0dda752d9cfffc3f5ec518f2efb5ec9ae027056b113758fadbebcdfdd549ff5803c3d7257761da6e3859ff6131cc137
2023-05-24 15:50:06 +02:00
Jonas Nick
05873bb6b1 tweak_add: fix API doc for tweak=0 2023-05-24 13:48:42 +00:00
Jonas Nick
ad84603297 release process: clarify change log updates 2023-05-24 13:43:29 +00:00
Jonas Nick
6348bc7eee release process: fix process for maintenance release 2023-05-24 13:43:29 +00:00
Jonas Nick
79fa50b082 release process: mention targeted release schedule 2023-05-24 13:43:28 +00:00
Jonas Nick
165206789b release process: add sanity checks 2023-05-24 13:43:25 +00:00
Tim Ruffing
09df0bfb23 Merge bitcoin-core/secp256k1#1327: ci: Move wine prefix to /tmp to avoid error D8037 in cl.exe
27504d5c94 ci: Move wine prefix to /tmp to avoid error D8037 in cl.exe (Tim Ruffing)

Pull request description:

  Don't ask me why this makes a difference. It may be some permission problem even though everything in Cirrus CI runs as root anyway. In any case, I'll probably get mad if I investigate this further.

  Fixes #1326.

ACKs for top commit:
  hebasto:
    ACK 27504d5c94, tested in my personal Cirrus account.

Tree-SHA512: 08bb1734827579b59c705a44ee8fad6d504031eb5659c2743649be95fb048794b95ac0869a994bfa732f7f0714b4d12674c325637fe079b2266f18a3c14bbec0
2023-05-24 15:36:01 +02:00
Tim Ruffing
27504d5c94 ci: Move wine prefix to /tmp to avoid error D8037 in cl.exe
Don't ask me why this makes a difference. It may be some permission
problem even though everything in Cirrus CI runs as root anyway. In
any case, I'll probably get mad if I investigate this further.

Fixes #1326.
2023-05-24 14:28:05 +02:00
Tim Ruffing
d373a7215b Merge bitcoin-core/secp256k1#1316: Do not invoke fe_is_zero on failed set_b32_limit
6433175ffe Do not invoke fe_is_zero on failed set_b32_limit (Pieter Wuille)

Pull request description:

  Noticed in the CI output of #1313 (https://cirrus-ci.com/task/5117786435878912)

  The code violates the field element contract that states that a field element that comes out of a failed `secp256k1_fe_set_b32_limit` call cannot be used before overwriting it. This is not an issue in practice, as such failure can only occur with negligible probability, but the experimental compiler in that CI setting is technically correct in detecting this possibility.

  Fix it by setting it to 1 based on a `secp256k1_fe_normalizes_to_zero` test rather than a `secp256k1_fe_is_zero` one (which does not require normalization).

ACKs for top commit:
  stratospher:
    ACK 6433175
  real-or-random:
    utACK 6433175ffe

Tree-SHA512: 49da4535181c4607c1f4d23d1fd7cd65e7751c7cfa68643f1da77f3ec7961754fc8553bb415137fd61d86c805fe69f5adf97c05b9dc4d3bf357ae7c6409cc51a
2023-05-23 13:34:03 +02:00
Pieter Wuille
6433175ffe Do not invoke fe_is_zero on failed set_b32_limit 2023-05-19 08:40:28 -04:00
Tim Ruffing
5f7903c73c Merge bitcoin-core/secp256k1#1318: build: Enable -DVERIFY for precomputation binaries
5768b50229 build: Enable -DVERIFY for precomputation binaries (Tim Ruffing)

Pull request description:

  because... why not?!

  I realized that this can't hurt when working on #1313.

ACKs for top commit:
  sipa:
    ACK 5768b50229

Tree-SHA512: 2412cb93097f5c7904cfded6816bc5cdc69d958b4023ddaffd6e7575615ac5bfcd3a7cfc9ce2c0b0e6526a6f000dd84ecd32909d9d207a3644aadb5d34905911
2023-05-19 10:05:19 +02:00
Tim Ruffing
e9e4526a4e Merge bitcoin-core/secp256k1#1317: Make fe_cmov take max of magnitudes
31b4bbee1e Make fe_cmov take max of magnitudes (Pieter Wuille)

Pull request description:

  This addresses part of #1001.

  The magnitude and normalization of the output of `secp256k1_fe_cmov` should not depend on the runtime value of `flag`.

ACKs for top commit:
  real-or-random:
    utACK 31b4bbee1e
  stratospher:
    ACK 31b4bbe.

Tree-SHA512: 08bef9f63797cb8a1f3ea63c716c09aaa267dfee285b74ef5fbb47d614569d2787ec73d21bce080214872dfe70246f73cea42ad3c24e6baccecabe3312f71433
2023-05-19 09:55:08 +02:00
Tim Ruffing
5768b50229 build: Enable -DVERIFY for precomputation binaries 2023-05-17 23:28:36 +02:00
Pieter Wuille
31b4bbee1e Make fe_cmov take max of magnitudes 2023-05-15 09:36:55 -04:00
Tim Ruffing
ff33018fe7 Merge ElementsProject/secp256k1-zkp#232: Backports from libsecp256k1 v0.3.2
39407c3f59 Mark stack variables as early clobber for technical correctness (Pieter Wuille)
56a5d41429 Bugfix: mark outputs as early clobber in scalar x86_64 asm (Pieter Wuille)
c8c0f55a11 ct: Be cautious and use volatile trick in more "conditional" paths (Tim Ruffing)
3e94289966 ct: Use volatile trick in scalar_cond_negate (Tim Ruffing)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 39407c3f59 I also verified that the ct time tests pass on GCC 13.1.1 and Clang 15.0.7.

Tree-SHA512: b7e695527ea58cc7b94a5f2fff6473b6779a469bc5c38baf92624b655cbdf303fbd204e6c1395fa02b98db3bc47bab32afe64bae4ab4fab18da856b621aab070
2023-05-14 20:21:19 +02:00
Pieter Wuille
39407c3f59 Mark stack variables as early clobber for technical correctness
In the field 5x52 asm for x86_64, stack variables are provided as outputs.
The existing inputs are all forcibly allocated to registers, so cannot
coincide, but mark them as early clobber anyway to make this clearer.
2023-05-14 17:20:10 +00:00
Pieter Wuille
56a5d41429 Bugfix: mark outputs as early clobber in scalar x86_64 asm
In the existing code, the compiler is allowed to allocate the RSI register
for outputs m0, m1, or m2, which are written to before the input in RSI is
read from. Fix this by marking them as early clobber.

Reported by ehoffman2 in https://github.com/bitcoin-core/secp256k1/issues/766
2023-05-14 17:20:01 +00:00
Tim Ruffing
c8c0f55a11 ct: Be cautious and use volatile trick in more "conditional" paths
- secp256k1_scalar_cadd_bit
 - secp256k1_modinvXX_normalize_YY
 - secp256k1_modinvXX_divsteps_ZZ
 - ECMULT_CONST_TABLE_GET_GE

Even though those code loations are not problematic right now
(with current compilers).
2023-05-14 17:19:04 +00:00
Tim Ruffing
3e94289966 ct: Use volatile trick in scalar_cond_negate 2023-05-14 17:16:50 +00:00
Tim Ruffing
83186db34a Merge bitcoin-core/secp256k1#1314: release cleanup: bump version after 0.3.2
95448ef2f8 release cleanup: bump version after 0.3.2 (Pieter Wuille)

Pull request description:

ACKs for top commit:
  hebasto:
    ACK 95448ef2f8
  real-or-random:
    ACK 95448ef2f8

Tree-SHA512: 82724afd8c4b3a383a9a6b6db787fe9dd8dabd76df896a5e1d1a90733ef1c6a2fbbd6dd1d82faee359eb98fe3c636fb31ec659d49e70e17c649ded6155b9a71d
2023-05-13 19:55:44 +02:00
Pieter Wuille
95448ef2f8 release cleanup: bump version after 0.3.2 2023-05-13 13:54:32 -04:00
Tim Ruffing
acf5c55ae6 Merge bitcoin-core/secp256k1#1312: release: Prepare for 0.3.2
d490ca2046 release: Prepare for 0.3.2 (Tim Ruffing)

Pull request description:

ACKs for top commit:
  sipa:
    ACK d490ca2046
  hebasto:
    ACK d490ca2046
  jonasnick:
    ACK d490ca2046

Tree-SHA512: 0785e9654974b25977dcdb00fe2e91d79a941143d278e315b96238e18c7aedd5814c2534c0aff356d8d4bb456ff8b815bea3657b99243e0a8296bbe635329cfb
2023-05-13 19:41:35 +02:00
Tim Ruffing
d490ca2046 release: Prepare for 0.3.2 2023-05-12 22:52:30 +02:00
Tim Ruffing
3e3d125b83 Merge bitcoin-core/secp256k1#1309: changelog: Catch up
697e1ccf4a changelog: Catch up (Tim Ruffing)
76b43f3443 changelog: Add entry for #1303 (Tim Ruffing)

Pull request description:

ACKs for top commit:
  sipa:
    ACK 697e1ccf4a
  jonasnick:
    ACK 697e1ccf4a

Tree-SHA512: cfeb513effc69925bdedd3a298b1e2e5bf7709f68b453a5f157c584560b5400c3dc8b9ce87a775281cdea9db7f44e7e1337fbc93563f6efe350fe5defacbc4f6
2023-05-12 17:26:29 +02:00
Pieter Wuille
e8295d07ab Merge bitcoin-core/secp256k1#1311: Revert "Remove unused scratch space from API"
3ad1027a40 Revert "Remove unused scratch space from API" (Jonas Nick)

Pull request description:

  This reverts commit 712e7f8722.

  Removing the scratch space from the API may break bindings to the library.

ACKs for top commit:
  sipa:
    ACK 3ad1027a40
  real-or-random:
    ACK 3ad1027a40

Tree-SHA512: ad394c0a2f83fe3a5f400c0e8f2b9bf40037ce4141d4414e6345918f5e6003c61da02a538425a49bdeb5700f5ecb713bd58f5752c0715fb1fcc4950099fdc0e6
2023-05-12 11:14:57 -04:00
Tim Ruffing
697e1ccf4a changelog: Catch up 2023-05-12 17:09:00 +02:00
Jonas Nick
3ad1027a40 Revert "Remove unused scratch space from API"
This reverts commit 712e7f8722.
2023-05-12 15:05:57 +00:00
Tim Ruffing
76b43f3443 changelog: Add entry for #1303 2023-05-12 16:44:03 +02:00
Jonas Nick
7d4f86d242 Merge bitcoin-core/secp256k1#1307: Mark more assembly outputs as early clobber
8c9ae37a5a Add release note (Pieter Wuille)
350b4bd6e6 Mark stack variables as early clobber for technical correctness (Pieter Wuille)
0c729ba70d Bugfix: mark outputs as early clobber in scalar x86_64 asm (Pieter Wuille)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 8c9ae37a5a
  jonasnick:
    ACK 8c9ae37a5a

Tree-SHA512: 874d01f5540d14b5188aec25f6441dbc6631f8d3980416040a3e250f1aef75150068415e7a458a9a3fb0d7cbdeb97f5c7e089b187d6d3dd79aa6e45274c241b6
2023-05-12 13:37:09 +00:00
Tim Ruffing
b54a0672ef Merge bitcoin-core/secp256k1#1304: build: Rename arm to arm32 and check if it's really supported
c6bb29b303 build: Rename `64bit` to `x86_64` (Hennadii Stepanov)
03246457a8 autotools: Add `SECP_ARM32_ASM_CHECK` macro (Hennadii Stepanov)
ed4ba238e2 cmake: Add `check_arm32_assembly` function (Hennadii Stepanov)
e5cf4bf3ff build: Rename `arm` to `arm32` (Hennadii Stepanov)

Pull request description:

  Closes https://github.com/bitcoin-core/secp256k1/issues/1034.

  Solves one item in https://github.com/bitcoin-core/secp256k1/issues/1235.

ACKs for top commit:
  real-or-random:
    ACK c6bb29b303 tested on x86_64 but not on ARM

Tree-SHA512: c3615a18cfa30bb2cc53be18c09ccab08fc800b84444d8c6b333347b4db039a3981da61e7da5086dd9f4472838d7c031d554be9ddc7c435ba906852bba593982
2023-05-12 14:58:32 +02:00
Hennadii Stepanov
c6bb29b303 build: Rename 64bit to x86_64 2023-05-12 10:50:18 +01:00
Pieter Wuille
8c9ae37a5a Add release note 2023-05-12 05:47:59 -04:00
Jonas Nick
edcba04c28 Merge elementsproject/secp256k1-zkp#231: musig: add note about missing verification to partial_sign to doc
4ab4ec38a0 musig: add note about missing verification to partial_sign to doc (Jonas Nick)
f50ad76004 musig: update version number of BIP (Jonas Nick)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 4ab4ec38a0

Tree-SHA512: 1e35d83dd97bac96dfbc02d58841582afe67c38562c728bc3c593a797e1316dfdd550c4988dc78557f25a1633711ec13b35f6c5bae0f7dd29c9f1c994ad5c82c
2023-05-12 09:40:51 +00:00
Hennadii Stepanov
03246457a8 autotools: Add SECP_ARM32_ASM_CHECK macro 2023-05-12 10:38:51 +01:00
Hennadii Stepanov
ed4ba238e2 cmake: Add check_arm32_assembly function 2023-05-12 10:38:50 +01:00
Pieter Wuille
350b4bd6e6 Mark stack variables as early clobber for technical correctness
In the field 5x52 asm for x86_64, stack variables are provided as outputs.
The existing inputs are all forcibly allocated to registers, so cannot
coincide, but mark them as early clobber anyway to make this clearer.
2023-05-12 05:23:11 -04:00
Pieter Wuille
0c729ba70d Bugfix: mark outputs as early clobber in scalar x86_64 asm
In the existing code, the compiler is allowed to allocate the RSI register
for outputs m0, m1, or m2, which are written to before the input in RSI is
read from. Fix this by marking them as early clobber.

Reported by ehoffman2 in https://github.com/bitcoin-core/secp256k1/issues/766
2023-05-12 05:23:07 -04:00
Pieter Wuille
3353d3c753 Merge bitcoin-core/secp256k1#1207: Split fe_set_b32 into reducing and normalizing variants
5b32602295 Split fe_set_b32 into reducing and normalizing variants (Pieter Wuille)

Pull request description:

  Follow-up to #1205.

  This splits the `secp256k1_fe_set_b32` function into two variants:
  * `secp256k1_fe_set_b32_mod`, which returns `void`, reduces modulo the curve order, and only promises weakly normalized output.
  * `secp256k1_fe_set_b32_limit`, which returns `int` indicating success/failure, and only promises valid output in case the input is in range (but guarantees it's strongly normalized in this case).

  This removes one of the few cases in the codebase where normalization status depends on runtime values, making it fixed at compile-time instead.

ACKs for top commit:
  real-or-random:
    ACK 5b32602295
  jonasnick:
    ACK 5b32602295

Tree-SHA512: 4b93502272638c6ecdef4d74afa629e7ee540c0a20b377dccedbe567857b56c4684fad3af4b4293ed7ba35fed4aa5d0beaacdd77a903f44f24e8d87305919b61
2023-05-11 16:06:15 -04:00
Jonas Nick
4ab4ec38a0 musig: add note about missing verification to partial_sign to doc 2023-05-11 17:50:18 +00:00
Jonas Nick
f50ad76004 musig: update version number of BIP 2023-05-11 17:50:06 +00:00
Pieter Wuille
5b32602295 Split fe_set_b32 into reducing and normalizing variants 2023-05-11 13:49:33 -04:00
Jonas Nick
006ddc1f42 Merge bitcoin-core/secp256k1#1306: build: Make tests work with external default callbacks
1907f0f166 build: Make tests work with external default callbacks (Tim Ruffing)

Pull request description:

ACKs for top commit:
  sipa:
    ACK 1907f0f166
  jonasnick:
    ACK 1907f0f166

Tree-SHA512: 198598f7bf5292bf5709187f9a40ddf9a0fba93e8b62afb49df2c05b4ef61c394cea43ee07615b51ceea97862228d8ad351fddef13c190cb2e6690943ed63128
2023-05-11 17:31:29 +00:00
Tim Ruffing
1907f0f166 build: Make tests work with external default callbacks 2023-05-11 19:08:35 +02:00
Jonas Nick
fb3a806365 Merge bitcoin-core/secp256k1#1133: schnorrsig: Add test vectors for variable-length messages
cd54ac7c1c schnorrsig: Improve docs of schnorrsig_sign_custom (Tim Ruffing)
28687b0312 schnorrsig: Add BIP340 varlen test vectors (Tim Ruffing)
97a98bed1e schnorrsig: Refactor test vector code to allow varlen messages (Tim Ruffing)

Pull request description:

ACKs for top commit:
  sipa:
    ACK cd54ac7c1c. I didn't verify the included test vectors match the BIP.
  jonasnick:
    ACK cd54ac7c1c

Tree-SHA512: 268140e239b703aaf79825de2263675a8c31bef999f013ea532b0cd7b80f2d600d78f3872209a93774ba4dbc0a046108e87d151fc4604882c5636876026a0816
2023-05-11 16:44:08 +00:00
Tim Ruffing
cd54ac7c1c schnorrsig: Improve docs of schnorrsig_sign_custom 2023-05-11 18:36:42 +02:00
Tim Ruffing
28687b0312 schnorrsig: Add BIP340 varlen test vectors 2023-05-11 18:36:42 +02:00
Tim Ruffing
97a98bed1e schnorrsig: Refactor test vector code to allow varlen messages 2023-05-11 18:36:42 +02:00
Jonas Nick
ab5a917128 Merge bitcoin-core/secp256k1#1303: ct: Use more volatile
17fa21733a ct: Be cautious and use volatile trick in more "conditional" paths (Tim Ruffing)
5fb336f9ce ct: Use volatile trick in scalar_cond_negate (Tim Ruffing)

Pull request description:

ACKs for top commit:
  sipa:
    ACK 17fa21733a
  jonasnick:
    ACK 17fa21733a

Tree-SHA512: 4a0fbee7b1cce4f4647bff697c0e645d93aa8fb49777feef5eb1e1eadce2116bafdcc6175c066ee4fe4bf1340047311e2d7d2c48bb288867a837ecd6c8687121
2023-05-11 16:14:44 +00:00
Tim Ruffing
9eb6934f69 Merge bitcoin-core/secp256k1#1305: Remove unused scratch space from API
712e7f8722 Remove unused scratch space from API (Jonas Nick)

Pull request description:

  Not sure if we want the typedef and `secp256k1_scratch_space_{create,destroy}` but if we don't keep them then this PR will be a rather large diff.

ACKs for top commit:
  sipa:
    ACK 712e7f8722
  real-or-random:
    utACK 712e7f8722

Tree-SHA512: b3a8feb0fe4639d5e48b708ccbf355bca5da658a291f63899086d2bbeb6d0ab33e3dcd55d8984ec7fa803f757b7d02e71bcb7e7eeecaab52ffc70ae85dce8c44
2023-05-11 18:07:53 +02:00
Jonas Nick
073d98a076 Merge bitcoin-core/secp256k1#1292: refactor: Make 64-bit shift explicit
d1e48e5474 refactor: Make 64-bit shift explicit (Hennadii Stepanov)
b2e29e43d0 ci: Treat all compiler warnings as errors in "Windows (VS 2022)" task (Hennadii Stepanov)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK d1e48e5474
  jonasnick:
    ACK d1e48e5474

Tree-SHA512: fd07c8c136b1c947900d45b5a4ad4963e2c29884aca62a26be07713dfd1b0c5e7655f07a0b99217fc055bf3266e71cb5edabbd4d5c145a172b4be5d10f7ad51c
2023-05-11 15:06:47 +00:00
Tim Ruffing
17fa21733a ct: Be cautious and use volatile trick in more "conditional" paths
- secp256k1_scalar_cadd_bit
 - secp256k1_modinvXX_normalize_YY
 - secp256k1_modinvXX_divsteps_ZZ
 - ECMULT_CONST_TABLE_GET_GE

Even though those code loations are not problematic right now
(with current compilers).
2023-05-11 16:32:07 +02:00
Tim Ruffing
5fb336f9ce ct: Use volatile trick in scalar_cond_negate 2023-05-11 16:32:07 +02:00
Jonas Nick
712e7f8722 Remove unused scratch space from API 2023-05-11 13:39:56 +00:00
Pieter Wuille
54d34b6c24 Merge bitcoin-core/secp256k1#1300: Avoid normalize conditional on VERIFY
97c63b9039 Avoid normalize conditional on VERIFY (Pieter Wuille)

Pull request description:

  In the old code, `secp256k1_gej_rescale` requires a normalized input in VERIFY mode, but not otherwise. Its requirements shouldn't depend on this mode being enabled or not.

ACKs for top commit:
  real-or-random:
    utACK 97c63b9039 I've also verified that the loop in secp256k1_ecmult_strauss_wnaf holds up the invariant that the magnitude of Z is 1, even with the normalization removed
  jonasnick:
    ACK 97c63b9039

Tree-SHA512: 9598c133c6f4e488c74512089dabe0508529f20ca782be1c8fbeae9d7f132da9d570a061053acd3d245a9a187abf1f2581207441ce6aac8d0f8972cf357a349f
2023-05-11 08:30:21 -04:00
Pieter Wuille
c63ec88ebf Merge bitcoin-core/secp256k1#1066: Abstract out and merge all the magnitude/normalized logic
7fc642fa25 Simplify secp256k1_fe_{impl_,}verify (Pieter Wuille)
4e176ad5b9 Abstract out verify logic for fe_is_square_var (Pieter Wuille)
4371f98346 Abstract out verify logic for fe_add_int (Pieter Wuille)
89e324c6b9 Abstract out verify logic for fe_half (Pieter Wuille)
283cd80ab4 Abstract out verify logic for fe_get_bounds (Pieter Wuille)
d5aa2f0358 Abstract out verify logic for fe_inv{,_var} (Pieter Wuille)
3167646072 Abstract out verify logic for fe_from_storage (Pieter Wuille)
76d31e5047 Abstract out verify logic for fe_to_storage (Pieter Wuille)
1e6894bdd7 Abstract out verify logic for fe_cmov (Pieter Wuille)
be82bd8e03 Improve comments/checks for fe_sqrt (Pieter Wuille)
6ab35082ef Abstract out verify logic for fe_sqr (Pieter Wuille)
4c25f6efbd Abstract out verify logic for fe_mul (Pieter Wuille)
e179e651cb Abstract out verify logic for fe_add (Pieter Wuille)
7e7ad7ff57 Abstract out verify logic for fe_mul_int (Pieter Wuille)
65d82a3445 Abstract out verify logic for fe_negate (Pieter Wuille)
144670893e Abstract out verify logic for fe_get_b32 (Pieter Wuille)
f7a7666aeb Abstract out verify logic for fe_set_b32 (Pieter Wuille)
ce4d2093e8 Abstract out verify logic for fe_cmp_var (Pieter Wuille)
7d7d43c6dd Improve comments/check for fe_equal{,_var} (Pieter Wuille)
c5e788d672 Abstract out verify logic for fe_is_odd (Pieter Wuille)
d3f3fe8616 Abstract out verify logic for fe_is_zero (Pieter Wuille)
c701d9a471 Abstract out verify logic for fe_clear (Pieter Wuille)
19a2bfeeea Abstract out verify logic for fe_set_int (Pieter Wuille)
864f9db491 Abstract out verify logic for fe_normalizes_to_zero{,_var} (Pieter Wuille)
6c31371120 Abstract out verify logic for fe_normalize_var (Pieter Wuille)
e28b51f522 Abstract out verify logic for fe_normalize_weak (Pieter Wuille)
b6b6f9cb97 Abstract out verify logic for fe_normalize (Pieter Wuille)
7fa5195559 Bugfix: correct SECP256K1_FE_CONST mag/norm fields (Pieter Wuille)
b29566c51b Merge magnitude/normalized fields, move/improve comments (Pieter Wuille)

Pull request description:

  Right now, all the logic for propagating/computing the magnitude/normalized fields in `secp256k1_fe` (when `VERIFY` is defined) and the code for checking it, is duplicated across the two field implementations. I believe that is undesirable, as these properties should purely be a function of the performed fe_ functions, and not of the choice of field implementation. This becomes even uglier with #967, which would copy all that, and even needs an additional dimension that would then need to be added to the two other fields. It's also related to #1001, which I think will become easier if it doesn't need to be done/reasoned about separately for every field.

  This PR moves all logic around these fields (collectively called field verification) to implementations in field_impl.h, which dispatch to renamed functions in field_*_impl.h for the actual implementation.

  Fixes #1060.

ACKs for top commit:
  jonasnick:
    ACK 7fc642fa25
  real-or-random:
    ACK 7fc642fa25

Tree-SHA512: 0f94e13fedc47e47859261a182c4077308f8910495691f7e4d7877d9298385172c70e98b4a1e270b6bde4d0062b932607106306bdb35a519cdeab9695a5c71e4
2023-05-11 08:23:48 -04:00
Pieter Wuille
7fc642fa25 Simplify secp256k1_fe_{impl_,}verify 2023-05-11 06:25:59 -04:00
Pieter Wuille
4e176ad5b9 Abstract out verify logic for fe_is_square_var 2023-05-11 06:25:56 -04:00
Pieter Wuille
4371f98346 Abstract out verify logic for fe_add_int 2023-05-11 06:25:19 -04:00
Pieter Wuille
89e324c6b9 Abstract out verify logic for fe_half 2023-05-11 06:25:15 -04:00
Pieter Wuille
283cd80ab4 Abstract out verify logic for fe_get_bounds 2023-05-11 06:24:26 -04:00
Pieter Wuille
d5aa2f0358 Abstract out verify logic for fe_inv{,_var} 2023-05-11 06:24:26 -04:00
Pieter Wuille
3167646072 Abstract out verify logic for fe_from_storage 2023-05-11 06:24:26 -04:00
Pieter Wuille
76d31e5047 Abstract out verify logic for fe_to_storage 2023-05-11 06:24:26 -04:00
Pieter Wuille
1e6894bdd7 Abstract out verify logic for fe_cmov 2023-05-11 06:24:26 -04:00
Pieter Wuille
be82bd8e03 Improve comments/checks for fe_sqrt 2023-05-11 06:24:22 -04:00
Pieter Wuille
6ab35082ef Abstract out verify logic for fe_sqr 2023-05-11 06:18:40 -04:00
Pieter Wuille
4c25f6efbd Abstract out verify logic for fe_mul 2023-05-11 06:18:40 -04:00
Pieter Wuille
e179e651cb Abstract out verify logic for fe_add 2023-05-11 06:18:40 -04:00
Pieter Wuille
7e7ad7ff57 Abstract out verify logic for fe_mul_int 2023-05-11 06:18:40 -04:00
Pieter Wuille
65d82a3445 Abstract out verify logic for fe_negate 2023-05-11 06:18:40 -04:00
Pieter Wuille
144670893e Abstract out verify logic for fe_get_b32 2023-05-11 06:18:40 -04:00
Pieter Wuille
f7a7666aeb Abstract out verify logic for fe_set_b32 2023-05-11 06:18:40 -04:00
Pieter Wuille
ce4d2093e8 Abstract out verify logic for fe_cmp_var 2023-05-11 06:18:40 -04:00
Pieter Wuille
7d7d43c6dd Improve comments/check for fe_equal{,_var} 2023-05-11 06:18:40 -04:00
Pieter Wuille
c5e788d672 Abstract out verify logic for fe_is_odd 2023-05-11 06:18:40 -04:00
Pieter Wuille
d3f3fe8616 Abstract out verify logic for fe_is_zero 2023-05-11 06:18:40 -04:00
Pieter Wuille
c701d9a471 Abstract out verify logic for fe_clear 2023-05-11 06:18:40 -04:00
Pieter Wuille
19a2bfeeea Abstract out verify logic for fe_set_int 2023-05-11 06:18:40 -04:00
Pieter Wuille
864f9db491 Abstract out verify logic for fe_normalizes_to_zero{,_var} 2023-05-11 06:18:40 -04:00
Pieter Wuille
6c31371120 Abstract out verify logic for fe_normalize_var 2023-05-11 06:18:40 -04:00
Pieter Wuille
e28b51f522 Abstract out verify logic for fe_normalize_weak 2023-05-11 06:18:40 -04:00
Pieter Wuille
b6b6f9cb97 Abstract out verify logic for fe_normalize 2023-05-11 06:18:40 -04:00
Pieter Wuille
7fa5195559 Bugfix: correct SECP256K1_FE_CONST mag/norm fields 2023-05-11 06:18:37 -04:00
Hennadii Stepanov
e5cf4bf3ff build: Rename arm to arm32 2023-05-11 10:03:23 +01:00
Pieter Wuille
b29566c51b Merge magnitude/normalized fields, move/improve comments
Also split secp256k1_fe_verify into a generic and an implementation
specific part.
2023-05-11 04:25:19 -04:00
Pieter Wuille
97c63b9039 Avoid normalize conditional on VERIFY 2023-05-11 03:41:48 -04:00
Tim Ruffing
341cc19726 Merge bitcoin-core/secp256k1#1299: Infinity handling: ecmult_const(infinity) works, and group verification
bbc834467c Avoid secp256k1_ge_set_gej_zinv with uninitialized z (Pieter Wuille)
0a2e0b2ae4 Make secp256k1_{fe,ge,gej}_verify work as no-op if non-VERIFY (Pieter Wuille)
f20266722a Add invariant checking to group elements (Pieter Wuille)
a18821d5b1 Always initialize output coordinates in secp256k1_ge_set_gej (Pieter Wuille)
3086cb90ac Expose secp256k1_fe_verify to other modules (Pieter Wuille)
a0e696fd4d Make secp256k1_ecmult_const handle infinity (Gregory Maxwell)

Pull request description:

  Rebase of #791.

  * Clean up infinity handling, make x/y/z always initialized for infinity.
  * Make secp256k1_ecmult_const handle infinity.
    * Infinity isn't currently needed here, but correctly handling it is a little more safe against future changes.
    * Update docs for it to make it clear that it is not constant time in Q. It never was constant time in Q (and would be a little complicated to make constant time in Q: needs a constant time addition function that tracks RZR). It isn't typical for ECDH to be constant time in terms of the pubkey. If it was later made constant time in Q infinity support would be easy to preserve, e.g. by running it on a dummy value and cmoving infinity into the output.
  * Add group verification (`secp256k1_ge_verify` and `secp256k1_gej_verify`, mimicking `secp256k1_fe_verify`).
  * Make the `secp256k1_{fe,ge,gej}_verify` functions also defined (as no-ops) in non-VERIFY mode.

ACKs for top commit:
  jonasnick:
    ACK bbc834467c
  real-or-random:
    ACK bbc834467c

Tree-SHA512: 82cb51faa2c207603aa10359a311ea618fcb5a81ba175bf15515bf84043223db6428434875854cdfce9ae95f9cfd68c74e4e415f26bd574f1791b5dec1615d19
2023-05-10 18:44:18 +02:00
Pieter Wuille
6ec3731e8c Simplify test PRNG implementation 2023-05-10 10:40:08 -04:00
Pieter Wuille
bbc834467c Avoid secp256k1_ge_set_gej_zinv with uninitialized z 2023-05-10 09:25:09 -04:00
Pieter Wuille
0a2e0b2ae4 Make secp256k1_{fe,ge,gej}_verify work as no-op if non-VERIFY 2023-05-10 09:25:09 -04:00
Pieter Wuille
f20266722a Add invariant checking to group elements 2023-05-10 09:25:09 -04:00
Pieter Wuille
a18821d5b1 Always initialize output coordinates in secp256k1_ge_set_gej 2023-05-10 09:25:06 -04:00
Pieter Wuille
3086cb90ac Expose secp256k1_fe_verify to other modules 2023-05-10 09:06:02 -04:00
Gregory Maxwell
a0e696fd4d Make secp256k1_ecmult_const handle infinity
Infinity isn't currently needed here, but correctly handling it is a
little more safe against future changes.

Update docs for it to make it clear that it is not constant time in A
(the input point). It never was constant time in Q (and would be a little
complicated to make constant time in A).

If it was later made constant time in A, infinity support would be easy
to preserve, e.g. by running it on a dummy value and cmoving infinity into
the output.
2023-05-10 09:06:02 -04:00
Tim Ruffing
24c768ae09 Merge bitcoin-core/secp256k1#1301: Avoid using bench_verify_data as bench_sign_data; merge them
2e65f1fdbc Avoid using bench_verify_data as bench_sign_data; merge them (Pieter Wuille)

Pull request description:

  The existing bench.c code defines `bench_verify_data data` variable, but some of the benchmarks then use it as `bench_sign`. Fix this by merging the two types into one.

ACKs for top commit:
  stratospher:
    ACK 2e65f1f.
  real-or-random:
    utACK 2e65f1fdbc

Tree-SHA512: 676b43e5d30abd13bfd9595378b1a0bd90a2e713be4f8f713260f989ea8c971b229dfb683cd7a1614665b1688a0bdda7a4019f358dd6cd645e1b3d9f8d71e814
2023-05-10 10:03:25 +02:00
Pieter Wuille
2e65f1fdbc Avoid using bench_verify_data as bench_sign_data; merge them 2023-05-09 14:00:43 -04:00
Tim Ruffing
fb5bfa4eed Add static test vector for Xoshiro256++ 2023-05-09 18:11:29 +02:00
Jonas Nick
1cf15ebd94 Merge bitcoin-core/secp256k1#1296: docs: complete interface description for secp256k1_schnorrsig_sign_custom
149c41cee1 docs: complete interface description for `secp256k1_schnorrsig_sign_custom` (Sebastian Falbesoner)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK 149c41cee1
  jonasnick:
    ACK 149c41cee1

Tree-SHA512: ee677ed6b474b547066ce149688edab7ba6d2572acfbc0989256a669341fff4cf2e17b451cd3fc6fff3944a896647f0f5c1411056678505fa85ba71e8cfe6229
2023-05-09 10:44:27 +00:00
Jonas Nick
4eab2c2fd8 Merge elementsproject/secp256k1-zkp#230: norm arg: add prove test vectors
f3126fdfec norm arg: remove prove edge tests which are now covered by vectors (Jonas Nick)
847ed9ecb2 norm arg: add verification to prove vectors (Jonas Nick)
cf797ed2a4 norm arg: add prove test vectors (Jonas Nick)
095c1e749c norm arg: add prove_const to tests (Jonas Nick)
bf7bf8a64f norm arg: split norm_arg_zero into prove_edge and verify_zero_len (Jonas Nick)
a70c4d4a8a norm arg: add test vector for |n| = 0 (Jonas Nick)
f5e4b16f0f norm arg: add test vector for sign bit malleability (Jonas Nick)
c0de361fc5 norm arg: allow X and R to be the point at infinity (Jonas Nick)
f22834f202 norm arg: add verify vector for n = [0], l = [0] (Jonas Nick)
d8e7f3763b musig: move ge_{serialize,parse}_ext to module-independent file (Jonas Nick)

Pull request description:

ACKs for top commit:
  Liam-Eagen:
    ACK f3126fd

Tree-SHA512: 1aad86521fce74435beabe7690c7fcc38ad9ae7a884ddcab69ef825b573433f700723a7672d29df1b4465bc33d5957b6a46f657f988cfd2cc73fa94a3472357d
2023-05-09 10:42:07 +00:00
Pieter Wuille
723e8ca8f7 Remove randomness tests
Our RNG has been replaced with Xoshiro256++, a well-analyzed RNG. Our
unit tests should not be resposible for verifying its statistical
qualities.
2023-05-08 12:17:33 -04:00
Cory Fields
bc7c8db179 abi: Use dllexport for mingw builds
This should fix mingw exports, specifically hiding the following:
secp256k1_pre_g_128
secp256k1_pre_g
secp256k1_ecmult_gen_prec_table

This changes our visibility macros to look more like gcc's recommendation:
https://gcc.gnu.org/wiki/Visibility#How_to_use_the_new_C.2B-.2B-_visibility_support
2023-05-08 15:25:26 +00:00
Sebastian Falbesoner
149c41cee1 docs: complete interface description for secp256k1_schnorrsig_sign_custom
For the sake of completeness, add the missing descriptions for the
return value and parameters (`ctx`, `sig64`, `keypair`), in the same
wording/style as for the function `secp256k1_schnorrsig_sign32`.
2023-05-08 13:09:42 +02:00
Tim Ruffing
f30c74866b Merge bitcoin-core/secp256k1#1270: cmake: Fix library ABI versioning
bef448f9af cmake: Fix library ABI versioning (Hennadii Stepanov)

Pull request description:

  This change emulates Libtool to make sure Libtool and CMake agree on the ABI version.

  To test, one needs to simulate a release with backward-compatible API changes, which means the following changes in `configure.ac` and `CMakeLists.txt`:
  - incrementing of `*_LIB_VERSION_CURRENT`
  - setting `*_LIB_VERSION_REVISION` to zero
  - incrementing of `*_LIB_VERSION_AGE`

ACKs for top commit:
  real-or-random:
    ACK bef448f9af  diff looks good and I tested on Linux

Tree-SHA512: f7551fc7377ea50c8bc32d14108a034a1f91ebbb63d5fec562e5cc28416637834b9a4dcba3692df1780adcd1212ad4f238dc0219ab5add68bd88a5a458572ee5
2023-05-03 15:58:55 +02:00
Hennadii Stepanov
d1e48e5474 refactor: Make 64-bit shift explicit
This change fixes MSVC level-3 warning C4334.
See: https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-3-c4334

Required to enable level 3 warnings (/W3).
2023-05-02 13:35:15 +01:00
Hennadii Stepanov
b2e29e43d0 ci: Treat all compiler warnings as errors in "Windows (VS 2022)" task 2023-04-30 16:46:03 +01:00
Tim Ruffing
3c81838856 Merge bitcoin-core/secp256k1#1289: cmake: Use full signature of add_test() command
755629bc03 cmake: Use full signature of `add_test()` command (Hennadii Stepanov)

Pull request description:

  This PR fixes tests for Windows binaries using Wine:
  ```
  $ cmake -S . -B ../mingw -DCMAKE_TOOLCHAIN_FILE=cmake/x86_64-w64-mingw32.toolchain.cmake
  $ cmake --build ../mingw
  $ cmake --build ../mingw -t check
  Test project /home/hebasto/git/secp256k1/mingw
      Start 1: noverify_tests
  Could not find executable noverify_tests
  ...
  ```

ACKs for top commit:
  real-or-random:
    ACK 755629bc03

Tree-SHA512: d1b24a1f1de2e8b70203132f4f6e685b9a120a987302cefe033fa916dfe7a135dbacaf8174d4046e30be170e92a16d070db54292c038cd2acdecc334f7f516dd
2023-04-29 17:17:47 +02:00
Hennadii Stepanov
755629bc03 cmake: Use full signature of add_test() command
An executable target in the `COMMAND` option will automatically be
replaced by the location of the executable created at build time.

This change fixes tests for Windows binaries using Wine.
2023-04-29 09:49:25 +01:00
Hennadii Stepanov
bef448f9af cmake: Fix library ABI versioning
This change emulates Libtool to make sure Libtool and CMake agree on the
ABI version.
2023-04-28 20:59:53 +01:00
Tim Ruffing
4b0f711d46 Merge bitcoin-core/secp256k1#1277: autotools: Clean up after adding Wycheproof
7e977b3c50 autotools: Take VPATH builds into account when generating testvectors (Tim Ruffing)
2418d3260a autotools: Create src/wycheproof dir before creating file in it (Tim Ruffing)
8764034ed5 autotools: Make all "pregenerated" targets .PHONY (Tim Ruffing)
e1b9ce8811 autotools: Use same conventions for all pregenerated files (Tim Ruffing)
08f4b1632d autotools: Move code around to tidy Makefile (Tim Ruffing)
529b54d922 autotools: Move Wycheproof header from EXTRA_DIST to noinst_HEADERS (Tim Ruffing)

Pull request description:

  Follow-up to https://github.com/bitcoin-core/secp256k1/pull/1245.

  This builds on top of https://github.com/bitcoin-core/secp256k1/pull/1276. Let's only merge https://github.com/bitcoin-core/secp256k1/pull/1276 as a hotfix for the Core build.

ACKs for top commit:
  hebasto:
    ACK 7e977b3c50

Tree-SHA512: 42e09feaed15d903e759360e1dfbd1afce9da07a55512e2e791147b72d9b6477e34ae6028439af57dbcae318081a37ddcf3a630f9617bfea95c130135ba2313f
2023-04-27 15:39:30 +01:00
Tim Ruffing
222ecaf661 Merge bitcoin-core/secp256k1#1284: cmake: Some improvements using PROJECT_IS_TOP_LEVEL variable
71f746c057 cmake: Include `include` directory for subtree builds (Hennadii Stepanov)
5431b9decd cmake: Make `SECP256K1_INSTALL` default depend on `PROJECT_IS_TOP_LEVEL` (Hennadii Stepanov)
162608cc98 cmake: Emulate `PROJECT_IS_TOP_LEVEL` for CMake<3.21 (Hennadii Stepanov)

Pull request description:

  This PR:
  1. Emulates [`PROJECT_IS_TOP_LEVEL`](https://cmake.org/cmake/help/latest/variable/PROJECT_IS_TOP_LEVEL.html) variable for CMake versions where it is not available.
  2. Makes the `SECP256K1_INSTALL` option dependent on `PROJECT_IS_TOP_LEVEL` (a [follow up](https://github.com/bitcoin-core/secp256k1/pull/1263#issuecomment-1516564300) of https://github.com/bitcoin-core/secp256k1/pull/1263).
  3. Makes integration of this project as a subtree easier. A top project can `#include <secp256k1.h>` with no additional `target_include_directories()` commands. For example, see https://github.com/hebasto/secp256k1-CMake-example/tree/subtree.

ACKs for top commit:
  theuni:
    utACK 71f746c057.

Tree-SHA512: 8ccdbcc94b26f36e772611ebaab0f2846debd6ad20f9e361be31a8d2128a14273acb692b0631026e12cc6cdef6d445dce0fd3beb4f71af47b46dfcf840a18879
2023-04-27 15:17:38 +01:00
Hennadii Stepanov
71f746c057 cmake: Include include directory for subtree builds 2023-04-27 15:13:10 +01:00
Tim Ruffing
024a409484 Merge bitcoin-core/secp256k1#1240: cmake: Improve and document compiler flag checks
a8d059f76c cmake, doc: Document compiler flags (Hennadii Stepanov)
6ece1507cb cmake, refactor: Rename `try_add_compile_option` to `try_append_cflags` (Hennadii Stepanov)
19516ed3e9 cmake: Use `add_compile_options()` in `try_add_compile_option()` (Hennadii Stepanov)

Pull request description:

  This PR:
  - drops tinkering with the `COMPILE_OPTIONS` directory property in `try_add_compile_option()`  and renames it to `try_append_cflags()`
  - copies related comments from `configure.ac`

ACKs for top commit:
  theuni:
    ACK a8d059f76c .

Tree-SHA512: 7ac011c135e12a65c45f4feb7cd74fd2d961ed77252afecf3a66e2af1d57facab446120c63696507b5ecd5bdb3eee1521760a53028b914c429652d00d03a4462
2023-04-27 14:48:46 +01:00
Hennadii Stepanov
a8d059f76c cmake, doc: Document compiler flags 2023-04-27 14:41:13 +01:00
Hennadii Stepanov
6ece1507cb cmake, refactor: Rename try_add_compile_option to try_append_cflags
Actually, `try_append_cflags()` can handle a list of flags, and the new
name is similar to the one used in `configure.ac`.
2023-04-27 14:41:13 +01:00
Hennadii Stepanov
19516ed3e9 cmake: Use add_compile_options() in try_add_compile_option()
This change drops tinkering with the `COMPILE_OPTIONS` directory
property. Also `try_add_compile_option()` can handle a list of flags
now, if they are required to be checked simultaneously.

An explanatory comments have been added as well.
2023-04-27 14:39:10 +01:00
Tim Ruffing
4b84f4bf0f Merge bitcoin-core/secp256k1#1239: cmake: Bugfix and other improvements after bumping CMake up to 3.13
a273d74b2e cmake: Improve version comparison (Hennadii Stepanov)
6a58b483ef cmake: Use `if(... IN_LIST ...)` command (Hennadii Stepanov)
2445808c02 cmake: Use dedicated `GENERATOR_IS_MULTI_CONFIG` property (Hennadii Stepanov)
9f8703ef17 cmake: Use dedicated `CMAKE_HOST_APPLE` variable (Hennadii Stepanov)
8c2017035a cmake: Use recommended `add_compile_definitions` command (Hennadii Stepanov)
04d4cc071a cmake: Add `DESCRIPTION` and `HOMEPAGE_URL` options to `project` command (Hennadii Stepanov)
8a8b6536ef cmake: Use `SameMinorVersion` compatibility mode (Hennadii Stepanov)

Pull request description:

  This PR:
  - resolves two items from #1235, including a bugfix with package version compatibility
  - includes other improvements which have become available for CMake 3.13+.

  To test the `GENERATOR_IS_MULTI_CONFIG` property on Linux, one can use the "[Ninja Multi-Config](https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html)" generator:
  ```sh
  cmake -S . -B build -G "Ninja Multi-Config"
  ```

ACKs for top commit:
  real-or-random:
    ACK a273d74b2e
  theuni:
    ACK a273d74b2e

Tree-SHA512: f31c4f0f30bf368303e70ab8952cde5cc8c70a5e79a04f879abcbee3d0a8d8c598379fb38f5142cb1f8ff5f9dcfc8b8eb4c13c975a1d05fdcc92d9c805a59d9a
2023-04-27 11:23:55 +01:00
Tim Ruffing
596b336ff6 Merge bitcoin-core/secp256k1#1234: cmake: Add dev-mode
ce5ba9e24d gitignore: Add CMakeUserPresets.json (Tim Ruffing)
0a446a312f cmake: Add dev-mode CMake preset (Tim Ruffing)

Pull request description:

  To use, invoke `cmake` with argument `--preset dev-mode`.

  One disadvantage over `./configure --enable-dev-mode` is that CMake does not provide a way to "hide" presets from users. That is, `cmake --list-presets` will list dev-mode, and it will also appear in `cmake-gui`, even though it's not selectable there due to a bug in cmake-gui.

  Solves one item in #1224.

ACKs for top commit:
  hebasto:
    ACK ce5ba9e24d
  theuni:
    ACK ce5ba9e24d

Tree-SHA512: c14bd283bd5bf64006bf3a23d72e6e55777b084aff71eb2a002f8ddde1d3549ccb2f08feb2b83366a24272209ab579cac8b73cfc020919adf7f039beb65bc9cc
2023-04-27 11:05:25 +01:00
Tim Ruffing
6b7e5b717d Merge bitcoin-core/secp256k1#1275: build: Fix C4005 "macro redefinition" MSVC warnings in examples
dc0657c762 build: Fix C4005 "macro redefinition" MSVC warnings in examples (Hennadii Stepanov)

Pull request description:

  This PR:
  - fixes C4005 "macro redefinition" MSVC warnings in examples
  - removes warning suppressions in both build systems, Autotools-based and CMake-based ones

ACKs for top commit:
  real-or-random:
    utACK dc0657c762

Tree-SHA512: fe3bb8f06b3ff1d51e5e20754a289e0e6b99ddf4c0bd4e6e4786e2558e71e043ab23ff7782a83a902df5db28d18ae65312674c373fdc49f5af252763a22bd0fb
2023-04-26 16:44:51 +01:00
Hennadii Stepanov
42f8c51402 cmake: Add SECP256K1_LATE_CFLAGS configure option 2023-04-26 11:10:03 +01:00
Tim Ruffing
1c89536718 Merge bitcoin-core/secp256k1#1286: tests: remove extra semicolon in macro
c4062d6b5d debug: move helper for printing buffers into util.h (Jonas Nick)
3858bad2c6 tests: remove extra semicolon in macro (Jonas Nick)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK c4062d6b5d
  hebasto:
    ACK c4062d6b5d, I have reviewed the code and it looks OK.

Tree-SHA512: a2c97433d82c1ab2ba976c4fd8aaf337de5f225abcd459e84dcdab689e77e43d4ed654c971ab7f11f27af12e7a744122a0fdd9ece8e635d7a7041c45e9484de8
2023-04-25 23:10:00 +01:00
Jonas Nick
c4062d6b5d debug: move helper for printing buffers into util.h 2023-04-25 16:07:10 +00:00
Jonas Nick
f3126fdfec norm arg: remove prove edge tests which are now covered by vectors 2023-04-25 15:06:57 +00:00
Jonas Nick
847ed9ecb2 norm arg: add verification to prove vectors 2023-04-25 15:06:40 +00:00
Tim Ruffing
7e977b3c50 autotools: Take VPATH builds into account when generating testvectors 2023-04-25 16:06:25 +01:00
Tim Ruffing
2418d3260a autotools: Create src/wycheproof dir before creating file in it
This directory may not exist in a VPATH build,
see https://github.com/bitcoin/bitcoin/pull/27445#issuecomment-1502994264 .
2023-04-25 16:06:25 +01:00
Tim Ruffing
8764034ed5 autotools: Make all "pregenerated" targets .PHONY
This follows the automake conventions more, see:
https://www.gnu.org/software/automake/manual/html_node/Clean.html
2023-04-25 16:06:25 +01:00
Tim Ruffing
e1b9ce8811 autotools: Use same conventions for all pregenerated files 2023-04-25 16:06:25 +01:00
Jonas Nick
cf797ed2a4 norm arg: add prove test vectors 2023-04-25 14:56:42 +00:00
Jonas Nick
095c1e749c norm arg: add prove_const to tests 2023-04-25 14:54:30 +00:00
Jonas Nick
ce18267b66 Merge elementsproject/secp256k1-zkp#229: musig: Fix nits left open in #211
a0b51afc01 musig: VERIFY_CHECK preconditions of _musig_keyaggcoef_internal() (Tim Ruffing)
da7702844e extrakeys: Clarify comparison order of compare/sort functions (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK a0b51afc01

Tree-SHA512: ad509d7a55c6f832a25b896b0fe38e259b79864b2a8d1fb337b9d9b4a5e1950a9d579040285465c89d815becc6e49af4129ab2d904d32ac98cef74357a440c89
2023-04-23 08:06:33 +00:00
Jonas Nick
78ed0e09ca Merge elementsproject/secp256k1-zkp#227: Use relative #include paths and tidy header guards (as in upstream)
e444d24bca Fix include guards: No _ prefix/suffix but _H suffix (as in upstream) (Tim Ruffing)
0eea7d97ab Use relative #include paths in tests (as in upstream) (Tim Ruffing)
c690d6df70 Use relative #include paths in benchmarks (as in upstream) (Tim Ruffing)
c565827c1a Use relative #include paths in ctime_test (as in upstream) (Tim Ruffing)
4eca406f4c Use relative #include paths in library (as in upstream) (Tim Ruffing)

Pull request description:

ACKs for top commit:
  apoelstra:
    ACK e444d24bca
  jonasnick:
    ACK e444d24bca

Tree-SHA512: 4d125cf75748f4a921b70ca933ee59c3cf5c0845c6960e6915a322e53840cb3a0955fe5952e654d133ad36991f3268aeee44430cbd6f7d83e333a554c436f39b
2023-04-23 07:50:30 +00:00
Jonas Nick
3858bad2c6 tests: remove extra semicolon in macro 2023-04-21 20:21:28 +00:00
Jonas Nick
1f33bb2b1c Merge bitcoin-core/secp256k1#1205: field: Improve docs +tests of secp256k1_fe_set_b32
162da73e9a tests: Add debug helper for printing buffers (Tim Ruffing)
e9fd3dff76 field: Improve docs and tests of secp256k1_fe_set_b32 (Tim Ruffing)
ca92a35d01 field: Simplify code in secp256k1_fe_set_b32 (Tim Ruffing)
d93f62e369 field: Verify field element even after secp256k1_fe_set_b32 fails (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 162da73e9a

Tree-SHA512: b3ed8e45c969d0420275ff154462f3820b72b57832ccba1f6f427e0cfd9cff3e27440c20994f69ea33a576b1903eb7f04a989f0dbd574bbd96ee56c6dd4500f7
2023-04-21 16:23:59 +00:00
Jonas Nick
e7fc61ff16 Merge elementsproject/secp256k1-zkp#228: Simple dedicated -zkp README
4d9d8f92d4 Simple dedicated -zkp README (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 4d9d8f92d4

Tree-SHA512: bae7aafed0d524d2fea956261547ca094dbaa4b444b56b6f3fb947764cc5647b5eec82ac392f988df3d3d88d1357ae2aa34550c7a596b386a2d0a774f9764661
2023-04-21 16:22:17 +00:00
Tim Ruffing
162da73e9a tests: Add debug helper for printing buffers 2023-04-21 17:20:37 +02:00
Tim Ruffing
e9fd3dff76 field: Improve docs and tests of secp256k1_fe_set_b32 2023-04-21 17:20:37 +02:00
Tim Ruffing
a0b51afc01 musig: VERIFY_CHECK preconditions of _musig_keyaggcoef_internal() 2023-04-21 16:18:19 +02:00
Tim Ruffing
da7702844e extrakeys: Clarify comparison order of compare/sort functions
Note that the touched functions don't exist upstream currently.
2023-04-21 16:17:52 +02:00
Tim Ruffing
f6bef03c0a Merge bitcoin-core/secp256k1#1283: Get rid of secp256k1_fe_const_b
69e1ec0331 Get rid of secp256k1_fe_const_b (Pieter Wuille)

Pull request description:

  Replaces #1282.

  Its only remaining use is in a test introduced in #1118, and it is easily replaced by the new `secp256k1_fe_add_int` from #1217.

ACKs for top commit:
  real-or-random:
    utACK 69e1ec0331

Tree-SHA512: 6ada192e0643fc5326198b60f019a5081444f9ba0a5b8ba6236f2a526829d8e5e479556600a604d9bc96c7ba86e3aab813f93c66679287d2135e95a2b75f5d3e
2023-04-21 13:07:59 +02:00
Hennadii Stepanov
5431b9decd cmake: Make SECP256K1_INSTALL default depend on PROJECT_IS_TOP_LEVEL
Also full stops have been added to the option help texts for consistency
in cmake-gui.
2023-04-21 12:03:04 +01:00
Tim Ruffing
5ec1333d4f Merge bitcoin-core/secp256k1#1285: bench: Make sys/time.h a system include
68b16a1662 bench: Make sys/time.h a system include (Tim Ruffing)

Pull request description:

  just because it is minimally more correct

ACKs for top commit:
  hebasto:
    ACK 68b16a1662, I've skimmed through the whole codebase and did not find any more similar cases.

Tree-SHA512: 0a929b36202100abf0d14e9328a2dc2b4c9db5532f95514315cb04dd0a970dbbb1dc02c6275be0ec109dc88f6090f6ce48a65003c852fd4dc750decf07e563c4
2023-04-21 12:52:01 +02:00
Tim Ruffing
4d9d8f92d4 Simple dedicated -zkp README 2023-04-21 12:38:34 +02:00
Tim Ruffing
e444d24bca Fix include guards: No _ prefix/suffix but _H suffix (as in upstream) 2023-04-21 12:02:28 +02:00
Tim Ruffing
0eea7d97ab Use relative #include paths in tests (as in upstream) 2023-04-21 11:51:04 +02:00
Tim Ruffing
c690d6df70 Use relative #include paths in benchmarks (as in upstream) 2023-04-21 11:50:46 +02:00
Tim Ruffing
c565827c1a Use relative #include paths in ctime_test (as in upstream) 2023-04-21 11:50:34 +02:00
Tim Ruffing
4eca406f4c Use relative #include paths in library (as in upstream) 2023-04-21 11:50:24 +02:00
Tim Ruffing
68b16a1662 bench: Make sys/time.h a system include 2023-04-21 11:18:36 +02:00
Hennadii Stepanov
162608cc98 cmake: Emulate PROJECT_IS_TOP_LEVEL for CMake<3.21 2023-04-20 23:12:28 +01:00
Pieter Wuille
69e1ec0331 Get rid of secp256k1_fe_const_b 2023-04-20 16:07:56 -04:00
Jonas Nick
bf7bf8a64f norm arg: split norm_arg_zero into prove_edge and verify_zero_len
One function tests prover edge cases, the other tests verifier edge cases.
2023-04-20 19:05:22 +00:00
Jonas Nick
a70c4d4a8a norm arg: add test vector for |n| = 0 2023-04-20 19:03:27 +00:00
Jonas Nick
f5e4b16f0f norm arg: add test vector for sign bit malleability
R is point at infinity but sign is != 0
2023-04-20 19:02:51 +00:00
Jonas Nick
c0de361fc5 norm arg: allow X and R to be the point at infinity
Add test vector
2023-04-20 19:02:41 +00:00
Jonas Nick
f22834f202 norm arg: add verify vector for n = [0], l = [0] 2023-04-20 19:00:14 +00:00
Jonas Nick
d8e7f3763b musig: move ge_{serialize,parse}_ext to module-independent file 2023-04-20 18:56:11 +00:00
Jonas Nick
050d9b2912 Merge elementsproject/secp256k1-zkp#226: bppp: align terminology with paper
2c63d17c1e bppp: align terminology with paper (gamma) (Jonas Nick)
dbf2e4d3e1 bppp: align terminology with paper (mu, rho) (Jonas Nick)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK  2c63d17c1e

Tree-SHA512: 494db14717acf95de74ca14cdbd4908b31a2e81562ca18b8e3ddd795d40f60cd8ea8d7472c348da108db7d314d510f7366dc594809cf29c0c044c701c56119cc
2023-04-20 18:54:16 +00:00
Tim Ruffing
ce5ba9e24d gitignore: Add CMakeUserPresets.json
This file is specifically intended for *local* CMake templates
(as opposed to CMakePresets.json).
2023-04-20 19:23:12 +02:00
Tim Ruffing
0a446a312f cmake: Add dev-mode CMake preset
To use, invoke `cmake` with argument `--preset dev-mode`.

Solves one item in #1235.

One disadvantage over `./configure --enable-dev-mode` is that CMake
does not provide a way to "hide" presets from users. That is,
`cmake --list-presets` will list dev-mode, and it will also appear
in `cmake-gui`, even though it's not selectable there due to bug
https://gitlab.kitware.com/cmake/cmake/-/issues/23341. (So in our
case, that's probably rather a feature than a bug.)

We curently use version 3 presets which require CMake 3.21+.
Unfortunately, CMake versions before 3.19 may ignore the `--preset`
argument silently. So if the preset is not picked up, make sure you
have a recent enough CMake version.

More unfortunately, we can't even spell this warning out in
CMakePresets.json because CMake does not support officially support
comments in JSON, see
 - https://gitlab.kitware.com/cmake/cmake/-/issues/21858
 - https://gitlab.kitware.com/cmake/cmake/-/merge_requests/5853 .
We could use a hack hinted at in
https://gitlab.kitware.com/cmake/cmake/-/issues/21858#note_908543
but that's risky, because it could simply break for future versions,
and we probably want to use presets not only for dev mode.
2023-04-20 19:22:43 +02:00
Tim Ruffing
a6f4bcf6e1 Merge bitcoin-core/secp256k1#1231: Move SECP256K1_INLINE macro definition out from include/secp256k1.h
8e142ca410 Move `SECP256K1_INLINE` macro definition out from `include/secp256k1.h` (Hennadii Stepanov)
77445898a5 Remove `SECP256K1_INLINE` usage from examples (Hennadii Stepanov)

Pull request description:

  From [IRC](https://gnusha.org/secp256k1/2023-01-31.log):
  > 06:29 \< hebasto\> What are reasons to define the `SECP256K1_INLINE` macro in user's `include/secp256k1.h` header, while it is used internally only?
  > 06:32 \< hebasto\> I mean, any other (or a new dedicated) header in `src` looks more appropriate, no?
  > 06:35 \< sipa\> I think it may just predate any "utility" internal headers.
  > 06:42 \< sipa\> I think it makes sense to move it to util.h

  Pros:
  - it is a step in direction to better organized headers (in context of #924, #1039)

  Cons:
  - code duplication for `SECP256K1_GNUC_PREREQ` macro

ACKs for top commit:
  sipa:
    utACK 8e142ca410
  real-or-random:
    utACK 8e142ca410

Tree-SHA512: 180e0ba7c2ef242b765f20698b67d06c492b7b70866c21db27c18d8b2e85c3e11f86c6cb99ffa88bbd23891ce3ee8a24bc528f2c91167ec2fddc167463f78eac
2023-04-20 18:18:11 +02:00
Hennadii Stepanov
a273d74b2e cmake: Improve version comparison 2023-04-20 17:03:42 +01:00
Hennadii Stepanov
6a58b483ef cmake: Use if(... IN_LIST ...) command
Available in CMake 3.3+.
2023-04-20 17:00:11 +01:00
Hennadii Stepanov
2445808c02 cmake: Use dedicated GENERATOR_IS_MULTI_CONFIG property
Available in CMake 3.9+.
2023-04-20 17:00:10 +01:00
Hennadii Stepanov
9f8703ef17 cmake: Use dedicated CMAKE_HOST_APPLE variable 2023-04-20 17:00:10 +01:00
Hennadii Stepanov
8c2017035a cmake: Use recommended add_compile_definitions command
Available in CMake 3.12+.
2023-04-20 17:00:10 +01:00
Hennadii Stepanov
04d4cc071a cmake: Add DESCRIPTION and HOMEPAGE_URL options to project command
`DESCRIPTION` is available in CMake 3.9+.
`HOMEPAGE_URL` is available in CMake 3.12+.
2023-04-20 17:00:10 +01:00
Hennadii Stepanov
8a8b6536ef cmake: Use SameMinorVersion compatibility mode
Available in CMake 3.11+.
2023-04-20 17:00:03 +01:00
Tim Ruffing
5b0444a3b5 Merge bitcoin-core/secp256k1#1263: cmake: Make installation optional
47ac3d63cd cmake: Make installation optional (Anna “CyberTailor”)

Pull request description:

  Useful for embedding secp256k1 in a subproject.

ACKs for top commit:
  theuni:
    ACK 47ac3d63cd.
  real-or-random:
    utACK 47ac3d63cd
  hebasto:
    ACK 47ac3d63cd, tested on Ubuntu 23.04.

Tree-SHA512: 12ac0ba9dc38adf45684055386280b669384b5a4e528a3f6f4470fd0b7f57d64dfed6a8bb9f0a84cacfcb72f509534d71676c5ba37b27297b1a96676eea44e6e
2023-04-20 17:44:44 +02:00
Anna “CyberTailor”
47ac3d63cd cmake: Make installation optional
Useful for embedding secp256k1 in a subproject.
2023-04-20 19:20:33 +05:00
Tim Ruffing
2e035af251 Merge bitcoin-core/secp256k1#1273: build: Make SECP_VALGRIND_CHECK preserve CPPFLAGS
1ecb94ebe9 build: Make `SECP_VALGRIND_CHECK` preserve `CPPFLAGS` (Hennadii Stepanov)

Pull request description:

  It was overlooked in #862 and #1027.

ACKs for top commit:
  real-or-random:
    utACK 1ecb94ebe9

Tree-SHA512: 263fc600ce9743e4aad767150f706bf7d4325dabb9c363ed57f08fe38faea94d7d1999804947cffeacbe698bb6d959ee6de3f6e50400050a390ecc0db957e426
2023-04-20 10:34:04 +02:00
Tim Ruffing
5be353d658 Merge bitcoin-core/secp256k1#1279: tests: lint wycheproof's python script
35ada3b954 tests: lint wycheproof's python script (RandomLattice)

Pull request description:

  This PR lints tests_wycheproof_generate.py according to bitcoin's python linting scripts. This is a follow-up to PR #1245.

ACKs for top commit:
  sipa:
    utACK 35ada3b954
  real-or-random:
    utACK 35ada3b954

Tree-SHA512: ea405060d2e73ff3543626687de5bc5282be923b914bd5c8c53e65df8dca9bea0000c416603095efff29bc7ae43c2081454c4e506db0f6805443d023fbffaf4c
2023-04-19 16:28:39 +02:00
Tim Ruffing
08f4b1632d autotools: Move code around to tidy Makefile 2023-04-19 15:55:25 +02:00
Jonas Nick
2c63d17c1e bppp: align terminology with paper (gamma)
e -> gamma
2023-04-19 12:37:47 +00:00
Jonas Nick
dbf2e4d3e1 bppp: align terminology with paper (mu, rho)
q-> mu, r -> rho
2023-04-19 12:37:29 +00:00
Tim Ruffing
04bf3f6778 Merge bitcoin-core/secp256k1#1230: Build: allow static or shared but not both
ef49a11d29 build: allow static or shared but not both (Cory Fields)
36b0adf1b9 build: remove warning until it's reproducible (Cory Fields)

Pull request description:

  Continuing from here: https://github.com/bitcoin-core/secp256k1/issues/1224#issuecomment-1460438227

  Unfortunately it wasn't really possible to keep a clean diff here because of the nature of the change. I suggest reviewing the lib creation stuff in its entirety, sorry about that :\

  Rather than allowing for shared and static libs to be built at the same time like autotools, this PR switches to the CMake convention of allowing only 1.

  A new `BUILD_SHARED_LIBS` option is added to match CMake convention, as well as a `SECP256K1_DISABLE_SHARED` option which overrides it. That way even projects which have `BUILD_SHARED_LIBS=1` can opt-into a static libsecp in particular.

  Details:

  Two object libraries are created: `secp256k1_asm` and `secp256k1_precomputed_objs`. Some tests/benchmarks use the object libraries directly, some link against the real lib: `secp256k1`.

  Because the objs don't know what they're going to be linked into, they need to be told how to deal with PIC.

  The `DEFINE_SYMBOL` property sets the `DLL_EXPORT` define as necessary (when building a shared lib)

ACKs for top commit:
  hebasto:
    re-ACK ef49a11d29, only [suggested](https://github.com/bitcoin-core/secp256k1/pull/1230#pullrequestreview-1388191165) changes since my recent [review](https://github.com/bitcoin-core/secp256k1/pull/1230#pullrequestreview-1352125381).
  real-or-random:
    ACK ef49a11d29

Tree-SHA512: 8870de305176fdb677caff0fdfc6f8c59c0e906489cb72bc9980e551002812685e59e20d731f2a82e33628bdfbb7261eafd6f228038cad3ec83bd74335959600
2023-04-18 12:54:03 +02:00
Tim Ruffing
9ce9984f32 Merge bitcoin-core/secp256k1#1265: Remove bits argument from secp256k1_wnaf_const{_xonly}
a575339c02 Remove bits argument from secp256k1_wnaf_const (always 256) (Pieter Wuille)

Pull request description:

  There is little reason for having the number of bits in the scalar as a parameter, as I don't think there are any (current) use cases for non-256-bit scalars.

ACKs for top commit:
  jonasnick:
    ACK a575339c02
  real-or-random:
    utACK a575339c02

Tree-SHA512: 994b1f19b4c513f6d070ed259a5d6f221a0c2450271ec824c5eba1cd0ecace276de391c170285bfeae96aaf8f1e0f7fe6260966ded0336c75c522ab6c56d182c
2023-04-18 12:25:09 +02:00
Jonas Nick
566faa17d3 Merge bitcoin-core/secp256k1#1267: doc: clarify process for patch releases
1b6fb5593c doc: clarify process for patch releases (Jonas Nick)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 1b6fb5593c

Tree-SHA512: 5c1da34c920f66327b91c1fd11ad2eccbb55c5befdb3ba59138faf921ce83d0e7c62de84f2431b0a63433f1edc0f7f0f025a852a76dd3638e3fd583ca13b83e4
2023-04-18 08:19:51 +00:00
Cory Fields
ef49a11d29 build: allow static or shared but not both 2023-04-17 16:25:27 +00:00
Tim Ruffing
f4dd0419aa Merge ElementsProject/secp256k1-zkp#225: sync-upstream: Use --autostash to handle uncommitted changes
13c438cdee sync-upstream: Use --autostash to handle uncommitted changes (Tim Ruffing)

Pull request description:

  This makes it possible to use sync-upstream with uncommitted changes. (This is in particular helpful when working on the script itself.)

  Without this commit, git pull will fail due to the uncommitted changes.

ACKs for top commit:
  apoelstra:
    utACK 13c438cdee

Tree-SHA512: c3a2fce68382bf4e769c64bbdc5666a8f4d9cf6f387e7d8af408e9c3e07b4a875205b7cdae9f647b7127128c13ee58effc0045ac5faf5fba2851b38af40439e8
2023-04-17 11:49:56 +02:00
RandomLattice
35ada3b954 tests: lint wycheproof's python script
This PR lints tests_wycheproof_generate.py according to pylint.
This is a follow-up to PR #1245.

Co-authored-by: Sean Andersen <6730974+andozw@users.noreply.github.com>
2023-04-14 18:59:35 +02:00
Tim Ruffing
4258c54f4e Merge bitcoin-core/secp256k1#1276: autotools: Don't regenerate Wycheproof header automatically
06c67dea9f autotools: Don't regenerate Wycheproof header automatically (Tim Ruffing)

Pull request description:

  This is a hot fix for https://github.com/bitcoin/bitcoin/pull/27445 .

  ---

  Pregenerated files that we distribute should not have dependencies in Makefile.am. For rationale, see the comments about the precomputed table files.

  See also https://github.com/bitcoin/bitcoin/pull/27445#issuecomment-1502994264 .

ACKs for top commit:
  hebasto:
    ACK 06c67dea9f
  RandomLattice:
    ACK 06c67dea9f

Tree-SHA512: fa7f44eaa1c7e42ecba5829ac1b8ae8b5826d1a1551e01c3caf37af780bd5c102c8f54e88520723937f7016d93c67b62a334c7a28b96c4f422a38fcf8e6a1984
2023-04-14 13:46:48 +02:00
Tim Ruffing
529b54d922 autotools: Move Wycheproof header from EXTRA_DIST to noinst_HEADERS 2023-04-14 08:00:10 +02:00
Tim Ruffing
06c67dea9f autotools: Don't regenerate Wycheproof header automatically
Pregenerated files that we distribute should not have dependencies
in Makefile.am. For rationale, see the comments about the precomputed
table files.

See also https://github.com/bitcoin/bitcoin/pull/27445#issuecomment-1502994264 .
2023-04-14 07:59:57 +02:00
Hennadii Stepanov
dc0657c762 build: Fix C4005 "macro redefinition" MSVC warnings in examples 2023-04-13 12:23:30 +01:00
Hennadii Stepanov
1ecb94ebe9 build: Make SECP_VALGRIND_CHECK preserve CPPFLAGS 2023-04-11 18:59:12 +01:00
Tim Ruffing
13c438cdee sync-upstream: Use --autostash to handle uncommitted changes
This makes it possible to use sync-upstream with uncommitted changes. (This
is in particular helpful when working on the script itself.)

Without this commit, git pull will fail due to the uncommitted changes.
2023-04-11 12:25:51 +02:00
Jonas Nick
6ec1ff6040 Merge elementsproject/secp256k1-zkp#224: Backport of "ct: Use volatile "trick" in all fe/scalar cmov implementations"
96f4853850 ct: Use volatile "trick" in all fe/scalar cmov implementations (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 96f4853850

Tree-SHA512: b3524a817ad8787a19dd28fc38523ab0ee2ddb72c5d88dfef566a9baa849b8d6a12df93030ecf97251e078128ec8203478bf98f3e8d9b28cc595ea5e8579c762
2023-04-11 10:15:01 +00:00
Tim Ruffing
96f4853850 ct: Use volatile "trick" in all fe/scalar cmov implementations
Apparently clang 15 is able to compile our cmov code into a branch,
at least for fe_cmov and fe_storage_cmov. This commit makes the
condition volatile in all cmov implementations (except ge but that
one only calls into the fe impls).

This is just a quick fix. We should still look into other methods,
e.g., asm and #457. We should also consider not caring about
constant-time in scalar_low_impl.h

We should also consider testing on very new compilers in nightly CI,
see https://github.com/bitcoin-core/secp256k1/pull/864#issuecomment-769211867
2023-04-11 12:06:09 +02:00
Jonas Nick
3bab71cf05 Merge bitcoin-core/secp256k1#1268: release cleanup: bump version after 0.3.1
656c6ea8d8 release cleanup: bump version after 0.3.1 (Jonas Nick)

Pull request description:

ACKs for top commit:
  sipa:
    ACK 656c6ea8d8
  real-or-random:
    ACK 656c6ea8d8

Tree-SHA512: da24326ed5feaa6a432522bddd64e6c129455cfe55a9e2decfce8c6039f4ce1a1da64233d17200f45d2c142f5414505b9a9b2ef5d136e047c1dd6cfdde1b560d
2023-04-10 20:05:59 +00:00
Jonas Nick
656c6ea8d8 release cleanup: bump version after 0.3.1 2023-04-10 19:50:27 +00:00
Jonas Nick
346a053d4c Merge bitcoin-core/secp256k1#1269: changelog: Fix link
6a37b2a5ea changelog: Fix link (Tim Ruffing)

Pull request description:

Top commit has no ACKs.

Tree-SHA512: 70d50c8fe958a197eb527e51c6f8120609e3166d93bfc1bbec75a3cb565c406d5ba0e6d088a724dcfda422b6594abf53f507211946a0533515df371d5d2a91bf
2023-04-10 19:31:28 +00:00
Tim Ruffing
6a37b2a5ea changelog: Fix link 2023-04-10 20:52:11 +02:00
Jonas Nick
ec98fcedd5 Merge bitcoin-core/secp256k1#1266: release: Prepare for 0.3.1
898e1c676e release: Prepare for 0.3.1 (Tim Ruffing)
1d9a13fc26 changelog: Remove inconsistent newlines (Tim Ruffing)
0e091669a1 changelog: Catch up in preparation of 0.3.1 (Tim Ruffing)

Pull request description:

ACKs for top commit:
  sipa:
    ACK 898e1c676e
  jonasnick:
    ACK 898e1c676e

Tree-SHA512: 941b1524f8b34ca803a2ede55a7baf54d2faa69a4c5e47254297e96cc4ac2121094ed90e7cd64a708f3e9af830b0de0ef3c755dfee1b01ce958cc998fc1a1311
2023-04-10 17:28:39 +00:00
Jonas Nick
1b6fb5593c doc: clarify process for patch releases 2023-04-10 15:19:07 +00:00
Tim Ruffing
898e1c676e release: Prepare for 0.3.1 2023-04-10 17:12:12 +02:00
Tim Ruffing
1d9a13fc26 changelog: Remove inconsistent newlines 2023-04-10 16:45:38 +02:00
Tim Ruffing
0e091669a1 changelog: Catch up in preparation of 0.3.1
Co-authored-by: Pieter Wuille <pieter@wuille.net>
2023-04-10 16:45:38 +02:00
Pieter Wuille
7b7503dac5 Merge bitcoin-core/secp256k1#1245: tests: Add Wycheproof ECDSA vectors
e5de454609 tests: Add Wycheproof ECDSA vectors (RandomLattice)

Pull request description:

  This PR adds a test using the Wycheproof vectors as outlined in #1106. We add all 463 ECDSA test vectors. These vectors cover:
  - edge cases in arithmetic operations
  - signatures with special values for (r,s) that should be rejected
  - special cases of public keys

  The vectors are pulled from the Wycheproof project using a python script to emit C code.

  All the new ECDSA Wycheproof vectors pass.

ACKs for top commit:
  sipa:
    ACK e5de454609
  real-or-random:
    ACK e5de454609

Tree-SHA512: e9684f14ff3f5225a4a4949b490e07527d559c28aa61ed03c03bc52ea64785f0b80b9e1b1628665eacf24006526271ea0fb108629c9c3c1d758e52d214a056f1
2023-04-10 09:29:02 -04:00
Pieter Wuille
a575339c02 Remove bits argument from secp256k1_wnaf_const (always 256) 2023-04-10 06:40:21 -04:00
Tim Ruffing
145078c418 Merge bitcoin-core/secp256k1#1118: Add x-only ecmult_const version with x specified as n/d
0f8642079b Add exhaustive tests for ecmult_const_xonly (Pieter Wuille)
4485926ace Add x-only ecmult_const version for x=n/d (Pieter Wuille)

Pull request description:

  This implements a generalization of Peter Dettman's sqrt-less x-only random-base multiplication algorithm from #262, using the Jacobi symbol algorithm from #979. The generalization is to permit the X coordinate of the base point to be specified as a fraction $n/d$:

  To compute $x(q \cdot P)$, where $x(P) = n/d$:
  * Compute $g=n^3 + 7d^3$.
  * Let $P' = (ng, g^2, 1)$ (the Jacobian coordinates of $P$ mapped to the isomorphic curve $y^2 = x^3 + 7(dg)^3$).
  * Compute the Jacobian coordinates $(X',Y',Z') = q \cdot P'$ on the isomorphic curve.
  * Return $X'/(dgZ'^2)$, which is the affine x coordinate on the isomorphic curve $X/Z'^2$ mapped back to secp256k1.

  This ability to specify the X coordinate as a fraction is useful in the context of x-only [Elligator Swift](https://eprint.iacr.org/2022/759), which can decode to X coordinates on the curve without inversions this way.

ACKs for top commit:
  jonasnick:
    ACK 0f8642079b
  real-or-random:
    ACK 0f8642079b

Tree-SHA512: eeedb3045bfabcb4bcaf3a1738067c83a5ea9a79b150b8fd1c00dc3f68505d34c19654885a90e2292ae40ddf40a58dfb27197d98eebcf5d6d9e25897e07ae595
2023-04-10 08:24:05 +02:00
RandomLattice
e5de454609 tests: Add Wycheproof ECDSA vectors
Adds a test using the Wycheproof vectors as outlined in #1106. The
vectors are taken from the Wycheproof repo. We use a python script
to convert the JSON-formatted vectors into C code.

Co-authored-by: Sean Andersen <6730974+andozw@users.noreply.github.com>
2023-04-09 06:17:16 +02:00
Pieter Wuille
0f8642079b Add exhaustive tests for ecmult_const_xonly 2023-04-08 15:25:41 -04:00
Pieter Wuille
4485926ace Add x-only ecmult_const version for x=n/d 2023-04-08 15:24:36 -04:00
Tim Ruffing
a0f4644f7e Merge bitcoin-core/secp256k1#1252: Make position of * in pointer declarations in include/ consistent
3d1f430f9f Make position of * in pointer declarations in include/ consistent (Jonas Nick)

Pull request description:

ACKs for top commit:
  sipa:
    utACK 3d1f430f9f. I have not verified these are the only instances where changes would need to be made.
  apoelstra:
    utACK 3d1f430 from me too. I also value consistency more than either specific choice.'
  real-or-random:
    utACK 3d1f430f9f

Tree-SHA512: 6361880f4a47e58c83623f094dd121882752fa805e275033cd638d1e8d3477ade9037e5d9e34a57ae46013848648bd7ab764cad326133f2d3435c9a70a0c841b
2023-04-08 09:44:12 +02:00
Jonas Nick
4e682626a3 Merge bitcoin-core/secp256k1#1226: Add CMake instructions to release process
0c07c82834 Add CMake instructions to release process (Tim Ruffing)

Pull request description:

ACKs for top commit:
  hebasto:
    ACK 0c07c82834
  jonasnick:
    ACK 0c07c82834

Tree-SHA512: a2c38f71cc96766f833f6ed79af1b560501f2d9516843b789de06c9cbffd7a1d9e8709a2f4d08bea8c1c3616301e51942cfa9f11e25e903ee4146c7733a8cb8c
2023-04-07 15:07:00 +00:00
Tim Ruffing
2d51a454fc Merge bitcoin-core/secp256k1#1257: ct: Use volatile "trick" in all fe/scalar cmov implementations
4a496a36fb ct: Use volatile "trick" in all fe/scalar cmov implementations (Tim Ruffing)

Pull request description:

  Apparently clang 15 is able to compile our cmov code into a branch, at least for fe_cmov and fe_storage_cmov. This commit makes the condition volatile in all cmov implementations (except ge but that one only calls into the fe impls).

  This is just a quick fix. We should still look into other methods, e.g., asm and #457. We should also consider not caring about constant-time in scalar_low_impl.h

  We should also consider testing on very new compilers in nightly CI, see https://github.com/bitcoin-core/secp256k1/pull/864#issuecomment-769211867

ACKs for top commit:
  jonasnick:
    ACK 4a496a36fb

Tree-SHA512: a6010f9d752e45f01f88b804a9b27e77caf5ddf133ddcbc4235b94698bda41c9276bf588c93710e538250d1a96844bcec198ec5459e675f166ceaaa42da921d5
2023-04-06 03:59:30 +02:00
Tim Ruffing
4a496a36fb ct: Use volatile "trick" in all fe/scalar cmov implementations
Apparently clang 15 is able to compile our cmov code into a branch,
at least for fe_cmov and fe_storage_cmov. This commit makes the
condition volatile in all cmov implementations (except ge but that
one only calls into the fe impls).

This is just a quick fix. We should still look into other methods,
e.g., asm and #457. We should also consider not caring about
constant-time in scalar_low_impl.h

We should also consider testing on very new compilers in nightly CI,
see https://github.com/bitcoin-core/secp256k1/pull/864#issuecomment-769211867
2023-04-01 15:58:24 +09:00
Jonas Nick
3d1f430f9f Make position of * in pointer declarations in include/ consistent 2023-03-28 19:39:02 +00:00
Jonas Nick
2bca0a5cbf Merge bitcoin-core/secp256k1#1241: build: Improve SECP_TRY_APPEND_DEFAULT_CFLAGS macro
3addb4c1e8 build: Improve `SECP_TRY_APPEND_DEFAULT_CFLAGS` macro (Hennadii Stepanov)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK 3addb4c1e8
  jonasnick:
    ACK 3addb4c1e8

Tree-SHA512: 918d906570d82be9354fba72bb55d50b8f661cf7cd4404dc244deb489c2bca95b3942ae8af830873ba825dc8ddc68b99c973fc984ff13fdd1f6668f412ca56a3
2023-03-28 19:02:20 +00:00
Jonas Nick
afd8b23b27 Merge bitcoin-core/secp256k1#1244: Suppress -Wunused-parameter when building for coverage analysis
5bb03c2911 Replace `SECP256K1_ECMULT_TABLE_VERIFY` macro by a function (Hennadii Stepanov)
4429a8c218 Suppress `-Wunused-parameter` when building for coverage analysis (Hennadii Stepanov)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK 5bb03c2911
  jonasnick:
    ACK 5bb03c2911

Tree-SHA512: 19a395434ecefea201a03fc45b3f0b88f1520908926ac1207bbc6570034b1141b49c3c98e66819dcd9069dfdd28c7c6fbe957f13fb6bd178fd57ce65bfbb8fbd
2023-03-28 07:18:23 +00:00
Jonas Nick
1d8f367515 Merge bitcoin-core/secp256k1#1250: No need to subtract 1 before doing a right shift
3e43041be6 No need to subtract 1 before doing a right shift (roconnor-blockstream)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK 3e43041be6
  jonasnick:
    ACK 3e43041be6

Tree-SHA512: bcecda11eae3fb845bef7af88c6171bedcd933872d08a9849c0a250cb6c9e982a88bd45e8a8364a4a348f8be413fc91ee04cf8fa78adae44e584e3ad7ec544cf
2023-03-28 06:32:28 +00:00
roconnor-blockstream
3e43041be6 No need to subtract 1 before doing a right shift 2023-03-27 09:29:41 -04:00
Hennadii Stepanov
3addb4c1e8 build: Improve SECP_TRY_APPEND_DEFAULT_CFLAGS macro
Co-authored-by: Tim Ruffing <crypto@timruffing.de>
2023-03-26 10:38:43 +01:00
Tim Ruffing
0c07c82834 Add CMake instructions to release process
... and make wording a bit more consistent.

Co-authored-by: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
2023-03-26 17:40:18 +09:00
Tim Ruffing
464a9115b4 Merge bitcoin-core/secp256k1#1242: Set ARM ASM symbol visibility to hidden
fd2a408647 Set ARM ASM symbol visibility to `hidden` (Hennadii Stepanov)

Pull request description:

  Solves one item in #1181.

  To test on arm-32bit hardware, run:
  ```
  $ ./autogen.sh && ./configure --enable-experimental --with-asm=arm && make
  ```

  On master branch (427bc3cdcf):
  ```
  $ nm -D .libs/libsecp256k1.so | grep secp256k1_fe
  0000e2bc T secp256k1_fe_mul_inner
  0000e8dc T secp256k1_fe_sqr_inner
  ```

  With this PR:
  ```
  $ nm -D .libs/libsecp256k1.so | grep secp256k1_fe | wc -l
  0
  ```

  For reference, see https://sourceware.org/binutils/docs/as/Hidden.html.

ACKs for top commit:
  theuni:
    ACK fd2a408647.
  sipa:
    ACK fd2a408647

Tree-SHA512: abf8ad332631672c036844f69c5599917c49e12c4402bf9066f93a692d3007b1914bd3eea8f83f0141c1b09d5c88ebc5e6c8bfbb5444b7b3471749f7b901ca59
2023-03-26 12:26:01 +09:00
Pieter Wuille
f16a709fd6 Merge bitcoin-core/secp256k1#1247: Apply Checks only in VERIFY mode.
4ebd82852d Apply Checks only in VERIFY mode. (roconnor-blockstream)

Pull request description:

  This is already done in `field_5x52_impl.h`.

ACKs for top commit:
  sipa:
    ACK 4ebd82852d
  jonasnick:
    ACK 4ebd82852d

Tree-SHA512: c24211e5219907e41e2c5792255734bd50ca5866a4863abbb3ec174ed92d1792dd10563a94c08e8fecd6cdf776a9c49ca87e8f9806a023d9081ecc0d55ae3e66
2023-03-24 09:35:04 -04:00
Jonas Nick
70be3cade5 Merge bitcoin-core/secp256k1#1246: Typo
d1e7ca192d Typo (roconnor-blockstream)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK d1e7ca192d

Tree-SHA512: 0d53ad29cf86921a59aae3953c7d786b7ee0567c9cf92d037853e8c4f7536e45c6b50467eb95d3763f27ae3fd1a8b2b9cf88689f320cb13cebf52f70bb4affef
2023-03-23 08:35:06 +00:00
roconnor-blockstream
4ebd82852d Apply Checks only in VERIFY mode. 2023-03-22 22:06:47 -04:00
roconnor-blockstream
d1e7ca192d Typo 2023-03-22 22:01:01 -04:00
Cory Fields
36b0adf1b9 build: remove warning until it's reproducible
Also remove the interface it was attached to since it's no longer needed.
This removal simplifies the next commit.
2023-03-21 16:21:21 +00:00
Hennadii Stepanov
5bb03c2911 Replace SECP256K1_ECMULT_TABLE_VERIFY macro by a function 2023-03-21 15:29:22 +00:00
Tim Ruffing
9c8c4f443c Merge bitcoin-core/secp256k1#1238: build: bump CMake minimum requirement to 3.13
96dd062511 build: bump CMake minimum requirement to 3.13 (Cory Fields)

Pull request description:

  As requested here: https://github.com/bitcoin-core/secp256k1/pull/1230#issuecomment-1464730218 . Ping @hebasto

  Among other things this allows us to link against object libraries.

  3.13 has been mentioned several times as a good overlap between newish features and widespread Linux availability.

ACKs for top commit:
  hebasto:
    ACK 96dd062511
  real-or-random:
    utACK 96dd062511

Tree-SHA512: 6c744809aa393b48ef10b3d46c6630370c388a8d375116bfad65c6c907e69c36ed71c1579b9d5c3aa976f70b1cd70e837c1a0226910a43539435125115b32568
2023-03-22 00:14:55 +09:00
Tim Ruffing
0cf2fb91ef Merge bitcoin-core/secp256k1#1243: build: Ensure no optimization when building for coverage analysis
8e79c7ed11 build: Ensure no optimization when building for coverage analysis (Hennadii Stepanov)

Pull request description:

  #944 introduced a regression when building for coverage analysis. The `-O2` flag from the default Autoconf's `CFLAGS` overrides the coverage-specific `-O0` one, which makes coverage analysis results [less reliable](https://gcc.gnu.org/onlinedocs/gcc/Gcov-and-Optimization.html).

  This PR restores the pre-#944 behaviour.

  In contrast to an alternative smaller diff:
  ```diff
  --- a/configure.ac
  +++ b/configure.ac
  @@ -240,7 +240,7 @@ fi

   if test x"$enable_coverage" = x"yes"; then
       SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DCOVERAGE=1"
  -    SECP_CFLAGS="-O0 --coverage $SECP_CFLAGS"
  +    CFLAGS="$CFLAGS -O0 --coverage "
       LDFLAGS="--coverage $LDFLAGS"
   else
       # Most likely the CFLAGS already contain -O2 because that is autoconf's default.
  ```

  this PR ensures that the user always has the last word.

  FWIW, Bitcoin Core uses a similar [approach](460e394625/configure.ac (L879-L884)).

ACKs for top commit:
  jonasnick:
    tested ACK 8e79c7ed11
  real-or-random:
    utACK 8e79c7ed11

Tree-SHA512: f04b55921d397bd7c003ec0283101d3908f3fb507789c855e1b6d5abd150e7d6281d5eeb8fefbb7d6a55b3c6f29a19324f570eee009794f8fa9bca956229e7ce
2023-03-21 21:05:09 +09:00
Hennadii Stepanov
fd2a408647 Set ARM ASM symbol visibility to hidden
Co-authored-by: Cory Fields <cory-nospam-@coryfields.com>
2023-03-15 09:08:41 +00:00
Hennadii Stepanov
4429a8c218 Suppress -Wunused-parameter when building for coverage analysis 2023-03-14 20:03:42 +00:00
Hennadii Stepanov
8e79c7ed11 build: Ensure no optimization when building for coverage analysis 2023-03-14 18:56:24 +00:00
Cory Fields
96dd062511 build: bump CMake minimum requirement to 3.13
Among other things this allows us to link against object libraries.
2023-03-12 19:03:39 +00:00
Pieter Wuille
427bc3cdcf Merge bitcoin-core/secp256k1#1236: Update comment for secp256k1_modinv32_inv256
647f0a5cb1 Update comment for secp256k1_modinv32_inv256 (roconnor-blockstream)

Pull request description:

ACKs for top commit:
  sipa:
    ACK 647f0a5cb1
  real-or-random:
    utACK 647f0a5cb1

Tree-SHA512: 7c2ec02acf985bb6edfc619ce31bd63511ff634d847a25888927b48b5164353a912d470421b0b969a868fbc5b865cbea188e14357557f44be42d5702af7c5a6b
2023-03-11 18:14:01 -05:00
roconnor-blockstream
647f0a5cb1 Update comment for secp256k1_modinv32_inv256 2023-03-10 08:53:33 -05:00
Hennadii Stepanov
8e142ca410 Move SECP256K1_INLINE macro definition out from include/secp256k1.h 2023-03-09 15:29:56 +00:00
Hennadii Stepanov
77445898a5 Remove SECP256K1_INLINE usage from examples 2023-03-09 13:05:14 +00:00
Tim Ruffing
5658209459 Merge bitcoin-core/secp256k1#1228: release cleanup: bump version after 0.3.0
28e63f7ea7 release cleanup: bump version after 0.3.0 (Jonas Nick)

Pull request description:

  Based on #1223. Should be merged only after tagging the release.

ACKs for top commit:
  sipa:
    ACK 28e63f7ea7
  real-or-random:
    ACK 28e63f7ea7

Tree-SHA512: d219f836c9258af52389f62c167adb79a0f83f520ede514e286e84f0540d35234322e67d582409c332662db17114da1681419d5d400ed88ad2be66a0f6a06089
2023-03-08 23:59:29 +01:00
Jonas Nick
bdf39000b9 Merge bitcoin-core/secp256k1#1223: release: prepare for 0.3.0
b40adf2360 release: prepare for 0.3.0 (Jonas Nick)

Pull request description:

ACKs for top commit:
  sipa:
    ACK b40adf2360
  real-or-random:
    ACK b40adf2360
  hebasto:
    ACK b40adf2360

Tree-SHA512: 221ba2d846804cefa139bee28b985414e293106cf63ef71ce4b34f815a62e5efd58d4ca6a03d6bcd5d843010d18f5be8d1cf43721a92e5196d732f5325499377
2023-03-08 22:14:06 +00:00
Jonas Nick
28e63f7ea7 release cleanup: bump version after 0.3.0 2023-03-08 22:07:11 +00:00
Jonas Nick
b40adf2360 release: prepare for 0.3.0 2023-03-08 22:00:43 +00:00
Pieter Wuille
90b513aada Merge bitcoin-core/secp256k1#1229: cmake: Rename project to "libsecp256k1"
8be82d4362 cmake: Rename project to "libsecp256k1" (Hennadii Stepanov)

Pull request description:

  Was discussed today on IRC.

ACKs for top commit:
  sipa:
    ACK 8be82d4362
  real-or-random:
    ACK 8be82d4362

Tree-SHA512: 4ea0fe6722c34acc50ebfba9f3c0503c773e268f8c3df6368e20c829ea800e3cb96758eec2813ed9f56ae4aae1f3919d8ae2755d55582e8c1811a08386f1b925
2023-03-08 16:58:47 -05:00
Hennadii Stepanov
8be82d4362 cmake: Rename project to "libsecp256k1" 2023-03-08 21:22:24 +00:00
Tim Ruffing
ef4f8bd025 Merge bitcoin-core/secp256k1#1227: readme: Use correct build type in CMake/Windows build instructions
756b61d451 readme: Use correct build type in CMake/Windows build instructions (Tim Ruffing)

Pull request description:

ACKs for top commit:
  hebasto:
    ACK 756b61d451, it is correct to provide the "RelWithDebInfo" configuration in multi-config setup, as the same build type is the default in single-config setups.

Tree-SHA512: e98a1519fdae4a29c7e06ecd0e68083acaf0f4fc14dfcd12282b89468052bb7c6c2fc7517c8526c9f7555a822a64b2f7c3f1ecc70d17e37a11d831d213f1daef
2023-03-08 19:39:59 +01:00
Tim Ruffing
756b61d451 readme: Use correct build type in CMake/Windows build instructions 2023-03-08 19:21:13 +01:00
Tim Ruffing
3295aa149b Merge bitcoin-core/secp256k1#1225: changelog: Add entry for CMake
92098d84cf changelog: Add entry for CMake (Tim Ruffing)

Pull request description:

ACKs for top commit:
  sipa:
    ACK 92098d84cf
  jonasnick:
    ACK 92098d84cf
  hebasto:
    ACK 92098d84cf

Tree-SHA512: d81ee4f7e1cd31c85a738fb7caaa96fe02add936732b5cdfd74a77191206709fa18157e949b84c04b1932fbcba8f082106acd303924be8312b4ea2f012ecae53
2023-03-08 18:28:04 +01:00
Tim Ruffing
92098d84cf changelog: Add entry for CMake 2023-03-08 17:49:01 +01:00
Pieter Wuille
df323b5c14 Merge bitcoin-core/secp256k1#1113: build: Add CMake-based build system
e1eb33724c ci: Add "x86_64: Windows (VS 2022)" task (Hennadii Stepanov)
10602b0030 cmake: Export config files (Hennadii Stepanov)
5468d70964 build: Add CMake-based build system (Hennadii Stepanov)

Pull request description:

  This PR adds a [CMake](https://cmake.org/)-based build system.

  Added build instructions and examples to the [`README.md`](https://github.com/hebasto/secp256k1/blob/220628-cmake/README.md#building-with-cmake-experimental) file.

  Ways to integrate with downstream CMake-based projects:
  - if `secp256k1` is a subtree (including Bitcoin Core project) -- `add_subdirectory(secp256k1)`
  - if `secp256k1` has been installed -- `find_package(secp256k1 0.2.1 CONFIG)`, see https://github.com/hebasto/secp256k1-CMake-example

  Added a few toolchain files for easy cross compiling.

  Discussions on IRC:
  - https://gnusha.org/secp256k1/2022-06-23.log
  - https://gnusha.org/secp256k1/2022-06-24.log
  - https://gnusha.org/secp256k1/2022-06-27.log
  - https://gnusha.org/secp256k1/2023-01-30.log

  ---

  Related PRs:
  - #315
  - #549
  - #761

  ---

  **Implementation notes**

  Minimum required CMake version is 3.1. This was required to provide [`C_STANDARD`](https://cmake.org/cmake/help/latest/prop_tgt/C_STANDARD.html) property.

  In turn, this choice of CMake version implies it is not possible to build with default CMake on Debian 8, which has CMake v3.0.2 only.

  Also see:
  - [CMake Versions on Linux Distros](https://gitlab.kitware.com/cmake/community/-/wikis/CMake-Versions-on-Linux-Distros)
  - https://repology.org/project/cmake/versions

  ---

  # Autotools -- CMake Feature Parity Tables

  ## 1. Configuration options

  Autotool-based build system features being listed according to the `./configure --help` output.

  | Autotools | CMake |
  |---|---|
  | `--prefix` | `-DCMAKE_INSTALL_PREFIX`
  | `--enable-shared` | `-DSECP256K1_BUILD_SHARED` |
  | `--enable-static` | `-DSECP256K1_BUILD_STATIC` |
  | `--enable-dev-mode` _hidden_ | N/A, see https://github.com/bitcoin-core/secp256k1/pull/1113#discussion_r916979117 |
  | `--enable-benchmark` | `-DSECP256K1_BUILD_BENCHMARK` |
  | `--enable-coverage` | `-DCMAKE_BUILD_TYPE=Coverage` |
  | `--enable-tests` | `-DSECP256K1_BUILD_TESTS` |
  | `--enable-ctime-tests` | `-DSECP256K1_BUILD_CTIME_TESTS` |
  | `--enable-experimental` | `-DSECP256K1_EXPERIMENTAL` |
  | `--enable-exhaustive-tests` | `-DSECP256K1_BUILD_EXHAUSTIVE_TESTS` |
  | `--enable-examples` | `-DSECP256K1_BUILD_EXAMPLES` |
  | `--enable-module-ecdh` | `-DSECP256K1_ENABLE_MODULE_ECDH` |
  | `--enable-module-recovery` | `-DSECP256K1_ENABLE_MODULE_RECOVERY` |
  | `--enable-module-extrakeys` | `-DSECP256K1_ENABLE_MODULE_EXTRAKEYS` |
  | `--enable-module-schnorrsig` | `-DSECP256K1_ENABLE_MODULE_SCHNORRSIG` |
  | `--enable-external-default-callbacks` | `-DSECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS` |
  | `--with-test-override-wide-multiply` _hidden_ | `-DSECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY` |
  | `--with-asm` | `-DSECP256K1_ASM` |
  | `--with-ecmult-window` | `-DSECP256K1_ECMULT_WINDOW_SIZE` |
  | `--with-ecmult-gen-precision` | `-DSECP256K1_ECMULT_GEN_PREC_BITS` |
  | `--with-valgrind` | `-DSECP256K1_VALGRING` |

  A screenshot of grouped options from `cmake-gui`:
  ![image](https://user-images.githubusercontent.com/32963518/214821305-fc3ffe82-4d05-4dd7-b2c2-7ca2d5d12e86.png)

  ## 2. `make` targets

  | Autotools | CMake |
  |---|---|
  | `make` | `make` |
  | `make check` | `make check` |
  | `make install` | `make install` * |

  * Installation of `lib/pkgconfig/libsecp256k1.pc` not implemented.

ACKs for top commit:
  theuni:
    ACK e1eb33724c.
  sipa:
    ACK e1eb33724c
  real-or-random:
    ACK e1eb33724c

Tree-SHA512: ebe2772eeb1a430a0a7ae767fb1a9a82d52d5e9bf2306956cd08f7b442c862be2539774dd10d5555817353d37d1c6add78b8fe5a85bb71239304fb42c98ff337
2023-03-08 10:33:09 -05:00
Hennadii Stepanov
e1eb33724c ci: Add "x86_64: Windows (VS 2022)" task 2023-03-08 13:33:58 +00:00
Hennadii Stepanov
10602b0030 cmake: Export config files 2023-03-08 13:33:52 +00:00
Hennadii Stepanov
5468d70964 build: Add CMake-based build system
Co-authored-by: Tim Ruffing <crypto@timruffing.de>
2023-03-08 13:33:16 +00:00
Tim Ruffing
6048e6c03e Merge bitcoin-core/secp256k1#1222: Remove redundant checks.
5d8f53e312 Remove redudent checks. (Russell O'Connor)

Pull request description:

  These abs checks are implied by the subsequent line, and with the subsequent line written as it is, no underflow is possible with signed integers.

  Follows up on https://github.com/bitcoin-core/secp256k1/pull/1218.

ACKs for top commit:
  sipa:
    utACK 5d8f53e312
  real-or-random:
    ACK 5d8f53e312

Tree-SHA512: ddd6758638fe634866fdaf900224372e2e51cb81ef4d024f169fbc39fff38ef1b29e90e0732877e8910158b82bc428ee9c3a4031882c2850b22ad87cc63ee305
2023-03-08 14:18:44 +01:00
Tim Ruffing
eb8749fcd0 Merge bitcoin-core/secp256k1#1221: Update Changelog
d232112fa7 Update Changelog (Tim Ruffing)

Pull request description:

  Fixes #1220.

ACKs for top commit:
  sipa:
    ACK d232112fa7
  jonasnick:
    ACK d232112fa7

Tree-SHA512: 86c0b9ec54480b87772bb3458ba3016676f747ea76148326b1c9c7fa3f0d8f3cee26bb68c1f2cb736f69a00811691b4d8c02e27c2de799552c547e824fbbb7ec
2023-03-08 12:08:56 +01:00
Russell O'Connor
5d8f53e312 Remove redudent checks.
These abs checks are implied by the subsequent line, and with the subsequent line written as it is, no underflow is possible with signed integers.
2023-03-07 09:10:36 -05:00
Jonas Nick
9d1b458d5f Merge bitcoin-core/secp256k1#1217: Add secp256k1_fe_add_int function
b081f7e4cb Add secp256k1_fe_add_int function (Pieter Wuille)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK b081f7e4cb
  real-or-random:
    utACK b081f7e4cb

Tree-SHA512: daf9956c81a328505faee7fb59d29ec0c5a326bce7c48159a8e0ed7590505b430785d750d0c34f152b9119ad130030063be999da0c2035747a27fe501e77560a
2023-03-07 14:08:05 +00:00
Tim Ruffing
d232112fa7 Update Changelog
Fixes #1220.
2023-03-07 12:01:23 +01:00
Tim Ruffing
8962fc95bb Merge bitcoin-core/secp256k1#1218: Update overflow check
2ef1c9b387 Update overflow check (Russell O'Connor)

Pull request description:

  One does not simply check for integer overlow.

ACKs for top commit:
  sipa:
    ACK 2ef1c9b387
  real-or-random:
    ACK 2ef1c9b387

Tree-SHA512: 61238b7b59b3840aa04c4c3ff768789eba95d8d9cbd16507b86bae585fe8d077ac1ac234f9d8aea7fa342c7278a30d2d888df3a93d7ab24730e73b682b11a7fe
2023-03-07 09:50:03 +01:00
Russell O'Connor
2ef1c9b387 Update overflow check
One does not simply check for integer overlow.
2023-03-06 18:13:47 -05:00
Jonas Nick
1d25608900 Merge elementsproject/secp256k1-zkp#223: musig: Update to BIP v1.0.0-rc.4 (Check pubnonce in NonceGen vectors)
d23c23e24d musig: Update to BIP v1.0.0-rc.4 (Check pubnonce in NonceGen vectors) (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK d23c23e24d

Tree-SHA512: 5edc80a7c60a3699c06a46eaea300cf31478e561afa3d29efb9e1b8220969b3f0503ebd1bf906addde2c7367c4e99e2f62c7ef07198c3925d38194c4eb2e9f76
2023-03-03 21:45:23 +00:00
Tim Ruffing
d23c23e24d musig: Update to BIP v1.0.0-rc.4 (Check pubnonce in NonceGen vectors) 2023-03-03 22:31:28 +01:00
Tim Ruffing
c4862f6869 Merge ElementsProject/secp256k1-zkp#215: musig: include pubkey in secnonce and compare when signing
a1ec2bb67b musig: add test for signing with wrong secnonce for a keypair (Jonas Nick)
bd57a017aa musig: include pubkey in secnonce and compare when signing (Jonas Nick)

Pull request description:

  Builds on #211.

  This PR implements a defense-in-depth measure that is specified in BIP-MuSig2. In fact, it revealed a bug in the `scriptless_atomic_swap` test.

ACKs for top commit:
  real-or-random:
    ACK a1ec2bb67b

Tree-SHA512: dfd54a07c13648e6a7163962bb516cc4ec3a25e4534da2c14a593e2da0f3779eb9b84bfa12ffd94676bb3f6ab86a323e7ec7dee938fd870f36882fee0181ca05
2023-03-03 16:53:29 +01:00
Jonas Nick
a1ec2bb67b musig: add test for signing with wrong secnonce for a keypair 2023-03-03 12:55:00 +00:00
Jonas Nick
bd57a017aa musig: include pubkey in secnonce and compare when signing 2023-03-03 12:55:00 +00:00
Tim Ruffing
5757318782 Merge bitcoin-core/secp256k1#1212: Prevent dead-store elimination when clearing secrets in examples
5660c13755 prevent optimization in algorithms (Harshil Jani)

Pull request description:

  Signed-off-by: Harshil Jani <harshiljani2002@gmail.com>

ACKs for top commit:
  sipa:
    utACK 5660c13755
  real-or-random:
    utACK 5660c13755

Tree-SHA512: 90024b7445c04e18a88af4099fc1ac6d1b9b2309b88dd22ae2b1f50aed7bac28b2c180cc28e1a95d5e9ec94b4c4adc44b9ada1477e6abe8efae7884c2382645c
2023-03-02 23:30:20 +01:00
Pieter Wuille
b081f7e4cb Add secp256k1_fe_add_int function 2023-03-02 17:09:25 -05:00
Tim Ruffing
4f57024d86 Merge ElementsProject/secp256k1-zkp#211: Update musig module to BIP MuSig2 v1.0.0-rc.3
b43dd83b43 musig: add missing static keyword to function (Jonas Nick)
068e6a036a musig: add test vectors from BIP MuSig (Jonas Nick)
36621d13be musig: update to BIP v1.0.0-rc.2 "Add ''pk'' arg to ''NonceGen''" (Jonas Nick)
d717a4980b musig: update to BIP v0.8 "Switch from X-only to plain pk inputs." (Jonas Nick)
304f1bc96d extrakeys: add pubkey_sort test vectors from BIP MuSig2 (Jonas Nick)
ae89051547 extrakeys: replace xonly_sort with pubkey_sort (Jonas Nick)
98242fcdd9 extrakeys: add secp256k1_pubkey_cmp (Jonas Nick)
73d5b6654d musig: update to BIP v0.7.0 (NonceGen) (Jonas Nick)
060887e9d7 musig: update to BIP v0.5.1 "Rename ordinary tweaking to plain" (Jonas Nick)
cbe2815633 musig: update to BIP v0.4 "Allow the output of NonceAgg to be inf" (Jonas Nick)
206017d67d musig: update to BIP v0.3 (NonceGen) (Jonas Nick)
d800dd55db musig: remove test vectors (Jonas Nick)

Pull request description:

  Version 1.0.0-rc.3 of BIP MuSig2 can be found [here](https://github.com/jonasnick/bips/pull/75). This PR does _not_ implement the following optional features that have been added to BIP MuSig2:

  - variable length messages
  - deterministic signing
  - identifiable aborts

  The PR also does _not_ yet change the `secnonce` structure to also contain the signer's public key (which would also imply changing the seckey argument in `sign` to a keypair). Additionally, we may want to rename some things in the future to be more consistent with the BIP (e.g. keyagg_cache vs. keyagg_ctx, applytweak vs. tweak_add).

ACKs for top commit:
  ariard:
    Light Code Review ACK b43dd83b, mostly looks on how the user API will make sense for Lightning, thanks for the answers!
  real-or-random:
    ACK b43dd83b43

Tree-SHA512: 9b1410951b55a1b0e6590b8c302052996d1fb6d9771765498b4282ff68b44ab0d6add8144c9330217b682ec5a93508b5546099db9a1f2c865f99253010dd76f4
2023-03-02 15:24:50 +01:00
Harshil Jani
5660c13755 prevent optimization in algorithms
Signed-off-by: Harshil Jani <harshiljani2002@gmail.com>

Add secure_erase function to clear secrets

Signed-off-by: Harshil Jani <harshiljani2002@gmail.com>

Update the function with good practices

Signed-off-by: Harshil Jani <harshiljani2002@gmail.com>

Renaming random.h to examples_util.h

Signed-off-by: Harshil Jani <harshiljani2002@gmail.com>
2023-03-02 15:36:41 +05:30
Tim Ruffing
09b1d466db Merge bitcoin-core/secp256k1#979: Native jacobi symbol algorithm
ce3cfc78a6 doc: Describe Jacobi calculation in safegcd_implementation.md (Elliott Jin)
6be01036c8 Add secp256k1_fe_is_square_var function (Pieter Wuille)
1de2a01c2b Native jacobi symbol algorithm (Pieter Wuille)
04c6c1b181 Make secp256k1_modinv64_det_check_pow2 support abs val (Pieter Wuille)
5fffb2c7af Make secp256k1_i128_check_pow2 support -(2^n) (Pieter Wuille)

Pull request description:

  This introduces variants of the vartime divsteps-based GCD algorithm used for modular inverses to compute Jacobi symbols. Changes compared to the normal vartime divsteps:
  * Only positive matrices are used, guaranteeing that f and g remain positive.
  * An additional jac variable is updated to track sign changes during matrix computation.
  * There is (so far) no proof that this algorithm terminates within reasonable amount of time for every input, but experimentally it appears to almost always need less than 900 iterations. To account for that, only a bounded number of iterations is performed (1500), after which failure is returned. The field logic then falls back to using square roots to determining the result.
  * The algorithm converges to f=g=gcd(f0,g0) rather than g=0. To keep this test simple, the end condition is f=1, which won't be reached if started with g=0. That case is dealt with specially.

  This code is currently unused, except for tests. I don't aim for it to be merged until there is a need for it, but this demonstrates its feasibility.

  In terms of performance:
  ```
  field_inverse: min 1.76us / avg 1.76us / max 1.78us
  field_inverse_var: min 0.991us / avg 0.993us / max 0.996us
  field_jacobi_var: min 1.31us / avg 1.31us / max 1.31us
  field_sqrt: min 4.36us / avg 4.37us / max 4.40us
  ```

  while with the older (f24e122d13) libgmp based Jacobi code on the same system:
  ```
  num_jacobi: min 1.53us / avg 1.54us / max 1.55us
  ```

ACKs for top commit:
  jonasnick:
    ACK ce3cfc78a6
  real-or-random:
    reACK ce3cfc78a6 diff and writeup is good and I tested every commit

Tree-SHA512: 8a6204a7a108d8802d942a54faca39917f90ea5923130683bbd870f9025f4ec8ef256ffa1d939a793f0b32d4cdfcdcd1d3f8ae5ed74a0193be7ad98362ce027e
2023-03-01 15:44:00 +01:00
Elliott Jin
ce3cfc78a6 doc: Describe Jacobi calculation in safegcd_implementation.md 2023-02-28 15:57:32 -05:00
Pieter Wuille
6be01036c8 Add secp256k1_fe_is_square_var function
The implementation calls the secp256k1_modinvNN_jacobi_var code, falling back
to computing a square root in the (extremely rare) case it failed converge.
2023-02-28 15:57:32 -05:00
Pieter Wuille
1de2a01c2b Native jacobi symbol algorithm
This introduces variants of the divsteps-based GCD algorithm used for
modular inverses to compute Jacobi symbols. Changes compared to
the normal vartime divsteps:
* Only positive matrices are used, guaranteeing that f and g remain
  positive.
* An additional jac variable is updated to track sign changes during
  matrix computation.
* There is (so far) no proof that this algorithm terminates within
  reasonable amount of time for every input, but experimentally it
  appears to almost always need less than 900 iterations. To account
  for that, only a bounded number of iterations is performed (1500),
  after which failure is returned. In VERIFY mode a lower iteration
  count is used to make sure that callers exercise their fallback.
* The algorithm converges to f=g=gcd(f0,g0) rather than g=0. To keep
  this test simple, the end condition is f=1, which won't be reached
  if started with non-coprime or g=0 inputs. Because of that we only
  support coprime non-zero inputs.
2023-02-28 15:54:00 -05:00
Pieter Wuille
04c6c1b181 Make secp256k1_modinv64_det_check_pow2 support abs val 2023-02-27 15:38:05 -05:00
Pieter Wuille
5fffb2c7af Make secp256k1_i128_check_pow2 support -(2^n) 2023-02-27 15:38:05 -05:00
Jonas Nick
8ec6d111c8 Merge elementsproject/secp256k1-zkp#205: Bulletproofs++: Norm argument
d7fb25c8ca Make sure that bppp_log2 isn't called with value 0 (Jonas Nick)
e5a01d12c6 Rename buletproof_pp* to bppp* (sanket1729)
c983186872 transcript: add tests (Jonas Nick)
73edc75528 norm arg: add verification vectors (Jonas Nick)
13ad32e814 norm arg: add tests for zero length and zero vectors (Jonas Nick)
34c4847a6a ci: add bulletproofs (Jonas Nick)
2574516483 Add testcases for bulletproofs++ norm arugment (sanket1729)
46c7391154 Add norm argument verify API (sanket1729)
d9145455bb Add bulletproofs++ norm argument prove API (sanket1729)
8638f0e0ce Add internal BP++ commit API (sanket1729)
412f8f66a0 Add utility functions required in norm argument (sanket1729)
420353d7da Add utilities for log2 (sanket1729)
17417d44f3 Add utilities from uncompressed Bulletproofs PR (sanket1729)
48563c8c79 bulletproofs: add API functionality to generate a large set of generators (Andrew Poelstra)
048f9f8642 bulletproofs: add new empty module (Andrew Poelstra)
6162d577fe generator: cleanups in Pedersen/generator code (Andrew Poelstra)
0a6006989f Revert "Remove unused scalar_sqr" (Andrew Poelstra)
87373f5145 MOVE ONLY: move Pedersen commitment stuff to generator module from rangeproof module (Andrew Poelstra)

Pull request description:

ACKs for top commit:
  Liam-Eagen:
    ACK d7fb25c
  jonasnick:
    ACK d7fb25c8ca

Tree-SHA512: 0a51e2b404ab594e4ce6c4a65a35f6bbf870d718e0a3cdf7ddd085ed37a0e0c0db55dabca8fe9d8b8beb3f7e60280aa46a2951408c18942dd6ad1c9a71bab5cd
2023-02-27 17:37:46 +00:00
Tim Ruffing
cbd2555934 Merge bitcoin-core/secp256k1#1209: build: Add SECP256K1_API_VAR to fix importing variables from DLLs
e4330341bd ci: Shutdown wineserver whenever CI script exits (Tim Ruffing)
9a5a611a21 build: Suppress stupid MSVC linker warning (Tim Ruffing)
739c53b19a examples: Extend sig examples by call that uses static context (Tim Ruffing)
914276e4d2 build: Add SECP256K1_API_VAR to fix importing variables from DLLs (Tim Ruffing)

Pull request description:

  ... and more Windows fixes, please see the individual commits.

  The fixed issues were discovered in https://github.com/bitcoin-core/secp256k1/pull/1198.

ACKs for top commit:
  sipa:
    utACK e4330341bd
  hebasto:
    ACK e4330341bd, tested on Windows using [CMake](https://github.com/bitcoin-core/secp256k1/pull/1113) (which means that the 3rd commit is reviewed only, but not tested). FWIW, `LNK4217` warnings have been indeed observed.

Tree-SHA512: ce7845b106190cdc517988c30aaf2cc9f1d6da22904dfc5cb6bf4ee05f063929dc8b3038479e703b6cebac79d1c21d0c84560344d2478cb1c1740087383f40e3
2023-02-22 00:41:04 +01:00
Pieter Wuille
1b21aa5175 Merge bitcoin-core/secp256k1#1078: group: Save a normalize_to_zero in gej_add_ge
e089eecc1e group: Further simply gej_add_ge (Tim Ruffing)
ac71020ebe group: Save a normalize_to_zero in gej_add_ge (Tim Ruffing)

Pull request description:

  As discovered  by sipa in #1033.

  See commit message for reasoning but note that the infinity handling will be replaced in the second commit again.

ACKs for top commit:
  sipa:
    ACK e089eecc1e
  apoelstra:
    ACK e089eecc1e

Tree-SHA512: fb1b5742e73dd8b2172b4d3e2852490cfd626e8673b72274d281fa34b04e9368a186895fb9cd232429c22b14011df136f4c09bdc7332beef2b3657f7f2798d66
2023-02-14 14:55:46 -05:00
Jonas Nick
d7fb25c8ca Make sure that bppp_log2 isn't called with value 0
Author:    Jonas Nick <jonasd.nick@gmail.com>
Date:      Thu Feb 9 21:31:43 2023 +0000
2023-02-13 23:53:36 -08:00
sanket1729
e5a01d12c6 Rename buletproof_pp* to bppp* 2023-02-13 22:16:17 -08:00
Jonas Nick
c983186872 transcript: add tests 2023-02-13 22:15:47 -08:00
Jonas Nick
73edc75528 norm arg: add verification vectors
norm arg: add verify test vector with vector size > 1
2023-02-13 22:15:47 -08:00
Jonas Nick
13ad32e814 norm arg: add tests for zero length and zero vectors 2023-02-13 22:15:47 -08:00
Jonas Nick
34c4847a6a ci: add bulletproofs 2023-02-13 22:15:47 -08:00
sanket1729
2574516483 Add testcases for bulletproofs++ norm arugment 2023-02-13 22:15:47 -08:00
sanket1729
46c7391154 Add norm argument verify API 2023-02-13 22:15:46 -08:00
Jonas Nick
b43dd83b43 musig: add missing static keyword to function 2023-02-13 14:03:51 +00:00
Jonas Nick
068e6a036a musig: add test vectors from BIP MuSig 2023-02-13 14:03:51 +00:00
Jonas Nick
36621d13be musig: update to BIP v1.0.0-rc.2 "Add ''pk'' arg to ''NonceGen''" 2023-02-13 14:03:51 +00:00
Jonas Nick
d717a4980b musig: update to BIP v0.8 "Switch from X-only to plain pk inputs." 2023-02-13 14:03:51 +00:00
Jonas Nick
304f1bc96d extrakeys: add pubkey_sort test vectors from BIP MuSig2 2023-02-13 14:03:51 +00:00
Jonas Nick
ae89051547 extrakeys: replace xonly_sort with pubkey_sort 2023-02-13 14:03:51 +00:00
Jonas Nick
98242fcdd9 extrakeys: add secp256k1_pubkey_cmp 2023-02-13 14:03:51 +00:00
Jonas Nick
73d5b6654d musig: update to BIP v0.7.0 (NonceGen)
- 0.7.0: Change ''NonceGen'' such that output when message is not present is different from when message is present but has length 0.
- 0.6.0: Change order of arguments and serialization of the message in the ''NonceGen'' hash function
2023-02-13 14:03:51 +00:00
Jonas Nick
060887e9d7 musig: update to BIP v0.5.1 "Rename ordinary tweaking to plain" 2023-02-13 14:03:51 +00:00
sanket1729
d9145455bb Add bulletproofs++ norm argument prove API 2023-02-08 13:07:05 -08:00
sanket1729
8638f0e0ce Add internal BP++ commit API 2023-02-08 13:07:05 -08:00
sanket1729
412f8f66a0 Add utility functions required in norm argument 2023-02-08 03:09:11 -08:00
sanket1729
420353d7da Add utilities for log2 2023-02-08 03:09:11 -08:00
sanket1729
17417d44f3 Add utilities from uncompressed Bulletproofs PR
Add a transcript module for doing a generic Fiat Shamir
2023-02-08 03:09:11 -08:00
Andrew Poelstra
48563c8c79 bulletproofs: add API functionality to generate a large set of generators 2023-02-08 03:09:11 -08:00
Andrew Poelstra
048f9f8642 bulletproofs: add new empty module 2023-02-08 03:09:11 -08:00
Andrew Poelstra
6162d577fe generator: cleanups in Pedersen/generator code
Silence a compiler warning about an unitialized use of a scalar in case
the user tries to provide a 0-length list of commitments.

Also ensures that commitments have normalized field elements when they
are loaded into ges.
2023-02-08 03:09:11 -08:00
Tim Ruffing
e4330341bd ci: Shutdown wineserver whenever CI script exits
Before: CI times out when a wine task fails.
After:  Wine tasks exit properly when they fail.
2023-02-06 21:44:56 +01:00
Tim Ruffing
9a5a611a21 build: Suppress stupid MSVC linker warning
... and use correct format to pass linker flags
2023-02-06 21:44:56 +01:00
Tim Ruffing
739c53b19a examples: Extend sig examples by call that uses static context
Besides improving the examples, this makes sure that the examples
import a variable (instead of a function), namely the static context,
from the library. This is helpful when testing MSVC builds, because
the MSVC linker tends to be awkward when importing variables.
2023-02-06 21:44:56 +01:00
Tim Ruffing
914276e4d2 build: Add SECP256K1_API_VAR to fix importing variables from DLLs
This fixes a build issue with MSVC. While MSVC imports *functions*
from DLLs automatically when building a consumer of the DLL, it does
not import *variables* automatically. In these cases, we need an
explicit __declspec(dllimport).

This commit simply changes our logic to what the libtool manual
suggests, which has a very comprehensive writeup on the topic. Note
that in particular, this solution is carefully designed not to break
static linking. However, as described in the libtool manual,
statically linking the library with MSVC will output warning LNK4217.
This is still the best solution overall, because the warning is
merely a cosmetic issue.
2023-02-06 21:44:56 +01:00
Tim Ruffing
1cca7c1744 Merge bitcoin-core/secp256k1#1206: build: Add -Wreserved-identifier supported by clang
8c7e0fc1de build: Add -Wreserved-identifier supported by clang (Tim Ruffing)

Pull request description:

  This warns on certain identifiers reserved by the C standard, namely
   * identifiers that begin with an underscore followed by an uppercase letter, and
   * identifiers in the global namespace that begin with an underscore.

  We had used such identifiers in the past for macros in include guards, and we should make sure that we don't reintroduce such identifiers going forward.

  Note that C reserves more identifiers for "future library directions", e.g., identifiers that begin with "str" followed by a lowercase letter. But even the C standards committee has decided that this is somewhat silly and adopted a proposal [1] for C23 that removes the restriction that programs using these identifiers have UB. Instead, these identifiers are now "potentially reserved", which is not a normative restriction but simply an informative warning that the identifiers may become fully reserved in the future.

  [1] https://www.open-std.org/jtc1/sc22/WG14/www/docs/n2625.pdf

ACKs for top commit:
  sipa:
    utACK 8c7e0fc1de
  jonasnick:
    tested ACK 8c7e0fc1de

Tree-SHA512: da0c5f1e36cffad2ab2f0b8055c8b3cb56e904d8bfea5a9eed9d6fa984359217b3ef3b9232bfb455cf4071c04a6c2a077e26d2a15b20d1eabc99b1fc61d2025c
2023-02-03 11:39:03 +01:00
Tim Ruffing
8c7e0fc1de build: Add -Wreserved-identifier supported by clang
This warns on certain identifiers reserved by the C standard, namely
 * identifiers that begin with an underscore followed by an uppercase
   letter, and
 * identifiers in the global namespace that begin with an underscore.

We had used such identifiers in the past for macros in include guards,
and we should make sure that we don't reintroduce such identifiers
going forward.

Note that C reserves more identifiers for "future library directions",
e.g., identifiers that begin with "str" followed by a lowercase letter.
But even the C standards committee has decided that this is somewhat
silly and adopted a proposal [1] for C23 that removes the restriction
that programs using these identifiers have UB. Instead, these
identifiers are now "potentially reserved", which is not a normative
restriction but simply an informative warning that the identifiers
may become fully reserved in the future.

[1] https://www.open-std.org/jtc1/sc22/WG14/www/docs/n2625.pdf
2023-02-02 14:56:58 +01:00
Tim Ruffing
ca92a35d01 field: Simplify code in secp256k1_fe_set_b32 2023-02-01 12:29:34 +01:00
Tim Ruffing
d93f62e369 field: Verify field element even after secp256k1_fe_set_b32 fails 2023-02-01 12:29:03 +01:00
Tim Ruffing
8ebe5c5205 Merge bitcoin-core/secp256k1#1201: ci: Do not set git's user.{email,name} config options
9b60e3148d ci: Do not set git's `user.{email,name}` config options (Hennadii Stepanov)

Pull request description:

  A cleanup after https://github.com/bitcoin-core/secp256k1/pull/1199.

  git's `user.{email,name}` config options have been no longer required since 0ecf318851.

ACKs for top commit:
  real-or-random:
    utACK 9b60e3148d

Tree-SHA512: 04f737b0549a91ca992cd1410420e041549a07869eeef068e08971781ea8a4c88a2486e789df36a5ad370ccbbf5d9f7e49ab5f7c1d01faef358ffc4863aaf8e4
2023-01-31 09:15:48 +01:00
Tim Ruffing
5596ec5c2c Merge bitcoin-core/secp256k1#1203: Do not link bench and ctime_tests to COMMON_LIB
ef39721ccc Do not link `bench` and `ctime_tests` to `COMMON_LIB` (Hennadii Stepanov)

Pull request description:

  The `bench` and `ctime_tests` binaries are users of the library, they should only be linked to the library, not the objects it was built from.

ACKs for top commit:
  sipa:
    utACK ef39721ccc
  real-or-random:
    utACK ef39721ccc

Tree-SHA512: 8bf8330adcce9bf6b21aceacf86e6aff7594762ab68b09257cfe2904fa0ce827377d5a13c0bed5acde74a2b420bb49460657c66d0068ecbe36dc162140876be4
2023-01-31 09:08:46 +01:00
Hennadii Stepanov
ef39721ccc Do not link bench and ctime_tests to COMMON_LIB
The `bench` and `ctime_tests` are users of the library, they should only
be linked to the library, not the objects it was built from.
2023-01-30 22:42:39 +00:00
Hennadii Stepanov
9b60e3148d ci: Do not set git's user.{email,name} config options
git's `user.{email,name}` config options have been no longer required
since 0ecf318851.
2023-01-30 16:29:46 +00:00
Tim Ruffing
e1817a6f54 Merge bitcoin-core/secp256k1#1199: ci: Minor improvements inspired by Bitcoin Core
c2415866c7 ci: Don't fetch git history (Tim Ruffing)
0ecf318851 ci: Use remote pull/merge ref instead of local git merge (Tim Ruffing)

Pull request description:

  This steals two recent CI improvements from bitcoin/bitcoin.  See individual commit messages.

ACKs for top commit:
  sipa:
    utACK c2415866c7

Tree-SHA512: 966130f45767c6bee8bc041d7e90a3166591a54c7cfccdcf4dff99aa4f6ccc2d02544fa7dca9fd020241349775da3cbd9bdbb041fcdd32de7426efd9dcc9c7f8
2023-01-30 11:06:19 +01:00
Pieter Wuille
1bff200588 Merge bitcoin-core/secp256k1#1200: Drop no longer used Autoheader macros
9b7d18669d Drop no longer used Autoheader macros (Hennadii Stepanov)

Pull request description:

  A cleanup after #1178.

ACKs for top commit:
  kevkevinpal:
    utACK [9b7d186](9b7d18669d)
  sipa:
    utACK 9b7d18669d
  real-or-random:
    utACK 9b7d18669d

Tree-SHA512: ce95547683580bde46a55a6adc3dc46aca02fc86b0300ce0598d62ed47f1d77c4fa9ffd38dcda858655cefa6c940260d05f42cca294e7f3e7a46394b117c9ce9
2023-01-29 23:43:03 -05:00
Hennadii Stepanov
9b7d18669d Drop no longer used Autoheader macros 2023-01-28 07:26:10 +00:00
Tim Ruffing
c2415866c7 ci: Don't fetch git history
(copied from bitcoin/bitcoin@faa65f12fc)
2023-01-27 22:44:11 +01:00
Tim Ruffing
0ecf318851 ci: Use remote pull/merge ref instead of local git merge
The merge strategy on the remote may be different than the local one.
This may cause local merges to be different or fail completely. Fix this
by using the result of the remote merge.

(copied from bitcoin/bitcoin@fad7281d78)
2023-01-27 22:38:45 +01:00
Andrew Poelstra
0a6006989f Revert "Remove unused scalar_sqr"
This reverts commit 5437e7bdfb.
2023-01-23 10:18:21 -08:00
Andrew Poelstra
87373f5145 MOVE ONLY: move Pedersen commitment stuff to generator module from rangeproof module
You can verify this commit with `git diff --color-moved=zebra`
2023-01-23 10:18:21 -08:00
Jonas Nick
b1f1675375 Merge elementsproject/secp256k1-zkp#214: sync-upstream: Fix $REPRODUCE_COMMAND for "select"
e04c660b11 sync-upstream: Fix $REPRODUCE_COMMAND for "select" (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    utACK e04c660b11

Tree-SHA512: 898b56f5931ef3a8e84546e5d2c0bd1a644cb7492aac4ecf80090edc250663b79b1bf4295a516868960c3a13113272f6fc50744b5daf0c90d5b9d9f561913c0b
2023-01-23 09:40:20 +00:00
Jonas Nick
cbe2815633 musig: update to BIP v0.4 "Allow the output of NonceAgg to be inf" 2023-01-23 09:36:46 +00:00
Jonas Nick
206017d67d musig: update to BIP v0.3 (NonceGen)
- 0.3.0: Hash i - 1 instead of i in NonceGen
- 0.2.0: Change order of arguments in NonceGen hash function
2023-01-23 09:36:45 +00:00
Jonas Nick
d800dd55db musig: remove test vectors
These vectors are superseded by test vectors in BIP MuSig2 which will be added
in a later commit.
2023-01-23 09:36:45 +00:00
Jonas Nick
a58c7d29bd Merge elementsproject/secp256k1-zkp#213: Update macOS image for CI
3b2c675955 Update macOS image for CI (Pieter Wuille)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK 3b2c675955
  jonasnick:
    ACK 3b2c675955

Tree-SHA512: 21987ea64929f7b43ea9a6f7eaa98bf47345aa03af10c45c0aa7a6e19b3a21c4a5d2aef0f6b99d6ddb4bf97752c8e2cdaeec619d4ef105e5d931790479de8ef5
2023-01-23 09:35:36 +00:00
Tim Ruffing
e04c660b11 sync-upstream: Fix $REPRODUCE_COMMAND for "select" 2023-01-20 17:09:18 +01:00
Pieter Wuille
3b2c675955 Update macOS image for CI 2023-01-20 07:08:50 -08:00
Pieter Wuille
2b77240b3b Merge bitcoin-core/secp256k1#1172: benchmarks: fix bench_scalar_split
eb6bebaee3 scalar: restrict split_lambda args, improve doc and VERIFY_CHECKs (Jonas Nick)
7f49aa7f2d ci: add test job with -DVERIFY (Jonas Nick)
620ba3d74b benchmarks: fix bench_scalar_split (Jonas Nick)

Pull request description:

  scalar_split_lambda requires that the input pointer is different to both output
  pointers. Without this fix, the internal benchmarks crash when compiled with
  -DVERIFY.

  This was introduced in commit 362bb25608 (which
  requires configuring with --enable-endomorphism to exhibit the crash).

  I tested that the new CI job would have caught this bug.

ACKs for top commit:
  sipa:
    utACK eb6bebaee3
  real-or-random:
    utACK eb6bebaee3

Tree-SHA512: c810545aefb01561ddb77b53618fa7acbb156ec13ab809c00523d4758492cafab1dfa01b6ebfb6195a3803bb49b16e63e8b0efcd1abb76ecefdb0476c3e483a3
2023-01-19 17:40:41 -05:00
Jonas Nick
eb6bebaee3 scalar: restrict split_lambda args, improve doc and VERIFY_CHECKs
VERIFY_CHECK(r1 != r2) is added because otherwise the verify_scalar_split fails.
2023-01-19 21:14:38 +00:00
Jonas Nick
7f49aa7f2d ci: add test job with -DVERIFY
This detects benchmarks that crash when VERIFY is defined.
2023-01-19 21:14:33 +00:00
Jonas Nick
620ba3d74b benchmarks: fix bench_scalar_split
scalar_split_lambda requires that the input pointer is different to both output
pointers. Without this fix, the internal benchmarks crash when compiled with
-DVERIFY.

This was introduced in commit 362bb25608 (which
requires configuring with --enable-endomorphism to exhibit the crash).
2023-01-19 18:12:31 +00:00
Pieter Wuille
5fbff5d348 Merge bitcoin-core/secp256k1#1170: contexts: Forbid destroying, cloning and randomizing the static context
e39d954f11 tests: Add CHECK_ILLEGAL(_VOID) macros and use in static ctx tests (Tim Ruffing)
61841fc9ee contexts: Forbid randomizing secp256k1_context_static (Tim Ruffing)
4b6df5e33e contexts: Forbid cloning/destroying secp256k1_context_static (Tim Ruffing)

Pull request description:

  As discussed in #1126.

  For randomization, this has a history. Initially, this threw the illegal callback but then we changed it to be a no-op on non-signing contexts: 6198375218 But this was with (non-static) none/verification contexts in mind, not with the static context. If we anyway forbid cloning the static context, you should never a way to randomize a copy of the static context. (You need a copy because the static context itself is not writable. But you cannot obtain a copy except when using memcpy etc.)

ACKs for top commit:
  sipa:
    utACK e39d954f11
  apoelstra:
    ACK e39d954f11

Tree-SHA512: dc804b15652d536b5d67db7297ac0e65eab3a64cbb35a9856329cb87e7ea0fe8ea733108104b3bba580077fe03d6ad6b161c797cf866a74722bab7849f0bb60c
2023-01-19 13:04:18 -05:00
Pieter Wuille
233822d849 Merge bitcoin-core/secp256k1#1195: ctime_tests: improve output when CHECKMEM_RUNNING is not defined
8f51229e03 ctime_tests: improve output when CHECKMEM_RUNNING is not defined (Jonas Nick)

Pull request description:

  When seeing the output
  ```
  Unless compiled under msan, this test can only usefully be run inside valgrind.
  ```
  I thought that I would have to go back to the `configure` output to manually check if it was compiled under memsan to determine whether this test can be usefully run outside valgrind. But when we go into this branch then it was definitely not compiled under msan, which means that we can make the output clearer.

ACKs for top commit:
  sipa:
    utACK 8f51229e03
  real-or-random:
    utACK 8f51229e03

Tree-SHA512: a4953a158b1375d8fc3a2ee29e7014c5399becf5f75ffd3765c0141861e092fbc120003e00dfd25ec54b92a466e133377b96d5a9f4017c100aaf64fb9a045df1
2023-01-19 11:00:16 -05:00
Pieter Wuille
ad7433b140 Merge bitcoin-core/secp256k1#1196: Drop no longer used variables from the build system
2cd4e3c0a9 Drop no longer used `SECP_{LIBS,INCLUDE}` variables (Hennadii Stepanov)
613626f94c Drop no longer used `SECP_TEST_{LIBS,INCLUDE}` variables (Hennadii Stepanov)

Pull request description:

  `SECP_INCLUDES`, `SECP_LIBS`, `SECP_TEST_LIBS` and `SECP_TEST_INCLUDES` were introduced in 78cd96b151.

  The last usage of the `SECP_TEST_{LIBS,INCLUDE}` variables was removed in https://github.com/bitcoin-core/secp256k1/pull/983.

  The last usage of the `SECP_LIBS` variable was removed in https://github.com/bitcoin-core/secp256k1/pull/831.

  The last usage of the `SECP_INCLUDE` variable was removed in https://github.com/bitcoin-core/secp256k1/pull/1169.

ACKs for top commit:
  sipa:
    utACK 2cd4e3c0a9
  real-or-random:
    utACK 2cd4e3c0a9

Tree-SHA512: ceee39dfb74aaeaa9a1e52fba819f32cee8e08922872bca2bfd6db8575c9b4695da476a4b8e8579abb92d6484fbf461e691369b160ecbc792261dbb454349efb
2023-01-19 10:57:46 -05:00
Tim Ruffing
e39d954f11 tests: Add CHECK_ILLEGAL(_VOID) macros and use in static ctx tests 2023-01-19 13:36:40 +01:00
Hennadii Stepanov
2cd4e3c0a9 Drop no longer used SECP_{LIBS,INCLUDE} variables
The last usage of the `SECP_INCLUDE` variable was removed
in https://github.com/bitcoin-core/secp256k1/pull/1169.
2023-01-19 09:43:28 +00:00
Hennadii Stepanov
613626f94c Drop no longer used SECP_TEST_{LIBS,INCLUDE} variables
The last usage of the `SECP_TEST_{LIBS,INCLUDE}` variables was removed
in https://github.com/bitcoin-core/secp256k1/pull/983.
2023-01-19 09:27:33 +00:00
Tim Ruffing
61841fc9ee contexts: Forbid randomizing secp256k1_context_static 2023-01-18 16:47:31 +01:00
Tim Ruffing
4b6df5e33e contexts: Forbid cloning/destroying secp256k1_context_static 2023-01-18 16:39:31 +01:00
Tim Ruffing
b1579cf5fb Merge bitcoin-core/secp256k1#1194: Ensure safety of ctz_debruijn implementation.
d6ff738d5b Ensure safety of ctz_debruijn implementation. (Russell O'Connor)

Pull request description:

  Adding `U` to the magic constants ensures that we are not mixing unsigned and signed value during multiplication, and ensures that the multiplication will not be subject to integer promotion.

  The `(uint32_t)`/`(uint64_t)` casts ensure the values are properly truncated no matter the size of an int.

  Prior to this commit, if `secp256k1_ctz32_var_debruijn` were some how managed to be built on a platform with 64-bit ints, (though this function is specifically only intended to be used on 32-bit platforms) it would perform an out-of-bounds array access.

ACKs for top commit:
  real-or-random:
    utACK d6ff738d5b
  apoelstra:
    ACK d6ff738d5b

Tree-SHA512: f2292fa6e03deff4598514f9070b1357ce307ce1d2b34c15da120198c2f9171dfae9e0aaddb99f2c577ec368a903337eb68281518e93e43c381c9875aa84144e
2023-01-18 10:37:07 +01:00
Jonas Nick
8f51229e03 ctime_tests: improve output when CHECKMEM_RUNNING is not defined 2023-01-18 09:02:47 +00:00
Russell O'Connor
d6ff738d5b Ensure safety of ctz_debruijn implementation.
Adding U to the magic constants ensures that we are not mixing unsigned and signed value during multiplication, and ensures that the multiplication will not be subject to integer promotion.

The (uint32_t)/(uint64_t) casts ensure the values are properly truncated no matter the size of an int.

Prior to this commit, if secp256k1_ctz32_var_debruijn were some how managed to be built on a platform with 64-bit ints, (though this function is specifically only intended to be used on 32-bit platforms) it would perform an out-of-bounds array access.
2023-01-16 22:23:57 -05:00
Tim Ruffing
a01a7d86dc Merge bitcoin-core/secp256k1#1192: Switch to exhaustive groups with small B coefficient
ce60785b26 Introduce SECP256K1_B macro for curve b coefficient (Pieter Wuille)
4934aa7995 Switch to exhaustive groups with small B coefficient (Pieter Wuille)

Pull request description:

  This has the advantage that in the future, multiplication with B can be done using `secp256k1_fe_mul_int` rather than the slower `secp256k1_fe_mul`.

ACKs for top commit:
  real-or-random:
    ACK ce60785b26 also ran the exhaustive tests with the group of size 7
  apoelstra:
    ACK ce60785b26

Tree-SHA512: 006041189d18319ddb9c0ed54e479f393b83ab2a368d198bd24860d1d2574c0c1a311aea24fbef2e74bb7859a687dfc803b9e963e6dc5c61cb707e20f52b5a70
2023-01-16 22:36:15 +01:00
Tim Ruffing
a7a7bfaf3d Merge bitcoin-core/secp256k1#1190: Make all non-API functions (except main) static
e03ef86559 Make all non-API functions (except main) static (Pieter Wuille)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK e03ef86559
  hebasto:
    ACK e03ef86559.

Tree-SHA512: 36a35d9a8da05411c88644aec81e79883febce3e08c9eb6b0ec95cfc3705fd6abfd66f7ee10dfa081ca20786d26b0a060ead7f5c8109bf02a73dde7ef811144b
2023-01-16 18:46:37 +01:00
Tim Ruffing
f29a327092 Merge bitcoin-core/secp256k1#1169: Add support for msan instead of valgrind (for memcheck and ctime test)
0f088ec112 Rename CTIMETEST -> CTIMETESTS (Pieter Wuille)
74b026f05d Add runtime checking for DECLASSIFY flag (Pieter Wuille)
5e2e6fcfc0 Run ctime test in Linux MSan CI job (Pieter Wuille)
18974061a3 Make ctime tests building configurable (Pieter Wuille)
5048be17e9 Rename valgrind_ctime_test -> ctime_tests (Pieter Wuille)
6eed6c18de Update error messages to suggest msan as well (Pieter Wuille)
8e11f89a68 Add support for msan integration to checkmem.h (Pieter Wuille)
8dc64079eb Add compile-time error to valgrind_ctime_test (Pieter Wuille)
0db05a770e Abstract interactions with valgrind behind new checkmem.h (Pieter Wuille)
4f1a54e41d Move valgrind CPPFLAGS into SECP_CONFIG_DEFINES (Pieter Wuille)

Pull request description:

  This introduces an abstraction layer `src/checkmem.h`, which defines macros for interacting with memory checking tools. Depending on the environment, they're mapped to MemorySanitizer builtins, Valgrind integration macros, or nothing at all.

  This means that msan builds immediately benefit from existing undefined memory checks in the tests. It also means those builds result in a `ctime_tests` (new name for `valgrind_ctime_test`) binary that can usefully test constant-timeness (not inside Valgrind, and with the downside that it's not running against a production library build, but it's faster and available on more platforms).

  Such an msan-ctime test is added to the Linux x86_64 msan CI job, as an example. More CI cases could be added (e.g. for MacOs or ARM Linux) later.

ACKs for top commit:
  real-or-random:
    ACK 0f088ec112
  hebasto:
    ACK 0f088ec112, I have reviewed the code and it looks OK. Able to build `ctime_tests` using MSan.

Tree-SHA512: f4ffcc0c2ea794894662d9797b3a349770a4b361996f967f33d7d14b332171de5d525f50bcebaeaf7d0624957083380962079c75e490d1b7d71f8f9eb6211590
2023-01-16 16:03:05 +01:00
Tim Ruffing
ff8edf89e2 Merge bitcoin-core/secp256k1#1193: Add noverify_tests to .gitignore
d4a6b58df7 Add `noverify_tests` to `.gitignore` (Hennadii Stepanov)

Pull request description:

  This is a follow up of #1188.

ACKs for top commit:
  sipa:
    ACK d4a6b58df7
  real-or-random:
    utACK d4a6b58df7

Tree-SHA512: a249c949d4b1432c6a5ff05a49f51a1f605f026ce6faa01bebee12a49d1ad2e38a344c35d2a21b827ceb40190448306262af7ca9a4385ebd96115d18ace42856
2023-01-14 03:46:44 +01:00
Pieter Wuille
ce60785b26 Introduce SECP256K1_B macro for curve b coefficient 2023-01-13 17:05:39 -05:00
Pieter Wuille
4934aa7995 Switch to exhaustive groups with small B coefficient 2023-01-13 17:05:35 -05:00
Hennadii Stepanov
d4a6b58df7 Add noverify_tests to .gitignore 2023-01-13 18:46:57 +00:00
Tim Ruffing
88e80722d2 Merge bitcoin-core/secp256k1#1160: Makefile: add -I$(top_srcdir)/{include,src} to CPPFLAGS for precomputed
e862c4af0c Makefile: add -I$(top_srcdir)/src to CPPFLAGS for precomputed (Matt Whitlock)

Pull request description:

  When performing an out-of-source-tree build, regenerating the source files for the precomputed ecmult tables places them outside the source tree. Then, when they are to be compiled, they cannot find the headers they need because the source tree is absent from their include search path. This appears to have been an oversight, as the relevant `-I` options are present in `libsecp256k1_la_CPPFLAGS` but were missing from `libsecp256k1_precomputed_la_CPPFLAGS`. This PR adds them.

ACKs for top commit:
  sipa:
    utACK e862c4af0c
  real-or-random:
    ACK e862c4af0c

Tree-SHA512: f58b8670b2798f2ca4bd6e9fd83218afcd14cf1b796cd18fb40e7b8a148dcdfabe5f0beae81bc6b82727c97a507431e6a7c72d756587e047daf1ea81242cccf9
2023-01-12 10:50:57 +01:00
Pieter Wuille
0f088ec112 Rename CTIMETEST -> CTIMETESTS 2023-01-11 16:07:37 -05:00
Pieter Wuille
74b026f05d Add runtime checking for DECLASSIFY flag 2023-01-11 16:07:37 -05:00
Pieter Wuille
5e2e6fcfc0 Run ctime test in Linux MSan CI job 2023-01-11 16:07:37 -05:00
Pieter Wuille
18974061a3 Make ctime tests building configurable 2023-01-11 16:07:37 -05:00
Pieter Wuille
5048be17e9 Rename valgrind_ctime_test -> ctime_tests 2023-01-11 16:07:37 -05:00
Pieter Wuille
6eed6c18de Update error messages to suggest msan as well 2023-01-11 16:07:37 -05:00
Pieter Wuille
8e11f89a68 Add support for msan integration to checkmem.h 2023-01-11 16:07:37 -05:00
Pieter Wuille
8dc64079eb Add compile-time error to valgrind_ctime_test 2023-01-11 16:07:37 -05:00
Pieter Wuille
0db05a770e Abstract interactions with valgrind behind new checkmem.h 2023-01-11 16:07:35 -05:00
Pieter Wuille
4f1a54e41d Move valgrind CPPFLAGS into SECP_CONFIG_DEFINES 2023-01-11 16:03:15 -05:00
Tim Ruffing
cc3b8a4f40 Merge bitcoin-core/secp256k1#1187: refactor: Rename global variables in tests
9a93f48f50 refactor: Rename STTC to STATIC_CTX in tests (Tim Ruffing)
3385a2648d refactor: Rename global variables to uppercase in tests (Tim Ruffing)

Pull request description:

  On top of #1186 .

  I feel that this is an improvement, but it touches a lot of lines and so it deserves a separate discussion.

ACKs for top commit:
  sipa:
    ACK 9a93f48f50

Tree-SHA512: b6dad2ffff2267034bf8cefdd3ef7ea11e9bcb8142d64b460ca61e0d3ab8de22fb3ee994dea0fb32feee3864d07395c070abffab318690d09d104294895300c4
2023-01-11 10:55:14 +01:00
Tim Ruffing
9a93f48f50 refactor: Rename STTC to STATIC_CTX in tests 2023-01-10 18:43:09 +01:00
Tim Ruffing
3385a2648d refactor: Rename global variables to uppercase in tests 2023-01-10 18:43:09 +01:00
Pieter Wuille
e03ef86559 Make all non-API functions (except main) static 2023-01-09 12:02:27 -05:00
Pieter Wuille
cbe41ac138 Merge bitcoin-core/secp256k1#1188: tests: Add noverify_tests which is like tests but without VERIFY
203760023c tests: Add noverify_tests which is like tests but without VERIFY (Tim Ruffing)

Pull request description:

  mentioned in https://github.com/bitcoin-core/secp256k1/issues/1037#issuecomment-1371870423

  Let's see how this affects CI time

ACKs for top commit:
  sipa:
    ACK 203760023c
  apoelstra:
    ACK 203760023c

Tree-SHA512: fab1ce1499d418671d3d0ecfddf15d75b7c2bbfbfb4be958a95730491244185a906c7133aba4d0bec56ee6c721cb525750eef4cafc12f386484af931e34b0e8e
2023-01-09 11:06:24 -05:00
Tim Ruffing
203760023c tests: Add noverify_tests which is like tests but without VERIFY 2023-01-07 23:13:06 +01:00
Matt Whitlock
e862c4af0c Makefile: add -I$(top_srcdir)/src to CPPFLAGS for precomputed
When performing an out-of-source-tree build, regenerating the source
files for the precomputed ecmult tables places them outside the source
tree. Then, when they are to be compiled, they cannot find the headers
they need because the source tree is absent from their include search
path. This appears to have been an oversight, as the relevant -I options
are present in libsecp256k1_la_CPPFLAGS but were missing from
libsecp256k1_precomputed_la_CPPFLAGS. This commit adds them.
2023-01-06 18:20:05 -05:00
Tim Ruffing
0eb3000417 Merge bitcoin-core/secp256k1#1186: tests: Tidy context tests
39e8f0e3d7 refactor: Separate run_context_tests into static vs proper contexts (Tim Ruffing)
a4a09379b1 tests: Clean up and improve run_context_tests() further (Tim Ruffing)
fc90bb5695 refactor: Tidy up main() (Tim Ruffing)
f32a36f620 tests: Don't use global context for context tests (Tim Ruffing)
ce4f936c4f tests: Tidy run_context_tests() by extracting functions (Tim Ruffing)
18e0db30cb tests: Don't recreate global context in scratch space test (Tim Ruffing)
b19806122e tests: Use global copy of secp256k1_context_static instead of clone (Tim Ruffing)

Pull request description:

  This is an improved version of some of the tidying/refactoring in #1170.

  I think it's enough to deserve a separate PR. Once this is merged, I'll get back to the actual goal of #1170 (namely, forbidding cloning and randomizing static contexts.)

  This PR is a general clean up of the context tests. A notable change is that this avoids a code smell where `run_context_tests()` would use the global `ctx` variable like a local one (i.e., create a context in it and destroy it afterwards).  After this PR, the global `ctx` is properly initialized for all the other tests, and they can decide whether they want to use it or not. Same for a global `sttc`, which is a memcpy of the static context (we need a writable copy in order to be able to set callbacks).

  Note that this touches code which is also affected by #1167 but I refrained from trying to solve this issue. The goal of this PR is simply not to worsen the situation w.r.t. #1167. We should really introduce a macro to solve #1167 but that's another PR.

ACKs for top commit:
  sipa:
    utACK 39e8f0e3d7
  apoelstra:
    ACK 39e8f0e3d7

Tree-SHA512: a22471758111061a062b126a52a0de24a1a311d1a0332a4ef006882379a4f3f2b00e53089e3c374bf47c4051bb10bbc6a9fdbcf6d0cd4eca15b5703590395fba
2023-01-06 11:52:59 +01:00
Tim Ruffing
39e8f0e3d7 refactor: Separate run_context_tests into static vs proper contexts 2023-01-05 10:28:10 +01:00
Tim Ruffing
a4a09379b1 tests: Clean up and improve run_context_tests() further 2023-01-05 10:28:10 +01:00
Tim Ruffing
fc90bb5695 refactor: Tidy up main() 2023-01-05 10:28:10 +01:00
Tim Ruffing
f32a36f620 tests: Don't use global context for context tests 2023-01-05 10:28:10 +01:00
Tim Ruffing
ce4f936c4f tests: Tidy run_context_tests() by extracting functions 2023-01-05 10:28:04 +01:00
Tim Ruffing
18e0db30cb tests: Don't recreate global context in scratch space test 2023-01-04 16:52:36 +01:00
Tim Ruffing
b19806122e tests: Use global copy of secp256k1_context_static instead of clone 2023-01-04 16:39:50 +01:00
Tim Ruffing
2a39ac162e Merge bitcoin-core/secp256k1#1185: Drop SECP_CONFIG_DEFINES from examples
2f9ca284e2 Drop `SECP_CONFIG_DEFINES` from examples (Hennadii Stepanov)

Pull request description:

  User applications shouldn't need or rely on `SECP_CONFIG_DEFINES`.

  See https://github.com/bitcoin-core/secp256k1/pull/1178#discussion_r1059457252.

ACKs for top commit:
  sipa:
    utACK 2f9ca284e2
  real-or-random:
    utACK 2f9ca284e2

Tree-SHA512: c8e81e6842b31e7f4ebcbb18d5962f7d7308f024025d6225330a7ec099739278bb43ad98243698c5802bcc49bf7e247ab7cae7f40008fbba87f0d0e46cbe1e85
2023-01-03 21:03:40 +01:00
Hennadii Stepanov
2f9ca284e2 Drop SECP_CONFIG_DEFINES from examples
User applications shouldn't need or rely on `SECP_CONFIG_DEFINES`.
2023-01-03 17:33:32 +00:00
Tim Ruffing
31ed5386e8 Merge bitcoin-core/secp256k1#1183: Bugfix: pass SECP_CONFIG_DEFINES to bench compilation
c0a555b2ae Bugfix: pass SECP_CONFIG_DEFINES to bench compilation (Pieter Wuille)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK c0a555b2ae
  apoelstra:
    ACK c0a555b2ae

Tree-SHA512: 4ec6ca4c012166beb6c5bdd1b2ed939554415e03545c176cf281000145c4000a460e231d5da26f617a81b048cd0fa3f8f16b61a207aed9479fdd854483e35ded
2023-01-02 13:02:40 +01:00
Pieter Wuille
c0a555b2ae Bugfix: pass SECP_CONFIG_DEFINES to bench compilation 2022-12-29 15:31:55 -05:00
Tim Ruffing
01b819a8c7 Merge bitcoin-core/secp256k1#1158: Add a secp256k1_i128_to_u64 function.
d216475205 test secp256k1_i128_to_i64 (Russell O'Connor)
4bc429019d Add a secp256k1_i128_to_u64 function. (Russell O'Connor)

Pull request description:

  I wanted to experiment with what would be required to split up `secp256k1_i128_to_i64` between those cases when a signed 64 bit value is being demoted, versus an unsigned 64 bit value is being extracted from the lower bits, and this is the result.

  I'm not sure this is a useful PR, so feel free to close it.  However, since it is already written, I figured it is worth at least discussing.

ACKs for top commit:
  sipa:
    utACK d216475205
  real-or-random:
    ACK d216475205

Tree-SHA512: 41dbb1d33b3078bee8e71a838cfad6f1859c0bba602ae061259add8e9e8ea5aa482daa41de79dbd7433ddbef4a0bc52757f3c45d63acc9c0eb05aa3ca891b922
2022-12-21 17:25:07 +01:00
Jonas Nick
eacad90f69 Merge bitcoin-core/secp256k1#1171: Change ARG_CHECK_NO_RETURN to ARG_CHECK_VOID which returns (void)
a49e0940ad docs: Fix typo (Tim Ruffing)
2551cdac90 tests: Fix code formatting (Tim Ruffing)
c635c1bfd5 Change ARG_CHECK_NO_RETURN to ARG_CHECK_VOID which returns (void) (Tim Ruffing)
cf66f2357c refactor: Add helper function secp256k1_context_is_proper() (Tim Ruffing)

Pull request description:

ACKs for top commit:
  sipa:
    utACK a49e0940ad
  jonasnick:
    ACK a49e0940ad

Tree-SHA512: 0fd4ee88510f2de0de96378ae69ce6e610a446000bb78597026c5924803e1ce5a4f76303fc6446233a6129f9c42dce1b1549f93bef935131101e47b5a69cdf2f
2022-12-21 15:28:10 +00:00
Jonas Nick
3f57b9f774 Merge bitcoin-core/secp256k1#1177: Some improvements to the changelog
c30b889f17 Clarify that the ABI-incompatible versions are earlier (Pieter Wuille)
881fc33d0c Consistency in naming of modules (Pieter Wuille)
9ecf8149a1 Reduce font size in changelog (Pieter Wuille)
2dc133a67f Add more changelog entries (Pieter Wuille)
ac233e181a Add links to diffs to changelog (Pieter Wuille)
cee8223ef6 Mention semantic versioning in changelog (Pieter Wuille)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK c30b889f17
  jonasnick:
    ACK c30b889f17

Tree-SHA512: 0f753eae0ea4d65035bfbcd81b90169111ea030cf7196dd072fb1ccc8aac1437768031f3fcef431584028da68b66873204e16e03bcde4a6ae96b08ab7f97a480
2022-12-20 19:43:06 +00:00
Pieter Wuille
c30b889f17 Clarify that the ABI-incompatible versions are earlier 2022-12-20 11:09:37 -05:00
Pieter Wuille
881fc33d0c Consistency in naming of modules 2022-12-20 11:09:13 -05:00
Pieter Wuille
665ba77e79 Merge bitcoin-core/secp256k1#1178: Drop src/libsecp256k1-config.h
9c5a4d21bb Do not define unused `HAVE_VALGRIND` macro (Hennadii Stepanov)
ad8647f548 Drop no longer relevant files from `.gitignore` (Hennadii Stepanov)
b627ba7050 Remove dependency on `src/libsecp256k1-config.h` (Hennadii Stepanov)

Pull request description:

  Cherry-picked the first commit from #1142 and addressed a [comment](https://github.com/bitcoin-core/secp256k1/pull/1142#issuecomment-1295099597).

ACKs for top commit:
  sipa:
    utACK 9c5a4d21bb
  real-or-random:
    utACK 9c5a4d21bb

Tree-SHA512: c6f268261fc5edee855a7e69fdf9f6c5f4b859eb1e078e3c44c3ee4c9c445738af3de9fc2fbcca90db9b9e38681da8217faaeb0735201052b16ea397a7817db9
2022-12-19 22:43:47 -05:00
Tim Ruffing
75d7b7f5ba Merge bitcoin-core/secp256k1#1154: ci: set -u in cirrus.sh to treat unset variables as an error
7a74688201 ci: add missing CFLAGS & CPPFLAGS variable to print_environment (Jonas Nick)
c2e0fdadeb ci: set -u in cirrus.sh to treat unset variables as an error (Jonas Nick)

Pull request description:

  This PR is supposed to prevent accidental misuse of cirrus.sh. Maybe there is a way to check if `CC`, `AR` and `NM` are set within the loop that deals with the other variables, but so far I did not come up with one (that's POSIX shell compliant).

ACKs for top commit:
  real-or-random:
    ACK 7a74688201
  hebasto:
    re-ACK 7a74688201

Tree-SHA512: 91e42b3f1192fbf86e6fb43942713e78b2bee977ddd95256ea7448f84324369399d31ec4eedd47af595bf994bbc9396e26bb5c93bdb7f58c4310b5d3d5d66731
2022-12-19 14:57:55 +01:00
Jonas Nick
7a74688201 ci: add missing CFLAGS & CPPFLAGS variable to print_environment 2022-12-19 13:22:28 +00:00
Jonas Nick
c2e0fdadeb ci: set -u in cirrus.sh to treat unset variables as an error 2022-12-19 13:22:18 +00:00
Hennadii Stepanov
9c5a4d21bb Do not define unused HAVE_VALGRIND macro 2022-12-15 20:06:55 +00:00
Hennadii Stepanov
ad8647f548 Drop no longer relevant files from .gitignore 2022-12-15 10:56:29 +00:00
Hennadii Stepanov
b627ba7050 Remove dependency on src/libsecp256k1-config.h
This change eases the use of alternate build systems by moving
the variables in `src/libsecp256k1-config.h` to compiler macros
for each invocation, preventing duplication of these variables
for each build system.

Co-authored-by: Ali Sherief <ali@notatether.com>
2022-12-15 10:56:16 +00:00
Pieter Wuille
9ecf8149a1 Reduce font size in changelog 2022-12-13 12:06:42 -05:00
Pieter Wuille
2dc133a67f Add more changelog entries 2022-12-13 12:05:10 -05:00
Pieter Wuille
ac233e181a Add links to diffs to changelog 2022-12-13 11:53:50 -05:00
Pieter Wuille
cee8223ef6 Mention semantic versioning in changelog 2022-12-13 11:50:32 -05:00
Jonas Nick
9a8d65f07f Merge bitcoin-core/secp256k1#1174: release cleanup: bump version after 0.2.0
02ebc290f7 release cleanup: bump version after 0.2.0 (Jonas Nick)
b6b360efaf doc: improve message of cleanup commit (Jonas Nick)

Pull request description:

ACKs for top commit:
  sipa:
    ACK 02ebc290f7

Tree-SHA512: b887e31a531f7d21025558ed0a64ff5f68dee6feff8288478f7eb023189ceb20e5ca8baf0434ebd2ee49488d35d7aebc1b837888ff8c6e6420e6b86cc2f99cb1
2022-12-12 22:21:26 +00:00
Jonas Nick
02ebc290f7 release cleanup: bump version after 0.2.0 2022-12-12 22:08:22 +00:00
Jonas Nick
b6b360efaf doc: improve message of cleanup commit 2022-12-12 22:08:13 +00:00
Pieter Wuille
21ffe4b22a Merge bitcoin-core/secp256k1#1055: Prepare initial release
e025ccdf74 release: prepare for initial release 0.2.0 (Jonas Nick)
6d1784a2e2 build: add missing files to EXTRA_DIST (Jonas Nick)
13bf1b6b32 changelog: make order of change types match keepachangelog.com (Jonas Nick)
b1f992a552 doc: improve release process (Jonas Nick)
ad39e2dc41 build: change package version to 0.1.0-dev (Jonas Nick)
90618e9263 doc: move CHANGELOG from doc/ to root directory (Jonas Nick)

Pull request description:

  Based on #964

ACKs for top commit:
  sipa:
    ACK e025ccdf74

Tree-SHA512: b9ab71d7362537d383a32b5e321ef44069f00e3e92340375bcd662267bc5a60c2bad60222998e6602cfac24ad65efb23d772eac37c86065036b90ef090b54c49
2022-12-12 17:01:25 -05:00
Jonas Nick
e025ccdf74 release: prepare for initial release 0.2.0
There are plenty of unreleased variants of libsecp256k1 version 0.1.0
(libsecp256k1.so.0.0.0) in the wild. We choose a new version number to allow a
clear distinction.

There are variants of 0.1.0 that are incompatible with the initial release,
hence we increase the minor version to arrive at version number 0.2.0. For the
same reason, we increase the LIB_VERSION_CURRENT and keep AGE at 0.

The changelog for 0.2.0 consists of the relevant changes since 2021-12-25, which
is the date when the initial release process PR was merged (and the library
version was set to a pre-release, see 423b6d19d3).
This is somewhat arbitrary but at least points readers to relevant changes.
2022-12-12 21:26:36 +00:00
Jonas Nick
6d1784a2e2 build: add missing files to EXTRA_DIST 2022-12-12 21:26:32 +00:00
Jonas Nick
8c949f56da Merge bitcoin-core/secp256k1#1173: Don't use compute credits for now
7e5b22684f Don't use compute credits for now (Pieter Wuille)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 7e5b22684f

Tree-SHA512: 5f37521dede4270151f4f1ed59e021f78e39b7e3362f4c16ecf2b7733dd1d49306466cc4e9b7837be10769c86799905fb1305cb35fe5cae0366a7f7861e6e9df
2022-12-12 20:10:04 +00:00
Jonas Nick
13bf1b6b32 changelog: make order of change types match keepachangelog.com 2022-12-12 19:53:36 +00:00
Jonas Nick
b1f992a552 doc: improve release process
- make version on master always equal to latest release with patch+1
- separate regular from maintenance releases
- add more git commands to prevent accidents
- mention that one needs to somehow deal with release dates
- _LIB_VERSIONS_ -> _LIB_VERSION_
- don't push all tags in step 4
- add required message to git tag
- add suggested commit messages
2022-12-12 19:53:27 +00:00
Pieter Wuille
7e5b22684f Don't use compute credits for now 2022-12-12 08:35:36 -05:00
Tim Ruffing
a49e0940ad docs: Fix typo 2022-12-08 16:31:00 +01:00
Tim Ruffing
2551cdac90 tests: Fix code formatting 2022-12-08 16:30:26 +01:00
Tim Ruffing
c635c1bfd5 Change ARG_CHECK_NO_RETURN to ARG_CHECK_VOID which returns (void) 2022-12-08 16:30:26 +01:00
Tim Ruffing
cf66f2357c refactor: Add helper function secp256k1_context_is_proper() 2022-12-08 16:30:26 +01:00
Jonas Nick
ad39e2dc41 build: change package version to 0.1.0-dev
The suffix -dev is slightly clearer.

Also, since the package version follows semantic versioning, rename
VERSION_BUILD to VERSION_PATCH for clarity.
2022-12-07 22:07:05 +00:00
Tim Ruffing
5c789dcd73 Merge bitcoin-core/secp256k1#1168: Replace deprecated context flags with NONE in benchmarks and tests
d6dc0f4ae3 tests: Switch to NONE contexts in module tests (Jonas Nick)
0c8a5caddd tests: Switch to NONE contexts in tests.c (Jonas Nick)
86540e9e1f tests: add test for deprecated flags and rm them from run_context (Jonas Nick)
caa0ad631e group: add gej_eq_var (Jonas Nick)
37ba744f5b tests: Switch to NONE contexts in exhaustive and ctime tests (Jonas Nick)
8d7a9a8eda benchmarks: Switch to NONE contexts (Jonas Nick)

Pull request description:

  Based on #1126.

ACKs for top commit:
  real-or-random:
    ACK d6dc0f4ae3 diff looks good and tests pass locally
  sipa:
    utACK d6dc0f4ae3

Tree-SHA512: 1fb1dc1336409b52827787a03c791a21ee1d6b1bdc388d1fa126600572f348ba16865a01d29bac67b36b8f29f30cda117d82913e2044ccb9d073f5d04338ac9f
2022-12-07 16:32:12 +01:00
Jonas Nick
d6dc0f4ae3 tests: Switch to NONE contexts in module tests 2022-12-07 10:54:50 +00:00
Jonas Nick
0c8a5caddd tests: Switch to NONE contexts in tests.c 2022-12-07 10:54:50 +00:00
Jonas Nick
86540e9e1f tests: add test for deprecated flags and rm them from run_context 2022-12-07 10:54:50 +00:00
Jonas Nick
caa0ad631e group: add gej_eq_var 2022-12-07 10:54:50 +00:00
Jonas Nick
37ba744f5b tests: Switch to NONE contexts in exhaustive and ctime tests 2022-12-07 10:54:50 +00:00
Jonas Nick
8d7a9a8eda benchmarks: Switch to NONE contexts 2022-12-07 10:54:43 +00:00
Jonas Nick
90618e9263 doc: move CHANGELOG from doc/ to root directory 2022-12-06 15:29:50 +00:00
Jonas Nick
e3f84777eb Merge bitcoin-core/secp256k1#1126: API cleanup with respect to contexts
4386a2306c examples: Switch to NONE contexts (Tim Ruffing)
7289b51d31 docs: Use doxygen style if and only if comment is user-facing (Tim Ruffing)
e7d0185c90 docs: Get rid of "initialized for signing" terminology (Tim Ruffing)
06126364ad docs: Tidy and improve docs about contexts and randomization (Tim Ruffing)
e02d6862bd selftest: Expose in public API (Tim Ruffing)
e383fbfa66 selftest: Rename internal function to make name available for API (Tim Ruffing)
d2c6d48de3 tests: Use new name of static context (Tim Ruffing)
53796d2b24 contexts: Rename static context (Tim Ruffing)
72fedf8a6c docs: Improve docs for static context (Tim Ruffing)
316ac7625a contexts: Deprecate all context flags except SECP256K1_CONTEXT_NONE (Tim Ruffing)
1a553ee8be docs: Change signature "validation" to "verification" (Tim Ruffing)
ee7341fbac docs: Never require a verification context (Tim Ruffing)

Pull request description:

ACKs for top commit:
  sipa:
    utACK 4386a2306c
  jonasnick:
    ACK 4386a2306c

Tree-SHA512: 7bf07dfae0ecbf7de1418de64ef743a23dc5f244aeba2c1cf3ecbdc117d6ac12bb6c8f17f739605566074a9b901765ee4a32288b6edc6f9a0040a70cb472f6ee
2022-12-06 08:15:03 +00:00
Tim Ruffing
4386a2306c examples: Switch to NONE contexts 2022-12-05 11:26:44 +01:00
Tim Ruffing
7289b51d31 docs: Use doxygen style if and only if comment is user-facing
and improve phrasing slightly.
2022-12-05 11:26:44 +01:00
Tim Ruffing
e7d0185c90 docs: Get rid of "initialized for signing" terminology 2022-12-05 11:26:44 +01:00
Tim Ruffing
06126364ad docs: Tidy and improve docs about contexts and randomization 2022-12-05 11:26:44 +01:00
Tim Ruffing
e02d6862bd selftest: Expose in public API 2022-12-05 11:26:44 +01:00
Tim Ruffing
e383fbfa66 selftest: Rename internal function to make name available for API 2022-12-05 11:26:44 +01:00
Tim Ruffing
d2c6d48de3 tests: Use new name of static context 2022-12-05 11:26:44 +01:00
Tim Ruffing
53796d2b24 contexts: Rename static context 2022-12-05 11:26:44 +01:00
Tim Ruffing
72fedf8a6c docs: Improve docs for static context 2022-12-05 11:26:39 +01:00
Tim Ruffing
316ac7625a contexts: Deprecate all context flags except SECP256K1_CONTEXT_NONE 2022-12-05 11:26:02 +01:00
Jonas Nick
477f02c4de Merge bitcoin-core/secp256k1#1165: gitignore: Add *.sage.py files autogenerated by sage [skip ci]
092be61c5e gitignore: Add *.sage.py files autogenerated by sage (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 092be61c5e

Tree-SHA512: ee77e8634814ccc1894eb633816da877a4d4511d9e77f5628b19e0e37006d43ae45431dfd1b30977504a5975a92a2b1824ed53c7837fb5600994d11003996b86
2022-12-01 14:46:40 +00:00
Tim Ruffing
092be61c5e gitignore: Add *.sage.py files autogenerated by sage 2022-12-01 12:07:00 +01:00
Tim Ruffing
1a553ee8be docs: Change signature "validation" to "verification" 2022-11-25 23:26:15 +01:00
Tim Ruffing
ee7341fbac docs: Never require a verification context 2022-11-25 23:26:15 +01:00
Jonas Nick
751c4354d5 Merge bitcoin-core/secp256k1#1152: Update macOS image for CI
a8494b02bf Use compute credits for macOS jobs (Pieter Wuille)
c0ae48c995 Update macOS image for CI (Pieter Wuille)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK a8494b02bf
  jonasnick:
    ACK a8494b02bf

Tree-SHA512: af99585ef68fc8305785885efaf0a0ebe45e5765661d654523a36ba843fc83e0ac40a554638437fa53804e4aa42dbcd92d597702ee6225b66a044a6304bafd45
2022-11-24 21:53:02 +00:00
Tim Ruffing
2286f80902 Merge bitcoin-core/secp256k1#993: Enable non-experimental modules by default
41e8704b48 build: Enable some modules by default (Tim Ruffing)

Pull request description:

  This has been discussed in https://github.com/bitcoin-core/secp256k1/issues/817#issuecomment-693198323 and I agree with the arguments brought up there.

  Alternatively, we could not enable them and add a discussion to the readme why we discourage people from using the modules. I believe enabling ECDH is not very controversial. But what about recovery? Do we want to leave it off and instead give a reason?

ACKs for top commit:
  sipa:
    ACK 41e8704b48
  jonasnick:
    ACK 41e8704b48

Tree-SHA512: 1dd21037043f2b2c94a92cd2f31e69b505ba5b43119897bc0934966d9ccd84fc4fc20e7509af634f1c3a096710db1a2253090f5f1f107b9d258945a5546e9ba4
2022-11-22 12:53:48 +01:00
Russell O'Connor
d216475205 test secp256k1_i128_to_i64 2022-11-21 11:16:56 -05:00
Russell O'Connor
4bc429019d Add a secp256k1_i128_to_u64 function. 2022-11-21 11:03:44 -05:00
Tim Ruffing
e40fd277b7 Merge bitcoin-core/secp256k1#1156: Followups to int128_struct arithmetic
99bd335599 Make int128 overflow test use secp256k1_[ui]128_mul (Pieter Wuille)
3afce0af7c Avoid signed overflow in MSVC AMR64 secp256k1_mul128 (Pieter Wuille)
9b5f589d30 Heuristically decide whether to use int128_struct (Pieter Wuille)
63ff064d2f int128: Add test override for testing __(u)mulh on MSVC X64 (Tim Ruffing)
f2b7e88768 Add int128 randomized tests (Pieter Wuille)

Pull request description:

  This is a follow-up to #1000:
  * Add randomized unit tests for int128 logic.
  * Add CI for the `_(u)mulh` code path (on non-ARM64 MSVC).
  * Add heuristic logic to enable int128_struct based arithmetic on 64-bit MSVC, or systems with pointers wider than 32 bits.
  * Fix signed overflow in ARM64 MSVC code.

ACKs for top commit:
  roconnor-blockstream:
    utACK 99bd335
  real-or-random:
    ACK 99bd335599 tested this also on MSVC locally with the override, including all the benchmark binaries
  jonasnick:
    utACK 99bd335599

Tree-SHA512: 5ea897362293b45a86650593e1fdc8c4004a1d9452eed2fa070d22dffc7ed7ca1ec50a4df61e3a33dbe35e08132ad9686286ac44af6742b32b82f11c9d3341c6
2022-11-18 16:51:07 -05:00
Pieter Wuille
99bd335599 Make int128 overflow test use secp256k1_[ui]128_mul 2022-11-17 12:22:29 -05:00
Pieter Wuille
a8494b02bf Use compute credits for macOS jobs 2022-11-17 10:20:16 -05:00
Pieter Wuille
3afce0af7c Avoid signed overflow in MSVC AMR64 secp256k1_mul128 2022-11-17 09:44:10 -05:00
Pieter Wuille
c0ae48c995 Update macOS image for CI 2022-11-17 09:34:51 -05:00
Pieter Wuille
9b5f589d30 Heuristically decide whether to use int128_struct 2022-11-17 09:28:30 -05:00
Tim Ruffing
63ff064d2f int128: Add test override for testing __(u)mulh on MSVC X64
Also add a corresponding CI job
2022-11-17 09:28:30 -05:00
Pieter Wuille
f2b7e88768 Add int128 randomized tests 2022-11-17 09:28:30 -05:00
Jonas Nick
6138d73be4 Merge bitcoin-core/secp256k1#1155: Add MSan CI jobs
00a42b91b3 Add MSan CI job (Pieter Wuille)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK 00a42b91b3
  jonasnick:
    ACK 00a42b91b3

Tree-SHA512: 0b9ced572430e917041c916d8cda5c94996899a6e0a8c5a13f73f2c99b58b0098f7562cd758b48f18bec8c7095fab37980aa6dc2b139b2d1c293c965ea603686
2022-11-17 11:06:56 +00:00
Tim Ruffing
ddf2b2910e Merge bitcoin-core/secp256k1#1000: Synthetic int128 type.
a340d9500a ci: add int128_struct tests (Jonas Nick)
dceaa1f579 int128: Tidy #includes of int128.h and int128_impl.h (Tim Ruffing)
2914bccbc0 Simulated int128 type. (Russell O'Connor)

Pull request description:

  Abstracts the int128 type and provides an native version, if available, or a implements it using a pair of int64_t's.

  This is activated by setting the configuration flag `--with-test-override-wide-multiply=int128_struct`.

  The primary purpose of this PR is to take advantage of MSVC's [umulh](https://docs.microsoft.com/en-us/cpp/intrinsics/umulh?view=msvc-170) intrinsic that we can use to simulate an int128 type which MSVC does not have (AFAIU). This PR lays out the groundwork for this level of MSVC support, but doesn't include the configuration logic to enable it yet.

  For completeness, and implementation of `umulh` and `mulh` are also provided for compilers that support neither the intrinsic nor the int128 type (such as CompCert?).  This also opens up the possibility of removing the 32-bit field and scalar implementations should that ever be desired.

ACKs for top commit:
  sipa:
    ACK a340d9500a
  jonasnick:
    ACK a340d9500a

Tree-SHA512: b4f2853fa3ab60ce9d77b4eaee1fd20c4b612850e19fcb3179d7e36986f420c6c4589ff72f0cf844f989584ace49a1cd23cca3f4e405dabefc8da647a0df679d
2022-11-16 14:37:01 -05:00
Tim Ruffing
86e3b38a4a Merge bitcoin-core/secp256k1#1149: Remove usage of CHECK from non-test file
6a965b6b98 Remove usage of CHECK from non-test file (Tobin C. Harding)

Pull request description:

  Currently CHECK is used only in test and bench mark files except for one usage in `ecmult_impl.h`.

  We would like to move the definition of CHECK out of `util.h` so that `util.h` no longer has a hard dependency on `stdio.h`.

  Done as part of an effort to allow secp256k1 to be compiled to WASM as part of `rust-secp256k1`.

  ### Note to reviewers

  Please review carefully, I don't actually know if this patch is correct. Done while working on #1095. I'm happy to make any changes both in concept and execution - I'm super rusty at C programming.

  cc real-or-random

ACKs for top commit:
  sipa:
    utACK 6a965b6b98
  real-or-random:
    utACK 6a965b6b98

Tree-SHA512: 6bfb456bdb92a831acd3bc202607e80f6d0a194d6b2cf745c8eceb12ba675d03a319d6d105332b0cbca474e443969295e5a8e938635453e21e057d0ee597440b
2022-11-16 14:22:06 -05:00
Pieter Wuille
00a42b91b3 Add MSan CI job 2022-11-16 13:36:56 -05:00
Tim Ruffing
44916ae915 Merge bitcoin-core/secp256k1#1147: ci: print env to allow reproducing the job outside of CI
4e54c03153 ci: print env to allow reproducing the job outside of CI (Jonas Nick)

Pull request description:

  Example output:

  ```
  WERROR_CFLAGS="-Werror -pedantic-errors"  MAKEFLAGS="-j4"  BUILD="check"  ECMULTWINDOW="auto"  ECMULTGENPRECISION="auto"  ASM="no"  WIDEMUL="int64"  WITH_VALGRIND="no"  EXTRAFLAGS=""  EXPERIMENTAL="no"  ECDH="no"  RECOVERY="yes"  SCHNORRSIG="no"  SECP256K1_TEST_ITERS=""  BENCH="yes"  SECP256K1_BENCH_ITERS="2"  CTIMETEST="yes"  EXAMPLES="yes"  WRAPPER_CMD=""  CC="gcc"  AR=""  NM=""  HOST=""  ./ci/cirrus.sh
  ```

ACKs for top commit:
  sipa:
    ACK 4e54c03153
  real-or-random:
    ACK 4e54c03153

Tree-SHA512: b74a8724e72b3de7884e4d93fe933dc5043aec37020672b7997a8faebda3b0cbbba1bca69c344109729261ab4a94e76f4eca0d8773dc101a443fdf9e0d7d54f5
2022-11-14 18:01:49 -05:00
Jonas Nick
c2ee9175e9 Merge bitcoin-core/secp256k1#1146: ci: prevent "-v/--version: not found" irrelevant error
49ae843592 ci: mostly prevent "-v/--version: not found" irrelevant error (Jonas Nick)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 49ae843592

Tree-SHA512: 2e048b037826dff372e26103f198e0d490494e7909d17d8632b51f6d9e0629b51bcd0b55b65b2c21d63d522394ccfed481ce126cea165c087df670556bc8ccf6
2022-11-08 13:26:06 +00:00
Jonas Nick
e13fae487e Merge bitcoin-core/secp256k1#1150: ci: always cat test_env.log
5c9f1a5c37 ci: always cat all logs_snippets (Jonas Nick)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 5c9f1a5c37

Tree-SHA512: fc715c5fc4006d80a4b0c2faa8ef81ed23c4479614945ffa7c96665a3acc38fe956dd6d148bcf97043232ceee055b724ea9490e4ac4142a210e4488fed8dd299
2022-11-08 13:24:29 +00:00
Jonas Nick
a340d9500a ci: add int128_struct tests 2022-11-07 16:55:43 -05:00
Tim Ruffing
dceaa1f579 int128: Tidy #includes of int128.h and int128_impl.h
After this commit, int128.h and int128_impl.h are included as follows:
 - .c files which use int128 include int128_impl.h (after util.h)
 - .h files which use int128 include int128.h (after util.h)

This list is exhaustive. util.h needs to included first because it sets
up necessary #defines.
2022-11-07 16:38:30 -05:00
Russell O'Connor
2914bccbc0 Simulated int128 type. 2022-11-07 16:37:24 -05:00
Tobin C. Harding
6a965b6b98 Remove usage of CHECK from non-test file
Currently CHECK is used only in test and bench mark files except for one
usage in `ecmult_impl.h`.

We would like to move the definition of CHECK out of `util.h` so that
`util.h` no longer has a hard dependency on `stdio.h`.

Done in preparation for moving the definition of `CHECK` as part of an
effort to allow secp256k1 to be compiled to WASM as part of
`rust-secp256k1`.
2022-11-08 07:29:52 +11:00
Jonas Nick
5c9f1a5c37 ci: always cat all logs_snippets 2022-11-07 20:12:33 +00:00
Jonas Nick
49ae843592 ci: mostly prevent "-v/--version: not found" irrelevant error
$CC, $WRAPPER_CMD and valgrind are not necessarily defined
2022-11-02 17:13:21 +00:00
Jonas Nick
4e54c03153 ci: print env to allow reproducing the job outside of CI 2022-11-02 15:57:14 +00:00
Jonas Nick
a43e982bca Merge bitcoin-core/secp256k1#1144: Cleanup .gitignore file
f5039cb66c Cleanup `.gitignore` file (Hennadii Stepanov)
798727ae1e Revert "Add test logs to gitignore" (Hennadii Stepanov)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK f5039cb66c
  real-or-random:
    ACK f5039cb66c

Tree-SHA512: 3586329e77958a9bfa06dd84e5b121cd456e93332670d5afc1a6691e165cdfa5a6fd6a61f82be12ec33f2a58b26a13adfedeb177ae1056202e53a530949fc549
2022-11-01 16:32:30 +00:00
Hennadii Stepanov
f5039cb66c Cleanup .gitignore file
The removed line was introduced for `obj/.gitignore` file. Since the
`obj` directory has been removed, it is not longer required.
2022-10-28 16:30:20 +01:00
Hennadii Stepanov
798727ae1e Revert "Add test logs to gitignore"
This reverts commit bceefd6547.
2022-10-28 16:10:46 +01:00
Jonas Nick
d22774e248 Merge elementsproject/secp256k1-zkp#203: MuSig doc fixes
dd83e72d52 Add ordinary tweak info (Jesse Posner)
d26100cab2 Exclude nonce_process from pre-processing steps (Jesse Posner)
b7607f93f2 Fix reference to xonly_tweak_add (Jesse Posner)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK dd83e72d52

Tree-SHA512: b5b94e94625e235557d4a0d9973b14ef74be153b6bdd9a0701add9aa8af4a54411344030db2e65aaac701e3e6a0c1f46190f0d760f7314d426d077959271b615
2022-09-02 12:20:12 +00:00
Jesse Posner
dd83e72d52 Add ordinary tweak info 2022-09-01 22:39:34 -07:00
Jesse Posner
d26100cab2 Exclude nonce_process from pre-processing steps 2022-09-01 22:39:22 -07:00
Jesse Posner
b7607f93f2 Fix reference to xonly_tweak_add 2022-09-01 22:38:03 -07:00
Jonas Nick
f7e9a8544f Merge elementsproject/secp256k1-zkp#201: rangeproof: add secp256k1_rangeproof_max_size function to estimate rangeproof size
6b6ced9839 rangeproof: add more max_size tests (Jonas Nick)
34876ecb5f rangeproof: add more static test vectors (Jonas Nick)
310e517061 rangeproof: add a bunch more testing (Andrew Poelstra)
f1410cb67a rangeproof: add secp256k1_rangeproof_max_size function to estimate rangeproof size (Andrew Poelstra)

Pull request description:

ACKs for top commit:
  real-or-random:
    tACK 6b6ced9839
  jonasnick:
    ACK 6b6ced9839

Tree-SHA512: 421dfb0824f67f3822be729dc7f11e4654a21e32e3a6c5565e09b191ec57710b33a73c3d09c08f1d767d769f0957006ac257eabe00a2f37f88b99377644e8741
2022-08-25 20:21:47 +00:00
Jonas Nick
6b6ced9839 rangeproof: add more max_size tests 2022-08-25 14:26:02 +00:00
Jonas Nick
34876ecb5f rangeproof: add more static test vectors
Fixes #42
2022-08-25 14:26:02 +00:00
Andrew Poelstra
310e517061 rangeproof: add a bunch more testing
Add two new fixed rangeproof vectors; check that various extracted
values are correct; add a test for creating and verifying single-value
proofs.
2022-08-25 14:26:02 +00:00
Andrew Poelstra
f1410cb67a rangeproof: add secp256k1_rangeproof_max_size function to estimate rangeproof size
Provides a method that will give an upper bound on the size of a rangeproof,
given an upper bound on the value to be passed in and an upper bound on the
min_bits parameter.

There is a lot of design freedom here since the actual size of the rangeproof
depends on every parameter passed to rangeproof_sign, including the value to
be proven, often in quite intricate ways. For the sake of simplicity we assume
a nonzero `min_value` and that `exp` will be 0 (the default, and size-maximizing,
choice), and provide an exact value for a proof of the given value and min_bits.
2022-08-25 14:26:00 +00:00
Jonas Nick
c137ddbdff Merge elementsproject/secp256k1-zkp#200: build: automatically enable module dependencies
171b294a1c build: improve error message if --enable-experimental is missed (Jonas Nick)
58ab152bb4 build: move all output concerning enabled modules at single place (Jonas Nick)
1493113e61 build: automatically enable module dependencies (Jonas Nick)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK 171b294a1c

Tree-SHA512: 644e7d96b02c1f4f0751cf84b268f313cc0bd955ea6eacdeddb932b9ba7990be8e8aca9db8c050fd91a35d0a0173061e40fe8c1bf8bfd03107b86aa1bf85e871
2022-08-22 14:45:42 +00:00
Jonas Nick
0202d839fb Merge elementsproject/secp256k1-zkp#199: surjectionproof: make sure that n_used_pubkeys > 0 in generate
5ac8fb035e surjectionproof: make sure that n_used_pubkeys > 0 in generate (Jonas Nick)

Pull request description:

ACKs for top commit:
  apoelstra:
    utACK 5ac8fb035e

Tree-SHA512: 915f7181e69e2c4e1f830d6c2620a2d9b0af4d2ae8a63709b489b01ed9e13ccfeeaedebd4680cf2d927cd473a6ae88602cf29e2fdd116cb597fba6c0ab77720d
2022-08-18 19:54:00 +00:00
Jonas Nick
5ac8fb035e surjectionproof: make sure that n_used_pubkeys > 0 in generate
If the proof was generated with surjectionproof_initialize (as mandated by the
API docs), then n_used_pubkeys can never be 0. Without this commit, compilers
will (rightfully) warn that borromean_s[ring_input_index] is not initialized in
surjectionproof_generate. Therefore, this commit makes sure that n_used_pubkeys
is greater than 0 which ensures that the array is initialized at
ring_input_index.
2022-08-15 20:01:39 +00:00
Andrew Poelstra
7ff446df8b Merge ElementsProject/secp256k1-zkp#198: rangeproof: add a test for all-zero blinding factors
5a40f3d99b replace memcmp with secp256k1_memcmp_var throughout the codebase (Andrew Poelstra)
92820d944b rangeproof: add a test for all-zero blinding factors (Andrew Poelstra)

Pull request description:

  I was curious about under what conditions you can create a rangeproof on an "unblinded" commitment which has a zero blinding factor. Apparently the answer is "when you are proving at least 3-bits". In this case rewinding words and you can encode 32 bytes of data. (In fact I believe you can encode up to 128 but I haven't tested that.)

ACKs for top commit:
  real-or-random:
    utACK 5a40f3d99b

Tree-SHA512: bed7f9362d082d2b56668809077d5ddde52280109c992a290d87b55cb70138a08799fcca18cafbb3b3e9efed4349418bf9bb2c0ccedacdce0567e841e6d21e13
2022-08-12 23:55:46 +00:00
Andrew Poelstra
5a40f3d99b replace memcmp with secp256k1_memcmp_var throughout the codebase
memcmp only appears in -zkp-specific modules. Fix those.
2022-08-10 22:14:31 +00:00
Andrew Poelstra
92820d944b rangeproof: add a test for all-zero blinding factors 2022-08-10 22:10:33 +00:00
Jonas Nick
171b294a1c build: improve error message if --enable-experimental is missed 2022-08-10 09:20:26 +00:00
Jonas Nick
58ab152bb4 build: move all output concerning enabled modules at single place 2022-08-10 09:04:47 +00:00
Jonas Nick
1493113e61 build: automatically enable module dependencies 2022-08-10 08:58:29 +00:00
Tim Ruffing
4fd7e1eabd Merge ElementsProject/secp256k1-zkp#197: fix include paths in all the -zkp modules
347f96d94a fix include paths in all the -zkp modules (Andrew Poelstra)

Pull request description:

  This is causing out-of-tree build failures in Elements.

ACKs for top commit:
  real-or-random:
    utACK 347f96d94a

Tree-SHA512: 7d6211f3b8d5612f95bcb3085c22458e7ceaa79f1ee74e37404cc6d1fdf0fbc02b4443b02623b9b6c1225437c1a1954b6d36a953d52b020ac7913326404894e0
2022-08-05 23:42:10 +02:00
Andrew Poelstra
347f96d94a fix include paths in all the -zkp modules
This is causing out-of-tree build failures in Elements.
2022-08-05 14:56:10 +00:00
Tim Ruffing
41e8704b48 build: Enable some modules by default
We don't enable the ECDSA recovery module, because we don't recommend
ECDSA recovery for new protocols. In particular, the recovery API is
prone to misuse: It invites the caller to forget to check the public
key (and the verification function always returns 1).

In general, we also don't recommend ordinary ECDSA for new protocols.
But disabling the ECDSA functions is not possible because they're not
in a module, and let's be honest: disabling ECDSA would mean to ignore
reality blatantly.
2022-08-03 17:09:54 +02:00
Tim Ruffing
694ce8fb2d Merge bitcoin-core/secp256k1#1131: readme: Misc improvements
88b00897e7 readme: Fix line break (Tim Ruffing)
78f5296da4 readme: Sell "no runtime dependencies" (Tim Ruffing)
ef48f088ad readme: Add IRC channel (Tim Ruffing)

Pull request description:

ACKs for top commit:
  apoelstra:
    utACK 88b00897e7
  sipa:
    ACK 88b00897e7

Tree-SHA512: 174f1596406f98a19059a18cd4fb993102e5ffb8ec29fcc6d03e27f135fcb526b37204b64055b5e4f0a273daab05d395cf335f26241cf3a29a060041c9ef109b
2022-08-02 17:33:21 +02:00
Tim Ruffing
88b00897e7 readme: Fix line break 2022-08-02 10:41:15 +02:00
Tim Ruffing
78f5296da4 readme: Sell "no runtime dependencies" 2022-08-02 10:41:15 +02:00
Tim Ruffing
ef48f088ad readme: Add IRC channel 2022-08-02 10:41:15 +02:00
Tim Ruffing
d1d6e47c17 Merge ElementsProject/secp256k1-zkp#196: surjectionproof: fail to generate proofs when an input equals the output
d1175d265d surjectionproof: use secp256k1_memcmp_var rather than bare memcmp (Andrew Poelstra)
bf18ff5a8c surjectionproof: fix generation to fail when any input == the output (Andrew Poelstra)
4ff6e4274d surjectionproof: add test for existing behavior on input=output proofs (Andrew Poelstra)

Pull request description:

  If any ephemeral input tag equals the ephemeral output tag (i.e. an input asset is exactly equal to the output asset), verification will fail due to an unexpected interaction between our surjectionproof logic and the underlying borromean ring siganture logic. However, our generation code still allows creating proofs like this, "succeeding" in creating bad proofs.

  Since we cannot fix the verification side without hardforking Liquid, fix the generation side to fail in this situation.

ACKs for top commit:
  real-or-random:
    utACK d1175d265d

Tree-SHA512: c15e130de028d6c1f705543fe2774ec23016c71f9d6b38ef0708820a517d156e2126f8369e94f16f9fd1855c29cd907d406f6ea26c95499a9ae1ce0dd92f77b2
2022-08-01 13:25:31 +02:00
Andrew Poelstra
d1175d265d surjectionproof: use secp256k1_memcmp_var rather than bare memcmp
Co-authored-by: Tim Ruffing <crypto@timruffing.de>
2022-07-29 21:04:04 +00:00
Andrew Poelstra
bf18ff5a8c surjectionproof: fix generation to fail when any input == the output
Verification will fail in this case, so don't "succeed" in generating a bad proof.
2022-07-26 17:14:49 +00:00
Andrew Poelstra
4ff6e4274d surjectionproof: add test for existing behavior on input=output proofs 2022-07-26 17:09:36 +00:00
Tim Ruffing
9f8a13dc8e Merge bitcoin-core/secp256k1#1128: configure: Remove pkgconfig macros again (reintroduced by mismerge)
cabe085bb4 configure: Remove pkgconfig macros again (reintroduced by mismerge) (Tim Ruffing)

Pull request description:

  We had removed `PKG_PROG_PKG_CONFIG` in 21b2ebaf74
  (#1090). But then then the not rebased (!) merge of 2be6ba0fed
  (#1084) brought that macro back at another location, without git
  complaining about a conflict.

  Fixes #1127.

ACKs for top commit:
  fanquake:
    ACK cabe085bb4
  hebasto:
    ACK cabe085bb4
  jonasnick:
    ACK cabe085bb4

Tree-SHA512: ba497503db3a11e631b15c4fe875e62d892971c2c708d90b2f6be684e85d164043ea97c13af0452831eef41f3cf8230cd8a9eafa332dc5b5ae18e118b87c3828
2022-07-21 12:06:35 +02:00
Tim Ruffing
cabe085bb4 configure: Remove pkgconfig macros again (reintroduced by mismerge)
We had removed `PKG_PROG_PKG_CONFIG` in 21b2ebaf74
(#1090). But then then the not rebased (!) merge of 2be6ba0fed
(#1084) brought that macro back at another location, without git
complaining about a conflict.

Fixes #1127.
2022-07-21 11:10:05 +02:00
Tim Ruffing
71a206fa5b Merge ElementsProject/secp256k1-zkp#194: extrakeys: rename swap/swap64 to fix OpenBSD 7.1 compilation
db648478c3 extrakeys: rename swap/swap64 to fix OpenBSD 7.1 compilation (Jon Griffiths)

Pull request description:

  OpenBSD defines swap64 in <endian.h>.

ACKs for top commit:
  real-or-random:
    ACK db648478c3
  jonasnick:
    ACK db648478c3

Tree-SHA512: a3bf4175918c06457ec941eb029fded98d367c82a352024a9f96919219cc494e40f96e090dc03b73d0d22b99374f0656f27b755a56caebcd5df27efbd978fd56
2022-07-20 21:07:32 +02:00
Jon Griffiths
db648478c3 extrakeys: rename swap/swap64 to fix OpenBSD 7.1 compilation
OpenBSD defines swap64 in <endian.h>.
2022-07-18 12:29:54 +12:00
Jonas Nick
3efeb9da21 Merge bitcoin-core/secp256k1#1121: config: Set preprocessor defaults for ECMULT_* config values
c27ae45144 config: Remove basic-config.h (Tim Ruffing)
da6514a04a config: Introduce DEBUG_CONFIG macro for debug output of config (Tim Ruffing)
d0cf55e13a config: Set preprocessor defaults for ECMULT_* config values (Tim Ruffing)

Pull request description:

ACKs for top commit:
  sipa:
    ACK c27ae45144
  hebasto:
    ACK c27ae45144, I have reviewed the code and it looks correct.
  jonasnick:
    ACK c27ae45144

Tree-SHA512: 56b0f384bd9f42cf7c903bec08f4807db1415ddf9a06676dfe1e638e4d02431c522ef0422585e85429074e0dbb51da4f400cf53e8f883d6e07122731c57be1e3
2022-07-11 12:14:25 +00:00
Jonas Nick
6a873cc4a9 Merge bitcoin-core/secp256k1#1122: tests: Randomize the context with probability 15/16 instead of 1/4
17065f48ae tests: Randomize the context with probability 15/16 instead of 1/4 (Tim Ruffing)

Pull request description:

ACKs for top commit:
  sipa:
    ACK 17065f48ae
  jonasnick:
    ACK 17065f48ae

Tree-SHA512: 3b7005770007b922a294be610f23da60b0dde74dfd7585d64a2cb04eaa6ec879de8d21a0ade31c1857019a8dd97260fa3aa167ae16fc55027ef280a3e3feaa6d
2022-07-11 11:21:57 +00:00
Tim Ruffing
17065f48ae tests: Randomize the context with probability 15/16 instead of 1/4 2022-07-08 18:45:32 +02:00
Tim Ruffing
c27ae45144 config: Remove basic-config.h
It's unused and thus potentially confusing.
2022-07-07 20:32:18 +02:00
Tim Ruffing
da6514a04a config: Introduce DEBUG_CONFIG macro for debug output of config 2022-07-07 20:32:08 +02:00
Tim Ruffing
63a3565e97 Merge bitcoin-core/secp256k1#1120: ecmult_gen: Skip RNG when creating blinding if no seed is available
55f8bc99dc ecmult_gen: Improve comments about projective blinding (Tim Ruffing)
7a86955800 ecmult_gen: Simplify code (no observable change) (Tim Ruffing)
4cc0b1b669 ecmult_gen: Skip RNG when creating blinding if no seed is available (Tim Ruffing)

Pull request description:

  Running the RNG is pointless if no seed is available because the key
  will be fixed. The computation just wastes time.

  Previously, users could avoid this computation at least by asking for
  a context without signing capabilities. But since 3b0c218 we always
  build an ecmult_gen context, ignoring the context flags. Moreover,
  users could never avoid this pointless computation when asking for
  the creation of a signing context.

  This fixes one item in #1065.

ACKs for top commit:
  sipa:
    ACK 55f8bc99dc
  apoelstra:
    ACK 55f8bc99dc

Tree-SHA512: 5ccba56041f94fa8f40a8a56ce505369ff2e0ed20cd7f0bfc3fdfffa5fa7bf826a93602b9b2455a352865a9548ab4928e858c19bb5af7ec221594a3bf25c4f3d
2022-07-07 20:08:17 +02:00
Tim Ruffing
d0cf55e13a config: Set preprocessor defaults for ECMULT_* config values
This simplifies manual builds and solves one item in #929.
2022-07-06 15:07:57 +02:00
Tim Ruffing
55f8bc99dc ecmult_gen: Improve comments about projective blinding
Whenever I read this code, I first think that rescaling ctx->initial is
a dead store because we overwrite it later with gb. But that's wrong.
The rescaling blinds the computation of gb and affects its result.
2022-07-05 19:28:09 +02:00
Tim Ruffing
7a86955800 ecmult_gen: Simplify code (no observable change) 2022-07-05 19:28:09 +02:00
Tim Ruffing
4cc0b1b669 ecmult_gen: Skip RNG when creating blinding if no seed is available
Running the RNG is pointless if no seed is available because the key
will be fixed. The computation just wastes time.

Previously, users could avoid this computation at least by asking for
a context without signing capabilities. But since 3b0c218 we always
build an ecmult_gen context, ignoring the context flags. Moreover,
users could never avoid this pointless computation when asking for
the creation of a signing context.
2022-07-05 19:27:47 +02:00
Tim Ruffing
af65d30cc8 Merge bitcoin-core/secp256k1#1116: build: Fix #include "..." paths to get rid of further -I arguments
40a3473a9d build: Fix #include "..." paths to get rid of further -I arguments (Tim Ruffing)

Pull request description:

  This simplifies building without a build system.

  This is in line with #925; the paths fixed here were either forgotten
  there or only introduced later. This commit also makes the Makefile
  stricter so that further "wrong" #include paths will lead to build
  errors even in autotools builds.

  This belongs to #929.

ACKs for top commit:
  hebasto:
    ACK 40a3473a9d

Tree-SHA512: 6f4d825ea3cf86b13f294e2ec19fafc29660fa99450e6b579157d7a6e9bdb3404d761edf89c1135fa89b984d6431a527beeb97031dc90f2fae9761528f4d06d1
2022-07-01 22:13:32 +02:00
Tim Ruffing
40a3473a9d build: Fix #include "..." paths to get rid of further -I arguments
This simplifies building without a build system.

This is in line with #925; the paths fixed here were either forgotten
there or only introduced later. This commit also makes the Makefile
stricter so that further "wrong" #include paths will lead to build
errors even in autotools builds.

This belongs to #929.

Co-authored-by: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
2022-07-01 15:03:35 +02:00
Tim Ruffing
43756da819 Merge bitcoin-core/secp256k1#1115: Fix sepc256k1 -> secp256k1 typo in group.h
069aba8125 Fix sepc256k1 -> secp256k1 typo in group.h (henopied)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 069aba8125

Tree-SHA512: 0fcb7d042f201737870da99f5425c8449e9ec3f5f8e9bbe5eb719e46cdf230db057509fb9102d4ce50a94d616015233c29249665c754e726899174fea3ea9f40
2022-06-30 12:17:51 +02:00
henopied
069aba8125 Fix sepc256k1 -> secp256k1 typo in group.h 2022-06-29 20:08:47 -05:00
Jonas Nick
accadc94df Merge bitcoin-core/secp256k1#1114: _scratch_destroy: move VERIFY_CHECK after invalid scrach space check
1827c9bf2b scratch_destroy: move VERIFY_CHECK after invalid scrach space check (siv2r)

Pull request description:

ACKs for top commit:
  sipa:
    utACK 1827c9bf2b
  jonasnick:
    ACK 1827c9bf2b

Tree-SHA512: 5c4f97ca16f46380b30d1d077a54e25eab21efb10e0ce3ca27e7f73a2318d130f0f0773e26b2fdfc8f9d98c1334880f9d80a51b0941be3ba0af2b656b7c0ea7e
2022-06-29 20:32:00 +00:00
Jonas Nick
cd47033335 Merge bitcoin-core/secp256k1#1084: ci: Add MSVC builds
49e2acd927 configure: Improve rationale for WERROR_CFLAGS (Tim Ruffing)
8dc4b03341 ci: Add a C++ job that compiles the public headers without -fpermissive (Tim Ruffing)
51f296a46c ci: Run persistent wineserver to speed up wine (Tim Ruffing)
3fb3269c22 ci: Add 32-bit MinGW64 build (Tim Ruffing)
9efc2e5221 ci: Add MSVC builds (Tim Ruffing)
2be6ba0fed configure: Convince autotools to work with MSVC's archiver lib.exe (Tim Ruffing)
bd81f4140a schnorrsig bench: Suppress a stupid warning in MSVC (Tim Ruffing)
09f3d71c51 configure: Add a few CFLAGS for MSVC (Tim Ruffing)
3b4f3d0d46 build: Reject C++ compilers in the preprocessor (Tim Ruffing)
1cc0941414 configure: Don't abort if the compiler does not define __STDC__ (Tim Ruffing)
cca8cbbac8 configure: Output message when checking for valgrind (Tim Ruffing)
1a6be5745f bench: Make benchmarks compile on MSVC (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 49e2acd927

Tree-SHA512: 986c498fb218231fff3519167d34a92e11dea6a4383788a9723be105c20578cd483c6b06ba5686c6669e3a02cfeebc29b8e5f1428552ebf4ec67fa7a86957548
2022-06-29 15:39:28 +00:00
siv2r
1827c9bf2b scratch_destroy: move VERIFY_CHECK after invalid scrach space check 2022-06-29 20:24:11 +05:30
Tim Ruffing
49e2acd927 configure: Improve rationale for WERROR_CFLAGS 2022-06-29 11:12:00 +02:00
Tim Ruffing
8dc4b03341 ci: Add a C++ job that compiles the public headers without -fpermissive 2022-06-29 11:05:40 +02:00
Tim Ruffing
51f296a46c ci: Run persistent wineserver to speed up wine 2022-06-29 11:05:40 +02:00
Tim Ruffing
3fb3269c22 ci: Add 32-bit MinGW64 build
This commit also raises the TEST_ITERS for wine tasks to the default.
The overhead of wine is negligible, so we can certainly afford the same
number of iterations as for native Linux tests.
2022-06-29 11:05:40 +02:00
Tim Ruffing
9efc2e5221 ci: Add MSVC builds
This adds MSVC builds built on Linux using wine. This requires some
settings of tools and flags because the autotools support for MSVC is
naturally somewhat limited.

The advantage of this approach is that it is compatible with our
existing CI scripts, so there's no need to write a Windows CI script
(in PowerShell or similar). If we want to test building and running on
Windows native (e.g., as supported by Cirrus CI) we could still do this
in the future.

Another advantage of this approach is that contributors can simply use
the docker image if they need a MSVC installation in a non-Windows
environment.

This commit also improves the Dockerfile by grouping RUN commands
according to Docker docs:
https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#run
2022-06-29 11:05:40 +02:00
Tim Ruffing
2be6ba0fed configure: Convince autotools to work with MSVC's archiver lib.exe 2022-06-29 11:05:40 +02:00
Tim Ruffing
bd81f4140a schnorrsig bench: Suppress a stupid warning in MSVC 2022-06-29 11:05:40 +02:00
Tim Ruffing
44c2452fd3 Merge bitcoin-core/secp256k1#1105: Don't export symbols in static libraries
6f6cab9989 abi: Don't export symbols in static Windows libraries (Cory Fields)

Pull request description:

  For context, Bitcoin Core has recently merged [libbitcoin-kernel](https://github.com/bitcoin/bitcoin/pull/24322), a small library that intends to eventually minimally encompass Core's validation engine. This kernel lib includes a static libsecp256k1. Without this change, because libsecp256k1.a ends up with exported symbols, we end up with libsecp256k1 symbols exported by our libbitcoin-kernel library (which causes unrelated problems not worth getting into here).

  libtool takes care of building both object versions, and it automatically builds objects for shared libs with -DDLL_EXPORT. We just need to opt-in to its functionality.

  I can't imagine this having any negative impact on any current statically-linking applications, if anything they'll just be a tiny bit smaller because they can now strip unused symbols.

ACKs for top commit:
  real-or-random:
    utACK 6f6cab9989
  theuni:
    > Not sure what other changes made compilation on CI fail but Concept ACK [6f6cab9](6f6cab9989). This should be entirely harmless.
  sipa:
    utACK 6f6cab9989
  laanwj:
    utACK 6f6cab9989

Tree-SHA512: 39f240046639738f7a8c01068e728b2f9ceac2754cc4b0a5fa46c28f6f57a8c4124653b56dfbf5c13106b07c11ac599cc41b508e16862d539ce1af6c3365a205
2022-05-19 11:49:02 +02:00
Cory Fields
6f6cab9989 abi: Don't export symbols in static Windows libraries
libtool takes care of building both object versions, we just need to pick the
right one to export symbols.
2022-05-04 20:12:21 +00:00
Tim Ruffing
485f608fa9 Merge bitcoin-core/secp256k1#1104: Fix the false positive of SECP_64BIT_ASM_CHECK
7efc9835a9 Fix the false positive of `SECP_64BIT_ASM_CHECK` (Sprite)

Pull request description:

  I'm trying to compile this project for RISC-V architecture, and I encountered errors:
  ```
  src/field_5x52_asm_impl.h:28:1: error: unknown register name '%r15' in 'asm'
     28 | __asm__ __volatile__(
        | ^
  src/field_5x52_asm_impl.h:28:1: error: unknown register name '%r14' in 'asm'
  src/field_5x52_asm_impl.h:28:1: error: unknown register name '%r13' in 'asm'
  src/field_5x52_asm_impl.h:28:1: error: unknown register name '%r12' in 'asm'
  src/field_5x52_asm_impl.h:28:1: error: unknown register name '%r11' in 'asm'
  src/field_5x52_asm_impl.h:28:1: error: unknown register name '%r10' in 'asm'
  src/field_5x52_asm_impl.h:28:1: error: unknown register name '%r9' in 'asm'
  src/field_5x52_asm_impl.h:28:1: error: unknown register name '%r8' in 'asm'
  src/field_5x52_asm_impl.h:28:1: error: unknown register name '%rdx' in 'asm'
  src/field_5x52_asm_impl.h:28:1: error: unknown register name '%rcx' in 'asm'
  src/field_5x52_asm_impl.h:28:1: error: unknown register name '%rax' in 'asm'
  src/field_5x52_asm_impl.h:28:1: error: output number 0 not directly addressable
  src/field_5x52_asm_impl.h: In function 'secp256k1_fe_sqr':
  src/field_5x52_asm_impl.h:298:1: error: unknown register name '%r15' in 'asm'
    298 | __asm__ __volatile__(
        | ^
  src/field_5x52_asm_impl.h:298:1: error: unknown register name '%r14' in 'asm'
  src/field_5x52_asm_impl.h:298:1: error: unknown register name '%r13' in 'asm'
  src/field_5x52_asm_impl.h:298:1: error: unknown register name '%r12' in 'asm'
  src/field_5x52_asm_impl.h:298:1: error: unknown register name '%r11' in 'asm'
  src/field_5x52_asm_impl.h:298:1: error: unknown register name '%r10' in 'asm'
  src/field_5x52_asm_impl.h:298:1: error: unknown register name '%r9' in 'asm'
  src/field_5x52_asm_impl.h:298:1: error: unknown register name '%r8' in 'asm'
  src/field_5x52_asm_impl.h:298:1: error: unknown register name '%rdx' in 'asm'
  src/field_5x52_asm_impl.h:298:1: error: unknown register name '%rcx' in 'asm'
  src/field_5x52_asm_impl.h:298:1: error: unknown register name '%rbx' in 'asm'
  src/field_5x52_asm_impl.h:298:1: error: unknown register name '%rax' in 'asm'
  src/field_5x52_asm_impl.h:298:1: error: output number 0 not directly addressable
  ```

  After further investigation I found that for RISC-V, macro `USE_ASM_X86_64` was defined unexpectedly, and `checking for x86_64 assembly availability... yes` appeared in the compilation log file, which means `SECP_64BIT_ASM_CHECK` was not working as expected.

  For unknown reasons, `AC_COMPILE_IFELSE` does not check if `__asm__` can be compiled, and an example can verify this point:
  ```m4
  AC_DEFUN([SECP_64BIT_ASM_CHECK],[
  AC_MSG_CHECKING(for x86_64 assembly availability)
  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
    #include <stdint.h>]],[[
    __asm__ __volatile__("this is obviously wrong");
    ]])],[has_64bit_asm=yes],[has_64bit_asm=no])
  AC_MSG_RESULT([$has_64bit_asm])
  ])
  ```

  It always gives results: `checking for x86_64 assembly availability... yes`

  After testing, replacing `AC_COMPILE_IFELSE` with `AC_LINK_IFELSE` can correctly check if `__asm__` can be compiled and make the project able to compile for RISC-V.

ACKs for top commit:
  real-or-random:
    ACK 7efc9835a9

Tree-SHA512: 7318dd42004b2930cfcd6541c5a9ce0aa186e2179a668b76089a908bea8d9f70fcfdb264512f971e395a3ce9dc7f9ca24c8f3d46175cad2972a2d713f518ed85
2022-04-16 13:17:25 +02:00
Tim Ruffing
8b013fce51 Merge bitcoin-core/secp256k1#1056: Save negations in var-time group addition
2f984ffc45 Save negations in var-time group addition (Peter Dettman)

Pull request description:

  - Updated _gej_add_var, _gej_add_ge_var, _gej_add_zinv_var
  - 2 fewer _fe_negate in each method
  - Updated operation counts and standardize layout
  - Added internal benchmark for _gej_add_zinv_var

  benchmark_internal shows about 2% speedup in each method as a result (64bit).

ACKs for top commit:
  real-or-random:
    ACK 2f984ffc45
  jonasnick:
    ACK 2f984ffc45

Tree-SHA512: 01366fa23c83a8dd37c9a0a24e0acc53ce38a201607fe4da6672ea5618d82c62d1299f0e0aa50317883821539af739ea52b6561faff230c148e6fdc5bc5af30b
2022-04-16 12:58:57 +02:00
Sprite
7efc9835a9 Fix the false positive of SECP_64BIT_ASM_CHECK 2022-04-15 18:34:24 +08:00
Tim Ruffing
7a30cb0c9d Merge ElementsProject/secp256k1-zkp#187: musig-spec: remove it from this repo
cc07b8f7a9 musig-spec: remove it (Jonas Nick)

Pull request description:

  Moved to https://github.com/jonasnick/bips/blob/musig2/bip-musig2.mediawiki.

ACKs for top commit:
  real-or-random:
    ACK cc07b8f7a9

Tree-SHA512: 67aebe6afbacd83153c465fcea794d36f07d067e21f767d9f82d7429458d91fe1df8a7289c10d9fa5b5458b1b6603b51a3349528dc8af6b0293f34f0b25c311f
2022-04-06 00:50:33 +02:00
Jonas Nick
cc07b8f7a9 musig-spec: remove it 2022-04-05 22:47:17 +00:00
Jonas Nick
c1640b7049 Merge elementsproject/secp256k1-zkp#166: musig-spec: Add naive Python reference implementation
c235e5055f musig-spec: Add naive Python reference implementation (Elliott Jin)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK c235e5055f
  real-or-random:
    utACK c235e5055f

Tree-SHA512: f0ff8b84730a82d8eab15ac5c46b190af125a87c0c8b3eef88fa5f67c4b7cd88e3d981cae857a99456b72a0edb56ef7f0593e7ed488914f2f4cd070efb579de8
2022-04-05 22:28:18 +00:00
Elliott Jin
c235e5055f musig-spec: Add naive Python reference implementation 2022-04-05 18:18:18 -04:00
Tim Ruffing
d45fbdcfad Merge ElementsProject/secp256k1-zkp#180: musig: add test vectors for applying multiple tweaks
510b61a803 musig: add test vectors for applying multiple tweaks (Jonas Nick)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK 510b61a803
  robot-dreams:
    utACK 510b61a803

Tree-SHA512: 5fed7e01f23c0c7d1526bd9f89c5f385ad95ab1f0331df6e5bc7710e4d9f4f3860a5fd63adb7adda0a57e5fcf6204ccb941232ceb26eae44cb74f0916963d674
2022-04-05 23:19:34 +02:00
Jonas Nick
9a814bea32 Merge elementsproject/secp256k1-zkp#186: musig-spec: Minor cleanup
67247e53af musig-spec: More minor cleanup (Elliott Jin)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 67247e53af

Tree-SHA512: 8ea2880aef0bd69e2faf10a5eb44d5ba3839867565bd735a4582189f04ea54ab73ec23f04d08aed1d10bc5aaa55bab688ff4cb4e733dc73e2a5946f9a187c7ac
2022-04-05 19:38:43 +00:00
Elliott Jin
67247e53af musig-spec: More minor cleanup 2022-04-05 15:30:28 -04:00
Jonas Nick
9a1645f0ef Merge elementsproject/secp256k1-zkp#184: musig-spec: minor fixups
bf615193ce musig-spec: minor fixups (Jonas Nick)

Pull request description:

ACKs for top commit:
  robot-dreams:
    ACK bf615193ce, thanks!

Tree-SHA512: dff21e4f68640de6087426af934d882146f53392166fb9826bc15fc13490bbb20b4ae94410604567df451ac5875fa3cf17be5f2cc7f7d2ae135aff91b17f3754
2022-04-05 18:47:11 +00:00
Jonas Nick
bf615193ce musig-spec: minor fixups 2022-04-05 18:39:27 +00:00
Jonas Nick
ebd10f210b Merge elementsproject/secp256k1-zkp#185: musig-spec: Clarify negation for signing and verification
0940575215 musig-spec: Clarify negation for signing and verification (Elliott Jin)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 0940575215

Tree-SHA512: 907f55f633a397d99d7a0243e4175bce0e647c634dee452996622a22e29c37e78eafcc4f4c90ad44b8571e469b8a1ab882be3231e0e4c6e1ff0ca44fbfac9dcd
2022-04-05 16:50:53 +00:00
Elliott Jin
0940575215 musig-spec: Clarify negation for signing and verification 2022-04-05 12:47:36 -04:00
Jonas Nick
18a35ec1af Merge elementsproject/secp256k1-zkp#183: Improve writing in Signing flow
1b292cdb52 Improve writing in Signing flow (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 1b292cdb52

Tree-SHA512: 08ab5480afb53ffdfd660713aabe5f21529e2f3a450c99e74f5b5f14135bf735454c845ca9e574197098a68dbb97fb1601a5bc68f8095bc74262b1677f4275a4
2022-04-05 14:58:08 +00:00
Tim Ruffing
1b292cdb52 Improve writing in Signing flow 2022-04-05 15:01:09 +02:00
Tim Ruffing
a86bfa991a Merge ElementsProject/secp256k1-zkp#181: musig-spec: clarify hashing in noncegen by converting ints to bytes
376733b58b musig-spec: clarify hashing in noncegen by converting ints to bytes (Jonas Nick)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 376733b58b

Tree-SHA512: c4708c476094d242fe7312177e345932bd40b52549007b43d2e5e4efc094101624d8583647f305bcbd042692a9d0117eda38f71e22fee0e0f49d677d9f512a8e
2022-04-05 10:42:02 +02:00
Tim Ruffing
4469cad42f Merge ElementsProject/secp256k1-zkp#182: musig-spec: address robot-dreams' comments
b7f8ea2f2a musig-spec: address robot-dreams' comments (Jonas Nick)

Pull request description:

  - KeyAggCoeff' -> KeyAggCoeffInternal for consistency
  - In Sign, add mod n when calculating d
  - In Tweak, reorder the parameters to (Q, gacc, tacc, tweak, is_xonly) because
    the first three are "state" arguments
  - Rename Tweak function to ApplyTweak to avoid confusion with tweak (the
    vector). This becomes apparent in the python reference code.

ACKs for top commit:
  real-or-random:
    ACK b7f8ea2f2a

Tree-SHA512: 6f9066af2f67b6d2769f38ebb2537769568e77bab18d487590a0095a695eab5c34a7177e4d299f27e3e30628dd07aff831f3f08db256cf2ae13ea0d92f3e18b8
2022-04-05 10:41:08 +02:00
Jonas Nick
b7f8ea2f2a musig-spec: address robot-dreams' comments
- KeyAggCoeff' -> KeyAggCoeffInternal for consistency
- In Sign, add mod n when calculating d
- In Tweak, reorder the parameters to (Q, gacc, tacc, tweak, is_xonly) because
  the first three are "state" arguments
- Rename Tweak function to ApplyTweak to avoid confusion with tweak (the
  vector). This becomes apparent in the python reference code.
2022-04-04 22:39:38 +00:00
Jonas Nick
376733b58b musig-spec: clarify hashing in noncegen by converting ints to bytes 2022-04-04 21:48:38 +00:00
Jonas Nick
510b61a803 musig: add test vectors for applying multiple tweaks 2022-04-04 21:38:46 +00:00
Jonas Nick
ac477d5148 Merge elementsproject/secp256k1-zkp#179: musig-spec: Improve writing in Motivation, Design
d903c09fd2 musig-spec: Improve writing in Motivation, Design (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK d903c09fd2

Tree-SHA512: b429e82ba7f5fa1acf3fbb599a019cff5d2531e6b91d8aaf6191c1639e5a32a0e47676714c14af5d0e9bf61a6318654a00b8ea6c75840a82e64935e7a9712c13
2022-04-04 20:15:19 +00:00
Tim Ruffing
d903c09fd2 musig-spec: Improve writing in Motivation, Design 2022-04-04 22:11:58 +02:00
Tim Ruffing
1d0d60d9eb Merge ElementsProject/secp256k1-zkp#178: musig-spec: expand on signing flow
fd51a6281e musig-spec: add authors (Jonas Nick)
f56e223a7a musig-spec: explain NonceGen and tweaking in signing flow context (Jonas Nick)
e463ea42bb musig-spec: mention stateless signing in signing flow (Jonas Nick)
a29b961eb7 musig-spec: add acknowledgements and improve abstract (Jonas Nick)
1a086ba9c9 musig-spec: add optional arguments to strengthen nonce function (Jonas Nick)
8d04ac318f musig-spec: remove unnecessary and inconsistent input paragraph (Jonas Nick)

Pull request description:

  Based on #177

  It's likely we're missing people in the acknowledgements. Ping me if you think you are.

ACKs for top commit:
  real-or-random:
    ACK fd51a6281e

Tree-SHA512: 5240b783c15f76655b2593422dc7c76de1c5e298bbe2f39858daca4ee1b1877f1ff179b4043e6f1f75f8c804b734f4bb739d38a18a54b094d8640c57fd074ed9
2022-04-04 15:21:37 +02:00
Jonas Nick
fd51a6281e musig-spec: add authors 2022-04-04 11:57:00 +00:00
Jonas Nick
f56e223a7a musig-spec: explain NonceGen and tweaking in signing flow context 2022-04-04 11:57:00 +00:00
Jonas Nick
e463ea42bb musig-spec: mention stateless signing in signing flow 2022-04-04 10:42:09 +00:00
Jonas Nick
a29b961eb7 musig-spec: add acknowledgements and improve abstract 2022-04-04 10:42:09 +00:00
Jonas Nick
1a086ba9c9 musig-spec: add optional arguments to strengthen nonce function
This is a defense-in-depth measure that may help if the value is not drawn
uniformly at random. The handling of sk is similar to BIP340.
2022-04-03 09:58:44 +00:00
Jonas Nick
8d04ac318f musig-spec: remove unnecessary and inconsistent input paragraph 2022-04-01 21:26:00 +00:00
Tim Ruffing
6c0aecf72b Merge ElementsProject/secp256k1-zkp#174: Upstream PRs 1064, 1049, 899, 1068, 1072, 1069, 1074, 1026, 1033, 748, 1079, 1088, 1090, 731, 1089, 995, 1094, 1093
645d9c53c4 examples: let musig use random.h instead of /dev/urandom (Jonas Nick)
eccba5b4e5 examples: relicense musig example to CC0 public domain (Jonas Nick)
7c5af740fa ci: fix missing EXPERIMENTAL flags (Jonas Nick)
03bea1e173 configure: add -zkp modules to dev-mode and remove redundant code (Jonas Nick)
2adb741c45 examples: rename example_musig to musig_example for consistency (Jonas Nick)
37d36927df tests: Add tests for _read_be32 and _write_be32 (Tim Ruffing)
616b43dd3b util: Remove endianness detection (Tim Ruffing)
8d89b9e6e5 hash: Make code agnostic of endianness (Tim Ruffing)
55512d30b7 doc: clean up module help text in configure.ac (Elliott Jin)
d9d94a9969 doc: mention optional modules in README (Elliott Jin)
7f09d0f311 README: mention that ARM assembly is experimental (Jonas Nick)
80cf4eea5f build: stop treating schnorrsig, extrakeys modules as experimental (Jonas Nick)
b8f8b99f0f docs: Fix return value for functions that don't have invalid inputs (Tim Ruffing)
f813bb0df3 schnorrsig: Adapt example to new API (Tim Ruffing)
99e6568fc6 schnorrsig: Rename schnorrsig_sign to schnorsig_sign32 and deprecate (Tim Ruffing)
fc94a2da44 Use SECP256K1_DEPRECATED for existing deprecated API functions (Tim Ruffing)
3db0560606 Add SECP256K1_DEPRECATED attribute for marking API parts as deprecated (Tim Ruffing)
f8d9174357 Add SHA256 bit counter tests (Tim Ruffing)
9b514ce1d2 Add test vector for very long SHA256 messages (Tim Ruffing)
8e3dde1137 Simplify struct initializer for SHA256 padding (Tim Ruffing)
eb28464a8b Change SHA256 byte counter from size_t to uint64_t (Tim Ruffing)
21b2ebaf74 configure: Remove redundant pkg-config code (Tim Ruffing)
0d253d52e8 configure: Use modern way to set AR (Tim Ruffing)
e0838d663d configure: Add hidden --enable-dev-mode to enable all the stuff (Tim Ruffing)
fabd579dfa configure: Remove redundant code that sets _enable variables (Tim Ruffing)
0d4226c051 configure: Use canonical variable prefix _enable consistently (Tim Ruffing)
7c9502cece Add a copy of the CC0 license to the examples (Elichai Turkel)
42e03432e6 Add usage examples to the readme (Elichai Turkel)
517644eab1 Optionally compile the examples in autotools, compile+run in travis (Elichai Turkel)
422a7cc86a Add a ecdh shared secret example (Elichai Turkel)
b0cfbcc143 Add a Schnorr signing and verifying example (Elichai Turkel)
fee7d4bf9e Add an ECDSA signing and verifying example (Elichai Turkel)
e848c3799c Update sage files for new formulae (Peter Dettman)
d64bb5d4f3 Add fe_half tests for worst-case inputs (Peter Dettman)
4eb8b932ff Further improve doubling formula using fe_half (Peter Dettman)
557b31fac3 Doubling formula using fe_half (Pieter Wuille)
2cbb4b1a42 Run more iterations of run_field_misc (Pieter Wuille)
9cc5c257ed Add test for secp256k1_fe_half (Pieter Wuille)
925f78d55e Add _fe_half and use in _gej_add_ge (Peter Dettman)
3531a43b5b ecdh: Make generator_basepoint test depend on global iteration count (Tim Ruffing)
c881dd49bd ecdh: Add test computing shared_secret=basepoint with random inputs (Tim Ruffing)
e51ad3b737 ci: Retry `brew update` a few times to avoid random failures (Tim Ruffing)
b1cb969e8a ci: Revert "Attempt to make macOS builds more reliable" (Tim Ruffing)
e0db3f8a25 build: Replace use of deprecated autoconf macro AC_PROG_CC_C89 (laanwj)
d9396a56da ci: Attempt to make macOS builds more reliable (Tim Ruffing)
ebb1beea78 sage: Ensure that constraints are always fastfracs (Tim Ruffing)
d8d54859ed ci: Run sage prover on CI (Tim Ruffing)
77cfa98dbc sage: Normalize sign of polynomial factors in prover (Tim Ruffing)
eae75869cf sage: Exit with non-zero status in case of failures (Tim Ruffing)
b54d843eac sage: Fix printing of errors (Tim Ruffing)
e108d0039c sage: Fix incompatibility with sage 9.4 (Tim Ruffing)
b797a500ec Create a SECP256K1_ECMULT_TABLE_VERIFY macro. (Russell O'Connor)
a731200cc3 Replace ECMULT_TABLE_GET_GE_STORAGE macro with a function. (Russell O'Connor)
fe34d9f341 Eliminate input_pos state field from ecmult_strauss_wnaf. (Russell O'Connor)
0397d00ba0 Eliminate na_1 and na_lam state fields from ecmult_strauss_wnaf. (Russell O'Connor)
7ba3ffcca0 Remove the unused pre_a_lam allocations. (Russell O'Connor)
b3b57ad6ee Eliminate the pre_a_lam array from ecmult_strauss_wnaf. (Russell O'Connor)
ae7ba0f922 Remove the unused prej allocations. (Russell O'Connor)
e5c18892db Eliminate the prej array from ecmult_strauss_wnaf. (Russell O'Connor)
c9da1baad1 Move secp256k1_fe_one to field.h (Russell O'Connor)
070e772211 Faster fixed-input ecmult tests (Pieter Wuille)
45f37b6506 Modulo-reduce msg32 inside RFC6979 nonce fn to match spec. Fixes #1063. (Paul Miller)

Pull request description:

  [bitcoin-core/secp256k1#1064]: Modulo-reduce msg32 inside RFC6979 nonce fn to match spec. Fixes #1063
  [bitcoin-core/secp256k1#1049]: Faster fixed-input ecmult tests
  [bitcoin-core/secp256k1#899]: Reduce stratch space needed by ecmult_strauss_wnaf.
  [bitcoin-core/secp256k1#1068]: sage: Fix incompatibility with sage 9.4
  [bitcoin-core/secp256k1#1072]: ci: Attempt to make macOS builds more reliable
  [bitcoin-core/secp256k1#1069]: build: Replace use of deprecated autoconf macro AC_PROG_CC_C89
  [bitcoin-core/secp256k1#1074]: ci: Retry brew update a few times to avoid random failures
  [bitcoin-core/secp256k1#1026]: ecdh: Add test computing shared_secret=basepoint with random inputs
  [bitcoin-core/secp256k1#1033]: Add _fe_half and use in _gej_add_ge and _gej_double
  [bitcoin-core/secp256k1#748]: Add usage examples
  [bitcoin-core/secp256k1#1079]: configure: Add hidden --enable-dev-mode to enable all the stuff
  [bitcoin-core/secp256k1#1088]: configure: Use modern way to set AR
  [bitcoin-core/secp256k1#1090]: configure: Remove redundant pkg-config code
  [bitcoin-core/secp256k1#731]: Change SHA256 byte counter from size_t to uint64_t
  [bitcoin-core/secp256k1#1089]: Schnorrsig API improvements
  [bitcoin-core/secp256k1#995]: build: stop treating schnorrsig, extrakeys modules as experimental
  [bitcoin-core/secp256k1#1094]: doc: Clarify configure flags for optional modules
  [bitcoin-core/secp256k1#1093]: hash: Make code agnostic of endianness

  This PR can be recreated  with `./sync-upstream.sh range 8746600eec5e7fcd35dabd480839a3a4bdfee87b`.

ACKs for top commit:
  real-or-random:
    ACK 645d9c53c4 I rederived the tree, and tested it with MSVC, including the musig example

Tree-SHA512: 3b771630806ed8481053958c21820dce6e869371833cd18a5c430a2768bda8064ad2bb247afbe38e3fa37320a8b1dbbe65ad68c8963efb995d96aa29ae574884
2022-04-01 15:20:59 +02:00
Tim Ruffing
eafcd04216 Merge ElementsProject/secp256k1-zkp#176: musig-spec: expand on signing flow
c715407b4f musig-spec: fix partial sig verification note in intro (Jonas Nick)
11fb8a664b musig-spec: expand on signing flow (Jonas Nick)

Pull request description:

  based on #173

ACKs for top commit:
  real-or-random:
    ACK c715407b4f

Tree-SHA512: def3158157e3b369ede5469501d4899bfe0dd0ec7282883847e0dd58d7874761cf681b9416e79e01d84873446a5187b330fb3b30533059216db8178dd1dd0548
2022-04-01 15:14:22 +02:00
Jonas Nick
c715407b4f musig-spec: fix partial sig verification note in intro 2022-04-01 13:12:28 +00:00
Jonas Nick
11fb8a664b musig-spec: expand on signing flow
Also move signing flow before specification because it is slightly more natural.
2022-04-01 13:12:20 +00:00
Jonas Nick
43c853fa28 Merge elementsproject/secp256k1-zkp#173: musig-spec: Add motivation and design sections
802b7daf23 musig-spec: add motivation and design sections (Jonas Nick)
686d96222d musig-spec: various cleanups (Jonas Nick)
ef537b2065 musig-spec: fix unnecessary O(n^2) KeyAgg runtime (Jonas Nick)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 802b7daf23

Tree-SHA512: 03e69f8a4028411454f9e3533989de170abd788a964fd12d7b15f75768aecbf34e64f12d02c673732279a9748844481185721b5c02fd7cca8ee6d7c37e3c194c
2022-04-01 10:43:11 +00:00
Jonas Nick
3deaa006a0 Merge elementsproject/secp256k1-zkp#175: configure: Check compile+link when checking existence of functions
79472c7ee5 configure: Check compile+link when checking existence of functions (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 79472c7ee5

Tree-SHA512: 947f794138636390d74366d9d06eb18f315f038a8555d1057c407f5592f1bd432a74c94ab758a85a5d8324908f46656518ebce30124f56a9d9c3936d144789ae
2022-03-31 20:46:53 +00:00
Tim Ruffing
79472c7ee5 configure: Check compile+link when checking existence of functions
Undeclared functions are fine in C but linking will fail.
2022-03-31 17:41:54 +02:00
Jonas Nick
645d9c53c4 examples: let musig use random.h instead of /dev/urandom 2022-03-31 13:38:30 +00:00
Jonas Nick
eccba5b4e5 examples: relicense musig example to CC0 public domain 2022-03-31 13:33:30 +00:00
Jonas Nick
802b7daf23 musig-spec: add motivation and design sections 2022-03-31 09:25:25 +00:00
Jonas Nick
7c5af740fa ci: fix missing EXPERIMENTAL flags
This was introduced when merging upstream PRs.
2022-03-30 18:45:59 +00:00
Jonas Nick
03bea1e173 configure: add -zkp modules to dev-mode and remove redundant code 2022-03-30 15:18:07 +00:00
Jonas Nick
2adb741c45 examples: rename example_musig to musig_example for consistency 2022-03-30 15:06:46 +00:00
Jonas Nick
8298c0c79b Merge commits 'c8aa516b 0a40a486 d8a24632 85b00a1c 59547943 5dcc6f8d 07752831 3ef94aa5 1253a277 64b34979 ac83be33 0e5cbd01 e0508ee9 587239db 1ac7e31c d0ad5814 912b7ccc 8746600e ' into temp-merge-1093
Revert: util: Remove endianness detection
2022-03-30 15:00:03 +00:00
Tim Ruffing
8746600eec Merge bitcoin-core/secp256k1#1093: hash: Make code agnostic of endianness
37d36927df tests: Add tests for _read_be32 and _write_be32 (Tim Ruffing)
616b43dd3b util: Remove endianness detection (Tim Ruffing)
8d89b9e6e5 hash: Make code agnostic of endianness (Tim Ruffing)

Pull request description:

  Recent compilers compile the two new functions to very efficient code
  on various platforms. In particular, already GCC >= 5 and clang >= 5
  understand do this for the read function, which is the one critical
  for performance (called 16 times per SHA256 transform).

  Fixes #1080.

ACKs for top commit:
  sipa:
    utACK 37d36927df
  robot-dreams:
    ACK 37d36927df

Tree-SHA512: b03cec67756fb3c94ca8e7e06f974136050efd5065f392dba6eed4d0dbe61dbf93dad054627267225bac1bb302bb025f86588612ef7d4beeb834466686c70b8f
2022-03-28 21:30:21 +02:00
Peter Dettman
2f984ffc45 Save negations in var-time group addition
- Updated _gej_add_var, _gej_add_ge_var, _gej_add_zinv_var
- 2 fewer _fe_negate in each method
- Updated operation counts and standardize layout
- Added internal benchmark for _gej_add_zinv_var
- Update sage files (fixed by Tim Ruffing)
2022-03-28 23:40:55 +07:00
Jonas Nick
686d96222d musig-spec: various cleanups
- add BIP header & abstract
- rename MuSig to MuSig2 because some people may want to use the 3-round version
- remove applications because we don't need to motivate an informational BIP
- x-only -> X-only
- remove overly repetetitive "The algorithm [...] is defined as"
- move "Remarks" and "Design" out of "Description" section and move "Test
  vectors and ..." into "Description" section. The idea is that the Description
  contains everything that is absolutely required to implement the BIP (safely).
2022-03-27 21:44:10 +00:00
Jonas Nick
ef537b2065 musig-spec: fix unnecessary O(n^2) KeyAgg runtime 2022-03-27 13:30:39 +00:00
Tim Ruffing
37d36927df tests: Add tests for _read_be32 and _write_be32 2022-03-26 10:26:53 +01:00
Jonas Nick
912b7ccc44 Merge bitcoin-core/secp256k1#1094: doc: Clarify configure flags for optional modules
55512d30b7 doc: clean up module help text in configure.ac (Elliott Jin)
d9d94a9969 doc: mention optional modules in README (Elliott Jin)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK 55512d30b7
  jonasnick:
    ACK 55512d30b7

Tree-SHA512: ae4ec355730983117c5e9a8a8abd17aaf42afe6f8f8f7474a551df6269a62094883e0827d2f3642e3ed6eb26cf71982c20f7ac27498cb4bd7e4aea57ec308d6a
2022-03-25 20:20:30 +00:00
Elliott Jin
55512d30b7 doc: clean up module help text in configure.ac 2022-03-25 08:14:18 -07:00
Elliott Jin
d9d94a9969 doc: mention optional modules in README 2022-03-25 08:14:18 -07:00
Tim Ruffing
616b43dd3b util: Remove endianness detection 2022-03-25 11:32:22 +01:00
Tim Ruffing
8d89b9e6e5 hash: Make code agnostic of endianness
Recent compilers compile the two new functions to very efficient code
on various platforms. In particular, already GCC >= 5 and clang >= 5
understand do this for the read function, which is the one critical
for performance (called 16 times per SHA256 transform).

Fixes #1080.
2022-03-25 11:32:14 +01:00
Tim Ruffing
d0ad5814a5 Merge bitcoin-core/secp256k1#995: build: stop treating schnorrsig, extrakeys modules as experimental
7f09d0f311 README: mention that ARM assembly is experimental (Jonas Nick)
80cf4eea5f build: stop treating schnorrsig, extrakeys modules as experimental (Jonas Nick)

Pull request description:

  Fixes #992

ACKs for top commit:
  real-or-random:
    ACK 7f09d0f311
  fanquake:
    ACK 7f09d0f311 - When this is in, I think we'll do a subtree update in Core, and prune some build cruft on our side.

Tree-SHA512: 13deb82dcca88bacb2cd5c1c589a8d4af2277c4d675262337ae4d7e93eb41d43825dda4945ca1c202c36aaa2e6fd42de9c6d711fe8d71bce578368281db698b2
2022-03-25 10:57:17 +01:00
Tim Ruffing
1ac7e31c5b Merge bitcoin-core/secp256k1#1089: Schnorrsig API improvements
b8f8b99f0f docs: Fix return value for functions that don't have invalid inputs (Tim Ruffing)
f813bb0df3 schnorrsig: Adapt example to new API (Tim Ruffing)
99e6568fc6 schnorrsig: Rename schnorrsig_sign to schnorsig_sign32 and deprecate (Tim Ruffing)
fc94a2da44 Use SECP256K1_DEPRECATED for existing deprecated API functions (Tim Ruffing)
3db0560606 Add SECP256K1_DEPRECATED attribute for marking API parts as deprecated (Tim Ruffing)

Pull request description:

  Should be merged before #995 if we want this.

  I suspect the only change here which is debatable on a conceptual level is the renaming. I can drop this of course.

ACKs for top commit:
  sipa:
    utACK b8f8b99f0f
  jonasnick:
    ACK b8f8b99f0f

Tree-SHA512: 7c5b9715013002eecbf2e649032673204f6eaffe156f20e3ddf51fab938643847d23068f11b127ef3d7fe759e42a20ecaf2ec98718d901ef9eaadbc9853c1dfe
2022-03-25 00:15:15 +01:00
Tim Ruffing
587239dbe3 Merge bitcoin-core/secp256k1#731: Change SHA256 byte counter from size_t to uint64_t
f8d9174357 Add SHA256 bit counter tests (Tim Ruffing)
9b514ce1d2 Add test vector for very long SHA256 messages (Tim Ruffing)
8e3dde1137 Simplify struct initializer for SHA256 padding (Tim Ruffing)
eb28464a8b Change SHA256 byte counter from size_t to uint64_t (Tim Ruffing)

Pull request description:

  This avoids that the SHA256 implementation would produce wrong paddings
  and thus wrong digests for messages of length >= 2^32 bytes on 32-bit
  platforms.

  This is not exploitable in any way since the SHA256 API is an internal
  API and we never call it with that long messages.

  This also simplifies the struct initializer for the padding.
  Since missing elements are initialized with zeros, this change is
  purely syntactical.

ACKs for top commit:
  sipa:
    utACK f8d9174357
  jonasnick:
    ACK f8d9174357

Tree-SHA512: 4fba64b255ef34bb144e4ac6d796798d620d6a7a0f3be409a46b98a8aedb129be19a6816b07caa4d1a3862a01769b42ce70240690fddc6231d591e6c06252750
2022-03-24 23:54:33 +01:00
Tim Ruffing
f8d9174357 Add SHA256 bit counter tests 2022-03-23 16:33:44 +01:00
Jonas Nick
d13429e28c Merge elementsproject/secp256k1-zkp#167: Add ordinary and x-only tweaking to spec and simplify implementation
eac0df1379 musig: mention how keyagg_cache tweak and parity relate to spec (Jonas Nick)
57eb6b4167 musig-spec: move description of secret key negation to spec (Jonas Nick)
633d01add0 musig-spec: add x-only and ordinary tweaking to musig (Jonas Nick)
aee0747e38 musig-spec: add general description of tweaking (Jonas Nick)
fb060a0c4e musig-spec: add Session Context to simplify sign/verify/sigagg (Jonas Nick)
3aec4332b5 musig-spec: move remarks on spec below specification section (Jonas Nick)
628d52c718 musig-spec: fix title/abstract and make algo names bold (Jonas Nick)
5b760cc172 musig-spec: consistently call partial sigs psig (Jonas Nick)
f0edc90755 musig: fix number of tweaks in tweak_test (Jonas Nick)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK eac0df1379 -- I haven't checked all the indices etc, so this is more of a Concept ACK than a "pseudocode review ACK" but we we have the ACK by Brandon and this is anyway still a draft, so I think this is good to be merged.

Tree-SHA512: 9e16e7892e103205d96060158a7a6c01480d2b59300bbf9f0655b4d26586e632be8b8f656fe07c7ece1421ec91e0b387d6fcf363db7aedc0402d265b1d9df474
2022-03-22 17:25:47 +00:00
Jonas Nick
eac0df1379 musig: mention how keyagg_cache tweak and parity relate to spec
Also rename internal_key_parity -> parity_acc because the former is
confusing.
2022-03-21 22:10:24 +00:00
Jonas Nick
57eb6b4167 musig-spec: move description of secret key negation to spec
Also fix bug in description that resulted in a wrong definition of t.
And rename keyagg coefficient from 'mu' to 'a' since we don't use the term "musig
coefficient" anymore and a is what is used in the paper.
2022-03-21 22:10:24 +00:00
Jonas Nick
633d01add0 musig-spec: add x-only and ordinary tweaking to musig 2022-03-21 22:10:24 +00:00
Jonas Nick
aee0747e38 musig-spec: add general description of tweaking 2022-03-21 22:10:24 +00:00
Jonas Nick
fb060a0c4e musig-spec: add Session Context to simplify sign/verify/sigagg
Besides reducing the number of arguments, this also removes the R argument from
PartialSigAgg which was not defined precisely:
* The final nonce ''R'' as created during  ''Sign'' or ''PartialSigVerify'': a point

Moreover, this paves the way for adding the tweaking, which requires
PartialSigAgg to also have access to challenge e and can now be easily computed
from the Session Context.
2022-03-21 22:10:24 +00:00
Jonas Nick
3aec4332b5 musig-spec: move remarks on spec below specification section
We will need more of these explanations and it's better if they do not interfere
the specification section. The remarks section is intended for content that's
not required for implementing the spec.
2022-03-21 22:10:24 +00:00
Jonas Nick
628d52c718 musig-spec: fix title/abstract and make algo names bold 2022-03-21 22:10:24 +00:00
Jonas Nick
5b760cc172 musig-spec: consistently call partial sigs psig 2022-03-21 20:47:32 +00:00
Jonas Nick
7f09d0f311 README: mention that ARM assembly is experimental 2022-03-18 13:22:21 +00:00
Tim Ruffing
b8f8b99f0f docs: Fix return value for functions that don't have invalid inputs
_tagged_sha256 simply cannot have invalid inputs.

The other functions could in some sense have invalid inputs but only in
violation of the type system. For example, a pubkey could be invalid but
invalid objects of type secp256k1_pubkey either can't be obtained
via the API or will be caught by an ARG_CHECK when calling pubkey_load.

This is consistent with similar functions in the public API, e.g.,
_ec_pubkey_negate or _ec_pubkey_serialize.
2022-03-18 11:33:23 +01:00
Tim Ruffing
f813bb0df3 schnorrsig: Adapt example to new API 2022-03-17 22:41:36 +01:00
Tim Ruffing
99e6568fc6 schnorrsig: Rename schnorrsig_sign to schnorsig_sign32 and deprecate 2022-03-17 22:41:36 +01:00
Tim Ruffing
fc94a2da44 Use SECP256K1_DEPRECATED for existing deprecated API functions 2022-03-17 22:41:36 +01:00
Tim Ruffing
3db0560606 Add SECP256K1_DEPRECATED attribute for marking API parts as deprecated 2022-03-17 22:41:36 +01:00
Tim Ruffing
09f3d71c51 configure: Add a few CFLAGS for MSVC 2022-03-17 22:32:24 +01:00
Tim Ruffing
3b4f3d0d46 build: Reject C++ compilers in the preprocessor 2022-03-17 22:32:24 +01:00
Tim Ruffing
1cc0941414 configure: Don't abort if the compiler does not define __STDC__
This removes a check for $ac_cv_prog_cc_c89 which is set by AC_PROG_CC
if defined(__STDC__) in the preprocessor. (Standard compliant compilers
are supposed to define __STDC__ to 1 but the value is actually not
checked here.)

Unfortunately, MSVC doesn't define it, so configure fails for MSVC.

This check is not very useful in practice. Over 30 years after C89 has
been released, there are no C compilers out there that are not
sufficiently compliant with C89 for the project. The only practically
relevant case was that the check rejected C++ compilers. A different
method to reject C++ compilers will be introduced in a later commit.
2022-03-17 22:13:47 +01:00
Jonas Nick
80cf4eea5f build: stop treating schnorrsig, extrakeys modules as experimental 2022-03-17 14:14:08 +00:00
Tim Ruffing
e0508ee9db Merge bitcoin-core/secp256k1#1090: configure: Remove redundant pkg-config code
21b2ebaf74 configure: Remove redundant pkg-config code (Tim Ruffing)

Pull request description:

  This removes code that detects the pkg-config tool. We used this
  back in the days when we had dependencies. ;) It can always be brought
  back if we'll need it in the future.

  Note that we still deliver a .pc file for this library, and there is
  code in Makefile.am to install it. But this does not require the
  pkg-config tool; only consumers of the .pc file will need it. This can
  be verified by running `make install` (maybe after `mkdir /tmp/pre` and
  `./configure --prefix=/tmp/pre` and checking that the .pc file is
  installed correctly.

ACKs for top commit:
  theuni:
    ACK 21b2ebaf74.
  fanquake:
    ACK 21b2ebaf74

Tree-SHA512: 07affcd0e85f59d10479f279c832b1384208bead2fd152e0d1e3d99167dba4e14dbe87b0bc9c367f0f18da3d37f1d51de064689bff329ee5b01cacfe54e5ede7
2022-03-17 11:39:12 +01:00
Tim Ruffing
21b2ebaf74 configure: Remove redundant pkg-config code
This removes code that detects the pkg-config tool. We used this
back in the days when we had dependencies. ;) It can always be brought
back if we'll need it in the future.

Note that we still deliver a .pc file for this library, and there is
code in Makefile.am to install it. But this does not require the
pkg-config tool; only consumers of the .pc file will need it. This can
be verified by running `make install` (maybe after `mkdir /tmp/pre` and
`./configure --prefix=/tmp/pre` and checking that the .pc file is
installed correctly.
2022-03-16 16:45:17 +01:00
Tim Ruffing
cca8cbbac8 configure: Output message when checking for valgrind 2022-03-16 16:36:29 +01:00
Tim Ruffing
1a6be5745f bench: Make benchmarks compile on MSVC 2022-03-16 16:36:29 +01:00
Jonas Nick
0e5cbd01b3 Merge bitcoin-core/secp256k1#1088: configure: Use modern way to set AR
0d253d52e8 configure: Use modern way to set AR (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jb55:
    tACK 0d253d52e8
  hebasto:
    ACK 0d253d52e8
  jonasnick:
    ACK 0d253d52e8

Tree-SHA512: c85a068b0b6cd0ae59c796d4493d50b1d92394b8620dd65affb5aaac889a41aa625408062f49fbed761217ab2bc35ec10942684a84487cb81becdadf5f2ae2af
2022-03-16 15:15:00 +00:00
Tim Ruffing
0d253d52e8 configure: Use modern way to set AR
This uses AM_PROG_AR to discover ar, which is the recommended way to do
so. Among other advantages, it honors the AR environment variable (as
set from the outside). The macro has been around since automake 1.11.2
(Dec 2011).

This commit also removes code that discovers ranlib and strip. ranlib
has been obsolete for decades (ar does its task now automatically), and
anyway LT_INIT takes care of discovering it. The code we used to set
STRIP was last mentioned in the automake 1.5 manual. Since automake 1.6
(Mar 2002), strip is discovered automatically when necessary (look for
the *private* macro AM_PROG_INSTALL_STRIP in the automake manual).
2022-03-14 18:35:59 +01:00
Tim Ruffing
9b514ce1d2 Add test vector for very long SHA256 messages
The vector has been taken from https://www.di-mgt.com.au/sha_testvectors.html.
It can be independently verified using the following Python code.

```
h = hashlib.sha256()
for i in range(1_000_000):
    h.update(b'a')
print(h.hexdigest())
```
2022-03-07 12:54:13 +01:00
Tim Ruffing
8e3dde1137 Simplify struct initializer for SHA256 padding
Since missing elements are initialized with zeros, this change is
purely syntactical.
2022-03-02 15:54:33 +01:00
Tim Ruffing
eb28464a8b Change SHA256 byte counter from size_t to uint64_t
This avoids that the SHA256 implementation would produce wrong paddings
and thus wrong digests for messages of length >= 2^32 bytes on 32-bit
platforms.

This is not exploitable in any way since the SHA256 API is an internal
API and we never call it with that long messages.
2022-03-02 15:54:33 +01:00
Jonas Nick
ac83be33d0 Merge bitcoin-core/secp256k1#1079: configure: Add hidden --enable-dev-mode to enable all the stuff
e0838d663d configure: Add hidden --enable-dev-mode to enable all the stuff (Tim Ruffing)
fabd579dfa configure: Remove redundant code that sets _enable variables (Tim Ruffing)
0d4226c051 configure: Use canonical variable prefix _enable consistently (Tim Ruffing)

Pull request description:

ACKs for top commit:
  elichai:
    tACK e0838d663d
  jonasnick:
    ACK e0838d663d

Tree-SHA512: dfa1977f8844b8c93c6e72e81845166b47892a0169d931413587ce4ca6b0516b38214635ccfcc008f657d49a07d00574bf9b2c3d40a6d538cc7493b8716219aa
2022-02-27 18:30:53 +00:00
Tim Ruffing
e089eecc1e group: Further simply gej_add_ge 2022-02-26 13:23:22 +01:00
Tim Ruffing
e0838d663d configure: Add hidden --enable-dev-mode to enable all the stuff
Co-authored-by: Elichai Turkel <elichai.turkel@gmail.com>
2022-02-26 10:30:29 +01:00
Tim Ruffing
fabd579dfa configure: Remove redundant code that sets _enable variables
These are set automatically by autoconf [1], and this has been the
case in at least since 2.60, which is our minimum supported version.

[1] https://www.gnu.org/software/autoconf/manual/autoconf-2.70/html_node/Package-Options.html
[2] https://www.gnu.org/software/autoconf/manual/autoconf-2.60/html_node/Package-Options.html
2022-02-23 21:14:59 +01:00
Tim Ruffing
0d4226c051 configure: Use canonical variable prefix _enable consistently 2022-02-23 21:11:53 +01:00
Jonas Nick
64b34979ed Merge bitcoin-core/secp256k1#748: Add usage examples
7c9502cece Add a copy of the CC0 license to the examples (Elichai Turkel)
42e03432e6 Add usage examples to the readme (Elichai Turkel)
517644eab1 Optionally compile the examples in autotools, compile+run in travis (Elichai Turkel)
422a7cc86a Add a ecdh shared secret example (Elichai Turkel)
b0cfbcc143 Add a Schnorr signing and verifying example (Elichai Turkel)
fee7d4bf9e Add an ECDSA signing and verifying example (Elichai Turkel)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 7c9502cece
  jonasnick:
    ACK 7c9502cece

Tree-SHA512: c475cfd5b324b1e2d7126aa5bb1e7da25183b50adb7357d464c140de83d9097cb1bdc027d09aeadf167dbf9c8afd123235b0a1a742c5795089862418fafa1964
2022-02-23 17:37:58 +00:00
Elichai Turkel
7c9502cece Add a copy of the CC0 license to the examples 2022-02-23 16:15:00 +02:00
Elichai Turkel
42e03432e6 Add usage examples to the readme 2022-02-23 16:14:59 +02:00
Elichai Turkel
517644eab1 Optionally compile the examples in autotools, compile+run in travis 2022-02-23 16:14:58 +02:00
Elichai Turkel
422a7cc86a Add a ecdh shared secret example
Co-authored-by: Jonas Nick <jonasd.nick@gmail.com>
2022-02-23 16:14:57 +02:00
Elichai Turkel
b0cfbcc143 Add a Schnorr signing and verifying example
Co-authored-by: Jonas Nick <jonasd.nick@gmail.com>
2022-02-23 16:14:55 +02:00
Elichai Turkel
fee7d4bf9e Add an ECDSA signing and verifying example
Co-authored-by: Jonas Nick <jonasd.nick@gmail.com>
2022-02-23 16:14:53 +02:00
Tim Ruffing
ac71020ebe group: Save a normalize_to_zero in gej_add_ge
The code currently switches to the alternative formula for lambda only if (R,M)
= (0,0) but the alternative formula works whenever M = 0: Specifically, M = 0
implies y1 = -y2. If x1 = x2, then a = -b this is the r = infinity case that we
handle separately. If x1 != x2, then the denominator in the alternative formula
is non-zero, so this formula is well-defined.

One needs to carefully check that the infinity assignment is still correct
because now the definition of m_alt at this point in the code has changed. But
this is true:

Case y1 = -y2:
  Then degenerate = true and infinity = ((x1 - x2)Z == 0) & ~a->infinity .
  a->infinity is handled separately.
  And if ~a->infinity, then Z = Z1 != 0,
  so infinity = (x1 - x2 == 0) = (a == -b) by case condition.

Case y1 != -y2:
  Then degenerate = false and infinity = ((y1 + y2)Z == 0) & ~a->infinity .
  a->infinity is handled separately.
  And if ~a->infinity, then Z = Z1 != 0,
  so infinity = (y1 + y2 == 0) = false by case condition.

Co-Authored-By: Pieter Wuille <pieter@wuille.net>
2022-02-21 11:25:18 +01:00
Tim Ruffing
1253a27756 Merge bitcoin-core/secp256k1#1033: Add _fe_half and use in _gej_add_ge and _gej_double
e848c3799c Update sage files for new formulae (Peter Dettman)
d64bb5d4f3 Add fe_half tests for worst-case inputs (Peter Dettman)
4eb8b932ff Further improve doubling formula using fe_half (Peter Dettman)
557b31fac3 Doubling formula using fe_half (Pieter Wuille)
2cbb4b1a42 Run more iterations of run_field_misc (Pieter Wuille)
9cc5c257ed Add test for secp256k1_fe_half (Pieter Wuille)
925f78d55e Add _fe_half and use in _gej_add_ge (Peter Dettman)

Pull request description:

  - Trades 1 _half for 3 _mul_int and 2 _normalize_weak

  Gives around 2-3% faster signing and ECDH, depending on compiler/platform.

ACKs for top commit:
  sipa:
    utACK e848c3799c
  jonasnick:
    ACK e848c3799c
  real-or-random:
    ACK e848c3799c

Tree-SHA512: 81a6c93b3d983f1b48ec8e8b6f262ba914215045a95415147f41ee6e85296aa4d0cbbad9f370cdf475571447baad861d2cc8e0b04a71202d48959cb8a098f584
2022-02-21 11:00:08 +01:00
Jonas Nick
3ef94aa5ba Merge bitcoin-core/secp256k1#1026: ecdh: Add test computing shared_secret=basepoint with random inputs
3531a43b5b ecdh: Make generator_basepoint test depend on global iteration count (Tim Ruffing)
c881dd49bd ecdh: Add test computing shared_secret=basepoint with random inputs (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 3531a43b5b

Tree-SHA512: 5a2e47bad7ec5b3fd9033283fe00e54563b7b1655baf2b8ca39718deceddcc816bb8fcda0d07af6f1f8a785642da5dc69b7df52a1ddd445a3a98a5d5ecff6780
2022-02-11 19:38:07 +00:00
Tim Ruffing
3531a43b5b ecdh: Make generator_basepoint test depend on global iteration count
Co-authored-by: Elliott Jin <elliott.jin@gmail.com>
2022-02-11 16:39:04 +01:00
Tim Ruffing
c881dd49bd ecdh: Add test computing shared_secret=basepoint with random inputs 2022-02-11 16:39:04 +01:00
Jonas Nick
077528317d Merge bitcoin-core/secp256k1#1074: ci: Retry brew update a few times to avoid random failures
e51ad3b737 ci: Retry `brew update` a few times to avoid random failures (Tim Ruffing)
b1cb969e8a ci: Revert "Attempt to make macOS builds more reliable" (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK e51ad3b737

Tree-SHA512: cb0b81ac8d81fe8ea58afa7382d3f922bd4eb713645c5d0b99f9de963c9906273f5d573a9272e8f6cdb16ffcca5e162c088cc2b0772278f68930f8cb726824be
2022-02-08 17:14:17 +00:00
Tim Ruffing
e51ad3b737 ci: Retry brew update a few times to avoid random failures 2022-02-08 14:09:58 +01:00
Tim Ruffing
b1cb969e8a ci: Revert "Attempt to make macOS builds more reliable"
This reverts commit d9396a56da, which
didn't have the desired effect.
2022-02-08 13:53:05 +01:00
Jonas Nick
f0edc90755 musig: fix number of tweaks in tweak_test 2022-02-07 13:56:56 +00:00
Jonas Nick
5dcc6f8dbd Merge bitcoin-core/secp256k1#1069: build: Replace use of deprecated autoconf macro AC_PROG_CC_C89
e0db3f8a25 build: Replace use of deprecated autoconf macro AC_PROG_CC_C89 (laanwj)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK e0db3f8a25
  jonasnick:
    ACK e0db3f8a25

Tree-SHA512: 00d6719fcdea69d002c795bbed07ccbd69900fef7dcba8ee42aa4e77765034feeb036ac9147b7fccc88b41623f735f62d4c72e25b3a1e68caad08a1237d6c5f5
2022-02-06 20:44:55 +00:00
Jonas Nick
59547943d6 Merge bitcoin-core/secp256k1#1072: ci: Attempt to make macOS builds more reliable
d9396a56da ci: Attempt to make macOS builds more reliable (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK d9396a56da

Tree-SHA512: 68df44107d74671de148e9c3e6dbc6b16bec937137d7d9771efce10f5d66459559b372346d05ecc23237b2e3af9479156f733219717cb93f5204f9ea5b2636a9
2022-02-06 19:30:14 +00:00
Jonas Nick
85b00a1c65 Merge bitcoin-core/secp256k1#1068: sage: Fix incompatibility with sage 9.4
ebb1beea78 sage: Ensure that constraints are always fastfracs (Tim Ruffing)
d8d54859ed ci: Run sage prover on CI (Tim Ruffing)
77cfa98dbc sage: Normalize sign of polynomial factors in prover (Tim Ruffing)
eae75869cf sage: Exit with non-zero status in case of failures (Tim Ruffing)
b54d843eac sage: Fix printing of errors (Tim Ruffing)
e108d0039c sage: Fix incompatibility with sage 9.4 (Tim Ruffing)

Pull request description:

ACKs for top commit:
  sipa:
    ACK ebb1beea78
  jonasnick:
    ACK ebb1beea78

Tree-SHA512: 7a4732fd31d925d3dff471911183acc465ddcadbb5c88c46995502df61a913433c7639cb52fad3db72373b7cc47b9b0f063f7f5d5f8189c9ef998955e409479f
2022-02-05 22:06:29 +00:00
Tim Ruffing
ebb1beea78 sage: Ensure that constraints are always fastfracs
Even if they are constants created in the formula functions. We now
lift integer constants to fastfracs.
2022-02-04 15:39:44 +01:00
Tim Ruffing
d8d54859ed ci: Run sage prover on CI 2022-02-04 15:37:32 +01:00
Tim Ruffing
77cfa98dbc sage: Normalize sign of polynomial factors in prover
The prover, when run on recent sage versions,  failed to prove some of its
goals due to a change in sage. This commit adapts our code accordingly.
The prover passes again after this commit.
2022-02-04 15:37:32 +01:00
Tim Ruffing
eae75869cf sage: Exit with non-zero status in case of failures 2022-02-04 15:37:32 +01:00
Tim Ruffing
d9396a56da ci: Attempt to make macOS builds more reliable
The macOS CI tasks often error fail when doing `brew update` with
git fetch errors:
```
remote: fatal: packfile /data/repositories/b/nw/b6/07/5c/123272362/network.git/objects/pack/pack-2139bd07361b62a358e380a0e7d58ec35593d191.pack cannot be accessed
fatal: protocol error: bad pack header
Error: Fetching /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core failed!
```
Superficially this seems to be a problem on the GitHub server because
the message shows a "remote" error. But it seems we're the only one in
the world running into this specific issue when doing `brew update`, so
it's more likely that the something else is the culprit, and this error
message is just a symptom.

This commit replaces `brew update` with a complete reinstallation of
brew. This is essentially a shot in the dark but it's worth a try, and
I doubt it's significantly more expensive. If that won't work, we may
consider simply retrying `brew update` a few times.
2022-02-04 10:55:19 +01:00
laanwj
e0db3f8a25 build: Replace use of deprecated autoconf macro AC_PROG_CC_C89
According to [autoconf 2.70](https://www.gnu.org/software/autoconf/manual/autoconf-2.70/html_node/Obsolete-Macros.html)
documentation, the `AC_PROG_CC_C89' is replaced by `AC_PROG_CC`, which
defines the same variable `ac_cv_prog_cc_c89`.

Avoids the following message:
```
configure.ac:23: warning: The macro `AC_PROG_CC_C89' is obsolete.
```

Also, remove deprecated `AM_PROG_CC_C_O`.
2022-02-03 08:57:36 +01:00
Peter Dettman
e848c3799c Update sage files for new formulae
- formula_secp256k1_gej_double_var
- formula_secp256k1_gej_add_ge
2022-02-01 17:51:13 +07:00
Peter Dettman
d64bb5d4f3 Add fe_half tests for worst-case inputs
- Add field method _fe_get_bounds
2022-02-01 17:51:05 +07:00
Tim Ruffing
b54d843eac sage: Fix printing of errors
Python 3 often returns iterable map objects where Python 2 returned
list. We can just them down to lists explicitly.

Overlooked in 13c88efed0.
2022-01-31 15:17:46 +01:00
Jonas Nick
725d895fc5 Merge elementsproject/secp256k1-zkp#165: musig-spec: improve security argument for handling infinity
aa1acb4bd1 musig-spec: improve security argument for handling infinity (Elliott Jin)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK aa1acb4bd1

Tree-SHA512: bea792019462a6de4d3e5f5c60982a1e1b2faa90b047681592a22ac56e872ef8f86f976adb41586bbf8cf86f39cc012dd1d02e58ff8e7226f7d857d9a67d05f6
2022-01-31 14:07:15 +00:00
Peter Dettman
4eb8b932ff Further improve doubling formula using fe_half 2022-01-31 19:41:07 +07:00
Pieter Wuille
557b31fac3 Doubling formula using fe_half 2022-01-31 19:41:07 +07:00
Pieter Wuille
2cbb4b1a42 Run more iterations of run_field_misc
At count=64, this makes the test take around 1% of the total time.
2022-01-31 19:41:07 +07:00
Pieter Wuille
9cc5c257ed Add test for secp256k1_fe_half 2022-01-31 19:41:07 +07:00
Peter Dettman
925f78d55e Add _fe_half and use in _gej_add_ge
- Trades 1 _half for 3 _mul_int and 2 _normalize_weak
- Updated formula and comments in _gej_add_ge
- Added internal benchmark for _fe_half
2022-01-31 19:41:01 +07:00
Tim Ruffing
e108d0039c sage: Fix incompatibility with sage 9.4
`allexprs` is already the product all numerators. Don't take it's
numerator again.

Fixes #1067.
2022-01-31 12:15:16 +01:00
Elliott Jin
aa1acb4bd1 musig-spec: improve security argument for handling infinity
Co-authored-by: Tim Ruffing <crypto@timruffing.de>
2022-01-27 05:23:15 -08:00
Jonas Nick
d8a2463246 Merge bitcoin-core/secp256k1#899: Reduce stratch space needed by ecmult_strauss_wnaf.
b797a500ec Create a SECP256K1_ECMULT_TABLE_VERIFY macro. (Russell O'Connor)
a731200cc3 Replace ECMULT_TABLE_GET_GE_STORAGE macro with a function. (Russell O'Connor)
fe34d9f341 Eliminate input_pos state field from ecmult_strauss_wnaf. (Russell O'Connor)
0397d00ba0 Eliminate na_1 and na_lam state fields from ecmult_strauss_wnaf. (Russell O'Connor)
7ba3ffcca0 Remove the unused pre_a_lam allocations. (Russell O'Connor)
b3b57ad6ee Eliminate the pre_a_lam array from ecmult_strauss_wnaf. (Russell O'Connor)
ae7ba0f922 Remove the unused prej allocations. (Russell O'Connor)
e5c18892db Eliminate the prej array from ecmult_strauss_wnaf. (Russell O'Connor)
c9da1baad1 Move secp256k1_fe_one to field.h (Russell O'Connor)

Pull request description:

ACKs for top commit:
  sipa:
    ACK b797a500ec
  jonasnick:
    ACK b797a500ec

Tree-SHA512: 6742469979c306104a0861be76c2be86bf8ab14116b00afbd24f91b9e3ea843bf9b9a74552b367bd06ee617090019ad4df6be037d58937c8c869f8b37ddaa6cc
2022-01-26 14:49:40 +00:00
Tim Ruffing
73f0cbd3cc Merge ElementsProject/secp256k1-zkp#157: Add description of MuSig signing to musig-spec.md
69b392f3cb musig: move explanation for aggnonce=inf to spec (Jonas Nick)
4824220bb7 musig-spec: describe NonceGen, NonceAgg, Sign,PartialSig{Verify,Agg} (Jonas Nick)
3c122d0780 musig-spec: improve definition of lift_x (Jonas Nick)
e0bb2d7009 musig-spec: improve KeyAgg description (Jonas Nick)
b8f4e75d89 musig-spec: move to doc directory (Jonas Nick)

Pull request description:

  Will wait before adding tweaking until #151 is merged.

ACKs for top commit:
  robot-dreams:
    ACK 69b392f3cb based on:
  real-or-random:
    ACK 69b392f3cb I haven't looked at every detail but it's certainly ready to be merged as draft spec

Tree-SHA512: e3aa0265a9d7a7648e03ca42575397100edd5af43f0224937af51aa5c77efc451d7938149bdc711f69e24fb9291438453b8cd762affaa1a2e7bcc89f121485df
2022-01-25 10:55:25 +01:00
Tim Ruffing
8fd97d8116 Merge ElementsProject/secp256k1-zkp#158: Small musig improvements
d895b10c18 musig: mention musig.md in example (Jonas Nick)
588009d26f musig: improve doc of partial_sig_verify regarding signing sessions (Jonas Nick)
b1094953c4 musig: remove superfluous comment (Jonas Nick)

Pull request description:

ACKs for top commit:
  robot-dreams:
    ACK d895b10c18
  real-or-random:
    ACK d895b10c18

Tree-SHA512: 35169240868500bb27e5a6b8779f090d3f33a6c0cb1a4574e6e53e9c52782f454fe7df6d49b68e0acdd174e25a756bf6267339f0d4e94f28d5ae49145f21e298
2022-01-25 10:53:38 +01:00
Tim Ruffing
772df3694e Merge ElementsProject/secp256k1-zkp#151: MuSig: Add Minimal Compatibility with BIP32 Tweaking
8088eddc53 musig: add test vector for ordinary (non xonly) tweaking (Elliott Jin)
57a17929fc musig: add ordinary and xonly tweaking to the example (Jonas Nick)
37107361a0 musig: allow ordinary, non-xonly tweaking (Jonas Nick)
c519b46879 musig: add pubkey_get to obtain a full pubkey from a keyagg_cache (Jonas Nick)

Pull request description:

  In short, `musig_pubkey_tweak_add` now allows for xonly _and_ "ordinary" tweaking. Also, in order to allow using `ec_pubkey_tweak_add` on the non-xonly aggregate public key, there's a new function `musig_pubkey_get` that allows obtaining it from the `keyagg_cache`.

  One alternative would be that instead of adding `musig_pubkey_get`, we could change `pubkey_agg` to output an ordinary (non-xonly) pubkey. Then users of the API who do not need ordinary (BIP32) tweaking would be forced to call `xonly_pubkey_from_pubkey`. And we'd probably want to change the spec. And it would be a bit weird to output a pubkey that can't be directly schnorrsig_verify'd.

  Based on #131

ACKs for top commit:
  robot-dreams:
    ACK 8088eddc53 based on https://github.com/ElementsProject/secp256k1-zkp/pull/151#issuecomment-1005198409 and the following `range-diff`:

Tree-SHA512: a4a0100f0470c870f88a8da27dbcc4684fcc2caabb368d4340e962e08d5ee04634e6289bafa3448dbfd0b5793a3e70de5bd6ddca7a619cc3220ff762d518a8fe
2022-01-25 10:18:40 +01:00
Tim Ruffing
0a40a4861a Merge bitcoin-core/secp256k1#1049: Faster fixed-input ecmult tests
070e772211 Faster fixed-input ecmult tests (Pieter Wuille)

Pull request description:

  Given how much #920 slowed down the tests with low iteration count, replace it with 3 different similar test:
  * count >= 1: a test with 1024 multiplies that tests any pattern of 6 bits in windows not more than 20 bits wide
  * count >= 3: a test with 2048 multiplies that tests any pattern of 8 consecutive bits
  * count >= 35: the old test (which effectively tests all 2-bit patterns)

ACKs for top commit:
  robot-dreams:
    ACK 070e772211, the addition of the `CONDITIONAL_TEST` macro is nice.
  real-or-random:
    ACK 070e772211

Tree-SHA512: b4ccca42c71fcd1baa7143f73d1c3ac9d012c296485164a03341dbeee02e4ba9f7c7ad6b441923a5fe0286c97eff60815033adb4e1d30b3ef08bcb79590327ff
2022-01-24 22:01:54 +01:00
Jonas Nick
69b392f3cb musig: move explanation for aggnonce=inf to spec 2022-01-24 15:50:42 +00:00
Jonas Nick
4824220bb7 musig-spec: describe NonceGen, NonceAgg, Sign,PartialSig{Verify,Agg} 2022-01-24 15:50:42 +00:00
Jonas Nick
3c122d0780 musig-spec: improve definition of lift_x 2022-01-24 15:50:42 +00:00
Jonas Nick
e0bb2d7009 musig-spec: improve KeyAgg description
It's easier to identify a signer with a public key instead of an index in
KeyAggCoef because it doesn't force the signer to know its index.
2022-01-24 15:50:39 +00:00
Jonas Nick
b8f4e75d89 musig-spec: move to doc directory 2022-01-24 15:45:51 +00:00
Pieter Wuille
070e772211 Faster fixed-input ecmult tests 2022-01-22 18:44:32 -05:00
Pieter Wuille
c8aa516b57 Merge bitcoin-core/secp256k1#1064: Modulo-reduce msg32 inside RFC6979 nonce fn to match spec. Fixes #1063
45f37b6506 Modulo-reduce msg32 inside RFC6979 nonce fn to match spec. Fixes #1063. (Paul Miller)

Pull request description:

ACKs for top commit:
  siv2r:
    ACK 45f37b6. The diff looks good. It reduces `msg32` to modulo curve order for rfc6979 nonce generation. All tests passed on my machine with `make check`.
  sipa:
    utACK 45f37b6506
  real-or-random:
    ACK 45f37b6506

Tree-SHA512: 4c36784b2d6f2983bc0c3f380ff59cd9f2bd1822b98116d70964cd15183742fcc1f2ccde225a76dd30d946b3678b2cf29caff018efc07f40a200ee85843b39dd
2022-01-22 18:38:27 -05:00
Elliott Jin
8088eddc53 musig: add test vector for ordinary (non xonly) tweaking 2022-01-21 17:07:06 +00:00
Jonas Nick
57a17929fc musig: add ordinary and xonly tweaking to the example 2022-01-21 17:07:06 +00:00
Jonas Nick
37107361a0 musig: allow ordinary, non-xonly tweaking 2022-01-21 17:07:06 +00:00
Jonas Nick
c519b46879 musig: add pubkey_get to obtain a full pubkey from a keyagg_cache 2022-01-21 17:07:06 +00:00
Russell O'Connor
b797a500ec Create a SECP256K1_ECMULT_TABLE_VERIFY macro. 2022-01-19 11:51:43 -05:00
Russell O'Connor
a731200cc3 Replace ECMULT_TABLE_GET_GE_STORAGE macro with a function. 2022-01-19 11:51:43 -05:00
Russell O'Connor
fe34d9f341 Eliminate input_pos state field from ecmult_strauss_wnaf. 2022-01-19 11:51:43 -05:00
Russell O'Connor
0397d00ba0 Eliminate na_1 and na_lam state fields from ecmult_strauss_wnaf. 2022-01-19 11:51:43 -05:00
Russell O'Connor
7ba3ffcca0 Remove the unused pre_a_lam allocations. 2022-01-19 11:51:43 -05:00
Russell O'Connor
b3b57ad6ee Eliminate the pre_a_lam array from ecmult_strauss_wnaf. 2022-01-19 11:51:43 -05:00
Russell O'Connor
ae7ba0f922 Remove the unused prej allocations. 2022-01-19 11:51:43 -05:00
Russell O'Connor
e5c18892db Eliminate the prej array from ecmult_strauss_wnaf. 2022-01-19 11:51:42 -05:00
Russell O'Connor
c9da1baad1 Move secp256k1_fe_one to field.h
This makes secp256k1_fe_one part of field.h's interface, and allows other modules to appropriately access the constant.
2022-01-19 09:53:02 -05:00
Paul Miller
45f37b6506 Modulo-reduce msg32 inside RFC6979 nonce fn to match spec. Fixes #1063. 2022-01-17 04:07:16 +02:00
Jonas Nick
a5b5909e8d Merge elementsproject/secp256k1-zkp#163: Typo, add subscript i
44001ad716 Typo fix, add subscript i (Kalle Rosenbaum)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 44001ad716

Tree-SHA512: a0d472e8708a467c471be033113bff9f3c6ab5990751173c6150452efdb403f1af8d61314e8358fa817a9a20cbeefd1c33154231a4d1d68ca09ced64dbb8d2b2
2022-01-15 15:12:30 +00:00
Kalle Rosenbaum
44001ad716 Typo fix, add subscript i 2022-01-15 12:31:00 +01:00
Jonas Nick
eb5e71b5dc Merge elementsproject/secp256k1-zkp#162: whitelist: remove ability to specific nonce function
11d675dce8 whitelist: remove ability to specific nonce function (Andrew Poelstra)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 11d675dce8

Tree-SHA512: aa53d445a1e817e9998a41f5da186f1d92e3da0dcc088b9ff8fe795af06072d3e6b22be7842ece9f4dcb5e0ad97a90ebeaca097247fa8307d88a6d2bfb0fb573
2022-01-13 16:47:49 +00:00
Andrew Poelstra
11d675dce8 whitelist: remove ability to specific nonce function
This functionality is inappropriate to expose for a zero-knowledge proof,
and was confusingly (and potentially dangerously) implemented.
2022-01-06 19:12:14 +00:00
Tim Ruffing
21e2d65b79 Merge ElementsProject/secp256k1-zkp#159: Sync Upstream
b7ebe6436c Test APIs of funcs that need an ecmult_gen ctx with static ctx (Jonas Nick)
e82144edfb Fixup skew before global Z fixup (Peter Dettman)
40b624c90b Add tests for _gej_cmov (Peter Dettman)
8c13a9bfe1 ECDH skews by 0 or 1 (Peter Dettman)
1515099433 Simpler and faster ecdh skew fixup (Peter Dettman)
3d7cbafb5f tests: Fix test whose result is implementation-defined (Tim Ruffing)
77a19750b4 Use xoshiro256++ PRNG instead of RFC6979 in tests (Pieter Wuille)
5f2efe684e secp256k1_testrand_int(2**N) -> secp256k1_testrand_bits(N) (Pieter Wuille)
3ed0d02bf7 doc: add CHANGELOG template (Jonas Nick)
6f42dc16c8 doc: add release_process.md (Jonas Nick)
0bd3e4243c build: set library version to 0.0.0 explicitly (Jonas Nick)
b4b02fd8c4 build: change libsecp version from 0.1 to 0.1.0-pre (Jonas Nick)
05e049b73c ecmult: move `_ecmult_odd_multiples_table_globalz_windowa` (siv2r)
b4ac1a1d5f ci: Run valgrind/memcheck tasks with 2 CPUs (Tim Ruffing)
e70acab601 ci: Use Cirrus "greedy" flag to use idle CPU time when available (Tim Ruffing)
d07e30176e ci: Update brew on macOS (Tim Ruffing)
22382f0ea0 ci: Test different ecmult window sizes (Tim Ruffing)
26a022a3a0 ci: Remove STATICPRECOMPUTATION (Tim Ruffing)
10461d8bd3 precompute_ecmult: Always compute all tables up to default WINDOW_G (Tim Ruffing)
1287786c7a doc: Add comment to top of field_10x26_impl.h (Elliott Jin)
58da5bd589 doc: Fix upper bounds + cleanup in field_5x52_impl.h comment (Elliott Jin)
22d25c8e0a Add another ecmult_multi test (Pieter Wuille)
515e7953ca Improve checks at top of _fe_negate methods (Peter Dettman)
e05da9e480 Fix c++ build (Pieter Wuille)
c45386d994 Cleanup preprocessor indentation in precompute{,d}_ecmult{,_gen} (Pieter Wuille)
19d96e15f9 Split off .c file from precomputed_ecmult.h (Pieter Wuille)
1a6691adae Split off .c file from precomputed_ecmult_gen.h (Pieter Wuille)
bb36331412 Simplify precompute_ecmult_print_* (Pieter Wuille)
38cd84a0cb Compute ecmult tables at runtime for tests_exhaustive (Pieter Wuille)
e458ec26d6 Move ecmult table computation code to separate file (Pieter Wuille)
fc1bf9f15f Split ecmult table computation and printing (Pieter Wuille)
31feab053b Rename function secp256k1_ecmult_gen_{create_prec -> compute}_table (Pieter Wuille)
725370c3f2 Rename ecmult_gen_prec -> ecmult_gen_compute_table (Pieter Wuille)
075252c1b7 Rename ecmult_static_pre_g -> precomputed_ecmult (Pieter Wuille)
7cf47f72bc Rename ecmult_gen_static_prec_table -> precomputed_ecmult_gen (Pieter Wuille)
f95b8106d0 Rename gen_ecmult_static_pre_g -> precompute_ecmult (Pieter Wuille)
bae77685eb Rename gen_ecmult_gen_static_prec_table -> precompute_ecmult_gen (Pieter Wuille)
7dfceceea6 build: Remove #undef hack for ASM in the precomputation programs (Tim Ruffing)
bb36fe9be0 ci: Test `make precomp` (Tim Ruffing)
d94a37a20c build: Remove CC_FOR_BUILD stuff (Tim Ruffing)
ad63bb4c29 build: Prebuild and distribute ecmult_gen table (Tim Ruffing)
ac49361ed0 prealloc: Get rid of manual memory management for prealloc contexts (Tim Ruffing)
6573c08f65 ecmult_gen: Tidy precomputed file and save space (Tim Ruffing)
5eba83f17c ecmult_gen: Precompute tables for all values of ECMULT_GEN_PREC_BITS (Tim Ruffing)
fdb33dd122 refactor: Make PREC_BITS a parameter of ecmult_gen_build_prec_table (Tim Ruffing)
a4875e30a6 refactor: Move default callbacks to util.h (Tim Ruffing)
4c94c55bce doc: Remove obsolete hint for valgrind stack size (Tim Ruffing)
5106226991 exhaustive_tests: Fix with ecmult_gen table with custom generator (Tim Ruffing)
e1a76530db refactor: Make generator a parameter of ecmult_gen_create_prec_table (Tim Ruffing)
9ad09f6911 refactor: Rename program that generates static ecmult_gen table (Tim Ruffing)
8ae18f1ab3 refactor: Rename file that contains static ecmult_gen table (Tim Ruffing)
00d2fa116e ecmult_gen: Make code consistent with comment (Tim Ruffing)
3b0c2185ea ecmult_gen: Simplify ecmult_gen context after making table static (Tim Ruffing)
e43ba02cfc refactor: Decouple table generation and ecmult_gen context (Tim Ruffing)
22dc2c0a0d ecmult_gen: Move table creation to new file and force static prec (Tim Ruffing)
099bad945e Comment and check a parameter for inf in secp256k1_ecmult_const. (Russell O'Connor)
6c0be857f8 Verify that secp256k1_ge_set_gej_zinv does not operate on infinity. a->x and a->y should not be used if the infinity flag is set. (Russell O'Connor)
5eb519e1f6 ci: reduce TEST_ITERS in memcheck run (Pieter Wuille)
e2cf77328a Test ecmult functions for all i*2^j for j=0..255 and odd i=1..255. (Pieter Wuille)
c0cd7de6d4 build: add -no-undefined to libtool LDFLAGS (fanquake)
fe32a79d35 build: pass win32-dll to LT_INIT (fanquake)
7c7ce872a5 build: Add a check that Valgrind actually supports a host platform (Hennadii Stepanov)
592661c22f ci: move test environment variable declaration to .cirrus.yml (siv2r)
dcbe84b841 bench: add --help option to bench. (siv2r)
2b7c7497ef build: replace backtick command substitution with $() (fanquake)
60bf8890df ecmult: fix definition of STRAUSS_SCRATCH_OBJECTS (Jonas Nick)
214042a170 build: don't append valgrind CPPFLAGS if not installed (fanquake)
812ff5c747 doc: remove use of 0xa0 "no break space" (fanquake)
dc9b6853b7 doc: Minor fixes in safegcd_implementation.md (Elliott Jin)
233297579d Fix typos (Dimitris Apostolou)
72de1359e9 ci: Enable -g if we set CFLAGS manually (Tim Ruffing)
16d132215c refactor: Use (int)&(int) in boolean context to avoid compiler warning (MarcoFalke)
3b157c48ed doc: Suggest keys.openpgp.org as keyserver in SECURITY.md (Tim Ruffing)
73a7472cd0 doc: Replace apoelstra's GPG key by jonasnick's GPG key (Tim Ruffing)
af6abcb3d0 Make bench support selecting which benchmarks to run (Pieter Wuille)
9f56bdf5b9 Merge bench_schnorrsig into bench (Pieter Wuille)
3208557ae1 Merge bench_recover into bench (Pieter Wuille)
855e18d8a8 Merge bench_ecdh into bench (Pieter Wuille)
2a7be678a6 Combine bench_sign and bench_verify into single bench (Pieter Wuille)
5324f8942d Make aux_rnd32==NULL behave identical to 0x0000..00. (Pieter Wuille)
2888640132 VERIFY_CHECK precondition for secp256k1_fe_set_int. (Russell O'Connor)
d49011f54c Make _set_fe_int( . , 0 ) set magnitude to 0 (Tim Ruffing)
23e2f66726 bench: don't return 1 in have_flag() if argc = 1 (Jonas Nick)
96b1ad2ea9 bench_ecmult: improve clarity of output (Jonas Nick)
b4b130678d create csv file from the benchmark output (siv2r)
26a255beb6 Shared benchmark format for command line and CSV outputs (siv2r)
044d956305 Fix G.y parity in sage code (Pieter Wuille)
b53e0cd61f Avoid overly-wide multiplications (Peter Dettman)
9be7b0f083 Avoid computing out-of-bounds pointer. (Tim Ruffing)
bc08599e77 Remove OpenSSL testing support (Pieter Wuille)
db4667d5e0 Make aux_rand32 arg to secp256k1_schnorrsig_sign const (Pieter Wuille)
189f6bcfef Fix unused parameter warnings when building without VERIFY (Jonas Nick)
d43993724d tests: remove `secp256k1_fe_verify` from tests.c and modify `secp256k1_fe_from_storage` to call `secp256k1_fe_verify` (siv2r)

Pull request description:

  [bitcoin-core/secp256k1#986]: tests: remove `secp256k1_fe_verify` from tests.c and modify `_fe_from_storage` to call `_fe_verify`
  [bitcoin-core/secp256k1#987]: Fix unused parameter warnings when building without VERIFY
  [bitcoin-core/secp256k1#966]: Make aux_rand32 arg to secp256k1_schnorrsig_sign const
  [bitcoin-core/secp256k1#983]: [RFC] Remove OpenSSL testing support
  [bitcoin-core/secp256k1#952]: Avoid computing out-of-bounds pointer.
  [bitcoin-core/secp256k1#810]: Avoid overly-wide multiplications in 5x52 field mul/sqr
  [bitcoin-core/secp256k1#996]: Fix G.y parity in sage code
  [bitcoin-core/secp256k1#989]: Shared benchmark format for command line and CSV outputs
  [bitcoin-core/secp256k1#999]: bench_ecmult: improve clarity of output
  [bitcoin-core/secp256k1#943]: VERIFY_CHECK precondition for secp256k1_fe_set_int.
  [bitcoin-core/secp256k1#1002]: Make aux_rnd32==NULL behave identical to 0x0000..00.
  [bitcoin-core/secp256k1#991]: Merge all "external" benchmarks into a single bench binary
  [bitcoin-core/secp256k1#1007]: doc: Replace apoelstra's GPG key by jonasnick's GPG key
  [bitcoin-core/secp256k1#1009]: refactor: Use (int)&(int) in boolean context to avoid compiler warning
  [bitcoin-core/secp256k1#1011]: ci: Enable -g if we set CFLAGS manually
  [bitcoin-core/secp256k1#1012]: Fix typos
  [bitcoin-core/secp256k1#1010]: doc: Minor fixes in safegcd_implementation.md
  [bitcoin-core/secp256k1#1020]: doc: remove use of <0xa0> "no break space"
  [bitcoin-core/secp256k1#1019]: build: don't append valgrind CPPFLAGS if not installed (macOS)
  [bitcoin-core/secp256k1#1004]: ecmult: fix definition of STRAUSS_SCRATCH_OBJECTS
  [bitcoin-core/secp256k1#1025]: build: replace backtick command substitution with $()
  [bitcoin-core/secp256k1#1008]: bench.c: add `--help` option and ci: move env variables
  [bitcoin-core/secp256k1#1027]: build: Add a check that Valgrind actually supports a host platform
  [bitcoin-core/secp256k1#1022]: build: Windows DLL additions
  [bitcoin-core/secp256k1#920]: Test all ecmult functions with many j*2^i combinations
  [bitcoin-core/secp256k1#942]: Verify that secp256k1_ge_set_gej_zinv does not operate on infinity.
  [bitcoin-core/secp256k1#988]: Make signing table fully static
  [bitcoin-core/secp256k1#1042]: Follow-ups to making all tables fully static
  [bitcoin-core/secp256k1#816]: Improve checks at top of _fe_negate methods
  [bitcoin-core/secp256k1#1044]: Add another ecmult_multi test
  [bitcoin-core/secp256k1#1030]: doc: Fix upper bounds + cleanup in field_5x52_impl.h comment
  [bitcoin-core/secp256k1#1047]: ci: Various improvements
  [bitcoin-core/secp256k1#1053]: ecmult: move `_ecmult_odd_multiples_table_globalz_windowa`
  [bitcoin-core/secp256k1#964]: Add release-process.md
  [bitcoin-core/secp256k1#1052]: Use xoshiro256++ instead of RFC6979 for tests
  [bitcoin-core/secp256k1#1054]: tests: Fix test whose result is implementation-defined
  [bitcoin-core/secp256k1#1029]: Simpler and faster ecdh skew fixup

  This PR can be recreated  with `./contrib/sync-upstream.sh range a1102b12196ea27f44d6201de4d25926a2ae9640`.

ACKs for top commit:
  apoelstra:
    utACK b7ebe6436c
  real-or-random:
    ACK b7ebe6436c diff looks good. tested on my machine, also on valgrind.

Tree-SHA512: 8b01347bbb9ac35cb93df628eaaf2a997fc8182046588bccc48a0623e9595d40cad2d46102a9c62c819ff77069331f344361138fd8ad0afc81bba9c1690bb541
2022-01-05 19:02:17 +01:00
Jonas Nick
b7ebe6436c Test APIs of funcs that need an ecmult_gen ctx with static ctx
The API tests of upstream functions were similarly amended in commit 3b0c2185ea.
2022-01-04 12:57:57 +00:00
Jonas Nick
d895b10c18 musig: mention musig.md in example 2022-01-02 19:42:15 +00:00
Jonas Nick
588009d26f musig: improve doc of partial_sig_verify regarding signing sessions 2022-01-02 19:42:15 +00:00
Jonas Nick
72c8deac03 Merge commits with sync-upstream.sh
da0092bc 10f9bd84 297ce820 f34b5cae 920a0e5f 9526874d aa1b889b 20d791ed 3e7b2ea1 21c188b3 8fa41201 515a5dbd c74a7b7e 74c34e72 7006f1b9 ea5e8a9c 793ad901 2e5e4b67 fecf436d 49f608de 49002274 6ad908aa 4f01840b 61ae37c6 486205aa 5d0dbef0 0559fc6e be6944ad a69df3ad b39d431a 0b83b203 09971a3f 9281c9f4 423b6d19 a310e79e 39a36db9 a1102b12

Deal with
  - secp256k1_test_rng removal in commit
    77a19750b4
  - ecmult_gen context simplification after making table static in commit
    3b0c2185ea
2022-01-02 16:11:15 +00:00
Pieter Wuille
a1102b1219 Merge bitcoin-core/secp256k1#1029: Simpler and faster ecdh skew fixup
e82144edfb Fixup skew before global Z fixup (Peter Dettman)
40b624c90b Add tests for _gej_cmov (Peter Dettman)
8c13a9bfe1 ECDH skews by 0 or 1 (Peter Dettman)
1515099433 Simpler and faster ecdh skew fixup (Peter Dettman)

Pull request description:

  This PR adds a `_gej_cmov` method, with accompanying tests, and uses it to simplify the skew fixup at the end of `_ecmult_const`.

  In the existing code, `_wnaf_const` chooses a skew of either 1 or 2, and `_ecmult_const` needs a call to `_ge_set_gej` (which does an expensive field inversion internally) and some overly-complicated conversions to/from `_ge_storage` so that `_ge_storage_cmov` can be used to select what value to add for the fixup.

  This PR uses a simpler scheme where `_wnaf_const` chooses a skew of 0 or 1 and no longer needs special handling for scalars with value negative one. A new `_gej_cmov` method is used at the end of `_ecmult_const` for const-time optional addition to adjust the final result for the skew. Finally, the skew fixup is moved to before the global-Z adjustment, and the precomputed table entries (for 1P, &#955;(1P)) are used for the skew fixup, saving a field multiply and ensuring the fixup is done on the same isomorphism as the ladder.

  The resulting `_wnaf_const` and `_ecmult_const` are shorter and simpler, and the ECDH benchmark is around 5% faster (64bit, i7).

  Edit: Updated description once the final scope was clear.

ACKs for top commit:
  apoelstra:
    ACK e82144ed
  sipa:
    ACK e82144edfb
  real-or-random:
    ACK e82144edfb

Tree-SHA512: 10d6770f4ef4f8d0c78abbf58d643f25f5daef68896643af0a3f7f877414e23356724b6f20af2027316a4353a35b8cb0a7851e057a3f6483897df02bf033a8a2
2021-12-31 14:44:59 -05:00
Jonas Nick
b1094953c4 musig: remove superfluous comment
This was simply forgotten to be removed.
2021-12-30 17:52:03 +00:00
Peter Dettman
e82144edfb Fixup skew before global Z fixup 2021-12-26 14:56:51 +07:00
Peter Dettman
40b624c90b Add tests for _gej_cmov 2021-12-26 14:56:51 +07:00
Peter Dettman
8c13a9bfe1 ECDH skews by 0 or 1 2021-12-26 14:56:51 +07:00
Peter Dettman
1515099433 Simpler and faster ecdh skew fixup 2021-12-26 14:56:51 +07:00
Tim Ruffing
39a36db94a Merge bitcoin-core/secp256k1#1054: tests: Fix test whose result is implementation-defined
3d7cbafb5f tests: Fix test whose result is implementation-defined (Tim Ruffing)

Pull request description:

  A compiler may add struct padding and fe_cmov is not guaranteed to
  preserve it.

  On the way, we restore the name of the function. It was mistakenly
  renamed in 6173839c90 using
  "search and replace".

ACKs for top commit:
  robot-dreams:
    ACK 3d7cbafb5f
  sipa:
    utACK 3d7cbafb5f

Tree-SHA512: f8bb643d4915e9ce9c4fe45b48a2878f6cf1f29e654be1c150cdf65c6959cf65f8491928cf098da5a01f1d488ba475914905ca96b232abed499eb6ed65e53fb8
2021-12-25 21:41:17 +01:00
Tim Ruffing
a310e79ee5 Merge bitcoin-core/secp256k1#1052: Use xoshiro256++ instead of RFC6979 for tests
77a19750b4 Use xoshiro256++ PRNG instead of RFC6979 in tests (Pieter Wuille)
5f2efe684e secp256k1_testrand_int(2**N) -> secp256k1_testrand_bits(N) (Pieter Wuille)

Pull request description:

  Just some easy low-hanging fruit. It's complete overkill to use the RFC6979 RNG for our test randomness. Replace it with a modern non-cryptographic RNG with good properties. It's a few % speedup for me.

  Given the internal naming of all these functions to be "testrand", I'm not concerned about the risk of someone using this for something that needs actual cryptographic randomness.

ACKs for top commit:
  robot-dreams:
    ACK 77a19750b4
  real-or-random:
    utACK 77a19750b4

Tree-SHA512: 2706f37689e037e84b5df25c98af924c0756e6d59f5f822b23aec5ba381b2d536e0848f134026e2568396427218f1c770f1bb07613d702efb23a84015dc9271d
2021-12-25 19:21:21 +01:00
Tim Ruffing
423b6d19d3 Merge bitcoin-core/secp256k1#964: Add release-process.md
3ed0d02bf7 doc: add CHANGELOG template (Jonas Nick)
6f42dc16c8 doc: add release_process.md (Jonas Nick)
0bd3e4243c build: set library version to 0.0.0 explicitly (Jonas Nick)
b4b02fd8c4 build: change libsecp version from 0.1 to 0.1.0-pre (Jonas Nick)

Pull request description:

  This is an attempt at a simple release process. Fixes #856. To keep it simple, there is no concept of release candidates for now.

  The release version is determined by semantic versioning of the API. Since it does not seem to be a lot of work, it is proper to also version the ABI with the libtool versioning system. This versioning scheme (semver API, libtool versioning ABI) follows the suggestion in the [autotools mythbusters](https://autotools.io/libtool/version.html).

  Experimental modules are a bit of a headache, as expected. This release process suggests to treat any change in experimental modules as backwards compatible. That way, users of stable modules are not bothered by frequent non-backwards compatible releases. But a downside is that one must not use experimental modules in shared libraries (which should be mentioned in the README?). It would be nice if we could make the schnorrsig module stable in the not too distant future (see also #817).

ACKs for top commit:
  apoelstra:
    utACK 3ed0d02bf7
  elichai:
    ACK 3ed0d02bf7
  sipa:
    ACK 3ed0d02bf7
  real-or-random:
    ACK 3ed0d02bf7

Tree-SHA512: 25a04335a9579e16de48d378b93a9c6a248529f67f7c436680fa2d495192132743ce016c547aa9718cdcc7fe932de31dd7594f49052e8bd85572a84264f2dbee
2021-12-25 01:03:03 +01:00
Tim Ruffing
9281c9f4e1 Merge bitcoin-core/secp256k1#1053: ecmult: move _ecmult_odd_multiples_table_globalz_windowa
05e049b73c ecmult: move `_ecmult_odd_multiples_table_globalz_windowa` (siv2r)

Pull request description:

  Fixes #1035

  **Changes:**
      - move `secp256k1_ecmult_odd_multiples_table_globalz_windowa` function from ecmult to ecmult_const
      - remove outdated comment

ACKs for top commit:
  robot-dreams:
    utACK 05e049b73c (`diff` between removed and added lines is exactly as expected)
  real-or-random:
    utACK 05e049b73c

Tree-SHA512: 3fad4e93c641b642e84f4bbafcb8083d3e63b0523009fe0edcb2c1ebe1571d822320451289c651403ed1dc033ec6a7a3e8c3c56ad93d81bb1590cf9ff15a3b34
2021-12-25 00:11:19 +01:00
Pieter Wuille
77a19750b4 Use xoshiro256++ PRNG instead of RFC6979 in tests 2021-12-24 11:19:29 -05:00
Pieter Wuille
5f2efe684e secp256k1_testrand_int(2**N) -> secp256k1_testrand_bits(N) 2021-12-24 10:56:16 -05:00
siv2r
05e049b73c ecmult: move _ecmult_odd_multiples_table_globalz_windowa
Changes:
    - move `secp256k1_ecmult_odd_multiples_table_globalz_windowa` function from ecmult to ecmult_const
    - remove outdated comment
2021-12-24 16:22:49 +05:30
Tim Ruffing
3d7cbafb5f tests: Fix test whose result is implementation-defined
A compiler may add struct padding and fe_cmov is not guaranteed to
preserve it.

On the way, we improve the identity check such that it covers the
VERIFY struct members.
2021-12-23 20:18:36 +01:00
Jonas Nick
3ed0d02bf7 doc: add CHANGELOG template 2021-12-23 14:47:15 +00:00
Jonas Nick
6f42dc16c8 doc: add release_process.md 2021-12-23 14:47:15 +00:00
Jonas Nick
0bd3e4243c build: set library version to 0.0.0 explicitly 2021-12-23 14:47:14 +00:00
Jonas Nick
b4b02fd8c4 build: change libsecp version from 0.1 to 0.1.0-pre 2021-12-23 14:46:19 +00:00
Jonas Nick
09971a3ffd Merge bitcoin-core/secp256k1#1047: ci: Various improvements
b4ac1a1d5f ci: Run valgrind/memcheck tasks with 2 CPUs (Tim Ruffing)
e70acab601 ci: Use Cirrus "greedy" flag to use idle CPU time when available (Tim Ruffing)
d07e30176e ci: Update brew on macOS (Tim Ruffing)
22382f0ea0 ci: Test different ecmult window sizes (Tim Ruffing)
26a022a3a0 ci: Remove STATICPRECOMPUTATION (Tim Ruffing)
10461d8bd3 precompute_ecmult: Always compute all tables up to default WINDOW_G (Tim Ruffing)

Pull request description:

ACKs for top commit:
  elichai:
    utACK b4ac1a1d5f
  jonasnick:
    ACK b4ac1a1d5f

Tree-SHA512: b283d7b1c72cf87484de1fe98318298698fe9982dc33389eaca62e92318ab0074c183b9799add274f46358032491fee875e5ffb2a76a47f3b07520b850f4c85e
2021-12-22 18:15:42 +00:00
Tim Ruffing
0b83b203e1 Merge bitcoin-core/secp256k1#1030: doc: Fix upper bounds + cleanup in field_5x52_impl.h comment
1287786c7a doc: Add comment to top of field_10x26_impl.h (Elliott Jin)
58da5bd589 doc: Fix upper bounds + cleanup in field_5x52_impl.h comment (Elliott Jin)

Pull request description:

  When reviewing #816 I noticed the upper bounds in the comment at the top of `field_5x52_impl.h` were off by 1 (see `fe_verify`). This PR fixes the upper bounds and also cleans up the comment along the way.

ACKs for top commit:
  real-or-random:
    ACK 1287786c7a

Tree-SHA512: 4b7dadc92451ab1ceb5a547a3101ff37f3ffd0645490563f1f3442ea8d6219f100ed914289d22435c4172d190fa1ff52e37e4464132bb3f9bbcc338488227f7b
2021-12-22 18:53:26 +01:00
Elliott Jin
1287786c7a doc: Add comment to top of field_10x26_impl.h 2021-12-22 07:32:41 -08:00
Elliott Jin
58da5bd589 doc: Fix upper bounds + cleanup in field_5x52_impl.h comment 2021-12-22 07:32:41 -08:00
Jonas Nick
b39d431aed Merge bitcoin-core/secp256k1#1044: Add another ecmult_multi test
22d25c8e0a Add another ecmult_multi test (Pieter Wuille)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 22d25c8e0a

Tree-SHA512: e1394fa1708e65a66d4b324cca60dd49c67e37b23b7da2a3ff0db7a2a25c23976cb03b96a8c8584ee81aaec559feb84fb113dff2e2ebf89110ed466a4a6b158b
2021-12-22 14:18:55 +00:00
Tim Ruffing
b4ac1a1d5f ci: Run valgrind/memcheck tasks with 2 CPUs
... and increase the memory only for UBSan, ASan, LSan builds. Those are
the ones who need more memory.
2021-12-22 14:57:16 +01:00
Tim Ruffing
e70acab601 ci: Use Cirrus "greedy" flag to use idle CPU time when available 2021-12-22 14:57:16 +01:00
Tim Ruffing
d07e30176e ci: Update brew on macOS
The preinstalled brew is very old and tries to download prebuilt bottles
from a server which is no longer available. Because that will fail, brew
falls back to building our dependencies (e.g., autotools) from source,
which takes very long.

This commit makes sure that brew is updated before we start the build.

We also need to remove the `--shallow` argument from `brew tap`. It
doesn't exist in recent brew versions.
2021-12-22 14:56:49 +01:00
Tim Ruffing
22382f0ea0 ci: Test different ecmult window sizes 2021-12-22 14:56:27 +01:00
Tim Ruffing
a69df3ad24 Merge bitcoin-core/secp256k1#816: Improve checks at top of _fe_negate methods
515e7953ca Improve checks at top of _fe_negate methods (Peter Dettman)

Pull request description:

  In theory we could have a single static assertion that would ensure all of these are always true (for any magnitude up to the limit), but I think this small redundancy is clearer.

ACKs for top commit:
  sipa:
    utACK 515e7953ca
  real-or-random:
    ACK 515e7953ca bounds hold by inspection and by robot-dreams's script

Tree-SHA512: c33e47e186b37ca0b4e8d23712f8e5ab0c113024a0229fc6ce63b8cbad21bddbecc0c50029721a1fb3376b2d1da678c1ddb69c5ae971d84ddb7993c755867da4
2021-12-22 11:44:24 +01:00
Pieter Wuille
22d25c8e0a Add another ecmult_multi test 2021-12-21 16:42:08 -05:00
Peter Dettman
515e7953ca Improve checks at top of _fe_negate methods 2021-12-21 19:54:34 +07:00
Tim Ruffing
b2206619e6 Merge ElementsProject/secp256k1-zkp#131: Replace MuSig(1) module with MuSig2
ac1e36769d musig: turn off multiexponentiation for now (Jonas Nick)
3c79d97bd9 ci: increase timeout for macOS tasks (Jonas Nick)
22c88815c7 musig: replace MuSig(1) with MuSig2 (Jonas Nick)

Pull request description:

  The main commit comprises `905 insertions(+), 1253 deletions(-)`. The diff isn't as small as I had hoped, but that's mostly because it was possible to simplify the API quite substantially which required rewriting large parts. Sorry, almost all of the changes are in one big commit which makes the diff very hard to read. Perhaps best to re-review most parts from scratch.

  A few key changes:

  - Obviously no commitment round. No big session struct and no `verifier` sessions. No `signer` struct.
  - There's a new `secnonce` struct that is the output of musig_nonce_gen and derived from a uniformly random session_id32. The derivation can be strengthened by adding whatever session parameters (combined_pk, msg) are available. The nonce function is my ad-hoc construction that allows for these optional inputs. Please have a look at that.
  - The secnonce is made invalid after being used in partial_sign.
  - Adaptor signatures basically work as before, according to https://github.com/ElementsProject/scriptless-scripts/pull/24 (with the exception that they operate on aggregate instead of partial sigs)
  - To avoid making this PR overly complex I did not consider how this implementation interacts with nested-MuSig, sign-to-contract, and antiklepto.
  - Testing should be close to complete. There's no reachable line or branch that isn't exercised by the tests.
  - [x] ~In the current implementation when a signer sends an invalid nonce (i.e. some garbage that can't be mapped to a group element), it is ignored when combining nonces. Only after receiving the signers partial signature and running `partial_sig_verify` will we notice that the signer misbehaved. The reason for this is that 1) this makes the API simpler and 2) malicious peers don't gain any additional powers because they can always interrupt the protocol by refusing to sign. However, this is up for discussion.~ EDIT: this is not the case anymore since invalid nonces are rejected when they're parsed.
  - [x] ~For every partial signature we verify we have to parse the pubnonce (two compressed points), despite having parsed it in `process_nonces` already. This is not great. `process_nonces` could optionally output the array of parsed pubnonces.~ EDIT: fixed by having a dedicated type for nonces.
  - [x] ~I left `src/modules/musig/musig.md` unchanged for now. Perhaps we should merge it with the `musig-spec`~ EDIT: musig.md is updated
  - [x] partial verification should use multiexp to compute `R1 + b*R2 + c*P`, but this can be done in a separate PR
  - [x] renaming wishlist
      - pre_session -> keyagg_cache (because there is no session anymore)
      - pubkey_combine, nonce_combine, partial_sig_combine -> pubkey_agg, nonce_agg, partial_sig_agg (shorter, matches terminology in musig2)
      - musig_session_init -> musig_start (shorter, simpler) or [musig_generate_nonce](https://github.com/ElementsProject/secp256k1-zkp/pull/131#discussion_r654190890) or musig_prepare
      - musig_partial_signature to musig_partial_sig (shorter)
  - [x] perhaps remove pubnonces and n_pubnonces argument from process_nonces (and then also add a opaque type for the combined nonce?)
  - [x] write the `combined_pubkey` into the `pre_session` struct (as suggested [below](https://github.com/ElementsProject/secp256k1-zkp/pull/131#issuecomment-866904975): then 1) session_init and process_nonces don't need a combined_pk argument (and there can't be mix up between tweaked and untweaked keys) and 2) pubkey_tweak doesn't need an input_pubkey and the output_pubkey can be written directly into the pre_session (reducing frustration such as Replace MuSig(1) module with MuSig2 #131 (comment))
  - [x] perhaps allow adapting both partial sigs (`partial_sig` struct) and aggregate partial sigs (64 raw bytes) as suggested [below](https://github.com/ElementsProject/secp256k1-zkp/pull/131#issuecomment-867281531).

  Based on #120.

ACKs for top commit:
  robot-dreams:
    ACK ac1e36769d
  real-or-random:
    ACK ac1e36769d

Tree-SHA512: 916b42811aa5c00649cfb923d2002422c338106a6936a01253ba693015a242f21f7f7b4cce60d5ab5764a129926c6fd6676977c69c9e6e0aedc51b308ac6578d
2021-12-20 15:14:44 +01:00
Tim Ruffing
26a022a3a0 ci: Remove STATICPRECOMPUTATION
This has been overlooked in #988.
2021-12-20 14:18:02 +01:00
Tim Ruffing
10461d8bd3 precompute_ecmult: Always compute all tables up to default WINDOW_G
Also simplify #ifdefs in generated file.
2021-12-20 14:18:02 +01:00
Tim Ruffing
be6944ade9 Merge bitcoin-core/secp256k1#1042: Follow-ups to making all tables fully static
e05da9e480 Fix c++ build (Pieter Wuille)
c45386d994 Cleanup preprocessor indentation in precompute{,d}_ecmult{,_gen} (Pieter Wuille)
19d96e15f9 Split off .c file from precomputed_ecmult.h (Pieter Wuille)
1a6691adae Split off .c file from precomputed_ecmult_gen.h (Pieter Wuille)
bb36331412 Simplify precompute_ecmult_print_* (Pieter Wuille)
38cd84a0cb Compute ecmult tables at runtime for tests_exhaustive (Pieter Wuille)
e458ec26d6 Move ecmult table computation code to separate file (Pieter Wuille)
fc1bf9f15f Split ecmult table computation and printing (Pieter Wuille)
31feab053b Rename function secp256k1_ecmult_gen_{create_prec -> compute}_table (Pieter Wuille)
725370c3f2 Rename ecmult_gen_prec -> ecmult_gen_compute_table (Pieter Wuille)
075252c1b7 Rename ecmult_static_pre_g -> precomputed_ecmult (Pieter Wuille)
7cf47f72bc Rename ecmult_gen_static_prec_table -> precomputed_ecmult_gen (Pieter Wuille)
f95b8106d0 Rename gen_ecmult_static_pre_g -> precompute_ecmult (Pieter Wuille)
bae77685eb Rename gen_ecmult_gen_static_prec_table -> precompute_ecmult_gen (Pieter Wuille)

Pull request description:

  This PR implements a number of changes to follow up after merging #988:

  * Naming consistency:
    * All precomputed table files now have name `precomputed_*.*`
    * All source files related to the creation of the precomputed table files have name `precompute_*.*`.
    * All source files related to the computation of tables (whether they go in precomputed files or not) have name `*_compute_table.*`.
  * Make the tables for exhaustive tests be computed at runtime rather than compile time (this was already the case for ecmult_gen, but not ecmult). This is a preparation for the next point, as the alternative would be to have separate precomputed libraries for the exhaustive tests and other binaries.
  * Moves the actual tables to separate `precomputed_*.c` files, which are compiled only once as part of a new `libsecp256k1_precomputed.la`, included where relevant. The corresponding `precomputed_*.h` file are normal source files.

  Retry of #1041.

ACKs for top commit:
  real-or-random:
    ACK e05da9e480
  jonasnick:
    ACK e05da9e480

Tree-SHA512: 71eadd66e30e511b786e910755e0eda53330dfa163b37e33602c3392f7b893569f56d3ca9870e85cbb3de83880fc5aef61ac3d55d759d7395086a69023f13f03
2021-12-20 11:43:51 +01:00
Pieter Wuille
e05da9e480 Fix c++ build 2021-12-18 16:12:34 -05:00
Pieter Wuille
c45386d994 Cleanup preprocessor indentation in precompute{,d}_ecmult{,_gen} 2021-12-18 16:12:34 -05:00
Pieter Wuille
19d96e15f9 Split off .c file from precomputed_ecmult.h 2021-12-18 16:12:34 -05:00
Pieter Wuille
1a6691adae Split off .c file from precomputed_ecmult_gen.h 2021-12-18 16:12:34 -05:00
Pieter Wuille
bb36331412 Simplify precompute_ecmult_print_* 2021-12-18 16:12:34 -05:00
Pieter Wuille
38cd84a0cb Compute ecmult tables at runtime for tests_exhaustive 2021-12-18 16:12:33 -05:00
Pieter Wuille
e458ec26d6 Move ecmult table computation code to separate file 2021-12-18 16:11:56 -05:00
Pieter Wuille
fc1bf9f15f Split ecmult table computation and printing 2021-12-18 16:11:56 -05:00
Pieter Wuille
31feab053b Rename function secp256k1_ecmult_gen_{create_prec -> compute}_table 2021-12-18 16:11:52 -05:00
Pieter Wuille
725370c3f2 Rename ecmult_gen_prec -> ecmult_gen_compute_table 2021-12-17 14:43:45 -05:00
Pieter Wuille
075252c1b7 Rename ecmult_static_pre_g -> precomputed_ecmult 2021-12-17 11:29:17 -05:00
Pieter Wuille
7cf47f72bc Rename ecmult_gen_static_prec_table -> precomputed_ecmult_gen 2021-12-17 11:24:18 -05:00
Pieter Wuille
f95b8106d0 Rename gen_ecmult_static_pre_g -> precompute_ecmult 2021-12-17 11:19:45 -05:00
Pieter Wuille
bae77685eb Rename gen_ecmult_gen_static_prec_table -> precompute_ecmult_gen 2021-12-17 11:15:37 -05:00
Jonas Nick
ac1e36769d musig: turn off multiexponentiation for now
Before turning it on we need to have a discussion about our confidence in the
correctness of the multiexponentiation code.
2021-12-17 13:47:43 +00:00
Jonas Nick
3c79d97bd9 ci: increase timeout for macOS tasks 2021-12-17 13:47:43 +00:00
Jonas Nick
22c88815c7 musig: replace MuSig(1) with MuSig2 2021-12-17 13:47:23 +00:00
Tim Ruffing
0559fc6e41 Merge bitcoin-core/secp256k1#988: Make signing table fully static
7dfceceea6 build: Remove #undef hack for ASM in the precomputation programs (Tim Ruffing)
bb36fe9be0 ci: Test `make precomp` (Tim Ruffing)
d94a37a20c build: Remove CC_FOR_BUILD stuff (Tim Ruffing)
ad63bb4c29 build: Prebuild and distribute ecmult_gen table (Tim Ruffing)
ac49361ed0 prealloc: Get rid of manual memory management for prealloc contexts (Tim Ruffing)
6573c08f65 ecmult_gen: Tidy precomputed file and save space (Tim Ruffing)
5eba83f17c ecmult_gen: Precompute tables for all values of ECMULT_GEN_PREC_BITS (Tim Ruffing)
fdb33dd122 refactor: Make PREC_BITS a parameter of ecmult_gen_build_prec_table (Tim Ruffing)
a4875e30a6 refactor: Move default callbacks to util.h (Tim Ruffing)
4c94c55bce doc: Remove obsolete hint for valgrind stack size (Tim Ruffing)
5106226991 exhaustive_tests: Fix with ecmult_gen table with custom generator (Tim Ruffing)
e1a76530db refactor: Make generator a parameter of ecmult_gen_create_prec_table (Tim Ruffing)
9ad09f6911 refactor: Rename program that generates static ecmult_gen table (Tim Ruffing)
8ae18f1ab3 refactor: Rename file that contains static ecmult_gen table (Tim Ruffing)
00d2fa116e ecmult_gen: Make code consistent with comment (Tim Ruffing)
3b0c2185ea ecmult_gen: Simplify ecmult_gen context after making table static (Tim Ruffing)
e43ba02cfc refactor: Decouple table generation and ecmult_gen context (Tim Ruffing)
22dc2c0a0d ecmult_gen: Move table creation to new file and force static prec (Tim Ruffing)

Pull request description:

  This resolves #893,  resolves #692 (and also resolves bitcoin/bitcoin#22854).

  - [x] Extract table generation to separate function in separate file (to be used by generation script and exhaustive tests)
  - [x] Tidy up
    - [x] Remove code that deals with non-static tables
    - [x] Make functions that need ecmult_gen not depend on signing context
    - [x] Rename stuff to make it fit the new structure and consistent with how we hande verification tables (#956)
  - [x] Fix exhaustive tests
    - [x] Make table generation function take generator as input
    - [x] Overwrite the static tables with a table with custom generator in exhaustive tests
  - [x] Overhaul script that generates table files
    - [x] Make table generation function take PREC_BITS as input (I have some code already, just not yet in this branch)
    - [x] Change generation script to generate three tables (for all three values of ECMULT_GEN_PREC_BITS)
  - [x] Ship pre-built tables
    - [x] Add pregenerated table file to repo
    - [x] Remove generation of table file from build process (like in #956)
    - [x] Remove left-over stuff (e.g., detecting a compiler running on the build machine) from build system
  - [x] Final cleanups (copyright headers, commit, messages, etc.)
  - [ ] (separate PR:) Make sure link-time optimization remove corresponding static tables (and code) when no signing/verifcation function is called
  - [ ] (separate PR:) Compile precomputation as a separate object file and link it (https://github.com/bitcoin-core/secp256k1/pull/988#issuecomment-977813538)
  - [ ] (separate PR:) Document the backwards-compatible API changes made in this PR and in #956.
    - [ ] Maybe deprecate the static context

ACKs for top commit:
  sipa:
    ACK 7dfceceea6
  robot-dreams:
    ACK 7dfceceea6 (based on range-diff between 56284c7d44c0ed46e636588bfbf6c403b7dfa6c1 and 7dfceceea6)

Tree-SHA512: 6efb3f36f05efe3b79bbd877881fe1409f71fd6488d24c811b2e77d9f053bed78670dd1dcbb42ad780458a51c4ffa36de9cd6567271b22041dc7a122ceb677c5
2021-12-15 11:06:47 +01:00
Tim Ruffing
7dfceceea6 build: Remove #undef hack for ASM in the precomputation programs
This was necessary because we used to cross-compile the library but
compile the precomputation programs for the build host. Now it's no
longer necessary and we can cleanly link even the external ASM
(which was the intent of #935).

On the way, remove an obsolete "-I" parameter.
2021-12-09 20:52:56 +01:00
Tim Ruffing
bb36fe9be0 ci: Test make precomp 2021-12-09 20:52:28 +01:00
Tim Ruffing
d94a37a20c build: Remove CC_FOR_BUILD stuff 2021-12-09 20:52:28 +01:00
Tim Ruffing
ad63bb4c29 build: Prebuild and distribute ecmult_gen table
- Improve Makefile.am for both prebuilt tables files
 - On the way, tidy EXTRA_DIST: Move the header files to noinst_HEADERS,
   where they conceptually belong, and add missing SECURITY.md to EXTRA_DIST
2021-12-09 20:52:28 +01:00
Tim Ruffing
ac49361ed0 prealloc: Get rid of manual memory management for prealloc contexts 2021-12-09 20:52:28 +01:00
Tim Ruffing
6573c08f65 ecmult_gen: Tidy precomputed file and save space 2021-12-09 20:52:26 +01:00
Tim Ruffing
5eba83f17c ecmult_gen: Precompute tables for all values of ECMULT_GEN_PREC_BITS 2021-12-09 20:51:59 +01:00
Tim Ruffing
5d0dbef018 Merge bitcoin-core/secp256k1#942: Verify that secp256k1_ge_set_gej_zinv does not operate on infinity.
099bad945e Comment and check a parameter for inf in secp256k1_ecmult_const. (Russell O'Connor)
6c0be857f8 Verify that secp256k1_ge_set_gej_zinv does not operate on infinity. a->x and a->y should not be used if the infinity flag is set. (Russell O'Connor)

Pull request description:

  a->x and a->y should not be used if the infinity flag is set.

ACKs for top commit:
  robot-dreams:
    ACK 099bad945e
  real-or-random:
    ACK 099bad945e I inspected all call sites, they all ensure that a is not infinity

Tree-SHA512: 495fcfe4ec4cacb3fc64bd5d04ecc67ab34f6b63666c6169d473abfd63c2041bc501a9a60d817566517435b986406ea2b7db3f5806043cecf30e214eba9892e9
2021-12-07 11:26:10 +01:00
Tim Ruffing
486205aa68 Merge bitcoin-core/secp256k1#920: Test all ecmult functions with many j*2^i combinations
5eb519e1f6 ci: reduce TEST_ITERS in memcheck run (Pieter Wuille)
e2cf77328a Test ecmult functions for all i*2^j for j=0..255 and odd i=1..255. (Pieter Wuille)

Pull request description:

  Instead of just testing properties of the points xG for x=-36..36:
  * also compute all xG where x=j*2^i for i=0..255 and odd j=1..255.
  * test them against known exact results (SHA256 all of them, and compared against an independently created result)
  * test all 4 ecmult functions (and for secp256k1_ecmult and secp256k1_ecmult_multi_var, both as G, and through the generic point input)

ACKs for top commit:
  real-or-random:
    ACK 5eb519e1f6
  jonasnick:
    ACK 5eb519e1f6

Tree-SHA512: 5d3fcbff754e859ba27d4f4581fa91fafb450fa3f7880364667dba51287e7f02f489af19b9de6a6e0f52faa183c0c7ae46db6add05180c3d4f45a6557b00c0ed
2021-12-06 17:57:14 +01:00
Tim Ruffing
fdb33dd122 refactor: Make PREC_BITS a parameter of ecmult_gen_build_prec_table 2021-12-05 17:58:26 +01:00
Pieter Wuille
5eb519e1f6 ci: reduce TEST_ITERS in memcheck run 2021-12-05 11:54:05 -05:00
Pieter Wuille
e2cf77328a Test ecmult functions for all i*2^j for j=0..255 and odd i=1..255. 2021-12-05 11:53:47 -05:00
Tim Ruffing
61ae37c612 Merge bitcoin-core/secp256k1#1022: build: Windows DLL additions
c0cd7de6d4 build: add -no-undefined to libtool LDFLAGS (fanquake)
fe32a79d35 build: pass win32-dll to LT_INIT (fanquake)

Pull request description:

  This takes care of two of the outstanding issues in #923. One being initializing libtool with `win32-dll` and the other being the addition of `-no-undefined` to the libtool LDFLAGS. See each commit for more details.

  Builders cross-compiling for Windows (including Core) will no-longer see:
  ```bash
  libtool: warning: undefined symbols not allowed in x86_64-w64-mingw32 shared libraries; building static only
  ```

  I'm planning on making some related changes downstream.

ACKs for top commit:
  sipa:
    utACK c0cd7de6d4. We indeed have done the work to propertly mark exported symbols, and AFAIK have no imported symbols apart from standard library ones.
  real-or-random:
    ACK c0cd7de6d4
  hebasto:
    ACK c0cd7de6d4

Tree-SHA512: 6756bc88ac439a27117a1341d82a801cef70354a9e7a563592ab3ac7298fbefdaa0a2c410ea3fba8953d53f254c449dc491069f30468db12791027a65dd02f80
2021-12-05 12:19:35 +01:00
Tim Ruffing
4f01840b82 Merge bitcoin-core/secp256k1#1027: build: Add a check that Valgrind actually supports a host platform
7c7ce872a5 build: Add a check that Valgrind actually supports a host platform (Hennadii Stepanov)

Pull request description:

  This PR adds a check that Valgrind actually supports a host platform.

  On master (49f608de47):
  ```
  $ ./autogen.sh &> /dev/null && ./configure -q --host=riscv64-linux-gnu 2>&1 | grep valgrind
    valgrind                = yes
  ```

  With this PR:
  ```
  $ ./autogen.sh &> /dev/null && ./configure -q --host=riscv64-linux-gnu 2>&1 | grep valgrind
    valgrind                = no
  ```

  Closes #1023.

ACKs for top commit:
  sipa:
    utACK 7c7ce872a5
  real-or-random:
    utACK 7c7ce872a5

Tree-SHA512: 27f660f7b992ab35dba64b525af1c631f33b8cb25b6a990c81ec4d358c609a2dc03b0932847db9d5aa35eaa880929c7ad2bb4e7719785c2402b1b291cfa91ede
2021-12-05 11:48:02 +01:00
Tim Ruffing
6ad908aa00 Merge bitcoin-core/secp256k1#1008: bench.c: add --help option and ci: move env variables
592661c22f ci: move test environment variable declaration to .cirrus.yml (siv2r)
dcbe84b841 bench: add --help option to bench. (siv2r)

Pull request description:

  Fixes #1005

  **Changes:**
  - added `--help` option to `bench.c`
      - `help()` function prints the help to command-line
      - `have_invalid_args()` checks if the user has entered an invalid argument
  - moved `secp256k1_bench_iters` and `secp256k1_test_iters` environment variables declaration to `.cirrus.yml`

ACKs for top commit:
  sipa:
    utACK 592661c22f
  real-or-random:
    ACK 592661c22f

Tree-SHA512: ebc6a2e6e47b529212efa1c9b75cc79649fca7f42aa75ce46502db24ac94f46b6cef59c828d13265d1fa69187a81c140d1951e7daeb7c8e008a6c1ad75259741
2021-12-05 11:24:00 +01:00
siv2r
592661c22f ci: move test environment variable declaration to .cirrus.yml
environment var moved:
    1. SECP256K1_TEST_ITERS (replaces TEST_ITERS)
    2. SECP256K1_BENCH_ITERS (replaces BENCH_ITERS)
2021-12-04 22:47:40 +05:30
siv2r
dcbe84b841 bench: add --help option to bench.
The following functions were created:
    1. bench.c: help()
        - prints the help to the command-line
    2. bench.h: have_invalid_args()
        - takes a list of arguments that the user is allowed to enter on the command-line
        - returns 1 if the user entered an invalid argument
        - returns 0 if all the user entered arguments are valid
2021-12-04 22:47:30 +05:30
Russell O'Connor
099bad945e Comment and check a parameter for inf in secp256k1_ecmult_const. 2021-12-03 13:57:38 -05:00
Russell O'Connor
6c0be857f8 Verify that secp256k1_ge_set_gej_zinv does not operate on infinity.
a->x and a->y should not be used if the infinity flag is set.
2021-12-03 12:01:41 -05:00
Tim Ruffing
4900227451 Merge bitcoin-core/secp256k1#1025: build: replace backtick command substitution with $()
2b7c7497ef build: replace backtick command substitution with $() (fanquake)

Pull request description:

  This is only needed for the very oldest of non-POSIX-compatible shells.
  Note that this code will also only be executed on macOS, where it'd be
  very unlikely to run into such a shell anyways.

  Followup to https://github.com/bitcoin-core/secp256k1/pull/1019#pullrequestreview-815300521. I had thought there were more usages of this
  syntax, but seems like it's just the one.

  See:
  https://github.com/koalaman/shellcheck/wiki/SC2006

  Co-authored-by: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>

ACKs for top commit:
  real-or-random:
    ACK 2b7c7497ef
  hebasto:
    ACK 2b7c7497ef, verified that this is the only case.

Tree-SHA512: 6192f5efe437ff428ce7843ac595049a1aa7969a9e696f649cfd4820b28fc96ad0fabd6eec0ec1ca404763f02e64af6a99e57666a00d8749c6212a0646211991
2021-12-03 17:27:09 +01:00
Hennadii Stepanov
7c7ce872a5 build: Add a check that Valgrind actually supports a host platform 2021-12-03 17:32:26 +02:00
Tim Ruffing
a4875e30a6 refactor: Move default callbacks to util.h 2021-12-03 11:23:33 +01:00
Tim Ruffing
4c94c55bce doc: Remove obsolete hint for valgrind stack size
Also don't mention exhaustive_tests without explanation. They're
included in our test suite (`make check`) anyway.
2021-12-03 11:23:33 +01:00
Tim Ruffing
5106226991 exhaustive_tests: Fix with ecmult_gen table with custom generator 2021-12-03 11:23:33 +01:00
Tim Ruffing
e1a76530db refactor: Make generator a parameter of ecmult_gen_create_prec_table 2021-12-03 11:23:33 +01:00
Tim Ruffing
9ad09f6911 refactor: Rename program that generates static ecmult_gen table 2021-12-03 11:23:33 +01:00
Tim Ruffing
8ae18f1ab3 refactor: Rename file that contains static ecmult_gen table 2021-12-03 11:23:33 +01:00
Tim Ruffing
00d2fa116e ecmult_gen: Make code consistent with comment
This also fixes a typo in the comment.
2021-12-03 11:23:33 +01:00
Tim Ruffing
3b0c2185ea ecmult_gen: Simplify ecmult_gen context after making table static
This is a backwards-compatible API change: Before this commit, a context
initialized for signing was required to call functions that rely on
ecmult_gen. After this commit, this is no longer necessary because the
static ecmult_gen table is always present. In practice this means that
the corresponding functions will just work instead of calling the
illegal callback when given a context which is not (officially)
initialized for signing.

This is in line with 6815761, which made the analogous change with
respect to ecmult and contexts initialized for signing. But as opposed
to 681571, which removed the ecmult context entirely, we cannot remove
the ecmult_gen context entirely because it is still used for random
blinding. Moreover, since the secp256k1_context_no_precomp context is
const and cannot meaningfully support random blinding, we refrain (for
now) from changing its API, i.e., the illegal callback will still be
called when trying to use ecmult_gen operations with the static
secp256k1_context_no_precomp context.
2021-12-03 11:23:33 +01:00
fanquake
2b7c7497ef build: replace backtick command substitution with $()
This is only needed for the very oldest of non-POSIX-compatible shells.
Note that this code will also only be executed on macOS, where it'd be
very unlikely to run into such a shell.

Followup to #1019.

See:
https://github.com/koalaman/shellcheck/wiki/SC2006

Co-authored-by: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
2021-12-03 15:22:59 +08:00
Tim Ruffing
49f608de47 Merge bitcoin-core/secp256k1#1004: ecmult: fix definition of STRAUSS_SCRATCH_OBJECTS
60bf8890df ecmult: fix definition of STRAUSS_SCRATCH_OBJECTS (Jonas Nick)

Pull request description:

  This bug was introduced in 7506e064d7 by adding
  an allocation but not updating the constant.

ACKs for top commit:
  robot-dreams:
    ACK 60bf8890df
  real-or-random:
    ACK 60bf8890df

Tree-SHA512: d7782fe9bf09fea8cf22304ab13679223a48f4d8b09081e662ea162a68c4e35f6b5820fbe4c6030fabad02a48dfdd02eb9eef22262c1dbbf02955bb92b75aef8
2021-12-02 21:26:49 +01:00
fanquake
c0cd7de6d4 build: add -no-undefined to libtool LDFLAGS
Instruct libtool to not allow undefined symbols when linking a shared
library.

See:
https://autotools.io/libtool/windows.html
https://www.gnu.org/software/libtool/manual/libtool.html#LT_005fINIT
https://www.gnu.org/software/gnulib/manual/html_node/Libtool-and-Windows.html
2021-12-02 11:48:43 +08:00
fanquake
fe32a79d35 build: pass win32-dll to LT_INIT
This is the recommended way to support building PE DLLs with modern
mingw toolchains and libtool.

> This option should be used if the package has been ported to build clean
> dlls on win32 platforms.
> If this macro is not used, libtool will assume that the package libraries
> are not dll clean and will build only static libraries on win32 hosts.

See:
https://www.gnu.org/software/libtool/manual/libtool.html#LT_005fINIT
https://www.gnu.org/software/gnulib/manual/html_node/Libtool-and-Windows.html
https://autotools.io/libtool/windows.html
2021-12-02 11:44:13 +08:00
Jonas Nick
60bf8890df ecmult: fix definition of STRAUSS_SCRATCH_OBJECTS
This bug was introduced in 7506e064d7 by adding
an allocation but not updating the constant.
2021-11-30 19:25:40 +00:00
Tim Ruffing
fecf436d53 Merge bitcoin-core/secp256k1#1019: build: don't append valgrind CPPFLAGS if not installed (macOS)
214042a170 build: don't append valgrind CPPFLAGS if not installed (fanquake)

Pull request description:

  Valgrinds CPPFLAGS, i.e `-I/usr/local/opt/valgrind/include`, are currently added to CPPFLAGS, regardless of whether valgrind is installed. This changes configure so that they are only added if valgrind is available. i.e the output of `brew list --versions valgrind` is non-null.

ACKs for top commit:
  real-or-random:
    ACK 214042a170
  hebasto:
    ACK 214042a170, tested on macOS Big Sur 11.6.1 (20G224, Intel).

Tree-SHA512: 5101636a0a12f1941b01967ca8eab7aa20f44db0d1ef4571a5ad6026bb89494b983465d34d93c8b17a260b695116792991da53d135bc19a3c9e974f5266a90af
2021-11-24 21:16:00 +01:00
Tim Ruffing
2e5e4b67df Merge bitcoin-core/secp256k1#1020: doc: remove use of <0xa0> "no break space"
812ff5c747 doc: remove use of 0xa0 "no break space" (fanquake)

Pull request description:

  This is miscellaneous, but I don't think these were being used on purpose?

ACKs for top commit:
  siv2r:
    ACK 812ff5c. The non-breaking space character is replaced with whitespace. Tested with [NBSP highlighter extension](https://marketplace.visualstudio.com/items?itemName=viktorzetterstrom.non-breaking-space-highlighter) on vscode.
  real-or-random:
    ACK 812ff5c747

Tree-SHA512: ccfcc64798f5a5eb0c669eb00f4408ab713e6710d67fd15ee2a4dca0d052e27636d7f0ad312aa94be0cd068c7e7874441aa2e114c4118322d0c764398a4ff695
2021-11-24 14:42:02 +01:00
fanquake
812ff5c747 doc: remove use of 0xa0 "no break space" 2021-11-24 08:11:49 +08:00
fanquake
214042a170 build: don't append valgrind CPPFLAGS if not installed 2021-11-23 11:24:12 +08:00
Tim Ruffing
e43ba02cfc refactor: Decouple table generation and ecmult_gen context 2021-11-19 14:03:44 +01:00
Tim Ruffing
22dc2c0a0d ecmult_gen: Move table creation to new file and force static prec 2021-11-19 13:47:05 +01:00
Tim Ruffing
793ad9016a Merge bitcoin-core/secp256k1#1010: doc: Minor fixes in safegcd_implementation.md
dc9b6853b7 doc: Minor fixes in safegcd_implementation.md (Elliott Jin)

Pull request description:

ACKs for top commit:
  sipa:
    ACK dc9b6853b7
  real-or-random:
    ACK dc9b6853b7

Tree-SHA512: 990c969806b9abf42e5554093aa573911bbdf28a68c26f60e03e2a754506b1c714f784c673d862b973c5d0a38576605b14aff9d4bd3df176d535ca8ebfe4c0bd
2021-11-17 02:12:59 +01:00
Elliott Jin
dc9b6853b7 doc: Minor fixes in safegcd_implementation.md 2021-11-15 21:16:00 -06:00
Tim Ruffing
ea5e8a9c47 Merge bitcoin-core/secp256k1#1012: Fix typos
233297579d Fix typos (Dimitris Apostolou)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 233297579d

Tree-SHA512: c8b091d26ceb15518cc668e05ac56e205668e10c63ecc38c9b9b3edf01f4767e66891856bb931b16f32e34521913ebb3d06b57804063210e12a7aab9447249ca
2021-11-13 10:11:08 +01:00
Dimitris Apostolou
233297579d Fix typos 2021-11-13 02:12:47 +02:00
Jonas Nick
7006f1b97f Merge bitcoin-core/secp256k1#1011: ci: Enable -g if we set CFLAGS manually
72de1359e9 ci: Enable -g if we set CFLAGS manually (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 72de1359e9

Tree-SHA512: 0456db0ba53410640653e5d11ee4f328be0657e1e9077aa982ed4fd3eb6e326cfc022ec7ab71fc5c62d7942a20bbc7a5e8000cf5b62201fa1c183853d899ea77
2021-11-10 22:11:38 +00:00
Tim Ruffing
72de1359e9 ci: Enable -g if we set CFLAGS manually
This enables sanitizers to output line numbers in stack traces.
2021-11-10 15:17:26 +01:00
Tim Ruffing
74c34e727b Merge bitcoin-core/secp256k1#1009: refactor: Use (int)&(int) in boolean context to avoid compiler warning
16d132215c refactor: Use (int)&(int) in boolean context to avoid compiler warning (MarcoFalke)

Pull request description:

  This one should *really* be only a refactor with the goal to silence static analysis warnings. clang-14 (trunk) recently added one in commit f62d18ff14 and I expect other tools will offer similar warnings.

  Follow up to #1006, which was not a refactor.

ACKs for top commit:
  real-or-random:
    ACK 16d132215c
  jonasnick:
    ACK 16d132215c

Tree-SHA512: c465522ea4ddb58b5974c95bc36423c453e6fcf5948cb32114172113b5244209ceaa9418ec86ebe210390ae5509c2f24a42c41a7353de4cfb8fd063b0d5c0e79
2021-11-10 00:46:51 +01:00
MarcoFalke
16d132215c refactor: Use (int)&(int) in boolean context to avoid compiler warning
This fixes a compiler warning:

./src/ecdsa_impl.h:312:12: warning: use of bitwise '&' with boolean operands [-Wbitwise-instead-of-logical]
    return !secp256k1_scalar_is_zero(sigr) & !secp256k1_scalar_is_zero(sigs);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2021-11-09 11:34:48 +01:00
Tim Ruffing
c74a7b7e51 Merge bitcoin-core/secp256k1#1007: doc: Replace apoelstra's GPG key by jonasnick's GPG key
3b157c48ed doc: Suggest keys.openpgp.org as keyserver in SECURITY.md (Tim Ruffing)
73a7472cd0 doc: Replace apoelstra's GPG key by jonasnick's GPG key (Tim Ruffing)

Pull request description:

  I have verified the new key via other secure channels.

  This closes #1003 .

  We can skip the second commit but I expect https://github.com/bitcoin/bitcoin/pull/23466/ to be merged. If it won't be merged, we could still revert.

ACKs for top commit:
  sipa:
    ACK 3b157c48ed. I've also verified the key out of band.
  jonasnick:
    ACK 3b157c48ed

Tree-SHA512: 496f98121f14031bc693aa83bf208b253f79b700b4bca0b629deadc8852f76ef6d69ad90109baa771d7b9f6e4b983e4ed8dca404cf5aceffe9d520d3362b533a
2021-11-09 09:09:32 +01:00
Tim Ruffing
3b157c48ed doc: Suggest keys.openpgp.org as keyserver in SECURITY.md
This is in line with https://github.com/bitcoin/bitcoin/pull/23466/ .
2021-11-08 20:33:22 +01:00
Tim Ruffing
73a7472cd0 doc: Replace apoelstra's GPG key by jonasnick's GPG key
I have verified the new key via other secure channels.
2021-11-08 20:33:17 +01:00
Tim Ruffing
515a5dbd02 Merge bitcoin-core/secp256k1#991: Merge all "external" benchmarks into a single bench binary
af6abcb3d0 Make bench support selecting which benchmarks to run (Pieter Wuille)
9f56bdf5b9 Merge bench_schnorrsig into bench (Pieter Wuille)
3208557ae1 Merge bench_recover into bench (Pieter Wuille)
855e18d8a8 Merge bench_ecdh into bench (Pieter Wuille)
2a7be678a6 Combine bench_sign and bench_verify into single bench (Pieter Wuille)

Pull request description:

  This combines `bench_verify`, `bench_sign`, `bench_ecdh`, `bench_recovery`, and `bench_schnorrsig` into a single `bench` binary.

  I don't think there is a good reason to have this many binaries, and it complicates build config and CI.

ACKs for top commit:
  real-or-random:
    ACK af6abcb3d0 diff looks good, command line options work, valgrind is happy
  siv2r:
    tACK af6abcb, the command-line options work as expected on my ubuntu machine. The diff looks good.

Tree-SHA512: 39c099b508c70136eaac8a429591b4250a8c22e423fa922d83928ea9273d8f2c1136317427563b28f249c02cf83d1c73ea787c6d26aa88545236241641965705
2021-11-08 11:24:56 +01:00
Pieter Wuille
af6abcb3d0 Make bench support selecting which benchmarks to run 2021-11-05 17:48:18 -04:00
Pieter Wuille
9f56bdf5b9 Merge bench_schnorrsig into bench 2021-11-05 17:35:11 -04:00
Pieter Wuille
3208557ae1 Merge bench_recover into bench 2021-11-05 17:34:46 -04:00
Pieter Wuille
855e18d8a8 Merge bench_ecdh into bench 2021-11-05 17:34:25 -04:00
Pieter Wuille
2a7be678a6 Combine bench_sign and bench_verify into single bench 2021-11-05 17:30:56 -04:00
Tim Ruffing
8fa41201bd Merge bitcoin-core/secp256k1#1002: Make aux_rnd32==NULL behave identical to 0x0000..00.
5324f8942d Make aux_rnd32==NULL behave identical to 0x0000..00. (Pieter Wuille)

Pull request description:

  BIP340's default signing algorithm always requires an aux_rnd argument, but permits using an all-zero one when no randomness is available.

  Make secp256k1_schnorrsig_sign follow this even when aux_rnd32==NULL, by treating the same as if an all-zero byte array was provided as input.

ACKs for top commit:
  junderw:
    ACK 5324f89
  elichai:
    ACK 5324f8942d
  jonasnick:
    ACK 5324f8942d
  real-or-random:
    utACK 5324f8942d

Tree-SHA512: caa1d5a0eacea3239d8aaace5284eedcd850058bbe759768e626233a010199db6c637618aedccfb51fe94ec8d28f45bc0c441be77e2e12fa2a393b9cc3a5d3ae
2021-10-31 17:55:02 +01:00
Pieter Wuille
5324f8942d Make aux_rnd32==NULL behave identical to 0x0000..00.
BIP340's default signing algorithm always requires an aux_rnd argument,
but permits using an all-zero one when no randomness is available.

Make secp256k1_schnorrsig_sign follow this even when aux_rnd32==NULL,
by treating the same as if an all-zero byte array was provided as
input.
2021-10-30 13:03:55 -04:00
Tim Ruffing
21c188b3c5 Merge bitcoin-core/secp256k1#943: VERIFY_CHECK precondition for secp256k1_fe_set_int.
2888640132 VERIFY_CHECK precondition for secp256k1_fe_set_int. (Russell O'Connor)
d49011f54c Make _set_fe_int( . , 0 ) set magnitude to 0 (Tim Ruffing)

Pull request description:

  Also set the magnitude to 0 when setting the value to 0.

ACKs for top commit:
  real-or-random:
    ACK 2888640132
  jonasnick:
    ACK 2888640132

Tree-SHA512: 6ec9b3485380503b11c00f30bfa79f92ba3facb93ee4f3df582b881c4e19fb8ae8b5acd5aeb6326497c290cd0904230d0356f33bd136ca577d2f25616279e090
2021-10-28 17:19:40 +02:00
Tim Ruffing
3e7b2ea194 Merge bitcoin-core/secp256k1#999: bench_ecmult: improve clarity of output
23e2f66726 bench: don't return 1 in have_flag() if argc = 1 (Jonas Nick)
96b1ad2ea9 bench_ecmult: improve clarity of output (Jonas Nick)

Pull request description:

  Previously "ecmult{,_multi} xg" meant multiplication with (x - 1) random points
  and base point G. Now
  - xP means multiplication with x random points and
  - xP & G means multiplication with x random points and G

ACKs for top commit:
  siv2r:
    tACK 23e2f66
  real-or-random:
    ACK 23e2f66726

Tree-SHA512: 0218aaa0baa4c2f92a7b98c97b8cc3b596e3da44d7f38ab4bdd707a4bdb96bb071b953fc6106cd34977a562278e4eaa860a3a7fa64c323c5117945e7a3107162
2021-10-25 12:06:24 +02:00
Jonas Nick
23e2f66726 bench: don't return 1 in have_flag() if argc = 1
This makes the semantic of have_flag more clear and fixes a bug
that was introduced in

2fe1b50df1
Add ecmult_gen, ecmult_const and ecmult to benchmark

where the behavior introduced by this commit was already assumed. If
bench_ecmult was called without arguments, have_flag("simple") returned 1 and no
scratch space was allocated which led to very wrong output.
2021-10-24 19:43:20 +00:00
Jonas Nick
96b1ad2ea9 bench_ecmult: improve clarity of output
Previously "ecmult{,_multi} xg" meant multiplication with (x - 1) random points
and base point G. Now
- ecmult_{,multi_}xp means multiplication with x random points and
- ecmult_{,multi_}xp_g means multiplication with x random points and G
2021-10-24 18:47:24 +00:00
Jonas Nick
20d791edfb Merge bitcoin-core/secp256k1#989: Shared benchmark format for command line and CSV outputs
b4b130678d create csv file from the benchmark output (siv2r)
26a255beb6 Shared benchmark format for command line and CSV outputs (siv2r)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK b4b130678d
  jonasnick:
    ACK b4b130678d

Tree-SHA512: 1eebbdd7701ad21d9647434ff05f23827be217d47870bb05a2fdb12447abc365fc6e56306f344e05d8d2ec1ff5532562131b3876261733e4412117357c5c65f8
2021-10-22 12:30:36 +00:00
Tim Ruffing
aa1b889b61 Merge bitcoin-core/secp256k1#996: Fix G.y parity in sage code
044d956305 Fix G.y parity in sage code (Pieter Wuille)

Pull request description:

  I'm not sure if `EllipticCurve.lift_x` has well-defined Y coordinate or not, but at least my current version of Sage computes the wrong G. Fix this.

ACKs for top commit:
  real-or-random:
    ACK 044d956305

Tree-SHA512: afb919af29027da2bb3c58628924f9740672d3c347ad39cc663c9c399b1aa8536256fd3fd4e1e54457e38344704d47f281d82488da413f4e6e67e191decc960f
2021-10-20 16:40:55 +02:00
Pieter Wuille
044d956305 Fix G.y parity in sage code 2021-10-20 10:14:13 -04:00
siv2r
b4b130678d create csv file from the benchmark output 2021-10-19 21:30:23 +05:30
siv2r
26a255beb6 Shared benchmark format for command line and CSV outputs
1. add `print_output_table_header_row` func to print the table header for benchmark output
2. modify the following benchmarks to include the table header
    - bench_ecdh.c
    - bench_ecmult.c
    - bench_internal.c
    - bench_recover.c
    - bench_schnorrsig.c
    - bench_sign.c
    - bench_verify.c
2021-10-19 21:25:37 +05:30
Tim Ruffing
9526874d14 Merge bitcoin-core/secp256k1#810: Avoid overly-wide multiplications in 5x52 field mul/sqr
b53e0cd61f Avoid overly-wide multiplications (Peter Dettman)

Pull request description:

  Speeds up bench_ecdh, bench_sign, bench_verify relative to master by 5+% at -O3, haswell.

ACKs for top commit:
  sipa:
    ACK b53e0cd61f
  real-or-random:
    ACK b53e0cd61f I've inspected the diff and run the tests without asm for a CPU day

Tree-SHA512: 4f79c98371a3dc9da013632210c8db979f910b222291999dfaa0c31849a77eb427361e4ab9206cbfee73c30a8933178784d6cb8e747e8dca6b227eb77fbea2a2
2021-10-17 18:44:54 +02:00
Jonas Nick
6b8733577e Merge elementsproject/secp256k1-zkp#147: whitelist: fix SECP256K1_WHITELIST_MAX_N_KEYS constant
27d1c3b6a1 whitelist: add test for MAX_N_KEYS (Jonas Nick)
c8ac14d9dc whitelist: fix SECP256K1_WHITELIST_MAX_N_KEYS constant (Jonas Nick)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK 27d1c3b6a1

Tree-SHA512: 329099b134811462930866f572914075a3210d81fe15a21f48f26e17bc1a4650c31afdcad7a24af8dc4af093b96300386833d68604be05da89c3f7bc0aabf550
2021-10-17 15:29:49 +00:00
Tim Ruffing
e02f313b1f Add comment on length checks when parsing ECDSA sigs
I claim the check can be removed but I don't want to touch this
stable and well-tested code.

On the way, we fix grammar in another comment.
2021-10-17 12:02:10 +02:00
Tim Ruffing
920a0e5fa6 Merge bitcoin-core/secp256k1#952: Avoid computing out-of-bounds pointer.
9be7b0f083 Avoid computing out-of-bounds pointer. (Tim Ruffing)

Pull request description:

  This is a pedantic case of UB.

  Spotted in #879.

ACKs for top commit:
  elichai:
    ACK 9be7b0f083
  practicalswift:
    cr ACK 9be7b0f083
  sipa:
    ACK 9be7b0f083

Tree-SHA512: a9d028c4cdb37ad0d5fcf0d2f678eef732a653d37155a69a20272c6b283c28e083172485d7a37dc4a7c6100b22a6f5b6a92e729239031be228cc511842ee35e8
2021-10-17 11:55:31 +02:00
Tim Ruffing
f34b5cae03 Merge bitcoin-core/secp256k1#983: [RFC] Remove OpenSSL testing support
bc08599e77 Remove OpenSSL testing support (Pieter Wuille)

Pull request description:

  This removes the ability to test against OpenSSL, as well as the OpenSSL verification benchmark.

  The motivation is that OpenSSL 3 is deprecating part of the API used here (see #869), and I'm not sure it's worth maintaining. We do lose the fact that this is the only test that verifies randomly-generated cases against an independent implementation. On the other hand, there are tons of existing fixed tests now that test all kinds of edge cases already.

ACKs for top commit:
  elichai:
    tACK bc08599
  real-or-random:
    ACK bc08599e77
  jonasnick:
    ACK bc08599e77

Tree-SHA512: 632e6d3cf7bbc5828f5ca1f0f2a92c80bcb681bbcd4320c352b4a86fd521e410c852ccebcfc30fadc8fbf86649267a9e521f53e0f78072a8cd74d8726da28973
2021-10-17 00:36:32 +02:00
Jonas Nick
27d1c3b6a1 whitelist: add test for MAX_N_KEYS
Don't test all MAX_N_KEYS because it is quite slow.
2021-10-15 16:17:20 +00:00
Jonas Nick
c8ac14d9dc whitelist: fix SECP256K1_WHITELIST_MAX_N_KEYS constant
"MAX" should mean inclusive. And the whitelisting functions handled this
inconsistently.
2021-10-15 16:17:20 +00:00
Jonas Nick
297ce82091 Merge bitcoin-core/secp256k1#966: Make aux_rand32 arg to secp256k1_schnorrsig_sign const
db4667d5e0 Make aux_rand32 arg to secp256k1_schnorrsig_sign const (Pieter Wuille)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK db4667d5e0 diff looks good
  jonasnick:
    ACK db4667d5e0

Tree-SHA512: 6f003c856b0e11f3f41f6d8007470129f02f9075416c6a5d3904f8efb5fa461f38e600a6b31d326314b2961946c8c6b3bca1a8e9b333b52e099a6f023a04c698
2021-10-15 15:57:23 +00:00
Russell O'Connor
2888640132 VERIFY_CHECK precondition for secp256k1_fe_set_int. 2021-10-15 11:27:24 -04:00
Tim Ruffing
d49011f54c Make _set_fe_int( . , 0 ) set magnitude to 0 2021-10-15 11:20:27 -04:00
Tim Ruffing
e290c0f835 Merge ElementsProject/secp256k1-zkp#148: fix a couple things to make Elements 22's linter happy
b9ebee1490 fix a couple things to make Elements 22's linter happy (Andrew Poelstra)

Pull request description:

  In Elements 22 the linter looks for executable files that don't have a properly-formed shebang. For some reason it wants `/usr/bin/env bash` rather than `/bin/bash`, and also one of our source files was erroneously 755.

ACKs for top commit:
  real-or-random:
    ACK b9ebee1490

Tree-SHA512: 00da8fefd67c1882c6cec39dc81ce67ae3f52f902ddf72545e902b8f5bc7cd7c1249bf71027c530245c403a99c86ffbb61a89bc18c27c5ec975f6f653200766c
2021-10-15 15:23:57 +02:00
Tim Ruffing
7812feb896 Merge ElementsProject/secp256k1-zkp#144: Upstream PRs 969, 956, 783, 976
72713872a8 Add missing static to secp256k1_schnorrsig_sign_internal (Elichai Turkel)
adec5a1638 Add missing null check for ctx and input keys in the public API (Elichai Turkel)
f4edfc7581 Improve consistency for NULL arguments in the public interface (Elichai Turkel)
20abd52c2e Add tests for pre_g tables. (Russell O'Connor)
6815761cf5 Remove ecmult_context. (Russell O'Connor)
f20dcbbad1 Correct typo. (Russell O'Connor)
16a3cc07e8 Generate ecmult_static_pre_g.h (Russell O'Connor)
8de2d86a06 Bump memory limits in advance of making the ecmult context static. (Russell O'Connor)
5d5c74a057 tests: Rewrite code to circument potential bug in clang (Tim Ruffing)
3d2f492ceb ci: Install libasan6 (instead of 5) after Debian upgrade (Tim Ruffing)

Pull request description:

  [bitcoin-core/secp256k1#969]: ci: Fixes after Debian release
  [bitcoin-core/secp256k1#956]: Replace ecmult_context with a generated static array.
  [bitcoin-core/secp256k1#783]: Make the public API docs more consistent and explicit
  [bitcoin-core/secp256k1#976]: `secp256k1_schnorrsig_sign_internal` should be static

  This PR can be recreated  with `./sync-upstream.sh range 2a3a97c665475bc00d5d60f2f04830202983a631`.

ACKs for top commit:
  real-or-random:
    ACK 938725c1c9 inspected the diff between the pure output of running the sync script and this PR

Tree-SHA512: 6dd5964563497ced6afe533e4deaa82df76c071b5146a9eb7a5a998187210b5fbf19195d34320b7b2193f6b40d778cf258ad22033d7bc33479e0dc4791aceff9
2021-10-15 15:20:35 +02:00
Andrew Poelstra
b9ebee1490 fix a couple things to make Elements 22's linter happy 2021-10-14 21:21:30 +00:00
Pieter Wuille
bc08599e77 Remove OpenSSL testing support 2021-10-14 12:39:27 -04:00
Tim Ruffing
10f9bd84f4 Merge bitcoin-core/secp256k1#987: Fix unused parameter warnings when building without VERIFY
189f6bcfef Fix unused parameter warnings when building without VERIFY (Jonas Nick)

Pull request description:

  This commit makes `./configure --enable-coverage && make check` free of warnings.

ACKs for top commit:
  practicalswift:
    cr ACK 189f6bcfef
  elichai:
    utACK 189f6bcfef
  siv2r:
    Tested ACK 189f6bc

Tree-SHA512: 727fe0e40ff61f404780b32dfa4102a58bed9d922e61bd17ddaaf1243b0c06edd9697ff4763b5e92d033e7db3778193bee07d85cfa3b9c46d45e5fec3f568009
2021-10-12 16:31:38 +02:00
Jonas Nick
189f6bcfef Fix unused parameter warnings when building without VERIFY 2021-10-04 19:06:41 +00:00
Jonas Nick
da0092bccc Merge bitcoin-core/secp256k1#986: tests: remove secp256k1_fe_verify from tests.c and modify _fe_from_storage to call _fe_verify
d43993724d tests: remove `secp256k1_fe_verify` from tests.c and modify `secp256k1_fe_from_storage` to call `secp256k1_fe_verify` (siv2r)

Pull request description:

ACKs for top commit:
  roconnor-blockstream:
    utACK d439937 diff looks correct, I also didn't run the tests locally.
  real-or-random:
    utACK d43993724d diff looks correct, I didn't run the tests locally
  jonasnick:
    ACK d43993724d ran tests with `--enable-coverage`

Tree-SHA512: c3c9ecf8e9b7dfdcd1144ddcf8bcc637996c699dbd0fc6223e6186d082908728468fa276b09c6f344e036ca05f54432dde6366a83eb39f915a334164faadd556
2021-10-04 18:54:24 +00:00
siv2r
d43993724d tests: remove secp256k1_fe_verify from tests.c and modify secp256k1_fe_from_storage to call secp256k1_fe_verify
1. secp256k1_fe_verify is removed from tests since, it throws an error if VERIFY is not defined during compilation.
   (Ex: ./configure --enable-coverage)
2. `secp256k1_fe_from_storage` calls `secp256k1_fe_verify` in the VERIFY build to check for invalid field element.
2021-10-02 15:52:05 +05:30
Jonas Nick
7fec4e7acc Merge elementsproject/secp256k1-zkp#145: sync-upstream: fix quoting
95ee1fa030 sync-upstream: fix quoting (Jonas Nick)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 95ee1fa030

Tree-SHA512: e730d5985cf3b02998d8cd07d3e007e3b5239745553a2b275f7442298f2602c154d3bdeb5904f81cc0da3ce2bd42cf09ba946afa9ab3215da2ff3c9ce2f63777
2021-09-17 11:32:13 +00:00
Jonas Nick
938725c1c9 Merge commits 'd7ec49a6 9a5a87e0 aa5d34a8 2a3a97c6 ' into temp-merge-976
Also remove remaining uses of ecmult context in secp-zkp and update API tests
accordingly.
2021-09-16 15:21:11 +00:00
Jonas Nick
95ee1fa030 sync-upstream: fix quoting
Otherwise strings in $TITLE and $BODAY that are enclosed in ` are executed in
gh-pr-create.sh.
2021-09-15 20:29:33 +00:00
Tim Ruffing
2a3a97c665 Merge bitcoin-core/secp256k1#976: secp256k1_schnorrsig_sign_internal should be static
72713872a8 Add missing static to secp256k1_schnorrsig_sign_internal (Elichai Turkel)

Pull request description:

  This function isn't used outside of this module so it should be declared static

ACKs for top commit:
  real-or-random:
    ACK 72713872a8
  jonasnick:
    ACK 72713872a8

Tree-SHA512: 6107a2c84c3e11ffd68de22a5288d989a3c71c2ec1ee4827c88f6165fc27ef8339d0f6740928540e8ccd03aff49a2a96149bf698ccebe6d6d8ad6e23e38e8838
2021-09-15 16:55:50 +02:00
Tim Ruffing
aa5d34a8fe Merge bitcoin-core/secp256k1#783: Make the public API docs more consistent and explicit
adec5a1638 Add missing null check for ctx and input keys in the public API (Elichai Turkel)
f4edfc7581 Improve consistency for NULL arguments in the public interface (Elichai Turkel)

Pull request description:

  I went over the public API and added missing explanations on when a pointer can be null and when it cannot,
  and added some missing checks for null ctx and null pubkey pointers.

  Open questions IMHO:
  1. Can `secp256k1_context_create` return NULL? right now it could return null if you replaced the callbacks at compile time to ones that do return(unlike the default ones which never return).
  2. Related to the first, should we document that the callbacks should never return? (in the tests we use returning callbacks but we can violate our own API) right now we say the following:

  > After this callback returns, anything may happen, including crashing.

  Is this enough to document answer `no` for the first question and just saying that if the callback returned then you violated the API so `secp256k1_context_create` can return NULL even though it is promised not to?
  Right now we AFAICT we never check if it returns null

  Another nit I'm not sure about is wording `(does nothing if NULL)`/`(ignored if NULL)`/`(can be NULL)`

  More missing docs:
  1. Documenting the `data` argument to the default nonce functions

ACKs for top commit:
  ariard:
    ACK adec5a16
  jonasnick:
    ACK adec5a1638

Tree-SHA512: 6fe785776b7e451e9e8cae944987f927b1eb2e2d404dfcb1b0ceb0a30bda4ce16469708920269417e5ada09739723a430e270dea1868fe7d12ccd5699dde5976
2021-09-15 16:36:11 +02:00
Elichai Turkel
72713872a8 Add missing static to secp256k1_schnorrsig_sign_internal 2021-09-15 12:46:13 +03:00
Pieter Wuille
db4667d5e0 Make aux_rand32 arg to secp256k1_schnorrsig_sign const 2021-09-11 10:05:14 -04:00
Tim Ruffing
9a5a87e0f1 Merge bitcoin-core/secp256k1#956: Replace ecmult_context with a generated static array.
20abd52c2e Add tests for pre_g tables. (Russell O'Connor)
6815761cf5 Remove ecmult_context. (Russell O'Connor)
f20dcbbad1 Correct typo. (Russell O'Connor)
16a3cc07e8 Generate ecmult_static_pre_g.h (Russell O'Connor)
8de2d86a06 Bump memory limits in advance of making the ecmult context static. (Russell O'Connor)

Pull request description:

  Replace ecmult_context with a static array.

ACKs for top commit:
  real-or-random:
    ACK 20abd52c2e code inspection and tested some parameters
  sipa:
    utACK 20abd52c2e (reviewed diff with earlier reviewed commit 8e9f75a5888a8ec549fe9026053051c3db7a1282)

Tree-SHA512: 9980edf36e81430ea1774e6d5eef81946c26684f6e13eab2b61a8a6c9f23ed074ea8f33e80023bdf4275749275221879eacc8f222d2027e4286725127139f069
2021-08-25 20:57:47 +02:00
Russell O'Connor
20abd52c2e Add tests for pre_g tables.
We check that the static table entries are all correct.
2021-08-20 11:11:26 -04:00
Russell O'Connor
6815761cf5 Remove ecmult_context.
These tables stored in this context are now statically available from the generated ecmult_static_pre_g.h file.
2021-08-20 11:11:26 -04:00
Russell O'Connor
f20dcbbad1 Correct typo. 2021-08-20 11:11:26 -04:00
Russell O'Connor
16a3cc07e8 Generate ecmult_static_pre_g.h
This header contains a static array that replaces the ecmult_context pre_g and pre_g_128 tables.
The gen_ecmult_static_pre_g program generates this header file.
2021-08-20 11:11:26 -04:00
Russell O'Connor
8de2d86a06 Bump memory limits in advance of making the ecmult context static. 2021-08-20 11:11:26 -04:00
Jonas Nick
d7ec49a689 Merge bitcoin-core/secp256k1#969: ci: Fixes after Debian release
5d5c74a057 tests: Rewrite code to circument potential bug in clang (Tim Ruffing)
3d2f492ceb ci: Install libasan6 (instead of 5) after Debian upgrade (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 5d5c74a057

Tree-SHA512: 540ede482214bf9feaa607de52a69f6d34169dd98fb14bd3d003f4c8f722c1eebed56eb9d933e742f36d8886c25bfa9fa0ebbed5b0c3b161f04dc26180f5d214
2021-08-20 14:17:16 +00:00
Tim Ruffing
5d5c74a057 tests: Rewrite code to circument potential bug in clang
clang 7 to 11 (and maybe earlier versions) warn about recid being
potentially unitiliazed in "CHECK(recid >= 0 [...]", which was mitigated
in commit 3d2cf6c5bd by initializing recid
to make clang happy but VG_UNDEF'ing the variable after initializiation
in order to ensure valgrind's memcheck analysis will still be sound and
complain if recid is not actually written to when creating a signature.

However, it turns out that at least for binaries produced by clang 11
(but not clang 7), valgrind complains about a branch on unitialized data
in the recid variable in that line before *and* after the aforementioned
commit. While the complaint after the commit could be spurious (clang
knows that recid is initialized, so it's fine to access it even though
the access is stupid), the complaint before the commit indicates a real
problem: it might be the case that clang is performing a wrong
optimization that leads to a situation where recid is really not
guaranteed to be initialized when it's accessed. As a result, clang
warns about this and generates code that just accesses the variable.

I'm not going to bother with this further because this is fixed in
clang 12 and the problem is just in our test code, not in the tested
code.

This commit rewrites the code in a way that groups the signing together
with the CHECK such that it's very easy to figure out for clang that
recid will be initialized properly. This seems to circument the issue.
2021-08-19 13:41:40 +02:00
Tim Ruffing
3d2f492ceb ci: Install libasan6 (instead of 5) after Debian upgrade 2021-08-19 12:11:11 +02:00
Jonas Nick
9447642140 Merge elementsproject/secp256k1-zkp#142: musig: fix session_init argument NULL check
9124ce0d9c musig: fix session_init argument NULL check (Jonas Nick)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 9124ce0d9c

Tree-SHA512: 15b6e4012a2444803563151a37e3340e3aa59729ccafebfd80aac17b93f5429dc2b3c99e37119bfd68523f1e58ffd3efca67922d6cb4a2bbb7c8679de9f36097
2021-08-18 18:01:43 +00:00
Jonas Nick
9124ce0d9c musig: fix session_init argument NULL check 2021-08-18 14:02:29 +00:00
Jonas Nick
881b15cb43 Merge elementsproject/secp256k1-zkp#139: musig: use tagged hash for the list of pubkeys to aggregate
8f093be374 musig: use tagged hash for the list of pubkeys to aggregate (Jonas Nick)
a6a768a4bf musig: make key agg test vector more precise (Jonas Nick)

Pull request description:

Top commit has no ACKs.

Tree-SHA512: 5369dc5b4039dd4cda2c50282db2882c088b96e1daa5801240f92be1832ed8f29317fdbfc3cab211707155c284a68dc593967f3141703e2544f6b8dc1553e44d
2021-08-02 11:34:07 +00:00
Andrew Poelstra
90580edcc9 Merge pull request #140 from apoelstra/2021-07--resync
Upstream PRs 879, 959, 955, 944, 951, 960, 844, 963, 965
2021-07-28 21:58:53 +00:00
Andrew Poelstra
6ad66de680 rangeproof: add an (unnecessary) variable initialization to shut up CI 2021-07-27 18:15:58 +00:00
Andrew Poelstra
2979e4d9d4 Merge commits '8ae56e33 75ce488c 4866178d 446d28d9 253f90cd ec3aaa50 0440945f 7688a4f1 be8d9c26 ' into temp-merge-965 2021-07-27 18:12:45 +00:00
Jonas Nick
8f093be374 musig: use tagged hash for the list of pubkeys to aggregate
This is done to use tagged hashing consistently. Changes the musig test vectors.
2021-07-27 11:37:10 +00:00
Jonas Nick
a6a768a4bf musig: make key agg test vector more precise 2021-07-27 10:06:22 +00:00
Jonas Nick
5d2df05419 Merge elementsproject/secp256k1-zkp#120: Add MuSig Key Aggregation spec
fc26ca8dde musig: remove unnecessary constant time normalize in combine (Jonas Nick)
48f63efe68 musig: remove unnecessary branch in pubkey_tweak_add (Jonas Nick)
5860b5e0fe musig: do not also require schnorrsig module config flag (Jonas Nick)
f27fd1d5e7 musig: improve test coverage of pubkey_combine (Jonas Nick)
56014e8ca0 musig: change pubkey_combine arg to array of pointers to pks (Jonas Nick)
08fa02d579 musig: add key aggregation spec draft (Jonas Nick)
4a9b059b16 musig: rename Musig coefficient to KeyAgg coefficient (Jonas Nick)
4bc46d836e musig: optimize key aggregation using const 1 for 2nd key (Jonas Nick)
2310849f50 musig: compute musig coefficient by hashing key instead of index (Jonas Nick)
9683c8a7eb musig: add static test vectors for key aggregation (Jonas Nick)
9b3d7bf536 extrakeys: add xonly_sort function (Jonas Nick)
f31affd8a6 extrakeys: add hsort, in-place, iterative heapsort (Jonas Nick)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK fc26ca8dde

Tree-SHA512: fa29fe259d0e98d634782c0fb36308716dc3ffa6e35fe47b87fc25b2e5dd0a9859a72da0b9d669f03d379bc3ed972c5961995762b2f7e4ac16b9c6b5d8c4721d
2021-07-18 17:56:28 +00:00
Jonas Nick
fc26ca8dde musig: remove unnecessary constant time normalize in combine 2021-07-14 19:59:38 +00:00
Jonas Nick
48f63efe68 musig: remove unnecessary branch in pubkey_tweak_add 2021-07-14 19:59:38 +00:00
Jonas Nick
5860b5e0fe musig: do not also require schnorrsig module config flag
Also add musig to build options output.
2021-07-14 19:59:38 +00:00
Jonas Nick
f27fd1d5e7 musig: improve test coverage of pubkey_combine 2021-07-14 19:59:38 +00:00
Jonas Nick
56014e8ca0 musig: change pubkey_combine arg to array of pointers to pks
... instead of taking an array of pubkeys directly
2021-07-14 19:59:38 +00:00
Jonas Nick
08fa02d579 musig: add key aggregation spec draft 2021-07-14 19:59:38 +00:00
Jonas Nick
4a9b059b16 musig: rename Musig coefficient to KeyAgg coefficient
This is done to be consistent with the MuSig2 paper
2021-07-14 19:59:19 +00:00
Jonas Nick
4bc46d836e musig: optimize key aggregation using const 1 for 2nd key 2021-07-14 19:58:54 +00:00
Jonas Nick
2310849f50 musig: compute musig coefficient by hashing key instead of index 2021-07-14 19:41:38 +00:00
Jonas Nick
9683c8a7eb musig: add static test vectors for key aggregation 2021-07-14 19:41:38 +00:00
Jonas Nick
9b3d7bf536 extrakeys: add xonly_sort function 2021-07-14 19:41:38 +00:00
Jonas Nick
f31affd8a6 extrakeys: add hsort, in-place, iterative heapsort 2021-07-14 19:29:30 +00:00
Tim Ruffing
be8d9c262f Merge bitcoin-core/secp256k1#965: gen_context: Don't use any ASM
aeece44599 gen_context: Don't use any ASM (Tim Ruffing)

Pull request description:

  See https://github.com/bitcoin/bitcoin/issues/22441 , we need to wait for the testing results there.

ACKs for top commit:
  sipa:
    utACK aeece44599
  jonasnick:
    ACK aeece44599

Tree-SHA512: 52ff90f3dedda90124140de1c2c1c065a2f9374930d6b988d35c37f5eeae97f7d557b7ab0cf99d22add5a76ff8a3e06226572e43949e12d1048cb323d1b3d92b
2021-07-14 18:57:40 +02:00
Jonas Nick
d9560e0af7 Merge elementsproject/secp256k1-zkp#136: Eliminate a wrong -Wmaybe-uninitialized warning in GCC
cc0b279568 Eliminate a wrong -Wmaybe-uninitialized warning in GCC (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK cc0b279568

Tree-SHA512: ee9ae840ba7df471f566fc9b4d5bdf04e1d0759bd6fec1d1144e0e7b3f12603865371d238f8a2ee4648db88224e5ea582ab837c2cbc041d2582141736ebe5fd0
2021-07-14 13:57:13 +00:00
Tim Ruffing
aeece44599 gen_context: Don't use any ASM 2021-07-14 11:15:36 +02:00
Jonas Nick
6db00f5b2e Merge elementsproject/secp256k1-zkp#132: Upstream PRs 831, 907, 903, 889, 918, 906, 928, 922, 933, Merge bitcoin-core/secp256k1#936: Fix gen_context/ASM build on ARM, 925, 937, 926, Merge bitcoin-core/secp256k1#940: contrib: Explain explicit header guards, 850, 930, 941, 846, 947, 662, 950
f09497ea3e CI: tweak cirrus.yml to prevent OOM and timeout w sanitizer/valgrind (Jonas Nick)
7226cf215a ecdsa_adaptor: fix too small buffer in tests (Jonas Nick)
b053e853d4 ecdsa_adaptor: fix test case with invalid signature (Jonas Nick)
d27e459861 Revert "Remove unused Jacobi symbol support" (Jonas Nick)
c58c4ea470 ci: Add ppc64le build (Tim Ruffing)
8f879c2887 Fix array size in bench_ecmult (Jonas Nick)
2fe1b50df1 Add ecmult_gen, ecmult_const and ecmult to benchmark (Jonas Nick)
593e6bad9c Clean up ecmult_bench to make space for more benchmarks (Jonas Nick)
a35fdd3478 ci: Run PRs on merge result even for i686 (Tim Ruffing)
02dcea1ad9 ci: Make test iterations configurable and tweak for sanitizer builds (Tim Ruffing)
489ff5c20a tests: Treat empty SECP2561_TEST_ITERS as if it was unset (Tim Ruffing)
fcfcb97e74 ci: Simplify to use generic wrapper for QEMU, Valgrind, etc (Tim Ruffing)
de4157f13a ci: Run ASan/LSan and reorganize sanitizer and Valgrind jobs (Tim Ruffing)
09b3bb8648 Clean up git tree (Tim Ruffing)
8bbad7a18e Add asm build to ARM32 CI (Pieter Wuille)
7d65ed5214 Add ARM32/ARM64 CI (Pieter Wuille)
6eceec6d56 add `secp256k1_xonly_pubkey_cmp` method (Andrew Poelstra)
0d9561ae87 add `secp256k1_ec_pubkey_cmp` method (Andrew Poelstra)
22a9ea154a contrib: Explain explicit header guards (Tim Ruffing)
0881633dfd secp256k1.h: clarify that by default arguments must be != NULL (Jonas Nick)
14c9739a1f tests: Improve secp256k1_ge_set_all_gej_var for some infinity inputs (Tim Ruffing)
4a19668c37 tests: Test secp256k1_ge_set_all_gej_var for all infinity inputs (Tim Ruffing)
45b6468d7e Have secp256k1_ge_set_all_gej_var initialize all fields. Previous behaviour would not initialize r->y values in the case where infinity is passed in. Furthermore, the previous behaviour wouldn't initialize anything in the case where all inputs were infinity. (Russell O'Connor)
31c0f6de41 Have secp256k1_gej_double_var initialize all fields. Previous behaviour would not initialize r->x and r->y values in the case where infinity is passed in. (Russell O'Connor)
dd6c3de322 Have secp256k1_ge_set_gej_var initialize all fields. Previous behaviour would not initialize r->x and r->y values in the case where infinity is passed in. (Russell O'Connor)
3c90bdda95 change local lib headers to be relative for those pointing at "include/" dir (William Bright)
c8483520c9 Makefile.am: Don't pass a variable twice (Tim Ruffing)
2161f31785 Makefile.am: Honor config when building gen_context (Tim Ruffing)
99f47c20ec gen_context: Don't use external ASM because it complicates the build (Tim Ruffing)
99e2d5be0d Avoids a missing brace warning in schnorrsig/tests_impl.h on old compilers. (Gregory Maxwell)
ed5a199bed tests: fopen /dev/urandom in binary mode (Tim Ruffing)
4dc37bf81b Add mingw32-w64/wine CI build (Pieter Wuille)
ae9e648526 Define SECP256K1_BUILD in secp256k1.c directly. (Gregory Maxwell)
be0609fd54 Add unit tests for edge cases with delta=1/2 variant of divsteps (Pieter Wuille)
cd393ce228 Optimization: only do 59 hddivsteps per iteration instead of 62 (Pieter Wuille)
277b224b6a Use modified divsteps with initial delta=1/2 for constant-time (Pieter Wuille)
376ca366db Fix typo in explanation (Pieter Wuille)
07067967ee add ECMULT_GEN_PREC_BITS to basic_config.h (Aaron Voisine)
a3aa2628c7 gen_context: Don't include basic-config.h (Tim Ruffing)
99a1cfec17 print warnings for conditional-uninitialized (PiRK)
3d2cf6c5bd initialize variable in tests (PiRK)
23c3fb629b Make argument of fe_normalizes_to_zero{_var} const (Pieter Wuille)
4504472269 changed import to use brackets <> for openssl as they are not local to the project (William Bright)
24ad04fc06 Make scalar_inverse{,_var} benchmark scale with SECP256K1_BENCH_ITERS (Pieter Wuille)
ebc1af700f Optimization: track f,g limb count and pass to new variable-time update_fg_var (Peter Dettman)
b306935ac1 Optimization: use formulas instead of lookup tables for cancelling g bits (Peter Dettman)
9164a1b658 Optimization: special-case zero modulus limbs in modinv64 (Pieter Wuille)
1f233b3fa0 Remove num/gmp support (Pieter Wuille)
20448b8d09 Remove unused Jacobi symbol support (Pieter Wuille)
5437e7bdfb Remove unused scalar_sqr (Pieter Wuille)
aa9cc52180 Improve field/scalar inverse tests (Pieter Wuille)
1e0e885c8a Make field/scalar code use the new modinv modules for inverses (Pieter Wuille)
436281afdc Move secp256k1_fe_inverse{_var} to per-impl files (Pieter Wuille)
aa404d53be Move secp256k1_scalar_{inverse{_var},is_even} to per-impl files (Pieter Wuille)
08d54964e5 Improve bounds checks in modinv modules (Pieter Wuille)
151aac00d3 Add tests for modinv modules (Pieter Wuille)
d8a92fcc4c Add extensive comments on the safegcd algorithm and implementation (Pieter Wuille)
8e415acba2 Add safegcd based modular inverse modules (Peter Dettman)
de0a643c3d Add secp256k1_ctz{32,64}_var functions (Pieter Wuille)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK f09497ea3e

Tree-SHA512: 6cf3e96c5974e9aa17bd649fa7fdd738090ec3ab8c99e144fec397c086a24adc2ace9a5218a3c527989fc07e1d5c669027e4c895caf92d22771c8414b2a9bf35
2021-07-13 22:22:27 +00:00
Tim Ruffing
cc0b279568 Eliminate a wrong -Wmaybe-uninitialized warning in GCC 2021-07-13 17:30:05 +02:00
Jonas Nick
f09497ea3e CI: tweak cirrus.yml to prevent OOM and timeout w sanitizer/valgrind 2021-07-13 14:09:58 +00:00
Jonas Nick
7226cf215a ecdsa_adaptor: fix too small buffer in tests
Also add a specific test that fails adaptor sig deserialization because with the
correct size buffer that's not guaranteed anymore with the existing test.
2021-07-13 14:09:58 +00:00
Jonas Nick
b053e853d4 ecdsa_adaptor: fix test case with invalid signature
Previously the ECDSA signature had an overflowing s value, which after the sync
with upstream results in a failing VERIFY_CHECK in the inversion function.
However, normally parsed signatures shouldn't contain overflowing s values.
2021-07-13 14:09:58 +00:00
Jonas Nick
91b64770c3 Merge elementsproject/secp256k1-zkp#135: sync-upstream: fix "end" parameter for specifying range
907633e2e9 sync-upstream: fix "end" parameter for specifying range (Tim Ruffing)
394f49fd1a sync-upstream: quote variables (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    utACK 907633e2e9

Tree-SHA512: ba7834bf7fce403de29027e8df9387bbc6df5ba62eaacc31547bff0587962620475940b253966d0af0a3a4b3b12b4f72b64c8832aeffc638a308405a3945b6c2
2021-07-12 18:18:42 +00:00
Tim Ruffing
907633e2e9 sync-upstream: fix "end" parameter for specifying range 2021-07-12 18:24:04 +02:00
Tim Ruffing
394f49fd1a sync-upstream: quote variables 2021-07-12 18:23:18 +02:00
Jonas Nick
1bb5db3d60 Merge elementsproject/secp256k1-zkp#134: sync-upstream: parse merge commits w/ and w/o repo identifier
9321d42f75 sync-upstream: parse merge commits w/ and w/o repo identifier (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 9321d42f75

Tree-SHA512: 89347703b56199327813b9ac72d2e4b9620d852fb4059855f87a245f60f72605acf57ba07d073affe7eb0c4e7e97814f410679f4ed1e067939fab50c18a1eeee
2021-07-12 14:04:55 +00:00
Tim Ruffing
9321d42f75 sync-upstream: parse merge commits w/ and w/o repo identifier 2021-07-12 15:21:38 +02:00
Jonas Nick
7688a4f13a Merge bitcoin-core/secp256k1#963: "Schnorrsig API overhaul" fixups
90e83449b2 ci: Add C++ test (Tim Ruffing)
f698caaff6 Use unsigned char consistently for byte arrays (Tim Ruffing)
b5b8e7b719 Don't declare constants twice (Tim Ruffing)
769528f307 Don't use string literals for char arrays without NUL termination (Tim Ruffing)
2cc3cfa583 Fix -Wmissing-braces warning in clang (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 90e83449b2

Tree-SHA512: c26ba3db7514399c502f6c5c6f6ce6703459d83d831765042e331b051aeee282641197c3ae881c614f51ca714a818c5528410d288aadbd3e92361c1e9c129afe
2021-07-05 20:59:43 +00:00
Tim Ruffing
90e83449b2 ci: Add C++ test 2021-07-05 13:57:40 +02:00
Elichai Turkel
adec5a1638 Add missing null check for ctx and input keys in the public API 2021-07-04 12:47:46 +03:00
Elichai Turkel
f4edfc7581 Improve consistency for NULL arguments in the public interface 2021-07-04 12:47:45 +03:00
Tim Ruffing
f698caaff6 Use unsigned char consistently for byte arrays
C++ does not allow initialization with string literals but we do it in other
places and -fpermissive will convince g++ to compile.
2021-07-04 11:37:06 +02:00
Tim Ruffing
b5b8e7b719 Don't declare constants twice
This is forbidden in C++.
2021-07-04 11:35:52 +02:00
Tim Ruffing
769528f307 Don't use string literals for char arrays without NUL termination
unsigned char foo[4] = "abcd" is not valid C++ because the string
literal "abcd" does not fit into foo due to the terminating NUL
character. This is valid in C, it will just omit the NUL character.

Fixes #962.
2021-07-04 10:40:30 +02:00
Tim Ruffing
2cc3cfa583 Fix -Wmissing-braces warning in clang 2021-07-04 02:01:44 +02:00
Tim Ruffing
0440945fb5 Merge #844: schnorrsig API overhaul
5f6ceafcfa schnorrsig: allow setting MSGLEN != 32 in benchmark (Jonas Nick)
fdd06b7967 schnorrsig: add tests for sign_custom and varlen msg verification (Jonas Nick)
d8d806aaf3 schnorrsig: add extra parameter struct for sign_custom (Jonas Nick)
a0c3fc177f schnorrsig: allow signing and verification of variable length msgs (Jonas Nick)
5a8e4991ad Add secp256k1_tagged_sha256 as defined in BIP-340 (Jonas Nick)
b6c0b72fb0 schnorrsig: remove noncefp args from sign; add sign_custom function (Jonas Nick)
442cee5baf schnorrsig: add algolen argument to nonce_function_hardened (Jonas Nick)
df3bfa12c3 schnorrsig: clarify result of calling nonce_function_bip340 without data (Jonas Nick)
99e8614812 README: mention schnorrsig module (Jonas Nick)

Pull request description:

  This is a work in progress because I wanted to put this up for discussion before writing tests. It addresses the TODOs that didn't make it in the schnorrsig PR and changes the APIs of `schnorrsig_sign`, `schnorrsig_verify` and `hardened_nonce_function`.

  - Ideally, the new `aux_rand32` argument for `sign` would be const, but didn't find a solution I was happy with.
  - Support for variable length message signing and verification supports the [suggested BIP amendment](https://github.com/sipa/bips/issues/207#issuecomment-673681901) for such messages.
  - ~~`sign_custom` with its opaque config object allows adding more arguments later without having to change the API again. Perhaps there are other sensible customization options, but I'm thinking of [sign-to-contract/covert-channel](https://github.com/bitcoin-core/secp256k1/pull/590) in particular. It would require adding the fields `unsigned char *s2c_data32` and `secp256k1_s2c_opening *s2c_opening` to the config struct. The former is the data to commit to and the latter is written to by `sign_custom`.~~ (EDIT: see below)

ACKs for top commit:
  ariard:
    utACK 5f6ceaf
  LLFourn:
    utACK 5f6ceafcfa

Tree-SHA512: cf1716dddf4f29bcacf542ed22622a817d0ec9c20d0592333cb7e6105902c77d819952e776b9407fae1333cbd03d63fded492d3a5df7769dcc5b450d91bb4761
2021-07-03 11:45:30 +02:00
Tim Ruffing
ec3aaa5014 Merge #960: tests_exhaustive: check the result of secp256k1_ecdsa_sign
a1ee83c654 tests_exhaustive: check the result of secp256k1_ecdsa_sign (Nicolas Iooss)

Pull request description:

  Hello,

  In `test_exhaustive_sign`, if `secp256k1_ecdsa_sign` fails, the signature which is then loaded by `secp256k1_ecdsa_signature_load` is garbage. Exit early with an error when this occurs.

  By the way, I am wondering whether attribute `SECP256K1_WARN_UNUSED_RESULT` should be added to function `secp256k1_ecdsa_sign`: as (according to the documentation of this function) the nonce generation function may fail, it seems to be a good idea to force callers to check the value returned by this function. What do you think about this?

ACKs for top commit:
  sipa:
    ACK a1ee83c654
  real-or-random:
    utACK a1ee83c654

Tree-SHA512: d8c186afecbd95522e909c269255e8879695bf9df2de91f0f9303e575e18f03cafc66683d863e6cf9892fe61b668eab00d586861c39013292b71484a962f846d
2021-07-03 11:21:18 +02:00
Nicolas Iooss
a1ee83c654 tests_exhaustive: check the result of secp256k1_ecdsa_sign
If `secp256k1_ecdsa_sign` fails, the signature which is then loaded by
`secp256k1_ecdsa_signature_load` is garbage. Exit early with an error
when this occurs.
2021-07-02 16:22:43 +02:00
Jonas Nick
253f90cdeb Merge bitcoin-core/secp256k1#951: configure: replace AC_PATH_PROG to AC_CHECK_PROG
a4642fa15e configure: replace AC_PATH_PROG to AC_CHECK_PROG (UdjinM6)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK a4642fa15e
  jonasnick:
    utACK a4642fa15e

Tree-SHA512: 55a431633ca45ea78be3887cda2e94f6ec9e8a937bc60cf04f14d7e3be11acb7ee861bd356070e3b1f6ccdeff28c6f9ab7048a58f920681c09fe3a976621a187
2021-07-02 12:08:00 +00:00
Jonas Nick
446d28d9de Merge bitcoin-core/secp256k1#944: Various improvements related to CFLAGS
0302138f75 ci: Make compiler warning into errors on CI (Tim Ruffing)
b924e1e605 build: Ensure that configure's compile checks default to -O2 (Tim Ruffing)
7939cd571c build: List *CPPFLAGS before *CFLAGS like on the compiler command line (Tim Ruffing)
595e8a35d8 build: Enable -Wcast-align=strict warning (Tim Ruffing)
07256267ff build: Use own variable SECP_CFLAGS instead of touching user CFLAGS (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 0302138f75

Tree-SHA512: 619eb6b512ae0eb8c51134f5bb1b7bc7a397321dc51073ae3117f9433505ec19b407518b47a181163e1a841216b20487c7a50c6f5045faffa5cfa7fad0b8c906
2021-07-01 21:34:20 +00:00
Tim Ruffing
0302138f75 ci: Make compiler warning into errors on CI
This also tidies the list of environment variables in .cirrus.yml.
2021-07-01 20:37:40 +02:00
Tim Ruffing
b924e1e605 build: Ensure that configure's compile checks default to -O2
Fixes #896.
2021-07-01 19:59:25 +02:00
Tim Ruffing
7939cd571c build: List *CPPFLAGS before *CFLAGS like on the compiler command line 2021-07-01 19:59:25 +02:00
Tim Ruffing
595e8a35d8 build: Enable -Wcast-align=strict warning 2021-07-01 19:59:23 +02:00
Tim Ruffing
07256267ff build: Use own variable SECP_CFLAGS instead of touching user CFLAGS
Fixes one of the items in #923, namely the warnings of the form
    '_putenv' redeclared without dllimport attribute:
    previous dllimport ignored [-Wattributes]

This also cleans up the way we add CFLAGS, in particular flags enabling
warnings. Now we perform some more fine-grained checking for flag
support, which is not strictly necessary but the changes also help to
document autoconf.ac.
2021-07-01 19:58:44 +02:00
Jonas Nick
4866178dfc Merge bitcoin-core/secp256k1#955: Add random field multiply/square tests
bdf19f105c Add random field multiply/square tests (Pieter Wuille)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK bdf19f105c
  jonasnick:
    ACK bdf19f105c

Tree-SHA512: e78ce25f5440e87ad2cad0d4a87e5d95c983bc0be3a3e53d97f9cf6d8b3c3db9a830cb5f2f8c62f2f6dc9c6703c2a507cc23fa18d60bb624716e024539db5c21
2021-06-30 16:45:26 +00:00
Jonas Nick
75ce488c2a Merge bitcoin-core/secp256k1#959: tests: really test the non-var scalar inverse
41ed13942b tests: really test the non-var scalar inverse (Nicolas Iooss)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 41ed13942b
  jonasnick:
    ACK 41ed13942b

Tree-SHA512: d501300fea3f24af669556317ca899f6d184a2b1b64a3705417fce7c028288348555942604672eafa3ec59884849655a55cd9aacdd9ca8e34edf21b081702438
2021-06-28 15:32:33 +00:00
Nicolas Iooss
41ed13942b tests: really test the non-var scalar inverse
Function `test_inverse_scalar` contains:

    (var ? secp256k1_scalar_inverse_var : secp256k1_scalar_inverse_var)(&l, x);  /* l = 1/x */

The two sides of the condition are the same function. This seems to be
an error, as there also exists a non-var function, named
`secp256k1_scalar_inverse`.

Make `test_inverse_scalar` use this other function when `var` is false.

This issue was found using clang's static analyzer, which reported a
"Logic error: Identical expressions in conditional expression" (with
checker `alpha.core.IdenticalExpr`).
2021-06-28 15:21:00 +02:00
Jonas Nick
5f6ceafcfa schnorrsig: allow setting MSGLEN != 32 in benchmark 2021-06-27 20:26:15 +00:00
Jonas Nick
fdd06b7967 schnorrsig: add tests for sign_custom and varlen msg verification 2021-06-27 20:26:15 +00:00
Jonas Nick
d8d806aaf3 schnorrsig: add extra parameter struct for sign_custom
This simplifies the interface of sign_custom and allows adding more parameters
later in a backward compatible way.
2021-06-27 20:26:15 +00:00
Jonas Nick
a0c3fc177f schnorrsig: allow signing and verification of variable length msgs
Varlen message support for the default sign function comes from recommending
tagged_sha256. sign_custom on the other hand gets the ability to directly sign
message of any length. This also implies signing and verification support for
the empty message (NULL) with msglen 0.

Tests for variable lengths follow in a later commit.
2021-06-27 20:26:15 +00:00
Jonas Nick
5a8e4991ad Add secp256k1_tagged_sha256 as defined in BIP-340
Gives users the ability to hash messages to 32 byte before they are signed while
allowing efficient domain separation through the tag.
2021-06-27 20:26:15 +00:00
Jonas Nick
b6c0b72fb0 schnorrsig: remove noncefp args from sign; add sign_custom function
This makes the default sign function easier to use while allowing more granular
control through sign_custom.

Tests for sign_custom follow in a later commit.
2021-06-27 20:26:15 +00:00
Pieter Wuille
bdf19f105c Add random field multiply/square tests 2021-06-21 16:34:33 -07:00
Tim Ruffing
9be7b0f083 Avoid computing out-of-bounds pointer.
This is a pedantic case of UB.
2021-06-16 10:33:41 +02:00
Tim Ruffing
8ae56e33e7 Merge #879: Avoid passing out-of-bound pointers to 0-size memcpy
9570f674cc Avoid passing out-of-bound pointers to 0-size memcpy (Pieter Wuille)

Pull request description:

  Doing so could be considered UB in a pedantic interpretation of the standard. Avoid it.

  Closes #876.

ACKs for top commit:
  practicalswift:
    cr ACK 9570f674cc: patch looks correct
  real-or-random:
    ACK 9570f674cc

Tree-SHA512: f991462d72e39f14e609021b8427c2e6756009bc8cd21efca2da46ec9410250725a4fed662df20fcdcfd10a4dc59038f13e8c166362b2eadde4366586b9ca72b
2021-06-16 10:22:03 +02:00
UdjinM6
a4642fa15e configure: replace AC_PATH_PROG to AC_CHECK_PROG
Bitcoin Core's `configure` script uses `AC_CHECK_PROG` to find brew in the `PATH` [1]. If found, this macro will set `BREW=brew`. When building with dependencies however the `BREW` variable is set to `no` on macOS via `depends/<host_prefix>/share/config.site` [2] and this overrides `AC_CHECK_PROG` results [3]. Ideally, secp256k1's `configure` script should follow the same logic but this is not what happens because secp256k1's `configure` uses `AC_PATH_PROG` instead which respects preset variable values (in this case for variable `BREW`) only if they are a valid path (i.e., they match `[\\/*] | ?:[\\/]*` [4]), and `no` is not a path.

This commit changes `AC_PATH_PROG` to `AC_CHECK_PROG` to be consistent with Core's `AC_CHECK_PROG`. Both of these macros are supposed to find executables in the `PATH` but the difference is that former is supposed to return the full path whereas the latter is supposed to find only the program. As a result, the latter will accept even non-paths `no` as an override. Not knowing the full path is not an issue for the `configure` script because it will only execute `BREW` immediately afterwards, which works fine without the full path. (In particular, `PATH` cannot have changed in between [5].)

[1] https://github.com/bitcoin/bitcoin/blob/master/configure.ac#L684
[2] https://github.com/bitcoin/bitcoin/blob/master/depends/config.site.in#L73-L76
[3] 6d38e9fa2b/lib/autoconf/programs.m4 (L47)
[4] 6d38e9fa2b/lib/autoconf/programs.m4 (L127)
[5] [3ab1178](3ab1178d54)
2021-06-15 19:33:57 +03:00
Jonas Nick
d27e459861 Revert "Remove unused Jacobi symbol support"
This reverts commit 20448b8d09.

The removed functions secp256k1_ge_set_xquad and secp256k1_fe_is_quad_var
are required for some modules in secp256k1-zkp.
2021-06-14 20:24:08 +00:00
Jonas Nick
edcacc2b2e Merge commits '26de4dfe 6e898534 c083cc6e 1e5d50fa cc2c09e3 efad3506 7012a188 34388af6 98e0358d d0bd2693 185a6af2 6c52ae87 69394879 1e78c18d 202a030f bf0ac460 399722a6 3dc8c072 50f33677 7973576f 1758a92f ' into temp-merge-950 2021-06-14 18:16:46 +00:00
Jonas Nick
1758a92ffd Merge #950: ci: Add ppc64le build
c58c4ea470 ci: Add ppc64le build (Tim Ruffing)

Pull request description:

ACKs for top commit:
  sipa:
    ACK c58c4ea470
  jonasnick:
    ACK c58c4ea470

Tree-SHA512: 8f58783d07b34241619051c8375749699b1bd447de56541b3aea3d2e9546c6eb22fbcae55ad57bff614b8c3455933d74031162d00e5eabe6d1d55d56b4aaca16
2021-06-09 13:32:37 +00:00
Tim Ruffing
c58c4ea470 ci: Add ppc64le build 2021-06-08 17:03:53 +02:00
Tim Ruffing
7973576f6e Merge #662: Add ecmult_gen, ecmult_const and ecmult to benchmark
8f879c2887 Fix array size in bench_ecmult (Jonas Nick)
2fe1b50df1 Add ecmult_gen, ecmult_const and ecmult to benchmark (Jonas Nick)
593e6bad9c Clean up ecmult_bench to make space for more benchmarks (Jonas Nick)

Pull request description:

  I was trying to determine the impact of ecmult_gen in schnorrsig signing and noticed that there is no way to bench this right now. The new benchmarks look like this:
  ```
  $ ./bench_ecmult
  ecmult_gen: min 20.9us / avg 21.2us / max 21.7us
  ecmult_const: min 63.9us / avg 64.3us / max 64.8us
  ecmult 1: min 49.4us / avg 49.7us / max 50.3us
  ecmult 1g: min 39.8us / avg 40.0us / max 40.3us
  ecmult 2g: min 27.2us / avg 27.3us / max 27.8us
  ecmult_multi 1g: min 39.8us / avg 40.0us / max 40.2us
  ecmult_multi 2g: min 27.2us / avg 27.4us / max 27.7us
  ecmult_multi 3g: min 22.8us / avg 22.9us / max 23.1us
  ecmult_multi 4g: min 20.6us / avg 20.8us / max 21.1us
  ecmult_multi 5g: min 19.3us / avg 19.5us / max 19.7us
  ```

  (Turns out ecmult_gen is 37% of the 55.8us that schnorrsig sign takes)

ACKs for top commit:
  real-or-random:
    ACK 8f879c2887
  elichai:
    tACK 8f879c2887

Tree-SHA512: 8a739f5de1e2c0467c8d1c3ceeaf453b396a470ea0e8e5bef15fe1b32f3f9633b6b1c7e2ce1d94d736cf3e9adecd8f4f983ad4ba37450cd5991767f1a95db85c
2021-06-06 13:57:30 +02:00
Jonas Nick
8f879c2887 Fix array size in bench_ecmult 2021-05-31 20:46:04 +00:00
Jonas Nick
2fe1b50df1 Add ecmult_gen, ecmult_const and ecmult to benchmark 2021-05-31 20:46:04 +00:00
Jonas Nick
593e6bad9c Clean up ecmult_bench to make space for more benchmarks 2021-05-31 20:46:04 +00:00
Jonas Nick
50f3367712 Merge #947: ci: Run PRs on merge result even for i686
a35fdd3478 ci: Run PRs on merge result even for i686 (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK a35fdd3478

Tree-SHA512: 9b800b1136da2ecdaff7fcffaac92d91623c682abed1fa5c2a1fe4384f20d2ff1079786f7216c39f58f5dd025e4ed32237e7aff29f7658a74554f0c298e9148e
2021-05-31 20:34:10 +00:00
Tim Ruffing
a35fdd3478 ci: Run PRs on merge result even for i686
This line should have been added in c7f754fe4d.

This mistake caused some i686 builds to fail when the PR was not
rebased, see https://cirrus-ci.com/build/5156197872435200.
2021-05-31 18:11:27 +02:00
Jonas Nick
442cee5baf schnorrsig: add algolen argument to nonce_function_hardened
This avoids having to remove trailing NUL bytes in the nonce function
2021-05-28 11:40:52 +00:00
Jonas Nick
df3bfa12c3 schnorrsig: clarify result of calling nonce_function_bip340 without data 2021-05-28 11:40:52 +00:00
Jonas Nick
99e8614812 README: mention schnorrsig module 2021-05-28 11:40:52 +00:00
Jonas Nick
3dc8c072b6 Merge #846: ci: Run ASan/LSan and reorganize sanitizer and Valgrind jobs
02dcea1ad9 ci: Make test iterations configurable and tweak for sanitizer builds (Tim Ruffing)
489ff5c20a tests: Treat empty SECP2561_TEST_ITERS as if it was unset (Tim Ruffing)
fcfcb97e74 ci: Simplify to use generic wrapper for QEMU, Valgrind, etc (Tim Ruffing)
de4157f13a ci: Run ASan/LSan and reorganize sanitizer and Valgrind jobs (Tim Ruffing)

Pull request description:

ACKs for top commit:
  sipa:
    utACK 02dcea1ad9
  jonasnick:
    ACK 02dcea1ad9 spot-checked ci output, checked that when `valgrind ./tests` crashes then `LOG_COMPILER=valgrind make check` also crashes.

Tree-SHA512: 5f4a2fe186eca0b4ca29190eb18e20d0804934df614cdc8eb8cf0145ff36ded43194325572bb77eaaeba85c369f6effe69b7bdf7df97ba418d72cf36c9749a8c
2021-05-21 21:58:08 +00:00
Tim Ruffing
02dcea1ad9 ci: Make test iterations configurable and tweak for sanitizer builds 2021-05-21 20:48:07 +02:00
Tim Ruffing
489ff5c20a tests: Treat empty SECP2561_TEST_ITERS as if it was unset 2021-05-21 20:46:48 +02:00
Tim Ruffing
fcfcb97e74 ci: Simplify to use generic wrapper for QEMU, Valgrind, etc 2021-05-21 20:46:48 +02:00
Tim Ruffing
de4157f13a ci: Run ASan/LSan and reorganize sanitizer and Valgrind jobs 2021-05-21 12:12:46 +02:00
Jonas Nick
399722a63a Merge #941: Clean up git tree
09b3bb8648 Clean up git tree (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 09b3bb8648

Tree-SHA512: 70db146f4475e9618ecd68cf678d09a351e8da6c4fd4aa937c3f2fa30e3f6a9480ff24ac6301785fc2463bb5f8ff974091f8e9292ae7674ca9632b449a7034d5
2021-05-14 20:04:36 +00:00
Tim Ruffing
09b3bb8648 Clean up git tree
This removes the ununsed `obj` directory. It also suggests in the README
to create the "coverage" files in a separate directory and adds the
coverage files to .gitignore.

readme: Improve instructions for coverage reports
2021-05-14 11:37:44 +02:00
Jonas Nick
bf0ac46066 Merge #930: Add ARM32/ARM64 CI
8bbad7a18e Add asm build to ARM32 CI (Pieter Wuille)
7d65ed5214 Add ARM32/ARM64 CI (Pieter Wuille)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 8bbad7a18e CI output looks fine
  jonasnick:
    ACK 8bbad7a18e

Tree-SHA512: 090a52af6914cf9fb659f9626a8224d82c8da81f6e628b7300e34851e198d8299dfd25789c0f1d6f2c79f58b5413be498f9fba43bc50238480fe6524b640538a
2021-05-13 19:31:56 +00:00
Jonas Nick
202a030f7d Merge #850: add secp256k1_ec_pubkey_cmp method
6eceec6d56 add `secp256k1_xonly_pubkey_cmp` method (Andrew Poelstra)
0d9561ae87 add `secp256k1_ec_pubkey_cmp` method (Andrew Poelstra)

Pull request description:

ACKs for top commit:
  elichai:
    Code review ACK 6eceec6d56
  jonasnick:
    ACK 6eceec6d56
  real-or-random:
    ACK 6eceec6d56

Tree-SHA512: f95cbf65f16c88a4adfa1ea7cc6ddabab14baa3b68fa069e78e6faad4852cdbfaea42ee72590d2e0b8f3159cf9b37969511550eb6b2d256b101e2147711cc817
2021-05-13 19:17:53 +00:00
Pieter Wuille
1e78c18d5b Merge bitcoin-core/secp256k1#940: contrib: Explain explicit header guards
22a9ea154a contrib: Explain explicit header guards (Tim Ruffing)

Pull request description:

  They were added in #925 and deserve a comment.

ACKs for top commit:
  gmaxwell:
    ACK 22a9ea154a
  sipa:
    ACK 22a9ea154a

Tree-SHA512: 832e28d71857d52912dae7e6c0e08a3183bb788996bb2470616c6fbbac6ba601cc74bb51a4c908aec7df9ae4f4cbf2cbb1b451cefde1b5a7359dc93299840278
2021-05-11 20:10:07 -07:00
Tim Ruffing
69394879b6 Merge #926: secp256k1.h: clarify that by default arguments must be != NULL
0881633dfd secp256k1.h: clarify that by default arguments must be != NULL (Jonas Nick)

Pull request description:

  The same file says that the illegal callback will only triger for violations
  explicitly mentioned, which is not true without this commit because we often
  don't mention that an argument is not allowed to be NULL.

  This line is extracted from #783 in the hope that it gets merged faster because other PRs depend on it.

ACKs for top commit:
  gmaxwell:
    ACK 0881633dfd
  real-or-random:
    ACK 0881633dfd

Tree-SHA512: ecdc6954a1c21c333da5b03db51f50a0e53984aaef69cc697adaddc96b276da23e342037f476d21742632f6ec02bfa0574f837a5b5791f5985f4c355037176fa
2021-05-07 23:21:19 +02:00
Andrew Poelstra
6eceec6d56 add secp256k1_xonly_pubkey_cmp method 2021-05-06 18:36:44 +00:00
Andrew Poelstra
0d9561ae87 add secp256k1_ec_pubkey_cmp method 2021-05-06 18:36:41 +00:00
Tim Ruffing
22a9ea154a contrib: Explain explicit header guards
They were added in #925 and deserve a comment.
2021-05-06 17:12:11 +02:00
Tim Ruffing
6c52ae8724 Merge #937: Have ge_set_gej_var, gej_double_var and ge_set_all_gej_var initialize all fields of their outputs.
14c9739a1f tests: Improve secp256k1_ge_set_all_gej_var for some infinity inputs (Tim Ruffing)
4a19668c37 tests: Test secp256k1_ge_set_all_gej_var for all infinity inputs (Tim Ruffing)
45b6468d7e Have secp256k1_ge_set_all_gej_var initialize all fields. Previous behaviour would not initialize r->y values in the case where infinity is passed in. Furthermore, the previous behaviour wouldn't initialize anything in the case where all inputs were infinity. (Russell O'Connor)
31c0f6de41 Have secp256k1_gej_double_var initialize all fields. Previous behaviour would not initialize r->x and r->y values in the case where infinity is passed in. (Russell O'Connor)
dd6c3de322 Have secp256k1_ge_set_gej_var initialize all fields. Previous behaviour would not initialize r->x and r->y values in the case where infinity is passed in. (Russell O'Connor)

Pull request description:

  Previous behaviour would not initialize `r->x` and `r->y` values in the case where infinity is passed in.

ACKs for top commit:
  gmaxwell:
    ACK 14c9739a1f
  sipa:
    utACK 14c9739a1f
  real-or-random:
    ACK 14c9739a1f

Tree-SHA512: 2e779b767f02e348af4bbc62aa9871c3d1d29e61a6c643c879c49f2de27556a3588850acd2f7c7483790677597d01064025e14befdbf29e783f57996fe4430f9
2021-05-06 09:39:36 +02:00
Tim Ruffing
185a6af227 Merge #925: changed include statements without prefix 'include/'
3c90bdda95 change local lib headers to be relative for those pointing at "include/" dir (William Bright)

Pull request description:

  Referencing #924 , this PR splits the two issues brought on to a smaller to digest change. What this does is removes the prefix "include/" when referencing the local library header files.

  e.g:
  from:
  ```cpp
  #include "include/secp256k1.h"
  ```
  to:
  ```cpp
  #include "secp256k1.h"
  ```

  Rationale besides styling and consistency across other files in the repo, it makes it easier for outside builds to properly locate the headers.

  A live example seen here when attempting to build this library within bitcoin repo:
  ```sh
  [ 14%] Building CXX object leveldb/CMakeFiles/leveldb.dir/util/bloom.cc.o
  /tmp/bitcoin/src/secp256k1/src/secp256k1.c:7:10: fatal error: include/secp256k1.h: No such file or directory
      7 | #include "include/secp256k1.h"
        |          ^~~~~~~~~~~~~~~~~~~~~
  compilation terminated.
  make[2]: *** [secp256k1/CMakeFiles/Secp256k1.dir/build.make:76: secp256k1/CMakeFiles/Secp256k1.dir/src/secp256k1.c.o] Error 1
  make[1]: *** [CMakeFiles/Makefile2:537: secp256k1/CMakeFiles/Secp256k1.dir/all] Error 2
  make[1]: *** Waiting for unfinished jobs....

  ```

ACKs for top commit:
  gmaxwell:
    ACK 3c90bdda95
  real-or-random:
    ACK 3c90bdda95 code looks good and even the tests compile fine now without `-I` args

Tree-SHA512: 94d212718c6f4901f1c310aff504b7afedda91268143ffe1b45e9883cd517c0599e40ac798a51b54d66cd31646fe8cb1a489f1776612cfb5963654f4a1cee757
2021-05-05 20:18:25 +02:00
Tim Ruffing
14c9739a1f tests: Improve secp256k1_ge_set_all_gej_var for some infinity inputs 2021-05-05 13:07:25 -04:00
Tim Ruffing
4a19668c37 tests: Test secp256k1_ge_set_all_gej_var for all infinity inputs 2021-05-05 13:07:25 -04:00
William Bright
3c90bdda95 change local lib headers to be relative for those pointing at "include/" dir
added relative paths to header files imported from src directory

added include guards for contrib/ files when referring to secp256k1.h
2021-05-05 09:24:05 -04:00
Russell O'Connor
45b6468d7e Have secp256k1_ge_set_all_gej_var initialize all fields.
Previous behaviour would not initialize r->y values in the case where infinity is passed in.
Furthermore, the previous behaviour wouldn't initialize anything in the case where all inputs were infinity.
2021-05-04 16:17:00 -04:00
Russell O'Connor
31c0f6de41 Have secp256k1_gej_double_var initialize all fields.
Previous behaviour would not initialize r->x and r->y values in the case where infinity is passed in.
2021-05-04 15:49:48 -04:00
Russell O'Connor
dd6c3de322 Have secp256k1_ge_set_gej_var initialize all fields.
Previous behaviour would not initialize r->x and r->y values in the case where infinity is passed in.
2021-05-04 14:59:47 -04:00
Pieter Wuille
d0bd2693e3 Merge bitcoin-core/secp256k1#936: Fix gen_context/ASM build on ARM
c8483520c9 Makefile.am: Don't pass a variable twice (Tim Ruffing)
2161f31785 Makefile.am: Honor config when building gen_context (Tim Ruffing)
99f47c20ec gen_context: Don't use external ASM because it complicates the build (Tim Ruffing)

Pull request description:

  Obsoletes #935.

ACKs for top commit:
  gmaxwell:
    ACK c8483520c9   looks good and works here. Undefign is kinda yuck, but it is already doing it and it's cleaner than the obvious alternatives.
  sipa:
    utACK c8483520c9. I verified that building still works on ARM64, but without asm of course.

Tree-SHA512: fc5500688b2aecc4238e21c32f65559bcbfd1e83d1ae4d2c8e15573e94613667731064d8b5f2b9e4209016d88118263802ff4b9a73c1f37c224ccf2a4a1d6536
2021-05-04 11:33:30 -07:00
Pieter Wuille
8bbad7a18e Add asm build to ARM32 CI 2021-05-03 12:03:56 -07:00
Pieter Wuille
7d65ed5214 Add ARM32/ARM64 CI 2021-05-03 12:03:52 -07:00
Tim Ruffing
c8483520c9 Makefile.am: Don't pass a variable twice 2021-05-03 15:07:04 +02:00
Tim Ruffing
2161f31785 Makefile.am: Honor config when building gen_context
This passes $(DEFS) (which should literally be "-DHAVE_CONFIG_H") to the
compiler when building gen_context.

This has currently no effect because gen_context.c does not check for
this macro but it's conceivable that it may do so in the future.
2021-05-03 15:05:38 +02:00
Tim Ruffing
99f47c20ec gen_context: Don't use external ASM because it complicates the build
Fixes #931.
2021-05-03 15:05:38 +02:00
Jonas Nick
98e0358d29 Merge #933: Avoids a missing brace warning in schnorrsig/tests_impl.h on old compilers
99e2d5be0d Avoids a missing brace warning in schnorrsig/tests_impl.h on old compilers. (Gregory Maxwell)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 99e2d5be0d
  jonasnick:
    utACK 99e2d5be0d

Tree-SHA512: f3f9cfcd62830d7accca74dfce40abb091dec0990a66bad5d2a9599f2533121d8d1422499d511512bfb8d7c57da96e29e012dbc210e2e97ad55ad18de0869735
2021-05-03 09:52:01 +00:00
Gregory Maxwell
99e2d5be0d Avoids a missing brace warning in schnorrsig/tests_impl.h on old compilers.
GCC 4.9.2, at least, emits "warning: missing braces around initializer"
 without this.
2021-05-02 20:02:12 +00:00
Jonas Nick
34388af6b6 Merge #922: Add mingw32-w64/wine CI build
ed5a199bed tests: fopen /dev/urandom in binary mode (Tim Ruffing)
4dc37bf81b Add mingw32-w64/wine CI build (Pieter Wuille)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK ed5a199bed
  jonasnick:
    utACK ed5a199bed

Tree-SHA512: 45afc394e3a200f7c020426a66f78df8d12827b9dc91bb04dc1708c3ad5cdc4e7d20554d6d5c046d288552f4e722d4fe8a0f3234b662e7351a4d27aaaeb0d5c0
2021-05-02 12:57:40 +00:00
Tim Ruffing
7012a188e6 Merge #928: Define SECP256K1_BUILD in secp256k1.c directly.
ae9e648526 Define SECP256K1_BUILD in secp256k1.c directly. (Gregory Maxwell)

Pull request description:

  This avoids building without it and makes it safer to use a custom
   building environment.  Test harnesses need to #include secp256k1.c
   first now.

  Fixes #927

ACKs for top commit:
  sipa:
    utACK ae9e648526
  real-or-random:
    ACK ae9e648526

Tree-SHA512: 65ccc15c18f111ba926db1bb25f06c2beb2997c6f42c6d3ebc371ca84f4b5918379efd25c30556cedfd2e4275758bd79d733e80a11159c6ec013dd4707a683ad
2021-05-02 11:43:58 +02:00
Tim Ruffing
ed5a199bed tests: fopen /dev/urandom in binary mode
This makes a difference with mingw builds on Wine, where the subsequent
fread() may abort early in the default text mode.

The Microsoft C docs say:
"In text mode, CTRL+Z is interpreted as an EOF character on input."
2021-05-01 17:05:15 -07:00
Gregory Maxwell
ae9e648526 Define SECP256K1_BUILD in secp256k1.c directly.
This avoids building without it and makes it safer to use a custom
 building environment.  Test harnesses need to #include secp256k1.c
 first now.
2021-05-01 19:27:27 +00:00
Pieter Wuille
4dc37bf81b Add mingw32-w64/wine CI build 2021-04-30 16:37:44 -07:00
Jonas Nick
0881633dfd secp256k1.h: clarify that by default arguments must be != NULL
The same file says that the illegal callback will only triger for violations
explicitly mentioned, which is not true without this commit because we often
don't mention that an argument is not allowed to be NULL.
2021-04-29 10:21:26 +00:00
Tim Ruffing
efad3506a8 Merge #906: Use modified divsteps with initial delta=1/2 for constant-time
be0609fd54 Add unit tests for edge cases with delta=1/2 variant of divsteps (Pieter Wuille)
cd393ce228 Optimization: only do 59 hddivsteps per iteration instead of 62 (Pieter Wuille)
277b224b6a Use modified divsteps with initial delta=1/2 for constant-time (Pieter Wuille)
376ca366db Fix typo in explanation (Pieter Wuille)

Pull request description:

  This updates the divsteps-based modular inverse code to use the modified version which starts with delta=1/2. For variable time, the delta=1 variant is still used as it appears to be faster.

  See https://github.com/sipa/safegcd-bounds/tree/master/coq and https://medium.com/blockstream/a-formal-proof-of-safegcd-bounds-695e1735a348 for a proof of correctness of this variant.

  TODO:
  * [x] Update unit tests to include edge cases specific to this variant

  I'm still running the Coq proof verification for the 590 bound in non-native mode. It's unclear how long this will take.

ACKs for top commit:
  gmaxwell:
    ACK be0609fd54
  sanket1729:
    crACK be0609fd54
  real-or-random:
    ACK be0609fd54 careful code review and some testing

Tree-SHA512: 2f8f400ba3ac8dbd08622d564c3b3e5ff30768bd0eb559f2c4279c6c813e17cdde71b1c16f05742c5657b5238b4d592b48306f9f47d7dbdb57907e58dd99b47a
2021-04-22 20:18:52 +02:00
Jonas Nick
cc2c09e3a7 Merge #918: Clean up configuration in gen_context
07067967ee add ECMULT_GEN_PREC_BITS to basic_config.h (Aaron Voisine)
a3aa2628c7 gen_context: Don't include basic-config.h (Tim Ruffing)

Pull request description:

ACKs for top commit:
  sipa:
    utACK 07067967ee
  jonasnick:
    ACK 07067967ee

Tree-SHA512: 4889b483a33ac54f6038a5a5db1ccd225b03e752c5724243db7345389372ecf043433fd5441199043fc8b74c963f13cbf6a7c8068367f9a105e2be93392f24e9
2021-04-19 17:00:05 +00:00
Aaron Voisine
07067967ee add ECMULT_GEN_PREC_BITS to basic_config.h
set ECMULT_GEN_PREC_BITS to the "auto" value of 4 in basic_config.h, so libsecp can be used without autoconf
2021-04-15 17:18:03 +02:00
Tim Ruffing
a3aa2628c7 gen_context: Don't include basic-config.h
Before this commit, gen_context.c both included libsecp256k1-config.h
and basic-config.h: The former only to obtain ECMULT_GEN_PREC_BITS
and the latter to obtain a basic working configuration to be able to
use the library.

This was inelegant and confusing: It meant that basic-config.h needs
to #undef all the macros defined in libsecp256k1-config.h. Moreover,
it meant that basic-config.h cannot define ECMULT_GEN_PREC_BITS,
essentially making this file specific for use in gen_context.c.

After this commit, gen_context.c include only libsecp256k1-config.h.
basic-config.h is not necessary anymore for the modules used in
gen_context.c because 79f1f7a made the preprocessor detect all the
relevant config options.

On the way, we remove an unused #define in basic-config.h.
2021-04-15 17:18:03 +02:00
Pieter Wuille
be0609fd54 Add unit tests for edge cases with delta=1/2 variant of divsteps 2021-04-13 11:59:14 -07:00
Pieter Wuille
cd393ce228 Optimization: only do 59 hddivsteps per iteration instead of 62 2021-04-13 11:59:14 -07:00
Pieter Wuille
277b224b6a Use modified divsteps with initial delta=1/2 for constant-time
Instead of using eta=-delta, use zeta=-(delta+1/2) to represent
delta. This variant only needs at most 590 iterations for 256-bit
inputs rather than 724 (by convex hull bounds analysis).
2021-04-13 11:59:11 -07:00
Pieter Wuille
376ca366db Fix typo in explanation 2021-04-13 11:58:54 -07:00
Jonas Nick
1e5d50fa93 Merge #889: fix uninitialized read in tests
99a1cfec17 print warnings for conditional-uninitialized (PiRK)
3d2cf6c5bd initialize variable in tests (PiRK)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 99a1cfec17 code inspection
  jonasnick:
    ACK 99a1cfec17

Tree-SHA512: 72f92f51c44210ab54f166920f540525db0e3d1f19a2fa56e4a6d157a38a582f9dc649d919cf3278482c9fd723021b07759284a8fccbc574b62a22aac0facf51
2021-04-07 12:53:09 +00:00
Jonas Nick
f3708a1ecb Merge #117: Add ECDSA adaptor signatures module
b0ffa92319 ecdsa_adaptor: add tests (Jesse Posner)
6955af5ca8 ecdsa_adaptor: add ECDSA adaptor signature APIs (Jesse Posner)
b508e5dd9b ecdsa_adaptor: add support for proof of discrete logarithm equality (Jesse Posner)
d8f336564f ecdsa_adaptor: add nonce function and tags (Jesse Posner)
654cd633f5 ecdsa_adaptor: initialize project (Jesse Posner)

Pull request description:

ACKs for top commit:
  LLFourn:
    ACK b0ffa92319 I've added a small warning to the spec too.
  jonasnick:
    ACK b0ffa92319

Tree-SHA512: f14e6f32265518d435d4da00a73423615ba900de68c28039ae26ac7ee7b4088db44358741411d96c42bd497db79483ff0766fc2d076d95a9116bcc168b80802d
2021-04-06 12:13:51 +00:00
Jonas Nick
5710ebacb9 Merge #128: Make function argument name consistent with doc
cc82ad5ab7 Make function argument name consistent with doc (Sanket Kanjalkar)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK cc82ad5ab7

Tree-SHA512: ef0f4ee36452dc98fa39677c567313a35b067926c76a8e5c33ae5260d1c672d872a4be1c5ebfbdb3e75d0c70ed1bb7f3dcbc592b932cef8af38cdcd154784a98
2021-04-01 18:30:11 +00:00
Jesse Posner
b0ffa92319 ecdsa_adaptor: add tests
This commit adds test coverage including Cirrus scripts, Valgrind
constant time tests for secret data, API tests, nonce function tests,
and test vectors from the spec.
2021-03-26 16:04:56 -07:00
Jesse Posner
6955af5ca8 ecdsa_adaptor: add ECDSA adaptor signature APIs
This commit adds the ECDSA adaptor signature APIs:

- Encrypted Signing

  Creates an adaptor signature, which includes a proof to verify the adaptor
  signature.

- Encryption Verification

  Verifies that the adaptor decryption key can be extracted from the adaptor
  signature and the completed ECDSA signature.

- Signature Decryption

  Derives an ECDSA signature from an adaptor signature and an adaptor decryption
  key.

- Key Recovery

  Extracts the adaptor decryption key from the complete signature and the adaptor
  signature.
2021-03-26 16:04:52 -07:00
Jonas Nick
c083cc6e52 Merge #903: Make argument of fe_normalizes_to_zero{_var} const
23c3fb629b Make argument of fe_normalizes_to_zero{_var} const (Pieter Wuille)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 23c3fb629b diff looks good
  jonasnick:
    ACK 23c3fb629b

Tree-SHA512: a51894a9e59851dc4854e92e4200ef6d12a11f6785b903c23585cfff5ef8d369216f4121260fe8789d46d3e215f3c2baa42decae99ab9328e8081f5274e67fab
2021-03-26 14:57:01 +00:00
Jonas Nick
6e898534ff Merge #907: changed import to use brackets <> for openssl
4504472269 changed import to use brackets <> for openssl as they are not local to the project (William Bright)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 4504472269
  jonasnick:
    ACK 4504472269

Tree-SHA512: e35c202835a82dab5fe9f2f75e7752e70b15d5d2ee7485790749f145b35e8e995c4978b4015c726387c24248a7efb636d28791fe882581a144a0ddfb27e14075
2021-03-26 14:01:56 +00:00
Sanket Kanjalkar
cc82ad5ab7 Make function argument name consistent with doc 2021-03-24 01:44:15 -07:00
William Bright
4504472269 changed import to use brackets <> for openssl as they are not local to the project 2021-03-20 19:59:51 -04:00
Pieter Wuille
26de4dfeb1 Merge #831: Safegcd inverses, drop Jacobi symbols, remove libgmp
24ad04fc06 Make scalar_inverse{,_var} benchmark scale with SECP256K1_BENCH_ITERS (Pieter Wuille)
ebc1af700f Optimization: track f,g limb count and pass to new variable-time update_fg_var (Peter Dettman)
b306935ac1 Optimization: use formulas instead of lookup tables for cancelling g bits (Peter Dettman)
9164a1b658 Optimization: special-case zero modulus limbs in modinv64 (Pieter Wuille)
1f233b3fa0 Remove num/gmp support (Pieter Wuille)
20448b8d09 Remove unused Jacobi symbol support (Pieter Wuille)
5437e7bdfb Remove unused scalar_sqr (Pieter Wuille)
aa9cc52180 Improve field/scalar inverse tests (Pieter Wuille)
1e0e885c8a Make field/scalar code use the new modinv modules for inverses (Pieter Wuille)
436281afdc Move secp256k1_fe_inverse{_var} to per-impl files (Pieter Wuille)
aa404d53be Move secp256k1_scalar_{inverse{_var},is_even} to per-impl files (Pieter Wuille)
08d54964e5 Improve bounds checks in modinv modules (Pieter Wuille)
151aac00d3 Add tests for modinv modules (Pieter Wuille)
d8a92fcc4c Add extensive comments on the safegcd algorithm and implementation (Pieter Wuille)
8e415acba2 Add safegcd based modular inverse modules (Peter Dettman)
de0a643c3d Add secp256k1_ctz{32,64}_var functions (Pieter Wuille)

Pull request description:

  This is a rebased and squashed version of #767, adding safegcd-based implementations of constant-time and variable-time modular inverses for scalars and field elements, by Peter Dettman. The PR is organized as follows:
  * **Add secp256k1_ctz{32,64}_var functions** Introduction of ctz functions to util.h (which use `__builtin_ctz` on recent GCC and Clang, but fall back to using a software emulation using de Bruijn on other platforms). This isn't used anywhere in this commit, but does include tests.
  * **Add safegcd based modular inverse modules** Add Peter Dettman's safegcd code from #767 (without some of his optimizations, which are moved to later commits), turned into separate modules by me.
  * **Add extensive comments on the safegcd algorithm and implementation** Add a long description of the algorithm and optimizations to `doc/safegcd_implementation.md`, as well as additional comments to the code itself. It is probably best to review this together with the previous commit (they're separated to keep authorship).
  * **Add tests for modinv modules** Adds tests on the modinv interface directly, for arbitrary moduli.
  * **Improve bounds checks in modinv modules** Adds a lot of sanity checking to the modinv modules.
  * **Move secp256k1_scalar_{inverse{_var},is_even} to per-impl files** A pure refactor to prepare for switching the field and scalar code to modinv.
  * **Make field/scalar code use the new modinv modules for inverses** Actually switch over.
  * **Add extra modular inverse tests** This adds modular inverse tests through the field/scalar interface, now that those use modinv.
  * **Remove unused Jacobi symbol support** No longer needed.
  * **Remove num/gmp support** Bye-bye.
  * 3 commits with further optimizations.

ACKs for top commit:
  gmaxwell:
    ACK 24ad04fc06
  sanket1729:
    ACK 24ad04fc06
  real-or-random:
    ACK 24ad04fc06 careful code review, some testing

Tree-SHA512: 732fe29315965e43ec9a10ee8c71eceeb983c43fe443da9dc5380a5a11b5e40b06e98d6abf67b773b1de74571fd2014973c6376f3a0caeac85e0cf163ba2144b
2021-03-17 17:04:19 -07:00
Jesse Posner
b508e5dd9b ecdsa_adaptor: add support for proof of discrete logarithm equality
This commit adds proving and verification functions for discrete
logarithm equality.

From the spec (https://github.com/discreetlogcontracts/dlcspecs/pull/114):

"As part of the ECDSA adaptor signature a proof of discrete logarithm
equality must be provided. This is a proof that the discrete logarithm of
some X to the standard base G is the same as the discrete logarithm of
some Z to the base Y. This proof can be constructed by using equality
composition on two Sigma protocols proving knowledge of the discrete
logarithm between both pairs of points. In other words the prover proves
knowledge of a such that X = a * G and b such that Z = b * Y and that
a = b. We make the resulting Sigma protocol non-interactive by applying
the Fiat-Shamir transformation with SHA256 as the challenge hash."
2021-03-16 16:13:34 -07:00
Jesse Posner
d8f336564f ecdsa_adaptor: add nonce function and tags
This commit adds a nonce function that will be used by default
for ECDSA adaptor signatures.

This nonce function is similar to secp256k1_nonce_function_hardened
except it uses the compressed 33-byte encoding for the pubkey argument.
We need 33 bytes instead of 32 because, unlike with BIP-340, an ECDSA
X-coordinate alone is not sufficient to disambiguate the Y-coordinate.
2021-03-16 16:13:34 -07:00
Jesse Posner
654cd633f5 ecdsa_adaptor: initialize project
This commit adds the foundational configuration and building scripts
and an initial structure for the project.
2021-03-16 16:13:31 -07:00
Pieter Wuille
23c3fb629b Make argument of fe_normalizes_to_zero{_var} const 2021-03-15 16:01:57 -07:00
Pieter Wuille
24ad04fc06 Make scalar_inverse{,_var} benchmark scale with SECP256K1_BENCH_ITERS 2021-03-15 13:01:56 -07:00
Peter Dettman
ebc1af700f Optimization: track f,g limb count and pass to new variable-time update_fg_var
The magnitude of the f and g variables generally goes down as the algorithm
progresses. Make use of this by keeping tracking how many limbs are used, and
when the number becomes small enough, make use of this to reduce the complexity
of arithmetic on them.

Refactored by: Pieter Wuille <pieter@wuille.net>
2021-03-15 13:01:56 -07:00
Peter Dettman
b306935ac1 Optimization: use formulas instead of lookup tables for cancelling g bits
This only seems to be a win on 64-bit platforms, so only do it there.

Refactored by: Pieter Wuille <pieter@wuille.net>
2021-03-15 13:01:56 -07:00
Pieter Wuille
9164a1b658 Optimization: special-case zero modulus limbs in modinv64
Both the field and scalar modulus can be written in signed{30,62} notation
with one or more zero limbs. Make use of this in the update_de function to
avoid a few wide multiplications when that is the case.

This doesn't appear to be a win in the 32-bit implementation, so only
do it for the 64-bit one.
2021-03-15 13:01:56 -07:00
Pieter Wuille
1f233b3fa0 Remove num/gmp support
The whole "num" API and its libgmp-based implementation are now unused. Remove them.
2021-03-15 13:01:52 -07:00
Jonas Nick
fac477f822 Merge #126: Upstream PRs #854 #852 #857 #858 #860 #845 #862 #875 #878 #874 #877 #880 #864 #882 #894 #891 #901
4091e61924 cirrus: increase timeout for macOS tasks (Jonas Nick)
79d4c3ac68 whitelist: add SECP_INCLUDES to bench_whitelist CPPFLAGS (Jonas Nick)
649bf201d8 musig: fix tests for 32-bit (Jonas Nick)
9361f360bb ci: Select number of parallel make jobs depending on CI environment (Tim Ruffing)
28eccdf806 ci: Split output of logs into multiple sections (Tim Ruffing)
c7f754fe4d ci: Run PRs on merge result instead of on the source branch (Tim Ruffing)
b994a8be3c ci: Print information about binaries using "file" (Tim Ruffing)
f24e122d13 ci: Switch all Linux builds to Debian (Tim Ruffing)
f329bba244 build: Add workaround for automake 1.13 and older (Tim Ruffing)
7d3497cdc4 ctime_test: move context randomization test to the end (Jonas Nick)
e491d06b98 Use bit ops instead of int mult for constant-time logic in gej_add_ge (Tim Ruffing)
cc2a5451dc ci: Refactor Nix shell files (Jonas Nick)
2480e55c8f ci: Remove support for Travis CI (Tim Ruffing)
2b359f1c1d ci: Enable simple cache for brewing valgrind on macOS (Tim Ruffing)
8c02e465c5 ci: Add support for Cirrus CI (Tim Ruffing)
b6f649889a Add parens around ROUND_TO_ALIGN's parameter. This makes the macro robust against a hypothetical ROUND_TO_ALIGN(foo ? sizeA : size B) invocation. (Russell O'Connor)
482e4a9cfc Add missing secp256k1_ge_set_gej_var decl. (Russell O'Connor)
fb390c5299 Remove underscores from header defs. This makes them consistent with other files and avoids reserved identifiers. (Russell O'Connor)
75d2ae149e Remove unused secp256k1_fe_inv_all_var (Pieter Wuille)
2730618604 Avoid casting (void**) values. Replaced with an expression that only casts (void*) values. (Russell O'Connor)
3c15130709 Improve CC_FOR_BUILD detection (Tim Ruffing)
47802a4762 Restructure and tidy configure.ac (Tim Ruffing)
252c19dfc6 Ask brew for valgrind include path (Tim Ruffing)
33cb3c2b1f Add secret key extraction from keypair to constant time tests (Elichai Turkel)
36d9dc1e8e Add seckey extraction from keypair to the extrakeys tests (Elichai Turkel)
fc96aa73f5 Add a function to extract the secretkey from a keypair (Elichai Turkel)
b7bc3a4aaa fixed typo (Ferdinando M. Ametrano)
07aa4c70ff Fix insecure links (Dimitris Apostolou)
18aadf9d28 docs: fix simple typo, dependecy -> dependency (Tim Gates)
329a2e0a3f sage: Add script for generating scalar_split_lambda constants (Tim Ruffing)
f554dfc708 sage: Reorganize files (Tim Ruffing)
6e85d675aa Rename tweak to tweak32 in public API (Jonas Nick)
f587f04e35 Rename msg32 to msghash32 in ecdsa_sign/verify and add explanation (Jonas Nick)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 4091e61924 merge commit picks the right parents, merge resolution and  additional commit look good

Tree-SHA512: 4f91842ec08c0d6f62c85f6426fe6af6556b4e7b0e6f2a3317953f61557f9a02855e05a28eaa22d7c245bc915778cea6a43e8c881540de43ce08deb916caf07f
2021-03-12 20:40:06 +00:00
Pieter Wuille
20448b8d09 Remove unused Jacobi symbol support
No exposed functions rely on Jacobi symbol computation anymore. Remove it; it can always
be brough back later if needed.
2021-03-12 10:06:18 -08:00
Pieter Wuille
5437e7bdfb Remove unused scalar_sqr 2021-03-12 10:06:18 -08:00
Pieter Wuille
aa9cc52180 Improve field/scalar inverse tests
Add a new run_inverse_tests that replaces all existing field/scalar inverse tests,
and tests a few identities for fixed inputs, small numbers (-999...999), random
inputs (structured and unstructured), as well as comparing with the output of
secp256k1_fe_inv_all_var.
2021-03-12 10:06:18 -08:00
Pieter Wuille
1e0e885c8a Make field/scalar code use the new modinv modules for inverses 2021-03-12 10:06:14 -08:00
Pieter Wuille
436281afdc Move secp256k1_fe_inverse{_var} to per-impl files
This temporarily duplicates the inversion code across the 5x52 and 10x26
implementations. Those implementations will be replaced in a next commit.
2021-03-11 10:25:26 -08:00
Pieter Wuille
aa404d53be Move secp256k1_scalar_{inverse{_var},is_even} to per-impl files
This temporarily duplicates the inversion code across the 4x64 and 8x32
implementations. Those implementations will be replaced in a later commit.
2021-03-11 10:25:26 -08:00
Pieter Wuille
08d54964e5 Improve bounds checks in modinv modules
This commit adds functions to verify and compare numbers in signed{30,62} notation,
and uses that to do more extensive bounds checking on various variables in the modinv
code.
2021-03-11 10:25:22 -08:00
Jonas Nick
6a7861f646 Merge #127: sync-upstream: Create proper links to upstream PRs
136ed8f84d sync-upstream: Fix output of command to reproduce (Tim Ruffing)
38f1e777d4 sync-upstream: Create proper links to upstream PRs (Tim Ruffing)

Pull request description:

ACKs for top commit:
  jonasnick:
    ACK 136ed8f84d

Tree-SHA512: f3bc9a15ec62d6c0fc0cdd7c1b4553b0d4159eebbc6f0151d05fac6bd480296be4b2ffbec418ec9102fe228b98f1f57cbecfd70b1a72485b4e1ef57489aae115
2021-03-10 21:22:00 +00:00
Jonas Nick
4091e61924 cirrus: increase timeout for macOS tasks 2021-03-10 21:02:19 +00:00
Tim Ruffing
136ed8f84d sync-upstream: Fix output of command to reproduce 2021-03-10 16:13:17 +01:00
Tim Ruffing
38f1e777d4 sync-upstream: Create proper links to upstream PRs 2021-03-10 15:53:54 +01:00
Jonas Nick
79d4c3ac68 whitelist: add SECP_INCLUDES to bench_whitelist CPPFLAGS
This will fix the following compile error on macOS

In file included from src/num.h:17,
                 from src/num_impl.h:14,
                 from src/bench_whitelist.c:14:
src/num_gmp.h:10:10: fatal error: gmp.h: No such file or directory
2021-03-10 13:28:16 +00:00
Jonas Nick
649bf201d8 musig: fix tests for 32-bit 2021-03-10 13:20:01 +00:00
Pieter Wuille
151aac00d3 Add tests for modinv modules
This adds tests for the modinv{32,64}_impl.h directly (before the functions are used
inside the field/scalar code). It uses a naive implementation of modular multiplication
and gcds in order to verify the modular inverses themselves.
2021-03-08 09:56:07 -08:00
Pieter Wuille
d8a92fcc4c Add extensive comments on the safegcd algorithm and implementation
This adds a long comment explaining the algorithm and implementation choices by building
it up step by step in Python.

Comments in the code are also reworked/added, with references to the long explanation.
2021-03-08 09:56:07 -08:00
Peter Dettman
8e415acba2 Add safegcd based modular inverse modules
Refactored by: Pieter Wuille <pieter@wuille.net>
2021-03-08 09:56:07 -08:00
Pieter Wuille
de0a643c3d Add secp256k1_ctz{32,64}_var functions
These functions count the number of trailing zeroes in non-zero integers.
2021-03-08 09:56:07 -08:00
Jonas Nick
d4ca81f48e Merge commits 'dc6e5c3a 2d9e7175 b61f9da5 98dac878 8c727b90 328aaef2 f2d9aeae b732701f db726782 5671e5f3 a4abaab7 659d0d47 f8c0b57e 24d1656c 3a8b47bc ebdba03c 4c3ba88c ' into temp-merge-901
Also add -zkp modules to .cirrus.yml.
2021-03-08 13:35:16 +00:00
Tim Ruffing
4c3ba88c3a Merge #901: ci: Switch all Linux builds to Debian and more improvements
9361f360bb ci: Select number of parallel make jobs depending on CI environment (Tim Ruffing)
28eccdf806 ci: Split output of logs into multiple sections (Tim Ruffing)
c7f754fe4d ci: Run PRs on merge result instead of on the source branch (Tim Ruffing)
b994a8be3c ci: Print information about binaries using "file" (Tim Ruffing)
f24e122d13 ci: Switch all Linux builds to Debian (Tim Ruffing)

Pull request description:

  Best reviewed commit by commit

ACKs for top commit:
  jonasnick:
    ACK 9361f360bb
  sipa:
    utACK 9361f360bb

Tree-SHA512: fc754e8b57dc58058cebbf63a60ca76e08dbaefea1508ea27b7f962bce697c10033da3f57a35f731bc7cf3e210eb00e3b8985ae8b729d7bd83faee085b878b9c
2021-03-07 22:17:13 +01:00
Tim Ruffing
9361f360bb ci: Select number of parallel make jobs depending on CI environment
This should improve compilation times on macOS. Things can certainly
be improved further, e.g., by running the benchmarks in parallel.
2021-03-03 18:16:25 +01:00
Tim Ruffing
28eccdf806 ci: Split output of logs into multiple sections 2021-03-03 01:21:11 +01:00
Tim Ruffing
c7f754fe4d ci: Run PRs on merge result instead of on the source branch
This is taken from Bitcoin Core's .cirrus.yml
2021-03-03 01:21:11 +01:00
Tim Ruffing
b994a8be3c ci: Print information about binaries using "file" 2021-03-03 01:21:11 +01:00
Tim Ruffing
f24e122d13 ci: Switch all Linux builds to Debian
The experiment of using Nix Shell was not really successful. Most
notably, Nix uses a bunch of wrapper scripts around compilers, which
make the build much less "pure". This may be useful but it's exactly
not what we want for CI. In particular, this resulted in gcc being used
for the "clang" builds because a wrapper script redefined the CC env
variable.

This now builds a single docker image (Debian) for all architectures
that we test in CI on Linux.
2021-03-03 00:38:01 +01:00
Tim Ruffing
ebdba03cb5 Merge #891: build: Add workaround for automake 1.13 and older
f329bba244 build: Add workaround for automake 1.13 and older (Tim Ruffing)

Pull request description:

  Fixes #890.

ACKs for top commit:
  michaelfolkson:
    ACK f329bba244

Tree-SHA512: 1ae3d1587abb402c2d3bb28d3a48aeff056f061e755d65d482204bb502b8427aad376c7319b4a694a5bf79c193acd3c88cb65928f0bc0e5c7587222e1315b6d0
2021-03-02 15:27:16 +01:00
Jonas Nick
3a8b47bc6d Merge #894: ctime_test: move context randomization test to the end
7d3497cdc4 ctime_test: move context randomization test to the end (Jonas Nick)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 7d3497cdc4 diff looks good

Tree-SHA512: aef006c43df4cab254ee7de79cdd34c4e2f7a463f29d1da6d285006b32bb4e18d0b914a305f371b8b5f5a20594c37ee464eb1e59d1978db9b06bf6b642e651d8
2021-02-22 22:05:51 +00:00
Andrew Poelstra
6da00ec624 Merge pull request #124 from apoelstra/2021-02--rename-klepto
ecdsa_s2c: rename anti-klepto to anti-exfil
2021-02-10 19:06:07 +00:00
Andrew Poelstra
e354c5751d ecdsa_s2c: rename anti-klepto to anti-exfil 2021-02-09 22:47:24 +00:00
Jonas Nick
7d3497cdc4 ctime_test: move context randomization test to the end 2021-02-05 14:38:55 +00:00
PiRK
99a1cfec17 print warnings for conditional-uninitialized
This compiler flag is available for clang but not gcc.

Test plan:

```
autogen.sh
./configure
make check
CC=clang ./configure
make check
```

If a variable is used uninitialized, the warning should look something
like:
```
  CC       src/tests-tests.o
src/tests.c:4336:15: warning: variable 'recid' may be uninitialized when used here [-Wconditional-uninitialized]
        CHECK(recid >= 0 && recid < 4);
              ^~~~~
./src/util.h:54:18: note: expanded from macro 'CHECK'
    if (EXPECT(!(cond), 0)) { \
                 ^~~~
./src/util.h:41:39: note: expanded from macro 'EXPECT'
                                      ^
src/tests.c:4327:14: note: initialize the variable 'recid' to silence this warning
    int recid;
             ^
              = 0
1 warning generated.
```
2021-02-04 09:52:54 +01:00
PiRK
3d2cf6c5bd initialize variable in tests
This was detected while running the tests with the `-Wconditional-uninitialized` flag

```
./autogen.sh
CC=clang CFLAGS="-Wconditional-uninitialized" ./configure
make check
```

The resulting warning is a false positive, but setting the value to -1
ensures that the CHECK below will fail if recid is never written to.
2021-02-04 09:52:10 +01:00
Tim Ruffing
f329bba244 build: Add workaround for automake 1.13 and older
Fixes #890.
2021-02-01 22:54:09 +01:00
Jonas Nick
24d1656c32 Merge #882: Use bit ops instead of int mult for constant-time logic in gej_add_ge
e491d06b98 Use bit ops instead of int mult for constant-time logic in gej_add_ge (Tim Ruffing)

Pull request description:

ACKs for top commit:
  sipa:
    utACK e491d06b98. Seems obviously better.
  elichai:
    ACK e491d06b98
  jonasnick:
    ACK e491d06b98

Tree-SHA512: 65977d3405e3b6c184c736d46898b615689b56f7562165114429dea49c0f9feb81d021cbe196c8a813b6239254b394cc24ac8d278dab37e521843a1bb0f70c47
2021-02-01 10:23:09 +00:00
Tim Ruffing
e491d06b98 Use bit ops instead of int mult for constant-time logic in gej_add_ge 2021-01-30 19:38:24 +01:00
Jonas Nick
f8c0b57e6b Merge #864: Add support for Cirrus CI
cc2a5451dc ci: Refactor Nix shell files (Jonas Nick)
2480e55c8f ci: Remove support for Travis CI (Tim Ruffing)
2b359f1c1d ci: Enable simple cache for brewing valgrind on macOS (Tim Ruffing)
8c02e465c5 ci: Add support for Cirrus CI (Tim Ruffing)

Pull request description:

ACKs for top commit:
  sipa:
    ACK cc2a5451dc. Tested by introducing bugs: #883, #884, #885, #886, #887.
  jonasnick:
    ACK cc2a5451dc

Tree-SHA512: c9e8a891c9bda48b3fc307c2a85d2e4aa180531d084edd778d41c034769661627538ab397efac3abfc1a71c2f0730a45350dd212d499fe475c90a2a1b3c61ac8
2021-01-30 10:07:58 +00:00
Jonas Nick
cc2a5451dc ci: Refactor Nix shell files 2021-01-29 22:26:02 +01:00
Tim Ruffing
2480e55c8f ci: Remove support for Travis CI
So long, and thanks for all fish!
2021-01-29 21:54:07 +01:00
Tim Ruffing
2b359f1c1d ci: Enable simple cache for brewing valgrind on macOS 2021-01-29 21:54:07 +01:00
Tim Ruffing
8c02e465c5 ci: Add support for Cirrus CI 2021-01-29 21:54:07 +01:00
Tim Ruffing
659d0d4798 Merge #880: Add parens around ROUND_TO_ALIGN's parameter.
b6f649889a Add parens around ROUND_TO_ALIGN's parameter. This makes the macro robust against a hypothetical ROUND_TO_ALIGN(foo ? sizeA : size B) invocation. (Russell O'Connor)

Pull request description:

  This makes the macro robust against a hypothetical `ROUND_TO_ALIGN(foo ? sizeA : size B)` invocation.

  See also <https://wiki.sei.cmu.edu/confluence/display/c/PRE01-C.+Use+parentheses+within+macros+around+parameter+names>.

ACKs for top commit:
  sipa:
    ACK b6f649889a. This is the way.
  jonasnick:
    utACK b6f649889a
  real-or-random:
    utACK b6f649889a

Tree-SHA512: 6a2685f959e8ae472259e5ea75fe12e8e6213f56f5aec7603a896c294e6a8833caae25c412607d9c9a3125370a7765a3e506127b101a1b87203f95e326f6c6c6
2021-01-26 09:39:00 +01:00
Russell O'Connor
b6f649889a Add parens around ROUND_TO_ALIGN's parameter.
This makes the macro robust against a hypothetical ROUND_TO_ALIGN(foo ? sizeA : size B) invocation.
2021-01-25 11:43:45 -05:00
Jonas Nick
a4abaab793 Merge #877: Add missing secp256k1_ge_set_gej_var decl.
482e4a9cfc Add missing secp256k1_ge_set_gej_var decl. (Russell O'Connor)

Pull request description:

ACKs for top commit:
  sipa:
    utACK 482e4a9cfc
  real-or-random:
    utACK 482e4a9cfc
  jonasnick:
    ACK 482e4a9cfc

Tree-SHA512: 02195390fb79f08bcfd655dc56115ea37df42c1ad8f1123b26e7426e387d9658a3bb18fe9951140fc4dd78ce222b84d8b75ce77aec884675e0c26a2005dd2ddc
2021-01-25 14:00:47 +00:00
Jonas Nick
5671e5f3fd Merge #874: Remove underscores from header defs.
fb390c5299 Remove underscores from header defs. This makes them consistent with other files and avoids reserved identifiers. (Russell O'Connor)

Pull request description:

ACKs for top commit:
  real-or-random:
    utACK fb390c5299
  jonasnick:
    ACK fb390c5299

Tree-SHA512: f49da79c0a90d1e82494821e7cf6f61c66bc377a3f37b2d4787ef19d2126e000627bfe4a76aa1c5bfffeb1382054aa824a7e9ab5d73c19d876b0828722c73854
2021-01-25 13:57:43 +00:00
Jonas Nick
db726782fa Merge #878: Remove unused secp256k1_fe_inv_all_var
75d2ae149e Remove unused secp256k1_fe_inv_all_var (Pieter Wuille)

Pull request description:

ACKs for top commit:
  practicalswift:
    cr ACK 75d2ae149e: patch looks correct
  real-or-random:
    utACK 75d2ae149e
  jonasnick:
    utACK 75d2ae149e

Tree-SHA512: 6f548a436c6dcb275493e73e6afa23fd1b79392cc3071878f98735732ac9c93971e5c92736c3fe50eaae90a200e1a435e9be9f14d1a69251c83876a6e3c46d41
2021-01-25 13:40:00 +00:00
Jonas Nick
b732701faa Merge #875: Avoid casting (void**) values.
2730618604 Avoid casting (void**) values. Replaced with an expression that only casts (void*) values. (Russell O'Connor)

Pull request description:

ACKs for top commit:
  sipa:
    utACK 2730618604
  real-or-random:
    utACK 2730618604
  jonasnick:
    utACK 2730618604

Tree-SHA512: bdc1e9eefa10f79b744ef6ae83f379faff7bce9fb428c3bcfcc3f6e4e252e5c6543efbe0f84760709850948cbc8a432772c76a6c5f6b8cd18cb2d862b324912d
2021-01-25 13:36:01 +00:00
Pieter Wuille
9570f674cc Avoid passing out-of-bound pointers to 0-size memcpy
Doing so could be considered UB in a strict reading of the standard.
Avoid it.
2021-01-23 21:56:43 -08:00
Pieter Wuille
75d2ae149e Remove unused secp256k1_fe_inv_all_var 2021-01-23 20:16:51 -08:00
Russell O'Connor
482e4a9cfc Add missing secp256k1_ge_set_gej_var decl. 2021-01-23 19:12:19 -05:00
Russell O'Connor
2730618604 Avoid casting (void**) values.
Replaced with an expression that only casts (void*) values.
2021-01-23 15:22:54 -05:00
Russell O'Connor
fb390c5299 Remove underscores from header defs.
This makes them consistent with other files and avoids reserved identifiers.
2021-01-23 14:48:35 -05:00
Jonas Nick
ed69ea79b4 Merge #98: Add contrib/sync-upstream.sh script to automate syncing PRs
7eeacd7725 Add contrib/sync-upstream.sh script to automate merging upstream PRs (Jonas Nick)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 7eeacd7725  The code looks fine. I haven't tested this script but it's not the end of the world if the script has a bug.

Tree-SHA512: d2e0128980538f4e1f20ce3709d1464e82e2d0d89e6faafa157f627cea2919cc3d2a578daf73b93624fa61ecb74891b547d303471afb4f865130b7cd094cd0d0
2021-01-14 19:44:40 +00:00
Jonas Nick
7eeacd7725 Add contrib/sync-upstream.sh script to automate merging upstream PRs 2021-01-14 15:17:18 +00:00
Tim Ruffing
f2d9aeae6d Merge #862: Autoconf improvements
3c15130709 Improve CC_FOR_BUILD detection (Tim Ruffing)
47802a4762 Restructure and tidy configure.ac (Tim Ruffing)
252c19dfc6 Ask brew for valgrind include path (Tim Ruffing)

Pull request description:

  See individual commit messages. These are improvements in preparation of the switch to Cirrus CI. (Maybe I'll just open a PR on top of this one.)

  The first commit made the difference between successful build https://cirrus-ci.com/task/6740575057608704 and unsuccessful build https://cirrus-ci.com/task/4909571074424832.

  I've tested the second commit without cross-compilation and with cross-compilation for android (https://github.com/bitcoin-core/secp256k1/issues/621#issuecomment-495703399)

  When working on the autoconf stuff, I noticed two things that I just want to write down here:
   - At some point we should update [build-aux/m4/ax_prog_cc_for_build.m4](https://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html). This is outdated, and [there have been a lot of fixes](https://github.com/autoconf-archive/autoconf-archive/pull/207) But the latest version is [broken](https://lists.gnu.org/archive/html/autoconf-archive-maintainers/2020-06/msg00002.html), so now is probably not the time.
   - The latest autoconf 2.70 deprecates `AC_PROG_CC_C89`. It's not needed anymore because `AC_PROG_CC` cares about testing for version support. This makes autoconf 2.70 output a warning that we should probably just ignore. We don't want to force users onto 2.70...

ACKs for top commit:
  sipa:
    utACK 3c15130709
  jonasnick:
    utACK 3c15130 makes sense (with my very basic understanding of autoconf)

Tree-SHA512: 595b9de316374c2213f1340cddaa22eb3190b01fa99aa6ae26e77804df41e7ecf96a09e03c28e8f8b9fd04e211e4ee2f78f1e5a7995143c84f99d2e16d4f0260
2021-01-12 15:38:52 +01:00
Tim Ruffing
328aaef22a Merge #845: Extract the secret key from a keypair
33cb3c2b1f Add secret key extraction from keypair to constant time tests (Elichai Turkel)
36d9dc1e8e Add seckey extraction from keypair to the extrakeys tests (Elichai Turkel)
fc96aa73f5 Add a function to extract the secretkey from a keypair (Elichai Turkel)

Pull request description:

  With schnorrsig if you need to tweak the secret key (for BIP32) you must use the keypair API to get compatible secret/public keys which you do by calling `secp256k1_keypair_xonly_tweak_add()`, but after that there's no currently a way to extract the secret key back for storage.
  so I added a `secp256k1_keypair_seckey` function to extract the key

ACKs for top commit:
  jonasnick:
    ACK 33cb3c2b1f
  real-or-random:
    ACK 33cb3c2b1f code inspection, tests pass

Tree-SHA512: 11212db38c8b87a87e2dc35c4d6993716867b45215b94b20522b1b3164ca63d4c6bf5192a6bff0e9267b333779cc8164844c56669a94e9be72df9ef025ffcfd4
2021-01-12 10:56:14 +01:00
Tim Ruffing
3c15130709 Improve CC_FOR_BUILD detection
This commits simply uses CC as CC_FOR_BUILD and the same for
corresponding flags if we're not cross-compiling. This has a number of
benefits in this common case:
 - It avoids strange cases where very old compilers are used (#768).
 - Flags are consistently set for CC and CC_FOR_BUILD.
 - ./configure is faster.
 - You get compiler x consistently if you set CC=x; we got this wrong
   in CI in the past.

./configure warns if a _FOR_BUILD variable is set but ignored because
we're not cross-compiling.

The change exposed that //-style comments are used in gen_context.c,
which is also fixed by this commit.

This commit also reorganizes code in configure.ac to have a cleaner
separation of sections.
2021-01-08 16:09:04 +01:00
Tim Ruffing
47802a4762 Restructure and tidy configure.ac
No behavioral changes.
2021-01-08 15:29:40 +01:00
Tim Ruffing
252c19dfc6 Ask brew for valgrind include path
Valgrind is typically installed using brew on macOS. This commit
makes ./configure detect this case set the appropriate include
directory (in the same way as we already do for openssl and gmp).
2021-01-08 14:24:34 +01:00
Tim Ruffing
8c727b9087 Merge #860: fixed trivial typo
b7bc3a4aaa fixed typo (Ferdinando M. Ametrano)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK b7bc3a4aaa
  elichai:
    ACK b7bc3a4aaa

Tree-SHA512: 6c1889f095607a2f293ffe00359c03e63cfca572b0a17388b83ece54f24ec61ac12d6eb967a47d2dccd54de991383923a07c5cced320c0a96a36a28674cf739c
2021-01-08 14:16:38 +01:00
Tim Ruffing
cfac088e1b Merge #119: Remove repeated schnorr flag from travis config
96c83a83dc Remove repeated schnorr flag from travis config (Jesse Posner)

Pull request description:

  The `SCHNORRSIG=no` flag is set twice for `global` in `travis.yml`. This PR removes the duplicated flag.

ACKs for top commit:
  real-or-random:
    ACK 96c83a83dc

Tree-SHA512: 15b893e6ad22009e92ebd78389dc0939cec5ada7e84b7236d58f1426b9517333c544a6bea108a4b8921f2608a811269a5105a8eb5cb9010c5ee0945456656224
2021-01-06 11:00:34 +01:00
Jesse Posner
96c83a83dc Remove repeated schnorr flag from travis config 2021-01-05 16:09:04 -08:00
Andrew Poelstra
d2b6740688 Merge pull request #118 from jonasnick/clarify-rangeproof-rewind
rangeproof: clarify rewind outlen argument
2021-01-05 19:16:09 +00:00
Jonas Nick
41d6963bc1 rangeproof: clarify rewind outlen argument 2021-01-05 13:42:58 +00:00
Tim Ruffing
673e551f4d Merge #111: Add ECDSA sign-to-contract module
47efb5e39a ecdsa-s2c: add ctime tests (Andrew Poelstra)
396b558273 ecdsa-s2c: add anti-klepto protocol (Andrew Poelstra)
290dee566e ecdsa-s2c: add actual sign-to-contract functionality (Andrew Poelstra)
8e46cac5b3 ecdsa-s2c: block in module (Andrew Poelstra)
826bd04b43 add eccommit functionality (Andrew Poelstra)

Pull request description:

  This is a backport and rebase of https://github.com/bitcoin-core/secp256k1/pull/669

ACKs for top commit:
  jonasnick:
    ACK 47efb5e39a
  real-or-random:
    ACK 47efb5e39a

Tree-SHA512: e1f3ee3985bc77197eb57c03884b5d4a5f8733523bba50e11309f86388471c6265b7241e9856e1b80a88f4c268f2826c0394e26161292aa438b2246a1ad86aa1
2021-01-04 14:56:47 +01:00
Ferdinando M. Ametrano
b7bc3a4aaa fixed typo 2020-12-22 22:31:29 +01:00
Andrew Poelstra
47efb5e39a ecdsa-s2c: add ctime tests 2020-12-21 20:50:19 +00:00
Andrew Poelstra
396b558273 ecdsa-s2c: add anti-klepto protocol
Co-authored-by: Marko Bencun <mbencun+pgp@gmail.com>
Co-authored-by: Jonas Nick <jonasd.nick@gmail.com>
2020-12-21 20:50:19 +00:00
Andrew Poelstra
290dee566e ecdsa-s2c: add actual sign-to-contract functionality
Co-authored-by: Marko Bencun <mbencun+pgp@gmail.com>
Co-authored-by: Jonas Nick <jonasd.nick@gmail.com>
2020-12-21 20:50:17 +00:00
Andrew Poelstra
8e46cac5b3 ecdsa-s2c: block in module
Co-authored-by: Marko Bencun <mbencun+pgp@gmail.com>
Co-authored-by: Jonas Nick <jonasd.nick@gmail.com>
2020-12-21 20:49:41 +00:00
Andrew Poelstra
826bd04b43 add eccommit functionality
Co-authored-by: Marko Bencun <mbencun+pgp@gmail.com>
Co-authored-by: Jonas Nick <jonasd.nick@gmail.com>
2020-12-21 20:49:41 +00:00
Elichai Turkel
33cb3c2b1f Add secret key extraction from keypair to constant time tests 2020-12-19 11:01:36 +02:00
Elichai Turkel
36d9dc1e8e Add seckey extraction from keypair to the extrakeys tests 2020-12-19 11:00:25 +02:00
Elichai Turkel
fc96aa73f5 Add a function to extract the secretkey from a keypair 2020-12-19 11:00:25 +02:00
Jonas Nick
98dac87839 Merge #858: Fix insecure links
07aa4c70ff Fix insecure links (Dimitris Apostolou)

Pull request description:

ACKs for top commit:
  sipa:
    ACK 07aa4c70ff. Verified all the modified links.
  jonasnick:
    ACK 07aa4c70ff

Tree-SHA512: d1240aab5e40a204c75fca1049b99af9890684df7dbce4167b1904f73424c8a4f84ed85a8cc315501f1b7cf1674d744232b9f2126dff31e3d47e4f3fc65764d4
2020-12-18 18:33:03 +00:00
Dimitris Apostolou
07aa4c70ff Fix insecure links 2020-12-18 00:24:22 +02:00
Tim Ruffing
b61f9da54e Merge #857: docs: fix simple typo, dependecy -> dependency
18aadf9d28 docs: fix simple typo, dependecy -> dependency (Tim Gates)

Pull request description:

  There is a small typo in src/group_impl.h.

  Should read `dependency` rather than `dependecy`.

ACKs for top commit:
  real-or-random:
    ACK 18aadf9d28

Tree-SHA512: 3529f43bcc87ea8940ecf5af765951f61d97d1efa86fd8abc29e32b600fd449165a94a2fa525bc6b3d9a7d8aa6e691cc4d42033537b196ba166a867e6db7f397
2020-12-09 18:05:58 +01:00
Tim Gates
18aadf9d28 docs: fix simple typo, dependecy -> dependency
There is a small typo in src/group_impl.h.

Should read `dependency` rather than `dependecy`.
2020-12-08 21:45:13 +11:00
Jonas Nick
2d9e7175c6 Merge #852: Add sage script for generating scalar_split_lambda constants
329a2e0a3f sage: Add script for generating scalar_split_lambda constants (Tim Ruffing)
f554dfc708 sage: Reorganize files (Tim Ruffing)

Pull request description:

ACKs for top commit:
  sipa:
    ACK 329a2e0a3f

Tree-SHA512: d41fe5eba332f48af0b800778aa076925c4e8e95ec21c4371a500ddd6088b6d52961bdb93f7ce2b127e18095667dbb966a0d14191177f0d0e78dfaf55271d5e2
2020-12-07 21:49:32 +00:00
Tim Ruffing
dc6e5c3a5c Merge #854: Rename msg32 to msghash32 in ecdsa_sign/verify and add explanation
6e85d675aa Rename tweak to tweak32 in public API (Jonas Nick)
f587f04e35 Rename msg32 to msghash32 in ecdsa_sign/verify and add explanation (Jonas Nick)

Pull request description:

  This fixes #307 if there's nothing else that's confusing.

ACKs for top commit:
  real-or-random:
    ACK 6e85d675aa I inspected the diff

Tree-SHA512: 1b0dc9dfffd497058dc39c962a512ed6d7f89218020fef9d2c03aaae1aefbf272b918c4fe6503434b62547714855fe1b8b89f2366f3ae6cde16143207c9e6b86
2020-12-07 22:10:47 +01:00
Jonas Nick
6e85d675aa Rename tweak to tweak32 in public API 2020-12-04 14:16:43 +00:00
Jonas Nick
f587f04e35 Rename msg32 to msghash32 in ecdsa_sign/verify and add explanation 2020-12-04 14:12:38 +00:00
Tim Ruffing
329a2e0a3f sage: Add script for generating scalar_split_lambda constants 2020-12-03 11:56:09 +01:00
Tim Ruffing
f554dfc708 sage: Reorganize files
* Move curve parameters to separate file
 * Rename main prover script for clarity
2020-11-25 13:50:40 +01:00
Peter Dettman
b53e0cd61f Avoid overly-wide multiplications 2020-09-10 15:19:15 +07:00
247 changed files with 69963 additions and 12377 deletions

95
.cirrus.yml Normal file
View File

@@ -0,0 +1,95 @@
env:
### cirrus config
CIRRUS_CLONE_DEPTH: 1
### compiler options
HOST:
WRAPPER_CMD:
# Specific warnings can be disabled with -Wno-error=foo.
# -pedantic-errors is not equivalent to -Werror=pedantic and thus not implied by -Werror according to the GCC manual.
WERROR_CFLAGS: -Werror -pedantic-errors
MAKEFLAGS: -j4
BUILD: check
### secp256k1 config
ECMULTWINDOW: auto
ECMULTGENPRECISION: auto
ASM: no
WIDEMUL: auto
WITH_VALGRIND: yes
EXTRAFLAGS:
### secp256k1 modules
EXPERIMENTAL: no
ECDH: no
RECOVERY: no
SCHNORRSIG: no
ELLSWIFT: no
### test options
SECP256K1_TEST_ITERS:
BENCH: yes
SECP256K1_BENCH_ITERS: 2
CTIMETESTS: yes
# Compile and run the tests
EXAMPLES: yes
cat_logs_snippet: &CAT_LOGS
always:
cat_tests_log_script:
- cat tests.log || true
cat_noverify_tests_log_script:
- cat noverify_tests.log || true
cat_exhaustive_tests_log_script:
- cat exhaustive_tests.log || true
cat_ctime_tests_log_script:
- cat ctime_tests.log || true
cat_bench_log_script:
- cat bench.log || true
cat_config_log_script:
- cat config.log || true
cat_test_env_script:
- cat test_env.log || true
cat_ci_env_script:
- env
linux_arm64_container_snippet: &LINUX_ARM64_CONTAINER
env_script:
- env | tee /tmp/env
build_script:
- DOCKER_BUILDKIT=1 docker build --file "ci/linux-debian.Dockerfile" --tag="ci_secp256k1_arm"
- docker image prune --force # Cleanup stale layers
test_script:
- docker run --rm --mount "type=bind,src=./,dst=/ci_secp256k1" --env-file /tmp/env --replace --name "ci_secp256k1_arm" "ci_secp256k1_arm" bash -c "cd /ci_secp256k1/ && ./ci/ci.sh"
task:
name: "ARM64: Linux (Debian stable)"
persistent_worker:
labels:
type: arm64
env:
ECDH: yes
RECOVERY: yes
SCHNORRSIG: yes
ELLSWIFT: yes
matrix:
# Currently only gcc-snapshot, the other compilers are tested on GHA with QEMU
- env: { CC: 'gcc-snapshot' }
<< : *LINUX_ARM64_CONTAINER
<< : *CAT_LOGS
task:
name: "ARM64: Linux (Debian stable), Valgrind"
persistent_worker:
labels:
type: arm64
env:
ECDH: yes
RECOVERY: yes
SCHNORRSIG: yes
ELLSWIFT: yes
WRAPPER_CMD: 'valgrind --error-exitcode=42'
SECP256K1_TEST_ITERS: 2
matrix:
- env: { CC: 'gcc' }
- env: { CC: 'clang' }
- env: { CC: 'gcc-snapshot' }
- env: { CC: 'clang-snapshot' }
<< : *LINUX_ARM64_CONTAINER
<< : *CAT_LOGS

2
.gitattributes vendored Normal file
View File

@@ -0,0 +1,2 @@
src/precomputed_ecmult.c linguist-generated
src/precomputed_ecmult_gen.c linguist-generated

View File

@@ -0,0 +1,33 @@
name: "Install Valgrind"
description: "Install Homebrew's Valgrind package and cache it."
runs:
using: "composite"
steps:
- run: |
brew tap LouisBrunner/valgrind
brew fetch --HEAD LouisBrunner/valgrind/valgrind
echo "CI_HOMEBREW_CELLAR_VALGRIND=$(brew --cellar valgrind)" >> "$GITHUB_ENV"
shell: bash
- run: |
sw_vers > valgrind_fingerprint
brew --version >> valgrind_fingerprint
git -C "$(brew --cache)/valgrind--git" rev-parse HEAD >> valgrind_fingerprint
cat valgrind_fingerprint
shell: bash
- uses: actions/cache@v3
id: cache
with:
path: ${{ env.CI_HOMEBREW_CELLAR_VALGRIND }}
key: ${{ github.job }}-valgrind-${{ hashFiles('valgrind_fingerprint') }}
- if: steps.cache.outputs.cache-hit != 'true'
run: |
brew install --HEAD LouisBrunner/valgrind/valgrind
shell: bash
- if: steps.cache.outputs.cache-hit == 'true'
run: |
brew link valgrind
shell: bash

View File

@@ -0,0 +1,49 @@
name: 'Run in Docker with environment'
description: 'Run a command in a Docker container, while passing explicitly set environment variables into the container.'
inputs:
dockerfile:
description: 'A Dockerfile that defines an image'
required: true
tag:
description: 'A tag of an image'
required: true
command:
description: 'A command to run in a container'
required: false
default: ./ci/ci.sh
runs:
using: "composite"
steps:
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v5
id: main_builder
continue-on-error: true
with:
context: .
file: ${{ inputs.dockerfile }}
tags: ${{ inputs.tag }}
load: true
cache-from: type=gha
- uses: docker/build-push-action@v5
id: retry_builder
if: steps.main_builder.outcome == 'failure'
with:
context: .
file: ${{ inputs.dockerfile }}
tags: ${{ inputs.tag }}
load: true
cache-from: type=gha
- # Tell Docker to pass environment variables in `env` into the container.
run: >
docker run \
$(echo '${{ toJSON(env) }}' | jq -r 'keys[] | "--env \(.) "') \
--volume ${{ github.workspace }}:${{ github.workspace }} \
--workdir ${{ github.workspace }} \
${{ inputs.tag }} bash -c "
git config --global --add safe.directory ${{ github.workspace }}
${{ inputs.command }}
"
shell: bash

915
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,915 @@
name: CI
on:
pull_request:
push:
branches:
- '**'
tags-ignore:
- '**'
concurrency:
group: ${{ github.event_name != 'pull_request' && github.run_id || github.ref }}
cancel-in-progress: true
env:
### compiler options
HOST:
WRAPPER_CMD:
# Specific warnings can be disabled with -Wno-error=foo.
# -pedantic-errors is not equivalent to -Werror=pedantic and thus not implied by -Werror according to the GCC manual.
WERROR_CFLAGS: '-Werror -pedantic-errors'
MAKEFLAGS: '-j4'
BUILD: 'check'
### secp256k1 config
ECMULTWINDOW: 'auto'
ECMULTGENPRECISION: 'auto'
ASM: 'no'
WIDEMUL: 'auto'
WITH_VALGRIND: 'yes'
EXTRAFLAGS:
### secp256k1 modules
EXPERIMENTAL: 'no'
ECDH: 'no'
RECOVERY: 'no'
SCHNORRSIG: 'no'
ELLSWIFT: 'no'
ECDSA_S2C: 'no'
GENERATOR: 'no'
RANGEPROOF: 'no'
WHITELIST: 'no'
MUSIG: 'no'
ECDSAADAPTOR: 'no'
BPPP: 'no'
SCHNORRSIG_HALFAGG: 'no'
FROST: 'no'
### test options
SECP256K1_TEST_ITERS:
BENCH: 'yes'
SECP256K1_BENCH_ITERS: 2
CTIMETESTS: 'yes'
# Compile and run the examples.
EXAMPLES: 'yes'
jobs:
docker_cache:
name: "Build Docker image"
runs-on: ubuntu-latest
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
# See: https://github.com/moby/buildkit/issues/3969.
driver-opts: |
network=host
- name: Build container
uses: docker/build-push-action@v5
with:
file: ./ci/linux-debian.Dockerfile
tags: linux-debian-image
cache-from: type=gha
cache-to: type=gha,mode=min
linux_debian:
name: "x86_64: Linux (Debian stable)"
runs-on: ubuntu-latest
needs: docker_cache
strategy:
fail-fast: false
matrix:
configuration:
- env_vars: { WIDEMUL: 'int64', RECOVERY: 'yes' }
- env_vars: { WIDEMUL: 'int64', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', FROST: 'yes' }
- env_vars: { WIDEMUL: 'int128' }
- env_vars: { WIDEMUL: 'int128_struct', ELLSWIFT: 'yes' }
- env_vars: { WIDEMUL: 'int128', RECOVERY: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes' }
- env_vars: { WIDEMUL: 'int128', ECDH: 'yes', SCHNORRSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', FROST: 'yes' }
- env_vars: { WIDEMUL: 'int128', ASM: 'x86_64', ELLSWIFT: 'yes' }
- env_vars: { RECOVERY: 'yes', SCHNORRSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', FROST: 'yes' }
- env_vars: { CTIMETESTS: 'no', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', FROST: 'yes', CPPFLAGS: '-DVERIFY' }
- env_vars: { BUILD: 'distcheck', WITH_VALGRIND: 'no', CTIMETESTS: 'no', BENCH: 'no' }
- env_vars: { CPPFLAGS: '-DDETERMINISTIC' }
- env_vars: { CFLAGS: '-O0', CTIMETESTS: 'no' }
- env_vars: { CFLAGS: '-O1', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes' }
- env_vars: { ECMULTGENPRECISION: 2, ECMULTWINDOW: 2 }
- env_vars: { ECMULTGENPRECISION: 8, ECMULTWINDOW: 4 }
cc:
- 'gcc'
- 'clang'
- 'gcc-snapshot'
- 'clang-snapshot'
env:
CC: ${{ matrix.cc }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: CI script
env: ${{ matrix.configuration.env_vars }}
uses: ./.github/actions/run-in-docker-action
with:
dockerfile: ./ci/linux-debian.Dockerfile
tag: linux-debian-image
- run: cat tests.log || true
if: ${{ always() }}
- run: cat noverify_tests.log || true
if: ${{ always() }}
- run: cat exhaustive_tests.log || true
if: ${{ always() }}
- run: cat ctime_tests.log || true
if: ${{ always() }}
- run: cat bench.log || true
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
i686_debian:
name: "i686: Linux (Debian stable)"
runs-on: ubuntu-latest
needs: docker_cache
strategy:
fail-fast: false
matrix:
cc:
- 'i686-linux-gnu-gcc'
- 'clang --target=i686-pc-linux-gnu -isystem /usr/i686-linux-gnu/include'
env:
HOST: 'i686-linux-gnu'
ECDH: 'yes'
RECOVERY: 'yes'
SCHNORRSIG: 'yes'
ELLSWIFT: 'yes'
EXPERIMENTAL: 'yes'
ECDSA_S2C: 'yes'
RANGEPROOF: 'yes'
WHITELIST: 'yes'
GENERATOR: 'yes'
MUSIG: 'yes'
ECDSAADAPTOR: 'yes'
BPPP: 'yes'
SCHNORRSIG_HALFAGG: 'yes'
FROST: 'yes'
CC: ${{ matrix.cc }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: CI script
uses: ./.github/actions/run-in-docker-action
with:
dockerfile: ./ci/linux-debian.Dockerfile
tag: linux-debian-image
- run: cat tests.log || true
if: ${{ always() }}
- run: cat noverify_tests.log || true
if: ${{ always() }}
- run: cat exhaustive_tests.log || true
if: ${{ always() }}
- run: cat ctime_tests.log || true
if: ${{ always() }}
- run: cat bench.log || true
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
s390x_debian:
name: "s390x (big-endian): Linux (Debian stable, QEMU)"
runs-on: ubuntu-latest
needs: docker_cache
env:
WRAPPER_CMD: 'qemu-s390x'
SECP256K1_TEST_ITERS: 16
HOST: 's390x-linux-gnu'
WITH_VALGRIND: 'no'
ECDH: 'yes'
RECOVERY: 'yes'
SCHNORRSIG: 'yes'
ELLSWIFT: 'yes'
EXPERIMENTAL: 'yes'
ECDSA_S2C: 'yes'
RANGEPROOF: 'yes'
WHITELIST: 'yes'
GENERATOR: 'yes'
MUSIG: 'yes'
ECDSAADAPTOR: 'yes'
BPPP: 'yes'
SCHNORRSIG_HALFAGG: 'yes'
FROST: 'yes'
CTIMETESTS: 'no'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: CI script
uses: ./.github/actions/run-in-docker-action
with:
dockerfile: ./ci/linux-debian.Dockerfile
tag: linux-debian-image
- run: cat tests.log || true
if: ${{ always() }}
- run: cat noverify_tests.log || true
if: ${{ always() }}
- run: cat exhaustive_tests.log || true
if: ${{ always() }}
- run: cat ctime_tests.log || true
if: ${{ always() }}
- run: cat bench.log || true
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
arm32_debian:
name: "ARM32: Linux (Debian stable, QEMU)"
runs-on: ubuntu-latest
needs: docker_cache
strategy:
fail-fast: false
matrix:
configuration:
- env_vars: {}
- env_vars: { EXPERIMENTAL: 'yes', ASM: 'arm32' }
env:
WRAPPER_CMD: 'qemu-arm'
SECP256K1_TEST_ITERS: 16
HOST: 'arm-linux-gnueabihf'
WITH_VALGRIND: 'no'
ECDH: 'yes'
RECOVERY: 'yes'
SCHNORRSIG: 'yes'
ELLSWIFT: 'yes'
EXPERIMENTAL: 'yes'
ECDSA_S2C: 'yes'
GENERATOR: 'yes'
RANGEPROOF: 'yes'
WHITELIST: 'yes'
MUSIG: 'yes'
ECDSAADAPTOR: 'yes'
BPPP: 'yes'
SCHNORRSIG_HALFAGG: 'yes'
FROST: 'yes'
CTIMETESTS: 'no'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: CI script
env: ${{ matrix.configuration.env_vars }}
uses: ./.github/actions/run-in-docker-action
with:
dockerfile: ./ci/linux-debian.Dockerfile
tag: linux-debian-image
- run: cat tests.log || true
if: ${{ always() }}
- run: cat noverify_tests.log || true
if: ${{ always() }}
- run: cat exhaustive_tests.log || true
if: ${{ always() }}
- run: cat ctime_tests.log || true
if: ${{ always() }}
- run: cat bench.log || true
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
arm64_debian:
name: "ARM64: Linux (Debian stable, QEMU)"
runs-on: ubuntu-latest
needs: docker_cache
env:
WRAPPER_CMD: 'qemu-aarch64'
SECP256K1_TEST_ITERS: 16
HOST: 'aarch64-linux-gnu'
WITH_VALGRIND: 'no'
ECDH: 'yes'
RECOVERY: 'yes'
SCHNORRSIG: 'yes'
ELLSWIFT: 'yes'
EXPERIMENTAL: 'yes'
ECDSA_S2C: 'yes'
GENERATOR: 'yes'
RANGEPROOF: 'yes'
WHITELIST: 'yes'
MUSIG: 'yes'
ECDSAADAPTOR: 'yes'
BPPP: 'yes'
SCHNORRSIG_HALFAGG: 'yes'
FROST: 'yes'
CTIMETESTS: 'no'
strategy:
fail-fast: false
matrix:
configuration:
- env_vars: { } # gcc
- env_vars: # clang
CC: 'clang --target=aarch64-linux-gnu'
- env_vars: # clang-snapshot
CC: 'clang-snapshot --target=aarch64-linux-gnu'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: CI script
env: ${{ matrix.configuration.env_vars }}
uses: ./.github/actions/run-in-docker-action
with:
dockerfile: ./ci/linux-debian.Dockerfile
tag: linux-debian-image
- run: cat tests.log || true
if: ${{ always() }}
- run: cat noverify_tests.log || true
if: ${{ always() }}
- run: cat exhaustive_tests.log || true
if: ${{ always() }}
- run: cat ctime_tests.log || true
if: ${{ always() }}
- run: cat bench.log || true
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
ppc64le_debian:
name: "ppc64le: Linux (Debian stable, QEMU)"
runs-on: ubuntu-latest
needs: docker_cache
env:
WRAPPER_CMD: 'qemu-ppc64le'
SECP256K1_TEST_ITERS: 16
HOST: 'powerpc64le-linux-gnu'
WITH_VALGRIND: 'no'
ECDH: 'yes'
RECOVERY: 'yes'
SCHNORRSIG: 'yes'
ELLSWIFT: 'yes'
EXPERIMENTAL: 'yes'
ECDSA_S2C: 'yes'
GENERATOR: 'yes'
RANGEPROOF: 'yes'
WHITELIST: 'yes'
MUSIG: 'yes'
ECDSAADAPTOR: 'yes'
BPPP: 'yes'
SCHNORRSIG_HALFAGG: 'yes'
FROST: 'yes'
CTIMETESTS: 'no'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: CI script
uses: ./.github/actions/run-in-docker-action
with:
dockerfile: ./ci/linux-debian.Dockerfile
tag: linux-debian-image
- run: cat tests.log || true
if: ${{ always() }}
- run: cat noverify_tests.log || true
if: ${{ always() }}
- run: cat exhaustive_tests.log || true
if: ${{ always() }}
- run: cat ctime_tests.log || true
if: ${{ always() }}
- run: cat bench.log || true
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
valgrind_debian:
name: "Valgrind (memcheck)"
runs-on: ubuntu-latest
needs: docker_cache
strategy:
fail-fast: false
matrix:
configuration:
- env_vars: { CC: 'clang', ASM: 'auto' }
- env_vars: { CC: 'i686-linux-gnu-gcc', HOST: 'i686-linux-gnu', ASM: 'auto' }
- env_vars: { CC: 'clang', ASM: 'no', ECMULTGENPRECISION: 2, ECMULTWINDOW: 2 }
- env_vars: { CC: 'i686-linux-gnu-gcc', HOST: 'i686-linux-gnu', ASM: 'no', ECMULTGENPRECISION: 2, ECMULTWINDOW: 2 }
env:
# The `--error-exitcode` is required to make the test fail if valgrind found errors,
# otherwise it will return 0 (https://www.valgrind.org/docs/manual/manual-core.html).
WRAPPER_CMD: 'valgrind --error-exitcode=42'
ECDH: 'yes'
RECOVERY: 'yes'
SCHNORRSIG: 'yes'
ELLSWIFT: 'yes'
EXPERIMENTAL: 'yes'
ECDSA_S2C: 'yes'
GENERATOR: 'yes'
RANGEPROOF: 'yes'
WHITELIST: 'yes'
MUSIG: 'yes'
ECDSAADAPTOR: 'yes'
BPPP: 'yes'
SCHNORRSIG_HALFAGG: 'yes'
FROST: 'yes'
CTIMETESTS: 'no'
SECP256K1_TEST_ITERS: 2
steps:
- name: Checkout
uses: actions/checkout@v4
- name: CI script
env: ${{ matrix.configuration.env_vars }}
uses: ./.github/actions/run-in-docker-action
with:
dockerfile: ./ci/linux-debian.Dockerfile
tag: linux-debian-image
- run: cat tests.log || true
if: ${{ always() }}
- run: cat noverify_tests.log || true
if: ${{ always() }}
- run: cat exhaustive_tests.log || true
if: ${{ always() }}
- run: cat ctime_tests.log || true
if: ${{ always() }}
- run: cat bench.log || true
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
sanitizers_debian:
name: "UBSan, ASan, LSan"
runs-on: ubuntu-latest
needs: docker_cache
strategy:
fail-fast: false
matrix:
configuration:
- env_vars: { CC: 'clang', ASM: 'auto' }
- env_vars: { CC: 'i686-linux-gnu-gcc', HOST: 'i686-linux-gnu', ASM: 'auto' }
- env_vars: { CC: 'clang', ASM: 'no', ECMULTGENPRECISION: 2, ECMULTWINDOW: 2 }
- env_vars: { CC: 'i686-linux-gnu-gcc', HOST: 'i686-linux-gnu', ASM: 'no', ECMULTGENPRECISION: 2, ECMULTWINDOW: 2 }
env:
ECDH: 'yes'
RECOVERY: 'yes'
SCHNORRSIG: 'yes'
ELLSWIFT: 'yes'
EXPERIMENTAL: 'yes'
ECDSA_S2C: 'yes'
GENERATOR: 'yes'
RANGEPROOF: 'yes'
WHITELIST: 'yes'
MUSIG: 'yes'
ECDSAADAPTOR: 'yes'
BPPP: 'yes'
SCHNORRSIG_HALFAGG: 'yes'
FROST: 'yes'
CTIMETESTS: 'no'
CFLAGS: '-fsanitize=undefined,address -g'
UBSAN_OPTIONS: 'print_stacktrace=1:halt_on_error=1'
ASAN_OPTIONS: 'strict_string_checks=1:detect_stack_use_after_return=1:detect_leaks=1'
LSAN_OPTIONS: 'use_unaligned=1'
SECP256K1_TEST_ITERS: 32
steps:
- name: Checkout
uses: actions/checkout@v4
- name: CI script
env: ${{ matrix.configuration.env_vars }}
uses: ./.github/actions/run-in-docker-action
with:
dockerfile: ./ci/linux-debian.Dockerfile
tag: linux-debian-image
- run: cat tests.log || true
if: ${{ always() }}
- run: cat noverify_tests.log || true
if: ${{ always() }}
- run: cat exhaustive_tests.log || true
if: ${{ always() }}
- run: cat ctime_tests.log || true
if: ${{ always() }}
- run: cat bench.log || true
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
msan_debian:
name: "MSan"
runs-on: ubuntu-latest
needs: docker_cache
strategy:
fail-fast: false
matrix:
configuration:
- env_vars:
CFLAGS: '-fsanitize=memory -fsanitize-recover=memory -g'
- env_vars:
ECMULTGENPRECISION: 2
ECMULTWINDOW: 2
CFLAGS: '-fsanitize=memory -fsanitize-recover=memory -g -O3'
env:
ECDH: 'yes'
RECOVERY: 'yes'
SCHNORRSIG: 'yes'
ELLSWIFT: 'yes'
EXPERIMENTAL: 'yes'
ECDSA_S2C: 'yes'
GENERATOR: 'yes'
RANGEPROOF: 'yes'
WHITELIST: 'yes'
MUSIG: 'yes'
ECDSAADAPTOR: 'yes'
BPPP: 'yes'
SCHNORRSIG_HALFAGG: 'yes'
FROST: 'yes'
CTIMETESTS: 'yes'
CC: 'clang'
SECP256K1_TEST_ITERS: 32
ASM: 'no'
WITH_VALGRIND: 'no'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: CI script
env: ${{ matrix.configuration.env_vars }}
uses: ./.github/actions/run-in-docker-action
with:
dockerfile: ./ci/linux-debian.Dockerfile
tag: linux-debian-image
- run: cat tests.log || true
if: ${{ always() }}
- run: cat noverify_tests.log || true
if: ${{ always() }}
- run: cat exhaustive_tests.log || true
if: ${{ always() }}
- run: cat ctime_tests.log || true
if: ${{ always() }}
- run: cat bench.log || true
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
mingw_debian:
name: ${{ matrix.configuration.job_name }}
runs-on: ubuntu-latest
needs: docker_cache
env:
WRAPPER_CMD: 'wine'
WITH_VALGRIND: 'no'
ECDH: 'yes'
RECOVERY: 'yes'
SCHNORRSIG: 'yes'
ELLSWIFT: 'yes'
EXPERIMENTAL: 'yes'
ECDSA_S2C: 'yes'
GENERATOR: 'yes'
RANGEPROOF: 'yes'
WHITELIST: 'yes'
MUSIG: 'yes'
ECDSAADAPTOR: 'yes'
BPPP: 'yes'
SCHNORRSIG_HALFAGG: 'yes'
FROST: 'yes'
CTIMETESTS: 'no'
strategy:
fail-fast: false
matrix:
configuration:
- job_name: 'x86_64 (mingw32-w64): Windows (Debian stable, Wine)'
env_vars:
HOST: 'x86_64-w64-mingw32'
- job_name: 'i686 (mingw32-w64): Windows (Debian stable, Wine)'
env_vars:
HOST: 'i686-w64-mingw32'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: CI script
env: ${{ matrix.configuration.env_vars }}
uses: ./.github/actions/run-in-docker-action
with:
dockerfile: ./ci/linux-debian.Dockerfile
tag: linux-debian-image
- run: cat tests.log || true
if: ${{ always() }}
- run: cat noverify_tests.log || true
if: ${{ always() }}
- run: cat exhaustive_tests.log || true
if: ${{ always() }}
- run: cat ctime_tests.log || true
if: ${{ always() }}
- run: cat bench.log || true
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
macos-native:
name: "x86_64: macOS Monterey"
# See: https://github.com/actions/runner-images#available-images.
runs-on: macos-12 # Use M1 once available https://github.com/github/roadmap/issues/528
env:
CC: 'clang'
HOMEBREW_NO_AUTO_UPDATE: 1
HOMEBREW_NO_INSTALL_CLEANUP: 1
strategy:
fail-fast: false
matrix:
env_vars:
- { WIDEMUL: 'int64', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', FROST: 'yes' }
- { WIDEMUL: 'int128_struct', ECMULTGENPRECISION: 2, ECMULTWINDOW: 4 }
- { WIDEMUL: 'int128', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', FROST: 'yes' }
- { WIDEMUL: 'int128', RECOVERY: 'yes' }
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', FROST: 'yes' }
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', CC: 'gcc', FROST: 'yes' }
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', FROST: 'yes', WRAPPER_CMD: 'valgrind --error-exitcode=42', SECP256K1_TEST_ITERS: 2 }
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', FROST: 'yes', CC: 'gcc', WRAPPER_CMD: 'valgrind --error-exitcode=42', SECP256K1_TEST_ITERS: 2 }
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', FROST: 'yes', CPPFLAGS: '-DVERIFY', CTIMETESTS: 'no' }
- BUILD: 'distcheck'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Homebrew packages
run: |
brew install automake libtool gcc
ln -s $(brew --prefix gcc)/bin/gcc-?? /usr/local/bin/gcc
- name: Install and cache Valgrind
uses: ./.github/actions/install-homebrew-valgrind
- name: CI script
env: ${{ matrix.env_vars }}
run: ./ci/ci.sh
- run: cat tests.log || true
if: ${{ always() }}
- run: cat noverify_tests.log || true
if: ${{ always() }}
- run: cat exhaustive_tests.log || true
if: ${{ always() }}
- run: cat ctime_tests.log || true
if: ${{ always() }}
- run: cat bench.log || true
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
win64-native:
name: ${{ matrix.configuration.job_name }}
# See: https://github.com/actions/runner-images#available-images.
runs-on: windows-2022
strategy:
fail-fast: false
matrix:
configuration:
- job_name: 'x64 (MSVC): Windows (VS 2022, shared)'
cmake_options: '-A x64 -DBUILD_SHARED_LIBS=ON'
- job_name: 'x64 (MSVC): Windows (VS 2022, static)'
cmake_options: '-A x64 -DBUILD_SHARED_LIBS=OFF'
- job_name: 'x64 (MSVC): Windows (VS 2022, int128_struct)'
cmake_options: '-A x64 -DSECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY=int128_struct'
- job_name: 'x64 (MSVC): Windows (VS 2022, int128_struct with __(u)mulh)'
cmake_options: '-A x64 -DSECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY=int128_struct'
cpp_flags: '/DSECP256K1_MSVC_MULH_TEST_OVERRIDE'
- job_name: 'x86 (MSVC): Windows (VS 2022)'
cmake_options: '-A Win32'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Generate buildsystem
run: cmake -E env CFLAGS="/WX ${{ matrix.configuration.cpp_flags }}" cmake -B build -DSECP256K1_ENABLE_MODULE_RECOVERY=ON -DSECP256K1_BUILD_EXAMPLES=ON ${{ matrix.configuration.cmake_options }}
- name: Build
run: cmake --build build --config RelWithDebInfo -- /p:UseMultiToolTask=true /maxCpuCount
- name: Binaries info
# Use the bash shell included with Git for Windows.
shell: bash
run: |
cd build/src/RelWithDebInfo && file *tests.exe bench*.exe libsecp256k1-*.dll || true
- name: Check
run: |
ctest -C RelWithDebInfo --test-dir build -j ([int]$env:NUMBER_OF_PROCESSORS + 1)
build\src\RelWithDebInfo\bench_ecmult.exe
build\src\RelWithDebInfo\bench_internal.exe
build\src\RelWithDebInfo\bench.exe
win64-native-headers:
name: "x64 (MSVC): C++ (public headers)"
# See: https://github.com/actions/runner-images#available-images.
runs-on: windows-2022
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Add cl.exe to PATH
uses: ilammy/msvc-dev-cmd@v1
- name: C++ (public headers)
run: |
cl.exe -c -WX -TP include/*.h
cxx_fpermissive_debian:
name: "C++ -fpermissive (entire project)"
runs-on: ubuntu-latest
needs: docker_cache
env:
CC: 'g++'
CFLAGS: '-fpermissive -g'
CPPFLAGS: '-DSECP256K1_CPLUSPLUS_TEST_OVERRIDE'
WERROR_CFLAGS:
ECDH: 'yes'
RECOVERY: 'yes'
SCHNORRSIG: 'yes'
ELLSWIFT: 'yes'
EXPERIMENTAL: 'yes'
ECDSA_S2C: 'yes'
GENERATOR: 'yes'
RANGEPROOF: 'yes'
WHITELIST: 'yes'
MUSIG: 'yes'
ECDSAADAPTOR: 'yes'
BPPP: 'yes'
SCHNORRSIG_HALFAGG: 'yes'
FROST: 'yes'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: CI script
uses: ./.github/actions/run-in-docker-action
with:
dockerfile: ./ci/linux-debian.Dockerfile
tag: linux-debian-image
- run: cat tests.log || true
if: ${{ always() }}
- run: cat noverify_tests.log || true
if: ${{ always() }}
- run: cat exhaustive_tests.log || true
if: ${{ always() }}
- run: cat ctime_tests.log || true
if: ${{ always() }}
- run: cat bench.log || true
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
cxx_headers_debian:
name: "C++ (public headers)"
runs-on: ubuntu-latest
needs: docker_cache
steps:
- name: Checkout
uses: actions/checkout@v4
- name: CI script
uses: ./.github/actions/run-in-docker-action
with:
dockerfile: ./ci/linux-debian.Dockerfile
tag: linux-debian-image
command: |
g++ -Werror include/*.h
clang -Werror -x c++-header include/*.h
sage:
name: "SageMath prover"
runs-on: ubuntu-latest
container:
image: sagemath/sagemath:latest
options: --user root
steps:
- name: Checkout
uses: actions/checkout@v4
- name: CI script
run: |
cd sage
sage prove_group_implementations.sage
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- run: ./autogen.sh && ./configure --enable-dev-mode && make distcheck
- name: Check installation with Autotools
env:
CI_INSTALL: ${{ runner.temp }}/${{ github.run_id }}${{ github.action }}/install
run: |
./autogen.sh && ./configure --prefix=${{ env.CI_INSTALL }} && make clean && make install && ls -RlAh ${{ env.CI_INSTALL }}
gcc -o ecdsa examples/ecdsa.c $(PKG_CONFIG_PATH=${{ env.CI_INSTALL }}/lib/pkgconfig pkg-config --cflags --libs libsecp256k1) -Wl,-rpath,"${{ env.CI_INSTALL }}/lib" && ./ecdsa
- name: Check installation with CMake
env:
CI_BUILD: ${{ runner.temp }}/${{ github.run_id }}${{ github.action }}/build
CI_INSTALL: ${{ runner.temp }}/${{ github.run_id }}${{ github.action }}/install
run: |
cmake -B ${{ env.CI_BUILD }} -DCMAKE_INSTALL_PREFIX=${{ env.CI_INSTALL }} && cmake --build ${{ env.CI_BUILD }} --target install && ls -RlAh ${{ env.CI_INSTALL }}
gcc -o ecdsa examples/ecdsa.c -I ${{ env.CI_INSTALL }}/include -L ${{ env.CI_INSTALL }}/lib*/ -l secp256k1 -Wl,-rpath,"${{ env.CI_INSTALL }}/lib",-rpath,"${{ env.CI_INSTALL }}/lib64" && ./ecdsa

50
.gitignore vendored
View File

@@ -1,21 +1,27 @@
bench_inv
bench_ecdh
bench
bench_bppp
bench_ecmult
bench_generator
bench_rangeproof
bench_schnorrsig
bench_sign
bench_verify
bench_recover
bench_internal
bench_whitelist
noverify_tests
tests
example_musig
exhaustive_tests
gen_context
valgrind_ctime_test
precompute_ecmult_gen
precompute_ecmult
ctime_tests
ecdh_example
ecdsa_example
schnorr_example
*.exe
*.so
*.a
!.gitignore
*.csv
*.log
*.trs
*.sage.py
Makefile
configure
@@ -25,6 +31,7 @@ aclocal.m4
autom4te.cache/
config.log
config.status
conftest*
*.tar.gz
*.la
libtool
@@ -33,11 +40,15 @@ libtool
*.lo
*.o
*~
*.log
*.trs
src/libsecp256k1-config.h
src/libsecp256k1-config.h.in
src/ecmult_static_context.h
coverage/
coverage.html
coverage.*.html
*.gcda
*.gcno
*.gcov
build-aux/ar-lib
build-aux/config.guess
build-aux/config.sub
build-aux/depcomp
@@ -51,5 +62,14 @@ build-aux/m4/ltversion.m4
build-aux/missing
build-aux/compile
build-aux/test-driver
src/stamp-h1
libsecp256k1.pc
contrib/gh-pr-create.sh
musig_example
frost_example
### CMake
/CMakeUserPresets.json
# Default CMake build directory.
/build
xconfigure.sh

View File

@@ -1,111 +0,0 @@
language: c
os:
- linux
- osx
dist: bionic
# Valgrind currently supports upto macOS 10.13, the latest xcode of that version is 10.1
osx_image: xcode10.1
addons:
apt:
packages:
- libgmp-dev
- valgrind
- libtool-bin
compiler:
- clang
- gcc
env:
global:
- WIDEMUL=auto BIGNUM=auto STATICPRECOMPUTATION=yes ECMULTGENPRECISION=auto ASM=no BUILD=check WITH_VALGRIND=yes RUN_VALGRIND=no EXTRAFLAGS= HOST= ECDH=no RECOVERY=no SCHNORRSIG=no EXPERIMENTAL=no CTIMETEST=yes BENCH=yes ITERS=2 GENERATOR=no RANGEPROOF=no WHITELIST=no SCHNORRSIG=no MUSIG=no
matrix:
- WIDEMUL=int64 EXPERIMENTAL=yes RANGEPROOF=yes WHITELIST=yes GENERATOR=yes SCHNORRSIG=yes MUSIG=yes
- WIDEMUL=int128 EXPERIMENTAL=yes RANGEPROOF=yes WHITELIST=yes GENERATOR=yes SCHNORRSIG=yes MUSIG=yes
- WIDEMUL=int64 RECOVERY=yes
- WIDEMUL=int64 ECDH=yes EXPERIMENTAL=yes SCHNORRSIG=yes MUSIG=yes
- WIDEMUL=int128
- WIDEMUL=int128 RECOVERY=yes EXPERIMENTAL=yes SCHNORRSIG=yes MUSIG=yes
- WIDEMUL=int128 ECDH=yes EXPERIMENTAL=yes SCHNORRSIG=yes MUSIG=yes
- WIDEMUL=int128 ASM=x86_64
- BIGNUM=no
- BIGNUM=no RECOVERY=yes EXPERIMENTAL=yes SCHNORRSIG=yes MUSIG=yes
- BIGNUM=no STATICPRECOMPUTATION=no
- BUILD=distcheck WITH_VALGRIND=no CTIMETEST=no BENCH=no
- CPPFLAGS=-DDETERMINISTIC
- CFLAGS=-O0 CTIMETEST=no
- CFLAGS="-fsanitize=undefined -fno-omit-frame-pointer" LDFLAGS="-fsanitize=undefined -fno-omit-frame-pointer" UBSAN_OPTIONS="print_stacktrace=1:halt_on_error=1" BIGNUM=no ASM=x86_64 ECDH=yes RECOVERY=yes EXPERIMENTAL=yes SCHNORRSIG=yes MUSIG=yes CTIMETEST=no
- ECMULTGENPRECISION=2
- ECMULTGENPRECISION=8
- RUN_VALGRIND=yes BIGNUM=no ASM=x86_64 ECDH=yes RECOVERY=yes EXPERIMENTAL=yes SCHNORRSIG=yes MUSIG=yes EXTRAFLAGS="--disable-openssl-tests" BUILD=
matrix:
fast_finish: true
include:
- compiler: clang
os: linux
env: HOST=i686-linux-gnu
addons:
apt:
packages:
- gcc-multilib
- libgmp-dev:i386
- valgrind
- libtool-bin
- libc6-dbg:i386
- compiler: clang
env: HOST=i686-linux-gnu
os: linux
addons:
apt:
packages:
- gcc-multilib
- valgrind
- libtool-bin
- libc6-dbg:i386
- compiler: gcc
env: HOST=i686-linux-gnu
os: linux
addons:
apt:
packages:
- gcc-multilib
- valgrind
- libtool-bin
- libc6-dbg:i386
- compiler: gcc
os: linux
env: HOST=i686-linux-gnu
addons:
apt:
packages:
- gcc-multilib
- libgmp-dev:i386
- valgrind
- libtool-bin
- libc6-dbg:i386
# S390x build (big endian system)
- compiler: gcc
env: HOST=s390x-unknown-linux-gnu ECDH=yes RECOVERY=yes EXPERIMENTAL=yes SCHNORRSIG=yes MUSIG=yes CTIMETEST=
arch: s390x
# We use this to install macOS dependencies instead of the built in `homebrew` plugin,
# because in xcode earlier than 11 they have a bug requiring updating the system which overall takes ~8 minutes.
# https://travis-ci.community/t/macos-build-fails-because-of-homebrew-bundle-unknown-command/7296
before_install:
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then HOMEBREW_NO_AUTO_UPDATE=1 brew install gmp valgrind gcc@9; fi
before_script: ./autogen.sh
# travis auto terminates jobs that go for 10 minutes without printing to stdout, but travis_wait doesn't work well with forking programs like valgrind (https://docs.travis-ci.com/user/common-build-problems/#build-times-out-because-no-output-was-received https://github.com/bitcoin-core/secp256k1/pull/750#issuecomment-623476860)
script:
- function keep_alive() { while true; do echo -en "\a"; sleep 60; done }
- keep_alive &
- ./contrib/travis.sh
- kill %keep_alive
after_script:
- cat ./tests.log
- cat ./exhaustive_tests.log
- cat ./valgrind_ctime_test.log
- cat ./bench.log
- $CC --version
- valgrind --version

128
CHANGELOG.md Normal file
View File

@@ -0,0 +1,128 @@
**This changelog is not the libsecp256k1-zkp's changelog.**
Instead, it is the changelog of the upstream library [libsecp256k1](https://github.com/bitcoin-core/secp256k1).
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [0.4.1] - 2023-12-21
#### Changed
- The point multiplication algorithm used for ECDH operations (module `ecdh`) was replaced with a slightly faster one.
- Optional handwritten x86_64 assembly for field operations was removed because modern C compilers are able to output more efficient assembly. This change results in a significant speedup of some library functions when handwritten x86_64 assembly is enabled (`--with-asm=x86_64` in GNU Autotools, `-DSECP256K1_ASM=x86_64` in CMake), which is the default on x86_64. Benchmarks with GCC 10.5.0 show a 10% speedup for `secp256k1_ecdsa_verify` and `secp256k1_schnorrsig_verify`.
#### ABI Compatibility
The ABI is backward compatible with versions 0.4.0 and 0.3.x.
## [0.4.0] - 2023-09-04
#### Added
- New module `ellswift` implements ElligatorSwift encoding for public keys and x-only Diffie-Hellman key exchange for them.
ElligatorSwift permits representing secp256k1 public keys as 64-byte arrays which cannot be distinguished from uniformly random. See:
- Header file `include/secp256k1_ellswift.h` which defines the new API.
- Document `doc/ellswift.md` which explains the mathematical background of the scheme.
- The [paper](https://eprint.iacr.org/2022/759) on which the scheme is based.
- We now test the library with unreleased development snapshots of GCC and Clang. This gives us an early chance to catch miscompilations and constant-time issues introduced by the compiler (such as those that led to the previous two releases).
#### Fixed
- Fixed symbol visibility in Windows DLL builds, where three internal library symbols were wrongly exported.
#### Changed
- When consuming libsecp256k1 as a static library on Windows, the user must now define the `SECP256K1_STATIC` macro before including `secp256k1.h`.
#### ABI Compatibility
This release is backward compatible with the ABI of 0.3.0, 0.3.1, and 0.3.2. Symbol visibility is now believed to be handled properly on supported platforms and is now considered to be part of the ABI. Please report any improperly exported symbols as a bug.
## [0.3.2] - 2023-05-13
We strongly recommend updating to 0.3.2 if you use or plan to use GCC >=13 to compile libsecp256k1. When in doubt, check the GCC version using `gcc -v`.
#### Security
- Module `ecdh`: Fix "constant-timeness" issue with GCC 13.1 (and potentially future versions of GCC) that could leave applications using libsecp256k1's ECDH module vulnerable to a timing side-channel attack. The fix avoids secret-dependent control flow during ECDH computations when libsecp256k1 is compiled with GCC 13.1.
#### Fixed
- Fixed an old bug that permitted compilers to potentially output bad assembly code on x86_64. In theory, it could lead to a crash or a read of unrelated memory, but this has never been observed on any compilers so far.
#### Changed
- Various improvements and changes to CMake builds. CMake builds remain experimental.
- Made API versioning consistent with GNU Autotools builds.
- Switched to `BUILD_SHARED_LIBS` variable for controlling whether to build a static or a shared library.
- Added `SECP256K1_INSTALL` variable for the controlling whether to install the build artefacts.
- Renamed asm build option `arm` to `arm32`. Use `--with-asm=arm32` instead of `--with-asm=arm` (GNU Autotools), and `-DSECP256K1_ASM=arm32` instead of `-DSECP256K1_ASM=arm` (CMake).
#### ABI Compatibility
The ABI is compatible with versions 0.3.0 and 0.3.1.
## [0.3.1] - 2023-04-10
We strongly recommend updating to 0.3.1 if you use or plan to use Clang >=14 to compile libsecp256k1, e.g., Xcode >=14 on macOS has Clang >=14. When in doubt, check the Clang version using `clang -v`.
#### Security
- Fix "constant-timeness" issue with Clang >=14 that could leave applications using libsecp256k1 vulnerable to a timing side-channel attack. The fix avoids secret-dependent control flow and secret-dependent memory accesses in conditional moves of memory objects when libsecp256k1 is compiled with Clang >=14.
#### Added
- Added tests against [Project Wycheproof's](https://github.com/google/wycheproof/) set of ECDSA test vectors (Bitcoin "low-S" variant), a fixed set of test cases designed to trigger various edge cases.
#### Changed
- Increased minimum required CMake version to 3.13. CMake builds remain experimental.
#### ABI Compatibility
The ABI is compatible with version 0.3.0.
## [0.3.0] - 2023-03-08
#### Added
- Added experimental support for CMake builds. Traditional GNU Autotools builds (`./configure` and `make`) remain fully supported.
- Usage examples: Added a recommended method for securely clearing sensitive data, e.g., secret keys, from memory.
- Tests: Added a new test binary `noverify_tests`. This binary runs the tests without some additional checks present in the ordinary `tests` binary and is thereby closer to production binaries. The `noverify_tests` binary is automatically run as part of the `make check` target.
#### Fixed
- Fixed declarations of API variables for MSVC (`__declspec(dllimport)`). This fixes MSVC builds of programs which link against a libsecp256k1 DLL dynamically and use API variables (and not only API functions). Unfortunately, the MSVC linker now will emit warning `LNK4217` when trying to link against libsecp256k1 statically. Pass `/ignore:4217` to the linker to suppress this warning.
#### Changed
- Forbade cloning or destroying `secp256k1_context_static`. Create a new context instead of cloning the static context. (If this change breaks your code, your code is probably wrong.)
- Forbade randomizing (copies of) `secp256k1_context_static`. Randomizing a copy of `secp256k1_context_static` did not have any effect and did not provide defense-in-depth protection against side-channel attacks. Create a new context if you want to benefit from randomization.
#### Removed
- Removed the configuration header `src/libsecp256k1-config.h`. We recommend passing flags to `./configure` or `cmake` to set configuration options (see `./configure --help` or `cmake -LH`). If you cannot or do not want to use one of the supported build systems, pass configuration flags such as `-DSECP256K1_ENABLE_MODULE_SCHNORRSIG` manually to the compiler (see the file `configure.ac` for supported flags).
#### ABI Compatibility
Due to changes in the API regarding `secp256k1_context_static` described above, the ABI is *not* compatible with previous versions.
## [0.2.0] - 2022-12-12
#### Added
- Added usage examples for common use cases in a new `examples/` directory.
- Added `secp256k1_selftest`, to be used in conjunction with `secp256k1_context_static`.
- Added support for 128-bit wide multiplication on MSVC for x86_64 and arm64, giving roughly a 20% speedup on those platforms.
#### Changed
- Enabled modules `schnorrsig`, `extrakeys` and `ecdh` by default in `./configure`.
- The `secp256k1_nonce_function_rfc6979` nonce function, used by default by `secp256k1_ecdsa_sign`, now reduces the message hash modulo the group order to match the specification. This only affects improper use of ECDSA signing API.
#### Deprecated
- Deprecated context flags `SECP256K1_CONTEXT_VERIFY` and `SECP256K1_CONTEXT_SIGN`. Use `SECP256K1_CONTEXT_NONE` instead.
- Renamed `secp256k1_context_no_precomp` to `secp256k1_context_static`.
- Module `schnorrsig`: renamed `secp256k1_schnorrsig_sign` to `secp256k1_schnorrsig_sign32`.
#### ABI Compatibility
Since this is the first release, we do not compare application binary interfaces.
However, there are earlier unreleased versions of libsecp256k1 that are *not* ABI compatible with this version.
## [0.1.0] - 2013-03-05 to 2021-12-25
This version was in fact never released.
The number was given by the build system since the introduction of autotools in Jan 2014 (ea0fe5a5bf0c04f9cc955b2966b614f5f378c6f6).
Therefore, this version number does not uniquely identify a set of source files.
[unreleased]: https://github.com/bitcoin-core/secp256k1/compare/v0.4.1...HEAD
[0.4.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.4.0...v0.4.1
[0.4.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.2...v0.4.0
[0.3.2]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.1...v0.3.2
[0.3.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.0...v0.3.1
[0.3.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.2.0...v0.3.0
[0.2.0]: https://github.com/bitcoin-core/secp256k1/compare/423b6d19d373f1224fd671a982584d7e7900bc93..v0.2.0
[0.1.0]: https://github.com/bitcoin-core/secp256k1/commit/423b6d19d373f1224fd671a982584d7e7900bc93

430
CMakeLists.txt Normal file
View File

@@ -0,0 +1,430 @@
cmake_minimum_required(VERSION 3.13)
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.15)
# MSVC runtime library flags are selected by the CMAKE_MSVC_RUNTIME_LIBRARY abstraction.
cmake_policy(SET CMP0091 NEW)
# MSVC warning flags are not in CMAKE_<LANG>_FLAGS by default.
cmake_policy(SET CMP0092 NEW)
endif()
project(libsecp256k1
# The package (a.k.a. release) version is based on semantic versioning 2.0.0 of
# the API. All changes in experimental modules are treated as
# backwards-compatible and therefore at most increase the minor version.
VERSION 0.4.2
DESCRIPTION "Optimized C library for ECDSA signatures and secret/public key operations on curve secp256k1."
HOMEPAGE_URL "https://github.com/bitcoin-core/secp256k1"
LANGUAGES C
)
if(CMAKE_VERSION VERSION_LESS 3.21)
get_directory_property(parent_directory PARENT_DIRECTORY)
if(parent_directory)
set(PROJECT_IS_TOP_LEVEL OFF CACHE INTERNAL "Emulates CMake 3.21+ behavior.")
set(${PROJECT_NAME}_IS_TOP_LEVEL OFF CACHE INTERNAL "Emulates CMake 3.21+ behavior.")
else()
set(PROJECT_IS_TOP_LEVEL ON CACHE INTERNAL "Emulates CMake 3.21+ behavior.")
set(${PROJECT_NAME}_IS_TOP_LEVEL ON CACHE INTERNAL "Emulates CMake 3.21+ behavior.")
endif()
unset(parent_directory)
endif()
# The library version is based on libtool versioning of the ABI. The set of
# rules for updating the version can be found here:
# https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
# All changes in experimental modules are treated as if they don't affect the
# interface and therefore only increase the revision.
set(${PROJECT_NAME}_LIB_VERSION_CURRENT 3)
set(${PROJECT_NAME}_LIB_VERSION_REVISION 2)
set(${PROJECT_NAME}_LIB_VERSION_AGE 1)
set(CMAKE_C_STANDARD 90)
set(CMAKE_C_EXTENSIONS OFF)
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
option(BUILD_SHARED_LIBS "Build shared libraries." ON)
option(SECP256K1_DISABLE_SHARED "Disable shared library. Overrides BUILD_SHARED_LIBS." OFF)
if(SECP256K1_DISABLE_SHARED)
set(BUILD_SHARED_LIBS OFF)
endif()
option(SECP256K1_INSTALL "Enable installation." ${PROJECT_IS_TOP_LEVEL})
## Modules
# We declare all options before processing them, to make sure we can express
# dependendencies while processing.
option(SECP256K1_ENABLE_MODULE_ECDH "Enable ECDH module." ON)
option(SECP256K1_ENABLE_MODULE_RECOVERY "Enable ECDSA pubkey recovery module." OFF)
option(SECP256K1_ENABLE_MODULE_EXTRAKEYS "Enable extrakeys module." ON)
option(SECP256K1_ENABLE_MODULE_SCHNORRSIG "Enable schnorrsig module." ON)
option(SECP256K1_ENABLE_MODULE_ELLSWIFT "Enable ElligatorSwift module." ON)
option(SECP256K1_ENABLE_MODULE_GENERATOR "Enable NUMS generator module." ON)
option(SECP256K1_ENABLE_MODULE_RANGEPROOF "Enable Range proof module." ON)
option(SECP256K1_ENABLE_MODULE_SURJECTIONPROOF "Enable Surjection proof module." ON)
option(SECP256K1_ENABLE_MODULE_WHITELIST "Enable key whitelist module." ON)
option(SECP256K1_ENABLE_MODULE_MUSIG "Enable MuSig module." ON)
option(SECP256K1_ENABLE_MODULE_ECDSA_ADAPTOR "Enable ecdsa adaptor signatures module." ON)
option(SECP256K1_ENABLE_MODULE_ECDSA_S2C "Enable ECDSA sign-to-contract module." ON)
option(SECP256K1_ENABLE_MODULE_BPPP "Enable Bulletproofs++ module." ON)
# Processing must be done in a topological sorting of the dependency graph
# (dependent module first).
if(SECP256K1_ENABLE_MODULE_BPPP)
if(DEFINED SECP256K1_ENABLE_MODULE_GENERATOR AND NOT SECP256K1_ENABLE_MODULE_GENERATOR)
message(FATAL_ERROR "Module dependency error: You have disabled the generator module explicitly, but it is required by the bppp module.")
endif()
set(SECP256K1_ENABLE_MODULE_GENERATOR ON)
add_compile_definitions(ENABLE_MODULE_BPPP=1)
endif()
if(SECP256K1_ENABLE_MODULE_ECDSA_S2C)
add_compile_definitions(ENABLE_MODULE_ECDSA_S2C=1)
endif()
if(SECP256K1_ENABLE_MODULE_ECDSA_ADAPTOR)
add_compile_definitions(ENABLE_MODULE_ECDSA_ADAPTOR=1)
endif()
if(SECP256K1_ENABLE_MODULE_MUSIG)
if(DEFINED SECP256K1_ENABLE_MODULE_SCHNORRSIG AND NOT SECP256K1_ENABLE_MODULE_SCHNORRSIG)
message(FATAL_ERROR "Module dependency error: You have disabled the schnorrsig module explicitly, but it is required by the musig module.")
endif()
set(SECP256K1_ENABLE_MODULE_SCHNORRSIG ON)
add_compile_definitions(ENABLE_MODULE_MUSIG=1)
endif()
if(SECP256K1_ENABLE_MODULE_WHITELIST)
if(DEFINED SECP256K1_ENABLE_MODULE_RANGEPROOF AND NOT SECP256K1_ENABLE_MODULE_RANGEPROOF)
message(FATAL_ERROR "Module dependency error: You have disabled the rangeproof module explicitly, but it is required by the whitelist module.")
endif()
set(SECP256K1_ENABLE_MODULE_RANGEPROOF ON)
add_compile_definitions(ENABLE_MODULE_WHITELIST=1)
endif()
if(SECP256K1_ENABLE_MODULE_SURJECTIONPROOF)
if(DEFINED SECP256K1_ENABLE_MODULE_RANGEPROOF AND NOT SECP256K1_ENABLE_MODULE_RANGEPROOF)
message(FATAL_ERROR "Module dependency error: You have disabled the rangeproof module explicitly, but it is required by the surjectionproof module.")
endif()
set(SECP256K1_ENABLE_MODULE_RANGEPROOF ON)
add_compile_definitions(ENABLE_MODULE_SURJECTIONPROOF=1)
endif()
if(SECP256K1_ENABLE_MODULE_RANGEPROOF)
if(DEFINED SECP256K1_ENABLE_MODULE_GENERATOR AND NOT SECP256K1_ENABLE_MODULE_GENERATOR)
message(FATAL_ERROR "Module dependency error: You have disabled the generator module explicitly, but it is required by the rangeproof module.")
endif()
set(SECP256K1_ENABLE_MODULE_GENERATOR ON)
add_compile_definitions(ENABLE_MODULE_RANGEPROOF=1)
endif()
if(SECP256K1_ENABLE_MODULE_GENERATOR)
add_compile_definitions(ENABLE_MODULE_GENERATOR=1)
endif()
if(SECP256K1_ENABLE_MODULE_ELLSWIFT)
add_compile_definitions(ENABLE_MODULE_ELLSWIFT=1)
endif()
if(SECP256K1_ENABLE_MODULE_SCHNORRSIG)
if(DEFINED SECP256K1_ENABLE_MODULE_EXTRAKEYS AND NOT SECP256K1_ENABLE_MODULE_EXTRAKEYS)
message(FATAL_ERROR "Module dependency error: You have disabled the extrakeys module explicitly, but it is required by the schnorrsig module.")
endif()
set(SECP256K1_ENABLE_MODULE_EXTRAKEYS ON)
add_compile_definitions(ENABLE_MODULE_SCHNORRSIG=1)
endif()
if(SECP256K1_ENABLE_MODULE_EXTRAKEYS)
add_compile_definitions(ENABLE_MODULE_EXTRAKEYS=1)
endif()
if(SECP256K1_ENABLE_MODULE_RECOVERY)
add_compile_definitions(ENABLE_MODULE_RECOVERY=1)
endif()
if(SECP256K1_ENABLE_MODULE_ECDH)
add_compile_definitions(ENABLE_MODULE_ECDH=1)
endif()
option(SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS "Enable external default callback functions." OFF)
if(SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS)
add_compile_definitions(USE_EXTERNAL_DEFAULT_CALLBACKS=1)
endif()
set(SECP256K1_ECMULT_WINDOW_SIZE "AUTO" CACHE STRING "Window size for ecmult precomputation for verification, specified as integer in range [2..24]. \"AUTO\" is a reasonable setting for desktop machines (currently 15). [default=AUTO]")
set_property(CACHE SECP256K1_ECMULT_WINDOW_SIZE PROPERTY STRINGS "AUTO" 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24)
include(CheckStringOptionValue)
check_string_option_value(SECP256K1_ECMULT_WINDOW_SIZE)
if(SECP256K1_ECMULT_WINDOW_SIZE STREQUAL "AUTO")
set(SECP256K1_ECMULT_WINDOW_SIZE 15)
endif()
add_compile_definitions(ECMULT_WINDOW_SIZE=${SECP256K1_ECMULT_WINDOW_SIZE})
set(SECP256K1_ECMULT_GEN_PREC_BITS "AUTO" CACHE STRING "Precision bits to tune the precomputed table size for signing, specified as integer 2, 4 or 8. \"AUTO\" is a reasonable setting for desktop machines (currently 4). [default=AUTO]")
set_property(CACHE SECP256K1_ECMULT_GEN_PREC_BITS PROPERTY STRINGS "AUTO" 2 4 8)
check_string_option_value(SECP256K1_ECMULT_GEN_PREC_BITS)
if(SECP256K1_ECMULT_GEN_PREC_BITS STREQUAL "AUTO")
set(SECP256K1_ECMULT_GEN_PREC_BITS 4)
endif()
add_compile_definitions(ECMULT_GEN_PREC_BITS=${SECP256K1_ECMULT_GEN_PREC_BITS})
set(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY "OFF" CACHE STRING "Test-only override of the (autodetected by the C code) \"widemul\" setting. Legal values are: \"OFF\", \"int128_struct\", \"int128\" or \"int64\". [default=OFF]")
set_property(CACHE SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY PROPERTY STRINGS "OFF" "int128_struct" "int128" "int64")
check_string_option_value(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
if(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
string(TOUPPER "${SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY}" widemul_upper_value)
add_compile_definitions(USE_FORCE_WIDEMUL_${widemul_upper_value}=1)
endif()
mark_as_advanced(FORCE SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
set(SECP256K1_ASM "AUTO" CACHE STRING "Assembly to use: \"AUTO\", \"OFF\", \"x86_64\" or \"arm32\" (experimental). [default=AUTO]")
set_property(CACHE SECP256K1_ASM PROPERTY STRINGS "AUTO" "OFF" "x86_64" "arm32")
check_string_option_value(SECP256K1_ASM)
if(SECP256K1_ASM STREQUAL "arm32")
enable_language(ASM)
include(CheckArm32Assembly)
check_arm32_assembly()
if(HAVE_ARM32_ASM)
add_compile_definitions(USE_EXTERNAL_ASM=1)
else()
message(FATAL_ERROR "ARM32 assembly requested but not available.")
endif()
elseif(SECP256K1_ASM)
include(CheckX86_64Assembly)
check_x86_64_assembly()
if(HAVE_X86_64_ASM)
set(SECP256K1_ASM "x86_64")
add_compile_definitions(USE_ASM_X86_64=1)
elseif(SECP256K1_ASM STREQUAL "AUTO")
set(SECP256K1_ASM "OFF")
else()
message(FATAL_ERROR "x86_64 assembly requested but not available.")
endif()
endif()
option(SECP256K1_EXPERIMENTAL "Allow experimental configuration options." OFF)
if(NOT SECP256K1_EXPERIMENTAL)
if(SECP256K1_ASM STREQUAL "arm32")
message(FATAL_ERROR "ARM32 assembly is experimental. Use -DSECP256K1_EXPERIMENTAL=ON to allow.")
endif()
endif()
set(SECP256K1_VALGRIND "AUTO" CACHE STRING "Build with extra checks for running inside Valgrind. [default=AUTO]")
set_property(CACHE SECP256K1_VALGRIND PROPERTY STRINGS "AUTO" "OFF" "ON")
check_string_option_value(SECP256K1_VALGRIND)
if(SECP256K1_VALGRIND)
find_package(Valgrind MODULE)
if(Valgrind_FOUND)
set(SECP256K1_VALGRIND ON)
include_directories(${Valgrind_INCLUDE_DIR})
add_compile_definitions(VALGRIND)
elseif(SECP256K1_VALGRIND STREQUAL "AUTO")
set(SECP256K1_VALGRIND OFF)
else()
message(FATAL_ERROR "Valgrind support requested but valgrind/memcheck.h header not available.")
endif()
endif()
option(SECP256K1_BUILD_BENCHMARK "Build benchmarks." ON)
option(SECP256K1_BUILD_TESTS "Build tests." ON)
option(SECP256K1_BUILD_EXHAUSTIVE_TESTS "Build exhaustive tests." ON)
option(SECP256K1_BUILD_CTIME_TESTS "Build constant-time tests." ${SECP256K1_VALGRIND})
option(SECP256K1_BUILD_EXAMPLES "Build examples." OFF)
# Redefine configuration flags.
# We leave assertions on, because they are only used in the examples, and we want them always on there.
if(MSVC)
string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}")
else()
string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}")
# Prefer -O2 optimization level. (-O3 is CMake's default for Release for many compilers.)
string(REGEX REPLACE "-O3[ \t\r\n]*" "-O2" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
endif()
# Define custom "Coverage" build type.
set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O0 -DCOVERAGE=1 --coverage" CACHE STRING
"Flags used by the C compiler during \"Coverage\" builds."
FORCE
)
set(CMAKE_EXE_LINKER_FLAGS_COVERAGE "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} --coverage" CACHE STRING
"Flags used for linking binaries during \"Coverage\" builds."
FORCE
)
set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} --coverage" CACHE STRING
"Flags used by the shared libraries linker during \"Coverage\" builds."
FORCE
)
mark_as_advanced(
CMAKE_C_FLAGS_COVERAGE
CMAKE_EXE_LINKER_FLAGS_COVERAGE
CMAKE_SHARED_LINKER_FLAGS_COVERAGE
)
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
set(default_build_type "RelWithDebInfo")
if(is_multi_config)
set(CMAKE_CONFIGURATION_TYPES "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage" CACHE STRING
"Supported configuration types."
FORCE
)
else()
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
STRINGS "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage"
)
if(NOT CMAKE_BUILD_TYPE)
message(STATUS "Setting build type to \"${default_build_type}\" as none was specified")
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING
"Choose the type of build."
FORCE
)
endif()
endif()
include(TryAppendCFlags)
if(MSVC)
# Keep the following commands ordered lexicographically.
try_append_c_flags(/W3) # Production quality warning level.
try_append_c_flags(/wd4146) # Disable warning C4146 "unary minus operator applied to unsigned type, result still unsigned".
try_append_c_flags(/wd4244) # Disable warning C4244 "'conversion' conversion from 'type1' to 'type2', possible loss of data".
try_append_c_flags(/wd4267) # Disable warning C4267 "'var' : conversion from 'size_t' to 'type', possible loss of data".
# Eliminate deprecation warnings for the older, less secure functions.
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
else()
# Keep the following commands ordered lexicographically.
try_append_c_flags(-pedantic)
try_append_c_flags(-Wall) # GCC >= 2.95 and probably many other compilers.
try_append_c_flags(-Wcast-align) # GCC >= 2.95.
try_append_c_flags(-Wcast-align=strict) # GCC >= 8.0.
try_append_c_flags(-Wconditional-uninitialized) # Clang >= 3.0 only.
try_append_c_flags(-Wextra) # GCC >= 3.4, this is the newer name of -W, which we don't use because older GCCs will warn about unused functions.
try_append_c_flags(-Wnested-externs)
try_append_c_flags(-Wno-long-long) # GCC >= 3.0, -Wlong-long is implied by -pedantic.
try_append_c_flags(-Wno-overlength-strings) # GCC >= 4.2, -Woverlength-strings is implied by -pedantic.
try_append_c_flags(-Wno-unused-function) # GCC >= 3.0, -Wunused-function is implied by -Wall.
try_append_c_flags(-Wreserved-identifier) # Clang >= 13.0 only.
try_append_c_flags(-Wshadow)
try_append_c_flags(-Wstrict-prototypes)
try_append_c_flags(-Wundef)
endif()
set(CMAKE_C_VISIBILITY_PRESET hidden)
# Ask CTest to create a "check" target (e.g., make check) as alias for the "test" target.
# CTEST_TEST_TARGET_ALIAS is not documented but supposed to be user-facing.
# See: https://gitlab.kitware.com/cmake/cmake/-/commit/816c9d1aa1f2b42d40c81a991b68c96eb12b6d2
set(CTEST_TEST_TARGET_ALIAS check)
include(CTest)
# We do not use CTest's BUILD_TESTING because a single toggle for all tests is too coarse for our needs.
mark_as_advanced(BUILD_TESTING)
if(SECP256K1_BUILD_BENCHMARK OR SECP256K1_BUILD_TESTS OR SECP256K1_BUILD_EXHAUSTIVE_TESTS OR SECP256K1_BUILD_CTIME_TESTS OR SECP256K1_BUILD_EXAMPLES)
enable_testing()
endif()
set(SECP256K1_LATE_CFLAGS "" CACHE STRING "Compiler flags that are added to the command line after all other flags added by the build system.")
include(AllTargetsCompileOptions)
add_subdirectory(src)
all_targets_compile_options(src "${SECP256K1_LATE_CFLAGS}")
if(SECP256K1_BUILD_EXAMPLES)
add_subdirectory(examples)
all_targets_compile_options(examples "${SECP256K1_LATE_CFLAGS}")
endif()
message("\n")
message("secp256k1 configure summary")
message("===========================")
message("Build artifacts:")
if(BUILD_SHARED_LIBS)
set(library_type "Shared")
else()
set(library_type "Static")
endif()
message(" library type ........................ ${library_type}")
message("Optional modules:")
message(" ECDH ................................ ${SECP256K1_ENABLE_MODULE_ECDH}")
message(" ECDSA pubkey recovery ............... ${SECP256K1_ENABLE_MODULE_RECOVERY}")
message(" extrakeys ........................... ${SECP256K1_ENABLE_MODULE_EXTRAKEYS}")
message(" schnorrsig .......................... ${SECP256K1_ENABLE_MODULE_SCHNORRSIG}")
message(" ElligatorSwift ...................... ${SECP256K1_ENABLE_MODULE_ELLSWIFT}")
message(" generator ........................... ${SECP256K1_ENABLE_MODULE_GENERATOR}")
message(" rangeproof .......................... ${SECP256K1_ENABLE_MODULE_RANGEPROOF}")
message(" surjectionproof ..................... ${SECP256K1_ENABLE_MODULE_SURJECTIONPROOF}")
message(" whitelist ........................... ${SECP256K1_ENABLE_MODULE_WHITELIST}")
message(" musig ............................... ${SECP256K1_ENABLE_MODULE_MUSIG}")
message(" ecdsa-s2c ........................... ${SECP256K1_ENABLE_MODULE_ECDSA_S2C}")
message(" ecdsa-adaptor ....................... ${SECP256K1_ENABLE_MODULE_ECDSA_ADAPTOR}")
message(" bppp ................................ ${SECP256K1_ENABLE_MODULE_BPPP}")
message("Parameters:")
message(" ecmult window size .................. ${SECP256K1_ECMULT_WINDOW_SIZE}")
message(" ecmult gen precision bits ........... ${SECP256K1_ECMULT_GEN_PREC_BITS}")
message("Optional features:")
message(" assembly ............................ ${SECP256K1_ASM}")
message(" external callbacks .................. ${SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS}")
if(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
message(" wide multiplication (test-only) ..... ${SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY}")
endif()
message("Optional binaries:")
message(" benchmark ........................... ${SECP256K1_BUILD_BENCHMARK}")
message(" noverify_tests ...................... ${SECP256K1_BUILD_TESTS}")
set(tests_status "${SECP256K1_BUILD_TESTS}")
if(CMAKE_BUILD_TYPE STREQUAL "Coverage")
set(tests_status OFF)
endif()
message(" tests ............................... ${tests_status}")
message(" exhaustive tests .................... ${SECP256K1_BUILD_EXHAUSTIVE_TESTS}")
message(" ctime_tests ......................... ${SECP256K1_BUILD_CTIME_TESTS}")
message(" examples ............................ ${SECP256K1_BUILD_EXAMPLES}")
message("")
if(CMAKE_CROSSCOMPILING)
set(cross_status "TRUE, for ${CMAKE_SYSTEM_NAME}, ${CMAKE_SYSTEM_PROCESSOR}")
else()
set(cross_status "FALSE")
endif()
message("Cross compiling ....................... ${cross_status}")
message("Valgrind .............................. ${SECP256K1_VALGRIND}")
get_directory_property(definitions COMPILE_DEFINITIONS)
string(REPLACE ";" " " definitions "${definitions}")
message("Preprocessor defined macros ........... ${definitions}")
message("C compiler ............................ ${CMAKE_C_COMPILER}")
message("CFLAGS ................................ ${CMAKE_C_FLAGS}")
get_directory_property(compile_options COMPILE_OPTIONS)
string(REPLACE ";" " " compile_options "${compile_options}")
message("Compile options ....................... " ${compile_options})
if(NOT is_multi_config)
message("Build type:")
message(" - CMAKE_BUILD_TYPE ................... ${CMAKE_BUILD_TYPE}")
string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type)
message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_${build_type}}")
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_${build_type}}")
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_${build_type}}")
else()
message("Supported configurations .............. ${CMAKE_CONFIGURATION_TYPES}")
message("RelWithDebInfo configuration:")
message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}")
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}")
message("Debug configuration:")
message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_DEBUG}")
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}")
endif()
if(SECP256K1_LATE_CFLAGS)
message("SECP256K1_LATE_CFLAGS ................. ${SECP256K1_LATE_CFLAGS}")
endif()
message("\n")
if(SECP256K1_EXPERIMENTAL)
message(
" ******\n"
" WARNING: experimental build\n"
" Experimental features do not have stable APIs or properties, and may not be safe for production use.\n"
" ******\n"
)
endif()

19
CMakePresets.json Normal file
View File

@@ -0,0 +1,19 @@
{
"cmakeMinimumRequired": {"major": 3, "minor": 21, "patch": 0},
"version": 3,
"configurePresets": [
{
"name": "dev-mode",
"displayName": "Development mode (intended only for developers of the library)",
"cacheVariables": {
"SECP256K1_EXPERIMENTAL": "ON",
"SECP256K1_ENABLE_MODULE_RECOVERY": "ON",
"SECP256K1_BUILD_EXAMPLES": "ON"
},
"warnings": {
"dev": true,
"uninitialized": true
}
}
]
}

107
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,107 @@
# Contributing to libsecp256k1
## Scope
libsecp256k1 is a library for elliptic curve cryptography on the curve secp256k1, not a general-purpose cryptography library.
The library primarily serves the needs of the Bitcoin Core project but provides additional functionality for the benefit of the wider Bitcoin ecosystem.
## Adding new functionality or modules
The libsecp256k1 project welcomes contributions in the form of new functionality or modules, provided they are within the project's scope.
It is the responsibility of the contributors to convince the maintainers that the proposed functionality is within the project's scope, high-quality and maintainable.
Contributors are recommended to provide the following in addition to the new code:
* **Specification:**
A specification can help significantly in reviewing the new code as it provides documentation and context.
It may justify various design decisions, give a motivation and outline security goals.
If the specification contains pseudocode, a reference implementation or test vectors, these can be used to compare with the proposed libsecp256k1 code.
* **Security Arguments:**
In addition to a defining the security goals, it should be argued that the new functionality meets these goals.
Depending on the nature of the new functionality, a wide range of security arguments are acceptable, ranging from being "obviously secure" to rigorous proofs of security.
* **Relevance Arguments:**
The relevance of the new functionality for the Bitcoin ecosystem should be argued by outlining clear use cases.
These are not the only factors taken into account when considering to add new functionality.
The proposed new libsecp256k1 code must be of high quality, including API documentation and tests, as well as featuring a misuse-resistant API design.
We recommend reaching out to other contributors (see [Communication Channels](#communication-channels)) and get feedback before implementing new functionality.
## Communication channels
Most communication about libsecp256k1 occurs on the GitHub repository: in issues, pull request or on the discussion board.
Additionally, there is an IRC channel dedicated to libsecp256k1, with biweekly meetings (see channel topic).
The channel is `#secp256k1` on Libera Chat.
The easiest way to participate on IRC is with the web client, [web.libera.chat](https://web.libera.chat/#secp256k1).
Chat history logs can be found at https://gnusha.org/secp256k1/.
## Contributor workflow & peer review
The Contributor Workflow & Peer Review in libsecp256k1 are similar to Bitcoin Core's workflow and review processes described in its [CONTRIBUTING.md](https://github.com/bitcoin/bitcoin/blob/master/CONTRIBUTING.md).
### Coding conventions
In addition, libsecp256k1 tries to maintain the following coding conventions:
* No runtime heap allocation (e.g., no `malloc`) unless explicitly requested by the caller (via `secp256k1_context_create` or `secp256k1_scratch_space_create`, for example). Moreover, it should be possible to use the library without any heap allocations.
* The tests should cover all lines and branches of the library (see [Test coverage](#coverage)).
* Operations involving secret data should be tested for being constant time with respect to the secrets (see [src/ctime_tests.c](src/ctime_tests.c)).
* Local variables containing secret data should be cleared explicitly to try to delete secrets from memory.
* Use `secp256k1_memcmp_var` instead of `memcmp` (see [#823](https://github.com/bitcoin-core/secp256k1/issues/823)).
#### Style conventions
* Commits should be atomic and diffs should be easy to read. For this reason, do not mix any formatting fixes or code moves with actual code changes. Make sure each individual commit is hygienic: that it builds successfully on its own without warnings, errors, regressions, or test failures.
* New code should adhere to the style of existing, in particular surrounding, code. Other than that, we do not enforce strict rules for code formatting.
* The code conforms to C89. Most notably, that means that only `/* ... */` comments are allowed (no `//` line comments). Moreover, any declarations in a `{ ... }` block (e.g., a function) must appear at the beginning of the block before any statements. When you would like to declare a variable in the middle of a block, you can open a new block:
```C
void secp256k_foo(void) {
unsigned int x; /* declaration */
int y = 2*x; /* declaration */
x = 17; /* statement */
{
int a, b; /* declaration */
a = x + y; /* statement */
secp256k_bar(x, &b); /* statement */
}
}
```
* Use `unsigned int` instead of just `unsigned`.
* Use `void *ptr` instead of `void* ptr`.
* Arguments of the publicly-facing API must have a specific order defined in [include/secp256k1.h](include/secp256k1.h).
* User-facing comment lines in headers should be limited to 80 chars if possible.
* All identifiers in file scope should start with `secp256k1_`.
* Avoid trailing whitespace.
### Tests
#### Coverage
This library aims to have full coverage of reachable lines and branches.
To create a test coverage report, configure with `--enable-coverage` (use of GCC is necessary):
$ ./configure --enable-coverage
Run the tests:
$ make check
To create a report, `gcovr` is recommended, as it includes branch coverage reporting:
$ gcovr --exclude 'src/bench*' --print-summary
To create a HTML report with coloured and annotated source code:
$ mkdir -p coverage
$ gcovr --exclude 'src/bench*' --html --html-details -o coverage/coverage.html
#### Exhaustive tests
There are tests of several functions in which a small group replaces secp256k1.
These tests are *exhaustive* since they provide all elements and scalars of the small group as input arguments (see [src/tests_exhaustive.c](src/tests_exhaustive.c)).
### Benchmarks
See `src/bench*.c` for examples of benchmarks.

View File

@@ -1,5 +1,9 @@
ACLOCAL_AMFLAGS = -I build-aux/m4
# AM_CFLAGS will be automatically prepended to CFLAGS by Automake when compiling some foo
# which does not have an explicit foo_CFLAGS variable set.
AM_CFLAGS = $(SECP_CFLAGS)
lib_LTLIBRARIES = libsecp256k1.la
include_HEADERS = include/secp256k1.h
include_HEADERS += include/secp256k1_preallocated.h
@@ -14,28 +18,43 @@ noinst_HEADERS += src/scalar_8x32_impl.h
noinst_HEADERS += src/scalar_low_impl.h
noinst_HEADERS += src/group.h
noinst_HEADERS += src/group_impl.h
noinst_HEADERS += src/num_gmp.h
noinst_HEADERS += src/num_gmp_impl.h
noinst_HEADERS += src/eccommit.h
noinst_HEADERS += src/eccommit_impl.h
noinst_HEADERS += src/ecdsa.h
noinst_HEADERS += src/ecdsa_impl.h
noinst_HEADERS += src/eckey.h
noinst_HEADERS += src/eckey_impl.h
noinst_HEADERS += src/ecmult.h
noinst_HEADERS += src/ecmult_impl.h
noinst_HEADERS += src/ecmult_compute_table.h
noinst_HEADERS += src/ecmult_compute_table_impl.h
noinst_HEADERS += src/ecmult_const.h
noinst_HEADERS += src/ecmult_const_impl.h
noinst_HEADERS += src/ecmult_gen.h
noinst_HEADERS += src/ecmult_gen_impl.h
noinst_HEADERS += src/num.h
noinst_HEADERS += src/num_impl.h
noinst_HEADERS += src/ecmult_gen_compute_table.h
noinst_HEADERS += src/ecmult_gen_compute_table_impl.h
noinst_HEADERS += src/field_10x26.h
noinst_HEADERS += src/field_10x26_impl.h
noinst_HEADERS += src/field_5x52.h
noinst_HEADERS += src/field_5x52_impl.h
noinst_HEADERS += src/field_5x52_int128_impl.h
noinst_HEADERS += src/field_5x52_asm_impl.h
noinst_HEADERS += src/modinv32.h
noinst_HEADERS += src/modinv32_impl.h
noinst_HEADERS += src/modinv64.h
noinst_HEADERS += src/modinv64_impl.h
noinst_HEADERS += src/precomputed_ecmult.h
noinst_HEADERS += src/precomputed_ecmult_gen.h
noinst_HEADERS += src/assumptions.h
noinst_HEADERS += src/checkmem.h
noinst_HEADERS += src/testutil.h
noinst_HEADERS += src/util.h
noinst_HEADERS += src/int128.h
noinst_HEADERS += src/int128_impl.h
noinst_HEADERS += src/int128_native.h
noinst_HEADERS += src/int128_native_impl.h
noinst_HEADERS += src/int128_struct.h
noinst_HEADERS += src/int128_struct_impl.h
noinst_HEADERS += src/scratch.h
noinst_HEADERS += src/scratch_impl.h
noinst_HEADERS += src/selftest.h
@@ -46,17 +65,26 @@ noinst_HEADERS += src/hash_impl.h
noinst_HEADERS += src/field.h
noinst_HEADERS += src/field_impl.h
noinst_HEADERS += src/bench.h
noinst_HEADERS += src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h
noinst_HEADERS += contrib/lax_der_parsing.h
noinst_HEADERS += contrib/lax_der_parsing.c
noinst_HEADERS += contrib/lax_der_privatekey_parsing.h
noinst_HEADERS += contrib/lax_der_privatekey_parsing.c
noinst_HEADERS += examples/examples_util.h
PRECOMPUTED_LIB = libsecp256k1_precomputed.la
noinst_LTLIBRARIES = $(PRECOMPUTED_LIB)
libsecp256k1_precomputed_la_SOURCES = src/precomputed_ecmult.c src/precomputed_ecmult_gen.c
# We need `-I$(top_srcdir)/src` in VPATH builds if libsecp256k1_precomputed_la_SOURCES have been recreated in the build tree.
# This helps users and packagers who insist on recreating the precomputed files (e.g., Gentoo).
libsecp256k1_precomputed_la_CPPFLAGS = -I$(top_srcdir)/src $(SECP_CONFIG_DEFINES)
if USE_EXTERNAL_ASM
COMMON_LIB = libsecp256k1_common.la
noinst_LTLIBRARIES = $(COMMON_LIB)
else
COMMON_LIB =
endif
noinst_LTLIBRARIES += $(COMMON_LIB)
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libsecp256k1.pc
@@ -68,84 +96,193 @@ endif
endif
libsecp256k1_la_SOURCES = src/secp256k1.c
libsecp256k1_la_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/include -I$(top_srcdir)/src $(SECP_INCLUDES)
libsecp256k1_la_LIBADD = $(SECP_LIBS) $(COMMON_LIB)
if VALGRIND_ENABLED
libsecp256k1_la_CPPFLAGS += -DVALGRIND
endif
libsecp256k1_la_CPPFLAGS = $(SECP_CONFIG_DEFINES)
libsecp256k1_la_LIBADD = $(COMMON_LIB) $(PRECOMPUTED_LIB)
libsecp256k1_la_LDFLAGS = -no-undefined -version-info $(LIB_VERSION_CURRENT):$(LIB_VERSION_REVISION):$(LIB_VERSION_AGE)
noinst_PROGRAMS =
if USE_BENCHMARK
noinst_PROGRAMS += bench_verify bench_sign bench_internal bench_ecmult
bench_verify_SOURCES = src/bench_verify.c
bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB)
# SECP_TEST_INCLUDES are only used here for CRYPTO_CPPFLAGS
bench_verify_CPPFLAGS = -DSECP256K1_BUILD $(SECP_TEST_INCLUDES)
bench_sign_SOURCES = src/bench_sign.c
bench_sign_LDADD = libsecp256k1.la $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB)
noinst_PROGRAMS += bench bench_internal bench_ecmult
bench_SOURCES = src/bench.c
bench_LDADD = libsecp256k1.la
bench_CPPFLAGS = $(SECP_CONFIG_DEFINES)
bench_internal_SOURCES = src/bench_internal.c
bench_internal_LDADD = $(SECP_LIBS) $(COMMON_LIB)
bench_internal_CPPFLAGS = -DSECP256K1_BUILD $(SECP_INCLUDES)
bench_internal_LDADD = $(COMMON_LIB) $(PRECOMPUTED_LIB)
bench_internal_CPPFLAGS = $(SECP_CONFIG_DEFINES)
bench_ecmult_SOURCES = src/bench_ecmult.c
bench_ecmult_LDADD = $(SECP_LIBS) $(COMMON_LIB)
bench_ecmult_CPPFLAGS = -DSECP256K1_BUILD $(SECP_INCLUDES)
bench_ecmult_LDADD = $(COMMON_LIB) $(PRECOMPUTED_LIB)
bench_ecmult_CPPFLAGS = $(SECP_CONFIG_DEFINES)
endif
TESTS =
if USE_TESTS
noinst_PROGRAMS += tests
tests_SOURCES = src/tests.c
tests_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/src -I$(top_srcdir)/include $(SECP_INCLUDES) $(SECP_TEST_INCLUDES)
if VALGRIND_ENABLED
tests_CPPFLAGS += -DVALGRIND
noinst_PROGRAMS += valgrind_ctime_test
valgrind_ctime_test_SOURCES = src/valgrind_ctime_test.c
valgrind_ctime_test_LDADD = libsecp256k1.la $(SECP_LIBS) $(SECP_LIBS) $(COMMON_LIB)
endif
TESTS += noverify_tests
noinst_PROGRAMS += noverify_tests
noverify_tests_SOURCES = src/tests.c
noverify_tests_CPPFLAGS = $(SECP_CONFIG_DEFINES)
noverify_tests_LDADD = $(COMMON_LIB) $(PRECOMPUTED_LIB)
noverify_tests_LDFLAGS = -static
if !ENABLE_COVERAGE
tests_CPPFLAGS += -DVERIFY
endif
tests_LDADD = $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB)
tests_LDFLAGS = -static
TESTS += tests
noinst_PROGRAMS += tests
tests_SOURCES = $(noverify_tests_SOURCES)
tests_CPPFLAGS = $(noverify_tests_CPPFLAGS) -DVERIFY
tests_LDADD = $(noverify_tests_LDADD)
tests_LDFLAGS = $(noverify_tests_LDFLAGS)
endif
endif
if USE_CTIME_TESTS
noinst_PROGRAMS += ctime_tests
ctime_tests_SOURCES = src/ctime_tests.c
ctime_tests_LDADD = libsecp256k1.la
ctime_tests_CPPFLAGS = $(SECP_CONFIG_DEFINES)
endif
if USE_EXHAUSTIVE_TESTS
noinst_PROGRAMS += exhaustive_tests
exhaustive_tests_SOURCES = src/tests_exhaustive.c
exhaustive_tests_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/src $(SECP_INCLUDES)
exhaustive_tests_CPPFLAGS = $(SECP_CONFIG_DEFINES)
if !ENABLE_COVERAGE
exhaustive_tests_CPPFLAGS += -DVERIFY
endif
exhaustive_tests_LDADD = $(SECP_LIBS) $(COMMON_LIB)
# Note: do not include $(PRECOMPUTED_LIB) in exhaustive_tests (it uses runtime-generated tables).
exhaustive_tests_LDADD = $(COMMON_LIB)
exhaustive_tests_LDFLAGS = -static
TESTS += exhaustive_tests
endif
if USE_ECMULT_STATIC_PRECOMPUTATION
CPPFLAGS_FOR_BUILD +=-I$(top_srcdir) -I$(builddir)/src
gen_context_OBJECTS = gen_context.o
gen_context_BIN = gen_context$(BUILD_EXEEXT)
gen_%.o: src/gen_%.c src/libsecp256k1-config.h
$(CC_FOR_BUILD) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) -c $< -o $@
$(gen_context_BIN): $(gen_context_OBJECTS)
$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) $^ -o $@
$(libsecp256k1_la_OBJECTS): src/ecmult_static_context.h
$(tests_OBJECTS): src/ecmult_static_context.h
$(bench_internal_OBJECTS): src/ecmult_static_context.h
$(bench_ecmult_OBJECTS): src/ecmult_static_context.h
src/ecmult_static_context.h: $(gen_context_BIN)
./$(gen_context_BIN)
CLEANFILES = $(gen_context_BIN) src/ecmult_static_context.h
if USE_EXAMPLES
noinst_PROGRAMS += ecdsa_example
ecdsa_example_SOURCES = examples/ecdsa.c
ecdsa_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
ecdsa_example_LDADD = libsecp256k1.la
ecdsa_example_LDFLAGS = -static
if BUILD_WINDOWS
ecdsa_example_LDFLAGS += -lbcrypt
endif
TESTS += ecdsa_example
if ENABLE_MODULE_ECDH
noinst_PROGRAMS += ecdh_example
ecdh_example_SOURCES = examples/ecdh.c
ecdh_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
ecdh_example_LDADD = libsecp256k1.la
ecdh_example_LDFLAGS = -static
if BUILD_WINDOWS
ecdh_example_LDFLAGS += -lbcrypt
endif
TESTS += ecdh_example
endif
if ENABLE_MODULE_SCHNORRSIG
noinst_PROGRAMS += schnorr_example
schnorr_example_SOURCES = examples/schnorr.c
schnorr_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
schnorr_example_LDADD = libsecp256k1.la
schnorr_example_LDFLAGS = -static
if BUILD_WINDOWS
schnorr_example_LDFLAGS += -lbcrypt
endif
TESTS += schnorr_example
endif
if ENABLE_MODULE_MUSIG
noinst_PROGRAMS += musig_example
musig_example_SOURCES = examples/musig.c
musig_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
musig_example_LDADD = libsecp256k1.la
musig_example_LDFLAGS = -static
if BUILD_WINDOWS
musig_example_LDFLAGS += -lbcrypt
endif
TESTS += musig_example
endif
if ENABLE_MODULE_FROST
noinst_PROGRAMS += frost_example
frost_example_SOURCES = examples/frost.c
frost_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
frost_example_LDADD = libsecp256k1.la
frost_example_LDFLAGS = -static
if BUILD_WINDOWS
frost_example_LDFLAGS += -lbcrypt
endif
TESTS += frost_example
endif
endif
EXTRA_DIST = autogen.sh src/gen_context.c src/basic-config.h
### Precomputed tables
EXTRA_PROGRAMS = precompute_ecmult precompute_ecmult_gen
CLEANFILES = $(EXTRA_PROGRAMS)
precompute_ecmult_SOURCES = src/precompute_ecmult.c
precompute_ecmult_CPPFLAGS = $(SECP_CONFIG_DEFINES) -DVERIFY
precompute_ecmult_LDADD = $(COMMON_LIB)
precompute_ecmult_gen_SOURCES = src/precompute_ecmult_gen.c
precompute_ecmult_gen_CPPFLAGS = $(SECP_CONFIG_DEFINES) -DVERIFY
precompute_ecmult_gen_LDADD = $(COMMON_LIB)
# See Automake manual, Section "Errors with distclean".
# We don't list any dependencies for the prebuilt files here because
# otherwise make's decision whether to rebuild them (even in the first
# build by a normal user) depends on mtimes, and thus is very fragile.
# This means that rebuilds of the prebuilt files always need to be
# forced by deleting them.
src/precomputed_ecmult.c:
$(MAKE) $(AM_MAKEFLAGS) precompute_ecmult$(EXEEXT)
./precompute_ecmult$(EXEEXT)
src/precomputed_ecmult_gen.c:
$(MAKE) $(AM_MAKEFLAGS) precompute_ecmult_gen$(EXEEXT)
./precompute_ecmult_gen$(EXEEXT)
PRECOMP = src/precomputed_ecmult_gen.c src/precomputed_ecmult.c
precomp: $(PRECOMP)
# Ensure the prebuilt files will be build first (only if they don't exist,
# e.g., after `make maintainer-clean`).
BUILT_SOURCES = $(PRECOMP)
.PHONY: clean-precomp
clean-precomp:
rm -f $(PRECOMP)
maintainer-clean-local: clean-precomp
### Pregenerated test vectors
### (see the comments in the previous section for detailed rationale)
TESTVECTORS = src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h
src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h:
mkdir -p $(@D)
python3 $(top_srcdir)/tools/tests_wycheproof_generate.py $(top_srcdir)/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json > $@
testvectors: $(TESTVECTORS)
BUILT_SOURCES += $(TESTVECTORS)
.PHONY: clean-testvectors
clean-testvectors:
rm -f $(TESTVECTORS)
maintainer-clean-local: clean-testvectors
### Additional files to distribute
EXTRA_DIST = autogen.sh CHANGELOG.md SECURITY.md
EXTRA_DIST += doc/release-process.md doc/safegcd_implementation.md
EXTRA_DIST += examples/EXAMPLES_COPYING
EXTRA_DIST += sage/gen_exhaustive_groups.sage
EXTRA_DIST += sage/gen_split_lambda_constants.sage
EXTRA_DIST += sage/group_prover.sage
EXTRA_DIST += sage/prove_group_implementations.sage
EXTRA_DIST += sage/secp256k1_params.sage
EXTRA_DIST += sage/weierstrass_prover.sage
EXTRA_DIST += src/wycheproof/WYCHEPROOF_COPYING
EXTRA_DIST += src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json
EXTRA_DIST += tools/tests_wycheproof_generate.py
if ENABLE_MODULE_SCHNORRSIG_HALFAGG
include src/modules/schnorrsig_halfagg/Makefile.am.include
endif
if ENABLE_MODULE_BPPP
include src/modules/bppp/Makefile.am.include
endif
if ENABLE_MODULE_ECDH
include src/modules/ecdh/Makefile.am.include
@@ -182,3 +319,19 @@ endif
if ENABLE_MODULE_SCHNORRSIG
include src/modules/schnorrsig/Makefile.am.include
endif
if ENABLE_MODULE_ELLSWIFT
include src/modules/ellswift/Makefile.am.include
endif
if ENABLE_MODULE_ECDSA_S2C
include src/modules/ecdsa_s2c/Makefile.am.include
endif
if ENABLE_MODULE_ECDSA_ADAPTOR
include src/modules/ecdsa_adaptor/Makefile.am.include
endif
if ENABLE_MODULE_FROST
include src/modules/frost/Makefile.am.include
endif

151
README.md
View File

@@ -1,104 +1,101 @@
libsecp256k1
============
libsecp256k1-zkp
================
[![Build Status](https://travis-ci.org/bitcoin-core/secp256k1.svg?branch=master)](https://travis-ci.org/bitcoin-core/secp256k1)
![Dependencies: None](https://img.shields.io/badge/dependencies-none-success)
Optimized C library for ECDSA signatures and secret/public key operations on curve secp256k1.
A fork of [libsecp256k1](https://github.com/bitcoin-core/secp256k1) with support for advanced and experimental features such as Confidential Assets, MuSig2, and FROST.
This library is intended to be the highest quality publicly available library for cryptography on the secp256k1 curve. However, the primary focus of its development has been for usage in the Bitcoin system and usage unlike Bitcoin's may be less well tested, verified, or suffer from a less well thought out interface. Correct usage requires some care and consideration that the library is fit for your application's purpose.
Added features:
* Experimental module for ECDSA adaptor signatures.
* Experimental module for ECDSA sign-to-contract.
* Experimental module for [MuSig2](src/modules/musig/musig.md).
* Experimental module for Confidential Assets (Pedersen commitments, range proofs, and [surjection proofs](src/modules/surjection/surjection.md)).
* Experimental module for Bulletproofs++ range proofs.
* Experimental module for [address whitelisting](src/modules/whitelist/whitelist.md).
* Experimental module for [FROST](src/modules/frost/frost.md).
Features:
* secp256k1 ECDSA signing/verification and key generation.
* Additive and multiplicative tweaking of secret/public keys.
* Serialization/parsing of secret keys, public keys, signatures.
* Constant time, constant memory access signing and public key generation.
* Derandomized ECDSA (via RFC6979 or with a caller provided function.)
* Very efficient implementation.
* Suitable for embedded systems.
* Optional module for public key recovery.
* Optional module for ECDH key exchange.
Experimental features have not received enough scrutiny to satisfy the standard of quality of this library but are made available for testing and review by the community. The APIs of these features should not be considered stable.
Implementation details
----------------------
* General
* No runtime heap allocation.
* Extensive testing infrastructure.
* Structured to facilitate review and analysis.
* Intended to be portable to any system with a C89 compiler and uint64_t support.
* No use of floating types.
* Expose only higher level interfaces to minimize the API surface and improve application security. ("Be difficult to use insecurely.")
* Field operations
* Optimized implementation of arithmetic modulo the curve's field size (2^256 - 0x1000003D1).
* Using 5 52-bit limbs (including hand-optimized assembly for x86_64, by Diederik Huys).
* Using 10 26-bit limbs (including hand-optimized assembly for 32-bit ARM, by Wladimir J. van der Laan).
* Field inverses and square roots using a sliding window over blocks of 1s (by Peter Dettman).
* Scalar operations
* Optimized implementation without data-dependent branches of arithmetic modulo the curve's order.
* Using 4 64-bit limbs (relying on __int128 support in the compiler).
* Using 8 32-bit limbs.
* Group operations
* Point addition formula specifically simplified for the curve equation (y^2 = x^3 + 7).
* Use addition between points in Jacobian and affine coordinates where possible.
* Use a unified addition/doubling formula where necessary to avoid data-dependent branches.
* Point/x comparison without a field inversion by comparison in the Jacobian coordinate space.
* Point multiplication for verification (a*P + b*G).
* Use wNAF notation for point multiplicands.
* Use a much larger window for multiples of G, using precomputed multiples.
* Use Shamir's trick to do the multiplication with the public key and the generator simultaneously.
* Use secp256k1's efficiently-computable endomorphism to split the P multiplicand into 2 half-sized ones.
* Point multiplication for signing
* Use a precomputed table of multiples of powers of 16 multiplied with the generator, so general multiplication becomes a series of additions.
* Intended to be completely free of timing sidechannels for secret-key operations (on reasonable hardware/toolchains)
* Access the table with branch-free conditional moves so memory access is uniform.
* No data-dependent branches
* Optional runtime blinding which attempts to frustrate differential power analysis.
* The precomputed tables add and eventually subtract points for which no known scalar (secret key) is known, preventing even an attacker with control over the secret key used to control the data internally.
Experimental features are made available for testing and review by the community. The APIs of these features should not be considered stable.
Build steps
-----------
libsecp256k1 is built using autotools:
Building with Autotools
-----------------------
$ ./autogen.sh
$ ./configure
$ make
$ make check
$ make check # run the test suite
$ sudo make install # optional
Exhaustive tests
To compile optional modules (such as Schnorr signatures), you need to run `./configure` with additional flags (such as `--enable-module-schnorrsig`). Run `./configure --help` to see the full list of available flags. For experimental modules, you will also need `--enable-experimental` as well as a flag for each individual module, e.g. `--enable-module-musig`.
Building with CMake (experimental)
----------------------------------
To maintain a pristine source tree, CMake encourages to perform an out-of-source build by using a separate dedicated build tree.
### Building on POSIX systems
$ mkdir build && cd build
$ cmake ..
$ cmake --build .
$ ctest # run the test suite
$ sudo cmake --build . --target install # optional
To compile optional modules (such as Schnorr signatures), you need to run `cmake` with additional flags (such as `-DSECP256K1_ENABLE_MODULE_SCHNORRSIG=ON`). Run `cmake .. -LH` to see the full list of available flags.
### Cross compiling
To alleviate issues with cross compiling, preconfigured toolchain files are available in the `cmake` directory.
For example, to cross compile for Windows:
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/x86_64-w64-mingw32.toolchain.cmake
To cross compile for Android with [NDK](https://developer.android.com/ndk/guides/cmake) (using NDK's toolchain file, and assuming the `ANDROID_NDK_ROOT` environment variable has been set):
$ cmake .. -DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake" -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=28
### Building on Windows
To build on Windows with Visual Studio, a proper [generator](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#visual-studio-generators) must be specified for a new build tree.
The following example assumes using of Visual Studio 2022 and CMake v3.21+.
In "Developer Command Prompt for VS 2022":
>cmake -G "Visual Studio 17 2022" -A x64 -S . -B build
>cmake --build build --config RelWithDebInfo
Usage examples
-----------
$ ./exhaustive_tests
Usage examples can be found in the [examples](examples) directory. To compile them you need to configure with `--enable-examples`.
* [ECDSA example](examples/ecdsa.c)
* [Schnorr signatures example](examples/schnorr.c)
* [Deriving a shared secret (ECDH) example](examples/ecdh.c)
* [MuSig example](examples/musig.c)
With valgrind, you might need to increase the max stack size:
To compile the Schnorr signature, ECDH and MuSig examples, you need to enable the corresponding module by providing a flag to the `configure` script, for example `--enable-module-schnorrsig`.
$ valgrind --max-stackframe=2500000 ./exhaustive_tests
Benchmark
------------
If configured with `--enable-benchmark` (which is the default), binaries for benchmarking the libsecp256k1-zkp functions will be present in the root directory after the build.
Test coverage
-----------
To print the benchmark result to the command line:
This library aims to have full coverage of the reachable lines and branches.
$ ./bench_name
To create a test coverage report, configure with `--enable-coverage` (use of GCC is necessary):
To create a CSV file for the benchmark result :
$ ./configure --enable-coverage
Run the tests:
$ make check
To create a report, `gcovr` is recommended, as it includes branch coverage reporting:
$ gcovr --exclude 'src/bench*' --print-summary
To create a HTML report with coloured and annotated source code:
$ gcovr --exclude 'src/bench*' --html --html-details -o coverage.html
$ ./bench_name | sed '2d;s/ \{1,\}//g' > bench_name.csv
Reporting a vulnerability
------------
See [SECURITY.md](SECURITY.md)
Contributing to libsecp256k1
------------
See [CONTRIBUTING.md](CONTRIBUTING.md)

View File

@@ -9,7 +9,7 @@ The following keys may be used to communicate sensitive information to developer
| Name | Fingerprint |
|------|-------------|
| Pieter Wuille | 133E AC17 9436 F14A 5CF1 B794 860F EB80 4E66 9320 |
| Andrew Poelstra | 699A 63EF C17A D3A9 A34C FFC0 7AD0 A91C 40BD 0091 |
| Jonas Nick | 36C7 1A37 C9D9 88BD E825 08D9 B1A7 0E4F 8DCD 0366 |
| Tim Ruffing | 09E0 3F87 1092 E40E 106E 902B 33BC 86AB 80FF 5516 |
You can import a key by running the following command with that individuals fingerprint: `gpg --recv-keys "<fingerprint>"` Ensure that you put quotes around fingerprints containing spaces.
You can import a key by running the following command with that individuals fingerprint: `gpg --keyserver hkps://keys.openpgp.org --recv-keys "<fingerprint>"` Ensure that you put quotes around fingerprints containing spaces.

View File

@@ -1,125 +0,0 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_PROG_CC_FOR_BUILD
#
# DESCRIPTION
#
# This macro searches for a C compiler that generates native executables,
# that is a C compiler that surely is not a cross-compiler. This can be
# useful if you have to generate source code at compile-time like for
# example GCC does.
#
# The macro sets the CC_FOR_BUILD and CPP_FOR_BUILD macros to anything
# needed to compile or link (CC_FOR_BUILD) and preprocess (CPP_FOR_BUILD).
# The value of these variables can be overridden by the user by specifying
# a compiler with an environment variable (like you do for standard CC).
#
# It also sets BUILD_EXEEXT and BUILD_OBJEXT to the executable and object
# file extensions for the build platform, and GCC_FOR_BUILD to `yes' if
# the compiler we found is GCC. All these variables but GCC_FOR_BUILD are
# substituted in the Makefile.
#
# LICENSE
#
# Copyright (c) 2008 Paolo Bonzini <bonzini@gnu.org>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 8
AU_ALIAS([AC_PROG_CC_FOR_BUILD], [AX_PROG_CC_FOR_BUILD])
AC_DEFUN([AX_PROG_CC_FOR_BUILD], [dnl
AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AC_PROG_CPP])dnl
AC_REQUIRE([AC_EXEEXT])dnl
AC_REQUIRE([AC_CANONICAL_HOST])dnl
dnl Use the standard macros, but make them use other variable names
dnl
pushdef([ac_cv_prog_CPP], ac_cv_build_prog_CPP)dnl
pushdef([ac_cv_prog_gcc], ac_cv_build_prog_gcc)dnl
pushdef([ac_cv_prog_cc_works], ac_cv_build_prog_cc_works)dnl
pushdef([ac_cv_prog_cc_cross], ac_cv_build_prog_cc_cross)dnl
pushdef([ac_cv_prog_cc_g], ac_cv_build_prog_cc_g)dnl
pushdef([ac_cv_exeext], ac_cv_build_exeext)dnl
pushdef([ac_cv_objext], ac_cv_build_objext)dnl
pushdef([ac_exeext], ac_build_exeext)dnl
pushdef([ac_objext], ac_build_objext)dnl
pushdef([CC], CC_FOR_BUILD)dnl
pushdef([CPP], CPP_FOR_BUILD)dnl
pushdef([CFLAGS], CFLAGS_FOR_BUILD)dnl
pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)dnl
pushdef([LDFLAGS], LDFLAGS_FOR_BUILD)dnl
pushdef([host], build)dnl
pushdef([host_alias], build_alias)dnl
pushdef([host_cpu], build_cpu)dnl
pushdef([host_vendor], build_vendor)dnl
pushdef([host_os], build_os)dnl
pushdef([ac_cv_host], ac_cv_build)dnl
pushdef([ac_cv_host_alias], ac_cv_build_alias)dnl
pushdef([ac_cv_host_cpu], ac_cv_build_cpu)dnl
pushdef([ac_cv_host_vendor], ac_cv_build_vendor)dnl
pushdef([ac_cv_host_os], ac_cv_build_os)dnl
pushdef([ac_cpp], ac_build_cpp)dnl
pushdef([ac_compile], ac_build_compile)dnl
pushdef([ac_link], ac_build_link)dnl
save_cross_compiling=$cross_compiling
save_ac_tool_prefix=$ac_tool_prefix
cross_compiling=no
ac_tool_prefix=
AC_PROG_CC
AC_PROG_CPP
AC_EXEEXT
ac_tool_prefix=$save_ac_tool_prefix
cross_compiling=$save_cross_compiling
dnl Restore the old definitions
dnl
popdef([ac_link])dnl
popdef([ac_compile])dnl
popdef([ac_cpp])dnl
popdef([ac_cv_host_os])dnl
popdef([ac_cv_host_vendor])dnl
popdef([ac_cv_host_cpu])dnl
popdef([ac_cv_host_alias])dnl
popdef([ac_cv_host])dnl
popdef([host_os])dnl
popdef([host_vendor])dnl
popdef([host_cpu])dnl
popdef([host_alias])dnl
popdef([host])dnl
popdef([LDFLAGS])dnl
popdef([CPPFLAGS])dnl
popdef([CFLAGS])dnl
popdef([CPP])dnl
popdef([CC])dnl
popdef([ac_objext])dnl
popdef([ac_exeext])dnl
popdef([ac_cv_objext])dnl
popdef([ac_cv_exeext])dnl
popdef([ac_cv_prog_cc_g])dnl
popdef([ac_cv_prog_cc_cross])dnl
popdef([ac_cv_prog_cc_works])dnl
popdef([ac_cv_prog_gcc])dnl
popdef([ac_cv_prog_CPP])dnl
dnl Finally, set Makefile variables
dnl
BUILD_EXEEXT=$ac_build_exeext
BUILD_OBJEXT=$ac_build_objext
AC_SUBST(BUILD_EXEEXT)dnl
AC_SUBST(BUILD_OBJEXT)dnl
AC_SUBST([CFLAGS_FOR_BUILD])dnl
AC_SUBST([CPPFLAGS_FOR_BUILD])dnl
AC_SUBST([LDFLAGS_FOR_BUILD])dnl
])

View File

@@ -1,89 +1,75 @@
dnl escape "$0x" below using the m4 quadrigaph @S|@, and escape it again with a \ for the shell.
AC_DEFUN([SECP_64BIT_ASM_CHECK],[
AC_DEFUN([SECP_X86_64_ASM_CHECK],[
AC_MSG_CHECKING(for x86_64 assembly availability)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <stdint.h>]],[[
uint64_t a = 11, tmp;
__asm__ __volatile__("movq \@S|@0x100000000,%1; mulq %%rsi" : "+a"(a) : "S"(tmp) : "cc", "%rdx");
]])],[has_64bit_asm=yes],[has_64bit_asm=no])
AC_MSG_RESULT([$has_64bit_asm])
]])], [has_x86_64_asm=yes], [has_x86_64_asm=no])
AC_MSG_RESULT([$has_x86_64_asm])
])
dnl
AC_DEFUN([SECP_OPENSSL_CHECK],[
has_libcrypto=no
m4_ifdef([PKG_CHECK_MODULES],[
PKG_CHECK_MODULES([CRYPTO], [libcrypto], [has_libcrypto=yes],[has_libcrypto=no])
if test x"$has_libcrypto" = x"yes"; then
TEMP_LIBS="$LIBS"
LIBS="$LIBS $CRYPTO_LIBS"
AC_CHECK_LIB(crypto, main,[AC_DEFINE(HAVE_LIBCRYPTO,1,[Define this symbol if libcrypto is installed])],[has_libcrypto=no])
LIBS="$TEMP_LIBS"
fi
])
if test x$has_libcrypto = xno; then
AC_CHECK_HEADER(openssl/crypto.h,[
AC_CHECK_LIB(crypto, main,[
has_libcrypto=yes
CRYPTO_LIBS=-lcrypto
AC_DEFINE(HAVE_LIBCRYPTO,1,[Define this symbol if libcrypto is installed])
])
])
LIBS=
fi
if test x"$has_libcrypto" = x"yes" && test x"$has_openssl_ec" = x; then
AC_MSG_CHECKING(for EC functions in libcrypto)
AC_DEFUN([SECP_ARM32_ASM_CHECK], [
AC_MSG_CHECKING(for ARM32 assembly availability)
SECP_ARM32_ASM_CHECK_CFLAGS_saved_CFLAGS="$CFLAGS"
CFLAGS="-x assembler"
AC_LINK_IFELSE([AC_LANG_SOURCE([[
.syntax unified
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.text
.global main
main:
ldr r0, =0x002A
mov r7, #1
swi 0
]])], [has_arm32_asm=yes], [has_arm32_asm=no])
AC_MSG_RESULT([$has_arm32_asm])
CFLAGS="$SECP_ARM32_ASM_CHECK_CFLAGS_saved_CFLAGS"
])
AC_DEFUN([SECP_VALGRIND_CHECK],[
AC_MSG_CHECKING([for valgrind support])
if test x"$has_valgrind" != x"yes"; then
CPPFLAGS_TEMP="$CPPFLAGS"
CPPFLAGS="$CRYPTO_CPPFLAGS $CPPFLAGS"
CPPFLAGS="$VALGRIND_CPPFLAGS $CPPFLAGS"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/obj_mac.h>]],[[
# if OPENSSL_VERSION_NUMBER < 0x10100000L
void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) {(void)sig->r; (void)sig->s;}
# endif
unsigned int zero = 0;
const unsigned char *zero_ptr = (unsigned char*)&zero;
EC_KEY_free(EC_KEY_new_by_curve_name(NID_secp256k1));
EC_KEY *eckey = EC_KEY_new();
EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp256k1);
EC_KEY_set_group(eckey, group);
ECDSA_sign(0, NULL, 0, NULL, &zero, eckey);
ECDSA_verify(0, NULL, 0, NULL, 0, eckey);
o2i_ECPublicKey(&eckey, &zero_ptr, 0);
d2i_ECPrivateKey(&eckey, &zero_ptr, 0);
EC_KEY_check_key(eckey);
EC_KEY_free(eckey);
EC_GROUP_free(group);
ECDSA_SIG *sig_openssl;
sig_openssl = ECDSA_SIG_new();
d2i_ECDSA_SIG(&sig_openssl, &zero_ptr, 0);
i2d_ECDSA_SIG(sig_openssl, NULL);
ECDSA_SIG_get0(sig_openssl, NULL, NULL);
ECDSA_SIG_free(sig_openssl);
const BIGNUM *bignum = BN_value_one();
BN_is_negative(bignum);
BN_num_bits(bignum);
if (sizeof(zero) >= BN_num_bytes(bignum)) {
BN_bn2bin(bignum, (unsigned char*)&zero);
}
]])],[has_openssl_ec=yes],[has_openssl_ec=no])
AC_MSG_RESULT([$has_openssl_ec])
#include <valgrind/memcheck.h>
]], [[
#if defined(NVALGRIND)
# error "Valgrind does not support this platform."
#endif
]])], [has_valgrind=yes])
CPPFLAGS="$CPPFLAGS_TEMP"
fi
AC_MSG_RESULT($has_valgrind)
])
dnl
AC_DEFUN([SECP_GMP_CHECK],[
if test x"$has_gmp" != x"yes"; then
CPPFLAGS_TEMP="$CPPFLAGS"
CPPFLAGS="$GMP_CPPFLAGS $CPPFLAGS"
LIBS_TEMP="$LIBS"
LIBS="$GMP_LIBS $LIBS"
AC_CHECK_HEADER(gmp.h,[AC_CHECK_LIB(gmp, __gmpz_init,[has_gmp=yes; GMP_LIBS="$GMP_LIBS -lgmp"; AC_DEFINE(HAVE_LIBGMP,1,[Define this symbol if libgmp is installed])])])
CPPFLAGS="$CPPFLAGS_TEMP"
LIBS="$LIBS_TEMP"
fi
dnl SECP_TRY_APPEND_CFLAGS(flags, VAR)
dnl Append flags to VAR if CC accepts them.
AC_DEFUN([SECP_TRY_APPEND_CFLAGS], [
AC_MSG_CHECKING([if ${CC} supports $1])
SECP_TRY_APPEND_CFLAGS_saved_CFLAGS="$CFLAGS"
CFLAGS="$1 $CFLAGS"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])], [flag_works=yes], [flag_works=no])
AC_MSG_RESULT($flag_works)
CFLAGS="$SECP_TRY_APPEND_CFLAGS_saved_CFLAGS"
if test x"$flag_works" = x"yes"; then
$2="$$2 $1"
fi
unset flag_works
AC_SUBST($2)
])
dnl SECP_SET_DEFAULT(VAR, default, default-dev-mode)
dnl Set VAR to default or default-dev-mode, depending on whether dev mode is enabled
AC_DEFUN([SECP_SET_DEFAULT], [
if test "${enable_dev_mode+set}" != set; then
AC_MSG_ERROR([[Set enable_dev_mode before calling SECP_SET_DEFAULT]])
fi
if test x"$enable_dev_mode" = x"yes"; then
$1="$3"
else
$1="$2"
fi
])

157
ci/ci.sh Executable file
View File

@@ -0,0 +1,157 @@
#!/bin/sh
set -eux
export LC_ALL=C
# Print commit and relevant CI environment to allow reproducing the job outside of CI.
git show --no-patch
print_environment() {
# Turn off -x because it messes up the output
set +x
# There are many ways to print variable names and their content. This one
# does not rely on bash.
for var in WERROR_CFLAGS MAKEFLAGS BUILD \
ECMULTWINDOW ECMULTGENPRECISION ASM WIDEMUL WITH_VALGRIND EXTRAFLAGS \
EXPERIMENTAL ECDH RECOVERY SCHNORRSIG SCHNORRSIG_HALFAGG ELLSWIFT \
ECDSA_S2C GENERATOR RANGEPROOF WHITELIST MUSIG ECDSAADAPTOR BPPP \
FROST SECP256K1_TEST_ITERS BENCH SECP256K1_BENCH_ITERS CTIMETESTS\
EXAMPLES \
HOST WRAPPER_CMD \
CC CFLAGS CPPFLAGS AR NM
do
eval "isset=\${$var+x}"
if [ -n "$isset" ]; then
eval "val=\${$var}"
# shellcheck disable=SC2154
printf '%s="%s" ' "$var" "$val"
fi
done
echo "$0"
set -x
}
print_environment
env >> test_env.log
# If gcc is requested, assert that it's in fact gcc (and not some symlinked Apple clang).
case "${CC:-undefined}" in
*gcc*)
$CC -v 2>&1 | grep -q "gcc version" || exit 1;
;;
esac
if [ -n "${CC+x}" ]; then
# The MSVC compiler "cl" doesn't understand "-v"
$CC -v || true
fi
if [ "$WITH_VALGRIND" = "yes" ]; then
valgrind --version
fi
if [ -n "$WRAPPER_CMD" ]; then
$WRAPPER_CMD --version
fi
# Workaround for https://bugs.kde.org/show_bug.cgi?id=452758 (fixed in valgrind 3.20.0).
case "${CC:-undefined}" in
clang*)
if [ "$CTIMETESTS" = "yes" ] && [ "$WITH_VALGRIND" = "yes" ]
then
export CFLAGS="${CFLAGS:+$CFLAGS }-gdwarf-4"
else
case "$WRAPPER_CMD" in
valgrind*)
export CFLAGS="${CFLAGS:+$CFLAGS }-gdwarf-4"
;;
esac
fi
;;
esac
./autogen.sh
./configure \
--enable-experimental="$EXPERIMENTAL" \
--with-test-override-wide-multiply="$WIDEMUL" --with-asm="$ASM" \
--with-ecmult-window="$ECMULTWINDOW" \
--with-ecmult-gen-precision="$ECMULTGENPRECISION" \
--enable-module-ecdh="$ECDH" --enable-module-recovery="$RECOVERY" \
--enable-module-ellswift="$ELLSWIFT" \
--enable-module-ecdsa-s2c="$ECDSA_S2C" \
--enable-module-bppp="$BPPP" \
--enable-module-rangeproof="$RANGEPROOF" --enable-module-whitelist="$WHITELIST" --enable-module-generator="$GENERATOR" \
--enable-module-schnorrsig="$SCHNORRSIG" --enable-module-musig="$MUSIG" --enable-module-ecdsa-adaptor="$ECDSAADAPTOR" \
--enable-module-schnorrsig="$SCHNORRSIG" \
--enable-module-schnorrsig-halfagg="$SCHNORRSIG_HALFAGG" \
--enable-module-frost="$FROST" \
--enable-examples="$EXAMPLES" \
--enable-ctime-tests="$CTIMETESTS" \
--with-valgrind="$WITH_VALGRIND" \
--host="$HOST" $EXTRAFLAGS
# We have set "-j<n>" in MAKEFLAGS.
build_exit_code=0
make > make.log 2>&1 || build_exit_code=$?
cat make.log
if [ $build_exit_code -ne 0 ]; then
case "${CC:-undefined}" in
*snapshot*)
# Ignore internal compiler errors in gcc-snapshot and clang-snapshot
grep -e "internal compiler error:" -e "PLEASE submit a bug report" make.log
return $?;
;;
*)
return 1;
;;
esac
fi
# Print information about binaries so that we can see that the architecture is correct
file *tests* || true
file bench* || true
file .libs/* || true
# This tells `make check` to wrap test invocations.
export LOG_COMPILER="$WRAPPER_CMD"
make "$BUILD"
# Using the local `libtool` because on macOS the system's libtool has nothing to do with GNU libtool
EXEC='./libtool --mode=execute'
if [ -n "$WRAPPER_CMD" ]
then
EXEC="$EXEC $WRAPPER_CMD"
fi
if [ "$BENCH" = "yes" ]
then
{
$EXEC ./bench_ecmult
$EXEC ./bench_internal
$EXEC ./bench
if [ "$BPPP" = "yes" ]
then
$EXEC ./bench_bppp
fi
} >> bench.log 2>&1
fi
if [ "$CTIMETESTS" = "yes" ]
then
if [ "$WITH_VALGRIND" = "yes" ]; then
./libtool --mode=execute valgrind --error-exitcode=42 ./ctime_tests > ctime_tests.log 2>&1
else
$EXEC ./ctime_tests > ctime_tests.log 2>&1
fi
fi
# Rebuild precomputed files (if not cross-compiling).
if [ -z "$HOST" ]
then
make clean-precomp clean-testvectors
make precomp testvectors
fi
# Check that no repo files have been modified by the build.
# (This fails for example if the precomp files need to be updated in the repo.)
git diff --exit-code

View File

@@ -0,0 +1,79 @@
FROM debian:stable-slim
SHELL ["/bin/bash", "-c"]
WORKDIR /root
# A too high maximum number of file descriptors (with the default value
# inherited from the docker host) can cause issues with some of our tools:
# - sanitizers hanging: https://github.com/google/sanitizers/issues/1662
# - valgrind crashing: https://stackoverflow.com/a/75293014
# This is not be a problem on our CI hosts, but developers who run the image
# on their machines may run into this (e.g., on Arch Linux), so warn them.
# (Note that .bashrc is only executed in interactive bash shells.)
RUN echo 'if [[ $(ulimit -n) -gt 200000 ]]; then echo "WARNING: Very high value reported by \"ulimit -n\". Consider passing \"--ulimit nofile=32768\" to \"docker run\"."; fi' >> /root/.bashrc
RUN dpkg --add-architecture i386 && \
dpkg --add-architecture s390x && \
dpkg --add-architecture armhf && \
dpkg --add-architecture arm64 && \
dpkg --add-architecture ppc64el
# dkpg-dev: to make pkg-config work in cross-builds
# llvm: for llvm-symbolizer, which is used by clang's UBSan for symbolized stack traces
RUN apt-get update && apt-get install --no-install-recommends -y \
git ca-certificates \
make automake libtool pkg-config dpkg-dev valgrind qemu-user \
gcc clang llvm libclang-rt-dev libc6-dbg \
g++ \
gcc-i686-linux-gnu libc6-dev-i386-cross libc6-dbg:i386 libubsan1:i386 libasan8:i386 \
gcc-s390x-linux-gnu libc6-dev-s390x-cross libc6-dbg:s390x \
gcc-arm-linux-gnueabihf libc6-dev-armhf-cross libc6-dbg:armhf \
gcc-powerpc64le-linux-gnu libc6-dev-ppc64el-cross libc6-dbg:ppc64el \
gcc-mingw-w64-x86-64-win32 wine64 wine \
gcc-mingw-w64-i686-win32 wine32 \
python3 && \
if ! ( dpkg --print-architecture | grep --quiet "arm64" ) ; then \
apt-get install --no-install-recommends -y \
gcc-aarch64-linux-gnu libc6-dev-arm64-cross libc6-dbg:arm64 ;\
fi && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# Build and install gcc snapshot
ARG GCC_SNAPSHOT_MAJOR=14
RUN apt-get update && apt-get install --no-install-recommends -y wget libgmp-dev libmpfr-dev libmpc-dev flex && \
mkdir gcc && cd gcc && \
wget --progress=dot:giga --https-only --recursive --accept '*.tar.xz' --level 1 --no-directories "https://gcc.gnu.org/pub/gcc/snapshots/LATEST-${GCC_SNAPSHOT_MAJOR}" && \
wget "https://gcc.gnu.org/pub/gcc/snapshots/LATEST-${GCC_SNAPSHOT_MAJOR}/sha512.sum" && \
sha512sum --check --ignore-missing sha512.sum && \
# We should have downloaded exactly one tar.xz file
ls && \
[ $(ls *.tar.xz | wc -l) -eq "1" ] && \
tar xf *.tar.xz && \
mkdir gcc-build && cd gcc-build && \
../*/configure --prefix=/opt/gcc-snapshot --enable-languages=c --disable-bootstrap --disable-multilib --without-isl && \
make -j $(nproc) && \
make install && \
cd ../.. && rm -rf gcc && \
ln -s /opt/gcc-snapshot/bin/gcc /usr/bin/gcc-snapshot && \
apt-get autoremove -y wget libgmp-dev libmpfr-dev libmpc-dev flex && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# Install clang snapshot, see https://apt.llvm.org/
RUN \
# Setup GPG keys of LLVM repository
apt-get update && apt-get install --no-install-recommends -y wget && \
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc && \
# Add repository for this Debian release
. /etc/os-release && echo "deb http://apt.llvm.org/${VERSION_CODENAME} llvm-toolchain-${VERSION_CODENAME} main" >> /etc/apt/sources.list && \
apt-get update && \
# Determine the version number of the LLVM development branch
LLVM_VERSION=$(apt-cache search --names-only '^clang-[0-9]+$' | sort -V | tail -1 | cut -f1 -d" " | cut -f2 -d"-" ) && \
# Install
apt-get install --no-install-recommends -y "clang-${LLVM_VERSION}" && \
# Create symlink
ln -s "/usr/bin/clang-${LLVM_VERSION}" /usr/bin/clang-snapshot && \
# Clean up
apt-get autoremove -y wget && \
apt-get clean && rm -rf /var/lib/apt/lists/*

View File

@@ -0,0 +1,12 @@
# Add compile options to all targets added in the subdirectory.
function(all_targets_compile_options dir options)
get_directory_property(targets DIRECTORY ${dir} BUILDSYSTEM_TARGETS)
separate_arguments(options)
set(compiled_target_types STATIC_LIBRARY SHARED_LIBRARY OBJECT_LIBRARY EXECUTABLE)
foreach(target ${targets})
get_target_property(type ${target} TYPE)
if(type IN_LIST compiled_target_types)
target_compile_options(${target} PRIVATE ${options})
endif()
endforeach()
endfunction()

View File

@@ -0,0 +1,6 @@
function(check_arm32_assembly)
try_compile(HAVE_ARM32_ASM
${CMAKE_BINARY_DIR}/check_arm32_assembly
SOURCES ${CMAKE_SOURCE_DIR}/cmake/source_arm32.s
)
endfunction()

View File

@@ -0,0 +1,10 @@
function(check_string_option_value option)
get_property(expected_values CACHE ${option} PROPERTY STRINGS)
if(expected_values)
if(${option} IN_LIST expected_values)
return()
endif()
message(FATAL_ERROR "${option} value is \"${${option}}\", but must be one of ${expected_values}.")
endif()
message(AUTHOR_WARNING "The STRINGS property must be set before invoking `check_string_option_value' function.")
endfunction()

View File

@@ -0,0 +1,14 @@
include(CheckCSourceCompiles)
function(check_x86_64_assembly)
check_c_source_compiles("
#include <stdint.h>
int main()
{
uint64_t a = 11, tmp;
__asm__ __volatile__(\"movq $0x100000000,%1; mulq %%rsi\" : \"+a\"(a) : \"S\"(tmp) : \"cc\", \"%rdx\");
}
" HAVE_X86_64_ASM)
set(HAVE_X86_64_ASM ${HAVE_X86_64_ASM} PARENT_SCOPE)
endfunction()

41
cmake/FindValgrind.cmake Normal file
View File

@@ -0,0 +1,41 @@
if(CMAKE_HOST_APPLE)
find_program(BREW_COMMAND brew)
execute_process(
COMMAND ${BREW_COMMAND} --prefix valgrind
OUTPUT_VARIABLE valgrind_brew_prefix
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()
set(hints_paths)
if(valgrind_brew_prefix)
set(hints_paths ${valgrind_brew_prefix}/include)
endif()
find_path(Valgrind_INCLUDE_DIR
NAMES valgrind/memcheck.h
HINTS ${hints_paths}
)
if(Valgrind_INCLUDE_DIR)
include(CheckCSourceCompiles)
set(CMAKE_REQUIRED_INCLUDES ${Valgrind_INCLUDE_DIR})
check_c_source_compiles("
#include <valgrind/memcheck.h>
#if defined(NVALGRIND)
# error \"Valgrind does not support this platform.\"
#endif
int main() {}
" Valgrind_WORKS)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Valgrind
REQUIRED_VARS Valgrind_INCLUDE_DIR Valgrind_WORKS
)
mark_as_advanced(
Valgrind_INCLUDE_DIR
)

View File

@@ -0,0 +1,8 @@
function(generate_pkg_config_file in_file)
set(prefix ${CMAKE_INSTALL_PREFIX})
set(exec_prefix \${prefix})
set(libdir \${exec_prefix}/${CMAKE_INSTALL_LIBDIR})
set(includedir \${prefix}/${CMAKE_INSTALL_INCLUDEDIR})
set(PACKAGE_VERSION ${PROJECT_VERSION})
configure_file(${in_file} ${PROJECT_NAME}.pc @ONLY)
endfunction()

View File

@@ -0,0 +1,24 @@
include(CheckCCompilerFlag)
function(secp256k1_check_c_flags_internal flags output)
string(MAKE_C_IDENTIFIER "${flags}" result)
string(TOUPPER "${result}" result)
set(result "C_SUPPORTS_${result}")
if(NOT MSVC)
set(CMAKE_REQUIRED_FLAGS "-Werror")
endif()
# This avoids running a linker.
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
check_c_compiler_flag("${flags}" ${result})
set(${output} ${${result}} PARENT_SCOPE)
endfunction()
# Append flags to the COMPILE_OPTIONS directory property if CC accepts them.
macro(try_append_c_flags)
secp256k1_check_c_flags_internal("${ARGV}" result)
if(result)
add_compile_options(${ARGV})
endif()
endmacro()

View File

@@ -0,0 +1,3 @@
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)

5
cmake/config.cmake.in Normal file
View File

@@ -0,0 +1,5 @@
@PACKAGE_INIT@
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-targets.cmake")
check_required_components(@PROJECT_NAME@)

9
cmake/source_arm32.s Normal file
View File

@@ -0,0 +1,9 @@
.syntax unified
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.text
.global main
main:
ldr r0, =0x002A
mov r7, #1
swi 0

View File

@@ -0,0 +1,3 @@
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR x86_64)
set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,10 @@
/**********************************************************************
* Copyright (c) 2015 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
/***********************************************************************
* Copyright (c) 2015 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#include <string.h>
#include <secp256k1.h>
#include "lax_der_parsing.h"
@@ -121,7 +120,7 @@ int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_
/* Copy R value */
if (rlen > 32) {
overflow = 1;
} else {
} else if (rlen) {
memcpy(tmpsig + 32 - rlen, input + rpos, rlen);
}
@@ -133,7 +132,7 @@ int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_
/* Copy S value */
if (slen > 32) {
overflow = 1;
} else {
} else if (slen) {
memcpy(tmpsig + 64 - slen, input + spos, slen);
}

View File

@@ -1,8 +1,8 @@
/**********************************************************************
* Copyright (c) 2015 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
/***********************************************************************
* Copyright (c) 2015 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
/****
* Please do not link this file directly. It is not part of the libsecp256k1
@@ -51,7 +51,13 @@
#ifndef SECP256K1_CONTRIB_LAX_DER_PARSING_H
#define SECP256K1_CONTRIB_LAX_DER_PARSING_H
/* #include secp256k1.h only when it hasn't been included yet.
This enables this file to be #included directly in other project
files (such as tests.c) without the need to set an explicit -I flag,
which would be necessary to locate secp256k1.h. */
#ifndef SECP256K1_H
#include <secp256k1.h>
#endif
#ifdef __cplusplus
extern "C" {
@@ -61,8 +67,8 @@ extern "C" {
*
* Returns: 1 when the signature could be parsed, 0 otherwise.
* Args: ctx: a secp256k1 context object
* Out: sig: a pointer to a signature object
* In: input: a pointer to the signature to be parsed
* Out: sig: pointer to a signature object
* In: input: pointer to the signature to be parsed
* inputlen: the length of the array pointed to be input
*
* This function will accept any valid DER encoded signature, even if the

View File

@@ -1,11 +1,10 @@
/**********************************************************************
* Copyright (c) 2014, 2015 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
/***********************************************************************
* Copyright (c) 2014, 2015 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#include <string.h>
#include <secp256k1.h>
#include "lax_der_privatekey_parsing.h"
@@ -45,7 +44,7 @@ int ec_privkey_import_der(const secp256k1_context* ctx, unsigned char *out32, co
if (end < privkey+2 || privkey[0] != 0x04 || privkey[1] > 0x20 || end < privkey+2+privkey[1]) {
return 0;
}
memcpy(out32 + 32 - privkey[1], privkey + 2, privkey[1]);
if (privkey[1]) memcpy(out32 + 32 - privkey[1], privkey + 2, privkey[1]);
if (!secp256k1_ec_seckey_verify(ctx, out32)) {
memset(out32, 0, 32);
return 0;

View File

@@ -1,8 +1,8 @@
/**********************************************************************
* Copyright (c) 2014, 2015 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
/***********************************************************************
* Copyright (c) 2014, 2015 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
/****
* Please do not link this file directly. It is not part of the libsecp256k1
@@ -28,7 +28,13 @@
#ifndef SECP256K1_CONTRIB_BER_PRIVATEKEY_H
#define SECP256K1_CONTRIB_BER_PRIVATEKEY_H
/* #include secp256k1.h only when it hasn't been included yet.
This enables this file to be #included directly in other project
files (such as tests.c) without the need to set an explicit -I flag,
which would be necessary to locate secp256k1.h. */
#ifndef SECP256K1_H
#include <secp256k1.h>
#endif
#ifdef __cplusplus
extern "C" {
@@ -37,8 +43,7 @@ extern "C" {
/** Export a private key in DER format.
*
* Returns: 1 if the private key was valid.
* Args: ctx: pointer to a context object, initialized for signing (cannot
* be NULL)
* Args: ctx: pointer to a context object (not secp256k1_context_static).
* Out: privkey: pointer to an array for storing the private key in BER.
* Should have space for 279 bytes, and cannot be NULL.
* privkeylen: Pointer to an int where the length of the private key in

656
contrib/musig2-vectors.py Executable file
View File

@@ -0,0 +1,656 @@
#!/usr/bin/env python3
import sys
import json
import textwrap
max_pubkeys = 0
if len(sys.argv) < 2:
print(
"This script converts BIP MuSig2 test vectors in a given directory to a C file that can be used in the test framework."
)
print("Usage: %s <dir>" % sys.argv[0])
sys.exit(1)
def hexstr_to_intarray(str):
return ", ".join([f"0x{b:02X}" for b in bytes.fromhex(str)])
def create_init(name):
return """
static const struct musig_%s_vector musig_%s_vector = {
""" % (
name,
name,
)
def init_array(key):
return textwrap.indent("{ %s },\n" % hexstr_to_intarray(data[key]), 4 * " ")
def init_arrays(key):
s = textwrap.indent("{\n", 4 * " ")
s += textwrap.indent(
",\n".join(["{ %s }" % hexstr_to_intarray(x) for x in data[key]]), 8 * " "
)
s += textwrap.indent("\n},\n", 4 * " ")
return s
def init_indices(array):
return " %d, { %s }" % (
len(array),
", ".join(map(str, array) if len(array) > 0 else "0"),
)
def init_is_xonly(case):
if len(case["tweak_indices"]) > 0:
return ", ".join(map(lambda x: "1" if x else "0", case["is_xonly"]))
return "0"
def init_optional_expected(case):
return hexstr_to_intarray(case["expected"]) if "expected" in case else 0
def init_cases(cases, f):
s = textwrap.indent("{\n", 4 * " ")
for (i, case) in enumerate(cases):
s += textwrap.indent("%s\n" % f(case), 8 * " ")
s += textwrap.indent("},\n", 4 * " ")
return s
def finish_init():
return "};\n"
s = (
"""/**
* Automatically generated by %s.
*
* The test vectors for the KeySort function are included in this file. They can
* be found in src/modules/extrakeys/tests_impl.h. */
"""
% sys.argv[0]
)
s += """
enum MUSIG_ERROR {
MUSIG_PUBKEY,
MUSIG_TWEAK,
MUSIG_PUBNONCE,
MUSIG_AGGNONCE,
MUSIG_SECNONCE,
MUSIG_SIG,
MUSIG_SIG_VERIFY,
MUSIG_OTHER
};
"""
# key agg vectors
with open(sys.argv[1] + "/key_agg_vectors.json", "r") as f:
data = json.load(f)
max_key_indices = max(
len(test_case["key_indices"]) for test_case in data["valid_test_cases"]
)
max_tweak_indices = max(
len(test_case["tweak_indices"]) for test_case in data["error_test_cases"]
)
num_pubkeys = len(data["pubkeys"])
max_pubkeys = max(num_pubkeys, max_pubkeys)
num_tweaks = len(data["tweaks"])
num_valid_cases = len(data["valid_test_cases"])
num_error_cases = len(data["error_test_cases"])
# Add structures for valid and error cases
s += (
"""
struct musig_key_agg_valid_test_case {
size_t key_indices_len;
size_t key_indices[%d];
unsigned char expected[32];
};
"""
% max_key_indices
)
s += """
struct musig_key_agg_error_test_case {
size_t key_indices_len;
size_t key_indices[%d];
size_t tweak_indices_len;
size_t tweak_indices[%d];
int is_xonly[%d];
enum MUSIG_ERROR error;
};
""" % (
max_key_indices,
max_tweak_indices,
max_tweak_indices,
)
# Add structure for entire vector
s += """
struct musig_key_agg_vector {
unsigned char pubkeys[%d][33];
unsigned char tweaks[%d][32];
struct musig_key_agg_valid_test_case valid_case[%d];
struct musig_key_agg_error_test_case error_case[%d];
};
""" % (
num_pubkeys,
num_tweaks,
num_valid_cases,
num_error_cases,
)
s += create_init("key_agg")
# Add pubkeys and tweaks to the vector
s += init_arrays("pubkeys")
s += init_arrays("tweaks")
# Add valid cases to the vector
s += init_cases(
data["valid_test_cases"],
lambda case: "{ %s, { %s }},"
% (init_indices(case["key_indices"]), hexstr_to_intarray(case["expected"])),
)
def comment_to_error(case):
comment = case["comment"]
if "public key" in comment.lower():
return "MUSIG_PUBKEY"
elif "tweak" in comment.lower():
return "MUSIG_TWEAK"
else:
sys.exit("Unknown error")
# Add error cases to the vector
s += init_cases(
data["error_test_cases"],
lambda case: "{ %s, %s, { %s }, %s },"
% (
init_indices(case["key_indices"]),
init_indices(case["tweak_indices"]),
init_is_xonly(case),
comment_to_error(case),
),
)
s += finish_init()
# nonce gen vectors
with open(sys.argv[1] + "/nonce_gen_vectors.json", "r") as f:
data = json.load(f)
# The MuSig2 implementation only allows messages of length 32
data["test_cases"] = list(
filter(lambda c: c["msg"] is None or len(c["msg"]) == 64, data["test_cases"])
)
num_tests = len(data["test_cases"])
s += """
struct musig_nonce_gen_test_case {
unsigned char rand_[32];
int has_sk;
unsigned char sk[32];
unsigned char pk[33];
int has_aggpk;
unsigned char aggpk[32];
int has_msg;
unsigned char msg[32];
int has_extra_in;
unsigned char extra_in[32];
unsigned char expected_secnonce[97];
unsigned char expected_pubnonce[66];
};
"""
s += (
"""
struct musig_nonce_gen_vector {
struct musig_nonce_gen_test_case test_case[%d];
};
"""
% num_tests
)
s += create_init("nonce_gen")
def init_array_maybe(array):
return "%d , { %s }" % (
0 if array is None else 1,
hexstr_to_intarray(array) if array is not None else 0,
)
s += init_cases(
data["test_cases"],
lambda case: "{ { %s }, %s, { %s }, %s, %s, %s, { %s }, { %s } },"
% (
hexstr_to_intarray(case["rand_"]),
init_array_maybe(case["sk"]),
hexstr_to_intarray(case["pk"]),
init_array_maybe(case["aggpk"]),
init_array_maybe(case["msg"]),
init_array_maybe(case["extra_in"]),
hexstr_to_intarray(case["expected_secnonce"]),
hexstr_to_intarray(case["expected_pubnonce"]),
),
)
s += finish_init()
# nonce agg vectors
with open(sys.argv[1] + "/nonce_agg_vectors.json", "r") as f:
data = json.load(f)
num_pnonces = len(data["pnonces"])
num_valid_cases = len(data["valid_test_cases"])
num_error_cases = len(data["error_test_cases"])
pnonce_indices_len = 2
for case in data["valid_test_cases"] + data["error_test_cases"]:
assert len(case["pnonce_indices"]) == pnonce_indices_len
# Add structures for valid and error cases
s += """
struct musig_nonce_agg_test_case {
size_t pnonce_indices[2];
/* if valid case */
unsigned char expected[66];
/* if error case */
int invalid_nonce_idx;
};
"""
# Add structure for entire vector
s += """
struct musig_nonce_agg_vector {
unsigned char pnonces[%d][66];
struct musig_nonce_agg_test_case valid_case[%d];
struct musig_nonce_agg_test_case error_case[%d];
};
""" % (
num_pnonces,
num_valid_cases,
num_error_cases,
)
s += create_init("nonce_agg")
s += init_arrays("pnonces")
for cases in (data["valid_test_cases"], data["error_test_cases"]):
s += init_cases(
cases,
lambda case: "{ { %s }, { %s }, %d },"
% (
", ".join(map(str, case["pnonce_indices"])),
init_optional_expected(case),
case["error"]["signer"] if "error" in case else 0,
),
)
s += finish_init()
# sign/verify vectors
with open(sys.argv[1] + "/sign_verify_vectors.json", "r") as f:
data = json.load(f)
# The MuSig2 implementation only allows messages of length 32
assert list(filter(lambda x: len(x) == 64, data["msgs"]))[0] == data["msgs"][0]
data["msgs"] = [data["msgs"][0]]
def filter_msg32(k):
return list(filter(lambda x: x["msg_index"] == 0, data[k]))
data["valid_test_cases"] = filter_msg32("valid_test_cases")
data["sign_error_test_cases"] = filter_msg32("sign_error_test_cases")
data["verify_error_test_cases"] = filter_msg32("verify_error_test_cases")
data["verify_fail_test_cases"] = filter_msg32("verify_fail_test_cases")
num_pubkeys = len(data["pubkeys"])
max_pubkeys = max(num_pubkeys, max_pubkeys)
num_secnonces = len(data["secnonces"])
num_pubnonces = len(data["pnonces"])
num_aggnonces = len(data["aggnonces"])
num_msgs = len(data["msgs"])
num_valid_cases = len(data["valid_test_cases"])
num_sign_error_cases = len(data["sign_error_test_cases"])
num_verify_fail_cases = len(data["verify_fail_test_cases"])
num_verify_error_cases = len(data["verify_error_test_cases"])
all_cases = (
data["valid_test_cases"]
+ data["sign_error_test_cases"]
+ data["verify_error_test_cases"]
+ data["verify_fail_test_cases"]
)
max_key_indices = max(len(test_case["key_indices"]) for test_case in all_cases)
max_nonce_indices = max(
len(test_case["nonce_indices"]) if "nonce_indices" in test_case else 0
for test_case in all_cases
)
# Add structures for valid and error cases
s += (
"""
/* Omit pubnonces in the test vectors because our partial signature verification
* implementation is able to accept the aggnonce directly. */
struct musig_valid_case {
size_t key_indices_len;
size_t key_indices[%d];
size_t aggnonce_index;
size_t msg_index;
size_t signer_index;
unsigned char expected[32];
};
"""
% max_key_indices
)
s += (
"""
struct musig_sign_error_case {
size_t key_indices_len;
size_t key_indices[%d];
size_t aggnonce_index;
size_t msg_index;
size_t secnonce_index;
enum MUSIG_ERROR error;
};
"""
% max_key_indices
)
s += """
struct musig_verify_fail_error_case {
unsigned char sig[32];
size_t key_indices_len;
size_t key_indices[%d];
size_t nonce_indices_len;
size_t nonce_indices[%d];
size_t msg_index;
size_t signer_index;
enum MUSIG_ERROR error;
};
""" % (
max_key_indices,
max_nonce_indices,
)
# Add structure for entire vector
s += """
struct musig_sign_verify_vector {
unsigned char sk[32];
unsigned char pubkeys[%d][33];
unsigned char secnonces[%d][194];
unsigned char pubnonces[%d][194];
unsigned char aggnonces[%d][66];
unsigned char msgs[%d][32];
struct musig_valid_case valid_case[%d];
struct musig_sign_error_case sign_error_case[%d];
struct musig_verify_fail_error_case verify_fail_case[%d];
struct musig_verify_fail_error_case verify_error_case[%d];
};
""" % (
num_pubkeys,
num_secnonces,
num_pubnonces,
num_aggnonces,
num_msgs,
num_valid_cases,
num_sign_error_cases,
num_verify_fail_cases,
num_verify_error_cases,
)
s += create_init("sign_verify")
s += init_array("sk")
s += init_arrays("pubkeys")
s += init_arrays("secnonces")
s += init_arrays("pnonces")
s += init_arrays("aggnonces")
s += init_arrays("msgs")
s += init_cases(
data["valid_test_cases"],
lambda case: "{ %s, %d, %d, %d, { %s }},"
% (
init_indices(case["key_indices"]),
case["aggnonce_index"],
case["msg_index"],
case["signer_index"],
init_optional_expected(case),
),
)
def sign_error(case):
comment = case["comment"]
if "pubkey" in comment or "public key" in comment:
return "MUSIG_PUBKEY"
elif "Aggregate nonce" in comment:
return "MUSIG_AGGNONCE"
elif "Secnonce" in comment:
return "MUSIG_SECNONCE"
else:
sys.exit("Unknown sign error")
s += init_cases(
data["sign_error_test_cases"],
lambda case: "{ %s, %d, %d, %d, %s },"
% (
init_indices(case["key_indices"]),
case["aggnonce_index"],
case["msg_index"],
case["secnonce_index"],
sign_error(case),
),
)
def verify_error(case):
comment = case["comment"]
if "exceeds" in comment:
return "MUSIG_SIG"
elif "Wrong signer" in comment or "Wrong signature" in comment:
return "MUSIG_SIG_VERIFY"
elif "pubnonce" in comment:
return "MUSIG_PUBNONCE"
elif "pubkey" in comment:
return "MUSIG_PUBKEY"
else:
sys.exit("Unknown verify error")
for cases in ("verify_fail_test_cases", "verify_error_test_cases"):
s += init_cases(
data[cases],
lambda case: "{ { %s }, %s, %s, %d, %d, %s },"
% (
hexstr_to_intarray(case["sig"]),
init_indices(case["key_indices"]),
init_indices(case["nonce_indices"]),
case["msg_index"],
case["signer_index"],
verify_error(case),
),
)
s += finish_init()
# tweak vectors
with open(sys.argv[1] + "/tweak_vectors.json", "r") as f:
data = json.load(f)
num_pubkeys = len(data["pubkeys"])
max_pubkeys = max(num_pubkeys, max_pubkeys)
num_pubnonces = len(data["pnonces"])
num_tweaks = len(data["tweaks"])
num_valid_cases = len(data["valid_test_cases"])
num_error_cases = len(data["error_test_cases"])
all_cases = data["valid_test_cases"] + data["error_test_cases"]
max_key_indices = max(len(test_case["key_indices"]) for test_case in all_cases)
max_tweak_indices = max(len(test_case["tweak_indices"]) for test_case in all_cases)
max_nonce_indices = max(len(test_case["nonce_indices"]) for test_case in all_cases)
# Add structures for valid and error cases
s += """
struct musig_tweak_case {
size_t key_indices_len;
size_t key_indices[%d];
size_t nonce_indices_len;
size_t nonce_indices[%d];
size_t tweak_indices_len;
size_t tweak_indices[%d];
int is_xonly[%d];
size_t signer_index;
unsigned char expected[32];
};
""" % (
max_key_indices,
max_nonce_indices,
max_tweak_indices,
max_tweak_indices,
)
# Add structure for entire vector
s += """
struct musig_tweak_vector {
unsigned char sk[32];
unsigned char secnonce[97];
unsigned char aggnonce[66];
unsigned char msg[32];
unsigned char pubkeys[%d][33];
unsigned char pubnonces[%d][194];
unsigned char tweaks[%d][32];
struct musig_tweak_case valid_case[%d];
struct musig_tweak_case error_case[%d];
};
""" % (
num_pubkeys,
num_pubnonces,
num_tweaks,
num_valid_cases,
num_error_cases,
)
s += create_init("tweak")
s += init_array("sk")
s += init_array("secnonce")
s += init_array("aggnonce")
s += init_array("msg")
s += init_arrays("pubkeys")
s += init_arrays("pnonces")
s += init_arrays("tweaks")
s += init_cases(
data["valid_test_cases"],
lambda case: "{ %s, %s, %s, { %s }, %d, { %s }},"
% (
init_indices(case["key_indices"]),
init_indices(case["nonce_indices"]),
init_indices(case["tweak_indices"]),
init_is_xonly(case),
case["signer_index"],
init_optional_expected(case),
),
)
s += init_cases(
data["error_test_cases"],
lambda case: "{ %s, %s, %s, { %s }, %d, { %s }},"
% (
init_indices(case["key_indices"]),
init_indices(case["nonce_indices"]),
init_indices(case["tweak_indices"]),
init_is_xonly(case),
case["signer_index"],
init_optional_expected(case),
),
)
s += finish_init()
# sigagg vectors
with open(sys.argv[1] + "/sig_agg_vectors.json", "r") as f:
data = json.load(f)
num_pubkeys = len(data["pubkeys"])
max_pubkeys = max(num_pubkeys, max_pubkeys)
num_tweaks = len(data["tweaks"])
num_psigs = len(data["psigs"])
num_valid_cases = len(data["valid_test_cases"])
num_error_cases = len(data["error_test_cases"])
all_cases = data["valid_test_cases"] + data["error_test_cases"]
max_key_indices = max(len(test_case["key_indices"]) for test_case in all_cases)
max_tweak_indices = max(len(test_case["tweak_indices"]) for test_case in all_cases)
max_psig_indices = max(len(test_case["psig_indices"]) for test_case in all_cases)
# Add structures for valid and error cases
s += """
/* Omit pubnonces in the test vectors because they're only needed for
* implementations that do not directly accept an aggnonce. */
struct musig_sig_agg_case {
size_t key_indices_len;
size_t key_indices[%d];
size_t tweak_indices_len;
size_t tweak_indices[%d];
int is_xonly[%d];
unsigned char aggnonce[66];
size_t psig_indices_len;
size_t psig_indices[%d];
/* if valid case */
unsigned char expected[64];
/* if error case */
int invalid_sig_idx;
};
""" % (
max_key_indices,
max_tweak_indices,
max_tweak_indices,
max_psig_indices,
)
# Add structure for entire vector
s += """
struct musig_sig_agg_vector {
unsigned char pubkeys[%d][33];
unsigned char tweaks[%d][32];
unsigned char psigs[%d][32];
unsigned char msg[32];
struct musig_sig_agg_case valid_case[%d];
struct musig_sig_agg_case error_case[%d];
};
""" % (
num_pubkeys,
num_tweaks,
num_psigs,
num_valid_cases,
num_error_cases,
)
s += create_init("sig_agg")
s += init_arrays("pubkeys")
s += init_arrays("tweaks")
s += init_arrays("psigs")
s += init_array("msg")
for cases in (data["valid_test_cases"], data["error_test_cases"]):
s += init_cases(
cases,
lambda case: "{ %s, %s, { %s }, { %s }, %s, { %s }, %d },"
% (
init_indices(case["key_indices"]),
init_indices(case["tweak_indices"]),
init_is_xonly(case),
hexstr_to_intarray(case["aggnonce"]),
init_indices(case["psig_indices"]),
init_optional_expected(case),
case["error"]["signer"] if "error" in case else 0,
),
)
s += finish_init()
s += "enum { MUSIG_VECTORS_MAX_PUBKEYS = %d };" % max_pubkeys
print(s)

140
contrib/sync-upstream.sh Executable file
View File

@@ -0,0 +1,140 @@
#!/usr/bin/env bash
set -eou pipefail
help() {
echo "$0 [-b <branch>] range [end]"
echo " merges every merge commit present in upstream and missing in <branch> (default: master)."
echo " If the optional [end] commit is provided, only merges up to [end]."
echo " If the optional [-b branch] provided, then ."
echo
echo "$0 [-b <branch>] select <commit> ... <commit>"
echo " merges every selected merge commit into <branch> (default: master)"
echo
echo "This tool creates a branch and a script that can be executed to create the"
echo "PR automatically. The script requires the github-cli tool (aka gh)."
echo ""
echo "Tip: \`git log --oneline upstream/master --merges\` shows merge commits."
exit 1
}
REMOTE=upstream
REMOTE_BRANCH="$REMOTE/master"
LOCAL_BRANCH="master"
# Makes sure you have a remote "upstream" that is up-to-date
setup() {
ret=0
git fetch "$REMOTE" &> /dev/null || ret="$?"
if [ ${ret} == 0 ]; then
return
fi
echo "Adding remote \"$REMOTE\" with URL git@github.com:bitcoin-core/secp256k1.git. Continue with y"
read -r yn
case $yn in
[Yy]* ) ;;
* ) exit 1;;
esac
git remote add "$REMOTE" git@github.com:bitcoin-core/secp256k1.git &> /dev/null
git fetch "$REMOTE" &> /dev/null
}
range() {
RANGESTART_COMMIT=$(git merge-base "$REMOTE_BRANCH" "$LOCAL_BRANCH")
RANGEEND_COMMIT=$(git rev-parse "$REMOTE_BRANCH")
if [ "$#" = 1 ]; then
RANGEEND_COMMIT=$1
fi
COMMITS=$(git --no-pager log --oneline --merges "$RANGESTART_COMMIT".."$RANGEEND_COMMIT")
COMMITS=$(echo "$COMMITS" | tac | awk '{ print $1 }' ORS=' ')
echo "Merging $COMMITS. Continue with y"
read -r yn
case $yn in
[Yy]* ) ;;
* ) exit 1;;
esac
}
# Process -b <branch> argument
while getopts "b:" opt; do
case $opt in
b)
LOCAL_BRANCH=$OPTARG
;;
\?)
echo "Invalid option: -$OPTARG" >&2
;;
esac
done
# Shift off the processed options
shift $((OPTIND -1))
if [ "$#" -lt 1 ]; then
help
fi
case $1 in
range)
shift
setup
range "$@"
REPRODUCE_COMMAND="$0 -b $LOCAL_BRANCH range $RANGEEND_COMMIT"
;;
select)
shift
setup
COMMITS=$*
REPRODUCE_COMMAND="$0 -b $LOCAL_BRANCH select $@"
;;
help)
help
;;
*)
help
esac
TITLE="Upstream PRs"
BODY=""
for COMMIT in $COMMITS
do
PRNUM=$(git log -1 "$COMMIT" --pretty=format:%s | sed s/'Merge \(bitcoin-core\/secp256k1\)\?#\([0-9]*\).*'/'\2'/)
TITLE="$TITLE $PRNUM,"
BODY=$(printf "%s\n%s" "$BODY" "$(git log -1 "$COMMIT" --pretty=format:%s | sed s/'Merge \(bitcoin-core\/secp256k1\)\?#\([0-9]*\)'/'[bitcoin-core\/secp256k1#\2]'/)")
done
# Remove trailing ","
TITLE=${TITLE%?}
BODY=$(printf "%s\n\n%s\n%s" "$BODY" "This PR can be recreated with \`$REPRODUCE_COMMAND\`." "Tip: Use \`git show --remerge-diff\` to show the changes manually added to the merge commit.")
echo "-----------------------------------"
echo "$TITLE"
echo "-----------------------------------"
echo "$BODY"
echo "-----------------------------------"
# Create branch from PR commit and create PR
git checkout "$LOCAL_BRANCH"
git pull --autostash
git checkout -b temp-merge-"$PRNUM"
# Escape single quote
# ' -> '\''
quote() {
local quoted=${1//\'/\'\\\'\'}
printf "%s" "$quoted"
}
TITLE=$(quote "$TITLE")
BODY=$(quote "$BODY")
BASEDIR=$(dirname "$0")
FNAME="$BASEDIR/gh-pr-create.sh"
cat <<EOT > "$FNAME"
#!/bin/sh
gh pr create -t '$TITLE' -b '$BODY' --web
# Remove temporary branch
git checkout "$LOCAL_BRANCH"
git branch -D temp-merge-"$PRNUM"
EOT
chmod +x "$FNAME"
echo Run "$FNAME" after solving the merge conflicts
git merge --no-edit -m "Merge commits '$COMMITS' into temp-merge-$PRNUM" $COMMITS

View File

@@ -1,69 +0,0 @@
#!/bin/sh
set -e
set -x
if [ "$HOST" = "i686-linux-gnu" ]
then
export CC="$CC -m32"
fi
if [ "$TRAVIS_OS_NAME" = "osx" ] && [ "$TRAVIS_COMPILER" = "gcc" ]
then
export CC="gcc-9"
fi
./configure \
--enable-experimental="$EXPERIMENTAL" \
--with-test-override-wide-multiply="$WIDEMUL" --with-bignum="$BIGNUM" --with-asm="$ASM" \
--enable-ecmult-static-precomputation="$STATICPRECOMPUTATION" --with-ecmult-gen-precision="$ECMULTGENPRECISION" \
--enable-module-ecdh="$ECDH" --enable-module-recovery="$RECOVERY" \
--enable-module-rangeproof="$RANGEPROOF" --enable-module-whitelist="$WHITELIST" --enable-module-generator="$GENERATOR" \
--enable-module-schnorrsig="$SCHNORRSIG" --enable-module-musig="$MUSIG"\
--with-valgrind="$WITH_VALGRIND" \
--host="$HOST" $EXTRAFLAGS
if [ -n "$BUILD" ]
then
make -j2 "$BUILD"
fi
if [ "$RUN_VALGRIND" = "yes" ]
then
make -j2
# the `--error-exitcode` is required to make the test fail if valgrind found errors, otherwise it'll return 0 (http://valgrind.org/docs/manual/manual-core.html)
valgrind --error-exitcode=42 ./tests 16
valgrind --error-exitcode=42 ./exhaustive_tests
fi
if [ "$BENCH" = "yes" ]
then
if [ "$RUN_VALGRIND" = "yes" ]
then
# Using the local `libtool` because on macOS the system's libtool has nothing to do with GNU libtool
EXEC='./libtool --mode=execute valgrind --error-exitcode=42'
else
EXEC=
fi
# This limits the iterations in the benchmarks below to ITER(set in .travis.yml) iterations.
export SECP256K1_BENCH_ITERS="$ITERS"
{
$EXEC ./bench_ecmult
$EXEC ./bench_internal
$EXEC ./bench_sign
$EXEC ./bench_verify
} >> bench.log 2>&1
if [ "$RECOVERY" = "yes" ]
then
$EXEC ./bench_recover >> bench.log 2>&1
fi
if [ "$ECDH" = "yes" ]
then
$EXEC ./bench_ecdh >> bench.log 2>&1
fi
if [ "$SCHNORRSIG" = "yes" ]
then
$EXEC ./bench_schnorrsig >> bench.log 2>&1
fi
fi
if [ "$CTIMETEST" = "yes" ]
then
./libtool --mode=execute valgrind --error-exitcode=42 ./valgrind_ctime_test > valgrind_ctime_test.log 2>&1
fi

483
doc/ellswift.md Normal file
View File

@@ -0,0 +1,483 @@
# ElligatorSwift for secp256k1 explained
In this document we explain how the `ellswift` module implementation is related to the
construction in the
["SwiftEC: Shalluevan de Woestijne Indifferentiable Function To Elliptic Curves"](https://eprint.iacr.org/2022/759)
paper by Jorge Chávez-Saab, Francisco Rodríguez-Henríquez, and Mehdi Tibouchi.
* [1. Introduction](#1-introduction)
* [2. The decoding function](#2-the-decoding-function)
+ [2.1 Decoding for `secp256k1`](#21-decoding-for-secp256k1)
* [3. The encoding function](#3-the-encoding-function)
+ [3.1 Switching to *v, w* coordinates](#31-switching-to-v-w-coordinates)
+ [3.2 Avoiding computing all inverses](#32-avoiding-computing-all-inverses)
+ [3.3 Finding the inverse](#33-finding-the-inverse)
+ [3.4 Dealing with special cases](#34-dealing-with-special-cases)
+ [3.5 Encoding for `secp256k1`](#35-encoding-for-secp256k1)
* [4. Encoding and decoding full *(x, y)* coordinates](#4-encoding-and-decoding-full-x-y-coordinates)
+ [4.1 Full *(x, y)* coordinates for `secp256k1`](#41-full-x-y-coordinates-for-secp256k1)
## 1. Introduction
The `ellswift` module effectively introduces a new 64-byte public key format, with the property
that (uniformly random) public keys can be encoded as 64-byte arrays which are computationally
indistinguishable from uniform byte arrays. The module provides functions to convert public keys
from and to this format, as well as convenience functions for key generation and ECDH that operate
directly on ellswift-encoded keys.
The encoding consists of the concatenation of two (32-byte big endian) encoded field elements $u$
and $t.$ Together they encode an x-coordinate on the curve $x$, or (see further) a full point $(x, y)$ on
the curve.
**Decoding** consists of decoding the field elements $u$ and $t$ (values above the field size $p$
are taken modulo $p$), and then evaluating $F_u(t)$, which for every $u$ and $t$ results in a valid
x-coordinate on the curve. The functions $F_u$ will be defined in [Section 2](#2-the-decoding-function).
**Encoding** a given $x$ coordinate is conceptually done as follows:
* Loop:
* Pick a uniformly random field element $u.$
* Compute the set $L = F_u^{-1}(x)$ of $t$ values for which $F_u(t) = x$, which may have up to *8* elements.
* With probability $1 - \dfrac{\\#L}{8}$, restart the loop.
* Select a uniformly random $t \in L$ and return $(u, t).$
This is the *ElligatorSwift* algorithm, here given for just x-coordinates. An extension to full
$(x, y)$ points will be given in [Section 4](#4-encoding-and-decoding-full-x-y-coordinates).
The algorithm finds a uniformly random $(u, t)$ among (almost all) those
for which $F_u(t) = x.$ Section 3.2 in the paper proves that the number of such encodings for
almost all x-coordinates on the curve (all but at most 39) is close to two times the field size
(specifically, it lies in the range $2q \pm (22\sqrt{q} + O(1))$, where $q$ is the size of the field).
## 2. The decoding function
First some definitions:
* $\mathbb{F}$ is the finite field of size $q$, of characteristic 5 or more, and $q \equiv 1 \mod 3.$
* For `secp256k1`, $q = 2^{256} - 2^{32} - 977$, which satisfies that requirement.
* Let $E$ be the elliptic curve of points $(x, y) \in \mathbb{F}^2$ for which $y^2 = x^3 + ax + b$, with $a$ and $b$
public constants, for which $\Delta_E = -16(4a^3 + 27b^2)$ is a square, and at least one of $(-b \pm \sqrt{-3 \Delta_E} / 36)/2$ is a square.
This implies that the order of $E$ is either odd, or a multiple of *4*.
If $a=0$, this condition is always fulfilled.
* For `secp256k1`, $a=0$ and $b=7.$
* Let the function $g(x) = x^3 + ax + b$, so the $E$ curve equation is also $y^2 = g(x).$
* Let the function $h(x) = 3x^3 + 4a.$
* Define $V$ as the set of solutions $(x_1, x_2, x_3, z)$ to $z^2 = g(x_1)g(x_2)g(x_3).$
* Define $S_u$ as the set of solutions $(X, Y)$ to $X^2 + h(u)Y^2 = -g(u)$ and $Y \neq 0.$
* $P_u$ is a function from $\mathbb{F}$ to $S_u$ that will be defined below.
* $\psi_u$ is a function from $S_u$ to $V$ that will be defined below.
**Note**: In the paper:
* $F_u$ corresponds to $F_{0,u}$ there.
* $P_u(t)$ is called $P$ there.
* All $S_u$ sets together correspond to $S$ there.
* All $\psi_u$ functions together (operating on elements of $S$) correspond to $\psi$ there.
Note that for $V$, the left hand side of the equation $z^2$ is square, and thus the right
hand must also be square. As multiplying non-squares results in a square in $\mathbb{F}$,
out of the three right-hand side factors an even number must be non-squares.
This implies that exactly *1* or exactly *3* out of
$\\{g(x_1), g(x_2), g(x_3)\\}$ must be square, and thus that for any $(x_1,x_2,x_3,z) \in V$,
at least one of $\\{x_1, x_2, x_3\\}$ must be a valid x-coordinate on $E.$ There is one exception
to this, namely when $z=0$, but even then one of the three values is a valid x-coordinate.
**Define** the decoding function $F_u(t)$ as:
* Let $(x_1, x_2, x_3, z) = \psi_u(P_u(t)).$
* Return the first element $x$ of $(x_3, x_2, x_1)$ which is a valid x-coordinate on $E$ (i.e., $g(x)$ is square).
$P_u(t) = (X(u, t), Y(u, t))$, where:
$$
\begin{array}{lcl}
X(u, t) & = & \left\\{\begin{array}{ll}
\dfrac{g(u) - t^2}{2t} & a = 0 \\
\dfrac{g(u) + h(u)(Y_0(u) - X_0(u)t)^2}{X_0(u)(1 + h(u)t^2)} & a \neq 0
\end{array}\right. \\
Y(u, t) & = & \left\\{\begin{array}{ll}
\dfrac{X(u, t) + t}{u \sqrt{-3}} = \dfrac{g(u) + t^2}{2tu\sqrt{-3}} & a = 0 \\
Y_0(u) + t(X(u, t) - X_0(u)) & a \neq 0
\end{array}\right.
\end{array}
$$
$P_u(t)$ is defined:
* For $a=0$, unless:
* $u = 0$ or $t = 0$ (division by zero)
* $g(u) = -t^2$ (would give $Y=0$).
* For $a \neq 0$, unless:
* $X_0(u) = 0$ or $h(u)t^2 = -1$ (division by zero)
* $Y_0(u) (1 - h(u)t^2) = 2X_0(u)t$ (would give $Y=0$).
The functions $X_0(u)$ and $Y_0(u)$ are defined in Appendix A of the paper, and depend on various properties of $E.$
The function $\psi_u$ is the same for all curves: $\psi_u(X, Y) = (x_1, x_2, x_3, z)$, where:
$$
\begin{array}{lcl}
x_1 & = & \dfrac{X}{2Y} - \dfrac{u}{2} && \\
x_2 & = & -\dfrac{X}{2Y} - \dfrac{u}{2} && \\
x_3 & = & u + 4Y^2 && \\
z & = & \dfrac{g(x_3)}{2Y}(u^2 + ux_1 + x_1^2 + a) = \dfrac{-g(u)g(x_3)}{8Y^3}
\end{array}
$$
### 2.1 Decoding for `secp256k1`
Put together and specialized for $a=0$ curves, decoding $(u, t)$ to an x-coordinate is:
**Define** $F_u(t)$ as:
* Let $X = \dfrac{u^3 + b - t^2}{2t}.$
* Let $Y = \dfrac{X + t}{u\sqrt{-3}}.$
* Return the first $x$ in $(u + 4Y^2, \dfrac{-X}{2Y} - \dfrac{u}{2}, \dfrac{X}{2Y} - \dfrac{u}{2})$ for which $g(x)$ is square.
To make sure that every input decodes to a valid x-coordinate, we remap the inputs in case
$P_u$ is not defined (when $u=0$, $t=0$, or $g(u) = -t^2$):
**Define** $F_u(t)$ as:
* Let $u'=u$ if $u \neq 0$; $1$ otherwise (guaranteeing $u' \neq 0$).
* Let $t'=t$ if $t \neq 0$; $1$ otherwise (guaranteeing $t' \neq 0$).
* Let $t''=t'$ if $g(u') \neq -t'^2$; $2t'$ otherwise (guaranteeing $t'' \neq 0$ and $g(u') \neq -t''^2$).
* Let $X = \dfrac{u'^3 + b - t''^2}{2t''}.$
* Let $Y = \dfrac{X + t''}{u'\sqrt{-3}}.$
* Return the first $x$ in $(u' + 4Y^2, \dfrac{-X}{2Y} - \dfrac{u'}{2}, \dfrac{X}{2Y} - \dfrac{u'}{2})$ for which $x^3 + b$ is square.
The choices here are not strictly necessary. Just returning a fixed constant in any of the undefined cases would suffice,
but the approach here is simple enough and gives fairly uniform output even in these cases.
**Note**: in the paper these conditions result in $\infty$ as output, due to the use of projective coordinates there.
We wish to avoid the need for callers to deal with this special case.
This is implemented in `secp256k1_ellswift_xswiftec_frac_var` (which decodes to an x-coordinate represented as a fraction), and
in `secp256k1_ellswift_xswiftec_var` (which outputs the actual x-coordinate).
## 3. The encoding function
To implement $F_u^{-1}(x)$, the function to find the set of inverses $t$ for which $F_u(t) = x$, we have to reverse the process:
* Find all the $(X, Y) \in S_u$ that could have given rise to $x$, through the $x_1$, $x_2$, or $x_3$ formulas in $\psi_u.$
* Map those $(X, Y)$ solutions to $t$ values using $P_u^{-1}(X, Y).$
* For each of the found $t$ values, verify that $F_u(t) = x.$
* Return the remaining $t$ values.
The function $P_u^{-1}$, which finds $t$ given $(X, Y) \in S_u$, is significantly simpler than $P_u:$
$$
P_u^{-1}(X, Y) = \left\\{\begin{array}{ll}
Yu\sqrt{-3} - X & a = 0 \\
\dfrac{Y-Y_0(u)}{X-X_0(u)} & a \neq 0 \land X \neq X_0(u) \\
\dfrac{-X_0(u)}{h(u)Y_0(u)} & a \neq 0 \land X = X_0(u) \land Y = Y_0(u)
\end{array}\right.
$$
The third step above, verifying that $F_u(t) = x$, is necessary because for the $(X, Y)$ values found through the $x_1$ and $x_2$ expressions,
it is possible that decoding through $\psi_u(X, Y)$ yields a valid $x_3$ on the curve, which would take precedence over the
$x_1$ or $x_2$ decoding. These $(X, Y)$ solutions must be rejected.
Since we know that exactly one or exactly three out of $\\{x_1, x_2, x_3\\}$ are valid x-coordinates for any $t$,
the case where either $x_1$ or $x_2$ is valid and in addition also $x_3$ is valid must mean that all three are valid.
This means that instead of checking whether $x_3$ is on the curve, it is also possible to check whether the other one out of
$x_1$ and $x_2$ is on the curve. This is significantly simpler, as it turns out.
Observe that $\psi_u$ guarantees that $x_1 + x_2 = -u.$ So given either $x = x_1$ or $x = x_2$, the other one of the two can be computed as
$-u - x.$ Thus, when encoding $x$ through the $x_1$ or $x_2$ expressions, one can simply check whether $g(-u-x)$ is a square,
and if so, not include the corresponding $t$ values in the returned set. As this does not need $X$, $Y$, or $t$, this condition can be determined
before those values are computed.
It is not possible that an encoding found through the $x_1$ expression decodes to a different valid x-coordinate using $x_2$ (which would
take precedence), for the same reason: if both $x_1$ and $x_2$ decodings were valid, $x_3$ would be valid as well, and thus take
precedence over both. Because of this, the $g(-u-x)$ being square test for $x_1$ and $x_2$ is the only test necessary to guarantee the found $t$
values round-trip back to the input $x$ correctly. This is the reason for choosing the $(x_3, x_2, x_1)$ precedence order in the decoder;
any order which does not place $x_3$ first requires more complicated round-trip checks in the encoder.
### 3.1 Switching to *v, w* coordinates
Before working out the formulas for all this, we switch to different variables for $S_u.$ Let $v = (X/Y - u)/2$, and
$w = 2Y.$ Or in the other direction, $X = w(u/2 + v)$ and $Y = w/2:$
* $S_u'$ becomes the set of $(v, w)$ for which $w^2 (u^2 + uv + v^2 + a) = -g(u)$ and $w \neq 0.$
* For $a=0$ curves, $P_u^{-1}$ can be stated for $(v,w)$ as $P_u^{'-1}(v, w) = w\left(\frac{\sqrt{-3}-1}{2}u - v\right).$
* $\psi_u$ can be stated for $(v, w)$ as $\psi_u'(v, w) = (x_1, x_2, x_3, z)$, where
$$
\begin{array}{lcl}
x_1 & = & v \\
x_2 & = & -u - v \\
x_3 & = & u + w^2 \\
z & = & \dfrac{g(x_3)}{w}(u^2 + uv + v^2 + a) = \dfrac{-g(u)g(x_3)}{w^3}
\end{array}
$$
We can now write the expressions for finding $(v, w)$ given $x$ explicitly, by solving each of the $\\{x_1, x_2, x_3\\}$
expressions for $v$ or $w$, and using the $S_u'$ equation to find the other variable:
* Assuming $x = x_1$, we find $v = x$ and $w = \pm\sqrt{-g(u)/(u^2 + uv + v^2 + a)}$ (two solutions).
* Assuming $x = x_2$, we find $v = -u-x$ and $w = \pm\sqrt{-g(u)/(u^2 + uv + v^2 + a)}$ (two solutions).
* Assuming $x = x_3$, we find $w = \pm\sqrt{x-u}$ and $v = -u/2 \pm \sqrt{-w^2(4g(u) + w^2h(u))}/(2w^2)$ (four solutions).
### 3.2 Avoiding computing all inverses
The *ElligatorSwift* algorithm as stated in Section 1 requires the computation of $L = F_u^{-1}(x)$ (the
set of all $t$ such that $(u, t)$ decode to $x$) in full. This is unnecessary.
Observe that the procedure of restarting with probability $(1 - \frac{\\#L}{8})$ and otherwise returning a
uniformly random element from $L$ is actually equivalent to always padding $L$ with $\bot$ values up to length 8,
picking a uniformly random element from that, restarting whenever $\bot$ is picked:
**Define** *ElligatorSwift(x)* as:
* Loop:
* Pick a uniformly random field element $u.$
* Compute the set $L = F_u^{-1}(x).$
* Let $T$ be the 8-element vector consisting of the elements of $L$, plus $8 - \\#L$ times $\\{\bot\\}.$
* Select a uniformly random $t \in T.$
* If $t \neq \bot$, return $(u, t)$; restart loop otherwise.
Now notice that the order of elements in $T$ does not matter, as all we do is pick a uniformly
random element in it, so we do not need to have all $\bot$ values at the end.
As we have 8 distinct formulas for finding $(v, w)$ (taking the variants due to $\pm$ into account),
we can associate every index in $T$ with exactly one of those formulas, making sure that:
* Formulas that yield no solutions (due to division by zero or non-existing square roots) or invalid solutions are made to return $\bot.$
* For the $x_1$ and $x_2$ cases, if $g(-u-x)$ is a square, $\bot$ is returned instead (the round-trip check).
* In case multiple formulas would return the same non- $\bot$ result, all but one of those must be turned into $\bot$ to avoid biasing those.
The last condition above only occurs with negligible probability for cryptographically-sized curves, but is interesting
to take into account as it allows exhaustive testing in small groups. See [Section 3.4](#34-dealing-with-special-cases)
for an analysis of all the negligible cases.
If we define $T = (G_{0,u}(x), G_{1,u}(x), \ldots, G_{7,u}(x))$, with each $G_{i,u}$ matching one of the formulas,
the loop can be simplified to only compute one of the inverses instead of all of them:
**Define** *ElligatorSwift(x)* as:
* Loop:
* Pick a uniformly random field element $u.$
* Pick a uniformly random integer $c$ in $[0,8).$
* Let $t = G_{c,u}(x).$
* If $t \neq \bot$, return $(u, t)$; restart loop otherwise.
This is implemented in `secp256k1_ellswift_xelligatorswift_var`.
### 3.3 Finding the inverse
To implement $G_{c,u}$, we map $c=0$ to the $x_1$ formula, $c=1$ to the $x_2$ formula, and $c=2$ and $c=3$ to the $x_3$ formula.
Those are then repeated as $c=4$ through $c=7$ for the other sign of $w$ (noting that in each formula, $w$ is a square root of some expression).
Ignoring the negligible cases, we get:
**Define** $G_{c,u}(x)$ as:
* If $c \in \\{0, 1, 4, 5\\}$ (for $x_1$ and $x_2$ formulas):
* If $g(-u-x)$ is square, return $\bot$ (as $x_3$ would be valid and take precedence).
* If $c \in \\{0, 4\\}$ (the $x_1$ formula) let $v = x$, otherwise let $v = -u-x$ (the $x_2$ formula)
* Let $s = -g(u)/(u^2 + uv + v^2 + a)$ (using $s = w^2$ in what follows).
* Otherwise, when $c \in \\{2, 3, 6, 7\\}$ (for $x_3$ formulas):
* Let $s = x-u.$
* Let $r = \sqrt{-s(4g(u) + sh(u))}.$
* Let $v = (r/s - u)/2$ if $c \in \\{3, 7\\}$; $(-r/s - u)/2$ otherwise.
* Let $w = \sqrt{s}.$
* Depending on $c:$
* If $c \in \\{0, 1, 2, 3\\}:$ return $P_u^{'-1}(v, w).$
* If $c \in \\{4, 5, 6, 7\\}:$ return $P_u^{'-1}(v, -w).$
Whenever a square root of a non-square is taken, $\bot$ is returned; for both square roots this happens with roughly
50% on random inputs. Similarly, when a division by 0 would occur, $\bot$ is returned as well; this will only happen
with negligible probability. A division by 0 in the first branch in fact cannot occur at all, because $u^2 + uv + v^2 + a = 0$
implies $g(-u-x) = g(x)$ which would mean the $g(-u-x)$ is square condition has triggered
and $\bot$ would have been returned already.
**Note**: In the paper, the $case$ variable corresponds roughly to the $c$ above, but only takes on 4 possible values (1 to 4).
The conditional negation of $w$ at the end is done randomly, which is equivalent, but makes testing harder. We choose to
have the $G_{c,u}$ be deterministic, and capture all choices in $c.$
Now observe that the $c \in \\{1, 5\\}$ and $c \in \\{3, 7\\}$ conditions effectively perform the same $v \rightarrow -u-v$
transformation. Furthermore, that transformation has no effect on $s$ in the first branch
as $u^2 + ux + x^2 + a = u^2 + u(-u-x) + (-u-x)^2 + a.$ Thus we can extract it out and move it down:
**Define** $G_{c,u}(x)$ as:
* If $c \in \\{0, 1, 4, 5\\}:$
* If $g(-u-x)$ is square, return $\bot.$
* Let $s = -g(u)/(u^2 + ux + x^2 + a).$
* Let $v = x.$
* Otherwise, when $c \in \\{2, 3, 6, 7\\}:$
* Let $s = x-u.$
* Let $r = \sqrt{-s(4g(u) + sh(u))}.$
* Let $v = (r/s - u)/2.$
* Let $w = \sqrt{s}.$
* Depending on $c:$
* If $c \in \\{0, 2\\}:$ return $P_u^{'-1}(v, w).$
* If $c \in \\{1, 3\\}:$ return $P_u^{'-1}(-u-v, w).$
* If $c \in \\{4, 6\\}:$ return $P_u^{'-1}(v, -w).$
* If $c \in \\{5, 7\\}:$ return $P_u^{'-1}(-u-v, -w).$
This shows there will always be exactly 0, 4, or 8 $t$ values for a given $(u, x)$ input.
There can be 0, 1, or 2 $(v, w)$ pairs before invoking $P_u^{'-1}$, and each results in 4 distinct $t$ values.
### 3.4 Dealing with special cases
As mentioned before there are a few cases to deal with which only happen in a negligibly small subset of inputs.
For cryptographically sized fields, if only random inputs are going to be considered, it is unnecessary to deal with these. Still, for completeness
we analyse them here. They generally fall into two categories: cases in which the encoder would produce $t$ values that
do not decode back to $x$ (or at least cannot guarantee that they do), and cases in which the encoder might produce the same
$t$ value for multiple $c$ inputs (thereby biasing that encoding):
* In the branch for $x_1$ and $x_2$ (where $c \in \\{0, 1, 4, 5\\}$):
* When $g(u) = 0$, we would have $s=w=Y=0$, which is not on $S_u.$ This is only possible on even-ordered curves.
Excluding this also removes the one condition under which the simplified check for $x_3$ on the curve
fails (namely when $g(x_1)=g(x_2)=0$ but $g(x_3)$ is not square).
This does exclude some valid encodings: when both $g(u)=0$ and $u^2+ux+x^2+a=0$ (also implying $g(x)=0$),
the $S_u'$ equation degenerates to $0 = 0$, and many valid $t$ values may exist. Yet, these cannot be targeted uniformly by the
encoder anyway as there will generally be more than 8.
* When $g(x) = 0$, the same $t$ would be produced as in the $x_3$ branch (where $c \in \\{2, 3, 6, 7\\}$) which we give precedence
as it can deal with $g(u)=0$.
This is again only possible on even-ordered curves.
* In the branch for $x_3$ (where $c \in \\{2, 3, 6, 7\\}$):
* When $s=0$, a division by zero would occur.
* When $v = -u-v$ and $c \in \\{3, 7\\}$, the same $t$ would be returned as in the $c \in \\{2, 6\\}$ cases.
It is equivalent to checking whether $r=0$.
This cannot occur in the $x_1$ or $x_2$ branches, as it would trigger the $g(-u-x)$ is square condition.
A similar concern for $w = -w$ does not exist, as $w=0$ is already impossible in both branches: in the first
it requires $g(u)=0$ which is already outlawed on even-ordered curves and impossible on others; in the second it would trigger division by zero.
* Curve-specific special cases also exist that need to be rejected, because they result in $(u,t)$ which is invalid to the decoder, or because of division by zero in the encoder:
* For $a=0$ curves, when $u=0$ or when $t=0$. The latter can only be reached by the encoder when $g(u)=0$, which requires an even-ordered curve.
* For $a \neq 0$ curves, when $X_0(u)=0$, when $h(u)t^2 = -1$, or when $w(u + 2v) = 2X_0(u)$ while also either $w \neq 2Y_0(u)$ or $h(u)=0$.
**Define** a version of $G_{c,u}(x)$ which deals with all these cases:
* If $a=0$ and $u=0$, return $\bot.$
* If $a \neq 0$ and $X_0(u)=0$, return $\bot.$
* If $c \in \\{0, 1, 4, 5\\}:$
* If $g(u) = 0$ or $g(x) = 0$, return $\bot$ (even curves only).
* If $g(-u-x)$ is square, return $\bot.$
* Let $s = -g(u)/(u^2 + ux + x^2 + a)$ (cannot cause division by zero).
* Let $v = x.$
* Otherwise, when $c \in \\{2, 3, 6, 7\\}:$
* Let $s = x-u.$
* Let $r = \sqrt{-s(4g(u) + sh(u))}$; return $\bot$ if not square.
* If $c \in \\{3, 7\\}$ and $r=0$, return $\bot.$
* If $s = 0$, return $\bot.$
* Let $v = (r/s - u)/2.$
* Let $w = \sqrt{s}$; return $\bot$ if not square.
* If $a \neq 0$ and $w(u+2v) = 2X_0(u)$ and either $w \neq 2Y_0(u)$ or $h(u) = 0$, return $\bot.$
* Depending on $c:$
* If $c \in \\{0, 2\\}$, let $t = P_u^{'-1}(v, w).$
* If $c \in \\{1, 3\\}$, let $t = P_u^{'-1}(-u-v, w).$
* If $c \in \\{4, 6\\}$, let $t = P_u^{'-1}(v, -w).$
* If $c \in \\{5, 7\\}$, let $t = P_u^{'-1}(-u-v, -w).$
* If $a=0$ and $t=0$, return $\bot$ (even curves only).
* If $a \neq 0$ and $h(u)t^2 = -1$, return $\bot.$
* Return $t.$
Given any $u$, using this algorithm over all $x$ and $c$ values, every $t$ value will be reached exactly once,
for an $x$ for which $F_u(t) = x$ holds, except for these cases that will not be reached:
* All cases where $P_u(t)$ is not defined:
* For $a=0$ curves, when $u=0$, $t=0$, or $g(u) = -t^2.$
* For $a \neq 0$ curves, when $h(u)t^2 = -1$, $X_0(u) = 0$, or $Y_0(u) (1 - h(u) t^2) = 2X_0(u)t.$
* When $g(u)=0$, the potentially many $t$ values that decode to an $x$ satisfying $g(x)=0$ using the $x_2$ formula. These were excluded by the $g(u)=0$ condition in the $c \in \\{0, 1, 4, 5\\}$ branch.
These cases form a negligible subset of all $(u, t)$ for cryptographically sized curves.
### 3.5 Encoding for `secp256k1`
Specialized for odd-ordered $a=0$ curves:
**Define** $G_{c,u}(x)$ as:
* If $u=0$, return $\bot.$
* If $c \in \\{0, 1, 4, 5\\}:$
* If $(-u-x)^3 + b$ is square, return $\bot$
* Let $s = -(u^3 + b)/(u^2 + ux + x^2)$ (cannot cause division by 0).
* Let $v = x.$
* Otherwise, when $c \in \\{2, 3, 6, 7\\}:$
* Let $s = x-u.$
* Let $r = \sqrt{-s(4(u^3 + b) + 3su^2)}$; return $\bot$ if not square.
* If $c \in \\{3, 7\\}$ and $r=0$, return $\bot.$
* If $s = 0$, return $\bot.$
* Let $v = (r/s - u)/2.$
* Let $w = \sqrt{s}$; return $\bot$ if not square.
* Depending on $c:$
* If $c \in \\{0, 2\\}:$ return $w(\frac{\sqrt{-3}-1}{2}u - v).$
* If $c \in \\{1, 3\\}:$ return $w(\frac{\sqrt{-3}+1}{2}u + v).$
* If $c \in \\{4, 6\\}:$ return $w(\frac{-\sqrt{-3}+1}{2}u + v).$
* If $c \in \\{5, 7\\}:$ return $w(\frac{-\sqrt{-3}-1}{2}u - v).$
This is implemented in `secp256k1_ellswift_xswiftec_inv_var`.
And the x-only ElligatorSwift encoding algorithm is still:
**Define** *ElligatorSwift(x)* as:
* Loop:
* Pick a uniformly random field element $u.$
* Pick a uniformly random integer $c$ in $[0,8).$
* Let $t = G_{c,u}(x).$
* If $t \neq \bot$, return $(u, t)$; restart loop otherwise.
Note that this logic does not take the remapped $u=0$, $t=0$, and $g(u) = -t^2$ cases into account; it just avoids them.
While it is not impossible to make the encoder target them, this would increase the maximum number of $t$ values for a given $(u, x)$
combination beyond 8, and thereby slow down the ElligatorSwift loop proportionally, for a negligible gain in uniformity.
## 4. Encoding and decoding full *(x, y)* coordinates
So far we have only addressed encoding and decoding x-coordinates, but in some cases an encoding
for full points with $(x, y)$ coordinates is desirable. It is possible to encode this information
in $t$ as well.
Note that for any $(X, Y) \in S_u$, $(\pm X, \pm Y)$ are all on $S_u.$ Moreover, all of these are
mapped to the same x-coordinate. Negating $X$ or negating $Y$ just results in $x_1$ and $x_2$
being swapped, and does not affect $x_3.$ This will not change the outcome x-coordinate as the order
of $x_1$ and $x_2$ only matters if both were to be valid, and in that case $x_3$ would be used instead.
Still, these four $(X, Y)$ combinations all correspond to distinct $t$ values, so we can encode
the sign of the y-coordinate in the sign of $X$ or the sign of $Y.$ They correspond to the
four distinct $P_u^{'-1}$ calls in the definition of $G_{u,c}.$
**Note**: In the paper, the sign of the y coordinate is encoded in a separately-coded bit.
To encode the sign of $y$ in the sign of $Y:$
**Define** *Decode(u, t)* for full $(x, y)$ as:
* Let $(X, Y) = P_u(t).$
* Let $x$ be the first value in $(u + 4Y^2, \frac{-X}{2Y} - \frac{u}{2}, \frac{X}{2Y} - \frac{u}{2})$ for which $g(x)$ is square.
* Let $y = \sqrt{g(x)}.$
* If $sign(y) = sign(Y)$, return $(x, y)$; otherwise return $(x, -y).$
And encoding would be done using a $G_{c,u}(x, y)$ function defined as:
**Define** $G_{c,u}(x, y)$ as:
* If $c \in \\{0, 1\\}:$
* If $g(u) = 0$ or $g(x) = 0$, return $\bot$ (even curves only).
* If $g(-u-x)$ is square, return $\bot.$
* Let $s = -g(u)/(u^2 + ux + x^2 + a)$ (cannot cause division by zero).
* Let $v = x.$
* Otherwise, when $c \in \\{2, 3\\}:$
* Let $s = x-u.$
* Let $r = \sqrt{-s(4g(u) + sh(u))}$; return $\bot$ if not square.
* If $c = 3$ and $r = 0$, return $\bot.$
* Let $v = (r/s - u)/2.$
* Let $w = \sqrt{s}$; return $\bot$ if not square.
* Let $w' = w$ if $sign(w/2) = sign(y)$; $-w$ otherwise.
* Depending on $c:$
* If $c \in \\{0, 2\\}:$ return $P_u^{'-1}(v, w').$
* If $c \in \\{1, 3\\}:$ return $P_u^{'-1}(-u-v, w').$
Note that $c$ now only ranges $[0,4)$, as the sign of $w'$ is decided based on that of $y$, rather than on $c.$
This change makes some valid encodings unreachable: when $y = 0$ and $sign(Y) \neq sign(0)$.
In the above logic, $sign$ can be implemented in several ways, such as parity of the integer representation
of the input field element (for prime-sized fields) or the quadratic residuosity (for fields where
$-1$ is not square). The choice does not matter, as long as it only takes on two possible values, and for $x \neq 0$ it holds that $sign(x) \neq sign(-x)$.
### 4.1 Full *(x, y)* coordinates for `secp256k1`
For $a=0$ curves, there is another option. Note that for those,
the $P_u(t)$ function translates negations of $t$ to negations of (both) $X$ and $Y.$ Thus, we can use $sign(t)$ to
encode the y-coordinate directly. Combined with the earlier remapping to guarantee all inputs land on the curve, we get
as decoder:
**Define** *Decode(u, t)* as:
* Let $u'=u$ if $u \neq 0$; $1$ otherwise.
* Let $t'=t$ if $t \neq 0$; $1$ otherwise.
* Let $t''=t'$ if $u'^3 + b + t'^2 \neq 0$; $2t'$ otherwise.
* Let $X = \dfrac{u'^3 + b - t''^2}{2t''}.$
* Let $Y = \dfrac{X + t''}{u'\sqrt{-3}}.$
* Let $x$ be the first element of $(u' + 4Y^2, \frac{-X}{2Y} - \frac{u'}{2}, \frac{X}{2Y} - \frac{u'}{2})$ for which $g(x)$ is square.
* Let $y = \sqrt{g(x)}.$
* Return $(x, y)$ if $sign(y) = sign(t)$; $(x, -y)$ otherwise.
This is implemented in `secp256k1_ellswift_swiftec_var`. The used $sign(x)$ function is the parity of $x$ when represented as in integer in $[0,q).$
The corresponding encoder would invoke the x-only one, but negating the output $t$ if $sign(t) \neq sign(y).$
This is implemented in `secp256k1_ellswift_elligatorswift_var`.
Note that this is only intended for encoding points where both the x-coordinate and y-coordinate are unpredictable. When encoding x-only points
where the y-coordinate is implicitly even (or implicitly square, or implicitly in $[0,q/2]$), the encoder in
[Section 3.5](#35-encoding-for-secp256k1) must be used, or a bias is reintroduced that undoes all the benefit of using ElligatorSwift
in the first place.

1
doc/musig-spec.mediawiki Normal file
View File

@@ -0,0 +1 @@
This document was moved to [https://github.com/jonasnick/bips/blob/musig2/bip-musig2.mediawiki https://github.com/jonasnick/bips/blob/musig2/bip-musig2.mediawiki].

93
doc/release-process.md Normal file
View File

@@ -0,0 +1,93 @@
# Release process
This document outlines the process for releasing versions of the form `$MAJOR.$MINOR.$PATCH`.
We distinguish between two types of releases: *regular* and *maintenance* releases.
Regular releases are releases of a new major or minor version as well as patches of the most recent release.
Maintenance releases, on the other hand, are required for patches of older releases.
You should coordinate with the other maintainers on the release date, if possible.
This date will be part of the release entry in [CHANGELOG.md](../CHANGELOG.md) and it should match the dates of the remaining steps in the release process (including the date of the tag and the GitHub release).
It is best if the maintainers are present during the release, so they can help ensure that the process is followed correctly and, in the case of a regular release, they are aware that they should not modify the master branch between merging the PR in step 1 and the PR in step 3.
This process also assumes that there will be no minor releases for old major releases.
We aim to cut a regular release every 3-4 months, approximately twice as frequent as major Bitcoin Core releases. Every second release should be published one month before the feature freeze of the next major Bitcoin Core release, allowing sufficient time to update the library in Core.
## Sanity checks
Perform these checks when reviewing the release PR (see below):
1. Ensure `make distcheck` doesn't fail.
```shell
./autogen.sh && ./configure --enable-dev-mode && make distcheck
```
2. Check installation with autotools:
```shell
dir=$(mktemp -d)
./autogen.sh && ./configure --prefix=$dir && make clean && make install && ls -RlAh $dir
gcc -o ecdsa examples/ecdsa.c $(PKG_CONFIG_PATH=$dir/lib/pkgconfig pkg-config --cflags --libs libsecp256k1) -Wl,-rpath,"$dir/lib" && ./ecdsa
```
3. Check installation with CMake:
```shell
dir=$(mktemp -d)
build=$(mktemp -d)
cmake -B $build -DCMAKE_INSTALL_PREFIX=$dir && cmake --build $build --target install && ls -RlAh $dir
gcc -o ecdsa examples/ecdsa.c -I $dir/include -L $dir/lib*/ -l secp256k1 -Wl,-rpath,"$dir/lib",-rpath,"$dir/lib64" && ./ecdsa
```
4. Use the [`check-abi.sh`](/tools/check-abi.sh) tool to verify that there are no unexpected ABI incompatibilities and that the version number and the release notes accurately reflect all potential ABI changes. To run this tool, the `abi-dumper` and `abi-compliance-checker` packages are required.
```shell
tools/check-abi.sh
```
## Regular release
1. Open a PR to the master branch with a commit (using message `"release: prepare for $MAJOR.$MINOR.$PATCH"`, for example) that
* finalizes the release notes in [CHANGELOG.md](../CHANGELOG.md) by
* adding a section for the release (make sure that the version number is a link to a diff between the previous and new version),
* removing the `[Unreleased]` section header, and
* including an entry for `### ABI Compatibility` if it doesn't exist,
* sets `_PKG_VERSION_IS_RELEASE` to `true` in `configure.ac`, and,
* if this is not a patch release,
* updates `_PKG_VERSION_*` and `_LIB_VERSION_*` in `configure.ac`, and
* updates `project(libsecp256k1 VERSION ...)` and `${PROJECT_NAME}_LIB_VERSION_*` in `CMakeLists.txt`.
2. Perform the [sanity checks](#sanity-checks) on the PR branch.
3. After the PR is merged, tag the commit, and push the tag:
```
RELEASE_COMMIT=<merge commit of step 1>
git tag -s v$MAJOR.$MINOR.$PATCH -m "libsecp256k1 $MAJOR.$MINOR.$PATCH" $RELEASE_COMMIT
git push git@github.com:bitcoin-core/secp256k1.git v$MAJOR.$MINOR.$PATCH
```
4. Open a PR to the master branch with a commit (using message `"release cleanup: bump version after $MAJOR.$MINOR.$PATCH"`, for example) that
* sets `_PKG_VERSION_IS_RELEASE` to `false` and increments `_PKG_VERSION_PATCH` and `_LIB_VERSION_REVISION` in `configure.ac`,
* increments the `$PATCH` component of `project(libsecp256k1 VERSION ...)` and `${PROJECT_NAME}_LIB_VERSION_REVISION` in `CMakeLists.txt`, and
* adds an `[Unreleased]` section header to the [CHANGELOG.md](../CHANGELOG.md).
If other maintainers are not present to approve the PR, it can be merged without ACKs.
5. Create a new GitHub release with a link to the corresponding entry in [CHANGELOG.md](../CHANGELOG.md).
6. Send an announcement email to the bitcoin-dev mailing list.
## Maintenance release
Note that bug fixes need to be backported only to releases for which no compatible release without the bug exists.
1. If there's no maintenance branch `$MAJOR.$MINOR`, create one:
```
git checkout -b $MAJOR.$MINOR v$MAJOR.$MINOR.$((PATCH - 1))
git push git@github.com:bitcoin-core/secp256k1.git $MAJOR.$MINOR
```
2. Open a pull request to the `$MAJOR.$MINOR` branch that
* includes the bug fixes,
* finalizes the release notes similar to a regular release,
* increments `_PKG_VERSION_PATCH` and `_LIB_VERSION_REVISION` in `configure.ac`
and the `$PATCH` component of `project(libsecp256k1 VERSION ...)` and `${PROJECT_NAME}_LIB_VERSION_REVISION` in `CMakeLists.txt`
(with commit message `"release: bump versions for $MAJOR.$MINOR.$PATCH"`, for example).
3. Perform the [sanity checks](#sanity-checks) on the PR branch.
4. After the PRs are merged, update the release branch, tag the commit, and push the tag:
```
git checkout $MAJOR.$MINOR && git pull
git tag -s v$MAJOR.$MINOR.$PATCH -m "libsecp256k1 $MAJOR.$MINOR.$PATCH"
git push git@github.com:bitcoin-core/secp256k1.git v$MAJOR.$MINOR.$PATCH
```
6. Create a new GitHub release with a link to the corresponding entry in [CHANGELOG.md](../CHANGELOG.md).
7. Send an announcement email to the bitcoin-dev mailing list.
8. Open PR to the master branch that includes a commit (with commit message `"release notes: add $MAJOR.$MINOR.$PATCH"`, for example) that adds release notes to [CHANGELOG.md](../CHANGELOG.md).

View File

@@ -0,0 +1,819 @@
# The safegcd implementation in libsecp256k1 explained
This document explains the modular inverse and Jacobi symbol implementations in the `src/modinv*.h` files.
It is based on the paper
["Fast constant-time gcd computation and modular inversion"](https://gcd.cr.yp.to/papers.html#safegcd)
by Daniel J. Bernstein and Bo-Yin Yang. The references below are for the Date: 2019.04.13 version.
The actual implementation is in C of course, but for demonstration purposes Python3 is used here.
Most implementation aspects and optimizations are explained, except those that depend on the specific
number representation used in the C code.
## 1. Computing the Greatest Common Divisor (GCD) using divsteps
The algorithm from the paper (section 11), at a very high level, is this:
```python
def gcd(f, g):
"""Compute the GCD of an odd integer f and another integer g."""
assert f & 1 # require f to be odd
delta = 1 # additional state variable
while g != 0:
assert f & 1 # f will be odd in every iteration
if delta > 0 and g & 1:
delta, f, g = 1 - delta, g, (g - f) // 2
elif g & 1:
delta, f, g = 1 + delta, f, (g + f) // 2
else:
delta, f, g = 1 + delta, f, (g ) // 2
return abs(f)
```
It computes the greatest common divisor of an odd integer *f* and any integer *g*. Its inner loop
keeps rewriting the variables *f* and *g* alongside a state variable *&delta;* that starts at *1*, until
*g=0* is reached. At that point, *|f|* gives the GCD. Each of the transitions in the loop is called a
"division step" (referred to as divstep in what follows).
For example, *gcd(21, 14)* would be computed as:
- Start with *&delta;=1 f=21 g=14*
- Take the third branch: *&delta;=2 f=21 g=7*
- Take the first branch: *&delta;=-1 f=7 g=-7*
- Take the second branch: *&delta;=0 f=7 g=0*
- The answer *|f| = 7*.
Why it works:
- Divsteps can be decomposed into two steps (see paragraph 8.2 in the paper):
- (a) If *g* is odd, replace *(f,g)* with *(g,g-f)* or (f,g+f), resulting in an even *g*.
- (b) Replace *(f,g)* with *(f,g/2)* (where *g* is guaranteed to be even).
- Neither of those two operations change the GCD:
- For (a), assume *gcd(f,g)=c*, then it must be the case that *f=a&thinsp;c* and *g=b&thinsp;c* for some integers *a*
and *b*. As *(g,g-f)=(b&thinsp;c,(b-a)c)* and *(f,f+g)=(a&thinsp;c,(a+b)c)*, the result clearly still has
common factor *c*. Reasoning in the other direction shows that no common factor can be added by
doing so either.
- For (b), we know that *f* is odd, so *gcd(f,g)* clearly has no factor *2*, and we can remove
it from *g*.
- The algorithm will eventually converge to *g=0*. This is proven in the paper (see theorem G.3).
- It follows that eventually we find a final value *f'* for which *gcd(f,g) = gcd(f',0)*. As the
gcd of *f'* and *0* is *|f'|* by definition, that is our answer.
Compared to more [traditional GCD algorithms](https://en.wikipedia.org/wiki/Euclidean_algorithm), this one has the property of only ever looking at
the low-order bits of the variables to decide the next steps, and being easy to make
constant-time (in more low-level languages than Python). The *&delta;* parameter is necessary to
guide the algorithm towards shrinking the numbers' magnitudes without explicitly needing to look
at high order bits.
Properties that will become important later:
- Performing more divsteps than needed is not a problem, as *f* does not change anymore after *g=0*.
- Only even numbers are divided by *2*. This means that when reasoning about it algebraically we
do not need to worry about rounding.
- At every point during the algorithm's execution the next *N* steps only depend on the bottom *N*
bits of *f* and *g*, and on *&delta;*.
## 2. From GCDs to modular inverses
We want an algorithm to compute the inverse *a* of *x* modulo *M*, i.e. the number a such that *a&thinsp;x=1
mod M*. This inverse only exists if the GCD of *x* and *M* is *1*, but that is always the case if *M* is
prime and *0 < x < M*. In what follows, assume that the modular inverse exists.
It turns out this inverse can be computed as a side effect of computing the GCD by keeping track
of how the internal variables can be written as linear combinations of the inputs at every step
(see the [extended Euclidean algorithm](https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm)).
Since the GCD is *1*, such an algorithm will compute numbers *a* and *b* such that a&thinsp;x + b&thinsp;M = 1*.
Taking that expression *mod M* gives *a&thinsp;x mod M = 1*, and we see that *a* is the modular inverse of *x
mod M*.
A similar approach can be used to calculate modular inverses using the divsteps-based GCD
algorithm shown above, if the modulus *M* is odd. To do so, compute *gcd(f=M,g=x)*, while keeping
track of extra variables *d* and *e*, for which at every step *d = f/x (mod M)* and *e = g/x (mod M)*.
*f/x* here means the number which multiplied with *x* gives *f mod M*. As *f* and *g* are initialized to *M*
and *x* respectively, *d* and *e* just start off being *0* (*M/x mod M = 0/x mod M = 0*) and *1* (*x/x mod M
= 1*).
```python
def div2(M, x):
"""Helper routine to compute x/2 mod M (where M is odd)."""
assert M & 1
if x & 1: # If x is odd, make it even by adding M.
x += M
# x must be even now, so a clean division by 2 is possible.
return x // 2
def modinv(M, x):
"""Compute the inverse of x mod M (given that it exists, and M is odd)."""
assert M & 1
delta, f, g, d, e = 1, M, x, 0, 1
while g != 0:
# Note that while division by two for f and g is only ever done on even inputs, this is
# not true for d and e, so we need the div2 helper function.
if delta > 0 and g & 1:
delta, f, g, d, e = 1 - delta, g, (g - f) // 2, e, div2(M, e - d)
elif g & 1:
delta, f, g, d, e = 1 + delta, f, (g + f) // 2, d, div2(M, e + d)
else:
delta, f, g, d, e = 1 + delta, f, (g ) // 2, d, div2(M, e )
# Verify that the invariants d=f/x mod M, e=g/x mod M are maintained.
assert f % M == (d * x) % M
assert g % M == (e * x) % M
assert f == 1 or f == -1 # |f| is the GCD, it must be 1
# Because of invariant d = f/x (mod M), 1/x = d/f (mod M). As |f|=1, d/f = d*f.
return (d * f) % M
```
Also note that this approach to track *d* and *e* throughout the computation to determine the inverse
is different from the paper. There (see paragraph 12.1 in the paper) a transition matrix for the
entire computation is determined (see section 3 below) and the inverse is computed from that.
The approach here avoids the need for 2x2 matrix multiplications of various sizes, and appears to
be faster at the level of optimization we're able to do in C.
## 3. Batching multiple divsteps
Every divstep can be expressed as a matrix multiplication, applying a transition matrix *(1/2 t)*
to both vectors *[f, g]* and *[d, e]* (see paragraph 8.1 in the paper):
```
t = [ u, v ]
[ q, r ]
[ out_f ] = (1/2 * t) * [ in_f ]
[ out_g ] = [ in_g ]
[ out_d ] = (1/2 * t) * [ in_d ] (mod M)
[ out_e ] [ in_e ]
```
where *(u, v, q, r)* is *(0, 2, -1, 1)*, *(2, 0, 1, 1)*, or *(2, 0, 0, 1)*, depending on which branch is
taken. As above, the resulting *f* and *g* are always integers.
Performing multiple divsteps corresponds to a multiplication with the product of all the
individual divsteps' transition matrices. As each transition matrix consists of integers
divided by *2*, the product of these matrices will consist of integers divided by *2<sup>N</sup>* (see also
theorem 9.2 in the paper). These divisions are expensive when updating *d* and *e*, so we delay
them: we compute the integer coefficients of the combined transition matrix scaled by *2<sup>N</sup>*, and
do one division by *2<sup>N</sup>* as a final step:
```python
def divsteps_n_matrix(delta, f, g):
"""Compute delta and transition matrix t after N divsteps (multiplied by 2^N)."""
u, v, q, r = 1, 0, 0, 1 # start with identity matrix
for _ in range(N):
if delta > 0 and g & 1:
delta, f, g, u, v, q, r = 1 - delta, g, (g - f) // 2, 2*q, 2*r, q-u, r-v
elif g & 1:
delta, f, g, u, v, q, r = 1 + delta, f, (g + f) // 2, 2*u, 2*v, q+u, r+v
else:
delta, f, g, u, v, q, r = 1 + delta, f, (g ) // 2, 2*u, 2*v, q , r
return delta, (u, v, q, r)
```
As the branches in the divsteps are completely determined by the bottom *N* bits of *f* and *g*, this
function to compute the transition matrix only needs to see those bottom bits. Furthermore all
intermediate results and outputs fit in *(N+1)*-bit numbers (unsigned for *f* and *g*; signed for *u*, *v*,
*q*, and *r*) (see also paragraph 8.3 in the paper). This means that an implementation using 64-bit
integers could set *N=62* and compute the full transition matrix for 62 steps at once without any
big integer arithmetic at all. This is the reason why this algorithm is efficient: it only needs
to update the full-size *f*, *g*, *d*, and *e* numbers once every *N* steps.
We still need functions to compute:
```
[ out_f ] = (1/2^N * [ u, v ]) * [ in_f ]
[ out_g ] ( [ q, r ]) [ in_g ]
[ out_d ] = (1/2^N * [ u, v ]) * [ in_d ] (mod M)
[ out_e ] ( [ q, r ]) [ in_e ]
```
Because the divsteps transformation only ever divides even numbers by two, the result of *t&thinsp;[f,g]* is always even. When *t* is a composition of *N* divsteps, it follows that the resulting *f*
and *g* will be multiple of *2<sup>N</sup>*, and division by *2<sup>N</sup>* is simply shifting them down:
```python
def update_fg(f, g, t):
"""Multiply matrix t/2^N with [f, g]."""
u, v, q, r = t
cf, cg = u*f + v*g, q*f + r*g
# (t / 2^N) should cleanly apply to [f,g] so the result of t*[f,g] should have N zero
# bottom bits.
assert cf % 2**N == 0
assert cg % 2**N == 0
return cf >> N, cg >> N
```
The same is not true for *d* and *e*, and we need an equivalent of the `div2` function for division by *2<sup>N</sup> mod M*.
This is easy if we have precomputed *1/M mod 2<sup>N</sup>* (which always exists for odd *M*):
```python
def div2n(M, Mi, x):
"""Compute x/2^N mod M, given Mi = 1/M mod 2^N."""
assert (M * Mi) % 2**N == 1
# Find a factor m such that m*M has the same bottom N bits as x. We want:
# (m * M) mod 2^N = x mod 2^N
# <=> m mod 2^N = (x / M) mod 2^N
# <=> m mod 2^N = (x * Mi) mod 2^N
m = (Mi * x) % 2**N
# Subtract that multiple from x, cancelling its bottom N bits.
x -= m * M
# Now a clean division by 2^N is possible.
assert x % 2**N == 0
return (x >> N) % M
def update_de(d, e, t, M, Mi):
"""Multiply matrix t/2^N with [d, e], modulo M."""
u, v, q, r = t
cd, ce = u*d + v*e, q*d + r*e
return div2n(M, Mi, cd), div2n(M, Mi, ce)
```
With all of those, we can write a version of `modinv` that performs *N* divsteps at once:
```python3
def modinv(M, Mi, x):
"""Compute the modular inverse of x mod M, given Mi=1/M mod 2^N."""
assert M & 1
delta, f, g, d, e = 1, M, x, 0, 1
while g != 0:
# Compute the delta and transition matrix t for the next N divsteps (this only needs
# (N+1)-bit signed integer arithmetic).
delta, t = divsteps_n_matrix(delta, f % 2**N, g % 2**N)
# Apply the transition matrix t to [f, g]:
f, g = update_fg(f, g, t)
# Apply the transition matrix t to [d, e]:
d, e = update_de(d, e, t, M, Mi)
return (d * f) % M
```
This means that in practice we'll always perform a multiple of *N* divsteps. This is not a problem
because once *g=0*, further divsteps do not affect *f*, *g*, *d*, or *e* anymore (only *&delta;* keeps
increasing). For variable time code such excess iterations will be mostly optimized away in later
sections.
## 4. Avoiding modulus operations
So far, there are two places where we compute a remainder of big numbers modulo *M*: at the end of
`div2n` in every `update_de`, and at the very end of `modinv` after potentially negating *d* due to the
sign of *f*. These are relatively expensive operations when done generically.
To deal with the modulus operation in `div2n`, we simply stop requiring *d* and *e* to be in range
*[0,M)* all the time. Let's start by inlining `div2n` into `update_de`, and dropping the modulus
operation at the end:
```python
def update_de(d, e, t, M, Mi):
"""Multiply matrix t/2^N with [d, e] mod M, given Mi=1/M mod 2^N."""
u, v, q, r = t
cd, ce = u*d + v*e, q*d + r*e
# Cancel out bottom N bits of cd and ce.
md = -((Mi * cd) % 2**N)
me = -((Mi * ce) % 2**N)
cd += md * M
ce += me * M
# And cleanly divide by 2**N.
return cd >> N, ce >> N
```
Let's look at bounds on the ranges of these numbers. It can be shown that *|u|+|v|* and *|q|+|r|*
never exceed *2<sup>N</sup>* (see paragraph 8.3 in the paper), and thus a multiplication with *t* will have
outputs whose absolute values are at most *2<sup>N</sup>* times the maximum absolute input value. In case the
inputs *d* and *e* are in *(-M,M)*, which is certainly true for the initial values *d=0* and *e=1* assuming
*M > 1*, the multiplication results in numbers in range *(-2<sup>N</sup>M,2<sup>N</sup>M)*. Subtracting less than *2<sup>N</sup>*
times *M* to cancel out *N* bits brings that up to *(-2<sup>N+1</sup>M,2<sup>N</sup>M)*, and
dividing by *2<sup>N</sup>* at the end takes it to *(-2M,M)*. Another application of `update_de` would take that
to *(-3M,2M)*, and so forth. This progressive expansion of the variables' ranges can be
counteracted by incrementing *d* and *e* by *M* whenever they're negative:
```python
...
if d < 0:
d += M
if e < 0:
e += M
cd, ce = u*d + v*e, q*d + r*e
# Cancel out bottom N bits of cd and ce.
...
```
With inputs in *(-2M,M)*, they will first be shifted into range *(-M,M)*, which means that the
output will again be in *(-2M,M)*, and this remains the case regardless of how many `update_de`
invocations there are. In what follows, we will try to make this more efficient.
Note that increasing *d* by *M* is equal to incrementing *cd* by *u&thinsp;M* and *ce* by *q&thinsp;M*. Similarly,
increasing *e* by *M* is equal to incrementing *cd* by *v&thinsp;M* and *ce* by *r&thinsp;M*. So we could instead write:
```python
...
cd, ce = u*d + v*e, q*d + r*e
# Perform the equivalent of incrementing d, e by M when they're negative.
if d < 0:
cd += u*M
ce += q*M
if e < 0:
cd += v*M
ce += r*M
# Cancel out bottom N bits of cd and ce.
md = -((Mi * cd) % 2**N)
me = -((Mi * ce) % 2**N)
cd += md * M
ce += me * M
...
```
Now note that we have two steps of corrections to *cd* and *ce* that add multiples of *M*: this
increment, and the decrement that cancels out bottom bits. The second one depends on the first
one, but they can still be efficiently combined by only computing the bottom bits of *cd* and *ce*
at first, and using that to compute the final *md*, *me* values:
```python
def update_de(d, e, t, M, Mi):
"""Multiply matrix t/2^N with [d, e], modulo M."""
u, v, q, r = t
md, me = 0, 0
# Compute what multiples of M to add to cd and ce.
if d < 0:
md += u
me += q
if e < 0:
md += v
me += r
# Compute bottom N bits of t*[d,e] + M*[md,me].
cd, ce = (u*d + v*e + md*M) % 2**N, (q*d + r*e + me*M) % 2**N
# Correct md and me such that the bottom N bits of t*[d,e] + M*[md,me] are zero.
md -= (Mi * cd) % 2**N
me -= (Mi * ce) % 2**N
# Do the full computation.
cd, ce = u*d + v*e + md*M, q*d + r*e + me*M
# And cleanly divide by 2**N.
return cd >> N, ce >> N
```
One last optimization: we can avoid the *md&thinsp;M* and *me&thinsp;M* multiplications in the bottom bits of *cd*
and *ce* by moving them to the *md* and *me* correction:
```python
...
# Compute bottom N bits of t*[d,e].
cd, ce = (u*d + v*e) % 2**N, (q*d + r*e) % 2**N
# Correct md and me such that the bottom N bits of t*[d,e]+M*[md,me] are zero.
# Note that this is not the same as {md = (-Mi * cd) % 2**N} etc. That would also result in N
# zero bottom bits, but isn't guaranteed to be a reduction of [0,2^N) compared to the
# previous md and me values, and thus would violate our bounds analysis.
md -= (Mi*cd + md) % 2**N
me -= (Mi*ce + me) % 2**N
...
```
The resulting function takes *d* and *e* in range *(-2M,M)* as inputs, and outputs values in the same
range. That also means that the *d* value at the end of `modinv` will be in that range, while we want
a result in *[0,M)*. To do that, we need a normalization function. It's easy to integrate the
conditional negation of *d* (based on the sign of *f*) into it as well:
```python
def normalize(sign, v, M):
"""Compute sign*v mod M, where v is in range (-2*M,M); output in [0,M)."""
assert sign == 1 or sign == -1
# v in (-2*M,M)
if v < 0:
v += M
# v in (-M,M). Now multiply v with sign (which can only be 1 or -1).
if sign == -1:
v = -v
# v in (-M,M)
if v < 0:
v += M
# v in [0,M)
return v
```
And calling it in `modinv` is simply:
```python
...
return normalize(f, d, M)
```
## 5. Constant-time operation
The primary selling point of the algorithm is fast constant-time operation. What code flow still
depends on the input data so far?
- the number of iterations of the while *g &ne; 0* loop in `modinv`
- the branches inside `divsteps_n_matrix`
- the sign checks in `update_de`
- the sign checks in `normalize`
To make the while loop in `modinv` constant time it can be replaced with a constant number of
iterations. The paper proves (Theorem 11.2) that *741* divsteps are sufficient for any *256*-bit
inputs, and [safegcd-bounds](https://github.com/sipa/safegcd-bounds) shows that the slightly better bound *724* is
sufficient even. Given that every loop iteration performs *N* divsteps, it will run a total of
*&lceil;724/N&rceil;* times.
To deal with the branches in `divsteps_n_matrix` we will replace them with constant-time bitwise
operations (and hope the C compiler isn't smart enough to turn them back into branches; see
`ctime_tests.c` for automated tests that this isn't the case). To do so, observe that a
divstep can be written instead as (compare to the inner loop of `gcd` in section 1).
```python
x = -f if delta > 0 else f # set x equal to (input) -f or f
if g & 1:
g += x # set g to (input) g-f or g+f
if delta > 0:
delta = -delta
f += g # set f to (input) g (note that g was set to g-f before)
delta += 1
g >>= 1
```
To convert the above to bitwise operations, we rely on a trick to negate conditionally: per the
definition of negative numbers in two's complement, (*-v == ~v + 1*) holds for every number *v*. As
*-1* in two's complement is all *1* bits, bitflipping can be expressed as xor with *-1*. It follows
that *-v == (v ^ -1) - (-1)*. Thus, if we have a variable *c* that takes on values *0* or *-1*, then
*(v ^ c) - c* is *v* if *c=0* and *-v* if *c=-1*.
Using this we can write:
```python
x = -f if delta > 0 else f
```
in constant-time form as:
```python
c1 = (-delta) >> 63
# Conditionally negate f based on c1:
x = (f ^ c1) - c1
```
To use that trick, we need a helper mask variable *c1* that resolves the condition *&delta;>0* to *-1*
(if true) or *0* (if false). We compute *c1* using right shifting, which is equivalent to dividing by
the specified power of *2* and rounding down (in Python, and also in C under the assumption of a typical two's complement system; see
`assumptions.h` for tests that this is the case). Right shifting by *63* thus maps all
numbers in range *[-2<sup>63</sup>,0)* to *-1*, and numbers in range *[0,2<sup>63</sup>)* to *0*.
Using the facts that *x&0=0* and *x&(-1)=x* (on two's complement systems again), we can write:
```python
if g & 1:
g += x
```
as:
```python
# Compute c2=0 if g is even and c2=-1 if g is odd.
c2 = -(g & 1)
# This masks out x if g is even, and leaves x be if g is odd.
g += x & c2
```
Using the conditional negation trick again we can write:
```python
if g & 1:
if delta > 0:
delta = -delta
```
as:
```python
# Compute c3=-1 if g is odd and delta>0, and 0 otherwise.
c3 = c1 & c2
# Conditionally negate delta based on c3:
delta = (delta ^ c3) - c3
```
Finally:
```python
if g & 1:
if delta > 0:
f += g
```
becomes:
```python
f += g & c3
```
It turns out that this can be implemented more efficiently by applying the substitution
*&eta;=-&delta;*. In this representation, negating *&delta;* corresponds to negating *&eta;*, and incrementing
*&delta;* corresponds to decrementing *&eta;*. This allows us to remove the negation in the *c1*
computation:
```python
# Compute a mask c1 for eta < 0, and compute the conditional negation x of f:
c1 = eta >> 63
x = (f ^ c1) - c1
# Compute a mask c2 for odd g, and conditionally add x to g:
c2 = -(g & 1)
g += x & c2
# Compute a mask c for (eta < 0) and odd (input) g, and use it to conditionally negate eta,
# and add g to f:
c3 = c1 & c2
eta = (eta ^ c3) - c3
f += g & c3
# Incrementing delta corresponds to decrementing eta.
eta -= 1
g >>= 1
```
A variant of divsteps with better worst-case performance can be used instead: starting *&delta;* at
*1/2* instead of *1*. This reduces the worst case number of iterations to *590* for *256*-bit inputs
(which can be shown using convex hull analysis). In this case, the substitution *&zeta;=-(&delta;+1/2)*
is used instead to keep the variable integral. Incrementing *&delta;* by *1* still translates to
decrementing *&zeta;* by *1*, but negating *&delta;* now corresponds to going from *&zeta;* to *-(&zeta;+1)*, or
*~&zeta;*. Doing that conditionally based on *c3* is simply:
```python
...
c3 = c1 & c2
zeta ^= c3
...
```
By replacing the loop in `divsteps_n_matrix` with a variant of the divstep code above (extended to
also apply all *f* operations to *u*, *v* and all *g* operations to *q*, *r*), a constant-time version of
`divsteps_n_matrix` is obtained. The full code will be in section 7.
These bit fiddling tricks can also be used to make the conditional negations and additions in
`update_de` and `normalize` constant-time.
## 6. Variable-time optimizations
In section 5, we modified the `divsteps_n_matrix` function (and a few others) to be constant time.
Constant time operations are only necessary when computing modular inverses of secret data. In
other cases, it slows down calculations unnecessarily. In this section, we will construct a
faster non-constant time `divsteps_n_matrix` function.
To do so, first consider yet another way of writing the inner loop of divstep operations in
`gcd` from section 1. This decomposition is also explained in the paper in section 8.2. We use
the original version with initial *&delta;=1* and *&eta;=-&delta;* here.
```python
for _ in range(N):
if g & 1 and eta < 0:
eta, f, g = -eta, g, -f
if g & 1:
g += f
eta -= 1
g >>= 1
```
Whenever *g* is even, the loop only shifts *g* down and decreases *&eta;*. When *g* ends in multiple zero
bits, these iterations can be consolidated into one step. This requires counting the bottom zero
bits efficiently, which is possible on most platforms; it is abstracted here as the function
`count_trailing_zeros`.
```python
def count_trailing_zeros(v):
"""
When v is zero, consider all N zero bits as "trailing".
For a non-zero value v, find z such that v=(d<<z) for some odd d.
"""
if v == 0:
return N
else:
return (v & -v).bit_length() - 1
i = N # divsteps left to do
while True:
# Get rid of all bottom zeros at once. In the first iteration, g may be odd and the following
# lines have no effect (until "if eta < 0").
zeros = min(i, count_trailing_zeros(g))
eta -= zeros
g >>= zeros
i -= zeros
if i == 0:
break
# We know g is odd now
if eta < 0:
eta, f, g = -eta, g, -f
g += f
# g is even now, and the eta decrement and g shift will happen in the next loop.
```
We can now remove multiple bottom *0* bits from *g* at once, but still need a full iteration whenever
there is a bottom *1* bit. In what follows, we will get rid of multiple *1* bits simultaneously as
well.
Observe that as long as *&eta; &geq; 0*, the loop does not modify *f*. Instead, it cancels out bottom
bits of *g* and shifts them out, and decreases *&eta;* and *i* accordingly - interrupting only when *&eta;*
becomes negative, or when *i* reaches *0*. Combined, this is equivalent to adding a multiple of *f* to
*g* to cancel out multiple bottom bits, and then shifting them out.
It is easy to find what that multiple is: we want a number *w* such that *g+w&thinsp;f* has a few bottom
zero bits. If that number of bits is *L*, we want *g+w&thinsp;f mod 2<sup>L</sup> = 0*, or *w = -g/f mod 2<sup>L</sup>*. Since *f*
is odd, such a *w* exists for any *L*. *L* cannot be more than *i* steps (as we'd finish the loop before
doing more) or more than *&eta;+1* steps (as we'd run `eta, f, g = -eta, g, -f` at that point), but
apart from that, we're only limited by the complexity of computing *w*.
This code demonstrates how to cancel up to 4 bits per step:
```python
NEGINV16 = [15, 5, 3, 9, 7, 13, 11, 1] # NEGINV16[n//2] = (-n)^-1 mod 16, for odd n
i = N
while True:
zeros = min(i, count_trailing_zeros(g))
eta -= zeros
g >>= zeros
i -= zeros
if i == 0:
break
# We know g is odd now
if eta < 0:
eta, f, g = -eta, g, -f
# Compute limit on number of bits to cancel
limit = min(min(eta + 1, i), 4)
# Compute w = -g/f mod 2**limit, using the table value for -1/f mod 2**4. Note that f is
# always odd, so its inverse modulo a power of two always exists.
w = (g * NEGINV16[(f & 15) // 2]) % (2**limit)
# As w = -g/f mod (2**limit), g+w*f mod 2**limit = 0 mod 2**limit.
g += w * f
assert g % (2**limit) == 0
# The next iteration will now shift out at least limit bottom zero bits from g.
```
By using a bigger table more bits can be cancelled at once. The table can also be implemented
as a formula. Several formulas are known for computing modular inverses modulo powers of two;
some can be found in Hacker's Delight second edition by Henry S. Warren, Jr. pages 245-247.
Here we need the negated modular inverse, which is a simple transformation of those:
- Instead of a 3-bit table:
- *-f* or *f ^ 6*
- Instead of a 4-bit table:
- *1 - f(f + 1)*
- *-(f + (((f + 1) & 4) << 1))*
- For larger tables the following technique can be used: if *w=-1/f mod 2<sup>L</sup>*, then *w(w&thinsp;f+2)* is
*-1/f mod 2<sup>2L</sup>*. This allows extending the previous formulas (or tables). In particular we
have this 6-bit function (based on the 3-bit function above):
- *f(f<sup>2</sup> - 2)*
This loop, again extended to also handle *u*, *v*, *q*, and *r* alongside *f* and *g*, placed in
`divsteps_n_matrix`, gives a significantly faster, but non-constant time version.
## 7. Final Python version
All together we need the following functions:
- A way to compute the transition matrix in constant time, using the `divsteps_n_matrix` function
from section 2, but with its loop replaced by a variant of the constant-time divstep from
section 5, extended to handle *u*, *v*, *q*, *r*:
```python
def divsteps_n_matrix(zeta, f, g):
"""Compute zeta and transition matrix t after N divsteps (multiplied by 2^N)."""
u, v, q, r = 1, 0, 0, 1 # start with identity matrix
for _ in range(N):
c1 = zeta >> 63
# Compute x, y, z as conditionally-negated versions of f, u, v.
x, y, z = (f ^ c1) - c1, (u ^ c1) - c1, (v ^ c1) - c1
c2 = -(g & 1)
# Conditionally add x, y, z to g, q, r.
g, q, r = g + (x & c2), q + (y & c2), r + (z & c2)
c1 &= c2 # reusing c1 here for the earlier c3 variable
zeta = (zeta ^ c1) - 1 # inlining the unconditional zeta decrement here
# Conditionally add g, q, r to f, u, v.
f, u, v = f + (g & c1), u + (q & c1), v + (r & c1)
# When shifting g down, don't shift q, r, as we construct a transition matrix multiplied
# by 2^N. Instead, shift f's coefficients u and v up.
g, u, v = g >> 1, u << 1, v << 1
return zeta, (u, v, q, r)
```
- The functions to update *f* and *g*, and *d* and *e*, from section 2 and section 4, with the constant-time
changes to `update_de` from section 5:
```python
def update_fg(f, g, t):
"""Multiply matrix t/2^N with [f, g]."""
u, v, q, r = t
cf, cg = u*f + v*g, q*f + r*g
return cf >> N, cg >> N
def update_de(d, e, t, M, Mi):
"""Multiply matrix t/2^N with [d, e], modulo M."""
u, v, q, r = t
d_sign, e_sign = d >> 257, e >> 257
md, me = (u & d_sign) + (v & e_sign), (q & d_sign) + (r & e_sign)
cd, ce = (u*d + v*e) % 2**N, (q*d + r*e) % 2**N
md -= (Mi*cd + md) % 2**N
me -= (Mi*ce + me) % 2**N
cd, ce = u*d + v*e + M*md, q*d + r*e + M*me
return cd >> N, ce >> N
```
- The `normalize` function from section 4, made constant time as well:
```python
def normalize(sign, v, M):
"""Compute sign*v mod M, where v in (-2*M,M); output in [0,M)."""
v_sign = v >> 257
# Conditionally add M to v.
v += M & v_sign
c = (sign - 1) >> 1
# Conditionally negate v.
v = (v ^ c) - c
v_sign = v >> 257
# Conditionally add M to v again.
v += M & v_sign
return v
```
- And finally the `modinv` function too, adapted to use *&zeta;* instead of *&delta;*, and using the fixed
iteration count from section 5:
```python
def modinv(M, Mi, x):
"""Compute the modular inverse of x mod M, given Mi=1/M mod 2^N."""
zeta, f, g, d, e = -1, M, x, 0, 1
for _ in range((590 + N - 1) // N):
zeta, t = divsteps_n_matrix(zeta, f % 2**N, g % 2**N)
f, g = update_fg(f, g, t)
d, e = update_de(d, e, t, M, Mi)
return normalize(f, d, M)
```
- To get a variable time version, replace the `divsteps_n_matrix` function with one that uses the
divsteps loop from section 5, and a `modinv` version that calls it without the fixed iteration
count:
```python
NEGINV16 = [15, 5, 3, 9, 7, 13, 11, 1] # NEGINV16[n//2] = (-n)^-1 mod 16, for odd n
def divsteps_n_matrix_var(eta, f, g):
"""Compute eta and transition matrix t after N divsteps (multiplied by 2^N)."""
u, v, q, r = 1, 0, 0, 1
i = N
while True:
zeros = min(i, count_trailing_zeros(g))
eta, i = eta - zeros, i - zeros
g, u, v = g >> zeros, u << zeros, v << zeros
if i == 0:
break
if eta < 0:
eta, f, u, v, g, q, r = -eta, g, q, r, -f, -u, -v
limit = min(min(eta + 1, i), 4)
w = (g * NEGINV16[(f & 15) // 2]) % (2**limit)
g, q, r = g + w*f, q + w*u, r + w*v
return eta, (u, v, q, r)
def modinv_var(M, Mi, x):
"""Compute the modular inverse of x mod M, given Mi = 1/M mod 2^N."""
eta, f, g, d, e = -1, M, x, 0, 1
while g != 0:
eta, t = divsteps_n_matrix_var(eta, f % 2**N, g % 2**N)
f, g = update_fg(f, g, t)
d, e = update_de(d, e, t, M, Mi)
return normalize(f, d, Mi)
```
## 8. From GCDs to Jacobi symbol
We can also use a similar approach to calculate Jacobi symbol *(x | M)* by keeping track of an
extra variable *j*, for which at every step *(x | M) = j (g | f)*. As we update *f* and *g*, we
make corresponding updates to *j* using
[properties of the Jacobi symbol](https://en.wikipedia.org/wiki/Jacobi_symbol#Properties):
* *((g/2) | f)* is either *(g | f)* or *-(g | f)*, depending on the value of *f mod 8* (negating if it's *3* or *5*).
* *(f | g)* is either *(g | f)* or *-(g | f)*, depending on *f mod 4* and *g mod 4* (negating if both are *3*).
These updates depend only on the values of *f* and *g* modulo *4* or *8*, and can thus be applied
very quickly, as long as we keep track of a few additional bits of *f* and *g*. Overall, this
calculation is slightly simpler than the one for the modular inverse because we no longer need to
keep track of *d* and *e*.
However, one difficulty of this approach is that the Jacobi symbol *(a | n)* is only defined for
positive odd integers *n*, whereas in the original safegcd algorithm, *f, g* can take negative
values. We resolve this by using the following modified steps:
```python
# Before
if delta > 0 and g & 1:
delta, f, g = 1 - delta, g, (g - f) // 2
# After
if delta > 0 and g & 1:
delta, f, g = 1 - delta, g, (g + f) // 2
```
The algorithm is still correct, since the changed divstep, called a "posdivstep" (see section 8.4
and E.5 in the paper) preserves *gcd(f, g)*. However, there's no proof that the modified algorithm
will converge. The justification for posdivsteps is completely empirical: in practice, it appears
that the vast majority of nonzero inputs converge to *f=g=gcd(f<sub>0</sub>, g<sub>0</sub>)* in a
number of steps proportional to their logarithm.
Note that:
- We require inputs to satisfy *gcd(x, M) = 1*, as otherwise *f=1* is not reached.
- We require inputs *x &neq; 0*, because applying posdivstep with *g=0* has no effect.
- We need to update the termination condition from *g=0* to *f=1*.
We account for the possibility of nonconvergence by only performing a bounded number of
posdivsteps, and then falling back to square-root based Jacobi calculation if a solution has not
yet been found.
The optimizations in sections 3-7 above are described in the context of the original divsteps, but
in the C implementation we also adapt most of them (not including "avoiding modulus operations",
since it's not necessary to track *d, e*, and "constant-time operation", since we never calculate
Jacobi symbols for secret data) to the posdivsteps version.

30
examples/CMakeLists.txt Normal file
View File

@@ -0,0 +1,30 @@
function(add_example name)
set(target_name ${name}_example)
add_executable(${target_name} ${name}.c)
target_include_directories(${target_name} PRIVATE
${PROJECT_SOURCE_DIR}/include
)
target_link_libraries(${target_name}
secp256k1
$<$<PLATFORM_ID:Windows>:bcrypt>
)
set(test_name ${name}_example)
add_test(NAME ${test_name} COMMAND ${target_name})
if(BUILD_SHARED_LIBS AND MSVC)
# The DLL must reside either in the same folder where the executable is
# or somewhere in PATH. Using the latter option.
set_tests_properties(${test_name} PROPERTIES
ENVIRONMENT "PATH=$<TARGET_FILE_DIR:secp256k1>;$ENV{PATH}"
)
endif()
endfunction()
add_example(ecdsa)
if(SECP256K1_ENABLE_MODULE_ECDH)
add_example(ecdh)
endif()
if(SECP256K1_ENABLE_MODULE_SCHNORRSIG)
add_example(schnorr)
endif()

121
examples/EXAMPLES_COPYING Normal file
View File

@@ -0,0 +1,121 @@
Creative Commons Legal Code
CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.

122
examples/ecdh.c Normal file
View File

@@ -0,0 +1,122 @@
/*************************************************************************
* Written in 2020-2022 by Elichai Turkel *
* To the extent possible under law, the author(s) have dedicated all *
* copyright and related and neighboring rights to the software in this *
* file to the public domain worldwide. This software is distributed *
* without any warranty. For the CC0 Public Domain Dedication, see *
* EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 *
*************************************************************************/
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <secp256k1.h>
#include <secp256k1_ecdh.h>
#include "examples_util.h"
int main(void) {
unsigned char seckey1[32];
unsigned char seckey2[32];
unsigned char compressed_pubkey1[33];
unsigned char compressed_pubkey2[33];
unsigned char shared_secret1[32];
unsigned char shared_secret2[32];
unsigned char randomize[32];
int return_val;
size_t len;
secp256k1_pubkey pubkey1;
secp256k1_pubkey pubkey2;
/* Before we can call actual API functions, we need to create a "context". */
secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
if (!fill_random(randomize, sizeof(randomize))) {
printf("Failed to generate randomness\n");
return 1;
}
/* Randomizing the context is recommended to protect against side-channel
* leakage See `secp256k1_context_randomize` in secp256k1.h for more
* information about it. This should never fail. */
return_val = secp256k1_context_randomize(ctx, randomize);
assert(return_val);
/*** Key Generation ***/
/* If the secret key is zero or out of range (bigger than secp256k1's
* order), we try to sample a new key. Note that the probability of this
* happening is negligible. */
while (1) {
if (!fill_random(seckey1, sizeof(seckey1)) || !fill_random(seckey2, sizeof(seckey2))) {
printf("Failed to generate randomness\n");
return 1;
}
if (secp256k1_ec_seckey_verify(ctx, seckey1) && secp256k1_ec_seckey_verify(ctx, seckey2)) {
break;
}
}
/* Public key creation using a valid context with a verified secret key should never fail */
return_val = secp256k1_ec_pubkey_create(ctx, &pubkey1, seckey1);
assert(return_val);
return_val = secp256k1_ec_pubkey_create(ctx, &pubkey2, seckey2);
assert(return_val);
/* Serialize pubkey1 in a compressed form (33 bytes), should always return 1 */
len = sizeof(compressed_pubkey1);
return_val = secp256k1_ec_pubkey_serialize(ctx, compressed_pubkey1, &len, &pubkey1, SECP256K1_EC_COMPRESSED);
assert(return_val);
/* Should be the same size as the size of the output, because we passed a 33 byte array. */
assert(len == sizeof(compressed_pubkey1));
/* Serialize pubkey2 in a compressed form (33 bytes) */
len = sizeof(compressed_pubkey2);
return_val = secp256k1_ec_pubkey_serialize(ctx, compressed_pubkey2, &len, &pubkey2, SECP256K1_EC_COMPRESSED);
assert(return_val);
/* Should be the same size as the size of the output, because we passed a 33 byte array. */
assert(len == sizeof(compressed_pubkey2));
/*** Creating the shared secret ***/
/* Perform ECDH with seckey1 and pubkey2. Should never fail with a verified
* seckey and valid pubkey */
return_val = secp256k1_ecdh(ctx, shared_secret1, &pubkey2, seckey1, NULL, NULL);
assert(return_val);
/* Perform ECDH with seckey2 and pubkey1. Should never fail with a verified
* seckey and valid pubkey */
return_val = secp256k1_ecdh(ctx, shared_secret2, &pubkey1, seckey2, NULL, NULL);
assert(return_val);
/* Both parties should end up with the same shared secret */
return_val = memcmp(shared_secret1, shared_secret2, sizeof(shared_secret1));
assert(return_val == 0);
printf("Secret Key1: ");
print_hex(seckey1, sizeof(seckey1));
printf("Compressed Pubkey1: ");
print_hex(compressed_pubkey1, sizeof(compressed_pubkey1));
printf("\nSecret Key2: ");
print_hex(seckey2, sizeof(seckey2));
printf("Compressed Pubkey2: ");
print_hex(compressed_pubkey2, sizeof(compressed_pubkey2));
printf("\nShared Secret: ");
print_hex(shared_secret1, sizeof(shared_secret1));
/* This will clear everything from the context and free the memory */
secp256k1_context_destroy(ctx);
/* It's best practice to try to clear secrets from memory after using them.
* This is done because some bugs can allow an attacker to leak memory, for
* example through "out of bounds" array access (see Heartbleed), Or the OS
* swapping them to disk. Hence, we overwrite the secret key buffer with zeros.
*
* Here we are preventing these writes from being optimized out, as any good compiler
* will remove any writes that aren't used. */
secure_erase(seckey1, sizeof(seckey1));
secure_erase(seckey2, sizeof(seckey2));
secure_erase(shared_secret1, sizeof(shared_secret1));
secure_erase(shared_secret2, sizeof(shared_secret2));
return 0;
}

139
examples/ecdsa.c Normal file
View File

@@ -0,0 +1,139 @@
/*************************************************************************
* Written in 2020-2022 by Elichai Turkel *
* To the extent possible under law, the author(s) have dedicated all *
* copyright and related and neighboring rights to the software in this *
* file to the public domain worldwide. This software is distributed *
* without any warranty. For the CC0 Public Domain Dedication, see *
* EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 *
*************************************************************************/
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <secp256k1.h>
#include "examples_util.h"
int main(void) {
/* Instead of signing the message directly, we must sign a 32-byte hash.
* Here the message is "Hello, world!" and the hash function was SHA-256.
* An actual implementation should just call SHA-256, but this example
* hardcodes the output to avoid depending on an additional library.
* See https://bitcoin.stackexchange.com/questions/81115/if-someone-wanted-to-pretend-to-be-satoshi-by-posting-a-fake-signature-to-defrau/81116#81116 */
unsigned char msg_hash[32] = {
0x31, 0x5F, 0x5B, 0xDB, 0x76, 0xD0, 0x78, 0xC4,
0x3B, 0x8A, 0xC0, 0x06, 0x4E, 0x4A, 0x01, 0x64,
0x61, 0x2B, 0x1F, 0xCE, 0x77, 0xC8, 0x69, 0x34,
0x5B, 0xFC, 0x94, 0xC7, 0x58, 0x94, 0xED, 0xD3,
};
unsigned char seckey[32];
unsigned char randomize[32];
unsigned char compressed_pubkey[33];
unsigned char serialized_signature[64];
size_t len;
int is_signature_valid, is_signature_valid2;
int return_val;
secp256k1_pubkey pubkey;
secp256k1_ecdsa_signature sig;
/* Before we can call actual API functions, we need to create a "context". */
secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
if (!fill_random(randomize, sizeof(randomize))) {
printf("Failed to generate randomness\n");
return 1;
}
/* Randomizing the context is recommended to protect against side-channel
* leakage See `secp256k1_context_randomize` in secp256k1.h for more
* information about it. This should never fail. */
return_val = secp256k1_context_randomize(ctx, randomize);
assert(return_val);
/*** Key Generation ***/
/* If the secret key is zero or out of range (bigger than secp256k1's
* order), we try to sample a new key. Note that the probability of this
* happening is negligible. */
while (1) {
if (!fill_random(seckey, sizeof(seckey))) {
printf("Failed to generate randomness\n");
return 1;
}
if (secp256k1_ec_seckey_verify(ctx, seckey)) {
break;
}
}
/* Public key creation using a valid context with a verified secret key should never fail */
return_val = secp256k1_ec_pubkey_create(ctx, &pubkey, seckey);
assert(return_val);
/* Serialize the pubkey in a compressed form(33 bytes). Should always return 1. */
len = sizeof(compressed_pubkey);
return_val = secp256k1_ec_pubkey_serialize(ctx, compressed_pubkey, &len, &pubkey, SECP256K1_EC_COMPRESSED);
assert(return_val);
/* Should be the same size as the size of the output, because we passed a 33 byte array. */
assert(len == sizeof(compressed_pubkey));
/*** Signing ***/
/* Generate an ECDSA signature `noncefp` and `ndata` allows you to pass a
* custom nonce function, passing `NULL` will use the RFC-6979 safe default.
* Signing with a valid context, verified secret key
* and the default nonce function should never fail. */
return_val = secp256k1_ecdsa_sign(ctx, &sig, msg_hash, seckey, NULL, NULL);
assert(return_val);
/* Serialize the signature in a compact form. Should always return 1
* according to the documentation in secp256k1.h. */
return_val = secp256k1_ecdsa_signature_serialize_compact(ctx, serialized_signature, &sig);
assert(return_val);
/*** Verification ***/
/* Deserialize the signature. This will return 0 if the signature can't be parsed correctly. */
if (!secp256k1_ecdsa_signature_parse_compact(ctx, &sig, serialized_signature)) {
printf("Failed parsing the signature\n");
return 1;
}
/* Deserialize the public key. This will return 0 if the public key can't be parsed correctly. */
if (!secp256k1_ec_pubkey_parse(ctx, &pubkey, compressed_pubkey, sizeof(compressed_pubkey))) {
printf("Failed parsing the public key\n");
return 1;
}
/* Verify a signature. This will return 1 if it's valid and 0 if it's not. */
is_signature_valid = secp256k1_ecdsa_verify(ctx, &sig, msg_hash, &pubkey);
printf("Is the signature valid? %s\n", is_signature_valid ? "true" : "false");
printf("Secret Key: ");
print_hex(seckey, sizeof(seckey));
printf("Public Key: ");
print_hex(compressed_pubkey, sizeof(compressed_pubkey));
printf("Signature: ");
print_hex(serialized_signature, sizeof(serialized_signature));
/* This will clear everything from the context and free the memory */
secp256k1_context_destroy(ctx);
/* Bonus example: if all we need is signature verification (and no key
generation or signing), we don't need to use a context created via
secp256k1_context_create(). We can simply use the static (i.e., global)
context secp256k1_context_static. See its description in
include/secp256k1.h for details. */
is_signature_valid2 = secp256k1_ecdsa_verify(secp256k1_context_static,
&sig, msg_hash, &pubkey);
assert(is_signature_valid2 == is_signature_valid);
/* It's best practice to try to clear secrets from memory after using them.
* This is done because some bugs can allow an attacker to leak memory, for
* example through "out of bounds" array access (see Heartbleed), Or the OS
* swapping them to disk. Hence, we overwrite the secret key buffer with zeros.
*
* Here we are preventing these writes from being optimized out, as any good compiler
* will remove any writes that aren't used. */
secure_erase(seckey, sizeof(seckey));
return 0;
}

108
examples/examples_util.h Normal file
View File

@@ -0,0 +1,108 @@
/*************************************************************************
* Copyright (c) 2020-2021 Elichai Turkel *
* Distributed under the CC0 software license, see the accompanying file *
* EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 *
*************************************************************************/
/*
* This file is an attempt at collecting best practice methods for obtaining randomness with different operating systems.
* It may be out-of-date. Consult the documentation of the operating system before considering to use the methods below.
*
* Platform randomness sources:
* Linux -> `getrandom(2)`(`sys/random.h`), if not available `/dev/urandom` should be used. http://man7.org/linux/man-pages/man2/getrandom.2.html, https://linux.die.net/man/4/urandom
* macOS -> `getentropy(2)`(`sys/random.h`), if not available `/dev/urandom` should be used. https://www.unix.com/man-page/mojave/2/getentropy, https://opensource.apple.com/source/xnu/xnu-517.12.7/bsd/man/man4/random.4.auto.html
* FreeBSD -> `getrandom(2)`(`sys/random.h`), if not available `kern.arandom` should be used. https://www.freebsd.org/cgi/man.cgi?query=getrandom, https://www.freebsd.org/cgi/man.cgi?query=random&sektion=4
* OpenBSD -> `getentropy(2)`(`unistd.h`), if not available `/dev/urandom` should be used. https://man.openbsd.org/getentropy, https://man.openbsd.org/urandom
* Windows -> `BCryptGenRandom`(`bcrypt.h`). https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
*/
#if defined(_WIN32)
/*
* The defined WIN32_NO_STATUS macro disables return code definitions in
* windows.h, which avoids "macro redefinition" MSVC warnings in ntstatus.h.
*/
#define WIN32_NO_STATUS
#include <windows.h>
#undef WIN32_NO_STATUS
#include <ntstatus.h>
#include <bcrypt.h>
#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)
#include <sys/random.h>
#elif defined(__OpenBSD__)
#include <unistd.h>
#else
#error "Couldn't identify the OS"
#endif
#include <stddef.h>
#include <limits.h>
#include <stdio.h>
/* Returns 1 on success, and 0 on failure. */
static int fill_random(unsigned char* data, size_t size) {
#if defined(_WIN32)
NTSTATUS res = BCryptGenRandom(NULL, data, size, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
if (res != STATUS_SUCCESS || size > ULONG_MAX) {
return 0;
} else {
return 1;
}
#elif defined(__linux__) || defined(__FreeBSD__)
/* If `getrandom(2)` is not available you should fallback to /dev/urandom */
ssize_t res = getrandom(data, size, 0);
if (res < 0 || (size_t)res != size ) {
return 0;
} else {
return 1;
}
#elif defined(__APPLE__) || defined(__OpenBSD__)
/* If `getentropy(2)` is not available you should fallback to either
* `SecRandomCopyBytes` or /dev/urandom */
int res = getentropy(data, size);
if (res == 0) {
return 1;
} else {
return 0;
}
#endif
return 0;
}
static void print_hex(unsigned char* data, size_t size) {
size_t i;
printf("0x");
for (i = 0; i < size; i++) {
printf("%02x", data[i]);
}
printf("\n");
}
#if defined(_MSC_VER)
// For SecureZeroMemory
#include <Windows.h>
#endif
/* Cleanses memory to prevent leaking sensitive info. Won't be optimized out. */
static void secure_erase(void *ptr, size_t len) {
#if defined(_MSC_VER)
/* SecureZeroMemory is guaranteed not to be optimized out by MSVC. */
SecureZeroMemory(ptr, len);
#elif defined(__GNUC__)
/* We use a memory barrier that scares the compiler away from optimizing out the memset.
*
* Quoting Adam Langley <agl@google.com> in commit ad1907fe73334d6c696c8539646c21b11178f20f
* in BoringSSL (ISC License):
* As best as we can tell, this is sufficient to break any optimisations that
* might try to eliminate "superfluous" memsets.
* This method used in memzero_explicit() the Linux kernel, too. Its advantage is that it is
* pretty efficient, because the compiler can still implement the memset() efficiently,
* just not remove it entirely. See "Dead Store Elimination (Still) Considered Harmful" by
* Yang et al. (USENIX Security 2017) for more background.
*/
memset(ptr, 0, len);
__asm__ __volatile__("" : : "r"(ptr) : "memory");
#else
void *(*volatile const volatile_memset)(void *, int, size_t) = memset;
volatile_memset(ptr, 0, len);
#endif
}

294
examples/frost.c Normal file
View File

@@ -0,0 +1,294 @@
/***********************************************************************
* Copyright (c) 2021-2024 Jesse Posner *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
/**
* This file demonstrates how to use the FROST module to create a threshold
* signature. Additionally, see the documentation in include/secp256k1_frost.h.
*/
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <secp256k1.h>
#include <secp256k1_schnorrsig.h>
#include <secp256k1_frost.h>
#include "examples_util.h"
/* Number of public keys involved in creating the aggregate signature */
#define N_SIGNERS 5
/* Threshold required in creating the aggregate signature */
#define THRESHOLD 3
struct signer_secrets {
secp256k1_keypair keypair;
secp256k1_frost_share agg_share;
secp256k1_frost_secnonce secnonce;
unsigned char seed[32];
};
struct signer {
secp256k1_pubkey pubshare;
secp256k1_frost_pubnonce pubnonce;
secp256k1_frost_session session;
secp256k1_frost_partial_sig partial_sig;
secp256k1_pubkey vss_commitment[THRESHOLD];
unsigned char vss_hash[32];
unsigned char pok[64];
unsigned char id[33];
};
/* Create a key pair and store it in seckey and pubkey */
int create_keypair_and_seed(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, struct signer *signer) {
unsigned char seckey[32];
secp256k1_pubkey pubkey_tmp;
size_t size = 33;
while (1) {
if (!fill_random(seckey, sizeof(seckey))) {
printf("Failed to generate randomness\n");
return 1;
}
if (secp256k1_keypair_create(ctx, &signer_secrets->keypair, seckey)) {
break;
}
}
if (!secp256k1_keypair_pub(ctx, &pubkey_tmp, &signer_secrets->keypair)) {
return 0;
}
if (!secp256k1_ec_pubkey_serialize(ctx, signer->id, &size, &pubkey_tmp, SECP256K1_EC_COMPRESSED)) {
return 0;
}
if (!fill_random(signer_secrets->seed, sizeof(signer_secrets->seed))) {
return 0;
}
return 1;
}
/* Create shares and coefficient commitments */
int create_shares(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, struct signer *signer, secp256k1_xonly_pubkey *pk) {
int i, j;
secp256k1_frost_share shares[N_SIGNERS][N_SIGNERS];
const secp256k1_pubkey *vss_commitments[N_SIGNERS];
const unsigned char *ids[N_SIGNERS];
for (i = 0; i < N_SIGNERS; i++) {
vss_commitments[i] = signer[i].vss_commitment;
ids[i] = signer[i].id;
}
for (i = 0; i < N_SIGNERS; i++) {
/* Generate a polynomial share for the participants */
if (!secp256k1_frost_shares_gen(ctx, shares[i], signer[i].vss_commitment, signer[i].pok, signer_secrets[i].seed, THRESHOLD, N_SIGNERS, ids)) {
return 0;
}
}
/* KeyGen communication round 1: exchange shares and coefficient
* commitments */
for (i = 0; i < N_SIGNERS; i++) {
const secp256k1_frost_share *assigned_shares[N_SIGNERS];
/* Each participant receives a share from each participant (including
* themselves) corresponding to their index. */
for (j = 0; j < N_SIGNERS; j++) {
assigned_shares[j] = &shares[j][i];
}
/* Each participant aggregates the shares they received. */
if (!secp256k1_frost_share_agg(ctx, &signer_secrets[i].agg_share, pk, assigned_shares, vss_commitments, N_SIGNERS, THRESHOLD, signer[i].id)) {
return 0;
}
for (j = 0; j < N_SIGNERS; j++) {
/* Each participant verifies their shares. share_agg calls this
* internally, so it is only neccessary to call this function if
* share_agg returns an error, to determine which participant(s)
* submitted faulty data. */
if (!secp256k1_frost_share_verify(ctx, THRESHOLD, signer[i].id, assigned_shares[j], &vss_commitments[j])) {
return 0;
}
/* Each participant generates public verification shares that are
* used for verifying partial signatures. */
if (!secp256k1_frost_compute_pubshare(ctx, &signer[j].pubshare, THRESHOLD, signer[j].id, vss_commitments, N_SIGNERS)) {
return 0;
}
}
}
return 1;
}
/* Tweak the pubkey corresponding to the provided tweak cache, update the cache
* and return the tweaked aggregate pk. */
int tweak(const secp256k1_context* ctx, secp256k1_xonly_pubkey *pk, secp256k1_frost_tweak_cache *cache) {
secp256k1_pubkey output_pk;
unsigned char ordinary_tweak[32] = "this could be a BIP32 tweak....";
unsigned char xonly_tweak[32] = "this could be a taproot tweak..";
if (!secp256k1_frost_pubkey_tweak(ctx, cache, pk)) {
return 0;
}
/* Ordinary tweaking which, for example, allows deriving multiple child
* public keys from a single aggregate key using BIP32 */
if (!secp256k1_frost_pubkey_ec_tweak_add(ctx, NULL, cache, ordinary_tweak)) {
return 0;
}
/* If one is not interested in signing, the same output_pk can be obtained
* by calling `secp256k1_frost_pubkey_get` right after key aggregation to
* get the full pubkey and then call `secp256k1_ec_pubkey_tweak_add`. */
/* Xonly tweaking which, for example, allows creating taproot commitments */
if (!secp256k1_frost_pubkey_xonly_tweak_add(ctx, &output_pk, cache, xonly_tweak)) {
return 0;
}
/* Note that if we wouldn't care about signing, we can arrive at the same
* output_pk by providing the untweaked public key to
* `secp256k1_xonly_pubkey_tweak_add` (after converting it to an xonly pubkey
* if necessary with `secp256k1_xonly_pubkey_from_pubkey`). */
/* Now we convert the output_pk to an xonly pubkey to allow to later verify
* the Schnorr signature against it. For this purpose we can ignore the
* `pk_parity` output argument; we would need it if we would have to open
* the taproot commitment. */
if (!secp256k1_xonly_pubkey_from_pubkey(ctx, pk, NULL, &output_pk)) {
return 0;
}
return 1;
}
/* Sign a message hash with the given threshold and aggregate shares and store
* the result in sig */
int sign(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, struct signer *signer, const unsigned char* msg32, secp256k1_xonly_pubkey *pk, unsigned char *sig64, const secp256k1_frost_tweak_cache *cache) {
int i;
int signer_id = 0;
int signers[THRESHOLD];
int is_signer[N_SIGNERS];
const secp256k1_frost_pubnonce *pubnonces[THRESHOLD];
const unsigned char *ids[THRESHOLD];
const secp256k1_frost_partial_sig *partial_sigs[THRESHOLD];
for (i = 0; i < N_SIGNERS; i++) {
unsigned char session_id[32];
/* Create random session ID. It is absolutely necessary that the session ID
* is unique for every call of secp256k1_frost_nonce_gen. Otherwise
* it's trivial for an attacker to extract the secret key! */
if (!fill_random(session_id, sizeof(session_id))) {
return 0;
}
/* Initialize session and create secret nonce for signing and public
* nonce to send to the other signers. */
if (!secp256k1_frost_nonce_gen(ctx, &signer_secrets[i].secnonce, &signer[i].pubnonce, session_id, &signer_secrets[i].agg_share, msg32, pk, NULL)) {
return 0;
}
is_signer[i] = 0; /* Initialize is_signer */
}
/* Select a random subset of signers */
for (i = 0; i < THRESHOLD; i++) {
unsigned int subset_seed;
while (1) {
if (!fill_random((unsigned char*)&subset_seed, sizeof(subset_seed))) {
return 0;
}
signer_id = subset_seed % N_SIGNERS;
/* Check if signer has already been assigned */
if (!is_signer[signer_id]) {
is_signer[signer_id] = 1;
signers[i] = signer_id;
break;
}
}
/* Mark signer as assigned */
pubnonces[i] = &signer[signer_id].pubnonce;
/* pubkeys[i] = &signer[signer_id].pubkey; */
ids[i] = signer[signer_id].id;
}
/* Signing communication round 1: Exchange nonces */
for (i = 0; i < THRESHOLD; i++) {
signer_id = signers[i];
if (!secp256k1_frost_nonce_process(ctx, &signer[signer_id].session, pubnonces, THRESHOLD, msg32, pk, signer[signer_id].id, ids, cache, NULL)) {
return 0;
}
/* partial_sign will clear the secnonce by setting it to 0. That's because
* you must _never_ reuse the secnonce (or use the same session_id to
* create a secnonce). If you do, you effectively reuse the nonce and
* leak the secret key. */
if (!secp256k1_frost_partial_sign(ctx, &signer[signer_id].partial_sig, &signer_secrets[signer_id].secnonce, &signer_secrets[signer_id].agg_share, &signer[signer_id].session, cache)) {
return 0;
}
partial_sigs[i] = &signer[signer_id].partial_sig;
}
/* Communication round 2: A production system would exchange
* partial signatures here before moving on. */
for (i = 0; i < THRESHOLD; i++) {
signer_id = signers[i];
/* To check whether signing was successful, it suffices to either verify
* the aggregate signature with the aggregate public key using
* secp256k1_schnorrsig_verify, or verify all partial signatures of all
* signers individually. Verifying the aggregate signature is cheaper but
* verifying the individual partial signatures has the advantage that it
* can be used to determine which of the partial signatures are invalid
* (if any), i.e., which of the partial signatures cause the aggregate
* signature to be invalid and thus the protocol run to fail. It's also
* fine to first verify the aggregate sig, and only verify the individual
* sigs if it does not work.
*/
if (!secp256k1_frost_partial_sig_verify(ctx, &signer[signer_id].partial_sig, &signer[signer_id].pubnonce, &signer[signer_id].pubshare, &signer[signer_id].session, cache)) {
return 0;
}
}
return secp256k1_frost_partial_sig_agg(ctx, sig64, &signer[signer_id].session, partial_sigs, THRESHOLD);
}
int main(void) {
secp256k1_context* ctx;
int i;
struct signer_secrets signer_secrets[N_SIGNERS];
struct signer signers[N_SIGNERS];
secp256k1_xonly_pubkey pk;
secp256k1_frost_tweak_cache cache;
unsigned char msg[32] = "this_could_be_the_hash_of_a_msg!";
unsigned char sig[64];
/* Create a context for signing and verification */
ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
printf("Creating key pairs......");
for (i = 0; i < N_SIGNERS; i++) {
if (!create_keypair_and_seed(ctx, &signer_secrets[i], &signers[i])) {
printf("FAILED\n");
return 1;
}
}
printf("ok\n");
printf("Creating shares.........");
if (!create_shares(ctx, signer_secrets, signers, &pk)) {
printf("FAILED\n");
return 1;
}
printf("ok\n");
printf("Tweaking................");
/* Optionally tweak the aggregate key */
if (!tweak(ctx, &pk, &cache)) {
printf("FAILED\n");
return 1;
}
printf("ok\n");
printf("Signing message.........");
if (!sign(ctx, signer_secrets, signers, msg, &pk, sig, &cache)) {
printf("FAILED\n");
return 1;
}
printf("ok\n");
printf("Verifying signature.....");
if (!secp256k1_schnorrsig_verify(ctx, sig, msg, 32, &pk)) {
printf("FAILED\n");
return 1;
}
printf("ok\n");
secp256k1_context_destroy(ctx);
return 0;
}

214
examples/musig.c Normal file
View File

@@ -0,0 +1,214 @@
/*************************************************************************
* Written in 2018 by Jonas Nick *
* To the extent possible under law, the author(s) have dedicated all *
* copyright and related and neighboring rights to the software in this *
* file to the public domain worldwide. This software is distributed *
* without any warranty. For the CC0 Public Domain Dedication, see *
* EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 *
*************************************************************************/
/** This file demonstrates how to use the MuSig module to create a
* 3-of-3 multisignature. Additionally, see the documentation in
* include/secp256k1_musig.h and src/modules/musig/musig.md.
*/
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <secp256k1.h>
#include <secp256k1_schnorrsig.h>
#include <secp256k1_musig.h>
#include "examples_util.h"
struct signer_secrets {
secp256k1_keypair keypair;
secp256k1_musig_secnonce secnonce;
};
struct signer {
secp256k1_pubkey pubkey;
secp256k1_musig_pubnonce pubnonce;
secp256k1_musig_partial_sig partial_sig;
};
/* Number of public keys involved in creating the aggregate signature */
#define N_SIGNERS 3
/* Create a key pair, store it in signer_secrets->keypair and signer->pubkey */
static int create_keypair(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, struct signer *signer) {
unsigned char seckey[32];
while (1) {
if (!fill_random(seckey, sizeof(seckey))) {
printf("Failed to generate randomness\n");
return 1;
}
if (secp256k1_keypair_create(ctx, &signer_secrets->keypair, seckey)) {
break;
}
}
if (!secp256k1_keypair_pub(ctx, &signer->pubkey, &signer_secrets->keypair)) {
return 0;
}
return 1;
}
/* Tweak the pubkey corresponding to the provided keyagg cache, update the cache
* and return the tweaked aggregate pk. */
static int tweak(const secp256k1_context* ctx, secp256k1_xonly_pubkey *agg_pk, secp256k1_musig_keyagg_cache *cache) {
secp256k1_pubkey output_pk;
unsigned char plain_tweak[32] = "this could be a BIP32 tweak....";
unsigned char xonly_tweak[32] = "this could be a taproot tweak..";
/* Plain tweaking which, for example, allows deriving multiple child
* public keys from a single aggregate key using BIP32 */
if (!secp256k1_musig_pubkey_ec_tweak_add(ctx, NULL, cache, plain_tweak)) {
return 0;
}
/* Note that we did not provided an output_pk argument, because the
* resulting pk is also saved in the cache and so if one is just interested
* in signing the output_pk argument is unnecessary. On the other hand, if
* one is not interested in signing, the same output_pk can be obtained by
* calling `secp256k1_musig_pubkey_get` right after key aggregation to get
* the full pubkey and then call `secp256k1_ec_pubkey_tweak_add`. */
/* Xonly tweaking which, for example, allows creating taproot commitments */
if (!secp256k1_musig_pubkey_xonly_tweak_add(ctx, &output_pk, cache, xonly_tweak)) {
return 0;
}
/* Note that if we wouldn't care about signing, we can arrive at the same
* output_pk by providing the untweaked public key to
* `secp256k1_xonly_pubkey_tweak_add` (after converting it to an xonly pubkey
* if necessary with `secp256k1_xonly_pubkey_from_pubkey`). */
/* Now we convert the output_pk to an xonly pubkey to allow to later verify
* the Schnorr signature against it. For this purpose we can ignore the
* `pk_parity` output argument; we would need it if we would have to open
* the taproot commitment. */
if (!secp256k1_xonly_pubkey_from_pubkey(ctx, agg_pk, NULL, &output_pk)) {
return 0;
}
return 1;
}
/* Sign a message hash with the given key pairs and store the result in sig */
static int sign(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, struct signer *signer, const secp256k1_musig_keyagg_cache *cache, const unsigned char *msg32, unsigned char *sig64) {
int i;
const secp256k1_musig_pubnonce *pubnonces[N_SIGNERS];
const secp256k1_musig_partial_sig *partial_sigs[N_SIGNERS];
/* The same for all signers */
secp256k1_musig_session session;
for (i = 0; i < N_SIGNERS; i++) {
unsigned char seckey[32];
unsigned char session_id[32];
/* Create random session ID. It is absolutely necessary that the session ID
* is unique for every call of secp256k1_musig_nonce_gen. Otherwise
* it's trivial for an attacker to extract the secret key! */
if (!fill_random(session_id, sizeof(session_id))) {
return 0;
}
if (!secp256k1_keypair_sec(ctx, seckey, &signer_secrets[i].keypair)) {
return 0;
}
/* Initialize session and create secret nonce for signing and public
* nonce to send to the other signers. */
if (!secp256k1_musig_nonce_gen(ctx, &signer_secrets[i].secnonce, &signer[i].pubnonce, session_id, seckey, &signer[i].pubkey, msg32, NULL, NULL)) {
return 0;
}
pubnonces[i] = &signer[i].pubnonce;
}
/* Communication round 1: A production system would exchange public nonces
* here before moving on. */
for (i = 0; i < N_SIGNERS; i++) {
secp256k1_musig_aggnonce agg_pubnonce;
/* Create aggregate nonce and initialize the session */
if (!secp256k1_musig_nonce_agg(ctx, &agg_pubnonce, pubnonces, N_SIGNERS)) {
return 0;
}
if (!secp256k1_musig_nonce_process(ctx, &session, &agg_pubnonce, msg32, cache, NULL)) {
return 0;
}
/* partial_sign will clear the secnonce by setting it to 0. That's because
* you must _never_ reuse the secnonce (or use the same session_id to
* create a secnonce). If you do, you effectively reuse the nonce and
* leak the secret key. */
if (!secp256k1_musig_partial_sign(ctx, &signer[i].partial_sig, &signer_secrets[i].secnonce, &signer_secrets[i].keypair, cache, &session)) {
return 0;
}
partial_sigs[i] = &signer[i].partial_sig;
}
/* Communication round 2: A production system would exchange
* partial signatures here before moving on. */
for (i = 0; i < N_SIGNERS; i++) {
/* To check whether signing was successful, it suffices to either verify
* the aggregate signature with the aggregate public key using
* secp256k1_schnorrsig_verify, or verify all partial signatures of all
* signers individually. Verifying the aggregate signature is cheaper but
* verifying the individual partial signatures has the advantage that it
* can be used to determine which of the partial signatures are invalid
* (if any), i.e., which of the partial signatures cause the aggregate
* signature to be invalid and thus the protocol run to fail. It's also
* fine to first verify the aggregate sig, and only verify the individual
* sigs if it does not work.
*/
if (!secp256k1_musig_partial_sig_verify(ctx, &signer[i].partial_sig, &signer[i].pubnonce, &signer[i].pubkey, cache, &session)) {
return 0;
}
}
return secp256k1_musig_partial_sig_agg(ctx, sig64, &session, partial_sigs, N_SIGNERS);
}
int main(void) {
secp256k1_context* ctx;
int i;
struct signer_secrets signer_secrets[N_SIGNERS];
struct signer signers[N_SIGNERS];
const secp256k1_pubkey *pubkeys_ptr[N_SIGNERS];
secp256k1_xonly_pubkey agg_pk;
secp256k1_musig_keyagg_cache cache;
unsigned char msg[32] = "this_could_be_the_hash_of_a_msg!";
unsigned char sig[64];
/* Create a secp256k1 context */
ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
printf("Creating key pairs......");
for (i = 0; i < N_SIGNERS; i++) {
if (!create_keypair(ctx, &signer_secrets[i], &signers[i])) {
printf("FAILED\n");
return 1;
}
pubkeys_ptr[i] = &signers[i].pubkey;
}
printf("ok\n");
printf("Combining public keys...");
/* If you just want to aggregate and not sign the cache can be NULL */
if (!secp256k1_musig_pubkey_agg(ctx, NULL, &agg_pk, &cache, pubkeys_ptr, N_SIGNERS)) {
printf("FAILED\n");
return 1;
}
printf("ok\n");
printf("Tweaking................");
/* Optionally tweak the aggregate key */
if (!tweak(ctx, &agg_pk, &cache)) {
printf("FAILED\n");
return 1;
}
printf("ok\n");
printf("Signing message.........");
if (!sign(ctx, signer_secrets, signers, &cache, msg, sig)) {
printf("FAILED\n");
return 1;
}
printf("ok\n");
printf("Verifying signature.....");
if (!secp256k1_schnorrsig_verify(ctx, sig, msg, 32, &agg_pk)) {
printf("FAILED\n");
return 1;
}
printf("ok\n");
secp256k1_context_destroy(ctx);
return 0;
}

156
examples/schnorr.c Normal file
View File

@@ -0,0 +1,156 @@
/*************************************************************************
* Written in 2020-2022 by Elichai Turkel *
* To the extent possible under law, the author(s) have dedicated all *
* copyright and related and neighboring rights to the software in this *
* file to the public domain worldwide. This software is distributed *
* without any warranty. For the CC0 Public Domain Dedication, see *
* EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 *
*************************************************************************/
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <secp256k1.h>
#include <secp256k1_extrakeys.h>
#include <secp256k1_schnorrsig.h>
#include "examples_util.h"
int main(void) {
unsigned char msg[12] = "Hello World!";
unsigned char msg_hash[32];
unsigned char tag[17] = "my_fancy_protocol";
unsigned char seckey[32];
unsigned char randomize[32];
unsigned char auxiliary_rand[32];
unsigned char serialized_pubkey[32];
unsigned char signature[64];
int is_signature_valid, is_signature_valid2;
int return_val;
secp256k1_xonly_pubkey pubkey;
secp256k1_keypair keypair;
/* Before we can call actual API functions, we need to create a "context". */
secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
if (!fill_random(randomize, sizeof(randomize))) {
printf("Failed to generate randomness\n");
return 1;
}
/* Randomizing the context is recommended to protect against side-channel
* leakage See `secp256k1_context_randomize` in secp256k1.h for more
* information about it. This should never fail. */
return_val = secp256k1_context_randomize(ctx, randomize);
assert(return_val);
/*** Key Generation ***/
/* If the secret key is zero or out of range (bigger than secp256k1's
* order), we try to sample a new key. Note that the probability of this
* happening is negligible. */
while (1) {
if (!fill_random(seckey, sizeof(seckey))) {
printf("Failed to generate randomness\n");
return 1;
}
/* Try to create a keypair with a valid context, it should only fail if
* the secret key is zero or out of range. */
if (secp256k1_keypair_create(ctx, &keypair, seckey)) {
break;
}
}
/* Extract the X-only public key from the keypair. We pass NULL for
* `pk_parity` as the parity isn't needed for signing or verification.
* `secp256k1_keypair_xonly_pub` supports returning the parity for
* other use cases such as tests or verifying Taproot tweaks.
* This should never fail with a valid context and public key. */
return_val = secp256k1_keypair_xonly_pub(ctx, &pubkey, NULL, &keypair);
assert(return_val);
/* Serialize the public key. Should always return 1 for a valid public key. */
return_val = secp256k1_xonly_pubkey_serialize(ctx, serialized_pubkey, &pubkey);
assert(return_val);
/*** Signing ***/
/* Instead of signing (possibly very long) messages directly, we sign a
* 32-byte hash of the message in this example.
*
* We use secp256k1_tagged_sha256 to create this hash. This function expects
* a context-specific "tag", which restricts the context in which the signed
* messages should be considered valid. For example, if protocol A mandates
* to use the tag "my_fancy_protocol" and protocol B mandates to use the tag
* "my_boring_protocol", then signed messages from protocol A will never be
* valid in protocol B (and vice versa), even if keys are reused across
* protocols. This implements "domain separation", which is considered good
* practice. It avoids attacks in which users are tricked into signing a
* message that has intended consequences in the intended context (e.g.,
* protocol A) but would have unintended consequences if it were valid in
* some other context (e.g., protocol B). */
return_val = secp256k1_tagged_sha256(ctx, msg_hash, tag, sizeof(tag), msg, sizeof(msg));
assert(return_val);
/* Generate 32 bytes of randomness to use with BIP-340 schnorr signing. */
if (!fill_random(auxiliary_rand, sizeof(auxiliary_rand))) {
printf("Failed to generate randomness\n");
return 1;
}
/* Generate a Schnorr signature.
*
* We use the secp256k1_schnorrsig_sign32 function that provides a simple
* interface for signing 32-byte messages (which in our case is a hash of
* the actual message). BIP-340 recommends passing 32 bytes of randomness
* to the signing function to improve security against side-channel attacks.
* Signing with a valid context, a 32-byte message, a verified keypair, and
* any 32 bytes of auxiliary random data should never fail. */
return_val = secp256k1_schnorrsig_sign32(ctx, signature, msg_hash, &keypair, auxiliary_rand);
assert(return_val);
/*** Verification ***/
/* Deserialize the public key. This will return 0 if the public key can't
* be parsed correctly */
if (!secp256k1_xonly_pubkey_parse(ctx, &pubkey, serialized_pubkey)) {
printf("Failed parsing the public key\n");
return 1;
}
/* Compute the tagged hash on the received messages using the same tag as the signer. */
return_val = secp256k1_tagged_sha256(ctx, msg_hash, tag, sizeof(tag), msg, sizeof(msg));
assert(return_val);
/* Verify a signature. This will return 1 if it's valid and 0 if it's not. */
is_signature_valid = secp256k1_schnorrsig_verify(ctx, signature, msg_hash, 32, &pubkey);
printf("Is the signature valid? %s\n", is_signature_valid ? "true" : "false");
printf("Secret Key: ");
print_hex(seckey, sizeof(seckey));
printf("Public Key: ");
print_hex(serialized_pubkey, sizeof(serialized_pubkey));
printf("Signature: ");
print_hex(signature, sizeof(signature));
/* This will clear everything from the context and free the memory */
secp256k1_context_destroy(ctx);
/* Bonus example: if all we need is signature verification (and no key
generation or signing), we don't need to use a context created via
secp256k1_context_create(). We can simply use the static (i.e., global)
context secp256k1_context_static. See its description in
include/secp256k1.h for details. */
is_signature_valid2 = secp256k1_schnorrsig_verify(secp256k1_context_static,
signature, msg_hash, 32, &pubkey);
assert(is_signature_valid2 == is_signature_valid);
/* It's best practice to try to clear secrets from memory after using them.
* This is done because some bugs can allow an attacker to leak memory, for
* example through "out of bounds" array access (see Heartbleed), Or the OS
* swapping them to disk. Hence, we overwrite the secret key buffer with zeros.
*
* Here we are preventing these writes from being optimized out, as any good compiler
* will remove any writes that aren't used. */
secure_erase(seckey, sizeof(seckey));
return 0;
}

View File

@@ -7,11 +7,13 @@ extern "C" {
#include <stddef.h>
/* These rules specify the order of arguments in API calls:
/** Unless explicitly stated all pointer arguments must not be NULL.
*
* The following rules specify the order of arguments in API calls:
*
* 1. Context pointers go first, followed by output arguments, combined
* output/input arguments, and finally input-only arguments.
* 2. Array lengths always immediately the follow the argument whose length
* 2. Array lengths always immediately follow the argument whose length
* they describe, even if this violates rule 1.
* 3. Within the OUT/OUTIN/IN groups, pointers to data that is typically generated
* later go first. This means: signatures, public nonces, secret nonces,
@@ -22,15 +24,19 @@ extern "C" {
* 5. Opaque data pointers follow the function pointer they are to be passed to.
*/
/** Opaque data structure that holds context information (precomputed tables etc.).
/** Opaque data structure that holds context information
*
* The purpose of context structures is to cache large precomputed data tables
* that are expensive to construct, and also to maintain the randomization data
* for blinding.
* The primary purpose of context objects is to store randomization data for
* enhanced protection against side-channel leakage. This protection is only
* effective if the context is randomized after its creation. See
* secp256k1_context_create for creation of contexts and
* secp256k1_context_randomize for randomization.
*
* Do not create a new context object for each operation, as construction is
* far slower than all other API calls (~100 times slower than an ECDSA
* verification).
* A secondary purpose of context objects is to store pointers to callback
* functions that the library will call when certain error states arise. See
* secp256k1_context_set_error_callback as well as
* secp256k1_context_set_illegal_callback for details. Future library versions
* may use context objects for additional purposes.
*
* A constructed context can safely be used from multiple threads
* simultaneously, but API calls that take a non-const pointer to a context
@@ -43,7 +49,7 @@ extern "C" {
*/
typedef struct secp256k1_context_struct secp256k1_context;
/** Opaque data structure that holds rewriteable "scratch space"
/** Opaque data structure that holds rewritable "scratch space"
*
* The purpose of this structure is to replace dynamic memory allocations,
* because we target architectures where this may not be available. It is
@@ -61,8 +67,9 @@ typedef struct secp256k1_scratch_space_struct secp256k1_scratch_space;
* The exact representation of data inside is implementation defined and not
* guaranteed to be portable between different platforms or versions. It is
* however guaranteed to be 64 bytes in size, and can be safely copied/moved.
* If you need to convert to a format suitable for storage, transmission, or
* comparison, use secp256k1_ec_pubkey_serialize and secp256k1_ec_pubkey_parse.
* If you need to convert to a format suitable for storage or transmission,
* use secp256k1_ec_pubkey_serialize and secp256k1_ec_pubkey_parse. To
* compare keys, use secp256k1_ec_pubkey_cmp.
*/
typedef struct {
unsigned char data[64];
@@ -115,35 +122,52 @@ typedef int (*secp256k1_nonce_function)(
# endif
# endif
# if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) )
# if SECP256K1_GNUC_PREREQ(2,7)
# define SECP256K1_INLINE __inline__
# elif (defined(_MSC_VER))
# define SECP256K1_INLINE __inline
# else
# define SECP256K1_INLINE
# endif
# else
# define SECP256K1_INLINE inline
# endif
/* When this header is used at build-time the SECP256K1_BUILD define needs to be set
* to correctly setup export attributes and nullness checks. This is normally done
* by secp256k1.c but to guard against this header being included before secp256k1.c
* has had a chance to set the define (e.g. via test harnesses that just includes
* secp256k1.c) we set SECP256K1_NO_BUILD when this header is processed without the
* BUILD define so this condition can be caught.
*/
#ifndef SECP256K1_BUILD
# define SECP256K1_NO_BUILD
#endif
#ifndef SECP256K1_API
# if defined(_WIN32)
# ifdef SECP256K1_BUILD
# define SECP256K1_API __declspec(dllexport)
# else
# define SECP256K1_API
/* Symbol visibility. */
#if defined(_WIN32)
/* GCC for Windows (e.g., MinGW) accepts the __declspec syntax
* for MSVC compatibility. A __declspec declaration implies (but is not
* exactly equivalent to) __attribute__ ((visibility("default"))), and so we
* actually want __declspec even on GCC, see "Microsoft Windows Function
* Attributes" in the GCC manual and the recommendations in
* https://gcc.gnu.org/wiki/Visibility. */
# if defined(SECP256K1_BUILD)
# if defined(DLL_EXPORT) || defined(SECP256K1_DLL_EXPORT)
/* Building libsecp256k1 as a DLL.
* 1. If using Libtool, it defines DLL_EXPORT automatically.
* 2. In other cases, SECP256K1_DLL_EXPORT must be defined. */
# define SECP256K1_API extern __declspec (dllexport)
# endif
# elif defined(__GNUC__) && (__GNUC__ >= 4) && defined(SECP256K1_BUILD)
# define SECP256K1_API __attribute__ ((visibility ("default")))
/* The user must define SECP256K1_STATIC when consuming libsecp256k1 as a static
* library on Windows. */
# elif !defined(SECP256K1_STATIC)
/* Consuming libsecp256k1 as a DLL. */
# define SECP256K1_API extern __declspec (dllimport)
# endif
#endif
#ifndef SECP256K1_API
# if defined(__GNUC__) && (__GNUC__ >= 4) && defined(SECP256K1_BUILD)
/* Building libsecp256k1 on non-Windows using GCC or compatible. */
# define SECP256K1_API extern __attribute__ ((visibility ("default")))
# else
# define SECP256K1_API
/* All cases not captured above. */
# define SECP256K1_API extern
# endif
#endif
/**Warning attributes
* NONNULL is not used if SECP256K1_BUILD is set to avoid the compiler optimizing out
* some paranoid null checks. */
/* Warning attributes
* NONNULL is not used if SECP256K1_BUILD is set to avoid the compiler optimizing out
* some paranoid null checks. */
# if defined(__GNUC__) && SECP256K1_GNUC_PREREQ(3, 4)
# define SECP256K1_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__))
# else
@@ -155,22 +179,37 @@ typedef int (*secp256k1_nonce_function)(
# define SECP256K1_ARG_NONNULL(_x)
# endif
/** All flags' lower 8 bits indicate what they're for. Do not use directly. */
/* Attribute for marking functions, types, and variables as deprecated */
#if !defined(SECP256K1_BUILD) && defined(__has_attribute)
# if __has_attribute(__deprecated__)
# define SECP256K1_DEPRECATED(_msg) __attribute__ ((__deprecated__(_msg)))
# else
# define SECP256K1_DEPRECATED(_msg)
# endif
#else
# define SECP256K1_DEPRECATED(_msg)
#endif
/* All flags' lower 8 bits indicate what they're for. Do not use directly. */
#define SECP256K1_FLAGS_TYPE_MASK ((1 << 8) - 1)
#define SECP256K1_FLAGS_TYPE_CONTEXT (1 << 0)
#define SECP256K1_FLAGS_TYPE_COMPRESSION (1 << 1)
/** The higher bits contain the actual data. Do not use directly. */
/* The higher bits contain the actual data. Do not use directly. */
#define SECP256K1_FLAGS_BIT_CONTEXT_VERIFY (1 << 8)
#define SECP256K1_FLAGS_BIT_CONTEXT_SIGN (1 << 9)
#define SECP256K1_FLAGS_BIT_CONTEXT_DECLASSIFY (1 << 10)
#define SECP256K1_FLAGS_BIT_COMPRESSION (1 << 8)
/** Flags to pass to secp256k1_context_create, secp256k1_context_preallocated_size, and
/** Context flags to pass to secp256k1_context_create, secp256k1_context_preallocated_size, and
* secp256k1_context_preallocated_create. */
#define SECP256K1_CONTEXT_NONE (SECP256K1_FLAGS_TYPE_CONTEXT)
/** Deprecated context flags. These flags are treated equivalent to SECP256K1_CONTEXT_NONE. */
#define SECP256K1_CONTEXT_VERIFY (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_VERIFY)
#define SECP256K1_CONTEXT_SIGN (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_SIGN)
/* Testing flag. Do not use. */
#define SECP256K1_CONTEXT_DECLASSIFY (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_DECLASSIFY)
#define SECP256K1_CONTEXT_NONE (SECP256K1_FLAGS_TYPE_CONTEXT)
/** Flag to pass to secp256k1_ec_pubkey_serialize. */
#define SECP256K1_EC_COMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION | SECP256K1_FLAGS_BIT_COMPRESSION)
@@ -183,25 +222,68 @@ typedef int (*secp256k1_nonce_function)(
#define SECP256K1_TAG_PUBKEY_HYBRID_EVEN 0x06
#define SECP256K1_TAG_PUBKEY_HYBRID_ODD 0x07
/** A simple secp256k1 context object with no precomputed tables. These are useful for
* type serialization/parsing functions which require a context object to maintain
* API consistency, but currently do not require expensive precomputations or dynamic
* allocations.
/** A built-in constant secp256k1 context object with static storage duration, to be
* used in conjunction with secp256k1_selftest.
*
* This context object offers *only limited functionality* , i.e., it cannot be used
* for API functions that perform computations involving secret keys, e.g., signing
* and public key generation. If this restriction applies to a specific API function,
* it is mentioned in its documentation. See secp256k1_context_create if you need a
* full context object that supports all functionality offered by the library.
*
* It is highly recommended to call secp256k1_selftest before using this context.
*/
SECP256K1_API extern const secp256k1_context *secp256k1_context_no_precomp;
SECP256K1_API const secp256k1_context *secp256k1_context_static;
/** Deprecated alias for secp256k1_context_static. */
SECP256K1_API const secp256k1_context *secp256k1_context_no_precomp
SECP256K1_DEPRECATED("Use secp256k1_context_static instead");
/** Perform basic self tests (to be used in conjunction with secp256k1_context_static)
*
* This function performs self tests that detect some serious usage errors and
* similar conditions, e.g., when the library is compiled for the wrong endianness.
* This is a last resort measure to be used in production. The performed tests are
* very rudimentary and are not intended as a replacement for running the test
* binaries.
*
* It is highly recommended to call this before using secp256k1_context_static.
* It is not necessary to call this function before using a context created with
* secp256k1_context_create (or secp256k1_context_preallocated_create), which will
* take care of performing the self tests.
*
* If the tests fail, this function will call the default error handler to abort the
* program (see secp256k1_context_set_error_callback).
*/
SECP256K1_API void secp256k1_selftest(void);
/** Create a secp256k1 context object (in dynamically allocated memory).
*
* This function uses malloc to allocate memory. It is guaranteed that malloc is
* called at most once for every call of this function. If you need to avoid dynamic
* memory allocation entirely, see the functions in secp256k1_preallocated.h.
* memory allocation entirely, see secp256k1_context_static and the functions in
* secp256k1_preallocated.h.
*
* Returns: a newly created context object.
* In: flags: which parts of the context to initialize.
* Returns: pointer to a newly created context object.
* In: flags: Always set to SECP256K1_CONTEXT_NONE (see below).
*
* See also secp256k1_context_randomize.
* The only valid non-deprecated flag in recent library versions is
* SECP256K1_CONTEXT_NONE, which will create a context sufficient for all functionality
* offered by the library. All other (deprecated) flags will be treated as equivalent
* to the SECP256K1_CONTEXT_NONE flag. Though the flags parameter primarily exists for
* historical reasons, future versions of the library may introduce new flags.
*
* If the context is intended to be used for API functions that perform computations
* involving secret keys, e.g., signing and public key generation, then it is highly
* recommended to call secp256k1_context_randomize on the context before calling
* those API functions. This will provide enhanced protection against side-channel
* leakage, see secp256k1_context_randomize for details.
*
* Do not create a new context object for each operation, as construction and
* randomization can take non-negligible time.
*/
SECP256K1_API secp256k1_context* secp256k1_context_create(
SECP256K1_API secp256k1_context *secp256k1_context_create(
unsigned int flags
) SECP256K1_WARN_UNUSED_RESULT;
@@ -211,11 +293,14 @@ SECP256K1_API secp256k1_context* secp256k1_context_create(
* called at most once for every call of this function. If you need to avoid dynamic
* memory allocation entirely, see the functions in secp256k1_preallocated.h.
*
* Returns: a newly created context object.
* Args: ctx: an existing context to copy (cannot be NULL)
* Cloning secp256k1_context_static is not possible, and should not be emulated by
* the caller (e.g., using memcpy). Create a new context instead.
*
* Returns: pointer to a newly created context object.
* Args: ctx: pointer to a context to copy (not secp256k1_context_static).
*/
SECP256K1_API secp256k1_context* secp256k1_context_clone(
const secp256k1_context* ctx
SECP256K1_API secp256k1_context *secp256k1_context_clone(
const secp256k1_context *ctx
) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT;
/** Destroy a secp256k1 context object (created in dynamically allocated memory).
@@ -228,12 +313,13 @@ SECP256K1_API secp256k1_context* secp256k1_context_clone(
* behaviour is undefined. In that case, secp256k1_context_preallocated_destroy must
* be used instead.
*
* Args: ctx: an existing context to destroy, constructed using
* Args: ctx: pointer to a context to destroy, constructed using
* secp256k1_context_create or secp256k1_context_clone
* (i.e., not secp256k1_context_static).
*/
SECP256K1_API void secp256k1_context_destroy(
secp256k1_context* ctx
);
secp256k1_context *ctx
) SECP256K1_ARG_NONNULL(1);
/** Set a callback function to be called when an illegal argument is passed to
* an API call. It will only trigger for violations that are mentioned
@@ -250,36 +336,39 @@ SECP256K1_API void secp256k1_context_destroy(
* undefined.
*
* When this function has not been called (or called with fn==NULL), then the
* default handler will be used. The library provides a default handler which
* default handler will be used. The library provides a default handler which
* writes the message to stderr and calls abort. This default handler can be
* replaced at link time if the preprocessor macro
* USE_EXTERNAL_DEFAULT_CALLBACKS is defined, which is the case if the build
* has been configured with --enable-external-default-callbacks. Then the
* following two symbols must be provided to link against:
* - void secp256k1_default_illegal_callback_fn(const char* message, void* data);
* - void secp256k1_default_error_callback_fn(const char* message, void* data);
* - void secp256k1_default_illegal_callback_fn(const char *message, void *data);
* - void secp256k1_default_error_callback_fn(const char *message, void *data);
* The library can call these default handlers even before a proper callback data
* pointer could have been set using secp256k1_context_set_illegal_callback or
* secp256k1_context_set_error_callback, e.g., when the creation of a context
* fails. In this case, the corresponding default handler will be called with
* the data pointer argument set to NULL.
*
* Args: ctx: an existing context object (cannot be NULL)
* In: fun: a pointer to a function to call when an illegal argument is
* Args: ctx: pointer to a context object.
* In: fun: pointer to a function to call when an illegal argument is
* passed to the API, taking a message and an opaque pointer.
* (NULL restores the default handler.)
* data: the opaque pointer to pass to fun above.
* data: the opaque pointer to pass to fun above, must be NULL for the default handler.
*
* See also secp256k1_context_set_error_callback.
*/
SECP256K1_API void secp256k1_context_set_illegal_callback(
secp256k1_context* ctx,
void (*fun)(const char* message, void* data),
const void* data
secp256k1_context *ctx,
void (*fun)(const char *message, void *data),
const void *data
) SECP256K1_ARG_NONNULL(1);
/** Set a callback function to be called when an internal consistency check
* fails. The default is crashing.
* fails.
*
* The default callback writes an error message to stderr and calls abort
* to abort the program.
*
* This can only trigger in case of a hardware failure, miscompilation,
* memory corruption, serious bug in the library, or other error would can
@@ -288,49 +377,49 @@ SECP256K1_API void secp256k1_context_set_illegal_callback(
* for that). After this callback returns, anything may happen, including
* crashing.
*
* Args: ctx: an existing context object (cannot be NULL)
* In: fun: a pointer to a function to call when an internal error occurs,
* Args: ctx: pointer to a context object.
* In: fun: pointer to a function to call when an internal error occurs,
* taking a message and an opaque pointer (NULL restores the
* default handler, see secp256k1_context_set_illegal_callback
* for details).
* data: the opaque pointer to pass to fun above.
* data: the opaque pointer to pass to fun above, must be NULL for the default handler.
*
* See also secp256k1_context_set_illegal_callback.
*/
SECP256K1_API void secp256k1_context_set_error_callback(
secp256k1_context* ctx,
void (*fun)(const char* message, void* data),
const void* data
secp256k1_context *ctx,
void (*fun)(const char *message, void *data),
const void *data
) SECP256K1_ARG_NONNULL(1);
/** Create a secp256k1 scratch space object.
*
* Returns: a newly created scratch space.
* Args: ctx: an existing context object (cannot be NULL)
* Args: ctx: pointer to a context object.
* In: size: amount of memory to be available as scratch space. Some extra
* (<100 bytes) will be allocated for extra accounting.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT secp256k1_scratch_space* secp256k1_scratch_space_create(
const secp256k1_context* ctx,
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT secp256k1_scratch_space *secp256k1_scratch_space_create(
const secp256k1_context *ctx,
size_t size
) SECP256K1_ARG_NONNULL(1);
/** Destroy a secp256k1 scratch space.
*
* The pointer may not be used afterwards.
* Args: ctx: a secp256k1 context object.
* Args: ctx: pointer to a context object.
* scratch: space to destroy
*/
SECP256K1_API void secp256k1_scratch_space_destroy(
const secp256k1_context* ctx,
secp256k1_scratch_space* scratch
const secp256k1_context *ctx,
secp256k1_scratch_space *scratch
) SECP256K1_ARG_NONNULL(1);
/** Parse a variable-length public key into the pubkey object.
*
* Returns: 1 if the public key was fully valid.
* 0 if the public key could not be parsed or is invalid.
* Args: ctx: a secp256k1 context object.
* Args: ctx: pointer to a context object.
* Out: pubkey: pointer to a pubkey object. If 1 is returned, it is set to a
* parsed version of input. If not, its value is undefined.
* In: input: pointer to a serialized public key
@@ -341,8 +430,8 @@ SECP256K1_API void secp256k1_scratch_space_destroy(
* byte 0x06 or 0x07) format public keys.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(
const secp256k1_context* ctx,
secp256k1_pubkey* pubkey,
const secp256k1_context *ctx,
secp256k1_pubkey *pubkey,
const unsigned char *input,
size_t inputlen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
@@ -350,65 +439,80 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(
/** Serialize a pubkey object into a serialized byte sequence.
*
* Returns: 1 always.
* Args: ctx: a secp256k1 context object.
* Out: output: a pointer to a 65-byte (if compressed==0) or 33-byte (if
* Args: ctx: pointer to a context object.
* Out: output: pointer to a 65-byte (if compressed==0) or 33-byte (if
* compressed==1) byte array to place the serialized key
* in.
* In/Out: outputlen: a pointer to an integer which is initially set to the
* In/Out: outputlen: pointer to an integer which is initially set to the
* size of output, and is overwritten with the written
* size.
* In: pubkey: a pointer to a secp256k1_pubkey containing an
* In: pubkey: pointer to a secp256k1_pubkey containing an
* initialized public key.
* flags: SECP256K1_EC_COMPRESSED if serialization should be in
* compressed format, otherwise SECP256K1_EC_UNCOMPRESSED.
*/
SECP256K1_API int secp256k1_ec_pubkey_serialize(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
unsigned char *output,
size_t *outputlen,
const secp256k1_pubkey* pubkey,
const secp256k1_pubkey *pubkey,
unsigned int flags
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Compare two public keys using lexicographic (of compressed serialization) order
*
* Returns: <0 if the first public key is less than the second
* >0 if the first public key is greater than the second
* 0 if the two public keys are equal
* Args: ctx: pointer to a context object
* In: pubkey1: first public key to compare
* pubkey2: second public key to compare
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_cmp(
const secp256k1_context *ctx,
const secp256k1_pubkey *pubkey1,
const secp256k1_pubkey *pubkey2
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Parse an ECDSA signature in compact (64 bytes) format.
*
* Returns: 1 when the signature could be parsed, 0 otherwise.
* Args: ctx: a secp256k1 context object
* Out: sig: a pointer to a signature object
* In: input64: a pointer to the 64-byte array to parse
* Args: ctx: pointer to a context object
* Out: sig: pointer to a signature object
* In: input64: pointer to the 64-byte array to parse
*
* The signature must consist of a 32-byte big endian R value, followed by a
* 32-byte big endian S value. If R or S fall outside of [0..order-1], the
* encoding is invalid. R and S with value 0 are allowed in the encoding.
*
* After the call, sig will always be initialized. If parsing failed or R or
* S are zero, the resulting sig value is guaranteed to fail validation for any
* message and public key.
* S are zero, the resulting sig value is guaranteed to fail verification for
* any message and public key.
*/
SECP256K1_API int secp256k1_ecdsa_signature_parse_compact(
const secp256k1_context* ctx,
secp256k1_ecdsa_signature* sig,
const secp256k1_context *ctx,
secp256k1_ecdsa_signature *sig,
const unsigned char *input64
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Parse a DER ECDSA signature.
*
* Returns: 1 when the signature could be parsed, 0 otherwise.
* Args: ctx: a secp256k1 context object
* Out: sig: a pointer to a signature object
* In: input: a pointer to the signature to be parsed
* Args: ctx: pointer to a context object
* Out: sig: pointer to a signature object
* In: input: pointer to the signature to be parsed
* inputlen: the length of the array pointed to be input
*
* This function will accept any valid DER encoded signature, even if the
* encoded numbers are out of range.
*
* After the call, sig will always be initialized. If parsing failed or the
* encoded numbers are out of range, signature validation with it is
* encoded numbers are out of range, signature verification with it is
* guaranteed to fail for every message and public key.
*/
SECP256K1_API int secp256k1_ecdsa_signature_parse_der(
const secp256k1_context* ctx,
secp256k1_ecdsa_signature* sig,
const secp256k1_context *ctx,
secp256k1_ecdsa_signature *sig,
const unsigned char *input,
size_t inputlen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
@@ -416,71 +520,77 @@ SECP256K1_API int secp256k1_ecdsa_signature_parse_der(
/** Serialize an ECDSA signature in DER format.
*
* Returns: 1 if enough space was available to serialize, 0 otherwise
* Args: ctx: a secp256k1 context object
* Out: output: a pointer to an array to store the DER serialization
* In/Out: outputlen: a pointer to a length integer. Initially, this integer
* Args: ctx: pointer to a context object
* Out: output: pointer to an array to store the DER serialization
* In/Out: outputlen: pointer to a length integer. Initially, this integer
* should be set to the length of output. After the call
* it will be set to the length of the serialization (even
* if 0 was returned).
* In: sig: a pointer to an initialized signature object
* In: sig: pointer to an initialized signature object
*/
SECP256K1_API int secp256k1_ecdsa_signature_serialize_der(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
unsigned char *output,
size_t *outputlen,
const secp256k1_ecdsa_signature* sig
const secp256k1_ecdsa_signature *sig
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Serialize an ECDSA signature in compact (64 byte) format.
*
* Returns: 1
* Args: ctx: a secp256k1 context object
* Out: output64: a pointer to a 64-byte array to store the compact serialization
* In: sig: a pointer to an initialized signature object
* Args: ctx: pointer to a context object
* Out: output64: pointer to a 64-byte array to store the compact serialization
* In: sig: pointer to an initialized signature object
*
* See secp256k1_ecdsa_signature_parse_compact for details about the encoding.
*/
SECP256K1_API int secp256k1_ecdsa_signature_serialize_compact(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
unsigned char *output64,
const secp256k1_ecdsa_signature* sig
const secp256k1_ecdsa_signature *sig
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Verify an ECDSA signature.
*
* Returns: 1: correct signature
* 0: incorrect or unparseable signature
* Args: ctx: a secp256k1 context object, initialized for verification.
* In: sig: the signature being verified (cannot be NULL)
* msg32: the 32-byte message hash being verified (cannot be NULL)
* pubkey: pointer to an initialized public key to verify with (cannot be NULL)
* Args: ctx: pointer to a context object
* In: sig: the signature being verified.
* msghash32: the 32-byte message hash being verified.
* The verifier must make sure to apply a cryptographic
* hash function to the message by itself and not accept an
* msghash32 value directly. Otherwise, it would be easy to
* create a "valid" signature without knowledge of the
* secret key. See also
* https://bitcoin.stackexchange.com/a/81116/35586 for more
* background on this topic.
* pubkey: pointer to an initialized public key to verify with.
*
* To avoid accepting malleable signatures, only ECDSA signatures in lower-S
* form are accepted.
*
* If you need to accept ECDSA signatures from sources that do not obey this
* rule, apply secp256k1_ecdsa_signature_normalize to the signature prior to
* validation, but be aware that doing so results in malleable signatures.
* verification, but be aware that doing so results in malleable signatures.
*
* For details, see the comments for that function.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
const secp256k1_ecdsa_signature *sig,
const unsigned char *msg32,
const unsigned char *msghash32,
const secp256k1_pubkey *pubkey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Convert a signature to a normalized lower-S form.
*
* Returns: 1 if sigin was not normalized, 0 if it already was.
* Args: ctx: a secp256k1 context object
* Out: sigout: a pointer to a signature to fill with the normalized form,
* Args: ctx: pointer to a context object
* Out: sigout: pointer to a signature to fill with the normalized form,
* or copy if the input was already normalized. (can be NULL if
* you're only interested in whether the input was already
* normalized).
* In: sigin: a pointer to a signature to check/normalize (cannot be NULL,
* can be identical to sigout)
* In: sigin: pointer to a signature to check/normalize (can be identical to sigout)
*
* With ECDSA a third-party can forge a second distinct signature of the same
* message, given a single initial signature, but without knowing the key. This
@@ -514,7 +624,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(
* secp256k1_ecdsa_signature_normalize must be called before verification.
*/
SECP256K1_API int secp256k1_ecdsa_signature_normalize(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
secp256k1_ecdsa_signature *sigout,
const secp256k1_ecdsa_signature *sigin
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3);
@@ -523,29 +633,33 @@ SECP256K1_API int secp256k1_ecdsa_signature_normalize(
* If a data pointer is passed, it is assumed to be a pointer to 32 bytes of
* extra entropy.
*/
SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_rfc6979;
SECP256K1_API const secp256k1_nonce_function secp256k1_nonce_function_rfc6979;
/** A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979). */
SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_default;
SECP256K1_API const secp256k1_nonce_function secp256k1_nonce_function_default;
/** Create an ECDSA signature.
*
* Returns: 1: signature created
* 0: the nonce generation function failed, or the secret key was invalid.
* Args: ctx: pointer to a context object, initialized for signing (cannot be NULL)
* Out: sig: pointer to an array where the signature will be placed (cannot be NULL)
* In: msg32: the 32-byte message hash being signed (cannot be NULL)
* seckey: pointer to a 32-byte secret key (cannot be NULL)
* noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used
* ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
* Args: ctx: pointer to a context object (not secp256k1_context_static).
* Out: sig: pointer to an array where the signature will be placed.
* In: msghash32: the 32-byte message hash being signed.
* seckey: pointer to a 32-byte secret key.
* noncefp: pointer to a nonce generation function. If NULL,
* secp256k1_nonce_function_default is used.
* ndata: pointer to arbitrary data used by the nonce generation function
* (can be NULL). If it is non-NULL and
* secp256k1_nonce_function_default is used, then ndata must be a
* pointer to 32-bytes of additional data.
*
* The created signature is always in lower-S form. See
* secp256k1_ecdsa_signature_normalize for more details.
*/
SECP256K1_API int secp256k1_ecdsa_sign(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
secp256k1_ecdsa_signature *sig,
const unsigned char *msg32,
const unsigned char *msghash32,
const unsigned char *seckey,
secp256k1_nonce_function noncefp,
const void *ndata
@@ -560,24 +674,24 @@ SECP256K1_API int secp256k1_ecdsa_sign(
*
* Returns: 1: secret key is valid
* 0: secret key is invalid
* Args: ctx: pointer to a context object (cannot be NULL)
* In: seckey: pointer to a 32-byte secret key (cannot be NULL)
* Args: ctx: pointer to a context object.
* In: seckey: pointer to a 32-byte secret key.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
const unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
/** Compute the public key for a secret key.
*
* Returns: 1: secret was valid, public key stores
* 0: secret was invalid, try again
* Args: ctx: pointer to a context object, initialized for signing (cannot be NULL)
* Out: pubkey: pointer to the created public key (cannot be NULL)
* In: seckey: pointer to a 32-byte secret key (cannot be NULL)
* Returns: 1: secret was valid, public key stores.
* 0: secret was invalid, try again.
* Args: ctx: pointer to a context object (not secp256k1_context_static).
* Out: pubkey: pointer to the created public key.
* In: seckey: pointer to a 32-byte secret key.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
secp256k1_pubkey *pubkey,
const unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
@@ -590,29 +704,29 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
* In/Out: seckey: pointer to the 32-byte secret key to be negated. If the
* secret key is invalid according to
* secp256k1_ec_seckey_verify, this function returns 0 and
* seckey will be set to some unspecified value. (cannot be
* NULL)
* seckey will be set to some unspecified value.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_negate(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
/** Same as secp256k1_ec_seckey_negate, but DEPRECATED. Will be removed in
* future versions. */
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_negate(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2)
SECP256K1_DEPRECATED("Use secp256k1_ec_seckey_negate instead");
/** Negates a public key in place.
*
* Returns: 1 always
* Args: ctx: pointer to a context object
* In/Out: pubkey: pointer to the public key to be negated (cannot be NULL)
* In/Out: pubkey: pointer to the public key to be negated.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_negate(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
secp256k1_pubkey *pubkey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
@@ -621,122 +735,129 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_negate(
* Returns: 0 if the arguments are invalid or the resulting secret key would be
* invalid (only when the tweak is the negation of the secret key). 1
* otherwise.
* Args: ctx: pointer to a context object (cannot be NULL).
* Args: ctx: pointer to a context object.
* In/Out: seckey: pointer to a 32-byte secret key. If the secret key is
* invalid according to secp256k1_ec_seckey_verify, this
* function returns 0. seckey will be set to some unspecified
* value if this function returns 0. (cannot be NULL)
* In: tweak: pointer to a 32-byte tweak. If the tweak is invalid according to
* secp256k1_ec_seckey_verify, this function returns 0. For
* uniformly random 32-byte arrays the chance of being invalid
* is negligible (around 1 in 2^128) (cannot be NULL).
* value if this function returns 0.
* In: tweak32: pointer to a 32-byte tweak, which must be valid according to
* secp256k1_ec_seckey_verify or 32 zero bytes. For uniformly
* random 32-byte tweaks, the chance of being invalid is
* negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_add(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
unsigned char *seckey,
const unsigned char *tweak
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Same as secp256k1_ec_seckey_tweak_add, but DEPRECATED. Will be removed in
* future versions. */
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
unsigned char *seckey,
const unsigned char *tweak
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
SECP256K1_DEPRECATED("Use secp256k1_ec_seckey_tweak_add instead");
/** Tweak a public key by adding tweak times the generator to it.
*
* Returns: 0 if the arguments are invalid or the resulting public key would be
* invalid (only when the tweak is the negation of the corresponding
* secret key). 1 otherwise.
* Args: ctx: pointer to a context object initialized for validation
* (cannot be NULL).
* Args: ctx: pointer to a context object.
* In/Out: pubkey: pointer to a public key object. pubkey will be set to an
* invalid value if this function returns 0 (cannot be NULL).
* In: tweak: pointer to a 32-byte tweak. If the tweak is invalid according to
* secp256k1_ec_seckey_verify, this function returns 0. For
* uniformly random 32-byte arrays the chance of being invalid
* is negligible (around 1 in 2^128) (cannot be NULL).
* invalid value if this function returns 0.
* In: tweak32: pointer to a 32-byte tweak, which must be valid according to
* secp256k1_ec_seckey_verify or 32 zero bytes. For uniformly
* random 32-byte tweaks, the chance of being invalid is
* negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
secp256k1_pubkey *pubkey,
const unsigned char *tweak
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Tweak a secret key by multiplying it by a tweak.
*
* Returns: 0 if the arguments are invalid. 1 otherwise.
* Args: ctx: pointer to a context object (cannot be NULL).
* Args: ctx: pointer to a context object.
* In/Out: seckey: pointer to a 32-byte secret key. If the secret key is
* invalid according to secp256k1_ec_seckey_verify, this
* function returns 0. seckey will be set to some unspecified
* value if this function returns 0. (cannot be NULL)
* In: tweak: pointer to a 32-byte tweak. If the tweak is invalid according to
* value if this function returns 0.
* In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to
* secp256k1_ec_seckey_verify, this function returns 0. For
* uniformly random 32-byte arrays the chance of being invalid
* is negligible (around 1 in 2^128) (cannot be NULL).
* is negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_mul(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
unsigned char *seckey,
const unsigned char *tweak
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Same as secp256k1_ec_seckey_tweak_mul, but DEPRECATED. Will be removed in
* future versions. */
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
unsigned char *seckey,
const unsigned char *tweak
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
SECP256K1_DEPRECATED("Use secp256k1_ec_seckey_tweak_mul instead");
/** Tweak a public key by multiplying it by a tweak value.
*
* Returns: 0 if the arguments are invalid. 1 otherwise.
* Args: ctx: pointer to a context object initialized for validation
* (cannot be NULL).
* Args: ctx: pointer to a context object.
* In/Out: pubkey: pointer to a public key object. pubkey will be set to an
* invalid value if this function returns 0 (cannot be NULL).
* In: tweak: pointer to a 32-byte tweak. If the tweak is invalid according to
* invalid value if this function returns 0.
* In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to
* secp256k1_ec_seckey_verify, this function returns 0. For
* uniformly random 32-byte arrays the chance of being invalid
* is negligible (around 1 in 2^128) (cannot be NULL).
* is negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
secp256k1_pubkey *pubkey,
const unsigned char *tweak
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Updates the context randomization to protect against side-channel leakage.
* Returns: 1: randomization successfully updated or nothing to randomize
/** Randomizes the context to provide enhanced protection against side-channel leakage.
*
* Returns: 1: randomization successful
* 0: error
* Args: ctx: pointer to a context object (cannot be NULL)
* In: seed32: pointer to a 32-byte random seed (NULL resets to initial state)
* Args: ctx: pointer to a context object (not secp256k1_context_static).
* In: seed32: pointer to a 32-byte random seed (NULL resets to initial state).
*
* While secp256k1 code is written to be constant-time no matter what secret
* values are, it's possible that a future compiler may output code which isn't,
* While secp256k1 code is written and tested to be constant-time no matter what
* secret values are, it is possible that a compiler may output code which is not,
* and also that the CPU may not emit the same radio frequencies or draw the same
* amount power for all values.
* amount of power for all values. Randomization of the context shields against
* side-channel observations which aim to exploit secret-dependent behaviour in
* certain computations which involve secret keys.
*
* This function provides a seed which is combined into the blinding value: that
* blinding value is added before each multiplication (and removed afterwards) so
* that it does not affect function results, but shields against attacks which
* rely on any input-dependent behaviour.
* It is highly recommended to call this function on contexts returned from
* secp256k1_context_create or secp256k1_context_clone (or from the corresponding
* functions in secp256k1_preallocated.h) before using these contexts to call API
* functions that perform computations involving secret keys, e.g., signing and
* public key generation. It is possible to call this function more than once on
* the same context, and doing so before every few computations involving secret
* keys is recommended as a defense-in-depth measure. Randomization of the static
* context secp256k1_context_static is not supported.
*
* This function has currently an effect only on contexts initialized for signing
* because randomization is currently used only for signing. However, this is not
* guaranteed and may change in the future. It is safe to call this function on
* contexts not initialized for signing; then it will have no effect and return 1.
*
* You should call this after secp256k1_context_create or
* secp256k1_context_clone (and secp256k1_context_preallocated_create or
* secp256k1_context_clone, resp.), and you may call this repeatedly afterwards.
* Currently, the random seed is mainly used for blinding multiplications of a
* secret scalar with the elliptic curve base point. Multiplications of this
* kind are performed by exactly those API functions which are documented to
* require a context that is not secp256k1_context_static. As a rule of thumb,
* these are all functions which take a secret key (or a keypair) as an input.
* A notable exception to that rule is the ECDH module, which relies on a different
* kind of elliptic curve point multiplication and thus does not benefit from
* enhanced protection against side-channel leakage currently.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize(
secp256k1_context* ctx,
secp256k1_context *ctx,
const unsigned char *seed32
) SECP256K1_ARG_NONNULL(1);
@@ -744,18 +865,42 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize(
*
* Returns: 1: the sum of the public keys is valid.
* 0: the sum of the public keys is not valid.
* Args: ctx: pointer to a context object
* Out: out: pointer to a public key object for placing the resulting public key
* (cannot be NULL)
* In: ins: pointer to array of pointers to public keys (cannot be NULL)
* n: the number of public keys to add together (must be at least 1)
* Args: ctx: pointer to a context object.
* Out: out: pointer to a public key object for placing the resulting public key.
* In: ins: pointer to array of pointers to public keys.
* n: the number of public keys to add together (must be at least 1).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_combine(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
secp256k1_pubkey *out,
const secp256k1_pubkey * const * ins,
const secp256k1_pubkey * const *ins,
size_t n
) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Compute a tagged hash as defined in BIP-340.
*
* This is useful for creating a message hash and achieving domain separation
* through an application-specific tag. This function returns
* SHA256(SHA256(tag)||SHA256(tag)||msg). Therefore, tagged hash
* implementations optimized for a specific tag can precompute the SHA256 state
* after hashing the tag hashes.
*
* Returns: 1 always.
* Args: ctx: pointer to a context object
* Out: hash32: pointer to a 32-byte array to store the resulting hash
* In: tag: pointer to an array containing the tag
* taglen: length of the tag array
* msg: pointer to an array containing the message
* msglen: length of the message array
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_tagged_sha256(
const secp256k1_context *ctx,
unsigned char *hash32,
const unsigned char *tag,
size_t taglen,
const unsigned char *msg,
size_t msglen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
#ifdef __cplusplus
}

73
include/secp256k1_bppp.h Normal file
View File

@@ -0,0 +1,73 @@
#ifndef SECP256K1_BPPP_H
# define SECP256K1_BPPP_H
# include "secp256k1.h"
# ifdef __cplusplus
extern "C" {
# endif
#include <stdint.h>
/** Opaque structure representing a large number of NUMS generators */
typedef struct secp256k1_bppp_generators secp256k1_bppp_generators;
/** Allocates and initializes a list of NUMS generators.
* Returns a list of generators, or calls the error callback if the allocation fails.
* Args: ctx: pointer to a context object
* n: number of NUMS generators to produce.
*
* TODO: In a followup range-proof PR, this is would still require 16 + 8 = 24 NUMS
* points. We will later use G = H0(required for compatibility with pedersen_commitment DS)
* in a separate commit to make review easier.
*/
SECP256K1_API secp256k1_bppp_generators *secp256k1_bppp_generators_create(
const secp256k1_context *ctx,
size_t n
) SECP256K1_ARG_NONNULL(1);
/** Allocates a list of generators from a static array
* Returns a list of generators or NULL in case of failure.
* Args: ctx: pointer to a context object
* In: data: data that came from `secp256k1_bppp_generators_serialize`
* data_len: the length of the `data` buffer
*/
SECP256K1_API secp256k1_bppp_generators *secp256k1_bppp_generators_parse(
const secp256k1_context *ctx,
const unsigned char *data,
size_t data_len
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
/** Serializes a list of generators to an array
* Returns 1 on success, 0 if the provided array was not large enough
* Args: ctx: pointer to a context object
* gen: pointer to the generator set to be serialized
* Out: data: pointer to buffer into which the generators will be serialized
* In/Out: data_len: the length of the `data` buffer. Should be at least
* k = 33 * num_gens. Will be set to k on successful return
*
* TODO: For ease of review, this setting G = H0 is not included in this commit. We will
* add it in the follow-up rangeproof PR.
*/
SECP256K1_API int secp256k1_bppp_generators_serialize(
const secp256k1_context *ctx,
const secp256k1_bppp_generators *gen,
unsigned char *data,
size_t *data_len
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Destroys a list of NUMS generators, freeing allocated memory
* Args: ctx: pointer to a context object
* gen: pointer to the generator set to be destroyed
* (can be NULL, in which case this function is a no-op)
*/
SECP256K1_API void secp256k1_bppp_generators_destroy(
const secp256k1_context *ctx,
secp256k1_bppp_generators *gen
) SECP256K1_ARG_NONNULL(1);
# ifdef __cplusplus
}
# endif
#endif

View File

@@ -27,27 +27,28 @@ typedef int (*secp256k1_ecdh_hash_function)(
/** An implementation of SHA256 hash function that applies to compressed public key.
* Populates the output parameter with 32 bytes. */
SECP256K1_API extern const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256;
SECP256K1_API const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256;
/** A default ECDH hash function (currently equal to secp256k1_ecdh_hash_function_sha256).
* Populates the output parameter with 32 bytes. */
SECP256K1_API extern const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default;
SECP256K1_API const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default;
/** Compute an EC Diffie-Hellman secret in constant time
*
* Returns: 1: exponentiation was successful
* 0: scalar was invalid (zero or overflow) or hashfp returned 0
* Args: ctx: pointer to a context object (cannot be NULL)
* Out: output: pointer to an array to be filled by hashfp
* In: pubkey: a pointer to a secp256k1_pubkey containing an
* initialized public key
* seckey: a 32-byte scalar with which to multiply the point
* hashfp: pointer to a hash function. If NULL, secp256k1_ecdh_hash_function_sha256 is used
* (in which case, 32 bytes will be written to output)
* Args: ctx: pointer to a context object.
* Out: output: pointer to an array to be filled by hashfp.
* In: pubkey: pointer to a secp256k1_pubkey containing an initialized public key.
* seckey: a 32-byte scalar with which to multiply the point.
* hashfp: pointer to a hash function. If NULL,
* secp256k1_ecdh_hash_function_sha256 is used
* (in which case, 32 bytes will be written to output).
* data: arbitrary data pointer that is passed through to hashfp
* (can be NULL for secp256k1_ecdh_hash_function_sha256).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
unsigned char *output,
const secp256k1_pubkey *pubkey,
const unsigned char *seckey,

View File

@@ -0,0 +1,164 @@
#ifndef SECP256K1_ECDSA_ADAPTOR_H
#define SECP256K1_ECDSA_ADAPTOR_H
#ifdef __cplusplus
extern "C" {
#endif
#include "secp256k1.h"
/** This module implements single signer ECDSA adaptor signatures following
* "One-Time Verifiably Encrypted Signatures A.K.A. Adaptor Signatures" by
* Lloyd Fournier
* (https://lists.linuxfoundation.org/pipermail/lightning-dev/2019-November/002316.html
* and https://github.com/LLFourn/one-time-VES/blob/master/main.pdf).
*
* WARNING! DANGER AHEAD!
* As mentioned in Lloyd Fournier's paper, the adaptor signature leaks the
* Elliptic-curve DiffieHellman (ECDH) key between the signing key and the
* encryption key. This is not a problem for ECDSA adaptor signatures
* themselves, but may result in a complete loss of security when they are
* composed with other schemes. More specifically, let us refer to the
* signer's public key as X = x*G, and to the encryption key as Y = y*G.
* Given X, Y and the adaptor signature, it is trivial to compute Y^x = X^y.
*
* A defense is to not reuse the signing key of ECDSA adaptor signatures in
* protocols that rely on the hardness of the CDH problem, e.g., Diffie-Hellman
* key exchange and ElGamal encryption. In general, it is a well-established
* cryptographic practice to seperate keys for different purposes whenever
* possible.
*/
/** A pointer to a function to deterministically generate a nonce.
*
* Same as secp256k1_nonce_function_hardened with the exception of using the
* compressed 33-byte encoding for the pubkey argument.
*
* Returns: 1 if a nonce was successfully generated. 0 will cause signing to
* return an error.
* Out: nonce32: pointer to a 32-byte array to be filled by the function
* In: msg32: the 32-byte message hash being verified
* key32: pointer to a 32-byte secret key
* pk33: the 33-byte serialized pubkey corresponding to key32
* algo: pointer to an array describing the signature algorithm
* algolen: the length of the algo array
* data: arbitrary data pointer that is passed through
*
* Except for test cases, this function should compute some cryptographic hash of
* the message, the key, the pubkey, the algorithm description, and data.
*/
typedef int (*secp256k1_nonce_function_hardened_ecdsa_adaptor)(
unsigned char *nonce32,
const unsigned char *msg32,
const unsigned char *key32,
const unsigned char *pk33,
const unsigned char *algo,
size_t algolen,
void *data
);
/** A modified BIP-340 nonce generation function. If a data pointer is passed, it is
* assumed to be a pointer to 32 bytes of auxiliary random data as defined in BIP-340.
* The hash will be tagged with algo after removing all terminating null bytes.
*/
SECP256K1_API const secp256k1_nonce_function_hardened_ecdsa_adaptor secp256k1_nonce_function_ecdsa_adaptor;
/** Encrypted Signing
*
* Creates an adaptor signature, which includes a proof to verify the adaptor
* signature.
* WARNING: Make sure you have read and understood the WARNING at the top of
* this file and applied the suggested countermeasures.
*
* Returns: 1 on success, 0 on failure
* Args: ctx: pointer to a context object (not secp256k1_context_static)
* Out: adaptor_sig162: pointer to 162 byte to store the returned signature
* In: seckey32: pointer to 32 byte secret key that will be used for
* signing
* enckey: pointer to the encryption public key
* msg32: pointer to the 32-byte message hash to sign
* noncefp: pointer to a nonce generation function. If NULL,
* secp256k1_nonce_function_ecdsa_adaptor is used
* ndata: pointer to arbitrary data used by the nonce generation
* function (can be NULL). If it is non-NULL and
* secp256k1_nonce_function_ecdsa_adaptor is used, then
* ndata must be a pointer to 32-byte auxiliary randomness
* as per BIP-340.
*/
SECP256K1_API int secp256k1_ecdsa_adaptor_encrypt(
const secp256k1_context *ctx,
unsigned char *adaptor_sig162,
unsigned char *seckey32,
const secp256k1_pubkey *enckey,
const unsigned char *msg32,
secp256k1_nonce_function_hardened_ecdsa_adaptor noncefp,
void *ndata
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
/** Encryption Verification
*
* Verifies that the adaptor decryption key can be extracted from the adaptor signature
* and the completed ECDSA signature.
*
* Returns: 1 on success, 0 on failure
* Args: ctx: pointer to a context object
* In: adaptor_sig162: pointer to 162-byte signature to verify
* pubkey: pointer to the public key corresponding to the secret key
* used for signing
* msg32: pointer to the 32-byte message hash being verified
* enckey: pointer to the adaptor encryption public key
*/
SECP256K1_API int secp256k1_ecdsa_adaptor_verify(
const secp256k1_context *ctx,
const unsigned char *adaptor_sig162,
const secp256k1_pubkey *pubkey,
const unsigned char *msg32,
const secp256k1_pubkey *enckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
/** Signature Decryption
*
* Derives an ECDSA signature from an adaptor signature and an adaptor decryption key.
*
* Returns: 1 on success, 0 on failure
* Args: ctx: pointer to a context object
* Out: sig: pointer to the ECDSA signature to create
* In: deckey32: pointer to 32-byte decryption secret key for the adaptor
* encryption public key
* adaptor_sig162: pointer to 162-byte adaptor sig
*/
SECP256K1_API int secp256k1_ecdsa_adaptor_decrypt(
const secp256k1_context *ctx,
secp256k1_ecdsa_signature *sig,
const unsigned char *deckey32,
const unsigned char *adaptor_sig162
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Decryption Key Recovery
*
* Extracts the adaptor decryption key from the complete signature and the adaptor
* signature.
*
* Returns: 1 on success, 0 on failure
* Args: ctx: pointer to a context object (not secp256k1_context_static)
* Out: deckey32: pointer to 32-byte adaptor decryption key for the adaptor
* encryption public key
* In: sig: pointer to ECDSA signature to recover the adaptor decryption
* key from
* adaptor_sig162: pointer to adaptor signature to recover the adaptor
* decryption key from
* enckey: pointer to the adaptor encryption public key
*/
SECP256K1_API int secp256k1_ecdsa_adaptor_recover(
const secp256k1_context *ctx,
unsigned char *deckey32,
const secp256k1_ecdsa_signature *sig,
const unsigned char *adaptor_sig162,
const secp256k1_pubkey *enckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
#ifdef __cplusplus
}
#endif
#endif /* SECP256K1_ECDSA_ADAPTOR_H */

View File

@@ -0,0 +1,234 @@
#ifndef SECP256K1_ECDSA_S2C_H
#define SECP256K1_ECDSA_S2C_H
#include "secp256k1.h"
/** This module implements the sign-to-contract scheme for ECDSA signatures, as
* well as the "ECDSA Anti-Exfil Protocol" that is based on sign-to-contract
* and is specified further down. The sign-to-contract scheme allows creating a
* signature that also commits to some data. This works by offsetting the public
* nonce point of the signature R by hash(R, data)*G where G is the secp256k1
* group generator.
*/
#ifdef __cplusplus
extern "C" {
#endif
/** Data structure that holds a sign-to-contract ("s2c") opening information.
* Sign-to-contract allows a signer to commit to some data as part of a signature. It
* can be used as an Out-argument in certain signing functions.
*
* The exact representation of data inside is implementation defined and not
* guaranteed to be portable between different platforms or versions. It is
* however guaranteed to be 64 bytes in size, and can be safely copied/moved.
* If you need to convert to a format suitable for storage, transmission, or
* comparison, use secp256k1_ecdsa_s2c_opening_serialize and secp256k1_ecdsa_s2c_opening_parse.
*/
typedef struct {
unsigned char data[64];
} secp256k1_ecdsa_s2c_opening;
/** Parse a sign-to-contract opening.
*
* Returns: 1 if the opening could be parsed
* 0 if the opening could not be parsed
* Args: ctx: pointer to a context object
* Out: opening: pointer to an opening object. If 1 is returned, it is set to a
* parsed version of input. If not, its value is unspecified.
* In: input33: pointer to 33-byte array with a serialized opening
*
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_s2c_opening_parse(
const secp256k1_context *ctx,
secp256k1_ecdsa_s2c_opening *opening,
const unsigned char *input33
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Serialize a sign-to-contract opening into a byte sequence.
*
* Returns: 1 if the opening was successfully serialized.
* 0 if the opening could not be serialized
* Args: ctx: pointer to a context object
* Out: output33: pointer to a 33-byte array to place the serialized opening in
* In: opening: pointer to an initialized `secp256k1_ecdsa_s2c_opening`
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_s2c_opening_serialize(
const secp256k1_context *ctx,
unsigned char *output33,
const secp256k1_ecdsa_s2c_opening *opening
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Same as secp256k1_ecdsa_sign, but s2c_data32 is committed to inside the nonce
*
* Returns: 1: signature created
* 0: the nonce generation function failed, or the private key was invalid.
* Args: ctx: pointer to a context object (not secp256k1_context_static)
* Out: sig: pointer to an array where the signature will be placed (cannot be NULL)
* s2c_opening: if non-NULL, pointer to an secp256k1_ecdsa_s2c_opening structure to populate
* In: msg32: the 32-byte message hash being signed (cannot be NULL)
* seckey: pointer to a 32-byte secret key (cannot be NULL)
* s2c_data32: pointer to a 32-byte data to commit to in the nonce (cannot be NULL)
*/
SECP256K1_API int secp256k1_ecdsa_s2c_sign(
const secp256k1_context *ctx,
secp256k1_ecdsa_signature *sig,
secp256k1_ecdsa_s2c_opening *s2c_opening,
const unsigned char *msg32,
const unsigned char *seckey,
const unsigned char *s2c_data32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6);
/** Verify a sign-to-contract commitment.
*
* Returns: 1: the signature contains a commitment to data32 (though it does
* not necessarily need to be a valid siganture!)
* 0: incorrect opening
* Args: ctx: pointer to a context object
* In: sig: the signature containing the sign-to-contract commitment (cannot be NULL)
* data32: the 32-byte data that was committed to (cannot be NULL)
* opening: pointer to the opening created during signing (cannot be NULL)
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_s2c_verify_commit(
const secp256k1_context *ctx,
const secp256k1_ecdsa_signature *sig,
const unsigned char *data32,
const secp256k1_ecdsa_s2c_opening *opening
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** ECDSA Anti-Exfil Protocol
*
* The ecdsa_anti_exfil_* functions can be used to prevent a signing device from
* exfiltrating the secret signing keys through biased signature nonces. The general
* idea is that a host provides additional randomness to the signing device client
* and the client commits to the randomness in the nonce using sign-to-contract.
*
* The following scheme is described by Stepan Snigirev here:
* https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-February/017655.html
* and by Pieter Wuille (as "Scheme 6") here:
* https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-March/017667.html
*
* In order to ensure the host cannot trick the signing device into revealing its
* keys, or the signing device to bias the nonce despite the host's contributions,
* the host and client must engage in a commit-reveal protocol as follows:
* 1. The host draws randomness `rho` and computes a sha256 commitment to it using
* `secp256k1_ecdsa_anti_exfil_host_commit`. It sends this to the signing device.
* 2. The signing device computes a public nonce `R` using the host's commitment
* as auxiliary randomness, using `secp256k1_ecdsa_anti_exfil_signer_commit`.
* The signing device sends the resulting `R` to the host as a s2c_opening.
*
* If, at any point from this step onward, the hardware device fails, it is
* okay to restart the protocol using **exactly the same `rho`** and checking
* that the hardware device proposes **exactly the same** `R`. Otherwise, the
* hardware device may be selectively aborting and thereby biasing the set of
* nonces that are used in actual signatures.
*
* It takes many (>100) such aborts before there is a plausible attack, given
* current knowledge in 2020. However such aborts accumulate even across a total
* replacement of all relevant devices (but not across replacement of the actual
* signing keys with new independently random ones).
*
* In case the hardware device cannot be made to sign with the given `rho`, `R`
* pair, wallet authors should alert the user and present a very scary message
* implying that if this happens more than even a few times, say 20 or more times
* EVER, they should change hardware vendors and perhaps sweep their coins.
*
* 3. The host replies with `rho` generated in step 1.
* 4. The device signs with `secp256k1_anti_exfil_sign`, using `rho` as `host_data32`,
* and sends the signature to the host.
* 5. The host verifies that the signature's public nonce matches the opening from
* step 2 and its original randomness `rho`, using `secp256k1_anti_exfil_host_verify`.
*
* Rationale:
* - The reason for having a host commitment is to allow the signing device to
* deterministically derive a unique nonce even if the host restarts the protocol
* using the same message and keys. Otherwise the signer might reuse the original
* nonce in two iterations of the protocol with different `rho`, which leaks the
* the secret key.
* - The signer does not need to check that the host commitment matches the host's
* claimed `rho`. Instead it re-derives the commitment (and its original `R`) from
* the provided `rho`. If this differs from the original commitment, the result
* will be an invalid `s2c_opening`, but since `R` was unique there is no risk to
* the signer's secret keys. Because of this, the signing device does not need to
* maintain any state about the progress of the protocol.
*/
/** Create the initial host commitment to `rho`. Part of the ECDSA Anti-Exfil Protocol.
*
* Returns 1 on success, 0 on failure.
* Args: ctx: pointer to a context object (cannot be NULL)
* Out: rand_commitment32: pointer to 32-byte array to store the returned commitment (cannot be NULL)
* In: rand32: the 32-byte randomness to commit to (cannot be NULL). It must come from
* a cryptographically secure RNG. As per the protocol, this value must not
* be revealed to the client until after the host has received the client
* commitment.
*/
SECP256K1_API int secp256k1_ecdsa_anti_exfil_host_commit(
const secp256k1_context *ctx,
unsigned char *rand_commitment32,
const unsigned char *rand32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Compute signer's original nonce. Part of the ECDSA Anti-Exfil Protocol.
*
* Returns 1 on success, 0 on failure.
* Args: ctx: pointer to a context object (not secp256k1_context_static)
* Out: s2c_opening: pointer to an s2c_opening where the signer's public nonce will be
* placed. (cannot be NULL)
* In: msg32: the 32-byte message hash to be signed (cannot be NULL)
* seckey32: the 32-byte secret key used for signing (cannot be NULL)
* rand_commitment32: the 32-byte randomness commitment from the host (cannot be NULL)
*/
SECP256K1_API int secp256k1_ecdsa_anti_exfil_signer_commit(
const secp256k1_context *ctx,
secp256k1_ecdsa_s2c_opening *s2c_opening,
const unsigned char *msg32,
const unsigned char *seckey32,
const unsigned char *rand_commitment32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
/** Same as secp256k1_ecdsa_sign, but commits to host randomness in the nonce. Part of the
* ECDSA Anti-Exfil Protocol.
*
* Returns: 1: signature created
* 0: the nonce generation function failed, or the private key was invalid.
* Args: ctx: pointer to a context object (not secp256k1_context_static)
* Out: sig: pointer to an array where the signature will be placed (cannot be NULL)
* In: msg32: the 32-byte message hash being signed (cannot be NULL)
* seckey: pointer to a 32-byte secret key (cannot be NULL)
* host_data32: pointer to 32-byte host-provided randomness (cannot be NULL)
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_anti_exfil_sign(
const secp256k1_context *ctx,
secp256k1_ecdsa_signature *sig,
const unsigned char *msg32,
const unsigned char *seckey,
const unsigned char *host_data32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
/** Verify a signature was correctly constructed using the ECDSA Anti-Exfil Protocol.
*
* Returns: 1: the signature is valid and contains a commitment to host_data32
* 0: incorrect opening
* Args: ctx: pointer to a context object
* In: sig: the signature produced by the signer (cannot be NULL)
* msghash32: the 32-byte message hash being verified (cannot be NULL)
* pubkey: pointer to the signer's public key (cannot be NULL)
* host_data32: the 32-byte data provided by the host (cannot be NULL)
* opening: the s2c opening provided by the signer (cannot be NULL)
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_anti_exfil_host_verify(
const secp256k1_context *ctx,
const secp256k1_ecdsa_signature *sig,
const unsigned char *msg32,
const secp256k1_pubkey *pubkey,
const unsigned char *host_data32,
const secp256k1_ecdsa_s2c_opening *opening
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6);
#ifdef __cplusplus
}
#endif
#endif /* SECP256K1_ECDSA_S2C_H */

View File

@@ -0,0 +1,200 @@
#ifndef SECP256K1_ELLSWIFT_H
#define SECP256K1_ELLSWIFT_H
#include "secp256k1.h"
#ifdef __cplusplus
extern "C" {
#endif
/* This module provides an implementation of ElligatorSwift as well as a
* version of x-only ECDH using it (including compatibility with BIP324).
*
* ElligatorSwift is described in https://eprint.iacr.org/2022/759 by
* Chavez-Saab, Rodriguez-Henriquez, and Tibouchi. It permits encoding
* uniformly chosen public keys as 64-byte arrays which are indistinguishable
* from uniformly random arrays.
*
* Let f be the function from pairs of field elements to point X coordinates,
* defined as follows (all operations modulo p = 2^256 - 2^32 - 977)
* f(u,t):
* - Let C = 0xa2d2ba93507f1df233770c2a797962cc61f6d15da14ecd47d8d27ae1cd5f852,
* a square root of -3.
* - If u=0, set u=1 instead.
* - If t=0, set t=1 instead.
* - If u^3 + t^2 + 7 = 0, multiply t by 2.
* - Let X = (u^3 + 7 - t^2) / (2 * t)
* - Let Y = (X + t) / (C * u)
* - Return the first in [u + 4 * Y^2, (-X/Y - u) / 2, (X/Y - u) / 2] that is an
* X coordinate on the curve (at least one of them is, for any u and t).
*
* Then an ElligatorSwift encoding of x consists of the 32-byte big-endian
* encodings of field elements u and t concatenated, where f(u,t) = x.
* The encoding algorithm is described in the paper, and effectively picks a
* uniformly random pair (u,t) among those which encode x.
*
* If the Y coordinate is relevant, it is given the same parity as t.
*
* Changes w.r.t. the the paper:
* - The u=0, t=0, and u^3+t^2+7=0 conditions result in decoding to the point
* at infinity in the paper. Here they are remapped to finite points.
* - The paper uses an additional encoding bit for the parity of y. Here the
* parity of t is used (negating t does not affect the decoded x coordinate,
* so this is possible).
*
* For mathematical background about the scheme, see the doc/ellswift.md file.
*/
/** A pointer to a function used by secp256k1_ellswift_xdh to hash the shared X
* coordinate along with the encoded public keys to a uniform shared secret.
*
* Returns: 1 if a shared secret was successfully computed.
* 0 will cause secp256k1_ellswift_xdh to fail and return 0.
* Other return values are not allowed, and the behaviour of
* secp256k1_ellswift_xdh is undefined for other return values.
* Out: output: pointer to an array to be filled by the function
* In: x32: pointer to the 32-byte serialized X coordinate
* of the resulting shared point (will not be NULL)
* ell_a64: pointer to the 64-byte encoded public key of party A
* (will not be NULL)
* ell_b64: pointer to the 64-byte encoded public key of party B
* (will not be NULL)
* data: arbitrary data pointer that is passed through
*/
typedef int (*secp256k1_ellswift_xdh_hash_function)(
unsigned char *output,
const unsigned char *x32,
const unsigned char *ell_a64,
const unsigned char *ell_b64,
void *data
);
/** An implementation of an secp256k1_ellswift_xdh_hash_function which uses
* SHA256(prefix64 || ell_a64 || ell_b64 || x32), where prefix64 is the 64-byte
* array pointed to by data. */
SECP256K1_API const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_prefix;
/** An implementation of an secp256k1_ellswift_xdh_hash_function compatible with
* BIP324. It returns H_tag(ell_a64 || ell_b64 || x32), where H_tag is the
* BIP340 tagged hash function with tag "bip324_ellswift_xonly_ecdh". Equivalent
* to secp256k1_ellswift_xdh_hash_function_prefix with prefix64 set to
* SHA256("bip324_ellswift_xonly_ecdh")||SHA256("bip324_ellswift_xonly_ecdh").
* The data argument is ignored. */
SECP256K1_API const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_bip324;
/** Construct a 64-byte ElligatorSwift encoding of a given pubkey.
*
* Returns: 1 always.
* Args: ctx: pointer to a context object
* Out: ell64: pointer to a 64-byte array to be filled
* In: pubkey: pointer to a secp256k1_pubkey containing an
* initialized public key
* rnd32: pointer to 32 bytes of randomness
*
* It is recommended that rnd32 consists of 32 uniformly random bytes, not
* known to any adversary trying to detect whether public keys are being
* encoded, though 16 bytes of randomness (padded to an array of 32 bytes,
* e.g., with zeros) suffice to make the result indistinguishable from
* uniform. The randomness in rnd32 must not be a deterministic function of
* the pubkey (it can be derived from the private key, though).
*
* It is not guaranteed that the computed encoding is stable across versions
* of the library, even if all arguments to this function (including rnd32)
* are the same.
*
* This function runs in variable time.
*/
SECP256K1_API int secp256k1_ellswift_encode(
const secp256k1_context *ctx,
unsigned char *ell64,
const secp256k1_pubkey *pubkey,
const unsigned char *rnd32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Decode a 64-bytes ElligatorSwift encoded public key.
*
* Returns: always 1
* Args: ctx: pointer to a context object
* Out: pubkey: pointer to a secp256k1_pubkey that will be filled
* In: ell64: pointer to a 64-byte array to decode
*
* This function runs in variable time.
*/
SECP256K1_API int secp256k1_ellswift_decode(
const secp256k1_context *ctx,
secp256k1_pubkey *pubkey,
const unsigned char *ell64
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Compute an ElligatorSwift public key for a secret key.
*
* Returns: 1: secret was valid, public key was stored.
* 0: secret was invalid, try again.
* Args: ctx: pointer to a context object
* Out: ell64: pointer to a 64-byte array to receive the ElligatorSwift
* public key
* In: seckey32: pointer to a 32-byte secret key
* auxrnd32: (optional) pointer to 32 bytes of randomness
*
* Constant time in seckey and auxrnd32, but not in the resulting public key.
*
* It is recommended that auxrnd32 contains 32 uniformly random bytes, though
* it is optional (and does result in encodings that are indistinguishable from
* uniform even without any auxrnd32). It differs from the (mandatory) rnd32
* argument to secp256k1_ellswift_encode in this regard.
*
* This function can be used instead of calling secp256k1_ec_pubkey_create
* followed by secp256k1_ellswift_encode. It is safer, as it uses the secret
* key as entropy for the encoding (supplemented with auxrnd32, if provided).
*
* Like secp256k1_ellswift_encode, this function does not guarantee that the
* computed encoding is stable across versions of the library, even if all
* arguments (including auxrnd32) are the same.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ellswift_create(
const secp256k1_context *ctx,
unsigned char *ell64,
const unsigned char *seckey32,
const unsigned char *auxrnd32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Given a private key, and ElligatorSwift public keys sent in both directions,
* compute a shared secret using x-only Elliptic Curve Diffie-Hellman (ECDH).
*
* Returns: 1: shared secret was successfully computed
* 0: secret was invalid or hashfp returned 0
* Args: ctx: pointer to a context object.
* Out: output: pointer to an array to be filled by hashfp.
* In: ell_a64: pointer to the 64-byte encoded public key of party A
* (will not be NULL)
* ell_b64: pointer to the 64-byte encoded public key of party B
* (will not be NULL)
* seckey32: pointer to our 32-byte secret key
* party: boolean indicating which party we are: zero if we are
* party A, non-zero if we are party B. seckey32 must be
* the private key corresponding to that party's ell_?64.
* This correspondence is not checked.
* hashfp: pointer to a hash function.
* data: arbitrary data pointer passed through to hashfp.
*
* Constant time in seckey32.
*
* This function is more efficient than decoding the public keys, and performing
* ECDH on them.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ellswift_xdh(
const secp256k1_context *ctx,
unsigned char *output,
const unsigned char *ell_a64,
const unsigned char *ell_b64,
const unsigned char *seckey32,
int party,
secp256k1_ellswift_xdh_hash_function hashfp,
void *data
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(7);
#ifdef __cplusplus
}
#endif
#endif /* SECP256K1_ELLSWIFT_H */

View File

@@ -15,9 +15,9 @@ extern "C" {
* The exact representation of data inside is implementation defined and not
* guaranteed to be portable between different platforms or versions. It is
* however guaranteed to be 64 bytes in size, and can be safely copied/moved.
* If you need to convert to a format suitable for storage, transmission, or
* comparison, use secp256k1_xonly_pubkey_serialize and
* secp256k1_xonly_pubkey_parse.
* If you need to convert to a format suitable for storage, transmission, use
* use secp256k1_xonly_pubkey_serialize and secp256k1_xonly_pubkey_parse. To
* compare keys, use secp256k1_xonly_pubkey_cmp.
*/
typedef struct {
unsigned char data[64];
@@ -39,15 +39,14 @@ typedef struct {
* Returns: 1 if the public key was fully valid.
* 0 if the public key could not be parsed or is invalid.
*
* Args: ctx: a secp256k1 context object (cannot be NULL).
* Args: ctx: pointer to a context object.
* Out: pubkey: pointer to a pubkey object. If 1 is returned, it is set to a
* parsed version of input. If not, it's set to an invalid value.
* (cannot be NULL).
* In: input32: pointer to a serialized xonly_pubkey (cannot be NULL)
* In: input32: pointer to a serialized xonly_pubkey.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_parse(
const secp256k1_context* ctx,
secp256k1_xonly_pubkey* pubkey,
const secp256k1_context *ctx,
secp256k1_xonly_pubkey *pubkey,
const unsigned char *input32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
@@ -55,33 +54,44 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_parse(
*
* Returns: 1 always.
*
* Args: ctx: a secp256k1 context object (cannot be NULL).
* Out: output32: a pointer to a 32-byte array to place the serialized key in
* (cannot be NULL).
* In: pubkey: a pointer to a secp256k1_xonly_pubkey containing an
* initialized public key (cannot be NULL).
* Args: ctx: pointer to a context object.
* Out: output32: pointer to a 32-byte array to place the serialized key in.
* In: pubkey: pointer to a secp256k1_xonly_pubkey containing an initialized public key.
*/
SECP256K1_API int secp256k1_xonly_pubkey_serialize(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
unsigned char *output32,
const secp256k1_xonly_pubkey* pubkey
const secp256k1_xonly_pubkey *pubkey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Compare two x-only public keys using lexicographic order
*
* Returns: <0 if the first public key is less than the second
* >0 if the first public key is greater than the second
* 0 if the two public keys are equal
* Args: ctx: pointer to a context object.
* In: pubkey1: first public key to compare
* pubkey2: second public key to compare
*/
SECP256K1_API int secp256k1_xonly_pubkey_cmp(
const secp256k1_context *ctx,
const secp256k1_xonly_pubkey *pk1,
const secp256k1_xonly_pubkey *pk2
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Converts a secp256k1_pubkey into a secp256k1_xonly_pubkey.
*
* Returns: 1 if the public key was successfully converted
* 0 otherwise
* Returns: 1 always.
*
* Args: ctx: pointer to a context object (cannot be NULL)
* Out: xonly_pubkey: pointer to an x-only public key object for placing the
* converted public key (cannot be NULL)
* pk_parity: pointer to an integer that will be set to 1 if the point
* encoded by xonly_pubkey is the negation of the pubkey and
* set to 0 otherwise. (can be NULL)
* In: pubkey: pointer to a public key that is converted (cannot be NULL)
* Args: ctx: pointer to a context object.
* Out: xonly_pubkey: pointer to an x-only public key object for placing the converted public key.
* pk_parity: Ignored if NULL. Otherwise, pointer to an integer that
* will be set to 1 if the point encoded by xonly_pubkey is
* the negation of the pubkey and set to 0 otherwise.
* In: pubkey: pointer to a public key that is converted.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_from_pubkey(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
secp256k1_xonly_pubkey *xonly_pubkey,
int *pk_parity,
const secp256k1_pubkey *pubkey
@@ -98,21 +108,17 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_from_pubke
* invalid (only when the tweak is the negation of the corresponding
* secret key). 1 otherwise.
*
* Args: ctx: pointer to a context object initialized for verification
* (cannot be NULL)
* Args: ctx: pointer to a context object.
* Out: output_pubkey: pointer to a public key to store the result. Will be set
* to an invalid value if this function returns 0 (cannot
* be NULL)
* to an invalid value if this function returns 0.
* In: internal_pubkey: pointer to an x-only pubkey to apply the tweak to.
* (cannot be NULL).
* tweak32: pointer to a 32-byte tweak. If the tweak is invalid
* according to secp256k1_ec_seckey_verify, this function
* returns 0. For uniformly random 32-byte arrays the
* chance of being invalid is negligible (around 1 in
* 2^128) (cannot be NULL).
* tweak32: pointer to a 32-byte tweak, which must be valid
* according to secp256k1_ec_seckey_verify or 32 zero
* bytes. For uniformly random 32-byte tweaks, the chance of
* being invalid is negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
secp256k1_pubkey *output_pubkey,
const secp256k1_xonly_pubkey *internal_pubkey,
const unsigned char *tweak32
@@ -131,20 +137,18 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add(
*
* Returns: 0 if the arguments are invalid or the tweaked pubkey is not the
* result of tweaking the internal_pubkey with tweak32. 1 otherwise.
* Args: ctx: pointer to a context object initialized for verification
* (cannot be NULL)
* In: tweaked_pubkey32: pointer to a serialized xonly_pubkey (cannot be NULL)
* Args: ctx: pointer to a context object.
* In: tweaked_pubkey32: pointer to a serialized xonly_pubkey.
* tweaked_pk_parity: the parity of the tweaked pubkey (whose serialization
* is passed in as tweaked_pubkey32). This must match the
* pk_parity value that is returned when calling
* secp256k1_xonly_pubkey with the tweaked pubkey, or
* this function will fail.
* internal_pubkey: pointer to an x-only public key object to apply the
* tweak to (cannot be NULL)
* tweak32: pointer to a 32-byte tweak (cannot be NULL)
* internal_pubkey: pointer to an x-only public key object to apply the tweak to.
* tweak32: pointer to a 32-byte tweak.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add_check(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
const unsigned char *tweaked_pubkey32,
int tweaked_pk_parity,
const secp256k1_xonly_pubkey *internal_pubkey,
@@ -155,27 +159,38 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add_
*
* Returns: 1: secret was valid, keypair is ready to use
* 0: secret was invalid, try again with a different secret
* Args: ctx: pointer to a context object, initialized for signing (cannot be NULL)
* Out: keypair: pointer to the created keypair (cannot be NULL)
* In: seckey: pointer to a 32-byte secret key (cannot be NULL)
* Args: ctx: pointer to a context object (not secp256k1_context_static).
* Out: keypair: pointer to the created keypair.
* In: seckey: pointer to a 32-byte secret key.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_create(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
secp256k1_keypair *keypair,
const unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Get the secret key from a keypair.
*
* Returns: 1 always.
* Args: ctx: pointer to a context object.
* Out: seckey: pointer to a 32-byte buffer for the secret key.
* In: keypair: pointer to a keypair.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_sec(
const secp256k1_context *ctx,
unsigned char *seckey,
const secp256k1_keypair *keypair
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Get the public key from a keypair.
*
* Returns: 0 if the arguments are invalid. 1 otherwise.
* Args: ctx: pointer to a context object (cannot be NULL)
* Out: pubkey: pointer to a pubkey object. If 1 is returned, it is set to
* the keypair public key. If not, it's set to an invalid value.
* (cannot be NULL)
* In: keypair: pointer to a keypair (cannot be NULL)
* Returns: 1 always.
* Args: ctx: pointer to a context object.
* Out: pubkey: pointer to a pubkey object, set to the keypair public key.
* In: keypair: pointer to a keypair.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_pub(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
secp256k1_pubkey *pubkey,
const secp256k1_keypair *keypair
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
@@ -185,18 +200,16 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_pub(
* This is the same as calling secp256k1_keypair_pub and then
* secp256k1_xonly_pubkey_from_pubkey.
*
* Returns: 0 if the arguments are invalid. 1 otherwise.
* Args: ctx: pointer to a context object (cannot be NULL)
* Out: pubkey: pointer to an xonly_pubkey object. If 1 is returned, it is set
* to the keypair public key after converting it to an
* xonly_pubkey. If not, it's set to an invalid value (cannot be
* NULL).
* pk_parity: pointer to an integer that will be set to the pk_parity
* argument of secp256k1_xonly_pubkey_from_pubkey (can be NULL).
* In: keypair: pointer to a keypair (cannot be NULL)
* Returns: 1 always.
* Args: ctx: pointer to a context object.
* Out: pubkey: pointer to an xonly_pubkey object, set to the keypair
* public key after converting it to an xonly_pubkey.
* pk_parity: Ignored if NULL. Otherwise, pointer to an integer that will be set to the
* pk_parity argument of secp256k1_xonly_pubkey_from_pubkey.
* In: keypair: pointer to a keypair.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_pub(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
secp256k1_xonly_pubkey *pubkey,
int *pk_parity,
const secp256k1_keypair *keypair
@@ -213,22 +226,35 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_pub(
* invalid (only when the tweak is the negation of the keypair's
* secret key). 1 otherwise.
*
* Args: ctx: pointer to a context object initialized for verification
* (cannot be NULL)
* Args: ctx: pointer to a context object.
* In/Out: keypair: pointer to a keypair to apply the tweak to. Will be set to
* an invalid value if this function returns 0 (cannot be
* NULL).
* In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according
* to secp256k1_ec_seckey_verify, this function returns 0. For
* uniformly random 32-byte arrays the chance of being invalid
* is negligible (around 1 in 2^128) (cannot be NULL).
* an invalid value if this function returns 0.
* In: tweak32: pointer to a 32-byte tweak, which must be valid according to
* secp256k1_ec_seckey_verify or 32 zero bytes. For uniformly
* random 32-byte tweaks, the chance of being invalid is
* negligible (around 1 in 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_tweak_add(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
secp256k1_keypair *keypair,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Sort public keys using lexicographic order of their compressed
* serialization.
*
* Returns: 0 if the arguments are invalid. 1 otherwise.
*
* Args: ctx: pointer to a context object
* In: pubkeys: array of pointers to pubkeys to sort
* n_pubkeys: number of elements in the pubkeys array
*/
SECP256K1_API int secp256k1_pubkey_sort(
const secp256k1_context *ctx,
const secp256k1_pubkey **pubkeys,
size_t n_pubkeys
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
#ifdef __cplusplus
}
#endif

695
include/secp256k1_frost.h Normal file
View File

@@ -0,0 +1,695 @@
#ifndef SECP256K1_FROST_H
#define SECP256K1_FROST_H
#include "secp256k1_extrakeys.h"
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/** This code is currently a work in progress. It's not secure nor stable.
* IT IS EXTREMELY DANGEROUS AND RECKLESS TO USE THIS MODULE IN PRODUCTION!
*
* This module implements a variant of Flexible Round-Optimized Schnorr
* Threshold Signatures (FROST) by Chelsea Komlo and Ian Goldberg
* (https://crysp.uwaterloo.ca/software/frost/). Signatures are compatible with
* BIP-340 ("Schnorr"). There's an example C source file in the module's
* directory (examples/frost.c) that demonstrates how it can be used.
*
* The module also supports BIP-341 ("Taproot") and BIP-32 ("ordinary") public
* key tweaking, and adaptor signatures.
*
* It is recommended to read the documentation in this include file carefully.
* Further notes on API usage can be found in src/modules/frost/frost.md
*
* Following the convention used in the MuSig module, the API uses the singular
* term "nonce" to refer to the two "nonces" used by the FROST scheme.
*/
/** Opaque data structures
*
* The exact representation of data inside is implementation defined and not
* guaranteed to be portable between different platforms or versions. If you
* need to convert to a format suitable for storage, transmission, or
* comparison, use the corresponding serialization and parsing functions.
*/
/** Opaque data structure that caches information about key tweaking.
*
* Guaranteed to be 101 bytes in size. It can be safely copied/moved. No
* serialization and parsing functions.
*/
typedef struct {
unsigned char data[101];
} secp256k1_frost_tweak_cache;
/** Opaque data structure that holds a signer's _secret_ share.
*
* Guaranteed to be 36 bytes in size. Serialized and parsed with
* `frost_share_serialize` and `frost_share_parse`.
*/
typedef struct {
unsigned char data[36];
} secp256k1_frost_share;
/** Opaque data structure that holds a signer's _secret_ nonce.
*
* Guaranteed to be 68 bytes in size.
*
* WARNING: This structure MUST NOT be copied or read or written to directly.
* A signer who is online throughout the whole process and can keep this
* structure in memory can use the provided API functions for a safe standard
* workflow. See
* https://blockstream.com/2019/02/18/musig-a-new-multisignature-standard/ for
* more details about the risks associated with serializing or deserializing
* this structure.
*
* We repeat, copying this data structure can result in nonce reuse which will
* leak the secret signing key.
*/
typedef struct {
unsigned char data[68];
} secp256k1_frost_secnonce;
/** Opaque data structure that holds a signer's public nonce.
*
* Guaranteed to be 132 bytes in size. It can be safely copied/moved.
* Serialized and parsed with `frost_pubnonce_serialize` and
* `frost_pubnonce_parse`.
*/
typedef struct {
unsigned char data[132];
} secp256k1_frost_pubnonce;
/** Opaque data structure that holds a FROST session.
*
* This structure is not required to be kept secret for the signing protocol
* to be secure. Guaranteed to be 133 bytes in size. It can be safely
* copied/moved. No serialization and parsing functions.
*/
typedef struct {
unsigned char data[133];
} secp256k1_frost_session;
/** Opaque data structure that holds a partial FROST signature.
*
* Guaranteed to be 36 bytes in size. Serialized and parsed with
* `frost_partial_sig_serialize` and `frost_partial_sig_parse`.
*/
typedef struct {
unsigned char data[36];
} secp256k1_frost_partial_sig;
/** Parse a signer's public nonce.
*
* Returns: 1 when the nonce could be parsed, 0 otherwise.
* Args: ctx: pointer to a context object
* Out: nonce: pointer to a nonce object
* In: in66: pointer to the 66-byte nonce to be parsed
*/
SECP256K1_API int secp256k1_frost_pubnonce_parse(
const secp256k1_context *ctx,
secp256k1_frost_pubnonce *nonce,
const unsigned char *in66
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Serialize a signer's public nonce
*
* Returns: 1 when the nonce could be serialized, 0 otherwise
* Args: ctx: pointer to a context object
* Out: out66: pointer to a 66-byte array to store the serialized nonce
* In: nonce: pointer to the nonce
*/
SECP256K1_API int secp256k1_frost_pubnonce_serialize(
const secp256k1_context *ctx,
unsigned char *out66,
const secp256k1_frost_pubnonce *nonce
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Serialize a FROST partial signature
*
* Returns: 1 when the signature could be serialized, 0 otherwise
* Args: ctx: pointer to a context object
* Out: out32: pointer to a 32-byte array to store the serialized signature
* In: sig: pointer to the signature
*/
SECP256K1_API int secp256k1_frost_partial_sig_serialize(
const secp256k1_context *ctx,
unsigned char *out32,
const secp256k1_frost_partial_sig *sig
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Parse a FROST partial signature.
*
* Returns: 1 when the signature could be parsed, 0 otherwise.
* Args: ctx: pointer to a context object
* Out: sig: pointer to a signature object
* In: in32: pointer to the 32-byte signature to be parsed
*
* After the call, sig will always be initialized. If parsing failed or the
* encoded numbers are out of range, signature verification with it is
* guaranteed to fail for every message and public key.
*/
SECP256K1_API int secp256k1_frost_partial_sig_parse(
const secp256k1_context *ctx,
secp256k1_frost_partial_sig *sig,
const unsigned char *in32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Serialize a FROST share
*
* Returns: 1 when the share could be serialized, 0 otherwise
* Args: ctx: pointer to a context object
* Out: out32: pointer to a 32-byte array to store the serialized share
* In: share: pointer to the share
*/
SECP256K1_API int secp256k1_frost_share_serialize(
const secp256k1_context *ctx,
unsigned char *out32,
const secp256k1_frost_share *share
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Parse a FROST share.
*
* Returns: 1 when the share could be parsed, 0 otherwise.
* Args: ctx: pointer to a context object
* Out: share: pointer to a share object
* In: in32: pointer to the 32-byte share to be parsed
*/
SECP256K1_API int secp256k1_frost_share_parse(
const secp256k1_context *ctx,
secp256k1_frost_share *share,
const unsigned char *in32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Creates key shares
*
* To generate a key, each participant generates a share for each other
* participant. For example, in the case of 2 particpants, Alice and Bob, they
* each generate 2 shares, distribute 1 share to each other using a secure
* channel, and keep 1 for themselves.
*
* Each participant must transmit shares over secure channels to each other
* participant.
*
* Each call to this function must have a UNIQUE and uniformly RANDOM seed32
* that must that must NOT BE REUSED in subsequent calls to this function and
* must be KEPT SECRET (even from other participants).
*
* Returns: 0 if the arguments are invalid, 1 otherwise
* Args: ctx: pointer to a context object
* Out: shares: pointer to the key shares
* vss_commitment: pointer to the VSS commitment
* pok64: pointer to the proof of knowledge
* In: seed32: 32-byte random seed as explained above. Must be
* unique to this call to secp256k1_frost_shares_gen
* and must be uniformly random.
* threshold: the minimum number of signers required to produce a
* signature
* n_participants: the total number of participants
* ids33: array of 33-byte participant IDs
*/
SECP256K1_API int secp256k1_frost_shares_gen(
const secp256k1_context *ctx,
secp256k1_frost_share *shares,
secp256k1_pubkey *vss_commitment,
unsigned char *pok64,
const unsigned char *seed32,
size_t threshold,
size_t n_participants,
const unsigned char * const* ids33
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(8);
/** Aggregates shares
*
* As part of the key generation protocol, each participant receives a share
* from each participant, including a share they "receive" from themselves.
* This function verifies those shares against their VSS commitments,
* aggregates the shares, and then aggregates the commitments to each
* participant's first polynomial coefficient to derive the aggregate public
* key.
*
* If this function returns an error, `secp256k1_frost_share_verify` can be
* called on each share to determine which participants submitted faulty
* shares.
*
* Returns: 0 if the arguments are invalid, 1 otherwise (which does NOT mean
* the resulting signature verifies).
* Args: ctx: pointer to a context object
* Out: agg_share: the aggregated share
* agg_pk: the aggregated x-only public key
* In: shares: all key generation shares for the partcipant's index
* vss_commitments: coefficient commitments of all participants ordered by
* the x-only pubkeys of the participants
* n_shares: the total number of shares
* threshold: the minimum number of shares required to produce a
* signature
* id33: the 33-byte ID of the participant whose shares are being
* aggregated
*/
SECP256K1_API int secp256k1_frost_share_agg(
const secp256k1_context *ctx,
secp256k1_frost_share *agg_share,
secp256k1_xonly_pubkey *agg_pk,
const secp256k1_frost_share * const *shares,
const secp256k1_pubkey * const *vss_commitments,
size_t n_shares,
size_t threshold,
const unsigned char *id33
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(8);
/** Verifies a share received during a key generation session
*
* The signature is verified against the VSS commitment received with the
* share. This is only useful for purposes of determining which share(s) are
* invalid if share_agg returns an error.
*
* Returns: 0 if the arguments are invalid or the share does not verify, 1
* otherwise
* Args ctx: pointer to a context object
* In: threshold: the minimum number of signers required to produce a
* signature
* id33: the 33-byte participant ID of the share recipient
* share: pointer to a key generation share
* vss_commitment: the VSS commitment associated with the share
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_share_verify(
const secp256k1_context *ctx,
size_t threshold,
const unsigned char *id33,
const secp256k1_frost_share *share,
const secp256k1_pubkey * const *vss_commitment
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
/** Computes a public verification share used for verifying partial signatures
*
* Returns: 0 if the arguments are invalid, 1 otherwise
* Args: ctx: pointer to a context object
* Out: pubshare: pointer to a struct to store the public verification
* share
* In: threshold: the minimum number of signers required to produce a
* signature
* id33: the 33-byte participant ID of the participant whose
* partial signature will be verified with the pubshare
* vss_commitments: coefficient commitments of all participants
* n_participants: the total number of participants
*/
SECP256K1_API int secp256k1_frost_compute_pubshare(
const secp256k1_context *ctx,
secp256k1_pubkey *pubshare,
size_t threshold,
const unsigned char *id33,
const secp256k1_pubkey * const *vss_commitments,
size_t n_participants
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
/** Obtain the aggregate public key from a FROST x-only aggregate public key.
*
* This is only useful if you need the non-xonly public key, in particular for
* ordinary (non-xonly) tweaking or batch-verifying multiple key aggregations
* (not implemented).
*
* Returns: 0 if the arguments are invalid, 1 otherwise
* Args: ctx: pointer to a context object
* Out: ec_agg_pk: the FROST-aggregated public key.
* In: xonly_agg_pk: the aggregated x-only public key that is the output of
* `secp256k1_frost_share_agg`
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_pubkey_get(
const secp256k1_context *ctx,
secp256k1_pubkey *ec_agg_pk,
const secp256k1_xonly_pubkey *xonly_agg_pk
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Initializes a tweak cache used for applying tweaks to a FROST key
*
* Returns: 0 if the arguments are invalid, 1 otherwise
* Args: ctx: pointer to a context object
* Out: tweak_cache: pointer to a frost_tweak_cache struct that is required
* for key tweaking
* In: agg_pk: the aggregated x-only public key that is the output of
* `secp256k1_frost_share_agg`
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_pubkey_tweak(
const secp256k1_context *ctx,
secp256k1_frost_tweak_cache *tweak_cache,
const secp256k1_xonly_pubkey *agg_pk
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Apply ordinary "EC" tweaking to a public key in a given tweak_cache by
* adding the generator multiplied with `tweak32` to it. This is useful for
* deriving child keys from an aggregate public key via BIP32.
*
* The tweaking method is the same as `secp256k1_ec_pubkey_tweak_add`. So after
* the following pseudocode buf and buf2 have identical contents (absent
* earlier failures).
*
* secp256k1_frost_share_agg(..., xonly_agg_pk, ...)
* secp256k1_frost_pubkey_tweak(..., tweak_cache, xonly_agg_pk)
* secp256k1_frost_pubkey_ec_tweak_add(..., output_pk, tweak_cache, tweak32)
* secp256k1_ec_pubkey_serialize(..., buf, output_pk)
* secp256k1_frost_pubkey_get(..., ec_agg_pk, xonly_agg_pk)
* secp256k1_ec_pubkey_tweak_add(..., ec_agg_pk, tweak32)
* secp256k1_ec_pubkey_serialize(..., buf2, ec_agg_pk)
*
* This function is required if you want to _sign_ for a tweaked aggregate key.
* On the other hand, if you are only computing a public key, but not intending
* to create a signature for it, you can just use
* `secp256k1_ec_pubkey_tweak_add`.
*
* Returns: 0 if the arguments are invalid or the resulting public key would be
* invalid (only when the tweak is the negation of the corresponding
* secret key). 1 otherwise.
* Args: ctx: pointer to a context object
* Out: output_pubkey: pointer to a public key to store the result. Will be set
* to an invalid value if this function returns 0. If you
* do not need it, this arg can be NULL.
* In/Out: tweak_cache: pointer to a `frost_tweak_cache` struct initialized by
* `frost_pubkey_tweak`
* In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid
* according to `secp256k1_ec_seckey_verify`, this function
* returns 0. For uniformly random 32-byte arrays the
* chance of being invalid is negligible (around 1 in
* 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_pubkey_ec_tweak_add(
const secp256k1_context *ctx,
secp256k1_pubkey *output_pubkey,
secp256k1_frost_tweak_cache *tweak_cache,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Apply x-only tweaking to a public key in a given tweak_cache by adding the
* generator multiplied with `tweak32` to it. This is useful for creating
* Taproot outputs.
*
* The tweaking method is the same as `secp256k1_xonly_pubkey_tweak_add`. So in
* the following pseudocode xonly_pubkey_tweak_add_check (absent earlier
* failures) returns 1.
*
* secp256k1_frost_share_agg(..., agg_pk, ...)
* secp256k1_frost_pubkey_tweak(..., tweak_cache, agg_pk)
* secp256k1_frost_pubkey_xonly_tweak_add(..., output_pk, tweak_cache, tweak32)
* secp256k1_xonly_pubkey_serialize(..., buf, output_pk)
* secp256k1_xonly_pubkey_tweak_add_check(..., buf, ..., agg_pk, tweak32)
*
* This function is required if you want to _sign_ for a tweaked aggregate key.
* On the other hand, if you are only computing a public key, but not intending
* to create a signature for it, you can just use
* `secp256k1_xonly_pubkey_tweak_add`.
*
* Returns: 0 if the arguments are invalid or the resulting public key would be
* invalid (only when the tweak is the negation of the corresponding
* secret key). 1 otherwise.
* Args: ctx: pointer to a context object
* Out: output_pubkey: pointer to a public key to store the result. Will be set
* to an invalid value if this function returns 0. If you
* do not need it, this arg can be NULL.
* In/Out: tweak_cache: pointer to a `frost_tweak_cache` struct initialized by
* `frost_pubkey_tweak`
* In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid
* according to secp256k1_ec_seckey_verify, this function
* returns 0. For uniformly random 32-byte arrays the
* chance of being invalid is negligible (around 1 in
* 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_pubkey_xonly_tweak_add(
const secp256k1_context *ctx,
secp256k1_pubkey *output_pubkey,
secp256k1_frost_tweak_cache *tweak_cache,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Starts a signing session by generating a nonce
*
* This function outputs a secret nonce that will be required for signing and a
* corresponding public nonce that is intended to be sent to other signers.
*
* FROST, like MuSig, differs from regular Schnorr signing in that
* implementers _must_ take special care to not reuse a nonce. This can be
* ensured by following these rules:
*
* 1. Each call to this function must have a UNIQUE session_id32 that must NOT BE
* REUSED in subsequent calls to this function.
* If you do not provide a seckey, session_id32 _must_ be UNIFORMLY RANDOM
* AND KEPT SECRET (even from other signers). If you do provide a seckey,
* session_id32 can instead be a counter (that must never repeat!). However,
* it is recommended to always choose session_id32 uniformly at random.
* 2. If you already know the seckey, message or aggregate public key, they
* can be optionally provided to derive the nonce and increase
* misuse-resistance. The extra_input32 argument can be used to provide
* additional data that does not repeat in normal scenarios, such as the
* current time.
* 3. Avoid copying (or serializing) the secnonce. This reduces the possibility
* that it is used more than once for signing.
*
* Remember that nonce reuse will leak the secret key!
* Note that using the same agg_share for multiple FROST sessions is fine.
*
* Returns: 0 if the arguments are invalid and 1 otherwise
* Args: ctx: pointer to a context object (not secp256k1_context_static)
* Out: secnonce: pointer to a structure to store the secret nonce
* pubnonce: pointer to a structure to store the public nonce
* In: session_id32: a 32-byte session_id32 as explained above. Must be
* unique to this call to secp256k1_frost_nonce_gen and
* must be uniformly random unless you really know what you
* are doing.
* agg_share: the aggregated share that will later be used for
* signing, if already known (can be NULL)
* msg32: the 32-byte message that will later be signed, if
* already known (can be NULL)
* agg_pk: the FROST-aggregated public key (can be NULL)
* extra_input32: an optional 32-byte array that is input to the nonce
* derivation function (can be NULL)
*/
SECP256K1_API int secp256k1_frost_nonce_gen(
const secp256k1_context *ctx,
secp256k1_frost_secnonce *secnonce,
secp256k1_frost_pubnonce *pubnonce,
const unsigned char *session_id32,
const secp256k1_frost_share *agg_share,
const unsigned char *msg32,
const secp256k1_xonly_pubkey *agg_pk,
const unsigned char *extra_input32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Takes the public nonces of all signers and computes a session that is
* required for signing and verification of partial signatures. The participant
* IDs can be sorted before combining, but the corresponding pubnonces must be
* resorted as well. All signers must use the same sorting of pubnonces,
* otherwise signing will fail.
*
* Returns: 0 if the arguments are invalid or if some signer sent invalid
* pubnonces, 1 otherwise
* Args: ctx: pointer to a context object
* Out: session: pointer to a struct to store the session
* In: pubnonces: array of pointers to public nonces sent by the signers
* n_pubnonces: number of elements in the pubnonces array. Must be
* greater than 0.
* msg32: the 32-byte message to sign
* agg_pk: the FROST-aggregated public key
* myd_id33: the 33-byte ID of the participant who will use the
* session for signing
* ids33: array of the 33-byte participant IDs of the signers
* tweak_cache: pointer to frost_tweak_cache struct (can be NULL)
* adaptor: optional pointer to an adaptor point encoded as a
* public key if this signing session is part of an
* adaptor signature protocol (can be NULL)
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_nonce_process(
const secp256k1_context *ctx,
secp256k1_frost_session *session,
const secp256k1_frost_pubnonce * const *pubnonces,
size_t n_pubnonces,
const unsigned char *msg32,
const secp256k1_xonly_pubkey *agg_pk,
const unsigned char *my_id33,
const unsigned char * const* ids33,
const secp256k1_frost_tweak_cache *tweak_cache,
const secp256k1_pubkey *adaptor
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(8);
/** Produces a partial signature
*
* This function overwrites the given secnonce with zeros and will abort if given a
* secnonce that is all zeros. This is a best effort attempt to protect against nonce
* reuse. However, this is of course easily defeated if the secnonce has been
* copied (or serialized). Remember that nonce reuse will leak the secret key!
*
* Returns: 0 if the arguments are invalid or the provided secnonce has already
* been used for signing, 1 otherwise
* Args: ctx: pointer to a context object
* Out: partial_sig: pointer to struct to store the partial signature
* In/Out: secnonce: pointer to the secnonce struct created in
* frost_nonce_gen that has been never used in a
* partial_sign call before
* In: agg_share: the aggregated share
* session: pointer to the session that was created with
* frost_nonce_process
* tweak_cache: pointer to frost_tweak_cache struct (can be NULL)
*/
SECP256K1_API int secp256k1_frost_partial_sign(
const secp256k1_context *ctx,
secp256k1_frost_partial_sig *partial_sig,
secp256k1_frost_secnonce *secnonce,
const secp256k1_frost_share *agg_share,
const secp256k1_frost_session *session,
const secp256k1_frost_tweak_cache *tweak_cache
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
/** Verifies an individual signer's partial signature
*
* The signature is verified for a specific signing session. In order to avoid
* accidentally verifying a signature from a different or non-existing signing
* session, you must ensure the following:
* 1. The `tweak_cache` argument is identical to the one used to create the
* `session` with `frost_nonce_process`.
* 2. The `pubshare` argument must be the output of
* `secp256k1_frost_compute_pubshare` for the signer's ID.
* 3. The `pubnonce` argument must be identical to the one sent by the
* signer and used to create the `session` with `frost_nonce_process`.
*
* This function can be used to assign blame for a failed signature.
*
* Returns: 0 if the arguments are invalid or the partial signature does not
* verify, 1 otherwise
* Args ctx: pointer to a context object
* In: partial_sig: pointer to partial signature to verify, sent by
* the signer associated with `pubnonce` and `pubkey`
* pubnonce: public nonce of the signer in the signing session
* pubshare: public verification share of the signer in the signing
* session that is the output of
* `secp256k1_frost_compute_pubshare`
* session: pointer to the session that was created with
* `frost_nonce_process`
* tweak_cache: pointer to frost_tweak_cache struct (can be NULL)
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_partial_sig_verify(
const secp256k1_context *ctx,
const secp256k1_frost_partial_sig *partial_sig,
const secp256k1_frost_pubnonce *pubnonce,
const secp256k1_pubkey *pubshare,
const secp256k1_frost_session *session,
const secp256k1_frost_tweak_cache *tweak_cache
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
/** Aggregates partial signatures
*
* Returns: 0 if the arguments are invalid, 1 otherwise (which does NOT mean
* the resulting signature verifies).
* Args: ctx: pointer to a context object
* Out: sig64: complete (but possibly invalid) Schnorr signature
* In: session: pointer to the session that was created with
* frost_nonce_process
* partial_sigs: array of pointers to partial signatures to aggregate
* n_sigs: number of elements in the partial_sigs array. Must be
* greater than 0.
*/
SECP256K1_API int secp256k1_frost_partial_sig_agg(
const secp256k1_context *ctx,
unsigned char *sig64,
const secp256k1_frost_session *session,
const secp256k1_frost_partial_sig * const *partial_sigs,
size_t n_sigs
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Extracts the nonce_parity bit from a session
*
* This is used for adaptor signatures.
*
* Returns: 0 if the arguments are invalid, 1 otherwise
* Args: ctx: pointer to a context object
* Out: nonce_parity: pointer to an integer that indicates the parity
* of the aggregate public nonce. Used for adaptor
* signatures.
* In: session: pointer to the session that was created with
* frost_nonce_process
*/
SECP256K1_API int secp256k1_frost_nonce_parity(
const secp256k1_context *ctx,
int *nonce_parity,
const secp256k1_frost_session *session
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Verifies that the adaptor can be extracted by combining the adaptor
* pre-signature and the completed signature.
*
* Returns: 0 if the arguments are invalid or the adaptor signature does not
* verify, 1 otherwise
* Args: ctx: pointer to a context object
* In: pre_sig64: 64-byte pre-signature
* msg32: the 32-byte message being verified
* pubkey: pointer to an x-only public key to verify with
* adaptor: pointer to the adaptor point being verified
* nonce_parity: the output of `frost_nonce_parity` called with the
* session used for producing the pre-signature
*/
SECP256K1_API int secp256k1_frost_verify_adaptor(
const secp256k1_context *ctx,
const unsigned char *pre_sig64,
const unsigned char *msg32,
const secp256k1_xonly_pubkey *pubkey,
const secp256k1_pubkey *adaptor,
int nonce_parity
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
/** Creates a signature from a pre-signature and an adaptor.
*
* If the sec_adaptor32 argument is incorrect, the output signature will be
* invalid. This function does not verify the signature.
*
* Returns: 0 if the arguments are invalid, or pre_sig64 or sec_adaptor32 contain
* invalid (overflowing) values. 1 otherwise (which does NOT mean the
* signature or the adaptor are valid!)
* Args: ctx: pointer to a context object
* Out: sig64: 64-byte signature. This pointer may point to the same
* memory area as `pre_sig`.
* In: pre_sig64: 64-byte pre-signature
* sec_adaptor32: 32-byte secret adaptor to add to the pre-signature
* nonce_parity: the output of `frost_nonce_parity` called with the
* session used for producing the pre-signature
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_adapt(
const secp256k1_context *ctx,
unsigned char *sig64,
const unsigned char *pre_sig64,
const unsigned char *sec_adaptor32,
int nonce_parity
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Extracts a secret adaptor from a FROST pre-signature and corresponding
* signature
*
* This function will not fail unless given grossly invalid data; if it is
* merely given signatures that do not verify, the returned value will be
* nonsense. It is therefore important that all data be verified at earlier
* steps of any protocol that uses this function. In particular, this includes
* verifying all partial signatures that were aggregated into pre_sig64.
*
* Returns: 0 if the arguments are NULL, or sig64 or pre_sig64 contain
* grossly invalid (overflowing) values. 1 otherwise (which does NOT
* mean the signatures or the adaptor are valid!)
* Args: ctx: pointer to a context object
* Out:sec_adaptor32: 32-byte secret adaptor
* In: sig64: complete, valid 64-byte signature
* pre_sig64: the pre-signature corresponding to sig64, i.e., the
* aggregate of partial signatures without the secret
* adaptor
* nonce_parity: the output of `frost_nonce_parity` called with the
* session used for producing sig64
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_extract_adaptor(
const secp256k1_context *ctx,
unsigned char *sec_adaptor32,
const unsigned char *sig64,
const unsigned char *pre_sig64,
int nonce_parity
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,5 +1,5 @@
#ifndef _SECP256K1_GENERATOR_
# define _SECP256K1_GENERATOR_
#ifndef SECP256K1_GENERATOR_H
# define SECP256K1_GENERATOR_H
# include "secp256k1.h"
@@ -21,39 +21,44 @@ typedef struct {
unsigned char data[64];
} secp256k1_generator;
/**
* Static constant generator 'h' maintained for historical reasons.
*/
SECP256K1_API const secp256k1_generator *secp256k1_generator_h;
/** Parse a 33-byte generator byte sequence into a generator object.
*
* Returns: 1 if input contains a valid generator.
* Args: ctx: a secp256k1 context object.
* Args: ctx: pointer to a context object
* Out: gen: pointer to the output generator object
* In: input: pointer to a 33-byte serialized generator
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_generator_parse(
const secp256k1_context* ctx,
secp256k1_generator* gen,
const secp256k1_context *ctx,
secp256k1_generator *gen,
const unsigned char *input
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Serialize a 33-byte generator into a serialized byte sequence.
*
* Returns: 1 always.
* Args: ctx: a secp256k1 context object.
* Out: output: a pointer to a 33-byte byte array
* In: gen: a pointer to a generator
* Args: ctx: pointer to a context object
* Out: output: pointer to a 33-byte byte array
* In: gen: pointer to a generator object
*/
SECP256K1_API int secp256k1_generator_serialize(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
unsigned char *output,
const secp256k1_generator* gen
const secp256k1_generator *gen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Generate a generator for the curve.
*
* Returns: 0 in the highly unlikely case the seed is not acceptable,
* 1 otherwise.
* Args: ctx: a secp256k1 context object
* Out: gen: a generator object
* In: seed32: a 32-byte seed
* Args: ctx: pointer to a context object
* Out: gen: pointer to a the new generator object
* In: seed32: 32-byte seed
*
* If successful a valid generator will be placed in gen. The produced
* generators are distributed uniformly over the curve, and will not have a
@@ -61,8 +66,8 @@ SECP256K1_API int secp256k1_generator_serialize(
* or to the base generator G.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_generator_generate(
const secp256k1_context* ctx,
secp256k1_generator* gen,
const secp256k1_context *ctx,
secp256k1_generator *gen,
const unsigned char *seed32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
@@ -70,22 +75,165 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_generator_generate(
*
* Returns: 0 in the highly unlikely case the seed is not acceptable or when
* blind is out of range. 1 otherwise.
* Args: ctx: a secp256k1 context object, initialized for signing
* Out: gen: a generator object
* In: seed32: a 32-byte seed
* blind32: a 32-byte secret value to blind the generator with.
* Args: ctx: pointer to a context object (not secp256k1_context_static)
* Out: gen: pointer to a generator object
* In: seed32: 32-byte seed
* blind32: 32-byte secret value to blind the generator with.
*
* The result is equivalent to first calling secp256k1_generator_generate,
* converting the result to a public key, calling secp256k1_ec_pubkey_tweak_add,
* and then converting back to generator form.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_generator_generate_blinded(
const secp256k1_context* ctx,
secp256k1_generator* gen,
const unsigned char *key32,
const secp256k1_context *ctx,
secp256k1_generator *gen,
const unsigned char *seed32,
const unsigned char *blind32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Opaque data structure that stores a Pedersen commitment
*
* The exact representation of data inside is implementation defined and not
* guaranteed to be portable between different platforms or versions. It is
* however guaranteed to be 64 bytes in size, and can be safely copied/moved.
* If you need to convert to a format suitable for storage, transmission, or
* comparison, use secp256k1_pedersen_commitment_serialize and
* secp256k1_pedersen_commitment_parse.
*/
typedef struct {
unsigned char data[64];
} secp256k1_pedersen_commitment;
/** Parse a 33-byte commitment into a commitment object.
*
* Returns: 1 if input contains a valid commitment.
* Args: ctx: pointer to a context object
* Out: commit: pointer to the output commitment object
* In: input: pointer to a 33-byte serialized commitment key
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_commitment_parse(
const secp256k1_context *ctx,
secp256k1_pedersen_commitment *commit,
const unsigned char *input
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Serialize a commitment object into a serialized byte sequence.
*
* Returns: 1 always.
* Args: ctx: pointer to a context object
* Out: output: pointer to a 33-byte byte array
* In: commit: pointer to a secp256k1_pedersen_commitment containing an
* initialized commitment
*/
SECP256K1_API int secp256k1_pedersen_commitment_serialize(
const secp256k1_context *ctx,
unsigned char *output,
const secp256k1_pedersen_commitment *commit
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Generate a pedersen commitment.
* Returns 1: Commitment successfully created.
* 0: Error. The blinding factor is larger than the group order
* (probability for random 32 byte number < 2^-127) or results in the
* point at infinity. Retry with a different factor.
* In: ctx: pointer to a context object (not secp256k1_context_static)
* blind: pointer to a 32-byte blinding factor (cannot be NULL)
* value: unsigned 64-bit integer value to commit to.
* gen: additional generator 'h'
* Out: commit: pointer to the commitment (cannot be NULL)
*
* Blinding factors can be generated and verified in the same way as secp256k1 private keys for ECDSA.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_commit(
const secp256k1_context *ctx,
secp256k1_pedersen_commitment *commit,
const unsigned char *blind,
uint64_t value,
const secp256k1_generator *gen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
/** Computes the sum of multiple positive and negative blinding factors.
* Returns 1: Sum successfully computed.
* 0: Error. A blinding factor is larger than the group order
* (probability for random 32 byte number < 2^-127). Retry with
* different factors.
* In: ctx: pointer to a context object (cannot be NULL)
* blinds: pointer to pointers to 32-byte character arrays for blinding factors. (cannot be NULL)
* n: number of factors pointed to by blinds.
* npositive: how many of the initial factors should be treated with a positive sign.
* Out: blind_out: pointer to a 32-byte array for the sum (cannot be NULL)
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_blind_sum(
const secp256k1_context *ctx,
unsigned char *blind_out,
const unsigned char * const *blinds,
size_t n,
size_t npositive
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Verify a tally of pedersen commitments
* Returns 1: commitments successfully sum to zero.
* 0: Commitments do not sum to zero or other error.
* In: ctx: pointer to a context object (cannot be NULL)
* commits: pointer to array of pointers to the commitments. (cannot be NULL if pcnt is non-zero)
* pcnt: number of commitments pointed to by commits.
* ncommits: pointer to array of pointers to the negative commitments. (cannot be NULL if ncnt is non-zero)
* ncnt: number of commitments pointed to by ncommits.
*
* This computes sum(commit[0..pcnt)) - sum(ncommit[0..ncnt)) == 0.
*
* A pedersen commitment is xG + vA where G and A are generators for the secp256k1 group and x is a blinding factor,
* while v is the committed value. For a collection of commitments to sum to zero, for each distinct generator
* A all blinding factors and all values must sum to zero.
*
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_verify_tally(
const secp256k1_context *ctx,
const secp256k1_pedersen_commitment * const *commits,
size_t pcnt,
const secp256k1_pedersen_commitment * const *ncommits,
size_t ncnt
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
/** Sets the final Pedersen blinding factor correctly when the generators themselves
* have blinding factors.
*
* Consider a generator of the form A' = A + rG, where A is the "real" generator
* but A' is the generator provided to verifiers. Then a Pedersen commitment
* P = vA' + r'G really has the form vA + (vr + r')G. To get all these (vr + r')
* to sum to zero for multiple commitments, we take three arrays consisting of
* the `v`s, `r`s, and `r'`s, respectively called `value`s, `generator_blind`s
* and `blinding_factor`s, and sum them.
*
* The function then subtracts the sum of all (vr + r') from the last element
* of the `blinding_factor` array, setting the total sum to zero.
*
* Returns 1: Blinding factor successfully computed.
* 0: Error. A blinding_factor or generator_blind are larger than the group
* order (probability for random 32 byte number < 2^-127). Retry with
* different values.
*
* In: ctx: pointer to a context object
* value: array of asset values, `v` in the above paragraph.
* May not be NULL unless `n_total` is 0.
* generator_blind: array of asset blinding factors, `r` in the above paragraph
* May not be NULL unless `n_total` is 0.
* n_total: Total size of the above arrays
* n_inputs: How many of the initial array elements represent commitments that
* will be negated in the final sum
* In/Out: blinding_factor: array of commitment blinding factors, `r'` in the above paragraph
* May not be NULL unless `n_total` is 0.
* the last value will be modified to get the total sum to zero.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_blind_generator_blind_sum(
const secp256k1_context *ctx,
const uint64_t *value,
const unsigned char * const *generator_blind,
unsigned char * const *blinding_factor,
size_t n_total,
size_t n_inputs
);
# ifdef __cplusplus
}
# endif

View File

@@ -7,363 +7,168 @@
extern "C" {
#endif
#include <stdint.h>
#include <stddef.h>
/** This module implements a Schnorr-based multi-signature scheme called MuSig
* (https://eprint.iacr.org/2018/068.pdf). It is compatible with bip-schnorr.
* There's an example C source file in the module's directory
* (src/modules/musig/example.c) that demonstrates how it can be used.
/** This module implements BIP 327 "MuSig2 for BIP340-compatible
* Multi-Signatures"
* (https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki)
* v1.0.0. You can find an example demonstrating the musig module in
* examples/musig.c.
*
* The documentation in this include file is for reference and may not be sufficient
* for users to begin using the library. A full description of API usage can be found
* in src/modules/musig/musig.md
* The module also supports BIP-341 ("Taproot") public key tweaking and adaptor
* signatures as described in
* https://github.com/ElementsProject/scriptless-scripts/pull/24.
*
* It is recommended to read the documentation in this include file carefully.
* Further notes on API usage can be found in src/modules/musig/musig.md
*
* Since the first version of MuSig is essentially replaced by MuSig2, we use
* MuSig, musig and MuSig2 synonymously unless noted otherwise.
*/
/** Data structure containing auxiliary data generated in `pubkey_combine` and
* required for `session_*_init`.
* Fields:
* magic: Set during initialization in `pubkey_combine` to allow
* detecting an uninitialized object.
* pk_hash: The 32-byte hash of the original public keys
* pk_parity: Whether the MuSig-aggregated point was negated when
* converting it to the combined xonly pubkey.
* is_tweaked: Whether the combined pubkey was tweaked
* tweak: If is_tweaked, array with the 32-byte tweak
* internal_key_parity: If is_tweaked, the parity of the combined pubkey
* before tweaking
*/
typedef struct {
uint64_t magic;
unsigned char pk_hash[32];
int pk_parity;
int is_tweaked;
unsigned char tweak[32];
int internal_key_parity;
} secp256k1_musig_pre_session;
/** Data structure containing data related to a signing session resulting in a single
* signature.
*
* This structure is not opaque, but it MUST NOT be copied or read or written to it
* directly. A signer who is online throughout the whole process and can keep this
* structure in memory can use the provided API functions for a safe standard
* workflow. See https://blockstream.com/2019/02/18/musig-a-new-multisignature-standard/
* for more details about the risks associated with serializing or deserializing this
* structure.
*
* Fields:
* magic: Set in `musig_session_init` to allow detecting an
* uninitialized object.
* round: Current round of the session
* pre_session: Auxiliary data created in `pubkey_combine`
* combined_pk: MuSig-computed combined xonly public key
* n_signers: Number of signers
* msg: The 32-byte message (hash) to be signed
* is_msg_set: Whether the above message has been set
* has_secret_data: Whether this session object has a signers' secret data; if this
* is `false`, it may still be used for verification purposes.
* seckey: If `has_secret_data`, the signer's secret key
* secnonce: If `has_secret_data`, the signer's secret nonce
* nonce: If `has_secret_data`, the signer's public nonce
* nonce_commitments_hash: If `has_secret_data` and round >= 1, the hash of all
* signers' commitments
* combined_nonce: If round >= 2, the summed combined public nonce
* combined_nonce_parity: If round >= 2, the parity of the Y coordinate of above
* nonce.
*/
typedef struct {
uint64_t magic;
int round;
secp256k1_musig_pre_session pre_session;
secp256k1_xonly_pubkey combined_pk;
uint32_t n_signers;
int is_msg_set;
unsigned char msg[32];
int has_secret_data;
unsigned char seckey[32];
unsigned char secnonce[32];
secp256k1_xonly_pubkey nonce;
int partial_nonce_parity;
unsigned char nonce_commitments_hash[32];
secp256k1_xonly_pubkey combined_nonce;
int combined_nonce_parity;
} secp256k1_musig_session;
/** Data structure containing data on all signers in a single session.
*
* The workflow for this structure is as follows:
*
* 1. This structure is initialized with `musig_session_init` or
* `musig_session_init_verifier`, which set the `index` field, and zero out
* all other fields. The public session is initialized with the signers'
* nonce_commitments.
*
* 2. In a non-public session the nonce_commitments are set with the function
* `musig_get_public_nonce`, which also returns the signer's public nonce. This
* ensures that the public nonce is not exposed until all commitments have been
* received.
*
* 3. Each individual data struct should be updated with `musig_set_nonce` once a
* nonce is available. This function takes a single signer data struct rather than
* an array because it may fail in the case that the provided nonce does not match
* the commitment. In this case, it is desirable to identify the exact party whose
* nonce was inconsistent.
*
* Fields:
* present: indicates whether the signer's nonce is set
* index: index of the signer in the MuSig key aggregation
* nonce: public nonce, must be a valid curvepoint if the signer is `present`
* nonce_commitment: commitment to the nonce, or all-bits zero if a commitment
* has not yet been set
*/
typedef struct {
int present;
uint32_t index;
secp256k1_xonly_pubkey nonce;
unsigned char nonce_commitment[32];
} secp256k1_musig_session_signer_data;
/** Opaque data structure that holds a MuSig partial signature.
/** Opaque data structures
*
* The exact representation of data inside is implementation defined and not
* guaranteed to be portable between different platforms or versions. It is however
* guaranteed to be 32 bytes in size, and can be safely copied/moved. If you need
* to convert to a format suitable for storage, transmission, or comparison, use the
* `musig_partial_signature_serialize` and `musig_partial_signature_parse`
* functions.
* guaranteed to be portable between different platforms or versions. If you
* need to convert to a format suitable for storage, transmission, or
* comparison, use the corresponding serialization and parsing functions.
*/
/** Opaque data structure that caches information about public key aggregation.
*
* Guaranteed to be 197 bytes in size. It can be safely copied/moved. No
* serialization and parsing functions (yet).
*/
typedef struct {
unsigned char data[32];
} secp256k1_musig_partial_signature;
unsigned char data[197];
} secp256k1_musig_keyagg_cache;
/** Computes a combined public key and the hash of the given public keys.
* Different orders of `pubkeys` result in different `combined_pk`s.
/** Opaque data structure that holds a signer's _secret_ nonce.
*
* Returns: 1 if the public keys were successfully combined, 0 otherwise
* Args: ctx: pointer to a context object initialized for verification
* (cannot be NULL)
* scratch: scratch space used to compute the combined pubkey by
* multiexponentiation. If NULL, an inefficient algorithm is used.
* Out: combined_pk: the MuSig-combined xonly public key (cannot be NULL)
* pre_session: if non-NULL, pointer to a musig_pre_session struct to be used in
* `musig_session_init` or `musig_pubkey_tweak_add`.
* In: pubkeys: input array of public keys to combine. The order is important;
* a different order will result in a different combined public
* key (cannot be NULL)
* n_pubkeys: length of pubkeys array. Must be greater than 0.
* Guaranteed to be 132 bytes in size.
*
* WARNING: This structure MUST NOT be copied or read or written to directly. A
* signer who is online throughout the whole process and can keep this
* structure in memory can use the provided API functions for a safe standard
* workflow. See
* https://blockstream.com/2019/02/18/musig-a-new-multisignature-standard/ for
* more details about the risks associated with serializing or deserializing
* this structure.
*
* We repeat, copying this data structure can result in nonce reuse which will
* leak the secret signing key.
*/
SECP256K1_API int secp256k1_musig_pubkey_combine(
const secp256k1_context* ctx,
secp256k1_scratch_space *scratch,
secp256k1_xonly_pubkey *combined_pk,
secp256k1_musig_pre_session *pre_session,
const secp256k1_xonly_pubkey *pubkeys,
size_t n_pubkeys
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
typedef struct {
unsigned char data[132];
} secp256k1_musig_secnonce;
/** Tweak an x-only public key by adding the generator multiplied with tweak32
* to it. The resulting output_pubkey with the given internal_pubkey and tweak
* passes `secp256k1_xonly_pubkey_tweak_test`.
*
* This function is only useful before initializing a signing session. If you
* are only computing a public key, but not intending to create a signature for
* it, you can just use `secp256k1_xonly_pubkey_tweak_add`. Can only be called
* once with a given pre_session.
*
* Returns: 0 if the arguments are invalid or the resulting public key would be
* invalid (only when the tweak is the negation of the corresponding
* secret key). 1 otherwise.
* Args: ctx: pointer to a context object initialized for verification
* (cannot be NULL)
* pre_session: pointer to a `musig_pre_session` struct initialized in
* `musig_pubkey_combine` (cannot be NULL)
* Out: output_pubkey: pointer to a public key to store the result. Will be set
* to an invalid value if this function returns 0 (cannot
* be NULL)
* In: internal_pubkey: pointer to the `combined_pk` from
* `musig_pubkey_combine` to which the tweak is applied.
* (cannot be NULL).
* tweak32: pointer to a 32-byte tweak. If the tweak is invalid
* according to secp256k1_ec_seckey_verify, this function
* returns 0. For uniformly random 32-byte arrays the
* chance of being invalid is negligible (around 1 in
* 2^128) (cannot be NULL).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubkey_tweak_add(
const secp256k1_context* ctx,
secp256k1_musig_pre_session *pre_session,
secp256k1_pubkey *output_pubkey,
const secp256k1_xonly_pubkey *internal_pubkey,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
/** Opaque data structure that holds a signer's public nonce.
*
* Guaranteed to be 132 bytes in size. It can be safely copied/moved. Serialized
* and parsed with `musig_pubnonce_serialize` and `musig_pubnonce_parse`.
*/
typedef struct {
unsigned char data[132];
} secp256k1_musig_pubnonce;
/** Initializes a signing session for a signer
/** Opaque data structure that holds an aggregate public nonce.
*
* Returns: 1: session is successfully initialized
* 0: session could not be initialized: secret key or secret nonce overflow
* Args: ctx: pointer to a context object, initialized for signing (cannot
* be NULL)
* Out: session: the session structure to initialize (cannot be NULL)
* signers: an array of signers' data to be initialized. Array length must
* equal to `n_signers` (cannot be NULL)
* nonce_commitment32: filled with a 32-byte commitment to the generated nonce
* (cannot be NULL)
* In: session_id32: a *unique* 32-byte ID to assign to this session (cannot be
* NULL). If a non-unique session_id32 was given then a partial
* signature will LEAK THE SECRET KEY.
* msg32: the 32-byte message to be signed. Shouldn't be NULL unless you
* require sharing nonce commitments before the message is known
* because it reduces nonce misuse resistance. If NULL, must be
* set with `musig_session_get_public_nonce`.
* combined_pk: the combined xonly public key of all signers (cannot be NULL)
* pre_session: pointer to a musig_pre_session struct after initializing
* it with `musig_pubkey_combine` and optionally provided to
* `musig_pubkey_tweak_add` (cannot be NULL).
* n_signers: length of signers array. Number of signers participating in
* the MuSig. Must be greater than 0 and at most 2^32 - 1.
* my_index: index of this signer in the signers array. Must be less
* than `n_signers`.
* seckey: the signer's 32-byte secret key (cannot be NULL)
* Guaranteed to be 132 bytes in size. It can be safely copied/moved.
* Serialized and parsed with `musig_aggnonce_serialize` and
* `musig_aggnonce_parse`.
*/
SECP256K1_API int secp256k1_musig_session_init(
const secp256k1_context* ctx,
secp256k1_musig_session *session,
secp256k1_musig_session_signer_data *signers,
unsigned char *nonce_commitment32,
const unsigned char *session_id32,
const unsigned char *msg32,
const secp256k1_xonly_pubkey *combined_pk,
const secp256k1_musig_pre_session *pre_session,
size_t n_signers,
size_t my_index,
const unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(8) SECP256K1_ARG_NONNULL(11);
typedef struct {
unsigned char data[132];
} secp256k1_musig_aggnonce;
/** Gets the signer's public nonce given a list of all signers' data with
* commitments. Called by participating signers after
* `secp256k1_musig_session_init` and after all nonce commitments have
* been collected
/** Opaque data structure that holds a MuSig session.
*
* Returns: 1: public nonce is written in nonce
* 0: signer data is missing commitments or session isn't initialized
* for signing
* Args: ctx: pointer to a context object (cannot be NULL)
* session: the signing session to get the nonce from (cannot be NULL)
* signers: an array of signers' data initialized with
* `musig_session_init`. Array length must equal to
* `n_commitments` (cannot be NULL)
* Out: nonce32: filled with a 32-byte public nonce which is supposed to be
* sent to the other signers and then used in `musig_set nonce`
* (cannot be NULL)
* In: commitments: array of pointers to 32-byte nonce commitments (cannot be NULL)
* n_commitments: the length of commitments and signers array. Must be the total
* number of signers participating in the MuSig.
* msg32: the 32-byte message to be signed. Must be NULL if already
* set with `musig_session_init` otherwise can not be NULL.
* This structure is not required to be kept secret for the signing protocol to
* be secure. Guaranteed to be 133 bytes in size. It can be safely
* copied/moved. No serialization and parsing functions (yet).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_session_get_public_nonce(
const secp256k1_context* ctx,
secp256k1_musig_session *session,
secp256k1_musig_session_signer_data *signers,
unsigned char *nonce32,
const unsigned char *const *commitments,
size_t n_commitments,
const unsigned char *msg32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
typedef struct {
unsigned char data[133];
} secp256k1_musig_session;
/** Initializes a verifier session that can be used for verifying nonce commitments
* and partial signatures. It does not have secret key material and therefore can not
* be used to create signatures.
/** Opaque data structure that holds a partial MuSig signature.
*
* Returns: 1 when session is successfully initialized, 0 otherwise
* Args: ctx: pointer to a context object (cannot be NULL)
* Out: session: the session structure to initialize (cannot be NULL)
* signers: an array of signers' data to be initialized. Array length must
* equal to `n_signers`(cannot be NULL)
* In: msg32: the 32-byte message to be signed (cannot be NULL)
* combined_pk: the combined xonly public key of all signers (cannot be NULL)
* pre_session: pointer to a musig_pre_session struct from
* `musig_pubkey_combine` (cannot be NULL)
* pk_hash32: the 32-byte hash of the signers' individual keys (cannot be NULL)
* commitments: array of pointers to 32-byte nonce commitments. Array
* length must equal to `n_signers` (cannot be NULL)
* n_signers: length of signers and commitments array. Number of signers
* participating in the MuSig. Must be greater than 0 and at most
* 2^32 - 1.
* Guaranteed to be 36 bytes in size. Serialized and parsed with
* `musig_partial_sig_serialize` and `musig_partial_sig_parse`.
*/
SECP256K1_API int secp256k1_musig_session_init_verifier(
const secp256k1_context* ctx,
secp256k1_musig_session *session,
secp256k1_musig_session_signer_data *signers,
const unsigned char *msg32,
const secp256k1_xonly_pubkey *combined_pk,
const secp256k1_musig_pre_session *pre_session,
const unsigned char *const *commitments,
size_t n_signers
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7);
typedef struct {
unsigned char data[36];
} secp256k1_musig_partial_sig;
/** Checks a signer's public nonce against a commitment to said nonce, and update
* data structure if they match
/** Parse a signer's public nonce.
*
* Returns: 1: commitment was valid, data structure updated
* 0: commitment was invalid, nothing happened
* Args: ctx: pointer to a context object (cannot be NULL)
* signer: pointer to the signer data to update (cannot be NULL). Must have
* been used with `musig_session_get_public_nonce` or initialized
* with `musig_session_init_verifier`.
* In: nonce32: signer's alleged public nonce (cannot be NULL)
* Returns: 1 when the nonce could be parsed, 0 otherwise.
* Args: ctx: pointer to a context object
* Out: nonce: pointer to a nonce object
* In: in66: pointer to the 66-byte nonce to be parsed
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_set_nonce(
const secp256k1_context* ctx,
secp256k1_musig_session_signer_data *signer,
const unsigned char *nonce32
SECP256K1_API int secp256k1_musig_pubnonce_parse(
const secp256k1_context *ctx,
secp256k1_musig_pubnonce *nonce,
const unsigned char *in66
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Updates a session with the combined public nonce of all signers. The combined
* public nonce is the sum of every signer's public nonce.
/** Serialize a signer's public nonce
*
* Returns: 1: nonces are successfully combined
* 0: a signer's nonce is missing
* Args: ctx: pointer to a context object (cannot be NULL)
* session: session to update with the combined public nonce (cannot be
* NULL)
* signers: an array of signers' data, which must have had public nonces
* set with `musig_set_nonce`. Array length must equal to `n_signers`
* (cannot be NULL)
* n_signers: the length of the signers array. Must be the total number of
* signers participating in the MuSig.
* Out: nonce_parity: if non-NULL, a pointer to an integer that indicates the
* parity of the combined public nonce. Used for adaptor
* signatures.
* adaptor: point to add to the combined public nonce. If NULL, nothing is
* added to the combined nonce.
* Returns: 1 when the nonce could be serialized, 0 otherwise
* Args: ctx: pointer to a context object
* Out: out66: pointer to a 66-byte array to store the serialized nonce
* In: nonce: pointer to the nonce
*/
SECP256K1_API int secp256k1_musig_session_combine_nonces(
const secp256k1_context* ctx,
secp256k1_musig_session *session,
const secp256k1_musig_session_signer_data *signers,
size_t n_signers,
int *nonce_parity,
const secp256k1_pubkey *adaptor
SECP256K1_API int secp256k1_musig_pubnonce_serialize(
const secp256k1_context *ctx,
unsigned char *out66,
const secp256k1_musig_pubnonce *nonce
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Serialize a MuSig partial signature or adaptor signature
/** Parse an aggregate public nonce.
*
* Returns: 1 when the nonce could be parsed, 0 otherwise.
* Args: ctx: pointer to a context object
* Out: nonce: pointer to a nonce object
* In: in66: pointer to the 66-byte nonce to be parsed
*/
SECP256K1_API int secp256k1_musig_aggnonce_parse(
const secp256k1_context *ctx,
secp256k1_musig_aggnonce *nonce,
const unsigned char *in66
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Serialize an aggregate public nonce
*
* Returns: 1 when the nonce could be serialized, 0 otherwise
* Args: ctx: pointer to a context object
* Out: out66: pointer to a 66-byte array to store the serialized nonce
* In: nonce: pointer to the nonce
*/
SECP256K1_API int secp256k1_musig_aggnonce_serialize(
const secp256k1_context *ctx,
unsigned char *out66,
const secp256k1_musig_aggnonce *nonce
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Serialize a MuSig partial signature
*
* Returns: 1 when the signature could be serialized, 0 otherwise
* Args: ctx: a secp256k1 context object
* Args: ctx: pointer to a context object
* Out: out32: pointer to a 32-byte array to store the serialized signature
* In: sig: pointer to the signature
*/
SECP256K1_API int secp256k1_musig_partial_signature_serialize(
const secp256k1_context* ctx,
SECP256K1_API int secp256k1_musig_partial_sig_serialize(
const secp256k1_context *ctx,
unsigned char *out32,
const secp256k1_musig_partial_signature* sig
const secp256k1_musig_partial_sig *sig
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Parse and verify a MuSig partial signature.
/** Parse a MuSig partial signature.
*
* Returns: 1 when the signature could be parsed, 0 otherwise.
* Args: ctx: a secp256k1 context object
* Args: ctx: pointer to a context object
* Out: sig: pointer to a signature object
* In: in32: pointer to the 32-byte signature to be parsed
*
@@ -371,113 +176,429 @@ SECP256K1_API int secp256k1_musig_partial_signature_serialize(
* encoded numbers are out of range, signature verification with it is
* guaranteed to fail for every message and public key.
*/
SECP256K1_API int secp256k1_musig_partial_signature_parse(
const secp256k1_context* ctx,
secp256k1_musig_partial_signature* sig,
SECP256K1_API int secp256k1_musig_partial_sig_parse(
const secp256k1_context *ctx,
secp256k1_musig_partial_sig *sig,
const unsigned char *in32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Produces a partial signature
/** Computes an aggregate public key and uses it to initialize a keyagg_cache
*
* Returns: 1: partial signature constructed
* 0: session in incorrect or inconsistent state
* Args: ctx: pointer to a context object (cannot be NULL)
* session: active signing session for which the combined nonce has been
* computed (cannot be NULL)
* Out: partial_sig: partial signature (cannot be NULL)
* Different orders of `pubkeys` result in different `agg_pk`s.
*
* Before aggregating, the pubkeys can be sorted with `secp256k1_pubkey_sort`
* which ensures the same `agg_pk` result for the same multiset of pubkeys.
* This is useful to do before `pubkey_agg`, such that the order of pubkeys
* does not affect the aggregate public key.
*
* Returns: 0 if the arguments are invalid, 1 otherwise
* Args: ctx: pointer to a context object
* scratch: should be NULL because it is not yet implemented. If it
* was implemented then the scratch space would be used to
* compute the aggregate pubkey by multiexponentiation.
* Generally, the larger the scratch space, the faster this
* function. However, the returns of providing a larger
* scratch space are diminishing. If NULL, an inefficient
* algorithm is used.
* Out: agg_pk: the MuSig-aggregated x-only public key. If you do not need it,
* this arg can be NULL.
* keyagg_cache: if non-NULL, pointer to a musig_keyagg_cache struct that
* is required for signing (or observing the signing session
* and verifying partial signatures).
* In: pubkeys: input array of pointers to public keys to aggregate. The order
* is important; a different order will result in a different
* aggregate public key.
* n_pubkeys: length of pubkeys array. Must be greater than 0.
*/
SECP256K1_API int secp256k1_musig_partial_sign(
const secp256k1_context* ctx,
const secp256k1_musig_session *session,
secp256k1_musig_partial_signature *partial_sig
SECP256K1_API int secp256k1_musig_pubkey_agg(
const secp256k1_context *ctx,
secp256k1_scratch_space *scratch,
secp256k1_xonly_pubkey *agg_pk,
secp256k1_musig_keyagg_cache *keyagg_cache,
const secp256k1_pubkey * const *pubkeys,
size_t n_pubkeys
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(5);
/** Obtain the aggregate public key from a keyagg_cache.
*
* This is only useful if you need the non-xonly public key, in particular for
* plain (non-xonly) tweaking or batch-verifying multiple key aggregations
* (not implemented).
*
* Returns: 0 if the arguments are invalid, 1 otherwise
* Args: ctx: pointer to a context object
* Out: agg_pk: the MuSig-aggregated public key.
* In: keyagg_cache: pointer to a `musig_keyagg_cache` struct initialized by
* `musig_pubkey_agg`
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubkey_get(
const secp256k1_context *ctx,
secp256k1_pubkey *agg_pk,
const secp256k1_musig_keyagg_cache *keyagg_cache
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Checks that an individual partial signature verifies
/** Apply plain "EC" tweaking to a public key in a given keyagg_cache by
* adding the generator multiplied with `tweak32` to it. This is useful for
* deriving child keys from an aggregate public key via BIP32.
*
* This function is essential when using protocols with adaptor signatures.
* However, it is not essential for regular MuSig's, in the sense that if any
* partial signatures does not verify, the full signature will also not verify, so the
* problem will be caught. But this function allows determining the specific party
* who produced an invalid signature, so that signing can be restarted without them.
* The tweaking method is the same as `secp256k1_ec_pubkey_tweak_add`. So after
* the following pseudocode buf and buf2 have identical contents (absent
* earlier failures).
*
* Returns: 1: partial signature verifies
* 0: invalid signature or bad data
* Args: ctx: pointer to a context object (cannot be NULL)
* session: active session for which the combined nonce has been computed
* (cannot be NULL)
* signer: data for the signer who produced this signature (cannot be NULL)
* In: partial_sig: signature to verify (cannot be NULL)
* pubkey: public key of the signer who produced the signature (cannot be NULL)
* secp256k1_musig_pubkey_agg(..., keyagg_cache, pubkeys, ...)
* secp256k1_musig_pubkey_get(..., agg_pk, keyagg_cache)
* secp256k1_musig_pubkey_ec_tweak_add(..., output_pk, tweak32, keyagg_cache)
* secp256k1_ec_pubkey_serialize(..., buf, output_pk)
* secp256k1_ec_pubkey_tweak_add(..., agg_pk, tweak32)
* secp256k1_ec_pubkey_serialize(..., buf2, agg_pk)
*
* This function is required if you want to _sign_ for a tweaked aggregate key.
* On the other hand, if you are only computing a public key, but not intending
* to create a signature for it, you can just use
* `secp256k1_ec_pubkey_tweak_add`.
*
* Returns: 0 if the arguments are invalid or the resulting public key would be
* invalid (only when the tweak is the negation of the corresponding
* secret key). 1 otherwise.
* Args: ctx: pointer to a context object
* Out: output_pubkey: pointer to a public key to store the result. Will be set
* to an invalid value if this function returns 0. If you
* do not need it, this arg can be NULL.
* In/Out: keyagg_cache: pointer to a `musig_keyagg_cache` struct initialized by
* `musig_pubkey_agg`
* In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid
* according to `secp256k1_ec_seckey_verify`, this function
* returns 0. For uniformly random 32-byte arrays the
* chance of being invalid is negligible (around 1 in
* 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_verify(
const secp256k1_context* ctx,
const secp256k1_musig_session *session,
const secp256k1_musig_session_signer_data *signer,
const secp256k1_musig_partial_signature *partial_sig,
const secp256k1_xonly_pubkey *pubkey
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubkey_ec_tweak_add(
const secp256k1_context *ctx,
secp256k1_pubkey *output_pubkey,
secp256k1_musig_keyagg_cache *keyagg_cache,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Apply x-only tweaking to a public key in a given keyagg_cache by adding the
* generator multiplied with `tweak32` to it. This is useful for creating
* Taproot outputs.
*
* The tweaking method is the same as `secp256k1_xonly_pubkey_tweak_add`. So in
* the following pseudocode xonly_pubkey_tweak_add_check (absent earlier
* failures) returns 1.
*
* secp256k1_musig_pubkey_agg(..., agg_pk, keyagg_cache, pubkeys, ...)
* secp256k1_musig_pubkey_xonly_tweak_add(..., output_pk, tweak32, keyagg_cache)
* secp256k1_xonly_pubkey_serialize(..., buf, output_pk)
* secp256k1_xonly_pubkey_tweak_add_check(..., buf, ..., agg_pk, tweak32)
*
* This function is required if you want to _sign_ for a tweaked aggregate key.
* On the other hand, if you are only computing a public key, but not intending
* to create a signature for it, you can just use
* `secp256k1_xonly_pubkey_tweak_add`.
*
* Returns: 0 if the arguments are invalid or the resulting public key would be
* invalid (only when the tweak is the negation of the corresponding
* secret key). 1 otherwise.
* Args: ctx: pointer to a context object
* Out: output_pubkey: pointer to a public key to store the result. Will be set
* to an invalid value if this function returns 0. If you
* do not need it, this arg can be NULL.
* In/Out: keyagg_cache: pointer to a `musig_keyagg_cache` struct initialized by
* `musig_pubkey_agg`
* In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid
* according to secp256k1_ec_seckey_verify, this function
* returns 0. For uniformly random 32-byte arrays the
* chance of being invalid is negligible (around 1 in
* 2^128).
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubkey_xonly_tweak_add(
const secp256k1_context *ctx,
secp256k1_pubkey *output_pubkey,
secp256k1_musig_keyagg_cache *keyagg_cache,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Starts a signing session by generating a nonce
*
* This function outputs a secret nonce that will be required for signing and a
* corresponding public nonce that is intended to be sent to other signers.
*
* MuSig differs from regular Schnorr signing in that implementers _must_ take
* special care to not reuse a nonce. This can be ensured by following these rules:
*
* 1. Each call to this function must have a UNIQUE session_id32 that must NOT BE
* REUSED in subsequent calls to this function.
* If you do not provide a seckey, session_id32 _must_ be UNIFORMLY RANDOM
* AND KEPT SECRET (even from other signers). If you do provide a seckey,
* session_id32 can instead be a counter (that must never repeat!). However,
* it is recommended to always choose session_id32 uniformly at random.
* 2. If you already know the seckey, message or aggregate public key
* cache, they can be optionally provided to derive the nonce and increase
* misuse-resistance. The extra_input32 argument can be used to provide
* additional data that does not repeat in normal scenarios, such as the
* current time.
* 3. Avoid copying (or serializing) the secnonce. This reduces the possibility
* that it is used more than once for signing.
*
* Remember that nonce reuse will leak the secret key!
* Note that using the same seckey for multiple MuSig sessions is fine.
*
* Returns: 0 if the arguments are invalid and 1 otherwise
* Args: ctx: pointer to a context object (not secp256k1_context_static)
* Out: secnonce: pointer to a structure to store the secret nonce
* pubnonce: pointer to a structure to store the public nonce
* In: session_id32: a 32-byte session_id32 as explained above. Must be unique to this
* call to secp256k1_musig_nonce_gen and must be uniformly random
* unless you really know what you are doing.
* seckey: the 32-byte secret key that will later be used for signing, if
* already known (can be NULL)
* pubkey: public key of the signer creating the nonce. The secnonce
* output of this function cannot be used to sign for any
* other public key.
* msg32: the 32-byte message that will later be signed, if already known
* (can be NULL)
* keyagg_cache: pointer to the keyagg_cache that was used to create the aggregate
* (and potentially tweaked) public key if already known
* (can be NULL)
* extra_input32: an optional 32-byte array that is input to the nonce
* derivation function (can be NULL)
*/
SECP256K1_API int secp256k1_musig_nonce_gen(
const secp256k1_context *ctx,
secp256k1_musig_secnonce *secnonce,
secp256k1_musig_pubnonce *pubnonce,
const unsigned char *session_id32,
const unsigned char *seckey,
const secp256k1_pubkey *pubkey,
const unsigned char *msg32,
const secp256k1_musig_keyagg_cache *keyagg_cache,
const unsigned char *extra_input32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(6);
/** Aggregates the nonces of all signers into a single nonce
*
* This can be done by an untrusted party to reduce the communication
* between signers. Instead of everyone sending nonces to everyone else, there
* can be one party receiving all nonces, aggregating the nonces with this
* function and then sending only the aggregate nonce back to the signers.
*
* Returns: 0 if the arguments are invalid, 1 otherwise
* Args: ctx: pointer to a context object
* Out: aggnonce: pointer to an aggregate public nonce object for
* musig_nonce_process
* In: pubnonces: array of pointers to public nonces sent by the
* signers
* n_pubnonces: number of elements in the pubnonces array. Must be
* greater than 0.
*/
SECP256K1_API int secp256k1_musig_nonce_agg(
const secp256k1_context *ctx,
secp256k1_musig_aggnonce *aggnonce,
const secp256k1_musig_pubnonce * const *pubnonces,
size_t n_pubnonces
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Takes the public nonces of all signers and computes a session that is
* required for signing and verification of partial signatures.
*
* If the adaptor argument is non-NULL, then the output of
* musig_partial_sig_agg will be a pre-signature which is not a valid Schnorr
* signature. In order to create a valid signature, the pre-signature and the
* secret adaptor must be provided to `musig_adapt`.
*
* Returns: 0 if the arguments are invalid or if some signer sent invalid
* pubnonces, 1 otherwise
* Args: ctx: pointer to a context object
* Out: session: pointer to a struct to store the session
* In: aggnonce: pointer to an aggregate public nonce object that is the
* output of musig_nonce_agg
* msg32: the 32-byte message to sign
* keyagg_cache: pointer to the keyagg_cache that was used to create the
* aggregate (and potentially tweaked) pubkey
* adaptor: optional pointer to an adaptor point encoded as a public
* key if this signing session is part of an adaptor
* signature protocol (can be NULL)
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_nonce_process(
const secp256k1_context *ctx,
secp256k1_musig_session *session,
const secp256k1_musig_aggnonce *aggnonce,
const unsigned char *msg32,
const secp256k1_musig_keyagg_cache *keyagg_cache,
const secp256k1_pubkey *adaptor
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
/** Combines partial signatures
/** Produces a partial signature
*
* Returns: 1: all partial signatures have values in range. Does NOT mean the
* resulting signature verifies.
* 0: some partial signature are missing or had s or r out of range
* Args: ctx: pointer to a context object (cannot be NULL)
* session: initialized session for which the combined nonce has been
* computed (cannot be NULL)
* Out: sig64: complete signature (cannot be NULL)
* In: partial_sigs: array of partial signatures to combine (cannot be NULL)
* n_sigs: number of signatures in the partial_sigs array
* This function overwrites the given secnonce with zeros and will abort if given a
* secnonce that is all zeros. This is a best effort attempt to protect against nonce
* reuse. However, this is of course easily defeated if the secnonce has been
* copied (or serialized). Remember that nonce reuse will leak the secret key!
*
* For signing to succeed, the secnonce provided to this function must have
* been generated for the provided keypair. This means that when signing for a
* keypair consisting of a seckey and pubkey, the secnonce must have been
* created by calling musig_nonce_gen with that pubkey. Otherwise, the
* illegal_callback is called.
*
* This function does not verify the output partial signature, deviating from
* the BIP 327 specification. It is recommended to verify the output partial
* signature with `secp256k1_musig_partial_sig_verify` to prevent random or
* adversarially provoked computation errors.
*
* Returns: 0 if the arguments are invalid or the provided secnonce has already
* been used for signing, 1 otherwise
* Args: ctx: pointer to a context object
* Out: partial_sig: pointer to struct to store the partial signature
* In/Out: secnonce: pointer to the secnonce struct created in
* musig_nonce_gen that has been never used in a
* partial_sign call before and has been created for the
* keypair
* In: keypair: pointer to keypair to sign the message with
* keyagg_cache: pointer to the keyagg_cache that was output when the
* aggregate public key for this session
* session: pointer to the session that was created with
* musig_nonce_process
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_combine(
const secp256k1_context* ctx,
const secp256k1_musig_session *session,
SECP256K1_API int secp256k1_musig_partial_sign(
const secp256k1_context *ctx,
secp256k1_musig_partial_sig *partial_sig,
secp256k1_musig_secnonce *secnonce,
const secp256k1_keypair *keypair,
const secp256k1_musig_keyagg_cache *keyagg_cache,
const secp256k1_musig_session *session
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6);
/** Verifies an individual signer's partial signature
*
* The signature is verified for a specific signing session. In order to avoid
* accidentally verifying a signature from a different or non-existing signing
* session, you must ensure the following:
* 1. The `keyagg_cache` argument is identical to the one used to create the
* `session` with `musig_nonce_process`.
* 2. The `pubkey` argument must be identical to the one sent by the signer
* before aggregating it with `musig_pubkey_agg` to create the
* `keyagg_cache`.
* 3. The `pubnonce` argument must be identical to the one sent by the signer
* before aggregating it with `musig_nonce_agg` and using the result to
* create the `session` with `musig_nonce_process`.
*
* This function is essential when using protocols with adaptor signatures.
* However, it is not essential for regular MuSig sessions, in the sense that if any
* partial signature does not verify, the full signature will not verify either, so the
* problem will be caught. But this function allows determining the specific party
* who produced an invalid signature.
*
* Returns: 0 if the arguments are invalid or the partial signature does not
* verify, 1 otherwise
* Args ctx: pointer to a context object
* In: partial_sig: pointer to partial signature to verify, sent by
* the signer associated with `pubnonce` and `pubkey`
* pubnonce: public nonce of the signer in the signing session
* pubkey: public key of the signer in the signing session
* keyagg_cache: pointer to the keyagg_cache that was output when the
* aggregate public key for this signing session
* session: pointer to the session that was created with
* `musig_nonce_process`
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_verify(
const secp256k1_context *ctx,
const secp256k1_musig_partial_sig *partial_sig,
const secp256k1_musig_pubnonce *pubnonce,
const secp256k1_pubkey *pubkey,
const secp256k1_musig_keyagg_cache *keyagg_cache,
const secp256k1_musig_session *session
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6);
/** Aggregates partial signatures
*
* Returns: 0 if the arguments are invalid, 1 otherwise (which does NOT mean
* the resulting signature verifies).
* Args: ctx: pointer to a context object
* Out: sig64: complete (but possibly invalid) Schnorr signature
* In: session: pointer to the session that was created with
* musig_nonce_process
* partial_sigs: array of pointers to partial signatures to aggregate
* n_sigs: number of elements in the partial_sigs array. Must be
* greater than 0.
*/
SECP256K1_API int secp256k1_musig_partial_sig_agg(
const secp256k1_context *ctx,
unsigned char *sig64,
const secp256k1_musig_partial_signature *partial_sigs,
const secp256k1_musig_session *session,
const secp256k1_musig_partial_sig * const *partial_sigs,
size_t n_sigs
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Converts a partial signature to an adaptor signature by adding a given secret
* adaptor.
/** Extracts the nonce_parity bit from a session
*
* Returns: 1: signature and secret adaptor contained valid values
* 0: otherwise
* Args: ctx: pointer to a context object (cannot be NULL)
* Out: adaptor_sig: adaptor signature to produce (cannot be NULL)
* In: partial_sig: partial signature to tweak with secret adaptor (cannot be NULL)
* sec_adaptor32: 32-byte secret adaptor to add to the partial signature (cannot
* be NULL)
* nonce_parity: the `nonce_parity` output of `musig_session_combine_nonces`
* This is used for adaptor signatures.
*
* Returns: 0 if the arguments are invalid, 1 otherwise
* Args: ctx: pointer to a context object
* Out: nonce_parity: pointer to an integer that indicates the parity
* of the aggregate public nonce. Used for adaptor
* signatures.
* In: session: pointer to the session that was created with
* musig_nonce_process
*/
SECP256K1_API int secp256k1_musig_partial_sig_adapt(
const secp256k1_context* ctx,
secp256k1_musig_partial_signature *adaptor_sig,
const secp256k1_musig_partial_signature *partial_sig,
SECP256K1_API int secp256k1_musig_nonce_parity(
const secp256k1_context *ctx,
int *nonce_parity,
const secp256k1_musig_session *session
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Creates a signature from a pre-signature and an adaptor.
*
* If the sec_adaptor32 argument is incorrect, the output signature will be
* invalid. This function does not verify the signature.
*
* Returns: 0 if the arguments are invalid, or pre_sig64 or sec_adaptor32 contain
* invalid (overflowing) values. 1 otherwise (which does NOT mean the
* signature or the adaptor are valid!)
* Args: ctx: pointer to a context object
* Out: sig64: 64-byte signature. This pointer may point to the same
* memory area as `pre_sig`.
* In: pre_sig64: 64-byte pre-signature
* sec_adaptor32: 32-byte secret adaptor to add to the pre-signature
* nonce_parity: the output of `musig_nonce_parity` called with the
* session used for producing the pre-signature
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_adapt(
const secp256k1_context *ctx,
unsigned char *sig64,
const unsigned char *pre_sig64,
const unsigned char *sec_adaptor32,
int nonce_parity
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Extracts a secret adaptor from a MuSig, given all parties' partial
* signatures. This function will not fail unless given grossly invalid data; if it
* is merely given signatures that do not verify, the returned value will be
* nonsense. It is therefore important that all data be verified at earlier steps of
* any protocol that uses this function.
/** Extracts a secret adaptor from a MuSig pre-signature and corresponding
* signature
*
* Returns: 1: signatures contained valid data such that an adaptor could be extracted
* 0: otherwise
* Args: ctx: pointer to a context object (cannot be NULL)
* Out:sec_adaptor32: 32-byte secret adaptor (cannot be NULL)
* In: sig64: complete 2-of-2 signature (cannot be NULL)
* partial_sigs: array of partial signatures (cannot be NULL)
* n_partial_sigs: number of elements in partial_sigs array
* nonce_parity: the `nonce_parity` output of `musig_session_combine_nonces`
* This function will not fail unless given grossly invalid data; if it is
* merely given signatures that do not verify, the returned value will be
* nonsense. It is therefore important that all data be verified at earlier
* steps of any protocol that uses this function. In particular, this includes
* verifying all partial signatures that were aggregated into pre_sig64.
*
* Returns: 0 if the arguments are NULL, or sig64 or pre_sig64 contain
* grossly invalid (overflowing) values. 1 otherwise (which does NOT
* mean the signatures or the adaptor are valid!)
* Args: ctx: pointer to a context object
* Out:sec_adaptor32: 32-byte secret adaptor
* In: sig64: complete, valid 64-byte signature
* pre_sig64: the pre-signature corresponding to sig64, i.e., the
* aggregate of partial signatures without the secret
* adaptor
* nonce_parity: the output of `musig_nonce_parity` called with the
* session used for producing sig64
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_extract_secret_adaptor(
const secp256k1_context* ctx,
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_extract_adaptor(
const secp256k1_context *ctx,
unsigned char *sec_adaptor32,
const unsigned char *sig64,
const secp256k1_musig_partial_signature *partial_sigs,
size_t n_partial_sigs,
const unsigned char *pre_sig64,
int nonce_parity
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);

View File

@@ -52,17 +52,19 @@ SECP256K1_API size_t secp256k1_context_preallocated_size(
* in the memory. In simpler words, the prealloc pointer (or any pointer derived
* from it) should not be used during the lifetime of the context object.
*
* Returns: a newly created context object.
* In: prealloc: a pointer to a rewritable contiguous block of memory of
* Returns: pointer to newly created context object.
* In: prealloc: pointer to a rewritable contiguous block of memory of
* size at least secp256k1_context_preallocated_size(flags)
* bytes, as detailed above (cannot be NULL)
* bytes, as detailed above.
* flags: which parts of the context to initialize.
*
* See secp256k1_context_create (in secp256k1.h) for further details.
*
* See also secp256k1_context_randomize (in secp256k1.h)
* and secp256k1_context_preallocated_destroy.
*/
SECP256K1_API secp256k1_context* secp256k1_context_preallocated_create(
void* prealloc,
SECP256K1_API secp256k1_context *secp256k1_context_preallocated_create(
void *prealloc,
unsigned int flags
) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT;
@@ -70,10 +72,10 @@ SECP256K1_API secp256k1_context* secp256k1_context_preallocated_create(
* caller-provided memory.
*
* Returns: the required size of the caller-provided memory block.
* In: ctx: an existing context to copy (cannot be NULL)
* In: ctx: pointer to a context to copy.
*/
SECP256K1_API size_t secp256k1_context_preallocated_clone_size(
const secp256k1_context* ctx
const secp256k1_context *ctx
) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT;
/** Copy a secp256k1 context object into caller-provided memory.
@@ -86,15 +88,18 @@ SECP256K1_API size_t secp256k1_context_preallocated_clone_size(
* the lifetime of this context object, see the description of
* secp256k1_context_preallocated_create for details.
*
* Returns: a newly created context object.
* Args: ctx: an existing context to copy (cannot be NULL)
* In: prealloc: a pointer to a rewritable contiguous block of memory of
* Cloning secp256k1_context_static is not possible, and should not be emulated by
* the caller (e.g., using memcpy). Create a new context instead.
*
* Returns: pointer to a newly created context object.
* Args: ctx: pointer to a context to copy (not secp256k1_context_static).
* In: prealloc: pointer to a rewritable contiguous block of memory of
* size at least secp256k1_context_preallocated_size(flags)
* bytes, as detailed above (cannot be NULL)
* bytes, as detailed above.
*/
SECP256K1_API secp256k1_context* secp256k1_context_preallocated_clone(
const secp256k1_context* ctx,
void* prealloc
SECP256K1_API secp256k1_context *secp256k1_context_preallocated_clone(
const secp256k1_context *ctx,
void *prealloc
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_WARN_UNUSED_RESULT;
/** Destroy a secp256k1 context object that has been created in
@@ -113,13 +118,14 @@ SECP256K1_API secp256k1_context* secp256k1_context_preallocated_clone(
* preallocated pointer given to secp256k1_context_preallocated_create or
* secp256k1_context_preallocated_clone.
*
* Args: ctx: an existing context to destroy, constructed using
* Args: ctx: pointer to a context to destroy, constructed using
* secp256k1_context_preallocated_create or
* secp256k1_context_preallocated_clone (cannot be NULL)
* secp256k1_context_preallocated_clone
* (i.e., not secp256k1_context_static).
*/
SECP256K1_API void secp256k1_context_preallocated_destroy(
secp256k1_context* ctx
);
secp256k1_context *ctx
) SECP256K1_ARG_NONNULL(1);
#ifdef __cplusplus
}

View File

@@ -1,5 +1,5 @@
#ifndef _SECP256K1_RANGEPROOF_
# define _SECP256K1_RANGEPROOF_
#ifndef SECP256K1_RANGEPROOF_H
# define SECP256K1_RANGEPROOF_H
# include "secp256k1.h"
# include "secp256k1_generator.h"
@@ -10,158 +10,19 @@ extern "C" {
#include <stdint.h>
/** Opaque data structure that stores a Pedersen commitment
/** Length of a message that can be embedded into a maximally-sized rangeproof
*
* The exact representation of data inside is implementation defined and not
* guaranteed to be portable between different platforms or versions. It is
* however guaranteed to be 64 bytes in size, and can be safely copied/moved.
* If you need to convert to a format suitable for storage, transmission, or
* comparison, use secp256k1_pedersen_commitment_serialize and
* secp256k1_pedersen_commitment_parse.
* It is not be possible to fit a message of this size into a non-maximally-sized
* rangeproof, but it is guaranteed that any embeddable message can fit into an
* array of this size. This constant is intended to be used for memory allocations
* and sanity checks.
*/
typedef struct {
unsigned char data[64];
} secp256k1_pedersen_commitment;
/**
* Static constant generator 'h' maintained for historical reasons.
*/
SECP256K1_API extern const secp256k1_generator *secp256k1_generator_h;
/** Parse a 33-byte commitment into a commitment object.
*
* Returns: 1 if input contains a valid commitment.
* Args: ctx: a secp256k1 context object.
* Out: commit: pointer to the output commitment object
* In: input: pointer to a 33-byte serialized commitment key
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_commitment_parse(
const secp256k1_context* ctx,
secp256k1_pedersen_commitment* commit,
const unsigned char *input
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Serialize a commitment object into a serialized byte sequence.
*
* Returns: 1 always.
* Args: ctx: a secp256k1 context object.
* Out: output: a pointer to a 33-byte byte array
* In: commit: a pointer to a secp256k1_pedersen_commitment containing an
* initialized commitment
*/
SECP256K1_API int secp256k1_pedersen_commitment_serialize(
const secp256k1_context* ctx,
unsigned char *output,
const secp256k1_pedersen_commitment* commit
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Generate a pedersen commitment.
* Returns 1: Commitment successfully created.
* 0: Error. The blinding factor is larger than the group order
* (probability for random 32 byte number < 2^-127) or results in the
* point at infinity. Retry with a different factor.
* In: ctx: pointer to a context object, initialized for signing and Pedersen commitment (cannot be NULL)
* blind: pointer to a 32-byte blinding factor (cannot be NULL)
* value: unsigned 64-bit integer value to commit to.
* gen: additional generator 'h'
* Out: commit: pointer to the commitment (cannot be NULL)
*
* Blinding factors can be generated and verified in the same way as secp256k1 private keys for ECDSA.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_commit(
const secp256k1_context* ctx,
secp256k1_pedersen_commitment *commit,
const unsigned char *blind,
uint64_t value,
const secp256k1_generator *gen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
/** Computes the sum of multiple positive and negative blinding factors.
* Returns 1: Sum successfully computed.
* 0: Error. A blinding factor is larger than the group order
* (probability for random 32 byte number < 2^-127). Retry with
* different factors.
* In: ctx: pointer to a context object (cannot be NULL)
* blinds: pointer to pointers to 32-byte character arrays for blinding factors. (cannot be NULL)
* n: number of factors pointed to by blinds.
* npositive: how many of the initial factors should be treated with a positive sign.
* Out: blind_out: pointer to a 32-byte array for the sum (cannot be NULL)
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_blind_sum(
const secp256k1_context* ctx,
unsigned char *blind_out,
const unsigned char * const *blinds,
size_t n,
size_t npositive
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Verify a tally of pedersen commitments
* Returns 1: commitments successfully sum to zero.
* 0: Commitments do not sum to zero or other error.
* In: ctx: pointer to a context object (cannot be NULL)
* commits: pointer to array of pointers to the commitments. (cannot be NULL if pcnt is non-zero)
* pcnt: number of commitments pointed to by commits.
* ncommits: pointer to array of pointers to the negative commitments. (cannot be NULL if ncnt is non-zero)
* ncnt: number of commitments pointed to by ncommits.
*
* This computes sum(commit[0..pcnt)) - sum(ncommit[0..ncnt)) == 0.
*
* A pedersen commitment is xG + vA where G and A are generators for the secp256k1 group and x is a blinding factor,
* while v is the committed value. For a collection of commitments to sum to zero, for each distinct generator
* A all blinding factors and all values must sum to zero.
*
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_verify_tally(
const secp256k1_context* ctx,
const secp256k1_pedersen_commitment * const* commits,
size_t pcnt,
const secp256k1_pedersen_commitment * const* ncommits,
size_t ncnt
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
/** Sets the final Pedersen blinding factor correctly when the generators themselves
* have blinding factors.
*
* Consider a generator of the form A' = A + rG, where A is the "real" generator
* but A' is the generator provided to verifiers. Then a Pedersen commitment
* P = vA' + r'G really has the form vA + (vr + r')G. To get all these (vr + r')
* to sum to zero for multiple commitments, we take three arrays consisting of
* the `v`s, `r`s, and `r'`s, respectively called `value`s, `generator_blind`s
* and `blinding_factor`s, and sum them.
*
* The function then subtracts the sum of all (vr + r') from the last element
* of the `blinding_factor` array, setting the total sum to zero.
*
* Returns 1: Blinding factor successfully computed.
* 0: Error. A blinding_factor or generator_blind are larger than the group
* order (probability for random 32 byte number < 2^-127). Retry with
* different values.
*
* In: ctx: pointer to a context object
* value: array of asset values, `v` in the above paragraph.
* May not be NULL unless `n_total` is 0.
* generator_blind: array of asset blinding factors, `r` in the above paragraph
* May not be NULL unless `n_total` is 0.
* n_total: Total size of the above arrays
* n_inputs: How many of the initial array elements represent commitments that
* will be negated in the final sum
* In/Out: blinding_factor: array of commitment blinding factors, `r'` in the above paragraph
* May not be NULL unless `n_total` is 0.
* the last value will be modified to get the total sum to zero.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_blind_generator_blind_sum(
const secp256k1_context* ctx,
const uint64_t *value,
const unsigned char* const* generator_blind,
unsigned char* const* blinding_factor,
size_t n_total,
size_t n_inputs
);
#define SECP256K1_RANGEPROOF_MAX_MESSAGE_LEN 3968
/** Verify a proof that a committed value is within a range.
* Returns 1: Value is within the range [0..2^64), the specifically proven range is in the min/max value outputs.
* 0: Proof failed or other error.
* In: ctx: pointer to a context object, initialized for range-proof and commitment (cannot be NULL)
* In: ctx: pointer to a context object (not secp256k1_context_static)
* commit: the commitment being proved. (cannot be NULL)
* proof: pointer to character array with the proof. (cannot be NULL)
* plen: length of proof in bytes.
@@ -172,7 +33,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_blind_generato
* max_value: pointer to a unsigned int64 which will be updated with the maximum value that commit could have. (cannot be NULL)
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_verify(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
uint64_t *min_value,
uint64_t *max_value,
const secp256k1_pedersen_commitment *commit,
@@ -180,13 +41,13 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_verify(
size_t plen,
const unsigned char *extra_commit,
size_t extra_commit_len,
const secp256k1_generator* gen
const secp256k1_generator *gen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(9);
/** Verify a range proof proof and rewind the proof to recover information sent by its author.
* Returns 1: Value is within the range [0..2^64), the specifically proven range is in the min/max value outputs, and the value and blinding were recovered.
* 0: Proof failed, rewind failed, or other error.
* In: ctx: pointer to a context object, initialized for range-proof and Pedersen commitment (cannot be NULL)
* In: ctx: pointer to a context object (not secp256k1_context_static)
* commit: the commitment being proved. (cannot be NULL)
* proof: pointer to character array with the proof. (cannot be NULL)
* plen: length of proof in bytes.
@@ -197,12 +58,14 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_verify(
* In/Out: blind_out: storage for the 32-byte blinding factor used for the commitment
* value_out: pointer to an unsigned int64 which has the exact value of the commitment.
* message_out: pointer to a 4096 byte character array to receive message data from the proof author.
* outlen: length of message data written to message_out.
* outlen: length of message data written to message_out. This is generally not equal to the
* msg_len used by the signer. However, for all i with msg_len <= i < outlen, it is
* guaranteed that message_out[i] == 0.
* min_value: pointer to an unsigned int64 which will be updated with the minimum value that commit could have. (cannot be NULL)
* max_value: pointer to an unsigned int64 which will be updated with the maximum value that commit could have. (cannot be NULL)
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_rewind(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
unsigned char *blind_out,
uint64_t *value_out,
unsigned char *message_out,
@@ -221,11 +84,12 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_rewind(
/** Author a proof that a committed value is within a range.
* Returns 1: Proof successfully created.
* 0: Error
* In: ctx: pointer to a context object, initialized for range-proof, signing, and Pedersen commitment (cannot be NULL)
* In: ctx: pointer to a context object (not secp256k1_context_static)
* proof: pointer to array to receive the proof, can be up to 5134 bytes. (cannot be NULL)
* min_value: constructs a proof where the verifer can tell the minimum value is at least the specified amount.
* commit: the commitment being proved.
* blind: 32-byte blinding factor used by commit.
* blind: 32-byte blinding factor used by commit. The blinding factor may be all-zeros as long as min_bits is set to 3 or greater.
* This is a side-effect of the underlying crypto, not a deliberate API choice, but it may be useful when balancing CT transactions.
* nonce: 32-byte secret nonce used to initialize the proof (value can be reverse-engineered out of the proof if this secret is known.)
* exp: Base-10 exponent. Digits below above will be made public, but the proof will be made smaller. Allowed range is -1 to 18.
* (-1 is a special case that makes the value public. 0 is the most private.)
@@ -246,7 +110,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_rewind(
*
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_sign(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
unsigned char *proof,
size_t *plen,
uint64_t min_value,
@@ -275,7 +139,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_sign(
* max_value: pointer to an unsigned int64 which will be updated with the maximum value that commit could have. (cannot be NULL)
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_info(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
int *exp,
int *mantissa,
uint64_t *min_value,
@@ -284,6 +148,33 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_info(
size_t plen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
/** Returns an upper bound on the size of a rangeproof with the given parameters
*
* An actual rangeproof may be smaller, for example if the actual value
* is less than both the provided `max_value` and 2^`min_bits`, or if
* the `exp` parameter to `secp256k1_rangeproof_sign` is set such that
* the proven range is compressed. In particular this function will always
* overestimate the size of single-value proofs. Also, if `min_value`
* is set to 0 in the proof, the result will usually, but not always,
* be 8 bytes smaller than if a nonzero value had been passed.
*
* The goal of this function is to provide a useful upper bound for
* memory allocation or fee estimation purposes, without requiring
* too many parameters be fixed in advance.
*
* To obtain the size of largest possible proof, set `max_value` to
* `UINT64_MAX` (and `min_bits` to any valid value such as 0).
*
* In: ctx: pointer to a context object
* max_value: the maximum value that might be passed for `value` for the proof.
* min_bits: the value that will be passed as `min_bits` for the proof.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT size_t secp256k1_rangeproof_max_size(
const secp256k1_context *ctx,
uint64_t max_value,
int min_bits
) SECP256K1_ARG_NONNULL(1);
# ifdef __cplusplus
}
# endif

View File

@@ -28,14 +28,14 @@ typedef struct {
/** Parse a compact ECDSA signature (64 bytes + recovery id).
*
* Returns: 1 when the signature could be parsed, 0 otherwise
* Args: ctx: a secp256k1 context object
* Out: sig: a pointer to a signature object
* In: input64: a pointer to a 64-byte compact signature
* Args: ctx: pointer to a context object
* Out: sig: pointer to a signature object
* In: input64: pointer to a 64-byte compact signature
* recid: the recovery id (0, 1, 2 or 3)
*/
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact(
const secp256k1_context* ctx,
secp256k1_ecdsa_recoverable_signature* sig,
const secp256k1_context *ctx,
secp256k1_ecdsa_recoverable_signature *sig,
const unsigned char *input64,
int recid
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
@@ -43,45 +43,48 @@ SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact(
/** Convert a recoverable signature into a normal signature.
*
* Returns: 1
* Out: sig: a pointer to a normal signature (cannot be NULL).
* In: sigin: a pointer to a recoverable signature (cannot be NULL).
* Args: ctx: pointer to a context object.
* Out: sig: pointer to a normal signature.
* In: sigin: pointer to a recoverable signature.
*/
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_convert(
const secp256k1_context* ctx,
secp256k1_ecdsa_signature* sig,
const secp256k1_ecdsa_recoverable_signature* sigin
const secp256k1_context *ctx,
secp256k1_ecdsa_signature *sig,
const secp256k1_ecdsa_recoverable_signature *sigin
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Serialize an ECDSA signature in compact format (64 bytes + recovery id).
*
* Returns: 1
* Args: ctx: a secp256k1 context object
* Out: output64: a pointer to a 64-byte array of the compact signature (cannot be NULL)
* recid: a pointer to an integer to hold the recovery id (can be NULL).
* In: sig: a pointer to an initialized signature object (cannot be NULL)
* Args: ctx: pointer to a context object.
* Out: output64: pointer to a 64-byte array of the compact signature.
* recid: pointer to an integer to hold the recovery id.
* In: sig: pointer to an initialized signature object.
*/
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
unsigned char *output64,
int *recid,
const secp256k1_ecdsa_recoverable_signature* sig
const secp256k1_ecdsa_recoverable_signature *sig
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Create a recoverable ECDSA signature.
*
* Returns: 1: signature created
* 0: the nonce generation function failed, or the secret key was invalid.
* Args: ctx: pointer to a context object, initialized for signing (cannot be NULL)
* Out: sig: pointer to an array where the signature will be placed (cannot be NULL)
* In: msg32: the 32-byte message hash being signed (cannot be NULL)
* seckey: pointer to a 32-byte secret key (cannot be NULL)
* noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used
* ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
* Args: ctx: pointer to a context object (not secp256k1_context_static).
* Out: sig: pointer to an array where the signature will be placed.
* In: msghash32: the 32-byte message hash being signed.
* seckey: pointer to a 32-byte secret key.
* noncefp: pointer to a nonce generation function. If NULL,
* secp256k1_nonce_function_default is used.
* ndata: pointer to arbitrary data used by the nonce generation function
* (can be NULL for secp256k1_nonce_function_default).
*/
SECP256K1_API int secp256k1_ecdsa_sign_recoverable(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
secp256k1_ecdsa_recoverable_signature *sig,
const unsigned char *msg32,
const unsigned char *msghash32,
const unsigned char *seckey,
secp256k1_nonce_function noncefp,
const void *ndata
@@ -91,16 +94,16 @@ SECP256K1_API int secp256k1_ecdsa_sign_recoverable(
*
* Returns: 1: public key successfully recovered (which guarantees a correct signature).
* 0: otherwise.
* Args: ctx: pointer to a context object, initialized for verification (cannot be NULL)
* Out: pubkey: pointer to the recovered public key (cannot be NULL)
* In: sig: pointer to initialized signature that supports pubkey recovery (cannot be NULL)
* msg32: the 32-byte message hash assumed to be signed (cannot be NULL)
* Args: ctx: pointer to a context object.
* Out: pubkey: pointer to the recovered public key.
* In: sig: pointer to initialized signature that supports pubkey recovery.
* msghash32: the 32-byte message hash assumed to be signed.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
secp256k1_pubkey *pubkey,
const secp256k1_ecdsa_recoverable_signature *sig,
const unsigned char *msg32
const unsigned char *msghash32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
#ifdef __cplusplus

View File

@@ -23,24 +23,29 @@ extern "C" {
*
* Returns: 1 if a nonce was successfully generated. 0 will cause signing to
* return an error.
* Out: nonce32: pointer to a 32-byte array to be filled by the function.
* In: msg32: the 32-byte message hash being verified (will not be NULL)
* key32: pointer to a 32-byte secret key (will not be NULL)
* xonly_pk32: the 32-byte serialized xonly pubkey corresponding to key32
* (will not be NULL)
* algo16: pointer to a 16-byte array describing the signature
* algorithm (will not be NULL).
* data: Arbitrary data pointer that is passed through.
* Out: nonce32: pointer to a 32-byte array to be filled by the function
* In: msg: the message being verified. Is NULL if and only if msglen
* is 0.
* msglen: the length of the message
* key32: pointer to a 32-byte secret key (will not be NULL)
* xonly_pk32: the 32-byte serialized xonly pubkey corresponding to key32
* (will not be NULL)
* algo: pointer to an array describing the signature
* algorithm (will not be NULL)
* algolen: the length of the algo array
* data: arbitrary data pointer that is passed through
*
* Except for test cases, this function should compute some cryptographic hash of
* the message, the key, the pubkey, the algorithm description, and data.
*/
typedef int (*secp256k1_nonce_function_hardened)(
unsigned char *nonce32,
const unsigned char *msg32,
const unsigned char *msg,
size_t msglen,
const unsigned char *key32,
const unsigned char *xonly_pk32,
const unsigned char *algo16,
const unsigned char *algo,
size_t algolen,
void *data
);
@@ -50,13 +55,42 @@ typedef int (*secp256k1_nonce_function_hardened)(
*
* If a data pointer is passed, it is assumed to be a pointer to 32 bytes of
* auxiliary random data as defined in BIP-340. If the data pointer is NULL,
* schnorrsig_sign does not produce BIP-340 compliant signatures. The algo16
* argument must be non-NULL, otherwise the function will fail and return 0.
* The hash will be tagged with algo16 after removing all terminating null
* bytes. Therefore, to create BIP-340 compliant signatures, algo16 must be set
* to "BIP0340/nonce\0\0\0"
* the nonce derivation procedure follows BIP-340 by setting the auxiliary
* random data to zero. The algo argument must be non-NULL, otherwise the
* function will fail and return 0. The hash will be tagged with algo.
* Therefore, to create BIP-340 compliant signatures, algo must be set to
* "BIP0340/nonce" and algolen to 13.
*/
SECP256K1_API extern const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340;
SECP256K1_API const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340;
/** Data structure that contains additional arguments for schnorrsig_sign_custom.
*
* A schnorrsig_extraparams structure object can be initialized correctly by
* setting it to SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT.
*
* Members:
* magic: set to SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC at initialization
* and has no other function than making sure the object is
* initialized.
* noncefp: pointer to a nonce generation function. If NULL,
* secp256k1_nonce_function_bip340 is used
* ndata: pointer to arbitrary data used by the nonce generation function
* (can be NULL). If it is non-NULL and
* secp256k1_nonce_function_bip340 is used, then ndata must be a
* pointer to 32-byte auxiliary randomness as per BIP-340.
*/
typedef struct {
unsigned char magic[4];
secp256k1_nonce_function_hardened noncefp;
void *ndata;
} secp256k1_schnorrsig_extraparams;
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC { 0xda, 0x6f, 0xb3, 0x8c }
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT {\
SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC,\
NULL,\
NULL\
}
/** Create a Schnorr signature.
*
@@ -64,45 +98,90 @@ SECP256K1_API extern const secp256k1_nonce_function_hardened secp256k1_nonce_fun
* signature. Instead, you can manually use secp256k1_schnorrsig_verify and
* abort if it fails.
*
* Otherwise BIP-340 compliant if the noncefp argument is NULL or
* secp256k1_nonce_function_bip340 and the ndata argument is 32-byte auxiliary
* randomness.
* This function only signs 32-byte messages. If you have messages of a
* different size (or the same size but without a context-specific tag
* prefix), it is recommended to create a 32-byte message hash with
* secp256k1_tagged_sha256 and then sign the hash. Tagged hashing allows
* providing an context-specific tag for domain separation. This prevents
* signatures from being valid in multiple contexts by accident.
*
* Returns 1 on success, 0 on failure.
* Args: ctx: pointer to a context object, initialized for signing (cannot be NULL)
* Out: sig64: pointer to a 64-byte array to store the serialized signature (cannot be NULL)
* In: msg32: the 32-byte message being signed (cannot be NULL)
* keypair: pointer to an initialized keypair (cannot be NULL)
* noncefp: pointer to a nonce generation function. If NULL, secp256k1_nonce_function_bip340 is used
* ndata: pointer to arbitrary data used by the nonce generation
* function (can be NULL). If it is non-NULL and
* secp256k1_nonce_function_bip340 is used, then ndata must be a
* pointer to 32-byte auxiliary randomness as per BIP-340.
* Args: ctx: pointer to a context object (not secp256k1_context_static).
* Out: sig64: pointer to a 64-byte array to store the serialized signature.
* In: msg32: the 32-byte message being signed.
* keypair: pointer to an initialized keypair.
* aux_rand32: 32 bytes of fresh randomness. While recommended to provide
* this, it is only supplemental to security and can be NULL. A
* NULL argument is treated the same as an all-zero one. See
* BIP-340 "Default Signing" for a full explanation of this
* argument and for guidance if randomness is expensive.
*/
SECP256K1_API int secp256k1_schnorrsig_sign(
const secp256k1_context* ctx,
SECP256K1_API int secp256k1_schnorrsig_sign32(
const secp256k1_context *ctx,
unsigned char *sig64,
const unsigned char *msg32,
const secp256k1_keypair *keypair,
secp256k1_nonce_function_hardened noncefp,
void *ndata
const unsigned char *aux_rand32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Same as secp256k1_schnorrsig_sign32, but DEPRECATED. Will be removed in
* future versions. */
SECP256K1_API int secp256k1_schnorrsig_sign(
const secp256k1_context *ctx,
unsigned char *sig64,
const unsigned char *msg32,
const secp256k1_keypair *keypair,
const unsigned char *aux_rand32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
SECP256K1_DEPRECATED("Use secp256k1_schnorrsig_sign32 instead");
/** Create a Schnorr signature with a more flexible API.
*
* Same arguments as secp256k1_schnorrsig_sign except that it allows signing
* variable length messages and accepts a pointer to an extraparams object that
* allows customizing signing by passing additional arguments.
*
* Equivalent to secp256k1_schnorrsig_sign32(..., aux_rand32) if msglen is 32
* and extraparams is initialized as follows:
* ```
* secp256k1_schnorrsig_extraparams extraparams = SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT;
* extraparams.ndata = (unsigned char*)aux_rand32;
* ```
*
* Returns 1 on success, 0 on failure.
* Args: ctx: pointer to a context object (not secp256k1_context_static).
* Out: sig64: pointer to a 64-byte array to store the serialized signature.
* In: msg: the message being signed. Can only be NULL if msglen is 0.
* msglen: length of the message.
* keypair: pointer to an initialized keypair.
* extraparams: pointer to an extraparams object (can be NULL).
*/
SECP256K1_API int secp256k1_schnorrsig_sign_custom(
const secp256k1_context *ctx,
unsigned char *sig64,
const unsigned char *msg,
size_t msglen,
const secp256k1_keypair *keypair,
secp256k1_schnorrsig_extraparams *extraparams
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(5);
/** Verify a Schnorr signature.
*
* Returns: 1: correct signature
* 0: incorrect signature
* Args: ctx: a secp256k1 context object, initialized for verification.
* In: sig64: pointer to the 64-byte signature to verify (cannot be NULL)
* msg32: the 32-byte message being verified (cannot be NULL)
* pubkey: pointer to an x-only public key to verify with (cannot be NULL)
* Args: ctx: pointer to a context object.
* In: sig64: pointer to the 64-byte signature to verify.
* msg: the message being verified. Can only be NULL if msglen is 0.
* msglen: length of the message
* pubkey: pointer to an x-only public key to verify with
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorrsig_verify(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
const unsigned char *sig64,
const unsigned char *msg32,
const unsigned char *msg,
size_t msglen,
const secp256k1_xonly_pubkey *pubkey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(5);
#ifdef __cplusplus
}

View File

@@ -0,0 +1,107 @@
#ifndef SECP256K1_SCHNORRSIG_HALFAGG_H
#define SECP256K1_SCHNORRSIG_HALFAGG_H
#include "secp256k1.h"
#include "secp256k1_extrakeys.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Incrementally (Half-)Aggregate a sequence of Schnorr
* signatures to an existing half-aggregate signature.
*
* Returns 1 on success, 0 on failure.
* Args: ctx: a secp256k1 context object.
* In/Out: aggsig: pointer to the serialized aggregate signature
* that is input. The first 32*(n_before+1) of this
* array should hold the input aggsig. It will be
* overwritten by the new serialized aggregate signature.
* It should be large enough for that, see aggsig_len.
* aggsig_len: size of aggsig array in bytes.
* Should be large enough to hold the new
* serialized aggregate signature, i.e.,
* should satisfy aggsig_size >= 32*(n_before+n_new+1).
* It will be overwritten to be the exact size of the
* resulting aggsig.
* In: all_pubkeys: Array of (n_before + n_new) many x-only public keys,
* including both the ones for the already aggregated signature
* and the ones for the signatures that should be added.
* Can only be NULL if n_before + n_new is 0.
* all_msgs32: Array of (n_before + n_new) many 32-byte messages,
* including both the ones for the already aggregated signature
* and the ones for the signatures that should be added.
* Can only be NULL if n_before + n_new is 0.
* new_sigs64: Array of n_new many 64-byte signatures, containing the new
* signatures that should be added. Can only be NULL if n_new is 0.
* n_before: Number of signatures that have already been aggregated
* in the input aggregate signature.
* n_new: Number of signatures that should now be added
* to the aggregate signature.
*/
SECP256K1_API int secp256k1_schnorrsig_inc_aggregate(
const secp256k1_context *ctx,
unsigned char *aggsig,
size_t *aggsig_len,
const secp256k1_xonly_pubkey* all_pubkeys,
const unsigned char *all_msgs32,
const unsigned char *new_sigs64,
size_t n_before,
size_t n_new
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** (Half-)Aggregate a sequence of Schnorr signatures.
*
* Returns 1 on success, 0 on failure.
* Args: ctx: a secp256k1 context object.
* Out: aggsig: pointer to an array of aggsig_len many bytes to
* store the serialized aggregate signature.
* In/Out: aggsig_len: size of the aggsig array that is passed in bytes;
* will be overwritten to be the exact size of aggsig.
* In: pubkeys: Array of n many x-only public keys.
* Can only be NULL if n is 0.
* msgs32: Array of n many 32-byte messages.
* Can only be NULL if n is 0.
* sigs64: Array of n many 64-byte signatures.
* Can only be NULL if n is 0.
* n: number of signatures to be aggregated.
*/
SECP256K1_API int secp256k1_schnorrsig_aggregate(
const secp256k1_context *ctx,
unsigned char *aggsig,
size_t *aggsig_len,
const secp256k1_xonly_pubkey *pubkeys,
const unsigned char *msgs32,
const unsigned char *sigs64,
size_t n
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Verify a (Half-)aggregate Schnorr signature.
*
* Returns: 1: correct signature.
* 0: incorrect signature.
* Args: ctx: a secp256k1 context object.
* In: pubkeys: Array of n many x-only public keys. Can only be NULL if n is 0.
* msgs32: Array of n many 32-byte messages. Can only be NULL if n is 0.
* n: number of signatures to that have been aggregated.
* aggsig: Pointer to an array of aggsig_size many bytes
* containing the serialized aggregate
* signature to be verified.
* aggsig_len: Size of the aggregate signature in bytes.
* Should be aggsig_len = 32*(n+1)
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorrsig_aggverify(
const secp256k1_context *ctx,
const secp256k1_xonly_pubkey *pubkeys,
const unsigned char *msgs32,
size_t n,
const unsigned char *aggsig,
size_t aggsig_len
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(5);
#ifdef __cplusplus
}
#endif
#endif /* SECP256K1_SCHNORRSIG_HALFAGG_H */

View File

@@ -1,5 +1,5 @@
#ifndef _SECP256K1_SURJECTIONPROOF_
#define _SECP256K1_SURJECTIONPROOF_
#ifndef SECP256K1_SURJECTIONPROOF_H
#define SECP256K1_SURJECTIONPROOF_H
#include "secp256k1.h"
#include "secp256k1_rangeproof.h"
@@ -56,9 +56,9 @@ typedef struct {
/** Parse a surjection proof
*
* Returns: 1 when the proof could be parsed, 0 otherwise.
* Args: ctx: a secp256k1 context object
* Out: proof: a pointer to a proof object
* In: input: a pointer to the array to parse
* Args: ctx: pointer to a context object
* Out: proof: pointer to a proof object
* In: input: pointer to the array to parse
* inputlen: length of the array pointed to by input
*
* The proof must consist of:
@@ -69,7 +69,7 @@ typedef struct {
* is the number of set bits in the bitmap
*/
SECP256K1_API int secp256k1_surjectionproof_parse(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
secp256k1_surjectionproof *proof,
const unsigned char *input,
size_t inputlen
@@ -79,17 +79,16 @@ SECP256K1_API int secp256k1_surjectionproof_parse(
/** Serialize a surjection proof
*
* Returns: 1 if enough space was available to serialize, 0 otherwise
* Args: ctx: a secp256k1 context object
* Out: output: a pointer to an array to store the serialization
* In/Out: outputlen: a pointer to an integer which is initially set to the
* size of output, and is overwritten with the written
* size.
* In: proof: a pointer to an initialized proof object
* Args: ctx: pointer to a context object
* Out: output: pointer to an array to store the serialization
* In/Out: outputlen: pointer to an integer which is initially set to the size
* of output, and is overwritten with the written size.
* In: proof: pointer to an initialized proof object
*
* See secp256k1_surjectionproof_parse for details about the encoding.
*/
SECP256K1_API int secp256k1_surjectionproof_serialize(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
unsigned char *output,
size_t *outputlen,
const secp256k1_surjectionproof *proof
@@ -109,33 +108,33 @@ typedef struct {
*
* Returns: the number of inputs for the given proof
* In: ctx: pointer to a context object
* proof: a pointer to a proof object
* proof: pointer to a proof object
*/
SECP256K1_API size_t secp256k1_surjectionproof_n_total_inputs(
const secp256k1_context* ctx,
const secp256k1_surjectionproof* proof
const secp256k1_context *ctx,
const secp256k1_surjectionproof *proof
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
/** Returns the actual number of inputs that a proof uses
*
* Returns: the number of inputs for the given proof
* In: ctx: pointer to a context object
* proof: a pointer to a proof object
* proof: pointer to a proof object
*/
SECP256K1_API size_t secp256k1_surjectionproof_n_used_inputs(
const secp256k1_context* ctx,
const secp256k1_surjectionproof* proof
const secp256k1_context *ctx,
const secp256k1_surjectionproof *proof
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
/** Returns the total size this proof would take, in bytes, when serialized
*
* Returns: the total size
* In: ctx: pointer to a context object
* proof: a pointer to a proof object
* proof: pointer to a proof object
*/
SECP256K1_API size_t secp256k1_surjectionproof_serialized_size(
const secp256k1_context* ctx,
const secp256k1_surjectionproof* proof
const secp256k1_context *ctx,
const secp256k1_surjectionproof *proof
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
/** Surjection proof initialization function; decides on inputs to use
@@ -156,19 +155,19 @@ SECP256K1_API size_t secp256k1_surjectionproof_serialized_size(
* limited to 256 the probability of giving up is smaller than
* (255/256)^(n_input_tags_to_use*max_n_iterations).
*
* random_seed32: a random seed to be used for input selection
* random_seed32: random seed to be used for input selection
* Out: proof: The proof whose bitvector will be initialized. In case of failure,
* the state of the proof is undefined.
* input_index: The index of the actual input that is secretly mapped to the output
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_surjectionproof_initialize(
const secp256k1_context* ctx,
secp256k1_surjectionproof* proof,
const secp256k1_context *ctx,
secp256k1_surjectionproof *proof,
size_t *input_index,
const secp256k1_fixed_asset_tag* fixed_input_tags,
const secp256k1_fixed_asset_tag *fixed_input_tags,
const size_t n_input_tags,
const size_t n_input_tags_to_use,
const secp256k1_fixed_asset_tag* fixed_output_tag,
const secp256k1_fixed_asset_tag *fixed_output_tag,
const size_t n_max_iterations,
const unsigned char *random_seed32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(7);
@@ -179,8 +178,8 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_surjectionproof_initial
* n: inputs were selected after n iterations of random selection
*
* In: ctx: pointer to a context object
* proof_out_p: a pointer to a pointer to `secp256k1_surjectionproof*`.
* the newly-allocated struct pointer will be saved here.
* proof_out_p: pointer to a pointer to `secp256k1_surjectionproof*`.
* The newly-allocated struct pointer will be saved here.
* fixed_input_tags: fixed input tags `A_i` for all inputs. (If the fixed tag is not known,
* e.g. in a coinjoin with others' inputs, an ephemeral tag can be given;
* this won't match the output tag but might be used in the anonymity set.)
@@ -192,19 +191,19 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_surjectionproof_initial
* limited to 256 the probability of giving up is smaller than
* (255/256)^(n_input_tags_to_use*max_n_iterations).
*
* random_seed32: a random seed to be used for input selection
* Out: proof_out_p: The pointer to newly-allocated proof whose bitvector will be initialized.
* random_seed32: random seed to be used for input selection
* Out: proof_out_p: pointer to newly-allocated proof whose bitvector will be initialized.
* In case of failure, the pointer will be NULL.
* input_index: The index of the actual input that is secretly mapped to the output
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_surjectionproof_allocate_initialized(
const secp256k1_context* ctx,
secp256k1_surjectionproof** proof_out_p,
const secp256k1_context *ctx,
secp256k1_surjectionproof **proof_out_p,
size_t *input_index,
const secp256k1_fixed_asset_tag* fixed_input_tags,
const secp256k1_fixed_asset_tag *fixed_input_tags,
const size_t n_input_tags,
const size_t n_input_tags_to_use,
const secp256k1_fixed_asset_tag* fixed_output_tag,
const secp256k1_fixed_asset_tag *fixed_output_tag,
const size_t n_max_iterations,
const unsigned char *random_seed32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(7);
@@ -215,14 +214,14 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_surjectionproof_allocat
* In: proof: pointer to secp256k1_surjectionproof struct
*/
SECP256K1_API void secp256k1_surjectionproof_destroy(
secp256k1_surjectionproof* proof
secp256k1_surjectionproof *proof
) SECP256K1_ARG_NONNULL(1);
/** Surjection proof generation function
* Returns 0: proof could not be created
* 1: proof was successfully created
*
* In: ctx: pointer to a context object, initialized for signing and verification
* In: ctx: pointer to a context object (not secp256k1_context_static)
* ephemeral_input_tags: the ephemeral asset tag of all inputs
* n_ephemeral_input_tags: the number of entries in the ephemeral_input_tags array
* ephemeral_output_tag: the ephemeral asset tag of the output
@@ -232,11 +231,11 @@ SECP256K1_API void secp256k1_surjectionproof_destroy(
* In/Out: proof: The produced surjection proof. Must have already gone through `secp256k1_surjectionproof_initialize`
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_surjectionproof_generate(
const secp256k1_context* ctx,
secp256k1_surjectionproof* proof,
const secp256k1_generator* ephemeral_input_tags,
const secp256k1_context *ctx,
secp256k1_surjectionproof *proof,
const secp256k1_generator *ephemeral_input_tags,
size_t n_ephemeral_input_tags,
const secp256k1_generator* ephemeral_output_tag,
const secp256k1_generator *ephemeral_output_tag,
size_t input_index,
const unsigned char *input_blinding_key,
const unsigned char *output_blinding_key
@@ -248,18 +247,18 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_surjectionproof_generat
* Returns 0: proof was invalid
* 1: proof was valid
*
* In: ctx: pointer to a context object, initialized for signing and verification
* In: ctx: pointer to a context object (not secp256k1_context_static)
* proof: proof to be verified
* ephemeral_input_tags: the ephemeral asset tag of all inputs
* n_ephemeral_input_tags: the number of entries in the ephemeral_input_tags array
* ephemeral_output_tag: the ephemeral asset tag of the output
*/
SECP256K1_API int secp256k1_surjectionproof_verify(
const secp256k1_context* ctx,
const secp256k1_surjectionproof* proof,
const secp256k1_generator* ephemeral_input_tags,
const secp256k1_context *ctx,
const secp256k1_surjectionproof *proof,
const secp256k1_generator *ephemeral_input_tags,
size_t n_ephemeral_input_tags,
const secp256k1_generator* ephemeral_output_tag
const secp256k1_generator *ephemeral_output_tag
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
#endif

View File

@@ -4,8 +4,8 @@
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
#ifndef _SECP256K1_WHITELIST_
#define _SECP256K1_WHITELIST_
#ifndef SECP256K1_WHITELIST_H
#define SECP256K1_WHITELIST_H
#include "secp256k1.h"
@@ -13,7 +13,7 @@
extern "C" {
#endif
#define SECP256K1_WHITELIST_MAX_N_KEYS 256
#define SECP256K1_WHITELIST_MAX_N_KEYS 255
/** Opaque data structure that holds a parsed whitelist proof
*
@@ -40,9 +40,9 @@ typedef struct {
/** Parse a whitelist signature
*
* Returns: 1 when the signature could be parsed, 0 otherwise.
* Args: ctx: a secp256k1 context object
* Out: sig: a pointer to a signature object
* In: input: a pointer to the array to parse
* Args: ctx: pointer to a context object
* Out: sig: pointer to a signature object
* In: input: pointer to the array to parse
* input_len: the length of the above array
*
* The signature must consist of a 1-byte n_keys value, followed by a 32-byte
@@ -58,7 +58,7 @@ typedef struct {
* to fail validation for any set of keys.
*/
SECP256K1_API int secp256k1_whitelist_signature_parse(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
secp256k1_whitelist_signature *sig,
const unsigned char *input,
size_t input_len
@@ -67,7 +67,7 @@ SECP256K1_API int secp256k1_whitelist_signature_parse(
/** Returns the number of keys a signature expects to have.
*
* Returns: the number of keys for the given signature
* In: sig: a pointer to a signature object
* In: sig: pointer to a signature object
*/
SECP256K1_API size_t secp256k1_whitelist_signature_n_keys(
const secp256k1_whitelist_signature *sig
@@ -76,15 +76,15 @@ SECP256K1_API size_t secp256k1_whitelist_signature_n_keys(
/** Serialize a whitelist signature
*
* Returns: 1
* Args: ctx: a secp256k1 context object
* Out: output64: a pointer to an array to store the serialization
* Args: ctx: pointer to a context object
* Out: output64: pointer to an array to store the serialization
* In/Out: output_len: length of the above array, updated with the actual serialized length
* In: sig: a pointer to an initialized signature object
* In: sig: pointer to an initialized signature object
*
* See secp256k1_whitelist_signature_parse for details about the encoding.
*/
SECP256K1_API int secp256k1_whitelist_signature_serialize(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
unsigned char *output,
size_t *output_len,
const secp256k1_whitelist_signature *sig
@@ -93,7 +93,7 @@ SECP256K1_API int secp256k1_whitelist_signature_serialize(
/** Compute a whitelist signature
* Returns 1: signature was successfully created
* 0: signature was not successfully created
* In: ctx: pointer to a context object, initialized for signing and verification
* In: ctx: pointer to a context object (not secp256k1_context_static)
* online_pubkeys: list of all online pubkeys
* offline_pubkeys: list of all offline pubkeys
* n_keys: the number of entries in each of the above two arrays
@@ -101,8 +101,6 @@ SECP256K1_API int secp256k1_whitelist_signature_serialize(
* online_seckey: the secret key to the signer's online pubkey
* summed_seckey: the secret key to the sum of (whitelisted key, signer's offline pubkey)
* index: the signer's index in the lists of keys
* noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used
* ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
* Out: sig: The produced signature.
*
* The signatures are of the list of all passed pubkeys in the order
@@ -113,23 +111,21 @@ SECP256K1_API int secp256k1_whitelist_signature_serialize(
* compressed serialization of the key.
*/
SECP256K1_API int secp256k1_whitelist_sign(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
secp256k1_whitelist_signature *sig,
const secp256k1_pubkey *online_pubkeys,
const secp256k1_pubkey *offline_pubkeys,
const size_t n_keys,
const secp256k1_pubkey *sub_pubkey,
const unsigned char *online_seckey,
const unsigned char *summed_seckey,
const size_t index,
secp256k1_nonce_function noncefp,
const void *noncedata
const unsigned char *summed_seckeyx,
const size_t index
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(8);
/** Verify a whitelist signature
* Returns 1: signature is valid
* 0: signature is not valid
* In: ctx: pointer to a context object, initialized for signing and verification
* In: ctx: pointer to a context object (not secp256k1_context_static)
* sig: the signature to be verified
* online_pubkeys: list of all online pubkeys
* offline_pubkeys: list of all offline pubkeys
@@ -137,7 +133,7 @@ SECP256K1_API int secp256k1_whitelist_sign(
* sub_pubkey: the key to be whitelisted
*/
SECP256K1_API int secp256k1_whitelist_verify(
const secp256k1_context* ctx,
const secp256k1_context *ctx,
const secp256k1_whitelist_signature *sig,
const secp256k1_pubkey *online_pubkeys,
const secp256k1_pubkey *offline_pubkeys,

View File

@@ -9,5 +9,4 @@ URL: https://github.com/bitcoin-core/secp256k1
Version: @PACKAGE_VERSION@
Cflags: -I${includedir}
Libs: -L${libdir} -lsecp256k1
Libs.private: @SECP_LIBS@

0
obj/.gitignore vendored
View File

View File

@@ -1,129 +1,156 @@
# Define field size and field
P = 2^256 - 2^32 - 977
F = GF(P)
BETA = F(0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee)
load("secp256k1_params.sage")
assert(BETA != F(1) and BETA^3 == F(1))
MAX_ORDER = 1000
# Set of (curve) orders we have encountered so far.
orders_done = set()
results = {}
first = True
# Map from (subgroup) orders to [b, int(gen.x), int(gen.y), gen, lambda] for those subgroups.
solutions = {}
# Iterate over curves of the form y^2 = x^3 + B.
for b in range(1, P):
# There are only 6 curves (up to isomorphism) of the form y^2=x^3+B. Stop once we have tried all.
# There are only 6 curves (up to isomorphism) of the form y^2 = x^3 + B. Stop once we have tried all.
if len(orders_done) == 6:
break
E = EllipticCurve(F, [0, b])
print("Analyzing curve y^2 = x^3 + %i" % b)
n = E.order()
# Skip curves with an order we've already tried
if n in orders_done:
print("- Isomorphic to earlier curve")
print()
continue
orders_done.add(n)
# Skip curves isomorphic to the real secp256k1
if n.is_pseudoprime():
print(" - Isomorphic to secp256k1")
assert E.is_isomorphic(C)
print("- Isomorphic to secp256k1")
print()
continue
print("- Finding subgroups")
print("- Finding prime subgroups")
# Find what prime subgroups exist
for f, _ in n.factor():
print("- Analyzing subgroup of order %i" % f)
# Skip subgroups of order >1000
if f < 4 or f > 1000:
print(" - Bad size")
continue
# Map from group_order to a set of independent generators for that order.
curve_gens = {}
# Iterate over X coordinates until we find one that is on the curve, has order f,
# and for which curve isomorphism exists that maps it to X coordinate 1.
for x in range(1, P):
# Skip X coordinates not on the curve, and construct the full point otherwise.
if not E.is_x_coord(x):
for g in E.gens():
# Find what prime subgroups of group generated by g exist.
g_order = g.order()
for f, _ in g.order().factor():
# Skip subgroups that have bad size.
if f < 4:
print(f" - Subgroup of size {f}: too small")
continue
G = E.lift_x(F(x))
print(" - Analyzing (multiples of) point with X=%i" % x)
# Skip points whose order is not a multiple of f. Project the point to have
# order f otherwise.
if (G.order() % f):
print(" - Bad order")
if f > MAX_ORDER:
print(f" - Subgroup of size {f}: too large")
continue
G = G * (G.order() // f)
# Construct a generator for that subgroup.
gen = g * (g_order // f)
assert(gen.order() == f)
# Add to set the minimal multiple of gen.
curve_gens.setdefault(f, set()).add(min([j*gen for j in range(1, f)]))
print(f" - Subgroup of size {f}: ok")
for f in sorted(curve_gens.keys()):
print(f"- Constructing group of order {f}")
cbrts = sorted([int(c) for c in Integers(f)(1).nth_root(3, all=true) if c != 1])
gens = list(curve_gens[f])
sol_count = 0
no_endo_count = 0
# Consider all non-zero linear combinations of the independent generators.
for j in range(1, f**len(gens)):
gen = sum(gens[k] * ((j // f**k) % f) for k in range(len(gens)))
assert not gen.is_zero()
assert (f*gen).is_zero()
# Find lambda for endomorphism. Skip if none can be found.
lam = None
for l in Integers(f)(1).nth_root(3, all=True):
if int(l)*G == E(BETA*G[0], G[1]):
lam = int(l)
for l in cbrts:
if l*gen == E(BETA*gen[0], gen[1]):
lam = l
break
if lam is None:
print(" - No endomorphism for this subgroup")
break
no_endo_count += 1
else:
sol_count += 1
solutions.setdefault(f, []).append((b, int(gen[0]), int(gen[1]), gen, lam))
# Now look for an isomorphism of the curve that gives this point an X
# coordinate equal to 1.
# If (x,y) is on y^2 = x^3 + b, then (a^2*x, a^3*y) is on y^2 = x^3 + a^6*b.
# So look for m=a^2=1/x.
m = F(1)/G[0]
if not m.is_square():
print(" - No curve isomorphism maps it to a point with X=1")
continue
a = m.sqrt()
rb = a^6*b
RE = EllipticCurve(F, [0, rb])
print(f" - Found {sol_count} generators (plus {no_endo_count} without endomorphism)")
# Use as generator twice the image of G under the above isormorphism.
# This means that generator*(1/2 mod f) will have X coordinate 1.
RG = RE(1, a^3*G[1]) * 2
# And even Y coordinate.
if int(RG[1]) % 2:
RG = -RG
assert(RG.order() == f)
assert(lam*RG == RE(BETA*RG[0], RG[1]))
print()
# We have found curve RE:y^2=x^3+rb with generator RG of order f. Remember it
results[f] = {"b": rb, "G": RG, "lambda": lam}
print(" - Found solution")
break
def output_generator(g, name):
print(f"#define {name} SECP256K1_GE_CONST(\\")
print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x,\\" % tuple((int(g[0]) >> (32 * (7 - i))) & 0xffffffff for i in range(4)))
print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x,\\" % tuple((int(g[0]) >> (32 * (7 - i))) & 0xffffffff for i in range(4, 8)))
print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x,\\" % tuple((int(g[1]) >> (32 * (7 - i))) & 0xffffffff for i in range(4)))
print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x\\" % tuple((int(g[1]) >> (32 * (7 - i))) & 0xffffffff for i in range(4, 8)))
print(")")
print("")
def output_b(b):
print(f"#define SECP256K1_B {int(b)}")
print("")
print("")
print("/* To be put in src/group_impl.h: */")
print()
print("To be put in src/group_impl.h:")
print()
print("/* Begin of section generated by sage/gen_exhaustive_groups.sage. */")
for f in sorted(solutions.keys()):
# Use as generator/2 the one with lowest b, and lowest (x, y) generator (interpreted as non-negative integers).
b, _, _, HALF_G, lam = min(solutions[f])
output_generator(2 * HALF_G, f"SECP256K1_G_ORDER_{f}")
print("/** Generator for secp256k1, value 'g' defined in")
print(" * \"Standards for Efficient Cryptography\" (SEC2) 2.7.1.")
print(" */")
output_generator(G, "SECP256K1_G")
print("/* These exhaustive group test orders and generators are chosen such that:")
print(" * - The field size is equal to that of secp256k1, so field code is the same.")
print(" * - The curve equation is of the form y^2=x^3+B for some small constant B.")
print(" * - The subgroup has a generator 2*P, where P.x is as small as possible.")
print(f" * - The subgroup has size less than {MAX_ORDER} to permit exhaustive testing.")
print(" * - The subgroup admits an endomorphism of the form lambda*(x,y) == (beta*x,y).")
print(" */")
print("#if defined(EXHAUSTIVE_TEST_ORDER)")
first = True
for f in sorted(results.keys()):
b = results[f]["b"]
G = results[f]["G"]
print("# %s EXHAUSTIVE_TEST_ORDER == %i" % ("if" if first else "elif", f))
for f in sorted(solutions.keys()):
b, _, _, _, lam = min(solutions[f])
print(f"# {'if' if first else 'elif'} EXHAUSTIVE_TEST_ORDER == {f}")
first = False
print("static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST(")
print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x," % tuple((int(G[0]) >> (32 * (7 - i))) & 0xffffffff for i in range(4)))
print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x," % tuple((int(G[0]) >> (32 * (7 - i))) & 0xffffffff for i in range(4, 8)))
print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x," % tuple((int(G[1]) >> (32 * (7 - i))) & 0xffffffff for i in range(4)))
print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x" % tuple((int(G[1]) >> (32 * (7 - i))) & 0xffffffff for i in range(4, 8)))
print(");")
print("static const secp256k1_fe secp256k1_fe_const_b = SECP256K1_FE_CONST(")
print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x," % tuple((int(b) >> (32 * (7 - i))) & 0xffffffff for i in range(4)))
print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x" % tuple((int(b) >> (32 * (7 - i))) & 0xffffffff for i in range(4, 8)))
print(");")
print()
print(f"static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G_ORDER_{f};")
output_b(b)
print()
print("# else")
print("# error No known generator for the specified exhaustive test group order.")
print("# endif")
print("#else")
print()
print("static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G;")
output_b(7)
print()
print("#endif")
print("/* End of section generated by sage/gen_exhaustive_groups.sage. */")
print("")
print("")
print("/* To be put in src/scalar_impl.h: */")
print()
print()
print("To be put in src/scalar_impl.h:")
print()
print("/* Begin of section generated by sage/gen_exhaustive_groups.sage. */")
first = True
for f in sorted(results.keys()):
lam = results[f]["lambda"]
for f in sorted(solutions.keys()):
_, _, _, _, lam = min(solutions[f])
print("# %s EXHAUSTIVE_TEST_ORDER == %i" % ("if" if first else "elif", f))
first = False
print("# define EXHAUSTIVE_TEST_LAMBDA %i" % lam)
print("# else")
print("# error No known lambda for the specified exhaustive test group order.")
print("# endif")
print("")
print("/* End of section generated by sage/gen_exhaustive_groups.sage. */")

View File

@@ -0,0 +1,114 @@
""" Generates the constants used in secp256k1_scalar_split_lambda.
See the comments for secp256k1_scalar_split_lambda in src/scalar_impl.h for detailed explanations.
"""
load("secp256k1_params.sage")
def inf_norm(v):
"""Returns the infinity norm of a vector."""
return max(map(abs, v))
def gauss_reduction(i1, i2):
v1, v2 = i1.copy(), i2.copy()
while True:
if inf_norm(v2) < inf_norm(v1):
v1, v2 = v2, v1
# This is essentially
# m = round((v1[0]*v2[0] + v1[1]*v2[1]) / (inf_norm(v1)**2))
# (rounding to the nearest integer) without relying on floating point arithmetic.
m = ((v1[0]*v2[0] + v1[1]*v2[1]) + (inf_norm(v1)**2) // 2) // (inf_norm(v1)**2)
if m == 0:
return v1, v2
v2[0] -= m*v1[0]
v2[1] -= m*v1[1]
def find_split_constants_gauss():
"""Find constants for secp256k1_scalar_split_lamdba using gauss reduction."""
(v11, v12), (v21, v22) = gauss_reduction([0, N], [1, int(LAMBDA)])
# We use related vectors in secp256k1_scalar_split_lambda.
A1, B1 = -v21, -v11
A2, B2 = v22, -v21
return A1, B1, A2, B2
def find_split_constants_explicit_tof():
"""Find constants for secp256k1_scalar_split_lamdba using the trace of Frobenius.
See Benjamin Smith: "Easy scalar decompositions for efficient scalar multiplication on
elliptic curves and genus 2 Jacobians" (https://eprint.iacr.org/2013/672), Example 2
"""
assert P % 3 == 1 # The paper says P % 3 == 2 but that appears to be a mistake, see [10].
assert C.j_invariant() == 0
t = C.trace_of_frobenius()
c = Integer(sqrt((4*P - t**2)/3))
A1 = Integer((t - c)/2 - 1)
B1 = c
A2 = Integer((t + c)/2 - 1)
B2 = Integer(1 - (t - c)/2)
# We use a negated b values in secp256k1_scalar_split_lambda.
B1, B2 = -B1, -B2
return A1, B1, A2, B2
A1, B1, A2, B2 = find_split_constants_explicit_tof()
# For extra fun, use an independent method to recompute the constants.
assert (A1, B1, A2, B2) == find_split_constants_gauss()
# PHI : Z[l] -> Z_n where phi(a + b*l) == a + b*lambda mod n.
def PHI(a,b):
return Z(a + LAMBDA*b)
# Check that (A1, B1) and (A2, B2) are in the kernel of PHI.
assert PHI(A1, B1) == Z(0)
assert PHI(A2, B2) == Z(0)
# Check that the parallelogram generated by (A1, A2) and (B1, B2)
# is a fundamental domain by containing exactly N points.
# Since the LHS is the determinant and N != 0, this also checks that
# (A1, A2) and (B1, B2) are linearly independent. By the previous
# assertions, (A1, A2) and (B1, B2) are a basis of the kernel.
assert A1*B2 - B1*A2 == N
# Check that their components are short enough.
assert (A1 + A2)/2 < sqrt(N)
assert B1 < sqrt(N)
assert B2 < sqrt(N)
G1 = round((2**384)*B2/N)
G2 = round((2**384)*(-B1)/N)
def rnddiv2(v):
if v & 1:
v += 1
return v >> 1
def scalar_lambda_split(k):
"""Equivalent to secp256k1_scalar_lambda_split()."""
c1 = rnddiv2((k * G1) >> 383)
c2 = rnddiv2((k * G2) >> 383)
c1 = (c1 * -B1) % N
c2 = (c2 * -B2) % N
r2 = (c1 + c2) % N
r1 = (k + r2 * -LAMBDA) % N
return (r1, r2)
# The result of scalar_lambda_split can depend on the representation of k (mod n).
SPECIAL = (2**383) // G2 + 1
assert scalar_lambda_split(SPECIAL) != scalar_lambda_split(SPECIAL + N)
print(' A1 =', hex(A1))
print(' -B1 =', hex(-B1))
print(' A2 =', hex(A2))
print(' -B2 =', hex(-B2))
print(' =', hex(Z(-B2)))
print(' -LAMBDA =', hex(-LAMBDA))
print(' G1 =', hex(G1))
print(' G2 =', hex(G2))

View File

@@ -42,7 +42,7 @@
# as we assume that all constraints in it are complementary with each other.
#
# Based on the sage verification scripts used in the Explicit-Formulas Database
# by Tanja Lange and others, see http://hyperelliptic.org/EFD
# by Tanja Lange and others, see https://hyperelliptic.org/EFD
class fastfrac:
"""Fractions over rings."""
@@ -164,6 +164,9 @@ class constraints:
def negate(self):
return constraints(zero=self.nonzero, nonzero=self.zero)
def map(self, fun):
return constraints(zero={fun(k): v for k, v in self.zero.items()}, nonzero={fun(k): v for k, v in self.nonzero.items()})
def __add__(self, other):
zero = self.zero.copy()
zero.update(other.zero)
@@ -177,6 +180,30 @@ class constraints:
def __repr__(self):
return "%s" % self
def normalize_factor(p):
"""Normalizes the sign of primitive polynomials (as returned by factor())
This function ensures that the polynomial has a positive leading coefficient.
This is necessary because recent sage versions (starting with v9.3 or v9.4,
we don't know) are inconsistent about the placement of the minus sign in
polynomial factorizations:
```
sage: R.<ax,bx,ay,by,Az,Bz,Ai,Bi> = PolynomialRing(QQ,8,order='invlex')
sage: R((-2 * (bx - ax)) ^ 1).factor()
(-2) * (bx - ax)
sage: R((-2 * (bx - ax)) ^ 2).factor()
(4) * (-bx + ax)^2
sage: R((-2 * (bx - ax)) ^ 3).factor()
(8) * (-bx + ax)^3
```
"""
# Assert p is not 0 and that its non-zero coefficients are coprime.
# (We could just work with the primitive part p/p.content() but we want to be
# aware if factor() does not return a primitive part in future sage versions.)
assert p.content() == 1
# Ensure that the first non-zero coefficient is positive.
return p if p.lc() > 0 else -p
def conflicts(R, con):
"""Check whether any of the passed non-zero assumptions is implied by the zero assumptions"""
@@ -204,10 +231,10 @@ def get_nonzero_set(R, assume):
nonzero = set()
for nz in map(numerator, assume.nonzero):
for (f,n) in nz.factor():
nonzero.add(f)
nonzero.add(normalize_factor(f))
rnz = zero.reduce(nz)
for (f,n) in rnz.factor():
nonzero.add(f)
nonzero.add(normalize_factor(f))
return nonzero
@@ -222,27 +249,27 @@ def prove_nonzero(R, exprs, assume):
return (False, [exprs[expr]])
allexprs = reduce(lambda a,b: numerator(a)*numerator(b), exprs, 1)
for (f, n) in allexprs.factor():
if f not in nonzero:
if normalize_factor(f) not in nonzero:
ok = False
if ok:
return (True, None)
ok = True
for (f, n) in zero.reduce(numerator(allexprs)).factor():
if f not in nonzero:
for (f, n) in zero.reduce(allexprs).factor():
if normalize_factor(f) not in nonzero:
ok = False
if ok:
return (True, None)
ok = True
for expr in exprs:
for (f,n) in numerator(expr).factor():
if f not in nonzero:
if normalize_factor(f) not in nonzero:
ok = False
if ok:
return (True, None)
ok = True
for expr in exprs:
for (f,n) in zero.reduce(numerator(expr)).factor():
if f not in nonzero:
if normalize_factor(f) not in nonzero:
expl.add(exprs[expr])
if expl:
return (False, list(expl))
@@ -254,7 +281,7 @@ def prove_zero(R, exprs, assume):
"""Check whether all of the passed expressions are provably zero, given assumptions"""
r, e = prove_nonzero(R, dict(map(lambda x: (fastfrac(R, x.bot, 1), exprs[x]), exprs)), assume)
if not r:
return (False, map(lambda x: "Possibly zero denominator: %s" % x, e))
return (False, list(map(lambda x: "Possibly zero denominator: %s" % x, e)))
zero = R.ideal(list(map(numerator, assume.zero)))
nonzero = prod(x for x in assume.nonzero)
expl = []
@@ -279,8 +306,8 @@ def describe_extra(R, assume, assumeExtra):
if base not in zero:
add = []
for (f, n) in numerator(base).factor():
if f not in nonzero:
add += ["%s" % f]
if normalize_factor(f) not in nonzero:
add += ["%s" % normalize_factor(f)]
if add:
ret.add((" * ".join(add)) + " = 0 [%s]" % assumeExtra.zero[base])
# Iterate over the extra nonzero expressions
@@ -288,8 +315,8 @@ def describe_extra(R, assume, assumeExtra):
nzr = zeroextra.reduce(numerator(nz))
if nzr not in zeroextra:
for (f,n) in nzr.factor():
if zeroextra.reduce(f) not in nonzero:
ret.add("%s != 0" % zeroextra.reduce(f))
if normalize_factor(zeroextra.reduce(f)) not in nonzero:
ret.add("%s != 0" % normalize_factor(zeroextra.reduce(f)))
return ", ".join(x for x in ret)
@@ -299,22 +326,21 @@ def check_symbolic(R, assumeLaw, assumeAssert, assumeBranch, require):
if conflicts(R, assume):
# This formula does not apply
return None
return (True, None)
describe = describe_extra(R, assumeLaw + assumeBranch, assumeAssert)
if describe != "":
describe = " (assuming " + describe + ")"
ok, msg = prove_zero(R, require.zero, assume)
if not ok:
return "FAIL, %s fails (assuming %s)" % (str(msg), describe)
return (False, "FAIL, %s fails%s" % (str(msg), describe))
res, expl = prove_nonzero(R, require.nonzero, assume)
if not res:
return "FAIL, %s fails (assuming %s)" % (str(expl), describe)
return (False, "FAIL, %s fails%s" % (str(expl), describe))
if describe != "":
return "OK (assuming %s)" % describe
else:
return "OK"
return (True, "OK%s" % describe)
def concrete_verify(c):

View File

@@ -8,25 +8,20 @@ load("weierstrass_prover.sage")
def formula_secp256k1_gej_double_var(a):
"""libsecp256k1's secp256k1_gej_double_var, used by various addition functions"""
rz = a.Z * a.Y
rz = rz * 2
t1 = a.X^2
t1 = t1 * 3
t2 = t1^2
t3 = a.Y^2
t3 = t3 * 2
t4 = t3^2
t4 = t4 * 2
t3 = t3 * a.X
rx = t3
rx = rx * 4
rx = -rx
rx = rx + t2
t2 = -t2
t3 = t3 * 6
t3 = t3 + t2
ry = t1 * t3
t2 = -t4
ry = ry + t2
s = a.Y^2
l = a.X^2
l = l * 3
l = l / 2
t = -s
t = t * a.X
rx = l^2
rx = rx + t
rx = rx + t
s = s^2
t = t + rx
ry = t * l
ry = ry + s
ry = -ry
return jacobianpoint(rx, ry, rz)
def formula_secp256k1_gej_add_var(branch, a, b):
@@ -45,29 +40,26 @@ def formula_secp256k1_gej_add_var(branch, a, b):
s2 = s2 * a.Z
h = -u1
h = h + u2
i = -s1
i = i + s2
i = -s2
i = i + s1
if branch == 2:
r = formula_secp256k1_gej_double_var(a)
return (constraints(), constraints(zero={h : 'h=0', i : 'i=0', a.Infinity : 'a_finite', b.Infinity : 'b_finite'}), r)
if branch == 3:
return (constraints(), constraints(zero={h : 'h=0', a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={i : 'i!=0'}), point_at_infinity())
i2 = i^2
t = h * b.Z
rz = a.Z * t
h2 = h^2
h2 = -h2
h3 = h2 * h
h = h * b.Z
rz = a.Z * h
t = u1 * h2
rx = t
rx = rx * 2
rx = i^2
rx = rx + h3
rx = -rx
rx = rx + i2
ry = -rx
ry = ry + t
ry = ry * i
rx = rx + t
rx = rx + t
t = t + rx
ry = t * i
h3 = h3 * s1
h3 = -h3
ry = ry + h3
return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz))
@@ -85,28 +77,25 @@ def formula_secp256k1_gej_add_ge_var(branch, a, b):
s2 = s2 * a.Z
h = -u1
h = h + u2
i = -s1
i = i + s2
i = -s2
i = i + s1
if (branch == 2):
r = formula_secp256k1_gej_double_var(a)
return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0', i : 'i=0'}), r)
if (branch == 3):
return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0'}, nonzero={i : 'i!=0'}), point_at_infinity())
i2 = i^2
h2 = h^2
h3 = h * h2
rz = a.Z * h
h2 = h^2
h2 = -h2
h3 = h2 * h
t = u1 * h2
rx = t
rx = rx * 2
rx = i^2
rx = rx + h3
rx = -rx
rx = rx + i2
ry = -rx
ry = ry + t
ry = ry * i
rx = rx + t
rx = rx + t
t = t + rx
ry = t * i
h3 = h3 * s1
h3 = -h3
ry = ry + h3
return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz))
@@ -114,14 +103,15 @@ def formula_secp256k1_gej_add_zinv_var(branch, a, b):
"""libsecp256k1's secp256k1_gej_add_zinv_var"""
bzinv = b.Z^(-1)
if branch == 0:
return (constraints(), constraints(nonzero={b.Infinity : 'b_infinite'}), a)
if branch == 1:
rinf = b.Infinity
bzinv2 = bzinv^2
bzinv3 = bzinv2 * bzinv
rx = b.X * bzinv2
ry = b.Y * bzinv3
rz = 1
return (constraints(), constraints(zero={b.Infinity : 'b_finite'}, nonzero={a.Infinity : 'a_infinite'}), jacobianpoint(rx, ry, rz))
return (constraints(), constraints(nonzero={a.Infinity : 'a_infinite'}), jacobianpoint(rx, ry, rz, rinf))
if branch == 1:
return (constraints(), constraints(zero={a.Infinity : 'a_finite'}, nonzero={b.Infinity : 'b_infinite'}), a)
azz = a.Z * bzinv
z12 = azz^2
u1 = a.X
@@ -131,29 +121,25 @@ def formula_secp256k1_gej_add_zinv_var(branch, a, b):
s2 = s2 * azz
h = -u1
h = h + u2
i = -s1
i = i + s2
i = -s2
i = i + s1
if branch == 2:
r = formula_secp256k1_gej_double_var(a)
return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0', i : 'i=0'}), r)
if branch == 3:
return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0'}, nonzero={i : 'i!=0'}), point_at_infinity())
i2 = i^2
rz = a.Z * h
h2 = h^2
h3 = h * h2
rz = a.Z
rz = rz * h
h2 = -h2
h3 = h2 * h
t = u1 * h2
rx = t
rx = rx * 2
rx = i^2
rx = rx + h3
rx = -rx
rx = rx + i2
ry = -rx
ry = ry + t
ry = ry * i
rx = rx + t
rx = rx + t
t = t + rx
ry = t * i
h3 = h3 * s1
h3 = -h3
ry = ry + h3
return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz))
@@ -162,7 +148,7 @@ def formula_secp256k1_gej_add_ge(branch, a, b):
zeroes = {}
nonzeroes = {}
a_infinity = False
if (branch & 4) != 0:
if (branch & 2) != 0:
nonzeroes.update({a.Infinity : 'a_infinite'})
a_infinity = True
else:
@@ -181,15 +167,11 @@ def formula_secp256k1_gej_add_ge(branch, a, b):
m_alt = -u2
tt = u1 * m_alt
rr = rr + tt
degenerate = (branch & 3) == 3
if (branch & 1) != 0:
degenerate = (branch & 1) != 0
if degenerate:
zeroes.update({m : 'm_zero'})
else:
nonzeroes.update({m : 'm_nonzero'})
if (branch & 2) != 0:
zeroes.update({rr : 'rr_zero'})
else:
nonzeroes.update({rr : 'rr_nonzero'})
rr_alt = s1
rr_alt = rr_alt * 2
m_alt = m_alt + u1
@@ -197,21 +179,13 @@ def formula_secp256k1_gej_add_ge(branch, a, b):
rr_alt = rr
m_alt = m
n = m_alt^2
q = n * t
q = -t
q = q * n
n = n^2
if degenerate:
n = m
t = rr_alt^2
rz = a.Z * m_alt
infinity = False
if (branch & 8) != 0:
if not a_infinity:
infinity = True
zeroes.update({rz : 'r.z=0'})
else:
nonzeroes.update({rz : 'r.z!=0'})
rz = rz * 2
q = -q
t = t + q
rx = t
t = t * 2
@@ -219,14 +193,16 @@ def formula_secp256k1_gej_add_ge(branch, a, b):
t = t * rr_alt
t = t + n
ry = -t
rx = rx * 4
ry = ry * 4
ry = ry / 2
if a_infinity:
rx = b.X
ry = b.Y
rz = 1
if infinity:
if (branch & 4) != 0:
zeroes.update({rz : 'r.z = 0'})
return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zeroes, nonzero=nonzeroes), point_at_infinity())
else:
nonzeroes.update({rz : 'r.z != 0'})
return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zeroes, nonzero=nonzeroes), jacobianpoint(rx, ry, rz))
def formula_secp256k1_gej_add_ge_old(branch, a, b):
@@ -292,15 +268,18 @@ def formula_secp256k1_gej_add_ge_old(branch, a, b):
return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zero, nonzero=nonzero), jacobianpoint(rx, ry, rz))
if __name__ == "__main__":
check_symbolic_jacobian_weierstrass("secp256k1_gej_add_var", 0, 7, 5, formula_secp256k1_gej_add_var)
check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge_var", 0, 7, 5, formula_secp256k1_gej_add_ge_var)
check_symbolic_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 5, formula_secp256k1_gej_add_zinv_var)
check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 16, formula_secp256k1_gej_add_ge)
check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge_old [should fail]", 0, 7, 4, formula_secp256k1_gej_add_ge_old)
success = True
success = success & check_symbolic_jacobian_weierstrass("secp256k1_gej_add_var", 0, 7, 5, formula_secp256k1_gej_add_var)
success = success & check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge_var", 0, 7, 5, formula_secp256k1_gej_add_ge_var)
success = success & check_symbolic_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 5, formula_secp256k1_gej_add_zinv_var)
success = success & check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 8, formula_secp256k1_gej_add_ge)
success = success & (not check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge_old [should fail]", 0, 7, 4, formula_secp256k1_gej_add_ge_old))
if len(sys.argv) >= 2 and sys.argv[1] == "--exhaustive":
check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_var", 0, 7, 5, formula_secp256k1_gej_add_var, 43)
check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge_var", 0, 7, 5, formula_secp256k1_gej_add_ge_var, 43)
check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 5, formula_secp256k1_gej_add_zinv_var, 43)
check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 16, formula_secp256k1_gej_add_ge, 43)
check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge_old [should fail]", 0, 7, 4, formula_secp256k1_gej_add_ge_old, 43)
success = success & check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_var", 0, 7, 5, formula_secp256k1_gej_add_var, 43)
success = success & check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge_var", 0, 7, 5, formula_secp256k1_gej_add_ge_var, 43)
success = success & check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 5, formula_secp256k1_gej_add_zinv_var, 43)
success = success & check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 8, formula_secp256k1_gej_add_ge, 43)
success = success & (not check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge_old [should fail]", 0, 7, 4, formula_secp256k1_gej_add_ge_old, 43))
sys.exit(int(not success))

View File

@@ -0,0 +1,39 @@
"""Prime order of finite field underlying secp256k1 (2^256 - 2^32 - 977)"""
P = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
"""Finite field underlying secp256k1"""
F = FiniteField(P)
"""Elliptic curve secp256k1: y^2 = x^3 + 7"""
C = EllipticCurve([F(0), F(7)])
"""Base point of secp256k1"""
G = C.lift_x(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798)
if int(G[1]) & 1:
# G.y is even
G = -G
"""Prime order of secp256k1"""
N = C.order()
"""Finite field of scalars of secp256k1"""
Z = FiniteField(N)
""" Beta value of secp256k1 non-trivial endomorphism: lambda * (x, y) = (beta * x, y)"""
BETA = F(2)^((P-1)/3)
""" Lambda value of secp256k1 non-trivial endomorphism: lambda * (x, y) = (beta * x, y)"""
LAMBDA = Z(3)^((N-1)/3)
assert is_prime(P)
assert is_prime(N)
assert BETA != F(1)
assert BETA^3 == F(1)
assert BETA^2 + BETA + 1 == 0
assert LAMBDA != Z(1)
assert LAMBDA^3 == Z(1)
assert LAMBDA^2 + LAMBDA + 1 == 0
assert Integer(LAMBDA)*G == C(BETA*G[0], G[1])

View File

@@ -184,6 +184,7 @@ def check_exhaustive_jacobian_weierstrass(name, A, B, branches, formula, p):
if r:
points.append(point)
ret = True
for za in range(1, p):
for zb in range(1, p):
for pa in points:
@@ -211,8 +212,11 @@ def check_exhaustive_jacobian_weierstrass(name, A, B, branches, formula, p):
match = True
r, e = concrete_verify(require)
if not r:
ret = False
print(" failure in branch %i for (%s,%s,%s,%s) + (%s,%s,%s,%s) = (%s,%s,%s,%s): %s" % (branch, pA.X, pA.Y, pA.Z, pA.Infinity, pB.X, pB.Y, pB.Z, pB.Infinity, pC.X, pC.Y, pC.Z, pC.Infinity, e))
print()
return ret
def check_symbolic_function(R, assumeAssert, assumeBranch, f, A, B, pa, pb, pA, pB, pC):
@@ -244,15 +248,21 @@ def check_symbolic_jacobian_weierstrass(name, A, B, branches, formula):
print("Formula " + name + ":")
count = 0
ret = True
for branch in range(branches):
assumeFormula, assumeBranch, pC = formula(branch, pA, pB)
assumeBranch = assumeBranch.map(lift)
assumeFormula = assumeFormula.map(lift)
pC.X = lift(pC.X)
pC.Y = lift(pC.Y)
pC.Z = lift(pC.Z)
pC.Infinity = lift(pC.Infinity)
for key in laws_jacobian_weierstrass:
res[key].append((check_symbolic_function(R, assumeFormula, assumeBranch, laws_jacobian_weierstrass[key], A, B, pa, pb, pA, pB, pC), branch))
success, msg = check_symbolic_function(R, assumeFormula, assumeBranch, laws_jacobian_weierstrass[key], A, B, pa, pb, pA, pB, pC)
if not success:
ret = False
res[key].append((msg, branch))
for key in res:
print(" %s:" % key)
@@ -262,3 +272,4 @@ def check_symbolic_jacobian_weierstrass(name, A, B, branches, formula):
print(" branch %i: %s" % (x[1], x[0]))
print()
return ret

198
src/CMakeLists.txt Normal file
View File

@@ -0,0 +1,198 @@
# Must be included before CMAKE_INSTALL_INCLUDEDIR is used.
include(GNUInstallDirs)
add_library(secp256k1_precomputed OBJECT EXCLUDE_FROM_ALL
precomputed_ecmult.c
precomputed_ecmult_gen.c
)
# Add objects explicitly rather than linking to the object libs to keep them
# from being exported.
add_library(secp256k1 secp256k1.c $<TARGET_OBJECTS:secp256k1_precomputed>)
add_library(secp256k1_asm INTERFACE)
if(SECP256K1_ASM STREQUAL "arm32")
add_library(secp256k1_asm_arm OBJECT EXCLUDE_FROM_ALL)
target_sources(secp256k1_asm_arm PUBLIC
asm/field_10x26_arm.s
)
target_sources(secp256k1 PRIVATE $<TARGET_OBJECTS:secp256k1_asm_arm>)
target_link_libraries(secp256k1_asm INTERFACE secp256k1_asm_arm)
endif()
if(WIN32)
# Define our export symbol only for shared libs.
set_target_properties(secp256k1 PROPERTIES DEFINE_SYMBOL SECP256K1_DLL_EXPORT)
target_compile_definitions(secp256k1 INTERFACE $<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:SECP256K1_STATIC>)
endif()
# Object libs don't know if they're being built for a shared or static lib.
# Grab the PIC property from secp256k1 which knows.
get_target_property(use_pic secp256k1 POSITION_INDEPENDENT_CODE)
set_target_properties(secp256k1_precomputed PROPERTIES POSITION_INDEPENDENT_CODE ${use_pic})
target_include_directories(secp256k1 INTERFACE
# Add the include path for parent projects so that they don't have to manually add it.
$<BUILD_INTERFACE:$<$<NOT:$<BOOL:${PROJECT_IS_TOP_LEVEL}>>:${PROJECT_SOURCE_DIR}/include>>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
# This emulates Libtool to make sure Libtool and CMake agree on the ABI version,
# see below "Calculate the version variables" in build-aux/ltmain.sh.
math(EXPR ${PROJECT_NAME}_soversion "${${PROJECT_NAME}_LIB_VERSION_CURRENT} - ${${PROJECT_NAME}_LIB_VERSION_AGE}")
set_target_properties(secp256k1 PROPERTIES
SOVERSION ${${PROJECT_NAME}_soversion}
)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set_target_properties(secp256k1 PROPERTIES
VERSION ${${PROJECT_NAME}_soversion}.${${PROJECT_NAME}_LIB_VERSION_AGE}.${${PROJECT_NAME}_LIB_VERSION_REVISION}
)
elseif(APPLE)
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.17)
math(EXPR ${PROJECT_NAME}_compatibility_version "${${PROJECT_NAME}_LIB_VERSION_CURRENT} + 1")
set_target_properties(secp256k1 PROPERTIES
MACHO_COMPATIBILITY_VERSION ${${PROJECT_NAME}_compatibility_version}
MACHO_CURRENT_VERSION ${${PROJECT_NAME}_compatibility_version}.${${PROJECT_NAME}_LIB_VERSION_REVISION}
)
unset(${PROJECT_NAME}_compatibility_version)
elseif(BUILD_SHARED_LIBS)
message(WARNING
"The 'compatibility version' and 'current version' values of the DYLIB "
"will diverge from the values set by the GNU Libtool. To ensure "
"compatibility, it is recommended to upgrade CMake to at least version 3.17."
)
endif()
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(${PROJECT_NAME}_windows "secp256k1")
if(MSVC)
set(${PROJECT_NAME}_windows "${PROJECT_NAME}")
endif()
set_target_properties(secp256k1 PROPERTIES
ARCHIVE_OUTPUT_NAME "${${PROJECT_NAME}_windows}"
RUNTIME_OUTPUT_NAME "${${PROJECT_NAME}_windows}-${${PROJECT_NAME}_soversion}"
)
unset(${PROJECT_NAME}_windows)
endif()
unset(${PROJECT_NAME}_soversion)
if(SECP256K1_BUILD_BENCHMARK)
add_executable(bench bench.c)
target_link_libraries(bench secp256k1)
add_executable(bench_internal bench_internal.c)
target_link_libraries(bench_internal secp256k1_precomputed secp256k1_asm)
add_executable(bench_ecmult bench_ecmult.c)
target_link_libraries(bench_ecmult secp256k1_precomputed secp256k1_asm)
endif()
if(SECP256K1_BUILD_TESTS)
add_executable(noverify_tests tests.c)
target_link_libraries(noverify_tests secp256k1_precomputed secp256k1_asm)
add_test(NAME noverify_tests COMMAND noverify_tests)
if(NOT CMAKE_BUILD_TYPE STREQUAL "Coverage")
add_executable(tests tests.c)
target_compile_definitions(tests PRIVATE VERIFY)
target_link_libraries(tests secp256k1_precomputed secp256k1_asm)
add_test(NAME tests COMMAND tests)
endif()
endif()
if(SECP256K1_BUILD_EXHAUSTIVE_TESTS)
# Note: do not include secp256k1_precomputed in exhaustive_tests (it uses runtime-generated tables).
add_executable(exhaustive_tests tests_exhaustive.c)
target_link_libraries(exhaustive_tests secp256k1_asm)
target_compile_definitions(exhaustive_tests PRIVATE $<$<NOT:$<CONFIG:Coverage>>:VERIFY>)
add_test(NAME exhaustive_tests COMMAND exhaustive_tests)
endif()
if(SECP256K1_BUILD_CTIME_TESTS)
add_executable(ctime_tests ctime_tests.c)
target_link_libraries(ctime_tests secp256k1)
endif()
if(SECP256K1_INSTALL)
install(TARGETS secp256k1
EXPORT ${PROJECT_NAME}-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
set(${PROJECT_NAME}_headers
"${PROJECT_SOURCE_DIR}/include/secp256k1.h"
"${PROJECT_SOURCE_DIR}/include/secp256k1_preallocated.h"
)
if(SECP256K1_ENABLE_MODULE_BPPP)
list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_bppp.h")
endif()
if(SECP256K1_ENABLE_MODULE_ECDSA_S2C)
list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_ecdsa_s2c.h")
endif()
if(SECP256K1_ENABLE_MODULE_ECDSA_ADAPTOR)
list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_ecdsa_adaptor.h")
endif()
if(SECP256K1_ENABLE_MODULE_MUSIG)
list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_musig.h")
endif()
if(SECP256K1_ENABLE_MODULE_WHITELIST)
list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_whitelist.h")
endif()
if(SECP256K1_ENABLE_MODULE_SURJECTIONPROOF)
list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_surjectionproof.h")
endif()
if(SECP256K1_ENABLE_MODULE_RANGEPROOF)
list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_rangeproof.h")
endif()
if(SECP256K1_ENABLE_MODULE_GENERATOR)
list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_generator.h")
endif()
if(SECP256K1_ENABLE_MODULE_ECDH)
list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_ecdh.h")
endif()
if(SECP256K1_ENABLE_MODULE_RECOVERY)
list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_recovery.h")
endif()
if(SECP256K1_ENABLE_MODULE_EXTRAKEYS)
list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_extrakeys.h")
endif()
if(SECP256K1_ENABLE_MODULE_SCHNORRSIG)
list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_schnorrsig.h")
endif()
if(SECP256K1_ENABLE_MODULE_ELLSWIFT)
list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_ellswift.h")
endif()
install(FILES ${${PROJECT_NAME}_headers}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(EXPORT ${PROJECT_NAME}-targets
FILE ${PROJECT_NAME}-targets.cmake
NAMESPACE ${PROJECT_NAME}::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
)
include(CMakePackageConfigHelpers)
configure_package_config_file(
${PROJECT_SOURCE_DIR}/cmake/config.cmake.in
${PROJECT_NAME}-config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
NO_SET_AND_CHECK_MACRO
)
write_basic_package_version_file(${PROJECT_NAME}-config-version.cmake
COMPATIBILITY SameMinorVersion
)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
)
include(GeneratePkgConfigFile)
generate_pkg_config_file(${PROJECT_SOURCE_DIR}/libsecp256k1.pc.in)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
)
endif()

View File

@@ -1,9 +1,9 @@
@ vim: set tabstop=8 softtabstop=8 shiftwidth=8 noexpandtab syntax=armasm:
/**********************************************************************
* Copyright (c) 2014 Wladimir J. van der Laan *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
/***********************************************************************
* Copyright (c) 2014 Wladimir J. van der Laan *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
/*
ARM implementation of field_10x26 inner loops.
@@ -29,6 +29,7 @@ Note:
.align 2
.global secp256k1_fe_mul_inner
.type secp256k1_fe_mul_inner, %function
.hidden secp256k1_fe_mul_inner
@ Arguments:
@ r0 r Restrict: can overlap with a, not with b
@ r1 a
@@ -516,6 +517,7 @@ secp256k1_fe_mul_inner:
.align 2
.global secp256k1_fe_sqr_inner
.type secp256k1_fe_sqr_inner, %function
.hidden secp256k1_fe_sqr_inner
@ Arguments:
@ r0 r Can overlap with a
@ r1 a
@@ -911,3 +913,4 @@ secp256k1_fe_sqr_inner:
ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, pc}
.size secp256k1_fe_sqr_inner, .-secp256k1_fe_sqr_inner
.section .note.GNU-stack,"",%progbits

View File

@@ -1,8 +1,8 @@
/**********************************************************************
* Copyright (c) 2020 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
/***********************************************************************
* Copyright (c) 2020 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#ifndef SECP256K1_ASSUMPTIONS_H
#define SECP256K1_ASSUMPTIONS_H
@@ -10,71 +10,78 @@
#include <limits.h>
#include "util.h"
#if defined(SECP256K1_INT128_NATIVE)
#include "int128_native.h"
#endif
/* This library, like most software, relies on a number of compiler implementation defined (but not undefined)
behaviours. Although the behaviours we require are essentially universal we test them specifically here to
reduce the odds of experiencing an unwelcome surprise.
*/
struct secp256k1_assumption_checker {
/* This uses a trick to implement a static assertion in C89: a type with an array of negative size is not
allowed. */
int dummy_array[(
/* Bytes are 8 bits. */
(CHAR_BIT == 8) &&
#if defined(__has_attribute)
# if __has_attribute(__unavailable__)
__attribute__((__unavailable__("Don't call this function. It only exists because STATIC_ASSERT cannot be used outside a function.")))
# endif
#endif
static void secp256k1_assumption_checker(void) {
/* Bytes are 8 bits. */
STATIC_ASSERT(CHAR_BIT == 8);
/* No integer promotion for uint32_t. This ensures that we can multiply uintXX_t values where XX >= 32
without signed overflow, which would be undefined behaviour. */
(UINT_MAX <= UINT32_MAX) &&
/* No integer promotion for uint32_t. This ensures that we can multiply uintXX_t values where XX >= 32
without signed overflow, which would be undefined behaviour. */
STATIC_ASSERT(UINT_MAX <= UINT32_MAX);
/* Conversions from unsigned to signed outside of the bounds of the signed type are
implementation-defined. Verify that they function as reinterpreting the lower
bits of the input in two's complement notation. Do this for conversions:
- from uint(N)_t to int(N)_t with negative result
- from uint(2N)_t to int(N)_t with negative result
- from int(2N)_t to int(N)_t with negative result
- from int(2N)_t to int(N)_t with positive result */
/* Conversions from unsigned to signed outside of the bounds of the signed type are
implementation-defined. Verify that they function as reinterpreting the lower
bits of the input in two's complement notation. Do this for conversions:
- from uint(N)_t to int(N)_t with negative result
- from uint(2N)_t to int(N)_t with negative result
- from int(2N)_t to int(N)_t with negative result
- from int(2N)_t to int(N)_t with positive result */
/* To int8_t. */
((int8_t)(uint8_t)0xAB == (int8_t)-(int8_t)0x55) &&
((int8_t)(uint16_t)0xABCD == (int8_t)-(int8_t)0x33) &&
((int8_t)(int16_t)(uint16_t)0xCDEF == (int8_t)(uint8_t)0xEF) &&
((int8_t)(int16_t)(uint16_t)0x9234 == (int8_t)(uint8_t)0x34) &&
/* To int8_t. */
STATIC_ASSERT(((int8_t)(uint8_t)0xAB == (int8_t)-(int8_t)0x55));
STATIC_ASSERT((int8_t)(uint16_t)0xABCD == (int8_t)-(int8_t)0x33);
STATIC_ASSERT((int8_t)(int16_t)(uint16_t)0xCDEF == (int8_t)(uint8_t)0xEF);
STATIC_ASSERT((int8_t)(int16_t)(uint16_t)0x9234 == (int8_t)(uint8_t)0x34);
/* To int16_t. */
((int16_t)(uint16_t)0xBCDE == (int16_t)-(int16_t)0x4322) &&
((int16_t)(uint32_t)0xA1B2C3D4 == (int16_t)-(int16_t)0x3C2C) &&
((int16_t)(int32_t)(uint32_t)0xC1D2E3F4 == (int16_t)(uint16_t)0xE3F4) &&
((int16_t)(int32_t)(uint32_t)0x92345678 == (int16_t)(uint16_t)0x5678) &&
/* To int16_t. */
STATIC_ASSERT((int16_t)(uint16_t)0xBCDE == (int16_t)-(int16_t)0x4322);
STATIC_ASSERT((int16_t)(uint32_t)0xA1B2C3D4 == (int16_t)-(int16_t)0x3C2C);
STATIC_ASSERT((int16_t)(int32_t)(uint32_t)0xC1D2E3F4 == (int16_t)(uint16_t)0xE3F4);
STATIC_ASSERT((int16_t)(int32_t)(uint32_t)0x92345678 == (int16_t)(uint16_t)0x5678);
/* To int32_t. */
((int32_t)(uint32_t)0xB2C3D4E5 == (int32_t)-(int32_t)0x4D3C2B1B) &&
((int32_t)(uint64_t)0xA123B456C789D012ULL == (int32_t)-(int32_t)0x38762FEE) &&
((int32_t)(int64_t)(uint64_t)0xC1D2E3F4A5B6C7D8ULL == (int32_t)(uint32_t)0xA5B6C7D8) &&
((int32_t)(int64_t)(uint64_t)0xABCDEF0123456789ULL == (int32_t)(uint32_t)0x23456789) &&
/* To int32_t. */
STATIC_ASSERT((int32_t)(uint32_t)0xB2C3D4E5 == (int32_t)-(int32_t)0x4D3C2B1B);
STATIC_ASSERT((int32_t)(uint64_t)0xA123B456C789D012ULL == (int32_t)-(int32_t)0x38762FEE);
STATIC_ASSERT((int32_t)(int64_t)(uint64_t)0xC1D2E3F4A5B6C7D8ULL == (int32_t)(uint32_t)0xA5B6C7D8);
STATIC_ASSERT((int32_t)(int64_t)(uint64_t)0xABCDEF0123456789ULL == (int32_t)(uint32_t)0x23456789);
/* To int64_t. */
((int64_t)(uint64_t)0xB123C456D789E012ULL == (int64_t)-(int64_t)0x4EDC3BA928761FEEULL) &&
#if defined(SECP256K1_WIDEMUL_INT128)
((int64_t)(((uint128_t)0xA1234567B8901234ULL << 64) + 0xC5678901D2345678ULL) == (int64_t)-(int64_t)0x3A9876FE2DCBA988ULL) &&
(((int64_t)(int128_t)(((uint128_t)0xB1C2D3E4F5A6B7C8ULL << 64) + 0xD9E0F1A2B3C4D5E6ULL)) == (int64_t)(uint64_t)0xD9E0F1A2B3C4D5E6ULL) &&
(((int64_t)(int128_t)(((uint128_t)0xABCDEF0123456789ULL << 64) + 0x0123456789ABCDEFULL)) == (int64_t)(uint64_t)0x0123456789ABCDEFULL) &&
/* To int64_t. */
STATIC_ASSERT((int64_t)(uint64_t)0xB123C456D789E012ULL == (int64_t)-(int64_t)0x4EDC3BA928761FEEULL);
#if defined(SECP256K1_INT128_NATIVE)
STATIC_ASSERT((int64_t)(((uint128_t)0xA1234567B8901234ULL << 64) + 0xC5678901D2345678ULL) == (int64_t)-(int64_t)0x3A9876FE2DCBA988ULL);
STATIC_ASSERT(((int64_t)(int128_t)(((uint128_t)0xB1C2D3E4F5A6B7C8ULL << 64) + 0xD9E0F1A2B3C4D5E6ULL)) == (int64_t)(uint64_t)0xD9E0F1A2B3C4D5E6ULL);
STATIC_ASSERT(((int64_t)(int128_t)(((uint128_t)0xABCDEF0123456789ULL << 64) + 0x0123456789ABCDEFULL)) == (int64_t)(uint64_t)0x0123456789ABCDEFULL);
/* To int128_t. */
((int128_t)(((uint128_t)0xB1234567C8901234ULL << 64) + 0xD5678901E2345678ULL) == (int128_t)(-(int128_t)0x8E1648B3F50E80DCULL * 0x8E1648B3F50E80DDULL + 0x5EA688D5482F9464ULL)) &&
/* To int128_t. */
STATIC_ASSERT((int128_t)(((uint128_t)0xB1234567C8901234ULL << 64) + 0xD5678901E2345678ULL) == (int128_t)(-(int128_t)0x8E1648B3F50E80DCULL * 0x8E1648B3F50E80DDULL + 0x5EA688D5482F9464ULL));
#endif
/* Right shift on negative signed values is implementation defined. Verify that it
acts as a right shift in two's complement with sign extension (i.e duplicating
the top bit into newly added bits). */
((((int8_t)0xE8) >> 2) == (int8_t)(uint8_t)0xFA) &&
((((int16_t)0xE9AC) >> 4) == (int16_t)(uint16_t)0xFE9A) &&
((((int32_t)0x937C918A) >> 9) == (int32_t)(uint32_t)0xFFC9BE48) &&
((((int64_t)0xA8B72231DF9CF4B9ULL) >> 19) == (int64_t)(uint64_t)0xFFFFF516E4463BF3ULL) &&
#if defined(SECP256K1_WIDEMUL_INT128)
((((int128_t)(((uint128_t)0xCD833A65684A0DBCULL << 64) + 0xB349312F71EA7637ULL)) >> 39) == (int128_t)(((uint128_t)0xFFFFFFFFFF9B0674ULL << 64) + 0xCAD0941B79669262ULL)) &&
/* Right shift on negative signed values is implementation defined. Verify that it
acts as a right shift in two's complement with sign extension (i.e duplicating
the top bit into newly added bits). */
STATIC_ASSERT((((int8_t)0xE8) >> 2) == (int8_t)(uint8_t)0xFA);
STATIC_ASSERT((((int16_t)0xE9AC) >> 4) == (int16_t)(uint16_t)0xFE9A);
STATIC_ASSERT((((int32_t)0x937C918A) >> 9) == (int32_t)(uint32_t)0xFFC9BE48);
STATIC_ASSERT((((int64_t)0xA8B72231DF9CF4B9ULL) >> 19) == (int64_t)(uint64_t)0xFFFFF516E4463BF3ULL);
#if defined(SECP256K1_INT128_NATIVE)
STATIC_ASSERT((((int128_t)(((uint128_t)0xCD833A65684A0DBCULL << 64) + 0xB349312F71EA7637ULL)) >> 39) == (int128_t)(((uint128_t)0xFFFFFFFFFF9B0674ULL << 64) + 0xCAD0941B79669262ULL));
#endif
1) * 2 - 1];
};
/* This function is not supposed to be called. */
VERIFY_CHECK(0);
}
#endif /* SECP256K1_ASSUMPTIONS_H */

View File

@@ -1,34 +0,0 @@
/**********************************************************************
* Copyright (c) 2013, 2014 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
#ifndef SECP256K1_BASIC_CONFIG_H
#define SECP256K1_BASIC_CONFIG_H
#ifdef USE_BASIC_CONFIG
#undef USE_ASM_X86_64
#undef USE_ECMULT_STATIC_PRECOMPUTATION
#undef USE_EXTERNAL_ASM
#undef USE_EXTERNAL_DEFAULT_CALLBACKS
#undef USE_FIELD_INV_BUILTIN
#undef USE_FIELD_INV_NUM
#undef USE_NUM_GMP
#undef USE_NUM_NONE
#undef USE_SCALAR_INV_BUILTIN
#undef USE_SCALAR_INV_NUM
#undef USE_FORCE_WIDEMUL_INT64
#undef USE_FORCE_WIDEMUL_INT128
#undef ECMULT_WINDOW_SIZE
#define USE_NUM_NONE 1
#define USE_FIELD_INV_BUILTIN 1
#define USE_SCALAR_INV_BUILTIN 1
#define USE_WIDEMUL_64 1
#define ECMULT_WINDOW_SIZE 15
#endif /* USE_BASIC_CONFIG */
#endif /* SECP256K1_BASIC_CONFIG_H */

279
src/bench.c Normal file
View File

@@ -0,0 +1,279 @@
/***********************************************************************
* Copyright (c) 2014 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#include <stdio.h>
#include <string.h>
#include "../include/secp256k1.h"
#include "util.h"
#include "bench.h"
static void help(int default_iters) {
printf("Benchmarks the following algorithms:\n");
printf(" - ECDSA signing/verification\n");
#ifdef ENABLE_MODULE_ECDH
printf(" - ECDH key exchange (optional module)\n");
#endif
#ifdef ENABLE_MODULE_RECOVERY
printf(" - Public key recovery (optional module)\n");
#endif
#ifdef ENABLE_MODULE_SCHNORRSIG
printf(" - Schnorr signatures (optional module)\n");
#endif
printf("\n");
printf("The default number of iterations for each benchmark is %d. This can be\n", default_iters);
printf("customized using the SECP256K1_BENCH_ITERS environment variable.\n");
printf("\n");
printf("Usage: ./bench [args]\n");
printf("By default, all benchmarks will be run.\n");
printf("args:\n");
printf(" help : display this help and exit\n");
printf(" ecdsa : all ECDSA algorithms--sign, verify, recovery (if enabled)\n");
printf(" ecdsa_sign : ECDSA siging algorithm\n");
printf(" ecdsa_verify : ECDSA verification algorithm\n");
printf(" ec : all EC public key algorithms (keygen)\n");
printf(" ec_keygen : EC public key generation\n");
#ifdef ENABLE_MODULE_RECOVERY
printf(" ecdsa_recover : ECDSA public key recovery algorithm\n");
#endif
#ifdef ENABLE_MODULE_ECDH
printf(" ecdh : ECDH key exchange algorithm\n");
#endif
#ifdef ENABLE_MODULE_SCHNORRSIG
printf(" schnorrsig : all Schnorr signature algorithms (sign, verify)\n");
printf(" schnorrsig_sign : Schnorr sigining algorithm\n");
printf(" schnorrsig_verify : Schnorr verification algorithm\n");
#endif
#ifdef ENABLE_MODULE_ELLSWIFT
printf(" ellswift : all ElligatorSwift benchmarks (encode, decode, keygen, ecdh)\n");
printf(" ellswift_encode : ElligatorSwift encoding\n");
printf(" ellswift_decode : ElligatorSwift decoding\n");
printf(" ellswift_keygen : ElligatorSwift key generation\n");
printf(" ellswift_ecdh : ECDH on ElligatorSwift keys\n");
#endif
printf("\n");
}
typedef struct {
secp256k1_context *ctx;
unsigned char msg[32];
unsigned char key[32];
unsigned char sig[72];
size_t siglen;
unsigned char pubkey[33];
size_t pubkeylen;
} bench_data;
static void bench_verify(void* arg, int iters) {
int i;
bench_data* data = (bench_data*)arg;
for (i = 0; i < iters; i++) {
secp256k1_pubkey pubkey;
secp256k1_ecdsa_signature sig;
data->sig[data->siglen - 1] ^= (i & 0xFF);
data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);
data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);
CHECK(secp256k1_ec_pubkey_parse(data->ctx, &pubkey, data->pubkey, data->pubkeylen) == 1);
CHECK(secp256k1_ecdsa_signature_parse_der(data->ctx, &sig, data->sig, data->siglen) == 1);
CHECK(secp256k1_ecdsa_verify(data->ctx, &sig, data->msg, &pubkey) == (i == 0));
data->sig[data->siglen - 1] ^= (i & 0xFF);
data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);
data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);
}
}
static void bench_sign_setup(void* arg) {
int i;
bench_data *data = (bench_data*)arg;
for (i = 0; i < 32; i++) {
data->msg[i] = i + 1;
}
for (i = 0; i < 32; i++) {
data->key[i] = i + 65;
}
}
static void bench_sign_run(void* arg, int iters) {
int i;
bench_data *data = (bench_data*)arg;
unsigned char sig[74];
for (i = 0; i < iters; i++) {
size_t siglen = 74;
int j;
secp256k1_ecdsa_signature signature;
CHECK(secp256k1_ecdsa_sign(data->ctx, &signature, data->msg, data->key, NULL, NULL));
CHECK(secp256k1_ecdsa_signature_serialize_der(data->ctx, sig, &siglen, &signature));
for (j = 0; j < 32; j++) {
data->msg[j] = sig[j];
data->key[j] = sig[j + 32];
}
}
}
static void bench_keygen_setup(void* arg) {
int i;
bench_data *data = (bench_data*)arg;
for (i = 0; i < 32; i++) {
data->key[i] = i + 65;
}
}
static void bench_keygen_run(void *arg, int iters) {
int i;
bench_data *data = (bench_data*)arg;
for (i = 0; i < iters; i++) {
unsigned char pub33[33];
size_t len = 33;
secp256k1_pubkey pubkey;
CHECK(secp256k1_ec_pubkey_create(data->ctx, &pubkey, data->key));
CHECK(secp256k1_ec_pubkey_serialize(data->ctx, pub33, &len, &pubkey, SECP256K1_EC_COMPRESSED));
memcpy(data->key, pub33 + 1, 32);
}
}
#ifdef ENABLE_MODULE_ECDH
# include "modules/ecdh/bench_impl.h"
#endif
#ifdef ENABLE_MODULE_RECOVERY
# include "modules/recovery/bench_impl.h"
#endif
#ifdef ENABLE_MODULE_SCHNORRSIG
# include "modules/schnorrsig/bench_impl.h"
#endif
#ifdef ENABLE_MODULE_ELLSWIFT
# include "modules/ellswift/bench_impl.h"
#endif
int main(int argc, char** argv) {
int i;
secp256k1_pubkey pubkey;
secp256k1_ecdsa_signature sig;
bench_data data;
int d = argc == 1;
int default_iters = 20000;
int iters = get_iters(default_iters);
/* Check for invalid user arguments */
char* valid_args[] = {"ecdsa", "verify", "ecdsa_verify", "sign", "ecdsa_sign", "ecdh", "recover",
"ecdsa_recover", "schnorrsig", "schnorrsig_verify", "schnorrsig_sign", "ec",
"keygen", "ec_keygen", "ellswift", "encode", "ellswift_encode", "decode",
"ellswift_decode", "ellswift_keygen", "ellswift_ecdh"};
size_t valid_args_size = sizeof(valid_args)/sizeof(valid_args[0]);
int invalid_args = have_invalid_args(argc, argv, valid_args, valid_args_size);
if (argc > 1) {
if (have_flag(argc, argv, "-h")
|| have_flag(argc, argv, "--help")
|| have_flag(argc, argv, "help")) {
help(default_iters);
return 0;
} else if (invalid_args) {
fprintf(stderr, "./bench: unrecognized argument.\n\n");
help(default_iters);
return 1;
}
}
/* Check if the user tries to benchmark optional module without building it */
#ifndef ENABLE_MODULE_ECDH
if (have_flag(argc, argv, "ecdh")) {
fprintf(stderr, "./bench: ECDH module not enabled.\n");
fprintf(stderr, "Use ./configure --enable-module-ecdh.\n\n");
return 1;
}
#endif
#ifndef ENABLE_MODULE_RECOVERY
if (have_flag(argc, argv, "recover") || have_flag(argc, argv, "ecdsa_recover")) {
fprintf(stderr, "./bench: Public key recovery module not enabled.\n");
fprintf(stderr, "Use ./configure --enable-module-recovery.\n\n");
return 1;
}
#endif
#ifndef ENABLE_MODULE_SCHNORRSIG
if (have_flag(argc, argv, "schnorrsig") || have_flag(argc, argv, "schnorrsig_sign") || have_flag(argc, argv, "schnorrsig_verify")) {
fprintf(stderr, "./bench: Schnorr signatures module not enabled.\n");
fprintf(stderr, "Use ./configure --enable-module-schnorrsig.\n\n");
return 1;
}
#endif
#ifndef ENABLE_MODULE_ELLSWIFT
if (have_flag(argc, argv, "ellswift") || have_flag(argc, argv, "ellswift_encode") || have_flag(argc, argv, "ellswift_decode") ||
have_flag(argc, argv, "encode") || have_flag(argc, argv, "decode") || have_flag(argc, argv, "ellswift_keygen") ||
have_flag(argc, argv, "ellswift_ecdh")) {
fprintf(stderr, "./bench: ElligatorSwift module not enabled.\n");
fprintf(stderr, "Use ./configure --enable-module-ellswift.\n\n");
return 1;
}
#endif
/* ECDSA benchmark */
data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
for (i = 0; i < 32; i++) {
data.msg[i] = 1 + i;
}
for (i = 0; i < 32; i++) {
data.key[i] = 33 + i;
}
data.siglen = 72;
CHECK(secp256k1_ecdsa_sign(data.ctx, &sig, data.msg, data.key, NULL, NULL));
CHECK(secp256k1_ecdsa_signature_serialize_der(data.ctx, data.sig, &data.siglen, &sig));
CHECK(secp256k1_ec_pubkey_create(data.ctx, &pubkey, data.key));
data.pubkeylen = 33;
CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED) == 1);
print_output_table_header_row();
if (d || have_flag(argc, argv, "ecdsa") || have_flag(argc, argv, "verify") || have_flag(argc, argv, "ecdsa_verify")) run_benchmark("ecdsa_verify", bench_verify, NULL, NULL, &data, 10, iters);
if (d || have_flag(argc, argv, "ecdsa") || have_flag(argc, argv, "sign") || have_flag(argc, argv, "ecdsa_sign")) run_benchmark("ecdsa_sign", bench_sign_run, bench_sign_setup, NULL, &data, 10, iters);
if (d || have_flag(argc, argv, "ec") || have_flag(argc, argv, "keygen") || have_flag(argc, argv, "ec_keygen")) run_benchmark("ec_keygen", bench_keygen_run, bench_keygen_setup, NULL, &data, 10, iters);
secp256k1_context_destroy(data.ctx);
#ifdef ENABLE_MODULE_ECDH
/* ECDH benchmarks */
run_ecdh_bench(iters, argc, argv);
#endif
#ifdef ENABLE_MODULE_RECOVERY
/* ECDSA recovery benchmarks */
run_recovery_bench(iters, argc, argv);
#endif
#ifdef ENABLE_MODULE_SCHNORRSIG
/* Schnorr signature benchmarks */
run_schnorrsig_bench(iters, argc, argv);
#endif
#ifdef ENABLE_MODULE_ELLSWIFT
/* ElligatorSwift benchmarks */
run_ellswift_bench(iters, argc, argv);
#endif
return 0;
}

View File

@@ -1,30 +1,46 @@
/**********************************************************************
* Copyright (c) 2014 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
/***********************************************************************
* Copyright (c) 2014 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#ifndef SECP256K1_BENCH_H
#define SECP256K1_BENCH_H
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "sys/time.h"
#if (defined(_MSC_VER) && _MSC_VER >= 1900)
# include <time.h>
#else
# include <sys/time.h>
#endif
static int64_t gettime_i64(void) {
#if (defined(_MSC_VER) && _MSC_VER >= 1900)
/* C11 way to get wallclock time */
struct timespec tv;
if (!timespec_get(&tv, TIME_UTC)) {
fputs("timespec_get failed!", stderr);
exit(1);
}
return (int64_t)tv.tv_nsec / 1000 + (int64_t)tv.tv_sec * 1000000LL;
#else
struct timeval tv;
gettimeofday(&tv, NULL);
return (int64_t)tv.tv_usec + (int64_t)tv.tv_sec * 1000000LL;
#endif
}
#define FP_EXP (6)
#define FP_MULT (1000000LL)
/* Format fixed point number. */
void print_number(const int64_t x) {
static void print_number(const int64_t x) {
int64_t x_abs, y;
int c, i, rounding;
int c, i, rounding, g; /* g = integer part size, c = fractional part size */
size_t ptr;
char buffer[30];
@@ -56,24 +72,30 @@ void print_number(const int64_t x) {
/* Format and print the number. */
ptr = sizeof(buffer) - 1;
buffer[ptr] = 0;
if (c != 0) {
g = 0;
if (c != 0) { /* non zero fractional part */
for (i = 0; i < c; ++i) {
buffer[--ptr] = '0' + (y % 10);
y /= 10;
}
buffer[--ptr] = '.';
} else if (c == 0) { /* fractional part is 0 */
buffer[--ptr] = '0';
}
buffer[--ptr] = '.';
do {
buffer[--ptr] = '0' + (y % 10);
y /= 10;
g++;
} while (y != 0);
if (x < 0) {
buffer[--ptr] = '-';
g++;
}
printf("%s", &buffer[ptr]);
printf("%5.*s", g, &buffer[ptr]); /* Prints integer part */
printf("%-*s", FP_EXP, &buffer[ptr + g]); /* Prints fractional part */
}
void run_benchmark(char *name, void (*benchmark)(void*, int), void (*setup)(void*), void (*teardown)(void*, int), void* data, int count, int iter) {
static void run_benchmark(char *name, void (*benchmark)(void*, int), void (*setup)(void*), void (*teardown)(void*, int), void* data, int count, int iter) {
int i;
int64_t min = INT64_MAX;
int64_t sum = 0;
@@ -97,22 +119,20 @@ void run_benchmark(char *name, void (*benchmark)(void*, int), void (*setup)(void
}
sum += total;
}
printf("%s: min ", name);
/* ',' is used as a column delimiter */
printf("%-30s, ", name);
print_number(min * FP_MULT / iter);
printf("us / avg ");
printf(" , ");
print_number(((sum * FP_MULT) / count) / iter);
printf("us / max ");
printf(" , ");
print_number(max * FP_MULT / iter);
printf("us\n");
printf("\n");
}
int have_flag(int argc, char** argv, char *flag) {
static int have_flag(int argc, char** argv, char *flag) {
char** argm = argv + argc;
argv++;
if (argv == argm) {
return 1;
}
while (argv != NULL && argv != argm) {
while (argv != argm) {
if (strcmp(*argv, flag) == 0) {
return 1;
}
@@ -121,7 +141,33 @@ int have_flag(int argc, char** argv, char *flag) {
return 0;
}
int get_iters(int default_iters) {
/* takes an array containing the arguments that the user is allowed to enter on the command-line
returns:
- 1 if the user entered an invalid argument
- 0 if all the user entered arguments are valid */
static int have_invalid_args(int argc, char** argv, char** valid_args, size_t n) {
size_t i;
int found_valid;
char** argm = argv + argc;
argv++;
while (argv != argm) {
found_valid = 0;
for (i = 0; i < n; i++) {
if (strcmp(*argv, valid_args[i]) == 0) {
found_valid = 1; /* user entered a valid arg from the list */
break;
}
}
if (found_valid == 0) {
return 1; /* invalid arg found */
}
argv++;
}
return 0;
}
static int get_iters(int default_iters) {
char* env = getenv("SECP256K1_BENCH_ITERS");
if (env) {
return strtol(env, NULL, 0);
@@ -130,4 +176,13 @@ int get_iters(int default_iters) {
}
}
static void print_output_table_header_row(void) {
char* bench_str = "Benchmark"; /* left justified */
char* min_str = " Min(us) "; /* center alignment */
char* avg_str = " Avg(us) ";
char* max_str = " Max(us) ";
printf("%-30s,%-15s,%-15s,%-15s\n", bench_str, min_str, avg_str, max_str);
printf("\n");
}
#endif /* SECP256K1_BENCH_H */

38
src/bench_bppp.c Normal file
View File

@@ -0,0 +1,38 @@
/**********************************************************************
* Copyright (c) 2020 Andrew Poelstra *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
#include <stdint.h>
#include "../include/secp256k1_bppp.h"
#include "util.h"
#include "bench.h"
typedef struct {
secp256k1_context* ctx;
} bench_bppp_data;
static void bench_bppp_setup(void* arg) {
(void) arg;
}
static void bench_bppp(void* arg, int iters) {
bench_bppp_data *data = (bench_bppp_data*)arg;
(void) data;
(void) iters;
}
int main(void) {
bench_bppp_data data;
int iters = get_iters(32);
data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
run_benchmark("bppp_verify_bit", bench_bppp, bench_bppp_setup, NULL, &data, 10, iters);
secp256k1_context_destroy(data.ctx);
return 0;
}

View File

@@ -1,47 +1,187 @@
/**********************************************************************
* Copyright (c) 2017 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
/***********************************************************************
* Copyright (c) 2017 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#include <stdio.h>
#include "include/secp256k1.h"
#include "secp256k1.c"
#include "../include/secp256k1.h"
#include "util.h"
#include "hash_impl.h"
#include "num_impl.h"
#include "field_impl.h"
#include "group_impl.h"
#include "scalar_impl.h"
#include "ecmult_impl.h"
#include "bench.h"
#include "secp256k1.c"
#define POINTS 32768
static void help(char **argv) {
printf("Benchmark EC multiplication algorithms\n");
printf("\n");
printf("Usage: %s <help|pippenger_wnaf|strauss_wnaf|simple>\n", argv[0]);
printf("The output shows the number of multiplied and summed points right after the\n");
printf("function name. The letter 'g' indicates that one of the points is the generator.\n");
printf("The benchmarks are divided by the number of points.\n");
printf("\n");
printf("default (ecmult_multi): picks pippenger_wnaf or strauss_wnaf depending on the\n");
printf(" batch size\n");
printf("pippenger_wnaf: for all batch sizes\n");
printf("strauss_wnaf: for all batch sizes\n");
printf("simple: multiply and sum each point individually\n");
}
typedef struct {
/* Setup once in advance */
secp256k1_context* ctx;
secp256k1_scratch_space* scratch;
secp256k1_scalar* scalars;
secp256k1_ge* pubkeys;
secp256k1_gej* pubkeys_gej;
secp256k1_scalar* seckeys;
secp256k1_gej* expected_output;
secp256k1_ecmult_multi_func ecmult_multi;
/* Changes per test */
/* Changes per benchmark */
size_t count;
int includes_g;
/* Changes per test iteration */
/* Changes per benchmark iteration, used to pick different scalars and pubkeys
* in each run. */
size_t offset1;
size_t offset2;
/* Test output. */
/* Benchmark output. */
secp256k1_gej* output;
} bench_data;
static int bench_callback(secp256k1_scalar* sc, secp256k1_ge* ge, size_t idx, void* arg) {
/* Hashes x into [0, POINTS) twice and store the result in offset1 and offset2. */
static void hash_into_offset(bench_data* data, size_t x) {
data->offset1 = (x * 0x537b7f6f + 0x8f66a481) % POINTS;
data->offset2 = (x * 0x7f6f537b + 0x6a1a8f49) % POINTS;
}
/* Check correctness of the benchmark by computing
* sum(outputs) ?= (sum(scalars_gen) + sum(seckeys)*sum(scalars))*G */
static void bench_ecmult_teardown_helper(bench_data* data, size_t* seckey_offset, size_t* scalar_offset, size_t* scalar_gen_offset, int iters) {
int i;
secp256k1_gej sum_output, tmp;
secp256k1_scalar sum_scalars;
secp256k1_gej_set_infinity(&sum_output);
secp256k1_scalar_clear(&sum_scalars);
for (i = 0; i < iters; ++i) {
secp256k1_gej_add_var(&sum_output, &sum_output, &data->output[i], NULL);
if (scalar_gen_offset != NULL) {
secp256k1_scalar_add(&sum_scalars, &sum_scalars, &data->scalars[(*scalar_gen_offset+i) % POINTS]);
}
if (seckey_offset != NULL) {
secp256k1_scalar s = data->seckeys[(*seckey_offset+i) % POINTS];
secp256k1_scalar_mul(&s, &s, &data->scalars[(*scalar_offset+i) % POINTS]);
secp256k1_scalar_add(&sum_scalars, &sum_scalars, &s);
}
}
secp256k1_ecmult_gen(&data->ctx->ecmult_gen_ctx, &tmp, &sum_scalars);
CHECK(secp256k1_gej_eq_var(&tmp, &sum_output));
}
static void bench_ecmult_setup(void* arg) {
bench_data* data = (bench_data*)arg;
/* Re-randomize offset to ensure that we're using different scalars and
* group elements in each run. */
hash_into_offset(data, data->offset1);
}
static void bench_ecmult_gen(void* arg, int iters) {
bench_data* data = (bench_data*)arg;
int i;
for (i = 0; i < iters; ++i) {
secp256k1_ecmult_gen(&data->ctx->ecmult_gen_ctx, &data->output[i], &data->scalars[(data->offset1+i) % POINTS]);
}
}
static void bench_ecmult_gen_teardown(void* arg, int iters) {
bench_data* data = (bench_data*)arg;
bench_ecmult_teardown_helper(data, NULL, NULL, &data->offset1, iters);
}
static void bench_ecmult_const(void* arg, int iters) {
bench_data* data = (bench_data*)arg;
int i;
for (i = 0; i < iters; ++i) {
secp256k1_ecmult_const(&data->output[i], &data->pubkeys[(data->offset1+i) % POINTS], &data->scalars[(data->offset2+i) % POINTS]);
}
}
static void bench_ecmult_const_teardown(void* arg, int iters) {
bench_data* data = (bench_data*)arg;
bench_ecmult_teardown_helper(data, &data->offset1, &data->offset2, NULL, iters);
}
static void bench_ecmult_1p(void* arg, int iters) {
bench_data* data = (bench_data*)arg;
int i;
for (i = 0; i < iters; ++i) {
secp256k1_ecmult(&data->output[i], &data->pubkeys_gej[(data->offset1+i) % POINTS], &data->scalars[(data->offset2+i) % POINTS], NULL);
}
}
static void bench_ecmult_1p_teardown(void* arg, int iters) {
bench_data* data = (bench_data*)arg;
bench_ecmult_teardown_helper(data, &data->offset1, &data->offset2, NULL, iters);
}
static void bench_ecmult_0p_g(void* arg, int iters) {
bench_data* data = (bench_data*)arg;
int i;
for (i = 0; i < iters; ++i) {
secp256k1_ecmult(&data->output[i], NULL, &secp256k1_scalar_zero, &data->scalars[(data->offset1+i) % POINTS]);
}
}
static void bench_ecmult_0p_g_teardown(void* arg, int iters) {
bench_data* data = (bench_data*)arg;
bench_ecmult_teardown_helper(data, NULL, NULL, &data->offset1, iters);
}
static void bench_ecmult_1p_g(void* arg, int iters) {
bench_data* data = (bench_data*)arg;
int i;
for (i = 0; i < iters/2; ++i) {
secp256k1_ecmult(&data->output[i], &data->pubkeys_gej[(data->offset1+i) % POINTS], &data->scalars[(data->offset2+i) % POINTS], &data->scalars[(data->offset1+i) % POINTS]);
}
}
static void bench_ecmult_1p_g_teardown(void* arg, int iters) {
bench_data* data = (bench_data*)arg;
bench_ecmult_teardown_helper(data, &data->offset1, &data->offset2, &data->offset1, iters/2);
}
static void run_ecmult_bench(bench_data* data, int iters) {
char str[32];
sprintf(str, "ecmult_gen");
run_benchmark(str, bench_ecmult_gen, bench_ecmult_setup, bench_ecmult_gen_teardown, data, 10, iters);
sprintf(str, "ecmult_const");
run_benchmark(str, bench_ecmult_const, bench_ecmult_setup, bench_ecmult_const_teardown, data, 10, iters);
/* ecmult with non generator point */
sprintf(str, "ecmult_1p");
run_benchmark(str, bench_ecmult_1p, bench_ecmult_setup, bench_ecmult_1p_teardown, data, 10, iters);
/* ecmult with generator point */
sprintf(str, "ecmult_0p_g");
run_benchmark(str, bench_ecmult_0p_g, bench_ecmult_setup, bench_ecmult_0p_g_teardown, data, 10, iters);
/* ecmult with generator and non-generator point. The reported time is per point. */
sprintf(str, "ecmult_1p_g");
run_benchmark(str, bench_ecmult_1p_g, bench_ecmult_setup, bench_ecmult_1p_g_teardown, data, 10, 2*iters);
}
static int bench_ecmult_multi_callback(secp256k1_scalar* sc, secp256k1_ge* ge, size_t idx, void* arg) {
bench_data* data = (bench_data*)arg;
if (data->includes_g) ++idx;
if (idx == 0) {
@@ -54,7 +194,7 @@ static int bench_callback(secp256k1_scalar* sc, secp256k1_ge* ge, size_t idx, vo
return 1;
}
static void bench_ecmult(void* arg, int iters) {
static void bench_ecmult_multi(void* arg, int iters) {
bench_data* data = (bench_data*)arg;
int includes_g = data->includes_g;
@@ -63,19 +203,18 @@ static void bench_ecmult(void* arg, int iters) {
iters = iters / data->count;
for (iter = 0; iter < iters; ++iter) {
data->ecmult_multi(&data->ctx->error_callback, &data->ctx->ecmult_ctx, data->scratch, &data->output[iter], data->includes_g ? &data->scalars[data->offset1] : NULL, bench_callback, arg, count - includes_g);
data->ecmult_multi(&data->ctx->error_callback, data->scratch, &data->output[iter], data->includes_g ? &data->scalars[data->offset1] : NULL, bench_ecmult_multi_callback, arg, count - includes_g);
data->offset1 = (data->offset1 + count) % POINTS;
data->offset2 = (data->offset2 + count - 1) % POINTS;
}
}
static void bench_ecmult_setup(void* arg) {
static void bench_ecmult_multi_setup(void* arg) {
bench_data* data = (bench_data*)arg;
data->offset1 = (data->count * 0x537b7f6f + 0x8f66a481) % POINTS;
data->offset2 = (data->count * 0x7f6f537b + 0x6a1a8f49) % POINTS;
hash_into_offset(data, data->count);
}
static void bench_ecmult_teardown(void* arg, int iters) {
static void bench_ecmult_multi_teardown(void* arg, int iters) {
bench_data* data = (bench_data*)arg;
int iter;
iters = iters / data->count;
@@ -89,7 +228,7 @@ static void bench_ecmult_teardown(void* arg, int iters) {
static void generate_scalar(uint32_t num, secp256k1_scalar* scalar) {
secp256k1_sha256 sha256;
unsigned char c[11] = {'e', 'c', 'm', 'u', 'l', 't', 0, 0, 0, 0};
unsigned char c[10] = {'e', 'c', 'm', 'u', 'l', 't', 0, 0, 0, 0};
unsigned char buf[32];
int overflow = 0;
c[6] = num;
@@ -103,9 +242,8 @@ static void generate_scalar(uint32_t num, secp256k1_scalar* scalar) {
CHECK(!overflow);
}
static void run_test(bench_data* data, size_t count, int includes_g, int num_iters) {
static void run_ecmult_multi_bench(bench_data* data, size_t count, int includes_g, int num_iters) {
char str[32];
static const secp256k1_scalar zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0);
size_t iters = 1 + num_iters / count;
size_t iter;
@@ -113,8 +251,7 @@ static void run_test(bench_data* data, size_t count, int includes_g, int num_ite
data->includes_g = includes_g;
/* Compute (the negation of) the expected results directly. */
data->offset1 = (data->count * 0x537b7f6f + 0x8f66a481) % POINTS;
data->offset2 = (data->count * 0x7f6f537b + 0x6a1a8f49) % POINTS;
hash_into_offset(data, data->count);
for (iter = 0; iter < iters; ++iter) {
secp256k1_scalar tmp;
secp256k1_scalar total = data->scalars[(data->offset1++) % POINTS];
@@ -124,29 +261,34 @@ static void run_test(bench_data* data, size_t count, int includes_g, int num_ite
secp256k1_scalar_add(&total, &total, &tmp);
}
secp256k1_scalar_negate(&total, &total);
secp256k1_ecmult(&data->ctx->ecmult_ctx, &data->expected_output[iter], NULL, &zero, &total);
secp256k1_ecmult(&data->expected_output[iter], NULL, &secp256k1_scalar_zero, &total);
}
/* Run the benchmark. */
sprintf(str, includes_g ? "ecmult_%ig" : "ecmult_%i", (int)count);
run_benchmark(str, bench_ecmult, bench_ecmult_setup, bench_ecmult_teardown, data, 10, count * iters);
if (includes_g) {
sprintf(str, "ecmult_multi_%ip_g", (int)count - 1);
} else {
sprintf(str, "ecmult_multi_%ip", (int)count);
}
run_benchmark(str, bench_ecmult_multi, bench_ecmult_multi_setup, bench_ecmult_multi_teardown, data, 10, count * iters);
}
int main(int argc, char **argv) {
bench_data data;
int i, p;
secp256k1_gej* pubkeys_gej;
size_t scratch_size;
int iters = get_iters(10000);
data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
scratch_size = secp256k1_strauss_scratch_size(POINTS) + STRAUSS_SCRATCH_OBJECTS*16;
data.scratch = secp256k1_scratch_space_create(data.ctx, scratch_size);
data.ecmult_multi = secp256k1_ecmult_multi_var;
if (argc > 1) {
if(have_flag(argc, argv, "pippenger_wnaf")) {
if(have_flag(argc, argv, "-h")
|| have_flag(argc, argv, "--help")
|| have_flag(argc, argv, "help")) {
help(argv);
return 0;
} else if(have_flag(argc, argv, "pippenger_wnaf")) {
printf("Using pippenger_wnaf:\n");
data.ecmult_multi = secp256k1_ecmult_pippenger_batch_single;
} else if(have_flag(argc, argv, "strauss_wnaf")) {
@@ -154,39 +296,49 @@ int main(int argc, char **argv) {
data.ecmult_multi = secp256k1_ecmult_strauss_batch_single;
} else if(have_flag(argc, argv, "simple")) {
printf("Using simple algorithm:\n");
data.ecmult_multi = secp256k1_ecmult_multi_var;
secp256k1_scratch_space_destroy(data.ctx, data.scratch);
data.scratch = NULL;
} else {
fprintf(stderr, "%s: unrecognized argument '%s'.\n", argv[0], argv[1]);
fprintf(stderr, "Use 'pippenger_wnaf', 'strauss_wnaf', 'simple' or no argument to benchmark a combined algorithm.\n");
fprintf(stderr, "%s: unrecognized argument '%s'.\n\n", argv[0], argv[1]);
help(argv);
return 1;
}
}
data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
scratch_size = secp256k1_strauss_scratch_size(POINTS) + STRAUSS_SCRATCH_OBJECTS*16;
if (!have_flag(argc, argv, "simple")) {
data.scratch = secp256k1_scratch_space_create(data.ctx, scratch_size);
} else {
data.scratch = NULL;
}
/* Allocate stuff */
data.scalars = malloc(sizeof(secp256k1_scalar) * POINTS);
data.seckeys = malloc(sizeof(secp256k1_scalar) * POINTS);
data.pubkeys = malloc(sizeof(secp256k1_ge) * POINTS);
data.pubkeys_gej = malloc(sizeof(secp256k1_gej) * POINTS);
data.expected_output = malloc(sizeof(secp256k1_gej) * (iters + 1));
data.output = malloc(sizeof(secp256k1_gej) * (iters + 1));
/* Generate a set of scalars, and private/public keypairs. */
pubkeys_gej = malloc(sizeof(secp256k1_gej) * POINTS);
secp256k1_gej_set_ge(&pubkeys_gej[0], &secp256k1_ge_const_g);
secp256k1_gej_set_ge(&data.pubkeys_gej[0], &secp256k1_ge_const_g);
secp256k1_scalar_set_int(&data.seckeys[0], 1);
for (i = 0; i < POINTS; ++i) {
generate_scalar(i, &data.scalars[i]);
if (i) {
secp256k1_gej_double_var(&pubkeys_gej[i], &pubkeys_gej[i - 1], NULL);
secp256k1_gej_double_var(&data.pubkeys_gej[i], &data.pubkeys_gej[i - 1], NULL);
secp256k1_scalar_add(&data.seckeys[i], &data.seckeys[i - 1], &data.seckeys[i - 1]);
}
}
secp256k1_ge_set_all_gej_var(data.pubkeys, pubkeys_gej, POINTS);
free(pubkeys_gej);
secp256k1_ge_set_all_gej_var(data.pubkeys, data.pubkeys_gej, POINTS);
print_output_table_header_row();
/* Initialize offset1 and offset2 */
hash_into_offset(&data, 0);
run_ecmult_bench(&data, iters);
for (i = 1; i <= 8; ++i) {
run_test(&data, i, 1, iters);
run_ecmult_multi_bench(&data, i, 1, iters);
}
/* This is disabled with low count of iterations because the loop runs 77 times even with iters=1
@@ -195,7 +347,7 @@ int main(int argc, char **argv) {
if (iters > 2) {
for (p = 0; p <= 11; ++p) {
for (i = 9; i <= 16; ++i) {
run_test(&data, i << p, 1, iters);
run_ecmult_multi_bench(&data, i << p, 1, iters);
}
}
}
@@ -206,6 +358,7 @@ int main(int argc, char **argv) {
secp256k1_context_destroy(data.ctx);
free(data.scalars);
free(data.pubkeys);
free(data.pubkeys_gej);
free(data.seckeys);
free(data.output);
free(data.expected_output);

View File

@@ -7,7 +7,7 @@
#include <stdint.h>
#include <string.h>
#include "include/secp256k1_generator.h"
#include "../include/secp256k1_generator.h"
#include "util.h"
#include "bench.h"
@@ -50,7 +50,7 @@ int main(void) {
bench_generator_t data;
int iters = get_iters(20000);
data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
run_benchmark("generator_generate", bench_generator_generate, bench_generator_setup, NULL, &data, 10, iters);
run_benchmark("generator_generate_blinded", bench_generator_generate_blinded, bench_generator_setup, NULL, &data, 10, iters);

View File

@@ -1,23 +1,40 @@
/**********************************************************************
* Copyright (c) 2014-2015 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
/***********************************************************************
* Copyright (c) 2014-2015 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#include <stdio.h>
#include "include/secp256k1.h"
#include "secp256k1.c"
#include "../include/secp256k1.h"
#include "assumptions.h"
#include "util.h"
#include "hash_impl.h"
#include "num_impl.h"
#include "field_impl.h"
#include "group_impl.h"
#include "scalar_impl.h"
#include "ecmult_const_impl.h"
#include "ecmult_impl.h"
#include "bench.h"
#include "secp256k1.c"
static void help(int default_iters) {
printf("Benchmarks various internal routines.\n");
printf("\n");
printf("The default number of iterations for each benchmark is %d. This can be\n", default_iters);
printf("customized using the SECP256K1_BENCH_ITERS environment variable.\n");
printf("\n");
printf("Usage: ./bench_internal [args]\n");
printf("By default, all benchmarks will be run.\n");
printf("args:\n");
printf(" help : display this help and exit\n");
printf(" scalar : all scalar operations (add, half, inverse, mul, negate, split)\n");
printf(" field : all field operations (half, inverse, issquare, mul, normalize, sqr, sqrt)\n");
printf(" group : all group operations (add, double, to_affine)\n");
printf(" ecmult : all point multiplication operations (ecmult_wnaf) \n");
printf(" hash : all hash algorithms (hmac, rng6979, sha256)\n");
printf(" context : all context object operations (context_create)\n");
printf("\n");
}
typedef struct {
secp256k1_scalar scalar[2];
@@ -28,7 +45,7 @@ typedef struct {
int wnaf[256];
} bench_inv;
void bench_setup(void* arg) {
static void bench_setup(void* arg) {
bench_inv *data = (bench_inv*)arg;
static const unsigned char init[4][32] = {
@@ -66,10 +83,10 @@ void bench_setup(void* arg) {
secp256k1_scalar_set_b32(&data->scalar[0], init[0], NULL);
secp256k1_scalar_set_b32(&data->scalar[1], init[1], NULL);
secp256k1_fe_set_b32(&data->fe[0], init[0]);
secp256k1_fe_set_b32(&data->fe[1], init[1]);
secp256k1_fe_set_b32(&data->fe[2], init[2]);
secp256k1_fe_set_b32(&data->fe[3], init[3]);
secp256k1_fe_set_b32_limit(&data->fe[0], init[0]);
secp256k1_fe_set_b32_limit(&data->fe[1], init[1]);
secp256k1_fe_set_b32_limit(&data->fe[2], init[2]);
secp256k1_fe_set_b32_limit(&data->fe[3], init[3]);
CHECK(secp256k1_ge_set_xo_var(&data->ge[0], &data->fe[0], 0));
CHECK(secp256k1_ge_set_xo_var(&data->ge[1], &data->fe[1], 1));
secp256k1_gej_set_ge(&data->gej[0], &data->ge[0]);
@@ -80,7 +97,7 @@ void bench_setup(void* arg) {
memcpy(data->data + 32, init[1], 32);
}
void bench_scalar_add(void* arg, int iters) {
static void bench_scalar_add(void* arg, int iters) {
int i, j = 0;
bench_inv *data = (bench_inv*)arg;
@@ -90,7 +107,7 @@ void bench_scalar_add(void* arg, int iters) {
CHECK(j <= iters);
}
void bench_scalar_negate(void* arg, int iters) {
static void bench_scalar_negate(void* arg, int iters) {
int i;
bench_inv *data = (bench_inv*)arg;
@@ -99,7 +116,7 @@ void bench_scalar_negate(void* arg, int iters) {
}
}
void bench_scalar_sqr(void* arg, int iters) {
static void bench_scalar_sqr(void* arg, int iters) {
int i;
bench_inv *data = (bench_inv*)arg;
@@ -108,7 +125,19 @@ void bench_scalar_sqr(void* arg, int iters) {
}
}
void bench_scalar_mul(void* arg, int iters) {
static void bench_scalar_half(void* arg, int iters) {
int i;
bench_inv *data = (bench_inv*)arg;
secp256k1_scalar s = data->scalar[0];
for (i = 0; i < iters; i++) {
secp256k1_scalar_half(&s, &s);
}
data->scalar[0] = s;
}
static void bench_scalar_mul(void* arg, int iters) {
int i;
bench_inv *data = (bench_inv*)arg;
@@ -117,18 +146,19 @@ void bench_scalar_mul(void* arg, int iters) {
}
}
void bench_scalar_split(void* arg, int iters) {
static void bench_scalar_split(void* arg, int iters) {
int i, j = 0;
bench_inv *data = (bench_inv*)arg;
secp256k1_scalar tmp;
for (i = 0; i < iters; i++) {
secp256k1_scalar_split_lambda(&data->scalar[0], &data->scalar[1], &data->scalar[0]);
j += secp256k1_scalar_add(&data->scalar[0], &data->scalar[0], &data->scalar[1]);
secp256k1_scalar_split_lambda(&tmp, &data->scalar[1], &data->scalar[0]);
j += secp256k1_scalar_add(&data->scalar[0], &tmp, &data->scalar[1]);
}
CHECK(j <= iters);
}
void bench_scalar_inverse(void* arg, int iters) {
static void bench_scalar_inverse(void* arg, int iters) {
int i, j = 0;
bench_inv *data = (bench_inv*)arg;
@@ -139,7 +169,7 @@ void bench_scalar_inverse(void* arg, int iters) {
CHECK(j <= iters);
}
void bench_scalar_inverse_var(void* arg, int iters) {
static void bench_scalar_inverse_var(void* arg, int iters) {
int i, j = 0;
bench_inv *data = (bench_inv*)arg;
@@ -150,7 +180,16 @@ void bench_scalar_inverse_var(void* arg, int iters) {
CHECK(j <= iters);
}
void bench_field_normalize(void* arg, int iters) {
static void bench_field_half(void* arg, int iters) {
int i;
bench_inv *data = (bench_inv*)arg;
for (i = 0; i < iters; i++) {
secp256k1_fe_half(&data->fe[0]);
}
}
static void bench_field_normalize(void* arg, int iters) {
int i;
bench_inv *data = (bench_inv*)arg;
@@ -159,7 +198,7 @@ void bench_field_normalize(void* arg, int iters) {
}
}
void bench_field_normalize_weak(void* arg, int iters) {
static void bench_field_normalize_weak(void* arg, int iters) {
int i;
bench_inv *data = (bench_inv*)arg;
@@ -168,7 +207,7 @@ void bench_field_normalize_weak(void* arg, int iters) {
}
}
void bench_field_mul(void* arg, int iters) {
static void bench_field_mul(void* arg, int iters) {
int i;
bench_inv *data = (bench_inv*)arg;
@@ -177,7 +216,7 @@ void bench_field_mul(void* arg, int iters) {
}
}
void bench_field_sqr(void* arg, int iters) {
static void bench_field_sqr(void* arg, int iters) {
int i;
bench_inv *data = (bench_inv*)arg;
@@ -186,7 +225,7 @@ void bench_field_sqr(void* arg, int iters) {
}
}
void bench_field_inverse(void* arg, int iters) {
static void bench_field_inverse(void* arg, int iters) {
int i;
bench_inv *data = (bench_inv*)arg;
@@ -196,7 +235,7 @@ void bench_field_inverse(void* arg, int iters) {
}
}
void bench_field_inverse_var(void* arg, int iters) {
static void bench_field_inverse_var(void* arg, int iters) {
int i;
bench_inv *data = (bench_inv*)arg;
@@ -206,7 +245,7 @@ void bench_field_inverse_var(void* arg, int iters) {
}
}
void bench_field_sqrt(void* arg, int iters) {
static void bench_field_sqrt(void* arg, int iters) {
int i, j = 0;
bench_inv *data = (bench_inv*)arg;
secp256k1_fe t;
@@ -219,7 +258,20 @@ void bench_field_sqrt(void* arg, int iters) {
CHECK(j <= iters);
}
void bench_group_double_var(void* arg, int iters) {
static void bench_field_is_square_var(void* arg, int iters) {
int i, j = 0;
bench_inv *data = (bench_inv*)arg;
secp256k1_fe t = data->fe[0];
for (i = 0; i < iters; i++) {
j += secp256k1_fe_is_square_var(&t);
secp256k1_fe_add(&t, &data->fe[1]);
secp256k1_fe_normalize_var(&t);
}
CHECK(j <= iters);
}
static void bench_group_double_var(void* arg, int iters) {
int i;
bench_inv *data = (bench_inv*)arg;
@@ -228,7 +280,7 @@ void bench_group_double_var(void* arg, int iters) {
}
}
void bench_group_add_var(void* arg, int iters) {
static void bench_group_add_var(void* arg, int iters) {
int i;
bench_inv *data = (bench_inv*)arg;
@@ -237,7 +289,7 @@ void bench_group_add_var(void* arg, int iters) {
}
}
void bench_group_add_affine(void* arg, int iters) {
static void bench_group_add_affine(void* arg, int iters) {
int i;
bench_inv *data = (bench_inv*)arg;
@@ -246,7 +298,7 @@ void bench_group_add_affine(void* arg, int iters) {
}
}
void bench_group_add_affine_var(void* arg, int iters) {
static void bench_group_add_affine_var(void* arg, int iters) {
int i;
bench_inv *data = (bench_inv*)arg;
@@ -255,7 +307,7 @@ void bench_group_add_affine_var(void* arg, int iters) {
}
}
void bench_group_jacobi_var(void* arg, int iters) {
static void bench_group_jacobi_var(void* arg, int iters) {
int i, j = 0;
bench_inv *data = (bench_inv*)arg;
@@ -275,7 +327,16 @@ void bench_group_jacobi_var(void* arg, int iters) {
CHECK(j <= iters);
}
void bench_group_to_affine_var(void* arg, int iters) {
static void bench_group_add_zinv_var(void* arg, int iters) {
int i;
bench_inv *data = (bench_inv*)arg;
for (i = 0; i < iters; i++) {
secp256k1_gej_add_zinv_var(&data->gej[0], &data->gej[0], &data->ge[1], &data->gej[0].y);
}
}
static void bench_group_to_affine_var(void* arg, int iters) {
int i;
bench_inv *data = (bench_inv*)arg;
@@ -293,7 +354,7 @@ void bench_group_to_affine_var(void* arg, int iters) {
}
}
void bench_ecmult_wnaf(void* arg, int iters) {
static void bench_ecmult_wnaf(void* arg, int iters) {
int i, bits = 0, overflow = 0;
bench_inv *data = (bench_inv*)arg;
@@ -305,20 +366,7 @@ void bench_ecmult_wnaf(void* arg, int iters) {
CHECK(bits <= 256*iters);
}
void bench_wnaf_const(void* arg, int iters) {
int i, bits = 0, overflow = 0;
bench_inv *data = (bench_inv*)arg;
for (i = 0; i < iters; i++) {
bits += secp256k1_wnaf_const(data->wnaf, &data->scalar[0], WINDOW_A, 256);
overflow += secp256k1_scalar_add(&data->scalar[0], &data->scalar[0], &data->scalar[1]);
}
CHECK(overflow >= 0);
CHECK(bits <= 256*iters);
}
void bench_sha256(void* arg, int iters) {
static void bench_sha256(void* arg, int iters) {
int i;
bench_inv *data = (bench_inv*)arg;
secp256k1_sha256 sha;
@@ -330,7 +378,7 @@ void bench_sha256(void* arg, int iters) {
}
}
void bench_hmac_sha256(void* arg, int iters) {
static void bench_hmac_sha256(void* arg, int iters) {
int i;
bench_inv *data = (bench_inv*)arg;
secp256k1_hmac_sha256 hmac;
@@ -342,7 +390,7 @@ void bench_hmac_sha256(void* arg, int iters) {
}
}
void bench_rfc6979_hmac_sha256(void* arg, int iters) {
static void bench_rfc6979_hmac_sha256(void* arg, int iters) {
int i;
bench_inv *data = (bench_inv*)arg;
secp256k1_rfc6979_hmac_sha256 rng;
@@ -353,79 +401,65 @@ void bench_rfc6979_hmac_sha256(void* arg, int iters) {
}
}
void bench_context_verify(void* arg, int iters) {
static void bench_context(void* arg, int iters) {
int i;
(void)arg;
for (i = 0; i < iters; i++) {
secp256k1_context_destroy(secp256k1_context_create(SECP256K1_CONTEXT_VERIFY));
secp256k1_context_destroy(secp256k1_context_create(SECP256K1_CONTEXT_NONE));
}
}
void bench_context_sign(void* arg, int iters) {
int i;
(void)arg;
for (i = 0; i < iters; i++) {
secp256k1_context_destroy(secp256k1_context_create(SECP256K1_CONTEXT_SIGN));
}
}
#ifndef USE_NUM_NONE
void bench_num_jacobi(void* arg, int iters) {
int i, j = 0;
bench_inv *data = (bench_inv*)arg;
secp256k1_num nx, na, norder;
secp256k1_scalar_get_num(&nx, &data->scalar[0]);
secp256k1_scalar_order_get_num(&norder);
secp256k1_scalar_get_num(&na, &data->scalar[1]);
for (i = 0; i < iters; i++) {
j += secp256k1_num_jacobi(&nx, &norder);
secp256k1_num_add(&nx, &nx, &na);
}
CHECK(j <= iters);
}
#endif
int main(int argc, char **argv) {
bench_inv data;
int iters = get_iters(20000);
int default_iters = 20000;
int iters = get_iters(default_iters);
int d = argc == 1; /* default */
if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "add")) run_benchmark("scalar_add", bench_scalar_add, bench_setup, NULL, &data, 10, iters*100);
if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "negate")) run_benchmark("scalar_negate", bench_scalar_negate, bench_setup, NULL, &data, 10, iters*100);
if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "sqr")) run_benchmark("scalar_sqr", bench_scalar_sqr, bench_setup, NULL, &data, 10, iters*10);
if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "mul")) run_benchmark("scalar_mul", bench_scalar_mul, bench_setup, NULL, &data, 10, iters*10);
if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "split")) run_benchmark("scalar_split", bench_scalar_split, bench_setup, NULL, &data, 10, iters);
if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse", bench_scalar_inverse, bench_setup, NULL, &data, 10, 2000);
if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse_var", bench_scalar_inverse_var, bench_setup, NULL, &data, 10, 2000);
if (argc > 1) {
if (have_flag(argc, argv, "-h")
|| have_flag(argc, argv, "--help")
|| have_flag(argc, argv, "help")) {
help(default_iters);
return 0;
}
}
if (have_flag(argc, argv, "field") || have_flag(argc, argv, "normalize")) run_benchmark("field_normalize", bench_field_normalize, bench_setup, NULL, &data, 10, iters*100);
if (have_flag(argc, argv, "field") || have_flag(argc, argv, "normalize")) run_benchmark("field_normalize_weak", bench_field_normalize_weak, bench_setup, NULL, &data, 10, iters*100);
if (have_flag(argc, argv, "field") || have_flag(argc, argv, "sqr")) run_benchmark("field_sqr", bench_field_sqr, bench_setup, NULL, &data, 10, iters*10);
if (have_flag(argc, argv, "field") || have_flag(argc, argv, "mul")) run_benchmark("field_mul", bench_field_mul, bench_setup, NULL, &data, 10, iters*10);
if (have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse", bench_field_inverse, bench_setup, NULL, &data, 10, iters);
if (have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse_var", bench_field_inverse_var, bench_setup, NULL, &data, 10, iters);
if (have_flag(argc, argv, "field") || have_flag(argc, argv, "sqrt")) run_benchmark("field_sqrt", bench_field_sqrt, bench_setup, NULL, &data, 10, iters);
print_output_table_header_row();
if (have_flag(argc, argv, "group") || have_flag(argc, argv, "double")) run_benchmark("group_double_var", bench_group_double_var, bench_setup, NULL, &data, 10, iters*10);
if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_var", bench_group_add_var, bench_setup, NULL, &data, 10, iters*10);
if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine", bench_group_add_affine, bench_setup, NULL, &data, 10, iters*10);
if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine_var", bench_group_add_affine_var, bench_setup, NULL, &data, 10, iters*10);
if (have_flag(argc, argv, "group") || have_flag(argc, argv, "jacobi")) run_benchmark("group_jacobi_var", bench_group_jacobi_var, bench_setup, NULL, &data, 10, iters);
if (have_flag(argc, argv, "group") || have_flag(argc, argv, "to_affine")) run_benchmark("group_to_affine_var", bench_group_to_affine_var, bench_setup, NULL, &data, 10, iters);
if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "half")) run_benchmark("scalar_half", bench_scalar_half, bench_setup, NULL, &data, 10, iters*100);
if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "add")) run_benchmark("scalar_add", bench_scalar_add, bench_setup, NULL, &data, 10, iters*100);
if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "negate")) run_benchmark("scalar_negate", bench_scalar_negate, bench_setup, NULL, &data, 10, iters*100);
if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "sqr")) run_benchmark("scalar_sqr", bench_scalar_sqr, bench_setup, NULL, &data, 10, iters*10);
if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "mul")) run_benchmark("scalar_mul", bench_scalar_mul, bench_setup, NULL, &data, 10, iters*10);
if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "split")) run_benchmark("scalar_split", bench_scalar_split, bench_setup, NULL, &data, 10, iters);
if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse", bench_scalar_inverse, bench_setup, NULL, &data, 10, iters);
if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse_var", bench_scalar_inverse_var, bench_setup, NULL, &data, 10, iters);
if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("wnaf_const", bench_wnaf_const, bench_setup, NULL, &data, 10, iters);
if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("ecmult_wnaf", bench_ecmult_wnaf, bench_setup, NULL, &data, 10, iters);
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "half")) run_benchmark("field_half", bench_field_half, bench_setup, NULL, &data, 10, iters*100);
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "normalize")) run_benchmark("field_normalize", bench_field_normalize, bench_setup, NULL, &data, 10, iters*100);
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "normalize")) run_benchmark("field_normalize_weak", bench_field_normalize_weak, bench_setup, NULL, &data, 10, iters*100);
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "sqr")) run_benchmark("field_sqr", bench_field_sqr, bench_setup, NULL, &data, 10, iters*10);
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "mul")) run_benchmark("field_mul", bench_field_mul, bench_setup, NULL, &data, 10, iters*10);
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse", bench_field_inverse, bench_setup, NULL, &data, 10, iters);
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse_var", bench_field_inverse_var, bench_setup, NULL, &data, 10, iters);
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "issquare")) run_benchmark("field_is_square_var", bench_field_is_square_var, bench_setup, NULL, &data, 10, iters);
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "sqrt")) run_benchmark("field_sqrt", bench_field_sqrt, bench_setup, NULL, &data, 10, iters);
if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "sha256")) run_benchmark("hash_sha256", bench_sha256, bench_setup, NULL, &data, 10, iters);
if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "hmac")) run_benchmark("hash_hmac_sha256", bench_hmac_sha256, bench_setup, NULL, &data, 10, iters);
if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "rng6979")) run_benchmark("hash_rfc6979_hmac_sha256", bench_rfc6979_hmac_sha256, bench_setup, NULL, &data, 10, iters);
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "double")) run_benchmark("group_double_var", bench_group_double_var, bench_setup, NULL, &data, 10, iters*10);
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_var", bench_group_add_var, bench_setup, NULL, &data, 10, iters*10);
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine", bench_group_add_affine, bench_setup, NULL, &data, 10, iters*10);
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine_var", bench_group_add_affine_var, bench_setup, NULL, &data, 10, iters*10);
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "jacobi")) run_benchmark("group_jacobi_var", bench_group_jacobi_var, bench_setup, NULL, &data, 10, iters);
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_zinv_var", bench_group_add_zinv_var, bench_setup, NULL, &data, 10, iters*10);
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "to_affine")) run_benchmark("group_to_affine_var", bench_group_to_affine_var, bench_setup, NULL, &data, 10, iters);
if (have_flag(argc, argv, "context") || have_flag(argc, argv, "verify")) run_benchmark("context_verify", bench_context_verify, bench_setup, NULL, &data, 10, 1 + iters/1000);
if (have_flag(argc, argv, "context") || have_flag(argc, argv, "sign")) run_benchmark("context_sign", bench_context_sign, bench_setup, NULL, &data, 10, 1 + iters/100);
if (d || have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("ecmult_wnaf", bench_ecmult_wnaf, bench_setup, NULL, &data, 10, iters);
if (d || have_flag(argc, argv, "hash") || have_flag(argc, argv, "sha256")) run_benchmark("hash_sha256", bench_sha256, bench_setup, NULL, &data, 10, iters);
if (d || have_flag(argc, argv, "hash") || have_flag(argc, argv, "hmac")) run_benchmark("hash_hmac_sha256", bench_hmac_sha256, bench_setup, NULL, &data, 10, iters);
if (d || have_flag(argc, argv, "hash") || have_flag(argc, argv, "rng6979")) run_benchmark("hash_rfc6979_hmac_sha256", bench_rfc6979_hmac_sha256, bench_setup, NULL, &data, 10, iters);
if (d || have_flag(argc, argv, "context")) run_benchmark("context_create", bench_context, bench_setup, NULL, &data, 10, iters);
#ifndef USE_NUM_NONE
if (have_flag(argc, argv, "num") || have_flag(argc, argv, "jacobi")) run_benchmark("num_jacobi", bench_num_jacobi, bench_setup, NULL, &data, 10, iters*10);
#endif
return 0;
}

View File

@@ -6,7 +6,7 @@
#include <stdint.h>
#include "include/secp256k1_rangeproof.h"
#include "../include/secp256k1_rangeproof.h"
#include "util.h"
#include "bench.h"
@@ -53,7 +53,7 @@ int main(void) {
bench_rangeproof_t data;
int iters;
data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
data.min_bits = 32;
iters = data.min_bits*get_iters(32);

View File

@@ -1,58 +0,0 @@
/**********************************************************************
* Copyright (c) 2014 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
#include "include/secp256k1.h"
#include "util.h"
#include "bench.h"
typedef struct {
secp256k1_context* ctx;
unsigned char msg[32];
unsigned char key[32];
} bench_sign_data;
static void bench_sign_setup(void* arg) {
int i;
bench_sign_data *data = (bench_sign_data*)arg;
for (i = 0; i < 32; i++) {
data->msg[i] = i + 1;
}
for (i = 0; i < 32; i++) {
data->key[i] = i + 65;
}
}
static void bench_sign_run(void* arg, int iters) {
int i;
bench_sign_data *data = (bench_sign_data*)arg;
unsigned char sig[74];
for (i = 0; i < iters; i++) {
size_t siglen = 74;
int j;
secp256k1_ecdsa_signature signature;
CHECK(secp256k1_ecdsa_sign(data->ctx, &signature, data->msg, data->key, NULL, NULL));
CHECK(secp256k1_ecdsa_signature_serialize_der(data->ctx, sig, &siglen, &signature));
for (j = 0; j < 32; j++) {
data->msg[j] = sig[j];
data->key[j] = sig[j + 32];
}
}
}
int main(void) {
bench_sign_data data;
int iters = get_iters(20000);
data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
run_benchmark("ecdsa_sign", bench_sign_run, bench_sign_setup, NULL, &data, 10, iters);
secp256k1_context_destroy(data.ctx);
return 0;
}

View File

@@ -1,115 +0,0 @@
/**********************************************************************
* Copyright (c) 2014 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
#include <stdio.h>
#include <string.h>
#include "include/secp256k1.h"
#include "util.h"
#include "bench.h"
#ifdef ENABLE_OPENSSL_TESTS
#include <openssl/bn.h>
#include <openssl/ecdsa.h>
#include <openssl/obj_mac.h>
#endif
typedef struct {
secp256k1_context *ctx;
unsigned char msg[32];
unsigned char key[32];
unsigned char sig[72];
size_t siglen;
unsigned char pubkey[33];
size_t pubkeylen;
#ifdef ENABLE_OPENSSL_TESTS
EC_GROUP* ec_group;
#endif
} bench_verify_data;
static void bench_verify(void* arg, int iters) {
int i;
bench_verify_data* data = (bench_verify_data*)arg;
for (i = 0; i < iters; i++) {
secp256k1_pubkey pubkey;
secp256k1_ecdsa_signature sig;
data->sig[data->siglen - 1] ^= (i & 0xFF);
data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);
data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);
CHECK(secp256k1_ec_pubkey_parse(data->ctx, &pubkey, data->pubkey, data->pubkeylen) == 1);
CHECK(secp256k1_ecdsa_signature_parse_der(data->ctx, &sig, data->sig, data->siglen) == 1);
CHECK(secp256k1_ecdsa_verify(data->ctx, &sig, data->msg, &pubkey) == (i == 0));
data->sig[data->siglen - 1] ^= (i & 0xFF);
data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);
data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);
}
}
#ifdef ENABLE_OPENSSL_TESTS
static void bench_verify_openssl(void* arg, int iters) {
int i;
bench_verify_data* data = (bench_verify_data*)arg;
for (i = 0; i < iters; i++) {
data->sig[data->siglen - 1] ^= (i & 0xFF);
data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);
data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);
{
EC_KEY *pkey = EC_KEY_new();
const unsigned char *pubkey = &data->pubkey[0];
int result;
CHECK(pkey != NULL);
result = EC_KEY_set_group(pkey, data->ec_group);
CHECK(result);
result = (o2i_ECPublicKey(&pkey, &pubkey, data->pubkeylen)) != NULL;
CHECK(result);
result = ECDSA_verify(0, &data->msg[0], sizeof(data->msg), &data->sig[0], data->siglen, pkey) == (i == 0);
CHECK(result);
EC_KEY_free(pkey);
}
data->sig[data->siglen - 1] ^= (i & 0xFF);
data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);
data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);
}
}
#endif
int main(void) {
int i;
secp256k1_pubkey pubkey;
secp256k1_ecdsa_signature sig;
bench_verify_data data;
int iters = get_iters(20000);
data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
for (i = 0; i < 32; i++) {
data.msg[i] = 1 + i;
}
for (i = 0; i < 32; i++) {
data.key[i] = 33 + i;
}
data.siglen = 72;
CHECK(secp256k1_ecdsa_sign(data.ctx, &sig, data.msg, data.key, NULL, NULL));
CHECK(secp256k1_ecdsa_signature_serialize_der(data.ctx, data.sig, &data.siglen, &sig));
CHECK(secp256k1_ec_pubkey_create(data.ctx, &pubkey, data.key));
data.pubkeylen = 33;
CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED) == 1);
run_benchmark("ecdsa_verify", bench_verify, NULL, NULL, &data, 10, iters);
#ifdef ENABLE_OPENSSL_TESTS
data.ec_group = EC_GROUP_new_by_curve_name(NID_secp256k1);
run_benchmark("ecdsa_verify_openssl", bench_verify_openssl, NULL, NULL, &data, 10, iters);
EC_GROUP_free(data.ec_group);
#endif
secp256k1_context_destroy(data.ctx);
return 0;
}

View File

@@ -5,13 +5,13 @@
**********************************************************************/
#include <stdio.h>
#include "include/secp256k1.h"
#include "../include/secp256k1.h"
#include "include/secp256k1_whitelist.h"
#include "../include/secp256k1_whitelist.h"
#include "util.h"
#include "bench.h"
#include "hash_impl.h"
#include "num_impl.h"
#include "int128_impl.h"
#include "scalar_impl.h"
#include "testrand_impl.h"
@@ -40,7 +40,7 @@ static void bench_whitelist(void* arg, int iters) {
static void bench_whitelist_setup(void* arg) {
bench_data* data = (bench_data*)arg;
int i = 0;
CHECK(secp256k1_whitelist_sign(data->ctx, &data->sig, data->online_pubkeys, data->offline_pubkeys, data->n_keys, &data->sub_pubkey, data->online_seckey[i], data->summed_seckey[i], i, NULL, NULL));
CHECK(secp256k1_whitelist_sign(data->ctx, &data->sig, data->online_pubkeys, data->offline_pubkeys, data->n_keys, &data->sub_pubkey, data->online_seckey[i], data->summed_seckey[i], i));
}
static void run_test(bench_data* data, int iters) {
@@ -49,7 +49,7 @@ static void run_test(bench_data* data, int iters) {
run_benchmark(str, bench_whitelist, bench_whitelist_setup, NULL, data, 100, iters);
}
void random_scalar_order(secp256k1_scalar *num) {
static void random_scalar_order(secp256k1_scalar *num) {
do {
unsigned char b32[32];
int overflow = 0;
@@ -69,7 +69,7 @@ int main(void) {
secp256k1_scalar ssub;
int iters = get_iters(5);
data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
/* Start with subkey */
random_scalar_order(&ssub);

95
src/checkmem.h Normal file
View File

@@ -0,0 +1,95 @@
/***********************************************************************
* Copyright (c) 2022 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
/* The code here is inspired by Kris Kwiatkowski's approach in
* https://github.com/kriskwiatkowski/pqc/blob/main/src/common/ct_check.h
* to provide a general interface for memory-checking mechanisms, primarily
* for constant-time checking.
*/
/* These macros are defined by this header file:
*
* - SECP256K1_CHECKMEM_ENABLED:
* - 1 if memory-checking integration is available, 0 otherwise.
* This is just a compile-time macro. Use the next macro to check it is actually
* available at runtime.
* - SECP256K1_CHECKMEM_RUNNING():
* - Acts like a function call, returning 1 if memory checking is available
* at runtime.
* - SECP256K1_CHECKMEM_CHECK(p, len):
* - Assert or otherwise fail in case the len-byte memory block pointed to by p is
* not considered entirely defined.
* - SECP256K1_CHECKMEM_CHECK_VERIFY(p, len):
* - Like SECP256K1_CHECKMEM_CHECK, but only works in VERIFY mode.
* - SECP256K1_CHECKMEM_UNDEFINE(p, len):
* - marks the len-byte memory block pointed to by p as undefined data (secret data,
* in the context of constant-time checking).
* - SECP256K1_CHECKMEM_DEFINE(p, len):
* - marks the len-byte memory pointed to by p as defined data (public data, in the
* context of constant-time checking).
*
*/
#ifndef SECP256K1_CHECKMEM_H
#define SECP256K1_CHECKMEM_H
/* Define a statement-like macro that ignores the arguments. */
#define SECP256K1_CHECKMEM_NOOP(p, len) do { (void)(p); (void)(len); } while(0)
/* If compiling under msan, map the SECP256K1_CHECKMEM_* functionality to msan.
* Choose this preferentially, even when VALGRIND is defined, as msan-compiled
* binaries can't be run under valgrind anyway. */
#if defined(__has_feature)
# if __has_feature(memory_sanitizer)
# include <sanitizer/msan_interface.h>
# define SECP256K1_CHECKMEM_ENABLED 1
# define SECP256K1_CHECKMEM_UNDEFINE(p, len) __msan_allocated_memory((p), (len))
# define SECP256K1_CHECKMEM_DEFINE(p, len) __msan_unpoison((p), (len))
# define SECP256K1_CHECKMEM_CHECK(p, len) __msan_check_mem_is_initialized((p), (len))
# define SECP256K1_CHECKMEM_RUNNING() (1)
# endif
#endif
/* If valgrind integration is desired (through the VALGRIND define), implement the
* SECP256K1_CHECKMEM_* macros using valgrind. */
#if !defined SECP256K1_CHECKMEM_ENABLED
# if defined VALGRIND
# include <stddef.h>
# if defined(__clang__) && defined(__APPLE__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wreserved-identifier"
# endif
# include <valgrind/memcheck.h>
# if defined(__clang__) && defined(__APPLE__)
# pragma clang diagnostic pop
# endif
# define SECP256K1_CHECKMEM_ENABLED 1
# define SECP256K1_CHECKMEM_UNDEFINE(p, len) VALGRIND_MAKE_MEM_UNDEFINED((p), (len))
# define SECP256K1_CHECKMEM_DEFINE(p, len) VALGRIND_MAKE_MEM_DEFINED((p), (len))
# define SECP256K1_CHECKMEM_CHECK(p, len) VALGRIND_CHECK_MEM_IS_DEFINED((p), (len))
/* VALGRIND_MAKE_MEM_DEFINED returns 0 iff not running on memcheck.
* This is more precise than the RUNNING_ON_VALGRIND macro, which
* checks for valgrind in general instead of memcheck specifically. */
# define SECP256K1_CHECKMEM_RUNNING() (VALGRIND_MAKE_MEM_DEFINED(NULL, 0) != 0)
# endif
#endif
/* As a fall-back, map these macros to dummy statements. */
#if !defined SECP256K1_CHECKMEM_ENABLED
# define SECP256K1_CHECKMEM_ENABLED 0
# define SECP256K1_CHECKMEM_UNDEFINE(p, len) SECP256K1_CHECKMEM_NOOP((p), (len))
# define SECP256K1_CHECKMEM_DEFINE(p, len) SECP256K1_CHECKMEM_NOOP((p), (len))
# define SECP256K1_CHECKMEM_CHECK(p, len) SECP256K1_CHECKMEM_NOOP((p), (len))
# define SECP256K1_CHECKMEM_RUNNING() (0)
#endif
#if defined VERIFY
#define SECP256K1_CHECKMEM_CHECK_VERIFY(p, len) SECP256K1_CHECKMEM_CHECK((p), (len))
#else
#define SECP256K1_CHECKMEM_CHECK_VERIFY(p, len) SECP256K1_CHECKMEM_NOOP((p), (len))
#endif
#endif /* SECP256K1_CHECKMEM_H */

471
src/ctime_tests.c Normal file
View File

@@ -0,0 +1,471 @@
/***********************************************************************
* Copyright (c) 2020 Gregory Maxwell *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#include <stdio.h>
#include <string.h>
#include "../include/secp256k1.h"
#include "assumptions.h"
#include "checkmem.h"
#if !SECP256K1_CHECKMEM_ENABLED
# error "This tool cannot be compiled without memory-checking interface (valgrind or msan)"
#endif
#ifdef ENABLE_MODULE_ECDH
# include "../include/secp256k1_ecdh.h"
#endif
#ifdef ENABLE_MODULE_RECOVERY
# include "../include/secp256k1_recovery.h"
#endif
#ifdef ENABLE_MODULE_EXTRAKEYS
# include "../include/secp256k1_extrakeys.h"
#endif
#ifdef ENABLE_MODULE_SCHNORRSIG
#include "../include/secp256k1_schnorrsig.h"
#endif
#ifdef ENABLE_MODULE_ELLSWIFT
#include "../include/secp256k1_ellswift.h"
#endif
#ifdef ENABLE_MODULE_ECDSA_S2C
#include "../include/secp256k1_ecdsa_s2c.h"
#endif
#ifdef ENABLE_MODULE_ECDSA_ADAPTOR
#include "../include/secp256k1_ecdsa_adaptor.h"
#endif
#ifdef ENABLE_MODULE_MUSIG
#include "../include/secp256k1_musig.h"
#endif
#ifdef ENABLE_MODULE_FROST
#include "include/secp256k1_frost.h"
#endif
static void run_tests(secp256k1_context *ctx, unsigned char *key);
int main(void) {
secp256k1_context* ctx;
unsigned char key[32];
int ret, i;
if (!SECP256K1_CHECKMEM_RUNNING()) {
fprintf(stderr, "This test can only usefully be run inside valgrind because it was not compiled under msan.\n");
fprintf(stderr, "Usage: libtool --mode=execute valgrind ./ctime_tests\n");
return 1;
}
ctx = secp256k1_context_create(SECP256K1_CONTEXT_DECLASSIFY);
/** In theory, testing with a single secret input should be sufficient:
* If control flow depended on secrets the tool would generate an error.
*/
for (i = 0; i < 32; i++) {
key[i] = i + 65;
}
run_tests(ctx, key);
/* Test context randomisation. Do this last because it leaves the context
* tainted. */
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
ret = secp256k1_context_randomize(ctx, key);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret);
secp256k1_context_destroy(ctx);
return 0;
}
static void run_tests(secp256k1_context *ctx, unsigned char *key) {
secp256k1_ecdsa_signature signature;
secp256k1_pubkey pubkey;
size_t siglen = 74;
size_t outputlen = 33;
int i;
int ret;
unsigned char msg[32];
unsigned char sig[74];
unsigned char spubkey[33];
#ifdef ENABLE_MODULE_RECOVERY
secp256k1_ecdsa_recoverable_signature recoverable_signature;
int recid;
#endif
#ifdef ENABLE_MODULE_EXTRAKEYS
secp256k1_keypair keypair;
#endif
#ifdef ENABLE_MODULE_ELLSWIFT
unsigned char ellswift[64];
static const unsigned char prefix[64] = {'t', 'e', 's', 't'};
#endif
for (i = 0; i < 32; i++) {
msg[i] = i + 1;
}
/* Test keygen. */
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
ret = secp256k1_ec_pubkey_create(ctx, &pubkey, key);
SECP256K1_CHECKMEM_DEFINE(&pubkey, sizeof(secp256k1_pubkey));
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret);
CHECK(secp256k1_ec_pubkey_serialize(ctx, spubkey, &outputlen, &pubkey, SECP256K1_EC_COMPRESSED) == 1);
/* Test signing. */
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
ret = secp256k1_ecdsa_sign(ctx, &signature, msg, key, NULL, NULL);
SECP256K1_CHECKMEM_DEFINE(&signature, sizeof(secp256k1_ecdsa_signature));
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret);
CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, sig, &siglen, &signature));
#ifdef ENABLE_MODULE_ECDH
/* Test ECDH. */
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
ret = secp256k1_ecdh(ctx, msg, &pubkey, key, NULL, NULL);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
#endif
#ifdef ENABLE_MODULE_RECOVERY
/* Test signing a recoverable signature. */
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
ret = secp256k1_ecdsa_sign_recoverable(ctx, &recoverable_signature, msg, key, NULL, NULL);
SECP256K1_CHECKMEM_DEFINE(&recoverable_signature, sizeof(recoverable_signature));
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret);
CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &recoverable_signature));
CHECK(recid >= 0 && recid <= 3);
#endif
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
ret = secp256k1_ec_seckey_verify(ctx, key);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
ret = secp256k1_ec_seckey_negate(ctx, key);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
SECP256K1_CHECKMEM_UNDEFINE(msg, 32);
ret = secp256k1_ec_seckey_tweak_add(ctx, key, msg);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
SECP256K1_CHECKMEM_UNDEFINE(msg, 32);
ret = secp256k1_ec_seckey_tweak_mul(ctx, key, msg);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
/* Test keypair_create and keypair_xonly_tweak_add. */
#ifdef ENABLE_MODULE_EXTRAKEYS
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
ret = secp256k1_keypair_create(ctx, &keypair, key);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
/* The tweak is not treated as a secret in keypair_tweak_add */
SECP256K1_CHECKMEM_DEFINE(msg, 32);
ret = secp256k1_keypair_xonly_tweak_add(ctx, &keypair, msg);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
SECP256K1_CHECKMEM_UNDEFINE(&keypair, sizeof(keypair));
ret = secp256k1_keypair_sec(ctx, key, &keypair);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
#endif
#ifdef ENABLE_MODULE_SCHNORRSIG
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
ret = secp256k1_keypair_create(ctx, &keypair, key);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
ret = secp256k1_schnorrsig_sign32(ctx, sig, msg, &keypair, NULL);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
#endif
#ifdef ENABLE_MODULE_ELLSWIFT
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
ret = secp256k1_ellswift_create(ctx, ellswift, key, NULL);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
ret = secp256k1_ellswift_create(ctx, ellswift, key, ellswift);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
for (i = 0; i < 2; i++) {
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
SECP256K1_CHECKMEM_DEFINE(&ellswift, sizeof(ellswift));
ret = secp256k1_ellswift_xdh(ctx, msg, ellswift, ellswift, key, i, secp256k1_ellswift_xdh_hash_function_bip324, NULL);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
SECP256K1_CHECKMEM_DEFINE(&ellswift, sizeof(ellswift));
ret = secp256k1_ellswift_xdh(ctx, msg, ellswift, ellswift, key, i, secp256k1_ellswift_xdh_hash_function_prefix, (void *)prefix);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
}
#endif
#ifdef ENABLE_MODULE_ECDSA_S2C
{
unsigned char s2c_data[32] = {0};
unsigned char s2c_data_comm[32] = {0};
secp256k1_ecdsa_s2c_opening s2c_opening;
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
SECP256K1_CHECKMEM_UNDEFINE(s2c_data, 32);
ret = secp256k1_ecdsa_s2c_sign(ctx, &signature, &s2c_opening, msg, key, s2c_data);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
SECP256K1_CHECKMEM_UNDEFINE(s2c_data, 32);
ret = secp256k1_ecdsa_anti_exfil_host_commit(ctx, s2c_data_comm, s2c_data);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
SECP256K1_CHECKMEM_UNDEFINE(s2c_data, 32);
ret = secp256k1_ecdsa_anti_exfil_signer_commit(ctx, &s2c_opening, msg, key, s2c_data);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
}
#endif
#ifdef ENABLE_MODULE_ECDSA_ADAPTOR
{
unsigned char adaptor_sig[162];
unsigned char deckey[32];
unsigned char expected_deckey[32];
secp256k1_pubkey enckey;
for (i = 0; i < 32; i++) {
deckey[i] = i + 2;
}
ret = secp256k1_ec_pubkey_create(ctx, &enckey, deckey);
CHECK(ret == 1);
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
ret = secp256k1_ecdsa_adaptor_encrypt(ctx, adaptor_sig, key, &enckey, msg, NULL, NULL);
SECP256K1_CHECKMEM_DEFINE(adaptor_sig, sizeof(adaptor_sig));
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
SECP256K1_CHECKMEM_UNDEFINE(deckey, 32);
ret = secp256k1_ecdsa_adaptor_decrypt(ctx, &signature, deckey, adaptor_sig);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
SECP256K1_CHECKMEM_UNDEFINE(&signature, 32);
ret = secp256k1_ecdsa_adaptor_recover(ctx, expected_deckey, &signature, adaptor_sig, &enckey);
SECP256K1_CHECKMEM_DEFINE(expected_deckey, sizeof(expected_deckey));
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
SECP256K1_CHECKMEM_DEFINE(deckey, sizeof(deckey));
ret = secp256k1_memcmp_var(deckey, expected_deckey, sizeof(expected_deckey));
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 0);
}
#endif
#ifdef ENABLE_MODULE_MUSIG
{
secp256k1_pubkey pk;
const secp256k1_pubkey *pk_ptr[1];
secp256k1_xonly_pubkey agg_pk;
unsigned char session_id[32];
secp256k1_musig_secnonce secnonce;
secp256k1_musig_pubnonce pubnonce;
const secp256k1_musig_pubnonce *pubnonce_ptr[1];
secp256k1_musig_aggnonce aggnonce;
secp256k1_musig_keyagg_cache cache;
secp256k1_musig_session session;
secp256k1_musig_partial_sig partial_sig;
const secp256k1_musig_partial_sig *partial_sig_ptr[1];
unsigned char extra_input[32];
unsigned char sec_adaptor[32];
secp256k1_pubkey adaptor;
unsigned char pre_sig[64];
int nonce_parity;
pk_ptr[0] = &pk;
pubnonce_ptr[0] = &pubnonce;
SECP256K1_CHECKMEM_DEFINE(key, 32);
memcpy(session_id, key, sizeof(session_id));
session_id[0] = session_id[0] + 1;
memcpy(extra_input, key, sizeof(extra_input));
extra_input[0] = extra_input[0] + 2;
memcpy(sec_adaptor, key, sizeof(sec_adaptor));
sec_adaptor[0] = extra_input[0] + 3;
partial_sig_ptr[0] = &partial_sig;
CHECK(secp256k1_keypair_create(ctx, &keypair, key));
CHECK(secp256k1_keypair_pub(ctx, &pk, &keypair));
CHECK(secp256k1_musig_pubkey_agg(ctx, NULL, &agg_pk, &cache, pk_ptr, 1));
CHECK(secp256k1_ec_pubkey_create(ctx, &adaptor, sec_adaptor));
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
SECP256K1_CHECKMEM_UNDEFINE(session_id, sizeof(session_id));
SECP256K1_CHECKMEM_UNDEFINE(extra_input, sizeof(extra_input));
SECP256K1_CHECKMEM_UNDEFINE(sec_adaptor, sizeof(sec_adaptor));
ret = secp256k1_musig_nonce_gen(ctx, &secnonce, &pubnonce, session_id, key, &pk, msg, &cache, extra_input);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
CHECK(secp256k1_musig_nonce_agg(ctx, &aggnonce, pubnonce_ptr, 1));
/* Make sure that previous tests don't undefine msg. It's not used as a secret here. */
SECP256K1_CHECKMEM_DEFINE(msg, sizeof(msg));
CHECK(secp256k1_musig_nonce_process(ctx, &session, &aggnonce, msg, &cache, &adaptor) == 1);
ret = secp256k1_keypair_create(ctx, &keypair, key);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
ret = secp256k1_musig_partial_sign(ctx, &partial_sig, &secnonce, &keypair, &cache, &session);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
SECP256K1_CHECKMEM_DEFINE(&partial_sig, sizeof(partial_sig));
CHECK(secp256k1_musig_partial_sig_agg(ctx, pre_sig, &session, partial_sig_ptr, 1));
SECP256K1_CHECKMEM_DEFINE(pre_sig, sizeof(pre_sig));
CHECK(secp256k1_musig_nonce_parity(ctx, &nonce_parity, &session));
ret = secp256k1_musig_adapt(ctx, sig, pre_sig, sec_adaptor, nonce_parity);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
ret = secp256k1_musig_extract_adaptor(ctx, sec_adaptor, sig, pre_sig, nonce_parity);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
}
#endif
#ifdef ENABLE_MODULE_FROST
{
secp256k1_pubkey pk[2];
secp256k1_xonly_pubkey agg_pk;
unsigned char session_id[32];
unsigned char seed[2][32];
secp256k1_frost_secnonce secnonce[2];
secp256k1_frost_pubnonce pubnonce[2];
const secp256k1_frost_pubnonce *pubnonce_ptr[2];
secp256k1_frost_tweak_cache cache;
secp256k1_frost_session session;
secp256k1_frost_partial_sig partial_sig;
const secp256k1_frost_partial_sig *partial_sig_ptr[1];
unsigned char extra_input[32];
unsigned char sec_adaptor[32];
secp256k1_pubkey adaptor;
unsigned char pre_sig[64];
int nonce_parity;
secp256k1_frost_share shares[2][2];
const secp256k1_frost_share *share_ptr[2];
secp256k1_frost_share agg_share;
const secp256k1_pubkey *vss_ptr[2];
unsigned char pok[2][64];
secp256k1_pubkey vss_commitment[2][2];
unsigned char key2[32];
secp256k1_keypair keypair2;
unsigned char id[2][33];
const unsigned char *id_ptr[2];
size_t size = 33;
id_ptr[0] = id[0];
id_ptr[1] = id[1];
pubnonce_ptr[0] = &pubnonce[0];
pubnonce_ptr[1] = &pubnonce[1];
SECP256K1_CHECKMEM_DEFINE(key, 32);
memcpy(seed[0], key, 32);
seed[0][0] = seed[0][0] + 1;
memcpy(seed[0], key, 32);
seed[1][0] = seed[1][0] + 2;
memcpy(extra_input, key, sizeof(extra_input));
extra_input[0] = extra_input[0] + 3;
memcpy(sec_adaptor, key, sizeof(sec_adaptor));
sec_adaptor[0] = extra_input[0] + 4;
memcpy(key2, key, sizeof(key2));
key2[0] = key2[0] + 5;
memcpy(session_id, key, sizeof(session_id));
session_id[0] = session_id[0] + 6;
partial_sig_ptr[0] = &partial_sig;
share_ptr[0] = &shares[0][0];
share_ptr[1] = &shares[1][0];
vss_ptr[0] = vss_commitment[0];
vss_ptr[1] = vss_commitment[1];
CHECK(secp256k1_keypair_create(ctx, &keypair, key));
CHECK(secp256k1_keypair_create(ctx, &keypair2, key2));
CHECK(secp256k1_keypair_pub(ctx, &pk[0], &keypair));
CHECK(secp256k1_keypair_pub(ctx, &pk[1], &keypair2));
CHECK(secp256k1_ec_pubkey_serialize(ctx, id[0], &size, &pk[0], SECP256K1_EC_COMPRESSED));
CHECK(secp256k1_ec_pubkey_serialize(ctx, id[1], &size, &pk[1], SECP256K1_EC_COMPRESSED));
/* shares_gen */
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
SECP256K1_CHECKMEM_UNDEFINE(key2, 32);
SECP256K1_CHECKMEM_UNDEFINE(seed[0], 32);
SECP256K1_CHECKMEM_UNDEFINE(seed[1], 32);
ret = secp256k1_frost_shares_gen(ctx, shares[0], vss_commitment[0], pok[0], seed[0], 2, 2, id_ptr);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
ret = secp256k1_frost_shares_gen(ctx, shares[1], vss_commitment[1], pok[1], seed[1], 2, 2, id_ptr);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
/* share_agg */
SECP256K1_CHECKMEM_DEFINE(&vss_commitment[0][0], sizeof(secp256k1_pubkey));
SECP256K1_CHECKMEM_DEFINE(&vss_commitment[0][1], sizeof(secp256k1_pubkey));
SECP256K1_CHECKMEM_DEFINE(&vss_commitment[1][0], sizeof(secp256k1_pubkey));
SECP256K1_CHECKMEM_DEFINE(&vss_commitment[1][1], sizeof(secp256k1_pubkey));
SECP256K1_CHECKMEM_DEFINE(pok[0], 64);
ret = secp256k1_frost_share_agg(ctx, &agg_share, &agg_pk, share_ptr, vss_ptr, 2, 2, id_ptr[0]);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
/* nonce_gen */
SECP256K1_CHECKMEM_UNDEFINE(session_id, sizeof(session_id));
CHECK(secp256k1_ec_pubkey_create(ctx, &adaptor, sec_adaptor));
SECP256K1_CHECKMEM_UNDEFINE(extra_input, sizeof(extra_input));
SECP256K1_CHECKMEM_UNDEFINE(sec_adaptor, sizeof(sec_adaptor));
CHECK(secp256k1_frost_pubkey_tweak(ctx, &cache, &agg_pk) == 1);
ret = secp256k1_frost_nonce_gen(ctx, &secnonce[0], &pubnonce[0], session_id, &agg_share, msg, &agg_pk, extra_input);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
ret = secp256k1_frost_nonce_gen(ctx, &secnonce[1], &pubnonce[1], session_id, &agg_share, msg, &agg_pk, extra_input);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
/* partial_sign */
CHECK(secp256k1_frost_nonce_process(ctx, &session, pubnonce_ptr, 2, msg, &agg_pk, id_ptr[0], id_ptr, &cache, &adaptor) == 1);
ret = secp256k1_keypair_create(ctx, &keypair, key);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
ret = secp256k1_frost_partial_sign(ctx, &partial_sig, &secnonce[0], &agg_share, &session, &cache);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
/* adapt */
SECP256K1_CHECKMEM_DEFINE(&partial_sig, sizeof(partial_sig));
CHECK(secp256k1_frost_partial_sig_agg(ctx, pre_sig, &session, partial_sig_ptr, 1));
SECP256K1_CHECKMEM_DEFINE(pre_sig, sizeof(pre_sig));
CHECK(secp256k1_frost_nonce_parity(ctx, &nonce_parity, &session));
ret = secp256k1_frost_adapt(ctx, sig, pre_sig, sec_adaptor, nonce_parity);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
/* extract_adaptor */
ret = secp256k1_frost_extract_adaptor(ctx, sec_adaptor, sig, pre_sig, nonce_parity);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
}
#endif
}

28
src/eccommit.h Normal file
View File

@@ -0,0 +1,28 @@
/**********************************************************************
* Copyright (c) 2020 The libsecp256k1-zkp Developers *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
#ifndef SECP256K1_ECCOMMIT_H
#define SECP256K1_ECCOMMIT_H
/** Helper function to add a 32-byte value to a scalar */
static int secp256k1_ec_seckey_tweak_add_helper(secp256k1_scalar *sec, const unsigned char *tweak);
/** Helper function to add a 32-byte value, times G, to an EC point */
static int secp256k1_ec_pubkey_tweak_add_helper(const secp256k1_ecmult_context* ecmult_ctx, secp256k1_ge *p, const unsigned char *tweak);
/** Serializes elem as a 33 byte array. This is non-constant time with respect to
* whether pubp is the point at infinity. Thus, you may need to declassify
* pubp->infinity before calling this function. */
static int secp256k1_ec_commit_pubkey_serialize_const(secp256k1_ge *pubp, unsigned char *buf33);
/** Compute an ec commitment tweak as hash(pubkey, data). */
static int secp256k1_ec_commit_tweak(unsigned char *tweak32, secp256k1_ge* pubp, secp256k1_sha256* sha, const unsigned char *data, size_t data_size);
/** Compute an ec commitment as pubkey + hash(pubkey, data)*G. */
static int secp256k1_ec_commit(const secp256k1_ecmult_context* ecmult_ctx, secp256k1_ge* commitp, const secp256k1_ge* pubp, secp256k1_sha256* sha, const unsigned char *data, size_t data_size);
/** Compute a secret key commitment as seckey + hash(pubkey, data). */
static int secp256k1_ec_commit_seckey(const secp256k1_ecmult_gen_context* ecmult_gen_ctx, secp256k1_scalar* seckey, secp256k1_ge* pubp, secp256k1_sha256* sha, const unsigned char *data, size_t data_size);
/** Verify an ec commitment as pubkey + hash(pubkey, data)*G ?= commitment. */
static int secp256k1_ec_commit_verify(const secp256k1_ecmult_context* ecmult_ctx, const secp256k1_ge* commitp, const secp256k1_ge* pubp, secp256k1_sha256* sha, const unsigned char *data, size_t data_size);
#endif /* SECP256K1_ECCOMMIT_H */

73
src/eccommit_impl.h Normal file
View File

@@ -0,0 +1,73 @@
/**********************************************************************
* Copyright (c) 2020 The libsecp256k1 Developers *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
#include <stddef.h>
#include "eckey.h"
#include "hash.h"
/* from secp256k1.c */
static int secp256k1_ec_seckey_tweak_add_helper(secp256k1_scalar *sec, const unsigned char *tweak);
static int secp256k1_ec_pubkey_tweak_add_helper(secp256k1_ge *pubp, const unsigned char *tweak);
static int secp256k1_ec_commit_pubkey_serialize_const(secp256k1_ge *pubp, unsigned char *buf33) {
if (secp256k1_ge_is_infinity(pubp)) {
return 0;
}
secp256k1_fe_normalize(&pubp->x);
secp256k1_fe_normalize(&pubp->y);
secp256k1_fe_get_b32(&buf33[1], &pubp->x);
buf33[0] = secp256k1_fe_is_odd(&pubp->y) ? SECP256K1_TAG_PUBKEY_ODD : SECP256K1_TAG_PUBKEY_EVEN;
return 1;
}
/* Compute an ec commitment tweak as hash(pubp, data). */
static int secp256k1_ec_commit_tweak(unsigned char *tweak32, secp256k1_ge* pubp, secp256k1_sha256* sha, const unsigned char *data, size_t data_size)
{
unsigned char rbuf[33];
if (!secp256k1_ec_commit_pubkey_serialize_const(pubp, rbuf)) {
return 0;
}
secp256k1_sha256_write(sha, rbuf, sizeof(rbuf));
secp256k1_sha256_write(sha, data, data_size);
secp256k1_sha256_finalize(sha, tweak32);
return 1;
}
/* Compute an ec commitment as pubp + hash(pubp, data)*G. */
static int secp256k1_ec_commit(secp256k1_ge* commitp, const secp256k1_ge* pubp, secp256k1_sha256* sha, const unsigned char *data, size_t data_size) {
unsigned char tweak[32];
*commitp = *pubp;
return secp256k1_ec_commit_tweak(tweak, commitp, sha, data, data_size)
&& secp256k1_ec_pubkey_tweak_add_helper(commitp, tweak);
}
/* Compute the seckey of an ec commitment from the original secret key of the pubkey as seckey +
* hash(pubp, data). */
static int secp256k1_ec_commit_seckey(secp256k1_scalar* seckey, secp256k1_ge* pubp, secp256k1_sha256* sha, const unsigned char *data, size_t data_size) {
unsigned char tweak[32];
return secp256k1_ec_commit_tweak(tweak, pubp, sha, data, data_size)
&& secp256k1_ec_seckey_tweak_add_helper(seckey, tweak);
}
/* Verify an ec commitment as pubp + hash(pubp, data)*G ?= commitment. */
static int secp256k1_ec_commit_verify(const secp256k1_ge* commitp, const secp256k1_ge* pubp, secp256k1_sha256* sha, const unsigned char *data, size_t data_size) {
secp256k1_gej pj;
secp256k1_ge p;
if (!secp256k1_ec_commit(&p, pubp, sha, data, data_size)) {
return 0;
}
/* Return p == commitp */
secp256k1_ge_neg(&p, &p);
secp256k1_gej_set_ge(&pj, &p);
secp256k1_gej_add_ge_var(&pj, &pj, commitp, NULL);
return secp256k1_gej_is_infinity(&pj);
}

View File

@@ -1,8 +1,8 @@
/**********************************************************************
* Copyright (c) 2013, 2014 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
/***********************************************************************
* Copyright (c) 2013, 2014 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#ifndef SECP256K1_ECDSA_H
#define SECP256K1_ECDSA_H
@@ -15,7 +15,7 @@
static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *r, secp256k1_scalar *s, const unsigned char *sig, size_t size);
static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar *r, const secp256k1_scalar *s);
static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar* r, const secp256k1_scalar* s, const secp256k1_ge *pubkey, const secp256k1_scalar *message);
static int secp256k1_ecdsa_sig_verify(const secp256k1_scalar* r, const secp256k1_scalar* s, const secp256k1_ge *pubkey, const secp256k1_scalar *message);
static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_scalar *seckey, const secp256k1_scalar *message, const secp256k1_scalar *nonce, int *recid);
#endif /* SECP256K1_ECDSA_H */

View File

@@ -1,8 +1,8 @@
/**********************************************************************
* Copyright (c) 2013-2015 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
/***********************************************************************
* Copyright (c) 2013-2015 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#ifndef SECP256K1_ECDSA_IMPL_H
@@ -16,17 +16,8 @@
#include "ecdsa.h"
/** Group order for secp256k1 defined as 'n' in "Standards for Efficient Cryptography" (SEC2) 2.7.1
* sage: for t in xrange(1023, -1, -1):
* .. p = 2**256 - 2**32 - t
* .. if p.is_prime():
* .. print '%x'%p
* .. break
* 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'
* sage: a = 0
* sage: b = 7
* sage: F = FiniteField (p)
* sage: '%x' % (EllipticCurve ([F (a), F (b)]).order())
* 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141'
* $ sage -c 'load("secp256k1_params.sage"); print(hex(N))'
* 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
*/
static const secp256k1_fe secp256k1_ecdsa_const_order_as_fe = SECP256K1_FE_CONST(
0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL,
@@ -35,12 +26,8 @@ static const secp256k1_fe secp256k1_ecdsa_const_order_as_fe = SECP256K1_FE_CONST
/** Difference between field and order, values 'p' and 'n' values defined in
* "Standards for Efficient Cryptography" (SEC2) 2.7.1.
* sage: p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
* sage: a = 0
* sage: b = 7
* sage: F = FiniteField (p)
* sage: '%x' % (p - EllipticCurve ([F (a), F (b)]).order())
* '14551231950b75fc4402da1722fc9baee'
* $ sage -c 'load("secp256k1_params.sage"); print(hex(P-N))'
* 0x14551231950b75fc4402da1722fc9baee
*/
static const secp256k1_fe secp256k1_ecdsa_const_p_minus_order = SECP256K1_FE_CONST(
0, 0, 0, 1, 0x45512319UL, 0x50B75FC4UL, 0x402DA172UL, 0x2FC9BAEEUL
@@ -79,8 +66,7 @@ static int secp256k1_der_read_len(size_t *len, const unsigned char **sigp, const
}
if (lenleft > sizeof(size_t)) {
/* The resulting length would exceed the range of a size_t, so
* certainly longer than the passed array size.
*/
* it is certainly longer than the passed array size. */
return 0;
}
while (lenleft > 0) {
@@ -89,7 +75,9 @@ static int secp256k1_der_read_len(size_t *len, const unsigned char **sigp, const
lenleft--;
}
if (*len > (size_t)(sigend - *sigp)) {
/* Result exceeds the length of the passed array. */
/* Result exceeds the length of the passed array.
(Checking this is the responsibility of the caller but it
can't hurt do it here, too.) */
return 0;
}
if (*len < 128) {
@@ -112,7 +100,7 @@ static int secp256k1_der_parse_integer(secp256k1_scalar *r, const unsigned char
if (secp256k1_der_read_len(&rlen, sig, sigend) == 0) {
return 0;
}
if (rlen == 0 || *sig + rlen > sigend) {
if (rlen == 0 || rlen > (size_t)(sigend - *sig)) {
/* Exceeds bounds or not at least length 1 (X.690-0207 8.3.1). */
return 0;
}
@@ -140,7 +128,7 @@ static int secp256k1_der_parse_integer(secp256k1_scalar *r, const unsigned char
overflow = 1;
}
if (!overflow) {
memcpy(ra + 32 - rlen, *sig, rlen);
if (rlen) memcpy(ra + 32 - rlen, *sig, rlen);
secp256k1_scalar_set_b32(r, ra, &overflow);
}
if (overflow) {
@@ -204,7 +192,7 @@ static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const
return 1;
}
static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar *sigr, const secp256k1_scalar *sigs, const secp256k1_ge *pubkey, const secp256k1_scalar *message) {
static int secp256k1_ecdsa_sig_verify(const secp256k1_scalar *sigr, const secp256k1_scalar *sigs, const secp256k1_ge *pubkey, const secp256k1_scalar *message) {
unsigned char c[32];
secp256k1_scalar sn, u1, u2;
#if !defined(EXHAUSTIVE_TEST_ORDER)
@@ -221,7 +209,7 @@ static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const
secp256k1_scalar_mul(&u1, &sn, message);
secp256k1_scalar_mul(&u2, &sn, sigr);
secp256k1_gej_set_ge(&pubkeyj, pubkey);
secp256k1_ecmult(ctx, &pr, &pubkeyj, &u2, &u1);
secp256k1_ecmult(&pr, &pubkeyj, &u2, &u1);
if (secp256k1_gej_is_infinity(&pr)) {
return 0;
}
@@ -239,7 +227,8 @@ static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const
}
#else
secp256k1_scalar_get_b32(c, sigr);
secp256k1_fe_set_b32(&xr, c);
/* we can ignore the fe_set_b32_limit return value, because we know the input is in range */
(void)secp256k1_fe_set_b32_limit(&xr, c);
/** We now have the recomputed R point in pr, and its claimed x coordinate (modulo n)
* in xr. Naively, we would extract the x coordinate from pr (requiring a inversion modulo p),
@@ -304,12 +293,12 @@ static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, sec
high = secp256k1_scalar_is_high(sigs);
secp256k1_scalar_cond_negate(sigs, high);
if (recid) {
*recid ^= high;
*recid ^= high;
}
/* P.x = order is on the curve, so technically sig->r could end up being zero, which would be an invalid signature.
* This is cryptographically unreachable as hitting it requires finding the discrete log of P.x = N.
*/
return !secp256k1_scalar_is_zero(sigr) & !secp256k1_scalar_is_zero(sigs);
return (int)(!secp256k1_scalar_is_zero(sigr)) & (int)(!secp256k1_scalar_is_zero(sigs));
}
#endif /* SECP256K1_ECDSA_IMPL_H */

View File

@@ -1,8 +1,8 @@
/**********************************************************************
* Copyright (c) 2013, 2014 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
/***********************************************************************
* Copyright (c) 2013, 2014 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#ifndef SECP256K1_ECKEY_H
#define SECP256K1_ECKEY_H
@@ -18,8 +18,8 @@ static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char
static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed);
static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak);
static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak);
static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge *key, const secp256k1_scalar *tweak);
static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak);
static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak);
static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge *key, const secp256k1_scalar *tweak);
#endif /* SECP256K1_ECKEY_H */

View File

@@ -1,8 +1,8 @@
/**********************************************************************
* Copyright (c) 2013, 2014 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
/***********************************************************************
* Copyright (c) 2013, 2014 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#ifndef SECP256K1_ECKEY_IMPL_H
#define SECP256K1_ECKEY_IMPL_H
@@ -17,10 +17,10 @@
static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size) {
if (size == 33 && (pub[0] == SECP256K1_TAG_PUBKEY_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_ODD)) {
secp256k1_fe x;
return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == SECP256K1_TAG_PUBKEY_ODD);
return secp256k1_fe_set_b32_limit(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == SECP256K1_TAG_PUBKEY_ODD);
} else if (size == 65 && (pub[0] == SECP256K1_TAG_PUBKEY_UNCOMPRESSED || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD)) {
secp256k1_fe x, y;
if (!secp256k1_fe_set_b32(&x, pub+1) || !secp256k1_fe_set_b32(&y, pub+33)) {
if (!secp256k1_fe_set_b32_limit(&x, pub+1) || !secp256k1_fe_set_b32_limit(&y, pub+33)) {
return 0;
}
secp256k1_ge_set_xy(elem, &x, &y);
@@ -57,12 +57,10 @@ static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp25
return !secp256k1_scalar_is_zero(key);
}
static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) {
static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge *key, const secp256k1_scalar *tweak) {
secp256k1_gej pt;
secp256k1_scalar one;
secp256k1_gej_set_ge(&pt, key);
secp256k1_scalar_set_int(&one, 1);
secp256k1_ecmult(ctx, &pt, &pt, &one, tweak);
secp256k1_ecmult(&pt, &pt, &secp256k1_scalar_one, tweak);
if (secp256k1_gej_is_infinity(&pt)) {
return 0;
@@ -79,16 +77,14 @@ static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp25
return ret;
}
static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) {
secp256k1_scalar zero;
static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge *key, const secp256k1_scalar *tweak) {
secp256k1_gej pt;
if (secp256k1_scalar_is_zero(tweak)) {
return 0;
}
secp256k1_scalar_set_int(&zero, 0);
secp256k1_gej_set_ge(&pt, key);
secp256k1_ecmult(ctx, &pt, &pt, tweak, &zero);
secp256k1_ecmult(&pt, &pt, tweak, &secp256k1_scalar_zero);
secp256k1_ge_set_gej(key, &pt);
return 1;
}

View File

@@ -1,32 +1,47 @@
/**********************************************************************
* Copyright (c) 2013, 2014, 2017 Pieter Wuille, Andrew Poelstra *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
/***********************************************************************
* Copyright (c) 2013, 2014, 2017 Pieter Wuille, Andrew Poelstra *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#ifndef SECP256K1_ECMULT_H
#define SECP256K1_ECMULT_H
#include "num.h"
#include "group.h"
#include "scalar.h"
#include "scratch.h"
typedef struct {
/* For accelerating the computation of a*P + b*G: */
secp256k1_ge_storage (*pre_g)[]; /* odd multiples of the generator */
secp256k1_ge_storage (*pre_g_128)[]; /* odd multiples of 2^128*generator */
} secp256k1_ecmult_context;
#ifndef ECMULT_WINDOW_SIZE
# define ECMULT_WINDOW_SIZE 15
# ifdef DEBUG_CONFIG
# pragma message DEBUG_CONFIG_MSG("ECMULT_WINDOW_SIZE undefined, assuming default value")
# endif
#endif
static const size_t SECP256K1_ECMULT_CONTEXT_PREALLOCATED_SIZE;
static void secp256k1_ecmult_context_init(secp256k1_ecmult_context *ctx);
static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, void **prealloc);
static void secp256k1_ecmult_context_finalize_memcpy(secp256k1_ecmult_context *dst, const secp256k1_ecmult_context *src);
static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context *ctx);
static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context *ctx);
#ifdef DEBUG_CONFIG
# pragma message DEBUG_CONFIG_DEF(ECMULT_WINDOW_SIZE)
#endif
/* No one will ever need more than a window size of 24. The code might
* be correct for larger values of ECMULT_WINDOW_SIZE but this is not
* tested.
*
* The following limitations are known, and there are probably more:
* If WINDOW_G > 27 and size_t has 32 bits, then the code is incorrect
* because the size of the memory object that we allocate (in bytes)
* will not fit in a size_t.
* If WINDOW_G > 31 and int has 32 bits, then the code is incorrect
* because certain expressions will overflow.
*/
#if ECMULT_WINDOW_SIZE < 2 || ECMULT_WINDOW_SIZE > 24
# error Set ECMULT_WINDOW_SIZE to an integer in range [2..24].
#endif
/** The number of entries a table with precomputed multiples needs to have. */
#define ECMULT_TABLE_SIZE(w) (1L << ((w)-2))
/** Double multiply: R = na*A + ng*G */
static void secp256k1_ecmult(const secp256k1_ecmult_context *ctx, secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng);
static void secp256k1_ecmult(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng);
typedef int (secp256k1_ecmult_multi_callback)(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *data);
@@ -41,6 +56,6 @@ typedef int (secp256k1_ecmult_multi_callback)(secp256k1_scalar *sc, secp256k1_ge
* 0 if there is not enough scratch space for a single point or
* callback returns 0
*/
static int secp256k1_ecmult_multi_var(const secp256k1_callback* error_callback, const secp256k1_ecmult_context *ctx, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n);
static int secp256k1_ecmult_multi_var(const secp256k1_callback* error_callback, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n);
#endif /* SECP256K1_ECMULT_H */

View File

@@ -0,0 +1,16 @@
/*****************************************************************************************************
* Copyright (c) 2013, 2014, 2017, 2021 Pieter Wuille, Andrew Poelstra, Jonas Nick, Russell O'Connor *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php. *
*****************************************************************************************************/
#ifndef SECP256K1_ECMULT_COMPUTE_TABLE_H
#define SECP256K1_ECMULT_COMPUTE_TABLE_H
/* Construct table of all odd multiples of gen in range 1..(2**(window_g-1)-1). */
static void secp256k1_ecmult_compute_table(secp256k1_ge_storage* table, int window_g, const secp256k1_gej* gen);
/* Like secp256k1_ecmult_compute_table, but one for both gen and gen*2^128. */
static void secp256k1_ecmult_compute_two_tables(secp256k1_ge_storage* table, secp256k1_ge_storage* table_128, int window_g, const secp256k1_ge* gen);
#endif /* SECP256K1_ECMULT_COMPUTE_TABLE_H */

View File

@@ -0,0 +1,49 @@
/*****************************************************************************************************
* Copyright (c) 2013, 2014, 2017, 2021 Pieter Wuille, Andrew Poelstra, Jonas Nick, Russell O'Connor *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php. *
*****************************************************************************************************/
#ifndef SECP256K1_ECMULT_COMPUTE_TABLE_IMPL_H
#define SECP256K1_ECMULT_COMPUTE_TABLE_IMPL_H
#include "ecmult_compute_table.h"
#include "group_impl.h"
#include "field_impl.h"
#include "ecmult.h"
#include "util.h"
static void secp256k1_ecmult_compute_table(secp256k1_ge_storage* table, int window_g, const secp256k1_gej* gen) {
secp256k1_gej gj;
secp256k1_ge ge, dgen;
int j;
gj = *gen;
secp256k1_ge_set_gej_var(&ge, &gj);
secp256k1_ge_to_storage(&table[0], &ge);
secp256k1_gej_double_var(&gj, gen, NULL);
secp256k1_ge_set_gej_var(&dgen, &gj);
for (j = 1; j < ECMULT_TABLE_SIZE(window_g); ++j) {
secp256k1_gej_set_ge(&gj, &ge);
secp256k1_gej_add_ge_var(&gj, &gj, &dgen, NULL);
secp256k1_ge_set_gej_var(&ge, &gj);
secp256k1_ge_to_storage(&table[j], &ge);
}
}
/* Like secp256k1_ecmult_compute_table, but one for both gen and gen*2^128. */
static void secp256k1_ecmult_compute_two_tables(secp256k1_ge_storage* table, secp256k1_ge_storage* table_128, int window_g, const secp256k1_ge* gen) {
secp256k1_gej gj;
int i;
secp256k1_gej_set_ge(&gj, gen);
secp256k1_ecmult_compute_table(table, window_g, &gj);
for (i = 0; i < 128; ++i) {
secp256k1_gej_double_var(&gj, &gj, NULL);
}
secp256k1_ecmult_compute_table(table_128, window_g, &gj);
}
#endif /* SECP256K1_ECMULT_COMPUTE_TABLE_IMPL_H */

View File

@@ -1,8 +1,8 @@
/**********************************************************************
* Copyright (c) 2015 Andrew Poelstra *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
/***********************************************************************
* Copyright (c) 2015 Andrew Poelstra *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#ifndef SECP256K1_ECMULT_CONST_H
#define SECP256K1_ECMULT_CONST_H
@@ -11,10 +11,28 @@
#include "group.h"
/**
* Multiply: R = q*A (in constant-time)
* Here `bits` should be set to the maximum bitlength of the _absolute value_ of `q`, plus
* one because we internally sometimes add 2 to the number during the WNAF conversion.
* Multiply: R = q*A (in constant-time for q)
*/
static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *q, int bits);
static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *q);
/**
* Same as secp256k1_ecmult_const, but takes in an x coordinate of the base point
* only, specified as fraction n/d (numerator/denominator). Only the x coordinate of the result is
* returned.
*
* If known_on_curve is 0, a verification is performed that n/d is a valid X
* coordinate, and 0 is returned if not. Otherwise, 1 is returned.
*
* d being NULL is interpreted as d=1. If non-NULL, d must not be zero. q must not be zero.
*
* Constant time in the value of q, but not any other inputs.
*/
static int secp256k1_ecmult_const_xonly(
secp256k1_fe *r,
const secp256k1_fe *n,
const secp256k1_fe *d,
const secp256k1_scalar *q,
int known_on_curve
);
#endif /* SECP256K1_ECMULT_CONST_H */

Some files were not shown because too many files have changed in this diff Show More