/***********************************************************************
 * Distributed under the MIT software license, see the accompanying    *
 * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
 ***********************************************************************/

#ifndef SECP256K1_MODULE_CHILLDKG_TESTS_IMPL_H
#define SECP256K1_MODULE_CHILLDKG_TESTS_IMPL_H

#include <string.h>

#include "../../../include/secp256k1.h"
#include "../../../include/secp256k1_chilldkg.h"
#include "../../../include/secp256k1_schnorrsig.h"

#include "util.h"
#include "vss.h"
#include "simplpedpop.h"
#include "encpedpop.h"

#ifdef ENABLE_MODULE_FROST
#include "../../../include/secp256k1_frost.h"
#endif

#include "vectors.h"
#include "../../group.h"
#include "../../hash.h"
#include "../../scalar.h"
#include "../../util.h"

/* All expected values below were generated from the Python reference
 * implementation of bip-frost-dkg (chilldkg_ref and the vendored
 * secp256k1lab), commit a91896883f85b159415ecf298d5e844879af112d, using the
 * tagged hashes, serializations and algorithms of the reference directly. */

static const unsigned char vec_th_encpedpop_seed_msg[96] = { 0x5c, 0x6f, 0x26, 0x18, 0xc5, 0xcd, 0x99, 0xce, 0x44, 0xd0, 0x27, 0xf4, 0x24, 0xc5, 0x6b, 0xa7, 0x91, 0xd6, 0xe0, 0x01, 0xfd, 0xe7, 0xe4, 0x12, 0x09, 0x17, 0xed, 0x40, 0x0e, 0xc0, 0x7e, 0x4d, 0xe2, 0x41, 0xa0, 0x0a, 0x4d, 0xcf, 0x7e, 0xb2, 0x58, 0x47, 0xbd, 0x35, 0xc1, 0xb9, 0x24, 0x23, 0x9a, 0x25, 0xe2, 0x74, 0x87, 0xbd, 0x3b, 0x6a, 0xee, 0x45, 0xd3, 0x38, 0x4f, 0xe2, 0x09, 0x91, 0xe6, 0x81, 0x7d, 0x9a, 0x5e, 0xa8, 0x5f, 0x8f, 0xef, 0x9f, 0x92, 0x6e, 0x08, 0x27, 0xb8, 0xda, 0x3f, 0x99, 0xb4, 0xc8, 0xd3, 0xb5, 0xe2, 0x14, 0xdd, 0x82, 0x8f, 0x0c, 0x0c, 0xd1, 0x3d, 0x55 };
static const unsigned char vec_th_encpedpop_seed[32] = { 0xca, 0x51, 0x72, 0x9c, 0x93, 0x61, 0x90, 0x75, 0x11, 0xb0, 0x97, 0x44, 0x34, 0xfd, 0xde, 0x00, 0xac, 0x38, 0x50, 0xcf, 0x58, 0xef, 0x76, 0x4f, 0x72, 0x33, 0x75, 0x48, 0xc2, 0x6f, 0x56, 0xc0 };
static const unsigned char vec_th_simplpedpop_aux_msg[32] = { 0xc3, 0x10, 0x9e, 0x35, 0x1b, 0x35, 0xbb, 0xc9, 0x49, 0x73, 0x47, 0x8c, 0x63, 0xae, 0x47, 0xef, 0xda, 0xc1, 0x80, 0x8e, 0x0e, 0x7e, 0x66, 0x95, 0x0b, 0xe5, 0x2b, 0xa3, 0xb5, 0x40, 0x90, 0x17 };
static const unsigned char vec_th_simplpedpop_aux[32] = { 0x98, 0x2e, 0x55, 0xfb, 0x84, 0x1b, 0x61, 0x72, 0xbb, 0x63, 0xd5, 0xae, 0x6a, 0x0a, 0xa2, 0x7c, 0x17, 0x83, 0xa3, 0x98, 0x56, 0xe0, 0xaf, 0x60, 0x0b, 0x6e, 0x22, 0xb2, 0xe6, 0xa4, 0x8a, 0x78 };
static const unsigned char vec_th_encpedpop_secnonce_msg[32] = { 0xc5, 0xdf, 0x8c, 0x18, 0x85, 0x6b, 0xa3, 0xc4, 0xe8, 0xef, 0xd7, 0xe5, 0xf3, 0xf8, 0x34, 0x1b, 0x43, 0xd9, 0x31, 0xbe, 0x7b, 0xaf, 0xd9, 0xa0, 0x06, 0xc6, 0x82, 0x0b, 0xe6, 0x14, 0xce, 0xe3 };
static const unsigned char vec_th_encpedpop_secnonce[32] = { 0x52, 0xbb, 0x8a, 0x83, 0x6f, 0xb6, 0x4e, 0x46, 0x46, 0x79, 0x42, 0x77, 0xe4, 0xf4, 0x49, 0x77, 0x24, 0xbb, 0xbc, 0x0e, 0x5c, 0xaf, 0x20, 0x3b, 0x55, 0xa2, 0x79, 0x22, 0xa4, 0x45, 0x19, 0x3c };
static const unsigned char vec_th_encpedpop_ecdh_msg[110] = { 0x40, 0x2c, 0xc3, 0xde, 0x0d, 0xe6, 0x25, 0xf7, 0x8b, 0x9f, 0xf9, 0x69, 0xb6, 0x69, 0x7b, 0xae, 0x70, 0x2d, 0x2f, 0x0b, 0x91, 0x9c, 0x3f, 0x1f, 0xc9, 0x54, 0x18, 0x22, 0x95, 0xe0, 0x9a, 0x81, 0x52, 0x63, 0x4e, 0x58, 0xdc, 0xbb, 0x77, 0xe4, 0x63, 0xcd, 0x17, 0x94, 0xf4, 0x8b, 0xce, 0xa9, 0x31, 0xcd, 0xb8, 0xeb, 0xca, 0x85, 0x8b, 0xc3, 0x9c, 0x88, 0x34, 0x45, 0x90, 0x8f, 0x9c, 0x4a, 0xc7, 0x74, 0xf5, 0xe5, 0x3a, 0x1e, 0x8b, 0x59, 0x84, 0x97, 0x10, 0x14, 0x55, 0xa9, 0xfb, 0x2b, 0x00, 0xa4, 0x6c, 0xdf, 0x0a, 0x3b, 0x82, 0x68, 0xee, 0x05, 0xd0, 0x09, 0xdd, 0x82, 0x08, 0xbc, 0x2b, 0x12, 0x6d, 0x38, 0x24, 0xdf, 0x3d, 0xa5, 0xf2, 0x68, 0x3a, 0xd2, 0x64, 0x54 };
static const unsigned char vec_th_encpedpop_ecdh[32] = { 0x10, 0xf5, 0xeb, 0xfd, 0x78, 0x7e, 0x82, 0x6e, 0x9c, 0x3b, 0xf8, 0xdc, 0x19, 0x29, 0x04, 0xfb, 0x8d, 0xb0, 0xde, 0xf4, 0x70, 0x26, 0xac, 0xc5, 0xbd, 0x2e, 0xf0, 0xbd, 0xec, 0x92, 0xb9, 0xc9 };
static const unsigned char vec_th_encaps_multi_self_pad_msg[77] = { 0x04, 0x08, 0x06, 0x85, 0x44, 0xaa, 0x7c, 0xe9, 0xe9, 0x03, 0x9a, 0x13, 0x0d, 0x07, 0xfb, 0xe7, 0x17, 0xa9, 0x18, 0xe7, 0x77, 0x9b, 0x5f, 0xc1, 0x69, 0xc4, 0x8b, 0x51, 0xd7, 0x62, 0x39, 0xec, 0xf5, 0x6d, 0x5e, 0xc3, 0xaf, 0xcd, 0x66, 0x52, 0x27, 0x42, 0xf3, 0x37, 0xce, 0xa2, 0xda, 0x8a, 0x32, 0x2f, 0xd0, 0xf2, 0x00, 0xa6, 0x73, 0xfd, 0x85, 0xf5, 0xc5, 0xc4, 0xc9, 0x28, 0xe1, 0xc1, 0xe9, 0x43, 0xe3, 0x67, 0xf3, 0x59, 0x03, 0x87, 0x5b, 0xcf, 0x4a, 0xb6, 0x2a };
static const unsigned char vec_th_encaps_multi_self_pad[32] = { 0xf1, 0x7f, 0x82, 0x28, 0x50, 0x82, 0xda, 0x3c, 0x56, 0xf7, 0x3b, 0x18, 0xa5, 0x81, 0xaf, 0xff, 0x42, 0x7b, 0x89, 0x9e, 0xce, 0xf7, 0x92, 0x32, 0x8b, 0x85, 0x86, 0x53, 0x4e, 0x41, 0x2b, 0x87 };
static const unsigned char vec_th_vss_coeffs_msg[36] = { 0xc3, 0x7b, 0x8b, 0xd8, 0x94, 0x59, 0xf9, 0xc5, 0xb8, 0xcb, 0xc8, 0x4e, 0xe2, 0xd6, 0x68, 0x81, 0x3a, 0xcb, 0x36, 0x82, 0x3d, 0x51, 0xd9, 0x8a, 0xf7, 0xfe, 0xcb, 0xe9, 0x66, 0x00, 0x98, 0xdb, 0x67, 0x81, 0x41, 0x42 };
static const unsigned char vec_th_vss_coeffs[32] = { 0xb6, 0x63, 0x8b, 0x82, 0x4d, 0x68, 0xe0, 0xc7, 0x00, 0x63, 0xfb, 0xf2, 0x1a, 0x7d, 0xcd, 0x30, 0xbd, 0x3e, 0x47, 0xa2, 0x44, 0xb0, 0x9e, 0x60, 0x51, 0x15, 0x15, 0xf4, 0xc9, 0xcf, 0xcb, 0x89 };
static const unsigned char vec_taptweak_msg[32] = { 0xc6, 0x04, 0x7f, 0x94, 0x41, 0xed, 0x7d, 0x6d, 0x30, 0x45, 0x40, 0x6e, 0x95, 0xc0, 0x7c, 0xd8, 0x5c, 0x77, 0x8e, 0x4b, 0x8c, 0xef, 0x3c, 0xa7, 0xab, 0xac, 0x09, 0xb9, 0x5c, 0x70, 0x9e, 0xe5 };
static const unsigned char vec_taptweak[32] = { 0x04, 0xb2, 0x6d, 0xeb, 0xa6, 0x6b, 0x94, 0xdb, 0x39, 0x9b, 0xbf, 0x0c, 0x31, 0x02, 0x9d, 0x16, 0x8c, 0x5f, 0xeb, 0x56, 0x64, 0xcd, 0x7a, 0x21, 0x22, 0x48, 0x32, 0x21, 0x71, 0x34, 0x5a, 0xde };
static const unsigned char vec_params_hash_hostpubkeys[3][33] = {
    { 0x02, 0x0d, 0xce, 0x0a, 0x57, 0x0a, 0x10, 0x96, 0xce, 0x63, 0xdb, 0x07, 0xf2, 0xbe, 0x37, 0x28, 0x13, 0xbc, 0x92, 0xa1, 0xc4, 0xa0, 0xe0, 0x5a, 0x92, 0x94, 0xe8, 0x99, 0x9a, 0xb1, 0x46, 0xf0, 0xd2 },
    { 0x03, 0xfa, 0x40, 0x88, 0xaa, 0x3e, 0xd9, 0x4e, 0xdc, 0x40, 0x03, 0x59, 0x78, 0xca, 0xf0, 0x22, 0x99, 0x1c, 0x0f, 0xd3, 0xc4, 0xfc, 0xd0, 0x2e, 0x5b, 0xfb, 0x00, 0x7c, 0x3c, 0x44, 0xcb, 0xff, 0x06 },
    { 0x02, 0xcc, 0x4e, 0xe5, 0x03, 0x48, 0x9b, 0xf1, 0xbf, 0x88, 0xb0, 0xe6, 0xbf, 0x98, 0xc9, 0x44, 0xe6, 0x0b, 0x59, 0x4b, 0x45, 0x6a, 0xfa, 0x75, 0x10, 0xe2, 0x05, 0x16, 0xbd, 0xfd, 0xba, 0x87, 0xc0 },
};
static const unsigned char vec_params_hash[32] = { 0x99, 0x23, 0x3b, 0x82, 0x2a, 0xe9, 0x49, 0x24, 0xbd, 0x43, 0x1d, 0x4f, 0xad, 0x04, 0x47, 0x48, 0x8a, 0xc9, 0xf4, 0xbb, 0x9d, 0x8c, 0x21, 0x6e, 0x39, 0xdb, 0xab, 0x02, 0x15, 0xdd, 0x1e, 0x96 };
/* params_hash t = 2 */
static const unsigned char vec_point_0[33] = { 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 };
/* point_0 = 1*G, y odd = False */
static const unsigned char vec_point_1[33] = { 0x02, 0xc6, 0x04, 0x7f, 0x94, 0x41, 0xed, 0x7d, 0x6d, 0x30, 0x45, 0x40, 0x6e, 0x95, 0xc0, 0x7c, 0xd8, 0x5c, 0x77, 0x8e, 0x4b, 0x8c, 0xef, 0x3c, 0xa7, 0xab, 0xac, 0x09, 0xb9, 0x5c, 0x70, 0x9e, 0xe5 };
/* point_1 = 2*G, y odd = False */
static const unsigned char vec_point_2[33] = { 0x02, 0xf9, 0x30, 0x8a, 0x01, 0x92, 0x58, 0xc3, 0x10, 0x49, 0x34, 0x4f, 0x85, 0xf8, 0x9d, 0x52, 0x29, 0xb5, 0x31, 0xc8, 0x45, 0x83, 0x6f, 0x99, 0xb0, 0x86, 0x01, 0xf1, 0x13, 0xbc, 0xe0, 0x36, 0xf9 };
/* point_2 = 3*G, y odd = False */
static const unsigned char vec_pop_seckey[32] = { 0x8a, 0xda, 0x60, 0x76, 0xb8, 0xfd, 0x7c, 0x17, 0xf9, 0x3d, 0x04, 0xf5, 0x3e, 0xb9, 0x79, 0x9a, 0xfd, 0xdd, 0x0a, 0x52, 0x29, 0x16, 0xb1, 0xb3, 0x73, 0x6a, 0x85, 0xa4, 0xfc, 0x7c, 0x63, 0xca };
static const unsigned char vec_pop_aux[32] = { 0x18, 0xa6, 0x54, 0xb7, 0x17, 0xd3, 0xcd, 0xa8, 0xaf, 0x10, 0x7e, 0x9c, 0xbb, 0xbe, 0x35, 0x35, 0xd7, 0x51, 0x3a, 0xea, 0xda, 0x47, 0x65, 0xcb, 0x96, 0x58, 0x24, 0x5a, 0x75, 0x7b, 0x93, 0x97 };
static const unsigned char vec_pop_pubkey[32] = { 0x43, 0x20, 0xdf, 0x02, 0xf3, 0xa5, 0x13, 0xd3, 0xb0, 0x30, 0x1d, 0x23, 0x5f, 0xe3, 0xb7, 0x44, 0x84, 0xd1, 0xbe, 0xe1, 0xfb, 0x50, 0x22, 0xe5, 0x1c, 0x7f, 0x3c, 0xce, 0x24, 0x82, 0x60, 0xe9 };
static const unsigned char vec_pop_sig[64] = { 0x0c, 0xd9, 0x96, 0x33, 0x52, 0x7d, 0xa9, 0xec, 0x9b, 0xb2, 0x8d, 0xaa, 0x12, 0xb5, 0xf7, 0x41, 0x37, 0xa3, 0x62, 0xa2, 0xc9, 0x3b, 0x5c, 0x54, 0xbd, 0x98, 0x6b, 0x07, 0x0b, 0x4f, 0x46, 0xee, 0xe3, 0x32, 0xa2, 0xf0, 0x53, 0x99, 0xbb, 0x2f, 0xba, 0x2d, 0xe4, 0xd4, 0xe3, 0x8a, 0x1d, 0x1a, 0xaf, 0x2c, 0x3f, 0x48, 0xc0, 0xe2, 0xe8, 0x4b, 0x27, 0x81, 0x99, 0xdd, 0x87, 0x62, 0xb6, 0x87 };
/* pop participant_id = 5 */
static const unsigned char vec_certeq_seckey[32] = { 0x61, 0xf9, 0x3a, 0xd4, 0x0b, 0xd1, 0xe0, 0x97, 0x9e, 0xfc, 0x8f, 0x11, 0x99, 0xb1, 0x9b, 0xac, 0xee, 0xa2, 0x61, 0xcb, 0x9e, 0xe7, 0x36, 0x4b, 0x27, 0xde, 0xeb, 0x5d, 0xc7, 0x75, 0xc8, 0xd3 };
static const unsigned char vec_certeq_aux[32] = { 0x88, 0x3c, 0xa1, 0x82, 0x29, 0x39, 0x2a, 0x95, 0x8c, 0xff, 0x53, 0xd8, 0x72, 0x22, 0x0f, 0x73, 0xdd, 0x65, 0x2a, 0x6b, 0x54, 0xef, 0xc3, 0x1d, 0x6a, 0xfc, 0x64, 0x65, 0x58, 0x0d, 0x21, 0x37 };
static const unsigned char vec_certeq_eq_input[64] = { 0x62, 0x46, 0xc7, 0x4b, 0x5e, 0xdb, 0xf9, 0x07, 0xf0, 0x64, 0xb9, 0x8f, 0x97, 0x37, 0x63, 0x1e, 0x40, 0x7c, 0xd0, 0xb6, 0xe1, 0xbd, 0x2a, 0x0d, 0xdc, 0xae, 0x35, 0x6b, 0xc0, 0xf9, 0x0b, 0x78, 0x16, 0x66, 0xde, 0x7e, 0x85, 0x73, 0xc5, 0x1b, 0x38, 0xca, 0x9e, 0x86, 0x0a, 0xaa, 0x40, 0x2d, 0xf4, 0x0d, 0x8b, 0x38, 0x8e, 0xff, 0x10, 0x18, 0x49, 0xe0, 0xcf, 0xc7, 0xfe, 0xb3, 0xf7, 0xae };
static const unsigned char vec_certeq_pubkey[32] = { 0x72, 0x96, 0x62, 0x22, 0x23, 0xcb, 0x4f, 0x60, 0x32, 0xbd, 0x7d, 0x85, 0x98, 0x7c, 0x8a, 0xb7, 0xf1, 0xe7, 0xc4, 0xff, 0xda, 0xf3, 0xdf, 0xfb, 0xa5, 0x60, 0x91, 0x78, 0x79, 0x2b, 0x6f, 0xa3 };
static const unsigned char vec_certeq_sig[64] = { 0x63, 0xd7, 0xa5, 0xec, 0x8d, 0xfe, 0x7a, 0x8f, 0x2b, 0x5d, 0xa5, 0x4b, 0x3e, 0x14, 0x26, 0xec, 0xbc, 0x5a, 0xd0, 0xf6, 0x02, 0xf3, 0x77, 0xb1, 0x39, 0x47, 0x4f, 0x9b, 0x62, 0xd4, 0x8c, 0xd3, 0x1d, 0x78, 0xe5, 0xe6, 0x31, 0xcb, 0xb6, 0x90, 0x6e, 0xde, 0xa1, 0xc1, 0xf3, 0xf6, 0xc8, 0x0b, 0xed, 0x14, 0xad, 0x30, 0xff, 0x82, 0xa9, 0x6e, 0x89, 0x93, 0xe4, 0x0a, 0x1b, 0xf9, 0xa8, 0xe1 };
/* certeq participant_id = 7 */
static const unsigned char vec_ecdh_secnonce[32] = { 0x78, 0xfd, 0xe1, 0x58, 0x43, 0x13, 0x37, 0xaf, 0xbe, 0x0a, 0x27, 0x3f, 0x97, 0x8e, 0x84, 0x6b, 0x1d, 0xc3, 0x1b, 0x24, 0x72, 0x04, 0x25, 0x4b, 0x1f, 0x43, 0x76, 0x3c, 0x39, 0x38, 0x92, 0x3d };
static const unsigned char vec_ecdh_pubnonce[33] = { 0x02, 0x83, 0xae, 0x0b, 0x87, 0xf3, 0x12, 0xcc, 0x02, 0x12, 0xb9, 0x09, 0x30, 0x30, 0xe7, 0x1b, 0xc3, 0xd7, 0x11, 0x83, 0xff, 0x3b, 0xbe, 0x4d, 0x1c, 0x51, 0xd7, 0x1d, 0x74, 0x77, 0xc7, 0xb8, 0xc4 };
static const unsigned char vec_ecdh_hostseckey[32] = { 0xf9, 0xc4, 0x5c, 0xef, 0x58, 0x6b, 0x12, 0x4f, 0x47, 0x1e, 0x79, 0xc7, 0xa2, 0xc5, 0x14, 0xe3, 0x5e, 0xab, 0x6e, 0xdb, 0xb0, 0xdf, 0x48, 0x6a, 0x1b, 0x07, 0x20, 0xf5, 0xc0, 0xf3, 0x25, 0xc3 };
static const unsigned char vec_ecdh_hostpubkey[33] = { 0x03, 0x23, 0xf5, 0xef, 0x76, 0xc9, 0x7c, 0xb5, 0x01, 0x35, 0xe8, 0x5f, 0x1e, 0x2b, 0x4a, 0x5d, 0xfa, 0x97, 0x33, 0xb5, 0xca, 0xed, 0x7b, 0xa9, 0xc2, 0xcc, 0x08, 0x0c, 0x9a, 0xa7, 0xe6, 0x08, 0x9c };
static const unsigned char vec_ecdh_enc_context[70] = { 0x00, 0x00, 0x00, 0x02, 0x03, 0x23, 0xf5, 0xef, 0x76, 0xc9, 0x7c, 0xb5, 0x01, 0x35, 0xe8, 0x5f, 0x1e, 0x2b, 0x4a, 0x5d, 0xfa, 0x97, 0x33, 0xb5, 0xca, 0xed, 0x7b, 0xa9, 0xc2, 0xcc, 0x08, 0x0c, 0x9a, 0xa7, 0xe6, 0x08, 0x9c, 0x02, 0x0d, 0xce, 0x0a, 0x57, 0x0a, 0x10, 0x96, 0xce, 0x63, 0xdb, 0x07, 0xf2, 0xbe, 0x37, 0x28, 0x13, 0xbc, 0x92, 0xa1, 0xc4, 0xa0, 0xe0, 0x5a, 0x92, 0x94, 0xe8, 0x99, 0x9a, 0xb1, 0x46, 0xf0, 0xd2 };
static const unsigned char vec_ecdh_pad[32] = { 0x6a, 0x7a, 0x0f, 0xe9, 0xdc, 0x78, 0x5e, 0x35, 0x2e, 0x56, 0xf5, 0x12, 0x5a, 0x7f, 0x78, 0xeb, 0x4f, 0x7f, 0x5e, 0x4e, 0x8f, 0x6b, 0x05, 0x67, 0xe0, 0x27, 0x87, 0x45, 0xc1, 0x1e, 0xe8, 0x05 };
/* ecdh receiver_index = 0, t = 2 */
static const unsigned char vec_self_pad[32] = { 0xd0, 0xc2, 0x55, 0x74, 0xec, 0x55, 0xb5, 0xa8, 0x9e, 0x13, 0x7d, 0x62, 0xbd, 0x3f, 0x4b, 0x2f, 0xae, 0x9d, 0x00, 0x55, 0xbf, 0x4f, 0x94, 0x4f, 0xe8, 0xa1, 0xa3, 0x49, 0x99, 0x93, 0xab, 0x75 };
static const unsigned char vec_vss_seed[32] = { 0x5c, 0xd9, 0x4a, 0x21, 0x75, 0xd5, 0xf1, 0x6d, 0xc5, 0xa5, 0x9a, 0xc8, 0xf0, 0x91, 0x46, 0x44, 0x3a, 0xbc, 0x19, 0x64, 0xc2, 0xe0, 0xe3, 0x4f, 0xd8, 0x60, 0x26, 0x81, 0xea, 0xdc, 0xa8, 0x56 };
static const unsigned char vec_vss_coeffs[3][32] = {
    { 0xc9, 0xfd, 0x58, 0x25, 0xd8, 0x99, 0xc5, 0xb9, 0xd3, 0x16, 0x47, 0xa7, 0x16, 0xdb, 0xc9, 0x0e, 0xbb, 0xa7, 0x2c, 0x7f, 0xe2, 0xad, 0xfd, 0xd8, 0xb3, 0x86, 0x94, 0x93, 0xb1, 0x8b, 0xef, 0x1a },
    { 0x95, 0x22, 0xdb, 0x0d, 0x1f, 0xa2, 0xd3, 0xa5, 0xd9, 0x39, 0xd7, 0xfb, 0xf8, 0xb3, 0xd7, 0x17, 0xef, 0x44, 0x51, 0x2c, 0xd5, 0xea, 0x24, 0xdc, 0xb9, 0xea, 0x74, 0x19, 0xf6, 0x55, 0x0c, 0x34 },
    { 0xc1, 0x62, 0xf3, 0x91, 0x1c, 0x0b, 0x18, 0x91, 0x64, 0xc3, 0x66, 0x81, 0x87, 0xb7, 0x2e, 0x52, 0xab, 0x6a, 0x6e, 0x97, 0xbf, 0x12, 0x25, 0x3b, 0x28, 0x9b, 0x61, 0x2b, 0x9e, 0xf1, 0x72, 0xb1 },
};
static const unsigned char vec_vss_secshares[4][32] = {
    { 0x20, 0x83, 0x26, 0xc4, 0x14, 0x47, 0xb1, 0xf1, 0x11, 0x13, 0x86, 0x24, 0x97, 0x46, 0xce, 0x7b, 0xe0, 0xf8, 0x32, 0x77, 0x19, 0x19, 0x07, 0x79, 0x16, 0x67, 0xac, 0xbf, 0xa6, 0x65, 0xeb, 0x7d },
    { 0xf9, 0xce, 0xdc, 0x84, 0x88, 0x0b, 0xcf, 0x4b, 0x18, 0x97, 0x91, 0xa5, 0x27, 0x20, 0x30, 0x8e, 0x5d, 0x1e, 0x15, 0x9d, 0xcd, 0xa8, 0x5b, 0x8f, 0xca, 0x7f, 0x87, 0x42, 0xd9, 0x22, 0xcd, 0x42 },
    { 0x55, 0xe0, 0x79, 0x67, 0x33, 0xe6, 0x1d, 0xc7, 0xe9, 0xa2, 0x6a, 0x28, 0xc6, 0x67, 0xef, 0x4a, 0x00, 0x0c, 0x3f, 0x3f, 0xf2, 0x82, 0x19, 0x69, 0x90, 0x57, 0x08, 0x76, 0xd9, 0x1f, 0xd0, 0xa6 },
    { 0x34, 0xb7, 0xfd, 0x6c, 0x17, 0xd6, 0x9d, 0x67, 0x84, 0x34, 0x0f, 0xaf, 0x75, 0x1e, 0x0a, 0xac, 0x3f, 0x20, 0x69, 0x2a, 0xe6, 0x37, 0x81, 0x7d, 0xe7, 0x92, 0xed, 0x75, 0x46, 0xc9, 0x78, 0x2b },
};
static const unsigned char vec_vss_coms[3][33] = {
    { 0x03, 0xa5, 0xf8, 0x18, 0x69, 0x15, 0x26, 0x30, 0x9b, 0xbd, 0xdd, 0xbe, 0xd8, 0xf9, 0x7f, 0xfe, 0x02, 0xe0, 0x48, 0x90, 0x9b, 0xa0, 0xa0, 0x26, 0xa2, 0xee, 0x06, 0x84, 0x8f, 0x60, 0xc6, 0xd0, 0xe4 },
    { 0x02, 0x57, 0x8f, 0x58, 0x5c, 0x87, 0xa6, 0xad, 0x82, 0x2d, 0x39, 0xe4, 0x25, 0x30, 0xf0, 0xfe, 0xc4, 0x15, 0x7d, 0x57, 0xc2, 0xab, 0x32, 0x4d, 0x54, 0x6b, 0x48, 0xc9, 0x55, 0xc6, 0xa7, 0x47, 0x71 },
    { 0x03, 0xff, 0x1d, 0x03, 0xb8, 0x58, 0x0a, 0xc7, 0xf4, 0x3f, 0xc2, 0x45, 0x89, 0x6b, 0xae, 0xfb, 0x13, 0xb8, 0x58, 0xe7, 0x58, 0x37, 0x6a, 0xdf, 0x98, 0x94, 0xd9, 0xb5, 0x81, 0x18, 0xac, 0xf7, 0x87 },
};
static const unsigned char vec_vss_pubshares[4][33] = {
    { 0x02, 0x9b, 0x76, 0x00, 0x0c, 0x77, 0xf6, 0x00, 0x87, 0xe0, 0x0f, 0x6e, 0x62, 0xee, 0x8a, 0xa5, 0x83, 0x77, 0x76, 0xd7, 0xee, 0x72, 0x56, 0x8d, 0xf8, 0x3e, 0x75, 0xd9, 0x2f, 0x7b, 0xfe, 0x17, 0x17 },
    { 0x03, 0x16, 0x8c, 0x91, 0xbf, 0xac, 0xbf, 0x64, 0x11, 0x0c, 0x9b, 0x08, 0x0d, 0xb7, 0xb8, 0x4d, 0xe8, 0x39, 0x29, 0x34, 0xbb, 0x47, 0x04, 0xb4, 0xc5, 0x66, 0xaa, 0x19, 0xa2, 0xf0, 0x8c, 0x4c, 0xed },
    { 0x03, 0x92, 0x75, 0x4a, 0xba, 0x32, 0x6a, 0x59, 0x7d, 0x5b, 0x11, 0x2f, 0xc5, 0x40, 0x03, 0xbc, 0x4e, 0x0d, 0x30, 0x3a, 0x7f, 0x61, 0xbc, 0xb6, 0xbf, 0xdd, 0x4f, 0xe7, 0x89, 0x93, 0xbb, 0xa1, 0x4c },
    { 0x03, 0xc4, 0x96, 0xca, 0x1e, 0x45, 0xc7, 0xd9, 0xa8, 0x6f, 0x65, 0xcc, 0x9c, 0xe0, 0xef, 0xc1, 0x33, 0xfc, 0xbb, 0x37, 0xb2, 0xca, 0x55, 0xf7, 0x7e, 0x14, 0xea, 0x21, 0xcb, 0x58, 0x52, 0x1c, 0x35 },
};
static const unsigned char vec_vss_seed_b[32] = { 0x7c, 0x91, 0x4e, 0xab, 0x0b, 0x5c, 0x67, 0x77, 0xac, 0xfd, 0xef, 0x37, 0x16, 0xf9, 0x4a, 0xb9, 0x36, 0x06, 0xe7, 0x3c, 0xb0, 0xcd, 0x15, 0x67, 0xee, 0x3f, 0xae, 0x3c, 0x8a, 0xe4, 0xfa, 0x83 };
static const unsigned char vec_vss_coms_b[3][33] = {
    { 0x03, 0xb5, 0xbf, 0x93, 0x27, 0xec, 0xd2, 0x0c, 0xfa, 0xac, 0xcb, 0x38, 0x90, 0xda, 0xbf, 0x5e, 0x0d, 0x0b, 0xbc, 0x3b, 0x95, 0x12, 0x0a, 0x2e, 0xd3, 0x12, 0xc7, 0xdf, 0x4b, 0xae, 0x04, 0xa3, 0x12 },
    { 0x02, 0xde, 0xec, 0xea, 0x7f, 0x10, 0x13, 0x27, 0x03, 0x50, 0x0f, 0xe9, 0x76, 0xe8, 0x6e, 0xd4, 0x0e, 0xb5, 0x68, 0x94, 0x41, 0x0b, 0x2c, 0x69, 0x16, 0x7f, 0x3e, 0x63, 0x12, 0x57, 0xc3, 0xec, 0xf2 },
    { 0x03, 0x46, 0x36, 0x31, 0x26, 0x2a, 0x46, 0xb3, 0xca, 0x6d, 0x78, 0xb2, 0x81, 0x1f, 0xbe, 0x2c, 0xa0, 0x3a, 0xc3, 0x0f, 0x9c, 0x47, 0x5d, 0xa6, 0x27, 0x23, 0xd6, 0x2b, 0x66, 0xb7, 0x7a, 0x64, 0x1a },
};
static const unsigned char vec_vss_coms_sum[3][33] = {
    { 0x02, 0x01, 0xf8, 0x09, 0x72, 0x3e, 0x78, 0x2d, 0xd6, 0x9d, 0x3f, 0xac, 0xa9, 0x52, 0x53, 0x10, 0xe5, 0x00, 0x10, 0x25, 0xaa, 0x71, 0x51, 0x5a, 0xbb, 0x0c, 0x28, 0x0a, 0x65, 0xf9, 0x2a, 0xfb, 0xbd },
    { 0x03, 0xa5, 0x69, 0xf0, 0x2f, 0x95, 0xe2, 0x60, 0xd4, 0x14, 0x82, 0xcc, 0x4f, 0x23, 0x26, 0x90, 0xee, 0xa4, 0xb6, 0x76, 0xcc, 0x54, 0x73, 0x50, 0x4b, 0x98, 0x2c, 0x04, 0x78, 0x0a, 0xe5, 0xe1, 0x19 },
    { 0x03, 0x78, 0x2e, 0xb3, 0x69, 0x44, 0x8b, 0x68, 0x8e, 0xec, 0x98, 0x2b, 0x41, 0x11, 0xca, 0xb8, 0xf5, 0x5b, 0xbe, 0x0b, 0x22, 0xc7, 0x73, 0xc2, 0x9b, 0x6f, 0x7d, 0xdf, 0x8b, 0x73, 0x23, 0xe2, 0xc5 },
};
static const unsigned char vec_tweak[32] = { 0x83, 0xc0, 0x78, 0xa0, 0xb8, 0x64, 0x40, 0xf7, 0x5e, 0x2e, 0x23, 0xa6, 0xf1, 0x53, 0x81, 0xff, 0x9d, 0xd1, 0x2a, 0x2a, 0xee, 0xbf, 0xb1, 0xe1, 0x6e, 0xa4, 0x4a, 0x3d, 0x5d, 0xce, 0x00, 0xdd };
static const unsigned char vec_pubtweak[33] = { 0x02, 0xa7, 0xb9, 0xf0, 0x1f, 0x01, 0x58, 0x7e, 0xb0, 0x04, 0x7b, 0xc7, 0xc3, 0x83, 0x00, 0x0b, 0xd7, 0x26, 0xe9, 0xad, 0x33, 0x9c, 0x53, 0x62, 0xc8, 0x80, 0xf8, 0xb7, 0x56, 0x26, 0xe2, 0xc1, 0x1f };
static const unsigned char vec_vss_coms_tweaked[3][33] = {
    { 0x03, 0xf0, 0x1a, 0xf4, 0x40, 0xc3, 0x6d, 0xec, 0x54, 0xf8, 0x5f, 0xd6, 0x91, 0x1b, 0xe3, 0x97, 0xdd, 0x95, 0xf0, 0x19, 0x85, 0x20, 0x70, 0x3f, 0x8a, 0x18, 0xc8, 0x06, 0xde, 0xd8, 0x98, 0x5c, 0x1c },
    { 0x02, 0x57, 0x8f, 0x58, 0x5c, 0x87, 0xa6, 0xad, 0x82, 0x2d, 0x39, 0xe4, 0x25, 0x30, 0xf0, 0xfe, 0xc4, 0x15, 0x7d, 0x57, 0xc2, 0xab, 0x32, 0x4d, 0x54, 0x6b, 0x48, 0xc9, 0x55, 0xc6, 0xa7, 0x47, 0x71 },
    { 0x03, 0xff, 0x1d, 0x03, 0xb8, 0x58, 0x0a, 0xc7, 0xf4, 0x3f, 0xc2, 0x45, 0x89, 0x6b, 0xae, 0xfb, 0x13, 0xb8, 0x58, 0xe7, 0x58, 0x37, 0x6a, 0xdf, 0x98, 0x94, 0xd9, 0xb5, 0x81, 0x18, 0xac, 0xf7, 0x87 },
};
/* all python-side sanity checks passed */

static const unsigned char vec_simpl_seeds[3][32] = {
    { 0xa6, 0xf4, 0xe5, 0xf2, 0x7b, 0xdd, 0xce, 0xa7, 0x26, 0xb2, 0x34, 0xfb, 0x7b, 0xde, 0x82, 0x98, 0xa5, 0x43, 0xc2, 0x51, 0x45, 0xa9, 0x7a, 0xd2, 0x34, 0x3d, 0xb5, 0x22, 0x5b, 0x29, 0x31, 0x14 },
    { 0xb3, 0xa1, 0xef, 0xa6, 0x69, 0xc6, 0x9c, 0xa8, 0xdd, 0x58, 0x0a, 0xfe, 0x92, 0x0b, 0x8c, 0x00, 0xcc, 0x6e, 0x92, 0x2f, 0xd0, 0x7b, 0x88, 0x13, 0x80, 0x20, 0x9b, 0x86, 0x78, 0x2b, 0x3b, 0x9b },
    { 0xe9, 0x9e, 0xe7, 0xeb, 0x84, 0xe2, 0x22, 0xca, 0x0a, 0xcc, 0x8a, 0x88, 0x24, 0x9b, 0x94, 0x28, 0xbd, 0xd9, 0xfd, 0x7e, 0x86, 0x45, 0xb5, 0xb3, 0xb9, 0xc0, 0x90, 0x7d, 0x20, 0x4d, 0x55, 0x61 },
};
static const unsigned char vec_simpl_auxs[3][32] = {
    { 0x33, 0x0e, 0x6c, 0x54, 0x12, 0x16, 0x2a, 0xc7, 0x24, 0x63, 0x4e, 0x89, 0x6a, 0x05, 0x86, 0xcb, 0x00, 0x7c, 0xa4, 0xf9, 0x87, 0xf7, 0x13, 0x85, 0x5d, 0x29, 0xc4, 0xbb, 0x41, 0x8d, 0x28, 0xdf },
    { 0xf8, 0xfd, 0xb8, 0x21, 0xbc, 0x3d, 0x58, 0x44, 0xea, 0x95, 0x03, 0x73, 0x85, 0xf3, 0x9e, 0xab, 0x9f, 0x31, 0x77, 0xbe, 0x40, 0x81, 0x63, 0x73, 0x85, 0xeb, 0xdd, 0x8d, 0x0e, 0xaf, 0xde, 0xac },
    { 0xe4, 0x6d, 0x0d, 0x20, 0x61, 0x82, 0xee, 0x3c, 0x90, 0xb7, 0xdf, 0xb2, 0x9a, 0x78, 0x5e, 0x8d, 0x6b, 0xb5, 0x37, 0x1d, 0x4f, 0x0d, 0x84, 0xe4, 0xe0, 0xe8, 0x0d, 0xe5, 0x65, 0x04, 0x31, 0x34 },
};
static const unsigned char vec_simpl_pmsgs[3][130] = {
    { 0x03, 0x8c, 0xb4, 0x5f, 0x49, 0xf0, 0x01, 0x02, 0xf9, 0x84, 0x09, 0x9c, 0xe4, 0x1b, 0x85, 0xed, 0x90, 0x2e, 0xb8, 0x67, 0x69, 0x7a, 0x07, 0x88, 0x62, 0x34, 0xb7, 0x66, 0x32, 0xd2, 0x9b, 0xbe, 0xbc, 0x03, 0x9f, 0x74, 0xfc, 0x67, 0x4f, 0x91, 0xb6, 0x7d, 0xaf, 0x76, 0xb5, 0x25, 0x47, 0xb4, 0x4d, 0x60, 0xf6, 0x06, 0xef, 0x1d, 0x3a, 0xa8, 0x64, 0x8f, 0x68, 0x2d, 0xc6, 0xd3, 0x71, 0x75, 0x63, 0x4c, 0x72, 0x78, 0x3a, 0x94, 0xd6, 0x86, 0x8a, 0x58, 0x61, 0x22, 0x4f, 0xda, 0x99, 0x0d, 0x70, 0x38, 0x88, 0xa8, 0x7b, 0x00, 0xc0, 0x2a, 0x27, 0xca, 0x52, 0x66, 0x4a, 0x99, 0x36, 0xb1, 0x3c, 0xc1, 0xaf, 0xe6, 0x59, 0x12, 0x3c, 0xfe, 0xcb, 0x3b, 0x7a, 0x77, 0x85, 0x0d, 0x96, 0x32, 0x4a, 0x3f, 0x7e, 0xd9, 0x66, 0x22, 0x3b, 0x30, 0x36, 0x73, 0xdf, 0x16, 0x78, 0xd0, 0x76, 0xa6, 0xf8, 0x2f },
    { 0x03, 0xc6, 0x5d, 0x00, 0x8d, 0xd5, 0x1c, 0x5f, 0xe9, 0x64, 0x38, 0x62, 0xbe, 0x0e, 0x7f, 0x6f, 0xcf, 0x08, 0x98, 0x90, 0xe9, 0x2d, 0x9e, 0x6e, 0xc3, 0x3d, 0x62, 0x44, 0xbf, 0x77, 0x7e, 0x7a, 0x1b, 0x03, 0x19, 0xe5, 0x0b, 0xbb, 0x2a, 0xb2, 0xd4, 0x65, 0x36, 0xd9, 0xbf, 0xef, 0x5c, 0x04, 0xa1, 0x09, 0xb3, 0x07, 0x47, 0x17, 0xc4, 0x5c, 0x2f, 0xdf, 0xc8, 0x21, 0x52, 0x1f, 0x3f, 0x84, 0xae, 0x11, 0xe9, 0xbd, 0xcd, 0xb3, 0xba, 0x31, 0x72, 0xe5, 0x04, 0xc1, 0x51, 0xc2, 0x59, 0xfa, 0x8d, 0x05, 0xb7, 0xe1, 0x75, 0x98, 0x35, 0xd3, 0xb9, 0x47, 0xf0, 0x57, 0x5b, 0xe4, 0x37, 0xfc, 0x91, 0x1e, 0x61, 0xe7, 0x4b, 0x1d, 0x5c, 0x07, 0x18, 0x94, 0x5f, 0x33, 0x79, 0x55, 0x64, 0x35, 0x6d, 0x3e, 0x69, 0x92, 0x0f, 0xc0, 0x7a, 0x03, 0xc0, 0x33, 0x7f, 0x26, 0xb5, 0xfd, 0xc3, 0x3e, 0x47, 0x5c },
    { 0x02, 0x99, 0xad, 0x8e, 0x28, 0xa8, 0x4c, 0x91, 0x5e, 0xc8, 0x19, 0x03, 0xc3, 0x1b, 0xb4, 0x0f, 0xc5, 0xa5, 0xd4, 0xad, 0x06, 0xdf, 0xd0, 0xaa, 0x77, 0xd1, 0xf4, 0x62, 0x8e, 0x07, 0xf4, 0x58, 0xee, 0x03, 0x43, 0x6e, 0x96, 0x90, 0x01, 0x45, 0x43, 0xb7, 0x27, 0x3f, 0xa4, 0xd8, 0x86, 0x17, 0x63, 0x70, 0x2b, 0x50, 0x97, 0xaa, 0x1b, 0x8c, 0x71, 0x91, 0x9d, 0x55, 0x5c, 0x59, 0xbe, 0x54, 0x05, 0x9d, 0x54, 0x08, 0x18, 0x4a, 0x80, 0xbd, 0x80, 0x31, 0x49, 0x0d, 0xef, 0x23, 0x98, 0xb2, 0x1a, 0x4f, 0x59, 0x20, 0x29, 0x72, 0xbd, 0x3d, 0xb3, 0xeb, 0x7e, 0x9e, 0xec, 0x9c, 0x4c, 0xe9, 0x56, 0x7a, 0x97, 0xab, 0x0b, 0xc9, 0x90, 0xd9, 0x7f, 0xb9, 0xc5, 0x6f, 0x67, 0x74, 0x29, 0x8b, 0x32, 0x41, 0x05, 0xf5, 0xe0, 0x4f, 0xa2, 0xbe, 0x68, 0x84, 0x43, 0xe6, 0x13, 0xd1, 0xbb, 0xe9, 0x8d, 0x6b },
};
static const unsigned char vec_simpl_cmsg[324] = { 0x03, 0x8c, 0xb4, 0x5f, 0x49, 0xf0, 0x01, 0x02, 0xf9, 0x84, 0x09, 0x9c, 0xe4, 0x1b, 0x85, 0xed, 0x90, 0x2e, 0xb8, 0x67, 0x69, 0x7a, 0x07, 0x88, 0x62, 0x34, 0xb7, 0x66, 0x32, 0xd2, 0x9b, 0xbe, 0xbc, 0x03, 0xc6, 0x5d, 0x00, 0x8d, 0xd5, 0x1c, 0x5f, 0xe9, 0x64, 0x38, 0x62, 0xbe, 0x0e, 0x7f, 0x6f, 0xcf, 0x08, 0x98, 0x90, 0xe9, 0x2d, 0x9e, 0x6e, 0xc3, 0x3d, 0x62, 0x44, 0xbf, 0x77, 0x7e, 0x7a, 0x1b, 0x02, 0x99, 0xad, 0x8e, 0x28, 0xa8, 0x4c, 0x91, 0x5e, 0xc8, 0x19, 0x03, 0xc3, 0x1b, 0xb4, 0x0f, 0xc5, 0xa5, 0xd4, 0xad, 0x06, 0xdf, 0xd0, 0xaa, 0x77, 0xd1, 0xf4, 0x62, 0x8e, 0x07, 0xf4, 0x58, 0xee, 0x02, 0x64, 0xcc, 0x1f, 0x7a, 0x2d, 0x27, 0xbb, 0x89, 0xf0, 0x68, 0xb1, 0x80, 0xfe, 0xe6, 0x9a, 0x6c, 0xd6, 0xce, 0x69, 0x93, 0x58, 0x6c, 0x61, 0x2b, 0x8b, 0x2e, 0x31, 0x08, 0xb9, 0x20, 0xf5, 0xac, 0x72, 0x78, 0x3a, 0x94, 0xd6, 0x86, 0x8a, 0x58, 0x61, 0x22, 0x4f, 0xda, 0x99, 0x0d, 0x70, 0x38, 0x88, 0xa8, 0x7b, 0x00, 0xc0, 0x2a, 0x27, 0xca, 0x52, 0x66, 0x4a, 0x99, 0x36, 0xb1, 0x3c, 0xc1, 0xaf, 0xe6, 0x59, 0x12, 0x3c, 0xfe, 0xcb, 0x3b, 0x7a, 0x77, 0x85, 0x0d, 0x96, 0x32, 0x4a, 0x3f, 0x7e, 0xd9, 0x66, 0x22, 0x3b, 0x30, 0x36, 0x73, 0xdf, 0x16, 0x78, 0xd0, 0x76, 0xa6, 0xf8, 0x2f, 0xe9, 0xbd, 0xcd, 0xb3, 0xba, 0x31, 0x72, 0xe5, 0x04, 0xc1, 0x51, 0xc2, 0x59, 0xfa, 0x8d, 0x05, 0xb7, 0xe1, 0x75, 0x98, 0x35, 0xd3, 0xb9, 0x47, 0xf0, 0x57, 0x5b, 0xe4, 0x37, 0xfc, 0x91, 0x1e, 0x61, 0xe7, 0x4b, 0x1d, 0x5c, 0x07, 0x18, 0x94, 0x5f, 0x33, 0x79, 0x55, 0x64, 0x35, 0x6d, 0x3e, 0x69, 0x92, 0x0f, 0xc0, 0x7a, 0x03, 0xc0, 0x33, 0x7f, 0x26, 0xb5, 0xfd, 0xc3, 0x3e, 0x47, 0x5c, 0x54, 0x08, 0x18, 0x4a, 0x80, 0xbd, 0x80, 0x31, 0x49, 0x0d, 0xef, 0x23, 0x98, 0xb2, 0x1a, 0x4f, 0x59, 0x20, 0x29, 0x72, 0xbd, 0x3d, 0xb3, 0xeb, 0x7e, 0x9e, 0xec, 0x9c, 0x4c, 0xe9, 0x56, 0x7a, 0x97, 0xab, 0x0b, 0xc9, 0x90, 0xd9, 0x7f, 0xb9, 0xc5, 0x6f, 0x67, 0x74, 0x29, 0x8b, 0x32, 0x41, 0x05, 0xf5, 0xe0, 0x4f, 0xa2, 0xbe, 0x68, 0x84, 0x43, 0xe6, 0x13, 0xd1, 0xbb, 0xe9, 0x8d, 0x6b };
static const unsigned char vec_simpl_eq_input[70] = { 0x00, 0x00, 0x00, 0x02, 0x02, 0xd0, 0x90, 0x3c, 0xe9, 0x3d, 0xa3, 0x13, 0x95, 0x1e, 0x45, 0xd4, 0xa1, 0xb3, 0x84, 0x79, 0xbe, 0x50, 0x00, 0xc0, 0xd0, 0x6b, 0xec, 0xbc, 0x9a, 0xb3, 0xdf, 0x19, 0x56, 0x14, 0xd2, 0x15, 0x4c, 0x02, 0x64, 0xcc, 0x1f, 0x7a, 0x2d, 0x27, 0xbb, 0x89, 0xf0, 0x68, 0xb1, 0x80, 0xfe, 0xe6, 0x9a, 0x6c, 0xd6, 0xce, 0x69, 0x93, 0x58, 0x6c, 0x61, 0x2b, 0x8b, 0x2e, 0x31, 0x08, 0xb9, 0x20, 0xf5, 0xac };
static const unsigned char vec_simpl_untweaked_secshares[3][32] = {
    { 0x59, 0x2f, 0xa6, 0x21, 0xe3, 0xf7, 0xb2, 0xd2, 0x8d, 0x65, 0x4b, 0x93, 0xc2, 0xfd, 0x3f, 0xae, 0xe9, 0x58, 0x56, 0xf6, 0xde, 0x20, 0xb4, 0xc9, 0x24, 0xae, 0x60, 0x9a, 0x5f, 0x95, 0xaf, 0x91 },
    { 0x19, 0xd3, 0x87, 0xab, 0x70, 0xd1, 0x17, 0x08, 0x5e, 0xbd, 0x0e, 0xae, 0x69, 0x96, 0xe3, 0x1b, 0x12, 0x93, 0x8b, 0x7b, 0x74, 0xd6, 0xe9, 0xbd, 0xdc, 0xe8, 0x49, 0x12, 0x89, 0xdc, 0xf9, 0x9a },
    { 0xda, 0x77, 0x69, 0x34, 0xfd, 0xaa, 0x7b, 0x3e, 0x30, 0x14, 0xd1, 0xc9, 0x10, 0x30, 0x86, 0x85, 0xf6, 0x7d, 0x9c, 0xe6, 0xba, 0xd5, 0xbe, 0xee, 0x54, 0xf4, 0x90, 0x17, 0x84, 0x5a, 0x84, 0xe4 },
};
static const unsigned char vec_simpl_secshares[3][32] = {
    { 0x3b, 0x3a, 0x99, 0x94, 0x6a, 0x23, 0x46, 0xb0, 0xd2, 0xf6, 0x9f, 0x20, 0xb0, 0xa6, 0x93, 0x0c, 0x0d, 0x10, 0x96, 0xc7, 0x7b, 0x07, 0xd8, 0x34, 0x5c, 0xc4, 0x54, 0x36, 0x2c, 0xfd, 0xc6, 0x6d },
    { 0xfb, 0xde, 0x7b, 0x1d, 0xf6, 0xfc, 0xaa, 0xe6, 0xa4, 0x4e, 0x62, 0x3b, 0x57, 0x40, 0x36, 0x76, 0xf0, 0xfa, 0xa8, 0x32, 0xc1, 0x06, 0xad, 0x64, 0xd4, 0xd0, 0x9b, 0x3b, 0x27, 0x7b, 0x51, 0xb7 },
    { 0xbc, 0x82, 0x5c, 0xa7, 0x83, 0xd6, 0x0f, 0x1c, 0x75, 0xa6, 0x25, 0x55, 0xfd, 0xd9, 0xd9, 0xe3, 0x1a, 0x35, 0xdc, 0xb7, 0x57, 0xbc, 0xe2, 0x59, 0x8d, 0x0a, 0x83, 0xb3, 0x51, 0xc2, 0x9b, 0xc0 },
};
static const unsigned char vec_simpl_thresh_pk[33] = { 0x03, 0x40, 0x04, 0x9c, 0x23, 0x3f, 0xcd, 0xc0, 0xed, 0x61, 0xe5, 0xc0, 0x2b, 0x69, 0xc2, 0xd8, 0x87, 0x6e, 0x78, 0xe9, 0xb3, 0xd4, 0x6d, 0x00, 0x7e, 0x26, 0x99, 0x8e, 0xeb, 0xfe, 0xa0, 0xdd, 0xc2 };
static const unsigned char vec_simpl_pubshares[3][33] = {
    { 0x02, 0xe4, 0x79, 0xc9, 0x2f, 0x41, 0xe8, 0x17, 0xef, 0x02, 0xa0, 0xa7, 0x50, 0x72, 0xb5, 0x9c, 0xce, 0xcd, 0xc5, 0xbf, 0xae, 0x56, 0x23, 0x19, 0x14, 0x97, 0x58, 0x9f, 0x80, 0xcd, 0x8c, 0x0b, 0x66 },
    { 0x03, 0xc2, 0x2e, 0x8e, 0x3b, 0x79, 0xff, 0xa2, 0x98, 0xb3, 0xc6, 0x26, 0xdd, 0x32, 0xdb, 0x4d, 0xad, 0xd6, 0xca, 0xeb, 0xae, 0xb3, 0x21, 0xb2, 0x0e, 0xc3, 0x7e, 0x80, 0xce, 0x55, 0x26, 0xdd, 0xed },
    { 0x03, 0x47, 0xef, 0x6d, 0x6b, 0x08, 0x3c, 0x91, 0xe2, 0x0a, 0xb0, 0x09, 0xa9, 0x1e, 0xa0, 0x40, 0x0c, 0x45, 0x19, 0x04, 0x53, 0x4a, 0xa3, 0x7f, 0x12, 0x1f, 0x22, 0xcb, 0xbf, 0x5c, 0x80, 0xcb, 0xf5 },
};
/* simplpedpop n = 3, t = 2 */
static const unsigned char vec_enc_hostseckeys[3][32] = {
    { 0xdb, 0x3d, 0x72, 0xeb, 0x38, 0x03, 0x1d, 0x5e, 0x7e, 0x83, 0xd7, 0x23, 0x30, 0xe2, 0xd0, 0xb9, 0x41, 0x77, 0xcb, 0x4c, 0x35, 0x65, 0x59, 0xee, 0x41, 0xca, 0xd5, 0x61, 0x52, 0x58, 0xd5, 0x00 },
    { 0xe8, 0x12, 0xb0, 0xff, 0x5b, 0xb8, 0xf0, 0x8a, 0xfc, 0x87, 0xd7, 0xc3, 0x5b, 0x92, 0x17, 0x22, 0xab, 0x4d, 0x89, 0x76, 0x87, 0x45, 0x7a, 0x27, 0x2f, 0x71, 0x0c, 0xfb, 0x0a, 0xc9, 0x94, 0x50 },
    { 0xff, 0x64, 0xf0, 0x9b, 0xb5, 0x03, 0xb5, 0x66, 0x29, 0x6e, 0xb6, 0xb2, 0x69, 0x09, 0x60, 0xab, 0x8b, 0x42, 0x13, 0x2d, 0x64, 0xdb, 0x9d, 0x4d, 0x27, 0x74, 0xc1, 0x19, 0x15, 0x74, 0x49, 0xba },
};
static const unsigned char vec_enc_hostpubkeys[3][33] = {
    { 0x03, 0x30, 0x45, 0x46, 0x1f, 0xd4, 0xb4, 0xe8, 0xbc, 0xd2, 0x88, 0x8b, 0xc0, 0x5d, 0x2f, 0x8c, 0x86, 0x10, 0x53, 0x43, 0x10, 0x2e, 0x42, 0x5f, 0x18, 0xae, 0x64, 0xe0, 0x03, 0x2a, 0xba, 0xe1, 0xe3 },
    { 0x03, 0x5c, 0x1f, 0xe2, 0x1b, 0xce, 0x62, 0x99, 0x2a, 0xe0, 0x66, 0x67, 0x7e, 0xc0, 0x4f, 0x68, 0xfc, 0x1b, 0x25, 0x79, 0x5f, 0x1a, 0x33, 0x62, 0x9a, 0xfb, 0x00, 0x24, 0x90, 0x60, 0x02, 0x85, 0x37 },
    { 0x02, 0x19, 0xd6, 0xb1, 0x40, 0xab, 0x84, 0xa2, 0x5a, 0x49, 0x38, 0xcd, 0x62, 0xb2, 0x63, 0xd1, 0xd9, 0x85, 0x5e, 0xa4, 0x1e, 0x1e, 0xbc, 0x19, 0x56, 0x85, 0x47, 0x7f, 0xed, 0xd6, 0xd6, 0xa1, 0x38 },
};
static const unsigned char vec_enc_randoms[3][32] = {
    { 0x95, 0xd1, 0xe5, 0x58, 0xb0, 0xba, 0x91, 0x29, 0x56, 0xfc, 0x6a, 0x07, 0xf1, 0xc1, 0xb5, 0x7a, 0x79, 0x98, 0x04, 0x26, 0xf7, 0x62, 0xfd, 0x70, 0x56, 0x46, 0x27, 0xab, 0x00, 0x05, 0xb1, 0x57 },
    { 0x5d, 0xec, 0x98, 0x69, 0xa0, 0xf1, 0x7d, 0xbb, 0x48, 0x07, 0x10, 0x1d, 0x39, 0xe7, 0x77, 0x67, 0x24, 0xeb, 0xb1, 0xfe, 0x67, 0x36, 0x55, 0xd8, 0xd9, 0x29, 0xe1, 0x42, 0x4b, 0x74, 0x78, 0x4c },
    { 0x7a, 0x98, 0x6c, 0xf5, 0x5d, 0xfa, 0xfc, 0x25, 0x0b, 0xa4, 0xb9, 0x51, 0x8a, 0x86, 0x9f, 0xfc, 0xb9, 0x84, 0x5a, 0x02, 0x0e, 0x46, 0xcd, 0xeb, 0xfd, 0xd8, 0x69, 0xf0, 0x96, 0x1b, 0xe1, 0x33 },
};
static const unsigned char vec_enc_context[103] = { 0x00, 0x00, 0x00, 0x02, 0x03, 0x30, 0x45, 0x46, 0x1f, 0xd4, 0xb4, 0xe8, 0xbc, 0xd2, 0x88, 0x8b, 0xc0, 0x5d, 0x2f, 0x8c, 0x86, 0x10, 0x53, 0x43, 0x10, 0x2e, 0x42, 0x5f, 0x18, 0xae, 0x64, 0xe0, 0x03, 0x2a, 0xba, 0xe1, 0xe3, 0x03, 0x5c, 0x1f, 0xe2, 0x1b, 0xce, 0x62, 0x99, 0x2a, 0xe0, 0x66, 0x67, 0x7e, 0xc0, 0x4f, 0x68, 0xfc, 0x1b, 0x25, 0x79, 0x5f, 0x1a, 0x33, 0x62, 0x9a, 0xfb, 0x00, 0x24, 0x90, 0x60, 0x02, 0x85, 0x37, 0x02, 0x19, 0xd6, 0xb1, 0x40, 0xab, 0x84, 0xa2, 0x5a, 0x49, 0x38, 0xcd, 0x62, 0xb2, 0x63, 0xd1, 0xd9, 0x85, 0x5e, 0xa4, 0x1e, 0x1e, 0xbc, 0x19, 0x56, 0x85, 0x47, 0x7f, 0xed, 0xd6, 0xd6, 0xa1, 0x38 };
static const unsigned char vec_enc_secnonces[3][32] = {
    { 0xe0, 0x4c, 0x21, 0xfc, 0x3d, 0xe8, 0x14, 0x0b, 0xa5, 0x69, 0x1b, 0xd8, 0x95, 0x74, 0xb5, 0x39, 0x13, 0x62, 0x7e, 0x30, 0x4a, 0x57, 0x9e, 0xa3, 0x78, 0x27, 0x48, 0x67, 0xb2, 0x17, 0x02, 0xd7 },
    { 0x40, 0x32, 0xd6, 0xcc, 0x81, 0x70, 0xca, 0x6c, 0xcd, 0x31, 0x18, 0xa6, 0x07, 0xc0, 0x68, 0x45, 0x6b, 0x3e, 0x91, 0x28, 0xd5, 0x99, 0x65, 0xbe, 0x57, 0x02, 0x11, 0xd4, 0x2a, 0x3f, 0x28, 0xdb },
    { 0x34, 0x10, 0x60, 0x33, 0x60, 0x32, 0xc1, 0xc5, 0x8a, 0x76, 0x9a, 0xcb, 0xcd, 0xee, 0x2d, 0x78, 0xe7, 0x41, 0x89, 0x7f, 0xe0, 0xdb, 0xda, 0x5a, 0x8f, 0xf5, 0xa0, 0x1c, 0x4f, 0x01, 0x26, 0x36 },
};
static const unsigned char vec_enc_pubnonces[3][33] = {
    { 0x02, 0xb4, 0x37, 0x07, 0x73, 0x50, 0x98, 0x00, 0xf2, 0x22, 0x91, 0x6a, 0x54, 0x79, 0x78, 0x41, 0xd6, 0xcf, 0xc5, 0xb7, 0x00, 0x88, 0x0b, 0xcf, 0xb0, 0x39, 0xfb, 0x00, 0x08, 0x49, 0x41, 0x5f, 0x3f },
    { 0x03, 0x97, 0x21, 0xcb, 0xf9, 0xbe, 0xde, 0xbf, 0x1b, 0xd5, 0x53, 0x0a, 0x04, 0x8d, 0x9d, 0x5b, 0x08, 0xf4, 0x6b, 0xb6, 0x1e, 0x6e, 0x7f, 0xf6, 0xc9, 0x96, 0x12, 0x9b, 0x14, 0x9e, 0xf3, 0xa0, 0x2d },
    { 0x02, 0x12, 0xab, 0xc1, 0x3e, 0x84, 0x05, 0xa3, 0x3f, 0xcb, 0x4c, 0x43, 0x77, 0x43, 0xf8, 0x65, 0x20, 0x37, 0xf1, 0x4b, 0x67, 0x0e, 0x8d, 0x57, 0x42, 0xea, 0x26, 0x33, 0xa6, 0xec, 0x5e, 0x42, 0x37 },
};
static const unsigned char vec_enc_pmsgs[3][259] = {
    { 0x03, 0xec, 0x16, 0x3c, 0xbf, 0xfc, 0x00, 0x8b, 0xf2, 0x5b, 0x99, 0x89, 0x8f, 0x5c, 0x4c, 0x0b, 0x5b, 0x00, 0xf3, 0xeb, 0xf8, 0xb2, 0xde, 0x73, 0x0d, 0x78, 0xdb, 0xef, 0xcb, 0xad, 0x01, 0xf9, 0x12, 0x03, 0xf2, 0x85, 0xe9, 0xd4, 0x54, 0x84, 0x8b, 0x3e, 0xc0, 0xaa, 0x4b, 0x14, 0xd5, 0x9c, 0x40, 0x8c, 0xd4, 0xa2, 0xed, 0x0a, 0x7d, 0x12, 0xf6, 0x4d, 0xed, 0xa7, 0xb7, 0x46, 0x0b, 0xee, 0xe4, 0xd1, 0xc0, 0x01, 0xd9, 0x1f, 0x98, 0x64, 0x8c, 0xa5, 0x81, 0xe0, 0x48, 0xef, 0x5b, 0xb8, 0xaa, 0x8f, 0x17, 0xe7, 0x05, 0xc8, 0x78, 0x4b, 0xaa, 0xe1, 0xbe, 0xc1, 0x2e, 0x9f, 0xc8, 0x16, 0x79, 0x1d, 0x2e, 0x54, 0xde, 0xef, 0x4b, 0x3a, 0xba, 0xcf, 0x76, 0x71, 0x63, 0x53, 0x42, 0xd5, 0x78, 0xfb, 0x32, 0x18, 0xce, 0x70, 0x27, 0xe1, 0x6e, 0x1e, 0x3c, 0x55, 0x10, 0x11, 0x62, 0xcf, 0xfa, 0x7c, 0x02, 0xb4, 0x37, 0x07, 0x73, 0x50, 0x98, 0x00, 0xf2, 0x22, 0x91, 0x6a, 0x54, 0x79, 0x78, 0x41, 0xd6, 0xcf, 0xc5, 0xb7, 0x00, 0x88, 0x0b, 0xcf, 0xb0, 0x39, 0xfb, 0x00, 0x08, 0x49, 0x41, 0x5f, 0x3f, 0x01, 0x0c, 0xd2, 0xc2, 0xfe, 0xe8, 0x28, 0x59, 0xf3, 0xe8, 0x8c, 0xe9, 0x34, 0x4e, 0x90, 0x48, 0xd2, 0x45, 0xe2, 0xb1, 0xdc, 0x31, 0x06, 0x46, 0x7e, 0xf6, 0xda, 0xc6, 0x9b, 0xa9, 0x7b, 0xfb, 0xd6, 0xf0, 0xef, 0x8e, 0x90, 0x8d, 0xa1, 0x43, 0x18, 0x4b, 0xd1, 0x3a, 0x7d, 0xa1, 0x96, 0x19, 0x34, 0x98, 0xb5, 0xcf, 0x50, 0x0c, 0x96, 0x5b, 0xe3, 0xba, 0x60, 0x75, 0xac, 0x39, 0x79, 0x00, 0xcc, 0x77, 0x7c, 0x7f, 0xb5, 0x43, 0x4f, 0x27, 0x2e, 0x17, 0xdb, 0xf6, 0x2f, 0xcb, 0xe2, 0x1e, 0x39, 0x14, 0x18, 0x24, 0x87, 0x11, 0x8c, 0x5f, 0x82, 0xe0, 0xbc, 0x49, 0xed, 0x36, 0xea, 0xd9 },
    { 0x02, 0xba, 0x32, 0x18, 0xa3, 0xd4, 0xd6, 0x53, 0xcc, 0x8a, 0xb6, 0x1d, 0x4b, 0xea, 0x1f, 0xc9, 0xfd, 0x08, 0xa5, 0x1b, 0x5f, 0xb1, 0x93, 0xba, 0xa8, 0x3d, 0x37, 0x81, 0x16, 0x20, 0x5d, 0x52, 0xb9, 0x02, 0x22, 0xd4, 0x83, 0xee, 0x97, 0x61, 0x5a, 0x68, 0x49, 0x5e, 0x87, 0xaa, 0x1a, 0xad, 0x0d, 0x42, 0x38, 0x8f, 0x6f, 0xd6, 0x93, 0x24, 0xca, 0x13, 0x3a, 0x0b, 0x8f, 0x38, 0xbd, 0x7b, 0xb0, 0x37, 0x71, 0x7d, 0xe1, 0xc6, 0xd8, 0xf7, 0x14, 0x89, 0x65, 0x7c, 0xa4, 0xab, 0x22, 0x6b, 0xfe, 0x00, 0x72, 0x39, 0x03, 0xbf, 0xbc, 0x17, 0x3f, 0x53, 0x06, 0x1a, 0xae, 0x44, 0xba, 0x0d, 0x10, 0xa4, 0x1a, 0x13, 0xf1, 0xcc, 0x25, 0xa6, 0x1a, 0xf0, 0x53, 0xc4, 0x29, 0x66, 0xf9, 0x7f, 0x3e, 0xc6, 0x88, 0x32, 0xac, 0xd5, 0xe8, 0x28, 0x06, 0x47, 0xf1, 0x04, 0x43, 0xae, 0xdb, 0x90, 0x00, 0x3a, 0x03, 0x97, 0x21, 0xcb, 0xf9, 0xbe, 0xde, 0xbf, 0x1b, 0xd5, 0x53, 0x0a, 0x04, 0x8d, 0x9d, 0x5b, 0x08, 0xf4, 0x6b, 0xb6, 0x1e, 0x6e, 0x7f, 0xf6, 0xc9, 0x96, 0x12, 0x9b, 0x14, 0x9e, 0xf3, 0xa0, 0x2d, 0x10, 0x95, 0x16, 0x68, 0xd3, 0x2a, 0xa7, 0x04, 0xcf, 0xf5, 0x60, 0xb9, 0x10, 0x40, 0xc7, 0x67, 0xdd, 0x3d, 0x36, 0x9d, 0x47, 0x18, 0x2e, 0x39, 0xe8, 0xc1, 0x1b, 0x38, 0xb3, 0xc6, 0x86, 0x04, 0x68, 0x83, 0x1f, 0xeb, 0x67, 0x8c, 0xff, 0xca, 0x77, 0x53, 0x51, 0x62, 0x4e, 0x9e, 0x9f, 0x3b, 0x88, 0xe0, 0x51, 0x94, 0xd8, 0x0b, 0xf8, 0x47, 0xe3, 0xe8, 0x8b, 0xe8, 0x32, 0xa4, 0x5e, 0xdc, 0x9d, 0x77, 0x5b, 0x9a, 0x7b, 0x71, 0x96, 0xca, 0xb9, 0x2c, 0x3b, 0xff, 0x7b, 0x94, 0x46, 0x24, 0x4a, 0x08, 0x23, 0x2d, 0x32, 0x8f, 0xb9, 0x4c, 0x30, 0x8c, 0x2f, 0xea, 0x3b, 0x47, 0xf9, 0xc6 },
    { 0x03, 0x58, 0x20, 0x38, 0x53, 0xa3, 0x8b, 0x1c, 0xa3, 0x49, 0x5f, 0x78, 0xfb, 0x4a, 0xcb, 0x67, 0x95, 0x30, 0xa5, 0xe6, 0xe9, 0x12, 0xfc, 0x6f, 0x49, 0x7e, 0x4f, 0x6c, 0x9d, 0x29, 0xf3, 0x1a, 0x5e, 0x03, 0xf4, 0xb1, 0x99, 0xf5, 0x2a, 0x56, 0x5b, 0x7e, 0x06, 0xc8, 0x5b, 0x4c, 0xd9, 0xc4, 0x8f, 0x14, 0xa0, 0x22, 0xbd, 0x95, 0x33, 0x6a, 0x8d, 0xa0, 0xf5, 0x53, 0x5c, 0x62, 0xd6, 0x1d, 0x24, 0x2f, 0x3e, 0xea, 0x96, 0xeb, 0xd9, 0xb0, 0x64, 0x21, 0x6a, 0x1b, 0x3d, 0x4d, 0x34, 0xc0, 0x20, 0xc8, 0x5f, 0x03, 0xf2, 0xe9, 0x3d, 0x13, 0x6d, 0x74, 0x97, 0xe8, 0x26, 0xf9, 0x0c, 0xef, 0x4e, 0xfe, 0xd3, 0x68, 0x5f, 0x01, 0x91, 0x0a, 0x1c, 0x72, 0x4f, 0xbc, 0x97, 0xfc, 0x66, 0x8d, 0x76, 0x62, 0xde, 0x33, 0xdb, 0x70, 0x58, 0x2f, 0x73, 0xd3, 0xc1, 0x19, 0xe1, 0x98, 0xe0, 0x6b, 0x3a, 0x4d, 0x02, 0x12, 0xab, 0xc1, 0x3e, 0x84, 0x05, 0xa3, 0x3f, 0xcb, 0x4c, 0x43, 0x77, 0x43, 0xf8, 0x65, 0x20, 0x37, 0xf1, 0x4b, 0x67, 0x0e, 0x8d, 0x57, 0x42, 0xea, 0x26, 0x33, 0xa6, 0xec, 0x5e, 0x42, 0x37, 0x57, 0x28, 0x52, 0x4e, 0xb1, 0x88, 0xcb, 0xa5, 0xc5, 0xda, 0x24, 0x60, 0x44, 0x7a, 0xa8, 0x1b, 0xc7, 0x3f, 0x6b, 0x53, 0x2e, 0x75, 0xc9, 0xf6, 0xd7, 0x54, 0x9b, 0x7f, 0xdc, 0xe9, 0xee, 0x7f, 0x04, 0xae, 0xb4, 0x62, 0xdd, 0x76, 0x6c, 0x4f, 0x09, 0xaf, 0xa9, 0x8c, 0x91, 0x63, 0x49, 0x4f, 0x3c, 0x97, 0x4a, 0xa6, 0x8c, 0xb7, 0x8a, 0xf3, 0x0b, 0x09, 0xe7, 0xc5, 0x09, 0x93, 0x38, 0x81, 0x2e, 0x5e, 0xa8, 0x9d, 0xeb, 0xc5, 0xfd, 0xf2, 0xfc, 0xae, 0x0c, 0x3a, 0xbf, 0x94, 0x6f, 0x3e, 0xce, 0xd5, 0x8a, 0xa4, 0xf4, 0xfa, 0x39, 0x4a, 0x92, 0xa2, 0xe1, 0xe7, 0x83, 0x9f, 0xd2, 0xc8 },
};
static const unsigned char vec_enc_cmsg[423] = { 0x03, 0xec, 0x16, 0x3c, 0xbf, 0xfc, 0x00, 0x8b, 0xf2, 0x5b, 0x99, 0x89, 0x8f, 0x5c, 0x4c, 0x0b, 0x5b, 0x00, 0xf3, 0xeb, 0xf8, 0xb2, 0xde, 0x73, 0x0d, 0x78, 0xdb, 0xef, 0xcb, 0xad, 0x01, 0xf9, 0x12, 0x02, 0xba, 0x32, 0x18, 0xa3, 0xd4, 0xd6, 0x53, 0xcc, 0x8a, 0xb6, 0x1d, 0x4b, 0xea, 0x1f, 0xc9, 0xfd, 0x08, 0xa5, 0x1b, 0x5f, 0xb1, 0x93, 0xba, 0xa8, 0x3d, 0x37, 0x81, 0x16, 0x20, 0x5d, 0x52, 0xb9, 0x03, 0x58, 0x20, 0x38, 0x53, 0xa3, 0x8b, 0x1c, 0xa3, 0x49, 0x5f, 0x78, 0xfb, 0x4a, 0xcb, 0x67, 0x95, 0x30, 0xa5, 0xe6, 0xe9, 0x12, 0xfc, 0x6f, 0x49, 0x7e, 0x4f, 0x6c, 0x9d, 0x29, 0xf3, 0x1a, 0x5e, 0x03, 0x14, 0x72, 0x50, 0xbc, 0x22, 0x95, 0xb2, 0x46, 0x18, 0x25, 0x31, 0x7a, 0x10, 0x01, 0x12, 0x09, 0x32, 0xf4, 0xea, 0x0c, 0x8a, 0xaa, 0xba, 0xc3, 0x24, 0xa4, 0x35, 0x5f, 0x6e, 0xf2, 0x85, 0xb6, 0xc0, 0x01, 0xd9, 0x1f, 0x98, 0x64, 0x8c, 0xa5, 0x81, 0xe0, 0x48, 0xef, 0x5b, 0xb8, 0xaa, 0x8f, 0x17, 0xe7, 0x05, 0xc8, 0x78, 0x4b, 0xaa, 0xe1, 0xbe, 0xc1, 0x2e, 0x9f, 0xc8, 0x16, 0x79, 0x1d, 0x2e, 0x54, 0xde, 0xef, 0x4b, 0x3a, 0xba, 0xcf, 0x76, 0x71, 0x63, 0x53, 0x42, 0xd5, 0x78, 0xfb, 0x32, 0x18, 0xce, 0x70, 0x27, 0xe1, 0x6e, 0x1e, 0x3c, 0x55, 0x10, 0x11, 0x62, 0xcf, 0xfa, 0x7c, 0x71, 0x7d, 0xe1, 0xc6, 0xd8, 0xf7, 0x14, 0x89, 0x65, 0x7c, 0xa4, 0xab, 0x22, 0x6b, 0xfe, 0x00, 0x72, 0x39, 0x03, 0xbf, 0xbc, 0x17, 0x3f, 0x53, 0x06, 0x1a, 0xae, 0x44, 0xba, 0x0d, 0x10, 0xa4, 0x1a, 0x13, 0xf1, 0xcc, 0x25, 0xa6, 0x1a, 0xf0, 0x53, 0xc4, 0x29, 0x66, 0xf9, 0x7f, 0x3e, 0xc6, 0x88, 0x32, 0xac, 0xd5, 0xe8, 0x28, 0x06, 0x47, 0xf1, 0x04, 0x43, 0xae, 0xdb, 0x90, 0x00, 0x3a, 0x3e, 0xea, 0x96, 0xeb, 0xd9, 0xb0, 0x64, 0x21, 0x6a, 0x1b, 0x3d, 0x4d, 0x34, 0xc0, 0x20, 0xc8, 0x5f, 0x03, 0xf2, 0xe9, 0x3d, 0x13, 0x6d, 0x74, 0x97, 0xe8, 0x26, 0xf9, 0x0c, 0xef, 0x4e, 0xfe, 0xd3, 0x68, 0x5f, 0x01, 0x91, 0x0a, 0x1c, 0x72, 0x4f, 0xbc, 0x97, 0xfc, 0x66, 0x8d, 0x76, 0x62, 0xde, 0x33, 0xdb, 0x70, 0x58, 0x2f, 0x73, 0xd3, 0xc1, 0x19, 0xe1, 0x98, 0xe0, 0x6b, 0x3a, 0x4d, 0x02, 0xb4, 0x37, 0x07, 0x73, 0x50, 0x98, 0x00, 0xf2, 0x22, 0x91, 0x6a, 0x54, 0x79, 0x78, 0x41, 0xd6, 0xcf, 0xc5, 0xb7, 0x00, 0x88, 0x0b, 0xcf, 0xb0, 0x39, 0xfb, 0x00, 0x08, 0x49, 0x41, 0x5f, 0x3f, 0x03, 0x97, 0x21, 0xcb, 0xf9, 0xbe, 0xde, 0xbf, 0x1b, 0xd5, 0x53, 0x0a, 0x04, 0x8d, 0x9d, 0x5b, 0x08, 0xf4, 0x6b, 0xb6, 0x1e, 0x6e, 0x7f, 0xf6, 0xc9, 0x96, 0x12, 0x9b, 0x14, 0x9e, 0xf3, 0xa0, 0x2d, 0x02, 0x12, 0xab, 0xc1, 0x3e, 0x84, 0x05, 0xa3, 0x3f, 0xcb, 0x4c, 0x43, 0x77, 0x43, 0xf8, 0x65, 0x20, 0x37, 0xf1, 0x4b, 0x67, 0x0e, 0x8d, 0x57, 0x42, 0xea, 0x26, 0x33, 0xa6, 0xec, 0x5e, 0x42, 0x37 };
static const unsigned char vec_enc_secshares[3][32] = {
    { 0x68, 0xca, 0x3b, 0x7a, 0x83, 0x9b, 0x9b, 0x04, 0x89, 0xb8, 0x12, 0x02, 0x89, 0x09, 0xff, 0xcc, 0x76, 0xc2, 0x84, 0xa2, 0x51, 0xbe, 0xfe, 0x77, 0x3f, 0x0c, 0x91, 0x7f, 0x2c, 0x59, 0xf0, 0x7e },
    { 0x44, 0x22, 0xc3, 0xdc, 0xd5, 0x91, 0x0d, 0x5c, 0x99, 0x4e, 0xcc, 0x29, 0x5d, 0xa3, 0x7e, 0xa5, 0x3f, 0x61, 0x75, 0x24, 0x05, 0x87, 0x79, 0x5b, 0x12, 0xda, 0x75, 0x96, 0x18, 0x3a, 0xcf, 0x1c },
    { 0x98, 0x4d, 0x80, 0xb8, 0x1c, 0x7a, 0xe3, 0xe4, 0xe3, 0xf2, 0x24, 0x30, 0x6a, 0xf4, 0x97, 0x82, 0x97, 0x42, 0xe9, 0x0f, 0xff, 0x52, 0xde, 0xba, 0x86, 0x3d, 0x6f, 0x8e, 0xdb, 0xe8, 0x76, 0x26 },
};
static const unsigned char vec_enc_eq_input[268] = { 0x00, 0x00, 0x00, 0x02, 0x02, 0x4a, 0x73, 0xaa, 0xd2, 0xf5, 0x00, 0xc7, 0xca, 0x28, 0x24, 0x5e, 0xfa, 0xd5, 0x55, 0x93, 0x67, 0xcf, 0xfb, 0xaa, 0x01, 0x19, 0x31, 0xa6, 0x9c, 0xe4, 0x11, 0xb3, 0x8e, 0xa7, 0x3d, 0x3f, 0x52, 0x03, 0x14, 0x72, 0x50, 0xbc, 0x22, 0x95, 0xb2, 0x46, 0x18, 0x25, 0x31, 0x7a, 0x10, 0x01, 0x12, 0x09, 0x32, 0xf4, 0xea, 0x0c, 0x8a, 0xaa, 0xba, 0xc3, 0x24, 0xa4, 0x35, 0x5f, 0x6e, 0xf2, 0x85, 0xb6, 0x03, 0x30, 0x45, 0x46, 0x1f, 0xd4, 0xb4, 0xe8, 0xbc, 0xd2, 0x88, 0x8b, 0xc0, 0x5d, 0x2f, 0x8c, 0x86, 0x10, 0x53, 0x43, 0x10, 0x2e, 0x42, 0x5f, 0x18, 0xae, 0x64, 0xe0, 0x03, 0x2a, 0xba, 0xe1, 0xe3, 0x03, 0x5c, 0x1f, 0xe2, 0x1b, 0xce, 0x62, 0x99, 0x2a, 0xe0, 0x66, 0x67, 0x7e, 0xc0, 0x4f, 0x68, 0xfc, 0x1b, 0x25, 0x79, 0x5f, 0x1a, 0x33, 0x62, 0x9a, 0xfb, 0x00, 0x24, 0x90, 0x60, 0x02, 0x85, 0x37, 0x02, 0x19, 0xd6, 0xb1, 0x40, 0xab, 0x84, 0xa2, 0x5a, 0x49, 0x38, 0xcd, 0x62, 0xb2, 0x63, 0xd1, 0xd9, 0x85, 0x5e, 0xa4, 0x1e, 0x1e, 0xbc, 0x19, 0x56, 0x85, 0x47, 0x7f, 0xed, 0xd6, 0xd6, 0xa1, 0x38, 0x02, 0xb4, 0x37, 0x07, 0x73, 0x50, 0x98, 0x00, 0xf2, 0x22, 0x91, 0x6a, 0x54, 0x79, 0x78, 0x41, 0xd6, 0xcf, 0xc5, 0xb7, 0x00, 0x88, 0x0b, 0xcf, 0xb0, 0x39, 0xfb, 0x00, 0x08, 0x49, 0x41, 0x5f, 0x3f, 0x03, 0x97, 0x21, 0xcb, 0xf9, 0xbe, 0xde, 0xbf, 0x1b, 0xd5, 0x53, 0x0a, 0x04, 0x8d, 0x9d, 0x5b, 0x08, 0xf4, 0x6b, 0xb6, 0x1e, 0x6e, 0x7f, 0xf6, 0xc9, 0x96, 0x12, 0x9b, 0x14, 0x9e, 0xf3, 0xa0, 0x2d, 0x02, 0x12, 0xab, 0xc1, 0x3e, 0x84, 0x05, 0xa3, 0x3f, 0xcb, 0x4c, 0x43, 0x77, 0x43, 0xf8, 0x65, 0x20, 0x37, 0xf1, 0x4b, 0x67, 0x0e, 0x8d, 0x57, 0x42, 0xea, 0x26, 0x33, 0xa6, 0xec, 0x5e, 0x42, 0x37 };
static const unsigned char vec_enc_out_secshares[3][32] = {
    { 0xbf, 0x52, 0xb6, 0x81, 0xfb, 0xea, 0x1b, 0x4a, 0xde, 0x2d, 0xe5, 0x45, 0xae, 0x80, 0xf8, 0x79, 0x5a, 0x86, 0x65, 0x85, 0xe2, 0x54, 0xaa, 0x25, 0xf6, 0xf0, 0x38, 0x80, 0x71, 0x82, 0x83, 0x11 },
    { 0x7d, 0x86, 0xbe, 0x5d, 0x04, 0x99, 0xac, 0x5a, 0x02, 0x18, 0x6c, 0xef, 0xf3, 0x26, 0x2f, 0xef, 0x95, 0x8e, 0x71, 0x43, 0xb6, 0xf0, 0x48, 0xa0, 0xc6, 0x13, 0x77, 0x3b, 0xb1, 0x8d, 0xc8, 0xae },
    { 0x3b, 0xba, 0xc6, 0x38, 0x0d, 0x49, 0x3d, 0x69, 0x26, 0x02, 0xf4, 0x9a, 0x37, 0xcb, 0x67, 0x65, 0xd0, 0x96, 0x7d, 0x01, 0x8b, 0x8b, 0xe7, 0x1b, 0x95, 0x36, 0xb5, 0xf6, 0xf1, 0x99, 0x0e, 0x4b },
};
static const unsigned char vec_enc_thresh_pk[33] = { 0x03, 0xba, 0x4f, 0x2c, 0x1a, 0x9d, 0x2c, 0xf5, 0x36, 0x9d, 0x7b, 0xd4, 0xff, 0x32, 0x8c, 0x76, 0x92, 0xce, 0x87, 0x32, 0x9e, 0x88, 0x00, 0x05, 0x7b, 0x31, 0xf7, 0x09, 0xd0, 0xa8, 0x88, 0x48, 0x22 };
static const unsigned char vec_enc_pubshares[3][33] = {
    { 0x03, 0xa9, 0x45, 0xce, 0x22, 0xcd, 0x1c, 0x4d, 0x2c, 0x67, 0x24, 0xdb, 0xc1, 0x76, 0x77, 0xe8, 0xd7, 0x38, 0x8b, 0x6f, 0x7c, 0x74, 0x2f, 0xa1, 0x5a, 0x15, 0x76, 0x82, 0xa4, 0x9f, 0xca, 0x56, 0x45 },
    { 0x02, 0xf4, 0x8a, 0xc7, 0x32, 0x0e, 0xb3, 0x40, 0x52, 0x79, 0xa8, 0x63, 0xdf, 0x81, 0xb2, 0x6c, 0x44, 0xe9, 0x5b, 0x0c, 0x1f, 0x7d, 0xe2, 0x8c, 0x7a, 0x68, 0xa8, 0xa8, 0x01, 0x7f, 0x6c, 0xee, 0xf3 },
    { 0x03, 0x2b, 0xf1, 0xf8, 0xdf, 0x4a, 0x28, 0x18, 0xe5, 0xbf, 0xde, 0x30, 0xbe, 0xb0, 0xa9, 0x2e, 0x2e, 0xa2, 0xb0, 0x79, 0x92, 0xab, 0xeb, 0xd5, 0x14, 0xdd, 0x54, 0x44, 0x2e, 0xb7, 0x12, 0xd8, 0xb9 },
};
/* encpedpop n = 3, t = 2 */
/* all python-side sanity checks passed */

static const unsigned char vec3_hostseckeys[3][32] = {
    { 0x63, 0xf1, 0xca, 0xd7, 0x7b, 0xa9, 0x64, 0x63, 0x48, 0x03, 0xa3, 0x11, 0x03, 0x0f, 0x5c, 0x74, 0x30, 0x5b, 0x9c, 0x06, 0x24, 0x13, 0xc3, 0xbe, 0xc0, 0xe1, 0xbc, 0xf4, 0x39, 0xb3, 0x35, 0xcf },
    { 0xba, 0x8b, 0x85, 0xb8, 0xd3, 0x0d, 0xcf, 0x07, 0x87, 0xc6, 0x5b, 0x7c, 0x6a, 0x46, 0x08, 0xef, 0xc7, 0x25, 0x35, 0x52, 0x8d, 0xc5, 0x4f, 0xf1, 0xa7, 0x13, 0x52, 0x32, 0x6b, 0x51, 0x71, 0xb1 },
    { 0x73, 0xed, 0x74, 0x96, 0x68, 0x50, 0xa1, 0x21, 0x61, 0x59, 0xd6, 0xe1, 0xf8, 0x07, 0xcc, 0xfb, 0xfa, 0x89, 0x3d, 0xc8, 0xa9, 0x07, 0xfe, 0xfd, 0xe2, 0x34, 0x01, 0xd0, 0xd2, 0xe9, 0xa3, 0xa8 },
};
static const unsigned char vec3_hostpubkeys[3][33] = {
    { 0x02, 0x2d, 0x9b, 0xc8, 0xa8, 0x44, 0x57, 0xc7, 0x51, 0x00, 0x1f, 0x71, 0x4a, 0xd9, 0xac, 0x72, 0x82, 0x8a, 0x01, 0xe5, 0x31, 0xbe, 0x63, 0xe7, 0xfc, 0x3c, 0x4d, 0x37, 0x0c, 0x2f, 0xec, 0xd8, 0x43 },
    { 0x03, 0x34, 0xbe, 0xe4, 0x54, 0x9f, 0x86, 0x95, 0xd8, 0x96, 0xa3, 0xf0, 0x60, 0x40, 0xe0, 0x26, 0x3c, 0x41, 0x90, 0x54, 0xf3, 0xb8, 0xc7, 0x83, 0xa7, 0x7a, 0x77, 0x02, 0x82, 0x86, 0x14, 0x97, 0x3a },
    { 0x02, 0x85, 0xe6, 0xb7, 0xa7, 0xfb, 0x26, 0x5f, 0x38, 0xb9, 0xad, 0xc3, 0x9e, 0x51, 0xd4, 0xac, 0x2d, 0xfb, 0x0f, 0x31, 0xa6, 0xf1, 0x8e, 0x7f, 0xf8, 0xae, 0x2f, 0x3c, 0xa7, 0xbc, 0xaa, 0x7d, 0xcf },
};
static const unsigned char vec3_params_hash[32] = { 0x40, 0x6a, 0x61, 0xe7, 0xd3, 0x91, 0x7e, 0xc0, 0x8d, 0x10, 0x51, 0x38, 0x62, 0xab, 0xbb, 0x40, 0x42, 0x14, 0x39, 0x7c, 0x81, 0x5b, 0x32, 0x60, 0x87, 0xb8, 0x0b, 0x90, 0x31, 0xee, 0xf6, 0xbb };
static const unsigned char vec3_randoms[3][32] = {
    { 0x47, 0x1f, 0x0e, 0xfc, 0x32, 0x6d, 0xaa, 0x68, 0xbb, 0x76, 0x70, 0x31, 0x88, 0x3a, 0xff, 0x5a, 0xcd, 0xc8, 0xca, 0xad, 0x58, 0x5b, 0x0f, 0x5d, 0x13, 0x52, 0xf7, 0x54, 0x70, 0x6c, 0x23, 0xcc },
    { 0xb6, 0x2d, 0x69, 0xb3, 0x7f, 0x3b, 0x20, 0xbd, 0x57, 0x7a, 0xf0, 0x05, 0x7d, 0xd5, 0x11, 0x52, 0xe2, 0xea, 0x90, 0x1c, 0xe1, 0x0f, 0xe9, 0x6c, 0x25, 0x68, 0x55, 0x1d, 0xda, 0xfc, 0xa1, 0x9d },
    { 0xda, 0x99, 0x81, 0x45, 0xd2, 0x74, 0x0f, 0x62, 0xbe, 0x66, 0x57, 0x5b, 0x5f, 0xc1, 0xfd, 0x8d, 0xf4, 0x42, 0x53, 0x72, 0xbb, 0x59, 0x5a, 0x5b, 0xe5, 0x55, 0x17, 0xb9, 0xfe, 0xac, 0x3e, 0x21 },
};
static const unsigned char vec3_aux_rands[3][32] = {
    { 0x43, 0xbb, 0x36, 0xca, 0xf9, 0x05, 0x46, 0x37, 0xdf, 0x41, 0x06, 0x33, 0x10, 0x0c, 0x83, 0x4c, 0x96, 0x5f, 0x6b, 0x88, 0xe9, 0x4c, 0x54, 0x7a, 0x88, 0x0d, 0xce, 0x85, 0x7a, 0xd9, 0x58, 0x66 },
    { 0x01, 0x96, 0xeb, 0x2f, 0x75, 0x84, 0x78, 0x28, 0x2d, 0x0a, 0x8f, 0x73, 0x55, 0x90, 0x22, 0x8c, 0x2d, 0x26, 0xef, 0xfe, 0x9e, 0xad, 0xf8, 0x4b, 0xf2, 0xfe, 0x5d, 0xa0, 0x94, 0x3e, 0x64, 0x03 },
    { 0x4a, 0xee, 0x4b, 0xc4, 0x92, 0x1b, 0xf2, 0x6e, 0xf1, 0xe2, 0x25, 0x75, 0x1b, 0x4f, 0x5f, 0x3d, 0x5f, 0x9a, 0x16, 0x08, 0x04, 0x45, 0x18, 0x5c, 0x98, 0xb5, 0xbf, 0xb1, 0x70, 0xa7, 0x0a, 0x0d },
};
static const unsigned char vec3_pmsgs1[3][259] = {
    { 0x03, 0x13, 0xa8, 0x3d, 0xe5, 0x5f, 0xc3, 0xef, 0x04, 0xe3, 0xd5, 0x0b, 0xe3, 0xe5, 0xae, 0x6f, 0x7d, 0xc8, 0x17, 0x5c, 0x03, 0x61, 0xa2, 0x87, 0xe3, 0x05, 0xac, 0x24, 0xb7, 0xdb, 0x90, 0x5b, 0xa0, 0x02, 0x8e, 0x23, 0x9d, 0x76, 0x52, 0xf4, 0xe2, 0x7b, 0x8f, 0xf7, 0x3b, 0xce, 0xe1, 0xd5, 0xb4, 0xea, 0xf3, 0xc4, 0x1b, 0xef, 0x9d, 0xfc, 0xae, 0x10, 0x53, 0x51, 0xc3, 0x5d, 0xce, 0x73, 0x15, 0xaf, 0x5a, 0x61, 0xbc, 0x3f, 0x93, 0x88, 0x46, 0xad, 0x6e, 0x75, 0x60, 0x32, 0xaf, 0x07, 0x13, 0x50, 0xa5, 0x7f, 0x4d, 0xe5, 0xcc, 0x19, 0x2c, 0xb8, 0x94, 0xc9, 0x05, 0x7e, 0xd1, 0x98, 0x92, 0x80, 0xf4, 0xba, 0x10, 0x30, 0xe5, 0x6a, 0x11, 0xe9, 0xfa, 0xf6, 0x6c, 0xe9, 0x15, 0xcc, 0x29, 0x19, 0xb6, 0x5c, 0x91, 0x3c, 0xbf, 0xcf, 0xf1, 0x92, 0x88, 0xf6, 0xd5, 0x6f, 0x0a, 0x19, 0xb9, 0x06, 0x03, 0x14, 0x18, 0x10, 0xaf, 0x9a, 0x1b, 0x7c, 0x34, 0x27, 0x0a, 0x83, 0xaa, 0x52, 0x62, 0xc2, 0xbe, 0x22, 0x4a, 0x4c, 0x6b, 0xde, 0x0d, 0xc4, 0xdf, 0xda, 0xd1, 0xc2, 0x7f, 0x09, 0x3b, 0x9b, 0x38, 0xea, 0x7b, 0xb3, 0xd7, 0x0c, 0xfc, 0x81, 0x31, 0xe7, 0x7c, 0x63, 0x93, 0xad, 0x2a, 0x28, 0xd7, 0x8b, 0x5a, 0xda, 0x3b, 0xc4, 0x18, 0x5a, 0xcb, 0x64, 0x49, 0x5a, 0x4d, 0xfe, 0xde, 0xd9, 0x82, 0xd7, 0xcc, 0x01, 0x2a, 0x67, 0x40, 0x5b, 0x09, 0xe8, 0x61, 0xbd, 0xa2, 0x72, 0xb8, 0x23, 0x1f, 0xa6, 0xaa, 0xe5, 0xee, 0xdd, 0x01, 0x35, 0xa4, 0x13, 0x5d, 0x08, 0xa5, 0xc5, 0x5c, 0xd9, 0xd4, 0xe1, 0x0e, 0x48, 0x6f, 0x44, 0x6c, 0x29, 0x72, 0xe2, 0x25, 0x06, 0x25, 0x37, 0x0e, 0x28, 0x3f, 0x69, 0x26, 0xc2, 0xc1, 0x79, 0x50, 0xad, 0x0a, 0x0b, 0x20, 0xc1, 0xce, 0x41, 0xe1, 0xff, 0x66 },
    { 0x03, 0x98, 0xf0, 0x88, 0x65, 0x27, 0x59, 0x6b, 0x2c, 0x49, 0xf6, 0xa3, 0xf6, 0x58, 0x46, 0x52, 0x76, 0xdf, 0x6c, 0xd5, 0xc6, 0x68, 0xe2, 0xdf, 0x88, 0x6b, 0xe6, 0x15, 0x81, 0x60, 0x5e, 0x10, 0xa7, 0x02, 0x8c, 0x88, 0x50, 0xb8, 0x9e, 0xe9, 0xb1, 0xe9, 0x89, 0x8a, 0xb2, 0x61, 0x91, 0xb4, 0xf4, 0xc2, 0x9e, 0x9b, 0x7b, 0x0f, 0x71, 0x27, 0x05, 0xe3, 0xd9, 0x54, 0xb0, 0xaf, 0xa1, 0x40, 0x3c, 0x6c, 0xc5, 0xe6, 0x8a, 0xcd, 0xb0, 0xaf, 0x07, 0x62, 0xb1, 0x3f, 0x24, 0xeb, 0x34, 0xd0, 0x39, 0x72, 0xd5, 0x34, 0xcc, 0x72, 0x02, 0x0c, 0x10, 0x19, 0x44, 0x00, 0xd0, 0x21, 0x3f, 0x0d, 0x7f, 0x1e, 0x0d, 0x08, 0xaa, 0xd3, 0xec, 0x21, 0xff, 0x9b, 0xc7, 0xcb, 0x04, 0x97, 0x79, 0x27, 0xd7, 0xc6, 0xe6, 0xbb, 0x4f, 0x0d, 0x88, 0x7a, 0x70, 0x4a, 0x7d, 0xbd, 0x65, 0x8f, 0xa3, 0xc3, 0xc9, 0x2d, 0x03, 0x77, 0xb8, 0xeb, 0x7f, 0x3c, 0xf3, 0x08, 0x9a, 0xeb, 0x55, 0x77, 0xeb, 0xb3, 0x7a, 0xf4, 0x84, 0x25, 0x91, 0xcf, 0x6c, 0x97, 0x42, 0xa4, 0x8e, 0xc6, 0x56, 0xdb, 0xb8, 0xf2, 0x50, 0xf7, 0x09, 0xaf, 0xa6, 0x65, 0x5c, 0xee, 0xee, 0x61, 0x74, 0x28, 0x40, 0xb7, 0xf1, 0xaf, 0x76, 0x0d, 0xf2, 0xf6, 0xcc, 0x6d, 0x4e, 0xe0, 0x5a, 0x9a, 0xd1, 0xfc, 0x7b, 0x5d, 0x86, 0x5c, 0x42, 0xc0, 0x52, 0xd5, 0xb6, 0x97, 0xb0, 0x91, 0xdb, 0xf8, 0xde, 0x6d, 0x2d, 0x81, 0xab, 0xff, 0xb5, 0xf0, 0xcb, 0x75, 0xbd, 0x86, 0xe3, 0x86, 0x04, 0x15, 0x68, 0x05, 0x5e, 0xe2, 0xb4, 0x8f, 0x7c, 0xfc, 0x3d, 0x91, 0x54, 0x76, 0x91, 0x11, 0x18, 0x25, 0x84, 0xf4, 0xf9, 0xdf, 0xad, 0x29, 0xc6, 0x2b, 0x57, 0xc1, 0xf1, 0xe4, 0xa5, 0x40, 0xc0, 0x7f, 0xcb, 0x18, 0x65, 0x07, 0x5c, 0xb2, 0x14, 0x6c, 0x2b },
    { 0x02, 0xc0, 0xa6, 0xde, 0xcb, 0x4a, 0xd7, 0x34, 0xe9, 0xec, 0x43, 0xbd, 0x50, 0xf3, 0xa6, 0xd6, 0xe8, 0xad, 0xa8, 0x38, 0xe8, 0x44, 0x40, 0x0b, 0xfe, 0x14, 0x7e, 0x46, 0xc8, 0xa1, 0x61, 0x5a, 0x2e, 0x03, 0xc8, 0x14, 0xb5, 0xe1, 0x99, 0xff, 0x42, 0x88, 0x52, 0x78, 0x52, 0x96, 0xc4, 0x57, 0x06, 0x65, 0xde, 0x04, 0x58, 0x15, 0x99, 0xc3, 0xb0, 0xcd, 0x24, 0x7e, 0x67, 0x0c, 0x15, 0x51, 0x01, 0xc2, 0x7b, 0x09, 0xdd, 0x3d, 0x86, 0x90, 0xba, 0x4c, 0x1d, 0x65, 0x33, 0x07, 0x50, 0x7a, 0x2c, 0xb3, 0x06, 0x9e, 0xab, 0xbd, 0xe2, 0xb6, 0xe2, 0x4f, 0x0d, 0x79, 0xb4, 0x0a, 0xb4, 0x90, 0xae, 0x89, 0x48, 0xcc, 0x90, 0x5a, 0x4d, 0xc5, 0xc2, 0xe0, 0x59, 0xda, 0x08, 0x33, 0x1b, 0x82, 0x40, 0x51, 0xfa, 0x0b, 0x07, 0x93, 0xe3, 0x6d, 0x96, 0xaf, 0xeb, 0xf6, 0xfc, 0xef, 0x85, 0x1b, 0x21, 0x94, 0x03, 0xfc, 0x22, 0xdc, 0xf0, 0xed, 0xd5, 0x9e, 0xdf, 0x52, 0xab, 0x06, 0xeb, 0xce, 0xba, 0x18, 0x33, 0x7d, 0x00, 0xec, 0x2e, 0xf5, 0x57, 0xcd, 0x23, 0x70, 0xe4, 0x82, 0x07, 0x2b, 0x51, 0x6d, 0x37, 0x6b, 0xc6, 0x34, 0x69, 0xb1, 0x4e, 0x16, 0xc0, 0x90, 0xdf, 0x4a, 0xc9, 0x3b, 0x3d, 0xbc, 0xee, 0xee, 0x29, 0x96, 0x3e, 0xa4, 0x87, 0x2b, 0x9a, 0xb2, 0x59, 0x4f, 0x81, 0x45, 0xaf, 0xfc, 0x3a, 0xfe, 0x8b, 0xfb, 0x90, 0x3d, 0x9b, 0x91, 0xde, 0x14, 0x0f, 0xee, 0xfb, 0x7a, 0x30, 0x67, 0x6d, 0x0d, 0x0f, 0x0e, 0xe7, 0xd9, 0x1b, 0xb8, 0x99, 0xcf, 0xe6, 0xf9, 0x2c, 0x74, 0x1f, 0xb5, 0xb8, 0x20, 0xab, 0x89, 0x01, 0x21, 0x83, 0xf7, 0x65, 0x7e, 0x27, 0x60, 0xf6, 0xa6, 0x73, 0xfa, 0xef, 0x33, 0x72, 0x77, 0xd3, 0xdc, 0x12, 0xc2, 0xe3, 0x87, 0xa9, 0xd4, 0x57, 0x80, 0x89, 0xab, 0xa2 },
};
static const unsigned char vec3_cmsg1[519] = { 0x03, 0x13, 0xa8, 0x3d, 0xe5, 0x5f, 0xc3, 0xef, 0x04, 0xe3, 0xd5, 0x0b, 0xe3, 0xe5, 0xae, 0x6f, 0x7d, 0xc8, 0x17, 0x5c, 0x03, 0x61, 0xa2, 0x87, 0xe3, 0x05, 0xac, 0x24, 0xb7, 0xdb, 0x90, 0x5b, 0xa0, 0x03, 0x98, 0xf0, 0x88, 0x65, 0x27, 0x59, 0x6b, 0x2c, 0x49, 0xf6, 0xa3, 0xf6, 0x58, 0x46, 0x52, 0x76, 0xdf, 0x6c, 0xd5, 0xc6, 0x68, 0xe2, 0xdf, 0x88, 0x6b, 0xe6, 0x15, 0x81, 0x60, 0x5e, 0x10, 0xa7, 0x02, 0xc0, 0xa6, 0xde, 0xcb, 0x4a, 0xd7, 0x34, 0xe9, 0xec, 0x43, 0xbd, 0x50, 0xf3, 0xa6, 0xd6, 0xe8, 0xad, 0xa8, 0x38, 0xe8, 0x44, 0x40, 0x0b, 0xfe, 0x14, 0x7e, 0x46, 0xc8, 0xa1, 0x61, 0x5a, 0x2e, 0x03, 0xe5, 0x85, 0xdb, 0x07, 0xe5, 0x5b, 0xe4, 0x78, 0x39, 0x99, 0xeb, 0xae, 0x7a, 0x14, 0xe0, 0x02, 0x32, 0x42, 0x98, 0x8f, 0x93, 0x8d, 0x44, 0x71, 0x9b, 0x3a, 0x52, 0xae, 0x63, 0xed, 0x0b, 0x6d, 0x5a, 0x61, 0xbc, 0x3f, 0x93, 0x88, 0x46, 0xad, 0x6e, 0x75, 0x60, 0x32, 0xaf, 0x07, 0x13, 0x50, 0xa5, 0x7f, 0x4d, 0xe5, 0xcc, 0x19, 0x2c, 0xb8, 0x94, 0xc9, 0x05, 0x7e, 0xd1, 0x98, 0x92, 0x80, 0xf4, 0xba, 0x10, 0x30, 0xe5, 0x6a, 0x11, 0xe9, 0xfa, 0xf6, 0x6c, 0xe9, 0x15, 0xcc, 0x29, 0x19, 0xb6, 0x5c, 0x91, 0x3c, 0xbf, 0xcf, 0xf1, 0x92, 0x88, 0xf6, 0xd5, 0x6f, 0x0a, 0x19, 0xb9, 0x06, 0xc5, 0xe6, 0x8a, 0xcd, 0xb0, 0xaf, 0x07, 0x62, 0xb1, 0x3f, 0x24, 0xeb, 0x34, 0xd0, 0x39, 0x72, 0xd5, 0x34, 0xcc, 0x72, 0x02, 0x0c, 0x10, 0x19, 0x44, 0x00, 0xd0, 0x21, 0x3f, 0x0d, 0x7f, 0x1e, 0x0d, 0x08, 0xaa, 0xd3, 0xec, 0x21, 0xff, 0x9b, 0xc7, 0xcb, 0x04, 0x97, 0x79, 0x27, 0xd7, 0xc6, 0xe6, 0xbb, 0x4f, 0x0d, 0x88, 0x7a, 0x70, 0x4a, 0x7d, 0xbd, 0x65, 0x8f, 0xa3, 0xc3, 0xc9, 0x2d, 0x7b, 0x09, 0xdd, 0x3d, 0x86, 0x90, 0xba, 0x4c, 0x1d, 0x65, 0x33, 0x07, 0x50, 0x7a, 0x2c, 0xb3, 0x06, 0x9e, 0xab, 0xbd, 0xe2, 0xb6, 0xe2, 0x4f, 0x0d, 0x79, 0xb4, 0x0a, 0xb4, 0x90, 0xae, 0x89, 0x48, 0xcc, 0x90, 0x5a, 0x4d, 0xc5, 0xc2, 0xe0, 0x59, 0xda, 0x08, 0x33, 0x1b, 0x82, 0x40, 0x51, 0xfa, 0x0b, 0x07, 0x93, 0xe3, 0x6d, 0x96, 0xaf, 0xeb, 0xf6, 0xfc, 0xef, 0x85, 0x1b, 0x21, 0x94, 0x03, 0x14, 0x18, 0x10, 0xaf, 0x9a, 0x1b, 0x7c, 0x34, 0x27, 0x0a, 0x83, 0xaa, 0x52, 0x62, 0xc2, 0xbe, 0x22, 0x4a, 0x4c, 0x6b, 0xde, 0x0d, 0xc4, 0xdf, 0xda, 0xd1, 0xc2, 0x7f, 0x09, 0x3b, 0x9b, 0x38, 0x03, 0x77, 0xb8, 0xeb, 0x7f, 0x3c, 0xf3, 0x08, 0x9a, 0xeb, 0x55, 0x77, 0xeb, 0xb3, 0x7a, 0xf4, 0x84, 0x25, 0x91, 0xcf, 0x6c, 0x97, 0x42, 0xa4, 0x8e, 0xc6, 0x56, 0xdb, 0xb8, 0xf2, 0x50, 0xf7, 0x09, 0x03, 0xfc, 0x22, 0xdc, 0xf0, 0xed, 0xd5, 0x9e, 0xdf, 0x52, 0xab, 0x06, 0xeb, 0xce, 0xba, 0x18, 0x33, 0x7d, 0x00, 0xec, 0x2e, 0xf5, 0x57, 0xcd, 0x23, 0x70, 0xe4, 0x82, 0x07, 0x2b, 0x51, 0x6d, 0x37, 0x05, 0xe8, 0x4d, 0x9d, 0xad, 0x38, 0xf9, 0x66, 0xa0, 0x9c, 0x66, 0x4e, 0x97, 0xdd, 0xf3, 0xbb, 0xfa, 0xf3, 0x23, 0xfb, 0xea, 0x68, 0xe0, 0xc0, 0x93, 0x79, 0x4a, 0x3c, 0x00, 0x65, 0x13, 0x8c, 0xac, 0x0e, 0x94, 0x6b, 0x36, 0xb7, 0xe5, 0xc6, 0x69, 0x9f, 0x2e, 0x49, 0xec, 0x9e, 0x7b, 0x5a, 0xb4, 0x19, 0xc1, 0xec, 0xdd, 0x8f, 0xc3, 0x2e, 0x68, 0xfe, 0x27, 0x6d, 0x28, 0x8d, 0x09, 0x47, 0x93, 0x0e, 0x48, 0x01, 0x77, 0x08, 0x46, 0x5d, 0x55, 0x46, 0x46, 0xc9, 0x07, 0x48, 0x4e, 0x87, 0xa3, 0xdc, 0x42, 0x53, 0xe6, 0xdb, 0x4f, 0x7c, 0xeb, 0x5d, 0x3e, 0xf5, 0xa4, 0x49, 0xd5, 0xf2 };
static const unsigned char vec3_pmsgs2[3][64] = {
    { 0x09, 0x1e, 0xab, 0x60, 0x71, 0x94, 0x54, 0x81, 0xfb, 0x97, 0xd0, 0x1c, 0x93, 0xdc, 0x2d, 0xd2, 0xcb, 0xea, 0xbc, 0xa1, 0xb0, 0x9a, 0xd6, 0x65, 0x85, 0xa4, 0x25, 0x84, 0xf2, 0x8d, 0xeb, 0xb3, 0x2c, 0x20, 0x4e, 0xc5, 0xe0, 0x5d, 0xaf, 0xd5, 0xc9, 0xf2, 0x65, 0xce, 0x1a, 0x2b, 0xa4, 0x50, 0x1b, 0x4a, 0x1b, 0x9a, 0x0e, 0x97, 0xc7, 0xf4, 0xb3, 0x4f, 0x86, 0x23, 0x31, 0x85, 0x54, 0xe5 },
    { 0x4f, 0x38, 0xc9, 0x07, 0xc0, 0x20, 0x29, 0xb9, 0x8d, 0x8b, 0x65, 0xa1, 0xc1, 0xbb, 0x24, 0x89, 0x64, 0x38, 0xc0, 0x71, 0xef, 0xd6, 0xa4, 0x90, 0x96, 0x4e, 0x9d, 0x83, 0x23, 0x8a, 0x98, 0xf0, 0xd3, 0x06, 0xf3, 0xc9, 0x4c, 0xa1, 0x50, 0x07, 0x57, 0x89, 0xc6, 0xfc, 0xe8, 0xb8, 0x02, 0xf2, 0x36, 0xfd, 0xcd, 0xf5, 0x8e, 0x5a, 0x1c, 0x65, 0x21, 0x4d, 0xa2, 0x7f, 0xed, 0x3e, 0xa6, 0xed },
    { 0x8b, 0x92, 0x3f, 0xae, 0x45, 0x7c, 0xb0, 0x5c, 0x36, 0x9f, 0x7d, 0x9d, 0x84, 0x28, 0xa2, 0x2c, 0x63, 0x0a, 0x62, 0xeb, 0x6b, 0x51, 0x89, 0x11, 0x54, 0x6a, 0x96, 0xf7, 0x45, 0x88, 0xc1, 0x4a, 0xbd, 0x63, 0xa7, 0xfa, 0x16, 0x9e, 0x17, 0xd9, 0xc5, 0x97, 0x4b, 0x0b, 0xe6, 0xc5, 0x92, 0xfe, 0x48, 0x6b, 0xec, 0xfc, 0xfd, 0xea, 0x76, 0xa3, 0xfa, 0x92, 0xa7, 0x2f, 0xba, 0x1e, 0x7b, 0xef },
};
static const unsigned char vec3_cmsg2[192] = { 0x09, 0x1e, 0xab, 0x60, 0x71, 0x94, 0x54, 0x81, 0xfb, 0x97, 0xd0, 0x1c, 0x93, 0xdc, 0x2d, 0xd2, 0xcb, 0xea, 0xbc, 0xa1, 0xb0, 0x9a, 0xd6, 0x65, 0x85, 0xa4, 0x25, 0x84, 0xf2, 0x8d, 0xeb, 0xb3, 0x2c, 0x20, 0x4e, 0xc5, 0xe0, 0x5d, 0xaf, 0xd5, 0xc9, 0xf2, 0x65, 0xce, 0x1a, 0x2b, 0xa4, 0x50, 0x1b, 0x4a, 0x1b, 0x9a, 0x0e, 0x97, 0xc7, 0xf4, 0xb3, 0x4f, 0x86, 0x23, 0x31, 0x85, 0x54, 0xe5, 0x4f, 0x38, 0xc9, 0x07, 0xc0, 0x20, 0x29, 0xb9, 0x8d, 0x8b, 0x65, 0xa1, 0xc1, 0xbb, 0x24, 0x89, 0x64, 0x38, 0xc0, 0x71, 0xef, 0xd6, 0xa4, 0x90, 0x96, 0x4e, 0x9d, 0x83, 0x23, 0x8a, 0x98, 0xf0, 0xd3, 0x06, 0xf3, 0xc9, 0x4c, 0xa1, 0x50, 0x07, 0x57, 0x89, 0xc6, 0xfc, 0xe8, 0xb8, 0x02, 0xf2, 0x36, 0xfd, 0xcd, 0xf5, 0x8e, 0x5a, 0x1c, 0x65, 0x21, 0x4d, 0xa2, 0x7f, 0xed, 0x3e, 0xa6, 0xed, 0x8b, 0x92, 0x3f, 0xae, 0x45, 0x7c, 0xb0, 0x5c, 0x36, 0x9f, 0x7d, 0x9d, 0x84, 0x28, 0xa2, 0x2c, 0x63, 0x0a, 0x62, 0xeb, 0x6b, 0x51, 0x89, 0x11, 0x54, 0x6a, 0x96, 0xf7, 0x45, 0x88, 0xc1, 0x4a, 0xbd, 0x63, 0xa7, 0xfa, 0x16, 0x9e, 0x17, 0xd9, 0xc5, 0x97, 0x4b, 0x0b, 0xe6, 0xc5, 0x92, 0xfe, 0x48, 0x6b, 0xec, 0xfc, 0xfd, 0xea, 0x76, 0xa3, 0xfa, 0x92, 0xa7, 0x2f, 0xba, 0x1e, 0x7b, 0xef };
static const unsigned char vec3_secshares[3][32] = {
    { 0x38, 0xf8, 0x44, 0xd4, 0x6d, 0xf1, 0xf9, 0x51, 0x56, 0x40, 0x60, 0x09, 0xb7, 0x04, 0x11, 0xcf, 0x88, 0x02, 0x4c, 0xa6, 0xd6, 0x4a, 0x37, 0x06, 0x9f, 0x44, 0x97, 0x10, 0x7d, 0x3d, 0x47, 0x33 },
    { 0x01, 0x1d, 0x1f, 0x86, 0x77, 0xaf, 0x70, 0x71, 0xcf, 0x89, 0xf6, 0x3f, 0x94, 0xad, 0xf7, 0x7c, 0xfa, 0xe7, 0xca, 0xb3, 0x28, 0xd4, 0x4d, 0x5e, 0x24, 0x29, 0x5e, 0x06, 0x77, 0xda, 0x3b, 0xfe },
    { 0xc9, 0x41, 0xfa, 0x38, 0x81, 0x6c, 0xe7, 0x92, 0x48, 0xd3, 0x8c, 0x75, 0x72, 0x57, 0xdd, 0x29, 0x28, 0x7c, 0x25, 0xa6, 0x2a, 0xa7, 0x03, 0xf1, 0x68, 0xe0, 0x83, 0x89, 0x42, 0xad, 0x72, 0x0a },
};
static const unsigned char vec3_thresh_pk[33] = { 0x03, 0x07, 0xf3, 0xc6, 0x29, 0x69, 0xf9, 0xee, 0xaf, 0xb9, 0xf3, 0xd6, 0x25, 0xcb, 0xa6, 0xe8, 0x09, 0x00, 0x17, 0x04, 0xc0, 0x92, 0xd7, 0xca, 0xac, 0x49, 0x6f, 0xd3, 0xed, 0x07, 0x35, 0x23, 0x2c };
static const unsigned char vec3_pubshares[3][33] = {
    { 0x02, 0x2a, 0x8d, 0x1c, 0x2a, 0x1c, 0x95, 0x97, 0x89, 0xdf, 0xa2, 0xb5, 0xc4, 0xc2, 0x97, 0xdb, 0xc9, 0x09, 0x6b, 0xb7, 0xd7, 0x20, 0x1f, 0xe6, 0x67, 0x38, 0x13, 0xae, 0xff, 0x9f, 0xbc, 0x58, 0xba },
    { 0x03, 0x1a, 0x40, 0x20, 0x79, 0x6b, 0x0c, 0x5f, 0x0e, 0x4a, 0x67, 0xd2, 0x74, 0x8f, 0xd2, 0xea, 0x93, 0x65, 0x2c, 0xae, 0x41, 0x0f, 0xf0, 0x2d, 0x45, 0x79, 0x8a, 0x44, 0xb4, 0x50, 0x8f, 0xd5, 0x4d },
    { 0x02, 0xea, 0xad, 0x03, 0x65, 0xfe, 0x7e, 0xa9, 0xea, 0xd9, 0x30, 0x44, 0xb9, 0x68, 0xf6, 0xe7, 0x18, 0x51, 0xe5, 0xac, 0xd3, 0x80, 0x92, 0x11, 0xd8, 0x4d, 0xe2, 0xd7, 0x3a, 0xf6, 0xf9, 0x4a, 0xee },
};
static const unsigned char vec3_recovery[556] = { 0x00, 0x00, 0x00, 0x02, 0x03, 0xdd, 0xe3, 0x46, 0x0b, 0x06, 0x56, 0x58, 0xf6, 0x85, 0x78, 0x85, 0xee, 0x42, 0xa8, 0xfa, 0x9c, 0x53, 0xd6, 0x3d, 0x75, 0x02, 0x16, 0x65, 0x03, 0xf1, 0xb6, 0x6a, 0x56, 0xb9, 0x76, 0xa2, 0x70, 0x03, 0xe5, 0x85, 0xdb, 0x07, 0xe5, 0x5b, 0xe4, 0x78, 0x39, 0x99, 0xeb, 0xae, 0x7a, 0x14, 0xe0, 0x02, 0x32, 0x42, 0x98, 0x8f, 0x93, 0x8d, 0x44, 0x71, 0x9b, 0x3a, 0x52, 0xae, 0x63, 0xed, 0x0b, 0x6d, 0x02, 0x2d, 0x9b, 0xc8, 0xa8, 0x44, 0x57, 0xc7, 0x51, 0x00, 0x1f, 0x71, 0x4a, 0xd9, 0xac, 0x72, 0x82, 0x8a, 0x01, 0xe5, 0x31, 0xbe, 0x63, 0xe7, 0xfc, 0x3c, 0x4d, 0x37, 0x0c, 0x2f, 0xec, 0xd8, 0x43, 0x03, 0x34, 0xbe, 0xe4, 0x54, 0x9f, 0x86, 0x95, 0xd8, 0x96, 0xa3, 0xf0, 0x60, 0x40, 0xe0, 0x26, 0x3c, 0x41, 0x90, 0x54, 0xf3, 0xb8, 0xc7, 0x83, 0xa7, 0x7a, 0x77, 0x02, 0x82, 0x86, 0x14, 0x97, 0x3a, 0x02, 0x85, 0xe6, 0xb7, 0xa7, 0xfb, 0x26, 0x5f, 0x38, 0xb9, 0xad, 0xc3, 0x9e, 0x51, 0xd4, 0xac, 0x2d, 0xfb, 0x0f, 0x31, 0xa6, 0xf1, 0x8e, 0x7f, 0xf8, 0xae, 0x2f, 0x3c, 0xa7, 0xbc, 0xaa, 0x7d, 0xcf, 0x03, 0x14, 0x18, 0x10, 0xaf, 0x9a, 0x1b, 0x7c, 0x34, 0x27, 0x0a, 0x83, 0xaa, 0x52, 0x62, 0xc2, 0xbe, 0x22, 0x4a, 0x4c, 0x6b, 0xde, 0x0d, 0xc4, 0xdf, 0xda, 0xd1, 0xc2, 0x7f, 0x09, 0x3b, 0x9b, 0x38, 0x03, 0x77, 0xb8, 0xeb, 0x7f, 0x3c, 0xf3, 0x08, 0x9a, 0xeb, 0x55, 0x77, 0xeb, 0xb3, 0x7a, 0xf4, 0x84, 0x25, 0x91, 0xcf, 0x6c, 0x97, 0x42, 0xa4, 0x8e, 0xc6, 0x56, 0xdb, 0xb8, 0xf2, 0x50, 0xf7, 0x09, 0x03, 0xfc, 0x22, 0xdc, 0xf0, 0xed, 0xd5, 0x9e, 0xdf, 0x52, 0xab, 0x06, 0xeb, 0xce, 0xba, 0x18, 0x33, 0x7d, 0x00, 0xec, 0x2e, 0xf5, 0x57, 0xcd, 0x23, 0x70, 0xe4, 0x82, 0x07, 0x2b, 0x51, 0x6d, 0x37, 0x05, 0xe8, 0x4d, 0x9d, 0xad, 0x38, 0xf9, 0x66, 0xa0, 0x9c, 0x66, 0x4e, 0x97, 0xdd, 0xf3, 0xbb, 0xfa, 0xf3, 0x23, 0xfb, 0xea, 0x68, 0xe0, 0xc0, 0x93, 0x79, 0x4a, 0x3c, 0x00, 0x65, 0x13, 0x8c, 0xac, 0x0e, 0x94, 0x6b, 0x36, 0xb7, 0xe5, 0xc6, 0x69, 0x9f, 0x2e, 0x49, 0xec, 0x9e, 0x7b, 0x5a, 0xb4, 0x19, 0xc1, 0xec, 0xdd, 0x8f, 0xc3, 0x2e, 0x68, 0xfe, 0x27, 0x6d, 0x28, 0x8d, 0x09, 0x47, 0x93, 0x0e, 0x48, 0x01, 0x77, 0x08, 0x46, 0x5d, 0x55, 0x46, 0x46, 0xc9, 0x07, 0x48, 0x4e, 0x87, 0xa3, 0xdc, 0x42, 0x53, 0xe6, 0xdb, 0x4f, 0x7c, 0xeb, 0x5d, 0x3e, 0xf5, 0xa4, 0x49, 0xd5, 0xf2, 0x09, 0x1e, 0xab, 0x60, 0x71, 0x94, 0x54, 0x81, 0xfb, 0x97, 0xd0, 0x1c, 0x93, 0xdc, 0x2d, 0xd2, 0xcb, 0xea, 0xbc, 0xa1, 0xb0, 0x9a, 0xd6, 0x65, 0x85, 0xa4, 0x25, 0x84, 0xf2, 0x8d, 0xeb, 0xb3, 0x2c, 0x20, 0x4e, 0xc5, 0xe0, 0x5d, 0xaf, 0xd5, 0xc9, 0xf2, 0x65, 0xce, 0x1a, 0x2b, 0xa4, 0x50, 0x1b, 0x4a, 0x1b, 0x9a, 0x0e, 0x97, 0xc7, 0xf4, 0xb3, 0x4f, 0x86, 0x23, 0x31, 0x85, 0x54, 0xe5, 0x4f, 0x38, 0xc9, 0x07, 0xc0, 0x20, 0x29, 0xb9, 0x8d, 0x8b, 0x65, 0xa1, 0xc1, 0xbb, 0x24, 0x89, 0x64, 0x38, 0xc0, 0x71, 0xef, 0xd6, 0xa4, 0x90, 0x96, 0x4e, 0x9d, 0x83, 0x23, 0x8a, 0x98, 0xf0, 0xd3, 0x06, 0xf3, 0xc9, 0x4c, 0xa1, 0x50, 0x07, 0x57, 0x89, 0xc6, 0xfc, 0xe8, 0xb8, 0x02, 0xf2, 0x36, 0xfd, 0xcd, 0xf5, 0x8e, 0x5a, 0x1c, 0x65, 0x21, 0x4d, 0xa2, 0x7f, 0xed, 0x3e, 0xa6, 0xed, 0x8b, 0x92, 0x3f, 0xae, 0x45, 0x7c, 0xb0, 0x5c, 0x36, 0x9f, 0x7d, 0x9d, 0x84, 0x28, 0xa2, 0x2c, 0x63, 0x0a, 0x62, 0xeb, 0x6b, 0x51, 0x89, 0x11, 0x54, 0x6a, 0x96, 0xf7, 0x45, 0x88, 0xc1, 0x4a, 0xbd, 0x63, 0xa7, 0xfa, 0x16, 0x9e, 0x17, 0xd9, 0xc5, 0x97, 0x4b, 0x0b, 0xe6, 0xc5, 0x92, 0xfe, 0x48, 0x6b, 0xec, 0xfc, 0xfd, 0xea, 0x76, 0xa3, 0xfa, 0x92, 0xa7, 0x2f, 0xba, 0x1e, 0x7b, 0xef };
/* chilldkg session n = 3, t = 2 */
/* all python-side sanity checks passed */

static const unsigned char vec5_hostseckeys[3][32] = {
    { 0x12, 0x83, 0xa7, 0x64, 0x03, 0x38, 0xef, 0x46, 0x92, 0x13, 0x25, 0xa8, 0x3e, 0xae, 0x85, 0x94, 0x58, 0x52, 0x0a, 0x93, 0x5a, 0x17, 0x9d, 0xe9, 0x1c, 0xba, 0x39, 0xd8, 0xb6, 0xf9, 0x3d, 0xbf },
    { 0xd2, 0xd5, 0x5c, 0xf8, 0x10, 0xd0, 0x93, 0xcc, 0xfb, 0xff, 0xdd, 0x89, 0x65, 0x13, 0x59, 0x79, 0xa7, 0x3f, 0x5f, 0x70, 0x06, 0x20, 0x3e, 0x0f, 0x1f, 0x57, 0x20, 0x90, 0x1a, 0x0d, 0x3e, 0xf2 },
    { 0x70, 0x86, 0x80, 0x07, 0x06, 0x69, 0xf8, 0x6b, 0x8f, 0x14, 0x24, 0xb3, 0x93, 0xdd, 0x03, 0x03, 0xd6, 0x63, 0xa6, 0xa9, 0x1f, 0x85, 0x2d, 0x03, 0x34, 0xae, 0x64, 0xac, 0xdd, 0x17, 0x72, 0x34 },
};
static const unsigned char vec5_hostpubkeys[3][33] = {
    { 0x03, 0x4f, 0x68, 0x91, 0xb1, 0xd2, 0x7f, 0x67, 0xd3, 0xbb, 0x8a, 0xd4, 0x80, 0x83, 0x1a, 0x3d, 0x80, 0x7f, 0x58, 0xed, 0x42, 0x21, 0x6c, 0x94, 0x9b, 0xd0, 0xc7, 0x8a, 0x51, 0x9c, 0xbe, 0x76, 0xe0 },
    { 0x02, 0xfb, 0x7e, 0x20, 0xfb, 0xa2, 0x87, 0xee, 0x46, 0xb9, 0x53, 0x62, 0x32, 0xf6, 0x9c, 0x31, 0xa9, 0x0c, 0x66, 0xea, 0xf1, 0xfd, 0x67, 0x18, 0xdd, 0xdc, 0x1f, 0x10, 0xaa, 0x15, 0xf8, 0xa3, 0x4f },
    { 0x03, 0x59, 0x5a, 0x19, 0x3f, 0xe6, 0xe8, 0xf1, 0xf4, 0x36, 0x00, 0x79, 0x4e, 0x19, 0x39, 0xaa, 0x29, 0x04, 0x1f, 0x3b, 0xc1, 0xd3, 0x29, 0x49, 0x1e, 0x88, 0x38, 0x32, 0x19, 0x74, 0x8c, 0x2f, 0xa5 },
};
static const unsigned char vec5_randoms[3][32] = {
    { 0xa8, 0xfa, 0xcd, 0xc0, 0x2b, 0x1f, 0xcf, 0x2a, 0x0f, 0x0e, 0xd0, 0x22, 0xe5, 0x59, 0x53, 0xb2, 0xf6, 0xf7, 0x96, 0x9e, 0x49, 0x55, 0x96, 0xde, 0xa9, 0x2c, 0xd4, 0x3d, 0xed, 0x48, 0x3a, 0x24 },
    { 0xe9, 0xfb, 0x8f, 0x6b, 0x5e, 0x9a, 0x21, 0xc2, 0x16, 0x58, 0xbd, 0x75, 0x7e, 0x66, 0xda, 0x5f, 0x5c, 0x8f, 0xe6, 0x6b, 0x39, 0xf3, 0xca, 0x82, 0xf0, 0xd9, 0xe7, 0x5e, 0x49, 0x00, 0xde, 0xbd },
    { 0xed, 0xf0, 0x7d, 0x54, 0x83, 0x08, 0xea, 0xf8, 0x85, 0x83, 0x38, 0x0b, 0xb2, 0xf4, 0xf0, 0x5d, 0x42, 0x4a, 0x7d, 0x2f, 0x6d, 0xed, 0x43, 0x36, 0xd7, 0x7e, 0xc4, 0x63, 0x59, 0x72, 0x37, 0x5f },
};
static const unsigned char vec5_aux_rands[3][32] = {
    { 0xb7, 0x35, 0xae, 0xe7, 0x29, 0x77, 0x3e, 0x4f, 0xdd, 0xc1, 0x89, 0x15, 0xb7, 0xb1, 0x93, 0x5f, 0x86, 0x7c, 0xe1, 0x08, 0xa0, 0x50, 0x64, 0x27, 0x9a, 0x8f, 0x8d, 0x0d, 0x0e, 0xc1, 0xe8, 0x2f },
    { 0x3f, 0xf6, 0x7d, 0xab, 0x0f, 0x97, 0xf4, 0x79, 0x28, 0xf3, 0x63, 0x67, 0xb8, 0x6f, 0xde, 0x1c, 0x16, 0xe7, 0x13, 0xf9, 0x25, 0x0f, 0xb6, 0xd9, 0x19, 0x44, 0xbf, 0x53, 0xc7, 0xfd, 0x6f, 0xfb },
    { 0x01, 0xda, 0x0f, 0xd4, 0xa7, 0xff, 0xc9, 0x7a, 0x15, 0x1e, 0x01, 0xfa, 0x07, 0x54, 0x53, 0xf0, 0x83, 0x5e, 0x25, 0x40, 0x63, 0x01, 0x5f, 0xcd, 0xac, 0xc7, 0x31, 0xb9, 0xdc, 0x6e, 0x24, 0x15 },
};
static const unsigned char vec5_ack_aux_rands[3][32] = {
    { 0xd1, 0x29, 0xa1, 0x50, 0x10, 0xb1, 0xba, 0x89, 0x99, 0x00, 0x1b, 0x3c, 0xb8, 0x35, 0x8e, 0x2c, 0x48, 0xb7, 0x87, 0x83, 0xb8, 0xdf, 0x4d, 0x94, 0xb4, 0x3e, 0x88, 0xa8, 0x97, 0xb6, 0x3a, 0xd6 },
    { 0xc5, 0x26, 0xf1, 0xa4, 0xa1, 0x3d, 0xf9, 0xea, 0x33, 0x1e, 0x05, 0x48, 0x81, 0x79, 0x25, 0xfb, 0x3a, 0x1b, 0x82, 0x56, 0xb5, 0x8f, 0x93, 0xab, 0x22, 0xbf, 0x45, 0x1c, 0x70, 0x4e, 0x28, 0x89 },
    { 0x39, 0x1c, 0xc5, 0x83, 0x75, 0x88, 0x23, 0x92, 0x8e, 0xd7, 0x87, 0xb5, 0x81, 0x9c, 0x40, 0x1e, 0x91, 0xe5, 0xa1, 0xe7, 0x5d, 0x5d, 0x4d, 0x42, 0x2f, 0xd3, 0xf7, 0x0d, 0x11, 0x6b, 0x2a, 0xae },
};
static const unsigned char vec5_pmsgs1[3][259] = {
    { 0x02, 0xa9, 0xf7, 0xa6, 0x54, 0x1e, 0x12, 0x22, 0x46, 0xfd, 0x57, 0xee, 0xdc, 0x6e, 0x3a, 0x6a, 0x12, 0x48, 0x05, 0x4f, 0x02, 0x2b, 0x7c, 0x01, 0xe2, 0xa4, 0x36, 0x4c, 0x09, 0x20, 0xda, 0x93, 0x4b, 0x03, 0xcd, 0xba, 0xe2, 0x7d, 0xcc, 0x62, 0x90, 0x56, 0x8d, 0x21, 0xb6, 0x35, 0xa7, 0xbb, 0xd2, 0x93, 0x28, 0x78, 0xd7, 0x34, 0x55, 0x74, 0xa0, 0x52, 0xd6, 0x9e, 0xa1, 0x43, 0xe9, 0x8b, 0xc2, 0x12, 0xf5, 0xb1, 0x94, 0x34, 0xb9, 0x81, 0x06, 0x4d, 0x17, 0xa1, 0x6a, 0x1d, 0x81, 0x58, 0x4c, 0xf0, 0x55, 0xdf, 0x32, 0x62, 0x08, 0xd8, 0x29, 0x1e, 0xf2, 0xa6, 0xa3, 0xdb, 0x52, 0x98, 0xb8, 0x0f, 0xe6, 0x49, 0x74, 0xe1, 0x9f, 0x90, 0x70, 0x66, 0x09, 0x6b, 0xa9, 0xd5, 0x05, 0xd6, 0xb2, 0x36, 0x7a, 0xf2, 0x9b, 0xbb, 0x0e, 0x66, 0xed, 0x22, 0xd5, 0xdf, 0x21, 0xba, 0x1e, 0x51, 0x77, 0x40, 0x03, 0x07, 0xd9, 0x3f, 0x10, 0xca, 0xd5, 0x95, 0x92, 0xf3, 0x83, 0xc1, 0xd0, 0x0e, 0xb3, 0xb2, 0xf0, 0xea, 0xcb, 0x67, 0x79, 0xd7, 0xc1, 0x70, 0x0a, 0x42, 0x74, 0x77, 0x4d, 0xfd, 0x00, 0xab, 0x72, 0xbc, 0x05, 0xad, 0x21, 0x38, 0x77, 0xd9, 0x5b, 0x57, 0xb5, 0xa2, 0x0d, 0x49, 0x36, 0x53, 0x58, 0xfe, 0x61, 0x5e, 0x3c, 0x35, 0xb2, 0x8a, 0x6e, 0x7b, 0xdc, 0xc2, 0x44, 0x4c, 0x36, 0xeb, 0x06, 0xeb, 0x3b, 0xea, 0xd3, 0x1e, 0xb1, 0x6b, 0xe9, 0x70, 0x40, 0xd8, 0xeb, 0x68, 0x18, 0x84, 0x62, 0x82, 0xde, 0x65, 0x73, 0x5f, 0x24, 0x71, 0x9f, 0xd2, 0x68, 0xaf, 0x79, 0xdb, 0x1a, 0xa9, 0x8f, 0xe1, 0xab, 0xf1, 0x0b, 0xbb, 0x29, 0xf0, 0xf7, 0x33, 0xc4, 0x8e, 0x6f, 0xa6, 0x16, 0x94, 0x58, 0x75, 0x2a, 0x39, 0x8d, 0xfa, 0x5c, 0x37, 0x8d, 0x66, 0xb2, 0xb4, 0xfd, 0xe6, 0x5b, 0x27, 0xec },
    { 0x03, 0x1a, 0x5c, 0xb4, 0x0b, 0x67, 0xdb, 0xbc, 0xc4, 0x8b, 0x03, 0xcc, 0x2c, 0xc5, 0x54, 0x52, 0x0c, 0x01, 0x72, 0x57, 0x55, 0xd5, 0x2a, 0x0d, 0xec, 0x5d, 0xb1, 0xe0, 0xe1, 0xad, 0x00, 0x45, 0x59, 0x02, 0x9b, 0xac, 0x46, 0x00, 0xbb, 0xa5, 0xa5, 0x43, 0x08, 0x81, 0xc5, 0xac, 0x25, 0x1c, 0x8a, 0x01, 0xc7, 0x2d, 0x04, 0x69, 0x0e, 0x89, 0xeb, 0x6c, 0xb8, 0xe3, 0xdb, 0x4c, 0x60, 0x9d, 0x12, 0xf1, 0x1d, 0xf4, 0x21, 0xdd, 0xdf, 0x41, 0xc4, 0x1c, 0xae, 0x3a, 0x03, 0xd6, 0xd6, 0x7a, 0x25, 0x48, 0xcb, 0x36, 0x8b, 0xfa, 0x59, 0xb8, 0xfe, 0x6a, 0x2a, 0x39, 0x1b, 0x30, 0x60, 0xd0, 0x2e, 0x8b, 0x2d, 0xab, 0x0a, 0x99, 0x90, 0x31, 0xb9, 0x0f, 0x62, 0xa1, 0xb0, 0x1a, 0x3f, 0x3e, 0x43, 0xf6, 0xce, 0x94, 0x73, 0xcc, 0x88, 0xda, 0x76, 0x91, 0x66, 0x98, 0xa2, 0xd2, 0x4f, 0xdf, 0x81, 0xcb, 0x03, 0x7f, 0xc5, 0xc6, 0x73, 0xb0, 0xe6, 0xfb, 0x74, 0x98, 0xce, 0x1a, 0x86, 0xd7, 0xf7, 0xe8, 0x05, 0xf4, 0x65, 0xe6, 0x8b, 0xca, 0xe2, 0x95, 0x10, 0xdd, 0xdd, 0xec, 0xb6, 0x34, 0x2f, 0xae, 0x12, 0x10, 0x87, 0xc2, 0xea, 0x8c, 0x60, 0xeb, 0xc6, 0x3d, 0x40, 0x37, 0x38, 0xcf, 0x60, 0x3e, 0xfd, 0x7b, 0xc8, 0x31, 0x10, 0xfa, 0x29, 0x61, 0x5b, 0x93, 0x6e, 0x85, 0xa0, 0xd3, 0x5c, 0xe0, 0xa1, 0xa2, 0xf0, 0xff, 0xfb, 0x07, 0x2f, 0x48, 0xdb, 0x25, 0x84, 0x4d, 0xd0, 0x5c, 0xeb, 0xc0, 0xba, 0x8c, 0x51, 0x3d, 0x06, 0x69, 0x28, 0x42, 0xe6, 0x40, 0x4a, 0xfe, 0x20, 0x0d, 0x37, 0xc4, 0xe1, 0x46, 0x4f, 0x8e, 0x55, 0xc0, 0xd5, 0x13, 0x65, 0xf2, 0x99, 0xa2, 0x78, 0x3e, 0xd4, 0xc9, 0x47, 0x5d, 0x4d, 0x45, 0xbd, 0x5c, 0xd7, 0xe8, 0xd2, 0x82, 0xc2, 0x4a, 0xe5, 0xd1, 0x5d, 0xe9, 0x4b },
    { 0x02, 0x54, 0xc4, 0xc5, 0x71, 0x04, 0x3b, 0x01, 0x22, 0xe0, 0x1a, 0x79, 0x37, 0x1e, 0x0f, 0xc2, 0x6b, 0x66, 0x4e, 0xbc, 0xbb, 0x4e, 0x18, 0xe5, 0x1a, 0xa9, 0x67, 0x21, 0x18, 0x23, 0x0b, 0x86, 0xef, 0x02, 0xd3, 0x52, 0xd3, 0x63, 0x83, 0x81, 0xad, 0x26, 0x0d, 0x5d, 0xc0, 0x99, 0xcf, 0x80, 0xd4, 0xd7, 0x5f, 0x33, 0x3e, 0x15, 0xe3, 0xff, 0xce, 0xf6, 0x01, 0xe8, 0x66, 0x20, 0xb3, 0x15, 0x84, 0x18, 0xa7, 0x13, 0x00, 0x3b, 0x39, 0x2d, 0x2d, 0x35, 0xa5, 0x7c, 0x5d, 0x3c, 0x96, 0x92, 0xb8, 0xd4, 0x43, 0x94, 0xca, 0xf7, 0x71, 0x60, 0x5c, 0x6f, 0x5b, 0x99, 0x33, 0xcb, 0x39, 0xf8, 0xae, 0xf5, 0xbc, 0x92, 0x09, 0x3f, 0x03, 0xd0, 0x5c, 0x4a, 0x16, 0xff, 0x0a, 0xc3, 0x0b, 0x34, 0x78, 0xe7, 0xea, 0xfb, 0x48, 0xbc, 0x38, 0xbb, 0x18, 0x20, 0xf0, 0x8f, 0x10, 0x63, 0x3f, 0x42, 0xf4, 0xbd, 0x02, 0x6d, 0xda, 0xf4, 0x4d, 0x4a, 0x66, 0xfc, 0xf7, 0x7b, 0xc2, 0x81, 0x44, 0xa9, 0x62, 0xb9, 0x5b, 0xc9, 0x09, 0x9d, 0x87, 0x1e, 0x4d, 0xbe, 0x5f, 0x0a, 0x94, 0x78, 0xa5, 0x24, 0xaf, 0xb7, 0x90, 0xc8, 0x1e, 0xcf, 0x74, 0xdc, 0xd5, 0xb4, 0x7d, 0x16, 0xf1, 0xad, 0x68, 0xbc, 0xdb, 0x0c, 0xd5, 0x6e, 0x07, 0x49, 0xbf, 0xcc, 0x15, 0x62, 0x12, 0xd1, 0xa1, 0x91, 0x71, 0x37, 0x39, 0x98, 0x1d, 0x59, 0xdc, 0x42, 0x24, 0x9d, 0x7d, 0x04, 0x7f, 0xa4, 0x12, 0xc2, 0x4d, 0x87, 0x0b, 0x62, 0x1e, 0x81, 0x48, 0x68, 0x27, 0xfd, 0xde, 0x94, 0x34, 0x2e, 0xf3, 0x17, 0x78, 0x37, 0x4c, 0x90, 0xff, 0x71, 0x7f, 0x6a, 0xf2, 0xad, 0x9d, 0x84, 0x6e, 0x5d, 0x39, 0x36, 0xec, 0x80, 0xf1, 0xba, 0xa4, 0x1d, 0x5b, 0x09, 0xc6, 0xd5, 0x50, 0xeb, 0x45, 0x7c, 0x21, 0x7e, 0x86, 0xff, 0xf8, 0x15, 0x6c },
};
static const unsigned char vec5_cmsg1[519] = { 0x02, 0xa9, 0xf7, 0xa6, 0x54, 0x1e, 0x12, 0x22, 0x46, 0xfd, 0x57, 0xee, 0xdc, 0x6e, 0x3a, 0x6a, 0x12, 0x48, 0x05, 0x4f, 0x02, 0x2b, 0x7c, 0x01, 0xe2, 0xa4, 0x36, 0x4c, 0x09, 0x20, 0xda, 0x93, 0x4b, 0x03, 0x1a, 0x5c, 0xb4, 0x0b, 0x67, 0xdb, 0xbc, 0xc4, 0x8b, 0x03, 0xcc, 0x2c, 0xc5, 0x54, 0x52, 0x0c, 0x01, 0x72, 0x57, 0x55, 0xd5, 0x2a, 0x0d, 0xec, 0x5d, 0xb1, 0xe0, 0xe1, 0xad, 0x00, 0x45, 0x59, 0x02, 0x54, 0xc4, 0xc5, 0x71, 0x04, 0x3b, 0x01, 0x22, 0xe0, 0x1a, 0x79, 0x37, 0x1e, 0x0f, 0xc2, 0x6b, 0x66, 0x4e, 0xbc, 0xbb, 0x4e, 0x18, 0xe5, 0x1a, 0xa9, 0x67, 0x21, 0x18, 0x23, 0x0b, 0x86, 0xef, 0x02, 0x67, 0x0c, 0x35, 0xb2, 0xae, 0x50, 0x90, 0xff, 0xe0, 0x32, 0x36, 0xee, 0x4f, 0x86, 0xf9, 0x31, 0xac, 0x79, 0x80, 0x64, 0xfb, 0x9d, 0x9c, 0xd1, 0x95, 0x4b, 0xf0, 0x5f, 0xc1, 0x38, 0x38, 0x69, 0xf5, 0xb1, 0x94, 0x34, 0xb9, 0x81, 0x06, 0x4d, 0x17, 0xa1, 0x6a, 0x1d, 0x81, 0x58, 0x4c, 0xf0, 0x55, 0xdf, 0x32, 0x62, 0x08, 0xd8, 0x29, 0x1e, 0xf2, 0xa6, 0xa3, 0xdb, 0x52, 0x98, 0xb8, 0x0f, 0xe6, 0x49, 0x74, 0xe1, 0x9f, 0x90, 0x70, 0x66, 0x09, 0x6b, 0xa9, 0xd5, 0x05, 0xd6, 0xb2, 0x36, 0x7a, 0xf2, 0x9b, 0xbb, 0x0e, 0x66, 0xed, 0x22, 0xd5, 0xdf, 0x21, 0xba, 0x1e, 0x51, 0x77, 0x40, 0x1d, 0xf4, 0x21, 0xdd, 0xdf, 0x41, 0xc4, 0x1c, 0xae, 0x3a, 0x03, 0xd6, 0xd6, 0x7a, 0x25, 0x48, 0xcb, 0x36, 0x8b, 0xfa, 0x59, 0xb8, 0xfe, 0x6a, 0x2a, 0x39, 0x1b, 0x30, 0x60, 0xd0, 0x2e, 0x8b, 0x2d, 0xab, 0x0a, 0x99, 0x90, 0x31, 0xb9, 0x0f, 0x62, 0xa1, 0xb0, 0x1a, 0x3f, 0x3e, 0x43, 0xf6, 0xce, 0x94, 0x73, 0xcc, 0x88, 0xda, 0x76, 0x91, 0x66, 0x98, 0xa2, 0xd2, 0x4f, 0xdf, 0x81, 0xcb, 0xa7, 0x13, 0x00, 0x3b, 0x39, 0x2d, 0x2d, 0x35, 0xa5, 0x7c, 0x5d, 0x3c, 0x96, 0x92, 0xb8, 0xd4, 0x43, 0x94, 0xca, 0xf7, 0x71, 0x60, 0x5c, 0x6f, 0x5b, 0x99, 0x33, 0xcb, 0x39, 0xf8, 0xae, 0xf5, 0xbc, 0x92, 0x09, 0x3f, 0x03, 0xd0, 0x5c, 0x4a, 0x16, 0xff, 0x0a, 0xc3, 0x0b, 0x34, 0x78, 0xe7, 0xea, 0xfb, 0x48, 0xbc, 0x38, 0xbb, 0x18, 0x20, 0xf0, 0x8f, 0x10, 0x63, 0x3f, 0x42, 0xf4, 0xbd, 0x03, 0x07, 0xd9, 0x3f, 0x10, 0xca, 0xd5, 0x95, 0x92, 0xf3, 0x83, 0xc1, 0xd0, 0x0e, 0xb3, 0xb2, 0xf0, 0xea, 0xcb, 0x67, 0x79, 0xd7, 0xc1, 0x70, 0x0a, 0x42, 0x74, 0x77, 0x4d, 0xfd, 0x00, 0xab, 0x72, 0x03, 0x7f, 0xc5, 0xc6, 0x73, 0xb0, 0xe6, 0xfb, 0x74, 0x98, 0xce, 0x1a, 0x86, 0xd7, 0xf7, 0xe8, 0x05, 0xf4, 0x65, 0xe6, 0x8b, 0xca, 0xe2, 0x95, 0x10, 0xdd, 0xdd, 0xec, 0xb6, 0x34, 0x2f, 0xae, 0x12, 0x02, 0x6d, 0xda, 0xf4, 0x4d, 0x4a, 0x66, 0xfc, 0xf7, 0x7b, 0xc2, 0x81, 0x44, 0xa9, 0x62, 0xb9, 0x5b, 0xc9, 0x09, 0x9d, 0x87, 0x1e, 0x4d, 0xbe, 0x5f, 0x0a, 0x94, 0x78, 0xa5, 0x24, 0xaf, 0xb7, 0x90, 0x94, 0xac, 0x3f, 0x80, 0xa1, 0xae, 0x79, 0x9e, 0xab, 0xe7, 0x86, 0xae, 0xd5, 0x71, 0x9f, 0x2d, 0x2d, 0x81, 0xfc, 0x26, 0x4c, 0xa8, 0xad, 0xa1, 0x21, 0x1a, 0x7a, 0xc9, 0x86, 0x97, 0x22, 0x83, 0xe8, 0x09, 0x2c, 0xf2, 0xc3, 0x5d, 0xb9, 0x44, 0x39, 0xd7, 0xe9, 0x09, 0x4c, 0x0f, 0xa7, 0x3c, 0xd5, 0xc9, 0x2d, 0xbb, 0x16, 0xe2, 0xa8, 0x7e, 0x81, 0xd4, 0x66, 0x85, 0x4f, 0x68, 0xbe, 0x2e, 0x99, 0x7a, 0xea, 0x54, 0x29, 0x9c, 0x88, 0xcb, 0x83, 0x97, 0x67, 0xd4, 0x65, 0xdd, 0x18, 0x45, 0x35, 0x23, 0xac, 0x2b, 0x7d, 0x3c, 0x6b, 0x69, 0xa5, 0xc4, 0x1f, 0xdd, 0xe7, 0x7a, 0xe5, 0x62 };
static const unsigned char vec5_pmsgs2[3][64] = {
    { 0x37, 0x24, 0xa1, 0x76, 0xf2, 0x82, 0xd3, 0x37, 0xac, 0x82, 0x26, 0xd2, 0xe7, 0x1c, 0x92, 0xff, 0x87, 0x65, 0x9c, 0x7f, 0x98, 0x17, 0x4e, 0x54, 0xd3, 0x43, 0x6f, 0x1a, 0x83, 0xda, 0xc4, 0x14, 0xbf, 0xbb, 0x69, 0x94, 0x7a, 0xc2, 0x3c, 0xd4, 0x42, 0x3a, 0x0d, 0xdd, 0x4a, 0x22, 0x0c, 0xbb, 0x17, 0x63, 0xfa, 0xbb, 0x3f, 0x54, 0xd0, 0xdc, 0xcc, 0x4d, 0x44, 0xb3, 0xa3, 0x23, 0x83, 0x3b },
    { 0x5e, 0xbc, 0xe2, 0x1d, 0x9a, 0xbe, 0x87, 0x88, 0x67, 0x56, 0xbd, 0x19, 0x66, 0x0c, 0x3a, 0x3c, 0x02, 0x36, 0x82, 0x4a, 0xb9, 0xc3, 0x3e, 0x3b, 0x5c, 0xb4, 0xa8, 0x3b, 0x06, 0xa1, 0x20, 0xff, 0x11, 0x7f, 0x2b, 0xf8, 0x18, 0x3b, 0x79, 0xe2, 0x46, 0x61, 0x1b, 0xd2, 0x3b, 0x22, 0x7a, 0x8c, 0x7b, 0xbb, 0xcb, 0xe7, 0xbd, 0xf8, 0x2a, 0x05, 0xf2, 0x34, 0xfa, 0x66, 0x26, 0xd3, 0x02, 0x20 },
    { 0x30, 0x42, 0x47, 0x3e, 0x0b, 0x02, 0x24, 0xf9, 0x9a, 0xc5, 0x1a, 0xe8, 0x12, 0xdb, 0x5f, 0x99, 0x70, 0x78, 0x96, 0x72, 0x41, 0x75, 0x99, 0x2e, 0xf1, 0xdf, 0x5d, 0xdf, 0xee, 0x41, 0xc5, 0x75, 0x99, 0xa6, 0xb4, 0x3f, 0xd3, 0x86, 0xdc, 0xb7, 0xc4, 0x01, 0x21, 0xe2, 0xe9, 0x59, 0x34, 0xa8, 0xe3, 0x1d, 0x79, 0xb7, 0xa9, 0xda, 0xd4, 0x46, 0xea, 0x9a, 0x72, 0x7f, 0xb6, 0xe9, 0x26, 0x17 },
};
static const unsigned char vec5_cmsg2[192] = { 0x37, 0x24, 0xa1, 0x76, 0xf2, 0x82, 0xd3, 0x37, 0xac, 0x82, 0x26, 0xd2, 0xe7, 0x1c, 0x92, 0xff, 0x87, 0x65, 0x9c, 0x7f, 0x98, 0x17, 0x4e, 0x54, 0xd3, 0x43, 0x6f, 0x1a, 0x83, 0xda, 0xc4, 0x14, 0xbf, 0xbb, 0x69, 0x94, 0x7a, 0xc2, 0x3c, 0xd4, 0x42, 0x3a, 0x0d, 0xdd, 0x4a, 0x22, 0x0c, 0xbb, 0x17, 0x63, 0xfa, 0xbb, 0x3f, 0x54, 0xd0, 0xdc, 0xcc, 0x4d, 0x44, 0xb3, 0xa3, 0x23, 0x83, 0x3b, 0x5e, 0xbc, 0xe2, 0x1d, 0x9a, 0xbe, 0x87, 0x88, 0x67, 0x56, 0xbd, 0x19, 0x66, 0x0c, 0x3a, 0x3c, 0x02, 0x36, 0x82, 0x4a, 0xb9, 0xc3, 0x3e, 0x3b, 0x5c, 0xb4, 0xa8, 0x3b, 0x06, 0xa1, 0x20, 0xff, 0x11, 0x7f, 0x2b, 0xf8, 0x18, 0x3b, 0x79, 0xe2, 0x46, 0x61, 0x1b, 0xd2, 0x3b, 0x22, 0x7a, 0x8c, 0x7b, 0xbb, 0xcb, 0xe7, 0xbd, 0xf8, 0x2a, 0x05, 0xf2, 0x34, 0xfa, 0x66, 0x26, 0xd3, 0x02, 0x20, 0x30, 0x42, 0x47, 0x3e, 0x0b, 0x02, 0x24, 0xf9, 0x9a, 0xc5, 0x1a, 0xe8, 0x12, 0xdb, 0x5f, 0x99, 0x70, 0x78, 0x96, 0x72, 0x41, 0x75, 0x99, 0x2e, 0xf1, 0xdf, 0x5d, 0xdf, 0xee, 0x41, 0xc5, 0x75, 0x99, 0xa6, 0xb4, 0x3f, 0xd3, 0x86, 0xdc, 0xb7, 0xc4, 0x01, 0x21, 0xe2, 0xe9, 0x59, 0x34, 0xa8, 0xe3, 0x1d, 0x79, 0xb7, 0xa9, 0xda, 0xd4, 0x46, 0xea, 0x9a, 0x72, 0x7f, 0xb6, 0xe9, 0x26, 0x17 };
static const unsigned char vec5_secshares[3][32] = {
    { 0x1a, 0xba, 0xaa, 0x2d, 0x25, 0xd0, 0x5b, 0x3f, 0x9b, 0xdc, 0x54, 0xc4, 0x51, 0xe9, 0x90, 0xec, 0xf0, 0x4b, 0x22, 0x49, 0xf1, 0xbc, 0x61, 0x5e, 0xa8, 0x7b, 0xf7, 0x31, 0x62, 0xcb, 0xf5, 0xce },
    { 0x35, 0xe1, 0x3c, 0x52, 0xfa, 0x2f, 0x39, 0x4c, 0x6a, 0x9d, 0x9b, 0xcd, 0x1b, 0x96, 0xd2, 0x95, 0xff, 0xbb, 0x85, 0x95, 0x62, 0x56, 0x02, 0xdf, 0x1a, 0x44, 0xd6, 0x7f, 0xf7, 0x25, 0x4f, 0x1f },
    { 0x51, 0x07, 0xce, 0x78, 0xce, 0x8e, 0x17, 0x59, 0x39, 0x5e, 0xe2, 0xd5, 0xe5, 0x44, 0x14, 0x3f, 0x0f, 0x2b, 0xe8, 0xe0, 0xd2, 0xef, 0xa4, 0x5f, 0x8c, 0x0d, 0xb5, 0xce, 0x8b, 0x7e, 0xa8, 0x70 },
};
static const unsigned char vec5_thresh_pk[33] = { 0x02, 0xd6, 0x31, 0x69, 0x44, 0xf7, 0x8c, 0x21, 0x4a, 0xac, 0x9f, 0x93, 0x32, 0x70, 0xe7, 0xa6, 0xad, 0xa9, 0x5e, 0xd0, 0xe0, 0x03, 0x6a, 0xab, 0x78, 0x16, 0x1b, 0xbb, 0xbe, 0x25, 0xa5, 0xee, 0xb5 };
static const unsigned char vec5_pubshares[3][33] = {
    { 0x02, 0x9d, 0x60, 0x50, 0x8f, 0x5e, 0xd6, 0x93, 0x19, 0x8f, 0x17, 0x6d, 0x2e, 0x19, 0x99, 0x3e, 0x3a, 0x17, 0x0f, 0xb9, 0x83, 0xc8, 0x95, 0x97, 0x94, 0xe9, 0x8b, 0x4e, 0x75, 0x95, 0xf7, 0x99, 0x5f },
    { 0x03, 0x81, 0xff, 0x24, 0x16, 0x43, 0xe5, 0x5b, 0x70, 0xc0, 0xfc, 0x01, 0x65, 0xcc, 0x16, 0x80, 0x6e, 0x23, 0x76, 0xf2, 0x6b, 0xf4, 0xf2, 0xc2, 0x58, 0x72, 0x98, 0x69, 0xb2, 0x89, 0x46, 0x2a, 0x69 },
    { 0x02, 0x6e, 0x74, 0xfa, 0x97, 0x9d, 0x46, 0xe9, 0xe4, 0x71, 0x23, 0x66, 0x8a, 0x55, 0x85, 0x09, 0x21, 0x67, 0x3b, 0x37, 0x41, 0x6e, 0xcf, 0x95, 0x34, 0x98, 0xca, 0x19, 0x0a, 0xe6, 0xce, 0xd3, 0xa1 },
};
static const unsigned char vec5_recovery[556] = { 0x00, 0x00, 0x00, 0x02, 0x03, 0x3b, 0x49, 0x45, 0x46, 0x83, 0x43, 0x3e, 0xc5, 0x06, 0x9a, 0x38, 0xaf, 0x81, 0x12, 0xc3, 0xe8, 0x77, 0x51, 0x2a, 0xfe, 0xf3, 0x58, 0xfa, 0x5b, 0xb7, 0x2a, 0xb7, 0x6e, 0x26, 0x7e, 0x8f, 0x8a, 0x02, 0x67, 0x0c, 0x35, 0xb2, 0xae, 0x50, 0x90, 0xff, 0xe0, 0x32, 0x36, 0xee, 0x4f, 0x86, 0xf9, 0x31, 0xac, 0x79, 0x80, 0x64, 0xfb, 0x9d, 0x9c, 0xd1, 0x95, 0x4b, 0xf0, 0x5f, 0xc1, 0x38, 0x38, 0x69, 0x03, 0x4f, 0x68, 0x91, 0xb1, 0xd2, 0x7f, 0x67, 0xd3, 0xbb, 0x8a, 0xd4, 0x80, 0x83, 0x1a, 0x3d, 0x80, 0x7f, 0x58, 0xed, 0x42, 0x21, 0x6c, 0x94, 0x9b, 0xd0, 0xc7, 0x8a, 0x51, 0x9c, 0xbe, 0x76, 0xe0, 0x02, 0xfb, 0x7e, 0x20, 0xfb, 0xa2, 0x87, 0xee, 0x46, 0xb9, 0x53, 0x62, 0x32, 0xf6, 0x9c, 0x31, 0xa9, 0x0c, 0x66, 0xea, 0xf1, 0xfd, 0x67, 0x18, 0xdd, 0xdc, 0x1f, 0x10, 0xaa, 0x15, 0xf8, 0xa3, 0x4f, 0x03, 0x59, 0x5a, 0x19, 0x3f, 0xe6, 0xe8, 0xf1, 0xf4, 0x36, 0x00, 0x79, 0x4e, 0x19, 0x39, 0xaa, 0x29, 0x04, 0x1f, 0x3b, 0xc1, 0xd3, 0x29, 0x49, 0x1e, 0x88, 0x38, 0x32, 0x19, 0x74, 0x8c, 0x2f, 0xa5, 0x03, 0x07, 0xd9, 0x3f, 0x10, 0xca, 0xd5, 0x95, 0x92, 0xf3, 0x83, 0xc1, 0xd0, 0x0e, 0xb3, 0xb2, 0xf0, 0xea, 0xcb, 0x67, 0x79, 0xd7, 0xc1, 0x70, 0x0a, 0x42, 0x74, 0x77, 0x4d, 0xfd, 0x00, 0xab, 0x72, 0x03, 0x7f, 0xc5, 0xc6, 0x73, 0xb0, 0xe6, 0xfb, 0x74, 0x98, 0xce, 0x1a, 0x86, 0xd7, 0xf7, 0xe8, 0x05, 0xf4, 0x65, 0xe6, 0x8b, 0xca, 0xe2, 0x95, 0x10, 0xdd, 0xdd, 0xec, 0xb6, 0x34, 0x2f, 0xae, 0x12, 0x02, 0x6d, 0xda, 0xf4, 0x4d, 0x4a, 0x66, 0xfc, 0xf7, 0x7b, 0xc2, 0x81, 0x44, 0xa9, 0x62, 0xb9, 0x5b, 0xc9, 0x09, 0x9d, 0x87, 0x1e, 0x4d, 0xbe, 0x5f, 0x0a, 0x94, 0x78, 0xa5, 0x24, 0xaf, 0xb7, 0x90, 0x94, 0xac, 0x3f, 0x80, 0xa1, 0xae, 0x79, 0x9e, 0xab, 0xe7, 0x86, 0xae, 0xd5, 0x71, 0x9f, 0x2d, 0x2d, 0x81, 0xfc, 0x26, 0x4c, 0xa8, 0xad, 0xa1, 0x21, 0x1a, 0x7a, 0xc9, 0x86, 0x97, 0x22, 0x83, 0xe8, 0x09, 0x2c, 0xf2, 0xc3, 0x5d, 0xb9, 0x44, 0x39, 0xd7, 0xe9, 0x09, 0x4c, 0x0f, 0xa7, 0x3c, 0xd5, 0xc9, 0x2d, 0xbb, 0x16, 0xe2, 0xa8, 0x7e, 0x81, 0xd4, 0x66, 0x85, 0x4f, 0x68, 0xbe, 0x2e, 0x99, 0x7a, 0xea, 0x54, 0x29, 0x9c, 0x88, 0xcb, 0x83, 0x97, 0x67, 0xd4, 0x65, 0xdd, 0x18, 0x45, 0x35, 0x23, 0xac, 0x2b, 0x7d, 0x3c, 0x6b, 0x69, 0xa5, 0xc4, 0x1f, 0xdd, 0xe7, 0x7a, 0xe5, 0x62, 0x37, 0x24, 0xa1, 0x76, 0xf2, 0x82, 0xd3, 0x37, 0xac, 0x82, 0x26, 0xd2, 0xe7, 0x1c, 0x92, 0xff, 0x87, 0x65, 0x9c, 0x7f, 0x98, 0x17, 0x4e, 0x54, 0xd3, 0x43, 0x6f, 0x1a, 0x83, 0xda, 0xc4, 0x14, 0xbf, 0xbb, 0x69, 0x94, 0x7a, 0xc2, 0x3c, 0xd4, 0x42, 0x3a, 0x0d, 0xdd, 0x4a, 0x22, 0x0c, 0xbb, 0x17, 0x63, 0xfa, 0xbb, 0x3f, 0x54, 0xd0, 0xdc, 0xcc, 0x4d, 0x44, 0xb3, 0xa3, 0x23, 0x83, 0x3b, 0x5e, 0xbc, 0xe2, 0x1d, 0x9a, 0xbe, 0x87, 0x88, 0x67, 0x56, 0xbd, 0x19, 0x66, 0x0c, 0x3a, 0x3c, 0x02, 0x36, 0x82, 0x4a, 0xb9, 0xc3, 0x3e, 0x3b, 0x5c, 0xb4, 0xa8, 0x3b, 0x06, 0xa1, 0x20, 0xff, 0x11, 0x7f, 0x2b, 0xf8, 0x18, 0x3b, 0x79, 0xe2, 0x46, 0x61, 0x1b, 0xd2, 0x3b, 0x22, 0x7a, 0x8c, 0x7b, 0xbb, 0xcb, 0xe7, 0xbd, 0xf8, 0x2a, 0x05, 0xf2, 0x34, 0xfa, 0x66, 0x26, 0xd3, 0x02, 0x20, 0x30, 0x42, 0x47, 0x3e, 0x0b, 0x02, 0x24, 0xf9, 0x9a, 0xc5, 0x1a, 0xe8, 0x12, 0xdb, 0x5f, 0x99, 0x70, 0x78, 0x96, 0x72, 0x41, 0x75, 0x99, 0x2e, 0xf1, 0xdf, 0x5d, 0xdf, 0xee, 0x41, 0xc5, 0x75, 0x99, 0xa6, 0xb4, 0x3f, 0xd3, 0x86, 0xdc, 0xb7, 0xc4, 0x01, 0x21, 0xe2, 0xe9, 0x59, 0x34, 0xa8, 0xe3, 0x1d, 0x79, 0xb7, 0xa9, 0xda, 0xd4, 0x46, 0xea, 0x9a, 0x72, 0x7f, 0xb6, 0xe9, 0x26, 0x17 };
static const unsigned char vec5_ack_sigs[3][64] = {
    { 0x11, 0xfc, 0x90, 0x7c, 0x69, 0x20, 0x13, 0x7a, 0x51, 0x09, 0xa2, 0x03, 0x75, 0x32, 0x7e, 0x7f, 0x7f, 0x20, 0xf2, 0x82, 0x60, 0xa8, 0xf3, 0x01, 0xcf, 0xbc, 0xfd, 0xbb, 0xa7, 0xea, 0x64, 0xa8, 0xbc, 0xf5, 0xc7, 0x05, 0xfc, 0xa4, 0x81, 0xa9, 0xbb, 0x4e, 0x0b, 0x49, 0x1a, 0x2a, 0x49, 0x0d, 0x9c, 0xc8, 0x6f, 0x6d, 0x23, 0xdc, 0x15, 0x2f, 0xdc, 0xe7, 0x99, 0xa7, 0x8a, 0xe1, 0x4d, 0x1a },
    { 0x44, 0xff, 0xf6, 0x84, 0xf5, 0x8d, 0x9f, 0xc4, 0xad, 0x46, 0xc6, 0x49, 0x33, 0x42, 0x8e, 0x9e, 0xa7, 0xc1, 0x25, 0xc0, 0x28, 0x6d, 0xbd, 0x78, 0xfd, 0x61, 0x30, 0x85, 0x52, 0x8f, 0x40, 0x67, 0x9e, 0x97, 0x55, 0xcc, 0x21, 0x30, 0xf8, 0xa4, 0x3b, 0x11, 0x88, 0xd2, 0xe4, 0x0a, 0xa2, 0x41, 0x4f, 0x60, 0x41, 0x01, 0x7b, 0x4b, 0xc1, 0x88, 0x6c, 0x74, 0x1d, 0xee, 0x85, 0xa7, 0x99, 0xa0 },
    { 0x00, 0x20, 0xeb, 0x92, 0x88, 0x9e, 0x59, 0x81, 0x9e, 0x0d, 0x7b, 0x3f, 0x6b, 0x91, 0x3e, 0xe0, 0x70, 0x33, 0x02, 0x8e, 0xf3, 0xd9, 0x57, 0x66, 0xe8, 0x48, 0xb6, 0xad, 0xe8, 0x2b, 0x22, 0x21, 0xf5, 0x51, 0xa7, 0x4a, 0x64, 0x8e, 0xa6, 0xc1, 0x4e, 0xa7, 0x07, 0x81, 0xb9, 0x16, 0xfb, 0xc9, 0xca, 0x27, 0xac, 0x70, 0xd7, 0xb6, 0x2d, 0x97, 0xaa, 0x95, 0xd5, 0x40, 0x4f, 0x04, 0x56, 0x69 },
};
static const unsigned char vec5_inv_pmsg1_bad[259] = { 0x03, 0x1a, 0x5c, 0xb4, 0x0b, 0x67, 0xdb, 0xbc, 0xc4, 0x8b, 0x03, 0xcc, 0x2c, 0xc5, 0x54, 0x52, 0x0c, 0x01, 0x72, 0x57, 0x55, 0xd5, 0x2a, 0x0d, 0xec, 0x5d, 0xb1, 0xe0, 0xe1, 0xad, 0x00, 0x45, 0x59, 0x02, 0x9b, 0xac, 0x46, 0x00, 0xbb, 0xa5, 0xa5, 0x43, 0x08, 0x81, 0xc5, 0xac, 0x25, 0x1c, 0x8a, 0x01, 0xc7, 0x2d, 0x04, 0x69, 0x0e, 0x89, 0xeb, 0x6c, 0xb8, 0xe3, 0xdb, 0x4c, 0x60, 0x9d, 0x12, 0xf1, 0x1d, 0xf4, 0x21, 0xdd, 0xdf, 0x41, 0xc4, 0x1c, 0xae, 0x3a, 0x03, 0xd6, 0xd6, 0x7a, 0x25, 0x48, 0xcb, 0x36, 0x8b, 0xfa, 0x59, 0xb8, 0xfe, 0x6a, 0x2a, 0x39, 0x1b, 0x30, 0x60, 0xd0, 0x2e, 0x8b, 0x2d, 0xab, 0x0a, 0x99, 0x90, 0x31, 0xb9, 0x0f, 0x62, 0xa1, 0xb0, 0x1a, 0x3f, 0x3e, 0x43, 0xf6, 0xce, 0x94, 0x73, 0xcc, 0x88, 0xda, 0x76, 0x91, 0x66, 0x98, 0xa2, 0xd2, 0x4f, 0xdf, 0x81, 0xcb, 0x03, 0x7f, 0xc5, 0xc6, 0x73, 0xb0, 0xe6, 0xfb, 0x74, 0x98, 0xce, 0x1a, 0x86, 0xd7, 0xf7, 0xe8, 0x05, 0xf4, 0x65, 0xe6, 0x8b, 0xca, 0xe2, 0x95, 0x10, 0xdd, 0xdd, 0xec, 0xb6, 0x34, 0x2f, 0xae, 0x12, 0x10, 0x87, 0xc2, 0xea, 0x8c, 0x60, 0xeb, 0xc6, 0x3d, 0x40, 0x37, 0x38, 0xcf, 0x60, 0x3e, 0xfd, 0x7b, 0xc8, 0x31, 0x10, 0xfa, 0x29, 0x61, 0x5b, 0x93, 0x6e, 0x85, 0xa0, 0xd3, 0x5c, 0xe0, 0xa1, 0xa2, 0xf0, 0xff, 0xfb, 0x07, 0x2f, 0x48, 0xdb, 0x25, 0x84, 0x4d, 0xd0, 0x5c, 0xeb, 0xc0, 0xba, 0x8c, 0x51, 0x3d, 0x06, 0x69, 0x28, 0x42, 0xe6, 0x40, 0x4a, 0xfe, 0x20, 0x0d, 0x37, 0xc4, 0xe1, 0x46, 0x4f, 0x8e, 0x55, 0xc0, 0xd5, 0x13, 0x65, 0xf2, 0x99, 0xa2, 0x78, 0x3e, 0xd4, 0xc9, 0x47, 0x5d, 0x4d, 0x45, 0xbd, 0x5c, 0xd7, 0xe8, 0xd2, 0x82, 0xc2, 0x4a, 0xe5, 0xd1, 0x5d, 0xe9, 0x4a };
static const unsigned char vec5_inv_cmsg1[519] = { 0x02, 0xa9, 0xf7, 0xa6, 0x54, 0x1e, 0x12, 0x22, 0x46, 0xfd, 0x57, 0xee, 0xdc, 0x6e, 0x3a, 0x6a, 0x12, 0x48, 0x05, 0x4f, 0x02, 0x2b, 0x7c, 0x01, 0xe2, 0xa4, 0x36, 0x4c, 0x09, 0x20, 0xda, 0x93, 0x4b, 0x03, 0x1a, 0x5c, 0xb4, 0x0b, 0x67, 0xdb, 0xbc, 0xc4, 0x8b, 0x03, 0xcc, 0x2c, 0xc5, 0x54, 0x52, 0x0c, 0x01, 0x72, 0x57, 0x55, 0xd5, 0x2a, 0x0d, 0xec, 0x5d, 0xb1, 0xe0, 0xe1, 0xad, 0x00, 0x45, 0x59, 0x02, 0x54, 0xc4, 0xc5, 0x71, 0x04, 0x3b, 0x01, 0x22, 0xe0, 0x1a, 0x79, 0x37, 0x1e, 0x0f, 0xc2, 0x6b, 0x66, 0x4e, 0xbc, 0xbb, 0x4e, 0x18, 0xe5, 0x1a, 0xa9, 0x67, 0x21, 0x18, 0x23, 0x0b, 0x86, 0xef, 0x02, 0x67, 0x0c, 0x35, 0xb2, 0xae, 0x50, 0x90, 0xff, 0xe0, 0x32, 0x36, 0xee, 0x4f, 0x86, 0xf9, 0x31, 0xac, 0x79, 0x80, 0x64, 0xfb, 0x9d, 0x9c, 0xd1, 0x95, 0x4b, 0xf0, 0x5f, 0xc1, 0x38, 0x38, 0x69, 0xf5, 0xb1, 0x94, 0x34, 0xb9, 0x81, 0x06, 0x4d, 0x17, 0xa1, 0x6a, 0x1d, 0x81, 0x58, 0x4c, 0xf0, 0x55, 0xdf, 0x32, 0x62, 0x08, 0xd8, 0x29, 0x1e, 0xf2, 0xa6, 0xa3, 0xdb, 0x52, 0x98, 0xb8, 0x0f, 0xe6, 0x49, 0x74, 0xe1, 0x9f, 0x90, 0x70, 0x66, 0x09, 0x6b, 0xa9, 0xd5, 0x05, 0xd6, 0xb2, 0x36, 0x7a, 0xf2, 0x9b, 0xbb, 0x0e, 0x66, 0xed, 0x22, 0xd5, 0xdf, 0x21, 0xba, 0x1e, 0x51, 0x77, 0x40, 0x1d, 0xf4, 0x21, 0xdd, 0xdf, 0x41, 0xc4, 0x1c, 0xae, 0x3a, 0x03, 0xd6, 0xd6, 0x7a, 0x25, 0x48, 0xcb, 0x36, 0x8b, 0xfa, 0x59, 0xb8, 0xfe, 0x6a, 0x2a, 0x39, 0x1b, 0x30, 0x60, 0xd0, 0x2e, 0x8b, 0x2d, 0xab, 0x0a, 0x99, 0x90, 0x31, 0xb9, 0x0f, 0x62, 0xa1, 0xb0, 0x1a, 0x3f, 0x3e, 0x43, 0xf6, 0xce, 0x94, 0x73, 0xcc, 0x88, 0xda, 0x76, 0x91, 0x66, 0x98, 0xa2, 0xd2, 0x4f, 0xdf, 0x81, 0xcb, 0xa7, 0x13, 0x00, 0x3b, 0x39, 0x2d, 0x2d, 0x35, 0xa5, 0x7c, 0x5d, 0x3c, 0x96, 0x92, 0xb8, 0xd4, 0x43, 0x94, 0xca, 0xf7, 0x71, 0x60, 0x5c, 0x6f, 0x5b, 0x99, 0x33, 0xcb, 0x39, 0xf8, 0xae, 0xf5, 0xbc, 0x92, 0x09, 0x3f, 0x03, 0xd0, 0x5c, 0x4a, 0x16, 0xff, 0x0a, 0xc3, 0x0b, 0x34, 0x78, 0xe7, 0xea, 0xfb, 0x48, 0xbc, 0x38, 0xbb, 0x18, 0x20, 0xf0, 0x8f, 0x10, 0x63, 0x3f, 0x42, 0xf4, 0xbd, 0x03, 0x07, 0xd9, 0x3f, 0x10, 0xca, 0xd5, 0x95, 0x92, 0xf3, 0x83, 0xc1, 0xd0, 0x0e, 0xb3, 0xb2, 0xf0, 0xea, 0xcb, 0x67, 0x79, 0xd7, 0xc1, 0x70, 0x0a, 0x42, 0x74, 0x77, 0x4d, 0xfd, 0x00, 0xab, 0x72, 0x03, 0x7f, 0xc5, 0xc6, 0x73, 0xb0, 0xe6, 0xfb, 0x74, 0x98, 0xce, 0x1a, 0x86, 0xd7, 0xf7, 0xe8, 0x05, 0xf4, 0x65, 0xe6, 0x8b, 0xca, 0xe2, 0x95, 0x10, 0xdd, 0xdd, 0xec, 0xb6, 0x34, 0x2f, 0xae, 0x12, 0x02, 0x6d, 0xda, 0xf4, 0x4d, 0x4a, 0x66, 0xfc, 0xf7, 0x7b, 0xc2, 0x81, 0x44, 0xa9, 0x62, 0xb9, 0x5b, 0xc9, 0x09, 0x9d, 0x87, 0x1e, 0x4d, 0xbe, 0x5f, 0x0a, 0x94, 0x78, 0xa5, 0x24, 0xaf, 0xb7, 0x90, 0x94, 0xac, 0x3f, 0x80, 0xa1, 0xae, 0x79, 0x9e, 0xab, 0xe7, 0x86, 0xae, 0xd5, 0x71, 0x9f, 0x2d, 0x2d, 0x81, 0xfc, 0x26, 0x4c, 0xa8, 0xad, 0xa1, 0x21, 0x1a, 0x7a, 0xc9, 0x86, 0x97, 0x22, 0x83, 0xe8, 0x09, 0x2c, 0xf2, 0xc3, 0x5d, 0xb9, 0x44, 0x39, 0xd7, 0xe9, 0x09, 0x4c, 0x0f, 0xa7, 0x3c, 0xd5, 0xc9, 0x2d, 0xbb, 0x16, 0xe2, 0xa8, 0x7e, 0x81, 0xd4, 0x66, 0x85, 0x4f, 0x68, 0xbe, 0x2e, 0x99, 0x7a, 0xea, 0x54, 0x29, 0x9c, 0x88, 0xcb, 0x83, 0x97, 0x67, 0xd4, 0x65, 0xdd, 0x18, 0x45, 0x35, 0x23, 0xac, 0x2b, 0x7d, 0x3c, 0x6b, 0x69, 0xa5, 0xc4, 0x1f, 0xdd, 0xe7, 0x7a, 0xe5, 0x61 };
static const unsigned char vec5_inv_cinv[195] = { 0xe1, 0xab, 0xf1, 0x0b, 0xbb, 0x29, 0xf0, 0xf7, 0x33, 0xc4, 0x8e, 0x6f, 0xa6, 0x16, 0x94, 0x58, 0x75, 0x2a, 0x39, 0x8d, 0xfa, 0x5c, 0x37, 0x8d, 0x66, 0xb2, 0xb4, 0xfd, 0xe6, 0x5b, 0x27, 0xec, 0x46, 0x4f, 0x8e, 0x55, 0xc0, 0xd5, 0x13, 0x65, 0xf2, 0x99, 0xa2, 0x78, 0x3e, 0xd4, 0xc9, 0x47, 0x5d, 0x4d, 0x45, 0xbd, 0x5c, 0xd7, 0xe8, 0xd2, 0x82, 0xc2, 0x4a, 0xe5, 0xd1, 0x5d, 0xe9, 0x4a, 0x71, 0x7f, 0x6a, 0xf2, 0xad, 0x9d, 0x84, 0x6e, 0x5d, 0x39, 0x36, 0xec, 0x80, 0xf1, 0xba, 0xa4, 0x1d, 0x5b, 0x09, 0xc6, 0xd5, 0x50, 0xeb, 0x45, 0x7c, 0x21, 0x7e, 0x86, 0xff, 0xf8, 0x15, 0x6c, 0x03, 0x46, 0x53, 0x9b, 0xa9, 0x64, 0xd2, 0x4c, 0x64, 0x4b, 0x70, 0x9e, 0xa7, 0x39, 0xc3, 0xc0, 0x2d, 0x6a, 0xa3, 0xce, 0xe8, 0xd2, 0xad, 0x1d, 0x86, 0xff, 0x27, 0x51, 0x8b, 0xf6, 0xd1, 0xa4, 0x42, 0x03, 0x03, 0x35, 0xc1, 0x1b, 0x53, 0x33, 0xf4, 0xb5, 0x2c, 0x35, 0xaf, 0xcb, 0x5c, 0xc7, 0x8d, 0x15, 0x30, 0xdf, 0x92, 0x04, 0xe1, 0x26, 0xe1, 0x5f, 0x4b, 0x33, 0xb0, 0x2a, 0x59, 0x67, 0xf4, 0x80, 0x03, 0x31, 0x29, 0xb0, 0x6b, 0xfb, 0xf6, 0x50, 0xe1, 0x70, 0xd4, 0x90, 0x59, 0xd5, 0xcd, 0x80, 0x10, 0x1b, 0x39, 0xd8, 0x45, 0x04, 0x4f, 0xc3, 0x55, 0xea, 0x24, 0x18, 0x6f, 0x94, 0xe1, 0x62, 0xb2 };
static const unsigned char vec5_inv_secshare[32] = { 0x40, 0x03, 0x27, 0xf8, 0xd3, 0xb5, 0x90, 0x1a, 0xb1, 0x15, 0x1f, 0x57, 0x34, 0xee, 0x71, 0xea, 0x8c, 0xa6, 0x79, 0x0f, 0xc6, 0xd7, 0x6a, 0xe8, 0x19, 0xc8, 0xb2, 0x46, 0x17, 0x4f, 0xaf, 0xce };
static const unsigned char vec5_inv_pubshare[33] = { 0x02, 0x08, 0xd9, 0x49, 0xec, 0x74, 0xe5, 0xc0, 0xd9, 0x65, 0x75, 0xb8, 0x17, 0xd9, 0x3b, 0x00, 0xf8, 0xc3, 0xf6, 0x03, 0xde, 0x20, 0x66, 0x00, 0xc9, 0x3c, 0x18, 0xb0, 0x25, 0x4d, 0xc4, 0x47, 0x2e };
static const unsigned char vec5_inv_enc_secshare[32] = { 0x99, 0x7a, 0xea, 0x54, 0x29, 0x9c, 0x88, 0xcb, 0x83, 0x97, 0x67, 0xd4, 0x65, 0xdd, 0x18, 0x45, 0x35, 0x23, 0xac, 0x2b, 0x7d, 0x3c, 0x6b, 0x69, 0xa5, 0xc4, 0x1f, 0xdd, 0xe7, 0x7a, 0xe5, 0x61 };
static const unsigned char vec5_inv_pads[3][32] = {
    { 0xa5, 0x7a, 0xcd, 0xa1, 0x9b, 0x4a, 0x2b, 0x89, 0xf3, 0x10, 0x6d, 0xd2, 0x77, 0x09, 0x3b, 0x29, 0x42, 0x86, 0x77, 0x22, 0x3b, 0x58, 0x8a, 0xe8, 0xa6, 0xa0, 0x9a, 0xfc, 0x43, 0x14, 0x42, 0x36 },
    { 0x01, 0x8d, 0x94, 0xfa, 0x65, 0x1c, 0x3f, 0xdb, 0x06, 0x08, 0x3a, 0xcf, 0x2f, 0xd5, 0x79, 0x36, 0x53, 0x99, 0x1a, 0x8d, 0x80, 0x2f, 0x6a, 0xfa, 0x7a, 0xb4, 0x3d, 0x9f, 0xd1, 0x45, 0x59, 0xa2 },
    { 0xb2, 0x6f, 0x5f, 0xbf, 0x55, 0x80, 0x8d, 0x4b, 0xd9, 0x69, 0x9f, 0xdb, 0x8a, 0x0f, 0xf1, 0xf9, 0xcd, 0x0c, 0x7e, 0x52, 0xaa, 0x25, 0xaa, 0xda, 0x2a, 0x78, 0xf3, 0x88, 0x8c, 0x07, 0xda, 0xfc },
};
/* investigation: dealer 1 sent bad share to participant 2; blame = FaultyParticipantOrCoordinatorError(1) */
static const unsigned char vec5_inv_cmsg1_coord_bad[519] = { 0x02, 0xa9, 0xf7, 0xa6, 0x54, 0x1e, 0x12, 0x22, 0x46, 0xfd, 0x57, 0xee, 0xdc, 0x6e, 0x3a, 0x6a, 0x12, 0x48, 0x05, 0x4f, 0x02, 0x2b, 0x7c, 0x01, 0xe2, 0xa4, 0x36, 0x4c, 0x09, 0x20, 0xda, 0x93, 0x4b, 0x03, 0x1a, 0x5c, 0xb4, 0x0b, 0x67, 0xdb, 0xbc, 0xc4, 0x8b, 0x03, 0xcc, 0x2c, 0xc5, 0x54, 0x52, 0x0c, 0x01, 0x72, 0x57, 0x55, 0xd5, 0x2a, 0x0d, 0xec, 0x5d, 0xb1, 0xe0, 0xe1, 0xad, 0x00, 0x45, 0x59, 0x02, 0x54, 0xc4, 0xc5, 0x71, 0x04, 0x3b, 0x01, 0x22, 0xe0, 0x1a, 0x79, 0x37, 0x1e, 0x0f, 0xc2, 0x6b, 0x66, 0x4e, 0xbc, 0xbb, 0x4e, 0x18, 0xe5, 0x1a, 0xa9, 0x67, 0x21, 0x18, 0x23, 0x0b, 0x86, 0xef, 0x02, 0x67, 0x0c, 0x35, 0xb2, 0xae, 0x50, 0x90, 0xff, 0xe0, 0x32, 0x36, 0xee, 0x4f, 0x86, 0xf9, 0x31, 0xac, 0x79, 0x80, 0x64, 0xfb, 0x9d, 0x9c, 0xd1, 0x95, 0x4b, 0xf0, 0x5f, 0xc1, 0x38, 0x38, 0x69, 0xf5, 0xb1, 0x94, 0x34, 0xb9, 0x81, 0x06, 0x4d, 0x17, 0xa1, 0x6a, 0x1d, 0x81, 0x58, 0x4c, 0xf0, 0x55, 0xdf, 0x32, 0x62, 0x08, 0xd8, 0x29, 0x1e, 0xf2, 0xa6, 0xa3, 0xdb, 0x52, 0x98, 0xb8, 0x0f, 0xe6, 0x49, 0x74, 0xe1, 0x9f, 0x90, 0x70, 0x66, 0x09, 0x6b, 0xa9, 0xd5, 0x05, 0xd6, 0xb2, 0x36, 0x7a, 0xf2, 0x9b, 0xbb, 0x0e, 0x66, 0xed, 0x22, 0xd5, 0xdf, 0x21, 0xba, 0x1e, 0x51, 0x77, 0x40, 0x1d, 0xf4, 0x21, 0xdd, 0xdf, 0x41, 0xc4, 0x1c, 0xae, 0x3a, 0x03, 0xd6, 0xd6, 0x7a, 0x25, 0x48, 0xcb, 0x36, 0x8b, 0xfa, 0x59, 0xb8, 0xfe, 0x6a, 0x2a, 0x39, 0x1b, 0x30, 0x60, 0xd0, 0x2e, 0x8b, 0x2d, 0xab, 0x0a, 0x99, 0x90, 0x31, 0xb9, 0x0f, 0x62, 0xa1, 0xb0, 0x1a, 0x3f, 0x3e, 0x43, 0xf6, 0xce, 0x94, 0x73, 0xcc, 0x88, 0xda, 0x76, 0x91, 0x66, 0x98, 0xa2, 0xd2, 0x4f, 0xdf, 0x81, 0xcb, 0xa7, 0x13, 0x00, 0x3b, 0x39, 0x2d, 0x2d, 0x35, 0xa5, 0x7c, 0x5d, 0x3c, 0x96, 0x92, 0xb8, 0xd4, 0x43, 0x94, 0xca, 0xf7, 0x71, 0x60, 0x5c, 0x6f, 0x5b, 0x99, 0x33, 0xcb, 0x39, 0xf8, 0xae, 0xf5, 0xbc, 0x92, 0x09, 0x3f, 0x03, 0xd0, 0x5c, 0x4a, 0x16, 0xff, 0x0a, 0xc3, 0x0b, 0x34, 0x78, 0xe7, 0xea, 0xfb, 0x48, 0xbc, 0x38, 0xbb, 0x18, 0x20, 0xf0, 0x8f, 0x10, 0x63, 0x3f, 0x42, 0xf4, 0xbd, 0x03, 0x07, 0xd9, 0x3f, 0x10, 0xca, 0xd5, 0x95, 0x92, 0xf3, 0x83, 0xc1, 0xd0, 0x0e, 0xb3, 0xb2, 0xf0, 0xea, 0xcb, 0x67, 0x79, 0xd7, 0xc1, 0x70, 0x0a, 0x42, 0x74, 0x77, 0x4d, 0xfd, 0x00, 0xab, 0x72, 0x03, 0x7f, 0xc5, 0xc6, 0x73, 0xb0, 0xe6, 0xfb, 0x74, 0x98, 0xce, 0x1a, 0x86, 0xd7, 0xf7, 0xe8, 0x05, 0xf4, 0x65, 0xe6, 0x8b, 0xca, 0xe2, 0x95, 0x10, 0xdd, 0xdd, 0xec, 0xb6, 0x34, 0x2f, 0xae, 0x12, 0x02, 0x6d, 0xda, 0xf4, 0x4d, 0x4a, 0x66, 0xfc, 0xf7, 0x7b, 0xc2, 0x81, 0x44, 0xa9, 0x62, 0xb9, 0x5b, 0xc9, 0x09, 0x9d, 0x87, 0x1e, 0x4d, 0xbe, 0x5f, 0x0a, 0x94, 0x78, 0xa5, 0x24, 0xaf, 0xb7, 0x90, 0x94, 0xac, 0x3f, 0x80, 0xa1, 0xae, 0x79, 0x9e, 0xab, 0xe7, 0x86, 0xae, 0xd5, 0x71, 0x9f, 0x2d, 0x2d, 0x81, 0xfc, 0x26, 0x4c, 0xa8, 0xad, 0xa1, 0x21, 0x1a, 0x7a, 0xc9, 0x86, 0x97, 0x22, 0x83, 0xe8, 0x09, 0x2c, 0xf2, 0xc3, 0x5d, 0xb9, 0x44, 0x39, 0xd7, 0xe9, 0x09, 0x4c, 0x0f, 0xa7, 0x3c, 0xd5, 0xc9, 0x2d, 0xbb, 0x16, 0xe2, 0xa8, 0x7e, 0x81, 0xd4, 0x66, 0x85, 0x4f, 0x68, 0xbe, 0x2e, 0x99, 0x7a, 0xea, 0x54, 0x29, 0x9c, 0x88, 0xcb, 0x83, 0x97, 0x67, 0xd4, 0x65, 0xdd, 0x18, 0x45, 0x35, 0x23, 0xac, 0x2b, 0x7d, 0x3c, 0x6b, 0x69, 0xa5, 0xc4, 0x1f, 0xdd, 0xe7, 0x7a, 0xe5, 0x63 };
/* investigation: coordinator tampered with enc_secshare of 2; blame = FaultyCoordinatorError */
/* chilldkg session n = 3, t = 2 */
/* all python-side sanity checks passed */

/* The group order n and (2^256 - 1) mod n, for scalar parsing edge cases. */
static const unsigned char vec_scalar_order_n[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
};
static const unsigned char vec_scalar_order_n_minus_1[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, 0x40
};
static const unsigned char vec_scalar_wrapped_ff[32] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x45, 0x51, 0x23, 0x19, 0x50, 0xb7, 0x5f, 0xc4,
    0x40, 0x2d, 0xa1, 0x73, 0x2f, 0xc9, 0xbe, 0xbe
};

static void chilldkg_tagged_hashes_test(void) {
    const secp256k1_hash_ctx *hash_ctx = secp256k1_get_hash_context(CTX);
    secp256k1_sha256 sha;
    unsigned char out[32];

    secp256k1_chilldkg_sha256_tagged_encpedpop_seed(hash_ctx, &sha);
    secp256k1_sha256_write(hash_ctx, &sha, vec_th_encpedpop_seed_msg, sizeof(vec_th_encpedpop_seed_msg));
    secp256k1_sha256_finalize(hash_ctx, &sha, out);
    CHECK(secp256k1_memcmp_var(out, vec_th_encpedpop_seed, 32) == 0);

    secp256k1_chilldkg_sha256_tagged_simplpedpop_aux(hash_ctx, &sha);
    secp256k1_sha256_write(hash_ctx, &sha, vec_th_simplpedpop_aux_msg, sizeof(vec_th_simplpedpop_aux_msg));
    secp256k1_sha256_finalize(hash_ctx, &sha, out);
    CHECK(secp256k1_memcmp_var(out, vec_th_simplpedpop_aux, 32) == 0);

    secp256k1_chilldkg_sha256_tagged_encpedpop_secnonce(hash_ctx, &sha);
    secp256k1_sha256_write(hash_ctx, &sha, vec_th_encpedpop_secnonce_msg, sizeof(vec_th_encpedpop_secnonce_msg));
    secp256k1_sha256_finalize(hash_ctx, &sha, out);
    CHECK(secp256k1_memcmp_var(out, vec_th_encpedpop_secnonce, 32) == 0);

    secp256k1_chilldkg_sha256_tagged_encpedpop_ecdh(hash_ctx, &sha);
    secp256k1_sha256_write(hash_ctx, &sha, vec_th_encpedpop_ecdh_msg, sizeof(vec_th_encpedpop_ecdh_msg));
    secp256k1_sha256_finalize(hash_ctx, &sha, out);
    CHECK(secp256k1_memcmp_var(out, vec_th_encpedpop_ecdh, 32) == 0);

    secp256k1_chilldkg_sha256_tagged_self_pad(hash_ctx, &sha);
    secp256k1_sha256_write(hash_ctx, &sha, vec_th_encaps_multi_self_pad_msg, sizeof(vec_th_encaps_multi_self_pad_msg));
    secp256k1_sha256_finalize(hash_ctx, &sha, out);
    CHECK(secp256k1_memcmp_var(out, vec_th_encaps_multi_self_pad, 32) == 0);

    secp256k1_chilldkg_sha256_tagged_vss_coeffs(hash_ctx, &sha);
    secp256k1_sha256_write(hash_ctx, &sha, vec_th_vss_coeffs_msg, sizeof(vec_th_vss_coeffs_msg));
    secp256k1_sha256_finalize(hash_ctx, &sha, out);
    CHECK(secp256k1_memcmp_var(out, vec_th_vss_coeffs, 32) == 0);

    /* BIP 341 TapTweak over the x-only encoding of 2*G (no merkle root). */
    secp256k1_chilldkg_sha256_tagged_taptweak(hash_ctx, &sha);
    secp256k1_sha256_write(hash_ctx, &sha, vec_taptweak_msg, sizeof(vec_taptweak_msg));
    secp256k1_sha256_finalize(hash_ctx, &sha, out);
    CHECK(secp256k1_memcmp_var(out, vec_taptweak, 32) == 0);
}

static void chilldkg_params_hash_test(void) {
    const secp256k1_hash_ctx *hash_ctx = secp256k1_get_hash_context(CTX);
    unsigned char out[32];

    /* TH("BIP DKG/params_hash", u32be(2) || hostpubkeys) */
    secp256k1_chilldkg_params_hash_internal(hash_ctx, out, &vec_params_hash_hostpubkeys[0][0], 3, 2);
    CHECK(secp256k1_memcmp_var(out, vec_params_hash, 32) == 0);

    /* t is part of the hash input. */
    secp256k1_chilldkg_params_hash_internal(hash_ctx, out, &vec_params_hash_hostpubkeys[0][0], 3, 3);
    CHECK(secp256k1_memcmp_var(out, vec_params_hash, 32) != 0);
}

static void chilldkg_point_serialization_test(void) {
    static const unsigned char zeros33[33] = { 0 };
    secp256k1_ge p, q;
    secp256k1_gej pj;
    secp256k1_scalar one;
    unsigned char buf[33];
    unsigned char buf32[32];
    size_t i;

    /* Roundtrip of the compressed encodings of 1*G, 2*G and 3*G. */
    for (i = 0; i < 3; i++) {
        const unsigned char *expected = i == 0 ? vec_point_0 : (i == 1 ? vec_point_1 : vec_point_2);
        CHECK(secp256k1_chilldkg_point_load(&p, expected) == 1);
        CHECK(!secp256k1_ge_is_infinity(&p));
        secp256k1_chilldkg_point_save(buf, &p);
        CHECK(secp256k1_memcmp_var(buf, expected, 33) == 0);
    }

    /* 1*G computed in C serializes like the reference. */
    secp256k1_scalar_set_int(&one, 1);
    secp256k1_ecmult_gen_gej(&CTX->ecmult_gen_ctx, &pj, &one);
    secp256k1_ge_set_gej(&p, &pj);
    secp256k1_chilldkg_point_save(buf, &p);
    CHECK(secp256k1_memcmp_var(buf, vec_point_0, 33) == 0);

    /* The point at infinity maps to 33 zero bytes and back. */
    CHECK(secp256k1_chilldkg_point_load(&p, zeros33) == 1);
    CHECK(secp256k1_ge_is_infinity(&p));
    secp256k1_chilldkg_point_save(buf, &p);
    CHECK(secp256k1_memcmp_var(buf, zeros33, 33) == 0);

    /* Invalid encodings are rejected and distinguishable from success. */
    /* Wrong prefix (0x04). */
    memcpy(buf, vec_point_0, 33);
    buf[0] = 0x04;
    CHECK(secp256k1_chilldkg_point_load(&p, buf) == 0);
    /* x >= p. */
    buf[0] = 0x02;
    memset(&buf[1], 0xff, 32);
    CHECK(secp256k1_chilldkg_point_load(&p, buf) == 0);
    /* x = 0 is not on the curve (0^3 + 7 = 7 is not a quadratic residue). */
    buf[0] = 0x02;
    memset(&buf[1], 0x00, 32);
    CHECK(secp256k1_chilldkg_point_load(&p, buf) == 0);
    /* 0x03 with x = 0 is also not on the curve. */
    buf[0] = 0x03;
    CHECK(secp256k1_chilldkg_point_load(&p, buf) == 0);

    /* The prefix selects the y parity: 0x03 || x(G) is -G. */
    memcpy(buf, vec_point_0, 33);
    buf[0] = 0x03;
    CHECK(secp256k1_chilldkg_point_load(&p, buf) == 1);
    CHECK(secp256k1_chilldkg_point_load(&q, vec_point_0) == 1);
    secp256k1_ge_neg(&q, &q);
    CHECK(secp256k1_ge_eq_var(&p, &q));
    secp256k1_chilldkg_point_save(buf, &p);
    CHECK(buf[0] == 0x03);

    /* x-only save/load roundtrip (even y representative). */
    CHECK(secp256k1_chilldkg_point_load(&p, vec_point_2) == 1);
    secp256k1_chilldkg_xonly_save(buf32, &p);
    CHECK(secp256k1_memcmp_var(buf32, &vec_point_2[1], 32) == 0);
    CHECK(secp256k1_chilldkg_xonly_load(&q, buf32) == 1);
    secp256k1_chilldkg_xonly_save(buf, &q);
    CHECK(secp256k1_memcmp_var(buf, buf32, 32) == 0);
    /* x-only load rejects x >= p and non-curve x. */
    memset(buf32, 0xff, 32);
    CHECK(secp256k1_chilldkg_xonly_load(&q, buf32) == 0);
    memset(buf32, 0x00, 32);
    CHECK(secp256k1_chilldkg_xonly_load(&q, buf32) == 0);
}

static void chilldkg_scalar_parse_test(void) {
    static const unsigned char ff32[32] = {
        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
    };
    static const unsigned char zeros32[32] = { 0 };
    secp256k1_scalar s;
    unsigned char out[32];
    int overflow;

    /* Checked parse (Scalar.from_bytes_checked): n and above are rejected. */
    secp256k1_scalar_set_b32(&s, vec_scalar_order_n, &overflow);
    CHECK(overflow);
    secp256k1_scalar_set_b32(&s, ff32, &overflow);
    CHECK(overflow);
    /* n - 1 and 0 are accepted. */
    secp256k1_scalar_set_b32(&s, vec_scalar_order_n_minus_1, &overflow);
    CHECK(!overflow);
    secp256k1_scalar_get_b32(out, &s);
    CHECK(secp256k1_memcmp_var(out, vec_scalar_order_n_minus_1, 32) == 0);
    secp256k1_scalar_set_b32(&s, zeros32, &overflow);
    CHECK(!overflow);
    CHECK(secp256k1_scalar_is_zero(&s));

    /* Wrapping parse (Scalar.from_bytes_wrapping): reduce mod n. */
    secp256k1_scalar_set_b32(&s, ff32, NULL);
    secp256k1_scalar_get_b32(out, &s);
    CHECK(secp256k1_memcmp_var(out, vec_scalar_wrapped_ff, 32) == 0);
    secp256k1_scalar_set_b32(&s, vec_scalar_order_n, NULL);
    CHECK(secp256k1_scalar_is_zero(&s));
}

static void chilldkg_schnorrsig_test(void) {
    unsigned char sig[64];
    unsigned char sig_ref[64];
    unsigned char pop_msg[4] = { 0, 0, 0, 5 };
    unsigned char msg[101];
    unsigned char msg32[32];
    unsigned char zero32[32] = { 0 };
    secp256k1_keypair keypair;
    size_t i;

    /* Proof of possession: custom tag prefix "BIP DKG/pop message" over
     * u32be(participant_id). */
    CHECK(secp256k1_chilldkg_schnorrsig_sign(CTX, sig, pop_msg, sizeof(pop_msg), vec_pop_seckey, vec_pop_aux, "BIP DKG/pop message") == 1);
    CHECK(secp256k1_memcmp_var(sig, vec_pop_sig, 64) == 0);
    CHECK(secp256k1_chilldkg_schnorrsig_verify(CTX, sig, pop_msg, sizeof(pop_msg), vec_pop_pubkey, "BIP DKG/pop message") == 1);
    /* Wrong tag prefix, message or public key fail verification. */
    CHECK(secp256k1_chilldkg_schnorrsig_verify(CTX, sig, pop_msg, sizeof(pop_msg), vec_pop_pubkey, "BIP0340") == 0);
    pop_msg[3] = 6;
    CHECK(secp256k1_chilldkg_schnorrsig_verify(CTX, sig, pop_msg, sizeof(pop_msg), vec_pop_pubkey, "BIP DKG/pop message") == 0);
    pop_msg[3] = 5;
    CHECK(secp256k1_chilldkg_schnorrsig_verify(CTX, sig, pop_msg, sizeof(pop_msg), vec_certeq_pubkey, "BIP DKG/pop message") == 0);
    /* A corrupted signature fails verification. */
    sig[63] ^= 1;
    CHECK(secp256k1_chilldkg_schnorrsig_verify(CTX, sig, pop_msg, sizeof(pop_msg), vec_pop_pubkey, "BIP DKG/pop message") == 0);
    sig[63] ^= 1;

    /* CertEq-style message: standard "BIP0340" tags over an
     * arbitrary-length message with a 33-byte zero-padded prefix
     * (pad33("BIP DKG/certeq message") || u32be(id) || eq_input). */
    secp256k1_chilldkg_pad33(msg, "BIP DKG/certeq message");
    /* pad33 zero-pads to exactly 33 bytes. */
    CHECK(secp256k1_memcmp_var(msg, "BIP DKG/certeq message", 22) == 0);
    for (i = 22; i < 33; i++) {
        CHECK(msg[i] == 0);
    }
    secp256k1_write_be32(msg + 33, 7);
    memcpy(msg + 37, vec_certeq_eq_input, 64);
    CHECK(secp256k1_chilldkg_schnorrsig_sign(CTX, sig, msg, sizeof(msg), vec_certeq_seckey, vec_certeq_aux, "BIP0340") == 1);
    CHECK(secp256k1_memcmp_var(sig, vec_certeq_sig, 64) == 0);
    CHECK(secp256k1_chilldkg_schnorrsig_verify(CTX, sig, msg, sizeof(msg), vec_certeq_pubkey, "BIP0340") == 1);
    CHECK(secp256k1_chilldkg_schnorrsig_verify(CTX, sig, msg, sizeof(msg), vec_certeq_pubkey, "BIP DKG/pop message") == 0);

    /* With the "BIP0340" tag prefix and a 32-byte message, the internal
     * signer agrees with the public schnorrsig module. */
    for (i = 0; i < 32; i++) {
        msg32[i] = (unsigned char)(i + 1);
    }
    CHECK(secp256k1_keypair_create(CTX, &keypair, vec_certeq_seckey) == 1);
    CHECK(secp256k1_schnorrsig_sign32(CTX, sig_ref, msg32, &keypair, vec_certeq_aux) == 1);
    CHECK(secp256k1_chilldkg_schnorrsig_sign(CTX, sig, msg32, 32, vec_certeq_seckey, vec_certeq_aux, "BIP0340") == 1);
    CHECK(secp256k1_memcmp_var(sig, sig_ref, 64) == 0);

    /* Invalid secret keys (0 and n) are rejected. */
    CHECK(secp256k1_chilldkg_schnorrsig_sign(CTX, sig, msg32, 32, zero32, vec_certeq_aux, "BIP0340") == 0);
    CHECK(secp256k1_memcmp_var(sig, zero32, 32) == 0);
    CHECK(secp256k1_chilldkg_schnorrsig_sign(CTX, sig, msg32, 32, vec_scalar_order_n, vec_certeq_aux, "BIP0340") == 0);
}

static void chilldkg_ecdh_pad_test(void) {
    const secp256k1_hash_ctx *hash_ctx = secp256k1_get_hash_context(CTX);
    secp256k1_scalar secnonce, hostseckey, pad, self_pad;
    secp256k1_ge pubnonce_ge, hostpubkey_ge;
    /* context = u32be(receiver_index = 0) || enc_context */
    unsigned char context[4 + 70];
    unsigned char out[32];
    int overflow;

    secp256k1_write_be32(context, 0);
    memcpy(context + 4, vec_ecdh_enc_context, 70);

    secp256k1_scalar_set_b32(&secnonce, vec_ecdh_secnonce, &overflow);
    CHECK(!overflow);
    secp256k1_scalar_set_b32(&hostseckey, vec_ecdh_hostseckey, &overflow);
    CHECK(!overflow);
    CHECK(secp256k1_chilldkg_point_load(&pubnonce_ge, vec_ecdh_pubnonce) == 1);
    CHECK(secp256k1_chilldkg_point_load(&hostpubkey_ge, vec_ecdh_hostpubkey) == 1);

    /* Sender side: ecdh(secnonce, my=pubnonce, their=hostpubkey, sending). */
    secp256k1_chilldkg_encpedpop_ecdh(CTX, &pad, &secnonce, &hostpubkey_ge, vec_ecdh_pubnonce, vec_ecdh_hostpubkey, context, sizeof(context), 1);
    secp256k1_scalar_get_b32(out, &pad);
    CHECK(secp256k1_memcmp_var(out, vec_ecdh_pad, 32) == 0);

    /* Receiver side: ecdh(hostseckey, my=hostpubkey, their=pubnonce, !sending)
     * derives the same pad. */
    secp256k1_chilldkg_encpedpop_ecdh(CTX, &pad, &hostseckey, &pubnonce_ge, vec_ecdh_hostpubkey, vec_ecdh_pubnonce, context, sizeof(context), 0);
    secp256k1_scalar_get_b32(out, &pad);
    CHECK(secp256k1_memcmp_var(out, vec_ecdh_pad, 32) == 0);

    /* Swapping the roles on the sender side changes the pad (the sender's
     * pubnonce comes first in the hash input). */
    secp256k1_chilldkg_encpedpop_ecdh(CTX, &pad, &secnonce, &hostpubkey_ge, vec_ecdh_pubnonce, vec_ecdh_hostpubkey, context, sizeof(context), 0);
    secp256k1_scalar_get_b32(out, &pad);
    CHECK(secp256k1_memcmp_var(out, vec_ecdh_pad, 32) != 0);

    /* Symmetric self pad. */
    secp256k1_chilldkg_encpedpop_self_pad(hash_ctx, &self_pad, vec_ecdh_hostseckey, vec_ecdh_pubnonce, context, sizeof(context));
    secp256k1_scalar_get_b32(out, &self_pad);
    CHECK(secp256k1_memcmp_var(out, vec_self_pad, 32) == 0);

    secp256k1_scalar_clear(&secnonce);
    secp256k1_scalar_clear(&hostseckey);
    secp256k1_scalar_clear(&pad);
    secp256k1_scalar_clear(&self_pad);
}

static void chilldkg_vss_test(void) {
    const secp256k1_hash_ctx *hash_ctx = secp256k1_get_hash_context(CTX);
    secp256k1_scalar coeffs[3], share, share2, x, tweak;
    secp256k1_ge coms[3], coms_b[3], coms_sum[3], tweaked[3], pubtweak, pubshare;
    secp256k1_gej pubsharej;
    unsigned char buf[33];
    unsigned char buf32[32];
    size_t i, j;

    /* Coefficient derivation from the seed. */
    CHECK(secp256k1_chilldkg_vss_gen_coeffs(hash_ctx, coeffs, 3, vec_vss_seed) == 1);
    for (j = 0; j < 3; j++) {
        secp256k1_scalar_get_b32(buf32, &coeffs[j]);
        CHECK(secp256k1_memcmp_var(buf32, vec_vss_coeffs[j], 32) == 0);
    }

    /* Shamir shares f(id+1) via Horner. */
    for (i = 0; i < 4; i++) {
        secp256k1_chilldkg_vss_secshare_for(&share, coeffs, 3, (uint32_t)i);
        secp256k1_scalar_get_b32(buf32, &share);
        CHECK(secp256k1_memcmp_var(buf32, vec_vss_secshares[i], 32) == 0);
    }
    /* The x = id+1 convention: secshare_for(0) is the evaluation at x = 1. */
    secp256k1_scalar_set_int(&x, 1);
    secp256k1_chilldkg_vss_poly_eval(&share2, coeffs, 3, &x);
    secp256k1_chilldkg_vss_secshare_for(&share, coeffs, 3, 0);
    secp256k1_scalar_get_b32(buf32, &share);
    secp256k1_scalar_get_b32(buf, &share2);
    CHECK(secp256k1_memcmp_var(buf32, buf, 32) == 0);

    /* Commitments com_j = coeffs[j]*G. */
    secp256k1_chilldkg_vss_commit(CTX, coms, coeffs, 3);
    for (j = 0; j < 3; j++) {
        secp256k1_chilldkg_point_save(buf, &coms[j]);
        CHECK(secp256k1_memcmp_var(buf, vec_vss_coms[j], 33) == 0);
    }

    /* Pubshares sum_j (id+1)^j * com_j, and share verification. */
    for (i = 0; i < 4; i++) {
        secp256k1_chilldkg_vss_pubshare(&pubsharej, coms, 3, (uint32_t)i);
        CHECK(!secp256k1_gej_is_infinity(&pubsharej));
        secp256k1_ge_set_gej_var(&pubshare, &pubsharej);
        secp256k1_chilldkg_point_save(buf, &pubshare);
        CHECK(secp256k1_memcmp_var(buf, vec_vss_pubshares[i], 33) == 0);
        secp256k1_chilldkg_vss_secshare_for(&share, coeffs, 3, (uint32_t)i);
        CHECK(secp256k1_chilldkg_vss_verify_secshare(CTX, &share, &pubshare) == 1);
    }
    /* The share of participant 0 does not verify against pubshare 1. */
    secp256k1_chilldkg_vss_pubshare(&pubsharej, coms, 3, 1);
    secp256k1_ge_set_gej_var(&pubshare, &pubsharej);
    secp256k1_chilldkg_vss_secshare_for(&share, coeffs, 3, 0);
    CHECK(secp256k1_chilldkg_vss_verify_secshare(CTX, &share, &pubshare) == 0);

    /* Component-wise commitment addition. */
    CHECK(secp256k1_chilldkg_vss_gen_coeffs(hash_ctx, coeffs, 3, vec_vss_seed_b) == 1);
    secp256k1_chilldkg_vss_commit(CTX, coms_b, coeffs, 3);
    for (j = 0; j < 3; j++) {
        secp256k1_chilldkg_point_save(buf, &coms_b[j]);
        CHECK(secp256k1_memcmp_var(buf, vec_vss_coms_b[j], 33) == 0);
    }
    /* Reload the first commitment (coeffs were overwritten above). */
    for (j = 0; j < 3; j++) {
        CHECK(secp256k1_chilldkg_point_load(&coms[j], vec_vss_coms[j]) == 1);
    }
    secp256k1_chilldkg_vss_commitment_add(coms_sum, coms, coms_b, 3);
    for (j = 0; j < 3; j++) {
        secp256k1_chilldkg_point_save(buf, &coms_sum[j]);
        CHECK(secp256k1_memcmp_var(buf, vec_vss_coms_sum[j], 33) == 0);
    }
    /* Adding the point at infinity (33 zero bytes) is the identity. */
    {
        secp256k1_ge inf_com[3], id_sum[3];
        static const unsigned char zeros33[33] = { 0 };
        for (j = 0; j < 3; j++) {
            CHECK(secp256k1_chilldkg_point_load(&inf_com[j], zeros33) == 1);
        }
        secp256k1_chilldkg_vss_commitment_add(id_sum, coms, inf_com, 3);
        for (j = 0; j < 3; j++) {
            secp256k1_chilldkg_point_save(buf, &id_sum[j]);
            CHECK(secp256k1_memcmp_var(buf, vec_vss_coms[j], 33) == 0);
        }
    }

    /* TapTweak: the tweaked commitment, tweak and pubtweak match the
     * reference, and the tweaked share verifies against the tweaked
     * pubshare. */
    CHECK(secp256k1_chilldkg_vss_invalid_taproot_commit(CTX, tweaked, &tweak, &pubtweak, coms, 3) == 1);
    secp256k1_scalar_get_b32(buf32, &tweak);
    CHECK(secp256k1_memcmp_var(buf32, vec_tweak, 32) == 0);
    secp256k1_chilldkg_point_save(buf, &pubtweak);
    CHECK(secp256k1_memcmp_var(buf, vec_pubtweak, 33) == 0);
    for (j = 0; j < 3; j++) {
        secp256k1_chilldkg_point_save(buf, &tweaked[j]);
        CHECK(secp256k1_memcmp_var(buf, vec_vss_coms_tweaked[j], 33) == 0);
    }
    CHECK(secp256k1_chilldkg_vss_gen_coeffs(hash_ctx, coeffs, 3, vec_vss_seed) == 1);
    secp256k1_chilldkg_vss_secshare_for(&share, coeffs, 3, 0);
    secp256k1_scalar_add(&share, &share, &tweak);
    secp256k1_chilldkg_vss_pubshare(&pubsharej, tweaked, 3, 0);
    secp256k1_ge_set_gej_var(&pubshare, &pubsharej);
    CHECK(secp256k1_chilldkg_vss_verify_secshare(CTX, &share, &pubshare) == 1);

    /* invalid_taproot_commit fails on an infinity constant term. */
    {
        static const unsigned char zeros33[33] = { 0 };
        CHECK(secp256k1_chilldkg_point_load(&coms[0], zeros33) == 1);
        CHECK(secp256k1_chilldkg_vss_invalid_taproot_commit(CTX, tweaked, &tweak, &pubtweak, coms, 3) == 0);
    }

    for (j = 0; j < 3; j++) {
        secp256k1_scalar_clear(&coeffs[j]);
    }
    secp256k1_scalar_clear(&share);
    secp256k1_scalar_clear(&share2);
    secp256k1_scalar_clear(&x);
    secp256k1_scalar_clear(&tweak);
}

static void chilldkg_simplpedpop_test(void) {
    const uint32_t n = 3, t = 2;
    const size_t pmsg_len = 33 * 2 + 64;
    const size_t cmsg_len = 97 * 3 + 33 * 1;
    const size_t eq_len = 4 + 33 * 2;
    secp256k1_chilldkg_simplpedpop_participant_state states[3];
    secp256k1_scalar shares[3][3]; /* shares[dealer][recipient] */
    secp256k1_scalar partials[3];
    secp256k1_scalar secshare, secshare_tweaked;
    secp256k1_ge pubshare;
    unsigned char pmsgs[3][130];
    const unsigned char *pmsg_ptrs[3];
    unsigned char cmsg[324];
    unsigned char cmsg_bad[324];
    unsigned char eq_input[70];
    unsigned char buf32[32];
    secp256k1_chilldkg_simplpedpop_dkg_output dkg_outputs[3];
    secp256k1_chilldkg_simplpedpop_dkg_output coord_dkg;
    secp256k1_chilldkg_fault fault;
    uint32_t fault_index = 0;
    uint32_t i, j;

    /* participant_step1: messages are byte-exact against the reference. */
    for (i = 0; i < n; i++) {
        CHECK(secp256k1_chilldkg_simplpedpop_participant_step1(CTX, &states[i], pmsgs[i], shares[i], vec_simpl_seeds[i], t, n, i, vec_simpl_auxs[i]) == 1);
        CHECK(secp256k1_memcmp_var(pmsgs[i], vec_simpl_pmsgs[i], pmsg_len) == 0);
        pmsg_ptrs[i] = pmsgs[i];
    }
    /* Invalid inputs are rejected: participant_id >= n, t > n, t == 0, n
     * exceeding the participant cap. */
    CHECK(secp256k1_chilldkg_simplpedpop_participant_step1(CTX, &states[0], pmsgs[0], shares[0], vec_simpl_seeds[0], t, n, n, vec_simpl_auxs[0]) == 0);
    CHECK(secp256k1_chilldkg_simplpedpop_participant_step1(CTX, &states[0], pmsgs[0], shares[0], vec_simpl_seeds[0], n + 1, n, 0, vec_simpl_auxs[0]) == 0);
    CHECK(secp256k1_chilldkg_simplpedpop_participant_step1(CTX, &states[0], pmsgs[0], shares[0], vec_simpl_seeds[0], 0, n, 0, vec_simpl_auxs[0]) == 0);
    CHECK(secp256k1_chilldkg_simplpedpop_participant_step1(CTX, &states[0], pmsgs[0], shares[0], vec_simpl_seeds[0], t, SECP256K1_CHILLDKG_MAX_PARTICIPANTS + 1, 0, vec_simpl_auxs[0]) == 0);

    /* coordinator_step: cmsg, eq_input and the DKG output are byte-exact. */
    fault = secp256k1_chilldkg_simplpedpop_coordinator_step(CTX, cmsg, &coord_dkg, eq_input, &fault_index, pmsg_ptrs, t, n);
    CHECK(fault == SECP256K1_CHILLDKG_OK);
    CHECK(secp256k1_memcmp_var(cmsg, vec_simpl_cmsg, cmsg_len) == 0);
    CHECK(secp256k1_memcmp_var(eq_input, vec_simpl_eq_input, eq_len) == 0);
    CHECK(secp256k1_memcmp_var(coord_dkg.thresh_pk33, vec_simpl_thresh_pk, 33) == 0);
    for (j = 0; j < 32; j++) {
        CHECK(coord_dkg.secshare32[j] == 0);
    }
    for (i = 0; i < n; i++) {
        CHECK(secp256k1_memcmp_var(coord_dkg.pubshares33[i], vec_simpl_pubshares[i], 33) == 0);
    }

    /* participant_step2 for all participants (happy path). */
    for (i = 0; i < n; i++) {
        unsigned char eq_input_p[70];
        for (j = 0; j < n; j++) {
            partials[j] = shares[j][i];
        }
        secp256k1_chilldkg_simplpedpop_participant_step2_prepare_secshare(&secshare, partials, n);
        secp256k1_scalar_get_b32(buf32, &secshare);
        CHECK(secp256k1_memcmp_var(buf32, vec_simpl_untweaked_secshares[i], 32) == 0);
        fault = secp256k1_chilldkg_simplpedpop_participant_step2(CTX, &dkg_outputs[i], eq_input_p, &fault_index, NULL, &states[i], cmsg, cmsg_len, &secshare);
        CHECK(fault == SECP256K1_CHILLDKG_OK);
        CHECK(secp256k1_memcmp_var(eq_input_p, vec_simpl_eq_input, eq_len) == 0);
        CHECK(secp256k1_memcmp_var(dkg_outputs[i].secshare32, vec_simpl_secshares[i], 32) == 0);
        CHECK(secp256k1_memcmp_var(dkg_outputs[i].thresh_pk33, vec_simpl_thresh_pk, 33) == 0);
        for (j = 0; j < n; j++) {
            CHECK(secp256k1_memcmp_var(dkg_outputs[i].pubshares33[j], vec_simpl_pubshares[j], 33) == 0);
        }
        /* The tweaked secshare verifies against the tweaked own pubshare. */
        secp256k1_scalar_set_b32(&secshare_tweaked, dkg_outputs[i].secshare32, NULL);
        CHECK(secp256k1_chilldkg_point_load(&pubshare, dkg_outputs[i].pubshares33[i]) == 1);
        CHECK(secp256k1_chilldkg_vss_verify_secshare(CTX, &secshare_tweaked, &pubshare) == 1);
    }

    /* Fault cases (participant 0's view; the untweaked secshare of
     * participant 0 is still in `secshare`). */
    for (j = 0; j < n; j++) {
        partials[j] = shares[j][0];
    }
    secp256k1_chilldkg_simplpedpop_participant_step2_prepare_secshare(&secshare, partials, n);

    /* The coordinator echoes a wrong commitment to our secret. */
    memcpy(cmsg_bad, cmsg, cmsg_len);
    {
        unsigned char swap[33];
        memcpy(swap, cmsg_bad, 33);
        memcpy(cmsg_bad, cmsg_bad + 33, 33);
        memcpy(cmsg_bad + 33, swap, 33);
    }
    fault = secp256k1_chilldkg_simplpedpop_participant_step2(CTX, &dkg_outputs[0], eq_input, &fault_index, NULL, &states[0], cmsg_bad, cmsg_len, &secshare);
    CHECK(fault == SECP256K1_CHILLDKG_FAULTY_COORDINATOR);

    /* A tampered pop blames the corresponding participant (or the
     * coordinator). */
    memcpy(cmsg_bad, cmsg, cmsg_len);
    cmsg_bad[33 * 3 + 33 * 1 + 64 * 1] ^= 1;
    fault_index = 0;
    fault = secp256k1_chilldkg_simplpedpop_participant_step2(CTX, &dkg_outputs[0], eq_input, &fault_index, NULL, &states[0], cmsg_bad, cmsg_len, &secshare);
    CHECK(fault == SECP256K1_CHILLDKG_FAULTY_PARTICIPANT_OR_COORDINATOR);
    CHECK(fault_index == 1);

    /* A pop valid for participant 2 fails at the position of participant 1
     * (wrong signer for this index). */
    memcpy(cmsg_bad, cmsg, cmsg_len);
    {
        unsigned char swap[64];
        memcpy(swap, cmsg_bad + 33 * 3 + 33 + 64, 64);
        memcpy(cmsg_bad + 33 * 3 + 33 + 64, cmsg_bad + 33 * 3 + 33 + 2 * 64, 64);
        memcpy(cmsg_bad + 33 * 3 + 33 + 2 * 64, swap, 64);
    }
    fault_index = 0;
    fault = secp256k1_chilldkg_simplpedpop_participant_step2(CTX, &dkg_outputs[0], eq_input, &fault_index, NULL, &states[0], cmsg_bad, cmsg_len, &secshare);
    CHECK(fault == SECP256K1_CHILLDKG_FAULTY_PARTICIPANT_OR_COORDINATOR);
    CHECK(fault_index == 1);

    /* A point at infinity as commitment to the secret of participant 2. */
    memcpy(cmsg_bad, cmsg, cmsg_len);
    memset(cmsg_bad + 33 * 2, 0, 33);
    fault_index = 0;
    fault = secp256k1_chilldkg_simplpedpop_participant_step2(CTX, &dkg_outputs[0], eq_input, &fault_index, NULL, &states[0], cmsg_bad, cmsg_len, &secshare);
    CHECK(fault == SECP256K1_CHILLDKG_FAULTY_PARTICIPANT_OR_COORDINATOR);
    CHECK(fault_index == 2);

    /* A tampered sum of the commitments to the non-constant terms (flipping
     * the prefix byte negates the point, which stays valid) makes the
     * secshare verification fail: the fault cannot be attributed without the
     * investigation procedure. */
    memcpy(cmsg_bad, cmsg, cmsg_len);
    cmsg_bad[33 * 3] ^= 1;
    fault_index = 0;
    fault = secp256k1_chilldkg_simplpedpop_participant_step2(CTX, &dkg_outputs[0], eq_input, &fault_index, NULL, &states[0], cmsg_bad, cmsg_len, &secshare);
    CHECK(fault == SECP256K1_CHILLDKG_UNKNOWN_FAULTY_PARTICIPANT_OR_COORDINATOR);
    CHECK(fault_index == UINT32_MAX);

    /* A malformed cmsg (wrong length, invalid point) blames the coordinator. */
    fault = secp256k1_chilldkg_simplpedpop_participant_step2(CTX, &dkg_outputs[0], eq_input, &fault_index, NULL, &states[0], cmsg, cmsg_len - 1, &secshare);
    CHECK(fault == SECP256K1_CHILLDKG_FAULTY_COORDINATOR);
    memcpy(cmsg_bad, cmsg, cmsg_len);
    cmsg_bad[0] = 0x04;
    fault = secp256k1_chilldkg_simplpedpop_participant_step2(CTX, &dkg_outputs[0], eq_input, &fault_index, NULL, &states[0], cmsg_bad, cmsg_len, &secshare);
    CHECK(fault == SECP256K1_CHILLDKG_FAULTY_COORDINATOR);

    /* The coordinator blames the sender of a malformed participant message. */
    {
        unsigned char pmsg_bad[130];
        const unsigned char *pmsg_bad_ptrs[3];
        pmsg_bad_ptrs[0] = pmsg_ptrs[0];
        pmsg_bad_ptrs[1] = pmsg_bad;
        pmsg_bad_ptrs[2] = pmsg_ptrs[2];
        memcpy(pmsg_bad, pmsgs[1], pmsg_len);
        pmsg_bad[0] = 0x04; /* invalid point in the commitment */
        fault_index = 0;
        fault = secp256k1_chilldkg_simplpedpop_coordinator_step(CTX, cmsg_bad, &coord_dkg, eq_input, &fault_index, pmsg_bad_ptrs, t, n);
        CHECK(fault == SECP256K1_CHILLDKG_FAULTY_PARTICIPANT);
        CHECK(fault_index == 1);
        /* Invalid session parameters are input errors. */
        fault = secp256k1_chilldkg_simplpedpop_coordinator_step(CTX, cmsg_bad, &coord_dkg, eq_input, &fault_index, pmsg_ptrs, n + 1, n);
        CHECK(fault == SECP256K1_CHILLDKG_INVALID_INPUT);
    }

    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            secp256k1_scalar_clear(&shares[i][j]);
        }
        secp256k1_scalar_clear(&partials[i]);
    }
    secp256k1_scalar_clear(&secshare);
    secp256k1_scalar_clear(&secshare_tweaked);
}

static void chilldkg_encpedpop_test(void) {
    const uint32_t n = 3, t = 2;
    const size_t pmsg_len = 33 * 2 + 64 + 33 + 32 * 3;
    const size_t simpl_cmsg_len = 97 * 3 + 33 * 1;
    const size_t cmsg_len = simpl_cmsg_len + 33 * 3;
    const size_t eq_len = 4 + 33 * 2 + 33 * 3 + 33 * 3;
    secp256k1_chilldkg_encpedpop_participant_state states[3];
    secp256k1_scalar enc_secshares[3];
    secp256k1_scalar pads_send[3];
    secp256k1_scalar pads_recv[3];
    secp256k1_scalar scalar_tmp, scalar_tmp2;
    secp256k1_ge pubshare;
    unsigned char pmsgs[3][259];
    const unsigned char *pmsg_ptrs[3];
    unsigned char cmsg[423];
    unsigned char cmsg_bad[423];
    unsigned char eq_input[268];
    unsigned char enc_context[4 + 33 * 3];
    unsigned char buf32[32];
    secp256k1_chilldkg_simplpedpop_dkg_output dkg_output;
    secp256k1_chilldkg_simplpedpop_dkg_output coord_dkg;
    secp256k1_chilldkg_fault fault;
    uint32_t fault_index = 0;
    uint32_t i, j;
    int overflow;

    /* serialize_enc_context: u32be(t) || host public keys. */
    secp256k1_chilldkg_encpedpop_serialize_enc_context(enc_context, t, &vec_enc_hostpubkeys[0][0], n);
    CHECK(secp256k1_memcmp_var(enc_context, vec_enc_context, sizeof(enc_context)) == 0);

    /* participant_step1: messages (and thus the derivations of simpl_seed,
     * secnonce, pubnonce, shares and pads) are byte-exact against the
     * reference. */
    for (i = 0; i < n; i++) {
        CHECK(secp256k1_chilldkg_encpedpop_participant_step1(CTX, &states[i], pmsgs[i], vec_enc_hostseckeys[i], vec_enc_hostseckeys[i], &vec_enc_hostpubkeys[0][0], t, i, vec_enc_randoms[i], n) == 1);
        CHECK(secp256k1_memcmp_var(pmsgs[i], vec_enc_pmsgs[i], pmsg_len) == 0);
        CHECK(secp256k1_memcmp_var(states[i].pubnonce33, vec_enc_pubnonces[i], 33) == 0);
        pmsg_ptrs[i] = pmsgs[i];
    }
    /* Invalid inputs are rejected. */
    CHECK(secp256k1_chilldkg_encpedpop_participant_step1(CTX, &states[0], pmsgs[0], vec_enc_hostseckeys[0], vec_enc_hostseckeys[0], &vec_enc_hostpubkeys[0][0], t, n, vec_enc_randoms[0], n) == 0);
    CHECK(secp256k1_chilldkg_encpedpop_participant_step1(CTX, &states[0], pmsgs[0], vec_enc_hostseckeys[0], vec_enc_hostseckeys[0], &vec_enc_hostpubkeys[0][0], n + 1, 0, vec_enc_randoms[0], n) == 0);

    /* Pad symmetry: the pad computed by sender 0 for recipient i equals the
     * pad computed by recipient i for sender 0 (for the own index both sides
     * use the symmetric self pad). */
    secp256k1_scalar_set_b32(&scalar_tmp, vec_enc_secnonces[0], &overflow);
    CHECK(!overflow);
    CHECK(secp256k1_chilldkg_encpedpop_encaps_multi(CTX, pads_send, &scalar_tmp, vec_enc_pubnonces[0], vec_enc_hostseckeys[0], &vec_enc_hostpubkeys[0][0], enc_context, sizeof(enc_context), 0, n) == 1);
    for (i = 0; i < n; i++) {
        fault = secp256k1_chilldkg_encpedpop_decaps_multi(CTX, pads_recv, &fault_index, vec_enc_hostseckeys[i], vec_enc_hostpubkeys[i], &vec_enc_pubnonces[0][0], enc_context, sizeof(enc_context), i, n);
        CHECK(fault == SECP256K1_CHILLDKG_OK);
        CHECK(secp256k1_scalar_eq(&pads_send[i], &pads_recv[0]));
    }
    /* decaps_multi rejects an invalid own host secret key. */
    memset(buf32, 0, 32);
    fault = secp256k1_chilldkg_encpedpop_decaps_multi(CTX, pads_recv, &fault_index, buf32, vec_enc_hostpubkeys[0], &vec_enc_pubnonces[0][0], enc_context, sizeof(enc_context), 0, n);
    CHECK(fault == SECP256K1_CHILLDKG_INVALID_INPUT);

    /* encrypt -> coordinator sum -> decrypt_sum roundtrip with deterministic
     * plaintexts (plaintext from sender i to recipient j is 3*i + j + 1). */
    for (j = 0; j < n; j++) {
        secp256k1_scalar_set_int(&enc_secshares[j], 0);
    }
    for (i = 0; i < n; i++) {
        secp256k1_scalar plaintexts[3];
        secp256k1_scalar ciphertexts[3];
        secp256k1_scalar_set_b32(&scalar_tmp, vec_enc_secnonces[i], &overflow);
        CHECK(!overflow);
        for (j = 0; j < n; j++) {
            secp256k1_scalar_set_int(&plaintexts[j], 3 * i + j + 1);
        }
        CHECK(secp256k1_chilldkg_encpedpop_encrypt_multi(CTX, ciphertexts, &scalar_tmp, vec_enc_pubnonces[i], vec_enc_hostseckeys[i], &vec_enc_hostpubkeys[0][0], enc_context, sizeof(enc_context), i, plaintexts, n) == 1);
        for (j = 0; j < n; j++) {
            secp256k1_scalar_add(&enc_secshares[j], &enc_secshares[j], &ciphertexts[j]);
            secp256k1_scalar_clear(&plaintexts[j]);
            secp256k1_scalar_clear(&ciphertexts[j]);
        }
    }
    for (j = 0; j < n; j++) {
        fault = secp256k1_chilldkg_encpedpop_decrypt_sum(CTX, &scalar_tmp, &fault_index, vec_enc_hostseckeys[j], vec_enc_hostpubkeys[j], &vec_enc_pubnonces[0][0], enc_context, sizeof(enc_context), j, &enc_secshares[j], n);
        CHECK(fault == SECP256K1_CHILLDKG_OK);
        secp256k1_scalar_set_int(&scalar_tmp2, 0);
        for (i = 0; i < n; i++) {
            secp256k1_scalar p;
            secp256k1_scalar_set_int(&p, 3 * i + j + 1);
            secp256k1_scalar_add(&scalar_tmp2, &scalar_tmp2, &p);
        }
        CHECK(secp256k1_scalar_eq(&scalar_tmp, &scalar_tmp2));
    }

    /* coordinator_step: cmsg, eq_input, summed encrypted shares and the DKG
     * output are byte-exact. */
    fault = secp256k1_chilldkg_encpedpop_coordinator_step(CTX, cmsg, &coord_dkg, eq_input, enc_secshares, &fault_index, pmsg_ptrs, t, &vec_enc_hostpubkeys[0][0], n);
    CHECK(fault == SECP256K1_CHILLDKG_OK);
    CHECK(secp256k1_memcmp_var(cmsg, vec_enc_cmsg, cmsg_len) == 0);
    CHECK(secp256k1_memcmp_var(eq_input, vec_enc_eq_input, eq_len) == 0);
    for (i = 0; i < n; i++) {
        secp256k1_scalar_get_b32(buf32, &enc_secshares[i]);
        CHECK(secp256k1_memcmp_var(buf32, vec_enc_secshares[i], 32) == 0);
        CHECK(secp256k1_memcmp_var(coord_dkg.pubshares33[i], vec_enc_pubshares[i], 33) == 0);
    }
    CHECK(secp256k1_memcmp_var(coord_dkg.thresh_pk33, vec_enc_thresh_pk, 33) == 0);

    /* participant_step2 for all participants (happy path): the decrypted
     * (tweaked) secshare matches the pubshare, and all outputs are
     * byte-exact. */
    for (i = 0; i < n; i++) {
        unsigned char eq_input_p[268];
        fault = secp256k1_chilldkg_encpedpop_participant_step2(CTX, &dkg_output, eq_input_p, &fault_index, NULL, &states[i], vec_enc_hostseckeys[i], cmsg, cmsg_len, &enc_secshares[i]);
        CHECK(fault == SECP256K1_CHILLDKG_OK);
        CHECK(secp256k1_memcmp_var(eq_input_p, vec_enc_eq_input, eq_len) == 0);
        CHECK(secp256k1_memcmp_var(dkg_output.secshare32, vec_enc_out_secshares[i], 32) == 0);
        CHECK(secp256k1_memcmp_var(dkg_output.thresh_pk33, vec_enc_thresh_pk, 33) == 0);
        for (j = 0; j < n; j++) {
            CHECK(secp256k1_memcmp_var(dkg_output.pubshares33[j], vec_enc_pubshares[j], 33) == 0);
        }
        secp256k1_scalar_set_b32(&scalar_tmp, dkg_output.secshare32, NULL);
        CHECK(secp256k1_chilldkg_point_load(&pubshare, dkg_output.pubshares33[i]) == 1);
        CHECK(secp256k1_chilldkg_vss_verify_secshare(CTX, &scalar_tmp, &pubshare) == 1);
    }

    /* Fault cases (participant 0's view). */

    /* The coordinator echoes a wrong pubnonce for us. */
    memcpy(cmsg_bad, cmsg, cmsg_len);
    cmsg_bad[simpl_cmsg_len] ^= 1;
    fault = secp256k1_chilldkg_encpedpop_participant_step2(CTX, &dkg_output, eq_input, &fault_index, NULL, &states[0], vec_enc_hostseckeys[0], cmsg_bad, cmsg_len, &enc_secshares[0]);
    CHECK(fault == SECP256K1_CHILLDKG_FAULTY_COORDINATOR);

    /* An invalid pubnonce of sender 1 (bad encoding, or the infinity
     * encoding) blames the sender or the coordinator. */
    memcpy(cmsg_bad, cmsg, cmsg_len);
    memset(cmsg_bad + simpl_cmsg_len + 33, 0xff, 33);
    fault_index = 0;
    fault = secp256k1_chilldkg_encpedpop_participant_step2(CTX, &dkg_output, eq_input, &fault_index, NULL, &states[0], vec_enc_hostseckeys[0], cmsg_bad, cmsg_len, &enc_secshares[0]);
    CHECK(fault == SECP256K1_CHILLDKG_FAULTY_PARTICIPANT_OR_COORDINATOR);
    CHECK(fault_index == 1);
    memcpy(cmsg_bad, cmsg, cmsg_len);
    memset(cmsg_bad + simpl_cmsg_len + 33, 0, 33);
    fault_index = 0;
    fault = secp256k1_chilldkg_encpedpop_participant_step2(CTX, &dkg_output, eq_input, &fault_index, NULL, &states[0], vec_enc_hostseckeys[0], cmsg_bad, cmsg_len, &enc_secshares[0]);
    CHECK(fault == SECP256K1_CHILLDKG_FAULTY_PARTICIPANT_OR_COORDINATOR);
    CHECK(fault_index == 1);

    /* A tampered encrypted secshare decrypts to a wrong secshare: the fault
     * cannot be attributed without the investigation procedure. */
    secp256k1_scalar_set_int(&scalar_tmp2, 1);
    secp256k1_scalar_add(&scalar_tmp, &enc_secshares[0], &scalar_tmp2);
    fault_index = 0;
    fault = secp256k1_chilldkg_encpedpop_participant_step2(CTX, &dkg_output, eq_input, &fault_index, NULL, &states[0], vec_enc_hostseckeys[0], cmsg, cmsg_len, &scalar_tmp);
    CHECK(fault == SECP256K1_CHILLDKG_UNKNOWN_FAULTY_PARTICIPANT_OR_COORDINATOR);
    CHECK(fault_index == UINT32_MAX);

    /* A malformed cmsg (wrong length) blames the coordinator. */
    fault = secp256k1_chilldkg_encpedpop_participant_step2(CTX, &dkg_output, eq_input, &fault_index, NULL, &states[0], vec_enc_hostseckeys[0], cmsg, cmsg_len - 1, &enc_secshares[0]);
    CHECK(fault == SECP256K1_CHILLDKG_FAULTY_COORDINATOR);

    /* The coordinator blames the sender of a malformed participant message:
     * an encrypted share that overflows the group order, or an invalid
     * commitment. */
    {
        unsigned char pmsg_bad[259];
        const unsigned char *pmsg_bad_ptrs[3];
        pmsg_bad_ptrs[0] = pmsg_ptrs[0];
        pmsg_bad_ptrs[1] = pmsg_bad;
        pmsg_bad_ptrs[2] = pmsg_ptrs[2];
        memcpy(pmsg_bad, pmsgs[1], pmsg_len);
        memset(pmsg_bad + 33 * 2 + 64 + 33, 0xff, 32); /* share for recipient 0 */
        fault_index = 0;
        fault = secp256k1_chilldkg_encpedpop_coordinator_step(CTX, cmsg_bad, &coord_dkg, eq_input, enc_secshares, &fault_index, pmsg_bad_ptrs, t, &vec_enc_hostpubkeys[0][0], n);
        CHECK(fault == SECP256K1_CHILLDKG_FAULTY_PARTICIPANT);
        CHECK(fault_index == 1);
        memcpy(pmsg_bad, pmsgs[1], pmsg_len);
        pmsg_bad[33] = 0x07; /* invalid prefix of the second commitment entry */
        fault_index = 0;
        fault = secp256k1_chilldkg_encpedpop_coordinator_step(CTX, cmsg_bad, &coord_dkg, eq_input, enc_secshares, &fault_index, pmsg_bad_ptrs, t, &vec_enc_hostpubkeys[0][0], n);
        CHECK(fault == SECP256K1_CHILLDKG_FAULTY_PARTICIPANT);
        CHECK(fault_index == 1);
    }

    secp256k1_scalar_clear(&scalar_tmp);
    secp256k1_scalar_clear(&scalar_tmp2);
    for (i = 0; i < n; i++) {
        secp256k1_scalar_clear(&enc_secshares[i]);
        secp256k1_scalar_clear(&pads_send[i]);
        secp256k1_scalar_clear(&pads_recv[i]);
    }
}

static void chilldkg_participant_api_test(void) {
    const size_t n = 3;
    const uint32_t t = 2;
    const size_t pmsg1_len = 33 * 2 + 32 * 3 + 97; /* 259 */
    const size_t cmsg1_len = 162 * 3 + 33 * 1; /* 519 */
    const size_t enc_cmsg_len = 97 * 3 + 33 * 1 + 33 * 3; /* 423 */
    const size_t recovery_len = 4 + 33 * 2 + 162 * 3; /* 556 */
    secp256k1_chilldkg_participant_state1 state1[3];
    secp256k1_chilldkg_participant_state2 state2[3];
    secp256k1_chilldkg_simplpedpop_dkg_output coord_dkg;
    secp256k1_scalar enc_secshares[3];
    unsigned char pmsg1[3][259];
    unsigned char sig64[3][64];
    unsigned char cmsg1[519];
    unsigned char cmsg1_bad[519];
    unsigned char cmsg2[192];
    unsigned char cmsg2_bad[192];
    unsigned char hostpubkeys33[3 * 33];
    unsigned char pubshares33[3 * 33];
    unsigned char recovery[556];
    unsigned char eq_input[268];
    unsigned char buf33[33];
    unsigned char buf32[32];
    unsigned char secshare32[32];
    unsigned char zero32[32] = { 0 };
    const unsigned char *pmsg1_ptrs[3];
    secp256k1_chilldkg_fault fault;
    uint32_t fault_index = 0;
    size_t i, j;

    for (i = 0; i < n; i++) {
        pmsg1_ptrs[i] = pmsg1[i];
        memcpy(hostpubkeys33 + 33 * i, vec3_hostpubkeys[i], 33);
    }

    /* Message length helpers. */
    CHECK(secp256k1_chilldkg_participant_msg1_len(n, t) == pmsg1_len);
    CHECK(secp256k1_chilldkg_coordinator_msg1_len(n, t) == cmsg1_len);
    CHECK(secp256k1_chilldkg_participant_msg2_len() == 64);
    CHECK(secp256k1_chilldkg_coordinator_msg2_len(n) == sizeof(cmsg2));
    CHECK(secp256k1_chilldkg_recovery_data_len(n, t) == recovery_len);
    CHECK(secp256k1_chilldkg_participant_msg1_len(0, 1) == 0);
    CHECK(secp256k1_chilldkg_participant_msg1_len(n, 0) == 0);
    CHECK(secp256k1_chilldkg_participant_msg1_len(n, (uint32_t)(n + 1)) == 0);
    CHECK(secp256k1_chilldkg_participant_msg1_len(SECP256K1_CHILLDKG_MAX_PARTICIPANTS + 1, 1) == 0);
    CHECK(secp256k1_chilldkg_coordinator_msg1_len(n, 0) == 0);
    CHECK(secp256k1_chilldkg_coordinator_msg2_len(0) == 0);
    CHECK(secp256k1_chilldkg_recovery_data_len(n, (uint32_t)(n + 1)) == 0);

    /* hostpubkey_gen: byte-exact against the reference; invalid host secret
     * keys are rejected and zero the output. */
    for (i = 0; i < n; i++) {
        CHECK(secp256k1_chilldkg_hostpubkey_gen(CTX, buf33, vec3_hostseckeys[i]) == 1);
        CHECK(secp256k1_memcmp_var(buf33, vec3_hostpubkeys[i], 33) == 0);
    }
    CHECK(secp256k1_chilldkg_hostpubkey_gen(CTX, buf33, zero32) == 0);
    CHECK(secp256k1_is_zero_array(buf33, 33));
    CHECK(secp256k1_chilldkg_hostpubkey_gen(CTX, buf33, vec_scalar_order_n) == 0);
    CHECK(secp256k1_is_zero_array(buf33, 33));

    /* params_hash: byte-exact against the reference; invalid parameters
     * (duplicate or invalid host public keys, t or n out of range) are
     * rejected and zero the output. */
    CHECK(secp256k1_chilldkg_params_hash(CTX, buf32, hostpubkeys33, n, t) == 1);
    CHECK(secp256k1_memcmp_var(buf32, vec3_params_hash, 32) == 0);
    {
        unsigned char bad_hostpubkeys[3 * 33];
        memcpy(bad_hostpubkeys, hostpubkeys33, sizeof(bad_hostpubkeys));
        memcpy(bad_hostpubkeys + 33, hostpubkeys33, 33); /* duplicate */
        CHECK(secp256k1_chilldkg_params_hash(CTX, buf32, bad_hostpubkeys, n, t) == 0);
        CHECK(secp256k1_is_zero_array(buf32, 32));
        memcpy(bad_hostpubkeys, hostpubkeys33, sizeof(bad_hostpubkeys));
        memset(bad_hostpubkeys + 33, 0xff, 33); /* invalid public key */
        CHECK(secp256k1_chilldkg_params_hash(CTX, buf32, bad_hostpubkeys, n, t) == 0);
        memcpy(bad_hostpubkeys, hostpubkeys33, sizeof(bad_hostpubkeys));
        memset(bad_hostpubkeys + 33, 0, 33); /* infinity is not a valid public key */
        CHECK(secp256k1_chilldkg_params_hash(CTX, buf32, bad_hostpubkeys, n, t) == 0);
    }
    CHECK(secp256k1_chilldkg_params_hash(CTX, buf32, hostpubkeys33, n, 0) == 0);
    CHECK(secp256k1_chilldkg_params_hash(CTX, buf32, hostpubkeys33, n, (uint32_t)(n + 1)) == 0);
    CHECK(secp256k1_chilldkg_params_hash(CTX, buf32, hostpubkeys33, SECP256K1_CHILLDKG_MAX_PARTICIPANTS + 1, t) == 0);

    /* participant_step1: byte-exact messages against the reference. */
    for (i = 0; i < n; i++) {
        CHECK(secp256k1_chilldkg_participant_step1(CTX, &state1[i], pmsg1[i], vec3_hostseckeys[i], hostpubkeys33, n, t, vec3_randoms[i]) == 1);
        CHECK(secp256k1_memcmp_var(pmsg1[i], vec3_pmsgs1[i], pmsg1_len) == 0);
    }

    /* participant_step1 rejects invalid input and zeroes its outputs. */
    {
        secp256k1_chilldkg_participant_state1 tmp_state1;
        unsigned char tmp_pmsg1[259];
        unsigned char other_seckey[32];
        memset(other_seckey, 0, 32);
        other_seckey[31] = 1; /* valid key, but not in hostpubkeys33 */

        /* All-zero randomness (RandomnessError in the reference). */
        CHECK(secp256k1_chilldkg_participant_step1(CTX, &tmp_state1, tmp_pmsg1, vec3_hostseckeys[0], hostpubkeys33, n, t, zero32) == 0);
        CHECK(secp256k1_is_zero_array(tmp_state1.data, sizeof(tmp_state1.data)));
        CHECK(secp256k1_is_zero_array(tmp_pmsg1, sizeof(tmp_pmsg1)));
        /* Host secret key not in the session (HostSeckeyError). */
        CHECK(secp256k1_chilldkg_participant_step1(CTX, &tmp_state1, tmp_pmsg1, other_seckey, hostpubkeys33, n, t, vec3_randoms[0]) == 0);
        /* Invalid host secret key. */
        CHECK(secp256k1_chilldkg_participant_step1(CTX, &tmp_state1, tmp_pmsg1, zero32, hostpubkeys33, n, t, vec3_randoms[0]) == 0);
        /* Invalid session parameters. */
        CHECK(secp256k1_chilldkg_participant_step1(CTX, &tmp_state1, tmp_pmsg1, vec3_hostseckeys[0], hostpubkeys33, n, 0, vec3_randoms[0]) == 0);
        CHECK(secp256k1_chilldkg_participant_step1(CTX, &tmp_state1, tmp_pmsg1, vec3_hostseckeys[0], hostpubkeys33, n, (uint32_t)(n + 1), vec3_randoms[0]) == 0);
    }

    /* Simulate the coordinator with the internal EncPedPop coordinator step:
     * cmsg1 = enc_cmsg || enc_secshares. The result is byte-exact against the
     * reference coordinator_step1. */
    fault = secp256k1_chilldkg_encpedpop_coordinator_step(CTX, cmsg1, &coord_dkg, eq_input, enc_secshares, &fault_index, pmsg1_ptrs, t, hostpubkeys33, n);
    CHECK(fault == SECP256K1_CHILLDKG_OK);
    for (i = 0; i < n; i++) {
        secp256k1_scalar_get_b32(cmsg1 + enc_cmsg_len + 32 * i, &enc_secshares[i]);
    }
    CHECK(secp256k1_memcmp_var(cmsg1, vec3_cmsg1, cmsg1_len) == 0);

    /* participant_step2: byte-exact CertEq signatures against the reference. */
    for (i = 0; i < n; i++) {
        fault = secp256k1_chilldkg_participant_step2(CTX, &state2[i], sig64[i], &fault_index, NULL, &state1[i], vec3_hostseckeys[i], cmsg1, vec3_aux_rands[i]);
        CHECK(fault == SECP256K1_CHILLDKG_OK);
        CHECK(secp256k1_memcmp_var(sig64[i], vec3_pmsgs2[i], 64) == 0);
    }

    /* The certificate is the concatenation of the pmsg2 signatures. */
    for (i = 0; i < n; i++) {
        memcpy(cmsg2 + 64 * i, sig64[i], 64);
    }
    CHECK(secp256k1_memcmp_var(cmsg2, vec3_cmsg2, sizeof(cmsg2)) == 0);

    /* participant_finalize: byte-exact outputs against the reference. */
    for (i = 0; i < n; i++) {
        fault = secp256k1_chilldkg_participant_finalize(CTX, secshare32, buf33, pubshares33, recovery, &fault_index, &state2[i], cmsg2);
        CHECK(fault == SECP256K1_CHILLDKG_OK);
        CHECK(secp256k1_memcmp_var(secshare32, vec3_secshares[i], 32) == 0);
        CHECK(secp256k1_memcmp_var(buf33, vec3_thresh_pk, 33) == 0);
        for (j = 0; j < n; j++) {
            CHECK(secp256k1_memcmp_var(pubshares33 + 33 * j, vec3_pubshares[j], 33) == 0);
        }
        CHECK(secp256k1_memcmp_var(recovery, vec3_recovery, recovery_len) == 0);
    }

    /* participant_step2 with a host secret key that does not match the one
     * used in step 1 is an input error (HostSeckeyError in the reference). */
    {
        unsigned char tmp_sig64[64];
        fault = secp256k1_chilldkg_participant_step2(CTX, &state2[0], tmp_sig64, &fault_index, NULL, &state1[0], vec3_hostseckeys[1], cmsg1, vec3_aux_rands[0]);
        CHECK(fault == SECP256K1_CHILLDKG_INVALID_INPUT);
        CHECK(secp256k1_is_zero_array(tmp_sig64, 64));
    }

    /* participant_step2 blames faults correctly. */
    {
        secp256k1_chilldkg_participant_state1 fresh_state1;
        unsigned char tmp_sig64[64];

        /* A tampered encrypted secshare: the decrypted share does not match
         * the pubshare; the fault cannot be attributed without the
         * investigation procedure. */
        CHECK(secp256k1_chilldkg_participant_step1(CTX, &fresh_state1, pmsg1[0], vec3_hostseckeys[0], hostpubkeys33, n, t, vec3_randoms[0]) == 1);
        memcpy(cmsg1_bad, cmsg1, cmsg1_len);
        cmsg1_bad[enc_cmsg_len + 31] ^= 1;
        fault_index = 0;
        fault = secp256k1_chilldkg_participant_step2(CTX, &state2[0], tmp_sig64, &fault_index, NULL, &fresh_state1, vec3_hostseckeys[0], cmsg1_bad, vec3_aux_rands[0]);
        CHECK(fault == SECP256K1_CHILLDKG_UNKNOWN_FAULTY_PARTICIPANT_OR_COORDINATOR);
        CHECK(fault_index == UINT32_MAX);

        /* An invalid pubnonce of participant 1 blames that participant or the
         * coordinator. */
        CHECK(secp256k1_chilldkg_participant_step1(CTX, &fresh_state1, pmsg1[0], vec3_hostseckeys[0], hostpubkeys33, n, t, vec3_randoms[0]) == 1);
        memcpy(cmsg1_bad, cmsg1, cmsg1_len);
        memset(cmsg1_bad + 324 + 33, 0xff, 33);
        fault_index = 0;
        fault = secp256k1_chilldkg_participant_step2(CTX, &state2[0], tmp_sig64, &fault_index, NULL, &fresh_state1, vec3_hostseckeys[0], cmsg1_bad, vec3_aux_rands[0]);
        CHECK(fault == SECP256K1_CHILLDKG_FAULTY_PARTICIPANT_OR_COORDINATOR);
        CHECK(fault_index == 1);

        /* An encrypted secshare that overflows the group order blames the
         * coordinator. */
        CHECK(secp256k1_chilldkg_participant_step1(CTX, &fresh_state1, pmsg1[0], vec3_hostseckeys[0], hostpubkeys33, n, t, vec3_randoms[0]) == 1);
        memcpy(cmsg1_bad, cmsg1, cmsg1_len);
        memset(cmsg1_bad + enc_cmsg_len, 0xff, 32);
        fault = secp256k1_chilldkg_participant_step2(CTX, &state2[0], tmp_sig64, &fault_index, NULL, &fresh_state1, vec3_hostseckeys[0], cmsg1_bad, vec3_aux_rands[0]);
        CHECK(fault == SECP256K1_CHILLDKG_FAULTY_COORDINATOR);
    }

    /* participant_finalize: an invalid signature in the certificate blames
     * the coordinator and zeroes the outputs. */
    {
        secp256k1_chilldkg_participant_state1 fresh_state1;
        secp256k1_chilldkg_participant_state2 fresh_state2;
        unsigned char tmp_sig64[64];
        CHECK(secp256k1_chilldkg_participant_step1(CTX, &fresh_state1, pmsg1[0], vec3_hostseckeys[0], hostpubkeys33, n, t, vec3_randoms[0]) == 1);
        fault = secp256k1_chilldkg_participant_step2(CTX, &fresh_state2, tmp_sig64, &fault_index, NULL, &fresh_state1, vec3_hostseckeys[0], cmsg1, vec3_aux_rands[0]);
        CHECK(fault == SECP256K1_CHILLDKG_OK);

        memcpy(cmsg2_bad, cmsg2, sizeof(cmsg2));
        cmsg2_bad[64 + 10] ^= 1; /* corrupt the signature of participant 1 */
        fault_index = 0;
        fault = secp256k1_chilldkg_participant_finalize(CTX, secshare32, buf33, pubshares33, recovery, &fault_index, &fresh_state2, cmsg2_bad);
        CHECK(fault == SECP256K1_CHILLDKG_FAULTY_COORDINATOR);
        CHECK(fault_index == 1);
        CHECK(secp256k1_is_zero_array(secshare32, 32));
        CHECK(secp256k1_is_zero_array(buf33, 33));
        CHECK(secp256k1_is_zero_array(pubshares33, 33 * n));
        CHECK(secp256k1_is_zero_array(recovery, recovery_len));
    }

    /* API misuse. */
    CHECK_ILLEGAL(CTX, secp256k1_chilldkg_hostpubkey_gen(CTX, NULL, vec3_hostseckeys[0]));
    CHECK_ILLEGAL(CTX, secp256k1_chilldkg_hostpubkey_gen(CTX, buf33, NULL));
    CHECK_ILLEGAL(CTX, secp256k1_chilldkg_params_hash(CTX, NULL, hostpubkeys33, n, t));
    CHECK_ILLEGAL(CTX, secp256k1_chilldkg_params_hash(CTX, buf32, NULL, n, t));
    CHECK_ILLEGAL(CTX, secp256k1_chilldkg_participant_step1(CTX, NULL, pmsg1[0], vec3_hostseckeys[0], hostpubkeys33, n, t, vec3_randoms[0]));
    CHECK_ILLEGAL(CTX, secp256k1_chilldkg_participant_step1(CTX, &state1[0], NULL, vec3_hostseckeys[0], hostpubkeys33, n, t, vec3_randoms[0]));
    CHECK_ILLEGAL(CTX, secp256k1_chilldkg_participant_step1(CTX, &state1[0], pmsg1[0], NULL, hostpubkeys33, n, t, vec3_randoms[0]));
    CHECK_ILLEGAL(CTX, secp256k1_chilldkg_participant_step1(CTX, &state1[0], pmsg1[0], vec3_hostseckeys[0], NULL, n, t, vec3_randoms[0]));
    CHECK_ILLEGAL(CTX, secp256k1_chilldkg_participant_step1(CTX, &state1[0], pmsg1[0], vec3_hostseckeys[0], hostpubkeys33, n, t, NULL));
    /* API misuse of the enum-returning functions: the illegal-argument
     * callback fires exactly once and the function returns INVALID_INPUT. */
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_step2(CTX, NULL, sig64[0], &fault_index, NULL, &state1[0], vec3_hostseckeys[0], cmsg1, vec3_aux_rands[0]) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_step2(CTX, &state2[0], NULL, &fault_index, NULL, &state1[0], vec3_hostseckeys[0], cmsg1, vec3_aux_rands[0]) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_step2(CTX, &state2[0], sig64[0], NULL, NULL, &state1[0], vec3_hostseckeys[0], cmsg1, vec3_aux_rands[0]) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_step2(CTX, &state2[0], sig64[0], &fault_index, NULL, NULL, vec3_hostseckeys[0], cmsg1, vec3_aux_rands[0]) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_step2(CTX, &state2[0], sig64[0], &fault_index, NULL, &state1[0], NULL, cmsg1, vec3_aux_rands[0]) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_step2(CTX, &state2[0], sig64[0], &fault_index, NULL, &state1[0], vec3_hostseckeys[0], NULL, vec3_aux_rands[0]) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_step2(CTX, &state2[0], sig64[0], &fault_index, NULL, &state1[0], vec3_hostseckeys[0], cmsg1, NULL) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_finalize(CTX, NULL, buf33, pubshares33, recovery, &fault_index, &state2[0], cmsg2) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_finalize(CTX, secshare32, NULL, pubshares33, recovery, &fault_index, &state2[0], cmsg2) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_finalize(CTX, secshare32, buf33, NULL, recovery, &fault_index, &state2[0], cmsg2) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_finalize(CTX, secshare32, buf33, pubshares33, NULL, &fault_index, &state2[0], cmsg2) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_finalize(CTX, secshare32, buf33, pubshares33, recovery, NULL, &state2[0], cmsg2) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_finalize(CTX, secshare32, buf33, pubshares33, recovery, &fault_index, NULL, cmsg2) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_finalize(CTX, secshare32, buf33, pubshares33, recovery, &fault_index, &state2[0], NULL) == SECP256K1_CHILLDKG_INVALID_INPUT));

    /* States with a bad magic (uninitialized or corrupted) are rejected. */
    {
        secp256k1_chilldkg_participant_state1 bad_state1;
        secp256k1_chilldkg_participant_state2 bad_state2;
        unsigned char tmp_sig64[64];
        memset(&bad_state1, 0, sizeof(bad_state1));
        memset(&bad_state2, 0, sizeof(bad_state2));
        CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_step2(CTX, &state2[0], tmp_sig64, &fault_index, NULL, &bad_state1, vec3_hostseckeys[0], cmsg1, vec3_aux_rands[0]) == SECP256K1_CHILLDKG_INVALID_INPUT));
        CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_finalize(CTX, secshare32, buf33, pubshares33, recovery, &fault_index, &bad_state2, cmsg2) == SECP256K1_CHILLDKG_INVALID_INPUT));
        CHECK(secp256k1_chilldkg_participant_step1(CTX, &bad_state1, pmsg1[0], vec3_hostseckeys[0], hostpubkeys33, n, t, vec3_randoms[0]) == 1);
        bad_state1.data[0] ^= 1;
        CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_step2(CTX, &state2[0], tmp_sig64, &fault_index, NULL, &bad_state1, vec3_hostseckeys[0], cmsg1, vec3_aux_rands[0]) == SECP256K1_CHILLDKG_INVALID_INPUT));
    }

    for (i = 0; i < n; i++) {
        secp256k1_scalar_clear(&enc_secshares[i]);
    }
}

static void chilldkg_coordinator_api_test(void) {
    const size_t n = 3;
    const uint32_t t = 2;
    const size_t pmsg1_len = 33 * 2 + 32 * 3 + 97; /* 259 */
    const size_t cmsg1_len = 162 * 3 + 33 * 1; /* 519 */
    const size_t recovery_len = 4 + 33 * 2 + 162 * 3; /* 556 */
    secp256k1_chilldkg_participant_state1 p_state1[3];
    secp256k1_chilldkg_participant_state2 p_state2[3];
    secp256k1_chilldkg_coordinator_state coord_state;
    unsigned char pmsg1[3][259];
    unsigned char pmsg2[3][64];
    const unsigned char *pmsg1_ptrs[3];
    const unsigned char *pmsg2_ptrs[3];
    unsigned char cmsg1[519];
    unsigned char cmsg2[192];
    unsigned char hostpubkeys33[3 * 33];
    unsigned char pubshares33[3 * 33];
    unsigned char recovery[556];
    unsigned char buf33[33];
    unsigned char secshare32[32];
    secp256k1_chilldkg_fault fault;
    uint32_t fault_index = 0;
    size_t i, j;

    for (i = 0; i < n; i++) {
        pmsg1_ptrs[i] = pmsg1[i];
        pmsg2_ptrs[i] = pmsg2[i];
        memcpy(hostpubkeys33 + 33 * i, vec3_hostpubkeys[i], 33);
    }

    /* A full session using only the public API on both sides. */
    for (i = 0; i < n; i++) {
        CHECK(secp256k1_chilldkg_participant_step1(CTX, &p_state1[i], pmsg1[i], vec3_hostseckeys[i], hostpubkeys33, n, t, vec3_randoms[i]) == 1);
        CHECK(secp256k1_memcmp_var(pmsg1[i], vec3_pmsgs1[i], pmsg1_len) == 0);
    }
    fault = secp256k1_chilldkg_coordinator_step1(CTX, &coord_state, cmsg1, &fault_index, pmsg1_ptrs, hostpubkeys33, n, t);
    CHECK(fault == SECP256K1_CHILLDKG_OK);
    CHECK(secp256k1_memcmp_var(cmsg1, vec3_cmsg1, cmsg1_len) == 0);
    for (i = 0; i < n; i++) {
        fault = secp256k1_chilldkg_participant_step2(CTX, &p_state2[i], pmsg2[i], &fault_index, NULL, &p_state1[i], vec3_hostseckeys[i], cmsg1, vec3_aux_rands[i]);
        CHECK(fault == SECP256K1_CHILLDKG_OK);
        CHECK(secp256k1_memcmp_var(pmsg2[i], vec3_pmsgs2[i], 64) == 0);
    }
    fault = secp256k1_chilldkg_coordinator_finalize(CTX, cmsg2, buf33, pubshares33, recovery, &fault_index, &coord_state, pmsg2_ptrs);
    CHECK(fault == SECP256K1_CHILLDKG_OK);
    CHECK(secp256k1_memcmp_var(cmsg2, vec3_cmsg2, sizeof(cmsg2)) == 0);
    CHECK(secp256k1_memcmp_var(buf33, vec3_thresh_pk, 33) == 0);
    for (j = 0; j < n; j++) {
        CHECK(secp256k1_memcmp_var(pubshares33 + 33 * j, vec3_pubshares[j], 33) == 0);
    }
    CHECK(secp256k1_memcmp_var(recovery, vec3_recovery, recovery_len) == 0);
    /* The participants agree with the coordinator's outputs. */
    for (i = 0; i < n; i++) {
        unsigned char p_recovery[556];
        unsigned char p_pubshares33[3 * 33];
        fault = secp256k1_chilldkg_participant_finalize(CTX, secshare32, buf33, p_pubshares33, p_recovery, &fault_index, &p_state2[i], cmsg2);
        CHECK(fault == SECP256K1_CHILLDKG_OK);
        CHECK(secp256k1_memcmp_var(secshare32, vec3_secshares[i], 32) == 0);
        CHECK(secp256k1_memcmp_var(buf33, vec3_thresh_pk, 33) == 0);
        CHECK(secp256k1_memcmp_var(p_pubshares33, pubshares33, 33 * n) == 0);
        CHECK(secp256k1_memcmp_var(p_recovery, recovery, recovery_len) == 0);
    }

    /* A malformed pmsg1 blames its sender and zeroes the outputs. */
    {
        secp256k1_chilldkg_coordinator_state tmp_state;
        unsigned char pmsg1_bad[259];
        const unsigned char *bad_ptrs[3];
        bad_ptrs[0] = pmsg1[0];
        bad_ptrs[1] = pmsg1_bad;
        bad_ptrs[2] = pmsg1[2];

        /* Invalid commitment encoding. */
        memcpy(pmsg1_bad, pmsg1[1], pmsg1_len);
        pmsg1_bad[0] = 0x04;
        fault_index = 0;
        fault = secp256k1_chilldkg_coordinator_step1(CTX, &tmp_state, cmsg1, &fault_index, bad_ptrs, hostpubkeys33, n, t);
        CHECK(fault == SECP256K1_CHILLDKG_FAULTY_PARTICIPANT);
        CHECK(fault_index == 1);
        CHECK(secp256k1_is_zero_array(cmsg1, cmsg1_len));
        CHECK(secp256k1_is_zero_array(tmp_state.data, sizeof(tmp_state.data)));

        /* An encrypted share that overflows the group order. */
        memcpy(pmsg1_bad, pmsg1[1], pmsg1_len);
        memset(pmsg1_bad + 33 * 2 + 64 + 33, 0xff, 32);
        fault_index = 0;
        fault = secp256k1_chilldkg_coordinator_step1(CTX, &tmp_state, cmsg1, &fault_index, bad_ptrs, hostpubkeys33, n, t);
        CHECK(fault == SECP256K1_CHILLDKG_FAULTY_PARTICIPANT);
        CHECK(fault_index == 1);

        /* Invalid session parameters are input errors. */
        fault = secp256k1_chilldkg_coordinator_step1(CTX, &tmp_state, cmsg1, &fault_index, pmsg1_ptrs, hostpubkeys33, n, 0);
        CHECK(fault == SECP256K1_CHILLDKG_INVALID_INPUT);
        fault = secp256k1_chilldkg_coordinator_step1(CTX, &tmp_state, cmsg1, &fault_index, pmsg1_ptrs, hostpubkeys33, n, (uint32_t)(n + 1));
        CHECK(fault == SECP256K1_CHILLDKG_INVALID_INPUT);
    }

    /* An invalid CertEq signature in a pmsg2 blames the signer (unlike on
     * the participant side, where it blames the coordinator). */
    {
        secp256k1_chilldkg_coordinator_state fresh_state;
        unsigned char pmsg2_bad[64];
        const unsigned char *bad_ptrs[3];
        bad_ptrs[0] = pmsg2[0];
        bad_ptrs[1] = pmsg2[1];
        bad_ptrs[2] = pmsg2_bad;

        fault = secp256k1_chilldkg_coordinator_step1(CTX, &fresh_state, cmsg1, &fault_index, pmsg1_ptrs, hostpubkeys33, n, t);
        CHECK(fault == SECP256K1_CHILLDKG_OK);
        memcpy(pmsg2_bad, pmsg2[2], 64);
        pmsg2_bad[10] ^= 1;
        fault_index = 0;
        fault = secp256k1_chilldkg_coordinator_finalize(CTX, cmsg2, buf33, pubshares33, recovery, &fault_index, &fresh_state, bad_ptrs);
        CHECK(fault == SECP256K1_CHILLDKG_FAULTY_PARTICIPANT);
        CHECK(fault_index == 2);
        CHECK(secp256k1_is_zero_array(cmsg2, sizeof(cmsg2)));
        CHECK(secp256k1_is_zero_array(buf33, 33));
        CHECK(secp256k1_is_zero_array(pubshares33, 33 * n));
        CHECK(secp256k1_is_zero_array(recovery, recovery_len));
    }

    /* API misuse of the enum-returning functions: the illegal-argument
     * callback fires exactly once and the function returns INVALID_INPUT. */
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_coordinator_step1(CTX, NULL, cmsg1, &fault_index, pmsg1_ptrs, hostpubkeys33, n, t) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_coordinator_step1(CTX, &coord_state, NULL, &fault_index, pmsg1_ptrs, hostpubkeys33, n, t) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_coordinator_step1(CTX, &coord_state, cmsg1, NULL, pmsg1_ptrs, hostpubkeys33, n, t) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_coordinator_step1(CTX, &coord_state, cmsg1, &fault_index, NULL, hostpubkeys33, n, t) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_coordinator_step1(CTX, &coord_state, cmsg1, &fault_index, pmsg1_ptrs, NULL, n, t) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_coordinator_finalize(CTX, NULL, buf33, pubshares33, recovery, &fault_index, &coord_state, pmsg2_ptrs) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_coordinator_finalize(CTX, cmsg2, NULL, pubshares33, recovery, &fault_index, &coord_state, pmsg2_ptrs) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_coordinator_finalize(CTX, cmsg2, buf33, NULL, recovery, &fault_index, &coord_state, pmsg2_ptrs) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_coordinator_finalize(CTX, cmsg2, buf33, pubshares33, NULL, &fault_index, &coord_state, pmsg2_ptrs) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_coordinator_finalize(CTX, cmsg2, buf33, pubshares33, recovery, NULL, &coord_state, pmsg2_ptrs) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_coordinator_finalize(CTX, cmsg2, buf33, pubshares33, recovery, &fault_index, NULL, pmsg2_ptrs) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_coordinator_finalize(CTX, cmsg2, buf33, pubshares33, recovery, &fault_index, &coord_state, NULL) == SECP256K1_CHILLDKG_INVALID_INPUT));

    /* A state with a bad magic (uninitialized or corrupted) is rejected. */
    {
        secp256k1_chilldkg_coordinator_state bad_state;
        memset(&bad_state, 0, sizeof(bad_state));
        CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_coordinator_finalize(CTX, cmsg2, buf33, pubshares33, recovery, &fault_index, &bad_state, pmsg2_ptrs) == SECP256K1_CHILLDKG_INVALID_INPUT));
        fault = secp256k1_chilldkg_coordinator_step1(CTX, &bad_state, cmsg1, &fault_index, pmsg1_ptrs, hostpubkeys33, n, t);
        CHECK(fault == SECP256K1_CHILLDKG_OK);
        bad_state.data[0] ^= 1;
        CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_coordinator_finalize(CTX, cmsg2, buf33, pubshares33, recovery, &fault_index, &bad_state, pmsg2_ptrs) == SECP256K1_CHILLDKG_INVALID_INPUT));
    }
}

static void chilldkg_recovery_test(void) {
    const size_t n = 3;
    const uint32_t t = 2;
    const size_t recovery_len = 4 + 33 * 2 + 162 * 3; /* 556 */
    unsigned char hostpubkeys33[3 * 33];
    unsigned char pubshares33[3 * 33];
    unsigned char hostpubkeys_out[3 * 33];
    unsigned char recovery[556];
    unsigned char recovery_bad[556];
    unsigned char buf33[33];
    unsigned char secshare32[32];
    unsigned char ack_sigs[3][64];
    const unsigned char *ack_sig_ptrs[3];
    size_t n_out;
    uint32_t t_out, fault_index;
    secp256k1_chilldkg_fault fault;
    size_t i, j;

    for (i = 0; i < n; i++) {
        memcpy(hostpubkeys33 + 33 * i, vec5_hostpubkeys[i], 33);
        ack_sig_ptrs[i] = ack_sigs[i];
    }

    CHECK(secp256k1_chilldkg_investigation_msg_len(n) == 65 * n);
    CHECK(secp256k1_chilldkg_investigation_msg_len(0) == 0);
    CHECK(secp256k1_chilldkg_investigation_msg_len(SECP256K1_CHILLDKG_MAX_PARTICIPANTS + 1) == 0);

    /* Recovery data taken from the reference vectors directly (the session
     * itself is covered by the participant/coordinator API tests). */
    memcpy(recovery, vec5_recovery, recovery_len);

    /* participant_recover: outputs match the session's DKG output. */
    for (i = 0; i < n; i++) {
        fault = secp256k1_chilldkg_participant_recover(CTX, secshare32, buf33, pubshares33, hostpubkeys_out, &n_out, &t_out, &fault_index, vec5_hostseckeys[i], recovery, recovery_len);
        CHECK(fault == SECP256K1_CHILLDKG_OK);
        CHECK(secp256k1_memcmp_var(secshare32, vec5_secshares[i], 32) == 0);
        CHECK(secp256k1_memcmp_var(buf33, vec5_thresh_pk, 33) == 0);
        for (j = 0; j < n; j++) {
            CHECK(secp256k1_memcmp_var(pubshares33 + 33 * j, vec5_pubshares[j], 33) == 0);
            CHECK(secp256k1_memcmp_var(hostpubkeys_out + 33 * j, vec5_hostpubkeys[j], 33) == 0);
        }
        CHECK(n_out == n && t_out == t);
    }

    /* coordinator_recover: same outputs, no secret share. */
    fault = secp256k1_chilldkg_coordinator_recover(CTX, buf33, pubshares33, hostpubkeys_out, &n_out, &t_out, recovery, recovery_len);
    CHECK(fault == SECP256K1_CHILLDKG_OK);
    CHECK(secp256k1_memcmp_var(buf33, vec5_thresh_pk, 33) == 0);
    CHECK(n_out == n && t_out == t);
    for (j = 0; j < n; j++) {
        CHECK(secp256k1_memcmp_var(pubshares33 + 33 * j, vec5_pubshares[j], 33) == 0);
    }

    /* Invalid recovery data is an input error (RecoveryDataError in the
     * reference) and zeroes the outputs. */
    memcpy(recovery_bad, recovery, recovery_len);
    recovery_bad[recovery_len - 1] ^= 1; /* corrupt the last cert signature */
    fault_index = 0;
    fault = secp256k1_chilldkg_participant_recover(CTX, secshare32, buf33, pubshares33, hostpubkeys_out, &n_out, &t_out, &fault_index, vec5_hostseckeys[0], recovery_bad, recovery_len);
    CHECK(fault == SECP256K1_CHILLDKG_INVALID_INPUT);
    CHECK(fault_index == UINT32_MAX);
    CHECK(secp256k1_is_zero_array(secshare32, 32));
    CHECK(secp256k1_is_zero_array(buf33, 33));
    CHECK(n_out == 0 && t_out == 0);
    /* Truncated and extended recovery data have inconsistent lengths. */
    fault = secp256k1_chilldkg_participant_recover(CTX, secshare32, buf33, pubshares33, hostpubkeys_out, &n_out, &t_out, &fault_index, vec5_hostseckeys[0], recovery, recovery_len - 1);
    CHECK(fault == SECP256K1_CHILLDKG_INVALID_INPUT);
    fault = secp256k1_chilldkg_participant_recover(CTX, secshare32, buf33, pubshares33, hostpubkeys_out, &n_out, &t_out, &fault_index, vec5_hostseckeys[0], recovery, 3);
    CHECK(fault == SECP256K1_CHILLDKG_INVALID_INPUT);
    fault = secp256k1_chilldkg_coordinator_recover(CTX, buf33, pubshares33, hostpubkeys_out, &n_out, &t_out, recovery, recovery_len + 1);
    CHECK(fault == SECP256K1_CHILLDKG_INVALID_INPUT);
    /* A host secret key not in the session is an input error
     * (HostSeckeyError in the reference). */
    {
        unsigned char other_seckey[32] = { 0 };
        other_seckey[31] = 1; /* valid key, but not in the session */
        fault = secp256k1_chilldkg_participant_recover(CTX, secshare32, buf33, pubshares33, hostpubkeys_out, &n_out, &t_out, &fault_index, other_seckey, recovery, recovery_len);
        CHECK(fault == SECP256K1_CHILLDKG_INVALID_INPUT);
    }
    {
        unsigned char zero32[32] = { 0 };
        fault = secp256k1_chilldkg_participant_recover(CTX, secshare32, buf33, pubshares33, hostpubkeys_out, &n_out, &t_out, &fault_index, zero32, recovery, recovery_len);
        CHECK(fault == SECP256K1_CHILLDKG_INVALID_INPUT);
    }

    /* Recovery acks: byte-exact signatures, and verification succeeds. */
    for (i = 0; i < n; i++) {
        CHECK(secp256k1_chilldkg_recovery_ack_sign(CTX, ack_sigs[i], vec5_hostseckeys[i], hostpubkeys33, n, t, recovery, recovery_len, vec5_ack_aux_rands[i]) == 1);
        CHECK(secp256k1_memcmp_var(ack_sigs[i], vec5_ack_sigs[i], 64) == 0);
    }
    fault = secp256k1_chilldkg_recovery_acks_verify(CTX, &fault_index, hostpubkeys33, n, t, recovery, recovery_len, ack_sig_ptrs);
    CHECK(fault == SECP256K1_CHILLDKG_OK);

    /* An invalid ack blames its signer (InvalidRecoveryAckError is a
     * FaultyParticipantError in the reference). */
    {
        unsigned char ack_bad[64];
        const unsigned char *bad_ptrs[3];
        bad_ptrs[0] = ack_sigs[0];
        bad_ptrs[1] = ack_bad;
        bad_ptrs[2] = ack_sigs[2];
        memcpy(ack_bad, ack_sigs[1], 64);
        ack_bad[7] ^= 1;
        fault_index = 0;
        fault = secp256k1_chilldkg_recovery_acks_verify(CTX, &fault_index, hostpubkeys33, n, t, recovery, recovery_len, bad_ptrs);
        CHECK(fault == SECP256K1_CHILLDKG_FAULTY_PARTICIPANT);
        CHECK(fault_index == 1);
        /* An ack for the wrong participant index fails verification. */
        bad_ptrs[1] = ack_sigs[2];
        bad_ptrs[2] = ack_sigs[1];
        fault = secp256k1_chilldkg_recovery_acks_verify(CTX, &fault_index, hostpubkeys33, n, t, recovery, recovery_len, bad_ptrs);
        CHECK(fault == SECP256K1_CHILLDKG_FAULTY_PARTICIPANT);
        CHECK(fault_index == 1);
    }

    /* Ack sign/verify with mismatched session parameters or recovery data
     * fails (RecoveryDataError in the reference). */
    CHECK(secp256k1_chilldkg_recovery_ack_sign(CTX, ack_sigs[0], vec5_hostseckeys[0], hostpubkeys33, n, 1, recovery, recovery_len, vec5_ack_aux_rands[0]) == 0);
    CHECK(secp256k1_is_zero_array(ack_sigs[0], 64));
    memcpy(recovery_bad, recovery, recovery_len);
    recovery_bad[4 + 33 * 2] ^= 1; /* corrupt a host public key in eq_input */
    CHECK(secp256k1_chilldkg_recovery_ack_sign(CTX, ack_sigs[0], vec5_hostseckeys[0], hostpubkeys33, n, t, recovery_bad, recovery_len, vec5_ack_aux_rands[0]) == 0);
    fault = secp256k1_chilldkg_recovery_acks_verify(CTX, &fault_index, hostpubkeys33, n, t, recovery_bad, recovery_len, ack_sig_ptrs);
    CHECK(fault == SECP256K1_CHILLDKG_INVALID_INPUT);
    /* A host secret key not in the session cannot sign an ack. */
    {
        unsigned char other_seckey[32] = { 0 };
        other_seckey[31] = 1;
        CHECK(secp256k1_chilldkg_recovery_ack_sign(CTX, ack_sigs[0], other_seckey, hostpubkeys33, n, t, recovery, recovery_len, vec5_ack_aux_rands[0]) == 0);
    }

    /* API misuse. */
    CHECK_ILLEGAL(CTX, secp256k1_chilldkg_recovery_ack_sign(CTX, NULL, vec5_hostseckeys[0], hostpubkeys33, n, t, recovery, recovery_len, vec5_ack_aux_rands[0]));
    CHECK_ILLEGAL(CTX, secp256k1_chilldkg_recovery_ack_sign(CTX, ack_sigs[0], NULL, hostpubkeys33, n, t, recovery, recovery_len, vec5_ack_aux_rands[0]));
    CHECK_ILLEGAL(CTX, secp256k1_chilldkg_recovery_ack_sign(CTX, ack_sigs[0], vec5_hostseckeys[0], NULL, n, t, recovery, recovery_len, vec5_ack_aux_rands[0]));
    CHECK_ILLEGAL(CTX, secp256k1_chilldkg_recovery_ack_sign(CTX, ack_sigs[0], vec5_hostseckeys[0], hostpubkeys33, n, t, NULL, recovery_len, vec5_ack_aux_rands[0]));
    CHECK_ILLEGAL(CTX, secp256k1_chilldkg_recovery_ack_sign(CTX, ack_sigs[0], vec5_hostseckeys[0], hostpubkeys33, n, t, recovery, recovery_len, NULL));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_recover(CTX, NULL, buf33, pubshares33, hostpubkeys_out, &n_out, &t_out, &fault_index, vec5_hostseckeys[0], recovery, recovery_len) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_recover(CTX, secshare32, buf33, pubshares33, hostpubkeys_out, &n_out, &t_out, &fault_index, NULL, recovery, recovery_len) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_recover(CTX, secshare32, buf33, pubshares33, hostpubkeys_out, &n_out, &t_out, &fault_index, vec5_hostseckeys[0], NULL, recovery_len) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_coordinator_recover(CTX, NULL, pubshares33, hostpubkeys_out, &n_out, &t_out, recovery, recovery_len) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_recovery_acks_verify(CTX, NULL, hostpubkeys33, n, t, recovery, recovery_len, ack_sig_ptrs) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_recovery_acks_verify(CTX, &fault_index, NULL, n, t, recovery, recovery_len, ack_sig_ptrs) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_recovery_acks_verify(CTX, &fault_index, hostpubkeys33, n, t, recovery, recovery_len, NULL) == SECP256K1_CHILLDKG_INVALID_INPUT));
}

static void chilldkg_investigate_test(void) {
    const size_t n = 3;
    const uint32_t t = 2;
    const size_t pmsg1_len = 33 * 2 + 32 * 3 + 97; /* 259 */
    const size_t cmsg1_len = 162 * 3 + 33 * 1; /* 519 */
    const size_t cinv_len = 65 * 3; /* 195 */
    const uint32_t dealer = 1;
    const uint32_t victim = 2;
    secp256k1_chilldkg_participant_state1 state1;
    secp256k1_chilldkg_participant_state2 state2;
    secp256k1_chilldkg_participant_inv_data inv_data;
    secp256k1_chilldkg_coordinator_state coord_state;
    unsigned char pmsg1[3][259];
    const unsigned char *pmsg1_ptrs[3];
    unsigned char cmsg1[519];
    unsigned char cinv[195];
    unsigned char cinv_bad[195];
    unsigned char hostpubkeys33[3 * 33];
    unsigned char sig64[64];
    secp256k1_chilldkg_fault fault;
    uint32_t fault_index = 0;
    size_t i;

    for (i = 0; i < n; i++) {
        pmsg1_ptrs[i] = pmsg1[i];
        memcpy(hostpubkeys33 + 33 * i, vec5_hostpubkeys[i], 33);
    }
    for (i = 0; i < n; i++) {
        CHECK(secp256k1_chilldkg_participant_step1(CTX, &state1, pmsg1[i], vec5_hostseckeys[i], hostpubkeys33, n, t, vec5_randoms[i]) == 1);
        CHECK(secp256k1_memcmp_var(pmsg1[i], vec5_pmsgs1[i], pmsg1_len) == 0);
    }

    /* Scenario 1: dealer 1 sent a corrupted encrypted share to participant
     * 2. */
    memcpy(pmsg1[dealer], vec5_inv_pmsg1_bad, pmsg1_len);
    fault = secp256k1_chilldkg_coordinator_step1(CTX, &coord_state, cmsg1, &fault_index, pmsg1_ptrs, hostpubkeys33, n, t);
    CHECK(fault == SECP256K1_CHILLDKG_OK);
    CHECK(secp256k1_memcmp_var(cmsg1, vec5_inv_cmsg1, cmsg1_len) == 0);

    /* The victim's step2 fails with UNKNOWN and fills the inv data. */
    CHECK(secp256k1_chilldkg_participant_step1(CTX, &state1, pmsg1[victim], vec5_hostseckeys[victim], hostpubkeys33, n, t, vec5_randoms[victim]) == 1);
    fault = secp256k1_chilldkg_participant_step2(CTX, &state2, sig64, &fault_index, &inv_data, &state1, vec5_hostseckeys[victim], cmsg1, vec5_aux_rands[victim]);
    CHECK(fault == SECP256K1_CHILLDKG_UNKNOWN_FAULTY_PARTICIPANT_OR_COORDINATOR);
    CHECK(fault_index == UINT32_MAX);
    CHECK(secp256k1_is_zero_array(sig64, 64));
    /* The inv data is byte-exact against the reference's
     * ParticipantInvestigationData (layout: magic || n || participant_id ||
     * secshare || pubshare || enc_secshare || pads). */
    CHECK(secp256k1_read_be32(&inv_data.data[4]) == n);
    CHECK(secp256k1_read_be32(&inv_data.data[8]) == victim);
    CHECK(secp256k1_memcmp_var(&inv_data.data[12], vec5_inv_secshare, 32) == 0);
    CHECK(secp256k1_memcmp_var(&inv_data.data[44], vec5_inv_pubshare, 33) == 0);
    CHECK(secp256k1_memcmp_var(&inv_data.data[77], vec5_inv_enc_secshare, 32) == 0);
    for (i = 0; i < n; i++) {
        CHECK(secp256k1_memcmp_var(&inv_data.data[109 + 32 * i], vec5_inv_pads[i], 32) == 0);
    }

    /* The coordinator's investigation message is byte-exact. */
    fault = secp256k1_chilldkg_coordinator_investigate(CTX, cinv, &fault_index, pmsg1_ptrs, hostpubkeys33, n, t, victim);
    CHECK(fault == SECP256K1_CHILLDKG_OK);
    CHECK(secp256k1_memcmp_var(cinv, vec5_inv_cinv, cinv_len) == 0);

    /* The investigation blames the dealer. */
    fault_index = 0;
    fault = secp256k1_chilldkg_participant_investigate(CTX, &fault_index, &inv_data, cinv);
    CHECK(fault == SECP256K1_CHILLDKG_FAULTY_PARTICIPANT_OR_COORDINATOR);
    CHECK(fault_index == dealer);

    /* A malformed investigation message (invalid point encoding, wrong
     * scalar) blames the coordinator. */
    memcpy(cinv_bad, cinv, cinv_len);
    cinv_bad[32 * n] = 0x07; /* invalid prefix of the first partial pubshare */
    fault = secp256k1_chilldkg_participant_investigate(CTX, &fault_index, &inv_data, cinv_bad);
    CHECK(fault == SECP256K1_CHILLDKG_FAULTY_COORDINATOR);
    memcpy(cinv_bad, cinv, cinv_len);
    memset(cinv_bad, 0xff, 32); /* overflowing first encrypted partial share */
    fault = secp256k1_chilldkg_participant_investigate(CTX, &fault_index, &inv_data, cinv_bad);
    CHECK(fault == SECP256K1_CHILLDKG_FAULTY_COORDINATOR);

    /* Scenario 2: the coordinator tampered with the encrypted secshare of
     * participant 2 in cmsg1. */
    for (i = 0; i < n; i++) {
        memcpy(pmsg1[i], vec5_pmsgs1[i], pmsg1_len);
    }
    memcpy(cmsg1, vec5_inv_cmsg1_coord_bad, cmsg1_len);
    CHECK(secp256k1_chilldkg_participant_step1(CTX, &state1, pmsg1[victim], vec5_hostseckeys[victim], hostpubkeys33, n, t, vec5_randoms[victim]) == 1);
    fault = secp256k1_chilldkg_participant_step2(CTX, &state2, sig64, &fault_index, &inv_data, &state1, vec5_hostseckeys[victim], cmsg1, vec5_aux_rands[victim]);
    CHECK(fault == SECP256K1_CHILLDKG_UNKNOWN_FAULTY_PARTICIPANT_OR_COORDINATOR);
    fault = secp256k1_chilldkg_coordinator_investigate(CTX, cinv, &fault_index, pmsg1_ptrs, hostpubkeys33, n, t, victim);
    CHECK(fault == SECP256K1_CHILLDKG_OK);
    fault_index = 0;
    fault = secp256k1_chilldkg_participant_investigate(CTX, &fault_index, &inv_data, cinv);
    CHECK(fault == SECP256K1_CHILLDKG_FAULTY_COORDINATOR);
    CHECK(fault_index == UINT32_MAX);

    /* coordinator_investigate: a malformed pmsg1 blames its sender; an
     * out-of-range participant id is an input error. */
    {
        unsigned char pmsg1_bad[259];
        const unsigned char *bad_ptrs[3];
        bad_ptrs[0] = pmsg1[0];
        bad_ptrs[1] = pmsg1_bad;
        bad_ptrs[2] = pmsg1[2];
        memcpy(pmsg1_bad, pmsg1[1], pmsg1_len);
        memset(pmsg1_bad + 33 * 2 + 97, 0xff, 32); /* overflowing share for participant 0 */
        fault_index = 0;
        fault = secp256k1_chilldkg_coordinator_investigate(CTX, cinv, &fault_index, bad_ptrs, hostpubkeys33, n, t, victim);
        CHECK(fault == SECP256K1_CHILLDKG_FAULTY_PARTICIPANT);
        CHECK(fault_index == 1);
        fault = secp256k1_chilldkg_coordinator_investigate(CTX, cinv, &fault_index, pmsg1_ptrs, hostpubkeys33, n, t, (uint32_t)n);
        CHECK(fault == SECP256K1_CHILLDKG_INVALID_INPUT);
        CHECK(secp256k1_is_zero_array(cinv, cinv_len));
    }

    /* A zeroed (or corrupted) inv_data object is rejected. */
    {
        secp256k1_chilldkg_participant_inv_data bad_inv_data;
        memset(&bad_inv_data, 0, sizeof(bad_inv_data));
        CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_investigate(CTX, &fault_index, &bad_inv_data, cinv) == SECP256K1_CHILLDKG_INVALID_INPUT));
    }

    /* API misuse. */
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_coordinator_investigate(CTX, NULL, &fault_index, pmsg1_ptrs, hostpubkeys33, n, t, victim) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_coordinator_investigate(CTX, cinv, NULL, pmsg1_ptrs, hostpubkeys33, n, t, victim) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_coordinator_investigate(CTX, cinv, &fault_index, NULL, hostpubkeys33, n, t, victim) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_coordinator_investigate(CTX, cinv, &fault_index, pmsg1_ptrs, NULL, n, t, victim) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_investigate(CTX, NULL, &inv_data, cinv) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_investigate(CTX, &fault_index, NULL, cinv) == SECP256K1_CHILLDKG_INVALID_INPUT));
    CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_investigate(CTX, &fault_index, &inv_data, NULL) == SECP256K1_CHILLDKG_INVALID_INPUT));
}

/* Vector runners for the upstream bip-frost-dkg test vectors (see
 * vectors.h, generated by tools/test_vectors_chilldkg_generate.py). */

static void chilldkg_vec_hostpubkey_gen_run(void) {
    unsigned char out33[33];
    size_t i;

    for (i = 0; i < sizeof(chilldkg_vec_hostpubkey_gen_cases) / sizeof(*chilldkg_vec_hostpubkey_gen_cases); i++) {
        const struct chilldkg_vec_hostpubkey_gen_case *c = &chilldkg_vec_hostpubkey_gen_cases[i];
        int ret = secp256k1_chilldkg_hostpubkey_gen(CTX, out33, c->hostseckey);
        CHECK(ret == c->is_valid);
        if (c->is_valid) {
            CHECK(secp256k1_memcmp_var(out33, c->expected_hostpubkey, 33) == 0);
        }
    }
}

static void chilldkg_vec_params_hash_run(void) {
    unsigned char out32[32];
    size_t i;

    for (i = 0; i < sizeof(chilldkg_vec_params_hash_cases) / sizeof(*chilldkg_vec_params_hash_cases); i++) {
        const struct chilldkg_vec_params_hash_case *c = &chilldkg_vec_params_hash_cases[i];
        int ret = secp256k1_chilldkg_params_hash(CTX, out32, &c->params.hostpubkeys[0][0], c->params.n, c->params.t);
        CHECK(ret == c->is_valid);
        if (c->is_valid) {
            CHECK(secp256k1_memcmp_var(out32, c->expected_hash, 32) == 0);
        }
    }
}

static void chilldkg_vec_participant_step1_run(void) {
    secp256k1_chilldkg_participant_state1 state1;
    unsigned char pmsg1[CHILLDKG_VEC_MAX_PMSG1_LEN];
    size_t i;

    for (i = 0; i < sizeof(chilldkg_vec_step1_cases) / sizeof(*chilldkg_vec_step1_cases); i++) {
        const struct chilldkg_vec_step1_case *c = &chilldkg_vec_step1_cases[i];
        size_t pmsg1_len = secp256k1_chilldkg_participant_msg1_len(c->params.n, c->params.t);
        int ret = secp256k1_chilldkg_participant_step1(CTX, &state1, pmsg1, c->hostseckey, &c->params.hostpubkeys[0][0], c->params.n, c->params.t, c->random);
        CHECK(ret == c->is_valid);
        if (c->is_valid) {
            CHECK(pmsg1_len > 0);
            CHECK(secp256k1_memcmp_var(pmsg1, c->expected_pmsg1, pmsg1_len) == 0);
        }
    }
}

static void chilldkg_vec_participant_step2_run(void) {
    secp256k1_chilldkg_participant_state1 state1;
    secp256k1_chilldkg_participant_state2 state2;
    secp256k1_chilldkg_participant_inv_data inv_data;
    unsigned char pmsg1[CHILLDKG_VEC_MAX_PMSG1_LEN];
    unsigned char sig64[64];
    uint32_t fault_index;
    secp256k1_chilldkg_fault fault;
    size_t gi, ci, j;

    ci = 0;
    for (gi = 0; gi < sizeof(chilldkg_vec_step2_groups) / sizeof(*chilldkg_vec_step2_groups); gi++) {
        const struct chilldkg_vec_step2_group *g = &chilldkg_vec_step2_groups[gi];
        size_t pmsg1_len = secp256k1_chilldkg_participant_msg1_len(g->params.n, g->params.t);
        CHECK(secp256k1_chilldkg_participant_step1(CTX, &state1, pmsg1, g->hostseckey, &g->params.hostpubkeys[0][0], g->params.n, g->params.t, g->random) == 1);
        /* Checkpoint: the re-derived pmsg1 matches. */
        CHECK(secp256k1_memcmp_var(pmsg1, g->pmsg1, pmsg1_len) == 0);
        for (j = 0; j < chilldkg_vec_step2_group_case_counts[gi]; j++, ci++) {
            const struct chilldkg_vec_step2_case *c = &chilldkg_vec_step2_cases[ci];
            const unsigned char *hostseckey = c->has_hostseckey ? c->hostseckey : g->hostseckey;
            fault = secp256k1_chilldkg_participant_step2(CTX, &state2, sig64, &fault_index, &inv_data, &state1, hostseckey, c->cmsg1, g->aux_rand);
            CHECK((int)fault == c->expected_error);
            CHECK(fault_index == c->expected_fault_index);
            if (c->is_valid) {
                CHECK(secp256k1_memcmp_var(sig64, c->expected_pmsg2, 64) == 0);
            }
        }
    }
    CHECK(ci == sizeof(chilldkg_vec_step2_cases) / sizeof(*chilldkg_vec_step2_cases));
}

static void chilldkg_vec_participant_finalize_run(void) {
    secp256k1_chilldkg_participant_state1 state1;
    secp256k1_chilldkg_participant_state2 state2;
    unsigned char pmsg1[CHILLDKG_VEC_MAX_PMSG1_LEN];
    unsigned char sig64[64];
    unsigned char secshare32[32];
    unsigned char thresh_pk33[33];
    unsigned char pubshares33[33 * CHILLDKG_VEC_MAX_PARTICIPANTS];
    unsigned char recovery[CHILLDKG_VEC_MAX_RECOVERY_LEN];
    uint32_t fault_index;
    secp256k1_chilldkg_fault fault;
    size_t gi, ci, j, k;

    ci = 0;
    for (gi = 0; gi < sizeof(chilldkg_vec_finalize_groups) / sizeof(*chilldkg_vec_finalize_groups); gi++) {
        const struct chilldkg_vec_finalize_group *g = &chilldkg_vec_finalize_groups[gi];
        size_t n = g->params.n;
        size_t t = g->params.t;
        /* Checkpoints: re-derive pmsg1 and pmsg2. */
        CHECK(secp256k1_chilldkg_participant_step1(CTX, &state1, pmsg1, g->hostseckey, &g->params.hostpubkeys[0][0], n, t, g->random) == 1);
        CHECK(secp256k1_memcmp_var(pmsg1, g->pmsg1, secp256k1_chilldkg_participant_msg1_len(n, t)) == 0);
        fault = secp256k1_chilldkg_participant_step2(CTX, &state2, sig64, &fault_index, NULL, &state1, g->hostseckey, g->cmsg1, g->aux_rand);
        CHECK(fault == SECP256K1_CHILLDKG_OK);
        CHECK(secp256k1_memcmp_var(sig64, g->pmsg2, 64) == 0);
        for (j = 0; j < chilldkg_vec_finalize_group_case_counts[gi]; j++, ci++) {
            const struct chilldkg_vec_finalize_case *c = &chilldkg_vec_finalize_cases[ci];
            fault = secp256k1_chilldkg_participant_finalize(CTX, secshare32, thresh_pk33, pubshares33, recovery, &fault_index, &state2, c->cmsg2);
            CHECK((int)fault == c->expected_error);
            if (c->is_valid) {
                CHECK(c->expected_output.has_secshare);
                CHECK(secp256k1_memcmp_var(secshare32, c->expected_output.secshare, 32) == 0);
                CHECK(secp256k1_memcmp_var(thresh_pk33, c->expected_output.thresh_pk, 33) == 0);
                for (k = 0; k < n; k++) {
                    CHECK(secp256k1_memcmp_var(pubshares33 + 33 * k, c->expected_output.pubshares[k], 33) == 0);
                }
                CHECK(secp256k1_memcmp_var(recovery, c->expected_recovery, secp256k1_chilldkg_recovery_data_len(n, t)) == 0);
            }
        }
    }
    CHECK(ci == sizeof(chilldkg_vec_finalize_cases) / sizeof(*chilldkg_vec_finalize_cases));
}

static void chilldkg_vec_participant_investigate_run(void) {
    secp256k1_chilldkg_participant_state1 state1;
    secp256k1_chilldkg_participant_state2 state2;
    secp256k1_chilldkg_participant_inv_data inv_data;
    unsigned char pmsg1[CHILLDKG_VEC_MAX_PMSG1_LEN];
    unsigned char sig64[64];
    uint32_t fault_index;
    secp256k1_chilldkg_fault fault;
    size_t gi, ci, j;

    ci = 0;
    for (gi = 0; gi < sizeof(chilldkg_vec_investigate_groups) / sizeof(*chilldkg_vec_investigate_groups); gi++) {
        const struct chilldkg_vec_investigate_group *g = &chilldkg_vec_investigate_groups[gi];
        CHECK(secp256k1_chilldkg_participant_step1(CTX, &state1, pmsg1, g->hostseckey, &g->params.hostpubkeys[0][0], g->params.n, g->params.t, g->random) == 1);
        CHECK(secp256k1_memcmp_var(pmsg1, g->pmsg1, secp256k1_chilldkg_participant_msg1_len(g->params.n, g->params.t)) == 0);
        for (j = 0; j < chilldkg_vec_investigate_group_case_counts[gi]; j++, ci++) {
            const struct chilldkg_vec_investigate_case *c = &chilldkg_vec_investigate_cases[ci];
            /* The tampered cmsg1 must make step2 fail with UNKNOWN. */
            fault = secp256k1_chilldkg_participant_step2(CTX, &state2, sig64, &fault_index, &inv_data, &state1, g->hostseckey, g->cmsg1_pool[c->cmsg1_index], g->aux_rand);
            CHECK(fault == SECP256K1_CHILLDKG_UNKNOWN_FAULTY_PARTICIPANT_OR_COORDINATOR);
            fault = secp256k1_chilldkg_participant_investigate(CTX, &fault_index, &inv_data, c->cinv);
            CHECK((int)fault == c->expected_error);
            CHECK(fault_index == c->expected_fault_index);
        }
    }
    CHECK(ci == sizeof(chilldkg_vec_investigate_cases) / sizeof(*chilldkg_vec_investigate_cases));
}

static void chilldkg_vec_coordinator_step1_run(void) {
    secp256k1_chilldkg_coordinator_state cstate;
    unsigned char cmsg1[CHILLDKG_VEC_MAX_CMSG1_LEN];
    const unsigned char *pmsg1_ptrs[CHILLDKG_VEC_MAX_INDICES];
    uint32_t fault_index;
    secp256k1_chilldkg_fault fault;
    size_t gi, ci, j, k;

    ci = 0;
    for (gi = 0; gi < sizeof(chilldkg_vec_coord_step1_groups) / sizeof(*chilldkg_vec_coord_step1_groups); gi++) {
        const struct chilldkg_vec_coord_step1_group *g = &chilldkg_vec_coord_step1_groups[gi];
        for (j = 0; j < chilldkg_vec_coord_step1_group_case_counts[gi]; j++, ci++) {
            const struct chilldkg_vec_coord_step1_case *c = &chilldkg_vec_coord_step1_cases[ci];
            for (k = 0; k < c->n_pmsgs1; k++) {
                pmsg1_ptrs[k] = g->pmsg1_pool[c->pmsg1_indices[k]];
            }
            fault = secp256k1_chilldkg_coordinator_step1(CTX, &cstate, cmsg1, &fault_index, pmsg1_ptrs, &c->params.hostpubkeys[0][0], c->params.n, c->params.t);
            CHECK((int)fault == c->expected_error);
            CHECK(fault_index == c->expected_fault_index);
            if (c->is_valid) {
                CHECK(secp256k1_memcmp_var(cmsg1, c->expected_cmsg1, secp256k1_chilldkg_coordinator_msg1_len(c->params.n, c->params.t)) == 0);
            }
        }
    }
    CHECK(ci == sizeof(chilldkg_vec_coord_step1_cases) / sizeof(*chilldkg_vec_coord_step1_cases));
}

static void chilldkg_vec_coordinator_finalize_run(void) {
    secp256k1_chilldkg_coordinator_state cstate;
    unsigned char cmsg1[CHILLDKG_VEC_MAX_CMSG1_LEN];
    unsigned char cmsg2[CHILLDKG_VEC_MAX_CMSG2_LEN];
    unsigned char thresh_pk33[33];
    unsigned char pubshares33[33 * CHILLDKG_VEC_MAX_PARTICIPANTS];
    unsigned char recovery[CHILLDKG_VEC_MAX_RECOVERY_LEN];
    const unsigned char *pmsg1_ptrs[CHILLDKG_VEC_MAX_PARTICIPANTS];
    const unsigned char *pmsg2_ptrs[CHILLDKG_VEC_MAX_INDICES];
    uint32_t fault_index;
    secp256k1_chilldkg_fault fault;
    size_t gi, ci, j, k;

    ci = 0;
    for (gi = 0; gi < sizeof(chilldkg_vec_coord_finalize_groups) / sizeof(*chilldkg_vec_coord_finalize_groups); gi++) {
        const struct chilldkg_vec_coord_finalize_group *g = &chilldkg_vec_coord_finalize_groups[gi];
        size_t n = g->params.n;
        size_t t = g->params.t;
        for (k = 0; k < n; k++) {
            pmsg1_ptrs[k] = g->pmsgs1[k];
        }
        fault = secp256k1_chilldkg_coordinator_step1(CTX, &cstate, cmsg1, &fault_index, pmsg1_ptrs, &g->params.hostpubkeys[0][0], n, t);
        CHECK(fault == SECP256K1_CHILLDKG_OK);
        /* Checkpoint: the re-derived cmsg1 matches. */
        CHECK(secp256k1_memcmp_var(cmsg1, g->cmsg1, secp256k1_chilldkg_coordinator_msg1_len(n, t)) == 0);
        for (j = 0; j < chilldkg_vec_coord_finalize_group_case_counts[gi]; j++, ci++) {
            const struct chilldkg_vec_coord_finalize_case *c = &chilldkg_vec_coord_finalize_cases[ci];
            for (k = 0; k < c->n_pmsgs2; k++) {
                pmsg2_ptrs[k] = g->pmsg2_pool[c->pmsg2_indices[k]];
            }
            fault = secp256k1_chilldkg_coordinator_finalize(CTX, cmsg2, thresh_pk33, pubshares33, recovery, &fault_index, &cstate, pmsg2_ptrs);
            CHECK((int)fault == c->expected_error);
            CHECK(fault_index == c->expected_fault_index);
            if (c->is_valid) {
                CHECK(!c->expected_output.has_secshare);
                CHECK(secp256k1_memcmp_var(cmsg2, c->expected_cmsg2, secp256k1_chilldkg_coordinator_msg2_len(n)) == 0);
                CHECK(secp256k1_memcmp_var(thresh_pk33, c->expected_output.thresh_pk, 33) == 0);
                for (k = 0; k < n; k++) {
                    CHECK(secp256k1_memcmp_var(pubshares33 + 33 * k, c->expected_output.pubshares[k], 33) == 0);
                }
                CHECK(secp256k1_memcmp_var(recovery, c->expected_recovery, secp256k1_chilldkg_recovery_data_len(n, t)) == 0);
            }
        }
    }
    CHECK(ci == sizeof(chilldkg_vec_coord_finalize_cases) / sizeof(*chilldkg_vec_coord_finalize_cases));
}

static void chilldkg_vec_coordinator_investigate_run(void) {
    unsigned char cinv[CHILLDKG_VEC_MAX_CINV_LEN];
    const unsigned char *pmsg1_ptrs[CHILLDKG_VEC_MAX_PARTICIPANTS];
    uint32_t fault_index;
    secp256k1_chilldkg_fault fault;
    size_t gi, i, k;

    for (gi = 0; gi < sizeof(chilldkg_vec_coord_investigate_groups) / sizeof(*chilldkg_vec_coord_investigate_groups); gi++) {
        const struct chilldkg_vec_coord_investigate_group *g = &chilldkg_vec_coord_investigate_groups[gi];
        size_t n = g->params.n;
        for (k = 0; k < n; k++) {
            pmsg1_ptrs[k] = g->pmsgs1[k];
        }
        for (i = 0; i < n; i++) {
            fault = secp256k1_chilldkg_coordinator_investigate(CTX, cinv, &fault_index, pmsg1_ptrs, &g->params.hostpubkeys[0][0], n, g->params.t, (uint32_t)i);
            CHECK(fault == SECP256K1_CHILLDKG_OK);
            CHECK(secp256k1_memcmp_var(cinv, g->expected_cinv[i], secp256k1_chilldkg_investigation_msg_len(n)) == 0);
        }
    }
}

static void chilldkg_vec_recover_run(void) {
    unsigned char secshare32[32];
    unsigned char thresh_pk33[33];
    unsigned char pubshares33[33 * CHILLDKG_VEC_MAX_PARTICIPANTS];
    unsigned char hostpubkeys33[33 * CHILLDKG_VEC_MAX_PARTICIPANTS];
    uint32_t fault_index, t_out;
    secp256k1_chilldkg_fault fault;
    size_t n_out;
    size_t ci, k;

    for (ci = 0; ci < sizeof(chilldkg_vec_recover_cases) / sizeof(*chilldkg_vec_recover_cases); ci++) {
        const struct chilldkg_vec_recover_case *c = &chilldkg_vec_recover_cases[ci];
        if (c->has_hostseckey) {
            fault = secp256k1_chilldkg_participant_recover(CTX, secshare32, thresh_pk33, pubshares33, hostpubkeys33, &n_out, &t_out, &fault_index, c->hostseckey, c->recovery, c->recovery_len);
        } else {
            fault = secp256k1_chilldkg_coordinator_recover(CTX, thresh_pk33, pubshares33, hostpubkeys33, &n_out, &t_out, c->recovery, c->recovery_len);
        }
        CHECK((int)fault == c->expected_error);
        if (c->is_valid) {
            CHECK(n_out == c->expected_params.n);
            CHECK(t_out == c->expected_params.t);
            CHECK(secp256k1_memcmp_var(thresh_pk33, c->expected_output.thresh_pk, 33) == 0);
            if (c->expected_output.has_secshare) {
                CHECK(c->has_hostseckey);
                CHECK(secp256k1_memcmp_var(secshare32, c->expected_output.secshare, 32) == 0);
            }
            for (k = 0; k < n_out; k++) {
                CHECK(secp256k1_memcmp_var(pubshares33 + 33 * k, c->expected_output.pubshares[k], 33) == 0);
                CHECK(secp256k1_memcmp_var(hostpubkeys33 + 33 * k, c->expected_params.hostpubkeys[k], 33) == 0);
            }
        }
    }
}

static void chilldkg_vectors_test(void) {
    chilldkg_vec_hostpubkey_gen_run();
    chilldkg_vec_params_hash_run();
    chilldkg_vec_participant_step1_run();
    chilldkg_vec_participant_step2_run();
    chilldkg_vec_participant_finalize_run();
    chilldkg_vec_participant_investigate_run();
    chilldkg_vec_coordinator_step1_run();
    chilldkg_vec_coordinator_finalize_run();
    chilldkg_vec_coordinator_investigate_run();
    chilldkg_vec_recover_run();
}

/* Runs a full ChillDKG session (n participants, threshold t) through the
 * public API and checks consistency: all participants obtain the same
 * threshold public key, public shares and recovery data, and every
 * participant's secret share matches its public share. Static buffers keep
 * the max-participants case off the stack. */
#define CHILLDKG_BND_MAX 128
static secp256k1_chilldkg_participant_state1 bnd_state1[CHILLDKG_BND_MAX];
static secp256k1_chilldkg_participant_state2 bnd_state2[CHILLDKG_BND_MAX];
static unsigned char bnd_pmsg1[CHILLDKG_BND_MAX][33 * CHILLDKG_BND_MAX + 32 * CHILLDKG_BND_MAX + 97];
static unsigned char bnd_hostseckeys[CHILLDKG_BND_MAX][32];
static unsigned char bnd_hostpubkeys[CHILLDKG_BND_MAX * 33];
static unsigned char bnd_pubshares[CHILLDKG_BND_MAX * 33];
static unsigned char bnd_recovery[4 + 33 * CHILLDKG_BND_MAX + 162 * CHILLDKG_BND_MAX];

static void chilldkg_run_full_session(size_t n, uint32_t t) {
    static unsigned char cmsg1[162 * CHILLDKG_BND_MAX + 33 * (CHILLDKG_BND_MAX - 1)];
    static unsigned char cmsg2[64 * CHILLDKG_BND_MAX];
    static unsigned char coord_recovery[4 + 33 * CHILLDKG_BND_MAX + 162 * CHILLDKG_BND_MAX];
    static secp256k1_chilldkg_participant_state1 state1_copy;
    secp256k1_chilldkg_coordinator_state coord_state;
    const unsigned char *pmsg1_ptrs[CHILLDKG_BND_MAX];
    const unsigned char *pmsg2_ptrs[CHILLDKG_BND_MAX];
    unsigned char pmsg2[CHILLDKG_BND_MAX][64];
    unsigned char thresh_pk33[33];
    unsigned char coord_thresh_pk33[33];
    unsigned char secshare32[32];
    unsigned char aux_rand32[32];
    unsigned char random32[32];
    unsigned char buf33[33];
    secp256k1_chilldkg_fault fault;
    secp256k1_pubkey pubkey;
    uint32_t fault_index;
    size_t outputlen;
    size_t i;

    for (i = 0; i < n; i++) {
        memset(bnd_hostseckeys[i], 0, 32);
        secp256k1_write_be32(&bnd_hostseckeys[i][28], (uint32_t)(i + 1));
        pmsg1_ptrs[i] = bnd_pmsg1[i];
        pmsg2_ptrs[i] = pmsg2[i];
        CHECK(secp256k1_chilldkg_hostpubkey_gen(CTX, &bnd_hostpubkeys[33 * i], bnd_hostseckeys[i]) == 1);
    }
    for (i = 0; i < n; i++) {
        memset(random32, (unsigned char)(i + 1), 32);
        CHECK(secp256k1_chilldkg_participant_step1(CTX, &bnd_state1[i], bnd_pmsg1[i], bnd_hostseckeys[i], bnd_hostpubkeys, n, t, random32) == 1);
    }
    fault = secp256k1_chilldkg_coordinator_step1(CTX, &coord_state, cmsg1, &fault_index, pmsg1_ptrs, bnd_hostpubkeys, n, t);
    CHECK(fault == SECP256K1_CHILLDKG_OK);
    for (i = 0; i < n; i++) {
        /* The state objects can be copied (e.g., to persist them): run
         * participant 0's step2 with a copy of its state. */
        const secp256k1_chilldkg_participant_state1 *state1 = &bnd_state1[i];
        if (i == 0) {
            memcpy(&state1_copy, &bnd_state1[i], sizeof(state1_copy));
            state1 = &state1_copy;
        }
        memset(aux_rand32, (unsigned char)(0xA0 + i), 32);
        fault = secp256k1_chilldkg_participant_step2(CTX, &bnd_state2[i], pmsg2[i], &fault_index, NULL, state1, bnd_hostseckeys[i], cmsg1, aux_rand32);
        CHECK(fault == SECP256K1_CHILLDKG_OK);
    }
    fault = secp256k1_chilldkg_coordinator_finalize(CTX, cmsg2, coord_thresh_pk33, bnd_pubshares, coord_recovery, &fault_index, &coord_state, pmsg2_ptrs);
    CHECK(fault == SECP256K1_CHILLDKG_OK);
    for (i = 0; i < n; i++) {
        unsigned char pubshares33[33 * CHILLDKG_BND_MAX];
        fault = secp256k1_chilldkg_participant_finalize(CTX, secshare32, thresh_pk33, pubshares33, bnd_recovery, &fault_index, &bnd_state2[i], cmsg2);
        CHECK(fault == SECP256K1_CHILLDKG_OK);
        /* All participants agree with the coordinator. */
        CHECK(secp256k1_memcmp_var(thresh_pk33, coord_thresh_pk33, 33) == 0);
        CHECK(secp256k1_memcmp_var(pubshares33, bnd_pubshares, 33 * n) == 0);
        CHECK(secp256k1_memcmp_var(bnd_recovery, coord_recovery, secp256k1_chilldkg_recovery_data_len(n, t)) == 0);
        /* The secret share matches the public share. */
        CHECK(secp256k1_ec_pubkey_create(CTX, &pubkey, secshare32) == 1);
        outputlen = 33;
        CHECK(secp256k1_ec_pubkey_serialize(CTX, buf33, &outputlen, &pubkey, SECP256K1_EC_COMPRESSED) == 1);
        CHECK(outputlen == 33);
        CHECK(secp256k1_memcmp_var(buf33, &bnd_pubshares[33 * i], 33) == 0);
    }
    /* The outputs can be recovered from the recovery data. */
    {
        unsigned char rec_secshare32[32];
        unsigned char rec_thresh_pk33[33];
        unsigned char rec_pubshares33[33 * CHILLDKG_BND_MAX];
        unsigned char rec_hostpubkeys33[33 * CHILLDKG_BND_MAX];
        size_t n_out;
        uint32_t t_out;
        fault = secp256k1_chilldkg_participant_recover(CTX, rec_secshare32, rec_thresh_pk33, rec_pubshares33, rec_hostpubkeys33, &n_out, &t_out, &fault_index, bnd_hostseckeys[0], bnd_recovery, secp256k1_chilldkg_recovery_data_len(n, t));
        CHECK(fault == SECP256K1_CHILLDKG_OK);
        CHECK(n_out == n && t_out == t);
        CHECK(secp256k1_memcmp_var(rec_thresh_pk33, coord_thresh_pk33, 33) == 0);
        secp256k1_memclear_explicit(rec_secshare32, 32);
    }
    secp256k1_memclear_explicit(secshare32, 32);
}

static void chilldkg_boundary_test(void) {
    /* Boundary session sizes: n = 2 (minimum useful), t = 1 (constant
     * polynomial), t = n (full threshold), and a smoke test with the maximum
     * number of participants. */
    chilldkg_run_full_session(2, 1);
    chilldkg_run_full_session(2, 2);
    chilldkg_run_full_session(3, 1);
    chilldkg_run_full_session(3, 3);
    chilldkg_run_full_session(CHILLDKG_BND_MAX, 2);
}

#ifdef ENABLE_MODULE_FROST
/* Full pipeline integration test: run a ChillDKG session (n = 3, t = 2) and
 * use the resulting key material in a FROST signing session with the signers
 * 0 and 2. The ChillDKG outputs are already TapTweak'ed; FROST's tweak cache
 * is initialized from the (tweaked) threshold public key without applying
 * further tweaks, so the final signature verifies against the x-only ChillDKG
 * threshold public key. */
static void chilldkg_frost_integration_test(void) {
    const size_t n = 3;
    const uint32_t t = 2;
    const uint32_t ids[2] = { 0, 2 };
    secp256k1_chilldkg_participant_state1 state1[3];
    secp256k1_chilldkg_participant_state2 state2[3];
    secp256k1_chilldkg_coordinator_state coord_state;
    secp256k1_frost_secnonce secnonce[2];
    secp256k1_frost_pubnonce pubnonce[2];
    secp256k1_frost_aggnonce aggnonce;
    secp256k1_frost_session session;
    secp256k1_frost_tweak_cache cache;
    secp256k1_frost_partial_sig partial_sigs[2];
    secp256k1_xonly_pubkey xonly_thresh_pk;
    secp256k1_pubkey thresh_pk;
    secp256k1_pubkey pubshares[3];
    secp256k1_pubkey signer_pubshares[2];
    const secp256k1_frost_pubnonce *pubnonce_ptrs[2];
    const secp256k1_frost_partial_sig *partial_sig_ptrs[2];
    unsigned char hostseckeys[3][32];
    unsigned char hostpubkeys33[3 * 33];
    unsigned char pmsg1[3][33 * 2 + 32 * 3 + 97];
    unsigned char pmsg2[3][64];
    const unsigned char *pmsg1_ptrs[3];
    const unsigned char *pmsg2_ptrs[3];
    unsigned char cmsg1[162 * 3 + 33];
    unsigned char cmsg2[64 * 3];
    unsigned char secshares[3][32];
    unsigned char thresh_pk33[33];
    unsigned char pubshares33[3 * 33];
    unsigned char coord_recovery[4 + 33 * 2 + 162 * 3];
    unsigned char xonly_thresh_pk32[32];
    unsigned char msg32[32] = "this_could_be_the_hash_of_a_msg";
    unsigned char sig64[64];
    secp256k1_chilldkg_fault fault;
    uint32_t fault_index;
    size_t i;

    /* Run a full ChillDKG session. */
    for (i = 0; i < n; i++) {
        memset(hostseckeys[i], 0, 32);
        secp256k1_write_be32(&hostseckeys[i][28], (uint32_t)(i + 7));
        pmsg1_ptrs[i] = pmsg1[i];
        pmsg2_ptrs[i] = pmsg2[i];
        CHECK(secp256k1_chilldkg_hostpubkey_gen(CTX, &hostpubkeys33[33 * i], hostseckeys[i]) == 1);
    }
    for (i = 0; i < n; i++) {
        unsigned char random32[32];
        memset(random32, (unsigned char)(i + 1), 32);
        CHECK(secp256k1_chilldkg_participant_step1(CTX, &state1[i], pmsg1[i], hostseckeys[i], hostpubkeys33, n, t, random32) == 1);
    }
    fault = secp256k1_chilldkg_coordinator_step1(CTX, &coord_state, cmsg1, &fault_index, pmsg1_ptrs, hostpubkeys33, n, t);
    CHECK(fault == SECP256K1_CHILLDKG_OK);
    for (i = 0; i < n; i++) {
        unsigned char aux_rand32[32];
        memset(aux_rand32, (unsigned char)(0xB0 + i), 32);
        fault = secp256k1_chilldkg_participant_step2(CTX, &state2[i], pmsg2[i], &fault_index, NULL, &state1[i], hostseckeys[i], cmsg1, aux_rand32);
        CHECK(fault == SECP256K1_CHILLDKG_OK);
    }
    fault = secp256k1_chilldkg_coordinator_finalize(CTX, cmsg2, thresh_pk33, pubshares33, coord_recovery, &fault_index, &coord_state, pmsg2_ptrs);
    CHECK(fault == SECP256K1_CHILLDKG_OK);
    for (i = 0; i < n; i++) {
        unsigned char recovery[4 + 33 * 2 + 162 * 3];
        fault = secp256k1_chilldkg_participant_finalize(CTX, secshares[i], thresh_pk33, pubshares33, recovery, &fault_index, &state2[i], cmsg2);
        CHECK(fault == SECP256K1_CHILLDKG_OK);
    }

    /* Feed the ChillDKG outputs into the FROST module. ChillDKG participant i
     * (polynomial x-coordinate i + 1) corresponds to FROST participant id i.
     * The ChillDKG threshold public key is already tweaked; the FROST tweak
     * cache is initialized from it without applying further tweaks. */
    CHECK(secp256k1_ec_pubkey_parse(CTX, &thresh_pk, thresh_pk33, 33) == 1);
    for (i = 0; i < n; i++) {
        CHECK(secp256k1_ec_pubkey_parse(CTX, &pubshares[i], &pubshares33[33 * i], 33) == 1);
    }
    CHECK(secp256k1_frost_tweak_cache_init(CTX, &cache, &thresh_pk) == 1);
    CHECK(secp256k1_frost_tweaked_pubkey_get(CTX, &xonly_thresh_pk, &cache) == 1);
    CHECK(secp256k1_xonly_pubkey_serialize(CTX, xonly_thresh_pk32, &xonly_thresh_pk) == 1);
    /* Without further tweaks, FROST's (x-only) threshold public key is the
     * x-only part of the ChillDKG threshold public key. */
    CHECK(secp256k1_memcmp_var(xonly_thresh_pk32, thresh_pk33 + 1, 32) == 0);

    for (i = 0; i < 2; i++) {
        unsigned char session_secrand[32];
        memset(session_secrand, (unsigned char)(0xC0 + i), 32);
        pubnonce_ptrs[i] = &pubnonce[i];
        partial_sig_ptrs[i] = &partial_sigs[i];
        signer_pubshares[i] = pubshares[ids[i]];
        CHECK(secp256k1_frost_nonce_gen(CTX, &secnonce[i], &pubnonce[i], session_secrand, secshares[ids[i]], &signer_pubshares[i], xonly_thresh_pk32, msg32, sizeof(msg32), NULL, 0) == 1);
    }
    CHECK(secp256k1_frost_nonce_agg(CTX, &aggnonce, NULL, pubnonce_ptrs, 2) == 1);
    CHECK(secp256k1_frost_session_init(CTX, &session, &aggnonce, ids, signer_pubshares, 2, n, t, &cache, msg32, sizeof(msg32)) == 1);
    for (i = 0; i < 2; i++) {
        CHECK(secp256k1_frost_sign(CTX, &partial_sigs[i], &secnonce[i], secshares[ids[i]], &session, ids, signer_pubshares, 2, ids[i]) == 1);
        CHECK(secp256k1_frost_partial_sig_verify(CTX, &partial_sigs[i], &pubnonce[i], &signer_pubshares[i], &session, ids, 2, i) == 1);
    }
    CHECK(secp256k1_frost_partial_sig_agg(CTX, sig64, NULL, &session, partial_sig_ptrs, 2) == 1);
    CHECK(secp256k1_schnorrsig_verify(CTX, sig64, msg32, sizeof(msg32), &xonly_thresh_pk) == 1);
}
#endif

/* Regression tests for two review findings the vector suite cannot catch
 * (the Python reference is memory-safe and has no fixed-size arrays, so no
 * vector exercises them):
 * 1. The threshold t in untrusted recovery data was used directly as a loop
 *    bound over the fixed-size sum_coms[SECP256K1_CHILLDKG_MAX_PARTICIPANTS]
 *    array in deserialize_recovery_data: a blob with t = 129 wrote one group
 *    element past the array, t = 30000 wrote ~1.2 MB past it. Reachable from
 *    both participant_recover and coordinator_recover with attacker-supplied
 *    recovery data.
 * 2. The bounds on t/n in the persisted-state loaders were VERIFY_CHECKs,
 *    which are compiled out in noverify builds: a state1 with n altered to
 *    100000 (magic left intact) crashed participant_step2. */
static void chilldkg_input_bounds_test(void) {
    static unsigned char recovery_big[4 + 33 * 30000]; /* 990004 bytes */
    unsigned char secshare32[32];
    unsigned char thresh_pk33[33];
    unsigned char pubshares33[33 * SECP256K1_CHILLDKG_MAX_PARTICIPANTS];
    unsigned char hostpubkeys33[33 * SECP256K1_CHILLDKG_MAX_PARTICIPANTS];
    unsigned char sig64[64] = { 0 };
    unsigned char aux_rand32[32] = { 0 };
    unsigned char cmsg1_dummy[357] = { 0 }; /* cmsg1 size for n = 2, t = 2 */
    unsigned char cmsg2_dummy[64] = { 0 };
    unsigned char cinv_dummy[130] = { 0 }; /* 65 * 2 */
    unsigned char recovery_dummy[556] = { 0 };
    const unsigned char *pmsgs2_dummy[1];
    secp256k1_chilldkg_fault fault;
    size_t n_out;
    uint32_t t_out, fault_index;

    pmsgs2_dummy[0] = sig64;

    /* Out-of-range thresholds in recovery data are rejected as invalid input
     * (RecoveryDataError in the reference), with the outputs zeroed. t = 129
     * is one past SECP256K1_CHILLDKG_MAX_PARTICIPANTS; t = 30000 is the
     * large-overflow case. In both, n computes to 0. */
    memset(recovery_big, 0, sizeof(recovery_big));
    secp256k1_write_be32(recovery_big, 129);
    memset(secshare32, 1, 32);
    memset(thresh_pk33, 1, 33);
    n_out = 77;
    t_out = 77;
    fault = secp256k1_chilldkg_participant_recover(CTX, secshare32, thresh_pk33, pubshares33, hostpubkeys33, &n_out, &t_out, &fault_index, vec5_hostseckeys[0], recovery_big, 4 + 33 * 129);
    CHECK(fault == SECP256K1_CHILLDKG_INVALID_INPUT);
    CHECK(secp256k1_is_zero_array(secshare32, 32));
    CHECK(secp256k1_is_zero_array(thresh_pk33, 33));
    CHECK(n_out == 0 && t_out == 0);
    fault = secp256k1_chilldkg_coordinator_recover(CTX, thresh_pk33, pubshares33, hostpubkeys33, &n_out, &t_out, recovery_big, 4 + 33 * 129);
    CHECK(fault == SECP256K1_CHILLDKG_INVALID_INPUT);

    secp256k1_write_be32(recovery_big, 30000);
    fault = secp256k1_chilldkg_participant_recover(CTX, secshare32, thresh_pk33, pubshares33, hostpubkeys33, &n_out, &t_out, &fault_index, vec5_hostseckeys[0], recovery_big, 4 + 33 * 30000);
    CHECK(fault == SECP256K1_CHILLDKG_INVALID_INPUT);
    fault = secp256k1_chilldkg_coordinator_recover(CTX, thresh_pk33, pubshares33, hostpubkeys33, &n_out, &t_out, recovery_big, 4 + 33 * 30000);
    CHECK(fault == SECP256K1_CHILLDKG_INVALID_INPUT);

    /* t = 0 is invalid as well (the session parameters require 1 <= t). */
    secp256k1_write_be32(recovery_big, 0);
    fault = secp256k1_chilldkg_participant_recover(CTX, secshare32, thresh_pk33, pubshares33, hostpubkeys33, &n_out, &t_out, &fault_index, vec5_hostseckeys[0], recovery_big, 4 + 162 * 3);
    CHECK(fault == SECP256K1_CHILLDKG_INVALID_INPUT);

    /* Tampered persisted state: valid magic, but n = 100000. The loaders
     * reject it in all build modes (the illegal-argument callback fires), the
     * public functions return INVALID_INPUT, and nothing is indexed out of
     * bounds. */
    {
        secp256k1_chilldkg_participant_state1 state1;
        secp256k1_chilldkg_participant_state2 state2;
        secp256k1_chilldkg_coordinator_state cstate;
        secp256k1_chilldkg_participant_inv_data inv_data;

        memset(&state1, 0, sizeof(state1));
        memcpy(state1.data, secp256k1_chilldkg_participant_state1_magic, 4);
        secp256k1_write_be32(state1.data + 4, 1);      /* t */
        secp256k1_write_be32(state1.data + 8, 100000); /* n */
        secp256k1_write_be32(state1.data + 12, 0);     /* participant_id */
        fault_index = 0;
        CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_step2(CTX, &state2, sig64, &fault_index, NULL, &state1, vec5_hostseckeys[0], cmsg1_dummy, aux_rand32) == SECP256K1_CHILLDKG_INVALID_INPUT));
        CHECK(fault_index == UINT32_MAX);

        memset(&state2, 0, sizeof(state2));
        memcpy(state2.data, secp256k1_chilldkg_participant_state2_magic, 4);
        secp256k1_write_be32(state2.data + 4, 1);      /* t */
        secp256k1_write_be32(state2.data + 8, 100000); /* n */
        fault_index = 0;
        CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_finalize(CTX, secshare32, thresh_pk33, pubshares33, recovery_dummy, &fault_index, &state2, cmsg2_dummy) == SECP256K1_CHILLDKG_INVALID_INPUT));

        memset(&cstate, 0, sizeof(cstate));
        memcpy(cstate.data, secp256k1_chilldkg_coordinator_state_magic, 4);
        secp256k1_write_be32(cstate.data + 4, 1);      /* t */
        secp256k1_write_be32(cstate.data + 8, 100000); /* n */
        fault_index = 0;
        CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_coordinator_finalize(CTX, cmsg2_dummy, thresh_pk33, pubshares33, recovery_dummy, &fault_index, &cstate, pmsgs2_dummy) == SECP256K1_CHILLDKG_INVALID_INPUT));

        memset(&inv_data, 0, sizeof(inv_data));
        memcpy(inv_data.data, secp256k1_chilldkg_participant_inv_data_magic, 4);
        secp256k1_write_be32(inv_data.data + 4, 100000); /* n */
        secp256k1_write_be32(inv_data.data + 8, 0);      /* participant_id */
        fault_index = 0;
        CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_chilldkg_participant_investigate(CTX, &fault_index, &inv_data, cinv_dummy) == SECP256K1_CHILLDKG_INVALID_INPUT));
        CHECK(fault_index == UINT32_MAX);
    }
}

static const struct tf_test_entry tests_chilldkg[] = {
    CASE1(chilldkg_tagged_hashes_test),
    CASE1(chilldkg_params_hash_test),
    CASE1(chilldkg_point_serialization_test),
    CASE1(chilldkg_scalar_parse_test),
    CASE1(chilldkg_schnorrsig_test),
    CASE1(chilldkg_ecdh_pad_test),
    CASE1(chilldkg_vss_test),
    CASE1(chilldkg_simplpedpop_test),
    CASE1(chilldkg_encpedpop_test),
    CASE1(chilldkg_participant_api_test),
    CASE1(chilldkg_coordinator_api_test),
    CASE1(chilldkg_recovery_test),
    CASE1(chilldkg_investigate_test),
    CASE1(chilldkg_vectors_test),
    CASE1(chilldkg_boundary_test),
    CASE1(chilldkg_input_bounds_test),
#ifdef ENABLE_MODULE_FROST
    CASE1(chilldkg_frost_integration_test),
#endif
};

#endif
