aboutsummaryrefslogtreecommitdiff
/*
 * 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 */