Some checks failed
CI / Build arm64 Docker image (push) Has been cancelled
CI / Build x64 Docker image (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[ASM:x86_64 ELLSWIFT:yes WIDEMUL:int128]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[BENCH:no BUILD:distcheck CTIMETESTS:no WITH_VALGRIND:no]]) (push) Has been cancelled
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 EXTRAKEYS:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRS… (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes EXTRAKEYS:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SURJECTIONPROOF:y… (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes EXTRAKEYS:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SURJECTIONPROOF:yes WHITELIST:… (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[BPPP:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes EXTRAKEYS:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SURJECTIONPROOF:yes WHITEL… (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[CFLAGS:-O0 CTIMETESTS:no]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[CFLAGS:-O1 ECDH:yes ELLSWIFT:yes EXTRAKEYS:yes MUSIG:yes RECOVERY:yes SCHNORRSIG:yes]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[CPPFLAGS:-DDETERMINISTIC]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[ECMULTGENKB:2 ECMULTWINDOW:2]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[ECMULTGENKB:86 ECMULTWINDOW:4]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[ELLSWIFT:yes EXTRAKEYS:yes MUSIG:yes RECOVERY:yes SCHNORRSIG:yes WIDEMUL:int128]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[ELLSWIFT:yes WIDEMUL:int128_struct]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[RECOVERY:yes WIDEMUL:int64]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang, map[env_vars:map[WIDEMUL:int128]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[ASM:x86_64 ELLSWIFT:yes WIDEMUL:int128]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[BENCH:no BUILD:distcheck CTIMETESTS:no WITH_VALGRIND:no]]) (push) Has been cancelled
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 EXTRAKEYS:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes… (push) Has been cancelled
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 EXTRAKEYS:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SURJECTI… (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes EXTRAKEYS:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SURJECTIONPROOF:yes W… (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[BPPP:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes EXTRAKEYS:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SURJECTIONPROOF:y… (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[CFLAGS:-O0 CTIMETESTS:no]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[CFLAGS:-O1 ECDH:yes ELLSWIFT:yes EXTRAKEYS:yes MUSIG:yes RECOVERY:yes SCHNORRSIG:yes]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[CPPFLAGS:-DDETERMINISTIC]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[ECMULTGENKB:2 ECMULTWINDOW:2]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[ECMULTGENKB:86 ECMULTWINDOW:4]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[ELLSWIFT:yes EXTRAKEYS:yes MUSIG:yes RECOVERY:yes SCHNORRSIG:yes WIDEMUL:int128]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[ELLSWIFT:yes WIDEMUL:int128_struct]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[RECOVERY:yes WIDEMUL:int64]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[WIDEMUL:int128]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[ASM:x86_64 ELLSWIFT:yes WIDEMUL:int128]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[BENCH:no BUILD:distcheck CTIMETESTS:no WITH_VALGRIND:no]]) (push) Has been cancelled
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 EXTRAKEYS:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG… (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes EXTRAKEYS:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SURJECTIONPROOF:yes… (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes EXTRAKEYS:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SURJECTIONPROOF:yes WHITELIST:ye… (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[BPPP:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes EXTRAKEYS:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SURJECTIONPROOF:yes WHITELIS… (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[CFLAGS:-O0 CTIMETESTS:no]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[CFLAGS:-O1 ECDH:yes ELLSWIFT:yes EXTRAKEYS:yes MUSIG:yes RECOVERY:yes SCHNORRSIG:yes]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[CPPFLAGS:-DDETERMINISTIC]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[ECMULTGENKB:2 ECMULTWINDOW:2]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[ECMULTGENKB:86 ECMULTWINDOW:4]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[ELLSWIFT:yes EXTRAKEYS:yes MUSIG:yes RECOVERY:yes SCHNORRSIG:yes WIDEMUL:int128]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[ELLSWIFT:yes WIDEMUL:int128_struct]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[RECOVERY:yes WIDEMUL:int64]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc, map[env_vars:map[WIDEMUL:int128]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[ASM:x86_64 ELLSWIFT:yes WIDEMUL:int128]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[BENCH:no BUILD:distcheck CTIMETESTS:no WITH_VALGRIND:no]]) (push) Has been cancelled
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 EXTRAKEYS:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes S… (push) Has been cancelled
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 EXTRAKEYS:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SURJECTION… (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes EXTRAKEYS:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SURJECTIONPROOF:yes WHI… (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[BPPP:yes ECDSAADAPTOR:yes ECDSA_S2C:yes EXPERIMENTAL:yes EXTRAKEYS:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SURJECTIONPROOF:yes… (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[CFLAGS:-O0 CTIMETESTS:no]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[CFLAGS:-O1 ECDH:yes ELLSWIFT:yes EXTRAKEYS:yes MUSIG:yes RECOVERY:yes SCHNORRSIG:yes]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[CPPFLAGS:-DDETERMINISTIC]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[ECMULTGENKB:2 ECMULTWINDOW:2]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[ECMULTGENKB:86 ECMULTWINDOW:4]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[ELLSWIFT:yes EXTRAKEYS:yes MUSIG:yes RECOVERY:yes SCHNORRSIG:yes WIDEMUL:int128]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[ELLSWIFT:yes WIDEMUL:int128_struct]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[RECOVERY:yes WIDEMUL:int64]]) (push) Has been cancelled
CI / x86_64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[WIDEMUL:int128]]) (push) Has been cancelled
CI / i686: Linux (Debian stable) (clang --target=i686-pc-linux-gnu -isystem /usr/i686-linux-gnu/include, map[env_vars:map[]]) (push) Has been cancelled
CI / i686: Linux (Debian stable) (i686-linux-gnu-gcc, map[env_vars:map[]]) (push) Has been cancelled
CI / s390x (big-endian): Linux (Debian stable, QEMU) (map[env_vars:map[]]) (push) Has been cancelled
CI / ARM32: Linux (Debian stable, QEMU) (map[env_vars:map[ASM:arm32 EXPERIMENTAL:yes]]) (push) Has been cancelled
CI / ARM32: Linux (Debian stable, QEMU) (map[env_vars:map[]]) (push) Has been cancelled
CI / arm64: Linux (Debian stable) (clang, map[env_vars:map[]]) (push) Has been cancelled
CI / arm64: Linux (Debian stable) (clang-snapshot, map[env_vars:map[]]) (push) Has been cancelled
CI / arm64: Linux (Debian stable) (gcc, map[env_vars:map[]]) (push) Has been cancelled
CI / arm64: Linux (Debian stable) (gcc-snapshot, map[env_vars:map[]]) (push) Has been cancelled
CI / ppc64le: Linux (Debian stable, QEMU) (map[env_vars:map[]]) (push) Has been cancelled
CI / Valgrind arm64 (memcheck) (push) Has been cancelled
CI / Valgrind i686 (memcheck) (push) Has been cancelled
CI / Valgrind x64 (memcheck) (push) Has been cancelled
CI / UBSan, ASan, LSan (map[env_vars:map[ASM:auto CC:clang]]) (push) Has been cancelled
CI / UBSan, ASan, LSan (map[env_vars:map[ASM:auto CC:i686-linux-gnu-gcc HOST:i686-linux-gnu]]) (push) Has been cancelled
CI / UBSan, ASan, LSan (map[env_vars:map[ASM:no CC:clang ECMULTGENKB:2 ECMULTWINDOW:2]]) (push) Has been cancelled
CI / UBSan, ASan, LSan (map[env_vars:map[ASM:no CC:i686-linux-gnu-gcc ECMULTGENKB:2 ECMULTWINDOW:2 HOST:i686-linux-gnu]]) (push) Has been cancelled
CI / MSan (clang, map[env_vars:map[CFLAGS:-fsanitize=memory -fsanitize-recover=memory -fsanitize-memory-param-retval -g CTIMETESTS:no]]) (push) Has been cancelled
CI / MSan (clang, map[env_vars:map[CFLAGS:-fsanitize=memory -fsanitize-recover=memory -g -O3 CTIMETESTS:yes ECMULTGENKB:2 ECMULTWINDOW:2]]) (push) Has been cancelled
CI / MSan (clang, map[env_vars:map[CFLAGS:-fsanitize=memory -fsanitize-recover=memory -g CTIMETESTS:yes]]) (push) Has been cancelled
CI / MSan (clang-snapshot, map[env_vars:map[CFLAGS:-fsanitize=memory -fsanitize-recover=memory -fsanitize-memory-param-retval -g CTIMETESTS:no]]) (push) Has been cancelled
CI / MSan (clang-snapshot, map[env_vars:map[CFLAGS:-fsanitize=memory -fsanitize-recover=memory -g -O3 CTIMETESTS:yes ECMULTGENKB:2 ECMULTWINDOW:2]]) (push) Has been cancelled
CI / MSan (clang-snapshot, map[env_vars:map[CFLAGS:-fsanitize=memory -fsanitize-recover=memory -g CTIMETESTS:yes]]) (push) Has been cancelled
CI / i686 (mingw32-w64): Windows (Debian stable, Wine) (push) Has been cancelled
CI / x86_64 (mingw32-w64): Windows (Debian stable, Wine) (push) Has been cancelled
CI / x86_64: macOS Sequoia, Valgrind (map[BPPP:yes CC:gcc ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes EXTRAKEYS:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SECP256K1_TEST_… (push) Has been cancelled
CI / x86_64: macOS Sequoia, Valgrind (map[BPPP:yes CC:gcc ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes EXTRAKEYS:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SURJECTIONPROOF… (push) Has been cancelled
CI / x86_64: macOS Sequoia, Valgrind (map[BPPP:yes CPPFLAGS:-DVERIFY CTIMETESTS:no ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes EXTRAKEYS:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HA… (push) Has been cancelled
CI / x86_64: macOS Sequoia, Valgrind (map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes EXTRAKEYS:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SECP256K1_TEST_ITERS:2… (push) Has been cancelled
CI / x86_64: macOS Sequoia, Valgrind (map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes EXTRAKEYS:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SURJECTIONPROOF:yes WH… (push) Has been cancelled
CI / x86_64: macOS Sequoia, Valgrind (map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes EXTRAKEYS:yes FROST:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SURJECTIONPROOF:yes WHITELIST:yes W… (push) Has been cancelled
CI / x86_64: macOS Sequoia, Valgrind (map[BUILD:distcheck]) (push) Has been cancelled
CI / x86_64: macOS Sequoia, Valgrind (map[ECMULTGENKB:2 ECMULTWINDOW:4 WIDEMUL:int128_struct]) (push) Has been cancelled
CI / x86_64: macOS Sequoia, Valgrind (map[RECOVERY:yes WIDEMUL:int128]) (push) Has been cancelled
CI / ARM64: macOS Sonoma (map[BPPP:yes CC:gcc ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes EXTRAKEYS:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SURJECTIONPROOF:yes WHITELIST:yes WID… (push) Has been cancelled
CI / ARM64: macOS Sonoma (map[BPPP:yes CPPFLAGS:-DVERIFY ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes EXTRAKEYS:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SURJECTIONPROOF:yes WHITEL… (push) Has been cancelled
CI / ARM64: macOS Sonoma (map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes EXTRAKEYS:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes RECOVERY:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SURJECTIONPROOF:yes WHITELIST:yes WIDEMUL:in… (push) Has been cancelled
CI / ARM64: macOS Sonoma (map[BPPP:yes ECDH:yes ECDSAADAPTOR:yes ECDSA_S2C:yes ELLSWIFT:yes EXPERIMENTAL:yes EXTRAKEYS:yes GENERATOR:yes MUSIG:yes RANGEPROOF:yes SCHNORRSIG:yes SCHNORRSIG_HALFAGG:yes SURJECTIONPROOF:yes WHITELIST:yes WIDEMUL:int128]) (push) Has been cancelled
CI / ARM64: macOS Sonoma (map[BUILD:distcheck]) (push) Has been cancelled
CI / ARM64: macOS Sonoma (map[ECMULTGENKB:2 ECMULTWINDOW:4 WIDEMUL:int128_struct]) (push) Has been cancelled
CI / ARM64: macOS Sonoma (map[RECOVERY:yes WIDEMUL:int128]) (push) Has been cancelled
CI / x86 (MSVC): Windows (VS 2022) (push) Has been cancelled
CI / x64 (MSVC): Windows (VS 2022, static) (push) Has been cancelled
CI / x64 (MSVC): Windows (VS 2022, shared) (push) Has been cancelled
CI / x64 (MSVC): Windows (VS 2022, int128_struct with __(u)mulh) (push) Has been cancelled
CI / x64 (MSVC): Windows (VS 2022, int128_struct) (push) Has been cancelled
CI / x64 (clang-cl): Windows (VS 2022, static) (push) Has been cancelled
CI / x64 (clang-cl): Windows (VS 2022, shared) (push) Has been cancelled
CI / x64 (clang-cl): Windows (VS 2022, int128_struct with __(u)mulh) (push) Has been cancelled
CI / x64 (clang-cl): Windows (VS 2022, int128_struct) (push) Has been cancelled
CI / x64 (MSVC): C++ (public headers) (push) Has been cancelled
CI / C++ -fpermissive (entire project) (map[env_vars:map[]]) (push) Has been cancelled
CI / C++ (public headers) (push) Has been cancelled
CI / SageMath prover (push) Has been cancelled
CI / release (push) Has been cancelled
698 lines
24 KiB
Python
698 lines
24 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import sys
|
|
import json
|
|
import re
|
|
import textwrap
|
|
|
|
if len(sys.argv) < 2:
|
|
print(
|
|
"This script converts the BIP 445 FROST signing 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)
|
|
|
|
# The curve order; partial signatures >= ORDER fail frost_partial_sig_parse.
|
|
ORDER = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
|
|
|
|
skipped_cases = []
|
|
|
|
|
|
def hexstr_to_intarray(str):
|
|
return ", ".join([f"0x{b:02X}" for b in bytes.fromhex(str)])
|
|
|
|
|
|
def indent(s, level=1):
|
|
return textwrap.indent(s, 4 * level * " ")
|
|
|
|
|
|
def byte_array(hex_str):
|
|
return "{ %s }" % hexstr_to_intarray(hex_str)
|
|
|
|
|
|
def init_byte_array_maybe(hex_str):
|
|
"""Emits 'has_flag, { bytes }' for a possibly-None byte string."""
|
|
return "%d, %s" % (
|
|
0 if hex_str is None else 1,
|
|
byte_array(hex_str) if hex_str is not None else "{ 0 }",
|
|
)
|
|
|
|
|
|
def init_var_bytes(hex_str, max_len):
|
|
"""Emits 'has_flag, len, { bytes }' for a possibly-None variable-length byte string."""
|
|
has = 0 if hex_str is None else 1
|
|
b = bytes.fromhex(hex_str) if hex_str is not None else b""
|
|
return "%d, %d, { %s }" % (has, len(b), hexstr_to_intarray(hex_str or ""))
|
|
|
|
|
|
def init_indices(array):
|
|
return "%d, { %s }" % (len(array), ", ".join(map(str, array)) if array else "0")
|
|
|
|
|
|
def init_indices_maybe(array):
|
|
"""Emits 'has_flag, { indices }' for a possibly-None index list."""
|
|
return "%d, { %s }" % (
|
|
0 if array is None else 1,
|
|
", ".join(map(str, array)) if array else "0",
|
|
)
|
|
|
|
|
|
def init_is_xonly(case, max_tweaks):
|
|
is_xonly = case.get("is_xonly", [])
|
|
if len(is_xonly) > 0:
|
|
return ", ".join("1" if x else "0" for x in is_xonly)
|
|
return "0"
|
|
|
|
|
|
def parse_sign_error(case):
|
|
"""Maps the reference error of a sign/tweak error case to a frost_vec_error
|
|
code (and a blame index into the case's index lists where applicable)."""
|
|
err = case["error"]
|
|
if err["type"] == "InvalidContributionError":
|
|
assert err["contrib"] == "aggnonce"
|
|
return "FROST_VEC_ERR_AGGNONCE_PARSE", -1
|
|
msg = err["message"]
|
|
if msg == "The signer's id is missing from the ids list.":
|
|
return "FROST_VEC_ERR_SIGN", -1
|
|
if msg == "The ids list contains duplicate elements.":
|
|
return "FROST_VEC_ERR_SESSION_INIT", -1
|
|
if msg == "The signer's pubshare is missing from the pubshares list.":
|
|
return "FROST_VEC_ERR_SIGN", -1
|
|
if msg.startswith("Invalid pubshare at index"):
|
|
return "FROST_VEC_ERR_PUBSHARE_PARSE", int(re.search(r"index (\d+)", msg).group(1))
|
|
if msg == "The threshold public key must not be the point at infinity.":
|
|
return "FROST_VEC_ERR_SESSION_INIT", -1
|
|
if msg.startswith("Invalid id at index"):
|
|
return "FROST_VEC_ERR_SESSION_INIT", -1
|
|
if msg == "The provided key material is incorrect: the public shares do not match the threshold public key.":
|
|
return "FROST_VEC_ERR_SESSION_INIT", -1
|
|
if msg in ("first secnonce value is out of range.", "second secnonce value is out of range."):
|
|
return "FROST_VEC_ERR_SECNONCE", -1
|
|
if msg == "The number of signers must be between t and n.":
|
|
return "FROST_VEC_ERR_SESSION_INIT", -1
|
|
if msg == "The signer's secret share value is out of range.":
|
|
return "FROST_VEC_ERR_SIGN", -1
|
|
if msg == "The tweak value is out of range.":
|
|
return "FROST_VEC_ERR_TWEAK_ADD", -1
|
|
if msg == "The result of tweaking cannot be infinity.":
|
|
return "FROST_VEC_ERR_TWEAK_ADD", -1
|
|
sys.exit("Unknown sign error: %s" % msg)
|
|
|
|
|
|
def parse_det_error(case):
|
|
"""Maps the reference error of a deterministic_sign error case to a
|
|
frost_vec_error code."""
|
|
err = case["error"]
|
|
if err["type"] == "InvalidContributionError":
|
|
assert err["contrib"] == "aggothernonce"
|
|
return "FROST_VEC_ERR_AGGOTHERNONCE", -1
|
|
msg = err["message"]
|
|
if msg == "The tweak value is out of range.":
|
|
return "FROST_VEC_ERR_TWEAK_ADD", -1
|
|
if msg.startswith("Invalid pubshare at index"):
|
|
return "FROST_VEC_ERR_PUBSHARE_PARSE", int(re.search(r"index (\d+)", msg).group(1))
|
|
if msg in (
|
|
"The signer's id is missing from the ids list.",
|
|
"The ids list contains duplicate elements.",
|
|
"The signer's pubshare is missing from the pubshares list.",
|
|
"The provided key material is incorrect: the public shares do not match the threshold public key.",
|
|
"The number of signers must be between t and n.",
|
|
"The signer's secret share value is out of range.",
|
|
) or msg.startswith("Invalid id at index"):
|
|
return "FROST_VEC_ERR_DET_SIGN", -1
|
|
sys.exit("Unknown det_sign error: %s" % msg)
|
|
|
|
|
|
def parse_verify_error(case):
|
|
err = case["error"]
|
|
if err["type"] == "InvalidContributionError":
|
|
assert err["contrib"] == "pubnonce"
|
|
return "FROST_VEC_ERR_PUBNONCE_PARSE", err["signer_index"]
|
|
msg = err["message"]
|
|
if msg.startswith("Invalid pubshare at index"):
|
|
return "FROST_VEC_ERR_PUBSHARE_PARSE", int(re.search(r"index (\d+)", msg).group(1))
|
|
sys.exit("Unknown verify error: %s" % err)
|
|
|
|
|
|
s = (
|
|
"""/**
|
|
* Automatically generated by %s.
|
|
*
|
|
* The test vectors are from the BIP 445 reference repository
|
|
* https://github.com/siv2r/bip-frost-signing, pinned at commit
|
|
* bb5396f90d45ba5a954cbfd1af80f1b45e02b229 (BIP v0.10.0). They are used by the
|
|
* tests in src/modules/frost/tests_impl.h. */
|
|
"""
|
|
% sys.argv[0]
|
|
)
|
|
|
|
s += """
|
|
enum frost_vec_error {
|
|
/* Valid case. */
|
|
FROST_VEC_ERR_NONE,
|
|
/* frost_session_init returns 0 (invalid session parameters). */
|
|
FROST_VEC_ERR_SESSION_INIT,
|
|
/* frost_sign returns 0. */
|
|
FROST_VEC_ERR_SIGN,
|
|
/* frost_sign triggers the illegal-argument callback when loading the
|
|
* injected (corrupt) secnonce. */
|
|
FROST_VEC_ERR_SECNONCE,
|
|
/* frost_aggnonce_parse returns 0. */
|
|
FROST_VEC_ERR_AGGNONCE_PARSE,
|
|
/* frost_pubnonce_parse of the blamed pubnonce returns 0. */
|
|
FROST_VEC_ERR_PUBNONCE_PARSE,
|
|
/* secp256k1_ec_pubkey_parse of the blamed pubshare returns 0. */
|
|
FROST_VEC_ERR_PUBSHARE_PARSE,
|
|
/* frost_partial_sig_parse of the blamed partial signature returns 0. */
|
|
FROST_VEC_ERR_PSIG_PARSE,
|
|
/* Applying the tweak chain to the tweak cache fails. */
|
|
FROST_VEC_ERR_TWEAK_ADD,
|
|
/* frost_partial_sig_agg returns 0 (wrong number of partial signatures). */
|
|
FROST_VEC_ERR_AGG_LEN,
|
|
/* frost_deterministic_sign returns 0. */
|
|
FROST_VEC_ERR_DET_SIGN,
|
|
/* The aggothernonce is rejected: frost_aggnonce_parse or
|
|
* frost_deterministic_sign returns 0. */
|
|
FROST_VEC_ERR_AGGOTHERNONCE,
|
|
};
|
|
"""
|
|
|
|
# Load all vector files first (to compute the shared maximum sizes).
|
|
nonce_gen_data = json.load(open(sys.argv[1] + "/nonce_gen_vectors.json"))
|
|
nonce_agg_data = json.load(open(sys.argv[1] + "/nonce_agg_vectors.json"))
|
|
sign_verify_data = json.load(open(sys.argv[1] + "/sign_verify_vectors.json"))
|
|
tweak_data = json.load(open(sys.argv[1] + "/tweak_vectors.json"))
|
|
sig_agg_data = json.load(open(sys.argv[1] + "/sig_agg_vectors.json"))
|
|
det_sign_data = json.load(open(sys.argv[1] + "/det_sign_vectors.json"))
|
|
|
|
# Skip tweak error cases that the C API cannot express: the C API applies
|
|
# tweaks individually via frost_pubkey_{xonly,ec}_tweak_add, so a mismatch
|
|
# between the number of tweaks and tweak modes cannot occur, and tweaks always
|
|
# have a fixed length of 32 bytes.
|
|
tweak_error_tests = []
|
|
for group in tweak_data["test_groups"]:
|
|
for case in group["error_tests"]:
|
|
if case["error"]["message"] in (
|
|
"The tweaks and is_xonly arrays must have the same length.",
|
|
"The tweak must be a 32-byte array.",
|
|
):
|
|
skipped_cases.append(
|
|
"tweak_vectors error tc_id %d (%s): not expressible in the C API (tweaks are applied individually and have a fixed length of 32 bytes)"
|
|
% (case["tc_id"], case["error"]["message"])
|
|
)
|
|
continue
|
|
tweak_error_tests.append((tweak_data["test_groups"].index(group), case))
|
|
|
|
all_groups = (
|
|
sign_verify_data["test_groups"]
|
|
+ tweak_data["test_groups"]
|
|
+ sig_agg_data["test_groups"]
|
|
+ det_sign_data["test_groups"]
|
|
)
|
|
max_pubshares = max(len(g["pubshares"]) for g in all_groups)
|
|
max_secshares = max(len(g.get("secshares", [])) for g in all_groups)
|
|
max_pubnonces = max(len(g.get("pubnonces", [])) for g in all_groups)
|
|
max_secnonces = max(len(g.get("secnonces", [])) for g in all_groups)
|
|
max_tweaks = max(len(g.get("tweaks", [])) for g in all_groups)
|
|
# A group's tweak pool may contain a tweak that is not 32 bytes long (only
|
|
# referenced by error cases that the C API cannot express).
|
|
max_tweak_len = max(
|
|
len(bytes.fromhex(t)) for g in all_groups for t in g.get("tweaks", [])
|
|
)
|
|
|
|
sign_cases = [
|
|
c
|
|
for g in sign_verify_data["test_groups"]
|
|
for c in g["valid_tests"] + g["sign_error_tests"]
|
|
] + [c for g in tweak_data["test_groups"] for c in g["valid_tests"]] + [
|
|
c for _, c in tweak_error_tests
|
|
]
|
|
det_cases = [
|
|
c
|
|
for g in det_sign_data["test_groups"]
|
|
for c in g["valid_tests"] + g["error_tests"]
|
|
]
|
|
verify_cases = [
|
|
c
|
|
for g in sign_verify_data["test_groups"]
|
|
for c in g["verify_fail_tests"] + g["verify_error_tests"]
|
|
]
|
|
sig_agg_cases = [
|
|
c for g in sig_agg_data["test_groups"] for c in g["valid_tests"] + g["error_tests"]
|
|
]
|
|
|
|
max_ids = max(len(c["ids"]) for c in sign_cases + det_cases + verify_cases + sig_agg_cases)
|
|
max_msg = max(
|
|
len(bytes.fromhex(c["msg"]))
|
|
for c in sign_cases + det_cases + verify_cases + sig_agg_cases
|
|
)
|
|
max_case_tweaks = max(
|
|
[len(c.get("tweak_indices", [])) for c in sign_cases + sig_agg_cases]
|
|
+ [len(c["tweaks"]) for c in det_cases]
|
|
)
|
|
max_extra_in = max(
|
|
len(bytes.fromhex(c["extra_in"] or "")) for c in nonce_gen_data["valid_tests"]
|
|
)
|
|
max_ng_msg = max(
|
|
len(bytes.fromhex(c["msg"] or "")) for c in nonce_gen_data["valid_tests"]
|
|
)
|
|
max_psigs = max(len(c["psigs"]) for c in sig_agg_cases)
|
|
max_na_indices = max(
|
|
len(c["pubnonce_indices"])
|
|
for c in nonce_agg_data["valid_tests"] + nonce_agg_data["error_tests"]
|
|
)
|
|
|
|
s += """
|
|
enum {
|
|
FROST_VEC_MAX_PUBSHARES = %d,
|
|
FROST_VEC_MAX_SECSHARES = %d,
|
|
FROST_VEC_MAX_PUBNONCES = %d,
|
|
FROST_VEC_MAX_SECNONCES = %d,
|
|
FROST_VEC_MAX_GROUP_TWEAKS = %d,
|
|
FROST_VEC_MAX_TWEAK_LEN = %d,
|
|
FROST_VEC_MAX_SIGNERS = %d,
|
|
FROST_VEC_MAX_TWEAKS = %d,
|
|
FROST_VEC_MAX_MSGLEN = %d,
|
|
FROST_VEC_MAX_PSIGS = %d
|
|
};
|
|
""" % (
|
|
max_pubshares,
|
|
max_secshares,
|
|
max_pubnonces,
|
|
max_secnonces,
|
|
max_tweaks,
|
|
max_tweak_len,
|
|
max_ids,
|
|
max_case_tweaks,
|
|
max(max_msg, max_ng_msg, 1),
|
|
max(max_psigs, 1),
|
|
)
|
|
|
|
s += """
|
|
/* A test group's shared key material. Entry i of each array belongs to the
|
|
* participant with id i; entries at indices >= n are deliberately bad values
|
|
* that only error cases select. */
|
|
struct frost_vec_group {
|
|
uint32_t threshold;
|
|
uint32_t n_participants;
|
|
unsigned char thresh_pk[33];
|
|
size_t n_pubshares;
|
|
unsigned char pubshares[FROST_VEC_MAX_PUBSHARES][33];
|
|
size_t n_secshares;
|
|
unsigned char secshares[FROST_VEC_MAX_SECSHARES][32];
|
|
size_t n_pubnonces;
|
|
unsigned char pubnonces[FROST_VEC_MAX_PUBNONCES][66];
|
|
size_t n_secnonces;
|
|
unsigned char secnonces[FROST_VEC_MAX_SECNONCES][64];
|
|
size_t n_tweaks;
|
|
unsigned char tweaks[FROST_VEC_MAX_GROUP_TWEAKS][FROST_VEC_MAX_TWEAK_LEN];
|
|
};
|
|
"""
|
|
|
|
|
|
def init_group(group):
|
|
def counted(key):
|
|
values = group.get(key, [])
|
|
inner = ""
|
|
if values:
|
|
inner = "\n" + indent(",\n".join(byte_array(x) for x in values), 1) + "\n"
|
|
return "%d, {%s}" % (len(values), inner)
|
|
|
|
return "{ %d, %d, %s, %s, %s, %s, %s, %s }," % (
|
|
group["t"],
|
|
group["n"],
|
|
byte_array(group["thresh_pk"]),
|
|
counted("pubshares"),
|
|
counted("secshares"),
|
|
counted("pubnonces"),
|
|
counted("secnonces"),
|
|
counted("tweaks"),
|
|
)
|
|
|
|
|
|
def init_groups(name, data):
|
|
out = "static const struct frost_vec_group frost_vec_%s_groups[%d] = {\n" % (
|
|
name,
|
|
len(data["test_groups"]),
|
|
)
|
|
for group in data["test_groups"]:
|
|
out += indent(init_group(group) + "\n")
|
|
out += "};\n"
|
|
return out
|
|
|
|
|
|
# nonce_gen vectors
|
|
num_cases = len(nonce_gen_data["valid_tests"])
|
|
s += """
|
|
struct frost_vec_nonce_gen_case {
|
|
unsigned char rand[32];
|
|
int has_secshare;
|
|
unsigned char secshare[32];
|
|
int has_pubshare;
|
|
unsigned char pubshare[33];
|
|
int has_thresh_pk;
|
|
unsigned char thresh_pk_xonly[32];
|
|
int has_msg;
|
|
size_t msg_len;
|
|
unsigned char msg[FROST_VEC_MAX_MSGLEN];
|
|
int has_extra_in;
|
|
size_t extra_in_len;
|
|
unsigned char extra_in[%d];
|
|
unsigned char expected_secnonce[64];
|
|
unsigned char expected_pubnonce[66];
|
|
};
|
|
""" % max(
|
|
max_extra_in, 1
|
|
)
|
|
|
|
s += "static const struct frost_vec_nonce_gen_case frost_vec_nonce_gen_cases[%d] = {\n" % num_cases
|
|
for case in nonce_gen_data["valid_tests"]:
|
|
s += indent(
|
|
"{ %s, %s, %s, %s, %s, %s, %s },\n"
|
|
% (
|
|
byte_array(case["rand"]),
|
|
init_byte_array_maybe(case["secshare"]),
|
|
init_byte_array_maybe(case["pubshare"]),
|
|
init_byte_array_maybe(case["thresh_pk_xonly"]),
|
|
init_var_bytes(case["msg"], max_ng_msg),
|
|
init_var_bytes(case["extra_in"], max_extra_in),
|
|
byte_array(case["expected"][0]) + ", " + byte_array(case["expected"][1]),
|
|
)
|
|
)
|
|
s += "};\n"
|
|
|
|
# nonce_agg vectors
|
|
num_pubnonces = len(nonce_agg_data["pubnonces"])
|
|
s += """
|
|
struct frost_vec_nonce_agg_case {
|
|
size_t n_pubnonces;
|
|
size_t pubnonce_indices[%d];
|
|
/* -1 for valid cases; otherwise the position (in pubnonce_indices) of the
|
|
* pubnonce that must fail frost_pubnonce_parse. */
|
|
int error_index;
|
|
unsigned char expected[66];
|
|
};
|
|
""" % max_na_indices
|
|
|
|
s += "static const unsigned char frost_vec_nonce_agg_pubnonces[%d][66] = {\n" % num_pubnonces
|
|
s += indent(",\n".join(byte_array(x) for x in nonce_agg_data["pubnonces"])) + "\n"
|
|
s += "};\n"
|
|
|
|
for name, cases in (("valid", nonce_agg_data["valid_tests"]), ("error", nonce_agg_data["error_tests"])):
|
|
s += "static const struct frost_vec_nonce_agg_case frost_vec_nonce_agg_%s_cases[%d] = {\n" % (name, len(cases))
|
|
for case in cases:
|
|
s += indent(
|
|
"{ %d, { %s }, %d, %s },\n"
|
|
% (
|
|
len(case["pubnonce_indices"]),
|
|
", ".join(map(str, case["pubnonce_indices"])),
|
|
case["error"]["signer_index"] if "error" in case else -1,
|
|
byte_array(case["expected"]) if "expected" in case else "{ 0 }",
|
|
)
|
|
)
|
|
s += "};\n"
|
|
|
|
# Shared sign case struct (used by sign_verify and tweak vectors)
|
|
s += """
|
|
struct frost_vec_sign_case {
|
|
size_t group;
|
|
uint32_t my_id;
|
|
size_t n_ids;
|
|
uint32_t ids[FROST_VEC_MAX_SIGNERS];
|
|
int has_pubshares;
|
|
size_t pubshare_indices[FROST_VEC_MAX_SIGNERS];
|
|
size_t secshare_index;
|
|
size_t secnonce_index;
|
|
unsigned char aggnonce[66];
|
|
size_t msg_len;
|
|
unsigned char msg[FROST_VEC_MAX_MSGLEN];
|
|
size_t n_tweaks;
|
|
size_t tweak_indices[FROST_VEC_MAX_TWEAKS];
|
|
int is_xonly[FROST_VEC_MAX_TWEAKS];
|
|
/* FROST_VEC_ERR_NONE for valid cases, otherwise an enum frost_vec_error value. */
|
|
int error;
|
|
/* For FROST_VEC_ERR_PUBSHARE_PARSE: position in pubshare_indices. */
|
|
int error_index;
|
|
unsigned char expected[32];
|
|
};
|
|
"""
|
|
|
|
|
|
def init_sign_case(group_idx, case, error):
|
|
if error:
|
|
error_code, error_index = parse_sign_error(case)
|
|
expected = "{ 0 }"
|
|
else:
|
|
error_code, error_index = "FROST_VEC_ERR_NONE", -1
|
|
expected = byte_array(case["expected"])
|
|
return "{ %d, %d, %s, %s, %d, %d, %s, %s, %s, %s, %s, %d, %s }," % (
|
|
group_idx,
|
|
case["my_id"],
|
|
init_indices(case["ids"]),
|
|
init_indices_maybe(case["pubshare_indices"]),
|
|
case["secshare_index"],
|
|
case["secnonce_index"],
|
|
byte_array(case["aggnonce"]),
|
|
"%d, { %s }" % (len(bytes.fromhex(case["msg"])), hexstr_to_intarray(case["msg"])),
|
|
init_indices(case.get("tweak_indices", [])),
|
|
"{ %s }" % init_is_xonly(case, max_case_tweaks),
|
|
error_code,
|
|
error_index,
|
|
expected,
|
|
)
|
|
|
|
|
|
# sign_verify vectors
|
|
s += init_groups("sign", sign_verify_data)
|
|
for name, key, is_error in (
|
|
("sign_valid", "valid_tests", False),
|
|
("sign_error", "sign_error_tests", True),
|
|
):
|
|
flat = []
|
|
for gi, g in enumerate(sign_verify_data["test_groups"]):
|
|
for c in (g["valid_tests"] if not is_error else g["sign_error_tests"]):
|
|
flat.append((gi, c))
|
|
s += "static const struct frost_vec_sign_case frost_vec_%s_cases[%d] = {\n" % (name, len(flat))
|
|
for gi, c in flat:
|
|
s += indent(init_sign_case(gi, c, is_error) + "\n")
|
|
s += "};\n"
|
|
|
|
s += """
|
|
struct frost_vec_verify_case {
|
|
size_t group;
|
|
unsigned char psig[32];
|
|
size_t n_ids;
|
|
uint32_t ids[FROST_VEC_MAX_SIGNERS];
|
|
size_t pubshare_indices[FROST_VEC_MAX_SIGNERS];
|
|
size_t pubnonce_indices[FROST_VEC_MAX_SIGNERS];
|
|
size_t signer_index;
|
|
size_t msg_len;
|
|
unsigned char msg[FROST_VEC_MAX_MSGLEN];
|
|
/* 0 if the psig is not a valid scalar (frost_partial_sig_parse fails). */
|
|
int psig_parses;
|
|
/* 0 for verify_fail cases; otherwise an enum frost_vec_error value. */
|
|
int error;
|
|
/* Position in pubnonce_indices/pubshare_indices of the blamed value. */
|
|
int error_index;
|
|
};
|
|
"""
|
|
|
|
|
|
def init_verify_case(group_idx, case, is_error):
|
|
psig = bytes.fromhex(case["psig"])
|
|
psig_parses = 1 if int.from_bytes(psig, "big") < ORDER else 0
|
|
if is_error:
|
|
error_code, error_index = parse_verify_error(case)
|
|
else:
|
|
error_code, error_index = "FROST_VEC_ERR_NONE", -1
|
|
return "{ %d, %s, %s, { %s }, { %s }, %d, %s, %d, %s, %d }," % (
|
|
group_idx,
|
|
byte_array(case["psig"]),
|
|
init_indices(case["ids"]),
|
|
", ".join(map(str, case["pubshare_indices"])),
|
|
", ".join(map(str, case["pubnonce_indices"])),
|
|
case["signer_index"],
|
|
"%d, { %s }" % (len(bytes.fromhex(case["msg"])), hexstr_to_intarray(case["msg"])),
|
|
psig_parses,
|
|
error_code,
|
|
error_index,
|
|
)
|
|
|
|
|
|
for name, key, is_error in (
|
|
("verify_fail", "verify_fail_tests", False),
|
|
("verify_error", "verify_error_tests", True),
|
|
):
|
|
flat = []
|
|
for gi, g in enumerate(sign_verify_data["test_groups"]):
|
|
for c in g[key]:
|
|
flat.append((gi, c))
|
|
s += "static const struct frost_vec_verify_case frost_vec_%s_cases[%d] = {\n" % (name, len(flat))
|
|
for gi, c in flat:
|
|
s += indent(init_verify_case(gi, c, is_error) + "\n")
|
|
s += "};\n"
|
|
|
|
# tweak vectors (reuse the sign case struct; tweaks are indexed into the group)
|
|
s += init_groups("tweak", tweak_data)
|
|
flat_valid = []
|
|
for gi, g in enumerate(tweak_data["test_groups"]):
|
|
for c in g["valid_tests"]:
|
|
flat_valid.append((gi, c))
|
|
s += "static const struct frost_vec_sign_case frost_vec_tweak_valid_cases[%d] = {\n" % len(flat_valid)
|
|
for gi, c in flat_valid:
|
|
s += indent(init_sign_case(gi, c, False) + "\n")
|
|
s += "};\n"
|
|
s += "static const struct frost_vec_sign_case frost_vec_tweak_error_cases[%d] = {\n" % len(tweak_error_tests)
|
|
for gi, c in tweak_error_tests:
|
|
s += indent(init_sign_case(gi, c, True) + "\n")
|
|
s += "};\n"
|
|
|
|
# sig_agg vectors
|
|
s += init_groups("sig_agg", sig_agg_data)
|
|
s += """
|
|
struct frost_vec_sig_agg_case {
|
|
size_t group;
|
|
size_t n_ids;
|
|
uint32_t ids[FROST_VEC_MAX_SIGNERS];
|
|
int has_pubshares;
|
|
size_t pubshare_indices[FROST_VEC_MAX_SIGNERS];
|
|
unsigned char aggnonce[66];
|
|
size_t n_tweaks;
|
|
size_t tweak_indices[FROST_VEC_MAX_TWEAKS];
|
|
int is_xonly[FROST_VEC_MAX_TWEAKS];
|
|
size_t n_psigs;
|
|
unsigned char psigs[FROST_VEC_MAX_PSIGS][32];
|
|
size_t msg_len;
|
|
unsigned char msg[FROST_VEC_MAX_MSGLEN];
|
|
/* FROST_VEC_ERR_NONE for valid cases, otherwise an enum frost_vec_error value. */
|
|
int error;
|
|
/* For FROST_VEC_ERR_PSIG_PARSE: position in psigs. */
|
|
int error_index;
|
|
unsigned char expected[64];
|
|
};
|
|
"""
|
|
|
|
|
|
def init_sig_agg_case(group_idx, case, is_error):
|
|
if is_error:
|
|
err = case["error"]
|
|
if err["type"] == "InvalidContributionError":
|
|
assert err["contrib"] == "psig"
|
|
error_code, error_index = "FROST_VEC_ERR_PSIG_PARSE", err["signer_index"]
|
|
elif err["message"] == "The psigs and ids lists must have the same length.":
|
|
error_code, error_index = "FROST_VEC_ERR_AGG_LEN", -1
|
|
else:
|
|
sys.exit("Unknown sig_agg error: %s" % err)
|
|
expected = "{ 0 }"
|
|
else:
|
|
error_code, error_index = "FROST_VEC_ERR_NONE", -1
|
|
expected = byte_array(case["expected"])
|
|
return "{ %d, %s, %s, %s, %s, { %s }, %s, %s, %s, %d, %s }," % (
|
|
group_idx,
|
|
init_indices(case["ids"]),
|
|
init_indices_maybe(case["pubshare_indices"]),
|
|
byte_array(case["aggnonce"]),
|
|
init_indices(case["tweak_indices"]),
|
|
init_is_xonly(case, max_case_tweaks),
|
|
"%d, %s" % (
|
|
len(case["psigs"]),
|
|
"{ %s }" % ", ".join(byte_array(p) for p in case["psigs"]) if case["psigs"] else "{ { 0 } }",
|
|
),
|
|
"%d, { %s }" % (len(bytes.fromhex(case["msg"])), hexstr_to_intarray(case["msg"])),
|
|
error_code,
|
|
error_index,
|
|
expected,
|
|
)
|
|
|
|
|
|
for name, key, is_error in (
|
|
("sig_agg_valid", "valid_tests", False),
|
|
("sig_agg_error", "error_tests", True),
|
|
):
|
|
flat = []
|
|
for gi, g in enumerate(sig_agg_data["test_groups"]):
|
|
for c in g[key]:
|
|
flat.append((gi, c))
|
|
s += "static const struct frost_vec_sig_agg_case frost_vec_%s_cases[%d] = {\n" % (name, len(flat))
|
|
for gi, c in flat:
|
|
s += indent(init_sig_agg_case(gi, c, is_error) + "\n")
|
|
s += "};\n"
|
|
|
|
# det_sign vectors
|
|
s += init_groups("det_sign", det_sign_data)
|
|
s += """
|
|
struct frost_vec_det_sign_case {
|
|
size_t group;
|
|
uint32_t my_id;
|
|
size_t n_ids;
|
|
uint32_t ids[FROST_VEC_MAX_SIGNERS];
|
|
int has_pubshares;
|
|
size_t pubshare_indices[FROST_VEC_MAX_SIGNERS];
|
|
size_t secshare_index;
|
|
int has_aggothernonce;
|
|
unsigned char aggothernonce[66];
|
|
int has_aux_rand;
|
|
unsigned char aux_rand[32];
|
|
size_t msg_len;
|
|
unsigned char msg[FROST_VEC_MAX_MSGLEN];
|
|
size_t n_tweaks;
|
|
unsigned char tweaks[FROST_VEC_MAX_TWEAKS][32];
|
|
int is_xonly[FROST_VEC_MAX_TWEAKS];
|
|
/* FROST_VEC_ERR_NONE for valid cases, otherwise an enum frost_vec_error value. */
|
|
int error;
|
|
/* For FROST_VEC_ERR_PUBSHARE_PARSE: position in pubshare_indices. */
|
|
int error_index;
|
|
unsigned char expected_pubnonce[66];
|
|
unsigned char expected_psig[32];
|
|
};
|
|
"""
|
|
|
|
|
|
def init_det_case(group_idx, case, is_error):
|
|
if is_error:
|
|
error_code, error_index = parse_det_error(case)
|
|
expected = "{ 0 }, { 0 }"
|
|
else:
|
|
error_code, error_index = "FROST_VEC_ERR_NONE", -1
|
|
expected = byte_array(case["expected"][0]) + ", " + byte_array(case["expected"][1])
|
|
return "{ %d, %d, %s, %s, %d, %s, %s, %s, %s, %s, %s, %d, %s }," % (
|
|
group_idx,
|
|
case["my_id"],
|
|
init_indices(case["ids"]),
|
|
init_indices_maybe(case["pubshare_indices"]),
|
|
case["secshare_index"],
|
|
init_byte_array_maybe(case["aggothernonce"]),
|
|
init_byte_array_maybe(case["aux_rand"]),
|
|
"%d, { %s }" % (len(bytes.fromhex(case["msg"])), hexstr_to_intarray(case["msg"])),
|
|
"%d, %s" % (
|
|
len(case["tweaks"]),
|
|
"{ %s }" % ", ".join(byte_array(t) for t in case["tweaks"]) if case["tweaks"] else "{ { 0 } }",
|
|
),
|
|
"{ %s }" % init_is_xonly(case, max_case_tweaks),
|
|
error_code,
|
|
error_index,
|
|
expected,
|
|
)
|
|
|
|
|
|
for name, key, is_error in (
|
|
("det_sign_valid", "valid_tests", False),
|
|
("det_sign_error", "error_tests", True),
|
|
):
|
|
flat = []
|
|
for gi, g in enumerate(det_sign_data["test_groups"]):
|
|
for c in g[key]:
|
|
flat.append((gi, c))
|
|
s += "static const struct frost_vec_det_sign_case frost_vec_%s_cases[%d] = {\n" % (name, len(flat))
|
|
for gi, c in flat:
|
|
s += indent(init_det_case(gi, c, is_error) + "\n")
|
|
s += "};\n"
|
|
|
|
if skipped_cases:
|
|
s += "\n/* Skipped test cases (not expressible in the C API):\n"
|
|
for case in skipped_cases:
|
|
s += " * - %s\n" % case
|
|
s += " */\n"
|
|
|
|
print(s)
|