diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c6670774..25712e00 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,6 +47,7 @@ env: ECDSAADAPTOR: 'no' BPPP: 'no' SCHNORRSIG_HALFAGG: 'no' + FROST: 'no' ### test options SECP256K1_TEST_ITERS: 64 BENCH: 'yes' @@ -104,14 +105,14 @@ jobs: matrix: configuration: - env_vars: { WIDEMUL: 'int64', RECOVERY: 'yes' } - - env_vars: { WIDEMUL: 'int64', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes'} + - env_vars: { WIDEMUL: 'int64', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: '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', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes' } - - env_vars: { WIDEMUL: 'int128', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes'} + - env_vars: { WIDEMUL: 'int128', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', FROST: 'yes'} - env_vars: { WIDEMUL: 'int128', ASM: 'x86_64', ELLSWIFT: 'yes' } - - env_vars: { RECOVERY: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes'} - - env_vars: { CTIMETESTS: 'no', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', CPPFLAGS: '-DVERIFY' } + - env_vars: { RECOVERY: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', FROST: 'yes'} + - env_vars: { CTIMETESTS: 'no', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: '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' } @@ -177,6 +178,7 @@ jobs: ECDSAADAPTOR: 'yes' BPPP: 'yes' SCHNORRSIG_HALFAGG: 'yes' + FROST: 'yes' CC: ${{ matrix.cc }} steps: @@ -214,6 +216,7 @@ jobs: ECDSAADAPTOR: 'yes' BPPP: 'yes' SCHNORRSIG_HALFAGG: 'yes' + FROST: 'yes' CTIMETESTS: 'no' steps: @@ -253,6 +256,7 @@ jobs: ECDSAADAPTOR: 'yes' BPPP: 'yes' SCHNORRSIG_HALFAGG: 'yes' + FROST: 'yes' CTIMETESTS: 'no' steps: @@ -283,6 +287,7 @@ jobs: ECDSAADAPTOR: 'yes' BPPP: 'yes' SCHNORRSIG_HALFAGG: 'yes' + FROST: 'yes' CTIMETESTS: 'no' CC: ${{ matrix.cc }} @@ -332,6 +337,7 @@ jobs: ECDSAADAPTOR: 'yes' BPPP: 'yes' SCHNORRSIG_HALFAGG: 'yes' + FROST: 'yes' CTIMETESTS: 'no' steps: @@ -386,6 +392,7 @@ jobs: ECDSAADAPTOR: 'yes' BPPP: 'yes' SCHNORRSIG_HALFAGG: 'yes' + FROST: 'yes' CTIMETESTS: 'no' SECP256K1_TEST_ITERS: 2 @@ -424,6 +431,7 @@ jobs: 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' @@ -479,6 +487,7 @@ jobs: ECDSAADAPTOR: 'yes' BPPP: 'yes' SCHNORRSIG_HALFAGG: 'yes' + FROST: 'yes' CC: ${{ matrix.cc }} SECP256K1_TEST_ITERS: 32 ASM: 'no' @@ -513,6 +522,7 @@ jobs: ECDSAADAPTOR: 'yes' BPPP: 'yes' SCHNORRSIG_HALFAGG: 'yes' + FROST: 'yes' CTIMETESTS: 'no' strategy: @@ -545,15 +555,15 @@ jobs: fail-fast: false matrix: env_vars: - - { WIDEMUL: 'int64', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes' } + - { WIDEMUL: 'int64', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', FROST: 'yes' } - { WIDEMUL: 'int128_struct', ECMULTGENKB: 2, ECMULTWINDOW: 4 } - - { WIDEMUL: 'int128', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes' } + - { WIDEMUL: 'int128', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', FROST: 'yes' } - { WIDEMUL: 'int128', RECOVERY: 'yes' } - - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes' } - - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', CC: 'gcc' } - - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', WRAPPER_CMD: 'valgrind --error-exitcode=42', SECP256K1_TEST_ITERS: 2 } - - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', CC: 'gcc', WRAPPER_CMD: 'valgrind --error-exitcode=42', SECP256K1_TEST_ITERS: 2 } - - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', CPPFLAGS: '-DVERIFY', CTIMETESTS: 'no' } + - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', FROST: 'yes' } + - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', FROST: 'yes', CC: 'gcc' } + - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: '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', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: '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', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', FROST: 'yes', CPPFLAGS: '-DVERIFY', CTIMETESTS: 'no' } - BUILD: 'distcheck' steps: @@ -729,6 +739,7 @@ jobs: ECDSAADAPTOR: 'yes' BPPP: 'yes' SCHNORRSIG_HALFAGG: 'yes' + FROST: 'yes' steps: - *CHECKOUT diff --git a/.gitignore b/.gitignore index 8658272e..4f3c5340 100644 --- a/.gitignore +++ b/.gitignore @@ -55,6 +55,8 @@ coverage.*.html libsecp256k1.pc contrib/gh-pr-create.sh +frost_example + ### CMake /CMakeUserPresets.json # CMake build directories. diff --git a/CMakeLists.txt b/CMakeLists.txt index c894f41a..f59fa935 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,7 @@ option(SECP256K1_ENABLE_MODULE_RECOVERY "Enable ECDSA pubkey recovery module." O option(SECP256K1_ENABLE_MODULE_EXTRAKEYS "Enable extrakeys module." ON) option(SECP256K1_ENABLE_MODULE_SCHNORRSIG "Enable schnorrsig module." ON) option(SECP256K1_ENABLE_MODULE_MUSIG "Enable musig module." ON) +option(SECP256K1_ENABLE_MODULE_FROST "Enable FROST module (experimental)." OFF) option(SECP256K1_ENABLE_MODULE_ELLSWIFT "Enable ElligatorSwift module." ON) option(SECP256K1_ENABLE_MODULE_GENERATOR "Enable NUMS generator module." ON) @@ -297,6 +298,7 @@ message(" ECDSA pubkey recovery ............... ${SECP256K1_ENABLE_MODULE_RECOV message(" extrakeys ........................... ${SECP256K1_ENABLE_MODULE_EXTRAKEYS}") message(" schnorrsig .......................... ${SECP256K1_ENABLE_MODULE_SCHNORRSIG}") message(" musig ............................... ${SECP256K1_ENABLE_MODULE_MUSIG}") +message(" frost ............................... ${SECP256K1_ENABLE_MODULE_FROST}") message(" ElligatorSwift ...................... ${SECP256K1_ENABLE_MODULE_ELLSWIFT}") message(" generator ........................... ${SECP256K1_ENABLE_MODULE_GENERATOR}") message(" rangeproof .......................... ${SECP256K1_ENABLE_MODULE_RANGEPROOF}") diff --git a/Makefile.am b/Makefile.am index 51c8f6bf..9053929b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -212,6 +212,17 @@ 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 ### Precomputed tables @@ -348,3 +359,7 @@ 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 diff --git a/README.md b/README.md index 69456dc8..05ef12b0 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ Added features: * Experimental modules for Confidential Assets (Pedersen commitments, range proofs, and [surjection proofs](src/modules/surjection/surjection.md)). * Experimental module for [address whitelisting](src/modules/whitelist/whitelist.md). * Experimental module for Schnorr signature half-aggregation. +* Experimental module for [FROST (BIP 445)](src/modules/frost/frost.md). Experimental features are made available for testing and review by the community. The APIs of these features should not be considered stable. diff --git a/ci/ci.sh b/ci/ci.sh index 2185e789..b3bf27e0 100755 --- a/ci/ci.sh +++ b/ci/ci.sh @@ -15,7 +15,7 @@ print_environment() { ECMULTWINDOW ECMULTGENKB ASM WIDEMUL WITH_VALGRIND EXTRAFLAGS \ EXPERIMENTAL ECDH RECOVERY EXTRAKEYS SCHNORRSIG MUSIG SCHNORRSIG_HALFAGG ELLSWIFT \ ECDSA_S2C GENERATOR RANGEPROOF SURJECTIONPROOF WHITELIST ECDSAADAPTOR BPPP \ - SECP256K1_TEST_ITERS BENCH SECP256K1_BENCH_ITERS CTIMETESTS SYMBOL_CHECK \ + FROST SECP256K1_TEST_ITERS BENCH SECP256K1_BENCH_ITERS CTIMETESTS SYMBOL_CHECK \ EXAMPLES \ HOST WRAPPER_CMD \ CC CFLAGS CPPFLAGS AR NM \ @@ -69,6 +69,7 @@ fi --enable-module-schnorrsig="$SCHNORRSIG" --enable-module-ecdsa-adaptor="$ECDSAADAPTOR" \ --enable-module-musig="$MUSIG" \ --enable-module-schnorrsig-halfagg="$SCHNORRSIG_HALFAGG" \ + --enable-module-frost="$FROST" \ --enable-examples="$EXAMPLES" \ --enable-ctime-tests="$CTIMETESTS" \ --with-valgrind="$WITH_VALGRIND" \ diff --git a/configure.ac b/configure.ac index 05a8c586..9df02dd4 100644 --- a/configure.ac +++ b/configure.ac @@ -240,6 +240,11 @@ AC_ARG_ENABLE(external_default_callbacks, AS_HELP_STRING([--enable-external-default-callbacks],[enable external default callback functions [default=no]]), [], [SECP_SET_DEFAULT([enable_external_default_callbacks], [no], [no])]) +AC_ARG_ENABLE(module_frost, + AS_HELP_STRING([--enable-module-frost],[enable FROST module (experimental)]), + [], + [SECP_SET_DEFAULT([enable_module_frost], [no], [yes])]) + # Test-only override of the (autodetected by the C code) "widemul" setting. # Legal values are: # * int64 (for [u]int64_t), @@ -538,6 +543,14 @@ if test x"$enable_module_ecdh" = x"yes"; then SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_ECDH=1" fi +if test x"$enable_module_frost" = x"yes"; then + if test x"$enable_module_schnorrsig" = x"no"; then + AC_MSG_ERROR([Module dependency error: You have disabled the schnorrsig module explicitly, but it is required by the frost module.]) + fi + SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_FROST=1" + enable_module_schnorrsig=yes +fi + if test x"$enable_external_default_callbacks" = x"yes"; then SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DUSE_EXTERNAL_DEFAULT_CALLBACKS=1" fi @@ -582,6 +595,9 @@ if test x"$enable_experimental" = x"no"; then if test x"$set_asm" = x"arm32"; then AC_MSG_ERROR([ARM32 assembly is experimental. Use --enable-experimental to allow.]) fi + if test x"$enable_module_frost" = x"yes"; then + AC_MSG_ERROR([FROST module is experimental. Use --enable-experimental to allow.]) + fi fi # Check for concurrency support (tests only) @@ -619,6 +635,7 @@ AM_CONDITIONAL([ENABLE_MODULE_ECDSA_S2C], [test x"$enable_module_ecdsa_s2c" = x" AM_CONDITIONAL([ENABLE_MODULE_ECDSA_ADAPTOR], [test x"$enable_module_ecdsa_adaptor" = x"yes"]) AM_CONDITIONAL([ENABLE_MODULE_BPPP], [test x"$enable_module_bppp" = x"yes"]) AM_CONDITIONAL([ENABLE_MODULE_SCHNORRSIG_HALFAGG], [test x"$enable_module_schnorrsig_halfagg" = x"yes"]) +AM_CONDITIONAL([ENABLE_MODULE_FROST], [test x"$enable_module_frost" = x"yes"]) AM_CONDITIONAL([USE_REDUCED_SURJECTION_PROOF_SIZE], [test x"$use_reduced_surjection_proof_size" = x"yes"]) AM_CONDITIONAL([USE_EXTERNAL_ASM], [test x"$enable_external_asm" = x"yes"]) AM_CONDITIONAL([USE_ASM_ARM], [test x"$set_asm" = x"arm32"]) @@ -660,6 +677,7 @@ echo " module ecdsa-s2c = $enable_module_ecdsa_s2c" echo " module ecdsa-adaptor = $enable_module_ecdsa_adaptor" echo " module bppp = $enable_module_bppp" echo " module schnorrsig-halfagg = $enable_module_schnorrsig_halfagg" +echo " module frost = $enable_module_frost" echo echo " asm = $set_asm" echo " ecmult window size = $set_ecmult_window" diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 808917c4..cfb03222 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -31,3 +31,7 @@ endif() if(SECP256K1_ENABLE_MODULE_MUSIG) add_example(musig) endif() + +if(SECP256K1_ENABLE_MODULE_FROST) + add_example(frost) +endif() diff --git a/examples/frost.c b/examples/frost.c new file mode 100644 index 00000000..0c6a5398 --- /dev/null +++ b/examples/frost.c @@ -0,0 +1,281 @@ +/************************************************************************* + * 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 FROST module (BIP 445) to create a + * 2-of-3 threshold signature. Additionally, see the documentation in + * include/secp256k1_frost.h and src/modules/frost/frost.md. + * + * The example runs all roles (trusted dealer, signers, coordinator) in a + * single process. In a real deployment these roles are performed by + * different parties communicating over secure/authenticated channels. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "examples_util.h" + +/* Total number of participants n */ +#define N_PARTICIPANTS 3 +/* Threshold t: the minimum number of signers required to produce a + * signature */ +#define THRESHOLD 2 +/* The signers of this signing session (u = 2, participants 0 and 2) */ +#define N_SIGNERS 2 +static const uint32_t SIGNER_IDS[N_SIGNERS] = { 0, 2 }; + +struct signer_secrets { + /* The signer's secret share, received from the dealer over a secure + * channel */ + unsigned char secshare[32]; + /* Secret nonce. It is wiped by secp256k1_frost_sign; never reuse it. */ + secp256k1_frost_secnonce secnonce; +}; + +struct signer { + uint32_t id; + secp256k1_pubkey pubshare; + secp256k1_frost_pubnonce pubnonce; + secp256k1_frost_partial_sig partial_sig; +}; + +/* Run the trusted dealer key generation: from a random threshold secret key, + * derive the secret share of every participant, the threshold public key and + * the public shares. + * + * WARNING: The trusted dealer knows the threshold secret key and all secret + * shares, and must erase them securely after distributing the shares. A + * distributed key generation (DKG) protocol avoids a trusted dealer entirely + * but is out of scope for BIP 445 and for this example. */ +static int trusted_dealer_keygen(const secp256k1_context* ctx, unsigned char *threshold_seckey, unsigned char *secshares, secp256k1_pubkey *thresh_pk, secp256k1_pubkey *pubshares) { + if (!fill_random(threshold_seckey, 32)) { + printf("Failed to generate randomness\n"); + return 0; + } + if (!secp256k1_frost_trusted_dealer_keygen(ctx, secshares, thresh_pk, pubshares, N_PARTICIPANTS, THRESHOLD, threshold_seckey)) { + return 0; + } + /* Everyone can check that the public shares and the threshold public key + * are consistent. Note that this does NOT validate the security of the + * key generation that produced them. */ + if (!secp256k1_frost_threshold_info_validate(ctx, thresh_pk, pubshares, N_PARTICIPANTS, THRESHOLD)) { + return 0; + } + return 1; +} + +/* Apply an x-only tweak to the threshold public key, e.g. a BIP 341 + * ("Taproot") tweak committing to a script tree. All participants (and the + * coordinator) must apply exactly the same tweaks in the same order to their + * own tweak cache. */ +static int tweak(const secp256k1_context* ctx, secp256k1_frost_tweak_cache *cache, secp256k1_xonly_pubkey *tweaked_pk) { + /* For Taproot tweaking the tweak is set to the TapTweak hash as defined + * in BIP 341. */ + unsigned char xonly_tweak[32] = "this could be a Taproot tweak.."; + + if (!secp256k1_frost_pubkey_xonly_tweak_add(ctx, tweaked_pk, cache, xonly_tweak)) { + return 0; + } + /* For BIP 32-style plain tweaking, use + * secp256k1_frost_pubkey_ec_tweak_add instead. */ + return 1; +} + +/* Sign a message with the given signers and store the resulting BIP340 + * signature in sig64. */ +static int sign(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, struct signer *signers, const secp256k1_frost_tweak_cache *cache, const unsigned char *msg, size_t msglen, unsigned char *sig64) { + int i; + const secp256k1_frost_pubnonce *pubnonces[N_SIGNERS]; + const secp256k1_frost_partial_sig *partial_sigs[N_SIGNERS]; + secp256k1_pubkey signer_pubshares[N_SIGNERS]; + uint32_t ids[N_SIGNERS]; + /* The same for all signers and the coordinator */ + secp256k1_frost_aggnonce aggnonce; + secp256k1_frost_session session; + /* The x-only encoding of the tweaked threshold public key, bound into the + * nonce derivation */ + secp256k1_xonly_pubkey tweaked_pk; + unsigned char tweaked_pk32[32]; + + if (!secp256k1_frost_tweaked_pubkey_get(ctx, &tweaked_pk, cache)) { + return 0; + } + if (!secp256k1_xonly_pubkey_serialize(ctx, tweaked_pk32, &tweaked_pk)) { + return 0; + } + + /* Every signer creates a nonce pair and sends the pubnonce to the + * coordinator. */ + for (i = 0; i < N_SIGNERS; i++) { + unsigned char session_secrand[32]; + + ids[i] = signers[i].id; + signer_pubshares[i] = signers[i].pubshare; + pubnonces[i] = &signers[i].pubnonce; + partial_sigs[i] = &signers[i].partial_sig; + + /* Create random session randomness. It is absolutely necessary that + * this is unique for every call of secp256k1_frost_nonce_gen. + * Otherwise it's trivial for an attacker to extract the secret share! + * nonce_gen wipes session_secrand before returning. */ + if (!fill_random(session_secrand, sizeof(session_secrand))) { + printf("Failed to generate randomness\n"); + return 0; + } + /* Bind the secret share (defense-in-depth against bad randomness), + * the public share, the tweaked threshold public key and the message + * into the nonce derivation. */ + if (!secp256k1_frost_nonce_gen(ctx, &signer_secrets[i].secnonce, &signers[i].pubnonce, session_secrand, signer_secrets[i].secshare, &signers[i].pubshare, tweaked_pk32, msg, msglen, NULL, 0)) { + return 0; + } + secure_erase(session_secrand, sizeof(session_secrand)); + } + + /* Communication round 1: the coordinator aggregates the pubnonces and + * sends the aggregate nonce to the signers. */ + if (!secp256k1_frost_nonce_agg(ctx, &aggnonce, NULL, pubnonces, N_SIGNERS)) { + return 0; + } + + /* Every signer and the coordinator run session_init locally with + * identical arguments (aside from the session object), which yields + * identical sessions. */ + if (!secp256k1_frost_session_init(ctx, &session, &aggnonce, ids, signer_pubshares, N_SIGNERS, N_PARTICIPANTS, THRESHOLD, cache, msg, msglen)) { + return 0; + } + + /* Every signer creates a partial signature and sends it to the + * coordinator. frost_sign wipes the secnonce. That's because you must + * _never_ reuse the secnonce (or use the same session_secrand to create a + * secnonce). If you do, you effectively reuse the nonce and leak the + * secret share. */ + for (i = 0; i < N_SIGNERS; i++) { + if (!secp256k1_frost_sign(ctx, &signers[i].partial_sig, &signer_secrets[i].secnonce, signer_secrets[i].secshare, &session, ids, signer_pubshares, N_SIGNERS, signers[i].id)) { + return 0; + } + } + + /* Communication round 2: the coordinator verifies the partial signatures + * and aggregates them. Verifying the individual partial signatures (as + * opposed to only verifying the final signature) allows the coordinator + * to identify which signer misbehaved if the protocol run fails. */ + for (i = 0; i < N_SIGNERS; i++) { + if (!secp256k1_frost_partial_sig_verify(ctx, &signers[i].partial_sig, &signers[i].pubnonce, &signers[i].pubshare, &session, ids, N_SIGNERS, i)) { + return 0; + } + } + return secp256k1_frost_partial_sig_agg(ctx, sig64, NULL, &session, partial_sigs, N_SIGNERS); +} + +int main(void) { + secp256k1_context* ctx; + int i; + /* Secret key material known to the trusted dealer. The dealer must erase + * it after the participants received their shares (done at the end of + * this function). */ + unsigned char threshold_seckey[32]; + unsigned char secshares[N_PARTICIPANTS * 32]; + secp256k1_pubkey thresh_pk; + secp256k1_pubkey pubshares[N_PARTICIPANTS]; + secp256k1_frost_tweak_cache cache; + secp256k1_xonly_pubkey tweaked_pk; + struct signer_secrets signer_secrets[N_SIGNERS]; + struct signer signers[N_SIGNERS]; + unsigned char msg[32] = "this_could_be_the_hash_of_a_msg"; + unsigned char sig[64]; + unsigned char buf[33]; + size_t outputlen; + + /* Create a secp256k1 context */ + ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); + + printf("Generating threshold key material..."); + fflush(stdout); + if (!trusted_dealer_keygen(ctx, threshold_seckey, secshares, &thresh_pk, pubshares)) { + printf("FAILED\n"); + return EXIT_FAILURE; + } + printf("ok\n"); + + outputlen = sizeof(buf); + if (!secp256k1_ec_pubkey_serialize(ctx, buf, &outputlen, &thresh_pk, SECP256K1_EC_COMPRESSED)) { + printf("FAILED\n"); + return EXIT_FAILURE; + } + printf("Threshold public key: "); + print_hex(buf, outputlen); + fflush(stdout); + + /* The dealer hands each participant their secret share (over a secure + * channel). This example signs with the participants 0 and 2. */ + for (i = 0; i < N_SIGNERS; i++) { + signers[i].id = SIGNER_IDS[i]; + signers[i].pubshare = pubshares[SIGNER_IDS[i]]; + memcpy(signer_secrets[i].secshare, &secshares[32 * SIGNER_IDS[i]], 32); + } + + printf("Applying x-only tweak (Taproot-style)..."); + fflush(stdout); + /* Every participant and the coordinator initializes a tweak cache from + * the threshold public key and applies the same tweaks. */ + if (!secp256k1_frost_tweak_cache_init(ctx, &cache, &thresh_pk)) { + printf("FAILED\n"); + return EXIT_FAILURE; + } + if (!tweak(ctx, &cache, &tweaked_pk)) { + printf("FAILED\n"); + return EXIT_FAILURE; + } + printf("ok\n"); + if (!secp256k1_xonly_pubkey_serialize(ctx, buf, &tweaked_pk)) { + printf("FAILED\n"); + return EXIT_FAILURE; + } + printf("Tweaked threshold public key: "); + print_hex(buf, 32); + fflush(stdout); + + printf("Signing message with %d-of-%d signers...", N_SIGNERS, N_PARTICIPANTS); + fflush(stdout); + if (!sign(ctx, signer_secrets, signers, &cache, msg, sizeof(msg), sig)) { + printf("FAILED\n"); + return EXIT_FAILURE; + } + printf("ok\n"); + + printf("Verifying signature....."); + fflush(stdout); + if (!secp256k1_schnorrsig_verify(ctx, sig, msg, sizeof(msg), &tweaked_pk)) { + printf("FAILED\n"); + return EXIT_FAILURE; + } + printf("ok\n"); + + /* 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 secret key material with zeros. + * + * Here we are preventing these writes from being optimized out, as any good compiler + * will remove any writes that aren't used. + * + * The secnonces have already been wiped by secp256k1_frost_sign. */ + secure_erase(threshold_seckey, sizeof(threshold_seckey)); + secure_erase(secshares, sizeof(secshares)); + for (i = 0; i < N_SIGNERS; i++) { + secure_erase(&signer_secrets[i], sizeof(signer_secrets[i])); + } + secp256k1_context_destroy(ctx); + return EXIT_SUCCESS; +} diff --git a/include/secp256k1_frost.h b/include/secp256k1_frost.h new file mode 100644 index 00000000..d0e89d24 --- /dev/null +++ b/include/secp256k1_frost.h @@ -0,0 +1,622 @@ +#ifndef SECP256K1_FROST_H +#define SECP256K1_FROST_H + +#include "secp256k1.h" +#include "secp256k1_extrakeys.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** This module implements BIP 445 "FROST Signing Protocol for BIP340 + * Signatures" (https://github.com/siv2r/bip-frost-signing), a FROST3-based + * threshold Schnorr signature scheme. + * + * 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! + * + * Since distributed key generation is out of scope for BIP 445, this module + * provides a trusted dealer for key generation + * (secp256k1_frost_trusted_dealer_keygen). Participants are identified by + * uint32 identifiers 0..n-1 (participant id i sits at polynomial x-coordinate + * i+1). The total number of participants n must not exceed + * SECP256K1_FROST_MAX_PARTICIPANTS. + * + * A signing session involves u signers (threshold <= u <= n) and, + * optionally, a coordinator: + * 1. Every signer runs secp256k1_frost_nonce_gen and sends the pubnonce to + * the coordinator. + * 2. The coordinator aggregates the pubnonces with + * secp256k1_frost_nonce_agg and sends the aggnonce to the signers. + * 3. Everyone runs secp256k1_frost_session_init on the same session + * parameters (aggnonce, signer ids, tweak cache, message). + * 4. Every signer runs secp256k1_frost_sign and sends the partial signature + * to the coordinator. + * 5. The coordinator verifies partial signatures with + * secp256k1_frost_partial_sig_verify and aggregates them with + * secp256k1_frost_partial_sig_agg. + * + * 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. + */ + +/** The maximum number of participants n in a FROST setup. See BIP 445 for the + * security rationale behind this bound. */ +#define SECP256K1_FROST_MAX_PARTICIPANTS 128 + +/** Opaque data structures + * + * The exact representation of data inside the opaque data structures is + * implementation defined and not guaranteed to be portable between different + * platforms or versions. With the exception of `secp256k1_frost_secnonce`, + * the data structures can be safely copied/moved. 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 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. + * + * Copying this data structure can result in nonce reuse which will leak the + * signer's secret share. + */ +typedef struct secp256k1_frost_secnonce { + unsigned char data[68]; +} secp256k1_frost_secnonce; + +/** Opaque data structure that holds a signer's public nonce. + * + * Guaranteed to be 132 bytes in size. Serialized and parsed with + * `frost_pubnonce_serialize` and `frost_pubnonce_parse`. + */ +typedef struct secp256k1_frost_pubnonce { + unsigned char data[132]; +} secp256k1_frost_pubnonce; + +/** Opaque data structure that holds an aggregate public nonce. + * + * Guaranteed to be 132 bytes in size. Serialized and parsed with + * `frost_aggnonce_serialize` and `frost_aggnonce_parse`. + */ +typedef struct secp256k1_frost_aggnonce { + unsigned char data[132]; +} secp256k1_frost_aggnonce; + +/** Opaque data structure that caches the threshold public key and the state + * of public key tweaking. + * + * Initialized with `frost_tweak_cache_init` from the (untweaked) threshold + * public key and required for `frost_session_init`. Tweaks are applied to + * the cache with `frost_pubkey_xonly_tweak_add` and + * `frost_pubkey_ec_tweak_add`. + * + * Guaranteed to be 165 bytes in size. No serialization and parsing functions + * (yet). + */ +typedef struct secp256k1_frost_tweak_cache { + unsigned char data[165]; +} secp256k1_frost_tweak_cache; + +/** Opaque data structure that holds a FROST signing session. + * + * The session is signer-agnostic: the same session object can be used by a + * coordinator to verify the partial signatures of all signers. This + * structure is not required to be kept secret for the signing protocol to + * be secure. Guaranteed to be 137 bytes in size. No serialization and + * parsing functions (yet). + */ +typedef struct secp256k1_frost_session { + unsigned char data[137]; +} 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 secp256k1_frost_partial_sig { + 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 SECP256K1_WARN_UNUSED_RESULT 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 always + * 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); + +/** Parse an aggregate public nonce. + * + * In contrast to `frost_pubnonce_parse`, this function accepts the point at + * infinity (encoded as 33 zero bytes) for either nonce component, as + * specified by BIP 445 NonceAgg. + * + * 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_frost_aggnonce_parse( + const secp256k1_context *ctx, + secp256k1_frost_aggnonce *nonce, + const unsigned char *in66 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Serialize an aggregate public nonce + * + * A nonce component that is the point at infinity is encoded as 33 zero + * bytes, as specified by BIP 445. + * + * Returns: 1 always + * 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_aggnonce_serialize( + const secp256k1_context *ctx, + unsigned char *out66, + const secp256k1_frost_aggnonce *nonce +) 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 + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT 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 partial signature + * + * Returns: 1 always + * 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); + +/** Generate threshold key material with a trusted dealer. + * + * Implements the trusted dealer key generation of BIP 445: from the given + * threshold secret key, the dealer derives the secret share of every + * participant and the corresponding public shares. The dealer must transmit + * each secret share to its participant over a secure channel and erase all + * secret key material afterwards. + * + * Returns: 0 if the arguments are invalid, 1 otherwise + * Args: ctx: pointer to a context object + * Out: secshares32: pointer to an n_participants*32-byte array to store + * the secret shares; participant with id i receives + * secshares32[i*32..(i+1)*32] + * thresh_pk: pointer to a pubkey object to store the threshold + * public key (full point, parity is meaningful) + * pubshares: pointer to an array of n_participants pubkey + * objects to store the public shares; entry i belongs + * to the participant with id i + * In: n_participants: total number of participants n. Must be between 1 + * and SECP256K1_FROST_MAX_PARTICIPANTS. + * threshold: threshold t. Must be between 1 and n_participants. + * threshold_seckey32: pointer to the 32-byte threshold secret key + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_trusted_dealer_keygen( + const secp256k1_context *ctx, + unsigned char *secshares32, + secp256k1_pubkey *thresh_pk, + secp256k1_pubkey *pubshares, + size_t n_participants, + uint32_t threshold, + const unsigned char *threshold_seckey32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(7); + +/** Validate threshold key material. + * + * Implements ValidateThresholdInfo of BIP 445: checks that the public shares + * lie on a single polynomial and that they are consistent with the threshold + * public key. Note that this validates functional compatibility of the key + * material; it does NOT validate the security of the key generation that + * produced it. + * + * Returns: 1 if the key material is valid and consistent, 0 otherwise + * Args: ctx: pointer to a context object + * In: thresh_pk: pointer to the threshold public key + * pubshares: array of n_participants pubkeys; entry i is the + * public share of the participant with id i + * n_participants: total number of participants n + * threshold: threshold t + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_threshold_info_validate( + const secp256k1_context *ctx, + const secp256k1_pubkey *thresh_pk, + const secp256k1_pubkey *pubshares, + size_t n_participants, + uint32_t threshold +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Initialize a tweak cache from the threshold public key. + * + * The tweak cache is required for creating a signing session with + * `frost_session_init`, even if no tweaks are applied. + * + * Returns: 0 if the arguments are invalid, 1 otherwise + * Args: ctx: pointer to a context object + * Out: cache: pointer to the tweak cache to initialize + * In: thresh_pk: pointer to the (untweaked) threshold public key + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_tweak_cache_init( + const secp256k1_context *ctx, + secp256k1_frost_tweak_cache *cache, + const secp256k1_pubkey *thresh_pk +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Get the current (tweaked) threshold public key from a tweak cache. + * + * This is the BIP340 x-only public key that final signatures of sessions + * created with this cache verify against. + * + * Returns: 0 if the arguments are invalid, 1 otherwise + * Args: ctx: pointer to a context object + * Out: tweaked_pk: pointer to an xonly_pubkey object to store the tweaked + * threshold public key + * In: cache: pointer to the tweak cache + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_tweaked_pubkey_get( + const secp256k1_context *ctx, + secp256k1_xonly_pubkey *tweaked_pk, + const secp256k1_frost_tweak_cache *cache +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Apply an x-only tweak to the tweak cache. + * + * Implements ApplyTweak of BIP 445 with is_xonly = true, i.e. BIP 341 + * ("Taproot") tweaking: the current public key is negated if it has odd Y + * before the tweak is applied. + * + * Returns: 0 if the arguments are invalid or the tweaked key would be the + * point at infinity, 1 otherwise + * Args: ctx: pointer to a context object + * Out: tweaked_pk: pointer to an xonly_pubkey object to store the tweaked + * threshold public key. If you do not need it, this arg can + * be NULL. + * In: cache: pointer to the tweak cache + * tweak32: pointer to the 32-byte tweak + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_pubkey_xonly_tweak_add( + const secp256k1_context *ctx, + secp256k1_xonly_pubkey *tweaked_pk, + secp256k1_frost_tweak_cache *cache, + const unsigned char *tweak32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Apply a plain tweak to the tweak cache. + * + * Implements ApplyTweak of BIP 445 with is_xonly = false, i.e. ordinary + * (BIP 32-style) tweaking: the current public key is not negated before the + * tweak is applied. + * + * Returns: 0 if the arguments are invalid or the tweaked key would be the + * point at infinity, 1 otherwise + * Args: ctx: pointer to a context object + * Out: tweaked_pk: pointer to an xonly_pubkey object to store the tweaked + * threshold public key. If you do not need it, this arg can + * be NULL. + * In: cache: pointer to the tweak cache + * tweak32: pointer to the 32-byte tweak + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_pubkey_ec_tweak_add( + const secp256k1_context *ctx, + secp256k1_xonly_pubkey *tweaked_pk, + secp256k1_frost_tweak_cache *cache, + const unsigned char *tweak32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Create a FROST nonce (pair) and its public counterpart. + * + * Implements NonceGen of BIP 445. This function must only be called once per + * signing session; never reuse a secnonce for a second signature, as this + * leaks the secret share. To prevent reuse, this function wipes + * session_secrand32 before returning, and `frost_sign` wipes the secnonce. + * + * Returns: 0 if the arguments are invalid, 1 otherwise + * Args: ctx: pointer to a context object + * Out: secnonce: pointer to a secnonce object that will be + * required for `frost_sign` + * pubnonce: pointer to a pubnonce object to be sent to the + * coordinator + * In/Out: session_secrand32: pointer to 32 bytes of fresh randomness. Must + * be unique for every call. It is wiped before + * this function returns. + * In: secshare: pointer to the signer's 32-byte secret share, + * or NULL. Providing the secret share adds + * defense-in-depth against bad randomness (the + * randomness is masked with the share, see + * BIP 445 "Modifications to Nonce Generation"). + * pubshare: pointer to the signer's public share, or NULL + * thresh_pk32: pointer to the 32-byte x-only encoding of the + * threshold public key the signature will verify + * against (i.e. after applying tweaks, if any), + * or NULL + * msg: pointer to the message to be signed, or NULL if + * the message is not known yet + * msglen: length of msg. Must be 0 if msg is NULL. + * extra_in: pointer to additional data to bind into the + * nonce derivation, or NULL + * extra_in_len: length of extra_in. Must be 0 if extra_in is + * NULL. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_nonce_gen( + const secp256k1_context *ctx, + secp256k1_frost_secnonce *secnonce, + secp256k1_frost_pubnonce *pubnonce, + unsigned char *session_secrand32, + const unsigned char *secshare32, + const secp256k1_pubkey *pubshare, + const unsigned char *thresh_pk32, + const unsigned char *msg, + size_t msglen, + const unsigned char *extra_in, + size_t extra_in_len +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Aggregate the public nonces of the signers. + * + * Implements NonceAgg of BIP 445. Note that the aggregate nonce may contain + * the point at infinity (if the corresponding column sums to it); this is + * not an error. + * + * Returns: 0 if the arguments are invalid or one of the pubnonces is + * malformed, 1 otherwise + * Args: ctx: pointer to a context object + * Out: aggnonce: pointer to an aggnonce object + * error_index: if non-NULL, set to the index of the offending + * pubnonce on failure + * In: pubnonces: input array of pointers to pubnonces. The pubnonce at + * index i must belong to the signer with ids[i] passed + * to `frost_session_init`. + * n_pubnonces: length of the pubnonces array. Must be greater than + * 0. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_nonce_agg( + const secp256k1_context *ctx, + secp256k1_frost_aggnonce *aggnonce, + size_t *error_index, + const secp256k1_frost_pubnonce *const *pubnonces, + size_t n_pubnonces +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4); + +/** Initialize a FROST signing session. + * + * Implements GetSessionValues of BIP 445: computes the nonce coefficient, + * the final nonce, and the BIP340 challenge. All signers and the coordinator + * must call this function with identical arguments (aside from ctx and + * session). The session is signer-agnostic; the coordinator can use it to + * verify the partial signatures of all signers. + * + * Returns: 0 if the arguments are invalid (including inconsistent key + * material or duplicate signer ids), 1 otherwise + * Args: ctx: pointer to a context object + * Out: session: pointer to a session object + * In: aggnonce: pointer to the aggregate nonce from + * `frost_nonce_agg` + * ids: array of the u signer identifiers. Every id must + * be unique and smaller than n_participants. + * pubshares: array of u pubkeys with the public shares of the + * signers (entry i belongs to ids[i]), or NULL if the + * pubshares are unknown. If provided, they are + * validated against the threshold public key. + * n_signers: number of signers u. Must be between threshold and + * n_participants. + * n_participants: total number of participants n. Must be at most + * SECP256K1_FROST_MAX_PARTICIPANTS. + * threshold: threshold t. Must be between 1 and n_participants. + * tweak_cache: pointer to the tweak cache holding the threshold + * public key and all tweaks applied to it + * msg: pointer to the message to sign + * msglen: length of msg + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_session_init( + const secp256k1_context *ctx, + secp256k1_frost_session *session, + const secp256k1_frost_aggnonce *aggnonce, + const uint32_t *ids, + const secp256k1_pubkey *pubshares, + size_t n_signers, + size_t n_participants, + uint32_t threshold, + const secp256k1_frost_tweak_cache *tweak_cache, + const unsigned char *msg, + size_t msglen +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(9) SECP256K1_ARG_NONNULL(10); + +/** Produce a partial signature. + * + * Implements Sign of BIP 445. Fails if my_id is not in the session's + * signer set. If pubshares is non-NULL, it must be the same array that was + * passed to `frost_session_init`, and the secret share is checked against + * the signer's public share (recommended; pass NULL only if the pubshares + * are unavailable). The secnonce is wiped by this function; calling it + * again with the same secnonce fails. + * + * The same ids array that was passed to `frost_session_init` must be passed + * here. + * + * Returns: 0 if the arguments are invalid or signing fails, 1 otherwise + * Args: ctx: pointer to a context object + * Out: partial_sig: pointer to a partial_sig object + * In: secnonce: pointer to the signer's secnonce from + * `frost_nonce_gen` + * secshare32: pointer to the signer's 32-byte secret share + * session: pointer to the session + * ids: array of the u signer identifiers (identical to + * session_init) + * pubshares: array of u pubkeys with the signers' public shares + * (identical to session_init), or NULL + * n_signers: number of signers u + * my_id: this signer's identifier + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_sign( + const secp256k1_context *ctx, + secp256k1_frost_partial_sig *partial_sig, + secp256k1_frost_secnonce *secnonce, + const unsigned char *secshare32, + const secp256k1_frost_session *session, + const uint32_t *ids, + const secp256k1_pubkey *pubshares, + size_t n_signers, + uint32_t my_id +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6); + +/** Produce a partial signature with a deterministically derived nonce. + * + * Implements DeterministicSign of BIP 445. This function combines nonce + * generation and signing into one step for a signer that is online + * throughout the whole session. The nonce is derived deterministically from + * the secret share, the signer set, the other signers' aggregate nonce, the + * tweaked threshold public key, and the message; no secnonce object is + * involved. + * + * A sole signer (u = 1) passes aggothernonce = NULL. Otherwise aggothernonce + * is the aggregate of all _other_ signers' pubnonces (obtainable via + * `frost_nonce_agg`). Unlike an aggnonce passed to `frost_session_init`, the + * aggothernonce must not contain the point at infinity (BIP 445 feeds it + * through NonceAgg as a pubnonce contribution, and a pubnonce's components + * are never the point at infinity); if it does, this function fails. + * + * Returns: 0 if the arguments are invalid or signing fails, 1 otherwise + * Args: ctx: pointer to a context object + * Out: partial_sig: pointer to a partial_sig object + * pubnonce: pointer to a pubnonce object holding this signer's + * public nonce, to be sent to the coordinator + * In: secshare32: pointer to the signer's 32-byte secret share + * my_id: this signer's identifier + * aggothernonce: pointer to the aggregate of the other signers' + * public nonces, or NULL for a sole signer + * ids: array of the u signer identifiers + * pubshares: array of u pubkeys with the signers' public + * shares, or NULL + * n_signers: number of signers u + * n_participants: total number of participants n + * threshold: threshold t + * tweak_cache: pointer to the tweak cache + * msg: pointer to the message to sign + * msglen: length of msg + * aux_rand32: pointer to 32 bytes of auxiliary randomness mixed + * into the nonce derivation, or NULL + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_deterministic_sign( + const secp256k1_context *ctx, + secp256k1_frost_partial_sig *partial_sig, + secp256k1_frost_pubnonce *pubnonce, + const unsigned char *secshare32, + uint32_t my_id, + const secp256k1_frost_aggnonce *aggothernonce, + const uint32_t *ids, + const secp256k1_pubkey *pubshares, + size_t n_signers, + size_t n_participants, + uint32_t threshold, + const secp256k1_frost_tweak_cache *tweak_cache, + const unsigned char *msg, + size_t msglen, + const unsigned char *aux_rand32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(12) SECP256K1_ARG_NONNULL(13); + +/** Verify a partial signature. + * + * Implements PartialSigVerify of BIP 445. The same ids array that was passed + * to `frost_session_init` must be passed here; signer_index is the index + * into that array identifying the signer whose partial signature is + * verified. + * + * Returns: 1 if the partial signature is valid, 0 otherwise + * Args: ctx: pointer to a context object + * In: partial_sig: pointer to the partial signature + * pubnonce: pointer to the signer's public nonce + * pubshare: pointer to the signer's public share + * session: pointer to the session + * ids: array of the u signer identifiers (identical to + * session_init) + * n_signers: number of signers u + * signer_index: index of the signer in the ids array + */ +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 uint32_t *ids, + size_t n_signers, + size_t signer_index +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6); + +/** Aggregate partial signatures into a BIP340 signature. + * + * Implements PartialSigAgg of BIP 445. The number of partial signatures must + * equal the number of signers u given to `frost_session_init`. The partial + * signature at index i must belong to the signer with ids[i]. + * + * Returns: 0 if the arguments are invalid or a partial signature cannot be + * parsed, 1 otherwise. Note that 1 does NOT mean that the resulting + * signature verifies; invalid partial signatures are only detected + * by `frost_partial_sig_verify`. + * Args: ctx: pointer to a context object + * Out: sig64: pointer to a 64-byte array to store the final + * BIP340 signature + * error_index: if non-NULL, set to the index of the offending + * partial signature on failure + * In: session: pointer to the session + * partial_sigs: input array of pointers to partial signatures + * n_sigs: length of the partial_sigs array. Must equal + * n_signers from `frost_session_init`. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_frost_partial_sig_agg( + const secp256k1_context *ctx, + unsigned char *sig64, + size_t *error_index, + 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(4) SECP256K1_ARG_NONNULL(5); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4431fd47..1f544426 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -82,6 +82,15 @@ if(SECP256K1_ENABLE_MODULE_MUSIG) set_property(TARGET secp256k1 APPEND PROPERTY PUBLIC_HEADER ${PROJECT_SOURCE_DIR}/include/secp256k1_musig.h) endif() +if(SECP256K1_ENABLE_MODULE_FROST) + 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 frost module.") + endif() + set(SECP256K1_ENABLE_MODULE_SCHNORRSIG ON) + add_compile_definitions(ENABLE_MODULE_FROST=1) + set_property(TARGET secp256k1 APPEND PROPERTY PUBLIC_HEADER ${PROJECT_SOURCE_DIR}/include/secp256k1_frost.h) +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.") diff --git a/src/ctime_tests.c b/src/ctime_tests.c index 30cbe7a1..4bc11ec5 100644 --- a/src/ctime_tests.c +++ b/src/ctime_tests.c @@ -53,6 +53,10 @@ # pragma GCC diagnostic warning "-Wunused-function" #endif +#ifdef ENABLE_MODULE_FROST +#include "../include/secp256k1_frost.h" +#endif + static void run_tests(secp256k1_context *ctx, unsigned char *key); int main(void) { @@ -361,6 +365,82 @@ static void run_tests(secp256k1_context *ctx, unsigned char *key) { CHECK(ret == 0); } #endif + +#ifdef ENABLE_MODULE_FROST + { + unsigned char thresh_seckey[32]; + unsigned char secshares[2 * 32]; + secp256k1_pubkey thresh_pk; + secp256k1_pubkey pubshares[2]; + uint32_t frost_ids[2] = { 0, 1 }; + secp256k1_frost_tweak_cache cache; + secp256k1_frost_secnonce secnonce[2]; + secp256k1_frost_pubnonce pubnonce[2]; + const secp256k1_frost_pubnonce *pubnonce_ptrs[2]; + secp256k1_frost_aggnonce aggnonce; + secp256k1_frost_session session; + secp256k1_frost_partial_sig partial_sig[2]; + const secp256k1_frost_partial_sig *partial_sig_ptrs[2]; + unsigned char session_secrand[2][32]; + + pubnonce_ptrs[0] = &pubnonce[0]; + pubnonce_ptrs[1] = &pubnonce[1]; + partial_sig_ptrs[0] = &partial_sig[0]; + partial_sig_ptrs[1] = &partial_sig[1]; + + /* All public inputs are derived from defined memory. key is reused as + * the base of the (secret) threshold key and session randomness. */ + SECP256K1_CHECKMEM_DEFINE(key, 32); + memcpy(thresh_seckey, key, sizeof(thresh_seckey)); + thresh_seckey[0] = thresh_seckey[0] + 1; + memcpy(session_secrand[0], key, 32); + session_secrand[0][0] = session_secrand[0][0] + 2; + memcpy(session_secrand[1], key, 32); + session_secrand[1][0] = session_secrand[1][0] + 3; + + /* Test frost_trusted_dealer_keygen. The threshold secret key and the + * resulting secret shares are secret; the threshold public key and + * the public shares are public. */ + SECP256K1_CHECKMEM_UNDEFINE(thresh_seckey, sizeof(thresh_seckey)); + ret = secp256k1_frost_trusted_dealer_keygen(ctx, secshares, &thresh_pk, pubshares, 2, 2, thresh_seckey); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret == 1); + SECP256K1_CHECKMEM_DEFINE(&thresh_pk, sizeof(thresh_pk)); + SECP256K1_CHECKMEM_DEFINE(pubshares, sizeof(pubshares)); + + /* The session setup uses only public inputs. */ + CHECK(secp256k1_frost_tweak_cache_init(ctx, &cache, &thresh_pk) == 1); + /* Make sure that previous tests don't undefine msg. It's not used as a secret here. */ + SECP256K1_CHECKMEM_DEFINE(msg, sizeof(msg)); + + /* Test frost_nonce_gen. The session randomness and the secret share + * are secret; the pubnonce is public. The secnonce stays secret. */ + for (i = 0; i < 2; i++) { + SECP256K1_CHECKMEM_UNDEFINE(session_secrand[i], 32); + SECP256K1_CHECKMEM_UNDEFINE(&secshares[32 * i], 32); + ret = secp256k1_frost_nonce_gen(ctx, &secnonce[i], &pubnonce[i], session_secrand[i], &secshares[32 * i], &pubshares[i], NULL, msg, 32, NULL, 0); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret == 1); + SECP256K1_CHECKMEM_DEFINE(&pubnonce[i], sizeof(pubnonce[i])); + } + + CHECK(secp256k1_frost_nonce_agg(ctx, &aggnonce, NULL, pubnonce_ptrs, 2) == 1); + CHECK(secp256k1_frost_session_init(ctx, &session, &aggnonce, frost_ids, pubshares, 2, 2, 2, &cache, msg, 32) == 1); + + /* Test frost_sign. The secret share is secret (the secnonce is + * tainted through the tainted session randomness; its magic bytes + * must remain defined for the validity check). The partial signature + * is public. */ + for (i = 0; i < 2; i++) { + SECP256K1_CHECKMEM_UNDEFINE(&secshares[32 * i], 32); + ret = secp256k1_frost_sign(ctx, &partial_sig[i], &secnonce[i], &secshares[32 * i], &session, frost_ids, pubshares, 2, frost_ids[i]); + SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret)); + CHECK(ret == 1); + SECP256K1_CHECKMEM_DEFINE(&partial_sig[i], sizeof(partial_sig[i])); + } + CHECK(secp256k1_frost_partial_sig_agg(ctx, sig, NULL, &session, partial_sig_ptrs, 2) == 1); + } +#endif } #if defined(__GNUC__) diff --git a/src/hash.h b/src/hash.h index 79d97671..7946fbac 100644 --- a/src/hash.h +++ b/src/hash.h @@ -23,6 +23,9 @@ typedef struct { } secp256k1_sha256; static void secp256k1_sha256_initialize(secp256k1_sha256 *hash); +/* Initializes a sha256 struct and writes the 64 byte string + * SHA256(tag)||SHA256(tag) into it. */ +static void secp256k1_sha256_initialize_tagged(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *hash, const unsigned char *tag, size_t taglen); /* Initialize a SHA256 hash state with a precomputed midstate. * The byte counter must be a multiple of 64, i.e., there must be no unwritten * bytes in the buffer. */ diff --git a/src/hash_impl.h b/src/hash_impl.h index 7c40f82e..45ad8833 100644 --- a/src/hash_impl.h +++ b/src/hash_impl.h @@ -191,8 +191,6 @@ static void secp256k1_sha256_finalize(const secp256k1_hash_ctx *hash_ctx, secp25 } } -/* Initializes a sha256 struct and writes the 64 byte string - * SHA256(tag)||SHA256(tag) into it. */ static void secp256k1_sha256_initialize_tagged(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *hash, const unsigned char *tag, size_t taglen) { unsigned char buf[32]; secp256k1_sha256_initialize(hash); diff --git a/src/modules/frost/Makefile.am.include b/src/modules/frost/Makefile.am.include new file mode 100644 index 00000000..b09307de --- /dev/null +++ b/src/modules/frost/Makefile.am.include @@ -0,0 +1,8 @@ +include_HEADERS += include/secp256k1_frost.h +noinst_HEADERS += src/modules/frost/main_impl.h +noinst_HEADERS += src/modules/frost/keygen.h +noinst_HEADERS += src/modules/frost/keygen_impl.h +noinst_HEADERS += src/modules/frost/session.h +noinst_HEADERS += src/modules/frost/session_impl.h +noinst_HEADERS += src/modules/frost/tests_impl.h +noinst_HEADERS += src/modules/frost/vectors.h diff --git a/src/modules/frost/frost.md b/src/modules/frost/frost.md new file mode 100644 index 00000000..f93528a7 --- /dev/null +++ b/src/modules/frost/frost.md @@ -0,0 +1,120 @@ +Notes on the frost module API +============================= + +This module implements BIP 445 "FROST Signing Protocol for BIP340 Signatures" +(FROST3), a threshold Schnorr signature scheme: any t-of-n subset of +participants can jointly produce a BIP340 signature on the shared threshold +public key. The specification lives at +https://github.com/siv2r/bip-frost-signing. The implementation and its test +vectors are validated against the pinned spec commit +`bb5396f90d45ba5a954cbfd1af80f1b45e02b229` (BIP v0.10.0). + +The following sections contain additional notes on the API of the frost module +(`include/secp256k1_frost.h`). A usage example can be found in +`examples/frost.c`. + +**This module is experimental.** Do not use it in production. The API should +not be considered stable. + +Key generation +-------------- + +Distributed key generation (DKG) is out of scope for BIP 445; the intended DKG +is ChillDKG (https://github.com/BlockstreamResearch/bip-frost-dkg). This module +therefore only provides key generation with a trusted dealer: +`secp256k1_frost_trusted_dealer_keygen` derives, from a threshold secret key, +one secret share and one public share per participant. + +The dealer MUST transmit each secret share to its participant over a secure +(authenticated and encrypted) channel and MUST erase the threshold secret key +and all secret shares afterwards. If key generation is compromised, the entire +setup is compromised; `secp256k1_frost_threshold_info_validate` cannot detect +this. It only proves that the key material is functionally compatible (the +public shares lie on a single polynomial consistent with the threshold public +key) — it says nothing about the security of the key generation that produced +it. + +Signing flow +------------ + +A signing session involves u signers (threshold <= u <= n) and, optionally, a +coordinator: + +1. Every signer runs `secp256k1_frost_nonce_gen` and sends the pubnonce to the + coordinator. +2. The coordinator aggregates the pubnonces with `secp256k1_frost_nonce_agg` + and sends the aggnonce to the signers. +3. Everyone runs `secp256k1_frost_session_init` on identical session + parameters (aggnonce, signer ids, tweak cache, message). +4. Every signer runs `secp256k1_frost_sign` and sends the partial signature + to the coordinator. +5. The coordinator verifies every partial signature with + `secp256k1_frost_partial_sig_verify` and aggregates them with + `secp256k1_frost_partial_sig_agg` into the final BIP340 signature. + +The session object is signer-agnostic: a coordinator initializes a single +session and uses it to verify the partial signatures of all signers. + +`secp256k1_frost_deterministic_sign` is an alternative for a signer that is +online throughout the whole session: it combines nonce generation and signing +into one deterministic step and involves no secnonce object. + +`secp256k1_frost_nonce_agg` and `secp256k1_frost_partial_sig_agg` support +identifiable abort via their `error_index` out-params: on failure, they report +the index of the offending contribution. Note that invalid partial signatures +are only detected by `secp256k1_frost_partial_sig_verify`; a successful +`secp256k1_frost_partial_sig_agg` does NOT imply that the resulting signature +verifies. + +The same `ids` array that is passed to `secp256k1_frost_session_init` must be +passed identically to `secp256k1_frost_sign` and +`secp256k1_frost_partial_sig_verify`. + +Tweaking +-------- + +Public key tweaking (e.g. BIP 341 Taproot tweaking) is handled via a tweak +cache: initialize it from the untweaked threshold public key with +`secp256k1_frost_tweak_cache_init`, apply tweaks with +`secp256k1_frost_pubkey_xonly_tweak_add` (x-only/BIP 341 tweaking) and/or +`secp256k1_frost_pubkey_ec_tweak_add` (plain/BIP 32-style tweaking), and +retrieve the resulting x-only threshold public key with +`secp256k1_frost_tweaked_pubkey_get`. A tweak cache is required for +`secp256k1_frost_session_init` even if no tweaks are applied; all session +participants must apply the same tweaks in the same order. + +Security notes +-------------- + +- A secnonce must never be reused. Reusing a secret nonce in two signatures + leaks the signer's secret share. To prevent reuse, `secp256k1_frost_sign` + wipes the secnonce (a second call with the same secnonce fails), and + `secp256k1_frost_nonce_gen` wipes `session_secrand32`. Never copy, serialize + or otherwise duplicate a `secp256k1_frost_secnonce` structure. +- `session_secrand32` must be 32 bytes of fresh, uniformly random data that is + unique for every call to `secp256k1_frost_nonce_gen`. Passing the secret + share to `nonce_gen` is recommended as defense-in-depth against bad + randomness. +- Final signatures produced by `secp256k1_frost_partial_sig_agg` are ordinary + BIP340 signatures; they are verified with `secp256k1_schnorrsig_verify` + against the (tweaked) x-only threshold public key. + +Deviations from the BIP 445 reference code +------------------------------------------ + +- Error model: the BIP 445 reference code raises exceptions; this API maps + them to 0 return values, to the illegal-argument callback (for violations of + the documented API contract, e.g. NULL arguments or corrupt opaque structs), + and to `error_index` out-params (for identifying the offending contribution + in `nonce_agg` and `partial_sig_agg`). +- `secp256k1_frost_threshold_info_validate` requires all n public shares to be + present; the BIP 445 algorithm tolerates missing pubshares ("holes"), which + is not expressible in this API. +- 8 error test cases of the BIP 445 tweak vectors (mismatched `tweaks` and + `is_xonly` array lengths, non-32-byte tweaks) are not expressible in this + API — tweaks are applied individually and have a fixed length of 32 bytes — + and are therefore skipped (documented in `src/modules/frost/vectors.h`). +- Signer identifiers must be passed to `secp256k1_frost_sign` and + `secp256k1_frost_partial_sig_verify` identical to + `secp256k1_frost_session_init` (the BIP 445 reference code carries them in + its session/context objects instead). diff --git a/src/modules/frost/keygen.h b/src/modules/frost/keygen.h new file mode 100644 index 00000000..4ac798ca --- /dev/null +++ b/src/modules/frost/keygen.h @@ -0,0 +1,56 @@ +/*********************************************************************** + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_FROST_KEYGEN_H +#define SECP256K1_MODULE_FROST_KEYGEN_H + +#include "../../../include/secp256k1.h" +#include "../../../include/secp256k1_frost.h" + +#include "../../group.h" +#include "../../hash.h" +#include "../../scalar.h" + +typedef struct { + /* The untweaked threshold public key (Q_0 in the specification). Required + * for validating the signers' pubshares in session_init. Never the point + * at infinity. */ + secp256k1_ge thresh_pk; + /* The current (tweaked) threshold public key (Q in the specification). + * Never the point at infinity. */ + secp256k1_ge pk; + /* Accumulated tweak. Identical to tacc in the specification. */ + secp256k1_scalar tacc; + /* gacc_parity corresponds to (1 - gacc)/2 in the specification. So if + * gacc is -1, gacc_parity is 1. Otherwise, gacc_parity is 0. */ + int gacc_parity; +} secp256k1_frost_tweak_cache_internal; + +static void secp256k1_frost_tweak_cache_save(secp256k1_frost_tweak_cache *cache, const secp256k1_frost_tweak_cache_internal *cache_i); + +static int secp256k1_frost_tweak_cache_load(const secp256k1_context* ctx, secp256k1_frost_tweak_cache_internal *cache_i, const secp256k1_frost_tweak_cache *cache); + +/* Computes the Lagrange interpolating value for signer my_id as defined in the + * BIP 445 derive_interpolating_value algorithm: with x-coordinate of an + * identifier id being id + 1, the value is + * lambda = product_{j != i} x_j / (x_j - x_i) (mod n). + * Returns 1 on success and 0 if my_id is not in ids, if ids contains + * duplicates, or if an id equals UINT32_MAX (for which id + 1 overflows). */ +static int secp256k1_frost_derive_interpolating_value(secp256k1_scalar *out, const uint32_t *ids, size_t n_ids, uint32_t my_id); + +/* Evaluates the polynomial given by the pubshares at the identifier-space + * point x (a scalar, i.e., identifier -1 is represented by -1 mod n), as + * defined in the BIP 445 derive_pubshare_at algorithm. Returns 1 on success + * and 0 if ids contains duplicates. The result may be the point at infinity; + * the caller must handle that case. */ +static int secp256k1_frost_derive_pubshare_at(secp256k1_gej *out, const uint32_t *ids, const secp256k1_ge *pubshares, size_t n_ids, const secp256k1_scalar *x); + +/* Derives the threshold public key from the pubshares by evaluating the + * polynomial at identifier -1 (i.e., x-coordinate 0), as defined in the + * BIP 445 derive_thresh_pubkey algorithm. Returns 1 on success and 0 if ids + * contains duplicates or the result is the point at infinity. */ +static int secp256k1_frost_derive_thresh_pubkey(secp256k1_gej *out, const uint32_t *ids, const secp256k1_ge *pubshares, size_t n_ids); + +#endif diff --git a/src/modules/frost/keygen_impl.h b/src/modules/frost/keygen_impl.h new file mode 100644 index 00000000..9fa9c7ac --- /dev/null +++ b/src/modules/frost/keygen_impl.h @@ -0,0 +1,459 @@ +/*********************************************************************** + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_FROST_KEYGEN_IMPL_H +#define SECP256K1_MODULE_FROST_KEYGEN_IMPL_H + +#include + +#include "../../../include/secp256k1.h" +#include "../../../include/secp256k1_frost.h" + +#include "keygen.h" +#include "../../eckey.h" +#include "../../ecmult.h" +#include "../../util.h" + +/* Initializes SHA256 with the BIP 445 "BIP0445/trusted/keygen" tag. */ +static void secp256k1_frost_sha256_tagged_trusted_keygen(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *sha) { + secp256k1_sha256_initialize_tagged(hash_ctx, sha, (const unsigned char *)"BIP0445/trusted/keygen", sizeof("BIP0445/trusted/keygen") - 1); +} + +/* Derives the i-th (1 <= i <= t-1) trusted-dealer polynomial coefficient as + * a_i = tagged_hash("BIP0445/trusted/keygen", thresh_sk32 || ser32(i)). + * Returns 0 if the hash output is zero or overflows the curve order (which can + * only happen with negligible probability). */ +static int secp256k1_frost_derive_coefficient(const secp256k1_hash_ctx *hash_ctx, secp256k1_scalar *out, const unsigned char *thresh_sk32, uint32_t i) { + secp256k1_sha256 sha; + unsigned char buf[4]; + unsigned char hash32[32]; + int overflow; + + secp256k1_frost_sha256_tagged_trusted_keygen(hash_ctx, &sha); + secp256k1_sha256_write(hash_ctx, &sha, thresh_sk32, 32); + secp256k1_write_be32(buf, i); + secp256k1_sha256_write(hash_ctx, &sha, buf, sizeof(buf)); + secp256k1_sha256_finalize(hash_ctx, &sha, hash32); + secp256k1_memclear_explicit(buf, sizeof(buf)); + secp256k1_scalar_set_b32(out, hash32, &overflow); + secp256k1_memclear_explicit(hash32, sizeof(hash32)); + return !overflow && !secp256k1_scalar_is_zero(out); +} + +static const unsigned char secp256k1_frost_tweak_cache_magic[4] = { 0x8d, 0x86, 0xb5, 0x01 }; + +/* A tweak cache consists of + * - 4 byte magic set during initialization to allow detecting an uninitialized + * object. + * - 64 byte untweaked threshold public key (Q_0) + * - 64 byte current (tweaked) threshold public key (Q) + * - 32 byte tweak accumulator tacc + * - 1 byte gacc_parity (1 if the tweak factor accumulator gacc is -1) + */ +/* Requires that cache_i->thresh_pk and cache_i->pk are not infinity. */ +static void secp256k1_frost_tweak_cache_save(secp256k1_frost_tweak_cache *cache, const secp256k1_frost_tweak_cache_internal *cache_i) { + unsigned char *ptr = cache->data; + + VERIFY_CHECK(!secp256k1_ge_is_infinity(&cache_i->thresh_pk)); + VERIFY_CHECK(!secp256k1_ge_is_infinity(&cache_i->pk)); + memcpy(ptr, secp256k1_frost_tweak_cache_magic, 4); + ptr += 4; + secp256k1_ge_to_bytes(ptr, &cache_i->thresh_pk); + ptr += 64; + secp256k1_ge_to_bytes(ptr, &cache_i->pk); + ptr += 64; + secp256k1_scalar_get_b32(ptr, &cache_i->tacc); + ptr += 32; + *ptr = cache_i->gacc_parity & 1; +} + +static int secp256k1_frost_tweak_cache_load(const secp256k1_context* ctx, secp256k1_frost_tweak_cache_internal *cache_i, const secp256k1_frost_tweak_cache *cache) { + const unsigned char *ptr = cache->data; + + ARG_CHECK(secp256k1_memcmp_var(ptr, secp256k1_frost_tweak_cache_magic, 4) == 0); + ptr += 4; + secp256k1_ge_from_bytes(&cache_i->thresh_pk, ptr); + ptr += 64; + secp256k1_ge_from_bytes(&cache_i->pk, ptr); + ptr += 64; + secp256k1_scalar_set_b32(&cache_i->tacc, ptr, NULL); + ptr += 32; + cache_i->gacc_parity = *ptr & 1; + return 1; +} + +/* Returns 1 if the ids array contains no duplicates and no id equals + * UINT32_MAX (whose x-coordinate id + 1 would overflow), 0 otherwise. */ +static int secp256k1_frost_ids_are_valid(const uint32_t *ids, size_t n_ids) { + size_t i, j; + + for (i = 0; i < n_ids; i++) { + if (ids[i] == UINT32_MAX) { + return 0; + } + for (j = i + 1; j < n_ids; j++) { + if (ids[i] == ids[j]) { + return 0; + } + } + } + return 1; +} + +static int secp256k1_frost_derive_interpolating_value(secp256k1_scalar *out, const uint32_t *ids, size_t n_ids, uint32_t my_id) { + secp256k1_scalar num, deno; + size_t i; + int found = 0; + + if (!secp256k1_frost_ids_are_valid(ids, n_ids)) { + return 0; + } + for (i = 0; i < n_ids; i++) { + if (ids[i] == my_id) { + found = 1; + break; + } + } + if (!found) { + return 0; + } + + /* lambda = product_{j != i} x_j / (x_j - x_i), where the x-coordinate of + * an identifier id is id + 1. */ + secp256k1_scalar_set_int(&num, 1); + secp256k1_scalar_set_int(&deno, 1); + for (i = 0; i < n_ids; i++) { + secp256k1_scalar x_j, term; + if (ids[i] == my_id) { + continue; + } + secp256k1_scalar_set_int(&x_j, ids[i] + 1); + secp256k1_scalar_mul(&num, &num, &x_j); + /* x_j - x_i = (id_j + 1) - (my_id + 1) = id_j - my_id */ + secp256k1_scalar_set_int(&term, my_id + 1); + secp256k1_scalar_negate(&term, &term); + secp256k1_scalar_add(&term, &term, &x_j); + secp256k1_scalar_mul(&deno, &deno, &term); + } + /* deno != 0 because the ids are distinct */ + VERIFY_CHECK(!secp256k1_scalar_is_zero(&deno)); + secp256k1_scalar_inverse_var(&deno, &deno); + secp256k1_scalar_mul(out, &num, &deno); + return 1; +} + +static int secp256k1_frost_derive_pubshare_at(secp256k1_gej *out, const uint32_t *ids, const secp256k1_ge *pubshares, size_t n_ids, const secp256k1_scalar *x) { + size_t i, j; + + if (!secp256k1_frost_ids_are_valid(ids, n_ids)) { + return 0; + } + + /* out = sum_i lambda_i * pubshares[i] with + * lambda_i = product_{j != i} (x - id_j) / (id_i - id_j). */ + secp256k1_gej_set_infinity(out); + for (i = 0; i < n_ids; i++) { + secp256k1_scalar num, deno, lambda, id_i; + secp256k1_gej term; + + secp256k1_scalar_set_int(&id_i, ids[i]); + secp256k1_scalar_set_int(&num, 1); + secp256k1_scalar_set_int(&deno, 1); + for (j = 0; j < n_ids; j++) { + secp256k1_scalar id_j; + if (j == i) { + continue; + } + secp256k1_scalar_set_int(&id_j, ids[j]); + /* num *= x - id_j */ + secp256k1_scalar_negate(&id_j, &id_j); + secp256k1_scalar_add(&id_j, &id_j, x); + secp256k1_scalar_mul(&num, &num, &id_j); + /* deno *= id_i - id_j */ + secp256k1_scalar_set_int(&id_j, ids[j]); + secp256k1_scalar_negate(&id_j, &id_j); + secp256k1_scalar_add(&id_j, &id_j, &id_i); + secp256k1_scalar_mul(&deno, &deno, &id_j); + } + /* deno != 0 because the ids are distinct */ + VERIFY_CHECK(!secp256k1_scalar_is_zero(&deno)); + secp256k1_scalar_inverse_var(&deno, &deno); + secp256k1_scalar_mul(&lambda, &num, &deno); + + VERIFY_CHECK(!secp256k1_ge_is_infinity(&pubshares[i])); + secp256k1_gej_set_ge(&term, &pubshares[i]); + secp256k1_ecmult(&term, &term, &lambda, NULL); + secp256k1_gej_add_var(out, out, &term, NULL); + } + /* The result may be the point at infinity; the caller must handle it. */ + return 1; +} + +static int secp256k1_frost_derive_thresh_pubkey(secp256k1_gej *out, const uint32_t *ids, const secp256k1_ge *pubshares, size_t n_ids) { + /* Evaluating in identifier space at identifier -1 corresponds to + * evaluating the polynomial at x-coordinate 0. */ + secp256k1_scalar minus_one; + + secp256k1_scalar_set_int(&minus_one, 1); + secp256k1_scalar_negate(&minus_one, &minus_one); + if (!secp256k1_frost_derive_pubshare_at(out, ids, pubshares, n_ids, &minus_one)) { + return 0; + } + /* The threshold public key must not be the point at infinity. */ + return !secp256k1_gej_is_infinity(out); +} + +int secp256k1_frost_trusted_dealer_keygen(const secp256k1_context *ctx, unsigned char *secshares32, secp256k1_pubkey *thresh_pk, secp256k1_pubkey *pubshares, size_t n_participants, uint32_t threshold, const unsigned char *threshold_seckey32) { + /* At most SECP256K1_FROST_MAX_PARTICIPANTS - 1 coefficients */ + secp256k1_scalar coeffs[SECP256K1_FROST_MAX_PARTICIPANTS - 1]; + secp256k1_scalar secret, share, x; + secp256k1_gej pkj; + secp256k1_ge pk; + size_t i, j; + int overflow; + int ret = 0; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secshares32 != NULL); + ARG_CHECK(thresh_pk != NULL); + ARG_CHECK(pubshares != NULL); + ARG_CHECK(threshold_seckey32 != NULL); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + + if (n_participants < 1 || n_participants > SECP256K1_FROST_MAX_PARTICIPANTS) { + return 0; + } + if (threshold < 1 || (size_t)threshold > n_participants) { + return 0; + } + /* Ensure that the outputs are unusable if this function fails. */ + memset(secshares32, 0, n_participants * 32); + memset(thresh_pk, 0, sizeof(*thresh_pk)); + memset(pubshares, 0, n_participants * sizeof(*pubshares)); + + secp256k1_scalar_set_b32(&secret, threshold_seckey32, &overflow); + overflow |= secp256k1_scalar_is_zero(&secret); + /* We can declassify because branching on overflow only leaks whether the + * threshold secret key is valid, which is not secret. */ + secp256k1_declassify(ctx, &overflow, sizeof(overflow)); + if (overflow) { + goto cleanup; + } + + /* The coefficients a_1, ..., a_{t-1} (a_1 is the highest-degree term) are + * derived deterministically from the threshold secret key. */ + for (i = 0; i + 1 < threshold; i++) { + /* A failure can only occur with negligible probability, so its + * occurrence is not secret. */ + int coeff_ok = secp256k1_frost_derive_coefficient(secp256k1_get_hash_context(ctx), &coeffs[i], threshold_seckey32, (uint32_t)(i + 1)); + secp256k1_declassify(ctx, &coeff_ok, sizeof(coeff_ok)); + if (!coeff_ok) { + goto cleanup; + } + } + + /* The secret share of participant id i is p(i + 1), where the polynomial + * p(x) = a_1*x^(t-1) + ... + a_{t-1}*x + secret is evaluated with Horner's + * method. */ + for (i = 0; i < n_participants; i++) { + secp256k1_scalar_set_int(&x, (unsigned int)(i + 1)); + secp256k1_scalar_set_int(&share, 0); + for (j = 0; j + 1 < threshold; j++) { + secp256k1_scalar_mul(&share, &share, &x); + secp256k1_scalar_add(&share, &share, &coeffs[j]); + } + secp256k1_scalar_mul(&share, &share, &x); + secp256k1_scalar_add(&share, &share, &secret); + /* A zero share can only occur with negligible probability, so its + * occurrence is not secret. */ + { + int share_is_zero = secp256k1_scalar_is_zero(&share); + secp256k1_declassify(ctx, &share_is_zero, sizeof(share_is_zero)); + if (share_is_zero) { + goto cleanup; + } + } + secp256k1_scalar_get_b32(&secshares32[32 * i], &share); + + secp256k1_ecmult_gen_gej(&ctx->ecmult_gen_ctx, &pkj, &share); + secp256k1_ge_set_gej(&pk, &pkj); + secp256k1_pubkey_save(&pubshares[i], &pk); + } + + /* The threshold public key is the plain (parity-preserving) encoding of + * threshold_seckey32*G. */ + secp256k1_ecmult_gen_gej(&ctx->ecmult_gen_ctx, &pkj, &secret); + secp256k1_ge_set_gej(&pk, &pkj); + secp256k1_pubkey_save(thresh_pk, &pk); + ret = 1; + +cleanup: + secp256k1_scalar_clear(&secret); + secp256k1_scalar_clear(&share); + secp256k1_scalar_clear(&x); + for (i = 0; i + 1 < threshold; i++) { + secp256k1_scalar_clear(&coeffs[i]); + } + secp256k1_ge_clear(&pk); + secp256k1_gej_clear(&pkj); + return ret; +} + +int secp256k1_frost_threshold_info_validate(const secp256k1_context *ctx, const secp256k1_pubkey *thresh_pk, const secp256k1_pubkey *pubshares, size_t n_participants, uint32_t threshold) { + secp256k1_ge base_points[SECP256K1_FROST_MAX_PARTICIPANTS]; + uint32_t base_ids[SECP256K1_FROST_MAX_PARTICIPANTS]; + secp256k1_ge pk, expected, derived; + secp256k1_gej result; + size_t i; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(thresh_pk != NULL); + ARG_CHECK(pubshares != NULL); + + if (n_participants < 1 || n_participants > SECP256K1_FROST_MAX_PARTICIPANTS) { + return 0; + } + if (threshold < 1 || (size_t)threshold > n_participants) { + return 0; + } + + /* A corrupted or uninitialized pubkey fails in pubkey_load. */ + if (!secp256k1_pubkey_load(ctx, &pk, thresh_pk)) { + return 0; + } + + /* The base set for polynomial interpolation consists of the first t + * pubshares (identifiers 0, ..., t-1). */ + for (i = 0; i < threshold; i++) { + base_ids[i] = (uint32_t)i; + if (!secp256k1_pubkey_load(ctx, &base_points[i], &pubshares[i])) { + return 0; + } + } + + /* Every remaining pubshare must lie on the same polynomial as the base + * set. */ + for (i = threshold; i < n_participants; i++) { + secp256k1_scalar x; + if (!secp256k1_pubkey_load(ctx, &expected, &pubshares[i])) { + return 0; + } + secp256k1_scalar_set_int(&x, (unsigned int)i); + if (!secp256k1_frost_derive_pubshare_at(&result, base_ids, base_points, threshold, &x)) { + return 0; + } + if (secp256k1_gej_is_infinity(&result)) { + return 0; + } + secp256k1_ge_set_gej_var(&derived, &result); + if (!secp256k1_ge_eq_var(&expected, &derived)) { + return 0; + } + } + + /* The public key derived from the base set must match the provided + * threshold public key. */ + if (!secp256k1_frost_derive_thresh_pubkey(&result, base_ids, base_points, threshold)) { + return 0; + } + secp256k1_ge_set_gej_var(&derived, &result); + return secp256k1_ge_eq_var(&pk, &derived); +} + +int secp256k1_frost_tweak_cache_init(const secp256k1_context *ctx, secp256k1_frost_tweak_cache *cache, const secp256k1_pubkey *thresh_pk) { + secp256k1_frost_tweak_cache_internal cache_i = { 0 }; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(cache != NULL); + memset(cache, 0, sizeof(*cache)); + ARG_CHECK(thresh_pk != NULL); + + if (!secp256k1_pubkey_load(ctx, &cache_i.pk, thresh_pk)) { + return 0; + } + /* Q = thresh_pk (parity is preserved), gacc = 1, tacc = 0. */ + cache_i.thresh_pk = cache_i.pk; + secp256k1_scalar_set_int(&cache_i.tacc, 0); + cache_i.gacc_parity = 0; + secp256k1_frost_tweak_cache_save(cache, &cache_i); + return 1; +} + +int secp256k1_frost_tweaked_pubkey_get(const secp256k1_context *ctx, secp256k1_xonly_pubkey *tweaked_pk, const secp256k1_frost_tweak_cache *cache) { + secp256k1_frost_tweak_cache_internal cache_i; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(tweaked_pk != NULL); + memset(tweaked_pk, 0, sizeof(*tweaked_pk)); + ARG_CHECK(cache != NULL); + + if (!secp256k1_frost_tweak_cache_load(ctx, &cache_i, cache)) { + return 0; + } + /* x-only public keys carry the even-Y representative (required for BIP340 + * verification), so the point is normalized to even Y before saving. */ + secp256k1_extrakeys_ge_even_y(&cache_i.pk); + secp256k1_xonly_pubkey_save(tweaked_pk, &cache_i.pk); + return 1; +} + +/* Implements ApplyTweak of BIP 445: computes Q' = g*Q + tweak*G where g = -1 + * iff xonly is set and Q has odd Y, updates tacc = tweak + g*tacc and + * gacc_parity accordingly, and saves the result to the cache. On failure + * (tweak out of range or Q' is the point at infinity) the cache is left + * unchanged. */ +static int secp256k1_frost_pubkey_tweak_add_internal(const secp256k1_context *ctx, secp256k1_xonly_pubkey *tweaked_pk, secp256k1_frost_tweak_cache *cache, const unsigned char *tweak32, int xonly) { + secp256k1_frost_tweak_cache_internal cache_i; + secp256k1_scalar tweak; + int overflow = 0; + + VERIFY_CHECK(ctx != NULL); + if (tweaked_pk != NULL) { + memset(tweaked_pk, 0, sizeof(*tweaked_pk)); + } + ARG_CHECK(cache != NULL); + ARG_CHECK(tweak32 != NULL); + + if (!secp256k1_frost_tweak_cache_load(ctx, &cache_i, cache)) { + return 0; + } + secp256k1_scalar_set_b32(&tweak, tweak32, &overflow); + if (overflow) { + return 0; + } + /* For xonly tweaking, g = -1 iff the current public key has odd Y. All + * modifications happen in the local cache_i and are only committed on + * success. */ + if (xonly && secp256k1_extrakeys_ge_even_y(&cache_i.pk)) { + cache_i.gacc_parity ^= 1; + secp256k1_scalar_negate(&cache_i.tacc, &cache_i.tacc); + } + secp256k1_scalar_add(&cache_i.tacc, &cache_i.tacc, &tweak); + if (!secp256k1_eckey_pubkey_tweak_add(&cache_i.pk, &tweak)) { + return 0; + } + /* eckey_pubkey_tweak_add fails if the result is the point at infinity */ + VERIFY_CHECK(!secp256k1_ge_is_infinity(&cache_i.pk)); + secp256k1_frost_tweak_cache_save(cache, &cache_i); + if (tweaked_pk != NULL) { + secp256k1_ge pk_even = cache_i.pk; + /* x-only public keys carry the even-Y representative (required for + * BIP340 verification) */ + secp256k1_fe_normalize_var(&pk_even.y); + secp256k1_extrakeys_ge_even_y(&pk_even); + secp256k1_xonly_pubkey_save(tweaked_pk, &pk_even); + } + return 1; +} + +int secp256k1_frost_pubkey_ec_tweak_add(const secp256k1_context *ctx, secp256k1_xonly_pubkey *tweaked_pk, secp256k1_frost_tweak_cache *cache, const unsigned char *tweak32) { + return secp256k1_frost_pubkey_tweak_add_internal(ctx, tweaked_pk, cache, tweak32, 0); +} + +int secp256k1_frost_pubkey_xonly_tweak_add(const secp256k1_context *ctx, secp256k1_xonly_pubkey *tweaked_pk, secp256k1_frost_tweak_cache *cache, const unsigned char *tweak32) { + return secp256k1_frost_pubkey_tweak_add_internal(ctx, tweaked_pk, cache, tweak32, 1); +} + +#endif diff --git a/src/modules/frost/main_impl.h b/src/modules/frost/main_impl.h new file mode 100644 index 00000000..93153503 --- /dev/null +++ b/src/modules/frost/main_impl.h @@ -0,0 +1,12 @@ +/*********************************************************************** + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_FROST_MAIN_H +#define SECP256K1_MODULE_FROST_MAIN_H + +#include "keygen_impl.h" +#include "session_impl.h" + +#endif diff --git a/src/modules/frost/session.h b/src/modules/frost/session.h new file mode 100644 index 00000000..01bb1c4f --- /dev/null +++ b/src/modules/frost/session.h @@ -0,0 +1,65 @@ +/*********************************************************************** + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_FROST_SESSION_H +#define SECP256K1_MODULE_FROST_SESSION_H + +#include "../../../include/secp256k1.h" +#include "../../../include/secp256k1_frost.h" + +#include "../../group.h" +#include "../../scalar.h" + +typedef struct { + /* The x-coordinate of the final nonce R (x-only encoding). */ + unsigned char fin_nonce[32]; + /* The nonce coefficient b. */ + secp256k1_scalar noncecoef; + /* The BIP340 challenge e. */ + secp256k1_scalar challenge; + /* The scalar e*g*tacc added to the aggregate partial signature. */ + secp256k1_scalar s_part; + /* The number of signers u. */ + uint32_t n_signers; + /* 1 if the y-coordinate of the final nonce R is odd, 0 otherwise. */ + int fin_nonce_parity; + /* g_times_gacc_parity corresponds to (1 - g*gacc)/2 in the specification, + * where g is 1 if the (tweaked) threshold public key has even y and -1 + * otherwise. So if g*gacc is -1, g_times_gacc_parity is 1. */ + int g_times_gacc_parity; +} secp256k1_frost_session_internal; + +/* Saves the two secret scalars k[0], k[1] into a secnonce. */ +static void secp256k1_frost_secnonce_save(secp256k1_frost_secnonce *secnonce, const secp256k1_scalar *k); + +/* Loads the two secret scalars from a secnonce. Fails (via ARG_CHECK) if the + * secnonce is uninitialized or has been invalidated (e.g., by sign), which is + * detected by checking the magic and that both scalars are nonzero. */ +static int secp256k1_frost_secnonce_load(const secp256k1_context* ctx, secp256k1_scalar *k, const secp256k1_frost_secnonce *secnonce); + +/* Saves two group elements into a pubnonce. Requires that none of the + * provided group elements is infinity. */ +static void secp256k1_frost_pubnonce_save(secp256k1_frost_pubnonce *nonce, const secp256k1_ge *ges); + +/* Loads two group elements from a pubnonce. */ +static int secp256k1_frost_pubnonce_load(const secp256k1_context* ctx, secp256k1_ge *ges, const secp256k1_frost_pubnonce *nonce); + +/* Saves two group elements into an aggnonce. In contrast to a pubnonce, the + * group elements are allowed to be the point at infinity. */ +static void secp256k1_frost_aggnonce_save(secp256k1_frost_aggnonce *nonce, const secp256k1_ge *ges); + +/* Loads two group elements from an aggnonce. Either element may be the point + * at infinity. */ +static int secp256k1_frost_aggnonce_load(const secp256k1_context* ctx, secp256k1_ge *ges, const secp256k1_frost_aggnonce *nonce); + +static void secp256k1_frost_partial_sig_save(secp256k1_frost_partial_sig *sig, const secp256k1_scalar *s); + +static int secp256k1_frost_partial_sig_load(const secp256k1_context* ctx, secp256k1_scalar *s, const secp256k1_frost_partial_sig *sig); + +static void secp256k1_frost_session_save(secp256k1_frost_session *session, const secp256k1_frost_session_internal *session_i); + +static int secp256k1_frost_session_load(const secp256k1_context* ctx, secp256k1_frost_session_internal *session_i, const secp256k1_frost_session *session); + +#endif diff --git a/src/modules/frost/session_impl.h b/src/modules/frost/session_impl.h new file mode 100644 index 00000000..4d01dc0a --- /dev/null +++ b/src/modules/frost/session_impl.h @@ -0,0 +1,1108 @@ +/*********************************************************************** + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_FROST_SESSION_IMPL_H +#define SECP256K1_MODULE_FROST_SESSION_IMPL_H + +#include + +#include "../../../include/secp256k1.h" +#include "../../../include/secp256k1_frost.h" + +#include "keygen.h" +#include "session.h" +#include "../../eckey.h" +#include "../../ecmult.h" +#include "../../hash.h" +#include "../../util.h" + +/* Initializes SHA256 with the BIP 445 "BIP0445/aux" tag. */ +static void secp256k1_frost_sha256_tagged_aux(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *sha) { + secp256k1_sha256_initialize_tagged(hash_ctx, sha, (const unsigned char *)"BIP0445/aux", sizeof("BIP0445/aux") - 1); +} + +/* Initializes SHA256 with the BIP 445 "BIP0445/nonce" tag. */ +static void secp256k1_frost_sha256_tagged_nonce(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *sha) { + secp256k1_sha256_initialize_tagged(hash_ctx, sha, (const unsigned char *)"BIP0445/nonce", sizeof("BIP0445/nonce") - 1); +} + +/* Initializes SHA256 with the BIP 445 "BIP0445/noncecoef" tag. */ +static void secp256k1_frost_sha256_tagged_noncecoef(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *sha) { + secp256k1_sha256_initialize_tagged(hash_ctx, sha, (const unsigned char *)"BIP0445/noncecoef", sizeof("BIP0445/noncecoef") - 1); +} + +/* Initializes SHA256 with the BIP 445 "BIP0445/deterministic/nonce" tag. */ +static void secp256k1_frost_sha256_tagged_deterministic_nonce(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *sha) { + secp256k1_sha256_initialize_tagged(hash_ctx, sha, (const unsigned char *)"BIP0445/deterministic/nonce", sizeof("BIP0445/deterministic/nonce") - 1); +} + +/* Writes data into the hash, framed with a big-endian length prefix of + * prefix_size bytes, matching the framing of optional and variable-length + * inputs in the BIP 445 nonce_hash and det_nonce_hash algorithms. If data is + * NULL, only the (zero) length prefix is written. */ +static void secp256k1_frost_sha256_write_prefixed(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *sha, unsigned int prefix_size, const unsigned char *data, size_t data_len) { + unsigned char prefix[8]; + size_t len = data_len; + unsigned int i; + + /* The spec requires length prefixes to be between 1 and 8 bytes + * (inclusive) */ + VERIFY_CHECK(prefix_size >= 1 && prefix_size <= 8); + VERIFY_CHECK(data != NULL || data_len == 0); + for (i = prefix_size; i-- > 0; ) { + prefix[i] = len & 0xFF; + len >>= 8; + } + /* The length must fit into the prefix */ + VERIFY_CHECK(len == 0); + secp256k1_sha256_write(hash_ctx, sha, prefix, prefix_size); + if (data != NULL) { + secp256k1_sha256_write(hash_ctx, sha, data, data_len); + } +} + +static const unsigned char secp256k1_frost_secnonce_magic[4] = { 0x5c, 0xcf, 0xb9, 0x99 }; + +static void secp256k1_frost_secnonce_save(secp256k1_frost_secnonce *secnonce, const secp256k1_scalar *k) { + memcpy(&secnonce->data[0], secp256k1_frost_secnonce_magic, 4); + secp256k1_scalar_get_b32(&secnonce->data[4], &k[0]); + secp256k1_scalar_get_b32(&secnonce->data[36], &k[1]); +} + +static int secp256k1_frost_secnonce_load(const secp256k1_context* ctx, secp256k1_scalar *k, const secp256k1_frost_secnonce *secnonce) { + int is_zero0, is_zero1; + ARG_CHECK(secp256k1_memcmp_var(&secnonce->data[0], secp256k1_frost_secnonce_magic, 4) == 0); + /* We make very sure that the nonce isn't invalidated by checking the + * values in addition to the magic. Both halves must be nonzero, matching + * the secnonce validation of the BIP 445 Sign algorithm ("first/second + * secnonce value is out of range"). */ + is_zero0 = secp256k1_is_zero_array(&secnonce->data[4], 32); + is_zero1 = secp256k1_is_zero_array(&secnonce->data[36], 32); + secp256k1_declassify(ctx, &is_zero0, sizeof(is_zero0)); + secp256k1_declassify(ctx, &is_zero1, sizeof(is_zero1)); + ARG_CHECK(!is_zero0); + ARG_CHECK(!is_zero1); + + secp256k1_scalar_set_b32(&k[0], &secnonce->data[4], NULL); + secp256k1_scalar_set_b32(&k[1], &secnonce->data[36], NULL); + return 1; +} + +static const unsigned char secp256k1_frost_pubnonce_magic[4] = { 0x70, 0xd5, 0x1c, 0xff }; + +/* Saves two group elements into a pubnonce. Requires that none of the + * provided group elements is infinity. */ +static void secp256k1_frost_pubnonce_save(secp256k1_frost_pubnonce *nonce, const secp256k1_ge *ges) { + int i; + memcpy(&nonce->data[0], secp256k1_frost_pubnonce_magic, 4); + for (i = 0; i < 2; i++) { + VERIFY_CHECK(!secp256k1_ge_is_infinity(&ges[i])); + secp256k1_ge_to_bytes(&nonce->data[4 + 64*i], &ges[i]); + } +} + +/* Loads two group elements from a pubnonce. Returns 1 unless the nonce wasn't + * properly initialized */ +static int secp256k1_frost_pubnonce_load(const secp256k1_context* ctx, secp256k1_ge *ges, const secp256k1_frost_pubnonce *nonce) { + int i; + + ARG_CHECK(secp256k1_memcmp_var(&nonce->data[0], secp256k1_frost_pubnonce_magic, 4) == 0); + for (i = 0; i < 2; i++) { + secp256k1_ge_from_bytes(&ges[i], &nonce->data[4 + 64*i]); + } + return 1; +} + +static const unsigned char secp256k1_frost_aggnonce_magic[4] = { 0xcd, 0x45, 0x0f, 0x4a }; + +/* Saves two group elements into an aggnonce. In contrast to a pubnonce, the + * group elements are allowed to be the point at infinity. */ +static void secp256k1_frost_aggnonce_save(secp256k1_frost_aggnonce *nonce, const secp256k1_ge *ges) { + int i; + memcpy(&nonce->data[0], secp256k1_frost_aggnonce_magic, 4); + for (i = 0; i < 2; i++) { + secp256k1_ge_to_bytes_ext(&nonce->data[4 + 64*i], &ges[i]); + } +} + +static int secp256k1_frost_aggnonce_load(const secp256k1_context* ctx, secp256k1_ge *ges, const secp256k1_frost_aggnonce *nonce) { + int i; + + ARG_CHECK(secp256k1_memcmp_var(&nonce->data[0], secp256k1_frost_aggnonce_magic, 4) == 0); + for (i = 0; i < 2; i++) { + secp256k1_ge_from_bytes_ext(&ges[i], &nonce->data[4 + 64*i]); + } + return 1; +} + +static const unsigned char secp256k1_frost_session_magic[4] = { 0x34, 0xb5, 0x27, 0x3d }; + +/* A session consists of + * - 4 byte session magic + * - 32 byte x-only encoding of the final nonce R + * - 32 byte nonce coefficient b + * - 32 byte signature challenge hash e + * - 32 byte scalar s_part = e*g*tacc that is added to the aggregate partial + * signature + * - 4 byte number of signers u (big-endian) + * - 1 byte with the parity of the final nonce in bit 0 and the parity of + * g*gacc in bit 1 + */ +static void secp256k1_frost_session_save(secp256k1_frost_session *session, const secp256k1_frost_session_internal *session_i) { + unsigned char *ptr = session->data; + + memcpy(ptr, secp256k1_frost_session_magic, 4); + ptr += 4; + memcpy(ptr, session_i->fin_nonce, 32); + ptr += 32; + secp256k1_scalar_get_b32(ptr, &session_i->noncecoef); + ptr += 32; + secp256k1_scalar_get_b32(ptr, &session_i->challenge); + ptr += 32; + secp256k1_scalar_get_b32(ptr, &session_i->s_part); + ptr += 32; + secp256k1_write_be32(ptr, session_i->n_signers); + ptr += 4; + *ptr = (session_i->fin_nonce_parity & 1) | ((session_i->g_times_gacc_parity & 1) << 1); +} + +static int secp256k1_frost_session_load(const secp256k1_context* ctx, secp256k1_frost_session_internal *session_i, const secp256k1_frost_session *session) { + const unsigned char *ptr = session->data; + + ARG_CHECK(secp256k1_memcmp_var(ptr, secp256k1_frost_session_magic, 4) == 0); + ptr += 4; + memcpy(session_i->fin_nonce, ptr, 32); + ptr += 32; + secp256k1_scalar_set_b32(&session_i->noncecoef, ptr, NULL); + ptr += 32; + secp256k1_scalar_set_b32(&session_i->challenge, ptr, NULL); + ptr += 32; + secp256k1_scalar_set_b32(&session_i->s_part, ptr, NULL); + ptr += 32; + session_i->n_signers = secp256k1_read_be32(ptr); + ptr += 4; + session_i->fin_nonce_parity = *ptr & 1; + session_i->g_times_gacc_parity = (*ptr >> 1) & 1; + return 1; +} + +static const unsigned char secp256k1_frost_partial_sig_magic[4] = { 0x58, 0x0a, 0x17, 0x4e }; + +static void secp256k1_frost_partial_sig_save(secp256k1_frost_partial_sig *sig, const secp256k1_scalar *s) { + memcpy(&sig->data[0], secp256k1_frost_partial_sig_magic, 4); + secp256k1_scalar_get_b32(&sig->data[4], s); +} + +static int secp256k1_frost_partial_sig_load(const secp256k1_context* ctx, secp256k1_scalar *s, const secp256k1_frost_partial_sig *sig) { + int overflow; + + ARG_CHECK(secp256k1_memcmp_var(&sig->data[0], secp256k1_frost_partial_sig_magic, 4) == 0); + secp256k1_scalar_set_b32(s, &sig->data[4], &overflow); + /* Parsed signatures can not overflow */ + VERIFY_CHECK(!overflow); + return 1; +} + +int secp256k1_frost_pubnonce_parse(const secp256k1_context* ctx, secp256k1_frost_pubnonce *nonce, const unsigned char *in66) { + secp256k1_ge ges[2]; + int i; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(nonce != NULL); + memset(nonce, 0, sizeof(*nonce)); + ARG_CHECK(in66 != NULL); + + for (i = 0; i < 2; i++) { + /* A 33-byte compressed encoding can never be the point at infinity */ + if (!secp256k1_eckey_pubkey_parse(&ges[i], &in66[33*i], 33)) { + return 0; + } + if (!secp256k1_ge_is_in_correct_subgroup(&ges[i])) { + return 0; + } + } + secp256k1_frost_pubnonce_save(nonce, ges); + return 1; +} + +int secp256k1_frost_pubnonce_serialize(const secp256k1_context* ctx, unsigned char *out66, const secp256k1_frost_pubnonce *nonce) { + secp256k1_ge ges[2]; + int i; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(out66 != NULL); + memset(out66, 0, 66); + ARG_CHECK(nonce != NULL); + + if (!secp256k1_frost_pubnonce_load(ctx, ges, nonce)) { + return 0; + } + for (i = 0; i < 2; i++) { + /* serialize must succeed because the point was just loaded and is not + * the point at infinity */ + secp256k1_eckey_pubkey_serialize33(&ges[i], &out66[33*i]); + } + return 1; +} + +int secp256k1_frost_aggnonce_parse(const secp256k1_context* ctx, secp256k1_frost_aggnonce *nonce, const unsigned char *in66) { + secp256k1_ge ges[2]; + int i; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(nonce != NULL); + memset(nonce, 0, sizeof(*nonce)); + ARG_CHECK(in66 != NULL); + + for (i = 0; i < 2; i++) { + /* 33 zero bytes encode the point at infinity (BIP 445 cbytes_ext) */ + if (!secp256k1_ge_parse_ext(&ges[i], &in66[33*i])) { + return 0; + } + if (!secp256k1_ge_is_infinity(&ges[i]) + && !secp256k1_ge_is_in_correct_subgroup(&ges[i])) { + return 0; + } + } + secp256k1_frost_aggnonce_save(nonce, ges); + return 1; +} + +int secp256k1_frost_aggnonce_serialize(const secp256k1_context* ctx, unsigned char *out66, const secp256k1_frost_aggnonce *nonce) { + secp256k1_ge ges[2]; + int i; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(out66 != NULL); + memset(out66, 0, 66); + ARG_CHECK(nonce != NULL); + + if (!secp256k1_frost_aggnonce_load(ctx, ges, nonce)) { + return 0; + } + for (i = 0; i < 2; i++) { + /* A point at infinity is encoded as 33 zero bytes (BIP 445 + * cbytes_ext) */ + secp256k1_ge_serialize_ext(&out66[33*i], &ges[i]); + } + return 1; +} + +int secp256k1_frost_partial_sig_parse(const secp256k1_context* ctx, secp256k1_frost_partial_sig *sig, const unsigned char *in32) { + secp256k1_scalar tmp; + int overflow; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(sig != NULL); + ARG_CHECK(in32 != NULL); + + /* Ensure that using the signature will fail if parsing fails (and the + * user doesn't check the return value). */ + memset(sig, 0, sizeof(*sig)); + + secp256k1_scalar_set_b32(&tmp, in32, &overflow); + if (overflow) { + return 0; + } + secp256k1_frost_partial_sig_save(sig, &tmp); + return 1; +} + +int secp256k1_frost_partial_sig_serialize(const secp256k1_context* ctx, unsigned char *out32, const secp256k1_frost_partial_sig *sig) { + secp256k1_scalar s; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(out32 != NULL); + ARG_CHECK(sig != NULL); + + if (!secp256k1_frost_partial_sig_load(ctx, &s, sig)) { + return 0; + } + secp256k1_scalar_get_b32(out32, &s); + return 1; +} + +/* Nonce derivation function of NonceGen (BIP 445). Computes the secret nonces + * k[0], k[1] from the session randomness and the optional inputs. All secret + * intermediates (the masked randomness, the hash states, the hash output) are + * cleansed before this function returns. */ +static void secp256k1_frost_nonce_function(const secp256k1_hash_ctx *hash_ctx, secp256k1_scalar *k, const unsigned char *session_secrand, const unsigned char *secshare32, const unsigned char *pubshare33, const unsigned char *thresh_pk32, const unsigned char *msg, size_t msglen, const unsigned char *extra_in, size_t extra_in_len) { + secp256k1_sha256 sha; + unsigned char rand[32]; + unsigned char i; + unsigned char msg_present; + + if (secshare32 != NULL) { + secp256k1_frost_sha256_tagged_aux(hash_ctx, &sha); + secp256k1_sha256_write(hash_ctx, &sha, session_secrand, 32); + secp256k1_sha256_finalize(hash_ctx, &sha, rand); + for (i = 0; i < 32; i++) { + rand[i] ^= secshare32[i]; + } + } else { + memcpy(rand, session_secrand, sizeof(rand)); + } + + secp256k1_frost_sha256_tagged_nonce(hash_ctx, &sha); + secp256k1_sha256_write(hash_ctx, &sha, rand, sizeof(rand)); + secp256k1_frost_sha256_write_prefixed(hash_ctx, &sha, 1, pubshare33, pubshare33 != NULL ? 33 : 0); + secp256k1_frost_sha256_write_prefixed(hash_ctx, &sha, 1, thresh_pk32, thresh_pk32 != NULL ? 32 : 0); + msg_present = msg != NULL; + secp256k1_sha256_write(hash_ctx, &sha, &msg_present, 1); + if (msg_present) { + secp256k1_frost_sha256_write_prefixed(hash_ctx, &sha, 8, msg, msglen); + } + secp256k1_frost_sha256_write_prefixed(hash_ctx, &sha, 4, extra_in, extra_in_len); + + for (i = 0; i < 2; i++) { + unsigned char buf[32]; + secp256k1_sha256 sha_tmp = sha; + secp256k1_sha256_write(hash_ctx, &sha_tmp, &i, 1); + secp256k1_sha256_finalize(hash_ctx, &sha_tmp, buf); + secp256k1_scalar_set_b32(&k[i], buf, NULL); + + /* Attempt to erase secret data */ + secp256k1_memclear_explicit(buf, sizeof(buf)); + secp256k1_sha256_clear(&sha_tmp); + } + secp256k1_memclear_explicit(rand, sizeof(rand)); + secp256k1_sha256_clear(&sha); +} + +int secp256k1_frost_nonce_gen(const secp256k1_context* ctx, secp256k1_frost_secnonce *secnonce, secp256k1_frost_pubnonce *pubnonce, unsigned char *session_secrand32, const unsigned char *secshare32, const secp256k1_pubkey *pubshare, const unsigned char *thresh_pk32, const unsigned char *msg, size_t msglen, const unsigned char *extra_in, size_t extra_in_len) { + secp256k1_scalar k[2]; + secp256k1_ge nonce_pts[2]; + secp256k1_gej nonce_ptj[2]; + unsigned char pubshare33[33]; + unsigned char *pubshare33_ptr = NULL; + int i; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secnonce != NULL); + memset(secnonce, 0, sizeof(*secnonce)); + ARG_CHECK(pubnonce != NULL); + memset(pubnonce, 0, sizeof(*pubnonce)); + ARG_CHECK(session_secrand32 != NULL); + ARG_CHECK(msg != NULL || msglen == 0); + ARG_CHECK(extra_in != NULL || extra_in_len == 0); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + + /* Check that the secshare is valid to be able to sign with it later. */ + if (secshare32 != NULL) { + secp256k1_scalar secshare; + int valid = secp256k1_scalar_set_b32_seckey(&secshare, secshare32); + secp256k1_scalar_clear(&secshare); + /* We can declassify because branching on valid only leaks whether the + * provided secret share is a valid secret key, which is not + * secret. */ + secp256k1_declassify(ctx, &valid, sizeof(valid)); + if (!valid) { + secp256k1_memzero_explicit(session_secrand32, 32); + return 0; + } + } + if (pubshare != NULL) { + secp256k1_ge pubshare_ge; + if (!secp256k1_pubkey_load(ctx, &pubshare_ge, pubshare)) { + secp256k1_memzero_explicit(session_secrand32, 32); + return 0; + } + secp256k1_eckey_pubkey_serialize33(&pubshare_ge, pubshare33); + pubshare33_ptr = pubshare33; + } + + secp256k1_frost_nonce_function(secp256k1_get_hash_context(ctx), k, session_secrand32, secshare32, pubshare33_ptr, thresh_pk32, msg, msglen, extra_in, extra_in_len); + { + /* k_i == 0 has negligible probability, so its occurrence is not + * secret. Fail cleanly instead of asserting like the reference + * implementation. */ + int k_zero = secp256k1_scalar_is_zero(&k[0]) | secp256k1_scalar_is_zero(&k[1]); + secp256k1_declassify(ctx, &k_zero, sizeof(k_zero)); + if (k_zero) { + secp256k1_scalar_clear(&k[0]); + secp256k1_scalar_clear(&k[1]); + secp256k1_memzero_explicit(session_secrand32, 32); + return 0; + } + } + + secp256k1_frost_secnonce_save(secnonce, k); + + /* Compute pubnonce as two gejs */ + for (i = 0; i < 2; i++) { + secp256k1_ecmult_gen_gej(&ctx->ecmult_gen_ctx, &nonce_ptj[i], &k[i]); + secp256k1_scalar_clear(&k[i]); + } + + /* Batch convert to two public ges */ + secp256k1_ge_set_all_gej(nonce_pts, nonce_ptj, 2); + for (i = 0; i < 2; i++) { + secp256k1_gej_clear(&nonce_ptj[i]); + secp256k1_declassify(ctx, &nonce_pts[i], sizeof(nonce_pts[i])); + } + + /* None of the nonce_pts will be infinity because k != 0 */ + secp256k1_frost_pubnonce_save(pubnonce, nonce_pts); + + /* Wipe the session_secrand32 buffer to prevent the caller from using + * nonce_gen multiple times with the same buffer. */ + secp256k1_memzero_explicit(session_secrand32, 32); + return 1; +} + +int secp256k1_frost_nonce_agg(const secp256k1_context* ctx, secp256k1_frost_aggnonce *aggnonce, size_t *error_index, const secp256k1_frost_pubnonce *const *pubnonces, size_t n_pubnonces) { + secp256k1_gej aggnonce_ptsj[2]; + secp256k1_ge aggnonce_pts[2]; + size_t i; + int j; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(aggnonce != NULL); + memset(aggnonce, 0, sizeof(*aggnonce)); + ARG_CHECK(pubnonces != NULL); + ARG_CHECK(n_pubnonces > 0); + + secp256k1_gej_set_infinity(&aggnonce_ptsj[0]); + secp256k1_gej_set_infinity(&aggnonce_ptsj[1]); + + for (i = 0; i < n_pubnonces; i++) { + secp256k1_ge nonce_pts[2]; + /* A NULL array element indicates a missing contribution. This is the + * identifiable-abort path, not an API usage error. */ + if (pubnonces[i] == NULL) { + if (error_index != NULL) { + *error_index = i; + } + return 0; + } + if (!secp256k1_frost_pubnonce_load(ctx, nonce_pts, pubnonces[i])) { + if (error_index != NULL) { + *error_index = i; + } + return 0; + } + for (j = 0; j < 2; j++) { + secp256k1_gej_add_ge_var(&aggnonce_ptsj[j], &aggnonce_ptsj[j], &nonce_pts[j], NULL); + } + } + /* The column sums may be the point at infinity; this is not an error (BIP + * 445 NonceAgg). */ + secp256k1_ge_set_all_gej_var(aggnonce_pts, aggnonce_ptsj, 2); + secp256k1_frost_aggnonce_save(aggnonce, aggnonce_pts); + return 1; +} + +/* Copies ids into out and sorts them in ascending order (insertion sort). + * Requires n_ids <= SECP256K1_FROST_MAX_PARTICIPANTS. The signers are a set; + * sorting keeps the nonce coefficient independent of the order of ids (BIP 445 + * serialize_ids). */ +static void secp256k1_frost_sort_ids(uint32_t *out, const uint32_t *ids, size_t n_ids) { + size_t i; + + VERIFY_CHECK(n_ids <= SECP256K1_FROST_MAX_PARTICIPANTS); + memcpy(out, ids, n_ids * sizeof(*out)); + for (i = 1; i < n_ids; i++) { + uint32_t v = out[i]; + size_t j = i; + while (j > 0 && out[j - 1] > v) { + out[j] = out[j - 1]; + j--; + } + out[j] = v; + } +} + +/* Implements the validate_session_params algorithm of BIP 445: checks the + * threshold parameters, the range and uniqueness of the signer ids and, if + * pubshares is non-NULL, that all pubshares parse and that the threshold + * public key derived from them equals the untweaked threshold public key of + * the tweak cache. Returns 1 if the parameters are valid, 0 otherwise. */ +static int secp256k1_frost_validate_session_params(const secp256k1_context *ctx, const uint32_t *ids, const secp256k1_pubkey *pubshares, size_t n_signers, size_t n_participants, uint32_t threshold, const secp256k1_frost_tweak_cache_internal *cache_i) { + size_t i; + + if (threshold < 1 || (size_t)threshold > n_participants) { + return 0; + } + if (n_participants > SECP256K1_FROST_MAX_PARTICIPANTS) { + return 0; + } + if (n_signers < (size_t)threshold || n_signers > n_participants) { + return 0; + } + for (i = 0; i < n_signers; i++) { + if ((size_t)ids[i] >= n_participants) { + return 0; + } + } + /* Rejects duplicate ids (and UINT32_MAX, already covered above). */ + if (!secp256k1_frost_ids_are_valid(ids, n_signers)) { + return 0; + } + if (pubshares != NULL) { + secp256k1_ge pubshares_ge[SECP256K1_FROST_MAX_PARTICIPANTS]; + secp256k1_gej derived; + secp256k1_ge derived_ge; + + for (i = 0; i < n_signers; i++) { + if (!secp256k1_pubkey_load(ctx, &pubshares_ge[i], &pubshares[i])) { + return 0; + } + } + /* derive_thresh_pubkey fails if the result is the point at infinity */ + if (!secp256k1_frost_derive_thresh_pubkey(&derived, ids, pubshares_ge, n_signers)) { + return 0; + } + secp256k1_ge_set_gej_var(&derived_ge, &derived); + /* The derived threshold public key must match the untweaked threshold + * public key (Q_0) stored in the tweak cache. */ + if (!secp256k1_ge_eq_var(&derived_ge, &cache_i->thresh_pk)) { + return 0; + } + } + return 1; +} + +/* Implements the GetSessionValues algorithm of BIP 445 (given already + * validated session parameters): computes the nonce coefficient b, the final + * nonce R, the BIP340 challenge e and s_part = e*g*tacc, where g = -1 iff the + * (tweaked) threshold public key has odd Y. aggnonce_pts holds the two + * aggregate nonce components, each of which may be the point at infinity. + * Returns 0 in the (negligible probability) case that b == 0 or e == 0, 1 + * otherwise. */ +static int secp256k1_frost_get_session_values(const secp256k1_context *ctx, secp256k1_frost_session_internal *session_i, secp256k1_ge *aggnonce_pts, const uint32_t *ids, size_t n_signers, const secp256k1_frost_tweak_cache_internal *cache_i, const unsigned char *msg, size_t msglen) { + const secp256k1_hash_ctx *hash_ctx = secp256k1_get_hash_context(ctx); + secp256k1_sha256 sha; + uint32_t sorted_ids[SECP256K1_FROST_MAX_PARTICIPANTS]; + unsigned char buf[4]; + unsigned char aggnonce66[66]; + unsigned char pk32[32]; + unsigned char hash32[32]; + secp256k1_gej rj; + secp256k1_ge r; + size_t i; + int pk_odd; + + VERIFY_CHECK(n_signers <= SECP256K1_FROST_MAX_PARTICIPANTS); + + /* b = tagged_hash("BIP0445/noncecoef", ser32(u) || sorted ser32 ids || + * aggnonce || xbytes(Q) || msg) */ + secp256k1_frost_sha256_tagged_noncecoef(hash_ctx, &sha); + secp256k1_write_be32(buf, (uint32_t)n_signers); + secp256k1_sha256_write(hash_ctx, &sha, buf, sizeof(buf)); + secp256k1_frost_sort_ids(sorted_ids, ids, n_signers); + for (i = 0; i < n_signers; i++) { + secp256k1_write_be32(buf, sorted_ids[i]); + secp256k1_sha256_write(hash_ctx, &sha, buf, sizeof(buf)); + } + /* An aggregate nonce component at infinity is encoded as 33 zero bytes + * (BIP 445 cbytes_ext) */ + secp256k1_ge_serialize_ext(&aggnonce66[0], &aggnonce_pts[0]); + secp256k1_ge_serialize_ext(&aggnonce66[33], &aggnonce_pts[1]); + secp256k1_sha256_write(hash_ctx, &sha, aggnonce66, sizeof(aggnonce66)); + /* The tweaked threshold public key Q is never the point at infinity and + * its x-coordinate is normalized (loaded from storage). */ + secp256k1_fe_get_b32(pk32, &cache_i->pk.x); + secp256k1_sha256_write(hash_ctx, &sha, pk32, sizeof(pk32)); + secp256k1_sha256_write(hash_ctx, &sha, msg, msglen); + secp256k1_sha256_finalize(hash_ctx, &sha, hash32); + secp256k1_scalar_set_b32(&session_i->noncecoef, hash32, NULL); + secp256k1_memclear_explicit(hash32, sizeof(hash32)); + if (secp256k1_scalar_is_zero(&session_i->noncecoef)) { + /* b == 0 can only occur with negligible probability */ + return 0; + } + + /* R = R1 + b*R2; R = G if R is the point at infinity */ + if (secp256k1_ge_is_infinity(&aggnonce_pts[1])) { + secp256k1_gej_set_infinity(&rj); + } else { + secp256k1_gej_set_ge(&rj, &aggnonce_pts[1]); + secp256k1_ecmult(&rj, &rj, &session_i->noncecoef, NULL); + } + secp256k1_gej_add_ge_var(&rj, &rj, &aggnonce_pts[0], NULL); + secp256k1_ge_set_gej_var(&r, &rj); + if (secp256k1_ge_is_infinity(&r)) { + r = secp256k1_ge_const_g; + } + secp256k1_fe_normalize_var(&r.x); + secp256k1_fe_get_b32(session_i->fin_nonce, &r.x); + secp256k1_fe_normalize_var(&r.y); + session_i->fin_nonce_parity = secp256k1_fe_is_odd(&r.y); + + /* e = tagged_hash("BIP0340/challenge", xbytes(R) || xbytes(Q) || msg) */ + secp256k1_schnorrsig_challenge(hash_ctx, &session_i->challenge, session_i->fin_nonce, msg, msglen, pk32); + if (secp256k1_scalar_is_zero(&session_i->challenge)) { + /* e == 0 can only occur with negligible probability */ + return 0; + } + + /* s_part = e*g*tacc, where g = -1 iff Q has odd Y */ + pk_odd = secp256k1_fe_is_odd(&cache_i->pk.y); + secp256k1_scalar_mul(&session_i->s_part, &session_i->challenge, &cache_i->tacc); + if (pk_odd) { + secp256k1_scalar_negate(&session_i->s_part, &session_i->s_part); + } + /* The signers need g*gacc, where gacc is the tweak factor accumulator. */ + session_i->g_times_gacc_parity = cache_i->gacc_parity ^ pk_odd; + session_i->n_signers = (uint32_t)n_signers; + return 1; +} + +int secp256k1_frost_session_init(const secp256k1_context *ctx, secp256k1_frost_session *session, const secp256k1_frost_aggnonce *aggnonce, const uint32_t *ids, const secp256k1_pubkey *pubshares, size_t n_signers, size_t n_participants, uint32_t threshold, const secp256k1_frost_tweak_cache *tweak_cache, const unsigned char *msg, size_t msglen) { + secp256k1_frost_tweak_cache_internal cache_i; + secp256k1_frost_session_internal session_i; + secp256k1_ge aggnonce_pts[2]; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(session != NULL); + memset(session, 0, sizeof(*session)); + ARG_CHECK(aggnonce != NULL); + ARG_CHECK(ids != NULL); + ARG_CHECK(tweak_cache != NULL); + ARG_CHECK(msg != NULL); + + if (!secp256k1_frost_tweak_cache_load(ctx, &cache_i, tweak_cache)) { + return 0; + } + if (!secp256k1_frost_validate_session_params(ctx, ids, pubshares, n_signers, n_participants, threshold, &cache_i)) { + return 0; + } + if (!secp256k1_frost_aggnonce_load(ctx, aggnonce_pts, aggnonce)) { + return 0; + } + if (!secp256k1_frost_get_session_values(ctx, &session_i, aggnonce_pts, ids, n_signers, &cache_i, msg, msglen)) { + return 0; + } + secp256k1_frost_session_save(session, &session_i); + return 1; +} + +/* Checks s*G == Re_s + (e*lambda*g')*P, where Re_s is the signer's effective + * nonce R1 + b*R2 (negated iff the final nonce R has odd Y) and g' = g*gacc. + * This is the verification equation of the BIP 445 partial_sig_verify_internal + * algorithm. nonce_pts must not contain the point at infinity. */ +static int secp256k1_frost_verify_partial_sig(const secp256k1_scalar *s, const secp256k1_ge *nonce_pts, const secp256k1_ge *pubshare, const secp256k1_scalar *lambda, const secp256k1_frost_session_internal *session_i) { + secp256k1_scalar e, s_neg; + secp256k1_gej rj, pkj, tmp; + + /* The signer's effective nonce rj = R1 + b*R2. The nonce components of a + * pubnonce are never the point at infinity. */ + VERIFY_CHECK(!secp256k1_ge_is_infinity(&nonce_pts[0])); + VERIFY_CHECK(!secp256k1_ge_is_infinity(&nonce_pts[1])); + secp256k1_gej_set_ge(&rj, &nonce_pts[1]); + secp256k1_ecmult(&rj, &rj, &session_i->noncecoef, NULL); + secp256k1_gej_add_ge_var(&rj, &rj, &nonce_pts[0], NULL); + if (session_i->fin_nonce_parity) { + secp256k1_gej_neg(&rj, &rj); + } + + /* e = e*lambda*g', where g' = -1 iff g*gacc == -1 */ + secp256k1_scalar_mul(&e, &session_i->challenge, lambda); + if (session_i->g_times_gacc_parity) { + secp256k1_scalar_negate(&e, &e); + } + + /* Check -s*G + e*P + rj == infinity, i.e. s*G == rj + e*P */ + secp256k1_scalar_negate(&s_neg, s); + secp256k1_gej_set_ge(&pkj, pubshare); + secp256k1_ecmult(&tmp, &pkj, &e, &s_neg); + secp256k1_gej_add_var(&tmp, &tmp, &rj, NULL); + return secp256k1_gej_is_infinity(&tmp); +} + +/* Shared signing routine of frost_sign and frost_deterministic_sign (the Sign + * algorithm of BIP 445): computes the partial signature s = k1 + b*k2 + + * e*lambda*d from the unnegated secret nonce pair k, the secret share and the + * session values. The nonces are negated iff the final nonce R has odd Y, and + * the secret share is multiplied by g*gacc. If pubshares is non-NULL, the + * secret share is checked against the signer's pubshare. Fails (returns 0) if + * the secret share is invalid, if my_id is not in the signer set, or if the + * pubshare check fails. The secret nonce pair k and all secret intermediates + * are cleansed before this function returns. */ +static int secp256k1_frost_sign_internal(const secp256k1_context *ctx, secp256k1_frost_partial_sig *partial_sig, secp256k1_scalar *k, const unsigned char *secshare32, const secp256k1_frost_session_internal *session_i, const uint32_t *ids, const secp256k1_pubkey *pubshares, size_t n_signers, uint32_t my_id) { + secp256k1_scalar d, lambda, s, tmp; + secp256k1_gej nonce_ptj[2]; + secp256k1_ge nonce_pts[2]; + secp256k1_ge pk; + size_t my_index = n_signers; + size_t i; + int ret = 0; + + /* Compute the pubnonce points from the unnegated nonces for the + * self-verification below. k[0] != 0 and k[1] != 0 is guaranteed by the + * caller, so the points are not the point at infinity. */ + secp256k1_ecmult_gen_gej(&ctx->ecmult_gen_ctx, &nonce_ptj[0], &k[0]); + secp256k1_ecmult_gen_gej(&ctx->ecmult_gen_ctx, &nonce_ptj[1], &k[1]); + secp256k1_ge_set_all_gej(nonce_pts, nonce_ptj, 2); + secp256k1_declassify(ctx, &nonce_pts, sizeof(nonce_pts)); + + /* The secret share must be nonzero and less than the curve order. We can + * declassify the result of the check because branching on it only leaks + * whether the provided secret share is a valid secret key, which is not + * secret. */ + { + int share_valid = secp256k1_scalar_set_b32_seckey(&d, secshare32); + secp256k1_declassify(ctx, &share_valid, sizeof(share_valid)); + if (!share_valid) { + goto cleanup; + } + } + /* P = d*G */ + secp256k1_ecmult_gen_ge(&ctx->ecmult_gen_ctx, &pk, &d); + secp256k1_declassify(ctx, &pk, sizeof(pk)); + + /* The signer's id must be in the session's signer set. */ + for (i = 0; i < n_signers; i++) { + if (ids[i] == my_id) { + my_index = i; + break; + } + } + if (my_index == n_signers) { + goto cleanup; + } + /* If the pubshares are known, the secret share must match the signer's + * pubshare (recommended by BIP 445). */ + if (pubshares != NULL) { + secp256k1_ge expected; + if (!secp256k1_pubkey_load(ctx, &expected, &pubshares[my_index])) { + goto cleanup; + } + if (!secp256k1_ge_eq_var(&pk, &expected)) { + goto cleanup; + } + } + if (!secp256k1_frost_derive_interpolating_value(&lambda, ids, n_signers, my_id)) { + goto cleanup; + } + + /* d = g*gacc*d' */ + if (session_i->g_times_gacc_parity) { + secp256k1_scalar_negate(&d, &d); + } + /* Negate the nonces iff the final nonce R has odd Y. */ + if (session_i->fin_nonce_parity) { + secp256k1_scalar_negate(&k[0], &k[0]); + secp256k1_scalar_negate(&k[1], &k[1]); + } + + /* s = k1 + b*k2 + e*lambda*d */ + secp256k1_scalar_mul(&s, &session_i->challenge, &lambda); + secp256k1_scalar_mul(&s, &s, &d); + secp256k1_scalar_mul(&tmp, &session_i->noncecoef, &k[1]); + secp256k1_scalar_add(&k[0], &k[0], &tmp); + secp256k1_scalar_add(&s, &s, &k[0]); + + /* Self-verify the partial signature, as recommended by BIP 445. This can + * only fail in case of an implementation bug or catastrophic hardware + * failure, so the result of the verification is not secret. */ + { + int verified = secp256k1_frost_verify_partial_sig(&s, nonce_pts, &pk, &lambda, session_i); + secp256k1_declassify(ctx, &verified, sizeof(verified)); + if (!verified) { + goto cleanup; + } + } + secp256k1_frost_partial_sig_save(partial_sig, &s); + ret = 1; + +cleanup: + secp256k1_scalar_clear(&d); + secp256k1_scalar_clear(&lambda); + secp256k1_scalar_clear(&s); + secp256k1_scalar_clear(&tmp); + secp256k1_scalar_clear(&k[0]); + secp256k1_scalar_clear(&k[1]); + secp256k1_gej_clear(&nonce_ptj[0]); + secp256k1_gej_clear(&nonce_ptj[1]); + return ret; +} + +int secp256k1_frost_sign(const secp256k1_context *ctx, secp256k1_frost_partial_sig *partial_sig, secp256k1_frost_secnonce *secnonce, const unsigned char *secshare32, const secp256k1_frost_session *session, const uint32_t *ids, const secp256k1_pubkey *pubshares, size_t n_signers, uint32_t my_id) { + secp256k1_scalar k[2]; + secp256k1_frost_session_internal session_i; + int ret; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secnonce != NULL); + /* Fails if the magic doesn't match or the nonce has been invalidated */ + ret = secp256k1_frost_secnonce_load(ctx, k, secnonce); + /* Wipe the secnonce to prevent nonce reuse. This will cause subsequent + * calls of this function with the same secnonce to fail. */ + secp256k1_memzero_explicit(secnonce, sizeof(*secnonce)); + if (!ret) { + secp256k1_scalar_clear(&k[0]); + secp256k1_scalar_clear(&k[1]); + return 0; + } + + ARG_CHECK(partial_sig != NULL); + memset(partial_sig, 0, sizeof(*partial_sig)); + ARG_CHECK(secshare32 != NULL); + ARG_CHECK(session != NULL); + ARG_CHECK(ids != NULL); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + + if (!secp256k1_frost_session_load(ctx, &session_i, session)) { + secp256k1_scalar_clear(&k[0]); + secp256k1_scalar_clear(&k[1]); + return 0; + } + /* The ids array must be identical to the one passed to session_init. */ + if (session_i.n_signers != n_signers) { + secp256k1_scalar_clear(&k[0]); + secp256k1_scalar_clear(&k[1]); + return 0; + } + return secp256k1_frost_sign_internal(ctx, partial_sig, k, secshare32, &session_i, ids, pubshares, n_signers, my_id); +} + +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 uint32_t *ids, size_t n_signers, size_t signer_index) { + secp256k1_frost_session_internal session_i; + secp256k1_scalar s, lambda; + secp256k1_ge nonce_pts[2]; + secp256k1_ge pubshare_ge; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(partial_sig != NULL); + ARG_CHECK(pubnonce != NULL); + ARG_CHECK(pubshare != NULL); + ARG_CHECK(session != NULL); + ARG_CHECK(ids != NULL); + + if (signer_index >= n_signers) { + return 0; + } + if (!secp256k1_frost_session_load(ctx, &session_i, session)) { + return 0; + } + /* The ids array must be identical to the one passed to session_init. */ + if (session_i.n_signers != n_signers) { + return 0; + } + if (!secp256k1_frost_pubnonce_load(ctx, nonce_pts, pubnonce)) { + return 0; + } + if (!secp256k1_pubkey_load(ctx, &pubshare_ge, pubshare)) { + return 0; + } + if (!secp256k1_frost_partial_sig_load(ctx, &s, partial_sig)) { + return 0; + } + if (!secp256k1_frost_derive_interpolating_value(&lambda, ids, n_signers, ids[signer_index])) { + return 0; + } + return secp256k1_frost_verify_partial_sig(&s, nonce_pts, &pubshare_ge, &lambda, &session_i); +} + +int secp256k1_frost_partial_sig_agg(const secp256k1_context *ctx, unsigned char *sig64, size_t *error_index, const secp256k1_frost_session *session, const secp256k1_frost_partial_sig *const *partial_sigs, size_t n_sigs) { + secp256k1_frost_session_internal session_i; + secp256k1_scalar s; + size_t i; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(sig64 != NULL); + memset(sig64, 0, 64); + ARG_CHECK(session != NULL); + ARG_CHECK(partial_sigs != NULL); + + if (!secp256k1_frost_session_load(ctx, &session_i, session)) { + return 0; + } + if (n_sigs != (size_t)session_i.n_signers) { + return 0; + } + /* s = e*g*tacc + sum_i s_i */ + s = session_i.s_part; + for (i = 0; i < n_sigs; i++) { + secp256k1_scalar term; + /* A NULL array element indicates a missing contribution. This is the + * identifiable-abort path, not an API usage error. */ + if (partial_sigs[i] == NULL) { + if (error_index != NULL) { + *error_index = i; + } + return 0; + } + if (!secp256k1_frost_partial_sig_load(ctx, &term, partial_sigs[i])) { + if (error_index != NULL) { + *error_index = i; + } + return 0; + } + secp256k1_scalar_add(&s, &s, &term); + } + memcpy(sig64, session_i.fin_nonce, 32); + secp256k1_scalar_get_b32(&sig64[32], &s); + return 1; +} + +/* Derives the deterministic nonce pair of DeterministicSign (BIP 445): + * k_i = tagged_hash("BIP0445/deterministic/nonce", secshare_ || ser32(my_id) + * || ser32(u) || sorted ser32 ids || aggothernonce || + * tweaked_thresh_pk_xonly || len8(msg) || msg || byte(i)) + * where aggothernonce is its 66-byte serialization or the empty string for a + * sole signer. Returns 0 if one of the nonces is zero (which can only happen + * with negligible probability), 1 otherwise. All secret intermediates are + * cleansed before this function returns. */ +static int secp256k1_frost_det_nonce_function(const secp256k1_hash_ctx *hash_ctx, secp256k1_scalar *k, const unsigned char *secshare32, uint32_t my_id, const uint32_t *sorted_ids, size_t n_signers, const unsigned char *aggothernonce66, const unsigned char *tweaked_pk32, const unsigned char *msg, size_t msglen) { + secp256k1_sha256 sha; + unsigned char buf[4]; + size_t i; + + secp256k1_frost_sha256_tagged_deterministic_nonce(hash_ctx, &sha); + secp256k1_sha256_write(hash_ctx, &sha, secshare32, 32); + secp256k1_write_be32(buf, my_id); + secp256k1_sha256_write(hash_ctx, &sha, buf, sizeof(buf)); + secp256k1_write_be32(buf, (uint32_t)n_signers); + secp256k1_sha256_write(hash_ctx, &sha, buf, sizeof(buf)); + for (i = 0; i < n_signers; i++) { + secp256k1_write_be32(buf, sorted_ids[i]); + secp256k1_sha256_write(hash_ctx, &sha, buf, sizeof(buf)); + } + if (aggothernonce66 != NULL) { + secp256k1_sha256_write(hash_ctx, &sha, aggothernonce66, 66); + } + secp256k1_sha256_write(hash_ctx, &sha, tweaked_pk32, 32); + secp256k1_frost_sha256_write_prefixed(hash_ctx, &sha, 8, msg, msglen); + + for (i = 0; i < 2; i++) { + unsigned char hash32[32]; + unsigned char idx = (unsigned char)i; + secp256k1_sha256 sha_tmp = sha; + secp256k1_sha256_write(hash_ctx, &sha_tmp, &idx, 1); + secp256k1_sha256_finalize(hash_ctx, &sha_tmp, hash32); + secp256k1_scalar_set_b32(&k[i], hash32, NULL); + + /* Attempt to erase secret data */ + secp256k1_memclear_explicit(hash32, sizeof(hash32)); + secp256k1_sha256_clear(&sha_tmp); + } + secp256k1_sha256_clear(&sha); + return !secp256k1_scalar_is_zero(&k[0]) && !secp256k1_scalar_is_zero(&k[1]); +} + +int secp256k1_frost_deterministic_sign(const secp256k1_context *ctx, secp256k1_frost_partial_sig *partial_sig, secp256k1_frost_pubnonce *pubnonce, const unsigned char *secshare32, uint32_t my_id, const secp256k1_frost_aggnonce *aggothernonce, const uint32_t *ids, const secp256k1_pubkey *pubshares, size_t n_signers, size_t n_participants, uint32_t threshold, const secp256k1_frost_tweak_cache *tweak_cache, const unsigned char *msg, size_t msglen, const unsigned char *aux_rand32) { + const secp256k1_hash_ctx *hash_ctx; + secp256k1_frost_tweak_cache_internal cache_i; + secp256k1_frost_session_internal session_i; + secp256k1_scalar k[2]; + secp256k1_gej nonce_ptj[2]; + secp256k1_ge nonce_pts[2]; + secp256k1_ge aggnonce_pts[2]; + secp256k1_ge aggother_pts[2]; + unsigned char secshare_[32]; + unsigned char pk32[32]; + unsigned char aggother66[66]; + const unsigned char *aggother66_ptr = NULL; + uint32_t sorted_ids[SECP256K1_FROST_MAX_PARTICIPANTS]; + int i; + int ret = 0; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(partial_sig != NULL); + memset(partial_sig, 0, sizeof(*partial_sig)); + ARG_CHECK(pubnonce != NULL); + memset(pubnonce, 0, sizeof(*pubnonce)); + ARG_CHECK(secshare32 != NULL); + ARG_CHECK(ids != NULL); + ARG_CHECK(tweak_cache != NULL); + ARG_CHECK(msg != NULL); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + hash_ctx = secp256k1_get_hash_context(ctx); + + if (!secp256k1_frost_tweak_cache_load(ctx, &cache_i, tweak_cache)) { + return 0; + } + if (!secp256k1_frost_validate_session_params(ctx, ids, pubshares, n_signers, n_participants, threshold, &cache_i)) { + return 0; + } + /* Check that the secshare is valid to be able to sign with it below. */ + { + secp256k1_scalar secshare; + int valid = secp256k1_scalar_set_b32_seckey(&secshare, secshare32); + secp256k1_scalar_clear(&secshare); + if (!valid) { + return 0; + } + } + if (aggothernonce != NULL) { + if (!secp256k1_frost_aggnonce_load(ctx, aggother_pts, aggothernonce)) { + return 0; + } + /* BIP 445 DeterministicSign feeds aggothernonce through NonceAgg as a + * pubnonce contribution, and a pubnonce's components cannot be the + * point at infinity (a pubnonce is serialized with plain compressed + * encoding). Reject an aggothernonce with an infinity component. */ + if (secp256k1_ge_is_infinity(&aggother_pts[0]) || secp256k1_ge_is_infinity(&aggother_pts[1])) { + return 0; + } + secp256k1_ge_serialize_ext(&aggother66[0], &aggother_pts[0]); + secp256k1_ge_serialize_ext(&aggother66[33], &aggother_pts[1]); + aggother66_ptr = aggother66; + } + + /* secshare' = secshare XOR tagged_hash("BIP0445/aux", aux_rand32) */ + if (aux_rand32 != NULL) { + secp256k1_sha256 sha; + secp256k1_frost_sha256_tagged_aux(hash_ctx, &sha); + secp256k1_sha256_write(hash_ctx, &sha, aux_rand32, 32); + secp256k1_sha256_finalize(hash_ctx, &sha, secshare_); + secp256k1_sha256_clear(&sha); + for (i = 0; i < 32; i++) { + secshare_[i] ^= secshare32[i]; + } + } else { + memcpy(secshare_, secshare32, sizeof(secshare_)); + } + + /* The x-only encoding of the tweaked threshold public key. Q is never the + * point at infinity and its x-coordinate is normalized. */ + secp256k1_fe_get_b32(pk32, &cache_i.pk.x); + secp256k1_frost_sort_ids(sorted_ids, ids, n_signers); + + if (!secp256k1_frost_det_nonce_function(hash_ctx, k, secshare_, my_id, sorted_ids, n_signers, aggother66_ptr, pk32, msg, msglen)) { + /* k_i == 0 can only occur with negligible probability */ + goto cleanup; + } + + /* The signer's pubnonce. k != 0, so the points are not infinity. */ + for (i = 0; i < 2; i++) { + secp256k1_ecmult_gen_gej(&ctx->ecmult_gen_ctx, &nonce_ptj[i], &k[i]); + } + secp256k1_ge_set_all_gej(nonce_pts, nonce_ptj, 2); + secp256k1_declassify(ctx, &nonce_pts, sizeof(nonce_pts)); + secp256k1_frost_pubnonce_save(pubnonce, nonce_pts); + + /* The aggregate nonce is the signer's own pubnonce for a sole signer and + * the column-wise sum with aggothernonce otherwise. The sums may be the + * point at infinity (BIP 445 NonceAgg). */ + if (aggothernonce == NULL) { + aggnonce_pts[0] = nonce_pts[0]; + aggnonce_pts[1] = nonce_pts[1]; + } else { + secp256k1_gej sumj[2]; + for (i = 0; i < 2; i++) { + secp256k1_gej_set_ge(&sumj[i], &nonce_pts[i]); + secp256k1_gej_add_ge_var(&sumj[i], &sumj[i], &aggother_pts[i], NULL); + } + secp256k1_ge_set_all_gej_var(aggnonce_pts, sumj, 2); + } + + if (!secp256k1_frost_get_session_values(ctx, &session_i, aggnonce_pts, ids, n_signers, &cache_i, msg, msglen)) { + goto cleanup; + } + ret = secp256k1_frost_sign_internal(ctx, partial_sig, k, secshare32, &session_i, ids, pubshares, n_signers, my_id); + +cleanup: + secp256k1_scalar_clear(&k[0]); + secp256k1_scalar_clear(&k[1]); + secp256k1_gej_clear(&nonce_ptj[0]); + secp256k1_gej_clear(&nonce_ptj[1]); + secp256k1_memzero_explicit(secshare_, sizeof(secshare_)); + return ret; +} + +#endif diff --git a/src/modules/frost/tests_impl.h b/src/modules/frost/tests_impl.h new file mode 100644 index 00000000..feacd361 --- /dev/null +++ b/src/modules/frost/tests_impl.h @@ -0,0 +1,2153 @@ +/*********************************************************************** + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_FROST_TESTS_IMPL_H +#define SECP256K1_MODULE_FROST_TESTS_IMPL_H + +#include + +#include "../../../include/secp256k1.h" +#include "../../../include/secp256k1_frost.h" +#include "../../../include/secp256k1_schnorrsig.h" + +#include "keygen.h" +#include "session.h" +#include "../../group.h" +#include "../../scalar.h" +#include "../../util.h" + +#include "vectors.h" + +/* Fixed-value test of the trusted dealer key generation (BIP 445 + * TrustedDealerKeyGen) with threshold_seckey32 = 0x0102...20, n = 5, t = 3. + * This is the first fixed-value anchor of the module. */ +static void frost_trusted_dealer_vector_test(void) { + static const unsigned char expected_thresh_pk[33] = { + 0x02, 0x84, 0xbf, 0x75, 0x62, 0x26, 0x2b, 0xbd, 0x69, 0x40, 0x08, 0x57, + 0x48, 0xf3, 0xbe, 0x6a, 0xfa, 0x52, 0xae, 0x31, 0x71, 0x55, 0x18, 0x1e, + 0xce, 0x31, 0xb6, 0x63, 0x51, 0xcc, 0xff, 0xa4, 0xb0 + }; + static const unsigned char expected_secshares[5][32] = { + { 0x68, 0x4d, 0x12, 0xac, 0xd2, 0x49, 0x4c, 0x6b, 0x3b, 0x87, 0xb4, 0x57, + 0x29, 0x8b, 0xb8, 0x66, 0xd3, 0xdd, 0x2c, 0x0d, 0x11, 0x5a, 0x40, 0xaa, + 0xd8, 0x37, 0x08, 0xcc, 0x9a, 0xc0, 0x4f, 0xc0 }, + { 0x85, 0x7a, 0x31, 0x82, 0x63, 0xa1, 0xd2, 0x53, 0x26, 0x1c, 0xdb, 0x1a, + 0x36, 0x55, 0x45, 0x26, 0x78, 0xaa, 0x92, 0xb2, 0x9d, 0xcc, 0x4b, 0x23, + 0xc0, 0xa1, 0xa0, 0xfe, 0x29, 0x0b, 0xd6, 0xac }, + { 0x58, 0x89, 0x5f, 0x84, 0xb9, 0x0f, 0x98, 0xbf, 0xc8, 0xc9, 0x7f, 0x55, + 0x33, 0x6a, 0xb5, 0x4e, 0xff, 0x7a, 0x47, 0x04, 0xba, 0x6c, 0x36, 0x82, + 0xd2, 0x59, 0xe3, 0xb0, 0xc8, 0x00, 0xb3, 0xe4 }, + { 0xe1, 0x7a, 0x9c, 0xb3, 0xd2, 0x92, 0x9f, 0xb1, 0x23, 0x8d, 0xa1, 0x08, + 0x20, 0xcc, 0x08, 0xdf, 0x22, 0xfb, 0x25, 0xea, 0x16, 0x82, 0xa3, 0x03, + 0xcd, 0x32, 0x2f, 0x71, 0x47, 0xd5, 0x28, 0xa9 }, + { 0x20, 0x4d, 0xe9, 0x0f, 0xb0, 0x2a, 0xe7, 0x27, 0x36, 0x69, 0x40, 0x32, + 0xfe, 0x79, 0x3f, 0xd9, 0x6d, 0xcf, 0x75, 0x95, 0x53, 0x7e, 0x50, 0x2f, + 0x31, 0x85, 0xc7, 0x26, 0x08, 0x1c, 0xb2, 0x79 } + }; + static const unsigned char expected_pubshares[5][33] = { + { 0x03, 0x8f, 0x88, 0x0d, 0xa3, 0x11, 0x06, 0xe8, 0x0e, 0xc2, 0x9e, 0xf3, + 0xe8, 0x60, 0x91, 0xc7, 0x6a, 0x3e, 0x4e, 0xc9, 0x1d, 0xdc, 0x57, 0xf4, + 0x34, 0x5e, 0x79, 0xc8, 0x10, 0x47, 0xe0, 0xe7, 0x61 }, + { 0x03, 0x2f, 0x80, 0x8b, 0x2a, 0x21, 0x24, 0x3d, 0xc2, 0x28, 0x62, 0xdf, + 0x5c, 0x60, 0x79, 0x89, 0x7e, 0x77, 0xe0, 0xfb, 0x39, 0xb1, 0x8b, 0x6b, + 0x92, 0x10, 0xf3, 0xba, 0xab, 0x76, 0x5a, 0x08, 0x2d }, + { 0x02, 0xd9, 0xa1, 0xfd, 0x34, 0xd8, 0xe3, 0x9f, 0xba, 0x3f, 0xcb, 0x59, + 0x9c, 0x98, 0x78, 0x3d, 0x88, 0xfe, 0xd1, 0x1a, 0xf4, 0xb8, 0x94, 0x9e, + 0x4b, 0x4a, 0xe3, 0xd9, 0x51, 0xe9, 0xed, 0xab, 0x6f }, + { 0x03, 0x8a, 0x07, 0x53, 0xbd, 0xf9, 0x11, 0x15, 0x50, 0x44, 0x99, 0xb0, + 0x92, 0xc3, 0x7a, 0x91, 0x9d, 0x08, 0x26, 0x4b, 0x59, 0xf7, 0x80, 0x28, + 0xb2, 0x0a, 0x85, 0x19, 0x05, 0xb0, 0x53, 0x81, 0xf5 }, + { 0x03, 0x7a, 0x34, 0xc6, 0x4b, 0x81, 0x55, 0xac, 0xfe, 0x23, 0x3e, 0x8c, + 0xab, 0xa3, 0xce, 0x15, 0xe9, 0xf4, 0xfb, 0x83, 0x10, 0xb3, 0xdf, 0xee, + 0xb9, 0x7d, 0xd2, 0x50, 0xdb, 0xe3, 0x08, 0x54, 0x0d } + }; + unsigned char thresh_sk[32]; + unsigned char secshares[5 * 32]; + secp256k1_pubkey thresh_pk; + secp256k1_pubkey pubshares[5]; + unsigned char buf[33]; + size_t outl; + size_t i; + + for (i = 0; i < 32; i++) { + thresh_sk[i] = (unsigned char)(i + 1); + } + CHECK(secp256k1_frost_trusted_dealer_keygen(CTX, secshares, &thresh_pk, pubshares, 5, 3, thresh_sk) == 1); + + outl = sizeof(buf); + CHECK(secp256k1_ec_pubkey_serialize(CTX, buf, &outl, &thresh_pk, SECP256K1_EC_COMPRESSED) == 1); + CHECK(outl == 33); + CHECK(secp256k1_memcmp_var(buf, expected_thresh_pk, 33) == 0); + + for (i = 0; i < 5; i++) { + CHECK(secp256k1_memcmp_var(&secshares[32 * i], expected_secshares[i], 32) == 0); + outl = sizeof(buf); + CHECK(secp256k1_ec_pubkey_serialize(CTX, buf, &outl, &pubshares[i], SECP256K1_EC_COMPRESSED) == 1); + CHECK(outl == 33); + CHECK(secp256k1_memcmp_var(buf, expected_pubshares[i], 33) == 0); + } + + CHECK(secp256k1_frost_threshold_info_validate(CTX, &thresh_pk, pubshares, 5, 3) == 1); +} + +static void frost_trusted_dealer_test_internal(void) { + unsigned char thresh_sk[32]; + unsigned char secshares[SECP256K1_FROST_MAX_PARTICIPANTS * 32]; + secp256k1_pubkey thresh_pk; + secp256k1_pubkey pubshares[SECP256K1_FROST_MAX_PARTICIPANTS]; + size_t n = 1 + testrand_int(SECP256K1_FROST_MAX_PARTICIPANTS); + uint32_t t = 1 + testrand_int(n); + size_t i; + + testutil_random_scalar_order_b32(thresh_sk); + CHECK(secp256k1_frost_trusted_dealer_keygen(CTX, secshares, &thresh_pk, pubshares, n, t, thresh_sk) == 1); + + /* Every pubshare matches its secshare. */ + for (i = 0; i < n; i++) { + secp256k1_scalar share; + secp256k1_ge expected, actual; + int overflow; + + secp256k1_scalar_set_b32(&share, &secshares[32 * i], &overflow); + CHECK(!overflow); + CHECK(!secp256k1_scalar_is_zero(&share)); + secp256k1_ecmult_gen_ge(&CTX->ecmult_gen_ctx, &expected, &share); + CHECK(secp256k1_pubkey_load(CTX, &actual, &pubshares[i])); + CHECK(secp256k1_ge_eq_var(&expected, &actual)); + secp256k1_scalar_clear(&share); + } + + /* The shares of a random subset of t signers combine to the threshold + * secret. */ + { + uint32_t ids[SECP256K1_FROST_MAX_PARTICIPANTS]; + secp256k1_scalar secret, combined, lambda, share; + + for (i = 0; i < n; i++) { + ids[i] = (uint32_t)i; + } + /* Partial Fisher-Yates shuffle of the ids */ + for (i = 0; i < n; i++) { + size_t j = i + testrand_int((uint32_t)(n - i)); + uint32_t tmp = ids[i]; + ids[i] = ids[j]; + ids[j] = tmp; + } + secp256k1_scalar_set_int(&combined, 0); + for (i = 0; i < t; i++) { + secp256k1_scalar_set_b32(&share, &secshares[32 * ids[i]], NULL); + CHECK(secp256k1_frost_derive_interpolating_value(&lambda, ids, t, ids[i]) == 1); + secp256k1_scalar_mul(&share, &share, &lambda); + secp256k1_scalar_add(&combined, &combined, &share); + } + secp256k1_scalar_set_b32(&secret, thresh_sk, NULL); + CHECK(secp256k1_scalar_eq(&combined, &secret)); + secp256k1_scalar_clear(&secret); + secp256k1_scalar_clear(&combined); + secp256k1_scalar_clear(&lambda); + secp256k1_scalar_clear(&share); + } + + /* The generated key material validates. */ + CHECK(secp256k1_frost_threshold_info_validate(CTX, &thresh_pk, pubshares, n, t) == 1); + + /* Replacing a pubshare with a valid but inconsistent point invalidates the + * key material. */ + { + secp256k1_pubkey backup = pubshares[n - 1]; + secp256k1_pubkey other_pk; + unsigned char other_sk[32]; + + testutil_random_scalar_order_b32(other_sk); + CHECK(secp256k1_ec_pubkey_create(CTX, &other_pk, other_sk) == 1); + pubshares[n - 1] = other_pk; + CHECK(secp256k1_frost_threshold_info_validate(CTX, &thresh_pk, pubshares, n, t) == 0); + pubshares[n - 1] = backup; + } + + /* Swapping two pubshares invalidates the key material (unless t = 1, in + * which case all pubshares are equal and the swap is undetectable). */ + if (t > 1) { + secp256k1_pubkey tmp = pubshares[0]; + pubshares[0] = pubshares[1]; + pubshares[1] = tmp; + CHECK(secp256k1_frost_threshold_info_validate(CTX, &thresh_pk, pubshares, n, t) == 0); + tmp = pubshares[0]; + pubshares[0] = pubshares[1]; + pubshares[1] = tmp; + } + + /* Invalid n and t are rejected. */ + CHECK(secp256k1_frost_threshold_info_validate(CTX, &thresh_pk, pubshares, n, 0) == 0); + CHECK(secp256k1_frost_threshold_info_validate(CTX, &thresh_pk, pubshares, n, (uint32_t)(n + 1)) == 0); + CHECK(secp256k1_frost_threshold_info_validate(CTX, &thresh_pk, pubshares, 0, t) == 0); + CHECK(secp256k1_frost_threshold_info_validate(CTX, &thresh_pk, pubshares, SECP256K1_FROST_MAX_PARTICIPANTS + 1, t) == 0); + CHECK(secp256k1_frost_trusted_dealer_keygen(CTX, secshares, &thresh_pk, pubshares, 0, 1, thresh_sk) == 0); + CHECK(secp256k1_frost_trusted_dealer_keygen(CTX, secshares, &thresh_pk, pubshares, SECP256K1_FROST_MAX_PARTICIPANTS + 1, 1, thresh_sk) == 0); + CHECK(secp256k1_frost_trusted_dealer_keygen(CTX, secshares, &thresh_pk, pubshares, n, 0, thresh_sk) == 0); + CHECK(secp256k1_frost_trusted_dealer_keygen(CTX, secshares, &thresh_pk, pubshares, n, (uint32_t)(n + 1), thresh_sk) == 0); +} +REPEAT_TEST(frost_trusted_dealer_test) + +/* Fixed-value test of the tweak cache functions (BIP 445 TweakCtxInit and + * ApplyTweak). The expected values have been verified against the BIP 445 + * Python reference implementation. */ +static void frost_tweak_vector_test(void) { + static const unsigned char thresh_pk33[33] = { + 0x02, 0x84, 0xbf, 0x75, 0x62, 0x26, 0x2b, 0xbd, 0x69, 0x40, 0x08, 0x57, + 0x48, 0xf3, 0xbe, 0x6a, 0xfa, 0x52, 0xae, 0x31, 0x71, 0x55, 0x18, 0x1e, + 0xce, 0x31, 0xb6, 0x63, 0x51, 0xcc, 0xff, 0xa4, 0xb0 + }; + static const unsigned char thresh_pk33_odd[33] = { + 0x03, 0x84, 0xbf, 0x75, 0x62, 0x26, 0x2b, 0xbd, 0x69, 0x40, 0x08, 0x57, + 0x48, 0xf3, 0xbe, 0x6a, 0xfa, 0x52, 0xae, 0x31, 0x71, 0x55, 0x18, 0x1e, + 0xce, 0x31, 0xb6, 0x63, 0x51, 0xcc, 0xff, 0xa4, 0xb0 + }; + /* xonly(thresh_pk) */ + static const unsigned char expected0[32] = { + 0x84, 0xbf, 0x75, 0x62, 0x26, 0x2b, 0xbd, 0x69, 0x40, 0x08, 0x57, 0x48, + 0xf3, 0xbe, 0x6a, 0xfa, 0x52, 0xae, 0x31, 0x71, 0x55, 0x18, 0x1e, 0xce, + 0x31, 0xb6, 0x63, 0x51, 0xcc, 0xff, 0xa4, 0xb0 + }; + /* after xonly tweak 0x02...02 */ + static const unsigned char expected1[32] = { + 0x55, 0xd2, 0xac, 0xd9, 0x3c, 0xcd, 0x26, 0x82, 0xc7, 0x49, 0xd5, 0x97, + 0xaf, 0x74, 0x26, 0x72, 0x6d, 0x31, 0x65, 0x42, 0x62, 0x04, 0x70, 0x8b, + 0xe4, 0xaa, 0x8e, 0x81, 0xe2, 0xbb, 0x8c, 0xd4 + }; + /* after plain tweak 0x03...03 */ + static const unsigned char expected2[32] = { + 0xdb, 0x5f, 0x9c, 0x2e, 0x60, 0xeb, 0xfb, 0x9e, 0x91, 0x74, 0xaa, 0xf9, + 0x0c, 0xa2, 0xab, 0x51, 0x8b, 0xb4, 0x9a, 0x56, 0x75, 0xd6, 0x36, 0x50, + 0x1d, 0x2f, 0x05, 0x84, 0x31, 0x54, 0xb8, 0x41 + }; + /* after xonly tweak 0x04...04 */ + static const unsigned char expected3[32] = { + 0xc8, 0xf3, 0x62, 0xf9, 0x68, 0x68, 0x60, 0xba, 0x45, 0x75, 0xc8, 0xd8, + 0xb2, 0x31, 0xb9, 0xcd, 0xed, 0x9e, 0x87, 0xec, 0x3a, 0x85, 0xff, 0x53, + 0x1a, 0x98, 0x2e, 0xd1, 0xb4, 0x70, 0xae, 0xfd + }; + secp256k1_pubkey thresh_pk; + secp256k1_frost_tweak_cache cache; + secp256k1_xonly_pubkey tweaked_pk; + unsigned char tweak[32]; + unsigned char out32[32]; + + /* Even-Y base point. */ + CHECK(secp256k1_ec_pubkey_parse(CTX, &thresh_pk, thresh_pk33, 33) == 1); + CHECK(secp256k1_frost_tweak_cache_init(CTX, &cache, &thresh_pk) == 1); + CHECK(secp256k1_frost_tweaked_pubkey_get(CTX, &tweaked_pk, &cache) == 1); + CHECK(secp256k1_xonly_pubkey_serialize(CTX, out32, &tweaked_pk) == 1); + CHECK(secp256k1_memcmp_var(out32, expected0, 32) == 0); + + memset(tweak, 0x02, 32); + CHECK(secp256k1_frost_pubkey_xonly_tweak_add(CTX, &tweaked_pk, &cache, tweak) == 1); + CHECK(secp256k1_xonly_pubkey_serialize(CTX, out32, &tweaked_pk) == 1); + CHECK(secp256k1_memcmp_var(out32, expected1, 32) == 0); + + memset(tweak, 0x03, 32); + CHECK(secp256k1_frost_pubkey_ec_tweak_add(CTX, &tweaked_pk, &cache, tweak) == 1); + CHECK(secp256k1_xonly_pubkey_serialize(CTX, out32, &tweaked_pk) == 1); + CHECK(secp256k1_memcmp_var(out32, expected2, 32) == 0); + + memset(tweak, 0x04, 32); + CHECK(secp256k1_frost_pubkey_xonly_tweak_add(CTX, &tweaked_pk, &cache, tweak) == 1); + CHECK(secp256k1_xonly_pubkey_serialize(CTX, out32, &tweaked_pk) == 1); + CHECK(secp256k1_memcmp_var(out32, expected3, 32) == 0); + + /* Odd-Y encoding of the same base point: x-only normalization makes the + * result of an xonly tweak identical to the even-Y base point. */ + CHECK(secp256k1_ec_pubkey_parse(CTX, &thresh_pk, thresh_pk33_odd, 33) == 1); + CHECK(secp256k1_frost_tweak_cache_init(CTX, &cache, &thresh_pk) == 1); + memset(tweak, 0x02, 32); + CHECK(secp256k1_frost_pubkey_xonly_tweak_add(CTX, &tweaked_pk, &cache, tweak) == 1); + CHECK(secp256k1_xonly_pubkey_serialize(CTX, out32, &tweaked_pk) == 1); + CHECK(secp256k1_memcmp_var(out32, expected1, 32) == 0); +} + +static void frost_tweak_test_internal(void) { + /* The curve order n; any tweak >= n is out of range. */ + static const unsigned char order32[32] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, + 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41 + }; + unsigned char sk[32]; + secp256k1_pubkey thresh_pk, invalid_pk; + secp256k1_frost_tweak_cache cache, invalid_cache; + secp256k1_xonly_pubkey tweaked_pk; + unsigned char tweak[32]; + int i; + + memset(&invalid_pk, 0, sizeof(invalid_pk)); + memset(&invalid_cache, 0, sizeof(invalid_cache)); + testutil_random_scalar_order_b32(sk); + CHECK(secp256k1_ec_pubkey_create(CTX, &thresh_pk, sk) == 1); + CHECK(secp256k1_frost_tweak_cache_init(CTX, &cache, &thresh_pk) == 1); + + /* NULL and invalid argument coverage. */ + CHECK_ILLEGAL(CTX, secp256k1_frost_tweak_cache_init(CTX, NULL, &thresh_pk)); + { + /* tweak_cache_init wipes the cache before checking arguments. */ + secp256k1_frost_tweak_cache tmp_cache = cache; + CHECK_ILLEGAL(CTX, secp256k1_frost_tweak_cache_init(CTX, &tmp_cache, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_frost_tweak_cache_init(CTX, &tmp_cache, &invalid_pk)); + } + CHECK_ILLEGAL(CTX, secp256k1_frost_tweaked_pubkey_get(CTX, NULL, &cache)); + CHECK_ILLEGAL(CTX, secp256k1_frost_tweaked_pubkey_get(CTX, &tweaked_pk, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_frost_tweaked_pubkey_get(CTX, &tweaked_pk, &invalid_cache)); + testrand256(tweak); + { + secp256k1_frost_tweak_cache tmp_cache = cache; + CHECK_ILLEGAL(CTX, secp256k1_frost_pubkey_xonly_tweak_add(CTX, &tweaked_pk, NULL, tweak)); + CHECK_ILLEGAL(CTX, secp256k1_frost_pubkey_xonly_tweak_add(CTX, &tweaked_pk, &tmp_cache, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_frost_pubkey_xonly_tweak_add(CTX, &tweaked_pk, &invalid_cache, tweak)); + CHECK_ILLEGAL(CTX, secp256k1_frost_pubkey_ec_tweak_add(CTX, &tweaked_pk, NULL, tweak)); + CHECK_ILLEGAL(CTX, secp256k1_frost_pubkey_ec_tweak_add(CTX, &tweaked_pk, &tmp_cache, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_frost_pubkey_ec_tweak_add(CTX, &tweaked_pk, &invalid_cache, tweak)); + CHECK(secp256k1_memcmp_var(tmp_cache.data, cache.data, sizeof(cache.data)) == 0); + } + + /* Apply a chain of random xonly/plain tweaks and cross-check each step: + * the frost tweak must match secp256k1_xonly_pubkey_tweak_add applied to + * xonly(current Q) or secp256k1_ec_pubkey_tweak_add applied to the full + * current Q, respectively. The reference point ref_pk tracks the full + * current Q. */ + { + secp256k1_pubkey ref_pk = thresh_pk; + + for (i = 0; i < 8; i++) { + secp256k1_xonly_pubkey ref_xonly; + unsigned char out32[32], ref32[32]; + + testrand256(tweak); + if (testrand_bits(1)) { + CHECK(secp256k1_frost_pubkey_xonly_tweak_add(CTX, &tweaked_pk, &cache, tweak) == 1); + CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &ref_xonly, NULL, &ref_pk) == 1); + CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &ref_pk, &ref_xonly, tweak) == 1); + } else { + CHECK(secp256k1_frost_pubkey_ec_tweak_add(CTX, &tweaked_pk, &cache, tweak) == 1); + CHECK(secp256k1_ec_pubkey_tweak_add(CTX, &ref_pk, tweak) == 1); + } + CHECK(secp256k1_xonly_pubkey_serialize(CTX, out32, &tweaked_pk) == 1); + CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &ref_xonly, NULL, &ref_pk) == 1); + CHECK(secp256k1_xonly_pubkey_serialize(CTX, ref32, &ref_xonly) == 1); + CHECK(secp256k1_memcmp_var(out32, ref32, 32) == 0); + + /* tweaked_pubkey_get agrees with the tweak_add output. */ + CHECK(secp256k1_frost_tweaked_pubkey_get(CTX, &tweaked_pk, &cache) == 1); + CHECK(secp256k1_xonly_pubkey_serialize(CTX, ref32, &tweaked_pk) == 1); + CHECK(secp256k1_memcmp_var(out32, ref32, 32) == 0); + } + } + + /* A failing tweak (out of range) must leave the cache unchanged: applying + * a known tweak after the failed one must give the same result as applying + * it to a cache that never saw the failed tweak. */ + { + secp256k1_frost_tweak_cache failed_cache = cache; + secp256k1_frost_tweak_cache backup_cache = cache; + secp256k1_xonly_pubkey out_pk1, out_pk2; + unsigned char ser1[32], ser2[32]; + + CHECK(secp256k1_frost_pubkey_xonly_tweak_add(CTX, &tweaked_pk, &failed_cache, order32) == 0); + CHECK(secp256k1_frost_pubkey_ec_tweak_add(CTX, &tweaked_pk, &failed_cache, order32) == 0); + CHECK(secp256k1_memcmp_var(failed_cache.data, cache.data, sizeof(cache.data)) == 0); + + testrand256(tweak); + CHECK(secp256k1_frost_pubkey_xonly_tweak_add(CTX, &out_pk1, &failed_cache, tweak) == 1); + CHECK(secp256k1_frost_pubkey_xonly_tweak_add(CTX, &out_pk2, &backup_cache, tweak) == 1); + CHECK(secp256k1_xonly_pubkey_serialize(CTX, ser1, &out_pk1) == 1); + CHECK(secp256k1_xonly_pubkey_serialize(CTX, ser2, &out_pk2) == 1); + CHECK(secp256k1_memcmp_var(ser1, ser2, 32) == 0); + } +} +REPEAT_TEST(frost_tweak_test) + +/* Fixed-value tests of nonce generation and aggregation (BIP 445 NonceGen and + * NonceAgg). The expected values have been verified against the BIP 445 + * Python reference implementation. */ +static void frost_nonce_vector_test(void) { + static const unsigned char pubshare33[33] = { + 0x03, 0x8f, 0x88, 0x0d, 0xa3, 0x11, 0x06, 0xe8, 0x0e, 0xc2, 0x9e, 0xf3, + 0xe8, 0x60, 0x91, 0xc7, 0x6a, 0x3e, 0x4e, 0xc9, 0x1d, 0xdc, 0x57, 0xf4, + 0x34, 0x5e, 0x79, 0xc8, 0x10, 0x47, 0xe0, 0xe7, 0x61 + }; + static const unsigned char thresh_pk32[32] = { + 0x84, 0xbf, 0x75, 0x62, 0x26, 0x2b, 0xbd, 0x69, 0x40, 0x08, 0x57, 0x48, + 0xf3, 0xbe, 0x6a, 0xfa, 0x52, 0xae, 0x31, 0x71, 0x55, 0x18, 0x1e, 0xce, + 0x31, 0xb6, 0x63, 0x51, 0xcc, 0xff, 0xa4, 0xb0 + }; + static const unsigned char msg[] = "frost test message"; + static const unsigned char expected_full_secnonce[64] = { + 0xc8, 0x5b, 0xe4, 0xd1, 0x05, 0x92, 0xcb, 0xf3, 0x94, 0xe6, 0xe2, 0x7f, + 0x7c, 0xa8, 0x78, 0x46, 0x4b, 0x1b, 0xd0, 0x3e, 0x81, 0x6a, 0x7a, 0x77, + 0xec, 0xf2, 0x93, 0x7e, 0x13, 0xdf, 0x8b, 0x16, 0x5e, 0x8c, 0xc9, 0x24, + 0x00, 0xd9, 0xa8, 0x4d, 0xa5, 0x3e, 0xfb, 0x9b, 0x25, 0x7b, 0x62, 0x37, + 0x65, 0x76, 0xb4, 0x2d, 0xe5, 0x74, 0xec, 0x9d, 0x9f, 0xcf, 0x82, 0x9c, + 0xc6, 0xbd, 0x14, 0xe8 + }; + static const unsigned char expected_full_pubnonce[66] = { + 0x03, 0x2e, 0x36, 0xc1, 0x27, 0x26, 0x27, 0x31, 0x41, 0x9a, 0xa1, 0x65, + 0xa9, 0xcc, 0xce, 0xcd, 0xb0, 0x03, 0x1c, 0x50, 0x19, 0xe1, 0x24, 0xb6, + 0x9c, 0x18, 0xd7, 0xa7, 0x5a, 0xa4, 0xa2, 0x27, 0x7c, 0x03, 0x77, 0x53, + 0xb9, 0xd7, 0xaf, 0x60, 0x16, 0x4a, 0x27, 0x18, 0x79, 0x2e, 0xa4, 0x95, + 0x60, 0xc7, 0xe1, 0xfe, 0x13, 0x7b, 0xea, 0xc1, 0x3d, 0x43, 0x85, 0xda, + 0x5e, 0xe1, 0xd6, 0x6d, 0x35, 0x75 + }; + static const unsigned char expected_min_secnonce[64] = { + 0x3e, 0x7f, 0xc5, 0xe4, 0x3a, 0xac, 0x89, 0xce, 0x22, 0x9f, 0x07, 0x9a, + 0x2b, 0x85, 0xd3, 0x10, 0xfd, 0x6d, 0x5a, 0x8f, 0x24, 0xa2, 0xc1, 0x13, + 0xb1, 0x3e, 0xdd, 0x37, 0x40, 0x3e, 0x0a, 0x21, 0xfc, 0xea, 0x76, 0x24, + 0x34, 0x5b, 0x3f, 0xab, 0xa0, 0xd0, 0xe1, 0xb6, 0x7f, 0xce, 0xb0, 0x7c, + 0xd4, 0x7b, 0x3c, 0xc3, 0x3c, 0x7c, 0x1e, 0xd0, 0x0b, 0xd4, 0x34, 0x6a, + 0xaf, 0x4e, 0x4f, 0xc6 + }; + static const unsigned char expected_min_pubnonce[66] = { + 0x03, 0x7d, 0xc8, 0xa9, 0xd6, 0x99, 0x91, 0xd5, 0x6e, 0x50, 0xf5, 0x85, + 0xbc, 0x79, 0x0a, 0xa3, 0x6b, 0x83, 0xfd, 0x16, 0x6c, 0xa2, 0x6d, 0x16, + 0x7c, 0x66, 0x84, 0xa5, 0xa6, 0xa4, 0x7d, 0x35, 0x0d, 0x03, 0xd5, 0x9d, + 0x58, 0xe9, 0xa6, 0x63, 0xaf, 0xa6, 0xfe, 0x00, 0xe8, 0xb7, 0x3c, 0x60, + 0xde, 0x79, 0x52, 0x68, 0x8b, 0x44, 0x6d, 0xe9, 0xb7, 0x2c, 0x34, 0x9f, + 0xa5, 0xb7, 0xdb, 0x5a, 0x27, 0x3a + }; + static const unsigned char expected_aggnonce[66] = { + 0x02, 0xca, 0x8f, 0x0a, 0x06, 0x95, 0x1f, 0xed, 0x10, 0x82, 0x96, 0x00, + 0xcb, 0x15, 0x81, 0xb1, 0xf6, 0x15, 0x31, 0xa5, 0x98, 0x97, 0xa8, 0x27, + 0x11, 0x6a, 0xd0, 0x57, 0xae, 0x91, 0x68, 0x28, 0x74, 0x03, 0xa8, 0x0f, + 0xb3, 0x5e, 0x70, 0xa9, 0xc1, 0xfd, 0x00, 0xd4, 0xcb, 0x4b, 0x79, 0x6f, + 0x60, 0xf1, 0x9d, 0x33, 0x05, 0x01, 0x86, 0x45, 0x52, 0xdb, 0xa6, 0xf1, + 0x69, 0xed, 0x8b, 0xb6, 0x8c, 0xeb + }; + static const unsigned char expected_inf_second[33] = { + 0x02, 0x2f, 0x8c, 0x4c, 0x80, 0xa4, 0x9f, 0x4e, 0x7b, 0x97, 0x35, 0x6a, + 0xed, 0x72, 0x3c, 0x3a, 0x17, 0xb8, 0x86, 0x0a, 0x58, 0x68, 0x8e, 0x83, + 0x03, 0x0d, 0x36, 0x95, 0xbe, 0x1e, 0x5f, 0x99, 0x91 + }; + secp256k1_pubkey pubshare; + secp256k1_frost_secnonce secnonce; + secp256k1_frost_secnonce secnonce2; + secp256k1_frost_pubnonce pubnonce; + secp256k1_frost_pubnonce pubnonce2; + secp256k1_frost_aggnonce aggnonce; + unsigned char rand[32]; + unsigned char secshare[32]; + unsigned char extra_in[16]; + unsigned char buf[66]; + secp256k1_scalar k[2]; + secp256k1_ge ges[2]; + + /* Full-input case: all optional inputs present. */ + memset(rand, 0x0a, 32); + memset(secshare, 0x0b, 32); + memset(extra_in, 0x0c, 16); + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubshare, pubshare33, 33) == 1); + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce, &pubnonce, rand, secshare, &pubshare, thresh_pk32, msg, sizeof(msg) - 1, extra_in, sizeof(extra_in)) == 1); + CHECK(secp256k1_frost_secnonce_load(CTX, k, &secnonce) == 1); + secp256k1_scalar_get_b32(&buf[0], &k[0]); + secp256k1_scalar_get_b32(&buf[32], &k[1]); + CHECK(secp256k1_memcmp_var(buf, expected_full_secnonce, 64) == 0); + CHECK(secp256k1_frost_pubnonce_serialize(CTX, buf, &pubnonce) == 1); + CHECK(secp256k1_memcmp_var(buf, expected_full_pubnonce, 66) == 0); + /* nonce_gen wipes the session randomness before returning. */ + CHECK(secp256k1_is_zero_array(rand, 32)); + + /* Minimal case: no optional inputs. */ + memset(rand, 0x0d, 32); + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce2, &pubnonce2, rand, NULL, NULL, NULL, NULL, 0, NULL, 0) == 1); + CHECK(secp256k1_frost_secnonce_load(CTX, k, &secnonce2) == 1); + secp256k1_scalar_get_b32(&buf[0], &k[0]); + secp256k1_scalar_get_b32(&buf[32], &k[1]); + CHECK(secp256k1_memcmp_var(buf, expected_min_secnonce, 64) == 0); + CHECK(secp256k1_frost_pubnonce_serialize(CTX, buf, &pubnonce2) == 1); + CHECK(secp256k1_memcmp_var(buf, expected_min_pubnonce, 66) == 0); + CHECK(secp256k1_is_zero_array(rand, 32)); + + /* Aggregating the two pubnonces. */ + { + const secp256k1_frost_pubnonce *pubnonce_ptrs[2] = { &pubnonce, &pubnonce2 }; + CHECK(secp256k1_frost_nonce_agg(CTX, &aggnonce, NULL, pubnonce_ptrs, 2) == 1); + CHECK(secp256k1_frost_aggnonce_serialize(CTX, buf, &aggnonce) == 1); + CHECK(secp256k1_memcmp_var(buf, expected_aggnonce, 66) == 0); + } + + /* A column whose sum is the point at infinity is allowed in an aggnonce + * and serializes as 33 zero bytes. */ + { + secp256k1_frost_pubnonce pubnonce_neg; + const secp256k1_frost_pubnonce *pubnonce_ptrs[2] = { &pubnonce, &pubnonce_neg }; + + CHECK(secp256k1_frost_pubnonce_load(CTX, ges, &pubnonce) == 1); + secp256k1_ge_neg(&ges[0], &ges[0]); + secp256k1_frost_pubnonce_save(&pubnonce_neg, ges); + CHECK(secp256k1_frost_nonce_agg(CTX, &aggnonce, NULL, pubnonce_ptrs, 2) == 1); + CHECK(secp256k1_frost_aggnonce_serialize(CTX, buf, &aggnonce) == 1); + CHECK(secp256k1_is_zero_array(buf, 33)); + CHECK(secp256k1_memcmp_var(&buf[33], expected_inf_second, 33) == 0); + + /* An aggnonce with an infinity component can be parsed; a pubnonce + * can not. */ + CHECK(secp256k1_frost_aggnonce_parse(CTX, &aggnonce, buf) == 1); + CHECK(secp256k1_frost_pubnonce_parse(CTX, &pubnonce_neg, buf) == 0); + } +} + +static void frost_nonce_test_internal(void) { + secp256k1_frost_secnonce secnonce[3]; + secp256k1_frost_pubnonce pubnonce[3]; + secp256k1_frost_aggnonce aggnonce; + unsigned char rand[32]; + unsigned char msg[32]; + unsigned char extra_in[16]; + unsigned char secshare[32]; + unsigned char thresh_pk32[32]; + secp256k1_pubkey pubshare; + unsigned char buf66[66]; + size_t msglen, extra_in_len; + size_t i; + int j; + + /* Generate nonces with randomly chosen optional inputs. */ + for (i = 0; i < 3; i++) { + const unsigned char *secshare_ptr = NULL; + const secp256k1_pubkey *pubshare_ptr = NULL; + const unsigned char *thresh_pk32_ptr = NULL; + const unsigned char *msg_ptr = NULL; + const unsigned char *extra_in_ptr = NULL; + + testrand256(rand); + testutil_random_scalar_order_b32(secshare); + testrand256(thresh_pk32); + msglen = testrand_int(sizeof(msg) + 1); + testrand256(msg); + extra_in_len = testrand_int(sizeof(extra_in) + 1); + testrand256(extra_in); + if (testrand_bits(1)) { + secp256k1_pubkey pubshare_tmp; + CHECK(secp256k1_ec_pubkey_create(CTX, &pubshare_tmp, secshare) == 1); + pubshare = pubshare_tmp; + secshare_ptr = secshare; + pubshare_ptr = &pubshare; + } + if (testrand_bits(1)) { + thresh_pk32_ptr = thresh_pk32; + } + if (testrand_bits(1)) { + msg_ptr = msg; + } else { + msglen = 0; + } + if (testrand_bits(1)) { + extra_in_ptr = extra_in; + } else { + extra_in_len = 0; + } + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce[i], &pubnonce[i], rand, secshare_ptr, pubshare_ptr, thresh_pk32_ptr, msg_ptr, msglen, extra_in_ptr, extra_in_len) == 1); + CHECK(secp256k1_is_zero_array(rand, 32)); + } + + /* Serialize/parse round-trip preserves the internal representation. */ + for (i = 0; i < 3; i++) { + secp256k1_frost_pubnonce parsed; + secp256k1_ge ges[2], ges_parsed[2]; + + CHECK(secp256k1_frost_pubnonce_serialize(CTX, buf66, &pubnonce[i]) == 1); + CHECK(secp256k1_frost_pubnonce_parse(CTX, &parsed, buf66) == 1); + CHECK(secp256k1_frost_pubnonce_load(CTX, ges, &pubnonce[i]) == 1); + CHECK(secp256k1_frost_pubnonce_load(CTX, ges_parsed, &parsed) == 1); + for (j = 0; j < 2; j++) { + CHECK(secp256k1_ge_eq_var(&ges[j], &ges_parsed[j])); + } + } + + /* Aggregating a single pubnonce (u = 1) yields the same points. */ + { + const secp256k1_frost_pubnonce *pubnonce_ptrs[1] = { &pubnonce[0] }; + secp256k1_ge ges[2], ges_agg[2]; + + CHECK(secp256k1_frost_nonce_agg(CTX, &aggnonce, NULL, pubnonce_ptrs, 1) == 1); + CHECK(secp256k1_frost_pubnonce_load(CTX, ges, &pubnonce[0]) == 1); + CHECK(secp256k1_frost_aggnonce_load(CTX, ges_agg, &aggnonce) == 1); + for (j = 0; j < 2; j++) { + CHECK(secp256k1_ge_eq_var(&ges[j], &ges_agg[j])); + } + } + + /* Aggregating u nonces matches the manual column sums. */ + { + const secp256k1_frost_pubnonce *pubnonce_ptrs[3] = { &pubnonce[0], &pubnonce[1], &pubnonce[2] }; + secp256k1_gej sumj[2]; + secp256k1_ge sums[2], ges_agg[2]; + + CHECK(secp256k1_frost_nonce_agg(CTX, &aggnonce, NULL, pubnonce_ptrs, 3) == 1); + secp256k1_gej_set_infinity(&sumj[0]); + secp256k1_gej_set_infinity(&sumj[1]); + for (i = 0; i < 3; i++) { + secp256k1_ge ges[2]; + CHECK(secp256k1_frost_pubnonce_load(CTX, ges, &pubnonce[i]) == 1); + for (j = 0; j < 2; j++) { + secp256k1_gej_add_ge_var(&sumj[j], &sumj[j], &ges[j], NULL); + } + } + secp256k1_ge_set_all_gej_var(sums, sumj, 2); + CHECK(secp256k1_frost_aggnonce_load(CTX, ges_agg, &aggnonce) == 1); + for (j = 0; j < 2; j++) { + CHECK(secp256k1_ge_eq_var(&sums[j], &ges_agg[j])); + } + } + + /* A NULL array element is a missing contribution: nonce_agg fails and + * reports its index. */ + { + const secp256k1_frost_pubnonce *pubnonce_ptrs[3] = { &pubnonce[0], &pubnonce[1], &pubnonce[2] }; + size_t null_index = testrand_int(3); + size_t error_index = 0xFF; + + pubnonce_ptrs[null_index] = NULL; + CHECK(secp256k1_frost_nonce_agg(CTX, &aggnonce, &error_index, pubnonce_ptrs, 3) == 0); + CHECK(error_index == null_index); + CHECK(secp256k1_frost_nonce_agg(CTX, &aggnonce, NULL, pubnonce_ptrs, 3) == 0); + } + + /* Domain separation: changing any optional input changes the pubnonce. */ + { + unsigned char buf_base[66], buf_variant[66]; + unsigned char rand_copy[32]; + + testrand256(rand); + memcpy(rand_copy, rand, 32); + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce[0], &pubnonce[0], rand_copy, NULL, NULL, NULL, NULL, 0, NULL, 0) == 1); + CHECK(secp256k1_frost_pubnonce_serialize(CTX, buf_base, &pubnonce[0]) == 1); + + /* msg = NULL differs from msg present (even when empty). */ + memcpy(rand_copy, rand, 32); + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce[0], &pubnonce[1], rand_copy, NULL, NULL, NULL, msg, 0, NULL, 0) == 1); + CHECK(secp256k1_frost_pubnonce_serialize(CTX, buf_variant, &pubnonce[1]) == 1); + CHECK(secp256k1_memcmp_var(buf_base, buf_variant, 66) != 0); + + /* A different msg. */ + memcpy(rand_copy, rand, 32); + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce[0], &pubnonce[1], rand_copy, NULL, NULL, NULL, msg, 1, NULL, 0) == 1); + CHECK(secp256k1_frost_pubnonce_serialize(CTX, buf_variant, &pubnonce[1]) == 1); + CHECK(secp256k1_memcmp_var(buf_base, buf_variant, 66) != 0); + + /* extra_in present. */ + memcpy(rand_copy, rand, 32); + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce[0], &pubnonce[1], rand_copy, NULL, NULL, NULL, NULL, 0, extra_in, 1) == 1); + CHECK(secp256k1_frost_pubnonce_serialize(CTX, buf_variant, &pubnonce[1]) == 1); + CHECK(secp256k1_memcmp_var(buf_base, buf_variant, 66) != 0); + + /* secshare and pubshare present. */ + testutil_random_scalar_order_b32(secshare); + CHECK(secp256k1_ec_pubkey_create(CTX, &pubshare, secshare) == 1); + memcpy(rand_copy, rand, 32); + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce[0], &pubnonce[1], rand_copy, secshare, &pubshare, NULL, NULL, 0, NULL, 0) == 1); + CHECK(secp256k1_frost_pubnonce_serialize(CTX, buf_variant, &pubnonce[1]) == 1); + CHECK(secp256k1_memcmp_var(buf_base, buf_variant, 66) != 0); + + /* thresh_pk32 present. */ + testrand256(thresh_pk32); + memcpy(rand_copy, rand, 32); + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce[0], &pubnonce[1], rand_copy, NULL, NULL, thresh_pk32, NULL, 0, NULL, 0) == 1); + CHECK(secp256k1_frost_pubnonce_serialize(CTX, buf_variant, &pubnonce[1]) == 1); + CHECK(secp256k1_memcmp_var(buf_base, buf_variant, 66) != 0); + } + + /* Invalid arguments. */ + testrand256(rand); + testutil_random_scalar_order_b32(secshare); + CHECK_ILLEGAL(STATIC_CTX, secp256k1_frost_nonce_gen(STATIC_CTX, &secnonce[0], &pubnonce[0], rand, NULL, NULL, NULL, NULL, 0, NULL, 0)); + CHECK_ILLEGAL(CTX, secp256k1_frost_nonce_gen(CTX, NULL, &pubnonce[0], rand, NULL, NULL, NULL, NULL, 0, NULL, 0)); + CHECK_ILLEGAL(CTX, secp256k1_frost_nonce_gen(CTX, &secnonce[0], NULL, rand, NULL, NULL, NULL, NULL, 0, NULL, 0)); + CHECK_ILLEGAL(CTX, secp256k1_frost_nonce_gen(CTX, &secnonce[0], &pubnonce[0], NULL, NULL, NULL, NULL, NULL, 0, NULL, 0)); + CHECK_ILLEGAL(CTX, secp256k1_frost_nonce_gen(CTX, &secnonce[0], &pubnonce[0], rand, NULL, NULL, NULL, NULL, 1, NULL, 0)); + CHECK_ILLEGAL(CTX, secp256k1_frost_nonce_gen(CTX, &secnonce[0], &pubnonce[0], rand, NULL, NULL, NULL, NULL, 0, NULL, 1)); + + /* An invalid secshare (zero) makes nonce_gen fail and still wipes the + * session randomness. */ + { + unsigned char zero_seckey[32] = { 0 }; + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce[0], &pubnonce[0], rand, zero_seckey, NULL, NULL, NULL, 0, NULL, 0) == 0); + CHECK(secp256k1_is_zero_array(rand, 32)); + } + + /* nonce_agg argument validation. */ + { + const secp256k1_frost_pubnonce *pubnonce_ptrs[3] = { &pubnonce[0], &pubnonce[1], &pubnonce[2] }; + CHECK_ILLEGAL(CTX, secp256k1_frost_nonce_agg(CTX, NULL, NULL, pubnonce_ptrs, 3)); + CHECK_ILLEGAL(CTX, secp256k1_frost_nonce_agg(CTX, &aggnonce, NULL, NULL, 3)); + CHECK_ILLEGAL(CTX, secp256k1_frost_nonce_agg(CTX, &aggnonce, NULL, pubnonce_ptrs, 0)); + } +} +REPEAT_TEST(frost_nonce_test) + +/* Fixed-value tests of a full signing session (BIP 445 GetSessionValues, + * Sign, PartialSigVerify and PartialSigAgg) with threshold_seckey32 = + * 0x0102...20, n = 5, t = 3, signers with ids {0, 2, 4} and msg = + * "BIP 445 phase 6 anchor". The expected values have been verified against + * the BIP 445 Python reference implementation. */ +static void frost_sign_vector_test(void) { + static const unsigned char msg[] = "BIP 445 phase 6 anchor"; + static const unsigned char expected_pubnonce0[66] = { + 0x03, 0x74, 0x8a, 0x28, 0x3e, 0x69, 0x78, 0x74, 0x88, 0x70, 0xff, 0x3e, + 0x30, 0x30, 0xe8, 0x1c, 0x69, 0x9c, 0x2b, 0xad, 0x22, 0x1c, 0xec, 0x8c, + 0xd8, 0xb4, 0xaf, 0x87, 0xfb, 0xae, 0x20, 0x1e, 0xf1, 0x03, 0x3b, 0x3e, + 0xa4, 0x7d, 0xf6, 0xca, 0x58, 0x6c, 0x78, 0x8c, 0x79, 0x4f, 0x86, 0x3d, + 0x7c, 0xbb, 0x11, 0x27, 0x74, 0x95, 0xc6, 0x9a, 0x8d, 0x85, 0x81, 0x44, + 0x53, 0xf9, 0xb3, 0x1d, 0x99, 0x3a + }; + static const unsigned char expected_pubnonce2[66] = { + 0x02, 0xbc, 0xa1, 0x24, 0x83, 0x98, 0x22, 0x6f, 0xef, 0xcb, 0x5e, 0x3f, + 0x28, 0xd6, 0x9b, 0x4b, 0x69, 0xf7, 0x12, 0xf3, 0xde, 0xe4, 0xca, 0x62, + 0xb0, 0xcb, 0xe9, 0xc8, 0xd0, 0x9c, 0x62, 0x33, 0x7a, 0x02, 0x31, 0xc1, + 0x8e, 0xd3, 0xc6, 0x57, 0x91, 0xf7, 0x01, 0x10, 0xde, 0x63, 0x50, 0x43, + 0xfb, 0xc6, 0x98, 0x1f, 0x71, 0xe3, 0x52, 0x90, 0x61, 0x98, 0x7f, 0x75, + 0x3a, 0x10, 0x48, 0x7f, 0x45, 0x20 + }; + static const unsigned char expected_pubnonce4[66] = { + 0x02, 0xf1, 0x7c, 0xe6, 0xbd, 0x2d, 0xe9, 0x97, 0x81, 0x5d, 0xdd, 0xb6, + 0x5d, 0x44, 0xea, 0x8c, 0x24, 0xfc, 0x6d, 0xd6, 0x41, 0xef, 0x0c, 0xc6, + 0x53, 0xa5, 0x1b, 0x82, 0x2d, 0xab, 0x86, 0x23, 0x61, 0x03, 0xb9, 0x56, + 0x14, 0xc7, 0xb2, 0xea, 0x79, 0x58, 0x9b, 0x3c, 0xb7, 0xc7, 0x47, 0x0f, + 0x9f, 0xf7, 0x3e, 0xe3, 0x57, 0x83, 0xcb, 0x9b, 0x7f, 0x0d, 0xf4, 0x8f, + 0xb0, 0x64, 0x3f, 0xdd, 0x74, 0xb1 + }; + static const unsigned char expected_aggnonce[66] = { + 0x03, 0xd8, 0x6c, 0xa2, 0xd4, 0xd8, 0x0b, 0x3e, 0xe6, 0xdf, 0xf7, 0xfc, + 0xab, 0x19, 0xb1, 0xf8, 0x60, 0x61, 0x8b, 0xd3, 0x0a, 0xbc, 0x2a, 0xe9, + 0x8d, 0x51, 0xb3, 0x7a, 0x2c, 0x89, 0x2f, 0x38, 0xec, 0x02, 0x37, 0x03, + 0x1d, 0x23, 0x71, 0x1b, 0xd0, 0x3b, 0x32, 0xb0, 0xab, 0x1f, 0xd2, 0x5e, + 0xed, 0x30, 0xf1, 0xcf, 0xb8, 0x7f, 0x11, 0xb6, 0xa0, 0xc7, 0xb6, 0x01, + 0x56, 0x93, 0x80, 0x2e, 0xda, 0x3e + }; + static const unsigned char expected_psig0[32] = { + 0xce, 0xa4, 0x74, 0xd1, 0xb8, 0xe3, 0x1b, 0xa3, 0xcd, 0x7a, 0xde, 0xe2, + 0xe5, 0x61, 0x12, 0x9c, 0xb0, 0x97, 0x88, 0x9f, 0x41, 0xcc, 0xf3, 0xc6, + 0x2b, 0x6e, 0x4f, 0x41, 0x63, 0x10, 0x00, 0x29 + }; + static const unsigned char expected_psig2[32] = { + 0xaa, 0x89, 0xef, 0x0c, 0x22, 0xb6, 0xae, 0xa2, 0x6a, 0x18, 0x40, 0x3a, + 0xc1, 0x2a, 0x5c, 0x4a, 0xfd, 0x84, 0x87, 0x89, 0x4e, 0xcd, 0x6b, 0x3e, + 0x69, 0x6f, 0xb0, 0x85, 0xaf, 0x91, 0x0e, 0x11 + }; + static const unsigned char expected_psig4[32] = { + 0x17, 0x73, 0xf9, 0x60, 0x68, 0x41, 0xd5, 0x3e, 0xe8, 0x49, 0x21, 0x39, + 0xf6, 0xda, 0xdd, 0xf2, 0xe7, 0xfb, 0x0c, 0xa0, 0xe9, 0xe2, 0x00, 0xd7, + 0x34, 0xea, 0x17, 0xb2, 0xfa, 0x6b, 0x77, 0x87 + }; + static const unsigned char expected_sig_a[64] = { + 0x5f, 0x4f, 0x69, 0xac, 0xf5, 0x19, 0xbc, 0x24, 0x02, 0xeb, 0xe9, 0x1f, + 0x9d, 0x54, 0xf9, 0x4c, 0xbc, 0xee, 0xd2, 0xc0, 0x62, 0x0b, 0x62, 0xa6, + 0x9b, 0x2f, 0x18, 0x64, 0xea, 0xd1, 0xdb, 0x41, 0x90, 0xa2, 0x5d, 0x3e, + 0x43, 0xdb, 0x9f, 0x85, 0x1f, 0xdc, 0x40, 0x57, 0x9d, 0x66, 0x4c, 0xdb, + 0xdb, 0x68, 0x3f, 0xe2, 0xcb, 0x33, 0xbf, 0xa0, 0x09, 0xf5, 0xb8, 0xed, + 0x3c, 0xd6, 0x44, 0x80 + }; + static const unsigned char expected_sig_b[64] = { + 0x9e, 0x1f, 0x53, 0xfa, 0xdd, 0x44, 0x5d, 0x70, 0x34, 0x8b, 0xae, 0xa1, + 0x98, 0xa3, 0x25, 0x9e, 0xd3, 0xef, 0xa9, 0x33, 0xcc, 0x0c, 0xe3, 0x25, + 0xa5, 0xc0, 0x4d, 0xef, 0x1c, 0x75, 0xf8, 0x80, 0x8e, 0x7c, 0x0d, 0xa7, + 0x3c, 0x29, 0xa2, 0x08, 0x68, 0xcf, 0x0f, 0x8b, 0x85, 0xbf, 0x17, 0xbf, + 0xa4, 0x44, 0xda, 0xa5, 0x23, 0x38, 0x88, 0x6d, 0x7f, 0xe5, 0x7e, 0x8b, + 0x92, 0x7e, 0xa4, 0xfe + }; + static const unsigned char expected_tweaked_pk_b[32] = { + 0x55, 0xd2, 0xac, 0xd9, 0x3c, 0xcd, 0x26, 0x82, 0xc7, 0x49, 0xd5, 0x97, + 0xaf, 0x74, 0x26, 0x72, 0x6d, 0x31, 0x65, 0x42, 0x62, 0x04, 0x70, 0x8b, + 0xe4, 0xaa, 0x8e, 0x81, 0xe2, 0xbb, 0x8c, 0xd4 + }; + const unsigned char * const expected_pubnonces[3] = { + expected_pubnonce0, expected_pubnonce2, expected_pubnonce4 + }; + const unsigned char * const expected_psigs[3] = { + expected_psig0, expected_psig2, expected_psig4 + }; + static const uint32_t ids[3] = { 0, 2, 4 }; + unsigned char thresh_sk[32]; + unsigned char secshares[5 * 32]; + secp256k1_pubkey thresh_pk; + secp256k1_pubkey pubshares[5]; + secp256k1_pubkey signer_pubshares[3]; + secp256k1_frost_secnonce secnonce[3]; + secp256k1_frost_pubnonce pubnonce[3]; + const secp256k1_frost_pubnonce *pubnonce_ptrs[3]; + secp256k1_frost_partial_sig psig[3]; + const secp256k1_frost_partial_sig *psig_ptrs[3]; + secp256k1_frost_aggnonce aggnonce; + secp256k1_frost_tweak_cache cache; + secp256k1_frost_session session; + secp256k1_xonly_pubkey xonly_pk, tweaked_pk; + unsigned char rand[32]; + unsigned char thresh_pk32[32]; + unsigned char pk32[32]; + unsigned char buf[66]; + unsigned char sig64[64]; + unsigned char tweak[32]; + size_t i; + + for (i = 0; i < 32; i++) { + thresh_sk[i] = (unsigned char)(i + 1); + } + CHECK(secp256k1_frost_trusted_dealer_keygen(CTX, secshares, &thresh_pk, pubshares, 5, 3, thresh_sk) == 1); + CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &thresh_pk) == 1); + CHECK(secp256k1_xonly_pubkey_serialize(CTX, thresh_pk32, &xonly_pk) == 1); + for (i = 0; i < 3; i++) { + signer_pubshares[i] = pubshares[ids[i]]; + pubnonce_ptrs[i] = &pubnonce[i]; + psig_ptrs[i] = &psig[i]; + } + + /* Case A: no tweaks. */ + CHECK(secp256k1_frost_tweak_cache_init(CTX, &cache, &thresh_pk) == 1); + for (i = 0; i < 3; i++) { + memset(rand, 0xa0 + i, 32); + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce[i], &pubnonce[i], rand, &secshares[32 * ids[i]], &signer_pubshares[i], thresh_pk32, msg, sizeof(msg) - 1, NULL, 0) == 1); + CHECK(secp256k1_frost_pubnonce_serialize(CTX, buf, &pubnonce[i]) == 1); + CHECK(secp256k1_memcmp_var(buf, expected_pubnonces[i], 66) == 0); + } + CHECK(secp256k1_frost_nonce_agg(CTX, &aggnonce, NULL, pubnonce_ptrs, 3) == 1); + CHECK(secp256k1_frost_aggnonce_serialize(CTX, buf, &aggnonce) == 1); + CHECK(secp256k1_memcmp_var(buf, expected_aggnonce, 66) == 0); + + CHECK(secp256k1_frost_session_init(CTX, &session, &aggnonce, ids, signer_pubshares, 3, 5, 3, &cache, msg, sizeof(msg) - 1) == 1); + for (i = 0; i < 3; i++) { + CHECK(secp256k1_frost_sign(CTX, &psig[i], &secnonce[i], &secshares[32 * ids[i]], &session, ids, signer_pubshares, 3, ids[i]) == 1); + CHECK(secp256k1_frost_partial_sig_serialize(CTX, buf, &psig[i]) == 1); + CHECK(secp256k1_memcmp_var(buf, expected_psigs[i], 32) == 0); + CHECK(secp256k1_frost_partial_sig_verify(CTX, &psig[i], &pubnonce[i], &signer_pubshares[i], &session, ids, 3, i) == 1); + } + CHECK(secp256k1_frost_partial_sig_agg(CTX, sig64, NULL, &session, psig_ptrs, 3) == 1); + CHECK(secp256k1_memcmp_var(sig64, expected_sig_a, 64) == 0); + CHECK(secp256k1_schnorrsig_verify(CTX, sig64, msg, sizeof(msg) - 1, &xonly_pk) == 1); + + /* Case B: one xonly tweak 0x02...02 applied to the tweak cache. The + * session inputs (and thus the nonces) are identical to case A. */ + memset(tweak, 0x02, 32); + CHECK(secp256k1_frost_pubkey_xonly_tweak_add(CTX, &tweaked_pk, &cache, tweak) == 1); + CHECK(secp256k1_xonly_pubkey_serialize(CTX, pk32, &tweaked_pk) == 1); + CHECK(secp256k1_memcmp_var(pk32, expected_tweaked_pk_b, 32) == 0); + for (i = 0; i < 3; i++) { + memset(rand, 0xa0 + i, 32); + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce[i], &pubnonce[i], rand, &secshares[32 * ids[i]], &signer_pubshares[i], thresh_pk32, msg, sizeof(msg) - 1, NULL, 0) == 1); + } + CHECK(secp256k1_frost_session_init(CTX, &session, &aggnonce, ids, signer_pubshares, 3, 5, 3, &cache, msg, sizeof(msg) - 1) == 1); + for (i = 0; i < 3; i++) { + CHECK(secp256k1_frost_sign(CTX, &psig[i], &secnonce[i], &secshares[32 * ids[i]], &session, ids, signer_pubshares, 3, ids[i]) == 1); + CHECK(secp256k1_frost_partial_sig_verify(CTX, &psig[i], &pubnonce[i], &signer_pubshares[i], &session, ids, 3, i) == 1); + } + CHECK(secp256k1_frost_partial_sig_agg(CTX, sig64, NULL, &session, psig_ptrs, 3) == 1); + CHECK(secp256k1_memcmp_var(sig64, expected_sig_b, 64) == 0); + CHECK(secp256k1_schnorrsig_verify(CTX, sig64, msg, sizeof(msg) - 1, &tweaked_pk) == 1); +} + +/* Fixed-value tests of deterministic signing (BIP 445 DeterministicSign) with + * threshold_seckey32 = 0x0102...20, n = 3, t = 1 and msg = + * "BIP 445 phase 6 anchor". With t = 1, every secret share equals the + * threshold secret and every pubshare equals the threshold public key. The + * expected values have been verified against the BIP 445 Python reference + * implementation. */ +static void frost_det_sign_vector_test(void) { + static const unsigned char msg[] = "BIP 445 phase 6 anchor"; + static const unsigned char expected_det_pubnonce_c[66] = { + 0x03, 0x9d, 0x34, 0xba, 0xb5, 0x4f, 0xf0, 0x63, 0xeb, 0xa8, 0x34, 0xa8, + 0xbf, 0x4f, 0xbf, 0x51, 0x72, 0xda, 0xe8, 0xdc, 0x5c, 0x4f, 0x3d, 0xf6, + 0xe3, 0x9f, 0xd9, 0xd5, 0x1d, 0xc9, 0x25, 0x93, 0x2e, 0x02, 0xc5, 0x62, + 0x90, 0x0e, 0x2f, 0x3b, 0x59, 0xa3, 0x5d, 0x70, 0x4a, 0xdd, 0xf1, 0xea, + 0xed, 0xfc, 0x40, 0x00, 0x59, 0xae, 0xd3, 0x36, 0x6b, 0x20, 0x7b, 0xea, + 0x96, 0xf9, 0xce, 0xd9, 0x3b, 0xeb + }; + static const unsigned char expected_det_psig_c[32] = { + 0x80, 0x67, 0x74, 0x87, 0xff, 0x6c, 0x1a, 0xdd, 0xee, 0x7a, 0x29, 0xbf, + 0x69, 0x3c, 0x8c, 0xee, 0x89, 0x7e, 0xed, 0x9c, 0x60, 0x3c, 0x05, 0x86, + 0x2d, 0x95, 0x98, 0x1e, 0x74, 0x44, 0x4e, 0xb4 + }; + static const unsigned char expected_pubnonce_d0[66] = { + 0x02, 0x8b, 0xde, 0xef, 0x70, 0x39, 0x48, 0x77, 0x04, 0xa3, 0xd6, 0xdd, + 0xe6, 0x46, 0xd0, 0x88, 0xe0, 0x29, 0x80, 0x66, 0x96, 0xd4, 0x4a, 0xa0, + 0xd9, 0x75, 0x4a, 0x41, 0xbd, 0x4d, 0x91, 0x6c, 0xd9, 0x03, 0x75, 0xa8, + 0x5e, 0x0b, 0x0a, 0xfe, 0x4a, 0xf7, 0x53, 0xdf, 0x09, 0x5c, 0x0e, 0xc8, + 0x7b, 0xa9, 0x75, 0xfa, 0x74, 0x4e, 0x00, 0x3c, 0x6d, 0x7a, 0xd7, 0x49, + 0xc2, 0x13, 0xb3, 0xc3, 0xc6, 0x1e + }; + static const unsigned char expected_pubnonce_d1[66] = { + 0x02, 0x1e, 0x05, 0xfb, 0xf1, 0xa2, 0x33, 0x08, 0xf8, 0xc5, 0x67, 0xc4, + 0x87, 0x3a, 0x8a, 0xcf, 0x1c, 0x9b, 0xc9, 0x88, 0xcb, 0x18, 0x10, 0x18, + 0x5f, 0xd8, 0x45, 0x06, 0xcd, 0xe2, 0x6d, 0x6c, 0x1c, 0x02, 0x00, 0x4e, + 0x9e, 0x9c, 0xea, 0x6c, 0x1e, 0x11, 0x56, 0x6a, 0x25, 0x2f, 0x12, 0x7d, + 0x52, 0xd7, 0xe4, 0x30, 0xb8, 0xe5, 0xe2, 0x21, 0x24, 0x52, 0x4c, 0x5f, + 0xe7, 0x2f, 0xc1, 0xa0, 0x8e, 0x02 + }; + static const unsigned char expected_psig_d1[32] = { + 0x3d, 0xdd, 0xe1, 0x1e, 0x87, 0xab, 0x4b, 0xd7, 0x3e, 0x65, 0xf3, 0x71, + 0x79, 0x62, 0x23, 0xac, 0x06, 0x1a, 0x13, 0x4f, 0x2a, 0x08, 0xb5, 0xce, + 0x1e, 0x7b, 0x93, 0x8b, 0x14, 0x82, 0x2e, 0x0c + }; + static const unsigned char expected_sig_d[64] = { + 0xaa, 0xd7, 0x30, 0xc9, 0x2e, 0xb6, 0x51, 0x17, 0x59, 0xd7, 0x35, 0x84, + 0x31, 0x15, 0x0d, 0x4a, 0x08, 0x26, 0x47, 0x29, 0xe1, 0xb3, 0x3e, 0x96, + 0x93, 0xbe, 0x5b, 0xf7, 0x8b, 0x06, 0x0a, 0xea, 0xa8, 0xd7, 0xfa, 0xfc, + 0x09, 0x26, 0x3d, 0x80, 0x4b, 0xd3, 0x67, 0x74, 0xe5, 0xcb, 0x33, 0xdd, + 0xaf, 0xd1, 0x90, 0x1b, 0x54, 0x53, 0x3d, 0xb2, 0x43, 0x3b, 0x0f, 0xf7, + 0xcf, 0x0a, 0xcc, 0xda + }; + unsigned char thresh_sk[32]; + unsigned char secshares[3 * 32]; + secp256k1_pubkey thresh_pk; + secp256k1_pubkey pubshares[3]; + secp256k1_frost_tweak_cache cache; + secp256k1_frost_session session; + secp256k1_frost_aggnonce aggnonce; + secp256k1_xonly_pubkey xonly_pk; + unsigned char pk32[32]; + unsigned char buf[66]; + unsigned char sig64[64]; + size_t i; + + for (i = 0; i < 32; i++) { + thresh_sk[i] = (unsigned char)(i + 1); + } + CHECK(secp256k1_frost_trusted_dealer_keygen(CTX, secshares, &thresh_pk, pubshares, 3, 1, thresh_sk) == 1); + CHECK(secp256k1_frost_tweak_cache_init(CTX, &cache, &thresh_pk) == 1); + CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &thresh_pk) == 1); + CHECK(secp256k1_xonly_pubkey_serialize(CTX, pk32, &xonly_pk) == 1); + + /* Case C: sole signer with id = 2, aggothernonce = NULL, aux_rand = + * 0x77...77. */ + { + static const uint32_t ids[1] = { 2 }; + secp256k1_frost_partial_sig psig; + const secp256k1_frost_partial_sig *psig_ptrs[1] = { &psig }; + secp256k1_frost_pubnonce pubnonce; + const secp256k1_frost_pubnonce *pubnonce_ptrs[1] = { &pubnonce }; + unsigned char aux_rand[32]; + + memset(aux_rand, 0x77, 32); + CHECK(secp256k1_frost_deterministic_sign(CTX, &psig, &pubnonce, &secshares[2 * 32], 2, NULL, ids, &pubshares[2], 1, 3, 1, &cache, msg, sizeof(msg) - 1, aux_rand) == 1); + CHECK(secp256k1_frost_pubnonce_serialize(CTX, buf, &pubnonce) == 1); + CHECK(secp256k1_memcmp_var(buf, expected_det_pubnonce_c, 66) == 0); + CHECK(secp256k1_frost_partial_sig_serialize(CTX, buf, &psig) == 1); + CHECK(secp256k1_memcmp_var(buf, expected_det_psig_c, 32) == 0); + + /* The coordinator aggregates the single pubnonce and verifies and + * aggregates the partial signature. */ + CHECK(secp256k1_frost_nonce_agg(CTX, &aggnonce, NULL, pubnonce_ptrs, 1) == 1); + CHECK(secp256k1_frost_session_init(CTX, &session, &aggnonce, ids, &pubshares[2], 1, 3, 1, &cache, msg, sizeof(msg) - 1) == 1); + CHECK(secp256k1_frost_partial_sig_verify(CTX, &psig, &pubnonce, &pubshares[2], &session, ids, 1, 0) == 1); + CHECK(secp256k1_frost_partial_sig_agg(CTX, sig64, NULL, &session, psig_ptrs, 1) == 1); + CHECK(secp256k1_schnorrsig_verify(CTX, sig64, msg, sizeof(msg) - 1, &xonly_pk) == 1); + } + + /* Case D: u = 2, ids = {0, 1}, no aux_rand. Signer 0 uses frost_nonce_gen + * with rand = 0xd0...d0; signer 1 uses frost_deterministic_sign with + * aggothernonce = nonce_agg([pubnonce of signer 0]). */ + { + static const uint32_t ids[2] = { 0, 1 }; + secp256k1_pubkey signer_pubshares[2]; + secp256k1_frost_secnonce secnonce; + secp256k1_frost_pubnonce pubnonce[2]; + const secp256k1_frost_pubnonce *pubnonce_ptrs[2] = { &pubnonce[0], &pubnonce[1] }; + secp256k1_frost_partial_sig psig[2]; + const secp256k1_frost_partial_sig *psig_ptrs[2] = { &psig[0], &psig[1] }; + secp256k1_frost_aggnonce aggothernonce; + unsigned char rand[32]; + + signer_pubshares[0] = pubshares[0]; + signer_pubshares[1] = pubshares[1]; + + memset(rand, 0xd0, 32); + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce, &pubnonce[0], rand, &secshares[0], &pubshares[0], pk32, msg, sizeof(msg) - 1, NULL, 0) == 1); + CHECK(secp256k1_frost_pubnonce_serialize(CTX, buf, &pubnonce[0]) == 1); + CHECK(secp256k1_memcmp_var(buf, expected_pubnonce_d0, 66) == 0); + CHECK(secp256k1_frost_nonce_agg(CTX, &aggothernonce, NULL, pubnonce_ptrs, 1) == 1); + CHECK(secp256k1_frost_deterministic_sign(CTX, &psig[1], &pubnonce[1], &secshares[32], 1, &aggothernonce, ids, signer_pubshares, 2, 3, 1, &cache, msg, sizeof(msg) - 1, NULL) == 1); + CHECK(secp256k1_frost_pubnonce_serialize(CTX, buf, &pubnonce[1]) == 1); + CHECK(secp256k1_memcmp_var(buf, expected_pubnonce_d1, 66) == 0); + CHECK(secp256k1_frost_partial_sig_serialize(CTX, buf, &psig[1]) == 1); + CHECK(secp256k1_memcmp_var(buf, expected_psig_d1, 32) == 0); + + CHECK(secp256k1_frost_nonce_agg(CTX, &aggnonce, NULL, pubnonce_ptrs, 2) == 1); + CHECK(secp256k1_frost_session_init(CTX, &session, &aggnonce, ids, signer_pubshares, 2, 3, 1, &cache, msg, sizeof(msg) - 1) == 1); + CHECK(secp256k1_frost_sign(CTX, &psig[0], &secnonce, &secshares[0], &session, ids, signer_pubshares, 2, 0) == 1); + CHECK(secp256k1_frost_partial_sig_verify(CTX, &psig[0], &pubnonce[0], &signer_pubshares[0], &session, ids, 2, 0) == 1); + CHECK(secp256k1_frost_partial_sig_verify(CTX, &psig[1], &pubnonce[1], &signer_pubshares[1], &session, ids, 2, 1) == 1); + CHECK(secp256k1_frost_partial_sig_agg(CTX, sig64, NULL, &session, psig_ptrs, 2) == 1); + CHECK(secp256k1_memcmp_var(sig64, expected_sig_d, 64) == 0); + CHECK(secp256k1_schnorrsig_verify(CTX, sig64, msg, sizeof(msg) - 1, &xonly_pk) == 1); + } +} + +#define FROST_SIGN_TEST_MAX_N 8 + +/* Runs a randomized full signing round: trusted-dealer keygen, random signer + * subset, random tweak chain (xonly and plain), random message length + * (including 0 and > 32), nonce gen/agg, session init, sign, partial sig + * verify and aggregation with a final BIP340 verification against the tweaked + * threshold public key. Also covers the failure paths of the signing API. */ +static void frost_sign_test_internal(void) { + unsigned char thresh_sk[32]; + unsigned char secshares[FROST_SIGN_TEST_MAX_N * 32]; + secp256k1_pubkey thresh_pk; + secp256k1_pubkey pubshares[FROST_SIGN_TEST_MAX_N]; + secp256k1_pubkey signer_pubshares[FROST_SIGN_TEST_MAX_N]; + uint32_t ids_all[FROST_SIGN_TEST_MAX_N]; + uint32_t ids[FROST_SIGN_TEST_MAX_N]; + secp256k1_frost_secnonce secnonce[FROST_SIGN_TEST_MAX_N]; + secp256k1_frost_pubnonce pubnonce[FROST_SIGN_TEST_MAX_N]; + const secp256k1_frost_pubnonce *pubnonce_ptrs[FROST_SIGN_TEST_MAX_N]; + secp256k1_frost_partial_sig psig[FROST_SIGN_TEST_MAX_N]; + const secp256k1_frost_partial_sig *psig_ptrs[FROST_SIGN_TEST_MAX_N]; + secp256k1_frost_aggnonce aggnonce; + secp256k1_frost_tweak_cache cache; + secp256k1_frost_session session; + secp256k1_xonly_pubkey tweaked_pk; + unsigned char msg[64]; + unsigned char rand[32]; + unsigned char pk32[32]; + unsigned char sig64[64]; + size_t n = 1 + testrand_int(FROST_SIGN_TEST_MAX_N); + uint32_t t = 1 + testrand_int((uint32_t)n); + size_t u = (size_t)t + testrand_int((uint32_t)(n - t + 1)); + size_t msglen = testrand_int(sizeof(msg) + 1); + int with_pubshares = testrand_bits(1); + size_t i; + int j; + + testutil_random_scalar_order_b32(thresh_sk); + testrand256(msg); + testrand256(&msg[32]); + CHECK(secp256k1_frost_trusted_dealer_keygen(CTX, secshares, &thresh_pk, pubshares, n, t, thresh_sk) == 1); + + /* Random signer subset via Fisher-Yates shuffle. */ + for (i = 0; i < n; i++) { + ids_all[i] = (uint32_t)i; + } + for (i = 0; i < n; i++) { + size_t sj = i + testrand_int((uint32_t)(n - i)); + uint32_t tmp = ids_all[i]; + ids_all[i] = ids_all[sj]; + ids_all[sj] = tmp; + } + for (i = 0; i < u; i++) { + ids[i] = ids_all[i]; + signer_pubshares[i] = pubshares[ids[i]]; + pubnonce_ptrs[i] = &pubnonce[i]; + psig_ptrs[i] = &psig[i]; + } + + /* Random tweak chain of up to 3 xonly/plain tweaks. */ + CHECK(secp256k1_frost_tweak_cache_init(CTX, &cache, &thresh_pk) == 1); + for (j = 0; j < 3; j++) { + unsigned char tweak[32]; + if (testrand_bits(2) == 0) { + continue; + } + testrand256(tweak); + if (testrand_bits(1)) { + CHECK(secp256k1_frost_pubkey_xonly_tweak_add(CTX, NULL, &cache, tweak) == 1); + } else { + CHECK(secp256k1_frost_pubkey_ec_tweak_add(CTX, NULL, &cache, tweak) == 1); + } + } + CHECK(secp256k1_frost_tweaked_pubkey_get(CTX, &tweaked_pk, &cache) == 1); + CHECK(secp256k1_xonly_pubkey_serialize(CTX, pk32, &tweaked_pk) == 1); + + /* Full signing round. */ + for (i = 0; i < u; i++) { + testrand256(rand); + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce[i], &pubnonce[i], rand, &secshares[32 * ids[i]], &signer_pubshares[i], pk32, msg, msglen, NULL, 0) == 1); + } + CHECK(secp256k1_frost_nonce_agg(CTX, &aggnonce, NULL, pubnonce_ptrs, u) == 1); + CHECK(secp256k1_frost_session_init(CTX, &session, &aggnonce, ids, with_pubshares ? signer_pubshares : NULL, u, n, t, &cache, msg, msglen) == 1); + for (i = 0; i < u; i++) { + CHECK(secp256k1_frost_sign(CTX, &psig[i], &secnonce[i], &secshares[32 * ids[i]], &session, ids, with_pubshares ? signer_pubshares : NULL, u, ids[i]) == 1); + CHECK(secp256k1_frost_partial_sig_verify(CTX, &psig[i], &pubnonce[i], &signer_pubshares[i], &session, ids, u, i) == 1); + } + CHECK(secp256k1_frost_partial_sig_agg(CTX, sig64, NULL, &session, psig_ptrs, u) == 1); + CHECK(secp256k1_schnorrsig_verify(CTX, sig64, msg, msglen, &tweaked_pk) == 1); + + /* A corrupted partial signature does not verify and invalidates the + * aggregate signature. */ + { + secp256k1_frost_partial_sig psig_corrupt; + const secp256k1_frost_partial_sig *corrupt_ptrs[FROST_SIGN_TEST_MAX_N]; + + memcpy(&psig_corrupt, &psig[0], sizeof(psig_corrupt)); + psig_corrupt.data[sizeof(psig_corrupt.data) - 1] ^= 1; + for (i = 0; i < u; i++) { + corrupt_ptrs[i] = psig_ptrs[i]; + } + corrupt_ptrs[0] = &psig_corrupt; + CHECK(secp256k1_frost_partial_sig_verify(CTX, &psig_corrupt, &pubnonce[0], &signer_pubshares[0], &session, ids, u, 0) == 0); + CHECK(secp256k1_frost_partial_sig_agg(CTX, sig64, NULL, &session, corrupt_ptrs, u) == 1); + CHECK(secp256k1_schnorrsig_verify(CTX, sig64, msg, msglen, &tweaked_pk) == 0); + } + + /* A missing contribution (a partial signature replaced by a duplicate of + * another one) invalidates the aggregate signature. */ + if (u > 1) { + const secp256k1_frost_partial_sig *dup_ptrs[FROST_SIGN_TEST_MAX_N]; + + for (i = 0; i < u; i++) { + dup_ptrs[i] = psig_ptrs[i]; + } + dup_ptrs[1] = &psig[0]; + CHECK(secp256k1_frost_partial_sig_agg(CTX, sig64, NULL, &session, dup_ptrs, u) == 1); + CHECK(secp256k1_schnorrsig_verify(CTX, sig64, msg, msglen, &tweaked_pk) == 0); + } + + /* Signing with a wrong secret share fails when the pubshares are + * given. */ + { + unsigned char wrong_share[32]; + secp256k1_frost_secnonce secnonce_tmp; + secp256k1_frost_pubnonce pubnonce_tmp; + + testutil_random_scalar_order_b32(wrong_share); + testrand256(rand); + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce_tmp, &pubnonce_tmp, rand, &secshares[32 * ids[0]], &signer_pubshares[0], pk32, msg, msglen, NULL, 0) == 1); + /* wrong_share equals the actual share with negligible probability */ + CHECK(secp256k1_frost_sign(CTX, &psig[0], &secnonce_tmp, wrong_share, &session, ids, signer_pubshares, u, ids[0]) == 0); + } + + /* A signer whose id is not in the signer set cannot sign. */ + if (u < n) { + secp256k1_frost_secnonce secnonce_tmp; + secp256k1_frost_pubnonce pubnonce_tmp; + + testrand256(rand); + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce_tmp, &pubnonce_tmp, rand, NULL, NULL, pk32, msg, msglen, NULL, 0) == 1); + CHECK(secp256k1_frost_sign(CTX, &psig[0], &secnonce_tmp, &secshares[32 * ids_all[u]], &session, ids, NULL, u, ids_all[u]) == 0); + } + + /* Signing wipes the secnonce; reusing it fails. */ + { + secp256k1_frost_secnonce secnonce_tmp; + secp256k1_frost_pubnonce pubnonce_tmp; + + testrand256(rand); + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce_tmp, &pubnonce_tmp, rand, &secshares[32 * ids[0]], &signer_pubshares[0], pk32, msg, msglen, NULL, 0) == 1); + CHECK(secp256k1_frost_sign(CTX, &psig[0], &secnonce_tmp, &secshares[32 * ids[0]], &session, ids, signer_pubshares, u, ids[0]) == 1); + CHECK(secp256k1_is_zero_array(secnonce_tmp.data, sizeof(secnonce_tmp.data))); + CHECK_ILLEGAL(CTX, secp256k1_frost_sign(CTX, &psig[0], &secnonce_tmp, &secshares[32 * ids[0]], &session, ids, signer_pubshares, u, ids[0])); + } + + /* session_init rejects invalid session parameters. */ + { + secp256k1_frost_session session_tmp; + uint32_t ids_bad[FROST_SIGN_TEST_MAX_N]; + + /* Duplicate signer ids. */ + if (u > 1) { + memcpy(ids_bad, ids, u * sizeof(uint32_t)); + ids_bad[1] = ids_bad[0]; + CHECK(secp256k1_frost_session_init(CTX, &session_tmp, &aggnonce, ids_bad, NULL, u, n, t, &cache, msg, msglen) == 0); + } + /* A signer id out of range. */ + memcpy(ids_bad, ids, u * sizeof(uint32_t)); + ids_bad[0] = (uint32_t)n; + CHECK(secp256k1_frost_session_init(CTX, &session_tmp, &aggnonce, ids_bad, NULL, u, n, t, &cache, msg, msglen) == 0); + /* Fewer than t signers. */ + if (t > 1) { + CHECK(secp256k1_frost_session_init(CTX, &session_tmp, &aggnonce, ids, NULL, t - 1, n, t, &cache, msg, msglen) == 0); + } + /* n > SECP256K1_FROST_MAX_PARTICIPANTS. */ + { + uint32_t one_id = 0; + CHECK(secp256k1_frost_session_init(CTX, &session_tmp, &aggnonce, &one_id, NULL, 1, SECP256K1_FROST_MAX_PARTICIPANTS + 1, 1, &cache, msg, msglen) == 0); + } + /* Pubshares that do not match the threshold public key. */ + { + secp256k1_pubkey bad_pubshares[FROST_SIGN_TEST_MAX_N]; + secp256k1_pubkey random_pk; + unsigned char random_sk[32]; + + for (i = 0; i < u; i++) { + bad_pubshares[i] = signer_pubshares[i]; + } + testutil_random_scalar_order_b32(random_sk); + CHECK(secp256k1_ec_pubkey_create(CTX, &random_pk, random_sk) == 1); + bad_pubshares[0] = random_pk; + CHECK(secp256k1_frost_session_init(CTX, &session_tmp, &aggnonce, ids, bad_pubshares, u, n, t, &cache, msg, msglen) == 0); + } + } + + /* Deterministic signing produces a pubnonce and partial signature that + * are consistent with a session built from them. */ + { + secp256k1_frost_partial_sig det_psig; + const secp256k1_frost_partial_sig *det_psig_ptrs[1] = { &det_psig }; + secp256k1_frost_pubnonce det_pubnonce; + const secp256k1_frost_pubnonce *det_pubnonce_ptrs[FROST_SIGN_TEST_MAX_N]; + secp256k1_frost_aggnonce det_aggnonce; + secp256k1_frost_session det_session; + unsigned char aux_rand[32]; + + det_pubnonce_ptrs[0] = &det_pubnonce; + for (i = 1; i < u; i++) { + det_pubnonce_ptrs[i] = &pubnonce[i]; + } + testrand256(aux_rand); + if (u == 1) { + CHECK(secp256k1_frost_deterministic_sign(CTX, &det_psig, &det_pubnonce, &secshares[32 * ids[0]], ids[0], NULL, ids, signer_pubshares, u, n, t, &cache, msg, msglen, aux_rand) == 1); + } else { + secp256k1_frost_aggnonce aggothernonce; + CHECK(secp256k1_frost_nonce_agg(CTX, &aggothernonce, NULL, &pubnonce_ptrs[1], u - 1) == 1); + CHECK(secp256k1_frost_deterministic_sign(CTX, &det_psig, &det_pubnonce, &secshares[32 * ids[0]], ids[0], &aggothernonce, ids, signer_pubshares, u, n, t, &cache, msg, msglen, aux_rand) == 1); + } + CHECK(secp256k1_frost_nonce_agg(CTX, &det_aggnonce, NULL, det_pubnonce_ptrs, u) == 1); + CHECK(secp256k1_frost_session_init(CTX, &det_session, &det_aggnonce, ids, signer_pubshares, u, n, t, &cache, msg, msglen) == 1); + CHECK(secp256k1_frost_partial_sig_verify(CTX, &det_psig, &det_pubnonce, &signer_pubshares[0], &det_session, ids, u, 0) == 1); + if (u == 1) { + /* A sole deterministic signer produces a full valid signature. */ + CHECK(secp256k1_frost_partial_sig_agg(CTX, sig64, NULL, &det_session, det_psig_ptrs, 1) == 1); + CHECK(secp256k1_schnorrsig_verify(CTX, sig64, msg, msglen, &tweaked_pk) == 1); + } + } + + /* partial_sig_verify rejects an out-of-range signer index, and + * partial_sig_agg rejects a wrong number of partial signatures and a + * NULL element (reporting its index). */ + CHECK(secp256k1_frost_partial_sig_verify(CTX, &psig[0], &pubnonce[0], &signer_pubshares[0], &session, ids, u, u) == 0); + CHECK(secp256k1_frost_partial_sig_agg(CTX, sig64, NULL, &session, psig_ptrs, u + 1) == 0); + if (u > 1) { + CHECK(secp256k1_frost_partial_sig_agg(CTX, sig64, NULL, &session, psig_ptrs, u - 1) == 0); + } + { + const secp256k1_frost_partial_sig *null_ptrs[FROST_SIGN_TEST_MAX_N]; + size_t null_index = testrand_int((uint32_t)u); + size_t error_index = 0xFF; + + for (i = 0; i < u; i++) { + null_ptrs[i] = psig_ptrs[i]; + } + null_ptrs[null_index] = NULL; + CHECK(secp256k1_frost_partial_sig_agg(CTX, sig64, &error_index, &session, null_ptrs, u) == 0); + CHECK(error_index == null_index); + CHECK(secp256k1_frost_partial_sig_agg(CTX, sig64, NULL, &session, null_ptrs, u) == 0); + } + + /* NULL and invalid argument coverage. */ + { + secp256k1_frost_secnonce secnonce_tmp; + secp256k1_frost_pubnonce pubnonce_tmp; + secp256k1_frost_partial_sig psig_tmp; + secp256k1_frost_session session_tmp, invalid_session; + secp256k1_frost_aggnonce invalid_aggnonce; + secp256k1_frost_tweak_cache invalid_cache; + + memset(&invalid_session, 0, sizeof(invalid_session)); + memset(&invalid_aggnonce, 0, sizeof(invalid_aggnonce)); + memset(&invalid_cache, 0, sizeof(invalid_cache)); + + /* session_init */ + CHECK_ILLEGAL(CTX, secp256k1_frost_session_init(CTX, NULL, &aggnonce, ids, NULL, u, n, t, &cache, msg, msglen)); + CHECK_ILLEGAL(CTX, secp256k1_frost_session_init(CTX, &session_tmp, NULL, ids, NULL, u, n, t, &cache, msg, msglen)); + CHECK_ILLEGAL(CTX, secp256k1_frost_session_init(CTX, &session_tmp, &invalid_aggnonce, ids, NULL, u, n, t, &cache, msg, msglen)); + CHECK_ILLEGAL(CTX, secp256k1_frost_session_init(CTX, &session_tmp, &aggnonce, NULL, NULL, u, n, t, &cache, msg, msglen)); + CHECK_ILLEGAL(CTX, secp256k1_frost_session_init(CTX, &session_tmp, &aggnonce, ids, NULL, u, n, t, NULL, msg, msglen)); + CHECK_ILLEGAL(CTX, secp256k1_frost_session_init(CTX, &session_tmp, &aggnonce, ids, NULL, u, n, t, &invalid_cache, msg, msglen)); + CHECK_ILLEGAL(CTX, secp256k1_frost_session_init(CTX, &session_tmp, &aggnonce, ids, NULL, u, n, t, &cache, NULL, msglen)); + + /* sign: every call that reaches the secnonce load wipes the secnonce, + * so a fresh one is generated before each call. */ + testrand256(rand); + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce_tmp, &pubnonce_tmp, rand, NULL, NULL, NULL, NULL, 0, NULL, 0) == 1); + CHECK_ILLEGAL(CTX, secp256k1_frost_sign(CTX, NULL, &secnonce_tmp, &secshares[32 * ids[0]], &session, ids, NULL, u, ids[0])); + CHECK_ILLEGAL(CTX, secp256k1_frost_sign(CTX, &psig_tmp, NULL, &secshares[32 * ids[0]], &session, ids, NULL, u, ids[0])); + testrand256(rand); + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce_tmp, &pubnonce_tmp, rand, NULL, NULL, NULL, NULL, 0, NULL, 0) == 1); + CHECK_ILLEGAL(CTX, secp256k1_frost_sign(CTX, &psig_tmp, &secnonce_tmp, NULL, &session, ids, NULL, u, ids[0])); + testrand256(rand); + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce_tmp, &pubnonce_tmp, rand, NULL, NULL, NULL, NULL, 0, NULL, 0) == 1); + CHECK_ILLEGAL(CTX, secp256k1_frost_sign(CTX, &psig_tmp, &secnonce_tmp, &secshares[32 * ids[0]], NULL, ids, NULL, u, ids[0])); + testrand256(rand); + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce_tmp, &pubnonce_tmp, rand, NULL, NULL, NULL, NULL, 0, NULL, 0) == 1); + CHECK_ILLEGAL(CTX, secp256k1_frost_sign(CTX, &psig_tmp, &secnonce_tmp, &secshares[32 * ids[0]], &invalid_session, ids, NULL, u, ids[0])); + testrand256(rand); + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce_tmp, &pubnonce_tmp, rand, NULL, NULL, NULL, NULL, 0, NULL, 0) == 1); + CHECK_ILLEGAL(CTX, secp256k1_frost_sign(CTX, &psig_tmp, &secnonce_tmp, &secshares[32 * ids[0]], &session, NULL, NULL, u, ids[0])); + /* A zeroed (already used) secnonce is detected. */ + memset(&secnonce_tmp, 0, sizeof(secnonce_tmp)); + CHECK_ILLEGAL(CTX, secp256k1_frost_sign(CTX, &psig_tmp, &secnonce_tmp, &secshares[32 * ids[0]], &session, ids, NULL, u, ids[0])); + + /* partial_sig_verify */ + CHECK_ILLEGAL(CTX, secp256k1_frost_partial_sig_verify(CTX, NULL, &pubnonce[0], &signer_pubshares[0], &session, ids, u, 0)); + CHECK_ILLEGAL(CTX, secp256k1_frost_partial_sig_verify(CTX, &psig[0], NULL, &signer_pubshares[0], &session, ids, u, 0)); + CHECK_ILLEGAL(CTX, secp256k1_frost_partial_sig_verify(CTX, &psig[0], &pubnonce[0], NULL, &session, ids, u, 0)); + CHECK_ILLEGAL(CTX, secp256k1_frost_partial_sig_verify(CTX, &psig[0], &pubnonce[0], &signer_pubshares[0], NULL, ids, u, 0)); + CHECK_ILLEGAL(CTX, secp256k1_frost_partial_sig_verify(CTX, &psig[0], &pubnonce[0], &signer_pubshares[0], &invalid_session, ids, u, 0)); + CHECK_ILLEGAL(CTX, secp256k1_frost_partial_sig_verify(CTX, &psig[0], &pubnonce[0], &signer_pubshares[0], &session, NULL, u, 0)); + + /* partial_sig_agg */ + CHECK_ILLEGAL(CTX, secp256k1_frost_partial_sig_agg(CTX, NULL, NULL, &session, psig_ptrs, u)); + CHECK_ILLEGAL(CTX, secp256k1_frost_partial_sig_agg(CTX, sig64, NULL, NULL, psig_ptrs, u)); + CHECK_ILLEGAL(CTX, secp256k1_frost_partial_sig_agg(CTX, sig64, NULL, &invalid_session, psig_ptrs, u)); + CHECK_ILLEGAL(CTX, secp256k1_frost_partial_sig_agg(CTX, sig64, NULL, &session, NULL, u)); + + /* deterministic_sign */ + CHECK_ILLEGAL(CTX, secp256k1_frost_deterministic_sign(CTX, NULL, &pubnonce_tmp, &secshares[32 * ids[0]], ids[0], NULL, ids, NULL, u, n, t, &cache, msg, msglen, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_frost_deterministic_sign(CTX, &psig_tmp, NULL, &secshares[32 * ids[0]], ids[0], NULL, ids, NULL, u, n, t, &cache, msg, msglen, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_frost_deterministic_sign(CTX, &psig_tmp, &pubnonce_tmp, NULL, ids[0], NULL, ids, NULL, u, n, t, &cache, msg, msglen, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_frost_deterministic_sign(CTX, &psig_tmp, &pubnonce_tmp, &secshares[32 * ids[0]], ids[0], NULL, NULL, NULL, u, n, t, &cache, msg, msglen, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_frost_deterministic_sign(CTX, &psig_tmp, &pubnonce_tmp, &secshares[32 * ids[0]], ids[0], NULL, ids, NULL, u, n, t, NULL, msg, msglen, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_frost_deterministic_sign(CTX, &psig_tmp, &pubnonce_tmp, &secshares[32 * ids[0]], ids[0], NULL, ids, NULL, u, n, t, &invalid_cache, msg, msglen, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_frost_deterministic_sign(CTX, &psig_tmp, &pubnonce_tmp, &secshares[32 * ids[0]], ids[0], NULL, ids, NULL, u, n, t, &cache, NULL, msglen, NULL)); + } +} +REPEAT_TEST(frost_sign_test) + +/* Runs a full signing round (nonce_gen, nonce_agg, session_init, sign, + * partial_sig_verify, partial_sig_agg) with the signers 0..n_signers-1 and + * BIP340-verifies the final signature against the tweaked threshold public + * key of the given tweak cache. */ +static void frost_run_signing_round(const unsigned char *secshares, const secp256k1_pubkey *pubshares, const secp256k1_frost_tweak_cache *cache, size_t n_participants, uint32_t threshold, size_t n_signers, const unsigned char *msg, size_t msglen) { + secp256k1_frost_secnonce secnonce[SECP256K1_FROST_MAX_PARTICIPANTS]; + secp256k1_frost_pubnonce pubnonce[SECP256K1_FROST_MAX_PARTICIPANTS]; + const secp256k1_frost_pubnonce *pubnonce_ptrs[SECP256K1_FROST_MAX_PARTICIPANTS]; + secp256k1_frost_partial_sig psig[SECP256K1_FROST_MAX_PARTICIPANTS]; + const secp256k1_frost_partial_sig *psig_ptrs[SECP256K1_FROST_MAX_PARTICIPANTS]; + secp256k1_pubkey signer_pubshares[SECP256K1_FROST_MAX_PARTICIPANTS]; + uint32_t ids[SECP256K1_FROST_MAX_PARTICIPANTS]; + secp256k1_frost_aggnonce aggnonce; + secp256k1_frost_session session; + secp256k1_xonly_pubkey tweaked_pk; + unsigned char rand[32]; + unsigned char pk32[32]; + unsigned char sig64[64]; + size_t i; + + CHECK(n_signers >= (size_t)threshold && (size_t)threshold <= n_participants); + CHECK(n_signers <= n_participants && n_participants <= SECP256K1_FROST_MAX_PARTICIPANTS); + CHECK(secp256k1_frost_tweaked_pubkey_get(CTX, &tweaked_pk, cache) == 1); + CHECK(secp256k1_xonly_pubkey_serialize(CTX, pk32, &tweaked_pk) == 1); + for (i = 0; i < n_signers; i++) { + ids[i] = (uint32_t)i; + signer_pubshares[i] = pubshares[i]; + pubnonce_ptrs[i] = &pubnonce[i]; + psig_ptrs[i] = &psig[i]; + testrand256(rand); + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce[i], &pubnonce[i], rand, &secshares[32 * i], &signer_pubshares[i], pk32, msg, msglen, NULL, 0) == 1); + } + CHECK(secp256k1_frost_nonce_agg(CTX, &aggnonce, NULL, pubnonce_ptrs, n_signers) == 1); + CHECK(secp256k1_frost_session_init(CTX, &session, &aggnonce, ids, signer_pubshares, n_signers, n_participants, threshold, cache, msg, msglen) == 1); + for (i = 0; i < n_signers; i++) { + CHECK(secp256k1_frost_sign(CTX, &psig[i], &secnonce[i], &secshares[32 * i], &session, ids, signer_pubshares, n_signers, ids[i]) == 1); + CHECK(secp256k1_frost_partial_sig_verify(CTX, &psig[i], &pubnonce[i], &signer_pubshares[i], &session, ids, n_signers, i) == 1); + } + CHECK(secp256k1_frost_partial_sig_agg(CTX, sig64, NULL, &session, psig_ptrs, n_signers) == 1); + CHECK(secp256k1_schnorrsig_verify(CTX, sig64, msg, msglen, &tweaked_pk) == 1); +} + +/* NULL/invalid argument and parse/serialize coverage for the module API + * functions not covered by the other tests: trusted_dealer_keygen, + * threshold_info_validate, the pubnonce, aggnonce and partial_sig + * serialize/parse functions, and nonce_gen with an invalid pubshare. */ +static void frost_api_test(void) { + /* The curve order n; a threshold secret key or partial signature >= n is + * out of range. */ + static const unsigned char order32[32] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, + 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41 + }; + unsigned char thresh_sk[32]; + unsigned char zero32[32] = { 0 }; + unsigned char secshares[3 * 32]; + secp256k1_pubkey thresh_pk; + secp256k1_pubkey pubshares[3]; + secp256k1_pubkey invalid_pk; + secp256k1_frost_secnonce secnonce; + secp256k1_frost_pubnonce pubnonce, parsed_pubnonce, invalid_pubnonce; + secp256k1_frost_aggnonce aggnonce, parsed_aggnonce, invalid_aggnonce; + secp256k1_frost_partial_sig psig, parsed_psig, invalid_psig; + unsigned char buf66[66]; + unsigned char buf32[32]; + unsigned char rand[32]; + + memset(&invalid_pk, 0, sizeof(invalid_pk)); + memset(&invalid_pubnonce, 0, sizeof(invalid_pubnonce)); + memset(&invalid_aggnonce, 0, sizeof(invalid_aggnonce)); + memset(&invalid_psig, 0, sizeof(invalid_psig)); + + testutil_random_scalar_order_b32(thresh_sk); + CHECK(secp256k1_frost_trusted_dealer_keygen(CTX, secshares, &thresh_pk, pubshares, 3, 2, thresh_sk) == 1); + + /* trusted_dealer_keygen: NULL arguments, and threshold secret keys that + * are zero or out of range (the outputs are zeroed on failure). */ + CHECK_ILLEGAL(CTX, secp256k1_frost_trusted_dealer_keygen(CTX, NULL, &thresh_pk, pubshares, 3, 2, thresh_sk)); + CHECK_ILLEGAL(CTX, secp256k1_frost_trusted_dealer_keygen(CTX, secshares, NULL, pubshares, 3, 2, thresh_sk)); + CHECK_ILLEGAL(CTX, secp256k1_frost_trusted_dealer_keygen(CTX, secshares, &thresh_pk, NULL, 3, 2, thresh_sk)); + CHECK_ILLEGAL(CTX, secp256k1_frost_trusted_dealer_keygen(CTX, secshares, &thresh_pk, pubshares, 3, 2, NULL)); + CHECK(secp256k1_frost_trusted_dealer_keygen(CTX, secshares, &thresh_pk, pubshares, 3, 2, zero32) == 0); + CHECK(secp256k1_is_zero_array(secshares, sizeof(secshares))); + CHECK(secp256k1_frost_trusted_dealer_keygen(CTX, secshares, &thresh_pk, pubshares, 3, 2, order32) == 0); + /* Re-run keygen for the tests below (the failed calls zeroed the outputs). */ + CHECK(secp256k1_frost_trusted_dealer_keygen(CTX, secshares, &thresh_pk, pubshares, 3, 2, thresh_sk) == 1); + + /* threshold_info_validate: NULL arguments and corrupted pubkeys (a zeroed + * pubkey fails in pubkey_load, triggering the illegal-argument + * callback). */ + CHECK_ILLEGAL(CTX, secp256k1_frost_threshold_info_validate(CTX, NULL, pubshares, 3, 2)); + CHECK_ILLEGAL(CTX, secp256k1_frost_threshold_info_validate(CTX, &thresh_pk, NULL, 3, 2)); + CHECK_ILLEGAL(CTX, secp256k1_frost_threshold_info_validate(CTX, &invalid_pk, pubshares, 3, 2)); + { + secp256k1_pubkey bad_pubshares[3]; + memcpy(bad_pubshares, pubshares, sizeof(bad_pubshares)); + bad_pubshares[1] = invalid_pk; + CHECK_ILLEGAL(CTX, secp256k1_frost_threshold_info_validate(CTX, &thresh_pk, bad_pubshares, 3, 2)); + } + + /* nonce_gen rejects an invalid pubshare (and wipes the session + * randomness). */ + testrand256(rand); + CHECK_ILLEGAL(CTX, secp256k1_frost_nonce_gen(CTX, &secnonce, &pubnonce, rand, NULL, &invalid_pk, NULL, NULL, 0, NULL, 0)); + CHECK(secp256k1_is_zero_array(rand, 32)); + + /* pubnonce parse/serialize. */ + testrand256(rand); + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce, &pubnonce, rand, NULL, NULL, NULL, NULL, 0, NULL, 0) == 1); + CHECK_ILLEGAL(CTX, secp256k1_frost_pubnonce_parse(CTX, NULL, buf66)); + CHECK_ILLEGAL(CTX, secp256k1_frost_pubnonce_parse(CTX, &parsed_pubnonce, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_frost_pubnonce_serialize(CTX, NULL, &pubnonce)); + CHECK_ILLEGAL(CTX, secp256k1_frost_pubnonce_serialize(CTX, buf66, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_frost_pubnonce_serialize(CTX, buf66, &invalid_pubnonce)); + /* A component with an invalid encoding is rejected. */ + memset(buf66, 0xff, 66); + CHECK(secp256k1_frost_pubnonce_parse(CTX, &parsed_pubnonce, buf66) == 0); + + /* aggnonce parse/serialize, including a round-trip. */ + { + const secp256k1_frost_pubnonce *pubnonce_ptrs[1]; + secp256k1_ge ges[2], ges_parsed[2]; + int j; + + pubnonce_ptrs[0] = &pubnonce; + CHECK(secp256k1_frost_nonce_agg(CTX, &aggnonce, NULL, pubnonce_ptrs, 1) == 1); + CHECK_ILLEGAL(CTX, secp256k1_frost_aggnonce_parse(CTX, NULL, buf66)); + CHECK_ILLEGAL(CTX, secp256k1_frost_aggnonce_parse(CTX, &parsed_aggnonce, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_frost_aggnonce_serialize(CTX, NULL, &aggnonce)); + CHECK_ILLEGAL(CTX, secp256k1_frost_aggnonce_serialize(CTX, buf66, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_frost_aggnonce_serialize(CTX, buf66, &invalid_aggnonce)); + memset(buf66, 0xff, 66); + CHECK(secp256k1_frost_aggnonce_parse(CTX, &parsed_aggnonce, buf66) == 0); + /* A serialize/parse round-trip preserves the aggregate nonce. */ + CHECK(secp256k1_frost_aggnonce_serialize(CTX, buf66, &aggnonce) == 1); + CHECK(secp256k1_frost_aggnonce_parse(CTX, &parsed_aggnonce, buf66) == 1); + CHECK(secp256k1_frost_aggnonce_load(CTX, ges, &aggnonce) == 1); + CHECK(secp256k1_frost_aggnonce_load(CTX, ges_parsed, &parsed_aggnonce) == 1); + for (j = 0; j < 2; j++) { + CHECK(secp256k1_ge_eq_var(&ges[j], &ges_parsed[j])); + } + } + + /* partial_sig parse/serialize, including a round-trip. */ + { + secp256k1_scalar s, s_parsed; + + testutil_random_scalar_order(&s); + secp256k1_frost_partial_sig_save(&psig, &s); + CHECK_ILLEGAL(CTX, secp256k1_frost_partial_sig_parse(CTX, NULL, buf32)); + CHECK_ILLEGAL(CTX, secp256k1_frost_partial_sig_parse(CTX, &parsed_psig, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_frost_partial_sig_serialize(CTX, NULL, &psig)); + CHECK_ILLEGAL(CTX, secp256k1_frost_partial_sig_serialize(CTX, buf32, NULL)); + CHECK_ILLEGAL(CTX, secp256k1_frost_partial_sig_serialize(CTX, buf32, &invalid_psig)); + /* Malformed/overflowing partial signature bytes fail to parse. */ + CHECK(secp256k1_frost_partial_sig_parse(CTX, &parsed_psig, order32) == 0); + memset(buf32, 0xff, 32); + CHECK(secp256k1_frost_partial_sig_parse(CTX, &parsed_psig, buf32) == 0); + /* A serialize/parse round-trip preserves the scalar. */ + CHECK(secp256k1_frost_partial_sig_serialize(CTX, buf32, &psig) == 1); + CHECK(secp256k1_frost_partial_sig_parse(CTX, &parsed_psig, buf32) == 1); + CHECK(secp256k1_frost_partial_sig_load(CTX, &s_parsed, &parsed_psig) == 1); + CHECK(secp256k1_scalar_eq(&s, &s_parsed)); + secp256k1_scalar_clear(&s); + secp256k1_scalar_clear(&s_parsed); + } +} + +/* Boundary test: keygen and a full signing round with n = + * SECP256K1_FROST_MAX_PARTICIPANTS (128), the rejection of n = 129, and the + * threshold extremes t = 1 and t = n. */ +static void frost_boundary_test(void) { + unsigned char thresh_sk[32]; + unsigned char secshares[SECP256K1_FROST_MAX_PARTICIPANTS * 32]; + secp256k1_pubkey thresh_pk; + secp256k1_pubkey pubshares[SECP256K1_FROST_MAX_PARTICIPANTS]; + secp256k1_frost_tweak_cache cache; + unsigned char msg[32]; + + testrand256(msg); + testutil_random_scalar_order_b32(thresh_sk); + + /* n = SECP256K1_FROST_MAX_PARTICIPANTS (128): keygen, validation and a + * signing round with u = t = 64. */ + CHECK(secp256k1_frost_trusted_dealer_keygen(CTX, secshares, &thresh_pk, pubshares, SECP256K1_FROST_MAX_PARTICIPANTS, 64, thresh_sk) == 1); + CHECK(secp256k1_frost_threshold_info_validate(CTX, &thresh_pk, pubshares, SECP256K1_FROST_MAX_PARTICIPANTS, 64) == 1); + CHECK(secp256k1_frost_tweak_cache_init(CTX, &cache, &thresh_pk) == 1); + frost_run_signing_round(secshares, pubshares, &cache, SECP256K1_FROST_MAX_PARTICIPANTS, 64, 64, msg, sizeof(msg)); + + /* n = 129 exceeds the maximum and is rejected (both functions return + * before touching the arrays). */ + CHECK(secp256k1_frost_trusted_dealer_keygen(CTX, secshares, &thresh_pk, pubshares, SECP256K1_FROST_MAX_PARTICIPANTS + 1, 1, thresh_sk) == 0); + CHECK(secp256k1_frost_threshold_info_validate(CTX, &thresh_pk, pubshares, SECP256K1_FROST_MAX_PARTICIPANTS + 1, 1) == 0); + + /* t = 1, including a solo signer (u = 1) going through the full + * nonce_gen/nonce_agg/session_init/sign/agg pipeline (not just + * deterministic_sign). */ + CHECK(secp256k1_frost_trusted_dealer_keygen(CTX, secshares, &thresh_pk, pubshares, 4, 1, thresh_sk) == 1); + CHECK(secp256k1_frost_tweak_cache_init(CTX, &cache, &thresh_pk) == 1); + frost_run_signing_round(secshares, pubshares, &cache, 4, 1, 1, msg, sizeof(msg)); + frost_run_signing_round(secshares, pubshares, &cache, 4, 1, 2, msg, sizeof(msg)); + + /* t = n. */ + CHECK(secp256k1_frost_trusted_dealer_keygen(CTX, secshares, &thresh_pk, pubshares, 3, 3, thresh_sk) == 1); + CHECK(secp256k1_frost_tweak_cache_init(CTX, &cache, &thresh_pk) == 1); + frost_run_signing_round(secshares, pubshares, &cache, 3, 3, 3, msg, sizeof(msg)); +} + +/* Edge cases of tweaking: a zero tweak (valid, leaves the x-only threshold + * public key unchanged), multiple consecutive plain tweaks and a mixed + * xonly/plain tweak chain, exercised in a full signing round with BIP340 + * verification of the final signature. */ +static void frost_tweak_edge_test(void) { + unsigned char thresh_sk[32]; + unsigned char secshares[3 * 32]; + secp256k1_pubkey thresh_pk; + secp256k1_pubkey pubshares[3]; + secp256k1_frost_tweak_cache cache; + secp256k1_xonly_pubkey tweaked_pk; + unsigned char zero_tweak[32] = { 0 }; + unsigned char tweak[32]; + unsigned char msg[32]; + unsigned char ser_before[32], ser_after[32]; + + testrand256(msg); + testutil_random_scalar_order_b32(thresh_sk); + CHECK(secp256k1_frost_trusted_dealer_keygen(CTX, secshares, &thresh_pk, pubshares, 3, 2, thresh_sk) == 1); + CHECK(secp256k1_frost_tweak_cache_init(CTX, &cache, &thresh_pk) == 1); + + /* tweak = 0 is valid. An xonly zero tweak normalizes Q to even Y and a + * plain zero tweak leaves Q untouched; both leave the x-only encoding of + * Q unchanged. */ + CHECK(secp256k1_frost_tweaked_pubkey_get(CTX, &tweaked_pk, &cache) == 1); + CHECK(secp256k1_xonly_pubkey_serialize(CTX, ser_before, &tweaked_pk) == 1); + CHECK(secp256k1_frost_pubkey_xonly_tweak_add(CTX, &tweaked_pk, &cache, zero_tweak) == 1); + CHECK(secp256k1_xonly_pubkey_serialize(CTX, ser_after, &tweaked_pk) == 1); + CHECK(secp256k1_memcmp_var(ser_before, ser_after, 32) == 0); + CHECK(secp256k1_frost_pubkey_ec_tweak_add(CTX, &tweaked_pk, &cache, zero_tweak) == 1); + CHECK(secp256k1_xonly_pubkey_serialize(CTX, ser_after, &tweaked_pk) == 1); + CHECK(secp256k1_memcmp_var(ser_before, ser_after, 32) == 0); + + /* Multiple consecutive plain tweaks, followed by an xonly tweak (giving + * an xonly/plain(0)/plain/plain/xonly chain in total). */ + testrand256(tweak); + CHECK(secp256k1_frost_pubkey_ec_tweak_add(CTX, NULL, &cache, tweak) == 1); + testrand256(tweak); + CHECK(secp256k1_frost_pubkey_ec_tweak_add(CTX, NULL, &cache, tweak) == 1); + testrand256(tweak); + CHECK(secp256k1_frost_pubkey_xonly_tweak_add(CTX, &tweaked_pk, &cache, tweak) == 1); + + /* A full signing round under the tweaked threshold public key. */ + frost_run_signing_round(secshares, pubshares, &cache, 3, 2, 2, msg, sizeof(msg)); +} + +/* Sessions whose aggregate nonce contains the point at infinity (BIP 445 + * NonceAgg explicitly allows infinity column sums). */ +static void frost_infinity_test(void) { + /* The x-coordinate of the generator G, which substitutes the final nonce + * R if R would be the point at infinity (BIP 445 GetSessionValues). */ + static const unsigned char generator_x[32] = { + 0x79, 0xbe, 0x66, 0x7e, 0xf9, 0xdc, 0xbb, 0xac, 0x55, 0xa0, 0x62, 0x95, + 0xce, 0x87, 0x0b, 0x07, 0x02, 0x9b, 0xfc, 0xdb, 0x2d, 0xce, 0x28, 0xd9, + 0x59, 0xf2, 0x81, 0x5b, 0x16, 0xf8, 0x17, 0x98 + }; + static const uint32_t ids[2] = { 0, 1 }; + unsigned char thresh_sk[32]; + unsigned char secshares[2 * 32]; + secp256k1_pubkey thresh_pk; + secp256k1_pubkey pubshares[2]; + secp256k1_frost_tweak_cache cache; + secp256k1_xonly_pubkey xonly_pk; + unsigned char msg[32]; + unsigned char pk32[32]; + unsigned char sig64[64]; + int case_i; + + testrand256(msg); + testutil_random_scalar_order_b32(thresh_sk); + CHECK(secp256k1_frost_trusted_dealer_keygen(CTX, secshares, &thresh_pk, pubshares, 2, 2, thresh_sk) == 1); + CHECK(secp256k1_frost_tweak_cache_init(CTX, &cache, &thresh_pk) == 1); + CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &thresh_pk) == 1); + CHECK(secp256k1_xonly_pubkey_serialize(CTX, pk32, &xonly_pk) == 1); + + /* The signers' secret nonces are injected directly (via the internal save + * functions) because frost_nonce_gen cannot produce nonce contributions + * that cancel out. + * + * case_i == 0: the second column of the aggregate nonce sums to the point + * at infinity. The final nonce R = R1 + b*R2 = R1 is a valid point and + * the session behaves like an ordinary session. + * case_i == 1: both columns sum to the point at infinity, so the final + * nonce R would be the point at infinity and is substituted with the + * generator G. session_init succeeds and produces a consistent session, + * but the resulting signature cannot verify (the nonce contributions + * cancel out instead of summing to G). + * + * A crafted case in which R is the point at infinity but the aggnonce is + * not cannot be constructed directly: it requires solving the fixed point + * R1 = -b(R1 || R2 || ...)*R2 for the hash-based nonce coefficient b. The + * R = G substitution is therefore tested via the all-infinity aggnonce. */ + for (case_i = 0; case_i < 2; case_i++) { + secp256k1_scalar k[2][2]; + secp256k1_ge ges[2]; + secp256k1_frost_secnonce secnonce[2]; + secp256k1_frost_pubnonce pubnonce[2]; + const secp256k1_frost_pubnonce *pubnonce_ptrs[2]; + secp256k1_frost_aggnonce aggnonce; + secp256k1_frost_session session; + secp256k1_frost_partial_sig psig[2]; + const secp256k1_frost_partial_sig *psig_ptrs[2]; + secp256k1_ge agg_ges[2]; + size_t i; + int j; + + pubnonce_ptrs[0] = &pubnonce[0]; + pubnonce_ptrs[1] = &pubnonce[1]; + psig_ptrs[0] = &psig[0]; + psig_ptrs[1] = &psig[1]; + + /* Signer 0 gets the random nonce pair (k0, k1); signer 1 gets + * (k0', -k1) with k0' random in case 0 and -k0 in case 1. */ + testutil_random_scalar_order(&k[0][0]); + testutil_random_scalar_order(&k[0][1]); + if (case_i == 0) { + testutil_random_scalar_order(&k[1][0]); + } else { + secp256k1_scalar_negate(&k[1][0], &k[0][0]); + } + secp256k1_scalar_negate(&k[1][1], &k[0][1]); + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + secp256k1_ecmult_gen_ge(&CTX->ecmult_gen_ctx, &ges[j], &k[i][j]); + } + secp256k1_frost_secnonce_save(&secnonce[i], k[i]); + secp256k1_frost_pubnonce_save(&pubnonce[i], ges); + } + + CHECK(secp256k1_frost_nonce_agg(CTX, &aggnonce, NULL, pubnonce_ptrs, 2) == 1); + CHECK(secp256k1_frost_aggnonce_load(CTX, agg_ges, &aggnonce) == 1); + CHECK(secp256k1_ge_is_infinity(&agg_ges[1])); + CHECK(secp256k1_ge_is_infinity(&agg_ges[0]) == case_i); + + /* session_init succeeds with an infinity component in the aggnonce. */ + CHECK(secp256k1_frost_session_init(CTX, &session, &aggnonce, ids, pubshares, 2, 2, 2, &cache, msg, sizeof(msg)) == 1); + if (case_i == 1) { + /* The final nonce R is the point at infinity and has been + * substituted with the generator G. */ + secp256k1_frost_session_internal session_i; + CHECK(secp256k1_frost_session_load(CTX, &session_i, &session) == 1); + CHECK(secp256k1_memcmp_var(session_i.fin_nonce, generator_x, 32) == 0); + CHECK(session_i.fin_nonce_parity == 0); + } + + for (i = 0; i < 2; i++) { + CHECK(secp256k1_frost_sign(CTX, &psig[i], &secnonce[i], &secshares[32 * i], &session, ids, pubshares, 2, ids[i]) == 1); + CHECK(secp256k1_frost_partial_sig_verify(CTX, &psig[i], &pubnonce[i], &pubshares[i], &session, ids, 2, i) == 1); + } + CHECK(secp256k1_frost_partial_sig_agg(CTX, sig64, NULL, &session, psig_ptrs, 2) == 1); + /* In case 0 the final nonce is R1 (a valid point) and the signature + * verifies. In case 1 the nonce contributions cancel out (their sum + * is the point at infinity, not the substituted G), so the signature + * must not verify. */ + CHECK(secp256k1_schnorrsig_verify(CTX, sig64, msg, sizeof(msg), &xonly_pk) == 1 - case_i); + + for (i = 0; i < 2; i++) { + secp256k1_scalar_clear(&k[i][0]); + secp256k1_scalar_clear(&k[i][1]); + } + } +} + +/* A partial signature is only valid for the session and the signer it was + * created for. */ +static void frost_mismatch_test(void) { + static const uint32_t ids[2] = { 0, 1 }; + unsigned char thresh_sk[32]; + unsigned char secshares[3 * 32]; + secp256k1_pubkey thresh_pk; + secp256k1_pubkey pubshares[3]; + secp256k1_pubkey invalid_pk; + secp256k1_frost_tweak_cache cache; + secp256k1_frost_secnonce secnonce[2]; + secp256k1_frost_pubnonce pubnonce[2]; + const secp256k1_frost_pubnonce *pubnonce_ptrs[2]; + secp256k1_frost_aggnonce aggnonce; + secp256k1_frost_session session_a, session_b; + secp256k1_frost_partial_sig psig[2]; + const secp256k1_frost_partial_sig *psig_ptrs[2]; + secp256k1_xonly_pubkey xonly_pk; + unsigned char msg_a[32], msg_b[32]; + unsigned char rand[32]; + unsigned char sig64[64]; + size_t i; + + memset(&invalid_pk, 0, sizeof(invalid_pk)); + testrand256(msg_a); + testrand256(msg_b); + testutil_random_scalar_order_b32(thresh_sk); + CHECK(secp256k1_frost_trusted_dealer_keygen(CTX, secshares, &thresh_pk, pubshares, 3, 2, thresh_sk) == 1); + CHECK(secp256k1_frost_tweak_cache_init(CTX, &cache, &thresh_pk) == 1); + CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &thresh_pk) == 1); + + for (i = 0; i < 2; i++) { + pubnonce_ptrs[i] = &pubnonce[i]; + psig_ptrs[i] = &psig[i]; + testrand256(rand); + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce[i], &pubnonce[i], rand, &secshares[32 * i], &pubshares[i], NULL, msg_a, sizeof(msg_a), NULL, 0) == 1); + } + CHECK(secp256k1_frost_nonce_agg(CTX, &aggnonce, NULL, pubnonce_ptrs, 2) == 1); + + /* Two sessions over the same aggnonce but different messages. */ + CHECK(secp256k1_frost_session_init(CTX, &session_a, &aggnonce, ids, pubshares, 2, 3, 2, &cache, msg_a, sizeof(msg_a)) == 1); + CHECK(secp256k1_frost_session_init(CTX, &session_b, &aggnonce, ids, pubshares, 2, 3, 2, &cache, msg_b, sizeof(msg_b)) == 1); + + /* Both signers sign session A. */ + for (i = 0; i < 2; i++) { + CHECK(secp256k1_frost_sign(CTX, &psig[i], &secnonce[i], &secshares[32 * i], &session_a, ids, pubshares, 2, ids[i]) == 1); + CHECK(secp256k1_frost_partial_sig_verify(CTX, &psig[i], &pubnonce[i], &pubshares[i], &session_a, ids, 2, i) == 1); + } + + /* Verifying a partial signature with the wrong signer index fails (the + * interpolating value of the other signer is used). */ + CHECK(secp256k1_frost_partial_sig_verify(CTX, &psig[0], &pubnonce[0], &pubshares[0], &session_a, ids, 2, 1) == 0); + + /* A partial signature created for session A does not verify in session B, + * and aggregating the partial signatures under session B yields an + * invalid signature. */ + CHECK(secp256k1_frost_partial_sig_verify(CTX, &psig[0], &pubnonce[0], &pubshares[0], &session_b, ids, 2, 0) == 0); + CHECK(secp256k1_frost_partial_sig_verify(CTX, &psig[1], &pubnonce[1], &pubshares[1], &session_b, ids, 2, 1) == 0); + CHECK(secp256k1_frost_partial_sig_agg(CTX, sig64, NULL, &session_b, psig_ptrs, 2) == 1); + CHECK(secp256k1_schnorrsig_verify(CTX, sig64, msg_b, sizeof(msg_b), &xonly_pk) == 0); + + /* Under the correct session the aggregate signature verifies. */ + CHECK(secp256k1_frost_partial_sig_agg(CTX, sig64, NULL, &session_a, psig_ptrs, 2) == 1); + CHECK(secp256k1_schnorrsig_verify(CTX, sig64, msg_a, sizeof(msg_a), &xonly_pk) == 1); + + /* partial_sig_verify rejects a corrupted pubshare object. */ + CHECK_ILLEGAL(CTX, secp256k1_frost_partial_sig_verify(CTX, &psig[0], &pubnonce[0], &invalid_pk, &session_a, ids, 2, 0)); +} + +/* BIP 445 test vectors (generated by tools/test_vectors_frost_generate.py + * from the reference repository, see vectors.h). */ + +/* Injects a raw 64-byte secnonce (k1 || k2) from the test vectors into a + * secnonce object using the internal save function (magic + k1 || k2). */ +static void frost_vectors_inject_secnonce(secp256k1_frost_secnonce *secnonce, const unsigned char *secnonce64) { + secp256k1_scalar k[2]; + + secp256k1_scalar_set_b32(&k[0], &secnonce64[0], NULL); + secp256k1_scalar_set_b32(&k[1], &secnonce64[32], NULL); + secp256k1_frost_secnonce_save(secnonce, k); + secp256k1_scalar_clear(&k[0]); + secp256k1_scalar_clear(&k[1]); +} + +/* Parses the pubshares selected by the given indices. Requires that all of + * them parse. */ +static void frost_vectors_parse_pubshares(secp256k1_pubkey *pubshares, const struct frost_vec_group *group, const size_t *indices, size_t n) { + size_t i; + + for (i = 0; i < n; i++) { + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubshares[i], group->pubshares[indices[i]], 33) == 1); + } +} + +/* Initializes the tweak cache from the group's threshold public key and + * applies the given tweak chain (indices into the group's tweak pool) in + * order. Returns 1 if all tweaks were applied, 0 otherwise. */ +static int frost_vectors_init_cache(secp256k1_frost_tweak_cache *cache, const struct frost_vec_group *group, size_t n_tweaks, const size_t *tweak_indices, const int *is_xonly) { + secp256k1_pubkey thresh_pk; + size_t i; + + CHECK(secp256k1_ec_pubkey_parse(CTX, &thresh_pk, group->thresh_pk, 33) == 1); + CHECK(secp256k1_frost_tweak_cache_init(CTX, cache, &thresh_pk) == 1); + for (i = 0; i < n_tweaks; i++) { + int ok = is_xonly[i] + ? secp256k1_frost_pubkey_xonly_tweak_add(CTX, NULL, cache, group->tweaks[tweak_indices[i]]) + : secp256k1_frost_pubkey_ec_tweak_add(CTX, NULL, cache, group->tweaks[tweak_indices[i]]); + if (!ok) { + return 0; + } + } + return 1; +} + +/* Runs one sign test case (from sign_verify_vectors.json or + * tweak_vectors.json). */ +static void frost_vectors_run_sign_case(const struct frost_vec_group *group, const struct frost_vec_sign_case *c) { + secp256k1_frost_tweak_cache cache; + secp256k1_frost_aggnonce aggnonce; + secp256k1_frost_session session; + secp256k1_frost_secnonce secnonce; + secp256k1_frost_partial_sig psig; + secp256k1_pubkey pubshares[FROST_VEC_MAX_SIGNERS]; + const secp256k1_pubkey *pubshares_ptr = NULL; + unsigned char buf[66]; + + /* The C API parses the pubshares individually (via + * secp256k1_ec_pubkey_parse) before session setup, so the reference's + * "Invalid pubshare at index i" ValueError maps to the parse of the blamed + * pubshare failing. */ + if (c->error == FROST_VEC_ERR_PUBSHARE_PARSE) { + secp256k1_pubkey pubkey; + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, group->pubshares[c->pubshare_indices[c->error_index]], 33) == 0); + return; + } + + /* Build the tweak cache and apply the tweak chain (if any). An invalid + * tweak maps to the tweak_add call returning 0. */ + if (c->error == FROST_VEC_ERR_TWEAK_ADD) { + CHECK(!frost_vectors_init_cache(&cache, group, c->n_tweaks, c->tweak_indices, c->is_xonly)); + return; + } + CHECK(frost_vectors_init_cache(&cache, group, c->n_tweaks, c->tweak_indices, c->is_xonly)); + + /* An invalid aggnonce (the coordinator's contribution) maps to + * frost_aggnonce_parse failing. */ + if (c->error == FROST_VEC_ERR_AGGNONCE_PARSE) { + CHECK(secp256k1_frost_aggnonce_parse(CTX, &aggnonce, c->aggnonce) == 0); + return; + } + CHECK(secp256k1_frost_aggnonce_parse(CTX, &aggnonce, c->aggnonce) == 1); + + if (c->has_pubshares) { + frost_vectors_parse_pubshares(pubshares, group, c->pubshare_indices, c->n_ids); + pubshares_ptr = pubshares; + } + + /* Invalid session parameters (duplicate ids, out-of-range ids, too few + * signers, pubshares inconsistent with the threshold public key) are + * rejected by frost_session_init. */ + if (c->error == FROST_VEC_ERR_SESSION_INIT) { + CHECK(secp256k1_frost_session_init(CTX, &session, &aggnonce, c->ids, pubshares_ptr, c->n_ids, group->n_participants, group->threshold, &cache, c->msg, c->msg_len) == 0); + return; + } + CHECK(secp256k1_frost_session_init(CTX, &session, &aggnonce, c->ids, pubshares_ptr, c->n_ids, group->n_participants, group->threshold, &cache, c->msg, c->msg_len) == 1); + + frost_vectors_inject_secnonce(&secnonce, group->secnonces[c->secnonce_index]); + if (c->error == FROST_VEC_ERR_SECNONCE) { + /* A secnonce with a zero half (e.g. from nonce reuse) is rejected when + * frost_sign loads it, which triggers the illegal-argument callback. */ + CHECK_ILLEGAL(CTX, secp256k1_frost_sign(CTX, &psig, &secnonce, group->secshares[c->secshare_index], &session, c->ids, pubshares_ptr, c->n_ids, c->my_id)); + return; + } + if (c->error == FROST_VEC_ERR_SIGN) { + CHECK(secp256k1_frost_sign(CTX, &psig, &secnonce, group->secshares[c->secshare_index], &session, c->ids, pubshares_ptr, c->n_ids, c->my_id) == 0); + return; + } + CHECK(c->error == FROST_VEC_ERR_NONE); + CHECK(secp256k1_frost_sign(CTX, &psig, &secnonce, group->secshares[c->secshare_index], &session, c->ids, pubshares_ptr, c->n_ids, c->my_id) == 1); + CHECK(secp256k1_frost_partial_sig_serialize(CTX, buf, &psig) == 1); + CHECK(secp256k1_memcmp_var(buf, c->expected, 32) == 0); +} + +static void frost_test_vectors_nonce_gen(void) { + size_t i; + + for (i = 0; i < sizeof(frost_vec_nonce_gen_cases) / sizeof(frost_vec_nonce_gen_cases[0]); i++) { + const struct frost_vec_nonce_gen_case *c = &frost_vec_nonce_gen_cases[i]; + secp256k1_frost_secnonce secnonce; + secp256k1_frost_pubnonce pubnonce; + secp256k1_pubkey pubshare; + secp256k1_scalar k[2]; + unsigned char rand[32]; + unsigned char buf[66]; + + /* nonce_gen wipes session_secrand32 before returning, so work on a + * copy. */ + memcpy(rand, c->rand, 32); + if (c->has_pubshare) { + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubshare, c->pubshare, 33) == 1); + } + CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce, &pubnonce, rand, c->has_secshare ? c->secshare : NULL, c->has_pubshare ? &pubshare : NULL, c->has_thresh_pk ? c->thresh_pk_xonly : NULL, c->has_msg ? c->msg : NULL, c->msg_len, c->has_extra_in ? c->extra_in : NULL, c->extra_in_len) == 1); + CHECK(secp256k1_is_zero_array(rand, 32)); + + CHECK(secp256k1_frost_pubnonce_serialize(CTX, buf, &pubnonce) == 1); + CHECK(secp256k1_memcmp_var(buf, c->expected_pubnonce, 66) == 0); + + /* Compare the secnonce via the internal load function (tests are + * compiled in the same translation unit). */ + CHECK(secp256k1_frost_secnonce_load(CTX, k, &secnonce) == 1); + secp256k1_scalar_get_b32(&buf[0], &k[0]); + secp256k1_scalar_get_b32(&buf[32], &k[1]); + CHECK(secp256k1_memcmp_var(buf, c->expected_secnonce, 64) == 0); + secp256k1_scalar_clear(&k[0]); + secp256k1_scalar_clear(&k[1]); + } +} + +static void frost_test_vectors_nonce_agg(void) { + size_t i; + + for (i = 0; i < sizeof(frost_vec_nonce_agg_valid_cases) / sizeof(frost_vec_nonce_agg_valid_cases[0]); i++) { + const struct frost_vec_nonce_agg_case *c = &frost_vec_nonce_agg_valid_cases[i]; + secp256k1_frost_pubnonce pubnonces[FROST_VEC_MAX_SIGNERS]; + const secp256k1_frost_pubnonce *pubnonce_ptrs[FROST_VEC_MAX_SIGNERS]; + secp256k1_frost_aggnonce aggnonce; + unsigned char buf[66]; + size_t j; + + for (j = 0; j < c->n_pubnonces; j++) { + CHECK(secp256k1_frost_pubnonce_parse(CTX, &pubnonces[j], frost_vec_nonce_agg_pubnonces[c->pubnonce_indices[j]]) == 1); + pubnonce_ptrs[j] = &pubnonces[j]; + } + /* The aggregate nonce may contain the point at infinity (serialized + * as 33 zero bytes); this is not an error. */ + CHECK(secp256k1_frost_nonce_agg(CTX, &aggnonce, NULL, pubnonce_ptrs, c->n_pubnonces) == 1); + CHECK(secp256k1_frost_aggnonce_serialize(CTX, buf, &aggnonce) == 1); + CHECK(secp256k1_memcmp_var(buf, c->expected, 66) == 0); + } + + for (i = 0; i < sizeof(frost_vec_nonce_agg_error_cases) / sizeof(frost_vec_nonce_agg_error_cases[0]); i++) { + const struct frost_vec_nonce_agg_case *c = &frost_vec_nonce_agg_error_cases[i]; + secp256k1_frost_pubnonce pubnonce; + + /* The C API parses the pubnonces individually (via + * frost_pubnonce_parse) before they are aggregated, so the + * reference's InvalidContributionError blaming the pubnonce at + * position i maps to the parse of that pubnonce failing. */ + CHECK(secp256k1_frost_pubnonce_parse(CTX, &pubnonce, frost_vec_nonce_agg_pubnonces[c->pubnonce_indices[c->error_index]]) == 0); + } +} + +static void frost_test_vectors_sign(void) { + size_t i; + + for (i = 0; i < sizeof(frost_vec_sign_valid_cases) / sizeof(frost_vec_sign_valid_cases[0]); i++) { + frost_vectors_run_sign_case(&frost_vec_sign_groups[frost_vec_sign_valid_cases[i].group], &frost_vec_sign_valid_cases[i]); + } + for (i = 0; i < sizeof(frost_vec_sign_error_cases) / sizeof(frost_vec_sign_error_cases[0]); i++) { + frost_vectors_run_sign_case(&frost_vec_sign_groups[frost_vec_sign_error_cases[i].group], &frost_vec_sign_error_cases[i]); + } +} + +static void frost_test_vectors_verify(void) { + size_t i, j; + + for (i = 0; i < sizeof(frost_vec_verify_fail_cases) / sizeof(frost_vec_verify_fail_cases[0]) + sizeof(frost_vec_verify_error_cases) / sizeof(frost_vec_verify_error_cases[0]); i++) { + const struct frost_vec_verify_case *c = i < sizeof(frost_vec_verify_fail_cases) / sizeof(frost_vec_verify_fail_cases[0]) + ? &frost_vec_verify_fail_cases[i] + : &frost_vec_verify_error_cases[i - sizeof(frost_vec_verify_fail_cases) / sizeof(frost_vec_verify_fail_cases[0])]; + const struct frost_vec_group *group = &frost_vec_sign_groups[c->group]; + secp256k1_frost_partial_sig psig; + + /* verify_error cases: the blamed contribution fails to parse. The C + * API parses the pubnonce and pubshare individually before + * verification, so the blame index maps to the parse step. */ + if (c->error == FROST_VEC_ERR_PUBNONCE_PARSE) { + secp256k1_frost_pubnonce pubnonce; + CHECK(secp256k1_frost_pubnonce_parse(CTX, &pubnonce, group->pubnonces[c->pubnonce_indices[c->error_index]]) == 0); + continue; + } + if (c->error == FROST_VEC_ERR_PUBSHARE_PARSE) { + secp256k1_pubkey pubkey; + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, group->pubshares[c->pubshare_indices[c->error_index]], 33) == 0); + continue; + } + CHECK(c->error == FROST_VEC_ERR_NONE); + + /* A psig that is not a valid scalar maps to frost_partial_sig_parse + * failing (the reference's partial_sig_verify returns False). */ + if (!c->psig_parses) { + CHECK(secp256k1_frost_partial_sig_parse(CTX, &psig, c->psig) == 0); + continue; + } + + /* verify_fail cases: the partial signature parses but does not + * verify. */ + { + secp256k1_frost_tweak_cache cache; + secp256k1_frost_session session; + secp256k1_frost_pubnonce pubnonces[FROST_VEC_MAX_SIGNERS]; + const secp256k1_frost_pubnonce *pubnonce_ptrs[FROST_VEC_MAX_SIGNERS]; + secp256k1_pubkey pubshares[FROST_VEC_MAX_SIGNERS]; + secp256k1_frost_aggnonce aggnonce; + + CHECK(secp256k1_frost_partial_sig_parse(CTX, &psig, c->psig) == 1); + /* The reference aggregates the pubnonces inside + * partial_sig_verify; the C API takes the session (built from the + * aggnonce) instead. */ + for (j = 0; j < c->n_ids; j++) { + CHECK(secp256k1_frost_pubnonce_parse(CTX, &pubnonces[j], group->pubnonces[c->pubnonce_indices[j]]) == 1); + pubnonce_ptrs[j] = &pubnonces[j]; + } + CHECK(secp256k1_frost_nonce_agg(CTX, &aggnonce, NULL, pubnonce_ptrs, c->n_ids) == 1); + frost_vectors_parse_pubshares(pubshares, group, c->pubshare_indices, c->n_ids); + CHECK(frost_vectors_init_cache(&cache, group, 0, NULL, NULL)); + CHECK(secp256k1_frost_session_init(CTX, &session, &aggnonce, c->ids, pubshares, c->n_ids, group->n_participants, group->threshold, &cache, c->msg, c->msg_len) == 1); + CHECK(secp256k1_frost_partial_sig_verify(CTX, &psig, &pubnonces[c->signer_index], &pubshares[c->signer_index], &session, c->ids, c->n_ids, c->signer_index) == 0); + } + } +} + +static void frost_test_vectors_tweak(void) { + size_t i; + + for (i = 0; i < sizeof(frost_vec_tweak_valid_cases) / sizeof(frost_vec_tweak_valid_cases[0]); i++) { + frost_vectors_run_sign_case(&frost_vec_tweak_groups[frost_vec_tweak_valid_cases[i].group], &frost_vec_tweak_valid_cases[i]); + } + for (i = 0; i < sizeof(frost_vec_tweak_error_cases) / sizeof(frost_vec_tweak_error_cases[0]); i++) { + frost_vectors_run_sign_case(&frost_vec_tweak_groups[frost_vec_tweak_error_cases[i].group], &frost_vec_tweak_error_cases[i]); + } +} + +static void frost_test_vectors_sig_agg(void) { + size_t i, j; + + for (i = 0; i < sizeof(frost_vec_sig_agg_valid_cases) / sizeof(frost_vec_sig_agg_valid_cases[0]) + sizeof(frost_vec_sig_agg_error_cases) / sizeof(frost_vec_sig_agg_error_cases[0]); i++) { + const struct frost_vec_sig_agg_case *c = i < sizeof(frost_vec_sig_agg_valid_cases) / sizeof(frost_vec_sig_agg_valid_cases[0]) + ? &frost_vec_sig_agg_valid_cases[i] + : &frost_vec_sig_agg_error_cases[i - sizeof(frost_vec_sig_agg_valid_cases) / sizeof(frost_vec_sig_agg_valid_cases[0])]; + const struct frost_vec_group *group = &frost_vec_sig_agg_groups[c->group]; + secp256k1_frost_tweak_cache cache; + secp256k1_frost_session session; + secp256k1_frost_aggnonce aggnonce; + secp256k1_frost_partial_sig psigs[FROST_VEC_MAX_PSIGS]; + const secp256k1_frost_partial_sig *psig_ptrs[FROST_VEC_MAX_PSIGS]; + secp256k1_pubkey pubshares[FROST_VEC_MAX_SIGNERS]; + const secp256k1_pubkey *pubshares_ptr = NULL; + unsigned char sig64[64]; + size_t error_index; + + /* An invalid partial signature (out of range) maps to + * frost_partial_sig_parse of the blamed psig failing: the C API + * parses the partial signatures individually before aggregation. */ + if (c->error == FROST_VEC_ERR_PSIG_PARSE) { + CHECK(secp256k1_frost_partial_sig_parse(CTX, &psigs[0], c->psigs[c->error_index]) == 0); + continue; + } + + CHECK(frost_vectors_init_cache(&cache, group, c->n_tweaks, c->tweak_indices, c->is_xonly)); + CHECK(secp256k1_frost_aggnonce_parse(CTX, &aggnonce, c->aggnonce) == 1); + if (c->has_pubshares) { + frost_vectors_parse_pubshares(pubshares, group, c->pubshare_indices, c->n_ids); + pubshares_ptr = pubshares; + } + CHECK(secp256k1_frost_session_init(CTX, &session, &aggnonce, c->ids, pubshares_ptr, c->n_ids, group->n_participants, group->threshold, &cache, c->msg, c->msg_len) == 1); + for (j = 0; j < c->n_psigs; j++) { + CHECK(secp256k1_frost_partial_sig_parse(CTX, &psigs[j], c->psigs[j]) == 1); + psig_ptrs[j] = &psigs[j]; + } + if (c->error == FROST_VEC_ERR_AGG_LEN) { + /* The number of partial signatures does not match the number of + * signers of the session. */ + CHECK(secp256k1_frost_partial_sig_agg(CTX, sig64, NULL, &session, psig_ptrs, c->n_psigs) == 0); + continue; + } + CHECK(c->error == FROST_VEC_ERR_NONE); + error_index = 0xFF; + CHECK(secp256k1_frost_partial_sig_agg(CTX, sig64, &error_index, &session, psig_ptrs, c->n_psigs) == 1); + CHECK(secp256k1_memcmp_var(sig64, c->expected, 64) == 0); + } +} + +static void frost_test_vectors_det_sign(void) { + size_t i, j; + + for (i = 0; i < sizeof(frost_vec_det_sign_valid_cases) / sizeof(frost_vec_det_sign_valid_cases[0]) + sizeof(frost_vec_det_sign_error_cases) / sizeof(frost_vec_det_sign_error_cases[0]); i++) { + const struct frost_vec_det_sign_case *c = i < sizeof(frost_vec_det_sign_valid_cases) / sizeof(frost_vec_det_sign_valid_cases[0]) + ? &frost_vec_det_sign_valid_cases[i] + : &frost_vec_det_sign_error_cases[i - sizeof(frost_vec_det_sign_valid_cases) / sizeof(frost_vec_det_sign_valid_cases[0])]; + const struct frost_vec_group *group = &frost_vec_det_sign_groups[c->group]; + secp256k1_frost_tweak_cache cache; + secp256k1_frost_partial_sig psig; + secp256k1_frost_pubnonce pubnonce; + secp256k1_frost_aggnonce aggothernonce; + const secp256k1_frost_aggnonce *aggothernonce_ptr = NULL; + secp256k1_pubkey pubshares[FROST_VEC_MAX_SIGNERS]; + const secp256k1_pubkey *pubshares_ptr = NULL; + secp256k1_pubkey thresh_pk; + unsigned char buf[66]; + int tweaks_ok = 1; + + /* Same mapping as in frost_vectors_run_sign_case: an invalid pubshare + * is detected when parsing it. */ + if (c->error == FROST_VEC_ERR_PUBSHARE_PARSE) { + secp256k1_pubkey pubkey; + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, group->pubshares[c->pubshare_indices[c->error_index]], 33) == 0); + continue; + } + + /* The tweaks are inlined in det_sign cases (not indexed into the + * group's pool). */ + CHECK(secp256k1_ec_pubkey_parse(CTX, &thresh_pk, group->thresh_pk, 33) == 1); + CHECK(secp256k1_frost_tweak_cache_init(CTX, &cache, &thresh_pk) == 1); + for (j = 0; j < c->n_tweaks; j++) { + int ok = c->is_xonly[j] + ? secp256k1_frost_pubkey_xonly_tweak_add(CTX, NULL, &cache, c->tweaks[j]) + : secp256k1_frost_pubkey_ec_tweak_add(CTX, NULL, &cache, c->tweaks[j]); + if (!ok) { + tweaks_ok = 0; + break; + } + } + if (c->error == FROST_VEC_ERR_TWEAK_ADD) { + CHECK(!tweaks_ok); + continue; + } + CHECK(tweaks_ok); + + /* An invalid aggothernonce (the coordinator's contribution) maps to + * frost_aggnonce_parse failing, or (for an infinity component, which + * parses as an aggnonce but is not a valid NonceAgg input) to + * frost_deterministic_sign failing. */ + if (c->has_aggothernonce) { + if (secp256k1_frost_aggnonce_parse(CTX, &aggothernonce, c->aggothernonce) == 0) { + CHECK(c->error == FROST_VEC_ERR_AGGOTHERNONCE); + continue; + } + aggothernonce_ptr = &aggothernonce; + } + if (c->has_pubshares) { + frost_vectors_parse_pubshares(pubshares, group, c->pubshare_indices, c->n_ids); + pubshares_ptr = pubshares; + } + if (c->error != FROST_VEC_ERR_NONE) { + CHECK(secp256k1_frost_deterministic_sign(CTX, &psig, &pubnonce, group->secshares[c->secshare_index], c->my_id, aggothernonce_ptr, c->ids, pubshares_ptr, c->n_ids, group->n_participants, group->threshold, &cache, c->msg, c->msg_len, c->has_aux_rand ? c->aux_rand : NULL) == 0); + continue; + } + CHECK(secp256k1_frost_deterministic_sign(CTX, &psig, &pubnonce, group->secshares[c->secshare_index], c->my_id, aggothernonce_ptr, c->ids, pubshares_ptr, c->n_ids, group->n_participants, group->threshold, &cache, c->msg, c->msg_len, c->has_aux_rand ? c->aux_rand : NULL) == 1); + CHECK(secp256k1_frost_pubnonce_serialize(CTX, buf, &pubnonce) == 1); + CHECK(secp256k1_memcmp_var(buf, c->expected_pubnonce, 66) == 0); + CHECK(secp256k1_frost_partial_sig_serialize(CTX, buf, &psig) == 1); + CHECK(secp256k1_memcmp_var(buf, c->expected_psig, 32) == 0); + } +} + +static const struct tf_test_entry tests_frost[] = { + CASE1(frost_trusted_dealer_vector_test), + CASE1(frost_trusted_dealer_test), + CASE1(frost_tweak_vector_test), + CASE1(frost_tweak_test), + CASE1(frost_nonce_vector_test), + CASE1(frost_nonce_test), + CASE1(frost_sign_vector_test), + CASE1(frost_det_sign_vector_test), + CASE1(frost_sign_test), + CASE1(frost_api_test), + CASE1(frost_boundary_test), + CASE1(frost_tweak_edge_test), + CASE1(frost_infinity_test), + CASE1(frost_mismatch_test), + CASE1(frost_test_vectors_nonce_gen), + CASE1(frost_test_vectors_nonce_agg), + CASE1(frost_test_vectors_sign), + CASE1(frost_test_vectors_verify), + CASE1(frost_test_vectors_tweak), + CASE1(frost_test_vectors_sig_agg), + CASE1(frost_test_vectors_det_sign), +}; + +#endif diff --git a/src/modules/frost/vectors.h b/src/modules/frost/vectors.h new file mode 100644 index 00000000..73d1681a --- /dev/null +++ b/src/modules/frost/vectors.h @@ -0,0 +1,800 @@ +/** + * Automatically generated by tools/test_vectors_frost_generate.py. + * + * 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. */ + +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, +}; + +enum { + FROST_VEC_MAX_PUBSHARES = 7, + FROST_VEC_MAX_SECSHARES = 6, + FROST_VEC_MAX_PUBNONCES = 7, + FROST_VEC_MAX_SECNONCES = 7, + FROST_VEC_MAX_GROUP_TWEAKS = 7, + FROST_VEC_MAX_TWEAK_LEN = 33, + FROST_VEC_MAX_SIGNERS = 5, + FROST_VEC_MAX_TWEAKS = 4, + FROST_VEC_MAX_MSGLEN = 38, + FROST_VEC_MAX_PSIGS = 5 +}; + +/* 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]; +}; + +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[32]; + unsigned char expected_secnonce[64]; + unsigned char expected_pubnonce[66]; +}; +static const struct frost_vec_nonce_gen_case frost_vec_nonce_gen_cases[5] = { + { { 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F }, 1, { 0x53, 0x44, 0x2F, 0xA9, 0xBD, 0x72, 0xEE, 0xA0, 0xA4, 0x2D, 0xF6, 0xF2, 0xD2, 0xD7, 0x6A, 0x2C, 0x0D, 0x3A, 0x3D, 0xFA, 0x2B, 0xE2, 0xF8, 0x20, 0xF4, 0x1A, 0xDE, 0x97, 0x6B, 0x82, 0x59, 0xFB }, 1, { 0x03, 0x9E, 0xE3, 0x33, 0x5A, 0xF4, 0x8D, 0xFE, 0x23, 0x70, 0x2A, 0xB3, 0x53, 0xF4, 0xAF, 0x20, 0xD4, 0x01, 0xF6, 0x7A, 0x13, 0x0D, 0xF7, 0x83, 0xCC, 0x84, 0x57, 0x32, 0x3A, 0x86, 0x0A, 0x2F, 0xB4 }, 1, { 0xD7, 0x72, 0xA0, 0x9F, 0x5F, 0x67, 0x57, 0x83, 0xD2, 0x75, 0xED, 0x9F, 0x6A, 0xAE, 0xDB, 0x2E, 0xCC, 0xBC, 0x74, 0x17, 0x1B, 0x37, 0xAC, 0x23, 0xAE, 0x3B, 0xBD, 0x9D, 0x7A, 0xE2, 0xCD, 0xAA }, 1, 32, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, 1, 32, { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, { 0x60, 0xF7, 0x3D, 0xF0, 0xC6, 0x6B, 0x5B, 0xCA, 0xDF, 0x68, 0xB4, 0xCB, 0x34, 0x87, 0xEC, 0xF3, 0xF3, 0x06, 0x5C, 0xC9, 0xD9, 0xC1, 0xDC, 0xF5, 0x56, 0x45, 0x3A, 0x42, 0xE2, 0x1A, 0xBF, 0x5C, 0x9C, 0xA3, 0x7B, 0xF6, 0xCF, 0xE0, 0xE9, 0x0C, 0x16, 0xD8, 0x3E, 0xFB, 0x57, 0x20, 0x95, 0xD8, 0x28, 0x63, 0xF2, 0x99, 0xCA, 0x86, 0xBE, 0x3C, 0x53, 0xF1, 0x67, 0xFF, 0xD1, 0xF3, 0x60, 0x6A }, { 0x03, 0x8E, 0xBC, 0x31, 0xEF, 0x5C, 0x88, 0xC3, 0xE4, 0x47, 0x0B, 0xDA, 0x87, 0x65, 0xA8, 0x37, 0x76, 0x97, 0xE1, 0xCB, 0x20, 0xA1, 0xD0, 0x7D, 0x6B, 0x09, 0xC0, 0x14, 0x68, 0x14, 0xEC, 0x5B, 0xDF, 0x03, 0x86, 0xD6, 0x1A, 0x1C, 0xCF, 0xBE, 0xC0, 0xA8, 0xAE, 0xF0, 0x1F, 0xFD, 0x83, 0xA6, 0xF9, 0xE0, 0xE9, 0x0F, 0xDC, 0x20, 0xD0, 0x93, 0x86, 0x1A, 0x27, 0xAC, 0x4A, 0x10, 0xC9, 0x31, 0xB0, 0xD3 } }, + { { 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F }, 1, { 0x53, 0x44, 0x2F, 0xA9, 0xBD, 0x72, 0xEE, 0xA0, 0xA4, 0x2D, 0xF6, 0xF2, 0xD2, 0xD7, 0x6A, 0x2C, 0x0D, 0x3A, 0x3D, 0xFA, 0x2B, 0xE2, 0xF8, 0x20, 0xF4, 0x1A, 0xDE, 0x97, 0x6B, 0x82, 0x59, 0xFB }, 1, { 0x03, 0x9E, 0xE3, 0x33, 0x5A, 0xF4, 0x8D, 0xFE, 0x23, 0x70, 0x2A, 0xB3, 0x53, 0xF4, 0xAF, 0x20, 0xD4, 0x01, 0xF6, 0x7A, 0x13, 0x0D, 0xF7, 0x83, 0xCC, 0x84, 0x57, 0x32, 0x3A, 0x86, 0x0A, 0x2F, 0xB4 }, 1, { 0xD7, 0x72, 0xA0, 0x9F, 0x5F, 0x67, 0x57, 0x83, 0xD2, 0x75, 0xED, 0x9F, 0x6A, 0xAE, 0xDB, 0x2E, 0xCC, 0xBC, 0x74, 0x17, 0x1B, 0x37, 0xAC, 0x23, 0xAE, 0x3B, 0xBD, 0x9D, 0x7A, 0xE2, 0xCD, 0xAA }, 1, 0, { }, 1, 32, { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, { 0x23, 0x35, 0x36, 0x90, 0x33, 0x40, 0xC2, 0xF5, 0x10, 0x47, 0x93, 0x34, 0x10, 0xAD, 0xD7, 0x5C, 0xC6, 0x2A, 0x90, 0x99, 0xAF, 0xAC, 0x1F, 0xAD, 0x41, 0x09, 0xCA, 0x23, 0x4E, 0xC9, 0x40, 0x99, 0xA3, 0x01, 0x06, 0xB1, 0x87, 0xA6, 0x57, 0x2B, 0x2E, 0xE1, 0x57, 0x0D, 0xE0, 0x58, 0x32, 0xB1, 0x68, 0x3D, 0xF2, 0x72, 0x76, 0x9D, 0xD0, 0xD3, 0x4E, 0x46, 0x0C, 0xB2, 0x78, 0x08, 0x61, 0x73 }, { 0x03, 0x4C, 0xCF, 0xCF, 0x7B, 0x15, 0xD5, 0xE5, 0xA0, 0xBA, 0xED, 0x01, 0xF7, 0x44, 0xB8, 0x4D, 0x3A, 0x40, 0x5C, 0x18, 0x00, 0xB6, 0xE1, 0x7B, 0xF1, 0xF2, 0xBC, 0xE8, 0x81, 0x7D, 0x4A, 0x96, 0x59, 0x03, 0xC1, 0x10, 0xE6, 0x4C, 0x61, 0xF7, 0x52, 0x7C, 0x0D, 0x2C, 0xF8, 0xE9, 0x9F, 0x9A, 0x62, 0xB8, 0xA4, 0x34, 0x0F, 0x08, 0x30, 0x3E, 0x27, 0x28, 0x45, 0x35, 0x1C, 0x9A, 0x60, 0x7F, 0xDF, 0x8F } }, + { { 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F }, 1, { 0x53, 0x44, 0x2F, 0xA9, 0xBD, 0x72, 0xEE, 0xA0, 0xA4, 0x2D, 0xF6, 0xF2, 0xD2, 0xD7, 0x6A, 0x2C, 0x0D, 0x3A, 0x3D, 0xFA, 0x2B, 0xE2, 0xF8, 0x20, 0xF4, 0x1A, 0xDE, 0x97, 0x6B, 0x82, 0x59, 0xFB }, 1, { 0x03, 0x9E, 0xE3, 0x33, 0x5A, 0xF4, 0x8D, 0xFE, 0x23, 0x70, 0x2A, 0xB3, 0x53, 0xF4, 0xAF, 0x20, 0xD4, 0x01, 0xF6, 0x7A, 0x13, 0x0D, 0xF7, 0x83, 0xCC, 0x84, 0x57, 0x32, 0x3A, 0x86, 0x0A, 0x2F, 0xB4 }, 1, { 0xD7, 0x72, 0xA0, 0x9F, 0x5F, 0x67, 0x57, 0x83, 0xD2, 0x75, 0xED, 0x9F, 0x6A, 0xAE, 0xDB, 0x2E, 0xCC, 0xBC, 0x74, 0x17, 0x1B, 0x37, 0xAC, 0x23, 0xAE, 0x3B, 0xBD, 0x9D, 0x7A, 0xE2, 0xCD, 0xAA }, 1, 38, { 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26 }, 1, 32, { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, { 0xE3, 0x7A, 0x19, 0x2E, 0x7B, 0xB9, 0x11, 0x94, 0x7C, 0x75, 0x8F, 0x8A, 0x8B, 0x81, 0x96, 0x5C, 0xBE, 0x0F, 0xB3, 0x39, 0xA7, 0xFD, 0x36, 0x82, 0xCC, 0x64, 0x9E, 0x29, 0x0C, 0x81, 0x11, 0xA2, 0x62, 0x68, 0x95, 0x94, 0x03, 0x57, 0xA4, 0xBF, 0x92, 0xDF, 0x25, 0x02, 0xBE, 0x55, 0x66, 0xBB, 0xE6, 0x64, 0xD8, 0xCA, 0xC0, 0xA7, 0xAF, 0x39, 0xE5, 0x7A, 0xD5, 0xF5, 0x15, 0xF7, 0xDF, 0x0D }, { 0x02, 0xDC, 0xF5, 0xFA, 0x50, 0x4E, 0x62, 0xA3, 0xC8, 0xBD, 0x73, 0x49, 0xC0, 0x2B, 0x13, 0xA6, 0xBB, 0x9E, 0xD5, 0xA3, 0x4F, 0x75, 0x5D, 0x25, 0x33, 0xCC, 0x01, 0x4D, 0xD1, 0x6C, 0x5D, 0xAE, 0x1E, 0x02, 0x65, 0x37, 0xB3, 0x47, 0x68, 0x3C, 0x17, 0x95, 0xAB, 0x20, 0xC3, 0x4E, 0xF6, 0x4C, 0x7C, 0x08, 0x6C, 0x87, 0xD2, 0x6B, 0x14, 0x9F, 0xF4, 0xB2, 0x44, 0x8C, 0xD5, 0x8F, 0x21, 0x7A, 0xA0, 0x26 } }, + { { 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F }, 0, { 0 }, 0, { 0 }, 0, { 0 }, 0, 0, { }, 0, 0, { }, { 0x42, 0xB3, 0x9C, 0xA5, 0x63, 0x90, 0x44, 0x9A, 0x85, 0xBC, 0xEC, 0x2E, 0xF9, 0xB1, 0x02, 0xCE, 0x94, 0x5E, 0x69, 0x35, 0x70, 0xA0, 0x07, 0x7E, 0x98, 0xF8, 0xE7, 0x74, 0x76, 0xAC, 0x30, 0x63, 0xEC, 0x9C, 0xFC, 0x5C, 0xE2, 0x49, 0xD1, 0x9C, 0x7B, 0xE5, 0xC3, 0x10, 0xA4, 0x25, 0xFB, 0x5E, 0x1E, 0x9B, 0x3B, 0x45, 0x77, 0xF6, 0x28, 0xD9, 0x85, 0x4A, 0x4A, 0x3C, 0x6C, 0x64, 0xC6, 0x53 }, { 0x03, 0x75, 0xB2, 0x8F, 0x15, 0x25, 0x61, 0x4D, 0x3A, 0x57, 0xAE, 0x7B, 0x5D, 0x91, 0x09, 0xC2, 0x4B, 0xDC, 0xB8, 0x23, 0x06, 0x5C, 0x4A, 0xD8, 0x5D, 0x01, 0xA5, 0x3E, 0xDC, 0xEB, 0xD2, 0x2F, 0xEA, 0x03, 0xEB, 0xAC, 0x79, 0x8B, 0xC7, 0xD8, 0xF6, 0x58, 0x0F, 0x21, 0x79, 0x29, 0x38, 0xCD, 0x7A, 0x8B, 0x44, 0x62, 0xBB, 0xBD, 0xB5, 0xAB, 0x17, 0x13, 0x70, 0xF1, 0x79, 0x51, 0xE5, 0x5C, 0xE9, 0x90 } }, + { { 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F }, 1, { 0x53, 0x44, 0x2F, 0xA9, 0xBD, 0x72, 0xEE, 0xA0, 0xA4, 0x2D, 0xF6, 0xF2, 0xD2, 0xD7, 0x6A, 0x2C, 0x0D, 0x3A, 0x3D, 0xFA, 0x2B, 0xE2, 0xF8, 0x20, 0xF4, 0x1A, 0xDE, 0x97, 0x6B, 0x82, 0x59, 0xFB }, 1, { 0x03, 0x9E, 0xE3, 0x33, 0x5A, 0xF4, 0x8D, 0xFE, 0x23, 0x70, 0x2A, 0xB3, 0x53, 0xF4, 0xAF, 0x20, 0xD4, 0x01, 0xF6, 0x7A, 0x13, 0x0D, 0xF7, 0x83, 0xCC, 0x84, 0x57, 0x32, 0x3A, 0x86, 0x0A, 0x2F, 0xB4 }, 1, { 0xD7, 0x72, 0xA0, 0x9F, 0x5F, 0x67, 0x57, 0x83, 0xD2, 0x75, 0xED, 0x9F, 0x6A, 0xAE, 0xDB, 0x2E, 0xCC, 0xBC, 0x74, 0x17, 0x1B, 0x37, 0xAC, 0x23, 0xAE, 0x3B, 0xBD, 0x9D, 0x7A, 0xE2, 0xCD, 0xAA }, 0, 0, { }, 1, 32, { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, { 0x00, 0xC1, 0x42, 0x32, 0x89, 0xD2, 0xFA, 0x1F, 0x44, 0xCC, 0x15, 0x38, 0xCD, 0x75, 0x68, 0xF8, 0xF9, 0x44, 0xA6, 0x81, 0x22, 0xBC, 0x3D, 0xF3, 0x85, 0xC1, 0x57, 0xED, 0x5F, 0x81, 0x91, 0x09, 0x8A, 0x53, 0xAF, 0xAF, 0x92, 0xEE, 0x42, 0xF6, 0x70, 0x5F, 0x0D, 0xE2, 0xE0, 0x1D, 0x26, 0x21, 0xA1, 0xFA, 0x76, 0x2D, 0x80, 0xF4, 0x50, 0xE0, 0x87, 0xB5, 0x21, 0xAA, 0x7C, 0xCA, 0x16, 0x67 }, { 0x02, 0xB5, 0x1A, 0xE0, 0x74, 0xE1, 0x5B, 0x3C, 0x34, 0xEE, 0x1E, 0x53, 0x28, 0xBA, 0x91, 0xFB, 0x9B, 0xA8, 0x8A, 0x97, 0x3B, 0x67, 0x6D, 0x77, 0x00, 0x63, 0xB5, 0x43, 0x06, 0xF8, 0x73, 0xE0, 0xD7, 0x02, 0xA8, 0x9D, 0xAE, 0xBF, 0x9F, 0x9E, 0x39, 0x3E, 0x9F, 0x5E, 0x39, 0x88, 0x03, 0xD6, 0xCA, 0x54, 0x4C, 0x26, 0xF9, 0xA8, 0xDD, 0x8F, 0xCC, 0x81, 0x44, 0x32, 0xF9, 0xC1, 0xCA, 0xC1, 0xF6, 0xC3 } }, +}; + +struct frost_vec_nonce_agg_case { + size_t n_pubnonces; + size_t pubnonce_indices[2]; + /* -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]; +}; +static const unsigned char frost_vec_nonce_agg_pubnonces[7][66] = { + { 0x02, 0x01, 0x51, 0xC8, 0x0F, 0x43, 0x56, 0x48, 0xDF, 0x67, 0xA2, 0x2B, 0x74, 0x9C, 0xD7, 0x98, 0xCE, 0x54, 0xE0, 0x32, 0x1D, 0x03, 0x4B, 0x92, 0xB7, 0x09, 0xB5, 0x67, 0xD6, 0x0A, 0x42, 0xE6, 0x66, 0x03, 0xBA, 0x47, 0xFB, 0xC1, 0x83, 0x44, 0x37, 0xB3, 0x21, 0x2E, 0x89, 0xA8, 0x4D, 0x84, 0x25, 0xE7, 0xBF, 0x12, 0xE0, 0x24, 0x5D, 0x98, 0x26, 0x22, 0x68, 0xEB, 0xDC, 0xB3, 0x85, 0xD5, 0x06, 0x41 }, + { 0x03, 0xFF, 0x40, 0x6F, 0xFD, 0x8A, 0xDB, 0x9C, 0xD2, 0x98, 0x77, 0xE4, 0x98, 0x50, 0x14, 0xF6, 0x6A, 0x59, 0xF6, 0xCD, 0x01, 0xC0, 0xE8, 0x8C, 0xAA, 0x8E, 0x5F, 0x31, 0x66, 0xB1, 0xF6, 0x76, 0xA6, 0x02, 0x48, 0xC2, 0x64, 0xCD, 0xD5, 0x7D, 0x3C, 0x24, 0xD7, 0x99, 0x90, 0xB0, 0xF8, 0x65, 0x67, 0x4E, 0xB6, 0x2A, 0x0F, 0x90, 0x18, 0x27, 0x7A, 0x95, 0x01, 0x1B, 0x41, 0xBF, 0xC1, 0x93, 0xB8, 0x33 }, + { 0x02, 0x01, 0x51, 0xC8, 0x0F, 0x43, 0x56, 0x48, 0xDF, 0x67, 0xA2, 0x2B, 0x74, 0x9C, 0xD7, 0x98, 0xCE, 0x54, 0xE0, 0x32, 0x1D, 0x03, 0x4B, 0x92, 0xB7, 0x09, 0xB5, 0x67, 0xD6, 0x0A, 0x42, 0xE6, 0x66, 0x02, 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98 }, + { 0x03, 0xFF, 0x40, 0x6F, 0xFD, 0x8A, 0xDB, 0x9C, 0xD2, 0x98, 0x77, 0xE4, 0x98, 0x50, 0x14, 0xF6, 0x6A, 0x59, 0xF6, 0xCD, 0x01, 0xC0, 0xE8, 0x8C, 0xAA, 0x8E, 0x5F, 0x31, 0x66, 0xB1, 0xF6, 0x76, 0xA6, 0x03, 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98 }, + { 0x04, 0xFF, 0x40, 0x6F, 0xFD, 0x8A, 0xDB, 0x9C, 0xD2, 0x98, 0x77, 0xE4, 0x98, 0x50, 0x14, 0xF6, 0x6A, 0x59, 0xF6, 0xCD, 0x01, 0xC0, 0xE8, 0x8C, 0xAA, 0x8E, 0x5F, 0x31, 0x66, 0xB1, 0xF6, 0x76, 0xA6, 0x02, 0x48, 0xC2, 0x64, 0xCD, 0xD5, 0x7D, 0x3C, 0x24, 0xD7, 0x99, 0x90, 0xB0, 0xF8, 0x65, 0x67, 0x4E, 0xB6, 0x2A, 0x0F, 0x90, 0x18, 0x27, 0x7A, 0x95, 0x01, 0x1B, 0x41, 0xBF, 0xC1, 0x93, 0xB8, 0x33 }, + { 0x03, 0xFF, 0x40, 0x6F, 0xFD, 0x8A, 0xDB, 0x9C, 0xD2, 0x98, 0x77, 0xE4, 0x98, 0x50, 0x14, 0xF6, 0x6A, 0x59, 0xF6, 0xCD, 0x01, 0xC0, 0xE8, 0x8C, 0xAA, 0x8E, 0x5F, 0x31, 0x66, 0xB1, 0xF6, 0x76, 0xA6, 0x02, 0x48, 0xC2, 0x64, 0xCD, 0xD5, 0x7D, 0x3C, 0x24, 0xD7, 0x99, 0x90, 0xB0, 0xF8, 0x65, 0x67, 0x4E, 0xB6, 0x2A, 0x0F, 0x90, 0x18, 0x27, 0x7A, 0x95, 0x01, 0x1B, 0x41, 0xBF, 0xC1, 0x93, 0xB8, 0x31 }, + { 0x03, 0xFF, 0x40, 0x6F, 0xFD, 0x8A, 0xDB, 0x9C, 0xD2, 0x98, 0x77, 0xE4, 0x98, 0x50, 0x14, 0xF6, 0x6A, 0x59, 0xF6, 0xCD, 0x01, 0xC0, 0xE8, 0x8C, 0xAA, 0x8E, 0x5F, 0x31, 0x66, 0xB1, 0xF6, 0x76, 0xA6, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x30 } +}; +static const struct frost_vec_nonce_agg_case frost_vec_nonce_agg_valid_cases[2] = { + { 2, { 0, 1 }, -1, { 0x03, 0x5F, 0xE1, 0x87, 0x3B, 0x4F, 0x29, 0x67, 0xF5, 0x2F, 0xEA, 0x4A, 0x06, 0xAD, 0x5A, 0x8E, 0xCC, 0xBE, 0x9D, 0x0F, 0xD7, 0x30, 0x68, 0x01, 0x2C, 0x89, 0x4E, 0x2E, 0x87, 0xCC, 0xB5, 0x80, 0x4B, 0x02, 0x47, 0x25, 0x37, 0x73, 0x45, 0xBD, 0xE0, 0xE9, 0xC3, 0x3A, 0xF3, 0xC4, 0x3C, 0x0A, 0x29, 0xA9, 0x24, 0x9F, 0x2F, 0x29, 0x56, 0xFA, 0x8C, 0xFE, 0xB5, 0x5C, 0x85, 0x73, 0xD0, 0x26, 0x2D, 0xC8 } }, + { 2, { 2, 3 }, -1, { 0x03, 0x5F, 0xE1, 0x87, 0x3B, 0x4F, 0x29, 0x67, 0xF5, 0x2F, 0xEA, 0x4A, 0x06, 0xAD, 0x5A, 0x8E, 0xCC, 0xBE, 0x9D, 0x0F, 0xD7, 0x30, 0x68, 0x01, 0x2C, 0x89, 0x4E, 0x2E, 0x87, 0xCC, 0xB5, 0x80, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, +}; +static const struct frost_vec_nonce_agg_case frost_vec_nonce_agg_error_cases[3] = { + { 2, { 0, 4 }, 1, { 0 } }, + { 2, { 5, 1 }, 0, { 0 } }, + { 2, { 6, 1 }, 0, { 0 } }, +}; + +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]; +}; +static const struct frost_vec_group frost_vec_sign_groups[4] = { + { 2, 3, { 0x02, 0xD7, 0x72, 0xA0, 0x9F, 0x5F, 0x67, 0x57, 0x83, 0xD2, 0x75, 0xED, 0x9F, 0x6A, 0xAE, 0xDB, 0x2E, 0xCC, 0xBC, 0x74, 0x17, 0x1B, 0x37, 0xAC, 0x23, 0xAE, 0x3B, 0xBD, 0x9D, 0x7A, 0xE2, 0xCD, 0xAA }, 5, { + { 0x03, 0x9E, 0xE3, 0x33, 0x5A, 0xF4, 0x8D, 0xFE, 0x23, 0x70, 0x2A, 0xB3, 0x53, 0xF4, 0xAF, 0x20, 0xD4, 0x01, 0xF6, 0x7A, 0x13, 0x0D, 0xF7, 0x83, 0xCC, 0x84, 0x57, 0x32, 0x3A, 0x86, 0x0A, 0x2F, 0xB4 }, + { 0x02, 0x84, 0xDC, 0x4A, 0xB2, 0xCB, 0x78, 0xA6, 0x21, 0xEB, 0x87, 0xFA, 0x1F, 0x14, 0xBC, 0xE2, 0xB7, 0x25, 0xAF, 0xEA, 0xAC, 0x98, 0x1A, 0xDC, 0xBA, 0xFF, 0x5C, 0xC2, 0xD4, 0x17, 0xD2, 0xA6, 0x3A }, + { 0x03, 0x64, 0x41, 0xEC, 0x2D, 0x4C, 0x12, 0x66, 0x20, 0x1C, 0xD8, 0x9B, 0x69, 0x54, 0x9A, 0x2F, 0x5B, 0x21, 0x88, 0x61, 0x2A, 0x0D, 0x43, 0x41, 0x53, 0xE6, 0x25, 0xFB, 0x38, 0x17, 0x3D, 0xD5, 0x09 }, + { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07 }, + { 0x02, 0xA5, 0x36, 0x3A, 0x09, 0x93, 0xE3, 0xE2, 0x09, 0x6E, 0xF8, 0x0B, 0x7B, 0x4D, 0xA1, 0xED, 0xF6, 0x50, 0xDB, 0xF0, 0x2C, 0xAE, 0x16, 0x8B, 0xB4, 0xAC, 0xC0, 0xE9, 0x0A, 0x24, 0xCE, 0xD0, 0xFD } + }, 4, { + { 0x53, 0x44, 0x2F, 0xA9, 0xBD, 0x72, 0xEE, 0xA0, 0xA4, 0x2D, 0xF6, 0xF2, 0xD2, 0xD7, 0x6A, 0x2C, 0x0D, 0x3A, 0x3D, 0xFA, 0x2B, 0xE2, 0xF8, 0x20, 0xF4, 0x1A, 0xDE, 0x97, 0x6B, 0x82, 0x59, 0xFB }, + { 0x5A, 0x7F, 0x9B, 0xD4, 0x1F, 0x4B, 0x54, 0x46, 0x64, 0xC5, 0x4D, 0x77, 0x7D, 0x43, 0x30, 0x3C, 0xB5, 0x30, 0x24, 0x34, 0xF9, 0x90, 0x3B, 0x9B, 0x55, 0x2C, 0x4E, 0x55, 0x2B, 0xF0, 0x22, 0x01 }, + { 0x61, 0xBB, 0x07, 0xFE, 0x81, 0x23, 0xB9, 0xEC, 0x25, 0x5C, 0xA3, 0xFC, 0x27, 0xAE, 0xF6, 0x4D, 0x5D, 0x26, 0x0A, 0x6F, 0xC7, 0x3D, 0x7F, 0x15, 0xB6, 0x3D, 0xBE, 0x12, 0xEC, 0x5D, 0xEA, 0x07 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, 5, { + { 0x03, 0xFC, 0x0D, 0x3E, 0x21, 0x2D, 0x25, 0x02, 0x73, 0x56, 0xA2, 0xC9, 0xBB, 0x7E, 0xDC, 0x3B, 0x90, 0x0D, 0xEA, 0x5E, 0x32, 0xAB, 0x10, 0xC0, 0x38, 0x68, 0xE0, 0x1C, 0x84, 0x90, 0xF9, 0xD3, 0x62, 0x02, 0xC6, 0x13, 0x89, 0xB6, 0x46, 0x9B, 0x43, 0x45, 0xE0, 0x06, 0x40, 0xCD, 0xC7, 0xEC, 0xA3, 0x01, 0x54, 0x7B, 0x97, 0xD3, 0x0F, 0xC1, 0x1A, 0xF4, 0x10, 0xE2, 0x3A, 0xD7, 0xB4, 0xBF, 0x69, 0xEE }, + { 0x03, 0x70, 0x6F, 0x00, 0x35, 0x3E, 0xA6, 0x9C, 0x08, 0x36, 0xBF, 0x63, 0xC2, 0x88, 0x4D, 0x2D, 0xE5, 0xAF, 0xE5, 0x49, 0xA3, 0x3E, 0xC8, 0x74, 0x27, 0xCA, 0x8B, 0x5C, 0xF4, 0x66, 0x6B, 0x28, 0xAE, 0x02, 0x1B, 0x63, 0x00, 0xD0, 0x54, 0x5E, 0x0B, 0x22, 0x5C, 0x2D, 0xFC, 0x67, 0xAE, 0x33, 0xA9, 0xB0, 0x25, 0x9B, 0x62, 0x80, 0x97, 0x40, 0x36, 0x37, 0x17, 0xE0, 0x5C, 0xDA, 0x4C, 0xC9, 0xEB, 0xFC }, + { 0x02, 0xB7, 0xF6, 0xEF, 0x56, 0x6D, 0xD2, 0xDD, 0xAA, 0x6A, 0xF3, 0x83, 0x71, 0xA4, 0x1F, 0x80, 0xF9, 0x3A, 0x90, 0xB9, 0xF4, 0x07, 0xB5, 0xBD, 0xB8, 0xED, 0x76, 0x3F, 0x00, 0x10, 0x3D, 0xB0, 0xFC, 0x03, 0x9C, 0x67, 0x76, 0x04, 0xE7, 0xB7, 0x5F, 0xF6, 0xE4, 0x7C, 0x42, 0xB0, 0x24, 0x9A, 0x3B, 0xAA, 0x9C, 0xC6, 0xB1, 0x7E, 0x68, 0xD6, 0xD7, 0x8E, 0x21, 0xAB, 0xA9, 0xD0, 0x4B, 0xF4, 0x07, 0x45 }, + { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x02, 0x87, 0xBF, 0x89, 0x1D, 0x2A, 0x6D, 0xEA, 0xEB, 0xAD, 0xC9, 0x09, 0x35, 0x2A, 0xA9, 0x40, 0x5D, 0x14, 0x28, 0xC1, 0x5F, 0x4B, 0x75, 0xF0, 0x4D, 0xAE, 0x64, 0x2A, 0x95, 0xC2, 0x54, 0x84, 0x80 }, + { 0x02, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x02, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 } + }, 5, { + { 0x67, 0xAF, 0xBE, 0x2B, 0x50, 0xF5, 0x21, 0x56, 0x9B, 0x9C, 0x1D, 0x94, 0x3F, 0x8F, 0xE2, 0x06, 0x20, 0xB8, 0xC2, 0x5F, 0xA8, 0x1E, 0x97, 0x88, 0x71, 0x8A, 0xF6, 0xEE, 0x87, 0xD5, 0x27, 0x5C, 0x9A, 0x48, 0x5A, 0x63, 0x4F, 0xE4, 0x15, 0x58, 0xE4, 0xE1, 0x08, 0xFB, 0xB5, 0x2C, 0x5C, 0xF6, 0x16, 0xC0, 0xCD, 0xF0, 0x2B, 0xC0, 0xC1, 0x0A, 0x99, 0x35, 0x9F, 0xF6, 0xC1, 0xBD, 0x70, 0x5C }, + { 0x6E, 0x5A, 0xAB, 0xD8, 0x14, 0xF3, 0x00, 0x45, 0x74, 0x4D, 0xC4, 0x70, 0x10, 0x3D, 0x44, 0xBC, 0xD8, 0x46, 0x28, 0x4D, 0x7A, 0x76, 0x3F, 0x9B, 0xA3, 0xF5, 0xC7, 0x3D, 0xCE, 0x20, 0xBF, 0x45, 0x9F, 0xCE, 0xDE, 0x0D, 0xFF, 0xF0, 0x9B, 0x9E, 0x01, 0x50, 0xCE, 0x5A, 0x2C, 0x05, 0xD3, 0x19, 0x9B, 0x4B, 0x09, 0x87, 0xA1, 0x8C, 0x49, 0xE9, 0x27, 0x3D, 0xEA, 0xDB, 0xBA, 0x40, 0xB4, 0xD6 }, + { 0x76, 0x2F, 0x46, 0x01, 0xAC, 0x20, 0x6E, 0x1F, 0x14, 0x97, 0xEB, 0x54, 0x12, 0x02, 0xB7, 0x27, 0xCC, 0x19, 0xFA, 0x04, 0x50, 0x28, 0x9C, 0x77, 0x8B, 0x5D, 0x5F, 0x4F, 0x1A, 0x4B, 0x53, 0xF4, 0xD6, 0x3D, 0x31, 0x2C, 0xC2, 0xC9, 0x19, 0x6D, 0x08, 0xFD, 0x62, 0xF3, 0x95, 0x8F, 0xE8, 0xBB, 0xC6, 0x6B, 0x85, 0x17, 0xD1, 0x0D, 0xE5, 0x34, 0xF6, 0xA6, 0x41, 0xD0, 0xE6, 0xE5, 0xEB, 0xCB }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x67, 0xAF, 0xBE, 0x2B, 0x50, 0xF5, 0x21, 0x56, 0x9B, 0x9C, 0x1D, 0x94, 0x3F, 0x8F, 0xE2, 0x06, 0x20, 0xB8, 0xC2, 0x5F, 0xA8, 0x1E, 0x97, 0x88, 0x71, 0x8A, 0xF6, 0xEE, 0x87, 0xD5, 0x27, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, 0, {} }, + { 1, 3, { 0x03, 0xD1, 0x93, 0x9B, 0xE8, 0x7D, 0x18, 0xEA, 0x5A, 0xB3, 0x02, 0xE2, 0x70, 0x77, 0xD1, 0x6B, 0x2C, 0x2F, 0xD9, 0x35, 0x16, 0xF9, 0x15, 0x14, 0xBA, 0x04, 0x99, 0x33, 0xD3, 0x48, 0xDA, 0x44, 0x1F }, 5, { + { 0x03, 0xD1, 0x93, 0x9B, 0xE8, 0x7D, 0x18, 0xEA, 0x5A, 0xB3, 0x02, 0xE2, 0x70, 0x77, 0xD1, 0x6B, 0x2C, 0x2F, 0xD9, 0x35, 0x16, 0xF9, 0x15, 0x14, 0xBA, 0x04, 0x99, 0x33, 0xD3, 0x48, 0xDA, 0x44, 0x1F }, + { 0x03, 0xD1, 0x93, 0x9B, 0xE8, 0x7D, 0x18, 0xEA, 0x5A, 0xB3, 0x02, 0xE2, 0x70, 0x77, 0xD1, 0x6B, 0x2C, 0x2F, 0xD9, 0x35, 0x16, 0xF9, 0x15, 0x14, 0xBA, 0x04, 0x99, 0x33, 0xD3, 0x48, 0xDA, 0x44, 0x1F }, + { 0x03, 0xD1, 0x93, 0x9B, 0xE8, 0x7D, 0x18, 0xEA, 0x5A, 0xB3, 0x02, 0xE2, 0x70, 0x77, 0xD1, 0x6B, 0x2C, 0x2F, 0xD9, 0x35, 0x16, 0xF9, 0x15, 0x14, 0xBA, 0x04, 0x99, 0x33, 0xD3, 0x48, 0xDA, 0x44, 0x1F }, + { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07 }, + { 0x03, 0x94, 0xF8, 0x59, 0x2D, 0xC5, 0xFE, 0xC7, 0x6C, 0xFF, 0x92, 0x20, 0x0E, 0xD3, 0xBA, 0x2B, 0xCF, 0x78, 0x51, 0x8B, 0x46, 0xB7, 0x06, 0xA4, 0x7B, 0xD5, 0x54, 0x58, 0xDB, 0x31, 0xD2, 0x94, 0xA7 } + }, 4, { + { 0x06, 0xD4, 0x7E, 0x05, 0xE9, 0x74, 0x81, 0x42, 0x86, 0x54, 0x56, 0x3E, 0x5A, 0xE6, 0x9C, 0x20, 0xC4, 0x96, 0x42, 0x77, 0x3B, 0x73, 0x34, 0x22, 0x0E, 0x63, 0x11, 0x02, 0x59, 0xA3, 0x0C, 0x32 }, + { 0x06, 0xD4, 0x7E, 0x05, 0xE9, 0x74, 0x81, 0x42, 0x86, 0x54, 0x56, 0x3E, 0x5A, 0xE6, 0x9C, 0x20, 0xC4, 0x96, 0x42, 0x77, 0x3B, 0x73, 0x34, 0x22, 0x0E, 0x63, 0x11, 0x02, 0x59, 0xA3, 0x0C, 0x32 }, + { 0x06, 0xD4, 0x7E, 0x05, 0xE9, 0x74, 0x81, 0x42, 0x86, 0x54, 0x56, 0x3E, 0x5A, 0xE6, 0x9C, 0x20, 0xC4, 0x96, 0x42, 0x77, 0x3B, 0x73, 0x34, 0x22, 0x0E, 0x63, 0x11, 0x02, 0x59, 0xA3, 0x0C, 0x32 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, 5, { + { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, + { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, + { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, + { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x02, 0x87, 0xBF, 0x89, 0x1D, 0x2A, 0x6D, 0xEA, 0xEB, 0xAD, 0xC9, 0x09, 0x35, 0x2A, 0xA9, 0x40, 0x5D, 0x14, 0x28, 0xC1, 0x5F, 0x4B, 0x75, 0xF0, 0x4D, 0xAE, 0x64, 0x2A, 0x95, 0xC2, 0x54, 0x84, 0x80 }, + { 0x02, 0xFB, 0xEA, 0x8F, 0x3C, 0x4C, 0xCA, 0x7D, 0xFD, 0x6B, 0xD6, 0x1F, 0x7D, 0xF7, 0xB4, 0x9B, 0xE7, 0x20, 0xD0, 0xDE, 0x01, 0x41, 0x44, 0x45, 0x7C, 0x1E, 0xEB, 0x08, 0x82, 0xB4, 0x0C, 0xA7, 0x6B, 0x03, 0x28, 0x9A, 0x43, 0xF1, 0x64, 0xE3, 0x40, 0x3C, 0xDA, 0x98, 0x73, 0x83, 0x88, 0x7B, 0xB8, 0x07, 0xEB, 0x8C, 0xF3, 0x32, 0x99, 0x49, 0xDC, 0x80, 0xC3, 0xDD, 0x5D, 0x75, 0x7E, 0xF4, 0xB8, 0x41 } + }, 5, { + { 0x85, 0x98, 0x8D, 0x37, 0xE7, 0xF2, 0xEE, 0x21, 0xFC, 0x47, 0x29, 0x5E, 0x90, 0xD0, 0xFD, 0x85, 0x02, 0x7C, 0xE0, 0xE7, 0x1D, 0xA3, 0x7B, 0x36, 0xCF, 0xB5, 0x5B, 0xD4, 0x71, 0xD3, 0xBA, 0x82, 0xAC, 0xE9, 0xF7, 0x3C, 0x19, 0xDC, 0xD3, 0x87, 0xAE, 0xF3, 0x0F, 0x9E, 0x89, 0x45, 0x64, 0xA4, 0x7F, 0x8B, 0xE8, 0x5F, 0xAA, 0xAE, 0x71, 0x0D, 0xD0, 0xF4, 0x42, 0xDF, 0x2A, 0x38, 0x01, 0x90 }, + { 0x85, 0x98, 0x8D, 0x37, 0xE7, 0xF2, 0xEE, 0x21, 0xFC, 0x47, 0x29, 0x5E, 0x90, 0xD0, 0xFD, 0x85, 0x02, 0x7C, 0xE0, 0xE7, 0x1D, 0xA3, 0x7B, 0x36, 0xCF, 0xB5, 0x5B, 0xD4, 0x71, 0xD3, 0xBA, 0x82, 0xAC, 0xE9, 0xF7, 0x3C, 0x19, 0xDC, 0xD3, 0x87, 0xAE, 0xF3, 0x0F, 0x9E, 0x89, 0x45, 0x64, 0xA4, 0x7F, 0x8B, 0xE8, 0x5F, 0xAA, 0xAE, 0x71, 0x0D, 0xD0, 0xF4, 0x42, 0xDF, 0x2A, 0x38, 0x01, 0x90 }, + { 0x85, 0x98, 0x8D, 0x37, 0xE7, 0xF2, 0xEE, 0x21, 0xFC, 0x47, 0x29, 0x5E, 0x90, 0xD0, 0xFD, 0x85, 0x02, 0x7C, 0xE0, 0xE7, 0x1D, 0xA3, 0x7B, 0x36, 0xCF, 0xB5, 0x5B, 0xD4, 0x71, 0xD3, 0xBA, 0x82, 0xAC, 0xE9, 0xF7, 0x3C, 0x19, 0xDC, 0xD3, 0x87, 0xAE, 0xF3, 0x0F, 0x9E, 0x89, 0x45, 0x64, 0xA4, 0x7F, 0x8B, 0xE8, 0x5F, 0xAA, 0xAE, 0x71, 0x0D, 0xD0, 0xF4, 0x42, 0xDF, 0x2A, 0x38, 0x01, 0x90 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x85, 0x98, 0x8D, 0x37, 0xE7, 0xF2, 0xEE, 0x21, 0xFC, 0x47, 0x29, 0x5E, 0x90, 0xD0, 0xFD, 0x85, 0x02, 0x7C, 0xE0, 0xE7, 0x1D, 0xA3, 0x7B, 0x36, 0xCF, 0xB5, 0x5B, 0xD4, 0x71, 0xD3, 0xBA, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, 0, {} }, + { 3, 3, { 0x02, 0x3E, 0x94, 0xD6, 0xA6, 0x86, 0x20, 0xD3, 0xF6, 0x02, 0x21, 0xA4, 0x18, 0x67, 0x86, 0x27, 0x4A, 0x71, 0x12, 0x21, 0xA8, 0xBB, 0xB3, 0x1A, 0x53, 0x88, 0xDF, 0xA6, 0x71, 0x8E, 0x8E, 0xF7, 0xBB }, 5, { + { 0x03, 0xA3, 0xE9, 0x32, 0xBA, 0x9D, 0xD0, 0x06, 0x3D, 0x72, 0x15, 0x90, 0xB6, 0xEF, 0x21, 0xDD, 0x45, 0x66, 0xA9, 0x7B, 0x20, 0x33, 0x43, 0xFD, 0xE9, 0xDA, 0x58, 0x15, 0xDB, 0x9B, 0xE0, 0x49, 0xCA }, + { 0x02, 0x01, 0xE5, 0xFE, 0xAC, 0x0D, 0xB5, 0x05, 0x9C, 0x32, 0xB0, 0x45, 0xF3, 0x77, 0x99, 0x10, 0x1A, 0x96, 0x26, 0x2B, 0x3C, 0x88, 0xCE, 0x85, 0xD6, 0x10, 0x45, 0x1F, 0xC2, 0x1A, 0x04, 0x57, 0xFF }, + { 0x03, 0xEF, 0x72, 0xD1, 0x0D, 0x1D, 0xFE, 0x4E, 0x78, 0x66, 0x19, 0x53, 0x6A, 0x45, 0x85, 0x07, 0xCA, 0xF1, 0x05, 0xFC, 0xCD, 0xB8, 0x17, 0x3D, 0xAF, 0x2E, 0x35, 0x80, 0x54, 0xAF, 0x2F, 0xA4, 0xA2 }, + { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07 }, + { 0x02, 0x8F, 0xB6, 0x42, 0x47, 0x19, 0xCF, 0x2E, 0x40, 0x14, 0x6B, 0x40, 0x25, 0x71, 0x5F, 0xDA, 0x43, 0x91, 0x8A, 0x72, 0x2F, 0x33, 0xA6, 0x26, 0x0C, 0xB0, 0x8A, 0x21, 0xE6, 0x5C, 0xB9, 0xE1, 0x4E } + }, 4, { + { 0xD4, 0xDE, 0x57, 0x1C, 0x66, 0x2C, 0x31, 0x9E, 0x7C, 0x4F, 0x46, 0x42, 0x0F, 0x5A, 0xCB, 0xEF, 0xD2, 0xD9, 0x05, 0xC3, 0xB5, 0x27, 0x71, 0xC5, 0x53, 0xDE, 0x1F, 0x76, 0x19, 0x7D, 0x94, 0x0D }, + { 0x0E, 0xAA, 0xC0, 0x17, 0xAB, 0xA2, 0x03, 0x02, 0x72, 0xB7, 0xF8, 0xEA, 0xAD, 0x68, 0xE2, 0x2B, 0xF0, 0x7F, 0x08, 0x95, 0x0D, 0x7B, 0x57, 0x0B, 0x69, 0xB2, 0xCC, 0xEF, 0x27, 0x8D, 0x52, 0xC1 }, + { 0x1E, 0x4E, 0x43, 0x44, 0xB9, 0xB5, 0x94, 0x10, 0x58, 0x8C, 0xCF, 0x32, 0x7B, 0x76, 0x6E, 0x4D, 0x29, 0x88, 0x82, 0xD9, 0x04, 0xF0, 0xFB, 0xF2, 0x88, 0xC8, 0x6B, 0x73, 0xAC, 0x59, 0x62, 0xA3 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, 5, { + { 0x02, 0xB6, 0x41, 0x8E, 0xDD, 0xC3, 0xE2, 0xD4, 0x8B, 0x06, 0x4B, 0xE4, 0x6F, 0x71, 0xCE, 0xDE, 0x3A, 0x34, 0x59, 0x4D, 0xEA, 0xC6, 0xE7, 0xF6, 0x70, 0x7C, 0x8A, 0x71, 0xCB, 0x52, 0x3E, 0xA5, 0x86, 0x02, 0xC0, 0xB4, 0x02, 0x21, 0x6E, 0x99, 0x52, 0xE6, 0x49, 0xB8, 0xCC, 0xFE, 0xDB, 0xAC, 0x6A, 0xA1, 0x0B, 0xAE, 0xEF, 0xF4, 0xC0, 0x2E, 0xEA, 0xA1, 0x14, 0x8E, 0x87, 0xC7, 0xB2, 0x1B, 0xDF, 0xB7 }, + { 0x02, 0xB6, 0x3A, 0x2B, 0x31, 0x9D, 0x64, 0xA7, 0xBF, 0xE6, 0x63, 0x44, 0x04, 0xCB, 0x9D, 0x80, 0xAA, 0xA5, 0x7B, 0xAF, 0xD8, 0xAA, 0x01, 0xFC, 0x52, 0xBF, 0x77, 0x23, 0x2D, 0xC0, 0xEE, 0x4B, 0x60, 0x03, 0x58, 0xE8, 0xB8, 0xF6, 0xFB, 0x17, 0xFB, 0x5D, 0x92, 0xFA, 0xFA, 0xC1, 0x09, 0x37, 0x73, 0x64, 0x5F, 0xE3, 0x23, 0x30, 0xD6, 0xE2, 0x77, 0x4B, 0x4B, 0xBB, 0xCE, 0xF7, 0xDD, 0xFA, 0x51, 0x02 }, + { 0x03, 0x64, 0xF6, 0x0E, 0x66, 0xB7, 0xBC, 0x35, 0xA3, 0x32, 0xB4, 0xF9, 0x68, 0x8B, 0xD5, 0xCA, 0x2E, 0xF5, 0x08, 0xE2, 0x5C, 0x69, 0x1D, 0x6A, 0x1A, 0x19, 0x40, 0x97, 0xD1, 0x70, 0xBB, 0xCC, 0xE6, 0x02, 0x49, 0x4A, 0xB4, 0x72, 0x55, 0x52, 0x1F, 0x01, 0x34, 0xEC, 0x7C, 0x41, 0x07, 0x9A, 0x89, 0x55, 0xDA, 0x72, 0x20, 0x17, 0x2A, 0x60, 0x37, 0x1D, 0xC3, 0x2C, 0x69, 0x6A, 0xE5, 0xD6, 0x14, 0x10 }, + { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x02, 0x87, 0xBF, 0x89, 0x1D, 0x2A, 0x6D, 0xEA, 0xEB, 0xAD, 0xC9, 0x09, 0x35, 0x2A, 0xA9, 0x40, 0x5D, 0x14, 0x28, 0xC1, 0x5F, 0x4B, 0x75, 0xF0, 0x4D, 0xAE, 0x64, 0x2A, 0x95, 0xC2, 0x54, 0x84, 0x80 }, + { 0x03, 0x35, 0xCC, 0xFF, 0xD0, 0xF3, 0xA9, 0x11, 0x0F, 0xF3, 0x68, 0xB7, 0x23, 0x60, 0xD7, 0x6A, 0x99, 0x40, 0x91, 0x0B, 0xD2, 0xDB, 0x6C, 0x2C, 0xCC, 0x26, 0xF2, 0xC4, 0xDA, 0x98, 0x4A, 0x1E, 0x9B, 0x03, 0x50, 0x2D, 0x16, 0xAC, 0x8A, 0xE6, 0x32, 0x2A, 0x0A, 0xE9, 0xA8, 0xCB, 0xE8, 0x87, 0x15, 0x8D, 0xE8, 0x23, 0x6A, 0x6F, 0x1C, 0x51, 0x0B, 0x2D, 0x5D, 0x06, 0xF0, 0x0A, 0x85, 0x1B, 0x48, 0xD0 } + }, 5, { + { 0x7B, 0x22, 0x47, 0xA3, 0x98, 0x0C, 0x88, 0x71, 0x4A, 0x08, 0x21, 0xF2, 0x30, 0xF6, 0x89, 0xF4, 0x36, 0xFB, 0xF8, 0x0B, 0x0B, 0x6D, 0xED, 0x33, 0x54, 0x0B, 0x92, 0xCB, 0x65, 0xBA, 0x6E, 0xD1, 0x49, 0xA8, 0xAD, 0xAF, 0x97, 0xEF, 0x6D, 0xBA, 0xA6, 0x01, 0x5C, 0xD5, 0xBA, 0x84, 0xE4, 0xCA, 0xAD, 0xB7, 0xA4, 0x53, 0x50, 0x8D, 0xD1, 0x7F, 0xD8, 0xEE, 0x36, 0x18, 0xE1, 0x19, 0xC0, 0xF9 }, + { 0xB1, 0x45, 0x6F, 0xA8, 0xF9, 0x24, 0x86, 0x0A, 0x66, 0x5A, 0xFC, 0x2A, 0xE2, 0x74, 0x6E, 0x6E, 0x2C, 0x99, 0xEB, 0xBE, 0x4B, 0xC1, 0xD0, 0xF5, 0xBD, 0x00, 0xBC, 0x52, 0xCB, 0x7D, 0xFD, 0x79, 0xA8, 0x23, 0xD9, 0x29, 0x11, 0x39, 0x38, 0x52, 0xD4, 0xEC, 0xCC, 0x59, 0x38, 0x7D, 0xB8, 0x8C, 0x52, 0x6F, 0xD1, 0xAD, 0x75, 0x74, 0xA3, 0x33, 0x68, 0x93, 0xB6, 0x18, 0x75, 0x0D, 0xBD, 0xDD }, + { 0xC3, 0x09, 0xD4, 0xBC, 0x04, 0x57, 0xA9, 0xD6, 0x03, 0x1C, 0xDA, 0xC3, 0x3B, 0xAF, 0xA4, 0x7B, 0xAB, 0x23, 0x34, 0x44, 0x5B, 0xF2, 0x2D, 0x09, 0xE1, 0x93, 0x6F, 0x91, 0x97, 0x56, 0xD2, 0x75, 0xBC, 0x09, 0x41, 0x0F, 0x5D, 0x39, 0xE5, 0xD7, 0x01, 0xC8, 0x1B, 0xBA, 0x99, 0xE4, 0xE9, 0x5F, 0x9E, 0x07, 0xFF, 0xC3, 0x2C, 0x32, 0x2F, 0x25, 0x60, 0x45, 0x82, 0xCB, 0x24, 0x2D, 0xD4, 0x6A }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x7B, 0x22, 0x47, 0xA3, 0x98, 0x0C, 0x88, 0x71, 0x4A, 0x08, 0x21, 0xF2, 0x30, 0xF6, 0x89, 0xF4, 0x36, 0xFB, 0xF8, 0x0B, 0x0B, 0x6D, 0xED, 0x33, 0x54, 0x0B, 0x92, 0xCB, 0x65, 0xBA, 0x6E, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, 0, {} }, + { 3, 5, { 0x03, 0xE1, 0xAE, 0xA0, 0x0A, 0x7B, 0x8D, 0x0E, 0x03, 0x93, 0x66, 0x4F, 0xEB, 0xBD, 0x31, 0x56, 0x9A, 0x02, 0xCA, 0xF2, 0x23, 0xD9, 0xAD, 0x83, 0xE9, 0x03, 0x31, 0xDC, 0x18, 0xB1, 0x98, 0x73, 0x58 }, 7, { + { 0x02, 0xF3, 0x33, 0xED, 0xD2, 0xB6, 0xF5, 0x32, 0xC2, 0xEF, 0x6C, 0x42, 0xE8, 0x03, 0xB6, 0x33, 0xA4, 0x22, 0x89, 0xD0, 0x56, 0x7A, 0x75, 0xC5, 0x0E, 0xB1, 0xC8, 0xCF, 0x85, 0xEC, 0x48, 0x0E, 0x8F }, + { 0x02, 0x53, 0x22, 0xF6, 0x36, 0x02, 0xEC, 0xCF, 0x14, 0x65, 0x41, 0xB7, 0xC9, 0xEE, 0x4D, 0x1F, 0xCB, 0x84, 0xEC, 0x13, 0x94, 0x71, 0x42, 0x04, 0x72, 0x18, 0x2A, 0xE9, 0x68, 0x67, 0x6A, 0x38, 0x7F }, + { 0x02, 0x30, 0x63, 0x9C, 0xEC, 0x0A, 0x83, 0x98, 0x2E, 0x17, 0x6D, 0x69, 0x05, 0xCE, 0x06, 0x20, 0xFD, 0xC5, 0x7E, 0x15, 0x15, 0x65, 0xA3, 0x9D, 0x0E, 0x08, 0x21, 0xB8, 0xE7, 0x53, 0xAE, 0x85, 0xB0 }, + { 0x02, 0x6E, 0x1A, 0x50, 0xE6, 0x72, 0xFE, 0xDD, 0x3F, 0x3C, 0x37, 0x8D, 0x61, 0x21, 0xE5, 0x70, 0x2B, 0x05, 0x06, 0x69, 0xDB, 0xC2, 0x41, 0xD2, 0xC2, 0x29, 0x98, 0x80, 0x15, 0x2C, 0xD2, 0x07, 0xBD }, + { 0x02, 0xDC, 0x06, 0xC4, 0xCA, 0x91, 0x9D, 0xE7, 0x0B, 0x4B, 0x82, 0x81, 0x90, 0x1C, 0xCF, 0x94, 0x71, 0xAB, 0x91, 0xFB, 0xFB, 0xEE, 0x1A, 0x8C, 0x57, 0x0D, 0x83, 0x91, 0x1C, 0xAA, 0xF9, 0xE2, 0xFA }, + { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07 }, + { 0x03, 0x1B, 0x21, 0xF2, 0xB4, 0x93, 0x1A, 0xC1, 0x74, 0x35, 0xD9, 0x43, 0xAB, 0xAD, 0xB9, 0x69, 0xCB, 0xCD, 0x4A, 0xFE, 0x3E, 0xB7, 0x1D, 0x1C, 0xD6, 0x2E, 0x87, 0xF9, 0xD2, 0xBD, 0x82, 0x51, 0x64 } + }, 6, { + { 0x77, 0xC9, 0x31, 0x6A, 0x64, 0x77, 0x0B, 0x17, 0xD5, 0x00, 0x84, 0x0E, 0x02, 0x0A, 0x94, 0x78, 0xF7, 0x93, 0xD3, 0x7D, 0xB0, 0xE6, 0xA2, 0x76, 0xCB, 0x4E, 0x62, 0x70, 0x18, 0x7D, 0x6C, 0x90 }, + { 0x74, 0x18, 0x04, 0x20, 0xA7, 0x84, 0x18, 0x9B, 0x55, 0xF8, 0xC4, 0x66, 0x70, 0x75, 0xE8, 0x9C, 0x20, 0x64, 0xFF, 0x48, 0x1B, 0x6E, 0xD2, 0xA2, 0x3A, 0x75, 0x17, 0xAF, 0x71, 0xF6, 0xB7, 0xA8 }, + { 0xBE, 0x6B, 0x9F, 0xB0, 0x75, 0x86, 0xEB, 0xAB, 0xD2, 0x34, 0xEE, 0xE0, 0xA0, 0x5E, 0x81, 0x3D, 0xFF, 0xC1, 0x4D, 0x73, 0x78, 0x20, 0x85, 0xC8, 0xDF, 0xE7, 0x7C, 0x1F, 0xAD, 0xDA, 0x71, 0x72 }, + { 0x56, 0xC4, 0x04, 0x19, 0xCE, 0x7F, 0x84, 0x49, 0x49, 0xB5, 0x03, 0x7C, 0x91, 0xC4, 0x5E, 0x5F, 0xDA, 0xF9, 0xE1, 0x19, 0x17, 0xB3, 0x1B, 0xAE, 0xFB, 0xD3, 0x31, 0x33, 0xFB, 0xF2, 0x58, 0xAD }, + { 0x3D, 0x21, 0x31, 0x5C, 0xB2, 0x6D, 0xE2, 0x73, 0xBC, 0x79, 0x02, 0x3A, 0x44, 0xA7, 0x80, 0x00, 0x6C, 0xBD, 0x97, 0x1F, 0xA9, 0x6F, 0x34, 0x90, 0x4E, 0x0A, 0x95, 0x79, 0x2C, 0x74, 0xAE, 0x9A }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, 7, { + { 0x02, 0xEB, 0xD2, 0x1E, 0x4F, 0x4E, 0xA2, 0x77, 0x2B, 0xD4, 0xE4, 0x27, 0xD9, 0x8C, 0x9D, 0xC2, 0x68, 0x89, 0x4D, 0x18, 0xEC, 0x45, 0xE1, 0x40, 0x63, 0x78, 0x5B, 0x89, 0x2D, 0x42, 0x92, 0x1F, 0xF4, 0x02, 0xFB, 0x73, 0x02, 0x8B, 0x71, 0x0A, 0xCB, 0xE4, 0x9F, 0xC2, 0xD9, 0x95, 0x75, 0x7E, 0x07, 0x77, 0x60, 0xCA, 0x7C, 0x1B, 0x24, 0x52, 0x79, 0x1A, 0x3B, 0xDA, 0x08, 0x6B, 0x91, 0xA1, 0xCE, 0xF3 }, + { 0x02, 0xBC, 0xBE, 0xF1, 0x17, 0x1F, 0x78, 0x85, 0x70, 0x16, 0xB2, 0x05, 0xC0, 0xC9, 0xDE, 0x61, 0x75, 0x0C, 0xC2, 0x14, 0x48, 0xC1, 0x67, 0xAA, 0xFA, 0xFD, 0x91, 0x90, 0x96, 0x2A, 0xEA, 0xFF, 0x79, 0x03, 0x27, 0x98, 0xE5, 0x33, 0xA6, 0x5F, 0x94, 0xD1, 0xDF, 0xF9, 0x01, 0xA2, 0xCB, 0x4F, 0x10, 0x7D, 0x49, 0xFE, 0x6B, 0x05, 0x27, 0xE9, 0x5D, 0x7A, 0xE2, 0x4E, 0x4D, 0xBB, 0xB6, 0x81, 0xF5, 0x52 }, + { 0x02, 0xA4, 0x55, 0xD7, 0x31, 0xEC, 0xDC, 0xAA, 0x59, 0x22, 0x8C, 0xE8, 0x2C, 0xA1, 0xB5, 0xCF, 0x45, 0x97, 0x4F, 0x6E, 0x6D, 0x21, 0xEB, 0x57, 0x50, 0x1B, 0xE2, 0x23, 0x10, 0xF0, 0x89, 0xBF, 0x69, 0x03, 0x7E, 0x26, 0x47, 0xE7, 0x3C, 0x02, 0x2A, 0x91, 0x3C, 0x87, 0xD8, 0x81, 0x3D, 0x48, 0xE7, 0x6D, 0x72, 0x31, 0x3D, 0xF4, 0x69, 0x76, 0x44, 0xC2, 0x3D, 0xDE, 0x82, 0x0D, 0xBE, 0xF7, 0x6D, 0x4A }, + { 0x02, 0x67, 0x30, 0xE2, 0x78, 0xBD, 0xB6, 0x5A, 0x8E, 0x77, 0x18, 0x64, 0x10, 0x38, 0x90, 0xA1, 0xF1, 0x0B, 0xA5, 0xAB, 0x9B, 0x42, 0x9E, 0x08, 0x43, 0xCC, 0xB4, 0x5F, 0xD2, 0xD9, 0x05, 0x2C, 0x6A, 0x03, 0x52, 0x5D, 0x89, 0xB7, 0xC9, 0x61, 0x5F, 0x84, 0x6D, 0x36, 0x22, 0x3D, 0x77, 0x7C, 0x5D, 0x6B, 0xF1, 0x34, 0xFD, 0x19, 0x81, 0xFC, 0xB2, 0xF6, 0xB9, 0x4F, 0x7F, 0xA7, 0x0C, 0xE6, 0x68, 0xAB }, + { 0x03, 0x4D, 0x04, 0x8E, 0xD3, 0x55, 0x4B, 0xE5, 0xD0, 0xF0, 0x33, 0x08, 0x93, 0x60, 0x60, 0xFA, 0xAA, 0x8A, 0x08, 0x89, 0xFD, 0x13, 0x5E, 0x81, 0x76, 0xDC, 0x08, 0x43, 0xC4, 0xFB, 0x68, 0xA8, 0x99, 0x03, 0x49, 0x74, 0x42, 0xC3, 0xAC, 0x05, 0xC9, 0x8A, 0x8F, 0xDD, 0xB4, 0x06, 0x46, 0xA6, 0x20, 0x3A, 0x6E, 0xA5, 0x3E, 0x20, 0x84, 0x6F, 0x8D, 0x0A, 0x86, 0x34, 0x47, 0x01, 0x1B, 0xE8, 0xEA, 0x71 }, + { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x02, 0x87, 0xBF, 0x89, 0x1D, 0x2A, 0x6D, 0xEA, 0xEB, 0xAD, 0xC9, 0x09, 0x35, 0x2A, 0xA9, 0x40, 0x5D, 0x14, 0x28, 0xC1, 0x5F, 0x4B, 0x75, 0xF0, 0x4D, 0xAE, 0x64, 0x2A, 0x95, 0xC2, 0x54, 0x84, 0x80 }, + { 0x03, 0x42, 0xB8, 0x12, 0xEE, 0x2B, 0x49, 0x9B, 0xAC, 0x6A, 0xAE, 0x1C, 0xC4, 0xF3, 0xB2, 0xE0, 0x73, 0x9D, 0x0C, 0x3D, 0xCB, 0x55, 0x85, 0x13, 0xDC, 0x73, 0x7A, 0xAA, 0x4B, 0x7F, 0x5B, 0xF7, 0xDE, 0x02, 0x3A, 0xFC, 0x98, 0xC8, 0xEB, 0xD4, 0x7B, 0x22, 0x77, 0xE6, 0x50, 0x05, 0x65, 0x43, 0xF2, 0x87, 0xE4, 0x58, 0x5B, 0xC8, 0x41, 0x9F, 0x47, 0x2D, 0x6A, 0x3F, 0xC3, 0xE5, 0xD2, 0xB4, 0x2D, 0x4A } + }, 7, { + { 0x8A, 0x11, 0x60, 0x47, 0x9C, 0x41, 0x88, 0xDA, 0x23, 0x7C, 0x53, 0x63, 0x9E, 0xDE, 0xFC, 0x60, 0xC2, 0x4E, 0x87, 0xF9, 0x1A, 0xC8, 0x97, 0x2D, 0x96, 0x60, 0x00, 0x68, 0x0A, 0x7D, 0x07, 0x32, 0x8A, 0x53, 0x18, 0xB8, 0x17, 0x26, 0xCB, 0x9B, 0x16, 0xB9, 0x32, 0x12, 0x64, 0x61, 0x1C, 0x7D, 0xF0, 0xC7, 0x37, 0xBB, 0x64, 0x94, 0x1F, 0x79, 0xD4, 0x03, 0xD2, 0xD5, 0x03, 0xFA, 0xB3, 0xAB }, + { 0x38, 0x21, 0x4C, 0x92, 0x72, 0x97, 0xFD, 0x9F, 0x61, 0x72, 0x2C, 0x93, 0xA6, 0x56, 0x8A, 0x7C, 0xFE, 0x37, 0xD8, 0xBF, 0xA7, 0xC7, 0x38, 0x22, 0x33, 0x7F, 0xEA, 0x77, 0xAD, 0x97, 0xA3, 0x25, 0xCB, 0x33, 0xA2, 0xD2, 0xCB, 0x48, 0x6A, 0x6F, 0x2E, 0xE5, 0x97, 0xD7, 0xED, 0x9D, 0x55, 0x52, 0xDD, 0x09, 0x64, 0x52, 0xE3, 0xAC, 0x9D, 0xFA, 0x97, 0x87, 0x01, 0x9B, 0xAB, 0x76, 0x52, 0xEB }, + { 0xE3, 0x49, 0x04, 0x27, 0xC9, 0x87, 0x33, 0x36, 0x62, 0xC6, 0x49, 0xE5, 0x80, 0x16, 0x83, 0xB8, 0xBF, 0xCB, 0x7E, 0x5F, 0x07, 0x25, 0x90, 0x8D, 0xBC, 0x96, 0x8A, 0xA8, 0x6A, 0xF1, 0xFA, 0x2C, 0x10, 0xE4, 0x69, 0x07, 0x66, 0xA5, 0x47, 0xCA, 0x58, 0x13, 0x6E, 0xF3, 0xDC, 0x10, 0x45, 0xA8, 0xC3, 0xEC, 0xEA, 0x53, 0x2A, 0x05, 0x7F, 0x1A, 0x1A, 0xF1, 0xE4, 0x27, 0x61, 0xE0, 0xEC, 0xD7 }, + { 0xEE, 0x85, 0x5A, 0x53, 0x46, 0x35, 0x21, 0xDE, 0xCA, 0xFA, 0x11, 0x32, 0xD1, 0x21, 0x64, 0x4C, 0xF0, 0xBB, 0xA4, 0xA8, 0x60, 0x45, 0x6F, 0x26, 0x54, 0x02, 0x61, 0x02, 0x3D, 0x9A, 0x49, 0x91, 0x0E, 0x40, 0xFA, 0x14, 0x6B, 0x6B, 0x9D, 0x4B, 0x89, 0x14, 0xD5, 0x7D, 0x0B, 0x14, 0xA0, 0x3B, 0xF5, 0xC7, 0x53, 0x06, 0x7C, 0xC1, 0x44, 0xC6, 0x9C, 0x14, 0xD9, 0x24, 0xF0, 0x37, 0xEF, 0x9E }, + { 0xCE, 0x5F, 0x5A, 0x72, 0x25, 0x36, 0xE5, 0x65, 0x61, 0xC5, 0xC1, 0x25, 0x8A, 0x8E, 0x6A, 0x38, 0x48, 0x0A, 0x7D, 0x00, 0xF7, 0x96, 0x45, 0x46, 0x0C, 0xCA, 0x3D, 0xE7, 0xF1, 0x0E, 0x48, 0x03, 0x08, 0xEF, 0x46, 0xC6, 0x44, 0xD0, 0x1F, 0x0F, 0xCB, 0x05, 0x95, 0x0F, 0x38, 0x4C, 0x65, 0x51, 0x98, 0x10, 0x1B, 0xDD, 0x83, 0xC6, 0x04, 0xA8, 0x48, 0x4F, 0xCC, 0xB4, 0x99, 0x14, 0xCC, 0x39 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x8A, 0x11, 0x60, 0x47, 0x9C, 0x41, 0x88, 0xDA, 0x23, 0x7C, 0x53, 0x63, 0x9E, 0xDE, 0xFC, 0x60, 0xC2, 0x4E, 0x87, 0xF9, 0x1A, 0xC8, 0x97, 0x2D, 0x96, 0x60, 0x00, 0x68, 0x0A, 0x7D, 0x07, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, 0, {} }, +}; +static const struct frost_vec_sign_case frost_vec_sign_valid_cases[29] = { + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 0, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x93, 0xDD, 0xE8, 0xC9, 0xCE, 0xE7, 0x14, 0xEB, 0x5B, 0xDF, 0x2B, 0xE0, 0x0F, 0xEC, 0x33, 0x27, 0xF9, 0xCF, 0x38, 0x6D, 0x3A, 0xC6, 0x72, 0xF0, 0xDA, 0x73, 0x4F, 0xFC, 0x08, 0xE7, 0xA0, 0x41 } }, + { 0, 0, 2, { 0, 1 }, 0, { 0 }, 0, 0, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x93, 0xDD, 0xE8, 0xC9, 0xCE, 0xE7, 0x14, 0xEB, 0x5B, 0xDF, 0x2B, 0xE0, 0x0F, 0xEC, 0x33, 0x27, 0xF9, 0xCF, 0x38, 0x6D, 0x3A, 0xC6, 0x72, 0xF0, 0xDA, 0x73, 0x4F, 0xFC, 0x08, 0xE7, 0xA0, 0x41 } }, + { 0, 0, 2, { 1, 0 }, 1, { 1, 0 }, 0, 0, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x93, 0xDD, 0xE8, 0xC9, 0xCE, 0xE7, 0x14, 0xEB, 0x5B, 0xDF, 0x2B, 0xE0, 0x0F, 0xEC, 0x33, 0x27, 0xF9, 0xCF, 0x38, 0x6D, 0x3A, 0xC6, 0x72, 0xF0, 0xDA, 0x73, 0x4F, 0xFC, 0x08, 0xE7, 0xA0, 0x41 } }, + { 0, 0, 2, { 0, 2 }, 1, { 0, 2 }, 0, 0, { 0x03, 0xE0, 0xD6, 0xD4, 0x49, 0xA7, 0xCD, 0xEC, 0x17, 0x78, 0x5A, 0x2C, 0xF1, 0x4A, 0x4F, 0xC5, 0x23, 0x68, 0xFC, 0x6C, 0x8E, 0xB0, 0x0F, 0x02, 0xF3, 0xB2, 0x18, 0xA7, 0x3F, 0xF6, 0x87, 0x38, 0x8B, 0x03, 0x29, 0x47, 0xBC, 0xD7, 0x43, 0x09, 0x62, 0x69, 0x0D, 0xBA, 0x05, 0x94, 0x71, 0x5D, 0x16, 0xF5, 0xC2, 0x13, 0x6F, 0x75, 0x16, 0xAB, 0x75, 0xA1, 0x0A, 0x0E, 0xDB, 0x3D, 0x5B, 0xBA, 0xD4, 0x6E }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x25, 0x51, 0xE5, 0xEB, 0x41, 0x69, 0x00, 0x87, 0x7F, 0x81, 0x7C, 0xAC, 0xA4, 0x17, 0xF5, 0x17, 0x98, 0x0E, 0x62, 0x01, 0x5A, 0x24, 0x99, 0x5D, 0x4B, 0x43, 0xF4, 0xFC, 0xCD, 0x08, 0x78, 0x5A } }, + { 0, 1, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 1, 1, { 0x02, 0xCB, 0xC2, 0xE4, 0x1A, 0xF8, 0x72, 0x90, 0xA1, 0x40, 0x1D, 0x49, 0x92, 0x7F, 0xC3, 0x0D, 0x7F, 0x40, 0xA4, 0x04, 0xC4, 0xDF, 0x3E, 0x5F, 0xC7, 0x34, 0x01, 0x41, 0x88, 0xDB, 0xC4, 0x4E, 0x15, 0x03, 0xC1, 0x53, 0x12, 0xED, 0xC6, 0x91, 0xEB, 0x21, 0x3F, 0x3B, 0x8A, 0xAC, 0x19, 0x5D, 0x25, 0x1A, 0x39, 0x05, 0x63, 0xCD, 0x5E, 0x31, 0x3D, 0x73, 0x8A, 0x89, 0xDA, 0xEB, 0x4D, 0xA8, 0x07, 0x46 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x09, 0x95, 0x5F, 0x6B, 0x6C, 0xF0, 0x9E, 0xD3, 0x83, 0xF3, 0x3C, 0x1B, 0xFC, 0xFE, 0x05, 0x9E, 0x79, 0xE9, 0xD2, 0x6F, 0xEC, 0xC0, 0x09, 0x5F, 0x4A, 0x31, 0xF2, 0x2E, 0x7E, 0xD2, 0x42, 0xAE } }, + { 0, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x70, 0xE4, 0x50, 0xAF, 0x54, 0x34, 0x13, 0xAD, 0x3F, 0x1C, 0x35, 0x95, 0xB8, 0x43, 0xEC, 0x8D, 0x7A, 0x9E, 0xD4, 0x69, 0x3C, 0x86, 0x75, 0x6D, 0xEE, 0xF7, 0xEB, 0x1D, 0x04, 0x61, 0xF7, 0xC1 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 0, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 0, { }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x90, 0x19, 0xCF, 0xAC, 0x70, 0xEF, 0xAD, 0xC7, 0x89, 0x1B, 0x15, 0x8B, 0x77, 0xC0, 0xC8, 0x0E, 0xBB, 0xF4, 0xF8, 0x84, 0x68, 0xF1, 0x67, 0x0B, 0xB1, 0xB7, 0x46, 0x27, 0xBE, 0x68, 0xE9, 0xB5 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 0, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 38, { 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26 }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x30, 0x1C, 0x26, 0xEC, 0x36, 0x35, 0xBC, 0xD8, 0x35, 0x9B, 0xFF, 0x82, 0x31, 0x2E, 0x37, 0x85, 0x83, 0xD6, 0xA4, 0x70, 0xBD, 0x09, 0x1E, 0xC3, 0xE9, 0xCC, 0x4A, 0x56, 0xCB, 0x50, 0xBB, 0x81 } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 0, 0, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0xB7, 0xC3, 0xFA, 0x9A, 0xEA, 0x2B, 0x09, 0x89, 0xD1, 0x50, 0xB5, 0x74, 0x33, 0x23, 0x30, 0x15, 0xA2, 0x69, 0xCB, 0x56, 0x23, 0x2B, 0x1D, 0xE2, 0xAF, 0xE5, 0x73, 0x49, 0x1D, 0x96, 0x0B, 0x2C } }, + { 1, 0, 1, { 0 }, 0, { 0 }, 0, 0, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0xB7, 0xC3, 0xFA, 0x9A, 0xEA, 0x2B, 0x09, 0x89, 0xD1, 0x50, 0xB5, 0x74, 0x33, 0x23, 0x30, 0x15, 0xA2, 0x69, 0xCB, 0x56, 0x23, 0x2B, 0x1D, 0xE2, 0xAF, 0xE5, 0x73, 0x49, 0x1D, 0x96, 0x0B, 0x2C } }, + { 1, 1, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 1, 1, { 0x02, 0x77, 0xE7, 0x16, 0x75, 0x6B, 0xAE, 0xFD, 0x92, 0x2D, 0xCD, 0x33, 0x9D, 0x08, 0x3F, 0xEB, 0x1C, 0x02, 0x63, 0xB0, 0x69, 0x99, 0x32, 0x84, 0x92, 0x33, 0x1F, 0xB8, 0x76, 0xA2, 0x25, 0xEE, 0xA3, 0x03, 0x39, 0x10, 0xC4, 0xFC, 0x15, 0x1C, 0x7A, 0xA9, 0x14, 0xB4, 0xD2, 0xAC, 0x97, 0xB3, 0xF0, 0x9C, 0x56, 0xA3, 0x6A, 0x5F, 0x95, 0xF1, 0x40, 0x43, 0xD9, 0x02, 0x10, 0xCC, 0x1F, 0xCD, 0x42, 0x45 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x97, 0xF8, 0xFC, 0x6A, 0x3E, 0xB6, 0x5E, 0x25, 0xF3, 0x85, 0x03, 0x41, 0xB8, 0xD5, 0x88, 0x51, 0x56, 0x4F, 0x12, 0xEF, 0x88, 0xD9, 0x96, 0xC5, 0x39, 0x16, 0xC7, 0x55, 0x78, 0x59, 0x5C, 0xFD } }, + { 1, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0xC5, 0x02, 0xC0, 0xA6, 0xCE, 0xF6, 0xDA, 0xEC, 0x24, 0x4D, 0xDF, 0x52, 0x2E, 0x42, 0x23, 0xC8, 0x3F, 0x97, 0x0C, 0x41, 0xBB, 0x99, 0xDE, 0x48, 0x28, 0x58, 0xA4, 0x09, 0x85, 0xC7, 0x58, 0xCB } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 0, 0, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 0, { }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0xAD, 0x2B, 0x79, 0x2E, 0x93, 0x66, 0x21, 0x07, 0x81, 0x40, 0x68, 0x05, 0x1C, 0x45, 0xB6, 0xC9, 0xF5, 0x90, 0x57, 0x0F, 0x19, 0x77, 0x05, 0x37, 0xE4, 0xF5, 0x0E, 0x13, 0x44, 0xF1, 0x00, 0xF3 } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 0, 0, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 38, { 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26 }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0xDC, 0xFB, 0x82, 0x5B, 0x67, 0x52, 0x05, 0xE0, 0x87, 0xDE, 0x88, 0xAA, 0x4D, 0xD5, 0x50, 0xC3, 0x1B, 0x0E, 0xF7, 0x7E, 0x4A, 0x23, 0xD7, 0xA0, 0x46, 0x32, 0x58, 0xCE, 0x58, 0x22, 0x6B, 0x6A } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x30, 0x5F, 0xE5, 0x09, 0xF0, 0x0F, 0x66, 0x5A, 0xAC, 0x83, 0x6D, 0x1E, 0x49, 0xFF, 0x25, 0x39, 0xD3, 0xA1, 0x1A, 0x9B, 0x20, 0x46, 0x24, 0x57, 0xA4, 0x9E, 0xBE, 0x28, 0xBE, 0xD0, 0x67, 0x28 } }, + { 2, 0, 3, { 0, 1, 2 }, 0, { 0 }, 0, 0, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x30, 0x5F, 0xE5, 0x09, 0xF0, 0x0F, 0x66, 0x5A, 0xAC, 0x83, 0x6D, 0x1E, 0x49, 0xFF, 0x25, 0x39, 0xD3, 0xA1, 0x1A, 0x9B, 0x20, 0x46, 0x24, 0x57, 0xA4, 0x9E, 0xBE, 0x28, 0xBE, 0xD0, 0x67, 0x28 } }, + { 2, 0, 3, { 2, 1, 0 }, 1, { 2, 1, 0 }, 0, 0, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x30, 0x5F, 0xE5, 0x09, 0xF0, 0x0F, 0x66, 0x5A, 0xAC, 0x83, 0x6D, 0x1E, 0x49, 0xFF, 0x25, 0x39, 0xD3, 0xA1, 0x1A, 0x9B, 0x20, 0x46, 0x24, 0x57, 0xA4, 0x9E, 0xBE, 0x28, 0xBE, 0xD0, 0x67, 0x28 } }, + { 2, 1, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 1, 1, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x2C, 0x2D, 0xF9, 0x99, 0x12, 0xA2, 0xEE, 0x3E, 0x69, 0x4F, 0x38, 0x08, 0xAF, 0xA1, 0x4B, 0x15, 0xC9, 0x90, 0xAF, 0x29, 0x62, 0x1B, 0x33, 0x85, 0x0A, 0xC1, 0xE2, 0x3D, 0x08, 0xB8, 0x4C, 0x18 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x32, 0xB9, 0xFE, 0xB0, 0x74, 0x68, 0xF1, 0x36, 0x4A, 0x96, 0x04, 0xE7, 0xD9, 0x2B, 0x5F, 0xD2, 0xF3, 0xE3, 0x2E, 0xB0, 0x8B, 0xED, 0x61, 0xCE, 0x4B, 0x43, 0xA8, 0x04, 0xC8, 0x8D, 0x01, 0xF6 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 0, { }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x73, 0xED, 0x44, 0xA6, 0x7A, 0x03, 0xA7, 0x6A, 0xF5, 0x0A, 0x87, 0x9F, 0x37, 0x88, 0x7A, 0xE2, 0xDC, 0x63, 0x02, 0x7D, 0x7F, 0x84, 0xEA, 0xD9, 0xAA, 0xC4, 0x7A, 0x5C, 0x79, 0xD2, 0x24, 0xA1 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 38, { 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26 }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x92, 0x18, 0xAF, 0xB2, 0xA4, 0x86, 0xB5, 0x2A, 0x8E, 0xC0, 0xEC, 0xB6, 0xC8, 0xEE, 0xF1, 0xD0, 0x22, 0xF8, 0xDC, 0x8C, 0x20, 0x32, 0x37, 0xD2, 0xE4, 0x26, 0x7B, 0x02, 0xF4, 0x1F, 0xF7, 0xF3 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x60, 0x3E, 0xC1, 0xEA, 0x86, 0xB2, 0x84, 0xE2, 0x8C, 0xEF, 0xD5, 0x9C, 0x85, 0xF8, 0xDD, 0xC6, 0xDF, 0xE8, 0x1C, 0x07, 0x44, 0xF5, 0x9D, 0x8F, 0xB5, 0xBE, 0xB2, 0x9F, 0x1C, 0x27, 0xF3, 0x8B } }, + { 3, 0, 3, { 0, 1, 2 }, 0, { 0 }, 0, 0, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x60, 0x3E, 0xC1, 0xEA, 0x86, 0xB2, 0x84, 0xE2, 0x8C, 0xEF, 0xD5, 0x9C, 0x85, 0xF8, 0xDD, 0xC6, 0xDF, 0xE8, 0x1C, 0x07, 0x44, 0xF5, 0x9D, 0x8F, 0xB5, 0xBE, 0xB2, 0x9F, 0x1C, 0x27, 0xF3, 0x8B } }, + { 3, 0, 3, { 2, 1, 0 }, 1, { 2, 1, 0 }, 0, 0, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x60, 0x3E, 0xC1, 0xEA, 0x86, 0xB2, 0x84, 0xE2, 0x8C, 0xEF, 0xD5, 0x9C, 0x85, 0xF8, 0xDD, 0xC6, 0xDF, 0xE8, 0x1C, 0x07, 0x44, 0xF5, 0x9D, 0x8F, 0xB5, 0xBE, 0xB2, 0x9F, 0x1C, 0x27, 0xF3, 0x8B } }, + { 3, 0, 3, { 0, 3, 4 }, 1, { 0, 3, 4 }, 0, 0, { 0x03, 0xCE, 0x3C, 0x1C, 0x18, 0x28, 0x29, 0xF3, 0x1D, 0xE2, 0xE6, 0xFD, 0x05, 0x7A, 0x06, 0xCF, 0xA5, 0x23, 0x76, 0xFE, 0xE4, 0x2C, 0x3F, 0xBD, 0x48, 0x7C, 0x19, 0xCF, 0xF3, 0xB5, 0xC7, 0x0D, 0xC5, 0x02, 0x0D, 0x9D, 0xD4, 0x1C, 0x4A, 0x2B, 0x9B, 0x43, 0xDB, 0x7C, 0x4E, 0x93, 0xB7, 0xC5, 0x04, 0x94, 0x64, 0x46, 0x63, 0x6F, 0x25, 0xC5, 0xD8, 0x93, 0xE9, 0x0C, 0x62, 0x62, 0x86, 0xD9, 0x07, 0x65 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x79, 0x45, 0xD5, 0xDE, 0xFF, 0x00, 0xBF, 0x4B, 0xF7, 0x15, 0x77, 0x41, 0x44, 0xC1, 0x0F, 0xF5, 0xE8, 0xC2, 0x5F, 0x7A, 0xC8, 0xC8, 0x86, 0xC3, 0x99, 0x98, 0x25, 0xD3, 0x0C, 0x7C, 0x60, 0x79 } }, + { 3, 1, 5, { 0, 1, 2, 3, 4 }, 1, { 0, 1, 2, 3, 4 }, 1, 1, { 0x03, 0x53, 0x60, 0x24, 0xF2, 0x1D, 0x3C, 0x18, 0xE0, 0xF0, 0x94, 0xD1, 0x5E, 0x9D, 0xDA, 0x07, 0x74, 0x07, 0x54, 0x90, 0x55, 0x70, 0xA1, 0xB6, 0x8C, 0xAF, 0xAC, 0x74, 0x3A, 0x6C, 0x21, 0x37, 0x45, 0x03, 0x7C, 0x9E, 0xA6, 0x73, 0x0C, 0xD2, 0x19, 0x04, 0xC1, 0x31, 0xFF, 0x4A, 0x6C, 0x62, 0x48, 0x0A, 0x7B, 0xAB, 0xAA, 0x75, 0xF0, 0xA4, 0xF6, 0x3F, 0x1A, 0xFD, 0x8D, 0xEE, 0x9F, 0xDD, 0x69, 0x9D }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x5D, 0x70, 0xB8, 0xD3, 0x7B, 0xF0, 0xDB, 0x38, 0x1C, 0xE1, 0x5E, 0x3A, 0xAB, 0x9F, 0x59, 0xBE, 0xCD, 0x54, 0xAD, 0x32, 0xAC, 0x19, 0xA2, 0x16, 0x09, 0x38, 0x81, 0xB8, 0xF6, 0x45, 0x8B, 0xB6 } }, + { 3, 0, 5, { 0, 1, 2, 3, 4 }, 1, { 0, 1, 2, 3, 4 }, 0, 0, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x96, 0x2E, 0x28, 0x44, 0xF8, 0x9E, 0xA8, 0x88, 0x51, 0x3C, 0xBD, 0xD6, 0xD5, 0x88, 0x81, 0x7C, 0xA3, 0xEC, 0xC2, 0xBB, 0xD3, 0x13, 0xF6, 0xAA, 0x07, 0xB2, 0xE6, 0xCB, 0xB9, 0x8B, 0xB3, 0xD6 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 0, { }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x6C, 0xD2, 0x57, 0x59, 0x24, 0x39, 0xD8, 0xA0, 0xA0, 0xFA, 0xF9, 0x03, 0x7F, 0x68, 0x45, 0x34, 0xB9, 0xA6, 0x85, 0xD5, 0x04, 0x60, 0x42, 0xC3, 0xE3, 0xA3, 0xF7, 0x6F, 0x59, 0x57, 0xCB, 0xD6 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 38, { 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26 }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x1F, 0xFA, 0xA6, 0x34, 0xBD, 0xB2, 0x51, 0xBF, 0x1E, 0x9E, 0x7C, 0x7E, 0xBD, 0x77, 0x6C, 0x9D, 0xA9, 0xD3, 0x5A, 0xA6, 0xF4, 0x7C, 0x65, 0xE3, 0xE4, 0xA6, 0xE8, 0xFF, 0x1F, 0x15, 0xFF, 0x3F } }, +}; +static const struct frost_vec_sign_case frost_vec_sign_error_cases[52] = { + { 0, 2, 2, { 0, 1 }, 1, { 0, 1 }, 0, 0, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SIGN, -1, { 0 } }, + { 0, 0, 3, { 0, 1, 1 }, 1, { 0, 1, 1 }, 0, 0, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SESSION_INIT, -1, { 0 } }, + { 0, 1, 2, { 1, 2 }, 1, { 1, 2 }, 0, 0, { 0x03, 0x33, 0x34, 0xD9, 0x4E, 0xBA, 0x8E, 0xD8, 0xD3, 0xCD, 0x7C, 0xDD, 0x44, 0x30, 0xF0, 0xEE, 0x85, 0xA2, 0x07, 0x91, 0x7A, 0x12, 0xDF, 0x12, 0xDF, 0xE0, 0x8E, 0x18, 0x61, 0xB0, 0x04, 0xA6, 0xD4, 0x03, 0x3D, 0x71, 0xB2, 0x93, 0x8B, 0x48, 0x51, 0x6A, 0xB2, 0xEE, 0x54, 0x6C, 0x5E, 0xC3, 0x6D, 0x0E, 0xFF, 0xBF, 0x0B, 0x3E, 0x29, 0x0E, 0x90, 0x84, 0xCE, 0x56, 0x06, 0x39, 0x43, 0x95, 0xEE, 0x5A }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SIGN, -1, { 0 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 3 }, 0, 0, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_PUBSHARE_PARSE, 1, { 0 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 4 }, 0, 0, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SESSION_INIT, -1, { 0 } }, + { 0, 1, 2, { 3, 1 }, 1, { 0, 1 }, 1, 1, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SESSION_INIT, -1, { 0 } }, + { 0, 0, 2, { 0, 1 }, 1, { 1, 0 }, 0, 0, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SESSION_INIT, -1, { 0 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 0, { 0x04, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x03, 0x74, 0x96, 0xA3, 0xCC, 0x86, 0x92, 0x6D, 0x45, 0x2C, 0xAF, 0xCF, 0xD5, 0x5D, 0x25, 0x97, 0x2C, 0xA1, 0x67, 0x5D, 0x54, 0x93, 0x10, 0xDE, 0x29, 0x6B, 0xFF, 0x42, 0xF7, 0x2E, 0xEE, 0xA8, 0xC9 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_AGGNONCE_PARSE, -1, { 0 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 0, { 0x02, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_AGGNONCE_PARSE, -1, { 0 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 0, { 0x02, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x30 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_AGGNONCE_PARSE, -1, { 0 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 3, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SECNONCE, -1, { 0 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 4, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SECNONCE, -1, { 0 } }, + { 0, 0, 1, { 0 }, 1, { 0 }, 0, 0, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SESSION_INIT, -1, { 0 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 3, 0, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SIGN, -1, { 0 } }, + { 1, 1, 1, { 0 }, 1, { 0 }, 0, 0, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SIGN, -1, { 0 } }, + { 1, 0, 3, { 0, 1, 1 }, 1, { 0, 1, 1 }, 0, 0, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SESSION_INIT, -1, { 0 } }, + { 1, 0, 2, { 0, 1 }, 1, { 0, 3 }, 0, 0, { 0x03, 0xFB, 0xEA, 0x8F, 0x3C, 0x4C, 0xCA, 0x7D, 0xFD, 0x6B, 0xD6, 0x1F, 0x7D, 0xF7, 0xB4, 0x9B, 0xE7, 0x20, 0xD0, 0xDE, 0x01, 0x41, 0x44, 0x45, 0x7C, 0x1E, 0xEB, 0x08, 0x82, 0xB4, 0x0C, 0xA7, 0x6B, 0x02, 0x28, 0x9A, 0x43, 0xF1, 0x64, 0xE3, 0x40, 0x3C, 0xDA, 0x98, 0x73, 0x83, 0x88, 0x7B, 0xB8, 0x07, 0xEB, 0x8C, 0xF3, 0x32, 0x99, 0x49, 0xDC, 0x80, 0xC3, 0xDD, 0x5D, 0x75, 0x7E, 0xF4, 0xB8, 0x41 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_PUBSHARE_PARSE, 1, { 0 } }, + { 1, 0, 2, { 0, 1 }, 1, { 0, 4 }, 0, 0, { 0x03, 0xFB, 0xEA, 0x8F, 0x3C, 0x4C, 0xCA, 0x7D, 0xFD, 0x6B, 0xD6, 0x1F, 0x7D, 0xF7, 0xB4, 0x9B, 0xE7, 0x20, 0xD0, 0xDE, 0x01, 0x41, 0x44, 0x45, 0x7C, 0x1E, 0xEB, 0x08, 0x82, 0xB4, 0x0C, 0xA7, 0x6B, 0x02, 0x28, 0x9A, 0x43, 0xF1, 0x64, 0xE3, 0x40, 0x3C, 0xDA, 0x98, 0x73, 0x83, 0x88, 0x7B, 0xB8, 0x07, 0xEB, 0x8C, 0xF3, 0x32, 0x99, 0x49, 0xDC, 0x80, 0xC3, 0xDD, 0x5D, 0x75, 0x7E, 0xF4, 0xB8, 0x41 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SESSION_INIT, -1, { 0 } }, + { 1, 0, 1, { 3 }, 1, { 0 }, 0, 0, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SESSION_INIT, -1, { 0 } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 0, 0, { 0x04, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x03, 0x74, 0x96, 0xA3, 0xCC, 0x86, 0x92, 0x6D, 0x45, 0x2C, 0xAF, 0xCF, 0xD5, 0x5D, 0x25, 0x97, 0x2C, 0xA1, 0x67, 0x5D, 0x54, 0x93, 0x10, 0xDE, 0x29, 0x6B, 0xFF, 0x42, 0xF7, 0x2E, 0xEE, 0xA8, 0xC9 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_AGGNONCE_PARSE, -1, { 0 } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 0, 0, { 0x02, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_AGGNONCE_PARSE, -1, { 0 } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 0, 0, { 0x02, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x30 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_AGGNONCE_PARSE, -1, { 0 } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 0, 3, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SECNONCE, -1, { 0 } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 0, 4, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SECNONCE, -1, { 0 } }, + { 1, 0, 0, { 0 }, 1, { 0 }, 0, 0, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SESSION_INIT, -1, { 0 } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 3, 0, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SIGN, -1, { 0 } }, + { 2, 0, 3, { 0, 1, 1 }, 1, { 0, 1, 1 }, 0, 0, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SESSION_INIT, -1, { 0 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 3, 2 }, 0, 0, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_PUBSHARE_PARSE, 1, { 0 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 4 }, 0, 0, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SESSION_INIT, -1, { 0 } }, + { 2, 1, 3, { 3, 1, 2 }, 1, { 0, 1, 2 }, 1, 1, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SESSION_INIT, -1, { 0 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 2, 1 }, 0, 0, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SESSION_INIT, -1, { 0 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x04, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x03, 0x74, 0x96, 0xA3, 0xCC, 0x86, 0x92, 0x6D, 0x45, 0x2C, 0xAF, 0xCF, 0xD5, 0x5D, 0x25, 0x97, 0x2C, 0xA1, 0x67, 0x5D, 0x54, 0x93, 0x10, 0xDE, 0x29, 0x6B, 0xFF, 0x42, 0xF7, 0x2E, 0xEE, 0xA8, 0xC9 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_AGGNONCE_PARSE, -1, { 0 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x02, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_AGGNONCE_PARSE, -1, { 0 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x02, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x30 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_AGGNONCE_PARSE, -1, { 0 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 3, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SECNONCE, -1, { 0 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 4, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SECNONCE, -1, { 0 } }, + { 2, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 0, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SESSION_INIT, -1, { 0 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 3, 0, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SIGN, -1, { 0 } }, + { 3, 3, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SIGN, -1, { 0 } }, + { 3, 0, 3, { 0, 1, 1 }, 1, { 0, 1, 1 }, 0, 0, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SESSION_INIT, -1, { 0 } }, + { 3, 1, 3, { 1, 2, 3 }, 1, { 1, 2, 3 }, 0, 0, { 0x02, 0x7F, 0xEA, 0xEF, 0x20, 0xE0, 0xDF, 0x0E, 0xC4, 0x19, 0xCF, 0x5D, 0x4F, 0xCE, 0x8C, 0xB1, 0x8D, 0x14, 0xB0, 0x51, 0xA1, 0xA3, 0xA0, 0x37, 0x4E, 0x9A, 0xB4, 0x2F, 0x2E, 0x63, 0x7B, 0xCD, 0xC8, 0x02, 0xF7, 0x6F, 0x1B, 0x7F, 0x5C, 0x27, 0x5C, 0x62, 0x78, 0xAA, 0x61, 0x13, 0x85, 0x60, 0x26, 0x26, 0x06, 0xC8, 0x4E, 0x66, 0x47, 0x8C, 0x0E, 0x20, 0xB3, 0x98, 0x0D, 0x9B, 0x02, 0x9F, 0x5F, 0x3C }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SIGN, -1, { 0 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 5, 2 }, 0, 0, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_PUBSHARE_PARSE, 1, { 0 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 6 }, 0, 0, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SESSION_INIT, -1, { 0 } }, + { 3, 1, 3, { 5, 1, 2 }, 1, { 0, 1, 2 }, 1, 1, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SESSION_INIT, -1, { 0 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 2, 1 }, 0, 0, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SESSION_INIT, -1, { 0 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x04, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x03, 0x74, 0x96, 0xA3, 0xCC, 0x86, 0x92, 0x6D, 0x45, 0x2C, 0xAF, 0xCF, 0xD5, 0x5D, 0x25, 0x97, 0x2C, 0xA1, 0x67, 0x5D, 0x54, 0x93, 0x10, 0xDE, 0x29, 0x6B, 0xFF, 0x42, 0xF7, 0x2E, 0xEE, 0xA8, 0xC9 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_AGGNONCE_PARSE, -1, { 0 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x02, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_AGGNONCE_PARSE, -1, { 0 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x02, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x30 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_AGGNONCE_PARSE, -1, { 0 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 5, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SECNONCE, -1, { 0 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 6, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SECNONCE, -1, { 0 } }, + { 3, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 0, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SESSION_INIT, -1, { 0 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 5, 0, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_SIGN, -1, { 0 } }, +}; + +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; +}; +static const struct frost_vec_verify_case frost_vec_verify_fail_cases[12] = { + { 0, { 0x6C, 0x22, 0x17, 0x36, 0x31, 0x18, 0xEB, 0x14, 0xA4, 0x20, 0xD4, 0x1F, 0xF0, 0x13, 0xCC, 0xD6, 0xC0, 0xDF, 0xA4, 0x79, 0x74, 0x82, 0x2D, 0x4A, 0xE5, 0x5F, 0x0E, 0x90, 0xC7, 0x4E, 0xA1, 0x00 }, 2, { 0, 1 }, { 0, 1 }, { 0, 1 }, 0, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, FROST_VEC_ERR_NONE, -1 }, + { 0, { 0x93, 0xDD, 0xE8, 0xC9, 0xCE, 0xE7, 0x14, 0xEB, 0x5B, 0xDF, 0x2B, 0xE0, 0x0F, 0xEC, 0x33, 0x27, 0xF9, 0xCF, 0x38, 0x6D, 0x3A, 0xC6, 0x72, 0xF0, 0xDA, 0x73, 0x4F, 0xFC, 0x08, 0xE7, 0xA0, 0x41 }, 2, { 0, 1 }, { 0, 1 }, { 0, 1 }, 1, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, FROST_VEC_ERR_NONE, -1 }, + { 0, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 }, 2, { 0, 1 }, { 0, 1 }, { 0, 1 }, 0, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, FROST_VEC_ERR_NONE, -1 }, + { 1, { 0xBD, 0x64, 0x80, 0xB3, 0xF2, 0x48, 0xA6, 0x61, 0x58, 0x63, 0x2C, 0x3F, 0xA4, 0x05, 0xC5, 0x87, 0x0E, 0xE4, 0x5B, 0xE2, 0x86, 0x96, 0x62, 0xEF, 0x7B, 0x39, 0xA8, 0x7C, 0xDD, 0xE7, 0xD3, 0x7B }, 2, { 0, 1 }, { 0, 1 }, { 0, 1 }, 0, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, FROST_VEC_ERR_NONE, -1 }, + { 1, { 0x42, 0x9B, 0x7F, 0x4C, 0x0D, 0xB7, 0x59, 0x9E, 0xA7, 0x9C, 0xD3, 0xC0, 0x5B, 0xFA, 0x3A, 0x77, 0xAB, 0xCA, 0x81, 0x04, 0x28, 0xB2, 0x3D, 0x4C, 0x44, 0x98, 0xB6, 0x0F, 0xF2, 0x4E, 0x6D, 0xC6 }, 2, { 0, 1 }, { 0, 1 }, { 0, 1 }, 1, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, FROST_VEC_ERR_NONE, -1 }, + { 1, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 }, 2, { 0, 1 }, { 0, 1 }, { 0, 1 }, 0, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, FROST_VEC_ERR_NONE, -1 }, + { 2, { 0xCF, 0xA0, 0x1A, 0xF6, 0x0F, 0xF0, 0x99, 0xA5, 0x53, 0x7C, 0x92, 0xE1, 0xB6, 0x00, 0xDA, 0xC4, 0xE7, 0x0D, 0xC2, 0x4B, 0x8F, 0x02, 0x7B, 0xE4, 0x1B, 0x33, 0xA0, 0x64, 0x11, 0x65, 0xDA, 0x19 }, 3, { 0, 1, 2 }, { 0, 1, 2 }, { 0, 1, 2 }, 0, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, FROST_VEC_ERR_NONE, -1 }, + { 2, { 0x30, 0x5F, 0xE5, 0x09, 0xF0, 0x0F, 0x66, 0x5A, 0xAC, 0x83, 0x6D, 0x1E, 0x49, 0xFF, 0x25, 0x39, 0xD3, 0xA1, 0x1A, 0x9B, 0x20, 0x46, 0x24, 0x57, 0xA4, 0x9E, 0xBE, 0x28, 0xBE, 0xD0, 0x67, 0x28 }, 3, { 0, 1, 2 }, { 0, 1, 2 }, { 0, 1, 2 }, 1, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, FROST_VEC_ERR_NONE, -1 }, + { 2, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 }, 3, { 0, 1, 2 }, { 0, 1, 2 }, { 0, 1, 2 }, 0, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, FROST_VEC_ERR_NONE, -1 }, + { 3, { 0x9F, 0xC1, 0x3E, 0x15, 0x79, 0x4D, 0x7B, 0x1D, 0x73, 0x10, 0x2A, 0x63, 0x7A, 0x07, 0x22, 0x37, 0xDA, 0xC6, 0xC0, 0xDF, 0x6A, 0x53, 0x02, 0xAC, 0x0A, 0x13, 0xAB, 0xED, 0xB4, 0x0E, 0x4D, 0xB6 }, 3, { 0, 1, 2 }, { 0, 1, 2 }, { 0, 1, 2 }, 0, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, FROST_VEC_ERR_NONE, -1 }, + { 3, { 0x60, 0x3E, 0xC1, 0xEA, 0x86, 0xB2, 0x84, 0xE2, 0x8C, 0xEF, 0xD5, 0x9C, 0x85, 0xF8, 0xDD, 0xC6, 0xDF, 0xE8, 0x1C, 0x07, 0x44, 0xF5, 0x9D, 0x8F, 0xB5, 0xBE, 0xB2, 0x9F, 0x1C, 0x27, 0xF3, 0x8B }, 3, { 0, 1, 2 }, { 0, 1, 2 }, { 0, 1, 2 }, 1, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, FROST_VEC_ERR_NONE, -1 }, + { 3, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 }, 3, { 0, 1, 2 }, { 0, 1, 2 }, { 0, 1, 2 }, 0, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, FROST_VEC_ERR_NONE, -1 }, +}; +static const struct frost_vec_verify_case frost_vec_verify_error_cases[8] = { + { 0, { 0x93, 0xDD, 0xE8, 0xC9, 0xCE, 0xE7, 0x14, 0xEB, 0x5B, 0xDF, 0x2B, 0xE0, 0x0F, 0xEC, 0x33, 0x27, 0xF9, 0xCF, 0x38, 0x6D, 0x3A, 0xC6, 0x72, 0xF0, 0xDA, 0x73, 0x4F, 0xFC, 0x08, 0xE7, 0xA0, 0x41 }, 2, { 0, 1 }, { 0, 1 }, { 3, 1 }, 0, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, FROST_VEC_ERR_PUBNONCE_PARSE, 0 }, + { 0, { 0x93, 0xDD, 0xE8, 0xC9, 0xCE, 0xE7, 0x14, 0xEB, 0x5B, 0xDF, 0x2B, 0xE0, 0x0F, 0xEC, 0x33, 0x27, 0xF9, 0xCF, 0x38, 0x6D, 0x3A, 0xC6, 0x72, 0xF0, 0xDA, 0x73, 0x4F, 0xFC, 0x08, 0xE7, 0xA0, 0x41 }, 2, { 0, 1 }, { 3, 1 }, { 0, 1 }, 0, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, FROST_VEC_ERR_PUBSHARE_PARSE, 0 }, + { 1, { 0xB7, 0xC3, 0xFA, 0x9A, 0xEA, 0x2B, 0x09, 0x89, 0xD1, 0x50, 0xB5, 0x74, 0x33, 0x23, 0x30, 0x15, 0xA2, 0x69, 0xCB, 0x56, 0x23, 0x2B, 0x1D, 0xE2, 0xAF, 0xE5, 0x73, 0x49, 0x1D, 0x96, 0x0B, 0x2C }, 1, { 0 }, { 0 }, { 3 }, 0, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, FROST_VEC_ERR_PUBNONCE_PARSE, 0 }, + { 1, { 0xB7, 0xC3, 0xFA, 0x9A, 0xEA, 0x2B, 0x09, 0x89, 0xD1, 0x50, 0xB5, 0x74, 0x33, 0x23, 0x30, 0x15, 0xA2, 0x69, 0xCB, 0x56, 0x23, 0x2B, 0x1D, 0xE2, 0xAF, 0xE5, 0x73, 0x49, 0x1D, 0x96, 0x0B, 0x2C }, 1, { 0 }, { 3 }, { 0 }, 0, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, FROST_VEC_ERR_PUBSHARE_PARSE, 0 }, + { 2, { 0x30, 0x5F, 0xE5, 0x09, 0xF0, 0x0F, 0x66, 0x5A, 0xAC, 0x83, 0x6D, 0x1E, 0x49, 0xFF, 0x25, 0x39, 0xD3, 0xA1, 0x1A, 0x9B, 0x20, 0x46, 0x24, 0x57, 0xA4, 0x9E, 0xBE, 0x28, 0xBE, 0xD0, 0x67, 0x28 }, 3, { 0, 1, 2 }, { 0, 1, 2 }, { 3, 1, 2 }, 0, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, FROST_VEC_ERR_PUBNONCE_PARSE, 0 }, + { 2, { 0x30, 0x5F, 0xE5, 0x09, 0xF0, 0x0F, 0x66, 0x5A, 0xAC, 0x83, 0x6D, 0x1E, 0x49, 0xFF, 0x25, 0x39, 0xD3, 0xA1, 0x1A, 0x9B, 0x20, 0x46, 0x24, 0x57, 0xA4, 0x9E, 0xBE, 0x28, 0xBE, 0xD0, 0x67, 0x28 }, 3, { 0, 1, 2 }, { 3, 1, 2 }, { 0, 1, 2 }, 0, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, FROST_VEC_ERR_PUBSHARE_PARSE, 0 }, + { 3, { 0x60, 0x3E, 0xC1, 0xEA, 0x86, 0xB2, 0x84, 0xE2, 0x8C, 0xEF, 0xD5, 0x9C, 0x85, 0xF8, 0xDD, 0xC6, 0xDF, 0xE8, 0x1C, 0x07, 0x44, 0xF5, 0x9D, 0x8F, 0xB5, 0xBE, 0xB2, 0x9F, 0x1C, 0x27, 0xF3, 0x8B }, 3, { 0, 1, 2 }, { 0, 1, 2 }, { 5, 1, 2 }, 0, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, FROST_VEC_ERR_PUBNONCE_PARSE, 0 }, + { 3, { 0x60, 0x3E, 0xC1, 0xEA, 0x86, 0xB2, 0x84, 0xE2, 0x8C, 0xEF, 0xD5, 0x9C, 0x85, 0xF8, 0xDD, 0xC6, 0xDF, 0xE8, 0x1C, 0x07, 0x44, 0xF5, 0x9D, 0x8F, 0xB5, 0xBE, 0xB2, 0x9F, 0x1C, 0x27, 0xF3, 0x8B }, 3, { 0, 1, 2 }, { 5, 1, 2 }, { 0, 1, 2 }, 0, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, FROST_VEC_ERR_PUBSHARE_PARSE, 0 }, +}; +static const struct frost_vec_group frost_vec_tweak_groups[4] = { + { 2, 3, { 0x02, 0xD7, 0x72, 0xA0, 0x9F, 0x5F, 0x67, 0x57, 0x83, 0xD2, 0x75, 0xED, 0x9F, 0x6A, 0xAE, 0xDB, 0x2E, 0xCC, 0xBC, 0x74, 0x17, 0x1B, 0x37, 0xAC, 0x23, 0xAE, 0x3B, 0xBD, 0x9D, 0x7A, 0xE2, 0xCD, 0xAA }, 3, { + { 0x03, 0x9E, 0xE3, 0x33, 0x5A, 0xF4, 0x8D, 0xFE, 0x23, 0x70, 0x2A, 0xB3, 0x53, 0xF4, 0xAF, 0x20, 0xD4, 0x01, 0xF6, 0x7A, 0x13, 0x0D, 0xF7, 0x83, 0xCC, 0x84, 0x57, 0x32, 0x3A, 0x86, 0x0A, 0x2F, 0xB4 }, + { 0x02, 0x84, 0xDC, 0x4A, 0xB2, 0xCB, 0x78, 0xA6, 0x21, 0xEB, 0x87, 0xFA, 0x1F, 0x14, 0xBC, 0xE2, 0xB7, 0x25, 0xAF, 0xEA, 0xAC, 0x98, 0x1A, 0xDC, 0xBA, 0xFF, 0x5C, 0xC2, 0xD4, 0x17, 0xD2, 0xA6, 0x3A }, + { 0x03, 0x64, 0x41, 0xEC, 0x2D, 0x4C, 0x12, 0x66, 0x20, 0x1C, 0xD8, 0x9B, 0x69, 0x54, 0x9A, 0x2F, 0x5B, 0x21, 0x88, 0x61, 0x2A, 0x0D, 0x43, 0x41, 0x53, 0xE6, 0x25, 0xFB, 0x38, 0x17, 0x3D, 0xD5, 0x09 } + }, 3, { + { 0x53, 0x44, 0x2F, 0xA9, 0xBD, 0x72, 0xEE, 0xA0, 0xA4, 0x2D, 0xF6, 0xF2, 0xD2, 0xD7, 0x6A, 0x2C, 0x0D, 0x3A, 0x3D, 0xFA, 0x2B, 0xE2, 0xF8, 0x20, 0xF4, 0x1A, 0xDE, 0x97, 0x6B, 0x82, 0x59, 0xFB }, + { 0x5A, 0x7F, 0x9B, 0xD4, 0x1F, 0x4B, 0x54, 0x46, 0x64, 0xC5, 0x4D, 0x77, 0x7D, 0x43, 0x30, 0x3C, 0xB5, 0x30, 0x24, 0x34, 0xF9, 0x90, 0x3B, 0x9B, 0x55, 0x2C, 0x4E, 0x55, 0x2B, 0xF0, 0x22, 0x01 }, + { 0x61, 0xBB, 0x07, 0xFE, 0x81, 0x23, 0xB9, 0xEC, 0x25, 0x5C, 0xA3, 0xFC, 0x27, 0xAE, 0xF6, 0x4D, 0x5D, 0x26, 0x0A, 0x6F, 0xC7, 0x3D, 0x7F, 0x15, 0xB6, 0x3D, 0xBE, 0x12, 0xEC, 0x5D, 0xEA, 0x07 } + }, 3, { + { 0x03, 0xFC, 0x0D, 0x3E, 0x21, 0x2D, 0x25, 0x02, 0x73, 0x56, 0xA2, 0xC9, 0xBB, 0x7E, 0xDC, 0x3B, 0x90, 0x0D, 0xEA, 0x5E, 0x32, 0xAB, 0x10, 0xC0, 0x38, 0x68, 0xE0, 0x1C, 0x84, 0x90, 0xF9, 0xD3, 0x62, 0x02, 0xC6, 0x13, 0x89, 0xB6, 0x46, 0x9B, 0x43, 0x45, 0xE0, 0x06, 0x40, 0xCD, 0xC7, 0xEC, 0xA3, 0x01, 0x54, 0x7B, 0x97, 0xD3, 0x0F, 0xC1, 0x1A, 0xF4, 0x10, 0xE2, 0x3A, 0xD7, 0xB4, 0xBF, 0x69, 0xEE }, + { 0x03, 0x70, 0x6F, 0x00, 0x35, 0x3E, 0xA6, 0x9C, 0x08, 0x36, 0xBF, 0x63, 0xC2, 0x88, 0x4D, 0x2D, 0xE5, 0xAF, 0xE5, 0x49, 0xA3, 0x3E, 0xC8, 0x74, 0x27, 0xCA, 0x8B, 0x5C, 0xF4, 0x66, 0x6B, 0x28, 0xAE, 0x02, 0x1B, 0x63, 0x00, 0xD0, 0x54, 0x5E, 0x0B, 0x22, 0x5C, 0x2D, 0xFC, 0x67, 0xAE, 0x33, 0xA9, 0xB0, 0x25, 0x9B, 0x62, 0x80, 0x97, 0x40, 0x36, 0x37, 0x17, 0xE0, 0x5C, 0xDA, 0x4C, 0xC9, 0xEB, 0xFC }, + { 0x02, 0xB7, 0xF6, 0xEF, 0x56, 0x6D, 0xD2, 0xDD, 0xAA, 0x6A, 0xF3, 0x83, 0x71, 0xA4, 0x1F, 0x80, 0xF9, 0x3A, 0x90, 0xB9, 0xF4, 0x07, 0xB5, 0xBD, 0xB8, 0xED, 0x76, 0x3F, 0x00, 0x10, 0x3D, 0xB0, 0xFC, 0x03, 0x9C, 0x67, 0x76, 0x04, 0xE7, 0xB7, 0x5F, 0xF6, 0xE4, 0x7C, 0x42, 0xB0, 0x24, 0x9A, 0x3B, 0xAA, 0x9C, 0xC6, 0xB1, 0x7E, 0x68, 0xD6, 0xD7, 0x8E, 0x21, 0xAB, 0xA9, 0xD0, 0x4B, 0xF4, 0x07, 0x45 } + }, 3, { + { 0x67, 0xAF, 0xBE, 0x2B, 0x50, 0xF5, 0x21, 0x56, 0x9B, 0x9C, 0x1D, 0x94, 0x3F, 0x8F, 0xE2, 0x06, 0x20, 0xB8, 0xC2, 0x5F, 0xA8, 0x1E, 0x97, 0x88, 0x71, 0x8A, 0xF6, 0xEE, 0x87, 0xD5, 0x27, 0x5C, 0x9A, 0x48, 0x5A, 0x63, 0x4F, 0xE4, 0x15, 0x58, 0xE4, 0xE1, 0x08, 0xFB, 0xB5, 0x2C, 0x5C, 0xF6, 0x16, 0xC0, 0xCD, 0xF0, 0x2B, 0xC0, 0xC1, 0x0A, 0x99, 0x35, 0x9F, 0xF6, 0xC1, 0xBD, 0x70, 0x5C }, + { 0x6E, 0x5A, 0xAB, 0xD8, 0x14, 0xF3, 0x00, 0x45, 0x74, 0x4D, 0xC4, 0x70, 0x10, 0x3D, 0x44, 0xBC, 0xD8, 0x46, 0x28, 0x4D, 0x7A, 0x76, 0x3F, 0x9B, 0xA3, 0xF5, 0xC7, 0x3D, 0xCE, 0x20, 0xBF, 0x45, 0x9F, 0xCE, 0xDE, 0x0D, 0xFF, 0xF0, 0x9B, 0x9E, 0x01, 0x50, 0xCE, 0x5A, 0x2C, 0x05, 0xD3, 0x19, 0x9B, 0x4B, 0x09, 0x87, 0xA1, 0x8C, 0x49, 0xE9, 0x27, 0x3D, 0xEA, 0xDB, 0xBA, 0x40, 0xB4, 0xD6 }, + { 0x76, 0x2F, 0x46, 0x01, 0xAC, 0x20, 0x6E, 0x1F, 0x14, 0x97, 0xEB, 0x54, 0x12, 0x02, 0xB7, 0x27, 0xCC, 0x19, 0xFA, 0x04, 0x50, 0x28, 0x9C, 0x77, 0x8B, 0x5D, 0x5F, 0x4F, 0x1A, 0x4B, 0x53, 0xF4, 0xD6, 0x3D, 0x31, 0x2C, 0xC2, 0xC9, 0x19, 0x6D, 0x08, 0xFD, 0x62, 0xF3, 0x95, 0x8F, 0xE8, 0xBB, 0xC6, 0x6B, 0x85, 0x17, 0xD1, 0x0D, 0xE5, 0x34, 0xF6, 0xA6, 0x41, 0xD0, 0xE6, 0xE5, 0xEB, 0xCB } + }, 7, { + { 0xE8, 0xF7, 0x91, 0xFF, 0x92, 0x25, 0xA2, 0xAF, 0x01, 0x02, 0xAF, 0xFF, 0x4A, 0x9A, 0x72, 0x3D, 0x96, 0x12, 0xA6, 0x82, 0xA2, 0x5E, 0xBE, 0x79, 0x80, 0x2B, 0x26, 0x3C, 0xDF, 0xCD, 0x83, 0xBB }, + { 0xAE, 0x2E, 0xA7, 0x97, 0xCC, 0x0F, 0xE7, 0x2A, 0xC5, 0xB9, 0x7B, 0x97, 0xF3, 0xC6, 0x95, 0x7D, 0x7E, 0x41, 0x99, 0xA1, 0x67, 0xA5, 0x8E, 0xB0, 0x8B, 0xCA, 0xFF, 0xDA, 0x70, 0xAC, 0x04, 0x55 }, + { 0xF5, 0x2E, 0xCB, 0xC5, 0x65, 0xB3, 0xD8, 0xBE, 0xA2, 0xDF, 0xD5, 0xB7, 0x5A, 0x4F, 0x45, 0x7E, 0x54, 0x36, 0x98, 0x09, 0x32, 0x2E, 0x41, 0x20, 0x83, 0x16, 0x26, 0xF2, 0x90, 0xFA, 0x87, 0xE0 }, + { 0x19, 0x69, 0xAD, 0x73, 0xCC, 0x17, 0x7F, 0xA0, 0xB4, 0xFC, 0xED, 0x6D, 0xF1, 0xF7, 0xBF, 0x99, 0x07, 0xE6, 0x65, 0xFD, 0xE9, 0xBA, 0x19, 0x6A, 0x74, 0xFE, 0xD0, 0xA3, 0xCF, 0x5A, 0xEF, 0x9D }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 }, + { 0xB3, 0xF7, 0x3C, 0x80, 0xA4, 0x65, 0x77, 0x05, 0x1C, 0x69, 0x5F, 0x91, 0xD7, 0x94, 0x5B, 0xE3, 0x55, 0x6A, 0x85, 0x27, 0x51, 0x12, 0xEB, 0x95, 0x2C, 0xC8, 0xEF, 0xB3, 0x25, 0x21, 0xAF, 0x4C }, + { 0xE8, 0xF7, 0x91, 0xFF, 0x92, 0x25, 0xA2, 0xAF, 0x01, 0x02, 0xAF, 0xFF, 0x4A, 0x9A, 0x72, 0x3D, 0x96, 0x12, 0xA6, 0x82, 0xA2, 0x5E, 0xBE, 0x79, 0x80, 0x2B, 0x26, 0x3C, 0xDF, 0xCD, 0x83, 0xBB, 0xFF } + } }, + { 1, 3, { 0x03, 0xD1, 0x93, 0x9B, 0xE8, 0x7D, 0x18, 0xEA, 0x5A, 0xB3, 0x02, 0xE2, 0x70, 0x77, 0xD1, 0x6B, 0x2C, 0x2F, 0xD9, 0x35, 0x16, 0xF9, 0x15, 0x14, 0xBA, 0x04, 0x99, 0x33, 0xD3, 0x48, 0xDA, 0x44, 0x1F }, 3, { + { 0x03, 0xD1, 0x93, 0x9B, 0xE8, 0x7D, 0x18, 0xEA, 0x5A, 0xB3, 0x02, 0xE2, 0x70, 0x77, 0xD1, 0x6B, 0x2C, 0x2F, 0xD9, 0x35, 0x16, 0xF9, 0x15, 0x14, 0xBA, 0x04, 0x99, 0x33, 0xD3, 0x48, 0xDA, 0x44, 0x1F }, + { 0x03, 0xD1, 0x93, 0x9B, 0xE8, 0x7D, 0x18, 0xEA, 0x5A, 0xB3, 0x02, 0xE2, 0x70, 0x77, 0xD1, 0x6B, 0x2C, 0x2F, 0xD9, 0x35, 0x16, 0xF9, 0x15, 0x14, 0xBA, 0x04, 0x99, 0x33, 0xD3, 0x48, 0xDA, 0x44, 0x1F }, + { 0x03, 0xD1, 0x93, 0x9B, 0xE8, 0x7D, 0x18, 0xEA, 0x5A, 0xB3, 0x02, 0xE2, 0x70, 0x77, 0xD1, 0x6B, 0x2C, 0x2F, 0xD9, 0x35, 0x16, 0xF9, 0x15, 0x14, 0xBA, 0x04, 0x99, 0x33, 0xD3, 0x48, 0xDA, 0x44, 0x1F } + }, 3, { + { 0x06, 0xD4, 0x7E, 0x05, 0xE9, 0x74, 0x81, 0x42, 0x86, 0x54, 0x56, 0x3E, 0x5A, 0xE6, 0x9C, 0x20, 0xC4, 0x96, 0x42, 0x77, 0x3B, 0x73, 0x34, 0x22, 0x0E, 0x63, 0x11, 0x02, 0x59, 0xA3, 0x0C, 0x32 }, + { 0x06, 0xD4, 0x7E, 0x05, 0xE9, 0x74, 0x81, 0x42, 0x86, 0x54, 0x56, 0x3E, 0x5A, 0xE6, 0x9C, 0x20, 0xC4, 0x96, 0x42, 0x77, 0x3B, 0x73, 0x34, 0x22, 0x0E, 0x63, 0x11, 0x02, 0x59, 0xA3, 0x0C, 0x32 }, + { 0x06, 0xD4, 0x7E, 0x05, 0xE9, 0x74, 0x81, 0x42, 0x86, 0x54, 0x56, 0x3E, 0x5A, 0xE6, 0x9C, 0x20, 0xC4, 0x96, 0x42, 0x77, 0x3B, 0x73, 0x34, 0x22, 0x0E, 0x63, 0x11, 0x02, 0x59, 0xA3, 0x0C, 0x32 } + }, 3, { + { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, + { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, + { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 } + }, 3, { + { 0x85, 0x98, 0x8D, 0x37, 0xE7, 0xF2, 0xEE, 0x21, 0xFC, 0x47, 0x29, 0x5E, 0x90, 0xD0, 0xFD, 0x85, 0x02, 0x7C, 0xE0, 0xE7, 0x1D, 0xA3, 0x7B, 0x36, 0xCF, 0xB5, 0x5B, 0xD4, 0x71, 0xD3, 0xBA, 0x82, 0xAC, 0xE9, 0xF7, 0x3C, 0x19, 0xDC, 0xD3, 0x87, 0xAE, 0xF3, 0x0F, 0x9E, 0x89, 0x45, 0x64, 0xA4, 0x7F, 0x8B, 0xE8, 0x5F, 0xAA, 0xAE, 0x71, 0x0D, 0xD0, 0xF4, 0x42, 0xDF, 0x2A, 0x38, 0x01, 0x90 }, + { 0x85, 0x98, 0x8D, 0x37, 0xE7, 0xF2, 0xEE, 0x21, 0xFC, 0x47, 0x29, 0x5E, 0x90, 0xD0, 0xFD, 0x85, 0x02, 0x7C, 0xE0, 0xE7, 0x1D, 0xA3, 0x7B, 0x36, 0xCF, 0xB5, 0x5B, 0xD4, 0x71, 0xD3, 0xBA, 0x82, 0xAC, 0xE9, 0xF7, 0x3C, 0x19, 0xDC, 0xD3, 0x87, 0xAE, 0xF3, 0x0F, 0x9E, 0x89, 0x45, 0x64, 0xA4, 0x7F, 0x8B, 0xE8, 0x5F, 0xAA, 0xAE, 0x71, 0x0D, 0xD0, 0xF4, 0x42, 0xDF, 0x2A, 0x38, 0x01, 0x90 }, + { 0x85, 0x98, 0x8D, 0x37, 0xE7, 0xF2, 0xEE, 0x21, 0xFC, 0x47, 0x29, 0x5E, 0x90, 0xD0, 0xFD, 0x85, 0x02, 0x7C, 0xE0, 0xE7, 0x1D, 0xA3, 0x7B, 0x36, 0xCF, 0xB5, 0x5B, 0xD4, 0x71, 0xD3, 0xBA, 0x82, 0xAC, 0xE9, 0xF7, 0x3C, 0x19, 0xDC, 0xD3, 0x87, 0xAE, 0xF3, 0x0F, 0x9E, 0x89, 0x45, 0x64, 0xA4, 0x7F, 0x8B, 0xE8, 0x5F, 0xAA, 0xAE, 0x71, 0x0D, 0xD0, 0xF4, 0x42, 0xDF, 0x2A, 0x38, 0x01, 0x90 } + }, 7, { + { 0xE8, 0xF7, 0x91, 0xFF, 0x92, 0x25, 0xA2, 0xAF, 0x01, 0x02, 0xAF, 0xFF, 0x4A, 0x9A, 0x72, 0x3D, 0x96, 0x12, 0xA6, 0x82, 0xA2, 0x5E, 0xBE, 0x79, 0x80, 0x2B, 0x26, 0x3C, 0xDF, 0xCD, 0x83, 0xBB }, + { 0xAE, 0x2E, 0xA7, 0x97, 0xCC, 0x0F, 0xE7, 0x2A, 0xC5, 0xB9, 0x7B, 0x97, 0xF3, 0xC6, 0x95, 0x7D, 0x7E, 0x41, 0x99, 0xA1, 0x67, 0xA5, 0x8E, 0xB0, 0x8B, 0xCA, 0xFF, 0xDA, 0x70, 0xAC, 0x04, 0x55 }, + { 0xF5, 0x2E, 0xCB, 0xC5, 0x65, 0xB3, 0xD8, 0xBE, 0xA2, 0xDF, 0xD5, 0xB7, 0x5A, 0x4F, 0x45, 0x7E, 0x54, 0x36, 0x98, 0x09, 0x32, 0x2E, 0x41, 0x20, 0x83, 0x16, 0x26, 0xF2, 0x90, 0xFA, 0x87, 0xE0 }, + { 0x19, 0x69, 0xAD, 0x73, 0xCC, 0x17, 0x7F, 0xA0, 0xB4, 0xFC, 0xED, 0x6D, 0xF1, 0xF7, 0xBF, 0x99, 0x07, 0xE6, 0x65, 0xFD, 0xE9, 0xBA, 0x19, 0x6A, 0x74, 0xFE, 0xD0, 0xA3, 0xCF, 0x5A, 0xEF, 0x9D }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 }, + { 0xF9, 0x2B, 0x81, 0xFA, 0x16, 0x8B, 0x7E, 0xBD, 0x79, 0xAB, 0xA9, 0xC1, 0xA5, 0x19, 0x63, 0xDD, 0xF6, 0x18, 0x9A, 0x6F, 0x73, 0xD5, 0x6C, 0x19, 0xB1, 0x6F, 0x4D, 0x8A, 0x76, 0x93, 0x35, 0x0F }, + { 0xE8, 0xF7, 0x91, 0xFF, 0x92, 0x25, 0xA2, 0xAF, 0x01, 0x02, 0xAF, 0xFF, 0x4A, 0x9A, 0x72, 0x3D, 0x96, 0x12, 0xA6, 0x82, 0xA2, 0x5E, 0xBE, 0x79, 0x80, 0x2B, 0x26, 0x3C, 0xDF, 0xCD, 0x83, 0xBB, 0xFF } + } }, + { 3, 3, { 0x02, 0x3E, 0x94, 0xD6, 0xA6, 0x86, 0x20, 0xD3, 0xF6, 0x02, 0x21, 0xA4, 0x18, 0x67, 0x86, 0x27, 0x4A, 0x71, 0x12, 0x21, 0xA8, 0xBB, 0xB3, 0x1A, 0x53, 0x88, 0xDF, 0xA6, 0x71, 0x8E, 0x8E, 0xF7, 0xBB }, 3, { + { 0x03, 0xA3, 0xE9, 0x32, 0xBA, 0x9D, 0xD0, 0x06, 0x3D, 0x72, 0x15, 0x90, 0xB6, 0xEF, 0x21, 0xDD, 0x45, 0x66, 0xA9, 0x7B, 0x20, 0x33, 0x43, 0xFD, 0xE9, 0xDA, 0x58, 0x15, 0xDB, 0x9B, 0xE0, 0x49, 0xCA }, + { 0x02, 0x01, 0xE5, 0xFE, 0xAC, 0x0D, 0xB5, 0x05, 0x9C, 0x32, 0xB0, 0x45, 0xF3, 0x77, 0x99, 0x10, 0x1A, 0x96, 0x26, 0x2B, 0x3C, 0x88, 0xCE, 0x85, 0xD6, 0x10, 0x45, 0x1F, 0xC2, 0x1A, 0x04, 0x57, 0xFF }, + { 0x03, 0xEF, 0x72, 0xD1, 0x0D, 0x1D, 0xFE, 0x4E, 0x78, 0x66, 0x19, 0x53, 0x6A, 0x45, 0x85, 0x07, 0xCA, 0xF1, 0x05, 0xFC, 0xCD, 0xB8, 0x17, 0x3D, 0xAF, 0x2E, 0x35, 0x80, 0x54, 0xAF, 0x2F, 0xA4, 0xA2 } + }, 3, { + { 0xD4, 0xDE, 0x57, 0x1C, 0x66, 0x2C, 0x31, 0x9E, 0x7C, 0x4F, 0x46, 0x42, 0x0F, 0x5A, 0xCB, 0xEF, 0xD2, 0xD9, 0x05, 0xC3, 0xB5, 0x27, 0x71, 0xC5, 0x53, 0xDE, 0x1F, 0x76, 0x19, 0x7D, 0x94, 0x0D }, + { 0x0E, 0xAA, 0xC0, 0x17, 0xAB, 0xA2, 0x03, 0x02, 0x72, 0xB7, 0xF8, 0xEA, 0xAD, 0x68, 0xE2, 0x2B, 0xF0, 0x7F, 0x08, 0x95, 0x0D, 0x7B, 0x57, 0x0B, 0x69, 0xB2, 0xCC, 0xEF, 0x27, 0x8D, 0x52, 0xC1 }, + { 0x1E, 0x4E, 0x43, 0x44, 0xB9, 0xB5, 0x94, 0x10, 0x58, 0x8C, 0xCF, 0x32, 0x7B, 0x76, 0x6E, 0x4D, 0x29, 0x88, 0x82, 0xD9, 0x04, 0xF0, 0xFB, 0xF2, 0x88, 0xC8, 0x6B, 0x73, 0xAC, 0x59, 0x62, 0xA3 } + }, 3, { + { 0x02, 0xB6, 0x41, 0x8E, 0xDD, 0xC3, 0xE2, 0xD4, 0x8B, 0x06, 0x4B, 0xE4, 0x6F, 0x71, 0xCE, 0xDE, 0x3A, 0x34, 0x59, 0x4D, 0xEA, 0xC6, 0xE7, 0xF6, 0x70, 0x7C, 0x8A, 0x71, 0xCB, 0x52, 0x3E, 0xA5, 0x86, 0x02, 0xC0, 0xB4, 0x02, 0x21, 0x6E, 0x99, 0x52, 0xE6, 0x49, 0xB8, 0xCC, 0xFE, 0xDB, 0xAC, 0x6A, 0xA1, 0x0B, 0xAE, 0xEF, 0xF4, 0xC0, 0x2E, 0xEA, 0xA1, 0x14, 0x8E, 0x87, 0xC7, 0xB2, 0x1B, 0xDF, 0xB7 }, + { 0x02, 0xB6, 0x3A, 0x2B, 0x31, 0x9D, 0x64, 0xA7, 0xBF, 0xE6, 0x63, 0x44, 0x04, 0xCB, 0x9D, 0x80, 0xAA, 0xA5, 0x7B, 0xAF, 0xD8, 0xAA, 0x01, 0xFC, 0x52, 0xBF, 0x77, 0x23, 0x2D, 0xC0, 0xEE, 0x4B, 0x60, 0x03, 0x58, 0xE8, 0xB8, 0xF6, 0xFB, 0x17, 0xFB, 0x5D, 0x92, 0xFA, 0xFA, 0xC1, 0x09, 0x37, 0x73, 0x64, 0x5F, 0xE3, 0x23, 0x30, 0xD6, 0xE2, 0x77, 0x4B, 0x4B, 0xBB, 0xCE, 0xF7, 0xDD, 0xFA, 0x51, 0x02 }, + { 0x03, 0x64, 0xF6, 0x0E, 0x66, 0xB7, 0xBC, 0x35, 0xA3, 0x32, 0xB4, 0xF9, 0x68, 0x8B, 0xD5, 0xCA, 0x2E, 0xF5, 0x08, 0xE2, 0x5C, 0x69, 0x1D, 0x6A, 0x1A, 0x19, 0x40, 0x97, 0xD1, 0x70, 0xBB, 0xCC, 0xE6, 0x02, 0x49, 0x4A, 0xB4, 0x72, 0x55, 0x52, 0x1F, 0x01, 0x34, 0xEC, 0x7C, 0x41, 0x07, 0x9A, 0x89, 0x55, 0xDA, 0x72, 0x20, 0x17, 0x2A, 0x60, 0x37, 0x1D, 0xC3, 0x2C, 0x69, 0x6A, 0xE5, 0xD6, 0x14, 0x10 } + }, 3, { + { 0x7B, 0x22, 0x47, 0xA3, 0x98, 0x0C, 0x88, 0x71, 0x4A, 0x08, 0x21, 0xF2, 0x30, 0xF6, 0x89, 0xF4, 0x36, 0xFB, 0xF8, 0x0B, 0x0B, 0x6D, 0xED, 0x33, 0x54, 0x0B, 0x92, 0xCB, 0x65, 0xBA, 0x6E, 0xD1, 0x49, 0xA8, 0xAD, 0xAF, 0x97, 0xEF, 0x6D, 0xBA, 0xA6, 0x01, 0x5C, 0xD5, 0xBA, 0x84, 0xE4, 0xCA, 0xAD, 0xB7, 0xA4, 0x53, 0x50, 0x8D, 0xD1, 0x7F, 0xD8, 0xEE, 0x36, 0x18, 0xE1, 0x19, 0xC0, 0xF9 }, + { 0xB1, 0x45, 0x6F, 0xA8, 0xF9, 0x24, 0x86, 0x0A, 0x66, 0x5A, 0xFC, 0x2A, 0xE2, 0x74, 0x6E, 0x6E, 0x2C, 0x99, 0xEB, 0xBE, 0x4B, 0xC1, 0xD0, 0xF5, 0xBD, 0x00, 0xBC, 0x52, 0xCB, 0x7D, 0xFD, 0x79, 0xA8, 0x23, 0xD9, 0x29, 0x11, 0x39, 0x38, 0x52, 0xD4, 0xEC, 0xCC, 0x59, 0x38, 0x7D, 0xB8, 0x8C, 0x52, 0x6F, 0xD1, 0xAD, 0x75, 0x74, 0xA3, 0x33, 0x68, 0x93, 0xB6, 0x18, 0x75, 0x0D, 0xBD, 0xDD }, + { 0xC3, 0x09, 0xD4, 0xBC, 0x04, 0x57, 0xA9, 0xD6, 0x03, 0x1C, 0xDA, 0xC3, 0x3B, 0xAF, 0xA4, 0x7B, 0xAB, 0x23, 0x34, 0x44, 0x5B, 0xF2, 0x2D, 0x09, 0xE1, 0x93, 0x6F, 0x91, 0x97, 0x56, 0xD2, 0x75, 0xBC, 0x09, 0x41, 0x0F, 0x5D, 0x39, 0xE5, 0xD7, 0x01, 0xC8, 0x1B, 0xBA, 0x99, 0xE4, 0xE9, 0x5F, 0x9E, 0x07, 0xFF, 0xC3, 0x2C, 0x32, 0x2F, 0x25, 0x60, 0x45, 0x82, 0xCB, 0x24, 0x2D, 0xD4, 0x6A } + }, 7, { + { 0xE8, 0xF7, 0x91, 0xFF, 0x92, 0x25, 0xA2, 0xAF, 0x01, 0x02, 0xAF, 0xFF, 0x4A, 0x9A, 0x72, 0x3D, 0x96, 0x12, 0xA6, 0x82, 0xA2, 0x5E, 0xBE, 0x79, 0x80, 0x2B, 0x26, 0x3C, 0xDF, 0xCD, 0x83, 0xBB }, + { 0xAE, 0x2E, 0xA7, 0x97, 0xCC, 0x0F, 0xE7, 0x2A, 0xC5, 0xB9, 0x7B, 0x97, 0xF3, 0xC6, 0x95, 0x7D, 0x7E, 0x41, 0x99, 0xA1, 0x67, 0xA5, 0x8E, 0xB0, 0x8B, 0xCA, 0xFF, 0xDA, 0x70, 0xAC, 0x04, 0x55 }, + { 0xF5, 0x2E, 0xCB, 0xC5, 0x65, 0xB3, 0xD8, 0xBE, 0xA2, 0xDF, 0xD5, 0xB7, 0x5A, 0x4F, 0x45, 0x7E, 0x54, 0x36, 0x98, 0x09, 0x32, 0x2E, 0x41, 0x20, 0x83, 0x16, 0x26, 0xF2, 0x90, 0xFA, 0x87, 0xE0 }, + { 0x19, 0x69, 0xAD, 0x73, 0xCC, 0x17, 0x7F, 0xA0, 0xB4, 0xFC, 0xED, 0x6D, 0xF1, 0xF7, 0xBF, 0x99, 0x07, 0xE6, 0x65, 0xFD, 0xE9, 0xBA, 0x19, 0x6A, 0x74, 0xFE, 0xD0, 0xA3, 0xCF, 0x5A, 0xEF, 0x9D }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 }, + { 0x8F, 0x16, 0xF7, 0xAD, 0x16, 0xAB, 0xE0, 0x1B, 0x8A, 0xAD, 0x48, 0xC7, 0x5E, 0xB3, 0xD4, 0x63, 0x5F, 0x76, 0x1C, 0x4F, 0x11, 0xE4, 0x94, 0x92, 0xF8, 0x2C, 0xB8, 0x9D, 0xEE, 0x78, 0x9D, 0x3C }, + { 0xE8, 0xF7, 0x91, 0xFF, 0x92, 0x25, 0xA2, 0xAF, 0x01, 0x02, 0xAF, 0xFF, 0x4A, 0x9A, 0x72, 0x3D, 0x96, 0x12, 0xA6, 0x82, 0xA2, 0x5E, 0xBE, 0x79, 0x80, 0x2B, 0x26, 0x3C, 0xDF, 0xCD, 0x83, 0xBB, 0xFF } + } }, + { 3, 5, { 0x03, 0xE1, 0xAE, 0xA0, 0x0A, 0x7B, 0x8D, 0x0E, 0x03, 0x93, 0x66, 0x4F, 0xEB, 0xBD, 0x31, 0x56, 0x9A, 0x02, 0xCA, 0xF2, 0x23, 0xD9, 0xAD, 0x83, 0xE9, 0x03, 0x31, 0xDC, 0x18, 0xB1, 0x98, 0x73, 0x58 }, 5, { + { 0x02, 0xF3, 0x33, 0xED, 0xD2, 0xB6, 0xF5, 0x32, 0xC2, 0xEF, 0x6C, 0x42, 0xE8, 0x03, 0xB6, 0x33, 0xA4, 0x22, 0x89, 0xD0, 0x56, 0x7A, 0x75, 0xC5, 0x0E, 0xB1, 0xC8, 0xCF, 0x85, 0xEC, 0x48, 0x0E, 0x8F }, + { 0x02, 0x53, 0x22, 0xF6, 0x36, 0x02, 0xEC, 0xCF, 0x14, 0x65, 0x41, 0xB7, 0xC9, 0xEE, 0x4D, 0x1F, 0xCB, 0x84, 0xEC, 0x13, 0x94, 0x71, 0x42, 0x04, 0x72, 0x18, 0x2A, 0xE9, 0x68, 0x67, 0x6A, 0x38, 0x7F }, + { 0x02, 0x30, 0x63, 0x9C, 0xEC, 0x0A, 0x83, 0x98, 0x2E, 0x17, 0x6D, 0x69, 0x05, 0xCE, 0x06, 0x20, 0xFD, 0xC5, 0x7E, 0x15, 0x15, 0x65, 0xA3, 0x9D, 0x0E, 0x08, 0x21, 0xB8, 0xE7, 0x53, 0xAE, 0x85, 0xB0 }, + { 0x02, 0x6E, 0x1A, 0x50, 0xE6, 0x72, 0xFE, 0xDD, 0x3F, 0x3C, 0x37, 0x8D, 0x61, 0x21, 0xE5, 0x70, 0x2B, 0x05, 0x06, 0x69, 0xDB, 0xC2, 0x41, 0xD2, 0xC2, 0x29, 0x98, 0x80, 0x15, 0x2C, 0xD2, 0x07, 0xBD }, + { 0x02, 0xDC, 0x06, 0xC4, 0xCA, 0x91, 0x9D, 0xE7, 0x0B, 0x4B, 0x82, 0x81, 0x90, 0x1C, 0xCF, 0x94, 0x71, 0xAB, 0x91, 0xFB, 0xFB, 0xEE, 0x1A, 0x8C, 0x57, 0x0D, 0x83, 0x91, 0x1C, 0xAA, 0xF9, 0xE2, 0xFA } + }, 5, { + { 0x77, 0xC9, 0x31, 0x6A, 0x64, 0x77, 0x0B, 0x17, 0xD5, 0x00, 0x84, 0x0E, 0x02, 0x0A, 0x94, 0x78, 0xF7, 0x93, 0xD3, 0x7D, 0xB0, 0xE6, 0xA2, 0x76, 0xCB, 0x4E, 0x62, 0x70, 0x18, 0x7D, 0x6C, 0x90 }, + { 0x74, 0x18, 0x04, 0x20, 0xA7, 0x84, 0x18, 0x9B, 0x55, 0xF8, 0xC4, 0x66, 0x70, 0x75, 0xE8, 0x9C, 0x20, 0x64, 0xFF, 0x48, 0x1B, 0x6E, 0xD2, 0xA2, 0x3A, 0x75, 0x17, 0xAF, 0x71, 0xF6, 0xB7, 0xA8 }, + { 0xBE, 0x6B, 0x9F, 0xB0, 0x75, 0x86, 0xEB, 0xAB, 0xD2, 0x34, 0xEE, 0xE0, 0xA0, 0x5E, 0x81, 0x3D, 0xFF, 0xC1, 0x4D, 0x73, 0x78, 0x20, 0x85, 0xC8, 0xDF, 0xE7, 0x7C, 0x1F, 0xAD, 0xDA, 0x71, 0x72 }, + { 0x56, 0xC4, 0x04, 0x19, 0xCE, 0x7F, 0x84, 0x49, 0x49, 0xB5, 0x03, 0x7C, 0x91, 0xC4, 0x5E, 0x5F, 0xDA, 0xF9, 0xE1, 0x19, 0x17, 0xB3, 0x1B, 0xAE, 0xFB, 0xD3, 0x31, 0x33, 0xFB, 0xF2, 0x58, 0xAD }, + { 0x3D, 0x21, 0x31, 0x5C, 0xB2, 0x6D, 0xE2, 0x73, 0xBC, 0x79, 0x02, 0x3A, 0x44, 0xA7, 0x80, 0x00, 0x6C, 0xBD, 0x97, 0x1F, 0xA9, 0x6F, 0x34, 0x90, 0x4E, 0x0A, 0x95, 0x79, 0x2C, 0x74, 0xAE, 0x9A } + }, 5, { + { 0x02, 0xEB, 0xD2, 0x1E, 0x4F, 0x4E, 0xA2, 0x77, 0x2B, 0xD4, 0xE4, 0x27, 0xD9, 0x8C, 0x9D, 0xC2, 0x68, 0x89, 0x4D, 0x18, 0xEC, 0x45, 0xE1, 0x40, 0x63, 0x78, 0x5B, 0x89, 0x2D, 0x42, 0x92, 0x1F, 0xF4, 0x02, 0xFB, 0x73, 0x02, 0x8B, 0x71, 0x0A, 0xCB, 0xE4, 0x9F, 0xC2, 0xD9, 0x95, 0x75, 0x7E, 0x07, 0x77, 0x60, 0xCA, 0x7C, 0x1B, 0x24, 0x52, 0x79, 0x1A, 0x3B, 0xDA, 0x08, 0x6B, 0x91, 0xA1, 0xCE, 0xF3 }, + { 0x02, 0xBC, 0xBE, 0xF1, 0x17, 0x1F, 0x78, 0x85, 0x70, 0x16, 0xB2, 0x05, 0xC0, 0xC9, 0xDE, 0x61, 0x75, 0x0C, 0xC2, 0x14, 0x48, 0xC1, 0x67, 0xAA, 0xFA, 0xFD, 0x91, 0x90, 0x96, 0x2A, 0xEA, 0xFF, 0x79, 0x03, 0x27, 0x98, 0xE5, 0x33, 0xA6, 0x5F, 0x94, 0xD1, 0xDF, 0xF9, 0x01, 0xA2, 0xCB, 0x4F, 0x10, 0x7D, 0x49, 0xFE, 0x6B, 0x05, 0x27, 0xE9, 0x5D, 0x7A, 0xE2, 0x4E, 0x4D, 0xBB, 0xB6, 0x81, 0xF5, 0x52 }, + { 0x02, 0xA4, 0x55, 0xD7, 0x31, 0xEC, 0xDC, 0xAA, 0x59, 0x22, 0x8C, 0xE8, 0x2C, 0xA1, 0xB5, 0xCF, 0x45, 0x97, 0x4F, 0x6E, 0x6D, 0x21, 0xEB, 0x57, 0x50, 0x1B, 0xE2, 0x23, 0x10, 0xF0, 0x89, 0xBF, 0x69, 0x03, 0x7E, 0x26, 0x47, 0xE7, 0x3C, 0x02, 0x2A, 0x91, 0x3C, 0x87, 0xD8, 0x81, 0x3D, 0x48, 0xE7, 0x6D, 0x72, 0x31, 0x3D, 0xF4, 0x69, 0x76, 0x44, 0xC2, 0x3D, 0xDE, 0x82, 0x0D, 0xBE, 0xF7, 0x6D, 0x4A }, + { 0x02, 0x67, 0x30, 0xE2, 0x78, 0xBD, 0xB6, 0x5A, 0x8E, 0x77, 0x18, 0x64, 0x10, 0x38, 0x90, 0xA1, 0xF1, 0x0B, 0xA5, 0xAB, 0x9B, 0x42, 0x9E, 0x08, 0x43, 0xCC, 0xB4, 0x5F, 0xD2, 0xD9, 0x05, 0x2C, 0x6A, 0x03, 0x52, 0x5D, 0x89, 0xB7, 0xC9, 0x61, 0x5F, 0x84, 0x6D, 0x36, 0x22, 0x3D, 0x77, 0x7C, 0x5D, 0x6B, 0xF1, 0x34, 0xFD, 0x19, 0x81, 0xFC, 0xB2, 0xF6, 0xB9, 0x4F, 0x7F, 0xA7, 0x0C, 0xE6, 0x68, 0xAB }, + { 0x03, 0x4D, 0x04, 0x8E, 0xD3, 0x55, 0x4B, 0xE5, 0xD0, 0xF0, 0x33, 0x08, 0x93, 0x60, 0x60, 0xFA, 0xAA, 0x8A, 0x08, 0x89, 0xFD, 0x13, 0x5E, 0x81, 0x76, 0xDC, 0x08, 0x43, 0xC4, 0xFB, 0x68, 0xA8, 0x99, 0x03, 0x49, 0x74, 0x42, 0xC3, 0xAC, 0x05, 0xC9, 0x8A, 0x8F, 0xDD, 0xB4, 0x06, 0x46, 0xA6, 0x20, 0x3A, 0x6E, 0xA5, 0x3E, 0x20, 0x84, 0x6F, 0x8D, 0x0A, 0x86, 0x34, 0x47, 0x01, 0x1B, 0xE8, 0xEA, 0x71 } + }, 5, { + { 0x8A, 0x11, 0x60, 0x47, 0x9C, 0x41, 0x88, 0xDA, 0x23, 0x7C, 0x53, 0x63, 0x9E, 0xDE, 0xFC, 0x60, 0xC2, 0x4E, 0x87, 0xF9, 0x1A, 0xC8, 0x97, 0x2D, 0x96, 0x60, 0x00, 0x68, 0x0A, 0x7D, 0x07, 0x32, 0x8A, 0x53, 0x18, 0xB8, 0x17, 0x26, 0xCB, 0x9B, 0x16, 0xB9, 0x32, 0x12, 0x64, 0x61, 0x1C, 0x7D, 0xF0, 0xC7, 0x37, 0xBB, 0x64, 0x94, 0x1F, 0x79, 0xD4, 0x03, 0xD2, 0xD5, 0x03, 0xFA, 0xB3, 0xAB }, + { 0x38, 0x21, 0x4C, 0x92, 0x72, 0x97, 0xFD, 0x9F, 0x61, 0x72, 0x2C, 0x93, 0xA6, 0x56, 0x8A, 0x7C, 0xFE, 0x37, 0xD8, 0xBF, 0xA7, 0xC7, 0x38, 0x22, 0x33, 0x7F, 0xEA, 0x77, 0xAD, 0x97, 0xA3, 0x25, 0xCB, 0x33, 0xA2, 0xD2, 0xCB, 0x48, 0x6A, 0x6F, 0x2E, 0xE5, 0x97, 0xD7, 0xED, 0x9D, 0x55, 0x52, 0xDD, 0x09, 0x64, 0x52, 0xE3, 0xAC, 0x9D, 0xFA, 0x97, 0x87, 0x01, 0x9B, 0xAB, 0x76, 0x52, 0xEB }, + { 0xE3, 0x49, 0x04, 0x27, 0xC9, 0x87, 0x33, 0x36, 0x62, 0xC6, 0x49, 0xE5, 0x80, 0x16, 0x83, 0xB8, 0xBF, 0xCB, 0x7E, 0x5F, 0x07, 0x25, 0x90, 0x8D, 0xBC, 0x96, 0x8A, 0xA8, 0x6A, 0xF1, 0xFA, 0x2C, 0x10, 0xE4, 0x69, 0x07, 0x66, 0xA5, 0x47, 0xCA, 0x58, 0x13, 0x6E, 0xF3, 0xDC, 0x10, 0x45, 0xA8, 0xC3, 0xEC, 0xEA, 0x53, 0x2A, 0x05, 0x7F, 0x1A, 0x1A, 0xF1, 0xE4, 0x27, 0x61, 0xE0, 0xEC, 0xD7 }, + { 0xEE, 0x85, 0x5A, 0x53, 0x46, 0x35, 0x21, 0xDE, 0xCA, 0xFA, 0x11, 0x32, 0xD1, 0x21, 0x64, 0x4C, 0xF0, 0xBB, 0xA4, 0xA8, 0x60, 0x45, 0x6F, 0x26, 0x54, 0x02, 0x61, 0x02, 0x3D, 0x9A, 0x49, 0x91, 0x0E, 0x40, 0xFA, 0x14, 0x6B, 0x6B, 0x9D, 0x4B, 0x89, 0x14, 0xD5, 0x7D, 0x0B, 0x14, 0xA0, 0x3B, 0xF5, 0xC7, 0x53, 0x06, 0x7C, 0xC1, 0x44, 0xC6, 0x9C, 0x14, 0xD9, 0x24, 0xF0, 0x37, 0xEF, 0x9E }, + { 0xCE, 0x5F, 0x5A, 0x72, 0x25, 0x36, 0xE5, 0x65, 0x61, 0xC5, 0xC1, 0x25, 0x8A, 0x8E, 0x6A, 0x38, 0x48, 0x0A, 0x7D, 0x00, 0xF7, 0x96, 0x45, 0x46, 0x0C, 0xCA, 0x3D, 0xE7, 0xF1, 0x0E, 0x48, 0x03, 0x08, 0xEF, 0x46, 0xC6, 0x44, 0xD0, 0x1F, 0x0F, 0xCB, 0x05, 0x95, 0x0F, 0x38, 0x4C, 0x65, 0x51, 0x98, 0x10, 0x1B, 0xDD, 0x83, 0xC6, 0x04, 0xA8, 0x48, 0x4F, 0xCC, 0xB4, 0x99, 0x14, 0xCC, 0x39 } + }, 7, { + { 0xE8, 0xF7, 0x91, 0xFF, 0x92, 0x25, 0xA2, 0xAF, 0x01, 0x02, 0xAF, 0xFF, 0x4A, 0x9A, 0x72, 0x3D, 0x96, 0x12, 0xA6, 0x82, 0xA2, 0x5E, 0xBE, 0x79, 0x80, 0x2B, 0x26, 0x3C, 0xDF, 0xCD, 0x83, 0xBB }, + { 0xAE, 0x2E, 0xA7, 0x97, 0xCC, 0x0F, 0xE7, 0x2A, 0xC5, 0xB9, 0x7B, 0x97, 0xF3, 0xC6, 0x95, 0x7D, 0x7E, 0x41, 0x99, 0xA1, 0x67, 0xA5, 0x8E, 0xB0, 0x8B, 0xCA, 0xFF, 0xDA, 0x70, 0xAC, 0x04, 0x55 }, + { 0xF5, 0x2E, 0xCB, 0xC5, 0x65, 0xB3, 0xD8, 0xBE, 0xA2, 0xDF, 0xD5, 0xB7, 0x5A, 0x4F, 0x45, 0x7E, 0x54, 0x36, 0x98, 0x09, 0x32, 0x2E, 0x41, 0x20, 0x83, 0x16, 0x26, 0xF2, 0x90, 0xFA, 0x87, 0xE0 }, + { 0x19, 0x69, 0xAD, 0x73, 0xCC, 0x17, 0x7F, 0xA0, 0xB4, 0xFC, 0xED, 0x6D, 0xF1, 0xF7, 0xBF, 0x99, 0x07, 0xE6, 0x65, 0xFD, 0xE9, 0xBA, 0x19, 0x6A, 0x74, 0xFE, 0xD0, 0xA3, 0xCF, 0x5A, 0xEF, 0x9D }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 }, + { 0x36, 0x80, 0xD8, 0x72, 0x53, 0xA0, 0x3C, 0xDE, 0xB0, 0xB3, 0xD2, 0x28, 0xAA, 0xE3, 0x7B, 0x2A, 0x35, 0x61, 0x12, 0xD2, 0x76, 0xC0, 0xAA, 0xF5, 0x2D, 0x5F, 0x02, 0x2B, 0x2E, 0xC7, 0xB1, 0x17 }, + { 0xE8, 0xF7, 0x91, 0xFF, 0x92, 0x25, 0xA2, 0xAF, 0x01, 0x02, 0xAF, 0xFF, 0x4A, 0x9A, 0x72, 0x3D, 0x96, 0x12, 0xA6, 0x82, 0xA2, 0x5E, 0xBE, 0x79, 0x80, 0x2B, 0x26, 0x3C, 0xDF, 0xCD, 0x83, 0xBB, 0xFF } + } }, +}; +static const struct frost_vec_sign_case frost_vec_tweak_valid_cases[28] = { + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 0, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x93, 0xDD, 0xE8, 0xC9, 0xCE, 0xE7, 0x14, 0xEB, 0x5B, 0xDF, 0x2B, 0xE0, 0x0F, 0xEC, 0x33, 0x27, 0xF9, 0xCF, 0x38, 0x6D, 0x3A, 0xC6, 0x72, 0xF0, 0xDA, 0x73, 0x4F, 0xFC, 0x08, 0xE7, 0xA0, 0x41 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 0, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { 0 }, { 1 }, FROST_VEC_ERR_NONE, -1, { 0xB8, 0x3A, 0x0D, 0x33, 0x12, 0x1B, 0x5A, 0x85, 0x8B, 0xDC, 0xA6, 0x75, 0x0E, 0xD2, 0x0C, 0x34, 0xB4, 0x90, 0xBA, 0xF2, 0x6D, 0xC8, 0x74, 0xB0, 0x88, 0x9F, 0x19, 0x86, 0x2B, 0x8D, 0xC9, 0x38 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 0, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0xB8, 0x3A, 0x0D, 0x33, 0x12, 0x1B, 0x5A, 0x85, 0x8B, 0xDC, 0xA6, 0x75, 0x0E, 0xD2, 0x0C, 0x34, 0xB4, 0x90, 0xBA, 0xF2, 0x6D, 0xC8, 0x74, 0xB0, 0x88, 0x9F, 0x19, 0x86, 0x2B, 0x8D, 0xC9, 0x38 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 0, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 2, { 0, 1 }, { 0, 1 }, FROST_VEC_ERR_NONE, -1, { 0xF8, 0x6C, 0x0A, 0x3F, 0xA8, 0xF2, 0x91, 0xC8, 0x09, 0x36, 0xF3, 0x7D, 0x3B, 0x3A, 0x5D, 0x3F, 0x69, 0x92, 0xA8, 0xBF, 0x4C, 0xF0, 0x30, 0xE0, 0x50, 0xE4, 0xBA, 0xD4, 0xA1, 0x56, 0xB0, 0xB5 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 0, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 4, { 0, 1, 2, 3 }, { 1, 0, 1, 0 }, FROST_VEC_ERR_NONE, -1, { 0x56, 0x06, 0xCC, 0x52, 0x73, 0x16, 0xC8, 0xA7, 0xFF, 0x47, 0xF3, 0x1A, 0xB6, 0x06, 0x4E, 0xC6, 0x8D, 0x73, 0x12, 0x4E, 0x9D, 0xC8, 0x91, 0x8A, 0x71, 0xD9, 0x90, 0xBD, 0xAB, 0x05, 0xF0, 0x0E } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 0, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 4, { 0, 1, 2, 3 }, { 0, 0, 1, 1 }, FROST_VEC_ERR_NONE, -1, { 0x72, 0x45, 0x54, 0x83, 0x43, 0xE8, 0x70, 0xFD, 0x5B, 0xA3, 0xB7, 0x30, 0x05, 0xDD, 0xE3, 0x99, 0x2C, 0x41, 0x11, 0x2F, 0xDC, 0x59, 0xF0, 0x08, 0xAD, 0x58, 0xF4, 0x53, 0xA3, 0xA4, 0x6A, 0x11 } }, + { 0, 1, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 1, 1, { 0x02, 0xCB, 0xC2, 0xE4, 0x1A, 0xF8, 0x72, 0x90, 0xA1, 0x40, 0x1D, 0x49, 0x92, 0x7F, 0xC3, 0x0D, 0x7F, 0x40, 0xA4, 0x04, 0xC4, 0xDF, 0x3E, 0x5F, 0xC7, 0x34, 0x01, 0x41, 0x88, 0xDB, 0xC4, 0x4E, 0x15, 0x03, 0xC1, 0x53, 0x12, 0xED, 0xC6, 0x91, 0xEB, 0x21, 0x3F, 0x3B, 0x8A, 0xAC, 0x19, 0x5D, 0x25, 0x1A, 0x39, 0x05, 0x63, 0xCD, 0x5E, 0x31, 0x3D, 0x73, 0x8A, 0x89, 0xDA, 0xEB, 0x4D, 0xA8, 0x07, 0x46 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 4, { 0, 1, 2, 3 }, { 0, 0, 1, 1 }, FROST_VEC_ERR_NONE, -1, { 0x5A, 0xC0, 0xE5, 0x10, 0xFB, 0x37, 0xF0, 0x2B, 0xAD, 0x7A, 0x04, 0xD1, 0xE0, 0xBA, 0x08, 0x27, 0xDF, 0x64, 0x60, 0xDE, 0xE7, 0xAA, 0x6C, 0xAB, 0x5D, 0xD2, 0x82, 0x91, 0x3D, 0x06, 0x49, 0x65 } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 0, 0, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0xB7, 0xC3, 0xFA, 0x9A, 0xEA, 0x2B, 0x09, 0x89, 0xD1, 0x50, 0xB5, 0x74, 0x33, 0x23, 0x30, 0x15, 0xA2, 0x69, 0xCB, 0x56, 0x23, 0x2B, 0x1D, 0xE2, 0xAF, 0xE5, 0x73, 0x49, 0x1D, 0x96, 0x0B, 0x2C } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 0, 0, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { 0 }, { 1 }, FROST_VEC_ERR_NONE, -1, { 0xF1, 0xD1, 0xFF, 0x60, 0xA0, 0x05, 0x22, 0x79, 0xEC, 0xE0, 0xF7, 0xF2, 0x16, 0x26, 0x6D, 0x08, 0xB5, 0xBD, 0x54, 0x83, 0xD5, 0xEA, 0xF1, 0x35, 0x0A, 0xB5, 0x19, 0x9D, 0x68, 0xCA, 0x8F, 0x83 } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 0, 0, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0xFB, 0xA0, 0x18, 0xDE, 0xF6, 0x4F, 0x55, 0xBC, 0xBC, 0x29, 0x58, 0xC2, 0xE6, 0xA7, 0xC3, 0xDF, 0xC0, 0xFC, 0xD1, 0xFD, 0x67, 0x5C, 0xF0, 0xA2, 0xA5, 0xB5, 0xA9, 0x2A, 0xC3, 0x79, 0x9A, 0x9B } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 0, 0, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 2, { 0, 1 }, { 0, 1 }, FROST_VEC_ERR_NONE, -1, { 0xAB, 0xDB, 0x67, 0x4B, 0x4B, 0xDB, 0xC2, 0x84, 0x7A, 0xE7, 0x99, 0x3F, 0x98, 0xF1, 0xB6, 0x00, 0x06, 0xDF, 0xE2, 0xE8, 0x40, 0xD7, 0x09, 0x96, 0xA6, 0x22, 0x3E, 0xE2, 0x93, 0x17, 0xD5, 0x79 } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 0, 0, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 4, { 0, 1, 2, 3 }, { 1, 0, 1, 0 }, FROST_VEC_ERR_NONE, -1, { 0xA6, 0x15, 0xA9, 0xC8, 0x61, 0x70, 0xBA, 0x08, 0x8E, 0x9F, 0x92, 0xAF, 0x09, 0xC2, 0x98, 0x81, 0xC7, 0xCF, 0x03, 0x69, 0xD8, 0x75, 0x0C, 0x4F, 0xAE, 0x30, 0x2A, 0x72, 0x33, 0x02, 0xD6, 0xEE } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 0, 0, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 4, { 0, 1, 2, 3 }, { 0, 0, 1, 1 }, FROST_VEC_ERR_NONE, -1, { 0xDD, 0xF8, 0x86, 0xA1, 0xED, 0x7A, 0x09, 0x2A, 0x5B, 0xE4, 0xB5, 0x76, 0x00, 0x3B, 0xC9, 0xAE, 0x93, 0x28, 0x89, 0x6E, 0x30, 0x89, 0x80, 0x2D, 0x62, 0xD4, 0x7F, 0xDF, 0xB2, 0x78, 0xAE, 0x12 } }, + { 1, 1, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 1, 1, { 0x02, 0x77, 0xE7, 0x16, 0x75, 0x6B, 0xAE, 0xFD, 0x92, 0x2D, 0xCD, 0x33, 0x9D, 0x08, 0x3F, 0xEB, 0x1C, 0x02, 0x63, 0xB0, 0x69, 0x99, 0x32, 0x84, 0x92, 0x33, 0x1F, 0xB8, 0x76, 0xA2, 0x25, 0xEE, 0xA3, 0x03, 0x39, 0x10, 0xC4, 0xFC, 0x15, 0x1C, 0x7A, 0xA9, 0x14, 0xB4, 0xD2, 0xAC, 0x97, 0xB3, 0xF0, 0x9C, 0x56, 0xA3, 0x6A, 0x5F, 0x95, 0xF1, 0x40, 0x43, 0xD9, 0x02, 0x10, 0xCC, 0x1F, 0xCD, 0x42, 0x45 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 4, { 0, 1, 2, 3 }, { 0, 0, 1, 1 }, FROST_VEC_ERR_NONE, -1, { 0x4A, 0x46, 0x46, 0x63, 0x3B, 0x30, 0xCE, 0xA9, 0xE9, 0x1B, 0x04, 0x1C, 0xBC, 0x5B, 0xF9, 0x05, 0x39, 0x9D, 0xC2, 0x30, 0xE0, 0x57, 0x47, 0x87, 0x06, 0x67, 0x55, 0x0D, 0x9F, 0xC9, 0x80, 0x53 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x30, 0x5F, 0xE5, 0x09, 0xF0, 0x0F, 0x66, 0x5A, 0xAC, 0x83, 0x6D, 0x1E, 0x49, 0xFF, 0x25, 0x39, 0xD3, 0xA1, 0x1A, 0x9B, 0x20, 0x46, 0x24, 0x57, 0xA4, 0x9E, 0xBE, 0x28, 0xBE, 0xD0, 0x67, 0x28 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { 0 }, { 1 }, FROST_VEC_ERR_NONE, -1, { 0x8B, 0x9B, 0x2F, 0x8D, 0xD7, 0x6C, 0x0F, 0xBB, 0xA0, 0xEC, 0x0E, 0xCF, 0xB6, 0x77, 0x56, 0xCB, 0x85, 0x5C, 0x26, 0x7E, 0xF1, 0x3D, 0x23, 0x0F, 0xAC, 0x86, 0x5C, 0x2D, 0xB6, 0x10, 0x1F, 0x0E } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x8B, 0x9B, 0x2F, 0x8D, 0xD7, 0x6C, 0x0F, 0xBB, 0xA0, 0xEC, 0x0E, 0xCF, 0xB6, 0x77, 0x56, 0xCB, 0x85, 0x5C, 0x26, 0x7E, 0xF1, 0x3D, 0x23, 0x0F, 0xAC, 0x86, 0x5C, 0x2D, 0xB6, 0x10, 0x1F, 0x0E } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 2, { 0, 1 }, { 0, 1 }, FROST_VEC_ERR_NONE, -1, { 0x2F, 0xD2, 0xED, 0xC6, 0x6C, 0xC8, 0x0A, 0x10, 0xAC, 0xE5, 0xA0, 0xFF, 0x5A, 0x2A, 0x18, 0x9F, 0x23, 0x44, 0x7E, 0xCB, 0x17, 0x25, 0xE8, 0xA1, 0xAE, 0xDD, 0x1D, 0x52, 0x40, 0xA5, 0x6E, 0x07 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 4, { 0, 1, 2, 3 }, { 1, 0, 1, 0 }, FROST_VEC_ERR_NONE, -1, { 0x68, 0x53, 0x30, 0x95, 0xDD, 0x3A, 0xC5, 0x09, 0x29, 0xFF, 0x52, 0x20, 0xFE, 0xEC, 0x28, 0x1E, 0x59, 0x3B, 0xB1, 0xDC, 0x80, 0x36, 0xC7, 0xEB, 0xA7, 0xCA, 0x88, 0xF4, 0x99, 0x67, 0xFD, 0x6A } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 4, { 0, 1, 2, 3 }, { 0, 0, 1, 1 }, FROST_VEC_ERR_NONE, -1, { 0x8C, 0xBD, 0x6D, 0xD4, 0x22, 0xB8, 0x2B, 0x04, 0x3C, 0x39, 0xB4, 0xD9, 0xE4, 0x0B, 0x11, 0x46, 0x45, 0x2F, 0x72, 0x69, 0x92, 0xF3, 0x76, 0x65, 0x3C, 0x11, 0x18, 0x6C, 0xE2, 0xB4, 0xDB, 0xB8 } }, + { 2, 1, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 1, 1, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 4, { 0, 1, 2, 3 }, { 0, 0, 1, 1 }, FROST_VEC_ERR_NONE, -1, { 0x07, 0x83, 0x6C, 0x86, 0xC4, 0xC5, 0x75, 0x3E, 0x51, 0xB5, 0x8B, 0xEB, 0xB7, 0xCC, 0xBB, 0x28, 0x22, 0x25, 0xC3, 0xC7, 0x7B, 0x48, 0x20, 0xF2, 0x36, 0xBC, 0x1C, 0x3D, 0x0F, 0xD4, 0xAC, 0xD0 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x60, 0x3E, 0xC1, 0xEA, 0x86, 0xB2, 0x84, 0xE2, 0x8C, 0xEF, 0xD5, 0x9C, 0x85, 0xF8, 0xDD, 0xC6, 0xDF, 0xE8, 0x1C, 0x07, 0x44, 0xF5, 0x9D, 0x8F, 0xB5, 0xBE, 0xB2, 0x9F, 0x1C, 0x27, 0xF3, 0x8B } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { 0 }, { 1 }, FROST_VEC_ERR_NONE, -1, { 0x02, 0xB3, 0x3B, 0xC2, 0xC8, 0xD2, 0x52, 0x66, 0xF0, 0x3A, 0xE9, 0xD6, 0x96, 0xDB, 0x21, 0xA1, 0x87, 0xDF, 0x31, 0x05, 0xA8, 0xA8, 0x64, 0x4F, 0xD5, 0x49, 0x05, 0xB3, 0x5C, 0x2B, 0xE8, 0x9D } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { 0 }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0xC8, 0x93, 0x19, 0x86, 0x09, 0xB8, 0x7B, 0x9E, 0xD6, 0x0A, 0xCC, 0xDF, 0x2A, 0xFE, 0x67, 0xEB, 0xFB, 0x6F, 0x98, 0xB7, 0x0A, 0x40, 0xFF, 0x4A, 0xA0, 0xA8, 0x40, 0xC0, 0x8B, 0xA5, 0xAC, 0xD6 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 2, { 0, 1 }, { 0, 1 }, FROST_VEC_ERR_NONE, -1, { 0x84, 0x59, 0x0B, 0xAE, 0x81, 0xC7, 0xD3, 0xF6, 0x61, 0x4F, 0xC8, 0xF7, 0x8D, 0x82, 0xC8, 0x27, 0xD1, 0x99, 0xF6, 0x4C, 0x1B, 0x13, 0x76, 0x45, 0x12, 0x94, 0x86, 0x02, 0x46, 0x95, 0x7B, 0x7E } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 4, { 0, 1, 2, 3 }, { 1, 0, 1, 0 }, FROST_VEC_ERR_NONE, -1, { 0xD2, 0xCC, 0x2C, 0x05, 0xE2, 0x0C, 0x80, 0x30, 0x4A, 0x7D, 0x89, 0x5F, 0xE5, 0x36, 0xCF, 0x77, 0x84, 0xEA, 0x46, 0xA6, 0xD5, 0xB5, 0xC2, 0xEC, 0x27, 0x99, 0x24, 0x08, 0x1B, 0xDE, 0x04, 0x4F } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 4, { 0, 1, 2, 3 }, { 0, 0, 1, 1 }, FROST_VEC_ERR_NONE, -1, { 0x7E, 0xDC, 0x83, 0x52, 0x90, 0xF0, 0xBB, 0x7B, 0xA6, 0x6A, 0x09, 0xFA, 0x47, 0xA5, 0x7F, 0x58, 0xA6, 0x65, 0x84, 0x87, 0x47, 0x7E, 0x0E, 0xB5, 0xC7, 0x67, 0x46, 0x51, 0x30, 0xD0, 0xDE, 0xCB } }, + { 3, 1, 5, { 0, 1, 2, 3, 4 }, 1, { 0, 1, 2, 3, 4 }, 1, 1, { 0x03, 0x53, 0x60, 0x24, 0xF2, 0x1D, 0x3C, 0x18, 0xE0, 0xF0, 0x94, 0xD1, 0x5E, 0x9D, 0xDA, 0x07, 0x74, 0x07, 0x54, 0x90, 0x55, 0x70, 0xA1, 0xB6, 0x8C, 0xAF, 0xAC, 0x74, 0x3A, 0x6C, 0x21, 0x37, 0x45, 0x03, 0x7C, 0x9E, 0xA6, 0x73, 0x0C, 0xD2, 0x19, 0x04, 0xC1, 0x31, 0xFF, 0x4A, 0x6C, 0x62, 0x48, 0x0A, 0x7B, 0xAB, 0xAA, 0x75, 0xF0, 0xA4, 0xF6, 0x3F, 0x1A, 0xFD, 0x8D, 0xEE, 0x9F, 0xDD, 0x69, 0x9D }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 4, { 0, 1, 2, 3 }, { 0, 0, 1, 1 }, FROST_VEC_ERR_NONE, -1, { 0x04, 0xE4, 0xBE, 0x62, 0x19, 0x36, 0x5A, 0xAB, 0x2B, 0x4D, 0x57, 0x7D, 0x4E, 0x55, 0x15, 0x99, 0x24, 0x09, 0x1B, 0xA7, 0xEB, 0x54, 0x01, 0x80, 0x4B, 0x60, 0x87, 0x6E, 0xF6, 0x60, 0x16, 0xE5 } }, +}; +static const struct frost_vec_sign_case frost_vec_tweak_error_cases[8] = { + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 0, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { 4 }, { 0 }, FROST_VEC_ERR_TWEAK_ADD, -1, { 0 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 0, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { 5 }, { 0 }, FROST_VEC_ERR_TWEAK_ADD, -1, { 0 } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 0, 0, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { 4 }, { 0 }, FROST_VEC_ERR_TWEAK_ADD, -1, { 0 } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 0, 0, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { 5 }, { 0 }, FROST_VEC_ERR_TWEAK_ADD, -1, { 0 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { 4 }, { 0 }, FROST_VEC_ERR_TWEAK_ADD, -1, { 0 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { 5 }, { 0 }, FROST_VEC_ERR_TWEAK_ADD, -1, { 0 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { 4 }, { 0 }, FROST_VEC_ERR_TWEAK_ADD, -1, { 0 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 0, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { 5 }, { 0 }, FROST_VEC_ERR_TWEAK_ADD, -1, { 0 } }, +}; +static const struct frost_vec_group frost_vec_sig_agg_groups[4] = { + { 2, 3, { 0x02, 0xD7, 0x72, 0xA0, 0x9F, 0x5F, 0x67, 0x57, 0x83, 0xD2, 0x75, 0xED, 0x9F, 0x6A, 0xAE, 0xDB, 0x2E, 0xCC, 0xBC, 0x74, 0x17, 0x1B, 0x37, 0xAC, 0x23, 0xAE, 0x3B, 0xBD, 0x9D, 0x7A, 0xE2, 0xCD, 0xAA }, 3, { + { 0x03, 0x9E, 0xE3, 0x33, 0x5A, 0xF4, 0x8D, 0xFE, 0x23, 0x70, 0x2A, 0xB3, 0x53, 0xF4, 0xAF, 0x20, 0xD4, 0x01, 0xF6, 0x7A, 0x13, 0x0D, 0xF7, 0x83, 0xCC, 0x84, 0x57, 0x32, 0x3A, 0x86, 0x0A, 0x2F, 0xB4 }, + { 0x02, 0x84, 0xDC, 0x4A, 0xB2, 0xCB, 0x78, 0xA6, 0x21, 0xEB, 0x87, 0xFA, 0x1F, 0x14, 0xBC, 0xE2, 0xB7, 0x25, 0xAF, 0xEA, 0xAC, 0x98, 0x1A, 0xDC, 0xBA, 0xFF, 0x5C, 0xC2, 0xD4, 0x17, 0xD2, 0xA6, 0x3A }, + { 0x03, 0x64, 0x41, 0xEC, 0x2D, 0x4C, 0x12, 0x66, 0x20, 0x1C, 0xD8, 0x9B, 0x69, 0x54, 0x9A, 0x2F, 0x5B, 0x21, 0x88, 0x61, 0x2A, 0x0D, 0x43, 0x41, 0x53, 0xE6, 0x25, 0xFB, 0x38, 0x17, 0x3D, 0xD5, 0x09 } + }, 0, {}, 0, {}, 0, {}, 4, { + { 0xE8, 0xF7, 0x91, 0xFF, 0x92, 0x25, 0xA2, 0xAF, 0x01, 0x02, 0xAF, 0xFF, 0x4A, 0x9A, 0x72, 0x3D, 0x96, 0x12, 0xA6, 0x82, 0xA2, 0x5E, 0xBE, 0x79, 0x80, 0x2B, 0x26, 0x3C, 0xDF, 0xCD, 0x83, 0xBB }, + { 0xAE, 0x2E, 0xA7, 0x97, 0xCC, 0x0F, 0xE7, 0x2A, 0xC5, 0xB9, 0x7B, 0x97, 0xF3, 0xC6, 0x95, 0x7D, 0x7E, 0x41, 0x99, 0xA1, 0x67, 0xA5, 0x8E, 0xB0, 0x8B, 0xCA, 0xFF, 0xDA, 0x70, 0xAC, 0x04, 0x55 }, + { 0xF5, 0x2E, 0xCB, 0xC5, 0x65, 0xB3, 0xD8, 0xBE, 0xA2, 0xDF, 0xD5, 0xB7, 0x5A, 0x4F, 0x45, 0x7E, 0x54, 0x36, 0x98, 0x09, 0x32, 0x2E, 0x41, 0x20, 0x83, 0x16, 0x26, 0xF2, 0x90, 0xFA, 0x87, 0xE0 }, + { 0x19, 0x69, 0xAD, 0x73, 0xCC, 0x17, 0x7F, 0xA0, 0xB4, 0xFC, 0xED, 0x6D, 0xF1, 0xF7, 0xBF, 0x99, 0x07, 0xE6, 0x65, 0xFD, 0xE9, 0xBA, 0x19, 0x6A, 0x74, 0xFE, 0xD0, 0xA3, 0xCF, 0x5A, 0xEF, 0x9D } + } }, + { 1, 3, { 0x03, 0xD1, 0x93, 0x9B, 0xE8, 0x7D, 0x18, 0xEA, 0x5A, 0xB3, 0x02, 0xE2, 0x70, 0x77, 0xD1, 0x6B, 0x2C, 0x2F, 0xD9, 0x35, 0x16, 0xF9, 0x15, 0x14, 0xBA, 0x04, 0x99, 0x33, 0xD3, 0x48, 0xDA, 0x44, 0x1F }, 3, { + { 0x03, 0xD1, 0x93, 0x9B, 0xE8, 0x7D, 0x18, 0xEA, 0x5A, 0xB3, 0x02, 0xE2, 0x70, 0x77, 0xD1, 0x6B, 0x2C, 0x2F, 0xD9, 0x35, 0x16, 0xF9, 0x15, 0x14, 0xBA, 0x04, 0x99, 0x33, 0xD3, 0x48, 0xDA, 0x44, 0x1F }, + { 0x03, 0xD1, 0x93, 0x9B, 0xE8, 0x7D, 0x18, 0xEA, 0x5A, 0xB3, 0x02, 0xE2, 0x70, 0x77, 0xD1, 0x6B, 0x2C, 0x2F, 0xD9, 0x35, 0x16, 0xF9, 0x15, 0x14, 0xBA, 0x04, 0x99, 0x33, 0xD3, 0x48, 0xDA, 0x44, 0x1F }, + { 0x03, 0xD1, 0x93, 0x9B, 0xE8, 0x7D, 0x18, 0xEA, 0x5A, 0xB3, 0x02, 0xE2, 0x70, 0x77, 0xD1, 0x6B, 0x2C, 0x2F, 0xD9, 0x35, 0x16, 0xF9, 0x15, 0x14, 0xBA, 0x04, 0x99, 0x33, 0xD3, 0x48, 0xDA, 0x44, 0x1F } + }, 0, {}, 0, {}, 0, {}, 4, { + { 0xE8, 0xF7, 0x91, 0xFF, 0x92, 0x25, 0xA2, 0xAF, 0x01, 0x02, 0xAF, 0xFF, 0x4A, 0x9A, 0x72, 0x3D, 0x96, 0x12, 0xA6, 0x82, 0xA2, 0x5E, 0xBE, 0x79, 0x80, 0x2B, 0x26, 0x3C, 0xDF, 0xCD, 0x83, 0xBB }, + { 0xAE, 0x2E, 0xA7, 0x97, 0xCC, 0x0F, 0xE7, 0x2A, 0xC5, 0xB9, 0x7B, 0x97, 0xF3, 0xC6, 0x95, 0x7D, 0x7E, 0x41, 0x99, 0xA1, 0x67, 0xA5, 0x8E, 0xB0, 0x8B, 0xCA, 0xFF, 0xDA, 0x70, 0xAC, 0x04, 0x55 }, + { 0xF5, 0x2E, 0xCB, 0xC5, 0x65, 0xB3, 0xD8, 0xBE, 0xA2, 0xDF, 0xD5, 0xB7, 0x5A, 0x4F, 0x45, 0x7E, 0x54, 0x36, 0x98, 0x09, 0x32, 0x2E, 0x41, 0x20, 0x83, 0x16, 0x26, 0xF2, 0x90, 0xFA, 0x87, 0xE0 }, + { 0x19, 0x69, 0xAD, 0x73, 0xCC, 0x17, 0x7F, 0xA0, 0xB4, 0xFC, 0xED, 0x6D, 0xF1, 0xF7, 0xBF, 0x99, 0x07, 0xE6, 0x65, 0xFD, 0xE9, 0xBA, 0x19, 0x6A, 0x74, 0xFE, 0xD0, 0xA3, 0xCF, 0x5A, 0xEF, 0x9D } + } }, + { 3, 3, { 0x02, 0x3E, 0x94, 0xD6, 0xA6, 0x86, 0x20, 0xD3, 0xF6, 0x02, 0x21, 0xA4, 0x18, 0x67, 0x86, 0x27, 0x4A, 0x71, 0x12, 0x21, 0xA8, 0xBB, 0xB3, 0x1A, 0x53, 0x88, 0xDF, 0xA6, 0x71, 0x8E, 0x8E, 0xF7, 0xBB }, 3, { + { 0x03, 0xA3, 0xE9, 0x32, 0xBA, 0x9D, 0xD0, 0x06, 0x3D, 0x72, 0x15, 0x90, 0xB6, 0xEF, 0x21, 0xDD, 0x45, 0x66, 0xA9, 0x7B, 0x20, 0x33, 0x43, 0xFD, 0xE9, 0xDA, 0x58, 0x15, 0xDB, 0x9B, 0xE0, 0x49, 0xCA }, + { 0x02, 0x01, 0xE5, 0xFE, 0xAC, 0x0D, 0xB5, 0x05, 0x9C, 0x32, 0xB0, 0x45, 0xF3, 0x77, 0x99, 0x10, 0x1A, 0x96, 0x26, 0x2B, 0x3C, 0x88, 0xCE, 0x85, 0xD6, 0x10, 0x45, 0x1F, 0xC2, 0x1A, 0x04, 0x57, 0xFF }, + { 0x03, 0xEF, 0x72, 0xD1, 0x0D, 0x1D, 0xFE, 0x4E, 0x78, 0x66, 0x19, 0x53, 0x6A, 0x45, 0x85, 0x07, 0xCA, 0xF1, 0x05, 0xFC, 0xCD, 0xB8, 0x17, 0x3D, 0xAF, 0x2E, 0x35, 0x80, 0x54, 0xAF, 0x2F, 0xA4, 0xA2 } + }, 0, {}, 0, {}, 0, {}, 4, { + { 0xE8, 0xF7, 0x91, 0xFF, 0x92, 0x25, 0xA2, 0xAF, 0x01, 0x02, 0xAF, 0xFF, 0x4A, 0x9A, 0x72, 0x3D, 0x96, 0x12, 0xA6, 0x82, 0xA2, 0x5E, 0xBE, 0x79, 0x80, 0x2B, 0x26, 0x3C, 0xDF, 0xCD, 0x83, 0xBB }, + { 0xAE, 0x2E, 0xA7, 0x97, 0xCC, 0x0F, 0xE7, 0x2A, 0xC5, 0xB9, 0x7B, 0x97, 0xF3, 0xC6, 0x95, 0x7D, 0x7E, 0x41, 0x99, 0xA1, 0x67, 0xA5, 0x8E, 0xB0, 0x8B, 0xCA, 0xFF, 0xDA, 0x70, 0xAC, 0x04, 0x55 }, + { 0xF5, 0x2E, 0xCB, 0xC5, 0x65, 0xB3, 0xD8, 0xBE, 0xA2, 0xDF, 0xD5, 0xB7, 0x5A, 0x4F, 0x45, 0x7E, 0x54, 0x36, 0x98, 0x09, 0x32, 0x2E, 0x41, 0x20, 0x83, 0x16, 0x26, 0xF2, 0x90, 0xFA, 0x87, 0xE0 }, + { 0x19, 0x69, 0xAD, 0x73, 0xCC, 0x17, 0x7F, 0xA0, 0xB4, 0xFC, 0xED, 0x6D, 0xF1, 0xF7, 0xBF, 0x99, 0x07, 0xE6, 0x65, 0xFD, 0xE9, 0xBA, 0x19, 0x6A, 0x74, 0xFE, 0xD0, 0xA3, 0xCF, 0x5A, 0xEF, 0x9D } + } }, + { 3, 5, { 0x03, 0xE1, 0xAE, 0xA0, 0x0A, 0x7B, 0x8D, 0x0E, 0x03, 0x93, 0x66, 0x4F, 0xEB, 0xBD, 0x31, 0x56, 0x9A, 0x02, 0xCA, 0xF2, 0x23, 0xD9, 0xAD, 0x83, 0xE9, 0x03, 0x31, 0xDC, 0x18, 0xB1, 0x98, 0x73, 0x58 }, 5, { + { 0x02, 0xF3, 0x33, 0xED, 0xD2, 0xB6, 0xF5, 0x32, 0xC2, 0xEF, 0x6C, 0x42, 0xE8, 0x03, 0xB6, 0x33, 0xA4, 0x22, 0x89, 0xD0, 0x56, 0x7A, 0x75, 0xC5, 0x0E, 0xB1, 0xC8, 0xCF, 0x85, 0xEC, 0x48, 0x0E, 0x8F }, + { 0x02, 0x53, 0x22, 0xF6, 0x36, 0x02, 0xEC, 0xCF, 0x14, 0x65, 0x41, 0xB7, 0xC9, 0xEE, 0x4D, 0x1F, 0xCB, 0x84, 0xEC, 0x13, 0x94, 0x71, 0x42, 0x04, 0x72, 0x18, 0x2A, 0xE9, 0x68, 0x67, 0x6A, 0x38, 0x7F }, + { 0x02, 0x30, 0x63, 0x9C, 0xEC, 0x0A, 0x83, 0x98, 0x2E, 0x17, 0x6D, 0x69, 0x05, 0xCE, 0x06, 0x20, 0xFD, 0xC5, 0x7E, 0x15, 0x15, 0x65, 0xA3, 0x9D, 0x0E, 0x08, 0x21, 0xB8, 0xE7, 0x53, 0xAE, 0x85, 0xB0 }, + { 0x02, 0x6E, 0x1A, 0x50, 0xE6, 0x72, 0xFE, 0xDD, 0x3F, 0x3C, 0x37, 0x8D, 0x61, 0x21, 0xE5, 0x70, 0x2B, 0x05, 0x06, 0x69, 0xDB, 0xC2, 0x41, 0xD2, 0xC2, 0x29, 0x98, 0x80, 0x15, 0x2C, 0xD2, 0x07, 0xBD }, + { 0x02, 0xDC, 0x06, 0xC4, 0xCA, 0x91, 0x9D, 0xE7, 0x0B, 0x4B, 0x82, 0x81, 0x90, 0x1C, 0xCF, 0x94, 0x71, 0xAB, 0x91, 0xFB, 0xFB, 0xEE, 0x1A, 0x8C, 0x57, 0x0D, 0x83, 0x91, 0x1C, 0xAA, 0xF9, 0xE2, 0xFA } + }, 0, {}, 0, {}, 0, {}, 4, { + { 0xE8, 0xF7, 0x91, 0xFF, 0x92, 0x25, 0xA2, 0xAF, 0x01, 0x02, 0xAF, 0xFF, 0x4A, 0x9A, 0x72, 0x3D, 0x96, 0x12, 0xA6, 0x82, 0xA2, 0x5E, 0xBE, 0x79, 0x80, 0x2B, 0x26, 0x3C, 0xDF, 0xCD, 0x83, 0xBB }, + { 0xAE, 0x2E, 0xA7, 0x97, 0xCC, 0x0F, 0xE7, 0x2A, 0xC5, 0xB9, 0x7B, 0x97, 0xF3, 0xC6, 0x95, 0x7D, 0x7E, 0x41, 0x99, 0xA1, 0x67, 0xA5, 0x8E, 0xB0, 0x8B, 0xCA, 0xFF, 0xDA, 0x70, 0xAC, 0x04, 0x55 }, + { 0xF5, 0x2E, 0xCB, 0xC5, 0x65, 0xB3, 0xD8, 0xBE, 0xA2, 0xDF, 0xD5, 0xB7, 0x5A, 0x4F, 0x45, 0x7E, 0x54, 0x36, 0x98, 0x09, 0x32, 0x2E, 0x41, 0x20, 0x83, 0x16, 0x26, 0xF2, 0x90, 0xFA, 0x87, 0xE0 }, + { 0x19, 0x69, 0xAD, 0x73, 0xCC, 0x17, 0x7F, 0xA0, 0xB4, 0xFC, 0xED, 0x6D, 0xF1, 0xF7, 0xBF, 0x99, 0x07, 0xE6, 0x65, 0xFD, 0xE9, 0xBA, 0x19, 0x6A, 0x74, 0xFE, 0xD0, 0xA3, 0xCF, 0x5A, 0xEF, 0x9D } + } }, +}; + +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]; +}; +static const struct frost_vec_sig_agg_case frost_vec_sig_agg_valid_cases[18] = { + { 0, 2, { 0, 1 }, 1, { 0, 1 }, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 0, { 0 }, { 0 }, 2, { { 0x93, 0xDD, 0xE8, 0xC9, 0xCE, 0xE7, 0x14, 0xEB, 0x5B, 0xDF, 0x2B, 0xE0, 0x0F, 0xEC, 0x33, 0x27, 0xF9, 0xCF, 0x38, 0x6D, 0x3A, 0xC6, 0x72, 0xF0, 0xDA, 0x73, 0x4F, 0xFC, 0x08, 0xE7, 0xA0, 0x41 }, { 0x43, 0x68, 0xB9, 0xCD, 0x58, 0x81, 0x50, 0x01, 0x63, 0x04, 0x03, 0xFA, 0x8F, 0x63, 0x19, 0xCF, 0xD4, 0x84, 0x9E, 0x95, 0xF1, 0x33, 0x79, 0xFA, 0x43, 0x1A, 0x28, 0x8F, 0xD2, 0x30, 0xE8, 0x72 } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_NONE, -1, { 0x74, 0xB2, 0x02, 0x85, 0x8D, 0x1B, 0x9B, 0x11, 0x13, 0xA5, 0x61, 0x5E, 0x20, 0xCD, 0xB4, 0x1C, 0xD6, 0xCA, 0xEE, 0x2D, 0xC1, 0x25, 0xEB, 0x32, 0xAE, 0xA1, 0xA7, 0xC1, 0x89, 0x62, 0x1C, 0x12, 0xD7, 0x46, 0xA2, 0x97, 0x27, 0x68, 0x64, 0xEC, 0xBE, 0xE3, 0x2F, 0xDA, 0x9F, 0x4F, 0x4C, 0xF7, 0xCE, 0x53, 0xD7, 0x03, 0x2B, 0xF9, 0xEC, 0xEB, 0x1D, 0x8D, 0x78, 0x8B, 0xDB, 0x18, 0x88, 0xB3 } }, + { 0, 2, { 0, 1 }, 0, { 0 }, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 0, { 0 }, { 0 }, 2, { { 0x93, 0xDD, 0xE8, 0xC9, 0xCE, 0xE7, 0x14, 0xEB, 0x5B, 0xDF, 0x2B, 0xE0, 0x0F, 0xEC, 0x33, 0x27, 0xF9, 0xCF, 0x38, 0x6D, 0x3A, 0xC6, 0x72, 0xF0, 0xDA, 0x73, 0x4F, 0xFC, 0x08, 0xE7, 0xA0, 0x41 }, { 0x43, 0x68, 0xB9, 0xCD, 0x58, 0x81, 0x50, 0x01, 0x63, 0x04, 0x03, 0xFA, 0x8F, 0x63, 0x19, 0xCF, 0xD4, 0x84, 0x9E, 0x95, 0xF1, 0x33, 0x79, 0xFA, 0x43, 0x1A, 0x28, 0x8F, 0xD2, 0x30, 0xE8, 0x72 } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_NONE, -1, { 0x74, 0xB2, 0x02, 0x85, 0x8D, 0x1B, 0x9B, 0x11, 0x13, 0xA5, 0x61, 0x5E, 0x20, 0xCD, 0xB4, 0x1C, 0xD6, 0xCA, 0xEE, 0x2D, 0xC1, 0x25, 0xEB, 0x32, 0xAE, 0xA1, 0xA7, 0xC1, 0x89, 0x62, 0x1C, 0x12, 0xD7, 0x46, 0xA2, 0x97, 0x27, 0x68, 0x64, 0xEC, 0xBE, 0xE3, 0x2F, 0xDA, 0x9F, 0x4F, 0x4C, 0xF7, 0xCE, 0x53, 0xD7, 0x03, 0x2B, 0xF9, 0xEC, 0xEB, 0x1D, 0x8D, 0x78, 0x8B, 0xDB, 0x18, 0x88, 0xB3 } }, + { 0, 2, { 1, 0 }, 1, { 1, 0 }, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 0, { 0 }, { 0 }, 2, { { 0x43, 0x68, 0xB9, 0xCD, 0x58, 0x81, 0x50, 0x01, 0x63, 0x04, 0x03, 0xFA, 0x8F, 0x63, 0x19, 0xCF, 0xD4, 0x84, 0x9E, 0x95, 0xF1, 0x33, 0x79, 0xFA, 0x43, 0x1A, 0x28, 0x8F, 0xD2, 0x30, 0xE8, 0x72 }, { 0x93, 0xDD, 0xE8, 0xC9, 0xCE, 0xE7, 0x14, 0xEB, 0x5B, 0xDF, 0x2B, 0xE0, 0x0F, 0xEC, 0x33, 0x27, 0xF9, 0xCF, 0x38, 0x6D, 0x3A, 0xC6, 0x72, 0xF0, 0xDA, 0x73, 0x4F, 0xFC, 0x08, 0xE7, 0xA0, 0x41 } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_NONE, -1, { 0x74, 0xB2, 0x02, 0x85, 0x8D, 0x1B, 0x9B, 0x11, 0x13, 0xA5, 0x61, 0x5E, 0x20, 0xCD, 0xB4, 0x1C, 0xD6, 0xCA, 0xEE, 0x2D, 0xC1, 0x25, 0xEB, 0x32, 0xAE, 0xA1, 0xA7, 0xC1, 0x89, 0x62, 0x1C, 0x12, 0xD7, 0x46, 0xA2, 0x97, 0x27, 0x68, 0x64, 0xEC, 0xBE, 0xE3, 0x2F, 0xDA, 0x9F, 0x4F, 0x4C, 0xF7, 0xCE, 0x53, 0xD7, 0x03, 0x2B, 0xF9, 0xEC, 0xEB, 0x1D, 0x8D, 0x78, 0x8B, 0xDB, 0x18, 0x88, 0xB3 } }, + { 0, 2, { 0, 1 }, 1, { 0, 1 }, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 3, { 0, 1, 2 }, { 1, 0, 0 }, 2, { { 0xCC, 0x60, 0xDF, 0xBC, 0xAE, 0xE5, 0x85, 0x93, 0xEF, 0x5A, 0x58, 0xC7, 0x57, 0x62, 0x1F, 0xE8, 0xE6, 0x64, 0x49, 0x25, 0x94, 0x5B, 0x97, 0x35, 0x27, 0x26, 0x8D, 0x64, 0x93, 0xC1, 0xCB, 0x0E }, { 0x6B, 0xF7, 0xAC, 0x27, 0x8E, 0xA8, 0x37, 0x96, 0x03, 0x15, 0x47, 0xBA, 0xA8, 0x13, 0xC4, 0xFB, 0xF2, 0xD7, 0xB2, 0x5B, 0x70, 0xEC, 0x59, 0xDD, 0x46, 0xEC, 0xB8, 0x2C, 0x91, 0x04, 0xA5, 0xB0 } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_NONE, -1, { 0xE2, 0x30, 0x8F, 0x92, 0xDE, 0x70, 0xBC, 0x5F, 0x61, 0x2D, 0x32, 0x9F, 0x69, 0xF1, 0x41, 0xBF, 0x4E, 0x88, 0x67, 0x97, 0xB2, 0x55, 0x39, 0xFC, 0xBD, 0xF3, 0x90, 0x96, 0xB5, 0x3E, 0x0F, 0x08, 0x10, 0x93, 0x77, 0x7B, 0xBF, 0x7D, 0xAF, 0x39, 0xBD, 0x06, 0xD2, 0x99, 0xCB, 0x38, 0x60, 0xD4, 0x3F, 0x64, 0x7F, 0xC3, 0xA3, 0x65, 0x07, 0xE2, 0xA5, 0x70, 0x61, 0xD0, 0x31, 0xF5, 0x69, 0x6E } }, + { 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, { 0x02, 0xCB, 0xC2, 0xE4, 0x1A, 0xF8, 0x72, 0x90, 0xA1, 0x40, 0x1D, 0x49, 0x92, 0x7F, 0xC3, 0x0D, 0x7F, 0x40, 0xA4, 0x04, 0xC4, 0xDF, 0x3E, 0x5F, 0xC7, 0x34, 0x01, 0x41, 0x88, 0xDB, 0xC4, 0x4E, 0x15, 0x03, 0xC1, 0x53, 0x12, 0xED, 0xC6, 0x91, 0xEB, 0x21, 0x3F, 0x3B, 0x8A, 0xAC, 0x19, 0x5D, 0x25, 0x1A, 0x39, 0x05, 0x63, 0xCD, 0x5E, 0x31, 0x3D, 0x73, 0x8A, 0x89, 0xDA, 0xEB, 0x4D, 0xA8, 0x07, 0x46 }, 0, { 0 }, { 0 }, 3, { { 0x01, 0x87, 0xD0, 0x93, 0x00, 0xF2, 0x0F, 0x94, 0x0B, 0x83, 0x7A, 0xA9, 0x3A, 0xB9, 0xF4, 0x86, 0x38, 0x21, 0xC0, 0x44, 0x62, 0x79, 0x31, 0xF4, 0x02, 0xD4, 0xAC, 0xDA, 0x61, 0x8C, 0x0E, 0x15 }, { 0x09, 0x95, 0x5F, 0x6B, 0x6C, 0xF0, 0x9E, 0xD3, 0x83, 0xF3, 0x3C, 0x1B, 0xFC, 0xFE, 0x05, 0x9E, 0x79, 0xE9, 0xD2, 0x6F, 0xEC, 0xC0, 0x09, 0x5F, 0x4A, 0x31, 0xF2, 0x2E, 0x7E, 0xD2, 0x42, 0xAE }, { 0x01, 0x24, 0x50, 0x17, 0x36, 0x74, 0xFA, 0x82, 0xC0, 0x04, 0x8E, 0x8D, 0xA5, 0x89, 0xC4, 0x50, 0xE7, 0x42, 0x46, 0x9C, 0xD2, 0xC8, 0x1A, 0xAA, 0xCE, 0x07, 0x12, 0x97, 0xD9, 0xF1, 0x07, 0x2C } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_NONE, -1, { 0x01, 0x28, 0x03, 0x5A, 0x92, 0x70, 0x9B, 0x87, 0x1A, 0x9E, 0x7C, 0xD6, 0x87, 0x1E, 0x52, 0xB4, 0x75, 0x11, 0x4E, 0xE1, 0x89, 0xD5, 0xE5, 0x6A, 0xC5, 0xB9, 0xE6, 0xEE, 0x86, 0x12, 0x74, 0x69, 0x0C, 0x41, 0x80, 0x15, 0xA4, 0x57, 0xA8, 0xEA, 0x4F, 0x7B, 0x45, 0x52, 0xDD, 0x41, 0xBE, 0x75, 0x99, 0x4D, 0xD9, 0x51, 0x22, 0x01, 0x55, 0xFE, 0x1B, 0x0D, 0xB1, 0xA0, 0xBA, 0x4F, 0x57, 0xEF } }, + { 1, 1, { 0 }, 1, { 0 }, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 0, { 0 }, { 0 }, 1, { { 0xB7, 0xC3, 0xFA, 0x9A, 0xEA, 0x2B, 0x09, 0x89, 0xD1, 0x50, 0xB5, 0x74, 0x33, 0x23, 0x30, 0x15, 0xA2, 0x69, 0xCB, 0x56, 0x23, 0x2B, 0x1D, 0xE2, 0xAF, 0xE5, 0x73, 0x49, 0x1D, 0x96, 0x0B, 0x2C } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_NONE, -1, { 0x3E, 0xA6, 0xA1, 0x92, 0xEC, 0xA9, 0x02, 0x7F, 0x78, 0xFA, 0x53, 0x54, 0xDD, 0xCB, 0x53, 0x15, 0xC8, 0xC2, 0xAB, 0x06, 0x7F, 0x9B, 0xB6, 0x79, 0xD3, 0x6D, 0xF7, 0x0D, 0x4F, 0x78, 0xE3, 0x97, 0xB7, 0xC3, 0xFA, 0x9A, 0xEA, 0x2B, 0x09, 0x89, 0xD1, 0x50, 0xB5, 0x74, 0x33, 0x23, 0x30, 0x15, 0xA2, 0x69, 0xCB, 0x56, 0x23, 0x2B, 0x1D, 0xE2, 0xAF, 0xE5, 0x73, 0x49, 0x1D, 0x96, 0x0B, 0x2C } }, + { 1, 1, { 0 }, 0, { 0 }, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 0, { 0 }, { 0 }, 1, { { 0xB7, 0xC3, 0xFA, 0x9A, 0xEA, 0x2B, 0x09, 0x89, 0xD1, 0x50, 0xB5, 0x74, 0x33, 0x23, 0x30, 0x15, 0xA2, 0x69, 0xCB, 0x56, 0x23, 0x2B, 0x1D, 0xE2, 0xAF, 0xE5, 0x73, 0x49, 0x1D, 0x96, 0x0B, 0x2C } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_NONE, -1, { 0x3E, 0xA6, 0xA1, 0x92, 0xEC, 0xA9, 0x02, 0x7F, 0x78, 0xFA, 0x53, 0x54, 0xDD, 0xCB, 0x53, 0x15, 0xC8, 0xC2, 0xAB, 0x06, 0x7F, 0x9B, 0xB6, 0x79, 0xD3, 0x6D, 0xF7, 0x0D, 0x4F, 0x78, 0xE3, 0x97, 0xB7, 0xC3, 0xFA, 0x9A, 0xEA, 0x2B, 0x09, 0x89, 0xD1, 0x50, 0xB5, 0x74, 0x33, 0x23, 0x30, 0x15, 0xA2, 0x69, 0xCB, 0x56, 0x23, 0x2B, 0x1D, 0xE2, 0xAF, 0xE5, 0x73, 0x49, 0x1D, 0x96, 0x0B, 0x2C } }, + { 1, 1, { 0 }, 1, { 0 }, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 3, { 0, 1, 2 }, { 1, 0, 0 }, 1, { { 0xBB, 0xC0, 0xD3, 0x6C, 0x2F, 0xA7, 0x0A, 0x62, 0xBA, 0x1B, 0x6E, 0x0A, 0x59, 0xFF, 0xB7, 0xC6, 0x2E, 0xE3, 0x66, 0x43, 0xB6, 0xD1, 0x9E, 0x40, 0x18, 0x0A, 0x26, 0x7D, 0xB5, 0xF4, 0x88, 0x69 } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_NONE, -1, { 0x31, 0xC4, 0xE2, 0x6F, 0x6F, 0xF4, 0x8E, 0x6B, 0xF5, 0x8F, 0xFC, 0x7B, 0xCC, 0xB6, 0x42, 0x9B, 0x48, 0xA8, 0x92, 0x6D, 0x38, 0x81, 0x58, 0x58, 0xB4, 0xDA, 0xF9, 0x67, 0x6D, 0x25, 0xC1, 0xED, 0xB3, 0xFA, 0x2D, 0x48, 0xAF, 0xD3, 0xC6, 0x25, 0xE9, 0xD4, 0x95, 0x4A, 0xDA, 0x10, 0x54, 0x4D, 0xA3, 0xA0, 0x35, 0x95, 0x90, 0x26, 0xDA, 0x6E, 0x66, 0x38, 0x83, 0x3B, 0x1C, 0xFF, 0x9C, 0xF8 } }, + { 1, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, { 0x02, 0x77, 0xE7, 0x16, 0x75, 0x6B, 0xAE, 0xFD, 0x92, 0x2D, 0xCD, 0x33, 0x9D, 0x08, 0x3F, 0xEB, 0x1C, 0x02, 0x63, 0xB0, 0x69, 0x99, 0x32, 0x84, 0x92, 0x33, 0x1F, 0xB8, 0x76, 0xA2, 0x25, 0xEE, 0xA3, 0x03, 0x39, 0x10, 0xC4, 0xFC, 0x15, 0x1C, 0x7A, 0xA9, 0x14, 0xB4, 0xD2, 0xAC, 0x97, 0xB3, 0xF0, 0x9C, 0x56, 0xA3, 0x6A, 0x5F, 0x95, 0xF1, 0x40, 0x43, 0xD9, 0x02, 0x10, 0xCC, 0x1F, 0xCD, 0x42, 0x45 }, 0, { 0 }, { 0 }, 3, { { 0xDD, 0x3E, 0xD1, 0xA5, 0xC5, 0xA6, 0xC4, 0x6F, 0x71, 0x5E, 0xB1, 0x5C, 0x5E, 0x10, 0x86, 0x81, 0xB9, 0x93, 0xC6, 0xD4, 0x56, 0xD9, 0x5F, 0x55, 0x77, 0xC1, 0xC0, 0xCF, 0x15, 0x96, 0xD4, 0x39 }, { 0x97, 0xF8, 0xFC, 0x6A, 0x3E, 0xB6, 0x5E, 0x25, 0xF3, 0x85, 0x03, 0x41, 0xB8, 0xD5, 0x88, 0x51, 0x56, 0x4F, 0x12, 0xEF, 0x88, 0xD9, 0x96, 0xC5, 0x39, 0x16, 0xC7, 0x55, 0x78, 0x59, 0x5C, 0xFD }, { 0x70, 0xD2, 0x35, 0x3C, 0x98, 0xAB, 0xF7, 0xAC, 0x47, 0x6B, 0x77, 0x53, 0x7C, 0x52, 0x31, 0xC7, 0x5A, 0x42, 0x96, 0x90, 0x82, 0x6B, 0xE7, 0x11, 0x78, 0x42, 0xA3, 0x77, 0x9B, 0xC5, 0x96, 0xBA } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_NONE, -1, { 0x4C, 0x62, 0x2E, 0x9A, 0x2E, 0x1B, 0x3F, 0x4B, 0xF0, 0x3A, 0x93, 0xA4, 0xB6, 0x2B, 0x15, 0x46, 0xB0, 0xA3, 0x36, 0x96, 0xEC, 0xE1, 0x00, 0x83, 0x30, 0x27, 0x46, 0x09, 0x80, 0x1B, 0x43, 0x9D, 0xE6, 0x0A, 0x03, 0x4C, 0x9D, 0x09, 0x1A, 0x41, 0xAC, 0x4F, 0x2B, 0xF1, 0x93, 0x38, 0x40, 0x9B, 0xAF, 0x76, 0x93, 0x6D, 0xB2, 0xD6, 0x3C, 0xF0, 0x69, 0x48, 0xCD, 0x0F, 0x59, 0x7F, 0x86, 0xAF } }, + { 2, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 0, { 0 }, { 0 }, 3, { { 0x30, 0x5F, 0xE5, 0x09, 0xF0, 0x0F, 0x66, 0x5A, 0xAC, 0x83, 0x6D, 0x1E, 0x49, 0xFF, 0x25, 0x39, 0xD3, 0xA1, 0x1A, 0x9B, 0x20, 0x46, 0x24, 0x57, 0xA4, 0x9E, 0xBE, 0x28, 0xBE, 0xD0, 0x67, 0x28 }, { 0x2C, 0x2D, 0xF9, 0x99, 0x12, 0xA2, 0xEE, 0x3E, 0x69, 0x4F, 0x38, 0x08, 0xAF, 0xA1, 0x4B, 0x15, 0xC9, 0x90, 0xAF, 0x29, 0x62, 0x1B, 0x33, 0x85, 0x0A, 0xC1, 0xE2, 0x3D, 0x08, 0xB8, 0x4C, 0x18 }, { 0xAD, 0xEC, 0x5E, 0x2C, 0x1F, 0xBA, 0x9B, 0x5E, 0x02, 0x8B, 0xF4, 0xBA, 0x0E, 0xAA, 0x3F, 0x41, 0x68, 0x3D, 0x1B, 0xE2, 0x6F, 0x20, 0xD4, 0x84, 0x2C, 0xD8, 0x65, 0x03, 0x1B, 0x0F, 0x1F, 0x91 } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_NONE, -1, { 0x38, 0x6D, 0xC4, 0x54, 0x6A, 0x4F, 0xB1, 0xD7, 0x9F, 0xE9, 0xC4, 0x0C, 0x06, 0x48, 0x8D, 0xD2, 0x71, 0xEF, 0x54, 0x13, 0x25, 0xE4, 0x92, 0x64, 0x37, 0x94, 0x41, 0x3E, 0xAD, 0xFA, 0x28, 0x0C, 0x0A, 0x7A, 0x3C, 0xCF, 0x22, 0x6C, 0xEF, 0xF7, 0x18, 0x5E, 0x99, 0xE1, 0x08, 0x4A, 0xAF, 0x92, 0x4A, 0xC0, 0x08, 0xC0, 0x42, 0x39, 0x8C, 0x25, 0x1C, 0x66, 0xA6, 0xDC, 0x12, 0x61, 0x91, 0x90 } }, + { 2, 3, { 0, 1, 2 }, 0, { 0 }, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 0, { 0 }, { 0 }, 3, { { 0x30, 0x5F, 0xE5, 0x09, 0xF0, 0x0F, 0x66, 0x5A, 0xAC, 0x83, 0x6D, 0x1E, 0x49, 0xFF, 0x25, 0x39, 0xD3, 0xA1, 0x1A, 0x9B, 0x20, 0x46, 0x24, 0x57, 0xA4, 0x9E, 0xBE, 0x28, 0xBE, 0xD0, 0x67, 0x28 }, { 0x2C, 0x2D, 0xF9, 0x99, 0x12, 0xA2, 0xEE, 0x3E, 0x69, 0x4F, 0x38, 0x08, 0xAF, 0xA1, 0x4B, 0x15, 0xC9, 0x90, 0xAF, 0x29, 0x62, 0x1B, 0x33, 0x85, 0x0A, 0xC1, 0xE2, 0x3D, 0x08, 0xB8, 0x4C, 0x18 }, { 0xAD, 0xEC, 0x5E, 0x2C, 0x1F, 0xBA, 0x9B, 0x5E, 0x02, 0x8B, 0xF4, 0xBA, 0x0E, 0xAA, 0x3F, 0x41, 0x68, 0x3D, 0x1B, 0xE2, 0x6F, 0x20, 0xD4, 0x84, 0x2C, 0xD8, 0x65, 0x03, 0x1B, 0x0F, 0x1F, 0x91 } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_NONE, -1, { 0x38, 0x6D, 0xC4, 0x54, 0x6A, 0x4F, 0xB1, 0xD7, 0x9F, 0xE9, 0xC4, 0x0C, 0x06, 0x48, 0x8D, 0xD2, 0x71, 0xEF, 0x54, 0x13, 0x25, 0xE4, 0x92, 0x64, 0x37, 0x94, 0x41, 0x3E, 0xAD, 0xFA, 0x28, 0x0C, 0x0A, 0x7A, 0x3C, 0xCF, 0x22, 0x6C, 0xEF, 0xF7, 0x18, 0x5E, 0x99, 0xE1, 0x08, 0x4A, 0xAF, 0x92, 0x4A, 0xC0, 0x08, 0xC0, 0x42, 0x39, 0x8C, 0x25, 0x1C, 0x66, 0xA6, 0xDC, 0x12, 0x61, 0x91, 0x90 } }, + { 2, 3, { 2, 1, 0 }, 1, { 2, 1, 0 }, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 0, { 0 }, { 0 }, 3, { { 0xAD, 0xEC, 0x5E, 0x2C, 0x1F, 0xBA, 0x9B, 0x5E, 0x02, 0x8B, 0xF4, 0xBA, 0x0E, 0xAA, 0x3F, 0x41, 0x68, 0x3D, 0x1B, 0xE2, 0x6F, 0x20, 0xD4, 0x84, 0x2C, 0xD8, 0x65, 0x03, 0x1B, 0x0F, 0x1F, 0x91 }, { 0x2C, 0x2D, 0xF9, 0x99, 0x12, 0xA2, 0xEE, 0x3E, 0x69, 0x4F, 0x38, 0x08, 0xAF, 0xA1, 0x4B, 0x15, 0xC9, 0x90, 0xAF, 0x29, 0x62, 0x1B, 0x33, 0x85, 0x0A, 0xC1, 0xE2, 0x3D, 0x08, 0xB8, 0x4C, 0x18 }, { 0x30, 0x5F, 0xE5, 0x09, 0xF0, 0x0F, 0x66, 0x5A, 0xAC, 0x83, 0x6D, 0x1E, 0x49, 0xFF, 0x25, 0x39, 0xD3, 0xA1, 0x1A, 0x9B, 0x20, 0x46, 0x24, 0x57, 0xA4, 0x9E, 0xBE, 0x28, 0xBE, 0xD0, 0x67, 0x28 } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_NONE, -1, { 0x38, 0x6D, 0xC4, 0x54, 0x6A, 0x4F, 0xB1, 0xD7, 0x9F, 0xE9, 0xC4, 0x0C, 0x06, 0x48, 0x8D, 0xD2, 0x71, 0xEF, 0x54, 0x13, 0x25, 0xE4, 0x92, 0x64, 0x37, 0x94, 0x41, 0x3E, 0xAD, 0xFA, 0x28, 0x0C, 0x0A, 0x7A, 0x3C, 0xCF, 0x22, 0x6C, 0xEF, 0xF7, 0x18, 0x5E, 0x99, 0xE1, 0x08, 0x4A, 0xAF, 0x92, 0x4A, 0xC0, 0x08, 0xC0, 0x42, 0x39, 0x8C, 0x25, 0x1C, 0x66, 0xA6, 0xDC, 0x12, 0x61, 0x91, 0x90 } }, + { 2, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 3, { 0, 1, 2 }, { 1, 0, 0 }, 3, { { 0xE6, 0xDD, 0x42, 0x6B, 0x51, 0xE8, 0xCD, 0x40, 0xC1, 0x73, 0x17, 0x14, 0x02, 0x84, 0x97, 0x17, 0x4E, 0xD2, 0x4C, 0x3F, 0xFD, 0x8D, 0xD4, 0x29, 0x77, 0xBC, 0x90, 0x9C, 0x4E, 0xB9, 0xCB, 0xA6 }, { 0xA3, 0xC2, 0xB9, 0x91, 0x4E, 0x16, 0xCC, 0x92, 0x3D, 0x88, 0xFC, 0x56, 0xA5, 0x7A, 0x81, 0xAD, 0xAE, 0x61, 0x5E, 0xAB, 0xF0, 0xAA, 0x39, 0x30, 0x10, 0xFD, 0x6A, 0x08, 0x12, 0x08, 0xAA, 0xDE }, { 0xEE, 0x2A, 0xE7, 0x6E, 0xA4, 0xBC, 0x9D, 0x29, 0x18, 0x32, 0xD8, 0x4D, 0x9E, 0x81, 0xC3, 0xB1, 0x19, 0x86, 0xE0, 0x2C, 0xF3, 0x26, 0xE9, 0xCE, 0x4E, 0xEB, 0xF7, 0x72, 0xB4, 0x6E, 0x1E, 0xAB } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_NONE, -1, { 0x9E, 0x22, 0x5C, 0x55, 0x17, 0x91, 0xD8, 0x19, 0xF7, 0x57, 0xC1, 0xD0, 0x7A, 0x9A, 0x48, 0x88, 0xD3, 0xAD, 0x05, 0x1E, 0x11, 0x65, 0x48, 0xA3, 0xC0, 0x21, 0xBA, 0x59, 0x0D, 0xB1, 0x85, 0x58, 0x2B, 0xFD, 0x18, 0xA0, 0xDF, 0xF9, 0xAD, 0x81, 0x37, 0xCA, 0x33, 0xBB, 0x8C, 0xBD, 0xD9, 0x53, 0x4B, 0xE7, 0xDA, 0x7F, 0x03, 0x92, 0x9B, 0xB1, 0x0A, 0x91, 0x3F, 0xD8, 0x15, 0x46, 0x78, 0x61 } }, + { 3, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 0, { 0 }, { 0 }, 3, { { 0x60, 0x3E, 0xC1, 0xEA, 0x86, 0xB2, 0x84, 0xE2, 0x8C, 0xEF, 0xD5, 0x9C, 0x85, 0xF8, 0xDD, 0xC6, 0xDF, 0xE8, 0x1C, 0x07, 0x44, 0xF5, 0x9D, 0x8F, 0xB5, 0xBE, 0xB2, 0x9F, 0x1C, 0x27, 0xF3, 0x8B }, { 0x0E, 0x1C, 0xB1, 0xC6, 0xB7, 0x58, 0x47, 0xD6, 0x2D, 0x7D, 0xE2, 0x9D, 0xA5, 0xB6, 0x1E, 0x66, 0x38, 0x6F, 0x51, 0x2C, 0x1B, 0xFF, 0xD1, 0x2C, 0x20, 0x2D, 0x2D, 0x28, 0xD5, 0x45, 0x53, 0x14 }, { 0xB3, 0x89, 0x0F, 0x87, 0x99, 0x33, 0x10, 0xB2, 0xAE, 0x08, 0x87, 0xE0, 0xC8, 0xD5, 0x1C, 0xD2, 0x78, 0x98, 0xA7, 0x13, 0xFF, 0x48, 0xC2, 0x19, 0x7D, 0x28, 0x0B, 0xDA, 0x31, 0x3A, 0x4A, 0x2C } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_NONE, -1, { 0x2A, 0xCE, 0xEC, 0x78, 0xD4, 0x76, 0xDB, 0x0C, 0x70, 0x00, 0xD5, 0x48, 0xB0, 0x10, 0x02, 0x3B, 0xCD, 0x9E, 0x54, 0x00, 0x8B, 0x96, 0x61, 0x47, 0xA2, 0x32, 0x00, 0x3D, 0xA9, 0x1A, 0xA7, 0x90, 0x21, 0xE4, 0x83, 0x38, 0xD7, 0x3D, 0xDD, 0x6B, 0x68, 0x76, 0x40, 0x1A, 0xF4, 0x84, 0x19, 0x00, 0xD6, 0x41, 0x37, 0x60, 0xB0, 0xF5, 0x90, 0x99, 0x93, 0x41, 0x8D, 0x15, 0x52, 0x71, 0x4F, 0x8A } }, + { 3, 3, { 0, 1, 2 }, 0, { 0 }, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 0, { 0 }, { 0 }, 3, { { 0x60, 0x3E, 0xC1, 0xEA, 0x86, 0xB2, 0x84, 0xE2, 0x8C, 0xEF, 0xD5, 0x9C, 0x85, 0xF8, 0xDD, 0xC6, 0xDF, 0xE8, 0x1C, 0x07, 0x44, 0xF5, 0x9D, 0x8F, 0xB5, 0xBE, 0xB2, 0x9F, 0x1C, 0x27, 0xF3, 0x8B }, { 0x0E, 0x1C, 0xB1, 0xC6, 0xB7, 0x58, 0x47, 0xD6, 0x2D, 0x7D, 0xE2, 0x9D, 0xA5, 0xB6, 0x1E, 0x66, 0x38, 0x6F, 0x51, 0x2C, 0x1B, 0xFF, 0xD1, 0x2C, 0x20, 0x2D, 0x2D, 0x28, 0xD5, 0x45, 0x53, 0x14 }, { 0xB3, 0x89, 0x0F, 0x87, 0x99, 0x33, 0x10, 0xB2, 0xAE, 0x08, 0x87, 0xE0, 0xC8, 0xD5, 0x1C, 0xD2, 0x78, 0x98, 0xA7, 0x13, 0xFF, 0x48, 0xC2, 0x19, 0x7D, 0x28, 0x0B, 0xDA, 0x31, 0x3A, 0x4A, 0x2C } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_NONE, -1, { 0x2A, 0xCE, 0xEC, 0x78, 0xD4, 0x76, 0xDB, 0x0C, 0x70, 0x00, 0xD5, 0x48, 0xB0, 0x10, 0x02, 0x3B, 0xCD, 0x9E, 0x54, 0x00, 0x8B, 0x96, 0x61, 0x47, 0xA2, 0x32, 0x00, 0x3D, 0xA9, 0x1A, 0xA7, 0x90, 0x21, 0xE4, 0x83, 0x38, 0xD7, 0x3D, 0xDD, 0x6B, 0x68, 0x76, 0x40, 0x1A, 0xF4, 0x84, 0x19, 0x00, 0xD6, 0x41, 0x37, 0x60, 0xB0, 0xF5, 0x90, 0x99, 0x93, 0x41, 0x8D, 0x15, 0x52, 0x71, 0x4F, 0x8A } }, + { 3, 3, { 2, 1, 0 }, 1, { 2, 1, 0 }, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 0, { 0 }, { 0 }, 3, { { 0xB3, 0x89, 0x0F, 0x87, 0x99, 0x33, 0x10, 0xB2, 0xAE, 0x08, 0x87, 0xE0, 0xC8, 0xD5, 0x1C, 0xD2, 0x78, 0x98, 0xA7, 0x13, 0xFF, 0x48, 0xC2, 0x19, 0x7D, 0x28, 0x0B, 0xDA, 0x31, 0x3A, 0x4A, 0x2C }, { 0x0E, 0x1C, 0xB1, 0xC6, 0xB7, 0x58, 0x47, 0xD6, 0x2D, 0x7D, 0xE2, 0x9D, 0xA5, 0xB6, 0x1E, 0x66, 0x38, 0x6F, 0x51, 0x2C, 0x1B, 0xFF, 0xD1, 0x2C, 0x20, 0x2D, 0x2D, 0x28, 0xD5, 0x45, 0x53, 0x14 }, { 0x60, 0x3E, 0xC1, 0xEA, 0x86, 0xB2, 0x84, 0xE2, 0x8C, 0xEF, 0xD5, 0x9C, 0x85, 0xF8, 0xDD, 0xC6, 0xDF, 0xE8, 0x1C, 0x07, 0x44, 0xF5, 0x9D, 0x8F, 0xB5, 0xBE, 0xB2, 0x9F, 0x1C, 0x27, 0xF3, 0x8B } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_NONE, -1, { 0x2A, 0xCE, 0xEC, 0x78, 0xD4, 0x76, 0xDB, 0x0C, 0x70, 0x00, 0xD5, 0x48, 0xB0, 0x10, 0x02, 0x3B, 0xCD, 0x9E, 0x54, 0x00, 0x8B, 0x96, 0x61, 0x47, 0xA2, 0x32, 0x00, 0x3D, 0xA9, 0x1A, 0xA7, 0x90, 0x21, 0xE4, 0x83, 0x38, 0xD7, 0x3D, 0xDD, 0x6B, 0x68, 0x76, 0x40, 0x1A, 0xF4, 0x84, 0x19, 0x00, 0xD6, 0x41, 0x37, 0x60, 0xB0, 0xF5, 0x90, 0x99, 0x93, 0x41, 0x8D, 0x15, 0x52, 0x71, 0x4F, 0x8A } }, + { 3, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 3, { 0, 1, 2 }, { 1, 0, 0 }, 3, { { 0xF7, 0xAD, 0x2F, 0x8D, 0xAC, 0xC5, 0xD2, 0x2A, 0x0F, 0x68, 0x00, 0x7B, 0xB0, 0xAA, 0x3D, 0x65, 0x55, 0xF2, 0x29, 0xAA, 0x3E, 0x3E, 0xE3, 0xD5, 0x8E, 0xCA, 0x5A, 0xB5, 0xDE, 0xE1, 0xEC, 0x61 }, { 0x29, 0x6C, 0x56, 0x1E, 0xDB, 0x37, 0xE9, 0xDD, 0x75, 0x01, 0x90, 0xB5, 0x26, 0xFD, 0x96, 0xF3, 0xEE, 0xA3, 0x62, 0xCF, 0xF3, 0xDE, 0xEA, 0x61, 0x46, 0x97, 0xAB, 0xE2, 0x96, 0x3C, 0xF4, 0xE0 }, { 0x83, 0xF2, 0x30, 0x6C, 0xD2, 0x1A, 0x2F, 0x00, 0x38, 0x17, 0x25, 0x8B, 0x4D, 0x33, 0x90, 0x47, 0x71, 0xAA, 0x22, 0x9A, 0xED, 0x02, 0x26, 0xA7, 0x27, 0x39, 0xE8, 0xEF, 0x2B, 0xDD, 0x7B, 0xF3 } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_NONE, -1, { 0x75, 0x22, 0x0B, 0x52, 0xF1, 0xBD, 0x90, 0x6E, 0x43, 0x14, 0x71, 0x3F, 0x2D, 0xF1, 0x89, 0xB5, 0x2F, 0xEC, 0x6A, 0x33, 0x3F, 0x42, 0x50, 0x5D, 0x1F, 0x1C, 0x2A, 0x65, 0xEF, 0x3E, 0xD4, 0x7A, 0x17, 0x36, 0x0A, 0xAD, 0xFD, 0x3F, 0xFC, 0xE1, 0xE8, 0x90, 0x52, 0x42, 0x09, 0x36, 0xB4, 0x99, 0x1B, 0x2F, 0xD0, 0xE2, 0x0F, 0x7D, 0x5F, 0xF7, 0x11, 0x52, 0x31, 0xFB, 0xDB, 0x2E, 0x76, 0x7D } }, + { 3, 5, { 0, 1, 2, 3, 4 }, 1, { 0, 1, 2, 3, 4 }, { 0x03, 0x53, 0x60, 0x24, 0xF2, 0x1D, 0x3C, 0x18, 0xE0, 0xF0, 0x94, 0xD1, 0x5E, 0x9D, 0xDA, 0x07, 0x74, 0x07, 0x54, 0x90, 0x55, 0x70, 0xA1, 0xB6, 0x8C, 0xAF, 0xAC, 0x74, 0x3A, 0x6C, 0x21, 0x37, 0x45, 0x03, 0x7C, 0x9E, 0xA6, 0x73, 0x0C, 0xD2, 0x19, 0x04, 0xC1, 0x31, 0xFF, 0x4A, 0x6C, 0x62, 0x48, 0x0A, 0x7B, 0xAB, 0xAA, 0x75, 0xF0, 0xA4, 0xF6, 0x3F, 0x1A, 0xFD, 0x8D, 0xEE, 0x9F, 0xDD, 0x69, 0x9D }, 0, { 0 }, { 0 }, 5, { { 0xB6, 0x65, 0x46, 0x71, 0x00, 0xED, 0xB9, 0x35, 0x40, 0x41, 0xCD, 0xC8, 0xDF, 0x97, 0xCE, 0x74, 0xF0, 0x8D, 0xDA, 0x67, 0x57, 0xDF, 0x8D, 0x0A, 0xF5, 0x4D, 0x65, 0x02, 0xB9, 0x21, 0x55, 0x95 }, { 0x5D, 0x70, 0xB8, 0xD3, 0x7B, 0xF0, 0xDB, 0x38, 0x1C, 0xE1, 0x5E, 0x3A, 0xAB, 0x9F, 0x59, 0xBE, 0xCD, 0x54, 0xAD, 0x32, 0xAC, 0x19, 0xA2, 0x16, 0x09, 0x38, 0x81, 0xB8, 0xF6, 0x45, 0x8B, 0xB6 }, { 0x5C, 0xB1, 0x37, 0xBB, 0xB9, 0xB2, 0x41, 0x56, 0xB7, 0xDB, 0xD5, 0x33, 0x77, 0xDC, 0x35, 0x93, 0x57, 0xEB, 0x39, 0xA4, 0x73, 0xB4, 0xCC, 0x7D, 0xD1, 0xE5, 0x24, 0x24, 0x0B, 0xEB, 0xBF, 0xA6 }, { 0xE4, 0x7D, 0x93, 0x84, 0xAD, 0x76, 0x1C, 0x64, 0x09, 0x27, 0x2A, 0xAB, 0x2E, 0x71, 0xF9, 0x70, 0x01, 0xF4, 0xB7, 0x0E, 0x25, 0x64, 0x04, 0xA9, 0x7A, 0xC6, 0x45, 0xB3, 0x68, 0xE0, 0x0E, 0xA9 }, { 0xBD, 0x1E, 0x4B, 0x20, 0x98, 0x97, 0xC8, 0x47, 0xED, 0xD8, 0xE0, 0xDF, 0x6C, 0x46, 0xC8, 0x8D, 0xC4, 0xCD, 0xAF, 0xA1, 0xC4, 0x02, 0x11, 0x32, 0xE3, 0x1C, 0xE5, 0xDC, 0x51, 0xDC, 0x78, 0x9E } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_NONE, -1, { 0xC2, 0x6D, 0x81, 0xCC, 0x4C, 0x70, 0x3A, 0x46, 0xA3, 0xFE, 0x3B, 0x6E, 0x3F, 0xE8, 0x84, 0xFB, 0x90, 0x83, 0x48, 0xF4, 0x62, 0xDB, 0x73, 0x68, 0xC4, 0xA7, 0x54, 0xBD, 0xB6, 0x62, 0xC4, 0xDE, 0x12, 0x23, 0x15, 0xA5, 0x7C, 0x9E, 0xBA, 0x70, 0x0B, 0xFF, 0x0C, 0xC1, 0x9D, 0xCC, 0x1F, 0xC8, 0xAC, 0x83, 0x91, 0x3A, 0x53, 0x3A, 0x30, 0xC7, 0xEE, 0xD7, 0x1A, 0xC9, 0x05, 0x6C, 0x64, 0x75 } }, +}; +static const struct frost_vec_sig_agg_case frost_vec_sig_agg_error_cases[8] = { + { 0, 2, { 0, 1 }, 1, { 0, 1 }, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 0, { 0 }, { 0 }, 2, { { 0x93, 0xDD, 0xE8, 0xC9, 0xCE, 0xE7, 0x14, 0xEB, 0x5B, 0xDF, 0x2B, 0xE0, 0x0F, 0xEC, 0x33, 0x27, 0xF9, 0xCF, 0x38, 0x6D, 0x3A, 0xC6, 0x72, 0xF0, 0xDA, 0x73, 0x4F, 0xFC, 0x08, 0xE7, 0xA0, 0x41 }, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_PSIG_PARSE, 1, { 0 } }, + { 0, 2, { 0, 1 }, 1, { 0, 1 }, { 0x03, 0x0F, 0x26, 0x1B, 0xFE, 0x5D, 0xF0, 0xAE, 0x3E, 0xC0, 0x6B, 0xB7, 0xA1, 0xD6, 0x39, 0x4A, 0x3A, 0xF2, 0x06, 0x96, 0x82, 0x81, 0xF0, 0x3B, 0x70, 0xD2, 0x5F, 0xB8, 0x4D, 0x49, 0x03, 0x6C, 0xE2, 0x03, 0xBE, 0x48, 0x27, 0x76, 0x30, 0x57, 0x9C, 0x72, 0x16, 0x04, 0x30, 0xC8, 0x19, 0xAA, 0xBB, 0x1D, 0xFA, 0x20, 0xFF, 0x70, 0x74, 0x96, 0x66, 0x08, 0x0B, 0xB8, 0x86, 0xB7, 0x28, 0x47, 0x62, 0x61 }, 0, { 0 }, { 0 }, 1, { { 0x93, 0xDD, 0xE8, 0xC9, 0xCE, 0xE7, 0x14, 0xEB, 0x5B, 0xDF, 0x2B, 0xE0, 0x0F, 0xEC, 0x33, 0x27, 0xF9, 0xCF, 0x38, 0x6D, 0x3A, 0xC6, 0x72, 0xF0, 0xDA, 0x73, 0x4F, 0xFC, 0x08, 0xE7, 0xA0, 0x41 } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_AGG_LEN, -1, { 0 } }, + { 1, 1, { 0 }, 1, { 0 }, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 0, { 0 }, { 0 }, 1, { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_PSIG_PARSE, 0, { 0 } }, + { 1, 1, { 0 }, 1, { 0 }, { 0x02, 0x68, 0x05, 0xDC, 0x7B, 0x31, 0x8F, 0x79, 0x6C, 0x36, 0x0B, 0xB8, 0x2F, 0x85, 0xFA, 0x0C, 0x10, 0x6A, 0xB8, 0x77, 0x5F, 0xEC, 0xF8, 0x92, 0xA0, 0xA7, 0xF8, 0x5F, 0xB6, 0x67, 0x20, 0xCB, 0xAB, 0x03, 0x95, 0x09, 0xCF, 0x07, 0xC0, 0xA7, 0x87, 0xAB, 0x86, 0x28, 0xC8, 0x4E, 0x1F, 0x6F, 0x5E, 0x9C, 0xA4, 0x24, 0x49, 0x6D, 0x6E, 0xD4, 0xAC, 0x36, 0x72, 0x2E, 0x56, 0x02, 0xE0, 0xC3, 0x2C, 0x57 }, 0, { 0 }, { 0 }, 0, { { 0 } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_AGG_LEN, -1, { 0 } }, + { 2, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 0, { 0 }, { 0 }, 3, { { 0x30, 0x5F, 0xE5, 0x09, 0xF0, 0x0F, 0x66, 0x5A, 0xAC, 0x83, 0x6D, 0x1E, 0x49, 0xFF, 0x25, 0x39, 0xD3, 0xA1, 0x1A, 0x9B, 0x20, 0x46, 0x24, 0x57, 0xA4, 0x9E, 0xBE, 0x28, 0xBE, 0xD0, 0x67, 0x28 }, { 0x2C, 0x2D, 0xF9, 0x99, 0x12, 0xA2, 0xEE, 0x3E, 0x69, 0x4F, 0x38, 0x08, 0xAF, 0xA1, 0x4B, 0x15, 0xC9, 0x90, 0xAF, 0x29, 0x62, 0x1B, 0x33, 0x85, 0x0A, 0xC1, 0xE2, 0x3D, 0x08, 0xB8, 0x4C, 0x18 }, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_PSIG_PARSE, 2, { 0 } }, + { 2, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, { 0x03, 0x0C, 0xC8, 0xDD, 0x78, 0x11, 0x03, 0x34, 0x74, 0xFA, 0xD5, 0x7D, 0x2D, 0xD0, 0x38, 0x01, 0x58, 0x4E, 0xD6, 0xA6, 0x8C, 0xD1, 0xA7, 0x3B, 0x33, 0x01, 0xC3, 0xDD, 0x1F, 0x68, 0x5B, 0xBF, 0x78, 0x02, 0xDE, 0x92, 0x50, 0xBD, 0xBE, 0xF7, 0x4C, 0x5E, 0xC1, 0x85, 0x4A, 0x17, 0x1E, 0xC8, 0xF5, 0xBD, 0x06, 0xCB, 0xDD, 0xCF, 0xB7, 0x83, 0x84, 0x43, 0x5A, 0xC6, 0x2E, 0x5B, 0x35, 0x9A, 0xCF, 0x2C }, 0, { 0 }, { 0 }, 2, { { 0x30, 0x5F, 0xE5, 0x09, 0xF0, 0x0F, 0x66, 0x5A, 0xAC, 0x83, 0x6D, 0x1E, 0x49, 0xFF, 0x25, 0x39, 0xD3, 0xA1, 0x1A, 0x9B, 0x20, 0x46, 0x24, 0x57, 0xA4, 0x9E, 0xBE, 0x28, 0xBE, 0xD0, 0x67, 0x28 }, { 0x2C, 0x2D, 0xF9, 0x99, 0x12, 0xA2, 0xEE, 0x3E, 0x69, 0x4F, 0x38, 0x08, 0xAF, 0xA1, 0x4B, 0x15, 0xC9, 0x90, 0xAF, 0x29, 0x62, 0x1B, 0x33, 0x85, 0x0A, 0xC1, 0xE2, 0x3D, 0x08, 0xB8, 0x4C, 0x18 } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_AGG_LEN, -1, { 0 } }, + { 3, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 0, { 0 }, { 0 }, 3, { { 0x60, 0x3E, 0xC1, 0xEA, 0x86, 0xB2, 0x84, 0xE2, 0x8C, 0xEF, 0xD5, 0x9C, 0x85, 0xF8, 0xDD, 0xC6, 0xDF, 0xE8, 0x1C, 0x07, 0x44, 0xF5, 0x9D, 0x8F, 0xB5, 0xBE, 0xB2, 0x9F, 0x1C, 0x27, 0xF3, 0x8B }, { 0x0E, 0x1C, 0xB1, 0xC6, 0xB7, 0x58, 0x47, 0xD6, 0x2D, 0x7D, 0xE2, 0x9D, 0xA5, 0xB6, 0x1E, 0x66, 0x38, 0x6F, 0x51, 0x2C, 0x1B, 0xFF, 0xD1, 0x2C, 0x20, 0x2D, 0x2D, 0x28, 0xD5, 0x45, 0x53, 0x14 }, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_PSIG_PARSE, 2, { 0 } }, + { 3, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, { 0x03, 0x91, 0xD5, 0x2F, 0x65, 0x6B, 0x3C, 0xA3, 0xE6, 0x6A, 0xC5, 0xDA, 0xEF, 0x5B, 0x0D, 0x34, 0x7F, 0x7E, 0x85, 0xB7, 0xDD, 0x7A, 0x9E, 0xBA, 0x10, 0xE9, 0x82, 0x7A, 0xE2, 0x3F, 0xB7, 0x6E, 0x93, 0x03, 0x16, 0x10, 0xE1, 0x84, 0xE5, 0x40, 0x47, 0x01, 0x39, 0xF7, 0x62, 0x62, 0x53, 0xF2, 0x7E, 0x88, 0x71, 0xD6, 0x35, 0x49, 0x41, 0xCC, 0x9F, 0xF9, 0x4A, 0x07, 0xD8, 0x3F, 0x61, 0xBB, 0x4C, 0xD5 }, 0, { 0 }, { 0 }, 2, { { 0x60, 0x3E, 0xC1, 0xEA, 0x86, 0xB2, 0x84, 0xE2, 0x8C, 0xEF, 0xD5, 0x9C, 0x85, 0xF8, 0xDD, 0xC6, 0xDF, 0xE8, 0x1C, 0x07, 0x44, 0xF5, 0x9D, 0x8F, 0xB5, 0xBE, 0xB2, 0x9F, 0x1C, 0x27, 0xF3, 0x8B }, { 0x0E, 0x1C, 0xB1, 0xC6, 0xB7, 0x58, 0x47, 0xD6, 0x2D, 0x7D, 0xE2, 0x9D, 0xA5, 0xB6, 0x1E, 0x66, 0x38, 0x6F, 0x51, 0x2C, 0x1B, 0xFF, 0xD1, 0x2C, 0x20, 0x2D, 0x2D, 0x28, 0xD5, 0x45, 0x53, 0x14 } }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, FROST_VEC_ERR_AGG_LEN, -1, { 0 } }, +}; +static const struct frost_vec_group frost_vec_det_sign_groups[4] = { + { 2, 3, { 0x02, 0xD7, 0x72, 0xA0, 0x9F, 0x5F, 0x67, 0x57, 0x83, 0xD2, 0x75, 0xED, 0x9F, 0x6A, 0xAE, 0xDB, 0x2E, 0xCC, 0xBC, 0x74, 0x17, 0x1B, 0x37, 0xAC, 0x23, 0xAE, 0x3B, 0xBD, 0x9D, 0x7A, 0xE2, 0xCD, 0xAA }, 5, { + { 0x03, 0x9E, 0xE3, 0x33, 0x5A, 0xF4, 0x8D, 0xFE, 0x23, 0x70, 0x2A, 0xB3, 0x53, 0xF4, 0xAF, 0x20, 0xD4, 0x01, 0xF6, 0x7A, 0x13, 0x0D, 0xF7, 0x83, 0xCC, 0x84, 0x57, 0x32, 0x3A, 0x86, 0x0A, 0x2F, 0xB4 }, + { 0x02, 0x84, 0xDC, 0x4A, 0xB2, 0xCB, 0x78, 0xA6, 0x21, 0xEB, 0x87, 0xFA, 0x1F, 0x14, 0xBC, 0xE2, 0xB7, 0x25, 0xAF, 0xEA, 0xAC, 0x98, 0x1A, 0xDC, 0xBA, 0xFF, 0x5C, 0xC2, 0xD4, 0x17, 0xD2, 0xA6, 0x3A }, + { 0x03, 0x64, 0x41, 0xEC, 0x2D, 0x4C, 0x12, 0x66, 0x20, 0x1C, 0xD8, 0x9B, 0x69, 0x54, 0x9A, 0x2F, 0x5B, 0x21, 0x88, 0x61, 0x2A, 0x0D, 0x43, 0x41, 0x53, 0xE6, 0x25, 0xFB, 0x38, 0x17, 0x3D, 0xD5, 0x09 }, + { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07 }, + { 0x02, 0xA5, 0x36, 0x3A, 0x09, 0x93, 0xE3, 0xE2, 0x09, 0x6E, 0xF8, 0x0B, 0x7B, 0x4D, 0xA1, 0xED, 0xF6, 0x50, 0xDB, 0xF0, 0x2C, 0xAE, 0x16, 0x8B, 0xB4, 0xAC, 0xC0, 0xE9, 0x0A, 0x24, 0xCE, 0xD0, 0xFD } + }, 4, { + { 0x53, 0x44, 0x2F, 0xA9, 0xBD, 0x72, 0xEE, 0xA0, 0xA4, 0x2D, 0xF6, 0xF2, 0xD2, 0xD7, 0x6A, 0x2C, 0x0D, 0x3A, 0x3D, 0xFA, 0x2B, 0xE2, 0xF8, 0x20, 0xF4, 0x1A, 0xDE, 0x97, 0x6B, 0x82, 0x59, 0xFB }, + { 0x5A, 0x7F, 0x9B, 0xD4, 0x1F, 0x4B, 0x54, 0x46, 0x64, 0xC5, 0x4D, 0x77, 0x7D, 0x43, 0x30, 0x3C, 0xB5, 0x30, 0x24, 0x34, 0xF9, 0x90, 0x3B, 0x9B, 0x55, 0x2C, 0x4E, 0x55, 0x2B, 0xF0, 0x22, 0x01 }, + { 0x61, 0xBB, 0x07, 0xFE, 0x81, 0x23, 0xB9, 0xEC, 0x25, 0x5C, 0xA3, 0xFC, 0x27, 0xAE, 0xF6, 0x4D, 0x5D, 0x26, 0x0A, 0x6F, 0xC7, 0x3D, 0x7F, 0x15, 0xB6, 0x3D, 0xBE, 0x12, 0xEC, 0x5D, 0xEA, 0x07 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, 0, {}, 0, {}, 0, {} }, + { 1, 3, { 0x03, 0xD1, 0x93, 0x9B, 0xE8, 0x7D, 0x18, 0xEA, 0x5A, 0xB3, 0x02, 0xE2, 0x70, 0x77, 0xD1, 0x6B, 0x2C, 0x2F, 0xD9, 0x35, 0x16, 0xF9, 0x15, 0x14, 0xBA, 0x04, 0x99, 0x33, 0xD3, 0x48, 0xDA, 0x44, 0x1F }, 5, { + { 0x03, 0xD1, 0x93, 0x9B, 0xE8, 0x7D, 0x18, 0xEA, 0x5A, 0xB3, 0x02, 0xE2, 0x70, 0x77, 0xD1, 0x6B, 0x2C, 0x2F, 0xD9, 0x35, 0x16, 0xF9, 0x15, 0x14, 0xBA, 0x04, 0x99, 0x33, 0xD3, 0x48, 0xDA, 0x44, 0x1F }, + { 0x03, 0xD1, 0x93, 0x9B, 0xE8, 0x7D, 0x18, 0xEA, 0x5A, 0xB3, 0x02, 0xE2, 0x70, 0x77, 0xD1, 0x6B, 0x2C, 0x2F, 0xD9, 0x35, 0x16, 0xF9, 0x15, 0x14, 0xBA, 0x04, 0x99, 0x33, 0xD3, 0x48, 0xDA, 0x44, 0x1F }, + { 0x03, 0xD1, 0x93, 0x9B, 0xE8, 0x7D, 0x18, 0xEA, 0x5A, 0xB3, 0x02, 0xE2, 0x70, 0x77, 0xD1, 0x6B, 0x2C, 0x2F, 0xD9, 0x35, 0x16, 0xF9, 0x15, 0x14, 0xBA, 0x04, 0x99, 0x33, 0xD3, 0x48, 0xDA, 0x44, 0x1F }, + { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07 }, + { 0x03, 0x94, 0xF8, 0x59, 0x2D, 0xC5, 0xFE, 0xC7, 0x6C, 0xFF, 0x92, 0x20, 0x0E, 0xD3, 0xBA, 0x2B, 0xCF, 0x78, 0x51, 0x8B, 0x46, 0xB7, 0x06, 0xA4, 0x7B, 0xD5, 0x54, 0x58, 0xDB, 0x31, 0xD2, 0x94, 0xA7 } + }, 4, { + { 0x06, 0xD4, 0x7E, 0x05, 0xE9, 0x74, 0x81, 0x42, 0x86, 0x54, 0x56, 0x3E, 0x5A, 0xE6, 0x9C, 0x20, 0xC4, 0x96, 0x42, 0x77, 0x3B, 0x73, 0x34, 0x22, 0x0E, 0x63, 0x11, 0x02, 0x59, 0xA3, 0x0C, 0x32 }, + { 0x06, 0xD4, 0x7E, 0x05, 0xE9, 0x74, 0x81, 0x42, 0x86, 0x54, 0x56, 0x3E, 0x5A, 0xE6, 0x9C, 0x20, 0xC4, 0x96, 0x42, 0x77, 0x3B, 0x73, 0x34, 0x22, 0x0E, 0x63, 0x11, 0x02, 0x59, 0xA3, 0x0C, 0x32 }, + { 0x06, 0xD4, 0x7E, 0x05, 0xE9, 0x74, 0x81, 0x42, 0x86, 0x54, 0x56, 0x3E, 0x5A, 0xE6, 0x9C, 0x20, 0xC4, 0x96, 0x42, 0x77, 0x3B, 0x73, 0x34, 0x22, 0x0E, 0x63, 0x11, 0x02, 0x59, 0xA3, 0x0C, 0x32 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, 0, {}, 0, {}, 0, {} }, + { 3, 3, { 0x02, 0x3E, 0x94, 0xD6, 0xA6, 0x86, 0x20, 0xD3, 0xF6, 0x02, 0x21, 0xA4, 0x18, 0x67, 0x86, 0x27, 0x4A, 0x71, 0x12, 0x21, 0xA8, 0xBB, 0xB3, 0x1A, 0x53, 0x88, 0xDF, 0xA6, 0x71, 0x8E, 0x8E, 0xF7, 0xBB }, 5, { + { 0x03, 0xA3, 0xE9, 0x32, 0xBA, 0x9D, 0xD0, 0x06, 0x3D, 0x72, 0x15, 0x90, 0xB6, 0xEF, 0x21, 0xDD, 0x45, 0x66, 0xA9, 0x7B, 0x20, 0x33, 0x43, 0xFD, 0xE9, 0xDA, 0x58, 0x15, 0xDB, 0x9B, 0xE0, 0x49, 0xCA }, + { 0x02, 0x01, 0xE5, 0xFE, 0xAC, 0x0D, 0xB5, 0x05, 0x9C, 0x32, 0xB0, 0x45, 0xF3, 0x77, 0x99, 0x10, 0x1A, 0x96, 0x26, 0x2B, 0x3C, 0x88, 0xCE, 0x85, 0xD6, 0x10, 0x45, 0x1F, 0xC2, 0x1A, 0x04, 0x57, 0xFF }, + { 0x03, 0xEF, 0x72, 0xD1, 0x0D, 0x1D, 0xFE, 0x4E, 0x78, 0x66, 0x19, 0x53, 0x6A, 0x45, 0x85, 0x07, 0xCA, 0xF1, 0x05, 0xFC, 0xCD, 0xB8, 0x17, 0x3D, 0xAF, 0x2E, 0x35, 0x80, 0x54, 0xAF, 0x2F, 0xA4, 0xA2 }, + { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07 }, + { 0x02, 0x8F, 0xB6, 0x42, 0x47, 0x19, 0xCF, 0x2E, 0x40, 0x14, 0x6B, 0x40, 0x25, 0x71, 0x5F, 0xDA, 0x43, 0x91, 0x8A, 0x72, 0x2F, 0x33, 0xA6, 0x26, 0x0C, 0xB0, 0x8A, 0x21, 0xE6, 0x5C, 0xB9, 0xE1, 0x4E } + }, 4, { + { 0xD4, 0xDE, 0x57, 0x1C, 0x66, 0x2C, 0x31, 0x9E, 0x7C, 0x4F, 0x46, 0x42, 0x0F, 0x5A, 0xCB, 0xEF, 0xD2, 0xD9, 0x05, 0xC3, 0xB5, 0x27, 0x71, 0xC5, 0x53, 0xDE, 0x1F, 0x76, 0x19, 0x7D, 0x94, 0x0D }, + { 0x0E, 0xAA, 0xC0, 0x17, 0xAB, 0xA2, 0x03, 0x02, 0x72, 0xB7, 0xF8, 0xEA, 0xAD, 0x68, 0xE2, 0x2B, 0xF0, 0x7F, 0x08, 0x95, 0x0D, 0x7B, 0x57, 0x0B, 0x69, 0xB2, 0xCC, 0xEF, 0x27, 0x8D, 0x52, 0xC1 }, + { 0x1E, 0x4E, 0x43, 0x44, 0xB9, 0xB5, 0x94, 0x10, 0x58, 0x8C, 0xCF, 0x32, 0x7B, 0x76, 0x6E, 0x4D, 0x29, 0x88, 0x82, 0xD9, 0x04, 0xF0, 0xFB, 0xF2, 0x88, 0xC8, 0x6B, 0x73, 0xAC, 0x59, 0x62, 0xA3 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, 0, {}, 0, {}, 0, {} }, + { 3, 5, { 0x03, 0xE1, 0xAE, 0xA0, 0x0A, 0x7B, 0x8D, 0x0E, 0x03, 0x93, 0x66, 0x4F, 0xEB, 0xBD, 0x31, 0x56, 0x9A, 0x02, 0xCA, 0xF2, 0x23, 0xD9, 0xAD, 0x83, 0xE9, 0x03, 0x31, 0xDC, 0x18, 0xB1, 0x98, 0x73, 0x58 }, 7, { + { 0x02, 0xF3, 0x33, 0xED, 0xD2, 0xB6, 0xF5, 0x32, 0xC2, 0xEF, 0x6C, 0x42, 0xE8, 0x03, 0xB6, 0x33, 0xA4, 0x22, 0x89, 0xD0, 0x56, 0x7A, 0x75, 0xC5, 0x0E, 0xB1, 0xC8, 0xCF, 0x85, 0xEC, 0x48, 0x0E, 0x8F }, + { 0x02, 0x53, 0x22, 0xF6, 0x36, 0x02, 0xEC, 0xCF, 0x14, 0x65, 0x41, 0xB7, 0xC9, 0xEE, 0x4D, 0x1F, 0xCB, 0x84, 0xEC, 0x13, 0x94, 0x71, 0x42, 0x04, 0x72, 0x18, 0x2A, 0xE9, 0x68, 0x67, 0x6A, 0x38, 0x7F }, + { 0x02, 0x30, 0x63, 0x9C, 0xEC, 0x0A, 0x83, 0x98, 0x2E, 0x17, 0x6D, 0x69, 0x05, 0xCE, 0x06, 0x20, 0xFD, 0xC5, 0x7E, 0x15, 0x15, 0x65, 0xA3, 0x9D, 0x0E, 0x08, 0x21, 0xB8, 0xE7, 0x53, 0xAE, 0x85, 0xB0 }, + { 0x02, 0x6E, 0x1A, 0x50, 0xE6, 0x72, 0xFE, 0xDD, 0x3F, 0x3C, 0x37, 0x8D, 0x61, 0x21, 0xE5, 0x70, 0x2B, 0x05, 0x06, 0x69, 0xDB, 0xC2, 0x41, 0xD2, 0xC2, 0x29, 0x98, 0x80, 0x15, 0x2C, 0xD2, 0x07, 0xBD }, + { 0x02, 0xDC, 0x06, 0xC4, 0xCA, 0x91, 0x9D, 0xE7, 0x0B, 0x4B, 0x82, 0x81, 0x90, 0x1C, 0xCF, 0x94, 0x71, 0xAB, 0x91, 0xFB, 0xFB, 0xEE, 0x1A, 0x8C, 0x57, 0x0D, 0x83, 0x91, 0x1C, 0xAA, 0xF9, 0xE2, 0xFA }, + { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07 }, + { 0x03, 0x1B, 0x21, 0xF2, 0xB4, 0x93, 0x1A, 0xC1, 0x74, 0x35, 0xD9, 0x43, 0xAB, 0xAD, 0xB9, 0x69, 0xCB, 0xCD, 0x4A, 0xFE, 0x3E, 0xB7, 0x1D, 0x1C, 0xD6, 0x2E, 0x87, 0xF9, 0xD2, 0xBD, 0x82, 0x51, 0x64 } + }, 6, { + { 0x77, 0xC9, 0x31, 0x6A, 0x64, 0x77, 0x0B, 0x17, 0xD5, 0x00, 0x84, 0x0E, 0x02, 0x0A, 0x94, 0x78, 0xF7, 0x93, 0xD3, 0x7D, 0xB0, 0xE6, 0xA2, 0x76, 0xCB, 0x4E, 0x62, 0x70, 0x18, 0x7D, 0x6C, 0x90 }, + { 0x74, 0x18, 0x04, 0x20, 0xA7, 0x84, 0x18, 0x9B, 0x55, 0xF8, 0xC4, 0x66, 0x70, 0x75, 0xE8, 0x9C, 0x20, 0x64, 0xFF, 0x48, 0x1B, 0x6E, 0xD2, 0xA2, 0x3A, 0x75, 0x17, 0xAF, 0x71, 0xF6, 0xB7, 0xA8 }, + { 0xBE, 0x6B, 0x9F, 0xB0, 0x75, 0x86, 0xEB, 0xAB, 0xD2, 0x34, 0xEE, 0xE0, 0xA0, 0x5E, 0x81, 0x3D, 0xFF, 0xC1, 0x4D, 0x73, 0x78, 0x20, 0x85, 0xC8, 0xDF, 0xE7, 0x7C, 0x1F, 0xAD, 0xDA, 0x71, 0x72 }, + { 0x56, 0xC4, 0x04, 0x19, 0xCE, 0x7F, 0x84, 0x49, 0x49, 0xB5, 0x03, 0x7C, 0x91, 0xC4, 0x5E, 0x5F, 0xDA, 0xF9, 0xE1, 0x19, 0x17, 0xB3, 0x1B, 0xAE, 0xFB, 0xD3, 0x31, 0x33, 0xFB, 0xF2, 0x58, 0xAD }, + { 0x3D, 0x21, 0x31, 0x5C, 0xB2, 0x6D, 0xE2, 0x73, 0xBC, 0x79, 0x02, 0x3A, 0x44, 0xA7, 0x80, 0x00, 0x6C, 0xBD, 0x97, 0x1F, 0xA9, 0x6F, 0x34, 0x90, 0x4E, 0x0A, 0x95, 0x79, 0x2C, 0x74, 0xAE, 0x9A }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, 0, {}, 0, {}, 0, {} }, +}; + +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]; +}; +static const struct frost_vec_det_sign_case frost_vec_det_sign_valid_cases[37] = { + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 1, { 0x03, 0xB5, 0x62, 0x3D, 0xAC, 0x86, 0xC6, 0x14, 0x52, 0x56, 0x8A, 0x33, 0x51, 0xC9, 0xBF, 0x29, 0xE4, 0xB9, 0x68, 0x93, 0x38, 0xD2, 0xA9, 0x6E, 0x09, 0x90, 0x30, 0x6C, 0x9F, 0xFE, 0x6A, 0x64, 0x0A, 0x03, 0x46, 0x72, 0xC9, 0x29, 0xA9, 0x54, 0xE0, 0x4F, 0x10, 0x9C, 0x90, 0xEC, 0x41, 0x57, 0x90, 0xD8, 0x46, 0x3C, 0x8A, 0x43, 0xA8, 0x4A, 0xBE, 0x39, 0xCC, 0x30, 0x2E, 0x07, 0x29, 0x9D, 0x95, 0xE0 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x02, 0x30, 0x12, 0x6A, 0x86, 0x3D, 0x62, 0xA9, 0x63, 0x14, 0x8B, 0xAE, 0x7A, 0x4A, 0xA3, 0x73, 0x66, 0x94, 0x33, 0x6F, 0x12, 0xC8, 0x68, 0xA8, 0xFE, 0x93, 0x6D, 0x91, 0x02, 0x66, 0x5F, 0x7C, 0x95, 0x02, 0x0C, 0xC7, 0xC3, 0x17, 0x00, 0x69, 0xAE, 0x05, 0xA8, 0xF5, 0xA4, 0xF0, 0x36, 0x38, 0x4C, 0x65, 0x49, 0x17, 0x3F, 0x2B, 0x17, 0x82, 0xC3, 0x5D, 0xB7, 0x1E, 0xA2, 0xCC, 0x71, 0x93, 0xB7, 0x0B }, { 0x1D, 0xCA, 0x36, 0x37, 0x29, 0x44, 0x60, 0x42, 0xE4, 0x9E, 0x5D, 0xA9, 0xA9, 0xB2, 0x6D, 0xA5, 0x08, 0x64, 0x4E, 0xF6, 0x8C, 0x7E, 0xFA, 0x6E, 0xE5, 0xEC, 0x7F, 0x73, 0xEF, 0x8E, 0x2B, 0x8B } }, + { 0, 0, 2, { 0, 1 }, 0, { 0 }, 0, 1, { 0x03, 0xB5, 0x62, 0x3D, 0xAC, 0x86, 0xC6, 0x14, 0x52, 0x56, 0x8A, 0x33, 0x51, 0xC9, 0xBF, 0x29, 0xE4, 0xB9, 0x68, 0x93, 0x38, 0xD2, 0xA9, 0x6E, 0x09, 0x90, 0x30, 0x6C, 0x9F, 0xFE, 0x6A, 0x64, 0x0A, 0x03, 0x46, 0x72, 0xC9, 0x29, 0xA9, 0x54, 0xE0, 0x4F, 0x10, 0x9C, 0x90, 0xEC, 0x41, 0x57, 0x90, 0xD8, 0x46, 0x3C, 0x8A, 0x43, 0xA8, 0x4A, 0xBE, 0x39, 0xCC, 0x30, 0x2E, 0x07, 0x29, 0x9D, 0x95, 0xE0 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x02, 0x30, 0x12, 0x6A, 0x86, 0x3D, 0x62, 0xA9, 0x63, 0x14, 0x8B, 0xAE, 0x7A, 0x4A, 0xA3, 0x73, 0x66, 0x94, 0x33, 0x6F, 0x12, 0xC8, 0x68, 0xA8, 0xFE, 0x93, 0x6D, 0x91, 0x02, 0x66, 0x5F, 0x7C, 0x95, 0x02, 0x0C, 0xC7, 0xC3, 0x17, 0x00, 0x69, 0xAE, 0x05, 0xA8, 0xF5, 0xA4, 0xF0, 0x36, 0x38, 0x4C, 0x65, 0x49, 0x17, 0x3F, 0x2B, 0x17, 0x82, 0xC3, 0x5D, 0xB7, 0x1E, 0xA2, 0xCC, 0x71, 0x93, 0xB7, 0x0B }, { 0x1D, 0xCA, 0x36, 0x37, 0x29, 0x44, 0x60, 0x42, 0xE4, 0x9E, 0x5D, 0xA9, 0xA9, 0xB2, 0x6D, 0xA5, 0x08, 0x64, 0x4E, 0xF6, 0x8C, 0x7E, 0xFA, 0x6E, 0xE5, 0xEC, 0x7F, 0x73, 0xEF, 0x8E, 0x2B, 0x8B } }, + { 0, 0, 2, { 1, 0 }, 1, { 1, 0 }, 0, 1, { 0x03, 0xB5, 0x62, 0x3D, 0xAC, 0x86, 0xC6, 0x14, 0x52, 0x56, 0x8A, 0x33, 0x51, 0xC9, 0xBF, 0x29, 0xE4, 0xB9, 0x68, 0x93, 0x38, 0xD2, 0xA9, 0x6E, 0x09, 0x90, 0x30, 0x6C, 0x9F, 0xFE, 0x6A, 0x64, 0x0A, 0x03, 0x46, 0x72, 0xC9, 0x29, 0xA9, 0x54, 0xE0, 0x4F, 0x10, 0x9C, 0x90, 0xEC, 0x41, 0x57, 0x90, 0xD8, 0x46, 0x3C, 0x8A, 0x43, 0xA8, 0x4A, 0xBE, 0x39, 0xCC, 0x30, 0x2E, 0x07, 0x29, 0x9D, 0x95, 0xE0 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x02, 0x30, 0x12, 0x6A, 0x86, 0x3D, 0x62, 0xA9, 0x63, 0x14, 0x8B, 0xAE, 0x7A, 0x4A, 0xA3, 0x73, 0x66, 0x94, 0x33, 0x6F, 0x12, 0xC8, 0x68, 0xA8, 0xFE, 0x93, 0x6D, 0x91, 0x02, 0x66, 0x5F, 0x7C, 0x95, 0x02, 0x0C, 0xC7, 0xC3, 0x17, 0x00, 0x69, 0xAE, 0x05, 0xA8, 0xF5, 0xA4, 0xF0, 0x36, 0x38, 0x4C, 0x65, 0x49, 0x17, 0x3F, 0x2B, 0x17, 0x82, 0xC3, 0x5D, 0xB7, 0x1E, 0xA2, 0xCC, 0x71, 0x93, 0xB7, 0x0B }, { 0x1D, 0xCA, 0x36, 0x37, 0x29, 0x44, 0x60, 0x42, 0xE4, 0x9E, 0x5D, 0xA9, 0xA9, 0xB2, 0x6D, 0xA5, 0x08, 0x64, 0x4E, 0xF6, 0x8C, 0x7E, 0xFA, 0x6E, 0xE5, 0xEC, 0x7F, 0x73, 0xEF, 0x8E, 0x2B, 0x8B } }, + { 0, 0, 2, { 0, 2 }, 1, { 0, 2 }, 0, 1, { 0x03, 0xA1, 0x20, 0xB3, 0x53, 0x16, 0x94, 0x5A, 0x5E, 0xB2, 0x2B, 0x30, 0x9A, 0x90, 0x88, 0xED, 0xED, 0xFC, 0xF4, 0x5C, 0x6C, 0xED, 0x2D, 0xDF, 0x15, 0x36, 0x61, 0xCB, 0x76, 0x66, 0x03, 0x1B, 0x86, 0x03, 0x4A, 0x04, 0xD6, 0xC3, 0x4C, 0x51, 0xF8, 0x1B, 0xFD, 0x9A, 0xDA, 0xC2, 0x09, 0x06, 0xDF, 0xCC, 0x77, 0x98, 0x21, 0x08, 0x72, 0x02, 0x0B, 0xF2, 0xAD, 0x0F, 0x52, 0x88, 0x7D, 0x60, 0x26, 0x23 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x03, 0x02, 0xBA, 0x55, 0xCB, 0x01, 0xDD, 0x64, 0x3A, 0xEA, 0x06, 0x5A, 0xAF, 0x00, 0x2F, 0x1A, 0x29, 0xD3, 0x89, 0x01, 0xE2, 0x1F, 0xFD, 0xF0, 0xE8, 0xEA, 0x88, 0xF6, 0x42, 0x79, 0x53, 0x44, 0x95, 0x02, 0xDD, 0xAD, 0x2A, 0x68, 0xB7, 0x88, 0x8B, 0x5D, 0x73, 0x85, 0xC3, 0x1D, 0xC5, 0x4C, 0x46, 0xFA, 0xA9, 0xCB, 0x1F, 0xBF, 0xD8, 0x26, 0x8A, 0xBB, 0x59, 0xF9, 0xA4, 0xFE, 0xB7, 0x0C, 0xB9, 0x9E }, { 0xEF, 0x6B, 0x84, 0x65, 0x65, 0xDB, 0x50, 0x17, 0x22, 0x70, 0xEB, 0x93, 0x89, 0xE0, 0xF7, 0x71, 0x3D, 0x94, 0x00, 0x90, 0x2D, 0xEE, 0x1B, 0xB5, 0xE3, 0xF2, 0xAD, 0xF7, 0x7B, 0xAA, 0x20, 0x96 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 1, { 0x02, 0x00, 0x5B, 0xA7, 0x1E, 0x0F, 0x89, 0x15, 0x67, 0x46, 0x49, 0x9B, 0x39, 0x2A, 0x8F, 0x61, 0x96, 0x9E, 0x2C, 0x51, 0xFB, 0xCB, 0x02, 0x31, 0xD1, 0x04, 0xD4, 0x21, 0x92, 0xAF, 0xDB, 0xCC, 0x74, 0x02, 0x49, 0x78, 0x9D, 0xED, 0x73, 0x17, 0xA4, 0x15, 0xCD, 0x0E, 0x5C, 0xA7, 0xA5, 0x1B, 0x29, 0x2F, 0xE6, 0x70, 0xF5, 0x27, 0xE0, 0x1D, 0xFB, 0xDD, 0xC7, 0x89, 0x8D, 0xD1, 0x97, 0x72, 0x24, 0xF3 }, 0, { 0 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x03, 0xE5, 0x39, 0x25, 0x67, 0x72, 0x53, 0x32, 0x41, 0x8C, 0xC6, 0x78, 0x8C, 0x5B, 0xAE, 0x50, 0x8B, 0x5F, 0x60, 0x7F, 0xD7, 0xDC, 0xA0, 0x5B, 0x95, 0x75, 0x0F, 0xC2, 0x12, 0x2D, 0xA2, 0x0F, 0x9D, 0x03, 0x22, 0xD2, 0x97, 0xFA, 0x57, 0x9B, 0xFE, 0x64, 0xEE, 0x8C, 0xD9, 0x4F, 0xA8, 0x2A, 0xE8, 0xE6, 0x2A, 0x5B, 0xBA, 0xFC, 0x81, 0x5C, 0xA2, 0x8A, 0xD0, 0x6C, 0x60, 0x65, 0xEE, 0x57, 0x01, 0x02 }, { 0xEA, 0x75, 0xE3, 0x88, 0x54, 0xF3, 0xE8, 0xF6, 0x9C, 0x40, 0xFD, 0x0C, 0xDC, 0xDE, 0x24, 0xAC, 0xCE, 0xF1, 0x1C, 0x5E, 0x27, 0xA2, 0xA6, 0x69, 0x08, 0xC6, 0x6F, 0xBE, 0xF5, 0xD1, 0xDC, 0x52 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 1, { 0x02, 0xDB, 0x94, 0x7F, 0x29, 0x6B, 0xBE, 0x29, 0x4C, 0xCE, 0x31, 0x17, 0xCD, 0x3D, 0xBB, 0xFB, 0x8D, 0xB2, 0xD3, 0xB3, 0x07, 0x1F, 0x75, 0x98, 0xB4, 0x2D, 0x12, 0xC0, 0x4D, 0xF8, 0xD2, 0x82, 0xF8, 0x03, 0xBA, 0x1E, 0x9D, 0x78, 0xBE, 0x28, 0x5B, 0x94, 0x45, 0x9C, 0x18, 0x2D, 0x30, 0x10, 0xE9, 0x49, 0xC8, 0xFE, 0xDB, 0xB1, 0x20, 0x9E, 0x3D, 0xA9, 0x66, 0xD6, 0x2C, 0xE5, 0x04, 0xFF, 0x79, 0xCC }, 1, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x03, 0x9F, 0xBB, 0xFD, 0x38, 0x1C, 0x1E, 0xE8, 0xAC, 0x22, 0x92, 0x45, 0xBB, 0x92, 0x64, 0x19, 0x75, 0x24, 0x71, 0xEF, 0xE3, 0xD8, 0xD0, 0x30, 0x22, 0x81, 0x03, 0x10, 0x8A, 0xA4, 0x78, 0xA8, 0x09, 0x02, 0x65, 0xB9, 0x31, 0xD2, 0xE5, 0x6D, 0x12, 0xAA, 0x07, 0xAC, 0x7C, 0x93, 0x10, 0x11, 0xE8, 0xF4, 0x3E, 0x7E, 0x6B, 0xCE, 0x7F, 0xE3, 0x2F, 0x3F, 0x85, 0x06, 0x44, 0x49, 0x5E, 0x3D, 0x6E, 0x9A }, { 0xDF, 0x26, 0xC9, 0x6F, 0x3C, 0xC7, 0x8E, 0x69, 0x27, 0x4C, 0x96, 0x52, 0xFB, 0xC4, 0x8D, 0x58, 0x28, 0x4E, 0xAF, 0x01, 0xD4, 0x8C, 0xA0, 0xB2, 0xCF, 0xE7, 0x26, 0xDB, 0x60, 0xF3, 0x51, 0x73 } }, + { 0, 1, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 1, 1, { 0x03, 0x1A, 0x74, 0xBE, 0x08, 0x95, 0xA2, 0x95, 0x13, 0xF4, 0x0F, 0x10, 0x95, 0x9B, 0x5D, 0x65, 0x25, 0x47, 0xFD, 0xB7, 0xC3, 0xC0, 0xC4, 0xB7, 0xD2, 0x75, 0x84, 0x34, 0x6A, 0x87, 0xF2, 0x5A, 0x9A, 0x03, 0xB8, 0xC2, 0x37, 0xA0, 0x9B, 0x79, 0x4F, 0x0F, 0x3C, 0xDA, 0x70, 0x19, 0xE4, 0x94, 0xC4, 0xC8, 0x17, 0xF6, 0x6D, 0x8A, 0xAE, 0x97, 0xD8, 0x9F, 0x42, 0x2E, 0x8E, 0xE9, 0xAD, 0xD5, 0x0D, 0xE1 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x02, 0xAC, 0x4B, 0x71, 0xD8, 0x20, 0x97, 0x71, 0x8E, 0xB6, 0xDD, 0xED, 0x85, 0x5A, 0x83, 0x1C, 0xB5, 0x2B, 0x41, 0x90, 0x67, 0xAF, 0xD0, 0xE8, 0x29, 0xBD, 0x54, 0x6A, 0x16, 0xD1, 0x4F, 0x59, 0xED, 0x02, 0x8C, 0xEE, 0xBB, 0x22, 0x89, 0x65, 0xF6, 0xE2, 0x6B, 0xFF, 0x8A, 0xE9, 0xC9, 0x06, 0xDC, 0x0B, 0x96, 0xAE, 0x85, 0xDA, 0x86, 0xFD, 0x55, 0x9A, 0x04, 0x06, 0xA3, 0xBD, 0xD1, 0x9E, 0xB7, 0xC0 }, { 0x2C, 0xD6, 0xD3, 0x39, 0xFB, 0x15, 0xDA, 0x4C, 0xA9, 0xEA, 0x89, 0x82, 0x1A, 0x5C, 0xB8, 0x30, 0x46, 0x21, 0xCE, 0x1F, 0x73, 0xD5, 0x50, 0x2C, 0x87, 0xC1, 0x33, 0xF7, 0xC3, 0x75, 0xB7, 0x69 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 1, { 0x03, 0x59, 0x6B, 0xB9, 0x81, 0x4A, 0xB3, 0x63, 0xF9, 0x93, 0x8C, 0x47, 0x69, 0x0A, 0xDA, 0x94, 0x89, 0xC0, 0xA0, 0xF9, 0xB9, 0x72, 0x29, 0xD6, 0x08, 0xB1, 0x19, 0xA1, 0x47, 0xB5, 0x60, 0x73, 0xE8, 0x03, 0x55, 0xCF, 0xC4, 0xE5, 0x42, 0x91, 0x44, 0x0B, 0x07, 0xC0, 0x1E, 0x54, 0x27, 0x36, 0x11, 0x66, 0x2D, 0xC9, 0xE1, 0x93, 0x24, 0x63, 0x9D, 0x1C, 0x88, 0x78, 0xF5, 0xAA, 0x9C, 0x5D, 0x59, 0xE6 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, { }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x03, 0x5B, 0xF0, 0xFB, 0x16, 0x5A, 0x25, 0x2B, 0x77, 0x6B, 0x84, 0x16, 0x3C, 0xD3, 0x68, 0x28, 0x97, 0x0D, 0x8E, 0xB4, 0xF4, 0x62, 0x41, 0xFE, 0x5B, 0x3E, 0x92, 0x93, 0x04, 0xEF, 0x4F, 0xA4, 0x68, 0x03, 0x07, 0x69, 0x33, 0xC1, 0x71, 0xBC, 0xEA, 0xD2, 0x92, 0xB3, 0x00, 0xF7, 0x57, 0x9F, 0x1E, 0x5A, 0xED, 0xA4, 0x94, 0x25, 0x84, 0xA3, 0x13, 0x69, 0x4F, 0x3C, 0x39, 0x72, 0x82, 0xA5, 0xB5, 0x65 }, { 0x41, 0xC1, 0x9A, 0x9F, 0xA4, 0x4D, 0x67, 0xB1, 0x88, 0xBF, 0xA4, 0x04, 0xD0, 0x4C, 0xF6, 0x5D, 0x1B, 0x80, 0xDB, 0x93, 0x67, 0x6C, 0x8C, 0x00, 0x7F, 0xBE, 0x81, 0x8A, 0x7A, 0x5E, 0x9A, 0x4C } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 1, { 0x03, 0x4A, 0x8C, 0xB7, 0x5F, 0xAF, 0xF9, 0xB2, 0x59, 0xAC, 0xEB, 0xCE, 0x97, 0xB9, 0x1A, 0xA9, 0xDF, 0x39, 0x18, 0xF8, 0x2D, 0xCF, 0x3A, 0xC7, 0xBB, 0x42, 0x73, 0x79, 0x06, 0xB8, 0x85, 0xCF, 0x7F, 0x02, 0xAA, 0x4F, 0x2A, 0xFA, 0xDF, 0xD0, 0x54, 0x39, 0xAA, 0x9B, 0x15, 0x83, 0x42, 0x22, 0x8C, 0xC6, 0x71, 0x1C, 0x39, 0xE4, 0x05, 0x0B, 0x1F, 0x50, 0xA0, 0x0F, 0x94, 0xAA, 0x6E, 0x7C, 0xC8, 0x20 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 38, { 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26 }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x03, 0x4A, 0xF4, 0x73, 0x3B, 0xC8, 0xB3, 0x2C, 0xC4, 0x48, 0x43, 0x87, 0xD6, 0x36, 0xB2, 0x7E, 0x7A, 0x0D, 0xDB, 0xE4, 0x11, 0x14, 0x10, 0x10, 0x38, 0x74, 0x2B, 0xF6, 0x6B, 0x17, 0x53, 0x7E, 0x90, 0x03, 0xE7, 0x0F, 0xA2, 0x88, 0x4F, 0xCD, 0xA8, 0x12, 0x2E, 0xCD, 0xC1, 0x78, 0x0D, 0x77, 0x6C, 0x49, 0x91, 0x4A, 0xA0, 0x71, 0x15, 0x8F, 0x70, 0x03, 0xC0, 0xF0, 0x61, 0xBD, 0x14, 0x6F, 0xD8, 0xAB }, { 0xBD, 0x75, 0x14, 0x9F, 0xEC, 0xFC, 0xAC, 0x40, 0xB8, 0xC8, 0x56, 0x33, 0x98, 0x30, 0x4F, 0xEE, 0x8F, 0x6D, 0x95, 0x9C, 0x17, 0x3F, 0x0E, 0xAF, 0xE5, 0xD2, 0x62, 0xA5, 0xAF, 0x4B, 0xD1, 0x78 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 1, { 0x03, 0xB5, 0x62, 0x3D, 0xAC, 0x86, 0xC6, 0x14, 0x52, 0x56, 0x8A, 0x33, 0x51, 0xC9, 0xBF, 0x29, 0xE4, 0xB9, 0x68, 0x93, 0x38, 0xD2, 0xA9, 0x6E, 0x09, 0x90, 0x30, 0x6C, 0x9F, 0xFE, 0x6A, 0x64, 0x0A, 0x03, 0x46, 0x72, 0xC9, 0x29, 0xA9, 0x54, 0xE0, 0x4F, 0x10, 0x9C, 0x90, 0xEC, 0x41, 0x57, 0x90, 0xD8, 0x46, 0x3C, 0x8A, 0x43, 0xA8, 0x4A, 0xBE, 0x39, 0xCC, 0x30, 0x2E, 0x07, 0x29, 0x9D, 0x95, 0xE0 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { { 0xE8, 0xF7, 0x91, 0xFF, 0x92, 0x25, 0xA2, 0xAF, 0x01, 0x02, 0xAF, 0xFF, 0x4A, 0x9A, 0x72, 0x3D, 0x96, 0x12, 0xA6, 0x82, 0xA2, 0x5E, 0xBE, 0x79, 0x80, 0x2B, 0x26, 0x3C, 0xDF, 0xCD, 0x83, 0xBB } }, { 1 }, FROST_VEC_ERR_NONE, -1, { 0x03, 0x8B, 0x82, 0x90, 0x77, 0x22, 0x95, 0x8F, 0x93, 0x84, 0xB8, 0xD5, 0xFA, 0x3C, 0x29, 0xB3, 0x39, 0x59, 0xC3, 0x0A, 0x77, 0x2A, 0x59, 0x36, 0xF0, 0xF3, 0x6F, 0xB0, 0xE5, 0x22, 0xB7, 0x4E, 0x0C, 0x03, 0x66, 0xBB, 0x9C, 0x37, 0x21, 0xC3, 0xDA, 0xB7, 0xA6, 0x53, 0xC7, 0x71, 0x88, 0x42, 0x5E, 0x23, 0xF7, 0xEF, 0x29, 0xAD, 0xC1, 0x28, 0xFC, 0x23, 0x55, 0xEF, 0xA6, 0xCC, 0x59, 0x1E, 0x91, 0xCF }, { 0x0E, 0x7A, 0xF7, 0xCE, 0x38, 0xCE, 0x61, 0xC9, 0x86, 0x7D, 0xCA, 0xE4, 0x87, 0xDD, 0xAC, 0x3F, 0x7F, 0x51, 0x1B, 0x2B, 0x73, 0x5B, 0xA6, 0x0E, 0x73, 0xD2, 0xFC, 0x08, 0x03, 0x70, 0xEB, 0x19 } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 0, 0, { 0 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x02, 0x95, 0xE6, 0x2D, 0x67, 0xF9, 0x8E, 0xE3, 0xF9, 0x34, 0x9D, 0xDA, 0x8D, 0x39, 0xB6, 0x66, 0x8B, 0xAF, 0x6F, 0x25, 0xE1, 0x95, 0x13, 0x55, 0x70, 0xFE, 0xC4, 0xE1, 0x67, 0x25, 0xFE, 0x0D, 0xCD, 0x02, 0x66, 0x7A, 0x76, 0x3E, 0x41, 0x6A, 0xF3, 0x18, 0xB9, 0x8A, 0x5D, 0x02, 0xED, 0x80, 0xE8, 0x94, 0x48, 0x04, 0x9E, 0xFA, 0x66, 0xFA, 0xE7, 0x3F, 0x6D, 0xAC, 0x30, 0xA9, 0x98, 0xCF, 0x43, 0x99 }, { 0x35, 0xD7, 0xD6, 0xD4, 0x61, 0xBF, 0xE5, 0x9B, 0x10, 0xF5, 0x7C, 0x6F, 0x10, 0x6F, 0x7A, 0xDF, 0xB9, 0xCE, 0x97, 0xC3, 0x7F, 0x02, 0xC0, 0x16, 0x55, 0xA5, 0x53, 0x15, 0x53, 0x8C, 0xD0, 0xCC } }, + { 1, 0, 1, { 0 }, 0, { 0 }, 0, 0, { 0 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x02, 0x95, 0xE6, 0x2D, 0x67, 0xF9, 0x8E, 0xE3, 0xF9, 0x34, 0x9D, 0xDA, 0x8D, 0x39, 0xB6, 0x66, 0x8B, 0xAF, 0x6F, 0x25, 0xE1, 0x95, 0x13, 0x55, 0x70, 0xFE, 0xC4, 0xE1, 0x67, 0x25, 0xFE, 0x0D, 0xCD, 0x02, 0x66, 0x7A, 0x76, 0x3E, 0x41, 0x6A, 0xF3, 0x18, 0xB9, 0x8A, 0x5D, 0x02, 0xED, 0x80, 0xE8, 0x94, 0x48, 0x04, 0x9E, 0xFA, 0x66, 0xFA, 0xE7, 0x3F, 0x6D, 0xAC, 0x30, 0xA9, 0x98, 0xCF, 0x43, 0x99 }, { 0x35, 0xD7, 0xD6, 0xD4, 0x61, 0xBF, 0xE5, 0x9B, 0x10, 0xF5, 0x7C, 0x6F, 0x10, 0x6F, 0x7A, 0xDF, 0xB9, 0xCE, 0x97, 0xC3, 0x7F, 0x02, 0xC0, 0x16, 0x55, 0xA5, 0x53, 0x15, 0x53, 0x8C, 0xD0, 0xCC } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 0, 0, { 0 }, 0, { 0 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x02, 0x26, 0x8A, 0x19, 0x9C, 0xEA, 0x08, 0xBA, 0x33, 0x53, 0xC0, 0x3D, 0x92, 0xA9, 0xD5, 0x88, 0x96, 0x34, 0xBD, 0x2F, 0xC7, 0x61, 0x40, 0x66, 0xB4, 0x21, 0x93, 0x95, 0x46, 0xD5, 0x11, 0xC8, 0xBA, 0x03, 0xFC, 0x81, 0x89, 0x75, 0x2F, 0xDB, 0x33, 0x4A, 0xAC, 0x10, 0x3C, 0xAC, 0x32, 0x3A, 0x81, 0x10, 0xF9, 0x00, 0xC1, 0x60, 0xA9, 0xDE, 0x58, 0x09, 0xBC, 0xA2, 0x90, 0x01, 0x94, 0x96, 0xBB, 0x55 }, { 0xDE, 0x5A, 0x09, 0xDF, 0x87, 0xC4, 0x7D, 0xB2, 0x05, 0xB5, 0xEF, 0xE1, 0x83, 0xEE, 0xDC, 0x7D, 0x8E, 0x7E, 0x24, 0x06, 0xB3, 0xA6, 0xEE, 0x3E, 0xE8, 0x08, 0x7A, 0x74, 0x28, 0xF8, 0x11, 0xDD } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 0, 0, { 0 }, 1, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x03, 0x4C, 0x92, 0x9B, 0x5F, 0xF1, 0xA3, 0x23, 0x12, 0x34, 0x4D, 0xBD, 0xB4, 0xCE, 0x73, 0x1C, 0xB5, 0xF4, 0xBB, 0x59, 0x04, 0xBC, 0x6C, 0x4D, 0xAB, 0x06, 0xEE, 0x62, 0x81, 0x61, 0x86, 0x9F, 0x29, 0x03, 0x85, 0x33, 0x22, 0xC0, 0xE0, 0x4E, 0x74, 0x71, 0xC1, 0x3B, 0xDD, 0x04, 0x3A, 0xD3, 0x79, 0xD0, 0xEF, 0x58, 0x68, 0xF6, 0xD1, 0x59, 0x16, 0xAA, 0x9D, 0x93, 0xAC, 0x84, 0x11, 0xDE, 0xF1, 0x38 }, { 0x92, 0xF0, 0x2A, 0xBF, 0xE9, 0xB0, 0x8A, 0x86, 0xA8, 0x2D, 0x6A, 0xFC, 0x0E, 0x6F, 0x58, 0xE4, 0x12, 0x84, 0xA1, 0xC8, 0x6F, 0x3D, 0x0F, 0x31, 0xCD, 0x05, 0x28, 0x6B, 0x69, 0xEE, 0xD0, 0x04 } }, + { 1, 1, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 1, 1, { 0x02, 0xBC, 0x6B, 0x50, 0xC4, 0x47, 0x3E, 0xDA, 0x59, 0x93, 0x39, 0xE7, 0x6D, 0x9F, 0x1E, 0x4A, 0x97, 0x0B, 0xB1, 0x9B, 0x25, 0x1E, 0xAD, 0xE8, 0x38, 0xC6, 0xAD, 0xF9, 0x03, 0x47, 0xC7, 0xA1, 0x45, 0x03, 0x29, 0x43, 0x35, 0x96, 0x23, 0x73, 0xC7, 0x2A, 0x43, 0x3F, 0x05, 0xB4, 0x92, 0x1A, 0x74, 0x31, 0x6D, 0xF9, 0xFE, 0x84, 0x99, 0x9B, 0xEA, 0x55, 0xB2, 0x8E, 0xF4, 0xCD, 0x83, 0x63, 0x8F, 0xC6 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x03, 0x6E, 0xAB, 0x06, 0x9C, 0x1F, 0x2C, 0x26, 0x4E, 0xF7, 0xF1, 0x5B, 0xD1, 0x42, 0xF8, 0x22, 0xEC, 0x77, 0x6E, 0x86, 0x10, 0x88, 0xD6, 0x47, 0x13, 0x00, 0x7C, 0x03, 0x66, 0xAB, 0xB1, 0xA7, 0x39, 0x03, 0x53, 0x89, 0x66, 0xA3, 0x0A, 0x0A, 0x1A, 0x1C, 0x0E, 0x6E, 0x71, 0x92, 0x98, 0xA4, 0xC2, 0xD5, 0x5F, 0x6E, 0x82, 0xE7, 0x59, 0xAB, 0xC9, 0xDA, 0xFD, 0x65, 0x77, 0x70, 0x6B, 0xFE, 0xA0, 0xF9 }, { 0xDD, 0xC7, 0x85, 0xC9, 0x84, 0x52, 0x3C, 0xB6, 0x07, 0xA8, 0x13, 0x30, 0xCA, 0x0A, 0x67, 0x64, 0xF1, 0xD3, 0x07, 0x55, 0x63, 0xC2, 0xA3, 0x7E, 0xDC, 0xD4, 0x32, 0xAA, 0xBC, 0xBE, 0xBF, 0x51 } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 0, 0, { 0 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, { }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x03, 0x8E, 0x64, 0x31, 0x2D, 0x0D, 0xD4, 0x73, 0x22, 0xD2, 0x6C, 0x9B, 0x25, 0x4E, 0x76, 0xFB, 0x49, 0x67, 0x20, 0xD5, 0x7C, 0x07, 0x49, 0x3C, 0x5B, 0x43, 0x29, 0xB7, 0x2A, 0x2E, 0x12, 0x8A, 0x7B, 0x02, 0xE6, 0x2E, 0x84, 0x4D, 0x74, 0x2B, 0x01, 0xF4, 0x32, 0xB2, 0x05, 0x54, 0x5C, 0x44, 0x1E, 0xD5, 0x26, 0xF4, 0x33, 0xF2, 0x45, 0xF6, 0x04, 0xBB, 0xC2, 0x91, 0xA9, 0xB8, 0x1F, 0x18, 0x3F, 0x1E }, { 0x3A, 0xDD, 0x02, 0x4F, 0xF6, 0x7D, 0xCB, 0x9B, 0x97, 0x5E, 0x40, 0x5B, 0x39, 0xA6, 0x2E, 0x37, 0xAC, 0x46, 0xEB, 0xB1, 0x86, 0xF3, 0xDE, 0x13, 0x2D, 0xF8, 0xA9, 0x28, 0x7A, 0x25, 0x2C, 0x2B } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 0, 0, { 0 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 38, { 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26 }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x03, 0xCC, 0xE5, 0x78, 0xEA, 0xBE, 0xBA, 0x27, 0xAC, 0xF6, 0x08, 0x73, 0xB6, 0xCF, 0x56, 0x6F, 0x45, 0x61, 0x61, 0x43, 0x36, 0xE7, 0x3C, 0x80, 0xCB, 0x83, 0x13, 0xD4, 0x7D, 0xAC, 0x01, 0x22, 0x9F, 0x02, 0x2F, 0x48, 0xD9, 0xE1, 0xA4, 0xF9, 0x27, 0x84, 0x9C, 0x33, 0x61, 0xBD, 0xD2, 0x59, 0x47, 0x50, 0x76, 0xD7, 0xF4, 0xD7, 0x58, 0x29, 0xD9, 0x14, 0x62, 0x5E, 0x05, 0x15, 0xFE, 0xC4, 0xAD, 0xE9 }, { 0x06, 0x71, 0x21, 0xBA, 0x13, 0xB7, 0xBF, 0xA6, 0xC8, 0x92, 0x08, 0x0F, 0x0E, 0xF4, 0x98, 0xDA, 0x12, 0xE9, 0x26, 0x80, 0x62, 0x2E, 0x39, 0xE0, 0xED, 0x15, 0x31, 0xD0, 0x23, 0x96, 0xC6, 0x91 } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 0, 0, { 0 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { { 0xE8, 0xF7, 0x91, 0xFF, 0x92, 0x25, 0xA2, 0xAF, 0x01, 0x02, 0xAF, 0xFF, 0x4A, 0x9A, 0x72, 0x3D, 0x96, 0x12, 0xA6, 0x82, 0xA2, 0x5E, 0xBE, 0x79, 0x80, 0x2B, 0x26, 0x3C, 0xDF, 0xCD, 0x83, 0xBB } }, { 1 }, FROST_VEC_ERR_NONE, -1, { 0x02, 0x67, 0x8C, 0xE1, 0x6A, 0xAC, 0x46, 0x53, 0x3D, 0x37, 0x5E, 0xA5, 0xD3, 0xE9, 0xA1, 0x22, 0x0F, 0x76, 0x14, 0x07, 0x4D, 0x34, 0x1E, 0x2D, 0x6D, 0xA3, 0xA5, 0x96, 0x95, 0xD8, 0x7D, 0x85, 0xC9, 0x03, 0x15, 0xE6, 0x22, 0x9E, 0xDA, 0x78, 0x16, 0xAF, 0x02, 0x16, 0x39, 0x57, 0x24, 0x7D, 0x1C, 0xF9, 0x16, 0x1E, 0x2A, 0x97, 0x5E, 0xE0, 0x4E, 0x76, 0xB5, 0x94, 0xC6, 0xEA, 0x45, 0xF3, 0x58, 0xB8 }, { 0x2A, 0xE6, 0x26, 0x80, 0xC6, 0x94, 0xAB, 0x35, 0x07, 0x09, 0x82, 0x68, 0xB7, 0xCB, 0x16, 0xE2, 0x90, 0xFB, 0xB3, 0x51, 0x61, 0x82, 0x6D, 0x99, 0xAB, 0x7A, 0x48, 0x28, 0xAF, 0xFD, 0x3E, 0xC6 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 1, { 0x03, 0x32, 0xB7, 0xFB, 0xB7, 0xF9, 0xA1, 0x6A, 0xD4, 0x07, 0x3F, 0xF4, 0x82, 0xBF, 0x6F, 0x77, 0xA2, 0x94, 0x30, 0x99, 0xFA, 0x5C, 0x2B, 0x69, 0x1C, 0xA9, 0x00, 0x2C, 0x39, 0xEC, 0x72, 0x49, 0xF3, 0x03, 0x0F, 0xB4, 0xD9, 0xD5, 0xD7, 0x4D, 0x2D, 0xEE, 0xDB, 0xA7, 0x7E, 0xD1, 0xF1, 0x6E, 0xF2, 0x77, 0x76, 0x9A, 0x12, 0xF5, 0x71, 0x17, 0xEA, 0x0A, 0x0B, 0x99, 0x99, 0x05, 0xFB, 0x0A, 0x04, 0x2C }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x02, 0xB8, 0x0E, 0xAF, 0xA0, 0x62, 0xC4, 0xF9, 0xC4, 0x7F, 0x36, 0x1E, 0x81, 0x5D, 0x56, 0x95, 0x69, 0xF1, 0x38, 0x0C, 0x87, 0x00, 0x02, 0x13, 0x9C, 0xDE, 0xE0, 0x79, 0x08, 0x06, 0x81, 0xEE, 0x6C, 0x03, 0xED, 0x14, 0xFF, 0x4C, 0x01, 0x48, 0x94, 0xD3, 0x92, 0x52, 0x9D, 0x35, 0xFA, 0xCA, 0x59, 0x94, 0xFB, 0x7D, 0x14, 0x7F, 0xB2, 0x32, 0xF0, 0x5D, 0x67, 0x18, 0x44, 0x98, 0x05, 0x3A, 0xF9, 0xAA }, { 0x89, 0x60, 0x97, 0x3E, 0x7A, 0xB5, 0xF4, 0x57, 0x6A, 0xFF, 0xEB, 0x9C, 0xA9, 0xBE, 0xBA, 0xC2, 0x7D, 0xBC, 0xA4, 0xD3, 0x6D, 0xF0, 0x2F, 0xED, 0x58, 0xA8, 0x77, 0x1B, 0xE5, 0xE0, 0x3A, 0x8A } }, + { 2, 0, 3, { 0, 1, 2 }, 0, { 0 }, 0, 1, { 0x03, 0x32, 0xB7, 0xFB, 0xB7, 0xF9, 0xA1, 0x6A, 0xD4, 0x07, 0x3F, 0xF4, 0x82, 0xBF, 0x6F, 0x77, 0xA2, 0x94, 0x30, 0x99, 0xFA, 0x5C, 0x2B, 0x69, 0x1C, 0xA9, 0x00, 0x2C, 0x39, 0xEC, 0x72, 0x49, 0xF3, 0x03, 0x0F, 0xB4, 0xD9, 0xD5, 0xD7, 0x4D, 0x2D, 0xEE, 0xDB, 0xA7, 0x7E, 0xD1, 0xF1, 0x6E, 0xF2, 0x77, 0x76, 0x9A, 0x12, 0xF5, 0x71, 0x17, 0xEA, 0x0A, 0x0B, 0x99, 0x99, 0x05, 0xFB, 0x0A, 0x04, 0x2C }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x02, 0xB8, 0x0E, 0xAF, 0xA0, 0x62, 0xC4, 0xF9, 0xC4, 0x7F, 0x36, 0x1E, 0x81, 0x5D, 0x56, 0x95, 0x69, 0xF1, 0x38, 0x0C, 0x87, 0x00, 0x02, 0x13, 0x9C, 0xDE, 0xE0, 0x79, 0x08, 0x06, 0x81, 0xEE, 0x6C, 0x03, 0xED, 0x14, 0xFF, 0x4C, 0x01, 0x48, 0x94, 0xD3, 0x92, 0x52, 0x9D, 0x35, 0xFA, 0xCA, 0x59, 0x94, 0xFB, 0x7D, 0x14, 0x7F, 0xB2, 0x32, 0xF0, 0x5D, 0x67, 0x18, 0x44, 0x98, 0x05, 0x3A, 0xF9, 0xAA }, { 0x89, 0x60, 0x97, 0x3E, 0x7A, 0xB5, 0xF4, 0x57, 0x6A, 0xFF, 0xEB, 0x9C, 0xA9, 0xBE, 0xBA, 0xC2, 0x7D, 0xBC, 0xA4, 0xD3, 0x6D, 0xF0, 0x2F, 0xED, 0x58, 0xA8, 0x77, 0x1B, 0xE5, 0xE0, 0x3A, 0x8A } }, + { 2, 0, 3, { 2, 1, 0 }, 1, { 2, 1, 0 }, 0, 1, { 0x03, 0x32, 0xB7, 0xFB, 0xB7, 0xF9, 0xA1, 0x6A, 0xD4, 0x07, 0x3F, 0xF4, 0x82, 0xBF, 0x6F, 0x77, 0xA2, 0x94, 0x30, 0x99, 0xFA, 0x5C, 0x2B, 0x69, 0x1C, 0xA9, 0x00, 0x2C, 0x39, 0xEC, 0x72, 0x49, 0xF3, 0x03, 0x0F, 0xB4, 0xD9, 0xD5, 0xD7, 0x4D, 0x2D, 0xEE, 0xDB, 0xA7, 0x7E, 0xD1, 0xF1, 0x6E, 0xF2, 0x77, 0x76, 0x9A, 0x12, 0xF5, 0x71, 0x17, 0xEA, 0x0A, 0x0B, 0x99, 0x99, 0x05, 0xFB, 0x0A, 0x04, 0x2C }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x02, 0xB8, 0x0E, 0xAF, 0xA0, 0x62, 0xC4, 0xF9, 0xC4, 0x7F, 0x36, 0x1E, 0x81, 0x5D, 0x56, 0x95, 0x69, 0xF1, 0x38, 0x0C, 0x87, 0x00, 0x02, 0x13, 0x9C, 0xDE, 0xE0, 0x79, 0x08, 0x06, 0x81, 0xEE, 0x6C, 0x03, 0xED, 0x14, 0xFF, 0x4C, 0x01, 0x48, 0x94, 0xD3, 0x92, 0x52, 0x9D, 0x35, 0xFA, 0xCA, 0x59, 0x94, 0xFB, 0x7D, 0x14, 0x7F, 0xB2, 0x32, 0xF0, 0x5D, 0x67, 0x18, 0x44, 0x98, 0x05, 0x3A, 0xF9, 0xAA }, { 0x89, 0x60, 0x97, 0x3E, 0x7A, 0xB5, 0xF4, 0x57, 0x6A, 0xFF, 0xEB, 0x9C, 0xA9, 0xBE, 0xBA, 0xC2, 0x7D, 0xBC, 0xA4, 0xD3, 0x6D, 0xF0, 0x2F, 0xED, 0x58, 0xA8, 0x77, 0x1B, 0xE5, 0xE0, 0x3A, 0x8A } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 1, { 0x02, 0x19, 0x86, 0x22, 0x49, 0x1E, 0x3A, 0x09, 0x71, 0xDD, 0xD3, 0xE3, 0x94, 0x2F, 0xF4, 0xCB, 0x87, 0xDD, 0x93, 0xC8, 0x9F, 0x44, 0xE6, 0x4F, 0x2F, 0x8E, 0xC6, 0x7F, 0xEA, 0x87, 0xF7, 0x78, 0x41, 0x03, 0xC7, 0x68, 0x26, 0xC4, 0x34, 0xE8, 0xFD, 0x7F, 0xC9, 0x70, 0x35, 0xA0, 0x2A, 0x48, 0xB6, 0x92, 0x16, 0xE4, 0xC9, 0xB7, 0xB7, 0xD1, 0x2E, 0x5F, 0x61, 0x09, 0x32, 0xD6, 0x84, 0xB9, 0x79, 0x18 }, 0, { 0 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x03, 0xCA, 0x9B, 0xF0, 0xAC, 0x6D, 0x0D, 0x53, 0xED, 0x04, 0x62, 0xC4, 0x60, 0xC0, 0x03, 0x9A, 0xD2, 0xD9, 0x11, 0x0E, 0x98, 0x99, 0x36, 0xB0, 0x44, 0x9F, 0xFD, 0x1D, 0x5C, 0xC9, 0x95, 0x1B, 0x34, 0x02, 0x77, 0xD0, 0x2C, 0x43, 0x10, 0x27, 0x0F, 0x0E, 0x8A, 0x88, 0xC1, 0xD4, 0xEC, 0x6A, 0xBF, 0x1B, 0xC3, 0xEC, 0x11, 0x15, 0xA3, 0x18, 0xDE, 0xCD, 0x42, 0xB9, 0xDB, 0x63, 0x38, 0x3A, 0x8D, 0xC0 }, { 0x28, 0xD5, 0xBE, 0x19, 0xCA, 0x1B, 0x86, 0x7F, 0x82, 0xC9, 0xBD, 0x5A, 0x8C, 0x9D, 0x45, 0x31, 0x8A, 0x2D, 0xA9, 0xD8, 0x38, 0x3D, 0xB7, 0x41, 0x0A, 0x00, 0x01, 0x4C, 0x0D, 0x8F, 0x23, 0xB5 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 1, { 0x03, 0x0E, 0xD1, 0xC8, 0x76, 0xE4, 0xF0, 0x15, 0x33, 0xA8, 0xD4, 0xBA, 0xB5, 0x7F, 0x06, 0x6F, 0x1F, 0x52, 0x46, 0x83, 0xB9, 0x78, 0x0D, 0x41, 0x0D, 0x95, 0x15, 0x6A, 0xA2, 0xFF, 0x33, 0x8C, 0x17, 0x03, 0xD1, 0x22, 0x0C, 0x19, 0x34, 0x3C, 0xD2, 0x6D, 0xAF, 0xC5, 0x3F, 0xA7, 0x0A, 0xD7, 0xF2, 0xD2, 0xFB, 0x9D, 0x09, 0x16, 0xDE, 0x8C, 0xDA, 0xD7, 0x1A, 0x65, 0x38, 0xE6, 0x2E, 0x2D, 0xA7, 0x3C }, 1, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x03, 0xF2, 0x40, 0x3F, 0x95, 0xC7, 0xEE, 0x84, 0x2E, 0xFB, 0xF0, 0xF9, 0x7F, 0x9C, 0x10, 0x47, 0x5A, 0xCF, 0x04, 0x05, 0x24, 0xBF, 0xD3, 0x30, 0xA8, 0x14, 0x69, 0x8F, 0xB0, 0x2D, 0xF9, 0x79, 0x9E, 0x03, 0x34, 0x17, 0x0A, 0xB7, 0xD1, 0x47, 0x32, 0xFA, 0x27, 0x15, 0xD8, 0x0F, 0x98, 0x37, 0xC0, 0x65, 0xC9, 0x4C, 0x7D, 0x01, 0xB3, 0xAF, 0x1D, 0x88, 0xAD, 0xBD, 0xF9, 0x77, 0xB8, 0x57, 0xC9, 0x8C }, { 0x29, 0xF1, 0x7E, 0x73, 0x28, 0xBE, 0xF4, 0xF7, 0xF3, 0x84, 0xF8, 0xDC, 0x91, 0x2E, 0x69, 0xB8, 0xD4, 0xC5, 0xED, 0xF8, 0x8B, 0x2F, 0x08, 0x1D, 0x4E, 0x75, 0xA2, 0x73, 0x5E, 0xA1, 0xAA, 0x6A } }, + { 2, 1, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 1, 1, { 0x03, 0xD1, 0x44, 0x59, 0xA3, 0x41, 0x1B, 0xAD, 0xB6, 0xC1, 0x4B, 0x48, 0x2B, 0xC1, 0x73, 0xA8, 0xBB, 0xF6, 0x44, 0xAC, 0x62, 0x74, 0xF7, 0x27, 0x04, 0x19, 0xDC, 0x7C, 0x79, 0x67, 0xDD, 0x66, 0xBC, 0x02, 0x54, 0xE1, 0x35, 0x81, 0xA0, 0xCC, 0xB6, 0x52, 0x93, 0xAE, 0x69, 0xB3, 0xC0, 0x70, 0xCC, 0x68, 0xAF, 0x13, 0x37, 0x98, 0x05, 0xCB, 0xDE, 0x72, 0x80, 0x9B, 0xA9, 0xA3, 0x54, 0x68, 0x3C, 0xAE }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x02, 0xA1, 0xD0, 0xB9, 0xE8, 0x56, 0x35, 0xBD, 0x87, 0x69, 0x7E, 0xAF, 0x55, 0xDD, 0x31, 0x9F, 0xAC, 0xAE, 0x2E, 0x99, 0x1C, 0x42, 0x33, 0x6E, 0x6B, 0x65, 0x35, 0xFD, 0xC0, 0x93, 0x21, 0x62, 0xB8, 0x02, 0xA9, 0xB3, 0x51, 0x55, 0xA8, 0xE7, 0x7D, 0x0B, 0xCC, 0x8D, 0x5C, 0x47, 0xEC, 0xBC, 0xE3, 0x7A, 0x6D, 0x0C, 0x7B, 0xB5, 0xCF, 0x0B, 0x2D, 0xD7, 0xB1, 0x16, 0x51, 0x21, 0x48, 0xCE, 0xC4, 0x36 }, { 0x6D, 0x86, 0x50, 0xB3, 0x86, 0xC5, 0x53, 0x8B, 0x69, 0x59, 0xD6, 0xB7, 0x4E, 0xAE, 0x4C, 0xDE, 0x2E, 0xDF, 0xA0, 0x77, 0x77, 0x1D, 0x16, 0xD3, 0x7F, 0x20, 0xBE, 0xA6, 0x30, 0x3E, 0xD5, 0xC0 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 1, { 0x03, 0xDB, 0xEC, 0x1D, 0xF7, 0x18, 0x05, 0xA7, 0x41, 0xA0, 0x71, 0x00, 0xBE, 0xE7, 0x88, 0x34, 0x4F, 0x00, 0x6E, 0xCB, 0xFD, 0xF4, 0xD6, 0x5E, 0x14, 0xCB, 0x18, 0xA7, 0x36, 0x38, 0xD5, 0x47, 0xF4, 0x03, 0xF1, 0x37, 0x98, 0x06, 0xF1, 0x9A, 0x84, 0xBD, 0x49, 0xBE, 0x1F, 0xB0, 0x2D, 0xB1, 0xEE, 0x7B, 0x14, 0x9F, 0xE2, 0x36, 0x2D, 0x99, 0x0F, 0xAD, 0xCE, 0xA3, 0x14, 0x3A, 0xFB, 0x89, 0xB0, 0xB3 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, { }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x03, 0x93, 0x6E, 0xB4, 0x57, 0x47, 0xFE, 0x90, 0x68, 0xDB, 0xC6, 0xD2, 0xD8, 0x6F, 0xBB, 0x97, 0x9D, 0x62, 0x5D, 0x61, 0x7F, 0x20, 0x51, 0x9A, 0x6D, 0xDD, 0x1F, 0xE2, 0x55, 0x91, 0xA4, 0x91, 0xB3, 0x03, 0xDC, 0xE0, 0x86, 0x73, 0x9A, 0x87, 0xDD, 0x04, 0xD9, 0x7B, 0x70, 0x42, 0xDD, 0xDF, 0x21, 0x7F, 0xFE, 0xD3, 0x66, 0x5C, 0x1D, 0x15, 0x17, 0x35, 0xEA, 0x17, 0xB6, 0xA7, 0x80, 0x68, 0xFD, 0x33 }, { 0x60, 0x27, 0x38, 0x82, 0x4E, 0x8F, 0x8F, 0xAF, 0xF9, 0x59, 0xDA, 0xED, 0xF5, 0xC9, 0xF0, 0xD2, 0xC7, 0xD3, 0x0A, 0x0B, 0xB0, 0x0B, 0x48, 0x73, 0x3A, 0xCF, 0xAE, 0x73, 0x9B, 0x5A, 0x35, 0x69 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 1, { 0x02, 0x3E, 0x91, 0xD8, 0x50, 0x64, 0x87, 0x9A, 0xCA, 0x2E, 0xB0, 0xA1, 0xB1, 0xAC, 0xEE, 0xDA, 0xF5, 0xFF, 0x75, 0xB0, 0x0B, 0xCE, 0x77, 0x55, 0x52, 0xA0, 0x12, 0xDD, 0x3D, 0x53, 0x3A, 0x83, 0x5E, 0x03, 0xA5, 0x66, 0xDD, 0xF1, 0xC7, 0xC6, 0xC9, 0x05, 0x9F, 0x6E, 0xD0, 0x7E, 0x81, 0xC6, 0xF9, 0xE0, 0x74, 0xDB, 0xC5, 0x4E, 0x87, 0x3E, 0x9E, 0xFE, 0x78, 0xDE, 0x15, 0x00, 0xCA, 0xF2, 0xD4, 0x82 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 38, { 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26 }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x02, 0x0B, 0xBE, 0x69, 0x91, 0xAF, 0x73, 0x8E, 0x91, 0x11, 0x9B, 0x52, 0x41, 0xB1, 0xBD, 0x00, 0x91, 0x0C, 0xEC, 0x72, 0x3A, 0x05, 0xC9, 0x5F, 0x77, 0x5B, 0x7F, 0x88, 0x7D, 0x67, 0xD2, 0x5F, 0xBD, 0x02, 0xF2, 0x0C, 0x39, 0xB9, 0x3C, 0x39, 0xD2, 0xCC, 0x60, 0x35, 0xC1, 0x6D, 0x9D, 0x1F, 0xA3, 0x8B, 0xCB, 0xC7, 0xB1, 0xB5, 0x28, 0x35, 0x5C, 0x6E, 0x4C, 0xF9, 0x10, 0x94, 0x4E, 0xBD, 0x09, 0xA6 }, { 0x8A, 0x1A, 0xEA, 0x83, 0x1E, 0xF5, 0x28, 0x4D, 0xAA, 0x8A, 0xCF, 0xE5, 0x76, 0xA2, 0xCA, 0x9C, 0x42, 0xC8, 0xD6, 0x60, 0xB4, 0x2F, 0x00, 0x15, 0x17, 0xB9, 0xF2, 0x69, 0x79, 0xAC, 0x46, 0x3C } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 1, { 0x03, 0x32, 0xB7, 0xFB, 0xB7, 0xF9, 0xA1, 0x6A, 0xD4, 0x07, 0x3F, 0xF4, 0x82, 0xBF, 0x6F, 0x77, 0xA2, 0x94, 0x30, 0x99, 0xFA, 0x5C, 0x2B, 0x69, 0x1C, 0xA9, 0x00, 0x2C, 0x39, 0xEC, 0x72, 0x49, 0xF3, 0x03, 0x0F, 0xB4, 0xD9, 0xD5, 0xD7, 0x4D, 0x2D, 0xEE, 0xDB, 0xA7, 0x7E, 0xD1, 0xF1, 0x6E, 0xF2, 0x77, 0x76, 0x9A, 0x12, 0xF5, 0x71, 0x17, 0xEA, 0x0A, 0x0B, 0x99, 0x99, 0x05, 0xFB, 0x0A, 0x04, 0x2C }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { { 0xE8, 0xF7, 0x91, 0xFF, 0x92, 0x25, 0xA2, 0xAF, 0x01, 0x02, 0xAF, 0xFF, 0x4A, 0x9A, 0x72, 0x3D, 0x96, 0x12, 0xA6, 0x82, 0xA2, 0x5E, 0xBE, 0x79, 0x80, 0x2B, 0x26, 0x3C, 0xDF, 0xCD, 0x83, 0xBB } }, { 1 }, FROST_VEC_ERR_NONE, -1, { 0x03, 0xE2, 0xDC, 0x20, 0xE1, 0xBF, 0x88, 0x2B, 0x1B, 0x2E, 0x6A, 0xDC, 0x64, 0x05, 0x71, 0x4F, 0x92, 0x37, 0x81, 0x51, 0xE6, 0x63, 0xF0, 0x19, 0xD8, 0xAE, 0xC4, 0x0B, 0x9E, 0x5E, 0xF4, 0x22, 0xCE, 0x02, 0x60, 0xD4, 0xCE, 0x00, 0xC2, 0xE0, 0xBC, 0x5A, 0xA5, 0x28, 0x2F, 0xC9, 0x74, 0xE8, 0x46, 0x0E, 0x08, 0x15, 0x4A, 0xD7, 0xE9, 0x31, 0x6C, 0xED, 0x83, 0x29, 0x81, 0x56, 0x1F, 0x02, 0x67, 0xC7 }, { 0xE8, 0x94, 0x4B, 0x17, 0xAF, 0x41, 0xFE, 0x22, 0x9D, 0x50, 0x3A, 0x83, 0x29, 0x73, 0x74, 0xA4, 0x30, 0x96, 0xB7, 0x28, 0xE3, 0x7B, 0x64, 0xD2, 0xBA, 0xA1, 0xB8, 0xCE, 0xCA, 0xC4, 0x41, 0xBE } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 1, { 0x02, 0x19, 0xF1, 0x79, 0x47, 0xF4, 0x6D, 0xF4, 0x7F, 0xF6, 0x49, 0x82, 0x66, 0x84, 0x0A, 0x3E, 0xB4, 0xEB, 0x3C, 0x00, 0x08, 0x42, 0xA7, 0x7A, 0xFF, 0x62, 0x91, 0x33, 0x25, 0x56, 0x74, 0xC9, 0x2E, 0x03, 0x44, 0xA4, 0x83, 0xE6, 0x3F, 0x20, 0xFF, 0xD0, 0x37, 0xA3, 0xBC, 0xA5, 0x3A, 0xDF, 0x55, 0x25, 0x49, 0xDF, 0x79, 0xD6, 0x4F, 0x3D, 0xCF, 0x89, 0x59, 0x6B, 0x70, 0x37, 0xB8, 0x56, 0xC1, 0xE4 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x03, 0xA1, 0x06, 0x47, 0xD6, 0xB6, 0x1E, 0xF5, 0xCA, 0xF2, 0x7F, 0x4E, 0xC0, 0x71, 0xB1, 0xE7, 0xAC, 0xF4, 0x5E, 0xC2, 0xA5, 0x5F, 0xE6, 0x86, 0xF3, 0x8B, 0x24, 0xFD, 0x7C, 0x36, 0xD5, 0xA2, 0xBF, 0x03, 0x3A, 0xB8, 0x14, 0x15, 0x79, 0x13, 0x49, 0x90, 0x01, 0x87, 0x39, 0x09, 0xDA, 0x78, 0x43, 0xDD, 0xCE, 0xC1, 0x5E, 0x64, 0xDF, 0xE9, 0xC3, 0xAC, 0x90, 0x80, 0xC3, 0x32, 0x21, 0x83, 0x62, 0x4A }, { 0x77, 0xF9, 0x41, 0xBD, 0x5C, 0x99, 0xBC, 0x4D, 0xAA, 0x94, 0x6A, 0x5E, 0x6D, 0x15, 0xA3, 0x9E, 0x99, 0xD2, 0xE1, 0xF1, 0xCF, 0x2F, 0xD4, 0x27, 0xC5, 0x2E, 0xC3, 0x16, 0xD8, 0x7E, 0xB0, 0xC0 } }, + { 3, 0, 3, { 0, 1, 2 }, 0, { 0 }, 0, 1, { 0x02, 0x19, 0xF1, 0x79, 0x47, 0xF4, 0x6D, 0xF4, 0x7F, 0xF6, 0x49, 0x82, 0x66, 0x84, 0x0A, 0x3E, 0xB4, 0xEB, 0x3C, 0x00, 0x08, 0x42, 0xA7, 0x7A, 0xFF, 0x62, 0x91, 0x33, 0x25, 0x56, 0x74, 0xC9, 0x2E, 0x03, 0x44, 0xA4, 0x83, 0xE6, 0x3F, 0x20, 0xFF, 0xD0, 0x37, 0xA3, 0xBC, 0xA5, 0x3A, 0xDF, 0x55, 0x25, 0x49, 0xDF, 0x79, 0xD6, 0x4F, 0x3D, 0xCF, 0x89, 0x59, 0x6B, 0x70, 0x37, 0xB8, 0x56, 0xC1, 0xE4 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x03, 0xA1, 0x06, 0x47, 0xD6, 0xB6, 0x1E, 0xF5, 0xCA, 0xF2, 0x7F, 0x4E, 0xC0, 0x71, 0xB1, 0xE7, 0xAC, 0xF4, 0x5E, 0xC2, 0xA5, 0x5F, 0xE6, 0x86, 0xF3, 0x8B, 0x24, 0xFD, 0x7C, 0x36, 0xD5, 0xA2, 0xBF, 0x03, 0x3A, 0xB8, 0x14, 0x15, 0x79, 0x13, 0x49, 0x90, 0x01, 0x87, 0x39, 0x09, 0xDA, 0x78, 0x43, 0xDD, 0xCE, 0xC1, 0x5E, 0x64, 0xDF, 0xE9, 0xC3, 0xAC, 0x90, 0x80, 0xC3, 0x32, 0x21, 0x83, 0x62, 0x4A }, { 0x77, 0xF9, 0x41, 0xBD, 0x5C, 0x99, 0xBC, 0x4D, 0xAA, 0x94, 0x6A, 0x5E, 0x6D, 0x15, 0xA3, 0x9E, 0x99, 0xD2, 0xE1, 0xF1, 0xCF, 0x2F, 0xD4, 0x27, 0xC5, 0x2E, 0xC3, 0x16, 0xD8, 0x7E, 0xB0, 0xC0 } }, + { 3, 0, 3, { 2, 1, 0 }, 1, { 2, 1, 0 }, 0, 1, { 0x02, 0x19, 0xF1, 0x79, 0x47, 0xF4, 0x6D, 0xF4, 0x7F, 0xF6, 0x49, 0x82, 0x66, 0x84, 0x0A, 0x3E, 0xB4, 0xEB, 0x3C, 0x00, 0x08, 0x42, 0xA7, 0x7A, 0xFF, 0x62, 0x91, 0x33, 0x25, 0x56, 0x74, 0xC9, 0x2E, 0x03, 0x44, 0xA4, 0x83, 0xE6, 0x3F, 0x20, 0xFF, 0xD0, 0x37, 0xA3, 0xBC, 0xA5, 0x3A, 0xDF, 0x55, 0x25, 0x49, 0xDF, 0x79, 0xD6, 0x4F, 0x3D, 0xCF, 0x89, 0x59, 0x6B, 0x70, 0x37, 0xB8, 0x56, 0xC1, 0xE4 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x03, 0xA1, 0x06, 0x47, 0xD6, 0xB6, 0x1E, 0xF5, 0xCA, 0xF2, 0x7F, 0x4E, 0xC0, 0x71, 0xB1, 0xE7, 0xAC, 0xF4, 0x5E, 0xC2, 0xA5, 0x5F, 0xE6, 0x86, 0xF3, 0x8B, 0x24, 0xFD, 0x7C, 0x36, 0xD5, 0xA2, 0xBF, 0x03, 0x3A, 0xB8, 0x14, 0x15, 0x79, 0x13, 0x49, 0x90, 0x01, 0x87, 0x39, 0x09, 0xDA, 0x78, 0x43, 0xDD, 0xCE, 0xC1, 0x5E, 0x64, 0xDF, 0xE9, 0xC3, 0xAC, 0x90, 0x80, 0xC3, 0x32, 0x21, 0x83, 0x62, 0x4A }, { 0x77, 0xF9, 0x41, 0xBD, 0x5C, 0x99, 0xBC, 0x4D, 0xAA, 0x94, 0x6A, 0x5E, 0x6D, 0x15, 0xA3, 0x9E, 0x99, 0xD2, 0xE1, 0xF1, 0xCF, 0x2F, 0xD4, 0x27, 0xC5, 0x2E, 0xC3, 0x16, 0xD8, 0x7E, 0xB0, 0xC0 } }, + { 3, 0, 3, { 0, 3, 4 }, 1, { 0, 3, 4 }, 0, 1, { 0x03, 0xBD, 0x60, 0xBB, 0xC5, 0xF2, 0x51, 0xF9, 0x88, 0xDA, 0x82, 0x50, 0x5A, 0x00, 0x25, 0xC0, 0xB2, 0xAC, 0x9D, 0x90, 0xFE, 0x17, 0x08, 0xCD, 0xC6, 0xAF, 0x73, 0xA2, 0xD5, 0x05, 0x12, 0x0F, 0xFA, 0x03, 0x2E, 0xA9, 0x35, 0xA5, 0x97, 0xAE, 0x9A, 0x6F, 0xFA, 0x87, 0x23, 0x8B, 0x5E, 0x5B, 0x19, 0xD9, 0x9B, 0x82, 0xDA, 0xFD, 0x2E, 0x63, 0xFB, 0xDF, 0x79, 0x40, 0x5D, 0x88, 0x04, 0xB0, 0xBE, 0xA5 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x03, 0xF3, 0xBF, 0x16, 0x6F, 0x72, 0x58, 0xAF, 0x83, 0x2B, 0x72, 0xC2, 0xB6, 0x38, 0xC0, 0x71, 0x2E, 0x62, 0xB0, 0x77, 0x7B, 0x79, 0xA0, 0x52, 0xC6, 0xB0, 0xB2, 0xE8, 0x48, 0x47, 0x58, 0x74, 0xB6, 0x03, 0x27, 0xE1, 0x80, 0x06, 0x44, 0x32, 0xD0, 0x55, 0x55, 0x54, 0xBD, 0x18, 0x60, 0x1D, 0x0D, 0xAA, 0xEB, 0x74, 0xA4, 0x92, 0x13, 0xD4, 0x04, 0x93, 0xFB, 0xB7, 0x52, 0xFB, 0x7C, 0x72, 0x0C, 0x27 }, { 0xAC, 0x09, 0x0F, 0xEB, 0x80, 0x83, 0x67, 0x36, 0x84, 0x20, 0x5D, 0xBE, 0x7F, 0xCA, 0x96, 0x0E, 0xE1, 0x7A, 0x9D, 0xBE, 0x83, 0xAE, 0x19, 0x84, 0x5C, 0x2C, 0x3F, 0x13, 0x4F, 0x11, 0x36, 0x49 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 1, { 0x03, 0x70, 0xED, 0xEF, 0xE5, 0xA1, 0x51, 0xF0, 0x30, 0x0A, 0x2D, 0x5B, 0x0D, 0x4D, 0xEB, 0x85, 0x2F, 0xCF, 0xA6, 0xFF, 0x5A, 0x51, 0xC4, 0x9F, 0x2C, 0x16, 0x5C, 0xDC, 0x89, 0x03, 0x9B, 0xAE, 0xA3, 0x02, 0x7E, 0xBD, 0x4C, 0xF5, 0x87, 0x85, 0x4D, 0xFF, 0x6E, 0x7E, 0x54, 0x3A, 0x0F, 0x29, 0x46, 0x10, 0x0E, 0xAF, 0xA0, 0x6B, 0xA7, 0x72, 0x5A, 0x52, 0x74, 0xFB, 0x3F, 0xFF, 0x51, 0xB4, 0x4E, 0x12 }, 0, { 0 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x02, 0xD1, 0xD6, 0x4C, 0xCA, 0x49, 0xF6, 0x17, 0x6E, 0x40, 0x04, 0xA6, 0x13, 0xD7, 0x7B, 0xF1, 0x3C, 0xCC, 0x26, 0x9A, 0xCA, 0x13, 0x1C, 0x30, 0x73, 0x1D, 0x6B, 0x57, 0xEC, 0xD1, 0x6C, 0xDC, 0x35, 0x02, 0x59, 0xC6, 0xBB, 0x03, 0xEE, 0x92, 0xFC, 0x0A, 0xC2, 0x96, 0x6F, 0x7C, 0x07, 0x10, 0xA9, 0xF0, 0x80, 0x96, 0x3F, 0x5C, 0x2D, 0x9D, 0x56, 0x56, 0x79, 0x6D, 0x14, 0x25, 0x5E, 0x33, 0xBB, 0xA4 }, { 0x35, 0x01, 0xAC, 0x7C, 0x95, 0xC3, 0x34, 0xA8, 0xAE, 0xE0, 0x7B, 0x27, 0x9E, 0x89, 0x35, 0x79, 0xD1, 0x38, 0xF7, 0x46, 0x19, 0x79, 0x2C, 0xFA, 0x30, 0xAD, 0x8B, 0x3C, 0x88, 0x74, 0x33, 0x5B } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 1, { 0x02, 0xC5, 0x78, 0xDB, 0x2B, 0xCA, 0x42, 0x88, 0xBA, 0xE8, 0xC8, 0x20, 0xEF, 0xCA, 0xB4, 0x4F, 0x1F, 0x71, 0x00, 0x70, 0x60, 0xAE, 0x30, 0xAB, 0x53, 0x62, 0x6B, 0x85, 0x1E, 0x93, 0xEC, 0x4D, 0x3A, 0x03, 0x7C, 0x5F, 0xB4, 0xE1, 0xAE, 0x08, 0xFC, 0xC4, 0x8C, 0xF4, 0xFE, 0x5A, 0x6A, 0x07, 0xD9, 0xBA, 0xFA, 0x45, 0x0A, 0x83, 0x24, 0x27, 0xC4, 0x9E, 0x4A, 0xC0, 0x7F, 0xBA, 0xFE, 0x03, 0x91, 0xCF }, 1, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x03, 0x29, 0x0D, 0x3A, 0xBE, 0xE3, 0x82, 0x51, 0x28, 0x60, 0x25, 0xA8, 0x48, 0x1C, 0x0E, 0x10, 0x75, 0xB2, 0xFA, 0x0B, 0x0C, 0xA1, 0xDF, 0xFB, 0x5C, 0xA7, 0xBF, 0x29, 0xB6, 0xE4, 0x97, 0x24, 0x1C, 0x02, 0x0A, 0x86, 0x45, 0x2A, 0xDC, 0x52, 0x03, 0x6A, 0xD0, 0x6D, 0x2E, 0x0C, 0xFB, 0x87, 0x04, 0x99, 0x8C, 0x65, 0xAA, 0x7A, 0xE1, 0x30, 0xEF, 0x79, 0xC9, 0xD2, 0x80, 0x5C, 0x56, 0x6B, 0xC5, 0xFA }, { 0x43, 0x51, 0x57, 0x63, 0x42, 0x82, 0xEB, 0x6B, 0x0B, 0x47, 0x28, 0x5C, 0x53, 0x87, 0xAE, 0x7B, 0x7B, 0xE2, 0x4A, 0xE9, 0xB1, 0x66, 0x20, 0xF8, 0x92, 0x94, 0x6A, 0x4E, 0x57, 0x61, 0xF1, 0x8F } }, + { 3, 1, 5, { 0, 1, 2, 3, 4 }, 1, { 0, 1, 2, 3, 4 }, 1, 1, { 0x03, 0x1B, 0x21, 0x16, 0x86, 0x2A, 0x49, 0x07, 0x40, 0xD7, 0x08, 0x2F, 0x47, 0x7A, 0x81, 0xEC, 0x24, 0x10, 0xA6, 0x8C, 0x39, 0xBF, 0xBD, 0x38, 0xB5, 0x09, 0x78, 0xC8, 0x0E, 0x4A, 0x2B, 0xFD, 0x28, 0x02, 0xA7, 0x69, 0xA1, 0xEF, 0x6E, 0xC7, 0x29, 0x5F, 0x19, 0x04, 0x0B, 0xF0, 0x19, 0x3B, 0xD2, 0x16, 0x92, 0x97, 0x72, 0x15, 0xC9, 0xB9, 0x33, 0x2D, 0x18, 0xAD, 0x81, 0x52, 0x05, 0xEE, 0x48, 0x3D }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x02, 0x35, 0x1B, 0xDA, 0x5B, 0xEE, 0xC2, 0x31, 0xE0, 0x94, 0x83, 0x23, 0x7F, 0x67, 0xD7, 0xEA, 0xBC, 0x00, 0x6E, 0x3C, 0x38, 0x6B, 0x6B, 0xF8, 0x30, 0x39, 0x51, 0xEA, 0x14, 0x04, 0x5E, 0x2A, 0xDF, 0x03, 0x0E, 0x49, 0xF3, 0x6C, 0x12, 0xA2, 0x46, 0x7E, 0xE7, 0x77, 0xBF, 0x76, 0xD3, 0xEE, 0xFB, 0xE5, 0x3F, 0xAB, 0x39, 0x9F, 0x0F, 0x5E, 0xB0, 0x8B, 0x9B, 0x89, 0xBD, 0x20, 0xB3, 0x58, 0x62, 0x48 }, { 0xB1, 0x17, 0x2B, 0x0B, 0x6A, 0x77, 0x65, 0x14, 0xBF, 0x08, 0xCA, 0x26, 0xBA, 0x5A, 0xB5, 0xBD, 0x77, 0x7D, 0x75, 0xEC, 0xED, 0x0F, 0x71, 0x11, 0xB4, 0x3B, 0x37, 0x49, 0x97, 0x5E, 0xD2, 0x30 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 1, { 0x02, 0x4C, 0x00, 0xC3, 0x26, 0xA1, 0x9D, 0x4F, 0xD3, 0x50, 0xBD, 0xA2, 0x21, 0x5C, 0x61, 0x06, 0xEA, 0x7F, 0x6E, 0xDB, 0xED, 0x39, 0xFA, 0xCA, 0x84, 0x3D, 0x63, 0xBA, 0x08, 0x18, 0xC2, 0x9B, 0xC1, 0x02, 0xF6, 0x08, 0x01, 0xC2, 0xF5, 0x3C, 0xAA, 0x17, 0xA3, 0x17, 0x88, 0x27, 0xBF, 0xE5, 0x42, 0x27, 0x91, 0x05, 0x48, 0xC5, 0x76, 0x3F, 0x41, 0x28, 0xAC, 0xE9, 0x8B, 0x35, 0xF5, 0xDB, 0x92, 0x0E }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, { }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x02, 0xC5, 0x3E, 0xF9, 0x4A, 0x81, 0xC7, 0x40, 0x95, 0x99, 0x54, 0xBA, 0x92, 0x11, 0x26, 0x38, 0xEA, 0x9F, 0x2F, 0xAA, 0x82, 0xA5, 0x21, 0x41, 0x24, 0x62, 0x75, 0xEF, 0x91, 0xEC, 0x6C, 0x6B, 0xFB, 0x02, 0x07, 0xB2, 0x51, 0xCE, 0xB4, 0x04, 0x5F, 0xBB, 0xBF, 0x6D, 0x64, 0xA8, 0x5A, 0x06, 0xFD, 0xB9, 0xDE, 0x2B, 0x79, 0xF9, 0x59, 0x9E, 0x4E, 0x1C, 0xA9, 0x61, 0x73, 0x79, 0x71, 0x3A, 0x5E, 0xBA }, { 0x87, 0x38, 0xB6, 0x1B, 0x41, 0xAB, 0x6D, 0x99, 0xDF, 0x70, 0x44, 0x9E, 0x77, 0x34, 0x87, 0xF4, 0x99, 0x29, 0x41, 0x9C, 0xAC, 0x6D, 0x98, 0x24, 0x19, 0x8E, 0x6D, 0xBB, 0xE9, 0x10, 0x5A, 0x6D } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 1, { 0x03, 0x95, 0x09, 0xDF, 0xFF, 0x34, 0xC4, 0x53, 0x69, 0x58, 0x55, 0x73, 0x01, 0xE5, 0x0B, 0xA8, 0xF4, 0x6E, 0xEA, 0x1C, 0xC9, 0xC3, 0xAF, 0x05, 0x43, 0xF7, 0x48, 0xF2, 0x28, 0x76, 0x66, 0xF0, 0xF4, 0x03, 0x86, 0x59, 0xDC, 0x10, 0x74, 0x36, 0xBD, 0x5C, 0xAC, 0xC6, 0x01, 0x9D, 0xE0, 0xDD, 0xB6, 0xFA, 0xA1, 0x76, 0x2D, 0x9A, 0xC0, 0x1A, 0x0A, 0x8C, 0xE7, 0x92, 0xED, 0xB5, 0xA1, 0x7C, 0x4C, 0xE0 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 38, { 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26 }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_NONE, -1, { 0x02, 0x98, 0xA8, 0x25, 0x47, 0x93, 0x99, 0x6B, 0x39, 0x88, 0x03, 0x89, 0xEA, 0xC2, 0x1A, 0x24, 0xE6, 0x98, 0xBD, 0x5F, 0x72, 0x3E, 0x83, 0x85, 0x7E, 0xB8, 0x92, 0x6D, 0xFF, 0xF2, 0x2B, 0x10, 0xA9, 0x02, 0x4B, 0x32, 0xBC, 0x14, 0xA4, 0x8B, 0x2E, 0x7B, 0x2C, 0xDE, 0xBA, 0x20, 0x7C, 0x77, 0xE3, 0x4E, 0xC8, 0xEB, 0x39, 0x4C, 0x34, 0xD1, 0xF9, 0x64, 0x08, 0x13, 0x59, 0x6F, 0xB5, 0xF9, 0x96, 0x1A }, { 0x46, 0x97, 0x66, 0x42, 0x16, 0x1A, 0xD5, 0x52, 0x23, 0xAB, 0x36, 0xBF, 0x70, 0x60, 0xE2, 0x14, 0xCA, 0x3F, 0x75, 0x9A, 0xC1, 0xC4, 0xAE, 0x63, 0xA0, 0x25, 0xC9, 0x50, 0xD0, 0x48, 0xD4, 0x09 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 1, { 0x02, 0x19, 0xF1, 0x79, 0x47, 0xF4, 0x6D, 0xF4, 0x7F, 0xF6, 0x49, 0x82, 0x66, 0x84, 0x0A, 0x3E, 0xB4, 0xEB, 0x3C, 0x00, 0x08, 0x42, 0xA7, 0x7A, 0xFF, 0x62, 0x91, 0x33, 0x25, 0x56, 0x74, 0xC9, 0x2E, 0x03, 0x44, 0xA4, 0x83, 0xE6, 0x3F, 0x20, 0xFF, 0xD0, 0x37, 0xA3, 0xBC, 0xA5, 0x3A, 0xDF, 0x55, 0x25, 0x49, 0xDF, 0x79, 0xD6, 0x4F, 0x3D, 0xCF, 0x89, 0x59, 0x6B, 0x70, 0x37, 0xB8, 0x56, 0xC1, 0xE4 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { { 0xE8, 0xF7, 0x91, 0xFF, 0x92, 0x25, 0xA2, 0xAF, 0x01, 0x02, 0xAF, 0xFF, 0x4A, 0x9A, 0x72, 0x3D, 0x96, 0x12, 0xA6, 0x82, 0xA2, 0x5E, 0xBE, 0x79, 0x80, 0x2B, 0x26, 0x3C, 0xDF, 0xCD, 0x83, 0xBB } }, { 1 }, FROST_VEC_ERR_NONE, -1, { 0x03, 0x10, 0xB1, 0x4C, 0xBD, 0xD8, 0xE9, 0x31, 0x94, 0x42, 0xC2, 0x39, 0x35, 0x3A, 0xC2, 0x4A, 0xD6, 0x98, 0xC6, 0x02, 0x88, 0x87, 0x9A, 0xDA, 0xD3, 0x57, 0xBF, 0x4A, 0xCD, 0x4A, 0x7C, 0x8D, 0xB7, 0x02, 0x90, 0xD0, 0x19, 0x9D, 0x6C, 0x7B, 0xA8, 0xA3, 0xD7, 0x24, 0x62, 0xD9, 0xAA, 0xB7, 0x01, 0x50, 0xBE, 0x92, 0xE5, 0x4F, 0xD0, 0x31, 0xED, 0xE2, 0x11, 0x67, 0x25, 0x94, 0x4C, 0x1C, 0x07, 0xB7 }, { 0xA3, 0x5B, 0x8A, 0x18, 0x3F, 0xA7, 0x09, 0xA8, 0x74, 0xD5, 0xC0, 0x90, 0x60, 0x0A, 0xF1, 0xE8, 0x6F, 0xF6, 0x92, 0x5C, 0x13, 0x94, 0x1B, 0xF0, 0xC0, 0x71, 0x01, 0x3E, 0xAA, 0x52, 0x77, 0xF9 } }, +}; +static const struct frost_vec_det_sign_case frost_vec_det_sign_error_cases[48] = { + { 0, 2, 2, { 0, 1 }, 1, { 0, 1 }, 0, 1, { 0x02, 0xDF, 0x47, 0xC4, 0xDC, 0x15, 0xF4, 0x25, 0xFD, 0x45, 0x0E, 0x42, 0x07, 0x72, 0xF6, 0x3C, 0x51, 0x05, 0x48, 0xE0, 0x12, 0xE3, 0xFE, 0x5E, 0xC4, 0x20, 0xC7, 0xE3, 0x12, 0xEB, 0x05, 0xC4, 0xFA, 0x03, 0x73, 0x7C, 0x76, 0x98, 0x5C, 0xBF, 0x3E, 0x8D, 0x55, 0x1E, 0xD1, 0x95, 0x7C, 0x6B, 0x2E, 0x71, 0x7E, 0x4A, 0xAB, 0xB8, 0xFF, 0x0A, 0xFF, 0x52, 0xA1, 0x64, 0xB4, 0x56, 0x04, 0x38, 0xA9, 0x14 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, + { 0, 0, 3, { 0, 1, 1 }, 1, { 0, 1, 1 }, 0, 1, { 0x03, 0xCD, 0x1C, 0x89, 0xD4, 0x0F, 0xD1, 0x41, 0x92, 0x73, 0x8E, 0x39, 0xF3, 0x10, 0xC8, 0x8D, 0x32, 0xD2, 0xA6, 0x25, 0x01, 0x77, 0xE1, 0xE5, 0x74, 0xDF, 0xEA, 0x2C, 0xCF, 0xF3, 0x87, 0x6C, 0xF3, 0x02, 0x68, 0xB2, 0xF8, 0x2F, 0xB6, 0x18, 0x94, 0x08, 0xF1, 0x78, 0x9A, 0xDC, 0x08, 0xCE, 0x92, 0x74, 0x41, 0x45, 0x15, 0x2E, 0xCC, 0x54, 0xDD, 0xD9, 0xB8, 0xF9, 0x4E, 0xF6, 0x54, 0xD8, 0xC1, 0x9A }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, + { 0, 1, 2, { 1, 2 }, 1, { 1, 2 }, 0, 1, { 0x03, 0xA1, 0x20, 0xB3, 0x53, 0x16, 0x94, 0x5A, 0x5E, 0xB2, 0x2B, 0x30, 0x9A, 0x90, 0x88, 0xED, 0xED, 0xFC, 0xF4, 0x5C, 0x6C, 0xED, 0x2D, 0xDF, 0x15, 0x36, 0x61, 0xCB, 0x76, 0x66, 0x03, 0x1B, 0x86, 0x03, 0x4A, 0x04, 0xD6, 0xC3, 0x4C, 0x51, 0xF8, 0x1B, 0xFD, 0x9A, 0xDA, 0xC2, 0x09, 0x06, 0xDF, 0xCC, 0x77, 0x98, 0x21, 0x08, 0x72, 0x02, 0x0B, 0xF2, 0xAD, 0x0F, 0x52, 0x88, 0x7D, 0x60, 0x26, 0x23 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 3 }, 0, 1, { 0x03, 0xB5, 0x62, 0x3D, 0xAC, 0x86, 0xC6, 0x14, 0x52, 0x56, 0x8A, 0x33, 0x51, 0xC9, 0xBF, 0x29, 0xE4, 0xB9, 0x68, 0x93, 0x38, 0xD2, 0xA9, 0x6E, 0x09, 0x90, 0x30, 0x6C, 0x9F, 0xFE, 0x6A, 0x64, 0x0A, 0x03, 0x46, 0x72, 0xC9, 0x29, 0xA9, 0x54, 0xE0, 0x4F, 0x10, 0x9C, 0x90, 0xEC, 0x41, 0x57, 0x90, 0xD8, 0x46, 0x3C, 0x8A, 0x43, 0xA8, 0x4A, 0xBE, 0x39, 0xCC, 0x30, 0x2E, 0x07, 0x29, 0x9D, 0x95, 0xE0 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_PUBSHARE_PARSE, 1, { 0 }, { 0 } }, + { 0, 1, 2, { 3, 1 }, 1, { 0, 1 }, 1, 1, { 0x03, 0x3F, 0x62, 0x52, 0xCA, 0xDE, 0x1A, 0xB6, 0x42, 0xBC, 0x9B, 0xF9, 0xD3, 0xCC, 0x15, 0x27, 0x7A, 0x87, 0x3D, 0x6C, 0xF5, 0x65, 0x49, 0xF4, 0x4D, 0x35, 0xB5, 0x0F, 0xE1, 0x5C, 0x00, 0xC2, 0x4E, 0x02, 0x21, 0x2B, 0x52, 0x10, 0x94, 0x36, 0x85, 0x53, 0x02, 0x20, 0x50, 0x14, 0x04, 0xDF, 0x3B, 0xD8, 0x91, 0xC2, 0x64, 0xE4, 0xDE, 0xF9, 0x90, 0xF3, 0x37, 0x87, 0xEA, 0x66, 0x30, 0xBC, 0x2A, 0xFC }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, + { 0, 0, 2, { 0, 1 }, 1, { 1, 0 }, 0, 1, { 0x03, 0xB5, 0x62, 0x3D, 0xAC, 0x86, 0xC6, 0x14, 0x52, 0x56, 0x8A, 0x33, 0x51, 0xC9, 0xBF, 0x29, 0xE4, 0xB9, 0x68, 0x93, 0x38, 0xD2, 0xA9, 0x6E, 0x09, 0x90, 0x30, 0x6C, 0x9F, 0xFE, 0x6A, 0x64, 0x0A, 0x03, 0x46, 0x72, 0xC9, 0x29, 0xA9, 0x54, 0xE0, 0x4F, 0x10, 0x9C, 0x90, 0xEC, 0x41, 0x57, 0x90, 0xD8, 0x46, 0x3C, 0x8A, 0x43, 0xA8, 0x4A, 0xBE, 0x39, 0xCC, 0x30, 0x2E, 0x07, 0x29, 0x9D, 0x95, 0xE0 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 1, { 0x04, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x03, 0x74, 0x96, 0xA3, 0xCC, 0x86, 0x92, 0x6D, 0x45, 0x2C, 0xAF, 0xCF, 0xD5, 0x5D, 0x25, 0x97, 0x2C, 0xA1, 0x67, 0x5D, 0x54, 0x93, 0x10, 0xDE, 0x29, 0x6B, 0xFF, 0x42, 0xF7, 0x2E, 0xEE, 0xA8, 0xC9 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_AGGOTHERNONCE, -1, { 0 }, { 0 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x87, 0xBF, 0x89, 0x1D, 0x2A, 0x6D, 0xEA, 0xEB, 0xAD, 0xC9, 0x09, 0x35, 0x2A, 0xA9, 0x40, 0x5D, 0x14, 0x28, 0xC1, 0x5F, 0x4B, 0x75, 0xF0, 0x4D, 0xAE, 0x64, 0x2A, 0x95, 0xC2, 0x54, 0x84, 0x80 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_AGGOTHERNONCE, -1, { 0 }, { 0 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 1, { 0x03, 0x53, 0xBC, 0x23, 0x14, 0xD4, 0x6C, 0x81, 0x3A, 0xF8, 0x13, 0x17, 0xAF, 0x1B, 0xDF, 0x99, 0x81, 0x6B, 0x64, 0x44, 0xE4, 0x16, 0xBB, 0x8D, 0x3D, 0xC0, 0x4A, 0xCB, 0x2F, 0x53, 0x88, 0xD1, 0xAC, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_AGGOTHERNONCE, -1, { 0 }, { 0 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 1, { 0x03, 0x53, 0xBC, 0x23, 0x14, 0xD4, 0x6C, 0x81, 0x3A, 0xF8, 0x13, 0x17, 0xAF, 0x1B, 0xDF, 0x99, 0x81, 0x6B, 0x64, 0x44, 0xE4, 0x16, 0xBB, 0x8D, 0x3D, 0xC0, 0x4A, 0xCB, 0x2F, 0x53, 0x88, 0xD1, 0xAC, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x30 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_AGGOTHERNONCE, -1, { 0 }, { 0 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 1, { 0x03, 0xB5, 0x62, 0x3D, 0xAC, 0x86, 0xC6, 0x14, 0x52, 0x56, 0x8A, 0x33, 0x51, 0xC9, 0xBF, 0x29, 0xE4, 0xB9, 0x68, 0x93, 0x38, 0xD2, 0xA9, 0x6E, 0x09, 0x90, 0x30, 0x6C, 0x9F, 0xFE, 0x6A, 0x64, 0x0A, 0x03, 0x46, 0x72, 0xC9, 0x29, 0xA9, 0x54, 0xE0, 0x4F, 0x10, 0x9C, 0x90, 0xEC, 0x41, 0x57, 0x90, 0xD8, 0x46, 0x3C, 0x8A, 0x43, 0xA8, 0x4A, 0xBE, 0x39, 0xCC, 0x30, 0x2E, 0x07, 0x29, 0x9D, 0x95, 0xE0 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 } }, { 0 }, FROST_VEC_ERR_TWEAK_ADD, -1, { 0 }, { 0 } }, + { 0, 0, 1, { 0 }, 1, { 0 }, 0, 0, { 0 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, + { 0, 0, 2, { 0, 1 }, 1, { 0, 1 }, 3, 1, { 0x03, 0xB5, 0x62, 0x3D, 0xAC, 0x86, 0xC6, 0x14, 0x52, 0x56, 0x8A, 0x33, 0x51, 0xC9, 0xBF, 0x29, 0xE4, 0xB9, 0x68, 0x93, 0x38, 0xD2, 0xA9, 0x6E, 0x09, 0x90, 0x30, 0x6C, 0x9F, 0xFE, 0x6A, 0x64, 0x0A, 0x03, 0x46, 0x72, 0xC9, 0x29, 0xA9, 0x54, 0xE0, 0x4F, 0x10, 0x9C, 0x90, 0xEC, 0x41, 0x57, 0x90, 0xD8, 0x46, 0x3C, 0x8A, 0x43, 0xA8, 0x4A, 0xBE, 0x39, 0xCC, 0x30, 0x2E, 0x07, 0x29, 0x9D, 0x95, 0xE0 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, + { 1, 1, 1, { 0 }, 1, { 0 }, 0, 1, { 0x03, 0xBF, 0x06, 0x14, 0x9B, 0x3E, 0x61, 0x44, 0x03, 0xEA, 0x89, 0x9F, 0x37, 0x44, 0x6B, 0x29, 0x41, 0x17, 0x78, 0x5D, 0x15, 0xD2, 0x38, 0xE1, 0xE3, 0x69, 0x89, 0xF2, 0x94, 0x12, 0x02, 0x00, 0xA2, 0x03, 0x29, 0x62, 0x0E, 0xA3, 0x31, 0xF7, 0x04, 0x50, 0xB9, 0x4A, 0x7F, 0x6B, 0x17, 0x5C, 0xF7, 0xC5, 0xA6, 0x5C, 0xD9, 0x67, 0xD3, 0x67, 0x33, 0x2A, 0xFD, 0x4C, 0x6F, 0xE5, 0x14, 0x88, 0x24, 0x67 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, + { 1, 0, 3, { 0, 1, 1 }, 1, { 0, 1, 1 }, 0, 1, { 0x02, 0xBC, 0x6B, 0x50, 0xC4, 0x47, 0x3E, 0xDA, 0x59, 0x93, 0x39, 0xE7, 0x6D, 0x9F, 0x1E, 0x4A, 0x97, 0x0B, 0xB1, 0x9B, 0x25, 0x1E, 0xAD, 0xE8, 0x38, 0xC6, 0xAD, 0xF9, 0x03, 0x47, 0xC7, 0xA1, 0x45, 0x03, 0x29, 0x43, 0x35, 0x96, 0x23, 0x73, 0xC7, 0x2A, 0x43, 0x3F, 0x05, 0xB4, 0x92, 0x1A, 0x74, 0x31, 0x6D, 0xF9, 0xFE, 0x84, 0x99, 0x9B, 0xEA, 0x55, 0xB2, 0x8E, 0xF4, 0xCD, 0x83, 0x63, 0x8F, 0xC6 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, + { 1, 0, 2, { 0, 1 }, 1, { 0, 3 }, 0, 1, { 0x03, 0xBF, 0x06, 0x14, 0x9B, 0x3E, 0x61, 0x44, 0x03, 0xEA, 0x89, 0x9F, 0x37, 0x44, 0x6B, 0x29, 0x41, 0x17, 0x78, 0x5D, 0x15, 0xD2, 0x38, 0xE1, 0xE3, 0x69, 0x89, 0xF2, 0x94, 0x12, 0x02, 0x00, 0xA2, 0x03, 0x29, 0x62, 0x0E, 0xA3, 0x31, 0xF7, 0x04, 0x50, 0xB9, 0x4A, 0x7F, 0x6B, 0x17, 0x5C, 0xF7, 0xC5, 0xA6, 0x5C, 0xD9, 0x67, 0xD3, 0x67, 0x33, 0x2A, 0xFD, 0x4C, 0x6F, 0xE5, 0x14, 0x88, 0x24, 0x67 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_PUBSHARE_PARSE, 1, { 0 }, { 0 } }, + { 1, 0, 1, { 3 }, 1, { 0 }, 0, 1, { 0x03, 0xB1, 0x9C, 0x94, 0xC4, 0xB6, 0x53, 0x70, 0x08, 0xFF, 0xF0, 0x18, 0x97, 0x1B, 0x31, 0x1B, 0xF3, 0x0B, 0x1B, 0xAB, 0x5F, 0x89, 0x83, 0xA5, 0xB2, 0x62, 0xD0, 0xCD, 0x37, 0xCB, 0xD3, 0x09, 0x20, 0x03, 0x29, 0xA0, 0x28, 0xAD, 0xEF, 0x6A, 0xB3, 0x0E, 0x66, 0x71, 0x23, 0xE8, 0x2D, 0xFB, 0x1B, 0xB0, 0x55, 0xF3, 0x80, 0xD0, 0xCD, 0xD5, 0xCD, 0xBF, 0x4A, 0xDC, 0xB1, 0x06, 0x73, 0x98, 0xF5, 0x58 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, + { 1, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 1, { 0x04, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x03, 0x74, 0x96, 0xA3, 0xCC, 0x86, 0x92, 0x6D, 0x45, 0x2C, 0xAF, 0xCF, 0xD5, 0x5D, 0x25, 0x97, 0x2C, 0xA1, 0x67, 0x5D, 0x54, 0x93, 0x10, 0xDE, 0x29, 0x6B, 0xFF, 0x42, 0xF7, 0x2E, 0xEE, 0xA8, 0xC9 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_AGGOTHERNONCE, -1, { 0 }, { 0 } }, + { 1, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x87, 0xBF, 0x89, 0x1D, 0x2A, 0x6D, 0xEA, 0xEB, 0xAD, 0xC9, 0x09, 0x35, 0x2A, 0xA9, 0x40, 0x5D, 0x14, 0x28, 0xC1, 0x5F, 0x4B, 0x75, 0xF0, 0x4D, 0xAE, 0x64, 0x2A, 0x95, 0xC2, 0x54, 0x84, 0x80 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_AGGOTHERNONCE, -1, { 0 }, { 0 } }, + { 1, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 1, { 0x03, 0x53, 0xBC, 0x23, 0x14, 0xD4, 0x6C, 0x81, 0x3A, 0xF8, 0x13, 0x17, 0xAF, 0x1B, 0xDF, 0x99, 0x81, 0x6B, 0x64, 0x44, 0xE4, 0x16, 0xBB, 0x8D, 0x3D, 0xC0, 0x4A, 0xCB, 0x2F, 0x53, 0x88, 0xD1, 0xAC, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_AGGOTHERNONCE, -1, { 0 }, { 0 } }, + { 1, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 1, { 0x03, 0x53, 0xBC, 0x23, 0x14, 0xD4, 0x6C, 0x81, 0x3A, 0xF8, 0x13, 0x17, 0xAF, 0x1B, 0xDF, 0x99, 0x81, 0x6B, 0x64, 0x44, 0xE4, 0x16, 0xBB, 0x8D, 0x3D, 0xC0, 0x4A, 0xCB, 0x2F, 0x53, 0x88, 0xD1, 0xAC, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x30 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_AGGOTHERNONCE, -1, { 0 }, { 0 } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 0, 0, { 0 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 } }, { 0 }, FROST_VEC_ERR_TWEAK_ADD, -1, { 0 }, { 0 } }, + { 1, 0, 0, { 0 }, 1, { 0 }, 0, 0, { 0 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, + { 1, 0, 1, { 0 }, 1, { 0 }, 3, 0, { 0 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, + { 2, 0, 3, { 0, 1, 1 }, 1, { 0, 1, 1 }, 0, 1, { 0x03, 0x78, 0x98, 0x00, 0x8E, 0xFD, 0xB2, 0xDF, 0x4E, 0xC5, 0xD9, 0x90, 0xA7, 0x46, 0x1F, 0xBC, 0x51, 0xB9, 0xD3, 0x5E, 0x6F, 0x9F, 0x06, 0xF2, 0x42, 0x4F, 0x77, 0xF7, 0x4D, 0x0D, 0xB6, 0xC4, 0x94, 0x02, 0xA1, 0x95, 0x84, 0x75, 0xAE, 0x70, 0x73, 0xDB, 0xE8, 0xC6, 0x99, 0xA4, 0x1B, 0xD5, 0x43, 0xDD, 0x10, 0x26, 0x71, 0xA7, 0xCD, 0xBC, 0x12, 0x41, 0xC4, 0xF6, 0x13, 0xD1, 0x38, 0x65, 0xA7, 0xE1 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 3, 2 }, 0, 1, { 0x03, 0x32, 0xB7, 0xFB, 0xB7, 0xF9, 0xA1, 0x6A, 0xD4, 0x07, 0x3F, 0xF4, 0x82, 0xBF, 0x6F, 0x77, 0xA2, 0x94, 0x30, 0x99, 0xFA, 0x5C, 0x2B, 0x69, 0x1C, 0xA9, 0x00, 0x2C, 0x39, 0xEC, 0x72, 0x49, 0xF3, 0x03, 0x0F, 0xB4, 0xD9, 0xD5, 0xD7, 0x4D, 0x2D, 0xEE, 0xDB, 0xA7, 0x7E, 0xD1, 0xF1, 0x6E, 0xF2, 0x77, 0x76, 0x9A, 0x12, 0xF5, 0x71, 0x17, 0xEA, 0x0A, 0x0B, 0x99, 0x99, 0x05, 0xFB, 0x0A, 0x04, 0x2C }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_PUBSHARE_PARSE, 1, { 0 }, { 0 } }, + { 2, 1, 3, { 3, 1, 2 }, 1, { 0, 1, 2 }, 1, 1, { 0x03, 0x7F, 0xF9, 0xB8, 0xD6, 0x9E, 0x03, 0x3F, 0x05, 0x48, 0x4D, 0x8B, 0x6F, 0x3F, 0x12, 0x54, 0x52, 0x87, 0x65, 0x85, 0x02, 0x18, 0xBE, 0x9D, 0x6D, 0x43, 0x88, 0x64, 0xD6, 0x1D, 0x87, 0x94, 0xC6, 0x02, 0x9D, 0xEB, 0x09, 0x8F, 0x8F, 0xD6, 0x7D, 0x8C, 0x00, 0x6D, 0x68, 0x6A, 0x64, 0x21, 0x76, 0xB7, 0xE5, 0x60, 0xCB, 0xD6, 0xF1, 0x35, 0x6E, 0x45, 0x4A, 0x5E, 0x93, 0xB2, 0xCE, 0x65, 0x96, 0x09 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 2, 1 }, 0, 1, { 0x03, 0x32, 0xB7, 0xFB, 0xB7, 0xF9, 0xA1, 0x6A, 0xD4, 0x07, 0x3F, 0xF4, 0x82, 0xBF, 0x6F, 0x77, 0xA2, 0x94, 0x30, 0x99, 0xFA, 0x5C, 0x2B, 0x69, 0x1C, 0xA9, 0x00, 0x2C, 0x39, 0xEC, 0x72, 0x49, 0xF3, 0x03, 0x0F, 0xB4, 0xD9, 0xD5, 0xD7, 0x4D, 0x2D, 0xEE, 0xDB, 0xA7, 0x7E, 0xD1, 0xF1, 0x6E, 0xF2, 0x77, 0x76, 0x9A, 0x12, 0xF5, 0x71, 0x17, 0xEA, 0x0A, 0x0B, 0x99, 0x99, 0x05, 0xFB, 0x0A, 0x04, 0x2C }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 1, { 0x04, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x03, 0x74, 0x96, 0xA3, 0xCC, 0x86, 0x92, 0x6D, 0x45, 0x2C, 0xAF, 0xCF, 0xD5, 0x5D, 0x25, 0x97, 0x2C, 0xA1, 0x67, 0x5D, 0x54, 0x93, 0x10, 0xDE, 0x29, 0x6B, 0xFF, 0x42, 0xF7, 0x2E, 0xEE, 0xA8, 0xC9 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_AGGOTHERNONCE, -1, { 0 }, { 0 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x87, 0xBF, 0x89, 0x1D, 0x2A, 0x6D, 0xEA, 0xEB, 0xAD, 0xC9, 0x09, 0x35, 0x2A, 0xA9, 0x40, 0x5D, 0x14, 0x28, 0xC1, 0x5F, 0x4B, 0x75, 0xF0, 0x4D, 0xAE, 0x64, 0x2A, 0x95, 0xC2, 0x54, 0x84, 0x80 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_AGGOTHERNONCE, -1, { 0 }, { 0 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 1, { 0x03, 0x53, 0xBC, 0x23, 0x14, 0xD4, 0x6C, 0x81, 0x3A, 0xF8, 0x13, 0x17, 0xAF, 0x1B, 0xDF, 0x99, 0x81, 0x6B, 0x64, 0x44, 0xE4, 0x16, 0xBB, 0x8D, 0x3D, 0xC0, 0x4A, 0xCB, 0x2F, 0x53, 0x88, 0xD1, 0xAC, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_AGGOTHERNONCE, -1, { 0 }, { 0 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 1, { 0x03, 0x53, 0xBC, 0x23, 0x14, 0xD4, 0x6C, 0x81, 0x3A, 0xF8, 0x13, 0x17, 0xAF, 0x1B, 0xDF, 0x99, 0x81, 0x6B, 0x64, 0x44, 0xE4, 0x16, 0xBB, 0x8D, 0x3D, 0xC0, 0x4A, 0xCB, 0x2F, 0x53, 0x88, 0xD1, 0xAC, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x30 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_AGGOTHERNONCE, -1, { 0 }, { 0 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 1, { 0x03, 0x32, 0xB7, 0xFB, 0xB7, 0xF9, 0xA1, 0x6A, 0xD4, 0x07, 0x3F, 0xF4, 0x82, 0xBF, 0x6F, 0x77, 0xA2, 0x94, 0x30, 0x99, 0xFA, 0x5C, 0x2B, 0x69, 0x1C, 0xA9, 0x00, 0x2C, 0x39, 0xEC, 0x72, 0x49, 0xF3, 0x03, 0x0F, 0xB4, 0xD9, 0xD5, 0xD7, 0x4D, 0x2D, 0xEE, 0xDB, 0xA7, 0x7E, 0xD1, 0xF1, 0x6E, 0xF2, 0x77, 0x76, 0x9A, 0x12, 0xF5, 0x71, 0x17, 0xEA, 0x0A, 0x0B, 0x99, 0x99, 0x05, 0xFB, 0x0A, 0x04, 0x2C }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 } }, { 0 }, FROST_VEC_ERR_TWEAK_ADD, -1, { 0 }, { 0 } }, + { 2, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 1, { 0x02, 0xEF, 0x35, 0x29, 0x23, 0xD0, 0xB4, 0x76, 0x87, 0x32, 0xA3, 0x80, 0x31, 0x5C, 0x00, 0x96, 0x0A, 0x71, 0xDA, 0x1F, 0xAB, 0x06, 0xD7, 0xCF, 0x3B, 0x44, 0x03, 0x85, 0x08, 0x4E, 0x3F, 0xAC, 0x2F, 0x02, 0x14, 0x13, 0x28, 0xA4, 0x20, 0xCA, 0x79, 0x16, 0x71, 0x1C, 0xC3, 0xB4, 0x09, 0x81, 0xB9, 0x34, 0x23, 0x77, 0xFC, 0x75, 0xFB, 0x8F, 0xEF, 0x29, 0xD4, 0xD3, 0xBC, 0x71, 0x14, 0x8A, 0x40, 0x82 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, + { 2, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 3, 1, { 0x03, 0x32, 0xB7, 0xFB, 0xB7, 0xF9, 0xA1, 0x6A, 0xD4, 0x07, 0x3F, 0xF4, 0x82, 0xBF, 0x6F, 0x77, 0xA2, 0x94, 0x30, 0x99, 0xFA, 0x5C, 0x2B, 0x69, 0x1C, 0xA9, 0x00, 0x2C, 0x39, 0xEC, 0x72, 0x49, 0xF3, 0x03, 0x0F, 0xB4, 0xD9, 0xD5, 0xD7, 0x4D, 0x2D, 0xEE, 0xDB, 0xA7, 0x7E, 0xD1, 0xF1, 0x6E, 0xF2, 0x77, 0x76, 0x9A, 0x12, 0xF5, 0x71, 0x17, 0xEA, 0x0A, 0x0B, 0x99, 0x99, 0x05, 0xFB, 0x0A, 0x04, 0x2C }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, + { 3, 3, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 1, { 0x02, 0x6F, 0xA8, 0xA1, 0xE9, 0x64, 0x58, 0xEF, 0x85, 0x24, 0x50, 0x11, 0x68, 0x77, 0x18, 0x88, 0x0B, 0xD4, 0x74, 0xA2, 0x43, 0x36, 0x18, 0x43, 0x7E, 0xD6, 0x7A, 0xBA, 0xF2, 0xD1, 0x2C, 0x5A, 0x6A, 0x03, 0x18, 0x3F, 0x17, 0x77, 0xED, 0x74, 0x34, 0xF0, 0x24, 0x21, 0xF8, 0x39, 0x15, 0x97, 0x73, 0x61, 0x24, 0xD3, 0xEC, 0x38, 0xB2, 0x1C, 0x98, 0xF1, 0xFF, 0x5F, 0x01, 0xA5, 0xB4, 0xBE, 0x19, 0x6F }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, + { 3, 0, 3, { 0, 1, 1 }, 1, { 0, 1, 1 }, 0, 1, { 0x02, 0xDB, 0x1A, 0xFD, 0xB6, 0x9C, 0xAB, 0x66, 0xCD, 0xBE, 0x9D, 0xD4, 0x5F, 0x04, 0x87, 0xE5, 0x1E, 0x72, 0x23, 0x8F, 0x1E, 0x2F, 0xA6, 0xF1, 0xC4, 0x68, 0xE1, 0x91, 0x53, 0xC5, 0x38, 0x11, 0x5B, 0x02, 0x6B, 0xA7, 0xF8, 0x1D, 0xFD, 0x36, 0xE6, 0x78, 0x79, 0x62, 0xFC, 0xA7, 0x6C, 0x75, 0x4B, 0x54, 0xB0, 0x2B, 0xB3, 0xBF, 0x31, 0x43, 0x13, 0xD2, 0x18, 0x92, 0x14, 0xFA, 0xEF, 0xF7, 0xE7, 0x24 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, + { 3, 1, 3, { 1, 2, 3 }, 1, { 1, 2, 3 }, 0, 1, { 0x03, 0xCC, 0x8D, 0x9E, 0x20, 0x0D, 0xF6, 0xC7, 0x35, 0xAD, 0x17, 0x92, 0x21, 0xFF, 0x44, 0x25, 0xB0, 0x07, 0x44, 0x55, 0x6C, 0x77, 0xBA, 0x0A, 0x89, 0xE6, 0xDD, 0x71, 0x0E, 0x11, 0x03, 0x68, 0x60, 0x02, 0xF8, 0xDB, 0x24, 0x17, 0xFA, 0xA2, 0xFF, 0x76, 0x96, 0x32, 0x20, 0x94, 0x47, 0x1D, 0xEF, 0x93, 0x52, 0xA8, 0xDE, 0x60, 0x1B, 0x3E, 0xA2, 0x67, 0xA5, 0x90, 0x89, 0xB4, 0x9A, 0x4C, 0x29, 0x4A }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 5, 2 }, 0, 1, { 0x02, 0x19, 0xF1, 0x79, 0x47, 0xF4, 0x6D, 0xF4, 0x7F, 0xF6, 0x49, 0x82, 0x66, 0x84, 0x0A, 0x3E, 0xB4, 0xEB, 0x3C, 0x00, 0x08, 0x42, 0xA7, 0x7A, 0xFF, 0x62, 0x91, 0x33, 0x25, 0x56, 0x74, 0xC9, 0x2E, 0x03, 0x44, 0xA4, 0x83, 0xE6, 0x3F, 0x20, 0xFF, 0xD0, 0x37, 0xA3, 0xBC, 0xA5, 0x3A, 0xDF, 0x55, 0x25, 0x49, 0xDF, 0x79, 0xD6, 0x4F, 0x3D, 0xCF, 0x89, 0x59, 0x6B, 0x70, 0x37, 0xB8, 0x56, 0xC1, 0xE4 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_PUBSHARE_PARSE, 1, { 0 }, { 0 } }, + { 3, 1, 3, { 5, 1, 2 }, 1, { 0, 1, 2 }, 1, 1, { 0x03, 0x5C, 0xDD, 0x6D, 0x23, 0x63, 0xEA, 0x4A, 0xE8, 0xD2, 0xEB, 0x92, 0xA7, 0x8B, 0x3B, 0x9E, 0x74, 0x1D, 0xEA, 0x06, 0x54, 0xDD, 0x22, 0x07, 0x06, 0xB1, 0xA0, 0x56, 0x64, 0xE6, 0xB4, 0xF7, 0xFE, 0x02, 0xC9, 0xF9, 0xFA, 0x09, 0x82, 0x81, 0x8E, 0x3F, 0xE7, 0x55, 0xF7, 0x8D, 0x74, 0x0A, 0x8A, 0x07, 0xFE, 0x1F, 0xB5, 0xA0, 0xCF, 0x25, 0x33, 0x89, 0xA7, 0x55, 0x33, 0xED, 0x6A, 0x03, 0x64, 0x86 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 2, 1 }, 0, 1, { 0x02, 0x19, 0xF1, 0x79, 0x47, 0xF4, 0x6D, 0xF4, 0x7F, 0xF6, 0x49, 0x82, 0x66, 0x84, 0x0A, 0x3E, 0xB4, 0xEB, 0x3C, 0x00, 0x08, 0x42, 0xA7, 0x7A, 0xFF, 0x62, 0x91, 0x33, 0x25, 0x56, 0x74, 0xC9, 0x2E, 0x03, 0x44, 0xA4, 0x83, 0xE6, 0x3F, 0x20, 0xFF, 0xD0, 0x37, 0xA3, 0xBC, 0xA5, 0x3A, 0xDF, 0x55, 0x25, 0x49, 0xDF, 0x79, 0xD6, 0x4F, 0x3D, 0xCF, 0x89, 0x59, 0x6B, 0x70, 0x37, 0xB8, 0x56, 0xC1, 0xE4 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 1, { 0x04, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x03, 0x74, 0x96, 0xA3, 0xCC, 0x86, 0x92, 0x6D, 0x45, 0x2C, 0xAF, 0xCF, 0xD5, 0x5D, 0x25, 0x97, 0x2C, 0xA1, 0x67, 0x5D, 0x54, 0x93, 0x10, 0xDE, 0x29, 0x6B, 0xFF, 0x42, 0xF7, 0x2E, 0xEE, 0xA8, 0xC9 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_AGGOTHERNONCE, -1, { 0 }, { 0 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x87, 0xBF, 0x89, 0x1D, 0x2A, 0x6D, 0xEA, 0xEB, 0xAD, 0xC9, 0x09, 0x35, 0x2A, 0xA9, 0x40, 0x5D, 0x14, 0x28, 0xC1, 0x5F, 0x4B, 0x75, 0xF0, 0x4D, 0xAE, 0x64, 0x2A, 0x95, 0xC2, 0x54, 0x84, 0x80 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_AGGOTHERNONCE, -1, { 0 }, { 0 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 1, { 0x03, 0x53, 0xBC, 0x23, 0x14, 0xD4, 0x6C, 0x81, 0x3A, 0xF8, 0x13, 0x17, 0xAF, 0x1B, 0xDF, 0x99, 0x81, 0x6B, 0x64, 0x44, 0xE4, 0x16, 0xBB, 0x8D, 0x3D, 0xC0, 0x4A, 0xCB, 0x2F, 0x53, 0x88, 0xD1, 0xAC, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_AGGOTHERNONCE, -1, { 0 }, { 0 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 1, { 0x03, 0x53, 0xBC, 0x23, 0x14, 0xD4, 0x6C, 0x81, 0x3A, 0xF8, 0x13, 0x17, 0xAF, 0x1B, 0xDF, 0x99, 0x81, 0x6B, 0x64, 0x44, 0xE4, 0x16, 0xBB, 0x8D, 0x3D, 0xC0, 0x4A, 0xCB, 0x2F, 0x53, 0x88, 0xD1, 0xAC, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x30 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_AGGOTHERNONCE, -1, { 0 }, { 0 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 0, 1, { 0x02, 0x19, 0xF1, 0x79, 0x47, 0xF4, 0x6D, 0xF4, 0x7F, 0xF6, 0x49, 0x82, 0x66, 0x84, 0x0A, 0x3E, 0xB4, 0xEB, 0x3C, 0x00, 0x08, 0x42, 0xA7, 0x7A, 0xFF, 0x62, 0x91, 0x33, 0x25, 0x56, 0x74, 0xC9, 0x2E, 0x03, 0x44, 0xA4, 0x83, 0xE6, 0x3F, 0x20, 0xFF, 0xD0, 0x37, 0xA3, 0xBC, 0xA5, 0x3A, 0xDF, 0x55, 0x25, 0x49, 0xDF, 0x79, 0xD6, 0x4F, 0x3D, 0xCF, 0x89, 0x59, 0x6B, 0x70, 0x37, 0xB8, 0x56, 0xC1, 0xE4 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 1, { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 } }, { 0 }, FROST_VEC_ERR_TWEAK_ADD, -1, { 0 }, { 0 } }, + { 3, 0, 2, { 0, 1 }, 1, { 0, 1 }, 0, 1, { 0x02, 0xDC, 0x0C, 0xD5, 0xCA, 0xC6, 0xA1, 0xED, 0xFF, 0x9A, 0xFE, 0x93, 0xC2, 0x2F, 0x1A, 0x86, 0x18, 0x9B, 0xD5, 0x49, 0x3D, 0xD8, 0x73, 0x5A, 0x09, 0x81, 0xC0, 0x0F, 0xFB, 0x26, 0x7D, 0x00, 0x75, 0x03, 0x00, 0xCA, 0x72, 0x7F, 0xCD, 0x50, 0x3E, 0x73, 0x2E, 0x37, 0x56, 0x7B, 0x12, 0xA2, 0x7D, 0xFB, 0xE5, 0x44, 0x0B, 0x82, 0x40, 0xB0, 0x38, 0x48, 0xFF, 0xF5, 0x5F, 0x14, 0x16, 0x8A, 0xE3, 0x97 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, + { 3, 0, 3, { 0, 1, 2 }, 1, { 0, 1, 2 }, 5, 1, { 0x02, 0x19, 0xF1, 0x79, 0x47, 0xF4, 0x6D, 0xF4, 0x7F, 0xF6, 0x49, 0x82, 0x66, 0x84, 0x0A, 0x3E, 0xB4, 0xEB, 0x3C, 0x00, 0x08, 0x42, 0xA7, 0x7A, 0xFF, 0x62, 0x91, 0x33, 0x25, 0x56, 0x74, 0xC9, 0x2E, 0x03, 0x44, 0xA4, 0x83, 0xE6, 0x3F, 0x20, 0xFF, 0xD0, 0x37, 0xA3, 0xBC, 0xA5, 0x3A, 0xDF, 0x55, 0x25, 0x49, 0xDF, 0x79, 0xD6, 0x4F, 0x3D, 0xCF, 0x89, 0x59, 0x6B, 0x70, 0x37, 0xB8, 0x56, 0xC1, 0xE4 }, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 32, { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }, 0, { { 0 } }, { 0 }, FROST_VEC_ERR_DET_SIGN, -1, { 0 }, { 0 } }, +}; + +/* Skipped test cases (not expressible in the C API): + * - tweak_vectors error tc_id 10 (The tweaks and is_xonly arrays must have the same length.): not expressible in the C API (tweaks are applied individually and have a fixed length of 32 bytes) + * - tweak_vectors error tc_id 11 (The tweak must be a 32-byte array.): not expressible in the C API (tweaks are applied individually and have a fixed length of 32 bytes) + * - tweak_vectors error tc_id 21 (The tweaks and is_xonly arrays must have the same length.): not expressible in the C API (tweaks are applied individually and have a fixed length of 32 bytes) + * - tweak_vectors error tc_id 22 (The tweak must be a 32-byte array.): not expressible in the C API (tweaks are applied individually and have a fixed length of 32 bytes) + * - tweak_vectors error tc_id 32 (The tweaks and is_xonly arrays must have the same length.): not expressible in the C API (tweaks are applied individually and have a fixed length of 32 bytes) + * - tweak_vectors error tc_id 33 (The tweak must be a 32-byte array.): not expressible in the C API (tweaks are applied individually and have a fixed length of 32 bytes) + * - tweak_vectors error tc_id 43 (The tweaks and is_xonly arrays must have the same length.): not expressible in the C API (tweaks are applied individually and have a fixed length of 32 bytes) + * - tweak_vectors error tc_id 44 (The tweak must be a 32-byte array.): not expressible in the C API (tweaks are applied individually and have a fixed length of 32 bytes) + */ + diff --git a/src/secp256k1.c b/src/secp256k1.c index b2852dc5..0cedc958 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -952,3 +952,7 @@ static int secp256k1_ge_parse_ext(secp256k1_ge* ge, const unsigned char *in33) { #ifdef ENABLE_MODULE_SURJECTIONPROOF # include "modules/surjection/main_impl.h" #endif + +#ifdef ENABLE_MODULE_FROST +# include "modules/frost/main_impl.h" +#endif diff --git a/src/tests.c b/src/tests.c index ebc49c41..24ab3378 100644 --- a/src/tests.c +++ b/src/tests.c @@ -7920,6 +7920,10 @@ static void run_ecdsa_wycheproof(void) { # include "modules/ecdsa_adaptor/tests_impl.h" #endif +#ifdef ENABLE_MODULE_FROST +# include "modules/frost/tests_impl.h" +#endif + static void run_secp256k1_memczero_test(void) { unsigned char buf1[6] = {1, 2, 3, 4, 5, 6}; unsigned char buf2[sizeof(buf1)]; @@ -8287,6 +8291,9 @@ static const struct tf_test_module registry_modules[] = { #endif #ifdef ENABLE_MODULE_ECDSA_S2C MAKE_TEST_MODULE(ecdsa_s2c), +#endif +#ifdef ENABLE_MODULE_FROST + MAKE_TEST_MODULE(frost), #endif MAKE_TEST_MODULE(utils), }; diff --git a/tools/test_vectors_frost_generate.py b/tools/test_vectors_frost_generate.py new file mode 100644 index 00000000..10bbd499 --- /dev/null +++ b/tools/test_vectors_frost_generate.py @@ -0,0 +1,697 @@ +#!/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 " % 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)