/*
* SPDX-License-Identifier: CC0-1.0
*
* Copyright (C) 2025 W. Kosior <koszko@koszko.org>
*/
#ifndef PQCRYPTO_BLIND_SIG_H
#define PQCRYPTO_BLIND_SIG_H
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "pqcrypto_poly.h"
#include "pqcrypto_hash.h"
/***
*** Definitions of types serializable as parts of other structers (but without
*** exposed API functions for this).
***/
struct blind_sig_message {
void * buf;
size_t bytes;
};
typedef struct blind_sig_message blind_sig_message_t[1];
typedef fmpz_poly_struct * blind_sig_poly_vector_t[1];
typedef void * blind_sig_n_bit_buf_t[1];
/***
*** Definitions of non-serializable types.
***/
enum blind_sig_log_level {
BLIND_SIG_LOG_QUIET = 0,
BLIND_SIG_LOG_ERROR = 1,
BLIND_SIG_LOG_INFO_1_CONTROL = 2,
BLIND_SIG_LOG_INFO_2_PARAMETERS = 3,
BLIND_SIG_LOG_DEBUG_1_PHASES = 4,
BLIND_SIG_LOG_DEBUG_2_VALUES = 5,
};
struct blind_sig_params {
/*
* n — number of polynomial coefficients to work on, the computations
* will be performed in a ring modulo X^n + 1
*/
ulong n;
/*
* q_bits — number of bits of a prime quotient for a modulo field to
* which polynomial coefficients will belong
*/
flint_bitcnt_t q_bits;
/*
* phi — a constant, affects completeness
*/
ulong phi;
/*
* psi — a constant, affects speed
*/
ulong psi;
/*
* d_s — maximum coefficient value for a polynomial in the private key
*/
ulong d_s;
/*
* m — number of polynomials in a private key, equal to the number of
* polynomials in the
*/
ulong m;
/*
* whether to print information about performed operations to stderr
*/
enum blind_sig_log_level log_level;
};
typedef struct blind_sig_params blind_sig_params_t[1];
typedef void (* commitment_function_t) (void * res, void const * data,
size_t data_len,
void const * randomness, ulong n);
struct blind_sig_ctx {
ulong n;
ulong d_s;
mod_centered_0_ctx_t key_gen_ctx;
ulong m;
ulong phi;
ulong psi;
ulong d_alpha;
mod_centered_0_ctx_t alpha_gen_ctx;
ulong d_epsilon_star;
fmpz_t d_y;
mod_centered_0_ctx_t y_commitment_gen_ctx;
fmpz_t d_g_star;
fmpz_t d_beta;
mod_centered_0_ctx_t beta_gen_ctx;
fmpz_t d_g;
poly_ring_ctx_t poly_ring_ctx;
blind_sig_poly_vector_t public_homomorphism;
commitment_function_t public_commitment_function;
hash_function_t public_hash_function;
enum blind_sig_log_level log_level;
};
typedef struct blind_sig_ctx blind_sig_ctx_t[1];
/***
*** Serializable structure definitions and their (de)serialization and
*** deinitialization function stubs.
***/
#define FIELD(type, name) type name;
#define SERIALIZABLE_STRUCT(name, fields) \
struct name { fields }; \
\
typedef struct name name##_t[1]; \
\
size_t name##_serialize(FILE * stream, name##_t const obj, \
blind_sig_ctx_t const ctx); \
\
void name##_file_serialize(const char * filename, name##_t const obj, \
blind_sig_ctx_t const ctx); \
\
size_t name##_deserialize(FILE * stream, name##_t obj, \
blind_sig_ctx_t const ctx); \
\
void name##_file_deserialize(const char * filename, name##_t obj, \
blind_sig_ctx_t const ctx); \
\
void name##_clear(name##_t obj, blind_sig_ctx_t const ctx);
#include "pqcrypto_blind_sig_serializable.c"
#undef FIELD
#undef SERIALIZABLE_STRUCT
/***
*** Declarations related to context handling.
***/
void blind_sig_ctx_init(blind_sig_ctx_t ctx, blind_sig_params_t const params);
void blind_sig_ctx_clear(blind_sig_ctx_t ctx);
#ifndef PQCRYPTO_BLIND_SIG_C
extern blind_sig_params_t blind_sig_params_current_III, blind_sig_params_toy;
#endif
/***
*** Logging facility.
***/
int blind_sig_vlog(blind_sig_ctx_t const ctx,
enum blind_sig_log_level message_level,
char const * fmt, va_list ap);
#define X(level) \
inline static int blind_sig_log_##level(blind_sig_ctx_t const ctx, \
char const * fmt, ...) { \
va_list ap; \
int result = 0; \
\
va_start(ap, fmt); \
\
result = blind_sig_vlog(ctx, BLIND_SIG_LOG_##level, fmt, ap); \
\
va_end(ap); \
\
return result; \
}
X(ERROR)
X(INFO_1_CONTROL)
X(INFO_2_PARAMETERS)
X(DEBUG_1_PHASES)
X(DEBUG_2_VALUES)
#undef X
/***
*** Key handling function stubs.
***/
void blind_sig_key_init_gen(blind_sig_priv_key_t priv_key,
blind_sig_pub_key_t pub_key,
blind_sig_ctx_t const ctx);
/***
*** Signature protocol-related function stubs.
***/
void blind_sig_signer_state_init(blind_sig_signer_state_t state,
blind_sig_ctx_t const ctx);
void blind_sig_user_state_init(blind_sig_user_state_t state,
blind_sig_ctx_t const ctx);
void blind_sig_proto_p1_init_do(blind_sig_proto_p1_t result,
blind_sig_signer_state_t state,
blind_sig_ctx_t const ctx);
void blind_sig_proto_p2_init_do(blind_sig_proto_p2_t result,
blind_sig_user_state_t state,
blind_sig_pub_key_t const pub_key,
void const * message_buf, size_t message_bytes,
blind_sig_proto_p1_t const p1_result,
unsigned long * retries_left,
blind_sig_ctx_t const ctx);
void blind_sig_proto_p3_init_do(blind_sig_proto_p3_t result,
blind_sig_signer_state_t state,
blind_sig_priv_key_t const priv_key,
blind_sig_proto_p2_t const p2_result,
blind_sig_ctx_t const ctx);
/*
* Also initializes and populates sig, but only of the signature could be
* successfully obtained (result->needs_restart == false).
*/
void blind_sig_proto_p4_init_do(blind_sig_proto_p4_t result,
blind_sig_t sig,
blind_sig_user_state_t const state,
blind_sig_proto_p3_t const p3_result,
blind_sig_ctx_t const ctx);
void blind_sig_proto_p5_init_do(blind_sig_proto_p5_t result,
blind_sig_signer_state_t const state,
blind_sig_pub_key_t const pub_key,
blind_sig_proto_p4_t const p4_result,
blind_sig_ctx_t const ctx);
/***
*** Signature verification function stub.
***/
bool blind_sig_verify(blind_sig_t const sig, blind_sig_pub_key_t const pub_key,
blind_sig_ctx_t const ctx);
#endif /* PQCRYPTO_BLIND_SIG_H */