/* -----------------------------------------------------------------------
 *
 * 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-hash.h>

/* example is only fo SHA160 algorithm
 */
s2byte hash_file_stepbystep()
{
	/* tmp buffer to read input file by block
	 */
	u1byte	buffer[8192];

	/* set name of file to hash
	 */
	s1byte	file[]	= "file_to_hash";
	
	/* create output stream with maximum size for the hash value
	 */
#ifndef ECCTK_EVALUATION

#define ALGO_CTX	SHA384_CTX
#define ALGO_Init	SHA384_Init
#define ALGO_Update	SHA384_Update
#define ALGO_Final	SHA384_Final
#define ALGO_Free	SHA384_Free
	
	u1byte	hash[ECCTK_HASH_SIZE_SHA384];
#else

#define ALGO_CTX	SHA160_CTX
#define ALGO_Init	SHA160_Init
#define ALGO_Update	SHA160_Update
#define ALGO_Final	SHA160_Final
#define ALGO_Free	SHA160_Free
	
	u1byte	hash[ECCTK_HASH_SIZE_SHA160];
#endif

	/* hash algorithm context
	 */
	ALGO_CTX	*ctx;

	FILE		*f;
	u4byte		nbread;
	s2byte		res;

	/* initialize context
	 */
	ctx = ALGO_Init();
	if (ctx == NULL)
	{
		fprintf(stderr, "Initialize SHA160 context failed\n");
		return EXIT_FAILURE;
	}
		
	f = fopen(file, "rb");
	if (f == NULL)
	{
		ALGO_Free(ctx);
		fprintf(stderr, "Open %s failed\n", file);
		return EXIT_FAILURE;
	}
	
	while (!feof(f)) 
    {
    	nbread = fread(buffer, sizeof(u1byte), sizeof(buffer), f);
    	if (ferror(f))
    	{
    		fprintf(stderr, "Read on %s failed\n", file);
			fclose(f);
			ALGO_Free(ctx);
			return EXIT_FAILURE;
		}
		
		res = ALGO_Update(ctx, buffer, nbread);
		if (res != ECCTK_HASH_NO_ERROR)
		{
			fprintf(stderr, "Update hash failed\n");
			fclose(f);
			ALGO_Free(ctx);
			return EXIT_FAILURE;
		}
    }
	fclose(f);
	
	res = ALGO_Final(ctx, hash, sizeof(hash));
	if (res != ECCTK_HASH_NO_ERROR)
	{
		ALGO_Free(ctx);
		return EXIT_FAILURE;
		fprintf(stderr, "Finalize hash failed\n");
	}
	
	fprintf(stderr, "Hash file (%s) success\n", file);
	ALGO_Free(ctx);
	return EXIT_SUCCESS;
}
