#ifndef __ECLIB_H
#define __ECLIB_H

#include <stddef.h>

#include "gflib.h"

#if (GF_M==191)
#if (GF_T==71)
	#define EC_B	0x145
	#define EC_SQR_B	0x1B
#elif (GF_T==9)
	#define EC_B		0x1445
	#define EC_SQR_B	0x6B
	#define EC_A		1
#elif (GF_T==140)
	#define EC_B	 0x1541
	#define EC_SQR_B 0x79
#elif (GF_T==18)
	#define EC_B	 0x55
	#define EC_SQR_B 0x0F	

#else
	#error "Unsupported trinomial"
#endif /* ? GF_T */
#else
#error "Unsupported trinomial"
#endif /* ?GF_M */

#define ecOpen(A)	{A = ec_Open();}
#define ecProjOpen(A)	{A = ec_ProjOpen();}
/*#define ecClear(A)	{gfClear((A)->x); gfClear((A)->y);}*/
#define ecExists(A)  (gfExists((A)->x) && gfExists((A)->y))
#define ecProjExists(A)  (gfExists((A)->x) && gfExists((A)->y) && gfExists((A)->z))

typedef struct  {
	gf_poly x, y;
} _ecpoint ;

typedef struct  {
	gf_poly x, y, z;
} _ecprojective ;

typedef _ecpoint  ec_point[1];
typedef _ecprojective  ec_projective[1];
typedef gf_poly	vl_number;

/*** Compressed types ****/
typedef gfPoint ecPoint;
typedef gfPoint vlPoint;

#define vlOpen		gfOpen
#define vlSet		gfSet
#define vlCopy		gfCopy
#define vlRandom 	gfRandom
#define vlClear		gfClear
#define vlExists	gfExists
#define vlPack		gfPack
#define vlUnpack	gfUnpack
#define vl_iszero	gf_iszero
#define vlEqual		gfEqual

int ecCheck (/*const*/ ec_point p);
//ec_point ec_Open(void);
void ecClear(ec_point a);
int ecEqual (/*const*/ ec_point p, /*const*/ ec_point q);
void ecZero(ec_point p);
void ecCopy (ec_point p, /*const*/ ec_point q);
ERROR ecCalcY (ec_point p, int ybit);
void ecRandom (ec_point p);
int ecYbit (/*const*/ ec_point p);
void ecDouble (ec_point p);
void ecAdd (ec_point p, /*const*/ ec_point q);
/*void ecMultiply (ec_point p, vl_number k); */
void ecPack (/*const*/ ec_point p, ecPoint k );
ERROR ecUnpack ( ec_point p, /*const*/ ecPoint k );
void ecNegate (ec_point p);

#ifdef _ECCRYPT_C
//ec_projective ec_ProjOpen(void);
void ecProjClear(ec_projective a);
void ecProj2Affine(ec_point p, /* const */ ec_projective q);
void ecProjDouble (ec_projective p);
void ecProjAdd (ec_projective p, /*const*/ ec_point q);
#endif /* _ECCRYPT_C */

#endif /* __ECLIB_H */
