/* -----------------------------------------------------------------------
 *
 * Copyright (c) 2002-2005 Mr Ludovic FLAMENT <ludovic.flament@free.fr>, LIEVIN, FRANCE
 *
 * Termes :
 *
 * L'utilisation et/ou la redistribution de ce code (avec ou sans modification),
 * ainsi que de tous les composants du produit (librairies, documentation, exemples, ...)
 * est soumise aux termes de la licence qui vous est attribuée par son auteur.
 *
 * -----------------------------------------------------------------------
 */

#include <stdlib.h>
#include <stdio.h>

#include <include/ecctk-prototype.h>
#include <include/ecctk-ecc.h>

#define MAX_SECRET	5

s2byte secret_sharing()
{
	s2byte	ret		= -1,
			i,
			j;

	/* set output file name
	 */
	s1byte	*share_file[MAX_SECRET] = {"share1_file", "share2_file", "share3_file", "share4_file", "share5_file"};

	/* set the secret to share
	 */
	u1byte secret[] = "This is my Secret to share";

	/* to get the secret (validation)
	 */
	u1byte *result_secret = NULL;

	/* to get the secret size (validation)
	 */
	u2byte result_secret_size;

	/* set the number of secret generated and necessary to compute the secret in next time
	 */
	u2byte	nb_generated_secret = MAX_SECRET,
			nb_necessary_secret = MAX_SECRET-2;

	/* sharing context
	 */
	SHARING_CTX **ctx	= NULL;

	/* creation code
	 * ---------------------------------------------------------------------------------------------
	 */
	ctx = CreateSecretSharingCtx(secret, sizeof(secret), nb_necessary_secret, nb_generated_secret);
	if (ctx == NULL)
	{
		fprintf(stderr, "Create secret failed\n\n");
		return EXIT_FAILURE;
	}

	/* write all sharing secret value
	 * on output file
	 */
	for (i = 0; i < nb_generated_secret; i++)
	{
		ret = WriteFileSharingCtx(share_file[i], ctx[i]);
		if (ret != ECCTK_ECC_NO_ERROR)
		{
			fprintf(stderr, "Write sharing secret (Error : %d)\n", ret);
			goto create_end;
		}

		/* free context
		 */
		SharingCtxFree(ctx[i]);
		ctx[i] = NULL;
	}

	/* free context
	 */
	SharingPtFree(ctx);
	ctx = NULL;

	/* end of creation code
	 * ---------------------------------------------------------------------------------------------
	 */


	/* verification code
	 * check that we can compute the initial secret with only 3 share
	 * ---------------------------------------------------------------------------------------------
	 */
	ctx = SharingPtInit(nb_necessary_secret);
	if (ctx == NULL)
	{
		fprintf(stderr, "Create pointer context failed\n");
		goto val_end;
	}

	/* read secret in file share1_file, share3_file, share5_file
	 */
	for (i = 0, j = 0; i < nb_necessary_secret; i++, j+=2)
	{
		ctx[i] = ReadFileSharingCtx(share_file[j]);
		if (ctx[i] == NULL)
		{
			fprintf(stderr, "Read sharing secret on %s failed\n", share_file[j]);
			goto val_end;
		}
	}

	/* compute the secret value
	 */
	result_secret = ResolveSecretSharingCtx(ctx, &result_secret_size);
	if (result_secret == NULL)
	{
		fprintf(stderr, "Error during compute the secret\n");
		goto val_end;
	}

	fprintf(stdout, "Secret (%d) : '%s'\n", result_secret_size, result_secret);

	/* free all context, and result secret
	 */
	for (i = 0; i < nb_necessary_secret; i++)
		SharingCtxFree(ctx[i]);
	SharingPtFree(ctx);

	free(result_secret);

	return EXIT_SUCCESS;

	/* end of verification code
	 * ---------------------------------------------------------------------------------------------
	 */

create_end:

	if (ctx != NULL)
	{
		for (i = 0; i < nb_generated_secret; i++)
			SharingCtxFree(ctx[i]);
		SharingPtFree(ctx);
	}

	return EXIT_FAILURE;

val_end:
	
	if (ctx != NULL)
	{
		for (i = 0; i < nb_necessary_secret; i++)
			SharingCtxFree(ctx[i]);
		SharingPtFree(ctx);
	}

	if (result_secret != NULL)
		free(result_secret);

	return EXIT_FAILURE;
}
