#ifndef SECP256K1_CHILLDKG_H #define SECP256K1_CHILLDKG_H #include "secp256k1.h" #include "secp256k1_extrakeys.h" #ifdef __cplusplus extern "C" { #endif #include #include /** This module implements ChillDKG, a distributed key generation (DKG) * protocol for FROST, as specified by the bip-frost-dkg BIP draft * (https://github.com/BlockstreamResearch/bip-frost-dkg, version 0.3.0-dev). * * This code is currently a work in progress. It's not secure nor stable. * IT IS EXTREMELY DANGEROUS AND RECKLESS TO USE THIS MODULE IN PRODUCTION! * * Moreover, the bip-frost-dkg BIP is still a draft: tagged hashes, wire * formats, and protocol details may change in future BIP versions. There is * no guarantee that this implementation will remain compatible with the * final specification. * * The output of a ChillDKG session (a secret share, the threshold public * key, and the public shares of all participants) is designed to be used * directly with the FROST signing module (see include/secp256k1_frost.h). * * A DKG session involves n participants (identified by uint32 identifiers * 0..n-1) and an untrusted coordinator. The number of participants n must * not exceed SECP256K1_CHILLDKG_MAX_PARTICIPANTS. The message flow is: * 1. Every participant runs secp256k1_chilldkg_participant_step1 and sends * the resulting pmsg1 to the coordinator. * 2. The coordinator runs secp256k1_chilldkg_coordinator_step1 on all * pmsg1s and broadcasts the resulting cmsg1 to all participants. * 3. Every participant runs secp256k1_chilldkg_participant_step2 and sends * the resulting signature (pmsg2) to the coordinator. * 4. The coordinator runs secp256k1_chilldkg_coordinator_finalize on all * pmsg2s and broadcasts the resulting certificate (cmsg2) to all * participants. * 5. Every participant runs secp256k1_chilldkg_participant_finalize to * obtain the DKG output and the recovery data. * * It is recommended to read the documentation in this include file carefully. * Further notes on API usage can be found in src/modules/chilldkg/chilldkg.md. */ /** The maximum number of participants n in a ChillDKG session. The state * objects of this module are fixed-size and do not use dynamic allocation, * so a compile-time cap is required. This matches the FROST module's * SECP256K1_FROST_MAX_PARTICIPANTS. */ #define SECP256K1_CHILLDKG_MAX_PARTICIPANTS 128 /** Fault report of the ChillDKG protocol functions, mapping the exception * taxonomy of the reference implementation. * * For SECP256K1_CHILLDKG_FAULTY_PARTICIPANT and * SECP256K1_CHILLDKG_FAULTY_PARTICIPANT_OR_COORDINATOR, the fault_index * output of the failing function is set to the identifier of the (suspected) * faulty participant. For the other fault codes, fault_index is set to * UINT32_MAX, except where documented otherwise. */ typedef enum { /** No fault; the step succeeded. */ SECP256K1_CHILLDKG_OK = 0, /** The coordinator is faulty. */ SECP256K1_CHILLDKG_FAULTY_COORDINATOR = 1, /** The participant with the given fault_index is faulty. */ SECP256K1_CHILLDKG_FAULTY_PARTICIPANT = 2, /** The participant with the given fault_index or the coordinator is * faulty. */ SECP256K1_CHILLDKG_FAULTY_PARTICIPANT_OR_COORDINATOR = 3, /** Some unknown participant or the coordinator is faulty; the * investigation procedure of the protocol is necessary to determine a * suspected participant. */ SECP256K1_CHILLDKG_UNKNOWN_FAULTY_PARTICIPANT_OR_COORDINATOR = 4, /** The caller provided invalid input (e.g., an invalid host secret key or * invalid session parameters). */ SECP256K1_CHILLDKG_INVALID_INPUT = 5 } secp256k1_chilldkg_fault; /** Opaque data structures * * The exact representation of data inside the opaque data structures is * implementation defined and not guaranteed to be portable between different * platforms or versions. The data structures can be safely copied/moved. */ /** Opaque data structure that holds a participant's session state after * secp256k1_chilldkg_participant_step1. * * The state does not contain secret key material (the secret shares it * relates to are encrypted in pmsg1), but it must not be reused: it must be * passed only to a single secp256k1_chilldkg_participant_step2 call. * * Guaranteed to be 4306 bytes in size. */ typedef struct secp256k1_chilldkg_participant_state1 { unsigned char data[4 + 12 + 33 + 33 + 33 * SECP256K1_CHILLDKG_MAX_PARTICIPANTS]; } secp256k1_chilldkg_participant_state1; /** Opaque data structure that holds a participant's session state after * secp256k1_chilldkg_participant_step2. * * This structure contains the participant's secret share; it MUST be kept * secret and MUST NOT be copied. It must not be reused: it must be passed * only to a single secp256k1_chilldkg_participant_finalize call. * * Guaranteed to be 21073 bytes in size. */ typedef struct secp256k1_chilldkg_participant_state2 { unsigned char data[12 + 4 + 131 * SECP256K1_CHILLDKG_MAX_PARTICIPANTS + 32 + 33 + 33 * SECP256K1_CHILLDKG_MAX_PARTICIPANTS]; } secp256k1_chilldkg_participant_state2; /** Opaque data structure that holds the investigation data output by * secp256k1_chilldkg_participant_step2 when it returns * SECP256K1_CHILLDKG_UNKNOWN_FAULTY_PARTICIPANT_OR_COORDINATOR, to be passed * to secp256k1_chilldkg_participant_investigate together with the * coordinator's investigation message. * * This structure contains secret data (the untweaked secret share and the * decryption pads); it MUST be kept secret. * * Guaranteed to be 4205 bytes in size. */ typedef struct secp256k1_chilldkg_participant_inv_data { unsigned char data[12 + 32 + 33 + 32 + 32 * SECP256K1_CHILLDKG_MAX_PARTICIPANTS]; } secp256k1_chilldkg_participant_inv_data; /** Opaque data structure that holds the coordinator's session state after * secp256k1_chilldkg_coordinator_step1, to be passed to * secp256k1_chilldkg_coordinator_finalize (it must not be reused). * * This structure contains no secret key material; it can be copied freely * (e.g., to persist it between the two coordinator steps). * * Guaranteed to be 21041 bytes in size. */ typedef struct secp256k1_chilldkg_coordinator_state { unsigned char data[12 + 4 + 131 * SECP256K1_CHILLDKG_MAX_PARTICIPANTS + 33 + 33 * SECP256K1_CHILLDKG_MAX_PARTICIPANTS]; } secp256k1_chilldkg_coordinator_state; /** Compute the participant's host public key from the host secret key. * * The host public key is the long-term cryptographic identity of the * participant. This function interprets hostseckey32 as a big-endian integer * and computes the corresponding "plain" public key in compressed * serialization (33 bytes, starting with 0x02 or 0x03), equivalent to * IndividualPubkey as defined in BIP 327. * * Returns: 1 on success, 0 if the host secret key is invalid (zero or not * less than the group order). On failure, hostpubkey33 is set to * zero. * Args: ctx: pointer to a context object * Out: hostpubkey33: pointer to a 33-byte array to store the host public key * In: hostseckey32: pointer to the 32-byte host secret key */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_chilldkg_hostpubkey_gen( const secp256k1_context *ctx, unsigned char *hostpubkey33, const unsigned char *hostseckey32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Return a hash of the session parameters for out-of-band comparison. * * If all participants have obtained an identical parameters hash (as can be * verified out of band), then they all agree on all host public keys and the * threshold t. * * Returns: 1 on success, 0 if the session parameters are invalid (not * 1 <= t <= n <= SECP256K1_CHILLDKG_MAX_PARTICIPANTS, an invalid * host public key, or a duplicate host public key). On failure, * hash32 is set to zero. * Args: ctx: pointer to a context object * Out: hash32: pointer to a 32-byte array to store the parameters * hash * In: hostpubkeys33: pointer to an array of n_participants host public * keys (33 bytes each, compressed serialization) * n_participants: total number of participants n * threshold: threshold t */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_chilldkg_params_hash( const secp256k1_context *ctx, unsigned char *hash32, const unsigned char *hostpubkeys33, size_t n_participants, uint32_t threshold ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Length of a participant's first message (pmsg1): 33*t + 32*n + 97 bytes. * Returns 0 if the parameters are out of range. */ SECP256K1_API size_t secp256k1_chilldkg_participant_msg1_len( size_t n_participants, uint32_t threshold ); /** Length of the coordinator's first message (cmsg1): 162*n + 33*(t-1) bytes. * Returns 0 if the parameters are out of range. */ SECP256K1_API size_t secp256k1_chilldkg_coordinator_msg1_len( size_t n_participants, uint32_t threshold ); /** Length of a participant's second message (pmsg2): 64 bytes. */ SECP256K1_API size_t secp256k1_chilldkg_participant_msg2_len(void); /** Length of the coordinator's second message (cmsg2, the certificate): * 64*n bytes. Returns 0 if the parameters are out of range. */ SECP256K1_API size_t secp256k1_chilldkg_coordinator_msg2_len( size_t n_participants ); /** Length of the recovery data output by * secp256k1_chilldkg_participant_finalize: 4 + 33*t + 162*n bytes. * Returns 0 if the parameters are out of range. */ SECP256K1_API size_t secp256k1_chilldkg_recovery_data_len( size_t n_participants, uint32_t threshold ); /** Perform a participant's first step of a ChillDKG session. * * Returns: 1 on success, 0 on invalid input (invalid host secret key, host * secret key not matching any host public key, invalid session * parameters, or all-zero randomness). On failure, pmsg1 and the * state are set to zero. * Args: ctx: pointer to a context object * Out: state1: pointer to a state1 object to be passed to * secp256k1_chilldkg_participant_step2 (must not be * reused) * pmsg1: pointer to a 33*t + 32*n + 97 byte array (see * secp256k1_chilldkg_participant_msg1_len) to store * the message to be sent to the coordinator * In: hostseckey32: pointer to the 32-byte host secret key * hostpubkeys33: pointer to an array of n host public keys (33 bytes * each); all participants must agree on the order * n_participants: total number of participants n * threshold: threshold t * random32: pointer to 32 bytes of FRESH randomness */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_chilldkg_participant_step1( const secp256k1_context *ctx, secp256k1_chilldkg_participant_state1 *state1, unsigned char *pmsg1, const unsigned char *hostseckey32, const unsigned char *hostpubkeys33, size_t n_participants, uint32_t threshold, const unsigned char *random32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(8); /** Perform a participant's second step of a ChillDKG session. * * Verifies the coordinator's first message, computes the DKG output, and * produces the CertEq signature over the session transcript. * * **Warning:** After sending the produced signature to the coordinator, the * caller **must not** erase the hostseckey, even if the coordinator reply * needed for secp256k1_chilldkg_participant_finalize is not received (some * other participant may deem the session successful and use the resulting * threshold public key). * * Returns: SECP256K1_CHILLDKG_OK on success, otherwise a fault code: * SECP256K1_CHILLDKG_INVALID_INPUT if the host secret key is * invalid or does not match the one used in step 1; * SECP256K1_CHILLDKG_FAULTY_COORDINATOR, * SECP256K1_CHILLDKG_FAULTY_PARTICIPANT_OR_COORDINATOR, or * SECP256K1_CHILLDKG_UNKNOWN_FAULTY_PARTICIPANT_OR_COORDINATOR on * protocol faults. On failure, sig64 and the state are set to zero. * Args: ctx: pointer to a context object * Out: state2: pointer to a state2 object to be passed to * secp256k1_chilldkg_participant_finalize (must not be * reused) * sig64: pointer to a 64-byte array to store the CertEq * signature (pmsg2) to be sent to the coordinator * fault_index: pointer to a uint32 that receives the identifier of * the (suspected) faulty participant where applicable, * and UINT32_MAX otherwise * inv_data: pointer to a participant_inv_data object that * receives the investigation data if (and only if) the * return value is * SECP256K1_CHILLDKG_UNKNOWN_FAULTY_PARTICIPANT_OR_COORDINATOR, * or NULL if the caller does not intend to run * secp256k1_chilldkg_participant_investigate * In: state1: pointer to the state1 object output by * secp256k1_chilldkg_participant_step1 * hostseckey32: pointer to the 32-byte host secret key (must be the * same as in step 1) * cmsg1: pointer to the coordinator's first message * (162*n + 33*(t-1) bytes, see * secp256k1_chilldkg_coordinator_msg1_len) * aux_rand32: pointer to 32 bytes of auxiliary randomness for the * CertEq signature (see BIP 340) */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT secp256k1_chilldkg_fault secp256k1_chilldkg_participant_step2( const secp256k1_context *ctx, secp256k1_chilldkg_participant_state2 *state2, unsigned char *sig64, uint32_t *fault_index, secp256k1_chilldkg_participant_inv_data *inv_data, const secp256k1_chilldkg_participant_state1 *state1, const unsigned char *hostseckey32, const unsigned char *cmsg1, const unsigned char *aux_rand32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(8) SECP256K1_ARG_NONNULL(9); /** Perform a participant's final step of a ChillDKG session. * * Re-verifies all n CertEq signatures of the certificate and outputs the * DKG output and the recovery data. If this function returns * SECP256K1_CHILLDKG_OK, this participant deems the DKG session successful. * * Returns: SECP256K1_CHILLDKG_OK on success, * SECP256K1_CHILLDKG_FAULTY_COORDINATOR if the certificate contains * an invalid signature. As diagnostic information (deviating from * the reference implementation, which does not report it), * fault_index receives the index of the first invalid signature in * the latter case. On failure, all outputs are set to zero. * Args: ctx: pointer to a context object * Out: secshare32: pointer to a 32-byte array to store the (tweaked) * secret share * thresh_pk33: pointer to a 33-byte array to store the threshold * public key (compressed serialization) * pubshares33: pointer to an array of n 33-byte elements to store * the public shares of all participants * recovery: pointer to a 4 + 33*t + 162*n byte array (see * secp256k1_chilldkg_recovery_data_len) to store the * recovery data * fault_index: pointer to a uint32 (see above) * In: state2: pointer to the state2 object output by * secp256k1_chilldkg_participant_step2 * cmsg2: pointer to the coordinator's second message (the * certificate, 64*n bytes) */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT secp256k1_chilldkg_fault secp256k1_chilldkg_participant_finalize( const secp256k1_context *ctx, unsigned char *secshare32, unsigned char *thresh_pk33, unsigned char *pubshares33, unsigned char *recovery, uint32_t *fault_index, const secp256k1_chilldkg_participant_state2 *state2, const unsigned char *cmsg2 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(8); /** Perform the coordinator's first step of a ChillDKG session. * * Parses all n participant messages and aggregates them into the message to * broadcast to all participants. The proofs of possession contained in the * pmsg1s are NOT verified here; the participants verify them in step 2 (this * mirrors the reference implementation). * * Returns: SECP256K1_CHILLDKG_OK on success, * SECP256K1_CHILLDKG_INVALID_INPUT on invalid session parameters, * or SECP256K1_CHILLDKG_FAULTY_PARTICIPANT (with fault_index set to * the sender) if a participant message is malformed (invalid * commitment encoding, or an encrypted share that overflows the * group order). On failure, cmsg1 and the state are set to zero. * Args: ctx: pointer to a context object * Out: state: pointer to a coordinator_state object to be passed * to secp256k1_chilldkg_coordinator_finalize (must not * be reused) * cmsg1: pointer to a 162*n + 33*(t-1) byte array (see * secp256k1_chilldkg_coordinator_msg1_len) to store * the message to be broadcast to all participants * fault_index: pointer to a uint32 that receives the identifier of * the faulty participant where applicable, and * UINT32_MAX otherwise * In: pmsgs1: array of n pointers to the participants' first * messages (33*t + 32*n + 97 bytes each) * hostpubkeys33: pointer to an array of n host public keys (33 bytes * each); must be identical (in content and order) to * the arrays used by the participants * n_participants: total number of participants n * threshold: threshold t */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT secp256k1_chilldkg_fault secp256k1_chilldkg_coordinator_step1( const secp256k1_context *ctx, secp256k1_chilldkg_coordinator_state *state, unsigned char *cmsg1, uint32_t *fault_index, const unsigned char *const *pmsgs1, const unsigned char *hostpubkeys33, size_t n_participants, uint32_t threshold ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6); /** Perform the coordinator's final step of a ChillDKG session. * * Collects the n CertEq signatures into the certificate and verifies all of * them. If this function returns SECP256K1_CHILLDKG_OK, the coordinator * deems the DKG session successful. * * Returns: SECP256K1_CHILLDKG_OK on success, or * SECP256K1_CHILLDKG_FAULTY_PARTICIPANT (with fault_index set to * the signer) if a CertEq signature is invalid. On failure, all * outputs are set to zero. * Args: ctx: pointer to a context object * Out: cmsg2: pointer to a 64*n byte array to store the * certificate, to be broadcast to all participants * thresh_pk33: pointer to a 33-byte array to store the threshold * public key (compressed serialization) * pubshares33: pointer to an array of n 33-byte elements to store * the public shares of all participants * recovery: pointer to a 4 + 33*t + 162*n byte array (see * secp256k1_chilldkg_recovery_data_len) to store the * recovery data * fault_index: pointer to a uint32 (see above) * In: state: pointer to the coordinator_state object output by * secp256k1_chilldkg_coordinator_step1 * pmsgs2: array of n pointers to the participants' second * messages (64 bytes each) */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT secp256k1_chilldkg_fault secp256k1_chilldkg_coordinator_finalize( const secp256k1_context *ctx, unsigned char *cmsg2, unsigned char *thresh_pk33, unsigned char *pubshares33, unsigned char *recovery, uint32_t *fault_index, const secp256k1_chilldkg_coordinator_state *state, const unsigned char *const *pmsgs2 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(8); /** Length of a coordinator investigation message (cinv): 65*n bytes (n * encrypted partial secret shares of 32 bytes each, followed by n partial * public shares of 33 bytes each). Returns 0 if n is out of range. */ SECP256K1_API size_t secp256k1_chilldkg_investigation_msg_len( size_t n_participants ); /** Recover the DKG output of a participant from recovery data. * * This function serves two purposes: recovering from a failure of * secp256k1_chilldkg_participant_finalize after obtaining the recovery data * from another participant or the coordinator, and reproducing the DKG * outputs on a new device (e.g., after data loss). * * The recovery data (see secp256k1_chilldkg_recovery_data_len) is * self-delimiting: the number of participants n and the threshold t are * derived from its length and contents. * * Returns: SECP256K1_CHILLDKG_OK on success, * SECP256K1_CHILLDKG_INVALID_INPUT if the recovery data is invalid * (this includes an invalid certificate) or if the host secret key * is invalid or does not match any host public key in the recovery * data (RecoveryDataError and HostSeckeyError in the reference * implementation), or * SECP256K1_CHILLDKG_FAULTY_PARTICIPANT_OR_COORDINATOR (with * fault_index set) if a pubnonce in the recovery data is invalid. * On failure, secshare32 and thresh_pk33 are set to zero and * *n_participants_out and *threshold_out are set to 0; pubshares33 * and hostpubkeys33_out are set to zero whenever n could be * determined. * Args: ctx: pointer to a context object * Out: secshare32: pointer to a 32-byte array to store the * (tweaked) secret share * thresh_pk33: pointer to a 33-byte array to store the * threshold public key (compressed serialization) * pubshares33: pointer to an array capable of holding * 33*SECP256K1_CHILLDKG_MAX_PARTICIPANTS bytes * to store the public shares (33 bytes each; the * first n entries are filled) * hostpubkeys33_out: pointer to an array capable of holding * 33*SECP256K1_CHILLDKG_MAX_PARTICIPANTS bytes * to store the host public keys of the recovered * session (the first n entries are filled) * n_participants_out: pointer to a size_t to store the number of * participants n of the recovered session * threshold_out: pointer to a uint32 to store the threshold t * of the recovered session * fault_index: pointer to a uint32 that receives the identifier * of the suspected participant where applicable, * and UINT32_MAX otherwise * In: hostseckey32: pointer to the 32-byte host secret key * recovery: pointer to the recovery data * recovery_len: length of the recovery data */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT secp256k1_chilldkg_fault secp256k1_chilldkg_participant_recover( const secp256k1_context *ctx, unsigned char *secshare32, unsigned char *thresh_pk33, unsigned char *pubshares33, unsigned char *hostpubkeys33_out, size_t *n_participants_out, uint32_t *threshold_out, uint32_t *fault_index, const unsigned char *hostseckey32, const unsigned char *recovery, size_t recovery_len ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(8) SECP256K1_ARG_NONNULL(9) SECP256K1_ARG_NONNULL(10); /** Recover the DKG output of the coordinator from recovery data. * * Like secp256k1_chilldkg_participant_recover, but for the coordinator, who * has no secret share. * * Returns: SECP256K1_CHILLDKG_OK on success, * SECP256K1_CHILLDKG_INVALID_INPUT if the recovery data is invalid. * On failure, thresh_pk33 is set to zero and *n_participants_out * and *threshold_out are set to 0; pubshares33 and * hostpubkeys33_out are set to zero whenever n could be determined. * Args: ctx: pointer to a context object * Out: thresh_pk33: pointer to a 33-byte array to store the * threshold public key (compressed serialization) * pubshares33: pointer to an array capable of holding * 33*SECP256K1_CHILLDKG_MAX_PARTICIPANTS bytes * to store the public shares (the first n * entries are filled) * hostpubkeys33_out: pointer to an array capable of holding * 33*SECP256K1_CHILLDKG_MAX_PARTICIPANTS bytes * to store the host public keys of the recovered * session (the first n entries are filled) * n_participants_out: pointer to a size_t to store n * threshold_out: pointer to a uint32 to store t * In: recovery: pointer to the recovery data * recovery_len: length of the recovery data */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT secp256k1_chilldkg_fault secp256k1_chilldkg_coordinator_recover( const secp256k1_context *ctx, unsigned char *thresh_pk33, unsigned char *pubshares33, unsigned char *hostpubkeys33_out, size_t *n_participants_out, uint32_t *threshold_out, const unsigned char *recovery, size_t recovery_len ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7); /** Sign recovery data to create a recovery acknowledgment. * * The acknowledgment signature (64 bytes) is a BIP 340 signature over * pad33("BIP DKG/recovery acknowledgment") || u32be(participant_id) || * recovery_data under the participant's host key. Acks can be collected in * an optional acknowledgment round to confirm that all participants have * received the recovery data. * * Returns: 1 on success, 0 on invalid input (invalid host secret key, host * secret key not matching any host public key, invalid session * parameters, or recovery data that is invalid or does not match * the session parameters). On failure, sig64 is set to zero. * Args: ctx: pointer to a context object * Out: sig64: pointer to a 64-byte array to store the * acknowledgment signature * In: hostseckey32: pointer to the 32-byte host secret key * hostpubkeys33: pointer to an array of n host public keys (33 bytes * each) * n_participants: total number of participants n * threshold: threshold t * recovery: pointer to the recovery data * recovery_len: length of the recovery data * aux_rand32: pointer to 32 bytes of auxiliary randomness (see * BIP 340) */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_chilldkg_recovery_ack_sign( const secp256k1_context *ctx, unsigned char *sig64, const unsigned char *hostseckey32, const unsigned char *hostpubkeys33, size_t n_participants, uint32_t threshold, const unsigned char *recovery, size_t recovery_len, const unsigned char *aux_rand32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(9); /** Verify recovery acknowledgment signatures from all participants. * * Note that a failure of this function does NOT mean the DKG failed * (reaching this point implies the DKG itself was successful). It only means * it cannot be confirmed that all participants have a copy of the recovery * data. * * Returns: SECP256K1_CHILLDKG_OK if all n acknowledgment signatures are * valid, SECP256K1_CHILLDKG_INVALID_INPUT on invalid session * parameters or recovery data, or SECP256K1_CHILLDKG_FAULTY_PARTICIPANT * (with fault_index set to the signer) if an acknowledgment * signature is invalid (InvalidRecoveryAckError in the reference * implementation). * Args: ctx: pointer to a context object * Out: fault_index: pointer to a uint32 that receives the identifier of * the participant whose signature is invalid, where * applicable, and UINT32_MAX otherwise * In: hostpubkeys33: pointer to an array of n host public keys (33 bytes * each) * n_participants: total number of participants n * threshold: threshold t * recovery: pointer to the recovery data * recovery_len: length of the recovery data * ack_sigs64: array of n pointers to the acknowledgment * signatures (64 bytes each), in the same order as * hostpubkeys33 */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT secp256k1_chilldkg_fault secp256k1_chilldkg_recovery_acks_verify( const secp256k1_context *ctx, uint32_t *fault_index, const unsigned char *hostpubkeys33, size_t n_participants, uint32_t threshold, const unsigned char *recovery, size_t recovery_len, const unsigned char *const *ack_sigs64 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(8); /** Generate the investigation message for a single participant. * * The investigation message (65*n bytes, see * secp256k1_chilldkg_investigation_msg_len) allows the given participant to * investigate who is to blame for a failed ChillDKG session (see * secp256k1_chilldkg_participant_investigate). The message contains no * confidential information and can be safely broadcast. (Unlike the * reference implementation, which computes the investigation messages for * all participants at once, this function computes one message per call.) * * Returns: SECP256K1_CHILLDKG_OK on success, * SECP256K1_CHILLDKG_INVALID_INPUT on invalid session parameters or * participant_id >= n, or SECP256K1_CHILLDKG_FAULTY_PARTICIPANT * (with fault_index set to the sender) if a participant message is * malformed. On failure, cinv is set to zero. * Args: ctx: pointer to a context object * Out: cinv: pointer to a 65*n byte array to store the * investigation message for the given participant * fault_index: pointer to a uint32 (see above) * In: pmsgs1: array of n pointers to the participants' first * messages (33*t + 32*n + 97 bytes each) * hostpubkeys33: pointer to an array of n host public keys (33 bytes * each) * n_participants: total number of participants n * threshold: threshold t * participant_id: the participant the investigation message is for */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT secp256k1_chilldkg_fault secp256k1_chilldkg_coordinator_investigate( const secp256k1_context *ctx, unsigned char *cinv, uint32_t *fault_index, const unsigned char *const *pmsgs1, const unsigned char *hostpubkeys33, size_t n_participants, uint32_t threshold, uint32_t participant_id ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5); /** Investigate who is to blame for a failed ChillDKG session. * * This function can be called when secp256k1_chilldkg_participant_step2 * returned SECP256K1_CHILLDKG_UNKNOWN_FAULTY_PARTICIPANT_OR_COORDINATOR. It * narrows down the suspected faulty parties by analyzing the investigation * message provided by the coordinator. * * Returns: SECP256K1_CHILLDKG_FAULTY_COORDINATOR if the coordinator is * faulty, SECP256K1_CHILLDKG_FAULTY_PARTICIPANT_OR_COORDINATOR * (with fault_index set to the suspected participant) if another * participant or the coordinator is faulty, or * SECP256K1_CHILLDKG_INVALID_INPUT if all inputs are consistent * (i.e., the function was called even though no fault occurred). * Args: ctx: pointer to a context object * Out: fault_index: pointer to a uint32 (see above) * In: inv_data: pointer to the participant_inv_data object output by * secp256k1_chilldkg_participant_step2 * cinv: pointer to the coordinator's investigation message * for this participant (65*n bytes, see * secp256k1_chilldkg_investigation_msg_len) */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT secp256k1_chilldkg_fault secp256k1_chilldkg_participant_investigate( const secp256k1_context *ctx, uint32_t *fault_index, const secp256k1_chilldkg_participant_inv_data *inv_data, const unsigned char *cinv ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); #ifdef __cplusplus } #endif #endif