#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <memory.h>
#include "gmp.h"
#include "mpzutil.h"
#include "hecurve.h"
#include "ffwrapper.h"
#include "cstd.h"
#define _dbg_print_uv(s,u,v) if ( dbg_level >= 2 ) { printf (s); hecurve_print(u,v); }
int hecurve_g1_compose (ff_t u[HECURVE_GENUS+1], ff_t v[HECURVE_GENUS], ff_t u1[HECURVE_GENUS+1],
ff_t v1[HECURVE_GENUS], ff_t u2[HECURVE_GENUS+1],
ff_t v2[HECURVE_GENUS+1], ff_t f[HECURVE_DEGREE+1], hecurve_ctx_t *ctx)
{
_ff_t_declare_reg m, t1, t2;
#ifdef FF_INIT_REQUIRED
static int init;
if ( ! init ) { _ff_init (m); _ff_init (t1); _ff_init (t2); init = 1; }
#endif
#if ! HECURVE_FAST
_dbg_print_uv ("Genus 1 Compose A: ", u1, v1);
_dbg_print_uv ("Genus 1 Compose B: ", u2, v2);
#endif
#if HECURVE_VERIFY
if ( ! hecurve_verify (u1, v1, f) ) { err_printf ("hecurve_compose_g1 input verification failed for input: "); hecurve_print(u1,v1); exit (0); }
if ( ! hecurve_verify (u2, v2, f) ) { err_printf ("hecurve_compose_g1 input verification failed for input: "); hecurve_print(u2,v2); exit (0); }
#endif
if ( _hecurve_is_identity (u1,v2) ) { _hecurve_set(u,v,u2,v2); return 1; }
if ( _hecurve_is_identity (u2,v2) ) { _hecurve_set(u,v,u1,v1); return 1; }
if ( ctx && ctx->state ) {
if ( ctx->state == 1 ) {
_ff_set (t2, ctx->invert);
goto hecurve_g1_compose_inverted;
} else if ( ctx->state == 2 ) {
return hecurve_g1_square (u, v, u1, v1, f, ctx);
}
}
_ff_sub (t1, u2[0], u1[0]);
if ( _ff_zero(t1) ) {
if ( _ff_equal(v1[0],v2[0]) ) {
return hecurve_g1_square (u, v, u1, v1, f, ctx);
} else {
_hecurve_set_identity (u,v);
return 1;
}
}
if ( ctx && ! ctx->state ) {
_ff_set (ctx->invert, t1);
ctx->state = 1;
return 0;
}
_ff_invert(t2,t1);
hecurve_g1_compose_inverted:
_ff_sub (t1,v1[0],v2[0]);
_ff_mult (m,t1,t2);
_ff_square (t1,m);
_ff_add (t2,u1[0],u2[0]);
_ff_addto (t2,t1);
_ff_neg (t1,t2);
_ff_sub (t2, t1, u1[0]);
_ff_set_one (u[1]);
_ff_set (u[0], t1);
_ff_mult (t1, t2, m);
_ff_subfrom (t1, v1[0]);
_ff_set (v[0], t1);
#if ! HECURVE_FAST
_dbg_print_uv ("Genus 1 Compose Result: ", u, v);
#endif
#if HECURVE_VERIFY
if ( ! hecurve_verify (u, v, f) ) {
err_printf ("hecurve_compose output verification failed for inputs:\n");
err_printf (" "); hecurve_print(u1,v1);
err_printf (" "); hecurve_print(u2,v2);
err_printf ("note that inputs have been modified if output overlapped input.\n");
exit (0);
}
#endif
return 1;
}
int hecurve_g1_square (ff_t u[HECURVE_GENUS+1], ff_t v[HECURVE_GENUS],
ff_t u1[HECURVE_GENUS+1], ff_t v1[HECURVE_GENUS], ff_t f[HECURVE_DEGREE+1], hecurve_ctx_t *ctx)
{
_ff_t_declare_reg m, t1, t2;
#ifdef FF_INIT_REQUIRED
static int init;
if ( ! init ) { _ff_init (m); _ff_init (t1); _ff_init (t2); init = 1; }
#endif
#if HECURVE_VERIFY
if ( ! hecurve_verify (u1, v1, f) ) { err_printf ("hecurve_square_g1 input verification failed for input: "); hecurve_print(u1,v1); exit (0); }
#endif
if ( ctx && ctx->state == 2 ) {
_ff_set (t2, ctx->invert);
goto hecurve_g1_square_inverted;
}
#if ! HECURVE_FAST
_dbg_print_uv ("Genus 1 Square: ", u1, v1);
#endif
if ( _hecurve_2tor (u1,v1) ) { _hecurve_set_identity (u,v); return 1; }
_ff_add (t1, v1[0], v1[0]);
if ( ctx && ! ctx->state ) {
_ff_set (ctx->invert, t1);
ctx->state = 2;
return 0;
}
_ff_invert (t2,t1);
hecurve_g1_square_inverted:
_ff_square (t1, u1[0]);
_ff_add (m, t1, t1);
_ff_addto (t1, m);
_ff_addto (t1, f[1]);
_ff_mult (m, t1, t2);
_ff_square (t1,m);
_ff_add (t2,u1[0],u1[0]);
_ff_addto (t2,t1);
_ff_neg (t1, t2);
_ff_sub (t2,t1,u1[0]);
ff_mult (t2, t2, m);
_ff_subfrom (t2, v1[0]);
_ff_set_one (u[1]);
_ff_set (u[0], t1);
_ff_set (v[0], t2);
#if ! HECURVE_FAST
_dbg_print_uv ("Genus 1 square Result: ", u, v);
#endif
#if HECURVE_VERIFY
if ( ! hecurve_verify (u, v, f) ) {
err_printf ("hecurve_square output verification failed for input:\n");
err_printf (" "); hecurve_print(u1,v1);
err_printf ("note that inputs have been modified if output overlapped input.\n");
exit (0);
}
#endif
return 1;
}